{"record":{"id":"b6c81e518d851bca","repo":"tursodatabase/turso","slug":"unsupported-operator-in-trivial-expression-op","errorCode":null,"errorMessage":"Unsupported operator in trivial expression: {op:?}","messagePattern":"Unsupported operator in trivial expression: (.+?)","errorType":"panic","errorClass":null,"httpStatus":null,"severity":"error","filePath":"core/incremental/expr_compiler.rs","lineNumber":132,"sourceCode":"impl TrivialExpression {\n    /// Evaluate the trivial expression with the given input values\n    /// Automatically promotes integers to floats when mixing types in arithmetic\n    pub fn evaluate(&self, values: &[Value]) -> Value {\n        match self {\n            TrivialExpression::Column(idx) => values.get(*idx).cloned().unwrap_or(Value::Null),\n            TrivialExpression::Immediate(val) => val.clone(),\n            TrivialExpression::Binary { left, op, right } => {\n                let left_val = left.evaluate(values);\n                let right_val = right.evaluate(values);\n\n                // Use Value's exec_* methods which handle all type coercion\n                // (including Text → Numeric) consistently with SQLite semantics\n                match op {\n                    Operator::Add => left_val.exec_add(&right_val),\n                    Operator::Subtract => left_val.exec_subtract(&right_val),\n                    Operator::Multiply => left_val.exec_multiply(&right_val),\n                    Operator::Divide => left_val.exec_divide(&right_val),\n                    _ => panic!(\"Unsupported operator in trivial expression: {op:?}\"),\n                }\n            }\n        }\n    }\n}\n\n/// Compiled expression that can be executed on row values\n#[derive(Clone)]\npub struct CompiledExpression {\n    /// The expression executor (trivial or compiled)\n    pub executor: ExpressionExecutor,\n    /// Number of input values expected (columns from the row)\n    pub input_count: usize,\n}\n\nimpl std::fmt::Debug for CompiledExpression {\n    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {\n        let mut s = f.debug_struct(\"CompiledExpression\");","sourceCodeStart":114,"sourceCodeEnd":150,"githubUrl":"https://github.com/tursodatabase/turso/blob/492c4a71cd7c2649e7df83da1471b74f4b1c7aa9/core/incremental/expr_compiler.rs#L114-L150","documentation":"The incremental-maintenance expression compiler can lower 'trivial' binary expressions to a fast path, but TrivialExpression::evaluate only implements Add, Subtract, Multiply and Divide (via Value::exec_*). Any other Operator reaching this match panics - the analyzer/lowering admitted an expression the evaluator cannot run.","triggerScenarios":"Creating incrementally-maintained structures in core/incremental whose expression uses an operator outside + - * / (e.g. %, ||, <<, comparisons); or a lowering change that routes wider expression classes into TrivialExpression.","commonSituations":"Writing new incremental view definitions with rich expressions; analyzer refactors that widen the trivial-expression filter without extending evaluate().","solutions":["Restrict incremental-maintained expressions to +, -, *, / until the operator is supported","If you maintain the compiler, keep the analyzer whitelist in sync with the operators handled in evaluate()","Report or add support for the specific operator with a minimal SQL repro"],"exampleFix":"-- before\nCREATE MATERIALIZED VIEW v AS SELECT (n % 10) AS bucket FROM t; -- modulo has no trivial path\n\n-- after\nCREATE MATERIALIZED VIEW v AS SELECT (n / 10) AS decade FROM t; -- division is supported","handlingStrategy":"type-guard","validationCode":"fn is_trivial_op(op: &Operator) -> bool {\n    matches!(op, Operator::Add | Operator::Subtract | Operator::Multiply | Operator::Divide)\n}\n// reject anything else before lowering to TrivialExpression","typeGuard":"fn is_trivial_expression(e: &TrivialExpression) -> bool {\n    match e {\n        TrivialExpression::Immediate(_) => true,\n        TrivialExpression::Binary { op, .. } => matches!(\n            op,\n            Operator::Add | Operator::Subtract | Operator::Multiply | Operator::Divide\n        ),\n    }\n}","tryCatchPattern":null,"preventionTips":["Keep the analyzer whitelist and the evaluator match in the same change/review","Add a unit test enumerating operators accepted by lowering versus handled by evaluate()"],"tags":["incremental","expression","operator","compiler","panic"],"backgroundTag":"unsupported-expression-operator","analyzedSha":"492c4a71cd7c2649e7df83da1471b74f4b1c7aa9","analyzedAt":"2026-08-20T07:02:18.389Z","contentChangedAt":"2026-08-20T07:02:18.389Z","schemaVersion":2},"datasetVersion":"2026-09-14T00:17:10.932Z"}