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 f91d64e7ea5 support json function call (#28319)
f91d64e7ea5 is described below

commit f91d64e7ea5a0fb70410326dcc7fae020988fc2f
Author: Yunbo Ni <[email protected]>
AuthorDate: Mon Sep 4 15:18:20 2023 +0800

    support json function call (#28319)
    
    * fix: function call recognize order in g4
    
    * feat: json function call
    
    * fix: spotless
    
    * fix: add json function params in case
    
    * fix: add json function params in case
    
    * fix: spotless and check style
    
    * fix: checkstyle
---
 .../segment/expression/impl/FunctionConverter.java | 11 +++++++++-
 .../segment/projection/impl/DataTypeConverter.java |  7 ++++--
 .../src/main/antlr4/imports/mysql/BaseRule.g4      |  2 +-
 .../visitor/statement/MySQLStatementVisitor.java   | 17 +++++++++++++--
 .../src/test/resources/converter/select.xml        |  1 +
 .../main/resources/case/dml/select-expression.xml  | 25 ++++++++++++++++++++--
 .../parser/src/main/resources/case/dml/select.xml  | 12 ++++++++++-
 7 files changed, 66 insertions(+), 9 deletions(-)

diff --git 
a/kernel/sql-federation/core/src/main/java/org/apache/shardingsphere/sqlfederation/compiler/converter/segment/expression/impl/FunctionConverter.java
 
b/kernel/sql-federation/core/src/main/java/org/apache/shardingsphere/sqlfederation/compiler/converter/segment/expression/impl/FunctionConverter.java
index e687f92b011..0c509775852 100644
--- 
a/kernel/sql-federation/core/src/main/java/org/apache/shardingsphere/sqlfederation/compiler/converter/segment/expression/impl/FunctionConverter.java
+++ 
b/kernel/sql-federation/core/src/main/java/org/apache/shardingsphere/sqlfederation/compiler/converter/segment/expression/impl/FunctionConverter.java
@@ -21,6 +21,7 @@ import org.apache.calcite.sql.SqlBasicCall;
 import org.apache.calcite.sql.SqlFunctionCategory;
 import org.apache.calcite.sql.SqlIdentifier;
 import org.apache.calcite.sql.SqlNode;
+import org.apache.calcite.sql.SqlNodeList;
 import org.apache.calcite.sql.SqlOperator;
 import org.apache.calcite.sql.SqlSyntax;
 import org.apache.calcite.sql.SqlUnresolvedFunction;
@@ -65,8 +66,16 @@ public class FunctionConverter implements 
SQLSegmentConverter<FunctionSegment, S
     
     private List<SqlNode> getFunctionParameters(final 
Collection<ExpressionSegment> sqlSegments) {
         List<SqlNode> result = new LinkedList<>();
+        ExpressionConverter expressionConverter = new ExpressionConverter();
         for (ExpressionSegment each : sqlSegments) {
-            new ExpressionConverter().convert(each).ifPresent(result::add);
+            if (expressionConverter.convert(each).isPresent()) {
+                SqlNode sqlNode = expressionConverter.convert(each).get();
+                if (sqlNode instanceof SqlNodeList) {
+                    result.addAll(((SqlNodeList) sqlNode).getList());
+                } else {
+                    result.add(expressionConverter.convert(each).get());
+                }
+            }
         }
         return result;
     }
diff --git 
a/kernel/sql-federation/core/src/main/java/org/apache/shardingsphere/sqlfederation/compiler/converter/segment/projection/impl/DataTypeConverter.java
 
b/kernel/sql-federation/core/src/main/java/org/apache/shardingsphere/sqlfederation/compiler/converter/segment/projection/impl/DataTypeConverter.java
index f2b84bd5d67..1e94cb16ebf 100644
--- 
a/kernel/sql-federation/core/src/main/java/org/apache/shardingsphere/sqlfederation/compiler/converter/segment/projection/impl/DataTypeConverter.java
+++ 
b/kernel/sql-federation/core/src/main/java/org/apache/shardingsphere/sqlfederation/compiler/converter/segment/projection/impl/DataTypeConverter.java
@@ -19,11 +19,13 @@ package 
org.apache.shardingsphere.sqlfederation.compiler.converter.segment.proje
 
 import org.apache.calcite.sql.SqlDataTypeSpec;
 import org.apache.calcite.sql.SqlNode;
-import org.apache.calcite.sql.SqlUserDefinedTypeNameSpec;
+import org.apache.calcite.sql.SqlBasicTypeNameSpec;
 import org.apache.calcite.sql.parser.SqlParserPos;
+import org.apache.calcite.sql.type.SqlTypeName;
 import 
org.apache.shardingsphere.sql.parser.sql.common.segment.generic.DataTypeSegment;
 import 
org.apache.shardingsphere.sqlfederation.compiler.converter.segment.SQLSegmentConverter;
 
+import java.util.Objects;
 import java.util.Optional;
 
 /**
@@ -36,6 +38,7 @@ public final class DataTypeConverter implements 
SQLSegmentConverter<DataTypeSegm
         if (null == segment) {
             return Optional.empty();
         }
-        return Optional.of(new SqlDataTypeSpec(new 
SqlUserDefinedTypeNameSpec(segment.getDataTypeName(), SqlParserPos.ZERO), 
SqlParserPos.ZERO));
+        return Optional.of(new SqlDataTypeSpec(new 
SqlBasicTypeNameSpec(Objects.requireNonNull(SqlTypeName.get(segment.getDataTypeName())),
 segment.getDataLength().getPrecision(), SqlParserPos.ZERO),
+                SqlParserPos.ZERO));
     }
 }
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 a75bac4296f..113ca78dc60 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
@@ -947,7 +947,7 @@ columnRefList
     ;
     
 functionCall
-    : aggregationFunction | specialFunction | regularFunction | jsonFunction | 
udfFunction
+    : aggregationFunction | specialFunction | jsonFunction | regularFunction | 
udfFunction
     ;
 
 udfFunction
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 7673d381e0c..9402d1e9020 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
@@ -238,6 +238,7 @@ import java.util.Collections;
 import java.util.LinkedList;
 import java.util.List;
 import java.util.stream.Collectors;
+import java.util.Arrays;
 
 /**
  * Statement visitor for MySQL.
@@ -896,17 +897,21 @@ public abstract class MySQLStatementVisitor extends 
MySQLStatementBaseVisitor<AS
     public final ASTNode visitJsonFunction(final JsonFunctionContext ctx) {
         JsonFunctionNameContext functionNameContext = ctx.jsonFunctionName();
         String functionName;
+        FunctionSegment result;
         if (null != functionNameContext) {
             functionName = functionNameContext.getText();
+            result = new FunctionSegment(ctx.getStart().getStartIndex(), 
ctx.getStop().getStopIndex(), functionName, getOriginalText(ctx));
             for (ExprContext each : ctx.expr()) {
-                visit(each);
+                result.getParameters().add((ExpressionSegment) visit(each));
             }
         } else if (null != ctx.JSON_SEPARATOR()) {
             functionName = ctx.JSON_SEPARATOR().getText();
+            result = new FunctionSegment(ctx.getStart().getStartIndex(), 
ctx.getStop().getStopIndex(), functionName, getOriginalText(ctx));
         } else {
             functionName = ctx.JSON_UNQUOTED_SEPARATOR().getText();
+            result = new FunctionSegment(ctx.getStart().getStartIndex(), 
ctx.getStop().getStopIndex(), functionName, getOriginalText(ctx));
         }
-        return new FunctionSegment(ctx.getStart().getStartIndex(), 
ctx.getStop().getStopIndex(), functionName, getOriginalText(ctx));
+        return result;
     }
     
     private ASTNode createAggregationSegment(final AggregationFunctionContext 
ctx, final String aggregationType) {
@@ -1178,6 +1183,14 @@ public abstract class MySQLStatementVisitor extends 
MySQLStatementBaseVisitor<AS
         if (null != ctx.variable()) {
             return visit(ctx.variable());
         }
+        if (null != ctx.RETURNING()) {
+            ListExpression list = new 
ListExpression(ctx.start.getStartIndex(), ctx.stop.getStopIndex());
+            list.getItems()
+                    .addAll(Arrays.asList(new 
LiteralExpressionSegment(ctx.path().start.getStartIndex(), 
ctx.path().stop.getStopIndex(), ctx.path().getText()),
+                            new 
LiteralExpressionSegment(ctx.RETURNING().getSymbol().getStartIndex(), 
ctx.RETURNING().getSymbol().getStopIndex(), 
ctx.RETURNING().getSymbol().getText()),
+                            (ExpressionSegment) visit(ctx.dataType())));
+            return list;
+        }
         if (null != ctx.LBE_()) {
             return visit(ctx.expr(0));
         }
diff --git a/test/it/optimizer/src/test/resources/converter/select.xml 
b/test/it/optimizer/src/test/resources/converter/select.xml
index 8bcd8cc3c15..50f904e895e 100644
--- a/test/it/optimizer/src/test/resources/converter/select.xml
+++ b/test/it/optimizer/src/test/resources/converter/select.xml
@@ -19,4 +19,5 @@
 <sql-node-converter-test-cases>
     <test-cases 
sql-case-id="select_with_database_name_and_schema_name_in_table" 
expected-sql="SELECT &quot;order_id&quot; FROM 
&quot;sharding_db&quot;.&quot;public&quot;.&quot;t_order&quot; WHERE 
&quot;user_id&quot; = ? AND &quot;order_id&quot; = ?" 
db-types="PostgreSQL,openGauss" sql-case-types="PLACEHOLDER" />
     <test-cases 
sql-case-id="select_with_database_name_and_schema_name_in_table" 
expected-sql="SELECT &quot;order_id&quot; FROM 
&quot;sharding_db&quot;.&quot;public&quot;.&quot;t_order&quot; WHERE 
&quot;user_id&quot; = 1 AND &quot;order_id&quot; = 1" 
db-types="PostgreSQL,openGauss" sql-case-types="LITERAL" />
+    <test-cases sql-case-id="select_with_json_value_return_type" 
expected-sql="SELECT * FROM `t_order` WHERE JSON_VALUE(`items`, '''$.name''' 
'RETURNING' VARCHAR(100)) = 'jack'" db-types="MySQL" />
 </sql-node-converter-test-cases>
diff --git a/test/it/parser/src/main/resources/case/dml/select-expression.xml 
b/test/it/parser/src/main/resources/case/dml/select-expression.xml
index b1d9e8c7c27..2becc5b332b 100644
--- a/test/it/parser/src/main/resources/case/dml/select-expression.xml
+++ b/test/it/parser/src/main/resources/case/dml/select-expression.xml
@@ -2055,7 +2055,17 @@
         </projections>
         <where start-index="22" stop-index="76">
             <expr>
-                <function function-name="JSON_CONTAINS" 
text="JSON_CONTAINS(order_msg -> '$[*].code', 'x', '$')" start-index="28" 
stop-index="76" />
+                <function function-name="JSON_CONTAINS" 
text="JSON_CONTAINS(order_msg -> '$[*].code', 'x', '$')" start-index="28" 
stop-index="76" >
+                    <parameter>
+                        <function start-index="42" stop-index="65" 
function-name="->" text="order_msg -> '$[*].code'" />
+                    </parameter>
+                    <parameter>
+                        <literal-expression start-index="68" stop-index="70" 
value="x" />
+                    </parameter>
+                    <parameter>
+                        <literal-expression start-index="73" stop-index="75" 
value="$" />
+                    </parameter>
+                </function>
             </expr>
         </where>
     </select>
@@ -2070,7 +2080,18 @@
         </from>
         <where start-index="43" stop-index="84">
             <expr>
-                <function function-name="json_contains" 
text="json_contains(order_info, ?, '$.id')" 
literal-text="json_contains(order_info, 1, '$.id')" start-index="49" 
stop-index="84" />
+                <function function-name="json_contains" 
text="json_contains(order_info, ?, '$.id')" 
literal-text="json_contains(order_info, 1, '$.id')" start-index="49" 
stop-index="84" >
+                    <parameter>
+                        <column start-index="63" stop-index="72" 
name="order_info" />
+                    </parameter>
+                    <parameter>
+                        <parameter-marker-expression start-index="75" 
stop-index="75" parameter-index="0" />
+                        <literal-expression start-index="75" stop-index="75" 
value="1" />
+                    </parameter>
+                    <parameter>
+                        <literal-expression start-index="78" stop-index="83" 
value="$.id" />
+                    </parameter>
+                </function>
             </expr>
         </where>
         <limit start-index="86" stop-index="95">
diff --git a/test/it/parser/src/main/resources/case/dml/select.xml 
b/test/it/parser/src/main/resources/case/dml/select.xml
index 229ed1d6134..8009fe15404 100644
--- a/test/it/parser/src/main/resources/case/dml/select.xml
+++ b/test/it/parser/src/main/resources/case/dml/select.xml
@@ -3748,7 +3748,17 @@
                                 <column name="items" start-index="39" 
stop-index="43" />
                             </parameter>
                             <parameter>
-                                <common-expression text="'$.name' RETURNING 
VARCHAR(100)" start-index="46" stop-index="76" />
+                                <list-expression start-index="46" 
stop-index="76" >
+                                    <items>
+                                        <literal-expression start-index="46" 
stop-index="53" value="'$.name'" />
+                                    </items>
+                                    <items>
+                                        <literal-expression start-index="55" 
stop-index="63" value="RETURNING" />
+                                    </items>
+                                    <items>
+                                        <data-type value="VARCHAR" 
start-index="65" stop-index="76" />
+                                    </items>
+                                </list-expression>
                             </parameter>
                         </function>
                     </left>

Reply via email to