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/03/04 11:21:35 UTC

(shardingsphere) branch master updated: Refactor constructor of InsertStatement to empty buildAttributes (#38342)

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

zhangliang 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 127c159cc3a Refactor constructor of InsertStatement to empty buildAttributes (#38342)
127c159cc3a is described below

commit 127c159cc3a12442cf7f4919c59ffd599033e8e6
Author: Liang Zhang <zh...@apache.org>
AuthorDate: Wed Mar 4 19:21:26 2026 +0800

    Refactor constructor of InsertStatement to empty buildAttributes (#38342)
---
 .../core/advice/SQLRouteCountAdviceTest.java       |   2 +-
 .../fixture/EncryptGeneratorFixtureBuilder.java    |  21 ++--
 .../merge/ShardingResultMergerEngineTest.java      |   5 +-
 .../InsertClauseShardingConditionEngineTest.java   |   5 +-
 .../statement/dml/InsertStatementBinder.java       |  38 ++++---
 .../context/SQLStatementContextFactoryTest.java    |   4 +-
 .../engine/GeneratedKeyContextEngineTest.java      |  26 +++--
 .../type/dml/InsertStatementContextTest.java       |  23 ++--
 .../statement/dml/InsertStatementBinderTest.java   |  40 +++----
 .../ast/converter/SQLNodeConverterEngineTest.java  |   2 +-
 .../type/ExplainStatementConverterTest.java        |   6 +-
 .../type/InsertStatementConverterTest.java         |  27 +++--
 .../transaction/util/AutoCommitUtilsTest.java      |   2 +-
 .../type/ClickHouseDMLStatementVisitor.java        |  27 +++--
 .../visitor/statement/DorisStatementVisitor.java   |  96 ++++++++++-------
 .../type/FirebirdDMLStatementVisitor.java          |  30 ++++--
 .../statement/type/HiveDMLStatementVisitor.java    | 101 +++++++++--------
 .../visitor/statement/MySQLStatementVisitor.java   | 120 +++++++++++----------
 .../statement/OpenGaussStatementVisitor.java       |  43 +++++---
 .../statement/type/OracleDMLStatementVisitor.java  |  63 ++++++-----
 .../statement/PostgreSQLStatementVisitor.java      |  30 +++---
 .../statement/type/PrestoDMLStatementVisitor.java  |  51 +++++----
 .../statement/type/SQL92DMLStatementVisitor.java   |  19 ++--
 .../statement/SQLServerStatementVisitor.java       |  85 +++++++++------
 .../core/statement/type/dml/InsertStatement.java   |  76 ++++++++-----
 .../statement/core/util/MultiSQLSplitterTest.java  |   5 +-
 .../backend/connector/ProxySQLExecutorTest.java    |   4 +-
 .../StandardDatabaseProxyConnectorTest.java        |  14 +--
 .../MySQLDialectSaneQueryResultEngineTest.java     |   2 +-
 .../simple/OpenGaussComQueryExecutorTest.java      |   2 +-
 .../command/query/extended/PortalTest.java         |   2 +-
 .../PostgreSQLBatchedStatementsExecutorTest.java   |   3 +-
 .../simple/PostgreSQLComQueryExecutorTest.java     |   2 +-
 33 files changed, 557 insertions(+), 419 deletions(-)

diff --git a/agent/plugins/metrics/core/src/test/java/org/apache/shardingsphere/agent/plugin/metrics/core/advice/SQLRouteCountAdviceTest.java b/agent/plugins/metrics/core/src/test/java/org/apache/shardingsphere/agent/plugin/metrics/core/advice/SQLRouteCountAdviceTest.java
index 2379b826e0c..61d00470b8d 100644
--- a/agent/plugins/metrics/core/src/test/java/org/apache/shardingsphere/agent/plugin/metrics/core/advice/SQLRouteCountAdviceTest.java
+++ b/agent/plugins/metrics/core/src/test/java/org/apache/shardingsphere/agent/plugin/metrics/core/advice/SQLRouteCountAdviceTest.java
@@ -71,7 +71,7 @@ class SQLRouteCountAdviceTest {
     
     private static Stream<Arguments> routeContexts() {
         return Stream.of(
-                Arguments.of("INSERT", createQueryContext(new InsertStatement(DATABASE_TYPE))),
+                Arguments.of("INSERT", createQueryContext(InsertStatement.builder().databaseType(DATABASE_TYPE).build())),
                 Arguments.of("UPDATE", createQueryContext(new UpdateStatement(DATABASE_TYPE))),
                 Arguments.of("DELETE", createQueryContext(DeleteStatement.builder().databaseType(DATABASE_TYPE).build())),
                 Arguments.of("SELECT", createQueryContext(new SelectStatement(DATABASE_TYPE))));
diff --git a/features/encrypt/core/src/test/java/org/apache/shardingsphere/encrypt/rewrite/token/generator/fixture/EncryptGeneratorFixtureBuilder.java b/features/encrypt/core/src/test/java/org/apache/shardingsphere/encrypt/rewrite/token/generator/fixture/EncryptGeneratorFixtureBuilder.java
index 510bbd54db9..c17a58a97b6 100644
--- a/features/encrypt/core/src/test/java/org/apache/shardingsphere/encrypt/rewrite/token/generator/fixture/EncryptGeneratorFixtureBuilder.java
+++ b/features/encrypt/core/src/test/java/org/apache/shardingsphere/encrypt/rewrite/token/generator/fixture/EncryptGeneratorFixtureBuilder.java
@@ -120,19 +120,15 @@ public final class EncryptGeneratorFixtureBuilder {
     }
     
     private static InsertStatement createInsertStatement() {
-        InsertStatement result = new InsertStatement(DATABASE_TYPE);
-        result.setTable(new SimpleTableSegment(new TableNameSegment(0, 0, new IdentifierValue("t_user"))));
         InsertColumnsSegment insertColumnsSegment = new InsertColumnsSegment(0, 0, Arrays.asList(
                 new ColumnSegment(0, 0, new IdentifierValue("id")), new ColumnSegment(0, 0, new IdentifierValue("name")),
                 new ColumnSegment(0, 0, new IdentifierValue("status")), new ColumnSegment(0, 0, new IdentifierValue("pwd"))));
-        result.setInsertColumns(insertColumnsSegment);
-        result.getValues().add(new InsertValuesSegment(0, 0, createValueExpressions()));
-        return result;
+        return InsertStatement.builder().databaseType(DATABASE_TYPE).table(new SimpleTableSegment(new TableNameSegment(0, 0, new IdentifierValue("t_user"))))
+                .insertColumns(insertColumnsSegment).values(Collections.singletonList(new InsertValuesSegment(0, 0, createValueExpressions()))).build();
     }
     
     private static InsertStatement createInsertSelectStatement(final boolean containsInsertColumns) {
-        InsertStatement result = new InsertStatement(DATABASE_TYPE);
-        result.setTable(new SimpleTableSegment(new TableNameSegment(0, 0, new IdentifierValue("t_user"))));
+        InsertColumnsSegment insertColumnsSegment;
         ColumnSegment userIdColumn = new ColumnSegment(0, 0, new IdentifierValue("user_id"));
         userIdColumn.setColumnBoundInfo(new ColumnSegmentBoundInfo(new TableSegmentBoundInfo(new IdentifierValue("foo_db"), new IdentifierValue("foo_db")), new IdentifierValue("t_user"),
                 new IdentifierValue("user_id"), TableSourceType.PHYSICAL_TABLE));
@@ -140,11 +136,12 @@ public final class EncryptGeneratorFixtureBuilder {
         userNameColumn.setColumnBoundInfo(new ColumnSegmentBoundInfo(new TableSegmentBoundInfo(new IdentifierValue("foo_db"), new IdentifierValue("foo_db")),
                 new IdentifierValue("t_user"), new IdentifierValue("user_name"), TableSourceType.PHYSICAL_TABLE));
         List<ColumnSegment> insertColumns = Arrays.asList(userIdColumn, userNameColumn);
+        List<ColumnSegment> derivedInsertColumns = new ArrayList<>();
         if (containsInsertColumns) {
-            result.setInsertColumns(new InsertColumnsSegment(0, 0, insertColumns));
+            insertColumnsSegment = new InsertColumnsSegment(0, 0, insertColumns);
         } else {
-            result.setInsertColumns(new InsertColumnsSegment(0, 0, Collections.emptyList()));
-            result.getDerivedInsertColumns().addAll(insertColumns);
+            insertColumnsSegment = new InsertColumnsSegment(0, 0, Collections.emptyList());
+            derivedInsertColumns.addAll(insertColumns);
         }
         SelectStatement selectStatement = new SelectStatement(DATABASE_TYPE);
         selectStatement.setFrom(new SimpleTableSegment(new TableNameSegment(0, 0, new IdentifierValue("t_user"))));
@@ -155,8 +152,8 @@ public final class EncryptGeneratorFixtureBuilder {
                 new IdentifierValue("status"), TableSourceType.PHYSICAL_TABLE));
         projections.getProjections().add(new ColumnProjectionSegment(statusColumn));
         selectStatement.setProjections(projections);
-        result.setInsertSelect(new SubquerySegment(0, 0, selectStatement, ""));
-        return result;
+        return InsertStatement.builder().databaseType(DATABASE_TYPE).table(new SimpleTableSegment(new TableNameSegment(0, 0, new IdentifierValue("t_user"))))
+                .insertColumns(insertColumnsSegment).derivedInsertColumns(derivedInsertColumns).insertSelect(new SubquerySegment(0, 0, selectStatement, "")).build();
     }
     
     /**
diff --git a/features/sharding/core/src/test/java/org/apache/shardingsphere/sharding/merge/ShardingResultMergerEngineTest.java b/features/sharding/core/src/test/java/org/apache/shardingsphere/sharding/merge/ShardingResultMergerEngineTest.java
index c5ec5cd02be..58361bff8c0 100644
--- a/features/sharding/core/src/test/java/org/apache/shardingsphere/sharding/merge/ShardingResultMergerEngineTest.java
+++ b/features/sharding/core/src/test/java/org/apache/shardingsphere/sharding/merge/ShardingResultMergerEngineTest.java
@@ -80,10 +80,9 @@ class ShardingResultMergerEngineTest {
     
     @Test
     void assertNewInstanceWithOtherStatement() {
-        InsertStatement insertStatement = new InsertStatement(databaseType);
         InsertColumnsSegment insertColumnsSegment = new InsertColumnsSegment(0, 0, Collections.singletonList(new ColumnSegment(0, 0, new IdentifierValue("col"))));
-        insertStatement.setTable(new SimpleTableSegment(new TableNameSegment(0, 0, new IdentifierValue("tbl"))));
-        insertStatement.setInsertColumns(insertColumnsSegment);
+        InsertStatement insertStatement = InsertStatement.builder().databaseType(databaseType)
+                .table(new SimpleTableSegment(new TableNameSegment(0, 0, new IdentifierValue("tbl")))).insertColumns(insertColumnsSegment).build();
         InsertStatementContext sqlStatementContext = createInsertStatementContext(insertStatement);
         ConfigurationProperties props = new ConfigurationProperties(new Properties());
         assertThat(new ShardingResultMergerEngine().newInstance("foo_db", databaseType, null, props, sqlStatementContext), isA(TransparentResultMerger.class));
diff --git a/features/sharding/core/src/test/java/org/apache/shardingsphere/sharding/route/engine/condition/engine/InsertClauseShardingConditionEngineTest.java b/features/sharding/core/src/test/java/org/apache/shardingsphere/sharding/route/engine/condition/engine/InsertClauseShardingConditionEngineTest.java
index 04b332ad03f..1a6c36fdb7a 100644
--- a/features/sharding/core/src/test/java/org/apache/shardingsphere/sharding/route/engine/condition/engine/InsertClauseShardingConditionEngineTest.java
+++ b/features/sharding/core/src/test/java/org/apache/shardingsphere/sharding/route/engine/condition/engine/InsertClauseShardingConditionEngineTest.java
@@ -99,9 +99,8 @@ class InsertClauseShardingConditionEngineTest {
     }
     
     private InsertStatement createInsertStatement() {
-        InsertStatement result = new InsertStatement(TypedSPILoader.getService(DatabaseType.class, "FIXTURE"));
-        result.setTable(new SimpleTableSegment(new TableNameSegment(0, 0, new IdentifierValue("foo_tbl"))));
-        return result;
+        return InsertStatement.builder().databaseType(TypedSPILoader.getService(DatabaseType.class, "FIXTURE"))
+                .table(new SimpleTableSegment(new TableNameSegment(0, 0, new IdentifierValue("foo_tbl")))).build();
     }
     
     private InsertValueContext createInsertValueContext() {
diff --git a/infra/binder/core/src/main/java/org/apache/shardingsphere/infra/binder/engine/statement/dml/InsertStatementBinder.java b/infra/binder/core/src/main/java/org/apache/shardingsphere/infra/binder/engine/statement/dml/InsertStatementBinder.java
index 083f1e6396e..499c75e6736 100644
--- a/infra/binder/core/src/main/java/org/apache/shardingsphere/infra/binder/engine/statement/dml/InsertStatementBinder.java
+++ b/infra/binder/core/src/main/java/org/apache/shardingsphere/infra/binder/engine/statement/dml/InsertStatementBinder.java
@@ -40,6 +40,7 @@ import org.apache.shardingsphere.sql.parser.statement.core.segment.generic.table
 import org.apache.shardingsphere.sql.parser.statement.core.statement.type.dml.InsertStatement;
 
 import java.util.Collection;
+import java.util.LinkedList;
 import java.util.stream.Collectors;
 
 /**
@@ -67,21 +68,28 @@ public final class InsertStatementBinder implements SQLStatementBinder<InsertSta
     
     private InsertStatement copy(final InsertStatement sqlStatement, final WithSegment boundWith, final SimpleTableSegment boundTable,
                                  final InsertColumnsSegment boundInsertColumns, final SetAssignmentSegment boundSetAssignment, final SubquerySegment boundInsertSelect) {
-        InsertStatement result = new InsertStatement(sqlStatement.getDatabaseType());
-        result.setWith(boundWith);
-        result.setTable(boundTable);
-        result.setInsertColumns(boundInsertColumns);
-        result.setSetAssignment(boundSetAssignment);
-        result.setInsertSelect(boundInsertSelect);
-        result.getValues().addAll(sqlStatement.getValues());
-        result.setIgnore(sqlStatement.isIgnore());
-        result.setReplace(sqlStatement.isReplace());
-        sqlStatement.getOnDuplicateKeyColumns().ifPresent(result::setOnDuplicateKeyColumns);
-        sqlStatement.getOutput().ifPresent(result::setOutput);
-        sqlStatement.getMultiTableInsertType().ifPresent(result::setMultiTableInsertType);
-        sqlStatement.getMultiTableInsertInto().ifPresent(result::setMultiTableInsertInto);
-        sqlStatement.getMultiTableConditionalInto().ifPresent(result::setMultiTableConditionalInto);
-        sqlStatement.getReturning().ifPresent(result::setReturning);
+        InsertStatement result = InsertStatement.builder()
+                .databaseType(sqlStatement.getDatabaseType())
+                .table(boundTable)
+                .insertColumns(boundInsertColumns)
+                .insertSelect(boundInsertSelect)
+                .setAssignment(boundSetAssignment)
+                .onDuplicateKeyColumns(sqlStatement.getOnDuplicateKeyColumns().orElse(null))
+                .valueReference(sqlStatement.getValueReference().orElse(null))
+                .returning(sqlStatement.getReturning().orElse(null))
+                .output(sqlStatement.getOutput().orElse(null))
+                .with(boundWith)
+                .multiTableInsertType(sqlStatement.getMultiTableInsertType().orElse(null))
+                .multiTableInsertInto(sqlStatement.getMultiTableInsertInto().orElse(null))
+                .multiTableConditionalInto(sqlStatement.getMultiTableConditionalInto().orElse(null))
+                .where(sqlStatement.getWhere().orElse(null))
+                .exec(sqlStatement.getExec().orElse(null))
+                .withTableHint(sqlStatement.getWithTableHint().orElse(null))
+                .rowSetFunction(sqlStatement.getRowSetFunction().orElse(null))
+                .ignore(sqlStatement.isIgnore())
+                .replace(sqlStatement.isReplace())
+                .values(new LinkedList<>(sqlStatement.getValues()))
+                .build();
         SQLStatementCopyUtils.copyAttributes(sqlStatement, result);
         return result;
     }
diff --git a/infra/binder/core/src/test/java/org/apache/shardingsphere/infra/binder/context/SQLStatementContextFactoryTest.java b/infra/binder/core/src/test/java/org/apache/shardingsphere/infra/binder/context/SQLStatementContextFactoryTest.java
index eae36cd0bf1..085add7f433 100644
--- a/infra/binder/core/src/test/java/org/apache/shardingsphere/infra/binder/context/SQLStatementContextFactoryTest.java
+++ b/infra/binder/core/src/test/java/org/apache/shardingsphere/infra/binder/context/SQLStatementContextFactoryTest.java
@@ -71,8 +71,8 @@ class SQLStatementContextFactoryTest {
     
     @Test
     void assertSQLStatementContextCreatedWhenSQLStatementInstance() {
-        InsertStatement insertStatement = new InsertStatement(databaseType);
-        insertStatement.setTable(new SimpleTableSegment(new TableNameSegment(0, 0, new IdentifierValue("tbl"))));
+        InsertStatement insertStatement = InsertStatement.builder().databaseType(databaseType)
+                .table(new SimpleTableSegment(new TableNameSegment(0, 0, new IdentifierValue("tbl")))).build();
         insertStatement.buildAttributes();
         SQLStatementContext sqlStatementContext = new SQLBindEngine(mockMetaData(), "foo_db", new HintValueContext()).bind(insertStatement);
         assertThat(sqlStatementContext, isA(InsertStatementContext.class));
diff --git a/infra/binder/core/src/test/java/org/apache/shardingsphere/infra/binder/context/segment/insert/keygen/engine/GeneratedKeyContextEngineTest.java b/infra/binder/core/src/test/java/org/apache/shardingsphere/infra/binder/context/segment/insert/keygen/engine/GeneratedKeyContextEngineTest.java
index 08fd0e94901..3017351d7ca 100644
--- a/infra/binder/core/src/test/java/org/apache/shardingsphere/infra/binder/context/segment/insert/keygen/engine/GeneratedKeyContextEngineTest.java
+++ b/infra/binder/core/src/test/java/org/apache/shardingsphere/infra/binder/context/segment/insert/keygen/engine/GeneratedKeyContextEngineTest.java
@@ -69,21 +69,19 @@ class GeneratedKeyContextEngineTest {
     
     @Test
     void assertCreateGenerateKeyContextWithoutGenerateKeyColumnConfiguration() {
-        InsertStatement insertStatement = new InsertStatement(databaseType);
-        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")))));
+        InsertStatement insertStatement = InsertStatement.builder().databaseType(databaseType).table(new SimpleTableSegment(new TableNameSegment(0, 0, new IdentifierValue("tbl1"))))
+                .insertColumns(new InsertColumnsSegment(0, 0, Collections.singletonList(new ColumnSegment(0, 0, new IdentifierValue("id"))))).build();
         assertFalse(new GeneratedKeyContextEngine(insertStatement, schema).createGenerateKeyContext(Collections.emptyMap(),
                 Collections.emptyList(), Collections.singletonList(1)).isPresent());
     }
     
     @Test
     void assertCreateGenerateKeyContextWhenCreateWithGenerateKeyColumnConfiguration() {
-        InsertStatement insertStatement = new InsertStatement(databaseType);
-        insertStatement.setTable(new SimpleTableSegment(new TableNameSegment(0, 0, new IdentifierValue("foo_tbl"))));
-        insertStatement.setInsertColumns(new InsertColumnsSegment(0, 0, Collections.singletonList(new ColumnSegment(0, 0, new IdentifierValue("id")))));
         List<ExpressionSegment> expressionSegments = Collections.singletonList(new LiteralExpressionSegment(0, 0, 1));
         InsertValueContext insertValueContext = new InsertValueContext(expressionSegments, Collections.emptyList(), 0);
-        insertStatement.getValues().add(new InsertValuesSegment(0, 0, expressionSegments));
+        InsertStatement insertStatement = InsertStatement.builder().databaseType(databaseType).table(new SimpleTableSegment(new TableNameSegment(0, 0, new IdentifierValue("foo_tbl"))))
+                .insertColumns(new InsertColumnsSegment(0, 0, Collections.singletonList(new ColumnSegment(0, 0, new IdentifierValue("id")))))
+                .values(Collections.singletonList(new InsertValuesSegment(0, 0, expressionSegments))).build();
         Optional<GeneratedKeyContext> actual = new GeneratedKeyContextEngine(insertStatement, schema)
                 .createGenerateKeyContext(new CaseInsensitiveMap<>(Collections.singletonMap("id", 0)), Collections.singletonList(insertValueContext), Collections.singletonList(1));
         assertTrue(actual.isPresent());
@@ -92,13 +90,13 @@ class GeneratedKeyContextEngineTest {
     
     @Test
     void assertCreateGenerateKeyContextWhenFind() {
-        InsertStatement insertStatement = new InsertStatement(databaseType);
-        insertStatement.setTable(new SimpleTableSegment(new TableNameSegment(0, 0, new IdentifierValue("foo_tbl"))));
-        insertStatement.setInsertColumns(new InsertColumnsSegment(0, 0, Collections.singletonList(new ColumnSegment(0, 0, new IdentifierValue("id")))));
-        insertStatement.getValues().add(new InsertValuesSegment(0, 0, Collections.singletonList(new ParameterMarkerExpressionSegment(1, 2, 0))));
-        insertStatement.getValues().add(new InsertValuesSegment(0, 0, Collections.singletonList(new LiteralExpressionSegment(1, 2, 100))));
-        insertStatement.getValues().add(new InsertValuesSegment(0, 0, Collections.singletonList(new LiteralExpressionSegment(1, 2, "value"))));
-        insertStatement.getValues().add(new InsertValuesSegment(0, 0, Collections.singletonList(new CommonExpressionSegment(1, 2, "ignored value"))));
+        InsertStatement insertStatement = InsertStatement.builder().databaseType(databaseType).table(new SimpleTableSegment(new TableNameSegment(0, 0, new IdentifierValue("foo_tbl"))))
+                .insertColumns(new InsertColumnsSegment(0, 0, Collections.singletonList(new ColumnSegment(0, 0, new IdentifierValue("id")))))
+                .values(Arrays.asList(new InsertValuesSegment(0, 0, Collections.singletonList(new ParameterMarkerExpressionSegment(1, 2, 0))),
+                        new InsertValuesSegment(0, 0, Collections.singletonList(new LiteralExpressionSegment(1, 2, 100))),
+                        new InsertValuesSegment(0, 0, Collections.singletonList(new LiteralExpressionSegment(1, 2, "value"))),
+                        new InsertValuesSegment(0, 0, Collections.singletonList(new CommonExpressionSegment(1, 2, "ignored value")))))
+                .build();
         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)
diff --git a/infra/binder/core/src/test/java/org/apache/shardingsphere/infra/binder/context/statement/type/dml/InsertStatementContextTest.java b/infra/binder/core/src/test/java/org/apache/shardingsphere/infra/binder/context/statement/type/dml/InsertStatementContextTest.java
index 688bb4c7e57..02b7dc5f5bc 100644
--- a/infra/binder/core/src/test/java/org/apache/shardingsphere/infra/binder/context/statement/type/dml/InsertStatementContextTest.java
+++ b/infra/binder/core/src/test/java/org/apache/shardingsphere/infra/binder/context/statement/type/dml/InsertStatementContextTest.java
@@ -136,15 +136,13 @@ class InsertStatementContextTest {
     
     @Test
     void assertInsertSelect() {
-        InsertStatement insertStatement = new InsertStatement(databaseType);
         SelectStatement selectStatement = new SelectStatement(databaseType);
         selectStatement.addParameterMarkers(Collections.singleton(new ParameterMarkerExpressionSegment(0, 0, 0, ParameterMarkerType.QUESTION)));
         selectStatement.setProjections(new ProjectionsSegment(0, 0));
         SubquerySegment insertSelect = new SubquerySegment(0, 0, selectStatement, "");
-        insertStatement.setInsertSelect(insertSelect);
         TableNameSegment tableNameSegment = new TableNameSegment(0, 0, new IdentifierValue("tbl"));
         tableNameSegment.setTableBoundInfo(new TableSegmentBoundInfo(new IdentifierValue("foo_db"), new IdentifierValue("foo_schema")));
-        insertStatement.setTable(new SimpleTableSegment(tableNameSegment));
+        InsertStatement insertStatement = InsertStatement.builder().databaseType(databaseType).insertSelect(insertSelect).table(new SimpleTableSegment(tableNameSegment)).build();
         InsertStatementContext actual = createInsertStatementContext(insertStatement);
         actual.bindParameters(Collections.singletonList("param"));
         assertThat(actual.getInsertSelectContext().getSelectStatementContext().getSqlStatement().getParameterCount(), is(1));
@@ -213,22 +211,19 @@ class InsertStatementContextTest {
     
     @Test
     void assertContainsInsertColumns() {
-        InsertStatement insertStatement = new InsertStatement(databaseType);
         InsertColumnsSegment insertColumnsSegment = new InsertColumnsSegment(0, 0, Collections.singletonList(new ColumnSegment(0, 0, new IdentifierValue("col"))));
-        insertStatement.setInsertColumns(insertColumnsSegment);
         TableNameSegment tableNameSegment = new TableNameSegment(0, 0, new IdentifierValue(""));
         tableNameSegment.setTableBoundInfo(new TableSegmentBoundInfo(new IdentifierValue("foo_db"), new IdentifierValue("foo_schema")));
-        insertStatement.setTable(new SimpleTableSegment(tableNameSegment));
+        InsertStatement insertStatement = InsertStatement.builder().databaseType(databaseType).insertColumns(insertColumnsSegment).table(new SimpleTableSegment(tableNameSegment)).build();
         InsertStatementContext insertStatementContext = createInsertStatementContext(insertStatement);
         assertTrue(insertStatementContext.containsInsertColumns());
     }
     
     @Test
     void assertNotContainsInsertColumns() {
-        InsertStatement insertStatement = new InsertStatement(databaseType);
         TableNameSegment tableNameSegment = new TableNameSegment(0, 0, new IdentifierValue(""));
         tableNameSegment.setTableBoundInfo(new TableSegmentBoundInfo(new IdentifierValue("foo_db"), new IdentifierValue("foo_schema")));
-        insertStatement.setTable(new SimpleTableSegment(tableNameSegment));
+        InsertStatement insertStatement = InsertStatement.builder().databaseType(databaseType).table(new SimpleTableSegment(tableNameSegment)).build();
         InsertStatementContext insertStatementContext = createInsertStatementContext(insertStatement);
         assertFalse(insertStatementContext.containsInsertColumns());
     }
@@ -247,12 +242,12 @@ class InsertStatementContextTest {
     
     @Test
     void assertGetValueListCountWithValues() {
-        InsertStatement insertStatement = new InsertStatement(databaseType);
-        insertStatement.getValues().add(new InsertValuesSegment(0, 0, Collections.singletonList(new LiteralExpressionSegment(0, 0, 1))));
-        insertStatement.getValues().add(new InsertValuesSegment(0, 0, Collections.singletonList(new LiteralExpressionSegment(0, 0, 2))));
         TableNameSegment tableNameSegment = new TableNameSegment(0, 0, new IdentifierValue(""));
         tableNameSegment.setTableBoundInfo(new TableSegmentBoundInfo(new IdentifierValue("foo_db"), new IdentifierValue("foo_schema")));
-        insertStatement.setTable(new SimpleTableSegment(tableNameSegment));
+        InsertStatement insertStatement = InsertStatement.builder().databaseType(databaseType).table(new SimpleTableSegment(tableNameSegment))
+                .values(Arrays.asList(new InsertValuesSegment(0, 0, Collections.singletonList(new LiteralExpressionSegment(0, 0, 1))),
+                        new InsertValuesSegment(0, 0, Collections.singletonList(new LiteralExpressionSegment(0, 0, 2)))))
+                .build();
         InsertStatementContext insertStatementContext = createInsertStatementContext(insertStatement);
         assertThat(insertStatementContext.getValueListCount(), is(2));
     }
@@ -274,12 +269,10 @@ class InsertStatementContextTest {
     
     @Test
     void assertGetInsertColumnNamesForInsertColumns() {
-        InsertStatement insertStatement = new InsertStatement(databaseType);
         InsertColumnsSegment insertColumnsSegment = new InsertColumnsSegment(0, 0, Collections.singletonList(new ColumnSegment(0, 0, new IdentifierValue("col"))));
-        insertStatement.setInsertColumns(insertColumnsSegment);
         TableNameSegment tableNameSegment = new TableNameSegment(0, 0, new IdentifierValue(""));
         tableNameSegment.setTableBoundInfo(new TableSegmentBoundInfo(new IdentifierValue("foo_db"), new IdentifierValue("foo_schema")));
-        insertStatement.setTable(new SimpleTableSegment(tableNameSegment));
+        InsertStatement insertStatement = InsertStatement.builder().databaseType(databaseType).insertColumns(insertColumnsSegment).table(new SimpleTableSegment(tableNameSegment)).build();
         InsertStatementContext insertStatementContext = createInsertStatementContext(insertStatement);
         List<String> columnNames = insertStatementContext.getInsertColumnNames();
         assertThat(columnNames.size(), is(1));
diff --git a/infra/binder/core/src/test/java/org/apache/shardingsphere/infra/binder/engine/statement/dml/InsertStatementBinderTest.java b/infra/binder/core/src/test/java/org/apache/shardingsphere/infra/binder/engine/statement/dml/InsertStatementBinderTest.java
index 6739c649a37..23e598bbbf1 100644
--- a/infra/binder/core/src/test/java/org/apache/shardingsphere/infra/binder/engine/statement/dml/InsertStatementBinderTest.java
+++ b/infra/binder/core/src/test/java/org/apache/shardingsphere/infra/binder/engine/statement/dml/InsertStatementBinderTest.java
@@ -42,6 +42,7 @@ import org.junit.jupiter.api.Test;
 import java.sql.Types;
 import java.util.Arrays;
 import java.util.Collection;
+import java.util.Collections;
 import java.util.Iterator;
 
 import static org.hamcrest.Matchers.is;
@@ -59,12 +60,13 @@ class InsertStatementBinderTest {
     
     @Test
     void assertBindInsertValues() {
-        InsertStatement insertStatement = new InsertStatement(databaseType);
-        insertStatement.setTable(new SimpleTableSegment(new TableNameSegment(0, 0, new IdentifierValue("t_order"))));
-        insertStatement.setInsertColumns(new InsertColumnsSegment(0, 0, Arrays.asList(new ColumnSegment(0, 0, new IdentifierValue("order_id")),
-                new ColumnSegment(0, 0, new IdentifierValue("user_id")), new ColumnSegment(0, 0, new IdentifierValue("status")))));
-        insertStatement.getValues().add(new InsertValuesSegment(0, 0, Arrays.asList(new LiteralExpressionSegment(0, 0, 1),
-                new LiteralExpressionSegment(0, 0, 1), new LiteralExpressionSegment(0, 0, "OK"))));
+        InsertStatement insertStatement = InsertStatement.builder().databaseType(databaseType)
+                .table(new SimpleTableSegment(new TableNameSegment(0, 0, new IdentifierValue("t_order"))))
+                .insertColumns(new InsertColumnsSegment(0, 0, Arrays.asList(new ColumnSegment(0, 0, new IdentifierValue("order_id")),
+                        new ColumnSegment(0, 0, new IdentifierValue("user_id")), new ColumnSegment(0, 0, new IdentifierValue("status")))))
+                .values(Collections.singletonList(new InsertValuesSegment(0, 0, Arrays.asList(new LiteralExpressionSegment(0, 0, 1),
+                        new LiteralExpressionSegment(0, 0, 1), new LiteralExpressionSegment(0, 0, "OK")))))
+                .build();
         InsertStatement actual = new InsertStatementBinder().bind(insertStatement, new SQLStatementBinderContext(createMetaData(), "foo_db", new HintValueContext(), insertStatement));
         assertThat(actual, not(insertStatement));
         assertTrue(actual.getTable().isPresent());
@@ -96,10 +98,6 @@ class InsertStatementBinderTest {
     
     @Test
     void assertBindInsertSelectWithColumns() {
-        InsertStatement insertStatement = new InsertStatement(databaseType);
-        insertStatement.setTable(new SimpleTableSegment(new TableNameSegment(0, 0, new IdentifierValue("t_order"))));
-        insertStatement.setInsertColumns(new InsertColumnsSegment(0, 0, Arrays.asList(new ColumnSegment(0, 0, new IdentifierValue("order_id")),
-                new ColumnSegment(0, 0, new IdentifierValue("user_id")), new ColumnSegment(0, 0, new IdentifierValue("status")))));
         SelectStatement subSelectStatement = new SelectStatement(databaseType);
         subSelectStatement.setFrom(new SimpleTableSegment(new TableNameSegment(0, 0, new IdentifierValue("t_order"))));
         ProjectionsSegment projections = new ProjectionsSegment(0, 0);
@@ -107,9 +105,14 @@ class InsertStatementBinderTest {
         projections.getProjections().add(new ColumnProjectionSegment(new ColumnSegment(0, 0, new IdentifierValue("user_id"))));
         projections.getProjections().add(new ColumnProjectionSegment(new ColumnSegment(0, 0, new IdentifierValue("status"))));
         subSelectStatement.setProjections(projections);
-        insertStatement.setInsertSelect(new SubquerySegment(0, 0, subSelectStatement, ""));
-        insertStatement.getValues().add(new InsertValuesSegment(0, 0, Arrays.asList(new LiteralExpressionSegment(0, 0, 1),
-                new LiteralExpressionSegment(0, 0, 1), new LiteralExpressionSegment(0, 0, "OK"))));
+        InsertStatement insertStatement = InsertStatement.builder().databaseType(databaseType)
+                .table(new SimpleTableSegment(new TableNameSegment(0, 0, new IdentifierValue("t_order"))))
+                .insertColumns(new InsertColumnsSegment(0, 0, Arrays.asList(new ColumnSegment(0, 0, new IdentifierValue("order_id")),
+                        new ColumnSegment(0, 0, new IdentifierValue("user_id")), new ColumnSegment(0, 0, new IdentifierValue("status")))))
+                .insertSelect(new SubquerySegment(0, 0, subSelectStatement, ""))
+                .values(Collections.singletonList(new InsertValuesSegment(0, 0, Arrays.asList(new LiteralExpressionSegment(0, 0, 1),
+                        new LiteralExpressionSegment(0, 0, 1), new LiteralExpressionSegment(0, 0, "OK")))))
+                .build();
         InsertStatement actual = new InsertStatementBinder().bind(insertStatement, new SQLStatementBinderContext(createMetaData(), "foo_db", new HintValueContext(), insertStatement));
         assertThat(actual, not(insertStatement));
         assertTrue(actual.getTable().isPresent());
@@ -122,8 +125,6 @@ class InsertStatementBinderTest {
     
     @Test
     void assertBindInsertSelectWithoutColumns() {
-        InsertStatement insertStatement = new InsertStatement(databaseType);
-        insertStatement.setTable(new SimpleTableSegment(new TableNameSegment(0, 0, new IdentifierValue("t_order"))));
         SelectStatement subSelectStatement = new SelectStatement(databaseType);
         subSelectStatement.setFrom(new SimpleTableSegment(new TableNameSegment(0, 0, new IdentifierValue("t_order"))));
         ProjectionsSegment projections = new ProjectionsSegment(0, 0);
@@ -131,9 +132,12 @@ class InsertStatementBinderTest {
         projections.getProjections().add(new ColumnProjectionSegment(new ColumnSegment(0, 0, new IdentifierValue("user_id"))));
         projections.getProjections().add(new ColumnProjectionSegment(new ColumnSegment(0, 0, new IdentifierValue("status"))));
         subSelectStatement.setProjections(projections);
-        insertStatement.setInsertSelect(new SubquerySegment(0, 0, subSelectStatement, ""));
-        insertStatement.getValues().add(new InsertValuesSegment(0, 0, Arrays.asList(new LiteralExpressionSegment(0, 0, 1),
-                new LiteralExpressionSegment(0, 0, 1), new LiteralExpressionSegment(0, 0, "OK"))));
+        InsertStatement insertStatement = InsertStatement.builder().databaseType(databaseType)
+                .table(new SimpleTableSegment(new TableNameSegment(0, 0, new IdentifierValue("t_order"))))
+                .insertSelect(new SubquerySegment(0, 0, subSelectStatement, ""))
+                .values(Collections.singletonList(new InsertValuesSegment(0, 0, Arrays.asList(new LiteralExpressionSegment(0, 0, 1),
+                        new LiteralExpressionSegment(0, 0, 1), new LiteralExpressionSegment(0, 0, "OK")))))
+                .build();
         InsertStatement actual = new InsertStatementBinder().bind(insertStatement, new SQLStatementBinderContext(createMetaData(), "foo_db", new HintValueContext(), insertStatement));
         assertThat(actual, not(insertStatement));
         assertTrue(actual.getTable().isPresent());
diff --git a/kernel/sql-federation/compiler/src/test/java/org/apache/shardingsphere/sqlfederation/compiler/sql/ast/converter/SQLNodeConverterEngineTest.java b/kernel/sql-federation/compiler/src/test/java/org/apache/shardingsphere/sqlfederation/compiler/sql/ast/converter/SQLNodeConverterEngineTest.java
index 502acdf0a76..3f562429804 100644
--- a/kernel/sql-federation/compiler/src/test/java/org/apache/shardingsphere/sqlfederation/compiler/sql/ast/converter/SQLNodeConverterEngineTest.java
+++ b/kernel/sql-federation/compiler/src/test/java/org/apache/shardingsphere/sqlfederation/compiler/sql/ast/converter/SQLNodeConverterEngineTest.java
@@ -75,7 +75,7 @@ class SQLNodeConverterEngineTest {
         try (
                 MockedConstruction<InsertStatementConverter> ignored = mockConstruction(InsertStatementConverter.class,
                         (mock, context) -> when(mock.convert(any(InsertStatement.class))).thenReturn(insertSqlNode))) {
-            InsertStatement insertStatement = new InsertStatement(databaseType);
+            InsertStatement insertStatement = InsertStatement.builder().databaseType(databaseType).build();
             SqlNode actual = SQLNodeConverterEngine.convert(insertStatement);
             assertThat(actual, is(insertSqlNode));
         }
diff --git a/kernel/sql-federation/compiler/src/test/java/org/apache/shardingsphere/sqlfederation/compiler/sql/ast/converter/statement/type/ExplainStatementConverterTest.java b/kernel/sql-federation/compiler/src/test/java/org/apache/shardingsphere/sqlfederation/compiler/sql/ast/converter/statement/type/ExplainStatementConverterTest.java
index e0f19151907..4730fc936c9 100644
--- a/kernel/sql-federation/compiler/src/test/java/org/apache/shardingsphere/sqlfederation/compiler/sql/ast/converter/statement/type/ExplainStatementConverterTest.java
+++ b/kernel/sql-federation/compiler/src/test/java/org/apache/shardingsphere/sqlfederation/compiler/sql/ast/converter/statement/type/ExplainStatementConverterTest.java
@@ -106,10 +106,8 @@ class ExplainStatementConverterTest {
     }
     
     private InsertStatement createInsertStatement() {
-        InsertStatement result = new InsertStatement(databaseType);
-        result.setTable(new SimpleTableSegment(new TableNameSegment(0, 0, new IdentifierValue("t_insert"))));
-        result.getValues().add(new InsertValuesSegment(0, 0, Collections.singletonList(new ParameterMarkerExpressionSegment(0, 0, 0))));
-        return result;
+        return InsertStatement.builder().databaseType(databaseType).table(new SimpleTableSegment(new TableNameSegment(0, 0, new IdentifierValue("t_insert"))))
+                .values(Collections.singletonList(new InsertValuesSegment(0, 0, Collections.singletonList(new ParameterMarkerExpressionSegment(0, 0, 0))))).build();
     }
     
     private ProjectionsSegment createProjectionsSegment() {
diff --git a/kernel/sql-federation/compiler/src/test/java/org/apache/shardingsphere/sqlfederation/compiler/sql/ast/converter/statement/type/InsertStatementConverterTest.java b/kernel/sql-federation/compiler/src/test/java/org/apache/shardingsphere/sqlfederation/compiler/sql/ast/converter/statement/type/InsertStatementConverterTest.java
index 314fe584ca3..0811fced543 100644
--- a/kernel/sql-federation/compiler/src/test/java/org/apache/shardingsphere/sqlfederation/compiler/sql/ast/converter/statement/type/InsertStatementConverterTest.java
+++ b/kernel/sql-federation/compiler/src/test/java/org/apache/shardingsphere/sqlfederation/compiler/sql/ast/converter/statement/type/InsertStatementConverterTest.java
@@ -51,22 +51,21 @@ class InsertStatementConverterTest {
     
     @Test
     void assertConvertWithInsertSelect() {
-        InsertStatement insertStatement = new InsertStatement(databaseType);
-        insertStatement.setTable(new SimpleTableSegment(new TableNameSegment(0, 0, new IdentifierValue("t_insert_select"))));
         SelectStatement selectStatement = new SelectStatement(databaseType);
         selectStatement.setProjections(createProjectionsSegment());
-        insertStatement.setInsertSelect(new SubquerySegment(0, 0, selectStatement, "select"));
+        InsertStatement insertStatement = InsertStatement.builder().databaseType(databaseType)
+                .table(new SimpleTableSegment(new TableNameSegment(0, 0, new IdentifierValue("t_insert_select"))))
+                .insertSelect(new SubquerySegment(0, 0, selectStatement, "select")).build();
         SqlInsert actual = (SqlInsert) new InsertStatementConverter().convert(insertStatement);
         assertThat(actual.getSource(), isA(SqlNode.class));
     }
     
     @Test
     void assertConvertWithSetAssignmentColumns() {
-        InsertStatement insertStatement = new InsertStatement(databaseType);
-        insertStatement.setTable(new SimpleTableSegment(new TableNameSegment(0, 0, new IdentifierValue("t_insert_set"))));
         SetAssignmentSegment setAssignment = createSetAssignmentSegment();
-        insertStatement.setSetAssignment(setAssignment);
-        insertStatement.setInsertColumns(new InsertColumnsSegment(0, 0, Collections.emptyList()));
+        InsertStatement insertStatement = InsertStatement.builder().databaseType(databaseType)
+                .table(new SimpleTableSegment(new TableNameSegment(0, 0, new IdentifierValue("t_insert_set"))))
+                .setAssignment(setAssignment).insertColumns(new InsertColumnsSegment(0, 0, Collections.emptyList())).build();
         SqlInsert actual = (SqlInsert) new InsertStatementConverter().convert(insertStatement);
         assertThat(actual.getTargetTable(), isA(SqlNode.class));
         assertThat(actual.getSource(), isA(SqlBasicCall.class));
@@ -75,9 +74,9 @@ class InsertStatementConverterTest {
     
     @Test
     void assertConvertWithValuesOnly() {
-        InsertStatement insertStatement = new InsertStatement(databaseType);
-        insertStatement.setTable(new SimpleTableSegment(new TableNameSegment(0, 0, new IdentifierValue("t_insert_values"))));
-        insertStatement.getValues().add(new InsertValuesSegment(0, 0, Collections.singletonList(new ParameterMarkerExpressionSegment(0, 0, 0))));
+        InsertStatement insertStatement = InsertStatement.builder().databaseType(databaseType)
+                .table(new SimpleTableSegment(new TableNameSegment(0, 0, new IdentifierValue("t_insert_values"))))
+                .values(Collections.singletonList(new InsertValuesSegment(0, 0, Collections.singletonList(new ParameterMarkerExpressionSegment(0, 0, 0))))).build();
         SqlInsert actual = (SqlInsert) new InsertStatementConverter().convert(insertStatement);
         assertThat(actual.getSource(), isA(SqlBasicCall.class));
         assertNull(actual.getTargetColumnList());
@@ -85,11 +84,11 @@ class InsertStatementConverterTest {
     
     @Test
     void assertConvertWithExplicitColumns() {
-        InsertStatement insertStatement = new InsertStatement(databaseType);
-        insertStatement.setTable(new SimpleTableSegment(new TableNameSegment(0, 0, new IdentifierValue("t_insert_columns"))));
         InsertColumnsSegment insertColumnsSegment = new InsertColumnsSegment(0, 0, Collections.singletonList(new ColumnSegment(0, 0, new IdentifierValue("col"))));
-        insertStatement.setInsertColumns(insertColumnsSegment);
-        insertStatement.getValues().add(new InsertValuesSegment(0, 0, Collections.singletonList(new ParameterMarkerExpressionSegment(0, 0, 0))));
+        InsertStatement insertStatement = InsertStatement.builder().databaseType(databaseType)
+                .table(new SimpleTableSegment(new TableNameSegment(0, 0, new IdentifierValue("t_insert_columns"))))
+                .insertColumns(insertColumnsSegment)
+                .values(Collections.singletonList(new InsertValuesSegment(0, 0, Collections.singletonList(new ParameterMarkerExpressionSegment(0, 0, 0))))).build();
         SqlInsert actual = (SqlInsert) new InsertStatementConverter().convert(insertStatement);
         assertThat(actual.getTargetColumnList(), isA(SqlNodeList.class));
     }
diff --git a/kernel/transaction/core/src/test/java/org/apache/shardingsphere/transaction/util/AutoCommitUtilsTest.java b/kernel/transaction/core/src/test/java/org/apache/shardingsphere/transaction/util/AutoCommitUtilsTest.java
index a63dc8a47de..f46fca3966a 100644
--- a/kernel/transaction/core/src/test/java/org/apache/shardingsphere/transaction/util/AutoCommitUtilsTest.java
+++ b/kernel/transaction/core/src/test/java/org/apache/shardingsphere/transaction/util/AutoCommitUtilsTest.java
@@ -41,7 +41,7 @@ class AutoCommitUtilsTest {
     
     @Test
     void assertIsNeedStartTransactionWithDML() {
-        assertTrue(AutoCommitUtils.isNeedStartTransaction(new InsertStatement(databaseType)));
+        assertTrue(AutoCommitUtils.isNeedStartTransaction(InsertStatement.builder().databaseType(databaseType).build()));
     }
     
     @Test
diff --git a/parser/sql/engine/dialect/clickhouse/src/main/java/org/apache/shardingsphere/sql/parser/engine/clickhouse/visitor/statement/type/ClickHouseDMLStatementVisitor.java b/parser/sql/engine/dialect/clickhouse/src/main/java/org/apache/shardingsphere/sql/parser/engine/clickhouse/visitor/statement/type/ClickHouseDMLStatementVisitor.java
index a3d742fc627..a593a55ecc5 100644
--- a/parser/sql/engine/dialect/clickhouse/src/main/java/org/apache/shardingsphere/sql/parser/engine/clickhouse/visitor/statement/type/ClickHouseDMLStatementVisitor.java
+++ b/parser/sql/engine/dialect/clickhouse/src/main/java/org/apache/shardingsphere/sql/parser/engine/clickhouse/visitor/statement/type/ClickHouseDMLStatementVisitor.java
@@ -86,8 +86,21 @@ public final class ClickHouseDMLStatementVisitor extends ClickHouseStatementVisi
     
     @Override
     public ASTNode visitInsert(final InsertContext ctx) {
-        InsertStatement result = (InsertStatement) visit(ctx.insertValuesClause());
-        result.setTable((SimpleTableSegment) visit(ctx.tableName()));
+        InsertStatement insertValuesStatement = (InsertStatement) visit(ctx.insertValuesClause());
+        InsertStatement result = InsertStatement.builder().databaseType(getDatabaseType()).table((SimpleTableSegment) visit(ctx.tableName()))
+                .insertColumns(insertValuesStatement.getInsertColumns().orElse(null)).insertSelect(insertValuesStatement.getInsertSelect().orElse(null))
+                .setAssignment(insertValuesStatement.getSetAssignment().orElse(null)).onDuplicateKeyColumns(insertValuesStatement.getOnDuplicateKeyColumns().orElse(null))
+                .valueReference(insertValuesStatement.getValueReference().orElse(null)).returning(insertValuesStatement.getReturning().orElse(null))
+                .output(insertValuesStatement.getOutput().orElse(null)).with(insertValuesStatement.getWith().orElse(null))
+                .multiTableInsertType(insertValuesStatement.getMultiTableInsertType().orElse(null))
+                .multiTableInsertInto(insertValuesStatement.getMultiTableInsertInto().orElse(null))
+                .multiTableConditionalInto(insertValuesStatement.getMultiTableConditionalInto().orElse(null)).where(insertValuesStatement.getWhere().orElse(null))
+                .exec(insertValuesStatement.getExec().orElse(null)).withTableHint(insertValuesStatement.getWithTableHint().orElse(null))
+                .rowSetFunction(insertValuesStatement.getRowSetFunction().orElse(null)).ignore(insertValuesStatement.isIgnore()).replace(insertValuesStatement.isReplace())
+                .values(new LinkedList<>(insertValuesStatement.getValues())).derivedInsertColumns(new LinkedList<>(insertValuesStatement.getDerivedInsertColumns())).build();
+        result.addParameterMarkers(insertValuesStatement.getParameterMarkers());
+        result.getVariableNames().addAll(insertValuesStatement.getVariableNames());
+        result.getComments().addAll(insertValuesStatement.getComments());
         result.addParameterMarkers(getParameterMarkerSegments());
         return result;
     }
@@ -95,16 +108,16 @@ public final class ClickHouseDMLStatementVisitor extends ClickHouseStatementVisi
     @SuppressWarnings("unchecked")
     @Override
     public ASTNode visitInsertValuesClause(final InsertValuesClauseContext ctx) {
-        InsertStatement result = new InsertStatement(getDatabaseType());
+        InsertColumnsSegment insertColumns;
         if (null != ctx.columnNames()) {
             ColumnNamesContext columnNames = ctx.columnNames();
             CollectionValue<ColumnSegment> columnSegments = (CollectionValue<ColumnSegment>) visit(columnNames);
-            result.setInsertColumns(new InsertColumnsSegment(columnNames.start.getStartIndex(), columnNames.stop.getStopIndex(), columnSegments.getValue()));
+            insertColumns = new InsertColumnsSegment(columnNames.start.getStartIndex(), columnNames.stop.getStopIndex(), columnSegments.getValue());
         } else {
-            result.setInsertColumns(new InsertColumnsSegment(ctx.start.getStartIndex() - 1, ctx.start.getStartIndex() - 1, Collections.emptyList()));
+            insertColumns = new InsertColumnsSegment(ctx.start.getStartIndex() - 1, ctx.start.getStartIndex() - 1, Collections.emptyList());
         }
-        result.getValues().addAll(ctx.assignmentValues().stream().map(each -> (InsertValuesSegment) visit(each)).collect(Collectors.toList()));
-        return result;
+        return InsertStatement.builder().databaseType(getDatabaseType()).insertColumns(insertColumns)
+                .values(ctx.assignmentValues().stream().map(each -> (InsertValuesSegment) visit(each)).collect(Collectors.toList())).build();
     }
     
     @Override
diff --git a/parser/sql/engine/dialect/doris/src/main/java/org/apache/shardingsphere/sql/parser/engine/doris/visitor/statement/DorisStatementVisitor.java b/parser/sql/engine/dialect/doris/src/main/java/org/apache/shardingsphere/sql/parser/engine/doris/visitor/statement/DorisStatementVisitor.java
index f268d684109..598a66a3762 100644
--- a/parser/sql/engine/dialect/doris/src/main/java/org/apache/shardingsphere/sql/parser/engine/doris/visitor/statement/DorisStatementVisitor.java
+++ b/parser/sql/engine/dialect/doris/src/main/java/org/apache/shardingsphere/sql/parser/engine/doris/visitor/statement/DorisStatementVisitor.java
@@ -1549,37 +1549,45 @@ public abstract class DorisStatementVisitor extends DorisStatementBaseVisitor<AS
     @Override
     public ASTNode visitInsert(final InsertContext ctx) {
         // TODO :FIXME, since there is no segment for insertValuesClause, InsertStatement is created by sub rule.
-        InsertStatement result;
+        InsertStatement insertStatement;
         if (null != ctx.insertValuesClause()) {
-            result = (InsertStatement) visit(ctx.insertValuesClause());
+            insertStatement = (InsertStatement) visit(ctx.insertValuesClause());
         } else if (null != ctx.insertSelectClause()) {
-            result = (InsertStatement) visit(ctx.insertSelectClause());
+            insertStatement = (InsertStatement) visit(ctx.insertSelectClause());
         } else {
-            result = new InsertStatement(databaseType);
-            result.setSetAssignment((SetAssignmentSegment) visit(ctx.setAssignmentsClause()));
-        }
-        if (null != ctx.onDuplicateKeyClause()) {
-            result.setOnDuplicateKeyColumns((OnDuplicateKeyColumnsSegment) visit(ctx.onDuplicateKeyClause()));
-        }
-        result.setTable((SimpleTableSegment) visit(ctx.tableName()));
+            insertStatement = InsertStatement.builder().databaseType(databaseType).setAssignment((SetAssignmentSegment) visit(ctx.setAssignmentsClause())).build();
+        }
+        InsertStatement result = InsertStatement.builder().databaseType(databaseType).table((SimpleTableSegment) visit(ctx.tableName()))
+                .insertColumns(insertStatement.getInsertColumns().orElse(null)).insertSelect(insertStatement.getInsertSelect().orElse(null))
+                .setAssignment(insertStatement.getSetAssignment().orElse(null))
+                .onDuplicateKeyColumns(null == ctx.onDuplicateKeyClause() ? insertStatement.getOnDuplicateKeyColumns().orElse(null) : (OnDuplicateKeyColumnsSegment) visit(ctx.onDuplicateKeyClause()))
+                .valueReference(insertStatement.getValueReference().orElse(null)).returning(insertStatement.getReturning().orElse(null))
+                .output(insertStatement.getOutput().orElse(null)).with(insertStatement.getWith().orElse(null))
+                .multiTableInsertType(insertStatement.getMultiTableInsertType().orElse(null)).multiTableInsertInto(insertStatement.getMultiTableInsertInto().orElse(null))
+                .multiTableConditionalInto(insertStatement.getMultiTableConditionalInto().orElse(null)).where(insertStatement.getWhere().orElse(null))
+                .exec(insertStatement.getExec().orElse(null)).withTableHint(insertStatement.getWithTableHint().orElse(null))
+                .rowSetFunction(insertStatement.getRowSetFunction().orElse(null)).ignore(insertStatement.isIgnore()).replace(insertStatement.isReplace())
+                .values(new LinkedList<>(insertStatement.getValues())).derivedInsertColumns(new LinkedList<>(insertStatement.getDerivedInsertColumns())).build();
+        result.addParameterMarkers(insertStatement.getParameterMarkers());
+        result.getVariableNames().addAll(insertStatement.getVariableNames());
+        result.getComments().addAll(insertStatement.getComments());
         result.addParameterMarkers(getParameterMarkerSegments());
         return result;
     }
     
     @Override
     public ASTNode visitInsertSelectClause(final InsertSelectClauseContext ctx) {
-        InsertStatement result = new InsertStatement(databaseType);
-        result.setInsertSelect(createInsertSelectSegment(ctx));
+        InsertColumnsSegment insertColumns;
         if (null != ctx.LP_()) {
             if (null != ctx.fields()) {
-                result.setInsertColumns(new InsertColumnsSegment(ctx.LP_().getSymbol().getStartIndex(), ctx.RP_().getSymbol().getStopIndex(), createInsertColumns(ctx.fields())));
+                insertColumns = new InsertColumnsSegment(ctx.LP_().getSymbol().getStartIndex(), ctx.RP_().getSymbol().getStopIndex(), createInsertColumns(ctx.fields()));
             } else {
-                result.setInsertColumns(new InsertColumnsSegment(ctx.LP_().getSymbol().getStartIndex(), ctx.RP_().getSymbol().getStopIndex(), Collections.emptyList()));
+                insertColumns = new InsertColumnsSegment(ctx.LP_().getSymbol().getStartIndex(), ctx.RP_().getSymbol().getStopIndex(), Collections.emptyList());
             }
         } else {
-            result.setInsertColumns(new InsertColumnsSegment(ctx.start.getStartIndex() - 1, ctx.start.getStartIndex() - 1, Collections.emptyList()));
+            insertColumns = new InsertColumnsSegment(ctx.start.getStartIndex() - 1, ctx.start.getStartIndex() - 1, Collections.emptyList());
         }
-        return result;
+        return InsertStatement.builder().databaseType(databaseType).insertColumns(insertColumns).insertSelect(createInsertSelectSegment(ctx)).build();
     }
     
     private SubquerySegment createInsertSelectSegment(final InsertSelectClauseContext ctx) {
@@ -1590,18 +1598,17 @@ public abstract class DorisStatementVisitor extends DorisStatementBaseVisitor<AS
     
     @Override
     public ASTNode visitInsertValuesClause(final InsertValuesClauseContext ctx) {
-        InsertStatement result = new InsertStatement(databaseType);
+        InsertColumnsSegment insertColumns;
         if (null != ctx.LP_()) {
             if (null != ctx.fields()) {
-                result.setInsertColumns(new InsertColumnsSegment(ctx.LP_().getSymbol().getStartIndex(), ctx.RP_().getSymbol().getStopIndex(), createInsertColumns(ctx.fields())));
+                insertColumns = new InsertColumnsSegment(ctx.LP_().getSymbol().getStartIndex(), ctx.RP_().getSymbol().getStopIndex(), createInsertColumns(ctx.fields()));
             } else {
-                result.setInsertColumns(new InsertColumnsSegment(ctx.LP_().getSymbol().getStartIndex(), ctx.RP_().getSymbol().getStopIndex(), Collections.emptyList()));
+                insertColumns = new InsertColumnsSegment(ctx.LP_().getSymbol().getStartIndex(), ctx.RP_().getSymbol().getStopIndex(), Collections.emptyList());
             }
         } else {
-            result.setInsertColumns(new InsertColumnsSegment(ctx.start.getStartIndex() - 1, ctx.start.getStartIndex() - 1, Collections.emptyList()));
+            insertColumns = new InsertColumnsSegment(ctx.start.getStartIndex() - 1, ctx.start.getStartIndex() - 1, Collections.emptyList());
         }
-        result.getValues().addAll(createInsertValuesSegments(ctx.assignmentValues()));
-        return result;
+        return InsertStatement.builder().databaseType(databaseType).insertColumns(insertColumns).values(createInsertValuesSegments(ctx.assignmentValues())).build();
     }
     
     private Collection<InsertValuesSegment> createInsertValuesSegments(final Collection<AssignmentValuesContext> assignmentValuesContexts) {
@@ -1630,28 +1637,38 @@ public abstract class DorisStatementVisitor extends DorisStatementBaseVisitor<AS
         } else if (null != ctx.replaceSelectClause()) {
             result = (InsertStatement) visit(ctx.replaceSelectClause());
         } else {
-            result = new InsertStatement(databaseType);
-            result.setSetAssignment((SetAssignmentSegment) visit(ctx.setAssignmentsClause()));
-        }
-        result.setTable((SimpleTableSegment) visit(ctx.tableName()));
-        result.addParameterMarkers(getParameterMarkerSegments());
-        return result;
+            result = InsertStatement.builder().databaseType(databaseType).setAssignment((SetAssignmentSegment) visit(ctx.setAssignmentsClause())).build();
+        }
+        InsertStatement actual = InsertStatement.builder().databaseType(databaseType).table((SimpleTableSegment) visit(ctx.tableName()))
+                .insertColumns(result.getInsertColumns().orElse(null)).insertSelect(result.getInsertSelect().orElse(null))
+                .setAssignment(result.getSetAssignment().orElse(null)).onDuplicateKeyColumns(result.getOnDuplicateKeyColumns().orElse(null))
+                .valueReference(result.getValueReference().orElse(null)).returning(result.getReturning().orElse(null))
+                .output(result.getOutput().orElse(null)).with(result.getWith().orElse(null))
+                .multiTableInsertType(result.getMultiTableInsertType().orElse(null)).multiTableInsertInto(result.getMultiTableInsertInto().orElse(null))
+                .multiTableConditionalInto(result.getMultiTableConditionalInto().orElse(null)).where(result.getWhere().orElse(null))
+                .exec(result.getExec().orElse(null)).withTableHint(result.getWithTableHint().orElse(null))
+                .rowSetFunction(result.getRowSetFunction().orElse(null)).ignore(result.isIgnore()).replace(result.isReplace())
+                .values(new LinkedList<>(result.getValues())).derivedInsertColumns(new LinkedList<>(result.getDerivedInsertColumns())).build();
+        actual.addParameterMarkers(result.getParameterMarkers());
+        actual.getVariableNames().addAll(result.getVariableNames());
+        actual.getComments().addAll(result.getComments());
+        actual.addParameterMarkers(getParameterMarkerSegments());
+        return actual;
     }
     
     @Override
     public ASTNode visitReplaceSelectClause(final ReplaceSelectClauseContext ctx) {
-        InsertStatement result = new InsertStatement(databaseType);
+        InsertColumnsSegment insertColumns;
         if (null != ctx.LP_()) {
             if (null != ctx.fields()) {
-                result.setInsertColumns(new InsertColumnsSegment(ctx.LP_().getSymbol().getStartIndex(), ctx.RP_().getSymbol().getStopIndex(), createInsertColumns(ctx.fields())));
+                insertColumns = new InsertColumnsSegment(ctx.LP_().getSymbol().getStartIndex(), ctx.RP_().getSymbol().getStopIndex(), createInsertColumns(ctx.fields()));
             } else {
-                result.setInsertColumns(new InsertColumnsSegment(ctx.LP_().getSymbol().getStartIndex(), ctx.RP_().getSymbol().getStopIndex(), Collections.emptyList()));
+                insertColumns = new InsertColumnsSegment(ctx.LP_().getSymbol().getStartIndex(), ctx.RP_().getSymbol().getStopIndex(), Collections.emptyList());
             }
         } else {
-            result.setInsertColumns(new InsertColumnsSegment(ctx.start.getStartIndex() - 1, ctx.start.getStartIndex() - 1, Collections.emptyList()));
+            insertColumns = new InsertColumnsSegment(ctx.start.getStartIndex() - 1, ctx.start.getStartIndex() - 1, Collections.emptyList());
         }
-        result.setInsertSelect(createReplaceSelectSegment(ctx));
-        return result;
+        return InsertStatement.builder().databaseType(databaseType).insertColumns(insertColumns).insertSelect(createReplaceSelectSegment(ctx)).build();
     }
     
     private SubquerySegment createReplaceSelectSegment(final ReplaceSelectClauseContext ctx) {
@@ -1661,18 +1678,17 @@ public abstract class DorisStatementVisitor extends DorisStatementBaseVisitor<AS
     
     @Override
     public ASTNode visitReplaceValuesClause(final ReplaceValuesClauseContext ctx) {
-        InsertStatement result = new InsertStatement(databaseType);
+        InsertColumnsSegment insertColumns;
         if (null != ctx.LP_()) {
             if (null != ctx.fields()) {
-                result.setInsertColumns(new InsertColumnsSegment(ctx.LP_().getSymbol().getStartIndex(), ctx.RP_().getSymbol().getStopIndex(), createInsertColumns(ctx.fields())));
+                insertColumns = new InsertColumnsSegment(ctx.LP_().getSymbol().getStartIndex(), ctx.RP_().getSymbol().getStopIndex(), createInsertColumns(ctx.fields()));
             } else {
-                result.setInsertColumns(new InsertColumnsSegment(ctx.LP_().getSymbol().getStartIndex(), ctx.RP_().getSymbol().getStopIndex(), Collections.emptyList()));
+                insertColumns = new InsertColumnsSegment(ctx.LP_().getSymbol().getStartIndex(), ctx.RP_().getSymbol().getStopIndex(), Collections.emptyList());
             }
         } else {
-            result.setInsertColumns(new InsertColumnsSegment(ctx.start.getStartIndex() - 1, ctx.start.getStartIndex() - 1, Collections.emptyList()));
+            insertColumns = new InsertColumnsSegment(ctx.start.getStartIndex() - 1, ctx.start.getStartIndex() - 1, Collections.emptyList());
         }
-        result.getValues().addAll(createInsertValuesSegments(ctx.assignmentValues()));
-        return result;
+        return InsertStatement.builder().databaseType(databaseType).insertColumns(insertColumns).values(createInsertValuesSegments(ctx.assignmentValues())).build();
     }
     
     private List<ColumnSegment> createInsertColumns(final FieldsContext fields) {
diff --git a/parser/sql/engine/dialect/firebird/src/main/java/org/apache/shardingsphere/sql/parser/engine/firebird/visitor/statement/type/FirebirdDMLStatementVisitor.java b/parser/sql/engine/dialect/firebird/src/main/java/org/apache/shardingsphere/sql/parser/engine/firebird/visitor/statement/type/FirebirdDMLStatementVisitor.java
index c50881609be..4f44684b875 100644
--- a/parser/sql/engine/dialect/firebird/src/main/java/org/apache/shardingsphere/sql/parser/engine/firebird/visitor/statement/type/FirebirdDMLStatementVisitor.java
+++ b/parser/sql/engine/dialect/firebird/src/main/java/org/apache/shardingsphere/sql/parser/engine/firebird/visitor/statement/type/FirebirdDMLStatementVisitor.java
@@ -126,28 +126,38 @@ public final class FirebirdDMLStatementVisitor extends FirebirdStatementVisitor
     
     @Override
     public ASTNode visitInsert(final InsertContext ctx) {
-        InsertStatement result = (InsertStatement) visit(ctx.insertValuesClause());
-        result.setTable((SimpleTableSegment) visit(ctx.tableName()));
+        InsertStatement insertValuesStatement = (InsertStatement) visit(ctx.insertValuesClause());
+        InsertStatement result = InsertStatement.builder().databaseType(getDatabaseType()).table((SimpleTableSegment) visit(ctx.tableName()))
+                .insertColumns(insertValuesStatement.getInsertColumns().orElse(null)).insertSelect(insertValuesStatement.getInsertSelect().orElse(null))
+                .setAssignment(insertValuesStatement.getSetAssignment().orElse(null)).onDuplicateKeyColumns(insertValuesStatement.getOnDuplicateKeyColumns().orElse(null))
+                .valueReference(insertValuesStatement.getValueReference().orElse(null))
+                .returning(null == ctx.returningClause() ? insertValuesStatement.getReturning().orElse(null) : (ReturningSegment) visit(ctx.returningClause()))
+                .output(insertValuesStatement.getOutput().orElse(null)).with(insertValuesStatement.getWith().orElse(null))
+                .multiTableInsertType(insertValuesStatement.getMultiTableInsertType().orElse(null))
+                .multiTableInsertInto(insertValuesStatement.getMultiTableInsertInto().orElse(null))
+                .multiTableConditionalInto(insertValuesStatement.getMultiTableConditionalInto().orElse(null)).where(insertValuesStatement.getWhere().orElse(null))
+                .exec(insertValuesStatement.getExec().orElse(null)).withTableHint(insertValuesStatement.getWithTableHint().orElse(null))
+                .rowSetFunction(insertValuesStatement.getRowSetFunction().orElse(null)).ignore(insertValuesStatement.isIgnore()).replace(insertValuesStatement.isReplace())
+                .values(new LinkedList<>(insertValuesStatement.getValues())).derivedInsertColumns(new LinkedList<>(insertValuesStatement.getDerivedInsertColumns())).build();
+        result.addParameterMarkers(insertValuesStatement.getParameterMarkers());
+        result.getVariableNames().addAll(insertValuesStatement.getVariableNames());
+        result.getComments().addAll(insertValuesStatement.getComments());
         result.addParameterMarkers(getParameterMarkerSegments());
-        if (null != ctx.returningClause()) {
-            result.setReturning((ReturningSegment) visit(ctx.returningClause()));
-        }
         return result;
     }
     
     @SuppressWarnings("unchecked")
     @Override
     public ASTNode visitInsertValuesClause(final InsertValuesClauseContext ctx) {
-        InsertStatement result = new InsertStatement(getDatabaseType());
+        InsertColumnsSegment insertColumns;
         if (null != ctx.columnNames()) {
             ColumnNamesContext columnNames = ctx.columnNames();
             CollectionValue<ColumnSegment> columnSegments = (CollectionValue<ColumnSegment>) visit(columnNames);
-            result.setInsertColumns(new InsertColumnsSegment(columnNames.start.getStartIndex(), columnNames.stop.getStopIndex(), columnSegments.getValue()));
+            insertColumns = new InsertColumnsSegment(columnNames.start.getStartIndex(), columnNames.stop.getStopIndex(), columnSegments.getValue());
         } else {
-            result.setInsertColumns(new InsertColumnsSegment(ctx.start.getStartIndex() - 1, ctx.start.getStartIndex() - 1, Collections.emptyList()));
+            insertColumns = new InsertColumnsSegment(ctx.start.getStartIndex() - 1, ctx.start.getStartIndex() - 1, Collections.emptyList());
         }
-        result.getValues().addAll(createInsertValuesSegments(ctx.assignmentValues()));
-        return result;
+        return InsertStatement.builder().databaseType(getDatabaseType()).insertColumns(insertColumns).values(createInsertValuesSegments(ctx.assignmentValues())).build();
     }
     
     private Collection<InsertValuesSegment> createInsertValuesSegments(final Collection<AssignmentValuesContext> assignmentValuesContexts) {
diff --git a/parser/sql/engine/dialect/hive/src/main/java/org/apache/shardingsphere/sql/parser/engine/hive/visitor/statement/type/HiveDMLStatementVisitor.java b/parser/sql/engine/dialect/hive/src/main/java/org/apache/shardingsphere/sql/parser/engine/hive/visitor/statement/type/HiveDMLStatementVisitor.java
index 69aff4eaf43..a705f478130 100644
--- a/parser/sql/engine/dialect/hive/src/main/java/org/apache/shardingsphere/sql/parser/engine/hive/visitor/statement/type/HiveDMLStatementVisitor.java
+++ b/parser/sql/engine/dialect/hive/src/main/java/org/apache/shardingsphere/sql/parser/engine/hive/visitor/statement/type/HiveDMLStatementVisitor.java
@@ -880,19 +880,28 @@ public final class HiveDMLStatementVisitor extends HiveStatementVisitor implemen
         if (null != ctx.insertingValuesIntoTables()) {
             return visit(ctx.insertingValuesIntoTables());
         }
-        InsertStatement result;
+        InsertStatement insertStatement;
         if (null != ctx.insertValuesClause()) {
-            result = (InsertStatement) visit(ctx.insertValuesClause());
+            insertStatement = (InsertStatement) visit(ctx.insertValuesClause());
         } else if (null != ctx.insertSelectClause()) {
-            result = (InsertStatement) visit(ctx.insertSelectClause());
+            insertStatement = (InsertStatement) visit(ctx.insertSelectClause());
         } else {
-            result = new InsertStatement(getDatabaseType());
-            result.setSetAssignment((SetAssignmentSegment) visit(ctx.setAssignmentsClause()));
-        }
-        if (null != ctx.onDuplicateKeyClause()) {
-            result.setOnDuplicateKeyColumns((OnDuplicateKeyColumnsSegment) visit(ctx.onDuplicateKeyClause()));
-        }
-        result.setTable((SimpleTableSegment) visit(ctx.tableName()));
+            insertStatement = InsertStatement.builder().databaseType(getDatabaseType()).setAssignment((SetAssignmentSegment) visit(ctx.setAssignmentsClause())).build();
+        }
+        InsertStatement result = InsertStatement.builder().databaseType(getDatabaseType()).table((SimpleTableSegment) visit(ctx.tableName()))
+                .insertColumns(insertStatement.getInsertColumns().orElse(null)).insertSelect(insertStatement.getInsertSelect().orElse(null))
+                .setAssignment(insertStatement.getSetAssignment().orElse(null))
+                .onDuplicateKeyColumns(null == ctx.onDuplicateKeyClause() ? insertStatement.getOnDuplicateKeyColumns().orElse(null) : (OnDuplicateKeyColumnsSegment) visit(ctx.onDuplicateKeyClause()))
+                .valueReference(insertStatement.getValueReference().orElse(null)).returning(insertStatement.getReturning().orElse(null))
+                .output(insertStatement.getOutput().orElse(null)).with(insertStatement.getWith().orElse(null))
+                .multiTableInsertType(insertStatement.getMultiTableInsertType().orElse(null)).multiTableInsertInto(insertStatement.getMultiTableInsertInto().orElse(null))
+                .multiTableConditionalInto(insertStatement.getMultiTableConditionalInto().orElse(null)).where(insertStatement.getWhere().orElse(null))
+                .exec(insertStatement.getExec().orElse(null)).withTableHint(insertStatement.getWithTableHint().orElse(null))
+                .rowSetFunction(insertStatement.getRowSetFunction().orElse(null)).ignore(insertStatement.isIgnore()).replace(insertStatement.isReplace())
+                .values(new LinkedList<>(insertStatement.getValues())).derivedInsertColumns(new LinkedList<>(insertStatement.getDerivedInsertColumns())).build();
+        result.addParameterMarkers(insertStatement.getParameterMarkers());
+        result.getVariableNames().addAll(insertStatement.getVariableNames());
+        result.getComments().addAll(insertStatement.getComments());
         result.addParameterMarkers(getParameterMarkerSegments());
         return result;
     }
@@ -945,8 +954,6 @@ public final class HiveDMLStatementVisitor extends HiveStatementVisitor implemen
             single.addParameterMarkers(getParameterMarkerSegments());
             return single;
         }
-        InsertStatement result = new InsertStatement(getDatabaseType());
-        result.setMultiTableInsertType(MultiTableInsertType.ALL);
         MultiTableInsertIntoSegment multiTableInsertInto = new MultiTableInsertIntoSegment(
                 ctx.getStart().getStartIndex(), ctx.getStop().getStopIndex());
         for (HiveInsertStatementContext each : insertStatements) {
@@ -958,7 +965,7 @@ public final class HiveDMLStatementVisitor extends HiveStatementVisitor implemen
             insertStmt.buildAttributes();
             multiTableInsertInto.getInsertStatements().add(insertStmt);
         }
-        result.setMultiTableInsertInto(multiTableInsertInto);
+        InsertStatement result = InsertStatement.builder().databaseType(getDatabaseType()).multiTableInsertType(MultiTableInsertType.ALL).multiTableInsertInto(multiTableInsertInto).build();
         result.addParameterMarkers(getParameterMarkerSegments());
         return result;
     }
@@ -969,23 +976,17 @@ public final class HiveDMLStatementVisitor extends HiveStatementVisitor implemen
     }
     
     private InsertStatement createHiveInsertStatement(final TableNameContext tableName, final SelectContext select, final int startIndex) {
-        InsertStatement result = new InsertStatement(getDatabaseType());
-        result.setTable((SimpleTableSegment) visit(tableName));
-        result.setInsertColumns(new InsertColumnsSegment(startIndex, startIndex, Collections.emptyList()));
-        result.setInsertSelect(createInsertSelectSegment(select));
+        InsertStatement result = InsertStatement.builder().databaseType(getDatabaseType()).table((SimpleTableSegment) visit(tableName))
+                .insertColumns(new InsertColumnsSegment(startIndex, startIndex, Collections.emptyList())).insertSelect(createInsertSelectSegment(select)).build();
         result.addParameterMarkers(getParameterMarkerSegments());
         return result;
     }
     
     @Override
     public ASTNode visitHiveInsertStatement(final HiveInsertStatementContext ctx) {
-        InsertStatement result = new InsertStatement(getDatabaseType());
-        result.setTable((SimpleTableSegment) visit(ctx.tableName()));
-        result.setInsertColumns(new InsertColumnsSegment(ctx.start.getStartIndex(), ctx.start.getStartIndex(), Collections.emptyList()));
-        if (null != ctx.select()) {
-            result.setInsertSelect(createInsertSelectSegment(ctx.select()));
-        }
-        return result;
+        return InsertStatement.builder().databaseType(getDatabaseType()).table((SimpleTableSegment) visit(ctx.tableName()))
+                .insertColumns(new InsertColumnsSegment(ctx.start.getStartIndex(), ctx.start.getStartIndex(), Collections.emptyList()))
+                .insertSelect(null == ctx.select() ? null : createInsertSelectSegment(ctx.select())).build();
     }
     
     @Override
@@ -1013,8 +1014,6 @@ public final class HiveDMLStatementVisitor extends HiveStatementVisitor implemen
             single.addParameterMarkers(getParameterMarkerSegments());
             return single;
         }
-        InsertStatement result = new InsertStatement(getDatabaseType());
-        result.setMultiTableInsertType(MultiTableInsertType.ALL);
         MultiTableInsertIntoSegment multiTableInsertInto = new MultiTableInsertIntoSegment(
                 ctx.getStart().getStartIndex(), ctx.getStop().getStopIndex());
         for (InsertOverwriteStandardSyntaxContext each : statements) {
@@ -1026,7 +1025,7 @@ public final class HiveDMLStatementVisitor extends HiveStatementVisitor implemen
             insertStmt.buildAttributes();
             multiTableInsertInto.getInsertStatements().add(insertStmt);
         }
-        result.setMultiTableInsertInto(multiTableInsertInto);
+        InsertStatement result = InsertStatement.builder().databaseType(getDatabaseType()).multiTableInsertType(MultiTableInsertType.ALL).multiTableInsertInto(multiTableInsertInto).build();
         result.addParameterMarkers(getParameterMarkerSegments());
         return result;
     }
@@ -1037,17 +1036,28 @@ public final class HiveDMLStatementVisitor extends HiveStatementVisitor implemen
     }
     
     private InsertStatement createHiveInsertStatementForDirectory(final SelectContext select, final int startIndex) {
-        InsertStatement result = new InsertStatement(getDatabaseType());
-        result.setInsertColumns(new InsertColumnsSegment(startIndex, startIndex, Collections.emptyList()));
-        result.setInsertSelect(createInsertSelectSegment(select));
+        InsertStatement result = InsertStatement.builder().databaseType(getDatabaseType())
+                .insertColumns(new InsertColumnsSegment(startIndex, startIndex, Collections.emptyList())).insertSelect(createInsertSelectSegment(select)).build();
         result.addParameterMarkers(getParameterMarkerSegments());
         return result;
     }
     
     @Override
     public ASTNode visitInsertingValuesIntoTables(final InsertingValuesIntoTablesContext ctx) {
-        InsertStatement result = (InsertStatement) visit(ctx.insertValuesClause());
-        result.setTable((SimpleTableSegment) visit(ctx.tableName()));
+        InsertStatement insertStatement = (InsertStatement) visit(ctx.insertValuesClause());
+        InsertStatement result = InsertStatement.builder().databaseType(getDatabaseType()).table((SimpleTableSegment) visit(ctx.tableName()))
+                .insertColumns(insertStatement.getInsertColumns().orElse(null)).insertSelect(insertStatement.getInsertSelect().orElse(null))
+                .setAssignment(insertStatement.getSetAssignment().orElse(null)).onDuplicateKeyColumns(insertStatement.getOnDuplicateKeyColumns().orElse(null))
+                .valueReference(insertStatement.getValueReference().orElse(null)).returning(insertStatement.getReturning().orElse(null))
+                .output(insertStatement.getOutput().orElse(null)).with(insertStatement.getWith().orElse(null))
+                .multiTableInsertType(insertStatement.getMultiTableInsertType().orElse(null)).multiTableInsertInto(insertStatement.getMultiTableInsertInto().orElse(null))
+                .multiTableConditionalInto(insertStatement.getMultiTableConditionalInto().orElse(null)).where(insertStatement.getWhere().orElse(null))
+                .exec(insertStatement.getExec().orElse(null)).withTableHint(insertStatement.getWithTableHint().orElse(null))
+                .rowSetFunction(insertStatement.getRowSetFunction().orElse(null)).ignore(insertStatement.isIgnore()).replace(insertStatement.isReplace())
+                .values(new LinkedList<>(insertStatement.getValues())).derivedInsertColumns(new LinkedList<>(insertStatement.getDerivedInsertColumns())).build();
+        result.addParameterMarkers(insertStatement.getParameterMarkers());
+        result.getVariableNames().addAll(insertStatement.getVariableNames());
+        result.getComments().addAll(insertStatement.getComments());
         result.addParameterMarkers(getParameterMarkerSegments());
         return result;
     }
@@ -1064,34 +1074,32 @@ public final class HiveDMLStatementVisitor extends HiveStatementVisitor implemen
     
     @Override
     public ASTNode visitInsertSelectClause(final InsertSelectClauseContext ctx) {
-        InsertStatement result = new InsertStatement(getDatabaseType());
+        InsertColumnsSegment insertColumns;
         if (null != ctx.LP_()) {
             if (null != ctx.fields()) {
-                result.setInsertColumns(new InsertColumnsSegment(ctx.LP_().getSymbol().getStartIndex(), ctx.RP_().getSymbol().getStopIndex(), createInsertColumns(ctx.fields())));
+                insertColumns = new InsertColumnsSegment(ctx.LP_().getSymbol().getStartIndex(), ctx.RP_().getSymbol().getStopIndex(), createInsertColumns(ctx.fields()));
             } else {
-                result.setInsertColumns(new InsertColumnsSegment(ctx.LP_().getSymbol().getStartIndex(), ctx.RP_().getSymbol().getStopIndex(), Collections.emptyList()));
+                insertColumns = new InsertColumnsSegment(ctx.LP_().getSymbol().getStartIndex(), ctx.RP_().getSymbol().getStopIndex(), Collections.emptyList());
             }
         } else {
-            result.setInsertColumns(new InsertColumnsSegment(ctx.start.getStartIndex() - 1, ctx.start.getStartIndex() - 1, Collections.emptyList()));
+            insertColumns = new InsertColumnsSegment(ctx.start.getStartIndex() - 1, ctx.start.getStartIndex() - 1, Collections.emptyList());
         }
-        result.setInsertSelect(createInsertSelectSegment(ctx));
-        return result;
+        return InsertStatement.builder().databaseType(getDatabaseType()).insertColumns(insertColumns).insertSelect(createInsertSelectSegment(ctx)).build();
     }
     
     @Override
     public ASTNode visitInsertValuesClause(final InsertValuesClauseContext ctx) {
-        InsertStatement result = new InsertStatement(getDatabaseType());
+        InsertColumnsSegment insertColumns;
         if (null != ctx.LP_()) {
             if (null != ctx.fields()) {
-                result.setInsertColumns(new InsertColumnsSegment(ctx.LP_().getSymbol().getStartIndex(), ctx.RP_().getSymbol().getStopIndex(), createInsertColumns(ctx.fields())));
+                insertColumns = new InsertColumnsSegment(ctx.LP_().getSymbol().getStartIndex(), ctx.RP_().getSymbol().getStopIndex(), createInsertColumns(ctx.fields()));
             } else {
-                result.setInsertColumns(new InsertColumnsSegment(ctx.LP_().getSymbol().getStartIndex(), ctx.RP_().getSymbol().getStopIndex(), Collections.emptyList()));
+                insertColumns = new InsertColumnsSegment(ctx.LP_().getSymbol().getStartIndex(), ctx.RP_().getSymbol().getStopIndex(), Collections.emptyList());
             }
         } else {
-            result.setInsertColumns(new InsertColumnsSegment(ctx.start.getStartIndex() - 1, ctx.start.getStartIndex() - 1, Collections.emptyList()));
+            insertColumns = new InsertColumnsSegment(ctx.start.getStartIndex() - 1, ctx.start.getStartIndex() - 1, Collections.emptyList());
         }
-        result.getValues().addAll(createInsertValuesSegments(ctx.assignmentValues()));
-        return result;
+        return InsertStatement.builder().databaseType(getDatabaseType()).insertColumns(insertColumns).values(createInsertValuesSegments(ctx.assignmentValues())).build();
     }
     
     private Collection<InsertValuesSegment> createInsertValuesSegments(final Collection<AssignmentValuesContext> assignmentValuesContexts) {
@@ -1230,10 +1238,11 @@ public final class HiveDMLStatementVisitor extends HiveStatementVisitor implemen
                 seg.setUpdate(upd);
             }
             if (null != each.INSERT()) {
-                InsertStatement ins = new InsertStatement(getDatabaseType());
+                Collection<InsertValuesSegment> values = new LinkedList<>();
                 if (null != each.insertValuesClause().assignmentValues()) {
-                    ins.getValues().addAll(createInsertValuesSegments(each.insertValuesClause().assignmentValues()));
+                    values.addAll(createInsertValuesSegments(each.insertValuesClause().assignmentValues()));
                 }
+                InsertStatement ins = InsertStatement.builder().databaseType(getDatabaseType()).values(values).build();
                 seg.setInsert(ins);
             }
             result.getWhenAndThens().add(seg);
diff --git a/parser/sql/engine/dialect/mysql/src/main/java/org/apache/shardingsphere/sql/parser/engine/mysql/visitor/statement/MySQLStatementVisitor.java b/parser/sql/engine/dialect/mysql/src/main/java/org/apache/shardingsphere/sql/parser/engine/mysql/visitor/statement/MySQLStatementVisitor.java
index 125da708eae..708c996bf30 100644
--- a/parser/sql/engine/dialect/mysql/src/main/java/org/apache/shardingsphere/sql/parser/engine/mysql/visitor/statement/MySQLStatementVisitor.java
+++ b/parser/sql/engine/dialect/mysql/src/main/java/org/apache/shardingsphere/sql/parser/engine/mysql/visitor/statement/MySQLStatementVisitor.java
@@ -1486,16 +1486,14 @@ public abstract class MySQLStatementVisitor extends MySQLStatementBaseVisitor<AS
     @Override
     public ASTNode visitInsert(final InsertContext ctx) {
         // TODO :FIXME, since there is no segment for insertValuesClause, InsertStatement is created by sub rule.
-        InsertStatement result = (InsertStatement) visit(ctx.insertBody());
-        if (null != ctx.onDuplicateKeyClause()) {
-            result.setOnDuplicateKeyColumns((OnDuplicateKeyColumnsSegment) visit(ctx.onDuplicateKeyClause()));
-        }
-        result.setIgnore(null != ctx.insertSpecification().IGNORE());
-        result.setTable((SimpleTableSegment) visit(ctx.tableName()));
+        InsertStatement insertBodyStatement = (InsertStatement) visit(ctx.insertBody());
+        InsertStatement result = createInsertStatementBuilder(insertBodyStatement).table((SimpleTableSegment) visit(ctx.tableName()))
+                .onDuplicateKeyColumns(
+                        null == ctx.onDuplicateKeyClause() ? insertBodyStatement.getOnDuplicateKeyColumns().orElse(null) : (OnDuplicateKeyColumnsSegment) visit(ctx.onDuplicateKeyClause()))
+                .ignore(null != ctx.insertSpecification().IGNORE())
+                .returning(null == ctx.returningClause() ? insertBodyStatement.getReturning().orElse(null) : (ReturningSegment) visit(ctx.returningClause())).build();
+        copyInsertStatementMetadata(insertBodyStatement, result);
         result.addParameterMarkers(getParameterMarkerSegments());
-        if (null != ctx.returningClause()) {
-            result.setReturning((ReturningSegment) visit(ctx.returningClause()));
-        }
         return result;
     }
     
@@ -1506,36 +1504,35 @@ public abstract class MySQLStatementVisitor extends MySQLStatementBaseVisitor<AS
             result = (InsertStatement) visit(ctx.insertValuesClause());
         } else if (null != ctx.insertSelectClause()) {
             result = (InsertStatement) visit(ctx.insertSelectClause());
-            if (null != ctx.valueReference()) {
-                result.setValueReference((ValueReferenceSegment) visit(ctx.valueReference()));
-            }
         } else {
-            result = new InsertStatement(databaseType);
-            result.setSetAssignment((SetAssignmentSegment) visit(ctx.setAssignmentsClause()));
-            if (null != ctx.valueReference()) {
-                result.setValueReference((ValueReferenceSegment) visit(ctx.valueReference()));
-            }
-            if (null == ctx.valueReference() && null != ctx.setAssignmentsClause().setRowAlias()) {
-                result.setValueReference(createValueReferenceFromSetRowAlias(ctx.setAssignmentsClause().setRowAlias()));
-            }
+            result = InsertStatement.builder().databaseType(databaseType).setAssignment((SetAssignmentSegment) visit(ctx.setAssignmentsClause())).build();
+        }
+        if (null != ctx.valueReference()) {
+            InsertStatement actual = createInsertStatementBuilder(result).valueReference((ValueReferenceSegment) visit(ctx.valueReference())).build();
+            copyInsertStatementMetadata(result, actual);
+            result = actual;
+        }
+        if (null == ctx.valueReference() && null != ctx.setAssignmentsClause() && null != ctx.setAssignmentsClause().setRowAlias()) {
+            InsertStatement actual = createInsertStatementBuilder(result).valueReference(createValueReferenceFromSetRowAlias(ctx.setAssignmentsClause().setRowAlias())).build();
+            copyInsertStatementMetadata(result, actual);
+            result = actual;
         }
         return result;
     }
     
     @Override
     public ASTNode visitInsertSelectClause(final InsertSelectClauseContext ctx) {
-        InsertStatement result = new InsertStatement(databaseType);
-        result.setInsertSelect(createInsertSelectSegment(ctx));
+        InsertColumnsSegment insertColumns;
         if (null != ctx.LP_() && !ctx.LP_().isEmpty()) {
             if (null != ctx.fields()) {
-                result.setInsertColumns(new InsertColumnsSegment(ctx.LP_().get(0).getSymbol().getStartIndex(), ctx.RP_().get(0).getSymbol().getStopIndex(), createInsertColumns(ctx.fields())));
+                insertColumns = new InsertColumnsSegment(ctx.LP_().get(0).getSymbol().getStartIndex(), ctx.RP_().get(0).getSymbol().getStopIndex(), createInsertColumns(ctx.fields()));
             } else {
-                result.setInsertColumns(new InsertColumnsSegment(ctx.LP_().get(0).getSymbol().getStartIndex(), ctx.RP_().get(0).getSymbol().getStopIndex(), Collections.emptyList()));
+                insertColumns = new InsertColumnsSegment(ctx.LP_().get(0).getSymbol().getStartIndex(), ctx.RP_().get(0).getSymbol().getStopIndex(), Collections.emptyList());
             }
         } else {
-            result.setInsertColumns(new InsertColumnsSegment(ctx.start.getStartIndex() - 1, ctx.start.getStartIndex() - 1, Collections.emptyList()));
+            insertColumns = new InsertColumnsSegment(ctx.start.getStartIndex() - 1, ctx.start.getStartIndex() - 1, Collections.emptyList());
         }
-        return result;
+        return InsertStatement.builder().databaseType(databaseType).insertColumns(insertColumns).insertSelect(createInsertSelectSegment(ctx)).build();
     }
     
     private ValueReferenceSegment createValueReferenceFromSetRowAlias(final SetRowAliasContext ctx) {
@@ -1560,24 +1557,23 @@ public abstract class MySQLStatementVisitor extends MySQLStatementBaseVisitor<AS
     
     @Override
     public ASTNode visitInsertValuesClause(final InsertValuesClauseContext ctx) {
-        InsertStatement result = new InsertStatement(databaseType);
+        InsertColumnsSegment insertColumns;
         if (null != ctx.LP_()) {
             if (null != ctx.fields()) {
-                result.setInsertColumns(new InsertColumnsSegment(ctx.LP_().getSymbol().getStartIndex(), ctx.RP_().getSymbol().getStopIndex(), createInsertColumns(ctx.fields())));
+                insertColumns = new InsertColumnsSegment(ctx.LP_().getSymbol().getStartIndex(), ctx.RP_().getSymbol().getStopIndex(), createInsertColumns(ctx.fields()));
             } else {
-                result.setInsertColumns(new InsertColumnsSegment(ctx.LP_().getSymbol().getStartIndex(), ctx.RP_().getSymbol().getStopIndex(), Collections.emptyList()));
+                insertColumns = new InsertColumnsSegment(ctx.LP_().getSymbol().getStartIndex(), ctx.RP_().getSymbol().getStopIndex(), Collections.emptyList());
             }
         } else {
-            result.setInsertColumns(new InsertColumnsSegment(ctx.start.getStartIndex() - 1, ctx.start.getStartIndex() - 1, Collections.emptyList()));
+            insertColumns = new InsertColumnsSegment(ctx.start.getStartIndex() - 1, ctx.start.getStartIndex() - 1, Collections.emptyList());
         }
+        ValueReferenceSegment valueReference = null;
         if (null != ctx.valueReference()) {
-            ValueReferenceSegment valueRef = (ValueReferenceSegment) visit(ctx.valueReference());
-            result.setValueReference(valueRef);
+            valueReference = (ValueReferenceSegment) visit(ctx.valueReference());
         }
         Collection<InsertValuesSegment> insertValuesSegments =
                 null == ctx.rowConstructorList() ? createInsertValuesSegments(ctx.assignmentValues()) : createRowConstructorList(ctx.rowConstructorList());
-        result.getValues().addAll(insertValuesSegments);
-        return result;
+        return InsertStatement.builder().databaseType(databaseType).insertColumns(insertColumns).valueReference(valueReference).values(insertValuesSegments).build();
     }
     
     private Collection<InsertValuesSegment> createInsertValuesSegments(final Collection<AssignmentValuesContext> assignmentValuesContexts) {
@@ -1636,32 +1632,28 @@ public abstract class MySQLStatementVisitor extends MySQLStatementBaseVisitor<AS
         } else if (null != ctx.replaceSelectClause()) {
             result = (InsertStatement) visit(ctx.replaceSelectClause());
         } else {
-            result = new InsertStatement(databaseType);
-            result.setSetAssignment((SetAssignmentSegment) visit(ctx.setAssignmentsClause()));
+            result = InsertStatement.builder().databaseType(databaseType).setAssignment((SetAssignmentSegment) visit(ctx.setAssignmentsClause())).build();
         }
-        result.setReplace(true);
-        result.setTable((SimpleTableSegment) visit(ctx.tableName()));
-        result.addParameterMarkers(getParameterMarkerSegments());
-        if (null != ctx.returningClause()) {
-            result.setReturning((ReturningSegment) visit(ctx.returningClause()));
-        }
-        return result;
+        InsertStatement actual = createInsertStatementBuilder(result).replace(true).table((SimpleTableSegment) visit(ctx.tableName()))
+                .returning(null == ctx.returningClause() ? result.getReturning().orElse(null) : (ReturningSegment) visit(ctx.returningClause())).build();
+        copyInsertStatementMetadata(result, actual);
+        actual.addParameterMarkers(getParameterMarkerSegments());
+        return actual;
     }
     
     @Override
     public ASTNode visitReplaceSelectClause(final ReplaceSelectClauseContext ctx) {
-        InsertStatement result = new InsertStatement(databaseType);
+        InsertColumnsSegment insertColumns;
         if (null != ctx.LP_()) {
             if (null != ctx.fields()) {
-                result.setInsertColumns(new InsertColumnsSegment(ctx.LP_().getSymbol().getStartIndex(), ctx.RP_().getSymbol().getStopIndex(), createInsertColumns(ctx.fields())));
+                insertColumns = new InsertColumnsSegment(ctx.LP_().getSymbol().getStartIndex(), ctx.RP_().getSymbol().getStopIndex(), createInsertColumns(ctx.fields()));
             } else {
-                result.setInsertColumns(new InsertColumnsSegment(ctx.LP_().getSymbol().getStartIndex(), ctx.RP_().getSymbol().getStopIndex(), Collections.emptyList()));
+                insertColumns = new InsertColumnsSegment(ctx.LP_().getSymbol().getStartIndex(), ctx.RP_().getSymbol().getStopIndex(), Collections.emptyList());
             }
         } else {
-            result.setInsertColumns(new InsertColumnsSegment(ctx.start.getStartIndex() - 1, ctx.start.getStartIndex() - 1, Collections.emptyList()));
+            insertColumns = new InsertColumnsSegment(ctx.start.getStartIndex() - 1, ctx.start.getStartIndex() - 1, Collections.emptyList());
         }
-        result.setInsertSelect(createReplaceSelectSegment(ctx));
-        return result;
+        return InsertStatement.builder().databaseType(databaseType).insertColumns(insertColumns).insertSelect(createReplaceSelectSegment(ctx)).build();
     }
     
     private SubquerySegment createReplaceSelectSegment(final ReplaceSelectClauseContext ctx) {
@@ -1671,18 +1663,36 @@ public abstract class MySQLStatementVisitor extends MySQLStatementBaseVisitor<AS
     
     @Override
     public ASTNode visitReplaceValuesClause(final ReplaceValuesClauseContext ctx) {
-        InsertStatement result = new InsertStatement(databaseType);
+        InsertColumnsSegment insertColumns;
         if (null != ctx.LP_()) {
             if (null != ctx.fields()) {
-                result.setInsertColumns(new InsertColumnsSegment(ctx.LP_().getSymbol().getStartIndex(), ctx.RP_().getSymbol().getStopIndex(), createInsertColumns(ctx.fields())));
+                insertColumns = new InsertColumnsSegment(ctx.LP_().getSymbol().getStartIndex(), ctx.RP_().getSymbol().getStopIndex(), createInsertColumns(ctx.fields()));
             } else {
-                result.setInsertColumns(new InsertColumnsSegment(ctx.LP_().getSymbol().getStartIndex(), ctx.RP_().getSymbol().getStopIndex(), Collections.emptyList()));
+                insertColumns = new InsertColumnsSegment(ctx.LP_().getSymbol().getStartIndex(), ctx.RP_().getSymbol().getStopIndex(), Collections.emptyList());
             }
         } else {
-            result.setInsertColumns(new InsertColumnsSegment(ctx.start.getStartIndex() - 1, ctx.start.getStartIndex() - 1, Collections.emptyList()));
+            insertColumns = new InsertColumnsSegment(ctx.start.getStartIndex() - 1, ctx.start.getStartIndex() - 1, Collections.emptyList());
         }
-        result.getValues().addAll(createInsertValuesSegments(ctx.assignmentValues()));
-        return result;
+        return InsertStatement.builder().databaseType(databaseType).insertColumns(insertColumns).values(createInsertValuesSegments(ctx.assignmentValues())).build();
+    }
+    
+    private InsertStatement.InsertStatementBuilder createInsertStatementBuilder(final InsertStatement insertStatement) {
+        return InsertStatement.builder().databaseType(databaseType).table(insertStatement.getTable().orElse(null))
+                .insertColumns(insertStatement.getInsertColumns().orElse(null)).insertSelect(insertStatement.getInsertSelect().orElse(null))
+                .setAssignment(insertStatement.getSetAssignment().orElse(null)).onDuplicateKeyColumns(insertStatement.getOnDuplicateKeyColumns().orElse(null))
+                .valueReference(insertStatement.getValueReference().orElse(null)).returning(insertStatement.getReturning().orElse(null))
+                .output(insertStatement.getOutput().orElse(null)).with(insertStatement.getWith().orElse(null))
+                .multiTableInsertType(insertStatement.getMultiTableInsertType().orElse(null)).multiTableInsertInto(insertStatement.getMultiTableInsertInto().orElse(null))
+                .multiTableConditionalInto(insertStatement.getMultiTableConditionalInto().orElse(null)).where(insertStatement.getWhere().orElse(null))
+                .exec(insertStatement.getExec().orElse(null)).withTableHint(insertStatement.getWithTableHint().orElse(null))
+                .rowSetFunction(insertStatement.getRowSetFunction().orElse(null)).ignore(insertStatement.isIgnore()).replace(insertStatement.isReplace())
+                .values(new LinkedList<>(insertStatement.getValues())).derivedInsertColumns(new LinkedList<>(insertStatement.getDerivedInsertColumns()));
+    }
+    
+    private void copyInsertStatementMetadata(final InsertStatement source, final InsertStatement target) {
+        target.addParameterMarkers(source.getParameterMarkers());
+        target.getVariableNames().addAll(source.getVariableNames());
+        target.getComments().addAll(source.getComments());
     }
     
     private List<ColumnSegment> createInsertColumns(final FieldsContext fields) {
diff --git a/parser/sql/engine/dialect/opengauss/src/main/java/org/apache/shardingsphere/sql/parser/engine/opengauss/visitor/statement/OpenGaussStatementVisitor.java b/parser/sql/engine/dialect/opengauss/src/main/java/org/apache/shardingsphere/sql/parser/engine/opengauss/visitor/statement/OpenGaussStatementVisitor.java
index 418bcd1ccb4..3fcd77d2ebe 100644
--- a/parser/sql/engine/dialect/opengauss/src/main/java/org/apache/shardingsphere/sql/parser/engine/opengauss/visitor/statement/OpenGaussStatementVisitor.java
+++ b/parser/sql/engine/dialect/opengauss/src/main/java/org/apache/shardingsphere/sql/parser/engine/opengauss/visitor/statement/OpenGaussStatementVisitor.java
@@ -703,14 +703,22 @@ public abstract class OpenGaussStatementVisitor extends OpenGaussStatementParser
     public ASTNode visitInsert(final InsertContext ctx) {
         // TODO :FIXME, since there is no segment for insertValuesClause, InsertStatement is created by sub rule.
         // TODO :deal with insert select
-        InsertStatement result = (InsertStatement) visit(ctx.insertRest());
-        result.setTable((SimpleTableSegment) visit(ctx.insertTarget()));
-        if (null != ctx.optOnDuplicateKey()) {
-            result.setOnDuplicateKeyColumns((OnDuplicateKeyColumnsSegment) visit(ctx.optOnDuplicateKey()));
-        }
-        if (null != ctx.returningClause()) {
-            result.setReturning((ReturningSegment) visit(ctx.returningClause()));
-        }
+        InsertStatement insertRestStatement = (InsertStatement) visit(ctx.insertRest());
+        InsertStatement result = InsertStatement.builder().databaseType(databaseType).table((SimpleTableSegment) visit(ctx.insertTarget()))
+                .insertColumns(insertRestStatement.getInsertColumns().orElse(null)).insertSelect(insertRestStatement.getInsertSelect().orElse(null))
+                .setAssignment(insertRestStatement.getSetAssignment().orElse(null))
+                .onDuplicateKeyColumns(null == ctx.optOnDuplicateKey() ? insertRestStatement.getOnDuplicateKeyColumns().orElse(null) : (OnDuplicateKeyColumnsSegment) visit(ctx.optOnDuplicateKey()))
+                .valueReference(insertRestStatement.getValueReference().orElse(null))
+                .returning(null == ctx.returningClause() ? insertRestStatement.getReturning().orElse(null) : (ReturningSegment) visit(ctx.returningClause()))
+                .output(insertRestStatement.getOutput().orElse(null)).with(insertRestStatement.getWith().orElse(null))
+                .multiTableInsertType(insertRestStatement.getMultiTableInsertType().orElse(null)).multiTableInsertInto(insertRestStatement.getMultiTableInsertInto().orElse(null))
+                .multiTableConditionalInto(insertRestStatement.getMultiTableConditionalInto().orElse(null)).where(insertRestStatement.getWhere().orElse(null))
+                .exec(insertRestStatement.getExec().orElse(null)).withTableHint(insertRestStatement.getWithTableHint().orElse(null))
+                .rowSetFunction(insertRestStatement.getRowSetFunction().orElse(null)).ignore(insertRestStatement.isIgnore()).replace(insertRestStatement.isReplace())
+                .values(new LinkedList<>(insertRestStatement.getValues())).derivedInsertColumns(new LinkedList<>(insertRestStatement.getDerivedInsertColumns())).build();
+        result.addParameterMarkers(insertRestStatement.getParameterMarkers());
+        result.getVariableNames().addAll(insertRestStatement.getVariableNames());
+        result.getComments().addAll(insertRestStatement.getComments());
         result.addParameterMarkers(getParameterMarkerSegments());
         return result;
     }
@@ -760,23 +768,24 @@ public abstract class OpenGaussStatementVisitor extends OpenGaussStatementParser
     @SuppressWarnings("unchecked")
     @Override
     public ASTNode visitInsertRest(final InsertRestContext ctx) {
-        InsertStatement result = new InsertStatement(databaseType);
+        SubquerySegment insertSelect = null;
+        Collection<InsertValuesSegment> values = new LinkedList<>();
         ValuesClauseContext valuesClause = ctx.select().selectNoParens().selectClauseN().simpleSelect().valuesClause();
         if (null == valuesClause) {
             SelectStatement selectStatement = (SelectStatement) visit(ctx.select());
-            result.setInsertSelect(new SubquerySegment(ctx.select().start.getStartIndex(), ctx.select().stop.getStopIndex(), selectStatement, getOriginalText(ctx.select())));
+            insertSelect = new SubquerySegment(ctx.select().start.getStartIndex(), ctx.select().stop.getStopIndex(), selectStatement, getOriginalText(ctx.select()));
         } else {
-            result.getValues().addAll(createInsertValuesSegments(valuesClause));
+            values.addAll(createInsertValuesSegments(valuesClause));
         }
+        InsertColumnsSegment insertColumns;
         if (null == ctx.insertColumnList()) {
-            result.setInsertColumns(new InsertColumnsSegment(ctx.start.getStartIndex() - 1, ctx.start.getStartIndex() - 1, Collections.emptyList()));
+            insertColumns = new InsertColumnsSegment(ctx.start.getStartIndex() - 1, ctx.start.getStartIndex() - 1, Collections.emptyList());
         } else {
-            InsertColumnListContext insertColumns = ctx.insertColumnList();
-            CollectionValue<ColumnSegment> columns = (CollectionValue<ColumnSegment>) visit(insertColumns);
-            InsertColumnsSegment insertColumnsSegment = new InsertColumnsSegment(insertColumns.start.getStartIndex() - 1, insertColumns.stop.getStopIndex() + 1, columns.getValue());
-            result.setInsertColumns(insertColumnsSegment);
+            InsertColumnListContext insertColumnList = ctx.insertColumnList();
+            CollectionValue<ColumnSegment> columns = (CollectionValue<ColumnSegment>) visit(insertColumnList);
+            insertColumns = new InsertColumnsSegment(insertColumnList.start.getStartIndex() - 1, insertColumnList.stop.getStopIndex() + 1, columns.getValue());
         }
-        return result;
+        return InsertStatement.builder().databaseType(databaseType).insertColumns(insertColumns).insertSelect(insertSelect).values(values).build();
     }
     
     @Override
diff --git a/parser/sql/engine/dialect/oracle/src/main/java/org/apache/shardingsphere/sql/parser/engine/oracle/visitor/statement/type/OracleDMLStatementVisitor.java b/parser/sql/engine/dialect/oracle/src/main/java/org/apache/shardingsphere/sql/parser/engine/oracle/visitor/statement/type/OracleDMLStatementVisitor.java
index b47072662f9..aec322e02d4 100644
--- a/parser/sql/engine/dialect/oracle/src/main/java/org/apache/shardingsphere/sql/parser/engine/oracle/visitor/statement/type/OracleDMLStatementVisitor.java
+++ b/parser/sql/engine/dialect/oracle/src/main/java/org/apache/shardingsphere/sql/parser/engine/oracle/visitor/statement/type/OracleDMLStatementVisitor.java
@@ -316,16 +316,24 @@ public final class OracleDMLStatementVisitor extends OracleStatementVisitor impl
     
     @Override
     public ASTNode visitInsertSingleTable(final InsertSingleTableContext ctx) {
-        InsertStatement result = (InsertStatement) visit(ctx.insertIntoClause());
+        InsertStatement insertStatement = (InsertStatement) visit(ctx.insertIntoClause());
+        Collection<InsertValuesSegment> insertValues = new LinkedList<>(insertStatement.getValues());
         if (null != ctx.insertValuesClause()) {
-            result.getValues().addAll(createInsertValuesSegments(ctx.insertValuesClause().assignmentValues()));
+            insertValues.addAll(createInsertValuesSegments(ctx.insertValuesClause().assignmentValues()));
         }
+        SubquerySegment insertSelect = insertStatement.getInsertSelect().orElse(null);
         if (null != ctx.selectSubquery()) {
             SelectStatement subquery = (SelectStatement) visit(ctx.selectSubquery());
-            SubquerySegment subquerySegment = new SubquerySegment(ctx.selectSubquery().start.getStartIndex(), ctx.selectSubquery().stop.getStopIndex(), subquery,
+            insertSelect = new SubquerySegment(ctx.selectSubquery().start.getStartIndex(), ctx.selectSubquery().stop.getStopIndex(), subquery,
                     getOriginalText(ctx.selectSubquery()));
-            result.setInsertSelect(subquerySegment);
         }
+        InsertStatement result = InsertStatement.builder()
+                .databaseType(insertStatement.getDatabaseType())
+                .table(insertStatement.getTable().orElse(null))
+                .insertColumns(insertStatement.getInsertColumns().orElse(null))
+                .insertSelect(insertSelect)
+                .values(insertValues)
+                .build();
         result.getVariableNames().addAll(getVariableNames());
         return result;
     }
@@ -338,21 +346,23 @@ public final class OracleDMLStatementVisitor extends OracleStatementVisitor impl
     
     @Override
     public ASTNode visitInsertMultiTable(final InsertMultiTableContext ctx) {
-        InsertStatement result = new InsertStatement(getDatabaseType());
-        result.setMultiTableInsertType(null != ctx.conditionalInsertClause() && null != ctx.conditionalInsertClause().FIRST() ? MultiTableInsertType.FIRST : MultiTableInsertType.ALL);
+        InsertStatement.InsertStatementBuilder result = InsertStatement.builder()
+                .databaseType(getDatabaseType())
+                .multiTableInsertType(null != ctx.conditionalInsertClause() && null != ctx.conditionalInsertClause().FIRST() ? MultiTableInsertType.FIRST : MultiTableInsertType.ALL);
         List<MultiTableElementContext> multiTableElementContexts = ctx.multiTableElement();
         if (null != multiTableElementContexts && !multiTableElementContexts.isEmpty()) {
             MultiTableInsertIntoSegment multiTableInsertIntoSegment = new MultiTableInsertIntoSegment(
                     multiTableElementContexts.get(0).getStart().getStartIndex(), multiTableElementContexts.get(multiTableElementContexts.size() - 1).getStop().getStopIndex());
             multiTableInsertIntoSegment.getInsertStatements().addAll(createInsertIntoSegments(multiTableElementContexts));
-            result.setMultiTableInsertInto(multiTableInsertIntoSegment);
+            result.multiTableInsertInto(multiTableInsertIntoSegment);
         } else {
-            result.setMultiTableConditionalInto((MultiTableConditionalIntoSegment) visit(ctx.conditionalInsertClause()));
+            result.multiTableConditionalInto((MultiTableConditionalIntoSegment) visit(ctx.conditionalInsertClause()));
         }
-        result.setInsertSelect(new SubquerySegment(ctx.selectSubquery().start.getStartIndex(), ctx.selectSubquery().stop.getStopIndex(), (SelectStatement) visit(ctx.selectSubquery()),
+        result.insertSelect(new SubquerySegment(ctx.selectSubquery().start.getStartIndex(), ctx.selectSubquery().stop.getStopIndex(), (SelectStatement) visit(ctx.selectSubquery()),
                 getOriginalText(ctx.selectSubquery())));
-        result.getVariableNames().addAll(getVariableNames());
-        return result;
+        InsertStatement actual = result.build();
+        actual.getVariableNames().addAll(getVariableNames());
+        return actual;
     }
     
     private Collection<InsertStatement> createInsertIntoSegments(final List<MultiTableElementContext> ctx) {
@@ -377,34 +387,32 @@ public final class OracleDMLStatementVisitor extends OracleStatementVisitor impl
     
     @Override
     public ASTNode visitInsertValuesClause(final InsertValuesClauseContext ctx) {
-        InsertStatement result = new InsertStatement(getDatabaseType());
-        result.getValues().addAll(createInsertValuesSegments(ctx.assignmentValues()));
-        return result;
+        return InsertStatement.builder().databaseType(getDatabaseType()).values(createInsertValuesSegments(ctx.assignmentValues())).build();
     }
     
     @SuppressWarnings("unchecked")
     @Override
     public ASTNode visitInsertIntoClause(final InsertIntoClauseContext ctx) {
-        InsertStatement result = new InsertStatement(getDatabaseType());
+        InsertStatement.InsertStatementBuilder result = InsertStatement.builder().databaseType(getDatabaseType());
         if (null != ctx.dmlTableExprClause().dmlTableClause()) {
             SimpleTableSegment simpleTableSegment = (SimpleTableSegment) visit(ctx.dmlTableExprClause().dmlTableClause());
             if (null != ctx.dmlTableExprClause().alias()) {
                 simpleTableSegment.setAlias((AliasSegment) visit(ctx.dmlTableExprClause().alias()));
             }
-            result.setTable(simpleTableSegment);
+            result.table(simpleTableSegment);
         } else if (null != ctx.dmlTableExprClause().dmlSubqueryClause()) {
-            result.setInsertSelect((SubquerySegment) visit(ctx.dmlTableExprClause().dmlSubqueryClause()));
+            result.insertSelect((SubquerySegment) visit(ctx.dmlTableExprClause().dmlSubqueryClause()));
         } else {
-            result.setInsertSelect((SubquerySegment) visit(ctx.dmlTableExprClause().tableCollectionExpr()));
+            result.insertSelect((SubquerySegment) visit(ctx.dmlTableExprClause().tableCollectionExpr()));
         }
         if (null != ctx.columnNames()) {
             ColumnNamesContext columnNames = ctx.columnNames();
             CollectionValue<ColumnSegment> columnSegments = (CollectionValue<ColumnSegment>) visit(columnNames);
-            result.setInsertColumns(new InsertColumnsSegment(columnNames.start.getStartIndex(), columnNames.stop.getStopIndex(), columnSegments.getValue()));
+            result.insertColumns(new InsertColumnsSegment(columnNames.start.getStartIndex(), columnNames.stop.getStopIndex(), columnSegments.getValue()));
         } else {
-            result.setInsertColumns(new InsertColumnsSegment(ctx.stop.getStopIndex() + 1, ctx.stop.getStopIndex() + 1, Collections.emptyList()));
+            result.insertColumns(new InsertColumnsSegment(ctx.stop.getStopIndex() + 1, ctx.stop.getStopIndex() + 1, Collections.emptyList()));
         }
-        return result;
+        return result.build();
     }
     
     @Override
@@ -1366,18 +1374,19 @@ public final class OracleDMLStatementVisitor extends OracleStatementVisitor impl
     @SuppressWarnings("unchecked")
     @Override
     public ASTNode visitMergeInsertClause(final MergeInsertClauseContext ctx) {
-        InsertStatement result = new InsertStatement(getDatabaseType());
+        InsertStatement.InsertStatementBuilder result = InsertStatement.builder().databaseType(getDatabaseType());
         if (null != ctx.mergeInsertColumn()) {
-            result.setInsertColumns((InsertColumnsSegment) visit(ctx.mergeInsertColumn()));
+            result.insertColumns((InsertColumnsSegment) visit(ctx.mergeInsertColumn()));
         }
         if (null != ctx.mergeColumnValue()) {
-            result.getValues().addAll(((CollectionValue<InsertValuesSegment>) visit(ctx.mergeColumnValue())).getValue());
+            result.values(((CollectionValue<InsertValuesSegment>) visit(ctx.mergeColumnValue())).getValue());
         }
         if (null != ctx.whereClause()) {
-            result.setWhere((WhereSegment) visit(ctx.whereClause()));
+            result.where((WhereSegment) visit(ctx.whereClause()));
         }
-        result.addParameterMarkers(popAllStatementParameterMarkerSegments());
-        return result;
+        InsertStatement actual = result.build();
+        actual.addParameterMarkers(popAllStatementParameterMarkerSegments());
+        return actual;
     }
     
     @Override
diff --git a/parser/sql/engine/dialect/postgresql/src/main/java/org/apache/shardingsphere/sql/parser/engine/postgresql/visitor/statement/PostgreSQLStatementVisitor.java b/parser/sql/engine/dialect/postgresql/src/main/java/org/apache/shardingsphere/sql/parser/engine/postgresql/visitor/statement/PostgreSQLStatementVisitor.java
index 58914e2b2b0..3f56e0687ef 100644
--- a/parser/sql/engine/dialect/postgresql/src/main/java/org/apache/shardingsphere/sql/parser/engine/postgresql/visitor/statement/PostgreSQLStatementVisitor.java
+++ b/parser/sql/engine/dialect/postgresql/src/main/java/org/apache/shardingsphere/sql/parser/engine/postgresql/visitor/statement/PostgreSQLStatementVisitor.java
@@ -709,16 +709,22 @@ public abstract class PostgreSQLStatementVisitor extends PostgreSQLStatementPars
     public ASTNode visitInsert(final InsertContext ctx) {
         // TODO :FIXME, since there is no segment for insertValuesClause, InsertStatement is created by sub rule.
         // TODO :deal with insert select
-        InsertStatement result = (InsertStatement) visit(ctx.insertRest());
-        result.setTable((SimpleTableSegment) visit(ctx.insertTarget()));
+        InsertStatement insertStatement = (InsertStatement) visit(ctx.insertRest());
+        InsertStatement.InsertStatementBuilder result = InsertStatement.builder()
+                .databaseType(insertStatement.getDatabaseType())
+                .table((SimpleTableSegment) visit(ctx.insertTarget()))
+                .insertColumns(insertStatement.getInsertColumns().orElse(null))
+                .insertSelect(insertStatement.getInsertSelect().orElse(null))
+                .values(insertStatement.getValues());
         if (null != ctx.optOnConflict()) {
-            result.setOnDuplicateKeyColumns((OnDuplicateKeyColumnsSegment) visit(ctx.optOnConflict()));
+            result.onDuplicateKeyColumns((OnDuplicateKeyColumnsSegment) visit(ctx.optOnConflict()));
         }
         if (null != ctx.returningClause()) {
-            result.setReturning((ReturningSegment) visit(ctx.returningClause()));
+            result.returning((ReturningSegment) visit(ctx.returningClause()));
         }
-        result.addParameterMarkers(getParameterMarkerSegments());
-        return result;
+        InsertStatement actual = result.build();
+        actual.addParameterMarkers(getParameterMarkerSegments());
+        return actual;
     }
     
     @Override
@@ -775,23 +781,23 @@ public abstract class PostgreSQLStatementVisitor extends PostgreSQLStatementPars
     @SuppressWarnings("unchecked")
     @Override
     public ASTNode visitInsertRest(final InsertRestContext ctx) {
-        InsertStatement result = new InsertStatement(databaseType);
+        InsertStatement.InsertStatementBuilder result = InsertStatement.builder().databaseType(databaseType);
         ValuesClauseContext valuesClause = ctx.select().selectNoParens().selectClauseN().simpleSelect().valuesClause();
         if (null == valuesClause) {
             SelectStatement selectStatement = (SelectStatement) visit(ctx.select());
-            result.setInsertSelect(new SubquerySegment(ctx.select().start.getStartIndex(), ctx.select().stop.getStopIndex(), selectStatement, getOriginalText(ctx.select())));
+            result.insertSelect(new SubquerySegment(ctx.select().start.getStartIndex(), ctx.select().stop.getStopIndex(), selectStatement, getOriginalText(ctx.select())));
         } else {
-            result.getValues().addAll(createInsertValuesSegments(valuesClause));
+            result.values(createInsertValuesSegments(valuesClause));
         }
         if (null == ctx.insertColumnList()) {
-            result.setInsertColumns(new InsertColumnsSegment(ctx.start.getStartIndex() - 1, ctx.start.getStartIndex() - 1, Collections.emptyList()));
+            result.insertColumns(new InsertColumnsSegment(ctx.start.getStartIndex() - 1, ctx.start.getStartIndex() - 1, Collections.emptyList()));
         } else {
             InsertColumnListContext insertColumns = ctx.insertColumnList();
             CollectionValue<ColumnSegment> columns = (CollectionValue<ColumnSegment>) visit(insertColumns);
             InsertColumnsSegment insertColumnsSegment = new InsertColumnsSegment(insertColumns.start.getStartIndex() - 1, insertColumns.stop.getStopIndex() + 1, columns.getValue());
-            result.setInsertColumns(insertColumnsSegment);
+            result.insertColumns(insertColumnsSegment);
         }
-        return result;
+        return result.build();
     }
     
     @SuppressWarnings("unchecked")
diff --git a/parser/sql/engine/dialect/presto/src/main/java/org/apache/shardingsphere/sql/parser/engine/presto/visitor/statement/type/PrestoDMLStatementVisitor.java b/parser/sql/engine/dialect/presto/src/main/java/org/apache/shardingsphere/sql/parser/engine/presto/visitor/statement/type/PrestoDMLStatementVisitor.java
index 49048304f0b..5abbc271058 100644
--- a/parser/sql/engine/dialect/presto/src/main/java/org/apache/shardingsphere/sql/parser/engine/presto/visitor/statement/type/PrestoDMLStatementVisitor.java
+++ b/parser/sql/engine/dialect/presto/src/main/java/org/apache/shardingsphere/sql/parser/engine/presto/visitor/statement/type/PrestoDMLStatementVisitor.java
@@ -806,37 +806,45 @@ public final class PrestoDMLStatementVisitor extends PrestoStatementVisitor impl
     @Override
     public ASTNode visitInsert(final InsertContext ctx) {
         // TODO :FIXME, since there is no segment for insertValuesClause, InsertStatement is created by sub rule.
-        InsertStatement result;
+        InsertStatement insertStatement;
         if (null != ctx.insertValuesClause()) {
-            result = (InsertStatement) visit(ctx.insertValuesClause());
+            insertStatement = (InsertStatement) visit(ctx.insertValuesClause());
         } else if (null != ctx.insertSelectClause()) {
-            result = (InsertStatement) visit(ctx.insertSelectClause());
+            insertStatement = (InsertStatement) visit(ctx.insertSelectClause());
         } else {
-            result = new InsertStatement(getDatabaseType());
-            result.setSetAssignment((SetAssignmentSegment) visit(ctx.setAssignmentsClause()));
-        }
-        if (null != ctx.onDuplicateKeyClause()) {
-            result.setOnDuplicateKeyColumns((OnDuplicateKeyColumnsSegment) visit(ctx.onDuplicateKeyClause()));
-        }
-        result.setTable((SimpleTableSegment) visit(ctx.tableName()));
+            insertStatement = InsertStatement.builder().databaseType(getDatabaseType()).setAssignment((SetAssignmentSegment) visit(ctx.setAssignmentsClause())).build();
+        }
+        InsertStatement result = InsertStatement.builder().databaseType(getDatabaseType()).table((SimpleTableSegment) visit(ctx.tableName()))
+                .insertColumns(insertStatement.getInsertColumns().orElse(null)).insertSelect(insertStatement.getInsertSelect().orElse(null))
+                .setAssignment(insertStatement.getSetAssignment().orElse(null))
+                .onDuplicateKeyColumns(null == ctx.onDuplicateKeyClause() ? insertStatement.getOnDuplicateKeyColumns().orElse(null) : (OnDuplicateKeyColumnsSegment) visit(ctx.onDuplicateKeyClause()))
+                .valueReference(insertStatement.getValueReference().orElse(null)).returning(insertStatement.getReturning().orElse(null))
+                .output(insertStatement.getOutput().orElse(null)).with(insertStatement.getWith().orElse(null))
+                .multiTableInsertType(insertStatement.getMultiTableInsertType().orElse(null)).multiTableInsertInto(insertStatement.getMultiTableInsertInto().orElse(null))
+                .multiTableConditionalInto(insertStatement.getMultiTableConditionalInto().orElse(null)).where(insertStatement.getWhere().orElse(null))
+                .exec(insertStatement.getExec().orElse(null)).withTableHint(insertStatement.getWithTableHint().orElse(null))
+                .rowSetFunction(insertStatement.getRowSetFunction().orElse(null)).ignore(insertStatement.isIgnore()).replace(insertStatement.isReplace())
+                .values(new LinkedList<>(insertStatement.getValues())).derivedInsertColumns(new LinkedList<>(insertStatement.getDerivedInsertColumns())).build();
+        result.addParameterMarkers(insertStatement.getParameterMarkers());
+        result.getVariableNames().addAll(insertStatement.getVariableNames());
+        result.getComments().addAll(insertStatement.getComments());
         result.addParameterMarkers(getParameterMarkerSegments());
         return result;
     }
     
     @Override
     public ASTNode visitInsertSelectClause(final InsertSelectClauseContext ctx) {
-        InsertStatement result = new InsertStatement(getDatabaseType());
+        InsertColumnsSegment insertColumns;
         if (null != ctx.LP_()) {
             if (null != ctx.fields()) {
-                result.setInsertColumns(new InsertColumnsSegment(ctx.LP_().getSymbol().getStartIndex(), ctx.RP_().getSymbol().getStopIndex(), createInsertColumns(ctx.fields())));
+                insertColumns = new InsertColumnsSegment(ctx.LP_().getSymbol().getStartIndex(), ctx.RP_().getSymbol().getStopIndex(), createInsertColumns(ctx.fields()));
             } else {
-                result.setInsertColumns(new InsertColumnsSegment(ctx.LP_().getSymbol().getStartIndex(), ctx.RP_().getSymbol().getStopIndex(), Collections.emptyList()));
+                insertColumns = new InsertColumnsSegment(ctx.LP_().getSymbol().getStartIndex(), ctx.RP_().getSymbol().getStopIndex(), Collections.emptyList());
             }
         } else {
-            result.setInsertColumns(new InsertColumnsSegment(ctx.start.getStartIndex() - 1, ctx.start.getStartIndex() - 1, Collections.emptyList()));
+            insertColumns = new InsertColumnsSegment(ctx.start.getStartIndex() - 1, ctx.start.getStartIndex() - 1, Collections.emptyList());
         }
-        result.setInsertSelect(createInsertSelectSegment(ctx));
-        return result;
+        return InsertStatement.builder().databaseType(getDatabaseType()).insertColumns(insertColumns).insertSelect(createInsertSelectSegment(ctx)).build();
     }
     
     private SubquerySegment createInsertSelectSegment(final InsertSelectClauseContext ctx) {
@@ -846,18 +854,17 @@ public final class PrestoDMLStatementVisitor extends PrestoStatementVisitor impl
     
     @Override
     public ASTNode visitInsertValuesClause(final InsertValuesClauseContext ctx) {
-        InsertStatement result = new InsertStatement(getDatabaseType());
+        InsertColumnsSegment insertColumns;
         if (null != ctx.LP_()) {
             if (null != ctx.fields()) {
-                result.setInsertColumns(new InsertColumnsSegment(ctx.LP_().getSymbol().getStartIndex(), ctx.RP_().getSymbol().getStopIndex(), createInsertColumns(ctx.fields())));
+                insertColumns = new InsertColumnsSegment(ctx.LP_().getSymbol().getStartIndex(), ctx.RP_().getSymbol().getStopIndex(), createInsertColumns(ctx.fields()));
             } else {
-                result.setInsertColumns(new InsertColumnsSegment(ctx.LP_().getSymbol().getStartIndex(), ctx.RP_().getSymbol().getStopIndex(), Collections.emptyList()));
+                insertColumns = new InsertColumnsSegment(ctx.LP_().getSymbol().getStartIndex(), ctx.RP_().getSymbol().getStopIndex(), Collections.emptyList());
             }
         } else {
-            result.setInsertColumns(new InsertColumnsSegment(ctx.start.getStartIndex() - 1, ctx.start.getStartIndex() - 1, Collections.emptyList()));
+            insertColumns = new InsertColumnsSegment(ctx.start.getStartIndex() - 1, ctx.start.getStartIndex() - 1, Collections.emptyList());
         }
-        result.getValues().addAll(createInsertValuesSegments(ctx.assignmentValues()));
-        return result;
+        return InsertStatement.builder().databaseType(getDatabaseType()).insertColumns(insertColumns).values(createInsertValuesSegments(ctx.assignmentValues())).build();
     }
     
     private Collection<InsertValuesSegment> createInsertValuesSegments(final Collection<AssignmentValuesContext> assignmentValuesContexts) {
diff --git a/parser/sql/engine/dialect/sql92/src/main/java/org/apache/shardingsphere/sql/parser/engine/sql92/visitor/statement/type/SQL92DMLStatementVisitor.java b/parser/sql/engine/dialect/sql92/src/main/java/org/apache/shardingsphere/sql/parser/engine/sql92/visitor/statement/type/SQL92DMLStatementVisitor.java
index 99ba848d177..14b436be1b8 100644
--- a/parser/sql/engine/dialect/sql92/src/main/java/org/apache/shardingsphere/sql/parser/engine/sql92/visitor/statement/type/SQL92DMLStatementVisitor.java
+++ b/parser/sql/engine/dialect/sql92/src/main/java/org/apache/shardingsphere/sql/parser/engine/sql92/visitor/statement/type/SQL92DMLStatementVisitor.java
@@ -110,8 +110,13 @@ public final class SQL92DMLStatementVisitor extends SQL92StatementVisitor implem
     
     @Override
     public ASTNode visitInsert(final InsertContext ctx) {
-        InsertStatement result = (InsertStatement) visit(ctx.insertValuesClause());
-        result.setTable((SimpleTableSegment) visit(ctx.tableName()));
+        InsertStatement insertStatement = (InsertStatement) visit(ctx.insertValuesClause());
+        InsertStatement result = InsertStatement.builder()
+                .databaseType(insertStatement.getDatabaseType())
+                .table((SimpleTableSegment) visit(ctx.tableName()))
+                .insertColumns(insertStatement.getInsertColumns().orElse(null))
+                .values(insertStatement.getValues())
+                .build();
         result.addParameterMarkers(getParameterMarkerSegments());
         return result;
     }
@@ -119,16 +124,16 @@ public final class SQL92DMLStatementVisitor extends SQL92StatementVisitor implem
     @SuppressWarnings("unchecked")
     @Override
     public ASTNode visitInsertValuesClause(final InsertValuesClauseContext ctx) {
-        InsertStatement result = new InsertStatement(getDatabaseType());
+        InsertStatement.InsertStatementBuilder result = InsertStatement.builder().databaseType(getDatabaseType());
         if (null != ctx.columnNames()) {
             ColumnNamesContext columnNames = ctx.columnNames();
             CollectionValue<ColumnSegment> columnSegments = (CollectionValue<ColumnSegment>) visit(columnNames);
-            result.setInsertColumns(new InsertColumnsSegment(columnNames.start.getStartIndex(), columnNames.stop.getStopIndex(), columnSegments.getValue()));
+            result.insertColumns(new InsertColumnsSegment(columnNames.start.getStartIndex(), columnNames.stop.getStopIndex(), columnSegments.getValue()));
         } else {
-            result.setInsertColumns(new InsertColumnsSegment(ctx.start.getStartIndex() - 1, ctx.start.getStartIndex() - 1, Collections.emptyList()));
+            result.insertColumns(new InsertColumnsSegment(ctx.start.getStartIndex() - 1, ctx.start.getStartIndex() - 1, Collections.emptyList()));
         }
-        result.getValues().addAll(createInsertValuesSegments(ctx.assignmentValues()));
-        return result;
+        result.values(createInsertValuesSegments(ctx.assignmentValues()));
+        return result.build();
     }
     
     private Collection<InsertValuesSegment> createInsertValuesSegments(final Collection<AssignmentValuesContext> assignmentValuesContexts) {
diff --git a/parser/sql/engine/dialect/sqlserver/src/main/java/org/apache/shardingsphere/sql/parser/engine/sqlserver/visitor/statement/SQLServerStatementVisitor.java b/parser/sql/engine/dialect/sqlserver/src/main/java/org/apache/shardingsphere/sql/parser/engine/sqlserver/visitor/statement/SQLServerStatementVisitor.java
index defc4533515..b816d657a3b 100644
--- a/parser/sql/engine/dialect/sqlserver/src/main/java/org/apache/shardingsphere/sql/parser/engine/sqlserver/visitor/statement/SQLServerStatementVisitor.java
+++ b/parser/sql/engine/dialect/sqlserver/src/main/java/org/apache/shardingsphere/sql/parser/engine/sqlserver/visitor/statement/SQLServerStatementVisitor.java
@@ -1437,30 +1437,56 @@ public abstract class SQLServerStatementVisitor extends SQLServerStatementBaseVi
     
     @Override
     public ASTNode visitInsert(final InsertContext ctx) {
-        InsertStatement result;
+        InsertStatement insertStatement;
         if (null != ctx.insertDefaultValue()) {
-            result = (InsertStatement) visit(ctx.insertDefaultValue());
+            insertStatement = (InsertStatement) visit(ctx.insertDefaultValue());
         } else if (null != ctx.insertValuesClause()) {
-            result = (InsertStatement) visit(ctx.insertValuesClause());
+            insertStatement = (InsertStatement) visit(ctx.insertValuesClause());
         } else if (null != ctx.insertExecClause()) {
-            result = (InsertStatement) visit(ctx.insertExecClause());
+            insertStatement = (InsertStatement) visit(ctx.insertExecClause());
         } else {
-            result = (InsertStatement) visit(ctx.insertSelectClause());
-        }
+            insertStatement = (InsertStatement) visit(ctx.insertSelectClause());
+        }
+        InsertStatement.InsertStatementBuilder result = InsertStatement.builder()
+                .databaseType(insertStatement.getDatabaseType())
+                .table(insertStatement.getTable().orElse(null))
+                .insertColumns(insertStatement.getInsertColumns().orElse(null))
+                .insertSelect(insertStatement.getInsertSelect().orElse(null))
+                .setAssignment(insertStatement.getSetAssignment().orElse(null))
+                .onDuplicateKeyColumns(insertStatement.getOnDuplicateKeyColumns().orElse(null))
+                .valueReference(insertStatement.getValueReference().orElse(null))
+                .returning(insertStatement.getReturning().orElse(null))
+                .output(insertStatement.getOutput().orElse(null))
+                .with(insertStatement.getWith().orElse(null))
+                .multiTableInsertType(insertStatement.getMultiTableInsertType().orElse(null))
+                .multiTableInsertInto(insertStatement.getMultiTableInsertInto().orElse(null))
+                .multiTableConditionalInto(insertStatement.getMultiTableConditionalInto().orElse(null))
+                .where(insertStatement.getWhere().orElse(null))
+                .exec(insertStatement.getExec().orElse(null))
+                .withTableHint(insertStatement.getWithTableHint().orElse(null))
+                .rowSetFunction(insertStatement.getRowSetFunction().orElse(null))
+                .ignore(insertStatement.isIgnore())
+                .replace(insertStatement.isReplace())
+                .values(insertStatement.getValues())
+                .derivedInsertColumns(insertStatement.getDerivedInsertColumns());
         if (null != ctx.withClause()) {
-            result.setWith((WithSegment) visit(ctx.withClause()));
+            result.with((WithSegment) visit(ctx.withClause()));
         }
         if (null != ctx.withTableHint()) {
-            result.setWithTableHint((WithTableHintSegment) visit(ctx.withTableHint()));
+            result.withTableHint((WithTableHintSegment) visit(ctx.withTableHint()));
         }
         if (null != ctx.tableName()) {
-            result.setTable((SimpleTableSegment) visit(ctx.tableName()));
+            result.table((SimpleTableSegment) visit(ctx.tableName()));
         }
         if (null != ctx.rowSetFunction()) {
-            result.setRowSetFunction((FunctionSegment) visit(ctx.rowSetFunction()));
+            result.rowSetFunction((FunctionSegment) visit(ctx.rowSetFunction()));
         }
-        result.addParameterMarkers(getParameterMarkerSegments());
-        return result;
+        InsertStatement actual = result.build();
+        actual.addParameterMarkers(insertStatement.getParameterMarkers());
+        actual.getVariableNames().addAll(insertStatement.getVariableNames());
+        actual.getComments().addAll(insertStatement.getComments());
+        actual.addParameterMarkers(getParameterMarkerSegments());
+        return actual;
     }
     
     @Override
@@ -1523,20 +1549,19 @@ public abstract class SQLServerStatementVisitor extends SQLServerStatementBaseVi
     
     @Override
     public ASTNode visitInsertDefaultValue(final InsertDefaultValueContext ctx) {
-        InsertStatement result = new InsertStatement(databaseType);
-        result.setInsertColumns(createInsertColumns(ctx.columnNames(), ctx.start.getStartIndex()));
+        InsertStatement.InsertStatementBuilder result = InsertStatement.builder().databaseType(databaseType).insertColumns(createInsertColumns(ctx.columnNames(), ctx.start.getStartIndex()));
         if (null != ctx.outputClause()) {
-            result.setOutput((OutputSegment) visit(ctx.outputClause()));
+            result.output((OutputSegment) visit(ctx.outputClause()));
         }
-        return result;
+        return result.build();
     }
     
     @Override
     public ASTNode visitInsertExecClause(final InsertExecClauseContext ctx) {
-        InsertStatement result = new InsertStatement(databaseType);
-        result.setInsertColumns(createInsertColumns(ctx.columnNames(), ctx.start.getStartIndex()));
-        result.setExec((ExecSegment) visit(ctx.exec()));
-        return result;
+        return InsertStatement.builder().databaseType(databaseType)
+                .insertColumns(createInsertColumns(ctx.columnNames(), ctx.start.getStartIndex()))
+                .exec((ExecSegment) visit(ctx.exec()))
+                .build();
     }
     
     @Override
@@ -1615,13 +1640,13 @@ public abstract class SQLServerStatementVisitor extends SQLServerStatementBaseVi
     
     @Override
     public ASTNode visitInsertValuesClause(final InsertValuesClauseContext ctx) {
-        InsertStatement result = new InsertStatement(databaseType);
-        result.setInsertColumns(createInsertColumns(ctx.columnNames(), ctx.start.getStartIndex()));
-        result.getValues().addAll(createInsertValuesSegments(ctx.assignmentValues()));
+        InsertStatement.InsertStatementBuilder result = InsertStatement.builder().databaseType(databaseType)
+                .insertColumns(createInsertColumns(ctx.columnNames(), ctx.start.getStartIndex()))
+                .values(createInsertValuesSegments(ctx.assignmentValues()));
         if (null != ctx.outputClause()) {
-            result.setOutput((OutputSegment) visit(ctx.outputClause()));
+            result.output((OutputSegment) visit(ctx.outputClause()));
         }
-        return result;
+        return result.build();
     }
     
     private Collection<InsertValuesSegment> createInsertValuesSegments(final Collection<AssignmentValuesContext> assignmentValuesContexts) {
@@ -1634,13 +1659,13 @@ public abstract class SQLServerStatementVisitor extends SQLServerStatementBaseVi
     
     @Override
     public ASTNode visitInsertSelectClause(final InsertSelectClauseContext ctx) {
-        InsertStatement result = new InsertStatement(databaseType);
-        result.setInsertColumns(createInsertColumns(ctx.columnNames(), ctx.start.getStartIndex()));
-        result.setInsertSelect(createInsertSelectSegment(ctx));
+        InsertStatement.InsertStatementBuilder result = InsertStatement.builder().databaseType(databaseType)
+                .insertColumns(createInsertColumns(ctx.columnNames(), ctx.start.getStartIndex()))
+                .insertSelect(createInsertSelectSegment(ctx));
         if (null != ctx.outputClause()) {
-            result.setOutput((OutputSegment) visit(ctx.outputClause()));
+            result.output((OutputSegment) visit(ctx.outputClause()));
         }
-        return result;
+        return result.build();
     }
     
     @SuppressWarnings("unchecked")
diff --git a/parser/sql/statement/core/src/main/java/org/apache/shardingsphere/sql/parser/statement/core/statement/type/dml/InsertStatement.java b/parser/sql/statement/core/src/main/java/org/apache/shardingsphere/sql/parser/statement/core/statement/type/dml/InsertStatement.java
index 9644e2b89a6..679c16a5c42 100644
--- a/parser/sql/statement/core/src/main/java/org/apache/shardingsphere/sql/parser/statement/core/statement/type/dml/InsertStatement.java
+++ b/parser/sql/statement/core/src/main/java/org/apache/shardingsphere/sql/parser/statement/core/statement/type/dml/InsertStatement.java
@@ -17,8 +17,8 @@
 
 package org.apache.shardingsphere.sql.parser.statement.core.statement.type.dml;
 
+import lombok.Builder;
 import lombok.Getter;
-import lombok.Setter;
 import org.apache.shardingsphere.database.connector.core.type.DatabaseType;
 import org.apache.shardingsphere.sql.parser.statement.core.segment.dml.ReturningSegment;
 import org.apache.shardingsphere.sql.parser.statement.core.segment.dml.assignment.InsertValuesSegment;
@@ -50,53 +50,80 @@ import java.util.Optional;
  * Insert statement.
  */
 @Getter
-@Setter
 public final class InsertStatement extends DMLStatement {
     
-    private SimpleTableSegment table;
+    private final SimpleTableSegment table;
     
-    private InsertColumnsSegment insertColumns;
+    private final InsertColumnsSegment insertColumns;
     
-    private SubquerySegment insertSelect;
+    private final SubquerySegment insertSelect;
     
-    private SetAssignmentSegment setAssignment;
+    private final SetAssignmentSegment setAssignment;
     
-    private OnDuplicateKeyColumnsSegment onDuplicateKeyColumns;
+    private final OnDuplicateKeyColumnsSegment onDuplicateKeyColumns;
     
-    private ValueReferenceSegment valueReference;
+    private final ValueReferenceSegment valueReference;
     
-    private ReturningSegment returning;
+    private final ReturningSegment returning;
     
-    private OutputSegment output;
+    private final OutputSegment output;
     
-    private WithSegment with;
+    private final WithSegment with;
     
-    private MultiTableInsertType multiTableInsertType;
+    private final MultiTableInsertType multiTableInsertType;
     
-    private MultiTableInsertIntoSegment multiTableInsertInto;
+    private final MultiTableInsertIntoSegment multiTableInsertInto;
     
-    private MultiTableConditionalIntoSegment multiTableConditionalInto;
+    private final MultiTableConditionalIntoSegment multiTableConditionalInto;
     
-    private WhereSegment where;
+    private final WhereSegment where;
     
-    private ExecSegment exec;
+    private final ExecSegment exec;
     
-    private WithTableHintSegment withTableHint;
+    private final WithTableHintSegment withTableHint;
     
-    private FunctionSegment rowSetFunction;
+    private final FunctionSegment rowSetFunction;
     
-    private boolean ignore;
+    private final boolean ignore;
     
-    private boolean replace;
+    private final boolean replace;
     
-    private final Collection<InsertValuesSegment> values = new LinkedList<>();
+    private final Collection<InsertValuesSegment> values;
     
-    private final Collection<ColumnSegment> derivedInsertColumns = new LinkedList<>();
+    private final Collection<ColumnSegment> derivedInsertColumns;
     
-    private SQLStatementAttributes attributes;
+    private final SQLStatementAttributes attributes;
     
-    public InsertStatement(final DatabaseType databaseType) {
+    @Builder
+    private InsertStatement(final DatabaseType databaseType, final SimpleTableSegment table, final InsertColumnsSegment insertColumns,
+                            final SubquerySegment insertSelect, final SetAssignmentSegment setAssignment, final OnDuplicateKeyColumnsSegment onDuplicateKeyColumns,
+                            final ValueReferenceSegment valueReference, final ReturningSegment returning, final OutputSegment output, final WithSegment with,
+                            final MultiTableInsertType multiTableInsertType, final MultiTableInsertIntoSegment multiTableInsertInto,
+                            final MultiTableConditionalIntoSegment multiTableConditionalInto, final WhereSegment where, final ExecSegment exec,
+                            final WithTableHintSegment withTableHint, final FunctionSegment rowSetFunction, final boolean ignore, final boolean replace,
+                            final Collection<InsertValuesSegment> values, final Collection<ColumnSegment> derivedInsertColumns) {
         super(databaseType);
+        this.table = table;
+        this.insertColumns = insertColumns;
+        this.insertSelect = insertSelect;
+        this.setAssignment = setAssignment;
+        this.onDuplicateKeyColumns = onDuplicateKeyColumns;
+        this.valueReference = valueReference;
+        this.returning = returning;
+        this.output = output;
+        this.with = with;
+        this.multiTableInsertType = multiTableInsertType;
+        this.multiTableInsertInto = multiTableInsertInto;
+        this.multiTableConditionalInto = multiTableConditionalInto;
+        this.where = where;
+        this.exec = exec;
+        this.withTableHint = withTableHint;
+        this.rowSetFunction = rowSetFunction;
+        this.ignore = ignore;
+        this.replace = replace;
+        this.values = null == values ? new LinkedList<>() : values;
+        this.derivedInsertColumns = null == derivedInsertColumns ? new LinkedList<>() : derivedInsertColumns;
+        attributes = new SQLStatementAttributes(new WithSQLStatementAttribute(with));
     }
     
     /**
@@ -254,6 +281,5 @@ public final class InsertStatement extends DMLStatement {
     
     @Override
     public void buildAttributes() {
-        attributes = new SQLStatementAttributes(new WithSQLStatementAttribute(with));
     }
 }
diff --git a/parser/sql/statement/core/src/test/java/org/apache/shardingsphere/sql/parser/statement/core/util/MultiSQLSplitterTest.java b/parser/sql/statement/core/src/test/java/org/apache/shardingsphere/sql/parser/statement/core/util/MultiSQLSplitterTest.java
index 76bbd131c2d..99231982e54 100644
--- a/parser/sql/statement/core/src/test/java/org/apache/shardingsphere/sql/parser/statement/core/util/MultiSQLSplitterTest.java
+++ b/parser/sql/statement/core/src/test/java/org/apache/shardingsphere/sql/parser/statement/core/util/MultiSQLSplitterTest.java
@@ -49,7 +49,7 @@ class MultiSQLSplitterTest {
         return Stream.of(
                 Arguments.of("nonDmlSample", new UpdateStatement(DATABASE_TYPE), Arrays.asList("select * from t_order;", "select * from t_order_item;"), false),
                 Arguments.of("singleStatementFalse", new UpdateStatement(DATABASE_TYPE), Collections.singletonList("update t_order set status='OK' where id=1"), false),
-                Arguments.of("insertWithBlockComment", new InsertStatement(DATABASE_TYPE),
+                Arguments.of("insertWithBlockComment", InsertStatement.builder().databaseType(DATABASE_TYPE).build(),
                         Arrays.asList("   /*comment*/ INSERT INTO t_order VALUES (1);", "/*remark*/ insert into t_order values (2)"), true),
                 Arguments.of("updateWithDashComment", new UpdateStatement(DATABASE_TYPE),
                         Arrays.asList("-- comment before\r\nupdate t_order set status='PAID' where id=1;", "-- \t\nupdate t_order set status='FAIL' where id=2;"), true),
@@ -60,7 +60,8 @@ class MultiSQLSplitterTest {
                 Arguments.of("hashCommentWithCROnly", DeleteStatement.builder().databaseType(DATABASE_TYPE).build(),
                         Arrays.asList("# comment\rdelete from t_order where id=1;", "# comment\rdelete from t_order where id=2;"), true),
                 Arguments.of("updateTypeMismatch", new UpdateStatement(DATABASE_TYPE), Arrays.asList("update t_order set status='PAID' where id=1;", "select * from t_order"), false),
-                Arguments.of("unterminatedBlockComment", new InsertStatement(DATABASE_TYPE), Arrays.asList("/* incomplete comment", "insert into t_order values (1);"), false),
+                Arguments.of("unterminatedBlockComment", InsertStatement.builder().databaseType(DATABASE_TYPE).build(), Arrays.asList("/* incomplete comment", "insert into t_order values (1);"),
+                        false),
                 Arguments.of("dashCommentOnlySegment", new UpdateStatement(DATABASE_TYPE), Arrays.asList("--", "update t_order set status='DONE' where id=1;"), false),
                 Arguments.of("whitespaceOnlySegment", new UpdateStatement(DATABASE_TYPE), Arrays.asList("   \t ", "update t_order set status='DONE' where id=1;"), false));
     }
diff --git a/proxy/backend/core/src/test/java/org/apache/shardingsphere/proxy/backend/connector/ProxySQLExecutorTest.java b/proxy/backend/core/src/test/java/org/apache/shardingsphere/proxy/backend/connector/ProxySQLExecutorTest.java
index fc25c621a20..8f0411f3101 100644
--- a/proxy/backend/core/src/test/java/org/apache/shardingsphere/proxy/backend/connector/ProxySQLExecutorTest.java
+++ b/proxy/backend/core/src/test/java/org/apache/shardingsphere/proxy/backend/connector/ProxySQLExecutorTest.java
@@ -420,9 +420,7 @@ class ProxySQLExecutorTest {
     }
     
     private InsertStatement createInsertStatement(final DatabaseType databaseType) {
-        InsertStatement result = new InsertStatement(databaseType);
-        result.setTable(new SimpleTableSegment(new TableNameSegment(0, 0, new IdentifierValue("t_order"))));
-        return result;
+        return InsertStatement.builder().databaseType(databaseType).table(new SimpleTableSegment(new TableNameSegment(0, 0, new IdentifierValue("t_order")))).build();
     }
     
     @SneakyThrows(ReflectiveOperationException.class)
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 489a4345c7c..a33f649950d 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
@@ -236,7 +236,7 @@ class StandardDatabaseProxyConnectorTest {
     void assertExecuteWithImplicitCommitTransaction() throws SQLException {
         when(databaseConnectionManager.getConnectionSession().isAutoCommit()).thenReturn(true);
         when(databaseConnectionManager.getConnectionSession().getConnectionContext().getTransactionContext().getTransactionType()).thenReturn(Optional.of("XA"));
-        SQLStatementContext sqlStatementContext = createSQLStatementContext(new InsertStatement(databaseType));
+        SQLStatementContext sqlStatementContext = createSQLStatementContext(InsertStatement.builder().databaseType(databaseType).build());
         DatabaseProxyConnector engine = createDatabaseProxyConnector(JDBCDriverType.STATEMENT, createQueryContext(sqlStatementContext, mockDatabase()));
         ProxySQLExecutor proxySQLExecutor = mock(ProxySQLExecutor.class, RETURNS_DEEP_STUBS);
         setField(engine, "proxySQLExecutor", proxySQLExecutor);
@@ -265,7 +265,7 @@ class StandardDatabaseProxyConnectorTest {
     void assertExecuteWithImplicitCommitTransactionAndException() throws SQLException {
         when(databaseConnectionManager.getConnectionSession().isAutoCommit()).thenReturn(true);
         when(databaseConnectionManager.getConnectionSession().getConnectionContext().getTransactionContext().getTransactionType()).thenReturn(Optional.of("XA"));
-        SQLStatementContext sqlStatementContext = createSQLStatementContext(new InsertStatement(databaseType));
+        SQLStatementContext sqlStatementContext = createSQLStatementContext(InsertStatement.builder().databaseType(databaseType).build());
         ProxySQLExecutor proxySQLExecutor = mock(ProxySQLExecutor.class, RETURNS_DEEP_STUBS);
         DatabaseProxyConnector engine = createDatabaseProxyConnector(JDBCDriverType.STATEMENT, createQueryContext(sqlStatementContext, mockDatabase()));
         setField(engine, "proxySQLExecutor", proxySQLExecutor);
@@ -292,7 +292,7 @@ class StandardDatabaseProxyConnectorTest {
     @Test
     void assertExecuteWithUpdateResultAndAccumulate() throws SQLException {
         InsertStatementContext sqlStatementContext = mock(InsertStatementContext.class, RETURNS_DEEP_STUBS);
-        InsertStatement insertStatement = new InsertStatement(databaseType);
+        InsertStatement insertStatement = InsertStatement.builder().databaseType(databaseType).build();
         insertStatement.buildAttributes();
         when(sqlStatementContext.getSqlStatement()).thenReturn(insertStatement);
         when(sqlStatementContext.getTablesContext().getDatabaseNames()).thenReturn(Collections.emptyList());
@@ -617,7 +617,7 @@ class StandardDatabaseProxyConnectorTest {
     
     @Test
     void assertExecuteWithUpdateResultAndNoAccumulate() throws SQLException {
-        SQLStatementContext sqlStatementContext = createSQLStatementContext(new InsertStatement(databaseType));
+        SQLStatementContext sqlStatementContext = createSQLStatementContext(InsertStatement.builder().databaseType(databaseType).build());
         when(sqlStatementContext.getTablesContext().getTableNames()).thenReturn(Collections.singleton("t_order"));
         ShardingSphereDatabase database = mockDatabase();
         when(database.getRuleMetaData().getAttributes(DataNodeRuleAttribute.class)).thenReturn(Collections.singleton(mock(DataNodeRuleAttribute.class)));
@@ -644,19 +644,19 @@ class StandardDatabaseProxyConnectorTest {
     
     @Test
     void assertExecuteWithoutImplicitCommitWhenSingleExecutionUnit() throws SQLException {
-        InsertStatement insertStatement = new InsertStatement(databaseType);
+        InsertStatement insertStatement = InsertStatement.builder().databaseType(databaseType).build();
         assertThat(executeWithImplicitCommitCondition(insertStatement, "XA", false, 1), isA(UpdateResponseHeader.class));
     }
     
     @Test
     void assertExecuteWithoutImplicitCommitWhenLocalTransaction() throws SQLException {
-        InsertStatement insertStatement = new InsertStatement(databaseType);
+        InsertStatement insertStatement = InsertStatement.builder().databaseType(databaseType).build();
         assertThat(executeWithImplicitCommitCondition(insertStatement, "LOCAL", false, 2), isA(UpdateResponseHeader.class));
     }
     
     @Test
     void assertExecuteWithoutImplicitCommitWhenAlreadyInTransaction() throws SQLException {
-        InsertStatement insertStatement = new InsertStatement(databaseType);
+        InsertStatement insertStatement = InsertStatement.builder().databaseType(databaseType).build();
         assertThat(executeWithImplicitCommitCondition(insertStatement, "XA", true, 2), isA(UpdateResponseHeader.class));
     }
     
diff --git a/proxy/backend/dialect/mysql/src/test/java/org/apache/shardingsphere/proxy/backend/mysql/connector/sane/MySQLDialectSaneQueryResultEngineTest.java b/proxy/backend/dialect/mysql/src/test/java/org/apache/shardingsphere/proxy/backend/mysql/connector/sane/MySQLDialectSaneQueryResultEngineTest.java
index 528f0ce45d9..cc817e61173 100644
--- a/proxy/backend/dialect/mysql/src/test/java/org/apache/shardingsphere/proxy/backend/mysql/connector/sane/MySQLDialectSaneQueryResultEngineTest.java
+++ b/proxy/backend/dialect/mysql/src/test/java/org/apache/shardingsphere/proxy/backend/mysql/connector/sane/MySQLDialectSaneQueryResultEngineTest.java
@@ -106,7 +106,7 @@ class MySQLDialectSaneQueryResultEngineTest {
     
     @Test
     void assertGetSaneQueryResultForOtherStatements() {
-        assertThat(new MySQLDialectSaneQueryResultEngine().getSaneQueryResult(new InsertStatement(databaseType), new SQLException("")), is(Optional.empty()));
+        assertThat(new MySQLDialectSaneQueryResultEngine().getSaneQueryResult(InsertStatement.builder().databaseType(databaseType).build(), new SQLException("")), is(Optional.empty()));
     }
     
     @Test
diff --git a/proxy/frontend/dialect/opengauss/src/test/java/org/apache/shardingsphere/proxy/frontend/opengauss/command/query/simple/OpenGaussComQueryExecutorTest.java b/proxy/frontend/dialect/opengauss/src/test/java/org/apache/shardingsphere/proxy/frontend/opengauss/command/query/simple/OpenGaussComQueryExecutorTest.java
index 7698f204bd3..9b6abf2a31f 100644
--- a/proxy/frontend/dialect/opengauss/src/test/java/org/apache/shardingsphere/proxy/frontend/opengauss/command/query/simple/OpenGaussComQueryExecutorTest.java
+++ b/proxy/frontend/dialect/opengauss/src/test/java/org/apache/shardingsphere/proxy/frontend/opengauss/command/query/simple/OpenGaussComQueryExecutorTest.java
@@ -164,7 +164,7 @@ class OpenGaussComQueryExecutorTest {
     
     @Test
     void assertExecuteUpdateReturnsCommandCompleteForDML() throws SQLException {
-        when(proxyBackendHandler.execute()).thenReturn(new UpdateResponseHeader(new InsertStatement(databaseType)));
+        when(proxyBackendHandler.execute()).thenReturn(new UpdateResponseHeader(InsertStatement.builder().databaseType(databaseType).build()));
         Collection<DatabasePacket> actualPackets = queryExecutor.execute();
         assertThat(new LinkedList<>(actualPackets).getFirst(), is(isA(PostgreSQLCommandCompletePacket.class)));
         assertThat(queryExecutor.getResponseType(), is(ResponseType.UPDATE));
diff --git a/proxy/frontend/dialect/postgresql/src/test/java/org/apache/shardingsphere/proxy/frontend/postgresql/command/query/extended/PortalTest.java b/proxy/frontend/dialect/postgresql/src/test/java/org/apache/shardingsphere/proxy/frontend/postgresql/command/query/extended/PortalTest.java
index 1521f1ccb25..a6c337220e5 100644
--- a/proxy/frontend/dialect/postgresql/src/test/java/org/apache/shardingsphere/proxy/frontend/postgresql/command/query/extended/PortalTest.java
+++ b/proxy/frontend/dialect/postgresql/src/test/java/org/apache/shardingsphere/proxy/frontend/postgresql/command/query/extended/PortalTest.java
@@ -197,7 +197,7 @@ class PortalTest {
         when(proxyBackendHandler.execute()).thenReturn(mock(UpdateResponseHeader.class));
         when(proxyBackendHandler.next()).thenReturn(false);
         InsertStatementContext insertStatementContext = mock(InsertStatementContext.class, RETURNS_DEEP_STUBS);
-        when(insertStatementContext.getSqlStatement()).thenReturn(new InsertStatement(databaseType));
+        when(insertStatementContext.getSqlStatement()).thenReturn(InsertStatement.builder().databaseType(databaseType).build());
         when(insertStatementContext.getTablesContext().getDatabaseName()).thenReturn(Optional.empty());
         PostgreSQLServerPreparedStatement preparedStatement = new PostgreSQLServerPreparedStatement(
                 "", insertStatementContext, new HintValueContext(), Collections.emptyList(), Collections.emptyList());
diff --git a/proxy/frontend/dialect/postgresql/src/test/java/org/apache/shardingsphere/proxy/frontend/postgresql/command/query/extended/PostgreSQLBatchedStatementsExecutorTest.java b/proxy/frontend/dialect/postgresql/src/test/java/org/apache/shardingsphere/proxy/frontend/postgresql/command/query/extended/PostgreSQLBatchedStatementsExecutorTest.java
index 6c8c0b8e9d0..0458d38c1e3 100644
--- a/proxy/frontend/dialect/postgresql/src/test/java/org/apache/shardingsphere/proxy/frontend/postgresql/command/query/extended/PostgreSQLBatchedStatementsExecutorTest.java
+++ b/proxy/frontend/dialect/postgresql/src/test/java/org/apache/shardingsphere/proxy/frontend/postgresql/command/query/extended/PostgreSQLBatchedStatementsExecutorTest.java
@@ -194,8 +194,7 @@ class PostgreSQLBatchedStatementsExecutorTest {
     }
     
     private InsertStatementContext mockInsertStatementContext() {
-        InsertStatement insertStatement = new InsertStatement(databaseType);
-        insertStatement.setTable(new SimpleTableSegment(new TableNameSegment(0, 0, new IdentifierValue("t"))));
+        InsertStatement insertStatement = InsertStatement.builder().databaseType(databaseType).table(new SimpleTableSegment(new TableNameSegment(0, 0, new IdentifierValue("t")))).build();
         InsertStatementContext result = mock(InsertStatementContext.class);
         when(result.getSqlStatement()).thenReturn(insertStatement);
         return result;
diff --git a/proxy/frontend/dialect/postgresql/src/test/java/org/apache/shardingsphere/proxy/frontend/postgresql/command/query/simple/PostgreSQLComQueryExecutorTest.java b/proxy/frontend/dialect/postgresql/src/test/java/org/apache/shardingsphere/proxy/frontend/postgresql/command/query/simple/PostgreSQLComQueryExecutorTest.java
index ad4cf9990a0..698240f598e 100644
--- a/proxy/frontend/dialect/postgresql/src/test/java/org/apache/shardingsphere/proxy/frontend/postgresql/command/query/simple/PostgreSQLComQueryExecutorTest.java
+++ b/proxy/frontend/dialect/postgresql/src/test/java/org/apache/shardingsphere/proxy/frontend/postgresql/command/query/simple/PostgreSQLComQueryExecutorTest.java
@@ -223,7 +223,7 @@ class PostgreSQLComQueryExecutorTest {
         return Stream.of(
                 Arguments.of("commit statement", new CommitStatement(DATABASE_TYPE), PostgreSQLCommandCompletePacket.class, "COMMIT", true),
                 Arguments.of("rollback statement", new RollbackStatement(DATABASE_TYPE), PostgreSQLCommandCompletePacket.class, "ROLLBACK", true),
-                Arguments.of("recognized command", new InsertStatement(DATABASE_TYPE), PostgreSQLCommandCompletePacket.class, "INSERT", false),
+                Arguments.of("recognized command", InsertStatement.builder().databaseType(DATABASE_TYPE).build(), PostgreSQLCommandCompletePacket.class, "INSERT", false),
                 Arguments.of("empty statement", new EmptyStatement(DATABASE_TYPE), PostgreSQLEmptyQueryResponsePacket.class, null, false),
                 Arguments.of("unrecognized statement", new SQLStatement(DATABASE_TYPE), PostgreSQLCommandCompletePacket.class, "", false));
     }