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 e3d669df5eb Refactor insert on duplicate key update parameter rewriter
for encrypt (#37275)
e3d669df5eb is described below
commit e3d669df5ebc9f9ea0301a5de3e2034d1b336b69
Author: ZhangCheng <[email protected]>
AuthorDate: Thu Dec 4 12:53:00 2025 +0800
Refactor insert on duplicate key update parameter rewriter for encrypt
(#37275)
* Refactor insert on duplicate key update parameter rewriter for encrypt
* Refactor insert on duplicate key update parameter rewriter for encrypt
---
...OnDuplicateKeyUpdateValueParameterRewriter.java | 29 +++++++++++++++-------
.../dml/insert/insert-on-duplicate.xml | 6 ++---
2 files changed, 23 insertions(+), 12 deletions(-)
diff --git
a/features/encrypt/core/src/main/java/org/apache/shardingsphere/encrypt/rewrite/parameter/rewriter/EncryptInsertOnDuplicateKeyUpdateValueParameterRewriter.java
b/features/encrypt/core/src/main/java/org/apache/shardingsphere/encrypt/rewrite/parameter/rewriter/EncryptInsertOnDuplicateKeyUpdateValueParameterRewriter.java
index 91ef132f69c..5dbdca47190 100644
---
a/features/encrypt/core/src/main/java/org/apache/shardingsphere/encrypt/rewrite/parameter/rewriter/EncryptInsertOnDuplicateKeyUpdateValueParameterRewriter.java
+++
b/features/encrypt/core/src/main/java/org/apache/shardingsphere/encrypt/rewrite/parameter/rewriter/EncryptInsertOnDuplicateKeyUpdateValueParameterRewriter.java
@@ -26,8 +26,10 @@ import
org.apache.shardingsphere.infra.binder.context.statement.SQLStatementCont
import
org.apache.shardingsphere.infra.binder.context.statement.type.dml.InsertStatementContext;
import
org.apache.shardingsphere.infra.rewrite.parameter.builder.ParameterBuilder;
import
org.apache.shardingsphere.infra.rewrite.parameter.builder.impl.GroupedParameterBuilder;
+import
org.apache.shardingsphere.infra.rewrite.parameter.builder.impl.StandardParameterBuilder;
import
org.apache.shardingsphere.infra.rewrite.parameter.rewriter.ParameterRewriter;
-import
org.apache.shardingsphere.sql.parser.statement.core.segment.dml.expr.FunctionSegment;
+import
org.apache.shardingsphere.sql.parser.statement.core.segment.dml.expr.ExpressionSegment;
+import
org.apache.shardingsphere.sql.parser.statement.core.segment.dml.expr.simple.ParameterMarkerExpressionSegment;
import java.util.Collection;
import java.util.LinkedList;
@@ -53,32 +55,41 @@ public final class
EncryptInsertOnDuplicateKeyUpdateValueParameterRewriter imple
public void rewrite(final ParameterBuilder paramBuilder, final
SQLStatementContext sqlStatementContext, final List<Object> params) {
InsertStatementContext insertStatementContext =
(InsertStatementContext) sqlStatementContext;
String tableName =
insertStatementContext.getSqlStatement().getTable().map(optional ->
optional.getTableName().getIdentifier().getValue()).orElse("");
- GroupedParameterBuilder groupedParamBuilder =
(GroupedParameterBuilder) paramBuilder;
+ StandardParameterBuilder standardParamBuilder = paramBuilder
instanceof StandardParameterBuilder
+ ? (StandardParameterBuilder) paramBuilder
+ : ((GroupedParameterBuilder)
paramBuilder).getAfterGenericParameterBuilder();
OnDuplicateUpdateContext onDuplicateKeyUpdateValueContext =
insertStatementContext.getOnDuplicateKeyUpdateValueContext();
String schemaName =
insertStatementContext.getTablesContext().getSchemaName()
.orElseGet(() -> new
DatabaseTypeRegistry(insertStatementContext.getSqlStatement().getDatabaseType()).getDefaultSchemaName(databaseName));
+ int onDuplicateKeyParameterMarkerIndex = 0;
for (int index = 0; index <
onDuplicateKeyUpdateValueContext.getValueExpressions().size(); index++) {
String logicColumnName =
onDuplicateKeyUpdateValueContext.getColumn(index).getIdentifier().getValue();
if (!rule.findEncryptTable(tableName).map(optional ->
optional.isEncryptColumn(logicColumnName)).orElse(false)) {
continue;
}
- Object plainValue =
onDuplicateKeyUpdateValueContext.getValue(index);
- if (plainValue instanceof FunctionSegment &&
"VALUES".equalsIgnoreCase(((FunctionSegment) plainValue).getFunctionName())) {
- return;
+ ExpressionSegment valueExpression =
onDuplicateKeyUpdateValueContext.getValueExpressions().get(index);
+ if (!(valueExpression instanceof
ParameterMarkerExpressionSegment)) {
+ continue;
}
+ int parameterIndex = getParameterMarkerIndex(paramBuilder,
(ParameterMarkerExpressionSegment) valueExpression,
onDuplicateKeyParameterMarkerIndex++);
+ Object plainValue =
onDuplicateKeyUpdateValueContext.getValue(index);
EncryptColumn encryptColumn =
rule.getEncryptTable(tableName).getEncryptColumn(logicColumnName);
Object cipherColumnValue =
encryptColumn.getCipher().encrypt(databaseName, schemaName, tableName,
logicColumnName, plainValue);
-
groupedParamBuilder.getAfterGenericParameterBuilder().addReplacedParameters(index,
cipherColumnValue);
+ standardParamBuilder.addReplacedParameters(parameterIndex,
cipherColumnValue);
Collection<Object> addedParams = buildAddedParams(schemaName,
tableName, encryptColumn, logicColumnName, plainValue);
if (!addedParams.isEmpty()) {
- if
(!groupedParamBuilder.getAfterGenericParameterBuilder().getAddedIndexAndParameters().containsKey(index))
{
-
groupedParamBuilder.getAfterGenericParameterBuilder().getAddedIndexAndParameters().put(index,
new LinkedList<>());
+ if
(!standardParamBuilder.getAddedIndexAndParameters().containsKey(parameterIndex))
{
+
standardParamBuilder.getAddedIndexAndParameters().put(parameterIndex, new
LinkedList<>());
}
-
groupedParamBuilder.getAfterGenericParameterBuilder().getAddedIndexAndParameters().get(index).addAll(addedParams);
+
standardParamBuilder.getAddedIndexAndParameters().get(parameterIndex).addAll(addedParams);
}
}
}
+ private int getParameterMarkerIndex(final ParameterBuilder paramBuilder,
final ParameterMarkerExpressionSegment paramMarkerExpression, final int index) {
+ return paramBuilder instanceof StandardParameterBuilder ?
paramMarkerExpression.getParameterMarkerIndex() : index;
+ }
+
private Collection<Object> buildAddedParams(final String schemaName, final
String tableName, final EncryptColumn encryptColumn, final String
logicColumnName, final Object plainValue) {
Collection<Object> result = new LinkedList<>();
if (encryptColumn.getAssistedQuery().isPresent()) {
diff --git
a/test/it/rewriter/src/test/resources/scenario/encrypt/case/query-with-cipher/dml/insert/insert-on-duplicate.xml
b/test/it/rewriter/src/test/resources/scenario/encrypt/case/query-with-cipher/dml/insert/insert-on-duplicate.xml
index 304ecb7b490..d1359ea2005 100644
---
a/test/it/rewriter/src/test/resources/scenario/encrypt/case/query-with-cipher/dml/insert/insert-on-duplicate.xml
+++
b/test/it/rewriter/src/test/resources/scenario/encrypt/case/query-with-cipher/dml/insert/insert-on-duplicate.xml
@@ -18,10 +18,10 @@
<rewrite-assertions yaml-rule="scenario/encrypt/config/query-with-cipher.yaml">
<rewrite-assertion
id="insert_values_on_duplicated_update_values_for_parameters" db-types="MySQL">
- <input sql="INSERT INTO t_account(account_id, certificate_number,
password, amount, status) VALUES (?, ?, ?, ?, ?) ON DUPLICATE KEY UPDATE
certificate_number = VALUES(certificate_number)" parameters="1, 111X, aaa,
1000, OK" />
- <output sql="INSERT INTO t_account(account_id,
`cipher_certificate_number`, `assisted_query_certificate_number`,
`like_query_certificate_number`, `cipher_password`, `assisted_query_password`,
`like_query_password`, `cipher_amount`, status) VALUES (?, ?, ?, ?, ?, ?, ?, ?,
?) ON DUPLICATE KEY UPDATE `cipher_certificate_number` =
VALUES(cipher_certificate_number), `assisted_query_certificate_number` =
VALUES(assisted_query_certificate_number), `like_query_certificate_number` =
VALUE [...]
+ <input sql="INSERT INTO t_account(account_id, certificate_number,
password, amount, status) VALUES (?, ?, ?, ?, ?) ON DUPLICATE KEY UPDATE
certificate_number = VALUES(certificate_number), password = ?, amount = ?,
status = VALUES(status)" parameters="1, 111X, aaa, 1000, OK, aaa, 100" />
+ <output sql="INSERT INTO t_account(account_id,
`cipher_certificate_number`, `assisted_query_certificate_number`,
`like_query_certificate_number`, `cipher_password`, `assisted_query_password`,
`like_query_password`, `cipher_amount`, status) VALUES (?, ?, ?, ?, ?, ?, ?, ?,
?) ON DUPLICATE KEY UPDATE `cipher_certificate_number` =
VALUES(cipher_certificate_number), `assisted_query_certificate_number` =
VALUES(assisted_query_certificate_number), `like_query_certificate_number` =
VALUE [...]
</rewrite-assertion>
-
+
<rewrite-assertion
id="insert_values_on_duplicated_update_values_for_literals" db-types="MySQL">
<input sql="INSERT INTO t_account(account_id, certificate_number,
password, amount, status) VALUES (1, '111X', 'aaa', '1000', 'OK') ON DUPLICATE
KEY UPDATE certificate_number = VALUES(certificate_number)" />
<output sql="INSERT INTO t_account(account_id,
`cipher_certificate_number`, `assisted_query_certificate_number`,
`like_query_certificate_number`, `cipher_password`, `assisted_query_password`,
`like_query_password`, `cipher_amount`, status) VALUES (1, 'encrypt_111X',
'assisted_query_111X', 'like_query_111X', 'encrypt_aaa', 'assisted_query_aaa',
'like_query_aaa', 'encrypt_1000', 'OK') ON DUPLICATE KEY UPDATE
`cipher_certificate_number` = VALUES(cipher_certificate_number), `assisted [...]