This is an automated email from the ASF dual-hosted git repository.

jianglongtao pushed a commit to branch fix-33341
in repository https://gitbox.apache.org/repos/asf/shardingsphere.git

commit aa2cf5604cbdb41288a1c704bab1bf82ad642fa1
Author: Raigor <[email protected]>
AuthorDate: Wed Sep 4 21:39:29 2024 +0800

    Pick #32595, #32763, fix the generated key column name case insensitivity 
error (#8)
    
    * Pick #32595, #32763, fix the generated key column name case insensitivity 
error
    
    * Improve DML E2E to support destroy-sql
    
    * Optimize code style
---
 .../keygen/engine/GeneratedKeyContextEngine.java   | 27 ++++-----
 .../statement/dml/InsertStatementContext.java      | 21 ++++++-
 .../engine/GeneratedKeyContextEngineTest.java      |  9 +--
 .../schema/model/ShardingSphereSchema.java         | 10 ++++
 .../database/schema/model/ShardingSphereTable.java | 37 ++++++------
 .../e2e/cases/assertion/IntegrationTestCase.java   |  3 +
 .../e2e/engine/type/dml/AdditionalDMLE2EIT.java    |  4 +-
 .../test/e2e/engine/type/dml/BaseDMLE2EIT.java     | 68 ++++++++++++++++++++--
 .../test/e2e/engine/type/dml/BatchDMLE2EIT.java    |  5 ++
 .../test/e2e/engine/type/dml/GeneralDMLE2EIT.java  | 30 +++++++---
 .../db/insert_single_with_generate_key_column.xml  | 24 ++++++++
 .../resources/cases/dml/dml-integration-insert.xml | 24 ++++++++
 .../data/actual/init-sql/mysql/01-actual-init.sql  |  1 +
 13 files changed, 215 insertions(+), 48 deletions(-)

diff --git 
a/infra/binder/src/main/java/org/apache/shardingsphere/infra/binder/context/segment/insert/keygen/engine/GeneratedKeyContextEngine.java
 
b/infra/binder/src/main/java/org/apache/shardingsphere/infra/binder/context/segment/insert/keygen/engine/GeneratedKeyContextEngine.java
index 9d801f98ea8..0604b39e6b7 100644
--- 
a/infra/binder/src/main/java/org/apache/shardingsphere/infra/binder/context/segment/insert/keygen/engine/GeneratedKeyContextEngine.java
+++ 
b/infra/binder/src/main/java/org/apache/shardingsphere/infra/binder/context/segment/insert/keygen/engine/GeneratedKeyContextEngine.java
@@ -17,7 +17,6 @@
 
 package 
org.apache.shardingsphere.infra.binder.context.segment.insert.keygen.engine;
 
-import com.cedarsoftware.util.CaseInsensitiveSet;
 import lombok.RequiredArgsConstructor;
 import 
org.apache.shardingsphere.infra.binder.context.segment.insert.keygen.GeneratedKeyContext;
 import 
org.apache.shardingsphere.infra.binder.context.segment.insert.values.InsertValueContext;
@@ -31,6 +30,7 @@ import 
org.apache.shardingsphere.sql.parser.sql.common.statement.dml.InsertState
 import 
org.apache.shardingsphere.sql.parser.sql.dialect.handler.dml.InsertStatementHandler;
 
 import java.util.List;
+import java.util.Map;
 import java.util.Optional;
 
 /**
@@ -46,15 +46,16 @@ public final class GeneratedKeyContextEngine {
     /**
      * Create generate key context.
      *
-     * @param insertColumnNames insert column names
+     * @param insertColumnNamesAndIndexes insert column names and indexes
      * @param insertValueContexts insert value contexts
      * @param params SQL parameters
      * @return generate key context
      */
-    public Optional<GeneratedKeyContext> createGenerateKeyContext(final 
List<String> insertColumnNames, final List<InsertValueContext> 
insertValueContexts, final List<Object> params) {
+    public Optional<GeneratedKeyContext> createGenerateKeyContext(final 
Map<String, Integer> insertColumnNamesAndIndexes, final 
List<InsertValueContext> insertValueContexts,
+                                                                  final 
List<Object> params) {
         String tableName = 
Optional.ofNullable(insertStatement.getTable()).map(optional -> 
optional.getTableName().getIdentifier().getValue()).orElse("");
-        return findGenerateKeyColumn(tableName).map(optional -> 
containsGenerateKey(insertColumnNames, optional)
-                ? findGeneratedKey(insertColumnNames, insertValueContexts, 
params, optional)
+        return findGenerateKeyColumn(tableName).map(optional -> 
containsGenerateKey(insertColumnNamesAndIndexes, optional)
+                ? findGeneratedKey(insertColumnNamesAndIndexes, 
insertValueContexts, params, optional)
                 : new GeneratedKeyContext(optional, true));
     }
     
@@ -70,9 +71,9 @@ public final class GeneratedKeyContextEngine {
         return Optional.empty();
     }
     
-    private boolean containsGenerateKey(final List<String> insertColumnNames, 
final String generateKeyColumnName) {
-        return insertColumnNames.isEmpty() ? 
schema.getVisibleColumnNames(insertStatement.getTable().getTableName().getIdentifier().getValue()).size()
 == getValueCountForPerGroup()
-                : new 
CaseInsensitiveSet<>(insertColumnNames).contains(generateKeyColumnName);
+    private boolean containsGenerateKey(final Map<String, Integer> 
insertColumnNamesAndIndexes, final String generateKeyColumnName) {
+        return insertColumnNamesAndIndexes.isEmpty() ? 
schema.getVisibleColumnNames(insertStatement.getTable().getTableName().getIdentifier().getValue()).size()
 == getValueCountForPerGroup()
+                : 
insertColumnNamesAndIndexes.containsKey(generateKeyColumnName);
     }
     
     private int getValueCountForPerGroup() {
@@ -89,11 +90,11 @@ public final class GeneratedKeyContextEngine {
         return 0;
     }
     
-    private GeneratedKeyContext findGeneratedKey(final List<String> 
insertColumnNames, final List<InsertValueContext> insertValueContexts,
+    private GeneratedKeyContext findGeneratedKey(final Map<String, Integer> 
insertColumnNamesAndIndexes, final List<InsertValueContext> insertValueContexts,
                                                  final List<Object> params, 
final String generateKeyColumnName) {
         GeneratedKeyContext result = new 
GeneratedKeyContext(generateKeyColumnName, false);
         for (InsertValueContext each : insertValueContexts) {
-            ExpressionSegment expression = 
each.getValueExpressions().get(findGenerateKeyIndex(insertColumnNames, 
generateKeyColumnName.toLowerCase()));
+            ExpressionSegment expression = 
each.getValueExpressions().get(findGenerateKeyIndex(insertColumnNamesAndIndexes,
 generateKeyColumnName));
             if (expression instanceof ParameterMarkerExpressionSegment) {
                 if (params.isEmpty()) {
                     continue;
@@ -108,8 +109,8 @@ public final class GeneratedKeyContextEngine {
         return result;
     }
     
-    private int findGenerateKeyIndex(final List<String> insertColumnNames, 
final String generateKeyColumnName) {
-        return insertColumnNames.isEmpty() ? 
schema.getVisibleColumnNames(insertStatement.getTable().getTableName().getIdentifier().getValue()).indexOf(generateKeyColumnName)
-                : insertColumnNames.indexOf(generateKeyColumnName);
+    private int findGenerateKeyIndex(final Map<String, Integer> 
insertColumnNamesAndIndexes, final String generateKeyColumnName) {
+        return insertColumnNamesAndIndexes.isEmpty() ? 
schema.getVisibleColumnNamesAndIndexes(insertStatement.getTable().getTableName().getIdentifier().getValue()).get(generateKeyColumnName)
+                : insertColumnNamesAndIndexes.get(generateKeyColumnName);
     }
 }
diff --git 
a/infra/binder/src/main/java/org/apache/shardingsphere/infra/binder/context/statement/dml/InsertStatementContext.java
 
b/infra/binder/src/main/java/org/apache/shardingsphere/infra/binder/context/statement/dml/InsertStatementContext.java
index 6e0227be195..b27a0f27aaf 100644
--- 
a/infra/binder/src/main/java/org/apache/shardingsphere/infra/binder/context/statement/dml/InsertStatementContext.java
+++ 
b/infra/binder/src/main/java/org/apache/shardingsphere/infra/binder/context/statement/dml/InsertStatementContext.java
@@ -17,6 +17,7 @@
 
 package org.apache.shardingsphere.infra.binder.context.statement.dml;
 
+import com.cedarsoftware.util.CaseInsensitiveMap;
 import lombok.Getter;
 import org.apache.shardingsphere.infra.binder.context.aware.ParameterAware;
 import 
org.apache.shardingsphere.infra.binder.context.segment.insert.keygen.GeneratedKeyContext;
@@ -53,6 +54,7 @@ import java.util.Collections;
 import java.util.Iterator;
 import java.util.LinkedList;
 import java.util.List;
+import java.util.Map;
 import java.util.Optional;
 import java.util.concurrent.atomic.AtomicInteger;
 
@@ -72,6 +74,8 @@ public final class InsertStatementContext extends 
CommonSQLStatementContext impl
     
     private final List<String> insertColumnNames;
     
+    private final Map<String, Integer> insertColumnNamesAndIndexes;
+    
     private final List<List<ExpressionSegment>> valueExpressions;
     
     private List<InsertValueContext> insertValueContexts;
@@ -96,7 +100,20 @@ public final class InsertStatementContext extends 
CommonSQLStatementContext impl
         ShardingSphereSchema schema = getSchema(metaData, defaultDatabaseName);
         columnNames = containsInsertColumns() ? insertColumnNames
                 : Optional.ofNullable(sqlStatement.getTable()).map(optional -> 
schema.getVisibleColumnNames(optional.getTableName().getIdentifier().getValue())).orElseGet(Collections::emptyList);
-        generatedKeyContext = new GeneratedKeyContextEngine(sqlStatement, 
schema).createGenerateKeyContext(insertColumnNames, insertValueContexts, 
params).orElse(null);
+        insertColumnNamesAndIndexes = 
createInsertColumnNamesAndIndexes(insertColumnNames);
+        generatedKeyContext = new GeneratedKeyContextEngine(sqlStatement, 
schema).createGenerateKeyContext(insertColumnNamesAndIndexes, 
insertValueContexts, params).orElse(null);
+    }
+    
+    private Map<String, Integer> createInsertColumnNamesAndIndexes(final 
List<String> insertColumnNames) {
+        if (containsInsertColumns()) {
+            Map<String, Integer> result = new 
CaseInsensitiveMap<>(insertColumnNames.size(), 1F);
+            int index = 0;
+            for (String each : insertColumnNames) {
+                result.put(each, index++);
+            }
+            return result;
+        }
+        return Collections.emptyMap();
     }
     
     private ShardingSphereSchema getSchema(final ShardingSphereMetaData 
metaData, final String defaultDatabaseName) {
@@ -276,6 +293,6 @@ public final class InsertStatementContext extends 
CommonSQLStatementContext impl
         insertSelectContext = getInsertSelectContext(metaData, params, 
parametersOffset, defaultDatabaseName).orElse(null);
         onDuplicateKeyUpdateValueContext = 
getOnDuplicateKeyUpdateValueContext(params, parametersOffset).orElse(null);
         ShardingSphereSchema schema = getSchema(metaData, defaultDatabaseName);
-        generatedKeyContext = new GeneratedKeyContextEngine(getSqlStatement(), 
schema).createGenerateKeyContext(insertColumnNames, insertValueContexts, 
params).orElse(null);
+        generatedKeyContext = new GeneratedKeyContextEngine(getSqlStatement(), 
schema).createGenerateKeyContext(insertColumnNamesAndIndexes, 
insertValueContexts, params).orElse(null);
     }
 }
diff --git 
a/infra/binder/src/test/java/org/apache/shardingsphere/infra/binder/context/segment/insert/keygen/engine/GeneratedKeyContextEngineTest.java
 
b/infra/binder/src/test/java/org/apache/shardingsphere/infra/binder/context/segment/insert/keygen/engine/GeneratedKeyContextEngineTest.java
index 467b57276de..ac20e87f9ba 100644
--- 
a/infra/binder/src/test/java/org/apache/shardingsphere/infra/binder/context/segment/insert/keygen/engine/GeneratedKeyContextEngineTest.java
+++ 
b/infra/binder/src/test/java/org/apache/shardingsphere/infra/binder/context/segment/insert/keygen/engine/GeneratedKeyContextEngineTest.java
@@ -17,6 +17,7 @@
 
 package 
org.apache.shardingsphere.infra.binder.context.segment.insert.keygen.engine;
 
+import com.cedarsoftware.util.CaseInsensitiveMap;
 import com.google.common.collect.ImmutableMap;
 import 
org.apache.shardingsphere.infra.binder.context.segment.insert.keygen.GeneratedKeyContext;
 import 
org.apache.shardingsphere.infra.binder.context.segment.insert.values.InsertValueContext;
@@ -95,7 +96,7 @@ class GeneratedKeyContextEngineTest {
     private void 
assertCreateGenerateKeyContextWithoutGenerateKeyColumnConfiguration(final 
InsertStatement insertStatement) {
         insertStatement.setTable(new SimpleTableSegment(new 
TableNameSegment(0, 0, new IdentifierValue("tbl1"))));
         insertStatement.setInsertColumns(new InsertColumnsSegment(0, 0, 
Collections.singletonList(new ColumnSegment(0, 0, new IdentifierValue("id")))));
-        assertFalse(new GeneratedKeyContextEngine(insertStatement, 
schema).createGenerateKeyContext(Collections.emptyList(),
+        assertFalse(new GeneratedKeyContextEngine(insertStatement, 
schema).createGenerateKeyContext(Collections.emptyMap(),
                 Collections.emptyList(), 
Collections.singletonList(1)).isPresent());
     }
     
@@ -140,7 +141,7 @@ class GeneratedKeyContextEngineTest {
         InsertValueContext insertValueContext = new 
InsertValueContext(expressionSegments, Collections.emptyList(), 0);
         insertStatement.getValues().add(new InsertValuesSegment(0, 0, 
expressionSegments));
         Optional<GeneratedKeyContext> actual = new 
GeneratedKeyContextEngine(insertStatement, schema)
-                .createGenerateKeyContext(Collections.singletonList("id"), 
Collections.singletonList(insertValueContext), Collections.singletonList(1));
+                .createGenerateKeyContext(new 
CaseInsensitiveMap<>(Collections.singletonMap("id", 0)), 
Collections.singletonList(insertValueContext), Collections.singletonList(1));
         assertTrue(actual.isPresent());
         assertThat(actual.get().getGeneratedValues().size(), is(1));
     }
@@ -180,13 +181,13 @@ class GeneratedKeyContextEngineTest {
         List<InsertValueContext> insertValueContexts = 
insertStatement.getValues().stream()
                 .map(each -> new InsertValueContext(each.getValues(), 
Collections.emptyList(), 0)).collect(Collectors.toList());
         Optional<GeneratedKeyContext> actual = new 
GeneratedKeyContextEngine(insertStatement, schema)
-                .createGenerateKeyContext(Collections.singletonList("id"), 
insertValueContexts, Collections.singletonList(1));
+                .createGenerateKeyContext(Collections.singletonMap("id", 0), 
insertValueContexts, Collections.singletonList(1));
         assertTrue(actual.isPresent());
         assertThat(actual.get().getGeneratedValues().size(), is(3));
         Iterator<Comparable<?>> generatedValuesIterator = 
actual.get().getGeneratedValues().iterator();
         assertThat(generatedValuesIterator.next(), is(1));
         assertThat(generatedValuesIterator.next(), is(100));
         assertThat(generatedValuesIterator.next(), is("value"));
-        assertTrue(new GeneratedKeyContextEngine(insertStatement, 
schema).createGenerateKeyContext(Collections.emptyList(), 
Collections.emptyList(), Collections.singletonList(1)).isPresent());
+        assertTrue(new GeneratedKeyContextEngine(insertStatement, 
schema).createGenerateKeyContext(Collections.emptyMap(), 
Collections.emptyList(), Collections.singletonList(1)).isPresent());
     }
 }
diff --git 
a/infra/common/src/main/java/org/apache/shardingsphere/infra/metadata/database/schema/model/ShardingSphereSchema.java
 
b/infra/common/src/main/java/org/apache/shardingsphere/infra/metadata/database/schema/model/ShardingSphereSchema.java
index 10bdac8ac12..7eeed72b903 100644
--- 
a/infra/common/src/main/java/org/apache/shardingsphere/infra/metadata/database/schema/model/ShardingSphereSchema.java
+++ 
b/infra/common/src/main/java/org/apache/shardingsphere/infra/metadata/database/schema/model/ShardingSphereSchema.java
@@ -197,4 +197,14 @@ public final class ShardingSphereSchema {
     public List<String> getVisibleColumnNames(final String tableName) {
         return containsTable(tableName) ? 
getTable(tableName).getVisibleColumns() : Collections.emptyList();
     }
+    
+    /**
+     * Get visible column names and indexes via table.
+     *
+     * @param tableName table name
+     * @return visible column names and indexes
+     */
+    public Map<String, Integer> getVisibleColumnNamesAndIndexes(final String 
tableName) {
+        return containsTable(tableName) ? 
getTable(tableName).getVisibleColumnsAndIndexes() : Collections.emptyMap();
+    }
 }
diff --git 
a/infra/common/src/main/java/org/apache/shardingsphere/infra/metadata/database/schema/model/ShardingSphereTable.java
 
b/infra/common/src/main/java/org/apache/shardingsphere/infra/metadata/database/schema/model/ShardingSphereTable.java
index a7e37fdac86..b87cf50b9c6 100644
--- 
a/infra/common/src/main/java/org/apache/shardingsphere/infra/metadata/database/schema/model/ShardingSphereTable.java
+++ 
b/infra/common/src/main/java/org/apache/shardingsphere/infra/metadata/database/schema/model/ShardingSphereTable.java
@@ -17,6 +17,7 @@
 
 package org.apache.shardingsphere.infra.metadata.database.schema.model;
 
+import com.cedarsoftware.util.CaseInsensitiveMap;
 import lombok.EqualsAndHashCode;
 import lombok.Getter;
 import lombok.ToString;
@@ -25,7 +26,6 @@ import 
org.apache.shardingsphere.infra.database.core.metadata.database.enums.Tab
 import java.util.ArrayList;
 import java.util.Collection;
 import java.util.Collections;
-import java.util.LinkedHashMap;
 import java.util.List;
 import java.util.Map;
 
@@ -49,6 +49,8 @@ public final class ShardingSphereTable {
     
     private final List<String> visibleColumns = new ArrayList<>();
     
+    private final Map<String, Integer> visibleColumnsAndIndexes = new 
CaseInsensitiveMap<>();
+    
     private final List<String> primaryKeyColumns = new ArrayList<>();
     
     private final TableType type;
@@ -63,7 +65,7 @@ public final class ShardingSphereTable {
         this.columns = createColumns(columns);
         this.indexes = createIndexes(indexes);
         this.constraints = createConstraints(constraints);
-        this.type = TableType.TABLE;
+        type = TableType.TABLE;
     }
     
     public ShardingSphereTable(final String name, final 
Collection<ShardingSphereColumn> columns,
@@ -76,33 +78,34 @@ public final class ShardingSphereTable {
     }
     
     private Map<String, ShardingSphereColumn> createColumns(final 
Collection<ShardingSphereColumn> columns) {
-        Map<String, ShardingSphereColumn> result = new 
LinkedHashMap<>(columns.size(), 1F);
+        Map<String, ShardingSphereColumn> result = new 
CaseInsensitiveMap<>(columns.size(), 1F);
+        int index = 0;
         for (ShardingSphereColumn each : columns) {
-            String lowerColumnName = each.getName().toLowerCase();
-            result.put(lowerColumnName, each);
+            result.put(each.getName(), each);
             columnNames.add(each.getName());
             if (each.isPrimaryKey()) {
-                primaryKeyColumns.add(lowerColumnName);
+                primaryKeyColumns.add(each.getName());
             }
             if (each.isVisible()) {
                 visibleColumns.add(each.getName());
+                visibleColumnsAndIndexes.put(each.getName(), index++);
             }
         }
         return result;
     }
     
     private Map<String, ShardingSphereIndex> createIndexes(final 
Collection<ShardingSphereIndex> indexes) {
-        Map<String, ShardingSphereIndex> result = new 
LinkedHashMap<>(indexes.size(), 1F);
+        Map<String, ShardingSphereIndex> result = new 
CaseInsensitiveMap<>(indexes.size(), 1F);
         for (ShardingSphereIndex each : indexes) {
-            result.put(each.getName().toLowerCase(), each);
+            result.put(each.getName(), each);
         }
         return result;
     }
     
     private Map<String, ShardingSphereConstraint> createConstraints(final 
Collection<ShardingSphereConstraint> constraints) {
-        Map<String, ShardingSphereConstraint> result = new 
LinkedHashMap<>(constraints.size(), 1F);
+        Map<String, ShardingSphereConstraint> result = new 
CaseInsensitiveMap<>(constraints.size(), 1F);
         for (ShardingSphereConstraint each : constraints) {
-            result.put(each.getName().toLowerCase(), each);
+            result.put(each.getName(), each);
         }
         return result;
     }
@@ -113,7 +116,7 @@ public final class ShardingSphereTable {
      * @param column column meta data
      */
     public void putColumn(final ShardingSphereColumn column) {
-        columns.put(column.getName().toLowerCase(), column);
+        columns.put(column.getName(), column);
     }
     
     /**
@@ -123,7 +126,7 @@ public final class ShardingSphereTable {
      * @return column meta data
      */
     public ShardingSphereColumn getColumn(final String columnName) {
-        return columns.get(columnName.toLowerCase());
+        return columns.get(columnName);
     }
     
     /**
@@ -142,7 +145,7 @@ public final class ShardingSphereTable {
      * @return whether contains column or not
      */
     public boolean containsColumn(final String columnName) {
-        return null != columnName && 
columns.containsKey(columnName.toLowerCase());
+        return null != columnName && columns.containsKey(columnName);
     }
     
     /**
@@ -151,7 +154,7 @@ public final class ShardingSphereTable {
      * @param index index meta data
      */
     public void putIndex(final ShardingSphereIndex index) {
-        indexes.put(index.getName().toLowerCase(), index);
+        indexes.put(index.getName(), index);
     }
     
     /**
@@ -160,7 +163,7 @@ public final class ShardingSphereTable {
      * @param indexName index name
      */
     public void removeIndex(final String indexName) {
-        indexes.remove(indexName.toLowerCase());
+        indexes.remove(indexName);
     }
     
     /**
@@ -170,7 +173,7 @@ public final class ShardingSphereTable {
      * @return index meta data
      */
     public ShardingSphereIndex getIndex(final String indexName) {
-        return indexes.get(indexName.toLowerCase());
+        return indexes.get(indexName);
     }
     
     /**
@@ -189,7 +192,7 @@ public final class ShardingSphereTable {
      * @return whether contains index or not
      */
     public boolean containsIndex(final String indexName) {
-        return null != indexName && 
indexes.containsKey(indexName.toLowerCase());
+        return null != indexName && indexes.containsKey(indexName);
     }
     
     /**
diff --git 
a/test/e2e/sql/src/test/java/org/apache/shardingsphere/test/e2e/cases/assertion/IntegrationTestCase.java
 
b/test/e2e/sql/src/test/java/org/apache/shardingsphere/test/e2e/cases/assertion/IntegrationTestCase.java
index 62e0365d2da..d451cd1d708 100644
--- 
a/test/e2e/sql/src/test/java/org/apache/shardingsphere/test/e2e/cases/assertion/IntegrationTestCase.java
+++ 
b/test/e2e/sql/src/test/java/org/apache/shardingsphere/test/e2e/cases/assertion/IntegrationTestCase.java
@@ -53,6 +53,9 @@ public final class IntegrationTestCase {
     @XmlAttribute(name = "delay-assertion-seconds")
     private Integer delayAssertionSeconds;
     
+    @XmlAttribute(name = "ignore-batch-test")
+    private Boolean ignoreBatchTest;
+    
     @XmlElement(name = "assertion")
     private Collection<IntegrationTestCaseAssertion> assertions = new 
LinkedList<>();
 }
diff --git 
a/test/e2e/sql/src/test/java/org/apache/shardingsphere/test/e2e/engine/type/dml/AdditionalDMLE2EIT.java
 
b/test/e2e/sql/src/test/java/org/apache/shardingsphere/test/e2e/engine/type/dml/AdditionalDMLE2EIT.java
index 93d42779c35..8db89093fdc 100644
--- 
a/test/e2e/sql/src/test/java/org/apache/shardingsphere/test/e2e/engine/type/dml/AdditionalDMLE2EIT.java
+++ 
b/test/e2e/sql/src/test/java/org/apache/shardingsphere/test/e2e/engine/type/dml/AdditionalDMLE2EIT.java
@@ -61,8 +61,10 @@ class AdditionalDMLE2EIT extends BaseDMLE2EIT {
             actualUpdateCount = SQLExecuteType.Literal == 
containerComposer.getSqlExecuteType()
                     ? 
executeUpdateForStatementWithAutoGeneratedKeys(testParam, containerComposer, 
connection)
                     : 
executeUpdateForPreparedStatementWithAutoGeneratedKeys(testParam, 
containerComposer, connection);
+            assertDataSet(containerComposer, actualUpdateCount, testParam);
+        } finally {
+            tearDown();
         }
-        assertDataSet(containerComposer, actualUpdateCount, testParam);
     }
     
     // TODO support oracle insert statement return auto generated keys
diff --git 
a/test/e2e/sql/src/test/java/org/apache/shardingsphere/test/e2e/engine/type/dml/BaseDMLE2EIT.java
 
b/test/e2e/sql/src/test/java/org/apache/shardingsphere/test/e2e/engine/type/dml/BaseDMLE2EIT.java
index d39bce3d24a..7f0f2f62773 100644
--- 
a/test/e2e/sql/src/test/java/org/apache/shardingsphere/test/e2e/engine/type/dml/BaseDMLE2EIT.java
+++ 
b/test/e2e/sql/src/test/java/org/apache/shardingsphere/test/e2e/engine/type/dml/BaseDMLE2EIT.java
@@ -17,6 +17,7 @@
 
 package org.apache.shardingsphere.test.e2e.engine.type.dml;
 
+import com.google.common.base.Splitter;
 import org.apache.shardingsphere.infra.database.core.type.DatabaseType;
 import org.apache.shardingsphere.infra.datanode.DataNode;
 import org.apache.shardingsphere.infra.expr.core.InlineExpressionParserFactory;
@@ -35,7 +36,8 @@ import 
org.apache.shardingsphere.test.e2e.framework.database.DatabaseAssertionMe
 import 
org.apache.shardingsphere.test.e2e.framework.database.DatabaseAssertionMetaDataFactory;
 import 
org.apache.shardingsphere.test.e2e.framework.param.model.AssertionTestParameter;
 import 
org.apache.shardingsphere.test.e2e.framework.param.model.CaseTestParameter;
-import org.junit.jupiter.api.AfterEach;
+import 
org.apache.shardingsphere.test.e2e.framework.param.model.E2ETestParameter;
+import org.testcontainers.shaded.org.awaitility.Awaitility;
 
 import javax.sql.DataSource;
 import javax.xml.bind.JAXBException;
@@ -52,6 +54,7 @@ import java.util.Collection;
 import java.util.List;
 import java.util.Map;
 import java.util.Optional;
+import java.util.concurrent.TimeUnit;
 
 import static org.hamcrest.CoreMatchers.is;
 import static org.hamcrest.MatcherAssert.assertThat;
@@ -71,13 +74,26 @@ public abstract class BaseDMLE2EIT {
      * @throws IOException IO exception
      * @throws JAXBException JAXB exception
      */
-    public final void init(final AssertionTestParameter testParam, final 
SingleE2EContainerComposer containerComposer) throws SQLException, IOException, 
JAXBException {
+    public void init(final E2ETestParameter testParam, final 
SingleE2EContainerComposer containerComposer) throws SQLException, IOException, 
JAXBException {
         dataSetEnvironmentManager = new DataSetEnvironmentManager(new 
ScenarioDataPath(testParam.getScenario()).getDataSetFile(Type.ACTUAL), 
containerComposer.getActualDataSourceMap());
         dataSetEnvironmentManager.fillData();
     }
     
-    @AfterEach
-    void tearDown() {
+    /**
+     * Init.
+     *
+     * @param testParam test parameter
+     * @param actualDataSourceMap actual data source map
+     * @throws SQLException SQL exception
+     * @throws IOException IO exception
+     * @throws JAXBException JAXB exception
+     */
+    public void init(final E2ETestParameter testParam, Map<String, DataSource> 
actualDataSourceMap) throws SQLException, IOException, JAXBException {
+        dataSetEnvironmentManager = new DataSetEnvironmentManager(new 
ScenarioDataPath(testParam.getScenario()).getDataSetFile(Type.ACTUAL), 
actualDataSourceMap);
+        dataSetEnvironmentManager.fillData();
+    }
+    
+    protected void tearDown() {
         // TODO make sure test case can not be null
         if (null != dataSetEnvironmentManager) {
             dataSetEnvironmentManager.cleanData();
@@ -203,4 +219,48 @@ public abstract class BaseDMLE2EIT {
         assertMetaData(generatedKeys.getMetaData(), 
containerComposer.getGeneratedKeyDataSet().getMetaDataList().get(0).getColumns());
         assertRows(generatedKeys, 
containerComposer.getGeneratedKeyDataSet().getRows(), databaseType);
     }
+    
+    protected void executeDestroySQLs(final SingleE2EContainerComposer 
containerComposer) throws SQLException {
+        if (null != containerComposer.getAssertion().getDestroySQL()) {
+            try (Connection connection = 
containerComposer.getTargetDataSource().getConnection()) {
+                executeDestroySQLs(containerComposer, connection);
+            }
+        }
+    }
+    
+    protected void executeInitSQLs(final SingleE2EContainerComposer 
containerComposer) throws SQLException {
+        if (null != containerComposer.getAssertion().getInitialSQL()) {
+            try (Connection connection = 
containerComposer.getTargetDataSource().getConnection()) {
+                executeInitSQLs(containerComposer, connection);
+            }
+        }
+    }
+    
+    private void executeInitSQLs(final SingleE2EContainerComposer 
containerComposer, final Connection connection) throws SQLException {
+        if (null == containerComposer.getAssertion().getInitialSQL().getSql()) 
{
+            return;
+        }
+        for (String each : 
Splitter.on(";").trimResults().omitEmptyStrings().splitToList(containerComposer.getAssertion().getInitialSQL().getSql()))
 {
+            try (PreparedStatement preparedStatement = 
connection.prepareStatement(each)) {
+                preparedStatement.executeUpdate();
+            }
+            waitCompleted();
+        }
+    }
+    
+    private void executeDestroySQLs(final SingleE2EContainerComposer 
containerComposer, final Connection connection) throws SQLException {
+        if (null == containerComposer.getAssertion().getDestroySQL().getSql()) 
{
+            return;
+        }
+        for (String each : 
Splitter.on(";").trimResults().omitEmptyStrings().splitToList(containerComposer.getAssertion().getDestroySQL().getSql()))
 {
+            try (PreparedStatement preparedStatement = 
connection.prepareStatement(each)) {
+                preparedStatement.executeUpdate();
+            }
+            waitCompleted();
+        }
+    }
+    
+    private void waitCompleted() {
+        Awaitility.await().pollDelay(1500L, TimeUnit.MILLISECONDS).until(() -> 
true);
+    }
 }
diff --git 
a/test/e2e/sql/src/test/java/org/apache/shardingsphere/test/e2e/engine/type/dml/BatchDMLE2EIT.java
 
b/test/e2e/sql/src/test/java/org/apache/shardingsphere/test/e2e/engine/type/dml/BatchDMLE2EIT.java
index 9e2974da0eb..befcb5c0a2f 100644
--- 
a/test/e2e/sql/src/test/java/org/apache/shardingsphere/test/e2e/engine/type/dml/BatchDMLE2EIT.java
+++ 
b/test/e2e/sql/src/test/java/org/apache/shardingsphere/test/e2e/engine/type/dml/BatchDMLE2EIT.java
@@ -49,12 +49,17 @@ class BatchDMLE2EIT extends BaseDMLE2EIT {
         if (null == testParam.getTestCaseContext()) {
             return;
         }
+        if 
(Boolean.TRUE.equals(testParam.getTestCaseContext().getTestCase().getIgnoreBatchTest()))
 {
+            return;
+        }
         try (BatchE2EContainerComposer containerComposer = new 
BatchE2EContainerComposer(testParam)) {
             int[] actualUpdateCounts;
             try (Connection connection = 
containerComposer.getTargetDataSource().getConnection()) {
                 actualUpdateCounts = 
executeBatchForPreparedStatement(testParam, connection);
             }
             assertDataSet(containerComposer, actualUpdateCounts, testParam);
+        } finally {
+            tearDown();
         }
     }
     
diff --git 
a/test/e2e/sql/src/test/java/org/apache/shardingsphere/test/e2e/engine/type/dml/GeneralDMLE2EIT.java
 
b/test/e2e/sql/src/test/java/org/apache/shardingsphere/test/e2e/engine/type/dml/GeneralDMLE2EIT.java
index 634d8895416..30ef856fc6f 100644
--- 
a/test/e2e/sql/src/test/java/org/apache/shardingsphere/test/e2e/engine/type/dml/GeneralDMLE2EIT.java
+++ 
b/test/e2e/sql/src/test/java/org/apache/shardingsphere/test/e2e/engine/type/dml/GeneralDMLE2EIT.java
@@ -51,13 +51,27 @@ class GeneralDMLE2EIT extends BaseDMLE2EIT {
         }
         SingleE2EContainerComposer containerComposer = new 
SingleE2EContainerComposer(testParam);
         init(testParam, containerComposer);
-        int actualUpdateCount;
-        try (Connection connection = 
containerComposer.getTargetDataSource().getConnection()) {
-            actualUpdateCount = SQLExecuteType.Literal == 
containerComposer.getSqlExecuteType()
-                    ? executeUpdateForStatement(containerComposer, connection)
-                    : executeUpdateForPreparedStatement(containerComposer, 
connection);
+        try {
+            int actualUpdateCount;
+            try (Connection connection = 
containerComposer.getTargetDataSource().getConnection()) {
+                actualUpdateCount = SQLExecuteType.Literal == 
containerComposer.getSqlExecuteType()
+                        ? executeUpdateForStatement(containerComposer, 
connection)
+                        : executeUpdateForPreparedStatement(containerComposer, 
connection);
+            }
+            assertDataSet(containerComposer, actualUpdateCount, testParam);
+        } finally {
+            tearDown(containerComposer);
         }
-        assertDataSet(containerComposer, actualUpdateCount, testParam);
+    }
+    
+    public void init(final AssertionTestParameter testParam, final 
SingleE2EContainerComposer containerComposer) throws SQLException, 
JAXBException, IOException {
+        super.init(testParam, containerComposer);
+        executeInitSQLs(containerComposer);
+    }
+    
+    void tearDown(final SingleE2EContainerComposer containerComposer) throws 
SQLException {
+        tearDown();
+        executeDestroySQLs(containerComposer);
     }
     
     private int executeUpdateForStatement(final SingleE2EContainerComposer 
containerComposer, final Connection connection) throws SQLException {
@@ -90,8 +104,10 @@ class GeneralDMLE2EIT extends BaseDMLE2EIT {
             actualUpdateCount = SQLExecuteType.Literal == 
containerComposer.getSqlExecuteType()
                     ? executeForStatement(containerComposer, connection)
                     : executeForPreparedStatement(containerComposer, 
connection);
+            assertDataSet(containerComposer, actualUpdateCount, testParam);
+        } finally {
+            tearDown(containerComposer);
         }
-        assertDataSet(containerComposer, actualUpdateCount, testParam);
     }
     
     private int executeForStatement(final SingleE2EContainerComposer 
containerComposer, final Connection connection) throws SQLException {
diff --git 
a/test/e2e/sql/src/test/resources/cases/dml/dataset/db/insert_single_with_generate_key_column.xml
 
b/test/e2e/sql/src/test/resources/cases/dml/dataset/db/insert_single_with_generate_key_column.xml
new file mode 100644
index 00000000000..4c811b81cd2
--- /dev/null
+++ 
b/test/e2e/sql/src/test/resources/cases/dml/dataset/db/insert_single_with_generate_key_column.xml
@@ -0,0 +1,24 @@
+<!--
+  ~ 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.
+  -->
+
+<dataset update-count="1">
+    <metadata data-nodes="db_0.t_single">
+        <column name="id" type="numeric" />
+        <column name="name" type="varchar" />
+    </metadata>
+    <row data-node="db_0.t_single" values="1, 1" />
+</dataset>
diff --git 
a/test/e2e/sql/src/test/resources/cases/dml/dml-integration-insert.xml 
b/test/e2e/sql/src/test/resources/cases/dml/dml-integration-insert.xml
index e0eb93f550c..4b450edb44a 100644
--- a/test/e2e/sql/src/test/resources/cases/dml/dml-integration-insert.xml
+++ b/test/e2e/sql/src/test/resources/cases/dml/dml-integration-insert.xml
@@ -233,4 +233,28 @@
     <test-case sql="/* SHARDINGSPHERE_HINT: DATA_SOURCE_NAME=encrypt_ds_0 
*/INSERT INTO t_order_0 values (1, 1, 'ok', 1, 'mark', '2021-01-01')" 
db-types="MySQL,PostgreSQL" scenario-types="sharding_and_encrypt">
         <assertion expected-data-file="insert_into_t_order_0.xml" />
     </test-case>
+    
+    <test-case sql="INSERT INTO t_single values (?, ?)" db-types="MySQL" 
scenario-types="db" ignore-batch-test="true">
+        <assertion parameters="1:int, 1:int" 
expected-data-file="insert_single_with_generate_key_column.xml" >
+            <destroy-sql sql="DELETE FROM t_single WHERE id = 1" />
+        </assertion>
+    </test-case>
+    
+    <test-case sql="INSERT INTO t_single(Id, Name) values (?, ?)" 
db-types="MySQL" scenario-types="db" ignore-batch-test="true">
+        <assertion parameters="1:int, 1:int" 
expected-data-file="insert_single_with_generate_key_column.xml" >
+            <destroy-sql sql="DELETE FROM t_single WHERE id = 1" />
+        </assertion>
+    </test-case>
+    
+    <test-case sql="INSERT INTO t_single(id, name) values (?, ?)" 
db-types="MySQL" scenario-types="db" ignore-batch-test="true">
+        <assertion parameters="1:int, 1:int" 
expected-data-file="insert_single_with_generate_key_column.xml" >
+            <destroy-sql sql="DELETE FROM t_single WHERE id = 1" />
+        </assertion>
+    </test-case>
+    
+    <test-case sql="INSERT INTO t_single(ID, NAME) values (?, ?)" 
db-types="MySQL" scenario-types="db" ignore-batch-test="true">
+        <assertion parameters="1:int, 1:int" 
expected-data-file="insert_single_with_generate_key_column.xml" >
+            <destroy-sql sql="DELETE FROM t_single WHERE id = 1" />
+        </assertion>
+    </test-case>
 </integration-test-cases>
diff --git 
a/test/e2e/sql/src/test/resources/env/scenario/db/data/actual/init-sql/mysql/01-actual-init.sql
 
b/test/e2e/sql/src/test/resources/env/scenario/db/data/actual/init-sql/mysql/01-actual-init.sql
index 4f204fd42a3..c2877821c58 100644
--- 
a/test/e2e/sql/src/test/resources/env/scenario/db/data/actual/init-sql/mysql/01-actual-init.sql
+++ 
b/test/e2e/sql/src/test/resources/env/scenario/db/data/actual/init-sql/mysql/01-actual-init.sql
@@ -46,6 +46,7 @@ CREATE TABLE db_0.t_user (user_id INT PRIMARY KEY, user_name 
VARCHAR(50) NOT NUL
 CREATE TABLE db_0.t_product (product_id INT PRIMARY KEY, product_name 
VARCHAR(50) NOT NULL, category_id INT NOT NULL, price DECIMAL NOT NULL, status 
VARCHAR(50) NOT NULL, creation_date DATE NOT NULL);
 CREATE TABLE db_0.t_product_category (category_id INT PRIMARY KEY, 
category_name VARCHAR(50) NOT NULL, parent_id INT NOT NULL, level TINYINT NOT 
NULL, creation_date DATE NOT NULL);
 CREATE TABLE db_0.t_country (country_id SMALLINT PRIMARY KEY, country_name 
VARCHAR(50), continent_name VARCHAR(50), creation_date DATE NOT NULL);
+CREATE TABLE db_0.t_single (ID BIGINT PRIMARY KEY, NAME VARCHAR(50));
 CREATE INDEX order_index_t_order ON db_0.t_order (order_id);
 
 CREATE TABLE db_1.t_order (order_id BIGINT PRIMARY KEY, user_id INT NOT NULL, 
status VARCHAR(50) NOT NULL, merchant_id INT, remark VARCHAR(50) NOT NULL, 
creation_date DATE NOT NULL);


Reply via email to