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 2023/05/22 11:19:01 UTC

[shardingsphere] branch master updated: Split XAStatement to concrete statements (#25850)

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 4a5576e9176 Split XAStatement to concrete statements (#25850)
4a5576e9176 is described below

commit 4a5576e9176831e11f839815aa1b057dc0eeb65d
Author: Liang Zhang <zh...@apache.org>
AuthorDate: Mon May 22 19:18:50 2023 +0800

    Split XAStatement to concrete statements (#25850)
    
    * Split XAStatement to concrete statements
    
    * Split XAStatement to concrete statements
---
 .../src/main/antlr4/imports/mysql/TCLStatement.g4  | 31 +++++++---
 .../sql/parser/autogen/MySQLStatement.g4           |  7 ++-
 .../statement/type/MySQLTCLStatementVisitor.java   | 43 ++++++++++++--
 .../visitor/statement/MySQLXAVisitorTest.java      | 66 ----------------------
 .../core/database/visitor/SQLVisitorRule.java      | 12 +++-
 .../{XAStatement.java => xa/XABeginStatement.java} |  8 +--
 .../statement/tcl/xa/XACommitStatement.java}       | 17 +++---
 .../{XAStatement.java => xa/XAEndStatement.java}   |  8 +--
 .../XAPrepareStatement.java}                       |  8 +--
 .../XARecoveryStatement.java}                      | 14 +----
 .../XARollbackStatement.java}                      |  8 +--
 .../common/statement/tcl/{ => xa}/XAStatement.java | 14 +----
 .../TransactionBackendHandlerFactory.java          |  2 +-
 .../handler/transaction/TransactionXAHandler.java  | 34 +++++------
 .../binary/prepare/MySQLComStmtPrepareChecker.java | 18 ++++--
 .../prepare/MySQLComStmtPrepareExecutor.java       |  2 +-
 .../prepare/MySQLComStmtPrepareCheckerTest.java    | 12 +++-
 17 files changed, 143 insertions(+), 161 deletions(-)

diff --git a/parser/sql/dialect/mysql/src/main/antlr4/imports/mysql/TCLStatement.g4 b/parser/sql/dialect/mysql/src/main/antlr4/imports/mysql/TCLStatement.g4
index 00bb7524553..091cda5e71d 100644
--- a/parser/sql/dialect/mysql/src/main/antlr4/imports/mysql/TCLStatement.g4
+++ b/parser/sql/dialect/mysql/src/main/antlr4/imports/mysql/TCLStatement.g4
@@ -79,17 +79,30 @@ lockOption
     : READ LOCAL? | LOW_PRIORITY? WRITE
     ;
 
-xa
-    : XA ((START | BEGIN) xid (JOIN | RESUME)?
-        | END xid (SUSPEND (FOR MIGRATE)?)?
-        | PREPARE xid
-        | COMMIT xid (ONE PHASE)?
-        | ROLLBACK xid
-        | RECOVER (CONVERT XID)?
-    )
+xaBegin
+    : XA (START | BEGIN) xid (JOIN | RESUME)?
+    ;
+
+xaPrepare
+    : XA PREPARE xid
+    ;
+
+xaCommit
+    : XA COMMIT xid (ONE PHASE)?
+    ;
+
+xaRollback
+    : XA ROLLBACK xid
+    ;
+
+xaEnd
+    : XA END xid (SUSPEND (FOR MIGRATE)?)?
+    ;
+
+xaRecovery
+    : XA RECOVER (CONVERT XID)?
     ;
 
 xid
     : gtrid=textString (COMMA_ bqual=textString (COMMA_ formatID=NUMBER_)?)?
     ;
-
diff --git a/parser/sql/dialect/mysql/src/main/antlr4/org/apache/shardingsphere/sql/parser/autogen/MySQLStatement.g4 b/parser/sql/dialect/mysql/src/main/antlr4/org/apache/shardingsphere/sql/parser/autogen/MySQLStatement.g4
index aaae498a96b..db1de9027b8 100644
--- a/parser/sql/dialect/mysql/src/main/antlr4/org/apache/shardingsphere/sql/parser/autogen/MySQLStatement.g4
+++ b/parser/sql/dialect/mysql/src/main/antlr4/org/apache/shardingsphere/sql/parser/autogen/MySQLStatement.g4
@@ -114,7 +114,12 @@ execute
     | renameTable
     | uninstall
     | unlock
-    | xa
+    | xaBegin
+    | xaPrepare
+    | xaCommit
+    | xaRollback
+    | xaEnd
+    | xaRecovery
     | createLoadableFunction
     | createTablespace
     | alterTablespace
diff --git a/parser/sql/dialect/mysql/src/main/java/org/apache/shardingsphere/sql/parser/mysql/visitor/statement/type/MySQLTCLStatementVisitor.java b/parser/sql/dialect/mysql/src/main/java/org/apache/shardingsphere/sql/parser/mysql/visitor/statement/type/MySQLTCLStatementVisitor.java
index 35cf1303a8d..7802a972a0d 100644
--- a/parser/sql/dialect/mysql/src/main/java/org/apache/shardingsphere/sql/parser/mysql/visitor/statement/type/MySQLTCLStatementVisitor.java
+++ b/parser/sql/dialect/mysql/src/main/java/org/apache/shardingsphere/sql/parser/mysql/visitor/statement/type/MySQLTCLStatementVisitor.java
@@ -30,7 +30,12 @@ import org.apache.shardingsphere.sql.parser.autogen.MySQLStatementParser.SetAuto
 import org.apache.shardingsphere.sql.parser.autogen.MySQLStatementParser.SetTransactionContext;
 import org.apache.shardingsphere.sql.parser.autogen.MySQLStatementParser.TableLockContext;
 import org.apache.shardingsphere.sql.parser.autogen.MySQLStatementParser.UnlockContext;
-import org.apache.shardingsphere.sql.parser.autogen.MySQLStatementParser.XaContext;
+import org.apache.shardingsphere.sql.parser.autogen.MySQLStatementParser.XaBeginContext;
+import org.apache.shardingsphere.sql.parser.autogen.MySQLStatementParser.XaCommitContext;
+import org.apache.shardingsphere.sql.parser.autogen.MySQLStatementParser.XaEndContext;
+import org.apache.shardingsphere.sql.parser.autogen.MySQLStatementParser.XaPrepareContext;
+import org.apache.shardingsphere.sql.parser.autogen.MySQLStatementParser.XaRecoveryContext;
+import org.apache.shardingsphere.sql.parser.autogen.MySQLStatementParser.XaRollbackContext;
 import org.apache.shardingsphere.sql.parser.mysql.visitor.statement.MySQLStatementVisitor;
 import org.apache.shardingsphere.sql.parser.sql.common.enums.OperationScope;
 import org.apache.shardingsphere.sql.parser.sql.common.enums.TransactionAccessType;
@@ -38,6 +43,12 @@ import org.apache.shardingsphere.sql.parser.sql.common.enums.TransactionIsolatio
 import org.apache.shardingsphere.sql.parser.sql.common.segment.generic.AliasSegment;
 import org.apache.shardingsphere.sql.parser.sql.common.segment.generic.table.SimpleTableSegment;
 import org.apache.shardingsphere.sql.parser.sql.common.segment.tcl.AutoCommitSegment;
+import org.apache.shardingsphere.sql.parser.sql.common.statement.tcl.xa.XABeginStatement;
+import org.apache.shardingsphere.sql.parser.sql.common.statement.tcl.xa.XACommitStatement;
+import org.apache.shardingsphere.sql.parser.sql.common.statement.tcl.xa.XAEndStatement;
+import org.apache.shardingsphere.sql.parser.sql.common.statement.tcl.xa.XAPrepareStatement;
+import org.apache.shardingsphere.sql.parser.sql.common.statement.tcl.xa.XARecoveryStatement;
+import org.apache.shardingsphere.sql.parser.sql.common.statement.tcl.xa.XARollbackStatement;
 import org.apache.shardingsphere.sql.parser.sql.common.value.identifier.IdentifierValue;
 import org.apache.shardingsphere.sql.parser.sql.dialect.statement.mysql.tcl.MySQLBeginTransactionStatement;
 import org.apache.shardingsphere.sql.parser.sql.dialect.statement.mysql.tcl.MySQLCommitStatement;
@@ -48,7 +59,6 @@ import org.apache.shardingsphere.sql.parser.sql.dialect.statement.mysql.tcl.MySQ
 import org.apache.shardingsphere.sql.parser.sql.dialect.statement.mysql.tcl.MySQLSetAutoCommitStatement;
 import org.apache.shardingsphere.sql.parser.sql.dialect.statement.mysql.tcl.MySQLSetTransactionStatement;
 import org.apache.shardingsphere.sql.parser.sql.dialect.statement.mysql.tcl.MySQLUnlockStatement;
-import org.apache.shardingsphere.sql.parser.sql.dialect.statement.mysql.tcl.MySQLXAStatement;
 
 import java.util.Collection;
 import java.util.LinkedList;
@@ -142,8 +152,33 @@ public final class MySQLTCLStatementVisitor extends MySQLStatementVisitor implem
     }
     
     @Override
-    public ASTNode visitXa(final XaContext ctx) {
-        return new MySQLXAStatement(ctx.getChild(1).getText().toUpperCase(), null == ctx.xid() ? null : ctx.xid().getText());
+    public ASTNode visitXaBegin(final XaBeginContext ctx) {
+        return new XABeginStatement(ctx.xid().getText());
+    }
+    
+    @Override
+    public ASTNode visitXaPrepare(final XaPrepareContext ctx) {
+        return new XAPrepareStatement(ctx.xid().getText());
+    }
+    
+    @Override
+    public ASTNode visitXaCommit(final XaCommitContext ctx) {
+        return new XACommitStatement(ctx.xid().getText());
+    }
+    
+    @Override
+    public ASTNode visitXaRollback(final XaRollbackContext ctx) {
+        return new XARollbackStatement(ctx.xid().getText());
+    }
+    
+    @Override
+    public ASTNode visitXaEnd(final XaEndContext ctx) {
+        return new XAEndStatement(ctx.xid().getText());
+    }
+    
+    @Override
+    public ASTNode visitXaRecovery(final XaRecoveryContext ctx) {
+        return new XARecoveryStatement();
     }
     
     @Override
diff --git a/parser/sql/dialect/mysql/src/test/java/org/apache/shardingsphere/sql/parser/mysql/visitor/statement/MySQLXAVisitorTest.java b/parser/sql/dialect/mysql/src/test/java/org/apache/shardingsphere/sql/parser/mysql/visitor/statement/MySQLXAVisitorTest.java
deleted file mode 100644
index 90a1c465867..00000000000
--- a/parser/sql/dialect/mysql/src/test/java/org/apache/shardingsphere/sql/parser/mysql/visitor/statement/MySQLXAVisitorTest.java
+++ /dev/null
@@ -1,66 +0,0 @@
-/*
- * 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.sql.parser.mysql.visitor.statement;
-
-import org.antlr.v4.runtime.CodePointBuffer;
-import org.antlr.v4.runtime.CodePointCharStream;
-import org.antlr.v4.runtime.CommonTokenStream;
-import org.apache.shardingsphere.sql.parser.autogen.MySQLStatementParser;
-import org.apache.shardingsphere.sql.parser.mysql.parser.MySQLLexer;
-import org.apache.shardingsphere.sql.parser.mysql.visitor.statement.type.MySQLTCLStatementVisitor;
-import org.apache.shardingsphere.sql.parser.sql.dialect.statement.mysql.tcl.MySQLXAStatement;
-import org.junit.jupiter.api.extension.ExtensionContext;
-import org.junit.jupiter.params.ParameterizedTest;
-import org.junit.jupiter.params.provider.Arguments;
-import org.junit.jupiter.params.provider.ArgumentsProvider;
-import org.junit.jupiter.params.provider.ArgumentsSource;
-
-import java.nio.CharBuffer;
-import java.util.stream.Stream;
-
-import static org.hamcrest.CoreMatchers.is;
-import static org.hamcrest.MatcherAssert.assertThat;
-
-class MySQLXAVisitorTest {
-    
-    @ParameterizedTest(name = "{0}")
-    @ArgumentsSource(TestCaseArgumentsProvider.class)
-    void assertXA(final String caseId, final String inputSQL, final String operation, final String xid) {
-        CodePointBuffer buffer = CodePointBuffer.withChars(CharBuffer.wrap(inputSQL.toCharArray()));
-        MySQLLexer lexer = new MySQLLexer(CodePointCharStream.fromBuffer(buffer));
-        MySQLStatementParser parser = new MySQLStatementParser(new CommonTokenStream(lexer));
-        MySQLTCLStatementVisitor visitor = new MySQLTCLStatementVisitor();
-        MySQLXAStatement xaStatement = (MySQLXAStatement) visitor.visitXa(parser.xa());
-        assertThat("XA parse error.", parser.getNumberOfSyntaxErrors(), is(0));
-        assertThat("XA operation error.", xaStatement.getOperator(), is(operation));
-        assertThat("XA xid error.", xaStatement.getXid(), is(xid));
-    }
-    
-    private static class TestCaseArgumentsProvider implements ArgumentsProvider {
-        
-        @Override
-        public Stream<? extends Arguments> provideArguments(final ExtensionContext extensionContext) {
-            return Stream.of(Arguments.of("xa_start", "XA START 0x6262,b'000',7", "START", "0x6262,b'000',7"),
-                    Arguments.of("xa_begin", "XA BEGIN 0x6262,b'000',7", "BEGIN", "0x6262,b'000',7"),
-                    Arguments.of("xa_end", "XA END 0x6262,b'000',7", "END", "0x6262,b'000',7"),
-                    Arguments.of("xa_commit", "XA COMMIT 0x6262,b'000',7", "COMMIT", "0x6262,b'000',7"),
-                    Arguments.of("xa_rollback", "XA ROLLBACK 0x6262,b'000',7", "ROLLBACK", "0x6262,b'000',7"),
-                    Arguments.of("xa_recover", "XA RECOVER", "RECOVER", null));
-        }
-    }
-}
diff --git a/parser/sql/engine/src/main/java/org/apache/shardingsphere/sql/parser/core/database/visitor/SQLVisitorRule.java b/parser/sql/engine/src/main/java/org/apache/shardingsphere/sql/parser/core/database/visitor/SQLVisitorRule.java
index 07df221528b..4228e74bcd9 100644
--- a/parser/sql/engine/src/main/java/org/apache/shardingsphere/sql/parser/core/database/visitor/SQLVisitorRule.java
+++ b/parser/sql/engine/src/main/java/org/apache/shardingsphere/sql/parser/core/database/visitor/SQLVisitorRule.java
@@ -473,7 +473,17 @@ public enum SQLVisitorRule {
     
     STOP_SLAVE("StopSlave", SQLStatementType.RL),
     
-    XA("Xa", SQLStatementType.TCL),
+    XA_BEGIN("XaBegin", SQLStatementType.TCL),
+    
+    XA_PREPARE("XaPrepare", SQLStatementType.TCL),
+    
+    XA_COMMIT("XaCommit", SQLStatementType.TCL),
+    
+    XA_ROLLBACK("XaRollback", SQLStatementType.TCL),
+    
+    XA_END("XaEnd", SQLStatementType.TCL),
+    
+    XA_RECOVERY("XaRecovery", SQLStatementType.TCL),
     
     ABORT("Abort", SQLStatementType.TCL),
     
diff --git a/parser/sql/statement/src/main/java/org/apache/shardingsphere/sql/parser/sql/common/statement/tcl/XAStatement.java b/parser/sql/statement/src/main/java/org/apache/shardingsphere/sql/parser/sql/common/statement/tcl/xa/XABeginStatement.java
similarity index 87%
copy from parser/sql/statement/src/main/java/org/apache/shardingsphere/sql/parser/sql/common/statement/tcl/XAStatement.java
copy to parser/sql/statement/src/main/java/org/apache/shardingsphere/sql/parser/sql/common/statement/tcl/xa/XABeginStatement.java
index 94b8992143e..9595f195ea0 100644
--- a/parser/sql/statement/src/main/java/org/apache/shardingsphere/sql/parser/sql/common/statement/tcl/XAStatement.java
+++ b/parser/sql/statement/src/main/java/org/apache/shardingsphere/sql/parser/sql/common/statement/tcl/xa/XABeginStatement.java
@@ -15,20 +15,18 @@
  * limitations under the License.
  */
 
-package org.apache.shardingsphere.sql.parser.sql.common.statement.tcl;
+package org.apache.shardingsphere.sql.parser.sql.common.statement.tcl.xa;
 
 import lombok.Getter;
 import lombok.RequiredArgsConstructor;
 import org.apache.shardingsphere.sql.parser.sql.common.statement.AbstractSQLStatement;
 
 /**
- * XA statement.
+ * XA begin statement.
  */
 @RequiredArgsConstructor
 @Getter
-public abstract class XAStatement extends AbstractSQLStatement implements TCLStatement {
-    
-    private final String operator;
+public final class XABeginStatement extends AbstractSQLStatement implements XAStatement {
     
     private final String xid;
 }
diff --git a/parser/sql/statement/src/main/java/org/apache/shardingsphere/sql/parser/sql/dialect/statement/mysql/tcl/MySQLXAStatement.java b/parser/sql/statement/src/main/java/org/apache/shardingsphere/sql/parser/sql/common/statement/tcl/xa/XACommitStatement.java
similarity index 68%
rename from parser/sql/statement/src/main/java/org/apache/shardingsphere/sql/parser/sql/dialect/statement/mysql/tcl/MySQLXAStatement.java
rename to parser/sql/statement/src/main/java/org/apache/shardingsphere/sql/parser/sql/common/statement/tcl/xa/XACommitStatement.java
index c897c671c73..254a1ef4575 100644
--- a/parser/sql/statement/src/main/java/org/apache/shardingsphere/sql/parser/sql/dialect/statement/mysql/tcl/MySQLXAStatement.java
+++ b/parser/sql/statement/src/main/java/org/apache/shardingsphere/sql/parser/sql/common/statement/tcl/xa/XACommitStatement.java
@@ -15,17 +15,18 @@
  * limitations under the License.
  */
 
-package org.apache.shardingsphere.sql.parser.sql.dialect.statement.mysql.tcl;
+package org.apache.shardingsphere.sql.parser.sql.common.statement.tcl.xa;
 
-import org.apache.shardingsphere.sql.parser.sql.common.statement.tcl.XAStatement;
-import org.apache.shardingsphere.sql.parser.sql.dialect.statement.mysql.MySQLStatement;
+import lombok.Getter;
+import lombok.RequiredArgsConstructor;
+import org.apache.shardingsphere.sql.parser.sql.common.statement.AbstractSQLStatement;
 
 /**
- * MySQL XA statement.
+ * XA commit statement.
  */
-public final class MySQLXAStatement extends XAStatement implements MySQLStatement {
+@RequiredArgsConstructor
+@Getter
+public final class XACommitStatement extends AbstractSQLStatement implements XAStatement {
     
-    public MySQLXAStatement(final String operator, final String xid) {
-        super(operator, xid);
-    }
+    private final String xid;
 }
diff --git a/parser/sql/statement/src/main/java/org/apache/shardingsphere/sql/parser/sql/common/statement/tcl/XAStatement.java b/parser/sql/statement/src/main/java/org/apache/shardingsphere/sql/parser/sql/common/statement/tcl/xa/XAEndStatement.java
similarity index 87%
copy from parser/sql/statement/src/main/java/org/apache/shardingsphere/sql/parser/sql/common/statement/tcl/XAStatement.java
copy to parser/sql/statement/src/main/java/org/apache/shardingsphere/sql/parser/sql/common/statement/tcl/xa/XAEndStatement.java
index 94b8992143e..cd57cf83650 100644
--- a/parser/sql/statement/src/main/java/org/apache/shardingsphere/sql/parser/sql/common/statement/tcl/XAStatement.java
+++ b/parser/sql/statement/src/main/java/org/apache/shardingsphere/sql/parser/sql/common/statement/tcl/xa/XAEndStatement.java
@@ -15,20 +15,18 @@
  * limitations under the License.
  */
 
-package org.apache.shardingsphere.sql.parser.sql.common.statement.tcl;
+package org.apache.shardingsphere.sql.parser.sql.common.statement.tcl.xa;
 
 import lombok.Getter;
 import lombok.RequiredArgsConstructor;
 import org.apache.shardingsphere.sql.parser.sql.common.statement.AbstractSQLStatement;
 
 /**
- * XA statement.
+ * XA end statement.
  */
 @RequiredArgsConstructor
 @Getter
-public abstract class XAStatement extends AbstractSQLStatement implements TCLStatement {
-    
-    private final String operator;
+public final class XAEndStatement extends AbstractSQLStatement implements XAStatement {
     
     private final String xid;
 }
diff --git a/parser/sql/statement/src/main/java/org/apache/shardingsphere/sql/parser/sql/common/statement/tcl/XAStatement.java b/parser/sql/statement/src/main/java/org/apache/shardingsphere/sql/parser/sql/common/statement/tcl/xa/XAPrepareStatement.java
similarity index 87%
copy from parser/sql/statement/src/main/java/org/apache/shardingsphere/sql/parser/sql/common/statement/tcl/XAStatement.java
copy to parser/sql/statement/src/main/java/org/apache/shardingsphere/sql/parser/sql/common/statement/tcl/xa/XAPrepareStatement.java
index 94b8992143e..ced5ca8284a 100644
--- a/parser/sql/statement/src/main/java/org/apache/shardingsphere/sql/parser/sql/common/statement/tcl/XAStatement.java
+++ b/parser/sql/statement/src/main/java/org/apache/shardingsphere/sql/parser/sql/common/statement/tcl/xa/XAPrepareStatement.java
@@ -15,20 +15,18 @@
  * limitations under the License.
  */
 
-package org.apache.shardingsphere.sql.parser.sql.common.statement.tcl;
+package org.apache.shardingsphere.sql.parser.sql.common.statement.tcl.xa;
 
 import lombok.Getter;
 import lombok.RequiredArgsConstructor;
 import org.apache.shardingsphere.sql.parser.sql.common.statement.AbstractSQLStatement;
 
 /**
- * XA statement.
+ * XA prepare statement.
  */
 @RequiredArgsConstructor
 @Getter
-public abstract class XAStatement extends AbstractSQLStatement implements TCLStatement {
-    
-    private final String operator;
+public final class XAPrepareStatement extends AbstractSQLStatement implements XAStatement {
     
     private final String xid;
 }
diff --git a/parser/sql/statement/src/main/java/org/apache/shardingsphere/sql/parser/sql/common/statement/tcl/XAStatement.java b/parser/sql/statement/src/main/java/org/apache/shardingsphere/sql/parser/sql/common/statement/tcl/xa/XARecoveryStatement.java
similarity index 77%
copy from parser/sql/statement/src/main/java/org/apache/shardingsphere/sql/parser/sql/common/statement/tcl/XAStatement.java
copy to parser/sql/statement/src/main/java/org/apache/shardingsphere/sql/parser/sql/common/statement/tcl/xa/XARecoveryStatement.java
index 94b8992143e..f65f1828bc3 100644
--- a/parser/sql/statement/src/main/java/org/apache/shardingsphere/sql/parser/sql/common/statement/tcl/XAStatement.java
+++ b/parser/sql/statement/src/main/java/org/apache/shardingsphere/sql/parser/sql/common/statement/tcl/xa/XARecoveryStatement.java
@@ -15,20 +15,12 @@
  * limitations under the License.
  */
 
-package org.apache.shardingsphere.sql.parser.sql.common.statement.tcl;
+package org.apache.shardingsphere.sql.parser.sql.common.statement.tcl.xa;
 
-import lombok.Getter;
-import lombok.RequiredArgsConstructor;
 import org.apache.shardingsphere.sql.parser.sql.common.statement.AbstractSQLStatement;
 
 /**
- * XA statement.
+ * XA recovery statement.
  */
-@RequiredArgsConstructor
-@Getter
-public abstract class XAStatement extends AbstractSQLStatement implements TCLStatement {
-    
-    private final String operator;
-    
-    private final String xid;
+public final class XARecoveryStatement extends AbstractSQLStatement implements XAStatement {
 }
diff --git a/parser/sql/statement/src/main/java/org/apache/shardingsphere/sql/parser/sql/common/statement/tcl/XAStatement.java b/parser/sql/statement/src/main/java/org/apache/shardingsphere/sql/parser/sql/common/statement/tcl/xa/XARollbackStatement.java
similarity index 87%
copy from parser/sql/statement/src/main/java/org/apache/shardingsphere/sql/parser/sql/common/statement/tcl/XAStatement.java
copy to parser/sql/statement/src/main/java/org/apache/shardingsphere/sql/parser/sql/common/statement/tcl/xa/XARollbackStatement.java
index 94b8992143e..7afd04faa62 100644
--- a/parser/sql/statement/src/main/java/org/apache/shardingsphere/sql/parser/sql/common/statement/tcl/XAStatement.java
+++ b/parser/sql/statement/src/main/java/org/apache/shardingsphere/sql/parser/sql/common/statement/tcl/xa/XARollbackStatement.java
@@ -15,20 +15,18 @@
  * limitations under the License.
  */
 
-package org.apache.shardingsphere.sql.parser.sql.common.statement.tcl;
+package org.apache.shardingsphere.sql.parser.sql.common.statement.tcl.xa;
 
 import lombok.Getter;
 import lombok.RequiredArgsConstructor;
 import org.apache.shardingsphere.sql.parser.sql.common.statement.AbstractSQLStatement;
 
 /**
- * XA statement.
+ * XA rollback statement.
  */
 @RequiredArgsConstructor
 @Getter
-public abstract class XAStatement extends AbstractSQLStatement implements TCLStatement {
-    
-    private final String operator;
+public final class XARollbackStatement extends AbstractSQLStatement implements XAStatement {
     
     private final String xid;
 }
diff --git a/parser/sql/statement/src/main/java/org/apache/shardingsphere/sql/parser/sql/common/statement/tcl/XAStatement.java b/parser/sql/statement/src/main/java/org/apache/shardingsphere/sql/parser/sql/common/statement/tcl/xa/XAStatement.java
similarity index 76%
rename from parser/sql/statement/src/main/java/org/apache/shardingsphere/sql/parser/sql/common/statement/tcl/XAStatement.java
rename to parser/sql/statement/src/main/java/org/apache/shardingsphere/sql/parser/sql/common/statement/tcl/xa/XAStatement.java
index 94b8992143e..9ef0d834a38 100644
--- a/parser/sql/statement/src/main/java/org/apache/shardingsphere/sql/parser/sql/common/statement/tcl/XAStatement.java
+++ b/parser/sql/statement/src/main/java/org/apache/shardingsphere/sql/parser/sql/common/statement/tcl/xa/XAStatement.java
@@ -15,20 +15,12 @@
  * limitations under the License.
  */
 
-package org.apache.shardingsphere.sql.parser.sql.common.statement.tcl;
+package org.apache.shardingsphere.sql.parser.sql.common.statement.tcl.xa;
 
-import lombok.Getter;
-import lombok.RequiredArgsConstructor;
-import org.apache.shardingsphere.sql.parser.sql.common.statement.AbstractSQLStatement;
+import org.apache.shardingsphere.sql.parser.sql.common.statement.tcl.TCLStatement;
 
 /**
  * XA statement.
  */
-@RequiredArgsConstructor
-@Getter
-public abstract class XAStatement extends AbstractSQLStatement implements TCLStatement {
-    
-    private final String operator;
-    
-    private final String xid;
+public interface XAStatement extends TCLStatement {
 }
diff --git a/proxy/backend/core/src/main/java/org/apache/shardingsphere/proxy/backend/handler/transaction/TransactionBackendHandlerFactory.java b/proxy/backend/core/src/main/java/org/apache/shardingsphere/proxy/backend/handler/transaction/TransactionBackendHandlerFactory.java
index db09302219f..d1c31f65435 100644
--- a/proxy/backend/core/src/main/java/org/apache/shardingsphere/proxy/backend/handler/transaction/TransactionBackendHandlerFactory.java
+++ b/proxy/backend/core/src/main/java/org/apache/shardingsphere/proxy/backend/handler/transaction/TransactionBackendHandlerFactory.java
@@ -34,7 +34,7 @@ import org.apache.shardingsphere.sql.parser.sql.common.statement.tcl.SetAutoComm
 import org.apache.shardingsphere.sql.parser.sql.common.statement.tcl.SetTransactionStatement;
 import org.apache.shardingsphere.sql.parser.sql.common.statement.tcl.StartTransactionStatement;
 import org.apache.shardingsphere.sql.parser.sql.common.statement.tcl.TCLStatement;
-import org.apache.shardingsphere.sql.parser.sql.common.statement.tcl.XAStatement;
+import org.apache.shardingsphere.sql.parser.sql.common.statement.tcl.xa.XAStatement;
 import org.apache.shardingsphere.transaction.core.TransactionOperationType;
 
 import java.util.Collections;
diff --git a/proxy/backend/core/src/main/java/org/apache/shardingsphere/proxy/backend/handler/transaction/TransactionXAHandler.java b/proxy/backend/core/src/main/java/org/apache/shardingsphere/proxy/backend/handler/transaction/TransactionXAHandler.java
index 0882e56836c..20553ddfccd 100644
--- a/proxy/backend/core/src/main/java/org/apache/shardingsphere/proxy/backend/handler/transaction/TransactionXAHandler.java
+++ b/proxy/backend/core/src/main/java/org/apache/shardingsphere/proxy/backend/handler/transaction/TransactionXAHandler.java
@@ -27,11 +27,14 @@ import org.apache.shardingsphere.proxy.backend.handler.ProxyBackendHandler;
 import org.apache.shardingsphere.proxy.backend.response.data.QueryResponseRow;
 import org.apache.shardingsphere.proxy.backend.response.header.ResponseHeader;
 import org.apache.shardingsphere.proxy.backend.session.ConnectionSession;
-import org.apache.shardingsphere.sql.parser.sql.common.statement.tcl.XAStatement;
+import org.apache.shardingsphere.sql.parser.sql.common.statement.tcl.xa.XABeginStatement;
+import org.apache.shardingsphere.sql.parser.sql.common.statement.tcl.xa.XACommitStatement;
+import org.apache.shardingsphere.sql.parser.sql.common.statement.tcl.xa.XARecoveryStatement;
+import org.apache.shardingsphere.sql.parser.sql.common.statement.tcl.xa.XARollbackStatement;
+import org.apache.shardingsphere.sql.parser.sql.common.statement.tcl.xa.XAStatement;
 import org.apache.shardingsphere.transaction.xa.jta.exception.XATransactionNestedBeginException;
 
 import java.sql.SQLException;
-import java.sql.SQLFeatureNotSupportedException;
 import java.util.Collections;
 
 /**
@@ -41,14 +44,14 @@ import java.util.Collections;
 @RequiredArgsConstructor
 public final class TransactionXAHandler implements ProxyBackendHandler {
     
-    private final XAStatement tclStatement;
+    private final XAStatement xaStatement;
     
     private final ConnectionSession connectionSession;
     
     private final DatabaseConnector backendHandler;
     
     public TransactionXAHandler(final SQLStatementContext sqlStatementContext, final String sql, final ConnectionSession connectionSession) {
-        tclStatement = (XAStatement) sqlStatementContext.getSqlStatement();
+        xaStatement = (XAStatement) sqlStatementContext.getSqlStatement();
         this.connectionSession = connectionSession;
         backendHandler = DatabaseConnectorFactory.getInstance().newInstance(
                 new QueryContext(sqlStatementContext, sql, Collections.emptyList()), connectionSession.getDatabaseConnectionManager(), false);
@@ -56,30 +59,23 @@ public final class TransactionXAHandler implements ProxyBackendHandler {
     
     @Override
     public boolean next() throws SQLException {
-        return "RECOVER".equals(tclStatement.getOperator()) && backendHandler.next();
+        return xaStatement instanceof XARecoveryStatement && backendHandler.next();
     }
     
     @Override
     public QueryResponseRow getRowData() throws SQLException {
-        return "RECOVER".equals(tclStatement.getOperator()) ? backendHandler.getRowData() : new QueryResponseRow(Collections.emptyList());
+        return xaStatement instanceof XARecoveryStatement ? backendHandler.getRowData() : new QueryResponseRow(Collections.emptyList());
     }
     
     @Override
     public ResponseHeader execute() throws SQLException {
-        switch (tclStatement.getOperator()) {
-            case "START":
-            case "BEGIN":
-                return begin();
-            case "END":
-            case "PREPARE":
-            case "RECOVER":
-                return backendHandler.execute();
-            case "COMMIT":
-            case "ROLLBACK":
-                return finish();
-            default:
-                throw new SQLFeatureNotSupportedException(String.format("unrecognized XA statement `%s`", tclStatement.getOperator()));
+        if (xaStatement instanceof XABeginStatement) {
+            return begin();
         }
+        if (xaStatement instanceof XACommitStatement || xaStatement instanceof XARollbackStatement) {
+            return finish();
+        }
+        return backendHandler.execute();
     }
     
     /*
diff --git a/proxy/frontend/type/mysql/src/main/java/org/apache/shardingsphere/proxy/frontend/mysql/command/query/binary/prepare/MySQLComStmtPrepareChecker.java b/proxy/frontend/type/mysql/src/main/java/org/apache/shardingsphere/proxy/frontend/mysql/command/query/binary/prepare/MySQLComStmtPrepareChecker.java
index 2702c132bec..6b85c108a37 100644
--- a/proxy/frontend/type/mysql/src/main/java/org/apache/shardingsphere/proxy/frontend/mysql/command/query/binary/prepare/MySQLComStmtPrepareChecker.java
+++ b/proxy/frontend/type/mysql/src/main/java/org/apache/shardingsphere/proxy/frontend/mysql/command/query/binary/prepare/MySQLComStmtPrepareChecker.java
@@ -20,6 +20,12 @@ package org.apache.shardingsphere.proxy.frontend.mysql.command.query.binary.prep
 import lombok.AccessLevel;
 import lombok.NoArgsConstructor;
 import org.apache.shardingsphere.sql.parser.sql.common.statement.SQLStatement;
+import org.apache.shardingsphere.sql.parser.sql.common.statement.tcl.xa.XABeginStatement;
+import org.apache.shardingsphere.sql.parser.sql.common.statement.tcl.xa.XACommitStatement;
+import org.apache.shardingsphere.sql.parser.sql.common.statement.tcl.xa.XAEndStatement;
+import org.apache.shardingsphere.sql.parser.sql.common.statement.tcl.xa.XAPrepareStatement;
+import org.apache.shardingsphere.sql.parser.sql.common.statement.tcl.xa.XARecoveryStatement;
+import org.apache.shardingsphere.sql.parser.sql.common.statement.tcl.xa.XARollbackStatement;
 import org.apache.shardingsphere.sql.parser.sql.dialect.statement.mysql.dal.MySQLAnalyzeTableStatement;
 import org.apache.shardingsphere.sql.parser.sql.dialect.statement.mysql.dal.MySQLCacheIndexStatement;
 import org.apache.shardingsphere.sql.parser.sql.dialect.statement.mysql.dal.MySQLChecksumTableStatement;
@@ -69,7 +75,6 @@ import org.apache.shardingsphere.sql.parser.sql.dialect.statement.mysql.rl.MySQL
 import org.apache.shardingsphere.sql.parser.sql.dialect.statement.mysql.rl.MySQLStartSlaveStatement;
 import org.apache.shardingsphere.sql.parser.sql.dialect.statement.mysql.rl.MySQLStopSlaveStatement;
 import org.apache.shardingsphere.sql.parser.sql.dialect.statement.mysql.tcl.MySQLCommitStatement;
-import org.apache.shardingsphere.sql.parser.sql.dialect.statement.mysql.tcl.MySQLXAStatement;
 
 import java.util.Arrays;
 import java.util.Collection;
@@ -83,10 +88,10 @@ import java.util.HashSet;
 @NoArgsConstructor(access = AccessLevel.PRIVATE)
 public final class MySQLComStmtPrepareChecker {
     
-    private static final Collection<Class<?>> SQL_STATEMENTS_ALLOWED = new HashSet<>();
+    private static final Collection<Class<?>> ALLOWED_SQL_STATEMENTS = new HashSet<>();
     
     static {
-        SQL_STATEMENTS_ALLOWED.addAll(Arrays.asList(MySQLAlterTableStatement.class, MySQLAlterUserStatement.class, MySQLAnalyzeTableStatement.class,
+        ALLOWED_SQL_STATEMENTS.addAll(Arrays.asList(MySQLAlterTableStatement.class, MySQLAlterUserStatement.class, MySQLAnalyzeTableStatement.class,
                 MySQLCacheIndexStatement.class, MySQLCallStatement.class, MySQLChangeMasterStatement.class, MySQLChecksumTableStatement.class, MySQLCommitStatement.class,
                 MySQLCreateIndexStatement.class, MySQLDropIndexStatement.class, MySQLCreateDatabaseStatement.class, MySQLDropDatabaseStatement.class,
                 MySQLCreateTableStatement.class, MySQLDropTableStatement.class, MySQLCreateUserStatement.class, MySQLRenameUserStatement.class, MySQLDropUserStatement.class,
@@ -96,7 +101,8 @@ public final class MySQLComStmtPrepareChecker {
                 MySQLRevokeStatement.class, MySQLSelectStatement.class, MySQLSetStatement.class, MySQLShowWarningsStatement.class, MySQLShowErrorsStatement.class,
                 MySQLShowBinlogEventsStatement.class, MySQLShowCreateProcedureStatement.class, MySQLShowCreateFunctionStatement.class, MySQLShowCreateEventStatement.class,
                 MySQLShowCreateTableStatement.class, MySQLShowCreateViewStatement.class, MySQLShowBinaryLogsStatement.class, MySQLShowStatusStatement.class,
-                MySQLStartSlaveStatement.class, MySQLStopSlaveStatement.class, MySQLTruncateStatement.class, MySQLUninstallPluginStatement.class, MySQLUpdateStatement.class, MySQLXAStatement.class));
+                MySQLStartSlaveStatement.class, MySQLStopSlaveStatement.class, MySQLTruncateStatement.class, MySQLUninstallPluginStatement.class, MySQLUpdateStatement.class,
+                XABeginStatement.class, XAPrepareStatement.class, XACommitStatement.class, XARollbackStatement.class, XAEndStatement.class, XARecoveryStatement.class));
     }
     
     /**
@@ -105,7 +111,7 @@ public final class MySQLComStmtPrepareChecker {
      * @param sqlStatement SQL statement
      * @return SQL statement is allowed or not
      */
-    public static boolean isStatementAllowed(final SQLStatement sqlStatement) {
-        return SQL_STATEMENTS_ALLOWED.contains(sqlStatement.getClass());
+    public static boolean isAllowedStatement(final SQLStatement sqlStatement) {
+        return ALLOWED_SQL_STATEMENTS.contains(sqlStatement.getClass());
     }
 }
diff --git a/proxy/frontend/type/mysql/src/main/java/org/apache/shardingsphere/proxy/frontend/mysql/command/query/binary/prepare/MySQLComStmtPrepareExecutor.java b/proxy/frontend/type/mysql/src/main/java/org/apache/shardingsphere/proxy/frontend/mysql/command/query/binary/prepare/MySQLComStmtPrepareExecutor.java
index c88dcb5b5e1..995aced3b2b 100644
--- a/proxy/frontend/type/mysql/src/main/java/org/apache/shardingsphere/proxy/frontend/mysql/command/query/binary/prepare/MySQLComStmtPrepareExecutor.java
+++ b/proxy/frontend/type/mysql/src/main/java/org/apache/shardingsphere/proxy/frontend/mysql/command/query/binary/prepare/MySQLComStmtPrepareExecutor.java
@@ -77,7 +77,7 @@ public final class MySQLComStmtPrepareExecutor implements CommandExecutor<MySQLP
         MetaDataContexts metaDataContexts = ProxyContext.getInstance().getContextManager().getMetaDataContexts();
         SQLParserRule sqlParserRule = metaDataContexts.getMetaData().getGlobalRuleMetaData().getSingleRule(SQLParserRule.class);
         SQLStatement sqlStatement = sqlParserRule.getSQLParserEngine(TypedSPILoader.getService(DatabaseType.class, "MySQL").getType()).parse(packet.getSql(), true);
-        if (!MySQLComStmtPrepareChecker.isStatementAllowed(sqlStatement)) {
+        if (!MySQLComStmtPrepareChecker.isAllowedStatement(sqlStatement)) {
             throw new UnsupportedPreparedStatementException();
         }
         SQLStatementContext sqlStatementContext = SQLStatementContextFactory.newInstance(ProxyContext.getInstance().getContextManager().getMetaDataContexts().getMetaData(),
diff --git a/proxy/frontend/type/mysql/src/test/java/org/apache/shardingsphere/proxy/frontend/mysql/command/query/binary/prepare/MySQLComStmtPrepareCheckerTest.java b/proxy/frontend/type/mysql/src/test/java/org/apache/shardingsphere/proxy/frontend/mysql/command/query/binary/prepare/MySQLComStmtPrepareCheckerTest.java
index c5d01dd7839..7d10926b19e 100644
--- a/proxy/frontend/type/mysql/src/test/java/org/apache/shardingsphere/proxy/frontend/mysql/command/query/binary/prepare/MySQLComStmtPrepareCheckerTest.java
+++ b/proxy/frontend/type/mysql/src/test/java/org/apache/shardingsphere/proxy/frontend/mysql/command/query/binary/prepare/MySQLComStmtPrepareCheckerTest.java
@@ -18,6 +18,12 @@
 package org.apache.shardingsphere.proxy.frontend.mysql.command.query.binary.prepare;
 
 import org.apache.shardingsphere.sql.parser.sql.common.statement.SQLStatement;
+import org.apache.shardingsphere.sql.parser.sql.common.statement.tcl.xa.XABeginStatement;
+import org.apache.shardingsphere.sql.parser.sql.common.statement.tcl.xa.XACommitStatement;
+import org.apache.shardingsphere.sql.parser.sql.common.statement.tcl.xa.XAEndStatement;
+import org.apache.shardingsphere.sql.parser.sql.common.statement.tcl.xa.XAPrepareStatement;
+import org.apache.shardingsphere.sql.parser.sql.common.statement.tcl.xa.XARecoveryStatement;
+import org.apache.shardingsphere.sql.parser.sql.common.statement.tcl.xa.XARollbackStatement;
 import org.apache.shardingsphere.sql.parser.sql.dialect.statement.mysql.dal.MySQLAnalyzeTableStatement;
 import org.apache.shardingsphere.sql.parser.sql.dialect.statement.mysql.dal.MySQLCacheIndexStatement;
 import org.apache.shardingsphere.sql.parser.sql.dialect.statement.mysql.dal.MySQLChecksumTableStatement;
@@ -67,7 +73,6 @@ import org.apache.shardingsphere.sql.parser.sql.dialect.statement.mysql.rl.MySQL
 import org.apache.shardingsphere.sql.parser.sql.dialect.statement.mysql.rl.MySQLStartSlaveStatement;
 import org.apache.shardingsphere.sql.parser.sql.dialect.statement.mysql.rl.MySQLStopSlaveStatement;
 import org.apache.shardingsphere.sql.parser.sql.dialect.statement.mysql.tcl.MySQLCommitStatement;
-import org.apache.shardingsphere.sql.parser.sql.dialect.statement.mysql.tcl.MySQLXAStatement;
 import org.junit.jupiter.api.Test;
 
 import java.util.Arrays;
@@ -91,9 +96,10 @@ class MySQLComStmtPrepareCheckerTest {
                 new MySQLShowErrorsStatement(), new MySQLShowBinlogEventsStatement(), new MySQLShowCreateProcedureStatement(), new MySQLShowCreateFunctionStatement(),
                 new MySQLShowCreateEventStatement(),
                 new MySQLShowCreateTableStatement(), new MySQLShowCreateViewStatement(), new MySQLShowBinaryLogsStatement(), new MySQLShowStatusStatement(), new MySQLStartSlaveStatement(),
-                new MySQLStopSlaveStatement(), new MySQLTruncateStatement(), new MySQLUninstallPluginStatement(), new MySQLUpdateStatement(), new MySQLXAStatement("END", null));
+                new MySQLStopSlaveStatement(), new MySQLTruncateStatement(), new MySQLUninstallPluginStatement(), new MySQLUpdateStatement(),
+                new XABeginStatement("1"), new XAPrepareStatement("1"), new XACommitStatement("1"), new XARollbackStatement("1"), new XAEndStatement("1"), new XARecoveryStatement());
         for (SQLStatement each : sqlStatements) {
-            assertTrue(MySQLComStmtPrepareChecker.isStatementAllowed(each));
+            assertTrue(MySQLComStmtPrepareChecker.isAllowedStatement(each));
         }
     }
 }