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 f45bcb961a7 support for WindowFunction (#28285)
f45bcb961a7 is described below

commit f45bcb961a7ebe2afea5dc943dcdcac15d46c87c
Author: Yunbo Ni <[email protected]>
AuthorDate: Mon Sep 4 15:14:42 2023 +0800

    support for WindowFunction (#28285)
    
    * feat: windowing clause
    
    * fix: final class
    
    * fix: checkstyle
    
    * fix: import *
    
    * fix: ci error - internal mysql parser it
---
 .../segment/expression/impl/FunctionConverter.java |  3 ++
 ...Converter.java => WindowFunctionConverter.java} | 33 ++++++++--------------
 .../visitor/statement/MySQLStatementVisitor.java   |  5 +++-
 .../converter/select-special-function.xml          |  1 +
 .../resources/case/dml/select-special-function.xml |  6 +++-
 5 files changed, 25 insertions(+), 23 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 89e964dc3a9..e687f92b011 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
@@ -52,6 +52,9 @@ public class FunctionConverter implements 
SQLSegmentConverter<FunctionSegment, S
         if ("TRIM".equalsIgnoreCase(functionName.getSimple())) {
             return new TrimFunctionConverter().convert(segment);
         }
+        if ("OVER".equalsIgnoreCase(functionName.getSimple())) {
+            return new WindowFunctionConverter().convert(segment);
+        }
         List<SqlOperator> functions = new LinkedList<>();
         SqlStdOperatorTable.instance().lookupOperatorOverloads(functionName, 
null, SqlSyntax.FUNCTION, functions, SqlNameMatchers.withCaseSensitive(false));
         return Optional.of(functions.isEmpty()
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/WindowFunctionConverter.java
similarity index 63%
copy from 
kernel/sql-federation/core/src/main/java/org/apache/shardingsphere/sqlfederation/compiler/converter/segment/expression/impl/FunctionConverter.java
copy to 
kernel/sql-federation/core/src/main/java/org/apache/shardingsphere/sqlfederation/compiler/converter/segment/expression/impl/WindowFunctionConverter.java
index 89e964dc3a9..18f59c3f096 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/WindowFunctionConverter.java
@@ -17,19 +17,19 @@
 
 package 
org.apache.shardingsphere.sqlfederation.compiler.converter.segment.expression.impl;
 
-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.SqlOperator;
 import org.apache.calcite.sql.SqlSyntax;
-import org.apache.calcite.sql.SqlUnresolvedFunction;
+import org.apache.calcite.sql.SqlBasicCall;
+import org.apache.calcite.sql.SqlWindow;
+import org.apache.calcite.sql.SqlNodeList;
+import org.apache.calcite.sql.SqlLiteral;
 import org.apache.calcite.sql.fun.SqlStdOperatorTable;
 import org.apache.calcite.sql.parser.SqlParserPos;
 import org.apache.calcite.sql.validate.SqlNameMatchers;
 import 
org.apache.shardingsphere.sql.parser.sql.common.segment.dml.expr.ExpressionSegment;
 import 
org.apache.shardingsphere.sql.parser.sql.common.segment.dml.expr.FunctionSegment;
-import 
org.apache.shardingsphere.sqlfederation.compiler.converter.segment.SQLSegmentConverter;
 import 
org.apache.shardingsphere.sqlfederation.compiler.converter.segment.expression.ExpressionConverter;
 
 import java.util.Collection;
@@ -37,34 +37,25 @@ import java.util.LinkedList;
 import java.util.List;
 import java.util.Optional;
 
-/**
- * Function converter.
- */
-public class FunctionConverter implements SQLSegmentConverter<FunctionSegment, 
SqlNode> {
+public final class WindowFunctionConverter extends FunctionConverter {
     
     @Override
     public Optional<SqlNode> convert(final FunctionSegment segment) {
         SqlIdentifier functionName = new 
SqlIdentifier(segment.getFunctionName(), SqlParserPos.ZERO);
-        // TODO optimize sql parse logic for select current_user.
-        if ("CURRENT_USER".equalsIgnoreCase(functionName.getSimple())) {
-            return Optional.of(functionName);
-        }
-        if ("TRIM".equalsIgnoreCase(functionName.getSimple())) {
-            return new TrimFunctionConverter().convert(segment);
-        }
         List<SqlOperator> functions = new LinkedList<>();
-        SqlStdOperatorTable.instance().lookupOperatorOverloads(functionName, 
null, SqlSyntax.FUNCTION, functions, SqlNameMatchers.withCaseSensitive(false));
-        return Optional.of(functions.isEmpty()
-                ? new SqlBasicCall(
-                        new SqlUnresolvedFunction(functionName, null, null, 
null, null, SqlFunctionCategory.USER_DEFINED_FUNCTION), 
getFunctionParameters(segment.getParameters()), SqlParserPos.ZERO)
-                : new SqlBasicCall(functions.iterator().next(), 
getFunctionParameters(segment.getParameters()), SqlParserPos.ZERO));
+        SqlStdOperatorTable.instance().lookupOperatorOverloads(functionName, 
null, SqlSyntax.BINARY, functions, SqlNameMatchers.withCaseSensitive(false));
+        return Optional.of(new SqlBasicCall(functions.iterator().next(), 
getWindowFunctionParameters(segment.getParameters()), SqlParserPos.ZERO));
     }
     
-    private List<SqlNode> getFunctionParameters(final 
Collection<ExpressionSegment> sqlSegments) {
+    private List<SqlNode> getWindowFunctionParameters(final 
Collection<ExpressionSegment> sqlSegments) {
         List<SqlNode> result = new LinkedList<>();
         for (ExpressionSegment each : sqlSegments) {
             new ExpressionConverter().convert(each).ifPresent(result::add);
         }
+        if (1 == result.size()) {
+            result.add(new SqlWindow(SqlParserPos.ZERO, null, null, new 
SqlNodeList(SqlParserPos.ZERO), new SqlNodeList(SqlParserPos.ZERO), 
SqlLiteral.createBoolean(false, SqlParserPos.ZERO), null,
+                    null, null));
+        }
         return result;
     }
 }
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 da49df9f066..7673d381e0c 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
@@ -995,7 +995,10 @@ public abstract class MySQLStatementVisitor extends 
MySQLStatementBaseVisitor<AS
     @Override
     public final ASTNode visitWindowFunction(final WindowFunctionContext ctx) {
         super.visitWindowFunction(ctx);
-        return new FunctionSegment(ctx.getStart().getStartIndex(), 
ctx.getStop().getStopIndex(), ctx.funcName.getText(), getOriginalText(ctx));
+        FunctionSegment result = new 
FunctionSegment(ctx.getStart().getStartIndex(), ctx.getStop().getStopIndex(), 
ctx.windowingClause().OVER().getText(), getOriginalText(ctx));
+        result.getParameters().add(new 
FunctionSegment(ctx.funcName.getStartIndex(), ctx.funcName.getStopIndex(), 
ctx.funcName.getText(), ctx.funcName.getText() + "()"));
+        
result.getParameters().addAll(getWindowSpecification(ctx.windowingClause().windowSpecification()));
+        return result;
     }
     
     @Override
diff --git 
a/test/it/optimizer/src/test/resources/converter/select-special-function.xml 
b/test/it/optimizer/src/test/resources/converter/select-special-function.xml
index 812bb212128..ed4357793f0 100644
--- a/test/it/optimizer/src/test/resources/converter/select-special-function.xml
+++ b/test/it/optimizer/src/test/resources/converter/select-special-function.xml
@@ -18,4 +18,5 @@
 
 <sql-node-converter-test-cases>
     <test-cases sql-case-id="select_extract_function" expected-sql="SELECT 
EXTRACT(&quot;YEAR&quot; FROM CAST('2001-02-16 20:38:40' AS TIMESTAMP))" 
db-types="PostgreSQL,openGauss" />
+    <test-cases sql-case-id="select_window_function" expected-sql="SELECT 
`order_id`, ROW_NUMBER() OVER () FROM `t_order`" db-types="MySQL" />
 </sql-node-converter-test-cases>
diff --git 
a/test/it/parser/src/main/resources/case/dml/select-special-function.xml 
b/test/it/parser/src/main/resources/case/dml/select-special-function.xml
index 96647f9d6fe..83d5fdb5c8c 100644
--- a/test/it/parser/src/main/resources/case/dml/select-special-function.xml
+++ b/test/it/parser/src/main/resources/case/dml/select-special-function.xml
@@ -41,7 +41,11 @@
             <column-projection name="order_id" start-index="7" stop-index="14" 
/>
             <expression-projection text="ROW_NUMBER() OVER()" start-index="17" 
stop-index="35">
                 <expr>
-                    <function function-name="ROW_NUMBER" start-index="17" 
stop-index="35" text="ROW_NUMBER() OVER()" />
+                    <function function-name="OVER" start-index="17" 
stop-index="35" text="ROW_NUMBER() OVER()" >
+                        <parameter>
+                            <function function-name="ROW_NUMBER" 
start-index="17" stop-index="26" text="ROW_NUMBER()" />
+                        </parameter>
+                    </function>
                 </expr>
             </expression-projection>
         </projections>

Reply via email to