diff options
author | Ribhav Jain <ribhav.jain@mongodb.com> | 2020-07-17 15:57:46 +0000 |
---|---|---|
committer | Evergreen Agent <no-reply@evergreen.mongodb.com> | 2020-07-20 15:29:32 +0000 |
commit | 4123eb7e7fde047ca1f1b396712d41a3de8a89f1 (patch) | |
tree | ee00a5699d758c04720d7ad35040765046bfbe4f /src/mongo/db/cst | |
parent | b7b91adc3a0e5f6e70231fdbcebcf11554cc1cb6 (diff) | |
download | mongo-4123eb7e7fde047ca1f1b396712d41a3de8a89f1.tar.gz |
SERVER-48840 Implemented skip in Grammar
Diffstat (limited to 'src/mongo/db/cst')
-rw-r--r-- | src/mongo/db/cst/bson_lexer.cpp | 1 | ||||
-rw-r--r-- | src/mongo/db/cst/cst_pipeline_translation.cpp | 31 | ||||
-rw-r--r-- | src/mongo/db/cst/cst_pipeline_translation_test.cpp | 40 | ||||
-rw-r--r-- | src/mongo/db/cst/cst_test.cpp | 52 | ||||
-rw-r--r-- | src/mongo/db/cst/key_fieldname.h | 4 | ||||
-rw-r--r-- | src/mongo/db/cst/location_gen.h | 18 | ||||
-rw-r--r-- | src/mongo/db/cst/pipeline_grammar.yy | 22 | ||||
-rw-r--r-- | src/mongo/db/cst/pipeline_parser_gen.cpp | 247 | ||||
-rw-r--r-- | src/mongo/db/cst/pipeline_parser_gen.hpp | 192 |
9 files changed, 411 insertions, 196 deletions
diff --git a/src/mongo/db/cst/bson_lexer.cpp b/src/mongo/db/cst/bson_lexer.cpp index 0f15a7eccef..d1766c780e1 100644 --- a/src/mongo/db/cst/bson_lexer.cpp +++ b/src/mongo/db/cst/bson_lexer.cpp @@ -44,6 +44,7 @@ const StringMap<PipelineParserGen::token_type> reservedKeyLookup = { {"$unionWith", PipelineParserGen::token::STAGE_UNION_WITH}, {"coll", PipelineParserGen::token::COLL_ARG}, {"pipeline", PipelineParserGen::token::PIPELINE_ARG}, + {"$skip", PipelineParserGen::token::STAGE_SKIP}, }; bool isCompound(PipelineParserGen::symbol_type token) { return token.type_get() == static_cast<int>(PipelineParserGen::token::START_OBJECT) || diff --git a/src/mongo/db/cst/cst_pipeline_translation.cpp b/src/mongo/db/cst/cst_pipeline_translation.cpp index 85602fe5d64..4b39ef388a7 100644 --- a/src/mongo/db/cst/cst_pipeline_translation.cpp +++ b/src/mongo/db/cst/cst_pipeline_translation.cpp @@ -39,6 +39,7 @@ #include "mongo/db/exec/inclusion_projection_executor.h" #include "mongo/db/pipeline/document_source.h" #include "mongo/db/pipeline/document_source_project.h" +#include "mongo/db/pipeline/document_source_skip.h" #include "mongo/db/pipeline/expression_context.h" #include "mongo/db/query/projection.h" #include "mongo/db/query/projection_ast.h" @@ -81,12 +82,40 @@ auto translateProject(const CNode& cst, const boost::intrusive_ptr<ExpressionCon } /** + * Cast a CNode payload to a UserLong. + */ +auto translateNumToLong(const CNode& cst) { + return stdx::visit( + visit_helper::Overloaded{ + [](const UserDouble& userDouble) { + return (BSON("" << userDouble).firstElement()).safeNumberLong(); + }, + [](const UserInt& userInt) { + return (BSON("" << userInt).firstElement()).safeNumberLong(); + }, + [](const UserLong& userLong) { return userLong; }, + [](auto &&) -> UserLong { MONGO_UNREACHABLE }}, + cst.payload); +} + +/** + * Walk a skip stage object CNode and produce a DocumentSourceSkip. + */ +auto translateSkip(const CNode& cst, const boost::intrusive_ptr<ExpressionContext>& expCtx) { + UserLong nToSkip = translateNumToLong(cst); + return DocumentSourceSkip::create(expCtx, nToSkip); +} + +/** * Walk an aggregation pipeline stage object CNode and produce a DocumentSource. */ -auto translateSource(const CNode& cst, const boost::intrusive_ptr<ExpressionContext>& expCtx) { +boost::intrusive_ptr<DocumentSource> translateSource( + const CNode& cst, const boost::intrusive_ptr<ExpressionContext>& expCtx) { switch (cst.firstKeyFieldname()) { case KeyFieldname::project: return translateProject(cst.objectChildren()[0].second, expCtx); + case KeyFieldname::skip: + return translateSkip(cst.objectChildren()[0].second, expCtx); default: MONGO_UNREACHABLE; } diff --git a/src/mongo/db/cst/cst_pipeline_translation_test.cpp b/src/mongo/db/cst/cst_pipeline_translation_test.cpp index bfcc11ef12d..90152227f91 100644 --- a/src/mongo/db/cst/cst_pipeline_translation_test.cpp +++ b/src/mongo/db/cst/cst_pipeline_translation_test.cpp @@ -42,6 +42,7 @@ #include "mongo/db/exec/document_value/document.h" #include "mongo/db/namespace_string.h" #include "mongo/db/pipeline/document_source_single_document_transformation.h" +#include "mongo/db/pipeline/document_source_skip.h" #include "mongo/db/pipeline/expression_context_for_test.h" #include "mongo/unittest/unittest.h" @@ -166,5 +167,44 @@ TEST(CstTest, TranslatesMultipleInclusionProjectionStages) { } } +TEST(CstTest, TranslatesSkipWithInt) { + auto nss = NamespaceString{"db", "coll"}; + const auto cst = CNode{CNode::ArrayChildren{ + CNode{CNode::ObjectChildren{{KeyFieldname::skip, CNode{UserInt{5}}}}}}}; + boost::intrusive_ptr<ExpressionContextForTest> expCtx(new ExpressionContextForTest(nss)); + auto pipeline = cst_pipeline_translation::translatePipeline(cst, expCtx); + auto& sources = pipeline->getSources(); + ASSERT_EQ(1u, sources.size()); + auto iter = sources.begin(); + ASSERT(typeid(DocumentSourceSkip) == typeid(**iter)); + ASSERT_EQ((dynamic_cast<DocumentSourceSkip&>(**iter).getSkip()), 5ll); +} + +TEST(CstTest, TranslatesSkipWithDouble) { + auto nss = NamespaceString{"db", "coll"}; + const auto cst = CNode{CNode::ArrayChildren{ + CNode{CNode::ObjectChildren{{KeyFieldname::skip, CNode{UserDouble{5.5}}}}}}}; + boost::intrusive_ptr<ExpressionContextForTest> expCtx(new ExpressionContextForTest(nss)); + auto pipeline = cst_pipeline_translation::translatePipeline(cst, expCtx); + auto& sources = pipeline->getSources(); + ASSERT_EQ(1u, sources.size()); + auto iter = sources.begin(); + ASSERT(typeid(DocumentSourceSkip) == typeid(**iter)); + ASSERT_EQ((dynamic_cast<DocumentSourceSkip&>(**iter).getSkip()), 5ll); +} + +TEST(CstTest, TranslatesSkipWithLong) { + auto nss = NamespaceString{"db", "coll"}; + const auto cst = CNode{CNode::ArrayChildren{ + CNode{CNode::ObjectChildren{{KeyFieldname::skip, CNode{UserLong{8223372036854775807}}}}}}}; + boost::intrusive_ptr<ExpressionContextForTest> expCtx(new ExpressionContextForTest(nss)); + auto pipeline = cst_pipeline_translation::translatePipeline(cst, expCtx); + auto& sources = pipeline->getSources(); + ASSERT_EQ(1u, sources.size()); + auto iter = sources.begin(); + ASSERT(typeid(DocumentSourceSkip) == typeid(**iter)); + ASSERT_EQ((dynamic_cast<DocumentSourceSkip&>(**iter).getSkip()), 8223372036854775807); +} + } // namespace } // namespace mongo diff --git a/src/mongo/db/cst/cst_test.cpp b/src/mongo/db/cst/cst_test.cpp index 02111f28ab4..97dbf6ebc0c 100644 --- a/src/mongo/db/cst/cst_test.cpp +++ b/src/mongo/db/cst/cst_test.cpp @@ -146,5 +146,57 @@ TEST(CstGrammarTest, ParsesUnionWith) { } } +TEST(CstGrammarTest, ParseSkipInt) { + CNode output; + auto input = fromjson("{pipeline: [{$skip: 5}]}"); + BSONLexer lexer(input["pipeline"].Array()); + auto parseTree = PipelineParserGen(lexer, &output); + ASSERT_EQ(0, parseTree.parse()); + auto stages = stdx::get<CNode::ArrayChildren>(output.payload); + ASSERT_EQ(1, stages.size()); + ASSERT(KeyFieldname::skip == stages[0].firstKeyFieldname()); + ASSERT_BSONOBJ_EQ(fromjson("{skip : \"<UserInt 5>\" }"), stages[0].toBson()); +} + +TEST(CstGrammarTest, ParseSkipDouble) { + CNode output; + auto input = fromjson("{pipeline: [{$skip: 1.5}]}"); + BSONLexer lexer(input["pipeline"].Array()); + auto parseTree = PipelineParserGen(lexer, &output); + ASSERT_EQ(0, parseTree.parse()); + auto stages = stdx::get<CNode::ArrayChildren>(output.payload); + ASSERT_EQ(1, stages.size()); + ASSERT(KeyFieldname::skip == stages[0].firstKeyFieldname()); + ASSERT_BSONOBJ_EQ(fromjson("{skip : \"<UserDouble 1.500000>\" }"), stages[0].toBson()); +} + +TEST(CstGrammarTest, ParseSkipLong) { + CNode output; + auto input = fromjson("{pipeline: [{$skip: 8223372036854775807}]}"); + BSONLexer lexer(input["pipeline"].Array()); + auto parseTree = PipelineParserGen(lexer, &output); + ASSERT_EQ(0, parseTree.parse()); + auto stages = stdx::get<CNode::ArrayChildren>(output.payload); + ASSERT_EQ(1, stages.size()); + ASSERT(KeyFieldname::skip == stages[0].firstKeyFieldname()); + ASSERT_BSONOBJ_EQ(fromjson("{skip : \"<UserLong 8223372036854775807>\" }"), stages[0].toBson()); +} + +TEST(CstGrammarTest, InvalidParseSkipObject) { + CNode output; + auto input = fromjson("{pipeline: [{$skip: {}}]}"); + BSONLexer lexer(input["pipeline"].Array()); + auto parseTree = PipelineParserGen(lexer, &output); + ASSERT_THROWS_CODE(parseTree.parse(), AssertionException, ErrorCodes::FailedToParse); +} + +TEST(CstGrammarTest, InvalidParseSkipString) { + CNode output; + auto input = fromjson("{pipeline: [{$skip: '5'}]}"); + BSONLexer lexer(input["pipeline"].Array()); + auto parseTree = PipelineParserGen(lexer, &output); + ASSERT_THROWS_CODE(parseTree.parse(), AssertionException, ErrorCodes::FailedToParse); +} + } // namespace } // namespace mongo diff --git a/src/mongo/db/cst/key_fieldname.h b/src/mongo/db/cst/key_fieldname.h index 37bcd6b7650..e6c36bf49be 100644 --- a/src/mongo/db/cst/key_fieldname.h +++ b/src/mongo/db/cst/key_fieldname.h @@ -40,7 +40,9 @@ ENUMIFY(inhibitOptimization) \ ENUMIFY(unionWith) \ ENUMIFY(collArg) \ - ENUMIFY(pipelineArg) + ENUMIFY(pipelineArg) \ + ENUMIFY(limit) \ + ENUMIFY(skip) MAKE_PRINTABLE_ENUM(KeyFieldname, KEYFIELDNAMES); MAKE_PRINTABLE_ENUM_STRING_ARRAY(key_fieldname, KeyFieldname, KEYFIELDNAMES); diff --git a/src/mongo/db/cst/location_gen.h b/src/mongo/db/cst/location_gen.h index c1a0c8cac32..3849efc00c0 100644 --- a/src/mongo/db/cst/location_gen.h +++ b/src/mongo/db/cst/location_gen.h @@ -1,4 +1,4 @@ -// A Bison parser, made by GNU Bison 3.6.3. +// A Bison parser, made by GNU Bison 3.6. // Locations for Bison parsers in C++ @@ -31,12 +31,12 @@ // version 2.2 of Bison. /** - ** \file location_gen.h + ** \file src/mongo/db/cst/location_gen.h ** Define the mongo::location class. */ -#ifndef YY_YY_LOCATION_GEN_H_INCLUDED -#define YY_YY_LOCATION_GEN_H_INCLUDED +#ifndef YY_YY_SRC_MONGO_DB_CST_LOCATION_GEN_H_INCLUDED +#define YY_YY_SRC_MONGO_DB_CST_LOCATION_GEN_H_INCLUDED #include <iostream> #include <string> @@ -53,9 +53,9 @@ #endif #endif -#line 52 "pipeline_grammar.yy" +#line 52 "src/mongo/db/cst/pipeline_grammar.yy" namespace mongo { -#line 59 "location_gen.h" +#line 59 "src/mongo/db/cst/location_gen.h" /// A point in a source file. class position { @@ -260,8 +260,8 @@ std::basic_ostream<YYChar>& operator<<(std::basic_ostream<YYChar>& ostr, const l return ostr; } -#line 52 "pipeline_grammar.yy" +#line 52 "src/mongo/db/cst/pipeline_grammar.yy" } // namespace mongo -#line 333 "location_gen.h" +#line 333 "src/mongo/db/cst/location_gen.h" -#endif // !YY_YY_LOCATION_GEN_H_INCLUDED +#endif // !YY_YY_SRC_MONGO_DB_CST_LOCATION_GEN_H_INCLUDED diff --git a/src/mongo/db/cst/pipeline_grammar.yy b/src/mongo/db/cst/pipeline_grammar.yy index 8ef7dc65d97..9d6a1bbe906 100644 --- a/src/mongo/db/cst/pipeline_grammar.yy +++ b/src/mongo/db/cst/pipeline_grammar.yy @@ -108,6 +108,7 @@ // Reserve pipeline stage names. STAGE_INHIBIT_OPTIMIZATION STAGE_UNION_WITH + STAGE_SKIP // $unionWith arguments. COLL_ARG @@ -125,7 +126,7 @@ // // Semantic values (aka the C++ types produced by the actions). // -%nterm <CNode> stageList stage inhibitOptimization unionWith +%nterm <CNode> stageList stage inhibitOptimization unionWith num skip // // Grammar rules @@ -150,7 +151,7 @@ stageList[result]: START_ORDERED_OBJECT: { lexer.sortObjTokens(); } START_OBJECT; stage: - inhibitOptimization | unionWith + inhibitOptimization | unionWith | skip ; inhibitOptimization: @@ -170,4 +171,21 @@ unionWith: }}}}}; }; +num: + NUMBER_INT { + $num = CNode{UserInt($NUMBER_INT)}; + } + | NUMBER_LONG { + $num = CNode{UserLong($NUMBER_LONG)}; + } + | NUMBER_DOUBLE { + $num = CNode{UserDouble($NUMBER_DOUBLE)}; + } +; + +skip: + STAGE_SKIP num { + $skip = CNode{CNode::ObjectChildren{std::pair{KeyFieldname::skip, $num}}}; +}; + %% diff --git a/src/mongo/db/cst/pipeline_parser_gen.cpp b/src/mongo/db/cst/pipeline_parser_gen.cpp index 261d4510841..159de24c602 100644 --- a/src/mongo/db/cst/pipeline_parser_gen.cpp +++ b/src/mongo/db/cst/pipeline_parser_gen.cpp @@ -1,4 +1,4 @@ -// A Bison parser, made by GNU Bison 3.6.3. +// A Bison parser, made by GNU Bison 3.6. // Skeleton implementation for Bison LALR(1) parsers in C++ @@ -39,7 +39,7 @@ // Unqualified %code blocks. -#line 77 "pipeline_grammar.yy" +#line 77 "src/mongo/db/cst/pipeline_grammar.yy" #include "mongo/db/cst/bson_lexer.h" @@ -53,7 +53,7 @@ void PipelineParserGen::error(const PipelineParserGen::location_type& loc, const } } // namespace mongo -#line 62 "pipeline_parser_gen.cpp" +#line 62 "src/mongo/db/cst/pipeline_parser_gen.cpp" #ifndef YY_ @@ -144,9 +144,16 @@ void PipelineParserGen::error(const PipelineParserGen::location_type& loc, const #define YYERROR goto yyerrorlab #define YYRECOVERING() (!!yyerrstatus_) -#line 52 "pipeline_grammar.yy" +#line 52 "src/mongo/db/cst/pipeline_grammar.yy" namespace mongo { -#line 155 "pipeline_parser_gen.cpp" +#line 155 "src/mongo/db/cst/pipeline_parser_gen.cpp" + +#if YYDEBUG || 0 +const char* PipelineParserGen::symbol_name(symbol_kind_type yysymbol) { + return yytname_[yysymbol]; +} +#endif // #if YYDEBUG || 0 + /// Build a parser object. PipelineParserGen::PipelineParserGen(BSONLexer& lexer_yyarg, CNode* cst_yyarg) @@ -197,30 +204,32 @@ PipelineParserGen::stack_symbol_type::stack_symbol_type() {} PipelineParserGen::stack_symbol_type::stack_symbol_type(YY_RVREF(stack_symbol_type) that) : super_type(YY_MOVE(that.state), YY_MOVE(that.location)) { switch (that.kind()) { - case 17: // stageList - case 18: // stage - case 19: // inhibitOptimization - case 20: // unionWith + case 18: // stageList + case 19: // stage + case 20: // inhibitOptimization + case 21: // unionWith + case 22: // num + case 23: // skip value.YY_MOVE_OR_COPY<CNode>(YY_MOVE(that.value)); break; - case 15: // BOOL + case 16: // BOOL value.YY_MOVE_OR_COPY<bool>(YY_MOVE(that.value)); break; - case 14: // NUMBER_DOUBLE + case 15: // NUMBER_DOUBLE value.YY_MOVE_OR_COPY<double>(YY_MOVE(that.value)); break; - case 12: // NUMBER_INT + case 13: // NUMBER_INT value.YY_MOVE_OR_COPY<int>(YY_MOVE(that.value)); break; - case 13: // NUMBER_LONG + case 14: // NUMBER_LONG value.YY_MOVE_OR_COPY<long long>(YY_MOVE(that.value)); break; - case 11: // STRING + case 12: // STRING value.YY_MOVE_OR_COPY<std::string>(YY_MOVE(that.value)); break; @@ -237,30 +246,32 @@ PipelineParserGen::stack_symbol_type::stack_symbol_type(YY_RVREF(stack_symbol_ty PipelineParserGen::stack_symbol_type::stack_symbol_type(state_type s, YY_MOVE_REF(symbol_type) that) : super_type(s, YY_MOVE(that.location)) { switch (that.kind()) { - case 17: // stageList - case 18: // stage - case 19: // inhibitOptimization - case 20: // unionWith + case 18: // stageList + case 19: // stage + case 20: // inhibitOptimization + case 21: // unionWith + case 22: // num + case 23: // skip value.move<CNode>(YY_MOVE(that.value)); break; - case 15: // BOOL + case 16: // BOOL value.move<bool>(YY_MOVE(that.value)); break; - case 14: // NUMBER_DOUBLE + case 15: // NUMBER_DOUBLE value.move<double>(YY_MOVE(that.value)); break; - case 12: // NUMBER_INT + case 13: // NUMBER_INT value.move<int>(YY_MOVE(that.value)); break; - case 13: // NUMBER_LONG + case 14: // NUMBER_LONG value.move<long long>(YY_MOVE(that.value)); break; - case 11: // STRING + case 12: // STRING value.move<std::string>(YY_MOVE(that.value)); break; @@ -277,30 +288,32 @@ PipelineParserGen::stack_symbol_type& PipelineParserGen::stack_symbol_type::oper const stack_symbol_type& that) { state = that.state; switch (that.kind()) { - case 17: // stageList - case 18: // stage - case 19: // inhibitOptimization - case 20: // unionWith + case 18: // stageList + case 19: // stage + case 20: // inhibitOptimization + case 21: // unionWith + case 22: // num + case 23: // skip value.copy<CNode>(that.value); break; - case 15: // BOOL + case 16: // BOOL value.copy<bool>(that.value); break; - case 14: // NUMBER_DOUBLE + case 15: // NUMBER_DOUBLE value.copy<double>(that.value); break; - case 12: // NUMBER_INT + case 13: // NUMBER_INT value.copy<int>(that.value); break; - case 13: // NUMBER_LONG + case 14: // NUMBER_LONG value.copy<long long>(that.value); break; - case 11: // STRING + case 12: // STRING value.copy<std::string>(that.value); break; @@ -316,30 +329,32 @@ PipelineParserGen::stack_symbol_type& PipelineParserGen::stack_symbol_type::oper stack_symbol_type& that) { state = that.state; switch (that.kind()) { - case 17: // stageList - case 18: // stage - case 19: // inhibitOptimization - case 20: // unionWith + case 18: // stageList + case 19: // stage + case 20: // inhibitOptimization + case 21: // unionWith + case 22: // num + case 23: // skip value.move<CNode>(that.value); break; - case 15: // BOOL + case 16: // BOOL value.move<bool>(that.value); break; - case 14: // NUMBER_DOUBLE + case 15: // NUMBER_DOUBLE value.move<double>(that.value); break; - case 12: // NUMBER_INT + case 13: // NUMBER_INT value.move<int>(that.value); break; - case 13: // NUMBER_LONG + case 14: // NUMBER_LONG value.move<long long>(that.value); break; - case 11: // STRING + case 12: // STRING value.move<std::string>(that.value); break; @@ -369,7 +384,7 @@ void PipelineParserGen::yy_print_(std::ostream& yyo, const basic_symbol<Base>& y yyo << "empty symbol"; else { symbol_kind_type yykind = yysym.kind(); - yyo << (yykind < YYNTOKENS ? "token" : "nterm") << ' ' << yysym.name() << " (" + yyo << (yykind < YYNTOKENS ? "token" : "nterm") << ' ' << symbol_name(yykind) << " (" << yysym.location << ": "; YYUSE(yykind); yyo << ')'; @@ -566,30 +581,32 @@ int PipelineParserGen::parse() { correct type. The default '$$ = $1' action is NOT applied when using variants. */ switch (yyr1_[yyn]) { - case 17: // stageList - case 18: // stage - case 19: // inhibitOptimization - case 20: // unionWith + case 18: // stageList + case 19: // stage + case 20: // inhibitOptimization + case 21: // unionWith + case 22: // num + case 23: // skip yylhs.value.emplace<CNode>(); break; - case 15: // BOOL + case 16: // BOOL yylhs.value.emplace<bool>(); break; - case 14: // NUMBER_DOUBLE + case 15: // NUMBER_DOUBLE yylhs.value.emplace<double>(); break; - case 12: // NUMBER_INT + case 13: // NUMBER_INT yylhs.value.emplace<int>(); break; - case 13: // NUMBER_LONG + case 14: // NUMBER_LONG yylhs.value.emplace<long long>(); break; - case 11: // STRING + case 12: // STRING yylhs.value.emplace<std::string>(); break; @@ -613,64 +630,72 @@ int PipelineParserGen::parse() { { switch (yyn) { case 2: -#line 136 "pipeline_grammar.yy" +#line 137 "src/mongo/db/cst/pipeline_grammar.yy" { *cst = std::move(yystack_[1].value.as<CNode>()); } -#line 687 "pipeline_parser_gen.cpp" +#line 706 "src/mongo/db/cst/pipeline_parser_gen.cpp" break; case 3: -#line 141 "pipeline_grammar.yy" +#line 142 "src/mongo/db/cst/pipeline_grammar.yy" { } -#line 693 "pipeline_parser_gen.cpp" +#line 712 "src/mongo/db/cst/pipeline_parser_gen.cpp" break; case 4: -#line 142 "pipeline_grammar.yy" +#line 143 "src/mongo/db/cst/pipeline_grammar.yy" { yylhs.value.as<CNode>() = CNode{CNode::ArrayChildren{yystack_[2].value.as<CNode>()}}; } -#line 701 "pipeline_parser_gen.cpp" +#line 720 "src/mongo/db/cst/pipeline_parser_gen.cpp" break; case 5: -#line 150 "pipeline_grammar.yy" +#line 151 "src/mongo/db/cst/pipeline_grammar.yy" { lexer.sortObjTokens(); } -#line 707 "pipeline_parser_gen.cpp" +#line 726 "src/mongo/db/cst/pipeline_parser_gen.cpp" break; case 7: -#line 153 "pipeline_grammar.yy" +#line 154 "src/mongo/db/cst/pipeline_grammar.yy" { yylhs.value.as<CNode>() = yystack_[0].value.as<CNode>(); } -#line 713 "pipeline_parser_gen.cpp" +#line 732 "src/mongo/db/cst/pipeline_parser_gen.cpp" break; case 8: -#line 153 "pipeline_grammar.yy" +#line 154 "src/mongo/db/cst/pipeline_grammar.yy" { yylhs.value.as<CNode>() = yystack_[0].value.as<CNode>(); } -#line 719 "pipeline_parser_gen.cpp" +#line 738 "src/mongo/db/cst/pipeline_parser_gen.cpp" break; case 9: -#line 157 "pipeline_grammar.yy" +#line 154 "src/mongo/db/cst/pipeline_grammar.yy" + { + yylhs.value.as<CNode>() = yystack_[0].value.as<CNode>(); + } +#line 744 "src/mongo/db/cst/pipeline_parser_gen.cpp" + break; + + case 10: +#line 158 "src/mongo/db/cst/pipeline_grammar.yy" { yylhs.value.as<CNode>() = CNode{CNode::ObjectChildren{ std::pair{KeyFieldname::inhibitOptimization, CNode::noopLeaf()}}}; } -#line 728 "pipeline_parser_gen.cpp" +#line 753 "src/mongo/db/cst/pipeline_parser_gen.cpp" break; - case 10: -#line 163 "pipeline_grammar.yy" + case 11: +#line 164 "src/mongo/db/cst/pipeline_grammar.yy" { auto coll = CNode{UserString(yystack_[3].value.as<std::string>())}; auto pipeline = CNode{UserDouble(yystack_[1].value.as<double>())}; @@ -680,11 +705,45 @@ int PipelineParserGen::parse() { {KeyFieldname::collArg, std::move(coll)}, {KeyFieldname::pipelineArg, std::move(pipeline)}}}}}}; } -#line 742 "pipeline_parser_gen.cpp" +#line 767 "src/mongo/db/cst/pipeline_parser_gen.cpp" + break; + + case 12: +#line 175 "src/mongo/db/cst/pipeline_grammar.yy" + { + yylhs.value.as<CNode>() = CNode{UserInt(yystack_[0].value.as<int>())}; + } +#line 775 "src/mongo/db/cst/pipeline_parser_gen.cpp" + break; + + case 13: +#line 178 "src/mongo/db/cst/pipeline_grammar.yy" + { + yylhs.value.as<CNode>() = + CNode{UserLong(yystack_[0].value.as<long long>())}; + } +#line 783 "src/mongo/db/cst/pipeline_parser_gen.cpp" break; + case 14: +#line 181 "src/mongo/db/cst/pipeline_grammar.yy" + { + yylhs.value.as<CNode>() = CNode{UserDouble(yystack_[0].value.as<double>())}; + } +#line 791 "src/mongo/db/cst/pipeline_parser_gen.cpp" + break; -#line 746 "pipeline_parser_gen.cpp" + case 15: +#line 187 "src/mongo/db/cst/pipeline_grammar.yy" + { + yylhs.value.as<CNode>() = CNode{CNode::ObjectChildren{ + std::pair{KeyFieldname::skip, yystack_[0].value.as<CNode>()}}}; + } +#line 799 "src/mongo/db/cst/pipeline_parser_gen.cpp" + break; + + +#line 803 "src/mongo/db/cst/pipeline_parser_gen.cpp" default: break; @@ -848,39 +907,36 @@ void PipelineParserGen::error(const syntax_error& yyexc) { error(yyexc.location, yyexc.what()); } -#if YYDEBUG || 0 -const char* PipelineParserGen::symbol_name(symbol_kind_type yysymbol) { - return yytname_[yysymbol]; -} -#endif // #if YYDEBUG || 0 - -const signed char PipelineParserGen::yypact_ninf_ = -8; +const signed char PipelineParserGen::yypact_ninf_ = -11; const signed char PipelineParserGen::yytable_ninf_ = -1; -const signed char PipelineParserGen::yypact_[] = {-3, 0, 4, -7, -1, -8, 3, -8, 5, -8, -8, -8, - 6, -2, 8, 0, -8, 1, -8, -8, 7, -6, 9, -8}; +const signed char PipelineParserGen::yypact_[] = {1, 4, 8, -7, 3, -11, 7, -11, -10, 9, + -11, -11, -11, -11, 10, 2, 12, -11, -11, -11, + -11, 4, -11, -1, -11, -11, 5, 6, 13, -11}; -const signed char PipelineParserGen::yydefact_[] = {0, 3, 0, 0, 0, 1, 0, 5, 0, 7, 8, 2, - 0, 0, 0, 3, 9, 0, 6, 4, 0, 0, 0, 10}; +const signed char PipelineParserGen::yydefact_[] = { + 0, 3, 0, 0, 0, 1, 0, 5, 0, 0, 7, 8, 9, 2, 0, 0, 0, 12, 13, 14, 15, 3, 10, 0, 6, 4, 0, 0, 0, 11}; -const signed char PipelineParserGen::yypgoto_[] = {-8, 10, -8, -8, -8, -8, -8, -8}; +const signed char PipelineParserGen::yypgoto_[] = {-11, -3, -11, -11, -11, -11, -11, -11, -11, -11}; -const signed char PipelineParserGen::yydefgoto_[] = {-1, 4, 8, 9, 10, 2, 13, 14}; +const signed char PipelineParserGen::yydefgoto_[] = {-1, 4, 9, 10, 11, 20, 12, 2, 15, 16}; -const signed char PipelineParserGen::yytable_[] = {6, 7, 1, 3, 5, 11, 12, 17, 22, 15, 16, 18, 20, - 23, 0, 0, 0, 21, 0, 0, 0, 0, 0, 0, 0, 19}; +const signed char PipelineParserGen::yytable_[] = {6, 7, 8, 17, 18, 19, 1, 3, 5, 13, 14, + 26, 23, 21, 22, 24, 27, 29, 25, 0, 0, 28}; -const signed char PipelineParserGen::yycheck_[] = { - 7, 8, 5, 3, 0, 6, 3, 9, 14, 4, 4, 3, 11, 4, -1, -1, -1, 10, -1, -1, -1, -1, -1, -1, -1, 15}; +const signed char PipelineParserGen::yycheck_[] = {7, 8, 9, 13, 14, 15, 5, 3, 0, 6, 3, + 12, 10, 4, 4, 3, 11, 4, 21, -1, -1, 15}; -const signed char PipelineParserGen::yystos_[] = {0, 5, 21, 3, 17, 0, 7, 8, 18, 19, 20, 6, - 3, 22, 23, 4, 4, 9, 3, 17, 11, 10, 14, 4}; +const signed char PipelineParserGen::yystos_[] = {0, 5, 24, 3, 18, 0, 7, 8, 9, 19, + 20, 21, 23, 6, 3, 25, 26, 13, 14, 15, + 22, 4, 4, 10, 3, 18, 12, 11, 15, 4}; -const signed char PipelineParserGen::yyr1_[] = {0, 16, 21, 17, 17, 23, 22, 18, 18, 19, 20}; +const signed char PipelineParserGen::yyr1_[] = { + 0, 17, 24, 18, 18, 26, 25, 19, 19, 19, 20, 21, 22, 22, 22, 23}; -const signed char PipelineParserGen::yyr2_[] = {0, 2, 3, 0, 4, 0, 2, 1, 1, 3, 7}; +const signed char PipelineParserGen::yyr2_[] = {0, 2, 3, 0, 4, 0, 2, 1, 1, 1, 3, 7, 1, 1, 1, 2}; #if YYDEBUG @@ -895,6 +951,7 @@ const char* const PipelineParserGen::yytname_[] = {"\"EOF\"", "END_ARRAY", "STAGE_INHIBIT_OPTIMIZATION", "STAGE_UNION_WITH", + "STAGE_SKIP", "COLL_ARG", "PIPELINE_ARG", "STRING", @@ -907,6 +964,8 @@ const char* const PipelineParserGen::yytname_[] = {"\"EOF\"", "stage", "inhibitOptimization", "unionWith", + "num", + "skip", "pipeline", "START_ORDERED_OBJECT", "$@1", @@ -916,7 +975,7 @@ const char* const PipelineParserGen::yytname_[] = {"\"EOF\"", #if YYDEBUG const unsigned char PipelineParserGen::yyrline_[] = { - 0, 136, 136, 141, 142, 150, 150, 153, 153, 157, 163}; + 0, 137, 137, 142, 143, 151, 151, 154, 154, 154, 158, 164, 175, 178, 181, 187}; void PipelineParserGen::yy_stack_print_() const { *yycdebug_ << "Stack now"; @@ -937,8 +996,8 @@ void PipelineParserGen::yy_reduce_print_(int yyrule) const { #endif // YYDEBUG -#line 52 "pipeline_grammar.yy" +#line 52 "src/mongo/db/cst/pipeline_grammar.yy" } // namespace mongo -#line 1060 "pipeline_parser_gen.cpp" +#line 1106 "src/mongo/db/cst/pipeline_parser_gen.cpp" -#line 173 "pipeline_grammar.yy" +#line 191 "src/mongo/db/cst/pipeline_grammar.yy" diff --git a/src/mongo/db/cst/pipeline_parser_gen.hpp b/src/mongo/db/cst/pipeline_parser_gen.hpp index 8e9787090f0..4c1a36754c0 100644 --- a/src/mongo/db/cst/pipeline_parser_gen.hpp +++ b/src/mongo/db/cst/pipeline_parser_gen.hpp @@ -1,4 +1,4 @@ -// A Bison parser, made by GNU Bison 3.6.3. +// A Bison parser, made by GNU Bison 3.6. // Skeleton interface for Bison LALR(1) parsers in C++ @@ -32,7 +32,7 @@ /** - ** \file pipeline_parser_gen.hpp + ** \file src/mongo/db/cst/pipeline_parser_gen.hpp ** Define the mongo::parser class. */ @@ -42,10 +42,10 @@ // especially those whose name start with YY_ or yy_. They are // private implementation details that can be changed or removed. -#ifndef YY_YY_PIPELINE_PARSER_GEN_HPP_INCLUDED -#define YY_YY_PIPELINE_PARSER_GEN_HPP_INCLUDED +#ifndef YY_YY_SRC_MONGO_DB_CST_PIPELINE_PARSER_GEN_HPP_INCLUDED +#define YY_YY_SRC_MONGO_DB_CST_PIPELINE_PARSER_GEN_HPP_INCLUDED // "%code requires" blocks. -#line 60 "pipeline_grammar.yy" +#line 60 "src/mongo/db/cst/pipeline_grammar.yy" #include "mongo/db/cst/c_node.h" #include "mongo/db/cst/key_fieldname.h" @@ -61,7 +61,7 @@ class BSONLexer; #pragma warning(disable : 4065) #endif -#line 65 "pipeline_parser_gen.hpp" +#line 65 "src/mongo/db/cst/pipeline_parser_gen.hpp" #include <cassert> #include <cstdlib> // std::abort @@ -190,9 +190,9 @@ class BSONLexer; #define YYDEBUG 0 #endif -#line 52 "pipeline_grammar.yy" +#line 52 "src/mongo/db/cst/pipeline_grammar.yy" namespace mongo { -#line 200 "pipeline_parser_gen.hpp" +#line 200 "src/mongo/db/cst/pipeline_parser_gen.hpp" /// A Bison parser. @@ -371,6 +371,8 @@ public: // stage // inhibitOptimization // unionWith + // num + // skip char dummy1[sizeof(CNode)]; // BOOL @@ -435,13 +437,14 @@ public: END_ARRAY = 6, // END_ARRAY STAGE_INHIBIT_OPTIMIZATION = 7, // STAGE_INHIBIT_OPTIMIZATION STAGE_UNION_WITH = 8, // STAGE_UNION_WITH - COLL_ARG = 9, // COLL_ARG - PIPELINE_ARG = 10, // PIPELINE_ARG - STRING = 11, // STRING - NUMBER_INT = 12, // NUMBER_INT - NUMBER_LONG = 13, // NUMBER_LONG - NUMBER_DOUBLE = 14, // NUMBER_DOUBLE - BOOL = 15 // BOOL + STAGE_SKIP = 9, // STAGE_SKIP + COLL_ARG = 10, // COLL_ARG + PIPELINE_ARG = 11, // PIPELINE_ARG + STRING = 12, // STRING + NUMBER_INT = 13, // NUMBER_INT + NUMBER_LONG = 14, // NUMBER_LONG + NUMBER_DOUBLE = 15, // NUMBER_DOUBLE + BOOL = 16 // BOOL }; /// Backward compatibility alias (Bison 3.6). typedef token_kind_type yytokentype; @@ -456,7 +459,7 @@ public: /// Symbol kinds. struct symbol_kind { enum symbol_kind_type { - YYNTOKENS = 16, ///< Number of tokens. + YYNTOKENS = 17, ///< Number of tokens. S_YYEMPTY = -2, S_YYEOF = 0, // "EOF" S_YYerror = 1, // error @@ -467,21 +470,24 @@ public: S_END_ARRAY = 6, // END_ARRAY S_STAGE_INHIBIT_OPTIMIZATION = 7, // STAGE_INHIBIT_OPTIMIZATION S_STAGE_UNION_WITH = 8, // STAGE_UNION_WITH - S_COLL_ARG = 9, // COLL_ARG - S_PIPELINE_ARG = 10, // PIPELINE_ARG - S_STRING = 11, // STRING - S_NUMBER_INT = 12, // NUMBER_INT - S_NUMBER_LONG = 13, // NUMBER_LONG - S_NUMBER_DOUBLE = 14, // NUMBER_DOUBLE - S_BOOL = 15, // BOOL - S_YYACCEPT = 16, // $accept - S_stageList = 17, // stageList - S_stage = 18, // stage - S_inhibitOptimization = 19, // inhibitOptimization - S_unionWith = 20, // unionWith - S_pipeline = 21, // pipeline - S_START_ORDERED_OBJECT = 22, // START_ORDERED_OBJECT - S_23_1 = 23 // $@1 + S_STAGE_SKIP = 9, // STAGE_SKIP + S_COLL_ARG = 10, // COLL_ARG + S_PIPELINE_ARG = 11, // PIPELINE_ARG + S_STRING = 12, // STRING + S_NUMBER_INT = 13, // NUMBER_INT + S_NUMBER_LONG = 14, // NUMBER_LONG + S_NUMBER_DOUBLE = 15, // NUMBER_DOUBLE + S_BOOL = 16, // BOOL + S_YYACCEPT = 17, // $accept + S_stageList = 18, // stageList + S_stage = 19, // stage + S_inhibitOptimization = 20, // inhibitOptimization + S_unionWith = 21, // unionWith + S_num = 22, // num + S_skip = 23, // skip + S_pipeline = 24, // pipeline + S_START_ORDERED_OBJECT = 25, // START_ORDERED_OBJECT + S_26_1 = 26 // $@1 }; }; @@ -510,30 +516,32 @@ public: basic_symbol(basic_symbol&& that) : Base(std::move(that)), value(), location(std::move(that.location)) { switch (this->kind()) { - case 17: // stageList - case 18: // stage - case 19: // inhibitOptimization - case 20: // unionWith + case 18: // stageList + case 19: // stage + case 20: // inhibitOptimization + case 21: // unionWith + case 22: // num + case 23: // skip value.move<CNode>(std::move(that.value)); break; - case 15: // BOOL + case 16: // BOOL value.move<bool>(std::move(that.value)); break; - case 14: // NUMBER_DOUBLE + case 15: // NUMBER_DOUBLE value.move<double>(std::move(that.value)); break; - case 12: // NUMBER_INT + case 13: // NUMBER_INT value.move<int>(std::move(that.value)); break; - case 13: // NUMBER_LONG + case 14: // NUMBER_LONG value.move<long long>(std::move(that.value)); break; - case 11: // STRING + case 12: // STRING value.move<std::string>(std::move(that.value)); break; @@ -614,30 +622,32 @@ public: // Value type destructor. switch (yykind) { - case 17: // stageList - case 18: // stage - case 19: // inhibitOptimization - case 20: // unionWith + case 18: // stageList + case 19: // stage + case 20: // inhibitOptimization + case 21: // unionWith + case 22: // num + case 23: // skip value.template destroy<CNode>(); break; - case 15: // BOOL + case 16: // BOOL value.template destroy<bool>(); break; - case 14: // NUMBER_DOUBLE + case 15: // NUMBER_DOUBLE value.template destroy<double>(); break; - case 12: // NUMBER_INT + case 13: // NUMBER_INT value.template destroy<int>(); break; - case 13: // NUMBER_LONG + case 14: // NUMBER_LONG value.template destroy<long long>(); break; - case 11: // STRING + case 12: // STRING value.template destroy<std::string>(); break; @@ -648,14 +658,6 @@ public: Base::clear(); } -#if YYDEBUG || 0 - /// The user-facing name of this symbol. - const char* name() const YY_NOEXCEPT { - return PipelineParserGen::symbol_name(this->kind()); - } -#endif // #if YYDEBUG || 0 - - /// Backward compatibility (Bison 3.6). symbol_kind_type type_get() const YY_NOEXCEPT; @@ -733,7 +735,8 @@ public: tok == token::START_OBJECT || tok == token::END_OBJECT || tok == token::START_ARRAY || tok == token::END_ARRAY || tok == token::STAGE_INHIBIT_OPTIMIZATION || tok == token::STAGE_UNION_WITH || - tok == token::COLL_ARG || tok == token::PIPELINE_ARG); + tok == token::STAGE_SKIP || tok == token::COLL_ARG || + tok == token::PIPELINE_ARG); } #else symbol_type(int tok, const location_type& l) : super_type(token_type(tok), l) { @@ -741,7 +744,8 @@ public: tok == token::START_OBJECT || tok == token::END_OBJECT || tok == token::START_ARRAY || tok == token::END_ARRAY || tok == token::STAGE_INHIBIT_OPTIMIZATION || tok == token::STAGE_UNION_WITH || - tok == token::COLL_ARG || tok == token::PIPELINE_ARG); + tok == token::STAGE_SKIP || tok == token::COLL_ARG || + tok == token::PIPELINE_ARG); } #endif #if 201103L <= YY_CPLUSPLUS @@ -842,13 +846,6 @@ public: /// Report a syntax error. void error(const syntax_error& err); -#if YYDEBUG || 0 - /// The user-facing name of the symbol whose (internal) number is - /// YYSYMBOL. No bounds checking. - static const char* symbol_name(symbol_kind_type yysymbol); -#endif // #if YYDEBUG || 0 - - // Implementation of make_symbol for each symbol type. #if 201103L <= YY_CPLUSPLUS static symbol_type make_END_OF_FILE(location_type l) { @@ -932,6 +929,15 @@ public: } #endif #if 201103L <= YY_CPLUSPLUS + static symbol_type make_STAGE_SKIP(location_type l) { + return symbol_type(token::STAGE_SKIP, std::move(l)); + } +#else + static symbol_type make_STAGE_SKIP(const location_type& l) { + return symbol_type(token::STAGE_SKIP, l); + } +#endif +#if 201103L <= YY_CPLUSPLUS static symbol_type make_COLL_ARG(location_type l) { return symbol_type(token::COLL_ARG, std::move(l)); } @@ -1030,6 +1036,10 @@ private: static symbol_kind_type yytranslate_(int t); #if YYDEBUG || 0 + /// The user-facing name of the symbol whose (internal) number is + /// YYSYMBOL. No bounds checking. + static const char* symbol_name(symbol_kind_type yysymbol); + /// For a symbol, its name in clear. static const char* const yytname_[]; #endif // #if YYDEBUG || 0 @@ -1270,8 +1280,8 @@ private: /// Constants. enum { - yylast_ = 25, ///< Last index in yytable_. - yynnts_ = 8, ///< Number of nonterminal symbols. + yylast_ = 21, ///< Last index in yytable_. + yynnts_ = 10, ///< Number of nonterminal symbols. yyfinal_ = 5 ///< Termination state number. }; @@ -1290,30 +1300,32 @@ template <typename Base> PipelineParserGen::basic_symbol<Base>::basic_symbol(const basic_symbol& that) : Base(that), value(), location(that.location) { switch (this->kind()) { - case 17: // stageList - case 18: // stage - case 19: // inhibitOptimization - case 20: // unionWith + case 18: // stageList + case 19: // stage + case 20: // inhibitOptimization + case 21: // unionWith + case 22: // num + case 23: // skip value.copy<CNode>(YY_MOVE(that.value)); break; - case 15: // BOOL + case 16: // BOOL value.copy<bool>(YY_MOVE(that.value)); break; - case 14: // NUMBER_DOUBLE + case 15: // NUMBER_DOUBLE value.copy<double>(YY_MOVE(that.value)); break; - case 12: // NUMBER_INT + case 13: // NUMBER_INT value.copy<int>(YY_MOVE(that.value)); break; - case 13: // NUMBER_LONG + case 14: // NUMBER_LONG value.copy<long long>(YY_MOVE(that.value)); break; - case 11: // STRING + case 12: // STRING value.copy<std::string>(YY_MOVE(that.value)); break; @@ -1338,30 +1350,32 @@ template <typename Base> void PipelineParserGen::basic_symbol<Base>::move(basic_symbol& s) { super_type::move(s); switch (this->kind()) { - case 17: // stageList - case 18: // stage - case 19: // inhibitOptimization - case 20: // unionWith + case 18: // stageList + case 19: // stage + case 20: // inhibitOptimization + case 21: // unionWith + case 22: // num + case 23: // skip value.move<CNode>(YY_MOVE(s.value)); break; - case 15: // BOOL + case 16: // BOOL value.move<bool>(YY_MOVE(s.value)); break; - case 14: // NUMBER_DOUBLE + case 15: // NUMBER_DOUBLE value.move<double>(YY_MOVE(s.value)); break; - case 12: // NUMBER_INT + case 13: // NUMBER_INT value.move<int>(YY_MOVE(s.value)); break; - case 13: // NUMBER_LONG + case 14: // NUMBER_LONG value.move<long long>(YY_MOVE(s.value)); break; - case 11: // STRING + case 12: // STRING value.move<std::string>(YY_MOVE(s.value)); break; @@ -1403,9 +1417,9 @@ inline PipelineParserGen::symbol_kind_type PipelineParserGen::by_kind::type_get( return this->kind(); } -#line 52 "pipeline_grammar.yy" +#line 52 "src/mongo/db/cst/pipeline_grammar.yy" } // namespace mongo -#line 1689 "pipeline_parser_gen.hpp" +#line 1705 "src/mongo/db/cst/pipeline_parser_gen.hpp" -#endif // !YY_YY_PIPELINE_PARSER_GEN_HPP_INCLUDED +#endif // !YY_YY_SRC_MONGO_DB_CST_PIPELINE_PARSER_GEN_HPP_INCLUDED |