// static StatusWith<std::unique_ptr<CanonicalQuery>> CanonicalQuery::canonicalize( OperationContext* opCtx, std::unique_ptr<QueryRequest> qr, const boost::intrusive_ptr<ExpressionContext>& expCtx, const ExtensionsCallback& extensionsCallback, MatchExpressionParser::AllowedFeatureSet allowedFeatures) { auto qrStatus = qr->validate(); if (!qrStatus.isOK()) { return qrStatus; } std::unique_ptr<CollatorInterface> collator; if (!qr->getCollation().isEmpty()) { auto statusWithCollator = CollatorFactoryInterface::get(opCtx->getServiceContext()) ->makeFromBSON(qr->getCollation()); if (!statusWithCollator.isOK()) { return statusWithCollator.getStatus(); } collator = std::move(statusWithCollator.getValue()); } // Make MatchExpression. boost::intrusive_ptr<ExpressionContext> newExpCtx; if (!expCtx.get()) { newExpCtx.reset(new ExpressionContext(opCtx, collator.get())); } else { newExpCtx = expCtx; invariant(CollatorInterface::collatorsMatch(collator.get(), expCtx->getCollator())); } StatusWithMatchExpression statusWithMatcher = MatchExpressionParser::parse( qr->getFilter(), newExpCtx, extensionsCallback, allowedFeatures); if (!statusWithMatcher.isOK()) { return statusWithMatcher.getStatus(); } std::unique_ptr<MatchExpression> me = std::move(statusWithMatcher.getValue()); // Make the CQ we'll hopefully return. std::unique_ptr<CanonicalQuery> cq(new CanonicalQuery()); Status initStatus = cq->init(opCtx, std::move(qr), parsingCanProduceNoopMatchNodes(extensionsCallback, allowedFeatures), std::move(me), std::move(collator)); if (!initStatus.isOK()) { return initStatus; } return std::move(cq); }
Status PullNode::init(BSONElement modExpr, const boost::intrusive_ptr<ExpressionContext>& expCtx) { invariant(modExpr.ok()); try { if (modExpr.type() == mongo::Object && !MatchExpressionParser::parsePathAcceptingKeyword( modExpr.embeddedObject().firstElement())) { _matcher = stdx::make_unique<ObjectMatcher>(modExpr.embeddedObject(), expCtx); } else if (modExpr.type() == mongo::Object || modExpr.type() == mongo::RegEx) { _matcher = stdx::make_unique<WrappedObjectMatcher>(modExpr, expCtx); } else { _matcher = stdx::make_unique<EqualityMatcher>(modExpr, expCtx->getCollator()); } } catch (AssertionException& exception) { return exception.toStatus(); } return Status::OK(); }