vitessio/vitess · error

unsupported select expression: %v

Error message

unsupported select expression: %v

What it means

While matching a vindex column against the SELECT list in matchColInSelect, an AST node type was encountered that is not a SelectExpr the matcher supports (e.g. a star expression in an unexpected position or another node kind in the select expression union). The matcher treats this as unsupported and errors out.

Source

Thrown at go/vt/wrangler/materializer.go:1494

		case *sqlparser.AliasedExpr:
			match := selExpr.As
			if match.IsEmpty() {
				if colExpr, ok := selExpr.Expr.(*sqlparser.ColName); ok {
					match = colExpr.Name
				} else {
					// Cannot match against a complex expression.
					continue
				}
			}
			if match.Equal(col) {
				colExpr, ok := selExpr.Expr.(*sqlparser.ColName)
				if !ok {
					return nil, fmt.Errorf("vindex column cannot be a complex expression: %v", sqlparser.String(selExpr))
				}
				return colExpr, nil
			}
		default:
			return nil, fmt.Errorf("unsupported select expression: %v", sqlparser.String(selExpr))
		}
	}
	return nil, fmt.Errorf("could not find vindex column %v", sqlparser.String(col))
}

func (mz *materializer) createStreams(ctx context.Context, insertsMap map[string]string) error {
	return mz.forAllTargets(func(target *topo.ShardInfo) error {
		inserts := insertsMap[target.ShardName()]
		targetPrimary, err := mz.wr.ts.GetTablet(ctx, target.PrimaryAlias)
		if err != nil {
			return vterrors.Wrapf(err, "GetTablet(%v) failed", target.PrimaryAlias)
		}
		buf := &strings.Builder{}
		t := template.Must(template.New("").Parse(inserts))
		input := map[string]string{
			"keyrange": key.KeyRangeString(target.KeyRange),
			"dbname":   targetPrimary.DbName(),
		}

View on GitHub (pinned to 01a25a7d17)

Solutions

  1. Rewrite SourceExpression as a simple `select col1, col2, ... from table [where ...]` explicitly listing columns including the vindex columns
  2. Avoid star/derived constructs in the select list when configuring materialization
  3. Test the expression through the same workflow path before production runs

Example fix

// before
{"sourceExpression":"select s.* from s"}
// after
{"sourceExpression":"select id, name, email from s"}
Defensive patterns

Strategy: validation

Validate before calling

func validSimpleSelect(p *sqlparser.Parser, expr string) error {
    stmt, err := p.Parse(expr)
    if err != nil { return err }
    sel, ok := stmt.(*sqlparser.Select)
    if !ok { return fmt.Errorf("not a select") }
    for _, e := range sel.SelectExprs {
        switch e.(type) {
        case *sqlparser.AliasedExpr, *sqlparser.StarExpr:
        default:
            return fmt.Errorf("unsupported select expr")
        }
    }
    return nil
}

Prevention

When it happens

Trigger: SourceExpression select list contains node kinds matchColInSelect's switch does not handle — typically reached via generateInserts when resolving the primary vindex columns for a sharded target table.

Common situations: Complex SourceExpression filters written programmatically; parser version differences producing AST shapes the matcher doesn't expect; exotic select items (e.g. `*.col` style constructs).

Related errors


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