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

zhangliang pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/shardingsphere.git


The following commit(s) were added to refs/heads/master by this push:
     new 0d54f1c8c56 Cache columnLabelAndIndexMap in 
ShardingSpherePreparedStatement (#20674)
0d54f1c8c56 is described below

commit 0d54f1c8c5633f09acb858e3b021b6590317fe7f
Author: 吴伟杰 <[email protected]>
AuthorDate: Wed Aug 31 15:34:54 2022 +0800

    Cache columnLabelAndIndexMap in ShardingSpherePreparedStatement (#20674)
    
    * Cache columnLabelAndIndexMap in ShardingSpherePreparedStatement
    
    * Add ShardingSphereResultSetUtilTest
    
    * Remove unreachable codes
---
 .../core/resultset/ShardingSphereResultSet.java    | 49 +++------------
 .../resultset/ShardingSphereResultSetUtil.java     | 71 ++++++++++++++++++++++
 .../statement/ShardingSpherePreparedStatement.java | 13 +++-
 .../resultset/ShardingSphereResultSetUtilTest.java | 65 ++++++++++++++++++++
 4 files changed, 154 insertions(+), 44 deletions(-)

diff --git 
a/shardingsphere-jdbc/shardingsphere-jdbc-core/src/main/java/org/apache/shardingsphere/driver/jdbc/core/resultset/ShardingSphereResultSet.java
 
b/shardingsphere-jdbc/shardingsphere-jdbc-core/src/main/java/org/apache/shardingsphere/driver/jdbc/core/resultset/ShardingSphereResultSet.java
index 2e8b62086ec..94d7315f8aa 100644
--- 
a/shardingsphere-jdbc/shardingsphere-jdbc-core/src/main/java/org/apache/shardingsphere/driver/jdbc/core/resultset/ShardingSphereResultSet.java
+++ 
b/shardingsphere-jdbc/shardingsphere-jdbc-core/src/main/java/org/apache/shardingsphere/driver/jdbc/core/resultset/ShardingSphereResultSet.java
@@ -17,15 +17,9 @@
 
 package org.apache.shardingsphere.driver.jdbc.core.resultset;
 
-import org.apache.commons.collections4.map.CaseInsensitiveMap;
 import org.apache.shardingsphere.driver.jdbc.adapter.AbstractResultSetAdapter;
-import org.apache.shardingsphere.driver.jdbc.exception.SQLExceptionErrorCode;
-import 
org.apache.shardingsphere.infra.executor.sql.execute.result.query.impl.driver.jdbc.type.util.ResultSetUtil;
-import 
org.apache.shardingsphere.infra.binder.segment.select.projection.DerivedColumn;
-import 
org.apache.shardingsphere.infra.binder.segment.select.projection.Projection;
-import org.apache.shardingsphere.infra.binder.statement.SQLStatementContext;
-import 
org.apache.shardingsphere.infra.binder.statement.dml.SelectStatementContext;
 import org.apache.shardingsphere.infra.executor.sql.context.ExecutionContext;
+import 
org.apache.shardingsphere.infra.executor.sql.execute.result.query.impl.driver.jdbc.type.util.ResultSetUtil;
 import org.apache.shardingsphere.infra.merge.result.MergedResult;
 
 import java.io.InputStream;
@@ -38,7 +32,6 @@ import java.sql.Blob;
 import java.sql.Clob;
 import java.sql.Date;
 import java.sql.ResultSet;
-import java.sql.ResultSetMetaData;
 import java.sql.SQLException;
 import java.sql.SQLFeatureNotSupportedException;
 import java.sql.SQLXML;
@@ -71,42 +64,14 @@ public final class ShardingSphereResultSet extends 
AbstractResultSetAdapter {
     public ShardingSphereResultSet(final List<ResultSet> resultSets, final 
MergedResult mergeResultSet, final Statement statement, final ExecutionContext 
executionContext) throws SQLException {
         super(resultSets, statement, executionContext);
         this.mergeResultSet = mergeResultSet;
-        columnLabelAndIndexMap = 
createColumnLabelAndIndexMap(resultSets.get(0).getMetaData());
-    }
-    
-    private Map<String, Integer> createColumnLabelAndIndexMap(final 
ResultSetMetaData resultSetMetaData) throws SQLException {
-        if (hasSelectExpandProjections()) {
-            return createColumnLabelAndIndexMapWithExpandProjections();
-        }
-        Map<String, Integer> result = new 
CaseInsensitiveMap<>(resultSetMetaData.getColumnCount(), 1);
-        for (int columnIndex = resultSetMetaData.getColumnCount(); columnIndex 
> 0; columnIndex--) {
-            result.put(resultSetMetaData.getColumnLabel(columnIndex), 
columnIndex);
-        }
-        return result;
-    }
-    
-    private Map<String, Integer> 
createColumnLabelAndIndexMapWithExpandProjections() throws SQLException {
-        SelectStatementContext statementContext = (SelectStatementContext) 
getExecutionContext().getSqlStatementContext();
-        Map<String, Integer> result = new 
CaseInsensitiveMap<>(statementContext.getProjectionsContext().getExpandProjections().size(),
 1);
-        for (int columnIndex = 
statementContext.getProjectionsContext().getExpandProjections().size(); 
columnIndex > 0; columnIndex--) {
-            checkColumnIndex(columnIndex);
-            Projection projection = 
statementContext.getProjectionsContext().getExpandProjections().get(columnIndex 
- 1);
-            
result.put(DerivedColumn.isDerivedColumnName(projection.getColumnLabel()) ? 
projection.getExpression() : projection.getColumnLabel(), columnIndex);
-        }
-        return result;
-    }
-    
-    private boolean hasSelectExpandProjections() {
-        SQLStatementContext<?> sqlStatementContext = 
getExecutionContext().getSqlStatementContext();
-        return sqlStatementContext instanceof SelectStatementContext && 
!((SelectStatementContext) 
sqlStatementContext).getProjectionsContext().getExpandProjections().isEmpty();
+        columnLabelAndIndexMap = 
ShardingSphereResultSetUtil.createColumnLabelAndIndexMap(executionContext.getSqlStatementContext(),
 resultSets.get(0).getMetaData());
     }
     
-    private void checkColumnIndex(final int column) throws SQLException {
-        List<Projection> actualProjections = ((SelectStatementContext) 
getExecutionContext().getSqlStatementContext()).getProjectionsContext().getExpandProjections();
-        if (column > actualProjections.size()) {
-            SQLExceptionErrorCode errorCode = 
SQLExceptionErrorCode.COLUMN_INDEX_OUT_OF_RANGE;
-            throw new SQLException(errorCode.getErrorMessage(), 
errorCode.getSqlState(), errorCode.getErrorCode());
-        }
+    public ShardingSphereResultSet(final List<ResultSet> resultSets, final 
MergedResult mergeResultSet, final Statement statement, final ExecutionContext 
executionContext,
+                                   final Map<String, Integer> 
columnLabelAndIndexMap) {
+        super(resultSets, statement, executionContext);
+        this.mergeResultSet = mergeResultSet;
+        this.columnLabelAndIndexMap = columnLabelAndIndexMap;
     }
     
     @Override
diff --git 
a/shardingsphere-jdbc/shardingsphere-jdbc-core/src/main/java/org/apache/shardingsphere/driver/jdbc/core/resultset/ShardingSphereResultSetUtil.java
 
b/shardingsphere-jdbc/shardingsphere-jdbc-core/src/main/java/org/apache/shardingsphere/driver/jdbc/core/resultset/ShardingSphereResultSetUtil.java
new file mode 100644
index 00000000000..227f7bceadd
--- /dev/null
+++ 
b/shardingsphere-jdbc/shardingsphere-jdbc-core/src/main/java/org/apache/shardingsphere/driver/jdbc/core/resultset/ShardingSphereResultSetUtil.java
@@ -0,0 +1,71 @@
+/*
+ * 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.driver.jdbc.core.resultset;
+
+import lombok.AccessLevel;
+import lombok.NoArgsConstructor;
+import org.apache.commons.collections4.map.CaseInsensitiveMap;
+import 
org.apache.shardingsphere.infra.binder.segment.select.projection.DerivedColumn;
+import 
org.apache.shardingsphere.infra.binder.segment.select.projection.Projection;
+import org.apache.shardingsphere.infra.binder.statement.SQLStatementContext;
+import 
org.apache.shardingsphere.infra.binder.statement.dml.SelectStatementContext;
+
+import java.sql.ResultSetMetaData;
+import java.sql.SQLException;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * Util for {@link ShardingSphereResultSet}.
+ */
+@NoArgsConstructor(access = AccessLevel.PRIVATE)
+public final class ShardingSphereResultSetUtil {
+    
+    /**
+     * Create column label and index map.
+     *
+     * @param sqlStatementContext SQL statement context
+     * @param resultSetMetaData meta data of result set
+     * @return column label and index map
+     * @throws SQLException SQL exception
+     */
+    public static Map<String, Integer> createColumnLabelAndIndexMap(final 
SQLStatementContext<?> sqlStatementContext, final ResultSetMetaData 
resultSetMetaData) throws SQLException {
+        if (hasSelectExpandProjections(sqlStatementContext)) {
+            return 
createColumnLabelAndIndexMapWithExpandProjections((SelectStatementContext) 
sqlStatementContext);
+        }
+        Map<String, Integer> result = new 
CaseInsensitiveMap<>(resultSetMetaData.getColumnCount(), 1);
+        for (int columnIndex = resultSetMetaData.getColumnCount(); columnIndex 
> 0; columnIndex--) {
+            result.put(resultSetMetaData.getColumnLabel(columnIndex), 
columnIndex);
+        }
+        return result;
+    }
+    
+    private static Map<String, Integer> 
createColumnLabelAndIndexMapWithExpandProjections(final SelectStatementContext 
statementContext) throws SQLException {
+        List<Projection> actualProjections = 
statementContext.getProjectionsContext().getExpandProjections();
+        Map<String, Integer> result = new 
CaseInsensitiveMap<>(actualProjections.size(), 1);
+        for (int columnIndex = actualProjections.size(); columnIndex > 0; 
columnIndex--) {
+            Projection projection = actualProjections.get(columnIndex - 1);
+            
result.put(DerivedColumn.isDerivedColumnName(projection.getColumnLabel()) ? 
projection.getExpression() : projection.getColumnLabel(), columnIndex);
+        }
+        return result;
+    }
+    
+    private static boolean hasSelectExpandProjections(final 
SQLStatementContext<?> sqlStatementContext) {
+        return sqlStatementContext instanceof SelectStatementContext && 
!((SelectStatementContext) 
sqlStatementContext).getProjectionsContext().getExpandProjections().isEmpty();
+    }
+}
diff --git 
a/shardingsphere-jdbc/shardingsphere-jdbc-core/src/main/java/org/apache/shardingsphere/driver/jdbc/core/statement/ShardingSpherePreparedStatement.java
 
b/shardingsphere-jdbc/shardingsphere-jdbc-core/src/main/java/org/apache/shardingsphere/driver/jdbc/core/statement/ShardingSpherePreparedStatement.java
index 5688eaab1ac..9bfd3a30ecc 100644
--- 
a/shardingsphere-jdbc/shardingsphere-jdbc-core/src/main/java/org/apache/shardingsphere/driver/jdbc/core/statement/ShardingSpherePreparedStatement.java
+++ 
b/shardingsphere-jdbc/shardingsphere-jdbc-core/src/main/java/org/apache/shardingsphere/driver/jdbc/core/statement/ShardingSpherePreparedStatement.java
@@ -27,6 +27,7 @@ import 
org.apache.shardingsphere.driver.executor.callback.impl.PreparedStatement
 import 
org.apache.shardingsphere.driver.jdbc.adapter.AbstractPreparedStatementAdapter;
 import 
org.apache.shardingsphere.driver.jdbc.core.connection.ShardingSphereConnection;
 import 
org.apache.shardingsphere.driver.jdbc.core.resultset.GeneratedKeysResultSet;
+import 
org.apache.shardingsphere.driver.jdbc.core.resultset.ShardingSphereResultSetUtil;
 import 
org.apache.shardingsphere.driver.jdbc.core.resultset.ShardingSphereResultSet;
 import 
org.apache.shardingsphere.driver.jdbc.core.statement.metadata.ShardingSphereParameterMetaData;
 import org.apache.shardingsphere.driver.jdbc.exception.SQLExceptionErrorCode;
@@ -97,6 +98,7 @@ import java.util.Collection;
 import java.util.Collections;
 import java.util.LinkedList;
 import java.util.List;
+import java.util.Map;
 import java.util.Optional;
 import java.util.stream.Collectors;
 
@@ -145,6 +147,8 @@ public final class ShardingSpherePreparedStatement extends 
AbstractPreparedState
     
     private ExecutionContext executionContext;
     
+    private Map<String, Integer> columnLabelAndIndexMap;
+    
     private ResultSet currentResultSet;
     
     private String trafficInstanceId;
@@ -227,7 +231,10 @@ public final class ShardingSpherePreparedStatement extends 
AbstractPreparedState
             executionContext = createExecutionContext(queryContext);
             List<QueryResult> queryResults = executeQuery0();
             MergedResult mergedResult = mergeQuery(queryResults);
-            result = new ShardingSphereResultSet(getResultSets(), 
mergedResult, this, executionContext);
+            List<ResultSet> resultSets = getResultSets();
+            Map<String, Integer> columnLabelAndIndexMap = null != 
this.columnLabelAndIndexMap ? this.columnLabelAndIndexMap
+                    : (this.columnLabelAndIndexMap = 
ShardingSphereResultSetUtil.createColumnLabelAndIndexMap(sqlStatementContext, 
resultSets.get(0).getMetaData()));
+            result = new ShardingSphereResultSet(resultSets, mergedResult, 
this, executionContext, columnLabelAndIndexMap);
         } catch (SQLException ex) {
             handleExceptionInTransaction(connection, metaDataContexts);
             throw ex;
@@ -450,7 +457,9 @@ public final class ShardingSpherePreparedStatement extends 
AbstractPreparedState
         if (executionContext.getSqlStatementContext() instanceof 
SelectStatementContext || 
executionContext.getSqlStatementContext().getSqlStatement() instanceof 
DALStatement) {
             List<ResultSet> resultSets = getResultSets();
             MergedResult mergedResult = 
mergeQuery(getQueryResults(resultSets));
-            currentResultSet = new ShardingSphereResultSet(resultSets, 
mergedResult, this, executionContext);
+            Map<String, Integer> columnLabelAndIndexMap = null != 
this.columnLabelAndIndexMap ? this.columnLabelAndIndexMap
+                    : (this.columnLabelAndIndexMap = 
ShardingSphereResultSetUtil.createColumnLabelAndIndexMap(sqlStatementContext, 
resultSets.get(0).getMetaData()));
+            currentResultSet = new ShardingSphereResultSet(resultSets, 
mergedResult, this, executionContext, columnLabelAndIndexMap);
         }
         return currentResultSet;
     }
diff --git 
a/shardingsphere-jdbc/shardingsphere-jdbc-core/src/test/java/org/apache/shardingsphere/driver/jdbc/core/resultset/ShardingSphereResultSetUtilTest.java
 
b/shardingsphere-jdbc/shardingsphere-jdbc-core/src/test/java/org/apache/shardingsphere/driver/jdbc/core/resultset/ShardingSphereResultSetUtilTest.java
new file mode 100644
index 00000000000..dbececa94b7
--- /dev/null
+++ 
b/shardingsphere-jdbc/shardingsphere-jdbc-core/src/test/java/org/apache/shardingsphere/driver/jdbc/core/resultset/ShardingSphereResultSetUtilTest.java
@@ -0,0 +1,65 @@
+/*
+ * 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.driver.jdbc.core.resultset;
+
+import 
org.apache.shardingsphere.infra.binder.segment.select.projection.Projection;
+import 
org.apache.shardingsphere.infra.binder.segment.select.projection.ProjectionsContext;
+import 
org.apache.shardingsphere.infra.binder.segment.select.projection.impl.ColumnProjection;
+import 
org.apache.shardingsphere.infra.binder.statement.dml.SelectStatementContext;
+import org.junit.Test;
+
+import java.sql.ResultSetMetaData;
+import java.sql.SQLException;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+import static org.hamcrest.CoreMatchers.is;
+import static org.junit.Assert.assertThat;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.when;
+
+public final class ShardingSphereResultSetUtilTest {
+    
+    @Test
+    public void 
assertCreateColumnLabelAndIndexMapWithSelectWithoutExpandProjections() throws 
SQLException {
+        SelectStatementContext selectStatementContext = 
mock(SelectStatementContext.class);
+        when(selectStatementContext.getProjectionsContext()).thenReturn(new 
ProjectionsContext(0, 0, false, Collections.emptyList()));
+        ResultSetMetaData resultSetMetaData = mock(ResultSetMetaData.class);
+        when(resultSetMetaData.getColumnCount()).thenReturn(1);
+        when(resultSetMetaData.getColumnLabel(1)).thenReturn("label");
+        Map<String, Integer> actual = 
ShardingSphereResultSetUtil.createColumnLabelAndIndexMap(selectStatementContext,
 resultSetMetaData);
+        assertThat(actual, is(Collections.singletonMap("label", 1)));
+    }
+    
+    @Test
+    public void 
assertCreateColumnLabelAndIndexMapWithSelectWithExpandProjections() throws 
SQLException {
+        SelectStatementContext selectStatementContext = 
mock(SelectStatementContext.class);
+        List<Projection> projections = new ArrayList<>(2);
+        projections.add(new ColumnProjection(null, "col1", null));
+        projections.add(new ColumnProjection(null, "col2", null));
+        when(selectStatementContext.getProjectionsContext()).thenReturn(new 
ProjectionsContext(0, 0, false, projections));
+        Map<String, Integer> expected = new HashMap<>(2, 1);
+        expected.put("col1", 1);
+        expected.put("col2", 2);
+        Map<String, Integer> actual = 
ShardingSphereResultSetUtil.createColumnLabelAndIndexMap(selectStatementContext,
 null);
+        assertThat(actual, is(expected));
+    }
+}

Reply via email to