Repository: apache/shardingsphere
Issue: Column types disordered when use prepared statement in Proxy

Please answer these questions before submitting your issue. Thanks!
开源不易，我们希望将精力放在完成新功能和解决有价值的问题上，为了让大家的配合更具有效率，请填写以下列出的全部问题

### Which version of Sharding-Sphere do you using?（您使用的Sharding-Sphere版本为？）
dev

### Expected behavior （您预期的结果是）
correct prepared statement result

### Actual behavior （实际运行的结果是）
a chance to triger wrong result

### Steps to reproduce the behavior （可重现问题的操作步骤）
use prepared statement in Proxy

### Please provide the reproduce example codes (such as github link)，otherwise we will label the issue as Invalid and close it.（为了节省复现问题的时间，请务必提供可重现的代码，否则我们会将issue直接标记为invalid并关闭）
example

Code should based on https://github.com/sharding-sphere/sharding-sphere-example
（代码请基于 https://github.com/sharding-sphere/sharding-sphere-example）


Changed files:
sharding-proxy/src/main/java/io/shardingsphere/proxy/backend/common/StatementExecuteWorker.java
sharding-proxy/src/main/java/io/shardingsphere/proxy/backend/common/StatementExecuteBackendHandler.java

diff --git a/sharding-proxy/src/main/java/io/shardingsphere/proxy/backend/common/StatementExecuteBackendHandler.java b/sharding-proxy/src/main/java/io/shardingsphere/proxy/backend/common/StatementExecuteBackendHandler.java
index e1468ce99a7..793a37e100a 100644
--- a/sharding-proxy/src/main/java/io/shardingsphere/proxy/backend/common/StatementExecuteBackendHandler.java
+++ b/sharding-proxy/src/main/java/io/shardingsphere/proxy/backend/common/StatementExecuteBackendHandler.java
@@ -84,7 +84,7 @@ public final class StatementExecuteBackendHandler implements BackendHandler {
     
     private int columnCount;
     
-    private final List<ColumnType> columnTypes;
+    private List<ColumnType> columnTypes;
     
     private boolean isMerged;
     
@@ -101,7 +101,6 @@ public final class StatementExecuteBackendHandler implements BackendHandler {
         connections = new CopyOnWriteArrayList<>();
         resultSets = new CopyOnWriteArrayList<>();
         resultLists = new CopyOnWriteArrayList<>();
-        columnTypes = new CopyOnWriteArrayList<>();
         isMerged = false;
         hasMoreResultValueFlag = true;
         this.databaseType = databaseType;
diff --git a/sharding-proxy/src/main/java/io/shardingsphere/proxy/backend/common/StatementExecuteWorker.java b/sharding-proxy/src/main/java/io/shardingsphere/proxy/backend/common/StatementExecuteWorker.java
index ad949d28e2e..c2f2dc1b53f 100644
--- a/sharding-proxy/src/main/java/io/shardingsphere/proxy/backend/common/StatementExecuteWorker.java
+++ b/sharding-proxy/src/main/java/io/shardingsphere/proxy/backend/common/StatementExecuteWorker.java
@@ -190,13 +190,15 @@ public final class StatementExecuteWorker implements Callable<CommandResponsePac
             return result;
         }
         result.addPacket(new FieldCountPacket(++currentSequenceId, columnCount));
+        List<ColumnType> columnTypes = new ArrayList<>(128);
         for (int i = 1; i <= columnCount; i++) {
             ColumnType columnType = ColumnType.valueOfJDBCType(resultSetMetaData.getColumnType(i));
             ColumnDefinition41Packet columnDefinition41Packet = new ColumnDefinition41Packet(++currentSequenceId, resultSetMetaData.getSchemaName(i), resultSetMetaData.getTableName(i),
                 resultSetMetaData.getTableName(i), resultSetMetaData.getColumnLabel(i), resultSetMetaData.getColumnName(i), resultSetMetaData.getColumnDisplaySize(i), columnType, 0);
             result.addPacket(columnDefinition41Packet);
-            statementExecuteBackendHandler.getColumnTypes().add(columnType);
+            columnTypes.add(columnType);
         }
+        statementExecuteBackendHandler.setColumnTypes(columnTypes);
         result.addPacket(new EofPacket(++currentSequenceId, 0, StatusFlag.SERVER_STATUS_AUTOCOMMIT.getValue()));
         return result;
     }
@@ -211,20 +213,22 @@ public final class StatementExecuteWorker implements Callable<CommandResponsePac
             return result;
         }
         result.addPacket(new FieldCountPacket(++currentSequenceId, columnCount));
+        List<ColumnType> columnTypes = new ArrayList<>(128);
         for (int i = 1; i <= columnCount; i++) {
             ColumnType columnType = ColumnType.valueOfJDBCType(resultSetMetaData.getColumnType(i));
             ColumnDefinition41Packet columnDefinition41Packet = new ColumnDefinition41Packet(++currentSequenceId, resultSetMetaData.getSchemaName(i), resultSetMetaData.getTableName(i),
                 resultSetMetaData.getTableName(i), resultSetMetaData.getColumnLabel(i), resultSetMetaData.getColumnName(i), resultSetMetaData.getColumnDisplaySize(i), columnType, 0);
             result.addPacket(columnDefinition41Packet);
-            statementExecuteBackendHandler.getColumnTypes().add(columnType);
+            columnTypes.add(columnType);
         }
+        statementExecuteBackendHandler.setColumnTypes(columnTypes);
         result.addPacket(new EofPacket(++currentSequenceId, 0, StatusFlag.SERVER_STATUS_AUTOCOMMIT.getValue()));
         while (resultSet.next()) {
             List<Object> data = new ArrayList<>(columnCount);
             for (int i = 1; i <= columnCount; i++) {
                 data.add(resultSet.getObject(i));
             }
-            result.addPacket(new BinaryResultSetRowPacket(++currentSequenceId, columnCount, data, statementExecuteBackendHandler.getColumnTypes()));
+            result.addPacket(new BinaryResultSetRowPacket(++currentSequenceId, columnCount, data, columnTypes));
         }
         result.addPacket(new EofPacket(++currentSequenceId, 0, StatusFlag.SERVER_STATUS_AUTOCOMMIT.getValue()));
         return result;