diff options
| author | Lucas de Castro Borges <lucas@gnuabordo.com.br> | 2025-02-11 15:07:35 -0300 |
|---|---|---|
| committer | Lucas de Castro Borges <lucas@gnuabordo.com.br> | 2025-02-11 15:07:35 -0300 |
| commit | 4cb8841196d0625dfa3825aa326f071cd27c7b8b (patch) | |
| tree | 1682a647d4463397c119183369ae6f750d5fdcff /src/mongo/db/query/projection_ast_util.cpp | |
| parent | aa03c6362cbaa767638e6eed9b031d86dd2643d1 (diff) | |
| parent | 8f0827553e09872941945a093b647a4211a9db7f (diff) | |
Update upstream source from tag 'upstream/6.0.0'master
Update to upstream version '6.0.0'
with Debian dir 5604a80ec1c96ca76f25f40d78e6ef855abec322
Diffstat (limited to 'src/mongo/db/query/projection_ast_util.cpp')
| -rw-r--r-- | src/mongo/db/query/projection_ast_util.cpp | 156 |
1 files changed, 38 insertions, 118 deletions
diff --git a/src/mongo/db/query/projection_ast_util.cpp b/src/mongo/db/query/projection_ast_util.cpp index 23c7b6d9582..e5b4cc1a9c4 100644 --- a/src/mongo/db/query/projection_ast_util.cpp +++ b/src/mongo/db/query/projection_ast_util.cpp @@ -29,26 +29,28 @@ #include "mongo/platform/basic.h" -#include "mongo/db/query/projection_ast_path_tracking_visitor.h" #include "mongo/db/query/projection_ast_util.h" -#include "mongo/db/query/query_shape/serialization_options.h" + +#include "mongo/db/query/projection_ast_path_tracking_visitor.h" #include "mongo/db/query/tree_walker.h" namespace mongo::projection_ast { namespace { struct BSONVisitorContext { std::stack<BSONObjBuilder> builders; - bool underElemMatch = false; }; class BSONPreVisitor : public ProjectionASTConstVisitor { public: - using ProjectionASTConstVisitor::visit; - BSONPreVisitor(PathTrackingVisitorContext<BSONVisitorContext>* context, - SerializationOptions options) - : _context(context), _builders(context->data().builders), _options(std::move(options)) {} + BSONPreVisitor(PathTrackingVisitorContext<BSONVisitorContext>* context) + : _context(context), _builders(context->data().builders) {} + + virtual void visit(const MatchExpressionASTNode* node) { + static_cast<const MatchExpressionASTNode*>(node)->matchExpression()->serialize( + &_builders.top(), true); + } - void visit(const ProjectionPathASTNode* node) override { + virtual void visit(const ProjectionPathASTNode* node) { if (!node->parent()) { // No root of the tree, thus this node has no field name. _builders.push(BSONObjBuilder()); @@ -57,46 +59,47 @@ public: } } - void visit(const ProjectionSliceASTNode* node) override { + virtual void visit(const ProjectionPositionalASTNode* node) { + // ProjectionPositional always has the original query's match expression node as its + // child. Serialize as: {"positional.projection.field.$": <original match expression>}. + _context->data().builders.push(_builders.top().subobjStart(getFieldName() + ".$")); + } + + virtual void visit(const ProjectionSliceASTNode* node) { BSONObjBuilder sub(_builders.top().subobjStart(getFieldName())); if (node->skip()) { - sub.appendArray("$slice", - BSON_ARRAY(_options.serializeLiteral(*node->skip()) - << _options.serializeLiteral(node->limit()))); + sub.appendArray("$slice", BSON_ARRAY(*node->skip() << node->limit())); } else { - _options.appendLiteral(&sub, "$slice", node->limit()); + sub.appendNumber("$slice", node->limit()); } } + virtual void visit(const ProjectionElemMatchASTNode* node) { + // Defer to the child, match expression node. + } - void visit(const ExpressionASTNode* node) override { - node->expression()->serialize(_options).addToBsonObj(&_builders.top(), getFieldName()); + virtual void visit(const ExpressionASTNode* node) { + node->expression()->serialize(false).addToBsonObj(&_builders.top(), getFieldName()); } - void visit(const BooleanConstantASTNode* node) override { + virtual void visit(const BooleanConstantASTNode* node) { _builders.top().append(getFieldName(), node->value()); } - void visit(const ProjectionPositionalASTNode* node) override = 0; - void visit(const ProjectionElemMatchASTNode* node) override = 0; - void visit(const MatchExpressionASTNode* node) override = 0; - -protected: +private: std::string getFieldName() { - return _options.serializeFieldPathFromString(_context->childPath()); + return _context->childPath(); } PathTrackingVisitorContext<BSONVisitorContext>* _context; std::stack<BSONObjBuilder>& _builders; - SerializationOptions _options; }; class BSONPostVisitor : public ProjectionASTConstVisitor { public: - using ProjectionASTConstVisitor::visit; BSONPostVisitor(BSONVisitorContext* context) : _context(context) {} - void visit(const ProjectionPathASTNode* node) override { + virtual void visit(const ProjectionPathASTNode* node) { // Don't pop the top builder. if (node->parent()) { // Pop the BSONObjBuilder that was added in the pre visitor. @@ -104,97 +107,25 @@ public: } } - void visit(const ProjectionSliceASTNode* node) override {} - void visit(const ExpressionASTNode* node) override {} - void visit(const BooleanConstantASTNode* node) override {} - void visit(const MatchExpressionASTNode* node) override {} - - void visit(const ProjectionPositionalASTNode* node) override = 0; - void visit(const ProjectionElemMatchASTNode* node) override = 0; - -protected: - BSONVisitorContext* _context; -}; - -class DebugPreVisitor : public BSONPreVisitor { -public: - using BSONPreVisitor::visit; - DebugPreVisitor(PathTrackingVisitorContext<BSONVisitorContext>* context) - : BSONPreVisitor(context, SerializationOptions{}) {} - - void visit(const ProjectionPositionalASTNode* node) override { - // ProjectionPositional always has the original query's match expression node as its - // child. Serialize as: {"positional.projection.field.$": <original match expression>}. - _context->data().builders.push(_builders.top().subobjStart(getFieldName() + ".$")); - } - - void visit(const ProjectionElemMatchASTNode* node) override { - // Defer to the child, match expression node. - } - - void visit(const MatchExpressionASTNode* node) override { - static_cast<const MatchExpressionASTNode*>(node)->matchExpression()->serialize( - &_builders.top(), {}); - } -}; - -class DebugPostVisitor : public BSONPostVisitor { -public: - using BSONPostVisitor::visit; - DebugPostVisitor(BSONVisitorContext* context) : BSONPostVisitor(context) {} - - void visit(const ProjectionPositionalASTNode* node) override { + virtual void visit(const ProjectionPositionalASTNode* node) { _context->builders.pop(); } - void visit(const ProjectionElemMatchASTNode* node) override {} -}; + virtual void visit(const MatchExpressionASTNode* node) {} + virtual void visit(const ProjectionSliceASTNode* node) {} + virtual void visit(const ProjectionElemMatchASTNode* node) {} + virtual void visit(const ExpressionASTNode* node) {} + virtual void visit(const BooleanConstantASTNode* node) {} -class SerializationPreVisitor : public BSONPreVisitor { -public: - using BSONPreVisitor::visit; - SerializationPreVisitor(PathTrackingVisitorContext<BSONVisitorContext>* context, - const SerializationOptions& options) - : BSONPreVisitor(context, options) {} - - void visit(const ProjectionPositionalASTNode* node) override { - tassert(73488, - "Positional projection should not appear below an $elemMatch projection.", - !_context->data().underElemMatch); - _builders.top().append(getFieldName() + ".$", true); - } - - void visit(const ProjectionElemMatchASTNode* node) override { - // The child match expression node should begin with $elemMatch. - _context->data().underElemMatch = true; - } - - void visit(const MatchExpressionASTNode* node) override { - if (_context->data().underElemMatch) { - static_cast<const MatchExpressionASTNode*>(node)->matchExpression()->serialize( - &_builders.top(), _options); - } - } -}; - -class SerializationPostVisitor : public BSONPostVisitor { -public: - using BSONPostVisitor::visit; - SerializationPostVisitor(BSONVisitorContext* context) : BSONPostVisitor(context) {} - - void visit(const ProjectionPositionalASTNode* node) override {} - void visit(const ProjectionElemMatchASTNode* node) override { - _context->underElemMatch = false; - } +private: + BSONVisitorContext* _context; }; - } // namespace BSONObj astToDebugBSON(const ASTNode* root) { PathTrackingVisitorContext<BSONVisitorContext> context; - DebugPreVisitor preVisitor{&context}; - DebugPostVisitor postVisitor{&context.data()}; - + BSONPreVisitor preVisitor{&context}; + BSONPostVisitor postVisitor{&context.data()}; PathTrackingWalker walker{&context, {&preVisitor}, {&postVisitor}}; tree_walker::walk<true, projection_ast::ASTNode>(root, &walker); @@ -202,15 +133,4 @@ BSONObj astToDebugBSON(const ASTNode* root) { invariant(context.data().builders.size() == 1); return context.data().builders.top().obj(); } - -BSONObj serialize(const ProjectionPathASTNode& root, const SerializationOptions& options) { - PathTrackingVisitorContext<BSONVisitorContext> context; - SerializationPreVisitor preVisitor{&context, options}; - SerializationPostVisitor postVisitor{&context.data()}; - PathTrackingWalker walker{&context, {&preVisitor}, {&postVisitor}}; - tree_walker::walk<true, projection_ast::ASTNode>(&root, &walker); - - invariant(context.data().builders.size() == 1); - return context.data().builders.top().obj(); -} } // namespace mongo::projection_ast |
