This is an automated email from the ASF dual-hosted git repository.
ntimofeev pushed a commit to branch STABLE-4.2
in repository https://gitbox.apache.org/repos/asf/cayenne.git
The following commit(s) were added to refs/heads/STABLE-4.2 by this push:
new 2a9debc1c CAY-2813 Regression: Constants.CI_PROPERTY flag is no longer
working for MySQL
2a9debc1c is described below
commit 2a9debc1c84d4f82bc688114f7f993f1d0193e6f
Author: Nikita Timofeev <[email protected]>
AuthorDate: Wed Aug 23 22:32:01 2023 +0300
CAY-2813 Regression: Constants.CI_PROPERTY flag is no longer working for
MySQL
(cherry picked from commit 983c51cd1f322ccbaa0468afe693adf938c3c1fe)
---
RELEASE-NOTES.txt | 1 +
.../select/TypeAwareSQLTreeProcessor.java | 3 +-
.../org/apache/cayenne/dba/mysql/MySQLAdapter.java | 2 +-
.../cayenne/dba/mysql/MySQLTreeProcessor.java | 14 +++++---
.../cayenne/dba/mysql/sqltree/MysqlLikeNode.java | 2 +-
.../access/sqlbuilder/BaseSqlBuilderTest.java | 10 +++---
.../cayenne/dba/mysql/MySQLTreeProcessorTest.java | 42 ++++++++++++++++++++++
7 files changed, 61 insertions(+), 13 deletions(-)
diff --git a/RELEASE-NOTES.txt b/RELEASE-NOTES.txt
index 1954a0dc8..10b3227e4 100644
--- a/RELEASE-NOTES.txt
+++ b/RELEASE-NOTES.txt
@@ -18,6 +18,7 @@ Bug Fixes:
CAY-2806 Incorrect processing of unicode escape syntax in JSON
CAY-2809 Cayenne Expression grammar doesn't allow custom function as an
argument for string functions
CAY-2810 Can't use custom operator expression with aggregate functions
+CAY-2813 Regression: Constants.CI_PROPERTY flag is no longer working for MySQL
----------------------------------
Release: 4.2
diff --git
a/cayenne-server/src/main/java/org/apache/cayenne/access/translator/select/TypeAwareSQLTreeProcessor.java
b/cayenne-server/src/main/java/org/apache/cayenne/access/translator/select/TypeAwareSQLTreeProcessor.java
index 7e48aed3f..b1f36b312 100644
---
a/cayenne-server/src/main/java/org/apache/cayenne/access/translator/select/TypeAwareSQLTreeProcessor.java
+++
b/cayenne-server/src/main/java/org/apache/cayenne/access/translator/select/TypeAwareSQLTreeProcessor.java
@@ -92,7 +92,8 @@ public class TypeAwareSQLTreeProcessor extends
SimpleNodeTreeVisitor implements
protected DbAttribute getColumnAttribute(ColumnNode node) {
DbAttribute attribute = node.getAttribute();
- if(attribute.getType() == Types.OTHER
+ if(attribute != null
+ && attribute.getType() == Types.OTHER
&& node.getParent() != null
&& node.getParent().getType() == NodeType.RESULT) {
return attribute;
diff --git
a/cayenne-server/src/main/java/org/apache/cayenne/dba/mysql/MySQLAdapter.java
b/cayenne-server/src/main/java/org/apache/cayenne/dba/mysql/MySQLAdapter.java
index 1573379ff..9a2acfef5 100644
---
a/cayenne-server/src/main/java/org/apache/cayenne/dba/mysql/MySQLAdapter.java
+++
b/cayenne-server/src/main/java/org/apache/cayenne/dba/mysql/MySQLAdapter.java
@@ -112,7 +112,7 @@ public class MySQLAdapter extends JdbcAdapter {
*/
@Override
public SQLTreeProcessor getSqlTreeProcessor() {
- return MySQLTreeProcessor.getInstance();
+ return
MySQLTreeProcessor.getInstance(caseInsensitiveCollations);
}
/**
diff --git
a/cayenne-server/src/main/java/org/apache/cayenne/dba/mysql/MySQLTreeProcessor.java
b/cayenne-server/src/main/java/org/apache/cayenne/dba/mysql/MySQLTreeProcessor.java
index f8243f5e8..e5ab32556 100644
---
a/cayenne-server/src/main/java/org/apache/cayenne/dba/mysql/MySQLTreeProcessor.java
+++
b/cayenne-server/src/main/java/org/apache/cayenne/dba/mysql/MySQLTreeProcessor.java
@@ -38,14 +38,18 @@ import org.apache.cayenne.value.Wkt;
*/
public class MySQLTreeProcessor extends TypeAwareSQLTreeProcessor {
- private static final MySQLTreeProcessor INSTANCE = new
MySQLTreeProcessor();
+ private static final MySQLTreeProcessor INSTANCE_CI = new
MySQLTreeProcessor(true);
+ private static final MySQLTreeProcessor INSTANCE_CS = new
MySQLTreeProcessor(false);
- public static MySQLTreeProcessor getInstance() {
- return INSTANCE;
+ public static MySQLTreeProcessor getInstance(boolean
caseInsensitiveCollations) {
+ return caseInsensitiveCollations ? INSTANCE_CI : INSTANCE_CS;
}
- protected MySQLTreeProcessor() {
- registerProcessor(NodeType.LIKE, (ChildProcessor<LikeNode>)
this::onLikeNode);
+ protected MySQLTreeProcessor(boolean ciCollations) {
+ if(ciCollations) {
+ // For case insensitive collations we need to use `LIKE BINARY`
operator to keep strict `LIKE` semantics
+ registerProcessor(NodeType.LIKE, (ChildProcessor<LikeNode>)
this::onLikeNode);
+ }
registerProcessor(NodeType.LIMIT_OFFSET,
(ChildProcessor<LimitOffsetNode>) this::onLimitOffsetNode);
registerProcessor(NodeType.FUNCTION, (ChildProcessor<FunctionNode>)
this::onFunctionNode);
diff --git
a/cayenne-server/src/main/java/org/apache/cayenne/dba/mysql/sqltree/MysqlLikeNode.java
b/cayenne-server/src/main/java/org/apache/cayenne/dba/mysql/sqltree/MysqlLikeNode.java
index 0a0ec454d..35d1470ae 100644
---
a/cayenne-server/src/main/java/org/apache/cayenne/dba/mysql/sqltree/MysqlLikeNode.java
+++
b/cayenne-server/src/main/java/org/apache/cayenne/dba/mysql/sqltree/MysqlLikeNode.java
@@ -36,7 +36,7 @@ public class MysqlLikeNode extends LikeNode {
if (not) {
buffer.append(" NOT");
}
- buffer.append(" LIKE BINARY ");
+ buffer.append(" LIKE BINARY");
}
@Override
diff --git
a/cayenne-server/src/test/java/org/apache/cayenne/access/sqlbuilder/BaseSqlBuilderTest.java
b/cayenne-server/src/test/java/org/apache/cayenne/access/sqlbuilder/BaseSqlBuilderTest.java
index 0df1e5066..f07862199 100644
---
a/cayenne-server/src/test/java/org/apache/cayenne/access/sqlbuilder/BaseSqlBuilderTest.java
+++
b/cayenne-server/src/test/java/org/apache/cayenne/access/sqlbuilder/BaseSqlBuilderTest.java
@@ -22,23 +22,23 @@ import org.apache.cayenne.access.sqlbuilder.sqltree.Node;
import static org.junit.Assert.assertEquals;
-class BaseSqlBuilderTest {
+public class BaseSqlBuilderTest {
- void assertSQL(String expected, Node node) {
+ protected void assertSQL(String expected, Node node) {
assertSQL(expected, node, new StringBuilderAppendable());
}
- void assertQuotedSQL(String expected, Node node) {
+ protected void assertQuotedSQL(String expected, Node node) {
assertSQL(expected, node, new MockQuotedStringBuilderAppendable());
}
- void assertSQL(String expected, Node node, QuotingAppendable appendable) {
+ protected void assertSQL(String expected, Node node, QuotingAppendable
appendable) {
SQLGenerationVisitor visitor = new SQLGenerationVisitor(appendable);
node.visit(visitor);
assertEquals(expected, visitor.getSQLString());
}
- static class MockQuotedStringBuilderAppendable extends
StringBuilderAppendable {
+ protected static class MockQuotedStringBuilderAppendable extends
StringBuilderAppendable {
@Override
public QuotingAppendable appendQuoted(CharSequence csq) {
builder.append('`').append(csq).append('`');
diff --git
a/cayenne-server/src/test/java/org/apache/cayenne/dba/mysql/MySQLTreeProcessorTest.java
b/cayenne-server/src/test/java/org/apache/cayenne/dba/mysql/MySQLTreeProcessorTest.java
new file mode 100644
index 000000000..4a35c1247
--- /dev/null
+++
b/cayenne-server/src/test/java/org/apache/cayenne/dba/mysql/MySQLTreeProcessorTest.java
@@ -0,0 +1,42 @@
+package org.apache.cayenne.dba.mysql;
+
+import org.apache.cayenne.access.sqlbuilder.BaseSqlBuilderTest;
+import org.apache.cayenne.access.sqlbuilder.sqltree.LikeNode;
+import org.apache.cayenne.access.sqlbuilder.sqltree.Node;
+import org.junit.Before;
+import org.junit.Test;
+
+import static org.apache.cayenne.access.sqlbuilder.SQLBuilder.*;
+
+public class MySQLTreeProcessorTest extends BaseSqlBuilderTest {
+
+ private Node sqlNode;
+
+ @Before
+ public void generateSql() {
+ sqlNode = select(column("*"))
+ .from(table("test"))
+ .where(() -> {
+ Node node = new LikeNode(false, false, (char) 0);
+ node.addChild(column("column").build());
+ node.addChild(value("abc").build());
+ return node;
+ })
+ .build();
+ assertSQL("SELECT * FROM test WHERE column LIKE 'abc'", sqlNode);
+ }
+
+ @Test
+ public void testLikeCI() {
+ MySQLTreeProcessor instance = MySQLTreeProcessor.getInstance(true);
+ Node processed = instance.process(sqlNode);
+ assertSQL("SELECT * FROM test WHERE column LIKE BINARY 'abc'",
processed);
+ }
+
+ @Test
+ public void testLikeCS() {
+ MySQLTreeProcessor instance = MySQLTreeProcessor.getInstance(false);
+ Node processed = instance.process(sqlNode);
+ assertSQL("SELECT * FROM test WHERE column LIKE 'abc'", processed);
+ }
+}
\ No newline at end of file