Skip to content

Commit 5fe4db8

Browse files
committed
fix(parser): parse qualified columns in GROUP BY
1 parent 4658415 commit 5fe4db8

3 files changed

Lines changed: 68 additions & 3 deletions

File tree

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

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7966,7 +7966,7 @@ ExpressionList SimpleExpressionList():
79667966
(
79677967
LOOKAHEAD(2, {!interrupted} ) ","
79687968
(
7969-
LOOKAHEAD( 7 ) expr=LambdaExpression()
7969+
LOOKAHEAD( RelObjectName() "->" ) expr=LambdaExpression()
79707970
|
79717971
expr=SimpleExpression()
79727972
)
@@ -8029,7 +8029,7 @@ ExpressionList ComplexExpressionList():
80298029
|
80308030
LOOKAHEAD(2) expr=PostgresNamedFunctionParameter()
80318031
|
8032-
LOOKAHEAD(7) expr=LambdaExpression()
8032+
LOOKAHEAD( RelObjectName() "->" ) expr=LambdaExpression()
80338033
|
80348034
expr=Expression()
80358035
) { expressions.add(expr); }

src/test/java/net/sf/jsqlparser/expression/LambdaExpressionTest.java

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
package net.sf.jsqlparser.expression;
1111

1212
import net.sf.jsqlparser.JSQLParserException;
13+
import net.sf.jsqlparser.statement.select.Select;
1314
import net.sf.jsqlparser.test.TestUtils;
1415
import org.junit.jupiter.api.Test;
1516

@@ -20,7 +21,10 @@ class LambdaExpressionTest {
2021
@Test
2122
void testLambdaFunctionSingleParameter() throws JSQLParserException {
2223
String sqlStr = "select list_transform( split('test', ''), x -> unicode(x) )";
23-
TestUtils.assertSqlCanBeParsedAndDeparsed(sqlStr, true);
24+
Select select = assertInstanceOf(
25+
Select.class, TestUtils.assertSqlCanBeParsedAndDeparsed(sqlStr, true));
26+
Function function = select.getPlainSelect().getSelectItem(0).getExpression(Function.class);
27+
assertInstanceOf(LambdaExpression.class, function.getParameters().get(1));
2428
}
2529

2630
@Test
@@ -52,4 +56,15 @@ void testLambdaFirstArgumentIssue2195() throws JSQLParserException {
5256
TestUtils.assertSqlCanBeParsedAndDeparsed(sqlStr, true);
5357
}
5458

59+
@Test
60+
void testLambdaFunctionFourParameters() throws JSQLParserException {
61+
String sqlStr = "SELECT list_transform([1], (a, b, c, d) -> a)";
62+
Select select = assertInstanceOf(
63+
Select.class, TestUtils.assertSqlCanBeParsedAndDeparsed(sqlStr, true));
64+
Function function = select.getPlainSelect().getSelectItem(0).getExpression(Function.class);
65+
LambdaExpression lambda =
66+
assertInstanceOf(LambdaExpression.class, function.getParameters().get(1));
67+
assertEquals(4, lambda.getIdentifiers().size());
68+
}
69+
5570
}

src/test/java/net/sf/jsqlparser/statement/select/SelectTest.java

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,7 @@
4343
import net.sf.jsqlparser.expression.IntervalExpression;
4444
import net.sf.jsqlparser.expression.JdbcNamedParameter;
4545
import net.sf.jsqlparser.expression.JdbcParameter;
46+
import net.sf.jsqlparser.expression.JsonExpression;
4647
import net.sf.jsqlparser.expression.LongValue;
4748
import net.sf.jsqlparser.expression.NotExpression;
4849
import net.sf.jsqlparser.expression.NullValue;
@@ -60,6 +61,7 @@
6061
import net.sf.jsqlparser.expression.operators.relational.GreaterThan;
6162
import net.sf.jsqlparser.expression.operators.relational.InExpression;
6263
import net.sf.jsqlparser.expression.operators.relational.LikeExpression;
64+
import net.sf.jsqlparser.expression.operators.relational.ParenthesedExpressionList;
6365
import net.sf.jsqlparser.parser.AbstractJSqlParser.Dialect;
6466
import net.sf.jsqlparser.parser.CCJSqlParserManager;
6567
import net.sf.jsqlparser.parser.CCJSqlParserUtil;
@@ -1375,6 +1377,47 @@ public void testGroupBy() throws JSQLParserException {
13751377
assertStatementCanBeDeparsedAs(select, statement);
13761378
}
13771379

1380+
@Test
1381+
public void testIssue2485OracleParenthesizedFullyQualifiedGroupByColumn()
1382+
throws JSQLParserException {
1383+
String sql = "SELECT sys.dual.dummy, count(*)\n"
1384+
+ "FROM sys.dual\n"
1385+
+ "GROUP BY (sys.dual.dummy), (sys.dual.dummy)";
1386+
1387+
Statement statement = TestUtils.assertSqlCanBeParsedAndDeparsed(sql, true);
1388+
Select select = assertInstanceOf(Select.class, statement);
1389+
PlainSelect plainSelect = select.getPlainSelect();
1390+
assertNotNull(plainSelect.getGroupBy());
1391+
1392+
ExpressionList<Expression> groupByExpressions = plainSelect.getGroupBy()
1393+
.getGroupByExpressionList();
1394+
assertEquals(2, groupByExpressions.size());
1395+
for (Expression groupByExpression : groupByExpressions) {
1396+
ParenthesedExpressionList<?> parenthesedExpression = assertInstanceOf(
1397+
ParenthesedExpressionList.class, groupByExpression);
1398+
Column column = assertInstanceOf(Column.class, parenthesedExpression.get(0));
1399+
assertEquals("sys.dual.dummy", column.getFullyQualifiedName());
1400+
}
1401+
}
1402+
1403+
@Test
1404+
public void testIssue2485OracleParenthesizedFourPartGroupByColumn()
1405+
throws JSQLParserException {
1406+
String sql = "SELECT 1\n"
1407+
+ "FROM sys.dual\n"
1408+
+ "GROUP BY sys.dual.dummy, (catalog.sys.dual.dummy)";
1409+
1410+
Statement statement = TestUtils.assertSqlCanBeParsedAndDeparsed(sql, true);
1411+
Select select = assertInstanceOf(Select.class, statement);
1412+
ExpressionList<Expression> groupByExpressions = select.getPlainSelect().getGroupBy()
1413+
.getGroupByExpressionList();
1414+
assertEquals(2, groupByExpressions.size());
1415+
ParenthesedExpressionList<?> parenthesedExpression = assertInstanceOf(
1416+
ParenthesedExpressionList.class, groupByExpressions.get(1));
1417+
Column column = assertInstanceOf(Column.class, parenthesedExpression.get(0));
1418+
assertEquals("catalog.sys.dual.dummy", column.getFullyQualifiedName());
1419+
}
1420+
13781421
@Test
13791422
public void testHaving() throws JSQLParserException {
13801423
String statement =
@@ -3205,6 +3248,13 @@ public void testJsonExpression() throws JSQLParserException {
32053248
assertSqlCanBeParsedAndDeparsed(
32063249
"SELECT json_typeof(sale->'items'), json_typeof(sale->'items'->'quantity') FROM sales");
32073250

3251+
Select jsonSelect = (Select) CCJSqlParserUtil.parse("SELECT data->'images' FROM instagram");
3252+
assertInstanceOf(JsonExpression.class,
3253+
jsonSelect.getPlainSelect().getSelectItem(0).getExpression());
3254+
jsonSelect = (Select) CCJSqlParserUtil.parse("SELECT data->>'images' FROM instagram");
3255+
assertInstanceOf(JsonExpression.class,
3256+
jsonSelect.getPlainSelect().getSelectItem(0).getExpression());
3257+
32083258
// The following staments can be parsed but not deparsed
32093259
for (String statement : new String[] {
32103260
"SELECT doc->'site_name' FROM websites WHERE doc @> '{\"tags\":[{\"term\":\"paris\"}, {\"term\":\"food\"}]}'",

0 commit comments

Comments
 (0)