From a3acc2cd896887f8d7cfca469d873a2af0bebc5e Mon Sep 17 00:00:00 2001 From: Radek Felcman Date: Wed, 13 Nov 2024 17:27:29 +0100 Subject: [PATCH] ID(this) is not accepted as an argument to a function - bugfix + tests (#2287) * ID(this) is not accepted as an argument to a function - bugfix + tests Signed-off-by: Radek Felcman --- .../JUnitJPQLJakartaDataNoAliasTest.java | 29 +++++++++ .../jpa/jpql/parser/JPQLGrammar3_2.java | 2 + .../jpa/tests/jpql/JPQLQueries3_2.java | 17 +++++ .../tests/jpql/parser/JPQLQueriesTest3_2.java | 63 +++++++++++++++++++ 4 files changed, 111 insertions(+) diff --git a/jpa/eclipselink.jpa.testapps/jpa.test.jpql/src/test/java/org/eclipse/persistence/testing/tests/jpa/jpql/advanced/JUnitJPQLJakartaDataNoAliasTest.java b/jpa/eclipselink.jpa.testapps/jpa.test.jpql/src/test/java/org/eclipse/persistence/testing/tests/jpa/jpql/advanced/JUnitJPQLJakartaDataNoAliasTest.java index 80fab887eb4..66c726b3fe0 100644 --- a/jpa/eclipselink.jpa.testapps/jpa.test.jpql/src/test/java/org/eclipse/persistence/testing/tests/jpa/jpql/advanced/JUnitJPQLJakartaDataNoAliasTest.java +++ b/jpa/eclipselink.jpa.testapps/jpa.test.jpql/src/test/java/org/eclipse/persistence/testing/tests/jpa/jpql/advanced/JUnitJPQLJakartaDataNoAliasTest.java @@ -115,6 +115,8 @@ public static Test suite() { suite.addTest(new JUnitJPQLJakartaDataNoAliasTest("testSelectQueryImplicitThisVariableInArithmeticExpression")); suite.addTest(new JUnitJPQLJakartaDataNoAliasTest("testSelectQueryImplicitThisVariableAndEnum")); suite.addTest(new JUnitJPQLJakartaDataNoAliasTest("testSelectQueryImplicitThisVariableAndRelationalAttributes")); + suite.addTest(new JUnitJPQLJakartaDataNoAliasTest("testSelectQueryIdFunctionNestedInArithmeticFunction_Where")); + suite.addTest(new JUnitJPQLJakartaDataNoAliasTest("testSelectQueryIdFunctionNestedInStringFunction_Where")); suite.addTest(new JUnitJPQLJakartaDataNoAliasTest("testUpdateImplicitVariableInArithmeticExpression")); suite.addTest(new JUnitJPQLJakartaDataNoAliasTest("testDeleteQueryLengthInExpressionOnLeft")); suite.addTest(new JUnitJPQLJakartaDataNoAliasTest("testDeleteQueryLengthInExpressionOnRight")); @@ -386,6 +388,33 @@ public void testSelectQueryImplicitThisVariableAndEnum() { assertEquals(ROOMS[1], rooms.get(0)); } + // Covers https://github.com/eclipse-ee4j/eclipselink/issues/2286 + public void testSelectQueryIdFunctionNestedInArithmeticFunction_Where() { + final String typeName = getPlatform().isMySQL() ? "UNSIGNED": "INTEGER"; + resetRooms(false); + Room room = getEntityManagerFactory().callInTransaction(em -> em.createQuery( + "SELECT this " + + "FROM Room " + + "WHERE ABS(CAST(ID(this) AS " + typeName + "))= :idParam", + Room.class) + .setParameter("idParam", ROOMS[1].getId()) + .getSingleResult()); + assertEquals(ROOMS[1], room); + } + + // Covers https://github.com/eclipse-ee4j/eclipselink/issues/2286 + public void testSelectQueryIdFunctionNestedInStringFunction_Where() { + resetRooms(false); + Room room = getEntityManagerFactory().callInTransaction(em -> em.createQuery( + "SELECT this " + + "FROM Room " + + "WHERE LOWER(CAST(ID(this) AS CHAR))= :idParam", + Room.class) + .setParameter("idParam", String.valueOf(ROOMS[1].getId())) + .getSingleResult()); + assertEquals(ROOMS[1], room); + } + // Covers https://github.com/eclipse-ee4j/eclipselink/issues/2188 public void testSelectQueryImplicitThisVariableAndRelationalAttributes() { resetRooms(false); diff --git a/jpa/org.eclipse.persistence.jpa.jpql/src/main/java/org/eclipse/persistence/jpa/jpql/parser/JPQLGrammar3_2.java b/jpa/org.eclipse.persistence.jpa.jpql/src/main/java/org/eclipse/persistence/jpa/jpql/parser/JPQLGrammar3_2.java index d437aeb0526..86b5058e297 100644 --- a/jpa/org.eclipse.persistence.jpa.jpql/src/main/java/org/eclipse/persistence/jpa/jpql/parser/JPQLGrammar3_2.java +++ b/jpa/org.eclipse.persistence.jpa.jpql/src/main/java/org/eclipse/persistence/jpa/jpql/parser/JPQLGrammar3_2.java @@ -143,12 +143,14 @@ protected void initializeBNFs() { // ID function addChildBNF(SelectExpressionBNF.ID, IdExpressionBNF.ID); addChildBNF(ComparisonExpressionBNF.ID, IdExpressionBNF.ID); + addChildBNF(ScalarExpressionBNF.ID, IdExpressionBNF.ID); addChildBNF(IdExpressionBNF.ID, GeneralIdentificationVariableBNF.ID); addChildBNF(IdExpressionBNF.ID, SingleValuedObjectPathExpressionBNF.ID); // VERSION function addChildBNF(SelectExpressionBNF.ID, VersionExpressionBNF.ID); addChildBNF(ComparisonExpressionBNF.ID, VersionExpressionBNF.ID); + addChildBNF(ScalarExpressionBNF.ID, VersionExpressionBNF.ID); } @Override diff --git a/jpa/org.eclipse.persistence.jpa.jpql/src/test/java/org/eclipse/persistence/jpa/tests/jpql/JPQLQueries3_2.java b/jpa/org.eclipse.persistence.jpa.jpql/src/test/java/org/eclipse/persistence/jpa/tests/jpql/JPQLQueries3_2.java index aae04a420e8..fe8c0a434fb 100644 --- a/jpa/org.eclipse.persistence.jpa.jpql/src/test/java/org/eclipse/persistence/jpa/tests/jpql/JPQLQueries3_2.java +++ b/jpa/org.eclipse.persistence.jpa.jpql/src/test/java/org/eclipse/persistence/jpa/tests/jpql/JPQLQueries3_2.java @@ -111,6 +111,14 @@ public static String query_IdFunction_Where() { return "SELECT c FROM Customer c WHERE ID(c) = 1"; } + public static String query_IdFunctionNestedInArithmeticFunction_Where() { + return "SELECT this FROM Customer this WHERE ABS(CAST(ID(this) AS INTEGER)) = 1"; + } + + public static String query_IdFunctionNestedInStringFunction_Where() { + return "SELECT this FROM Customer this WHERE LOWER(CAST(ID(this) AS STRING)) = 'abc'"; + } + public static String query_VersionFunction_Select01() { return "SELECT VERSION(c) FROM Customer c"; } @@ -118,4 +126,13 @@ public static String query_VersionFunction_Select01() { public static String query_VersionFunction_Where() { return "SELECT c FROM Customer c WHERE VERSION(c) = 1"; } + + public static String query_VersionFunctionNestedInArithmeticFunction_Where() { + return "SELECT this FROM Customer this WHERE ABS(CAST(VERSION(this) AS INTEGER)) = 1"; + } + + public static String query_VersionFunctionNestedInStringFunction_Where() { + return "SELECT this FROM Customer this WHERE LOWER(CAST(VERSION(this) AS STRING)) = '1'"; + } + } diff --git a/jpa/org.eclipse.persistence.jpa.jpql/src/test/java/org/eclipse/persistence/jpa/tests/jpql/parser/JPQLQueriesTest3_2.java b/jpa/org.eclipse.persistence.jpa.jpql/src/test/java/org/eclipse/persistence/jpa/tests/jpql/parser/JPQLQueriesTest3_2.java index 9ed684acaed..0fb0e0c7dd2 100644 --- a/jpa/org.eclipse.persistence.jpa.jpql/src/test/java/org/eclipse/persistence/jpa/tests/jpql/parser/JPQLQueriesTest3_2.java +++ b/jpa/org.eclipse.persistence.jpa.jpql/src/test/java/org/eclipse/persistence/jpa/tests/jpql/parser/JPQLQueriesTest3_2.java @@ -24,6 +24,8 @@ import static org.eclipse.persistence.jpa.tests.jpql.JPQLQueries3_2.query_ConcatPipes_Where; import static org.eclipse.persistence.jpa.tests.jpql.JPQLQueries3_2.query_IdFunction_Select01; import static org.eclipse.persistence.jpa.tests.jpql.JPQLQueries3_2.query_IdFunction_Where; +import static org.eclipse.persistence.jpa.tests.jpql.JPQLQueries3_2.query_IdFunctionNestedInArithmeticFunction_Where; +import static org.eclipse.persistence.jpa.tests.jpql.JPQLQueries3_2.query_IdFunctionNestedInStringFunction_Where; import static org.eclipse.persistence.jpa.tests.jpql.JPQLQueries3_2.query_LeftFunction_Select01; import static org.eclipse.persistence.jpa.tests.jpql.JPQLQueries3_2.query_LeftFunction_Select02; import static org.eclipse.persistence.jpa.tests.jpql.JPQLQueries3_2.query_LeftFunction_Select03; @@ -39,7 +41,11 @@ import static org.eclipse.persistence.jpa.tests.jpql.JPQLQueries3_2.query_RightFunction_Where; import static org.eclipse.persistence.jpa.tests.jpql.JPQLQueries3_2.query_VersionFunction_Select01; import static org.eclipse.persistence.jpa.tests.jpql.JPQLQueries3_2.query_VersionFunction_Where; +import static org.eclipse.persistence.jpa.tests.jpql.JPQLQueries3_2.query_VersionFunctionNestedInArithmeticFunction_Where; +import static org.eclipse.persistence.jpa.tests.jpql.JPQLQueries3_2.query_VersionFunctionNestedInStringFunction_Where; import static org.eclipse.persistence.jpa.tests.jpql.JPQLQueries3_2.query_Union01; +import static org.eclipse.persistence.jpa.tests.jpql.parser.JPQLParserTester.abs; +import static org.eclipse.persistence.jpa.tests.jpql.parser.JPQLParserTester.castAs; import static org.eclipse.persistence.jpa.tests.jpql.parser.JPQLParserTester.concatPipes; import static org.eclipse.persistence.jpa.tests.jpql.parser.JPQLParserTester.count; import static org.eclipse.persistence.jpa.tests.jpql.parser.JPQLParserTester.except; @@ -50,6 +56,7 @@ import static org.eclipse.persistence.jpa.tests.jpql.parser.JPQLParserTester.intersect; import static org.eclipse.persistence.jpa.tests.jpql.parser.JPQLParserTester.left; import static org.eclipse.persistence.jpa.tests.jpql.parser.JPQLParserTester.leftJoin; +import static org.eclipse.persistence.jpa.tests.jpql.parser.JPQLParserTester.lower; import static org.eclipse.persistence.jpa.tests.jpql.parser.JPQLParserTester.numeric; import static org.eclipse.persistence.jpa.tests.jpql.parser.JPQLParserTester.path; import static org.eclipse.persistence.jpa.tests.jpql.parser.JPQLParserTester.replace; @@ -412,6 +419,34 @@ public final void test_Query_IdFunction_Where() { testQuery(query_IdFunction_Where(), selectStatement); } + @Test + public final void test_Query_IdFunctionNestedInArithmeticFunction_Where() { + //SELECT this + // FROM Customer this + // WHERE ABS(CAST(ID(this) AS INTEGER)) = 1" + + ExpressionTester selectStatement = selectStatement( + select(variable("this")), + from("Customer", "this"), + where(abs(castAs(id("this"), "INTEGER")).equal(numeric(1)))); + + testQuery(query_IdFunctionNestedInArithmeticFunction_Where(), selectStatement); + } + + @Test + public final void test_Query_IdFunctionNestedInStringFunction_Where() { + // SELECT this + // FROM Customer this + // WHERE LOWER(CAST(ID(this) AS STRING)) = 'a' + + ExpressionTester selectStatement = selectStatement( + select(variable("this")), + from("Customer", "this"), + where(lower(castAs(id("this"), "STRING")).equal(string("'abc'")))); + + testQuery(query_IdFunctionNestedInStringFunction_Where(), selectStatement); + } + @Test public final void test_Query_VersionFunction_Select01() { // select version(c) @@ -437,4 +472,32 @@ public final void test_Query_VersionFunction_Where() { testQuery(query_VersionFunction_Where(), selectStatement); } + + @Test + public final void test_Query_VersionFunctionNestedInArithmeticFunction_Where() { + //SELECT this + // FROM Customer this + // WHERE ABS(CAST(VERSION(this) AS INTEGER)) = 1" + + ExpressionTester selectStatement = selectStatement( + select(variable("this")), + from("Customer", "this"), + where(abs(castAs(version("this"), "INTEGER")).equal(numeric(1)))); + + testQuery(query_VersionFunctionNestedInArithmeticFunction_Where(), selectStatement); + } + + @Test + public final void test_Query_VersionFunctionNestedInStringFunction_Where() { + // SELECT this + // FROM Customer this + // WHERE LOWER(CAST(VERSION(this) AS STRING)) = '1' + + ExpressionTester selectStatement = selectStatement( + select(variable("this")), + from("Customer", "this"), + where(lower(castAs(version("this"), "STRING")).equal(string("'1'")))); + + testQuery(query_VersionFunctionNestedInStringFunction_Where(), selectStatement); + } }