@@ -184,6 +184,28 @@ TOKEN_MGR_DECLS : {
184184 }
185185 }
186186
187+ // Finds first occurrence of "\\'"
188+ public static int indexOfSequence(String s, String target) {
189+ int len = s.length();
190+ for (int i = 0; i < len - 1; i++) {
191+ if (s.charAt(i) == '\\' && s.charAt(i + 1) == '\'') {
192+ return i;
193+ }
194+ }
195+ return -1;
196+ }
197+
198+ // Finds last occurrence of "\\''"
199+ public static int lastIndexOfSequence(String s, String target) {
200+ int len = s.length();
201+ for (int i = len - 3; i >= 0; i--) {
202+ if (s.charAt(i) == '\\' && s.charAt(i + 1) == '\'' && s.charAt(i + 2) == '\'') {
203+ return i;
204+ }
205+ }
206+ return -1;
207+ }
208+
187209 public void CommonTokenAction(Token t)
188210 {
189211 t.absoluteBegin = getCurrentTokenAbsolutePosition();
@@ -757,22 +779,26 @@ TOKEN:
757779 // which contains the <SPECIAL_ESC>, then we will need to
758780 // 1) break the <S_CHAR_LITERAL> at <SPECIAL_ESC> close it with a "'"
759781 // 2) continue tokenizing after that <SPECIAL_ESC> with a new <S_CHAR_LITERAL> or any other Token
760- if ( !configuration.getAsBoolean(Feature.allowBackslashEscapeCharacter)
761- && matchedToken.image.contains("\\'") ) {
762-
763- matchedToken.image = "'" + image.substring( 0, image.indexOf("\\'") + 1 ) + "'";
764- // `charLiteralIndex` defined in TokenManagerDeclaration above
765- matchedToken.kind = charLiteralIndex;
766- input_stream.backup(image.length() + 1 - matchedToken.image.length());
767-
768- } else if ( configuration.getAsBoolean(Feature.allowBackslashEscapeCharacter)
769- && matchedToken.image.contains("\\''") ) {
770-
771- matchedToken.image = "'" + image.substring( 0, image.lastIndexOf("\\'") + 3);
772- // `charLiteralIndex` defined in TokenManagerDeclaration above
773- matchedToken.kind = charLiteralIndex;
774- input_stream.backup(image.length() + 1 - matchedToken.image.length() );
775- }
782+ boolean allowEscape = configuration.getAsBoolean(Feature.allowBackslashEscapeCharacter);
783+ String img = matchedToken.image;
784+ int pos;
785+ if (!allowEscape) {
786+ pos = indexOfSequence(img, "\\'");
787+ if (pos > 0) {
788+ matchedToken.image = "'" + image.substring( 0, image.indexOf("\\'") + 1 ) + "'";
789+ // `charLiteralIndex` defined in TokenManagerDeclaration above
790+ matchedToken.kind = charLiteralIndex;
791+ input_stream.backup(image.length() + 1 - matchedToken.image.length());
792+ }
793+ } else {
794+ pos = lastIndexOfSequence(img, "\\''");
795+ if (pos > 0) {
796+ matchedToken.image = "'" + image.substring( 0, image.lastIndexOf("\\'") + 3);
797+ // `charLiteralIndex` defined in TokenManagerDeclaration above
798+ matchedToken.kind = charLiteralIndex;
799+ input_stream.backup(image.length() + 1 - matchedToken.image.length() );
800+ }
801+ }
776802 }
777803| < S_QUOTED_IDENTIFIER: "\"" ( "\"\"" | ~["\n","\r","\""])* "\"" | "$$" (~["$"])* "$$" | ("`" (~["\n","\r","`"])+ "`") | ( "[" (~["\n","\r","]"])* "]" ) >
778804 {
@@ -2414,16 +2440,12 @@ Select Select() #Select:
24142440 Alias alias = null;
24152441}
24162442{
2417- (
24182443
2419- //@todo: avoid this expensive semantic look ahead
2420- LOOKAHEAD( [ WithList() ] FromQuery()) (
2421- [ with=WithList() ]
2422- select = FromQuery()
2423- )
2444+ [ with=WithList() ]
2445+ (
2446+ LOOKAHEAD(3) select = FromQuery()
24242447 |
24252448 (
2426- [ with=WithList() ]
24272449 (
24282450 LOOKAHEAD(3) select = PlainSelect()
24292451 |
@@ -4998,7 +5020,6 @@ ExpressionList SimpleExpressionList():
49985020 (
49995021 LOOKAHEAD(2, {!interrupted} ) ","
50005022 (
5001- // @todo: Check hot to avoid this expensive look ahead
50025023 LOOKAHEAD( 6 ) expr=LambdaExpression()
50035024 |
50045025 expr=SimpleExpression()
@@ -5058,7 +5079,6 @@ ExpressionList ComplexExpressionList():
50585079 (
50595080 LOOKAHEAD(2) expr=OracleNamedFunctionParameter()
50605081 |
5061- // @todo: Check hot to avoid this expensive look ahead
50625082 LOOKAHEAD( 6 ) expr=LambdaExpression()
50635083 | expr=Expression()
50645084 ) { expressions.add(expr); }
@@ -5404,7 +5424,9 @@ Expression PrimaryExpression() #PrimaryExpression:
54045424
54055425 | LOOKAHEAD(16) retval=AllTableColumns()
54065426
5407- // | LOOKAHEAD(250) retval=FunctionAllColumns()
5427+ // See issue #2207
5428+ // there is a huge! performance deterioration from this production
5429+ //| LOOKAHEAD(FunctionAllColumns()) retval=FunctionAllColumns()
54085430
54095431 // support timestamp expressions
54105432 | LOOKAHEAD(2, {!interrupted}) (token=<K_TIME_KEY_EXPR> | token=<K_CURRENT>) { retval = new TimeKeyExpression(token.image); }
0 commit comments