From c894aa6fe8ed9f459b2f2f6801976776cd53f7c8 Mon Sep 17 00:00:00 2001 From: Andreas Reichel Date: Thu, 9 Jun 2022 22:01:00 +0700 Subject: [PATCH 1/2] Postgres NATURAL LEFT/RIGHT joins Fixes #1559 Make NATURAL an optional Join Keyword, which can be combined with LEFT, RIGHT, INNER Add tests --- .../sf/jsqlparser/statement/select/Join.java | 6 ++- .../util/deparser/SelectDeParser.java | 6 ++- .../net/sf/jsqlparser/parser/JSqlParserCC.jjt | 39 ++++++++++++------- .../statement/select/SelectTest.java | 13 +++++++ .../statement/select/oracle-tests/join21.sql | 3 +- 5 files changed, 49 insertions(+), 18 deletions(-) diff --git a/src/main/java/net/sf/jsqlparser/statement/select/Join.java b/src/main/java/net/sf/jsqlparser/statement/select/Join.java index 4c6d74ffc..7c4200bef 100644 --- a/src/main/java/net/sf/jsqlparser/statement/select/Join.java +++ b/src/main/java/net/sf/jsqlparser/statement/select/Join.java @@ -304,10 +304,12 @@ public String toString() { } else if (isSimple()) { builder.append(rightItem); } else { + if (isNatural()) { + builder.append("NATURAL "); + } + if (isRight()) { builder.append("RIGHT "); - } else if (isNatural()) { - builder.append("NATURAL "); } else if (isFull()) { builder.append("FULL "); } else if (isLeft()) { diff --git a/src/main/java/net/sf/jsqlparser/util/deparser/SelectDeParser.java b/src/main/java/net/sf/jsqlparser/util/deparser/SelectDeParser.java index 055f610a4..7889a3369 100644 --- a/src/main/java/net/sf/jsqlparser/util/deparser/SelectDeParser.java +++ b/src/main/java/net/sf/jsqlparser/util/deparser/SelectDeParser.java @@ -401,10 +401,12 @@ public void deparseJoin(Join join) { buffer.append(", "); } else { + if (join.isNatural()) { + buffer.append(" NATURAL"); + } + if (join.isRight()) { buffer.append(" RIGHT"); - } else if (join.isNatural()) { - buffer.append(" NATURAL"); } else if (join.isFull()) { buffer.append(" FULL"); } else if (join.isLeft()) { diff --git a/src/main/jjtree/net/sf/jsqlparser/parser/JSqlParserCC.jjt b/src/main/jjtree/net/sf/jsqlparser/parser/JSqlParserCC.jjt index c2da5b3ab..839b946c6 100644 --- a/src/main/jjtree/net/sf/jsqlparser/parser/JSqlParserCC.jjt +++ b/src/main/jjtree/net/sf/jsqlparser/parser/JSqlParserCC.jjt @@ -2579,24 +2579,37 @@ Join JoinerExpression() #JoinerExpression: } { - + [ { join.setNatural(true); } ] [ - { join.setLeft(true); } [ { join.setSemi(true); } | { join.setOuter(true); } ] - | ( { join.setRight(true); } - | { join.setFull(true); } - ) [ { join.setOuter(true); } ] - | { join.setInner(true); } - | { join.setNatural(true); } - | { join.setCross(true); } - | { join.setOuter(true); } + ( + { join.setLeft(true); } [ { join.setSemi(true); } | { join.setOuter(true); } ] + | + ( + { join.setRight(true); } + | + { join.setFull(true); } + ) [ { join.setOuter(true); } ] + | + { join.setInner(true); } + ) + | + { join.setCross(true); } + | + { join.setOuter(true); } ] - ( | "," { join.setSimple(true); } ( { join.setOuter(true); } )? - | { join.setStraight(true); } | {join.setApply(true); } ) - - right=FromItem() + ( + + | + "," { join.setSimple(true); } ( { join.setOuter(true); } )? + | + { join.setStraight(true); } + | + {join.setApply(true); } + ) + right=FromItem() [ LOOKAHEAD(2) ( diff --git a/src/test/java/net/sf/jsqlparser/statement/select/SelectTest.java b/src/test/java/net/sf/jsqlparser/statement/select/SelectTest.java index 78402b8fc..0858b7ec6 100644 --- a/src/test/java/net/sf/jsqlparser/statement/select/SelectTest.java +++ b/src/test/java/net/sf/jsqlparser/statement/select/SelectTest.java @@ -5213,4 +5213,17 @@ public void testLoclTimezone1471() throws JSQLParserException { public void testMissingLimitIssue1505() throws JSQLParserException { assertSqlCanBeParsedAndDeparsed("(SELECT * FROM mytable) LIMIT 1"); } + + @Test + public void testPostgresNaturalJoinIssue1559() throws JSQLParserException { + assertSqlCanBeParsedAndDeparsed( + "SELECT t1.ID,t1.name, t2.DID, t2.name\n" + + "FROM table1 as t1\n" + + "NATURAL RIGHT JOIN table2 as t2", true); + + assertSqlCanBeParsedAndDeparsed( + "SELECT t1.ID,t1.name, t2.DID, t2.name\n" + + "FROM table1 as t1\n" + + "NATURAL RIGHT JOIN table2 as t2", true); + } } diff --git a/src/test/resources/net/sf/jsqlparser/statement/select/oracle-tests/join21.sql b/src/test/resources/net/sf/jsqlparser/statement/select/oracle-tests/join21.sql index c17cfc6d2..29a8425aa 100644 --- a/src/test/resources/net/sf/jsqlparser/statement/select/oracle-tests/join21.sql +++ b/src/test/resources/net/sf/jsqlparser/statement/select/oracle-tests/join21.sql @@ -10,4 +10,5 @@ select * from sys.dual natural join sys.dual ---@SUCCESSFULLY_PARSED_AND_DEPARSED first on Aug 3, 2021, 7:20:08 AM \ No newline at end of file +--@SUCCESSFULLY_PARSED_AND_DEPARSED first on Aug 3, 2021, 7:20:08 AM +--@FAILURE: Encountered unexpected token: "natural" "NATURAL" recorded first on 9 Jun 2022, 21:50:07 \ No newline at end of file From 643e038981461084ca8cb40496f645df34a7039c Mon Sep 17 00:00:00 2001 From: Andreas Reichel Date: Thu, 9 Jun 2022 22:09:58 +0700 Subject: [PATCH 2/2] Postgres NATURAL LEFT/RIGHT joins Amend readme Revert successful Oracle test --- README.md | 1 + .../net/sf/jsqlparser/statement/select/oracle-tests/join21.sql | 3 +-- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 49f6b165c..5a2a21e47 100644 --- a/README.md +++ b/README.md @@ -67,6 +67,7 @@ Additionally, we have fixed many errors and improved the code quality and the te * Add support for `... ALTER COLUMN ... DROP DEFAULT` * `INSERT` supports `SetOperations` (e. g. `INSERT INTO ... SELECT ... FROM ... UNION SELECT ... FROM ...`), those `SetOperations` are used both for `SELECT` and `VALUES` clauses (API change) in order to simplify the Grammar * `(WITH ... SELECT ...)` statements within brackets are now supported +* Postgres `NATURAL { INNER | LEFT | RIGHT } JOIN` support ## Building from the sources diff --git a/src/test/resources/net/sf/jsqlparser/statement/select/oracle-tests/join21.sql b/src/test/resources/net/sf/jsqlparser/statement/select/oracle-tests/join21.sql index 29a8425aa..c17cfc6d2 100644 --- a/src/test/resources/net/sf/jsqlparser/statement/select/oracle-tests/join21.sql +++ b/src/test/resources/net/sf/jsqlparser/statement/select/oracle-tests/join21.sql @@ -10,5 +10,4 @@ select * from sys.dual natural join sys.dual ---@SUCCESSFULLY_PARSED_AND_DEPARSED first on Aug 3, 2021, 7:20:08 AM ---@FAILURE: Encountered unexpected token: "natural" "NATURAL" recorded first on 9 Jun 2022, 21:50:07 \ No newline at end of file +--@SUCCESSFULLY_PARSED_AND_DEPARSED first on Aug 3, 2021, 7:20:08 AM \ No newline at end of file