{"record":{"id":"662e04ccef244ae3","repo":"vitessio/vitess","slug":"invalid-intervaldateexpr-syntax","errorCode":null,"errorMessage":"invalid IntervalDateExpr syntax","messagePattern":"invalid IntervalDateExpr syntax","errorType":"panic","errorClass":null,"httpStatus":null,"severity":"error","filePath":"go/vt/sqlparser/ast_funcs.go","lineNumber":2840,"sourceCode":"\tdefault:\n\t\treturn \"Unknown GeomFromWktType\"\n\t}\n}\n\nfunc getAliasedTableExprFromTableName(tblName TableName) *AliasedTableExpr {\n\treturn &AliasedTableExpr{\n\t\tExpr: tblName,\n\t}\n}\n\nfunc (node *IntervalDateExpr) IsSubtraction() bool {\n\tswitch node.Syntax {\n\tcase IntervalDateExprDateAdd, IntervalDateExprAdddate, IntervalDateExprBinaryAdd, IntervalDateExprBinaryAddLeft, IntervalDateExprTimestampadd:\n\t\treturn false\n\tcase IntervalDateExprDateSub, IntervalDateExprSubdate, IntervalDateExprBinarySub:\n\t\treturn true\n\tdefault:\n\t\tpanic(\"invalid IntervalDateExpr syntax\")\n\t}\n}\n\nfunc (node *IntervalDateExpr) NormalizedUnit() IntervalType {\n\tif node.Unit == IntervalNone {\n\t\tif node.Syntax == IntervalDateExprAdddate || node.Syntax == IntervalDateExprSubdate {\n\t\t\treturn IntervalDay\n\t\t}\n\t\tpanic(\"IntervalDateExpr.Unit is not set\")\n\t}\n\treturn node.Unit\n}\n\nfunc (node *IntervalDateExpr) FnName() string {\n\tswitch node.Syntax {\n\tcase IntervalDateExprDateAdd:\n\t\treturn \"date_add\"\n\tcase IntervalDateExprDateSub:","sourceCodeStart":2822,"sourceCodeEnd":2858,"githubUrl":"https://github.com/vitessio/vitess/blob/01a25a7d176f94613b8d59d799f438380a8760e4/go/vt/sqlparser/ast_funcs.go#L2822-L2858","documentation":"IntervalDateExpr represents MySQL DATE_ADD/ADDATE/SUBDATE-family expressions; some helpers only make sense when the syntax is an add-family or sub-family form. When the Syntax field is none of the six known values (e.g. IntervalNone from an incompletely built AST node), the method panics rather than guessing.","triggerScenarios":"Calling the boolean is-add/sub helper method (on IntervalDateExpr at go/vt/sqlparser/ast_funcs.go:2840) on a node whose Syntax was never set, or on a Syntax constant added later without updating the switch.","commonSituations":"Hand-constructing sqlparser AST nodes in tests/tools without setting Syntax; a new IntervalDateExpr syntax variant introduced in the parser but not handled in ast_funcs.go switch statements; malformed queries bypassing normal parse paths.","solutions":["Always set Syntax explicitly when constructing an IntervalDateExpr programmatically","Update the switch (and NormalizedUnit) to handle any newly added IntervalDateExpr* constant","Check for recent parser changes adding a new syntax constant and extend the helper accordingly"],"exampleFix":"// before\nexpr := &sqlparser.IntervalDateExpr{Unit: sqlparser.IntervalDay} // Syntax unset\n_ = expr.IsBinarySyntax() // panics\n// after\nexpr := &sqlparser.IntervalDateExpr{Syntax: sqlparser.IntervalDateExprDateAdd, Unit: sqlparser.IntervalDay}","handlingStrategy":"validation","validationCode":"func validSyntax(s sqlparser.IntervalDateExprSyntax) bool {\n\tswitch s {\n\tcase sqlparser.IntervalDateExprDateAdd, sqlparser.IntervalDateExprAdddate, sqlparser.IntervalDateExprBinaryAdd,\n\t\tsqlparser.IntervalDateExprBinaryAddLeft, sqlparser.IntervalDateExprTimestampadd, sqlparser.IntervalDateExprDateSub,\n\t\tsqlparser.IntervalDateExprSubdate, sqlparser.IntervalDateExprBinarySub:\n\t\treturn true\n\t}\n\treturn false\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Never hand-build IntervalDateExpr without setting Syntax","After parser upgrades, grep for IntervalDateExpr constants not covered in ast_funcs.go switches","Construct AST nodes via parser helpers rather than struct literals"],"tags":["go","panic","sqlparser","ast","enum"],"backgroundTag":"unhandled-enum-case","analyzedSha":"01a25a7d176f94613b8d59d799f438380a8760e4","analyzedAt":"2026-09-01T17:28:30.605Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-08T10:18:20.063Z"}