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 8ed52536168 Support oracle wm_concat function parse (#28945)
8ed52536168 is described below

commit 8ed525361686d0febb63d3adba3b25fde6b8ceba
Author: niu niu <[email protected]>
AuthorDate: Mon Nov 6 08:00:43 2023 +0800

    Support oracle wm_concat function parse (#28945)
---
 .../src/main/antlr4/imports/oracle/BaseRule.g4     |   6 +-
 .../src/main/antlr4/imports/oracle/Keyword.g4      |   4 +
 .../visitor/statement/OracleStatementVisitor.java  |  11 ++
 .../parser/src/main/resources/case/dml/select.xml  | 142 +++++++++++++++++++++
 .../main/resources/sql/supported/dml/select.xml    |   4 +
 5 files changed, 166 insertions(+), 1 deletion(-)

diff --git 
a/parser/sql/dialect/oracle/src/main/antlr4/imports/oracle/BaseRule.g4 
b/parser/sql/dialect/oracle/src/main/antlr4/imports/oracle/BaseRule.g4
index de4c4074888..d18cb9e3b86 100644
--- a/parser/sql/dialect/oracle/src/main/antlr4/imports/oracle/BaseRule.g4
+++ b/parser/sql/dialect/oracle/src/main/antlr4/imports/oracle/BaseRule.g4
@@ -783,7 +783,11 @@ leadLagInfo
 
 specialFunction
     : castFunction | charFunction | extractFunction | formatFunction | 
firstOrLastValueFunction | trimFunction | featureFunction
-    | setFunction | translateFunction | cursorFunction | toDateFunction | 
approxRank
+    | setFunction | translateFunction | cursorFunction | toDateFunction | 
approxRank | wmConcatFunction
+    ;
+
+wmConcatFunction
+    : WM_CONCAT LP_ expr RP_ overClause?
     ;
 
 approxRank
diff --git 
a/parser/sql/dialect/oracle/src/main/antlr4/imports/oracle/Keyword.g4 
b/parser/sql/dialect/oracle/src/main/antlr4/imports/oracle/Keyword.g4
index 37d228e1e22..0580c89348a 100644
--- a/parser/sql/dialect/oracle/src/main/antlr4/imports/oracle/Keyword.g4
+++ b/parser/sql/dialect/oracle/src/main/antlr4/imports/oracle/Keyword.g4
@@ -835,3 +835,7 @@ ANYDATASET
 AUTONOMOUS_TRANSACTION
     : A U T O N O M O U S UL_ T R A N S A C T I O N
     ;
+
+WM_CONCAT
+    : W M UL_ C O N C A T
+    ;
diff --git 
a/parser/sql/dialect/oracle/src/main/java/org/apache/shardingsphere/sql/parser/oracle/visitor/statement/OracleStatementVisitor.java
 
b/parser/sql/dialect/oracle/src/main/java/org/apache/shardingsphere/sql/parser/oracle/visitor/statement/OracleStatementVisitor.java
index 915d2a392c1..7b375b5e28a 100644
--- 
a/parser/sql/dialect/oracle/src/main/java/org/apache/shardingsphere/sql/parser/oracle/visitor/statement/OracleStatementVisitor.java
+++ 
b/parser/sql/dialect/oracle/src/main/java/org/apache/shardingsphere/sql/parser/oracle/visitor/statement/OracleStatementVisitor.java
@@ -85,6 +85,7 @@ import 
org.apache.shardingsphere.sql.parser.autogen.OracleStatementParser.TrimFu
 import 
org.apache.shardingsphere.sql.parser.autogen.OracleStatementParser.TypeNameContext;
 import 
org.apache.shardingsphere.sql.parser.autogen.OracleStatementParser.UnreservedWordContext;
 import 
org.apache.shardingsphere.sql.parser.autogen.OracleStatementParser.ViewNameContext;
+import 
org.apache.shardingsphere.sql.parser.autogen.OracleStatementParser.WmConcatFunctionContext;
 import 
org.apache.shardingsphere.sql.parser.autogen.OracleStatementParser.XmlAggFunctionContext;
 import 
org.apache.shardingsphere.sql.parser.autogen.OracleStatementParser.XmlCdataFunctionContext;
 import 
org.apache.shardingsphere.sql.parser.autogen.OracleStatementParser.XmlColattvalFunctionContext;
@@ -710,6 +711,13 @@ public abstract class OracleStatementVisitor extends 
OracleStatementBaseVisitor<
                 : createAggregationFunctionSegment(ctx, aggregationType);
     }
     
+    @Override
+    public ASTNode visitWmConcatFunction(final WmConcatFunctionContext ctx) {
+        FunctionSegment result = new 
FunctionSegment(ctx.getStart().getStartIndex(), ctx.getStop().getStopIndex(), 
ctx.WM_CONCAT().getText(), getOriginalText(ctx));
+        result.getParameters().add((ExpressionSegment) visit(ctx.expr()));
+        return result;
+    }
+    
     private FunctionSegment createAggregationFunctionSegment(final 
AggregationFunctionContext ctx, final String aggregationType) {
         FunctionSegment result = new 
FunctionSegment(ctx.getStart().getStartIndex(), ctx.getStop().getStopIndex(), 
aggregationType, getOriginalText(ctx));
         result.getParameters().addAll(getExpressions(ctx.expr()));
@@ -982,6 +990,9 @@ public abstract class OracleStatementVisitor extends 
OracleStatementBaseVisitor<
         if (null != ctx.approxRank()) {
             return visit(ctx.approxRank());
         }
+        if (null != ctx.wmConcatFunction()) {
+            return visit(ctx.wmConcatFunction());
+        }
         throw new IllegalStateException(
                 "SpecialFunctionContext must have castFunction, charFunction, 
extractFunction, formatFunction, firstOrLastValueFunction, trimFunction, 
toDateFunction, approxCount"
                         + " or featureFunction.");
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 9dd07a52faf..8a497f44e3c 100644
--- a/test/it/parser/src/main/resources/case/dml/select.xml
+++ b/test/it/parser/src/main/resources/case/dml/select.xml
@@ -7032,4 +7032,146 @@
                           literal-stop-index="32"/>
         </from>
     </select>
+    
+    <select sql-case-id="select_wm_concat_function1">
+        <projections start-index="7" stop-index="72">
+            <expression-projection alias="ID" text="TO_CHAR(WM_CONCAT(DISTINCT 
TEST_ID) OVER(PARTITION BY TEST_ID))" start-index="7" stop-index="72">
+                <expr>
+                    <function alias="ID" function-name="TO_CHAR" 
text="TO_CHAR(WM_CONCAT(DISTINCT TEST_ID) OVER(PARTITION BY TEST_ID))" 
start-index="7" stop-index="69">
+                        <parameter>
+                            <function alias="ID" function-name="WM_CONCAT" 
text="WM_CONCAT(DISTINCT TEST_ID) OVER(PARTITION BY TEST_ID)" start-index="15" 
stop-index="68">
+                                <parameter>
+                                    <column name="TEST_ID" start-index="34" 
stop-index="40" />
+                                </parameter>
+                            </function>
+                        </parameter>
+                    </function>
+                </expr>
+            </expression-projection>
+        </projections>
+        <from>
+            <simple-table name="TEST_TABLE" start-index="79" stop-index="88" />
+        </from>
+    </select>
+    
+    <select sql-case-id="select_wm_concat_function2">
+        <projections start-index="7" stop-index="26">
+            <expression-projection alias="NAME" text="WM_CONCAT(NAME)" 
start-index="7" stop-index="26">
+                <expr>
+                    <function alias="ID" function-name="WM_CONCAT" 
text="WM_CONCAT(NAME)" start-index="7" stop-index="21">
+                        <parameter>
+                            <column name="NAME" start-index="17" 
stop-index="20" />
+                        </parameter>
+                    </function>
+                </expr>
+            </expression-projection>
+        </projections>
+        <from>
+            <simple-table name="TEST_TABLE" start-index="33" stop-index="42" />
+        </from>
+    </select>
+    
+    <select sql-case-id="select_wm_concat_function3">
+        <projections start-index="7" stop-index="38">
+            <expression-projection text="REPLACE(WM_CONCAT(NAME),',','|')" 
start-index="7" stop-index="38">
+                <expr>
+                    <function function-name="REPLACE" 
text="REPLACE(WM_CONCAT(NAME),',','|')" start-index="7" stop-index="38">
+                        <parameter>
+                            <function alias="ID" function-name="WM_CONCAT" 
text="WM_CONCAT(NAME)" start-index="15" stop-index="29">
+                                <parameter>
+                                    <column name="NAME" start-index="25" 
stop-index="28" />
+                                </parameter>
+                            </function>
+                        </parameter>
+                        <parameter>
+                            <literal-expression start-index="31" 
stop-index="33" value="," />
+                        </parameter>
+                        <parameter>
+                            <literal-expression start-index="35" 
stop-index="37" value="|" />
+                        </parameter>
+                    </function>
+                </expr>
+            </expression-projection>
+        </projections>
+        <from>
+            <simple-table name="TEST_TABLE" start-index="45" stop-index="54" />
+        </from>
+    </select>
+    
+    <select sql-case-id="select_wm_concat_function4">
+        <projections start-index="7" stop-index="102">
+            <column-projection name="NAME" start-index="7" stop-index="10" />
+            <expression-projection alias="WM_NAME" 
text="WM_CONCAT(DECODE(SUBSTR((TO_CHAR(NAME)),0,1),'.','0'||TO_CHAR(NAME),TO_CHAR(NAME)))"
 start-index="12" stop-index="102">
+                <expr>
+                    <function function-name="WM_CONCAT" 
text="WM_CONCAT(DECODE(SUBSTR((TO_CHAR(NAME)),0,1),'.','0'||TO_CHAR(NAME),TO_CHAR(NAME)))"
 start-index="12" stop-index="94">
+                        <parameter>
+                            <function function-name="DECODE" 
text="DECODE(SUBSTR((TO_CHAR(NAME)),0,1),'.','0'||TO_CHAR(NAME),TO_CHAR(NAME))" 
start-index="22" stop-index="93">
+                                <parameter>
+                                    <function function-name="SUBSTR" 
text="SUBSTR((TO_CHAR(NAME)),0,1)" start-index="29" stop-index="55">
+                                        <parameter>
+                                            <function function-name="TO_CHAR" 
text="TO_CHAR(NAME)" start-index="37" stop-index="49">
+                                                <parameter>
+                                                    <column name="NAME" 
start-index="45" stop-index="48" />
+                                                </parameter>
+                                            </function>
+                                        </parameter>
+                                        <parameter>
+                                            <literal-expression 
start-index="52" stop-index="52" value="0" />
+                                        </parameter>
+                                        <parameter>
+                                            <literal-expression 
start-index="54" stop-index="54" value="1" />
+                                        </parameter>
+                                    </function>
+                                </parameter>
+                                <parameter>
+                                    <literal-expression start-index="57" 
stop-index="59" value="." />
+                                </parameter>
+                                <parameter>
+                                    <binary-operation-expression 
text="'0'||TO_CHAR(NAME)" start-index="61" stop-index="78">
+                                        <left>
+                                            <literal-expression 
start-index="61" stop-index="63" value="0" />
+                                        </left>
+                                        <right>
+                                            <function start-index="66" 
stop-index="78" text="TO_CHAR(NAME)" function-name="TO_CHAR">
+                                                <parameter>
+                                                    <column name="NAME" 
start-index="74" stop-index="77" />
+                                                </parameter>
+                                            </function>
+                                        </right>
+                                        <operator>||</operator>
+                                    </binary-operation-expression>
+                                </parameter>
+                                <parameter>
+                                    <function function-name="TO_CHAR" 
text="TO_CHAR(NAME)" start-index="80" stop-index="92">
+                                        <parameter>
+                                            <column name="NAME" 
start-index="88" stop-index="91" />
+                                        </parameter>
+                                    </function>
+                                </parameter>
+                            </function>
+                        </parameter>
+                    </function>
+                </expr>
+            </expression-projection>
+        </projections>
+        <from>
+            <simple-table name="TEST_TABLE" start-index="109" stop-index="118" 
/>
+        </from>
+        <where start-index="120" stop-index="137">
+            <expr>
+                <binary-operation-expression text="NAME ='TEST'" 
start-index="126" stop-index="137">
+                    <left>
+                        <column name="NAME" start-index="126" stop-index="129" 
/>
+                    </left>
+                    <right>
+                        <literal-expression start-index="132" stop-index="137" 
value="TEST" />
+                    </right>
+                    <operator>=</operator>
+                </binary-operation-expression>
+            </expr>
+        </where>
+        <group-by>
+            <column-item name="NAME" order-direction="ASC" start-index="148" 
stop-index="151" />
+        </group-by>
+    </select>
 </sql-parser-test-cases>
diff --git a/test/it/parser/src/main/resources/sql/supported/dml/select.xml 
b/test/it/parser/src/main/resources/sql/supported/dml/select.xml
index 47d15ee9abf..00db43c5587 100644
--- a/test/it/parser/src/main/resources/sql/supported/dml/select.xml
+++ b/test/it/parser/src/main/resources/sql/supported/dml/select.xml
@@ -213,4 +213,8 @@
     <sql-case id="select_numeric_operator" value="SELECT 5! AS RESULT;" 
db-types="openGauss" />
     <sql-case id="select_with_custom_distinct_function" value="select 
custom_concat(distinct a.P1) From TEST a;" db-types="Oracle" />
     <sql-case id="select_with_unicode_string" value="SELECT u'test', U'test' 
from DUAL" db-types="Oracle" />
+    <sql-case id="select_wm_concat_function1" value="SELECT 
TO_CHAR(WM_CONCAT(DISTINCT TEST_ID) OVER(PARTITION BY TEST_ID)) ID FROM 
TEST_TABLE" db-types="Oracle" />
+    <sql-case id="select_wm_concat_function2" value="SELECT WM_CONCAT(NAME) 
NAME FROM TEST_TABLE" db-types="Oracle" />
+    <sql-case id="select_wm_concat_function3" value="SELECT 
REPLACE(WM_CONCAT(NAME),',','|') FROM TEST_TABLE" db-types="Oracle" />
+    <sql-case id="select_wm_concat_function4" value="SELECT 
NAME,WM_CONCAT(DECODE(SUBSTR((TO_CHAR(NAME)),0,1),'.','0'||TO_CHAR(NAME),TO_CHAR(NAME)))
 WM_NAME FROM TEST_TABLE WHERE NAME ='TEST' GROUP BY NAME" db-types="Oracle" />
 </sql-cases>

Reply via email to