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);