Example #1
0
    // TODO: Move this to query_validator.cpp
    Status isValid(MatchExpression* root) {
        // TODO: This should really be done as part of type checking in the parser.
        Status argStatus = argsValid(root);
        if (!argStatus.isOK()) {
            return argStatus;
        }

        // Analysis below should be done after squashing the tree to make it clearer.

        // There can only be one NEAR.  If there is a NEAR, it must be either the root or the root
        // must be an AND and its child must be a NEAR.
        size_t numGeoNear = countNodes(root, MatchExpression::GEO_NEAR);

        if (0 == numGeoNear) {
            return Status::OK();
        }

        if (numGeoNear > 1) {
            return Status(ErrorCodes::BadValue, "Too many geoNear expressions");
        }

        if (MatchExpression::GEO_NEAR == root->matchType()) {
            return Status::OK();
        }
        else if (MatchExpression::AND == root->matchType()) {
            for (size_t i = 0; i < root->numChildren(); ++i) {
                if (MatchExpression::GEO_NEAR == root->getChild(i)->matchType()) {
                    return Status::OK();
                }
            }
        }

        return Status(ErrorCodes::BadValue, "geoNear must be top-level expr");
    }
Example #2
0
// TODO: Should this really live in the parsing?  Or elsewhere?
Status argsValid(MatchExpression* root) {
    MatchExpression::MatchType type = root->matchType();

    if (MatchExpression::GT == type || MatchExpression::GTE == type
            || MatchExpression::LT == type || MatchExpression::LTE == type) {

        ComparisonMatchExpression* cme = static_cast<ComparisonMatchExpression*>(root);
        BSONElement data = cme->getData();
        if (RegEx == data.type()) {
            return Status(ErrorCodes::BadValue,
                          "Can't have RegEx as arg to pred " + cme->toString());
        }
    }

    for (size_t i = 0; i < root->numChildren(); ++i) {
        Status s = argsValid(root->getChild(i));
        if (!s.isOK()) {
            return s;
        }
    }

    return Status::OK();
}