vitessio/vitess · error

unknown ASTStep

Error message

unknown ASTStep

What it means

The generated ASTPath step-name resolver maps every ASTStep enum value to a string used for debugging/pretty-printing paths; an unknown step value falls out of the switch and panics. This indicates path corruption or a step enum produced by a mismatched code generation.

Source

Thrown at go/vt/sqlparser/ast_path.go:1777

		return "([]VindexParam)[]Offset"
	case SliceOfRefOfCommonTableExprOffset:
		return "([]*CommonTableExpr)[]Offset"
	case RefOfIndexColumnColumn:
		return "(*IndexColumn).Column"
	case RefOfIndexColumnExpression:
		return "(*IndexColumn).Expression"
	case RefOfIndexOptionValue:
		return "(*IndexOption).Value"
	case RefOfTableAndLockTypeTable:
		return "(*TableAndLockType).Table"
	case RefOfRenameTablePairFromTable:
		return "(*RenameTablePair).FromTable"
	case RefOfRenameTablePairToTable:
		return "(*RenameTablePair).ToTable"
	case VisitableInner:
		return "VisitableInner"
	}
	panic("unknown ASTStep")
}

func GetNodeFromPath(node SQLNode, path ASTPath) SQLNode {
	for len(path) >= 2 {
		step := path.nextPathStep()
		path = path[2:]
		switch step {
		case RefOfAddColumnsColumnsOffset:
			idx, bytesRead := path.nextPathOffset()
			path = path[bytesRead:]
			node = node.(*AddColumns).Columns[idx]
		case RefOfAddColumnsAfter:
			node = node.(*AddColumns).After
		case RefOfAddConstraintDefinitionConstraintDefinition:
			node = node.(*AddConstraintDefinition).ConstraintDefinition
		case RefOfAddIndexDefinitionIndexDefinition:
			node = node.(*AddIndexDefinition).IndexDefinition
		case RefOfAliasedExprExpr:

View on GitHub (pinned to 01a25a7d17)

Solutions

  1. Regenerate with `make codegen` so ASTStep constants and the name resolver come from the same generation
  2. Rebuild cached/persisted AST paths with the current parser version instead of reusing old ones
  3. Only construct ASTPaths via the official rewrite/collect APIs, never by hand with raw uint16 steps
  4. Pin all components (parser producer and consumer) to the same Vitess version

Example fix

// before
path := sqlparser.ASTPath{7, 3} // stale numeric steps
node := sqlparser.GetNodeFromPath(root, path)
// after
// collect fresh paths with the current build:
a := sqlparser.NewRewriter(...)
a.collectPaths = true
// use steps produced by a.CollectPaths(root), not persisted old values
Defensive patterns

Strategy: validation

Validate before calling

// Only use paths produced by the same build of the parser:
func withCollectedPaths(root sqlparser.SQLNode, fn func()) {
    // use sqlparser.RewriteOptions with CollectPaths enabled;
    // never persist or hand-craft ASTPath step values
    fn()
}

Try / catch

func nodeFromPathSafe(node sqlparser.SQLNode, path sqlparser.ASTPath) (res sqlparser.SQLNode, err error) {
    defer func() {
        if r := recover(); r != nil {
            err = fmt.Errorf("path resolution panicked: %v", r)
        }
    }()
    return sqlparser.GetNodeFromPath(node, path), nil
}

Prevention

When it happens

Trigger: Calling GetNodeFromPath (or path-name printing helpers) with an ASTPath containing a step value that is not a known ASTStep constant — e.g. paths built by a different parser build/version, or paths persisted across a regen that shifted enum numbering.

Common situations: Caching AST paths between Vitess versions; mixing generated files from different codegen runs; custom tools that fabricate ASTStep values numerically.

Related errors


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