diff options
Diffstat (limited to 'src/mongo/db/cst/grammar.yy')
-rw-r--r-- | src/mongo/db/cst/grammar.yy | 157 |
1 files changed, 134 insertions, 23 deletions
diff --git a/src/mongo/db/cst/grammar.yy b/src/mongo/db/cst/grammar.yy index 8b86c8e850c..3f14fcbe00d 100644 --- a/src/mongo/db/cst/grammar.yy +++ b/src/mongo/db/cst/grammar.yy @@ -126,11 +126,13 @@ ALL_ELEMENTS_TRUE "allElementsTrue" AND ANY_ELEMENT_TRUE "anyElementTrue" + ARG_CASE_SENSITIVE "$caseSensitive argument" ARG_CHARS "chars argument" ARG_COLL "coll argument" ARG_DATE "date argument" ARG_DATE_STRING "dateString argument" ARG_DAY "day argument" + ARG_DIACRITIC_SENSITIVE "$diacriticSensitive argument" ARG_FILTER "filter" ARG_FIND "find argument" ARG_FORMAT "format argument" @@ -140,6 +142,7 @@ ARG_ISO_DAY_OF_WEEK "ISO day of week argument" ARG_ISO_WEEK "ISO week argument" ARG_ISO_WEEK_YEAR "ISO week year argument" + ARG_LANGUAGE "$language argument" ARG_MILLISECOND "millisecond argument" ARG_MINUTE "minute argument" ARG_MONTH "month argument" @@ -149,21 +152,22 @@ ARG_PIPELINE "pipeline argument" ARG_REGEX "regex argument" ARG_REPLACEMENT "replacement argument" + ARG_SEARCH "$search argument" ARG_SECOND "second argument" ARG_SIZE "size argument" ARG_TIMEZONE "timezone argument" ARG_TO "to argument" + ARG_YEAR "year argument" ASIN ASINH ATAN - ARG_YEAR "year argument" ATAN2 ATANH BOOL_FALSE "false" BOOL_TRUE "true" CEIL - COMMENT CMP + COMMENT CONCAT CONST_EXPR CONVERT @@ -184,12 +188,13 @@ DOUBLE_NEGATIVE_ONE "-1 (double)" DOUBLE_ONE "1 (double)" DOUBLE_ZERO "zero (double)" + ELEM_MATCH "elemMatch operator" END_ARRAY "end of array" END_OBJECT "end of object" - ELEM_MATCH "elemMatch operator" EQ EXISTS EXPONENT + EXPR FLOOR GEO_NEAR_DISTANCE "geoNearDistance" GEO_NEAR_POINT "geoNearPoint" @@ -197,9 +202,9 @@ GTE HOUR ID + INDEX_KEY "indexKey" INDEX_OF_BYTES INDEX_OF_CP - INDEX_KEY "indexKey" INT_NEGATIVE_ONE "-1 (int)" INT_ONE "1 (int)" INT_ZERO "zero (int)" @@ -245,14 +250,15 @@ SET_INTERSECTION "setIntersection" SET_IS_SUBSET "setIsSubset" SET_UNION "setUnion" - SLICE "slice" - SORT_KEY "sortKey" SIN SINH + SLICE "slice" + SORT_KEY "sortKey" SPLIT SQRT STAGE_INHIBIT_OPTIMIZATION STAGE_LIMIT + STAGE_MATCH STAGE_PROJECT STAGE_SAMPLE STAGE_SKIP @@ -268,6 +274,7 @@ SUBTRACT TAN TANH + TEXT TEXT_SCORE "textScore" TO_BOOL TO_DATE @@ -283,6 +290,7 @@ TRUNC TYPE WEEK + WHERE YEAR END_OF_FILE 0 "EOF" @@ -334,7 +342,7 @@ %nterm <CNode> typeArray typeValue // Pipeline stages and related non-terminals. -%nterm <CNode> pipeline stageList stage inhibitOptimization unionWith skip limit project sample +%nterm <CNode> pipeline stageList stage inhibitOptimization unionWith skip limit matchStage project sample %nterm <CNode> aggregationProjectFields aggregationProjectionObjectFields %nterm <CNode> topLevelAggregationProjection aggregationProjection projectionCommon %nterm <CNode> aggregationProjectionObject num @@ -365,11 +373,15 @@ %nterm <CNode> aggregationOperatorWithoutSlice expressionSingletonArray singleArgExpression %nterm <CNode> nonArrayNonObjExpression // Match expressions. -%nterm <CNode> match predicates compoundMatchExprs predValue additionalExprs -%nterm <std::pair<CNode::Fieldname, CNode>> predicate logicalExpr operatorExpression notExpr +%nterm <CNode> matchExpression predicates compoundMatchExprs predValue additionalExprs +%nterm <std::pair<CNode::Fieldname, CNode>> predicate fieldPredicate logicalExpr operatorExpression notExpr matchMod %nterm <std::pair<CNode::Fieldname, CNode>> existsExpr typeExpr commentExpr %nterm <CNode::Fieldname> logicalExprField %nterm <std::vector<CNode>> typeValues +%nterm <std::pair<CNode::Fieldname, CNode>> matchExpr matchText matchWhere + +// $text arguments +%nterm <CNode> textArgCaseSensitive textArgDiacriticSensitive textArgLanguage textArgSearch // Find Projection specific rules. %nterm <CNode> findProject findProjectFields topLevelFindProjection findProjection @@ -393,8 +405,8 @@ start: START_PIPELINE pipeline { *cst = $pipeline; } - | START_MATCH match { - *cst = $match; + | START_MATCH matchExpression { + *cst = $matchExpression; } | START_PROJECT findProject { *cst = $findProject; @@ -424,7 +436,7 @@ stageList: START_ORDERED_OBJECT: START_OBJECT { lexer.sortObjTokens(); }; stage: - inhibitOptimization | unionWith | skip | limit | project | sample + inhibitOptimization | unionWith | skip | limit | matchStage | project | sample ; sample: STAGE_SAMPLE START_OBJECT ARG_SIZE num END_OBJECT { @@ -466,6 +478,12 @@ limit: $$ = CNode{CNode::ObjectChildren{std::pair{KeyFieldname::limit, $num}}}; }; +matchStage: + STAGE_MATCH matchExpression { + $$ = CNode{CNode::ObjectChildren{std::pair{KeyFieldname::match, $matchExpression}}}; + } +; + project: STAGE_PROJECT START_OBJECT aggregationProjectFields END_OBJECT { auto&& fields = $aggregationProjectFields; @@ -661,7 +679,7 @@ aggregationProjectionObjectField: } ; -match: +matchExpression: START_OBJECT predicates END_OBJECT { $$ = $predicates; } @@ -677,11 +695,20 @@ predicates: } ; -predicate: predFieldname predValue { +predicate: + fieldPredicate + | commentExpr + + // pathless match operators + | logicalExpr + | matchExpr + | matchText + | matchWhere +; + +fieldPredicate: predFieldname predValue { $$ = {$predFieldname, $predValue}; } - | logicalExpr - | commentExpr ; // TODO SERVER-48847: This rule assumes that object predicates always contain sub-expressions. @@ -706,7 +733,7 @@ compoundMatchExprs: // Rules for the operators which act on a path. operatorExpression: - notExpr | existsExpr | typeExpr + notExpr | existsExpr | typeExpr | matchMod ; existsExpr: @@ -772,11 +799,20 @@ notExpr: } ; +matchMod: + MOD START_ARRAY num[divisor] num[remainder] END_ARRAY { + $$ = {KeyFieldname::matchMod, CNode{CNode::ArrayChildren{ + $divisor, + $remainder, + }}}; + } +; + // Logical expressions accept an array of objects, with at least one element. 'additionalExprs' // comes before 'match' to allow us to naturally emplace_back() into the CST. -logicalExpr: logicalExprField START_ARRAY additionalExprs match END_ARRAY { +logicalExpr: logicalExprField START_ARRAY additionalExprs matchExpression END_ARRAY { auto&& children = $additionalExprs; - children.arrayChildren().emplace_back($match); + children.arrayChildren().emplace_back($matchExpression); $$ = {$logicalExprField, std::move(children)}; } ; @@ -790,9 +826,9 @@ additionalExprs: %empty { $$ = CNode{CNode::ArrayChildren{}}; } - | additionalExprs[exprs] match { + | additionalExprs[exprs] matchExpression { $$ = $exprs; - $$.arrayChildren().emplace_back($match); + $$.arrayChildren().emplace_back($matchExpression); } ; @@ -805,6 +841,66 @@ invariableUserFieldname: } ; +matchExpr: + EXPR expression { + $$ = {KeyFieldname::expr, $expression}; + } +; + +matchText: + TEXT START_ORDERED_OBJECT + textArgCaseSensitive + textArgDiacriticSensitive + textArgLanguage + textArgSearch + END_OBJECT + { + $$ = { + KeyFieldname::text, + CNode{CNode::ObjectChildren{ + {KeyFieldname::caseSensitive, $textArgCaseSensitive}, + {KeyFieldname::diacriticSensitive, $textArgDiacriticSensitive}, + {KeyFieldname::language, $textArgLanguage}, + {KeyFieldname::search, $textArgSearch}, + } + }}; + } +; +textArgCaseSensitive: + %empty { + $$ = CNode{KeyValue::absentKey}; + } + | ARG_CASE_SENSITIVE bool[val] { + $$ = $val; + } +; +textArgDiacriticSensitive: + %empty { + $$ = CNode{KeyValue::absentKey}; + } + | ARG_DIACRITIC_SENSITIVE bool[val] { + $$ = $val; + } +; +textArgLanguage: + %empty { + $$ = CNode{KeyValue::absentKey}; + } + | ARG_LANGUAGE string[val] { + $$ = $val; + } +; +textArgSearch: + ARG_SEARCH string[val] { + $$ = $val; + } +; + +matchWhere: + WHERE string { $$ = {KeyFieldname::where, $string}; } + | WHERE javascript { $$ = {KeyFieldname::where, $javascript}; } +; + stageAsUserFieldname: // Here we need to list all agg stage keys so they can be converted back to string in contexts // where they're not special. It's laborious but this is the perennial Bison way. @@ -820,6 +916,9 @@ stageAsUserFieldname: | STAGE_LIMIT { $$ = UserFieldname{"$limit"}; } + | STAGE_MATCH { + $$ = UserFieldname{"$match"}; + } | STAGE_PROJECT { $$ = UserFieldname{"$project"}; } @@ -932,6 +1031,18 @@ arg: | ARG_MONTH { $$ = UserFieldname{"month"}; } + | ARG_SEARCH { + $$ = UserFieldname{"$search"}; + } + | ARG_LANGUAGE { + $$ = UserFieldname{"$language"}; + } + | ARG_CASE_SENSITIVE { + $$ = UserFieldname{"$caseSensitive"}; + } + | ARG_DIACRITIC_SENSITIVE { + $$ = UserFieldname{"$diacriticSensitive"}; + } ; aggExprAsUserFieldname: @@ -2497,8 +2608,8 @@ findProjection: ; elemMatch: - START_OBJECT ELEM_MATCH match END_OBJECT { - $$ = {CNode::ObjectChildren{{KeyFieldname::elemMatch, $match}}}; + START_OBJECT ELEM_MATCH matchExpression END_OBJECT { + $$ = {CNode::ObjectChildren{{KeyFieldname::elemMatch, $matchExpression}}}; } ; |