You are viewing a plain text version of this content. The canonical link for it is here.
Posted to notifications@shardingsphere.apache.org by zh...@apache.org on 2022/07/26 03:21:55 UTC
[shardingsphere] branch master updated: Support encrypt column rewrite when execute column is null in predicate (#19543)
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 7a1d8ce8d2e Support encrypt column rewrite when execute column is null in predicate (#19543)
7a1d8ce8d2e is described below
commit 7a1d8ce8d2e893dd3ff52490ecb6d366eba7a4cf
Author: Zhengqiang Duan <du...@apache.org>
AuthorDate: Tue Jul 26 11:21:46 2022 +0800
Support encrypt column rewrite when execute column is null in predicate (#19543)
---
.../rewrite/condition/EncryptConditionEngine.java | 21 ++++++++++++++++-
.../generator/EncryptAssignmentTokenGenerator.java | 6 ++---
.../EncryptInsertValuesTokenGenerator.java | 2 +-
.../EncryptOrderByItemTokenGenerator.java | 8 +++----
.../generator/InsertCipherNameTokenGenerator.java | 2 +-
.../sql/common/util/ExpressionExtractUtil.java | 27 +---------------------
.../case/query-with-cipher/dml/update/update.xml | 8 +++----
7 files changed, 33 insertions(+), 41 deletions(-)
diff --git a/shardingsphere-features/shardingsphere-encrypt/shardingsphere-encrypt-core/src/main/java/org/apache/shardingsphere/encrypt/rewrite/condition/EncryptConditionEngine.java b/shardingsphere-features/shardingsphere-encrypt/shardingsphere-encrypt-core/src/main/java/org/apache/shardingsphere/encrypt/rewrite/condition/EncryptConditionEngine.java
index f7ede9ab31d..3047c2d99b8 100644
--- a/shardingsphere-features/shardingsphere-encrypt/shardingsphere-encrypt-core/src/main/java/org/apache/shardingsphere/encrypt/rewrite/condition/EncryptConditionEngine.java
+++ b/shardingsphere-features/shardingsphere-encrypt/shardingsphere-encrypt-core/src/main/java/org/apache/shardingsphere/encrypt/rewrite/condition/EncryptConditionEngine.java
@@ -31,6 +31,7 @@ import org.apache.shardingsphere.sql.parser.sql.common.segment.dml.expr.BetweenE
import org.apache.shardingsphere.sql.parser.sql.common.segment.dml.expr.BinaryOperationExpression;
import org.apache.shardingsphere.sql.parser.sql.common.segment.dml.expr.ExpressionSegment;
import org.apache.shardingsphere.sql.parser.sql.common.segment.dml.expr.InExpression;
+import org.apache.shardingsphere.sql.parser.sql.common.segment.dml.expr.simple.LiteralExpressionSegment;
import org.apache.shardingsphere.sql.parser.sql.common.segment.dml.expr.simple.SimpleExpressionSegment;
import org.apache.shardingsphere.sql.parser.sql.common.segment.dml.expr.subquery.SubqueryExpressionSegment;
import org.apache.shardingsphere.sql.parser.sql.common.segment.dml.predicate.AndPredicate;
@@ -110,7 +111,7 @@ public final class EncryptConditionEngine {
}
private void addEncryptConditions(final Collection<EncryptCondition> encryptConditions, final ExpressionSegment expression, final Map<String, String> expressionTableNames) {
- if (!ExpressionExtractUtil.findNotContainsNullLiteralsExpression(expression).isPresent()) {
+ if (!findNotContainsNullLiteralsExpression(expression).isPresent()) {
return;
}
for (ColumnSegment each : ColumnExtractor.extract(expression)) {
@@ -121,6 +122,24 @@ public final class EncryptConditionEngine {
}
}
+ private Optional<ExpressionSegment> findNotContainsNullLiteralsExpression(final ExpressionSegment expression) {
+ if (isContainsNullLiterals(expression)) {
+ return Optional.empty();
+ }
+ if (expression instanceof BinaryOperationExpression && isContainsNullLiterals(((BinaryOperationExpression) expression).getRight())) {
+ return Optional.empty();
+ }
+ return Optional.ofNullable(expression);
+ }
+
+ private boolean isContainsNullLiterals(final ExpressionSegment expression) {
+ if (!(expression instanceof LiteralExpressionSegment)) {
+ return false;
+ }
+ String literals = String.valueOf(((LiteralExpressionSegment) expression).getLiterals());
+ return "NULL".equalsIgnoreCase(literals) || "NOT NULL".equalsIgnoreCase(literals);
+ }
+
private Optional<EncryptCondition> createEncryptCondition(final ExpressionSegment expression, final String tableName) {
if (expression instanceof BinaryOperationExpression) {
return createBinaryEncryptCondition((BinaryOperationExpression) expression, tableName);
diff --git a/shardingsphere-features/shardingsphere-encrypt/shardingsphere-encrypt-core/src/main/java/org/apache/shardingsphere/encrypt/rewrite/token/generator/EncryptAssignmentTokenGenerator.java b/shardingsphere-features/shardingsphere-encrypt/shardingsphere-encrypt-core/src/main/java/org/apache/shardingsphere/encrypt/rewrite/token/generator/EncryptAssignmentTokenGenerator.java
index 3b974ab477e..e61bcf167df 100644
--- a/shardingsphere-features/shardingsphere-encrypt/shardingsphere-encrypt-core/src/main/java/org/apache/shardingsphere/encrypt/rewrite/token/generator/EncryptAssignmentTokenGenerator.java
+++ b/shardingsphere-features/shardingsphere-encrypt/shardingsphere-encrypt-core/src/main/java/org/apache/shardingsphere/encrypt/rewrite/token/generator/EncryptAssignmentTokenGenerator.java
@@ -49,20 +49,20 @@ import java.util.Optional;
* Assignment generator for encrypt.
*/
@Setter
-public final class EncryptAssignmentTokenGenerator implements CollectionSQLTokenGenerator, EncryptRuleAware, DatabaseNameAware {
+public final class EncryptAssignmentTokenGenerator implements CollectionSQLTokenGenerator<SQLStatementContext<?>>, EncryptRuleAware, DatabaseNameAware {
private EncryptRule encryptRule;
private String databaseName;
@Override
- public boolean isGenerateSQLToken(final SQLStatementContext sqlStatementContext) {
+ public boolean isGenerateSQLToken(final SQLStatementContext<?> sqlStatementContext) {
return sqlStatementContext instanceof UpdateStatementContext || (sqlStatementContext instanceof InsertStatementContext
&& InsertStatementHandler.getSetAssignmentSegment(((InsertStatementContext) sqlStatementContext).getSqlStatement()).isPresent());
}
@Override
- public Collection<EncryptAssignmentToken> generateSQLTokens(final SQLStatementContext sqlStatementContext) {
+ public Collection<EncryptAssignmentToken> generateSQLTokens(final SQLStatementContext<?> sqlStatementContext) {
Collection<EncryptAssignmentToken> result = new LinkedList<>();
String tableName = ((TableAvailable) sqlStatementContext).getAllTables().iterator().next().getTableName().getIdentifier().getValue();
String schemaName = sqlStatementContext.getTablesContext().getSchemaName().orElseGet(() -> DatabaseTypeEngine.getDefaultSchemaName(sqlStatementContext.getDatabaseType(), databaseName));
diff --git a/shardingsphere-features/shardingsphere-encrypt/shardingsphere-encrypt-core/src/main/java/org/apache/shardingsphere/encrypt/rewrite/token/generator/EncryptInsertValuesTokenGenerator.java b/shardingsphere-features/shardingsphere-encrypt/shardingsphere-encrypt-core/src/main/java/org/apache/shardingsphere/encrypt/rewrite/token/generator/EncryptInsertValuesTokenGenerator.java
index 24a6f37bdda..1add58f9048 100644
--- a/shardingsphere-features/shardingsphere-encrypt/shardingsphere-encrypt-core/src/main/java/org/apache/shardingsphere/encrypt/rewrite/token/generator/EncryptInsertValuesTokenGenerator.java
+++ b/shardingsphere-features/shardingsphere-encrypt/shardingsphere-encrypt-core/src/main/java/org/apache/shardingsphere/encrypt/rewrite/token/generator/EncryptInsertValuesTokenGenerator.java
@@ -62,7 +62,7 @@ public final class EncryptInsertValuesTokenGenerator implements OptionalSQLToken
private String databaseName;
@Override
- public boolean isGenerateSQLToken(final SQLStatementContext sqlStatementContext) {
+ public boolean isGenerateSQLToken(final SQLStatementContext<?> sqlStatementContext) {
return sqlStatementContext instanceof InsertStatementContext && !(((InsertStatementContext) sqlStatementContext).getSqlStatement()).getValues().isEmpty();
}
diff --git a/shardingsphere-features/shardingsphere-encrypt/shardingsphere-encrypt-core/src/main/java/org/apache/shardingsphere/encrypt/rewrite/token/generator/EncryptOrderByItemTokenGenerator.java b/shardingsphere-features/shardingsphere-encrypt/shardingsphere-encrypt-core/src/main/java/org/apache/shardingsphere/encrypt/rewrite/token/generator/EncryptOrderByItemTokenGenerator.java
index be125265ba9..c21a0330f29 100644
--- a/shardingsphere-features/shardingsphere-encrypt/shardingsphere-encrypt-core/src/main/java/org/apache/shardingsphere/encrypt/rewrite/token/generator/EncryptOrderByItemTokenGenerator.java
+++ b/shardingsphere-features/shardingsphere-encrypt/shardingsphere-encrypt-core/src/main/java/org/apache/shardingsphere/encrypt/rewrite/token/generator/EncryptOrderByItemTokenGenerator.java
@@ -44,7 +44,7 @@ import java.util.Optional;
* Order by item token generator for encrypt.
*/
@Setter
-public final class EncryptOrderByItemTokenGenerator implements CollectionSQLTokenGenerator, SchemaMetaDataAware, EncryptRuleAware {
+public final class EncryptOrderByItemTokenGenerator implements CollectionSQLTokenGenerator<SQLStatementContext<?>>, SchemaMetaDataAware, EncryptRuleAware {
private String databaseName;
@@ -52,15 +52,13 @@ public final class EncryptOrderByItemTokenGenerator implements CollectionSQLToke
private EncryptRule encryptRule;
- @SuppressWarnings("rawtypes")
@Override
- public boolean isGenerateSQLToken(final SQLStatementContext sqlStatementContext) {
+ public boolean isGenerateSQLToken(final SQLStatementContext<?> sqlStatementContext) {
return sqlStatementContext instanceof SelectStatementContext && containsOrderByItem(sqlStatementContext);
}
- @SuppressWarnings("rawtypes")
@Override
- public Collection<SubstitutableColumnNameToken> generateSQLTokens(final SQLStatementContext sqlStatementContext) {
+ public Collection<SubstitutableColumnNameToken> generateSQLTokens(final SQLStatementContext<?> sqlStatementContext) {
Collection<SubstitutableColumnNameToken> result = new LinkedHashSet<>();
String defaultSchema = DatabaseTypeEngine.getDefaultSchemaName(sqlStatementContext.getDatabaseType(), databaseName);
ShardingSphereSchema schema = sqlStatementContext.getTablesContext().getSchemaName().map(schemas::get).orElseGet(() -> schemas.get(defaultSchema));
diff --git a/shardingsphere-features/shardingsphere-encrypt/shardingsphere-encrypt-core/src/main/java/org/apache/shardingsphere/encrypt/rewrite/token/generator/InsertCipherNameTokenGenerator.java b/shardingsphere-features/shardingsphere-encrypt/shardingsphere-encrypt-core/src/main/java/org/apache/shardingsphere/encrypt/rewrite/token/generator/InsertCipherNameTokenGenerator.java
index ffc36f5d2ae..586a616fdf0 100644
--- a/shardingsphere-features/shardingsphere-encrypt/shardingsphere-encrypt-core/src/main/java/org/apache/shardingsphere/encrypt/rewrite/token/generator/InsertCipherNameTokenGenerator.java
+++ b/shardingsphere-features/shardingsphere-encrypt/shardingsphere-encrypt-core/src/main/java/org/apache/shardingsphere/encrypt/rewrite/token/generator/InsertCipherNameTokenGenerator.java
@@ -44,7 +44,7 @@ public final class InsertCipherNameTokenGenerator implements CollectionSQLTokenG
private EncryptRule encryptRule;
@Override
- public boolean isGenerateSQLToken(final SQLStatementContext sqlStatementContext) {
+ public boolean isGenerateSQLToken(final SQLStatementContext<?> sqlStatementContext) {
if (!(sqlStatementContext instanceof InsertStatementContext)) {
return false;
}
diff --git a/shardingsphere-sql-parser/shardingsphere-sql-parser-statement/src/main/java/org/apache/shardingsphere/sql/parser/sql/common/util/ExpressionExtractUtil.java b/shardingsphere-sql-parser/shardingsphere-sql-parser-statement/src/main/java/org/apache/shardingsphere/sql/parser/sql/common/util/ExpressionExtractUtil.java
index fb48d46e18a..16630d75371 100644
--- a/shardingsphere-sql-parser/shardingsphere-sql-parser-statement/src/main/java/org/apache/shardingsphere/sql/parser/sql/common/util/ExpressionExtractUtil.java
+++ b/shardingsphere-sql-parser/shardingsphere-sql-parser-statement/src/main/java/org/apache/shardingsphere/sql/parser/sql/common/util/ExpressionExtractUtil.java
@@ -23,7 +23,6 @@ import org.apache.shardingsphere.sql.parser.sql.common.constant.LogicalOperator;
import org.apache.shardingsphere.sql.parser.sql.common.segment.dml.expr.BinaryOperationExpression;
import org.apache.shardingsphere.sql.parser.sql.common.segment.dml.expr.ExpressionSegment;
import org.apache.shardingsphere.sql.parser.sql.common.segment.dml.expr.FunctionSegment;
-import org.apache.shardingsphere.sql.parser.sql.common.segment.dml.expr.simple.LiteralExpressionSegment;
import org.apache.shardingsphere.sql.parser.sql.common.segment.dml.expr.simple.ParameterMarkerExpressionSegment;
import org.apache.shardingsphere.sql.parser.sql.common.segment.dml.predicate.AndPredicate;
@@ -83,34 +82,10 @@ public final class ExpressionExtractUtil {
private static AndPredicate createAndPredicate(final ExpressionSegment expression) {
AndPredicate result = new AndPredicate();
- findNotContainsNullLiteralsExpression(expression).ifPresent(optional -> result.getPredicates().add(optional));
+ result.getPredicates().add(expression);
return result;
}
- /**
- * Find not contains null literals expression.
- *
- * @param expression ExpressionSegment
- * @return expression which not contains null literals
- */
- public static Optional<ExpressionSegment> findNotContainsNullLiteralsExpression(final ExpressionSegment expression) {
- if (isContainsNullLiterals(expression)) {
- return Optional.empty();
- }
- if (expression instanceof BinaryOperationExpression && isContainsNullLiterals(((BinaryOperationExpression) expression).getRight())) {
- return Optional.empty();
- }
- return Optional.ofNullable(expression);
- }
-
- private static boolean isContainsNullLiterals(final ExpressionSegment expression) {
- if (!(expression instanceof LiteralExpressionSegment)) {
- return false;
- }
- String literals = String.valueOf(((LiteralExpressionSegment) expression).getLiterals());
- return "NULL".equalsIgnoreCase(literals) || "NOT NULL".equalsIgnoreCase(literals);
- }
-
/**
* Get parameter marker expression collection.
*
diff --git a/shardingsphere-test/shardingsphere-rewrite-test/src/test/resources/scenario/encrypt/case/query-with-cipher/dml/update/update.xml b/shardingsphere-test/shardingsphere-rewrite-test/src/test/resources/scenario/encrypt/case/query-with-cipher/dml/update/update.xml
index 45a69c9926c..fe99df8c154 100644
--- a/shardingsphere-test/shardingsphere-rewrite-test/src/test/resources/scenario/encrypt/case/query-with-cipher/dml/update/update.xml
+++ b/shardingsphere-test/shardingsphere-rewrite-test/src/test/resources/scenario/encrypt/case/query-with-cipher/dml/update/update.xml
@@ -76,21 +76,21 @@
<rewrite-assertion id="update_null_to_clear_plain_where_is_null" db-types="MySQL">
<input sql="UPDATE t_account_bak SET certificate_number = NULL WHERE certificate_number IS NULL" />
- <output sql="UPDATE t_account_bak SET certificate_number = NULL WHERE certificate_number IS NULL" />
+ <output sql="UPDATE t_account_bak SET certificate_number = NULL WHERE assisted_query_certificate_number IS NULL" />
</rewrite-assertion>
<rewrite-assertion id="update_null_to_clear_plain_where_is_null_with_multi" db-types="MySQL">
<input sql="UPDATE t_account_bak SET certificate_number = NULL WHERE certificate_number IS NULL AND status = 'OK' AND certificate_number = '111X'" />
- <output sql="UPDATE t_account_bak SET certificate_number = NULL WHERE certificate_number IS NULL AND status = 'OK' AND assisted_query_certificate_number = 'assisted_query_111X'" />
+ <output sql="UPDATE t_account_bak SET certificate_number = NULL WHERE assisted_query_certificate_number IS NULL AND status = 'OK' AND assisted_query_certificate_number = 'assisted_query_111X'" />
</rewrite-assertion>
<rewrite-assertion id="update_null_to_clear_plain_where_is_not_null" db-types="MySQL">
<input sql="UPDATE t_account_bak SET certificate_number = NULL WHERE certificate_number IS NOT NULL" />
- <output sql="UPDATE t_account_bak SET certificate_number = NULL WHERE certificate_number IS NOT NULL" />
+ <output sql="UPDATE t_account_bak SET certificate_number = NULL WHERE assisted_query_certificate_number IS NOT NULL" />
</rewrite-assertion>
<rewrite-assertion id="update_null_to_clear_plain_where_is_not_null_with_multi" db-types="MySQL">
<input sql="UPDATE t_account_bak SET certificate_number = NULL WHERE certificate_number IS NOT NULL AND status = 'OK' AND certificate_number = '111X'" />
- <output sql="UPDATE t_account_bak SET certificate_number = NULL WHERE certificate_number IS NOT NULL AND status = 'OK' AND assisted_query_certificate_number = 'assisted_query_111X'" />
+ <output sql="UPDATE t_account_bak SET certificate_number = NULL WHERE assisted_query_certificate_number IS NOT NULL AND status = 'OK' AND assisted_query_certificate_number = 'assisted_query_111X'" />
</rewrite-assertion>
</rewrite-assertions>