You are viewing a plain text version of this content. The canonical link for it is here.
Posted to notifications@shardingsphere.apache.org by du...@apache.org on 2023/05/17 01:23:00 UTC

[shardingsphere] branch master updated: Optimize BaseRule.g4 support CREATE TABLE with cast function. (#25708)

This is an automated email from the ASF dual-hosted git repository.

duanzhengqiang pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/shardingsphere.git


The following commit(s) were added to refs/heads/master by this push:
     new ab79c6db91a Optimize BaseRule.g4 support CREATE TABLE with cast function. (#25708)
ab79c6db91a is described below

commit ab79c6db91a1ca7a4e53c8a84bd758dc9a78a57e
Author: Cong Hu <ia...@qq.com>
AuthorDate: Wed May 17 09:22:52 2023 +0800

    Optimize BaseRule.g4 support CREATE TABLE with cast function. (#25708)
---
 .../src/main/antlr4/imports/mysql/BaseRule.g4      | 36 ++++++++++------------
 .../src/main/antlr4/imports/mysql/MySQLKeyword.g4  |  4 +++
 .../visitor/statement/MySQLStatementVisitor.java   | 22 +++++++++++--
 .../src/main/resources/case/ddl/create-table.xml   |  8 +++++
 .../resources/sql/supported/ddl/create-table.xml   |  1 +
 5 files changed, 49 insertions(+), 22 deletions(-)

diff --git a/parser/sql/dialect/mysql/src/main/antlr4/imports/mysql/BaseRule.g4 b/parser/sql/dialect/mysql/src/main/antlr4/imports/mysql/BaseRule.g4
index 3528828ef9e..709d2d9882f 100644
--- a/parser/sql/dialect/mysql/src/main/antlr4/imports/mysql/BaseRule.g4
+++ b/parser/sql/dialect/mysql/src/main/antlr4/imports/mysql/BaseRule.g4
@@ -1013,7 +1013,7 @@ repairType
     ;
     
 castFunction
-    : CAST LP_ expr AS dataType RP_
+    : CAST LP_ expr AS castType ARRAY? RP_
     | CAST LP_ expr AT TIME ZONE expr AS DATETIME typeDatetimePrecision? RP_
     ;
 
@@ -1023,23 +1023,19 @@ convertFunction
     ;
     
 castType
-    : BINARY fieldLength?
-    | CHAR fieldLength? charsetWithOptBinary?
-    | nchar fieldLength?
-    | SIGNED INT?
-    | UNSIGNED INT?
-    | DATE
-    | TIME typeDatetimePrecision?
-    | DATETIME typeDatetimePrecision?
-    | DECIMAL (fieldLength | precision)?
-    | JSON
-    | REAL
-    | DOUBLE PRECISION
-    | FLOAT precision?
-    ;
-    
-nchar
-    : NCHAR | NATIONAL CHAR
+    : castTypeName = BINARY fieldLength?
+    | castTypeName = CHAR fieldLength? charsetWithOptBinary?
+    | (castTypeName = NCHAR | castTypeName = NATIONAL_CHAR) fieldLength?
+    | castTypeName = SIGNED (INT | INTEGER)?
+    | castTypeName = UNSIGNED (INT | INTEGER)?
+    | castTypeName = DATE
+    | castTypeName = TIME typeDatetimePrecision?
+    | castTypeName = DATETIME typeDatetimePrecision?
+    | castTypeName = DECIMAL (fieldLength | precision)?
+    | castTypeName = JSON
+    | castTypeName = REAL
+    | castTypeName = DOUBLE PRECISION
+    | castTypeName = FLOAT precision?
     ;
     
 positionFunction
@@ -1162,11 +1158,11 @@ dataType
     | dataTypeName = BIT fieldLength?
     | dataTypeName = (BOOL | BOOLEAN)
     | dataTypeName = CHAR fieldLength? charsetWithOptBinary?
-    | (dataTypeName = NCHAR | dataTypeName = NATIONAL CHAR) fieldLength? BINARY?
+    | (dataTypeName = NCHAR | dataTypeName = NATIONAL_CHAR) fieldLength? BINARY?
     | dataTypeName = SIGNED (INTEGER | INT)?
     | dataTypeName = BINARY fieldLength?
     | (dataTypeName = CHAR_VARYING | dataTypeName = CHARACTER_VARYING | dataTypeName = VARCHAR) fieldLength charsetWithOptBinary?
-    | (dataTypeName = NATIONAL VARCHAR | dataTypeName = NVARCHAR | dataTypeName = NCHAR VARCHAR | dataTypeName = NATIONAL CHAR VARYING | dataTypeName = NCHAR VARYING) fieldLength BINARY?
+    | (dataTypeName = NATIONAL VARCHAR | dataTypeName = NVARCHAR | dataTypeName = NCHAR VARCHAR | dataTypeName = NATIONAL_CHAR VARYING | dataTypeName = NCHAR VARYING) fieldLength BINARY?
     | dataTypeName = VARBINARY fieldLength?
     | dataTypeName = YEAR fieldLength? fieldOptions?
     | dataTypeName = DATE
diff --git a/parser/sql/dialect/mysql/src/main/antlr4/imports/mysql/MySQLKeyword.g4 b/parser/sql/dialect/mysql/src/main/antlr4/imports/mysql/MySQLKeyword.g4
index 0806f8e0049..20cd04fc202 100644
--- a/parser/sql/dialect/mysql/src/main/antlr4/imports/mysql/MySQLKeyword.g4
+++ b/parser/sql/dialect/mysql/src/main/antlr4/imports/mysql/MySQLKeyword.g4
@@ -1535,6 +1535,10 @@ NATIONAL
     : N A T I O N A L
     ;
 
+NATIONAL_CHAR
+    : NATIONAL ' ' CHAR
+    ;
+
 NATURAL
     : N A T U R A L
     ;
diff --git a/parser/sql/dialect/mysql/src/main/java/org/apache/shardingsphere/sql/parser/mysql/visitor/statement/MySQLStatementVisitor.java b/parser/sql/dialect/mysql/src/main/java/org/apache/shardingsphere/sql/parser/mysql/visitor/statement/MySQLStatementVisitor.java
index 2611c1f3ee5..729b166a727 100644
--- a/parser/sql/dialect/mysql/src/main/java/org/apache/shardingsphere/sql/parser/mysql/visitor/statement/MySQLStatementVisitor.java
+++ b/parser/sql/dialect/mysql/src/main/java/org/apache/shardingsphere/sql/parser/mysql/visitor/statement/MySQLStatementVisitor.java
@@ -38,6 +38,7 @@ import org.apache.shardingsphere.sql.parser.autogen.MySQLStatementParser.Boolean
 import org.apache.shardingsphere.sql.parser.autogen.MySQLStatementParser.CaseExpressionContext;
 import org.apache.shardingsphere.sql.parser.autogen.MySQLStatementParser.CaseWhenContext;
 import org.apache.shardingsphere.sql.parser.autogen.MySQLStatementParser.CastFunctionContext;
+import org.apache.shardingsphere.sql.parser.autogen.MySQLStatementParser.CastTypeContext;
 import org.apache.shardingsphere.sql.parser.autogen.MySQLStatementParser.CharFunctionContext;
 import org.apache.shardingsphere.sql.parser.autogen.MySQLStatementParser.CollateClauseContext;
 import org.apache.shardingsphere.sql.parser.autogen.MySQLStatementParser.ColumnNameContext;
@@ -922,8 +923,8 @@ public abstract class MySQLStatementVisitor extends MySQLStatementBaseVisitor<AS
                 result.getParameters().add((LiteralExpressionSegment) expr);
             }
         }
-        if (null != ctx.dataType()) {
-            result.getParameters().add((DataTypeSegment) visit(ctx.dataType()));
+        if (null != ctx.castType()) {
+            result.getParameters().add((DataTypeSegment) visit(ctx.castType()));
         }
         if (null != ctx.DATETIME()) {
             DataTypeSegment dataType = new DataTypeSegment();
@@ -938,6 +939,23 @@ public abstract class MySQLStatementVisitor extends MySQLStatementBaseVisitor<AS
         return result;
     }
     
+    @Override
+    public ASTNode visitCastType(final CastTypeContext ctx) {
+        DataTypeSegment result = new DataTypeSegment();
+        result.setDataTypeName(ctx.castTypeName.getText());
+        result.setStartIndex(ctx.start.getStartIndex());
+        result.setStopIndex(ctx.stop.getStopIndex());
+        if (null != ctx.fieldLength()) {
+            DataTypeLengthSegment dataTypeLengthSegment = (DataTypeLengthSegment) visit(ctx.fieldLength());
+            result.setDataLength(dataTypeLengthSegment);
+        }
+        if (null != ctx.precision()) {
+            DataTypeLengthSegment dataTypeLengthSegment = (DataTypeLengthSegment) visit(ctx.precision());
+            result.setDataLength(dataTypeLengthSegment);
+        }
+        return result;
+    }
+    
     @Override
     public final ASTNode visitConvertFunction(final ConvertFunctionContext ctx) {
         calculateParameterCount(Collections.singleton(ctx.expr()));
diff --git a/test/it/parser/src/main/resources/case/ddl/create-table.xml b/test/it/parser/src/main/resources/case/ddl/create-table.xml
index 339afba6e0e..66fe7a18a21 100644
--- a/test/it/parser/src/main/resources/case/ddl/create-table.xml
+++ b/test/it/parser/src/main/resources/case/ddl/create-table.xml
@@ -1821,4 +1821,12 @@
             <column name="order_id" />
         </column-definition>
     </create-table>
+
+    <create-table sql-case-id="create_table_with_cast_function">
+        <table name="t1" start-index="13" stop-index="14" />
+        <column-definition type="json" start-index="16" stop-index="21">
+            <column name="j" />
+        </column-definition>
+        <constraint-definition index-name="mv_idx" start-index="24" stop-index="64" />
+    </create-table>
 </sql-parser-test-cases>
diff --git a/test/it/parser/src/main/resources/sql/supported/ddl/create-table.xml b/test/it/parser/src/main/resources/sql/supported/ddl/create-table.xml
index e701191e2c5..df4ea7d94a1 100644
--- a/test/it/parser/src/main/resources/sql/supported/ddl/create-table.xml
+++ b/test/it/parser/src/main/resources/sql/supported/ddl/create-table.xml
@@ -131,4 +131,5 @@
     <sql-case id="create_table_with_character_varying" value="CREATE TABLE t_order (order_id INT, user_id INT, status CHARACTER VARYING(50))" db-types="MySQL" />
     <sql-case id="create_table_with_geomcollection" value="CREATE TABLE t1 (g GEOMCOLLECTION)" db-types="MySQL" />
     <sql-case id="create_table_with_start_transaction" value="CREATE TABLE t_order (order_id INT) START TRANSACTION" db-types="MySQL" />
+    <sql-case id="create_table_with_cast_function" value="CREATE TABLE t1(j json, INDEX mv_idx((CAST(j AS UNSIGNED ARRAY))))" db-types="MySQL" />
 </sql-cases>