Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix for JPQL queries where identifier clashes with function #2218

Conversation

OndroMih
Copy link
Contributor

@OndroMih OndroMih commented Jul 23, 2024

Provides test cases and fix for #2187

Adds some more test cases and fixes for implicit variable this in JPQL queries.

…as a function

E.g., if Box entity has field "length", "delete from Box where length = 1" fails
This commit fixes it.

To do:
- fix copyright headers
Tests with entityManager for SELECT, UPDATE, DELETE with implicit variable
* fix tests in AbstractGrammarValidatorTest for invalid numeric literals. Simplified my previous changes. Recompute word type after reverting functions without arguments. This avoids a literal would be parsed as a number
* fix test advanced.JUnitJPQLModifyTest.updateUnqualifiedAttributeInWhere. An implicit variable was incorrectly added in a nested statement, in which an explicit variable was defined
* @return <code>true</code> if the given sequence of characters is a valid numeric literal;
* <code>false</code> otherwise
*/
protected boolean isNumericLiteral(String text) {
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I didn't delete this method, just moved it to the NumericLiteral class and renamed to hasValidValue, so that it can be used also in the parser, not only in the validator.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

So you did an API change in a public API. Is it required to fix the bug? If so, re-do it in a backward compatible way, with appropriate deprecation step eventually, please.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I found a different way to fix the bug, so I reverted removing this method.

@@ -256,6 +257,7 @@ public int length() {
*/
public void moveBackward(CharSequence word) {
cursor -= word.length();
wordEndPosition();
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Needed to reset the word parser

*
* @return Parent expression
*/
public final ParentExpression getParentExpression() {
Copy link
Contributor Author

@OndroMih OndroMih Jul 23, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

For a query "SELECT e Employee e WHERE (SELECT COUNT(m) FROM managedEmployees m) > 0)", it will return root expression for subexpressions related to the a variable, and will return the nested SELECT COUNT(m) expression for subexpressions related to the m variable

Copy link
Member

@lukasj lukasj left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In general, the code change/fix looks (mostly) good, but given the bug is in the JPQL parser related tests belong to the jpa.test.jpql test app where a test can just reuse existing Room/SimpleRoom entity from the advanced model available there instead of changing jpa.test.persistence32 app dedicated to 3.2 related features

* @return <code>true</code> if the given sequence of characters is a valid numeric literal;
* <code>false</code> otherwise
*/
protected boolean isNumericLiteral(String text) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

So you did an API change in a public API. Is it required to fix the bug? If so, re-do it in a backward compatible way, with appropriate deprecation step eventually, please.

@lukasj
Copy link
Member

lukasj commented Jul 30, 2024

note that JUnitJPQLJakartaDataNoAliasTest may be a good place for more complex tests for queries with no alias

@@ -11,10 +12,15 @@
*/
package org.eclipse.persistence.testing.tests.jpa.persistence32;

import static org.hamcrest.CoreMatchers.equalTo;
import static org.hamcrest.CoreMatchers.is;
import static org.hamcrest.MatcherAssert.assertThat;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There is no single use of hamcrest in the repo and the project itself is happy without it, so do not add it, please.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Removed Hamcrest assertions. The hamcrest dependency is transitively brought to the project by junit. Maybe it would be good to exclude hamcrest from the project. I wouldn't use it if I saw it's excluded.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

inability to avoid hamcrest dependency is known junit 3/4 issue - see ie junit-team/junit4#1145 and/or junit-team/junit4#1741 if you're interested in details

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is no longer true with latest versions of JUnit 4. The Hamcrest dependency of JUnit can be excluded, see: OmniFish-EE@1e6a11c. Should I raise a PR to do it?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is no longer true with latest versions of JUnit 4. The Hamcrest dependency of JUnit can be excluded, see: OmniFish-EE@1e6a11c. Should I raise a PR to do it?

I did it in #2226

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is no longer true with latest versions of JUnit 4. The Hamcrest dependency of JUnit can be excluded, see: OmniFish-EE@1e6a11c. Should I raise a PR to do it?

It looks not so easy in EclipseLink project. There are test failures in #2226
mvn clean verify -pl :org.eclipse.persistence.jpa.jpql throws exception in org.eclipse.persistence.jpa.tests.jpql.AllHermesTests . I think it's releated with @RunWith, org.junit.runner.RunWith.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It looks like hamcrest is used somewhere. Maybe by JUnit itself. Here seems to be the same problem: #261. At that time, it looks like it was necessary to add hamcrest on the classpath in Ant configuration. But the problem was the same - something needed Hamcrest.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, JUnit 4 uses hamcrest in several places: https://github.com/search?q=repo%3Ajunit-team%2Fjunit4+hamcrest+language%3AJava&type=code&l=Java. So it's not possible to completely remove it.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

A solution could be to make hamcrest a runtime dependency. JUnit would work but it couldn't be used in compiled code.

Moved the check for invalid expression to general places in expression and factory.
This method is no longer needed in NumericLiteral after fixes in the previous commit.
Uses existing Room entity with a field named "length"

Note: the test "JUnitJPQLJakartaDataNoAliasTest.tesUpdateQueryWithThisVariable" is still failing
@OndroMih
Copy link
Contributor Author

OndroMih commented Aug 1, 2024

Thank you for your review, @lukasj . I made the changes you requested, please review again.

I moved the tests into JUnitJPQLJakartaDataNoAliasTest and used the Room entity as you suggested.

@lukasj lukasj merged commit 5fe6040 into eclipse-ee4j:master Aug 2, 2024
6 checks passed
@lukasj
Copy link
Member

lukasj commented Aug 2, 2024

thanks!

@lukasj
Copy link
Member

lukasj commented Aug 14, 2024

this caused regressions reported in #2234 and #2235 therefore I had to revert this in #2238

lukasj added a commit to lukasj/eclipselink that referenced this pull request Aug 15, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants