diff --git a/Installation/travisCI/script.sh b/Installation/travisCI/script.sh index 93a8ee5405..e74978c762 100755 --- a/Installation/travisCI/script.sh +++ b/Installation/travisCI/script.sh @@ -8,7 +8,6 @@ make setup || exit 1 echo echo "$0: configuring ArangoDB" # V8 needs lib realtime: -export LDFLAGS='-lrt -pthread' ./configure \ --enable-relative \ --enable-all-in-one-libev \ diff --git a/Makefile.am b/Makefile.am index 752239ebc1..f3b94799f3 100644 --- a/Makefile.am +++ b/Makefile.am @@ -140,6 +140,7 @@ AM_LDFLAGS = \ ################################################################################ LIBS = \ + @RT_LIBS@ \ @LIBEV_LIBS@ \ @MATH_LIBS@ \ @OPENSSL_LIBS@ \ diff --git a/UnitTests/Makefile.unittests b/UnitTests/Makefile.unittests index 519df410f1..2618fadba5 100755 --- a/UnitTests/Makefile.unittests +++ b/UnitTests/Makefile.unittests @@ -555,6 +555,7 @@ SHELL_SERVER_AQL = @top_srcdir@/js/server/tests/aql-arithmetic.js \ @top_srcdir@/js/server/tests/aql-modify-noncluster.js \ @top_srcdir@/js/server/tests/aql-modify-noncluster-serializetest.js \ @top_srcdir@/js/server/tests/aql-operators.js \ + @top_srcdir@/js/server/tests/aql-optimizer-collect-into.js \ @top_srcdir@/js/server/tests/aql-optimizer-count.js \ @top_srcdir@/js/server/tests/aql-optimizer-dynamic-bounds.js \ @top_srcdir@/js/server/tests/aql-optimizer-filters.js \ diff --git a/arangod/Aql/AqlValue.cpp b/arangod/Aql/AqlValue.cpp index 736b6a54e6..1616d8719c 100644 --- a/arangod/Aql/AqlValue.cpp +++ b/arangod/Aql/AqlValue.cpp @@ -786,6 +786,33 @@ AqlValue AqlValue::CreateFromBlocks (triagens::arango::AqlTransaction* trx, return AqlValue(json.release()); } +//////////////////////////////////////////////////////////////////////////////// +/// @brief create an AqlValue from a vector of AqlItemBlock*s +//////////////////////////////////////////////////////////////////////////////// + +AqlValue AqlValue::CreateFromBlocks (triagens::arango::AqlTransaction* trx, + std::vector const& src, + triagens::aql::RegisterId expressionRegister) { + size_t totalSize = 0; + + for (auto it = src.begin(); it != src.end(); ++it) { + totalSize += (*it)->size(); + } + + std::unique_ptr json(new Json(Json::List, totalSize)); + + for (auto it = src.begin(); it != src.end(); ++it) { + auto current = (*it); + auto document = current->getDocumentCollection(expressionRegister); + + for (size_t i = 0; i < current->size(); ++i) { + json->add(current->getValueReference(i, expressionRegister).toJson(trx, document)); + } + } + + return AqlValue(json.release()); +} + //////////////////////////////////////////////////////////////////////////////// /// @brief 3-way comparison for AqlValue objects //////////////////////////////////////////////////////////////////////////////// diff --git a/arangod/Aql/AqlValue.h b/arangod/Aql/AqlValue.h index de004eef78..a44d9ffd5f 100644 --- a/arangod/Aql/AqlValue.h +++ b/arangod/Aql/AqlValue.h @@ -30,6 +30,7 @@ #include "Basics/Common.h" #include "Aql/Range.h" +#include "Aql/types.h" #include "Basics/JsonHelper.h" #include "Utils/V8TransactionContext.h" #include "Utils/AqlTransaction.h" @@ -257,6 +258,14 @@ namespace triagens { std::vector const&, std::vector const&); +//////////////////////////////////////////////////////////////////////////////// +/// @brief create an AqlValue from a vector of AqlItemBlock*s +//////////////////////////////////////////////////////////////////////////////// + + static AqlValue CreateFromBlocks (triagens::arango::AqlTransaction*, + std::vector const&, + triagens::aql::RegisterId); + //////////////////////////////////////////////////////////////////////////////// /// @brief 3-way comparison for AqlValue objects //////////////////////////////////////////////////////////////////////////////// diff --git a/arangod/Aql/Ast.cpp b/arangod/Aql/Ast.cpp index fecf0ea631..a09a9b9450 100644 --- a/arangod/Aql/Ast.cpp +++ b/arangod/Aql/Ast.cpp @@ -353,11 +353,29 @@ AstNode* Ast::createNodeCollect (AstNode const* list, } //////////////////////////////////////////////////////////////////////////////// -/// @brief create an AST collect node, COUNT +/// @brief create an AST collect node, INTO var = expr //////////////////////////////////////////////////////////////////////////////// -AstNode* Ast::createNodeCollect (AstNode const* list, - char const* name) { +AstNode* Ast::createNodeCollectExpression (AstNode const* list, + char const* name, + AstNode const* expression) { + AstNode* node = createNode(NODE_TYPE_COLLECT_EXPRESSION); + node->addMember(list); + + AstNode* variable = createNodeVariable(name, true); + node->addMember(variable); + + node->addMember(expression); + + return node; +} + +//////////////////////////////////////////////////////////////////////////////// +/// @brief create an AST collect node, COUNT INTO +//////////////////////////////////////////////////////////////////////////////// + +AstNode* Ast::createNodeCollectCount (AstNode const* list, + char const* name) { AstNode* node = createNode(NODE_TYPE_COLLECT_COUNT); node->addMember(list); diff --git a/arangod/Aql/Ast.h b/arangod/Aql/Ast.h index fcce0aeaf2..bb1a1845d4 100644 --- a/arangod/Aql/Ast.h +++ b/arangod/Aql/Ast.h @@ -273,11 +273,19 @@ namespace triagens { AstNode const*); //////////////////////////////////////////////////////////////////////////////// -/// @brief create an AST collect node, COUNT +/// @brief create an AST collect node //////////////////////////////////////////////////////////////////////////////// - AstNode* createNodeCollect (AstNode const*, - char const*); + AstNode* createNodeCollectExpression (AstNode const*, + char const*, + AstNode const*); + +//////////////////////////////////////////////////////////////////////////////// +/// @brief create an AST collect node, COUNT INTO +//////////////////////////////////////////////////////////////////////////////// + + AstNode* createNodeCollectCount (AstNode const*, + char const*); //////////////////////////////////////////////////////////////////////////////// /// @brief create an AST sort node diff --git a/arangod/Aql/AstNode.cpp b/arangod/Aql/AstNode.cpp index c91308539e..131ef3258d 100644 --- a/arangod/Aql/AstNode.cpp +++ b/arangod/Aql/AstNode.cpp @@ -119,7 +119,8 @@ std::unordered_map const AstNode::TypeNames{ { static_cast(NODE_TYPE_FCALL_USER), "user function call" }, { static_cast(NODE_TYPE_RANGE), "range" }, { static_cast(NODE_TYPE_NOP), "no-op" }, - { static_cast(NODE_TYPE_COLLECT_COUNT), "collect count" } + { static_cast(NODE_TYPE_COLLECT_COUNT), "collect count" }, + { static_cast(NODE_TYPE_COLLECT_EXPRESSION), "collect expression" } }; std::unordered_map const AstNode::valueTypeNames{ @@ -492,6 +493,7 @@ AstNode::AstNode (Ast* ast, case NODE_TYPE_REPLACE: case NODE_TYPE_COLLECT: case NODE_TYPE_COLLECT_COUNT: + case NODE_TYPE_COLLECT_EXPRESSION: case NODE_TYPE_SORT: case NODE_TYPE_SORT_ELEMENT: case NODE_TYPE_LIMIT: diff --git a/arangod/Aql/AstNode.h b/arangod/Aql/AstNode.h index 0dfcc8cf60..e5856c1e5d 100644 --- a/arangod/Aql/AstNode.h +++ b/arangod/Aql/AstNode.h @@ -158,7 +158,8 @@ namespace triagens { NODE_TYPE_FCALL_USER = 48, NODE_TYPE_RANGE = 49, NODE_TYPE_NOP = 50, - NODE_TYPE_COLLECT_COUNT = 51 + NODE_TYPE_COLLECT_COUNT = 51, + NODE_TYPE_COLLECT_EXPRESSION = 52 }; static_assert(NODE_TYPE_VALUE < NODE_TYPE_LIST, "incorrect node types"); diff --git a/arangod/Aql/ExecutionBlock.cpp b/arangod/Aql/ExecutionBlock.cpp index ec13fc8f4d..31843099e1 100644 --- a/arangod/Aql/ExecutionBlock.cpp +++ b/arangod/Aql/ExecutionBlock.cpp @@ -2709,6 +2709,7 @@ AggregateBlock::AggregateBlock (ExecutionEngine* engine, : ExecutionBlock(engine, en), _aggregateRegisters(), _currentGroup(en->_countOnly), + _expressionRegister(ExecutionNode::MaxRegisterId), _groupRegister(ExecutionNode::MaxRegisterId), _variableNames() { @@ -2732,6 +2733,12 @@ AggregateBlock::AggregateBlock (ExecutionEngine* engine, _groupRegister = (*it).second.registerId; TRI_ASSERT(_groupRegister > 0 && _groupRegister < ExecutionNode::MaxRegisterId); + if (en->_expressionVariable != nullptr) { + auto it = registerPlan.find(en->_expressionVariable->id); + TRI_ASSERT(it != registerPlan.end()); + _expressionRegister = (*it).second.registerId; + } + // construct a mapping of all register ids to variable names // we need this mapping to generate the grouped output @@ -2978,9 +2985,18 @@ void AggregateBlock::emitGroup (AqlItemBlock const* cur, _currentGroup.addValues(cur, _groupRegister); if (static_cast(_exeNode)->_countOnly) { + // only set group count in result register res->setValue(row, _groupRegister, AqlValue(new Json(static_cast(_currentGroup.groupLength)))); } + else if (static_cast(_exeNode)->_expressionVariable != nullptr) { + // copy expression result into result register + res->setValue(row, _groupRegister, + AqlValue::CreateFromBlocks(_trx, + _currentGroup.groupBlocks, + _expressionRegister)); + } else { + // copy variables / keep variables into result register res->setValue(row, _groupRegister, AqlValue::CreateFromBlocks(_trx, _currentGroup.groupBlocks, diff --git a/arangod/Aql/ExecutionBlock.h b/arangod/Aql/ExecutionBlock.h index 55501921d4..e4090b9688 100644 --- a/arangod/Aql/ExecutionBlock.h +++ b/arangod/Aql/ExecutionBlock.h @@ -1084,6 +1084,13 @@ namespace triagens { AggregatorGroup _currentGroup; +//////////////////////////////////////////////////////////////////////////////// +/// @brief the optional register that contains the input expression values for +/// each group +//////////////////////////////////////////////////////////////////////////////// + + RegisterId _expressionRegister; + //////////////////////////////////////////////////////////////////////////////// /// @brief the optional register that contains the values for each group /// if no values should be returned, then this has a value of 0 diff --git a/arangod/Aql/ExecutionNode.cpp b/arangod/Aql/ExecutionNode.cpp index 67005e03bc..af0d972f3c 100644 --- a/arangod/Aql/ExecutionNode.cpp +++ b/arangod/Aql/ExecutionNode.cpp @@ -151,6 +151,7 @@ ExecutionNode* ExecutionNode::fromJsonFactory (ExecutionPlan* plan, return new SortNode(plan, oneNode, elements, stable); } case AGGREGATE: { + Variable* expressionVariable = varFromJson(plan->getAst(), oneNode, "expressionVariable", Optional); Variable* outVariable = varFromJson(plan->getAst(), oneNode, "outVariable", Optional); triagens::basics::Json jsonAggregates = oneNode.get("aggregates"); @@ -175,10 +176,10 @@ ExecutionNode* ExecutionNode::fromJsonFactory (ExecutionPlan* plan, aggregateVariables.reserve(len); for (size_t i = 0; i < len; i++) { triagens::basics::Json oneJsonAggregate = jsonAggregates.at(static_cast(i)); - Variable* outVariable = varFromJson(plan->getAst(), oneJsonAggregate, "outVariable"); - Variable* inVariable = varFromJson(plan->getAst(), oneJsonAggregate, "inVariable"); + Variable* outVar = varFromJson(plan->getAst(), oneJsonAggregate, "outVariable"); + Variable* inVar = varFromJson(plan->getAst(), oneJsonAggregate, "inVariable"); - aggregateVariables.emplace_back(std::make_pair(outVariable, inVariable)); + aggregateVariables.emplace_back(std::make_pair(outVar, inVar)); } triagens::basics::Json jsonCount = oneNode.get("count"); @@ -186,6 +187,7 @@ ExecutionNode* ExecutionNode::fromJsonFactory (ExecutionPlan* plan, return new AggregateNode(plan, oneNode, + expressionVariable, outVariable, keepVariables, plan->getAst()->variables()->variables(false), @@ -1980,6 +1982,7 @@ double SortNode::estimateCost (size_t& nrItems) const { AggregateNode::AggregateNode (ExecutionPlan* plan, triagens::basics::Json const& base, + Variable const* expressionVariable, Variable const* outVariable, std::vector const& keepVariables, std::unordered_map const& variableMap, @@ -1987,6 +1990,7 @@ AggregateNode::AggregateNode (ExecutionPlan* plan, bool countOnly) : ExecutionNode(plan, base), _aggregateVariables(aggregateVariables), + _expressionVariable(expressionVariable), _outVariable(outVariable), _keepVariables(keepVariables), _variableMap(variableMap), @@ -2015,6 +2019,11 @@ void AggregateNode::toJsonHelper (triagens::basics::Json& nodes, } json("aggregates", values); + // expression variable might be empty + if (_expressionVariable != nullptr) { + json("expressionVariable", _expressionVariable->toJson()); + } + // output variable might be empty if (_outVariable != nullptr) { json("outVariable", _outVariable->toJson()); @@ -2044,9 +2053,14 @@ ExecutionNode* AggregateNode::clone (ExecutionPlan* plan, bool withDependencies, bool withProperties) const { auto outVariable = _outVariable; + auto expressionVariable = _expressionVariable; auto aggregateVariables = _aggregateVariables; if (withProperties) { + if (expressionVariable != nullptr) { + expressionVariable = plan->getAst()->variables()->createVariable(expressionVariable); + } + if (outVariable != nullptr) { outVariable = plan->getAst()->variables()->createVariable(outVariable); } @@ -2059,7 +2073,14 @@ ExecutionNode* AggregateNode::clone (ExecutionPlan* plan, } - auto c = new AggregateNode(plan, _id, aggregateVariables, outVariable, _keepVariables, _variableMap, _countOnly); + auto c = new AggregateNode(plan, + _id, + aggregateVariables, + expressionVariable, + outVariable, + _keepVariables, + _variableMap, + _countOnly); CloneHelper(c, plan, withDependencies, withProperties); @@ -2110,6 +2131,10 @@ std::vector AggregateNode::getVariablesUsedHere () const { v.insert(p.second); } + if (_expressionVariable != nullptr) { + v.insert(_expressionVariable); + } + if (_outVariable != nullptr && ! _countOnly) { if (_keepVariables.empty()) { // Here we have to find all user defined variables in this query diff --git a/arangod/Aql/ExecutionNode.h b/arangod/Aql/ExecutionNode.h index 397af0f49c..1a38bc4e0c 100644 --- a/arangod/Aql/ExecutionNode.h +++ b/arangod/Aql/ExecutionNode.h @@ -1930,12 +1930,14 @@ namespace triagens { AggregateNode (ExecutionPlan* plan, size_t id, std::vector> const& aggregateVariables, + Variable const* expressionVariable, Variable const* outVariable, std::vector const& keepVariables, std::unordered_map const& variableMap, bool countOnly) : ExecutionNode(plan, id), _aggregateVariables(aggregateVariables), + _expressionVariable(expressionVariable), _outVariable(outVariable), _keepVariables(keepVariables), _variableMap(variableMap), @@ -1945,6 +1947,7 @@ namespace triagens { AggregateNode (ExecutionPlan*, triagens::basics::Json const& base, + Variable const* expressionVariable, Variable const* outVariable, std::vector const& keepVariables, std::unordered_map const& variableMap, @@ -2042,6 +2045,12 @@ namespace triagens { std::vector> _aggregateVariables; +//////////////////////////////////////////////////////////////////////////////// +/// @brief input expression variable (might be null) +//////////////////////////////////////////////////////////////////////////////// + + Variable const* _expressionVariable; + //////////////////////////////////////////////////////////////////////////////// /// @brief output variable to write to (might be null) //////////////////////////////////////////////////////////////////////////////// diff --git a/arangod/Aql/ExecutionPlan.cpp b/arangod/Aql/ExecutionPlan.cpp index 873cf341ed..7ad93764da 100644 --- a/arangod/Aql/ExecutionPlan.cpp +++ b/arangod/Aql/ExecutionPlan.cpp @@ -562,7 +562,8 @@ ExecutionNode* ExecutionPlan::fromNodeSort (ExecutionNode* previous, ExecutionNode* ExecutionPlan::fromNodeCollect (ExecutionNode* previous, AstNode const* node) { - TRI_ASSERT(node != nullptr && node->type == NODE_TYPE_COLLECT); + TRI_ASSERT(node != nullptr && + node->type == NODE_TYPE_COLLECT); size_t const n = node->numMembers(); TRI_ASSERT(n >= 1); @@ -635,12 +636,101 @@ ExecutionNode* ExecutionPlan::fromNodeCollect (ExecutionNode* previous, } } - auto en = registerNode(new AggregateNode(this, nextId(), aggregateVariables, + auto en = registerNode(new AggregateNode(this, nextId(), aggregateVariables, nullptr, outVariable, keepVariables, _ast->variables()->variables(false), false)); return addDependency(previous, en); } +//////////////////////////////////////////////////////////////////////////////// +/// @brief create an execution plan element from an AST COLLECT node +/// note that also a sort plan node will be added in front of the collect plan +/// node +//////////////////////////////////////////////////////////////////////////////// + +ExecutionNode* ExecutionPlan::fromNodeCollectExpression (ExecutionNode* previous, + AstNode const* node) { + TRI_ASSERT(node != nullptr && + node->type == NODE_TYPE_COLLECT_EXPRESSION); + size_t const n = node->numMembers(); + + TRI_ASSERT(n == 3); + + auto list = node->getMember(0); + size_t const numVars = list->numMembers(); + + std::vector> sortElements; + + std::vector> aggregateVariables; + aggregateVariables.reserve(numVars); + for (size_t i = 0; i < numVars; ++i) { + auto assigner = list->getMember(i); + + if (assigner == nullptr) { + continue; + } + + TRI_ASSERT(assigner->type == NODE_TYPE_ASSIGN); + auto out = assigner->getMember(0); + TRI_ASSERT(out != nullptr); + auto v = static_cast(out->getData()); + TRI_ASSERT(v != nullptr); + + auto expression = assigner->getMember(1); + + if (expression->type == NODE_TYPE_REFERENCE) { + // operand is a variable + auto e = static_cast(expression->getData()); + aggregateVariables.push_back(std::make_pair(v, e)); + sortElements.push_back(std::make_pair(e, true)); + } + else { + // operand is some misc expression + auto calc = createTemporaryCalculation(expression); + + calc->addDependency(previous); + previous = calc; + + aggregateVariables.emplace_back(std::make_pair(v, calc->outVariable())); + sortElements.emplace_back(std::make_pair(calc->outVariable(), true)); + } + } + + + Variable const* expressionVariable = nullptr; + auto expression = node->getMember(2); + if (expression->type == NODE_TYPE_REFERENCE) { + // expression is already a variable + auto variable = static_cast(expression->getData()); + TRI_ASSERT(variable != nullptr); + expressionVariable = variable; + } + else { + // expression is some misc expression + auto calc = createTemporaryCalculation(expression); + calc->addDependency(previous); + previous = calc; + expressionVariable = calc->outVariable(); + } + + // inject a sort node for all expressions / variables that we just picked up... + // note that this sort is stable + auto sort = registerNode(new SortNode(this, nextId(), sortElements, true)); + sort->addDependency(previous); + previous = sort; + + // output variable + auto v = node->getMember(1); + Variable* outVariable = static_cast(v->getData()); + + std::unordered_map variableMap; + + auto en = registerNode(new AggregateNode(this, nextId(), aggregateVariables, + expressionVariable, outVariable, std::vector(), variableMap, false)); + + return addDependency(previous, en); +} + //////////////////////////////////////////////////////////////////////////////// /// @brief create an execution plan element from an AST COLLECT node, COUNT /// note that also a sort plan node will be added in front of the collect plan @@ -649,7 +739,8 @@ ExecutionNode* ExecutionPlan::fromNodeCollect (ExecutionNode* previous, ExecutionNode* ExecutionPlan::fromNodeCollectCount (ExecutionNode* previous, AstNode const* node) { - TRI_ASSERT(node != nullptr && node->type == NODE_TYPE_COLLECT_COUNT); + TRI_ASSERT(node != nullptr && + node->type == NODE_TYPE_COLLECT_COUNT); size_t const n = node->numMembers(); TRI_ASSERT(n == 2); @@ -705,7 +796,7 @@ ExecutionNode* ExecutionPlan::fromNodeCollectCount (ExecutionNode* previous, // handle out variable Variable* outVariable = static_cast(v->getData()); - auto en = registerNode(new AggregateNode(this, nextId(), aggregateVariables, + auto en = registerNode(new AggregateNode(this, nextId(), aggregateVariables, nullptr, outVariable, std::vector(), _ast->variables()->variables(false), true)); return addDependency(previous, en); @@ -997,6 +1088,11 @@ ExecutionNode* ExecutionPlan::fromNode (AstNode const* node) { break; } + case NODE_TYPE_COLLECT_EXPRESSION: { + en = fromNodeCollectExpression(en, member); + break; + } + case NODE_TYPE_COLLECT_COUNT: { en = fromNodeCollectCount(en, member); break; diff --git a/arangod/Aql/ExecutionPlan.h b/arangod/Aql/ExecutionPlan.h index 487505f796..6aac7e5979 100644 --- a/arangod/Aql/ExecutionPlan.h +++ b/arangod/Aql/ExecutionPlan.h @@ -381,6 +381,13 @@ namespace triagens { ExecutionNode* fromNodeCollect (ExecutionNode*, AstNode const*); +//////////////////////////////////////////////////////////////////////////////// +/// @brief create an execution plan element from an AST COLLECT node, var = expr +//////////////////////////////////////////////////////////////////////////////// + + ExecutionNode* fromNodeCollectExpression (ExecutionNode*, + AstNode const*); + //////////////////////////////////////////////////////////////////////////////// /// @brief create an execution plan element from an AST COLLECT node, COUNT //////////////////////////////////////////////////////////////////////////////// diff --git a/arangod/Aql/grammar.cpp b/arangod/Aql/grammar.cpp index 9ff86f7854..11bd9bb7ab 100644 --- a/arangod/Aql/grammar.cpp +++ b/arangod/Aql/grammar.cpp @@ -492,16 +492,16 @@ union yyalloc /* YYFINAL -- State number of the termination state. */ #define YYFINAL 3 /* YYLAST -- Last index in YYTABLE. */ -#define YYLAST 642 +#define YYLAST 630 /* YYNTOKENS -- Number of terminals. */ #define YYNTOKENS 60 /* YYNNTS -- Number of nonterminals. */ #define YYNNTS 66 /* YYNRULES -- Number of rules. */ -#define YYNRULES 144 +#define YYNRULES 145 /* YYNSTATES -- Number of states. */ -#define YYNSTATES 237 +#define YYNSTATES 239 /* YYTRANSLATE[YYX] -- Symbol number corresponding to YYX as returned by yylex, with out-of-bounds checking. */ @@ -555,19 +555,19 @@ static const yytype_uint16 yyrline[] = { 0, 200, 200, 202, 204, 206, 208, 213, 215, 220, 222, 224, 226, 228, 230, 235, 244, 252, 257, 259, - 264, 271, 281, 281, 295, 315, 342, 376, 378, 383, - 390, 393, 399, 413, 430, 433, 433, 447, 447, 458, - 461, 467, 473, 476, 479, 482, 488, 493, 500, 508, - 511, 517, 528, 539, 547, 558, 566, 577, 580, 580, - 593, 596, 599, 602, 605, 608, 611, 617, 624, 641, - 641, 653, 656, 659, 665, 668, 671, 674, 677, 680, - 683, 686, 689, 692, 695, 698, 701, 704, 707, 713, - 719, 721, 726, 729, 729, 745, 748, 754, 757, 763, - 763, 772, 774, 779, 782, 788, 791, 805, 805, 814, - 816, 821, 823, 828, 834, 838, 838, 866, 879, 886, - 890, 894, 901, 906, 911, 916, 920, 924, 931, 934, - 940, 943, 960, 963, 966, 969, 972, 978, 985, 992, - 1006, 1012, 1019, 1028, 1034 + 264, 271, 281, 281, 295, 315, 342, 373, 403, 405, + 410, 417, 420, 426, 440, 457, 460, 460, 474, 474, + 485, 488, 494, 500, 503, 506, 509, 515, 520, 527, + 535, 538, 544, 555, 566, 574, 585, 593, 604, 607, + 607, 620, 623, 626, 629, 632, 635, 638, 644, 651, + 668, 668, 680, 683, 686, 692, 695, 698, 701, 704, + 707, 710, 713, 716, 719, 722, 725, 728, 731, 734, + 740, 746, 748, 753, 756, 756, 772, 775, 781, 784, + 790, 790, 799, 801, 806, 809, 815, 818, 832, 832, + 841, 843, 848, 850, 855, 861, 865, 865, 893, 906, + 913, 917, 921, 928, 933, 938, 943, 947, 951, 958, + 961, 967, 970, 987, 990, 993, 996, 999, 1005, 1012, + 1019, 1033, 1039, 1046, 1055, 1061 }; #endif @@ -626,12 +626,12 @@ static const yytype_uint16 yytoknum[] = }; # endif -#define YYPACT_NINF -104 +#define YYPACT_NINF -103 #define yypact_value_is_default(Yystate) \ - (!!((Yystate) == (-104))) + (!!((Yystate) == (-103))) -#define YYTABLE_NINF -140 +#define YYTABLE_NINF -141 #define yytable_value_is_error(Yytable_value) \ 0 @@ -640,30 +640,30 @@ static const yytype_uint16 yytoknum[] = STATE-NUM. */ static const yytype_int16 yypact[] = { - -104, 7, 561, -104, -7, -7, 569, 569, 16, -104, - 121, 569, 569, 569, 569, -104, -104, -104, -104, 65, - -104, -104, -104, -104, -104, -104, -104, -104, -104, 15, - -5, -104, 17, -104, -104, -104, 57, -104, -104, -104, - -104, 569, 569, 569, 569, -104, -104, 433, 5, -104, - -104, -104, -104, -104, -104, -104, 42, -35, -104, -104, - -104, -104, -104, 433, 34, -104, -7, 569, 53, 373, - 373, 308, 343, -7, -104, 82, 569, -7, 569, 83, - 83, 83, 233, -104, 14, 569, 569, 98, 569, 569, - 569, 569, 569, 569, 569, 569, 569, 569, 569, 569, - 569, 569, 569, 90, 66, 73, 569, 45, 102, 74, - -104, 93, 75, -104, 273, 121, 590, 23, 101, 101, - 569, 101, 569, 101, -104, -104, -104, 433, -104, 433, - -104, 78, -104, -104, 99, 104, -104, 85, 433, 95, - 105, 97, 569, 493, 463, 507, 507, 20, 20, 20, - 20, 24, 24, 83, 83, 83, 403, -6, -104, 535, - -33, 137, -104, -104, -7, -7, 569, 569, -104, -104, - -104, -104, -104, 6, 21, 25, -104, -104, -104, -104, - -104, 103, -104, -104, 373, -104, 373, -104, -7, -104, - -104, 14, 569, -104, 569, 97, 569, 433, 106, -104, - -104, 107, 569, 54, -29, -104, -104, -104, 433, -104, - -104, 101, 101, 110, -104, -104, 433, 433, 433, -104, - -104, 569, 173, -104, -104, 569, 55, -104, -104, -7, - -104, -104, 203, -104, -104, -104, -104 + -103, 18, 28, -103, 5, 5, 542, 542, 25, -103, + 112, 542, 542, 542, 542, -103, -103, -103, -103, 53, + -103, -103, -103, -103, -103, -103, -103, -103, -103, 63, + 54, -103, 75, -103, -103, -103, 37, -103, -103, -103, + -103, 542, 542, 542, 542, -103, -103, 436, 60, -103, + -103, -103, -103, -103, -103, -103, 66, -39, -103, -103, + -103, -103, -103, 436, 87, -103, 5, 542, 65, 376, + 376, 311, 346, 5, -103, 91, 542, 5, 542, 88, + 88, 88, 236, -103, 50, 542, 542, 103, 542, 542, + 542, 542, 542, 542, 542, 542, 542, 542, 542, 542, + 542, 542, 542, 95, 73, 80, 542, 2, 109, 77, + -103, 99, 82, -103, 276, 112, 563, 0, 117, 117, + 542, 117, 542, 117, 107, -103, -103, 436, -103, 436, + -103, 114, -103, -103, 111, 118, -103, 123, 436, 105, + 121, 584, 542, 466, 143, 480, 480, 252, 252, 252, + 252, 19, 19, 88, 88, 88, 406, 40, -103, 508, + 11, 113, -103, -103, 5, 5, 542, 542, -103, -103, + -103, -103, -103, 3, 7, 8, -103, -103, -103, -103, + -103, 119, -103, -103, 376, -103, 376, -103, 542, 5, + -103, -103, 50, 542, -103, 542, 584, 542, 436, 124, + -103, -103, 140, 542, 27, 12, -103, -103, -103, 436, + -103, -103, 117, 117, 436, 145, -103, -103, 436, 436, + 436, -103, -103, 542, 176, -103, -103, 542, 39, -103, + -103, 5, -103, -103, 206, -103, -103, -103, -103 }; /* YYDEFACT[STATE-NUM] -- Default reduction number in state STATE-NUM. @@ -671,53 +671,53 @@ static const yytype_int16 yypact[] = means the default is an error. */ static const yytype_uint8 yydefact[] = { - 7, 0, 0, 1, 0, 0, 0, 0, 22, 37, - 0, 0, 0, 0, 0, 8, 9, 11, 10, 30, - 12, 13, 14, 2, 3, 4, 5, 6, 143, 0, - 17, 18, 0, 134, 135, 136, 117, 132, 144, 131, - 140, 0, 0, 0, 58, 107, 99, 16, 69, 118, - 60, 61, 62, 63, 97, 98, 65, 114, 64, 133, - 128, 129, 130, 48, 0, 24, 0, 0, 46, 0, - 0, 0, 0, 0, 25, 34, 0, 0, 0, 73, - 71, 72, 0, 7, 109, 101, 0, 0, 0, 0, + 7, 0, 0, 1, 0, 0, 0, 0, 22, 38, + 0, 0, 0, 0, 0, 8, 9, 11, 10, 31, + 12, 13, 14, 2, 3, 4, 5, 6, 144, 0, + 17, 18, 0, 135, 136, 137, 118, 133, 145, 132, + 141, 0, 0, 0, 59, 108, 100, 16, 70, 119, + 61, 62, 63, 64, 98, 99, 66, 115, 65, 134, + 129, 130, 131, 49, 0, 24, 0, 0, 47, 0, + 0, 0, 0, 0, 25, 35, 0, 0, 0, 74, + 72, 73, 0, 7, 110, 102, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 23, - 27, 0, 38, 39, 42, 0, 0, 0, 105, 105, - 0, 105, 0, 105, 31, 35, 26, 15, 19, 20, - 57, 0, 141, 142, 0, 110, 111, 0, 103, 0, - 102, 87, 0, 75, 74, 81, 82, 83, 84, 85, - 86, 76, 77, 78, 79, 80, 0, 66, 68, 93, - 0, 0, 119, 120, 0, 0, 0, 0, 43, 44, - 41, 45, 47, 117, 132, 140, 49, 137, 138, 139, - 50, 0, 51, 52, 0, 53, 0, 55, 0, 59, - 108, 0, 0, 100, 0, 88, 0, 92, 0, 95, - 7, 91, 0, 0, 116, 121, 21, 28, 29, 40, - 106, 105, 105, 36, 32, 112, 113, 104, 89, 70, - 94, 93, 0, 122, 123, 0, 0, 54, 56, 0, - 96, 124, 0, 125, 126, 33, 127 + 28, 0, 39, 40, 43, 0, 0, 0, 106, 106, + 0, 106, 0, 106, 32, 36, 26, 15, 19, 20, + 58, 0, 142, 143, 0, 111, 112, 0, 104, 0, + 103, 88, 0, 76, 75, 82, 83, 84, 85, 86, + 87, 77, 78, 79, 80, 81, 0, 67, 69, 94, + 0, 0, 120, 121, 0, 0, 0, 0, 44, 45, + 42, 46, 48, 118, 133, 141, 50, 138, 139, 140, + 51, 0, 52, 53, 0, 54, 0, 56, 0, 0, + 60, 109, 0, 0, 101, 0, 89, 0, 93, 0, + 96, 7, 92, 0, 0, 117, 122, 21, 29, 30, + 41, 107, 106, 106, 27, 37, 33, 113, 114, 105, + 90, 71, 95, 94, 0, 123, 124, 0, 0, 55, + 57, 0, 97, 125, 0, 126, 127, 34, 128 }; /* YYPGOTO[NTERM-NUM]. */ static const yytype_int16 yypgoto[] = { - -104, -82, -104, -104, -104, -104, -104, -104, 81, 140, - -104, -104, -104, -104, -1, -104, -104, -104, -104, -104, - -104, -104, 12, -104, -104, -104, -58, -104, -104, -104, - -104, -3, -104, -104, -104, -104, -104, -104, -104, -104, - -59, -104, -104, -104, -104, -104, -104, -104, -103, 0, - -104, -104, -104, -9, -104, -104, -104, -104, -8, -104, - -104, 69, -102, -104, -4, -104 + -103, -82, -103, -103, -103, -103, -103, -103, 93, 171, + -103, -103, -103, -103, 29, -103, -103, -103, -103, -103, + -103, -103, 30, -103, -103, -103, -56, -103, -103, -103, + -103, -2, -103, -103, -103, -103, -103, -103, -103, -103, + -27, -103, -103, -103, -103, -103, -103, -103, -102, 17, + -103, -103, -103, 10, -103, -103, -103, -103, -8, -103, + -103, 83, -101, -103, -4, -103 }; /* YYDEFGOTO[NTERM-NUM]. */ static const yytype_int16 yydefgoto[] = { -1, 1, 2, 15, 16, 17, 18, 30, 31, 65, - 19, 66, 20, 109, 110, 75, 213, 126, 188, 21, + 19, 66, 20, 109, 110, 75, 215, 126, 189, 21, 67, 112, 113, 170, 22, 23, 118, 24, 25, 26, - 27, 114, 83, 48, 49, 104, 50, 51, 52, 198, - 199, 200, 201, 53, 54, 85, 139, 140, 182, 55, - 84, 134, 135, 136, 56, 105, 57, 204, 58, 59, + 27, 114, 83, 48, 49, 104, 50, 51, 52, 199, + 200, 201, 202, 53, 54, 85, 139, 140, 182, 55, + 84, 134, 135, 136, 56, 105, 57, 205, 58, 59, 60, 176, 61, 137, 32, 62 }; @@ -726,140 +726,138 @@ static const yytype_int16 yydefgoto[] = number is the opposite. If YYTABLE_NINF, syntax error. */ static const yytype_int16 yytable[] = { - 29, 131, 68, 47, 63, 163, -137, 3, 69, 70, - 71, 72, 119, 121, 123, 28, 183, 106, 185, 202, - 187, -138, 87, 225, 107, -139, 203, 76, -137, 64, - 226, 96, 97, 98, 99, 100, 132, 133, 79, 80, - 81, 82, 77, -138, 78, 177, 178, -139, 87, 179, - 103, -67, 87, -137, -67, -137, 108, 96, 97, 98, - 99, 100, 111, 98, 99, 100, 102, 162, -138, 124, - -138, 40, -139, 127, -139, 129, 223, 233, 64, 73, - 40, 40, 138, 141, -115, 143, 144, 145, 146, 147, - 148, 149, 150, 151, 152, 153, 154, 155, 156, 157, - 115, 224, -67, 161, 125, -67, 171, 172, 227, 228, - 142, 87, 158, 141, 159, 160, 164, 184, 220, 186, - 166, 165, 167, 181, 234, 87, 211, 189, 212, 192, - 92, 93, 94, 95, 96, 97, 98, 99, 100, 195, - 33, 34, 35, 102, 37, 38, 39, 40, 193, 86, - 190, 191, 194, 45, 221, 219, 197, 229, 128, 74, - 206, 111, 230, 208, 207, 87, 88, 89, 90, 91, - 92, 93, 94, 95, 96, 97, 98, 99, 100, 209, - 101, 210, 215, 102, 214, 86, 180, 0, 0, 216, - 205, 217, 0, 218, 0, 0, 0, 0, 0, 222, - 0, 87, 88, 89, 90, 91, 92, 93, 94, 95, - 96, 97, 98, 99, 100, 86, 101, 0, 197, 102, - 0, 0, 232, 0, 0, 235, 231, 0, 0, 0, - 0, 87, 88, 89, 90, 91, 92, 93, 94, 95, - 96, 97, 98, 99, 100, 86, 101, 0, 0, 102, - 0, 0, 0, 0, 0, 0, 236, 0, 0, 0, - 0, 87, 88, 89, 90, 91, 92, 93, 94, 95, - 96, 97, 98, 99, 100, 0, 101, 0, 0, 102, - 0, 0, 130, 168, 169, 86, 0, 0, 0, 0, - 0, 0, 33, 34, 35, 0, 37, 38, 39, 40, - 0, 87, 88, 89, 90, 91, 92, 93, 94, 95, - 96, 97, 98, 99, 100, 0, 101, 0, 0, 102, - 116, 120, 117, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 87, 88, 89, 90, - 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, - 0, 101, 0, 0, 102, 116, 122, 117, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 87, 88, 89, 90, 91, 92, 93, 94, 95, - 96, 97, 98, 99, 100, 116, 101, 117, 0, 102, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 87, 88, 89, 90, 91, 92, 93, 94, 95, - 96, 97, 98, 99, 100, 86, 101, 0, 0, 102, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 87, 88, 89, 90, 91, 92, 93, 94, 95, - 96, 97, 98, 99, 100, 86, 101, 196, 0, 102, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 87, 88, 89, 90, 91, 92, 93, 94, 95, - 96, 97, 98, 99, 100, 86, 101, 0, 0, 102, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 87, 88, 0, 90, 91, 92, 93, 94, 95, - 96, 97, 98, 99, 100, 86, 0, 0, 0, 102, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 86, - 0, 87, 0, 0, 90, 91, 92, 93, 94, 95, - 96, 97, 98, 99, 100, 87, 0, 0, 0, 102, - 92, 93, 94, 95, 96, 97, 98, 99, 100, 0, - 0, 0, 0, 102, 33, 34, 35, 36, 37, 38, - 39, 40, 0, 41, 4, 5, 6, 7, 8, 9, - 10, 0, 42, 43, 0, 0, 11, 12, 13, 14, - 0, 0, 0, 44, -90, 45, 0, 46, 33, 34, - 35, 36, 37, 38, 39, 40, 0, 41, 0, 0, - 0, 0, 0, 0, 0, 0, 42, 43, 0, 33, - 34, 35, 173, 174, 38, 39, 175, 44, 41, 45, - 0, 46, 0, 0, 0, 0, 0, 42, 43, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 44, 0, - 45, 0, 46 + 29, 131, 68, -138, 47, 63, 163, -139, -140, 69, + 70, 71, 72, 106, 119, 121, 123, 183, 3, 185, + 107, 187, 177, 178, 162, -138, 179, 28, 40, -139, + -140, 4, 5, 6, 7, 8, 9, 10, 64, 79, + 80, 81, 82, 11, 12, 13, 14, 87, -68, 225, + -138, -68, -138, 40, -139, -140, -139, -140, 98, 99, + 100, 235, 111, 203, 227, 40, 64, 73, 87, 124, + 204, 228, 132, 133, 127, 76, 129, 96, 97, 98, + 99, 100, -68, 138, 141, -68, 143, 144, 145, 146, + 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, + 157, 77, 78, 226, 161, 103, 171, 172, -116, 108, + 229, 230, 115, 125, 141, 142, 87, 158, 184, 222, + 186, 159, 160, 164, 165, 86, 166, 236, 212, 167, + 213, 33, 34, 35, 188, 37, 38, 39, 40, 181, + 196, 87, 88, 89, 90, 91, 92, 93, 94, 95, + 96, 97, 98, 99, 100, 86, 101, 198, 194, 102, + 207, 111, 191, 190, 209, 192, 206, 193, 195, 45, + 128, 87, 88, 221, 90, 91, 92, 93, 94, 95, + 96, 97, 98, 99, 100, 216, 214, 223, 86, 102, + 74, 218, 231, 219, 208, 220, 232, 210, 211, 0, + 180, 224, 217, 0, 87, 88, 89, 90, 91, 92, + 93, 94, 95, 96, 97, 98, 99, 100, 86, 101, + 0, 198, 102, 0, 0, 234, 0, 237, 0, 233, + 0, 0, 0, 0, 87, 88, 89, 90, 91, 92, + 93, 94, 95, 96, 97, 98, 99, 100, 86, 101, + 0, 0, 102, 0, 0, 0, 0, 0, 0, 238, + 0, 0, 0, 0, 87, 88, 89, 90, 91, 92, + 93, 94, 95, 96, 97, 98, 99, 100, 0, 101, + 87, 0, 102, 0, 0, 130, 168, 169, 86, 96, + 97, 98, 99, 100, 0, 33, 34, 35, 102, 37, + 38, 39, 40, 0, 87, 88, 89, 90, 91, 92, + 93, 94, 95, 96, 97, 98, 99, 100, 0, 101, + 0, 0, 102, 116, 120, 117, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 87, + 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, + 98, 99, 100, 0, 101, 0, 0, 102, 116, 122, + 117, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 87, 88, 89, 90, 91, 92, + 93, 94, 95, 96, 97, 98, 99, 100, 116, 101, + 117, 0, 102, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 87, 88, 89, 90, 91, 92, + 93, 94, 95, 96, 97, 98, 99, 100, 86, 101, + 0, 0, 102, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 87, 88, 89, 90, 91, 92, + 93, 94, 95, 96, 97, 98, 99, 100, 86, 101, + 197, 0, 102, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 87, 88, 89, 90, 91, 92, + 93, 94, 95, 96, 97, 98, 99, 100, 86, 101, + 0, 0, 102, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 86, 0, 87, 0, 0, 90, 91, 92, + 93, 94, 95, 96, 97, 98, 99, 100, 87, 0, + 0, 0, 102, 92, 93, 94, 95, 96, 97, 98, + 99, 100, 0, 0, 0, 0, 102, 33, 34, 35, + 36, 37, 38, 39, 40, 0, 41, 0, 0, 0, + 0, 0, 0, 0, 0, 42, 43, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 44, -91, 45, 0, + 46, 33, 34, 35, 36, 37, 38, 39, 40, 0, + 41, 0, 0, 0, 0, 0, 0, 0, 0, 42, + 43, 0, 33, 34, 35, 173, 174, 38, 39, 175, + 44, 41, 45, 0, 46, 0, 0, 0, 0, 0, + 42, 43, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 44, 87, 45, 0, 46, 0, 92, 93, 94, + 95, 96, 97, 98, 99, 100, 0, 0, 0, 0, + 102 }; static const yytype_int16 yycheck[] = { - 4, 83, 10, 6, 7, 107, 0, 0, 11, 12, - 13, 14, 70, 71, 72, 22, 119, 52, 121, 52, - 123, 0, 28, 52, 59, 0, 59, 12, 22, 13, - 59, 37, 38, 39, 40, 41, 22, 23, 41, 42, - 43, 44, 47, 22, 27, 22, 23, 22, 28, 26, - 45, 45, 28, 47, 48, 49, 22, 37, 38, 39, - 40, 41, 66, 39, 40, 41, 46, 22, 47, 73, - 49, 26, 47, 76, 49, 78, 22, 22, 13, 14, - 26, 26, 85, 86, 42, 88, 89, 90, 91, 92, - 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, - 47, 203, 45, 106, 22, 48, 114, 115, 211, 212, - 12, 28, 22, 116, 48, 42, 14, 120, 200, 122, - 27, 47, 47, 22, 226, 28, 184, 49, 186, 44, - 33, 34, 35, 36, 37, 38, 39, 40, 41, 142, - 19, 20, 21, 46, 23, 24, 25, 26, 53, 12, - 51, 47, 47, 50, 47, 49, 159, 47, 77, 19, - 164, 165, 221, 166, 165, 28, 29, 30, 31, 32, - 33, 34, 35, 36, 37, 38, 39, 40, 41, 167, - 43, 181, 191, 46, 188, 12, 117, -1, -1, 192, - 53, 194, -1, 196, -1, -1, -1, -1, -1, 202, - -1, 28, 29, 30, 31, 32, 33, 34, 35, 36, - 37, 38, 39, 40, 41, 12, 43, -1, 221, 46, - -1, -1, 225, -1, -1, 229, 53, -1, -1, -1, - -1, 28, 29, 30, 31, 32, 33, 34, 35, 36, - 37, 38, 39, 40, 41, 12, 43, -1, -1, 46, - -1, -1, -1, -1, -1, -1, 53, -1, -1, -1, - -1, 28, 29, 30, 31, 32, 33, 34, 35, 36, - 37, 38, 39, 40, 41, -1, 43, -1, -1, 46, - -1, -1, 49, 10, 11, 12, -1, -1, -1, -1, - -1, -1, 19, 20, 21, -1, 23, 24, 25, 26, - -1, 28, 29, 30, 31, 32, 33, 34, 35, 36, - 37, 38, 39, 40, 41, -1, 43, -1, -1, 46, - 12, 13, 14, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, 28, 29, 30, 31, - 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, - -1, 43, -1, -1, 46, 12, 13, 14, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, 28, 29, 30, 31, 32, 33, 34, 35, 36, - 37, 38, 39, 40, 41, 12, 43, 14, -1, 46, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, 28, 29, 30, 31, 32, 33, 34, 35, 36, - 37, 38, 39, 40, 41, 12, 43, -1, -1, 46, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, 28, 29, 30, 31, 32, 33, 34, 35, 36, - 37, 38, 39, 40, 41, 12, 43, 44, -1, 46, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, 28, 29, 30, 31, 32, 33, 34, 35, 36, - 37, 38, 39, 40, 41, 12, 43, -1, -1, 46, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, 28, 29, -1, 31, 32, 33, 34, 35, 36, - 37, 38, 39, 40, 41, 12, -1, -1, -1, 46, - -1, -1, -1, -1, -1, -1, -1, -1, -1, 12, - -1, 28, -1, -1, 31, 32, 33, 34, 35, 36, - 37, 38, 39, 40, 41, 28, -1, -1, -1, 46, - 33, 34, 35, 36, 37, 38, 39, 40, 41, -1, - -1, -1, -1, 46, 19, 20, 21, 22, 23, 24, - 25, 26, -1, 28, 3, 4, 5, 6, 7, 8, - 9, -1, 37, 38, -1, -1, 15, 16, 17, 18, - -1, -1, -1, 48, 49, 50, -1, 52, 19, 20, - 21, 22, 23, 24, 25, 26, -1, 28, -1, -1, - -1, -1, -1, -1, -1, -1, 37, 38, -1, 19, - 20, 21, 22, 23, 24, 25, 26, 48, 28, 50, - -1, 52, -1, -1, -1, -1, -1, 37, 38, -1, - -1, -1, -1, -1, -1, -1, -1, -1, 48, -1, - 50, -1, 52 + 4, 83, 10, 0, 6, 7, 107, 0, 0, 11, + 12, 13, 14, 52, 70, 71, 72, 119, 0, 121, + 59, 123, 22, 23, 22, 22, 26, 22, 26, 22, + 22, 3, 4, 5, 6, 7, 8, 9, 13, 41, + 42, 43, 44, 15, 16, 17, 18, 28, 45, 22, + 47, 48, 49, 26, 47, 47, 49, 49, 39, 40, + 41, 22, 66, 52, 52, 26, 13, 14, 28, 73, + 59, 59, 22, 23, 76, 12, 78, 37, 38, 39, + 40, 41, 45, 85, 86, 48, 88, 89, 90, 91, + 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, + 102, 47, 27, 204, 106, 45, 114, 115, 42, 22, + 212, 213, 47, 22, 116, 12, 28, 22, 120, 201, + 122, 48, 42, 14, 47, 12, 27, 228, 184, 47, + 186, 19, 20, 21, 27, 23, 24, 25, 26, 22, + 142, 28, 29, 30, 31, 32, 33, 34, 35, 36, + 37, 38, 39, 40, 41, 12, 43, 159, 53, 46, + 164, 165, 51, 49, 166, 47, 53, 44, 47, 50, + 77, 28, 29, 49, 31, 32, 33, 34, 35, 36, + 37, 38, 39, 40, 41, 189, 188, 47, 12, 46, + 19, 193, 47, 195, 165, 197, 223, 167, 181, -1, + 117, 203, 192, -1, 28, 29, 30, 31, 32, 33, + 34, 35, 36, 37, 38, 39, 40, 41, 12, 43, + -1, 223, 46, -1, -1, 227, -1, 231, -1, 53, + -1, -1, -1, -1, 28, 29, 30, 31, 32, 33, + 34, 35, 36, 37, 38, 39, 40, 41, 12, 43, + -1, -1, 46, -1, -1, -1, -1, -1, -1, 53, + -1, -1, -1, -1, 28, 29, 30, 31, 32, 33, + 34, 35, 36, 37, 38, 39, 40, 41, -1, 43, + 28, -1, 46, -1, -1, 49, 10, 11, 12, 37, + 38, 39, 40, 41, -1, 19, 20, 21, 46, 23, + 24, 25, 26, -1, 28, 29, 30, 31, 32, 33, + 34, 35, 36, 37, 38, 39, 40, 41, -1, 43, + -1, -1, 46, 12, 13, 14, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, 28, + 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, + 39, 40, 41, -1, 43, -1, -1, 46, 12, 13, + 14, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, 28, 29, 30, 31, 32, 33, + 34, 35, 36, 37, 38, 39, 40, 41, 12, 43, + 14, -1, 46, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, 28, 29, 30, 31, 32, 33, + 34, 35, 36, 37, 38, 39, 40, 41, 12, 43, + -1, -1, 46, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, 28, 29, 30, 31, 32, 33, + 34, 35, 36, 37, 38, 39, 40, 41, 12, 43, + 44, -1, 46, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, 28, 29, 30, 31, 32, 33, + 34, 35, 36, 37, 38, 39, 40, 41, 12, 43, + -1, -1, 46, -1, -1, -1, -1, -1, -1, -1, + -1, -1, 12, -1, 28, -1, -1, 31, 32, 33, + 34, 35, 36, 37, 38, 39, 40, 41, 28, -1, + -1, -1, 46, 33, 34, 35, 36, 37, 38, 39, + 40, 41, -1, -1, -1, -1, 46, 19, 20, 21, + 22, 23, 24, 25, 26, -1, 28, -1, -1, -1, + -1, -1, -1, -1, -1, 37, 38, -1, -1, -1, + -1, -1, -1, -1, -1, -1, 48, 49, 50, -1, + 52, 19, 20, 21, 22, 23, 24, 25, 26, -1, + 28, -1, -1, -1, -1, -1, -1, -1, -1, 37, + 38, -1, 19, 20, 21, 22, 23, 24, 25, 26, + 48, 28, 50, -1, 52, -1, -1, -1, -1, -1, + 37, 38, -1, -1, -1, -1, -1, -1, -1, -1, + -1, 48, 28, 50, -1, 52, -1, 33, 34, 35, + 36, 37, 38, 39, 40, 41, -1, -1, -1, -1, + 46 }; /* YYSTOS[STATE-NUM] -- The (internal number of the) accessing @@ -884,12 +882,12 @@ static const yytype_uint8 yystos[] = 91, 91, 91, 91, 91, 91, 91, 91, 22, 48, 42, 91, 22, 122, 14, 47, 27, 47, 10, 11, 83, 118, 118, 22, 23, 26, 121, 22, 23, 26, - 121, 22, 108, 108, 91, 108, 91, 108, 78, 49, - 51, 47, 44, 53, 47, 91, 44, 91, 99, 100, - 101, 102, 52, 59, 117, 53, 124, 74, 91, 82, - 109, 86, 86, 76, 124, 113, 91, 91, 91, 49, - 61, 47, 91, 22, 122, 52, 59, 108, 108, 47, - 100, 53, 91, 22, 122, 124, 53 + 121, 22, 108, 108, 91, 108, 91, 108, 27, 78, + 49, 51, 47, 44, 53, 47, 91, 44, 91, 99, + 100, 101, 102, 52, 59, 117, 53, 124, 74, 91, + 82, 109, 86, 86, 91, 76, 124, 113, 91, 91, + 91, 49, 61, 47, 91, 22, 122, 52, 59, 108, + 108, 47, 100, 53, 91, 22, 122, 124, 53 }; /* YYR1[YYN] -- Symbol number of symbol that rule YYN derives. */ @@ -897,19 +895,19 @@ static const yytype_uint8 yyr1[] = { 0, 60, 61, 61, 61, 61, 61, 62, 62, 63, 63, 63, 63, 63, 63, 64, 65, 66, 67, 67, - 68, 69, 71, 70, 72, 72, 72, 73, 73, 74, - 75, 75, 76, 76, 77, 78, 77, 80, 79, 81, - 81, 82, 83, 83, 83, 83, 84, 84, 85, 86, - 86, 87, 88, 89, 89, 90, 90, 91, 92, 91, - 91, 91, 91, 91, 91, 91, 91, 93, 93, 95, - 94, 96, 96, 96, 97, 97, 97, 97, 97, 97, - 97, 97, 97, 97, 97, 97, 97, 97, 97, 98, - 99, 99, 100, 101, 100, 102, 102, 103, 103, 105, - 104, 106, 106, 107, 107, 108, 108, 110, 109, 111, - 111, 112, 112, 113, 114, 115, 114, 116, 116, 116, - 116, 116, 117, 117, 117, 117, 117, 117, 118, 118, - 119, 119, 120, 120, 120, 120, 120, 121, 121, 121, - 122, 123, 123, 124, 125 + 68, 69, 71, 70, 72, 72, 72, 72, 73, 73, + 74, 75, 75, 76, 76, 77, 78, 77, 80, 79, + 81, 81, 82, 83, 83, 83, 83, 84, 84, 85, + 86, 86, 87, 88, 89, 89, 90, 90, 91, 92, + 91, 91, 91, 91, 91, 91, 91, 91, 93, 93, + 95, 94, 96, 96, 96, 97, 97, 97, 97, 97, + 97, 97, 97, 97, 97, 97, 97, 97, 97, 97, + 98, 99, 99, 100, 101, 100, 102, 102, 103, 103, + 105, 104, 106, 106, 107, 107, 108, 108, 110, 109, + 111, 111, 112, 112, 113, 114, 115, 114, 116, 116, + 116, 116, 116, 117, 117, 117, 117, 117, 117, 118, + 118, 119, 119, 120, 120, 120, 120, 120, 121, 121, + 121, 122, 123, 123, 124, 125 }; /* YYR2[YYN] -- Number of symbols on the right hand side of rule YYN. */ @@ -917,19 +915,19 @@ static const yytype_uint8 yyr2[] = { 0, 2, 2, 2, 2, 2, 2, 0, 2, 1, 1, 1, 1, 1, 1, 4, 2, 2, 1, 3, - 3, 4, 0, 3, 2, 2, 3, 1, 3, 3, - 0, 2, 1, 3, 0, 0, 3, 0, 3, 1, - 3, 2, 0, 1, 1, 1, 2, 4, 2, 2, - 2, 4, 4, 4, 6, 4, 6, 3, 0, 4, - 1, 1, 1, 1, 1, 1, 3, 1, 3, 0, - 5, 2, 2, 2, 3, 3, 3, 3, 3, 3, - 3, 3, 3, 3, 3, 3, 3, 3, 4, 5, - 0, 1, 1, 0, 2, 1, 3, 1, 1, 0, - 4, 0, 1, 1, 3, 0, 2, 0, 4, 0, - 1, 1, 3, 3, 1, 0, 4, 1, 1, 3, - 3, 4, 2, 2, 3, 3, 3, 4, 1, 1, + 3, 4, 0, 3, 2, 2, 3, 5, 1, 3, + 3, 0, 2, 1, 3, 0, 0, 3, 0, 3, + 1, 3, 2, 0, 1, 1, 1, 2, 4, 2, + 2, 2, 4, 4, 4, 6, 4, 6, 3, 0, + 4, 1, 1, 1, 1, 1, 1, 3, 1, 3, + 0, 5, 2, 2, 2, 3, 3, 3, 3, 3, + 3, 3, 3, 3, 3, 3, 3, 3, 3, 4, + 5, 0, 1, 1, 0, 2, 1, 3, 1, 1, + 0, 4, 0, 1, 1, 3, 0, 2, 0, 4, + 0, 1, 1, 3, 3, 1, 0, 4, 1, 1, + 3, 3, 4, 2, 2, 3, 3, 3, 4, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1 + 1, 1, 1, 1, 1, 1 }; @@ -1710,91 +1708,91 @@ yyreduce: #line 200 "arangod/Aql/grammar.y" /* yacc.c:1646 */ { } -#line 1714 "arangod/Aql/grammar.cpp" /* yacc.c:1646 */ +#line 1712 "arangod/Aql/grammar.cpp" /* yacc.c:1646 */ break; case 3: #line 202 "arangod/Aql/grammar.y" /* yacc.c:1646 */ { } -#line 1721 "arangod/Aql/grammar.cpp" /* yacc.c:1646 */ +#line 1719 "arangod/Aql/grammar.cpp" /* yacc.c:1646 */ break; case 4: #line 204 "arangod/Aql/grammar.y" /* yacc.c:1646 */ { } -#line 1728 "arangod/Aql/grammar.cpp" /* yacc.c:1646 */ +#line 1726 "arangod/Aql/grammar.cpp" /* yacc.c:1646 */ break; case 5: #line 206 "arangod/Aql/grammar.y" /* yacc.c:1646 */ { } -#line 1735 "arangod/Aql/grammar.cpp" /* yacc.c:1646 */ +#line 1733 "arangod/Aql/grammar.cpp" /* yacc.c:1646 */ break; case 6: #line 208 "arangod/Aql/grammar.y" /* yacc.c:1646 */ { } -#line 1742 "arangod/Aql/grammar.cpp" /* yacc.c:1646 */ +#line 1740 "arangod/Aql/grammar.cpp" /* yacc.c:1646 */ break; case 7: #line 213 "arangod/Aql/grammar.y" /* yacc.c:1646 */ { } -#line 1749 "arangod/Aql/grammar.cpp" /* yacc.c:1646 */ +#line 1747 "arangod/Aql/grammar.cpp" /* yacc.c:1646 */ break; case 8: #line 215 "arangod/Aql/grammar.y" /* yacc.c:1646 */ { } -#line 1756 "arangod/Aql/grammar.cpp" /* yacc.c:1646 */ +#line 1754 "arangod/Aql/grammar.cpp" /* yacc.c:1646 */ break; case 9: #line 220 "arangod/Aql/grammar.y" /* yacc.c:1646 */ { } -#line 1763 "arangod/Aql/grammar.cpp" /* yacc.c:1646 */ +#line 1761 "arangod/Aql/grammar.cpp" /* yacc.c:1646 */ break; case 10: #line 222 "arangod/Aql/grammar.y" /* yacc.c:1646 */ { } -#line 1770 "arangod/Aql/grammar.cpp" /* yacc.c:1646 */ +#line 1768 "arangod/Aql/grammar.cpp" /* yacc.c:1646 */ break; case 11: #line 224 "arangod/Aql/grammar.y" /* yacc.c:1646 */ { } -#line 1777 "arangod/Aql/grammar.cpp" /* yacc.c:1646 */ +#line 1775 "arangod/Aql/grammar.cpp" /* yacc.c:1646 */ break; case 12: #line 226 "arangod/Aql/grammar.y" /* yacc.c:1646 */ { } -#line 1784 "arangod/Aql/grammar.cpp" /* yacc.c:1646 */ +#line 1782 "arangod/Aql/grammar.cpp" /* yacc.c:1646 */ break; case 13: #line 228 "arangod/Aql/grammar.y" /* yacc.c:1646 */ { } -#line 1791 "arangod/Aql/grammar.cpp" /* yacc.c:1646 */ +#line 1789 "arangod/Aql/grammar.cpp" /* yacc.c:1646 */ break; case 14: #line 230 "arangod/Aql/grammar.y" /* yacc.c:1646 */ { } -#line 1798 "arangod/Aql/grammar.cpp" /* yacc.c:1646 */ +#line 1796 "arangod/Aql/grammar.cpp" /* yacc.c:1646 */ break; case 15: @@ -1805,7 +1803,7 @@ yyreduce: auto node = parser->ast()->createNodeFor((yyvsp[-2].strval), (yyvsp[0].node)); parser->ast()->addOperation(node); } -#line 1809 "arangod/Aql/grammar.cpp" /* yacc.c:1646 */ +#line 1807 "arangod/Aql/grammar.cpp" /* yacc.c:1646 */ break; case 16: @@ -1815,28 +1813,28 @@ yyreduce: auto node = parser->ast()->createNodeFilter((yyvsp[0].node)); parser->ast()->addOperation(node); } -#line 1819 "arangod/Aql/grammar.cpp" /* yacc.c:1646 */ +#line 1817 "arangod/Aql/grammar.cpp" /* yacc.c:1646 */ break; case 17: #line 252 "arangod/Aql/grammar.y" /* yacc.c:1646 */ { } -#line 1826 "arangod/Aql/grammar.cpp" /* yacc.c:1646 */ +#line 1824 "arangod/Aql/grammar.cpp" /* yacc.c:1646 */ break; case 18: #line 257 "arangod/Aql/grammar.y" /* yacc.c:1646 */ { } -#line 1833 "arangod/Aql/grammar.cpp" /* yacc.c:1646 */ +#line 1831 "arangod/Aql/grammar.cpp" /* yacc.c:1646 */ break; case 19: #line 259 "arangod/Aql/grammar.y" /* yacc.c:1646 */ { } -#line 1840 "arangod/Aql/grammar.cpp" /* yacc.c:1646 */ +#line 1838 "arangod/Aql/grammar.cpp" /* yacc.c:1646 */ break; case 20: @@ -1845,7 +1843,7 @@ yyreduce: auto node = parser->ast()->createNodeLet((yyvsp[-2].strval), (yyvsp[0].node), true); parser->ast()->addOperation(node); } -#line 1849 "arangod/Aql/grammar.cpp" /* yacc.c:1646 */ +#line 1847 "arangod/Aql/grammar.cpp" /* yacc.c:1646 */ break; case 21: @@ -1857,7 +1855,7 @@ yyreduce: (yyval.strval) = (yyvsp[0].strval); } -#line 1861 "arangod/Aql/grammar.cpp" /* yacc.c:1646 */ +#line 1859 "arangod/Aql/grammar.cpp" /* yacc.c:1646 */ break; case 22: @@ -1866,7 +1864,7 @@ yyreduce: auto node = parser->ast()->createNodeList(); parser->pushStack(node); } -#line 1870 "arangod/Aql/grammar.cpp" /* yacc.c:1646 */ +#line 1868 "arangod/Aql/grammar.cpp" /* yacc.c:1646 */ break; case 23: @@ -1879,7 +1877,7 @@ yyreduce: } (yyval.node) = list; } -#line 1883 "arangod/Aql/grammar.cpp" /* yacc.c:1646 */ +#line 1881 "arangod/Aql/grammar.cpp" /* yacc.c:1646 */ break; case 24: @@ -1901,10 +1899,10 @@ yyreduce: scopes->start(triagens::aql::AQL_SCOPE_COLLECT); } - auto node = parser->ast()->createNodeCollect(parser->ast()->createNodeList(), (yyvsp[0].strval)); + auto node = parser->ast()->createNodeCollectCount(parser->ast()->createNodeList(), (yyvsp[0].strval)); parser->ast()->addOperation(node); } -#line 1908 "arangod/Aql/grammar.cpp" /* yacc.c:1646 */ +#line 1906 "arangod/Aql/grammar.cpp" /* yacc.c:1646 */ break; case 25: @@ -1933,10 +1931,10 @@ yyreduce: } } - auto node = parser->ast()->createNodeCollect((yyvsp[-1].node), (yyvsp[0].strval)); + auto node = parser->ast()->createNodeCollectCount((yyvsp[-1].node), (yyvsp[0].strval)); parser->ast()->addOperation(node); } -#line 1940 "arangod/Aql/grammar.cpp" /* yacc.c:1646 */ +#line 1938 "arangod/Aql/grammar.cpp" /* yacc.c:1646 */ break; case 26: @@ -1972,69 +1970,82 @@ yyreduce: auto node = parser->ast()->createNodeCollect((yyvsp[-2].node), (yyvsp[-1].strval), (yyvsp[0].node)); parser->ast()->addOperation(node); } -#line 1976 "arangod/Aql/grammar.cpp" /* yacc.c:1646 */ +#line 1974 "arangod/Aql/grammar.cpp" /* yacc.c:1646 */ break; case 27: -#line 376 "arangod/Aql/grammar.y" /* yacc.c:1646 */ +#line 373 "arangod/Aql/grammar.y" /* yacc.c:1646 */ { + auto scopes = parser->ast()->scopes(); + + // check if we are in the main scope + bool reRegisterVariables = (scopes->type() != triagens::aql::AQL_SCOPE_MAIN); + + if (reRegisterVariables) { + // end the active scopes + scopes->endNested(); + // start a new scope + scopes->start(triagens::aql::AQL_SCOPE_COLLECT); + + size_t const n = (yyvsp[-4].node)->numMembers(); + for (size_t i = 0; i < n; ++i) { + auto member = (yyvsp[-4].node)->getMember(i); + + if (member != nullptr) { + TRI_ASSERT(member->type == NODE_TYPE_ASSIGN); + auto v = static_cast(member->getMember(0)->getData()); + scopes->addVariable(v); + } + } + } + + auto node = parser->ast()->createNodeCollectExpression((yyvsp[-4].node), (yyvsp[-2].strval), (yyvsp[0].node)); + parser->ast()->addOperation(node); } -#line 1983 "arangod/Aql/grammar.cpp" /* yacc.c:1646 */ +#line 2006 "arangod/Aql/grammar.cpp" /* yacc.c:1646 */ break; case 28: -#line 378 "arangod/Aql/grammar.y" /* yacc.c:1646 */ +#line 403 "arangod/Aql/grammar.y" /* yacc.c:1646 */ { } -#line 1990 "arangod/Aql/grammar.cpp" /* yacc.c:1646 */ +#line 2013 "arangod/Aql/grammar.cpp" /* yacc.c:1646 */ break; case 29: -#line 383 "arangod/Aql/grammar.y" /* yacc.c:1646 */ +#line 405 "arangod/Aql/grammar.y" /* yacc.c:1646 */ + { + } +#line 2020 "arangod/Aql/grammar.cpp" /* yacc.c:1646 */ + break; + + case 30: +#line 410 "arangod/Aql/grammar.y" /* yacc.c:1646 */ { auto node = parser->ast()->createNodeAssign((yyvsp[-2].strval), (yyvsp[0].node)); parser->pushList(node); } -#line 1999 "arangod/Aql/grammar.cpp" /* yacc.c:1646 */ - break; - - case 30: -#line 390 "arangod/Aql/grammar.y" /* yacc.c:1646 */ - { - (yyval.strval) = nullptr; - } -#line 2007 "arangod/Aql/grammar.cpp" /* yacc.c:1646 */ +#line 2029 "arangod/Aql/grammar.cpp" /* yacc.c:1646 */ break; case 31: -#line 393 "arangod/Aql/grammar.y" /* yacc.c:1646 */ +#line 417 "arangod/Aql/grammar.y" /* yacc.c:1646 */ { - (yyval.strval) = (yyvsp[0].strval); + (yyval.strval) = nullptr; } -#line 2015 "arangod/Aql/grammar.cpp" /* yacc.c:1646 */ +#line 2037 "arangod/Aql/grammar.cpp" /* yacc.c:1646 */ break; case 32: -#line 399 "arangod/Aql/grammar.y" /* yacc.c:1646 */ +#line 420 "arangod/Aql/grammar.y" /* yacc.c:1646 */ { - if (! parser->ast()->scopes()->existsVariable((yyvsp[0].strval))) { - parser->registerParseError(TRI_ERROR_QUERY_PARSE, "use of unknown variable '%s' for KEEP", (yyvsp[0].strval), yylloc.first_line, yylloc.first_column); - } - - auto node = parser->ast()->createNodeReference((yyvsp[0].strval)); - if (node == nullptr) { - ABORT_OOM - } - - // indicate the this node is a reference to the variable name, not the variable value - node->setFlag(FLAG_KEEP_VARIABLENAME); - parser->pushList(node); + (yyval.strval) = (yyvsp[0].strval); } -#line 2034 "arangod/Aql/grammar.cpp" /* yacc.c:1646 */ +#line 2045 "arangod/Aql/grammar.cpp" /* yacc.c:1646 */ break; case 33: -#line 413 "arangod/Aql/grammar.y" /* yacc.c:1646 */ +#line 426 "arangod/Aql/grammar.y" /* yacc.c:1646 */ { if (! parser->ast()->scopes()->existsVariable((yyvsp[0].strval))) { parser->registerParseError(TRI_ERROR_QUERY_PARSE, "use of unknown variable '%s' for KEEP", (yyvsp[0].strval), yylloc.first_line, yylloc.first_column); @@ -2049,19 +2060,38 @@ yyreduce: node->setFlag(FLAG_KEEP_VARIABLENAME); parser->pushList(node); } -#line 2053 "arangod/Aql/grammar.cpp" /* yacc.c:1646 */ +#line 2064 "arangod/Aql/grammar.cpp" /* yacc.c:1646 */ break; case 34: -#line 430 "arangod/Aql/grammar.y" /* yacc.c:1646 */ +#line 440 "arangod/Aql/grammar.y" /* yacc.c:1646 */ { - (yyval.node) = nullptr; + if (! parser->ast()->scopes()->existsVariable((yyvsp[0].strval))) { + parser->registerParseError(TRI_ERROR_QUERY_PARSE, "use of unknown variable '%s' for KEEP", (yyvsp[0].strval), yylloc.first_line, yylloc.first_column); + } + + auto node = parser->ast()->createNodeReference((yyvsp[0].strval)); + if (node == nullptr) { + ABORT_OOM + } + + // indicate the this node is a reference to the variable name, not the variable value + node->setFlag(FLAG_KEEP_VARIABLENAME); + parser->pushList(node); } -#line 2061 "arangod/Aql/grammar.cpp" /* yacc.c:1646 */ +#line 2083 "arangod/Aql/grammar.cpp" /* yacc.c:1646 */ break; case 35: -#line 433 "arangod/Aql/grammar.y" /* yacc.c:1646 */ +#line 457 "arangod/Aql/grammar.y" /* yacc.c:1646 */ + { + (yyval.node) = nullptr; + } +#line 2091 "arangod/Aql/grammar.cpp" /* yacc.c:1646 */ + break; + + case 36: +#line 460 "arangod/Aql/grammar.y" /* yacc.c:1646 */ { if (! TRI_CaseEqualString((yyvsp[0].strval), "KEEP")) { parser->registerParseError(TRI_ERROR_QUERY_PARSE, "unexpected qualifier '%s', expecting 'KEEP'", (yyvsp[0].strval), yylloc.first_line, yylloc.first_column); @@ -2070,140 +2100,140 @@ yyreduce: auto node = parser->ast()->createNodeList(); parser->pushStack(node); } -#line 2074 "arangod/Aql/grammar.cpp" /* yacc.c:1646 */ +#line 2104 "arangod/Aql/grammar.cpp" /* yacc.c:1646 */ break; - case 36: -#line 440 "arangod/Aql/grammar.y" /* yacc.c:1646 */ + case 37: +#line 467 "arangod/Aql/grammar.y" /* yacc.c:1646 */ { auto list = static_cast(parser->popStack()); (yyval.node) = list; } -#line 2083 "arangod/Aql/grammar.cpp" /* yacc.c:1646 */ +#line 2113 "arangod/Aql/grammar.cpp" /* yacc.c:1646 */ break; - case 37: -#line 447 "arangod/Aql/grammar.y" /* yacc.c:1646 */ + case 38: +#line 474 "arangod/Aql/grammar.y" /* yacc.c:1646 */ { auto node = parser->ast()->createNodeList(); parser->pushStack(node); } -#line 2092 "arangod/Aql/grammar.cpp" /* yacc.c:1646 */ +#line 2122 "arangod/Aql/grammar.cpp" /* yacc.c:1646 */ break; - case 38: -#line 450 "arangod/Aql/grammar.y" /* yacc.c:1646 */ + case 39: +#line 477 "arangod/Aql/grammar.y" /* yacc.c:1646 */ { auto list = static_cast(parser->popStack()); auto node = parser->ast()->createNodeSort(list); parser->ast()->addOperation(node); } -#line 2102 "arangod/Aql/grammar.cpp" /* yacc.c:1646 */ - break; - - case 39: -#line 458 "arangod/Aql/grammar.y" /* yacc.c:1646 */ - { - parser->pushList((yyvsp[0].node)); - } -#line 2110 "arangod/Aql/grammar.cpp" /* yacc.c:1646 */ +#line 2132 "arangod/Aql/grammar.cpp" /* yacc.c:1646 */ break; case 40: -#line 461 "arangod/Aql/grammar.y" /* yacc.c:1646 */ +#line 485 "arangod/Aql/grammar.y" /* yacc.c:1646 */ { parser->pushList((yyvsp[0].node)); } -#line 2118 "arangod/Aql/grammar.cpp" /* yacc.c:1646 */ +#line 2140 "arangod/Aql/grammar.cpp" /* yacc.c:1646 */ break; case 41: -#line 467 "arangod/Aql/grammar.y" /* yacc.c:1646 */ +#line 488 "arangod/Aql/grammar.y" /* yacc.c:1646 */ { - (yyval.node) = parser->ast()->createNodeSortElement((yyvsp[-1].node), (yyvsp[0].node)); + parser->pushList((yyvsp[0].node)); } -#line 2126 "arangod/Aql/grammar.cpp" /* yacc.c:1646 */ +#line 2148 "arangod/Aql/grammar.cpp" /* yacc.c:1646 */ break; case 42: -#line 473 "arangod/Aql/grammar.y" /* yacc.c:1646 */ +#line 494 "arangod/Aql/grammar.y" /* yacc.c:1646 */ { - (yyval.node) = parser->ast()->createNodeValueBool(true); + (yyval.node) = parser->ast()->createNodeSortElement((yyvsp[-1].node), (yyvsp[0].node)); } -#line 2134 "arangod/Aql/grammar.cpp" /* yacc.c:1646 */ +#line 2156 "arangod/Aql/grammar.cpp" /* yacc.c:1646 */ break; case 43: -#line 476 "arangod/Aql/grammar.y" /* yacc.c:1646 */ +#line 500 "arangod/Aql/grammar.y" /* yacc.c:1646 */ { (yyval.node) = parser->ast()->createNodeValueBool(true); } -#line 2142 "arangod/Aql/grammar.cpp" /* yacc.c:1646 */ +#line 2164 "arangod/Aql/grammar.cpp" /* yacc.c:1646 */ break; case 44: -#line 479 "arangod/Aql/grammar.y" /* yacc.c:1646 */ +#line 503 "arangod/Aql/grammar.y" /* yacc.c:1646 */ { - (yyval.node) = parser->ast()->createNodeValueBool(false); + (yyval.node) = parser->ast()->createNodeValueBool(true); } -#line 2150 "arangod/Aql/grammar.cpp" /* yacc.c:1646 */ +#line 2172 "arangod/Aql/grammar.cpp" /* yacc.c:1646 */ break; case 45: -#line 482 "arangod/Aql/grammar.y" /* yacc.c:1646 */ +#line 506 "arangod/Aql/grammar.y" /* yacc.c:1646 */ { - (yyval.node) = (yyvsp[0].node); + (yyval.node) = parser->ast()->createNodeValueBool(false); } -#line 2158 "arangod/Aql/grammar.cpp" /* yacc.c:1646 */ +#line 2180 "arangod/Aql/grammar.cpp" /* yacc.c:1646 */ break; case 46: -#line 488 "arangod/Aql/grammar.y" /* yacc.c:1646 */ +#line 509 "arangod/Aql/grammar.y" /* yacc.c:1646 */ + { + (yyval.node) = (yyvsp[0].node); + } +#line 2188 "arangod/Aql/grammar.cpp" /* yacc.c:1646 */ + break; + + case 47: +#line 515 "arangod/Aql/grammar.y" /* yacc.c:1646 */ { auto offset = parser->ast()->createNodeValueInt(0); auto node = parser->ast()->createNodeLimit(offset, (yyvsp[0].node)); parser->ast()->addOperation(node); } -#line 2168 "arangod/Aql/grammar.cpp" /* yacc.c:1646 */ +#line 2198 "arangod/Aql/grammar.cpp" /* yacc.c:1646 */ break; - case 47: -#line 493 "arangod/Aql/grammar.y" /* yacc.c:1646 */ + case 48: +#line 520 "arangod/Aql/grammar.y" /* yacc.c:1646 */ { auto node = parser->ast()->createNodeLimit((yyvsp[-2].node), (yyvsp[0].node)); parser->ast()->addOperation(node); } -#line 2177 "arangod/Aql/grammar.cpp" /* yacc.c:1646 */ +#line 2207 "arangod/Aql/grammar.cpp" /* yacc.c:1646 */ break; - case 48: -#line 500 "arangod/Aql/grammar.y" /* yacc.c:1646 */ + case 49: +#line 527 "arangod/Aql/grammar.y" /* yacc.c:1646 */ { auto node = parser->ast()->createNodeReturn((yyvsp[0].node)); parser->ast()->addOperation(node); parser->ast()->scopes()->endNested(); } -#line 2187 "arangod/Aql/grammar.cpp" /* yacc.c:1646 */ - break; - - case 49: -#line 508 "arangod/Aql/grammar.y" /* yacc.c:1646 */ - { - (yyval.node) = (yyvsp[0].node); - } -#line 2195 "arangod/Aql/grammar.cpp" /* yacc.c:1646 */ +#line 2217 "arangod/Aql/grammar.cpp" /* yacc.c:1646 */ break; case 50: -#line 511 "arangod/Aql/grammar.y" /* yacc.c:1646 */ +#line 535 "arangod/Aql/grammar.y" /* yacc.c:1646 */ { (yyval.node) = (yyvsp[0].node); } -#line 2203 "arangod/Aql/grammar.cpp" /* yacc.c:1646 */ +#line 2225 "arangod/Aql/grammar.cpp" /* yacc.c:1646 */ break; case 51: -#line 517 "arangod/Aql/grammar.y" /* yacc.c:1646 */ +#line 538 "arangod/Aql/grammar.y" /* yacc.c:1646 */ + { + (yyval.node) = (yyvsp[0].node); + } +#line 2233 "arangod/Aql/grammar.cpp" /* yacc.c:1646 */ + break; + + case 52: +#line 544 "arangod/Aql/grammar.y" /* yacc.c:1646 */ { if (! parser->configureWriteQuery(AQL_QUERY_REMOVE, (yyvsp[-1].node), (yyvsp[0].node))) { YYABORT; @@ -2212,11 +2242,11 @@ yyreduce: parser->ast()->addOperation(node); parser->ast()->scopes()->endNested(); } -#line 2216 "arangod/Aql/grammar.cpp" /* yacc.c:1646 */ +#line 2246 "arangod/Aql/grammar.cpp" /* yacc.c:1646 */ break; - case 52: -#line 528 "arangod/Aql/grammar.y" /* yacc.c:1646 */ + case 53: +#line 555 "arangod/Aql/grammar.y" /* yacc.c:1646 */ { if (! parser->configureWriteQuery(AQL_QUERY_INSERT, (yyvsp[-1].node), (yyvsp[0].node))) { YYABORT; @@ -2225,11 +2255,11 @@ yyreduce: parser->ast()->addOperation(node); parser->ast()->scopes()->endNested(); } -#line 2229 "arangod/Aql/grammar.cpp" /* yacc.c:1646 */ +#line 2259 "arangod/Aql/grammar.cpp" /* yacc.c:1646 */ break; - case 53: -#line 539 "arangod/Aql/grammar.y" /* yacc.c:1646 */ + case 54: +#line 566 "arangod/Aql/grammar.y" /* yacc.c:1646 */ { if (! parser->configureWriteQuery(AQL_QUERY_UPDATE, (yyvsp[-1].node), (yyvsp[0].node))) { YYABORT; @@ -2238,11 +2268,11 @@ yyreduce: parser->ast()->addOperation(node); parser->ast()->scopes()->endNested(); } -#line 2242 "arangod/Aql/grammar.cpp" /* yacc.c:1646 */ +#line 2272 "arangod/Aql/grammar.cpp" /* yacc.c:1646 */ break; - case 54: -#line 547 "arangod/Aql/grammar.y" /* yacc.c:1646 */ + case 55: +#line 574 "arangod/Aql/grammar.y" /* yacc.c:1646 */ { if (! parser->configureWriteQuery(AQL_QUERY_UPDATE, (yyvsp[-1].node), (yyvsp[0].node))) { YYABORT; @@ -2251,11 +2281,11 @@ yyreduce: parser->ast()->addOperation(node); parser->ast()->scopes()->endNested(); } -#line 2255 "arangod/Aql/grammar.cpp" /* yacc.c:1646 */ +#line 2285 "arangod/Aql/grammar.cpp" /* yacc.c:1646 */ break; - case 55: -#line 558 "arangod/Aql/grammar.y" /* yacc.c:1646 */ + case 56: +#line 585 "arangod/Aql/grammar.y" /* yacc.c:1646 */ { if (! parser->configureWriteQuery(AQL_QUERY_REPLACE, (yyvsp[-1].node), (yyvsp[0].node))) { YYABORT; @@ -2264,11 +2294,11 @@ yyreduce: parser->ast()->addOperation(node); parser->ast()->scopes()->endNested(); } -#line 2268 "arangod/Aql/grammar.cpp" /* yacc.c:1646 */ +#line 2298 "arangod/Aql/grammar.cpp" /* yacc.c:1646 */ break; - case 56: -#line 566 "arangod/Aql/grammar.y" /* yacc.c:1646 */ + case 57: +#line 593 "arangod/Aql/grammar.y" /* yacc.c:1646 */ { if (! parser->configureWriteQuery(AQL_QUERY_REPLACE, (yyvsp[-1].node), (yyvsp[0].node))) { YYABORT; @@ -2277,28 +2307,28 @@ yyreduce: parser->ast()->addOperation(node); parser->ast()->scopes()->endNested(); } -#line 2281 "arangod/Aql/grammar.cpp" /* yacc.c:1646 */ - break; - - case 57: -#line 577 "arangod/Aql/grammar.y" /* yacc.c:1646 */ - { - (yyval.node) = (yyvsp[-1].node); - } -#line 2289 "arangod/Aql/grammar.cpp" /* yacc.c:1646 */ +#line 2311 "arangod/Aql/grammar.cpp" /* yacc.c:1646 */ break; case 58: -#line 580 "arangod/Aql/grammar.y" /* yacc.c:1646 */ +#line 604 "arangod/Aql/grammar.y" /* yacc.c:1646 */ + { + (yyval.node) = (yyvsp[-1].node); + } +#line 2319 "arangod/Aql/grammar.cpp" /* yacc.c:1646 */ + break; + + case 59: +#line 607 "arangod/Aql/grammar.y" /* yacc.c:1646 */ { parser->ast()->scopes()->start(triagens::aql::AQL_SCOPE_SUBQUERY); parser->ast()->startSubQuery(); } -#line 2298 "arangod/Aql/grammar.cpp" /* yacc.c:1646 */ +#line 2328 "arangod/Aql/grammar.cpp" /* yacc.c:1646 */ break; - case 59: -#line 583 "arangod/Aql/grammar.y" /* yacc.c:1646 */ + case 60: +#line 610 "arangod/Aql/grammar.y" /* yacc.c:1646 */ { AstNode* node = parser->ast()->endSubQuery(); parser->ast()->scopes()->endCurrent(); @@ -2309,67 +2339,67 @@ yyreduce: (yyval.node) = parser->ast()->createNodeReference(variableName.c_str()); } -#line 2313 "arangod/Aql/grammar.cpp" /* yacc.c:1646 */ - break; - - case 60: -#line 593 "arangod/Aql/grammar.y" /* yacc.c:1646 */ - { - (yyval.node) = (yyvsp[0].node); - } -#line 2321 "arangod/Aql/grammar.cpp" /* yacc.c:1646 */ +#line 2343 "arangod/Aql/grammar.cpp" /* yacc.c:1646 */ break; case 61: -#line 596 "arangod/Aql/grammar.y" /* yacc.c:1646 */ +#line 620 "arangod/Aql/grammar.y" /* yacc.c:1646 */ { (yyval.node) = (yyvsp[0].node); } -#line 2329 "arangod/Aql/grammar.cpp" /* yacc.c:1646 */ +#line 2351 "arangod/Aql/grammar.cpp" /* yacc.c:1646 */ break; case 62: -#line 599 "arangod/Aql/grammar.y" /* yacc.c:1646 */ +#line 623 "arangod/Aql/grammar.y" /* yacc.c:1646 */ { (yyval.node) = (yyvsp[0].node); } -#line 2337 "arangod/Aql/grammar.cpp" /* yacc.c:1646 */ +#line 2359 "arangod/Aql/grammar.cpp" /* yacc.c:1646 */ break; case 63: -#line 602 "arangod/Aql/grammar.y" /* yacc.c:1646 */ +#line 626 "arangod/Aql/grammar.y" /* yacc.c:1646 */ { (yyval.node) = (yyvsp[0].node); } -#line 2345 "arangod/Aql/grammar.cpp" /* yacc.c:1646 */ +#line 2367 "arangod/Aql/grammar.cpp" /* yacc.c:1646 */ break; case 64: -#line 605 "arangod/Aql/grammar.y" /* yacc.c:1646 */ +#line 629 "arangod/Aql/grammar.y" /* yacc.c:1646 */ { (yyval.node) = (yyvsp[0].node); } -#line 2353 "arangod/Aql/grammar.cpp" /* yacc.c:1646 */ +#line 2375 "arangod/Aql/grammar.cpp" /* yacc.c:1646 */ break; case 65: -#line 608 "arangod/Aql/grammar.y" /* yacc.c:1646 */ +#line 632 "arangod/Aql/grammar.y" /* yacc.c:1646 */ { (yyval.node) = (yyvsp[0].node); } -#line 2361 "arangod/Aql/grammar.cpp" /* yacc.c:1646 */ +#line 2383 "arangod/Aql/grammar.cpp" /* yacc.c:1646 */ break; case 66: -#line 611 "arangod/Aql/grammar.y" /* yacc.c:1646 */ +#line 635 "arangod/Aql/grammar.y" /* yacc.c:1646 */ { - (yyval.node) = parser->ast()->createNodeRange((yyvsp[-2].node), (yyvsp[0].node)); + (yyval.node) = (yyvsp[0].node); } -#line 2369 "arangod/Aql/grammar.cpp" /* yacc.c:1646 */ +#line 2391 "arangod/Aql/grammar.cpp" /* yacc.c:1646 */ break; case 67: -#line 617 "arangod/Aql/grammar.y" /* yacc.c:1646 */ +#line 638 "arangod/Aql/grammar.y" /* yacc.c:1646 */ + { + (yyval.node) = parser->ast()->createNodeRange((yyvsp[-2].node), (yyvsp[0].node)); + } +#line 2399 "arangod/Aql/grammar.cpp" /* yacc.c:1646 */ + break; + + case 68: +#line 644 "arangod/Aql/grammar.y" /* yacc.c:1646 */ { (yyval.strval) = (yyvsp[0].strval); @@ -2377,11 +2407,11 @@ yyreduce: ABORT_OOM } } -#line 2381 "arangod/Aql/grammar.cpp" /* yacc.c:1646 */ +#line 2411 "arangod/Aql/grammar.cpp" /* yacc.c:1646 */ break; - case 68: -#line 624 "arangod/Aql/grammar.y" /* yacc.c:1646 */ + case 69: +#line 651 "arangod/Aql/grammar.y" /* yacc.c:1646 */ { if ((yyvsp[-2].strval) == nullptr || (yyvsp[0].strval) == nullptr) { ABORT_OOM @@ -2396,214 +2426,214 @@ yyreduce: ABORT_OOM } } -#line 2400 "arangod/Aql/grammar.cpp" /* yacc.c:1646 */ +#line 2430 "arangod/Aql/grammar.cpp" /* yacc.c:1646 */ break; - case 69: -#line 641 "arangod/Aql/grammar.y" /* yacc.c:1646 */ + case 70: +#line 668 "arangod/Aql/grammar.y" /* yacc.c:1646 */ { parser->pushStack((yyvsp[0].strval)); auto node = parser->ast()->createNodeList(); parser->pushStack(node); } -#line 2411 "arangod/Aql/grammar.cpp" /* yacc.c:1646 */ +#line 2441 "arangod/Aql/grammar.cpp" /* yacc.c:1646 */ break; - case 70: -#line 646 "arangod/Aql/grammar.y" /* yacc.c:1646 */ + case 71: +#line 673 "arangod/Aql/grammar.y" /* yacc.c:1646 */ { auto list = static_cast(parser->popStack()); (yyval.node) = parser->ast()->createNodeFunctionCall(static_cast(parser->popStack()), list); } -#line 2420 "arangod/Aql/grammar.cpp" /* yacc.c:1646 */ - break; - - case 71: -#line 653 "arangod/Aql/grammar.y" /* yacc.c:1646 */ - { - (yyval.node) = parser->ast()->createNodeUnaryOperator(NODE_TYPE_OPERATOR_UNARY_PLUS, (yyvsp[0].node)); - } -#line 2428 "arangod/Aql/grammar.cpp" /* yacc.c:1646 */ +#line 2450 "arangod/Aql/grammar.cpp" /* yacc.c:1646 */ break; case 72: -#line 656 "arangod/Aql/grammar.y" /* yacc.c:1646 */ +#line 680 "arangod/Aql/grammar.y" /* yacc.c:1646 */ { - (yyval.node) = parser->ast()->createNodeUnaryOperator(NODE_TYPE_OPERATOR_UNARY_MINUS, (yyvsp[0].node)); + (yyval.node) = parser->ast()->createNodeUnaryOperator(NODE_TYPE_OPERATOR_UNARY_PLUS, (yyvsp[0].node)); } -#line 2436 "arangod/Aql/grammar.cpp" /* yacc.c:1646 */ +#line 2458 "arangod/Aql/grammar.cpp" /* yacc.c:1646 */ break; case 73: -#line 659 "arangod/Aql/grammar.y" /* yacc.c:1646 */ - { - (yyval.node) = parser->ast()->createNodeUnaryOperator(NODE_TYPE_OPERATOR_UNARY_NOT, (yyvsp[0].node)); +#line 683 "arangod/Aql/grammar.y" /* yacc.c:1646 */ + { + (yyval.node) = parser->ast()->createNodeUnaryOperator(NODE_TYPE_OPERATOR_UNARY_MINUS, (yyvsp[0].node)); } -#line 2444 "arangod/Aql/grammar.cpp" /* yacc.c:1646 */ +#line 2466 "arangod/Aql/grammar.cpp" /* yacc.c:1646 */ break; case 74: -#line 665 "arangod/Aql/grammar.y" /* yacc.c:1646 */ - { - (yyval.node) = parser->ast()->createNodeBinaryOperator(NODE_TYPE_OPERATOR_BINARY_OR, (yyvsp[-2].node), (yyvsp[0].node)); +#line 686 "arangod/Aql/grammar.y" /* yacc.c:1646 */ + { + (yyval.node) = parser->ast()->createNodeUnaryOperator(NODE_TYPE_OPERATOR_UNARY_NOT, (yyvsp[0].node)); } -#line 2452 "arangod/Aql/grammar.cpp" /* yacc.c:1646 */ +#line 2474 "arangod/Aql/grammar.cpp" /* yacc.c:1646 */ break; case 75: -#line 668 "arangod/Aql/grammar.y" /* yacc.c:1646 */ +#line 692 "arangod/Aql/grammar.y" /* yacc.c:1646 */ { - (yyval.node) = parser->ast()->createNodeBinaryOperator(NODE_TYPE_OPERATOR_BINARY_AND, (yyvsp[-2].node), (yyvsp[0].node)); + (yyval.node) = parser->ast()->createNodeBinaryOperator(NODE_TYPE_OPERATOR_BINARY_OR, (yyvsp[-2].node), (yyvsp[0].node)); } -#line 2460 "arangod/Aql/grammar.cpp" /* yacc.c:1646 */ +#line 2482 "arangod/Aql/grammar.cpp" /* yacc.c:1646 */ break; case 76: -#line 671 "arangod/Aql/grammar.y" /* yacc.c:1646 */ +#line 695 "arangod/Aql/grammar.y" /* yacc.c:1646 */ { - (yyval.node) = parser->ast()->createNodeBinaryOperator(NODE_TYPE_OPERATOR_BINARY_PLUS, (yyvsp[-2].node), (yyvsp[0].node)); + (yyval.node) = parser->ast()->createNodeBinaryOperator(NODE_TYPE_OPERATOR_BINARY_AND, (yyvsp[-2].node), (yyvsp[0].node)); } -#line 2468 "arangod/Aql/grammar.cpp" /* yacc.c:1646 */ +#line 2490 "arangod/Aql/grammar.cpp" /* yacc.c:1646 */ break; case 77: -#line 674 "arangod/Aql/grammar.y" /* yacc.c:1646 */ +#line 698 "arangod/Aql/grammar.y" /* yacc.c:1646 */ { - (yyval.node) = parser->ast()->createNodeBinaryOperator(NODE_TYPE_OPERATOR_BINARY_MINUS, (yyvsp[-2].node), (yyvsp[0].node)); + (yyval.node) = parser->ast()->createNodeBinaryOperator(NODE_TYPE_OPERATOR_BINARY_PLUS, (yyvsp[-2].node), (yyvsp[0].node)); } -#line 2476 "arangod/Aql/grammar.cpp" /* yacc.c:1646 */ +#line 2498 "arangod/Aql/grammar.cpp" /* yacc.c:1646 */ break; case 78: -#line 677 "arangod/Aql/grammar.y" /* yacc.c:1646 */ +#line 701 "arangod/Aql/grammar.y" /* yacc.c:1646 */ { - (yyval.node) = parser->ast()->createNodeBinaryOperator(NODE_TYPE_OPERATOR_BINARY_TIMES, (yyvsp[-2].node), (yyvsp[0].node)); + (yyval.node) = parser->ast()->createNodeBinaryOperator(NODE_TYPE_OPERATOR_BINARY_MINUS, (yyvsp[-2].node), (yyvsp[0].node)); } -#line 2484 "arangod/Aql/grammar.cpp" /* yacc.c:1646 */ +#line 2506 "arangod/Aql/grammar.cpp" /* yacc.c:1646 */ break; case 79: -#line 680 "arangod/Aql/grammar.y" /* yacc.c:1646 */ +#line 704 "arangod/Aql/grammar.y" /* yacc.c:1646 */ { - (yyval.node) = parser->ast()->createNodeBinaryOperator(NODE_TYPE_OPERATOR_BINARY_DIV, (yyvsp[-2].node), (yyvsp[0].node)); + (yyval.node) = parser->ast()->createNodeBinaryOperator(NODE_TYPE_OPERATOR_BINARY_TIMES, (yyvsp[-2].node), (yyvsp[0].node)); } -#line 2492 "arangod/Aql/grammar.cpp" /* yacc.c:1646 */ +#line 2514 "arangod/Aql/grammar.cpp" /* yacc.c:1646 */ break; case 80: -#line 683 "arangod/Aql/grammar.y" /* yacc.c:1646 */ +#line 707 "arangod/Aql/grammar.y" /* yacc.c:1646 */ { - (yyval.node) = parser->ast()->createNodeBinaryOperator(NODE_TYPE_OPERATOR_BINARY_MOD, (yyvsp[-2].node), (yyvsp[0].node)); + (yyval.node) = parser->ast()->createNodeBinaryOperator(NODE_TYPE_OPERATOR_BINARY_DIV, (yyvsp[-2].node), (yyvsp[0].node)); } -#line 2500 "arangod/Aql/grammar.cpp" /* yacc.c:1646 */ +#line 2522 "arangod/Aql/grammar.cpp" /* yacc.c:1646 */ break; case 81: -#line 686 "arangod/Aql/grammar.y" /* yacc.c:1646 */ +#line 710 "arangod/Aql/grammar.y" /* yacc.c:1646 */ { - (yyval.node) = parser->ast()->createNodeBinaryOperator(NODE_TYPE_OPERATOR_BINARY_EQ, (yyvsp[-2].node), (yyvsp[0].node)); + (yyval.node) = parser->ast()->createNodeBinaryOperator(NODE_TYPE_OPERATOR_BINARY_MOD, (yyvsp[-2].node), (yyvsp[0].node)); } -#line 2508 "arangod/Aql/grammar.cpp" /* yacc.c:1646 */ +#line 2530 "arangod/Aql/grammar.cpp" /* yacc.c:1646 */ break; case 82: -#line 689 "arangod/Aql/grammar.y" /* yacc.c:1646 */ +#line 713 "arangod/Aql/grammar.y" /* yacc.c:1646 */ { - (yyval.node) = parser->ast()->createNodeBinaryOperator(NODE_TYPE_OPERATOR_BINARY_NE, (yyvsp[-2].node), (yyvsp[0].node)); + (yyval.node) = parser->ast()->createNodeBinaryOperator(NODE_TYPE_OPERATOR_BINARY_EQ, (yyvsp[-2].node), (yyvsp[0].node)); } -#line 2516 "arangod/Aql/grammar.cpp" /* yacc.c:1646 */ +#line 2538 "arangod/Aql/grammar.cpp" /* yacc.c:1646 */ break; case 83: -#line 692 "arangod/Aql/grammar.y" /* yacc.c:1646 */ +#line 716 "arangod/Aql/grammar.y" /* yacc.c:1646 */ { - (yyval.node) = parser->ast()->createNodeBinaryOperator(NODE_TYPE_OPERATOR_BINARY_LT, (yyvsp[-2].node), (yyvsp[0].node)); + (yyval.node) = parser->ast()->createNodeBinaryOperator(NODE_TYPE_OPERATOR_BINARY_NE, (yyvsp[-2].node), (yyvsp[0].node)); } -#line 2524 "arangod/Aql/grammar.cpp" /* yacc.c:1646 */ +#line 2546 "arangod/Aql/grammar.cpp" /* yacc.c:1646 */ break; case 84: -#line 695 "arangod/Aql/grammar.y" /* yacc.c:1646 */ +#line 719 "arangod/Aql/grammar.y" /* yacc.c:1646 */ { - (yyval.node) = parser->ast()->createNodeBinaryOperator(NODE_TYPE_OPERATOR_BINARY_GT, (yyvsp[-2].node), (yyvsp[0].node)); + (yyval.node) = parser->ast()->createNodeBinaryOperator(NODE_TYPE_OPERATOR_BINARY_LT, (yyvsp[-2].node), (yyvsp[0].node)); } -#line 2532 "arangod/Aql/grammar.cpp" /* yacc.c:1646 */ +#line 2554 "arangod/Aql/grammar.cpp" /* yacc.c:1646 */ break; case 85: -#line 698 "arangod/Aql/grammar.y" /* yacc.c:1646 */ +#line 722 "arangod/Aql/grammar.y" /* yacc.c:1646 */ { - (yyval.node) = parser->ast()->createNodeBinaryOperator(NODE_TYPE_OPERATOR_BINARY_LE, (yyvsp[-2].node), (yyvsp[0].node)); + (yyval.node) = parser->ast()->createNodeBinaryOperator(NODE_TYPE_OPERATOR_BINARY_GT, (yyvsp[-2].node), (yyvsp[0].node)); } -#line 2540 "arangod/Aql/grammar.cpp" /* yacc.c:1646 */ +#line 2562 "arangod/Aql/grammar.cpp" /* yacc.c:1646 */ break; case 86: -#line 701 "arangod/Aql/grammar.y" /* yacc.c:1646 */ +#line 725 "arangod/Aql/grammar.y" /* yacc.c:1646 */ { - (yyval.node) = parser->ast()->createNodeBinaryOperator(NODE_TYPE_OPERATOR_BINARY_GE, (yyvsp[-2].node), (yyvsp[0].node)); + (yyval.node) = parser->ast()->createNodeBinaryOperator(NODE_TYPE_OPERATOR_BINARY_LE, (yyvsp[-2].node), (yyvsp[0].node)); } -#line 2548 "arangod/Aql/grammar.cpp" /* yacc.c:1646 */ +#line 2570 "arangod/Aql/grammar.cpp" /* yacc.c:1646 */ break; case 87: -#line 704 "arangod/Aql/grammar.y" /* yacc.c:1646 */ +#line 728 "arangod/Aql/grammar.y" /* yacc.c:1646 */ { - (yyval.node) = parser->ast()->createNodeBinaryOperator(NODE_TYPE_OPERATOR_BINARY_IN, (yyvsp[-2].node), (yyvsp[0].node)); + (yyval.node) = parser->ast()->createNodeBinaryOperator(NODE_TYPE_OPERATOR_BINARY_GE, (yyvsp[-2].node), (yyvsp[0].node)); } -#line 2556 "arangod/Aql/grammar.cpp" /* yacc.c:1646 */ +#line 2578 "arangod/Aql/grammar.cpp" /* yacc.c:1646 */ break; case 88: -#line 707 "arangod/Aql/grammar.y" /* yacc.c:1646 */ - { - (yyval.node) = parser->ast()->createNodeBinaryOperator(NODE_TYPE_OPERATOR_BINARY_NIN, (yyvsp[-3].node), (yyvsp[0].node)); - } -#line 2564 "arangod/Aql/grammar.cpp" /* yacc.c:1646 */ - break; - - case 89: -#line 713 "arangod/Aql/grammar.y" /* yacc.c:1646 */ - { - (yyval.node) = parser->ast()->createNodeTernaryOperator((yyvsp[-4].node), (yyvsp[-2].node), (yyvsp[0].node)); - } -#line 2572 "arangod/Aql/grammar.cpp" /* yacc.c:1646 */ - break; - - case 90: -#line 719 "arangod/Aql/grammar.y" /* yacc.c:1646 */ - { - } -#line 2579 "arangod/Aql/grammar.cpp" /* yacc.c:1646 */ - break; - - case 91: -#line 721 "arangod/Aql/grammar.y" /* yacc.c:1646 */ +#line 731 "arangod/Aql/grammar.y" /* yacc.c:1646 */ { + (yyval.node) = parser->ast()->createNodeBinaryOperator(NODE_TYPE_OPERATOR_BINARY_IN, (yyvsp[-2].node), (yyvsp[0].node)); } #line 2586 "arangod/Aql/grammar.cpp" /* yacc.c:1646 */ break; - case 92: -#line 726 "arangod/Aql/grammar.y" /* yacc.c:1646 */ + case 89: +#line 734 "arangod/Aql/grammar.y" /* yacc.c:1646 */ { - (yyval.node) = (yyvsp[0].node); + (yyval.node) = parser->ast()->createNodeBinaryOperator(NODE_TYPE_OPERATOR_BINARY_NIN, (yyvsp[-3].node), (yyvsp[0].node)); } #line 2594 "arangod/Aql/grammar.cpp" /* yacc.c:1646 */ break; + case 90: +#line 740 "arangod/Aql/grammar.y" /* yacc.c:1646 */ + { + (yyval.node) = parser->ast()->createNodeTernaryOperator((yyvsp[-4].node), (yyvsp[-2].node), (yyvsp[0].node)); + } +#line 2602 "arangod/Aql/grammar.cpp" /* yacc.c:1646 */ + break; + + case 91: +#line 746 "arangod/Aql/grammar.y" /* yacc.c:1646 */ + { + } +#line 2609 "arangod/Aql/grammar.cpp" /* yacc.c:1646 */ + break; + + case 92: +#line 748 "arangod/Aql/grammar.y" /* yacc.c:1646 */ + { + } +#line 2616 "arangod/Aql/grammar.cpp" /* yacc.c:1646 */ + break; + case 93: -#line 729 "arangod/Aql/grammar.y" /* yacc.c:1646 */ +#line 753 "arangod/Aql/grammar.y" /* yacc.c:1646 */ + { + (yyval.node) = (yyvsp[0].node); + } +#line 2624 "arangod/Aql/grammar.cpp" /* yacc.c:1646 */ + break; + + case 94: +#line 756 "arangod/Aql/grammar.y" /* yacc.c:1646 */ { parser->ast()->scopes()->start(triagens::aql::AQL_SCOPE_SUBQUERY); parser->ast()->startSubQuery(); } -#line 2603 "arangod/Aql/grammar.cpp" /* yacc.c:1646 */ +#line 2633 "arangod/Aql/grammar.cpp" /* yacc.c:1646 */ break; - case 94: -#line 732 "arangod/Aql/grammar.y" /* yacc.c:1646 */ + case 95: +#line 759 "arangod/Aql/grammar.y" /* yacc.c:1646 */ { AstNode* node = parser->ast()->endSubQuery(); parser->ast()->scopes()->endCurrent(); @@ -2614,98 +2644,98 @@ yyreduce: (yyval.node) = parser->ast()->createNodeReference(variableName.c_str()); } -#line 2618 "arangod/Aql/grammar.cpp" /* yacc.c:1646 */ - break; - - case 95: -#line 745 "arangod/Aql/grammar.y" /* yacc.c:1646 */ - { - parser->pushList((yyvsp[0].node)); - } -#line 2626 "arangod/Aql/grammar.cpp" /* yacc.c:1646 */ +#line 2648 "arangod/Aql/grammar.cpp" /* yacc.c:1646 */ break; case 96: -#line 748 "arangod/Aql/grammar.y" /* yacc.c:1646 */ +#line 772 "arangod/Aql/grammar.y" /* yacc.c:1646 */ { parser->pushList((yyvsp[0].node)); } -#line 2634 "arangod/Aql/grammar.cpp" /* yacc.c:1646 */ +#line 2656 "arangod/Aql/grammar.cpp" /* yacc.c:1646 */ break; case 97: -#line 754 "arangod/Aql/grammar.y" /* yacc.c:1646 */ +#line 775 "arangod/Aql/grammar.y" /* yacc.c:1646 */ { - (yyval.node) = (yyvsp[0].node); + parser->pushList((yyvsp[0].node)); } -#line 2642 "arangod/Aql/grammar.cpp" /* yacc.c:1646 */ +#line 2664 "arangod/Aql/grammar.cpp" /* yacc.c:1646 */ break; case 98: -#line 757 "arangod/Aql/grammar.y" /* yacc.c:1646 */ +#line 781 "arangod/Aql/grammar.y" /* yacc.c:1646 */ { (yyval.node) = (yyvsp[0].node); } -#line 2650 "arangod/Aql/grammar.cpp" /* yacc.c:1646 */ +#line 2672 "arangod/Aql/grammar.cpp" /* yacc.c:1646 */ break; case 99: -#line 763 "arangod/Aql/grammar.y" /* yacc.c:1646 */ +#line 784 "arangod/Aql/grammar.y" /* yacc.c:1646 */ + { + (yyval.node) = (yyvsp[0].node); + } +#line 2680 "arangod/Aql/grammar.cpp" /* yacc.c:1646 */ + break; + + case 100: +#line 790 "arangod/Aql/grammar.y" /* yacc.c:1646 */ { auto node = parser->ast()->createNodeList(); parser->pushStack(node); } -#line 2659 "arangod/Aql/grammar.cpp" /* yacc.c:1646 */ - break; - - case 100: -#line 766 "arangod/Aql/grammar.y" /* yacc.c:1646 */ - { - (yyval.node) = static_cast(parser->popStack()); - } -#line 2667 "arangod/Aql/grammar.cpp" /* yacc.c:1646 */ - break; - - case 101: -#line 772 "arangod/Aql/grammar.y" /* yacc.c:1646 */ - { - } -#line 2674 "arangod/Aql/grammar.cpp" /* yacc.c:1646 */ - break; - - case 102: -#line 774 "arangod/Aql/grammar.y" /* yacc.c:1646 */ - { - } -#line 2681 "arangod/Aql/grammar.cpp" /* yacc.c:1646 */ - break; - - case 103: -#line 779 "arangod/Aql/grammar.y" /* yacc.c:1646 */ - { - parser->pushList((yyvsp[0].node)); - } #line 2689 "arangod/Aql/grammar.cpp" /* yacc.c:1646 */ break; - case 104: -#line 782 "arangod/Aql/grammar.y" /* yacc.c:1646 */ + case 101: +#line 793 "arangod/Aql/grammar.y" /* yacc.c:1646 */ { - parser->pushList((yyvsp[0].node)); + (yyval.node) = static_cast(parser->popStack()); } #line 2697 "arangod/Aql/grammar.cpp" /* yacc.c:1646 */ break; - case 105: -#line 788 "arangod/Aql/grammar.y" /* yacc.c:1646 */ + case 102: +#line 799 "arangod/Aql/grammar.y" /* yacc.c:1646 */ { - (yyval.node) = nullptr; } -#line 2705 "arangod/Aql/grammar.cpp" /* yacc.c:1646 */ +#line 2704 "arangod/Aql/grammar.cpp" /* yacc.c:1646 */ + break; + + case 103: +#line 801 "arangod/Aql/grammar.y" /* yacc.c:1646 */ + { + } +#line 2711 "arangod/Aql/grammar.cpp" /* yacc.c:1646 */ + break; + + case 104: +#line 806 "arangod/Aql/grammar.y" /* yacc.c:1646 */ + { + parser->pushList((yyvsp[0].node)); + } +#line 2719 "arangod/Aql/grammar.cpp" /* yacc.c:1646 */ + break; + + case 105: +#line 809 "arangod/Aql/grammar.y" /* yacc.c:1646 */ + { + parser->pushList((yyvsp[0].node)); + } +#line 2727 "arangod/Aql/grammar.cpp" /* yacc.c:1646 */ break; case 106: -#line 791 "arangod/Aql/grammar.y" /* yacc.c:1646 */ +#line 815 "arangod/Aql/grammar.y" /* yacc.c:1646 */ + { + (yyval.node) = nullptr; + } +#line 2735 "arangod/Aql/grammar.cpp" /* yacc.c:1646 */ + break; + + case 107: +#line 818 "arangod/Aql/grammar.y" /* yacc.c:1646 */ { if ((yyvsp[-1].strval) == nullptr || (yyvsp[0].node) == nullptr) { ABORT_OOM @@ -2717,73 +2747,73 @@ yyreduce: (yyval.node) = (yyvsp[0].node); } -#line 2721 "arangod/Aql/grammar.cpp" /* yacc.c:1646 */ +#line 2751 "arangod/Aql/grammar.cpp" /* yacc.c:1646 */ break; - case 107: -#line 805 "arangod/Aql/grammar.y" /* yacc.c:1646 */ + case 108: +#line 832 "arangod/Aql/grammar.y" /* yacc.c:1646 */ { auto node = parser->ast()->createNodeArray(); parser->pushStack(node); } -#line 2730 "arangod/Aql/grammar.cpp" /* yacc.c:1646 */ - break; - - case 108: -#line 808 "arangod/Aql/grammar.y" /* yacc.c:1646 */ - { - (yyval.node) = static_cast(parser->popStack()); - } -#line 2738 "arangod/Aql/grammar.cpp" /* yacc.c:1646 */ +#line 2760 "arangod/Aql/grammar.cpp" /* yacc.c:1646 */ break; case 109: -#line 814 "arangod/Aql/grammar.y" /* yacc.c:1646 */ +#line 835 "arangod/Aql/grammar.y" /* yacc.c:1646 */ { + (yyval.node) = static_cast(parser->popStack()); } -#line 2745 "arangod/Aql/grammar.cpp" /* yacc.c:1646 */ +#line 2768 "arangod/Aql/grammar.cpp" /* yacc.c:1646 */ break; case 110: -#line 816 "arangod/Aql/grammar.y" /* yacc.c:1646 */ +#line 841 "arangod/Aql/grammar.y" /* yacc.c:1646 */ { } -#line 2752 "arangod/Aql/grammar.cpp" /* yacc.c:1646 */ +#line 2775 "arangod/Aql/grammar.cpp" /* yacc.c:1646 */ break; case 111: -#line 821 "arangod/Aql/grammar.y" /* yacc.c:1646 */ +#line 843 "arangod/Aql/grammar.y" /* yacc.c:1646 */ { } -#line 2759 "arangod/Aql/grammar.cpp" /* yacc.c:1646 */ +#line 2782 "arangod/Aql/grammar.cpp" /* yacc.c:1646 */ break; case 112: -#line 823 "arangod/Aql/grammar.y" /* yacc.c:1646 */ +#line 848 "arangod/Aql/grammar.y" /* yacc.c:1646 */ { } -#line 2766 "arangod/Aql/grammar.cpp" /* yacc.c:1646 */ +#line 2789 "arangod/Aql/grammar.cpp" /* yacc.c:1646 */ break; case 113: -#line 828 "arangod/Aql/grammar.y" /* yacc.c:1646 */ +#line 850 "arangod/Aql/grammar.y" /* yacc.c:1646 */ { - parser->pushArray((yyvsp[-2].strval), (yyvsp[0].node)); } -#line 2774 "arangod/Aql/grammar.cpp" /* yacc.c:1646 */ +#line 2796 "arangod/Aql/grammar.cpp" /* yacc.c:1646 */ break; case 114: -#line 834 "arangod/Aql/grammar.y" /* yacc.c:1646 */ +#line 855 "arangod/Aql/grammar.y" /* yacc.c:1646 */ + { + parser->pushArray((yyvsp[-2].strval), (yyvsp[0].node)); + } +#line 2804 "arangod/Aql/grammar.cpp" /* yacc.c:1646 */ + break; + + case 115: +#line 861 "arangod/Aql/grammar.y" /* yacc.c:1646 */ { // start of reference (collection or variable name) (yyval.node) = (yyvsp[0].node); } -#line 2783 "arangod/Aql/grammar.cpp" /* yacc.c:1646 */ +#line 2813 "arangod/Aql/grammar.cpp" /* yacc.c:1646 */ break; - case 115: -#line 838 "arangod/Aql/grammar.y" /* yacc.c:1646 */ + case 116: +#line 865 "arangod/Aql/grammar.y" /* yacc.c:1646 */ { // expanded variable access, e.g. variable[*] @@ -2795,11 +2825,11 @@ yyreduce: parser->pushStack(iterator); parser->pushStack(parser->ast()->createNodeReference(iteratorName)); } -#line 2799 "arangod/Aql/grammar.cpp" /* yacc.c:1646 */ +#line 2829 "arangod/Aql/grammar.cpp" /* yacc.c:1646 */ break; - case 116: -#line 848 "arangod/Aql/grammar.y" /* yacc.c:1646 */ + case 117: +#line 875 "arangod/Aql/grammar.y" /* yacc.c:1646 */ { // return from the "expansion" subrule @@ -2815,11 +2845,11 @@ yyreduce: // return a reference only (yyval.node) = parser->ast()->createNodeReference(variableName); } -#line 2819 "arangod/Aql/grammar.cpp" /* yacc.c:1646 */ +#line 2849 "arangod/Aql/grammar.cpp" /* yacc.c:1646 */ break; - case 117: -#line 866 "arangod/Aql/grammar.y" /* yacc.c:1646 */ + case 118: +#line 893 "arangod/Aql/grammar.y" /* yacc.c:1646 */ { // variable or collection AstNode* node; @@ -2833,11 +2863,11 @@ yyreduce: (yyval.node) = node; } -#line 2837 "arangod/Aql/grammar.cpp" /* yacc.c:1646 */ +#line 2867 "arangod/Aql/grammar.cpp" /* yacc.c:1646 */ break; - case 118: -#line 879 "arangod/Aql/grammar.y" /* yacc.c:1646 */ + case 119: +#line 906 "arangod/Aql/grammar.y" /* yacc.c:1646 */ { (yyval.node) = (yyvsp[0].node); @@ -2845,119 +2875,119 @@ yyreduce: ABORT_OOM } } -#line 2849 "arangod/Aql/grammar.cpp" /* yacc.c:1646 */ +#line 2879 "arangod/Aql/grammar.cpp" /* yacc.c:1646 */ break; - case 119: -#line 886 "arangod/Aql/grammar.y" /* yacc.c:1646 */ + case 120: +#line 913 "arangod/Aql/grammar.y" /* yacc.c:1646 */ { // named variable access, e.g. variable.reference (yyval.node) = parser->ast()->createNodeAttributeAccess((yyvsp[-2].node), (yyvsp[0].strval)); } -#line 2858 "arangod/Aql/grammar.cpp" /* yacc.c:1646 */ +#line 2888 "arangod/Aql/grammar.cpp" /* yacc.c:1646 */ break; - case 120: -#line 890 "arangod/Aql/grammar.y" /* yacc.c:1646 */ + case 121: +#line 917 "arangod/Aql/grammar.y" /* yacc.c:1646 */ { // named variable access, e.g. variable.@reference (yyval.node) = parser->ast()->createNodeBoundAttributeAccess((yyvsp[-2].node), (yyvsp[0].node)); } -#line 2867 "arangod/Aql/grammar.cpp" /* yacc.c:1646 */ +#line 2897 "arangod/Aql/grammar.cpp" /* yacc.c:1646 */ break; - case 121: -#line 894 "arangod/Aql/grammar.y" /* yacc.c:1646 */ + case 122: +#line 921 "arangod/Aql/grammar.y" /* yacc.c:1646 */ { // indexed variable access, e.g. variable[index] (yyval.node) = parser->ast()->createNodeIndexedAccess((yyvsp[-3].node), (yyvsp[-1].node)); } -#line 2876 "arangod/Aql/grammar.cpp" /* yacc.c:1646 */ +#line 2906 "arangod/Aql/grammar.cpp" /* yacc.c:1646 */ break; - case 122: -#line 901 "arangod/Aql/grammar.y" /* yacc.c:1646 */ + case 123: +#line 928 "arangod/Aql/grammar.y" /* yacc.c:1646 */ { // named variable access, continuation from * expansion, e.g. [*].variable.reference auto node = static_cast(parser->popStack()); (yyval.node) = parser->ast()->createNodeAttributeAccess(node, (yyvsp[0].strval)); } -#line 2886 "arangod/Aql/grammar.cpp" /* yacc.c:1646 */ +#line 2916 "arangod/Aql/grammar.cpp" /* yacc.c:1646 */ break; - case 123: -#line 906 "arangod/Aql/grammar.y" /* yacc.c:1646 */ + case 124: +#line 933 "arangod/Aql/grammar.y" /* yacc.c:1646 */ { // named variable access w/ bind parameter, continuation from * expansion, e.g. [*].variable.@reference auto node = static_cast(parser->popStack()); (yyval.node) = parser->ast()->createNodeBoundAttributeAccess(node, (yyvsp[0].node)); } -#line 2896 "arangod/Aql/grammar.cpp" /* yacc.c:1646 */ +#line 2926 "arangod/Aql/grammar.cpp" /* yacc.c:1646 */ break; - case 124: -#line 911 "arangod/Aql/grammar.y" /* yacc.c:1646 */ + case 125: +#line 938 "arangod/Aql/grammar.y" /* yacc.c:1646 */ { // indexed variable access, continuation from * expansion, e.g. [*].variable[index] auto node = static_cast(parser->popStack()); (yyval.node) = parser->ast()->createNodeIndexedAccess(node, (yyvsp[-1].node)); } -#line 2906 "arangod/Aql/grammar.cpp" /* yacc.c:1646 */ +#line 2936 "arangod/Aql/grammar.cpp" /* yacc.c:1646 */ break; - case 125: -#line 916 "arangod/Aql/grammar.y" /* yacc.c:1646 */ + case 126: +#line 943 "arangod/Aql/grammar.y" /* yacc.c:1646 */ { // named variable access, continuation from * expansion, e.g. [*].variable.xx.reference (yyval.node) = parser->ast()->createNodeAttributeAccess((yyvsp[-2].node), (yyvsp[0].strval)); } -#line 2915 "arangod/Aql/grammar.cpp" /* yacc.c:1646 */ +#line 2945 "arangod/Aql/grammar.cpp" /* yacc.c:1646 */ break; - case 126: -#line 920 "arangod/Aql/grammar.y" /* yacc.c:1646 */ + case 127: +#line 947 "arangod/Aql/grammar.y" /* yacc.c:1646 */ { // named variable access w/ bind parameter, continuation from * expansion, e.g. [*].variable.xx.@reference (yyval.node) = parser->ast()->createNodeBoundAttributeAccess((yyvsp[-2].node), (yyvsp[0].node)); } -#line 2924 "arangod/Aql/grammar.cpp" /* yacc.c:1646 */ +#line 2954 "arangod/Aql/grammar.cpp" /* yacc.c:1646 */ break; - case 127: -#line 924 "arangod/Aql/grammar.y" /* yacc.c:1646 */ + case 128: +#line 951 "arangod/Aql/grammar.y" /* yacc.c:1646 */ { // indexed variable access, continuation from * expansion, e.g. [*].variable.xx.[index] (yyval.node) = parser->ast()->createNodeIndexedAccess((yyvsp[-3].node), (yyvsp[-1].node)); } -#line 2933 "arangod/Aql/grammar.cpp" /* yacc.c:1646 */ - break; - - case 128: -#line 931 "arangod/Aql/grammar.y" /* yacc.c:1646 */ - { - (yyval.node) = (yyvsp[0].node); - } -#line 2941 "arangod/Aql/grammar.cpp" /* yacc.c:1646 */ +#line 2963 "arangod/Aql/grammar.cpp" /* yacc.c:1646 */ break; case 129: -#line 934 "arangod/Aql/grammar.y" /* yacc.c:1646 */ +#line 958 "arangod/Aql/grammar.y" /* yacc.c:1646 */ { (yyval.node) = (yyvsp[0].node); } -#line 2949 "arangod/Aql/grammar.cpp" /* yacc.c:1646 */ +#line 2971 "arangod/Aql/grammar.cpp" /* yacc.c:1646 */ break; case 130: -#line 940 "arangod/Aql/grammar.y" /* yacc.c:1646 */ +#line 961 "arangod/Aql/grammar.y" /* yacc.c:1646 */ { (yyval.node) = (yyvsp[0].node); } -#line 2957 "arangod/Aql/grammar.cpp" /* yacc.c:1646 */ +#line 2979 "arangod/Aql/grammar.cpp" /* yacc.c:1646 */ break; case 131: -#line 943 "arangod/Aql/grammar.y" /* yacc.c:1646 */ +#line 967 "arangod/Aql/grammar.y" /* yacc.c:1646 */ + { + (yyval.node) = (yyvsp[0].node); + } +#line 2987 "arangod/Aql/grammar.cpp" /* yacc.c:1646 */ + break; + + case 132: +#line 970 "arangod/Aql/grammar.y" /* yacc.c:1646 */ { if ((yyvsp[0].strval) == nullptr) { ABORT_OOM @@ -2973,63 +3003,51 @@ yyreduce: (yyval.node) = parser->ast()->createNodeValueDouble(value); } } -#line 2977 "arangod/Aql/grammar.cpp" /* yacc.c:1646 */ - break; - - case 132: -#line 960 "arangod/Aql/grammar.y" /* yacc.c:1646 */ - { - (yyval.node) = parser->ast()->createNodeValueString((yyvsp[0].strval)); - } -#line 2985 "arangod/Aql/grammar.cpp" /* yacc.c:1646 */ +#line 3007 "arangod/Aql/grammar.cpp" /* yacc.c:1646 */ break; case 133: -#line 963 "arangod/Aql/grammar.y" /* yacc.c:1646 */ +#line 987 "arangod/Aql/grammar.y" /* yacc.c:1646 */ { - (yyval.node) = (yyvsp[0].node); + (yyval.node) = parser->ast()->createNodeValueString((yyvsp[0].strval)); } -#line 2993 "arangod/Aql/grammar.cpp" /* yacc.c:1646 */ +#line 3015 "arangod/Aql/grammar.cpp" /* yacc.c:1646 */ break; case 134: -#line 966 "arangod/Aql/grammar.y" /* yacc.c:1646 */ +#line 990 "arangod/Aql/grammar.y" /* yacc.c:1646 */ { - (yyval.node) = parser->ast()->createNodeValueNull(); + (yyval.node) = (yyvsp[0].node); } -#line 3001 "arangod/Aql/grammar.cpp" /* yacc.c:1646 */ +#line 3023 "arangod/Aql/grammar.cpp" /* yacc.c:1646 */ break; case 135: -#line 969 "arangod/Aql/grammar.y" /* yacc.c:1646 */ +#line 993 "arangod/Aql/grammar.y" /* yacc.c:1646 */ { - (yyval.node) = parser->ast()->createNodeValueBool(true); + (yyval.node) = parser->ast()->createNodeValueNull(); } -#line 3009 "arangod/Aql/grammar.cpp" /* yacc.c:1646 */ +#line 3031 "arangod/Aql/grammar.cpp" /* yacc.c:1646 */ break; case 136: -#line 972 "arangod/Aql/grammar.y" /* yacc.c:1646 */ +#line 996 "arangod/Aql/grammar.y" /* yacc.c:1646 */ { - (yyval.node) = parser->ast()->createNodeValueBool(false); + (yyval.node) = parser->ast()->createNodeValueBool(true); } -#line 3017 "arangod/Aql/grammar.cpp" /* yacc.c:1646 */ +#line 3039 "arangod/Aql/grammar.cpp" /* yacc.c:1646 */ break; case 137: -#line 978 "arangod/Aql/grammar.y" /* yacc.c:1646 */ +#line 999 "arangod/Aql/grammar.y" /* yacc.c:1646 */ { - if ((yyvsp[0].strval) == nullptr) { - ABORT_OOM - } - - (yyval.node) = parser->ast()->createNodeCollection((yyvsp[0].strval)); + (yyval.node) = parser->ast()->createNodeValueBool(false); } -#line 3029 "arangod/Aql/grammar.cpp" /* yacc.c:1646 */ +#line 3047 "arangod/Aql/grammar.cpp" /* yacc.c:1646 */ break; case 138: -#line 985 "arangod/Aql/grammar.y" /* yacc.c:1646 */ +#line 1005 "arangod/Aql/grammar.y" /* yacc.c:1646 */ { if ((yyvsp[0].strval) == nullptr) { ABORT_OOM @@ -3037,11 +3055,23 @@ yyreduce: (yyval.node) = parser->ast()->createNodeCollection((yyvsp[0].strval)); } -#line 3041 "arangod/Aql/grammar.cpp" /* yacc.c:1646 */ +#line 3059 "arangod/Aql/grammar.cpp" /* yacc.c:1646 */ break; case 139: -#line 992 "arangod/Aql/grammar.y" /* yacc.c:1646 */ +#line 1012 "arangod/Aql/grammar.y" /* yacc.c:1646 */ + { + if ((yyvsp[0].strval) == nullptr) { + ABORT_OOM + } + + (yyval.node) = parser->ast()->createNodeCollection((yyvsp[0].strval)); + } +#line 3071 "arangod/Aql/grammar.cpp" /* yacc.c:1646 */ + break; + + case 140: +#line 1019 "arangod/Aql/grammar.y" /* yacc.c:1646 */ { if ((yyvsp[0].strval) == nullptr) { ABORT_OOM @@ -3053,31 +3083,19 @@ yyreduce: (yyval.node) = parser->ast()->createNodeParameter((yyvsp[0].strval)); } -#line 3057 "arangod/Aql/grammar.cpp" /* yacc.c:1646 */ - break; - - case 140: -#line 1006 "arangod/Aql/grammar.y" /* yacc.c:1646 */ - { - (yyval.node) = parser->ast()->createNodeParameter((yyvsp[0].strval)); - } -#line 3065 "arangod/Aql/grammar.cpp" /* yacc.c:1646 */ +#line 3087 "arangod/Aql/grammar.cpp" /* yacc.c:1646 */ break; case 141: -#line 1012 "arangod/Aql/grammar.y" /* yacc.c:1646 */ +#line 1033 "arangod/Aql/grammar.y" /* yacc.c:1646 */ { - if ((yyvsp[0].strval) == nullptr) { - ABORT_OOM - } - - (yyval.strval) = (yyvsp[0].strval); + (yyval.node) = parser->ast()->createNodeParameter((yyvsp[0].strval)); } -#line 3077 "arangod/Aql/grammar.cpp" /* yacc.c:1646 */ +#line 3095 "arangod/Aql/grammar.cpp" /* yacc.c:1646 */ break; case 142: -#line 1019 "arangod/Aql/grammar.y" /* yacc.c:1646 */ +#line 1039 "arangod/Aql/grammar.y" /* yacc.c:1646 */ { if ((yyvsp[0].strval) == nullptr) { ABORT_OOM @@ -3085,19 +3103,31 @@ yyreduce: (yyval.strval) = (yyvsp[0].strval); } -#line 3089 "arangod/Aql/grammar.cpp" /* yacc.c:1646 */ +#line 3107 "arangod/Aql/grammar.cpp" /* yacc.c:1646 */ break; case 143: -#line 1028 "arangod/Aql/grammar.y" /* yacc.c:1646 */ +#line 1046 "arangod/Aql/grammar.y" /* yacc.c:1646 */ { + if ((yyvsp[0].strval) == nullptr) { + ABORT_OOM + } + (yyval.strval) = (yyvsp[0].strval); } -#line 3097 "arangod/Aql/grammar.cpp" /* yacc.c:1646 */ +#line 3119 "arangod/Aql/grammar.cpp" /* yacc.c:1646 */ break; case 144: -#line 1034 "arangod/Aql/grammar.y" /* yacc.c:1646 */ +#line 1055 "arangod/Aql/grammar.y" /* yacc.c:1646 */ + { + (yyval.strval) = (yyvsp[0].strval); + } +#line 3127 "arangod/Aql/grammar.cpp" /* yacc.c:1646 */ + break; + + case 145: +#line 1061 "arangod/Aql/grammar.y" /* yacc.c:1646 */ { if ((yyvsp[0].strval) == nullptr) { ABORT_OOM @@ -3118,11 +3148,11 @@ yyreduce: } } } -#line 3122 "arangod/Aql/grammar.cpp" /* yacc.c:1646 */ +#line 3152 "arangod/Aql/grammar.cpp" /* yacc.c:1646 */ break; -#line 3126 "arangod/Aql/grammar.cpp" /* yacc.c:1646 */ +#line 3156 "arangod/Aql/grammar.cpp" /* yacc.c:1646 */ default: break; } /* User semantic actions sometimes alter yychar, and that requires diff --git a/arangod/Aql/grammar.y b/arangod/Aql/grammar.y index 64676fd07b..2563a79f47 100644 --- a/arangod/Aql/grammar.y +++ b/arangod/Aql/grammar.y @@ -309,7 +309,7 @@ collect_statement: scopes->start(triagens::aql::AQL_SCOPE_COLLECT); } - auto node = parser->ast()->createNodeCollect(parser->ast()->createNodeList(), $2); + auto node = parser->ast()->createNodeCollectCount(parser->ast()->createNodeList(), $2); parser->ast()->addOperation(node); } | collect_variable_list count_into { @@ -336,7 +336,7 @@ collect_statement: } } - auto node = parser->ast()->createNodeCollect($1, $2); + auto node = parser->ast()->createNodeCollectCount($1, $2); parser->ast()->addOperation(node); } | collect_variable_list optional_into optional_keep { @@ -370,6 +370,33 @@ collect_statement: auto node = parser->ast()->createNodeCollect($1, $2, $3); parser->ast()->addOperation(node); } + | collect_variable_list T_INTO variable_name T_ASSIGN expression { + auto scopes = parser->ast()->scopes(); + + // check if we are in the main scope + bool reRegisterVariables = (scopes->type() != triagens::aql::AQL_SCOPE_MAIN); + + if (reRegisterVariables) { + // end the active scopes + scopes->endNested(); + // start a new scope + scopes->start(triagens::aql::AQL_SCOPE_COLLECT); + + size_t const n = $1->numMembers(); + for (size_t i = 0; i < n; ++i) { + auto member = $1->getMember(i); + + if (member != nullptr) { + TRI_ASSERT(member->type == NODE_TYPE_ASSIGN); + auto v = static_cast(member->getMember(0)->getData()); + scopes->addVariable(v); + } + } + } + + auto node = parser->ast()->createNodeCollectExpression($1, $3, $5); + parser->ast()->addOperation(node); + } ; collect_list: diff --git a/js/apps/system/aardvark/frontend/js/views/applicationsView.js b/js/apps/system/aardvark/frontend/js/views/applicationsView.js index 4e7a8cf395..ef28774bf3 100644 --- a/js/apps/system/aardvark/frontend/js/views/applicationsView.js +++ b/js/apps/system/aardvark/frontend/js/views/applicationsView.js @@ -1,6 +1,6 @@ /*jshint browser: true */ /*jshint strict: false, unused: false */ -/*global Backbone, $, window, arangoHelper, templateEngine, Joi, alert, _*/ +/*global require, Backbone, $, window, arangoHelper, templateEngine, Joi, alert, _*/ (function() { "use strict"; diff --git a/js/server/tests/aql-optimizer-collect-into.js b/js/server/tests/aql-optimizer-collect-into.js new file mode 100644 index 0000000000..de30aa3c82 --- /dev/null +++ b/js/server/tests/aql-optimizer-collect-into.js @@ -0,0 +1,161 @@ +/*jshint strict: false, maxlen: 500 */ +/*global require, assertEqual, AQL_EXECUTE */ + +//////////////////////////////////////////////////////////////////////////////// +/// @brief tests for COLLECT w/ INTO var = expr +/// +/// @file +/// +/// DISCLAIMER +/// +/// Copyright 2010-2012 triagens GmbH, Cologne, Germany +/// +/// Licensed under the Apache License, Version 2.0 (the "License"); +/// you may not use this file except in compliance with the License. +/// You may obtain a copy of the License at +/// +/// http://www.apache.org/licenses/LICENSE-2.0 +/// +/// Unless required by applicable law or agreed to in writing, software +/// distributed under the License is distributed on an "AS IS" BASIS, +/// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +/// See the License for the specific language governing permissions and +/// limitations under the License. +/// +/// Copyright holder is triAGENS GmbH, Cologne, Germany +/// +/// @author Jan Steemann +/// @author Copyright 2012, triAGENS GmbH, Cologne, Germany +//////////////////////////////////////////////////////////////////////////////// + +var jsunity = require("jsunity"); +var db = require("org/arangodb").db; + +//////////////////////////////////////////////////////////////////////////////// +/// @brief test suite +//////////////////////////////////////////////////////////////////////////////// + +function optimizerCollectExpressionTestSuite () { + var c; + + return { + setUp : function () { + db._drop("UnitTestsCollection"); + c = db._create("UnitTestsCollection"); + + for (var i = 0; i < 1000; ++i) { + c.save({ gender: (i % 2 === 0 ? "m" : "f"), age: 11 + (i % 71), value: i }); + } + }, + + tearDown : function () { + db._drop("UnitTestsCollection"); + }, + +//////////////////////////////////////////////////////////////////////////////// +/// @brief test expression +//////////////////////////////////////////////////////////////////////////////// + + testReference : function () { + var query = "FOR i IN " + c.name() + " COLLECT gender = i.gender INTO docs = i RETURN { gender: gender, age: MIN(docs[*].age) }"; + + var results = AQL_EXECUTE(query); + assertEqual(2, results.json.length); + assertEqual("f", results.json[0].gender); + assertEqual(11, results.json[0].age); + assertEqual("m", results.json[1].gender); + assertEqual(11, results.json[1].age); + }, + +//////////////////////////////////////////////////////////////////////////////// +/// @brief test expression +//////////////////////////////////////////////////////////////////////////////// + + testSubAttribute : function () { + var query = "FOR i IN " + c.name() + " COLLECT gender = i.gender INTO ages = i.age RETURN { gender: gender, age: MIN(ages) }"; + + var results = AQL_EXECUTE(query); + assertEqual(2, results.json.length); + assertEqual("f", results.json[0].gender); + assertEqual(11, results.json[0].age); + assertEqual("m", results.json[1].gender); + assertEqual(11, results.json[1].age); + }, + +//////////////////////////////////////////////////////////////////////////////// +/// @brief test expression +//////////////////////////////////////////////////////////////////////////////// + + testConst : function () { + var query = "FOR i IN " + c.name() + " COLLECT gender = i.gender INTO values = 1 RETURN { gender: gender, values: values }"; + + var values = [ ]; + for (var i = 0; i < 500; ++i) { + values.push(1); + } + + var results = AQL_EXECUTE(query); + assertEqual(2, results.json.length); + assertEqual("f", results.json[0].gender); + assertEqual(values, results.json[0].values); + assertEqual("m", results.json[1].gender); + assertEqual(values, results.json[1].values); + }, + +//////////////////////////////////////////////////////////////////////////////// +/// @brief test expression +//////////////////////////////////////////////////////////////////////////////// + + testDocAttribute : function () { + var query = "FOR i IN " + c.name() + " COLLECT gender = i.gender INTO values = i.value RETURN { gender: gender, values: values }"; + + var f = [ ], m = [ ]; + for (var i = 0; i < 500; ++i) { + m.push(i * 2); + f.push((i * 2) + 1); + } + + var results = AQL_EXECUTE(query); + assertEqual(2, results.json.length); + assertEqual("f", results.json[0].gender); + assertEqual(f, results.json[0].values.sort(function (l, r) { return l - r; })); + assertEqual("m", results.json[1].gender); + assertEqual(m, results.json[1].values.sort(function (l, r) { return l - r; })); + }, + +//////////////////////////////////////////////////////////////////////////////// +/// @brief test expression +//////////////////////////////////////////////////////////////////////////////// + + testCalculation : function () { + var query = "FOR i IN " + c.name() + " COLLECT gender = i.gender INTO names = (i.gender == 'f' ? 'female' : 'male') RETURN { gender: gender, names: names }"; + + var m = [ ], f = [ ]; + for (var i = 0; i < 500; ++i) { + m.push('male'); + f.push('female'); + } + + var results = AQL_EXECUTE(query); + assertEqual(2, results.json.length); + assertEqual("f", results.json[0].gender); + assertEqual(f, results.json[0].names); + assertEqual("m", results.json[1].gender); + assertEqual(m, results.json[1].names); + } + + }; +} + +//////////////////////////////////////////////////////////////////////////////// +/// @brief executes the test suite +//////////////////////////////////////////////////////////////////////////////// + +jsunity.run(optimizerCollectExpressionTestSuite); + +return jsunity.done(); + +// Local Variables: +// mode: outline-minor +// outline-regexp: "^\\(/// @brief\\|/// @addtogroup\\|// --SECTION--\\|/// @page\\|/// @}\\)" +// End: diff --git a/m4/clock_gettime b/m4/clock_gettime index 0f1b68ba49..9f872a8f1c 100644 --- a/m4/clock_gettime +++ b/m4/clock_gettime @@ -5,7 +5,7 @@ AC_DEFUN([AC_CLOCK], [ have_clock_gettime=no - AC_MSG_CHECKING([for clock_gettime oooooooooooooooooooooooooooooo]) + AC_MSG_CHECKING([for clock_gettime]) AC_TRY_LINK([ #include ], [struct timespec ts; clock_gettime(CLOCK_MONOTONIC, &ts);], [ have_clock_gettime=yes @@ -17,7 +17,7 @@ AC_DEFUN([AC_CLOCK], if test "$have_clock_gettime" = "no"; then AC_MSG_CHECKING([for clock_gettime in -lrt]) - SAVED_LIBS="$LIBS" + SAVED_LIBS=$LIBS LIBS="$LIBS -lrt" AC_TRY_LINK([ #include ], [struct timespec ts; clock_gettime(CLOCK_MONOTONIC, &ts);], [ @@ -69,6 +69,9 @@ AC_DEFUN([AC_CLOCK], if test "$have_clock_get_time" = "yes"; then AC_DEFINE([HAVE_CLOCK_GET_TIME], 1, [do we have clock_get_time?]) fi + RT_LIBS=$LIBS + AC_SUBST(RT_LIBS) + SAVED_LIBS=$LIBS ]) dnl Local Variables: diff --git a/m4/configure.basics b/m4/configure.basics index 1ec26bf191..e7033e3516 100644 --- a/m4/configure.basics +++ b/m4/configure.basics @@ -253,3 +253,30 @@ AC_DEFUN([TR_LIBRARY],[ esac done ]) + +dnl ---------------------------------------------------------------------------- +dnl check for std::unordered_map::emplace() +dnl ---------------------------------------------------------------------------- + +AC_DEFUN([AX_CXX_CHECK_UNORDERED_MAP_EMPLACE], [ + AC_LANG_PUSH([C++]) + AC_MSG_CHECKING([whether C++ has support for std::unordered_map::emplace()]) + AC_COMPILE_IFELSE( + [AC_LANG_SOURCE[ + #include + void test () { + std::unordered_map x; + x.emplace(1, 1); + } + ]], + [eval unordered_map_emplace=yes], + [eval unordered_map_emplace=no] + ) + AC_MSG_RESULT([$unordered_map_emplace]) + AC_LANG_POP([C++]) + if test x$unordered_map_emplace = xno; then + AC_MSG_ERROR([C++ has no support for std::unordered_map::emplace()]) + fi +]) +AX_CXX_CHECK_UNORDERED_MAP_EMPLACE +