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
This commit is contained in:
committed by
Mark Paluch
parent
7e6e029352
commit
d6227e52f9
@@ -107,7 +107,9 @@ public enum MongoRegexCreator {
|
||||
* @param source
|
||||
* @return
|
||||
* @since 2.2.14
|
||||
* @deprecated since 4.1.1
|
||||
*/
|
||||
@Deprecated(since = "4.1.1", forRemoval = true)
|
||||
public Object toCaseInsensitiveMatch(Object source) {
|
||||
return source instanceof String stringValue ? new BsonRegularExpression(Pattern.quote(stringValue), "i") : source;
|
||||
}
|
||||
|
||||
@@ -25,7 +25,7 @@ import java.util.regex.Pattern;
|
||||
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
|
||||
import org.bson.BsonRegularExpression;
|
||||
import org.springframework.data.domain.Range;
|
||||
import org.springframework.data.domain.Range.Bound;
|
||||
import org.springframework.data.domain.Sort;
|
||||
@@ -390,7 +390,18 @@ class MongoQueryCreator extends AbstractQueryCreator<Query, Criteria> {
|
||||
|
||||
Streamable<?> streamable = asStreamable(iterator.next());
|
||||
if (!isSimpleComparisionPossible(part)) {
|
||||
streamable = streamable.map(MongoRegexCreator.INSTANCE::toCaseInsensitiveMatch);
|
||||
|
||||
MatchMode matchMode = toMatchMode(part.getType());
|
||||
String regexOptions = toRegexOptions(part);
|
||||
|
||||
streamable = streamable.map(it -> {
|
||||
if (it instanceof String value) {
|
||||
|
||||
return new BsonRegularExpression(MongoRegexCreator.INSTANCE.toRegularExpression(value, matchMode),
|
||||
regexOptions);
|
||||
}
|
||||
return it;
|
||||
});
|
||||
}
|
||||
|
||||
return streamable.toList();
|
||||
@@ -481,6 +492,7 @@ class MongoQueryCreator extends AbstractQueryCreator<Query, Criteria> {
|
||||
return MatchMode.REGEX;
|
||||
case NEGATING_SIMPLE_PROPERTY:
|
||||
case SIMPLE_PROPERTY:
|
||||
case IN:
|
||||
return MatchMode.EXACT;
|
||||
default:
|
||||
return MatchMode.DEFAULT;
|
||||
|
||||
@@ -1510,9 +1510,16 @@ public abstract class AbstractPersonRepositoryIntegrationTests implements Dirtie
|
||||
assertThat(result.get(0).getId().equals(bart.getId()));
|
||||
}
|
||||
|
||||
@Test // GH-3395
|
||||
@Test // GH-3395, GH-4404
|
||||
void caseInSensitiveInClause() {
|
||||
|
||||
assertThat(repository.findByLastnameIgnoreCaseIn("bEAuFoRd", "maTTheWs")).hasSize(3);
|
||||
|
||||
repository.save(new Person("the-first", "The First"));
|
||||
repository.save(new Person("the-first-one", "The First One"));
|
||||
repository.save(new Person("the-second", "The Second"));
|
||||
|
||||
assertThat(repository.findByLastnameIgnoreCaseIn("tHE fIRsT")).hasSize(1);
|
||||
}
|
||||
|
||||
@Test // GH-3395
|
||||
|
||||
@@ -25,6 +25,7 @@ import java.lang.reflect.Method;
|
||||
import java.util.List;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
import org.bson.BsonRegularExpression;
|
||||
import org.bson.Document;
|
||||
import org.bson.types.ObjectId;
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
@@ -273,6 +274,17 @@ class MongoQueryCreatorUnitTests {
|
||||
assertThat(query).isEqualTo(query(where("firstName").regex("^dave$", "i")));
|
||||
}
|
||||
|
||||
@Test // GH-4404
|
||||
void createsQueryWithFindByInClauseHavingIgnoreCaseCorrectly() {
|
||||
|
||||
PartTree tree = new PartTree("findAllByFirstNameInIgnoreCase", Person.class);
|
||||
MongoQueryCreator creator = new MongoQueryCreator(tree, getAccessor(converter, List.of("da've", "carter")), context);
|
||||
|
||||
Query query = creator.createQuery();
|
||||
assertThat(query).isEqualTo(query(where("firstName")
|
||||
.in(List.of(new BsonRegularExpression("^\\Qda've\\E$", "i"), new BsonRegularExpression("^carter$", "i")))));
|
||||
}
|
||||
|
||||
@Test // DATAMONGO-770
|
||||
void createsQueryWithFindByNotIgnoreCaseCorrectly() {
|
||||
|
||||
|
||||
Reference in New Issue
Block a user