{"record":{"id":"94817a52ef854158","repo":"vitessio/vitess","slug":"unexpected-v-94817a","errorCode":null,"errorMessage":"unexpected: %v","messagePattern":"unexpected: (.+?)","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"go/vt/vttablet/tabletserver/vstreamer/planbuilder.go","lineNumber":618,"sourceCode":"\t\treturn err\n\t}\n\tenv := evalengine.EmptyExpressionEnv(plan.env)\n\tresolved, err := env.Evaluate(pv)\n\tif err != nil {\n\t\treturn err\n\t}\n\tplan.Filters = append(plan.Filters, Filter{\n\t\tOpcode: opcode,\n\t\tColNum: colnum,\n\t\tValues: resolved.TupleValues(),\n\t})\n\treturn nil\n}\n\nfunc (plan *Plan) getEvalResultForLiteral(expr sqlparser.Expr) (*evalengine.EvalResult, error) {\n\tliteralExpr, ok := expr.(*sqlparser.Literal)\n\tif !ok {\n\t\treturn nil, fmt.Errorf(\"unexpected: %v\", sqlparser.String(expr))\n\t}\n\tpv, err := evalengine.Translate(literalExpr, &evalengine.Config{\n\t\tCollation:   plan.env.CollationEnv().DefaultConnectionCharset(),\n\t\tEnvironment: plan.env,\n\t})\n\tif err != nil {\n\t\treturn nil, err\n\t}\n\tenv := evalengine.EmptyExpressionEnv(plan.env)\n\tresolved, err := env.Evaluate(pv)\n\treturn &resolved, err\n}\n\nfunc (plan *Plan) analyzeWhere(vschema *localVSchema, where *sqlparser.Where) error {\n\tif where == nil {\n\t\treturn nil\n\t}\n\t// Only a series of AND expressions are supported.","sourceCodeStart":600,"sourceCodeEnd":636,"githubUrl":"https://github.com/vitessio/vitess/blob/01a25a7d176f94613b8d59d799f438380a8760e4/go/vt/vttablet/tabletserver/vstreamer/planbuilder.go#L600-L636","documentation":"In vstreamer planbuilder, getEvalResultForLiteral expects the right-hand expression of a filter predicate to be a SQL literal. If analyzeWhere hands it any other expression node (column, function call, expression), the builder cannot evaluate it statically and returns 'unexpected: <expr>'.","triggerScenarios":"A VStream filter WHERE clause compares a column against a non-literal, e.g. col = other_col, col = now(), or col = concat('a','b'), causing getEvalResultForLiteral to receive a non-Literal expr.","commonSituations":"Filters written with function calls or column-to-column comparisons; users assuming full SQL expression support in VReplication filters.","solutions":["Replace the right-hand side with a literal constant: col = 'value' or col IN (1,2,3)","Precompute function results into constants before configuring the filter","Review the supported predicate forms in planbuilder.go (col op literal, col IN tuple)"],"exampleFix":"// before\nwhere updated_at > now()\n// after\nwhere updated_at > '2024-01-01 00:00:00'","handlingStrategy":"validation","validationCode":"// ensure predicates compare column op literal\nfor _, p := range predicates {\n    if _, ok := p.right.(sqlparser.Literal); !ok {\n        return fmt.Errorf(\"right side must be a literal: %v\", sqlparser.String(p.right))\n    }\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Use constant literals on the right side of comparisons","No function calls or column-to-column comparisons in filters","Precompute values before configuring the filter"],"tags":["vstreamer","planbuilder","literal","filter"],"backgroundTag":"unsupported-sql-feature","analyzedSha":"01a25a7d176f94613b8d59d799f438380a8760e4","analyzedAt":"2026-09-01T17:28:30.605Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}