diff --git a/src/main/jjtree/net/sf/jsqlparser/parser/JSqlParserCC.jjt b/src/main/jjtree/net/sf/jsqlparser/parser/JSqlParserCC.jjt index 2a28d21ba..fc0f1a77a 100644 --- a/src/main/jjtree/net/sf/jsqlparser/parser/JSqlParserCC.jjt +++ b/src/main/jjtree/net/sf/jsqlparser/parser/JSqlParserCC.jjt @@ -5053,6 +5053,9 @@ LateralView LateralView() #LateralView: [ LOOKAHEAD(2) "," { columnAlias.setName(null); columnAlias.addAliasColumns( columnName); } columnName = RelObjectName() { columnAlias.addAliasColumns( columnName); } + ( + LOOKAHEAD(2) "," columnName = RelObjectName() { columnAlias.addAliasColumns( columnName); } + )* ] { return new LateralView( diff --git a/src/test/java/net/sf/jsqlparser/statement/select/HiveTest.java b/src/test/java/net/sf/jsqlparser/statement/select/HiveTest.java index 98140fc71..30cdd925e 100644 --- a/src/test/java/net/sf/jsqlparser/statement/select/HiveTest.java +++ b/src/test/java/net/sf/jsqlparser/statement/select/HiveTest.java @@ -9,13 +9,16 @@ */ package net.sf.jsqlparser.statement.select; -import net.sf.jsqlparser.schema.Table; -import org.junit.jupiter.api.Test; - import static net.sf.jsqlparser.test.TestUtils.assertSqlCanBeParsedAndDeparsed; import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertNotNull; +import static org.junit.jupiter.api.Assertions.assertNull; import static org.junit.jupiter.api.Assertions.assertTrue; +import net.sf.jsqlparser.expression.Alias; +import net.sf.jsqlparser.schema.Table; +import org.junit.jupiter.api.Test; + public class HiveTest { @Test @@ -54,4 +57,30 @@ public void testGroupSimplified() throws Exception { + "GROUP BY GROUPING SETS (())"; assertSqlCanBeParsedAndDeparsed(sql, true); } + + @Test + public void testLateralViewManyColumnAliasesIssue2433() throws Exception { + // Hive/Spark LATERAL VIEW allows an arbitrary number of column aliases + // (e.g. json_tuple yielding many columns). Only the first two were absorbed; + // any further aliases leaked into the FROM clause as implicit cross-join + // tables, so the failure was silent and even round-tripped identically. + String sql = "SELECT a FROM t" + + " LATERAL VIEW json_tuple(j, 'a', 'b', 'c', 'd', 'e', 'f', 'g')" + + " x AS c1, c2, c3, c4, c5, c6, c7"; + + Select select = (Select) assertSqlCanBeParsedAndDeparsed(sql, true); + PlainSelect plainSelect = (PlainSelect) select.getSelectBody(); + + // The extra aliases must not leak as cross-join tables. + assertNull(plainSelect.getJoins()); + + java.util.List lateralViews = plainSelect.getLateralViews(); + assertNotNull(lateralViews); + assertEquals(1, lateralViews.size()); + + Alias columnAlias = lateralViews.get(0).getColumnAlias(); + assertNotNull(columnAlias); + assertNotNull(columnAlias.getAliasColumns()); + assertEquals(7, columnAlias.getAliasColumns().size()); + } }