Example #1
0
    Status LiteParsedQuery::init(const string& ns, int ntoskip, int ntoreturn, int queryOptions,
                                 const BSONObj& queryObj, const BSONObj& proj,
                                 bool fromQueryMessage) {
        _ns = ns;
        _ntoskip = ntoskip;
        _ntoreturn = ntoreturn;
        _options = queryOptions;
        _proj = proj.getOwned();

        if (_ntoskip < 0) {
            return Status(ErrorCodes::BadValue, "bad skip value in query");
        }
        
        if (_ntoreturn < 0) {
            // _ntoreturn greater than zero is simply a hint on how many objects to send back per
            // "cursor batch".  A negative number indicates a hard limit.
            _wantMore = false;
            _ntoreturn = -_ntoreturn;
        }

        if (fromQueryMessage) {
            BSONElement queryField = queryObj["query"];
            if (!queryField.isABSONObj()) { queryField = queryObj["$query"]; }
            if (queryField.isABSONObj()) {
                _filter = queryField.embeddedObject().getOwned();
                Status status = initFullQuery(queryObj);
                if (!status.isOK()) { return status; }
            }
            else {
                // TODO: Does this ever happen?
                _filter = queryObj.getOwned();
            }
        }
        else {
            // This is the debugging code path.
            _filter = queryObj.getOwned();
        }

        _hasReadPref = queryObj.hasField("$readPreference");

        if (!isValidSortOrder(_sort)) {
            return Status(ErrorCodes::BadValue, "bad sort specification");
        }
        _sort = normalizeSortOrder(_sort);

        return Status::OK();
    }
Example #2
0
    Status LiteParsedQuery::init(const string& ns, int ntoskip, int ntoreturn, int queryOptions,
                                 const BSONObj& queryObj, const BSONObj& proj,
                                 bool fromQueryMessage) {
        _ns = ns;
        _ntoskip = ntoskip;
        _ntoreturn = ntoreturn;
        _options = queryOptions;
        _proj = proj.getOwned();

        if (_ntoskip < 0) {
            return Status(ErrorCodes::BadValue, "bad skip value in query");
        }

        if (_ntoreturn == std::numeric_limits<int>::min()) {
            // _ntoreturn is negative but can't be negated.
            return Status(ErrorCodes::BadValue, "bad limit value in query");
        }

        if (_ntoreturn < 0) {
            // _ntoreturn greater than zero is simply a hint on how many objects to send back per
            // "cursor batch".  A negative number indicates a hard limit.
            _wantMore = false;
            _ntoreturn = -_ntoreturn;
        }

        if (fromQueryMessage) {
            BSONElement queryField = queryObj["query"];
            if (!queryField.isABSONObj()) { queryField = queryObj["$query"]; }
            if (queryField.isABSONObj()) {
                _filter = queryField.embeddedObject().getOwned();
                Status status = initFullQuery(queryObj);
                if (!status.isOK()) { return status; }
            }
            else {
                // TODO: Does this ever happen?
                _filter = queryObj.getOwned();
            }
        }
        else {
            // This is the debugging code path.
            _filter = queryObj.getOwned();
        }

        _hasReadPref = queryObj.hasField("$readPreference");

        if (!_sort.isEmpty()) {
            if (!isValidSortOrder(_sort)) {
                return Status(ErrorCodes::BadValue, "bad sort specification");
            }
            _sort = normalizeSortOrder(_sort);
        }

        // Min and Max objects must have the same fields.
        if (!_min.isEmpty() && !_max.isEmpty()) {
            if (!_min.isFieldNamePrefixOf(_max) || (_min.nFields() != _max.nFields())) {
                return Status(ErrorCodes::BadValue, "min and max must have the same field names");
            }
        }

        // Can't combine a normal sort and a $meta projection on the same field.
        BSONObjIterator projIt(_proj);
        while (projIt.more()) {
            BSONElement projElt = projIt.next();
            if (isTextScoreMeta(projElt)) {
                BSONElement sortElt = _sort[projElt.fieldName()];
                if (!sortElt.eoo() && !isTextScoreMeta(sortElt)) {
                    return Status(ErrorCodes::BadValue,
                                  "can't have a non-$meta sort on a $meta projection");
                }
            }
        }

        // All fields with a $meta sort must have a corresponding $meta projection.
        BSONObjIterator sortIt(_sort);
        while (sortIt.more()) {
            BSONElement sortElt = sortIt.next();
            if (isTextScoreMeta(sortElt)) {
                BSONElement projElt = _proj[sortElt.fieldName()];
                if (projElt.eoo() || !isTextScoreMeta(projElt)) {
                    return Status(ErrorCodes::BadValue,
                                  "must have $meta projection for all $meta sort keys");
                }
            }
        }

        return Status::OK();
    }