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

zhaojinchao 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 05d5a9b9249 Support encrypt insert select sql rewrite (#28425)
05d5a9b9249 is described below

commit 05d5a9b9249b2212c8a6126d0647fa7706f72576
Author: Zhengqiang Duan <[email protected]>
AuthorDate: Wed Sep 13 10:09:52 2023 +0800

    Support encrypt insert select sql rewrite (#28425)
---
 .../generator/EncryptProjectionTokenGenerator.java | 38 +++++++++++++++++-----
 .../statement/dml/InsertStatementContext.java      |  8 +++--
 2 files changed, 35 insertions(+), 11 deletions(-)

diff --git 
a/features/encrypt/core/src/main/java/org/apache/shardingsphere/encrypt/rewrite/token/generator/EncryptProjectionTokenGenerator.java
 
b/features/encrypt/core/src/main/java/org/apache/shardingsphere/encrypt/rewrite/token/generator/EncryptProjectionTokenGenerator.java
index e4130989c71..bd05308a6ac 100644
--- 
a/features/encrypt/core/src/main/java/org/apache/shardingsphere/encrypt/rewrite/token/generator/EncryptProjectionTokenGenerator.java
+++ 
b/features/encrypt/core/src/main/java/org/apache/shardingsphere/encrypt/rewrite/token/generator/EncryptProjectionTokenGenerator.java
@@ -17,7 +17,6 @@
 
 package org.apache.shardingsphere.encrypt.rewrite.token.generator;
 
-import com.google.common.base.Preconditions;
 import lombok.Setter;
 import org.apache.shardingsphere.encrypt.rewrite.aware.DatabaseTypeAware;
 import org.apache.shardingsphere.encrypt.rewrite.aware.EncryptRuleAware;
@@ -30,6 +29,7 @@ import 
org.apache.shardingsphere.infra.binder.context.segment.select.projection.
 import 
org.apache.shardingsphere.infra.binder.context.segment.select.projection.impl.ColumnProjection;
 import 
org.apache.shardingsphere.infra.binder.context.segment.select.projection.impl.ShorthandProjection;
 import 
org.apache.shardingsphere.infra.binder.context.statement.SQLStatementContext;
+import 
org.apache.shardingsphere.infra.binder.context.statement.dml.InsertStatementContext;
 import 
org.apache.shardingsphere.infra.binder.context.statement.dml.SelectStatementContext;
 import 
org.apache.shardingsphere.infra.database.core.metadata.database.DialectDatabaseMetaData;
 import 
org.apache.shardingsphere.infra.database.core.metadata.database.enums.QuoteCharacter;
@@ -69,21 +69,28 @@ public final class EncryptProjectionTokenGenerator 
implements CollectionSQLToken
     
     @Override
     public boolean isGenerateSQLToken(final SQLStatementContext 
sqlStatementContext) {
-        return sqlStatementContext instanceof SelectStatementContext && 
!((SelectStatementContext) sqlStatementContext).getAllTables().isEmpty();
+        return sqlStatementContext instanceof SelectStatementContext && 
!((SelectStatementContext) sqlStatementContext).getAllTables().isEmpty()
+                || sqlStatementContext instanceof InsertStatementContext && 
null != ((InsertStatementContext) sqlStatementContext).getInsertSelectContext();
     }
     
     @Override
     public Collection<SQLToken> generateSQLTokens(final SQLStatementContext 
sqlStatementContext) {
-        Preconditions.checkState(sqlStatementContext instanceof 
SelectStatementContext);
         Collection<SQLToken> result = new LinkedHashSet<>();
-        SelectStatementContext selectStatementContext = 
(SelectStatementContext) sqlStatementContext;
-        addGenerateSQLTokens(result, selectStatementContext);
-        for (SelectStatementContext each : 
selectStatementContext.getSubqueryContexts().values()) {
-            addGenerateSQLTokens(result, each);
+        if (sqlStatementContext instanceof SelectStatementContext) {
+            generateSQLTokens((SelectStatementContext) sqlStatementContext, 
result);
+        } else if (sqlStatementContext instanceof InsertStatementContext && 
null != ((InsertStatementContext) 
sqlStatementContext).getInsertSelectContext()) {
+            generateSQLTokens(((InsertStatementContext) 
sqlStatementContext).getInsertSelectContext().getSelectStatementContext(), 
result);
         }
         return result;
     }
     
+    private void generateSQLTokens(final SelectStatementContext 
selectStatementContext, final Collection<SQLToken> sqlTokens) {
+        addGenerateSQLTokens(sqlTokens, selectStatementContext);
+        for (SelectStatementContext each : 
selectStatementContext.getSubqueryContexts().values()) {
+            addGenerateSQLTokens(sqlTokens, each);
+        }
+    }
+    
     private void addGenerateSQLTokens(final Collection<SQLToken> sqlTokens, 
final SelectStatementContext selectStatementContext) {
         for (ProjectionSegment each : 
selectStatementContext.getSqlStatement().getProjections().getProjections()) {
             SubqueryType subqueryType = 
selectStatementContext.getSubqueryType();
@@ -153,8 +160,11 @@ public final class EncryptProjectionTokenGenerator 
implements CollectionSQLToken
             return generateProjectionsInTableSegmentSubquery(encryptColumn, 
columnProjection, shorthandProjection, subqueryType);
         } else if (SubqueryType.PREDICATE_SUBQUERY == subqueryType) {
             return 
Collections.singleton(generateProjectionInPredicateSubquery(encryptColumn, 
columnProjection, shorthandProjection));
+        } else if (SubqueryType.INSERT_SELECT_SUBQUERY == subqueryType) {
+            return generateProjectionsInInsertSelectSubquery(encryptColumn, 
columnProjection, shorthandProjection);
         }
-        throw new UnsupportedSQLOperationException("Projections not in simple 
select, table subquery, join subquery and predicate subquery are not supported 
in encrypt feature.");
+        throw new UnsupportedSQLOperationException(
+                "Projections not in simple select, table subquery, join 
subquery, predicate subquery and insert select subquery are not supported in 
encrypt feature.");
     }
     
     private ColumnProjection generateProjection(final EncryptColumn 
encryptColumn, final ColumnProjection columnProjection, final boolean 
shorthandProjection) {
@@ -186,6 +196,18 @@ public final class EncryptProjectionTokenGenerator 
implements CollectionSQLToken
                         databaseType));
     }
     
+    private Collection<Projection> 
generateProjectionsInInsertSelectSubquery(final EncryptColumn encryptColumn, 
final ColumnProjection columnProjection, final boolean shorthandProjection) {
+        QuoteCharacter quoteCharacter = 
columnProjection.getName().getQuoteCharacter();
+        IdentifierValue columnName = new 
IdentifierValue(encryptColumn.getCipher().getName(), quoteCharacter);
+        Collection<Projection> result = new LinkedList<>();
+        IdentifierValue encryptColumnOwner = shorthandProjection ? 
columnProjection.getOwner().orElse(null) : null;
+        result.add(new ColumnProjection(encryptColumnOwner, columnName, null, 
databaseType));
+        IdentifierValue assistedColumOwner = 
columnProjection.getOwner().orElse(null);
+        encryptColumn.getAssistedQuery().ifPresent(optional -> result.add(new 
ColumnProjection(assistedColumOwner, new IdentifierValue(optional.getName(), 
quoteCharacter), null, databaseType)));
+        encryptColumn.getLikeQuery().ifPresent(optional -> result.add(new 
ColumnProjection(assistedColumOwner, new IdentifierValue(optional.getName(), 
quoteCharacter), null, databaseType)));
+        return result;
+    }
+    
     private ShorthandProjection getShorthandProjection(final 
ShorthandProjectionSegment segment, final ProjectionsContext 
projectionsContext) {
         Optional<String> owner = segment.getOwner().isPresent() ? 
Optional.of(segment.getOwner().get().getIdentifier().getValue()) : 
Optional.empty();
         for (Projection each : projectionsContext.getProjections()) {
diff --git 
a/infra/binder/src/main/java/org/apache/shardingsphere/infra/binder/context/statement/dml/InsertStatementContext.java
 
b/infra/binder/src/main/java/org/apache/shardingsphere/infra/binder/context/statement/dml/InsertStatementContext.java
index 56144c459bb..a7848404c7f 100644
--- 
a/infra/binder/src/main/java/org/apache/shardingsphere/infra/binder/context/statement/dml/InsertStatementContext.java
+++ 
b/infra/binder/src/main/java/org/apache/shardingsphere/infra/binder/context/statement/dml/InsertStatementContext.java
@@ -18,8 +18,6 @@
 package org.apache.shardingsphere.infra.binder.context.statement.dml;
 
 import lombok.Getter;
-import 
org.apache.shardingsphere.infra.exception.dialect.exception.syntax.database.NoDatabaseSelectedException;
-import 
org.apache.shardingsphere.infra.exception.dialect.exception.syntax.database.UnknownDatabaseException;
 import org.apache.shardingsphere.infra.binder.context.aware.ParameterAware;
 import 
org.apache.shardingsphere.infra.binder.context.segment.insert.keygen.GeneratedKeyContext;
 import 
org.apache.shardingsphere.infra.binder.context.segment.insert.keygen.engine.GeneratedKeyContextEngine;
@@ -30,10 +28,13 @@ import 
org.apache.shardingsphere.infra.binder.context.segment.table.TablesContex
 import 
org.apache.shardingsphere.infra.binder.context.statement.CommonSQLStatementContext;
 import org.apache.shardingsphere.infra.binder.context.type.TableAvailable;
 import org.apache.shardingsphere.infra.database.core.type.DatabaseTypeRegistry;
+import 
org.apache.shardingsphere.infra.exception.core.ShardingSpherePreconditions;
+import 
org.apache.shardingsphere.infra.exception.dialect.exception.syntax.database.NoDatabaseSelectedException;
+import 
org.apache.shardingsphere.infra.exception.dialect.exception.syntax.database.UnknownDatabaseException;
 import org.apache.shardingsphere.infra.metadata.ShardingSphereMetaData;
 import 
org.apache.shardingsphere.infra.metadata.database.ShardingSphereDatabase;
 import 
org.apache.shardingsphere.infra.metadata.database.schema.model.ShardingSphereSchema;
-import 
org.apache.shardingsphere.infra.exception.core.ShardingSpherePreconditions;
+import org.apache.shardingsphere.sql.parser.sql.common.enums.SubqueryType;
 import 
org.apache.shardingsphere.sql.parser.sql.common.extractor.TableExtractor;
 import 
org.apache.shardingsphere.sql.parser.sql.common.segment.dml.assignment.AssignmentSegment;
 import 
org.apache.shardingsphere.sql.parser.sql.common.segment.dml.assignment.InsertValuesSegment;
@@ -129,6 +130,7 @@ public final class InsertStatementContext extends 
CommonSQLStatementContext impl
         }
         SubquerySegment insertSelectSegment = 
getSqlStatement().getInsertSelect().get();
         SelectStatementContext selectStatementContext = new 
SelectStatementContext(metaData, params, insertSelectSegment.getSelect(), 
defaultDatabaseName);
+        
selectStatementContext.setSubqueryType(SubqueryType.INSERT_SELECT_SUBQUERY);
         InsertSelectContext insertSelectContext = new 
InsertSelectContext(selectStatementContext, params, paramsOffset.get());
         paramsOffset.addAndGet(insertSelectContext.getParameterCount());
         return Optional.of(insertSelectContext);

Reply via email to