You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@cayenne.apache.org by nt...@apache.org on 2023/07/06 15:45:16 UTC

[cayenne] branch STABLE-4.2 updated (b87a8caf3 -> e888fb283)

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

ntimofeev pushed a change to branch STABLE-4.2
in repository https://gitbox.apache.org/repos/asf/cayenne.git


    from b87a8caf3 CAY-2806 Incorrect processing of unicode escape syntax in JSON
     new 9ac905173 CAY-2809 Cayenne Expression grammar doesn't allow custom function as an argument for string functions
     new 76c406ecc CAY-2810 Can't use custom operator expression with aggregate functions
     new e888fb283 CAY-2810 Can't use custom operator expression with aggregate functions

The 3 revisions listed above as "new" are entirely new to this
repository and will be described in separate emails.  The revisions
listed as "add" were already present in the repository and have only
been added to this reference.


Summary of changes:
 RELEASE-NOTES.txt                                  |  2 ++
 .../access/sqlbuilder/sqltree/AliasedNode.java     | 31 ++++++++++++++++++++--
 .../cayenne/exp/parser/ExpressionParser.java       | 10 ++++++-
 .../apache/cayenne/exp/parser/ExpressionParser.jjt |  4 +++
 .../cayenne/exp/parser/ASTCustomFunctionTest.java  |  8 ++++++
 .../cayenne/query/ObjectSelect_AggregateIT.java    | 20 ++++++++++++++
 6 files changed, 72 insertions(+), 3 deletions(-)


[cayenne] 01/03: CAY-2809 Cayenne Expression grammar doesn't allow custom function as an argument for string functions

Posted by nt...@apache.org.
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

commit 9ac905173c530de70e3336564e035be3ccbe53f8
Author: Nikita Timofeev <st...@gmail.com>
AuthorDate: Wed Jul 5 18:37:12 2023 +0300

    CAY-2809 Cayenne Expression grammar doesn't allow custom function as an argument for string functions
    
    (cherry picked from commit 0e79a606d20ecd1d31dd9be4fad28da37c14f3a2)
---
 RELEASE-NOTES.txt                                              |  1 +
 .../java/org/apache/cayenne/exp/parser/ExpressionParser.java   | 10 +++++++++-
 .../jjtree/org/apache/cayenne/exp/parser/ExpressionParser.jjt  |  4 ++++
 .../org/apache/cayenne/exp/parser/ASTCustomFunctionTest.java   |  8 ++++++++
 4 files changed, 22 insertions(+), 1 deletion(-)

diff --git a/RELEASE-NOTES.txt b/RELEASE-NOTES.txt
index f29952482..2be62e069 100644
--- a/RELEASE-NOTES.txt
+++ b/RELEASE-NOTES.txt
@@ -16,6 +16,7 @@ Changes/New Features:
 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
 
 ----------------------------------
 Release: 4.2
diff --git a/cayenne-server/src/main/java/org/apache/cayenne/exp/parser/ExpressionParser.java b/cayenne-server/src/main/java/org/apache/cayenne/exp/parser/ExpressionParser.java
index 4c710a485..5470adc87 100644
--- a/cayenne-server/src/main/java/org/apache/cayenne/exp/parser/ExpressionParser.java
+++ b/cayenne-server/src/main/java/org/apache/cayenne/exp/parser/ExpressionParser.java
@@ -955,6 +955,14 @@ if (jjtc001) {
       stringExpression();
       break;
       }
+    case FUNCTION:{
+      customFunction();
+      break;
+      }
+    case OPERATOR:{
+      customOperator();
+      break;
+      }
     default:
       jj_la1[15] = jj_gen;
       jj_consume_token(-1);
@@ -3058,7 +3066,7 @@ if (jjtc005) {
 	   jj_la1_1 = new int[] {0x0,0x0,0x0,0xfffffdfe,0x0,0x0,0x0,0x0,0x0,0xfffffdfe,0x0,0x0,0x0,0x0,0xfffffdf2,0x7c00,0x0,0x7c00,0xfffffdfe,0xc,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0xff8f8000,0x0,0xff8f8000,0xff8f8000,0x7c00,0x0,0xff8ffc00,0x0,0xff8ffc00,0x0,0x0,0xff8f8000,0x0,0x1f0,0x200,0x700000,0xff800000,0x0,0xfdfffff0,};
 	}
 	private static void jj_la1_init_2() {
-	   jj_la1_2 = new int[] {0x0,0x0,0x0,0xe402ff,0x0,0x0,0x8,0x0,0x0,0xe402ff,0x0,0x8,0x0,0x0,0xe402ff,0x2402f0,0x240000,0x240000,0xe402ff,0xe40008,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x100,0x100,0xc002ff,0x0,0xc002ff,0xc002ff,0x0,0x0,0xe402ff,0x0,0xe402ff,0x0,0x0,0x1,0x0,0x0,0x3f0,0x0,0x1,0x2f0,0x201,};
+	   jj_la1_2 = new int[] {0x0,0x0,0x0,0xe402ff,0x0,0x0,0x8,0x0,0x0,0xe402ff,0x0,0x8,0x0,0x0,0xe402ff,0x2402f6,0x240000,0x240000,0xe402ff,0xe40008,0x0,0x0,0x0,0x0,0x0,0x0,0x0,0x100,0x100,0xc002ff,0x0,0xc002ff,0xc002ff,0x0,0x0,0xe402ff,0x0,0xe402ff,0x0,0x0,0x1,0x0,0x0,0x3f0,0x0,0x1,0x2f0,0x201,};
 	}
 
   /** Constructor with InputStream. */
diff --git a/cayenne-server/src/main/jjtree/org/apache/cayenne/exp/parser/ExpressionParser.jjt b/cayenne-server/src/main/jjtree/org/apache/cayenne/exp/parser/ExpressionParser.jjt
index 0b3200340..d31bfdcf6 100644
--- a/cayenne-server/src/main/jjtree/org/apache/cayenne/exp/parser/ExpressionParser.jjt
+++ b/cayenne-server/src/main/jjtree/org/apache/cayenne/exp/parser/ExpressionParser.jjt
@@ -151,6 +151,10 @@ void stringParameter() : {}
         pathExpression()
     |
         stringExpression()
+    |
+        customFunction()
+    |
+        customOperator()
 }
 
 void stringLiteral() :  {}
diff --git a/cayenne-server/src/test/java/org/apache/cayenne/exp/parser/ASTCustomFunctionTest.java b/cayenne-server/src/test/java/org/apache/cayenne/exp/parser/ASTCustomFunctionTest.java
index 3ad0d2b25..7843907e1 100644
--- a/cayenne-server/src/test/java/org/apache/cayenne/exp/parser/ASTCustomFunctionTest.java
+++ b/cayenne-server/src/test/java/org/apache/cayenne/exp/parser/ASTCustomFunctionTest.java
@@ -39,6 +39,14 @@ public class ASTCustomFunctionTest {
         assertEquals("fn(\"MY_FUNCTION\", 1, \"abc\")", exp.toString());
     }
 
+    @Test
+    public void testCustomFunctionAsFunctionArg() {
+        Expression exp = ExpressionFactory.exp("length(fn('MY_FUNCTION', 1, 'abc'))");
+        assertTrue(exp instanceof ASTFunctionCall);
+
+        assertEquals("length(fn(\"MY_FUNCTION\", 1, \"abc\"))", exp.toString());
+    }
+
     @Test(expected = ExpressionException.class)
     public void testEvaluate() {
         new ASTCustomFunction("test").evaluate(new Object());


[cayenne] 03/03: CAY-2810 Can't use custom operator expression with aggregate functions

Posted by nt...@apache.org.
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

commit e888fb283f7f8ceb050d6736b52bd893c220acf3
Author: Nikita Timofeev <st...@gmail.com>
AuthorDate: Thu Jul 6 18:17:31 2023 +0300

    CAY-2810 Can't use custom operator expression with aggregate functions
    
    (cherry picked from commit 24b397fd9852cea32ed28ac10b4e8595295434e0)
---
 .../java/org/apache/cayenne/query/ObjectSelect_AggregateIT.java  | 9 +++++++--
 1 file changed, 7 insertions(+), 2 deletions(-)

diff --git a/cayenne-server/src/test/java/org/apache/cayenne/query/ObjectSelect_AggregateIT.java b/cayenne-server/src/test/java/org/apache/cayenne/query/ObjectSelect_AggregateIT.java
index 54a544496..efeecc4df 100644
--- a/cayenne-server/src/test/java/org/apache/cayenne/query/ObjectSelect_AggregateIT.java
+++ b/cayenne-server/src/test/java/org/apache/cayenne/query/ObjectSelect_AggregateIT.java
@@ -35,6 +35,7 @@ import org.apache.cayenne.test.jdbc.DBHelper;
 import org.apache.cayenne.test.jdbc.TableHelper;
 import org.apache.cayenne.testdo.testmap.Artist;
 import org.apache.cayenne.testdo.testmap.Painting;
+import org.apache.cayenne.unit.UnitDbAdapter;
 import org.apache.cayenne.unit.di.server.CayenneProjects;
 import org.apache.cayenne.unit.di.server.ServerCase;
 import org.apache.cayenne.unit.di.server.UseServerRuntime;
@@ -58,6 +59,9 @@ public class ObjectSelect_AggregateIT extends ServerCase {
     @Inject
     private DBHelper dbHelper;
 
+    @Inject
+    private UnitDbAdapter dbAdapter;
+
     // Format: d/m/YY
     DateFormat dateFormat = DateFormat.getDateInstance(DateFormat.SHORT, Locale.US);
 
@@ -163,6 +167,9 @@ public class ObjectSelect_AggregateIT extends ServerCase {
 
     @Test
     public void testGroupByOp() throws Exception {
+        if(!dbAdapter.supportsExpressionInHaving()) {
+            return;
+        }
         List<Object[]> count = ObjectSelect.query(Artist.class)
                 .columns(
                         Artist.ARTIST_NAME.count(),
@@ -172,8 +179,6 @@ public class ObjectSelect_AggregateIT extends ServerCase {
                 .select(context);
         assertEquals(5L, count.size());
         assertEquals(4L, count.get(1)[0]);
-
-
     }
 
     @Test


[cayenne] 02/03: CAY-2810 Can't use custom operator expression with aggregate functions

Posted by nt...@apache.org.
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

commit 76c406ecc3ca2471f73441f9a28350e86fb39d6b
Author: Nikita Timofeev <st...@gmail.com>
AuthorDate: Thu Jul 6 15:33:58 2023 +0300

    CAY-2810 Can't use custom operator expression with aggregate functions
    
    (cherry picked from commit edf9a48e08b831c4f3039146841eb665dc240f57)
---
 RELEASE-NOTES.txt                                  |  1 +
 .../access/sqlbuilder/sqltree/AliasedNode.java     | 31 ++++++++++++++++++++--
 .../cayenne/query/ObjectSelect_AggregateIT.java    | 15 +++++++++++
 3 files changed, 45 insertions(+), 2 deletions(-)

diff --git a/RELEASE-NOTES.txt b/RELEASE-NOTES.txt
index 2be62e069..1954a0dc8 100644
--- a/RELEASE-NOTES.txt
+++ b/RELEASE-NOTES.txt
@@ -17,6 +17,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
 
 ----------------------------------
 Release: 4.2
diff --git a/cayenne-server/src/main/java/org/apache/cayenne/access/sqlbuilder/sqltree/AliasedNode.java b/cayenne-server/src/main/java/org/apache/cayenne/access/sqlbuilder/sqltree/AliasedNode.java
index e6f0e65dc..f6cf638e9 100644
--- a/cayenne-server/src/main/java/org/apache/cayenne/access/sqlbuilder/sqltree/AliasedNode.java
+++ b/cayenne-server/src/main/java/org/apache/cayenne/access/sqlbuilder/sqltree/AliasedNode.java
@@ -19,6 +19,7 @@
 
 package org.apache.cayenne.access.sqlbuilder.sqltree;
 
+import org.apache.cayenne.access.sqlbuilder.NodeTreeVisitor;
 import org.apache.cayenne.access.sqlbuilder.QuotingAppendable;
 
 /**
@@ -39,17 +40,43 @@ public class AliasedNode extends Node {
 
     @Override
     public QuotingAppendable append(QuotingAppendable buffer) {
+        if(skipContent()) {
+            buffer.append(' ').append(alias);
+        }
         return buffer;
     }
 
+    @Override
+    public void visit(NodeTreeVisitor visitor) {
+        if(skipContent()) {
+            visitor.onNodeStart(this);
+            visitor.onNodeEnd(this);
+            return;
+        }
+        super.visit(visitor);
+    }
+
     @Override
     public void appendChildrenEnd(QuotingAppendable buffer) {
-        super.appendChildrenEnd(buffer);
-        buffer.append(' ').append(alias);
+        if(skipContent()){
+            return;
+        }
+        buffer.append(" AS ").append(alias);
     }
 
     public String getAlias() {
         return alias;
     }
 
+    private boolean skipContent() {
+        // check if parent is of type RESULT
+        Node parent = getParent();
+        while(parent != null) {
+            if(parent.getType() == NodeType.RESULT) {
+                return false;
+            }
+            parent = parent.getParent();
+        }
+        return true;
+    }
 }
diff --git a/cayenne-server/src/test/java/org/apache/cayenne/query/ObjectSelect_AggregateIT.java b/cayenne-server/src/test/java/org/apache/cayenne/query/ObjectSelect_AggregateIT.java
index 6c0943d52..54a544496 100644
--- a/cayenne-server/src/test/java/org/apache/cayenne/query/ObjectSelect_AggregateIT.java
+++ b/cayenne-server/src/test/java/org/apache/cayenne/query/ObjectSelect_AggregateIT.java
@@ -161,6 +161,21 @@ public class ObjectSelect_AggregateIT extends ServerCase {
         assertEquals(date, count.get(1)[1]);
     }
 
+    @Test
+    public void testGroupByOp() throws Exception {
+        List<Object[]> count = ObjectSelect.query(Artist.class)
+                .columns(
+                        Artist.ARTIST_NAME.count(),
+                        Artist.DATE_OF_BIRTH.dayOfMonth().add(1).alias("op")
+                )
+                .orderBy(Artist.DATE_OF_BIRTH.asc())
+                .select(context);
+        assertEquals(5L, count.size());
+        assertEquals(4L, count.get(1)[0]);
+
+
+    }
+
     @Test
     public void testSelectRelationshipCount() throws Exception {
         long count = ObjectSelect.query(Artist.class)