{"record":{"id":"10fcd2f404ce3e5b","repo":"vitessio/vitess","slug":"switch-should-be-exhaustive","errorCode":null,"errorMessage":"switch should be exhaustive","messagePattern":"switch should be exhaustive","errorType":"panic","errorClass":null,"httpStatus":null,"severity":"error","filePath":"go/vt/sqlparser/ast_funcs.go","lineNumber":2948,"sourceCode":"\ntype visitor struct {\n\tidx int\n}\n\nfunc (v *visitor) visitAllSelects(in TableStatement, f func(p *Select, idx int) error) error {\n\tswitch sel := in.(type) {\n\tcase *Select:\n\t\terr := f(sel, v.idx)\n\t\tv.idx++\n\t\treturn err\n\tcase *Union:\n\t\terr := v.visitAllSelects(sel.Left, f)\n\t\tif err != nil {\n\t\t\treturn err\n\t\t}\n\t\treturn v.visitAllSelects(sel.Right, f)\n\t}\n\tpanic(\"switch should be exhaustive\")\n}\n\n// IsRestrict returns true if the reference action is of restrict type.\nfunc (ra ReferenceAction) IsRestrict() bool {\n\tswitch ra {\n\tcase Restrict, NoAction, DefaultAction:\n\t\treturn true\n\tdefault:\n\t\treturn false\n\t}\n}\n\n// IsCascade returns true if the reference action is of cascade type.\nfunc (ra ReferenceAction) IsCascade() bool {\n\tswitch ra {\n\tcase Cascade:\n\t\treturn true\n\tdefault:","sourceCodeStart":2930,"sourceCodeEnd":2966,"githubUrl":"https://github.com/vitessio/vitess/blob/01a25a7d176f94613b8d59d799f438380a8760e4/go/vt/sqlparser/ast_funcs.go#L2930-L2966","documentation":"visitAllSelects() walks a SelectStatement tree recursively and panics when it encounters a SelectStatement implementation not covered by its type switch. The switch is expected to handle every SelectStatement variant in the AST; an unhandled one means a new/unknown node type reached the visitor.","triggerScenarios":"Calling code that invokes the visitor path over a SelectStatement whose concrete type is not *Select, *Union, *SetOp, or whatever variants the switch handles — typically a newly added AST node type or a custom node injected into the tree.","commonSituations":"Running on a Vitess version where a new SelectStatement type was introduced but this internal visitor was not regenerated/updated; custom AST extensions in forks; stale generated code after a parser change without `make codegen`.","solutions":["Regenerate the sqlparser code with `make codegen` so the visitor covers all current SelectStatement variants","Update your Vitess version so the visitor and AST node types are from the same release","Find the custom/unknown node type in your AST tree and replace it with a supported SelectStatement","Extend visitAllSelects' switch to handle the missing variant and file/fix the upstream gap"],"exampleFix":"// before\nswitch sel := sel.(type) {\ncase *sqlparser.Select: ...\ncase *sqlparser.Union: ...\n} // falls through to panic on new node type\n// after\n// regenerate: make codegen\n// or add the variant:\ncase *sqlparser.NewSelectVariant: ...\n_ = sel","handlingStrategy":"validation","validationCode":"func isKnownSelect(sel sqlparser.SelectStatement) bool {\n    switch sel.(type) {\n    case *sqlparser.Select, *sqlparser.Union:\n        return true\n    default:\n        return false\n    }\n}","typeGuard":"func isSupportedSelect(sel sqlparser.SelectStatement) bool {\n    switch sel.(type) {\n    case *sqlparser.Select:\n        return true\n    case *sqlparser.Union:\n        return true\n    default:\n        return false\n    }\n}","tryCatchPattern":"func visitSelectsSafe(sel sqlparser.SelectStatement, f func(sqlparser.Select) error) (err error) {\n    defer func() {\n        if r := recover(); r != nil {\n            err = fmt.Errorf(\"visitor panicked: %v\", r)\n        }\n    }()\n    return visitAllSelects(sel, f)\n}","preventionTips":["Keep sqlparser generated files in sync via `make codegen`","Upgrade parser and AST together — never mix versions","Add a default-case test for your visitor over all AST node kinds","Reject unknown SelectStatement types at input boundaries"],"tags":["sqlparser","ast","visitor","panic","exhaustive-switch"],"backgroundTag":"non-exhaustive-switch-panic","analyzedSha":"01a25a7d176f94613b8d59d799f438380a8760e4","analyzedAt":"2026-09-01T17:28:30.605Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}