1717
1818import static org .assertj .core .api .Assertions .*;
1919import static org .springframework .data .jpa .repository .query .QueryUtils .*;
20- import static org .assertj .core .api .Assertions .assertThat ;
21- import static org .assertj .core .api .Assertions .assertThatExceptionOfType ;
22- import static org .springframework .data .jpa .repository .query .QueryUtils .*;
2320
2421import java .util .Collections ;
2522import java .util .Set ;
2825
2926import org .assertj .core .api .SoftAssertions ;
3027import org .junit .jupiter .api .Test ;
28+ import org .junit .jupiter .params .ParameterizedTest ;
29+ import org .junit .jupiter .params .provider .ValueSource ;
3130import org .springframework .dao .InvalidDataAccessApiUsageException ;
3231import org .springframework .data .domain .Sort ;
3332import org .springframework .data .domain .Sort .Order ;
@@ -186,76 +185,84 @@ void testRemoveSubqueries() throws Exception {
186185 @ Test // GH-2581
187186 void testRemoveMultilineSubqueries () {
188187
189- assertThat (normalizeWhitespace (removeSubqueries ("select u from User u\n " //
190- + " where not exists (\n " //
191- + " from User u2\n " //
192- + " )" ))).isEqualTo ("select u from User u where not exists" );
193-
194- assertThat (normalizeWhitespace (removeSubqueries ("(\n " //
195- + " select u from User u \n " //
196- + " where not exists (\n " //
197- + " from User u2\n " //
198- + " )\n " //
199- + ")" ))).isEqualTo ("( select u from User u where not exists )" );
200-
201- assertThat (normalizeWhitespace (removeSubqueries ("select u from User u \n " //
202- + " where not exists (\n " //
203- + " from User u2 \n " //
204- + " where not exists (\n " //
205- + " from User u3\n " //
206- + " )\n " //
207- + " )" ))).isEqualTo ("select u from User u where not exists" );
208-
209- assertThat (normalizeWhitespace (removeSubqueries ("select u from User u \n " //
210- + " where not exists (\n " //
211- + " (\n " //
212- + " from User u2 \n " //
213- + " where not exists (\n " //
214- + " from User u3\n " //
215- + " )\n " //
216- + " )\n " //
217- + " )" ))).isEqualTo ("select u from User u where not exists ( )" );
218-
219- assertThat (normalizeWhitespace (removeSubqueries ("(\n " //
220- + " select u from User u \n " //
221- + " where not exists (\n " //
222- + " (\n " //
223- + " from User u2 \n " //
224- + " where not exists (\n " //
225- + " from User u3\n " //
226- + " )\n " //
227- + " )\n " //
228- + " )\n " //
229- + ")" ))).isEqualTo ("( select u from User u where not exists ( ) )" );
188+ assertThat (normalizeWhitespace (removeSubqueries ("""
189+ select u from User u
190+ where not exists (
191+ from User u2
192+ )""" ))).isEqualTo ("select u from User u where not exists" );
193+
194+ assertThat (normalizeWhitespace (removeSubqueries ("""
195+ (
196+ select u from User u\s
197+ where not exists (
198+ from User u2
199+ )
200+ )""" ))).isEqualTo ("( select u from User u where not exists )" );
201+
202+ assertThat (normalizeWhitespace (removeSubqueries ("""
203+ select u from User u\s
204+ where not exists (
205+ from User u2\s
206+ where not exists (
207+ from User u3
208+ )
209+ )""" ))).isEqualTo ("select u from User u where not exists" );
210+
211+ assertThat (normalizeWhitespace (removeSubqueries ("""
212+ select u from User u\s
213+ where not exists (
214+ (
215+ from User u2\s
216+ where not exists (
217+ from User u3
218+ )
219+ )
220+ )""" ))).isEqualTo ("select u from User u where not exists ( )" );
221+
222+ assertThat (normalizeWhitespace (removeSubqueries ("""
223+ (
224+ select u from User u\s
225+ where not exists (
226+ (
227+ from User u2\s
228+ where not exists (
229+ from User u3
230+ )
231+ )
232+ )
233+ )""" ))).isEqualTo ("( select u from User u where not exists ( ) )" );
230234 }
231235
232236 @ Test // GH-2557
233237 void applySortingAccountsForNewlinesInSubselect () {
234238
235239 Sort sort = Sort .by (Order .desc ("age" ));
236240
237- assertThat (QueryUtils .applySorting ("select u\n " + //
238- "from user u\n " + //
239- "where exists (select u2\n " + //
240- "from user u2\n " + //
241- ")\n " + //
242- "" , sort )).isEqualTo ("select u\n " + //
243- "from user u\n " + //
244- "where exists (select u2\n " + //
245- "from user u2\n " + //
246- ")\n " + //
247- " order by u.age desc" );
241+ assertThat (QueryUtils .applySorting ("""
242+ select u
243+ from user u
244+ where exists (select u2
245+ from user u2
246+ )
247+ """ , sort )).isEqualTo ("""
248+ select u
249+ from user u
250+ where exists (select u2
251+ from user u2
252+ )
253+ order by u.age desc""" );
248254 }
249255
250256 @ Test // GH-2563
251257 void aliasDetectionProperlyHandlesNewlinesInSubselects () {
252258
253- assertThat (detectAlias ("SELECT o\n " + //
254- "FROM Order o\n " + //
255- "AND EXISTS(SELECT 1\n " + //
256- "FROM Vehicle vehicle\n " + //
257- "WHERE vehicle.vehicleOrderId = o.id\n " + //
258- "AND LOWER(COALESCE(vehicle.make, '')) LIKE :query)" )).isEqualTo ("o" );
259+ assertThat (detectAlias ("""
260+ SELECT o
261+ FROM Order o
262+ AND EXISTS(SELECT 1
263+ FROM Vehicle vehicle
264+ WHERE vehicle.vehicleOrderId = o.id
265+ AND LOWER(COALESCE(vehicle.make, '')) LIKE :query)""" )).isEqualTo ("o" );
259266 }
260267
261268 private String normalizeWhitespace (String s ) {
@@ -570,10 +577,14 @@ void detectsAliasWithGroupAndOrderBy() {
570577 @ Test // DATAJPA-1500
571578 void createCountQuerySupportsWhitespaceCharacters () {
572579
573- assertThat (createCountQueryFor ("select * from User user\n " + //
574- " where user.age = 18\n " + //
575- " order by user.name\n " )).isEqualTo ("select count(user) from User user\n " + //
576- " where user.age = 18\n " );
580+ assertThat (createCountQueryFor ("""
581+ select * from User user
582+ where user.age = 18
583+ order by user.name
584+ \s """ )).isEqualTo ("""
585+ select count(user) from User user
586+ where user.age = 18
587+ \s """ );
577588 }
578589
579590 @ Test // GH-2341
@@ -584,12 +595,18 @@ void createCountQueryStarCharacterConverted() {
584595 @ Test
585596 void createCountQuerySupportsLineBreaksInSelectClause () {
586597
587- assertThat (createCountQueryFor ("select user.age,\n " + //
588- " user.name\n " + //
589- " from User user\n " + //
590- " where user.age = 18\n " + //
591- " order\n by\n user.name\n " )).isEqualTo ("select count(user) from User user\n " + //
592- " where user.age = 18\n " );
598+ assertThat (createCountQueryFor ("""
599+ select user.age,
600+ user.name
601+ from User user
602+ where user.age = 18
603+ order
604+ by
605+ user.name
606+ \s """ )).isEqualTo ("""
607+ select count(user) from User user
608+ where user.age = 18
609+ \s """ );
593610 }
594611
595612 @ Test // DATAJPA-1061
@@ -640,11 +657,20 @@ void appliesSortCorrectlyForSimpleField() {
640657 @ Test
641658 void createCountQuerySupportsLineBreakRightAfterDistinct () {
642659
643- assertThat (createCountQueryFor ("select\n distinct\n user.age,\n " + //
644- "user.name\n " + //
645- "from\n User\n user" )).isEqualTo (createCountQueryFor ("select\n distinct user.age,\n " + //
646- "user.name\n " + //
647- "from\n User\n user" ));
660+ assertThat (createCountQueryFor ("""
661+ select
662+ distinct
663+ user.age,
664+ user.name
665+ from
666+ User
667+ user""" )).isEqualTo (createCountQueryFor ("""
668+ select
669+ distinct user.age,
670+ user.name
671+ from
672+ User
673+ user""" ));
648674 }
649675
650676 @ Test
@@ -821,34 +847,37 @@ void orderByShouldWorkWithSubSelectStatements() {
821847
822848 Sort sort = Sort .by (Order .desc ("age" ));
823849
824- assertThat (QueryUtils .applySorting ("SELECT\n " //
825- + " foo_bar.*\n " //
826- + "FROM\n " //
827- + " foo foo\n " //
828- + "INNER JOIN\n " //
829- + " foo_bar_dnrmv foo_bar ON\n " //
830- + " foo_bar.foo_id = foo.foo_id\n " //
831- + "INNER JOIN\n " //
832- + " (\n " //
833- + " SELECT\n " //
834- + " foo_bar_action.*,\n " //
835- + " RANK() OVER (PARTITION BY \" foo_bar_action\" .attributes->>'baz' ORDER BY \" foo_bar_action\" .attributes->>'qux' DESC) AS ranking\n " //
836- + " FROM\n " //
837- + " foo_bar_action\n " //
838- + " WHERE\n " //
839- + " foo_bar_action.deleted_ts IS NULL)\n " //
840- + " foo_bar_action ON\n " //
841- + " foo_bar.foo_bar_id = foo_bar_action.foo_bar_id\n " //
842- + " AND ranking = 1\n " //
843- + "INNER JOIN\n " //
844- + " bar bar ON\n " //
845- + " foo_bar.bar_id = bar.bar_id\n " //
846- + "INNER JOIN\n " //
847- + " bar_metadata bar_metadata ON\n " //
848- + " bar.bar_metadata_key = bar_metadata.bar_metadata_key\n " //
849- + "WHERE\n " //
850- + " foo.tenant_id =:tenantId\n " //
851- + "AND (foo.attributes ->> :serialNum IN (:serialNumValue))" , sort )).endsWith ("order by foo.age desc" );
850+ assertThat (QueryUtils .applySorting (
851+ """
852+ SELECT
853+ foo_bar.*
854+ FROM
855+ foo foo
856+ INNER JOIN
857+ foo_bar_dnrmv foo_bar ON
858+ foo_bar.foo_id = foo.foo_id
859+ INNER JOIN
860+ (
861+ SELECT
862+ foo_bar_action.*,
863+ RANK() OVER (PARTITION BY "foo_bar_action".attributes->>'baz' ORDER BY "foo_bar_action".attributes->>'qux' DESC) AS ranking
864+ FROM
865+ foo_bar_action
866+ WHERE
867+ foo_bar_action.deleted_ts IS NULL)
868+ foo_bar_action ON
869+ foo_bar.foo_bar_id = foo_bar_action.foo_bar_id
870+ AND ranking = 1
871+ INNER JOIN
872+ bar bar ON
873+ foo_bar.bar_id = bar.bar_id
874+ INNER JOIN
875+ bar_metadata bar_metadata ON
876+ bar.bar_metadata_key = bar_metadata.bar_metadata_key
877+ WHERE
878+ foo.tenant_id =:tenantId
879+ AND (foo.attributes ->> :serialNum IN (:serialNumValue))""" ,
880+ sort )).endsWith ("order by foo.age desc" );
852881
853882 assertThat (QueryUtils .applySorting ("select r " //
854883 + "From DataRecord r " //
@@ -877,41 +906,32 @@ void orderByShouldWorkWithSubSelectStatements() {
877906 + "+ \" WHERE i2.field.id = :fieldId \" " //
878907 + "+ \" GROUP BY i2.field.id, i2.version)" , sort )).endsWith ("order by i.age desc" );
879908
880- assertThat (QueryUtils .applySorting ("select \n " //
881- + " f.id,\n " //
882- + " (\n " //
883- + " select timestamp from bar\n " //
884- + " where date(bar.timestamp) > '2022-05-21'\n " //
885- + " and bar.foo_id = f.id \n " //
886- + " order by date(bar.timestamp) desc\n " //
887- + " limit 1\n " //
888- + ") as timestamp\n " //
889- + "from foo f" , sort )).endsWith ("order by f.age desc" );
909+ assertThat (QueryUtils .applySorting ("""
910+ select\s
911+ f.id,
912+ (
913+ select timestamp from bar
914+ where date(bar.timestamp) > '2022-05-21'
915+ and bar.foo_id = f.id\s
916+ order by date(bar.timestamp) desc
917+ limit 1
918+ ) as timestamp
919+ from foo f""" , sort )).endsWith ("order by f.age desc" );
890920 }
891921
892- @ Test // GH-2884
893- void functionAliasShouldSupportArgumentsWithCommasOrArgumentsWithSemiColons () {
894-
895- assertThat (QueryUtils .getFunctionAliases ("""
896- select s.id as id, s.name as name, gp.points
897- from specialist s
898- left join (
899- select q.specialist_id, listagg(q.points, ',') as points
900- from qualification q
901- group by q.specialist_id
902- ) gp on gp.specialist_id = s.id
903- where name like :name
904- """ )).containsExactly ("points" );
922+ @ ParameterizedTest // GH-2884
923+ @ ValueSource (strings = { "," , ";" })
924+ void functionAliasShouldSupportArgumentsWithCommasOrArgumentsWithSemiColons (String arg ) {
905925
906- assertThat (QueryUtils .getFunctionAliases ("""
926+ assertThat (QueryUtils .getFunctionAliases (String . format ( """
907927 select s.id as id, s.name as name, gp.points
908928 from specialist s
909929 left join (
910- select q.specialist_id, listagg(q.points, '; ') as points
930+ select q.specialist_id, listagg(q.points, '%s ') as points
911931 from qualification q
912932 group by q.specialist_id
913933 ) gp on gp.specialist_id = s.id
914934 where name like :name
915- """ )).containsExactly ("points" );
935+ """ , arg ) )).containsExactly ("points" );
916936 }
917937}
0 commit comments