You are viewing a plain text version of this content. The canonical link for it is here.
Posted to notifications@shardingsphere.apache.org by pa...@apache.org on 2022/10/28 03:09:01 UTC

[shardingsphere] branch master updated: Support oracle analyticFunction parse (#21812)

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

panjuan 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 62005f74f50 Support oracle analyticFunction parse (#21812)
62005f74f50 is described below

commit 62005f74f508ff0e5ae3d5882fbbf0cd19c4784f
Author: Zhengqiang Duan <du...@apache.org>
AuthorDate: Fri Oct 28 11:08:55 2022 +0800

    Support oracle analyticFunction parse (#21812)
---
 .../src/main/antlr4/imports/oracle/BaseRule.g4     |  6 ++++-
 .../src/main/antlr4/imports/oracle/DMLStatement.g4 |  8 -------
 .../statement/impl/OracleStatementSQLVisitor.java  | 15 +++++++++++-
 test/parser/src/main/resources/case/dml/select.xml | 28 ++++++++++++++++++++++
 .../main/resources/sql/supported/dml/select.xml    |  1 +
 5 files changed, 48 insertions(+), 10 deletions(-)

diff --git a/sql-parser/dialect/oracle/src/main/antlr4/imports/oracle/BaseRule.g4 b/sql-parser/dialect/oracle/src/main/antlr4/imports/oracle/BaseRule.g4
index 585b3a7726b..0f9c5692ddb 100644
--- a/sql-parser/dialect/oracle/src/main/antlr4/imports/oracle/BaseRule.g4
+++ b/sql-parser/dialect/oracle/src/main/antlr4/imports/oracle/BaseRule.g4
@@ -504,7 +504,7 @@ simpleExpr
     ;
 
 functionCall
-    : aggregationFunction | specialFunction | regularFunction 
+    : aggregationFunction | analyticFunction | specialFunction | regularFunction 
     ;
 
 aggregationFunction
@@ -528,6 +528,10 @@ windowingClause
     | (UNBOUNDED PRECEDING | CURRENT ROW | expr PRECEDING))
     ;
 
+analyticFunction
+    : analyticFunctionName LP_ dataType* RP_ OVER LP_ analyticClause RP_
+    ;
+
 specialFunction
     : castFunction  | charFunction
     ;
diff --git a/sql-parser/dialect/oracle/src/main/antlr4/imports/oracle/DMLStatement.g4 b/sql-parser/dialect/oracle/src/main/antlr4/imports/oracle/DMLStatement.g4
index 508976d5048..3741ff2ba9b 100644
--- a/sql-parser/dialect/oracle/src/main/antlr4/imports/oracle/DMLStatement.g4
+++ b/sql-parser/dialect/oracle/src/main/antlr4/imports/oracle/DMLStatement.g4
@@ -670,14 +670,6 @@ modelExpr
     | analyticFunction) (PLUS_ modelExpr | ASTERISK_ numberLiterals (ASTERISK_ modelExpr)?)?
     ;
 
-analyticFunction
-    : analyticFunctionName LP_ arguments? RP_ OVER LP_ analyticClause RP_
-    ;
-
-arguments
-    : dataType*
-    ;
-
 forUpdateClause
     : FOR UPDATE (OF forUpdateClauseList)? ((NOWAIT | WAIT INTEGER_) | SKIP_SYMBOL LOCKED)?
     ;
diff --git a/sql-parser/dialect/oracle/src/main/java/org/apache/shardingsphere/sql/parser/oracle/visitor/statement/impl/OracleStatementSQLVisitor.java b/sql-parser/dialect/oracle/src/main/java/org/apache/shardingsphere/sql/parser/oracle/visitor/statement/impl/OracleStatementSQLVisitor.java
index ab63d091034..5ca12e13415 100644
--- a/sql-parser/dialect/oracle/src/main/java/org/apache/shardingsphere/sql/parser/oracle/visitor/statement/impl/OracleStatementSQLVisitor.java
+++ b/sql-parser/dialect/oracle/src/main/java/org/apache/shardingsphere/sql/parser/oracle/visitor/statement/impl/OracleStatementSQLVisitor.java
@@ -27,6 +27,7 @@ import org.antlr.v4.runtime.tree.TerminalNode;
 import org.apache.shardingsphere.sql.parser.api.visitor.ASTNode;
 import org.apache.shardingsphere.sql.parser.autogen.OracleStatementBaseVisitor;
 import org.apache.shardingsphere.sql.parser.autogen.OracleStatementParser.AggregationFunctionContext;
+import org.apache.shardingsphere.sql.parser.autogen.OracleStatementParser.AnalyticFunctionContext;
 import org.apache.shardingsphere.sql.parser.autogen.OracleStatementParser.BitExprContext;
 import org.apache.shardingsphere.sql.parser.autogen.OracleStatementParser.BitValueLiteralsContext;
 import org.apache.shardingsphere.sql.parser.autogen.OracleStatementParser.BooleanLiteralsContext;
@@ -477,10 +478,22 @@ public abstract class OracleStatementSQLVisitor extends OracleStatementBaseVisit
         if (null != ctx.specialFunction()) {
             return visit(ctx.specialFunction());
         }
+        if (null != ctx.analyticFunction()) {
+            return visit(ctx.analyticFunction());
+        }
         if (null != ctx.regularFunction()) {
             return visit(ctx.regularFunction());
         }
-        throw new IllegalStateException("FunctionCallContext must have aggregationFunction, regularFunction or specialFunction.");
+        throw new IllegalStateException("FunctionCallContext must have aggregationFunction, regularFunction, analyticFunction or specialFunction.");
+    }
+    
+    @Override
+    public ASTNode visitAnalyticFunction(final AnalyticFunctionContext ctx) {
+        FunctionSegment result = new FunctionSegment(ctx.getStart().getStartIndex(), ctx.getStop().getStopIndex(), ctx.analyticFunctionName().getText(), getOriginalText(ctx));
+        for (DataTypeContext each : ctx.dataType()) {
+            result.getParameters().add((DataTypeSegment) visit(each));
+        }
+        return result;
     }
     
     @Override
diff --git a/test/parser/src/main/resources/case/dml/select.xml b/test/parser/src/main/resources/case/dml/select.xml
index 2d677c43b5f..19b5eb84af6 100644
--- a/test/parser/src/main/resources/case/dml/select.xml
+++ b/test/parser/src/main/resources/case/dml/select.xml
@@ -4408,4 +4408,32 @@
             <column-projection name="UTC_TIMESTAMP" start-index="36" stop-index="48" />
         </projections>
     </select>
+
+    <select sql-case-id="select_with_analytic_function" parameters="1">
+        <projections start-index="7" stop-index="94">
+            <column-projection name="order_id" start-index="7" stop-index="14" />
+            <expression-projection text="ROW_NUMBER () OVER (PARTITION BY user_id ORDER BY order_id DESC)" start-index="17" stop-index="94" alias="row_number">
+                <expr>
+                    <function function-name="ROW_NUMBER" start-index="17" stop-index="80" text="ROW_NUMBER () OVER (PARTITION BY user_id ORDER BY order_id DESC)"/>
+                </expr>
+            </expression-projection>
+        </projections>
+        <from>
+            <simple-table name="t_order" start-index="101" stop-index="107" />
+        </from>
+        <where start-index="109" stop-index="126">
+            <expr>
+                <binary-operation-expression start-index="115" stop-index="126">
+                    <left>
+                        <column name="order_id" start-index="115" stop-index="122"/>
+                    </left>
+                    <right>
+                        <literal-expression value="1" start-index="126" stop-index="126" />
+                        <parameter-marker-expression parameter-index="0" start-index="126" stop-index="126" />
+                    </right>
+                    <operator>=</operator>
+                </binary-operation-expression>
+            </expr>
+        </where>
+    </select>
 </sql-parser-test-cases>
diff --git a/test/parser/src/main/resources/sql/supported/dml/select.xml b/test/parser/src/main/resources/sql/supported/dml/select.xml
index 2d7660c2824..5cd7fbcb8e0 100644
--- a/test/parser/src/main/resources/sql/supported/dml/select.xml
+++ b/test/parser/src/main/resources/sql/supported/dml/select.xml
@@ -132,4 +132,5 @@
     <sql-case id="select_with_xml_namespaces_clause" value="WITH XMLNAMESPACES ('uri' AS ns1) SELECT order_id AS 'ns1:order_id', status AS 'ns1:status' FROM t_order FOR XML RAW ('ns1:order'), ELEMENTS" db-types="SQLServer" />
     <sql-case id="select_with_xml_default_namespaces_clause" value="WITH XMLNAMESPACES ('uri1' AS ns1, 'uri2' AS ns2, DEFAULT 'uri2') SELECT order_id AS 'ns1:order_id', status AS 'ns1:status' FROM t_order FOR XML RAW ('ns1:order'), ELEMENTS XSINIL" db-types="SQLServer" />
     <sql-case id="select_with_mysql_main_and_utc_data_and_so_on" value="SELECT MYSQL_MAIN,UTC_DATE,UTC_TIME,UTC_TIMESTAMP FROM test" db-types="MySQL" />
+    <sql-case id="select_with_analytic_function" value="SELECT order_id, ROW_NUMBER () OVER (PARTITION BY user_id ORDER BY order_id DESC) AS row_number FROM t_order WHERE order_id = ?" db-types="Oracle" />
 </sql-cases>