예제 #1
0
    // static
    void IndexBoundsBuilder::translateEquality(const BSONElement& data, bool isHashed,
                                               OrderedIntervalList* oil, bool* exact) {
        // We have to copy the data out of the parse tree and stuff it into the index
        // bounds.  BSONValue will be useful here.
        BSONObj dataObj;

        if (isHashed) {
            dataObj = ExpressionMapping::hash(data);
        }
        else {
            dataObj = objFromElement(data);
        }

        // UNITTEST 11738048
        if (Array == dataObj.firstElement().type()) {
            // XXX: bad
            oil->intervals.push_back(allValues());
            *exact = false;
        }
        else {
            verify(dataObj.isOwned());
            oil->intervals.push_back(makePointInterval(dataObj));
            // XXX: it's exact if the index isn't sparse?
            if (dataObj.firstElement().isNull() || isHashed) {
                *exact = false;
            }
            else {
                *exact = true;
            }
        }
    }
예제 #2
0
    // static
    void IndexBoundsBuilder::translate(const MatchExpression* expr, const BSONElement& elt,
                                       OrderedIntervalList* oilOut, bool* exactOut) {
        int direction = (elt.numberInt() >= 0) ? 1 : -1;

        Interval interval;
        bool exact = false;
        oilOut->name = elt.fieldName();

        bool isHashed = false;
        if (mongoutils::str::equals("hashed", elt.valuestrsafe())) {
            isHashed = true;
        }

        if (isHashed) {
            verify(MatchExpression::EQ == expr->matchType()
                   || MatchExpression::MATCH_IN == expr->matchType());
        }

        if (MatchExpression::EQ == expr->matchType()) {
            const EqualityMatchExpression* node =
                static_cast<const EqualityMatchExpression*>(expr);

            // We have to copy the data out of the parse tree and stuff it into the index
            // bounds.  BSONValue will be useful here.
            BSONObj dataObj;

            if (isHashed) {
                dataObj = ExpressionMapping::hash(node->getData());
            }
            else {
                dataObj = objFromElement(node->getData());
            }

            // UNITTEST 11738048
            if (Array == dataObj.firstElement().type()) {
                // XXX: build better bounds
                warning() << "building lazy bounds for " << expr->toString() << endl;
                interval = allValues();
                exact = false;
            }
            else {
                verify(dataObj.isOwned());
                interval = makePointInterval(dataObj);
                // XXX: it's exact if the index isn't sparse
                if (dataObj.firstElement().isNull()) {
                    exact = false;
                }
                else if (isHashed) {
                    exact = false;
                }
                else {
                    exact = true;
                }
            }
        }
        else if (MatchExpression::LTE == expr->matchType()) {
            const LTEMatchExpression* node = static_cast<const LTEMatchExpression*>(expr);
            BSONElement dataElt = node->getData();
            BSONObjBuilder bob;
            bob.appendMinForType("", dataElt.type());
            bob.append(dataElt);
            BSONObj dataObj = bob.obj();
            verify(dataObj.isOwned());
            interval = makeRangeInterval(dataObj, true, true);
            // XXX: only exact if not (null or array)
            exact = true;
        }
        else if (MatchExpression::LT == expr->matchType()) {
            const LTMatchExpression* node = static_cast<const LTMatchExpression*>(expr);
            BSONElement dataElt = node->getData();
            BSONObjBuilder bob;
            bob.appendMinForType("", dataElt.type());
            bob.append(dataElt);
            BSONObj dataObj = bob.obj();
            verify(dataObj.isOwned());
            interval = makeRangeInterval(dataObj, true, false);
            // XXX: only exact if not (null or array)
            exact = true;
        }
        else if (MatchExpression::GT == expr->matchType()) {
            const GTMatchExpression* node = static_cast<const GTMatchExpression*>(expr);
            BSONElement dataElt = node->getData();
            BSONObjBuilder bob;
            bob.append(node->getData());
            bob.appendMaxForType("", dataElt.type());
            BSONObj dataObj = bob.obj();
            verify(dataObj.isOwned());
            interval = makeRangeInterval(dataObj, false, true);
            // XXX: only exact if not (null or array)
            exact = true;
        }
        else if (MatchExpression::GTE == expr->matchType()) {
            const GTEMatchExpression* node = static_cast<const GTEMatchExpression*>(expr);
            BSONElement dataElt = node->getData();

            BSONObjBuilder bob;
            bob.append(dataElt);
            bob.appendMaxForType("", dataElt.type());
            BSONObj dataObj = bob.obj();
            verify(dataObj.isOwned());
            interval = makeRangeInterval(dataObj, true, true);
            // XXX: only exact if not (null or array)
            exact = true;
        }
        else if (MatchExpression::REGEX == expr->matchType()) {
            warning() << "building lazy bounds for " << expr->toString() << endl;
            interval = allValues();
            exact = false;
        }
        else if (MatchExpression::MOD == expr->matchType()) {
            BSONObjBuilder bob;
            bob.appendMinForType("", NumberDouble);
            bob.appendMaxForType("", NumberDouble);
            BSONObj dataObj = bob.obj();
            verify(dataObj.isOwned());
            interval = makeRangeInterval(dataObj, true, true);
            exact = false;
        }
        else if (MatchExpression::MATCH_IN == expr->matchType()) {
            warning() << "building lazy bounds for " << expr->toString() << endl;
            interval = allValues();
            exact = false;
        }
        else if (MatchExpression::TYPE_OPERATOR == expr->matchType()) {
            const TypeMatchExpression* tme = static_cast<const TypeMatchExpression*>(expr);
            BSONObjBuilder bob;
            bob.appendMinForType("", tme->getData());
            bob.appendMaxForType("", tme->getData());
            BSONObj dataObj = bob.obj();
            verify(dataObj.isOwned());
            interval = makeRangeInterval(dataObj, true, true);
            exact = false;
        }
        else if (MatchExpression::MATCH_IN == expr->matchType()) {
            warning() << "building lazy bounds for " << expr->toString() << endl;
            interval = allValues();
            exact = false;
        }
        else if (MatchExpression::GEO == expr->matchType()) {
            const GeoMatchExpression* gme = static_cast<const GeoMatchExpression*>(expr);
            // Can only do this for 2dsphere.
            if (!mongoutils::str::equals("2dsphere", elt.valuestrsafe())) {
                warning() << "Planner error trying to build geo bounds for " << elt.toString()
                          << " index element.";
                verify(0);
            }

            const S2Region& region = gme->getGeoQuery().getRegion();
            ExpressionMapping::cover2dsphere(region, oilOut);
            *exactOut = false;
            // XXX: restructure this method
            return;
        }
        else {
            warning() << "Planner error, trying to build bounds for expr "
                      << expr->toString() << endl;
            verify(0);
        }

        if (-1 == direction) {
            reverseInterval(&interval);
        }

        oilOut->intervals.push_back(interval);
        *exactOut = exact;
    }
예제 #3
0
    // static
    void IndexBoundsBuilder::translate(const MatchExpression* expr, int direction,
                                       OrderedIntervalList* oilOut, bool* exactOut) {
        Interval interval;
        bool exact = false;

        if (expr->isLeaf()) {
            if (MatchExpression::EQ == expr->matchType()) {
                const EqualityMatchExpression* node = static_cast<const EqualityMatchExpression*>(expr);
                // We have to copy the data out of the parse tree and stuff it into the index bounds.
                // BSONValue will be useful here.
                BSONObj dataObj = objFromElement(node->getData());

                if (dataObj.couldBeArray()) {
                    // XXX: build better bounds
                    warning() << "building lazy bounds for " << expr->toString() << endl;
                    interval = allValues();
                    exact = false;
                }
                else {
                    verify(dataObj.isOwned());
                    interval = makePointInterval(dataObj);
                    exact = true;
                }
            }
            else if (MatchExpression::LTE == expr->matchType()) {
                const LTEMatchExpression* node = static_cast<const LTEMatchExpression*>(expr);
                BSONObjBuilder bob;
                bob.appendMinKey("");
                bob.append(node->getData());
                BSONObj dataObj = bob.obj();
                verify(dataObj.isOwned());
                interval = makeRangeInterval(dataObj, true, true);
                exact = true;
            }
            else if (MatchExpression::LT == expr->matchType()) {
                const LTMatchExpression* node = static_cast<const LTMatchExpression*>(expr);
                BSONObjBuilder bob;
                bob.appendMinKey("");
                bob.append(node->getData());
                BSONObj dataObj = bob.obj();
                verify(dataObj.isOwned());
                interval = makeRangeInterval(dataObj, true, false);
                exact = true;
            }
            else if (MatchExpression::GT == expr->matchType()) {
                const GTMatchExpression* node = static_cast<const GTMatchExpression*>(expr);
                BSONObjBuilder bob;
                bob.append(node->getData());
                bob.appendMaxKey("");
                BSONObj dataObj = bob.obj();
                verify(dataObj.isOwned());
                interval = makeRangeInterval(dataObj, false, true);
                exact = true;
            }
            else if (MatchExpression::GTE == expr->matchType()) {
                const GTEMatchExpression* node = static_cast<const GTEMatchExpression*>(expr);
                BSONObjBuilder bob;
                bob.append(node->getData());
                bob.appendMaxKey("");
                BSONObj dataObj = bob.obj();
                verify(dataObj.isOwned());
                interval = makeRangeInterval(dataObj, true, true);
                exact = true;
            }
            else {
                // XXX: build better bounds
                warning() << "building lazy bounds for " << expr->toString() << endl;
                interval = allValues();
                exact = false;
            }
        }
        else {
            // XXX: build better bounds
            verify(expr->isArray());
            warning() << "building lazy bounds for " << expr->toString() << endl;
            interval = allValues();
            exact = false;
        }

        if (-1 == direction) {
            reverseInterval(&interval);
        }

        oilOut->intervals.push_back(interval);
        *exactOut = exact;
    }