summaryrefslogtreecommitdiff
path: root/src/mongo/db/query/projection_ast_util.cpp
diff options
context:
space:
mode:
authorLucas de Castro Borges <lucas@gnuabordo.com.br>2025-02-11 15:07:35 -0300
committerLucas de Castro Borges <lucas@gnuabordo.com.br>2025-02-11 15:07:35 -0300
commit4cb8841196d0625dfa3825aa326f071cd27c7b8b (patch)
tree1682a647d4463397c119183369ae6f750d5fdcff /src/mongo/db/query/projection_ast_util.cpp
parentaa03c6362cbaa767638e6eed9b031d86dd2643d1 (diff)
parent8f0827553e09872941945a093b647a4211a9db7f (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.cpp156
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