vitessio/vitess · error
invalid comparison operator
Error message
invalid comparison operator
What it means
The tuple-comparison compiler (compileAsTuple) switches over the ComparisonExpr's operator and only supports EQ/NE/LT/LE/GT/GE-style tuple comparisons it knows about. An operator enum value outside the handled set reaches the default branch and panics. This is an internal exhaustive-switch guard: sqlparser/IR should never produce a comparison operator that lacks a tuple compilation strategy.
Source
Thrown at go/vt/vtgate/evalengine/expr_compare.go:350
c.asm.CmpTuple(c.env.CollationEnv(), true)
c.asm.Cmp_eq_n()
case compareNE:
c.asm.CmpTuple(c.env.CollationEnv(), true)
c.asm.Cmp_ne_n()
case compareLT:
c.asm.CmpTuple(c.env.CollationEnv(), false)
c.asm.Cmp_lt_n()
case compareLE:
c.asm.CmpTuple(c.env.CollationEnv(), false)
c.asm.Cmp_le_n()
case compareGT:
c.asm.CmpTuple(c.env.CollationEnv(), false)
c.asm.Cmp_gt_n()
case compareGE:
c.asm.CmpTuple(c.env.CollationEnv(), false)
c.asm.Cmp_ge_n()
default:
panic("invalid comparison operator")
}
return ctype{Type: sqltypes.Int64, Flag: flagNullable | flagIsBoolean, Col: collationNumeric}, nil
}
func (expr *ComparisonExpr) compile(c *compiler) (ctype, error) {
lt, err := expr.Left.compile(c)
if err != nil {
return ctype{}, err
}
var skip1 *jump
switch expr.Op.(type) {
case compareNullSafeEQ:
default:
skip1 = c.compileNullCheck1(lt)
}
rt, err := expr.Right.compile(c)View on GitHub (pinned to 01a25a7d17)
Solutions
- Check which operator value hit the default branch and confirm it is valid for tuple comparison
- Add a case for the missing operator in compileAsTuple with the appropriate CmpTuple asm sequence
- Reject non-tuple-comparable operators earlier during typecheck so they fail with a proper error
- Rebuild generated IR code to ensure parser and compiler agree on operator values
Example fix
// before
case compareGE:
c.asm.CmpTuple(c.env.CollationEnv(), false)
c.asm.Cmp_ge_n()
default:
panic("invalid comparison operator")
// after
case compareGE:
c.asm.CmpTuple(c.env.CollationEnv(), false)
c.asm.Cmp_ge_n()
case compareNewOp:
c.asm.CmpTuple(c.env.CollationEnv(), false)
c.asm.Cmp_newop_n()
default:
panic("invalid comparison operator") Defensive patterns
Strategy: validation
Validate before calling
// Validate the comparison operator is one supported for tuples
func tupleComparable(op evalengine.ComparisonOp) bool {
switch op {
case evalengine.Equal, evalengine.NotEqual, evalengine.LessThan,
evalengine.LessEqual, evalengine.GreaterThan, evalengine.GreaterEqual:
return true
}
return false
} Type guard
func isTupleComparison(expr *evalengine.ComparisonExpr) (supported bool) {
_, lTuple := expr.Left.(evalengine.TupleExpr)
_, rTuple := expr.Right.(evalengine.TupleExpr)
return lTuple && rTuple && tupleComparable(expr.Operator)
} Try / catch
func safeCompileCompare(expr *evalengine.ComparisonExpr, c *compiler) (ct ctype, err error) {
defer func() {
if r := recover(); r != nil {
err = fmt.Errorf("compare compile panic: %v", r)
}
}()
return expr.compile(c)
} Prevention
- Only use standard SQL comparison operators in tuple comparisons
- Add a compile case whenever adding a new ComparisonOp
- Use exhaustive switch linting on operator switches
- Pin parser and evalengine to the same build
When it happens
Trigger: Compiling a ComparisonExpr with a comparison operator value not in the switch's cases while the compiler has chosen the tuple-comparison path (both operands are tuples). Typically only possible with a corrupted/extended operator enum or a new operator added without tuple support.
Common situations: Adding a new comparison operator to the IR without implementing compileAsTuple support; tests constructing ComparisonExpr with invalid operator constants; inconsistent generated code between parser and evalengine.
Related errors
- panic(err)
- unexpected comparison operator
- Value.ForEachValue on non-tuple
- malformed hex literal from parser
- bad unsigned integer type
AI-assisted analysis of vitessio/vitess@01a25a7d17 (2026-09-01).
Data as JSON: /api/errors/f33251b1d5c66a07.
Report an issue: GitHub.