Skip to content

Commit 746199f

Browse files
christophstroblmp911de
authored andcommittedJun 14, 2023
Use exact matching for IN clause with ignore case.
Prior to this change the generated pattern would have matched more entries than it should have. The behavior is now aligned to its counterpart not using the IgnoreCase flag. Closes #4404 Original pull request: #4412
1 parent 66d6814 commit 746199f

File tree

4 files changed

+36
-3
lines changed

4 files changed

+36
-3
lines changed
 

‎spring-data-mongodb/src/main/java/org/springframework/data/mongodb/core/query/MongoRegexCreator.java

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -107,7 +107,9 @@ public String toRegularExpression(@Nullable String source, @Nullable MatchMode m
107107
* @param source
108108
* @return
109109
* @since 2.2.14
110+
* @deprecated since 3.4.13
110111
*/
112+
@Deprecated
111113
public Object toCaseInsensitiveMatch(Object source) {
112114
return source instanceof String ? new BsonRegularExpression(Pattern.quote((String) source), "i") : source;
113115
}

‎spring-data-mongodb/src/main/java/org/springframework/data/mongodb/repository/query/MongoQueryCreator.java

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@
2525

2626
import org.apache.commons.logging.Log;
2727
import org.apache.commons.logging.LogFactory;
28-
28+
import org.bson.BsonRegularExpression;
2929
import org.springframework.data.domain.Range;
3030
import org.springframework.data.domain.Range.Bound;
3131
import org.springframework.data.domain.Sort;
@@ -406,7 +406,18 @@ private java.util.List<?> nextAsList(Iterator<Object> iterator, Part part) {
406406

407407
Streamable<?> streamable = asStreamable(iterator.next());
408408
if (!isSimpleComparisionPossible(part)) {
409-
streamable = streamable.map(MongoRegexCreator.INSTANCE::toCaseInsensitiveMatch);
409+
410+
MatchMode matchMode = toMatchMode(part.getType());
411+
String regexOptions = toRegexOptions(part);
412+
413+
streamable = streamable.map(it -> {
414+
if (it instanceof String) {
415+
416+
return new BsonRegularExpression(MongoRegexCreator.INSTANCE.toRegularExpression((String) it, matchMode),
417+
regexOptions);
418+
}
419+
return it;
420+
});
410421
}
411422

412423
return streamable.toList();
@@ -498,6 +509,7 @@ private static MatchMode toMatchMode(Type type) {
498509
return MatchMode.REGEX;
499510
case NEGATING_SIMPLE_PROPERTY:
500511
case SIMPLE_PROPERTY:
512+
case IN:
501513
return MatchMode.EXACT;
502514
default:
503515
return MatchMode.DEFAULT;

‎spring-data-mongodb/src/test/java/org/springframework/data/mongodb/repository/AbstractPersonRepositoryIntegrationTests.java

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1451,9 +1451,16 @@ void findByUnwrapped() {
14511451
assertThat(result.get(0).getId().equals(bart.getId()));
14521452
}
14531453

1454-
@Test // GH-3395
1454+
@Test // GH-3395, GH-4404
14551455
void caseInSensitiveInClause() {
1456+
14561457
assertThat(repository.findByLastnameIgnoreCaseIn("bEAuFoRd", "maTTheWs")).hasSize(3);
1458+
1459+
repository.save(new Person("the-first", "The First"));
1460+
repository.save(new Person("the-first-one", "The First One"));
1461+
repository.save(new Person("the-second", "The Second"));
1462+
1463+
assertThat(repository.findByLastnameIgnoreCaseIn("tHE fIRsT")).hasSize(1);
14571464
}
14581465

14591466
@Test // GH-3395

‎spring-data-mongodb/src/test/java/org/springframework/data/mongodb/repository/query/MongoQueryCreatorUnitTests.java

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@
2525
import java.util.List;
2626
import java.util.regex.Pattern;
2727

28+
import org.bson.BsonRegularExpression;
2829
import org.bson.Document;
2930
import org.bson.types.ObjectId;
3031
import org.junit.jupiter.api.BeforeEach;
@@ -277,6 +278,17 @@ void createsQueryWithFindByIgnoreCaseCorrectly() {
277278
assertThat(query).isEqualTo(query(where("firstName").regex("^dave$", "i")));
278279
}
279280

281+
@Test // GH-4404
282+
void createsQueryWithFindByInClauseHavingIgnoreCaseCorrectly() {
283+
284+
PartTree tree = new PartTree("findAllByFirstNameInIgnoreCase", Person.class);
285+
MongoQueryCreator creator = new MongoQueryCreator(tree, getAccessor(converter, List.of("da've", "carter")), context);
286+
287+
Query query = creator.createQuery();
288+
assertThat(query).isEqualTo(query(where("firstName")
289+
.in(List.of(new BsonRegularExpression("^\\Qda've\\E$", "i"), new BsonRegularExpression("^carter$", "i")))));
290+
}
291+
280292
@Test // DATAMONGO-770
281293
void createsQueryWithFindByNotIgnoreCaseCorrectly() {
282294

0 commit comments

Comments
 (0)
Please sign in to comment.