From ad1163e3bbd20560c4c1d7adce9abc8603c2c12f Mon Sep 17 00:00:00 2001 From: Jan Steemann Date: Thu, 7 Jan 2016 13:35:12 +0100 Subject: [PATCH] refactoring for Aql COLLECT --- arangod/Aql/Ast.cpp | 20 + arangod/Aql/Ast.h | 6 + arangod/Aql/AstNode.cpp | 7 +- arangod/Aql/AstNode.h | 3 +- .../{AggregateBlock.cpp => CollectBlock.cpp} | 62 +- .../Aql/{AggregateBlock.h => CollectBlock.h} | 28 +- .../{AggregateNode.cpp => CollectNode.cpp} | 44 +- .../Aql/{AggregateNode.h => CollectNode.h} | 48 +- ...regationOptions.cpp => CollectOptions.cpp} | 26 +- ...{AggregationOptions.h => CollectOptions.h} | 26 +- arangod/Aql/ConditionFinder.cpp | 2 +- arangod/Aql/ExecutionEngine.cpp | 26 +- arangod/Aql/ExecutionNode.cpp | 22 +- arangod/Aql/ExecutionNode.h | 2 +- arangod/Aql/ExecutionPlan.cpp | 153 +- arangod/Aql/ExecutionPlan.h | 14 +- arangod/Aql/Optimizer.cpp | 2 +- arangod/Aql/Optimizer.h | 2 +- arangod/Aql/OptimizerRules.cpp | 62 +- arangod/Aql/OptimizerRules.h | 2 +- arangod/Aql/TraversalConditionFinder.cpp | 2 +- arangod/Aql/grammar.cpp | 2513 +++++++++-------- arangod/Aql/grammar.h | 109 +- arangod/Aql/grammar.y | 163 +- arangod/Aql/tokens.cpp | 547 ++-- arangod/Aql/tokens.ll | 4 + arangod/CMakeLists.txt | 6 +- arangod/Makefile.files | 6 +- .../modules/common/@arangodb/aql/explainer.js | 1 + js/common/modules/@arangodb/aql/explainer.js | 1 + js/server/tests/aql-explain-cluster.js | 2 +- js/server/tests/aql-explain-noncluster.js | 2 +- .../tests/aql-optimizer-collect-methods.js | 12 +- .../aql-optimizer-rule-remove-collect-into.js | 6 +- ...l-optimizer-rule-remove-redundant-sorts.js | 2 +- 35 files changed, 2150 insertions(+), 1783 deletions(-) rename arangod/Aql/{AggregateBlock.cpp => CollectBlock.cpp} (91%) rename arangod/Aql/{AggregateBlock.h => CollectBlock.h} (91%) rename arangod/Aql/{AggregateNode.cpp => CollectNode.cpp} (87%) rename arangod/Aql/{AggregateNode.h => CollectNode.h} (91%) rename arangod/Aql/{AggregationOptions.cpp => CollectOptions.cpp} (79%) rename arangod/Aql/{AggregationOptions.h => CollectOptions.h} (84%) diff --git a/arangod/Aql/Ast.cpp b/arangod/Aql/Ast.cpp index 3886bd6344..2e47498ba1 100644 --- a/arangod/Aql/Ast.cpp +++ b/arangod/Aql/Ast.cpp @@ -573,6 +573,26 @@ AstNode* Ast::createNodeCollectCount(AstNode const* list, char const* name, return node; } +//////////////////////////////////////////////////////////////////////////////// +/// @brief create an AST collect node, AGGREGATE +//////////////////////////////////////////////////////////////////////////////// + +AstNode* Ast::createNodeCollectAggregate(AstNode const* list, AstNode const* aggregations, + AstNode const* options) { + AstNode* node = createNode(NODE_TYPE_COLLECT_AGGREGATE); + + if (options == nullptr) { + // no options given. now use default options + options = &NopNode; + } + + node->addMember(options); + node->addMember(list); + node->addMember(aggregations); + + return node; +} + //////////////////////////////////////////////////////////////////////////////// /// @brief create an AST sort node //////////////////////////////////////////////////////////////////////////////// diff --git a/arangod/Aql/Ast.h b/arangod/Aql/Ast.h index e2e8f6e910..db0915da91 100644 --- a/arangod/Aql/Ast.h +++ b/arangod/Aql/Ast.h @@ -314,6 +314,12 @@ class Ast { AstNode* createNodeCollectCount(AstNode const*, char const*, size_t length, AstNode const*); + + //////////////////////////////////////////////////////////////////////////////// + /// @brief create an AST collect node, AGGREGATE + //////////////////////////////////////////////////////////////////////////////// + + AstNode* createNodeCollectAggregate(AstNode const*, AstNode const*, AstNode const*); //////////////////////////////////////////////////////////////////////////////// /// @brief create an AST sort node diff --git a/arangod/Aql/AstNode.cpp b/arangod/Aql/AstNode.cpp index 76c4a2f376..f143c772de 100644 --- a/arangod/Aql/AstNode.cpp +++ b/arangod/Aql/AstNode.cpp @@ -158,7 +158,8 @@ std::unordered_map const AstNode::TypeNames{ {static_cast(NODE_TYPE_DIRECTION), "direction"}, {static_cast(NODE_TYPE_COLLECTION_LIST), "collection list"}, {static_cast(NODE_TYPE_OPERATOR_NARY_AND), "n-ary and"}, - {static_cast(NODE_TYPE_OPERATOR_NARY_OR), "n-ary or"}}; + {static_cast(NODE_TYPE_OPERATOR_NARY_OR), "n-ary or"}, + {static_cast(NODE_TYPE_COLLECT_AGGREGATE), "collect aggregate"}}; //////////////////////////////////////////////////////////////////////////////// /// @brief names for AST node value types @@ -572,6 +573,7 @@ AstNode::AstNode(Ast* ast, triagens::basics::Json const& json) case NODE_TYPE_COLLECT: case NODE_TYPE_COLLECT_COUNT: case NODE_TYPE_COLLECT_EXPRESSION: + case NODE_TYPE_COLLECT_AGGREGATE: case NODE_TYPE_SORT: case NODE_TYPE_SORT_ELEMENT: case NODE_TYPE_LIMIT: @@ -720,6 +722,7 @@ AstNode::AstNode(std::function registerNode, case NODE_TYPE_COLLECT: case NODE_TYPE_COLLECT_COUNT: case NODE_TYPE_COLLECT_EXPRESSION: + case NODE_TYPE_COLLECT_AGGREGATE: case NODE_TYPE_SORT: case NODE_TYPE_SORT_ELEMENT: case NODE_TYPE_LIMIT: @@ -2435,6 +2438,7 @@ void AstNode::findVariableAccess( case NODE_TYPE_NOP: case NODE_TYPE_COLLECT_COUNT: case NODE_TYPE_COLLECT_EXPRESSION: + case NODE_TYPE_COLLECT_AGGREGATE: case NODE_TYPE_CALCULATED_OBJECT_ELEMENT: case NODE_TYPE_UPSERT: case NODE_TYPE_EXAMPLE: @@ -2576,6 +2580,7 @@ AstNode const* AstNode::findReference(AstNode const* findme) const { case NODE_TYPE_NOP: case NODE_TYPE_COLLECT_COUNT: case NODE_TYPE_COLLECT_EXPRESSION: + case NODE_TYPE_COLLECT_AGGREGATE: case NODE_TYPE_CALCULATED_OBJECT_ELEMENT: case NODE_TYPE_UPSERT: case NODE_TYPE_EXAMPLE: diff --git a/arangod/Aql/AstNode.h b/arangod/Aql/AstNode.h index c4ab94b396..f4629885ff 100644 --- a/arangod/Aql/AstNode.h +++ b/arangod/Aql/AstNode.h @@ -189,7 +189,8 @@ enum AstNodeType : uint32_t { NODE_TYPE_COLLECTION_LIST = 60, NODE_TYPE_DIRECTION = 61, NODE_TYPE_OPERATOR_NARY_AND = 62, - NODE_TYPE_OPERATOR_NARY_OR = 63 + NODE_TYPE_OPERATOR_NARY_OR = 63, + NODE_TYPE_COLLECT_AGGREGATE = 64 }; static_assert(NODE_TYPE_VALUE < NODE_TYPE_ARRAY, "incorrect node types order"); diff --git a/arangod/Aql/AggregateBlock.cpp b/arangod/Aql/CollectBlock.cpp similarity index 91% rename from arangod/Aql/AggregateBlock.cpp rename to arangod/Aql/CollectBlock.cpp index bf1d9cd6b9..033e86af56 100644 --- a/arangod/Aql/AggregateBlock.cpp +++ b/arangod/Aql/CollectBlock.cpp @@ -21,7 +21,7 @@ /// @author Max Neunhoeffer //////////////////////////////////////////////////////////////////////////////// -#include "Aql/AggregateBlock.h" +#include "Aql/CollectBlock.h" #include "Aql/AqlItemBlock.h" #include "Aql/ExecutionEngine.h" #include "Basics/Exceptions.h" @@ -36,14 +36,14 @@ using JsonHelper = triagens::basics::JsonHelper; using StringBuffer = triagens::basics::StringBuffer; -AggregatorGroup::AggregatorGroup(bool count) +CollectGroup::CollectGroup(bool count) : firstRow(0), lastRow(0), groupLength(0), rowsAreValid(false), count(count) {} -AggregatorGroup::~AggregatorGroup() { +CollectGroup::~CollectGroup() { // reset(); for (auto& it : groupBlocks) { delete it; @@ -54,7 +54,7 @@ AggregatorGroup::~AggregatorGroup() { } -void AggregatorGroup::initialize(size_t capacity) { +void CollectGroup::initialize(size_t capacity) { // TRI_ASSERT(capacity > 0); groupValues.clear(); @@ -73,7 +73,7 @@ void AggregatorGroup::initialize(size_t capacity) { groupLength = 0; } -void AggregatorGroup::reset() { +void CollectGroup::reset() { for (auto& it : groupBlocks) { delete it; } @@ -91,7 +91,7 @@ void AggregatorGroup::reset() { groupLength = 0; } -void AggregatorGroup::addValues(AqlItemBlock const* src, +void CollectGroup::addValues(AqlItemBlock const* src, RegisterId groupRegister) { if (groupRegister == ExecutionNode::MaxRegisterId) { // nothing to do @@ -107,7 +107,7 @@ void AggregatorGroup::addValues(AqlItemBlock const* src, } else { auto block = src->slice(firstRow, lastRow + 1); try { - TRI_IF_FAILURE("AggregatorGroup::addValues") { + TRI_IF_FAILURE("CollectGroup::addValues") { THROW_ARANGO_EXCEPTION(TRI_ERROR_DEBUG); } groupBlocks.emplace_back(block); @@ -124,15 +124,15 @@ void AggregatorGroup::addValues(AqlItemBlock const* src, } -SortedAggregateBlock::SortedAggregateBlock(ExecutionEngine* engine, - AggregateNode const* en) +SortedCollectBlock::SortedCollectBlock(ExecutionEngine* engine, + CollectNode const* en) : ExecutionBlock(engine, en), _aggregateRegisters(), _currentGroup(en->_count), _expressionRegister(ExecutionNode::MaxRegisterId), _groupRegister(ExecutionNode::MaxRegisterId), _variableNames() { - for (auto const& p : en->_aggregateVariables) { + for (auto const& p : en->_collectVariables) { // We know that planRegisters() has been run, so // getPlanNode()->_registerPlan is set up auto itOut = en->getRegisterPlan()->varInfo.find(p.first->id); @@ -177,7 +177,7 @@ SortedAggregateBlock::SortedAggregateBlock(ExecutionEngine* engine, // (which means no FOR in which we are contained) if (usedVariableIds.find(vi.first) == usedVariableIds.end()) { - // variable is not visible to the AggregateBlock + // variable is not visible to the CollectBlock continue; } @@ -201,13 +201,13 @@ SortedAggregateBlock::SortedAggregateBlock(ExecutionEngine* engine, } } -SortedAggregateBlock::~SortedAggregateBlock() {} +SortedCollectBlock::~SortedCollectBlock() {} //////////////////////////////////////////////////////////////////////////////// /// @brief initialize //////////////////////////////////////////////////////////////////////////////// -int SortedAggregateBlock::initialize() { +int SortedCollectBlock::initialize() { int res = ExecutionBlock::initialize(); if (res != TRI_ERROR_NO_ERROR) { @@ -220,7 +220,7 @@ int SortedAggregateBlock::initialize() { return TRI_ERROR_NO_ERROR; } -int SortedAggregateBlock::getOrSkipSome(size_t atLeast, size_t atMost, +int SortedCollectBlock::getOrSkipSome(size_t atLeast, size_t atMost, bool skipping, AqlItemBlock*& result, size_t& skipped) { TRI_ASSERT(result == nullptr && skipped == 0); @@ -337,7 +337,7 @@ int SortedAggregateBlock::getOrSkipSome(size_t atLeast, size_t atMost, if (!hasMore) { try { - TRI_IF_FAILURE("SortedAggregateBlock::hasMore") { + TRI_IF_FAILURE("SortedCollectBlock::hasMore") { THROW_ARANGO_EXCEPTION(TRI_ERROR_DEBUG); } hasMore = ExecutionBlock::getBlock(atLeast, atMost); @@ -353,7 +353,7 @@ int SortedAggregateBlock::getOrSkipSome(size_t atLeast, size_t atMost, try { // emit last buffered group if (!skipping) { - TRI_IF_FAILURE("SortedAggregateBlock::getOrSkipSome") { + TRI_IF_FAILURE("SortedCollectBlock::getOrSkipSome") { THROW_ARANGO_EXCEPTION(TRI_ERROR_DEBUG); } @@ -397,7 +397,7 @@ int SortedAggregateBlock::getOrSkipSome(size_t atLeast, size_t atMost, /// @brief writes the current group data into the result //////////////////////////////////////////////////////////////////////////////// -void SortedAggregateBlock::emitGroup(AqlItemBlock const* cur, AqlItemBlock* res, +void SortedCollectBlock::emitGroup(AqlItemBlock const* cur, AqlItemBlock* res, size_t row) { if (row > 0) { // re-use already copied aqlvalues @@ -433,12 +433,12 @@ void SortedAggregateBlock::emitGroup(AqlItemBlock const* cur, AqlItemBlock* res, // set the group values _currentGroup.addValues(cur, _groupRegister); - if (static_cast(_exeNode)->_count) { + if (static_cast(_exeNode)->_count) { // only set group count in result register res->setValue( row, _groupRegister, AqlValue(new Json(static_cast(_currentGroup.groupLength)))); - } else if (static_cast(_exeNode) + } else if (static_cast(_exeNode) ->_expressionVariable != nullptr) { // copy expression result into result register res->setValue(row, _groupRegister, @@ -457,12 +457,12 @@ void SortedAggregateBlock::emitGroup(AqlItemBlock const* cur, AqlItemBlock* res, } -HashedAggregateBlock::HashedAggregateBlock(ExecutionEngine* engine, - AggregateNode const* en) +HashedCollectBlock::HashedCollectBlock(ExecutionEngine* engine, + CollectNode const* en) : ExecutionBlock(engine, en), _aggregateRegisters(), _groupRegister(ExecutionNode::MaxRegisterId) { - for (auto const& p : en->_aggregateVariables) { + for (auto const& p : en->_collectVariables) { // We know that planRegisters() has been run, so // getPlanNode()->_registerPlan is set up auto itOut = en->getRegisterPlan()->varInfo.find(p.first->id); @@ -477,7 +477,7 @@ HashedAggregateBlock::HashedAggregateBlock(ExecutionEngine* engine, } if (en->_outVariable != nullptr) { - TRI_ASSERT(static_cast(_exeNode)->_count); + TRI_ASSERT(static_cast(_exeNode)->_count); auto const& registerPlan = en->getRegisterPlan()->varInfo; auto it = registerPlan.find(en->_outVariable->id); @@ -486,19 +486,19 @@ HashedAggregateBlock::HashedAggregateBlock(ExecutionEngine* engine, TRI_ASSERT(_groupRegister > 0 && _groupRegister < ExecutionNode::MaxRegisterId); } else { - TRI_ASSERT(!static_cast(_exeNode)->_count); + TRI_ASSERT(!static_cast(_exeNode)->_count); } TRI_ASSERT(!_aggregateRegisters.empty()); } -HashedAggregateBlock::~HashedAggregateBlock() {} +HashedCollectBlock::~HashedCollectBlock() {} //////////////////////////////////////////////////////////////////////////////// /// @brief initialize //////////////////////////////////////////////////////////////////////////////// -int HashedAggregateBlock::initialize() { +int HashedCollectBlock::initialize() { int res = ExecutionBlock::initialize(); if (res != TRI_ERROR_NO_ERROR) { @@ -508,7 +508,7 @@ int HashedAggregateBlock::initialize() { return TRI_ERROR_NO_ERROR; } -int HashedAggregateBlock::getOrSkipSome(size_t atLeast, size_t atMost, +int HashedCollectBlock::getOrSkipSome(size_t atLeast, size_t atMost, bool skipping, AqlItemBlock*& result, size_t& skipped) { TRI_ASSERT(result == nullptr && skipped == 0); @@ -539,7 +539,7 @@ int HashedAggregateBlock::getOrSkipSome(size_t atLeast, size_t atMost, allGroups(1024, GroupKeyHash(_trx, colls), GroupKeyEqual(_trx, colls)); auto buildResult = [&](AqlItemBlock const* src) { - auto planNode = static_cast(getPlanNode()); + auto planNode = static_cast(getPlanNode()); auto nrRegs = planNode->getRegisterPlan()->nrRegs[planNode->getDepth()]; auto result = std::make_unique(allGroups.size(), nrRegs); @@ -635,7 +635,7 @@ int HashedAggregateBlock::getOrSkipSome(size_t atLeast, size_t atMost, try { // emit last buffered group if (!skipping) { - TRI_IF_FAILURE("HashedAggregateBlock::getOrSkipSome") { + TRI_IF_FAILURE("HashedCollectBlock::getOrSkipSome") { THROW_ARANGO_EXCEPTION(TRI_ERROR_DEBUG); } } @@ -689,7 +689,7 @@ int HashedAggregateBlock::getOrSkipSome(size_t atLeast, size_t atMost, /// @brief hasher for groups //////////////////////////////////////////////////////////////////////////////// -size_t HashedAggregateBlock::GroupKeyHash::operator()( +size_t HashedCollectBlock::GroupKeyHash::operator()( std::vector const& value) const { uint64_t hash = 0x12345678; @@ -704,7 +704,7 @@ size_t HashedAggregateBlock::GroupKeyHash::operator()( /// @brief comparator for groups //////////////////////////////////////////////////////////////////////////////// -bool HashedAggregateBlock::GroupKeyEqual::operator()( +bool HashedCollectBlock::GroupKeyEqual::operator()( std::vector const& lhs, std::vector const& rhs) const { size_t const n = lhs.size(); diff --git a/arangod/Aql/AggregateBlock.h b/arangod/Aql/CollectBlock.h similarity index 91% rename from arangod/Aql/AggregateBlock.h rename to arangod/Aql/CollectBlock.h index d89ce76007..cd21b83941 100644 --- a/arangod/Aql/AggregateBlock.h +++ b/arangod/Aql/CollectBlock.h @@ -21,11 +21,11 @@ /// @author Jan Steemann //////////////////////////////////////////////////////////////////////////////// -#ifndef ARANGOD_AQL_AGGREGATE_BLOCK_H -#define ARANGOD_AQL_AGGREGATE_BLOCK_H 1 +#ifndef ARANGOD_AQL_COLLECT_BLOCK_H +#define ARANGOD_AQL_COLLECT_BLOCK_H 1 #include "Basics/Common.h" -#include "Aql/AggregateNode.h" +#include "Aql/CollectNode.h" #include "Aql/ExecutionBlock.h" #include "Aql/ExecutionNode.h" @@ -43,7 +43,7 @@ class ExecutionEngine; /// @brief details about the current group /////////////////////////////////////////////////////////////////////////////// -struct AggregatorGroup { +struct CollectGroup { std::vector groupValues; std::vector collections; @@ -54,11 +54,11 @@ struct AggregatorGroup { bool rowsAreValid; bool const count; - AggregatorGroup() = delete; + CollectGroup() = delete; - explicit AggregatorGroup(bool); + explicit CollectGroup(bool); - ~AggregatorGroup(); + ~CollectGroup(); void initialize(size_t capacity); void reset(); @@ -77,11 +77,11 @@ struct AggregatorGroup { }; -class SortedAggregateBlock : public ExecutionBlock { +class SortedCollectBlock : public ExecutionBlock { public: - SortedAggregateBlock(ExecutionEngine*, AggregateNode const*); + SortedCollectBlock(ExecutionEngine*, CollectNode const*); - ~SortedAggregateBlock(); + ~SortedCollectBlock(); int initialize() override; @@ -106,7 +106,7 @@ class SortedAggregateBlock : public ExecutionBlock { /// @brief details about the current group //////////////////////////////////////////////////////////////////////////////// - AggregatorGroup _currentGroup; + CollectGroup _currentGroup; //////////////////////////////////////////////////////////////////////////////// /// @brief the optional register that contains the input expression values for @@ -132,11 +132,11 @@ class SortedAggregateBlock : public ExecutionBlock { }; -class HashedAggregateBlock : public ExecutionBlock { +class HashedCollectBlock : public ExecutionBlock { public: - HashedAggregateBlock(ExecutionEngine*, AggregateNode const*); + HashedCollectBlock(ExecutionEngine*, CollectNode const*); - ~HashedAggregateBlock(); + ~HashedCollectBlock(); int initialize() override; diff --git a/arangod/Aql/AggregateNode.cpp b/arangod/Aql/CollectNode.cpp similarity index 87% rename from arangod/Aql/AggregateNode.cpp rename to arangod/Aql/CollectNode.cpp index e5741d917a..ee7a64fa3d 100644 --- a/arangod/Aql/AggregateNode.cpp +++ b/arangod/Aql/CollectNode.cpp @@ -21,7 +21,7 @@ /// @author Jan Steemann //////////////////////////////////////////////////////////////////////////////// -#include "AggregateNode.h" +#include "CollectNode.h" #include "Aql/Ast.h" #include "Aql/ExecutionPlan.h" #include "Aql/WalkerWorker.h" @@ -31,17 +31,17 @@ using namespace triagens::basics; using namespace triagens::aql; -AggregateNode::AggregateNode( +CollectNode::CollectNode( ExecutionPlan* plan, triagens::basics::Json const& base, Variable const* expressionVariable, Variable const* outVariable, std::vector const& keepVariables, std::unordered_map const& variableMap, std::vector> const& - aggregateVariables, + collectVariables, bool count, bool isDistinctCommand) : ExecutionNode(plan, base), _options(base), - _aggregateVariables(aggregateVariables), + _collectVariables(collectVariables), _expressionVariable(expressionVariable), _outVariable(outVariable), _keepVariables(keepVariables), @@ -51,10 +51,10 @@ AggregateNode::AggregateNode( _specialized(false) {} //////////////////////////////////////////////////////////////////////////////// -/// @brief toJson, for AggregateNode +/// @brief toJson, for CollectNode //////////////////////////////////////////////////////////////////////////////// -void AggregateNode::toJsonHelper(triagens::basics::Json& nodes, +void CollectNode::toJsonHelper(triagens::basics::Json& nodes, TRI_memory_zone_t* zone, bool verbose) const { triagens::basics::Json json(ExecutionNode::toJsonHelperGeneric( nodes, zone, verbose)); // call base class method @@ -64,9 +64,9 @@ void AggregateNode::toJsonHelper(triagens::basics::Json& nodes, } triagens::basics::Json values(triagens::basics::Json::Array, - _aggregateVariables.size()); + _collectVariables.size()); - for (auto it = _aggregateVariables.begin(); it != _aggregateVariables.end(); + for (auto it = _collectVariables.begin(); it != _collectVariables.end(); ++it) { triagens::basics::Json variable(triagens::basics::Json::Object); variable("outVariable", (*it).first->toJson())("inVariable", @@ -110,11 +110,11 @@ void AggregateNode::toJsonHelper(triagens::basics::Json& nodes, /// @brief clone ExecutionNode recursively //////////////////////////////////////////////////////////////////////////////// -ExecutionNode* AggregateNode::clone(ExecutionPlan* plan, bool withDependencies, +ExecutionNode* CollectNode::clone(ExecutionPlan* plan, bool withDependencies, bool withProperties) const { auto outVariable = _outVariable; auto expressionVariable = _expressionVariable; - auto aggregateVariables = _aggregateVariables; + auto collectVariables = _collectVariables; if (withProperties) { if (expressionVariable != nullptr) { @@ -127,16 +127,16 @@ ExecutionNode* AggregateNode::clone(ExecutionPlan* plan, bool withDependencies, } // need to re-create all variables - aggregateVariables.clear(); + collectVariables.clear(); - for (auto& it : _aggregateVariables) { + for (auto& it : _collectVariables) { auto out = plan->getAst()->variables()->createVariable(it.first); auto in = plan->getAst()->variables()->createVariable(it.second); - aggregateVariables.emplace_back(std::make_pair(out, in)); + collectVariables.emplace_back(std::make_pair(out, in)); } } - auto c = new AggregateNode(plan, _id, _options, aggregateVariables, + auto c = new CollectNode(plan, _id, _options, collectVariables, expressionVariable, outVariable, _keepVariables, _variableMap, _count, _isDistinctCommand); @@ -174,7 +174,7 @@ struct UserVarFinder final : public WalkerWorker { en->getType() == ExecutionNode::INDEX || en->getType() == ExecutionNode::ENUMERATE_LIST || en->getType() == ExecutionNode::TRAVERSAL || - en->getType() == ExecutionNode::AGGREGATE) { + en->getType() == ExecutionNode::COLLECT) { depth += 1; } // Now depth is set correct for this node. @@ -193,7 +193,7 @@ struct UserVarFinder final : public WalkerWorker { /// @brief getVariablesUsedHere, returning a vector //////////////////////////////////////////////////////////////////////////////// -std::vector AggregateNode::getVariablesUsedHere() const { +std::vector CollectNode::getVariablesUsedHere() const { std::unordered_set v; // actual work is done by that method getVariablesUsedHere(v); @@ -211,9 +211,9 @@ std::vector AggregateNode::getVariablesUsedHere() const { /// @brief getVariablesUsedHere, modifying the set in-place //////////////////////////////////////////////////////////////////////////////// -void AggregateNode::getVariablesUsedHere( +void CollectNode::getVariablesUsedHere( std::unordered_set& vars) const { - for (auto const& p : _aggregateVariables) { + for (auto const& p : _collectVariables) { vars.emplace(p.second); } @@ -226,7 +226,7 @@ void AggregateNode::getVariablesUsedHere( // Here we have to find all user defined variables in this query // amongst our dependencies: UserVarFinder finder(1); - auto myselfAsNonConst = const_cast(this); + auto myselfAsNonConst = const_cast(this); myselfAsNonConst->walk(&finder); if (finder.depth == 1) { // we are top level, let's run again with mindepth = 0 @@ -251,7 +251,7 @@ void AggregateNode::getVariablesUsedHere( /// @brief estimateCost //////////////////////////////////////////////////////////////////////////////// -double AggregateNode::estimateCost(size_t& nrItems) const { +double CollectNode::estimateCost(size_t& nrItems) const { double depCost = _dependencies.at(0)->getCost(nrItems); // As in the FilterNode case, we are pessimistic here by not reducing the @@ -259,10 +259,10 @@ double AggregateNode::estimateCost(size_t& nrItems) const { // as there are input items. In any case, we have to look at all incoming // items, and in particular in the COLLECT ... INTO ... case, we have // to actually hand on all data anyway, albeit not as separate items. - // Nevertheless, the optimizer does not do much with AggregateNodes + // Nevertheless, the optimizer does not do much with CollectNodes // and thus this potential overestimation does not really matter. - if (_count && _aggregateVariables.empty()) { + if (_count && _collectVariables.empty()) { // we are known to only produce a single output row nrItems = 1; } else { diff --git a/arangod/Aql/AggregateNode.h b/arangod/Aql/CollectNode.h similarity index 91% rename from arangod/Aql/AggregateNode.h rename to arangod/Aql/CollectNode.h index 33ce2c6b4b..3b803bd646 100644 --- a/arangod/Aql/AggregateNode.h +++ b/arangod/Aql/CollectNode.h @@ -21,11 +21,11 @@ /// @author Jan Steemann //////////////////////////////////////////////////////////////////////////////// -#ifndef ARANGOD_AQL_AGGREGATE_NODE_H -#define ARANGOD_AQL_AGGREGATE_NODE_H 1 +#ifndef ARANGOD_AQL_COLLECT_NODE_H +#define ARANGOD_AQL_COLLECT_NODE_H 1 #include "Basics/Common.h" -#include "Aql/AggregationOptions.h" +#include "Aql/CollectOptions.h" #include "Aql/ExecutionNode.h" #include "Aql/types.h" #include "Aql/Variable.h" @@ -41,15 +41,15 @@ class RedundantCalculationsReplacer; //////////////////////////////////////////////////////////////////////////////// -/// @brief class AggregateNode +/// @brief class CollectNode //////////////////////////////////////////////////////////////////////////////// -class AggregateNode : public ExecutionNode { +class CollectNode : public ExecutionNode { friend class ExecutionNode; friend class ExecutionBlock; - friend class SortedAggregateBlock; - friend class HashedAggregateBlock; + friend class HashedCollectBlock; friend class RedundantCalculationsReplacer; + friend class SortedCollectBlock; public: //////////////////////////////////////////////////////////////////////////////// @@ -57,17 +57,17 @@ class AggregateNode : public ExecutionNode { //////////////////////////////////////////////////////////////////////////////// public: - AggregateNode( - ExecutionPlan* plan, size_t id, AggregationOptions const& options, + CollectNode( + ExecutionPlan* plan, size_t id, CollectOptions const& options, std::vector> const& - aggregateVariables, + collectVariables, Variable const* expressionVariable, Variable const* outVariable, std::vector const& keepVariables, std::unordered_map const& variableMap, bool count, bool isDistinctCommand) : ExecutionNode(plan, id), _options(options), - _aggregateVariables(aggregateVariables), + _collectVariables(collectVariables), _expressionVariable(expressionVariable), _outVariable(outVariable), _keepVariables(keepVariables), @@ -79,20 +79,20 @@ class AggregateNode : public ExecutionNode { TRI_ASSERT(!_count || _outVariable != nullptr); } - AggregateNode( + CollectNode( ExecutionPlan*, triagens::basics::Json const& base, Variable const* expressionVariable, Variable const* outVariable, std::vector const& keepVariables, std::unordered_map const& variableMap, std::vector> const& - aggregateVariables, + collectVariables, bool count, bool isDistinctCommand); //////////////////////////////////////////////////////////////////////////////// /// @brief return the type of the node //////////////////////////////////////////////////////////////////////////////// - NodeType getType() const override final { return AGGREGATE; } + NodeType getType() const override final { return COLLECT; } //////////////////////////////////////////////////////////////////////////////// /// @brief whether or not the node requires an additional post SORT @@ -116,7 +116,7 @@ class AggregateNode : public ExecutionNode { /// @brief return the aggregation method //////////////////////////////////////////////////////////////////////////////// - AggregationOptions::AggregationMethod aggregationMethod() const { + CollectOptions::CollectMethod aggregationMethod() const { return _options.method; } @@ -124,7 +124,7 @@ class AggregateNode : public ExecutionNode { /// @brief set the aggregation method //////////////////////////////////////////////////////////////////////////////// - void aggregationMethod(AggregationOptions::AggregationMethod method) { + void aggregationMethod(CollectOptions::CollectMethod method) { _options.method = method; } @@ -132,13 +132,13 @@ class AggregateNode : public ExecutionNode { /// @brief getOptions //////////////////////////////////////////////////////////////////////////////// - AggregationOptions const& getOptions() const { return _options; } + CollectOptions const& getOptions() const { return _options; } //////////////////////////////////////////////////////////////////////////////// /// @brief getOptions //////////////////////////////////////////////////////////////////////////////// - AggregationOptions& getOptions() { return _options; } + CollectOptions& getOptions() { return _options; } //////////////////////////////////////////////////////////////////////////////// /// @brief export to JSON @@ -219,8 +219,8 @@ class AggregateNode : public ExecutionNode { //////////////////////////////////////////////////////////////////////////////// std::vector> const& - aggregateVariables() const { - return _aggregateVariables; + collectVariables() const { + return _collectVariables; } //////////////////////////////////////////////////////////////////////////////// @@ -243,10 +243,10 @@ class AggregateNode : public ExecutionNode { std::vector getVariablesSetHere() const override final { std::vector v; size_t const n = - _aggregateVariables.size() + (_outVariable == nullptr ? 0 : 1); + _collectVariables.size() + (_outVariable == nullptr ? 0 : 1); v.reserve(n); - for (auto const& p : _aggregateVariables) { + for (auto const& p : _collectVariables) { v.emplace_back(p.first); } if (_outVariable != nullptr) { @@ -261,13 +261,13 @@ class AggregateNode : public ExecutionNode { /// @brief options for the aggregation //////////////////////////////////////////////////////////////////////////////// - AggregationOptions _options; + CollectOptions _options; //////////////////////////////////////////////////////////////////////////////// /// @brief input/output variables for the aggregation (out, in) //////////////////////////////////////////////////////////////////////////////// - std::vector> _aggregateVariables; + std::vector> _collectVariables; //////////////////////////////////////////////////////////////////////////////// /// @brief input expression variable (might be null) diff --git a/arangod/Aql/AggregationOptions.cpp b/arangod/Aql/CollectOptions.cpp similarity index 79% rename from arangod/Aql/AggregationOptions.cpp rename to arangod/Aql/CollectOptions.cpp index f0b744c2af..a06a99e5fb 100644 --- a/arangod/Aql/AggregationOptions.cpp +++ b/arangod/Aql/CollectOptions.cpp @@ -21,7 +21,7 @@ /// @author Max Neunhoeffer //////////////////////////////////////////////////////////////////////////////// -#include "Aql/AggregationOptions.h" +#include "Aql/CollectOptions.h" #include "Basics/Exceptions.h" using namespace triagens::aql; @@ -32,7 +32,7 @@ using JsonHelper = triagens::basics::JsonHelper; /// @brief constructor, using JSON //////////////////////////////////////////////////////////////////////////////// -AggregationOptions::AggregationOptions(Json const& json) { +CollectOptions::CollectOptions(Json const& json) { Json obj = json.get("aggregationOptions"); method = @@ -43,8 +43,8 @@ AggregationOptions::AggregationOptions(Json const& json) { /// @brief whether or not the hash method can be used //////////////////////////////////////////////////////////////////////////////// -bool AggregationOptions::canUseHashMethod() const { - if (method == AggregationMethod::AGGREGATION_METHOD_SORTED) { +bool CollectOptions::canUseHashMethod() const { + if (method == CollectMethod::COLLECT_METHOD_SORTED) { return false; } @@ -55,7 +55,7 @@ bool AggregationOptions::canUseHashMethod() const { /// @brief convert the options to JSON //////////////////////////////////////////////////////////////////////////////// -void AggregationOptions::toJson(triagens::basics::Json& json, +void CollectOptions::toJson(triagens::basics::Json& json, TRI_memory_zone_t* zone) const { Json options; @@ -68,28 +68,28 @@ void AggregationOptions::toJson(triagens::basics::Json& json, /// @brief get the aggregation method from a string //////////////////////////////////////////////////////////////////////////////// -AggregationOptions::AggregationMethod AggregationOptions::methodFromString( +CollectOptions::CollectMethod CollectOptions::methodFromString( std::string const& method) { if (method == "hash") { - return AggregationMethod::AGGREGATION_METHOD_HASH; + return CollectMethod::COLLECT_METHOD_HASH; } if (method == "sorted") { - return AggregationMethod::AGGREGATION_METHOD_SORTED; + return CollectMethod::COLLECT_METHOD_SORTED; } - return AggregationMethod::AGGREGATION_METHOD_UNDEFINED; + return CollectMethod::COLLECT_METHOD_UNDEFINED; } //////////////////////////////////////////////////////////////////////////////// /// @brief stringify the aggregation method //////////////////////////////////////////////////////////////////////////////// -std::string AggregationOptions::methodToString( - AggregationOptions::AggregationMethod method) { - if (method == AggregationMethod::AGGREGATION_METHOD_HASH) { +std::string CollectOptions::methodToString( + CollectOptions::CollectMethod method) { + if (method == CollectMethod::COLLECT_METHOD_HASH) { return std::string("hash"); } - if (method == AggregationMethod::AGGREGATION_METHOD_SORTED) { + if (method == CollectMethod::COLLECT_METHOD_SORTED) { return std::string("sorted"); } diff --git a/arangod/Aql/AggregationOptions.h b/arangod/Aql/CollectOptions.h similarity index 84% rename from arangod/Aql/AggregationOptions.h rename to arangod/Aql/CollectOptions.h index 8201880f89..e3066d2597 100644 --- a/arangod/Aql/AggregationOptions.h +++ b/arangod/Aql/CollectOptions.h @@ -21,8 +21,8 @@ /// @author Max Neunhoeffer //////////////////////////////////////////////////////////////////////////////// -#ifndef ARANGOD_AQL_AGGREGATION_OPTIONS_H -#define ARANGOD_AQL_AGGREGATION_OPTIONS_H 1 +#ifndef ARANGOD_AQL_COLLECT_OPTIONS_H +#define ARANGOD_AQL_COLLECT_OPTIONS_H 1 #include "Basics/Common.h" #include "Basics/JsonHelper.h" @@ -31,19 +31,19 @@ namespace triagens { namespace aql { //////////////////////////////////////////////////////////////////////////////// -/// @brief AggregationOptions +/// @brief CollectOptions //////////////////////////////////////////////////////////////////////////////// -struct AggregationOptions { +struct CollectOptions { //////////////////////////////////////////////////////////////////////////////// /// @brief selected aggregation method //////////////////////////////////////////////////////////////////////////////// - enum AggregationMethod { - AGGREGATION_METHOD_UNDEFINED, - AGGREGATION_METHOD_HASH, - AGGREGATION_METHOD_SORTED + enum CollectMethod { + COLLECT_METHOD_UNDEFINED, + COLLECT_METHOD_HASH, + COLLECT_METHOD_SORTED }; @@ -51,13 +51,13 @@ struct AggregationOptions { /// @brief constructor, using default values //////////////////////////////////////////////////////////////////////////////// - AggregationOptions() : method(AGGREGATION_METHOD_UNDEFINED) {} + CollectOptions() : method(COLLECT_METHOD_UNDEFINED) {} //////////////////////////////////////////////////////////////////////////////// /// @brief constructor, using JSON //////////////////////////////////////////////////////////////////////////////// - AggregationOptions(triagens::basics::Json const&); + CollectOptions(triagens::basics::Json const&); //////////////////////////////////////////////////////////////////////////////// @@ -76,17 +76,17 @@ struct AggregationOptions { /// @brief get the aggregation method from a string //////////////////////////////////////////////////////////////////////////////// - static AggregationMethod methodFromString(std::string const&); + static CollectMethod methodFromString(std::string const&); //////////////////////////////////////////////////////////////////////////////// /// @brief stringify the aggregation method //////////////////////////////////////////////////////////////////////////////// static std::string methodToString( - AggregationOptions::AggregationMethod method); + CollectOptions::CollectMethod method); - AggregationMethod method; + CollectMethod method; }; } // namespace triagens::aql diff --git a/arangod/Aql/ConditionFinder.cpp b/arangod/Aql/ConditionFinder.cpp index 34b8d4f8cf..b0e2fb97ec 100644 --- a/arangod/Aql/ConditionFinder.cpp +++ b/arangod/Aql/ConditionFinder.cpp @@ -33,7 +33,7 @@ using EN = triagens::aql::ExecutionNode; bool ConditionFinder::before(ExecutionNode* en) { switch (en->getType()) { case EN::ENUMERATE_LIST: - case EN::AGGREGATE: + case EN::COLLECT: case EN::SCATTER: case EN::DISTRIBUTE: case EN::GATHER: diff --git a/arangod/Aql/ExecutionEngine.cpp b/arangod/Aql/ExecutionEngine.cpp index 8016cfa72d..eceb44980b 100644 --- a/arangod/Aql/ExecutionEngine.cpp +++ b/arangod/Aql/ExecutionEngine.cpp @@ -22,12 +22,12 @@ //////////////////////////////////////////////////////////////////////////////// #include "Aql/ExecutionEngine.h" -#include "Aql/AggregateBlock.h" -#include "Aql/AggregateNode.h" -#include "Aql/AggregationOptions.h" +#include "Aql/CollectOptions.h" #include "Aql/BasicBlocks.h" #include "Aql/CalculationBlock.h" #include "Aql/ClusterBlocks.h" +#include "Aql/CollectBlock.h" +#include "Aql/CollectNode.h" #include "Aql/EnumerateCollectionBlock.h" #include "Aql/EnumerateListBlock.h" #include "Aql/ExecutionBlock.h" @@ -87,22 +87,22 @@ static ExecutionBlock* CreateBlock( case ExecutionNode::SORT: { return new SortBlock(engine, static_cast(en)); } - case ExecutionNode::AGGREGATE: { + case ExecutionNode::COLLECT: { auto aggregationMethod = - static_cast(en)->aggregationMethod(); + static_cast(en)->aggregationMethod(); if (aggregationMethod == - AggregationOptions::AggregationMethod::AGGREGATION_METHOD_HASH) { - return new HashedAggregateBlock(engine, - static_cast(en)); - } else if (aggregationMethod == AggregationOptions::AggregationMethod:: - AGGREGATION_METHOD_SORTED) { - return new SortedAggregateBlock(engine, - static_cast(en)); + CollectOptions::CollectMethod::COLLECT_METHOD_HASH) { + return new HashedCollectBlock(engine, + static_cast(en)); + } else if (aggregationMethod == CollectOptions::CollectMethod:: + COLLECT_METHOD_SORTED) { + return new SortedCollectBlock(engine, + static_cast(en)); } THROW_ARANGO_EXCEPTION_MESSAGE(TRI_ERROR_INTERNAL, - "cannot instantiate AggregateBlock with " + "cannot instantiate CollectBlock with " "undetermined aggregation method"); } case ExecutionNode::SUBQUERY: { diff --git a/arangod/Aql/ExecutionNode.cpp b/arangod/Aql/ExecutionNode.cpp index b44bdb3400..6971c0ff4d 100644 --- a/arangod/Aql/ExecutionNode.cpp +++ b/arangod/Aql/ExecutionNode.cpp @@ -23,10 +23,10 @@ //////////////////////////////////////////////////////////////////////////////// #include "ExecutionNode.h" -#include "Aql/AggregateNode.h" #include "Aql/Ast.h" #include "Aql/ClusterNodes.h" #include "Aql/Collection.h" +#include "Aql/CollectNode.h" #include "Aql/ExecutionPlan.h" #include "Aql/IndexNode.h" #include "Aql/ModificationNodes.h" @@ -64,7 +64,7 @@ std::unordered_map const ExecutionNode::TypeNames{ {static_cast(SUBQUERY), "SubqueryNode"}, {static_cast(FILTER), "FilterNode"}, {static_cast(SORT), "SortNode"}, - {static_cast(AGGREGATE), "AggregateNode"}, + {static_cast(COLLECT), "CollectNode"}, {static_cast(RETURN), "ReturnNode"}, {static_cast(REMOVE), "RemoveNode"}, {static_cast(INSERT), "InsertNode"}, @@ -159,7 +159,7 @@ ExecutionNode* ExecutionNode::fromJsonFactory( getSortElements(elements, plan, oneNode, "SortNode"); return new SortNode(plan, oneNode, elements, stable); } - case AGGREGATE: { + case COLLECT: { Variable* expressionVariable = varFromJson(plan->getAst(), oneNode, "expressionVariable", Optional); Variable* outVariable = @@ -186,9 +186,9 @@ ExecutionNode* ExecutionNode::fromJsonFactory( size_t const len = jsonAggregates.size(); std::vector> - aggregateVariables; + collectVariables; - aggregateVariables.reserve(len); + collectVariables.reserve(len); for (size_t i = 0; i < len; i++) { triagens::basics::Json oneJsonAggregate = jsonAggregates.at(static_cast(i)); @@ -197,16 +197,16 @@ ExecutionNode* ExecutionNode::fromJsonFactory( Variable* inVar = varFromJson(plan->getAst(), oneJsonAggregate, "inVariable"); - aggregateVariables.emplace_back(std::make_pair(outVar, inVar)); + collectVariables.emplace_back(std::make_pair(outVar, inVar)); } bool count = JsonHelper::checkAndGetBooleanValue(oneNode.json(), "count"); bool isDistinctCommand = JsonHelper::checkAndGetBooleanValue( oneNode.json(), "isDistinctCommand"); - auto node = new AggregateNode( + auto node = new CollectNode( plan, oneNode, expressionVariable, outVariable, keepVariables, - plan->getAst()->variables()->variables(false), aggregateVariables, + plan->getAst()->variables()->variables(false), collectVariables, count, isDistinctCommand); // specialize the node if required @@ -924,7 +924,7 @@ void ExecutionNode::RegisterPlan::after(ExecutionNode* en) { break; } - case ExecutionNode::AGGREGATE: { + case ExecutionNode::COLLECT: { depth++; nrRegsHere.emplace_back(0); // create a copy of the last value here @@ -933,8 +933,8 @@ void ExecutionNode::RegisterPlan::after(ExecutionNode* en) { RegisterId registerId = nrRegs.back(); nrRegs.emplace_back(registerId); - auto ep = static_cast(en); - for (auto const& p : ep->_aggregateVariables) { + auto ep = static_cast(en); + for (auto const& p : ep->_collectVariables) { // p is std::pair // and the first is the to be assigned output variable // for which we need to create a register in the current diff --git a/arangod/Aql/ExecutionNode.h b/arangod/Aql/ExecutionNode.h index 3a591f863f..d02cdca257 100644 --- a/arangod/Aql/ExecutionNode.h +++ b/arangod/Aql/ExecutionNode.h @@ -75,7 +75,7 @@ class ExecutionNode { CALCULATION = 7, SUBQUERY = 8, SORT = 9, - AGGREGATE = 10, + COLLECT = 10, SCATTER = 11, GATHER = 12, REMOTE = 13, diff --git a/arangod/Aql/ExecutionPlan.cpp b/arangod/Aql/ExecutionPlan.cpp index dc020af6ff..02e55ddfb2 100644 --- a/arangod/Aql/ExecutionPlan.cpp +++ b/arangod/Aql/ExecutionPlan.cpp @@ -22,10 +22,10 @@ //////////////////////////////////////////////////////////////////////////////// #include "ExecutionPlan.h" -#include "Aql/AggregateNode.h" -#include "Aql/AggregationOptions.h" +#include "Aql/CollectOptions.h" #include "Aql/Ast.h" #include "Aql/AstNode.h" +#include "Aql/CollectNode.h" #include "Aql/ExecutionNode.h" #include "Aql/Expression.h" #include "Aql/ModificationNodes.h" @@ -362,15 +362,15 @@ Variable const* ExecutionPlan::getOutVariable(ExecutionNode const* node) const { return static_cast(node)->outVariable(); } - if (node->getType() == ExecutionNode::AGGREGATE) { - // AggregateNode has an outVariale() method, but we cannot use it. - // for AggregateNode, outVariable() will return the variable filled by INTO, + if (node->getType() == ExecutionNode::COLLECT) { + // CollectNode has an outVariale() method, but we cannot use it. + // for CollectNode, outVariable() will return the variable filled by INTO, // but INTO is an optional feature // so this will return the first result variable of the COLLECT // this part of the code should only be called for anonymous COLLECT nodes, // which only have one result variable - auto en = static_cast(node); - auto const& vars = en->aggregateVariables(); + auto en = static_cast(node); + auto const& vars = en->collectVariables(); TRI_ASSERT(vars.size() == 1); auto v = vars[0].first; @@ -386,17 +386,17 @@ Variable const* ExecutionPlan::getOutVariable(ExecutionNode const* node) const { /// @brief creates an anonymous COLLECT node (for a DISTINCT) //////////////////////////////////////////////////////////////////////////////// -AggregateNode* ExecutionPlan::createAnonymousCollect( +CollectNode* ExecutionPlan::createAnonymousCollect( CalculationNode const* previous) { // generate an out variable for the COLLECT auto out = _ast->variables()->createTemporaryVariable(); TRI_ASSERT(out != nullptr); std::vector> const - aggregateVariables{std::make_pair(out, previous->outVariable())}; + groupVariables{std::make_pair(out, previous->outVariable())}; - auto en = new AggregateNode(this, nextId(), AggregationOptions(), - aggregateVariables, nullptr, nullptr, + auto en = new CollectNode(this, nextId(), CollectOptions(), + groupVariables, nullptr, nullptr, std::vector(), _ast->variables()->variables(false), false, true); @@ -479,9 +479,9 @@ ModificationOptions ExecutionPlan::createModificationOptions( /// @brief create COLLECT options from an AST node //////////////////////////////////////////////////////////////////////////////// -AggregationOptions ExecutionPlan::createAggregationOptions( +CollectOptions ExecutionPlan::createCollectOptions( AstNode const* node) { - AggregationOptions options; + CollectOptions options; // parse the modification options we got if (node != nullptr && node->type == NODE_TYPE_OBJECT) { @@ -499,7 +499,7 @@ AggregationOptions ExecutionPlan::createAggregationOptions( if (strcmp(name, "method") == 0) { if (value->isStringValue()) { options.method = - AggregationOptions::methodFromString(value->getStringValue()); + CollectOptions::methodFromString(value->getStringValue()); } } } @@ -874,13 +874,13 @@ ExecutionNode* ExecutionPlan::fromNodeCollect(ExecutionNode* previous, TRI_ASSERT(n >= 2); - auto options = createAggregationOptions(node->getMember(0)); + auto options = createCollectOptions(node->getMember(0)); auto list = node->getMember(1); size_t const numVars = list->numMembers(); - std::vector> aggregateVariables; - aggregateVariables.reserve(numVars); + std::vector> groupVariables; + groupVariables.reserve(numVars); for (size_t i = 0; i < numVars; ++i) { auto assigner = list->getMember(i); @@ -900,12 +900,12 @@ ExecutionNode* ExecutionPlan::fromNodeCollect(ExecutionNode* previous, if (expression->type == NODE_TYPE_REFERENCE) { // operand is a variable auto e = static_cast(expression->getData()); - aggregateVariables.emplace_back(std::make_pair(v, e)); + groupVariables.emplace_back(std::make_pair(v, e)); } else { // operand is some misc expression auto calc = createTemporaryCalculation(expression, previous); previous = calc; - aggregateVariables.emplace_back(std::make_pair(v, getOutVariable(calc))); + groupVariables.emplace_back(std::make_pair(v, getOutVariable(calc))); } } @@ -933,8 +933,8 @@ ExecutionNode* ExecutionPlan::fromNodeCollect(ExecutionNode* previous, } } - auto collectNode = new AggregateNode( - this, nextId(), options, aggregateVariables, nullptr, outVariable, + auto collectNode = new CollectNode( + this, nextId(), options, groupVariables, nullptr, outVariable, keepVariables, _ast->variables()->variables(false), false, false); auto en = registerNode(collectNode); @@ -951,13 +951,13 @@ ExecutionNode* ExecutionPlan::fromNodeCollectExpression(ExecutionNode* previous, TRI_ASSERT(node != nullptr && node->type == NODE_TYPE_COLLECT_EXPRESSION); TRI_ASSERT(node->numMembers() == 4); - auto options = createAggregationOptions(node->getMember(0)); + auto options = createCollectOptions(node->getMember(0)); auto list = node->getMember(1); size_t const numVars = list->numMembers(); - std::vector> aggregateVariables; - aggregateVariables.reserve(numVars); + std::vector> groupVariables; + groupVariables.reserve(numVars); for (size_t i = 0; i < numVars; ++i) { auto assigner = list->getMember(i); @@ -976,12 +976,12 @@ ExecutionNode* ExecutionPlan::fromNodeCollectExpression(ExecutionNode* previous, if (expression->type == NODE_TYPE_REFERENCE) { // operand is a variable auto e = static_cast(expression->getData()); - aggregateVariables.emplace_back(std::make_pair(v, e)); + groupVariables.emplace_back(std::make_pair(v, e)); } else { // operand is some misc expression auto calc = createTemporaryCalculation(expression, previous); previous = calc; - aggregateVariables.emplace_back(std::make_pair(v, getOutVariable(calc))); + groupVariables.emplace_back(std::make_pair(v, getOutVariable(calc))); } } @@ -1004,8 +1004,8 @@ ExecutionNode* ExecutionPlan::fromNodeCollectExpression(ExecutionNode* previous, auto v = node->getMember(2); Variable* outVariable = static_cast(v->getData()); - auto collectNode = new AggregateNode( - this, nextId(), options, aggregateVariables, expressionVariable, + auto collectNode = new CollectNode( + this, nextId(), options, groupVariables, expressionVariable, outVariable, std::vector(), std::unordered_map(), false, false); @@ -1025,13 +1025,13 @@ ExecutionNode* ExecutionPlan::fromNodeCollectCount(ExecutionNode* previous, TRI_ASSERT(node != nullptr && node->type == NODE_TYPE_COLLECT_COUNT); TRI_ASSERT(node->numMembers() == 3); - auto options = createAggregationOptions(node->getMember(0)); + auto options = createCollectOptions(node->getMember(0)); auto list = node->getMember(1); size_t const numVars = list->numMembers(); - std::vector> aggregateVariables; - aggregateVariables.reserve(numVars); + std::vector> groupVariables; + groupVariables.reserve(numVars); for (size_t i = 0; i < numVars; ++i) { auto assigner = list->getMember(i); @@ -1050,12 +1050,12 @@ ExecutionNode* ExecutionPlan::fromNodeCollectCount(ExecutionNode* previous, if (expression->type == NODE_TYPE_REFERENCE) { // operand is a variable auto e = static_cast(expression->getData()); - aggregateVariables.emplace_back(std::make_pair(v, e)); + groupVariables.emplace_back(std::make_pair(v, e)); } else { // operand is some misc expression auto calc = createTemporaryCalculation(expression, previous); previous = calc; - aggregateVariables.emplace_back(std::make_pair(v, getOutVariable(calc))); + groupVariables.emplace_back(std::make_pair(v, getOutVariable(calc))); } } @@ -1067,13 +1067,93 @@ ExecutionNode* ExecutionPlan::fromNodeCollectCount(ExecutionNode* previous, TRI_ASSERT(outVariable != nullptr); auto en = registerNode( - new AggregateNode(this, nextId(), options, aggregateVariables, nullptr, + new CollectNode(this, nextId(), options, groupVariables, nullptr, outVariable, std::vector(), _ast->variables()->variables(false), true, false)); return addDependency(previous, en); } +//////////////////////////////////////////////////////////////////////////////// +/// @brief create an execution plan element from an AST COLLECT node, AGGREGATE +//////////////////////////////////////////////////////////////////////////////// + +ExecutionNode* ExecutionPlan::fromNodeCollectAggregate(ExecutionNode* previous, + AstNode const* node) { + TRI_ASSERT(node != nullptr && node->type == NODE_TYPE_COLLECT_AGGREGATE); + TRI_ASSERT(node->numMembers() == 3); + + auto options = createCollectOptions(node->getMember(0)); + + // parse group variables + auto list = node->getMember(1); + size_t numVars = list->numMembers(); + + std::vector> groupVariables; + groupVariables.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()); + groupVariables.emplace_back(std::make_pair(v, e)); + } else { + // operand is some misc expression + auto calc = createTemporaryCalculation(expression, previous); + previous = calc; + groupVariables.emplace_back(std::make_pair(v, getOutVariable(calc))); + } + } + + list = node->getMember(2); + numVars = list->numMembers(); + + 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); + + // operand is some misc expression + auto calc = createTemporaryCalculation(expression, previous); + previous = calc; + groupVariables.emplace_back(std::make_pair(v, getOutVariable(calc))); + } + + auto collectNode = new CollectNode( + this, nextId(), options, groupVariables, nullptr, + nullptr, std::vector(), + std::unordered_map(), false, false); + + auto en = registerNode(collectNode); + + return addDependency(previous, en); +} + //////////////////////////////////////////////////////////////////////////////// /// @brief create an execution plan element from an AST LIMIT node //////////////////////////////////////////////////////////////////////////////// @@ -1472,6 +1552,11 @@ ExecutionNode* ExecutionPlan::fromNode(AstNode const* node) { en = fromNodeCollectCount(en, member); break; } + + case NODE_TYPE_COLLECT_AGGREGATE: { + en = fromNodeCollectAggregate(en, member); + break; + } case NODE_TYPE_LIMIT: { en = fromNodeLimit(en, member); diff --git a/arangod/Aql/ExecutionPlan.h b/arangod/Aql/ExecutionPlan.h index 483d35024e..1de06276ea 100644 --- a/arangod/Aql/ExecutionPlan.h +++ b/arangod/Aql/ExecutionPlan.h @@ -25,7 +25,7 @@ #define ARANGOD_AQL_EXECUTION_PLAN_H 1 #include "Basics/Common.h" -#include "Aql/AggregationOptions.h" +#include "Aql/CollectOptions.h" #include "Aql/ExecutionNode.h" #include "Aql/ModificationOptions.h" #include "Aql/Query.h" @@ -35,10 +35,10 @@ namespace triagens { namespace aql { -class AggregateNode; class Ast; struct AstNode; class CalculationNode; +class CollectNode; class ExecutionNode; @@ -338,7 +338,7 @@ class ExecutionPlan { /// @brief creates an anonymous COLLECT node (for a DISTINCT) //////////////////////////////////////////////////////////////////////////////// - AggregateNode* createAnonymousCollect(CalculationNode const*); + CollectNode* createAnonymousCollect(CalculationNode const*); //////////////////////////////////////////////////////////////////////////////// /// @brief create modification options from an AST node @@ -350,7 +350,7 @@ class ExecutionPlan { /// @brief create COLLECT options from an AST node //////////////////////////////////////////////////////////////////////////////// - AggregationOptions createAggregationOptions(AstNode const*); + CollectOptions createCollectOptions(AstNode const*); //////////////////////////////////////////////////////////////////////////////// /// @brief adds "previous" as dependency to "plan", returns "plan" @@ -406,6 +406,12 @@ class ExecutionPlan { //////////////////////////////////////////////////////////////////////////////// ExecutionNode* fromNodeCollectCount(ExecutionNode*, AstNode const*); + + //////////////////////////////////////////////////////////////////////////////// + /// @brief create an execution plan element from an AST COLLECT node, AGGREGATE + //////////////////////////////////////////////////////////////////////////////// + + ExecutionNode* fromNodeCollectAggregate(ExecutionNode*, AstNode const*); //////////////////////////////////////////////////////////////////////////////// /// @brief create an execution plan element from an AST LIMIT node diff --git a/arangod/Aql/Optimizer.cpp b/arangod/Aql/Optimizer.cpp index f5581c345f..30849273a7 100644 --- a/arangod/Aql/Optimizer.cpp +++ b/arangod/Aql/Optimizer.cpp @@ -392,7 +392,7 @@ void Optimizer::setupRules() { true); #endif - // determine the "right" type of AggregateNode and + // determine the "right" type of CollectNode and // add a sort node for each COLLECT (may be removed later) // this rule cannot be turned off (otherwise, the query result might be // wrong!) diff --git a/arangod/Aql/Optimizer.h b/arangod/Aql/Optimizer.h index 44e081d6cb..278f225801 100644 --- a/arangod/Aql/Optimizer.h +++ b/arangod/Aql/Optimizer.h @@ -93,7 +93,7 @@ class Optimizer { pass1 = 100, - // determine the "right" type of AggregateNode and + // determine the "right" type of CollectNode and // add a sort node for each COLLECT (may be removed later) specializeCollectRule_pass1 = 105, diff --git a/arangod/Aql/OptimizerRules.cpp b/arangod/Aql/OptimizerRules.cpp index 09574eb1bb..13460f8e22 100644 --- a/arangod/Aql/OptimizerRules.cpp +++ b/arangod/Aql/OptimizerRules.cpp @@ -23,9 +23,9 @@ //////////////////////////////////////////////////////////////////////////////// #include "OptimizerRules.h" -#include "Aql/AggregateNode.h" -#include "Aql/AggregationOptions.h" +#include "Aql/CollectOptions.h" #include "Aql/ClusterNodes.h" +#include "Aql/CollectNode.h" #include "Aql/ConditionFinder.h" #include "Aql/ExecutionEngine.h" #include "Aql/ExecutionNode.h" @@ -440,10 +440,10 @@ void triagens::aql::removeUnnecessaryFiltersRule(Optimizer* opt, void triagens::aql::removeCollectIntoRule(Optimizer* opt, ExecutionPlan* plan, Optimizer::Rule const* rule) { bool modified = false; - std::vector nodes(plan->findNodesOfType(EN::AGGREGATE, true)); + std::vector nodes(plan->findNodesOfType(EN::COLLECT, true)); for (auto const& n : nodes) { - auto collectNode = static_cast(n); + auto collectNode = static_cast(n); TRI_ASSERT(collectNode != nullptr); auto outVariable = collectNode->outVariable(); @@ -774,13 +774,13 @@ void triagens::aql::removeSortRandRule(Optimizer* opt, ExecutionPlan* plan, switch (current->getType()) { case EN::SORT: - case EN::AGGREGATE: + case EN::COLLECT: case EN::FILTER: case EN::SUBQUERY: case EN::ENUMERATE_LIST: case EN::TRAVERSAL: case EN::INDEX: { - // if we found another SortNode, an AggregateNode, FilterNode, a + // if we found another SortNode, an CollectNode, FilterNode, a // SubqueryNode, // an EnumerateListNode, a TraversalNode or an IndexNode // this means we cannot apply our optimization @@ -965,7 +965,7 @@ void triagens::aql::moveCalculationsDownRule(Optimizer* opt, } else if (currentType == EN::INDEX || currentType == EN::ENUMERATE_COLLECTION || currentType == EN::ENUMERATE_LIST || - currentType == EN::TRAVERSAL || currentType == EN::AGGREGATE || + currentType == EN::TRAVERSAL || currentType == EN::COLLECT || currentType == EN::NORESULTS) { // we will not push further down than such nodes shouldMove = false; @@ -1108,29 +1108,29 @@ void triagens::aql::fuseCalculationsRule(Optimizer* opt, ExecutionPlan* plan, } //////////////////////////////////////////////////////////////////////////////// -/// @brief determine the "right" type of AggregateNode and +/// @brief determine the "right" type of CollectNode and /// add a sort node for each COLLECT (note: the sort may be removed later) /// this rule cannot be turned off (otherwise, the query result might be wrong!) //////////////////////////////////////////////////////////////////////////////// void triagens::aql::specializeCollectRule(Optimizer* opt, ExecutionPlan* plan, Optimizer::Rule const* rule) { - std::vector nodes(plan->findNodesOfType(EN::AGGREGATE, true)); + std::vector nodes(plan->findNodesOfType(EN::COLLECT, true)); bool modified = false; for (auto const& n : nodes) { - auto collectNode = static_cast(n); + auto collectNode = static_cast(n); if (collectNode->isSpecialized()) { // already specialized this node continue; } - auto const& aggregateVariables = collectNode->aggregateVariables(); + auto const& collectVariables = collectNode->collectVariables(); // test if we can use an alternative version of COLLECT with a hash table bool const canUseHashAggregation = - (!aggregateVariables.empty() && + (!collectVariables.empty() && (!collectNode->hasOutVariable() || collectNode->count()) && collectNode->getOptions().canUseHashMethod()); @@ -1140,21 +1140,21 @@ void triagens::aql::specializeCollectRule(Optimizer* opt, ExecutionPlan* plan, // use the cloned COLLECT node auto newCollectNode = - static_cast(newPlan->getNodeById(collectNode->id())); + static_cast(newPlan->getNodeById(collectNode->id())); TRI_ASSERT(newCollectNode != nullptr); - // specialize the AggregateNode so it will become a HashAggregateBlock + // specialize the CollectNode so it will become a HashedCollectBlock // later - // additionally, add a SortNode BEHIND the AggregateNode (to sort the + // additionally, add a SortNode BEHIND the CollectNode (to sort the // final result) newCollectNode->aggregationMethod( - AggregationOptions::AggregationMethod::AGGREGATION_METHOD_HASH); + CollectOptions::CollectMethod::COLLECT_METHOD_HASH); newCollectNode->specialized(); if (!collectNode->isDistinctCommand()) { // add the post-SORT std::vector> sortElements; - for (auto const& v : newCollectNode->aggregateVariables()) { + for (auto const& v : newCollectNode->collectVariables()) { sortElements.emplace_back(std::make_pair(v.first, true)); } @@ -1187,15 +1187,15 @@ void triagens::aql::specializeCollectRule(Optimizer* opt, ExecutionPlan* plan, // finally, adjust the original plan and create a sorted version of COLLECT - // specialize the AggregateNode so it will become a SortedAggregateBlock + // specialize the CollectNode so it will become a SortedCollectBlock // later collectNode->aggregationMethod( - AggregationOptions::AggregationMethod::AGGREGATION_METHOD_SORTED); + CollectOptions::CollectMethod::COLLECT_METHOD_SORTED); - // insert a SortNode IN FRONT OF the AggregateNode - if (!aggregateVariables.empty()) { + // insert a SortNode IN FRONT OF the CollectNode + if (!collectVariables.empty()) { std::vector> sortElements; - for (auto const& v : aggregateVariables) { + for (auto const& v : collectVariables) { sortElements.emplace_back(std::make_pair(v.second, true)); } @@ -1412,9 +1412,9 @@ class triagens::aql::RedundantCalculationsReplacer final break; } - case EN::AGGREGATE: { - auto node = static_cast(en); - for (auto& variable : node->_aggregateVariables) { + case EN::COLLECT: { + auto node = static_cast(en); + for (auto& variable : node->_collectVariables) { variable.second = Variable::replace(variable.second, _replacements); } break; @@ -1541,8 +1541,8 @@ void triagens::aql::removeRedundantCalculationsRule( } } - if (current->getType() == EN::AGGREGATE) { - if (static_cast(current)->hasOutVariable()) { + if (current->getType() == EN::COLLECT) { + if (static_cast(current)->hasOutVariable()) { // COLLECT ... INTO is evil (tm): it needs to keep all already defined // variables // we need to abort optimization here @@ -1891,7 +1891,7 @@ struct SortToIndexNode final : public WalkerWorker { } case EN::SINGLETON: - case EN::AGGREGATE: + case EN::COLLECT: case EN::INSERT: case EN::REMOVE: case EN::REPLACE: @@ -2568,7 +2568,7 @@ void triagens::aql::distributeFilternCalcToClusterRule( continue; } - case EN::AGGREGATE: + case EN::COLLECT: case EN::SUBQUERY: case EN::RETURN: case EN::NORESULTS: @@ -2663,7 +2663,7 @@ void triagens::aql::distributeSortToClusterRule(Optimizer* opt, switch (inspectNode->getType()) { case EN::ENUMERATE_LIST: case EN::SINGLETON: - case EN::AGGREGATE: + case EN::COLLECT: case EN::INSERT: case EN::REMOVE: case EN::REPLACE: @@ -2937,7 +2937,7 @@ class RemoveToEnumCollFinder final : public WalkerWorker { case EN::SINGLETON: case EN::ENUMERATE_LIST: case EN::SUBQUERY: - case EN::AGGREGATE: + case EN::COLLECT: case EN::INSERT: case EN::REPLACE: case EN::UPDATE: diff --git a/arangod/Aql/OptimizerRules.h b/arangod/Aql/OptimizerRules.h index 58a5c567fa..60bf243f14 100644 --- a/arangod/Aql/OptimizerRules.h +++ b/arangod/Aql/OptimizerRules.h @@ -103,7 +103,7 @@ void moveCalculationsDownRule(Optimizer*, ExecutionPlan*, void fuseCalculationsRule(Optimizer*, ExecutionPlan*, Optimizer::Rule const*); //////////////////////////////////////////////////////////////////////////////// -/// @brief determine the "right" type of AggregateNode and +/// @brief determine the "right" type of CollectNode and /// add a sort node for each COLLECT (may be removed later) /// this rule cannot be turned off (otherwise, the query result might be wrong!) //////////////////////////////////////////////////////////////////////////////// diff --git a/arangod/Aql/TraversalConditionFinder.cpp b/arangod/Aql/TraversalConditionFinder.cpp index 5e29b2c854..02d58d2325 100644 --- a/arangod/Aql/TraversalConditionFinder.cpp +++ b/arangod/Aql/TraversalConditionFinder.cpp @@ -227,7 +227,7 @@ bool TraversalConditionFinder::before(ExecutionNode* en) { switch (en->getType()) { case EN::ENUMERATE_LIST: - case EN::AGGREGATE: + case EN::COLLECT: case EN::SCATTER: case EN::DISTRIBUTE: case EN::GATHER: diff --git a/arangod/Aql/grammar.cpp b/arangod/Aql/grammar.cpp index b6a0c837f4..eb7a604b67 100644 --- a/arangod/Aql/grammar.cpp +++ b/arangod/Aql/grammar.cpp @@ -124,59 +124,60 @@ extern int Aqldebug; T_IN = 267, T_WITH = 268, T_INTO = 269, - T_GRAPH = 270, - T_DISTINCT = 271, - T_REMOVE = 272, - T_INSERT = 273, - T_UPDATE = 274, - T_REPLACE = 275, - T_UPSERT = 276, - T_NULL = 277, - T_TRUE = 278, - T_FALSE = 279, - T_STRING = 280, - T_QUOTED_STRING = 281, - T_INTEGER = 282, - T_DOUBLE = 283, - T_PARAMETER = 284, - T_ASSIGN = 285, - T_NOT = 286, - T_AND = 287, - T_OR = 288, - T_EQ = 289, - T_NE = 290, - T_LT = 291, - T_GT = 292, - T_LE = 293, - T_GE = 294, - T_PLUS = 295, - T_MINUS = 296, - T_TIMES = 297, - T_DIV = 298, - T_MOD = 299, - T_QUESTION = 300, - T_COLON = 301, - T_SCOPE = 302, - T_RANGE = 303, - T_COMMA = 304, - T_OPEN = 305, - T_CLOSE = 306, - T_OBJECT_OPEN = 307, - T_OBJECT_CLOSE = 308, - T_ARRAY_OPEN = 309, - T_ARRAY_CLOSE = 310, - T_OUTBOUND = 311, - T_INBOUND = 312, - T_ANY = 313, - T_ALL = 314, - T_NONE = 315, - T_NIN = 316, - UMINUS = 317, - UPLUS = 318, - FUNCCALL = 319, - REFERENCE = 320, - INDEXED = 321, - EXPANSION = 322 + T_AGGREGATE = 270, + T_GRAPH = 271, + T_DISTINCT = 272, + T_REMOVE = 273, + T_INSERT = 274, + T_UPDATE = 275, + T_REPLACE = 276, + T_UPSERT = 277, + T_NULL = 278, + T_TRUE = 279, + T_FALSE = 280, + T_STRING = 281, + T_QUOTED_STRING = 282, + T_INTEGER = 283, + T_DOUBLE = 284, + T_PARAMETER = 285, + T_ASSIGN = 286, + T_NOT = 287, + T_AND = 288, + T_OR = 289, + T_EQ = 290, + T_NE = 291, + T_LT = 292, + T_GT = 293, + T_LE = 294, + T_GE = 295, + T_PLUS = 296, + T_MINUS = 297, + T_TIMES = 298, + T_DIV = 299, + T_MOD = 300, + T_QUESTION = 301, + T_COLON = 302, + T_SCOPE = 303, + T_RANGE = 304, + T_COMMA = 305, + T_OPEN = 306, + T_CLOSE = 307, + T_OBJECT_OPEN = 308, + T_OBJECT_CLOSE = 309, + T_ARRAY_OPEN = 310, + T_ARRAY_CLOSE = 311, + T_OUTBOUND = 312, + T_INBOUND = 313, + T_ANY = 314, + T_ALL = 315, + T_NONE = 316, + T_NIN = 317, + UMINUS = 318, + UPLUS = 319, + FUNCCALL = 320, + REFERENCE = 321, + INDEXED = 322, + EXPANSION = 323 }; #endif @@ -195,7 +196,7 @@ union YYSTYPE bool boolval; int64_t intval; -#line 199 "arangod/Aql/grammar.cpp" /* yacc.c:355 */ +#line 200 "arangod/Aql/grammar.cpp" /* yacc.c:355 */ }; # define YYSTYPE_IS_TRIVIAL 1 # define YYSTYPE_IS_DECLARED 1 @@ -256,7 +257,7 @@ void Aqlerror (YYLTYPE* locp, #define scanner parser->scanner() -#line 260 "arangod/Aql/grammar.cpp" /* yacc.c:358 */ +#line 261 "arangod/Aql/grammar.cpp" /* yacc.c:358 */ #ifdef short # undef short @@ -500,21 +501,21 @@ union yyalloc /* YYFINAL -- State number of the termination state. */ #define YYFINAL 3 /* YYLAST -- Last index in YYTABLE. */ -#define YYLAST 999 +#define YYLAST 980 /* YYNTOKENS -- Number of terminals. */ -#define YYNTOKENS 69 +#define YYNTOKENS 70 /* YYNNTS -- Number of nonterminals. */ -#define YYNNTS 81 +#define YYNNTS 83 /* YYNRULES -- Number of rules. */ -#define YYNRULES 183 +#define YYNRULES 187 /* YYNSTATES -- Number of states. */ -#define YYNSTATES 304 +#define YYNSTATES 311 /* YYTRANSLATE[YYX] -- Symbol number corresponding to YYX as returned by yylex, with out-of-bounds checking. */ #define YYUNDEFTOK 2 -#define YYMAXUTOK 322 +#define YYMAXUTOK 323 #define YYTRANSLATE(YYX) \ ((unsigned int) (YYX) <= YYMAXUTOK ? yytranslate[YYX] : YYUNDEFTOK) @@ -527,7 +528,7 @@ static const yytype_uint8 yytranslate[] = 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 68, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 69, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, @@ -555,32 +556,32 @@ static const yytype_uint8 yytranslate[] = 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, - 65, 66, 67 + 65, 66, 67, 68 }; #if YYDEBUG /* YYRLINE[YYN] -- Source line where rule number YYN was defined. */ static const yytype_uint16 yyrline[] = { - 0, 217, 217, 222, 224, 227, 230, 233, 236, 242, - 244, 249, 251, 253, 255, 257, 259, 261, 263, 265, - 267, 269, 274, 280, 285, 290, 298, 306, 311, 313, - 318, 325, 335, 335, 349, 365, 392, 419, 451, 481, - 483, 488, 495, 499, 506, 520, 537, 537, 551, 551, - 562, 565, 571, 577, 580, 583, 586, 592, 597, 604, - 612, 615, 621, 631, 641, 649, 660, 665, 673, 684, - 689, 692, 698, 698, 749, 749, 759, 765, 768, 771, - 774, 777, 780, 786, 789, 805, 805, 817, 820, 823, - 829, 832, 835, 838, 841, 844, 847, 850, 853, 856, - 859, 862, 865, 868, 871, 877, 883, 885, 890, 893, - 893, 909, 912, 918, 921, 927, 927, 936, 938, 943, - 946, 952, 955, 969, 969, 978, 980, 985, 987, 992, - 1006, 1010, 1019, 1026, 1029, 1035, 1038, 1044, 1047, 1050, - 1056, 1059, 1065, 1068, 1075, 1079, 1086, 1092, 1091, 1100, - 1104, 1113, 1116, 1119, 1125, 1128, 1134, 1166, 1169, 1172, - 1179, 1189, 1189, 1202, 1217, 1231, 1245, 1245, 1288, 1291, - 1297, 1304, 1314, 1317, 1320, 1323, 1326, 1332, 1335, 1338, - 1348, 1354, 1357, 1362 + 0, 219, 219, 224, 226, 229, 232, 235, 238, 244, + 246, 251, 253, 255, 257, 259, 261, 263, 265, 267, + 269, 271, 276, 282, 287, 292, 300, 308, 313, 315, + 320, 327, 337, 337, 351, 368, 396, 424, 482, 510, + 538, 574, 576, 581, 588, 592, 599, 613, 630, 630, + 644, 644, 654, 654, 665, 668, 674, 680, 683, 686, + 689, 695, 700, 707, 715, 718, 724, 734, 744, 752, + 763, 768, 776, 787, 792, 795, 801, 801, 852, 852, + 862, 868, 871, 874, 877, 880, 883, 889, 892, 908, + 908, 920, 923, 926, 932, 935, 938, 941, 944, 947, + 950, 953, 956, 959, 962, 965, 968, 971, 974, 980, + 986, 988, 993, 996, 996, 1012, 1015, 1021, 1024, 1030, + 1030, 1039, 1041, 1046, 1049, 1055, 1058, 1072, 1072, 1081, + 1083, 1088, 1090, 1095, 1109, 1113, 1122, 1129, 1132, 1138, + 1141, 1147, 1150, 1153, 1159, 1162, 1168, 1171, 1178, 1182, + 1189, 1195, 1194, 1203, 1207, 1216, 1219, 1222, 1228, 1231, + 1237, 1269, 1272, 1275, 1282, 1292, 1292, 1305, 1320, 1334, + 1348, 1348, 1391, 1394, 1400, 1407, 1417, 1420, 1423, 1426, + 1429, 1435, 1438, 1441, 1451, 1457, 1460, 1465 }; #endif @@ -594,17 +595,18 @@ static const char *const yytname[] = "\"RETURN declaration\"", "\"COLLECT declaration\"", "\"SORT declaration\"", "\"LIMIT declaration\"", "\"ASC keyword\"", "\"DESC keyword\"", "\"IN keyword\"", "\"WITH keyword\"", - "\"INTO keyword\"", "\"GRAPH keyword\"", "\"DISTINCT modifier\"", - "\"REMOVE command\"", "\"INSERT command\"", "\"UPDATE command\"", - "\"REPLACE command\"", "\"UPSERT command\"", "\"null\"", "\"true\"", - "\"false\"", "\"identifier\"", "\"quoted string\"", "\"integer number\"", - "\"number\"", "\"bind parameter\"", "\"assignment\"", "\"not operator\"", + "\"INTO keyword\"", "\"AGGREGATE keyword\"", "\"GRAPH keyword\"", + "\"DISTINCT modifier\"", "\"REMOVE command\"", "\"INSERT command\"", + "\"UPDATE command\"", "\"REPLACE command\"", "\"UPSERT command\"", + "\"null\"", "\"true\"", "\"false\"", "\"identifier\"", + "\"quoted string\"", "\"integer number\"", "\"number\"", + "\"bind parameter\"", "\"assignment\"", "\"not operator\"", "\"and operator\"", "\"or operator\"", "\"== operator\"", "\"!= operator\"", "\"< operator\"", "\"> operator\"", "\"<= operator\"", "\">= operator\"", "\"+ operator\"", "\"- operator\"", "\"* operator\"", "\"/ operator\"", "\"% operator\"", "\"?\"", "\":\"", "\"::\"", "\"..\"", "\",\"", "\"(\"", "\")\"", "\"{\"", "\"}\"", "\"[\"", "\"]\"", - "\"outbound direction\"", "\"inbound direction\"", "\"any direction\"", + "\"outbound modifier\"", "\"inbound modifier\"", "\"any modifier\"", "\"all modifier\"", "\"none modifier\"", "T_NIN", "UMINUS", "UPLUS", "FUNCCALL", "REFERENCE", "INDEXED", "EXPANSION", "'.'", "$accept", "query", "final_statement", "optional_statement_block_statements", @@ -612,22 +614,23 @@ static const char *const yytname[] = "let_statement", "let_list", "let_element", "count_into", "collect_variable_list", "$@1", "collect_statement", "collect_list", "collect_element", "optional_into", "variable_list", "keep", "$@2", - "sort_statement", "$@3", "sort_list", "sort_element", "sort_direction", - "limit_statement", "return_statement", "in_or_into_collection", - "remove_statement", "insert_statement", "update_parameters", - "update_statement", "replace_parameters", "replace_statement", - "update_or_replace", "upsert_statement", "$@4", "distinct_expression", - "$@5", "expression", "function_name", "function_call", "$@6", - "operator_unary", "operator_binary", "operator_ternary", - "optional_function_call_arguments", "expression_or_query", "$@7", - "function_arguments_list", "compound_value", "array", "$@8", - "optional_array_elements", "array_elements_list", "options", "object", - "$@9", "optional_object_elements", "object_elements_list", - "object_element", "array_filter_operator", "optional_array_filter", - "optional_array_limit", "optional_array_return", "graph_collection", - "graph_collection_list", "graph_subject", "$@10", "graph_direction", - "graph_direction_steps", "reference", "$@11", "$@12", "simple_value", - "numeric_value", "value_literal", "collection_name", "bind_parameter", + "aggregate", "$@3", "sort_statement", "$@4", "sort_list", "sort_element", + "sort_direction", "limit_statement", "return_statement", + "in_or_into_collection", "remove_statement", "insert_statement", + "update_parameters", "update_statement", "replace_parameters", + "replace_statement", "update_or_replace", "upsert_statement", "$@5", + "distinct_expression", "$@6", "expression", "function_name", + "function_call", "$@7", "operator_unary", "operator_binary", + "operator_ternary", "optional_function_call_arguments", + "expression_or_query", "$@8", "function_arguments_list", + "compound_value", "array", "$@9", "optional_array_elements", + "array_elements_list", "options", "object", "$@10", + "optional_object_elements", "object_elements_list", "object_element", + "array_filter_operator", "optional_array_filter", "optional_array_limit", + "optional_array_return", "graph_collection", "graph_collection_list", + "graph_subject", "$@11", "graph_direction", "graph_direction_steps", + "reference", "$@12", "$@13", "simple_value", "numeric_value", + "value_literal", "collection_name", "bind_parameter", "object_element_name", "variable_name", YY_NULLPTR }; #endif @@ -643,16 +646,16 @@ static const yytype_uint16 yytoknum[] = 285, 286, 287, 288, 289, 290, 291, 292, 293, 294, 295, 296, 297, 298, 299, 300, 301, 302, 303, 304, 305, 306, 307, 308, 309, 310, 311, 312, 313, 314, - 315, 316, 317, 318, 319, 320, 321, 322, 46 + 315, 316, 317, 318, 319, 320, 321, 322, 323, 46 }; # endif -#define YYPACT_NINF -264 +#define YYPACT_NINF -269 #define yypact_value_is_default(Yystate) \ - (!!((Yystate) == (-264))) + (!!((Yystate) == (-269))) -#define YYTABLE_NINF -182 +#define YYTABLE_NINF -186 #define yytable_value_is_error(Yytable_value) \ 0 @@ -661,37 +664,38 @@ static const yytype_uint16 yytoknum[] = STATE-NUM. */ static const yytype_int16 yypact[] = { - -264, 13, 978, -264, 53, 53, 919, 463, 76, -264, - 214, 919, 919, 919, 919, -264, -264, -264, -264, -264, - -264, 40, -264, -264, -264, -264, 12, 17, 35, 59, - 70, -264, 7, 34, -264, 75, -264, -264, -264, -24, - -264, -264, -264, -264, 919, 919, 919, 919, -264, -264, - 751, 81, -264, -264, -264, -264, -264, -264, -264, 11, - -264, -264, -264, -264, -264, 751, 97, 106, 53, 919, - 91, -264, -264, 665, 665, -264, 559, -264, 596, 919, - 53, 106, 118, 778, 53, 53, 919, 114, 114, 114, - 391, -264, -5, 919, 919, 134, 919, 919, 919, 919, - 919, 919, 919, 919, 919, 919, 919, 919, 919, 919, - 919, 130, 109, 853, 23, 919, 142, 108, -264, 123, - -264, 155, 137, -264, 433, 214, 939, 56, 106, 106, - 919, 106, 919, 106, 699, 173, -264, 108, 106, -264, - -264, -264, -264, 289, -264, 919, 15, -264, 751, -264, - 159, 166, -264, 167, 919, 162, 168, -264, 170, 751, - 164, 175, 410, 919, 826, 808, 502, 502, 94, 94, - 94, 94, 138, 138, 114, 114, 114, 156, 110, -264, - 886, -264, 323, 183, -264, -264, 751, 53, -264, 53, - 919, 919, -264, -264, -264, -264, -264, 25, 158, 291, - -264, -264, -264, -264, -264, -264, -264, 665, -264, 665, - -264, 919, 919, 53, -264, -264, 522, 778, 53, -264, - 919, 357, -264, -5, 919, -264, 919, 410, 919, 751, - 176, -264, -264, 177, -264, -264, 223, -264, -264, 751, - -264, 106, 106, 630, 733, 180, -264, 86, -264, 182, - -264, -264, 289, 919, 221, 751, 188, -264, 751, 751, - 751, -264, -264, 919, 919, 226, -264, -264, -264, -264, - 919, -264, 53, -264, -264, -264, 522, 778, 919, -264, - 751, 919, 238, 665, -264, 89, -264, 919, 751, 487, - 919, 190, 106, -264, 197, 522, 919, 751, -264, -264, - 89, -264, 751, -264 + -269, 20, 958, -269, 5, 5, 898, 111, 55, -269, + 302, 898, 898, 898, 898, -269, -269, -269, -269, -269, + -269, 133, -269, -269, -269, -269, 9, 27, 32, 37, + 64, -269, -1, 15, -269, 19, -269, -269, -269, 12, + -269, -269, -269, -269, 898, 898, 898, 898, -269, -269, + 749, 30, -269, -269, -269, -269, -269, -269, -269, -22, + -269, -269, -269, -269, -269, 749, 59, -269, 60, 5, + 60, 898, 38, -269, -269, 642, 642, -269, 165, -269, + 571, 898, 5, 60, 66, 60, 812, 5, 5, 898, + 49, 49, 49, 436, -269, -2, 898, 898, 96, 898, + 898, 898, 898, 898, 898, 898, 898, 898, 898, 898, + 898, 898, 898, 898, 85, 75, 832, 0, 898, 101, + 5, 77, -269, 67, -269, 113, -269, 92, -269, 479, + 302, 918, 97, 60, 60, 898, 60, 898, 60, 677, + 119, -269, 77, 60, -269, -269, -269, -269, -269, 331, + -269, 898, 2, -269, 749, -269, 99, 108, -269, 109, + 898, 104, 110, -269, 114, 749, 112, 115, 198, 898, + 785, 767, 549, 549, 13, 13, 13, 13, 151, 151, + 49, 49, 49, 695, 216, -269, 865, -269, 366, 126, + -269, -269, 749, 5, 67, -269, 5, 898, 898, -269, + -269, -269, -269, -269, 298, 167, 333, -269, -269, -269, + -269, -269, -269, -269, 642, -269, 642, -269, 898, 898, + 5, -269, -269, 533, 812, 5, -269, 898, 401, -269, + -2, 898, -269, 898, 198, 898, 749, 138, -269, -269, + 142, -269, -269, 211, -269, -269, 749, -269, 60, 60, + 606, 731, 170, -269, 21, -269, 172, -269, -269, 331, + 898, 214, 749, 176, -269, 749, 749, 749, -269, -269, + 898, 898, 219, -269, -269, -269, -269, 898, -269, 5, + -269, -269, -269, 533, 812, 898, -269, 749, 898, 225, + 642, -269, 16, -269, 898, 749, 498, 898, 178, 60, + -269, 194, 533, 898, 749, -269, -269, 16, -269, 749, + -269 }; /* YYDEFACT[STATE-NUM] -- Default reduction number in state STATE-NUM. @@ -699,65 +703,66 @@ static const yytype_int16 yypact[] = means the default is an error. */ static const yytype_uint8 yydefact[] = { - 9, 0, 0, 1, 0, 0, 0, 0, 32, 48, - 0, 0, 0, 0, 0, 72, 2, 10, 11, 13, - 12, 42, 14, 15, 16, 3, 17, 18, 19, 20, - 21, 183, 0, 27, 28, 0, 174, 175, 176, 156, - 172, 170, 171, 180, 0, 0, 0, 161, 123, 115, - 26, 85, 159, 77, 78, 79, 157, 113, 114, 81, - 173, 80, 158, 74, 59, 76, 0, 121, 0, 0, - 57, 168, 169, 0, 0, 66, 0, 69, 0, 0, - 0, 121, 121, 0, 0, 0, 0, 89, 87, 88, - 0, 9, 125, 117, 0, 0, 0, 0, 0, 0, + 9, 0, 0, 1, 0, 0, 0, 0, 32, 52, + 0, 0, 0, 0, 0, 76, 2, 10, 11, 13, + 12, 44, 14, 15, 16, 3, 17, 18, 19, 20, + 21, 187, 0, 27, 28, 0, 178, 179, 180, 160, + 176, 174, 175, 184, 0, 0, 0, 165, 127, 119, + 26, 89, 163, 81, 82, 83, 161, 117, 118, 85, + 177, 84, 162, 78, 63, 80, 0, 50, 125, 0, + 125, 0, 61, 172, 173, 0, 0, 70, 0, 73, + 0, 0, 0, 125, 125, 125, 0, 0, 0, 0, + 93, 91, 92, 0, 9, 129, 121, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 34, 33, - 39, 0, 49, 50, 53, 0, 0, 0, 121, 121, - 0, 121, 0, 121, 0, 43, 35, 46, 121, 36, - 151, 152, 153, 22, 154, 0, 0, 29, 30, 160, - 0, 129, 182, 0, 0, 0, 126, 127, 0, 119, - 0, 118, 103, 0, 91, 90, 97, 98, 99, 100, - 101, 102, 92, 93, 94, 95, 96, 0, 82, 84, - 109, 133, 0, 166, 163, 164, 75, 0, 122, 0, - 0, 0, 54, 55, 52, 56, 58, 156, 172, 180, - 60, 177, 178, 179, 61, 62, 63, 0, 64, 0, - 67, 0, 0, 0, 37, 155, 0, 0, 0, 162, - 0, 0, 124, 0, 0, 116, 0, 104, 0, 108, - 0, 111, 9, 107, 165, 134, 135, 31, 40, 41, - 51, 121, 121, 0, 121, 47, 44, 0, 142, 146, - 23, 143, 0, 0, 0, 131, 0, 128, 130, 120, - 105, 86, 110, 109, 0, 137, 65, 68, 70, 71, - 0, 38, 0, 150, 149, 147, 0, 0, 0, 112, - 136, 0, 140, 0, 45, 0, 24, 0, 132, 138, - 0, 0, 121, 144, 148, 0, 0, 141, 167, 73, - 0, 25, 139, 145 + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 34, 33, 41, 0, 36, 53, 54, 57, + 0, 0, 0, 125, 125, 0, 125, 0, 125, 0, + 45, 35, 48, 125, 38, 37, 155, 156, 157, 22, + 158, 0, 0, 29, 30, 164, 0, 133, 186, 0, + 0, 0, 130, 131, 0, 123, 0, 122, 107, 0, + 95, 94, 101, 102, 103, 104, 105, 106, 96, 97, + 98, 99, 100, 0, 86, 88, 113, 137, 0, 170, + 167, 168, 79, 0, 51, 126, 0, 0, 0, 58, + 59, 56, 60, 62, 160, 176, 184, 64, 181, 182, + 183, 65, 66, 67, 0, 68, 0, 71, 0, 0, + 0, 40, 159, 0, 0, 0, 166, 0, 0, 128, + 0, 0, 120, 0, 108, 0, 112, 0, 115, 9, + 111, 169, 138, 139, 31, 42, 43, 55, 125, 125, + 0, 125, 49, 46, 0, 146, 150, 23, 147, 0, + 0, 0, 135, 0, 132, 134, 124, 109, 90, 114, + 113, 0, 141, 69, 72, 74, 75, 0, 39, 0, + 154, 153, 151, 0, 0, 0, 116, 140, 0, 144, + 0, 47, 0, 24, 0, 136, 142, 0, 0, 125, + 148, 152, 0, 0, 145, 171, 77, 0, 25, 143, + 149 }; /* YYPGOTO[NTERM-NUM]. */ static const yytype_int16 yypgoto[] = { - -264, -88, -264, -264, -264, -264, -264, -264, -264, 163, - 228, -264, -264, -264, -264, 61, -264, -264, -264, -264, - -264, -264, -264, 60, -264, -264, -264, -60, -264, -264, - -264, -264, -264, -264, -264, -264, -264, -264, -264, -6, - -264, -264, -264, -264, -264, -264, -264, -11, -264, -264, - -264, -264, -264, -264, -264, -71, -66, -264, -264, -264, - 30, -264, -264, -264, -264, -263, -264, -240, -264, -139, - -208, -264, -264, -264, 8, -264, 5, 127, -8, -264, - 43 + -269, -90, -269, -269, -269, -269, -269, -269, -269, 157, + 228, -269, -269, -269, 130, 56, -269, -269, -269, -269, + 232, -269, -269, -269, -269, 57, -269, -269, -269, -57, + -269, -269, -269, -269, -269, -269, -269, -269, -269, -269, + -269, -6, -269, -269, -269, -269, -269, -269, -269, -7, + -269, -269, -269, -269, -269, -269, -269, -67, -99, -269, + -269, -269, 36, -269, -269, -269, -269, -263, -269, -268, + -269, -139, -212, -269, -269, -269, -56, -269, 3, 135, + -8, -269, 31 }; /* YYDEFGOTO[NTERM-NUM]. */ static const yytype_int16 yydefgoto[] = { -1, 1, 16, 2, 17, 18, 19, 20, 33, 34, - 67, 21, 68, 22, 119, 120, 82, 245, 138, 213, - 23, 69, 122, 123, 194, 24, 25, 128, 26, 27, - 75, 28, 77, 29, 270, 30, 79, 64, 115, 124, - 51, 52, 112, 53, 54, 55, 230, 231, 232, 233, - 56, 57, 93, 160, 161, 118, 58, 92, 155, 156, - 157, 183, 265, 282, 291, 249, 294, 250, 285, 144, - 145, 59, 91, 236, 70, 60, 61, 200, 62, 158, - 35 + 68, 21, 69, 22, 123, 124, 84, 252, 143, 220, + 70, 120, 23, 71, 127, 128, 201, 24, 25, 133, + 26, 27, 77, 28, 79, 29, 277, 30, 81, 64, + 118, 129, 51, 52, 115, 53, 54, 55, 237, 238, + 239, 240, 56, 57, 96, 166, 167, 122, 58, 95, + 161, 162, 163, 189, 272, 289, 298, 256, 301, 257, + 292, 150, 151, 59, 94, 243, 72, 60, 61, 207, + 62, 164, 125 }; /* YYTABLE[YYPACT[STATE-NUM]] -- What to do in state STATE-NUM. If @@ -765,271 +770,270 @@ static const yytype_int16 yydefgoto[] = number is the opposite. If YYTABLE_NINF, syntax error. */ static const yytype_int16 yytable[] = { - 50, 65, 72, 150, 215, 73, 74, 76, 78, 253, - 136, 139, -4, 3, 129, 71, 131, -5, 133, 83, - 151, 152, 293, -83, 153, -177, -83, 217, -177, -177, - -177, -177, -177, -177, -177, -6, 286, 303, 87, 88, - 89, 90, -177, -177, -177, -177, -177, 32, 184, 154, - -177, 188, 43, 66, 80, 301, 84, 205, 206, -7, - 208, -4, 210, -4, 218, 113, -5, 214, -5, 287, - -8, 188, -83, 134, -177, -83, -177, 143, 31, 114, - 148, 201, 202, 85, -6, 203, -6, 159, 162, 66, - 164, 165, 166, 167, 168, 169, 170, 171, 172, 173, - 174, 175, 176, 177, 178, 86, 185, 182, -7, 186, - -7, 121, 273, 215, 248, 43, 72, 72, 43, -8, - 162, -8, 116, 135, 207, 95, 209, 146, 111, 71, - 71, 117, 195, 196, 104, 105, 106, 107, 108, 216, - 125, 95, 110, 137, 262, 95, 163, 241, 221, 242, - 104, 105, 106, 107, 108, 179, 187, 227, -178, 180, - 48, -178, -178, -178, -178, -178, -178, -178, 94, 95, - 266, 267, 189, 271, 229, -178, -178, -178, -178, -178, - 106, 107, 108, -178, 239, 190, 191, 95, 96, 97, - 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, - 108, 109, 228, 212, 110, 243, 244, -178, 251, -178, - 219, 252, -181, 220, 255, 222, 224, 223, 258, 225, - 259, 299, 260, 292, 226, 235, 263, 261, 264, 272, - 237, 275, 121, 277, 278, 281, 36, 37, 38, 274, - 40, 41, 42, 43, 290, 298, 300, 276, 147, 81, - 238, 240, 279, 257, 204, 0, 246, 229, 280, 0, - 0, 254, 0, 0, 283, 0, 0, 0, 251, 0, - 0, 252, 288, 0, 0, 289, 0, 251, 0, 0, - 0, 295, 0, 0, 297, 0, 0, 251, 0, 0, - 302, -179, 251, 0, -179, -179, -179, -179, -179, -179, - -179, 94, 0, 0, 0, 0, 0, 0, -179, -179, - -179, -179, -179, 0, 0, 284, -179, 0, 0, 0, - 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, - 105, 106, 107, 108, 109, 94, 0, 110, 0, 0, - -179, 0, -179, 0, 0, 140, 141, 142, 0, 0, - 0, 0, 0, 0, 95, 96, 97, 98, 99, 100, - 101, 102, 103, 104, 105, 106, 107, 108, 109, 94, - 0, 110, 0, 0, 0, 0, 0, 0, 234, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 95, 96, + 50, 65, 74, 126, 156, 75, 76, 78, 80, -4, + 222, 86, 260, 73, 224, 293, 141, 144, 145, 134, + 3, 136, 195, 138, 157, 158, 190, -5, 159, 300, + 43, 31, -6, 116, 308, 32, 35, -7, 90, 91, + 92, 93, 255, 195, 310, 98, 43, 117, 280, 87, + 89, 43, 225, 160, 107, 108, 109, 110, 111, -4, + -87, -4, 113, -87, -8, 88, 212, 213, 66, 215, + 67, 217, 294, 202, 203, 139, 221, -5, 114, -5, + 149, 98, -6, 154, -6, 119, 121, -7, 130, -7, + 165, 168, 142, 170, 171, 172, 173, 174, 175, 176, + 177, 178, 179, 180, 181, 182, 183, 184, 169, 191, + 188, 185, 192, 140, -8, 193, -8, 196, 152, 35, + 222, 74, 74, 208, 209, 168, 186, 210, 63, 214, + 48, 216, 73, 73, 36, 37, 38, 39, 40, 41, + 42, 43, 198, 44, 197, 223, 66, 82, 67, 269, + 219, 226, 45, 46, 228, -185, 227, 248, 229, 249, + 230, 231, 47, 234, 48, 233, 49, -182, 232, 242, + -182, -182, -182, -182, -182, -182, -182, 131, 135, 132, + 236, 273, 274, 98, 278, -182, -182, -182, -182, -182, + 268, 246, 270, -182, 109, 110, 111, 98, 99, 100, + 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, + 111, 112, 250, 251, 113, 258, 271, -182, 259, -182, + 279, 262, 282, 285, 244, 265, 284, 266, 288, 267, + 98, 297, 306, 299, 305, 103, 104, 105, 106, 107, + 108, 109, 110, 111, 307, 153, 281, 113, 98, 83, + 194, 253, 245, 85, 283, 247, 261, 107, 108, 109, + 110, 111, 0, 286, 236, 287, 264, 211, 0, 0, + 0, 290, 0, 0, 0, 258, 0, 0, 259, 295, + 0, 0, 296, 0, 258, 0, 0, 0, 302, 0, + 0, 304, 0, 0, 258, 0, 0, 309, -181, 258, + 0, -181, -181, -181, -181, -181, -181, -181, 0, 0, + 291, 0, 0, 0, 0, 0, -181, -181, -181, -181, + -181, 0, 0, 0, -181, 36, 37, 38, 0, 40, + 41, 42, 43, -183, 0, 0, -183, -183, -183, -183, + -183, -183, -183, 97, 0, 0, -87, 0, -181, -87, + -181, -183, -183, -183, -183, -183, 0, 0, 0, -183, + 0, 0, 0, 98, 99, 100, 101, 102, 103, 104, + 105, 106, 107, 108, 109, 110, 111, 112, 97, 0, + 113, 0, 0, -183, 0, -183, 0, 0, 146, 147, + 148, 0, 0, 0, 0, 0, 0, 0, 98, 99, + 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, + 110, 111, 112, 97, 0, 113, 0, 0, 0, 0, + 0, 0, 241, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 98, 99, 100, 101, 102, 103, 104, + 105, 106, 107, 108, 109, 110, 111, 112, 97, 0, + 113, 0, 0, 0, 0, 0, 0, 263, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 98, 99, + 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, + 110, 111, 112, 0, 0, 113, 0, 0, 155, 199, + 200, 97, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 36, 37, 38, 0, 40, 41, 42, 43, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, - 107, 108, 109, 94, 0, 110, 0, 0, 0, 0, - 0, 0, 256, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 95, 96, 97, 98, 99, 100, 101, 102, - 103, 104, 105, 106, 107, 108, 109, 0, 0, 110, - 0, 95, 149, 192, 193, 94, 100, 101, 102, 103, - 104, 105, 106, 107, 108, 36, 37, 38, 110, 40, - 41, 42, 43, 0, 95, 96, 97, 98, 99, 100, - 101, 102, 103, 104, 105, 106, 107, 108, 109, 63, - 0, 110, 0, 0, 0, 36, 37, 38, 39, 40, - 41, 42, 43, 0, 44, 0, 0, 0, 0, 94, - 0, 0, 0, 45, 46, 0, 0, 0, 0, 0, - 0, 0, 0, 47, 94, 48, 0, 49, 95, 96, - 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, - 107, 108, 109, 95, 94, 110, 296, 247, 100, 101, - 102, 103, 104, 105, 106, 107, 108, 248, 0, 0, - 110, 43, 0, 95, 96, 97, 98, 99, 100, 101, - 102, 103, 104, 105, 106, 107, 108, 109, 0, 0, - 110, 126, 130, 127, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, - 105, 106, 107, 108, 109, 0, 0, 110, 126, 132, - 127, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 95, 96, 97, + 107, 108, 109, 110, 111, 112, 0, 0, 113, 0, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, - 108, 109, 94, 0, 110, 0, 0, 0, 0, 268, - 269, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 95, 96, 97, 98, 99, 100, 101, 102, 103, - 104, 105, 106, 107, 108, 109, 0, 126, 110, 127, + 108, 109, 110, 111, 112, 97, 0, 113, 303, 254, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 255, + 0, 97, 0, 43, 0, 98, 99, 100, 101, 102, + 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, + 0, 98, 113, 131, 137, 132, 103, 104, 105, 106, + 107, 108, 109, 110, 111, 0, 0, 0, 113, 0, + 0, 0, 0, 98, 99, 100, 101, 102, 103, 104, + 105, 106, 107, 108, 109, 110, 111, 112, 97, 0, + 113, 0, 0, 0, 0, 0, 275, 276, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 98, 99, + 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, + 110, 111, 112, 0, 131, 113, 132, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 95, 96, 97, 98, + 0, 0, 0, 0, 98, 99, 100, 101, 102, 103, + 104, 105, 106, 107, 108, 109, 110, 111, 112, 97, + 0, 113, 0, 0, 0, 0, 218, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 97, 0, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, - 109, 94, 0, 110, 0, 0, 0, 211, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, - 105, 106, 107, 108, 109, 94, 0, 110, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 117, 0, - 0, 0, 0, 94, 95, 96, 97, 98, 99, 100, - 101, 102, 103, 104, 105, 106, 107, 108, 109, 0, - 0, 110, 95, 96, 97, 98, 99, 100, 101, 102, - 103, 104, 105, 106, 107, 108, 109, 0, 0, 110, - 36, 37, 38, 39, 40, 41, 42, 43, 0, 44, - 0, 0, 0, 0, 0, 0, 0, 0, 45, 46, - 94, 0, 0, 0, 0, 0, 0, 0, 47, 0, - 48, 0, 49, 0, 140, 141, 142, 0, 94, 95, - 96, 0, 98, 99, 100, 101, 102, 103, 104, 105, - 106, 107, 108, 0, 0, 0, 110, 95, 0, 0, - 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, - 108, 0, 0, 0, 110, 36, 37, 38, 39, 40, + 109, 110, 111, 112, 0, 0, 113, 98, 99, 100, + 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, + 111, 112, 235, 97, 113, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 121, 0, 0, + 0, 97, 0, 98, 99, 100, 101, 102, 103, 104, + 105, 106, 107, 108, 109, 110, 111, 112, 0, 97, + 113, 98, 99, 100, 101, 102, 103, 104, 105, 106, + 107, 108, 109, 110, 111, 112, 0, 97, 113, 98, + 99, 0, 101, 102, 103, 104, 105, 106, 107, 108, + 109, 110, 111, 0, 0, 0, 113, 98, 0, 0, + 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, + 111, 0, 0, 0, 113, 36, 37, 38, 39, 40, 41, 42, 43, 0, 44, 0, 0, 0, 0, 0, - 0, 0, 0, 45, 46, 181, 0, 0, 0, 0, + 0, 0, 0, 45, 46, 36, 37, 38, 39, 40, + 41, 42, 43, 47, 44, 48, 0, 49, 0, 146, + 147, 148, 0, 45, 46, 187, 0, 0, 0, 0, 0, 0, 0, 47, 0, 48, 0, 49, 36, 37, 38, 39, 40, 41, 42, 43, 0, 44, 0, 0, 0, 0, 0, 0, 0, 0, 45, 46, 0, 0, - 0, 0, 0, 0, 0, 0, 47, -106, 48, 0, + 0, 0, 0, 0, 0, 0, 47, -110, 48, 0, 49, 36, 37, 38, 39, 40, 41, 42, 43, 0, 44, 0, 0, 0, 0, 0, 0, 0, 0, 45, - 46, 36, 37, 38, 197, 198, 41, 42, 199, 47, + 46, 36, 37, 38, 204, 205, 41, 42, 206, 47, 44, 48, 0, 49, 0, 0, 0, 0, 0, 45, 46, 4, 5, 6, 7, 8, 9, 10, 0, 47, - 0, 48, 0, 49, 0, 11, 12, 13, 14, 15 + 0, 48, 0, 49, 0, 0, 11, 12, 13, 14, + 15 }; static const yytype_int16 yycheck[] = { - 6, 7, 10, 91, 143, 11, 12, 13, 14, 217, - 81, 82, 0, 0, 74, 10, 76, 0, 78, 12, - 25, 26, 285, 47, 29, 0, 50, 12, 3, 4, - 5, 6, 7, 8, 9, 0, 276, 300, 44, 45, - 46, 47, 17, 18, 19, 20, 21, 4, 25, 54, - 25, 117, 29, 13, 14, 295, 49, 128, 129, 0, - 131, 49, 133, 51, 49, 54, 49, 138, 51, 277, - 0, 137, 47, 79, 49, 50, 51, 83, 25, 68, - 86, 25, 26, 49, 49, 29, 51, 93, 94, 13, - 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, - 106, 107, 108, 109, 110, 30, 114, 113, 49, 115, - 51, 68, 26, 252, 25, 29, 124, 125, 29, 49, - 126, 51, 25, 80, 130, 31, 132, 84, 47, 124, - 125, 25, 124, 125, 40, 41, 42, 43, 44, 145, - 49, 31, 48, 25, 232, 31, 12, 207, 154, 209, - 40, 41, 42, 43, 44, 25, 14, 163, 0, 50, - 52, 3, 4, 5, 6, 7, 8, 9, 12, 31, - 241, 242, 49, 244, 180, 17, 18, 19, 20, 21, - 42, 43, 44, 25, 190, 30, 49, 31, 32, 33, - 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, - 44, 45, 46, 30, 48, 211, 212, 49, 216, 51, - 51, 217, 46, 46, 220, 53, 46, 49, 224, 55, - 226, 292, 228, 283, 49, 42, 49, 51, 5, 49, - 187, 49, 189, 12, 46, 9, 22, 23, 24, 247, - 26, 27, 28, 29, 6, 55, 49, 253, 85, 21, - 189, 191, 263, 223, 127, -1, 213, 263, 264, -1, - -1, 218, -1, -1, 270, -1, -1, -1, 276, -1, - -1, 277, 278, -1, -1, 281, -1, 285, -1, -1, - -1, 287, -1, -1, 290, -1, -1, 295, -1, -1, - 296, 0, 300, -1, 3, 4, 5, 6, 7, 8, - 9, 12, -1, -1, -1, -1, -1, -1, 17, 18, - 19, 20, 21, -1, -1, 272, 25, -1, -1, -1, - 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, - 41, 42, 43, 44, 45, 12, -1, 48, -1, -1, - 49, -1, 51, -1, -1, 56, 57, 58, -1, -1, - -1, -1, -1, -1, 31, 32, 33, 34, 35, 36, - 37, 38, 39, 40, 41, 42, 43, 44, 45, 12, - -1, 48, -1, -1, -1, -1, -1, -1, 55, -1, - -1, -1, -1, -1, -1, -1, -1, -1, 31, 32, - 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, - 43, 44, 45, 12, -1, 48, -1, -1, -1, -1, - -1, -1, 55, -1, -1, -1, -1, -1, -1, -1, - -1, -1, 31, 32, 33, 34, 35, 36, 37, 38, - 39, 40, 41, 42, 43, 44, 45, -1, -1, 48, - -1, 31, 51, 10, 11, 12, 36, 37, 38, 39, - 40, 41, 42, 43, 44, 22, 23, 24, 48, 26, - 27, 28, 29, -1, 31, 32, 33, 34, 35, 36, - 37, 38, 39, 40, 41, 42, 43, 44, 45, 16, - -1, 48, -1, -1, -1, 22, 23, 24, 25, 26, - 27, 28, 29, -1, 31, -1, -1, -1, -1, 12, - -1, -1, -1, 40, 41, -1, -1, -1, -1, -1, - -1, -1, -1, 50, 12, 52, -1, 54, 31, 32, - 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, - 43, 44, 45, 31, 12, 48, 49, 15, 36, 37, - 38, 39, 40, 41, 42, 43, 44, 25, -1, -1, - 48, 29, -1, 31, 32, 33, 34, 35, 36, 37, - 38, 39, 40, 41, 42, 43, 44, 45, -1, -1, - 48, 12, 13, 14, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, - 41, 42, 43, 44, 45, -1, -1, 48, 12, 13, - 14, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, -1, 31, 32, 33, - 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, - 44, 45, 12, -1, 48, -1, -1, -1, -1, 19, - 20, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, 31, 32, 33, 34, 35, 36, 37, 38, 39, - 40, 41, 42, 43, 44, 45, -1, 12, 48, 14, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, -1, -1, -1, -1, 31, 32, 33, 34, + 6, 7, 10, 70, 94, 11, 12, 13, 14, 0, + 149, 12, 224, 10, 12, 283, 83, 84, 85, 76, + 0, 78, 121, 80, 26, 27, 26, 0, 30, 292, + 30, 26, 0, 55, 302, 4, 5, 0, 44, 45, + 46, 47, 26, 142, 307, 32, 30, 69, 27, 50, + 31, 30, 50, 55, 41, 42, 43, 44, 45, 50, + 48, 52, 49, 51, 0, 50, 133, 134, 13, 136, + 15, 138, 284, 129, 130, 81, 143, 50, 48, 52, + 86, 32, 50, 89, 52, 26, 26, 50, 50, 52, + 96, 97, 26, 99, 100, 101, 102, 103, 104, 105, + 106, 107, 108, 109, 110, 111, 112, 113, 12, 117, + 116, 26, 118, 82, 50, 14, 52, 50, 87, 88, + 259, 129, 130, 26, 27, 131, 51, 30, 17, 135, + 53, 137, 129, 130, 23, 24, 25, 26, 27, 28, + 29, 30, 50, 32, 31, 151, 13, 14, 15, 239, + 31, 52, 41, 42, 160, 47, 47, 214, 54, 216, + 50, 47, 51, 169, 53, 50, 55, 0, 56, 43, + 3, 4, 5, 6, 7, 8, 9, 12, 13, 14, + 186, 248, 249, 32, 251, 18, 19, 20, 21, 22, + 52, 197, 50, 26, 43, 44, 45, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, - 45, 12, -1, 48, -1, -1, -1, 18, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, - 41, 42, 43, 44, 45, 12, -1, 48, -1, -1, - -1, -1, -1, -1, -1, -1, -1, -1, 25, -1, - -1, -1, -1, 12, 31, 32, 33, 34, 35, 36, - 37, 38, 39, 40, 41, 42, 43, 44, 45, -1, - -1, 48, 31, 32, 33, 34, 35, 36, 37, 38, - 39, 40, 41, 42, 43, 44, 45, -1, -1, 48, - 22, 23, 24, 25, 26, 27, 28, 29, -1, 31, - -1, -1, -1, -1, -1, -1, -1, -1, 40, 41, - 12, -1, -1, -1, -1, -1, -1, -1, 50, -1, - 52, -1, 54, -1, 56, 57, 58, -1, 12, 31, - 32, -1, 34, 35, 36, 37, 38, 39, 40, 41, - 42, 43, 44, -1, -1, -1, 48, 31, -1, -1, + 45, 46, 218, 219, 49, 223, 5, 50, 224, 52, + 50, 227, 50, 47, 193, 231, 12, 233, 9, 235, + 32, 6, 299, 290, 56, 37, 38, 39, 40, 41, + 42, 43, 44, 45, 50, 88, 254, 49, 32, 21, + 120, 220, 196, 21, 260, 198, 225, 41, 42, 43, + 44, 45, -1, 270, 270, 271, 230, 132, -1, -1, + -1, 277, -1, -1, -1, 283, -1, -1, 284, 285, + -1, -1, 288, -1, 292, -1, -1, -1, 294, -1, + -1, 297, -1, -1, 302, -1, -1, 303, 0, 307, + -1, 3, 4, 5, 6, 7, 8, 9, -1, -1, + 279, -1, -1, -1, -1, -1, 18, 19, 20, 21, + 22, -1, -1, -1, 26, 23, 24, 25, -1, 27, + 28, 29, 30, 0, -1, -1, 3, 4, 5, 6, + 7, 8, 9, 12, -1, -1, 48, -1, 50, 51, + 52, 18, 19, 20, 21, 22, -1, -1, -1, 26, + -1, -1, -1, 32, 33, 34, 35, 36, 37, 38, + 39, 40, 41, 42, 43, 44, 45, 46, 12, -1, + 49, -1, -1, 50, -1, 52, -1, -1, 57, 58, + 59, -1, -1, -1, -1, -1, -1, -1, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, - 44, -1, -1, -1, 48, 22, 23, 24, 25, 26, - 27, 28, 29, -1, 31, -1, -1, -1, -1, -1, - -1, -1, -1, 40, 41, 42, -1, -1, -1, -1, - -1, -1, -1, 50, -1, 52, -1, 54, 22, 23, - 24, 25, 26, 27, 28, 29, -1, 31, -1, -1, - -1, -1, -1, -1, -1, -1, 40, 41, -1, -1, - -1, -1, -1, -1, -1, -1, 50, 51, 52, -1, - 54, 22, 23, 24, 25, 26, 27, 28, 29, -1, - 31, -1, -1, -1, -1, -1, -1, -1, -1, 40, - 41, 22, 23, 24, 25, 26, 27, 28, 29, 50, - 31, 52, -1, 54, -1, -1, -1, -1, -1, 40, - 41, 3, 4, 5, 6, 7, 8, 9, -1, 50, - -1, 52, -1, 54, -1, 17, 18, 19, 20, 21 + 44, 45, 46, 12, -1, 49, -1, -1, -1, -1, + -1, -1, 56, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, 32, 33, 34, 35, 36, 37, 38, + 39, 40, 41, 42, 43, 44, 45, 46, 12, -1, + 49, -1, -1, -1, -1, -1, -1, 56, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, 32, 33, + 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, + 44, 45, 46, -1, -1, 49, -1, -1, 52, 10, + 11, 12, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, 23, 24, 25, -1, 27, 28, 29, 30, + 12, 32, 33, 34, 35, 36, 37, 38, 39, 40, + 41, 42, 43, 44, 45, 46, -1, -1, 49, -1, + 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, + 42, 43, 44, 45, 46, 12, -1, 49, 50, 16, + -1, -1, -1, -1, -1, -1, -1, -1, -1, 26, + -1, 12, -1, 30, -1, 32, 33, 34, 35, 36, + 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, + -1, 32, 49, 12, 13, 14, 37, 38, 39, 40, + 41, 42, 43, 44, 45, -1, -1, -1, 49, -1, + -1, -1, -1, 32, 33, 34, 35, 36, 37, 38, + 39, 40, 41, 42, 43, 44, 45, 46, 12, -1, + 49, -1, -1, -1, -1, -1, 20, 21, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, 32, 33, + 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, + 44, 45, 46, -1, 12, 49, 14, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, 32, 33, 34, 35, 36, 37, + 38, 39, 40, 41, 42, 43, 44, 45, 46, 12, + -1, 49, -1, -1, -1, -1, 19, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, 12, -1, 32, + 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, + 43, 44, 45, 46, -1, -1, 49, 32, 33, 34, + 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, + 45, 46, 47, 12, 49, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, 26, -1, -1, + -1, 12, -1, 32, 33, 34, 35, 36, 37, 38, + 39, 40, 41, 42, 43, 44, 45, 46, -1, 12, + 49, 32, 33, 34, 35, 36, 37, 38, 39, 40, + 41, 42, 43, 44, 45, 46, -1, 12, 49, 32, + 33, -1, 35, 36, 37, 38, 39, 40, 41, 42, + 43, 44, 45, -1, -1, -1, 49, 32, -1, -1, + 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, + 45, -1, -1, -1, 49, 23, 24, 25, 26, 27, + 28, 29, 30, -1, 32, -1, -1, -1, -1, -1, + -1, -1, -1, 41, 42, 23, 24, 25, 26, 27, + 28, 29, 30, 51, 32, 53, -1, 55, -1, 57, + 58, 59, -1, 41, 42, 43, -1, -1, -1, -1, + -1, -1, -1, 51, -1, 53, -1, 55, 23, 24, + 25, 26, 27, 28, 29, 30, -1, 32, -1, -1, + -1, -1, -1, -1, -1, -1, 41, 42, -1, -1, + -1, -1, -1, -1, -1, -1, 51, 52, 53, -1, + 55, 23, 24, 25, 26, 27, 28, 29, 30, -1, + 32, -1, -1, -1, -1, -1, -1, -1, -1, 41, + 42, 23, 24, 25, 26, 27, 28, 29, 30, 51, + 32, 53, -1, 55, -1, -1, -1, -1, -1, 41, + 42, 3, 4, 5, 6, 7, 8, 9, -1, 51, + -1, 53, -1, 55, -1, -1, 18, 19, 20, 21, + 22 }; /* YYSTOS[STATE-NUM] -- The (internal number of the) accessing symbol of state STATE-NUM. */ static const yytype_uint8 yystos[] = { - 0, 70, 72, 0, 3, 4, 5, 6, 7, 8, - 9, 17, 18, 19, 20, 21, 71, 73, 74, 75, - 76, 80, 82, 89, 94, 95, 97, 98, 100, 102, - 104, 25, 149, 77, 78, 149, 22, 23, 24, 25, - 26, 27, 28, 29, 31, 40, 41, 50, 52, 54, - 108, 109, 110, 112, 113, 114, 119, 120, 125, 140, - 144, 145, 147, 16, 106, 108, 13, 79, 81, 90, - 143, 145, 147, 108, 108, 99, 108, 101, 108, 105, - 14, 79, 85, 12, 49, 49, 30, 108, 108, 108, - 108, 141, 126, 121, 12, 31, 32, 33, 34, 35, - 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, - 48, 47, 111, 54, 68, 107, 25, 25, 124, 83, - 84, 149, 91, 92, 108, 49, 12, 14, 96, 96, - 13, 96, 13, 96, 108, 149, 124, 25, 87, 124, - 56, 57, 58, 108, 138, 139, 149, 78, 108, 51, - 70, 25, 26, 29, 54, 127, 128, 129, 148, 108, - 122, 123, 108, 12, 108, 108, 108, 108, 108, 108, - 108, 108, 108, 108, 108, 108, 108, 108, 108, 25, - 50, 42, 108, 130, 25, 147, 108, 14, 125, 49, - 30, 49, 10, 11, 93, 143, 143, 25, 26, 29, - 146, 25, 26, 29, 146, 124, 124, 108, 124, 108, - 124, 18, 30, 88, 124, 138, 108, 12, 49, 51, - 46, 108, 53, 49, 46, 55, 49, 108, 46, 108, - 115, 116, 117, 118, 55, 42, 142, 149, 84, 108, - 92, 96, 96, 108, 108, 86, 149, 15, 25, 134, - 136, 147, 108, 139, 149, 108, 55, 129, 108, 108, - 108, 51, 70, 49, 5, 131, 124, 124, 19, 20, - 103, 124, 49, 26, 147, 49, 108, 12, 46, 116, - 108, 9, 132, 108, 149, 137, 136, 139, 108, 108, - 6, 133, 96, 134, 135, 108, 49, 108, 55, 124, - 49, 136, 108, 134 + 0, 71, 73, 0, 3, 4, 5, 6, 7, 8, + 9, 18, 19, 20, 21, 22, 72, 74, 75, 76, + 77, 81, 83, 92, 97, 98, 100, 101, 103, 105, + 107, 26, 152, 78, 79, 152, 23, 24, 25, 26, + 27, 28, 29, 30, 32, 41, 42, 51, 53, 55, + 111, 112, 113, 115, 116, 117, 122, 123, 128, 143, + 147, 148, 150, 17, 109, 111, 13, 15, 80, 82, + 90, 93, 146, 148, 150, 111, 111, 102, 111, 104, + 111, 108, 14, 80, 86, 90, 12, 50, 50, 31, + 111, 111, 111, 111, 144, 129, 124, 12, 32, 33, + 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, + 44, 45, 46, 49, 48, 114, 55, 69, 110, 26, + 91, 26, 127, 84, 85, 152, 127, 94, 95, 111, + 50, 12, 14, 99, 99, 13, 99, 13, 99, 111, + 152, 127, 26, 88, 127, 127, 57, 58, 59, 111, + 141, 142, 152, 79, 111, 52, 71, 26, 27, 30, + 55, 130, 131, 132, 151, 111, 125, 126, 111, 12, + 111, 111, 111, 111, 111, 111, 111, 111, 111, 111, + 111, 111, 111, 111, 111, 26, 51, 43, 111, 133, + 26, 150, 111, 14, 84, 128, 50, 31, 50, 10, + 11, 96, 146, 146, 26, 27, 30, 149, 26, 27, + 30, 149, 127, 127, 111, 127, 111, 127, 19, 31, + 89, 127, 141, 111, 12, 50, 52, 47, 111, 54, + 50, 47, 56, 50, 111, 47, 111, 118, 119, 120, + 121, 56, 43, 145, 152, 85, 111, 95, 99, 99, + 111, 111, 87, 152, 16, 26, 137, 139, 150, 111, + 142, 152, 111, 56, 132, 111, 111, 111, 52, 71, + 50, 5, 134, 127, 127, 20, 21, 106, 127, 50, + 27, 150, 50, 111, 12, 47, 119, 111, 9, 135, + 111, 152, 140, 139, 142, 111, 111, 6, 136, 99, + 137, 138, 111, 50, 111, 56, 127, 50, 139, 111, + 137 }; /* YYR1[YYN] -- Symbol number of symbol that rule YYN derives. */ static const yytype_uint8 yyr1[] = { - 0, 69, 70, 71, 71, 71, 71, 71, 71, 72, - 72, 73, 73, 73, 73, 73, 73, 73, 73, 73, - 73, 73, 74, 74, 74, 74, 75, 76, 77, 77, - 78, 79, 81, 80, 82, 82, 82, 82, 82, 83, - 83, 84, 85, 85, 86, 86, 88, 87, 90, 89, - 91, 91, 92, 93, 93, 93, 93, 94, 94, 95, - 96, 96, 97, 98, 99, 99, 100, 101, 101, 102, - 103, 103, 105, 104, 107, 106, 106, 108, 108, 108, - 108, 108, 108, 109, 109, 111, 110, 112, 112, 112, - 113, 113, 113, 113, 113, 113, 113, 113, 113, 113, - 113, 113, 113, 113, 113, 114, 115, 115, 116, 117, - 116, 118, 118, 119, 119, 121, 120, 122, 122, 123, - 123, 124, 124, 126, 125, 127, 127, 128, 128, 129, - 129, 129, 129, 130, 130, 131, 131, 132, 132, 132, - 133, 133, 134, 134, 135, 135, 136, 137, 136, 136, - 136, 138, 138, 138, 139, 139, 140, 140, 140, 140, - 140, 141, 140, 140, 140, 140, 142, 140, 143, 143, - 144, 144, 145, 145, 145, 145, 145, 146, 146, 146, - 147, 148, 148, 149 + 0, 70, 71, 72, 72, 72, 72, 72, 72, 73, + 73, 74, 74, 74, 74, 74, 74, 74, 74, 74, + 74, 74, 75, 75, 75, 75, 76, 77, 78, 78, + 79, 80, 82, 81, 83, 83, 83, 83, 83, 83, + 83, 84, 84, 85, 86, 86, 87, 87, 89, 88, + 91, 90, 93, 92, 94, 94, 95, 96, 96, 96, + 96, 97, 97, 98, 99, 99, 100, 101, 102, 102, + 103, 104, 104, 105, 106, 106, 108, 107, 110, 109, + 109, 111, 111, 111, 111, 111, 111, 112, 112, 114, + 113, 115, 115, 115, 116, 116, 116, 116, 116, 116, + 116, 116, 116, 116, 116, 116, 116, 116, 116, 117, + 118, 118, 119, 120, 119, 121, 121, 122, 122, 124, + 123, 125, 125, 126, 126, 127, 127, 129, 128, 130, + 130, 131, 131, 132, 132, 132, 132, 133, 133, 134, + 134, 135, 135, 135, 136, 136, 137, 137, 138, 138, + 139, 140, 139, 139, 139, 141, 141, 141, 142, 142, + 143, 143, 143, 143, 143, 144, 143, 143, 143, 143, + 145, 143, 146, 146, 147, 147, 148, 148, 148, 148, + 148, 149, 149, 149, 150, 151, 151, 152 }; /* YYR2[YYN] -- Number of symbols on the right hand side of rule YYN. */ @@ -1038,22 +1042,22 @@ static const yytype_uint8 yyr2[] = 0, 2, 2, 1, 1, 1, 1, 1, 1, 0, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 4, 6, 8, 10, 2, 2, 1, 3, - 3, 4, 0, 3, 3, 3, 3, 4, 6, 1, - 3, 3, 0, 2, 1, 3, 0, 3, 0, 3, - 1, 3, 2, 0, 1, 1, 1, 2, 4, 2, - 2, 2, 4, 4, 3, 5, 2, 3, 5, 2, - 1, 1, 0, 9, 0, 3, 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, 1, - 3, 3, 5, 1, 2, 0, 2, 0, 2, 4, - 0, 2, 1, 1, 1, 3, 1, 0, 4, 2, - 2, 1, 1, 1, 1, 2, 1, 1, 1, 1, - 3, 0, 4, 3, 3, 4, 0, 8, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1 + 3, 4, 0, 3, 3, 3, 3, 3, 3, 6, + 4, 1, 3, 3, 0, 2, 1, 3, 0, 3, + 0, 3, 0, 3, 1, 3, 2, 0, 1, 1, + 1, 2, 4, 2, 2, 2, 4, 4, 3, 5, + 2, 3, 5, 2, 1, 1, 0, 9, 0, 3, + 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, 1, 3, 3, 5, 1, 2, 0, + 2, 0, 2, 4, 0, 2, 1, 1, 1, 3, + 1, 0, 4, 2, 2, 1, 1, 1, 1, 2, + 1, 1, 1, 1, 3, 0, 4, 3, 3, 4, + 0, 8, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1 }; @@ -1831,233 +1835,233 @@ yyreduce: switch (yyn) { case 2: -#line 217 "arangod/Aql/grammar.y" /* yacc.c:1646 */ +#line 219 "arangod/Aql/grammar.y" /* yacc.c:1646 */ { } -#line 1838 "arangod/Aql/grammar.cpp" /* yacc.c:1646 */ +#line 1842 "arangod/Aql/grammar.cpp" /* yacc.c:1646 */ break; case 3: -#line 222 "arangod/Aql/grammar.y" /* yacc.c:1646 */ +#line 224 "arangod/Aql/grammar.y" /* yacc.c:1646 */ { } -#line 1845 "arangod/Aql/grammar.cpp" /* yacc.c:1646 */ +#line 1849 "arangod/Aql/grammar.cpp" /* yacc.c:1646 */ break; case 4: -#line 224 "arangod/Aql/grammar.y" /* yacc.c:1646 */ +#line 226 "arangod/Aql/grammar.y" /* yacc.c:1646 */ { parser->ast()->scopes()->endNested(); } -#line 1853 "arangod/Aql/grammar.cpp" /* yacc.c:1646 */ +#line 1857 "arangod/Aql/grammar.cpp" /* yacc.c:1646 */ break; case 5: -#line 227 "arangod/Aql/grammar.y" /* yacc.c:1646 */ +#line 229 "arangod/Aql/grammar.y" /* yacc.c:1646 */ { parser->ast()->scopes()->endNested(); } -#line 1861 "arangod/Aql/grammar.cpp" /* yacc.c:1646 */ +#line 1865 "arangod/Aql/grammar.cpp" /* yacc.c:1646 */ break; case 6: -#line 230 "arangod/Aql/grammar.y" /* yacc.c:1646 */ +#line 232 "arangod/Aql/grammar.y" /* yacc.c:1646 */ { parser->ast()->scopes()->endNested(); } -#line 1869 "arangod/Aql/grammar.cpp" /* yacc.c:1646 */ +#line 1873 "arangod/Aql/grammar.cpp" /* yacc.c:1646 */ break; case 7: -#line 233 "arangod/Aql/grammar.y" /* yacc.c:1646 */ +#line 235 "arangod/Aql/grammar.y" /* yacc.c:1646 */ { parser->ast()->scopes()->endNested(); } -#line 1877 "arangod/Aql/grammar.cpp" /* yacc.c:1646 */ +#line 1881 "arangod/Aql/grammar.cpp" /* yacc.c:1646 */ break; case 8: -#line 236 "arangod/Aql/grammar.y" /* yacc.c:1646 */ +#line 238 "arangod/Aql/grammar.y" /* yacc.c:1646 */ { parser->ast()->scopes()->endNested(); } -#line 1885 "arangod/Aql/grammar.cpp" /* yacc.c:1646 */ +#line 1889 "arangod/Aql/grammar.cpp" /* yacc.c:1646 */ break; case 9: -#line 242 "arangod/Aql/grammar.y" /* yacc.c:1646 */ - { - } -#line 1892 "arangod/Aql/grammar.cpp" /* yacc.c:1646 */ - break; - - case 10: #line 244 "arangod/Aql/grammar.y" /* yacc.c:1646 */ { } -#line 1899 "arangod/Aql/grammar.cpp" /* yacc.c:1646 */ +#line 1896 "arangod/Aql/grammar.cpp" /* yacc.c:1646 */ + break; + + case 10: +#line 246 "arangod/Aql/grammar.y" /* yacc.c:1646 */ + { + } +#line 1903 "arangod/Aql/grammar.cpp" /* yacc.c:1646 */ break; case 11: -#line 249 "arangod/Aql/grammar.y" /* yacc.c:1646 */ - { - } -#line 1906 "arangod/Aql/grammar.cpp" /* yacc.c:1646 */ - break; - - case 12: #line 251 "arangod/Aql/grammar.y" /* yacc.c:1646 */ { } -#line 1913 "arangod/Aql/grammar.cpp" /* yacc.c:1646 */ +#line 1910 "arangod/Aql/grammar.cpp" /* yacc.c:1646 */ break; - case 13: + case 12: #line 253 "arangod/Aql/grammar.y" /* yacc.c:1646 */ { } -#line 1920 "arangod/Aql/grammar.cpp" /* yacc.c:1646 */ +#line 1917 "arangod/Aql/grammar.cpp" /* yacc.c:1646 */ break; - case 14: + case 13: #line 255 "arangod/Aql/grammar.y" /* yacc.c:1646 */ { } -#line 1927 "arangod/Aql/grammar.cpp" /* yacc.c:1646 */ +#line 1924 "arangod/Aql/grammar.cpp" /* yacc.c:1646 */ break; - case 15: + case 14: #line 257 "arangod/Aql/grammar.y" /* yacc.c:1646 */ { } -#line 1934 "arangod/Aql/grammar.cpp" /* yacc.c:1646 */ +#line 1931 "arangod/Aql/grammar.cpp" /* yacc.c:1646 */ break; - case 16: + case 15: #line 259 "arangod/Aql/grammar.y" /* yacc.c:1646 */ { } -#line 1941 "arangod/Aql/grammar.cpp" /* yacc.c:1646 */ +#line 1938 "arangod/Aql/grammar.cpp" /* yacc.c:1646 */ break; - case 17: + case 16: #line 261 "arangod/Aql/grammar.y" /* yacc.c:1646 */ { } -#line 1948 "arangod/Aql/grammar.cpp" /* yacc.c:1646 */ +#line 1945 "arangod/Aql/grammar.cpp" /* yacc.c:1646 */ break; - case 18: + case 17: #line 263 "arangod/Aql/grammar.y" /* yacc.c:1646 */ { } -#line 1955 "arangod/Aql/grammar.cpp" /* yacc.c:1646 */ +#line 1952 "arangod/Aql/grammar.cpp" /* yacc.c:1646 */ break; - case 19: + case 18: #line 265 "arangod/Aql/grammar.y" /* yacc.c:1646 */ { } -#line 1962 "arangod/Aql/grammar.cpp" /* yacc.c:1646 */ +#line 1959 "arangod/Aql/grammar.cpp" /* yacc.c:1646 */ break; - case 20: + case 19: #line 267 "arangod/Aql/grammar.y" /* yacc.c:1646 */ { } -#line 1969 "arangod/Aql/grammar.cpp" /* yacc.c:1646 */ +#line 1966 "arangod/Aql/grammar.cpp" /* yacc.c:1646 */ break; - case 21: + case 20: #line 269 "arangod/Aql/grammar.y" /* yacc.c:1646 */ { } -#line 1976 "arangod/Aql/grammar.cpp" /* yacc.c:1646 */ +#line 1973 "arangod/Aql/grammar.cpp" /* yacc.c:1646 */ + break; + + case 21: +#line 271 "arangod/Aql/grammar.y" /* yacc.c:1646 */ + { + } +#line 1980 "arangod/Aql/grammar.cpp" /* yacc.c:1646 */ break; case 22: -#line 274 "arangod/Aql/grammar.y" /* yacc.c:1646 */ +#line 276 "arangod/Aql/grammar.y" /* yacc.c:1646 */ { parser->ast()->scopes()->start(triagens::aql::AQL_SCOPE_FOR); auto node = parser->ast()->createNodeFor((yyvsp[-2].strval).value, (yyvsp[-2].strval).length, (yyvsp[0].node), true); parser->ast()->addOperation(node); } -#line 1987 "arangod/Aql/grammar.cpp" /* yacc.c:1646 */ +#line 1991 "arangod/Aql/grammar.cpp" /* yacc.c:1646 */ break; case 23: -#line 280 "arangod/Aql/grammar.y" /* yacc.c:1646 */ +#line 282 "arangod/Aql/grammar.y" /* yacc.c:1646 */ { parser->ast()->scopes()->start(triagens::aql::AQL_SCOPE_FOR); auto node = parser->ast()->createNodeTraversal((yyvsp[-4].strval).value, (yyvsp[-4].strval).length, (yyvsp[-2].node), (yyvsp[-1].node), (yyvsp[0].node)); parser->ast()->addOperation(node); } -#line 1997 "arangod/Aql/grammar.cpp" /* yacc.c:1646 */ +#line 2001 "arangod/Aql/grammar.cpp" /* yacc.c:1646 */ break; case 24: -#line 285 "arangod/Aql/grammar.y" /* yacc.c:1646 */ +#line 287 "arangod/Aql/grammar.y" /* yacc.c:1646 */ { parser->ast()->scopes()->start(triagens::aql::AQL_SCOPE_FOR); auto node = parser->ast()->createNodeTraversal((yyvsp[-6].strval).value, (yyvsp[-6].strval).length, (yyvsp[-4].strval).value, (yyvsp[-4].strval).length, (yyvsp[-2].node), (yyvsp[-1].node), (yyvsp[0].node)); parser->ast()->addOperation(node); } -#line 2007 "arangod/Aql/grammar.cpp" /* yacc.c:1646 */ +#line 2011 "arangod/Aql/grammar.cpp" /* yacc.c:1646 */ break; case 25: -#line 290 "arangod/Aql/grammar.y" /* yacc.c:1646 */ +#line 292 "arangod/Aql/grammar.y" /* yacc.c:1646 */ { parser->ast()->scopes()->start(triagens::aql::AQL_SCOPE_FOR); auto node = parser->ast()->createNodeTraversal((yyvsp[-8].strval).value, (yyvsp[-8].strval).length, (yyvsp[-6].strval).value, (yyvsp[-6].strval).length, (yyvsp[-4].strval).value, (yyvsp[-4].strval).length, (yyvsp[-2].node), (yyvsp[-1].node), (yyvsp[0].node)); parser->ast()->addOperation(node); } -#line 2017 "arangod/Aql/grammar.cpp" /* yacc.c:1646 */ +#line 2021 "arangod/Aql/grammar.cpp" /* yacc.c:1646 */ break; case 26: -#line 298 "arangod/Aql/grammar.y" /* yacc.c:1646 */ +#line 300 "arangod/Aql/grammar.y" /* yacc.c:1646 */ { // operand is a reference. can use it directly auto node = parser->ast()->createNodeFilter((yyvsp[0].node)); parser->ast()->addOperation(node); } -#line 2027 "arangod/Aql/grammar.cpp" /* yacc.c:1646 */ +#line 2031 "arangod/Aql/grammar.cpp" /* yacc.c:1646 */ break; case 27: -#line 306 "arangod/Aql/grammar.y" /* yacc.c:1646 */ +#line 308 "arangod/Aql/grammar.y" /* yacc.c:1646 */ { } -#line 2034 "arangod/Aql/grammar.cpp" /* yacc.c:1646 */ +#line 2038 "arangod/Aql/grammar.cpp" /* yacc.c:1646 */ break; case 28: -#line 311 "arangod/Aql/grammar.y" /* yacc.c:1646 */ - { - } -#line 2041 "arangod/Aql/grammar.cpp" /* yacc.c:1646 */ - break; - - case 29: #line 313 "arangod/Aql/grammar.y" /* yacc.c:1646 */ { } -#line 2048 "arangod/Aql/grammar.cpp" /* yacc.c:1646 */ +#line 2045 "arangod/Aql/grammar.cpp" /* yacc.c:1646 */ + break; + + case 29: +#line 315 "arangod/Aql/grammar.y" /* yacc.c:1646 */ + { + } +#line 2052 "arangod/Aql/grammar.cpp" /* yacc.c:1646 */ break; case 30: -#line 318 "arangod/Aql/grammar.y" /* yacc.c:1646 */ +#line 320 "arangod/Aql/grammar.y" /* yacc.c:1646 */ { auto node = parser->ast()->createNodeLet((yyvsp[-2].strval).value, (yyvsp[-2].strval).length, (yyvsp[0].node), true); parser->ast()->addOperation(node); } -#line 2057 "arangod/Aql/grammar.cpp" /* yacc.c:1646 */ +#line 2061 "arangod/Aql/grammar.cpp" /* yacc.c:1646 */ break; case 31: -#line 325 "arangod/Aql/grammar.y" /* yacc.c:1646 */ +#line 327 "arangod/Aql/grammar.y" /* yacc.c:1646 */ { if (! TRI_CaseEqualString((yyvsp[-2].strval).value, "COUNT")) { parser->registerParseError(TRI_ERROR_QUERY_PARSE, "unexpected qualifier '%s', expecting 'COUNT'", (yyvsp[-2].strval).value, yylloc.first_line, yylloc.first_column); @@ -2065,20 +2069,20 @@ yyreduce: (yyval.strval) = (yyvsp[0].strval); } -#line 2069 "arangod/Aql/grammar.cpp" /* yacc.c:1646 */ +#line 2073 "arangod/Aql/grammar.cpp" /* yacc.c:1646 */ break; case 32: -#line 335 "arangod/Aql/grammar.y" /* yacc.c:1646 */ +#line 337 "arangod/Aql/grammar.y" /* yacc.c:1646 */ { auto node = parser->ast()->createNodeArray(); parser->pushStack(node); } -#line 2078 "arangod/Aql/grammar.cpp" /* yacc.c:1646 */ +#line 2082 "arangod/Aql/grammar.cpp" /* yacc.c:1646 */ break; case 33: -#line 338 "arangod/Aql/grammar.y" /* yacc.c:1646 */ +#line 340 "arangod/Aql/grammar.y" /* yacc.c:1646 */ { auto list = static_cast(parser->popStack()); @@ -2087,12 +2091,13 @@ yyreduce: } (yyval.node) = list; } -#line 2091 "arangod/Aql/grammar.cpp" /* yacc.c:1646 */ +#line 2095 "arangod/Aql/grammar.cpp" /* yacc.c:1646 */ break; case 34: -#line 349 "arangod/Aql/grammar.y" /* yacc.c:1646 */ +#line 351 "arangod/Aql/grammar.y" /* yacc.c:1646 */ { + /* COLLECT WITH COUNT INTO var OPTIONS ... */ auto scopes = parser->ast()->scopes(); // check if we are in the main scope @@ -2108,12 +2113,13 @@ yyreduce: auto node = parser->ast()->createNodeCollectCount(parser->ast()->createNodeArray(), (yyvsp[-1].strval).value, (yyvsp[-1].strval).length, (yyvsp[0].node)); parser->ast()->addOperation(node); } -#line 2112 "arangod/Aql/grammar.cpp" /* yacc.c:1646 */ +#line 2117 "arangod/Aql/grammar.cpp" /* yacc.c:1646 */ break; case 35: -#line 365 "arangod/Aql/grammar.y" /* yacc.c:1646 */ +#line 368 "arangod/Aql/grammar.y" /* yacc.c:1646 */ { + /* COLLECT var = expr WITH COUNT INTO var OPTIONS ... */ auto scopes = parser->ast()->scopes(); // check if we are in the main scope @@ -2140,12 +2146,109 @@ yyreduce: auto node = parser->ast()->createNodeCollectCount((yyvsp[-2].node), (yyvsp[-1].strval).value, (yyvsp[-1].strval).length, (yyvsp[0].node)); parser->ast()->addOperation(node); } -#line 2144 "arangod/Aql/grammar.cpp" /* yacc.c:1646 */ +#line 2150 "arangod/Aql/grammar.cpp" /* yacc.c:1646 */ break; case 36: -#line 392 "arangod/Aql/grammar.y" /* yacc.c:1646 */ +#line 396 "arangod/Aql/grammar.y" /* yacc.c:1646 */ { + /* AGGREGATE var = expr OPTIONS ... */ + 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[-1].node)->numMembers(); + for (size_t i = 0; i < n; ++i) { + auto member = (yyvsp[-1].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()->createNodeCollectAggregate(parser->ast()->createNodeArray(), (yyvsp[-1].node), (yyvsp[0].node)); + parser->ast()->addOperation(node); + } +#line 2183 "arangod/Aql/grammar.cpp" /* yacc.c:1646 */ + break; + + case 37: +#line 424 "arangod/Aql/grammar.y" /* yacc.c:1646 */ + { + /* COLLECT var = expr AGGREGATE var = expr OPTIONS ... */ + 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); + + // register all used variables + size_t n = (yyvsp[-2].node)->numMembers(); + for (size_t i = 0; i < n; ++i) { + auto member = (yyvsp[-2].node)->getMember(i); + + if (member != nullptr) { + TRI_ASSERT(member->type == NODE_TYPE_ASSIGN); + auto v = static_cast(member->getMember(0)->getData()); + scopes->addVariable(v); + } + } + n = (yyvsp[-1].node)->numMembers(); + for (size_t i = 0; i < n; ++i) { + auto member = (yyvsp[-1].node)->getMember(i); + + if (member != nullptr) { + TRI_ASSERT(member->type == NODE_TYPE_ASSIGN); + auto func = member->getMember(1); + + bool isValid = true; + if (func->type != NODE_TYPE_FCALL) { + // aggregate expression must be a function call + isValid = false; + } + else { + auto f = static_cast(func->getData()); + if (f->externalName != "MIN" && f->externalName != "MAX" && f->externalName != "LENGTH") { + // aggregate expression must be a call to MIN|MAX|LENGTH + isValid = false; + } + } + + if (! isValid) { + parser->registerParseError(TRI_ERROR_QUERY_PARSE, "aggregate expression must be a function call", yylloc.first_line, yylloc.first_column); + } + + auto v = static_cast(member->getMember(0)->getData()); + scopes->addVariable(v); + } + } + } + + auto node = parser->ast()->createNodeCollectAggregate((yyvsp[-2].node), (yyvsp[-1].node), (yyvsp[0].node)); + parser->ast()->addOperation(node); + } +#line 2246 "arangod/Aql/grammar.cpp" /* yacc.c:1646 */ + break; + + case 38: +#line 482 "arangod/Aql/grammar.y" /* yacc.c:1646 */ + { + /* COLLECT var = expr INTO var OPTIONS ... */ auto scopes = parser->ast()->scopes(); // check if we are in the main scope @@ -2172,12 +2275,46 @@ yyreduce: auto node = parser->ast()->createNodeCollect((yyvsp[-2].node), (yyvsp[-1].strval).value, (yyvsp[-1].strval).length, nullptr, (yyvsp[0].node)); parser->ast()->addOperation(node); } -#line 2176 "arangod/Aql/grammar.cpp" /* yacc.c:1646 */ +#line 2279 "arangod/Aql/grammar.cpp" /* yacc.c:1646 */ break; - case 37: -#line 419 "arangod/Aql/grammar.y" /* yacc.c:1646 */ + case 39: +#line 510 "arangod/Aql/grammar.y" /* yacc.c:1646 */ { + /* COLLECT var = expr INTO var = expr OPTIONS ... */ + 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[-5].node)->numMembers(); + for (size_t i = 0; i < n; ++i) { + auto member = (yyvsp[-5].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[-5].node), (yyvsp[-3].strval).value, (yyvsp[-3].strval).length, (yyvsp[-1].node), (yyvsp[0].node)); + parser->ast()->addOperation(node); + } +#line 2312 "arangod/Aql/grammar.cpp" /* yacc.c:1646 */ + break; + + case 40: +#line 538 "arangod/Aql/grammar.y" /* yacc.c:1646 */ + { + /* COLLECT var = expr INTO var KEEP ... OPTIONS ... */ auto scopes = parser->ast()->scopes(); // check if we are in the main scope @@ -2209,122 +2346,90 @@ yyreduce: auto node = parser->ast()->createNodeCollect((yyvsp[-3].node), (yyvsp[-2].strval).value, (yyvsp[-2].strval).length, (yyvsp[-1].node), (yyvsp[0].node)); parser->ast()->addOperation(node); } -#line 2213 "arangod/Aql/grammar.cpp" /* yacc.c:1646 */ - break; - - case 38: -#line 451 "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[-5].node)->numMembers(); - for (size_t i = 0; i < n; ++i) { - auto member = (yyvsp[-5].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[-5].node), (yyvsp[-3].strval).value, (yyvsp[-3].strval).length, (yyvsp[-1].node), (yyvsp[0].node)); - parser->ast()->addOperation(node); - } -#line 2245 "arangod/Aql/grammar.cpp" /* yacc.c:1646 */ - break; - - case 39: -#line 481 "arangod/Aql/grammar.y" /* yacc.c:1646 */ - { - } -#line 2252 "arangod/Aql/grammar.cpp" /* yacc.c:1646 */ - break; - - case 40: -#line 483 "arangod/Aql/grammar.y" /* yacc.c:1646 */ - { - } -#line 2259 "arangod/Aql/grammar.cpp" /* yacc.c:1646 */ +#line 2350 "arangod/Aql/grammar.cpp" /* yacc.c:1646 */ break; case 41: -#line 488 "arangod/Aql/grammar.y" /* yacc.c:1646 */ +#line 574 "arangod/Aql/grammar.y" /* yacc.c:1646 */ + { + } +#line 2357 "arangod/Aql/grammar.cpp" /* yacc.c:1646 */ + break; + + case 42: +#line 576 "arangod/Aql/grammar.y" /* yacc.c:1646 */ + { + } +#line 2364 "arangod/Aql/grammar.cpp" /* yacc.c:1646 */ + break; + + case 43: +#line 581 "arangod/Aql/grammar.y" /* yacc.c:1646 */ { auto node = parser->ast()->createNodeAssign((yyvsp[-2].strval).value, (yyvsp[-2].strval).length, (yyvsp[0].node)); parser->pushArrayElement(node); } -#line 2268 "arangod/Aql/grammar.cpp" /* yacc.c:1646 */ +#line 2373 "arangod/Aql/grammar.cpp" /* yacc.c:1646 */ break; - case 42: -#line 495 "arangod/Aql/grammar.y" /* yacc.c:1646 */ + case 44: +#line 588 "arangod/Aql/grammar.y" /* yacc.c:1646 */ { (yyval.strval).value = nullptr; (yyval.strval).length = 0; } -#line 2277 "arangod/Aql/grammar.cpp" /* yacc.c:1646 */ +#line 2382 "arangod/Aql/grammar.cpp" /* yacc.c:1646 */ break; - case 43: -#line 499 "arangod/Aql/grammar.y" /* yacc.c:1646 */ + case 45: +#line 592 "arangod/Aql/grammar.y" /* yacc.c:1646 */ { (yyval.strval).value = (yyvsp[0].strval).value; (yyval.strval).length = (yyvsp[0].strval).length; } -#line 2286 "arangod/Aql/grammar.cpp" /* yacc.c:1646 */ - break; - - case 44: -#line 506 "arangod/Aql/grammar.y" /* yacc.c:1646 */ - { - if (! parser->ast()->scopes()->existsVariable((yyvsp[0].strval).value, (yyvsp[0].strval).length)) { - parser->registerParseError(TRI_ERROR_QUERY_PARSE, "use of unknown variable '%s' for KEEP", (yyvsp[0].strval).value, yylloc.first_line, yylloc.first_column); - } - - auto node = parser->ast()->createNodeReference((yyvsp[0].strval).value, (yyvsp[0].strval).length); - 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->pushArrayElement(node); - } -#line 2305 "arangod/Aql/grammar.cpp" /* yacc.c:1646 */ - break; - - case 45: -#line 520 "arangod/Aql/grammar.y" /* yacc.c:1646 */ - { - if (! parser->ast()->scopes()->existsVariable((yyvsp[0].strval).value, (yyvsp[0].strval).length)) { - parser->registerParseError(TRI_ERROR_QUERY_PARSE, "use of unknown variable '%s' for KEEP", (yyvsp[0].strval).value, yylloc.first_line, yylloc.first_column); - } - - auto node = parser->ast()->createNodeReference((yyvsp[0].strval).value, (yyvsp[0].strval).length); - 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->pushArrayElement(node); - } -#line 2324 "arangod/Aql/grammar.cpp" /* yacc.c:1646 */ +#line 2391 "arangod/Aql/grammar.cpp" /* yacc.c:1646 */ break; case 46: -#line 537 "arangod/Aql/grammar.y" /* yacc.c:1646 */ +#line 599 "arangod/Aql/grammar.y" /* yacc.c:1646 */ + { + if (! parser->ast()->scopes()->existsVariable((yyvsp[0].strval).value, (yyvsp[0].strval).length)) { + parser->registerParseError(TRI_ERROR_QUERY_PARSE, "use of unknown variable '%s' for KEEP", (yyvsp[0].strval).value, yylloc.first_line, yylloc.first_column); + } + + auto node = parser->ast()->createNodeReference((yyvsp[0].strval).value, (yyvsp[0].strval).length); + 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->pushArrayElement(node); + } +#line 2410 "arangod/Aql/grammar.cpp" /* yacc.c:1646 */ + break; + + case 47: +#line 613 "arangod/Aql/grammar.y" /* yacc.c:1646 */ + { + if (! parser->ast()->scopes()->existsVariable((yyvsp[0].strval).value, (yyvsp[0].strval).length)) { + parser->registerParseError(TRI_ERROR_QUERY_PARSE, "use of unknown variable '%s' for KEEP", (yyvsp[0].strval).value, yylloc.first_line, yylloc.first_column); + } + + auto node = parser->ast()->createNodeReference((yyvsp[0].strval).value, (yyvsp[0].strval).length); + 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->pushArrayElement(node); + } +#line 2429 "arangod/Aql/grammar.cpp" /* yacc.c:1646 */ + break; + + case 48: +#line 630 "arangod/Aql/grammar.y" /* yacc.c:1646 */ { if (! TRI_CaseEqualString((yyvsp[0].strval).value, "KEEP")) { parser->registerParseError(TRI_ERROR_QUERY_PARSE, "unexpected qualifier '%s', expecting 'KEEP'", (yyvsp[0].strval).value, yylloc.first_line, yylloc.first_column); @@ -2333,140 +2438,158 @@ yyreduce: auto node = parser->ast()->createNodeArray(); parser->pushStack(node); } -#line 2337 "arangod/Aql/grammar.cpp" /* yacc.c:1646 */ +#line 2442 "arangod/Aql/grammar.cpp" /* yacc.c:1646 */ break; - case 47: -#line 544 "arangod/Aql/grammar.y" /* yacc.c:1646 */ + case 49: +#line 637 "arangod/Aql/grammar.y" /* yacc.c:1646 */ { auto list = static_cast(parser->popStack()); (yyval.node) = list; } -#line 2346 "arangod/Aql/grammar.cpp" /* yacc.c:1646 */ +#line 2451 "arangod/Aql/grammar.cpp" /* yacc.c:1646 */ break; - case 48: -#line 551 "arangod/Aql/grammar.y" /* yacc.c:1646 */ + case 50: +#line 644 "arangod/Aql/grammar.y" /* yacc.c:1646 */ { auto node = parser->ast()->createNodeArray(); parser->pushStack(node); } -#line 2355 "arangod/Aql/grammar.cpp" /* yacc.c:1646 */ +#line 2460 "arangod/Aql/grammar.cpp" /* yacc.c:1646 */ break; - case 49: -#line 554 "arangod/Aql/grammar.y" /* yacc.c:1646 */ + case 51: +#line 647 "arangod/Aql/grammar.y" /* yacc.c:1646 */ + { + auto list = static_cast(parser->popStack()); + (yyval.node) = list; + } +#line 2469 "arangod/Aql/grammar.cpp" /* yacc.c:1646 */ + break; + + case 52: +#line 654 "arangod/Aql/grammar.y" /* yacc.c:1646 */ + { + auto node = parser->ast()->createNodeArray(); + parser->pushStack(node); + } +#line 2478 "arangod/Aql/grammar.cpp" /* yacc.c:1646 */ + break; + + case 53: +#line 657 "arangod/Aql/grammar.y" /* yacc.c:1646 */ { auto list = static_cast(parser->popStack()); auto node = parser->ast()->createNodeSort(list); parser->ast()->addOperation(node); } -#line 2365 "arangod/Aql/grammar.cpp" /* yacc.c:1646 */ - break; - - case 50: -#line 562 "arangod/Aql/grammar.y" /* yacc.c:1646 */ - { - parser->pushArrayElement((yyvsp[0].node)); - } -#line 2373 "arangod/Aql/grammar.cpp" /* yacc.c:1646 */ - break; - - case 51: -#line 565 "arangod/Aql/grammar.y" /* yacc.c:1646 */ - { - parser->pushArrayElement((yyvsp[0].node)); - } -#line 2381 "arangod/Aql/grammar.cpp" /* yacc.c:1646 */ - break; - - case 52: -#line 571 "arangod/Aql/grammar.y" /* yacc.c:1646 */ - { - (yyval.node) = parser->ast()->createNodeSortElement((yyvsp[-1].node), (yyvsp[0].node)); - } -#line 2389 "arangod/Aql/grammar.cpp" /* yacc.c:1646 */ - break; - - case 53: -#line 577 "arangod/Aql/grammar.y" /* yacc.c:1646 */ - { - (yyval.node) = parser->ast()->createNodeValueBool(true); - } -#line 2397 "arangod/Aql/grammar.cpp" /* yacc.c:1646 */ +#line 2488 "arangod/Aql/grammar.cpp" /* yacc.c:1646 */ break; case 54: -#line 580 "arangod/Aql/grammar.y" /* yacc.c:1646 */ +#line 665 "arangod/Aql/grammar.y" /* yacc.c:1646 */ { - (yyval.node) = parser->ast()->createNodeValueBool(true); + parser->pushArrayElement((yyvsp[0].node)); } -#line 2405 "arangod/Aql/grammar.cpp" /* yacc.c:1646 */ +#line 2496 "arangod/Aql/grammar.cpp" /* yacc.c:1646 */ break; case 55: -#line 583 "arangod/Aql/grammar.y" /* yacc.c:1646 */ +#line 668 "arangod/Aql/grammar.y" /* yacc.c:1646 */ { - (yyval.node) = parser->ast()->createNodeValueBool(false); + parser->pushArrayElement((yyvsp[0].node)); } -#line 2413 "arangod/Aql/grammar.cpp" /* yacc.c:1646 */ +#line 2504 "arangod/Aql/grammar.cpp" /* yacc.c:1646 */ break; case 56: -#line 586 "arangod/Aql/grammar.y" /* yacc.c:1646 */ +#line 674 "arangod/Aql/grammar.y" /* yacc.c:1646 */ { - (yyval.node) = (yyvsp[0].node); + (yyval.node) = parser->ast()->createNodeSortElement((yyvsp[-1].node), (yyvsp[0].node)); } -#line 2421 "arangod/Aql/grammar.cpp" /* yacc.c:1646 */ +#line 2512 "arangod/Aql/grammar.cpp" /* yacc.c:1646 */ break; case 57: -#line 592 "arangod/Aql/grammar.y" /* yacc.c:1646 */ +#line 680 "arangod/Aql/grammar.y" /* yacc.c:1646 */ + { + (yyval.node) = parser->ast()->createNodeValueBool(true); + } +#line 2520 "arangod/Aql/grammar.cpp" /* yacc.c:1646 */ + break; + + case 58: +#line 683 "arangod/Aql/grammar.y" /* yacc.c:1646 */ + { + (yyval.node) = parser->ast()->createNodeValueBool(true); + } +#line 2528 "arangod/Aql/grammar.cpp" /* yacc.c:1646 */ + break; + + case 59: +#line 686 "arangod/Aql/grammar.y" /* yacc.c:1646 */ + { + (yyval.node) = parser->ast()->createNodeValueBool(false); + } +#line 2536 "arangod/Aql/grammar.cpp" /* yacc.c:1646 */ + break; + + case 60: +#line 689 "arangod/Aql/grammar.y" /* yacc.c:1646 */ + { + (yyval.node) = (yyvsp[0].node); + } +#line 2544 "arangod/Aql/grammar.cpp" /* yacc.c:1646 */ + break; + + case 61: +#line 695 "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 2431 "arangod/Aql/grammar.cpp" /* yacc.c:1646 */ +#line 2554 "arangod/Aql/grammar.cpp" /* yacc.c:1646 */ break; - case 58: -#line 597 "arangod/Aql/grammar.y" /* yacc.c:1646 */ + case 62: +#line 700 "arangod/Aql/grammar.y" /* yacc.c:1646 */ { auto node = parser->ast()->createNodeLimit((yyvsp[-2].node), (yyvsp[0].node)); parser->ast()->addOperation(node); } -#line 2440 "arangod/Aql/grammar.cpp" /* yacc.c:1646 */ +#line 2563 "arangod/Aql/grammar.cpp" /* yacc.c:1646 */ break; - case 59: -#line 604 "arangod/Aql/grammar.y" /* yacc.c:1646 */ + case 63: +#line 707 "arangod/Aql/grammar.y" /* yacc.c:1646 */ { auto node = parser->ast()->createNodeReturn((yyvsp[0].node)); parser->ast()->addOperation(node); parser->ast()->scopes()->endNested(); } -#line 2450 "arangod/Aql/grammar.cpp" /* yacc.c:1646 */ +#line 2573 "arangod/Aql/grammar.cpp" /* yacc.c:1646 */ break; - case 60: -#line 612 "arangod/Aql/grammar.y" /* yacc.c:1646 */ + case 64: +#line 715 "arangod/Aql/grammar.y" /* yacc.c:1646 */ { (yyval.node) = (yyvsp[0].node); } -#line 2458 "arangod/Aql/grammar.cpp" /* yacc.c:1646 */ +#line 2581 "arangod/Aql/grammar.cpp" /* yacc.c:1646 */ break; - case 61: -#line 615 "arangod/Aql/grammar.y" /* yacc.c:1646 */ + case 65: +#line 718 "arangod/Aql/grammar.y" /* yacc.c:1646 */ { (yyval.node) = (yyvsp[0].node); } -#line 2466 "arangod/Aql/grammar.cpp" /* yacc.c:1646 */ +#line 2589 "arangod/Aql/grammar.cpp" /* yacc.c:1646 */ break; - case 62: -#line 621 "arangod/Aql/grammar.y" /* yacc.c:1646 */ + case 66: +#line 724 "arangod/Aql/grammar.y" /* yacc.c:1646 */ { if (! parser->configureWriteQuery((yyvsp[-1].node), (yyvsp[0].node))) { YYABORT; @@ -2474,11 +2597,11 @@ yyreduce: auto node = parser->ast()->createNodeRemove((yyvsp[-2].node), (yyvsp[-1].node), (yyvsp[0].node)); parser->ast()->addOperation(node); } -#line 2478 "arangod/Aql/grammar.cpp" /* yacc.c:1646 */ +#line 2601 "arangod/Aql/grammar.cpp" /* yacc.c:1646 */ break; - case 63: -#line 631 "arangod/Aql/grammar.y" /* yacc.c:1646 */ + case 67: +#line 734 "arangod/Aql/grammar.y" /* yacc.c:1646 */ { if (! parser->configureWriteQuery((yyvsp[-1].node), (yyvsp[0].node))) { YYABORT; @@ -2486,11 +2609,11 @@ yyreduce: auto node = parser->ast()->createNodeInsert((yyvsp[-2].node), (yyvsp[-1].node), (yyvsp[0].node)); parser->ast()->addOperation(node); } -#line 2490 "arangod/Aql/grammar.cpp" /* yacc.c:1646 */ +#line 2613 "arangod/Aql/grammar.cpp" /* yacc.c:1646 */ break; - case 64: -#line 641 "arangod/Aql/grammar.y" /* yacc.c:1646 */ + case 68: +#line 744 "arangod/Aql/grammar.y" /* yacc.c:1646 */ { if (! parser->configureWriteQuery((yyvsp[-1].node), (yyvsp[0].node))) { YYABORT; @@ -2499,11 +2622,11 @@ yyreduce: AstNode* node = parser->ast()->createNodeUpdate(nullptr, (yyvsp[-2].node), (yyvsp[-1].node), (yyvsp[0].node)); parser->ast()->addOperation(node); } -#line 2503 "arangod/Aql/grammar.cpp" /* yacc.c:1646 */ +#line 2626 "arangod/Aql/grammar.cpp" /* yacc.c:1646 */ break; - case 65: -#line 649 "arangod/Aql/grammar.y" /* yacc.c:1646 */ + case 69: +#line 752 "arangod/Aql/grammar.y" /* yacc.c:1646 */ { if (! parser->configureWriteQuery((yyvsp[-1].node), (yyvsp[0].node))) { YYABORT; @@ -2512,18 +2635,18 @@ yyreduce: AstNode* node = parser->ast()->createNodeUpdate((yyvsp[-4].node), (yyvsp[-2].node), (yyvsp[-1].node), (yyvsp[0].node)); parser->ast()->addOperation(node); } -#line 2516 "arangod/Aql/grammar.cpp" /* yacc.c:1646 */ +#line 2639 "arangod/Aql/grammar.cpp" /* yacc.c:1646 */ break; - case 66: -#line 660 "arangod/Aql/grammar.y" /* yacc.c:1646 */ + case 70: +#line 763 "arangod/Aql/grammar.y" /* yacc.c:1646 */ { } -#line 2523 "arangod/Aql/grammar.cpp" /* yacc.c:1646 */ +#line 2646 "arangod/Aql/grammar.cpp" /* yacc.c:1646 */ break; - case 67: -#line 665 "arangod/Aql/grammar.y" /* yacc.c:1646 */ + case 71: +#line 768 "arangod/Aql/grammar.y" /* yacc.c:1646 */ { if (! parser->configureWriteQuery((yyvsp[-1].node), (yyvsp[0].node))) { YYABORT; @@ -2532,11 +2655,11 @@ yyreduce: AstNode* node = parser->ast()->createNodeReplace(nullptr, (yyvsp[-2].node), (yyvsp[-1].node), (yyvsp[0].node)); parser->ast()->addOperation(node); } -#line 2536 "arangod/Aql/grammar.cpp" /* yacc.c:1646 */ +#line 2659 "arangod/Aql/grammar.cpp" /* yacc.c:1646 */ break; - case 68: -#line 673 "arangod/Aql/grammar.y" /* yacc.c:1646 */ + case 72: +#line 776 "arangod/Aql/grammar.y" /* yacc.c:1646 */ { if (! parser->configureWriteQuery((yyvsp[-1].node), (yyvsp[0].node))) { YYABORT; @@ -2545,44 +2668,44 @@ yyreduce: AstNode* node = parser->ast()->createNodeReplace((yyvsp[-4].node), (yyvsp[-2].node), (yyvsp[-1].node), (yyvsp[0].node)); parser->ast()->addOperation(node); } -#line 2549 "arangod/Aql/grammar.cpp" /* yacc.c:1646 */ +#line 2672 "arangod/Aql/grammar.cpp" /* yacc.c:1646 */ break; - case 69: -#line 684 "arangod/Aql/grammar.y" /* yacc.c:1646 */ + case 73: +#line 787 "arangod/Aql/grammar.y" /* yacc.c:1646 */ { } -#line 2556 "arangod/Aql/grammar.cpp" /* yacc.c:1646 */ +#line 2679 "arangod/Aql/grammar.cpp" /* yacc.c:1646 */ break; - case 70: -#line 689 "arangod/Aql/grammar.y" /* yacc.c:1646 */ + case 74: +#line 792 "arangod/Aql/grammar.y" /* yacc.c:1646 */ { (yyval.intval) = static_cast(NODE_TYPE_UPDATE); } -#line 2564 "arangod/Aql/grammar.cpp" /* yacc.c:1646 */ +#line 2687 "arangod/Aql/grammar.cpp" /* yacc.c:1646 */ break; - case 71: -#line 692 "arangod/Aql/grammar.y" /* yacc.c:1646 */ + case 75: +#line 795 "arangod/Aql/grammar.y" /* yacc.c:1646 */ { (yyval.intval) = static_cast(NODE_TYPE_REPLACE); } -#line 2572 "arangod/Aql/grammar.cpp" /* yacc.c:1646 */ +#line 2695 "arangod/Aql/grammar.cpp" /* yacc.c:1646 */ break; - case 72: -#line 698 "arangod/Aql/grammar.y" /* yacc.c:1646 */ + case 76: +#line 801 "arangod/Aql/grammar.y" /* yacc.c:1646 */ { // reserve a variable named "$OLD", we might need it in the update expression // and in a later return thing parser->pushStack(parser->ast()->createNodeVariable(TRI_CHAR_LENGTH_PAIR(Variable::NAME_OLD), true)); } -#line 2582 "arangod/Aql/grammar.cpp" /* yacc.c:1646 */ +#line 2705 "arangod/Aql/grammar.cpp" /* yacc.c:1646 */ break; - case 73: -#line 702 "arangod/Aql/grammar.y" /* yacc.c:1646 */ + case 77: +#line 805 "arangod/Aql/grammar.y" /* yacc.c:1646 */ { if (! parser->configureWriteQuery((yyvsp[-1].node), (yyvsp[0].node))) { YYABORT; @@ -2627,11 +2750,11 @@ yyreduce: auto node = parser->ast()->createNodeUpsert(static_cast((yyvsp[-3].intval)), parser->ast()->createNodeReference(TRI_CHAR_LENGTH_PAIR(Variable::NAME_OLD)), (yyvsp[-4].node), (yyvsp[-2].node), (yyvsp[-1].node), (yyvsp[0].node)); parser->ast()->addOperation(node); } -#line 2631 "arangod/Aql/grammar.cpp" /* yacc.c:1646 */ +#line 2754 "arangod/Aql/grammar.cpp" /* yacc.c:1646 */ break; - case 74: -#line 749 "arangod/Aql/grammar.y" /* yacc.c:1646 */ + case 78: +#line 852 "arangod/Aql/grammar.y" /* yacc.c:1646 */ { auto const scopeType = parser->ast()->scopes()->type(); @@ -2640,83 +2763,83 @@ yyreduce: parser->registerParseError(TRI_ERROR_QUERY_PARSE, "cannot use DISTINCT modifier on top-level query element", yylloc.first_line, yylloc.first_column); } } -#line 2644 "arangod/Aql/grammar.cpp" /* yacc.c:1646 */ - break; - - case 75: -#line 756 "arangod/Aql/grammar.y" /* yacc.c:1646 */ - { - (yyval.node) = parser->ast()->createNodeDistinct((yyvsp[0].node)); - } -#line 2652 "arangod/Aql/grammar.cpp" /* yacc.c:1646 */ - break; - - case 76: -#line 759 "arangod/Aql/grammar.y" /* yacc.c:1646 */ - { - (yyval.node) = (yyvsp[0].node); - } -#line 2660 "arangod/Aql/grammar.cpp" /* yacc.c:1646 */ - break; - - case 77: -#line 765 "arangod/Aql/grammar.y" /* yacc.c:1646 */ - { - (yyval.node) = (yyvsp[0].node); - } -#line 2668 "arangod/Aql/grammar.cpp" /* yacc.c:1646 */ - break; - - case 78: -#line 768 "arangod/Aql/grammar.y" /* yacc.c:1646 */ - { - (yyval.node) = (yyvsp[0].node); - } -#line 2676 "arangod/Aql/grammar.cpp" /* yacc.c:1646 */ +#line 2767 "arangod/Aql/grammar.cpp" /* yacc.c:1646 */ break; case 79: -#line 771 "arangod/Aql/grammar.y" /* yacc.c:1646 */ +#line 859 "arangod/Aql/grammar.y" /* yacc.c:1646 */ { - (yyval.node) = (yyvsp[0].node); + (yyval.node) = parser->ast()->createNodeDistinct((yyvsp[0].node)); } -#line 2684 "arangod/Aql/grammar.cpp" /* yacc.c:1646 */ +#line 2775 "arangod/Aql/grammar.cpp" /* yacc.c:1646 */ break; case 80: -#line 774 "arangod/Aql/grammar.y" /* yacc.c:1646 */ +#line 862 "arangod/Aql/grammar.y" /* yacc.c:1646 */ { (yyval.node) = (yyvsp[0].node); } -#line 2692 "arangod/Aql/grammar.cpp" /* yacc.c:1646 */ +#line 2783 "arangod/Aql/grammar.cpp" /* yacc.c:1646 */ break; case 81: -#line 777 "arangod/Aql/grammar.y" /* yacc.c:1646 */ +#line 868 "arangod/Aql/grammar.y" /* yacc.c:1646 */ { (yyval.node) = (yyvsp[0].node); } -#line 2700 "arangod/Aql/grammar.cpp" /* yacc.c:1646 */ +#line 2791 "arangod/Aql/grammar.cpp" /* yacc.c:1646 */ break; case 82: -#line 780 "arangod/Aql/grammar.y" /* yacc.c:1646 */ +#line 871 "arangod/Aql/grammar.y" /* yacc.c:1646 */ { - (yyval.node) = parser->ast()->createNodeRange((yyvsp[-2].node), (yyvsp[0].node)); + (yyval.node) = (yyvsp[0].node); } -#line 2708 "arangod/Aql/grammar.cpp" /* yacc.c:1646 */ +#line 2799 "arangod/Aql/grammar.cpp" /* yacc.c:1646 */ break; case 83: -#line 786 "arangod/Aql/grammar.y" /* yacc.c:1646 */ +#line 874 "arangod/Aql/grammar.y" /* yacc.c:1646 */ { - (yyval.strval) = (yyvsp[0].strval); + (yyval.node) = (yyvsp[0].node); } -#line 2716 "arangod/Aql/grammar.cpp" /* yacc.c:1646 */ +#line 2807 "arangod/Aql/grammar.cpp" /* yacc.c:1646 */ break; case 84: -#line 789 "arangod/Aql/grammar.y" /* yacc.c:1646 */ +#line 877 "arangod/Aql/grammar.y" /* yacc.c:1646 */ + { + (yyval.node) = (yyvsp[0].node); + } +#line 2815 "arangod/Aql/grammar.cpp" /* yacc.c:1646 */ + break; + + case 85: +#line 880 "arangod/Aql/grammar.y" /* yacc.c:1646 */ + { + (yyval.node) = (yyvsp[0].node); + } +#line 2823 "arangod/Aql/grammar.cpp" /* yacc.c:1646 */ + break; + + case 86: +#line 883 "arangod/Aql/grammar.y" /* yacc.c:1646 */ + { + (yyval.node) = parser->ast()->createNodeRange((yyvsp[-2].node), (yyvsp[0].node)); + } +#line 2831 "arangod/Aql/grammar.cpp" /* yacc.c:1646 */ + break; + + case 87: +#line 889 "arangod/Aql/grammar.y" /* yacc.c:1646 */ + { + (yyval.strval) = (yyvsp[0].strval); + } +#line 2839 "arangod/Aql/grammar.cpp" /* yacc.c:1646 */ + break; + + case 88: +#line 892 "arangod/Aql/grammar.y" /* yacc.c:1646 */ { std::string temp((yyvsp[-2].strval).value, (yyvsp[-2].strval).length); temp.append("::"); @@ -2730,214 +2853,214 @@ yyreduce: (yyval.strval).value = p; (yyval.strval).length = temp.size(); } -#line 2734 "arangod/Aql/grammar.cpp" /* yacc.c:1646 */ +#line 2857 "arangod/Aql/grammar.cpp" /* yacc.c:1646 */ break; - case 85: -#line 805 "arangod/Aql/grammar.y" /* yacc.c:1646 */ + case 89: +#line 908 "arangod/Aql/grammar.y" /* yacc.c:1646 */ { parser->pushStack((yyvsp[0].strval).value); auto node = parser->ast()->createNodeArray(); parser->pushStack(node); } -#line 2745 "arangod/Aql/grammar.cpp" /* yacc.c:1646 */ +#line 2868 "arangod/Aql/grammar.cpp" /* yacc.c:1646 */ break; - case 86: -#line 810 "arangod/Aql/grammar.y" /* yacc.c:1646 */ + case 90: +#line 913 "arangod/Aql/grammar.y" /* yacc.c:1646 */ { auto list = static_cast(parser->popStack()); (yyval.node) = parser->ast()->createNodeFunctionCall(static_cast(parser->popStack()), list); } -#line 2754 "arangod/Aql/grammar.cpp" /* yacc.c:1646 */ - break; - - case 87: -#line 817 "arangod/Aql/grammar.y" /* yacc.c:1646 */ - { - (yyval.node) = parser->ast()->createNodeUnaryOperator(NODE_TYPE_OPERATOR_UNARY_PLUS, (yyvsp[0].node)); - } -#line 2762 "arangod/Aql/grammar.cpp" /* yacc.c:1646 */ - break; - - case 88: -#line 820 "arangod/Aql/grammar.y" /* yacc.c:1646 */ - { - (yyval.node) = parser->ast()->createNodeUnaryOperator(NODE_TYPE_OPERATOR_UNARY_MINUS, (yyvsp[0].node)); - } -#line 2770 "arangod/Aql/grammar.cpp" /* yacc.c:1646 */ - break; - - case 89: -#line 823 "arangod/Aql/grammar.y" /* yacc.c:1646 */ - { - (yyval.node) = parser->ast()->createNodeUnaryOperator(NODE_TYPE_OPERATOR_UNARY_NOT, (yyvsp[0].node)); - } -#line 2778 "arangod/Aql/grammar.cpp" /* yacc.c:1646 */ - break; - - case 90: -#line 829 "arangod/Aql/grammar.y" /* yacc.c:1646 */ - { - (yyval.node) = parser->ast()->createNodeBinaryOperator(NODE_TYPE_OPERATOR_BINARY_OR, (yyvsp[-2].node), (yyvsp[0].node)); - } -#line 2786 "arangod/Aql/grammar.cpp" /* yacc.c:1646 */ +#line 2877 "arangod/Aql/grammar.cpp" /* yacc.c:1646 */ break; case 91: -#line 832 "arangod/Aql/grammar.y" /* yacc.c:1646 */ +#line 920 "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()->createNodeUnaryOperator(NODE_TYPE_OPERATOR_UNARY_PLUS, (yyvsp[0].node)); } -#line 2794 "arangod/Aql/grammar.cpp" /* yacc.c:1646 */ +#line 2885 "arangod/Aql/grammar.cpp" /* yacc.c:1646 */ break; case 92: -#line 835 "arangod/Aql/grammar.y" /* yacc.c:1646 */ +#line 923 "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()->createNodeUnaryOperator(NODE_TYPE_OPERATOR_UNARY_MINUS, (yyvsp[0].node)); } -#line 2802 "arangod/Aql/grammar.cpp" /* yacc.c:1646 */ +#line 2893 "arangod/Aql/grammar.cpp" /* yacc.c:1646 */ break; case 93: -#line 838 "arangod/Aql/grammar.y" /* yacc.c:1646 */ - { - (yyval.node) = parser->ast()->createNodeBinaryOperator(NODE_TYPE_OPERATOR_BINARY_MINUS, (yyvsp[-2].node), (yyvsp[0].node)); +#line 926 "arangod/Aql/grammar.y" /* yacc.c:1646 */ + { + (yyval.node) = parser->ast()->createNodeUnaryOperator(NODE_TYPE_OPERATOR_UNARY_NOT, (yyvsp[0].node)); } -#line 2810 "arangod/Aql/grammar.cpp" /* yacc.c:1646 */ +#line 2901 "arangod/Aql/grammar.cpp" /* yacc.c:1646 */ break; case 94: -#line 841 "arangod/Aql/grammar.y" /* yacc.c:1646 */ +#line 932 "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_OR, (yyvsp[-2].node), (yyvsp[0].node)); } -#line 2818 "arangod/Aql/grammar.cpp" /* yacc.c:1646 */ +#line 2909 "arangod/Aql/grammar.cpp" /* yacc.c:1646 */ break; case 95: -#line 844 "arangod/Aql/grammar.y" /* yacc.c:1646 */ +#line 935 "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_AND, (yyvsp[-2].node), (yyvsp[0].node)); } -#line 2826 "arangod/Aql/grammar.cpp" /* yacc.c:1646 */ +#line 2917 "arangod/Aql/grammar.cpp" /* yacc.c:1646 */ break; case 96: -#line 847 "arangod/Aql/grammar.y" /* yacc.c:1646 */ +#line 938 "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_PLUS, (yyvsp[-2].node), (yyvsp[0].node)); } -#line 2834 "arangod/Aql/grammar.cpp" /* yacc.c:1646 */ +#line 2925 "arangod/Aql/grammar.cpp" /* yacc.c:1646 */ break; case 97: -#line 850 "arangod/Aql/grammar.y" /* yacc.c:1646 */ +#line 941 "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_MINUS, (yyvsp[-2].node), (yyvsp[0].node)); } -#line 2842 "arangod/Aql/grammar.cpp" /* yacc.c:1646 */ +#line 2933 "arangod/Aql/grammar.cpp" /* yacc.c:1646 */ break; case 98: -#line 853 "arangod/Aql/grammar.y" /* yacc.c:1646 */ +#line 944 "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_TIMES, (yyvsp[-2].node), (yyvsp[0].node)); } -#line 2850 "arangod/Aql/grammar.cpp" /* yacc.c:1646 */ +#line 2941 "arangod/Aql/grammar.cpp" /* yacc.c:1646 */ break; case 99: -#line 856 "arangod/Aql/grammar.y" /* yacc.c:1646 */ +#line 947 "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_DIV, (yyvsp[-2].node), (yyvsp[0].node)); } -#line 2858 "arangod/Aql/grammar.cpp" /* yacc.c:1646 */ +#line 2949 "arangod/Aql/grammar.cpp" /* yacc.c:1646 */ break; case 100: -#line 859 "arangod/Aql/grammar.y" /* yacc.c:1646 */ +#line 950 "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_MOD, (yyvsp[-2].node), (yyvsp[0].node)); } -#line 2866 "arangod/Aql/grammar.cpp" /* yacc.c:1646 */ +#line 2957 "arangod/Aql/grammar.cpp" /* yacc.c:1646 */ break; case 101: -#line 862 "arangod/Aql/grammar.y" /* yacc.c:1646 */ +#line 953 "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_EQ, (yyvsp[-2].node), (yyvsp[0].node)); } -#line 2874 "arangod/Aql/grammar.cpp" /* yacc.c:1646 */ +#line 2965 "arangod/Aql/grammar.cpp" /* yacc.c:1646 */ break; case 102: -#line 865 "arangod/Aql/grammar.y" /* yacc.c:1646 */ +#line 956 "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_NE, (yyvsp[-2].node), (yyvsp[0].node)); } -#line 2882 "arangod/Aql/grammar.cpp" /* yacc.c:1646 */ +#line 2973 "arangod/Aql/grammar.cpp" /* yacc.c:1646 */ break; case 103: -#line 868 "arangod/Aql/grammar.y" /* yacc.c:1646 */ +#line 959 "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_LT, (yyvsp[-2].node), (yyvsp[0].node)); } -#line 2890 "arangod/Aql/grammar.cpp" /* yacc.c:1646 */ +#line 2981 "arangod/Aql/grammar.cpp" /* yacc.c:1646 */ break; case 104: -#line 871 "arangod/Aql/grammar.y" /* yacc.c:1646 */ +#line 962 "arangod/Aql/grammar.y" /* yacc.c:1646 */ { - (yyval.node) = parser->ast()->createNodeBinaryOperator(NODE_TYPE_OPERATOR_BINARY_NIN, (yyvsp[-3].node), (yyvsp[0].node)); + (yyval.node) = parser->ast()->createNodeBinaryOperator(NODE_TYPE_OPERATOR_BINARY_GT, (yyvsp[-2].node), (yyvsp[0].node)); } -#line 2898 "arangod/Aql/grammar.cpp" /* yacc.c:1646 */ +#line 2989 "arangod/Aql/grammar.cpp" /* yacc.c:1646 */ break; case 105: -#line 877 "arangod/Aql/grammar.y" /* yacc.c:1646 */ +#line 965 "arangod/Aql/grammar.y" /* yacc.c:1646 */ { - (yyval.node) = parser->ast()->createNodeTernaryOperator((yyvsp[-4].node), (yyvsp[-2].node), (yyvsp[0].node)); + (yyval.node) = parser->ast()->createNodeBinaryOperator(NODE_TYPE_OPERATOR_BINARY_LE, (yyvsp[-2].node), (yyvsp[0].node)); } -#line 2906 "arangod/Aql/grammar.cpp" /* yacc.c:1646 */ +#line 2997 "arangod/Aql/grammar.cpp" /* yacc.c:1646 */ break; case 106: -#line 883 "arangod/Aql/grammar.y" /* yacc.c:1646 */ +#line 968 "arangod/Aql/grammar.y" /* yacc.c:1646 */ { + (yyval.node) = parser->ast()->createNodeBinaryOperator(NODE_TYPE_OPERATOR_BINARY_GE, (yyvsp[-2].node), (yyvsp[0].node)); } -#line 2913 "arangod/Aql/grammar.cpp" /* yacc.c:1646 */ +#line 3005 "arangod/Aql/grammar.cpp" /* yacc.c:1646 */ break; case 107: -#line 885 "arangod/Aql/grammar.y" /* yacc.c:1646 */ +#line 971 "arangod/Aql/grammar.y" /* yacc.c:1646 */ { + (yyval.node) = parser->ast()->createNodeBinaryOperator(NODE_TYPE_OPERATOR_BINARY_IN, (yyvsp[-2].node), (yyvsp[0].node)); } -#line 2920 "arangod/Aql/grammar.cpp" /* yacc.c:1646 */ +#line 3013 "arangod/Aql/grammar.cpp" /* yacc.c:1646 */ break; case 108: -#line 890 "arangod/Aql/grammar.y" /* yacc.c:1646 */ +#line 974 "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 2928 "arangod/Aql/grammar.cpp" /* yacc.c:1646 */ +#line 3021 "arangod/Aql/grammar.cpp" /* yacc.c:1646 */ break; case 109: -#line 893 "arangod/Aql/grammar.y" /* yacc.c:1646 */ +#line 980 "arangod/Aql/grammar.y" /* yacc.c:1646 */ + { + (yyval.node) = parser->ast()->createNodeTernaryOperator((yyvsp[-4].node), (yyvsp[-2].node), (yyvsp[0].node)); + } +#line 3029 "arangod/Aql/grammar.cpp" /* yacc.c:1646 */ + break; + + case 110: +#line 986 "arangod/Aql/grammar.y" /* yacc.c:1646 */ + { + } +#line 3036 "arangod/Aql/grammar.cpp" /* yacc.c:1646 */ + break; + + case 111: +#line 988 "arangod/Aql/grammar.y" /* yacc.c:1646 */ + { + } +#line 3043 "arangod/Aql/grammar.cpp" /* yacc.c:1646 */ + break; + + case 112: +#line 993 "arangod/Aql/grammar.y" /* yacc.c:1646 */ + { + (yyval.node) = (yyvsp[0].node); + } +#line 3051 "arangod/Aql/grammar.cpp" /* yacc.c:1646 */ + break; + + case 113: +#line 996 "arangod/Aql/grammar.y" /* yacc.c:1646 */ { parser->ast()->scopes()->start(triagens::aql::AQL_SCOPE_SUBQUERY); parser->ast()->startSubQuery(); } -#line 2937 "arangod/Aql/grammar.cpp" /* yacc.c:1646 */ +#line 3060 "arangod/Aql/grammar.cpp" /* yacc.c:1646 */ break; - case 110: -#line 896 "arangod/Aql/grammar.y" /* yacc.c:1646 */ + case 114: +#line 999 "arangod/Aql/grammar.y" /* yacc.c:1646 */ { AstNode* node = parser->ast()->endSubQuery(); parser->ast()->scopes()->endCurrent(); @@ -2948,98 +3071,98 @@ yyreduce: (yyval.node) = parser->ast()->createNodeReference(variableName); } -#line 2952 "arangod/Aql/grammar.cpp" /* yacc.c:1646 */ - break; - - case 111: -#line 909 "arangod/Aql/grammar.y" /* yacc.c:1646 */ - { - parser->pushArrayElement((yyvsp[0].node)); - } -#line 2960 "arangod/Aql/grammar.cpp" /* yacc.c:1646 */ - break; - - case 112: -#line 912 "arangod/Aql/grammar.y" /* yacc.c:1646 */ - { - parser->pushArrayElement((yyvsp[0].node)); - } -#line 2968 "arangod/Aql/grammar.cpp" /* yacc.c:1646 */ - break; - - case 113: -#line 918 "arangod/Aql/grammar.y" /* yacc.c:1646 */ - { - (yyval.node) = (yyvsp[0].node); - } -#line 2976 "arangod/Aql/grammar.cpp" /* yacc.c:1646 */ - break; - - case 114: -#line 921 "arangod/Aql/grammar.y" /* yacc.c:1646 */ - { - (yyval.node) = (yyvsp[0].node); - } -#line 2984 "arangod/Aql/grammar.cpp" /* yacc.c:1646 */ +#line 3075 "arangod/Aql/grammar.cpp" /* yacc.c:1646 */ break; case 115: -#line 927 "arangod/Aql/grammar.y" /* yacc.c:1646 */ +#line 1012 "arangod/Aql/grammar.y" /* yacc.c:1646 */ + { + parser->pushArrayElement((yyvsp[0].node)); + } +#line 3083 "arangod/Aql/grammar.cpp" /* yacc.c:1646 */ + break; + + case 116: +#line 1015 "arangod/Aql/grammar.y" /* yacc.c:1646 */ + { + parser->pushArrayElement((yyvsp[0].node)); + } +#line 3091 "arangod/Aql/grammar.cpp" /* yacc.c:1646 */ + break; + + case 117: +#line 1021 "arangod/Aql/grammar.y" /* yacc.c:1646 */ + { + (yyval.node) = (yyvsp[0].node); + } +#line 3099 "arangod/Aql/grammar.cpp" /* yacc.c:1646 */ + break; + + case 118: +#line 1024 "arangod/Aql/grammar.y" /* yacc.c:1646 */ + { + (yyval.node) = (yyvsp[0].node); + } +#line 3107 "arangod/Aql/grammar.cpp" /* yacc.c:1646 */ + break; + + case 119: +#line 1030 "arangod/Aql/grammar.y" /* yacc.c:1646 */ { auto node = parser->ast()->createNodeArray(); parser->pushStack(node); } -#line 2993 "arangod/Aql/grammar.cpp" /* yacc.c:1646 */ - break; - - case 116: -#line 930 "arangod/Aql/grammar.y" /* yacc.c:1646 */ - { - (yyval.node) = static_cast(parser->popStack()); - } -#line 3001 "arangod/Aql/grammar.cpp" /* yacc.c:1646 */ - break; - - case 117: -#line 936 "arangod/Aql/grammar.y" /* yacc.c:1646 */ - { - } -#line 3008 "arangod/Aql/grammar.cpp" /* yacc.c:1646 */ - break; - - case 118: -#line 938 "arangod/Aql/grammar.y" /* yacc.c:1646 */ - { - } -#line 3015 "arangod/Aql/grammar.cpp" /* yacc.c:1646 */ - break; - - case 119: -#line 943 "arangod/Aql/grammar.y" /* yacc.c:1646 */ - { - parser->pushArrayElement((yyvsp[0].node)); - } -#line 3023 "arangod/Aql/grammar.cpp" /* yacc.c:1646 */ +#line 3116 "arangod/Aql/grammar.cpp" /* yacc.c:1646 */ break; case 120: -#line 946 "arangod/Aql/grammar.y" /* yacc.c:1646 */ +#line 1033 "arangod/Aql/grammar.y" /* yacc.c:1646 */ { - parser->pushArrayElement((yyvsp[0].node)); + (yyval.node) = static_cast(parser->popStack()); } -#line 3031 "arangod/Aql/grammar.cpp" /* yacc.c:1646 */ +#line 3124 "arangod/Aql/grammar.cpp" /* yacc.c:1646 */ break; case 121: -#line 952 "arangod/Aql/grammar.y" /* yacc.c:1646 */ +#line 1039 "arangod/Aql/grammar.y" /* yacc.c:1646 */ { - (yyval.node) = nullptr; } -#line 3039 "arangod/Aql/grammar.cpp" /* yacc.c:1646 */ +#line 3131 "arangod/Aql/grammar.cpp" /* yacc.c:1646 */ break; case 122: -#line 955 "arangod/Aql/grammar.y" /* yacc.c:1646 */ +#line 1041 "arangod/Aql/grammar.y" /* yacc.c:1646 */ + { + } +#line 3138 "arangod/Aql/grammar.cpp" /* yacc.c:1646 */ + break; + + case 123: +#line 1046 "arangod/Aql/grammar.y" /* yacc.c:1646 */ + { + parser->pushArrayElement((yyvsp[0].node)); + } +#line 3146 "arangod/Aql/grammar.cpp" /* yacc.c:1646 */ + break; + + case 124: +#line 1049 "arangod/Aql/grammar.y" /* yacc.c:1646 */ + { + parser->pushArrayElement((yyvsp[0].node)); + } +#line 3154 "arangod/Aql/grammar.cpp" /* yacc.c:1646 */ + break; + + case 125: +#line 1055 "arangod/Aql/grammar.y" /* yacc.c:1646 */ + { + (yyval.node) = nullptr; + } +#line 3162 "arangod/Aql/grammar.cpp" /* yacc.c:1646 */ + break; + + case 126: +#line 1058 "arangod/Aql/grammar.y" /* yacc.c:1646 */ { if ((yyvsp[0].node) == nullptr) { ABORT_OOM @@ -3051,56 +3174,56 @@ yyreduce: (yyval.node) = (yyvsp[0].node); } -#line 3055 "arangod/Aql/grammar.cpp" /* yacc.c:1646 */ +#line 3178 "arangod/Aql/grammar.cpp" /* yacc.c:1646 */ break; - case 123: -#line 969 "arangod/Aql/grammar.y" /* yacc.c:1646 */ + case 127: +#line 1072 "arangod/Aql/grammar.y" /* yacc.c:1646 */ { auto node = parser->ast()->createNodeObject(); parser->pushStack(node); } -#line 3064 "arangod/Aql/grammar.cpp" /* yacc.c:1646 */ - break; - - case 124: -#line 972 "arangod/Aql/grammar.y" /* yacc.c:1646 */ - { - (yyval.node) = static_cast(parser->popStack()); - } -#line 3072 "arangod/Aql/grammar.cpp" /* yacc.c:1646 */ - break; - - case 125: -#line 978 "arangod/Aql/grammar.y" /* yacc.c:1646 */ - { - } -#line 3079 "arangod/Aql/grammar.cpp" /* yacc.c:1646 */ - break; - - case 126: -#line 980 "arangod/Aql/grammar.y" /* yacc.c:1646 */ - { - } -#line 3086 "arangod/Aql/grammar.cpp" /* yacc.c:1646 */ - break; - - case 127: -#line 985 "arangod/Aql/grammar.y" /* yacc.c:1646 */ - { - } -#line 3093 "arangod/Aql/grammar.cpp" /* yacc.c:1646 */ +#line 3187 "arangod/Aql/grammar.cpp" /* yacc.c:1646 */ break; case 128: -#line 987 "arangod/Aql/grammar.y" /* yacc.c:1646 */ +#line 1075 "arangod/Aql/grammar.y" /* yacc.c:1646 */ { + (yyval.node) = static_cast(parser->popStack()); } -#line 3100 "arangod/Aql/grammar.cpp" /* yacc.c:1646 */ +#line 3195 "arangod/Aql/grammar.cpp" /* yacc.c:1646 */ break; case 129: -#line 992 "arangod/Aql/grammar.y" /* yacc.c:1646 */ +#line 1081 "arangod/Aql/grammar.y" /* yacc.c:1646 */ + { + } +#line 3202 "arangod/Aql/grammar.cpp" /* yacc.c:1646 */ + break; + + case 130: +#line 1083 "arangod/Aql/grammar.y" /* yacc.c:1646 */ + { + } +#line 3209 "arangod/Aql/grammar.cpp" /* yacc.c:1646 */ + break; + + case 131: +#line 1088 "arangod/Aql/grammar.y" /* yacc.c:1646 */ + { + } +#line 3216 "arangod/Aql/grammar.cpp" /* yacc.c:1646 */ + break; + + case 132: +#line 1090 "arangod/Aql/grammar.y" /* yacc.c:1646 */ + { + } +#line 3223 "arangod/Aql/grammar.cpp" /* yacc.c:1646 */ + break; + + case 133: +#line 1095 "arangod/Aql/grammar.y" /* yacc.c:1646 */ { // attribute-name-only (comparable to JS enhanced object literals, e.g. { foo, bar }) auto ast = parser->ast(); @@ -3115,20 +3238,20 @@ yyreduce: auto node = ast->createNodeReference(variable); parser->pushObjectElement((yyvsp[0].strval).value, (yyvsp[0].strval).length, node); } -#line 3119 "arangod/Aql/grammar.cpp" /* yacc.c:1646 */ +#line 3242 "arangod/Aql/grammar.cpp" /* yacc.c:1646 */ break; - case 130: -#line 1006 "arangod/Aql/grammar.y" /* yacc.c:1646 */ + case 134: +#line 1109 "arangod/Aql/grammar.y" /* yacc.c:1646 */ { // attribute-name : attribute-value parser->pushObjectElement((yyvsp[-2].strval).value, (yyvsp[-2].strval).length, (yyvsp[0].node)); } -#line 3128 "arangod/Aql/grammar.cpp" /* yacc.c:1646 */ +#line 3251 "arangod/Aql/grammar.cpp" /* yacc.c:1646 */ break; - case 131: -#line 1010 "arangod/Aql/grammar.y" /* yacc.c:1646 */ + case 135: +#line 1113 "arangod/Aql/grammar.y" /* yacc.c:1646 */ { // bind-parameter : attribute-value if ((yyvsp[-2].strval).length < 1 || (yyvsp[-2].strval).value[0] == '@') { @@ -3138,214 +3261,214 @@ yyreduce: auto param = parser->ast()->createNodeParameter((yyvsp[-2].strval).value, (yyvsp[-2].strval).length); parser->pushObjectElement(param, (yyvsp[0].node)); } -#line 3142 "arangod/Aql/grammar.cpp" /* yacc.c:1646 */ +#line 3265 "arangod/Aql/grammar.cpp" /* yacc.c:1646 */ break; - case 132: -#line 1019 "arangod/Aql/grammar.y" /* yacc.c:1646 */ + case 136: +#line 1122 "arangod/Aql/grammar.y" /* yacc.c:1646 */ { // [ attribute-name-expression ] : attribute-value parser->pushObjectElement((yyvsp[-3].node), (yyvsp[0].node)); } -#line 3151 "arangod/Aql/grammar.cpp" /* yacc.c:1646 */ - break; - - case 133: -#line 1026 "arangod/Aql/grammar.y" /* yacc.c:1646 */ - { - (yyval.intval) = 1; - } -#line 3159 "arangod/Aql/grammar.cpp" /* yacc.c:1646 */ - break; - - case 134: -#line 1029 "arangod/Aql/grammar.y" /* yacc.c:1646 */ - { - (yyval.intval) = (yyvsp[-1].intval) + 1; - } -#line 3167 "arangod/Aql/grammar.cpp" /* yacc.c:1646 */ - break; - - case 135: -#line 1035 "arangod/Aql/grammar.y" /* yacc.c:1646 */ - { - (yyval.node) = nullptr; - } -#line 3175 "arangod/Aql/grammar.cpp" /* yacc.c:1646 */ - break; - - case 136: -#line 1038 "arangod/Aql/grammar.y" /* yacc.c:1646 */ - { - (yyval.node) = (yyvsp[0].node); - } -#line 3183 "arangod/Aql/grammar.cpp" /* yacc.c:1646 */ +#line 3274 "arangod/Aql/grammar.cpp" /* yacc.c:1646 */ break; case 137: -#line 1044 "arangod/Aql/grammar.y" /* yacc.c:1646 */ +#line 1129 "arangod/Aql/grammar.y" /* yacc.c:1646 */ { - (yyval.node) = nullptr; + (yyval.intval) = 1; } -#line 3191 "arangod/Aql/grammar.cpp" /* yacc.c:1646 */ +#line 3282 "arangod/Aql/grammar.cpp" /* yacc.c:1646 */ break; case 138: -#line 1047 "arangod/Aql/grammar.y" /* yacc.c:1646 */ +#line 1132 "arangod/Aql/grammar.y" /* yacc.c:1646 */ { - (yyval.node) = parser->ast()->createNodeArrayLimit(nullptr, (yyvsp[0].node)); + (yyval.intval) = (yyvsp[-1].intval) + 1; } -#line 3199 "arangod/Aql/grammar.cpp" /* yacc.c:1646 */ +#line 3290 "arangod/Aql/grammar.cpp" /* yacc.c:1646 */ break; case 139: -#line 1050 "arangod/Aql/grammar.y" /* yacc.c:1646 */ - { - (yyval.node) = parser->ast()->createNodeArrayLimit((yyvsp[-2].node), (yyvsp[0].node)); - } -#line 3207 "arangod/Aql/grammar.cpp" /* yacc.c:1646 */ - break; - - case 140: -#line 1056 "arangod/Aql/grammar.y" /* yacc.c:1646 */ +#line 1138 "arangod/Aql/grammar.y" /* yacc.c:1646 */ { (yyval.node) = nullptr; } -#line 3215 "arangod/Aql/grammar.cpp" /* yacc.c:1646 */ +#line 3298 "arangod/Aql/grammar.cpp" /* yacc.c:1646 */ break; - case 141: -#line 1059 "arangod/Aql/grammar.y" /* yacc.c:1646 */ + case 140: +#line 1141 "arangod/Aql/grammar.y" /* yacc.c:1646 */ { (yyval.node) = (yyvsp[0].node); } -#line 3223 "arangod/Aql/grammar.cpp" /* yacc.c:1646 */ +#line 3306 "arangod/Aql/grammar.cpp" /* yacc.c:1646 */ + break; + + case 141: +#line 1147 "arangod/Aql/grammar.y" /* yacc.c:1646 */ + { + (yyval.node) = nullptr; + } +#line 3314 "arangod/Aql/grammar.cpp" /* yacc.c:1646 */ break; case 142: -#line 1065 "arangod/Aql/grammar.y" /* yacc.c:1646 */ +#line 1150 "arangod/Aql/grammar.y" /* yacc.c:1646 */ { - (yyval.node) = parser->ast()->createNodeValueString((yyvsp[0].strval).value, (yyvsp[0].strval).length); + (yyval.node) = parser->ast()->createNodeArrayLimit(nullptr, (yyvsp[0].node)); } -#line 3231 "arangod/Aql/grammar.cpp" /* yacc.c:1646 */ +#line 3322 "arangod/Aql/grammar.cpp" /* yacc.c:1646 */ break; case 143: -#line 1068 "arangod/Aql/grammar.y" /* yacc.c:1646 */ +#line 1153 "arangod/Aql/grammar.y" /* yacc.c:1646 */ + { + (yyval.node) = parser->ast()->createNodeArrayLimit((yyvsp[-2].node), (yyvsp[0].node)); + } +#line 3330 "arangod/Aql/grammar.cpp" /* yacc.c:1646 */ + break; + + case 144: +#line 1159 "arangod/Aql/grammar.y" /* yacc.c:1646 */ + { + (yyval.node) = nullptr; + } +#line 3338 "arangod/Aql/grammar.cpp" /* yacc.c:1646 */ + break; + + case 145: +#line 1162 "arangod/Aql/grammar.y" /* yacc.c:1646 */ + { + (yyval.node) = (yyvsp[0].node); + } +#line 3346 "arangod/Aql/grammar.cpp" /* yacc.c:1646 */ + break; + + case 146: +#line 1168 "arangod/Aql/grammar.y" /* yacc.c:1646 */ + { + (yyval.node) = parser->ast()->createNodeValueString((yyvsp[0].strval).value, (yyvsp[0].strval).length); + } +#line 3354 "arangod/Aql/grammar.cpp" /* yacc.c:1646 */ + break; + + case 147: +#line 1171 "arangod/Aql/grammar.y" /* yacc.c:1646 */ { // TODO FIXME check @s (yyval.node) = (yyvsp[0].node); } -#line 3240 "arangod/Aql/grammar.cpp" /* yacc.c:1646 */ +#line 3363 "arangod/Aql/grammar.cpp" /* yacc.c:1646 */ break; - case 144: -#line 1075 "arangod/Aql/grammar.y" /* yacc.c:1646 */ + case 148: +#line 1178 "arangod/Aql/grammar.y" /* yacc.c:1646 */ { auto node = static_cast(parser->peekStack()); node->addMember((yyvsp[0].node)); } -#line 3249 "arangod/Aql/grammar.cpp" /* yacc.c:1646 */ +#line 3372 "arangod/Aql/grammar.cpp" /* yacc.c:1646 */ break; - case 145: -#line 1079 "arangod/Aql/grammar.y" /* yacc.c:1646 */ + case 149: +#line 1182 "arangod/Aql/grammar.y" /* yacc.c:1646 */ { auto node = static_cast(parser->peekStack()); node->addMember((yyvsp[0].node)); } -#line 3258 "arangod/Aql/grammar.cpp" /* yacc.c:1646 */ +#line 3381 "arangod/Aql/grammar.cpp" /* yacc.c:1646 */ break; - case 146: -#line 1086 "arangod/Aql/grammar.y" /* yacc.c:1646 */ + case 150: +#line 1189 "arangod/Aql/grammar.y" /* yacc.c:1646 */ { auto node = parser->ast()->createNodeArray(); node->addMember((yyvsp[0].node)); (yyval.node) = parser->ast()->createNodeCollectionList(node); } -#line 3268 "arangod/Aql/grammar.cpp" /* yacc.c:1646 */ +#line 3391 "arangod/Aql/grammar.cpp" /* yacc.c:1646 */ break; - case 147: -#line 1092 "arangod/Aql/grammar.y" /* yacc.c:1646 */ + case 151: +#line 1195 "arangod/Aql/grammar.y" /* yacc.c:1646 */ { auto node = parser->ast()->createNodeArray(); parser->pushStack(node); node->addMember((yyvsp[-1].node)); } -#line 3278 "arangod/Aql/grammar.cpp" /* yacc.c:1646 */ +#line 3401 "arangod/Aql/grammar.cpp" /* yacc.c:1646 */ break; - case 148: -#line 1096 "arangod/Aql/grammar.y" /* yacc.c:1646 */ + case 152: +#line 1199 "arangod/Aql/grammar.y" /* yacc.c:1646 */ { auto node = static_cast(parser->popStack()); (yyval.node) = parser->ast()->createNodeCollectionList(node); } -#line 3287 "arangod/Aql/grammar.cpp" /* yacc.c:1646 */ +#line 3410 "arangod/Aql/grammar.cpp" /* yacc.c:1646 */ break; - case 149: -#line 1100 "arangod/Aql/grammar.y" /* yacc.c:1646 */ + case 153: +#line 1203 "arangod/Aql/grammar.y" /* yacc.c:1646 */ { // graph name (yyval.node) = (yyvsp[0].node); } -#line 3296 "arangod/Aql/grammar.cpp" /* yacc.c:1646 */ +#line 3419 "arangod/Aql/grammar.cpp" /* yacc.c:1646 */ break; - case 150: -#line 1104 "arangod/Aql/grammar.y" /* yacc.c:1646 */ + case 154: +#line 1207 "arangod/Aql/grammar.y" /* yacc.c:1646 */ { // graph name (yyval.node) = parser->ast()->createNodeValueString((yyvsp[0].strval).value, (yyvsp[0].strval).length); } -#line 3305 "arangod/Aql/grammar.cpp" /* yacc.c:1646 */ - break; - - case 151: -#line 1113 "arangod/Aql/grammar.y" /* yacc.c:1646 */ - { - (yyval.intval) = 2; - } -#line 3313 "arangod/Aql/grammar.cpp" /* yacc.c:1646 */ - break; - - case 152: -#line 1116 "arangod/Aql/grammar.y" /* yacc.c:1646 */ - { - (yyval.intval) = 1; - } -#line 3321 "arangod/Aql/grammar.cpp" /* yacc.c:1646 */ - break; - - case 153: -#line 1119 "arangod/Aql/grammar.y" /* yacc.c:1646 */ - { - (yyval.intval) = 0; - } -#line 3329 "arangod/Aql/grammar.cpp" /* yacc.c:1646 */ - break; - - case 154: -#line 1125 "arangod/Aql/grammar.y" /* yacc.c:1646 */ - { - (yyval.node) = parser->ast()->createNodeDirection((yyvsp[0].intval), 1); - } -#line 3337 "arangod/Aql/grammar.cpp" /* yacc.c:1646 */ +#line 3428 "arangod/Aql/grammar.cpp" /* yacc.c:1646 */ break; case 155: -#line 1128 "arangod/Aql/grammar.y" /* yacc.c:1646 */ +#line 1216 "arangod/Aql/grammar.y" /* yacc.c:1646 */ { - (yyval.node) = parser->ast()->createNodeDirection((yyvsp[0].intval), (yyvsp[-1].node)); + (yyval.intval) = 2; } -#line 3345 "arangod/Aql/grammar.cpp" /* yacc.c:1646 */ +#line 3436 "arangod/Aql/grammar.cpp" /* yacc.c:1646 */ break; case 156: -#line 1134 "arangod/Aql/grammar.y" /* yacc.c:1646 */ +#line 1219 "arangod/Aql/grammar.y" /* yacc.c:1646 */ + { + (yyval.intval) = 1; + } +#line 3444 "arangod/Aql/grammar.cpp" /* yacc.c:1646 */ + break; + + case 157: +#line 1222 "arangod/Aql/grammar.y" /* yacc.c:1646 */ + { + (yyval.intval) = 0; + } +#line 3452 "arangod/Aql/grammar.cpp" /* yacc.c:1646 */ + break; + + case 158: +#line 1228 "arangod/Aql/grammar.y" /* yacc.c:1646 */ + { + (yyval.node) = parser->ast()->createNodeDirection((yyvsp[0].intval), 1); + } +#line 3460 "arangod/Aql/grammar.cpp" /* yacc.c:1646 */ + break; + + case 159: +#line 1231 "arangod/Aql/grammar.y" /* yacc.c:1646 */ + { + (yyval.node) = parser->ast()->createNodeDirection((yyvsp[0].intval), (yyvsp[-1].node)); + } +#line 3468 "arangod/Aql/grammar.cpp" /* yacc.c:1646 */ + break; + + case 160: +#line 1237 "arangod/Aql/grammar.y" /* yacc.c:1646 */ { // variable or collection auto ast = parser->ast(); @@ -3378,27 +3501,27 @@ yyreduce: (yyval.node) = node; } -#line 3382 "arangod/Aql/grammar.cpp" /* yacc.c:1646 */ +#line 3505 "arangod/Aql/grammar.cpp" /* yacc.c:1646 */ break; - case 157: -#line 1166 "arangod/Aql/grammar.y" /* yacc.c:1646 */ + case 161: +#line 1269 "arangod/Aql/grammar.y" /* yacc.c:1646 */ { (yyval.node) = (yyvsp[0].node); } -#line 3390 "arangod/Aql/grammar.cpp" /* yacc.c:1646 */ +#line 3513 "arangod/Aql/grammar.cpp" /* yacc.c:1646 */ break; - case 158: -#line 1169 "arangod/Aql/grammar.y" /* yacc.c:1646 */ + case 162: +#line 1272 "arangod/Aql/grammar.y" /* yacc.c:1646 */ { (yyval.node) = (yyvsp[0].node); } -#line 3398 "arangod/Aql/grammar.cpp" /* yacc.c:1646 */ +#line 3521 "arangod/Aql/grammar.cpp" /* yacc.c:1646 */ break; - case 159: -#line 1172 "arangod/Aql/grammar.y" /* yacc.c:1646 */ + case 163: +#line 1275 "arangod/Aql/grammar.y" /* yacc.c:1646 */ { (yyval.node) = (yyvsp[0].node); @@ -3406,11 +3529,11 @@ yyreduce: ABORT_OOM } } -#line 3410 "arangod/Aql/grammar.cpp" /* yacc.c:1646 */ +#line 3533 "arangod/Aql/grammar.cpp" /* yacc.c:1646 */ break; - case 160: -#line 1179 "arangod/Aql/grammar.y" /* yacc.c:1646 */ + case 164: +#line 1282 "arangod/Aql/grammar.y" /* yacc.c:1646 */ { if ((yyvsp[-1].node)->type == NODE_TYPE_EXPANSION) { // create a dummy passthru node that reduces and evaluates the expansion first @@ -3421,20 +3544,20 @@ yyreduce: (yyval.node) = (yyvsp[-1].node); } } -#line 3425 "arangod/Aql/grammar.cpp" /* yacc.c:1646 */ +#line 3548 "arangod/Aql/grammar.cpp" /* yacc.c:1646 */ break; - case 161: -#line 1189 "arangod/Aql/grammar.y" /* yacc.c:1646 */ + case 165: +#line 1292 "arangod/Aql/grammar.y" /* yacc.c:1646 */ { parser->ast()->scopes()->start(triagens::aql::AQL_SCOPE_SUBQUERY); parser->ast()->startSubQuery(); } -#line 3434 "arangod/Aql/grammar.cpp" /* yacc.c:1646 */ +#line 3557 "arangod/Aql/grammar.cpp" /* yacc.c:1646 */ break; - case 162: -#line 1192 "arangod/Aql/grammar.y" /* yacc.c:1646 */ + case 166: +#line 1295 "arangod/Aql/grammar.y" /* yacc.c:1646 */ { AstNode* node = parser->ast()->endSubQuery(); parser->ast()->scopes()->endCurrent(); @@ -3445,11 +3568,11 @@ yyreduce: (yyval.node) = parser->ast()->createNodeReference(variableName); } -#line 3449 "arangod/Aql/grammar.cpp" /* yacc.c:1646 */ +#line 3572 "arangod/Aql/grammar.cpp" /* yacc.c:1646 */ break; - case 163: -#line 1202 "arangod/Aql/grammar.y" /* yacc.c:1646 */ + case 167: +#line 1305 "arangod/Aql/grammar.y" /* yacc.c:1646 */ { // named variable access, e.g. variable.reference if ((yyvsp[-2].node)->type == NODE_TYPE_EXPANSION) { @@ -3465,11 +3588,11 @@ yyreduce: (yyval.node) = parser->ast()->createNodeAttributeAccess((yyvsp[-2].node), (yyvsp[0].strval).value, (yyvsp[0].strval).length); } } -#line 3469 "arangod/Aql/grammar.cpp" /* yacc.c:1646 */ +#line 3592 "arangod/Aql/grammar.cpp" /* yacc.c:1646 */ break; - case 164: -#line 1217 "arangod/Aql/grammar.y" /* yacc.c:1646 */ + case 168: +#line 1320 "arangod/Aql/grammar.y" /* yacc.c:1646 */ { // named variable access, e.g. variable.@reference if ((yyvsp[-2].node)->type == NODE_TYPE_EXPANSION) { @@ -3484,11 +3607,11 @@ yyreduce: (yyval.node) = parser->ast()->createNodeBoundAttributeAccess((yyvsp[-2].node), (yyvsp[0].node)); } } -#line 3488 "arangod/Aql/grammar.cpp" /* yacc.c:1646 */ +#line 3611 "arangod/Aql/grammar.cpp" /* yacc.c:1646 */ break; - case 165: -#line 1231 "arangod/Aql/grammar.y" /* yacc.c:1646 */ + case 169: +#line 1334 "arangod/Aql/grammar.y" /* yacc.c:1646 */ { // indexed variable access, e.g. variable[index] if ((yyvsp[-3].node)->type == NODE_TYPE_EXPANSION) { @@ -3503,11 +3626,11 @@ yyreduce: (yyval.node) = parser->ast()->createNodeIndexedAccess((yyvsp[-3].node), (yyvsp[-1].node)); } } -#line 3507 "arangod/Aql/grammar.cpp" /* yacc.c:1646 */ +#line 3630 "arangod/Aql/grammar.cpp" /* yacc.c:1646 */ break; - case 166: -#line 1245 "arangod/Aql/grammar.y" /* yacc.c:1646 */ + case 170: +#line 1348 "arangod/Aql/grammar.y" /* yacc.c:1646 */ { // variable expansion, e.g. variable[*], with optional FILTER, LIMIT and RETURN clauses if ((yyvsp[0].intval) > 1 && (yyvsp[-2].node)->type == NODE_TYPE_EXPANSION) { @@ -3531,11 +3654,11 @@ yyreduce: auto scopes = parser->ast()->scopes(); scopes->stackCurrentVariable(scopes->getVariable(nextName)); } -#line 3535 "arangod/Aql/grammar.cpp" /* yacc.c:1646 */ +#line 3658 "arangod/Aql/grammar.cpp" /* yacc.c:1646 */ break; - case 167: -#line 1267 "arangod/Aql/grammar.y" /* yacc.c:1646 */ + case 171: +#line 1370 "arangod/Aql/grammar.y" /* yacc.c:1646 */ { auto scopes = parser->ast()->scopes(); scopes->unstackCurrentVariable(); @@ -3554,27 +3677,27 @@ yyreduce: (yyval.node) = parser->ast()->createNodeExpansion((yyvsp[-5].intval), iterator, parser->ast()->createNodeReference(variable->name), (yyvsp[-3].node), (yyvsp[-2].node), (yyvsp[-1].node)); } } -#line 3558 "arangod/Aql/grammar.cpp" /* yacc.c:1646 */ +#line 3681 "arangod/Aql/grammar.cpp" /* yacc.c:1646 */ break; - case 168: -#line 1288 "arangod/Aql/grammar.y" /* yacc.c:1646 */ + case 172: +#line 1391 "arangod/Aql/grammar.y" /* yacc.c:1646 */ { (yyval.node) = (yyvsp[0].node); } -#line 3566 "arangod/Aql/grammar.cpp" /* yacc.c:1646 */ +#line 3689 "arangod/Aql/grammar.cpp" /* yacc.c:1646 */ break; - case 169: -#line 1291 "arangod/Aql/grammar.y" /* yacc.c:1646 */ + case 173: +#line 1394 "arangod/Aql/grammar.y" /* yacc.c:1646 */ { (yyval.node) = (yyvsp[0].node); } -#line 3574 "arangod/Aql/grammar.cpp" /* yacc.c:1646 */ +#line 3697 "arangod/Aql/grammar.cpp" /* yacc.c:1646 */ break; - case 170: -#line 1297 "arangod/Aql/grammar.y" /* yacc.c:1646 */ + case 174: +#line 1400 "arangod/Aql/grammar.y" /* yacc.c:1646 */ { if ((yyvsp[0].node) == nullptr) { ABORT_OOM @@ -3582,11 +3705,11 @@ yyreduce: (yyval.node) = (yyvsp[0].node); } -#line 3586 "arangod/Aql/grammar.cpp" /* yacc.c:1646 */ +#line 3709 "arangod/Aql/grammar.cpp" /* yacc.c:1646 */ break; - case 171: -#line 1304 "arangod/Aql/grammar.y" /* yacc.c:1646 */ + case 175: +#line 1407 "arangod/Aql/grammar.y" /* yacc.c:1646 */ { if ((yyvsp[0].node) == nullptr) { ABORT_OOM @@ -3594,67 +3717,67 @@ yyreduce: (yyval.node) = (yyvsp[0].node); } -#line 3598 "arangod/Aql/grammar.cpp" /* yacc.c:1646 */ - break; - - case 172: -#line 1314 "arangod/Aql/grammar.y" /* yacc.c:1646 */ - { - (yyval.node) = parser->ast()->createNodeValueString((yyvsp[0].strval).value, (yyvsp[0].strval).length); - } -#line 3606 "arangod/Aql/grammar.cpp" /* yacc.c:1646 */ - break; - - case 173: -#line 1317 "arangod/Aql/grammar.y" /* yacc.c:1646 */ - { - (yyval.node) = (yyvsp[0].node); - } -#line 3614 "arangod/Aql/grammar.cpp" /* yacc.c:1646 */ - break; - - case 174: -#line 1320 "arangod/Aql/grammar.y" /* yacc.c:1646 */ - { - (yyval.node) = parser->ast()->createNodeValueNull(); - } -#line 3622 "arangod/Aql/grammar.cpp" /* yacc.c:1646 */ - break; - - case 175: -#line 1323 "arangod/Aql/grammar.y" /* yacc.c:1646 */ - { - (yyval.node) = parser->ast()->createNodeValueBool(true); - } -#line 3630 "arangod/Aql/grammar.cpp" /* yacc.c:1646 */ +#line 3721 "arangod/Aql/grammar.cpp" /* yacc.c:1646 */ break; case 176: -#line 1326 "arangod/Aql/grammar.y" /* yacc.c:1646 */ +#line 1417 "arangod/Aql/grammar.y" /* yacc.c:1646 */ { - (yyval.node) = parser->ast()->createNodeValueBool(false); + (yyval.node) = parser->ast()->createNodeValueString((yyvsp[0].strval).value, (yyvsp[0].strval).length); } -#line 3638 "arangod/Aql/grammar.cpp" /* yacc.c:1646 */ +#line 3729 "arangod/Aql/grammar.cpp" /* yacc.c:1646 */ break; case 177: -#line 1332 "arangod/Aql/grammar.y" /* yacc.c:1646 */ +#line 1420 "arangod/Aql/grammar.y" /* yacc.c:1646 */ { - (yyval.node) = parser->ast()->createNodeCollection((yyvsp[0].strval).value, TRI_TRANSACTION_WRITE); + (yyval.node) = (yyvsp[0].node); } -#line 3646 "arangod/Aql/grammar.cpp" /* yacc.c:1646 */ +#line 3737 "arangod/Aql/grammar.cpp" /* yacc.c:1646 */ break; case 178: -#line 1335 "arangod/Aql/grammar.y" /* yacc.c:1646 */ +#line 1423 "arangod/Aql/grammar.y" /* yacc.c:1646 */ { - (yyval.node) = parser->ast()->createNodeCollection((yyvsp[0].strval).value, TRI_TRANSACTION_WRITE); + (yyval.node) = parser->ast()->createNodeValueNull(); } -#line 3654 "arangod/Aql/grammar.cpp" /* yacc.c:1646 */ +#line 3745 "arangod/Aql/grammar.cpp" /* yacc.c:1646 */ break; case 179: -#line 1338 "arangod/Aql/grammar.y" /* yacc.c:1646 */ +#line 1426 "arangod/Aql/grammar.y" /* yacc.c:1646 */ + { + (yyval.node) = parser->ast()->createNodeValueBool(true); + } +#line 3753 "arangod/Aql/grammar.cpp" /* yacc.c:1646 */ + break; + + case 180: +#line 1429 "arangod/Aql/grammar.y" /* yacc.c:1646 */ + { + (yyval.node) = parser->ast()->createNodeValueBool(false); + } +#line 3761 "arangod/Aql/grammar.cpp" /* yacc.c:1646 */ + break; + + case 181: +#line 1435 "arangod/Aql/grammar.y" /* yacc.c:1646 */ + { + (yyval.node) = parser->ast()->createNodeCollection((yyvsp[0].strval).value, TRI_TRANSACTION_WRITE); + } +#line 3769 "arangod/Aql/grammar.cpp" /* yacc.c:1646 */ + break; + + case 182: +#line 1438 "arangod/Aql/grammar.y" /* yacc.c:1646 */ + { + (yyval.node) = parser->ast()->createNodeCollection((yyvsp[0].strval).value, TRI_TRANSACTION_WRITE); + } +#line 3777 "arangod/Aql/grammar.cpp" /* yacc.c:1646 */ + break; + + case 183: +#line 1441 "arangod/Aql/grammar.y" /* yacc.c:1646 */ { if ((yyvsp[0].strval).length < 2 || (yyvsp[0].strval).value[0] != '@') { parser->registerParseError(TRI_ERROR_QUERY_BIND_PARAMETER_TYPE, TRI_errno_string(TRI_ERROR_QUERY_BIND_PARAMETER_TYPE), (yyvsp[0].strval).value, yylloc.first_line, yylloc.first_column); @@ -3662,43 +3785,43 @@ yyreduce: (yyval.node) = parser->ast()->createNodeParameter((yyvsp[0].strval).value, (yyvsp[0].strval).length); } -#line 3666 "arangod/Aql/grammar.cpp" /* yacc.c:1646 */ +#line 3789 "arangod/Aql/grammar.cpp" /* yacc.c:1646 */ break; - case 180: -#line 1348 "arangod/Aql/grammar.y" /* yacc.c:1646 */ + case 184: +#line 1451 "arangod/Aql/grammar.y" /* yacc.c:1646 */ { (yyval.node) = parser->ast()->createNodeParameter((yyvsp[0].strval).value, (yyvsp[0].strval).length); } -#line 3674 "arangod/Aql/grammar.cpp" /* yacc.c:1646 */ +#line 3797 "arangod/Aql/grammar.cpp" /* yacc.c:1646 */ break; - case 181: -#line 1354 "arangod/Aql/grammar.y" /* yacc.c:1646 */ + case 185: +#line 1457 "arangod/Aql/grammar.y" /* yacc.c:1646 */ { (yyval.strval) = (yyvsp[0].strval); } -#line 3682 "arangod/Aql/grammar.cpp" /* yacc.c:1646 */ +#line 3805 "arangod/Aql/grammar.cpp" /* yacc.c:1646 */ break; - case 182: -#line 1357 "arangod/Aql/grammar.y" /* yacc.c:1646 */ + case 186: +#line 1460 "arangod/Aql/grammar.y" /* yacc.c:1646 */ { (yyval.strval) = (yyvsp[0].strval); } -#line 3690 "arangod/Aql/grammar.cpp" /* yacc.c:1646 */ +#line 3813 "arangod/Aql/grammar.cpp" /* yacc.c:1646 */ break; - case 183: -#line 1362 "arangod/Aql/grammar.y" /* yacc.c:1646 */ + case 187: +#line 1465 "arangod/Aql/grammar.y" /* yacc.c:1646 */ { (yyval.strval) = (yyvsp[0].strval); } -#line 3698 "arangod/Aql/grammar.cpp" /* yacc.c:1646 */ +#line 3821 "arangod/Aql/grammar.cpp" /* yacc.c:1646 */ break; -#line 3702 "arangod/Aql/grammar.cpp" /* yacc.c:1646 */ +#line 3825 "arangod/Aql/grammar.cpp" /* yacc.c:1646 */ default: break; } /* User semantic actions sometimes alter yychar, and that requires diff --git a/arangod/Aql/grammar.h b/arangod/Aql/grammar.h index 4e07ae00a2..00a865f5bc 100644 --- a/arangod/Aql/grammar.h +++ b/arangod/Aql/grammar.h @@ -58,59 +58,60 @@ extern int Aqldebug; T_IN = 267, T_WITH = 268, T_INTO = 269, - T_GRAPH = 270, - T_DISTINCT = 271, - T_REMOVE = 272, - T_INSERT = 273, - T_UPDATE = 274, - T_REPLACE = 275, - T_UPSERT = 276, - T_NULL = 277, - T_TRUE = 278, - T_FALSE = 279, - T_STRING = 280, - T_QUOTED_STRING = 281, - T_INTEGER = 282, - T_DOUBLE = 283, - T_PARAMETER = 284, - T_ASSIGN = 285, - T_NOT = 286, - T_AND = 287, - T_OR = 288, - T_EQ = 289, - T_NE = 290, - T_LT = 291, - T_GT = 292, - T_LE = 293, - T_GE = 294, - T_PLUS = 295, - T_MINUS = 296, - T_TIMES = 297, - T_DIV = 298, - T_MOD = 299, - T_QUESTION = 300, - T_COLON = 301, - T_SCOPE = 302, - T_RANGE = 303, - T_COMMA = 304, - T_OPEN = 305, - T_CLOSE = 306, - T_OBJECT_OPEN = 307, - T_OBJECT_CLOSE = 308, - T_ARRAY_OPEN = 309, - T_ARRAY_CLOSE = 310, - T_OUTBOUND = 311, - T_INBOUND = 312, - T_ANY = 313, - T_ALL = 314, - T_NONE = 315, - T_NIN = 316, - UMINUS = 317, - UPLUS = 318, - FUNCCALL = 319, - REFERENCE = 320, - INDEXED = 321, - EXPANSION = 322 + T_AGGREGATE = 270, + T_GRAPH = 271, + T_DISTINCT = 272, + T_REMOVE = 273, + T_INSERT = 274, + T_UPDATE = 275, + T_REPLACE = 276, + T_UPSERT = 277, + T_NULL = 278, + T_TRUE = 279, + T_FALSE = 280, + T_STRING = 281, + T_QUOTED_STRING = 282, + T_INTEGER = 283, + T_DOUBLE = 284, + T_PARAMETER = 285, + T_ASSIGN = 286, + T_NOT = 287, + T_AND = 288, + T_OR = 289, + T_EQ = 290, + T_NE = 291, + T_LT = 292, + T_GT = 293, + T_LE = 294, + T_GE = 295, + T_PLUS = 296, + T_MINUS = 297, + T_TIMES = 298, + T_DIV = 299, + T_MOD = 300, + T_QUESTION = 301, + T_COLON = 302, + T_SCOPE = 303, + T_RANGE = 304, + T_COMMA = 305, + T_OPEN = 306, + T_CLOSE = 307, + T_OBJECT_OPEN = 308, + T_OBJECT_CLOSE = 309, + T_ARRAY_OPEN = 310, + T_ARRAY_CLOSE = 311, + T_OUTBOUND = 312, + T_INBOUND = 313, + T_ANY = 314, + T_ALL = 315, + T_NONE = 316, + T_NIN = 317, + UMINUS = 318, + UPLUS = 319, + FUNCCALL = 320, + REFERENCE = 321, + INDEXED = 322, + EXPANSION = 323 }; #endif @@ -129,7 +130,7 @@ union YYSTYPE bool boolval; int64_t intval; -#line 133 "arangod/Aql/grammar.hpp" /* yacc.c:1909 */ +#line 134 "arangod/Aql/grammar.hpp" /* yacc.c:1909 */ }; # define YYSTYPE_IS_TRIVIAL 1 # define YYSTYPE_IS_DECLARED 1 diff --git a/arangod/Aql/grammar.y b/arangod/Aql/grammar.y index 2a99a5b89b..0e4a26299e 100644 --- a/arangod/Aql/grammar.y +++ b/arangod/Aql/grammar.y @@ -72,6 +72,7 @@ void Aqlerror (YYLTYPE* locp, %token T_IN "IN keyword" %token T_WITH "WITH keyword" %token T_INTO "INTO keyword" +%token T_AGGREGATE "AGGREGATE keyword" %token T_GRAPH "GRAPH keyword" %token T_DISTINCT "DISTINCT modifier" @@ -125,10 +126,10 @@ void Aqlerror (YYLTYPE* locp, %token T_END 0 "end of query string" -%token T_OUTBOUND "outbound direction" -%token T_INBOUND "inbound direction" -%token T_ANY "any direction" +%token T_OUTBOUND "outbound modifier" +%token T_INBOUND "inbound modifier" +%token T_ANY "any modifier" %token T_ALL "all modifier" %token T_NONE "none modifier" @@ -167,6 +168,7 @@ void Aqlerror (YYLTYPE* locp, %type collect_element; %type collect_variable_list; %type keep; +%type aggregate; %type optional_into; %type count_into; %type expression; @@ -347,6 +349,7 @@ collect_variable_list: collect_statement: T_COLLECT count_into options { + /* COLLECT WITH COUNT INTO var OPTIONS ... */ auto scopes = parser->ast()->scopes(); // check if we are in the main scope @@ -363,6 +366,7 @@ collect_statement: parser->ast()->addOperation(node); } | collect_variable_list count_into options { + /* COLLECT var = expr WITH COUNT INTO var OPTIONS ... */ auto scopes = parser->ast()->scopes(); // check if we are in the main scope @@ -389,7 +393,94 @@ collect_statement: auto node = parser->ast()->createNodeCollectCount($1, $2.value, $2.length, $3); parser->ast()->addOperation(node); } + | T_COLLECT aggregate options { + /* AGGREGATE var = expr OPTIONS ... */ + 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 = $2->numMembers(); + for (size_t i = 0; i < n; ++i) { + auto member = $2->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()->createNodeCollectAggregate(parser->ast()->createNodeArray(), $2, $3); + parser->ast()->addOperation(node); + } + | collect_variable_list aggregate options { + /* COLLECT var = expr AGGREGATE var = expr OPTIONS ... */ + 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); + + // register all used variables + size_t 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); + } + } + n = $2->numMembers(); + for (size_t i = 0; i < n; ++i) { + auto member = $2->getMember(i); + + if (member != nullptr) { + TRI_ASSERT(member->type == NODE_TYPE_ASSIGN); + auto func = member->getMember(1); + + bool isValid = true; + if (func->type != NODE_TYPE_FCALL) { + // aggregate expression must be a function call + isValid = false; + } + else { + auto f = static_cast(func->getData()); + if (f->externalName != "MIN" && f->externalName != "MAX" && f->externalName != "LENGTH") { + // aggregate expression must be a call to MIN|MAX|LENGTH + isValid = false; + } + } + + if (! isValid) { + parser->registerParseError(TRI_ERROR_QUERY_PARSE, "aggregate expression must be a function call", yylloc.first_line, yylloc.first_column); + } + + auto v = static_cast(member->getMember(0)->getData()); + scopes->addVariable(v); + } + } + } + + auto node = parser->ast()->createNodeCollectAggregate($1, $2, $3); + parser->ast()->addOperation(node); + } | collect_variable_list optional_into options { + /* COLLECT var = expr INTO var OPTIONS ... */ auto scopes = parser->ast()->scopes(); // check if we are in the main scope @@ -416,7 +507,36 @@ collect_statement: auto node = parser->ast()->createNodeCollect($1, $2.value, $2.length, nullptr, $3); parser->ast()->addOperation(node); } + | collect_variable_list T_INTO variable_name T_ASSIGN expression options { + /* COLLECT var = expr INTO var = expr OPTIONS ... */ + 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.value, $3.length, $5, $6); + parser->ast()->addOperation(node); + } | collect_variable_list optional_into keep options { + /* COLLECT var = expr INTO var KEEP ... OPTIONS ... */ auto scopes = parser->ast()->scopes(); // check if we are in the main scope @@ -448,33 +568,6 @@ collect_statement: auto node = parser->ast()->createNodeCollect($1, $2.value, $2.length, $3, $4); parser->ast()->addOperation(node); } - | collect_variable_list T_INTO variable_name T_ASSIGN expression options { - 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.value, $3.length, $5, $6); - parser->ast()->addOperation(node); - } ; collect_list: @@ -547,6 +640,16 @@ keep: } ; +aggregate: + T_AGGREGATE { + auto node = parser->ast()->createNodeArray(); + parser->pushStack(node); + } collect_list { + auto list = static_cast(parser->popStack()); + $$ = list; + } + ; + sort_statement: T_SORT { auto node = parser->ast()->createNodeArray(); diff --git a/arangod/Aql/tokens.cpp b/arangod/Aql/tokens.cpp index 94f8e03698..f356cbbda5 100644 --- a/arangod/Aql/tokens.cpp +++ b/arangod/Aql/tokens.cpp @@ -381,8 +381,8 @@ static void yy_fatal_error (yyconst char msg[] ,yyscan_t yyscanner ); *yy_cp = '\0'; \ yyg->yy_c_buf_p = yy_cp; -#define YY_NUM_RULES 87 -#define YY_END_OF_BUFFER 88 +#define YY_NUM_RULES 88 +#define YY_END_OF_BUFFER 89 /* This struct is not used in this scanner, but its presence is necessary. */ struct yy_trans_info @@ -390,32 +390,33 @@ struct yy_trans_info flex_int32_t yy_verify; flex_int32_t yy_nxt; }; -static yyconst flex_int16_t yy_accept[218] = +static yyconst flex_int16_t yy_accept[226] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 88, 86, 76, 77, 38, 63, 86, 45, - 86, 68, 51, 52, 43, 41, 50, 42, 86, 44, - 73, 73, 48, 36, 37, 34, 46, 86, 57, 57, - 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, - 57, 57, 57, 55, 56, 86, 58, 53, 86, 54, - 62, 61, 62, 59, 72, 71, 69, 72, 67, 66, - 64, 67, 80, 79, 83, 85, 84, 76, 32, 57, - 39, 49, 81, 78, 0, 0, 73, 47, 35, 31, - 33, 75, 0, 0, 57, 57, 57, 57, 57, 57, + 0, 0, 89, 87, 77, 78, 39, 64, 87, 46, + 87, 69, 52, 53, 44, 42, 51, 43, 87, 45, + 74, 74, 49, 37, 38, 35, 47, 87, 58, 58, + 58, 58, 58, 58, 58, 58, 58, 58, 58, 58, + 58, 58, 58, 56, 57, 87, 59, 54, 87, 55, + 63, 62, 63, 60, 73, 72, 70, 73, 68, 67, + 65, 68, 81, 80, 84, 86, 85, 77, 33, 58, + 40, 50, 82, 79, 0, 0, 74, 48, 36, 32, + 34, 76, 0, 0, 58, 58, 58, 58, 58, 58, - 57, 57, 57, 57, 57, 14, 57, 57, 57, 57, - 13, 57, 57, 57, 57, 57, 57, 57, 0, 40, - 60, 70, 65, 80, 83, 82, 74, 0, 74, 75, - 75, 26, 12, 25, 9, 57, 57, 57, 57, 57, - 1, 57, 57, 57, 57, 2, 57, 57, 11, 57, - 57, 57, 57, 57, 57, 57, 57, 57, 57, 57, - 57, 75, 75, 57, 10, 57, 57, 57, 57, 57, - 57, 15, 57, 27, 28, 57, 57, 57, 57, 6, - 29, 57, 57, 16, 57, 57, 30, 57, 22, 57, - 57, 7, 57, 57, 57, 57, 57, 57, 57, 57, + 58, 58, 58, 58, 58, 58, 15, 58, 58, 58, + 58, 14, 58, 58, 58, 58, 58, 58, 58, 0, + 41, 61, 71, 66, 81, 84, 83, 75, 0, 75, + 76, 76, 58, 27, 13, 26, 10, 58, 58, 58, + 58, 58, 1, 58, 58, 58, 58, 2, 58, 58, + 12, 58, 58, 58, 58, 58, 58, 58, 58, 58, + 58, 58, 58, 76, 76, 58, 58, 11, 58, 58, + 58, 58, 58, 58, 16, 58, 28, 29, 58, 58, + 58, 58, 6, 30, 58, 58, 17, 58, 58, 58, + 31, 58, 23, 58, 58, 7, 58, 58, 58, 58, - 3, 57, 18, 57, 17, 57, 4, 19, 21, 5, - 57, 24, 57, 20, 8, 23, 0 + 58, 58, 58, 58, 58, 3, 58, 19, 58, 18, + 58, 4, 20, 22, 58, 5, 58, 25, 58, 21, + 58, 8, 24, 9, 0 } ; static yyconst flex_int32_t yy_ec[256] = @@ -462,67 +463,69 @@ static yyconst flex_int32_t yy_meta[77] = 6, 6, 6, 1, 1, 1 } ; -static yyconst flex_int16_t yy_base[238] = +static yyconst flex_int16_t yy_base[246] = { 0, - 0, 0, 74, 75, 76, 79, 81, 84, 353, 352, - 78, 80, 354, 476, 351, 476, 330, 476, 0, 476, - 341, 476, 476, 476, 476, 476, 476, 476, 332, 79, - 64, 79, 327, 319, 316, 297, 476, 68, 70, 0, - 64, 80, 105, 75, 79, 88, 107, 106, 83, 96, - 107, 112, 119, 476, 476, 194, 476, 476, 148, 476, - 476, 476, 0, 476, 476, 476, 476, 0, 476, 476, - 476, 0, 0, 476, 0, 476, 190, 202, 476, 0, - 476, 476, 476, 476, 81, 141, 149, 476, 476, 476, - 476, 0, 130, 137, 0, 121, 135, 134, 133, 129, + 0, 0, 74, 75, 76, 79, 81, 84, 366, 365, + 78, 80, 367, 494, 363, 494, 342, 494, 0, 494, + 350, 494, 494, 494, 494, 494, 494, 494, 313, 79, + 64, 79, 299, 253, 243, 235, 494, 68, 70, 0, + 66, 80, 109, 72, 78, 88, 107, 106, 87, 101, + 111, 113, 120, 494, 494, 201, 494, 494, 145, 494, + 494, 494, 0, 494, 494, 494, 494, 0, 494, 494, + 494, 0, 0, 494, 0, 494, 186, 154, 494, 0, + 494, 494, 494, 494, 81, 142, 164, 494, 494, 494, + 494, 0, 133, 69, 0, 127, 127, 140, 136, 131, - 133, 148, 149, 145, 137, 160, 149, 156, 156, 160, - 0, 155, 190, 159, 161, 192, 166, 198, 69, 476, - 476, 476, 476, 0, 0, 476, 220, 83, 86, 0, - 64, 0, 0, 0, 0, 179, 185, 189, 194, 194, - 0, 202, 204, 214, 207, 0, 213, 221, 0, 218, - 225, 216, 221, 217, 221, 235, 240, 237, 237, 0, - 257, 60, 0, 243, 0, 248, 254, 255, 253, 244, - 248, 0, 248, 0, 0, 256, 251, 272, 260, 0, - 0, 259, 262, 0, 271, 266, 0, 264, 0, 268, - 264, 0, 266, 286, 290, 282, 293, 291, 292, 296, + 129, 133, 149, 152, 149, 139, 175, 155, 162, 162, + 168, 0, 163, 172, 166, 164, 181, 176, 209, 64, + 494, 494, 494, 494, 0, 0, 494, 221, 85, 228, + 0, 60, 181, 0, 0, 0, 0, 200, 140, 199, + 208, 210, 0, 214, 216, 226, 219, 0, 225, 231, + 0, 227, 237, 227, 231, 225, 227, 241, 246, 243, + 241, 0, 284, 56, 0, 247, 252, 0, 251, 257, + 260, 261, 253, 264, 0, 263, 0, 0, 268, 263, + 284, 272, 0, 0, 272, 275, 0, 279, 290, 282, + 0, 281, 0, 286, 282, 0, 282, 297, 300, 292, - 0, 308, 0, 301, 0, 310, 0, 0, 0, 0, - 299, 0, 315, 0, 0, 0, 476, 371, 378, 385, - 392, 399, 101, 403, 407, 409, 416, 423, 430, 437, - 444, 448, 452, 456, 460, 464, 468 + 306, 297, 317, 304, 316, 0, 320, 0, 315, 0, + 327, 0, 0, 0, 316, 0, 317, 0, 332, 0, + 332, 0, 0, 0, 494, 389, 396, 403, 410, 417, + 95, 421, 425, 427, 434, 441, 448, 455, 462, 466, + 470, 474, 478, 482, 486 } ; -static yyconst flex_int16_t yy_def[238] = +static yyconst flex_int16_t yy_def[246] = { 0, - 217, 1, 218, 218, 219, 219, 220, 220, 221, 221, - 222, 222, 217, 217, 217, 217, 217, 217, 223, 217, - 217, 217, 217, 217, 217, 217, 217, 217, 217, 217, - 217, 217, 217, 217, 217, 217, 217, 224, 225, 225, + 225, 1, 226, 226, 227, 227, 228, 228, 229, 229, + 230, 230, 225, 225, 225, 225, 225, 225, 231, 225, 225, 225, 225, 225, 225, 225, 225, 225, 225, 225, - 225, 225, 225, 217, 217, 226, 217, 217, 217, 217, - 217, 217, 227, 217, 217, 217, 217, 228, 217, 217, - 217, 229, 230, 217, 231, 217, 217, 217, 217, 225, - 217, 217, 217, 217, 217, 217, 217, 217, 217, 217, - 217, 232, 224, 233, 225, 225, 225, 225, 225, 225, + 225, 225, 225, 225, 225, 225, 225, 232, 233, 233, + 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, + 233, 233, 233, 225, 225, 234, 225, 225, 225, 225, + 225, 225, 235, 225, 225, 225, 225, 236, 225, 225, + 225, 237, 238, 225, 239, 225, 225, 225, 225, 233, + 225, 225, 225, 225, 225, 225, 225, 225, 225, 225, + 225, 240, 232, 241, 233, 233, 233, 233, 233, 233, - 225, 225, 225, 225, 225, 225, 225, 225, 225, 225, - 225, 225, 225, 225, 225, 225, 225, 234, 226, 217, - 217, 217, 217, 230, 231, 217, 217, 217, 217, 232, - 235, 225, 225, 225, 225, 225, 225, 225, 225, 225, - 225, 225, 225, 225, 225, 225, 225, 225, 225, 225, - 225, 225, 225, 225, 225, 225, 225, 225, 225, 236, - 234, 235, 237, 225, 225, 225, 225, 225, 225, 225, - 225, 225, 225, 225, 225, 225, 225, 225, 225, 225, - 225, 225, 225, 225, 225, 225, 225, 225, 225, 225, - 225, 225, 225, 225, 225, 225, 225, 225, 225, 225, + 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, + 233, 233, 233, 233, 233, 233, 233, 233, 242, 234, + 225, 225, 225, 225, 238, 239, 225, 225, 225, 225, + 240, 243, 233, 233, 233, 233, 233, 233, 233, 233, + 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, + 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, + 233, 244, 242, 243, 245, 233, 233, 233, 233, 233, + 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, + 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, + 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, + 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, + 233, 233, 233, 233, 233, 233, 233, 233, 233, 233, + 233, 233, 233, 233, 0, 225, 225, 225, 225, 225, 225, 225, 225, 225, 225, 225, 225, 225, 225, 225, - 225, 225, 225, 225, 225, 225, 0, 217, 217, 217, - 217, 217, 217, 217, 217, 217, 217, 217, 217, 217, - 217, 217, 217, 217, 217, 217, 217 + 225, 225, 225, 225, 225 } ; -static yyconst flex_int16_t yy_nxt[553] = +static yyconst flex_int16_t yy_nxt[571] = { 0, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, @@ -533,61 +536,62 @@ static yyconst flex_int16_t yy_nxt[553] = 45, 46, 40, 47, 48, 40, 49, 50, 51, 52, 40, 53, 40, 58, 59, 60, 62, 62, 66, 85, 76, 66, 76, 70, 67, 71, 70, 67, 71, 77, - 83, 77, 93, 86, 85, 84, 87, 87, 127, 127, + 83, 77, 93, 86, 85, 84, 87, 87, 128, 128, - 129, 129, 99, 129, 129, 96, 80, 97, 86, 100, - 163, 98, 113, 101, 163, 105, 106, 107, 94, 119, - 86, 108, 63, 63, 68, 64, 64, 68, 99, 72, - 102, 96, 72, 97, 114, 86, 100, 98, 103, 113, - 101, 105, 106, 104, 107, 109, 111, 115, 108, 112, - 110, 116, 117, 128, 217, 128, 132, 102, 129, 129, - 114, 135, 142, 133, 85, 103, 87, 87, 136, 104, - 137, 109, 111, 115, 138, 112, 110, 116, 86, 117, - 94, 134, 132, 139, 140, 141, 143, 94, 135, 142, - 133, 146, 147, 148, 136, 150, 137, 151, 149, 155, + 80, 96, 130, 130, 100, 97, 165, 98, 86, 101, + 165, 99, 106, 102, 120, 107, 114, 108, 94, 94, + 86, 109, 63, 63, 68, 64, 64, 68, 96, 72, + 100, 97, 72, 98, 103, 86, 101, 99, 106, 115, + 102, 107, 104, 114, 108, 110, 112, 105, 109, 113, + 111, 116, 117, 118, 129, 78, 129, 225, 133, 130, + 130, 103, 134, 137, 144, 115, 138, 168, 135, 104, + 139, 110, 112, 105, 140, 113, 111, 116, 117, 85, + 118, 87, 87, 94, 141, 133, 136, 142, 134, 143, + 137, 144, 138, 86, 168, 135, 139, 148, 149, 150, - 138, 144, 145, 78, 156, 86, 126, 134, 159, 139, - 140, 141, 165, 143, 164, 160, 160, 146, 147, 148, - 157, 150, 120, 151, 149, 155, 152, 144, 145, 153, - 156, 166, 154, 158, 159, 167, 168, 127, 127, 165, - 164, 169, 170, 171, 119, 172, 173, 157, 160, 86, - 174, 176, 152, 175, 177, 153, 178, 166, 154, 158, - 179, 167, 168, 180, 181, 182, 183, 169, 170, 184, - 171, 172, 185, 173, 160, 160, 86, 174, 176, 175, - 177, 186, 178, 187, 188, 189, 179, 190, 191, 180, - 192, 181, 182, 183, 193, 194, 184, 195, 199, 185, + 140, 145, 127, 152, 151, 153, 157, 158, 154, 159, + 141, 155, 136, 142, 156, 143, 146, 147, 161, 121, + 86, 166, 160, 148, 149, 150, 162, 162, 145, 152, + 151, 153, 157, 158, 154, 167, 159, 155, 128, 128, + 156, 169, 146, 147, 161, 130, 130, 166, 160, 170, + 86, 120, 171, 172, 173, 174, 91, 175, 176, 162, + 177, 167, 178, 179, 90, 180, 181, 169, 182, 183, + 184, 185, 186, 187, 89, 170, 188, 86, 171, 172, + 173, 189, 174, 175, 190, 176, 191, 177, 178, 192, + 179, 180, 181, 193, 182, 183, 194, 184, 185, 186, - 196, 197, 198, 200, 201, 202, 203, 160, 186, 204, - 187, 188, 189, 190, 191, 205, 192, 206, 91, 207, - 193, 194, 208, 211, 195, 199, 196, 197, 198, 200, - 201, 202, 203, 209, 210, 204, 212, 90, 213, 214, - 89, 215, 205, 216, 206, 207, 88, 82, 81, 208, - 211, 79, 78, 217, 74, 74, 217, 217, 217, 209, - 210, 217, 217, 212, 213, 217, 214, 215, 217, 217, - 216, 61, 61, 61, 61, 61, 61, 61, 65, 65, - 65, 65, 65, 65, 65, 69, 69, 69, 69, 69, - 69, 69, 73, 73, 73, 73, 73, 73, 73, 75, + 187, 162, 162, 188, 195, 196, 197, 198, 189, 199, + 203, 190, 200, 191, 201, 202, 192, 204, 88, 205, + 193, 206, 194, 207, 208, 209, 210, 211, 82, 212, + 195, 196, 197, 198, 162, 213, 199, 203, 200, 214, + 201, 202, 215, 217, 204, 205, 216, 206, 218, 207, + 208, 209, 219, 210, 211, 212, 220, 81, 221, 222, + 223, 224, 213, 79, 78, 214, 225, 74, 74, 215, + 217, 225, 216, 225, 225, 218, 225, 225, 219, 225, + 225, 225, 225, 220, 221, 222, 225, 223, 224, 61, + 61, 61, 61, 61, 61, 61, 65, 65, 65, 65, - 75, 75, 75, 75, 75, 75, 92, 92, 92, 92, - 95, 217, 95, 95, 118, 118, 121, 217, 121, 121, - 121, 121, 121, 122, 217, 122, 122, 122, 122, 122, - 123, 217, 123, 123, 123, 123, 123, 124, 217, 124, - 124, 124, 124, 124, 125, 217, 217, 125, 125, 125, - 125, 130, 217, 130, 130, 131, 217, 131, 131, 161, - 217, 161, 161, 162, 217, 162, 162, 160, 217, 160, - 160, 163, 217, 163, 163, 13, 217, 217, 217, 217, - 217, 217, 217, 217, 217, 217, 217, 217, 217, 217, - 217, 217, 217, 217, 217, 217, 217, 217, 217, 217, + 65, 65, 65, 69, 69, 69, 69, 69, 69, 69, + 73, 73, 73, 73, 73, 73, 73, 75, 75, 75, + 75, 75, 75, 75, 92, 92, 92, 92, 95, 225, + 95, 95, 119, 119, 122, 225, 122, 122, 122, 122, + 122, 123, 225, 123, 123, 123, 123, 123, 124, 225, + 124, 124, 124, 124, 124, 125, 225, 125, 125, 125, + 125, 125, 126, 225, 225, 126, 126, 126, 126, 131, + 225, 131, 131, 132, 225, 132, 132, 163, 225, 163, + 163, 164, 225, 164, 164, 162, 225, 162, 162, 165, + 225, 165, 165, 13, 225, 225, 225, 225, 225, 225, - 217, 217, 217, 217, 217, 217, 217, 217, 217, 217, - 217, 217, 217, 217, 217, 217, 217, 217, 217, 217, - 217, 217, 217, 217, 217, 217, 217, 217, 217, 217, - 217, 217, 217, 217, 217, 217, 217, 217, 217, 217, - 217, 217, 217, 217, 217, 217, 217, 217, 217, 217, - 217, 217 + 225, 225, 225, 225, 225, 225, 225, 225, 225, 225, + 225, 225, 225, 225, 225, 225, 225, 225, 225, 225, + 225, 225, 225, 225, 225, 225, 225, 225, 225, 225, + 225, 225, 225, 225, 225, 225, 225, 225, 225, 225, + 225, 225, 225, 225, 225, 225, 225, 225, 225, 225, + 225, 225, 225, 225, 225, 225, 225, 225, 225, 225, + 225, 225, 225, 225, 225, 225, 225, 225, 225, 225 } ; -static yyconst flex_int16_t yy_chk[553] = +static yyconst flex_int16_t yy_chk[571] = { 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, @@ -600,66 +604,67 @@ static yyconst flex_int16_t yy_chk[553] = 11, 6, 12, 7, 5, 7, 8, 6, 8, 11, 30, 12, 38, 31, 32, 30, 32, 32, 85, 85, - 128, 128, 41, 129, 129, 39, 223, 39, 32, 42, - 162, 39, 49, 42, 131, 44, 45, 46, 38, 119, - 31, 46, 3, 4, 5, 3, 4, 6, 41, 7, - 43, 39, 8, 39, 50, 32, 42, 39, 43, 49, - 42, 44, 45, 43, 46, 47, 48, 51, 46, 48, - 47, 52, 53, 86, 93, 86, 96, 43, 86, 86, - 50, 98, 105, 97, 87, 43, 87, 87, 99, 43, - 100, 47, 48, 51, 101, 48, 47, 52, 87, 53, - 93, 97, 96, 102, 103, 104, 106, 94, 98, 105, - 97, 107, 108, 109, 99, 110, 100, 112, 109, 114, + 231, 39, 129, 129, 41, 39, 164, 39, 32, 42, + 132, 39, 44, 42, 120, 45, 49, 46, 38, 94, + 31, 46, 3, 4, 5, 3, 4, 6, 39, 7, + 41, 39, 8, 39, 43, 32, 42, 39, 44, 50, + 42, 45, 43, 49, 46, 47, 48, 43, 46, 48, + 47, 51, 52, 53, 86, 78, 86, 93, 96, 86, + 86, 43, 97, 99, 106, 50, 100, 139, 98, 43, + 101, 47, 48, 43, 102, 48, 47, 51, 52, 87, + 53, 87, 87, 93, 103, 96, 98, 104, 97, 105, + 99, 106, 100, 87, 139, 98, 101, 108, 109, 110, - 101, 106, 106, 78, 115, 87, 77, 97, 117, 102, - 103, 104, 137, 106, 136, 118, 118, 107, 108, 109, - 116, 110, 59, 112, 109, 114, 113, 106, 106, 113, - 115, 138, 113, 116, 117, 139, 140, 127, 127, 137, - 136, 142, 143, 144, 56, 145, 147, 116, 118, 127, - 148, 151, 113, 150, 152, 113, 153, 138, 113, 116, - 154, 139, 140, 155, 156, 157, 158, 142, 143, 159, - 144, 145, 164, 147, 161, 161, 127, 148, 151, 150, - 152, 166, 153, 167, 168, 169, 154, 170, 171, 155, - 173, 156, 157, 158, 176, 177, 159, 178, 185, 164, + 102, 107, 77, 111, 110, 113, 115, 116, 114, 117, + 103, 114, 98, 104, 114, 105, 107, 107, 118, 59, + 87, 133, 117, 108, 109, 110, 119, 119, 107, 111, + 110, 113, 115, 116, 114, 138, 117, 114, 128, 128, + 114, 140, 107, 107, 118, 130, 130, 133, 117, 141, + 128, 56, 142, 144, 145, 146, 36, 147, 149, 119, + 150, 138, 152, 153, 35, 154, 155, 140, 156, 157, + 158, 159, 160, 161, 34, 141, 166, 128, 142, 144, + 145, 167, 146, 147, 169, 149, 170, 150, 152, 171, + 153, 154, 155, 172, 156, 157, 173, 158, 159, 160, - 179, 182, 183, 186, 188, 190, 191, 161, 166, 193, - 167, 168, 169, 170, 171, 194, 173, 195, 36, 196, - 176, 177, 197, 200, 178, 185, 179, 182, 183, 186, - 188, 190, 191, 198, 199, 193, 202, 35, 204, 206, - 34, 211, 194, 213, 195, 196, 33, 29, 21, 197, - 200, 17, 15, 13, 10, 9, 0, 0, 0, 198, - 199, 0, 0, 202, 204, 0, 206, 211, 0, 0, - 213, 218, 218, 218, 218, 218, 218, 218, 219, 219, - 219, 219, 219, 219, 219, 220, 220, 220, 220, 220, - 220, 220, 221, 221, 221, 221, 221, 221, 221, 222, + 161, 163, 163, 166, 174, 176, 179, 180, 167, 181, + 188, 169, 182, 170, 185, 186, 171, 189, 33, 190, + 172, 192, 173, 194, 195, 197, 198, 199, 29, 200, + 174, 176, 179, 180, 163, 201, 181, 188, 182, 202, + 185, 186, 203, 205, 189, 190, 204, 192, 207, 194, + 195, 197, 209, 198, 199, 200, 211, 21, 215, 217, + 219, 221, 201, 17, 15, 202, 13, 10, 9, 203, + 205, 0, 204, 0, 0, 207, 0, 0, 209, 0, + 0, 0, 0, 211, 215, 217, 0, 219, 221, 226, + 226, 226, 226, 226, 226, 226, 227, 227, 227, 227, - 222, 222, 222, 222, 222, 222, 224, 224, 224, 224, - 225, 0, 225, 225, 226, 226, 227, 0, 227, 227, - 227, 227, 227, 228, 0, 228, 228, 228, 228, 228, - 229, 0, 229, 229, 229, 229, 229, 230, 0, 230, - 230, 230, 230, 230, 231, 0, 0, 231, 231, 231, - 231, 232, 0, 232, 232, 233, 0, 233, 233, 234, - 0, 234, 234, 235, 0, 235, 235, 236, 0, 236, - 236, 237, 0, 237, 237, 217, 217, 217, 217, 217, - 217, 217, 217, 217, 217, 217, 217, 217, 217, 217, - 217, 217, 217, 217, 217, 217, 217, 217, 217, 217, + 227, 227, 227, 228, 228, 228, 228, 228, 228, 228, + 229, 229, 229, 229, 229, 229, 229, 230, 230, 230, + 230, 230, 230, 230, 232, 232, 232, 232, 233, 0, + 233, 233, 234, 234, 235, 0, 235, 235, 235, 235, + 235, 236, 0, 236, 236, 236, 236, 236, 237, 0, + 237, 237, 237, 237, 237, 238, 0, 238, 238, 238, + 238, 238, 239, 0, 0, 239, 239, 239, 239, 240, + 0, 240, 240, 241, 0, 241, 241, 242, 0, 242, + 242, 243, 0, 243, 243, 244, 0, 244, 244, 245, + 0, 245, 245, 225, 225, 225, 225, 225, 225, 225, - 217, 217, 217, 217, 217, 217, 217, 217, 217, 217, - 217, 217, 217, 217, 217, 217, 217, 217, 217, 217, - 217, 217, 217, 217, 217, 217, 217, 217, 217, 217, - 217, 217, 217, 217, 217, 217, 217, 217, 217, 217, - 217, 217, 217, 217, 217, 217, 217, 217, 217, 217, - 217, 217 + 225, 225, 225, 225, 225, 225, 225, 225, 225, 225, + 225, 225, 225, 225, 225, 225, 225, 225, 225, 225, + 225, 225, 225, 225, 225, 225, 225, 225, 225, 225, + 225, 225, 225, 225, 225, 225, 225, 225, 225, 225, + 225, 225, 225, 225, 225, 225, 225, 225, 225, 225, + 225, 225, 225, 225, 225, 225, 225, 225, 225, 225, + 225, 225, 225, 225, 225, 225, 225, 225, 225, 225 } ; /* Table of booleans, true if rule could match eol. */ -static yyconst flex_int32_t yy_rule_can_match_eol[88] = +static yyconst flex_int32_t yy_rule_can_match_eol[89] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 1, - 0, 0, 0, 0, 0, 1, 0, 0, }; + 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, + 1, 0, 0, 0, 0, 0, 1, 0, 0, }; /* The intent behind this definition is that it'll catch * any uses of REJECT which flex missed. @@ -1018,13 +1023,13 @@ yy_match: while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state ) { yy_current_state = (int) yy_def[yy_current_state]; - if ( yy_current_state >= 218 ) + if ( yy_current_state >= 226 ) yy_c = yy_meta[(unsigned int) yy_c]; } yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c]; ++yy_cp; } - while ( yy_current_state != 217 ); + while ( yy_current_state != 225 ); yy_cp = yyg->yy_last_accepting_cpos; yy_current_state = yyg->yy_last_accepting_state; @@ -1107,113 +1112,119 @@ YY_RULE_SETUP case 9: YY_RULE_SETUP { - return T_ASC; + return T_AGGREGATE; } YY_BREAK case 10: YY_RULE_SETUP { - return T_DESC; + return T_ASC; } YY_BREAK case 11: YY_RULE_SETUP { - return T_NOT; + return T_DESC; } YY_BREAK case 12: YY_RULE_SETUP { - return T_AND; + return T_NOT; } YY_BREAK case 13: YY_RULE_SETUP { - return T_OR; + return T_AND; } YY_BREAK case 14: YY_RULE_SETUP { - return T_IN; + return T_OR; } YY_BREAK case 15: YY_RULE_SETUP { - return T_INTO; + return T_IN; } YY_BREAK case 16: YY_RULE_SETUP { - return T_WITH; + return T_INTO; } YY_BREAK case 17: YY_RULE_SETUP { - return T_REMOVE; + return T_WITH; } YY_BREAK case 18: YY_RULE_SETUP { - return T_INSERT; + return T_REMOVE; } YY_BREAK case 19: YY_RULE_SETUP { - return T_UPDATE; + return T_INSERT; } YY_BREAK case 20: YY_RULE_SETUP { - return T_REPLACE; + return T_UPDATE; } YY_BREAK case 21: YY_RULE_SETUP { - return T_UPSERT; + return T_REPLACE; } YY_BREAK case 22: YY_RULE_SETUP { - return T_GRAPH; + return T_UPSERT; } YY_BREAK case 23: YY_RULE_SETUP { - return T_OUTBOUND; + return T_GRAPH; } YY_BREAK case 24: YY_RULE_SETUP { - return T_INBOUND; + return T_OUTBOUND; } YY_BREAK case 25: YY_RULE_SETUP { - return T_ANY; + return T_INBOUND; } YY_BREAK case 26: YY_RULE_SETUP { - return T_ALL; + return T_ANY; } YY_BREAK case 27: YY_RULE_SETUP +{ + return T_ALL; +} + YY_BREAK +case 28: +YY_RULE_SETUP { return T_NONE; } @@ -1221,19 +1232,19 @@ YY_RULE_SETUP /* --------------------------------------------------------------------------- * predefined type literals * --------------------------------------------------------------------------- */ -case 28: +case 29: YY_RULE_SETUP { return T_NULL; } YY_BREAK -case 29: +case 30: YY_RULE_SETUP { return T_TRUE; } YY_BREAK -case 30: +case 31: YY_RULE_SETUP { return T_FALSE; @@ -1242,115 +1253,115 @@ YY_RULE_SETUP /* --------------------------------------------------------------------------- * operators * --------------------------------------------------------------------------- */ -case 31: +case 32: YY_RULE_SETUP { return T_EQ; } YY_BREAK -case 32: +case 33: YY_RULE_SETUP { return T_NE; } YY_BREAK -case 33: +case 34: YY_RULE_SETUP { return T_GE; } YY_BREAK -case 34: +case 35: YY_RULE_SETUP { return T_GT; } YY_BREAK -case 35: +case 36: YY_RULE_SETUP { return T_LE; } YY_BREAK -case 36: +case 37: YY_RULE_SETUP { return T_LT; } YY_BREAK -case 37: +case 38: YY_RULE_SETUP { return T_ASSIGN; } YY_BREAK -case 38: +case 39: YY_RULE_SETUP { return T_NOT; } YY_BREAK -case 39: +case 40: YY_RULE_SETUP { return T_AND; } YY_BREAK -case 40: +case 41: YY_RULE_SETUP { return T_OR; } YY_BREAK -case 41: +case 42: YY_RULE_SETUP { return T_PLUS; } YY_BREAK -case 42: +case 43: YY_RULE_SETUP { return T_MINUS; } YY_BREAK -case 43: +case 44: YY_RULE_SETUP { return T_TIMES; } YY_BREAK -case 44: +case 45: YY_RULE_SETUP { return T_DIV; } YY_BREAK -case 45: +case 46: YY_RULE_SETUP { return T_MOD; } YY_BREAK -case 46: +case 47: YY_RULE_SETUP { return T_QUESTION; } YY_BREAK -case 47: +case 48: YY_RULE_SETUP { return T_SCOPE; } YY_BREAK -case 48: +case 49: YY_RULE_SETUP { return T_COLON; } YY_BREAK -case 49: +case 50: YY_RULE_SETUP { return T_RANGE; @@ -1359,43 +1370,43 @@ YY_RULE_SETUP /* --------------------------------------------------------------------------- * punctuation * --------------------------------------------------------------------------- */ -case 50: +case 51: YY_RULE_SETUP { return T_COMMA; } YY_BREAK -case 51: +case 52: YY_RULE_SETUP { return T_OPEN; } YY_BREAK -case 52: +case 53: YY_RULE_SETUP { return T_CLOSE; } YY_BREAK -case 53: +case 54: YY_RULE_SETUP { return T_OBJECT_OPEN; } YY_BREAK -case 54: +case 55: YY_RULE_SETUP { return T_OBJECT_CLOSE; } YY_BREAK -case 55: +case 56: YY_RULE_SETUP { return T_ARRAY_OPEN; } YY_BREAK -case 56: +case 57: YY_RULE_SETUP { return T_ARRAY_CLOSE; @@ -1404,7 +1415,7 @@ YY_RULE_SETUP /* --------------------------------------------------------------------------- * literals * --------------------------------------------------------------------------- */ -case 57: +case 58: YY_RULE_SETUP { /* unquoted string */ @@ -1413,7 +1424,7 @@ YY_RULE_SETUP return T_STRING; } YY_BREAK -case 58: +case 59: YY_RULE_SETUP { /* string enclosed in backticks */ @@ -1421,7 +1432,7 @@ YY_RULE_SETUP BEGIN(BACKTICK); } YY_BREAK -case 59: +case 60: YY_RULE_SETUP { /* end of backtick-enclosed string */ @@ -1432,36 +1443,36 @@ YY_RULE_SETUP return T_STRING; } YY_BREAK -case 60: +case 61: YY_RULE_SETUP { /* character escaped by backslash */ BEGIN(BACKTICK); } YY_BREAK -case 61: -/* rule 61 can match eol */ +case 62: +/* rule 62 can match eol */ YY_RULE_SETUP { /* newline character inside backtick */ BEGIN(BACKTICK); } YY_BREAK -case 62: +case 63: YY_RULE_SETUP { /* any character (except newline) inside backtick */ BEGIN(BACKTICK); } YY_BREAK -case 63: +case 64: YY_RULE_SETUP { yyextra->marker(yyextra->queryString() + yyextra->offset()); BEGIN(DOUBLE_QUOTE); } YY_BREAK -case 64: +case 65: YY_RULE_SETUP { /* end of quote-enclosed string */ @@ -1472,36 +1483,36 @@ YY_RULE_SETUP return T_QUOTED_STRING; } YY_BREAK -case 65: +case 66: YY_RULE_SETUP { /* character escaped by backslash */ BEGIN(DOUBLE_QUOTE); } YY_BREAK -case 66: -/* rule 66 can match eol */ +case 67: +/* rule 67 can match eol */ YY_RULE_SETUP { /* newline character inside quote */ BEGIN(DOUBLE_QUOTE); } YY_BREAK -case 67: -YY_RULE_SETUP -{ - /* any character (except newline) inside quote */ - BEGIN(DOUBLE_QUOTE); -} - YY_BREAK case 68: YY_RULE_SETUP +{ + /* any character (except newline) inside quote */ + BEGIN(DOUBLE_QUOTE); +} + YY_BREAK +case 69: +YY_RULE_SETUP { yyextra->marker(yyextra->queryString() + yyextra->offset()); BEGIN(SINGLE_QUOTE); } YY_BREAK -case 69: +case 70: YY_RULE_SETUP { /* end of quote-enclosed string */ @@ -1512,29 +1523,29 @@ YY_RULE_SETUP return T_QUOTED_STRING; } YY_BREAK -case 70: +case 71: YY_RULE_SETUP { /* character escaped by backslash */ BEGIN(SINGLE_QUOTE); } YY_BREAK -case 71: -/* rule 71 can match eol */ +case 72: +/* rule 72 can match eol */ YY_RULE_SETUP { /* newline character inside quote */ BEGIN(SINGLE_QUOTE); } YY_BREAK -case 72: +case 73: YY_RULE_SETUP { /* any character (except newline) inside quote */ BEGIN(SINGLE_QUOTE); } YY_BREAK -case 73: +case 74: YY_RULE_SETUP { /* a numeric integer value */ @@ -1561,7 +1572,7 @@ YY_RULE_SETUP return T_INTEGER; } YY_BREAK -case 74: +case 75: YY_RULE_SETUP { /* a numeric double value */ @@ -1586,7 +1597,7 @@ YY_RULE_SETUP /* --------------------------------------------------------------------------- * bind parameters * --------------------------------------------------------------------------- */ -case 75: +case 76: YY_RULE_SETUP { /* bind parameters must start with a @ @@ -1599,78 +1610,78 @@ YY_RULE_SETUP /* --------------------------------------------------------------------------- * whitespace etc. * --------------------------------------------------------------------------- */ -case 76: +case 77: YY_RULE_SETUP { /* whitespace is ignored */ } YY_BREAK -case 77: -/* rule 77 can match eol */ +case 78: +/* rule 78 can match eol */ YY_RULE_SETUP { yycolumn = 0; } YY_BREAK -case 78: +case 79: YY_RULE_SETUP { BEGIN(COMMENT_SINGLE); } YY_BREAK -case 79: -/* rule 79 can match eol */ +case 80: +/* rule 80 can match eol */ YY_RULE_SETUP { yylineno++; BEGIN(INITIAL); } YY_BREAK -case 80: +case 81: YY_RULE_SETUP { // eat comment in chunks } YY_BREAK -case 81: -YY_RULE_SETUP -{ - BEGIN(COMMENT_MULTI); -} - YY_BREAK case 82: YY_RULE_SETUP { - BEGIN(INITIAL); + BEGIN(COMMENT_MULTI); } YY_BREAK case 83: YY_RULE_SETUP +{ + BEGIN(INITIAL); +} + YY_BREAK +case 84: +YY_RULE_SETUP { // eat comment in chunks } YY_BREAK -case 84: +case 85: YY_RULE_SETUP { // eat the lone star } YY_BREAK -case 85: -/* rule 85 can match eol */ +case 86: +/* rule 86 can match eol */ YY_RULE_SETUP { yylineno++; } YY_BREAK -case 86: +case 87: YY_RULE_SETUP { /* anything else is returned as it is */ return (int) yytext[0]; } YY_BREAK -case 87: +case 88: YY_RULE_SETUP ECHO; YY_BREAK @@ -1974,7 +1985,7 @@ static int yy_get_next_buffer (yyscan_t yyscanner) while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state ) { yy_current_state = (int) yy_def[yy_current_state]; - if ( yy_current_state >= 218 ) + if ( yy_current_state >= 226 ) yy_c = yy_meta[(unsigned int) yy_c]; } yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c]; @@ -2003,11 +2014,11 @@ static int yy_get_next_buffer (yyscan_t yyscanner) while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state ) { yy_current_state = (int) yy_def[yy_current_state]; - if ( yy_current_state >= 218 ) + if ( yy_current_state >= 226 ) yy_c = yy_meta[(unsigned int) yy_c]; } yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c]; - yy_is_jam = (yy_current_state == 217); + yy_is_jam = (yy_current_state == 225); (void)yyg; return yy_is_jam ? 0 : yy_current_state; diff --git a/arangod/Aql/tokens.ll b/arangod/Aql/tokens.ll index a3c628dcee..f9d2dcfe82 100644 --- a/arangod/Aql/tokens.ll +++ b/arangod/Aql/tokens.ll @@ -93,6 +93,10 @@ namespace triagens { return T_DISTINCT; } +(?i:AGGREGATE) { + return T_AGGREGATE; +} + (?i:ASC) { return T_ASC; } diff --git a/arangod/CMakeLists.txt b/arangod/CMakeLists.txt index 54a0aad299..6af28854e6 100644 --- a/arangod/CMakeLists.txt +++ b/arangod/CMakeLists.txt @@ -60,9 +60,6 @@ add_executable( Actions/RestActionHandler.cpp ApplicationServer/ApplicationFeature.cpp ApplicationServer/ApplicationServer.cpp - Aql/AggregateBlock.cpp - Aql/AggregateNode.cpp - Aql/AggregationOptions.cpp Aql/AqlItemBlock.cpp Aql/AqlItemBlockManager.cpp Aql/AqlValue.cpp @@ -77,6 +74,9 @@ add_executable( Aql/Collection.cpp Aql/Collections.cpp Aql/CollectionScanner.cpp + Aql/CollectBlock.cpp + Aql/CollectNode.cpp + Aql/CollectOptions.cpp Aql/Condition.cpp Aql/ConditionFinder.cpp Aql/EnumerateCollectionBlock.cpp diff --git a/arangod/Makefile.files b/arangod/Makefile.files index b5cf7bcbf3..1f2cab6729 100644 --- a/arangod/Makefile.files +++ b/arangod/Makefile.files @@ -17,9 +17,6 @@ arangod_libarangod_a_SOURCES = \ arangod/Actions/RestActionHandler.cpp \ arangod/ApplicationServer/ApplicationFeature.cpp \ arangod/ApplicationServer/ApplicationServer.cpp \ - arangod/Aql/AggregateBlock.cpp \ - arangod/Aql/AggregateNode.cpp \ - arangod/Aql/AggregationOptions.cpp \ arangod/Aql/AqlItemBlock.cpp \ arangod/Aql/AqlItemBlockManager.cpp \ arangod/Aql/AqlValue.cpp \ @@ -34,6 +31,9 @@ arangod_libarangod_a_SOURCES = \ arangod/Aql/Collection.cpp \ arangod/Aql/Collections.cpp \ arangod/Aql/CollectionScanner.cpp \ + arangod/Aql/CollectBlock.cpp \ + arangod/Aql/CollectNode.cpp \ + arangod/Aql/CollectOptions.cpp \ arangod/Aql/Condition.cpp \ arangod/Aql/ConditionFinder.cpp \ arangod/Aql/EnumerateCollectionBlock.cpp \ diff --git a/js/apps/system/_admin/aardvark/APP/frontend/js/modules/common/@arangodb/aql/explainer.js b/js/apps/system/_admin/aardvark/APP/frontend/js/modules/common/@arangodb/aql/explainer.js index 140b1e5a1c..b1d5c1f69a 100644 --- a/js/apps/system/_admin/aardvark/APP/frontend/js/modules/common/@arangodb/aql/explainer.js +++ b/js/apps/system/_admin/aardvark/APP/frontend/js/modules/common/@arangodb/aql/explainer.js @@ -795,6 +795,7 @@ function processQuery (query, explain) { case "FilterNode": return keyword("FILTER") + " " + variableName(node.inVariable); case "AggregateNode": + case "CollectNode": return keyword("COLLECT") + " " + node.aggregates.map(function(node) { return variableName(node.outVariable) + " = " + variableName(node.inVariable); }).join(", ") + diff --git a/js/common/modules/@arangodb/aql/explainer.js b/js/common/modules/@arangodb/aql/explainer.js index f0c669906e..1f5981fc3a 100644 --- a/js/common/modules/@arangodb/aql/explainer.js +++ b/js/common/modules/@arangodb/aql/explainer.js @@ -794,6 +794,7 @@ function processQuery (query, explain) { case "FilterNode": return keyword("FILTER") + " " + variableName(node.inVariable); case "AggregateNode": + case "CollectNode": return keyword("COLLECT") + " " + node.aggregates.map(function(node) { return variableName(node.outVariable) + " = " + variableName(node.inVariable); }).join(", ") + diff --git a/js/server/tests/aql-explain-cluster.js b/js/server/tests/aql-explain-cluster.js index 2b3a477d18..b7cc3cc00c 100644 --- a/js/server/tests/aql-explain-cluster.js +++ b/js/server/tests/aql-explain-cluster.js @@ -282,7 +282,7 @@ function explainSuite () { prev = node.id; node = nodes[n++]; - assertEqual("AggregateNode", node.type); + assertEqual("CollectNode", node.type); assertEqual([ prev ], node.dependencies); assertEqual(1, node.aggregates.length); assertEqual("a", node.aggregates[0].inVariable.name); diff --git a/js/server/tests/aql-explain-noncluster.js b/js/server/tests/aql-explain-noncluster.js index 1c66bb03de..870316cb07 100644 --- a/js/server/tests/aql-explain-noncluster.js +++ b/js/server/tests/aql-explain-noncluster.js @@ -258,7 +258,7 @@ function explainSuite () { assertTrue(node.stable); node = nodes[7]; - assertEqual("AggregateNode", node.type); + assertEqual("CollectNode", node.type); assertEqual([ 9 ], node.dependencies); assertEqual(7, node.id); assertEqual(1, node.aggregates.length); diff --git a/js/server/tests/aql-optimizer-collect-methods.js b/js/server/tests/aql-optimizer-collect-methods.js index bb9555367d..c0bb2dde0b 100644 --- a/js/server/tests/aql-optimizer-collect-methods.js +++ b/js/server/tests/aql-optimizer-collect-methods.js @@ -126,7 +126,7 @@ function optimizerCollectMethodsTestSuite () { var aggregateNodes = 0; var sortNodes = 0; plan.nodes.map(function(node) { - if (node.type === "AggregateNode") { + if (node.type === "CollectNode") { ++aggregateNodes; assertEqual("hash", node.aggregationOptions.method); } @@ -166,7 +166,7 @@ function optimizerCollectMethodsTestSuite () { var aggregateNodes = 0; var sortNodes = 0; plan.nodes.map(function(node) { - if (node.type === "AggregateNode") { + if (node.type === "CollectNode") { ++aggregateNodes; assertEqual("hash", node.aggregationOptions.method); } @@ -204,7 +204,7 @@ function optimizerCollectMethodsTestSuite () { var aggregateNodes = 0; var sortNodes = 0; plan.nodes.map(function(node) { - if (node.type === "AggregateNode") { + if (node.type === "CollectNode") { ++aggregateNodes; assertEqual("sorted", node.aggregationOptions.method); } @@ -241,7 +241,7 @@ function optimizerCollectMethodsTestSuite () { var aggregateNodes = 0; var sortNodes = 0; plan.nodes.map(function(node) { - if (node.type === "AggregateNode") { + if (node.type === "CollectNode") { ++aggregateNodes; assertEqual("hash", node.aggregationOptions.method); } @@ -282,7 +282,7 @@ function optimizerCollectMethodsTestSuite () { var aggregateNodes = 0; var sortNodes = 0; plan.nodes.map(function(node) { - if (node.type === "AggregateNode") { + if (node.type === "CollectNode") { ++aggregateNodes; assertEqual("sorted", node.aggregationOptions.method); } @@ -317,7 +317,7 @@ function optimizerCollectMethodsTestSuite () { var aggregateNodes = 0; var sortNodes = 0; plan.nodes.map(function(node) { - if (node.type === "AggregateNode") { + if (node.type === "CollectNode") { ++aggregateNodes; assertEqual("sorted", node.aggregationOptions.method); } diff --git a/js/server/tests/aql-optimizer-rule-remove-collect-into.js b/js/server/tests/aql-optimizer-rule-remove-collect-into.js index db78c6ecdc..f084b3bd2d 100644 --- a/js/server/tests/aql-optimizer-rule-remove-collect-into.js +++ b/js/server/tests/aql-optimizer-rule-remove-collect-into.js @@ -117,9 +117,9 @@ function optimizerRuleTestSuite () { testPlans : function () { var plans = [ - [ "FOR i IN 1..10 COLLECT a = i INTO group RETURN a", [ "SingletonNode", "CalculationNode", "EnumerateListNode", "SortNode", "AggregateNode", "ReturnNode" ] ], - [ "FOR i IN 1..10 FOR j IN 1..10 COLLECT a = i, b = j INTO group RETURN a", [ "SingletonNode", "CalculationNode", "EnumerateListNode", "CalculationNode", "EnumerateListNode", "SortNode", "AggregateNode", "ReturnNode" ] ], - [ "FOR i IN 1..10 FOR j IN 1..10 COLLECT a = i, b = j INTO group RETURN { a: a, b : b }", [ "SingletonNode", "CalculationNode", "EnumerateListNode", "CalculationNode", "EnumerateListNode", "SortNode", "AggregateNode", "CalculationNode", "ReturnNode" ] ] + [ "FOR i IN 1..10 COLLECT a = i INTO group RETURN a", [ "SingletonNode", "CalculationNode", "EnumerateListNode", "SortNode", "CollectNode", "ReturnNode" ] ], + [ "FOR i IN 1..10 FOR j IN 1..10 COLLECT a = i, b = j INTO group RETURN a", [ "SingletonNode", "CalculationNode", "EnumerateListNode", "CalculationNode", "EnumerateListNode", "SortNode", "CollectNode", "ReturnNode" ] ], + [ "FOR i IN 1..10 FOR j IN 1..10 COLLECT a = i, b = j INTO group RETURN { a: a, b : b }", [ "SingletonNode", "CalculationNode", "EnumerateListNode", "CalculationNode", "EnumerateListNode", "SortNode", "CollectNode", "CalculationNode", "ReturnNode" ] ] ]; plans.forEach(function(plan) { diff --git a/js/server/tests/aql-optimizer-rule-remove-redundant-sorts.js b/js/server/tests/aql-optimizer-rule-remove-redundant-sorts.js index 10218aedcd..2da5503be7 100644 --- a/js/server/tests/aql-optimizer-rule-remove-redundant-sorts.js +++ b/js/server/tests/aql-optimizer-rule-remove-redundant-sorts.js @@ -133,7 +133,7 @@ function optimizerRuleTestSuite () { [ "FOR i IN [ { a: 1 }, { a: 2 }, { a: 3 } ] SORT i.a DESC SORT i.a DESC RETURN i", [ "SingletonNode", "CalculationNode", "EnumerateListNode", "CalculationNode", "SortNode", "ReturnNode" ] ], [ "FOR i IN [ { a: 1, b: 1 }, { a: 2, b: 1 }, { a: 3, b: 1 } ] SORT i.a ASC, i.b DESC SORT i.a DESC, i.b ASC RETURN i", [ "SingletonNode", "CalculationNode", "EnumerateListNode", "CalculationNode", "CalculationNode", "SortNode", "ReturnNode" ] ], [ "FOR i IN [ { a: 1, b: 1 }, { a: 2, b: 1 }, { a: 3, b: 1 } ] SORT i.a ASC, i.b DESC FILTER i.a == 1 SORT i.a DESC, i.b ASC RETURN i", [ "SingletonNode", "CalculationNode", "EnumerateListNode", "CalculationNode", "FilterNode", "CalculationNode", "CalculationNode", "SortNode", "ReturnNode" ] ], - [ "FOR i IN [ { a: 1, b: 1 }, { a: 2, b: 1 }, { a: 3, b: 1 } ] SORT i.a ASC COLLECT x = i.a RETURN x", [ "SingletonNode", "CalculationNode", "EnumerateListNode", "CalculationNode", "SortNode", "AggregateNode", "ReturnNode" ] ], + [ "FOR i IN [ { a: 1, b: 1 }, { a: 2, b: 1 }, { a: 3, b: 1 } ] SORT i.a ASC COLLECT x = i.a RETURN x", [ "SingletonNode", "CalculationNode", "EnumerateListNode", "CalculationNode", "SortNode", "CollectNode", "ReturnNode" ] ], [ "FOR i IN [ { a: 1, b: 1 }, { a: 2, b: 1 }, { a: 3, b: 1 } ] SORT i.a, i.b SORT i.a SORT i.a RETURN i", [ "SingletonNode", "CalculationNode", "EnumerateListNode", "CalculationNode", "CalculationNode", "SortNode", "ReturnNode" ] ], [ "FOR i IN [ { a: 1, b: 1 }, { a: 2, b: 1 }, { a: 3, b: 1 } ] SORT i.a, i.b SORT i.a DESC SORT i.a ASC RETURN i", [ "SingletonNode", "CalculationNode", "EnumerateListNode", "CalculationNode", "CalculationNode", "SortNode", "ReturnNode" ] ] ];