diff --git a/jpa/eclipselink.jpa.testapps/jpa.test.jpql/src/test/java/org/eclipse/persistence/testing/tests/jpa/jpql/advanced/JUnitJPQLJakartaDataNoAliasTest.java b/jpa/eclipselink.jpa.testapps/jpa.test.jpql/src/test/java/org/eclipse/persistence/testing/tests/jpa/jpql/advanced/JUnitJPQLJakartaDataNoAliasTest.java index d731d8deb3b..5a0bf3d1083 100644 --- a/jpa/eclipselink.jpa.testapps/jpa.test.jpql/src/test/java/org/eclipse/persistence/testing/tests/jpa/jpql/advanced/JUnitJPQLJakartaDataNoAliasTest.java +++ b/jpa/eclipselink.jpa.testapps/jpa.test.jpql/src/test/java/org/eclipse/persistence/testing/tests/jpa/jpql/advanced/JUnitJPQLJakartaDataNoAliasTest.java @@ -107,11 +107,15 @@ public static Test suite() { suite.addTest(new JUnitJPQLJakartaDataNoAliasTest("testGeneratedSelect")); suite.addTest(new JUnitJPQLJakartaDataNoAliasTest("testUpdateQueryLengthInAssignmentAndExpression")); suite.addTest(new JUnitJPQLJakartaDataNoAliasTest("testSelectQueryLengthInAssignmentAndExpression")); + suite.addTest(new JUnitJPQLJakartaDataNoAliasTest("testSelectQueryImplicitThisVariableInPath")); + suite.addTest(new JUnitJPQLJakartaDataNoAliasTest("testSelectQueryImplicitThisVariableInAggregateFunctionPath")); + suite.addTest(new JUnitJPQLJakartaDataNoAliasTest("testSelectQueryImplicitThisVariableInArithmeticExpression")); suite.addTest(new JUnitJPQLJakartaDataNoAliasTest("testUpdateImplicitVariableInArithmeticExpression")); suite.addTest(new JUnitJPQLJakartaDataNoAliasTest("testDeleteQueryLengthInExpressionOnLeft")); suite.addTest(new JUnitJPQLJakartaDataNoAliasTest("testDeleteQueryLengthInExpressionOnRight")); suite.addTest(new JUnitJPQLJakartaDataNoAliasTest("tesUpdateQueryWithThisVariable")); suite.addTest(new JUnitJPQLJakartaDataNoAliasTest("testThisVariableInPathExpressionUpdate")); + suite.addTest(new JUnitJPQLJakartaDataNoAliasTest("testThisVariableInPathAndIdFunctionExpressionUpdate")); suite.addTest(new JUnitJPQLJakartaDataNoAliasTest("testThisVariableInPathExpressionDelete")); suite.addTest(new JUnitJPQLJakartaDataNoAliasTest("testThisVariableInLikeExpressionDelete")); return suite; @@ -331,6 +335,38 @@ public void testSelectQueryLengthInAssignmentAndExpression() { assertTrue("Number of rooms with ID = 1", roomsWithIdOne.size() == 1); } + + // Covers https://github.com/eclipse-ee4j/eclipselink/issues/2182 + public void testSelectQueryImplicitThisVariableInPath() { + resetRooms(); + List roomsLengthWithIdOne = getEntityManagerFactory().callInTransaction(em -> em.createQuery( + "SELECT length FROM Room WHERE length IS NOT NULL AND id = :idParam", Integer.class) + .setParameter("idParam", ROOMS[1].getId()) + .getResultList()); + assertTrue("Number of rooms with ID = 1", roomsLengthWithIdOne.size() == 1); + assertTrue("Room ID = " + ROOMS[1].getId() + " has length of ", roomsLengthWithIdOne.get(0) == ROOMS[1].getLength()); + } + + + // Covers https://github.com/eclipse-ee4j/eclipselink/issues/2192 + public void testSelectQueryImplicitThisVariableInAggregateFunctionPath() { + resetRooms(); + Integer roomsMaxWidth = getEntityManagerFactory().callInTransaction(em -> em.createQuery( + "SELECT MAX(width) FROM Room", Integer.class) + .getSingleResult()); + assertTrue("Some Room with max width exist ", roomsMaxWidth != null); + } + + // Covers https://github.com/eclipse-ee4j/eclipselink/issues/2247 + public void testSelectQueryImplicitThisVariableInArithmeticExpression() { + resetRooms(); + int roomCapacity = getEntityManagerFactory().callInTransaction(em -> em.createQuery( + "SELECT length * width * height FROM Room WHERE id = :idParam", Integer.class) + .setParameter("idParam", ROOMS[1].getId()) + .getSingleResult()); + assertEquals(ROOMS[1].getLength() * ROOMS[1].getWidth() * ROOMS[1].getHeight(), roomCapacity); + } + public void testUpdateImplicitVariableInArithmeticExpression() { resetRooms(); int numberOfChanges = getEntityManagerFactory().callInTransaction(em -> em.createQuery( @@ -384,6 +420,18 @@ public void testThisVariableInPathExpressionUpdate() { assertTrue("Length of room with ID = 1 is " + length, length == 10); } + // Covers https://github.com/eclipse-ee4j/eclipselink/issues/2184 + public void testThisVariableInPathAndIdFunctionExpressionUpdate() { + resetRooms(); + int numberOfChanges = getEntityManagerFactory().callInTransaction(em -> em.createQuery( + "UPDATE Room SET length = 10 WHERE ID(this) = :idParam") + .setParameter("idParam", 1) + .executeUpdate()); + assertTrue("Number of rooms with ID = 1 modified is " + numberOfChanges, numberOfChanges == 1); + int length = findRoomById(1).getLength(); + assertTrue("Length of room with ID = 1 is " + length, length == 10); + } + // Covers https://github.com/eclipse-ee4j/eclipselink/issues/2198 public void testThisVariableInPathExpressionDelete() { resetRooms(); diff --git a/jpa/org.eclipse.persistence.jpa.jpql/src/main/java/org/eclipse/persistence/jpa/jpql/AbstractValidator.java b/jpa/org.eclipse.persistence.jpa.jpql/src/main/java/org/eclipse/persistence/jpa/jpql/AbstractValidator.java index 266a8aa098f..57d208539d7 100644 --- a/jpa/org.eclipse.persistence.jpa.jpql/src/main/java/org/eclipse/persistence/jpa/jpql/AbstractValidator.java +++ b/jpa/org.eclipse.persistence.jpa.jpql/src/main/java/org/eclipse/persistence/jpa/jpql/AbstractValidator.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2006, 2023 Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2006, 2024 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 @@ -36,6 +36,7 @@ import org.eclipse.persistence.jpa.jpql.parser.FromClause; import org.eclipse.persistence.jpa.jpql.parser.GroupByClause; import org.eclipse.persistence.jpa.jpql.parser.HavingClause; +import org.eclipse.persistence.jpa.jpql.parser.IdentificationVariable; import org.eclipse.persistence.jpa.jpql.parser.JPQLGrammar; import org.eclipse.persistence.jpa.jpql.parser.JPQLQueryBNF; import org.eclipse.persistence.jpa.jpql.parser.NullExpression; @@ -45,6 +46,7 @@ import org.eclipse.persistence.jpa.jpql.parser.SimpleFromClause; import org.eclipse.persistence.jpa.jpql.parser.SimpleSelectClause; import org.eclipse.persistence.jpa.jpql.parser.SimpleSelectStatement; +import org.eclipse.persistence.jpa.jpql.parser.StateFieldPathExpression; import org.eclipse.persistence.jpa.jpql.parser.SubExpression; import org.eclipse.persistence.jpa.jpql.parser.UnionClause; import org.eclipse.persistence.jpa.jpql.parser.UnknownExpression; @@ -967,6 +969,19 @@ public void visit(NullExpression expression) { valid = true; } + @Override + public void visit(StateFieldPathExpression expression) { + JPQLQueryBNF originQueryBNF = queryBNF; + if (Expression.THIS.equalsIgnoreCase(expression.toString()) && + expression.getParentExpression().isGenerateImplicitThisAlias() && + expression.getIdentificationVariable() != null && + ((IdentificationVariable)(expression.getIdentificationVariable())).isVirtual()) { + queryBNF = expression.getQueryBNF(); + } + visit((Expression) expression); + queryBNF = originQueryBNF; + } + @Override public void visit(SubExpression expression) { if (expression.hasExpression()) { diff --git a/jpa/org.eclipse.persistence.jpa.jpql/src/main/java/org/eclipse/persistence/jpa/jpql/parser/AbstractExpression.java b/jpa/org.eclipse.persistence.jpa.jpql/src/main/java/org/eclipse/persistence/jpa/jpql/parser/AbstractExpression.java index 59824728ed1..1cc53e8694e 100644 --- a/jpa/org.eclipse.persistence.jpa.jpql/src/main/java/org/eclipse/persistence/jpa/jpql/parser/AbstractExpression.java +++ b/jpa/org.eclipse.persistence.jpa.jpql/src/main/java/org/eclipse/persistence/jpa/jpql/parser/AbstractExpression.java @@ -525,7 +525,7 @@ public final JPQLExpression getRoot() { * @return Parent expression */ public final ParentExpression getParentExpression() { - if (!(this.isSubExpression()) && (this.isParentExpression())) { + if (parent == null || (!(this.isSubExpression()) && (this.isParentExpression()))) { return (ParentExpression)this; } else { return parent.getParentExpression(); @@ -602,6 +602,12 @@ protected boolean isNull() { return false; } + + /** + * Flag if expression is a parent/root in the tree. + * + * @return {@code boolean} {@code true} - yes it's parent/root , {@code false} - if not + */ public boolean isParentExpression() { return false; } diff --git a/jpa/org.eclipse.persistence.jpa.jpql/src/main/java/org/eclipse/persistence/jpa/jpql/parser/AbstractFromClause.java b/jpa/org.eclipse.persistence.jpa.jpql/src/main/java/org/eclipse/persistence/jpa/jpql/parser/AbstractFromClause.java index de7cc021dae..fe96779068c 100644 --- a/jpa/org.eclipse.persistence.jpa.jpql/src/main/java/org/eclipse/persistence/jpa/jpql/parser/AbstractFromClause.java +++ b/jpa/org.eclipse.persistence.jpa.jpql/src/main/java/org/eclipse/persistence/jpa/jpql/parser/AbstractFromClause.java @@ -344,7 +344,7 @@ else if (hierarchicalQueryClause == null) { identificationVariableDeclaration.hasRangeVariableDeclaration() && identificationVariableDeclaration.getRangeVariableDeclaration() instanceof RangeVariableDeclaration rangeVariableDeclaration && rangeVariableDeclaration.hasIdentificationVariable() && rangeVariableDeclaration.getIdentificationVariable() instanceof IdentificationVariable identificationVariable && Expression.THIS.equals(identificationVariable.getText())) { - this.getParentExpression().setGenerateThisPrefix(true); + this.getParentExpression().setGenerateImplicitThisAlias(true); } } diff --git a/jpa/org.eclipse.persistence.jpa.jpql/src/main/java/org/eclipse/persistence/jpa/jpql/parser/FullyQualifyPathExpressionVisitor.java b/jpa/org.eclipse.persistence.jpa.jpql/src/main/java/org/eclipse/persistence/jpa/jpql/parser/FullyQualifyPathExpressionVisitor.java index 8204ed0b54a..737f728f111 100644 --- a/jpa/org.eclipse.persistence.jpa.jpql/src/main/java/org/eclipse/persistence/jpa/jpql/parser/FullyQualifyPathExpressionVisitor.java +++ b/jpa/org.eclipse.persistence.jpa.jpql/src/main/java/org/eclipse/persistence/jpa/jpql/parser/FullyQualifyPathExpressionVisitor.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2006, 2022 Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2006, 2024 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 @@ -17,8 +17,6 @@ // - 527415: Fix code when locale is tr, az or lt package org.eclipse.persistence.jpa.jpql.parser; -import java.util.Locale; - /** * This visitor makes sure that all path expressions are fully qualified with a "virtual" * identification variable if the range variable declaration does not define one. This only applies @@ -56,8 +54,8 @@ private GeneralIdentificationVariableVisitor generalIdentificationVariableVisito @Override public void visit(AbstractSchemaName expression) { - // The "virtual" variable name will be the entity name - variableName = expression.toActualText().toLowerCase(Locale.ROOT); + // The "virtual" variable name will be "this" entity name + variableName = Expression.THIS; } @Override @@ -68,7 +66,7 @@ public void visit(CollectionMemberDeclaration expression) { @Override public void visit(CollectionValuedPathExpression expression) { visitAbstractPathExpression(expression); - variableName = expression.toActualText().toLowerCase(Locale.ROOT); + variableName = Expression.THIS; } @Override diff --git a/jpa/org.eclipse.persistence.jpa.jpql/src/main/java/org/eclipse/persistence/jpa/jpql/parser/IdentificationVariable.java b/jpa/org.eclipse.persistence.jpa.jpql/src/main/java/org/eclipse/persistence/jpa/jpql/parser/IdentificationVariable.java index bf6511be374..7941e997a7e 100644 --- a/jpa/org.eclipse.persistence.jpa.jpql/src/main/java/org/eclipse/persistence/jpa/jpql/parser/IdentificationVariable.java +++ b/jpa/org.eclipse.persistence.jpa.jpql/src/main/java/org/eclipse/persistence/jpa/jpql/parser/IdentificationVariable.java @@ -95,25 +95,7 @@ public final class IdentificationVariable extends AbstractExpression { */ public IdentificationVariable(AbstractExpression parent, String identificationVariable) { super(parent, identificationVariable); - //In subqueries "this" generation is not allowed. There are expected qualified IdentificationVariable from query string - if (!Expression.THIS.equalsIgnoreCase(identificationVariable) && getParentExpression().isGenerateThisPrefix() && !isInsideSubquery()) { - this.setVirtualIdentificationVariable(Expression.THIS); - } - } - - private boolean isInsideSubquery() { - boolean result = isSubquery(this); - return result; - } - - private boolean isSubquery(Expression expression) { - if (expression == null) { - return false; - } else if (expression instanceof AbstractSelectStatement && expression.getParent() != null && expression.getParent() instanceof SubExpression) { - return true; - } else { - return isSubquery(expression.getParent()); - } + setThisVirtualIdentificationVariable(true); } /** @@ -133,7 +115,7 @@ public IdentificationVariable(AbstractExpression parent, String identificationVa public void accept(ExpressionVisitor visitor) { //In "this" (Jakarta Data) generation mode pass for a validation stateFieldPathExpression //generated by this.setVirtualIdentificationVariable(Expression.THIS); in constructor above - if (getParentExpression().isGenerateThisPrefix() && isVirtual() && stateFieldPathExpression != null) { + if (getParentExpression().isGenerateImplicitThisAlias() && isVirtual() && stateFieldPathExpression != null) { visitor.visit(getStateFieldPathExpression()); } else { visitor.visit(this); @@ -199,6 +181,17 @@ protected void parse(WordParser wordParser, boolean tolerant) { wordParser.moveForward(getText()); } + public void setThisVirtualIdentificationVariable(boolean addToList) { + //In subqueries "this" generation is not allowed. There are expected qualified IdentificationVariable from query string + if (!Expression.THIS.equalsIgnoreCase(getText()) && getParentExpression().isGenerateImplicitThisAlias() && !isInsideSubquery()) { + this.setVirtualIdentificationVariable(Expression.THIS); + } else { + if (getParentExpression().getIdentificationVariablesWithoutAlias() != null && addToList) { + getParentExpression().getIdentificationVariablesWithoutAlias().add(this); + } + } + } + /** * Sets a virtual identification variable because the abstract schema name was parsed without * one. This is valid in an UPDATE and DELETE queries. This internally transforms @@ -226,4 +219,19 @@ public String toParsedText() { protected void toParsedText(StringBuilder writer, boolean actual) { writer.append(getText()); } + + private boolean isInsideSubquery() { + boolean result = isSubquery(this); + return result; + } + + private boolean isSubquery(Expression expression) { + if (expression == null) { + return false; + } else if (expression instanceof AbstractSelectStatement && expression.getParent() != null && expression.getParent() instanceof SubExpression) { + return true; + } else { + return isSubquery(expression.getParent()); + } + } } diff --git a/jpa/org.eclipse.persistence.jpa.jpql/src/main/java/org/eclipse/persistence/jpa/jpql/parser/JPQLExpression.java b/jpa/org.eclipse.persistence.jpa.jpql/src/main/java/org/eclipse/persistence/jpa/jpql/parser/JPQLExpression.java index ba2091ef8ad..915f011284f 100644 --- a/jpa/org.eclipse.persistence.jpa.jpql/src/main/java/org/eclipse/persistence/jpa/jpql/parser/JPQLExpression.java +++ b/jpa/org.eclipse.persistence.jpa.jpql/src/main/java/org/eclipse/persistence/jpa/jpql/parser/JPQLExpression.java @@ -16,8 +16,13 @@ // package org.eclipse.persistence.jpa.jpql.parser; +import java.util.ArrayList; +import java.util.Arrays; import java.util.Collection; +import java.util.Collections; import java.util.List; +import java.util.Locale; + import org.eclipse.persistence.jpa.jpql.ExpressionTools; import org.eclipse.persistence.jpa.jpql.JPAVersion; import org.eclipse.persistence.jpa.jpql.WordParser; @@ -89,7 +94,15 @@ public final class JPQLExpression extends AbstractExpression implements ParentEx */ private boolean jakartaData = false; - private boolean generateThisPrefix = false; + /** + * Flag if missing alias {@code this} is automatically generated. + */ + private boolean generateImplicitThisAlias = false; + + /** + * List of possible {@code IdentificationVariable} where {@code this} should be generated. + */ + private List identificationVariablesWithoutAlias = new ArrayList<>(); /** * Creates a new JPQLExpression, which is the root of the JPQL parsed tree. @@ -162,6 +175,12 @@ public JPQLExpression(CharSequence jpqlFragment, jpqlFragment = preParse(jpqlFragment); } parse(new WordParser(jpqlFragment), tolerant); + if (generateImplicitThisAlias && getIdentificationVariablesWithoutAlias() != null) { + for (IdentificationVariable identificationVariable : getIdentificationVariablesWithoutAlias()) { + identificationVariable.setThisVirtualIdentificationVariable(false); + } + identificationVariablesWithoutAlias = new ArrayList<>(); + } } /** @@ -257,13 +276,13 @@ public JPQLQueryBNF getQueryBNF() { } @Override - public boolean isGenerateThisPrefix() { - return generateThisPrefix; + public boolean isGenerateImplicitThisAlias() { + return generateImplicitThisAlias; } @Override - public void setGenerateThisPrefix(boolean generateThisPrefix) { - this.generateThisPrefix = generateThisPrefix; + public void setGenerateImplicitThisAlias(boolean generateImplicitThisAlias) { + this.generateImplicitThisAlias = generateImplicitThisAlias; } @Override @@ -301,6 +320,11 @@ public Expression getUnknownEndingStatement() { return unknownEndingStatement; } + @Override + public List getIdentificationVariablesWithoutAlias() { + return identificationVariablesWithoutAlias; + } + /** * Determines whether a query was parsed. The query may be incomplete but it started with one of * the three clauses (SELECT, DELETE FROM, or UPDATE). 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 36b4aebfa17..d437aeb0526 100644 --- a/jpa/org.eclipse.persistence.jpa.jpql/src/main/java/org/eclipse/persistence/jpa/jpql/parser/JPQLGrammar3_2.java +++ b/jpa/org.eclipse.persistence.jpa.jpql/src/main/java/org/eclipse/persistence/jpa/jpql/parser/JPQLGrammar3_2.java @@ -143,6 +143,8 @@ protected void initializeBNFs() { // ID function addChildBNF(SelectExpressionBNF.ID, IdExpressionBNF.ID); addChildBNF(ComparisonExpressionBNF.ID, IdExpressionBNF.ID); + addChildBNF(IdExpressionBNF.ID, GeneralIdentificationVariableBNF.ID); + addChildBNF(IdExpressionBNF.ID, SingleValuedObjectPathExpressionBNF.ID); // VERSION function addChildBNF(SelectExpressionBNF.ID, VersionExpressionBNF.ID); diff --git a/jpa/org.eclipse.persistence.jpa.jpql/src/main/java/org/eclipse/persistence/jpa/jpql/parser/ParentExpression.java b/jpa/org.eclipse.persistence.jpa.jpql/src/main/java/org/eclipse/persistence/jpa/jpql/parser/ParentExpression.java index 2576ba29c22..65f5a889082 100644 --- a/jpa/org.eclipse.persistence.jpa.jpql/src/main/java/org/eclipse/persistence/jpa/jpql/parser/ParentExpression.java +++ b/jpa/org.eclipse.persistence.jpa.jpql/src/main/java/org/eclipse/persistence/jpa/jpql/parser/ParentExpression.java @@ -14,14 +14,20 @@ // 21/07/2024: Ondro Mihalyi - implicit variable in sub-expressions package org.eclipse.persistence.jpa.jpql.parser; +import java.util.List; + public interface ParentExpression extends Expression { /** - * Whether should automatically add missing "this" prefix into where field variables if it doesn't exist. + * Whether Hermes parser should automatically add missing "this" prefix into where field variables if it doesn't exist. + * @return {@code boolean} {@code true} - if this aliases should be generated , {@code false} - if not */ - boolean isGenerateThisPrefix(); + boolean isGenerateImplicitThisAlias(); - void setGenerateThisPrefix(boolean generateThisPrefix); + void setGenerateImplicitThisAlias(boolean generateImplicitThisAlias); - boolean isParentExpression(); + /** + * Get list of {@code IdentificationVariable} where this alias should be added. + */ + List getIdentificationVariablesWithoutAlias(); } diff --git a/jpa/org.eclipse.persistence.jpa.jpql/src/main/java/org/eclipse/persistence/jpa/jpql/parser/RangeVariableDeclaration.java b/jpa/org.eclipse.persistence.jpa.jpql/src/main/java/org/eclipse/persistence/jpa/jpql/parser/RangeVariableDeclaration.java index 6d74dd38351..3e8aa089210 100644 --- a/jpa/org.eclipse.persistence.jpa.jpql/src/main/java/org/eclipse/persistence/jpa/jpql/parser/RangeVariableDeclaration.java +++ b/jpa/org.eclipse.persistence.jpa.jpql/src/main/java/org/eclipse/persistence/jpa/jpql/parser/RangeVariableDeclaration.java @@ -39,7 +39,7 @@ * @since 2.3 * @author Pascal Filion */ -public final class RangeVariableDeclaration extends AbstractExpression { +public final class RangeVariableDeclaration extends AbstractExpression implements ParentExpression { /** * The actual AS identifier found in the string representation of the JPQL query. @@ -175,6 +175,11 @@ public Expression getIdentificationVariable() { return identificationVariable; } + @Override + public List getIdentificationVariablesWithoutAlias() { + return null; + } + @Override public JPQLQueryBNF getQueryBNF() { return getQueryBNF(RangeVariableDeclarationBNF.ID); @@ -252,6 +257,11 @@ public boolean hasVirtualIdentificationVariable() { return virtualIdentificationVariable; } + @Override + public boolean isGenerateImplicitThisAlias() { + return false; + } + @Override protected boolean isParsingComplete(WordParser wordParser, String word, Expression expression) { return word.equalsIgnoreCase(AS) || @@ -289,6 +299,10 @@ protected void parse(WordParser wordParser, boolean tolerant) { } } + @Override + public void setGenerateImplicitThisAlias(boolean generateImplicitThisAlias) { + } + /** * Sets a virtual identification variable because the "root" object was parsed without one. This * is valid in an UPDATE and DELETE queries. Example: @@ -367,7 +381,7 @@ private void addMissingAlias(String aliasName) { || isMissingAliasInUpdateClause() || isMissingAliasInDeleteFromClause()) { this.setVirtualIdentificationVariable(aliasName); - this.getParentExpression().setGenerateThisPrefix(true); + this.getParentExpression().setGenerateImplicitThisAlias(true); } } diff --git a/jpa/org.eclipse.persistence.jpa.jpql/src/main/java/org/eclipse/persistence/jpa/jpql/parser/SubExpression.java b/jpa/org.eclipse.persistence.jpa.jpql/src/main/java/org/eclipse/persistence/jpa/jpql/parser/SubExpression.java index 1463fff0a57..13a533045db 100644 --- a/jpa/org.eclipse.persistence.jpa.jpql/src/main/java/org/eclipse/persistence/jpa/jpql/parser/SubExpression.java +++ b/jpa/org.eclipse.persistence.jpa.jpql/src/main/java/org/eclipse/persistence/jpa/jpql/parser/SubExpression.java @@ -18,6 +18,8 @@ import org.eclipse.persistence.jpa.jpql.ExpressionTools; +import java.util.List; + /** * This expression wraps a sub-expression within parenthesis. * @@ -48,13 +50,13 @@ public SubExpression(AbstractExpression parent, JPQLQueryBNF queryBNF) { } @Override - public boolean isGenerateThisPrefix() { + public boolean isGenerateImplicitThisAlias() { return generateThisPrefix; } @Override - public void setGenerateThisPrefix(boolean generateThisPrefix) { - this.generateThisPrefix = generateThisPrefix; + public void setGenerateImplicitThisAlias(boolean generateImplicitThisAlias) { + this.generateThisPrefix = generateImplicitThisAlias; } @Override @@ -101,4 +103,9 @@ public JPQLQueryBNF getQueryBNF() { protected boolean handleCollection(JPQLQueryBNF queryBNF) { return true; } + + @Override + public List getIdentificationVariablesWithoutAlias() { + return null; + } } diff --git a/jpa/org.eclipse.persistence.jpa.jpql/src/test/java/org/eclipse/persistence/jpa/tests/jpql/parser/DeleteClauseTest.java b/jpa/org.eclipse.persistence.jpa.jpql/src/test/java/org/eclipse/persistence/jpa/tests/jpql/parser/DeleteClauseTest.java index 284b987efd7..59e265a0c98 100644 --- a/jpa/org.eclipse.persistence.jpa.jpql/src/test/java/org/eclipse/persistence/jpa/tests/jpql/parser/DeleteClauseTest.java +++ b/jpa/org.eclipse.persistence.jpa.jpql/src/test/java/org/eclipse/persistence/jpa/tests/jpql/parser/DeleteClauseTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2006, 2020 Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2006, 2024 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 @@ -67,7 +67,7 @@ public void test_JPQLQuery_04() { RangeVariableDeclarationTester rangeVariableDeclaration = rangeVariableDeclaration( abstractSchemaName("Employee"), - virtualVariable("employee") + virtualVariable("this") ); rangeVariableDeclaration.hasSpaceAfterAbstractSchemaName = false; @@ -87,7 +87,7 @@ public void test_JPQLQuery_05() { delete( rangeVariableDeclaration( abstractSchemaName("Employee"), - virtualVariable("employee") + virtualVariable("this") ) ) ); @@ -102,7 +102,7 @@ public void test_JPQLQuery_06() { RangeVariableDeclarationTester rangeVariableDeclaration = rangeVariableDeclarationAs( abstractSchemaName("Employee"), - virtualVariable("employee") + virtualVariable("this") ); rangeVariableDeclaration.hasSpaceAfterAs = false; @@ -131,7 +131,7 @@ public void test_JPQLQuery_08() { String query = "DELETE FROM Employee AS WHERE"; DeleteStatementTester deleteStatement = deleteStatement( - deleteAs(abstractSchemaName("Employee"), virtualVariable("employee")), + deleteAs(abstractSchemaName("Employee"), virtualVariable("this")), where(nullExpression()) ); @@ -162,7 +162,7 @@ public void test_JPQLQuery_10() { whereClause.hasSpaceAfterIdentifier = true; DeleteStatementTester deleteStatement = deleteStatement( - deleteAs(abstractSchemaName("Employee"), virtualVariable("employee")), + deleteAs(abstractSchemaName("Employee"), virtualVariable("this")), whereClause ); diff --git a/jpa/org.eclipse.persistence.jpa.jpql/src/test/java/org/eclipse/persistence/jpa/tests/jpql/parser/EclipseLinkJPQLParserTests2_4.java b/jpa/org.eclipse.persistence.jpa.jpql/src/test/java/org/eclipse/persistence/jpa/tests/jpql/parser/EclipseLinkJPQLParserTests2_4.java index 311df17ba00..1d66f58d0dc 100644 --- a/jpa/org.eclipse.persistence.jpa.jpql/src/test/java/org/eclipse/persistence/jpa/tests/jpql/parser/EclipseLinkJPQLParserTests2_4.java +++ b/jpa/org.eclipse.persistence.jpa.jpql/src/test/java/org/eclipse/persistence/jpa/tests/jpql/parser/EclipseLinkJPQLParserTests2_4.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2011, 2020 Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2011, 2024 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 @@ -201,11 +201,11 @@ public void test_Query_016() { ExpressionTester updateStatement = updateStatement( update( - "Employee", - set("{employee}.name", string("'JPQL'")) + "Employee", "this", + set("{this}.name", string("'JPQL'")), false ), where( - virtualVariable("employee", "column").notEqual(string("'value'")) + virtualVariable("this", "column").notEqual(string("'value'")) ) ); diff --git a/jpa/org.eclipse.persistence.jpa.jpql/src/test/java/org/eclipse/persistence/jpa/tests/jpql/parser/EclipseLinkJPQLParserTests2_5.java b/jpa/org.eclipse.persistence.jpa.jpql/src/test/java/org/eclipse/persistence/jpa/tests/jpql/parser/EclipseLinkJPQLParserTests2_5.java index ba4e78a3c30..2359d95ee75 100644 --- a/jpa/org.eclipse.persistence.jpa.jpql/src/test/java/org/eclipse/persistence/jpa/tests/jpql/parser/EclipseLinkJPQLParserTests2_5.java +++ b/jpa/org.eclipse.persistence.jpa.jpql/src/test/java/org/eclipse/persistence/jpa/tests/jpql/parser/EclipseLinkJPQLParserTests2_5.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2012, 2021 Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2012, 2024 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 @@ -79,7 +79,7 @@ public void test_Query_006() { // UPDATE DateTime SET timestamp = CURRENT_TIMESTAMP ExpressionTester updateStatement = updateStatement( - update("DateTime", set("{datetime}.timestamp", CURRENT_TIMESTAMP())) + update("DateTime", "this", set("{this}.timestamp", CURRENT_TIMESTAMP()), false) ); testQuery(query_006(), updateStatement, buildQueryFormatter_1()); @@ -91,7 +91,7 @@ public void test_Query_007() { // UPDATE DateTime SET scn = CURRENT_TIMESTAMP ExpressionTester updateStatement = updateStatement( - update("DateTime", set("{datetime}.scn", CURRENT_TIMESTAMP())) + update("DateTime", "this", set("{this}.scn", CURRENT_TIMESTAMP()), false) ); testQuery(query_007(), updateStatement, buildQueryFormatter_2()); diff --git a/jpa/org.eclipse.persistence.jpa.jpql/src/test/java/org/eclipse/persistence/jpa/tests/jpql/parser/JPQLExpressionTestJakartaData.java b/jpa/org.eclipse.persistence.jpa.jpql/src/test/java/org/eclipse/persistence/jpa/tests/jpql/parser/JPQLExpressionTestJakartaData.java index 178b53691fd..1b9c92f6137 100644 --- a/jpa/org.eclipse.persistence.jpa.jpql/src/test/java/org/eclipse/persistence/jpa/tests/jpql/parser/JPQLExpressionTestJakartaData.java +++ b/jpa/org.eclipse.persistence.jpa.jpql/src/test/java/org/eclipse/persistence/jpa/tests/jpql/parser/JPQLExpressionTestJakartaData.java @@ -16,8 +16,15 @@ // package org.eclipse.persistence.jpa.tests.jpql.parser; +import static org.eclipse.persistence.jpa.tests.jpql.parser.JPQLParserTester.and; +import static org.eclipse.persistence.jpa.tests.jpql.parser.JPQLParserTester.avg; +import static org.eclipse.persistence.jpa.tests.jpql.parser.JPQLParserTester.division; import static org.eclipse.persistence.jpa.tests.jpql.parser.JPQLParserTester.equal; +import static org.eclipse.persistence.jpa.tests.jpql.parser.JPQLParserTester.id; import static org.eclipse.persistence.jpa.tests.jpql.parser.JPQLParserTester.from; +import static org.eclipse.persistence.jpa.tests.jpql.parser.JPQLParserTester.inputParameter; +import static org.eclipse.persistence.jpa.tests.jpql.parser.JPQLParserTester.isNotNull; +import static org.eclipse.persistence.jpa.tests.jpql.parser.JPQLParserTester.max; 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.select; @@ -51,74 +58,87 @@ public final class JPQLExpressionTestJakartaData extends JPQLParserTest { @Test public void testNoAlias() { - checkAliasFrom("SELECT this FROM NoAliasEntity", Expression.THIS); + JPQLExpression jpqlExpression = JPQLQueryBuilder.buildQuery("SELECT this FROM NoAliasEntity", JPQLGrammar3_2.instance(), JPQLStatementBNF.ID, true, true); + checkAliasFrom(jpqlExpression, Expression.THIS); } @Test public void testNoAliasOBJECT() { - checkAliasFrom("SELECT OBJECT(this) FROM NoAliasEntity", Expression.THIS); + JPQLExpression jpqlExpression = JPQLQueryBuilder.buildQuery("SELECT OBJECT(this) FROM NoAliasEntity", JPQLGrammar3_2.instance(), JPQLStatementBNF.ID, true, true); + checkAliasFrom(jpqlExpression, Expression.THIS); } @Test public void testNoAliasCOUNT() { - checkAliasFrom("SELECT COUNT(this) FROM NoAliasEntity", Expression.THIS); + JPQLExpression jpqlExpression = JPQLQueryBuilder.buildQuery("SELECT COUNT(this) FROM NoAliasEntity", JPQLGrammar3_2.instance(), JPQLStatementBNF.ID, true, true); + checkAliasFrom(jpqlExpression, Expression.THIS); } @Test public void testNoAliasCASTCOUNT() { - checkAliasFrom("SELECT CAST(COUNT(this) AS SMALLINT) FROM NoAliasEntity", Expression.THIS); + JPQLExpression jpqlExpression = JPQLQueryBuilder.buildQuery("SELECT CAST(COUNT(this) AS SMALLINT) FROM NoAliasEntity", JPQLGrammar3_2.instance(), JPQLStatementBNF.ID, true, true); + checkAliasFrom(jpqlExpression, Expression.THIS); } @Test public void testNoAliasCASTCASTCOUNT() { - checkAliasFrom("SELECT CAST(CAST(COUNT(this) AS SMALLINT) AS BIGINT) FROM NoAliasEntity", Expression.THIS); + JPQLExpression jpqlExpression = JPQLQueryBuilder.buildQuery("SELECT CAST(CAST(COUNT(this) AS SMALLINT) AS BIGINT) FROM NoAliasEntity", JPQLGrammar3_2.instance(), JPQLStatementBNF.ID, true, true); + checkAliasFrom(jpqlExpression, Expression.THIS); } @Test public void testCorrectAliases() { - JPQLExpression jpqlExpression = checkAliasFrom("SELECT this FROM NoAliasEntity this WHERE this.id1 = :id1", Expression.THIS); + JPQLExpression jpqlExpression = JPQLQueryBuilder.buildQuery("SELECT this FROM NoAliasEntity this WHERE this.id1 = :id1", JPQLGrammar3_2.instance(), JPQLStatementBNF.ID, true, true); + checkAliasFrom(jpqlExpression, Expression.THIS); checkAliasesWhere(jpqlExpression, Expression.THIS); } @Test public void testNoAliasWhere() { - JPQLExpression jpqlExpression = checkAliasFrom("SELECT this FROM NoAliasEntity this WHERE id1 = :id1", Expression.THIS); + JPQLExpression jpqlExpression = JPQLQueryBuilder.buildQuery("SELECT this FROM NoAliasEntity this WHERE id1 = :id1", JPQLGrammar3_2.instance(), JPQLStatementBNF.ID, true, true); + checkAliasFrom(jpqlExpression, Expression.THIS); checkAliasesWhere(jpqlExpression, Expression.THIS); } @Test public void testNoAliasFromWhere01() { - JPQLExpression jpqlExpression = checkAliasFrom("SELECT this FROM NoAliasEntity WHERE id1 = :id1", Expression.THIS); + JPQLExpression jpqlExpression = JPQLQueryBuilder.buildQuery("SELECT this FROM NoAliasEntity WHERE id1 = :id1", JPQLGrammar3_2.instance(), JPQLStatementBNF.ID, true, true); + checkAliasFrom(jpqlExpression, Expression.THIS); checkAliasesWhere(jpqlExpression, Expression.THIS); } @Test public void testNoAliasFromWhere02() { - JPQLExpression jpqlExpression = checkAliasFrom("SELECT this FROM NoAliasEntity WHERE (id1 = :id1)", Expression.THIS); + JPQLExpression jpqlExpression = JPQLQueryBuilder.buildQuery("SELECT this FROM NoAliasEntity WHERE (id1 = :id1)", JPQLGrammar3_2.instance(), JPQLStatementBNF.ID, true, true); + checkAliasFrom(jpqlExpression, Expression.THIS); checkAliasesWhere(jpqlExpression, Expression.THIS); } @Test public void testNoAliasFromWhere03() { - JPQLExpression jpqlExpression = checkAliasFrom("SELECT this FROM NoAliasEntity WHERE (ID <= :idParam AND UPPER(name) NOT LIKE UPPER(:nameParam) AND UPPER(name) NOT LIKE 'dgdgs') ORDER BY ID DESC, name", Expression.THIS); + JPQLExpression jpqlExpression = JPQLQueryBuilder.buildQuery("SELECT this FROM NoAliasEntity WHERE (ID <= :idParam AND UPPER(name) NOT LIKE UPPER(:nameParam) AND UPPER(name) NOT LIKE 'dgdgs') ORDER BY ID DESC, name", JPQLGrammar3_2.instance(), JPQLStatementBNF.ID, true, true); + checkAliasFrom(jpqlExpression, Expression.THIS); checkAliasesWhere(jpqlExpression, Expression.THIS); } @Test public void testNoAliasFromWhere04() { - JPQLExpression jpqlExpression = checkAliasFrom("SELECT this FROM NoAliasEntity WHERE (:rate * ID <= :max AND :rate * ID >= :min) ORDER BY name", Expression.THIS); + JPQLExpression jpqlExpression = JPQLQueryBuilder.buildQuery("SELECT this FROM NoAliasEntity WHERE (:rate * ID <= :max AND :rate * ID >= :min) ORDER BY name", JPQLGrammar3_2.instance(), JPQLStatementBNF.ID, true, true); + checkAliasFrom(jpqlExpression, Expression.THIS); checkAliasesWhere(jpqlExpression, Expression.THIS); } @Test public void testNoAliasFromWhereAnd() { - JPQLExpression jpqlExpression = checkAliasFrom("SELECT this FROM NoAliasEntity WHERE id1 = :id1 AND name = 'Name 1'", Expression.THIS); + JPQLExpression jpqlExpression = JPQLQueryBuilder.buildQuery("SELECT this FROM NoAliasEntity WHERE id1 = :id1 AND name = 'Name 1'", JPQLGrammar3_2.instance(), JPQLStatementBNF.ID, true, true); + checkAliasFrom(jpqlExpression, Expression.THIS); checkAliasesWhere(jpqlExpression, Expression.THIS); } @Test public void testNoAliasFromWhereAndUPPER() { - JPQLExpression jpqlExpression = checkAliasFrom("SELECT this FROM NoAliasEntity WHERE id1 = :id1 AND UPPER(name) = 'NAME 1'", Expression.THIS); + JPQLExpression jpqlExpression = JPQLQueryBuilder.buildQuery("SELECT this FROM NoAliasEntity WHERE id1 = :id1 AND UPPER(name) = 'NAME 1'", JPQLGrammar3_2.instance(), JPQLStatementBNF.ID, true, true); + checkAliasFrom(jpqlExpression, Expression.THIS); checkAliasesWhere(jpqlExpression, Expression.THIS); } @@ -170,6 +190,54 @@ public void testFunctionNameAsImplicitStateFieldInNumericExpression() { testJakartaDataQuery(inputJPQLQuery, selectStatement); } + // Covers https://github.com/eclipse-ee4j/eclipselink/issues/2182 + @Test + public void testFunctionNameAsImplicitStateFieldInSelectWhereExpression() { + + String inputJPQLQuery = "SELECT name FROM Order WHERE name IS NOT NULL AND id = :idParam"; + + SelectStatementTester selectStatement = selectStatement( + select(virtualVariable("this", "name")), + from("Order", "{this}"), + where(and(isNotNull(virtualVariable("this", "name")), + equal(virtualVariable("this", "id"), + inputParameter(":idParam")) + )) + ); + + testJakartaDataQuery(inputJPQLQuery, selectStatement); + } + + // Covers https://github.com/eclipse-ee4j/eclipselink/issues/2192 + @Test + public void testFunctionNameAsImplicitStateFieldInSelectAggregateMaxExpression() { + + String inputJPQLQuery = "SELECT MAX(price) FROM Item WHERE AVG(price) = 100"; + + SelectStatementTester selectStatement = selectStatement( + select(max(virtualVariable("this", "price"))), + from("Item", "{this}"), + where(equal(avg(virtualVariable("this", "price")), numeric(100))) + ); + + testJakartaDataQuery(inputJPQLQuery, selectStatement); + } + + // Covers https://github.com/eclipse-ee4j/eclipselink/issues/2247 + @Test + public void testFunctionNameAsImplicitStateFieldInSelectArithmeticExpression() { + + String inputJPQLQuery = "SELECT totalPrice / quantity FROM Order WHERE creationYear = :yearParam"; + + SelectStatementTester selectStatement = selectStatement( + select(division(virtualVariable("this", "totalPrice"), virtualVariable("this", "quantity"))), + from("Order", "{this}"), + where(equal(virtualVariable("this", "creationYear"), inputParameter(":yearParam"))) + ); + + testJakartaDataQuery(inputJPQLQuery, selectStatement); + } + @Test public void testUpdateFunctionNameAsImplicitStateFieldInNumericExpression() { @@ -177,18 +245,39 @@ public void testUpdateFunctionNameAsImplicitStateFieldInNumericExpression() { UpdateStatementTester selectStatement = updateStatement( update( - "Order", - set(path("{order}.length"), - virtualVariable("order", "length") + "Order", "this", + set(path("{this}.length"), + virtualVariable("this", "length") .add(numeric(1)) - )) + ), false) + ); + + testJakartaDataQuery(inputJPQLQuery, selectStatement); + } + + // Covers https://github.com/eclipse-ee4j/eclipselink/issues/2184 + @Test + public void testUpdateFunctionNameAsImplicitStateFieldInIdFunction() { + + String inputJPQLQuery = "UPDATE Order SET length = length + 1 WHERE ID(this) = 1"; + + UpdateStatementTester selectStatement = updateStatement( + update( + "Order", "this", + set(path("{this}.length"), + virtualVariable("this", "length") + .add(numeric(1)) + ), false), + where(equal( + id(virtualVariable("this", "this")), + numeric(1) + )) ); testJakartaDataQuery(inputJPQLQuery, selectStatement); } - private JPQLExpression checkAliasFrom(String actualQuery, String expectedAlias) { - JPQLExpression jpqlExpression = JPQLQueryBuilder.buildQuery(actualQuery, JPQLGrammar3_2.instance(), JPQLStatementBNF.ID, true, true); + private void checkAliasFrom(JPQLExpression jpqlExpression, String expectedAlias) { SelectStatement selectStatement = (SelectStatement) jpqlExpression.getQueryStatement(); FromClause fromClause = (FromClause) selectStatement.getFromClause(); IdentificationVariableDeclaration identificationVariableDeclaration = (IdentificationVariableDeclaration) fromClause.getDeclaration(); @@ -196,7 +285,6 @@ private JPQLExpression checkAliasFrom(String actualQuery, String expectedAlias) IdentificationVariable identificationVariable = (IdentificationVariable) rangeVariableDeclaration.getIdentificationVariable(); String alias = identificationVariable.getText(); assertEquals(expectedAlias, alias); - return jpqlExpression; } private void checkAliasesWhere(JPQLExpression jpqlExpression, String expectedAlias) { 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 94feabe3bcc..2b80b86041e 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 @@ -4034,6 +4034,22 @@ public static UpdateClauseTester update(String abstractSchemaName, return updateClause; } + public static UpdateClauseTester update(String abstractSchemaName, + String virtualVariable, + ExpressionTester updateItem, + boolean dummy) { + + UpdateClauseTester updateClause = update( + rangeVariableDeclaration( + abstractSchemaName(abstractSchemaName), + virtualVariable(virtualVariable) + ), + updateItem + ); + updateClause.hasSpaceAfterRangeVariableDeclaration = false; + return updateClause; + } + public static UpdateClauseTester update(String abstractSchemaName, ExpressionTester... updateItems) { diff --git a/jpa/org.eclipse.persistence.jpa.jpql/src/test/java/org/eclipse/persistence/jpa/tests/jpql/parser/JPQLQueriesTest1_0.java b/jpa/org.eclipse.persistence.jpa.jpql/src/test/java/org/eclipse/persistence/jpa/tests/jpql/parser/JPQLQueriesTest1_0.java index bd96f1ddd48..fe810b2626d 100644 --- a/jpa/org.eclipse.persistence.jpa.jpql/src/test/java/org/eclipse/persistence/jpa/tests/jpql/parser/JPQLQueriesTest1_0.java +++ b/jpa/org.eclipse.persistence.jpa.jpql/src/test/java/org/eclipse/persistence/jpa/tests/jpql/parser/JPQLQueriesTest1_0.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2006, 2021 Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2006, 2024 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 @@ -4176,7 +4176,7 @@ final void test_Query_177(JPQLGrammar jpqlGrammar) { // UPDATE DateTime SET date = CURRENT_DATE ExpressionTester updateStatement = updateStatement( - update("DateTime", set("{datetime}.date", CURRENT_DATE())) + update("DateTime", "this", set("{this}.date", CURRENT_DATE()), false) ); testQuery(query_177(), updateStatement, jpqlGrammar); @@ -5248,7 +5248,7 @@ final void test_Query_216(JPQLGrammar jpqlGrammar) { String jpqlQuery = "UPDATE Employee SET avg = 'JPQL'"; UpdateStatementTester updateStatement = updateStatement( - update("Employee", set("{employee}.avg", string("'JPQL'"))) + update("Employee", "this", set("{this}.avg", string("'JPQL'")), false) ); testQuery(jpqlQuery, updateStatement, jpqlGrammar, buildStringFormatter_1()); @@ -5264,7 +5264,7 @@ final void test_Query_217(JPQLGrammar jpqlGrammar) { String jpqlQuery = "UPDATE Employee SET current_timestamp = 'JPQL'"; UpdateStatementTester updateStatement = updateStatement( - update("Employee", set("{employee}.current_timestamp", string("'JPQL'"))) + update("Employee", "this", set("{this}.current_timestamp", string("'JPQL'")), false) ); testQuery(jpqlQuery, updateStatement, jpqlGrammar, buildStringFormatter_2()); @@ -5280,7 +5280,7 @@ final void test_Query_218(JPQLGrammar jpqlGrammar) { String jpqlQuery = "UPDATE Employee SET end = 'JPQL'"; UpdateStatementTester updateStatement = updateStatement( - update("Employee", set("{employee}.end", string("'JPQL'"))) + update("Employee", "this", set("{this}.end", string("'JPQL'")), false) ); testQuery(jpqlQuery, updateStatement, jpqlGrammar, buildStringFormatter_3()); diff --git a/jpa/org.eclipse.persistence.jpa.jpql/src/test/java/org/eclipse/persistence/jpa/tests/jpql/parser/UpdateClauseTest.java b/jpa/org.eclipse.persistence.jpa.jpql/src/test/java/org/eclipse/persistence/jpa/tests/jpql/parser/UpdateClauseTest.java index 2453a7849de..4f980324491 100644 --- a/jpa/org.eclipse.persistence.jpa.jpql/src/test/java/org/eclipse/persistence/jpa/tests/jpql/parser/UpdateClauseTest.java +++ b/jpa/org.eclipse.persistence.jpa.jpql/src/test/java/org/eclipse/persistence/jpa/tests/jpql/parser/UpdateClauseTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2006, 2020 Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2006, 2024 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 @@ -73,7 +73,7 @@ public void test_JPQLQuery_04() { RangeVariableDeclarationTester rangeVariableDeclaration = rangeVariableDeclaration( abstractSchemaName("Employee"), - virtualVariable("employee") + virtualVariable("this") ); rangeVariableDeclaration.hasSpaceAfterAbstractSchemaName = false; rangeVariableDeclaration.hasSpaceAfterAs = false; @@ -94,7 +94,7 @@ public void test_JPQLQuery_05() { RangeVariableDeclarationTester rangeVariableDeclaration = rangeVariableDeclaration( abstractSchemaName("Employee"), - virtualVariable("employee") + virtualVariable("this") ); rangeVariableDeclaration.hasSpaceAfterAbstractSchemaName = true; rangeVariableDeclaration.hasSpaceAfterAs = false; @@ -115,7 +115,7 @@ public void test_JPQLQuery_06() { RangeVariableDeclarationTester rangeVariableDeclaration = rangeVariableDeclarationAs( abstractSchemaName("Employee"), - virtualVariable("employee") + virtualVariable("this") ); rangeVariableDeclaration.hasSpaceAfterAs = false; @@ -147,7 +147,7 @@ public void test_JPQLQuery_08() { String query = "UPDATE Employee AS SET"; - UpdateClauseTester updateClause = updateAs("Employee", "{employee}"); + UpdateClauseTester updateClause = updateAs("Employee", "{this}"); updateClause.hasSet = true; updateClause.hasSpaceAfterSet = false; updateClause.hasSpaceAfterRangeVariableDeclaration = false; @@ -175,7 +175,7 @@ public void test_JPQLQuery_10() { String query = "UPDATE Employee AS SET "; - UpdateClauseTester updateClause = updateAs("Employee", "{employee}"); + UpdateClauseTester updateClause = updateAs("Employee", "{this}"); updateClause.hasSet = true; updateClause.hasSpaceAfterSet = true; updateClause.hasSpaceAfterRangeVariableDeclaration = false; diff --git a/jpa/org.eclipse.persistence.jpa.jpql/src/test/java/org/eclipse/persistence/jpa/tests/jpql/parser/UpdateItemTest.java b/jpa/org.eclipse.persistence.jpa.jpql/src/test/java/org/eclipse/persistence/jpa/tests/jpql/parser/UpdateItemTest.java index 11dcfb1f5e0..18ea09ae695 100644 --- a/jpa/org.eclipse.persistence.jpa.jpql/src/test/java/org/eclipse/persistence/jpa/tests/jpql/parser/UpdateItemTest.java +++ b/jpa/org.eclipse.persistence.jpa.jpql/src/test/java/org/eclipse/persistence/jpa/tests/jpql/parser/UpdateItemTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2006, 2021 Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2006, 2024 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 @@ -68,8 +68,8 @@ public void test_JPQLQuery_03() { UpdateStatementTester updateStatement = updateStatement( update( - "Employee", - set(bad(avg(numeric(2))), string("'Pascal'")) + "Employee", "this", + set(bad(avg(numeric(2))), string("'Pascal'")), false ) ); @@ -83,8 +83,8 @@ public void test_JPQLQuery_04() { UpdateStatementTester updateStatement = updateStatement( update( - "Employee", - set("{employee}.avg", string("'Pascal'")) + "Employee", "this", + set("{this}.avg", string("'Pascal'")), false ) ); diff --git a/jpa/org.eclipse.persistence.jpa.jpql/src/test/java/org/eclipse/persistence/jpa/tests/jpql/tools/AbstractContentAssistTest.java b/jpa/org.eclipse.persistence.jpa.jpql/src/test/java/org/eclipse/persistence/jpa/tests/jpql/tools/AbstractContentAssistTest.java index d7b723fc40c..79cd388bba3 100644 --- a/jpa/org.eclipse.persistence.jpa.jpql/src/test/java/org/eclipse/persistence/jpa/tests/jpql/tools/AbstractContentAssistTest.java +++ b/jpa/org.eclipse.persistence.jpa.jpql/src/test/java/org/eclipse/persistence/jpa/tests/jpql/tools/AbstractContentAssistTest.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2006, 2021 Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2006, 2024 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 @@ -6315,7 +6315,7 @@ public final void test_Update_23() { public final void test_Update_24() { String jpqlQuery = "UPDATE Employee SET e"; int position = "UPDATE Employee SET ".length(); - testHasOnlyTheseProposals(jpqlQuery, position, "employee"); + testHasOnlyTheseProposals(jpqlQuery, position, "this"); } @Test