summaryrefslogtreecommitdiff
path: root/src/mongo/db
diff options
context:
space:
mode:
authorHari Khalsa <hkhalsa@10gen.com>2013-10-08 19:28:44 -0400
committerHari Khalsa <hkhalsa@10gen.com>2013-10-09 11:02:54 -0400
commit3c831f3014fe9502a1ec78afce0448757bf7d7f7 (patch)
treea708b1faf28dc5c2aa134f3f997f14fe04b2786e /src/mongo/db
parent3aa47f21fa5d0370cd7a0ef277e7d1d8d359edbb (diff)
downloadmongo-3c831f3014fe9502a1ec78afce0448757bf7d7f7.tar.gz
SERVER-10471 fix intervals generated for minkey/maxkey lt(e) gt(e), modify spigot
Diffstat (limited to 'src/mongo/db')
-rw-r--r--src/mongo/db/query/index_bounds_builder.cpp46
-rw-r--r--src/mongo/db/query/new_find.cpp28
2 files changed, 67 insertions, 7 deletions
diff --git a/src/mongo/db/query/index_bounds_builder.cpp b/src/mongo/db/query/index_bounds_builder.cpp
index 89e3e8cdc6a..1734ef8a2be 100644
--- a/src/mongo/db/query/index_bounds_builder.cpp
+++ b/src/mongo/db/query/index_bounds_builder.cpp
@@ -224,9 +224,17 @@ namespace mongo {
else if (MatchExpression::LTE == expr->matchType()) {
const LTEMatchExpression* node = static_cast<const LTEMatchExpression*>(expr);
BSONElement dataElt = node->getData();
+
+ // Everything is <= MaxKey.
+ if (MaxKey == dataElt.type()) {
+ oilOut->intervals.push_back(allValues());
+ *exactOut = true;
+ return;
+ }
+
BSONObjBuilder bob;
bob.appendMinForType("", dataElt.type());
- bob.append(dataElt);
+ bob.appendAs(dataElt, "");
BSONObj dataObj = bob.obj();
verify(dataObj.isOwned());
oilOut->intervals.push_back(makeRangeInterval(dataObj, true, true));
@@ -236,11 +244,20 @@ namespace mongo {
else if (MatchExpression::LT == expr->matchType()) {
const LTMatchExpression* node = static_cast<const LTMatchExpression*>(expr);
BSONElement dataElt = node->getData();
+
+ // Everything is <= MaxKey.
+ if (MaxKey == dataElt.type()) {
+ oilOut->intervals.push_back(allValues());
+ *exactOut = true;
+ return;
+ }
+
BSONObjBuilder bob;
bob.appendMinForType("", dataElt.type());
- bob.append(dataElt);
+ bob.appendAs(dataElt, "");
BSONObj dataObj = bob.obj();
verify(dataObj.isOwned());
+ cout << "data obj is " << dataObj.toString() << endl;
oilOut->intervals.push_back(makeRangeInterval(dataObj, true, false));
// XXX: only exact if not (null or array)
*exactOut = true;
@@ -248,8 +265,16 @@ namespace mongo {
else if (MatchExpression::GT == expr->matchType()) {
const GTMatchExpression* node = static_cast<const GTMatchExpression*>(expr);
BSONElement dataElt = node->getData();
+
+ // Everything is > MinKey.
+ if (MinKey == dataElt.type()) {
+ oilOut->intervals.push_back(allValues());
+ *exactOut = true;
+ return;
+ }
+
BSONObjBuilder bob;
- bob.append(node->getData());
+ bob.appendAs(node->getData(), "");
bob.appendMaxForType("", dataElt.type());
BSONObj dataObj = bob.obj();
verify(dataObj.isOwned());
@@ -261,8 +286,15 @@ namespace mongo {
const GTEMatchExpression* node = static_cast<const GTEMatchExpression*>(expr);
BSONElement dataElt = node->getData();
+ // Everything is >= MinKey.
+ if (MinKey == dataElt.type()) {
+ oilOut->intervals.push_back(allValues());
+ *exactOut = true;
+ return;
+ }
+
BSONObjBuilder bob;
- bob.append(dataElt);
+ bob.appendAs(dataElt, "");
bob.appendMaxForType("", dataElt.type());
BSONObj dataObj = bob.obj();
verify(dataObj.isOwned());
@@ -464,8 +496,8 @@ namespace mongo {
// We want to merge intervals i and i+1.
// Interval 'i' starts before interval 'i+1'.
BSONObjBuilder bob;
- bob.append(iv[i].start);
- bob.append(iv[i + 1].end);
+ bob.appendAs(iv[i].start, "");
+ bob.appendAs(iv[i + 1].end, "");
BSONObj data = bob.obj();
bool startInclusive = iv[i].startInclusive;
bool endInclusive = iv[i + i].endInclusive;
@@ -505,7 +537,7 @@ namespace mongo {
// static
BSONObj IndexBoundsBuilder::objFromElement(const BSONElement& elt) {
BSONObjBuilder bob;
- bob.append(elt);
+ bob.appendAs(elt, "");
return bob.obj();
}
diff --git a/src/mongo/db/query/new_find.cpp b/src/mongo/db/query/new_find.cpp
index 4d1f81c52de..c0814cb22d5 100644
--- a/src/mongo/db/query/new_find.cpp
+++ b/src/mongo/db/query/new_find.cpp
@@ -35,6 +35,7 @@
#include "mongo/db/index/index_descriptor.h"
#include "mongo/db/keypattern.h"
#include "mongo/db/kill_current_op.h"
+#include "mongo/db/matcher/expression.h"
#include "mongo/db/query/cached_plan_runner.h"
#include "mongo/db/query/canonical_query.h"
#include "mongo/db/query/eof_runner.h"
@@ -101,6 +102,18 @@ namespace mongo {
bool isNewQueryFrameworkEnabled() { return newQueryFrameworkEnabled; }
void enableNewQueryFramework() { newQueryFrameworkEnabled = true; }
+ bool hasNode(MatchExpression* root, MatchExpression::MatchType type) {
+ if (type == root->matchType()) {
+ return true;
+ }
+ for (size_t i = 0; i < root->numChildren(); ++i) {
+ if (hasNode(root->getChild(i), type)) {
+ return true;
+ }
+ }
+ return false;
+ }
+
// Do we use the old or the new? I call this the spigot.
bool canUseNewSystem(const QueryMessage& qm, CanonicalQuery** cqOut) {
CanonicalQuery* cq;
@@ -125,6 +138,21 @@ namespace mongo {
return false;
}
+ if (hasNode(cq->root(), MatchExpression::NOT)
+ || hasNode(cq->root(), MatchExpression::NOR)) {
+
+ cout << "rejecting query w/negation\n";
+ return false;
+ }
+
+ if (pq.returnKey() || pq.showDiskLoc() || (0 != pq.getMaxScan()) || !pq.getMin().isEmpty()
+ || !pq.getMax().isEmpty()) {
+ cout << "rejecting wacky query args query\n";
+ return false;
+ }
+
+ // XXX: 2d.
+
*cqOut = scopedCq.release();
return true;
}