wangtiga opened a new issue, #25032:
URL: https://github.com/apache/shardingsphere/issues/25032
## Bug Report
In the encryption scenario of PostgreSQL, the LikeQueryColumn in the SQL
statement is misjudged as an AssistedQueryColumn. Here is the complete SQL:
```sql
-- Logic SQL:
SELECT account_id, password, amount AS a, status AS s FROM t_account WHERE
account_id = 1 AND password = 'aaa' AND password like 'aaa' AND amount = 1000
AND status = 'OK'
-- Expected SQL:
SELECT account_id, cipher_password AS password, cipher_amount AS a, status
AS s FROM t_account WHERE account_id = 1 AND assisted_query_password =
'assisted_query_aaa' AND like_query_password like 'like_query_aaa' AND
cipher_amount = 'encrypt_1000' AND status = 'OK'
-- Actual SQL:
SELECT account_id, cipher_password AS password, cipher_amount AS a, status
AS s FROM t_account WHERE account_id = 1 AND assisted_query_password =
'assisted_query_aaa' AND like_query_password like 'assisted_query_aaa' AND
cipher_amount = 'encrypt_1000' AND status = 'OK'
```
### Which version of ShardingSphere did you use?
ShardingSphere version 5.3.1
### Which project did you use? ShardingSphere-JDBC or ShardingSphere-Proxy?
Both ShardingSphere-JDBC and ShardingSphere-Proxy
### Expected behavior
Adding PostreSQL to the rewrite-assertion of encryption scenario, the unit
test of EncryptSQLRewriterIT runs without errors.
```sh
$ git diff
test/it/rewriter/src/test/resources/scenario/encrypt/case/query-with-cipher/dml/select/select-where.xml
<rewrite-assertions
yaml-rule="scenario/encrypt/config/query-with-cipher.yaml">
- <rewrite-assertion id="select_for_parameters" db-types="MySQL">
+ <rewrite-assertion id="select_for_parameters"
db-types="MySQL,PostgreSQL">
```
### Actual behavior
The error message when running the unit test EncryptSQLRewriterIT is as
follows:
```txt
java.lang.AssertionError:
Expected: is "like_query_aaa"
but: was "assisted_query_aaa"
```
### Reason analyze (If you can)
When using the LIKE operator in uppercase letters in SQL executed in
PostgreSQL, it can be correctly recognized and rewritten in the SQL, but when
mixed with lowercase letters, the rewriting of SQL will fail. The reason is
related to the sql-parser process. When `connection.prepareStatement` is
executed, PostgreSQLSelectStatement will parse
`sqlStatement.where.expr.operator` as a lowercase 'Like'. Therefore, when the
function `EncryptPredicateRightValueTokenGenerator@getEncryptedValues` is
executed, the LikeQueryColumn will be misjudged as an AssistedQueryColumn.
features/encrypt/core/src/main/java/org/apache/shardingsphere/encrypt/rewrite/token/generator/EncryptPredicateRightValueTokenGenerator.java
```java
private List<Object> getEncryptedValues(final String schemaName, final
EncryptCondition encryptCondition, final List<Object> originalValues) {
if (encryptCondition instanceof EncryptBinaryCondition &&
"LIKE".equals(((EncryptBinaryCondition) encryptCondition).getOperator())) {
Optional<String> likeQueryColumn =
encryptRule.findLikeQueryColumn(encryptCondition.getTableName(),
encryptCondition.getColumnName());
if (!likeQueryColumn.isPresent()) {
throw new UnsupportedEncryptSQLException("LIKE");
} else {
return encryptRule.getEncryptLikeQueryValues(databaseName,
schemaName, encryptCondition.getTableName(), encryptCondition.getColumnName(),
originalValues);
}
}
Optional<String> assistedQueryColumn =
encryptRule.findAssistedQueryColumn(encryptCondition.getTableName(),
encryptCondition.getColumnName());
return assistedQueryColumn.isPresent()
? encryptRule.getEncryptAssistedQueryValues(databaseName,
schemaName, encryptCondition.getTableName(), encryptCondition.getColumnName(),
originalValues)
: encryptRule.getEncryptValues(databaseName, schemaName,
encryptCondition.getTableName(), encryptCondition.getColumnName(),
originalValues);
}
```
### Steps to reproduce the behavior, such as: SQL to execute, sharding rule
configuration, when exception occur etc.
Step 1: Adding PostreSQL to the rewrite-assertion of encryption scenario.
```sh
$ git diff
test/it/rewriter/src/test/resources/scenario/encrypt/case/query-with-cipher/dml/select/select-where.xml
diff --git
a/test/it/rewriter/src/test/resources/scenario/encrypt/case/query-with-cipher/dml/select/select-where.xml
b/test/it/rewriter/src/test/resources/scenario/encrypt/case/query-with-cipher/dml/select/select-where.xml
index 52b76eb0af8..008c008703b 100644
---
a/test/it/rewriter/src/test/resources/scenario/encrypt/case/query-with-cipher/dml/select/select-where.xml
+++
b/test/it/rewriter/src/test/resources/scenario/encrypt/case/query-with-cipher/dml/select/select-where.xml
@@ -17,7 +17,7 @@
-->
<rewrite-assertions
yaml-rule="scenario/encrypt/config/query-with-cipher.yaml">
- <rewrite-assertion id="select_for_parameters" db-types="MySQL">
+ <rewrite-assertion id="select_for_parameters"
db-types="MySQL,PostgreSQL">
<input sql="SELECT account_id, password, amount AS a, status AS s
FROM t_account WHERE account_id = ? AND password = ? AND password like ? AND
amount = ? AND status = ?" parameters="1, aaa, aaa, 1000, OK" />
<output sql="SELECT account_id, cipher_password AS password,
cipher_amount AS a, status AS s FROM t_account WHERE account_id = ? AND
assisted_query_password = ? AND like_query_password like ? AND cipher_amount =
? AND statu
s = ?" parameters="1, assisted_query_aaa, like_query_aaa, encrypt_1000, OK"
/>
</rewrite-assertion>
```
Step 2: The error message when running the unit test EncryptSQLRewriterIT is
as follows:
```txt
java.lang.AssertionError:
Expected: is "like_query_aaa"
but: was "assisted_query_aaa"
预期:like_query_aaa
实际:assisted_query_aaa
at org.hamcrest.MatcherAssert.assertThat(MatcherAssert.java:20)
at org.hamcrest.MatcherAssert.assertThat(MatcherAssert.java:8)
at
org.apache.shardingsphere.test.it.rewrite.engine.AbstractSQLRewriterIT.assertRewrite(AbstractSQLRewriterIT.java:101)
at jdk.internal.reflect.GeneratedMethodAccessor38.invoke(Unknown Source)
at
java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.base/java.lang.reflect.Method.invoke(Method.java:566)
at
org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:59)
at
org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
at
org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:56)
at
org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17)
at org.junit.runners.ParentRunner$3.evaluate(ParentRunner.java:306)
at
org.junit.runners.BlockJUnit4ClassRunner$1.evaluate(BlockJUnit4ClassRunner.java:100)
at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:366)
at
org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:103)
at
org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:63)
at org.junit.runners.ParentRunner$4.run(ParentRunner.java:331)
at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:79)
at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:329)
at org.junit.runners.ParentRunner.access$100(ParentRunner.java:66)
at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:293)
at org.junit.runners.ParentRunner.run(ParentRunner.java:413)
at org.junit.runners.Suite.runChild(Suite.java:128)
at org.junit.runners.Suite.runChild(Suite.java:27)
at org.junit.runners.ParentRunner$4.run(ParentRunner.java:331)
at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:79)
at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:329)
at org.junit.runners.ParentRunner.access$100(ParentRunner.java:66)
at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:293)
at org.junit.runners.ParentRunner$3.evaluate(ParentRunner.java:306)
at org.junit.runners.ParentRunner.run(ParentRunner.java:413)
at org.junit.runner.JUnitCore.run(JUnitCore.java:137)
at
com.intellij.junit4.JUnit4IdeaTestRunner.startRunnerWithArgs(JUnit4IdeaTestRunner.java:69)
at
com.intellij.rt.junit.IdeaTestRunner$Repeater$1.execute(IdeaTestRunner.java:38)
at
com.intellij.rt.execution.junit.TestsRepeater.repeat(TestsRepeater.java:11)
at
com.intellij.rt.junit.IdeaTestRunner$Repeater.startRunnerWithArgs(IdeaTestRunner.java:35)
at
com.intellij.rt.junit.JUnitStarter.prepareStreamsAndStart(JUnitStarter.java:235)
at com.intellij.rt.junit.JUnitStarter.main(JUnitStarter.java:54)
进程已结束,退出代码-1
```
### Example codes for reproduce this issue (such as a github link).
None
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail:
[email protected]
For queries about this service, please contact Infrastructure at:
[email protected]