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 87cefce891a Support explain sqlNodeConverter (#28161)
87cefce891a is described below

commit 87cefce891abdecad7dfe51d89b33c6d590aabea
Author: niu niu <[email protected]>
AuthorDate: Fri Aug 18 18:41:40 2023 +0800

    Support explain sqlNodeConverter (#28161)
    
    * Support explain sqlNodeConverter
    
    * Format code
    
    * Rename method
---
 .../compiler/converter/SQLNodeConverterEngine.java |  5 +++
 .../explain/ExplainStatementConverter.java}        | 47 ++++++++++++----------
 .../converter/SQLNodeConverterEngineIT.java        |  8 +++-
 .../src/test/resources/converter/explain.xml       | 32 +++++++++++++++
 4 files changed, 69 insertions(+), 23 deletions(-)

diff --git 
a/kernel/sql-federation/core/src/main/java/org/apache/shardingsphere/sqlfederation/compiler/converter/SQLNodeConverterEngine.java
 
b/kernel/sql-federation/core/src/main/java/org/apache/shardingsphere/sqlfederation/compiler/converter/SQLNodeConverterEngine.java
index 756e92dede0..92520797027 100644
--- 
a/kernel/sql-federation/core/src/main/java/org/apache/shardingsphere/sqlfederation/compiler/converter/SQLNodeConverterEngine.java
+++ 
b/kernel/sql-federation/core/src/main/java/org/apache/shardingsphere/sqlfederation/compiler/converter/SQLNodeConverterEngine.java
@@ -21,9 +21,11 @@ import lombok.AccessLevel;
 import lombok.NoArgsConstructor;
 import org.apache.calcite.sql.SqlNode;
 import org.apache.shardingsphere.sql.parser.sql.common.statement.SQLStatement;
+import 
org.apache.shardingsphere.sql.parser.sql.common.statement.dal.ExplainStatement;
 import 
org.apache.shardingsphere.sql.parser.sql.common.statement.dml.DeleteStatement;
 import 
org.apache.shardingsphere.sql.parser.sql.common.statement.dml.SelectStatement;
 import 
org.apache.shardingsphere.sqlfederation.compiler.converter.statement.delete.DeleteStatementConverter;
+import 
org.apache.shardingsphere.sqlfederation.compiler.converter.statement.explain.ExplainStatementConverter;
 import 
org.apache.shardingsphere.sqlfederation.exception.OptimizationSQLNodeConvertException;
 import 
org.apache.shardingsphere.sqlfederation.compiler.converter.statement.select.SelectStatementConverter;
 
@@ -47,6 +49,9 @@ public final class SQLNodeConverterEngine {
         if (statement instanceof DeleteStatement) {
             return new DeleteStatementConverter().convert((DeleteStatement) 
statement);
         }
+        if (statement instanceof ExplainStatement) {
+            return new ExplainStatementConverter().convert((ExplainStatement) 
statement);
+        }
         throw new OptimizationSQLNodeConvertException(statement);
     }
 }
diff --git 
a/kernel/sql-federation/core/src/main/java/org/apache/shardingsphere/sqlfederation/compiler/converter/SQLNodeConverterEngine.java
 
b/kernel/sql-federation/core/src/main/java/org/apache/shardingsphere/sqlfederation/compiler/converter/statement/explain/ExplainStatementConverter.java
similarity index 52%
copy from 
kernel/sql-federation/core/src/main/java/org/apache/shardingsphere/sqlfederation/compiler/converter/SQLNodeConverterEngine.java
copy to 
kernel/sql-federation/core/src/main/java/org/apache/shardingsphere/sqlfederation/compiler/converter/statement/explain/ExplainStatementConverter.java
index 756e92dede0..1a71b866298 100644
--- 
a/kernel/sql-federation/core/src/main/java/org/apache/shardingsphere/sqlfederation/compiler/converter/SQLNodeConverterEngine.java
+++ 
b/kernel/sql-federation/core/src/main/java/org/apache/shardingsphere/sqlfederation/compiler/converter/statement/explain/ExplainStatementConverter.java
@@ -15,38 +15,43 @@
  * limitations under the License.
  */
 
-package org.apache.shardingsphere.sqlfederation.compiler.converter;
+package 
org.apache.shardingsphere.sqlfederation.compiler.converter.statement.explain;
 
-import lombok.AccessLevel;
-import lombok.NoArgsConstructor;
 import org.apache.calcite.sql.SqlNode;
+import org.apache.calcite.sql.SqlExplain;
+import org.apache.calcite.sql.SqlExplainLevel;
+import org.apache.calcite.sql.SqlExplainFormat;
+import org.apache.calcite.sql.parser.SqlParserPos;
 import org.apache.shardingsphere.sql.parser.sql.common.statement.SQLStatement;
+import 
org.apache.shardingsphere.sql.parser.sql.common.statement.dal.ExplainStatement;
 import 
org.apache.shardingsphere.sql.parser.sql.common.statement.dml.DeleteStatement;
 import 
org.apache.shardingsphere.sql.parser.sql.common.statement.dml.SelectStatement;
+import 
org.apache.shardingsphere.sqlfederation.compiler.converter.statement.SQLStatementConverter;
 import 
org.apache.shardingsphere.sqlfederation.compiler.converter.statement.delete.DeleteStatementConverter;
-import 
org.apache.shardingsphere.sqlfederation.exception.OptimizationSQLNodeConvertException;
 import 
org.apache.shardingsphere.sqlfederation.compiler.converter.statement.select.SelectStatementConverter;
 
 /**
- * SQL node converter engine.
+ * Explain statement converter.
  */
-@NoArgsConstructor(access = AccessLevel.PRIVATE)
-public final class SQLNodeConverterEngine {
+public final class ExplainStatementConverter implements 
SQLStatementConverter<ExplainStatement, SqlNode> {
     
-    /**
-     * Convert SQL statement to SQL node.
-     * 
-     * @param statement SQL statement to be converted
-     * @return sqlNode converted SQL node
-     * @throws OptimizationSQLNodeConvertException optimization SQL node 
convert exception
-     */
-    public static SqlNode convert(final SQLStatement statement) {
-        if (statement instanceof SelectStatement) {
-            return new SelectStatementConverter().convert((SelectStatement) 
statement);
-        }
-        if (statement instanceof DeleteStatement) {
-            return new DeleteStatementConverter().convert((DeleteStatement) 
statement);
+    @Override
+    public SqlNode convert(final ExplainStatement deleteStatement) {
+        return new SqlExplain(SqlParserPos.ZERO, 
convertSQLStatement(deleteStatement), 
SqlExplainLevel.ALL_ATTRIBUTES.symbol(SqlParserPos.ZERO),
+                SqlExplain.Depth.TYPE.symbol(SqlParserPos.ZERO), 
SqlExplainFormat.TEXT.symbol(SqlParserPos.ZERO), 0);
+    }
+    
+    private SqlNode convertSQLStatement(final ExplainStatement 
deleteStatement) {
+        return 
deleteStatement.getStatement().map(this::convertSqlNode).orElseThrow(IllegalStateException::new);
+    }
+    
+    private SqlNode convertSqlNode(final SQLStatement sqlStatement) {
+        if (sqlStatement instanceof SelectStatement) {
+            return new SelectStatementConverter().convert((SelectStatement) 
sqlStatement);
+        } else if (sqlStatement instanceof DeleteStatement) {
+            return new DeleteStatementConverter().convert((DeleteStatement) 
sqlStatement);
         }
-        throw new OptimizationSQLNodeConvertException(statement);
+        // TODO other statement converter.
+        return null;
     }
 }
diff --git 
a/test/it/optimizer/src/test/java/org/apache/shardingsphere/test/it/optimizer/converter/SQLNodeConverterEngineIT.java
 
b/test/it/optimizer/src/test/java/org/apache/shardingsphere/test/it/optimizer/converter/SQLNodeConverterEngineIT.java
index d78bd543740..d6d6b39a7b4 100644
--- 
a/test/it/optimizer/src/test/java/org/apache/shardingsphere/test/it/optimizer/converter/SQLNodeConverterEngineIT.java
+++ 
b/test/it/optimizer/src/test/java/org/apache/shardingsphere/test/it/optimizer/converter/SQLNodeConverterEngineIT.java
@@ -60,6 +60,8 @@ class SQLNodeConverterEngineIT {
     
     private static final String DELETE_STATEMENT_PREFIX = "DELETE";
     
+    private static final String EXPLAIN_STATEMENT_PREFIX = "EXPLAIN";
+    
     @ParameterizedTest(name = "{0} ({1}) -> {2}")
     @ArgumentsSource(TestCaseArgumentsProvider.class)
     void assertConvert(final String sqlCaseId, final SQLCaseType sqlCaseType, 
final String databaseType) {
@@ -83,7 +85,7 @@ class SQLNodeConverterEngineIT {
         
         @Override
         public Stream<? extends Arguments> provideArguments(final 
ExtensionContext extensionContext) {
-            return getTestParameters("MySQL", "PostgreSQL", 
"openGauss").stream();
+            return getTestParameters("MySQL", "PostgreSQL", "openGauss", 
"Oracle").stream();
         }
         
         private Collection<Arguments> getTestParameters(final String... 
databaseTypes) {
@@ -101,7 +103,9 @@ class SQLNodeConverterEngineIT {
         }
         
         private boolean isSupportedSQLCase(final 
InternalSQLParserTestParameter testParam) {
-            return 
testParam.getSqlCaseId().toUpperCase().startsWith(SELECT_STATEMENT_PREFIX) || 
testParam.getSqlCaseId().toUpperCase().startsWith(DELETE_STATEMENT_PREFIX);
+            return 
testParam.getSqlCaseId().toUpperCase().startsWith(SELECT_STATEMENT_PREFIX)
+                    || 
testParam.getSqlCaseId().toUpperCase().startsWith(DELETE_STATEMENT_PREFIX)
+                    || 
testParam.getSqlCaseId().toUpperCase().startsWith(EXPLAIN_STATEMENT_PREFIX);
         }
     }
 }
diff --git a/test/it/optimizer/src/test/resources/converter/explain.xml 
b/test/it/optimizer/src/test/resources/converter/explain.xml
new file mode 100644
index 00000000000..a8dad2f813d
--- /dev/null
+++ b/test/it/optimizer/src/test/resources/converter/explain.xml
@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+  ~ Licensed to the Apache Software Foundation (ASF) under one or more
+  ~ contributor license agreements.  See the NOTICE file distributed with
+  ~ this work for additional information regarding copyright ownership.
+  ~ The ASF licenses this file to You under the Apache License, Version 2.0
+  ~ (the "License"); you may not use this file except in compliance with
+  ~ the License.  You may obtain a copy of the License at
+  ~
+  ~     http://www.apache.org/licenses/LICENSE-2.0
+  ~
+  ~ Unless required by applicable law or agreed to in writing, software
+  ~ distributed under the License is distributed on an "AS IS" BASIS,
+  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  ~ See the License for the specific language governing permissions and
+  ~ limitations under the License.
+  -->
+
+<sql-node-converter-test-cases>
+    <test-cases sql-case-id="explain_select_constant_without_table" 
expected-sql="EXPLAIN PLAN INCLUDING ALL ATTRIBUTES WITH TYPE FOR SELECT 1 AS 
`a`" db-types="MySQL" sql-case-types="LITERAL" />
+    <test-cases sql-case-id="explain_select_constant_without_table" 
expected-sql="EXPLAIN PLAN INCLUDING ALL ATTRIBUTES WITH TYPE FOR SELECT ? AS 
`a`" db-types="MySQL" sql-case-types="PLACEHOLDER" />
+    <test-cases sql-case-id="explain_select_constant_without_table" 
expected-sql="EXPLAIN PLAN INCLUDING ALL ATTRIBUTES WITH TYPE FOR SELECT 1 AS 
&quot;a&quot;" db-types="PostgreSQL, openGauss" sql-case-types="LITERAL" />
+    <test-cases sql-case-id="explain_select_constant_without_table" 
expected-sql="EXPLAIN PLAN INCLUDING ALL ATTRIBUTES WITH TYPE FOR SELECT ? AS 
&quot;a&quot;" db-types="PostgreSQL, openGauss" sql-case-types="PLACEHOLDER" />
+    <test-cases sql-case-id="explain_delete_without_sharding_value" 
expected-sql="EXPLAIN PLAN INCLUDING ALL ATTRIBUTES WITH TYPE FOR DELETE FROM 
`t_order` WHERE `status` = 'init'" db-types="MySQL" sql-case-types="LITERAL" />
+    <test-cases sql-case-id="explain_delete_without_sharding_value" 
expected-sql="EXPLAIN PLAN INCLUDING ALL ATTRIBUTES WITH TYPE FOR DELETE FROM 
`t_order` WHERE `status` = ?" db-types="MySQL" sql-case-types="PLACEHOLDER" />
+    <test-cases sql-case-id="explain_delete_without_sharding_value" 
expected-sql="EXPLAIN PLAN INCLUDING ALL ATTRIBUTES WITH TYPE FOR DELETE FROM 
&quot;t_order&quot; WHERE &quot;status&quot; = 'init'" db-types="PostgreSQL, 
openGauss" sql-case-types="LITERAL" />
+    <test-cases sql-case-id="explain_delete_without_sharding_value" 
expected-sql="EXPLAIN PLAN INCLUDING ALL ATTRIBUTES WITH TYPE FOR DELETE FROM 
&quot;t_order&quot; WHERE &quot;status&quot; = ?" db-types="PostgreSQL, 
openGauss" sql-case-types="PLACEHOLDER" />
+    <test-cases sql-case-id="explain_for_select_with_analyze" 
expected-sql="EXPLAIN PLAN INCLUDING ALL ATTRIBUTES WITH TYPE FOR SELECT * FROM 
&quot;t_order&quot; WHERE &quot;order_id&quot; > 8" db-types="Oracle" 
sql-case-types="LITERAL" />
+    <test-cases sql-case-id="explain_for_select_with_analyze" 
expected-sql="EXPLAIN PLAN INCLUDING ALL ATTRIBUTES WITH TYPE FOR SELECT * FROM 
&quot;t_order&quot; WHERE &quot;order_id&quot; > ?" db-types="Oracle" 
sql-case-types="PLACEHOLDER" />
+    <test-cases sql-case-id="explain_for_delete_without_sharding_value" 
expected-sql="EXPLAIN PLAN INCLUDING ALL ATTRIBUTES WITH TYPE FOR DELETE FROM 
&quot;t_order&quot; WHERE &quot;status&quot; = 'init'" db-types="Oracle" 
sql-case-types="LITERAL" />
+    <test-cases sql-case-id="explain_for_delete_without_sharding_value" 
expected-sql="EXPLAIN PLAN INCLUDING ALL ATTRIBUTES WITH TYPE FOR DELETE FROM 
&quot;t_order&quot; WHERE &quot;status&quot; = ?" db-types="Oracle" 
sql-case-types="PLACEHOLDER" />
+</sql-node-converter-test-cases>

Reply via email to