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

asf-gitbox-commits pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/cayenne.git


The following commit(s) were added to refs/heads/master by this push:
     new e616fc6df CAY-2972 Fewer parentheses in generated SQL
e616fc6df is described below

commit e616fc6dfea1652762db199b7b12b9ae852799a9
Author: Andrus Adamchik <[email protected]>
AuthorDate: Sat Jul 4 15:32:16 2026 -0400

    CAY-2972 Fewer parentheses in generated SQL
---
 RELEASE-NOTES.txt                                  |  1 +
 .../access/sqlbuilder/sqltree/BetweenNode.java     |  5 +++
 .../access/sqlbuilder/sqltree/ElseNode.java        |  4 ++
 .../access/sqlbuilder/sqltree/ExpressionNode.java  | 49 ++++++++++++++++++----
 .../access/sqlbuilder/sqltree/NodeType.java        |  5 ++-
 .../sqlbuilder/sqltree/OpExpressionNode.java       | 13 ++++++
 .../access/sqlbuilder/sqltree/ThenNode.java        |  4 ++
 .../access/sqlbuilder/sqltree/WhenNode.java        |  4 ++
 .../access/sqlbuilder/DeleteBuilderTest.java       |  2 +-
 .../access/sqlbuilder/SelectBuilderTest.java       | 38 +++++++++--------
 .../translator/batch/DeleteBatchTranslatorIT.java  |  6 +--
 .../translator/batch/UpdateBatchTranslatorIT.java  |  6 +--
 .../QualifierTranslatorExistExpressionIT.java      | 32 +++++++-------
 .../translator/select/QualifierTranslatorIT.java   |  4 +-
 .../translator/select/QualifierTranslatorTest.java |  2 +-
 15 files changed, 122 insertions(+), 53 deletions(-)

diff --git a/RELEASE-NOTES.txt b/RELEASE-NOTES.txt
index 45deed439..2b29d881c 100644
--- a/RELEASE-NOTES.txt
+++ b/RELEASE-NOTES.txt
@@ -22,6 +22,7 @@ CAY-2963 Replace TypesHandler / types.xml with hardcoded map
 CAY-2969 Extender API for "soft" delete 
 CAY-2970 Tighten deferred value resolution contract on commit
 CAY-2971 Remove extra spaces within SQL parenthesis
+CAY-2972 Fewer parentheses in generated SQL
 
 Bug Fixes:
 
diff --git 
a/cayenne/src/main/java/org/apache/cayenne/access/sqlbuilder/sqltree/BetweenNode.java
 
b/cayenne/src/main/java/org/apache/cayenne/access/sqlbuilder/sqltree/BetweenNode.java
index 4199c4f4c..d9a56e0f3 100644
--- 
a/cayenne/src/main/java/org/apache/cayenne/access/sqlbuilder/sqltree/BetweenNode.java
+++ 
b/cayenne/src/main/java/org/apache/cayenne/access/sqlbuilder/sqltree/BetweenNode.java
@@ -47,6 +47,11 @@ public class BetweenNode extends ExpressionNode {
         }
     }
 
+    @Override
+    protected boolean isComparison() {
+        return true;
+    }
+
     @Override
     public Node copy() {
         return new BetweenNode(not);
diff --git 
a/cayenne/src/main/java/org/apache/cayenne/access/sqlbuilder/sqltree/ElseNode.java
 
b/cayenne/src/main/java/org/apache/cayenne/access/sqlbuilder/sqltree/ElseNode.java
index 7f9b23b8a..08b7d1157 100644
--- 
a/cayenne/src/main/java/org/apache/cayenne/access/sqlbuilder/sqltree/ElseNode.java
+++ 
b/cayenne/src/main/java/org/apache/cayenne/access/sqlbuilder/sqltree/ElseNode.java
@@ -26,6 +26,10 @@ import org.apache.cayenne.access.sqlbuilder.SQLAppendable;
  */
 public class ElseNode extends Node {
 
+    public ElseNode() {
+        super(NodeType.ELSE);
+    }
+
     @Override
     public SQLAppendable append(SQLAppendable buffer) {
         return buffer.appendTokenSeparator().append("ELSE");
diff --git 
a/cayenne/src/main/java/org/apache/cayenne/access/sqlbuilder/sqltree/ExpressionNode.java
 
b/cayenne/src/main/java/org/apache/cayenne/access/sqlbuilder/sqltree/ExpressionNode.java
index cab202194..fa8b6b5ad 100644
--- 
a/cayenne/src/main/java/org/apache/cayenne/access/sqlbuilder/sqltree/ExpressionNode.java
+++ 
b/cayenne/src/main/java/org/apache/cayenne/access/sqlbuilder/sqltree/ExpressionNode.java
@@ -41,24 +41,57 @@ public class ExpressionNode extends Node {
 
     @Override
     public void appendChildrenStart(SQLAppendable buffer) {
-        if(parent != null
-                && parent.type != NodeType.WHERE
-                && parent.type != NodeType.JOIN
-                && parent.type != NodeType.UPDATE_SET) {
+        if (needsParentheses()) {
             
buffer.appendTokenSeparator().append('(').suppressNextTokenSeparator();
         }
     }
 
     @Override
     public void appendChildrenEnd(SQLAppendable buffer) {
-        if(parent != null
-                && parent.type != NodeType.WHERE
-                && parent.type != NodeType.JOIN
-                && parent.type != NodeType.UPDATE_SET) {
+        if (needsParentheses()) {
             buffer.append(")");
         }
     }
 
+    protected boolean needsParentheses() {
+        if (parent == null
+                || parent.type == NodeType.WHERE
+                || parent.type == NodeType.JOIN
+                || parent.type == NodeType.UPDATE_SET
+                || parent.type == NodeType.WHEN
+                || parent.type == NodeType.THEN
+                || parent.type == NodeType.ELSE) {
+            return false;
+        }
+
+        if (parent instanceof ExpressionNode parentExpr) {
+            String parentOp = parentExpr.logicalOperator();
+            if (parentOp != null) {
+                if (isComparison()) {
+                    return false;
+                }
+
+                return !parentOp.equals(logicalOperator());
+            }
+        }
+        return true;
+    }
+
+    /**
+     * @return {@code "AND"} or {@code "OR"} if this node is a logical 
connective, otherwise {@code null}.
+     */
+    protected String logicalOperator() {
+        return null;
+    }
+
+    /**
+     * @return true for comparison operators that bind tighter than {@code 
AND}/{@code OR} and therefore don't need
+     * parentheses when nested directly under them.
+     */
+    protected boolean isComparison() {
+        return type == NodeType.EQUALITY || type == NodeType.LIKE;
+    }
+
     @Override
     public String toString() {
         return "{ExpressionNode}";
diff --git 
a/cayenne/src/main/java/org/apache/cayenne/access/sqlbuilder/sqltree/NodeType.java
 
b/cayenne/src/main/java/org/apache/cayenne/access/sqlbuilder/sqltree/NodeType.java
index c02019af7..881363d82 100644
--- 
a/cayenne/src/main/java/org/apache/cayenne/access/sqlbuilder/sqltree/NodeType.java
+++ 
b/cayenne/src/main/java/org/apache/cayenne/access/sqlbuilder/sqltree/NodeType.java
@@ -40,5 +40,8 @@ public enum NodeType {
     INSERT_COLUMNS,
     INSERT_VALUES,
     ORDER_BY,
-    SELECT
+    SELECT,
+    WHEN,
+    THEN,
+    ELSE
 }
diff --git 
a/cayenne/src/main/java/org/apache/cayenne/access/sqlbuilder/sqltree/OpExpressionNode.java
 
b/cayenne/src/main/java/org/apache/cayenne/access/sqlbuilder/sqltree/OpExpressionNode.java
index b8eb40640..feed85c98 100644
--- 
a/cayenne/src/main/java/org/apache/cayenne/access/sqlbuilder/sqltree/OpExpressionNode.java
+++ 
b/cayenne/src/main/java/org/apache/cayenne/access/sqlbuilder/sqltree/OpExpressionNode.java
@@ -39,6 +39,19 @@ public class OpExpressionNode extends ExpressionNode {
         buffer.appendTokenSeparator().append(op);
     }
 
+    @Override
+    protected String logicalOperator() {
+        return "AND".equals(op) || "OR".equals(op) ? op : null;
+    }
+
+    @Override
+    protected boolean isComparison() {
+        return switch (op) {
+            case "<", "<=", ">", ">=" -> true;
+            default -> false;
+        };
+    }
+
     @Override
     public Node copy() {
         return new OpExpressionNode(op);
diff --git 
a/cayenne/src/main/java/org/apache/cayenne/access/sqlbuilder/sqltree/ThenNode.java
 
b/cayenne/src/main/java/org/apache/cayenne/access/sqlbuilder/sqltree/ThenNode.java
index 7b6ccc76a..60ee9b960 100644
--- 
a/cayenne/src/main/java/org/apache/cayenne/access/sqlbuilder/sqltree/ThenNode.java
+++ 
b/cayenne/src/main/java/org/apache/cayenne/access/sqlbuilder/sqltree/ThenNode.java
@@ -26,6 +26,10 @@ import org.apache.cayenne.access.sqlbuilder.SQLAppendable;
  */
 public class ThenNode extends Node {
 
+    public ThenNode() {
+        super(NodeType.THEN);
+    }
+
     @Override
     public SQLAppendable append(SQLAppendable buffer) {
         return buffer.appendTokenSeparator().append("THEN");
diff --git 
a/cayenne/src/main/java/org/apache/cayenne/access/sqlbuilder/sqltree/WhenNode.java
 
b/cayenne/src/main/java/org/apache/cayenne/access/sqlbuilder/sqltree/WhenNode.java
index 13bc92cdd..fd9531327 100644
--- 
a/cayenne/src/main/java/org/apache/cayenne/access/sqlbuilder/sqltree/WhenNode.java
+++ 
b/cayenne/src/main/java/org/apache/cayenne/access/sqlbuilder/sqltree/WhenNode.java
@@ -26,6 +26,10 @@ import org.apache.cayenne.access.sqlbuilder.SQLAppendable;
  */
 public class WhenNode extends Node {
 
+    public WhenNode() {
+        super(NodeType.WHEN);
+    }
+
     @Override
     public SQLAppendable append(SQLAppendable buffer) {
         return buffer.appendTokenSeparator().append("WHEN");
diff --git 
a/cayenne/src/test/java/org/apache/cayenne/access/sqlbuilder/DeleteBuilderTest.java
 
b/cayenne/src/test/java/org/apache/cayenne/access/sqlbuilder/DeleteBuilderTest.java
index eb7b713dd..8a079d290 100644
--- 
a/cayenne/src/test/java/org/apache/cayenne/access/sqlbuilder/DeleteBuilderTest.java
+++ 
b/cayenne/src/test/java/org/apache/cayenne/access/sqlbuilder/DeleteBuilderTest.java
@@ -46,7 +46,7 @@ public class DeleteBuilderTest extends BaseSqlBuilderTest {
                         .and(column("col3").eq(value(null)))
         ).build();
         assertInstanceOf(DeleteNode.class, node);
-        assertSQL("DELETE FROM test WHERE ((col1 = 1) AND (col2 = 'test')) AND 
(col3 IS NULL)", node);
+        assertSQL("DELETE FROM test WHERE col1 = 1 AND col2 = 'test' AND col3 
IS NULL", node);
     }
 
     @Test
diff --git 
a/cayenne/src/test/java/org/apache/cayenne/access/sqlbuilder/SelectBuilderTest.java
 
b/cayenne/src/test/java/org/apache/cayenne/access/sqlbuilder/SelectBuilderTest.java
index 6c86c3ced..18b874eb6 100644
--- 
a/cayenne/src/test/java/org/apache/cayenne/access/sqlbuilder/SelectBuilderTest.java
+++ 
b/cayenne/src/test/java/org/apache/cayenne/access/sqlbuilder/SelectBuilderTest.java
@@ -96,7 +96,7 @@ public class SelectBuilderTest extends BaseSqlBuilderTest  {
                 
.where(column("a").eq(value(123)).and(column("c").lt(column("d"))));
         Node node = builder.build();
         assertInstanceOf(SelectNode.class, node);
-        assertSQL("SELECT a FROM b WHERE (a = 123) AND (c < d)", node);
+        assertSQL("SELECT a FROM b WHERE a = 123 AND c < d", node);
     }
 
     @Test
@@ -112,13 +112,14 @@ public class SelectBuilderTest extends BaseSqlBuilderTest 
 {
 
         Node node = builder.build();
         assertInstanceOf(SelectNode.class, node);
-        assertSQL("SELECT OrderID, Quantity, " +
-                "CASE " +
-                    "WHEN ((Quantity > 30) AND (Quantity < 100)) THEN 'The 
quantity from 30 to 100' " +
-                    "WHEN (Quantity = 30) THEN 'The quantity is 30' " +
-                    "ELSE 'The quantity is under 30' " +
-                    "END QuantityText " +
-                "FROM OrderDetails", node);
+        assertSQL("""
+                SELECT OrderID, Quantity, \
+                CASE \
+                WHEN Quantity > 30 AND Quantity < 100 THEN 'The quantity from 
30 to 100' \
+                WHEN Quantity = 30 THEN 'The quantity is 30' \
+                ELSE 'The quantity is under 30' \
+                END QuantityText \
+                FROM OrderDetails""", node);
     }
 
     @Test
@@ -179,16 +180,17 @@ public class SelectBuilderTest extends BaseSqlBuilderTest 
 {
                 
.orderBy(count(table("p").column("PAINTING_TITLE")).as("p_count").desc(), 
column("a_id").asc())
                 .build();
         assertInstanceOf(SelectNode.class, node);
-        assertSQL("SELECT DISTINCT" +
-                    " a.ARTIST_ID a_id, COUNT(p.PAINTING_TITLE) p_count" +
-                " FROM ARTIST a" +
-                " LEFT JOIN PAINTING p ON (a.ARTIST_ID = p.ARTIST_ID) AND 
(p.ESTIMATED_PRICE > 10)" +
-                " WHERE (((a.ARTIST_NAME = 'Picasso')" +
-                    " AND EXISTS (SELECT * FROM GALLERY g WHERE g.GALLERY_ID = 
p.GALLERY_ID))" +
-                    " AND (1 = 1)) OR false" +
-                " GROUP BY a.ARTIST_ID" +
-                " HAVING NOT (COUNT(p.PAINTING_TITLE) > 3)" +
-                " ORDER BY p_count DESC, a_id", node);
+        assertSQL("""
+                SELECT DISTINCT \
+                a.ARTIST_ID a_id, COUNT(p.PAINTING_TITLE) p_count \
+                FROM ARTIST a \
+                LEFT JOIN PAINTING p ON a.ARTIST_ID = p.ARTIST_ID AND 
p.ESTIMATED_PRICE > 10 \
+                WHERE (a.ARTIST_NAME = 'Picasso' \
+                AND EXISTS (SELECT * FROM GALLERY g WHERE g.GALLERY_ID = 
p.GALLERY_ID) \
+                AND 1 = 1) OR false \
+                GROUP BY a.ARTIST_ID \
+                HAVING NOT (COUNT(p.PAINTING_TITLE) > 3) \
+                ORDER BY p_count DESC, a_id""", node);
     }
 
 }
\ No newline at end of file
diff --git 
a/cayenne/src/test/java/org/apache/cayenne/access/translator/batch/DeleteBatchTranslatorIT.java
 
b/cayenne/src/test/java/org/apache/cayenne/access/translator/batch/DeleteBatchTranslatorIT.java
index 017e563ec..a735845c6 100644
--- 
a/cayenne/src/test/java/org/apache/cayenne/access/translator/batch/DeleteBatchTranslatorIT.java
+++ 
b/cayenne/src/test/java/org/apache/cayenne/access/translator/batch/DeleteBatchTranslatorIT.java
@@ -90,7 +90,7 @@ public class DeleteBatchTranslatorIT {
         DbAdapter adapter = objectFactory.newInstance(DbAdapter.class, 
JdbcAdapter.class.getName());
         String generatedSql = new 
DeleteBatchTranslator().translate(deleteQuery, adapter).sql();
         assertNotNull(generatedSql);
-        assertEquals("DELETE FROM " + entity.getName() + " WHERE 
(LOCKING_TEST_ID = ?) AND (NAME IS NULL)", generatedSql);
+        assertEquals("DELETE FROM " + entity.getName() + " WHERE 
LOCKING_TEST_ID = ? AND NAME IS NULL", generatedSql);
     }
 
     @Test
@@ -138,8 +138,8 @@ public class DeleteBatchTranslatorIT {
             String charEnd = unitAdapter.getIdentifiersEndQuote();
             assertNotNull(generatedSql);
 
-            assertEquals("DELETE FROM " + charStart + entity.getName() + 
charEnd + " WHERE (" + charStart
-                    + "LOCKING_TEST_ID" + charEnd + " = ?) AND (" + charStart 
+ "NAME" + charEnd + " IS NULL)",
+            assertEquals("DELETE FROM " + charStart + entity.getName() + 
charEnd + " WHERE " + charStart
+                    + "LOCKING_TEST_ID" + charEnd + " = ? AND " + charStart + 
"NAME" + charEnd + " IS NULL",
                     generatedSql);
         } finally {
             entity.getDataMap().setQuotingSQLIdentifiers(false);
diff --git 
a/cayenne/src/test/java/org/apache/cayenne/access/translator/batch/UpdateBatchTranslatorIT.java
 
b/cayenne/src/test/java/org/apache/cayenne/access/translator/batch/UpdateBatchTranslatorIT.java
index fcaccfd56..7cd2ff180 100644
--- 
a/cayenne/src/test/java/org/apache/cayenne/access/translator/batch/UpdateBatchTranslatorIT.java
+++ 
b/cayenne/src/test/java/org/apache/cayenne/access/translator/batch/UpdateBatchTranslatorIT.java
@@ -94,7 +94,7 @@ public class UpdateBatchTranslatorIT {
         String generatedSql = new 
UpdateBatchTranslator().translate(updateQuery, adapter).sql();
         assertNotNull(generatedSql);
 
-        assertEquals("UPDATE " + entity.getName() + " SET DESCRIPTION = ? 
WHERE (LOCKING_TEST_ID = ?) AND (NAME IS NULL)",
+        assertEquals("UPDATE " + entity.getName() + " SET DESCRIPTION = ? 
WHERE LOCKING_TEST_ID = ? AND NAME IS NULL",
                 generatedSql);
     }
 
@@ -145,8 +145,8 @@ public class UpdateBatchTranslatorIT {
             String charStart = unitAdapter.getIdentifiersStartQuote();
             String charEnd = unitAdapter.getIdentifiersEndQuote();
             assertEquals("UPDATE " + charStart + entity.getName() + charEnd + 
" SET " + charStart + "DESCRIPTION"
-                    + charEnd + " = ? WHERE (" + charStart + "LOCKING_TEST_ID" 
+ charEnd + " = ?) AND (" + charStart
-                    + "NAME" + charEnd + " IS NULL)", generatedSql);
+                    + charEnd + " = ? WHERE " + charStart + "LOCKING_TEST_ID" 
+ charEnd + " = ? AND " + charStart
+                    + "NAME" + charEnd + " IS NULL", generatedSql);
 
         } finally {
             entity.getDataMap().setQuotingSQLIdentifiers(false);
diff --git 
a/cayenne/src/test/java/org/apache/cayenne/access/translator/select/QualifierTranslatorExistExpressionIT.java
 
b/cayenne/src/test/java/org/apache/cayenne/access/translator/select/QualifierTranslatorExistExpressionIT.java
index fcea075a0..3bb2b69b2 100644
--- 
a/cayenne/src/test/java/org/apache/cayenne/access/translator/select/QualifierTranslatorExistExpressionIT.java
+++ 
b/cayenne/src/test/java/org/apache/cayenne/access/translator/select/QualifierTranslatorExistExpressionIT.java
@@ -113,7 +113,7 @@ public class QualifierTranslatorExistExpressionIT {
 
         assertSQL(" EXISTS (" +
                 "SELECT t1.PAINTING_ID FROM PAINTING t1 " +
-                "WHERE (t1.PAINTING_TITLE IS NOT NULL) AND (t1.ARTIST_ID = 
t0.ARTIST_ID)" +
+                "WHERE t1.PAINTING_TITLE IS NOT NULL AND t1.ARTIST_ID = 
t0.ARTIST_ID" +
                 ")", node);
     }
 
@@ -134,7 +134,7 @@ public class QualifierTranslatorExistExpressionIT {
 
         assertSQL(" EXISTS (" +
                 "SELECT t1.PAINTING_ID FROM PAINTING t1 " +
-                "WHERE (t1.GALLERY_ID IS NOT NULL) AND (t1.ARTIST_ID = 
t0.ARTIST_ID)" +
+                "WHERE t1.GALLERY_ID IS NOT NULL AND t1.ARTIST_ID = 
t0.ARTIST_ID" +
                 ")", node);
     }
 
@@ -157,7 +157,7 @@ public class QualifierTranslatorExistExpressionIT {
                 "SELECT DISTINCT t1.ARTIST_ID, t1.GROUP_ID FROM ARTIST_GROUP 
t1 " +
                 "JOIN ARTGROUP t2 ON t1.GROUP_ID = t2.GROUP_ID " +
                 "JOIN ARTGROUP t3 ON t2.GROUP_ID = t3.PARENT_GROUP_ID " +
-                "WHERE (t3.GROUP_ID IS NOT NULL) AND (t1.ARTIST_ID = 
t0.ARTIST_ID)" +
+                "WHERE t3.GROUP_ID IS NOT NULL AND t1.ARTIST_ID = 
t0.ARTIST_ID" +
                 ")", node);
     }
 
@@ -178,7 +178,7 @@ public class QualifierTranslatorExistExpressionIT {
 
         assertSQL(" EXISTS (" +
                 "SELECT t1.PAINTING_ID FROM PAINTING t1 " +
-                "WHERE (t1.PAINTING_TITLE = 'test') AND (t1.ARTIST_ID = 
t0.ARTIST_ID)" +
+                "WHERE t1.PAINTING_TITLE = 'test' AND t1.ARTIST_ID = 
t0.ARTIST_ID" +
                 ")", node);
     }
 
@@ -200,8 +200,8 @@ public class QualifierTranslatorExistExpressionIT {
 
         assertSQL(" EXISTS (" +
                 "SELECT t1.PAINTING_ID FROM PAINTING t1 " +
-                "WHERE ((t1.PAINTING_TITLE = 'test') OR (t1.PAINTING_TITLE = 
'test2')) " +
-                        "AND (t1.ARTIST_ID = t0.ARTIST_ID)" +
+                "WHERE (t1.PAINTING_TITLE = 'test' OR t1.PAINTING_TITLE = 
'test2') " +
+                        "AND t1.ARTIST_ID = t0.ARTIST_ID" +
                 ")", node);
     }
 
@@ -222,8 +222,8 @@ public class QualifierTranslatorExistExpressionIT {
 
         assertSQL(" EXISTS (" +
                 "SELECT t1.PAINTING_ID FROM PAINTING t1 " +
-                "WHERE ((t1.PAINTING_TITLE = 'test') OR (t1.PAINTING_TITLE = 
'test2')) " +
-                "AND (t1.ARTIST_ID = t0.ARTIST_ID)" +
+                "WHERE (t1.PAINTING_TITLE = 'test' OR t1.PAINTING_TITLE = 
'test2') " +
+                "AND t1.ARTIST_ID = t0.ARTIST_ID" +
                 ")", node);
     }
 
@@ -245,13 +245,13 @@ public class QualifierTranslatorExistExpressionIT {
 
         assertSQL(" EXISTS (" +
                     "SELECT t1.PAINTING_ID FROM PAINTING t1 " +
-                    "WHERE ((t1.PAINTING_TITLE = 'test') OR (t1.PAINTING_TITLE 
= 'test2')) " +
-                            "AND (t1.ARTIST_ID = t0.ARTIST_ID)" +
+                    "WHERE (t1.PAINTING_TITLE = 'test' OR t1.PAINTING_TITLE = 
'test2') " +
+                            "AND t1.ARTIST_ID = t0.ARTIST_ID" +
                 ") " +
                 "AND EXISTS (" +
                     "SELECT t2.ARTIST_ID, t2.GROUP_ID FROM ARTIST_GROUP t2 " +
                     "JOIN ARTGROUP t3 ON t2.GROUP_ID = t3.GROUP_ID " +
-                    "WHERE (t3.NAME = 'test') AND (t2.ARTIST_ID = 
t0.ARTIST_ID))", node);
+                    "WHERE t3.NAME = 'test' AND t2.ARTIST_ID = t0.ARTIST_ID)", 
node);
     }
 
     @Test
@@ -272,18 +272,18 @@ public class QualifierTranslatorExistExpressionIT {
 
         assertSQL(" EXISTS (" +
                     "SELECT t1.PAINTING_ID FROM PAINTING t1 " +
-                    "WHERE (t1.PAINTING_TITLE = 'test') AND (t1.ARTIST_ID = 
t0.ARTIST_ID)" +
+                    "WHERE t1.PAINTING_TITLE = 'test' AND t1.ARTIST_ID = 
t0.ARTIST_ID" +
                 ") " +
                 "AND (" +
                     "EXISTS (" +
                         "SELECT t2.ARTIST_ID, t2.GROUP_ID FROM ARTIST_GROUP t2 
" +
                         "JOIN ARTGROUP t3 ON t2.GROUP_ID = t3.GROUP_ID " +
-                        "WHERE (t3.NAME = 'test') AND (t2.ARTIST_ID = 
t0.ARTIST_ID)" +
+                        "WHERE t3.NAME = 'test' AND t2.ARTIST_ID = 
t0.ARTIST_ID" +
                     ") " +
                     "OR " +
                     "EXISTS (" +
                         "SELECT t4.PAINTING_ID FROM PAINTING t4 " +
-                        "WHERE (t4.PAINTING_TITLE = 'test2') AND (t4.ARTIST_ID 
= t0.ARTIST_ID)" +
+                        "WHERE t4.PAINTING_TITLE = 'test2' AND t4.ARTIST_ID = 
t0.ARTIST_ID" +
                     ")" +
                 ")", node);
     }
@@ -305,12 +305,12 @@ public class QualifierTranslatorExistExpressionIT {
 
         assertSQL(" EXISTS (" +
                     "SELECT t1.PAINTING_ID FROM PAINTING t1 " +
-                    "WHERE LENGTH(t1.PAINTING_TITLE) IN (1, 2, 3) AND 
(t1.ARTIST_ID = t0.ARTIST_ID)" +
+                    "WHERE LENGTH(t1.PAINTING_TITLE) IN (1, 2, 3) AND 
t1.ARTIST_ID = t0.ARTIST_ID" +
                 ") OR " +
                 "EXISTS (" +
                     "SELECT t2.ARTIST_ID, t2.GROUP_ID FROM ARTIST_GROUP t2 " +
                     "JOIN ARTGROUP t3 ON t2.GROUP_ID = t3.GROUP_ID " +
-                    "WHERE (LENGTH(t3.NAME) < 10) AND (t2.ARTIST_ID = 
t0.ARTIST_ID)" +
+                    "WHERE LENGTH(t3.NAME) < 10 AND t2.ARTIST_ID = 
t0.ARTIST_ID" +
                 ")", node);
     }
 
diff --git 
a/cayenne/src/test/java/org/apache/cayenne/access/translator/select/QualifierTranslatorIT.java
 
b/cayenne/src/test/java/org/apache/cayenne/access/translator/select/QualifierTranslatorIT.java
index c833b979c..8e139f182 100644
--- 
a/cayenne/src/test/java/org/apache/cayenne/access/translator/select/QualifierTranslatorIT.java
+++ 
b/cayenne/src/test/java/org/apache/cayenne/access/translator/select/QualifierTranslatorIT.java
@@ -73,7 +73,7 @@ public class QualifierTranslatorIT {
         SQLGenerationVisitor visitor = new SQLGenerationVisitor(new 
DefaultSQLAppendable(null));
         node.visit(visitor);
 
-        assertEquals(" (((t0.F_KEY1 = 'PK1') AND (t0.F_KEY2 = 'PK2')) AND 
t0.NAME LIKE 'test%') AND t0.NAME LIKE '%a%'", visitor.getSQLString());
+        assertEquals(" t0.F_KEY1 = 'PK1' AND t0.F_KEY2 = 'PK2' AND t0.NAME 
LIKE 'test%' AND t0.NAME LIKE '%a%'", visitor.getSQLString());
     }
 
     @Test
@@ -98,7 +98,7 @@ public class QualifierTranslatorIT {
         SQLGenerationVisitor visitor = new SQLGenerationVisitor(new 
DefaultSQLAppendable(null));
         node.visit(visitor);
 
-        assertEquals(" ((t0.F_KEY1 = 'PK1') AND (t0.F_KEY2 = 'PK2')) OR 
((t0.F_KEY1 = 'PK3') AND (t0.F_KEY2 = 'PK4'))", visitor.getSQLString());
+        assertEquals(" (t0.F_KEY1 = 'PK1' AND t0.F_KEY2 = 'PK2') OR (t0.F_KEY1 
= 'PK3' AND t0.F_KEY2 = 'PK4')", visitor.getSQLString());
     }
 
     @Test
diff --git 
a/cayenne/src/test/java/org/apache/cayenne/access/translator/select/QualifierTranslatorTest.java
 
b/cayenne/src/test/java/org/apache/cayenne/access/translator/select/QualifierTranslatorTest.java
index 8054ebce7..e6b3ee695 100644
--- 
a/cayenne/src/test/java/org/apache/cayenne/access/translator/select/QualifierTranslatorTest.java
+++ 
b/cayenne/src/test/java/org/apache/cayenne/access/translator/select/QualifierTranslatorTest.java
@@ -485,7 +485,7 @@ public class QualifierTranslatorTest {
 
         SQLGenerationVisitor visitor = new SQLGenerationVisitor(new 
DefaultSQLAppendable(null));
         and.visit(visitor);
-        assertEquals(" (t0.a < 2) AND t0.b IN (5, 6) AND (t0.b = 7)", 
visitor.getSQLString());
+        assertEquals(" t0.a < 2 AND t0.b IN (5, 6) AND t0.b = 7", 
visitor.getSQLString());
     }
 
     @Test

Reply via email to