Skip to content

Commit 3529b2f

Browse files
committed
Improve performance when parsing invalid queries
Use BailErrorStrategy as recommended by the ANTLR team.
1 parent b0a3bd9 commit 3529b2f

File tree

1 file changed

+36
-29
lines changed

1 file changed

+36
-29
lines changed

core/trino-parser/src/main/java/io/trino/sql/parser/SqlParser.java

Lines changed: 36 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@
2525
import io.trino.sql.tree.RowPattern;
2626
import io.trino.sql.tree.Statement;
2727
import org.antlr.v4.runtime.ANTLRErrorListener;
28+
import org.antlr.v4.runtime.BailErrorStrategy;
2829
import org.antlr.v4.runtime.BaseErrorListener;
2930
import org.antlr.v4.runtime.CharStreams;
3031
import org.antlr.v4.runtime.CommonToken;
@@ -39,6 +40,7 @@
3940
import org.antlr.v4.runtime.atn.PredictionMode;
4041
import org.antlr.v4.runtime.misc.Interval;
4142
import org.antlr.v4.runtime.misc.Pair;
43+
import org.antlr.v4.runtime.misc.ParseCancellationException;
4244
import org.antlr.v4.runtime.tree.TerminalNode;
4345

4446
import java.util.Arrays;
@@ -144,44 +146,16 @@ private Node invokeParser(String name, String sql, Optional<NodeLocation> locati
144146
SqlBaseParser parser = new SqlBaseParser(tokenStream);
145147
initializer.accept(lexer, parser);
146148

147-
// Override the default error strategy to not attempt inserting or deleting a token.
148-
// Otherwise, it messes up error reporting
149-
parser.setErrorHandler(new DefaultErrorStrategy()
150-
{
151-
@Override
152-
public Token recoverInline(Parser recognizer)
153-
throws RecognitionException
154-
{
155-
if (nextTokensContext == null) {
156-
throw new InputMismatchException(recognizer);
157-
}
158-
throw new InputMismatchException(recognizer, nextTokensState, nextTokensContext);
159-
}
160-
});
161-
162149
parser.addParseListener(new PostProcessor(Arrays.asList(parser.getRuleNames()), parser));
163150

164151
lexer.removeErrorListeners();
165152
lexer.addErrorListener(LEXER_ERROR_LISTENER);
166153

167154
parser.removeErrorListeners();
168-
parser.addErrorListener(PARSER_ERROR_HANDLER);
169155

170156
ParserRuleContext tree;
171157
try {
172-
try {
173-
// first, try parsing with potentially faster SLL mode
174-
parser.getInterpreter().setPredictionMode(PredictionMode.SLL);
175-
tree = parseFunction.apply(parser);
176-
}
177-
catch (ParsingException ex) {
178-
// if we fail, parse with LL mode
179-
tokenStream.seek(0); // rewind input stream
180-
parser.reset();
181-
182-
parser.getInterpreter().setPredictionMode(PredictionMode.LL);
183-
tree = parseFunction.apply(parser);
184-
}
158+
tree = twoStageParse(parseFunction, parser);
185159
}
186160
catch (ParsingException e) {
187161
location.ifPresent(statementLocation -> {
@@ -203,6 +177,39 @@ public Token recoverInline(Parser recognizer)
203177
}
204178
}
205179

180+
private static ParserRuleContext twoStageParse(Function<SqlBaseParser, ParserRuleContext> parseFunction, SqlBaseParser parser)
181+
{
182+
try {
183+
// first, try parsing with potentially faster SLL mode
184+
parser.getInterpreter().setPredictionMode(PredictionMode.SLL);
185+
parser.setErrorHandler(new BailErrorStrategy());
186+
return parseFunction.apply(parser);
187+
}
188+
catch (ParseCancellationException e) {
189+
// if we fail, parse with LL mode
190+
parser.reset();
191+
parser.getInterpreter().setPredictionMode(PredictionMode.LL);
192+
parser.setErrorHandler(new NonRecoveringErrorStrategy());
193+
parser.addErrorListener(PARSER_ERROR_HANDLER);
194+
return parseFunction.apply(parser);
195+
}
196+
}
197+
198+
// Override the default error strategy to not attempt inserting or deleting a token.
199+
// Otherwise, it messes up error reporting.
200+
private static final class NonRecoveringErrorStrategy
201+
extends DefaultErrorStrategy
202+
{
203+
@Override
204+
public Token recoverInline(Parser recognizer)
205+
{
206+
if (nextTokensContext == null) {
207+
throw new InputMismatchException(recognizer);
208+
}
209+
throw new InputMismatchException(recognizer, nextTokensState, nextTokensContext);
210+
}
211+
}
212+
206213
private static class PostProcessor
207214
extends SqlBaseBaseListener
208215
{

0 commit comments

Comments
 (0)