Repository: apache/shardingsphere
Issue: Get ShardingException when use `NSERT INTO t_plain_encrypt(col3, col4) VALUES (?, ?), (3, 4)`

## Bug Report

**For English only**, other languages will not accept.

Before report a bug, make sure you have:

- Searched open and closed [GitHub issues](https://github.com/apache/incubator-shardingsphere/issues).
- Read documentation: [ShardingSphere Doc](https://shardingsphere.apache.org/document/current/en/overview).

Please pay attention on issues you submitted, because we maybe need more details. 
If no response **more than 7 days** and we cannot reproduce it on current information, we will **close it**.

Please answer these questions before submitting your issue. Thanks!

### Which version of ShardingSphere did you use?
4.0.0.rc2
### Which project did you use? Sharding-JDBC or Sharding-Proxy?
Sharding-JDBC
### Expected behavior

### Actual behavior
throw new ShardingException("Index Out Of Bounds For InsertOptimizeResultUnit.")
### Reason analyze (If you can)

### Steps to reproduce the behavior, such as: SQL to execute, sharding rule configuration, when exception occur etc.

### Example codes for reproduce this issue (such as a github link).


Changed files:
sharding-core/sharding-core-optimize/src/main/java/org/apache/shardingsphere/core/optimize/encrypt/engine/dml/EncryptInsertOptimizeEngine.java
sharding-core/sharding-core-rewrite/src/test/java/org/apache/shardingsphere/core/rewrite/rewriter/EncryptSQLRewriteEngineTest.java
sharding-core/sharding-core-optimize/src/main/java/org/apache/shardingsphere/core/optimize/sharding/engnie/dml/ShardingInsertOptimizeEngine.java

diff --git a/sharding-core/sharding-core-optimize/src/main/java/org/apache/shardingsphere/core/optimize/encrypt/engine/dml/EncryptInsertOptimizeEngine.java b/sharding-core/sharding-core-optimize/src/main/java/org/apache/shardingsphere/core/optimize/encrypt/engine/dml/EncryptInsertOptimizeEngine.java
index 163e766057a..b53b37d6e09 100644
--- a/sharding-core/sharding-core-optimize/src/main/java/org/apache/shardingsphere/core/optimize/encrypt/engine/dml/EncryptInsertOptimizeEngine.java
+++ b/sharding-core/sharding-core-optimize/src/main/java/org/apache/shardingsphere/core/optimize/encrypt/engine/dml/EncryptInsertOptimizeEngine.java
@@ -27,6 +27,7 @@ import org.apache.shardingsphere.core.optimize.sharding.segment.insert.value.Ins
 import org.apache.shardingsphere.core.parse.sql.statement.dml.InsertStatement;
 import org.apache.shardingsphere.core.rule.EncryptRule;
 
+import java.util.Arrays;
 import java.util.Collection;
 import java.util.List;
 
@@ -46,12 +47,13 @@ public final class EncryptInsertOptimizeEngine implements EncryptOptimizeEngine<
         int derivedColumnsCount = encryptRule.getAssistedQueryAndPlainColumnCount(sqlStatement.getTable().getTableName());
         int parametersCount = 0;
         for (InsertValue each : result.getValues()) {
-            InsertOptimizeResultUnit unit = result.addUnit(each.getValues(derivedColumnsCount), each.getParameters(parameters, parametersCount, derivedColumnsCount), each.getParametersCount());
+            Object[] currentParameters = each.getParameters(parameters, parametersCount, derivedColumnsCount);
+            InsertOptimizeResultUnit unit = result.addUnit(each.getValues(derivedColumnsCount), currentParameters, each.getParametersCount());
             if (encryptRule.isHasQueryAssistedColumn(sqlStatement.getTable().getTableName())) {
-                fillAssistedQueryUnit(encryptRule, parameters, sqlStatement.getTable().getTableName(), result.getInsertColumns().getRegularColumnNames(), unit);
+                fillAssistedQueryUnit(encryptRule, Arrays.asList(currentParameters), sqlStatement.getTable().getTableName(), result.getInsertColumns().getRegularColumnNames(), unit);
             }
             if (encryptRule.isHasPlainColumn(sqlStatement.getTable().getTableName())) {
-                fillPlainUnit(encryptRule, parameters, sqlStatement.getTable().getTableName(), result.getInsertColumns().getRegularColumnNames(), unit);
+                fillPlainUnit(encryptRule, Arrays.asList(currentParameters), sqlStatement.getTable().getTableName(), result.getInsertColumns().getRegularColumnNames(), unit);
             }
             parametersCount += each.getParametersCount();
         }
diff --git a/sharding-core/sharding-core-optimize/src/main/java/org/apache/shardingsphere/core/optimize/sharding/engnie/dml/ShardingInsertOptimizeEngine.java b/sharding-core/sharding-core-optimize/src/main/java/org/apache/shardingsphere/core/optimize/sharding/engnie/dml/ShardingInsertOptimizeEngine.java
index 6f891b349f9..4b2fe326558 100644
--- a/sharding-core/sharding-core-optimize/src/main/java/org/apache/shardingsphere/core/optimize/sharding/engnie/dml/ShardingInsertOptimizeEngine.java
+++ b/sharding-core/sharding-core-optimize/src/main/java/org/apache/shardingsphere/core/optimize/sharding/engnie/dml/ShardingInsertOptimizeEngine.java
@@ -34,6 +34,7 @@ import org.apache.shardingsphere.core.parse.sql.segment.dml.column.OnDuplicateKe
 import org.apache.shardingsphere.core.parse.sql.statement.dml.InsertStatement;
 import org.apache.shardingsphere.core.rule.ShardingRule;
 
+import java.util.Arrays;
 import java.util.Collection;
 import java.util.Iterator;
 import java.util.List;
@@ -66,16 +67,17 @@ public final class ShardingInsertOptimizeEngine implements ShardingOptimizeEngin
         int derivedColumnsCount = getDerivedColumnsCount(shardingRule, tableName, isGeneratedValue);
         int parametersCount = 0;
         for (InsertValue each : result.getValues()) {
-            InsertOptimizeResultUnit unit = result.createUnit(each.getValues(derivedColumnsCount), each.getParameters(parameters, parametersCount, derivedColumnsCount), each.getParametersCount());
+            Object[] currentParameters = each.getParameters(parameters, parametersCount, derivedColumnsCount);
+            InsertOptimizeResultUnit unit = result.createUnit(each.getValues(derivedColumnsCount), currentParameters, each.getParametersCount());
             result.addUnit(unit);
             if (isGeneratedValue) {
-                unit.addInsertValue(generatedValues.next(), parameters);
+                unit.addInsertValue(generatedValues.next(), Arrays.asList(currentParameters));
             }
             if (shardingRule.getEncryptRule().isHasQueryAssistedColumn(tableName)) {
-                fillAssistedQueryUnit(shardingRule, tableName, insertColumns.getRegularColumnNames(), unit, parameters);
+                fillAssistedQueryUnit(shardingRule, tableName, insertColumns.getRegularColumnNames(), unit, Arrays.asList(currentParameters));
             }
             if (shardingRule.getEncryptRule().isHasPlainColumn(tableName)) {
-                fillPlainUnit(shardingRule, tableName, insertColumns.getRegularColumnNames(), unit, parameters);
+                fillPlainUnit(shardingRule, tableName, insertColumns.getRegularColumnNames(), unit, Arrays.asList(currentParameters));
             }
             parametersCount += each.getParametersCount();
         }
diff --git a/sharding-core/sharding-core-rewrite/src/test/java/org/apache/shardingsphere/core/rewrite/rewriter/EncryptSQLRewriteEngineTest.java b/sharding-core/sharding-core-rewrite/src/test/java/org/apache/shardingsphere/core/rewrite/rewriter/EncryptSQLRewriteEngineTest.java
index c6ae4d3b898..48f78c6c7a8 100644
--- a/sharding-core/sharding-core-rewrite/src/test/java/org/apache/shardingsphere/core/rewrite/rewriter/EncryptSQLRewriteEngineTest.java
+++ b/sharding-core/sharding-core-rewrite/src/test/java/org/apache/shardingsphere/core/rewrite/rewriter/EncryptSQLRewriteEngineTest.java
@@ -238,6 +238,18 @@ public final class EncryptSQLRewriteEngineTest {
         assertThat(actual.getParameters().get(1), is((Object) "encryptValue"));
     }
     
+    @Test
+    public void assertInsertWithValuesWithPlaceholderWithPlainEncrypt() {
+        String sql = "INSERT INTO t_plain_encrypt(col3, col4) VALUES (?, ?), (3, 4)";
+        SQLUnit actual = getSQLUnit(sql, parametersOfEqual, true);
+        assertThat(actual.getSql(), is("INSERT INTO t_plain_encrypt(col1, col2, plain1, plain2) VALUES (?, ?, ?, ?), ('encryptValue', 'encryptValue', 3, 4)"));
+        assertThat(actual.getParameters().size(), is(4));
+        assertThat(actual.getParameters().get(0), is((Object) "encryptValue"));
+        assertThat(actual.getParameters().get(1), is((Object) "encryptValue"));
+        assertThat(actual.getParameters().get(2), is((Object) 1));
+        assertThat(actual.getParameters().get(3), is((Object) 2));
+    }
+    
     @Test
     public void assertInsertWithValuesWithoutPlaceholderWithQueryEncrypt() {
         String sql = "INSERT INTO t_query_encrypt(col1, col2) VALUES (1, 2), (3, 4)";