{"record":{"id":"b6aec2654b761124","repo":"risingwavelabs/risingwave","slug":"failed-to-lookup-and-evaluate-the-expression-in-e","errorCode":null,"errorMessage":"failed to lookup and evaluate the expression in `eval`","messagePattern":"failed to lookup and evaluate the expression in `eval`","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"src/expr/impl/src/scalar/case.rs","lineNumber":232,"sourceCode":"        for i in 0..input_len {\n            let datum = eval_result.datum_at(i);\n            let (row, vis) = $input.row_at(i);\n\n            // Check for visibility\n            if !vis {\n                builder.append_null();\n                continue;\n            }\n\n            // Note that the `owned_row` here is extracted from input\n            // rather than from `eval_result`\n            let owned_row = row.into_owned_row();\n\n            // Lookup and evaluate the current input datum\n            if let Ok(datum) = lookup!($mode, $this, datum, &owned_row) {\n                builder.append(datum.as_ref());\n            } else {\n                bail!(\"failed to lookup and evaluate the expression in `eval`\");\n            }\n        }\n\n        Ok(Arc::new(builder.finish()))\n    }};\n}\n\nimpl<E: SyncExpression> SyncExpression for ConstantLookupExpression<E> {\n    fn eval(&self, input: &DataChunk) -> Result<ArrayRef> {\n        eval_constant_lookup!(sync, self, input)\n    }\n\n    fn eval_row(&self, input: &OwnedRow) -> Result<Datum> {\n        let datum = self.operand.eval_row(input)?;\n        lookup!(sync, self, datum, input)\n    }\n}\n","sourceCodeStart":214,"sourceCodeEnd":250,"githubUrl":"https://github.com/risingwavelabs/risingwave/blob/6469eb736d691e8e9b8a419a57edd6429ca77417/src/expr/impl/src/scalar/case.rs#L214-L250","documentation":"The batch `eval` path of the constant-lookup CASE expression iterates input rows and calls the `lookup!` macro for each datum. Any per-row failure (from a normal arm or the fallback) is converted into this single generic error, so the whole array evaluation fails with no detail about which row or sub-expression failed.","triggerScenarios":"Batch evaluation of a constant-lookup CASE where at least one row's matched arm or fallback expression returns Err, causing the entire eval to bail with this wrapper message.","commonSituations":"Bulk query or MV backfill where a few rows contain values that break a then/else sub-expression; debugging is hard because the root error is swallowed.","solutions":["Make the inner then/else expressions total (COALESCE, NULLIF, safe casts) so no row can fail.","Filter or sanitize problematic rows before the CASE expression.","If diagnosing, evaluate the CASE per-row or via a debug path to surface the underlying error."],"exampleFix":"// before\nCASE id WHEN 1 THEN amount / qty ELSE 0 END\n// after\nCASE id WHEN 1 THEN amount / NULLIF(qty, 0) ELSE 0 END","handlingStrategy":"try-catch","validationCode":null,"typeGuard":null,"tryCatchPattern":"match array_result {\n    Err(e) if e.to_string().contains(\"failed to lookup and evaluate the expression in `eval`\") => {\n        // re-run per-row to isolate the failing row and arm\n    }\n    other => other?,\n}","preventionTips":["Use NULLIF to protect division inside CASE arms.","Prefer explicit safe casts over implicit ones.","Evaluate candidate expressions on sample edge-case data first."],"tags":["rust","sql","case-expression","batch-eval"],"backgroundTag":"internal-invariant-violation","analyzedSha":"6469eb736d691e8e9b8a419a57edd6429ca77417","analyzedAt":"2026-09-11T21:06:21.487Z","contentChangedAt":"2026-09-11T21:06:21.487Z","schemaVersion":2},"datasetVersion":"2026-09-14T16:17:12.679Z"}