You are viewing a plain text version of this content. The canonical link for it is here.
Posted to notifications@shardingsphere.apache.org by GitBox <gi...@apache.org> on 2020/05/14 09:17:06 UTC

[GitHub] [shardingsphere] tristaZero commented on a change in pull request #5590: Issue5423 and issue5465

tristaZero commented on a change in pull request #5590:
URL: https://github.com/apache/shardingsphere/pull/5590#discussion_r424974164



##########
File path: shardingsphere-underlying/shardingsphere-rewrite/shardingsphere-rewrite-engine/src/main/java/org/apache/shardingsphere/underlying/rewrite/parameter/builder/impl/GroupedParameterBuilder.java
##########
@@ -35,16 +35,18 @@
     private final List<StandardParameterBuilder> parameterBuilders;
     
     @Getter
-    private final List<Object> onDuplicateKeyUpdateAddedParameters = new LinkedList<>();
+    private final StandardParameterBuilder onDuplicateKeyUpdateParametersBuilder;
     
     @Setter
     private String derivedColumnName;
     
-    public GroupedParameterBuilder(final List<List<Object>> groupedParameters) {
+    public GroupedParameterBuilder(final List<List<Object>> groupedParameters, final List<Object> onDuplicateKeyUpdateParameters) {
         parameterBuilders = new ArrayList<>(groupedParameters.size());
         for (List<Object> each : groupedParameters) {
             parameterBuilders.add(new StandardParameterBuilder(each));
         }
+    

Review comment:
       Please remove this redundant blank line.

##########
File path: shardingsphere-underlying/shardingsphere-rewrite/shardingsphere-rewrite-engine/src/main/java/org/apache/shardingsphere/underlying/rewrite/parameter/builder/impl/GroupedParameterBuilder.java
##########
@@ -53,9 +55,7 @@ public GroupedParameterBuilder(final List<List<Object>> groupedParameters) {
         for (int i = 0; i < parameterBuilders.size(); i++) {
             result.addAll(getParameters(i));
         }
-        if (!onDuplicateKeyUpdateAddedParameters.isEmpty()) {
-            result.addAll(onDuplicateKeyUpdateAddedParameters);
-        }
+

Review comment:
       Please remove this redundant blank line.

##########
File path: shardingsphere-sql-parser/shardingsphere-sql-parser-binder/src/test/java/org/apache/shardingsphere/sql/parser/binder/segment/insert/values/OnDuplicateUpdateContextTest.java
##########
@@ -0,0 +1,147 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.shardingsphere.sql.parser.binder.segment.insert.values;
+
+import com.google.common.collect.Lists;
+import org.apache.shardingsphere.sql.parser.sql.segment.dml.assignment.AssignmentSegment;
+import org.apache.shardingsphere.sql.parser.sql.segment.dml.column.ColumnSegment;
+import org.apache.shardingsphere.sql.parser.sql.segment.dml.expr.ExpressionSegment;
+import org.apache.shardingsphere.sql.parser.sql.segment.dml.expr.simple.LiteralExpressionSegment;
+import org.apache.shardingsphere.sql.parser.sql.segment.dml.expr.simple.ParameterMarkerExpressionSegment;
+import org.apache.shardingsphere.sql.parser.sql.segment.dml.expr.simple.SimpleExpressionSegment;
+import org.apache.shardingsphere.sql.parser.sql.value.identifier.IdentifierValue;
+import org.junit.Assert;
+import org.junit.Test;
+
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.List;
+
+import static org.hamcrest.CoreMatchers.is;
+import static org.junit.Assert.assertThat;
+import static org.junit.Assert.assertTrue;
+
+public final class OnDuplicateUpdateContextTest {
+    
+    @SuppressWarnings("unchecked")
+    @Test
+    public void assertInstanceConstructedOk() throws NoSuchMethodException, InvocationTargetException, IllegalAccessException {
+        Collection<AssignmentSegment> assignments = Lists.newArrayList();
+        List<Object> parameters = Collections.emptyList();
+        int parametersOffset = 0;
+
+        OnDuplicateUpdateContext onDuplicateUpdateContext = new OnDuplicateUpdateContext(assignments, parameters, parametersOffset);
+
+        Method calculateParametersCountMethod = OnDuplicateUpdateContext.class.getDeclaredMethod("calculateParametersCount", Collection.class);
+        calculateParametersCountMethod.setAccessible(true);
+        int calculateParametersCountResult = (int) calculateParametersCountMethod.invoke(onDuplicateUpdateContext, new Object[]{assignments});
+        assertThat(onDuplicateUpdateContext.getParametersCount(), is(calculateParametersCountResult));
+
+        Method getValueExpressionsMethod = OnDuplicateUpdateContext.class.getDeclaredMethod("getValueExpressions", Collection.class);
+        getValueExpressionsMethod.setAccessible(true);
+        List<ExpressionSegment> getValueExpressionsResult = (List<ExpressionSegment>) getValueExpressionsMethod.invoke(onDuplicateUpdateContext, new Object[]{assignments});
+        assertThat(onDuplicateUpdateContext.getValueExpressions(), is(getValueExpressionsResult));
+
+        Method getParametersMethod = OnDuplicateUpdateContext.class.getDeclaredMethod("getParameters", List.class, int.class);
+        getParametersMethod.setAccessible(true);
+        List<Object> getParametersResult = (List<Object>) getParametersMethod.invoke(onDuplicateUpdateContext, new Object[]{parameters, parametersOffset});
+        assertThat(onDuplicateUpdateContext.getParameters(), is(getParametersResult));
+    }
+    
+    @Test
+    public void assertGetValueWhenParameterMarker() {
+        Collection<AssignmentSegment> assignments = makeParameterMarkerExpressionAssignmentSegment();
+        String parameterValue1 = "test1";
+        String parameterValue2 = "test2";
+        List<Object> parameters = Lists.newArrayList(parameterValue1, parameterValue2);
+        int parametersOffset = 0;
+        OnDuplicateUpdateContext onDuplicateUpdateContext = new OnDuplicateUpdateContext(assignments, parameters, parametersOffset);
+        Object valueFromInsertValueContext1 = onDuplicateUpdateContext.getValue(0);
+        assertThat(valueFromInsertValueContext1, is(parameterValue1));
+
+        Object valueFromInsertValueContext2 = onDuplicateUpdateContext.getValue(1);
+        assertThat(valueFromInsertValueContext2, is(parameterValue2));
+    }
+    
+    private Collection<AssignmentSegment> makeParameterMarkerExpressionAssignmentSegment() {
+        ParameterMarkerExpressionSegment parameterMarkerExpressionSegment = new ParameterMarkerExpressionSegment(0, 10, 5);
+        AssignmentSegment assignmentSegment1 = makeAssignmentSegment(parameterMarkerExpressionSegment);
+
+        ParameterMarkerExpressionSegment parameterMarkerExpressionSegment2 = new ParameterMarkerExpressionSegment(0, 10, 6);
+        AssignmentSegment assignmentSegment2 = makeAssignmentSegment(parameterMarkerExpressionSegment2);
+        return Lists.newArrayList(assignmentSegment1, assignmentSegment2);
+    }
+    
+    @Test
+    public void assertGetValueWhenLiteralExpressionSegment() {
+        Object literalObject = new Object();
+        Collection<AssignmentSegment> assignments = makeLiteralExpressionSegment(literalObject);
+        List<Object> parameters = Collections.emptyList();
+        OnDuplicateUpdateContext onDuplicateUpdateContext = new OnDuplicateUpdateContext(assignments, parameters, 0);
+        Object valueFromInsertValueContext = onDuplicateUpdateContext.getValue(0);
+        assertThat(valueFromInsertValueContext, is(literalObject));
+    }
+    
+    private Collection<AssignmentSegment> makeLiteralExpressionSegment(final Object literalObject) {
+        LiteralExpressionSegment parameterLiteralExpression = new LiteralExpressionSegment(0, 10, literalObject);
+        AssignmentSegment assignmentSegment = makeAssignmentSegment(parameterLiteralExpression);
+        return Collections.singleton(assignmentSegment);
+    }
+    
+    private AssignmentSegment makeAssignmentSegment(final SimpleExpressionSegment expressionSegment) {
+        int doesNotMatterLexicalIndex = 0;
+        String doesNotMatterColumnName = "columnNameStr";
+
+        ColumnSegment column = new ColumnSegment(doesNotMatterLexicalIndex, doesNotMatterLexicalIndex, new IdentifierValue(doesNotMatterColumnName));
+        return new AssignmentSegment(doesNotMatterLexicalIndex, doesNotMatterLexicalIndex, column, expressionSegment);
+    }
+    
+    @Test
+    public void assertGetParameterIndex() throws NoSuchMethodException, IllegalAccessException {
+        Collection<AssignmentSegment> assignments = Lists.newArrayList();
+        List<Object> parameters = Collections.emptyList();
+        int parametersOffset = 0;
+

Review comment:
       Please remove this redundant blank line.

##########
File path: shardingsphere-underlying/shardingsphere-rewrite/shardingsphere-rewrite-engine/src/main/java/org/apache/shardingsphere/underlying/rewrite/engine/RouteSQLRewriteEngine.java
##########
@@ -66,6 +77,8 @@ public RouteSQLRewriteResult rewrite(final SQLRewriteContext sqlRewriteContext,
             }
             count++;
         }
+        result.addAll(((GroupedParameterBuilder) parameterBuilder).getOnDuplicateKeyUpdateParametersBuilder().getParameters());
+    

Review comment:
       Please remove this redundant blank line.

##########
File path: shardingsphere-sql-parser/shardingsphere-sql-parser-binder/src/test/java/org/apache/shardingsphere/sql/parser/binder/segment/insert/values/OnDuplicateUpdateContextTest.java
##########
@@ -0,0 +1,147 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.shardingsphere.sql.parser.binder.segment.insert.values;
+
+import com.google.common.collect.Lists;
+import org.apache.shardingsphere.sql.parser.sql.segment.dml.assignment.AssignmentSegment;
+import org.apache.shardingsphere.sql.parser.sql.segment.dml.column.ColumnSegment;
+import org.apache.shardingsphere.sql.parser.sql.segment.dml.expr.ExpressionSegment;
+import org.apache.shardingsphere.sql.parser.sql.segment.dml.expr.simple.LiteralExpressionSegment;
+import org.apache.shardingsphere.sql.parser.sql.segment.dml.expr.simple.ParameterMarkerExpressionSegment;
+import org.apache.shardingsphere.sql.parser.sql.segment.dml.expr.simple.SimpleExpressionSegment;
+import org.apache.shardingsphere.sql.parser.sql.value.identifier.IdentifierValue;
+import org.junit.Assert;
+import org.junit.Test;
+
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.List;
+
+import static org.hamcrest.CoreMatchers.is;
+import static org.junit.Assert.assertThat;
+import static org.junit.Assert.assertTrue;
+
+public final class OnDuplicateUpdateContextTest {
+    
+    @SuppressWarnings("unchecked")
+    @Test
+    public void assertInstanceConstructedOk() throws NoSuchMethodException, InvocationTargetException, IllegalAccessException {
+        Collection<AssignmentSegment> assignments = Lists.newArrayList();
+        List<Object> parameters = Collections.emptyList();
+        int parametersOffset = 0;
+
+        OnDuplicateUpdateContext onDuplicateUpdateContext = new OnDuplicateUpdateContext(assignments, parameters, parametersOffset);
+
+        Method calculateParametersCountMethod = OnDuplicateUpdateContext.class.getDeclaredMethod("calculateParametersCount", Collection.class);
+        calculateParametersCountMethod.setAccessible(true);
+        int calculateParametersCountResult = (int) calculateParametersCountMethod.invoke(onDuplicateUpdateContext, new Object[]{assignments});
+        assertThat(onDuplicateUpdateContext.getParametersCount(), is(calculateParametersCountResult));
+
+        Method getValueExpressionsMethod = OnDuplicateUpdateContext.class.getDeclaredMethod("getValueExpressions", Collection.class);
+        getValueExpressionsMethod.setAccessible(true);
+        List<ExpressionSegment> getValueExpressionsResult = (List<ExpressionSegment>) getValueExpressionsMethod.invoke(onDuplicateUpdateContext, new Object[]{assignments});
+        assertThat(onDuplicateUpdateContext.getValueExpressions(), is(getValueExpressionsResult));
+
+        Method getParametersMethod = OnDuplicateUpdateContext.class.getDeclaredMethod("getParameters", List.class, int.class);
+        getParametersMethod.setAccessible(true);
+        List<Object> getParametersResult = (List<Object>) getParametersMethod.invoke(onDuplicateUpdateContext, new Object[]{parameters, parametersOffset});
+        assertThat(onDuplicateUpdateContext.getParameters(), is(getParametersResult));
+    }
+    
+    @Test
+    public void assertGetValueWhenParameterMarker() {
+        Collection<AssignmentSegment> assignments = makeParameterMarkerExpressionAssignmentSegment();
+        String parameterValue1 = "test1";
+        String parameterValue2 = "test2";
+        List<Object> parameters = Lists.newArrayList(parameterValue1, parameterValue2);
+        int parametersOffset = 0;
+        OnDuplicateUpdateContext onDuplicateUpdateContext = new OnDuplicateUpdateContext(assignments, parameters, parametersOffset);
+        Object valueFromInsertValueContext1 = onDuplicateUpdateContext.getValue(0);
+        assertThat(valueFromInsertValueContext1, is(parameterValue1));
+
+        Object valueFromInsertValueContext2 = onDuplicateUpdateContext.getValue(1);
+        assertThat(valueFromInsertValueContext2, is(parameterValue2));
+    }
+    
+    private Collection<AssignmentSegment> makeParameterMarkerExpressionAssignmentSegment() {
+        ParameterMarkerExpressionSegment parameterMarkerExpressionSegment = new ParameterMarkerExpressionSegment(0, 10, 5);
+        AssignmentSegment assignmentSegment1 = makeAssignmentSegment(parameterMarkerExpressionSegment);
+

Review comment:
       Please remove this redundant blank line.

##########
File path: shardingsphere-underlying/shardingsphere-rewrite/shardingsphere-rewrite-engine/src/main/java/org/apache/shardingsphere/underlying/rewrite/engine/RouteSQLRewriteEngine.java
##########
@@ -55,9 +55,20 @@ public RouteSQLRewriteResult rewrite(final SQLRewriteContext sqlRewriteContext,
     }
     
     private List<Object> getParameters(final ParameterBuilder parameterBuilder, final RouteResult routeResult, final RouteUnit routeUnit) {
-        if (parameterBuilder instanceof StandardParameterBuilder || routeResult.getOriginalDataNodes().isEmpty() || parameterBuilder.getParameters().isEmpty()) {
+        if (parameterBuilder instanceof StandardParameterBuilder) {
             return parameterBuilder.getParameters();
+        } else if (routeResult.getOriginalDataNodes().isEmpty()) {

Review comment:
       I prefer `if` to `else if`.

##########
File path: shardingsphere-underlying/shardingsphere-rewrite/shardingsphere-rewrite-engine/src/main/java/org/apache/shardingsphere/underlying/rewrite/engine/GenericSQLRewriteEngine.java
##########
@@ -34,6 +40,22 @@
      * @return SQL rewrite result
      */
     public GenericSQLRewriteResult rewrite(final SQLRewriteContext sqlRewriteContext) {
-        return new GenericSQLRewriteResult(new SQLRewriteUnit(new DefaultSQLBuilder(sqlRewriteContext).toSQL(), sqlRewriteContext.getParameterBuilder().getParameters()));
+        return new GenericSQLRewriteResult(new SQLRewriteUnit(new DefaultSQLBuilder(sqlRewriteContext).toSQL(), getParameters(sqlRewriteContext.getParameterBuilder())));
+    }
+    
+    private List<Object> getParameters(final ParameterBuilder parameterBuilder) {
+        if (parameterBuilder instanceof StandardParameterBuilder) {
+            return parameterBuilder.getParameters();
+        } else {

Review comment:
       It is preferable to move the content in `else {}` to the parent level.

##########
File path: shardingsphere-sql-parser/shardingsphere-sql-parser-binder/src/test/java/org/apache/shardingsphere/sql/parser/binder/statement/impl/InsertStatementContextTest.java
##########
@@ -79,6 +98,22 @@ private void setUpInsertValues(final InsertStatement insertStatement) {
                 new ParameterMarkerExpressionSegment(0, 0, 3), new ParameterMarkerExpressionSegment(0, 0, 4), new LiteralExpressionSegment(0, 0, "init"))));
     }
     
+    private void setUpOnDuplicateValues(final InsertStatement insertStatement) {
+        AssignmentSegment parameterMarkerExpressionAssignment = new AssignmentSegment(0, 0,
+                new ColumnSegment(0, 0, new IdentifierValue("on_duplicate_key_update_column_1")),
+                new ParameterMarkerExpressionSegment(0, 0, 4)
+        );
+        AssignmentSegment literalExpressionAssignment = new AssignmentSegment(0, 0,
+                new ColumnSegment(0, 0, new IdentifierValue("on_duplicate_key_update_column_2")),
+                new LiteralExpressionSegment(0, 0, 5)
+        );
+

Review comment:
       Please remove this redundant blank line.

##########
File path: shardingsphere-sql-parser/shardingsphere-sql-parser-binder/src/test/java/org/apache/shardingsphere/sql/parser/binder/segment/insert/values/OnDuplicateUpdateContextTest.java
##########
@@ -0,0 +1,147 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.shardingsphere.sql.parser.binder.segment.insert.values;
+
+import com.google.common.collect.Lists;
+import org.apache.shardingsphere.sql.parser.sql.segment.dml.assignment.AssignmentSegment;
+import org.apache.shardingsphere.sql.parser.sql.segment.dml.column.ColumnSegment;
+import org.apache.shardingsphere.sql.parser.sql.segment.dml.expr.ExpressionSegment;
+import org.apache.shardingsphere.sql.parser.sql.segment.dml.expr.simple.LiteralExpressionSegment;
+import org.apache.shardingsphere.sql.parser.sql.segment.dml.expr.simple.ParameterMarkerExpressionSegment;
+import org.apache.shardingsphere.sql.parser.sql.segment.dml.expr.simple.SimpleExpressionSegment;
+import org.apache.shardingsphere.sql.parser.sql.value.identifier.IdentifierValue;
+import org.junit.Assert;
+import org.junit.Test;
+
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.List;
+
+import static org.hamcrest.CoreMatchers.is;
+import static org.junit.Assert.assertThat;
+import static org.junit.Assert.assertTrue;
+
+public final class OnDuplicateUpdateContextTest {
+    
+    @SuppressWarnings("unchecked")
+    @Test
+    public void assertInstanceConstructedOk() throws NoSuchMethodException, InvocationTargetException, IllegalAccessException {
+        Collection<AssignmentSegment> assignments = Lists.newArrayList();
+        List<Object> parameters = Collections.emptyList();
+        int parametersOffset = 0;
+
+        OnDuplicateUpdateContext onDuplicateUpdateContext = new OnDuplicateUpdateContext(assignments, parameters, parametersOffset);
+
+        Method calculateParametersCountMethod = OnDuplicateUpdateContext.class.getDeclaredMethod("calculateParametersCount", Collection.class);
+        calculateParametersCountMethod.setAccessible(true);
+        int calculateParametersCountResult = (int) calculateParametersCountMethod.invoke(onDuplicateUpdateContext, new Object[]{assignments});
+        assertThat(onDuplicateUpdateContext.getParametersCount(), is(calculateParametersCountResult));
+
+        Method getValueExpressionsMethod = OnDuplicateUpdateContext.class.getDeclaredMethod("getValueExpressions", Collection.class);
+        getValueExpressionsMethod.setAccessible(true);
+        List<ExpressionSegment> getValueExpressionsResult = (List<ExpressionSegment>) getValueExpressionsMethod.invoke(onDuplicateUpdateContext, new Object[]{assignments});
+        assertThat(onDuplicateUpdateContext.getValueExpressions(), is(getValueExpressionsResult));
+
+        Method getParametersMethod = OnDuplicateUpdateContext.class.getDeclaredMethod("getParameters", List.class, int.class);
+        getParametersMethod.setAccessible(true);
+        List<Object> getParametersResult = (List<Object>) getParametersMethod.invoke(onDuplicateUpdateContext, new Object[]{parameters, parametersOffset});
+        assertThat(onDuplicateUpdateContext.getParameters(), is(getParametersResult));
+    }
+    
+    @Test
+    public void assertGetValueWhenParameterMarker() {
+        Collection<AssignmentSegment> assignments = makeParameterMarkerExpressionAssignmentSegment();
+        String parameterValue1 = "test1";
+        String parameterValue2 = "test2";
+        List<Object> parameters = Lists.newArrayList(parameterValue1, parameterValue2);
+        int parametersOffset = 0;
+        OnDuplicateUpdateContext onDuplicateUpdateContext = new OnDuplicateUpdateContext(assignments, parameters, parametersOffset);
+        Object valueFromInsertValueContext1 = onDuplicateUpdateContext.getValue(0);
+        assertThat(valueFromInsertValueContext1, is(parameterValue1));
+
+        Object valueFromInsertValueContext2 = onDuplicateUpdateContext.getValue(1);
+        assertThat(valueFromInsertValueContext2, is(parameterValue2));
+    }
+    
+    private Collection<AssignmentSegment> makeParameterMarkerExpressionAssignmentSegment() {
+        ParameterMarkerExpressionSegment parameterMarkerExpressionSegment = new ParameterMarkerExpressionSegment(0, 10, 5);
+        AssignmentSegment assignmentSegment1 = makeAssignmentSegment(parameterMarkerExpressionSegment);
+
+        ParameterMarkerExpressionSegment parameterMarkerExpressionSegment2 = new ParameterMarkerExpressionSegment(0, 10, 6);
+        AssignmentSegment assignmentSegment2 = makeAssignmentSegment(parameterMarkerExpressionSegment2);
+        return Lists.newArrayList(assignmentSegment1, assignmentSegment2);
+    }
+    
+    @Test
+    public void assertGetValueWhenLiteralExpressionSegment() {
+        Object literalObject = new Object();
+        Collection<AssignmentSegment> assignments = makeLiteralExpressionSegment(literalObject);
+        List<Object> parameters = Collections.emptyList();
+        OnDuplicateUpdateContext onDuplicateUpdateContext = new OnDuplicateUpdateContext(assignments, parameters, 0);
+        Object valueFromInsertValueContext = onDuplicateUpdateContext.getValue(0);
+        assertThat(valueFromInsertValueContext, is(literalObject));
+    }
+    
+    private Collection<AssignmentSegment> makeLiteralExpressionSegment(final Object literalObject) {
+        LiteralExpressionSegment parameterLiteralExpression = new LiteralExpressionSegment(0, 10, literalObject);
+        AssignmentSegment assignmentSegment = makeAssignmentSegment(parameterLiteralExpression);
+        return Collections.singleton(assignmentSegment);
+    }
+    
+    private AssignmentSegment makeAssignmentSegment(final SimpleExpressionSegment expressionSegment) {
+        int doesNotMatterLexicalIndex = 0;
+        String doesNotMatterColumnName = "columnNameStr";
+
+        ColumnSegment column = new ColumnSegment(doesNotMatterLexicalIndex, doesNotMatterLexicalIndex, new IdentifierValue(doesNotMatterColumnName));
+        return new AssignmentSegment(doesNotMatterLexicalIndex, doesNotMatterLexicalIndex, column, expressionSegment);
+    }
+    
+    @Test
+    public void assertGetParameterIndex() throws NoSuchMethodException, IllegalAccessException {
+        Collection<AssignmentSegment> assignments = Lists.newArrayList();
+        List<Object> parameters = Collections.emptyList();
+        int parametersOffset = 0;
+
+        OnDuplicateUpdateContext onDuplicateUpdateContext = new OnDuplicateUpdateContext(assignments, parameters, parametersOffset);
+

Review comment:
       Please remove this redundant blank line.

##########
File path: shardingsphere-sql-parser/shardingsphere-sql-parser-binder/src/test/java/org/apache/shardingsphere/sql/parser/binder/segment/insert/values/OnDuplicateUpdateContextTest.java
##########
@@ -0,0 +1,147 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.shardingsphere.sql.parser.binder.segment.insert.values;
+
+import com.google.common.collect.Lists;
+import org.apache.shardingsphere.sql.parser.sql.segment.dml.assignment.AssignmentSegment;
+import org.apache.shardingsphere.sql.parser.sql.segment.dml.column.ColumnSegment;
+import org.apache.shardingsphere.sql.parser.sql.segment.dml.expr.ExpressionSegment;
+import org.apache.shardingsphere.sql.parser.sql.segment.dml.expr.simple.LiteralExpressionSegment;
+import org.apache.shardingsphere.sql.parser.sql.segment.dml.expr.simple.ParameterMarkerExpressionSegment;
+import org.apache.shardingsphere.sql.parser.sql.segment.dml.expr.simple.SimpleExpressionSegment;
+import org.apache.shardingsphere.sql.parser.sql.value.identifier.IdentifierValue;
+import org.junit.Assert;
+import org.junit.Test;
+
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.List;
+
+import static org.hamcrest.CoreMatchers.is;
+import static org.junit.Assert.assertThat;
+import static org.junit.Assert.assertTrue;
+
+public final class OnDuplicateUpdateContextTest {
+    
+    @SuppressWarnings("unchecked")
+    @Test
+    public void assertInstanceConstructedOk() throws NoSuchMethodException, InvocationTargetException, IllegalAccessException {
+        Collection<AssignmentSegment> assignments = Lists.newArrayList();
+        List<Object> parameters = Collections.emptyList();
+        int parametersOffset = 0;
+
+        OnDuplicateUpdateContext onDuplicateUpdateContext = new OnDuplicateUpdateContext(assignments, parameters, parametersOffset);
+
+        Method calculateParametersCountMethod = OnDuplicateUpdateContext.class.getDeclaredMethod("calculateParametersCount", Collection.class);
+        calculateParametersCountMethod.setAccessible(true);
+        int calculateParametersCountResult = (int) calculateParametersCountMethod.invoke(onDuplicateUpdateContext, new Object[]{assignments});
+        assertThat(onDuplicateUpdateContext.getParametersCount(), is(calculateParametersCountResult));
+
+        Method getValueExpressionsMethod = OnDuplicateUpdateContext.class.getDeclaredMethod("getValueExpressions", Collection.class);
+        getValueExpressionsMethod.setAccessible(true);
+        List<ExpressionSegment> getValueExpressionsResult = (List<ExpressionSegment>) getValueExpressionsMethod.invoke(onDuplicateUpdateContext, new Object[]{assignments});
+        assertThat(onDuplicateUpdateContext.getValueExpressions(), is(getValueExpressionsResult));
+
+        Method getParametersMethod = OnDuplicateUpdateContext.class.getDeclaredMethod("getParameters", List.class, int.class);
+        getParametersMethod.setAccessible(true);
+        List<Object> getParametersResult = (List<Object>) getParametersMethod.invoke(onDuplicateUpdateContext, new Object[]{parameters, parametersOffset});
+        assertThat(onDuplicateUpdateContext.getParameters(), is(getParametersResult));
+    }
+    
+    @Test
+    public void assertGetValueWhenParameterMarker() {
+        Collection<AssignmentSegment> assignments = makeParameterMarkerExpressionAssignmentSegment();
+        String parameterValue1 = "test1";
+        String parameterValue2 = "test2";
+        List<Object> parameters = Lists.newArrayList(parameterValue1, parameterValue2);
+        int parametersOffset = 0;
+        OnDuplicateUpdateContext onDuplicateUpdateContext = new OnDuplicateUpdateContext(assignments, parameters, parametersOffset);
+        Object valueFromInsertValueContext1 = onDuplicateUpdateContext.getValue(0);
+        assertThat(valueFromInsertValueContext1, is(parameterValue1));
+
+        Object valueFromInsertValueContext2 = onDuplicateUpdateContext.getValue(1);
+        assertThat(valueFromInsertValueContext2, is(parameterValue2));
+    }
+    
+    private Collection<AssignmentSegment> makeParameterMarkerExpressionAssignmentSegment() {
+        ParameterMarkerExpressionSegment parameterMarkerExpressionSegment = new ParameterMarkerExpressionSegment(0, 10, 5);
+        AssignmentSegment assignmentSegment1 = makeAssignmentSegment(parameterMarkerExpressionSegment);
+
+        ParameterMarkerExpressionSegment parameterMarkerExpressionSegment2 = new ParameterMarkerExpressionSegment(0, 10, 6);
+        AssignmentSegment assignmentSegment2 = makeAssignmentSegment(parameterMarkerExpressionSegment2);
+        return Lists.newArrayList(assignmentSegment1, assignmentSegment2);
+    }
+    
+    @Test
+    public void assertGetValueWhenLiteralExpressionSegment() {
+        Object literalObject = new Object();
+        Collection<AssignmentSegment> assignments = makeLiteralExpressionSegment(literalObject);
+        List<Object> parameters = Collections.emptyList();
+        OnDuplicateUpdateContext onDuplicateUpdateContext = new OnDuplicateUpdateContext(assignments, parameters, 0);
+        Object valueFromInsertValueContext = onDuplicateUpdateContext.getValue(0);
+        assertThat(valueFromInsertValueContext, is(literalObject));
+    }
+    
+    private Collection<AssignmentSegment> makeLiteralExpressionSegment(final Object literalObject) {
+        LiteralExpressionSegment parameterLiteralExpression = new LiteralExpressionSegment(0, 10, literalObject);
+        AssignmentSegment assignmentSegment = makeAssignmentSegment(parameterLiteralExpression);
+        return Collections.singleton(assignmentSegment);
+    }
+    
+    private AssignmentSegment makeAssignmentSegment(final SimpleExpressionSegment expressionSegment) {
+        int doesNotMatterLexicalIndex = 0;
+        String doesNotMatterColumnName = "columnNameStr";
+
+        ColumnSegment column = new ColumnSegment(doesNotMatterLexicalIndex, doesNotMatterLexicalIndex, new IdentifierValue(doesNotMatterColumnName));
+        return new AssignmentSegment(doesNotMatterLexicalIndex, doesNotMatterLexicalIndex, column, expressionSegment);
+    }
+    
+    @Test
+    public void assertGetParameterIndex() throws NoSuchMethodException, IllegalAccessException {
+        Collection<AssignmentSegment> assignments = Lists.newArrayList();
+        List<Object> parameters = Collections.emptyList();
+        int parametersOffset = 0;
+
+        OnDuplicateUpdateContext onDuplicateUpdateContext = new OnDuplicateUpdateContext(assignments, parameters, parametersOffset);
+
+        Method getParameterIndexMethod = OnDuplicateUpdateContext.class.getDeclaredMethod("getParameterIndex", ExpressionSegment.class);
+        getParameterIndexMethod.setAccessible(true);
+        ParameterMarkerExpressionSegment notExistsExpressionSegment = new ParameterMarkerExpressionSegment(0, 0, 0);
+

Review comment:
       Please remove this redundant blank line.

##########
File path: shardingsphere-sql-parser/shardingsphere-sql-parser-binder/src/test/java/org/apache/shardingsphere/sql/parser/binder/segment/insert/values/OnDuplicateUpdateContextTest.java
##########
@@ -0,0 +1,147 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.shardingsphere.sql.parser.binder.segment.insert.values;
+
+import com.google.common.collect.Lists;
+import org.apache.shardingsphere.sql.parser.sql.segment.dml.assignment.AssignmentSegment;
+import org.apache.shardingsphere.sql.parser.sql.segment.dml.column.ColumnSegment;
+import org.apache.shardingsphere.sql.parser.sql.segment.dml.expr.ExpressionSegment;
+import org.apache.shardingsphere.sql.parser.sql.segment.dml.expr.simple.LiteralExpressionSegment;
+import org.apache.shardingsphere.sql.parser.sql.segment.dml.expr.simple.ParameterMarkerExpressionSegment;
+import org.apache.shardingsphere.sql.parser.sql.segment.dml.expr.simple.SimpleExpressionSegment;
+import org.apache.shardingsphere.sql.parser.sql.value.identifier.IdentifierValue;
+import org.junit.Assert;
+import org.junit.Test;
+
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.List;
+
+import static org.hamcrest.CoreMatchers.is;
+import static org.junit.Assert.assertThat;
+import static org.junit.Assert.assertTrue;
+
+public final class OnDuplicateUpdateContextTest {
+    
+    @SuppressWarnings("unchecked")
+    @Test
+    public void assertInstanceConstructedOk() throws NoSuchMethodException, InvocationTargetException, IllegalAccessException {
+        Collection<AssignmentSegment> assignments = Lists.newArrayList();
+        List<Object> parameters = Collections.emptyList();
+        int parametersOffset = 0;
+
+        OnDuplicateUpdateContext onDuplicateUpdateContext = new OnDuplicateUpdateContext(assignments, parameters, parametersOffset);
+
+        Method calculateParametersCountMethod = OnDuplicateUpdateContext.class.getDeclaredMethod("calculateParametersCount", Collection.class);
+        calculateParametersCountMethod.setAccessible(true);
+        int calculateParametersCountResult = (int) calculateParametersCountMethod.invoke(onDuplicateUpdateContext, new Object[]{assignments});
+        assertThat(onDuplicateUpdateContext.getParametersCount(), is(calculateParametersCountResult));
+
+        Method getValueExpressionsMethod = OnDuplicateUpdateContext.class.getDeclaredMethod("getValueExpressions", Collection.class);
+        getValueExpressionsMethod.setAccessible(true);
+        List<ExpressionSegment> getValueExpressionsResult = (List<ExpressionSegment>) getValueExpressionsMethod.invoke(onDuplicateUpdateContext, new Object[]{assignments});
+        assertThat(onDuplicateUpdateContext.getValueExpressions(), is(getValueExpressionsResult));
+
+        Method getParametersMethod = OnDuplicateUpdateContext.class.getDeclaredMethod("getParameters", List.class, int.class);
+        getParametersMethod.setAccessible(true);
+        List<Object> getParametersResult = (List<Object>) getParametersMethod.invoke(onDuplicateUpdateContext, new Object[]{parameters, parametersOffset});
+        assertThat(onDuplicateUpdateContext.getParameters(), is(getParametersResult));
+    }
+    
+    @Test
+    public void assertGetValueWhenParameterMarker() {
+        Collection<AssignmentSegment> assignments = makeParameterMarkerExpressionAssignmentSegment();
+        String parameterValue1 = "test1";
+        String parameterValue2 = "test2";
+        List<Object> parameters = Lists.newArrayList(parameterValue1, parameterValue2);
+        int parametersOffset = 0;
+        OnDuplicateUpdateContext onDuplicateUpdateContext = new OnDuplicateUpdateContext(assignments, parameters, parametersOffset);
+        Object valueFromInsertValueContext1 = onDuplicateUpdateContext.getValue(0);
+        assertThat(valueFromInsertValueContext1, is(parameterValue1));
+
+        Object valueFromInsertValueContext2 = onDuplicateUpdateContext.getValue(1);
+        assertThat(valueFromInsertValueContext2, is(parameterValue2));
+    }
+    
+    private Collection<AssignmentSegment> makeParameterMarkerExpressionAssignmentSegment() {
+        ParameterMarkerExpressionSegment parameterMarkerExpressionSegment = new ParameterMarkerExpressionSegment(0, 10, 5);
+        AssignmentSegment assignmentSegment1 = makeAssignmentSegment(parameterMarkerExpressionSegment);
+
+        ParameterMarkerExpressionSegment parameterMarkerExpressionSegment2 = new ParameterMarkerExpressionSegment(0, 10, 6);
+        AssignmentSegment assignmentSegment2 = makeAssignmentSegment(parameterMarkerExpressionSegment2);
+        return Lists.newArrayList(assignmentSegment1, assignmentSegment2);
+    }
+    
+    @Test
+    public void assertGetValueWhenLiteralExpressionSegment() {
+        Object literalObject = new Object();
+        Collection<AssignmentSegment> assignments = makeLiteralExpressionSegment(literalObject);
+        List<Object> parameters = Collections.emptyList();
+        OnDuplicateUpdateContext onDuplicateUpdateContext = new OnDuplicateUpdateContext(assignments, parameters, 0);
+        Object valueFromInsertValueContext = onDuplicateUpdateContext.getValue(0);
+        assertThat(valueFromInsertValueContext, is(literalObject));
+    }
+    
+    private Collection<AssignmentSegment> makeLiteralExpressionSegment(final Object literalObject) {
+        LiteralExpressionSegment parameterLiteralExpression = new LiteralExpressionSegment(0, 10, literalObject);
+        AssignmentSegment assignmentSegment = makeAssignmentSegment(parameterLiteralExpression);
+        return Collections.singleton(assignmentSegment);
+    }
+    
+    private AssignmentSegment makeAssignmentSegment(final SimpleExpressionSegment expressionSegment) {
+        int doesNotMatterLexicalIndex = 0;
+        String doesNotMatterColumnName = "columnNameStr";
+

Review comment:
       Please remove this redundant blank line.

##########
File path: shardingsphere-sql-parser/shardingsphere-sql-parser-binder/src/main/java/org/apache/shardingsphere/sql/parser/binder/statement/dml/InsertStatementContext.java
##########
@@ -50,30 +54,47 @@
     
     private final List<InsertValueContext> insertValueContexts;
     
+    private final OnDuplicateUpdateContext onDuplicateKeyUpdateValueContext;
+    
     private final GeneratedKeyContext generatedKeyContext;
     
     public InsertStatementContext(final SchemaMetaData schemaMetaData, final List<Object> parameters, final InsertStatement sqlStatement) {
         super(sqlStatement);
         tablesContext = new TablesContext(sqlStatement.getTable());
         columnNames = sqlStatement.useDefaultColumns() ? schemaMetaData.getAllColumnNames(sqlStatement.getTable().getTableName().getIdentifier().getValue()) : sqlStatement.getColumnNames();
-        insertValueContexts = getInsertValueContexts(parameters);
+
+        AtomicInteger parametersOffset = new AtomicInteger(0);
+        insertValueContexts = getInsertValueContexts(parameters, parametersOffset);
+        onDuplicateKeyUpdateValueContext = getOnDuplicateKeyUpdateValueContext(parameters, parametersOffset).orElse(null);
+
         generatedKeyContext = new GeneratedKeyContextEngine(schemaMetaData).createGenerateKeyContext(parameters, sqlStatement).orElse(null);
     }
     
-    private List<InsertValueContext> getInsertValueContexts(final List<Object> parameters) {
+    private List<InsertValueContext> getInsertValueContexts(final List<Object> parameters, final AtomicInteger parametersOffset) {
         List<InsertValueContext> result = new LinkedList<>();
-        int parametersOffset = 0;
         for (Collection<ExpressionSegment> each : getSqlStatement().getAllValueExpressions()) {
-            InsertValueContext insertValueContext = new InsertValueContext(each, parameters, parametersOffset);
+            InsertValueContext insertValueContext = new InsertValueContext(each, parameters, parametersOffset.get());
             result.add(insertValueContext);
-            parametersOffset += insertValueContext.getParametersCount();
+            parametersOffset.addAndGet(insertValueContext.getParametersCount());
         }
         return result;
     }
     
+    private Optional<OnDuplicateUpdateContext> getOnDuplicateKeyUpdateValueContext(final List<Object> parameters, final AtomicInteger parametersOffset) {
+
+        if (!getSqlStatement().getOnDuplicateKeyColumns().isPresent()) {
+            return Optional.empty();
+        }
+        Collection<AssignmentSegment> onDuplicateKeyColumns = getSqlStatement().getOnDuplicateKeyColumns().get().getColumns();
+        OnDuplicateUpdateContext onDuplicateUpdateContext = new OnDuplicateUpdateContext(onDuplicateKeyColumns, parameters, parametersOffset.get());
+        parametersOffset.addAndGet(onDuplicateUpdateContext.getParametersCount());
+        return Optional.of(onDuplicateUpdateContext);
+

Review comment:
       Please remove this redundant blank line.

##########
File path: shardingsphere-sql-parser/shardingsphere-sql-parser-binder/src/main/java/org/apache/shardingsphere/sql/parser/binder/statement/dml/InsertStatementContext.java
##########
@@ -50,30 +54,47 @@
     
     private final List<InsertValueContext> insertValueContexts;
     
+    private final OnDuplicateUpdateContext onDuplicateKeyUpdateValueContext;
+    
     private final GeneratedKeyContext generatedKeyContext;
     
     public InsertStatementContext(final SchemaMetaData schemaMetaData, final List<Object> parameters, final InsertStatement sqlStatement) {
         super(sqlStatement);
         tablesContext = new TablesContext(sqlStatement.getTable());
         columnNames = sqlStatement.useDefaultColumns() ? schemaMetaData.getAllColumnNames(sqlStatement.getTable().getTableName().getIdentifier().getValue()) : sqlStatement.getColumnNames();
-        insertValueContexts = getInsertValueContexts(parameters);
+
+        AtomicInteger parametersOffset = new AtomicInteger(0);
+        insertValueContexts = getInsertValueContexts(parameters, parametersOffset);
+        onDuplicateKeyUpdateValueContext = getOnDuplicateKeyUpdateValueContext(parameters, parametersOffset).orElse(null);
+
         generatedKeyContext = new GeneratedKeyContextEngine(schemaMetaData).createGenerateKeyContext(parameters, sqlStatement).orElse(null);

Review comment:
       Please remove this redundant blank line.

##########
File path: shardingsphere-sql-parser/shardingsphere-sql-parser-binder/src/test/java/org/apache/shardingsphere/sql/parser/binder/segment/insert/values/OnDuplicateUpdateContextTest.java
##########
@@ -0,0 +1,147 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.shardingsphere.sql.parser.binder.segment.insert.values;
+
+import com.google.common.collect.Lists;
+import org.apache.shardingsphere.sql.parser.sql.segment.dml.assignment.AssignmentSegment;
+import org.apache.shardingsphere.sql.parser.sql.segment.dml.column.ColumnSegment;
+import org.apache.shardingsphere.sql.parser.sql.segment.dml.expr.ExpressionSegment;
+import org.apache.shardingsphere.sql.parser.sql.segment.dml.expr.simple.LiteralExpressionSegment;
+import org.apache.shardingsphere.sql.parser.sql.segment.dml.expr.simple.ParameterMarkerExpressionSegment;
+import org.apache.shardingsphere.sql.parser.sql.segment.dml.expr.simple.SimpleExpressionSegment;
+import org.apache.shardingsphere.sql.parser.sql.value.identifier.IdentifierValue;
+import org.junit.Assert;
+import org.junit.Test;
+
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.List;
+
+import static org.hamcrest.CoreMatchers.is;
+import static org.junit.Assert.assertThat;
+import static org.junit.Assert.assertTrue;
+
+public final class OnDuplicateUpdateContextTest {
+    
+    @SuppressWarnings("unchecked")
+    @Test
+    public void assertInstanceConstructedOk() throws NoSuchMethodException, InvocationTargetException, IllegalAccessException {
+        Collection<AssignmentSegment> assignments = Lists.newArrayList();
+        List<Object> parameters = Collections.emptyList();
+        int parametersOffset = 0;
+
+        OnDuplicateUpdateContext onDuplicateUpdateContext = new OnDuplicateUpdateContext(assignments, parameters, parametersOffset);
+
+        Method calculateParametersCountMethod = OnDuplicateUpdateContext.class.getDeclaredMethod("calculateParametersCount", Collection.class);
+        calculateParametersCountMethod.setAccessible(true);
+        int calculateParametersCountResult = (int) calculateParametersCountMethod.invoke(onDuplicateUpdateContext, new Object[]{assignments});
+        assertThat(onDuplicateUpdateContext.getParametersCount(), is(calculateParametersCountResult));
+

Review comment:
       Please remove this redundant blank line.

##########
File path: shardingsphere-sql-parser/shardingsphere-sql-parser-binder/src/test/java/org/apache/shardingsphere/sql/parser/binder/segment/insert/values/OnDuplicateUpdateContextTest.java
##########
@@ -0,0 +1,147 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements.  See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.shardingsphere.sql.parser.binder.segment.insert.values;
+
+import com.google.common.collect.Lists;
+import org.apache.shardingsphere.sql.parser.sql.segment.dml.assignment.AssignmentSegment;
+import org.apache.shardingsphere.sql.parser.sql.segment.dml.column.ColumnSegment;
+import org.apache.shardingsphere.sql.parser.sql.segment.dml.expr.ExpressionSegment;
+import org.apache.shardingsphere.sql.parser.sql.segment.dml.expr.simple.LiteralExpressionSegment;
+import org.apache.shardingsphere.sql.parser.sql.segment.dml.expr.simple.ParameterMarkerExpressionSegment;
+import org.apache.shardingsphere.sql.parser.sql.segment.dml.expr.simple.SimpleExpressionSegment;
+import org.apache.shardingsphere.sql.parser.sql.value.identifier.IdentifierValue;
+import org.junit.Assert;
+import org.junit.Test;
+
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.List;
+
+import static org.hamcrest.CoreMatchers.is;
+import static org.junit.Assert.assertThat;
+import static org.junit.Assert.assertTrue;
+
+public final class OnDuplicateUpdateContextTest {
+    
+    @SuppressWarnings("unchecked")
+    @Test
+    public void assertInstanceConstructedOk() throws NoSuchMethodException, InvocationTargetException, IllegalAccessException {
+        Collection<AssignmentSegment> assignments = Lists.newArrayList();
+        List<Object> parameters = Collections.emptyList();
+        int parametersOffset = 0;
+
+        OnDuplicateUpdateContext onDuplicateUpdateContext = new OnDuplicateUpdateContext(assignments, parameters, parametersOffset);
+
+        Method calculateParametersCountMethod = OnDuplicateUpdateContext.class.getDeclaredMethod("calculateParametersCount", Collection.class);
+        calculateParametersCountMethod.setAccessible(true);
+        int calculateParametersCountResult = (int) calculateParametersCountMethod.invoke(onDuplicateUpdateContext, new Object[]{assignments});
+        assertThat(onDuplicateUpdateContext.getParametersCount(), is(calculateParametersCountResult));
+
+        Method getValueExpressionsMethod = OnDuplicateUpdateContext.class.getDeclaredMethod("getValueExpressions", Collection.class);
+        getValueExpressionsMethod.setAccessible(true);
+        List<ExpressionSegment> getValueExpressionsResult = (List<ExpressionSegment>) getValueExpressionsMethod.invoke(onDuplicateUpdateContext, new Object[]{assignments});
+        assertThat(onDuplicateUpdateContext.getValueExpressions(), is(getValueExpressionsResult));
+

Review comment:
       Please remove this redundant blank line.

##########
File path: shardingsphere-sql-parser/shardingsphere-sql-parser-binder/src/main/java/org/apache/shardingsphere/sql/parser/binder/statement/dml/InsertStatementContext.java
##########
@@ -93,9 +114,21 @@ public InsertStatementContext(final SchemaMetaData schemaMetaData, final List<Ob
         return result;
     }
     
+    /**
+     * Get OnDuplicateKeyUpdateParameters.
+     * @return OnDuplicateKeyUpdateParameters
+     */
+    public List<Object> getOnDuplicateKeyUpdateParameters() {
+        if (null == onDuplicateKeyUpdateValueContext) {
+            return new ArrayList<>(0);
+        }
+

Review comment:
       Please remove this redundant blank line.

##########
File path: sharding-jdbc/sharding-jdbc-core/src/test/java/org/apache/shardingsphere/shardingjdbc/jdbc/core/statement/ShardingSpherePreparedStatementTest.java
##########
@@ -316,6 +320,79 @@ public void assertAddBatchWithGenerateKeyColumn() throws SQLException {
         }
     }
     
+    @Test
+    public void assertAddOnDuplicateKey() throws SQLException {
+        int itemId = 1;
+        int userId1 = 101;
+        int userId2 = 102;
+        int orderId = 200;
+        String status = "init";
+        
+        String updatedStatus = "updated on duplicate key";
+        

Review comment:
       Please remove this redundant blank line.

##########
File path: encrypt-core/encrypt-core-rewrite/src/main/java/org/apache/shardingsphere/encrypt/rewrite/parameter/impl/EncryptInsertOnDuplicateKeyUpdateValueParameterRewriter.java
##########
@@ -51,30 +47,36 @@ protected boolean isNeedRewriteForEncrypt(final SQLStatementContext sqlStatement
     @Override
     public void rewrite(final ParameterBuilder parameterBuilder, final InsertStatementContext insertStatementContext, final List<Object> parameters) {
         String tableName = insertStatementContext.getSqlStatement().getTable().getTableName().getIdentifier().getValue();
-        Preconditions.checkState(insertStatementContext.getSqlStatement().getOnDuplicateKeyColumns().isPresent());
-        OnDuplicateKeyColumnsSegment onDuplicateKeyColumnsSegment = insertStatementContext.getSqlStatement().getOnDuplicateKeyColumns().get();
-        Collection<AssignmentSegment> onDuplicateKeyColumnsSegments = onDuplicateKeyColumnsSegment.getColumns();
-        if (onDuplicateKeyColumnsSegments.isEmpty()) {
-            return;
-        }
+
         GroupedParameterBuilder groupedParameterBuilder = (GroupedParameterBuilder) parameterBuilder;
-        for (AssignmentSegment each : onDuplicateKeyColumnsSegments) {
-            ExpressionSegment expressionSegment = each.getValue();
-            Object cipherColumnValue;
-            Object plainColumnValue = null;
-            if (expressionSegment instanceof ParameterMarkerExpressionSegment) {
-                plainColumnValue = parameters.get(((ParameterMarkerExpressionSegment) expressionSegment).getParameterMarkerIndex());
-            }
-            if (queryWithCipherColumn) {
-                Optional<Encryptor> encryptor = getEncryptRule().findEncryptor(tableName, each.getColumn().getIdentifier().getValue());
-                if (encryptor.isPresent()) {
-                    cipherColumnValue = encryptor.get().encrypt(plainColumnValue);
-                    groupedParameterBuilder.getOnDuplicateKeyUpdateAddedParameters().add(cipherColumnValue);
+        OnDuplicateUpdateContext onDuplicateKeyUpdateValueContext = insertStatementContext.getOnDuplicateKeyUpdateValueContext();
+        for (int index = 0; index < onDuplicateKeyUpdateValueContext.getValueExpressions().size(); index++) {
+            final int columnIndex = index;
+            String encryptLogicColumnName = onDuplicateKeyUpdateValueContext.getColumn(columnIndex).getIdentifier().getValue();
+            Optional<Encryptor> encryptorOptional = getEncryptRule().findEncryptor(tableName, encryptLogicColumnName);
+            encryptorOptional.ifPresent(encryptor -> {
+                Object plainColumnValue = onDuplicateKeyUpdateValueContext.getValue(columnIndex);
+                Object cipherColumnValue = encryptorOptional.get().encrypt(plainColumnValue);
+                groupedParameterBuilder.getOnDuplicateKeyUpdateParametersBuilder().addReplacedParameters(columnIndex, cipherColumnValue);
+                Collection<Object> addedParameters = new LinkedList<>();
+                if (encryptor instanceof QueryAssistedEncryptor) {
+                    Optional<String> assistedColumnName = getEncryptRule().findAssistedQueryColumn(tableName, encryptLogicColumnName);
+                    Preconditions.checkArgument(assistedColumnName.isPresent(), "Can not find assisted query Column Name");
+                    addedParameters.add(((QueryAssistedEncryptor) encryptor).queryAssistedEncrypt(plainColumnValue.toString()));
+                }
+
+                if (getEncryptRule().findPlainColumn(tableName, encryptLogicColumnName).isPresent()) {
+                    addedParameters.add(plainColumnValue);
+                }
+
+                if (!addedParameters.isEmpty()) {
+                    if (!groupedParameterBuilder.getOnDuplicateKeyUpdateParametersBuilder().getAddedIndexAndParameters().containsKey(columnIndex + 1)) {
+                        groupedParameterBuilder.getOnDuplicateKeyUpdateParametersBuilder().getAddedIndexAndParameters().put(columnIndex + 1, new LinkedList<>());
+                    }
+                    groupedParameterBuilder.getOnDuplicateKeyUpdateParametersBuilder().getAddedIndexAndParameters().get(columnIndex + 1).addAll(addedParameters);
                 }
-            }
-            if (null != plainColumnValue) {
-                groupedParameterBuilder.getOnDuplicateKeyUpdateAddedParameters().add(plainColumnValue);
-            }
+            });
+

Review comment:
       Please remove this redundant blank line.

##########
File path: encrypt-core/encrypt-core-rewrite/src/main/java/org/apache/shardingsphere/encrypt/rewrite/parameter/impl/EncryptInsertOnDuplicateKeyUpdateValueParameterRewriter.java
##########
@@ -51,30 +47,36 @@ protected boolean isNeedRewriteForEncrypt(final SQLStatementContext sqlStatement
     @Override
     public void rewrite(final ParameterBuilder parameterBuilder, final InsertStatementContext insertStatementContext, final List<Object> parameters) {
         String tableName = insertStatementContext.getSqlStatement().getTable().getTableName().getIdentifier().getValue();
-        Preconditions.checkState(insertStatementContext.getSqlStatement().getOnDuplicateKeyColumns().isPresent());
-        OnDuplicateKeyColumnsSegment onDuplicateKeyColumnsSegment = insertStatementContext.getSqlStatement().getOnDuplicateKeyColumns().get();
-        Collection<AssignmentSegment> onDuplicateKeyColumnsSegments = onDuplicateKeyColumnsSegment.getColumns();
-        if (onDuplicateKeyColumnsSegments.isEmpty()) {
-            return;
-        }
+

Review comment:
       Please remove this redundant blank line.




----------------------------------------------------------------
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

For queries about this service, please contact Infrastructure at:
users@infra.apache.org