You are viewing a plain text version of this content. The canonical link for it is here.
Posted to notifications@shardingsphere.apache.org by ji...@apache.org on 2021/11/25 02:36:47 UTC

[shardingsphere] branch master updated: [DistSQL] Support `parse sql` statement. (#13773)

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

jianglongtao 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 654c876  [DistSQL] Support `parse sql` statement. (#13773)
654c876 is described below

commit 654c876aff05c8d51261e9ffb8d46f884fb685c7
Author: lanchengx <52...@users.noreply.github.com>
AuthorDate: Wed Nov 24 20:36:07 2021 -0600

    [DistSQL] Support `parse sql` statement. (#13773)
    
    * Support `Parse SQL` statement.
    
    * Support `Parse SQL` statement.
    
    * Comment order adjustment.
---
 .../src/main/antlr4/imports/AdvancedKeyword.g4     |  4 +
 .../src/main/antlr4/imports/AdvancedStatement.g4   |  4 +
 .../parser/autogen/AdvancedDistSQLStatement.g4     |  4 +-
 .../advanced/AdvancedDistSQLStatementVisitor.java  |  7 ++
 .../ral/advanced/parse/ParseStatement.java}        | 26 +++----
 .../text/distsql/DistSQLBackendHandlerFactory.java |  2 +-
 .../text/distsql/ral/RALBackendHandlerFactory.java |  6 +-
 .../AdvancedDistSQLBackendHandlerFactory.java      |  9 ++-
 .../ral/advanced/ParseDistSQLBackendHandler.java   | 90 ++++++++++++++++++++++
 .../distsql/DistSQLBackendHandlerFactoryTest.java  |  6 +-
 .../advance/ParseDistSQLBackendHandlerTest.java    | 57 ++++++++++++++
 .../ral/impl/AdvancedDistSQLStatementAssert.java   |  5 ++
 .../ParseStatementAssert.java}                     | 38 ++++-----
 .../jaxb/cases/domain/SQLParserTestCases.java      |  5 ++
 .../distsql/ral/ParseStatementTestCase.java        | 27 ++++---
 .../src/main/resources/case/ral/parse.xml          | 21 +++++
 .../src/main/resources/sql/supported/ral/parse.xml | 21 +++++
 17 files changed, 280 insertions(+), 52 deletions(-)

diff --git a/shardingsphere-distsql/shardingsphere-distsql-parser/src/main/antlr4/imports/AdvancedKeyword.g4 b/shardingsphere-distsql/shardingsphere-distsql-parser/src/main/antlr4/imports/AdvancedKeyword.g4
index 4211c46..3feea3c 100644
--- a/shardingsphere-distsql/shardingsphere-distsql-parser/src/main/antlr4/imports/AdvancedKeyword.g4
+++ b/shardingsphere-distsql/shardingsphere-distsql-parser/src/main/antlr4/imports/AdvancedKeyword.g4
@@ -27,6 +27,10 @@ PREVIEW
     : P R E V I E W
     ;
 
+PARSE
+    : P A R S E
+    ;
+
 SQLString
     : WS.*
     ;
diff --git a/shardingsphere-distsql/shardingsphere-distsql-parser/src/main/antlr4/imports/AdvancedStatement.g4 b/shardingsphere-distsql/shardingsphere-distsql-parser/src/main/antlr4/imports/AdvancedStatement.g4
index bd2ad2c..bc69ac6 100644
--- a/shardingsphere-distsql/shardingsphere-distsql-parser/src/main/antlr4/imports/AdvancedStatement.g4
+++ b/shardingsphere-distsql/shardingsphere-distsql-parser/src/main/antlr4/imports/AdvancedStatement.g4
@@ -23,6 +23,10 @@ previewSQL
     : PREVIEW sql
     ;
 
+parseSQL
+    : PARSE sql
+    ;
+
 sql
     : SQLString
     ;
diff --git a/shardingsphere-distsql/shardingsphere-distsql-parser/src/main/antlr4/org/apache/shardingsphere/distsql/parser/autogen/AdvancedDistSQLStatement.g4 b/shardingsphere-distsql/shardingsphere-distsql-parser/src/main/antlr4/org/apache/shardingsphere/distsql/parser/autogen/AdvancedDistSQLStatement.g4
index 62ce8dd..01803ae 100644
--- a/shardingsphere-distsql/shardingsphere-distsql-parser/src/main/antlr4/org/apache/shardingsphere/distsql/parser/autogen/AdvancedDistSQLStatement.g4
+++ b/shardingsphere-distsql/shardingsphere-distsql-parser/src/main/antlr4/org/apache/shardingsphere/distsql/parser/autogen/AdvancedDistSQLStatement.g4
@@ -20,5 +20,7 @@ grammar AdvancedDistSQLStatement;
 import Symbol, AdvancedStatement;
 
 execute
-    : previewSQL SEMI?
+    : (previewSQL 
+    | parseSQL
+    ) SEMI?
     ;
diff --git a/shardingsphere-distsql/shardingsphere-distsql-parser/src/main/java/org/apache/shardingsphere/distsql/parser/core/advanced/AdvancedDistSQLStatementVisitor.java b/shardingsphere-distsql/shardingsphere-distsql-parser/src/main/java/org/apache/shardingsphere/distsql/parser/core/advanced/AdvancedDistSQLStatementVisitor.java
index f8a2343..7a73233 100644
--- a/shardingsphere-distsql/shardingsphere-distsql-parser/src/main/java/org/apache/shardingsphere/distsql/parser/core/advanced/AdvancedDistSQLStatementVisitor.java
+++ b/shardingsphere-distsql/shardingsphere-distsql-parser/src/main/java/org/apache/shardingsphere/distsql/parser/core/advanced/AdvancedDistSQLStatementVisitor.java
@@ -18,7 +18,9 @@
 package org.apache.shardingsphere.distsql.parser.core.advanced;
 
 import org.apache.shardingsphere.distsql.parser.autogen.AdvancedDistSQLStatementBaseVisitor;
+import org.apache.shardingsphere.distsql.parser.autogen.AdvancedDistSQLStatementParser.ParseSQLContext;
 import org.apache.shardingsphere.distsql.parser.autogen.AdvancedDistSQLStatementParser.PreviewSQLContext;
+import org.apache.shardingsphere.distsql.parser.statement.ral.advanced.parse.ParseStatement;
 import org.apache.shardingsphere.distsql.parser.statement.ral.advanced.preview.PreviewStatement;
 import org.apache.shardingsphere.sql.parser.api.visitor.ASTNode;
 import org.apache.shardingsphere.sql.parser.api.visitor.SQLVisitor;
@@ -32,4 +34,9 @@ public final class AdvancedDistSQLStatementVisitor extends AdvancedDistSQLStatem
     public ASTNode visitPreviewSQL(final PreviewSQLContext ctx) {
         return new PreviewStatement(ctx.sql().getText().trim());
     }
+    
+    @Override
+    public ASTNode visitParseSQL(final ParseSQLContext ctx) {
+        return new ParseStatement(ctx.sql().getText().trim());
+    }
 }
diff --git a/shardingsphere-distsql/shardingsphere-distsql-parser/src/main/antlr4/imports/AdvancedKeyword.g4 b/shardingsphere-distsql/shardingsphere-distsql-statement/src/main/java/org/apache/shardingsphere/distsql/parser/statement/ral/advanced/parse/ParseStatement.java
similarity index 67%
copy from shardingsphere-distsql/shardingsphere-distsql-parser/src/main/antlr4/imports/AdvancedKeyword.g4
copy to shardingsphere-distsql/shardingsphere-distsql-statement/src/main/java/org/apache/shardingsphere/distsql/parser/statement/ral/advanced/parse/ParseStatement.java
index 4211c46..49b3784 100644
--- a/shardingsphere-distsql/shardingsphere-distsql-parser/src/main/antlr4/imports/AdvancedKeyword.g4
+++ b/shardingsphere-distsql/shardingsphere-distsql-statement/src/main/java/org/apache/shardingsphere/distsql/parser/statement/ral/advanced/parse/ParseStatement.java
@@ -15,18 +15,18 @@
  * limitations under the License.
  */
 
-lexer grammar AdvancedKeyword;
+package org.apache.shardingsphere.distsql.parser.statement.ral.advanced.parse;
 
-import Alphabet;
+import lombok.Getter;
+import lombok.RequiredArgsConstructor;
+import org.apache.shardingsphere.distsql.parser.statement.ral.AdvancedDistSQLStatement;
 
-WS
-    : [ \t\r\n] +
-    ;
-
-PREVIEW
-    : P R E V I E W
-    ;
-
-SQLString
-    : WS.*
-    ;
+/**
+ * Parse statement.
+ */
+@RequiredArgsConstructor
+@Getter
+public final class ParseStatement extends AdvancedDistSQLStatement {
+    
+    private final String sql;
+}
diff --git a/shardingsphere-proxy/shardingsphere-proxy-backend/src/main/java/org/apache/shardingsphere/proxy/backend/text/distsql/DistSQLBackendHandlerFactory.java b/shardingsphere-proxy/shardingsphere-proxy-backend/src/main/java/org/apache/shardingsphere/proxy/backend/text/distsql/DistSQLBackendHandlerFactory.java
index 69a4700..228ed83 100644
--- a/shardingsphere-proxy/shardingsphere-proxy-backend/src/main/java/org/apache/shardingsphere/proxy/backend/text/distsql/DistSQLBackendHandlerFactory.java
+++ b/shardingsphere-proxy/shardingsphere-proxy-backend/src/main/java/org/apache/shardingsphere/proxy/backend/text/distsql/DistSQLBackendHandlerFactory.java
@@ -56,7 +56,7 @@ public final class DistSQLBackendHandlerFactory {
             return RDLBackendHandlerFactory.newInstance(databaseType, (RDLStatement) sqlStatement, backendConnection);
         }
         if (sqlStatement instanceof RALStatement) {
-            return RALBackendHandlerFactory.newInstance((RALStatement) sqlStatement, backendConnection);
+            return RALBackendHandlerFactory.newInstance(databaseType, (RALStatement) sqlStatement, backendConnection);
         }
         throw new UnsupportedTypeException(sqlStatement.getClass().getCanonicalName());
     }
diff --git a/shardingsphere-proxy/shardingsphere-proxy-backend/src/main/java/org/apache/shardingsphere/proxy/backend/text/distsql/ral/RALBackendHandlerFactory.java b/shardingsphere-proxy/shardingsphere-proxy-backend/src/main/java/org/apache/shardingsphere/proxy/backend/text/distsql/ral/RALBackendHandlerFactory.java
index cf98704..88e9f4f 100644
--- a/shardingsphere-proxy/shardingsphere-proxy-backend/src/main/java/org/apache/shardingsphere/proxy/backend/text/distsql/ral/RALBackendHandlerFactory.java
+++ b/shardingsphere-proxy/shardingsphere-proxy-backend/src/main/java/org/apache/shardingsphere/proxy/backend/text/distsql/ral/RALBackendHandlerFactory.java
@@ -24,6 +24,7 @@ import org.apache.shardingsphere.distsql.parser.statement.ral.CommonDistSQLState
 import org.apache.shardingsphere.distsql.parser.statement.ral.QueryableRALStatement;
 import org.apache.shardingsphere.distsql.parser.statement.ral.RALStatement;
 import org.apache.shardingsphere.distsql.parser.statement.ral.UpdatableRALStatement;
+import org.apache.shardingsphere.infra.database.type.DatabaseType;
 import org.apache.shardingsphere.proxy.backend.communication.jdbc.connection.BackendConnection;
 import org.apache.shardingsphere.proxy.backend.text.TextProtocolBackendHandler;
 import org.apache.shardingsphere.proxy.backend.text.distsql.ral.advanced.AdvancedDistSQLBackendHandlerFactory;
@@ -42,12 +43,13 @@ public final class RALBackendHandlerFactory {
     /**
      * Create new instance of RAL backend handler.
      *
+     * @param databaseType database type
      * @param sqlStatement RAL statement
      * @param backendConnection backend connection
      * @return RAL backend handler
      * @throws SQLException SQL exception
      */
-    public static TextProtocolBackendHandler newInstance(final RALStatement sqlStatement, final BackendConnection backendConnection) throws SQLException {
+    public static TextProtocolBackendHandler newInstance(final DatabaseType databaseType, final RALStatement sqlStatement, final BackendConnection backendConnection) throws SQLException {
         if (sqlStatement instanceof QueryableRALStatement) {
             return QueryableRALBackendHandlerFactory.newInstance((QueryableRALStatement) sqlStatement, backendConnection);
         }
@@ -58,7 +60,7 @@ public final class RALBackendHandlerFactory {
             return CommonDistSQLBackendHandlerFactory.newInstance((CommonDistSQLStatement) sqlStatement, backendConnection);
         }
         if (sqlStatement instanceof AdvancedDistSQLStatement) {
-            return AdvancedDistSQLBackendHandlerFactory.newInstance((AdvancedDistSQLStatement) sqlStatement, backendConnection);
+            return AdvancedDistSQLBackendHandlerFactory.newInstance(databaseType, (AdvancedDistSQLStatement) sqlStatement, backendConnection);
         }
         throw new UnsupportedOperationException(sqlStatement.getClass().getCanonicalName());
     }
diff --git a/shardingsphere-proxy/shardingsphere-proxy-backend/src/main/java/org/apache/shardingsphere/proxy/backend/text/distsql/ral/advanced/AdvancedDistSQLBackendHandlerFactory.java b/shardingsphere-proxy/shardingsphere-proxy-backend/src/main/java/org/apache/shardingsphere/proxy/backend/text/distsql/ral/advanced/AdvancedDistSQLBackendHandlerFactory.java
index 29da6b7..5b0370b 100644
--- a/shardingsphere-proxy/shardingsphere-proxy-backend/src/main/java/org/apache/shardingsphere/proxy/backend/text/distsql/ral/advanced/AdvancedDistSQLBackendHandlerFactory.java
+++ b/shardingsphere-proxy/shardingsphere-proxy-backend/src/main/java/org/apache/shardingsphere/proxy/backend/text/distsql/ral/advanced/AdvancedDistSQLBackendHandlerFactory.java
@@ -21,7 +21,9 @@ import com.mchange.v1.db.sql.UnsupportedTypeException;
 import lombok.AccessLevel;
 import lombok.NoArgsConstructor;
 import org.apache.shardingsphere.distsql.parser.statement.ral.AdvancedDistSQLStatement;
+import org.apache.shardingsphere.distsql.parser.statement.ral.advanced.parse.ParseStatement;
 import org.apache.shardingsphere.distsql.parser.statement.ral.advanced.preview.PreviewStatement;
+import org.apache.shardingsphere.infra.database.type.DatabaseType;
 import org.apache.shardingsphere.proxy.backend.communication.jdbc.connection.BackendConnection;
 import org.apache.shardingsphere.proxy.backend.text.TextProtocolBackendHandler;
 
@@ -35,15 +37,18 @@ public final class AdvancedDistSQLBackendHandlerFactory {
     
     /**
      * Create new instance of advanced dist sql backend handler.
-     * 
+     *
+     * @param databaseType database type
      * @param sqlStatement advanced dist sql statement
      * @param backendConnection backend connection
      * @return advanced dist sql backend handler
      * @throws SQLException SQL exception
      */
-    public static TextProtocolBackendHandler newInstance(final AdvancedDistSQLStatement sqlStatement, final BackendConnection backendConnection) throws SQLException {
+    public static TextProtocolBackendHandler newInstance(final DatabaseType databaseType, final AdvancedDistSQLStatement sqlStatement, final BackendConnection backendConnection) throws SQLException {
         if (sqlStatement instanceof PreviewStatement) {
             return new PreviewDistSQLBackendHandler((PreviewStatement) sqlStatement, backendConnection);
+        } else if (sqlStatement instanceof ParseStatement) {
+            return new ParseDistSQLBackendHandler(databaseType, (ParseStatement) sqlStatement, backendConnection);
         }
         throw new UnsupportedTypeException(sqlStatement.getClass().getCanonicalName());
     }
diff --git a/shardingsphere-proxy/shardingsphere-proxy-backend/src/main/java/org/apache/shardingsphere/proxy/backend/text/distsql/ral/advanced/ParseDistSQLBackendHandler.java b/shardingsphere-proxy/shardingsphere-proxy-backend/src/main/java/org/apache/shardingsphere/proxy/backend/text/distsql/ral/advanced/ParseDistSQLBackendHandler.java
new file mode 100644
index 0000000..e5aca85
--- /dev/null
+++ b/shardingsphere-proxy/shardingsphere-proxy-backend/src/main/java/org/apache/shardingsphere/proxy/backend/text/distsql/ral/advanced/ParseDistSQLBackendHandler.java
@@ -0,0 +1,90 @@
+/*
+ * 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.
+ */
+
+package org.apache.shardingsphere.proxy.backend.text.distsql.ral.advanced;
+
+import com.google.common.base.Strings;
+import com.google.gson.Gson;
+import lombok.Getter;
+import lombok.RequiredArgsConstructor;
+import org.apache.shardingsphere.distsql.parser.statement.ral.advanced.parse.ParseStatement;
+import org.apache.shardingsphere.infra.config.properties.ConfigurationProperties;
+import org.apache.shardingsphere.infra.database.type.DatabaseType;
+import org.apache.shardingsphere.infra.parser.ShardingSphereSQLParserEngine;
+import org.apache.shardingsphere.proxy.backend.communication.jdbc.connection.BackendConnection;
+import org.apache.shardingsphere.proxy.backend.context.ProxyContext;
+import org.apache.shardingsphere.proxy.backend.response.header.ResponseHeader;
+import org.apache.shardingsphere.proxy.backend.response.header.query.QueryResponseHeader;
+import org.apache.shardingsphere.proxy.backend.response.header.query.impl.QueryHeader;
+import org.apache.shardingsphere.proxy.backend.text.TextProtocolBackendHandler;
+import org.apache.shardingsphere.sql.parser.exception.SQLParsingException;
+import org.apache.shardingsphere.sql.parser.sql.common.statement.SQLStatement;
+
+import java.sql.Types;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.Iterator;
+import java.util.List;
+
+/**
+ * Parse dist sql backend handler.
+ */
+@RequiredArgsConstructor
+@Getter
+public final class ParseDistSQLBackendHandler implements TextProtocolBackendHandler {
+    
+    private final DatabaseType databaseType;
+    
+    private final ParseStatement previewStatement;
+    
+    private final BackendConnection backendConnection;
+    
+    private final List<QueryHeader> queryHeaders = new ArrayList<>(1);
+    
+    private Iterator<String> data = Collections.emptyIterator();
+    
+    @Override
+    public ResponseHeader execute() {
+        ConfigurationProperties props = ProxyContext.getInstance().getContextManager().getMetaDataContexts().getProps();
+        SQLStatement sqlStatement;
+        try {
+            sqlStatement = new ShardingSphereSQLParserEngine(getBackendDatabaseType(databaseType, backendConnection).getName(), props).parse(previewStatement.getSql(), false);
+        } catch (SQLParsingException ex) {
+            throw new SQLParsingException("You have an error in your SQL syntax that you are parsed");
+        }
+        data = Collections.singleton(new Gson().toJson(sqlStatement)).iterator();
+        queryHeaders.add(new QueryHeader("", "", sqlStatement.getClass().getSimpleName(), "", Types.CHAR, "CHAR", 255, 0, false, false, false, false));
+        return new QueryResponseHeader(queryHeaders);
+    }
+    
+    private static DatabaseType getBackendDatabaseType(final DatabaseType defaultDatabaseType, final BackendConnection backendConnection) {
+        String schemaName = backendConnection.getSchemaName();
+        return Strings.isNullOrEmpty(schemaName) || !ProxyContext.getInstance().schemaExists(schemaName)
+                ? defaultDatabaseType : ProxyContext.getInstance().getContextManager().getMetaDataContexts().getMetaData(schemaName).getResource().getDatabaseType();
+    }
+    
+    @Override
+    public boolean next() {
+        return data.hasNext();
+    }
+    
+    @Override
+    public Collection<Object> getRowData() {
+        return Collections.singleton(data.next());
+    }
+}
diff --git a/shardingsphere-proxy/shardingsphere-proxy-backend/src/test/java/org/apache/shardingsphere/proxy/backend/text/distsql/DistSQLBackendHandlerFactoryTest.java b/shardingsphere-proxy/shardingsphere-proxy-backend/src/test/java/org/apache/shardingsphere/proxy/backend/text/distsql/DistSQLBackendHandlerFactoryTest.java
index 7a6f1cc..46c79ad 100644
--- a/shardingsphere-proxy/shardingsphere-proxy-backend/src/test/java/org/apache/shardingsphere/proxy/backend/text/distsql/DistSQLBackendHandlerFactoryTest.java
+++ b/shardingsphere-proxy/shardingsphere-proxy-backend/src/test/java/org/apache/shardingsphere/proxy/backend/text/distsql/DistSQLBackendHandlerFactoryTest.java
@@ -263,7 +263,7 @@ public final class DistSQLBackendHandlerFactoryTest {
         BackendConnection connection = mock(BackendConnection.class);
         when(connection.getSchemaName()).thenReturn("schema");
         mockScalingContext();
-        ResponseHeader response = RALBackendHandlerFactory.newInstance(mock(ShowScalingCheckAlgorithmsStatement.class), connection).execute();
+        ResponseHeader response = RALBackendHandlerFactory.newInstance(new MySQLDatabaseType(), mock(ShowScalingCheckAlgorithmsStatement.class), connection).execute();
         assertThat(response, instanceOf(QueryResponseHeader.class));
     }
     
@@ -272,7 +272,7 @@ public final class DistSQLBackendHandlerFactoryTest {
         BackendConnection connection = mock(BackendConnection.class);
         when(connection.getSchemaName()).thenReturn("schema");
         mockScalingContext();
-        ResponseHeader response = RALBackendHandlerFactory.newInstance(mock(StopScalingSourceWritingStatement.class), connection).execute();
+        ResponseHeader response = RALBackendHandlerFactory.newInstance(new MySQLDatabaseType(), mock(StopScalingSourceWritingStatement.class), connection).execute();
         assertThat(response, instanceOf(UpdateResponseHeader.class));
     }
     
@@ -282,7 +282,7 @@ public final class DistSQLBackendHandlerFactoryTest {
         BackendConnection connection = mock(BackendConnection.class);
         when(connection.getSchemaName()).thenReturn("schema");
         mockScalingContext();
-        ResponseHeader response = RALBackendHandlerFactory.newInstance(mock(CheckoutScalingStatement.class), connection).execute();
+        ResponseHeader response = RALBackendHandlerFactory.newInstance(new MySQLDatabaseType(), mock(CheckoutScalingStatement.class), connection).execute();
         assertThat(response, instanceOf(UpdateResponseHeader.class));
     }
     
diff --git a/shardingsphere-proxy/shardingsphere-proxy-backend/src/test/java/org/apache/shardingsphere/proxy/backend/text/distsql/ral/advance/ParseDistSQLBackendHandlerTest.java b/shardingsphere-proxy/shardingsphere-proxy-backend/src/test/java/org/apache/shardingsphere/proxy/backend/text/distsql/ral/advance/ParseDistSQLBackendHandlerTest.java
new file mode 100644
index 0000000..a1eee58
--- /dev/null
+++ b/shardingsphere-proxy/shardingsphere-proxy-backend/src/test/java/org/apache/shardingsphere/proxy/backend/text/distsql/ral/advance/ParseDistSQLBackendHandlerTest.java
@@ -0,0 +1,57 @@
+/*
+ * 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.
+ */
+
+package org.apache.shardingsphere.proxy.backend.text.distsql.ral.advance;
+
+import com.google.gson.Gson;
+import org.apache.shardingsphere.distsql.parser.statement.ral.advanced.parse.ParseStatement;
+import org.apache.shardingsphere.infra.config.properties.ConfigurationProperties;
+import org.apache.shardingsphere.infra.database.type.dialect.MySQLDatabaseType;
+import org.apache.shardingsphere.infra.parser.ShardingSphereSQLParserEngine;
+import org.apache.shardingsphere.proxy.backend.communication.jdbc.connection.BackendConnection;
+import org.apache.shardingsphere.proxy.backend.text.distsql.ral.advanced.ParseDistSQLBackendHandler;
+import org.apache.shardingsphere.sql.parser.exception.SQLParsingException;
+import org.apache.shardingsphere.sql.parser.sql.common.statement.SQLStatement;
+import org.junit.Test;
+
+import java.util.LinkedList;
+import java.util.Properties;
+
+import static org.hamcrest.CoreMatchers.is;
+import static org.junit.Assert.assertThat;
+import static org.mockito.Mockito.mock;
+
+public final class ParseDistSQLBackendHandlerTest {
+    
+    @Test
+    public void assertGetRowData() {
+        String sql = "select * from t_order";
+        ParseStatement parseStatement = new ParseStatement(sql);
+        ParseDistSQLBackendHandler parseDistSQLBackendHandler = new ParseDistSQLBackendHandler(new MySQLDatabaseType(), parseStatement, mock(BackendConnection.class));
+        parseDistSQLBackendHandler.execute();
+        SQLStatement statement = new ShardingSphereSQLParserEngine("MySQL", new ConfigurationProperties(new Properties())).parse(sql, false);
+        assertThat(new LinkedList<>(parseDistSQLBackendHandler.getRowData()).getFirst(), is(new Gson().toJson(statement)));
+    }
+    
+    @Test(expected = SQLParsingException.class)
+    public void assertExecute() {
+        String sql = "wrong sql";
+        ParseStatement parseStatement = new ParseStatement(sql);
+        ParseDistSQLBackendHandler parseDistSQLBackendHandler = new ParseDistSQLBackendHandler(new MySQLDatabaseType(), parseStatement, mock(BackendConnection.class));
+        parseDistSQLBackendHandler.execute();
+    }
+}
diff --git a/shardingsphere-test/shardingsphere-parser-test/src/main/java/org/apache/shardingsphere/test/sql/parser/parameterized/asserts/statement/distsql/ral/impl/AdvancedDistSQLStatementAssert.java b/shardingsphere-test/shardingsphere-parser-test/src/main/java/org/apache/shardingsphere/test/sql/parser/parameterized/asserts/statement/distsql/ral/impl/AdvancedDistSQLStatementAssert.java
index 65cd6f0..4171467 100644
--- a/shardingsphere-test/shardingsphere-parser-test/src/main/java/org/apache/shardingsphere/test/sql/parser/parameterized/asserts/statement/distsql/ral/impl/AdvancedDistSQLStatementAssert.java
+++ b/shardingsphere-test/shardingsphere-parser-test/src/main/java/org/apache/shardingsphere/test/sql/parser/parameterized/asserts/statement/distsql/ral/impl/AdvancedDistSQLStatementAssert.java
@@ -20,10 +20,13 @@ package org.apache.shardingsphere.test.sql.parser.parameterized.asserts.statemen
 import lombok.AccessLevel;
 import lombok.NoArgsConstructor;
 import org.apache.shardingsphere.distsql.parser.statement.ral.AdvancedDistSQLStatement;
+import org.apache.shardingsphere.distsql.parser.statement.ral.advanced.parse.ParseStatement;
 import org.apache.shardingsphere.distsql.parser.statement.ral.advanced.preview.PreviewStatement;
 import org.apache.shardingsphere.test.sql.parser.parameterized.asserts.SQLCaseAssertContext;
+import org.apache.shardingsphere.test.sql.parser.parameterized.asserts.statement.distsql.ral.impl.advanced.ParseStatementAssert;
 import org.apache.shardingsphere.test.sql.parser.parameterized.asserts.statement.distsql.ral.impl.advanced.PreviewStatementAssert;
 import org.apache.shardingsphere.test.sql.parser.parameterized.jaxb.cases.domain.statement.SQLParserTestCase;
+import org.apache.shardingsphere.test.sql.parser.parameterized.jaxb.cases.domain.statement.distsql.ral.ParseStatementTestCase;
 import org.apache.shardingsphere.test.sql.parser.parameterized.jaxb.cases.domain.statement.distsql.ral.PreviewStatementTestCase;
 
 /**
@@ -42,6 +45,8 @@ public final class AdvancedDistSQLStatementAssert {
     public static void assertIs(final SQLCaseAssertContext assertContext, final AdvancedDistSQLStatement actual, final SQLParserTestCase expected) {
         if (actual instanceof PreviewStatement) {
             PreviewStatementAssert.assertIs(assertContext, (PreviewStatement) actual, (PreviewStatementTestCase) expected);
+        } else if (actual instanceof ParseStatement) {
+            ParseStatementAssert.assertIs(assertContext, (ParseStatement) actual, (ParseStatementTestCase) expected);
         }
     }
 }
diff --git a/shardingsphere-test/shardingsphere-parser-test/src/main/java/org/apache/shardingsphere/test/sql/parser/parameterized/asserts/statement/distsql/ral/impl/AdvancedDistSQLStatementAssert.java b/shardingsphere-test/shardingsphere-parser-test/src/main/java/org/apache/shardingsphere/test/sql/parser/parameterized/asserts/statement/distsql/ral/impl/advanced/ParseStatementAssert.java
similarity index 52%
copy from shardingsphere-test/shardingsphere-parser-test/src/main/java/org/apache/shardingsphere/test/sql/parser/parameterized/asserts/statement/distsql/ral/impl/AdvancedDistSQLStatementAssert.java
copy to shardingsphere-test/shardingsphere-parser-test/src/main/java/org/apache/shardingsphere/test/sql/parser/parameterized/asserts/statement/distsql/ral/impl/advanced/ParseStatementAssert.java
index 65cd6f0..e1730ee 100644
--- a/shardingsphere-test/shardingsphere-parser-test/src/main/java/org/apache/shardingsphere/test/sql/parser/parameterized/asserts/statement/distsql/ral/impl/AdvancedDistSQLStatementAssert.java
+++ b/shardingsphere-test/shardingsphere-parser-test/src/main/java/org/apache/shardingsphere/test/sql/parser/parameterized/asserts/statement/distsql/ral/impl/advanced/ParseStatementAssert.java
@@ -15,33 +15,35 @@
  * limitations under the License.
  */
 
-package org.apache.shardingsphere.test.sql.parser.parameterized.asserts.statement.distsql.ral.impl;
+package org.apache.shardingsphere.test.sql.parser.parameterized.asserts.statement.distsql.ral.impl.advanced;
 
-import lombok.AccessLevel;
-import lombok.NoArgsConstructor;
-import org.apache.shardingsphere.distsql.parser.statement.ral.AdvancedDistSQLStatement;
-import org.apache.shardingsphere.distsql.parser.statement.ral.advanced.preview.PreviewStatement;
+import org.apache.shardingsphere.distsql.parser.statement.ral.advanced.parse.ParseStatement;
 import org.apache.shardingsphere.test.sql.parser.parameterized.asserts.SQLCaseAssertContext;
-import org.apache.shardingsphere.test.sql.parser.parameterized.asserts.statement.distsql.ral.impl.advanced.PreviewStatementAssert;
-import org.apache.shardingsphere.test.sql.parser.parameterized.jaxb.cases.domain.statement.SQLParserTestCase;
-import org.apache.shardingsphere.test.sql.parser.parameterized.jaxb.cases.domain.statement.distsql.ral.PreviewStatementTestCase;
+import org.apache.shardingsphere.test.sql.parser.parameterized.jaxb.cases.domain.statement.distsql.ral.ParseStatementTestCase;
+
+import static org.hamcrest.CoreMatchers.is;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertNull;
+import static org.junit.Assert.assertThat;
 
 /**
- * Advanced dist SQL statement assert.
+ * Parse statement assert.
  */
-@NoArgsConstructor(access = AccessLevel.PRIVATE)
-public final class AdvancedDistSQLStatementAssert {
-
+public final class ParseStatementAssert {
+    
     /**
-     * Assert updatable RAL statement is correct with expected parser result.
+     * Assert parse statement is correct with expected parser result.
      *
      * @param assertContext assert context
-     * @param actual actual advanced dist SQL statement
-     * @param expected expected advanced dist SQL statement test case
+     * @param actual actual parse statement
+     * @param expected expected parse statement test case
      */
-    public static void assertIs(final SQLCaseAssertContext assertContext, final AdvancedDistSQLStatement actual, final SQLParserTestCase expected) {
-        if (actual instanceof PreviewStatement) {
-            PreviewStatementAssert.assertIs(assertContext, (PreviewStatement) actual, (PreviewStatementTestCase) expected);
+    public static void assertIs(final SQLCaseAssertContext assertContext, final ParseStatement actual, final ParseStatementTestCase expected) {
+        if (null == expected) {
+            assertNull(assertContext.getText("Actual statement should not exist."), actual);
+        } else {
+            assertNotNull(assertContext.getText("Actual statement should exist."), actual);
+            assertThat(assertContext.getText("SQL assertion error"), actual.getSql(), is(expected.getSql()));
         }
     }
 }
diff --git a/shardingsphere-test/shardingsphere-parser-test/src/main/java/org/apache/shardingsphere/test/sql/parser/parameterized/jaxb/cases/domain/SQLParserTestCases.java b/shardingsphere-test/shardingsphere-parser-test/src/main/java/org/apache/shardingsphere/test/sql/parser/parameterized/jaxb/cases/domain/SQLParserTestCases.java
index fba2ee3..ec11601 100644
--- a/shardingsphere-test/shardingsphere-parser-test/src/main/java/org/apache/shardingsphere/test/sql/parser/parameterized/jaxb/cases/domain/SQLParserTestCases.java
+++ b/shardingsphere-test/shardingsphere-parser-test/src/main/java/org/apache/shardingsphere/test/sql/parser/parameterized/jaxb/cases/domain/SQLParserTestCases.java
@@ -128,6 +128,7 @@ import org.apache.shardingsphere.test.sql.parser.parameterized.jaxb.cases.domain
 import org.apache.shardingsphere.test.sql.parser.parameterized.jaxb.cases.domain.statement.distsql.ral.ClearHintStatementTestCase;
 import org.apache.shardingsphere.test.sql.parser.parameterized.jaxb.cases.domain.statement.distsql.ral.ClearReadwriteSplittingHintStatementTestCase;
 import org.apache.shardingsphere.test.sql.parser.parameterized.jaxb.cases.domain.statement.distsql.ral.ClearShardingHintStatementTestCase;
+import org.apache.shardingsphere.test.sql.parser.parameterized.jaxb.cases.domain.statement.distsql.ral.ParseStatementTestCase;
 import org.apache.shardingsphere.test.sql.parser.parameterized.jaxb.cases.domain.statement.distsql.ral.PreviewStatementTestCase;
 import org.apache.shardingsphere.test.sql.parser.parameterized.jaxb.cases.domain.statement.distsql.ral.SetReadwriteSplittingHintStatementTestCase;
 import org.apache.shardingsphere.test.sql.parser.parameterized.jaxb.cases.domain.statement.distsql.ral.SetShardingHintDatabaseValueStatementTestCase;
@@ -603,6 +604,9 @@ public final class SQLParserTestCases {
     @XmlElement(name = "preview-sql")
     private final List<PreviewStatementTestCase> previewStatementTestCase = new LinkedList<>();
     
+    @XmlElement(name = "parse-sql")
+    private final List<ParseStatementTestCase> parseStatementAsserts = new LinkedList<>();
+    
     @XmlElement(name = "show-variable")
     private final List<ShowVariableStatementTestCase> showVariableStatementTestCase = new LinkedList<>();
     
@@ -914,6 +918,7 @@ public final class SQLParserTestCases {
         putAll(showAllVariablesStatementTestCase, result);
         putAll(setVariableStatementTestCase, result);
         putAll(previewStatementTestCase, result);
+        putAll(parseStatementAsserts, result);
         putAll(setReadwriteSplittingHintStatementTestCase, result);
         putAll(setShardingHintDatabaseValueStatementTestCase, result);
         putAll(addShardingHintDatabaseValueStatementTestCase, result);
diff --git a/shardingsphere-distsql/shardingsphere-distsql-parser/src/main/antlr4/imports/AdvancedKeyword.g4 b/shardingsphere-test/shardingsphere-parser-test/src/main/java/org/apache/shardingsphere/test/sql/parser/parameterized/jaxb/cases/domain/statement/distsql/ral/ParseStatementTestCase.java
similarity index 62%
copy from shardingsphere-distsql/shardingsphere-distsql-parser/src/main/antlr4/imports/AdvancedKeyword.g4
copy to shardingsphere-test/shardingsphere-parser-test/src/main/java/org/apache/shardingsphere/test/sql/parser/parameterized/jaxb/cases/domain/statement/distsql/ral/ParseStatementTestCase.java
index 4211c46..50537fe 100644
--- a/shardingsphere-distsql/shardingsphere-distsql-parser/src/main/antlr4/imports/AdvancedKeyword.g4
+++ b/shardingsphere-test/shardingsphere-parser-test/src/main/java/org/apache/shardingsphere/test/sql/parser/parameterized/jaxb/cases/domain/statement/distsql/ral/ParseStatementTestCase.java
@@ -15,18 +15,21 @@
  * limitations under the License.
  */
 
-lexer grammar AdvancedKeyword;
+package org.apache.shardingsphere.test.sql.parser.parameterized.jaxb.cases.domain.statement.distsql.ral;
 
-import Alphabet;
+import lombok.Getter;
+import lombok.Setter;
+import org.apache.shardingsphere.test.sql.parser.parameterized.jaxb.cases.domain.statement.SQLParserTestCase;
 
-WS
-    : [ \t\r\n] +
-    ;
+import javax.xml.bind.annotation.XmlAttribute;
 
-PREVIEW
-    : P R E V I E W
-    ;
-
-SQLString
-    : WS.*
-    ;
+/**
+ * Parse statement test case.
+ */
+@Getter
+@Setter
+public final class ParseStatementTestCase extends SQLParserTestCase {
+    
+    @XmlAttribute(name = "sql")
+    private String sql;
+}
diff --git a/shardingsphere-test/shardingsphere-parser-test/src/main/resources/case/ral/parse.xml b/shardingsphere-test/shardingsphere-parser-test/src/main/resources/case/ral/parse.xml
new file mode 100644
index 0000000..6f6f2d4
--- /dev/null
+++ b/shardingsphere-test/shardingsphere-parser-test/src/main/resources/case/ral/parse.xml
@@ -0,0 +1,21 @@
+<?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-parser-test-cases>
+    <parse-sql sql-case-id="parse-sql" sql="SELECT * FROM t_order;" />
+</sql-parser-test-cases>
diff --git a/shardingsphere-test/shardingsphere-parser-test/src/main/resources/sql/supported/ral/parse.xml b/shardingsphere-test/shardingsphere-parser-test/src/main/resources/sql/supported/ral/parse.xml
new file mode 100644
index 0000000..d01790a
--- /dev/null
+++ b/shardingsphere-test/shardingsphere-parser-test/src/main/resources/sql/supported/ral/parse.xml
@@ -0,0 +1,21 @@
+<?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-cases>
+    <distsql-case id="parse-sql" value="PARSE SELECT * FROM t_order;" />
+</sql-cases>