helper = getHelper(EXTRACT);
if (helper == null) {
@@ -273,11 +163,6 @@ protected InExpressionWithNestedArrayVisitor getInExpressionWithNestedArray() {
return inExpressionWithNestedArrayVisitor;
}
- @Override
- protected EclipseLinkOwningClauseVisitor getOwningClauseVisitor() {
- return (EclipseLinkOwningClauseVisitor) super.getOwningClauseVisitor();
- }
-
/**
* Determines whether the persistence provider is EclipseLink or not.
*
@@ -328,24 +213,6 @@ protected boolean isOwnedByInExpression(Expression expression) {
return visitor.expression != null;
}
- /**
- * Determines whether the given {@link Expression} is a child of the UNION clause.
- *
- * @param expression The {@link Expression} to visit its parent hierarchy up to the clause
- * @return true
if the first parent being a clause is the UNION clause;
- * false
otherwise
- */
- protected boolean isOwnedByUnionClause(Expression expression) {
- EclipseLinkOwningClauseVisitor visitor = getOwningClauseVisitor();
- try {
- expression.accept(visitor);
- return visitor.unionClause != null;
- }
- finally {
- visitor.dispose();
- }
- }
-
@Override
protected boolean isSubqueryAllowedAnywhere() {
EclipseLinkVersion version = EclipseLinkVersion.value(getProviderVersion());
diff --git a/jpa/org.eclipse.persistence.jpa.jpql/src/main/java/org/eclipse/persistence/jpa/jpql/EclipseLinkLiteralVisitor.java b/jpa/org.eclipse.persistence.jpa.jpql/src/main/java/org/eclipse/persistence/jpa/jpql/EclipseLinkLiteralVisitor.java
index 34ddb60680c..03aa33f6fb5 100644
--- a/jpa/org.eclipse.persistence.jpa.jpql/src/main/java/org/eclipse/persistence/jpa/jpql/EclipseLinkLiteralVisitor.java
+++ b/jpa/org.eclipse.persistence.jpa.jpql/src/main/java/org/eclipse/persistence/jpa/jpql/EclipseLinkLiteralVisitor.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
@@ -16,9 +16,7 @@
package org.eclipse.persistence.jpa.jpql;
import org.eclipse.persistence.jpa.jpql.parser.AsOfClause;
-import org.eclipse.persistence.jpa.jpql.parser.CastExpression;
import org.eclipse.persistence.jpa.jpql.parser.ConnectByClause;
-import org.eclipse.persistence.jpa.jpql.parser.DatabaseType;
import org.eclipse.persistence.jpa.jpql.parser.EclipseLinkExpressionVisitor;
import org.eclipse.persistence.jpa.jpql.parser.ExtractExpression;
import org.eclipse.persistence.jpa.jpql.parser.HierarchicalQueryClause;
@@ -27,7 +25,6 @@
import org.eclipse.persistence.jpa.jpql.parser.StartWithClause;
import org.eclipse.persistence.jpa.jpql.parser.TableExpression;
import org.eclipse.persistence.jpa.jpql.parser.TableVariableDeclaration;
-import org.eclipse.persistence.jpa.jpql.parser.UnionClause;
/**
* This visitor traverses an {@link org.eclipse.persistence.jpa.jpql.parser.Expression Expression}
@@ -58,21 +55,10 @@ public EclipseLinkLiteralVisitor() {
public void visit(AsOfClause expression) {
}
- @Override
- public void visit(CastExpression expression) {
- }
-
@Override
public void visit(ConnectByClause expression) {
}
- @Override
- public void visit(DatabaseType expression) {
- if (type == LiteralType.STRING_LITERAL) {
- literal = expression.getActualIdentifier();
- }
- }
-
@Override
public void visit(ExtractExpression expression) {
}
@@ -103,8 +89,4 @@ public void visit(TableExpression expression) {
@Override
public void visit(TableVariableDeclaration expression) {
}
-
- @Override
- public void visit(UnionClause expression) {
- }
}
diff --git a/jpa/org.eclipse.persistence.jpa.jpql/src/main/java/org/eclipse/persistence/jpa/jpql/LiteralVisitor.java b/jpa/org.eclipse.persistence.jpa.jpql/src/main/java/org/eclipse/persistence/jpa/jpql/LiteralVisitor.java
index 6b52c83ecf9..83b6a66509b 100644
--- a/jpa/org.eclipse.persistence.jpa.jpql/src/main/java/org/eclipse/persistence/jpa/jpql/LiteralVisitor.java
+++ b/jpa/org.eclipse.persistence.jpa.jpql/src/main/java/org/eclipse/persistence/jpa/jpql/LiteralVisitor.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
@@ -20,6 +20,7 @@
import org.eclipse.persistence.jpa.jpql.parser.AnonymousExpressionVisitor;
import org.eclipse.persistence.jpa.jpql.parser.CollectionMemberDeclaration;
import org.eclipse.persistence.jpa.jpql.parser.CollectionValuedPathExpression;
+import org.eclipse.persistence.jpa.jpql.parser.DatabaseType;
import org.eclipse.persistence.jpa.jpql.parser.EntityTypeLiteral;
import org.eclipse.persistence.jpa.jpql.parser.FunctionExpression;
import org.eclipse.persistence.jpa.jpql.parser.IdentificationVariable;
@@ -112,6 +113,13 @@ public void visit(CollectionValuedPathExpression expression) {
visitAbstractPathExpression(expression);
}
+ @Override
+ public void visit(DatabaseType expression) {
+ if (type == LiteralType.STRING_LITERAL) {
+ literal = expression.getActualIdentifier();
+ }
+ }
+
@Override
public void visit(EntityTypeLiteral expression) {
if (type == LiteralType.ENTITY_TYPE) {
diff --git a/jpa/org.eclipse.persistence.jpa.jpql/src/main/java/org/eclipse/persistence/jpa/jpql/ParameterTypeVisitor.java b/jpa/org.eclipse.persistence.jpa.jpql/src/main/java/org/eclipse/persistence/jpa/jpql/ParameterTypeVisitor.java
index 88fdf955508..3a3000b8286 100644
--- a/jpa/org.eclipse.persistence.jpa.jpql/src/main/java/org/eclipse/persistence/jpa/jpql/ParameterTypeVisitor.java
+++ b/jpa/org.eclipse.persistence.jpa.jpql/src/main/java/org/eclipse/persistence/jpa/jpql/ParameterTypeVisitor.java
@@ -37,6 +37,7 @@
import org.eclipse.persistence.jpa.jpql.parser.ConcatExpression;
import org.eclipse.persistence.jpa.jpql.parser.ConstructorExpression;
import org.eclipse.persistence.jpa.jpql.parser.CountFunction;
+import org.eclipse.persistence.jpa.jpql.parser.DatabaseType;
import org.eclipse.persistence.jpa.jpql.parser.DateTime;
import org.eclipse.persistence.jpa.jpql.parser.DivisionExpression;
import org.eclipse.persistence.jpa.jpql.parser.EmptyCollectionComparisonExpression;
@@ -308,6 +309,11 @@ public void visit(CountFunction expression) {
this.expression = expression;
}
+ @Override
+ public void visit(DatabaseType expression) {
+ type = Object.class;
+ }
+
@Override
public void visit(DateTime expression) {
// A date/time always have a type
diff --git a/jpa/org.eclipse.persistence.jpa.jpql/src/main/java/org/eclipse/persistence/jpa/jpql/parser/AbstractEclipseLinkExpressionVisitor.java b/jpa/org.eclipse.persistence.jpa.jpql/src/main/java/org/eclipse/persistence/jpa/jpql/parser/AbstractEclipseLinkExpressionVisitor.java
index 124eca85548..60c54dfae1c 100644
--- a/jpa/org.eclipse.persistence.jpa.jpql/src/main/java/org/eclipse/persistence/jpa/jpql/parser/AbstractEclipseLinkExpressionVisitor.java
+++ b/jpa/org.eclipse.persistence.jpa.jpql/src/main/java/org/eclipse/persistence/jpa/jpql/parser/AbstractEclipseLinkExpressionVisitor.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
@@ -40,18 +40,10 @@ protected AbstractEclipseLinkExpressionVisitor() {
public void visit(AsOfClause expression) {
}
- @Override
- public void visit(CastExpression expression) {
- }
-
@Override
public void visit(ConnectByClause expression) {
}
- @Override
- public void visit(DatabaseType expression) {
- }
-
@Override
public void visit(ExtractExpression expression) {
}
@@ -79,8 +71,4 @@ public void visit(TableExpression expression) {
@Override
public void visit(TableVariableDeclaration expression) {
}
-
- @Override
- public void visit(UnionClause expression) {
- }
}
diff --git a/jpa/org.eclipse.persistence.jpa.jpql/src/main/java/org/eclipse/persistence/jpa/jpql/parser/AbstractEclipseLinkTraverseChildrenVisitor.java b/jpa/org.eclipse.persistence.jpa.jpql/src/main/java/org/eclipse/persistence/jpa/jpql/parser/AbstractEclipseLinkTraverseChildrenVisitor.java
index 17c8569177a..bb2e49b7891 100644
--- a/jpa/org.eclipse.persistence.jpa.jpql/src/main/java/org/eclipse/persistence/jpa/jpql/parser/AbstractEclipseLinkTraverseChildrenVisitor.java
+++ b/jpa/org.eclipse.persistence.jpa.jpql/src/main/java/org/eclipse/persistence/jpa/jpql/parser/AbstractEclipseLinkTraverseChildrenVisitor.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
@@ -43,21 +43,11 @@ public void visit(AsOfClause expression) {
visit((Expression) expression);
}
- @Override
- public void visit(CastExpression expression) {
- visit((Expression) expression);
- }
-
@Override
public void visit(ConnectByClause expression) {
visit((Expression) expression);
}
- @Override
- public void visit(DatabaseType expression) {
- visit((Expression) expression);
- }
-
@Override
public void visit(ExtractExpression expression) {
visit((Expression) expression);
@@ -92,9 +82,4 @@ public void visit(TableExpression expression) {
public void visit(TableVariableDeclaration expression) {
visit((Expression) expression);
}
-
- @Override
- public void visit(UnionClause expression) {
- visit((Expression) expression);
- }
}
diff --git a/jpa/org.eclipse.persistence.jpa.jpql/src/main/java/org/eclipse/persistence/jpa/jpql/parser/AbstractEclipseLinkTraverseParentVisitor.java b/jpa/org.eclipse.persistence.jpa.jpql/src/main/java/org/eclipse/persistence/jpa/jpql/parser/AbstractEclipseLinkTraverseParentVisitor.java
index d2fb78b89b4..26e527952a3 100644
--- a/jpa/org.eclipse.persistence.jpa.jpql/src/main/java/org/eclipse/persistence/jpa/jpql/parser/AbstractEclipseLinkTraverseParentVisitor.java
+++ b/jpa/org.eclipse.persistence.jpa.jpql/src/main/java/org/eclipse/persistence/jpa/jpql/parser/AbstractEclipseLinkTraverseParentVisitor.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
@@ -42,21 +42,11 @@ public void visit(AsOfClause expression) {
visit((Expression) expression);
}
- @Override
- public void visit(CastExpression expression) {
- visit((Expression) expression);
- }
-
@Override
public void visit(ConnectByClause expression) {
visit((Expression) expression);
}
- @Override
- public void visit(DatabaseType expression) {
- visit((Expression) expression);
- }
-
@Override
public void visit(ExtractExpression expression) {
visit((Expression) expression);
@@ -91,9 +81,4 @@ public void visit(TableExpression expression) {
public void visit(TableVariableDeclaration expression) {
visit((Expression) expression);
}
-
- @Override
- public void visit(UnionClause expression) {
- visit((Expression) expression);
- }
}
diff --git a/jpa/org.eclipse.persistence.jpa.jpql/src/main/java/org/eclipse/persistence/jpa/jpql/parser/AbstractExpressionVisitor.java b/jpa/org.eclipse.persistence.jpa.jpql/src/main/java/org/eclipse/persistence/jpa/jpql/parser/AbstractExpressionVisitor.java
index 09b27587d90..01340a625a5 100644
--- a/jpa/org.eclipse.persistence.jpa.jpql/src/main/java/org/eclipse/persistence/jpa/jpql/parser/AbstractExpressionVisitor.java
+++ b/jpa/org.eclipse.persistence.jpa.jpql/src/main/java/org/eclipse/persistence/jpa/jpql/parser/AbstractExpressionVisitor.java
@@ -78,6 +78,10 @@ public void visit(BetweenExpression expression) {
public void visit(CaseExpression expression) {
}
+ @Override
+ public void visit(CastExpression expression) {
+ }
+
@Override
public void visit(CoalesceExpression expression) {
}
@@ -118,6 +122,10 @@ public void visit(ConstructorExpression expression) {
public void visit(CountFunction expression) {
}
+ @Override
+ public void visit(DatabaseType expression) {
+ }
+
@Override
public void visit(DateTime expression) {
}
@@ -418,6 +426,10 @@ public void visit(UpperExpression expression) {
public void visit(ValueExpression expression) {
}
+ @Override
+ public void visit(UnionClause expression) {
+ }
+
@Override
public void visit(WhenClause expression) {
}
diff --git a/jpa/org.eclipse.persistence.jpa.jpql/src/main/java/org/eclipse/persistence/jpa/jpql/parser/AnonymousExpressionVisitor.java b/jpa/org.eclipse.persistence.jpa.jpql/src/main/java/org/eclipse/persistence/jpa/jpql/parser/AnonymousExpressionVisitor.java
index dcefa23456d..debf38622fd 100644
--- a/jpa/org.eclipse.persistence.jpa.jpql/src/main/java/org/eclipse/persistence/jpa/jpql/parser/AnonymousExpressionVisitor.java
+++ b/jpa/org.eclipse.persistence.jpa.jpql/src/main/java/org/eclipse/persistence/jpa/jpql/parser/AnonymousExpressionVisitor.java
@@ -138,6 +138,11 @@ public void visit(CountFunction expression) {
visit((Expression) expression);
}
+ @Override
+ public void visit(DatabaseType expression) {
+ visit((Expression) expression);
+ }
+
@Override
public void visit(DateTime expression) {
visit((Expression) expression);
@@ -186,6 +191,11 @@ public void visit(ExistsExpression expression) {
protected void visit(Expression expression) {
}
+ @Override
+ public void visit(CastExpression expression) {
+ visit((Expression) expression);
+ }
+
@Override
public void visit(FromClause expression) {
visit((Expression) expression);
@@ -530,4 +540,9 @@ public void visit(WhenClause expression) {
public void visit(WhereClause expression) {
visit((Expression) expression);
}
+
+ @Override
+ public void visit(UnionClause expression) {
+ visit((Expression) expression);
+ }
}
diff --git a/jpa/org.eclipse.persistence.jpa.jpql/src/main/java/org/eclipse/persistence/jpa/jpql/parser/EclipseLinkAnonymousExpressionVisitor.java b/jpa/org.eclipse.persistence.jpa.jpql/src/main/java/org/eclipse/persistence/jpa/jpql/parser/EclipseLinkAnonymousExpressionVisitor.java
index 55f410fd85b..d22f7e3bf2e 100644
--- a/jpa/org.eclipse.persistence.jpa.jpql/src/main/java/org/eclipse/persistence/jpa/jpql/parser/EclipseLinkAnonymousExpressionVisitor.java
+++ b/jpa/org.eclipse.persistence.jpa.jpql/src/main/java/org/eclipse/persistence/jpa/jpql/parser/EclipseLinkAnonymousExpressionVisitor.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
@@ -42,21 +42,11 @@ public void visit(AsOfClause expression) {
visit((Expression) expression);
}
- @Override
- public void visit(CastExpression expression) {
- visit((Expression) expression);
- }
-
@Override
public void visit(ConnectByClause expression) {
visit((Expression) expression);
}
- @Override
- public void visit(DatabaseType expression) {
- visit((Expression) expression);
- }
-
@Override
public void visit(ExtractExpression expression) {
visit((Expression) expression);
@@ -91,9 +81,4 @@ public void visit(TableExpression expression) {
public void visit(TableVariableDeclaration expression) {
visit((Expression) expression);
}
-
- @Override
- public void visit(UnionClause expression) {
- visit((Expression) expression);
- }
}
diff --git a/jpa/org.eclipse.persistence.jpa.jpql/src/main/java/org/eclipse/persistence/jpa/jpql/parser/EclipseLinkExpressionVisitor.java b/jpa/org.eclipse.persistence.jpa.jpql/src/main/java/org/eclipse/persistence/jpa/jpql/parser/EclipseLinkExpressionVisitor.java
index 663ee9c747f..8291bd88db9 100644
--- a/jpa/org.eclipse.persistence.jpa.jpql/src/main/java/org/eclipse/persistence/jpa/jpql/parser/EclipseLinkExpressionVisitor.java
+++ b/jpa/org.eclipse.persistence.jpa.jpql/src/main/java/org/eclipse/persistence/jpa/jpql/parser/EclipseLinkExpressionVisitor.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
@@ -45,13 +45,6 @@ public interface EclipseLinkExpressionVisitor extends ExpressionVisitor {
*/
void visit(AsOfClause expression);
- /**
- * Visits the {@link CastExpression} expression.
- *
- * @param expression The {@link Expression} to visit
- */
- void visit(CastExpression expression);
-
/**
* Visits the {@link ConnectByClause} expression.
*
@@ -59,13 +52,6 @@ public interface EclipseLinkExpressionVisitor extends ExpressionVisitor {
*/
void visit(ConnectByClause expression);
- /**
- * Visits the {@link DatabaseType} expression.
- *
- * @param expression The {@link DatabaseType} to visit
- */
- void visit(DatabaseType expression);
-
/**
* Visits the {@link ExtractExpression} expression.
*
@@ -114,11 +100,4 @@ public interface EclipseLinkExpressionVisitor extends ExpressionVisitor {
* @param expression The {@link Expression} to visit
*/
void visit(TableVariableDeclaration expression);
-
- /**
- * Visits the {@link UnionClause} expression.
- *
- * @param expression The {@link Expression} to visit
- */
- void visit(UnionClause expression);
}
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 3ce9dd54785..e2034cee522 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
@@ -102,6 +102,13 @@ public interface ExpressionVisitor {
*/
void visit(CaseExpression expression);
+ /**
+ * Visits the {@link CastExpression} expression.
+ *
+ * @param expression The {@link Expression} to visit
+ */
+ void visit(CastExpression expression);
+
/**
* Visits the {@link CoalesceExpression} expression.
*
@@ -172,6 +179,13 @@ public interface ExpressionVisitor {
*/
void visit(CountFunction expression);
+ /**
+ * Visits the {@link DatabaseType} expression.
+ *
+ * @param expression The {@link DatabaseType} to visit
+ */
+ void visit(DatabaseType expression);
+
/**
* Visits the {@link DateTime} expression.
*
@@ -710,4 +724,11 @@ public interface ExpressionVisitor {
* @param expression The {@link WhereClause} to visit
*/
void visit(WhereClause expression);
+
+ /**
+ * Visits the {@link UnionClause} expression.
+ *
+ * @param expression The {@link UnionClause} to visit
+ */
+ void visit(UnionClause expression);
}
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 f848a2e393b..97d63d58b12 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
@@ -18,19 +18,31 @@
import org.eclipse.persistence.jpa.jpql.ExpressionTools;
import org.eclipse.persistence.jpa.jpql.JPAVersion;
+import static org.eclipse.persistence.jpa.jpql.parser.Expression.CAST;
import static org.eclipse.persistence.jpa.jpql.parser.Expression.CONCAT_PIPES;
+import static org.eclipse.persistence.jpa.jpql.parser.Expression.EXCEPT;
+import static org.eclipse.persistence.jpa.jpql.parser.Expression.INTERSECT;
import static org.eclipse.persistence.jpa.jpql.parser.Expression.LEFT;
import static org.eclipse.persistence.jpa.jpql.parser.Expression.REPLACE;
import static org.eclipse.persistence.jpa.jpql.parser.Expression.RIGHT;
+import static org.eclipse.persistence.jpa.jpql.parser.Expression.UNION;
/**
* This {@link JPQLGrammar} provides support for parsing JPQL queries defined in Jakarta Persistence 3.2.
- *
+ * select_statement ::= select_clause from_clause [where_clause] [groupby_clause] [having_clause] [orderby_clause] {union_clause}*
+ *
+ * union_clause ::= { UNION | INTERSECT | EXCEPT} [ALL] subquery
*
* string_expression ::= string_expression || string_term
*
* functions_returning_strings ::= REPLACE(string_primary, string_primary, string_primary)
*
+ * functions_returning_string ::= LEFT(string_primary, simple_arithmetic_expression})
+ *
+ * functions_returning_string ::= RIGHT(string_primary, simple_arithmetic_expression})
+ *
+ * cast_expression ::= CAST(scalar_expression [AS] database_type)
+ *
*
*/
public class JPQLGrammar3_2 extends AbstractJPQLGrammar {
@@ -109,12 +121,20 @@ protected void initializeBNFs() {
registerBNF(new InternalLeftStringExpressionBNF());
registerBNF(new InternalRightPositionExpressionBNF());
registerBNF(new InternalRightStringExpressionBNF());
+ registerBNF(new UnionClauseBNF());
+ registerBNF(new CastExpressionBNF());
+ registerBNF(new DatabaseTypeQueryBNF());
// Extend some query BNFs
addChildBNF(StringPrimaryBNF.ID, SimpleStringExpressionBNF.ID);
addChildFactory(FunctionsReturningStringsBNF.ID, ReplaceExpressionFactory.ID);
addChildFactory(FunctionsReturningStringsBNF.ID, LeftExpressionFactory.ID);
addChildFactory(FunctionsReturningStringsBNF.ID, RightExpressionFactory.ID);
+
+ // CAST
+ addChildBNF(FunctionsReturningDatetimeBNF.ID, CastExpressionBNF.ID);
+ addChildBNF(FunctionsReturningNumericsBNF.ID, CastExpressionBNF.ID);
+ addChildBNF(FunctionsReturningStringsBNF.ID, CastExpressionBNF.ID);
}
@Override
@@ -123,6 +143,9 @@ protected void initializeExpressionFactories() {
registerFactory(new ReplaceExpressionFactory());
registerFactory(new LeftExpressionFactory());
registerFactory(new RightExpressionFactory());
+ registerFactory(new UnionClauseFactory());
+ registerFactory(new DatabaseTypeFactory());
+ registerFactory(new CastExpressionFactory());
}
@Override
@@ -135,6 +158,14 @@ protected void initializeIdentifiers() {
registerIdentifierVersion(LEFT, JPAVersion.VERSION_3_2);
registerIdentifierRole(RIGHT, IdentifierRole.FUNCTION); // REPLACE(x, y)
registerIdentifierVersion(RIGHT, JPAVersion.VERSION_3_2);
+ registerIdentifierRole(UNION, IdentifierRole.CLAUSE);
+ registerIdentifierVersion(UNION, JPAVersion.VERSION_3_2);
+ registerIdentifierRole(INTERSECT, IdentifierRole.CLAUSE);
+ registerIdentifierVersion(INTERSECT, JPAVersion.VERSION_3_2);
+ registerIdentifierRole(EXCEPT, IdentifierRole.CLAUSE);
+ registerIdentifierVersion(EXCEPT, JPAVersion.VERSION_3_2);
+ registerIdentifierRole(CAST, IdentifierRole.FUNCTION); // FUNCTION(n, x1, ..., x2)
+ registerIdentifierVersion(CAST, JPAVersion.VERSION_3_2);
}
@Override
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 6c528d8bfcb..9bd4568e197 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
@@ -66,6 +66,7 @@
import org.eclipse.persistence.jpa.jpql.parser.BetweenExpression;
import org.eclipse.persistence.jpa.jpql.parser.CaseExpression;
import org.eclipse.persistence.jpa.jpql.parser.CaseOperandBNF;
+import org.eclipse.persistence.jpa.jpql.parser.CastExpression;
import org.eclipse.persistence.jpa.jpql.parser.CoalesceExpression;
import org.eclipse.persistence.jpa.jpql.parser.CollectionExpression;
import org.eclipse.persistence.jpa.jpql.parser.CollectionMemberDeclaration;
@@ -81,6 +82,7 @@
import org.eclipse.persistence.jpa.jpql.parser.ConstructorExpression;
import org.eclipse.persistence.jpa.jpql.parser.ConstructorItemBNF;
import org.eclipse.persistence.jpa.jpql.parser.CountFunction;
+import org.eclipse.persistence.jpa.jpql.parser.DatabaseType;
import org.eclipse.persistence.jpa.jpql.parser.DateTime;
import org.eclipse.persistence.jpa.jpql.parser.DeleteClause;
import org.eclipse.persistence.jpa.jpql.parser.DeleteStatement;
@@ -168,6 +170,7 @@
import org.eclipse.persistence.jpa.jpql.parser.TrimExpression;
import org.eclipse.persistence.jpa.jpql.parser.TypeExpression;
import org.eclipse.persistence.jpa.jpql.parser.UnknownExpression;
+import org.eclipse.persistence.jpa.jpql.parser.UnionClause;
import org.eclipse.persistence.jpa.jpql.parser.UpdateClause;
import org.eclipse.persistence.jpa.jpql.parser.UpdateItem;
import org.eclipse.persistence.jpa.jpql.parser.UpdateStatement;
@@ -2657,6 +2660,51 @@ else if (expression.hasSpaceAfterCase()) {
}
}
+ @Override
+ public void visit(CastExpression expression) {
+ super.visit(expression);
+ int position = queryPosition.getPosition(expression) - corrections.peek();
+ String identifier = expression.getIdentifier();
+
+ // Within CAST
+ if (isPositionWithin(position, identifier)) {
+ addIdentifier(identifier);
+ addIdentificationVariables();
+ addFunctionIdentifiers(expression.getParent().findQueryBNF(expression));
+ }
+ // After "CAST("
+ else if (expression.hasLeftParenthesis()) {
+ int length = identifier.length() + 1 /* '(' */;
+
+ // Right after "CAST("
+ if (position == length) {
+ addIdentificationVariables();
+ addFunctionIdentifiers(expression.getEncapsulatedExpressionQueryBNFId());
+ }
+ else if (expression.hasExpression()) {
+ Expression scalarExpression = expression.getExpression();
+
+ if (isComplete(scalarExpression)) {
+ length += scalarExpression.getLength();
+
+ if (expression.hasSpaceAfterExpression()) {
+ length++;
+
+ // Right before "AS" or database type
+ if (position == length) {
+ addAggregateIdentifiers(expression.getEncapsulatedExpressionQueryBNFId());
+ proposals.addIdentifier(AS);
+ }
+ // Within "AS"
+ else if (isPositionWithin(position, length, AS)) {
+ proposals.addIdentifier(AS);
+ }
+ }
+ }
+ }
+ }
+ }
+
@Override
public void visit(CoalesceExpression expression) {
super.visit(expression);
@@ -2881,6 +2929,12 @@ public void visit(CountFunction expression) {
visitAggregateFunction(expression);
}
+ @Override
+ public void visit(DatabaseType expression) {
+ super.visit(expression);
+ // Nothing to do, this is database specific
+ }
+
@Override
public void visit(DateTime expression) {
super.visit(expression);
@@ -3849,6 +3903,58 @@ public void visit(TypeExpression expression) {
visitSingleEncapsulatedExpression(expression, IdentificationVariableType.ALL);
}
+ @Override
+ public void visit(UnionClause expression) {
+ super.visit(expression);
+ int position = queryPosition.getPosition(expression) - corrections.peek();
+ String identifier = expression.getIdentifier();
+
+ // Within
+ if (isPositionWithin(position, identifier)) {
+ proposals.addIdentifier(EXCEPT);
+ proposals.addIdentifier(INTERSECT);
+ proposals.addIdentifier(UNION);
+ }
+ // After " "
+ else if (expression.hasSpaceAfterIdentifier()) {
+ int length = identifier.length() + SPACE_LENGTH;
+
+ // Right after " "
+ if (position == length) {
+ proposals.addIdentifier(ALL);
+
+ if (!expression.hasAll()) {
+ addIdentifier(SELECT);
+ }
+ }
+ // Within "ALL"
+ else if (isPositionWithin(position, length, ALL)) {
+ addIdentifier(ALL);
+ }
+ else {
+ if ((position == length) && !expression.hasAll()) {
+ proposals.addIdentifier(SELECT);
+ }
+ else {
+
+ if (expression.hasAll()) {
+ length += 3 /* ALL */;
+ }
+
+ // After "ALL "
+ if (expression.hasSpaceAfterAll()) {
+ length += SPACE_LENGTH;
+
+ // Right after "ALL "
+ if (position == length) {
+ proposals.addIdentifier(SELECT);
+ }
+ }
+ }
+ }
+ }
+ }
+
@Override
public void visit(UnknownExpression expression) {
super.visit(expression);
@@ -5534,6 +5640,12 @@ public void visit(CaseExpression expression) {
expression.hasEnd();
}
+ @Override
+ public void visit(CastExpression expression) {
+ appendable = !conditionalExpression &&
+ expression.hasRightParenthesis();
+ }
+
@Override
public void visit(CoalesceExpression expression) {
appendable = !conditionalExpression &&
@@ -5653,6 +5765,11 @@ public void visit(CountFunction expression) {
expression.hasRightParenthesis();
}
+ @Override
+ public void visit(DatabaseType expression) {
+ // Always complete since it's a single word
+ }
+
@Override
public void visit(DateTime expression) {
@@ -7390,6 +7507,28 @@ else if (expression.hasCaseOperand()) {
}
}
+ @Override
+ public void visit(CastExpression expression) {
+
+ if (badExpression) {
+ return;
+ }
+
+ if (expression.hasScalarExpression() &&
+ !expression.hasAs() &&
+ !expression.hasDatabaseType() &&
+ !expression.hasRightParenthesis()) {
+
+ expression.getExpression().accept(this);
+ }
+
+ if (queryPosition.getExpression() == null) {
+ queryPosition.setExpression(expression);
+ }
+
+ queryPosition.addPosition(expression, expression.getLength() - correction);
+ }
+
@Override
public void visit(CoalesceExpression expression) {
visitAbstractSingleEncapsulatedExpression(expression);
@@ -7565,6 +7704,11 @@ public void visit(CountFunction expression) {
visitAbstractSingleEncapsulatedExpression(expression);
}
+ @Override
+ public void visit(DatabaseType expression) {
+ visitAbstractDoubleEncapsulatedExpression(expression);
+ }
+
@Override
public void visit(DateTime expression) {
@@ -8425,6 +8569,24 @@ public void visit(TypeExpression expression) {
visitAbstractSingleEncapsulatedExpression(expression);
}
+ @Override
+ public void visit(UnionClause expression) {
+
+ if (badExpression) {
+ return;
+ }
+
+ if (expression.hasQuery()) {
+ expression.getQuery().accept(this);
+ }
+
+ if (queryPosition.getExpression() == null) {
+ queryPosition.setExpression(expression);
+ }
+
+ queryPosition.addPosition(expression, expression.getLength() - correction);
+ }
+
@Override
public void visit(UnknownExpression expression) {
// Nothing to do, this is the expression that needs
diff --git a/jpa/org.eclipse.persistence.jpa.jpql/src/main/java/org/eclipse/persistence/jpa/jpql/tools/DefaultGrammarValidator.java b/jpa/org.eclipse.persistence.jpa.jpql/src/main/java/org/eclipse/persistence/jpa/jpql/tools/DefaultGrammarValidator.java
index dcf0e0b55e6..4539a21df17 100644
--- a/jpa/org.eclipse.persistence.jpa.jpql/src/main/java/org/eclipse/persistence/jpa/jpql/tools/DefaultGrammarValidator.java
+++ b/jpa/org.eclipse.persistence.jpa.jpql/src/main/java/org/eclipse/persistence/jpa/jpql/tools/DefaultGrammarValidator.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
@@ -54,11 +54,6 @@ protected LiteralVisitor buildLiteralVisitor() {
return new DefaultLiteralVisitor();
}
- @Override
- protected OwningClauseVisitor buildOwningClauseVisitor() {
- return new OwningClauseVisitor();
- }
-
@Override
protected boolean isJoinFetchIdentifiable() {
return false;
diff --git a/jpa/org.eclipse.persistence.jpa.jpql/src/main/java/org/eclipse/persistence/jpa/jpql/tools/EclipseLinkContentAssistVisitor.java b/jpa/org.eclipse.persistence.jpa.jpql/src/main/java/org/eclipse/persistence/jpa/jpql/tools/EclipseLinkContentAssistVisitor.java
index f3c00cc4841..0ca0169edd2 100644
--- a/jpa/org.eclipse.persistence.jpa.jpql/src/main/java/org/eclipse/persistence/jpa/jpql/tools/EclipseLinkContentAssistVisitor.java
+++ b/jpa/org.eclipse.persistence.jpa.jpql/src/main/java/org/eclipse/persistence/jpa/jpql/tools/EclipseLinkContentAssistVisitor.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
@@ -16,7 +16,6 @@
package org.eclipse.persistence.jpa.jpql.tools;
import static org.eclipse.persistence.jpa.jpql.parser.AbstractExpression.DOT;
-import static org.eclipse.persistence.jpa.jpql.parser.Expression.ALL;
import static org.eclipse.persistence.jpa.jpql.parser.Expression.AS;
import static org.eclipse.persistence.jpa.jpql.parser.Expression.AS_OF;
import static org.eclipse.persistence.jpa.jpql.parser.Expression.CONNECT_BY;
@@ -46,11 +45,9 @@
import org.eclipse.persistence.jpa.jpql.parser.AbstractPathExpression;
import org.eclipse.persistence.jpa.jpql.parser.AbstractSelectStatement;
import org.eclipse.persistence.jpa.jpql.parser.AsOfClause;
-import org.eclipse.persistence.jpa.jpql.parser.CastExpression;
import org.eclipse.persistence.jpa.jpql.parser.CollectionExpression;
import org.eclipse.persistence.jpa.jpql.parser.CollectionValuedPathExpressionBNF;
import org.eclipse.persistence.jpa.jpql.parser.ConnectByClause;
-import org.eclipse.persistence.jpa.jpql.parser.DatabaseType;
import org.eclipse.persistence.jpa.jpql.parser.DefaultEclipseLinkJPQLGrammar;
import org.eclipse.persistence.jpa.jpql.parser.EclipseLinkExpressionVisitor;
import org.eclipse.persistence.jpa.jpql.parser.Expression;
@@ -290,51 +287,6 @@ else if (expression.hasTimestamp()) {
}
}
- @Override
- public void visit(CastExpression expression) {
- super.visit(expression);
- int position = queryPosition.getPosition(expression) - corrections.peek();
- String identifier = expression.getIdentifier();
-
- // Within CAST
- if (isPositionWithin(position, identifier)) {
- addIdentifier(identifier);
- addIdentificationVariables();
- addFunctionIdentifiers(expression.getParent().findQueryBNF(expression));
- }
- // After "CAST("
- else if (expression.hasLeftParenthesis()) {
- int length = identifier.length() + 1 /* '(' */;
-
- // Right after "CAST("
- if (position == length) {
- addIdentificationVariables();
- addFunctionIdentifiers(expression.getEncapsulatedExpressionQueryBNFId());
- }
- else if (expression.hasExpression()) {
- Expression scalarExpression = expression.getExpression();
-
- if (isComplete(scalarExpression)) {
- length += scalarExpression.getLength();
-
- if (expression.hasSpaceAfterExpression()) {
- length++;
-
- // Right before "AS" or database type
- if (position == length) {
- addAggregateIdentifiers(expression.getEncapsulatedExpressionQueryBNFId());
- proposals.addIdentifier(AS);
- }
- // Within "AS"
- else if (isPositionWithin(position, length, AS)) {
- proposals.addIdentifier(AS);
- }
- }
- }
- }
- }
- }
-
@Override
public void visit(ConnectByClause expression) {
super.visit(expression);
@@ -357,12 +309,6 @@ else if (expression.hasSpaceAfterConnectBy()) {
}
}
- @Override
- public void visit(DatabaseType expression) {
- super.visit(expression);
- // Nothing to do, this is database specific
- }
-
@Override
public void visit(ExtractExpression expression) {
super.visit(expression);
@@ -647,58 +593,6 @@ public void visit(TableVariableDeclaration expression) {
}
}
- @Override
- public void visit(UnionClause expression) {
- super.visit(expression);
- int position = queryPosition.getPosition(expression) - corrections.peek();
- String identifier = expression.getIdentifier();
-
- // Within
- if (isPositionWithin(position, identifier)) {
- proposals.addIdentifier(EXCEPT);
- proposals.addIdentifier(INTERSECT);
- proposals.addIdentifier(UNION);
- }
- // After " "
- else if (expression.hasSpaceAfterIdentifier()) {
- int length = identifier.length() + SPACE_LENGTH;
-
- // Right after " "
- if (position == length) {
- proposals.addIdentifier(ALL);
-
- if (!expression.hasAll()) {
- addIdentifier(SELECT);
- }
- }
- // Within "ALL"
- else if (isPositionWithin(position, length, ALL)) {
- addIdentifier(ALL);
- }
- else {
- if ((position == length) && !expression.hasAll()) {
- proposals.addIdentifier(SELECT);
- }
- else {
-
- if (expression.hasAll()) {
- length += 3 /* ALL */;
- }
-
- // After "ALL "
- if (expression.hasSpaceAfterAll()) {
- length += SPACE_LENGTH;
-
- // Right after "ALL "
- if (position == length) {
- proposals.addIdentifier(SELECT);
- }
- }
- }
- }
- }
- }
-
@Override
protected void visitThirdPartyPathExpression(AbstractPathExpression expression,
String variableName) {
@@ -740,12 +634,6 @@ public void visit(AsOfClause expression) {
}
}
- @Override
- public void visit(CastExpression expression) {
- appendable = !conditionalExpression &&
- expression.hasRightParenthesis();
- }
-
@Override
public void visit(ConnectByClause expression) {
if (expression.hasExpression()) {
@@ -753,11 +641,6 @@ public void visit(ConnectByClause expression) {
}
}
- @Override
- public void visit(DatabaseType expression) {
- // Always complete since it's a single word
- }
-
@Override
public void visit(ExtractExpression expression) {
appendable = !conditionalExpression &&
@@ -817,13 +700,6 @@ public void visit(TableVariableDeclaration expression) {
expression.getIdentificationVariable().accept(this);
}
}
-
- @Override
- public void visit(UnionClause expression) {
- if (expression.hasQuery()) {
- expression.getQuery().accept(this);
- }
- }
}
// Made static final for performance reasons.
@@ -852,28 +728,6 @@ public void visit(AsOfClause expression) {
queryPosition.addPosition(expression, expression.getLength() - correction);
}
- @Override
- public void visit(CastExpression expression) {
-
- if (badExpression) {
- return;
- }
-
- if (expression.hasScalarExpression() &&
- !expression.hasAs() &&
- !expression.hasDatabaseType() &&
- !expression.hasRightParenthesis()) {
-
- expression.getExpression().accept(this);
- }
-
- if (queryPosition.getExpression() == null) {
- queryPosition.setExpression(expression);
- }
-
- queryPosition.addPosition(expression, expression.getLength() - correction);
- }
-
@Override
public void visit(ConnectByClause expression) {
@@ -892,11 +746,6 @@ public void visit(ConnectByClause expression) {
queryPosition.addPosition(expression, expression.getLength() - correction);
}
- @Override
- public void visit(DatabaseType expression) {
- visitAbstractDoubleEncapsulatedExpression(expression);
- }
-
@Override
public void visit(ExtractExpression expression) {
visitAbstractSingleEncapsulatedExpression(expression);
@@ -998,24 +847,6 @@ else if (!expression.hasAs()) {
queryPosition.addPosition(expression, expression.getLength() - correction);
}
-
- @Override
- public void visit(UnionClause expression) {
-
- if (badExpression) {
- return;
- }
-
- if (expression.hasQuery()) {
- expression.getQuery().accept(this);
- }
-
- if (queryPosition.getExpression() == null) {
- queryPosition.setExpression(expression);
- }
-
- queryPosition.addPosition(expression, expression.getLength() - correction);
- }
}
// Made static final for performance reasons.
diff --git a/jpa/org.eclipse.persistence.jpa.jpql/src/main/java/org/eclipse/persistence/jpa/jpql/tools/EclipseLinkResolverBuilder.java b/jpa/org.eclipse.persistence.jpa.jpql/src/main/java/org/eclipse/persistence/jpa/jpql/tools/EclipseLinkResolverBuilder.java
index c4eff81f522..6a669974bc3 100644
--- a/jpa/org.eclipse.persistence.jpa.jpql/src/main/java/org/eclipse/persistence/jpa/jpql/tools/EclipseLinkResolverBuilder.java
+++ b/jpa/org.eclipse.persistence.jpa.jpql/src/main/java/org/eclipse/persistence/jpa/jpql/tools/EclipseLinkResolverBuilder.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
@@ -16,9 +16,7 @@
package org.eclipse.persistence.jpa.jpql.tools;
import org.eclipse.persistence.jpa.jpql.parser.AsOfClause;
-import org.eclipse.persistence.jpa.jpql.parser.CastExpression;
import org.eclipse.persistence.jpa.jpql.parser.ConnectByClause;
-import org.eclipse.persistence.jpa.jpql.parser.DatabaseType;
import org.eclipse.persistence.jpa.jpql.parser.EclipseLinkExpressionVisitor;
import org.eclipse.persistence.jpa.jpql.parser.ExtractExpression;
import org.eclipse.persistence.jpa.jpql.parser.HierarchicalQueryClause;
@@ -27,7 +25,6 @@
import org.eclipse.persistence.jpa.jpql.parser.StartWithClause;
import org.eclipse.persistence.jpa.jpql.parser.TableExpression;
import org.eclipse.persistence.jpa.jpql.parser.TableVariableDeclaration;
-import org.eclipse.persistence.jpa.jpql.parser.UnionClause;
import org.eclipse.persistence.jpa.jpql.tools.resolver.ResolverBuilder;
/**
@@ -59,21 +56,11 @@ public void visit(AsOfClause expression) {
resolver = buildClassResolver(Object.class);
}
- @Override
- public void visit(CastExpression expression) {
- resolver = buildClassResolver(Object.class);
- }
-
@Override
public void visit(ConnectByClause expression) {
resolver = buildClassResolver(Object.class);
}
- @Override
- public void visit(DatabaseType expression) {
- resolver = buildClassResolver(Object.class);
- }
-
@Override
public void visit(ExtractExpression expression) {
resolver = buildClassResolver(Object.class);
@@ -108,9 +95,4 @@ public void visit(TableExpression expression) {
public void visit(TableVariableDeclaration expression) {
resolver = buildClassResolver(Object.class);
}
-
- @Override
- public void visit(UnionClause expression) {
- resolver = buildClassResolver(Object.class);
- }
}
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 3fe5ce75cc2..4532e3927b9 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
@@ -46,6 +46,7 @@
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.DatabaseType;
import org.eclipse.persistence.jpa.jpql.parser.DateTime;
import org.eclipse.persistence.jpa.jpql.parser.DeleteClause;
import org.eclipse.persistence.jpa.jpql.parser.DeleteStatement;
@@ -830,6 +831,11 @@ public void visit(CountFunction expression) {
this.stateObject = stateObject;
}
+ @Override
+ public void visit(DatabaseType expression) {
+ // TODO
+ }
+
@Override
public void visit(DateTime expression) {
DateTimeStateObject stateObject = new DateTimeStateObject(parent, expression.getText());
diff --git a/jpa/org.eclipse.persistence.jpa.jpql/src/main/java/org/eclipse/persistence/jpa/jpql/tools/model/EclipseLinkStateObjectBuilder.java b/jpa/org.eclipse.persistence.jpa.jpql/src/main/java/org/eclipse/persistence/jpa/jpql/tools/model/EclipseLinkStateObjectBuilder.java
index 56624269ea4..71e2e5eaa29 100644
--- a/jpa/org.eclipse.persistence.jpa.jpql/src/main/java/org/eclipse/persistence/jpa/jpql/tools/model/EclipseLinkStateObjectBuilder.java
+++ b/jpa/org.eclipse.persistence.jpa.jpql/src/main/java/org/eclipse/persistence/jpa/jpql/tools/model/EclipseLinkStateObjectBuilder.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
@@ -18,9 +18,7 @@
import org.eclipse.persistence.jpa.jpql.EclipseLinkLiteralVisitor;
import org.eclipse.persistence.jpa.jpql.LiteralVisitor;
import org.eclipse.persistence.jpa.jpql.parser.AsOfClause;
-import org.eclipse.persistence.jpa.jpql.parser.CastExpression;
import org.eclipse.persistence.jpa.jpql.parser.ConnectByClause;
-import org.eclipse.persistence.jpa.jpql.parser.DatabaseType;
import org.eclipse.persistence.jpa.jpql.parser.EclipseLinkExpressionVisitor;
import org.eclipse.persistence.jpa.jpql.parser.ExtractExpression;
import org.eclipse.persistence.jpa.jpql.parser.HierarchicalQueryClause;
@@ -29,7 +27,6 @@
import org.eclipse.persistence.jpa.jpql.parser.StartWithClause;
import org.eclipse.persistence.jpa.jpql.parser.TableExpression;
import org.eclipse.persistence.jpa.jpql.parser.TableVariableDeclaration;
-import org.eclipse.persistence.jpa.jpql.parser.UnionClause;
/**
* The default implementation of {@link BasicStateObjectBuilder}, which provides support based on
@@ -64,21 +61,11 @@ protected LiteralVisitor buildLiteralVisitor() {
public void visit(AsOfClause expression) {
}
- @Override
- public void visit(CastExpression expression) {
- // TODO
- }
-
@Override
public void visit(ConnectByClause expression) {
// TODO
}
- @Override
- public void visit(DatabaseType expression) {
- // TODO
- }
-
@Override
public void visit(ExtractExpression expression) {
// TODO
@@ -112,9 +99,4 @@ public void visit(TableExpression expression) {
public void visit(TableVariableDeclaration expression) {
// TODO
}
-
- @Override
- public void visit(UnionClause expression) {
- // TODO
- }
}
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 38e2e0a0027..43e5e2be25b 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
@@ -44,6 +44,7 @@
import org.eclipse.persistence.jpa.jpql.parser.BadExpression;
import org.eclipse.persistence.jpa.jpql.parser.BetweenExpression;
import org.eclipse.persistence.jpa.jpql.parser.CaseExpression;
+import org.eclipse.persistence.jpa.jpql.parser.CastExpression;
import org.eclipse.persistence.jpa.jpql.parser.CoalesceExpression;
import org.eclipse.persistence.jpa.jpql.parser.CollectionExpression;
import org.eclipse.persistence.jpa.jpql.parser.CollectionMemberDeclaration;
@@ -54,6 +55,7 @@
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.DatabaseType;
import org.eclipse.persistence.jpa.jpql.parser.DateTime;
import org.eclipse.persistence.jpa.jpql.parser.DeleteClause;
import org.eclipse.persistence.jpa.jpql.parser.DeleteStatement;
@@ -120,6 +122,7 @@
import org.eclipse.persistence.jpa.jpql.parser.TreatExpression;
import org.eclipse.persistence.jpa.jpql.parser.TrimExpression;
import org.eclipse.persistence.jpa.jpql.parser.TypeExpression;
+import org.eclipse.persistence.jpa.jpql.parser.UnionClause;
import org.eclipse.persistence.jpa.jpql.parser.UnknownExpression;
import org.eclipse.persistence.jpa.jpql.parser.UpdateClause;
import org.eclipse.persistence.jpa.jpql.parser.UpdateItem;
@@ -477,6 +480,11 @@ public void visit(CaseExpression expression) {
);
}
+ @Override
+ public void visit(CastExpression expression) {
+ resolver = buildClassResolver(Object.class);
+ }
+
@Override
public void visit(CoalesceExpression expression) {
visitCollectionEquivalentExpression(expression.getExpression(), null);
@@ -563,6 +571,11 @@ public void visit(CountFunction expression) {
resolver = buildClassResolver(Long.class);
}
+ @Override
+ public void visit(DatabaseType expression) {
+ resolver = buildClassResolver(Object.class);
+ }
+
@Override
public void visit(DateTime expression) {
@@ -1096,6 +1109,11 @@ public void visit(UpperExpression expression) {
resolver = buildClassResolver(String.class);
}
+ @Override
+ public void visit(UnionClause expression) {
+ resolver = buildClassResolver(Object.class);
+ }
+
@Override
public void visit(ValueExpression expression) {
diff --git a/jpa/org.eclipse.persistence.jpa.jpql/src/test/java/org/eclipse/persistence/jpa/tests/jpql/AllGrammarValidatorTests.java b/jpa/org.eclipse.persistence.jpa.jpql/src/test/java/org/eclipse/persistence/jpa/tests/jpql/AllGrammarValidatorTests.java
index 2701cf78bd9..b5cc9585f34 100644
--- a/jpa/org.eclipse.persistence.jpa.jpql/src/test/java/org/eclipse/persistence/jpa/tests/jpql/AllGrammarValidatorTests.java
+++ b/jpa/org.eclipse.persistence.jpa.jpql/src/test/java/org/eclipse/persistence/jpa/tests/jpql/AllGrammarValidatorTests.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
@@ -22,6 +22,7 @@
import org.eclipse.persistence.jpa.tests.jpql.parser.JPQLGrammarTools;
import org.eclipse.persistence.jpa.tests.jpql.tools.DefaultGrammarValidatorTest2_0;
import org.eclipse.persistence.jpa.tests.jpql.tools.DefaultGrammarValidatorTest2_1;
+import org.eclipse.persistence.jpa.tests.jpql.tools.DefaultGrammarValidatorTest3_2;
import org.junit.runner.RunWith;
import org.junit.runners.Suite.SuiteClasses;
@@ -36,6 +37,7 @@
@SuiteClasses({
AllGrammarValidatorTests.AllDefaultGrammarValidatorTest2_0.class,
AllGrammarValidatorTests.AllDefaultGrammarValidatorTest2_1.class,
+ AllGrammarValidatorTests.AllDefaultGrammarValidatorTest3_2.class,
AllGrammarValidatorTests.AllEclipseLinkGrammarValidatorTest.class,
AllGrammarValidatorTests.AllEclipseLinkGrammarValidatorTest2_4.class,
AllGrammarValidatorTests.AllEclipseLinkGrammarValidatorTest2_5.class,
@@ -87,6 +89,26 @@ static JPQLGrammar[] buildJPQLGrammars() {
}
}
+ /**
+ * This test suite tests JPQL queries written following the grammar defined in the JPA 3.2 spec
+ * and makes sure the various JPQL grammars that support it parses them correctly.
+ */
+ @SuiteClasses({
+ DefaultGrammarValidatorTest3_2.class,
+ })
+ @RunWith(JPQLTestRunner.class)
+ public static class AllDefaultGrammarValidatorTest3_2 {
+
+ private AllDefaultGrammarValidatorTest3_2() {
+ super();
+ }
+
+ @JPQLGrammarTestHelper
+ static JPQLGrammar[] buildJPQLGrammars() {
+ return JPQLGrammarTools.allDefaultJPQLGrammars(JPAVersion.VERSION_3_2);
+ }
+ }
+
/**
* This test suite tests JPQL queries written following the grammar defined in the JPA 2.0 spec
* with the extension provided by EclipseLink 2.0, 2.1, 2.2 and 2.3 and makes sure the various
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 7a6f630351c..e7859cbceed 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
@@ -95,4 +95,12 @@ public static String query_RightFunction_Where() {
return "SELECT c FROM Customer c WHERE RIGHT(c.firstName, 4) = 'John'";
}
+ public static String query_Union01() {
+ return "Select a from Address a where a.city = 'Ottawa' " +
+ "union Select a2 from Address a2 " +
+ "union all Select a2 from Address a2 " +
+ "intersect Select a from Address a where a.city = 'Ottawa' " +
+ "except Select a from Address a where a.city = 'Ottawa'";
+ }
+
}
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
index 429b9f62f58..7363293535b 100644
--- 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
@@ -26,7 +26,9 @@
* This test suite runs {@link JPQLParserTests3_2} using JPQL grammar written for JPA 3.2.
*/
@Suite.SuiteClasses({
- JPQLParserTests3_2.class
+ JPQLParserTests3_2.class,
+ CastExpressionTest.class,
+ UnionClauseTest.class
})
@RunWith(JPQLTestRunner.class)
public class AllJPQLParserTests3_2 {
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 f5f85749a64..e9606528ab0 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
@@ -18,7 +18,6 @@
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;
@@ -36,21 +35,27 @@
import static org.eclipse.persistence.jpa.tests.jpql.JPQLQueries3_2.query_RightFunction_Select02;
import static org.eclipse.persistence.jpa.tests.jpql.JPQLQueries3_2.query_RightFunction_Select03;
import static org.eclipse.persistence.jpa.tests.jpql.JPQLQueries3_2.query_RightFunction_Where;
+import static org.eclipse.persistence.jpa.tests.jpql.JPQLQueries3_2.query_Union01;
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;
import static org.eclipse.persistence.jpa.tests.jpql.parser.JPQLParserTester.from;
import static org.eclipse.persistence.jpa.tests.jpql.parser.JPQLParserTester.groupBy;
import static org.eclipse.persistence.jpa.tests.jpql.parser.JPQLParserTester.having;
+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.numeric;
import static org.eclipse.persistence.jpa.tests.jpql.parser.JPQLParserTester.path;
import static org.eclipse.persistence.jpa.tests.jpql.parser.JPQLParserTester.replace;
-import static org.eclipse.persistence.jpa.tests.jpql.parser.JPQLParserTester.resultVariable;
import static org.eclipse.persistence.jpa.tests.jpql.parser.JPQLParserTester.right;
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.subFrom;
+import static org.eclipse.persistence.jpa.tests.jpql.parser.JPQLParserTester.subSelect;
+import static org.eclipse.persistence.jpa.tests.jpql.parser.JPQLParserTester.union;
+import static org.eclipse.persistence.jpa.tests.jpql.parser.JPQLParserTester.unionAll;
import static org.eclipse.persistence.jpa.tests.jpql.parser.JPQLParserTester.variable;
import static org.eclipse.persistence.jpa.tests.jpql.parser.JPQLParserTester.where;
@@ -339,18 +344,39 @@ public void test_Query_RightFunction_Where() {
}
}
-// @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")
+ @Test
+ public void test_Query_Union01() {
+
+ // Select a from Address a where a.city = 'Ottawa'
+ // union Select a2 from Address a2
+ // union all Select a2 from Address a2
+ // intersect Select a from Address a where a.city = 'Ottawa'
+ // except Select a from Address a where a.city = 'Ottawa'
+
+ SelectStatementTester selectStatement = selectStatement(
+ select(variable("a")),
+ from("Address", "a"),
+ where(path("a.city").equal(string("'Ottawa'"))),
+ union(
+ subSelect(variable("a2")),
+ subFrom("Address", "a2")
+ ),
+ unionAll(
+ subSelect(variable("a2")),
+ subFrom("Address", "a2")
+ ),
+ intersect(
+ subSelect(variable("a")),
+ subFrom("Address", "a"),
+ where(path("a.city").equal(string("'Ottawa'")))
+ ),
+ except(
+ subSelect(variable("a")),
+ subFrom("Address", "a"),
+ where(path("a.city").equal(string("'Ottawa'")))
+ )
);
- testQuery(query_013(), selectStatement);
+ testQuery(query_Union01(), selectStatement);
}
-
}
diff --git a/jpa/org.eclipse.persistence.jpa.jpql/src/test/java/org/eclipse/persistence/jpa/tests/jpql/tools/DefaultGrammarValidatorTest3_2.java b/jpa/org.eclipse.persistence.jpa.jpql/src/test/java/org/eclipse/persistence/jpa/tests/jpql/tools/DefaultGrammarValidatorTest3_2.java
new file mode 100644
index 00000000000..f6c0ff31338
--- /dev/null
+++ b/jpa/org.eclipse.persistence.jpa.jpql/src/test/java/org/eclipse/persistence/jpa/tests/jpql/tools/DefaultGrammarValidatorTest3_2.java
@@ -0,0 +1,820 @@
+/*
+ * 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.tests.jpql.tools;
+
+import org.eclipse.persistence.jpa.jpql.AbstractGrammarValidator;
+import org.eclipse.persistence.jpa.jpql.JPAVersion;
+import org.eclipse.persistence.jpa.jpql.JPQLQueryProblem;
+import org.eclipse.persistence.jpa.jpql.tools.DefaultGrammarValidator;
+import org.eclipse.persistence.jpa.tests.jpql.AbstractGrammarValidatorTest;
+import org.eclipse.persistence.jpa.tests.jpql.parser.JPQLQueryStringFormatter;
+import org.junit.Test;
+
+import java.util.List;
+
+import static org.eclipse.persistence.jpa.jpql.JPQLQueryProblemMessages.CastExpression_InvalidExpression;
+import static org.eclipse.persistence.jpa.jpql.JPQLQueryProblemMessages.CastExpression_MissingDatabaseType;
+import static org.eclipse.persistence.jpa.jpql.JPQLQueryProblemMessages.CastExpression_MissingExpression;
+import static org.eclipse.persistence.jpa.jpql.JPQLQueryProblemMessages.CastExpression_MissingLeftParenthesis;
+import static org.eclipse.persistence.jpa.jpql.JPQLQueryProblemMessages.CastExpression_MissingRightParenthesis;
+import static org.eclipse.persistence.jpa.jpql.JPQLQueryProblemMessages.DatabaseType_InvalidFirstExpression;
+import static org.eclipse.persistence.jpa.jpql.JPQLQueryProblemMessages.DatabaseType_InvalidSecondExpression;
+import static org.eclipse.persistence.jpa.jpql.JPQLQueryProblemMessages.DatabaseType_MissingComma;
+import static org.eclipse.persistence.jpa.jpql.JPQLQueryProblemMessages.DatabaseType_MissingFirstExpression;
+import static org.eclipse.persistence.jpa.jpql.JPQLQueryProblemMessages.DatabaseType_MissingLeftParenthesis;
+import static org.eclipse.persistence.jpa.jpql.JPQLQueryProblemMessages.DatabaseType_MissingRightParenthesis;
+import static org.eclipse.persistence.jpa.jpql.JPQLQueryProblemMessages.DatabaseType_MissingSecondExpression;
+import static org.eclipse.persistence.jpa.jpql.JPQLQueryProblemMessages.UnionClause_MissingExpression;
+
+/**
+ * The unit-test class used for testing a JPQL query grammatically when the JPA version is 3.2.
+ *
+ * @since 4.1
+ * @author Radek Felcman
+ */
+@SuppressWarnings("nls")
+public class DefaultGrammarValidatorTest3_2 extends AbstractGrammarValidatorTest {
+
+ @Override
+ protected AbstractGrammarValidator buildValidator() {
+ return new DefaultGrammarValidator(jpqlGrammar);
+ }
+
+ @Override
+ protected boolean isJoinFetchIdentifiable() {
+ return false;
+ }
+
+ @Override
+ protected boolean isSubqueryAllowedAnywhere() {
+ return jpqlGrammar.getJPAVersion().isNewerThanOrEqual(JPAVersion.VERSION_3_2);
+ }
+
+ @Test
+ public void test_UnionClause_MissingExpression_01() throws Exception {
+
+ String jpqlQuery = "select e from Employee e intersect all select p from Product p where p.id <> 2";
+ List problems = validate(jpqlQuery);
+ testHasNoProblems(problems);
+ }
+
+ @Test
+ public void test_UnionClause_MissingExpression_02() throws Exception {
+
+ String jpqlQuery = "select e from Employee e intersect";
+ int startPosition = "select e from Employee e intersect".length();
+ int endPosition = jpqlQuery.length();
+
+ List problems = validate(jpqlQuery);
+
+ testHasOnlyOneProblem(
+ problems,
+ UnionClause_MissingExpression,
+ startPosition,
+ endPosition
+ );
+ }
+
+ @Test
+ public void test_UnionClause_MissingExpression_03() throws Exception {
+
+ String jpqlQuery = "select e from Employee e intersect ";
+ int startPosition = "select e from Employee e intersect ".length();
+ int endPosition = jpqlQuery.length();
+
+ List problems = validate(jpqlQuery);
+
+ testHasOnlyOneProblem(
+ problems,
+ UnionClause_MissingExpression,
+ startPosition,
+ endPosition
+ );
+ }
+
+ @Test
+ public void test_UnionClause_MissingExpression_04() throws Exception {
+
+ String jpqlQuery = "select e from Employee e intersect all";
+ int startPosition = "select e from Employee e intersect all".length();
+ int endPosition = jpqlQuery.length();
+
+ List problems = validate(jpqlQuery);
+
+ testHasOnlyOneProblem(
+ problems,
+ UnionClause_MissingExpression,
+ startPosition,
+ endPosition
+ );
+ }
+
+ @Test
+ public void test_UnionClause_MissingExpression_05() throws Exception {
+
+ String jpqlQuery = "select e from Employee e intersect all ";
+ int startPosition = "select e from Employee e intersect all ".length();
+ int endPosition = jpqlQuery.length();
+
+ List problems = validate(jpqlQuery);
+
+ testHasOnlyOneProblem(
+ problems,
+ UnionClause_MissingExpression,
+ startPosition,
+ endPosition
+ );
+ }
+
+ @Test
+ public void test_CastExpression_InvalidExpression_1() throws Exception {
+
+ String jpqlQuery = "Select cast(e.firstName as char) from Employee e";
+ List problems = validate(jpqlQuery);
+ testDoesNotHaveProblem(problems, CastExpression_InvalidExpression);
+ }
+
+ @Test
+ public void test_CastExpression_MissingDatabaseType_1() throws Exception {
+
+ String jpqlQuery = "Select cast(e.firstName char) from Employee e";
+ List problems = validate(jpqlQuery);
+ testDoesNotHaveProblem(problems, CastExpression_MissingDatabaseType);
+ }
+
+ @Test
+ public void test_CastExpression_MissingDatabaseType_2() throws Exception {
+
+ String jpqlQuery = "Select cast(e.firstName as char) from Employee e";
+ List problems = validate(jpqlQuery);
+ testDoesNotHaveProblem(problems, CastExpression_MissingDatabaseType);
+ }
+
+ @Test
+ public void test_CastExpression_MissingDatabaseType_3() throws Exception {
+
+ String jpqlQuery = "Select cast(e.firstName) from Employee e";
+ int startPosition = "Select cast(e.firstName".length();
+ int endPosition = startPosition;
+
+ List problems = validate(jpqlQuery);
+
+ testHasOnlyOneProblem(
+ problems,
+ CastExpression_MissingDatabaseType,
+ startPosition,
+ endPosition
+ );
+ }
+
+ @Test
+ public void test_CastExpression_MissingDatabaseType_4() throws Exception {
+
+ String jpqlQuery = "Select cast(e.firstName ) from Employee e";
+ int startPosition = "Select cast(e.firstName ".length();
+ int endPosition = startPosition;
+
+ List problems = validate(jpqlQuery, buildStringFormatter_2());
+
+ testHasOnlyOneProblem(
+ problems,
+ CastExpression_MissingDatabaseType,
+ startPosition,
+ endPosition
+ );
+ }
+
+ @Test
+ public void test_CastExpression_MissingDatabaseType_5() throws Exception {
+
+ String jpqlQuery = "Select cast(e.firstName as) from Employee e";
+ int startPosition = "Select cast(e.firstName as".length();
+ int endPosition = startPosition;
+
+ List problems = validate(jpqlQuery);
+
+ testHasOnlyOneProblem(
+ problems,
+ CastExpression_MissingDatabaseType,
+ startPosition,
+ endPosition
+ );
+ }
+
+ @Test
+ public void test_CastExpression_MissingDatabaseType_6() throws Exception {
+
+ String jpqlQuery = "Select cast(e.firstName as ) from Employee e";
+ int startPosition = "Select cast(e.firstName as ".length();
+ int endPosition = startPosition;
+
+ List problems = validate(jpqlQuery, buildStringFormatter_3());
+
+ testHasOnlyOneProblem(
+ problems,
+ CastExpression_MissingDatabaseType,
+ startPosition,
+ endPosition
+ );
+ }
+
+ @Test
+ public void test_CastExpression_MissingDatabaseType_7() throws Exception {
+
+ String jpqlQuery = "Select cast(e.firstName from Employee e";
+ int startPosition = "Select cast(e.firstName ".length();
+ int endPosition = startPosition;
+
+ List problems = validate(jpqlQuery);
+
+ testHasProblem(
+ problems,
+ CastExpression_MissingDatabaseType,
+ startPosition,
+ endPosition
+ );
+ }
+
+ @Test
+ public void test_CastExpression_MissingDatabaseType_8() throws Exception {
+
+ String jpqlQuery = "Select cast(e.firstName as from Employee e";
+ int startPosition = "Select cast(e.firstName as ".length();
+ int endPosition = startPosition;
+
+ List problems = validate(jpqlQuery);
+
+ testHasProblem(
+ problems,
+ CastExpression_MissingDatabaseType,
+ startPosition,
+ endPosition
+ );
+ }
+
+ @Test
+ public void test_CastExpression_MissingExpression_1() throws Exception {
+
+ String jpqlQuery = "Select cast(e.firstName as char) from Employee e";
+ List problems = validate(jpqlQuery);
+ testDoesNotHaveProblem(problems, CastExpression_MissingExpression);
+ }
+
+ @Test
+ public void test_CastExpression_MissingExpression_2() throws Exception {
+
+ String jpqlQuery = "Select cast(as char) from Employee e";
+ int startPosition = "Select cast(".length();
+ int endPosition = startPosition;
+
+ List problems = validate(jpqlQuery);
+
+ testHasOnlyOneProblem(
+ problems,
+ CastExpression_MissingExpression,
+ startPosition,
+ endPosition
+ );
+ }
+
+ @Test
+ public void test_CastExpression_MissingLeftParenthesis_1() throws Exception {
+
+ String jpqlQuery = "Select cast(e.firstName as char) from Employee e";
+ List problems = validate(jpqlQuery);
+ testDoesNotHaveProblem(problems, CastExpression_MissingLeftParenthesis);
+ }
+
+ @Test
+ public void test_CastExpression_MissingLeftParenthesis_2() throws Exception {
+
+ String jpqlQuery = "Select cast from Employee e";
+ int startPosition = "Select cast".length();
+ int endPosition = startPosition;
+
+ List problems = validate(jpqlQuery);
+
+ testHasOnlyOneProblem(
+ problems,
+ CastExpression_MissingLeftParenthesis,
+ startPosition,
+ endPosition
+ );
+ }
+
+ @Test
+ public void test_CastExpression_MissingLeftParenthesis_3() throws Exception {
+
+ String jpqlQuery = "Select cast e.firstName as char) from Employee e";
+ int startPosition = "Select cast".length();
+ int endPosition = startPosition;
+
+ List problems = validate(jpqlQuery);
+
+ testHasOnlyOneProblem(
+ problems,
+ CastExpression_MissingLeftParenthesis,
+ startPosition,
+ endPosition
+ );
+ }
+
+ @Test
+ public void test_CastExpression_MissingLeftParenthesis_4() throws Exception {
+
+ String jpqlQuery = "Select cast as from Employee e";
+ int startPosition = "Select cast".length();
+ int endPosition = startPosition;
+
+ List problems = validate(jpqlQuery);
+
+ testHasProblem(
+ problems,
+ CastExpression_MissingLeftParenthesis,
+ startPosition,
+ endPosition
+ );
+ }
+
+ @Test
+ public void test_CastExpression_MissingRightParenthesis_1() throws Exception {
+
+ String jpqlQuery = "Select cast(e.firstName char) from Employee e";
+ List problems = validate(jpqlQuery);
+ testDoesNotHaveProblem(problems, CastExpression_MissingRightParenthesis);
+ }
+
+ @Test
+ public void test_CastExpression_MissingRightParenthesis_2() throws Exception {
+
+ String jpqlQuery = "Select cast(e.firstName as char) from Employee e";
+ List problems = validate(jpqlQuery);
+ testDoesNotHaveProblem(problems, CastExpression_MissingRightParenthesis);
+ }
+
+ @Test
+ public void test_CastExpression_MissingRightParenthesis_3() throws Exception {
+
+ String jpqlQuery = "Select cast(e.firstName as char(2) from Employee e";
+ int startPosition = "Select cast(e.firstName as char(2)".length();
+ int endPosition = startPosition;
+
+ List problems = validate(jpqlQuery);
+
+ testHasOnlyOneProblem(
+ problems,
+ CastExpression_MissingRightParenthesis,
+ startPosition,
+ endPosition
+ );
+ }
+
+ @Test
+ public void test_CastExpression_MissingRightParenthesis_4() throws Exception {
+
+ String jpqlQuery = "Select cast(e.firstName as char from Employee e";
+ int startPosition = "Select cast(e.firstName as char".length();
+ int endPosition = startPosition;
+
+ List problems = validate(jpqlQuery);
+
+ testHasOnlyOneProblem(
+ problems,
+ CastExpression_MissingRightParenthesis,
+ startPosition,
+ endPosition
+ );
+ }
+
+ @Test
+ public void test_DatabaseType_InvalidFirstExpression_1() throws Exception {
+
+ String jpqlQuery = "Select cast(e.firstName char) from Employee e";
+ List problems = validate(jpqlQuery);
+ testDoesNotHaveProblem(problems, DatabaseType_InvalidFirstExpression);
+ }
+
+ @Test
+ public void test_DatabaseType_InvalidFirstExpression_2() throws Exception {
+
+ String jpqlQuery = "Select cast(e.firstName char(2)) from Employee e";
+ List problems = validate(jpqlQuery);
+ testDoesNotHaveProblem(problems, DatabaseType_InvalidFirstExpression);
+ }
+
+ @Test
+ public void test_DatabaseType_InvalidFirstExpression_3() throws Exception {
+
+ String jpqlQuery = "Select cast(e.firstName char(2, 2)) from Employee e";
+ List problems = validate(jpqlQuery);
+ testDoesNotHaveProblem(problems, DatabaseType_InvalidFirstExpression);
+ }
+
+ @Test
+ public void test_DatabaseType_InvalidFirstExpression_4() throws Exception {
+
+ String jpqlQuery = "Select cast(e.firstName char(avg(e.age), 2)) from Employee e";
+ int startPosition = "Select cast(e.firstName char(".length();
+ int endPosition = "Select cast(e.firstName char(avg(e.age)".length();
+
+ List problems = validate(jpqlQuery);
+
+ testHasOnlyOneProblem(
+ problems,
+ DatabaseType_InvalidFirstExpression,
+ startPosition,
+ endPosition
+ );
+ }
+
+ @Test
+ public void test_DatabaseType_InvalidSecondExpression_1() throws Exception {
+
+ String jpqlQuery = "Select cast(e.firstName char) from Employee e";
+ List problems = validate(jpqlQuery);
+ testDoesNotHaveProblem(problems, DatabaseType_InvalidSecondExpression);
+ }
+
+ @Test
+ public void test_DatabaseType_InvalidSecondExpression_2() throws Exception {
+
+ String jpqlQuery = "Select cast(e.firstName char(2)) from Employee e";
+ List problems = validate(jpqlQuery);
+ testDoesNotHaveProblem(problems, DatabaseType_InvalidSecondExpression);
+ }
+
+ @Test
+ public void test_DatabaseType_InvalidSecondExpression_3() throws Exception {
+
+ String jpqlQuery = "Select cast(e.firstName char(2, 2)) from Employee e";
+ List problems = validate(jpqlQuery);
+ testDoesNotHaveProblem(problems, DatabaseType_InvalidSecondExpression);
+ }
+
+ @Test
+ public void test_DatabaseType_InvalidSecondExpression_4() throws Exception {
+
+ String jpqlQuery = "Select cast(e.firstName char(2, avg(e.age))) from Employee e";
+ int startPosition = "Select cast(e.firstName char(2, ".length();
+ int endPosition = "Select cast(e.firstName char(2, avg(e.age)".length();
+
+ List problems = validate(jpqlQuery);
+
+ testHasOnlyOneProblem(
+ problems,
+ DatabaseType_InvalidSecondExpression,
+ startPosition,
+ endPosition
+ );
+ }
+
+ @Test
+ public void test_DatabaseType_MissingComma_1() throws Exception {
+
+ String jpqlQuery = "Select cast(e.firstName char(2, 2)) from Employee e";
+ List problems = validate(jpqlQuery);
+ testDoesNotHaveProblem(problems, DatabaseType_MissingComma);
+ }
+
+ @Test
+ public void test_DatabaseType_MissingComma_2() throws Exception {
+
+ String jpqlQuery = "Select cast(e.firstName char(2)) from Employee e";
+ List problems = validate(jpqlQuery);
+ testDoesNotHaveProblem(problems, DatabaseType_MissingComma);
+ }
+
+ @Test
+ public void test_DatabaseType_MissingComma_3() throws Exception {
+
+ String jpqlQuery = "Select cast(e.firstName char(2 2)) from Employee e";
+ int startPosition = "Select cast(e.firstName char(2".length();
+ int endPosition = startPosition;
+
+ List problems = validate(jpqlQuery);
+
+ testHasOnlyOneProblem(
+ problems,
+ DatabaseType_MissingComma,
+ startPosition,
+ endPosition
+ );
+ }
+
+ @Test
+ public void test_DatabaseType_MissingFirstExpression_1() throws Exception {
+
+ String jpqlQuery = "Select cast(e.firstName char) from Employee e";
+ List problems = validate(jpqlQuery);
+ testDoesNotHaveProblem(problems, DatabaseType_MissingFirstExpression);
+ }
+
+ @Test
+ public void test_DatabaseType_MissingFirstExpression_2() throws Exception {
+
+ String jpqlQuery = "Select cast(e.firstName char(2)) from Employee e";
+ List problems = validate(jpqlQuery);
+ testDoesNotHaveProblem(problems, DatabaseType_MissingFirstExpression);
+ }
+
+ @Test
+ public void test_DatabaseType_MissingFirstExpression_3() throws Exception {
+
+ String jpqlQuery = "Select cast(e.firstName char(2,)) from Employee e";
+ List problems = validate(jpqlQuery);
+ testDoesNotHaveProblem(problems, DatabaseType_MissingFirstExpression);
+ }
+
+ @Test
+ public void test_DatabaseType_MissingFirstExpression_4() throws Exception {
+
+ String jpqlQuery = "Select cast(e.firstName char(, 2)) from Employee e";
+ int startPosition = "Select cast(e.firstName char(".length();
+ int endPosition = startPosition;
+
+ List problems = validate(jpqlQuery);
+
+ testHasOnlyOneProblem(
+ problems,
+ DatabaseType_MissingFirstExpression,
+ startPosition,
+ endPosition
+ );
+ }
+
+ @Test
+ public void test_DatabaseType_MissingFirstExpression_5() throws Exception {
+
+ String jpqlQuery = "Select cast(e.firstName char(,)) from Employee e";
+ int startPosition = "Select cast(e.firstName char(".length();
+ int endPosition = startPosition;
+
+ List problems = validate(jpqlQuery);
+
+ testHasProblem(
+ problems,
+ DatabaseType_MissingFirstExpression,
+ startPosition,
+ endPosition
+ );
+ }
+
+ @Test
+ public void test_DatabaseType_MissingLeftParenthesis_1() throws Exception {
+
+ String jpqlQuery = "Select cast(e.firstName char) from Employee e";
+ List problems = validate(jpqlQuery);
+ testDoesNotHaveProblem(problems, DatabaseType_MissingLeftParenthesis);
+ }
+
+ @Test
+ public void test_DatabaseType_MissingLeftParenthesis_2() throws Exception {
+
+ String jpqlQuery = "Select cast(e.firstName char()) from Employee e";
+ List problems = validate(jpqlQuery);
+ testDoesNotHaveProblem(problems, DatabaseType_MissingLeftParenthesis);
+ }
+
+ @Test
+ public void test_DatabaseType_MissingLeftParenthesis_3() throws Exception {
+
+ String jpqlQuery = "Select cast(e.firstName char(3)) from Employee e";
+ List problems = validate(jpqlQuery);
+ testDoesNotHaveProblem(problems, DatabaseType_MissingLeftParenthesis);
+ }
+
+ @Test
+ public void test_DatabaseType_MissingLeftParenthesis_4() throws Exception {
+
+ String jpqlQuery = "Select cast(e.firstName char(3,)) from Employee e";
+ List problems = validate(jpqlQuery);
+ testDoesNotHaveProblem(problems, DatabaseType_MissingLeftParenthesis);
+ }
+
+ @Test
+ public void test_DatabaseType_MissingLeftParenthesis_5() throws Exception {
+
+ String jpqlQuery = "Select cast(e.firstName char(3, )) from Employee e";
+ List problems = validate(jpqlQuery, buildStringFormatter_4());
+ testDoesNotHaveProblem(problems, DatabaseType_MissingLeftParenthesis);
+ }
+
+ @Test
+ public void test_DatabaseType_MissingLeftParenthesis_6() throws Exception {
+
+ String jpqlQuery = "Select cast(e.firstName char(3, 3)) from Employee e";
+ List problems = validate(jpqlQuery);
+ testDoesNotHaveProblem(problems, DatabaseType_MissingLeftParenthesis);
+ }
+
+ @Test
+ public void test_DatabaseType_MissingLeftParenthesis_7() throws Exception {
+
+ String jpqlQuery = "Select cast(e.firstName char 3)) from Employee e";
+ int startPosition = "Select cast(e.firstName char".length();
+ int endPosition = startPosition;
+
+ List problems = validate(jpqlQuery);
+
+ testHasOnlyOneProblem(
+ problems,
+ DatabaseType_MissingLeftParenthesis,
+ startPosition,
+ endPosition
+ );
+ }
+
+ @Test
+ public void test_DatabaseType_MissingLeftParenthesis_8() throws Exception {
+
+ String jpqlQuery = "Select cast(e.firstName char 3, 3)) from Employee e";
+ int startPosition = "Select cast(e.firstName char".length();
+ int endPosition = startPosition;
+
+ List problems = validate(jpqlQuery);
+
+ testHasOnlyOneProblem(
+ problems,
+ DatabaseType_MissingLeftParenthesis,
+ startPosition,
+ endPosition
+ );
+ }
+
+ @Test
+ public void test_DatabaseType_MissingRightParenthesis_1() throws Exception {
+
+ String jpqlQuery = "Select cast(e.firstName char) from Employee e";
+ List problems = validate(jpqlQuery);
+ testDoesNotHaveProblem(problems, DatabaseType_MissingRightParenthesis);
+ }
+
+ @Test
+ public void test_DatabaseType_MissingRightParenthesis_2() throws Exception {
+
+ String jpqlQuery = "Select cast(e.firstName char()) from Employee e";
+ List problems = validate(jpqlQuery);
+ testDoesNotHaveProblem(problems, DatabaseType_MissingRightParenthesis);
+ }
+
+ @Test
+ public void test_DatabaseType_MissingRightParenthesis_3() throws Exception {
+
+ String jpqlQuery = "Select cast(e.firstName char(2 from Employee e";
+ int startPosition = "Select cast(e.firstName char(2".length();
+ int endPosition = startPosition;
+
+ List problems = validate(jpqlQuery);
+
+ testHasProblem(
+ problems,
+ DatabaseType_MissingRightParenthesis,
+ startPosition,
+ endPosition
+ );
+ }
+
+ @Test
+ public void test_DatabaseType_MissingRightParenthesis_4() throws Exception {
+
+ String jpqlQuery = "Select cast(e.firstName char(2, from Employee e";
+ int startPosition = "Select cast(e.firstName char(2, ".length();
+ int endPosition = startPosition;
+
+ List problems = validate(jpqlQuery);
+
+ testHasProblem(
+ problems,
+ DatabaseType_MissingRightParenthesis,
+ startPosition,
+ endPosition
+ );
+ }
+
+ @Test
+ public void test_DatabaseType_MissingRightParenthesis_5() throws Exception {
+
+ String jpqlQuery = "Select cast(e.firstName char(2, 2 from Employee e";
+ int startPosition = "Select cast(e.firstName char(2, 2".length();
+ int endPosition = startPosition;
+
+ List problems = validate(jpqlQuery);
+
+ testHasProblem(
+ problems,
+ DatabaseType_MissingRightParenthesis,
+ startPosition,
+ endPosition
+ );
+ }
+
+ @Test
+ public void test_DatabaseType_MissingSecondExpression_1() throws Exception {
+
+ String jpqlQuery = "Select cast(e.firstName char) from Employee e";
+ List problems = validate(jpqlQuery);
+ testDoesNotHaveProblem(problems, DatabaseType_MissingFirstExpression);
+ }
+
+ @Test
+ public void test_DatabaseType_MissingSecondExpression_2() throws Exception {
+
+ String jpqlQuery = "Select cast(e.firstName char(2, 2)) from Employee e";
+ List problems = validate(jpqlQuery);
+ testDoesNotHaveProblem(problems, DatabaseType_MissingFirstExpression);
+ }
+
+ @Test
+ public void test_DatabaseType_MissingSecondExpression_3() throws Exception {
+
+ String jpqlQuery = "Select cast(e.firstName char(, 2)) from Employee e";
+ int startPosition = "Select cast(e.firstName char(".length();
+ int endPosition = startPosition;
+
+ List problems = validate(jpqlQuery);
+
+ testHasOnlyOneProblem(
+ problems,
+ DatabaseType_MissingFirstExpression,
+ startPosition,
+ endPosition
+ );
+ }
+
+ @Test
+ public void test_DatabaseType_MissingSecondExpression_4() throws Exception {
+
+ String jpqlQuery = "Select cast(e.firstName char(2,)) from Employee e";
+ int startPosition = "Select cast(e.firstName char(2,".length();
+ int endPosition = startPosition;
+
+ List problems = validate(jpqlQuery);
+
+ testHasOnlyOneProblem(
+ problems,
+ DatabaseType_MissingSecondExpression,
+ startPosition,
+ endPosition
+ );
+ }
+
+ @Test
+ public void test_DatabaseType_MissingSecondExpression_5() throws Exception {
+
+ String jpqlQuery = "Select cast(e.firstName char(2, )) from Employee e";
+ int startPosition = "Select cast(e.firstName char(2, ".length();
+ int endPosition = startPosition;
+
+ List problems = validate(jpqlQuery, buildStringFormatter_4());
+
+ testHasOnlyOneProblem(
+ problems,
+ DatabaseType_MissingSecondExpression,
+ startPosition,
+ endPosition
+ );
+ }
+
+ @Test
+ public void test_DatabaseType_MissingSecondExpression_6() throws Exception {
+
+ String jpqlQuery = "Select cast(e.firstName char(,)) from Employee e";
+ int startPosition = "Select cast(e.firstName char(,".length();
+ int endPosition = startPosition;
+
+ List problems = validate(jpqlQuery);
+
+ testHasProblem(
+ problems,
+ DatabaseType_MissingSecondExpression,
+ startPosition,
+ endPosition
+ );
+ }
+
+ private JPQLQueryStringFormatter buildStringFormatter_2() {
+ return query -> query.replace("firstName)", "firstName )");
+ }
+
+ private JPQLQueryStringFormatter buildStringFormatter_3() {
+ return query -> query.replace(")", " )");
+ }
+
+ private JPQLQueryStringFormatter buildStringFormatter_4() {
+ return query -> query.replace(",", ", ");
+ }
+
+}