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));
+ }
+}