@@ -69,7 +69,7 @@ func (m *Manager) Analyze(sql string, indexes []model.IndexInfo) []model.SqlDiag
6969
7070 // Use SLL prediction mode for better performance, fallback to LL if it fails
7171 p .GetInterpreter ().SetPredictionMode (antlr .PredictionModeSLL )
72- p .SetErrorHandler (antlr . NewBailErrorStrategy ())
72+ p .SetErrorHandler (NewCustomBailErrorStrategy ())
7373
7474 // Parse the SQL (assuming 'Sql_stmt' is the entry point rule)
7575 parseStart := time .Now ()
@@ -78,11 +78,16 @@ func (m *Manager) Analyze(sql string, indexes []model.IndexInfo) []model.SqlDiag
7878 defer func () {
7979 if r := recover (); r != nil {
8080 // Fallback to LL prediction mode
81- stream .Seek (0 )
82- p .SetTokenStream (stream )
83- p .GetInterpreter ().SetPredictionMode (antlr .PredictionModeLL )
84- p .SetErrorHandler (antlr .NewDefaultErrorStrategy ())
85- tree = p .Sql_stmt ()
81+ // Recreate the entire stack to ensure no state pollution
82+ inputStream := antlr .NewInputStream (sql )
83+ lexer := obmysql .NewOBLexer (inputStream )
84+ stream := antlr .NewCommonTokenStream (lexer , antlr .TokenDefaultChannel )
85+
86+ p2 := obmysql .NewOBParser (stream )
87+ p2 .RemoveErrorListeners ()
88+ p2 .GetInterpreter ().SetPredictionMode (antlr .PredictionModeLL )
89+ p2 .SetErrorHandler (antlr .NewDefaultErrorStrategy ())
90+ tree = p2 .Sql_stmt ()
8691 }
8792 }()
8893 tree = p .Sql_stmt ()
@@ -113,3 +118,19 @@ func (m *Manager) Analyze(sql string, indexes []model.IndexInfo) []model.SqlDiag
113118
114119 return diagnostics
115120}
121+
122+ type CustomBailErrorStrategy struct {
123+ * antlr.BailErrorStrategy
124+ }
125+
126+ func NewCustomBailErrorStrategy () * CustomBailErrorStrategy {
127+ return & CustomBailErrorStrategy {
128+ BailErrorStrategy : antlr .NewBailErrorStrategy (),
129+ }
130+ }
131+
132+ func (s * CustomBailErrorStrategy ) ReportError (_ antlr.Parser , _ antlr.RecognitionException ) {
133+ // Avoid calling DefaultErrorStrategy.ReportError which might panic with "implement me"
134+ // Instead, explicitly bail out with ParseCancellationException, which is what BailErrorStrategy intends.
135+ panic (antlr .NewParseCancellationException ())
136+ }
0 commit comments