Skip to content

detectAlias() in QueryUtils incorreclty detects order by clause alias #2563

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

Closed
agzamovr opened this issue Jun 4, 2022 · 9 comments
Closed
Assignees
Labels
in: query-parser Everything related to parsing JPQL or SQL

Comments

@agzamovr
Copy link

agzamovr commented Jun 4, 2022

In the Spring Data shipped with Spring Boot 2.7.0 an order by clause alias is detected incorrectly. It seems like the detectAlias method in QueryUtils class is being confused by subquery in the where clause of the following query:

    @Test
    void testQueryAlias() {
        String query = """
                SELECT o
                  FROM Order o
                   AND EXISTS(SELECT 1
                                FROM Vehicle vehicle
                               WHERE vehicle.vehicleOrderId = o.id
                                 AND LOWER(COALESCE(vehicle.make, '')) LIKE :query)
                """;
        String alias = QueryUtils.detectAlias(query);
        assertThat(alias).isEqualTo("vehicle");
    }

This is a simplified version of the real query but the issue is still reproduced with this one. When running this query with PageRequest.of(0, 20, Sort.by("number")) pageable object to sort orders by number Spring Data generates order by vehicle.number asc clause.

There is a similar issue that was fixed and released in Spring Data 2.7.0. However, it looks like the bug is still there.

@spring-projects-issues spring-projects-issues added the status: waiting-for-triage An issue we've not yet triaged label Jun 4, 2022
@gregturn gregturn self-assigned this Jun 6, 2022
@gregturn gregturn added the in: query-parser Everything related to parsing JPQL or SQL label Jun 6, 2022
@gregturn
Copy link
Contributor

gregturn commented Jun 6, 2022

So far, this appears to be a wrinkle to our subquery detecting logic, which is removes (from ....) subqueries. You have the classic select 1 from ... variation.

It seems possible that if we optionally supported this version, the rest of the logic would flow and find the proper alias as expected.

@gregturn gregturn removed the status: waiting-for-triage An issue we've not yet triaged label Jun 6, 2022
@agzamovr
Copy link
Author

@gregturn Thank you for the response. Is this something that will be fixed in upcoming releases or should I change my query?

@darinmanica
Copy link
Contributor

@agzamovr Is this still an issue? I'm not able to reproduce it on the 2.7.0 tag and up. I've added the following unit test, which passes:

assertThat(detectAlias(
  "SELECT o FROM Order o AND EXISTS(SELECT 1 FROM Vehicle vehicle WHERE vehicle.vehicleOrderId = o.id AND LOWER(COALESCE(vehicle.make, '')) LIKE :query)"))
  .isEqualTo("o");

Similarly, the code that removes the subquery passes this unit test:

assertThat(normalizeWhitespace(removeSubqueries(
  "SELECT o FROM Order o AND EXISTS(SELECT 1 FROM Vehicle vehicle WHERE vehicle.vehicleOrderId = o.id AND LOWER(COALESCE(vehicle.make, '')) LIKE :query)")))
  .isEqualTo("SELECT o FROM Order o AND EXISTS()");

Perhaps I'm just misunderstanding the issue, so additional info may be helpful.

@agzamovr
Copy link
Author

@darinmanica the bug is still reproducible with the latest Spring Boot version 2.7.2. But your point is valid, if I remove new lines from the same query it works as expected:

String query = """
                SELECT o
                  FROM Order o
                 WHERE EXISTS(SELECT 1
                                FROM Vehicle vehicle
                               WHERE vehicle.vehicleOrderId = o.id
                                 AND LOWER(COALESCE(vehicle.make, '')) LIKE :query)
                """;

String alias = detectAlias(query);
assertThat(alias).isEqualTo("vehicle");
// remove all new lines
query = query.replaceAll("\n", "");
alias = detectAlias(query);
assertThat(alias).isEqualTo("o");

Seems like switching from regular Java string to text blocks created the issue. This query is just a toy example of a real query. Tests that execute the real query with the Spring Data repository still fail.

@darinmanica
Copy link
Contributor

darinmanica commented Jul 22, 2022

@agzamovr This was very helpful, thank you. I have this fixed in my local environment and will get a PR submitted soon.

darinmanica added a commit to darinmanica/spring-data-jpa that referenced this issue Jul 22, 2022
@agzamovr
Copy link
Author

@darinmanica is there any reason why your PR #2603 with the fix hasn't been merged yet?

@darinmanica
Copy link
Contributor

@agzamovr No reason that I'm aware of. PR #2557 and #2582 similarly solve the multi-line problem. I personally feel that #2582 should be merged while #2557 and #2603 (mine) should be discarded. Yet, all 3 remain in waiting-for-triage so I'm not sure which will be merged and which will be discarded as duplicates.

gregturn pushed a commit that referenced this issue Sep 28, 2022
gregturn added a commit that referenced this issue Sep 28, 2022
Also added more test cases from related pull requests.

Closes #2582.
Related: #2563, #2557, #2603
@gregturn
Copy link
Contributor

The fix was merged into 91cd84e and additional test cases from the other PRs were folded into f773701.

@gregturn gregturn added this to the 3.0 RC1 (2022.0.0) milestone Sep 28, 2022
gregturn pushed a commit that referenced this issue Sep 29, 2022
gregturn added a commit that referenced this issue Sep 29, 2022
Also added more test cases from related pull requests.

Closes #2582.
Related: #2563, #2557, #2603
gregturn pushed a commit that referenced this issue Sep 29, 2022
gregturn added a commit that referenced this issue Sep 29, 2022
Also added more test cases from related pull requests.

Closes #2582.
Related: #2563, #2557, #2603
@gregturn
Copy link
Contributor

Backported to 2.7.x. and 2.6.x.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
in: query-parser Everything related to parsing JPQL or SQL
Projects
None yet
Development

No branches or pull requests

4 participants