Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
28 changes: 5 additions & 23 deletions src/main/jjtree/net/sf/jsqlparser/parser/JSqlParserCC.jjt
Original file line number Diff line number Diff line change
Expand Up @@ -12715,23 +12715,9 @@ ExpressionList ExpressionList() #ExpressionList:
ExpressionList expressionList;
}
{
(
LOOKAHEAD(3, { !interrupted }) expressionList = ComplexExpressionList()
|
LOOKAHEAD(3) expressionList = SimpleExpressionList()
|
LOOKAHEAD(3) expressionList = ParenthesedExpressionList()
|
// Fallback, see isUnparenthesizedSelectAhead(): the three probes above are
// syntactic and cannot see through the Pratt operator loop, which lives in a
// Java action. They all fail on a bracketed operand of a larger expression,
// e.g. "( 1 + a ) / ( 1 + b )" or "( 1 + a )" - the third token is an operator
// where the probe expects "," or ")". Such input is still a valid expression
// list, so parse it as one instead of raising a ParseException.
LOOKAHEAD({ !interrupted }) expressionList = ComplexExpressionList()
|
expressionList = SimpleExpressionList()
)
// ComplexExpressionList() parses every list form, "()" and bracketed operands such as
// "( 1 + a ) / ( 1 + b )" included.
expressionList = ComplexExpressionList()
{
// Avoid redundant ExpressionLists containing only one ParenthesedExpressionList
// return the Parenthesed Sub ExpressionList instead
Expand Down Expand Up @@ -12763,11 +12749,7 @@ ParenthesedExpressionList ParenthesedExpressionList():
}
{
"("
(
LOOKAHEAD({ !interrupted }) expressions = ComplexExpressionList()
|
expressions = SimpleExpressionList()
)?
[ LOOKAHEAD({ getToken(1).kind != CLOSING_BRACKET }) expressions = ComplexExpressionList() ]
")"
{
return new ParenthesedExpressionList(expressions);
Expand Down Expand Up @@ -12835,7 +12817,7 @@ ExpressionList ComplexExpressionList():
|
LOOKAHEAD(2, { isNamedParameterAssignmentAhead() }) expr=PostgresNamedFunctionParameter()
|
// JavaCC scans an unguarded alternative's first token; a semantic-only lookahead enters directly
// The semantic lookahead makes JavaCC enter Expression() with no scan of its first token.
LOOKAHEAD({ !interrupted }) expr=Expression()
)
{
Expand Down
10 changes: 10 additions & 0 deletions src/test/java/net/sf/jsqlparser/expression/FunctionTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -157,4 +157,14 @@ void testAesDecryptWithKeyExpressionInSelect() throws JSQLParserException {

TestUtils.assertSqlCanBeParsedAndDeparsed(sqlStr, true);
}

@Test
void testBracketedOperandAndEmptyListArguments() throws JSQLParserException {
TestUtils.assertSqlCanBeParsedAndDeparsed(
"SELECT f((1 + a) / (1 + b), (c + d) * 2) FROM t", true);

TestUtils.assertSqlCanBeParsedAndDeparsed("SELECT f(()) FROM t", true);

TestUtils.assertSqlCanBeParsedAndDeparsed("INSERT INTO t VALUES ()", true);
}
}
Loading