You are viewing a plain text version of this content. The canonical link for it is here.
Posted to notifications@shardingsphere.apache.org by su...@apache.org on 2023/06/20 16:05:47 UTC
[shardingsphere] branch master updated: Refactor EncryptMergedResult (#26468)
This is an automated email from the ASF dual-hosted git repository.
sunnianjun 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 48b03d0d85f Refactor EncryptMergedResult (#26468)
48b03d0d85f is described below
commit 48b03d0d85f2c33fbecc75ff0a6e16843e148446
Author: Liang Zhang <zh...@apache.org>
AuthorDate: Wed Jun 21 00:05:41 2023 +0800
Refactor EncryptMergedResult (#26468)
* Refactor EncryptInsertOnDuplicateKeyUpdateValueParameterRewriter
* Refactor EncryptInsertOnDuplicateKeyUpdateValueParameterRewriter
* Refactor EncryptMergedResult
---
.../merge/dql/EncryptAlgorithmMetaData.java | 59 ---------
.../encrypt/merge/dql/EncryptMergedResult.java | 40 ++++--
.../merge/dql/EncryptAlgorithmMetaDataTest.java | 143 ---------------------
.../encrypt/merge/dql/EncryptMergedResultTest.java | 8 --
.../statement/dml/SelectStatementContext.java | 22 ++++
5 files changed, 54 insertions(+), 218 deletions(-)
diff --git a/features/encrypt/core/src/main/java/org/apache/shardingsphere/encrypt/merge/dql/EncryptAlgorithmMetaData.java b/features/encrypt/core/src/main/java/org/apache/shardingsphere/encrypt/merge/dql/EncryptAlgorithmMetaData.java
index 8583a32363e..b18f8f79ffe 100644
--- a/features/encrypt/core/src/main/java/org/apache/shardingsphere/encrypt/merge/dql/EncryptAlgorithmMetaData.java
+++ b/features/encrypt/core/src/main/java/org/apache/shardingsphere/encrypt/merge/dql/EncryptAlgorithmMetaData.java
@@ -19,22 +19,10 @@ package org.apache.shardingsphere.encrypt.merge.dql;
import lombok.Getter;
import lombok.RequiredArgsConstructor;
-import org.apache.shardingsphere.encrypt.api.context.EncryptContext;
-import org.apache.shardingsphere.encrypt.context.EncryptContextBuilder;
import org.apache.shardingsphere.encrypt.rule.EncryptRule;
-import org.apache.shardingsphere.infra.binder.segment.select.projection.Projection;
-import org.apache.shardingsphere.infra.binder.segment.select.projection.impl.ColumnProjection;
-import org.apache.shardingsphere.infra.binder.segment.select.projection.impl.SubqueryProjection;
-import org.apache.shardingsphere.infra.binder.segment.table.TablesContext;
import org.apache.shardingsphere.infra.binder.statement.dml.SelectStatementContext;
-import org.apache.shardingsphere.infra.database.type.DatabaseTypeEngine;
import org.apache.shardingsphere.infra.metadata.database.ShardingSphereDatabase;
-import java.util.Collections;
-import java.util.List;
-import java.util.Map;
-import java.util.Optional;
-
/**
* Encrypt algorithm meta data.
*/
@@ -47,51 +35,4 @@ public final class EncryptAlgorithmMetaData {
private final EncryptRule encryptRule;
private final SelectStatementContext selectStatementContext;
-
- /**
- * Find encrypt context.
- *
- * @param columnIndex column index
- * @return encrypt context
- */
- public Optional<EncryptContext> findEncryptContext(final int columnIndex) {
- Optional<ColumnProjection> columnProjection = findColumnProjection(columnIndex);
- if (!columnProjection.isPresent()) {
- return Optional.empty();
- }
- TablesContext tablesContext = selectStatementContext.getTablesContext();
- String schemaName = tablesContext.getSchemaName().orElseGet(() -> DatabaseTypeEngine.getDefaultSchemaName(selectStatementContext.getDatabaseType(), database.getName()));
- Map<String, String> expressionTableNames = tablesContext.findTableNamesByColumnProjection(
- Collections.singletonList(columnProjection.get()), database.getSchema(schemaName));
- Optional<String> tableName = findTableName(columnProjection.get(), expressionTableNames);
- return tableName.map(optional -> EncryptContextBuilder.build(database.getName(), schemaName, optional, columnProjection.get().getName()));
- }
-
- private Optional<ColumnProjection> findColumnProjection(final int columnIndex) {
- List<Projection> expandProjections = selectStatementContext.getProjectionsContext().getExpandProjections();
- if (expandProjections.size() < columnIndex) {
- return Optional.empty();
- }
- Projection projection = expandProjections.get(columnIndex - 1);
- if (projection instanceof ColumnProjection) {
- return Optional.of((ColumnProjection) projection);
- }
- if (projection instanceof SubqueryProjection && ((SubqueryProjection) projection).getProjection() instanceof ColumnProjection) {
- return Optional.of((ColumnProjection) ((SubqueryProjection) projection).getProjection());
- }
- return Optional.empty();
- }
-
- private Optional<String> findTableName(final ColumnProjection columnProjection, final Map<String, String> columnTableNames) {
- String tableName = columnTableNames.get(columnProjection.getExpression());
- if (null != tableName) {
- return Optional.of(tableName);
- }
- for (String each : selectStatementContext.getTablesContext().getTableNames()) {
- if (encryptRule.findEncryptTable(each).map(optional -> optional.isEncryptColumn(columnProjection.getName())).orElse(false)) {
- return Optional.of(each);
- }
- }
- return Optional.empty();
- }
}
diff --git a/features/encrypt/core/src/main/java/org/apache/shardingsphere/encrypt/merge/dql/EncryptMergedResult.java b/features/encrypt/core/src/main/java/org/apache/shardingsphere/encrypt/merge/dql/EncryptMergedResult.java
index f205b23a332..d07e538eb3e 100644
--- a/features/encrypt/core/src/main/java/org/apache/shardingsphere/encrypt/merge/dql/EncryptMergedResult.java
+++ b/features/encrypt/core/src/main/java/org/apache/shardingsphere/encrypt/merge/dql/EncryptMergedResult.java
@@ -18,13 +18,17 @@
package org.apache.shardingsphere.encrypt.merge.dql;
import lombok.RequiredArgsConstructor;
-import org.apache.shardingsphere.encrypt.api.context.EncryptContext;
+import org.apache.shardingsphere.infra.binder.segment.select.projection.impl.ColumnProjection;
+import org.apache.shardingsphere.infra.binder.segment.table.TablesContext;
+import org.apache.shardingsphere.infra.database.type.DatabaseTypeEngine;
import org.apache.shardingsphere.infra.merge.result.MergedResult;
import java.io.InputStream;
import java.io.Reader;
import java.sql.SQLException;
import java.util.Calendar;
+import java.util.Collections;
+import java.util.Map;
import java.util.Optional;
/**
@@ -44,16 +48,36 @@ public final class EncryptMergedResult implements MergedResult {
@Override
public Object getValue(final int columnIndex, final Class<?> type) throws SQLException {
- Optional<EncryptContext> encryptContext = metaData.findEncryptContext(columnIndex);
- if (!encryptContext.isPresent()) {
+ Optional<ColumnProjection> columnProjection = metaData.getSelectStatementContext().findColumnProjection(columnIndex);
+ if (!columnProjection.isPresent()) {
return mergedResult.getValue(columnIndex, type);
}
- if (metaData.getEncryptRule().findEncryptTable(encryptContext.get().getTableName()).map(optional -> optional.isEncryptColumn(encryptContext.get().getColumnName())).orElse(false)) {
- Object cipherValue = mergedResult.getValue(columnIndex, Object.class);
- return metaData.getEncryptRule().decrypt(
- encryptContext.get().getDatabaseName(), encryptContext.get().getSchemaName(), encryptContext.get().getTableName(), encryptContext.get().getColumnName(), cipherValue);
+ TablesContext tablesContext = metaData.getSelectStatementContext().getTablesContext();
+ String schemaName = tablesContext.getSchemaName()
+ .orElseGet(() -> DatabaseTypeEngine.getDefaultSchemaName(metaData.getSelectStatementContext().getDatabaseType(), metaData.getDatabase().getName()));
+ Map<String, String> expressionTableNames = tablesContext.findTableNamesByColumnProjection(Collections.singleton(columnProjection.get()), metaData.getDatabase().getSchema(schemaName));
+ Optional<String> tableName = findTableName(columnProjection.get(), expressionTableNames);
+ if (!tableName.isPresent()) {
+ return mergedResult.getValue(columnIndex, type);
+ }
+ if (!metaData.getEncryptRule().findEncryptTable(tableName.get()).map(optional -> optional.isEncryptColumn(columnProjection.get().getName())).orElse(false)) {
+ return mergedResult.getValue(columnIndex, type);
+ }
+ Object cipherValue = mergedResult.getValue(columnIndex, Object.class);
+ return metaData.getEncryptRule().decrypt(metaData.getDatabase().getName(), schemaName, tableName.get(), columnProjection.get().getName(), cipherValue);
+ }
+
+ private Optional<String> findTableName(final ColumnProjection columnProjection, final Map<String, String> columnTableNames) {
+ String tableName = columnTableNames.get(columnProjection.getExpression());
+ if (null != tableName) {
+ return Optional.of(tableName);
+ }
+ for (String each : metaData.getSelectStatementContext().getTablesContext().getTableNames()) {
+ if (metaData.getEncryptRule().findEncryptTable(each).map(optional -> optional.isEncryptColumn(columnProjection.getName())).orElse(false)) {
+ return Optional.of(each);
+ }
}
- return mergedResult.getValue(columnIndex, type);
+ return Optional.empty();
}
@Override
diff --git a/features/encrypt/core/src/test/java/org/apache/shardingsphere/encrypt/merge/dql/EncryptAlgorithmMetaDataTest.java b/features/encrypt/core/src/test/java/org/apache/shardingsphere/encrypt/merge/dql/EncryptAlgorithmMetaDataTest.java
deleted file mode 100644
index 4545fdcfc00..00000000000
--- a/features/encrypt/core/src/test/java/org/apache/shardingsphere/encrypt/merge/dql/EncryptAlgorithmMetaDataTest.java
+++ /dev/null
@@ -1,143 +0,0 @@
-/*
- * 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.encrypt.merge.dql;
-
-import org.apache.shardingsphere.encrypt.api.context.EncryptContext;
-import org.apache.shardingsphere.encrypt.rule.EncryptRule;
-import org.apache.shardingsphere.encrypt.rule.EncryptTable;
-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.segment.select.projection.impl.DerivedProjection;
-import org.apache.shardingsphere.infra.binder.segment.select.projection.impl.SubqueryProjection;
-import org.apache.shardingsphere.infra.binder.segment.table.TablesContext;
-import org.apache.shardingsphere.infra.binder.statement.dml.SelectStatementContext;
-import org.apache.shardingsphere.infra.database.DefaultDatabase;
-import org.apache.shardingsphere.infra.database.type.dialect.MySQLDatabaseType;
-import org.apache.shardingsphere.infra.metadata.database.ShardingSphereDatabase;
-import org.apache.shardingsphere.infra.metadata.database.schema.model.ShardingSphereSchema;
-import org.junit.jupiter.api.BeforeEach;
-import org.junit.jupiter.api.Test;
-import org.junit.jupiter.api.extension.ExtendWith;
-import org.mockito.Answers;
-import org.mockito.Mock;
-import org.mockito.junit.jupiter.MockitoExtension;
-import org.mockito.junit.jupiter.MockitoSettings;
-import org.mockito.quality.Strictness;
-
-import java.util.Arrays;
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.Map;
-import java.util.Optional;
-
-import static org.hamcrest.CoreMatchers.is;
-import static org.hamcrest.MatcherAssert.assertThat;
-import static org.junit.jupiter.api.Assertions.assertFalse;
-import static org.junit.jupiter.api.Assertions.assertTrue;
-import static org.mockito.Mockito.mock;
-import static org.mockito.Mockito.when;
-
-@ExtendWith(MockitoExtension.class)
-@MockitoSettings(strictness = Strictness.LENIENT)
-class EncryptAlgorithmMetaDataTest {
-
- @Mock(answer = Answers.RETURNS_DEEP_STUBS)
- private ShardingSphereDatabase database;
-
- @Mock
- private ShardingSphereSchema schema;
-
- @Mock
- private EncryptRule encryptRule;
-
- @Mock
- private SelectStatementContext selectStatementContext;
-
- @Mock
- private TablesContext tablesContext;
-
- @Mock
- private ColumnProjection columnProjection;
-
- @Mock
- private ProjectionsContext projectionsContext;
-
- @BeforeEach
- void setUp() {
- when(selectStatementContext.getProjectionsContext()).thenReturn(projectionsContext);
- when(projectionsContext.getExpandProjections()).thenReturn(Collections.singletonList(columnProjection));
- when(columnProjection.getName()).thenReturn("id");
- when(columnProjection.getExpression()).thenReturn("id");
- when(selectStatementContext.getTablesContext()).thenReturn(tablesContext);
- when(selectStatementContext.getDatabaseType()).thenReturn(new MySQLDatabaseType());
- when(database.getName()).thenReturn(DefaultDatabase.LOGIC_NAME);
- when(database.getSchema(DefaultDatabase.LOGIC_NAME)).thenReturn(schema);
- }
-
- @Test
- void assertFindEncryptContextByMetaData() {
- Map<String, String> columnTableNames = new HashMap<>();
- columnTableNames.put(columnProjection.getExpression(), "t_order");
- when(tablesContext.findTableNamesByColumnProjection(Collections.singletonList(columnProjection), schema)).thenReturn(columnTableNames);
- EncryptAlgorithmMetaData encryptAlgorithmMetaData = new EncryptAlgorithmMetaData(database, encryptRule, selectStatementContext);
- Optional<EncryptContext> actual = encryptAlgorithmMetaData.findEncryptContext(1);
- assertTrue(actual.isPresent());
- assertThat(actual.get().getDatabaseName(), is(DefaultDatabase.LOGIC_NAME));
- assertThat(actual.get().getTableName(), is("t_order"));
- assertThat(actual.get().getColumnName(), is("id"));
- }
-
- @Test
- void assertFindEncryptContextWhenSubqueryContainsEncryptColumn() {
- ColumnProjection columnProjection = new ColumnProjection(null, "user_name", null);
- Map<String, String> columnTableNames = new HashMap<>();
- columnTableNames.put(columnProjection.getExpression(), "t_user");
- when(projectionsContext.getExpandProjections())
- .thenReturn(Collections.singletonList(new SubqueryProjection("(SELECT user_name FROM t_user)", columnProjection, null, new MySQLDatabaseType())));
- when(tablesContext.findTableNamesByColumnProjection(Collections.singletonList(columnProjection), schema)).thenReturn(columnTableNames);
- EncryptAlgorithmMetaData encryptAlgorithmMetaData = new EncryptAlgorithmMetaData(database, encryptRule, selectStatementContext);
- Optional<EncryptContext> actual = encryptAlgorithmMetaData.findEncryptContext(1);
- assertTrue(actual.isPresent());
- assertThat(actual.get().getDatabaseName(), is(DefaultDatabase.LOGIC_NAME));
- assertThat(actual.get().getTableName(), is("t_user"));
- assertThat(actual.get().getColumnName(), is("user_name"));
- }
-
- @Test
- void assertFindEncryptContextByStatementContext() {
- when(tablesContext.findTableNamesByColumnProjection(Collections.singletonList(columnProjection), schema)).thenReturn(Collections.emptyMap());
- when(tablesContext.getTableNames()).thenReturn(Arrays.asList("t_user", "t_user_item", "t_order_item"));
- EncryptTable encryptTable = mock(EncryptTable.class);
- when(encryptTable.isEncryptColumn("id")).thenReturn(true);
- when(encryptRule.findEncryptTable("t_order_item")).thenReturn(Optional.of(encryptTable));
- EncryptAlgorithmMetaData encryptAlgorithmMetaData = new EncryptAlgorithmMetaData(database, encryptRule, selectStatementContext);
- Optional<EncryptContext> actual = encryptAlgorithmMetaData.findEncryptContext(1);
- assertTrue(actual.isPresent());
- assertThat(actual.get().getDatabaseName(), is(DefaultDatabase.LOGIC_NAME));
- assertThat(actual.get().getTableName(), is("t_order_item"));
- assertThat(actual.get().getColumnName(), is("id"));
- }
-
- @Test
- void assertFindEncryptContextWhenColumnProjectionIsNotExist() {
- when(projectionsContext.getExpandProjections()).thenReturn(Collections.singletonList(mock(DerivedProjection.class)));
- EncryptAlgorithmMetaData encryptAlgorithmMetaData = new EncryptAlgorithmMetaData(database, encryptRule, selectStatementContext);
- Optional<EncryptContext> actual = encryptAlgorithmMetaData.findEncryptContext(1);
- assertFalse(actual.isPresent());
- }
-}
diff --git a/features/encrypt/core/src/test/java/org/apache/shardingsphere/encrypt/merge/dql/EncryptMergedResultTest.java b/features/encrypt/core/src/test/java/org/apache/shardingsphere/encrypt/merge/dql/EncryptMergedResultTest.java
index 34124e20248..10a351de55c 100644
--- a/features/encrypt/core/src/test/java/org/apache/shardingsphere/encrypt/merge/dql/EncryptMergedResultTest.java
+++ b/features/encrypt/core/src/test/java/org/apache/shardingsphere/encrypt/merge/dql/EncryptMergedResultTest.java
@@ -28,7 +28,6 @@ import java.io.Reader;
import java.sql.SQLException;
import java.util.Calendar;
import java.util.Date;
-import java.util.Optional;
import static org.hamcrest.CoreMatchers.is;
import static org.hamcrest.MatcherAssert.assertThat;
@@ -50,13 +49,6 @@ class EncryptMergedResultTest {
assertFalse(new EncryptMergedResult(metaData, mergedResult).next());
}
- @Test
- void assertGetValueWithoutEncryptContext() throws SQLException {
- when(mergedResult.getValue(1, String.class)).thenReturn("VALUE");
- when(metaData.findEncryptContext(1)).thenReturn(Optional.empty());
- assertThat(new EncryptMergedResult(metaData, mergedResult).getValue(1, String.class), is("VALUE"));
- }
-
@Test
void assertGetCalendarValue() throws SQLException {
Calendar calendar = Calendar.getInstance();
diff --git a/infra/binder/src/main/java/org/apache/shardingsphere/infra/binder/statement/dml/SelectStatementContext.java b/infra/binder/src/main/java/org/apache/shardingsphere/infra/binder/statement/dml/SelectStatementContext.java
index e585d77c79e..4ba638f4699 100644
--- a/infra/binder/src/main/java/org/apache/shardingsphere/infra/binder/statement/dml/SelectStatementContext.java
+++ b/infra/binder/src/main/java/org/apache/shardingsphere/infra/binder/statement/dml/SelectStatementContext.java
@@ -37,6 +37,7 @@ import org.apache.shardingsphere.infra.binder.segment.select.projection.impl.Agg
import org.apache.shardingsphere.infra.binder.segment.select.projection.impl.AggregationProjection;
import org.apache.shardingsphere.infra.binder.segment.select.projection.impl.ColumnProjection;
import org.apache.shardingsphere.infra.binder.segment.select.projection.impl.ParameterMarkerProjection;
+import org.apache.shardingsphere.infra.binder.segment.select.projection.impl.SubqueryProjection;
import org.apache.shardingsphere.infra.binder.segment.table.TablesContext;
import org.apache.shardingsphere.infra.binder.statement.CommonSQLStatementContext;
import org.apache.shardingsphere.infra.binder.type.TableAvailable;
@@ -323,6 +324,27 @@ public final class SelectStatementContext extends CommonSQLStatementContext impl
return !groupByContext.getItems().isEmpty() && groupByContext.getItems().equals(orderByContext.getItems());
}
+ /**
+ * Find column projection.
+ *
+ * @param columnIndex column index
+ * @return find column projection
+ */
+ public Optional<ColumnProjection> findColumnProjection(final int columnIndex) {
+ List<Projection> expandProjections = projectionsContext.getExpandProjections();
+ if (expandProjections.size() < columnIndex) {
+ return Optional.empty();
+ }
+ Projection projection = expandProjections.get(columnIndex - 1);
+ if (projection instanceof ColumnProjection) {
+ return Optional.of((ColumnProjection) projection);
+ }
+ if (projection instanceof SubqueryProjection && ((SubqueryProjection) projection).getProjection() instanceof ColumnProjection) {
+ return Optional.of((ColumnProjection) ((SubqueryProjection) projection).getProjection());
+ }
+ return Optional.empty();
+ }
+
@Override
public SelectStatement getSqlStatement() {
return (SelectStatement) super.getSqlStatement();