summaryrefslogtreecommitdiff
path: root/src/mongo/db/cst/pipeline_grammar.yy
diff options
context:
space:
mode:
Diffstat (limited to 'src/mongo/db/cst/pipeline_grammar.yy')
-rw-r--r--src/mongo/db/cst/pipeline_grammar.yy47
1 files changed, 36 insertions, 11 deletions
diff --git a/src/mongo/db/cst/pipeline_grammar.yy b/src/mongo/db/cst/pipeline_grammar.yy
index 9616e113443..8ef7dc65d97 100644
--- a/src/mongo/db/cst/pipeline_grammar.yy
+++ b/src/mongo/db/cst/pipeline_grammar.yy
@@ -81,13 +81,17 @@
// Mandatory error function.
void PipelineParserGen::error (const PipelineParserGen::location_type& loc,
const std::string& msg) {
- std::cerr << msg << " at loc " << loc << std::endl;
+ uasserted(ErrorCodes::FailedToParse, str::stream() << msg <<
+ " at location " <<
+ loc.begin.line << ":" << loc.begin.column <<
+ " of input BSON. Lexer produced token of type " <<
+ lexer[loc.begin.column].type_get() << "." );
}
} // namespace mongo
}
// Parsing parameters, funneled through yyparse() to yylex().
-%param {BSONLexer& driver}
+%param {BSONLexer& lexer}
// yyparse() parameter only.
%parse-param {CNode* cst}
@@ -98,13 +102,16 @@
%token
START_OBJECT
END_OBJECT
- START_ORDERED_OBJECT
- END_ORDERED_OBJECT
START_ARRAY
END_ARRAY
// Reserve pipeline stage names.
STAGE_INHIBIT_OPTIMIZATION
+ STAGE_UNION_WITH
+
+ // $unionWith arguments.
+ COLL_ARG
+ PIPELINE_ARG
END_OF_FILE 0 "EOF"
;
@@ -118,7 +125,7 @@
//
// Semantic values (aka the C++ types produced by the actions).
//
-%nterm <CNode> stageList stage
+%nterm <CNode> stageList stage inhibitOptimization unionWith
//
// Grammar rules
@@ -133,16 +140,34 @@ pipeline: START_ARRAY stageList END_ARRAY {
stageList[result]:
%empty { }
| START_OBJECT stage END_OBJECT stageList[stagesArg] {
- $result = std::move($stagesArg);
- auto& children = stdx::get<CNode::ArrayChildren>($result.payload);
- children.emplace_back(std::move($stage));
+ $result = CNode{CNode::ArrayChildren{$stage}};
}
;
+// Special rule to hint to the lexer that the next set of tokens should be sorted. Note that the
+// sort order is not lexicographical, but rather based on the enum generated from the %token list
+// above.
+START_ORDERED_OBJECT: { lexer.sortObjTokens(); } START_OBJECT;
+
stage:
- STAGE_INHIBIT_OPTIMIZATION START_OBJECT END_OBJECT {
- $stage = CNode{CNode::ObjectChildren{std::pair{KeyFieldname::inhibitOptimization, CNode::noopLeaf()}}};
- }
+ inhibitOptimization | unionWith
;
+inhibitOptimization:
+ STAGE_INHIBIT_OPTIMIZATION START_OBJECT END_OBJECT {
+ $inhibitOptimization =
+CNode{CNode::ObjectChildren{std::pair{KeyFieldname::inhibitOptimization, CNode::noopLeaf()}}};
+ };
+
+unionWith:
+ STAGE_UNION_WITH START_ORDERED_OBJECT COLL_ARG STRING PIPELINE_ARG NUMBER_DOUBLE END_OBJECT {
+ auto coll = CNode{UserString($STRING)};
+ auto pipeline = CNode{UserDouble($NUMBER_DOUBLE)};
+ $unionWith = CNode{CNode::ObjectChildren{std::pair{KeyFieldname::unionWith,
+ CNode{CNode::ObjectChildren{
+ {KeyFieldname::collArg, std::move(coll)},
+ {KeyFieldname::pipelineArg, std::move(pipeline)}
+ }}}}};
+};
+
%%