Skip to content

Commit a7a1d12

Browse files
refactor: AndExpression and LimitWithOffset and better ParenthesedSelect lookahead
Signed-off-by: Andreas Reichel <andreas@manticore-projects.com> Signed-off-by: manticore-projects <andreas@manticore-projects.com>
1 parent 7b87d08 commit a7a1d12

File tree

1 file changed

+52
-14
lines changed

1 file changed

+52
-14
lines changed

src/main/jjtree/net/sf/jsqlparser/parser/JSqlParserCC.jjt

Lines changed: 52 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -211,6 +211,17 @@ public class CCJSqlParser extends AbstractJSqlParser<CCJSqlParser> {
211211
default: return false;
212212
}
213213
}
214+
215+
protected boolean isParenthesedSelectAhead() {
216+
if (getToken(1).kind != OPENING_BRACKET) {
217+
return false;
218+
}
219+
int nextKind = getToken(2).kind;
220+
return nextKind == K_SELECT
221+
|| nextKind == K_WITH
222+
|| nextKind == K_VALUES
223+
|| nextKind == K_FROM;
224+
}
214225
}
215226

216227
PARSER_END(CCJSqlParser)
@@ -5700,23 +5711,32 @@ JdbcParameter JdbcParameter() : {
57005711
Limit LimitWithOffset() #LimitWithOffset:
57015712
{
57025713
Limit limit = new Limit();
5703-
Expression rowCountExpression;
5704-
Expression offsetExpression;
5714+
Expression firstExpression;
5715+
Expression secondExpression;
57055716
}
57065717
{
5718+
<K_LIMIT>
57075719
(
5708-
LOOKAHEAD(<K_LIMIT> Expression() "," Expression()) (
5709-
// mysql-> LIMIT offset,row_count
5710-
<K_LIMIT>
5711-
offsetExpression=Expression() { limit.setOffset( offsetExpression ); }
5712-
","
5713-
rowCountExpression=Expression() { limit.setRowCount( rowCountExpression ); }
5714-
)
5720+
LOOKAHEAD(3) firstExpression = ParenthesedSelect()
5721+
|
5722+
firstExpression = Expression()
5723+
)
5724+
(
5725+
// MySQL: LIMIT offset, row_count
5726+
","
5727+
secondExpression = Expression()
5728+
{
5729+
limit.setOffset(firstExpression);
5730+
limit.setRowCount(secondExpression);
5731+
}
57155732
|
5716-
limit = PlainLimit()
5733+
// PostgreSQL: LIMIT row_count
5734+
{
5735+
limit.setRowCount(firstExpression);
5736+
}
57175737
)
57185738
{
5719-
linkAST(limit,jjtThis);
5739+
linkAST(limit, jjtThis);
57205740
return limit;
57215741
}
57225742
}
@@ -6007,10 +6027,23 @@ Expression AndExpression() :
60076027
{
60086028
Expression left, right, result;
60096029
boolean not = false;
6010-
boolean exclamationMarkNot=false;
6030+
boolean exclamationMarkNot=false;
60116031
}
60126032
{
60136033
(
6034+
// Fast path: when NOT starting with ( or NOT/!, Condition() always succeeds
6035+
// (PrimaryExpression can always match an identifier, literal, CASE, etc.)
6036+
// No speculative parsing needed — go directly.
6037+
LOOKAHEAD({ getToken(1).kind != OPENING_BRACKET
6038+
&& getToken(1).kind != K_NOT
6039+
&& !getToken(1).image.equals("!") })
6040+
left=Condition()
6041+
|
6042+
// Slow path: ( or NOT might introduce a parenthesized boolean expression
6043+
// that Condition() can't handle (because ParenthesedExpressionList uses
6044+
// SimpleExpression which doesn't support LIKE/IN/BETWEEN/IS).
6045+
// Try Condition() first (handles "( a + b ) > 5"), fall back to
6046+
// "(" XorExpression() ")" (handles "( value LIKE '%x%' )").
60146047
LOOKAHEAD(Condition(), {!interrupted}) left=Condition()
60156048
|
60166049
[ <K_NOT> { not=true; } | "!" { not=true; exclamationMarkNot=true; } ]
@@ -6022,6 +6055,11 @@ Expression AndExpression() :
60226055
{ boolean useOperator = false; }
60236056
(<K_AND> | <OP_DOUBLEAND> {useOperator=true;} )
60246057
(
6058+
LOOKAHEAD({ getToken(1).kind != OPENING_BRACKET
6059+
&& getToken(1).kind != K_NOT
6060+
&& !getToken(1).image.equals("!") })
6061+
right=Condition()
6062+
|
60256063
LOOKAHEAD(Condition(), {!interrupted}) right=Condition()
60266064
|
60276065
[ <K_NOT> { not=true; } | "!" { not=true; exclamationMarkNot=true; } ]
@@ -6296,7 +6334,7 @@ Expression Between(Expression leftExpression) :
62966334
)
62976335
]
62986336
(
6299-
LOOKAHEAD( ParenthesedSelect() ) betweenExpressionStart = ParenthesedSelect()
6337+
LOOKAHEAD({ isParenthesedSelectAhead() }) betweenExpressionStart = ParenthesedSelect()
63006338
|
63016339
betweenExpressionStart = SimpleExpression()
63026340
[
@@ -6307,7 +6345,7 @@ Expression Between(Expression leftExpression) :
63076345

63086346
<K_AND>
63096347
(
6310-
LOOKAHEAD( ParenthesedSelect() ) betweenExpressionEnd = ParenthesedSelect()
6348+
LOOKAHEAD({ isParenthesedSelectAhead() }) betweenExpressionEnd = ParenthesedSelect()
63116349
|
63126350
betweenExpressionEnd = SimpleExpression()
63136351
[

0 commit comments

Comments
 (0)