risingwavelabs/risingwave · error
expression must be a constant value
Error message
expression must be a constant value
What it means
`expr_impl_to_u64_fn` requires each argument's constant-folded value to exist. When the fold yields `None` (expression is not constant), the function errors with `expression must be a constant value` because time parameters must be known at plan time.
Solutions
- Inline literal int64 constants for both arguments.
- Precompute the value in the client and pass it as a literal.
- Remove column references or subqueries from the arguments.
- Use a supported API (dashboard service) if runtime-parameterized stats are needed.
Example fix
-- before SELECT * FROM internal_get_channel_delta_stats(my_offset_col, 0); -- after SELECT * FROM internal_get_channel_delta_stats(3600, 0);
Defensive patterns
Strategy: validation
Validate before calling
-- Arguments must be literals SELECT * FROM internal_get_channel_delta_stats(3600, 0);
Try / catch
match expr_impl_to_u64_fn(expr) {
Ok(v) => /* proceed */,
Err(e) => eprintln!("arguments must be constants: {e:#}"),
} Prevention
- Never reference columns, parameters, or session variables in arguments
- Compute values in the client and inline them
- Remember these are plan-time constants, not runtime parameters
When it happens
Trigger: Calling `internal_get_channel_delta_stats` with arguments that depend on columns, parameters, or non-constant expressions, e.g. `internal_get_channel_delta_stats(some_col, 0)`.
Common situations: Attempting to parameterize the dashboard stats function with runtime values, or using session variables/non-deterministic expressions as arguments.
Understand the failure class
Background: "Must be a positive integer", "Invalid value", "Unsupported": the invalid-argument-value error family, when a library rejects the value you pass — this error's family across 35 libraries.
Related errors
- failed to fold constant
- call predicate_pushdown of the PlanRef instead of calling…
- call prune_col of the PlanRef instead of calling directly…
- ` ` column not found in backfill table
- expected int64, got
AI-assisted analysis of risingwavelabs/risingwave@6469eb736d (2026-09-11).
Data as JSON: /api/errors/0a443b1605e153db.
Report an issue: GitHub.
Appendix: source
Thrown at src/frontend/src/optimizer/rule/table_function_to_internal_get_channel_delta_stats.rs:56
let Some(scalar) = value else {
return Ok(None);
};
match scalar {
ScalarImpl::Int64(value) => {
if value < 0 {
Err(anyhow::anyhow!(
"time parameter cannot be negative, got {}",
value
))
} else {
Ok(Some(value as u64))
}
}
_ => Err(anyhow::anyhow!("expected int64, got {:?}", scalar)),
}
}
Some(Err(err)) => Err(anyhow!(err).context("failed to fold constant")),
None => Err(anyhow::anyhow!("expression must be a constant value")),
}
}
/// Transform the `internal_get_channel_delta_stats()` table function
/// into a plan graph which will return channel statistics from the dashboard API.
/// It will return channel stats with `upstream_fragment_id` and `downstream_fragment_id` as primary key.
pub struct TableFunctionToInternalGetChannelDeltaStatsRule {}
impl FallibleRule<Logical> for TableFunctionToInternalGetChannelDeltaStatsRule {
fn apply(&self, plan: PlanRef) -> ApplyResult<PlanRef> {
let logical_table_function: &LogicalTableFunction = plan.as_logical_table_function()?;
if logical_table_function.table_function().function_type
!= TableFunctionType::InternalGetChannelDeltaStats
{
return ApplyResult::NotApplicable;
}
let plan = Self::build_plan(plan.ctx(), logical_table_function.table_function())?;
ApplyResult::Ok(plan)
}View on GitHub (pinned to 6469eb736d)