From d6df81c0cf2d8d77dddcbcc9d397152cf5e75587 Mon Sep 17 00:00:00 2001 From: Raigor Date: Thu, 28 Dec 2023 16:37:25 +0800 Subject: [PATCH] Fix #29578, add RenameTableStatement to UnsupportedSQLStatements in Proxy (#29582) * Add RenameTableStatement to UnsupportedSQLStatements * Add test cases for unsupported SQL statements in Proxy. --- .../RenameTableStatementSchemaRefresher.java | 2 +- .../handler/ProxyBackendHandlerFactory.java | 5 ++-- .../ProxyBackendHandlerFactoryTest.java | 30 +++++++++++++++---- 3 files changed, 28 insertions(+), 9 deletions(-) diff --git a/infra/context/src/main/java/org/apache/shardingsphere/infra/connection/refresher/type/table/RenameTableStatementSchemaRefresher.java b/infra/context/src/main/java/org/apache/shardingsphere/infra/connection/refresher/type/table/RenameTableStatementSchemaRefresher.java index b851025cca363..914341d984816 100644 --- a/infra/context/src/main/java/org/apache/shardingsphere/infra/connection/refresher/type/table/RenameTableStatementSchemaRefresher.java +++ b/infra/context/src/main/java/org/apache/shardingsphere/infra/connection/refresher/type/table/RenameTableStatementSchemaRefresher.java @@ -60,7 +60,7 @@ public void refresh(final ModeContextManager modeContextManager, final ShardingS private ShardingSphereTable getTable(final ShardingSphereDatabase database, final Collection logicDataSourceNames, final String schemaName, final String tableName, final ConfigurationProperties props) throws SQLException { RuleMetaData ruleMetaData = new RuleMetaData(new LinkedList<>(database.getRuleMetaData().getRules())); - if (TableRefreshUtils.isSingleTable(tableName, database)) { + if (TableRefreshUtils.isSingleTable(tableName, database) && !logicDataSourceNames.isEmpty()) { ruleMetaData.findRules(MutableDataNodeRule.class).forEach(each -> each.put(logicDataSourceNames.iterator().next(), schemaName, tableName)); } GenericSchemaBuilderMaterial material = new GenericSchemaBuilderMaterial( diff --git a/proxy/backend/core/src/main/java/org/apache/shardingsphere/proxy/backend/handler/ProxyBackendHandlerFactory.java b/proxy/backend/core/src/main/java/org/apache/shardingsphere/proxy/backend/handler/ProxyBackendHandlerFactory.java index fa9aa2db00997..1496e67df9664 100644 --- a/proxy/backend/core/src/main/java/org/apache/shardingsphere/proxy/backend/handler/ProxyBackendHandlerFactory.java +++ b/proxy/backend/core/src/main/java/org/apache/shardingsphere/proxy/backend/handler/ProxyBackendHandlerFactory.java @@ -58,6 +58,7 @@ import org.apache.shardingsphere.sql.parser.sql.common.statement.dcl.DCLStatement; import org.apache.shardingsphere.sql.parser.sql.common.statement.ddl.CreateDatabaseStatement; import org.apache.shardingsphere.sql.parser.sql.common.statement.ddl.DropDatabaseStatement; +import org.apache.shardingsphere.sql.parser.sql.common.statement.ddl.RenameTableStatement; import org.apache.shardingsphere.sql.parser.sql.common.statement.tcl.TCLStatement; import org.apache.shardingsphere.sql.parser.sql.common.util.SQLUtils; import org.apache.shardingsphere.sql.parser.sql.dialect.statement.mysql.dal.MySQLShowCreateUserStatement; @@ -222,8 +223,8 @@ private static Optional findDatabaseOperateBackendHandler(f } private static void checkUnsupportedSQLStatement(final SQLStatement sqlStatement) { - if (sqlStatement instanceof DCLStatement || sqlStatement instanceof FlushStatement || sqlStatement instanceof MySQLShowCreateUserStatement) { - throw new UnsupportedSQLOperationException("Unsupported operation"); + if (sqlStatement instanceof DCLStatement || sqlStatement instanceof FlushStatement || sqlStatement instanceof MySQLShowCreateUserStatement || sqlStatement instanceof RenameTableStatement) { + throw new UnsupportedSQLOperationException(String.format("unsupported SQL statement `%s`", sqlStatement.getClass().getSimpleName())); } } diff --git a/proxy/backend/core/src/test/java/org/apache/shardingsphere/proxy/backend/handler/ProxyBackendHandlerFactoryTest.java b/proxy/backend/core/src/test/java/org/apache/shardingsphere/proxy/backend/handler/ProxyBackendHandlerFactoryTest.java index 8e7cc3a984b91..7c6ec5cfc32fb 100644 --- a/proxy/backend/core/src/test/java/org/apache/shardingsphere/proxy/backend/handler/ProxyBackendHandlerFactoryTest.java +++ b/proxy/backend/core/src/test/java/org/apache/shardingsphere/proxy/backend/handler/ProxyBackendHandlerFactoryTest.java @@ -22,12 +22,12 @@ import org.apache.shardingsphere.infra.config.props.ConfigurationProperties; import org.apache.shardingsphere.infra.database.core.DefaultDatabase; import org.apache.shardingsphere.infra.database.core.type.DatabaseType; +import org.apache.shardingsphere.infra.exception.core.external.sql.type.generic.UnsupportedSQLOperationException; import org.apache.shardingsphere.infra.hint.HintValueContext; import org.apache.shardingsphere.infra.metadata.database.ShardingSphereDatabase; import org.apache.shardingsphere.infra.metadata.database.rule.RuleMetaData; -import org.apache.shardingsphere.infra.state.cluster.ClusterState; -import org.apache.shardingsphere.infra.exception.core.external.sql.type.generic.UnsupportedSQLOperationException; import org.apache.shardingsphere.infra.spi.type.typed.TypedSPILoader; +import org.apache.shardingsphere.infra.state.cluster.ClusterState; import org.apache.shardingsphere.mode.manager.ContextManager; import org.apache.shardingsphere.mode.metadata.MetaDataContexts; import org.apache.shardingsphere.parser.rule.SQLParserRule; @@ -194,14 +194,32 @@ void assertNewInstanceWithErrorRDL() { } @Test - void assertUnsupportedNonQueryDistSQLInTransaction() { + void assertNewInstanceWithUnsupportedDCLSQLStatement() { + String sql = "CREATE USER 'foo'@'%' IDENTIFIED BY 'bar';"; + assertThrows(UnsupportedSQLOperationException.class, () -> ProxyBackendHandlerFactory.newInstance(databaseType, sql, connectionSession, new HintValueContext())); + } + + @Test + void assertNewInstanceWithUnsupportedDALSQLStatement() { + assertThrows(UnsupportedSQLOperationException.class, () -> ProxyBackendHandlerFactory.newInstance(databaseType, "FLUSH PRIVILEGES;", connectionSession, new HintValueContext())); + assertThrows(UnsupportedSQLOperationException.class, () -> ProxyBackendHandlerFactory.newInstance(databaseType, "SHOW CREATE USER foo;", connectionSession, new HintValueContext())); + } + + @Test + void assertNewInstanceWithUnsupportedDDLSQLStatement() { + String sql = "RENAME TABLE foo TO bar;"; + assertThrows(UnsupportedSQLOperationException.class, () -> ProxyBackendHandlerFactory.newInstance(databaseType, sql, connectionSession, new HintValueContext())); + } + + @Test + void assertNewInstanceWithUnsupportedNonQueryDistSQLInTransaction() { when(connectionSession.getTransactionStatus().isInTransaction()).thenReturn(true); String sql = "CREATE SHARDING TABLE RULE t_order (STORAGE_UNITS(ms_group_0,ms_group_1), SHARDING_COLUMN=order_id, TYPE(NAME='hash_mod', PROPERTIES('sharding-count'='4')));"; assertThrows(UnsupportedSQLOperationException.class, () -> ProxyBackendHandlerFactory.newInstance(databaseType, sql, connectionSession, new HintValueContext())); } @Test - void assertUnsupportedQueryableRALStatementInTransaction() throws SQLException { + void assertNewInstanceWithQueryableRALStatementInTransaction() throws SQLException { when(connectionSession.getTransactionStatus().isInTransaction()).thenReturn(true); String sql = "SHOW TRANSACTION RULE;"; ProxyBackendHandler actual = ProxyBackendHandlerFactory.newInstance(databaseType, sql, connectionSession, new HintValueContext()); @@ -209,7 +227,7 @@ void assertUnsupportedQueryableRALStatementInTransaction() throws SQLException { } @Test - void assertUnsupportedRQLStatementInTransaction() throws SQLException { + void assertNewInstanceWithRQLStatementInTransaction() throws SQLException { when(connectionSession.getTransactionStatus().isInTransaction()).thenReturn(true); String sql = "SHOW DEFAULT SINGLE TABLE STORAGE UNIT"; ProxyBackendHandler actual = ProxyBackendHandlerFactory.newInstance(databaseType, sql, connectionSession, new HintValueContext()); @@ -217,7 +235,7 @@ void assertUnsupportedRQLStatementInTransaction() throws SQLException { } @Test - void assertDistSQLRULStatementInTransaction() throws SQLException { + void assertNewInstanceWithRULStatementInTransaction() 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, new HintValueContext());