vitessio/vitess · error

unexpected: %v

Error message

unexpected: %v

What it means

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>'.

Source

Thrown at go/vt/vttablet/tabletserver/vstreamer/planbuilder.go:618

		return err
	}
	env := evalengine.EmptyExpressionEnv(plan.env)
	resolved, err := env.Evaluate(pv)
	if err != nil {
		return err
	}
	plan.Filters = append(plan.Filters, Filter{
		Opcode: opcode,
		ColNum: colnum,
		Values: resolved.TupleValues(),
	})
	return nil
}

func (plan *Plan) getEvalResultForLiteral(expr sqlparser.Expr) (*evalengine.EvalResult, error) {
	literalExpr, ok := expr.(*sqlparser.Literal)
	if !ok {
		return nil, fmt.Errorf("unexpected: %v", sqlparser.String(expr))
	}
	pv, err := evalengine.Translate(literalExpr, &evalengine.Config{
		Collation:   plan.env.CollationEnv().DefaultConnectionCharset(),
		Environment: plan.env,
	})
	if err != nil {
		return nil, err
	}
	env := evalengine.EmptyExpressionEnv(plan.env)
	resolved, err := env.Evaluate(pv)
	return &resolved, err
}

func (plan *Plan) analyzeWhere(vschema *localVSchema, where *sqlparser.Where) error {
	if where == nil {
		return nil
	}
	// Only a series of AND expressions are supported.

View on GitHub (pinned to 01a25a7d17)

Solutions

  1. Replace the right-hand side with a literal constant: col = 'value' or col IN (1,2,3)
  2. Precompute function results into constants before configuring the filter
  3. Review the supported predicate forms in planbuilder.go (col op literal, col IN tuple)

Example fix

// before
where updated_at > now()
// after
where updated_at > '2024-01-01 00:00:00'
Defensive patterns

Strategy: validation

Validate before calling

// ensure predicates compare column op literal
for _, p := range predicates {
    if _, ok := p.right.(sqlparser.Literal); !ok {
        return fmt.Errorf("right side must be a literal: %v", sqlparser.String(p.right))
    }
}

Prevention

When it happens

Trigger: 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.

Common situations: Filters written with function calls or column-to-column comparisons; users assuming full SQL expression support in VReplication filters.

Related errors


AI-assisted analysis of vitessio/vitess@01a25a7d17 (2026-09-01). Data as JSON: /api/errors/94817a52ef854158. Report an issue: GitHub.