You are viewing a plain text version of this content. The canonical link for it is here.
Posted to notifications@shardingsphere.apache.org by zh...@apache.org on 2026/06/24 04:29:45 UTC
(shardingsphere) branch master updated: Fix unsupported MySQL temporary table DDL before backend execution (#38829)
This is an automated email from the ASF dual-hosted git repository.
terrymanu 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 31fa9e722f5 Fix unsupported MySQL temporary table DDL before backend execution (#38829)
31fa9e722f5 is described below
commit 31fa9e722f55498c173a08a4c41274d592e83c44
Author: Zhengcy05 <18...@qq.com>
AuthorDate: Wed Jun 24 12:29:38 2026 +0800
Fix unsupported MySQL temporary table DDL before backend execution (#38829)
* Fix: MySQL temporary table DDL pre-execution guard
* fix: block Doris temporary table DDL before metadata refresh
---
.../statement/ddl/CreateTableStatementBinder.java | 1 +
.../statement/ddl/DropTableStatementBinder.java | 2 +-
.../infra/connection/kernel/KernelProcessor.java | 15 ++++++
.../connection/kernel/KernelProcessorTest.java | 58 ++++++++++++++++++--
.../statement/type/DorisDDLStatementVisitor.java | 4 +-
.../statement/type/DorisStatementVisitorTest.java | 61 +++++++++++++++++++++
.../statement/type/MySQLDDLStatementVisitor.java | 3 +-
.../statement/MySQLStatementVisitorTest.java | 63 ++++++++++++++++++++++
.../type/ddl/table/CreateTableStatement.java | 5 +-
.../type/ddl/table/DropTableStatement.java | 7 +++
.../StandardDatabaseProxyConnectorTest.java | 23 ++++++++
11 files changed, 235 insertions(+), 7 deletions(-)
diff --git a/infra/binder/core/src/main/java/org/apache/shardingsphere/infra/binder/engine/statement/ddl/CreateTableStatementBinder.java b/infra/binder/core/src/main/java/org/apache/shardingsphere/infra/binder/engine/statement/ddl/CreateTableStatementBinder.java
index 8ed38d0850f..59fcfce8126 100644
--- a/infra/binder/core/src/main/java/org/apache/shardingsphere/infra/binder/engine/statement/ddl/CreateTableStatementBinder.java
+++ b/infra/binder/core/src/main/java/org/apache/shardingsphere/infra/binder/engine/statement/ddl/CreateTableStatementBinder.java
@@ -57,6 +57,7 @@ public final class CreateTableStatementBinder implements SQLStatementBinder<Crea
.table(boundTable)
.selectStatement(boundSelectStatement)
.ifNotExists(sqlStatement.isIfNotExists())
+ .temporary(sqlStatement.isTemporary())
.likeTable(sqlStatement.getLikeTable().orElse(null))
.createTableOption(sqlStatement.getCreateTableOption().orElse(null))
.columnDefinitions(boundColumnDefinitions)
diff --git a/infra/binder/core/src/main/java/org/apache/shardingsphere/infra/binder/engine/statement/ddl/DropTableStatementBinder.java b/infra/binder/core/src/main/java/org/apache/shardingsphere/infra/binder/engine/statement/ddl/DropTableStatementBinder.java
index cc4a8e8bac0..d76719eea02 100644
--- a/infra/binder/core/src/main/java/org/apache/shardingsphere/infra/binder/engine/statement/ddl/DropTableStatementBinder.java
+++ b/infra/binder/core/src/main/java/org/apache/shardingsphere/infra/binder/engine/statement/ddl/DropTableStatementBinder.java
@@ -41,7 +41,7 @@ public final class DropTableStatementBinder implements SQLStatementBinder<DropTa
}
private DropTableStatement copy(final DropTableStatement sqlStatement, final Collection<SimpleTableSegment> boundTables) {
- DropTableStatement result = new DropTableStatement(sqlStatement.getDatabaseType(), boundTables, sqlStatement.isIfExists(), sqlStatement.isContainsCascade());
+ DropTableStatement result = new DropTableStatement(sqlStatement.getDatabaseType(), boundTables, sqlStatement.isIfExists(), sqlStatement.isTemporary(), sqlStatement.isContainsCascade());
SQLStatementCopyUtils.copyAttributes(sqlStatement, result);
return result;
}
diff --git a/infra/context/src/main/java/org/apache/shardingsphere/infra/connection/kernel/KernelProcessor.java b/infra/context/src/main/java/org/apache/shardingsphere/infra/connection/kernel/KernelProcessor.java
index 73b98f00da3..86ad5360ad3 100644
--- a/infra/context/src/main/java/org/apache/shardingsphere/infra/connection/kernel/KernelProcessor.java
+++ b/infra/context/src/main/java/org/apache/shardingsphere/infra/connection/kernel/KernelProcessor.java
@@ -21,6 +21,7 @@ import org.apache.shardingsphere.infra.annotation.HighFrequencyInvocation;
import org.apache.shardingsphere.infra.checker.SupportedSQLCheckEngine;
import org.apache.shardingsphere.infra.config.props.ConfigurationProperties;
import org.apache.shardingsphere.infra.config.props.ConfigurationPropertyKey;
+import org.apache.shardingsphere.infra.exception.generic.UnsupportedSQLOperationException;
import org.apache.shardingsphere.infra.executor.sql.context.ExecutionContext;
import org.apache.shardingsphere.infra.executor.sql.context.ExecutionContextBuilder;
import org.apache.shardingsphere.infra.executor.sql.log.SQLLogger;
@@ -31,6 +32,9 @@ import org.apache.shardingsphere.infra.rewrite.engine.result.SQLRewriteResult;
import org.apache.shardingsphere.infra.route.context.RouteContext;
import org.apache.shardingsphere.infra.route.engine.SQLRouteEngine;
import org.apache.shardingsphere.infra.session.query.QueryContext;
+import org.apache.shardingsphere.sql.parser.statement.core.statement.SQLStatement;
+import org.apache.shardingsphere.sql.parser.statement.core.statement.type.ddl.table.CreateTableStatement;
+import org.apache.shardingsphere.sql.parser.statement.core.statement.type.ddl.table.DropTableStatement;
/**
* Kernel processor.
@@ -56,6 +60,7 @@ public final class KernelProcessor {
}
private void check(final QueryContext queryContext) {
+ checkUnsupportedTemporaryTableDDL(queryContext);
if (queryContext.getHintValueContext().isSkipMetadataValidate()) {
return;
}
@@ -63,6 +68,16 @@ public final class KernelProcessor {
new SupportedSQLCheckEngine().checkSQL(database.getRuleMetaData().getRules(), queryContext.getSqlStatementContext(), database);
}
+ private void checkUnsupportedTemporaryTableDDL(final QueryContext queryContext) {
+ SQLStatement sqlStatement = queryContext.getSqlStatementContext().getSqlStatement();
+ if (sqlStatement instanceof CreateTableStatement && ((CreateTableStatement) sqlStatement).isTemporary()) {
+ throw new UnsupportedSQLOperationException("CREATE TEMPORARY TABLE");
+ }
+ if (sqlStatement instanceof DropTableStatement && ((DropTableStatement) sqlStatement).isTemporary()) {
+ throw new UnsupportedSQLOperationException("DROP TEMPORARY TABLE");
+ }
+ }
+
private RouteContext route(final QueryContext queryContext, final RuleMetaData globalRuleMetaData, final ConfigurationProperties props) {
ShardingSphereDatabase database = queryContext.getUsedDatabase();
return new SQLRouteEngine(database.getRuleMetaData().getRules(), props).route(queryContext, globalRuleMetaData, database);
diff --git a/infra/context/src/test/java/org/apache/shardingsphere/infra/connection/kernel/KernelProcessorTest.java b/infra/context/src/test/java/org/apache/shardingsphere/infra/connection/kernel/KernelProcessorTest.java
index d4bef23791e..668ea8c920e 100644
--- a/infra/context/src/test/java/org/apache/shardingsphere/infra/connection/kernel/KernelProcessorTest.java
+++ b/infra/context/src/test/java/org/apache/shardingsphere/infra/connection/kernel/KernelProcessorTest.java
@@ -18,11 +18,12 @@
package org.apache.shardingsphere.infra.connection.kernel;
import org.apache.shardingsphere.database.connector.core.type.DatabaseType;
-import org.apache.shardingsphere.infra.binder.context.statement.SQLStatementContext;
import org.apache.shardingsphere.infra.binder.context.statement.type.CommonSQLStatementContext;
+import org.apache.shardingsphere.infra.binder.context.statement.SQLStatementContext;
import org.apache.shardingsphere.infra.checker.SupportedSQLCheckEngine;
import org.apache.shardingsphere.infra.config.props.ConfigurationProperties;
import org.apache.shardingsphere.infra.config.props.ConfigurationPropertyKey;
+import org.apache.shardingsphere.infra.exception.generic.UnsupportedSQLOperationException;
import org.apache.shardingsphere.infra.executor.sql.context.ExecutionContext;
import org.apache.shardingsphere.infra.executor.sql.log.SQLLogger;
import org.apache.shardingsphere.infra.hint.HintValueContext;
@@ -39,7 +40,13 @@ import org.apache.shardingsphere.infra.session.query.QueryContext;
import org.apache.shardingsphere.infra.spi.type.typed.TypedSPILoader;
import org.apache.shardingsphere.infra.util.props.PropertiesBuilder;
import org.apache.shardingsphere.infra.util.props.PropertiesBuilder.Property;
+import org.apache.shardingsphere.sql.parser.statement.core.segment.generic.table.SimpleTableSegment;
+import org.apache.shardingsphere.sql.parser.statement.core.segment.generic.table.TableNameSegment;
+import org.apache.shardingsphere.sql.parser.statement.core.statement.SQLStatement;
+import org.apache.shardingsphere.sql.parser.statement.core.statement.type.ddl.table.CreateTableStatement;
+import org.apache.shardingsphere.sql.parser.statement.core.statement.type.ddl.table.DropTableStatement;
import org.apache.shardingsphere.sql.parser.statement.core.statement.type.dml.SelectStatement;
+import org.apache.shardingsphere.sql.parser.statement.core.value.identifier.IdentifierValue;
import org.apache.shardingsphere.sqltranslator.context.SQLTranslatorContext;
import org.apache.shardingsphere.sqltranslator.rule.SQLTranslatorRule;
import org.junit.jupiter.api.Test;
@@ -52,8 +59,9 @@ import java.util.Collections;
import java.util.Optional;
import java.util.Properties;
-import static org.hamcrest.Matchers.is;
import static org.hamcrest.MatcherAssert.assertThat;
+import static org.hamcrest.Matchers.is;
+import static org.junit.jupiter.api.Assertions.assertThrows;
import static org.junit.jupiter.api.Assertions.assertTrue;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.Mockito.RETURNS_DEEP_STUBS;
@@ -96,6 +104,33 @@ class KernelProcessorTest {
}
}
+ @Test
+ void assertGenerateExecutionContextWithTemporaryCreateTable() {
+ QueryContext queryContext = createQueryContext(createTemporaryCreateTableStatement(databaseType), false, databaseType);
+ assertThrows(UnsupportedSQLOperationException.class,
+ () -> new KernelProcessor().generateExecutionContext(queryContext, new RuleMetaData(Arrays.asList(mockSQLTranslatorRule(), mockAggregatedDataSourceRule())), createProps(false)));
+ }
+
+ @Test
+ void assertGenerateExecutionContextWithTemporaryDropTable() {
+ QueryContext queryContext = createQueryContext(createTemporaryDropTableStatement(databaseType), false, databaseType);
+ assertThrows(UnsupportedSQLOperationException.class,
+ () -> new KernelProcessor().generateExecutionContext(queryContext, new RuleMetaData(Arrays.asList(mockSQLTranslatorRule(), mockAggregatedDataSourceRule())), createProps(false)));
+ }
+
+ @Test
+ void assertGenerateExecutionContextWithTemporaryCreateTableWhenSkipMetadataValidate() {
+ QueryContext queryContext = createQueryContext(createTemporaryCreateTableStatement(databaseType), true, databaseType);
+ try (
+ MockedConstruction<SupportedSQLCheckEngine> mockedCheckEngines = mockConstruction(SupportedSQLCheckEngine.class);
+ MockedStatic<SQLLogger> mockedSQLLogger = mockStatic(SQLLogger.class)) {
+ assertThrows(UnsupportedSQLOperationException.class,
+ () -> new KernelProcessor().generateExecutionContext(queryContext, new RuleMetaData(Arrays.asList(mockSQLTranslatorRule(), mockAggregatedDataSourceRule())), createProps(false)));
+ assertTrue(mockedCheckEngines.constructed().isEmpty());
+ mockedSQLLogger.verifyNoInteractions();
+ }
+ }
+
private SQLTranslatorRule mockSQLTranslatorRule() {
SQLTranslatorRule result = mock(SQLTranslatorRule.class);
when(result.getAttributes()).thenReturn(new RuleAttributes());
@@ -112,6 +147,10 @@ class KernelProcessorTest {
}
private QueryContext createQueryContext(final boolean skipMetadataValidate) {
+ return createQueryContext(SelectStatement.builder().databaseType(databaseType).build(), skipMetadataValidate, databaseType);
+ }
+
+ private QueryContext createQueryContext(final SQLStatement sqlStatement, final boolean skipMetadataValidate, final DatabaseType databaseType) {
HintValueContext hintValueContext = new HintValueContext();
hintValueContext.setSkipMetadataValidate(skipMetadataValidate);
ConnectionContext connectionContext = mock(ConnectionContext.class);
@@ -125,11 +164,24 @@ class KernelProcessorTest {
new ConfigurationProperties(new Properties()));
when(metaData.getDatabase("foo_db")).thenReturn(database);
when(metaData.getProps()).thenReturn(new ConfigurationProperties(new Properties()));
- SQLStatementContext sqlStatementContext = new CommonSQLStatementContext(SelectStatement.builder().databaseType(databaseType).build());
+ SQLStatementContext sqlStatementContext = new CommonSQLStatementContext(sqlStatement);
return new QueryContext(sqlStatementContext, "SELECT * FROM tbl", Collections.emptyList(), hintValueContext, connectionContext, metaData);
}
private ConfigurationProperties createProps(final boolean sqlShow) {
return new ConfigurationProperties(PropertiesBuilder.build(new Property(ConfigurationPropertyKey.SQL_SHOW.getKey(), Boolean.toString(sqlShow))));
}
+
+ private CreateTableStatement createTemporaryCreateTableStatement(final DatabaseType databaseType) {
+ return CreateTableStatement.builder()
+ .databaseType(databaseType)
+ .table(new SimpleTableSegment(new TableNameSegment(0, 0, new IdentifierValue("t_order"))))
+ .temporary(true)
+ .build();
+ }
+
+ private DropTableStatement createTemporaryDropTableStatement(final DatabaseType databaseType) {
+ return new DropTableStatement(databaseType,
+ Collections.singletonList(new SimpleTableSegment(new TableNameSegment(0, 0, new IdentifierValue("t_order")))), false, true, false);
+ }
}
diff --git a/parser/sql/engine/dialect/doris/src/main/java/org/apache/shardingsphere/sql/parser/engine/doris/visitor/statement/type/DorisDDLStatementVisitor.java b/parser/sql/engine/dialect/doris/src/main/java/org/apache/shardingsphere/sql/parser/engine/doris/visitor/statement/type/DorisDDLStatementVisitor.java
index 9f423726a0b..6d44e2a89c5 100644
--- a/parser/sql/engine/dialect/doris/src/main/java/org/apache/shardingsphere/sql/parser/engine/doris/visitor/statement/type/DorisDDLStatementVisitor.java
+++ b/parser/sql/engine/dialect/doris/src/main/java/org/apache/shardingsphere/sql/parser/engine/doris/visitor/statement/type/DorisDDLStatementVisitor.java
@@ -634,6 +634,7 @@ public final class DorisDDLStatementVisitor extends DorisStatementVisitor implem
.databaseType(getDatabaseType())
.table((SimpleTableSegment) visit(ctx.tableName()))
.ifNotExists(null != ctx.ifNotExists())
+ .temporary(null != ctx.TEMPORARY())
.likeTable(likeTable)
.createTableOption(createTableOption)
.selectStatement(selectStatement)
@@ -1244,7 +1245,8 @@ public final class DorisDDLStatementVisitor extends DorisStatementVisitor implem
@SuppressWarnings("unchecked")
@Override
public ASTNode visitDropTable(final DropTableContext ctx) {
- return new DropTableStatement(getDatabaseType(), ((CollectionValue<SimpleTableSegment>) visit(ctx.tableList())).getValue(), null != ctx.ifExists(), false);
+ return new DropTableStatement(getDatabaseType(), ((CollectionValue<SimpleTableSegment>) visit(ctx.tableList())).getValue(),
+ null != ctx.ifExists(), null != ctx.TEMPORARY(), false);
}
@Override
diff --git a/parser/sql/engine/dialect/doris/src/test/java/org/apache/shardingsphere/sql/parser/engine/doris/visitor/statement/type/DorisStatementVisitorTest.java b/parser/sql/engine/dialect/doris/src/test/java/org/apache/shardingsphere/sql/parser/engine/doris/visitor/statement/type/DorisStatementVisitorTest.java
new file mode 100644
index 00000000000..13b8722e5f6
--- /dev/null
+++ b/parser/sql/engine/dialect/doris/src/test/java/org/apache/shardingsphere/sql/parser/engine/doris/visitor/statement/type/DorisStatementVisitorTest.java
@@ -0,0 +1,61 @@
+/*
+ * 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.engine.doris.visitor.statement.type;
+
+import org.apache.shardingsphere.sql.parser.engine.api.CacheOption;
+import org.apache.shardingsphere.sql.parser.engine.api.SQLParserEngine;
+import org.apache.shardingsphere.sql.parser.engine.api.SQLStatementVisitorEngine;
+import org.apache.shardingsphere.sql.parser.statement.core.statement.type.ddl.table.CreateTableStatement;
+import org.apache.shardingsphere.sql.parser.statement.core.statement.type.ddl.table.DropTableStatement;
+import org.junit.jupiter.api.Test;
+
+import static org.junit.jupiter.api.Assertions.assertFalse;
+import static org.junit.jupiter.api.Assertions.assertTrue;
+
+class DorisStatementVisitorTest {
+
+ private static final CacheOption CACHE_OPTION = new CacheOption(128, 1024L);
+
+ @Test
+ void assertVisitCreateTemporaryTable() {
+ CreateTableStatement statement = (CreateTableStatement) parse("CREATE TEMPORARY TABLE t_order (order_id INT)");
+ assertTrue(statement.isTemporary());
+ }
+
+ @Test
+ void assertVisitCreateTableWithoutTemporary() {
+ CreateTableStatement statement = (CreateTableStatement) parse("CREATE TABLE t_order (order_id INT)");
+ assertFalse(statement.isTemporary());
+ }
+
+ @Test
+ void assertVisitDropTemporaryTable() {
+ DropTableStatement statement = (DropTableStatement) parse("DROP TEMPORARY TABLE t_order");
+ assertTrue(statement.isTemporary());
+ }
+
+ @Test
+ void assertVisitDropTableWithoutTemporary() {
+ DropTableStatement statement = (DropTableStatement) parse("DROP TABLE t_order");
+ assertFalse(statement.isTemporary());
+ }
+
+ private Object parse(final String sql) {
+ return new SQLStatementVisitorEngine("Doris").visit(new SQLParserEngine("Doris", CACHE_OPTION).parse(sql, false));
+ }
+}
diff --git a/parser/sql/engine/dialect/mysql/src/main/java/org/apache/shardingsphere/sql/parser/engine/mysql/visitor/statement/type/MySQLDDLStatementVisitor.java b/parser/sql/engine/dialect/mysql/src/main/java/org/apache/shardingsphere/sql/parser/engine/mysql/visitor/statement/type/MySQLDDLStatementVisitor.java
index ac53a195284..c62e4c9aaa2 100644
--- a/parser/sql/engine/dialect/mysql/src/main/java/org/apache/shardingsphere/sql/parser/engine/mysql/visitor/statement/type/MySQLDDLStatementVisitor.java
+++ b/parser/sql/engine/dialect/mysql/src/main/java/org/apache/shardingsphere/sql/parser/engine/mysql/visitor/statement/type/MySQLDDLStatementVisitor.java
@@ -284,6 +284,7 @@ public final class MySQLDDLStatementVisitor extends MySQLStatementVisitor implem
.databaseType(getDatabaseType())
.table((SimpleTableSegment) visit(ctx.tableName()))
.ifNotExists(null != ctx.ifNotExists())
+ .temporary(null != ctx.TEMPORARY())
.likeTable(null == ctx.createLikeClause() ? null : (SimpleTableSegment) visit(ctx.createLikeClause()))
.createTableOption(null == ctx.createTableOptions() ? null : (CreateTableOptionSegment) visit(ctx.createTableOptions()))
.columnDefinitions(columnDefinitions)
@@ -690,7 +691,7 @@ public final class MySQLDDLStatementVisitor extends MySQLStatementVisitor implem
@SuppressWarnings("unchecked")
@Override
public ASTNode visitDropTable(final DropTableContext ctx) {
- return new DropTableStatement(getDatabaseType(), ((CollectionValue<SimpleTableSegment>) visit(ctx.tableList())).getValue(), null != ctx.ifExists(), false);
+ return new DropTableStatement(getDatabaseType(), ((CollectionValue<SimpleTableSegment>) visit(ctx.tableList())).getValue(), null != ctx.ifExists(), null != ctx.TEMPORARY(), false);
}
@Override
diff --git a/parser/sql/engine/dialect/mysql/src/test/java/org/apache/shardingsphere/sql/parser/engine/mysql/visitor/statement/MySQLStatementVisitorTest.java b/parser/sql/engine/dialect/mysql/src/test/java/org/apache/shardingsphere/sql/parser/engine/mysql/visitor/statement/MySQLStatementVisitorTest.java
new file mode 100644
index 00000000000..1f283acf35e
--- /dev/null
+++ b/parser/sql/engine/dialect/mysql/src/test/java/org/apache/shardingsphere/sql/parser/engine/mysql/visitor/statement/MySQLStatementVisitorTest.java
@@ -0,0 +1,63 @@
+/*
+ * 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.engine.mysql.visitor.statement;
+
+import org.apache.shardingsphere.sql.parser.engine.api.CacheOption;
+import org.apache.shardingsphere.sql.parser.engine.api.SQLParserEngine;
+import org.apache.shardingsphere.sql.parser.engine.api.SQLStatementVisitorEngine;
+import org.apache.shardingsphere.sql.parser.engine.core.ParseASTNode;
+import org.apache.shardingsphere.sql.parser.statement.core.statement.type.ddl.table.CreateTableStatement;
+import org.apache.shardingsphere.sql.parser.statement.core.statement.type.ddl.table.DropTableStatement;
+import org.junit.jupiter.api.Test;
+
+import static org.junit.jupiter.api.Assertions.assertFalse;
+import static org.junit.jupiter.api.Assertions.assertTrue;
+
+class MySQLStatementVisitorTest {
+
+ private static final CacheOption CACHE_OPTION = new CacheOption(128, 1024L);
+
+ @Test
+ void assertVisitCreateTemporaryTable() {
+ CreateTableStatement statement = (CreateTableStatement) parse("CREATE TEMPORARY TABLE t_order (order_id INT)");
+ assertTrue(statement.isTemporary());
+ }
+
+ @Test
+ void assertVisitCreateTableWithoutTemporary() {
+ CreateTableStatement statement = (CreateTableStatement) parse("CREATE TABLE t_order (order_id INT)");
+ assertFalse(statement.isTemporary());
+ }
+
+ @Test
+ void assertVisitDropTemporaryTable() {
+ DropTableStatement statement = (DropTableStatement) parse("DROP TEMPORARY TABLE t_order");
+ assertTrue(statement.isTemporary());
+ }
+
+ @Test
+ void assertVisitDropTableWithoutTemporary() {
+ DropTableStatement statement = (DropTableStatement) parse("DROP TABLE t_order");
+ assertFalse(statement.isTemporary());
+ }
+
+ private Object parse(final String sql) {
+ ParseASTNode parseASTNode = new SQLParserEngine("MySQL", CACHE_OPTION).parse(sql, false);
+ return new SQLStatementVisitorEngine("MySQL").visit(parseASTNode);
+ }
+}
diff --git a/parser/sql/statement/core/src/main/java/org/apache/shardingsphere/sql/parser/statement/core/statement/type/ddl/table/CreateTableStatement.java b/parser/sql/statement/core/src/main/java/org/apache/shardingsphere/sql/parser/statement/core/statement/type/ddl/table/CreateTableStatement.java
index fa7f23d141a..b7ea52cf946 100644
--- a/parser/sql/statement/core/src/main/java/org/apache/shardingsphere/sql/parser/statement/core/statement/type/ddl/table/CreateTableStatement.java
+++ b/parser/sql/statement/core/src/main/java/org/apache/shardingsphere/sql/parser/statement/core/statement/type/ddl/table/CreateTableStatement.java
@@ -54,6 +54,8 @@ public final class CreateTableStatement extends DDLStatement {
private final boolean ifNotExists;
+ private final boolean temporary;
+
private final SimpleTableSegment likeTable;
private final CreateTableOptionSegment createTableOption;
@@ -70,13 +72,14 @@ public final class CreateTableStatement extends DDLStatement {
@Builder
private CreateTableStatement(final DatabaseType databaseType, final SimpleTableSegment table, final SelectStatement selectStatement,
- final boolean ifNotExists, final SimpleTableSegment likeTable, final CreateTableOptionSegment createTableOption,
+ final boolean ifNotExists, final boolean temporary, final SimpleTableSegment likeTable, final CreateTableOptionSegment createTableOption,
final Collection<ColumnDefinitionSegment> columnDefinitions, final Collection<ConstraintDefinitionSegment> constraintDefinitions,
final List<ColumnSegment> columns, final Collection<RollupSegment> rollups) {
super(databaseType);
this.table = table;
this.selectStatement = selectStatement;
this.ifNotExists = ifNotExists;
+ this.temporary = temporary;
this.likeTable = likeTable;
this.createTableOption = createTableOption;
this.columnDefinitions = null == columnDefinitions ? Collections.emptyList() : columnDefinitions;
diff --git a/parser/sql/statement/core/src/main/java/org/apache/shardingsphere/sql/parser/statement/core/statement/type/ddl/table/DropTableStatement.java b/parser/sql/statement/core/src/main/java/org/apache/shardingsphere/sql/parser/statement/core/statement/type/ddl/table/DropTableStatement.java
index b4cfd2e03d9..3b971a77359 100644
--- a/parser/sql/statement/core/src/main/java/org/apache/shardingsphere/sql/parser/statement/core/statement/type/ddl/table/DropTableStatement.java
+++ b/parser/sql/statement/core/src/main/java/org/apache/shardingsphere/sql/parser/statement/core/statement/type/ddl/table/DropTableStatement.java
@@ -36,14 +36,21 @@ public final class DropTableStatement extends DDLStatement {
private final boolean ifExists;
+ private final boolean temporary;
+
private final boolean containsCascade;
private final SQLStatementAttributes attributes;
public DropTableStatement(final DatabaseType databaseType, final Collection<SimpleTableSegment> tables, final boolean ifExists, final boolean containsCascade) {
+ this(databaseType, tables, ifExists, false, containsCascade);
+ }
+
+ public DropTableStatement(final DatabaseType databaseType, final Collection<SimpleTableSegment> tables, final boolean ifExists, final boolean temporary, final boolean containsCascade) {
super(databaseType);
this.tables = tables;
this.ifExists = ifExists;
+ this.temporary = temporary;
this.containsCascade = containsCascade;
attributes = new SQLStatementAttributes(new TableSQLStatementAttribute(tables));
}
diff --git a/proxy/backend/core/src/test/java/org/apache/shardingsphere/proxy/backend/connector/StandardDatabaseProxyConnectorTest.java b/proxy/backend/core/src/test/java/org/apache/shardingsphere/proxy/backend/connector/StandardDatabaseProxyConnectorTest.java
index c1151dd71eb..e181e2a2fe8 100644
--- a/proxy/backend/core/src/test/java/org/apache/shardingsphere/proxy/backend/connector/StandardDatabaseProxyConnectorTest.java
+++ b/proxy/backend/core/src/test/java/org/apache/shardingsphere/proxy/backend/connector/StandardDatabaseProxyConnectorTest.java
@@ -33,6 +33,7 @@ import org.apache.shardingsphere.infra.binder.context.statement.type.dml.InsertS
import org.apache.shardingsphere.infra.binder.context.statement.type.dml.SelectStatementContext;
import org.apache.shardingsphere.infra.config.props.ConfigurationProperties;
import org.apache.shardingsphere.infra.connection.kernel.KernelProcessor;
+import org.apache.shardingsphere.infra.exception.generic.UnsupportedSQLOperationException;
import org.apache.shardingsphere.infra.exception.kernel.metadata.resource.storageunit.EmptyStorageUnitException;
import org.apache.shardingsphere.infra.exception.kernel.metadata.rule.EmptyRuleException;
import org.apache.shardingsphere.infra.executor.sql.context.ExecutionContext;
@@ -75,9 +76,12 @@ import org.apache.shardingsphere.proxy.backend.response.header.update.UpdateResp
import org.apache.shardingsphere.sharding.rule.ShardingRule;
import org.apache.shardingsphere.sql.parser.engine.api.CacheOption;
import org.apache.shardingsphere.sql.parser.statement.core.segment.ddl.cursor.CursorNameSegment;
+import org.apache.shardingsphere.sql.parser.statement.core.segment.generic.table.SimpleTableSegment;
+import org.apache.shardingsphere.sql.parser.statement.core.segment.generic.table.TableNameSegment;
import org.apache.shardingsphere.sql.parser.statement.core.statement.SQLStatement;
import org.apache.shardingsphere.sql.parser.statement.core.statement.type.ddl.CloseStatement;
import org.apache.shardingsphere.sql.parser.statement.core.statement.type.ddl.CursorStatement;
+import org.apache.shardingsphere.sql.parser.statement.core.statement.type.ddl.table.CreateTableStatement;
import org.apache.shardingsphere.sql.parser.statement.core.statement.type.dml.InsertStatement;
import org.apache.shardingsphere.sql.parser.statement.core.statement.type.dml.SelectStatement;
import org.apache.shardingsphere.sql.parser.statement.core.value.identifier.IdentifierValue;
@@ -305,6 +309,25 @@ class StandardDatabaseProxyConnectorTest {
}
}
+ @Test
+ void assertExecuteWithUnsupportedTemporaryTableDDL() {
+ SQLStatementContext sqlStatementContext = createSQLStatementContext(CreateTableStatement.builder()
+ .databaseType(TypedSPILoader.getService(DatabaseType.class, "MySQL"))
+ .table(new SimpleTableSegment(new TableNameSegment(0, 0, new IdentifierValue("t_order"))))
+ .temporary(true)
+ .build());
+ DatabaseProxyConnector engine = createDatabaseProxyConnector(JDBCDriverType.STATEMENT, createQueryContext(sqlStatementContext, mockDatabase()));
+ try (
+ MockedConstruction<KernelProcessor> mockedKernelProcessor = mockConstruction(KernelProcessor.class,
+ (mock, context) -> when(mock.generateExecutionContext(any(QueryContext.class), any(RuleMetaData.class), any(ConfigurationProperties.class)))
+ .thenThrow(new UnsupportedSQLOperationException("CREATE TEMPORARY TABLE")));
+ MockedConstruction<PushDownMetaDataRefreshEngine> mockedPushDownMetaDataRefreshEngine = mockConstruction(PushDownMetaDataRefreshEngine.class)) {
+ assertThrows(UnsupportedSQLOperationException.class, engine::execute);
+ assertThat(mockedKernelProcessor.constructed().size(), is(1));
+ assertTrue(mockedPushDownMetaDataRefreshEngine.constructed().isEmpty());
+ }
+ }
+
@Test
void assertConstructWithSystemSchema() {
ShardingSphereDatabase database = mock(ShardingSphereDatabase.class, RETURNS_DEEP_STUBS);