From cd789080bf06164e1ed17ae3d3647e3c0f9b7ec3 Mon Sep 17 00:00:00 2001 From: zhenggli Date: Mon, 22 Apr 2024 18:23:04 -0500 Subject: [PATCH 01/10] Fix table alias reset to empty for join queries enclosed in parentheses --- .../oracle/parser/OracleSelectParser.java | 8 ++++-- .../sql/oracle/select/OracleSelectTest71.java | 25 +++++++++++++++++++ 2 files changed, 31 insertions(+), 2 deletions(-) diff --git a/core/src/main/java/com/alibaba/druid/sql/dialect/oracle/parser/OracleSelectParser.java b/core/src/main/java/com/alibaba/druid/sql/dialect/oracle/parser/OracleSelectParser.java index 9908780d38..c2091c9d51 100644 --- a/core/src/main/java/com/alibaba/druid/sql/dialect/oracle/parser/OracleSelectParser.java +++ b/core/src/main/java/com/alibaba/druid/sql/dialect/oracle/parser/OracleSelectParser.java @@ -892,8 +892,12 @@ protected SQLTableSource parseTableSourceRest(OracleSelectTableSource tableSourc SQLTableSource right; right = parseTableSourcePrimary(); - String tableAlias = tableAlias(); - right.setAlias(tableAlias); + // Alias is already set for "... JOIN (tbl1 alias1) ON ..." syntax, + // so skip setting alias + if (right.getAlias() == null) { + String tableAlias = tableAlias(); + right.setAlias(tableAlias); + } join.setRight(right); if (lexer.token() == Token.ON) { diff --git a/core/src/test/java/com/alibaba/druid/bvt/sql/oracle/select/OracleSelectTest71.java b/core/src/test/java/com/alibaba/druid/bvt/sql/oracle/select/OracleSelectTest71.java index d2cd312b19..2c4532799c 100644 --- a/core/src/test/java/com/alibaba/druid/bvt/sql/oracle/select/OracleSelectTest71.java +++ b/core/src/test/java/com/alibaba/druid/bvt/sql/oracle/select/OracleSelectTest71.java @@ -94,4 +94,29 @@ public void test_0() throws Exception { // Assert.assertTrue(visitor.getOrderByColumns().contains(new TableStat.Column("employees", "last_name"))); } + + public void testSelectWithJoin_UnderParen() { + String sql = "SELECT\n" + + "\tA.ID, B.NAME, C.TYPE\n" + + "\tFROM\n" + + "\ttbl_name1 A\n" + + "\tLEFT JOIN (tbl_name2 B)\n" + + "\tON A.ID = B.ID\n" + + "\tLEFT JOIN (tbl_name3 C)\n" + + "\tON A.ID = C.ID\n" + + "\tAND A.NAME = B.NAME"; + + OracleStatementParser parser = new OracleStatementParser(sql); + List statementList = parser.parseStatementList(); + SQLStatement statement = statementList.get(0); + print(statementList); + + Assert.assertEquals(1, statementList.size()); + + OracleSchemaStatVisitor visitor = new OracleSchemaStatVisitor(); + statement.accept(visitor); + + Assert.assertEquals(3, visitor.getTables().size()); + Assert.assertEquals(6, visitor.getColumns().size()); + } } From 2b3fbfbf01162e5da02420c48c04cbd522b8b0e1 Mon Sep 17 00:00:00 2001 From: zhenggli Date: Mon, 22 Apr 2024 18:27:17 -0500 Subject: [PATCH 02/10] Update query format --- .../sql/oracle/select/OracleSelectTest71.java | 20 ++++++++++--------- 1 file changed, 11 insertions(+), 9 deletions(-) diff --git a/core/src/test/java/com/alibaba/druid/bvt/sql/oracle/select/OracleSelectTest71.java b/core/src/test/java/com/alibaba/druid/bvt/sql/oracle/select/OracleSelectTest71.java index 2c4532799c..0e4336ec5f 100644 --- a/core/src/test/java/com/alibaba/druid/bvt/sql/oracle/select/OracleSelectTest71.java +++ b/core/src/test/java/com/alibaba/druid/bvt/sql/oracle/select/OracleSelectTest71.java @@ -96,15 +96,17 @@ public void test_0() throws Exception { } public void testSelectWithJoin_UnderParen() { - String sql = "SELECT\n" + - "\tA.ID, B.NAME, C.TYPE\n" + - "\tFROM\n" + - "\ttbl_name1 A\n" + - "\tLEFT JOIN (tbl_name2 B)\n" + - "\tON A.ID = B.ID\n" + - "\tLEFT JOIN (tbl_name3 C)\n" + - "\tON A.ID = C.ID\n" + - "\tAND A.NAME = B.NAME"; + String sql = "SELECT /* NUSQL.TEST */\n" + + " A.ID,\n" + + " B.NAME,\n" + + " C.TYPE\n" + + "FROM\n" + + " TBL_NAME1 A\n" + + " LEFT JOIN (TBL_NAME2 B)\n" + + " ON A.ID = B.ID\n" + + " LEFT JOIN (TBL_NAME3 C)\n" + + " ON A.ID = C.ID\n" + + " AND A.NAME = B.NAME"; OracleStatementParser parser = new OracleStatementParser(sql); List statementList = parser.parseStatementList(); From 3aca5626cee4e0a8292a1f40ec27f8703528b364 Mon Sep 17 00:00:00 2001 From: zhenggli Date: Mon, 22 Apr 2024 18:28:04 -0500 Subject: [PATCH 03/10] Update query format --- .../druid/bvt/sql/oracle/select/OracleSelectTest71.java | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/core/src/test/java/com/alibaba/druid/bvt/sql/oracle/select/OracleSelectTest71.java b/core/src/test/java/com/alibaba/druid/bvt/sql/oracle/select/OracleSelectTest71.java index 0e4336ec5f..870e53273d 100644 --- a/core/src/test/java/com/alibaba/druid/bvt/sql/oracle/select/OracleSelectTest71.java +++ b/core/src/test/java/com/alibaba/druid/bvt/sql/oracle/select/OracleSelectTest71.java @@ -101,10 +101,10 @@ public void testSelectWithJoin_UnderParen() { " B.NAME,\n" + " C.TYPE\n" + "FROM\n" + - " TBL_NAME1 A\n" + - " LEFT JOIN (TBL_NAME2 B)\n" + + " tbl_name1 A\n" + + " LEFT JOIN (tbl_name2 B)\n" + " ON A.ID = B.ID\n" + - " LEFT JOIN (TBL_NAME3 C)\n" + + " LEFT JOIN (tbl_name3 C)\n" + " ON A.ID = C.ID\n" + " AND A.NAME = B.NAME"; From d23e3d2a5e707955ec89f40780225318dcc46981 Mon Sep 17 00:00:00 2001 From: zhenggli Date: Mon, 22 Apr 2024 18:31:11 -0500 Subject: [PATCH 04/10] Remove trailing space --- .../druid/sql/dialect/oracle/parser/OracleSelectParser.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core/src/main/java/com/alibaba/druid/sql/dialect/oracle/parser/OracleSelectParser.java b/core/src/main/java/com/alibaba/druid/sql/dialect/oracle/parser/OracleSelectParser.java index c2091c9d51..1492b4b1e3 100644 --- a/core/src/main/java/com/alibaba/druid/sql/dialect/oracle/parser/OracleSelectParser.java +++ b/core/src/main/java/com/alibaba/druid/sql/dialect/oracle/parser/OracleSelectParser.java @@ -892,7 +892,7 @@ protected SQLTableSource parseTableSourceRest(OracleSelectTableSource tableSourc SQLTableSource right; right = parseTableSourcePrimary(); - // Alias is already set for "... JOIN (tbl1 alias1) ON ..." syntax, + // Alias is already set for "... JOIN (tbl1 alias1) ON ..." syntax, // so skip setting alias if (right.getAlias() == null) { String tableAlias = tableAlias(); From 0721e09cd741c1ee80be97a97b2b1dd89d926ca1 Mon Sep 17 00:00:00 2001 From: zhenggli Date: Mon, 22 Apr 2024 12:23:54 -0500 Subject: [PATCH 05/10] Fix unary operator for identifier --- .../dialect/oracle/parser/OracleExprParser.java | 5 ++++- .../OracleSelectTest83_number_negative.java | 17 +++++++++++++++++ 2 files changed, 21 insertions(+), 1 deletion(-) diff --git a/core/src/main/java/com/alibaba/druid/sql/dialect/oracle/parser/OracleExprParser.java b/core/src/main/java/com/alibaba/druid/sql/dialect/oracle/parser/OracleExprParser.java index a6e414aaa1..dfb11ebab3 100644 --- a/core/src/main/java/com/alibaba/druid/sql/dialect/oracle/parser/OracleExprParser.java +++ b/core/src/main/java/com/alibaba/druid/sql/dialect/oracle/parser/OracleExprParser.java @@ -422,9 +422,12 @@ public SQLExpr primary() { sqlExpr = new OracleBinaryDoubleExpr(Double.parseDouble(lexer.numberString()) * -1); lexer.nextToken(); break; + case IDENTIFIER: + sqlExpr = new SQLUnaryExpr(SQLUnaryOperator.Negative, new SQLIdentifierExpr(lexer.stringVal())); + lexer.nextToken(); + break; case VARIANT: case QUES: - case IDENTIFIER: case LITERAL_ALIAS: sqlExpr = expr(); sqlExpr = new SQLUnaryExpr(SQLUnaryOperator.Negative, sqlExpr); diff --git a/core/src/test/java/com/alibaba/druid/bvt/sql/oracle/select/OracleSelectTest83_number_negative.java b/core/src/test/java/com/alibaba/druid/bvt/sql/oracle/select/OracleSelectTest83_number_negative.java index 0f06a1b7bb..1dba99b45c 100644 --- a/core/src/test/java/com/alibaba/druid/bvt/sql/oracle/select/OracleSelectTest83_number_negative.java +++ b/core/src/test/java/com/alibaba/druid/bvt/sql/oracle/select/OracleSelectTest83_number_negative.java @@ -69,4 +69,21 @@ public void test_0() throws Exception { // Assert.assertTrue(visitor.containsColumn("sup_task", "orgid")); // } + + public void test_1() throws Exception { + String sql = "SELECT * FROM employees WHERE -salary < 0 ORDER BY employee_id"; + + OracleStatementParser parser = new OracleStatementParser(sql); + List statementList = parser.parseStatementList(); + SQLStatement statement = statementList.get(0); + print(statementList); + + Assert.assertEquals(1, statementList.size()); + + OracleSchemaStatVisitor visitor = new OracleSchemaStatVisitor(); + statement.accept(visitor); + + Assert.assertEquals(1, visitor.getTables().size()); + Assert.assertEquals(3, visitor.getColumns().size()); + } } From b3546cd5d0a92d963e0e6e408c17798d94abf971 Mon Sep 17 00:00:00 2001 From: zhenggli Date: Wed, 24 Apr 2024 15:36:54 -0500 Subject: [PATCH 06/10] Fix unit test --- .../druid/sql/dialect/oracle/parser/OracleExprParser.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/core/src/main/java/com/alibaba/druid/sql/dialect/oracle/parser/OracleExprParser.java b/core/src/main/java/com/alibaba/druid/sql/dialect/oracle/parser/OracleExprParser.java index dfb11ebab3..e07533fe4d 100644 --- a/core/src/main/java/com/alibaba/druid/sql/dialect/oracle/parser/OracleExprParser.java +++ b/core/src/main/java/com/alibaba/druid/sql/dialect/oracle/parser/OracleExprParser.java @@ -423,8 +423,8 @@ public SQLExpr primary() { lexer.nextToken(); break; case IDENTIFIER: - sqlExpr = new SQLUnaryExpr(SQLUnaryOperator.Negative, new SQLIdentifierExpr(lexer.stringVal())); - lexer.nextToken(); + sqlExpr = primary(); + sqlExpr = new SQLUnaryExpr(SQLUnaryOperator.Negative, sqlExpr); break; case VARIANT: case QUES: From 61f6d19090d03f57863b25eea0bd2768ad337d15 Mon Sep 17 00:00:00 2001 From: liuxy <1794014950@qq.com> Date: Wed, 24 Apr 2024 16:03:43 +0800 Subject: [PATCH 07/10] =?UTF-8?q?fix=20=E4=BF=AE=E5=A4=8D=E5=86=85?= =?UTF-8?q?=E7=BD=AE=E7=9B=91=E6=8E=A7=E9=A1=B5=E9=87=8D=E7=BD=AE=E5=8F=8A?= =?UTF-8?q?=E8=AE=B0=E5=BD=95=E6=97=A5=E5=BF=97=E5=B9=B6=E9=87=8D=E7=BD=AE?= =?UTF-8?q?=E6=8C=89=E9=92=AE=E5=A4=B1=E6=95=88=E7=BC=BA=E9=99=B7?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- core/src/main/resources/support/http/resources/header.html | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/core/src/main/resources/support/http/resources/header.html b/core/src/main/resources/support/http/resources/header.html index 7ab5bf1367..ba3b2d3e75 100644 --- a/core/src/main/resources/support/http/resources/header.html +++ b/core/src/main/resources/support/http/resources/header.html @@ -19,9 +19,9 @@
  • JSON API
  • Reset All + href="javascript:druid.common.ajaxRequestForReset();">Reset All Log And Reset + href="javascript:druid.common.ajaxRequestForLogAndReset();">Log And Reset From 48ea6cb2a5368ea445ca8ca2c1fad534dc53e24b Mon Sep 17 00:00:00 2001 From: bantao Date: Tue, 23 Apr 2024 14:12:59 +0800 Subject: [PATCH 08/10] fix oracle window between dialect error --- .../druid/sql/dialect/oracle/parser/OracleExprParser.java | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/core/src/main/java/com/alibaba/druid/sql/dialect/oracle/parser/OracleExprParser.java b/core/src/main/java/com/alibaba/druid/sql/dialect/oracle/parser/OracleExprParser.java index e07533fe4d..059e4a17e2 100644 --- a/core/src/main/java/com/alibaba/druid/sql/dialect/oracle/parser/OracleExprParser.java +++ b/core/src/main/java/com/alibaba/druid/sql/dialect/oracle/parser/OracleExprParser.java @@ -918,9 +918,9 @@ protected SQLAggregateExpr parseAggregateExpr(String methodName) { endExpr = new SQLIdentifierExpr("CURRENT ROW"); } else if (lexer.identifierEquals(FnvHash.Constants.UNBOUNDED)) { lexer.nextToken(); - if (lexer.stringVal().equalsIgnoreCase("PRECEDING")) { + if (lexer.stringVal().equalsIgnoreCase("FOLLOWING")) { lexer.nextToken(); - endExpr = new SQLIdentifierExpr("UNBOUNDED PRECEDING"); + endExpr = new SQLIdentifierExpr("UNBOUNDED FOLLOWING"); } else { throw new ParserException("syntax error. " + lexer.info()); } From 18d687281093d80e98254ae2fe6e56592df0d4d3 Mon Sep 17 00:00:00 2001 From: bantao Date: Tue, 23 Apr 2024 17:25:22 +0800 Subject: [PATCH 09/10] fix oracle window between dialect error Signed-off-by: bantao --- .../oracle/parser/OracleExprParser.java | 4 ++ .../oracle/visitor/OracleOutputVisitor.java | 3 ++ .../oracle/select/OracleSelectTest124.java | 39 +++++++++++++++++++ 3 files changed, 46 insertions(+) diff --git a/core/src/main/java/com/alibaba/druid/sql/dialect/oracle/parser/OracleExprParser.java b/core/src/main/java/com/alibaba/druid/sql/dialect/oracle/parser/OracleExprParser.java index 059e4a17e2..6452404ea1 100644 --- a/core/src/main/java/com/alibaba/druid/sql/dialect/oracle/parser/OracleExprParser.java +++ b/core/src/main/java/com/alibaba/druid/sql/dialect/oracle/parser/OracleExprParser.java @@ -928,6 +928,10 @@ protected SQLAggregateExpr parseAggregateExpr(String methodName) { endExpr = relational(); } + final SQLOver.WindowingBound endBound = parseWindowingBound(); + if (endBound != null) { + over.setWindowingBetweenEndBound(endBound); + } SQLExpr expr = new SQLBetweenExpr(null, beginExpr, endExpr); windowing.setExpr(expr); } else { diff --git a/core/src/main/java/com/alibaba/druid/sql/dialect/oracle/visitor/OracleOutputVisitor.java b/core/src/main/java/com/alibaba/druid/sql/dialect/oracle/visitor/OracleOutputVisitor.java index aa922efda4..9045a1eca8 100644 --- a/core/src/main/java/com/alibaba/druid/sql/dialect/oracle/visitor/OracleOutputVisitor.java +++ b/core/src/main/java/com/alibaba/druid/sql/dialect/oracle/visitor/OracleOutputVisitor.java @@ -99,6 +99,9 @@ public boolean visit(OracleAnalytic x) { if (x.isWindowingPreceding()) { print0(ucase ? " PRECEDING" : " preceding"); } + if (x.isWindowingBetweenEndFollowing()) { + print0(ucase ? " FOLLOWING" : " following"); + } print(')'); diff --git a/core/src/test/java/com/alibaba/druid/bvt/sql/oracle/select/OracleSelectTest124.java b/core/src/test/java/com/alibaba/druid/bvt/sql/oracle/select/OracleSelectTest124.java index 83362f2dd8..1c0e05a35a 100644 --- a/core/src/test/java/com/alibaba/druid/bvt/sql/oracle/select/OracleSelectTest124.java +++ b/core/src/test/java/com/alibaba/druid/bvt/sql/oracle/select/OracleSelectTest124.java @@ -45,5 +45,44 @@ public void test_0() throws Exception { assertEquals("SELECT J01.COL_A, J01.COL_B, \"SUM\"(J01.COL_C) OVER (PARTITION BY J01.COL_A ORDER BY J01.COL_B NULLS FIRST ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW) AS COL_C\n" + "FROM TAB_A J01", stmt.toString()); } + public void test_1() throws Exception { + String sql = "SELECT\n" + + "J01.COL_A,\n" + + "J01.COL_B,\n" + + "\"SUM\"(J01.COL_C) OVER (\n" + + "PARTITION BY J01.COL_A ORDER BY J01.COL_B NULLS FIRST ROWS BETWEEN 5 PRECEDING AND 8 FOLLOWING\n" + + ") AS COL_C\n" + + "FROM\n" + + "TAB_A J01"; + + List statementList = SQLUtils.parseStatements(sql, JdbcConstants.ORACLE); + + assertEquals(1, statementList.size()); + + SQLSelectStatement stmt = (SQLSelectStatement) statementList.get(0); + System.out.println(stmt.toString()); + + assertEquals("SELECT J01.COL_A, J01.COL_B, \"SUM\"(J01.COL_C) OVER (PARTITION BY J01.COL_A ORDER BY J01.COL_B NULLS FIRST ROWS BETWEEN 5 PRECEDING AND 8 FOLLOWING) AS COL_C\n" + + "FROM TAB_A J01", stmt.toString()); + } + public void test_2() throws Exception { + String sql = "SELECT\n" + + "J01.COL_A,\n" + + "J01.COL_B,\n" + + "\"SUM\"(J01.COL_C) OVER (\n" + + "PARTITION BY J01.COL_A ORDER BY J01.COL_B NULLS FIRST ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING\n" + + ") AS COL_C\n" + + "FROM\n" + + "TAB_A J01"; + + List statementList = SQLUtils.parseStatements(sql, JdbcConstants.ORACLE); + + assertEquals(1, statementList.size()); + + SQLSelectStatement stmt = (SQLSelectStatement) statementList.get(0); + System.out.println(stmt.toString()); + assertEquals("SELECT J01.COL_A, J01.COL_B, \"SUM\"(J01.COL_C) OVER (PARTITION BY J01.COL_A ORDER BY J01.COL_B NULLS FIRST ROWS BETWEEN UNBOUNDED PRECEDING AND UNBOUNDED FOLLOWING) AS COL_C\n" + + "FROM TAB_A J01", stmt.toString()); + } } \ No newline at end of file From 957bbab0e068a4cbe2707d85db08302ba1684a5e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E8=8C=83=E5=AE=B6=E7=91=9E?= Date: Sun, 28 Apr 2024 18:07:24 +0800 Subject: [PATCH 10/10] fixed #5866 DDL SQL syntax error. --- core/src/main/java/com/alibaba/druid/util/OracleUtils.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core/src/main/java/com/alibaba/druid/util/OracleUtils.java b/core/src/main/java/com/alibaba/druid/util/OracleUtils.java index d263143159..8a5acacae5 100644 --- a/core/src/main/java/com/alibaba/druid/util/OracleUtils.java +++ b/core/src/main/java/com/alibaba/druid/util/OracleUtils.java @@ -261,7 +261,7 @@ public static List getTableDDL(Connection conn, List tables) thr sql.append("select DBMS_METADATA.GET_DDL('TABLE', TABLE_NAME) FROM user_tables"); if (tables.size() > 0) { - sql.append("IN ("); + sql.append(" WHERE TABLE_NAME IN ("); for (int i = 0; i < tables.size(); ++i) { if (i != 0) { sql.append(", ?");