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();