diff --git a/foundation/org.eclipse.persistence.core/src/main/java/org/eclipse/persistence/config/ParserValidationType.java b/foundation/org.eclipse.persistence.core/src/main/java/org/eclipse/persistence/config/ParserValidationType.java index 7a63661daa2..c67b363335a 100644 --- a/foundation/org.eclipse.persistence.core/src/main/java/org/eclipse/persistence/config/ParserValidationType.java +++ b/foundation/org.eclipse.persistence.core/src/main/java/org/eclipse/persistence/config/ParserValidationType.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012, 2022 Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2012, 2023 Oracle and/or its affiliates. All rights reserved. * * This program and the accompanying materials are made available under the * terms of the Eclipse Public License v. 2.0 which is available at @@ -14,6 +14,8 @@ // Oracle - initial API and implementation from Oracle TopLink // 04/21/2022: Tomas Kraus // - Issue 1474: Update JPQL Grammar for Jakarta Persistence 2.2, 3.0 and 3.1 +// 06/02/2023: Radek Felcman +// - Issue 1885: Implement new JPQLGrammar for upcoming Jakarta Persistence 3.2 package org.eclipse.persistence.config; /** @@ -34,6 +36,7 @@ public class ParserValidationType { public static final String JPA22 = "JPA 2.2"; public static final String JPA30 = "JPA 3.0"; public static final String JPA31 = "JPA 3.1"; + public static final String JPA32 = "JPA 3.2"; public static final String None = "None"; public static final String DEFAULT = EclipseLink; diff --git a/foundation/org.eclipse.persistence.core/src/main/java/org/eclipse/persistence/expressions/ExpressionOperator.java b/foundation/org.eclipse.persistence.core/src/main/java/org/eclipse/persistence/expressions/ExpressionOperator.java index 43d060ca902..cc679f632d7 100644 --- a/foundation/org.eclipse.persistence.core/src/main/java/org/eclipse/persistence/expressions/ExpressionOperator.java +++ b/foundation/org.eclipse.persistence.core/src/main/java/org/eclipse/persistence/expressions/ExpressionOperator.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 1998, 2022 Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 1998, 2023 Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2018, 2022 IBM Corporation. All rights reserved. * * This program and the accompanying materials are made available under the @@ -20,6 +20,8 @@ // - 530214: trim operation should not bind parameters // 02/01/2022: Tomas Kraus // - Issue 1442: Implement New Jakarta Persistence 3.1 Features +// 06/02/2023: Radek Felcman +// - Issue 1885: Implement new JPQLGrammar for upcoming Jakarta Persistence 3.2 package org.eclipse.persistence.expressions; import java.io.Serializable; @@ -260,6 +262,9 @@ public class ExpressionOperator implements Serializable { public static final int Cot = 95; public static final int Negate = 135; + // String + public static final int ConcatPipes = 152; + // Object-relational public static final int Deref = 82; public static final int Ref = 83; @@ -736,6 +741,16 @@ public static ExpressionOperator concat() { return operator; } + /** + * INTERNAL: + * Build operator. + */ + public static ExpressionOperator concatPipes() { + ExpressionOperator operator = simpleMath(ConcatPipes, "||"); + operator.setIsBindingSupported(false); + return operator; + } + /** * INTERNAL: * Compare between in memory. diff --git a/foundation/org.eclipse.persistence.core/src/main/java/org/eclipse/persistence/expressions/ExpressionString.java b/foundation/org.eclipse.persistence.core/src/main/java/org/eclipse/persistence/expressions/ExpressionString.java new file mode 100644 index 00000000000..4e68bf311a0 --- /dev/null +++ b/foundation/org.eclipse.persistence.core/src/main/java/org/eclipse/persistence/expressions/ExpressionString.java @@ -0,0 +1,42 @@ +/* + * Copyright (c) 2023 Oracle and/or its affiliates. All rights reserved. + * + * This program and the accompanying materials are made available under the + * terms of the Eclipse Public License v. 2.0 which is available at + * http://www.eclipse.org/legal/epl-2.0, + * or the Eclipse Distribution License v. 1.0 which is available at + * http://www.eclipse.org/org/documents/edl-v10.php. + * + * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause + */ + +// Contributors: +// Oracle - initial API and implementation +// 06/02/2023: Radek Felcman +// - Issue 1885: Implement new JPQLGrammar for upcoming Jakarta Persistence 3.2 +package org.eclipse.persistence.expressions; + +/** + *
+ * Purpose: This class contains String operators.
+ *Example: + *
+ */ +public final class ExpressionString { + + private ExpressionString() { + } + + /** + * PUBLIC: + * Return a new expression that applies the function to the given expression. + */ + public static Expression concatPipes(Expression right, Object left) { + ExpressionOperator anOperator = Expression.getOperator(ExpressionOperator.ConcatPipes); + return anOperator.expressionFor(right, left); + } +} diff --git a/foundation/org.eclipse.persistence.core/src/main/java/org/eclipse/persistence/internal/databaseaccess/DatasourcePlatform.java b/foundation/org.eclipse.persistence.core/src/main/java/org/eclipse/persistence/internal/databaseaccess/DatasourcePlatform.java index 8215fd154e6..11f4e7c5f16 100644 --- a/foundation/org.eclipse.persistence.core/src/main/java/org/eclipse/persistence/internal/databaseaccess/DatasourcePlatform.java +++ b/foundation/org.eclipse.persistence.core/src/main/java/org/eclipse/persistence/internal/databaseaccess/DatasourcePlatform.java @@ -21,6 +21,8 @@ // - 529602: Added support for CLOBs in DELETE statements for Oracle // 02/01/2022: Tomas Kraus // - Issue 1442: Implement New Jakarta Persistence 3.1 Features +// 06/02/2023: Radek Felcman +// - Issue 1885: Implement new JPQLGrammar for upcoming Jakarta Persistence 3.2 package org.eclipse.persistence.internal.databaseaccess; import java.io.IOException; @@ -452,6 +454,7 @@ protected void initializePlatformOperators() { addOperator(ExpressionOperator.toLowerCase()); addOperator(ExpressionOperator.chr()); addOperator(ExpressionOperator.concat()); + addOperator(ExpressionOperator.concatPipes()); addOperator(ExpressionOperator.hexToRaw()); addOperator(ExpressionOperator.initcap()); addOperator(ExpressionOperator.instring()); diff --git a/foundation/org.eclipse.persistence.core/src/main/java/org/eclipse/persistence/internal/jpa/jpql/ExpressionBuilderVisitor.java b/foundation/org.eclipse.persistence.core/src/main/java/org/eclipse/persistence/internal/jpa/jpql/ExpressionBuilderVisitor.java index c8b9e9fca47..f1b48917099 100644 --- a/foundation/org.eclipse.persistence.core/src/main/java/org/eclipse/persistence/internal/jpa/jpql/ExpressionBuilderVisitor.java +++ b/foundation/org.eclipse.persistence.core/src/main/java/org/eclipse/persistence/internal/jpa/jpql/ExpressionBuilderVisitor.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2006, 2022 Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2006, 2023 Oracle and/or its affiliates. All rights reserved. * Copyright (c) 2006, 2021 IBM Corporation. All rights reserved. * * This program and the accompanying materials are made available under the @@ -24,6 +24,8 @@ // 04/21/2022: Tomas Kraus // - Issue 1474: Update JPQL Grammar for Jakarta Persistence 2.2, 3.0 and 3.1 // - Issue 317: Implement LOCAL DATE, LOCAL TIME and LOCAL DATETIME. +// 06/02/2023: Radek Felcman +// - Issue 1885: Implement new JPQLGrammar for upcoming Jakarta Persistence 3.2 package org.eclipse.persistence.internal.jpa.jpql; import java.sql.Date; @@ -78,6 +80,7 @@ import org.eclipse.persistence.jpa.jpql.parser.CollectionValuedPathExpression; import org.eclipse.persistence.jpa.jpql.parser.ComparisonExpression; import org.eclipse.persistence.jpa.jpql.parser.ConcatExpression; +import org.eclipse.persistence.jpa.jpql.parser.ConcatPipesExpression; import org.eclipse.persistence.jpa.jpql.parser.ConnectByClause; import org.eclipse.persistence.jpa.jpql.parser.ConstructorExpression; import org.eclipse.persistence.jpa.jpql.parser.CountFunction; @@ -797,6 +800,31 @@ public void visit(ConcatExpression expression) { type[0] = String.class; } + @Override + public void visit(ConcatPipesExpression expression) { + //Convert || string operator into function CONCAT() as not every DB supports it + //but DB platform should translate it into platform valid SQL + List+ * ExpressionBuilder builder = new ExpressionBuilder(); + * Expression stringResult = ExpressionString.concatPipes("abcd", "xyz"); + * session.readAllObjects(Company.class, stringResult); + *
string_expression ::= string_expression || string_term
ConcatExpressionPipes
.
+ *
+ * @param parent The parent of this expression
+ */
+ public ConcatPipesExpression(AbstractExpression parent) {
+ super(parent, CONCAT_PIPES);
+ }
+
+ @Override
+ public void accept(ExpressionVisitor visitor) {
+ visitor.visit(this);
+ }
+}
diff --git a/jpa/org.eclipse.persistence.jpa.jpql/src/main/java/org/eclipse/persistence/jpa/jpql/parser/DefaultEclipseLinkJPQLGrammar.java b/jpa/org.eclipse.persistence.jpa.jpql/src/main/java/org/eclipse/persistence/jpa/jpql/parser/DefaultEclipseLinkJPQLGrammar.java
index f0ac88d7537..4e3e738234c 100644
--- a/jpa/org.eclipse.persistence.jpa.jpql/src/main/java/org/eclipse/persistence/jpa/jpql/parser/DefaultEclipseLinkJPQLGrammar.java
+++ b/jpa/org.eclipse.persistence.jpa.jpql/src/main/java/org/eclipse/persistence/jpa/jpql/parser/DefaultEclipseLinkJPQLGrammar.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2006, 2022 Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2006, 2023 Oracle and/or its affiliates. All rights reserved.
*
* This program and the accompanying materials are made available under the
* terms of the Eclipse Public License v. 2.0 which is available at
@@ -14,6 +14,8 @@
// Oracle - initial API and implementation
// 04/21/2022: Tomas Kraus
// - Issue 1474: Update JPQL Grammar for Jakarta Persistence 2.2, 3.0 and 3.1
+// 06/02/2023: Radek Felcman
+// - Issue 1885: Implement new JPQLGrammar for upcoming Jakarta Persistence 3.2
package org.eclipse.persistence.jpa.jpql.parser;
import org.eclipse.persistence.jpa.jpql.JPAVersion;
@@ -53,7 +55,7 @@ private DefaultEclipseLinkJPQLGrammar() {
* @return The latest {@link JPQLGrammar} that supports EclipseLink
*/
public static JPQLGrammar instance() {
- return EclipseLinkJPQLGrammar4_0.instance();
+ return EclipseLinkJPQLGrammar4_1.instance();
}
@Override
diff --git a/jpa/org.eclipse.persistence.jpa.jpql/src/main/java/org/eclipse/persistence/jpa/jpql/parser/DefaultJPQLGrammar.java b/jpa/org.eclipse.persistence.jpa.jpql/src/main/java/org/eclipse/persistence/jpa/jpql/parser/DefaultJPQLGrammar.java
index 84bf9cea2c7..40a0fbf41eb 100644
--- a/jpa/org.eclipse.persistence.jpa.jpql/src/main/java/org/eclipse/persistence/jpa/jpql/parser/DefaultJPQLGrammar.java
+++ b/jpa/org.eclipse.persistence.jpa.jpql/src/main/java/org/eclipse/persistence/jpa/jpql/parser/DefaultJPQLGrammar.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2006, 2022 Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2006, 2023 Oracle and/or its affiliates. All rights reserved.
*
* This program and the accompanying materials are made available under the
* terms of the Eclipse Public License v. 2.0 which is available at
@@ -14,6 +14,8 @@
// Oracle - initial API and implementation
// 04/21/2022: Tomas Kraus
// - Issue 1474: Update JPQL Grammar for Jakarta Persistence 2.2, 3.0 and 3.1
+// 06/02/2023: Radek Felcman
+// - Issue 1885: Implement new JPQLGrammar for upcoming Jakarta Persistence 3.2
package org.eclipse.persistence.jpa.jpql.parser;
import org.eclipse.persistence.jpa.jpql.ExpressionTools;
@@ -54,7 +56,7 @@ private DefaultJPQLGrammar() {
* @return The singleton instance of this {@link DefaultJPQLGrammar}
*/
public static JPQLGrammar instance() {
- return JPQLGrammar3_1.instance();
+ return JPQLGrammar3_2.instance();
}
@Override
diff --git a/jpa/org.eclipse.persistence.jpa.jpql/src/main/java/org/eclipse/persistence/jpa/jpql/parser/EclipseLinkJPQLGrammar4_1.java b/jpa/org.eclipse.persistence.jpa.jpql/src/main/java/org/eclipse/persistence/jpa/jpql/parser/EclipseLinkJPQLGrammar4_1.java
new file mode 100644
index 00000000000..51a92a4f0ac
--- /dev/null
+++ b/jpa/org.eclipse.persistence.jpa.jpql/src/main/java/org/eclipse/persistence/jpa/jpql/parser/EclipseLinkJPQLGrammar4_1.java
@@ -0,0 +1,119 @@
+/*
+ * Copyright (c) 2023 Oracle and/or its affiliates. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0,
+ * or the Eclipse Distribution License v. 1.0 which is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ *
+ * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
+ */
+
+// Contributors:
+// 06/02/2023: Radek Felcman
+// - Issue 1885: Implement new JPQLGrammar for upcoming Jakarta Persistence 3.2
+package org.eclipse.persistence.jpa.jpql.parser;
+
+import org.eclipse.persistence.jpa.jpql.EclipseLinkVersion;
+import org.eclipse.persistence.jpa.jpql.JPAVersion;
+
+/**
+ * This {@link JPQLGrammar} provides support for parsing JPQL queries defined + * in Jakarta Persistence 3.2 and the additional support provided by EclipseLink 4.1.
+ */ +public class EclipseLinkJPQLGrammar4_1 extends AbstractJPQLGrammar { + + /** + * The singleton instance of this {@link EclipseLinkJPQLGrammar4_1}. + */ + private static final JPQLGrammar INSTANCE = new EclipseLinkJPQLGrammar4_1(); + + /** + * The EclipseLink version, which is 4.1. + */ + public static final EclipseLinkVersion VERSION = EclipseLinkVersion.VERSION_4_1; + + /** + * Creates a newEclipseLinkJPQLGrammar4_0
.
+ */
+ public EclipseLinkJPQLGrammar4_1() {
+ super();
+ }
+
+ /**
+ * Creates a new EclipseLinkJPQLGrammar4_0
.
+ *
+ * @param jpqlGrammar The {@link JPQLGrammar} to extend with the content of this one without
+ * instantiating the base {@link JPQLGrammar}
+ */
+ public EclipseLinkJPQLGrammar4_1(AbstractJPQLGrammar jpqlGrammar) {
+ super(jpqlGrammar);
+ }
+
+ /**
+ * Extends the given {@link JPQLGrammar} with the information of this one without instantiating
+ * the base {@link JPQLGrammar}.
+ *
+ * @param jpqlGrammar The {@link JPQLGrammar} to extend with the content of this one without
+ * instantiating the base {@link JPQLGrammar}
+ */
+ public static void extend(AbstractJPQLGrammar jpqlGrammar) {
+ new EclipseLinkJPQLGrammar4_1(jpqlGrammar);
+ }
+
+ /**
+ * Returns the singleton instance of this class.
+ *
+ * @return The singleton instance of {@link EclipseLinkJPQLGrammar4_1}
+ */
+ public static JPQLGrammar instance() {
+ return INSTANCE;
+ }
+
+ @Override
+ protected JPQLGrammar buildBaseGrammar() {
+ // First build the JPQL 3.2 grammar
+ JPQLGrammar3_2 jpqlGrammar = new JPQLGrammar3_2();
+ // Extend it by adding the EclipseLink 2.0 - 4.0 additional support
+ EclipseLinkJPQLGrammar2_0.extend(jpqlGrammar);
+ EclipseLinkJPQLGrammar2_1.extend(jpqlGrammar);
+ EclipseLinkJPQLGrammar2_4.extend(jpqlGrammar);
+ EclipseLinkJPQLGrammar2_5.extend(jpqlGrammar);
+ EclipseLinkJPQLGrammar4_0.extend(jpqlGrammar);
+ return jpqlGrammar;
+ }
+
+ @Override
+ public JPAVersion getJPAVersion() {
+ return JPAVersion.VERSION_3_2;
+ }
+
+ @Override
+ public String getProvider() {
+ return DefaultEclipseLinkJPQLGrammar.PROVIDER_NAME;
+ }
+
+ @Override
+ public String getProviderVersion() {
+ return VERSION.getVersion();
+ }
+
+ @Override
+ protected void initializeBNFs() {
+ }
+
+ @Override
+ protected void initializeExpressionFactories() {
+ }
+
+ @Override
+ protected void initializeIdentifiers() {
+ }
+
+ @Override
+ public String toString() {
+ return "EclipseLink 4.1";
+ }
+
+}
diff --git a/jpa/org.eclipse.persistence.jpa.jpql/src/main/java/org/eclipse/persistence/jpa/jpql/parser/Expression.java b/jpa/org.eclipse.persistence.jpa.jpql/src/main/java/org/eclipse/persistence/jpa/jpql/parser/Expression.java
index ae6bd40d73e..fea393b5587 100644
--- a/jpa/org.eclipse.persistence.jpa.jpql/src/main/java/org/eclipse/persistence/jpa/jpql/parser/Expression.java
+++ b/jpa/org.eclipse.persistence.jpa.jpql/src/main/java/org/eclipse/persistence/jpa/jpql/parser/Expression.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2006, 2022 Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2006, 2023 Oracle and/or its affiliates. All rights reserved.
*
* This program and the accompanying materials are made available under the
* terms of the Eclipse Public License v. 2.0 which is available at
@@ -15,6 +15,8 @@
// 04/21/2022: Tomas Kraus
// - Issue 1474: Update JPQL Grammar for Jakarta Persistence 2.2, 3.0 and 3.1
// - Issue 317: Implement LOCAL DATE, LOCAL TIME and LOCAL DATETIME.
+// 06/02/2023: Radek Felcman
+// - Issue 1885: Implement new JPQLGrammar for upcoming Jakarta Persistence 3.2
package org.eclipse.persistence.jpa.jpql.parser;
import org.eclipse.persistence.jpa.jpql.utility.iterable.ListIterable;
@@ -141,6 +143,11 @@ public interface Expression {
*/
String CONCAT = "CONCAT";
+ /**
+ * The constant for String concat operation like SQL '||'.
+ */
+ String CONCAT_PIPES = "||";
+
/**
* The constant for 'CONNECT BY'.
*
diff --git a/jpa/org.eclipse.persistence.jpa.jpql/src/main/java/org/eclipse/persistence/jpa/jpql/parser/ExpressionVisitor.java b/jpa/org.eclipse.persistence.jpa.jpql/src/main/java/org/eclipse/persistence/jpa/jpql/parser/ExpressionVisitor.java
index 5a5ee4f7888..5b7c4dd720f 100644
--- a/jpa/org.eclipse.persistence.jpa.jpql/src/main/java/org/eclipse/persistence/jpa/jpql/parser/ExpressionVisitor.java
+++ b/jpa/org.eclipse.persistence.jpa.jpql/src/main/java/org/eclipse/persistence/jpa/jpql/parser/ExpressionVisitor.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2006, 2022 Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2006, 2023 Oracle and/or its affiliates. All rights reserved.
*
* This program and the accompanying materials are made available under the
* terms of the Eclipse Public License v. 2.0 which is available at
@@ -15,6 +15,8 @@
// 04/21/2022: Tomas Kraus
// - Issue 1474: Update JPQL Grammar for Jakarta Persistence 2.2, 3.0 and 3.1
// - Issue 317: Implement LOCAL DATE, LOCAL TIME and LOCAL DATETIME.
+// 06/02/2023: Radek Felcman
+// - Issue 1885: Implement new JPQLGrammar for upcoming Jakarta Persistence 3.2
package org.eclipse.persistence.jpa.jpql.parser;
/**
@@ -149,6 +151,13 @@ public interface ExpressionVisitor {
*/
void visit(ConcatExpression expression);
+ /**
+ * Visits the {@link ConcatPipesExpression} expression.
+ *
+ * @param expression The {@link Expression} to visit
+ */
+ void visit(ConcatPipesExpression expression);
+
/**
* Visits the {@link ConstructorExpression} expression.
*
diff --git a/jpa/org.eclipse.persistence.jpa.jpql/src/main/java/org/eclipse/persistence/jpa/jpql/parser/JPQLGrammar.java b/jpa/org.eclipse.persistence.jpa.jpql/src/main/java/org/eclipse/persistence/jpa/jpql/parser/JPQLGrammar.java
index 7ead87988bf..3fcb73ac8c5 100644
--- a/jpa/org.eclipse.persistence.jpa.jpql/src/main/java/org/eclipse/persistence/jpa/jpql/parser/JPQLGrammar.java
+++ b/jpa/org.eclipse.persistence.jpa.jpql/src/main/java/org/eclipse/persistence/jpa/jpql/parser/JPQLGrammar.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2011, 2020 Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2011, 2023 Oracle and/or its affiliates. All rights reserved.
*
* This program and the accompanying materials are made available under the
* terms of the Eclipse Public License v. 2.0 which is available at
@@ -12,7 +12,8 @@
// Contributors:
// Oracle - initial API and implementation
-//
+// 06/02/2023: Radek Felcman
+// - Issue 1885: Implement new JPQLGrammar for upcoming Jakarta Persistence 3.2
package org.eclipse.persistence.jpa.jpql.parser;
import org.eclipse.persistence.jpa.jpql.JPAVersion;
@@ -28,6 +29,10 @@
*
+ *
+ * string_expression ::= string_expression || string_term
+ *
+ *
+ */
+public class JPQLGrammar3_2 extends AbstractJPQLGrammar {
+
+ /**
+ * The singleton instance of this {@link JPQLGrammar3_2}.
+ */
+ private static final JPQLGrammar INSTANCE = new JPQLGrammar3_2();
+
+ /**
+ * Creates an insance of Jakarta Persistence 3.1 JPQL grammar.
+ */
+ public JPQLGrammar3_2() {
+ super();
+ }
+
+ /**
+ * Creates an instance of Jakarta Persistence 3.2 JPQL grammar.
+ *
+ * @param jpqlGrammar The {@link JPQLGrammar} to extend with the content of this one without
+ * instantiating the base {@link JPQLGrammar}
+ */
+ private JPQLGrammar3_2(AbstractJPQLGrammar jpqlGrammar) {
+ super(jpqlGrammar);
+ }
+
+ /**
+ * Extends the given {@link JPQLGrammar} with the information of this one without instantiating
+ * the base {@link JPQLGrammar}.
+ *
+ * @param jpqlGrammar The {@link JPQLGrammar} to extend with the content of this one without
+ * instantiating the base {@link JPQLGrammar}
+ */
+ public static void extend(AbstractJPQLGrammar jpqlGrammar) {
+ new JPQLGrammar3_2(jpqlGrammar);
+ }
+
+ /**
+ * Returns the singleton instance of the default implementation of {@link JPQLGrammar} which
+ * provides support for the JPQL grammar defined in the Jakarta Persistence 3.2 functional specification.
+ *
+ * @return The {@link JPQLGrammar} that only has support for Jakarta Persistence 3.2
+ */
+ public static JPQLGrammar instance() {
+ return INSTANCE;
+ }
+
+ @Override
+ protected JPQLGrammar buildBaseGrammar() {
+ return new JPQLGrammar3_1();
+ }
+
+ @Override
+ public JPAVersion getJPAVersion() {
+ return JPAVersion.VERSION_3_2;
+ }
+
+ @Override
+ public String getProvider() {
+ return DefaultJPQLGrammar.PROVIDER_NAME;
+ }
+
+ @Override
+ public String getProviderVersion() {
+ return ExpressionTools.EMPTY_STRING;
+ }
+
+ @Override
+ protected void initializeBNFs() {
+ registerBNF(new StringFactorBNF());
+ registerBNF(new StringTermBNF());
+ registerBNF(new SimpleStringExpressionBNF());
+
+ // Extend some query BNFs
+ addChildBNF(StringPrimaryBNF.ID, SimpleStringExpressionBNF.ID);
+ }
+
+ @Override
+ protected void initializeExpressionFactories() {
+ registerFactory(new StringExpressionFactory());
+ }
+
+ @Override
+ protected void initializeIdentifiers() {
+ registerIdentifierRole(CONCAT_PIPES, IdentifierRole.AGGREGATE); // x || y
+ registerIdentifierVersion(CONCAT_PIPES, JPAVersion.VERSION_3_2);
+ }
+
+ @Override
+ public String toString() {
+ return "JPQLGrammar 3.2";
+ }
+}
diff --git a/jpa/org.eclipse.persistence.jpa.jpql/src/main/java/org/eclipse/persistence/jpa/jpql/parser/SimpleStringExpressionBNF.java b/jpa/org.eclipse.persistence.jpa.jpql/src/main/java/org/eclipse/persistence/jpa/jpql/parser/SimpleStringExpressionBNF.java
new file mode 100644
index 00000000000..8f0a88aa5f9
--- /dev/null
+++ b/jpa/org.eclipse.persistence.jpa.jpql/src/main/java/org/eclipse/persistence/jpa/jpql/parser/SimpleStringExpressionBNF.java
@@ -0,0 +1,50 @@
+/*
+ * Copyright (c) 2023 Oracle and/or its affiliates. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0,
+ * or the Eclipse Distribution License v. 1.0 which is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ *
+ * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
+ */
+
+// Contributors:
+// Oracle - initial API and implementation
+//
+package org.eclipse.persistence.jpa.jpql.parser;
+
+/**
+ * The query BNF for a simple string expression.
+ *
+ * simple_string_expression ::= string_term | simple_string_expression { || } string_term
SimpleStringExpressionBNF
.
+ */
+ public SimpleStringExpressionBNF() {
+ super(ID);
+ }
+
+ @Override
+ protected void initialize() {
+ super.initialize();
+ setHandleAggregate(true);
+ setFallbackBNFId(StringTermBNF.ID);
+ registerExpressionFactory(StringExpressionFactory.ID);
+ registerChild(StringTermBNF.ID);
+ }
+}
diff --git a/jpa/org.eclipse.persistence.jpa.jpql/src/main/java/org/eclipse/persistence/jpa/jpql/parser/StringExpression.java b/jpa/org.eclipse.persistence.jpa.jpql/src/main/java/org/eclipse/persistence/jpa/jpql/parser/StringExpression.java
new file mode 100644
index 00000000000..1cf8d19c28e
--- /dev/null
+++ b/jpa/org.eclipse.persistence.jpa.jpql/src/main/java/org/eclipse/persistence/jpa/jpql/parser/StringExpression.java
@@ -0,0 +1,88 @@
+/*
+ * Copyright (c) 2023 Oracle and/or its affiliates. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0,
+ * or the Eclipse Distribution License v. 1.0 which is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ *
+ * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
+ */
+
+// Contributors:
+// Oracle - initial API and implementation
+// 06/02/2023: Radek Felcman
+// - Issue 1885: Implement new JPQLGrammar for upcoming Jakarta Persistence 3.2
+package org.eclipse.persistence.jpa.jpql.parser;
+
+import org.eclipse.persistence.jpa.jpql.WordParser;
+
+/**
+ * This expression represents a String expression, which means the first and second expressions
+ * are aggregated with a String sign.
+ *
+ * @see ConcatPipesExpression
+ *
+ * @version 2.5
+ * @since 2.3
+ * @author Pascal Filion
+ */
+public abstract class StringExpression extends CompoundExpression {
+
+ /**
+ * Creates a new StringExpression
.
+ *
+ * @param parent The parent of this expression
+ */
+ protected StringExpression(AbstractExpression parent, String identifier) {
+ super(parent, identifier);
+ }
+
+ @Override
+ public JPQLQueryBNF findQueryBNF(Expression expression) {
+ return getParent().findQueryBNF(expression);
+ }
+
+ /**
+ * Returns the string sign this expression is actually representing.
+ *
+ * @return The single character value of the string sign
+ */
+ public final String getStringSign() {
+ return getText();
+ }
+
+ @Override
+ public String getLeftExpressionQueryBNFId() {
+ return StringExpressionBNF.ID;
+ }
+
+ @Override
+ public final JPQLQueryBNF getQueryBNF() {
+ return getQueryBNF(StringTermBNF.ID);
+ }
+
+ @Override
+ public final String getRightExpressionQueryBNFId() {
+ return StringTermBNF.ID;
+ }
+
+ @Override
+ protected boolean isParsingComplete(WordParser wordParser, String word, Expression expression) {
+
+ String character = word.substring(0,1);
+
+ // Concat will create a chain of operations
+ if ("||".equals(character)) {
+ return false;
+ }
+
+ return (expression != null);
+ }
+
+ @Override
+ protected final String parseIdentifier(WordParser wordParser) {
+ return getText();
+ }
+}
diff --git a/jpa/org.eclipse.persistence.jpa.jpql/src/main/java/org/eclipse/persistence/jpa/jpql/parser/StringExpressionFactory.java b/jpa/org.eclipse.persistence.jpa.jpql/src/main/java/org/eclipse/persistence/jpa/jpql/parser/StringExpressionFactory.java
new file mode 100644
index 00000000000..9666d5cf0f1
--- /dev/null
+++ b/jpa/org.eclipse.persistence.jpa.jpql/src/main/java/org/eclipse/persistence/jpa/jpql/parser/StringExpressionFactory.java
@@ -0,0 +1,117 @@
+/*
+ * Copyright (c) 2023 Oracle and/or its affiliates. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0,
+ * or the Eclipse Distribution License v. 1.0 which is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ *
+ * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
+ */
+
+// Contributors:
+// Oracle - initial API and implementation
+// 06/02/2023: Radek Felcman
+// - Issue 1885: Implement new JPQLGrammar for upcoming Jakarta Persistence 3.2
+package org.eclipse.persistence.jpa.jpql.parser;
+
+import org.eclipse.persistence.jpa.jpql.WordParser;
+
+/**
+ * This {@link ExpressionFactory} creates a new expression when the portion of the query to parse
+ * starts with a string identifier. It is possible the expression to parse is also a {@link StringLiteral}.
+ *
+ * @version 4.1
+ * @since 4.1
+ * @author Pascal Filion
+ */
+@SuppressWarnings("nls")
+public final class StringExpressionFactory extends ExpressionFactory {
+
+ /**
+ * This {@link ExpressionVisitor} is used to check if the {@link Expression} passed to this
+ * factory is an {@link ConcatPipesExpression}.
+ */
+ private StringExpressionVisitor visitor;
+
+ /**
+ * The unique identifier of this {@link StringExpressionFactory}.
+ */
+ public static final String ID = "||";
+
+ /**
+ * Creates a new AbstractStringExpressionFactory
.
+ */
+ public StringExpressionFactory() {
+ super(ID, Expression.CONCAT_PIPES);
+ }
+
+ /**
+ * Creates the {@link Expression} this factory for which it is responsible.
+ *
+ * @param parent The parent of the new {@link Expression}
+ * @param character The arithmetic character
+ * @return A new {@link CompoundExpression}
+ */
+ private CompoundExpression buildExpression(AbstractExpression parent, String character) {
+ if ("||".equals(character)) {
+ return new ConcatPipesExpression(parent);
+ }
+ return null;
+ }
+
+ @Override
+ protected final AbstractExpression buildExpression(AbstractExpression parent,
+ WordParser wordParser,
+ String word,
+ JPQLQueryBNF queryBNF,
+ AbstractExpression expression,
+ boolean tolerant) {
+
+ String character = word.substring(0,1);
+ //"|" implies concat operator which contains two characters
+ if ("|".equals(character)) {
+ character = word.substring(0,2);
+ }
+
+ // Concat operator '||'
+ if ("||".equals(character)) {
+ ConcatPipesExpression concatPipesExpression = new ConcatPipesExpression(parent);
+ concatPipesExpression.setLeftExpression(expression);
+ concatPipesExpression.parse(wordParser, tolerant);
+ return concatPipesExpression;
+ }
+
+ // Create the StringExpression
+ CompoundExpression compoundExpression = buildExpression(parent, character);
+ compoundExpression.setLeftExpression(expression);
+ compoundExpression.parse(wordParser, tolerant);
+ return compoundExpression;
+ }
+
+ private StringExpressionVisitor visitor() {
+ if (visitor == null) {
+ visitor = new StringExpressionVisitor();
+ }
+ return visitor;
+ }
+
+ // Made static final for performance reasons.
+ /**
+ * This {@link ExpressionVisitor} is used to check if the {@link Expression} passed to this
+ * factory is a {@link ConcatPipesExpression}.
+ */
+ private static final class StringExpressionVisitor extends AbstractExpressionVisitor {
+
+ /**
+ * This flag is turned on if the {@link Expression} visited is {@link OrExpression}.
+ */
+ boolean found;
+
+ @Override
+ public void visit(ConcatPipesExpression expression) {
+ found = true;
+ }
+ }
+}
diff --git a/jpa/org.eclipse.persistence.jpa.jpql/src/main/java/org/eclipse/persistence/jpa/jpql/parser/StringFactorBNF.java b/jpa/org.eclipse.persistence.jpa.jpql/src/main/java/org/eclipse/persistence/jpa/jpql/parser/StringFactorBNF.java
new file mode 100644
index 00000000000..efd54d6e5cb
--- /dev/null
+++ b/jpa/org.eclipse.persistence.jpa.jpql/src/main/java/org/eclipse/persistence/jpa/jpql/parser/StringFactorBNF.java
@@ -0,0 +1,49 @@
+/*
+ * Copyright (c) 2023 Oracle and/or its affiliates. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0,
+ * or the Eclipse Distribution License v. 1.0 which is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ *
+ * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
+ */
+
+// Contributors:
+// Oracle - initial API and implementation
+// 06/02/2023: Radek Felcman
+// - Issue 1885: Implement new JPQLGrammar for upcoming Jakarta Persistence 3.2
+package org.eclipse.persistence.jpa.jpql.parser;
+
+/**
+ * The query BNF for an string factor expression.
+ *
+ * string_factor ::= [{ || }] string_primary
StringFactorBNF
.
+ */
+ public StringFactorBNF() {
+ super(ID);
+ }
+
+ @Override
+ protected void initialize() {
+ super.initialize();
+ setFallbackBNFId(StringPrimaryBNF.ID);
+ registerChild(StringPrimaryBNF.ID);
+ }
+}
diff --git a/jpa/org.eclipse.persistence.jpa.jpql/src/main/java/org/eclipse/persistence/jpa/jpql/parser/StringTermBNF.java b/jpa/org.eclipse.persistence.jpa.jpql/src/main/java/org/eclipse/persistence/jpa/jpql/parser/StringTermBNF.java
new file mode 100644
index 00000000000..55f488bf90c
--- /dev/null
+++ b/jpa/org.eclipse.persistence.jpa.jpql/src/main/java/org/eclipse/persistence/jpa/jpql/parser/StringTermBNF.java
@@ -0,0 +1,51 @@
+/*
+ * Copyright (c) 2023 Oracle and/or its affiliates. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0,
+ * or the Eclipse Distribution License v. 1.0 which is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ *
+ * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
+ */
+
+// Contributors:
+// Oracle - initial API and implementation
+// 06/02/2023: Radek Felcman
+// - Issue 1885: Implement new JPQLGrammar for upcoming Jakarta Persistence 3.2
+package org.eclipse.persistence.jpa.jpql.parser;
+
+/**
+ * The query BNF for a string term expression.
+ *
+ * string_term ::= string_factor | string_term { || } string_factor
StringTermBNF
.
+ */
+ public StringTermBNF() {
+ super(ID);
+ }
+
+ @Override
+ protected void initialize() {
+ super.initialize();
+ setHandleAggregate(true);
+ setFallbackBNFId(StringFactorBNF.ID);
+ registerExpressionFactory(StringExpressionFactory.ID);
+ registerChild(StringFactorBNF.ID);
+ }
+}
diff --git a/jpa/org.eclipse.persistence.jpa.jpql/src/main/java/org/eclipse/persistence/jpa/jpql/tools/AbstractContentAssistVisitor.java b/jpa/org.eclipse.persistence.jpa.jpql/src/main/java/org/eclipse/persistence/jpa/jpql/tools/AbstractContentAssistVisitor.java
index ebaed5e6455..6041b2018ba 100644
--- a/jpa/org.eclipse.persistence.jpa.jpql/src/main/java/org/eclipse/persistence/jpa/jpql/tools/AbstractContentAssistVisitor.java
+++ b/jpa/org.eclipse.persistence.jpa.jpql/src/main/java/org/eclipse/persistence/jpa/jpql/tools/AbstractContentAssistVisitor.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2006, 2022 Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2006, 2023 Oracle and/or its affiliates. All rights reserved.
* Copyright (c) 2022 IBM Corporation. All rights reserved.
*
* This program and the accompanying materials are made available under the
@@ -18,6 +18,8 @@
// 04/21/2022: Tomas Kraus
// - Issue 1474: Update JPQL Grammar for Jakarta Persistence 2.2, 3.0 and 3.1
// - Issue 317: Implement LOCAL DATE, LOCAL TIME and LOCAL DATETIME.
+// 06/02/2023: Radek Felcman
+// - Issue 1885: Implement new JPQLGrammar for upcoming Jakarta Persistence 3.2
package org.eclipse.persistence.jpa.jpql.tools;
import java.util.ArrayList;
@@ -74,6 +76,7 @@
import org.eclipse.persistence.jpa.jpql.parser.ComparisonExpressionFactory;
import org.eclipse.persistence.jpa.jpql.parser.CompoundExpression;
import org.eclipse.persistence.jpa.jpql.parser.ConcatExpression;
+import org.eclipse.persistence.jpa.jpql.parser.ConcatPipesExpression;
import org.eclipse.persistence.jpa.jpql.parser.ConditionalExpressionBNF;
import org.eclipse.persistence.jpa.jpql.parser.ConstructorExpression;
import org.eclipse.persistence.jpa.jpql.parser.ConstructorItemBNF;
@@ -105,6 +108,7 @@
import org.eclipse.persistence.jpa.jpql.parser.InternalJoinBNF;
import org.eclipse.persistence.jpa.jpql.parser.JPQLExpression;
import org.eclipse.persistence.jpa.jpql.parser.JPQLGrammar;
+import org.eclipse.persistence.jpa.jpql.parser.JPQLGrammar3_2;
import org.eclipse.persistence.jpa.jpql.parser.JPQLQueryBNF;
import org.eclipse.persistence.jpa.jpql.parser.Join;
import org.eclipse.persistence.jpa.jpql.parser.KeyExpression;
@@ -148,6 +152,8 @@
import org.eclipse.persistence.jpa.jpql.parser.SizeExpression;
import org.eclipse.persistence.jpa.jpql.parser.SqrtExpression;
import org.eclipse.persistence.jpa.jpql.parser.StateFieldPathExpression;
+import org.eclipse.persistence.jpa.jpql.parser.StringExpression;
+import org.eclipse.persistence.jpa.jpql.parser.StringExpressionFactory;
import org.eclipse.persistence.jpa.jpql.parser.StringLiteral;
import org.eclipse.persistence.jpa.jpql.parser.StringPrimaryBNF;
import org.eclipse.persistence.jpa.jpql.parser.SubExpression;
@@ -337,6 +343,18 @@ protected void addArithmeticIdentifiers() {
}
}
+ /**
+ * Adds the JPQL identifiers which correspond to the String operators as valid proposals. The
+ * word has to be an empty string.
+ */
+ protected void addStringIdentifiers() {
+ if (this.queryContext.getGrammar() instanceof JPQLGrammar3_2) {
+ if (word.length() == 0) {
+ addExpressionFactoryIdentifiers(StringExpressionFactory.ID);
+ }
+ }
+ }
+
/**
* Adds the given JPQL identifier as a valid proposal if its role is {@link IdentifierRole#CLAUSE}
* and the beginning starts with the current word.
@@ -846,6 +864,17 @@ protected boolean areLogicalSymbolsAppendable(Expression expression) {
return isAppendable(expression, AppendableType.LOGICAL);
}
+ /**
+ * Determines whether the given {@link Expression} can be followed by an String operator.
+ *
+ * @param expression The {@link Expression} that found left of the cursor, which determines if
+ * the String operators are appendable or not
+ * @return true
if the operators are appendable; false
otherwise
+ */
+ protected boolean areStringSymbolsAppendable(Expression expression) {
+ return isAppendable(expression, AppendableType.STRING);
+ }
+
protected abstract AcceptableTypeVisitor buildAcceptableTypeVisitor();
protected AppendableExpressionVisitor buildAppendableExpressionVisitor() {
@@ -2802,6 +2831,12 @@ public void visit(ConcatExpression expression) {
visitCollectionExpression(expression, CONCAT, getConcatExpressionCollectionHelper());
}
+ @Override
+ public void visit(ConcatPipesExpression expression) {
+ super.visit(expression);
+ visitStringExpression(expression);
+ }
+
@Override
public void visit(ConstructorExpression expression) {
super.visit(expression);
@@ -4699,6 +4734,36 @@ else if (helper.hasSpaceAfterClause(expression)) {
}
}
+ /**
+ * Visits the given {@link StringExpression} and attempts to find valid proposals.
+ *
+ * @param expression The {@link StringExpression} to inspect
+ */
+ protected void visitStringExpression(StringExpression expression) {
+
+ int position = queryPosition.getPosition(expression) - corrections.peek();
+ int length = 0;
+
+ if (expression.hasLeftExpression()) {
+ length += expression.getLeftExpression().getLength() + SPACE_LENGTH;
+ }
+
+ // Within the string operator
+ if (isPositionWithin(position, length, CONCAT_PIPES)) {
+ addAggregateIdentifiers(expression.getQueryBNF());
+ }
+ // After the string operator, with or without the space
+ else if (expression.hasSpaceAfterIdentifier()) {
+ length += 2;
+
+ // Right after the space
+ if (position == length) {
+ addIdentificationVariables();
+ addFunctionIdentifiers(expression.getRightExpressionQueryBNFId());
+ }
+ }
+ }
+
/**
* Visits the given {@link AbstractPathExpression} and attempts to find valid proposals that is
* not provided by the default implementation. Subclasses can add additional proposals that is
@@ -4778,7 +4843,7 @@ public void addAtTheEndOfChild(Expression expression,
index = (-index / 10) - 1;
}
- // The only thing that is appendable is an arithmetic operator
+ // The only thing that is appendable is an arithmetic or String operator
// Example: "SELECT e FROM Employee e WHERE e.name|"
// Example: "SELECT e FROM Employee e WHERE I|"
if ((index == 0) && !virtualSpace) {
@@ -4788,6 +4853,10 @@ public void addAtTheEndOfChild(Expression expression,
if (visitor.areArithmeticSymbolsAppendable(child)) {
visitor.addArithmeticIdentifiers();
}
+
+ if (visitor.areStringSymbolsAppendable(child)) {
+ visitor.addStringIdentifiers();
+ }
}
else {
@@ -4812,6 +4881,10 @@ public void addAtTheEndOfChild(Expression expression,
visitor.addArithmeticIdentifiers();
}
+ if (visitor.areStringSymbolsAppendable(child)) {
+ visitor.addStringIdentifiers();
+ }
+
if (visitor.areComparisonSymbolsAppendable(child)) {
visitor.addComparisonIdentifiers(child);
}
@@ -5099,7 +5172,7 @@ public void addAtTheEndOfChild(T expression,
boolean hasComma,
boolean virtualSpace) {
- // The only thing that is appendable is an arithmetic operator
+ // The only thing that is appendable is arithmetic or String operator
// Example: "SELECT e.name|"
// Example: "SELECT e|"
if (queryBNF(expression, index).handleAggregate()) {
@@ -5109,6 +5182,10 @@ public void addAtTheEndOfChild(T expression,
if (visitor.areArithmeticSymbolsAppendable(child)) {
visitor.addArithmeticIdentifiers();
}
+
+ if (visitor.areStringSymbolsAppendable(child)) {
+ visitor.addStringIdentifiers();
+ }
}
}
@@ -5536,6 +5613,13 @@ public void visit(ConcatExpression expression) {
expression.hasRightParenthesis();
}
+ @Override
+ public void visit(ConcatPipesExpression expression) {
+ if (expression.hasRightExpression()) {
+ expression.getRightExpression().accept(this);
+ }
+ }
+
@Override
public void visit(ConstructorExpression expression) {
appendable = !conditionalExpression &&
@@ -6124,6 +6208,11 @@ else if (appendableType == AppendableType.CLAUSE ||
appendable = visitor.queryContext.getTypeHelper().isBooleanType(type);
break;
}
+ case STRING: {
+ // e.name (String) can be followed by ||
+ appendable = visitor.queryContext.getTypeHelper().isStringType(type);
+ break;
+ }
}
}
}
@@ -6290,6 +6379,11 @@ protected static enum AppendableType {
*/
LOGICAL,
+ /**
+ * Determines whether the String operators (||) can be appended as valid proposals.
+ */
+ STRING,
+
/**
* Determines whether the JPQL identifiers identifying a subquery (eg: SELECT
)
* can be appended as valid proposals.
@@ -6458,7 +6552,7 @@ public void addAtTheEndOfChild(ConcatExpression expression,
boolean hasComma,
boolean virtualSpace) {
- // The only thing that is appendable is an arithmetic operator
+ // The only thing that is appendable is arithmetic or String operator
// Example: "SELECT e.name|"
// Example: "SELECT e|"
if (queryBNF(expression, index).handleAggregate()) {
@@ -6470,6 +6564,10 @@ public void addAtTheEndOfChild(ConcatExpression expression,
if (visitor.areArithmeticSymbolsAppendable(child)) {
visitor.addArithmeticIdentifiers();
}
+
+ if (visitor.areStringSymbolsAppendable(child)) {
+ visitor.addStringIdentifiers();
+ }
}
else {
@@ -6477,6 +6575,10 @@ public void addAtTheEndOfChild(ConcatExpression expression,
visitor.addArithmeticIdentifiers();
}
+ if (visitor.areStringSymbolsAppendable(child)) {
+ visitor.addStringIdentifiers();
+ }
+
if (visitor.areComparisonSymbolsAppendable(child)) {
visitor.addComparisonIdentifiers(child);
}
@@ -6593,6 +6695,10 @@ public void addAtTheEndOfChild(ConstructorExpression expression,
if (visitor.areArithmeticSymbolsAppendable(child)) {
visitor.addArithmeticIdentifiers();
}
+
+ if (visitor.areStringSymbolsAppendable(child)) {
+ visitor.addStringIdentifiers();
+ }
}
else {
@@ -6600,6 +6706,10 @@ public void addAtTheEndOfChild(ConstructorExpression expression,
visitor.addArithmeticIdentifiers();
}
+ if (visitor.areStringSymbolsAppendable(child)) {
+ visitor.addStringIdentifiers();
+ }
+
if (visitor.areComparisonSymbolsAppendable(child)) {
visitor.addComparisonIdentifiers(child);
}
@@ -6890,6 +7000,10 @@ public void addAtTheEndOfChild(AbstractDoubleEncapsulatedExpression expression,
if (visitor.areArithmeticSymbolsAppendable(child)) {
visitor.addArithmeticIdentifiers();
}
+
+ if (visitor.areStringSymbolsAppendable(child)) {
+ visitor.addStringIdentifiers();
+ }
}
else {
@@ -6897,6 +7011,10 @@ public void addAtTheEndOfChild(AbstractDoubleEncapsulatedExpression expression,
visitor.addArithmeticIdentifiers();
}
+ if (visitor.areStringSymbolsAppendable(child)) {
+ visitor.addStringIdentifiers();
+ }
+
if (visitor.areComparisonSymbolsAppendable(child)) {
visitor.addComparisonIdentifiers(child);
}
@@ -7372,6 +7490,11 @@ public void visit(ConcatExpression expression) {
visitAbstractSingleEncapsulatedExpression(expression);
}
+ @Override
+ public void visit(ConcatPipesExpression expression) {
+ visitCompoundExpression(expression);
+ }
+
@Override
public void visit(ConstructorExpression expression) {
@@ -10482,6 +10605,10 @@ public void addAtTheEndOfChild(AbstractTripleEncapsulatedExpression expression,
if (visitor.areArithmeticSymbolsAppendable(child)) {
visitor.addArithmeticIdentifiers();
}
+
+ if (visitor.areStringSymbolsAppendable(child)) {
+ visitor.addStringIdentifiers();
+ }
}
else {
@@ -10489,6 +10616,10 @@ public void addAtTheEndOfChild(AbstractTripleEncapsulatedExpression expression,
visitor.addArithmeticIdentifiers();
}
+ if (visitor.areStringSymbolsAppendable(child)) {
+ visitor.addStringIdentifiers();
+ }
+
if (visitor.areComparisonSymbolsAppendable(child)) {
visitor.addComparisonIdentifiers(child);
}
diff --git a/jpa/org.eclipse.persistence.jpa.jpql/src/main/java/org/eclipse/persistence/jpa/jpql/tools/model/AbstractActualJPQLQueryFormatter.java b/jpa/org.eclipse.persistence.jpa.jpql/src/main/java/org/eclipse/persistence/jpa/jpql/tools/model/AbstractActualJPQLQueryFormatter.java
index c806900910a..5a91784522a 100644
--- a/jpa/org.eclipse.persistence.jpa.jpql/src/main/java/org/eclipse/persistence/jpa/jpql/tools/model/AbstractActualJPQLQueryFormatter.java
+++ b/jpa/org.eclipse.persistence.jpa.jpql/src/main/java/org/eclipse/persistence/jpa/jpql/tools/model/AbstractActualJPQLQueryFormatter.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2006, 2021 Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2006, 2023 Oracle and/or its affiliates. All rights reserved.
*
* This program and the accompanying materials are made available under the
* terms of the Eclipse Public License v. 2.0 which is available at
@@ -12,7 +12,8 @@
// Contributors:
// Oracle - initial API and implementation
-//
+// 06/02/2023: Radek Felcman
+// - Issue 1885: Implement new JPQLGrammar for upcoming Jakarta Persistence 3.2
package org.eclipse.persistence.jpa.jpql.tools.model;
import static org.eclipse.persistence.jpa.jpql.parser.Expression.AND;
@@ -21,6 +22,7 @@
import static org.eclipse.persistence.jpa.jpql.parser.Expression.CASE;
import static org.eclipse.persistence.jpa.jpql.parser.Expression.COALESCE;
import static org.eclipse.persistence.jpa.jpql.parser.Expression.CONCAT;
+import static org.eclipse.persistence.jpa.jpql.parser.Expression.CONCAT_PIPES;
import static org.eclipse.persistence.jpa.jpql.parser.Expression.DELETE;
import static org.eclipse.persistence.jpa.jpql.parser.Expression.DISTINCT;
import static org.eclipse.persistence.jpa.jpql.parser.Expression.DIVISION;
@@ -128,6 +130,7 @@
import org.eclipse.persistence.jpa.jpql.tools.model.query.ComparisonExpressionStateObject;
import org.eclipse.persistence.jpa.jpql.tools.model.query.CompoundExpressionStateObject;
import org.eclipse.persistence.jpa.jpql.tools.model.query.ConcatExpressionStateObject;
+import org.eclipse.persistence.jpa.jpql.tools.model.query.ConcatPipesExpressionStateObject;
import org.eclipse.persistence.jpa.jpql.tools.model.query.ConstructorExpressionStateObject;
import org.eclipse.persistence.jpa.jpql.tools.model.query.CountFunctionStateObject;
import org.eclipse.persistence.jpa.jpql.tools.model.query.DateTimeStateObject;
@@ -1041,6 +1044,11 @@ public void visit(ConcatExpressionStateObject stateObject) {
}
}
+ @Override
+ public void visit(ConcatPipesExpressionStateObject stateObject) {
+ toStringCompound(stateObject, CONCAT_PIPES);
+ }
+
@Override
public void visit(ConstructorExpressionStateObject stateObject) {
diff --git a/jpa/org.eclipse.persistence.jpa.jpql/src/main/java/org/eclipse/persistence/jpa/jpql/tools/model/AbstractJPQLQueryFormatter.java b/jpa/org.eclipse.persistence.jpa.jpql/src/main/java/org/eclipse/persistence/jpa/jpql/tools/model/AbstractJPQLQueryFormatter.java
index ff523a59eb7..e8cbc64def8 100644
--- a/jpa/org.eclipse.persistence.jpa.jpql/src/main/java/org/eclipse/persistence/jpa/jpql/tools/model/AbstractJPQLQueryFormatter.java
+++ b/jpa/org.eclipse.persistence.jpa.jpql/src/main/java/org/eclipse/persistence/jpa/jpql/tools/model/AbstractJPQLQueryFormatter.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2006, 2021 Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2006, 2023 Oracle and/or its affiliates. All rights reserved.
*
* This program and the accompanying materials are made available under the
* terms of the Eclipse Public License v. 2.0 which is available at
@@ -12,7 +12,8 @@
// Contributors:
// Oracle - initial API and implementation
-//
+// 06/02/2023: Radek Felcman
+// - Issue 1885: Implement new JPQLGrammar for upcoming Jakarta Persistence 3.2
package org.eclipse.persistence.jpa.jpql.tools.model;
import java.util.ListIterator;
@@ -45,6 +46,7 @@
import org.eclipse.persistence.jpa.jpql.tools.model.query.ComparisonExpressionStateObject;
import org.eclipse.persistence.jpa.jpql.tools.model.query.CompoundExpressionStateObject;
import org.eclipse.persistence.jpa.jpql.tools.model.query.ConcatExpressionStateObject;
+import org.eclipse.persistence.jpa.jpql.tools.model.query.ConcatPipesExpressionStateObject;
import org.eclipse.persistence.jpa.jpql.tools.model.query.ConstructorExpressionStateObject;
import org.eclipse.persistence.jpa.jpql.tools.model.query.CountFunctionStateObject;
import org.eclipse.persistence.jpa.jpql.tools.model.query.DateTimeStateObject;
@@ -652,6 +654,11 @@ public void visit(ConcatExpressionStateObject stateObject) {
}
}
+ @Override
+ public void visit(ConcatPipesExpressionStateObject stateObject) {
+ toStringCompound(stateObject);
+ }
+
@Override
public void visit(ConstructorExpressionStateObject stateObject) {
diff --git a/jpa/org.eclipse.persistence.jpa.jpql/src/main/java/org/eclipse/persistence/jpa/jpql/tools/model/BasicStateObjectBuilder.java b/jpa/org.eclipse.persistence.jpa.jpql/src/main/java/org/eclipse/persistence/jpa/jpql/tools/model/BasicStateObjectBuilder.java
index 0f072e4ac9c..0e1be4726cd 100644
--- a/jpa/org.eclipse.persistence.jpa.jpql/src/main/java/org/eclipse/persistence/jpa/jpql/tools/model/BasicStateObjectBuilder.java
+++ b/jpa/org.eclipse.persistence.jpa.jpql/src/main/java/org/eclipse/persistence/jpa/jpql/tools/model/BasicStateObjectBuilder.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2006, 2021 Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2006, 2023 Oracle and/or its affiliates. All rights reserved.
*
* This program and the accompanying materials are made available under the
* terms of the Eclipse Public License v. 2.0 which is available at
@@ -12,7 +12,8 @@
// Contributors:
// Oracle - initial API and implementation
-//
+// 06/02/2023: Radek Felcman
+// - Issue 1885: Implement new JPQLGrammar for upcoming Jakarta Persistence 3.2
package org.eclipse.persistence.jpa.jpql.tools.model;
import java.util.ArrayList;
@@ -42,6 +43,7 @@
import org.eclipse.persistence.jpa.jpql.parser.CollectionValuedPathExpression;
import org.eclipse.persistence.jpa.jpql.parser.ComparisonExpression;
import org.eclipse.persistence.jpa.jpql.parser.ConcatExpression;
+import org.eclipse.persistence.jpa.jpql.parser.ConcatPipesExpression;
import org.eclipse.persistence.jpa.jpql.parser.ConstructorExpression;
import org.eclipse.persistence.jpa.jpql.parser.CountFunction;
import org.eclipse.persistence.jpa.jpql.parser.DateTime;
@@ -132,6 +134,7 @@
import org.eclipse.persistence.jpa.jpql.tools.model.query.CollectionValuedPathExpressionStateObject;
import org.eclipse.persistence.jpa.jpql.tools.model.query.ComparisonExpressionStateObject;
import org.eclipse.persistence.jpa.jpql.tools.model.query.ConcatExpressionStateObject;
+import org.eclipse.persistence.jpa.jpql.tools.model.query.ConcatPipesExpressionStateObject;
import org.eclipse.persistence.jpa.jpql.tools.model.query.ConstructorExpressionStateObject;
import org.eclipse.persistence.jpa.jpql.tools.model.query.CountFunctionStateObject;
import org.eclipse.persistence.jpa.jpql.tools.model.query.DateTimeStateObject;
@@ -774,6 +777,25 @@ public void visit(ConcatExpression expression) {
this.stateObject = stateObject;
}
+ @Override
+ public void visit(ConcatPipesExpression expression) {
+
+ expression.getLeftExpression().accept(this);
+ StateObject leftStateObject = stateObject;
+
+ expression.getRightExpression().accept(this);
+ StateObject rightStateObject = stateObject;
+
+ ConcatPipesExpressionStateObject stateObject = new ConcatPipesExpressionStateObject(
+ parent,
+ leftStateObject,
+ rightStateObject
+ );
+
+ stateObject.setExpression(expression);
+ this.stateObject = stateObject;
+ }
+
@Override
public void visit(ConstructorExpression expression) {
diff --git a/jpa/org.eclipse.persistence.jpa.jpql/src/main/java/org/eclipse/persistence/jpa/jpql/tools/model/query/AbstractStateObjectVisitor.java b/jpa/org.eclipse.persistence.jpa.jpql/src/main/java/org/eclipse/persistence/jpa/jpql/tools/model/query/AbstractStateObjectVisitor.java
index 38e89d60aa3..d09a7b82057 100644
--- a/jpa/org.eclipse.persistence.jpa.jpql/src/main/java/org/eclipse/persistence/jpa/jpql/tools/model/query/AbstractStateObjectVisitor.java
+++ b/jpa/org.eclipse.persistence.jpa.jpql/src/main/java/org/eclipse/persistence/jpa/jpql/tools/model/query/AbstractStateObjectVisitor.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2006, 2021 Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2006, 2023 Oracle and/or its affiliates. All rights reserved.
*
* This program and the accompanying materials are made available under the
* terms of the Eclipse Public License v. 2.0 which is available at
@@ -12,7 +12,8 @@
// Contributors:
// Oracle - initial API and implementation
-//
+// 06/02/2023: Radek Felcman
+// - Issue 1885: Implement new JPQLGrammar for upcoming Jakarta Persistence 3.2
package org.eclipse.persistence.jpa.jpql.tools.model.query;
/**
@@ -89,6 +90,10 @@ public void visit(ComparisonExpressionStateObject stateObject) {
public void visit(ConcatExpressionStateObject stateObject) {
}
+ @Override
+ public void visit(ConcatPipesExpressionStateObject stateObject) {
+ }
+
@Override
public void visit(ConstructorExpressionStateObject stateObject) {
}
diff --git a/jpa/org.eclipse.persistence.jpa.jpql/src/main/java/org/eclipse/persistence/jpa/jpql/tools/model/query/AnonymousStateObjectVisitor.java b/jpa/org.eclipse.persistence.jpa.jpql/src/main/java/org/eclipse/persistence/jpa/jpql/tools/model/query/AnonymousStateObjectVisitor.java
index ed57bd7d6ce..5dbb34c1650 100644
--- a/jpa/org.eclipse.persistence.jpa.jpql/src/main/java/org/eclipse/persistence/jpa/jpql/tools/model/query/AnonymousStateObjectVisitor.java
+++ b/jpa/org.eclipse.persistence.jpa.jpql/src/main/java/org/eclipse/persistence/jpa/jpql/tools/model/query/AnonymousStateObjectVisitor.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2006, 2021 Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2006, 2023 Oracle and/or its affiliates. All rights reserved.
*
* This program and the accompanying materials are made available under the
* terms of the Eclipse Public License v. 2.0 which is available at
@@ -12,7 +12,8 @@
// Contributors:
// Oracle - initial API and implementation
-//
+// 06/02/2023: Radek Felcman
+// - Issue 1885: Implement new JPQLGrammar for upcoming Jakarta Persistence 3.2
package org.eclipse.persistence.jpa.jpql.tools.model.query;
/**
@@ -105,6 +106,11 @@ public void visit(ConcatExpressionStateObject stateObject) {
visit((StateObject) stateObject);
}
+ @Override
+ public void visit(ConcatPipesExpressionStateObject stateObject) {
+ visit((StateObject) stateObject);
+ }
+
@Override
public void visit(ConstructorExpressionStateObject stateObject) {
visit((StateObject) stateObject);
diff --git a/jpa/org.eclipse.persistence.jpa.jpql/src/main/java/org/eclipse/persistence/jpa/jpql/tools/model/query/ConcatPipesExpressionStateObject.java b/jpa/org.eclipse.persistence.jpa.jpql/src/main/java/org/eclipse/persistence/jpa/jpql/tools/model/query/ConcatPipesExpressionStateObject.java
new file mode 100644
index 00000000000..22e470063a2
--- /dev/null
+++ b/jpa/org.eclipse.persistence.jpa.jpql/src/main/java/org/eclipse/persistence/jpa/jpql/tools/model/query/ConcatPipesExpressionStateObject.java
@@ -0,0 +1,103 @@
+/*
+ * Copyright (c) 2023 Oracle and/or its affiliates. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0,
+ * or the Eclipse Distribution License v. 1.0 which is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ *
+ * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
+ */
+
+// Contributors:
+// Oracle - initial API and implementation
+// 06/02/2023: Radek Felcman
+// - Issue 1885: Implement new JPQLGrammar for upcoming Jakarta Persistence 3.2
+package org.eclipse.persistence.jpa.jpql.tools.model.query;
+
+import org.eclipse.persistence.jpa.jpql.parser.ConcatPipesExpression;
+
+import static org.eclipse.persistence.jpa.jpql.parser.Expression.CONCAT_PIPES;
+
+/**
+ *
+ * BNF: string_expression ::= string_expression || string_term
ConcatPipesExpressionStateObject
.
+ *
+ * @param parent The parent of this state object, which cannot be null
+ * @exception NullPointerException The given parent cannot be null
+ */
+ public ConcatPipesExpressionStateObject(StateObject parent) {
+ super(parent);
+ }
+
+ /**
+ * Creates a new ConcatPipesExpressionStateObject
.
+ *
+ * @param parent The parent of this state object, which cannot be null
+ * @param leftStateObject The {@link StateObject} representing the left expression
+ * @param rightStateObject The {@link StateObject} representing the right expression
+ * @exception NullPointerException The given parent cannot be null
+ */
+ public ConcatPipesExpressionStateObject(StateObject parent,
+ StateObject leftStateObject,
+ StateObject rightStateObject) {
+
+ super(parent, leftStateObject, rightStateObject);
+ }
+
+ /**
+ * Creates a new ConcatPipesExpressionStateObject
.
+ *
+ * @param parent The parent of this state object, which cannot be null
+ * @param leftJpqlFragment The string representation of the left expression to parse and to
+ * convert into a {@link StateObject}
+ * @param rightJpqlFragment The string representation of the right expression to parse and to
+ * convert into a {@link StateObject}
+ * @exception NullPointerException The given parent cannot be null
+ */
+ public ConcatPipesExpressionStateObject(StateObject parent,
+ String leftJpqlFragment,
+ String rightJpqlFragment) {
+
+ super(parent, leftJpqlFragment, rightJpqlFragment);
+ }
+
+ @Override
+ public void accept(StateObjectVisitor visitor) {
+ visitor.visit(this);
+ }
+
+ @Override
+ public ConcatPipesExpression getExpression() {
+ return (ConcatPipesExpression) super.getExpression();
+ }
+
+ @Override
+ public String getIdentifier() {
+ return CONCAT_PIPES;
+ }
+
+ /**
+ * Keeps a reference of the {@link ConcatPipesExpression parsed object} object, which should only be
+ * done when this object is instantiated during the conversion of a parsed JPQL query into
+ * {@link StateObject StateObjects}.
+ *
+ * @param expression The {@link ConcatPipesExpression parsed object} representing an addition
+ * expression
+ */
+ public void setExpression(ConcatPipesExpression expression) {
+ super.setExpression(expression);
+ }
+}
diff --git a/jpa/org.eclipse.persistence.jpa.jpql/src/main/java/org/eclipse/persistence/jpa/jpql/tools/model/query/StateObjectVisitor.java b/jpa/org.eclipse.persistence.jpa.jpql/src/main/java/org/eclipse/persistence/jpa/jpql/tools/model/query/StateObjectVisitor.java
index c7257038366..75fdd84d861 100644
--- a/jpa/org.eclipse.persistence.jpa.jpql/src/main/java/org/eclipse/persistence/jpa/jpql/tools/model/query/StateObjectVisitor.java
+++ b/jpa/org.eclipse.persistence.jpa.jpql/src/main/java/org/eclipse/persistence/jpa/jpql/tools/model/query/StateObjectVisitor.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2006, 2020 Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2006, 2023 Oracle and/or its affiliates. All rights reserved.
*
* This program and the accompanying materials are made available under the
* terms of the Eclipse Public License v. 2.0 which is available at
@@ -12,7 +12,8 @@
// Contributors:
// Oracle - initial API and implementation
-//
+// 06/02/2023: Radek Felcman
+// - Issue 1885: Implement new JPQLGrammar for upcoming Jakarta Persistence 3.2
package org.eclipse.persistence.jpa.jpql.tools.model.query;
/**
@@ -141,6 +142,13 @@ public interface StateObjectVisitor {
*/
void visit(ConcatExpressionStateObject stateObject);
+ /**
+ * Visits the given {@link ConcatPipesExpressionStateObject}.
+ *
+ * @param stateObject The {@link ConcatPipesExpressionStateObject} to visit
+ */
+ void visit(ConcatPipesExpressionStateObject stateObject);
+
/**
* Visits the given {@link ConstructorExpressionStateObject}.
*
diff --git a/jpa/org.eclipse.persistence.jpa.jpql/src/main/java/org/eclipse/persistence/jpa/jpql/tools/model/query/StringExpressionStateObject.java b/jpa/org.eclipse.persistence.jpa.jpql/src/main/java/org/eclipse/persistence/jpa/jpql/tools/model/query/StringExpressionStateObject.java
new file mode 100644
index 00000000000..e04b0cc98b0
--- /dev/null
+++ b/jpa/org.eclipse.persistence.jpa.jpql/src/main/java/org/eclipse/persistence/jpa/jpql/tools/model/query/StringExpressionStateObject.java
@@ -0,0 +1,95 @@
+/*
+ * Copyright (c) 2023 Oracle and/or its affiliates. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0,
+ * or the Eclipse Distribution License v. 1.0 which is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ *
+ * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
+ */
+
+// Contributors:
+// Oracle - initial API and implementation
+// 06/02/2023: Radek Felcman
+// - Issue 1885: Implement new JPQLGrammar for upcoming Jakarta Persistence 3.2
+package org.eclipse.persistence.jpa.jpql.tools.model.query;
+
+import org.eclipse.persistence.jpa.jpql.parser.StringExpression;
+import org.eclipse.persistence.jpa.jpql.parser.StringExpressionBNF;
+import org.eclipse.persistence.jpa.jpql.parser.StringTermBNF;
+
+/**
+ * This expression represents an arithmetic expression, which means the first and second expressions
+ * are aggregated with an arithmetic sign.
+ *
+ * BNF: arithmetic_expression ::= arithmetic_expression <identifier> arithmetic_term
StringExpressionStateObject
.
+ *
+ * @param parent The parent of this state object, which cannot be null
+ * @exception NullPointerException The given parent cannot be null
+ */
+ protected StringExpressionStateObject(StateObject parent) {
+ super(parent);
+ }
+
+ /**
+ * Creates a new StringExpressionStateObject
.
+ *
+ * @param parent The parent of this state object, which cannot be null
+ * @param leftStateObject The {@link StateObject} representing the left expression
+ * @param rightStateObject The {@link StateObject} representing the right expression
+ * @exception NullPointerException The given parent cannot be null
+ */
+ protected StringExpressionStateObject(StateObject parent,
+ StateObject leftStateObject,
+ StateObject rightStateObject) {
+
+ super(parent, leftStateObject, rightStateObject);
+ }
+
+ /**
+ * Creates a new StringExpressionStateObject
.
+ *
+ * @param parent The parent of this state object, which cannot be null
+ * @param leftJpqlFragment The string representation of the left expression to parse and to
+ * convert into a {@link StateObject}
+ * @param rightJpqlFragment The string representation of the right expression to parse and to
+ * convert into a {@link StateObject}
+ * @exception NullPointerException The given parent cannot be null
+ */
+ protected StringExpressionStateObject(StateObject parent,
+ String leftJpqlFragment,
+ String rightJpqlFragment) {
+
+ super(parent, leftJpqlFragment, rightJpqlFragment);
+ }
+
+ @Override
+ public StringExpression getExpression() {
+ return (StringExpression) super.getExpression();
+ }
+
+ @Override
+ protected String getLeftQueryBNFId() {
+ return StringExpressionBNF.ID;
+ }
+
+ @Override
+ protected String getRightQueryBNFId() {
+ return StringTermBNF.ID;
+ }
+}
diff --git a/jpa/org.eclipse.persistence.jpa.jpql/src/main/java/org/eclipse/persistence/jpa/jpql/tools/resolver/ResolverBuilder.java b/jpa/org.eclipse.persistence.jpa.jpql/src/main/java/org/eclipse/persistence/jpa/jpql/tools/resolver/ResolverBuilder.java
index 4f378fed81c..57084c71c48 100644
--- a/jpa/org.eclipse.persistence.jpa.jpql/src/main/java/org/eclipse/persistence/jpa/jpql/tools/resolver/ResolverBuilder.java
+++ b/jpa/org.eclipse.persistence.jpa.jpql/src/main/java/org/eclipse/persistence/jpa/jpql/tools/resolver/ResolverBuilder.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2006, 2022 Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2006, 2023 Oracle and/or its affiliates. All rights reserved.
*
* This program and the accompanying materials are made available under the
* terms of the Eclipse Public License v. 2.0 which is available at
@@ -15,6 +15,8 @@
// 04/21/2022: Tomas Kraus
// - Issue 1474: Update JPQL Grammar for Jakarta Persistence 2.2, 3.0 and 3.1
// - Issue 317: Implement LOCAL DATE, LOCAL TIME and LOCAL DATETIME.
+// 06/02/2023: Radek Felcman
+// - Issue 1885: Implement new JPQLGrammar for upcoming Jakarta Persistence 3.2
package org.eclipse.persistence.jpa.jpql.tools.resolver;
import java.sql.Date;
@@ -49,6 +51,7 @@
import org.eclipse.persistence.jpa.jpql.parser.CollectionValuedPathExpression;
import org.eclipse.persistence.jpa.jpql.parser.ComparisonExpression;
import org.eclipse.persistence.jpa.jpql.parser.ConcatExpression;
+import org.eclipse.persistence.jpa.jpql.parser.ConcatPipesExpression;
import org.eclipse.persistence.jpa.jpql.parser.ConstructorExpression;
import org.eclipse.persistence.jpa.jpql.parser.CountFunction;
import org.eclipse.persistence.jpa.jpql.parser.DateTime;
@@ -534,6 +537,11 @@ public void visit(ConcatExpression expression) {
resolver = buildClassResolver(String.class);
}
+ @Override
+ public void visit(ConcatPipesExpression expression) {
+ resolver = buildClassResolver(String.class);
+ }
+
@Override
public void visit(ConstructorExpression expression) {
diff --git a/jpa/org.eclipse.persistence.jpa.jpql/src/main/resources/org/eclipse/persistence/jpa/jpql/jpa_jpql_validation.properties b/jpa/org.eclipse.persistence.jpa.jpql/src/main/resources/org/eclipse/persistence/jpa/jpql/jpa_jpql_validation.properties
index 7056d03d587..fe1df3e4039 100644
--- a/jpa/org.eclipse.persistence.jpa.jpql/src/main/resources/org/eclipse/persistence/jpa/jpql/jpa_jpql_validation.properties
+++ b/jpa/org.eclipse.persistence.jpa.jpql/src/main/resources/org/eclipse/persistence/jpa/jpql/jpa_jpql_validation.properties
@@ -1,5 +1,5 @@
#
-# Copyright (c) 2006, 2020 Oracle and/or its affiliates. All rights reserved.
+# Copyright (c) 2006, 2023 Oracle and/or its affiliates. All rights reserved.
#
# This program and the accompanying materials are made available under the
# terms of the Eclipse Public License v. 2.0 which is available at
@@ -13,6 +13,8 @@
# Contributors:
# Oracle - initial API and implementation
+# 06/02/2023: Radek Felcman
+# - Issue 1885: Implement new JPQLGrammar for upcoming Jakarta Persistence 3.2
# AbsExpression - Grammar
ABS_EXPRESSION_INVALID_EXPRESSION = The encapsulated expression is not a valid expression.
@@ -487,6 +489,17 @@ SUB_EXPRESSION_MISSING_RIGHT_PARENTHESIS = The right parenthesis is missing from
SUBTRACTION_EXPRESSION_LEFT_EXPRESSION_WRONG_TYPE = The left side of the subtraction is not a valid arithmetic expression.
SUBTRACTION_EXPRESSION_RIGHT_EXPRESSION_WRONG_TYPE = The right side of the subtraction is not a valid arithmetic expression.
+# StringFactor - Grammar
+STRING_FACTOR_MISSING_EXPRESSION = An string factor must be followed by an expression.
+# StringFactor - Semantic
+STRING_FACTOR_INVALID_EXPRESSION = The expression must be an string expression.
+
+# StringExpression - Grammar
+STRING_EXPRESSION_INVALID_LEFT_EXPRESSION = The left expression is not an string expression.
+STRING_EXPRESSION_INVALID_RIGHT_EXPRESSION = The right expression is not an string expression.
+STRING_EXPRESSION_MISSING_LEFT_EXPRESSION = The left expression is missing from the string expression.
+STRING_EXPRESSION_MISSING_RIGHT_EXPRESSION = The right expression is missing from the string expression.
+
# SubstringExpression - Grammar
SUBSTRING_EXPRESSION_INVALID_FIRST_EXPRESSION = The first argument is not a valid expression.
SUBSTRING_EXPRESSION_INVALID_SECOND_EXPRESSION = The second argument is not a valid expression.
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
new file mode 100644
index 00000000000..901eeac9885
--- /dev/null
+++ b/jpa/org.eclipse.persistence.jpa.jpql/src/test/java/org/eclipse/persistence/jpa/tests/jpql/JPQLQueries3_2.java
@@ -0,0 +1,42 @@
+/*
+ * Copyright (c) 2023 Oracle and/or its affiliates. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0,
+ * or the Eclipse Distribution License v. 1.0 which is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ *
+ * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
+ */
+
+// Contributors:
+// 06/02/2023: Radek Felcman
+// - Issue 1885: Implement new JPQLGrammar for upcoming Jakarta Persistence 3.2
+package org.eclipse.persistence.jpa.tests.jpql;
+
+/**
+ * This class provides a list of queries that are written against the JPQL 3.2 grammar.
+ */
+public class JPQLQueries3_2 {
+
+ private JPQLQueries3_2() {
+ super();
+ }
+
+ public static String query_ConcatPipes_Select01() {
+ return "SELECT c.firstName || 'Smith' FROM Customer c";
+ }
+
+ public static String query_ConcatPipes_Select02() {
+ return "SELECT c.firstName || c.lastName FROM Customer c";
+ }
+
+ public static String query_ConcatPipes_Select_Chained() {
+ return "SELECT c.firstName || 'Francis' || 'Smith' FROM Customer c";
+ }
+
+ public static String query_ConcatPipes_Where() {
+ return "SELECT c FROM Customer c WHERE c.firstName || 'Smith' = 'JohnSmith'";
+ }
+}
diff --git a/jpa/org.eclipse.persistence.jpa.jpql/src/test/java/org/eclipse/persistence/jpa/tests/jpql/parser/AllJPQLParserTests.java b/jpa/org.eclipse.persistence.jpa.jpql/src/test/java/org/eclipse/persistence/jpa/tests/jpql/parser/AllJPQLParserTests.java
index 8397cadd267..d0901e5bbf2 100644
--- a/jpa/org.eclipse.persistence.jpa.jpql/src/test/java/org/eclipse/persistence/jpa/tests/jpql/parser/AllJPQLParserTests.java
+++ b/jpa/org.eclipse.persistence.jpa.jpql/src/test/java/org/eclipse/persistence/jpa/tests/jpql/parser/AllJPQLParserTests.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2011, 2022 Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2011, 2023 Oracle and/or its affiliates. All rights reserved.
*
* This program and the accompanying materials are made available under the
* terms of the Eclipse Public License v. 2.0 which is available at
@@ -30,6 +30,7 @@
AllJPQLParserTests2_0.class,
AllJPQLParserTests2_1.class,
AllJPQLParserTests3_1.class,
+ AllJPQLParserTests3_2.class,
AllEclipseLinkJPQLParserTests.class,
AllEclipseLinkJPQLParserTests2_1.class,
AllEclipseLinkJPQLParserTests2_4.class,
diff --git a/jpa/org.eclipse.persistence.jpa.jpql/src/test/java/org/eclipse/persistence/jpa/tests/jpql/parser/AllJPQLParserTests3_2.java b/jpa/org.eclipse.persistence.jpa.jpql/src/test/java/org/eclipse/persistence/jpa/tests/jpql/parser/AllJPQLParserTests3_2.java
new file mode 100644
index 00000000000..429b9f62f58
--- /dev/null
+++ b/jpa/org.eclipse.persistence.jpa.jpql/src/test/java/org/eclipse/persistence/jpa/tests/jpql/parser/AllJPQLParserTests3_2.java
@@ -0,0 +1,43 @@
+/*
+ * Copyright (c) 2023 Oracle and/or its affiliates. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0,
+ * or the Eclipse Distribution License v. 1.0 which is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ *
+ * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
+ */
+
+// Contributors:
+// Oracle - initial API and implementation
+// 06/02/2023: Radek Felcman
+// - Issue 1885: Implement new JPQLGrammar for upcoming Jakarta Persistence 3.2
+package org.eclipse.persistence.jpa.tests.jpql.parser;
+
+import org.eclipse.persistence.jpa.jpql.JPAVersion;
+import org.eclipse.persistence.jpa.jpql.parser.JPQLGrammar;
+import org.eclipse.persistence.jpa.tests.jpql.JPQLTestRunner;
+import org.junit.runner.RunWith;
+import org.junit.runners.Suite;
+
+/**
+ * This test suite runs {@link JPQLParserTests3_2} using JPQL grammar written for JPA 3.2.
+ */
+@Suite.SuiteClasses({
+ JPQLParserTests3_2.class
+})
+@RunWith(JPQLTestRunner.class)
+public class AllJPQLParserTests3_2 {
+
+ private AllJPQLParserTests3_2() {
+ super();
+ }
+
+ @JPQLGrammarTestHelper
+ static JPQLGrammar[] buildJPQLGrammars() {
+ return JPQLGrammarTools.allJPQLGrammars(JPAVersion.VERSION_3_2);
+ }
+
+}
diff --git a/jpa/org.eclipse.persistence.jpa.jpql/src/test/java/org/eclipse/persistence/jpa/tests/jpql/parser/JPQLGrammarTools.java b/jpa/org.eclipse.persistence.jpa.jpql/src/test/java/org/eclipse/persistence/jpa/tests/jpql/parser/JPQLGrammarTools.java
index 66b5644af6f..14f7d3392bb 100644
--- a/jpa/org.eclipse.persistence.jpa.jpql/src/test/java/org/eclipse/persistence/jpa/tests/jpql/parser/JPQLGrammarTools.java
+++ b/jpa/org.eclipse.persistence.jpa.jpql/src/test/java/org/eclipse/persistence/jpa/tests/jpql/parser/JPQLGrammarTools.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2012, 2022 Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2012, 2023 Oracle and/or its affiliates. All rights reserved.
*
* This program and the accompanying materials are made available under the
* terms of the Eclipse Public License v. 2.0 which is available at
@@ -14,6 +14,8 @@
// Oracle - initial API and implementation
// 04/21/2022: Tomas Kraus
// - Issue 1474: Update JPQL Grammar for Jakarta Persistence 2.2, 3.0 and 3.1
+// 06/02/2023: Radek Felcman
+// - Issue 1885: Implement new JPQLGrammar for upcoming Jakarta Persistence 3.2
package org.eclipse.persistence.jpa.tests.jpql.parser;
import org.eclipse.persistence.jpa.jpql.EclipseLinkVersion;
@@ -26,11 +28,13 @@
import org.eclipse.persistence.jpa.jpql.parser.EclipseLinkJPQLGrammar2_4;
import org.eclipse.persistence.jpa.jpql.parser.EclipseLinkJPQLGrammar2_5;
import org.eclipse.persistence.jpa.jpql.parser.EclipseLinkJPQLGrammar4_0;
+import org.eclipse.persistence.jpa.jpql.parser.EclipseLinkJPQLGrammar4_1;
import org.eclipse.persistence.jpa.jpql.parser.JPQLGrammar;
import org.eclipse.persistence.jpa.jpql.parser.JPQLGrammar1_0;
import org.eclipse.persistence.jpa.jpql.parser.JPQLGrammar2_0;
import org.eclipse.persistence.jpa.jpql.parser.JPQLGrammar2_1;
import org.eclipse.persistence.jpa.jpql.parser.JPQLGrammar3_1;
+import org.eclipse.persistence.jpa.jpql.parser.JPQLGrammar3_2;
/**
* This utility class provides an easy way of creating a list of {@link JPQLGrammar}, which is
@@ -76,6 +80,11 @@ public static JPQLGrammar[] allDefaultJPQLGrammars(JPAVersion minVersion) {
JPQLGrammar3_1.instance()
};
}
+ case VERSION_3_2: {
+ return new JPQLGrammar[] {
+ JPQLGrammar3_2.instance()
+ };
+ }
default: {
return new JPQLGrammar[0];
}
@@ -199,6 +208,12 @@ public static JPQLGrammar[] allJPQLGrammars(JPAVersion minVersion) {
EclipseLinkJPQLGrammar4_0.instance()
};
}
+ case VERSION_3_2: {
+ return new JPQLGrammar[] {
+ JPQLGrammar3_2.instance(),
+ EclipseLinkJPQLGrammar4_1.instance()
+ };
+ }
default: {
return new JPQLGrammar[0];
}
diff --git a/jpa/org.eclipse.persistence.jpa.jpql/src/test/java/org/eclipse/persistence/jpa/tests/jpql/parser/JPQLParserTest.java b/jpa/org.eclipse.persistence.jpa.jpql/src/test/java/org/eclipse/persistence/jpa/tests/jpql/parser/JPQLParserTest.java
index f698c4b5b73..6fc319b198e 100644
--- a/jpa/org.eclipse.persistence.jpa.jpql/src/test/java/org/eclipse/persistence/jpa/tests/jpql/parser/JPQLParserTest.java
+++ b/jpa/org.eclipse.persistence.jpa.jpql/src/test/java/org/eclipse/persistence/jpa/tests/jpql/parser/JPQLParserTest.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2006, 2022 Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2006, 2023 Oracle and/or its affiliates. All rights reserved.
*
* This program and the accompanying materials are made available under the
* terms of the Eclipse Public License v. 2.0 which is available at
@@ -14,6 +14,8 @@
// Oracle - initial API and implementation
// 04/21/2022: Tomas Kraus
// - Issue 1474: Update JPQL Grammar for Jakarta Persistence 2.2, 3.0 and 3.1
+// 06/02/2023: Radek Felcman
+// - Issue 1885: Implement new JPQLGrammar for upcoming Jakarta Persistence 3.2
package org.eclipse.persistence.jpa.tests.jpql.parser;
import org.eclipse.persistence.jpa.jpql.ExpressionTools;
@@ -48,6 +50,7 @@
import org.eclipse.persistence.jpa.jpql.parser.ComparisonExpression;
import org.eclipse.persistence.jpa.jpql.parser.CompoundExpression;
import org.eclipse.persistence.jpa.jpql.parser.ConcatExpression;
+import org.eclipse.persistence.jpa.jpql.parser.ConcatPipesExpression;
import org.eclipse.persistence.jpa.jpql.parser.ConnectByClause;
import org.eclipse.persistence.jpa.jpql.parser.ConstructorExpression;
import org.eclipse.persistence.jpa.jpql.parser.CountFunction;
@@ -2129,6 +2132,25 @@ protected String identifier() {
}
}
+ public static final class ConcatPipesExpressionTester extends CompoundExpressionTester {
+
+ protected ConcatPipesExpressionTester(ExpressionTester leftExpression,
+ ExpressionTester rightExpression) {
+
+ super(leftExpression, rightExpression);
+ }
+
+ @Override
+ protected Class extends CompoundExpression> expressionType() {
+ return ConcatPipesExpression.class;
+ }
+
+ @Override
+ protected String identifier() {
+ return CONCAT_PIPES;
+ }
+ }
+
public static final class ConnectByClauseTester extends AbstractExpressionTester {
private ExpressionTester expression;
diff --git a/jpa/org.eclipse.persistence.jpa.jpql/src/test/java/org/eclipse/persistence/jpa/tests/jpql/parser/JPQLParserTester.java b/jpa/org.eclipse.persistence.jpa.jpql/src/test/java/org/eclipse/persistence/jpa/tests/jpql/parser/JPQLParserTester.java
index 360bcd92c9f..7b6bb8c4e7e 100644
--- a/jpa/org.eclipse.persistence.jpa.jpql/src/test/java/org/eclipse/persistence/jpa/tests/jpql/parser/JPQLParserTester.java
+++ b/jpa/org.eclipse.persistence.jpa.jpql/src/test/java/org/eclipse/persistence/jpa/tests/jpql/parser/JPQLParserTester.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2012, 2022 Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2012, 2023 Oracle and/or its affiliates. All rights reserved.
*
* This program and the accompanying materials are made available under the
* terms of the Eclipse Public License v. 2.0 which is available at
@@ -42,6 +42,7 @@
import org.eclipse.persistence.jpa.tests.jpql.parser.JPQLParserTest.CollectionValuedPathExpressionTester;
import org.eclipse.persistence.jpa.tests.jpql.parser.JPQLParserTest.ComparisonExpressionTester;
import org.eclipse.persistence.jpa.tests.jpql.parser.JPQLParserTest.ConcatExpressionTester;
+import org.eclipse.persistence.jpa.tests.jpql.parser.JPQLParserTest.ConcatPipesExpressionTester;
import org.eclipse.persistence.jpa.tests.jpql.parser.JPQLParserTest.ConnectByClauseTester;
import org.eclipse.persistence.jpa.tests.jpql.parser.JPQLParserTest.ConstructorExpressionTester;
import org.eclipse.persistence.jpa.tests.jpql.parser.JPQLParserTest.CountFunctionTester;
@@ -440,6 +441,11 @@ public static ConcatExpressionTester concat(ExpressionTester... expressions) {
return new ConcatExpressionTester(expressions[0]);
}
+ public static ConcatPipesExpressionTester concatPipes(ExpressionTester leftExpression,
+ ExpressionTester rightExpression) {
+ return new ConcatPipesExpressionTester(leftExpression, rightExpression);
+ }
+
public static ConnectByClauseTester connectBy(ExpressionTester expression) {
return new ConnectByClauseTester(expression);
}
diff --git a/jpa/org.eclipse.persistence.jpa.jpql/src/test/java/org/eclipse/persistence/jpa/tests/jpql/parser/JPQLParserTests3_2.java b/jpa/org.eclipse.persistence.jpa.jpql/src/test/java/org/eclipse/persistence/jpa/tests/jpql/parser/JPQLParserTests3_2.java
new file mode 100644
index 00000000000..cbe7b889e56
--- /dev/null
+++ b/jpa/org.eclipse.persistence.jpa.jpql/src/test/java/org/eclipse/persistence/jpa/tests/jpql/parser/JPQLParserTests3_2.java
@@ -0,0 +1,36 @@
+/*
+ * Copyright (c) 2023 Oracle and/or its affiliates. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0,
+ * or the Eclipse Distribution License v. 1.0 which is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ *
+ * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
+ */
+
+// Contributors:
+// Oracle - initial API and implementation
+// 06/02/2023: Radek Felcman
+// - Issue 1885: Implement new JPQLGrammar for upcoming Jakarta Persistence 3.2
+package org.eclipse.persistence.jpa.tests.jpql.parser;
+
+import org.junit.runners.Suite;
+
+/**
+ * This test suite contains a series of unit-tests that test parsing JPQL queries that follows the
+ * JPQL grammar defined in Jakarta Persistence 3.2.
+ */
+@Suite.SuiteClasses({
+ // Test the parser with JPQL queries
+ JPQLQueriesTest3_2.class,
+
+})
+public class JPQLParserTests3_2 {
+
+ private JPQLParserTests3_2() {
+ super();
+ }
+
+}
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
new file mode 100644
index 00000000000..0e770eae0dd
--- /dev/null
+++ b/jpa/org.eclipse.persistence.jpa.jpql/src/test/java/org/eclipse/persistence/jpa/tests/jpql/parser/JPQLQueriesTest3_2.java
@@ -0,0 +1,119 @@
+/*
+ * Copyright (c) 2023 Oracle and/or its affiliates. All rights reserved.
+ *
+ * This program and the accompanying materials are made available under the
+ * terms of the Eclipse Public License v. 2.0 which is available at
+ * http://www.eclipse.org/legal/epl-2.0,
+ * or the Eclipse Distribution License v. 1.0 which is available at
+ * http://www.eclipse.org/org/documents/edl-v10.php.
+ *
+ * SPDX-License-Identifier: EPL-2.0 OR BSD-3-Clause
+ */
+
+// Contributors:
+// Oracle - initial API and implementation
+// 06/02/2023: Radek Felcman
+// - Issue 1885: Implement new JPQLGrammar for upcoming Jakarta Persistence 3.2
+package org.eclipse.persistence.jpa.tests.jpql.parser;
+
+import org.junit.Test;
+
+import static org.eclipse.persistence.jpa.tests.jpql.JPQLQueries2_0.query_013;
+import static org.eclipse.persistence.jpa.tests.jpql.JPQLQueries3_2.query_ConcatPipes_Select01;
+import static org.eclipse.persistence.jpa.tests.jpql.JPQLQueries3_2.query_ConcatPipes_Select02;
+import static org.eclipse.persistence.jpa.tests.jpql.JPQLQueries3_2.query_ConcatPipes_Select_Chained;
+import static org.eclipse.persistence.jpa.tests.jpql.JPQLQueries3_2.query_ConcatPipes_Where;
+import static org.eclipse.persistence.jpa.tests.jpql.parser.JPQLParserTester.concatPipes;
+import static org.eclipse.persistence.jpa.tests.jpql.parser.JPQLParserTester.from;
+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.resultVariable;
+import static org.eclipse.persistence.jpa.tests.jpql.parser.JPQLParserTester.select;
+import static org.eclipse.persistence.jpa.tests.jpql.parser.JPQLParserTester.selectStatement;
+import static org.eclipse.persistence.jpa.tests.jpql.parser.JPQLParserTester.string;
+import static org.eclipse.persistence.jpa.tests.jpql.parser.JPQLParserTester.variable;
+import static org.eclipse.persistence.jpa.tests.jpql.parser.JPQLParserTester.where;
+
+public class JPQLQueriesTest3_2 extends JPQLParserTest {
+
+ @Test
+ public void test_Query_ConcatPipes_Select01() {
+
+ // SELECT c.firstName || 'Smith' FROM Customer c
+ ExpressionTester selectStatement = selectStatement(
+ select(concatPipes(path("c.firstName"), string("'Smith'"))),
+ from("Customer", "c")
+ );
+ try {
+ testQuery(query_ConcatPipes_Select01(), selectStatement);
+ } catch (Throwable t) {
+ t.printStackTrace();
+ throw t;
+ }
+ }
+
+ @Test
+ public void test_Query_ConcatPipes_Select02() {
+
+ // SELECT c.firstName || c.lastName FROM Customer c
+ ExpressionTester selectStatement = selectStatement(
+ select(concatPipes(path("c.firstName"), path("c.lastName"))),
+ from("Customer", "c")
+ );
+ try {
+ testQuery(query_ConcatPipes_Select02(), selectStatement);
+ } catch (Throwable t) {
+ t.printStackTrace();
+ throw t;
+ }
+ }
+
+ @Test
+ public void test_Query_ConcatPipes_Select_Chained() {
+
+ // SELECT c.firstName || c.lastName FROM Customer c
+ ExpressionTester selectStatement = selectStatement(
+ select(concatPipes(concatPipes(path("c.firstName"), string("'Francis'")), string("'Smith'"))),
+ from("Customer", "c")
+ );
+ try {
+ testQuery(query_ConcatPipes_Select_Chained(), selectStatement);
+ } catch (Throwable t) {
+ t.printStackTrace();
+ throw t;
+ }
+ }
+
+ @Test
+ public void test_Query_ConcatPipes_Where() {
+
+ // SELECT c FROM Customer c WHERE c.firstName || 'Smith' = 'JohnSmith'
+ ExpressionTester selectStatement = selectStatement(
+ select(variable("c")),
+ from("Customer", "c"),
+ where(concatPipes(path("c.firstName"), string("'Smith'")).equal(string("'JohnSmith'")))
+ );
+ try {
+ testQuery(query_ConcatPipes_Where(), selectStatement);
+ } catch (Throwable t) {
+ t.printStackTrace();
+ throw t;
+ }
+ }
+
+
+// @Test
+ public void test_Query_013() {
+
+ // SELECT e.salary / 1000D n
+ // From Employee e
+
+ ExpressionTester selectStatement = selectStatement(
+ select(resultVariable(path("e.salary").divide(numeric("1000D")), "n")),
+ from("Employee", "e")
+ );
+
+ testQuery(query_013(), selectStatement);
+ }
+
+}
diff --git a/jpa/org.eclipse.persistence.jpa.jpql/src/test/java/org/eclipse/persistence/jpa/tests/jpql/parser/JPQLQueryBNFAccessor.java b/jpa/org.eclipse.persistence.jpa.jpql/src/test/java/org/eclipse/persistence/jpa/tests/jpql/parser/JPQLQueryBNFAccessor.java
index 322792abfdf..0359f8c6bdc 100644
--- a/jpa/org.eclipse.persistence.jpa.jpql/src/test/java/org/eclipse/persistence/jpa/tests/jpql/parser/JPQLQueryBNFAccessor.java
+++ b/jpa/org.eclipse.persistence.jpa.jpql/src/test/java/org/eclipse/persistence/jpa/tests/jpql/parser/JPQLQueryBNFAccessor.java
@@ -1,5 +1,5 @@
/*
- * Copyright (c) 2011, 2021 Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2011, 2023 Oracle and/or its affiliates. All rights reserved.
*
* This program and the accompanying materials are made available under the
* terms of the Eclipse Public License v. 2.0 which is available at
@@ -12,7 +12,8 @@
// Contributors:
// Oracle - initial API and implementation
-//
+// 06/02/2023: Radek Felcman
+// - Issue 1885: Implement new JPQLGrammar for upcoming Jakarta Persistence 3.2
package org.eclipse.persistence.jpa.tests.jpql.parser;
import java.util.ArrayList;
@@ -44,6 +45,7 @@
import org.eclipse.persistence.jpa.jpql.parser.SelectExpressionBNF;
import org.eclipse.persistence.jpa.jpql.parser.SimpleSelectExpressionBNF;
import org.eclipse.persistence.jpa.jpql.parser.StringExpressionBNF;
+import org.eclipse.persistence.jpa.jpql.parser.StringExpressionFactory;
import org.eclipse.persistence.jpa.jpql.utility.CollectionTools;
import org.eclipse.persistence.jpa.jpql.utility.iterable.ArrayIterable;
@@ -295,6 +297,11 @@ private Iterable