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 635d9db1bc4 Fix RUL DistSQL execution failure in transaction(#19831) 
(#19834)
635d9db1bc4 is described below

commit 635d9db1bc423ad1d55d6f986d71bc2b47acf922
Author: ZhangCheng <[email protected]>
AuthorDate: Thu Aug 4 13:43:40 2022 +0800

    Fix RUL DistSQL execution failure in transaction(#19831) (#19834)
    
    * Fix RUL DistSQL execution failure in transaction(#19831)
    
    * Fix checkstyle
    
    * Modify the method name
    
    * Formated code by Spotless
---
 .../backend/handler/ProxyBackendHandlerFactory.java     | 17 +++++++++++++----
 .../backend/handler/ProxyBackendHandlerFactoryTest.java | 11 ++++++++++-
 2 files changed, 23 insertions(+), 5 deletions(-)

diff --git 
a/shardingsphere-proxy/shardingsphere-proxy-backend/src/main/java/org/apache/shardingsphere/proxy/backend/handler/ProxyBackendHandlerFactory.java
 
b/shardingsphere-proxy/shardingsphere-proxy-backend/src/main/java/org/apache/shardingsphere/proxy/backend/handler/ProxyBackendHandlerFactory.java
index 0010ed32c03..d3b92e5a11f 100644
--- 
a/shardingsphere-proxy/shardingsphere-proxy-backend/src/main/java/org/apache/shardingsphere/proxy/backend/handler/ProxyBackendHandlerFactory.java
+++ 
b/shardingsphere-proxy/shardingsphere-proxy-backend/src/main/java/org/apache/shardingsphere/proxy/backend/handler/ProxyBackendHandlerFactory.java
@@ -23,6 +23,7 @@ import lombok.NoArgsConstructor;
 import org.apache.shardingsphere.distsql.parser.statement.DistSQLStatement;
 import 
org.apache.shardingsphere.distsql.parser.statement.ral.QueryableRALStatement;
 import org.apache.shardingsphere.distsql.parser.statement.rql.RQLStatement;
+import org.apache.shardingsphere.distsql.parser.statement.rul.RULStatement;
 import org.apache.shardingsphere.infra.binder.LogicSQL;
 import org.apache.shardingsphere.infra.binder.SQLStatementContextFactory;
 import org.apache.shardingsphere.infra.binder.statement.SQLStatementContext;
@@ -34,7 +35,6 @@ import 
org.apache.shardingsphere.mode.metadata.MetaDataContexts;
 import org.apache.shardingsphere.parser.rule.SQLParserRule;
 import 
org.apache.shardingsphere.proxy.backend.communication.SQLStatementDatabaseHolder;
 import org.apache.shardingsphere.proxy.backend.context.ProxyContext;
-import org.apache.shardingsphere.proxy.backend.session.ConnectionSession;
 import 
org.apache.shardingsphere.proxy.backend.handler.admin.DatabaseAdminBackendHandlerFactory;
 import 
org.apache.shardingsphere.proxy.backend.handler.data.DatabaseBackendHandlerFactory;
 import 
org.apache.shardingsphere.proxy.backend.handler.database.DatabaseOperateBackendHandlerFactory;
@@ -42,6 +42,7 @@ import 
org.apache.shardingsphere.proxy.backend.handler.distsql.DistSQLBackendHan
 import 
org.apache.shardingsphere.proxy.backend.handler.extra.ExtraProxyBackendHandler;
 import org.apache.shardingsphere.proxy.backend.handler.skip.SkipBackendHandler;
 import 
org.apache.shardingsphere.proxy.backend.handler.transaction.TransactionBackendHandlerFactory;
+import org.apache.shardingsphere.proxy.backend.session.ConnectionSession;
 import org.apache.shardingsphere.spi.ShardingSphereServiceLoader;
 import org.apache.shardingsphere.sql.parser.sql.common.statement.SQLStatement;
 import 
org.apache.shardingsphere.sql.parser.sql.common.statement.dal.FlushStatement;
@@ -106,9 +107,7 @@ public final class ProxyBackendHandlerFactory {
         
databaseType.handleRollbackOnly(connectionSession.getTransactionStatus().isRollbackOnly(),
 sqlStatement);
         checkUnsupportedSQLStatement(sqlStatement);
         if (sqlStatement instanceof DistSQLStatement) {
-            if (connectionSession.getTransactionStatus().isInTransaction() && 
!(sqlStatement instanceof RQLStatement || sqlStatement instanceof 
QueryableRALStatement)) {
-                throw new UnsupportedOperationException("Non-query dist sql is 
not supported within a transaction");
-            }
+            checkUnsupportedDistSQLStatementInTransaction(sqlStatement, 
connectionSession);
             return DistSQLBackendHandlerFactory.newInstance((DistSQLStatement) 
sqlStatement, connectionSession);
         }
         SQLStatementContext<?> sqlStatementContext = 
SQLStatementContextFactory.newInstance(ProxyContext.getInstance().getContextManager().getMetaDataContexts().getMetaData().getDatabases(),
@@ -161,6 +160,16 @@ public final class ProxyBackendHandlerFactory {
         return backendHandler.orElseGet(() -> 
DatabaseBackendHandlerFactory.newInstance(logicSQL, connectionSession, 
preferPreparedStatement));
     }
     
+    private static void checkUnsupportedDistSQLStatementInTransaction(final 
SQLStatement sqlStatement, final ConnectionSession connectionSession) {
+        if (connectionSession.getTransactionStatus().isInTransaction() && 
!isSupportedDistSQLStatementInTransaction(sqlStatement)) {
+            throw new UnsupportedOperationException("Non-query dist sql is not 
supported within a transaction");
+        }
+    }
+    
+    private static boolean isSupportedDistSQLStatementInTransaction(final 
SQLStatement sqlStatement) {
+        return sqlStatement instanceof RQLStatement || sqlStatement instanceof 
QueryableRALStatement || sqlStatement instanceof RULStatement;
+    }
+    
     private static DatabaseType getProtocolType(final DatabaseType 
defaultDatabaseType, final ConnectionSession connectionSession) {
         String databaseName = connectionSession.getDatabaseName();
         return Strings.isNullOrEmpty(databaseName) || 
!ProxyContext.getInstance().databaseExists(databaseName)
diff --git 
a/shardingsphere-proxy/shardingsphere-proxy-backend/src/test/java/org/apache/shardingsphere/proxy/backend/handler/ProxyBackendHandlerFactoryTest.java
 
b/shardingsphere-proxy/shardingsphere-proxy-backend/src/test/java/org/apache/shardingsphere/proxy/backend/handler/ProxyBackendHandlerFactoryTest.java
index cb78d0e87ee..e65367fcd4d 100644
--- 
a/shardingsphere-proxy/shardingsphere-proxy-backend/src/test/java/org/apache/shardingsphere/proxy/backend/handler/ProxyBackendHandlerFactoryTest.java
+++ 
b/shardingsphere-proxy/shardingsphere-proxy-backend/src/test/java/org/apache/shardingsphere/proxy/backend/handler/ProxyBackendHandlerFactoryTest.java
@@ -30,7 +30,6 @@ import org.apache.shardingsphere.parser.rule.SQLParserRule;
 import 
org.apache.shardingsphere.proxy.backend.communication.DatabaseCommunicationEngine;
 import 
org.apache.shardingsphere.proxy.backend.communication.jdbc.connection.JDBCBackendConnection;
 import org.apache.shardingsphere.proxy.backend.context.ProxyContext;
-import org.apache.shardingsphere.proxy.backend.session.ConnectionSession;
 import 
org.apache.shardingsphere.proxy.backend.handler.admin.DatabaseAdminQueryBackendHandler;
 import 
org.apache.shardingsphere.proxy.backend.handler.admin.DatabaseAdminUpdateBackendHandler;
 import 
org.apache.shardingsphere.proxy.backend.handler.data.impl.UnicastDatabaseBackendHandler;
@@ -38,8 +37,10 @@ import 
org.apache.shardingsphere.proxy.backend.handler.distsql.ral.QueryableRALB
 import 
org.apache.shardingsphere.proxy.backend.handler.distsql.ral.hint.HintRALBackendHandler;
 import 
org.apache.shardingsphere.proxy.backend.handler.distsql.ral.updatable.SetVariableHandler;
 import 
org.apache.shardingsphere.proxy.backend.handler.distsql.rql.RQLBackendHandler;
+import 
org.apache.shardingsphere.proxy.backend.handler.distsql.rul.SQLRULBackendHandler;
 import org.apache.shardingsphere.proxy.backend.handler.skip.SkipBackendHandler;
 import 
org.apache.shardingsphere.proxy.backend.handler.transaction.TransactionBackendHandler;
+import org.apache.shardingsphere.proxy.backend.session.ConnectionSession;
 import org.apache.shardingsphere.proxy.backend.util.ProxyContextRestorer;
 import org.apache.shardingsphere.sql.parser.api.CacheOption;
 import org.apache.shardingsphere.sql.parser.exception.SQLParsingException;
@@ -260,4 +261,12 @@ public final class ProxyBackendHandlerFactoryTest extends 
ProxyContextRestorer {
         ProxyBackendHandler actual = 
ProxyBackendHandlerFactory.newInstance(databaseType, sql, connectionSession);
         assertThat(actual, instanceOf(RQLBackendHandler.class));
     }
+    
+    @Test
+    public void assertDistSQLRULStatementInTransaction() throws SQLException {
+        
when(connectionSession.getTransactionStatus().isInTransaction()).thenReturn(true);
+        String sql = "PREVIEW INSERT INTO account VALUES(1, 1, 1)";
+        ProxyBackendHandler actual = 
ProxyBackendHandlerFactory.newInstance(databaseType, sql, connectionSession);
+        assertThat(actual, instanceOf(SQLRULBackendHandler.class));
+    }
 }

Reply via email to