diff options
author | Ribhav Jain <ribhav.jain@mongodb.com> | 2022-01-10 21:52:45 +0000 |
---|---|---|
committer | Evergreen Agent <no-reply@evergreen.mongodb.com> | 2022-01-10 22:56:08 +0000 |
commit | f97ee7d37f1a0e18f248d0726823445019409b50 (patch) | |
tree | 62a042cd9ccd853791198d9ed7b92456ea12ec8f /src | |
parent | 386986a651b852c3c98b426ea60a023d99e4a5a4 (diff) | |
download | mongo-f97ee7d37f1a0e18f248d0726823445019409b50.tar.gz |
SERVER-61750: Use DISTINCT_SCAN when a regex is a prefix of an index
Diffstat (limited to 'src')
-rw-r--r-- | src/mongo/db/query/index_bounds_builder.cpp | 10 | ||||
-rw-r--r-- | src/mongo/db/query/index_bounds_builder_regex_test.cpp | 35 |
2 files changed, 36 insertions, 9 deletions
diff --git a/src/mongo/db/query/index_bounds_builder.cpp b/src/mongo/db/query/index_bounds_builder.cpp index 90b59975281..ec16c4bb6b4 100644 --- a/src/mongo/db/query/index_bounds_builder.cpp +++ b/src/mongo/db/query/index_bounds_builder.cpp @@ -260,6 +260,16 @@ string IndexBoundsBuilder::simpleRegex(const char* regex, } } else if (strchr("^$.[()+{", c)) { // list of "metacharacters" from man pcrepattern + // For prefix patterns ending in '.*' (ex. /^abc.*/) we can build exact index bounds. + if (!multilineOK && (c == '.')) { + c = *(regex++); + if (c == '*' && *regex == 0) { + *tightnessOut = IndexBoundsBuilder::EXACT; + return ss; + } else { + c = *(regex--); + } + } r = ss; break; } else if (extended && c == '#') { diff --git a/src/mongo/db/query/index_bounds_builder_regex_test.cpp b/src/mongo/db/query/index_bounds_builder_regex_test.cpp index e112443e401..9e251a65b2e 100644 --- a/src/mongo/db/query/index_bounds_builder_regex_test.cpp +++ b/src/mongo/db/query/index_bounds_builder_regex_test.cpp @@ -109,15 +109,6 @@ TEST_F(IndexBoundsBuilderTest, RootedLiteral) { ASSERT_EQUALS(tightness, IndexBoundsBuilder::EXACT); } -TEST_F(IndexBoundsBuilderTest, RootedLiteralWithExtra) { - auto testIndex = buildSimpleIndexEntry(); - IndexBoundsBuilder::BoundsTightness tightness; - std::string prefix = - IndexBoundsBuilder::simpleRegex("^\\Qasdf\\E.*", "", testIndex, &tightness); - ASSERT_EQUALS(prefix, "asdf"); - ASSERT_EQUALS(tightness, IndexBoundsBuilder::INEXACT_COVERED); -} - TEST_F(IndexBoundsBuilderTest, RootedLiteralNoEnd) { auto testIndex = buildSimpleIndexEntry(); IndexBoundsBuilder::BoundsTightness tightness; @@ -331,5 +322,31 @@ TEST_F(IndexBoundsBuilderTest, SimplePrefixRegex) { ASSERT(tightness == IndexBoundsBuilder::EXACT); } +// Using exact index bounds for prefix regex in the form ^[].* +TEST_F(IndexBoundsBuilderTest, RootedLiteralWithExtra) { + auto testIndex = buildSimpleIndexEntry(); + IndexBoundsBuilder::BoundsTightness tightness; + std::string prefix = + IndexBoundsBuilder::simpleRegex("^\\Qasdf\\E.*", "", testIndex, &tightness); + ASSERT_EQUALS(prefix, "asdf"); + ASSERT_EQUALS(tightness, IndexBoundsBuilder::EXACT); +} + +TEST_F(IndexBoundsBuilderTest, PrefixRegex) { + auto testIndex = buildSimpleIndexEntry(); + IndexBoundsBuilder::BoundsTightness tightness; + std::string prefix = IndexBoundsBuilder::simpleRegex("^abc.*", "", testIndex, &tightness); + ASSERT_EQUALS(prefix, "abc"); + ASSERT_EQUALS(tightness, IndexBoundsBuilder::EXACT); +} + +TEST_F(IndexBoundsBuilderTest, RegexWithCharactersFollowingPrefix) { + auto testIndex = buildSimpleIndexEntry(); + IndexBoundsBuilder::BoundsTightness tightness; + std::string prefix = IndexBoundsBuilder::simpleRegex("^abc.*f", "", testIndex, &tightness); + ASSERT_EQUALS(prefix, "abc"); + ASSERT_EQUALS(tightness, IndexBoundsBuilder::INEXACT_COVERED); +} + } // namespace } // namespace mongo |