From b219209e621d9c550681fbcd72687fe25ab5bc55 Mon Sep 17 00:00:00 2001 From: LiZongbo Date: Mon, 3 Jun 2024 00:49:01 +0800 Subject: [PATCH] =?UTF-8?q?=E4=BC=98=E5=8C=96=E6=94=AF=E6=8C=81sql=20cast?= =?UTF-8?q?=E5=87=BD=E6=95=B0=E7=9A=84=E5=A4=9A=E9=87=8D=E6=8B=AC=E5=8F=B7?= =?UTF-8?q?=E8=A7=A3=E6=9E=90=E5=92=8C=E7=94=9F=E6=88=90=20#5958?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 优化支持sql cast函数的多重括号解析和生成 #5958 --- .../alibaba/druid/sql/ast/SQLExprImpl.java | 20 +++++++++- .../sql/visitor/SQLASTOutputVisitor.java | 20 +++++++++- .../druid/bvt/sql/mysql/issues/Issue5894.java | 2 +- .../druid/bvt/sql/mysql/issues/Issue5958.java | 37 +++++++++++++++++++ 4 files changed, 76 insertions(+), 3 deletions(-) create mode 100644 core/src/test/java/com/alibaba/druid/bvt/sql/mysql/issues/Issue5958.java diff --git a/core/src/main/java/com/alibaba/druid/sql/ast/SQLExprImpl.java b/core/src/main/java/com/alibaba/druid/sql/ast/SQLExprImpl.java index 2475c56e9a..6a4dfb5357 100644 --- a/core/src/main/java/com/alibaba/druid/sql/ast/SQLExprImpl.java +++ b/core/src/main/java/com/alibaba/druid/sql/ast/SQLExprImpl.java @@ -19,7 +19,7 @@ public abstract class SQLExprImpl extends SQLObjectImpl implements SQLExpr { protected boolean parenthesized; - + protected int parenthesizedCount; public SQLExprImpl() { } @@ -29,7 +29,25 @@ public boolean isParenthesized() { public void setParenthesized(boolean parenthesized) { this.parenthesized = parenthesized; + if (parenthesized) { + parenthesizedCount++; + } else { + parenthesizedCount--; + } + } + + public int getParenthesizedCount() { + return parenthesizedCount; + } + + public void setParenthesizedCount(int parenthesizedCount) { + this.parenthesizedCount = parenthesizedCount; + } + + public void increaseParenthesizedCount() { + this.parenthesizedCount++; } + public abstract boolean equals(Object o); public abstract int hashCode(); diff --git a/core/src/main/java/com/alibaba/druid/sql/visitor/SQLASTOutputVisitor.java b/core/src/main/java/com/alibaba/druid/sql/visitor/SQLASTOutputVisitor.java index 5b6f4e858c..9f1d0fa6d2 100644 --- a/core/src/main/java/com/alibaba/druid/sql/visitor/SQLASTOutputVisitor.java +++ b/core/src/main/java/com/alibaba/druid/sql/visitor/SQLASTOutputVisitor.java @@ -1288,6 +1288,7 @@ public boolean visit(SQLGetDiagnosticsStatement x) { } public boolean visit(SQLCastExpr x) { + tryPrintLparen(x); if (x.isTry()) { print0(ucase ? "TRY_CAST(" : "try_cast("); } else { @@ -1297,7 +1298,7 @@ public boolean visit(SQLCastExpr x) { print0(ucase ? " AS " : " as "); x.getDataType().accept(this); print0(")"); - + tryPrintRparen(x); return false; } @@ -11839,4 +11840,21 @@ public boolean visit(StarRocksIndexDefinition x) { } return false; } + protected void tryPrintLparen(SQLExprImpl x) { + if (x.isParenthesized()) { + print('('); + } + for (int i = 1; i < x.getParenthesizedCount(); ++i) { + print('('); + } + } + + protected void tryPrintRparen(SQLExprImpl x) { + if (x.isParenthesized()) { + print(')'); + } + for (int i = 1; i < x.getParenthesizedCount(); ++i) { + print(')'); + } + } } diff --git a/core/src/test/java/com/alibaba/druid/bvt/sql/mysql/issues/Issue5894.java b/core/src/test/java/com/alibaba/druid/bvt/sql/mysql/issues/Issue5894.java index 702310ca22..e085c9544d 100644 --- a/core/src/test/java/com/alibaba/druid/bvt/sql/mysql/issues/Issue5894.java +++ b/core/src/test/java/com/alibaba/druid/bvt/sql/mysql/issues/Issue5894.java @@ -29,7 +29,7 @@ public void test_parse_aschararray() { List statementList = parser.parseStatementList(); assertEquals(1, statementList.size()); assertEquals("ALTER TABLE db1.rs_push_mall_data\n" - + "\tADD KEY idx_bill_no_json (CAST(bill_no_json AS CHAR(50) ARRAY));", statementList.get(0).toString()); + + "\tADD KEY idx_bill_no_json ((CAST(bill_no_json AS CHAR(50) ARRAY)));", statementList.get(0).toString()); SQLParseAssertUtil.assertParseSql(sql, dbType); } } diff --git a/core/src/test/java/com/alibaba/druid/bvt/sql/mysql/issues/Issue5958.java b/core/src/test/java/com/alibaba/druid/bvt/sql/mysql/issues/Issue5958.java new file mode 100644 index 0000000000..2551bca85e --- /dev/null +++ b/core/src/test/java/com/alibaba/druid/bvt/sql/mysql/issues/Issue5958.java @@ -0,0 +1,37 @@ +package com.alibaba.druid.bvt.sql.mysql.issues; + +import java.util.List; + +import com.alibaba.druid.DbType; +import com.alibaba.druid.sql.SQLParseAssertUtil; +import com.alibaba.druid.sql.ast.SQLStatement; +import com.alibaba.druid.sql.parser.SQLParserUtils; +import com.alibaba.druid.sql.parser.SQLStatementParser; + +import org.junit.Test; + +import static org.junit.Assert.assertEquals; + +/** + * @author lizongbo + * @see Issue来源 + */ +public class Issue5958 { + + + @Test + public void test_parse_alter() { + for (DbType dbType : new DbType[]{DbType.mysql}) { + for (String sql : new String[]{ + //"select (((a-b))) from aa;", + "alter TABLE test.rs_urge_pickup_config ADD KEY idx_site_id_list2 ((cast(site_id_list as char(10) array)));", + }) { + SQLStatementParser parser = SQLParserUtils.createSQLStatementParser(sql, dbType); + List statementList = parser.parseStatementList(); + System.out.println(statementList); + assertEquals(1, statementList.size()); + SQLParseAssertUtil.assertParseSql(sql, dbType); + } + } + } +}