You are viewing a plain text version of this content. The canonical link for it is here.
Posted to notifications@shardingsphere.apache.org by du...@apache.org on 2023/03/20 03:54:39 UTC
[shardingsphere] branch master updated: Add ColumnContainedRule for EncryptRule and MaskRule (#24679)
This is an automated email from the ASF dual-hosted git repository.
duanzhengqiang 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 ed9a1739ac5 Add ColumnContainedRule for EncryptRule and MaskRule (#24679)
ed9a1739ac5 is described below
commit ed9a1739ac5ddd38c3dc04913a945dbf61091320
Author: zhaojinchao <zh...@apache.org>
AuthorDate: Mon Mar 20 11:54:32 2023 +0800
Add ColumnContainedRule for EncryptRule and MaskRule (#24679)
* Add ColumnContainedRule for EncryptRule and MaskRule
* Fix checkstyle
---
.../shardingsphere/encrypt/rule/EncryptRule.java | 3 +-
.../apache/shardingsphere/mask/rule/MaskRule.java | 3 +-
.../rule/identifier/type/ColumnContainedRule.java | 35 +++++++++++++++++++++
.../resultset/ShardingSphereResultSetMetaData.java | 25 +++++++++++++++
.../driver/jdbc/adapter/ResultSetAdapterTest.java | 14 ++++++++-
.../proxy/backend/connector/DatabaseConnector.java | 36 +++++++++++++++++-----
6 files changed, 106 insertions(+), 10 deletions(-)
diff --git a/features/encrypt/core/src/main/java/org/apache/shardingsphere/encrypt/rule/EncryptRule.java b/features/encrypt/core/src/main/java/org/apache/shardingsphere/encrypt/rule/EncryptRule.java
index b5acaa93327..1bd431d2f59 100644
--- a/features/encrypt/core/src/main/java/org/apache/shardingsphere/encrypt/rule/EncryptRule.java
+++ b/features/encrypt/core/src/main/java/org/apache/shardingsphere/encrypt/rule/EncryptRule.java
@@ -29,6 +29,7 @@ import org.apache.shardingsphere.encrypt.spi.EncryptAlgorithm;
import org.apache.shardingsphere.encrypt.spi.context.EncryptContext;
import org.apache.shardingsphere.infra.config.rule.RuleConfiguration;
import org.apache.shardingsphere.infra.rule.identifier.scope.DatabaseRule;
+import org.apache.shardingsphere.infra.rule.identifier.type.ColumnContainedRule;
import org.apache.shardingsphere.infra.rule.identifier.type.TableContainedRule;
import org.apache.shardingsphere.infra.util.exception.ShardingSpherePreconditions;
import org.apache.shardingsphere.infra.util.spi.type.typed.TypedSPILoader;
@@ -44,7 +45,7 @@ import java.util.Optional;
/**
* Encrypt rule.
*/
-public final class EncryptRule implements DatabaseRule, TableContainedRule {
+public final class EncryptRule implements DatabaseRule, TableContainedRule, ColumnContainedRule {
@Getter
private final RuleConfiguration configuration;
diff --git a/features/mask/core/src/main/java/org/apache/shardingsphere/mask/rule/MaskRule.java b/features/mask/core/src/main/java/org/apache/shardingsphere/mask/rule/MaskRule.java
index 139b2489a8f..13e2a2bd380 100644
--- a/features/mask/core/src/main/java/org/apache/shardingsphere/mask/rule/MaskRule.java
+++ b/features/mask/core/src/main/java/org/apache/shardingsphere/mask/rule/MaskRule.java
@@ -20,6 +20,7 @@ package org.apache.shardingsphere.mask.rule;
import lombok.Getter;
import org.apache.shardingsphere.infra.config.rule.RuleConfiguration;
import org.apache.shardingsphere.infra.rule.identifier.scope.DatabaseRule;
+import org.apache.shardingsphere.infra.rule.identifier.type.ColumnContainedRule;
import org.apache.shardingsphere.infra.rule.identifier.type.TableContainedRule;
import org.apache.shardingsphere.infra.util.spi.type.typed.TypedSPILoader;
import org.apache.shardingsphere.mask.api.config.MaskRuleConfiguration;
@@ -34,7 +35,7 @@ import java.util.Optional;
* Mask rule.
*/
@SuppressWarnings("rawtypes")
-public final class MaskRule implements DatabaseRule, TableContainedRule {
+public final class MaskRule implements DatabaseRule, TableContainedRule, ColumnContainedRule {
@Getter
private final RuleConfiguration configuration;
diff --git a/infra/common/src/main/java/org/apache/shardingsphere/infra/rule/identifier/type/ColumnContainedRule.java b/infra/common/src/main/java/org/apache/shardingsphere/infra/rule/identifier/type/ColumnContainedRule.java
new file mode 100644
index 00000000000..cd15c9f768b
--- /dev/null
+++ b/infra/common/src/main/java/org/apache/shardingsphere/infra/rule/identifier/type/ColumnContainedRule.java
@@ -0,0 +1,35 @@
+/*
+ * 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.infra.rule.identifier.type;
+
+import org.apache.shardingsphere.infra.rule.ShardingSphereRule;
+
+import java.util.Collection;
+
+/**
+ * ShardingSphere rule which contains column.
+ */
+public interface ColumnContainedRule extends ShardingSphereRule {
+
+ /**
+ * Get tables.
+ *
+ * @return tables
+ */
+ Collection<String> getTables();
+}
diff --git a/jdbc/core/src/main/java/org/apache/shardingsphere/driver/jdbc/core/resultset/ShardingSphereResultSetMetaData.java b/jdbc/core/src/main/java/org/apache/shardingsphere/driver/jdbc/core/resultset/ShardingSphereResultSetMetaData.java
index bcd810d0df2..87b8f90dadc 100644
--- a/jdbc/core/src/main/java/org/apache/shardingsphere/driver/jdbc/core/resultset/ShardingSphereResultSetMetaData.java
+++ b/jdbc/core/src/main/java/org/apache/shardingsphere/driver/jdbc/core/resultset/ShardingSphereResultSetMetaData.java
@@ -28,7 +28,9 @@ import org.apache.shardingsphere.infra.binder.statement.SQLStatementContext;
import org.apache.shardingsphere.infra.binder.statement.dml.SelectStatementContext;
import org.apache.shardingsphere.infra.database.DefaultDatabase;
import org.apache.shardingsphere.infra.metadata.database.ShardingSphereDatabase;
+import org.apache.shardingsphere.infra.rule.identifier.type.ColumnContainedRule;
import org.apache.shardingsphere.infra.rule.identifier.type.DataNodeContainedRule;
+import org.apache.shardingsphere.infra.rule.identifier.type.MutableDataNodeRule;
import java.sql.ResultSetMetaData;
import java.sql.SQLException;
@@ -50,6 +52,9 @@ public final class ShardingSphereResultSetMetaData extends WrapperAdapter implem
@Override
public int getColumnCount() throws SQLException {
if (sqlStatementContext instanceof SelectStatementContext) {
+ if (isAllSingleTable()) {
+ return resultSetMetaData.getColumnCount();
+ }
if (hasSelectExpandProjections()) {
return ((SelectStatementContext) sqlStatementContext).getProjectionsContext().getExpandProjections().size();
}
@@ -95,6 +100,9 @@ public final class ShardingSphereResultSetMetaData extends WrapperAdapter implem
@Override
public String getColumnLabel(final int column) throws SQLException {
+ if (isAllSingleTable()) {
+ return resultSetMetaData.getColumnLabel(column);
+ }
if (hasSelectExpandProjections()) {
checkColumnIndex(column);
Projection projection = ((SelectStatementContext) sqlStatementContext).getProjectionsContext().getExpandProjections().get(column - 1);
@@ -107,6 +115,9 @@ public final class ShardingSphereResultSetMetaData extends WrapperAdapter implem
@Override
public String getColumnName(final int column) throws SQLException {
+ if (isAllSingleTable()) {
+ return resultSetMetaData.getColumnName(column);
+ }
if (hasSelectExpandProjections()) {
checkColumnIndex(column);
Projection projection = ((SelectStatementContext) sqlStatementContext).getProjectionsContext().getExpandProjections().get(column - 1);
@@ -124,6 +135,20 @@ public final class ShardingSphereResultSetMetaData extends WrapperAdapter implem
return sqlStatementContext instanceof SelectStatementContext && !((SelectStatementContext) sqlStatementContext).getProjectionsContext().getExpandProjections().isEmpty();
}
+ private boolean isAllSingleTable() {
+ return sqlStatementContext.getTablesContext().getTableNames().stream().allMatch(each -> !containsInImmutableDataNodeContainedRule(each)
+ && !containsInColumnContainedRule(each));
+ }
+
+ private boolean containsInImmutableDataNodeContainedRule(final String tableName) {
+ return database.getRuleMetaData().findRules(DataNodeContainedRule.class).stream()
+ .filter(each -> !(each instanceof MutableDataNodeRule)).anyMatch(each -> each.getAllTables().contains(tableName));
+ }
+
+ private boolean containsInColumnContainedRule(final String tableName) {
+ return database.getRuleMetaData().findRules(ColumnContainedRule.class).stream().anyMatch(each -> each.getTables().contains(tableName));
+ }
+
private void checkColumnIndex(final int column) throws SQLException {
List<Projection> actualProjections = ((SelectStatementContext) sqlStatementContext).getProjectionsContext().getExpandProjections();
if (column > actualProjections.size()) {
diff --git a/jdbc/core/src/test/java/org/apache/shardingsphere/driver/jdbc/adapter/ResultSetAdapterTest.java b/jdbc/core/src/test/java/org/apache/shardingsphere/driver/jdbc/adapter/ResultSetAdapterTest.java
index 618d54c58b1..d131f855397 100644
--- a/jdbc/core/src/test/java/org/apache/shardingsphere/driver/jdbc/adapter/ResultSetAdapterTest.java
+++ b/jdbc/core/src/test/java/org/apache/shardingsphere/driver/jdbc/adapter/ResultSetAdapterTest.java
@@ -19,6 +19,8 @@ package org.apache.shardingsphere.driver.jdbc.adapter;
import org.apache.shardingsphere.driver.jdbc.core.resultset.ShardingSphereResultSet;
import org.apache.shardingsphere.driver.jdbc.core.statement.ShardingSphereStatement;
+import org.apache.shardingsphere.infra.binder.segment.table.TablesContext;
+import org.apache.shardingsphere.infra.binder.statement.SQLStatementContext;
import org.apache.shardingsphere.infra.executor.sql.context.ExecutionContext;
import org.apache.shardingsphere.infra.merge.result.MergedResult;
import org.junit.jupiter.api.Test;
@@ -111,6 +113,16 @@ public final class ResultSetAdapterTest {
when(resultSetMetaData.getColumnLabel(1)).thenReturn("col");
when(resultSetMetaData.getColumnCount()).thenReturn(1);
when(resultSet.getMetaData()).thenReturn(resultSetMetaData);
- return new ShardingSphereResultSet(Collections.singletonList(resultSet), mock(MergedResult.class), mock(ShardingSphereStatement.class, RETURNS_DEEP_STUBS), mock(ExecutionContext.class));
+ return new ShardingSphereResultSet(Collections.singletonList(resultSet), mock(MergedResult.class), mock(ShardingSphereStatement.class, RETURNS_DEEP_STUBS), createExecutionContext());
+ }
+
+ private ExecutionContext createExecutionContext() {
+ ExecutionContext result = mock(ExecutionContext.class);
+ SQLStatementContext sqlStatementContext = mock(SQLStatementContext.class);
+ TablesContext tablesContext = mock(TablesContext.class);
+ when(tablesContext.getTableNames()).thenReturn(Collections.emptyList());
+ when(sqlStatementContext.getTablesContext()).thenReturn(tablesContext);
+ when(result.getSqlStatementContext()).thenReturn(sqlStatementContext);
+ return result;
}
}
diff --git a/proxy/backend/core/src/main/java/org/apache/shardingsphere/proxy/backend/connector/DatabaseConnector.java b/proxy/backend/core/src/main/java/org/apache/shardingsphere/proxy/backend/connector/DatabaseConnector.java
index b581068c0b1..a261fac31aa 100644
--- a/proxy/backend/core/src/main/java/org/apache/shardingsphere/proxy/backend/connector/DatabaseConnector.java
+++ b/proxy/backend/core/src/main/java/org/apache/shardingsphere/proxy/backend/connector/DatabaseConnector.java
@@ -49,7 +49,9 @@ import org.apache.shardingsphere.infra.merge.MergeEngine;
import org.apache.shardingsphere.infra.merge.result.MergedResult;
import org.apache.shardingsphere.infra.metadata.database.ShardingSphereDatabase;
import org.apache.shardingsphere.infra.metadata.database.schema.util.SystemSchemaUtil;
+import org.apache.shardingsphere.infra.rule.identifier.type.ColumnContainedRule;
import org.apache.shardingsphere.infra.rule.identifier.type.DataNodeContainedRule;
+import org.apache.shardingsphere.infra.rule.identifier.type.MutableDataNodeRule;
import org.apache.shardingsphere.infra.util.exception.ShardingSpherePreconditions;
import org.apache.shardingsphere.mode.manager.ContextManager;
import org.apache.shardingsphere.mode.metadata.MetaDataContexts;
@@ -324,23 +326,43 @@ public final class DatabaseConnector implements DatabaseBackendHandler {
return result;
}
- private QueryHeader createQueryHeader(final QueryHeaderBuilderEngine queryHeaderBuilderEngine, final ExecutionContext executionContext,
- final QueryResult queryResultSample, final ShardingSphereDatabase database, final int columnIndex) throws SQLException {
- return hasSelectExpandProjections(executionContext.getSqlStatementContext()) ? queryHeaderBuilderEngine.build(
- ((SelectStatementContext) executionContext.getSqlStatementContext()).getProjectionsContext(), queryResultSample.getMetaData(), database, columnIndex)
- : queryHeaderBuilderEngine.build(queryResultSample.getMetaData(), database, columnIndex);
- }
-
private int getColumnCount(final ExecutionContext executionContext, final QueryResult queryResultSample) throws SQLException {
+ if (isAllSingleTable(executionContext.getSqlStatementContext())) {
+ return queryResultSample.getMetaData().getColumnCount();
+ }
return hasSelectExpandProjections(executionContext.getSqlStatementContext())
? ((SelectStatementContext) executionContext.getSqlStatementContext()).getProjectionsContext().getExpandProjections().size()
: queryResultSample.getMetaData().getColumnCount();
}
+ private boolean isAllSingleTable(final SQLStatementContext<?> sqlStatementContext) {
+ return sqlStatementContext.getTablesContext().getTableNames().stream().allMatch(each -> !containsInImmutableDataNodeContainedRule(each)
+ && !containsInColumnContainedRule(each));
+ }
+
+ private boolean containsInImmutableDataNodeContainedRule(final String tableName) {
+ return database.getRuleMetaData().findRules(DataNodeContainedRule.class).stream()
+ .filter(each -> !(each instanceof MutableDataNodeRule)).anyMatch(each -> each.getAllTables().contains(tableName));
+ }
+
+ private boolean containsInColumnContainedRule(final String tableName) {
+ return database.getRuleMetaData().findRules(ColumnContainedRule.class).stream().anyMatch(each -> each.getTables().contains(tableName));
+ }
+
private boolean hasSelectExpandProjections(final SQLStatementContext<?> sqlStatementContext) {
return sqlStatementContext instanceof SelectStatementContext && !((SelectStatementContext) sqlStatementContext).getProjectionsContext().getExpandProjections().isEmpty();
}
+ private QueryHeader createQueryHeader(final QueryHeaderBuilderEngine queryHeaderBuilderEngine, final ExecutionContext executionContext,
+ final QueryResult queryResultSample, final ShardingSphereDatabase database, final int columnIndex) throws SQLException {
+ if (isAllSingleTable(executionContext.getSqlStatementContext())) {
+ return queryHeaderBuilderEngine.build(queryResultSample.getMetaData(), database, columnIndex);
+ }
+ return hasSelectExpandProjections(executionContext.getSqlStatementContext())
+ ? queryHeaderBuilderEngine.build(((SelectStatementContext) executionContext.getSqlStatementContext()).getProjectionsContext(), queryResultSample.getMetaData(), database, columnIndex)
+ : queryHeaderBuilderEngine.build(queryResultSample.getMetaData(), database, columnIndex);
+ }
+
private MergedResult mergeQuery(final SQLStatementContext<?> sqlStatementContext, final List<QueryResult> queryResults) throws SQLException {
MergeEngine mergeEngine = new MergeEngine(database, ProxyContext.getInstance().getContextManager().getMetaDataContexts().getMetaData().getProps(),
backendConnection.getConnectionSession().getConnectionContext());