1515 */
1616package org .springframework .data .jpa .repository .query ;
1717
18- import static org .assertj .core .api .Assertions .assertThat ;
19- import static org .assertj .core .api .Assertions .assertThatExceptionOfType ;
20- import static org .assertj .core .api .Assertions .assertThatIllegalArgumentException ;
21- import static org .assertj .core .api .Assertions .assertThatNullPointerException ;
18+ import static org .assertj .core .api .Assertions .*;
2219
2320import jakarta .persistence .EntityManager ;
2421import jakarta .persistence .PersistenceContext ;
3532import org .junit .jupiter .api .Disabled ;
3633import org .junit .jupiter .api .Test ;
3734import org .junit .jupiter .api .extension .ExtendWith ;
35+
3836import org .springframework .data .jpa .domain .JpaSort ;
3937import org .springframework .data .jpa .domain .sample .User ;
4038import org .springframework .test .context .ContextConfiguration ;
@@ -57,186 +55,199 @@ class HqlOrderExpressionVisitorUnitTests {
5755 @ Test
5856 void genericFunctions () {
5957
60- assertThat (renderOrderBy (JpaSort .unsafe ("LENGTH(firstname)" ), "u " ))
61- .startsWithIgnoringCase ("order by character_length(u .firstname) asc" );
62- assertThat (renderOrderBy (JpaSort .unsafe ("char_length(firstname)" ), "u " ))
63- .startsWithIgnoringCase ("order by char_length(u .firstname) asc" );
58+ assertThat (renderOrderBy (JpaSort .unsafe ("LENGTH(firstname)" ), "var_1 " ))
59+ .startsWithIgnoringCase ("order by character_length(var_1 .firstname) asc" );
60+ assertThat (renderOrderBy (JpaSort .unsafe ("char_length(firstname)" ), "var_1 " ))
61+ .startsWithIgnoringCase ("order by char_length(var_1 .firstname) asc" );
6462
65- assertThat (renderOrderBy (JpaSort .unsafe ("nlssort(firstname, 'NLS_SORT = XGERMAN_DIN_AI')" ), "u " ))
66- .startsWithIgnoringCase ("order by nlssort(u .firstname, 'NLS_SORT = XGERMAN_DIN_AI')" );
63+ assertThat (renderOrderBy (JpaSort .unsafe ("nlssort(firstname, 'NLS_SORT = XGERMAN_DIN_AI')" ), "var_1 " ))
64+ .startsWithIgnoringCase ("order by nlssort(var_1 .firstname, 'NLS_SORT = XGERMAN_DIN_AI')" );
6765 }
6866
6967 @ Test // GH-3172
7068 void cast () {
7169
7270 assertThatExceptionOfType (UnsupportedOperationException .class )
73- .isThrownBy (() -> renderOrderBy (JpaSort .unsafe ("cast(emailAddress as date)" ), "u " ));
71+ .isThrownBy (() -> renderOrderBy (JpaSort .unsafe ("cast(emailAddress as date)" ), "var_1 " ));
7472 }
7573
7674 @ Test // GH-3172
7775 void extract () {
7876
79- assertThat (renderOrderBy (JpaSort .unsafe ("EXTRACT(DAY FROM createdAt)" ), "u " ))
80- .startsWithIgnoringCase ("order by extract(day from u .createdAt)" );
77+ assertThat (renderOrderBy (JpaSort .unsafe ("EXTRACT(DAY FROM createdAt)" ), "var_1 " ))
78+ .startsWithIgnoringCase ("order by extract(day from var_1 .createdAt)" );
8179
82- assertThat (renderOrderBy (JpaSort .unsafe ("WEEK(createdAt)" ), "u " ))
83- .startsWithIgnoringCase ("order by extract(week from u .createdAt)" );
80+ assertThat (renderOrderBy (JpaSort .unsafe ("WEEK(createdAt)" ), "var_1 " ))
81+ .startsWithIgnoringCase ("order by extract(week from var_1 .createdAt)" );
8482 }
8583
8684 @ Test // GH-3172
8785 void trunc () {
88- assertThat (renderOrderBy (JpaSort .unsafe ("TRUNC(age)" ), "u" )).startsWithIgnoringCase ("order by trunc(u.age)" );
86+ assertThat (renderOrderBy (JpaSort .unsafe ("TRUNC(age)" ), "var_1" ))
87+ .startsWithIgnoringCase ("order by trunc(var_1.age)" );
8988 }
9089
9190 @ Test // GH-3172
9291 void upperLower () {
93- assertThat (renderOrderBy (JpaSort .unsafe ("upper(firstname)" ), "u " ))
94- .startsWithIgnoringCase ("order by upper(u .firstname)" );
95- assertThat (renderOrderBy (JpaSort .unsafe ("lower(firstname)" ), "u " ))
96- .startsWithIgnoringCase ("order by lower(u .firstname)" );
92+ assertThat (renderOrderBy (JpaSort .unsafe ("upper(firstname)" ), "var_1 " ))
93+ .startsWithIgnoringCase ("order by upper(var_1 .firstname)" );
94+ assertThat (renderOrderBy (JpaSort .unsafe ("lower(firstname)" ), "var_1 " ))
95+ .startsWithIgnoringCase ("order by lower(var_1 .firstname)" );
9796 }
9897
9998 @ Test // GH-3172
10099 void substring () {
101- assertThat (renderOrderBy (JpaSort .unsafe ("substring(emailAddress, 0, 3)" ), "u " ))
102- .startsWithIgnoringCase ("order by substring(u .emailAddress, 0, 3) asc" );
103- assertThat (renderOrderBy (JpaSort .unsafe ("substring(emailAddress, 0)" ), "u " ))
104- .startsWithIgnoringCase ("order by substring(u .emailAddress, 0) asc" );
100+ assertThat (renderOrderBy (JpaSort .unsafe ("substring(emailAddress, 0, 3)" ), "var_1 " ))
101+ .startsWithIgnoringCase ("order by substring(var_1 .emailAddress, 0, 3) asc" );
102+ assertThat (renderOrderBy (JpaSort .unsafe ("substring(emailAddress, 0)" ), "var_1 " ))
103+ .startsWithIgnoringCase ("order by substring(var_1 .emailAddress, 0) asc" );
105104 }
106105
107106 @ Test // GH-3172
108107 void repeat () {
109- assertThat (renderOrderBy (JpaSort .unsafe ("repeat('a', 5)" ), "u " ))
108+ assertThat (renderOrderBy (JpaSort .unsafe ("repeat('a', 5)" ), "var_1 " ))
110109 .startsWithIgnoringCase ("order by repeat('a', 5) asc" );
111110 }
112111
113112 @ Test // GH-3172
114113 void literals () {
115114
116- assertThat (renderOrderBy (JpaSort .unsafe ("age + 1" ), "u" )).startsWithIgnoringCase ("order by u.age + 1" );
117- assertThat (renderOrderBy (JpaSort .unsafe ("age + 1l" ), "u" )).startsWithIgnoringCase ("order by u.age + 1" );
118- assertThat (renderOrderBy (JpaSort .unsafe ("age + 1L" ), "u" )).startsWithIgnoringCase ("order by u.age + 1" );
119- assertThat (renderOrderBy (JpaSort .unsafe ("age + 1.1" ), "u" )).startsWithIgnoringCase ("order by u.age + 1.1" );
120- assertThat (renderOrderBy (JpaSort .unsafe ("age + 1.1f" ), "u" )).startsWithIgnoringCase ("order by u.age + 1.1" );
121- assertThat (renderOrderBy (JpaSort .unsafe ("age + 1.1bi" ), "u" )).startsWithIgnoringCase ("order by u.age + 1.1" );
122- assertThat (renderOrderBy (JpaSort .unsafe ("age + 1.1bd" ), "u" )).startsWithIgnoringCase ("order by u.age + 1.1" );
123- assertThat (renderOrderBy (JpaSort .unsafe ("age + 0x12" ), "u" )).startsWithIgnoringCase ("order by u.age + 18" );
115+ assertThat (renderOrderBy (JpaSort .unsafe ("age + 1" ), "var_1" )).startsWithIgnoringCase ("order by var_1.age + 1" );
116+ assertThat (renderOrderBy (JpaSort .unsafe ("age + 1l" ), "var_1" )).startsWithIgnoringCase ("order by var_1.age + 1" );
117+ assertThat (renderOrderBy (JpaSort .unsafe ("age + 1L" ), "var_1" )).startsWithIgnoringCase ("order by var_1.age + 1" );
118+ assertThat (renderOrderBy (JpaSort .unsafe ("age + 1.1" ), "var_1" )).startsWithIgnoringCase ("order by var_1.age + 1.1" );
119+ assertThat (renderOrderBy (JpaSort .unsafe ("age + 1.1f" ), "var_1" )).startsWithIgnoringCase ("order by var_1.age + 1.1" );
120+ assertThat (renderOrderBy (JpaSort .unsafe ("age + 1.1bi" ), "var_1" ))
121+ .startsWithIgnoringCase ("order by var_1.age + 1.1" );
122+ assertThat (renderOrderBy (JpaSort .unsafe ("age + 1.1bd" ), "var_1" ))
123+ .startsWithIgnoringCase ("order by var_1.age + 1.1" );
124+ assertThat (renderOrderBy (JpaSort .unsafe ("age + 0x12" ), "var_1" )).startsWithIgnoringCase ("order by var_1.age + 18" );
124125 }
125126
126127 @ Test // GH-3172
127128 void temporalLiterals () {
128129
129130 // JDBC
130- assertThat (renderOrderBy (JpaSort .unsafe ("createdAt + {ts '2024-01-01 12:34:56'}" ), "u " ))
131- .startsWithIgnoringCase ("order by u .createdAt + '2024-01-01T12:34:56'" );
131+ assertThat (renderOrderBy (JpaSort .unsafe ("createdAt + {ts '2024-01-01 12:34:56'}" ), "var_1 " ))
132+ .startsWithIgnoringCase ("order by var_1 .createdAt + '2024-01-01T12:34:56'" );
132133
133- assertThat (renderOrderBy (JpaSort .unsafe ("createdAt + {ts '2012-01-03 09:00:00.000000001'}" ), "u " ))
134- .startsWithIgnoringCase ("order by u .createdAt + '2012-01-03T09:00:00.000000001'" );
134+ assertThat (renderOrderBy (JpaSort .unsafe ("createdAt + {ts '2012-01-03 09:00:00.000000001'}" ), "var_1 " ))
135+ .startsWithIgnoringCase ("order by var_1 .createdAt + '2012-01-03T09:00:00.000000001'" );
135136
136137 // Hibernate NPE
137- assertThatIllegalArgumentException ().isThrownBy (() -> renderOrderBy (JpaSort .unsafe ("createdAt + {t '12:34:56'}" ), "u" ));
138+ assertThatIllegalArgumentException ()
139+ .isThrownBy (() -> renderOrderBy (JpaSort .unsafe ("createdAt + {t '12:34:56'}" ), "var_1" ));
138140
139- assertThat (renderOrderBy (JpaSort .unsafe ("createdAt + {d '2024-01-01'}" ), "u " ))
140- .startsWithIgnoringCase ("order by u .createdAt + '2024-01-01'" );
141+ assertThat (renderOrderBy (JpaSort .unsafe ("createdAt + {d '2024-01-01'}" ), "var_1 " ))
142+ .startsWithIgnoringCase ("order by var_1 .createdAt + '2024-01-01'" );
141143
142144 // JPQL
143- assertThat (renderOrderBy (JpaSort .unsafe ("createdAt + {ts 2024-01-01 12:34:56}" ), "u " ))
144- .startsWithIgnoringCase ("order by u .createdAt + '2024-01-01T12:34:56'" );
145+ assertThat (renderOrderBy (JpaSort .unsafe ("createdAt + {ts 2024-01-01 12:34:56}" ), "var_1 " ))
146+ .startsWithIgnoringCase ("order by var_1 .createdAt + '2024-01-01T12:34:56'" );
145147
146- assertThat (renderOrderBy (JpaSort .unsafe ("createdAt + {t 12:34:56}" ), "u " ))
147- .startsWithIgnoringCase ("order by u .createdAt + '12:34:56'" );
148+ assertThat (renderOrderBy (JpaSort .unsafe ("createdAt + {t 12:34:56}" ), "var_1 " ))
149+ .startsWithIgnoringCase ("order by var_1 .createdAt + '12:34:56'" );
148150
149- assertThat (renderOrderBy (JpaSort .unsafe ("createdAt + {d 2024-01-01}" ), "u " ))
150- .startsWithIgnoringCase ("order by u .createdAt + '2024-01-01'" );
151+ assertThat (renderOrderBy (JpaSort .unsafe ("createdAt + {d 2024-01-01}" ), "var_1 " ))
152+ .startsWithIgnoringCase ("order by var_1 .createdAt + '2024-01-01'" );
151153 }
152154
153155 @ Test // GH-3172
154156 void arithmetic () {
155157
156- // Hibernate representation bugs, should be sum(u.age)
157- assertThat (renderOrderBy (JpaSort .unsafe ("sum(age)" ), "u" )).startsWithIgnoringCase ("order by sum()" );
158- assertThat (renderOrderBy (JpaSort .unsafe ("min(age)" ), "u" )).startsWithIgnoringCase ("order by min()" );
159- assertThat (renderOrderBy (JpaSort .unsafe ("max(age)" ), "u" )).startsWithIgnoringCase ("order by max()" );
160-
161- assertThat (renderOrderBy (JpaSort .unsafe ("age" ), "u" )).startsWithIgnoringCase ("order by u.age" );
162- assertThat (renderOrderBy (JpaSort .unsafe ("age + 1" ), "u" )).startsWithIgnoringCase ("order by u.age + 1" );
163- assertThat (renderOrderBy (JpaSort .unsafe ("ABS(age) + 1" ), "u" )).startsWithIgnoringCase ("order by abs(u.age) + 1" );
164-
165- assertThat (renderOrderBy (JpaSort .unsafe ("neg(active)" ), "u" )).startsWithIgnoringCase ("order by neg(u.active)" );
166- assertThat (renderOrderBy (JpaSort .unsafe ("abs(age)" ), "u" )).startsWithIgnoringCase ("order by abs(u.age)" );
167- assertThat (renderOrderBy (JpaSort .unsafe ("ceiling(age)" ), "u" )).startsWithIgnoringCase ("order by ceiling(u.age)" );
168- assertThat (renderOrderBy (JpaSort .unsafe ("floor(age)" ), "u" )).startsWithIgnoringCase ("order by floor(u.age)" );
169- assertThat (renderOrderBy (JpaSort .unsafe ("round(age)" ), "u" )).startsWithIgnoringCase ("order by round(u.age)" );
170-
171- assertThat (renderOrderBy (JpaSort .unsafe ("prod(age, 1)" ), "u" )).startsWithIgnoringCase ("order by prod(u.age, 1)" );
172- assertThat (renderOrderBy (JpaSort .unsafe ("prod(age, age)" ), "u" ))
173- .startsWithIgnoringCase ("order by prod(u.age, u.age)" );
174-
175- assertThat (renderOrderBy (JpaSort .unsafe ("diff(age, 1)" ), "u" )).startsWithIgnoringCase ("order by diff(u.age, 1)" );
176- assertThat (renderOrderBy (JpaSort .unsafe ("quot(age, 1)" ), "u" )).startsWithIgnoringCase ("order by quot(u.age, 1)" );
177- assertThat (renderOrderBy (JpaSort .unsafe ("mod(age, 1)" ), "u" )).startsWithIgnoringCase ("order by mod(u.age, 1)" );
178- assertThat (renderOrderBy (JpaSort .unsafe ("sqrt(age)" ), "u" )).startsWithIgnoringCase ("order by sqrt(u.age)" );
179- assertThat (renderOrderBy (JpaSort .unsafe ("exp(age)" ), "u" )).startsWithIgnoringCase ("order by exp(u.age)" );
180- assertThat (renderOrderBy (JpaSort .unsafe ("ln(age)" ), "u" )).startsWithIgnoringCase ("order by ln(u.age)" );
158+ // Hibernate representation bugs, should be sum(var_1.age)
159+ assertThat (renderOrderBy (JpaSort .unsafe ("sum(age)" ), "var_1" )).startsWithIgnoringCase ("order by sum()" );
160+ assertThat (renderOrderBy (JpaSort .unsafe ("min(age)" ), "var_1" )).startsWithIgnoringCase ("order by min()" );
161+ assertThat (renderOrderBy (JpaSort .unsafe ("max(age)" ), "var_1" )).startsWithIgnoringCase ("order by max()" );
162+
163+ assertThat (renderOrderBy (JpaSort .unsafe ("age" ), "var_1" )).startsWithIgnoringCase ("order by var_1.age" );
164+ assertThat (renderOrderBy (JpaSort .unsafe ("age + 1" ), "var_1" )).startsWithIgnoringCase ("order by var_1.age + 1" );
165+ assertThat (renderOrderBy (JpaSort .unsafe ("ABS(age) + 1" ), "var_1" ))
166+ .startsWithIgnoringCase ("order by abs(var_1.age) + 1" );
167+
168+ assertThat (renderOrderBy (JpaSort .unsafe ("neg(active)" ), "var_1" ))
169+ .startsWithIgnoringCase ("order by neg(var_1.active)" );
170+ assertThat (renderOrderBy (JpaSort .unsafe ("abs(age)" ), "var_1" )).startsWithIgnoringCase ("order by abs(var_1.age)" );
171+ assertThat (renderOrderBy (JpaSort .unsafe ("ceiling(age)" ), "var_1" ))
172+ .startsWithIgnoringCase ("order by ceiling(var_1.age)" );
173+ assertThat (renderOrderBy (JpaSort .unsafe ("floor(age)" ), "var_1" ))
174+ .startsWithIgnoringCase ("order by floor(var_1.age)" );
175+ assertThat (renderOrderBy (JpaSort .unsafe ("round(age)" ), "var_1" ))
176+ .startsWithIgnoringCase ("order by round(var_1.age)" );
177+
178+ assertThat (renderOrderBy (JpaSort .unsafe ("prod(age, 1)" ), "var_1" ))
179+ .startsWithIgnoringCase ("order by prod(var_1.age, 1)" );
180+ assertThat (renderOrderBy (JpaSort .unsafe ("prod(age, age)" ), "var_1" ))
181+ .startsWithIgnoringCase ("order by prod(var_1.age, var_1.age)" );
182+
183+ assertThat (renderOrderBy (JpaSort .unsafe ("diff(age, 1)" ), "var_1" ))
184+ .startsWithIgnoringCase ("order by diff(var_1.age, 1)" );
185+ assertThat (renderOrderBy (JpaSort .unsafe ("quot(age, 1)" ), "var_1" ))
186+ .startsWithIgnoringCase ("order by quot(var_1.age, 1)" );
187+ assertThat (renderOrderBy (JpaSort .unsafe ("mod(age, 1)" ), "var_1" ))
188+ .startsWithIgnoringCase ("order by mod(var_1.age, 1)" );
189+ assertThat (renderOrderBy (JpaSort .unsafe ("sqrt(age)" ), "var_1" )).startsWithIgnoringCase ("order by sqrt(var_1.age)" );
190+ assertThat (renderOrderBy (JpaSort .unsafe ("exp(age)" ), "var_1" )).startsWithIgnoringCase ("order by exp(var_1.age)" );
191+ assertThat (renderOrderBy (JpaSort .unsafe ("ln(age)" ), "var_1" )).startsWithIgnoringCase ("order by ln(var_1.age)" );
181192 }
182193
183194 @ Test // GH-3172
184195 @ Disabled ("HHH-19075" )
185196 void trim () {
186- assertThat (renderOrderBy (JpaSort .unsafe ("trim(leading '.' from lastname)" ), "u " ))
197+ assertThat (renderOrderBy (JpaSort .unsafe ("trim(leading '.' from lastname)" ), "var_1 " ))
187198 .startsWithIgnoringCase ("order by repeat('a', 5) asc" );
188199 }
189200
190201 @ Test // GH-3172
191202 void groupedExpression () {
192- assertThat (renderOrderBy (JpaSort .unsafe ("(lastname)" ), "u " )).startsWithIgnoringCase ("order by u .lastname" );
203+ assertThat (renderOrderBy (JpaSort .unsafe ("(lastname)" ), "var_1 " )).startsWithIgnoringCase ("order by var_1 .lastname" );
193204 }
194205
195206 @ Test // GH-3172
196207 void tupleExpression () {
197- assertThat (renderOrderBy (JpaSort .unsafe ("(firstname, lastname)" ), "u " ))
198- .startsWithIgnoringCase ("order by u .firstname, u .lastname" );
208+ assertThat (renderOrderBy (JpaSort .unsafe ("(firstname, lastname)" ), "var_1 " ))
209+ .startsWithIgnoringCase ("order by var_1 .firstname, var_1 .lastname" );
199210 }
200211
201212 @ Test // GH-3172
202213 void concat () {
203- assertThat (renderOrderBy (JpaSort .unsafe ("firstname || lastname" ), "u " ))
204- .startsWithIgnoringCase ("order by concat(u .firstname, u .lastname)" );
214+ assertThat (renderOrderBy (JpaSort .unsafe ("firstname || lastname" ), "var_1 " ))
215+ .startsWithIgnoringCase ("order by concat(var_1 .firstname, var_1 .lastname)" );
205216 }
206217
207218 @ Test // GH-3172
208219 void pathBased () {
209220
210- String query = renderQuery (JpaSort .unsafe ("manager.firstname" ), "u " );
221+ String query = renderQuery (JpaSort .unsafe ("manager.firstname" ), "var_1 " );
211222
212- assertThat (query ).contains ("from org.springframework.data.jpa.domain.sample.User u left join u .manager" );
223+ assertThat (query ).contains ("from org.springframework.data.jpa.domain.sample.User var_1 left join var_1 .manager" );
213224 assertThat (query ).contains (".firstname asc nulls last" );
214225 }
215226
216227 @ Test // GH-3172
217228 void caseSwitch () {
218229
219- assertThat (renderOrderBy (JpaSort .unsafe ("case firstname when 'Oliver' then 'A' else firstname end" ), "u " ))
220- .startsWithIgnoringCase ("order by case u .firstname when 'Oliver' then 'A' else u .firstname end" );
230+ assertThat (renderOrderBy (JpaSort .unsafe ("case firstname when 'Oliver' then 'A' else firstname end" ), "var_1 " ))
231+ .startsWithIgnoringCase ("order by case var_1 .firstname when 'Oliver' then 'A' else var_1 .firstname end" );
221232
222233 assertThat (renderOrderBy (
223- JpaSort .unsafe ("case firstname when 'Oliver' then 'A' when 'Joachim' then 'z' else firstname end" ), "u " ))
234+ JpaSort .unsafe ("case firstname when 'Oliver' then 'A' when 'Joachim' then 'z' else firstname end" ), "var_1 " ))
224235 .startsWithIgnoringCase (
225- "order by case u .firstname when 'Oliver' then 'A' when 'Joachim' then 'z' else u .firstname end" );
236+ "order by case var_1 .firstname when 'Oliver' then 'A' when 'Joachim' then 'z' else var_1 .firstname end" );
226237
227- assertThat (renderOrderBy (JpaSort .unsafe ("case when age < 31 then 'A' else firstname end" ), "u " ))
228- .startsWithIgnoringCase ("order by case when u .age < 31 then 'A' else u .firstname end" );
238+ assertThat (renderOrderBy (JpaSort .unsafe ("case when age < 31 then 'A' else firstname end" ), "var_1 " ))
239+ .startsWithIgnoringCase ("order by case when var_1 .age < 31 then 'A' else var_1 .firstname end" );
229240
230241 assertThat (
231- renderOrderBy (JpaSort .unsafe ("case when firstname not in ('Oliver', 'Dave') then 'A' else firstname end" ), "u" ))
242+ renderOrderBy (JpaSort .unsafe ("case when firstname not in ('Oliver', 'Dave') then 'A' else firstname end" ),
243+ "var_1" ))
232244 .startsWithIgnoringCase (
233- "order by case when u .firstname not in ('Oliver', 'Dave') then 'A' else u .firstname end" );
245+ "order by case when var_1 .firstname not in ('Oliver', 'Dave') then 'A' else var_1 .firstname end" );
234246 }
235247
236248 private String renderOrderBy (JpaSort sort , String alias ) {
237249
238250 String query = renderQuery (sort , alias );
239-
240251 String lowerCase = query .toLowerCase (Locale .ROOT );
241252 int index = lowerCase .indexOf ("order by" );
242253
0 commit comments