summaryrefslogtreecommitdiff
path: root/src/mongo/db/query/plan_cache.cpp
diff options
context:
space:
mode:
authorTess Avitabile <tess.avitabile@mongodb.com>2016-07-07 16:05:06 -0400
committerTess Avitabile <tess.avitabile@mongodb.com>2016-07-07 17:39:54 -0400
commit419a2e4eaf791a8d217050dbf0ca63149f261e0f (patch)
treeba9c00ba775f0cae95cdf16e75a1ac65e7b05cc1 /src/mongo/db/query/plan_cache.cpp
parent60af078e700d68999621dcd511f09220ab4d1892 (diff)
downloadmongo-419a2e4eaf791a8d217050dbf0ca63149f261e0f.tar.gz
SERVER-23882 Collation should be considered part of a query's shape
Diffstat (limited to 'src/mongo/db/query/plan_cache.cpp')
-rw-r--r--src/mongo/db/query/plan_cache.cpp15
1 files changed, 12 insertions, 3 deletions
diff --git a/src/mongo/db/query/plan_cache.cpp b/src/mongo/db/query/plan_cache.cpp
index 8268555215d..5554438ba09 100644
--- a/src/mongo/db/query/plan_cache.cpp
+++ b/src/mongo/db/query/plan_cache.cpp
@@ -36,6 +36,7 @@
#include "mongo/client/dbclientinterface.h" // For QueryOption_foobar
#include "mongo/db/matcher/expression_array.h"
#include "mongo/db/matcher/expression_geo.h"
+#include "mongo/db/query/collation/collator_interface.h"
#include "mongo/db/query/plan_ranker.h"
#include "mongo/db/query/query_knobs.h"
#include "mongo/db/query/query_solution.h"
@@ -57,6 +58,7 @@ const char kEncodeChildrenEnd = ']';
const char kEncodeChildrenSeparator = ',';
const char kEncodeSortSection = '~';
const char kEncodeProjectionSection = '|';
+const char kEncodeCollationSection = '#';
/**
* Encode user-provided string. Cache key delimiters seen in the
@@ -73,6 +75,7 @@ void encodeUserString(StringData s, StringBuilder* keyBuilder) {
case kEncodeChildrenSeparator:
case kEncodeSortSection:
case kEncodeProjectionSection:
+ case kEncodeCollationSection:
case '\\':
*keyBuilder << '\\';
// Fall through to default case.
@@ -309,6 +312,7 @@ CachedSolution::CachedSolution(const PlanCacheKey& key, const PlanCacheEntry& en
query(entry.query.getOwned()),
sort(entry.sort.getOwned()),
projection(entry.projection.getOwned()),
+ collation(entry.collation.getOwned()),
decisionWorks(entry.decision->stats[0]->common.works) {
// CachedSolution should not having any references into
// cache entry. All relevant data should be cloned/copied.
@@ -369,6 +373,7 @@ PlanCacheEntry* PlanCacheEntry::clone() const {
entry->query = query.getOwned();
entry->sort = sort.getOwned();
entry->projection = projection.getOwned();
+ entry->collation = collation.getOwned();
// Copy performance stats.
for (size_t i = 0; i < feedback.size(); ++i) {
@@ -383,6 +388,7 @@ PlanCacheEntry* PlanCacheEntry::clone() const {
std::string PlanCacheEntry::toString() const {
return str::stream() << "(query: " << query.toString() << ";sort: " << sort.toString()
<< ";projection: " << projection.toString()
+ << ";collation: " << collation.toString()
<< ";solutions: " << plannerData.size() << ")";
}
@@ -500,13 +506,13 @@ void PlanCache::encodeKeyForMatch(const MatchExpression* tree, StringBuilder* ke
}
// Encode indexability.
- const IndexabilityDiscriminators& discriminators =
+ const IndexToDiscriminatorMap& discriminators =
_indexabilityState.getDiscriminators(tree->path());
if (!discriminators.empty()) {
*keyBuilder << kEncodeDiscriminatorsBegin;
// For each discriminator on this path, append the character '0' or '1'.
- for (const IndexabilityDiscriminator& discriminator : discriminators) {
- *keyBuilder << discriminator(tree);
+ for (auto&& indexAndDiscriminatorPair : discriminators) {
+ *keyBuilder << indexAndDiscriminatorPair.second.isMatchCompatibleWithIndex(tree);
}
*keyBuilder << kEncodeDiscriminatorsEnd;
}
@@ -639,6 +645,9 @@ Status PlanCache::add(const CanonicalQuery& query,
const QueryRequest& qr = query.getQueryRequest();
entry->query = qr.getFilter().getOwned();
entry->sort = qr.getSort().getOwned();
+ if (query.getCollator()) {
+ entry->collation = query.getCollator()->getSpec().toBSON();
+ }
// Strip projections on $-prefixed fields, as these are added by internal callers of the query
// system and are not considered part of the user projection.