@@ -161,6 +161,66 @@ void rewritesNamedLikeToUniqueParametersIfNecessary() {
161161 assertThat (((MethodInvocationArgument ) parameterBinding .getOrigin ()).identifier ().getName ()).isEqualTo ("firstname" );
162162 }
163163
164+ @ Test // GH-3784
165+ void rewritesNamedLikeToUniqueParametersRetainingCountQuery () {
166+
167+ DeclaredQuery query = new StringQuery (
168+ "select u from User u where u.firstname like %:firstname or u.firstname like :firstname% or u.firstname = :firstname" ,
169+ false ).deriveCountQuery (null );
170+
171+ assertThat (query .getQueryString ()) //
172+ .isEqualTo (
173+ "select count(u) from User u where u.firstname like :firstname or u.firstname like :firstname_1 or u.firstname = :firstname_2" );
174+
175+ List <ParameterBinding > bindings = query .getParameterBindings ();
176+ assertThat (bindings ).hasSize (3 );
177+
178+ LikeParameterBinding binding = (LikeParameterBinding ) bindings .get (0 );
179+ assertThat (binding ).isNotNull ();
180+ assertThat (binding .getOrigin ()).isEqualTo (ParameterOrigin .ofParameter ("firstname" ));
181+ assertThat (binding .getName ()).isEqualTo ("firstname" );
182+ assertThat (binding .getType ()).isEqualTo (Type .ENDING_WITH );
183+
184+ binding = (LikeParameterBinding ) bindings .get (1 );
185+ assertThat (binding ).isNotNull ();
186+ assertThat (binding .getOrigin ()).isEqualTo (ParameterOrigin .ofParameter ("firstname" ));
187+ assertThat (binding .getName ()).isEqualTo ("firstname_1" );
188+ assertThat (binding .getType ()).isEqualTo (Type .STARTING_WITH );
189+
190+ ParameterBinding parameterBinding = bindings .get (2 );
191+ assertThat (parameterBinding ).isNotNull ();
192+ assertThat (parameterBinding .getOrigin ()).isEqualTo (ParameterOrigin .ofParameter ("firstname" ));
193+ assertThat (parameterBinding .getName ()).isEqualTo ("firstname_2" );
194+ assertThat (((MethodInvocationArgument ) parameterBinding .getOrigin ()).identifier ().getName ()).isEqualTo ("firstname" );
195+ }
196+
197+ @ Test // GH-3784
198+ void rewritesExpressionsLikeToUniqueParametersRetainingCountQuery () {
199+
200+ DeclaredQuery query = new StringQuery (
201+ "select u from User u where u.firstname like %:#{firstname} or u.firstname like :#{firstname}%" , false )
202+ .deriveCountQuery (null );
203+
204+ assertThat (query .getQueryString ()) //
205+ .isEqualTo (
206+ "select count(u) from User u where u.firstname like :__$synthetic$__1 or u.firstname like :__$synthetic$__2" );
207+
208+ List <ParameterBinding > bindings = query .getParameterBindings ();
209+ assertThat (bindings ).hasSize (2 );
210+
211+ LikeParameterBinding binding = (LikeParameterBinding ) bindings .get (0 );
212+ assertThat (binding ).isNotNull ();
213+ assertThat (binding .getOrigin ().isExpression ()).isTrue ();
214+ assertThat (binding .getName ()).isEqualTo ("__$synthetic$__1" );
215+ assertThat (binding .getType ()).isEqualTo (Type .ENDING_WITH );
216+
217+ binding = (LikeParameterBinding ) bindings .get (1 );
218+ assertThat (binding ).isNotNull ();
219+ assertThat (binding .getOrigin ().isExpression ()).isTrue ();
220+ assertThat (binding .getName ()).isEqualTo ("__$synthetic$__2" );
221+ assertThat (binding .getType ()).isEqualTo (Type .STARTING_WITH );
222+ }
223+
164224 @ Test // GH-3041
165225 void rewritesPositionalLikeToUniqueParametersIfNecessary () {
166226
@@ -290,6 +350,48 @@ void detectsMultipleNamedInParameterBindings() {
290350 assertNamedBinding (ParameterBinding .class , "bar" , bindings .get (2 ));
291351 }
292352
353+ @ Test // GH-3784
354+ void deriveCountQueryWithNamedInRetainsOrigin () {
355+
356+ String queryString = "select u from User u where (:logins) IS NULL OR LOWER(u.login) IN (:logins)" ;
357+ DeclaredQuery query = new StringQuery (queryString , false ).deriveCountQuery (null );
358+
359+ assertThat (query .getQueryString ())
360+ .isEqualTo ("select count(u) from User u where (:logins) IS NULL OR LOWER(u.login) IN (:logins_1)" );
361+
362+ List <ParameterBinding > bindings = query .getParameterBindings ();
363+ assertThat (bindings ).hasSize (2 );
364+
365+ assertNamedBinding (ParameterBinding .class , "logins" , bindings .get (0 ));
366+ assertThat ((MethodInvocationArgument ) bindings .get (0 ).getOrigin ()).extracting (MethodInvocationArgument ::identifier )
367+ .extracting (BindingIdentifier ::getName ).isEqualTo ("logins" );
368+
369+ assertNamedBinding (InParameterBinding .class , "logins_1" , bindings .get (1 ));
370+ assertThat ((MethodInvocationArgument ) bindings .get (1 ).getOrigin ()).extracting (MethodInvocationArgument ::identifier )
371+ .extracting (BindingIdentifier ::getName ).isEqualTo ("logins" );
372+ }
373+
374+ @ Test // GH-3784
375+ void deriveCountQueryWithPositionalInRetainsOrigin () {
376+
377+ String queryString = "select u from User u where (?1) IS NULL OR LOWER(u.login) IN (?1)" ;
378+ DeclaredQuery query = new StringQuery (queryString , false ).deriveCountQuery (null );
379+
380+ assertThat (query .getQueryString ())
381+ .isEqualTo ("select count(u) from User u where (?1) IS NULL OR LOWER(u.login) IN (?2)" );
382+
383+ List <ParameterBinding > bindings = query .getParameterBindings ();
384+ assertThat (bindings ).hasSize (2 );
385+
386+ assertPositionalBinding (ParameterBinding .class , 1 , bindings .get (0 ));
387+ assertThat ((MethodInvocationArgument ) bindings .get (0 ).getOrigin ()).extracting (MethodInvocationArgument ::identifier )
388+ .extracting (BindingIdentifier ::getPosition ).isEqualTo (1 );
389+
390+ assertPositionalBinding (InParameterBinding .class , 2 , bindings .get (1 ));
391+ assertThat ((MethodInvocationArgument ) bindings .get (1 ).getOrigin ()).extracting (MethodInvocationArgument ::identifier )
392+ .extracting (BindingIdentifier ::getPosition ).isEqualTo (1 );
393+ }
394+
293395 @ Test // DATAJPA-461
294396 void detectsPositionalInParameterBindings () {
295397
0 commit comments