From dc89da4d08c60288b44e70c607ccfdf6bc63b09b Mon Sep 17 00:00:00 2001 From: "Greg L. Turnquist" Date: Mon, 27 Mar 2023 14:01:46 -0500 Subject: [PATCH] Support functions that have semicolons as arguments. A native SQL function with ';' as an argument, e.g. listagg(a.b, ';'), will fail to find anything after it (like an alias). By adding ';' to the list of approved function tokens, queries with functional aliases will work properly. Resolves #2884. Original pull request: #2891 --- .../data/jpa/repository/query/QueryUtils.java | 2 +- .../repository/query/QueryUtilsUnitTests.java | 28 +++++++++++++++++++ 2 files changed, 29 insertions(+), 1 deletion(-) diff --git a/spring-data-jpa/src/main/java/org/springframework/data/jpa/repository/query/QueryUtils.java b/spring-data-jpa/src/main/java/org/springframework/data/jpa/repository/query/QueryUtils.java index f581f191f..0d2c65072 100644 --- a/spring-data-jpa/src/main/java/org/springframework/data/jpa/repository/query/QueryUtils.java +++ b/spring-data-jpa/src/main/java/org/springframework/data/jpa/repository/query/QueryUtils.java @@ -186,7 +186,7 @@ public abstract class QueryUtils { builder = new StringBuilder(); // any function call including parameters within the brackets - builder.append("\\w+\\s*\\([\\w\\.,\\s'=:\\\\?]+\\)"); + builder.append("\\w+\\s*\\([\\w\\.,\\s'=:;\\\\?]+\\)"); // the potential alias builder.append("\\s+[as|AS]+\\s+(([\\w\\.]+))"); diff --git a/spring-data-jpa/src/test/java/org/springframework/data/jpa/repository/query/QueryUtilsUnitTests.java b/spring-data-jpa/src/test/java/org/springframework/data/jpa/repository/query/QueryUtilsUnitTests.java index 45ce3b75e..884ecc2e6 100644 --- a/spring-data-jpa/src/test/java/org/springframework/data/jpa/repository/query/QueryUtilsUnitTests.java +++ b/spring-data-jpa/src/test/java/org/springframework/data/jpa/repository/query/QueryUtilsUnitTests.java @@ -15,6 +15,8 @@ */ package org.springframework.data.jpa.repository.query; +import static org.assertj.core.api.Assertions.*; +import static org.springframework.data.jpa.repository.query.QueryUtils.*; import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.Assertions.assertThatExceptionOfType; import static org.springframework.data.jpa.repository.query.QueryUtils.*; @@ -886,4 +888,30 @@ class QueryUtilsUnitTests { + ") as timestamp\n" // + "from foo f", sort)).endsWith("order by f.age desc"); } + + @Test // GH-2884 + void functionAliasShouldSupportArgumentsWithCommasOrArgumentsWithSemiColons() { + + assertThat(QueryUtils.getFunctionAliases(""" + select s.id as id, s.name as name, gp.points + from specialist s + left join ( + select q.specialist_id, listagg(q.points, ',') as points + from qualification q + group by q.specialist_id + ) gp on gp.specialist_id = s.id + where name like :name + """)).containsExactly("points"); + + assertThat(QueryUtils.getFunctionAliases(""" + select s.id as id, s.name as name, gp.points + from specialist s + left join ( + select q.specialist_id, listagg(q.points, ';') as points + from qualification q + group by q.specialist_id + ) gp on gp.specialist_id = s.id + where name like :name + """)).containsExactly("points"); + } }