risingwavelabs/risingwave · error · ExprError

not a constant

Error message

not a constant

What it means

ExprError::NotConstant is thrown when code that requires a constant (literal, foldable) expression receives a non-constant one. Certain APIs in the expression crate — e.g. extracting literal values for planning or constant folding — only accept expressions whose value is known at planning time.

Solutions

  1. Constant-fold the expression before extracting it (run the constant-folding pass).
  2. Handle the non-constant case explicitly instead of expecting a literal.
  3. If the value must be known statically, provide it as a literal parameter rather than a runtime expression.

Example fix

// before
let v = expr.as_literal().ok_or(ExprError::NotConstant)?; // expr is a column ref
// after
let folded = constant_fold(expr);
let v = folded.as_literal().ok_or_else(|| ExprError::NotConstant)?;
Defensive patterns

Strategy: type-guard

Validate before calling

// Rust: check constness before calling constant-only APIs
if expr.is_const_foldable() { extract_const(expr)?; } else { /* dynamic path */ }

Type guard

fn as_const(expr: &ExprImpl) -> Option<Literal> {
    constant_fold(expr.clone()).as_literal()
}

Prevention

When it happens

Trigger: Calling constant-extraction APIs (match on literal variants, `eval_const`-style helpers) with a column reference, volatile function, or any expression not folded to a literal during planning.

Common situations: Optimizer/planner passes assuming a literal after partial constant folding, custom expression rewrites passing dynamic expressions into constant-only APIs.

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


AI-assisted analysis of risingwavelabs/risingwave@6469eb736d (2026-09-11). Data as JSON: /api/errors/3445132a186fba8f. Report an issue: GitHub.

Appendix: source

Thrown at src/expr/core/src/error.rs:99

    #[error("Array error: {0}")]
    Array(
        #[from]
        #[backtrace]
        ArrayError,
    ),

    #[error("More than one row returned by {0} used as an expression")]
    MaxOneRow(&'static str),

    /// TODO: deprecate in favor of `Function`
    #[error(transparent)]
    Internal(
        #[from]
        #[backtrace]
        anyhow::Error,
    ),

    #[error("not a constant")]
    NotConstant,

    #[error("Context {0} not found")]
    Context(&'static str),

    #[error("field name must not be null")]
    FieldNameNull,

    #[error("too few arguments for format()")]
    TooFewArguments,

    #[error(
        "null value in column \"{col_name}\" of relation \"{table_name}\" violates not-null constraint"
    )]
    NotNullViolation {
        col_name: Box<str>,
        table_name: Box<str>,
    },

View on GitHub (pinned to 6469eb736d)