{"record":{"id":"3445132a186fba8f","repo":"risingwavelabs/risingwave","slug":"not-a-constant","errorCode":null,"errorMessage":"not a constant","messagePattern":"not a constant","errorType":"exception","errorClass":"ExprError","httpStatus":null,"severity":"error","filePath":"src/expr/core/src/error.rs","lineNumber":99,"sourceCode":"    #[error(\"Array error: {0}\")]\n    Array(\n        #[from]\n        #[backtrace]\n        ArrayError,\n    ),\n\n    #[error(\"More than one row returned by {0} used as an expression\")]\n    MaxOneRow(&'static str),\n\n    /// TODO: deprecate in favor of `Function`\n    #[error(transparent)]\n    Internal(\n        #[from]\n        #[backtrace]\n        anyhow::Error,\n    ),\n\n    #[error(\"not a constant\")]\n    NotConstant,\n\n    #[error(\"Context {0} not found\")]\n    Context(&'static str),\n\n    #[error(\"field name must not be null\")]\n    FieldNameNull,\n\n    #[error(\"too few arguments for format()\")]\n    TooFewArguments,\n\n    #[error(\n        \"null value in column \\\"{col_name}\\\" of relation \\\"{table_name}\\\" violates not-null constraint\"\n    )]\n    NotNullViolation {\n        col_name: Box<str>,\n        table_name: Box<str>,\n    },","sourceCodeStart":81,"sourceCodeEnd":117,"githubUrl":"https://github.com/risingwavelabs/risingwave/blob/6469eb736d691e8e9b8a419a57edd6429ca77417/src/expr/core/src/error.rs#L81-L117","documentation":"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.","triggerScenarios":"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.","commonSituations":"Optimizer/planner passes assuming a literal after partial constant folding, custom expression rewrites passing dynamic expressions into constant-only APIs.","solutions":["Constant-fold the expression before extracting it (run the constant-folding pass).","Handle the non-constant case explicitly instead of expecting a literal.","If the value must be known statically, provide it as a literal parameter rather than a runtime expression."],"exampleFix":"// before\nlet v = expr.as_literal().ok_or(ExprError::NotConstant)?; // expr is a column ref\n// after\nlet folded = constant_fold(expr);\nlet v = folded.as_literal().ok_or_else(|| ExprError::NotConstant)?;","handlingStrategy":"type-guard","validationCode":"// Rust: check constness before calling constant-only APIs\nif expr.is_const_foldable() { extract_const(expr)?; } else { /* dynamic path */ }","typeGuard":"fn as_const(expr: &ExprImpl) -> Option<Literal> {\n    constant_fold(expr.clone()).as_literal()\n}","tryCatchPattern":null,"preventionTips":["Run constant-folding before any constant-extraction API.","Never assume a literal after a rewrite; re-check foldability.","Route non-constant expressions to the dynamic evaluation path."],"tags":["rust","planner","constant-folding"],"backgroundTag":"invalid-argument-value","analyzedSha":"6469eb736d691e8e9b8a419a57edd6429ca77417","analyzedAt":"2026-09-11T21:06:21.487Z","contentChangedAt":"2026-09-11T21:06:21.487Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}