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 2025/08/18 10:06:54 UTC

(shardingsphere) branch master updated: Refactor sql rewrite GroupedParameterBuilder and ShardingPaginationParameterRewriter (#36342)

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

zhaojinchao 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 12db593e0b5 Refactor sql rewrite GroupedParameterBuilder and ShardingPaginationParameterRewriter (#36342)
12db593e0b5 is described below

commit 12db593e0b5ca7a087abe2a95a41a520c302e775
Author: Zhengqiang Duan <du...@apache.org>
AuthorDate: Mon Aug 18 18:06:48 2025 +0800

    Refactor sql rewrite GroupedParameterBuilder and ShardingPaginationParameterRewriter (#36342)
---
 ...OnDuplicateKeyUpdateValueParameterRewriter.java |  8 ++--
 .../impl/ShardingPaginationParameterRewriter.java  | 39 ++++++++++++---
 .../type/dml/InsertStatementBindingContext.java    |  3 --
 .../dml/expression/ExpressionSegmentBinder.java    |  5 ++
 .../dml/expression/type/RowExpressionBinder.java   | 56 ++++++++++++++++++++++
 .../type/dml/InsertStatementContextTest.java       |  3 +-
 .../infra/rewrite/context/SQLRewriteContext.java   | 21 ++++++--
 .../rewrite/engine/RouteSQLRewriteEngine.java      |  8 +++-
 .../builder/impl/GroupedParameterBuilder.java      | 23 +++++++--
 .../rewrite/context/SQLRewriteContextTest.java     |  2 +
 .../builder/impl/GroupedParameterBuilderTest.java  | 21 ++++----
 .../test/it/rewrite/engine/SQLRewriterIT.java      |  4 +-
 12 files changed, 156 insertions(+), 37 deletions(-)

diff --git a/features/encrypt/core/src/main/java/org/apache/shardingsphere/encrypt/rewrite/parameter/rewriter/EncryptInsertOnDuplicateKeyUpdateValueParameterRewriter.java b/features/encrypt/core/src/main/java/org/apache/shardingsphere/encrypt/rewrite/parameter/rewriter/EncryptInsertOnDuplicateKeyUpdateValueParameterRewriter.java
index ea36178ea56..81d82a38690 100644
--- a/features/encrypt/core/src/main/java/org/apache/shardingsphere/encrypt/rewrite/parameter/rewriter/EncryptInsertOnDuplicateKeyUpdateValueParameterRewriter.java
+++ b/features/encrypt/core/src/main/java/org/apache/shardingsphere/encrypt/rewrite/parameter/rewriter/EncryptInsertOnDuplicateKeyUpdateValueParameterRewriter.java
@@ -68,13 +68,13 @@ public final class EncryptInsertOnDuplicateKeyUpdateValueParameterRewriter imple
             }
             EncryptColumn encryptColumn = rule.getEncryptTable(tableName).getEncryptColumn(logicColumnName);
             Object cipherColumnValue = encryptColumn.getCipher().encrypt(databaseName, schemaName, tableName, logicColumnName, plainValue);
-            groupedParamBuilder.getGenericParameterBuilder().addReplacedParameters(index, cipherColumnValue);
+            groupedParamBuilder.getAfterGenericParameterBuilder().addReplacedParameters(index, cipherColumnValue);
             Collection<Object> addedParams = buildAddedParams(schemaName, tableName, encryptColumn, logicColumnName, plainValue);
             if (!addedParams.isEmpty()) {
-                if (!groupedParamBuilder.getGenericParameterBuilder().getAddedIndexAndParameters().containsKey(index)) {
-                    groupedParamBuilder.getGenericParameterBuilder().getAddedIndexAndParameters().put(index, new LinkedList<>());
+                if (!groupedParamBuilder.getAfterGenericParameterBuilder().getAddedIndexAndParameters().containsKey(index)) {
+                    groupedParamBuilder.getAfterGenericParameterBuilder().getAddedIndexAndParameters().put(index, new LinkedList<>());
                 }
-                groupedParamBuilder.getGenericParameterBuilder().getAddedIndexAndParameters().get(index).addAll(addedParams);
+                groupedParamBuilder.getAfterGenericParameterBuilder().getAddedIndexAndParameters().get(index).addAll(addedParams);
             }
         }
     }
diff --git a/features/sharding/core/src/main/java/org/apache/shardingsphere/sharding/rewrite/parameter/impl/ShardingPaginationParameterRewriter.java b/features/sharding/core/src/main/java/org/apache/shardingsphere/sharding/rewrite/parameter/impl/ShardingPaginationParameterRewriter.java
index af86e17230d..faa58f21eb2 100644
--- a/features/sharding/core/src/main/java/org/apache/shardingsphere/sharding/rewrite/parameter/impl/ShardingPaginationParameterRewriter.java
+++ b/features/sharding/core/src/main/java/org/apache/shardingsphere/sharding/rewrite/parameter/impl/ShardingPaginationParameterRewriter.java
@@ -22,6 +22,7 @@ import org.apache.shardingsphere.infra.binder.context.segment.select.pagination.
 import org.apache.shardingsphere.infra.binder.context.statement.SQLStatementContext;
 import org.apache.shardingsphere.infra.binder.context.statement.type.dml.SelectStatementContext;
 import org.apache.shardingsphere.infra.rewrite.parameter.builder.ParameterBuilder;
+import org.apache.shardingsphere.infra.rewrite.parameter.builder.impl.GroupedParameterBuilder;
 import org.apache.shardingsphere.infra.rewrite.parameter.builder.impl.StandardParameterBuilder;
 import org.apache.shardingsphere.infra.rewrite.parameter.rewriter.ParameterRewriter;
 import org.apache.shardingsphere.infra.route.context.RouteContext;
@@ -44,15 +45,41 @@ public final class ShardingPaginationParameterRewriter implements ParameterRewri
     @Override
     public void rewrite(final ParameterBuilder paramBuilder, final SQLStatementContext sqlStatementContext, final List<Object> params) {
         PaginationContext pagination = ((SelectStatementContext) sqlStatementContext).getPaginationContext();
-        pagination.getOffsetParameterIndex().ifPresent(optional -> rewriteOffset(pagination, optional, (StandardParameterBuilder) paramBuilder));
-        pagination.getRowCountParameterIndex().ifPresent(optional -> rewriteRowCount(pagination, optional, (StandardParameterBuilder) paramBuilder, sqlStatementContext));
+        pagination.getOffsetParameterIndex().ifPresent(optional -> rewriteOffset(pagination, optional, paramBuilder));
+        pagination.getRowCountParameterIndex().ifPresent(optional -> rewriteRowCount(pagination, optional, paramBuilder, sqlStatementContext));
     }
     
-    private void rewriteOffset(final PaginationContext pagination, final int offsetParamIndex, final StandardParameterBuilder paramBuilder) {
-        paramBuilder.addReplacedParameters(offsetParamIndex, pagination.getRevisedOffset());
+    private void rewriteOffset(final PaginationContext pagination, final int offsetParamIndex, final ParameterBuilder paramBuilder) {
+        if (paramBuilder instanceof StandardParameterBuilder) {
+            ((StandardParameterBuilder) paramBuilder).addReplacedParameters(offsetParamIndex, pagination.getRevisedOffset());
+            return;
+        }
+        rewriteOffset(pagination, offsetParamIndex, (GroupedParameterBuilder) paramBuilder);
     }
     
-    private void rewriteRowCount(final PaginationContext pagination, final int rowCountParamIndex, final StandardParameterBuilder paramBuilder, final SQLStatementContext sqlStatementContext) {
-        paramBuilder.addReplacedParameters(rowCountParamIndex, pagination.getRevisedRowCount((SelectStatementContext) sqlStatementContext));
+    private void rewriteOffset(final PaginationContext pagination, final int offsetParamIndex, final GroupedParameterBuilder paramBuilder) {
+        if (paramBuilder.isContainsGroupedParams()) {
+            paramBuilder.getAfterGenericParameterBuilder().addReplacedParameters(offsetParamIndex - paramBuilder.getAfterGenericParameterOffset(), pagination.getRevisedOffset());
+        } else {
+            paramBuilder.getBeforeGenericParameterBuilder().addReplacedParameters(offsetParamIndex, pagination.getRevisedOffset());
+        }
+    }
+    
+    private void rewriteRowCount(final PaginationContext pagination, final int rowCountParamIndex, final ParameterBuilder paramBuilder, final SQLStatementContext sqlStatementContext) {
+        if (paramBuilder instanceof StandardParameterBuilder) {
+            ((StandardParameterBuilder) paramBuilder).addReplacedParameters(rowCountParamIndex, pagination.getRevisedRowCount((SelectStatementContext) sqlStatementContext));
+            return;
+        }
+        rewriteRowCount(pagination, rowCountParamIndex, (GroupedParameterBuilder) paramBuilder, (SelectStatementContext) sqlStatementContext);
+    }
+    
+    private static void rewriteRowCount(final PaginationContext pagination, final int rowCountParamIndex, final GroupedParameterBuilder paramBuilder,
+                                        final SelectStatementContext sqlStatementContext) {
+        if (paramBuilder.isContainsGroupedParams()) {
+            paramBuilder.getAfterGenericParameterBuilder().addReplacedParameters(rowCountParamIndex - paramBuilder.getAfterGenericParameterOffset(),
+                    pagination.getRevisedRowCount(sqlStatementContext));
+        } else {
+            paramBuilder.getBeforeGenericParameterBuilder().addReplacedParameters(rowCountParamIndex, pagination.getRevisedRowCount(sqlStatementContext));
+        }
     }
 }
diff --git a/infra/binder/core/src/main/java/org/apache/shardingsphere/infra/binder/context/statement/type/dml/InsertStatementBindingContext.java b/infra/binder/core/src/main/java/org/apache/shardingsphere/infra/binder/context/statement/type/dml/InsertStatementBindingContext.java
index 0dddc337854..45415e6562e 100644
--- a/infra/binder/core/src/main/java/org/apache/shardingsphere/infra/binder/context/statement/type/dml/InsertStatementBindingContext.java
+++ b/infra/binder/core/src/main/java/org/apache/shardingsphere/infra/binder/context/statement/type/dml/InsertStatementBindingContext.java
@@ -135,9 +135,6 @@ public final class InsertStatementBindingContext implements SQLStatementContext
         for (InsertValueContext each : insertValueContexts) {
             result.add(each.getParameters());
         }
-        if (null != insertSelectContext && !insertSelectContext.getParameters().isEmpty()) {
-            result.add(insertSelectContext.getParameters());
-        }
         return result;
     }
     
diff --git a/infra/binder/core/src/main/java/org/apache/shardingsphere/infra/binder/engine/segment/dml/expression/ExpressionSegmentBinder.java b/infra/binder/core/src/main/java/org/apache/shardingsphere/infra/binder/engine/segment/dml/expression/ExpressionSegmentBinder.java
index c37c898c1ab..e864546a39f 100644
--- a/infra/binder/core/src/main/java/org/apache/shardingsphere/infra/binder/engine/segment/dml/expression/ExpressionSegmentBinder.java
+++ b/infra/binder/core/src/main/java/org/apache/shardingsphere/infra/binder/engine/segment/dml/expression/ExpressionSegmentBinder.java
@@ -35,6 +35,7 @@ import org.apache.shardingsphere.infra.binder.engine.segment.dml.expression.type
 import org.apache.shardingsphere.infra.binder.engine.segment.dml.expression.type.NotExpressionBinder;
 import org.apache.shardingsphere.infra.binder.engine.segment.dml.expression.type.OuterJoinExpressionBinder;
 import org.apache.shardingsphere.infra.binder.engine.segment.dml.expression.type.QuantifySubqueryExpressionBinder;
+import org.apache.shardingsphere.infra.binder.engine.segment.dml.expression.type.RowExpressionBinder;
 import org.apache.shardingsphere.infra.binder.engine.segment.dml.expression.type.SubquerySegmentBinder;
 import org.apache.shardingsphere.infra.binder.engine.segment.dml.from.context.TableSegmentBinderContext;
 import org.apache.shardingsphere.infra.binder.engine.statement.SQLStatementBinderContext;
@@ -48,6 +49,7 @@ import org.apache.shardingsphere.sql.parser.statement.core.segment.dml.expr.Func
 import org.apache.shardingsphere.sql.parser.statement.core.segment.dml.expr.InExpression;
 import org.apache.shardingsphere.sql.parser.statement.core.segment.dml.expr.NotExpression;
 import org.apache.shardingsphere.sql.parser.statement.core.segment.dml.expr.QuantifySubqueryExpression;
+import org.apache.shardingsphere.sql.parser.statement.core.segment.dml.expr.RowExpression;
 import org.apache.shardingsphere.sql.parser.statement.core.segment.dml.expr.subquery.SubqueryExpressionSegment;
 import org.apache.shardingsphere.sql.parser.statement.core.segment.dml.item.AggregationDistinctProjectionSegment;
 import org.apache.shardingsphere.sql.parser.statement.core.segment.dml.item.AggregationProjectionSegment;
@@ -117,6 +119,9 @@ public final class ExpressionSegmentBinder {
         if (segment instanceof QuantifySubqueryExpression) {
             return QuantifySubqueryExpressionBinder.bind((QuantifySubqueryExpression) segment, binderContext, tableBinderContexts);
         }
+        if (segment instanceof RowExpression) {
+            return RowExpressionBinder.bind((RowExpression) segment, parentSegmentType, binderContext, tableBinderContexts, outerTableBinderContexts);
+        }
         // TODO support more ExpressionSegment bound
         return segment;
     }
diff --git a/infra/binder/core/src/main/java/org/apache/shardingsphere/infra/binder/engine/segment/dml/expression/type/RowExpressionBinder.java b/infra/binder/core/src/main/java/org/apache/shardingsphere/infra/binder/engine/segment/dml/expression/type/RowExpressionBinder.java
new file mode 100644
index 00000000000..80e3157b640
--- /dev/null
+++ b/infra/binder/core/src/main/java/org/apache/shardingsphere/infra/binder/engine/segment/dml/expression/type/RowExpressionBinder.java
@@ -0,0 +1,56 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.shardingsphere.infra.binder.engine.segment.dml.expression.type;
+
+import com.cedarsoftware.util.CaseInsensitiveMap.CaseInsensitiveString;
+import com.google.common.collect.Multimap;
+import lombok.AccessLevel;
+import lombok.NoArgsConstructor;
+import org.apache.shardingsphere.infra.binder.engine.segment.SegmentType;
+import org.apache.shardingsphere.infra.binder.engine.segment.dml.expression.ExpressionSegmentBinder;
+import org.apache.shardingsphere.infra.binder.engine.segment.dml.from.context.TableSegmentBinderContext;
+import org.apache.shardingsphere.infra.binder.engine.statement.SQLStatementBinderContext;
+import org.apache.shardingsphere.sql.parser.statement.core.segment.dml.expr.ExpressionSegment;
+import org.apache.shardingsphere.sql.parser.statement.core.segment.dml.expr.RowExpression;
+
+/**
+ * Row expression binder.
+ */
+@NoArgsConstructor(access = AccessLevel.PRIVATE)
+public final class RowExpressionBinder {
+    
+    /**
+     * Bind row expression.
+     *
+     * @param segment outer join expression segment
+     * @param parentSegmentType parent segment type
+     * @param binderContext SQL statement binder context
+     * @param tableBinderContexts table binder contexts
+     * @param outerTableBinderContexts outer table binder contexts
+     * @return bound row expression
+     */
+    public static RowExpression bind(final RowExpression segment, final SegmentType parentSegmentType,
+                                     final SQLStatementBinderContext binderContext, final Multimap<CaseInsensitiveString, TableSegmentBinderContext> tableBinderContexts,
+                                     final Multimap<CaseInsensitiveString, TableSegmentBinderContext> outerTableBinderContexts) {
+        RowExpression result = new RowExpression(segment.getStartIndex(), segment.getStopIndex(), segment.getText());
+        for (ExpressionSegment each : segment.getItems()) {
+            result.getItems().add(ExpressionSegmentBinder.bind(each, parentSegmentType, binderContext, tableBinderContexts, outerTableBinderContexts));
+        }
+        return result;
+    }
+}
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 c5c0b927078..44781b279db 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
@@ -148,8 +148,7 @@ class InsertStatementContextTest {
         InsertStatementContext actual = createInsertStatementContext(Collections.singletonList("param"), insertStatement);
         actual.setUpParameters(Collections.singletonList("param"));
         assertThat(actual.getInsertSelectContext().getSelectStatementContext().getSqlStatement().getParameterCount(), is(1));
-        assertThat(actual.getGroupedParameters().size(), is(1));
-        assertThat(actual.getGroupedParameters().iterator().next(), is(Collections.singletonList("param")));
+        assertThat(actual.getGroupedParameters().size(), is(0));
     }
     
     @Test
diff --git a/infra/rewrite/core/src/main/java/org/apache/shardingsphere/infra/rewrite/context/SQLRewriteContext.java b/infra/rewrite/core/src/main/java/org/apache/shardingsphere/infra/rewrite/context/SQLRewriteContext.java
index 10a4ec16a48..f15bcd168f7 100644
--- a/infra/rewrite/core/src/main/java/org/apache/shardingsphere/infra/rewrite/context/SQLRewriteContext.java
+++ b/infra/rewrite/core/src/main/java/org/apache/shardingsphere/infra/rewrite/context/SQLRewriteContext.java
@@ -32,6 +32,7 @@ import org.apache.shardingsphere.infra.rewrite.sql.token.common.pojo.SQLToken;
 import org.apache.shardingsphere.infra.session.connection.ConnectionContext;
 import org.apache.shardingsphere.infra.session.query.QueryContext;
 
+import java.util.ArrayList;
 import java.util.Collection;
 import java.util.LinkedList;
 import java.util.List;
@@ -68,9 +69,23 @@ public final class SQLRewriteContext {
         if (!queryContext.getHintValueContext().isSkipSQLRewrite()) {
             addSQLTokenGenerators(new DefaultTokenGeneratorBuilder(sqlStatementContext).getSQLTokenGenerators());
         }
-        parameterBuilder = containsInsertValues(sqlStatementContext)
-                ? new GroupedParameterBuilder(((InsertStatementContext) sqlStatementContext).getGroupedParameters(), ((InsertStatementContext) sqlStatementContext).getOnDuplicateKeyUpdateParameters())
-                : new StandardParameterBuilder(parameters);
+        parameterBuilder = containsGroupedParameter(sqlStatementContext) ? buildGroupedParameterBuilder(sqlStatementContext) : new StandardParameterBuilder(parameters);
+    }
+    
+    private boolean containsGroupedParameter(final SQLStatementContext sqlStatementContext) {
+        return containsInsertValues(sqlStatementContext);
+    }
+    
+    private GroupedParameterBuilder buildGroupedParameterBuilder(final SQLStatementContext sqlStatementContext) {
+        List<List<Object>> groupedParams = new ArrayList<>();
+        List<Object> beforeGenericParams = new ArrayList<>();
+        List<Object> afterGenericParams = new ArrayList<>();
+        if (sqlStatementContext instanceof InsertStatementContext) {
+            groupedParams.addAll(((InsertStatementContext) sqlStatementContext).getGroupedParameters());
+            // TODO check insertstatment whether has beforeGenericParams
+            afterGenericParams.addAll(((InsertStatementContext) sqlStatementContext).getOnDuplicateKeyUpdateParameters());
+        }
+        return new GroupedParameterBuilder(groupedParams, beforeGenericParams, afterGenericParams);
     }
     
     private boolean containsInsertValues(final SQLStatementContext sqlStatementContext) {
diff --git a/infra/rewrite/core/src/main/java/org/apache/shardingsphere/infra/rewrite/engine/RouteSQLRewriteEngine.java b/infra/rewrite/core/src/main/java/org/apache/shardingsphere/infra/rewrite/engine/RouteSQLRewriteEngine.java
index 92d2955f473..67a550d0c52 100644
--- a/infra/rewrite/core/src/main/java/org/apache/shardingsphere/infra/rewrite/engine/RouteSQLRewriteEngine.java
+++ b/infra/rewrite/core/src/main/java/org/apache/shardingsphere/infra/rewrite/engine/RouteSQLRewriteEngine.java
@@ -41,6 +41,7 @@ import org.apache.shardingsphere.sqltranslator.context.SQLTranslatorContext;
 import org.apache.shardingsphere.sqltranslator.rule.SQLTranslatorRule;
 
 import java.util.Collection;
+import java.util.Collections;
 import java.util.LinkedHashMap;
 import java.util.LinkedList;
 import java.util.List;
@@ -133,6 +134,9 @@ public final class RouteSQLRewriteEngine {
     }
     
     private List<Object> getParameters(final SQLRewriteContext sqlRewriteContext, final RouteContext routeContext, final RouteUnit routeUnit) {
+        if (sqlRewriteContext.getParameters().isEmpty()) {
+            return Collections.emptyList();
+        }
         ParameterBuilder parameterBuilder = sqlRewriteContext.getParameterBuilder();
         if (parameterBuilder instanceof StandardParameterBuilder) {
             return parameterBuilder.getParameters();
@@ -143,7 +147,7 @@ public final class RouteSQLRewriteEngine {
     }
     
     private List<Object> buildRouteParameters(final GroupedParameterBuilder paramBuilder, final RouteContext routeContext, final RouteUnit routeUnit) {
-        List<Object> result = new LinkedList<>();
+        List<Object> result = new LinkedList<>(paramBuilder.getBeforeGenericParameterBuilder().getParameters());
         int count = 0;
         for (Collection<DataNode> each : routeContext.getOriginalDataNodes()) {
             if (isInSameDataNode(each, routeUnit)) {
@@ -151,7 +155,7 @@ public final class RouteSQLRewriteEngine {
             }
             count++;
         }
-        result.addAll(paramBuilder.getGenericParameterBuilder().getParameters());
+        result.addAll(paramBuilder.getAfterGenericParameterBuilder().getParameters());
         return result;
     }
     
diff --git a/infra/rewrite/core/src/main/java/org/apache/shardingsphere/infra/rewrite/parameter/builder/impl/GroupedParameterBuilder.java b/infra/rewrite/core/src/main/java/org/apache/shardingsphere/infra/rewrite/parameter/builder/impl/GroupedParameterBuilder.java
index 8e6915db975..5e784b646f0 100644
--- a/infra/rewrite/core/src/main/java/org/apache/shardingsphere/infra/rewrite/parameter/builder/impl/GroupedParameterBuilder.java
+++ b/infra/rewrite/core/src/main/java/org/apache/shardingsphere/infra/rewrite/parameter/builder/impl/GroupedParameterBuilder.java
@@ -35,26 +35,39 @@ public final class GroupedParameterBuilder implements ParameterBuilder {
     private final List<StandardParameterBuilder> parameterBuilders;
     
     @Getter
-    private final StandardParameterBuilder genericParameterBuilder;
+    private final StandardParameterBuilder beforeGenericParameterBuilder;
+    
+    @Getter
+    private final StandardParameterBuilder afterGenericParameterBuilder;
     
     @Setter
     private String derivedColumnName;
     
-    public GroupedParameterBuilder(final List<List<Object>> groupedParams, final List<Object> genericParams) {
+    @Getter
+    private boolean containsGroupedParams;
+    
+    @Getter
+    private int afterGenericParameterOffset;
+    
+    public GroupedParameterBuilder(final List<List<Object>> groupedParams, final List<Object> beforeGenericParams, final List<Object> afterGenericParams) {
         parameterBuilders = new ArrayList<>(groupedParams.size());
+        afterGenericParameterOffset += beforeGenericParams.size();
         for (List<Object> each : groupedParams) {
             parameterBuilders.add(new StandardParameterBuilder(each));
+            containsGroupedParams = containsGroupedParams || !each.isEmpty();
+            afterGenericParameterOffset += each.size();
         }
-        genericParameterBuilder = new StandardParameterBuilder(genericParams);
+        beforeGenericParameterBuilder = new StandardParameterBuilder(beforeGenericParams);
+        afterGenericParameterBuilder = new StandardParameterBuilder(afterGenericParams);
     }
     
     @Override
     public List<Object> getParameters() {
-        List<Object> result = new LinkedList<>();
+        List<Object> result = new LinkedList<>(beforeGenericParameterBuilder.getParameters());
         for (int i = 0; i < parameterBuilders.size(); i++) {
             result.addAll(getParameters(i));
         }
-        result.addAll(genericParameterBuilder.getParameters());
+        result.addAll(afterGenericParameterBuilder.getParameters());
         return result;
     }
     
diff --git a/infra/rewrite/core/src/test/java/org/apache/shardingsphere/infra/rewrite/context/SQLRewriteContextTest.java b/infra/rewrite/core/src/test/java/org/apache/shardingsphere/infra/rewrite/context/SQLRewriteContextTest.java
index 2bb8db69167..c03b44a5167 100644
--- a/infra/rewrite/core/src/test/java/org/apache/shardingsphere/infra/rewrite/context/SQLRewriteContextTest.java
+++ b/infra/rewrite/core/src/test/java/org/apache/shardingsphere/infra/rewrite/context/SQLRewriteContextTest.java
@@ -96,6 +96,8 @@ class SQLRewriteContextTest {
         InsertStatementContext statementContext = mock(InsertStatementContext.class, RETURNS_DEEP_STUBS);
         when(statementContext.getTablesContext().getDatabaseName().isPresent()).thenReturn(false);
         when(statementContext.getInsertSelectContext()).thenReturn(null);
+        when(statementContext.getGroupedParameters()).thenReturn(Collections.emptyList());
+        when(statementContext.getOnDuplicateKeyUpdateParameters()).thenReturn(Collections.emptyList());
         QueryContext queryContext = mock(QueryContext.class, RETURNS_DEEP_STUBS);
         when(queryContext.getSqlStatementContext()).thenReturn(statementContext);
         when(queryContext.getSql()).thenReturn("INSERT INTO tbl VALUES (?)");
diff --git a/infra/rewrite/core/src/test/java/org/apache/shardingsphere/infra/rewrite/parameter/builder/impl/GroupedParameterBuilderTest.java b/infra/rewrite/core/src/test/java/org/apache/shardingsphere/infra/rewrite/parameter/builder/impl/GroupedParameterBuilderTest.java
index 3149e0f595b..6e05a56f90f 100644
--- a/infra/rewrite/core/src/test/java/org/apache/shardingsphere/infra/rewrite/parameter/builder/impl/GroupedParameterBuilderTest.java
+++ b/infra/rewrite/core/src/test/java/org/apache/shardingsphere/infra/rewrite/parameter/builder/impl/GroupedParameterBuilderTest.java
@@ -20,6 +20,7 @@ package org.apache.shardingsphere.infra.rewrite.parameter.builder.impl;
 import org.junit.jupiter.api.Test;
 
 import java.util.Arrays;
+import java.util.Collections;
 import java.util.LinkedList;
 import java.util.List;
 import java.util.Optional;
@@ -31,30 +32,30 @@ class GroupedParameterBuilderTest {
     
     @Test
     void assertGetParameters() {
-        GroupedParameterBuilder actual = new GroupedParameterBuilder(createGroupedParameters(), new LinkedList<>());
+        GroupedParameterBuilder actual = new GroupedParameterBuilder(createGroupedParameters(), Collections.emptyList(), new LinkedList<>());
         assertThat(actual.getParameters(), is(Arrays.<Object>asList(3, 4, 5, 6)));
     }
     
     @Test
     void assertGetParametersWithGenericParameters() {
-        GroupedParameterBuilder actual = new GroupedParameterBuilder(createGroupedParameters(), createGenericParameters());
+        GroupedParameterBuilder actual = new GroupedParameterBuilder(createGroupedParameters(), Collections.emptyList(), createGenericParameters());
         assertThat(actual.getParameters(), is(Arrays.<Object>asList(3, 4, 5, 6, 7, 8)));
-        assertThat(actual.getGenericParameterBuilder().getParameters(), is(Arrays.<Object>asList(7, 8)));
+        assertThat(actual.getAfterGenericParameterBuilder().getParameters(), is(Arrays.<Object>asList(7, 8)));
     }
     
     @Test
     void assertGetGenericParametersWithModify() {
-        GroupedParameterBuilder actual = new GroupedParameterBuilder(new LinkedList<>(), createGenericParameters());
-        actual.getGenericParameterBuilder().addReplacedParameters(0, 77);
-        actual.getGenericParameterBuilder().addReplacedParameters(1, 88);
-        actual.getGenericParameterBuilder().addAddedParameters(0, Arrays.asList(66, -1));
-        actual.getGenericParameterBuilder().addAddedParameters(2, Arrays.asList(99, 110));
-        assertThat(actual.getGenericParameterBuilder().getParameters(), is(Arrays.<Object>asList(77, 66, -1, 88, 99, 110)));
+        GroupedParameterBuilder actual = new GroupedParameterBuilder(new LinkedList<>(), Collections.emptyList(), createGenericParameters());
+        actual.getAfterGenericParameterBuilder().addReplacedParameters(0, 77);
+        actual.getAfterGenericParameterBuilder().addReplacedParameters(1, 88);
+        actual.getAfterGenericParameterBuilder().addAddedParameters(0, Arrays.asList(66, -1));
+        actual.getAfterGenericParameterBuilder().addAddedParameters(2, Arrays.asList(99, 110));
+        assertThat(actual.getAfterGenericParameterBuilder().getParameters(), is(Arrays.<Object>asList(77, 66, -1, 88, 99, 110)));
     }
     
     @Test
     void assertGetDerivedColumnName() {
-        GroupedParameterBuilder actual = new GroupedParameterBuilder(createGroupedParameters(), createGenericParameters());
+        GroupedParameterBuilder actual = new GroupedParameterBuilder(createGroupedParameters(), Collections.emptyList(), createGenericParameters());
         String derivedColumnName = "derivedColumnName";
         actual.setDerivedColumnName(derivedColumnName);
         assertThat(actual.getDerivedColumnName(), is(Optional.of(derivedColumnName)));
diff --git a/test/it/rewriter/src/test/java/org/apache/shardingsphere/test/it/rewrite/engine/SQLRewriterIT.java b/test/it/rewriter/src/test/java/org/apache/shardingsphere/test/it/rewrite/engine/SQLRewriterIT.java
index 202b7b34af7..2ed2464609f 100644
--- a/test/it/rewriter/src/test/java/org/apache/shardingsphere/test/it/rewrite/engine/SQLRewriterIT.java
+++ b/test/it/rewriter/src/test/java/org/apache/shardingsphere/test/it/rewrite/engine/SQLRewriterIT.java
@@ -111,12 +111,12 @@ public abstract class SQLRewriterIT {
         Collection<ShardingSphereRule> rules = createDatabaseRules(databaseConfig, schemaName, sqlStatement, databaseType);
         ShardingSphereDatabase database = new ShardingSphereDatabase(databaseName, databaseType, resourceMetaData, new RuleMetaData(rules), mockSchemas(schemaName));
         RuleMetaData globalRuleMetaData = new RuleMetaData(GlobalRulesBuilder.buildRules(Collections.emptyList(), Collections.emptyList(), new ConfigurationProperties(new Properties())));
-        ShardingSphereMetaData metaData = new ShardingSphereMetaData(Collections.singleton(database), mock(), globalRuleMetaData, mock());
+        ConfigurationProperties props = new ConfigurationProperties(rootConfig.getProps());
+        ShardingSphereMetaData metaData = new ShardingSphereMetaData(Collections.singleton(database), mock(), globalRuleMetaData, props);
         HintValueContext hintValueContext = SQLHintUtils.extractHint(testParams.getInputSQL());
         SQLStatementContext sqlStatementContext = bind(testParams, metaData, databaseName, hintValueContext, sqlStatement, sqlParserEngine);
         ConnectionContext connectionContext = createConnectionContext(database.getName());
         QueryContext queryContext = new QueryContext(sqlStatementContext, sql, testParams.getInputParameters(), hintValueContext, connectionContext, metaData);
-        ConfigurationProperties props = new ConfigurationProperties(rootConfig.getProps());
         RouteContext routeContext = new SQLRouteEngine(rules, props).route(queryContext, globalRuleMetaData, database);
         SQLRewriteEntry sqlRewriteEntry = new SQLRewriteEntry(database, globalRuleMetaData, props);
         SQLRewriteResult sqlRewriteResult = sqlRewriteEntry.rewrite(queryContext, routeContext);