1
0
Fork 0

Merge branch 'aql2' of ssh://github.com/triAGENS/ArangoDB into aql2

This commit is contained in:
Max Neunhoeffer 2014-08-01 13:22:45 +02:00
commit 0bbb1a3408
7 changed files with 83 additions and 78 deletions

View File

@ -67,11 +67,6 @@ void ExecutionBlock::walk (WalkerWorker* worker) {
worker->after(this); worker->after(this);
} }
////////////////////////////////////////////////////////////////////////////////
/// @brief
////////////////////////////////////////////////////////////////////////////////
// Local Variables: // Local Variables:
// mode: outline-minor // mode: outline-minor
// outline-regexp: "^\\(/// @brief\\|/// {@inheritDoc}\\|/// @addtogroup\\|// --SECTION--\\|/// @\\}\\)" // outline-regexp: "^\\(/// @brief\\|/// {@inheritDoc}\\|/// @addtogroup\\|// --SECTION--\\|/// @\\}\\)"

View File

@ -594,7 +594,7 @@ namespace triagens {
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
~EnumerateCollectionBlock () { ~EnumerateCollectionBlock () {
if (_allDocs.size() > 0) { if (! _allDocs.empty()) {
for (auto it = _allDocs.begin(); it != _allDocs.end(); ++it) { for (auto it = _allDocs.begin(); it != _allDocs.end(); ++it) {
delete *it; delete *it;
} }
@ -627,6 +627,7 @@ namespace triagens {
auto shaper = trx.documentCollection()->getShaper(); auto shaper = trx.documentCollection()->getShaper();
// TODO: if _allDocs is not empty, its contents will leak
_allDocs.clear(); _allDocs.clear();
for (size_t i = 0; i < n; ++i) { for (size_t i = 0; i < n; ++i) {
TRI_shaped_json_t shaped; TRI_shaped_json_t shaped;
@ -637,7 +638,7 @@ namespace triagens {
res = trx.finish(res); res = trx.finish(res);
if (_allDocs.size() == 0) { if (_allDocs.empty()) {
_done = true; _done = true;
} }
@ -653,7 +654,7 @@ namespace triagens {
if (res != TRI_ERROR_NO_ERROR) { if (res != TRI_ERROR_NO_ERROR) {
return res; return res;
} }
if (_allDocs.size() == 0) { if (_allDocs.empty()) {
_done = true; _done = true;
} }
return TRI_ERROR_NO_ERROR; return TRI_ERROR_NO_ERROR;
@ -773,7 +774,7 @@ namespace triagens {
private: private:
vector<Json*> _allDocs; std::vector<Json*> _allDocs;
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
/// @brief current position in _allDocs /// @brief current position in _allDocs
@ -783,19 +784,19 @@ namespace triagens {
}; };
// ----------------------------------------------------------------------------- // -----------------------------------------------------------------------------
// --SECTION-- RootBlock // --SECTION-- ReturnBlock
// ----------------------------------------------------------------------------- // -----------------------------------------------------------------------------
class RootBlock : public ExecutionBlock { class ReturnBlock : public ExecutionBlock {
public: public:
RootBlock (RootNode const* ep) ReturnBlock (ReturnNode const* ep)
: ExecutionBlock(ep) { : ExecutionBlock(ep) {
} }
~RootBlock () { ~ReturnBlock () {
} }
virtual AqlItemBlock* getOne () { virtual AqlItemBlock* getOne () {
@ -808,7 +809,7 @@ namespace triagens {
// Let's steal the actual result and throw away the vars: // Let's steal the actual result and throw away the vars:
AqlItemBlock* stripped = new AqlItemBlock(1, 1); AqlItemBlock* stripped = new AqlItemBlock(1, 1);
auto ep = static_cast<RootNode const*>(getPlanNode()); auto ep = static_cast<ReturnNode const*>(getPlanNode());
auto it = _varOverview->varInfo.find(ep->_inVariable->id); auto it = _varOverview->varInfo.find(ep->_inVariable->id);
TRI_ASSERT(it != _varOverview->varInfo.end()); TRI_ASSERT(it != _varOverview->varInfo.end());
unsigned int index = it->second.index; unsigned int index = it->second.index;
@ -826,7 +827,7 @@ namespace triagens {
} }
// Let's steal the actual result and throw away the vars: // Let's steal the actual result and throw away the vars:
auto ep = static_cast<RootNode const*>(getPlanNode()); auto ep = static_cast<ReturnNode const*>(getPlanNode());
auto it = _varOverview->varInfo.find(ep->_inVariable->id); auto it = _varOverview->varInfo.find(ep->_inVariable->id);
TRI_ASSERT(it != _varOverview->varInfo.end()); TRI_ASSERT(it != _varOverview->varInfo.end());
unsigned int index = it->second.index; unsigned int index = it->second.index;

View File

@ -88,7 +88,7 @@ struct Instanciator : public ExecutionNode::WalkerWorker {
break; break;
} }
case ExecutionNode::ROOT: { case ExecutionNode::ROOT: {
eb = new RootBlock(static_cast<RootNode const*>(en)); eb = new ReturnBlock(static_cast<ReturnNode const*>(en));
root = eb; root = eb;
break; break;
} }
@ -139,13 +139,12 @@ ExecutionEngine* ExecutionEngine::instanciateFromPlan (ExecutionNode* plan) {
engine->_root = root; engine->_root = root;
return engine;
} }
catch (...) { catch (...) {
delete engine; delete engine;
throw; throw;
} }
return engine;
} }
// ----------------------------------------------------------------------------- // -----------------------------------------------------------------------------

View File

@ -414,16 +414,16 @@ void AggregateOnUnsortedNode::toJsonHelper (std::map<ExecutionNode*, int>& index
} }
// ----------------------------------------------------------------------------- // -----------------------------------------------------------------------------
// --SECTION-- methods of RootNode // --SECTION-- methods of ReturnNode
// ----------------------------------------------------------------------------- // -----------------------------------------------------------------------------
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
/// @brief toJson, for RootNode /// @brief toJson, for ReturnNode
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
void RootNode::toJsonHelper (std::map<ExecutionNode*, int>& indexTab, void ReturnNode::toJsonHelper (std::map<ExecutionNode*, int>& indexTab,
triagens::basics::Json& nodes, triagens::basics::Json& nodes,
TRI_memory_zone_t* zone) { TRI_memory_zone_t* zone) {
Json json(ExecutionNode::toJsonHelperGeneric(indexTab, nodes, zone)); // call base class method Json json(ExecutionNode::toJsonHelperGeneric(indexTab, nodes, zone)); // call base class method
if (json.isEmpty()) { if (json.isEmpty()) {
return; return;

View File

@ -1073,17 +1073,17 @@ namespace triagens {
// ----------------------------------------------------------------------------- // -----------------------------------------------------------------------------
// --SECTION-- class RootNode // --SECTION-- class ReturnNode
// ----------------------------------------------------------------------------- // -----------------------------------------------------------------------------
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
/// @brief class RootNode, derived from ExecutionNode /// @brief class ReturnNode, derived from ExecutionNode
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
class RootNode : public ExecutionNode { class ReturnNode : public ExecutionNode {
friend class ExecutionBlock; friend class ExecutionBlock;
friend class RootBlock; friend class ReturnBlock;
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
/// @brief constructors for various arguments, always with offset and limit /// @brief constructors for various arguments, always with offset and limit
@ -1091,7 +1091,7 @@ namespace triagens {
public: public:
RootNode (Variable const* inVariable) ReturnNode (Variable const* inVariable)
: ExecutionNode(), _inVariable(inVariable) { : ExecutionNode(), _inVariable(inVariable) {
TRI_ASSERT(_inVariable != nullptr); TRI_ASSERT(_inVariable != nullptr);
@ -1110,7 +1110,7 @@ namespace triagens {
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
virtual std::string getTypeString () const { virtual std::string getTypeString () const {
return std::string("RootNode"); return std::string("ReturnNode");
} }
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
@ -1126,7 +1126,7 @@ namespace triagens {
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
virtual ExecutionNode* clone () const { virtual ExecutionNode* clone () const {
auto c = new RootNode(_inVariable); auto c = new ReturnNode(_inVariable);
cloneDependencies(c); cloneDependencies(c);
return static_cast<ExecutionNode*>(c); return static_cast<ExecutionNode*>(c);
} }

View File

@ -96,13 +96,20 @@ ExecutionPlan* ExecutionPlan::instanciateFromAst (Ast const* ast) {
// ----------------------------------------------------------------------------- // -----------------------------------------------------------------------------
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
/// @brief add a node to the plan /// @brief add a node to the plan, will delete node if addition fails
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
void ExecutionPlan::addNode (ExecutionNode* node) { ExecutionNode* ExecutionPlan::addNode (ExecutionNode* node) {
TRI_ASSERT(node != nullptr); TRI_ASSERT(node != nullptr);
_nodes.push_back(node); try {
_nodes.push_back(node);
return node;
}
catch (...) {
delete node;
throw;
}
} }
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
@ -119,7 +126,10 @@ CalculationNode* ExecutionPlan::createTemporaryCalculation (Ast const* ast,
auto expr = new Expression(ast->query()->executor(), const_cast<AstNode*>(expression)); auto expr = new Expression(ast->query()->executor(), const_cast<AstNode*>(expression));
try { try {
return new CalculationNode(expr, out); auto en = new CalculationNode(expr, out);
addNode(reinterpret_cast<ExecutionNode*>(en));
return en;
} }
catch (...) { catch (...) {
// prevent memleak // prevent memleak
@ -167,27 +177,27 @@ ExecutionNode* ExecutionPlan::fromNodeFor (Ast const* ast,
auto v = static_cast<Variable*>(variable->getData()); auto v = static_cast<Variable*>(variable->getData());
TRI_ASSERT(v != nullptr); TRI_ASSERT(v != nullptr);
ExecutionNode* plan = nullptr; ExecutionNode* en = nullptr;
// peek at second operand // peek at second operand
if (expression->type == NODE_TYPE_COLLECTION) { if (expression->type == NODE_TYPE_COLLECTION) {
// second operand is a collection // second operand is a collection
char const* collectionName = expression->getStringValue(); char const* collectionName = expression->getStringValue();
plan = new EnumerateCollectionNode(ast->query()->vocbase(), std::string(collectionName), v); en = addNode(new EnumerateCollectionNode(ast->query()->vocbase(), std::string(collectionName), v));
} }
else if (expression->type == NODE_TYPE_REFERENCE) { else if (expression->type == NODE_TYPE_REFERENCE) {
// second operand is already a variable // second operand is already a variable
auto inVariable = static_cast<Variable*>(variable->getData()); auto inVariable = static_cast<Variable*>(variable->getData());
TRI_ASSERT(inVariable != nullptr); TRI_ASSERT(inVariable != nullptr);
plan = new EnumerateListNode(inVariable, v); en = addNode(new EnumerateListNode(inVariable, v));
} }
else { else {
// second operand is some misc. expression // second operand is some misc. expression
auto calc = createTemporaryCalculation(ast, expression); auto calc = createTemporaryCalculation(ast, expression);
try { try {
plan = new EnumerateListNode(calc->outVariable(), v); en = addNode(new EnumerateListNode(calc->outVariable(), v));
plan->addDependency(calc); en->addDependency(calc);
} }
catch (...) { catch (...) {
// prevent memleak // prevent memleak
@ -195,9 +205,9 @@ ExecutionNode* ExecutionPlan::fromNodeFor (Ast const* ast,
} }
} }
TRI_ASSERT(plan != nullptr); TRI_ASSERT(en != nullptr);
return addDependency(previous, plan); return addDependency(previous, en);
} }
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
@ -212,21 +222,21 @@ ExecutionNode* ExecutionPlan::fromNodeFilter (Ast const* ast,
auto expression = node->getMember(0); auto expression = node->getMember(0);
ExecutionNode* plan = nullptr; ExecutionNode* en = nullptr;
if (expression->type == NODE_TYPE_REFERENCE) { if (expression->type == NODE_TYPE_REFERENCE) {
// operand is already a variable // operand is already a variable
auto v = static_cast<Variable*>(expression->getData()); auto v = static_cast<Variable*>(expression->getData());
TRI_ASSERT(v != nullptr); TRI_ASSERT(v != nullptr);
plan = new FilterNode(v); en = addNode(new FilterNode(v));
} }
else { else {
// operand is some misc expression // operand is some misc expression
auto calc = createTemporaryCalculation(ast, expression); auto calc = createTemporaryCalculation(ast, expression);
try { try {
plan = new FilterNode(calc->outVariable()); en = addNode(new FilterNode(calc->outVariable()));
plan->addDependency(calc); en->addDependency(calc);
} }
catch (...) { catch (...) {
// prevent memleak // prevent memleak
@ -234,7 +244,7 @@ ExecutionNode* ExecutionPlan::fromNodeFilter (Ast const* ast,
} }
} }
return addDependency(previous, plan); return addDependency(previous, en);
} }
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
@ -252,7 +262,7 @@ ExecutionNode* ExecutionPlan::fromNodeLet (Ast const* ast,
auto v = static_cast<Variable*>(variable->getData()); auto v = static_cast<Variable*>(variable->getData());
ExecutionNode* plan = nullptr; ExecutionNode* en = nullptr;
if (expression->type == NODE_TYPE_SUBQUERY) { if (expression->type == NODE_TYPE_SUBQUERY) {
// TODO: node might be a subquery. this is currently NOT handled // TODO: node might be a subquery. this is currently NOT handled
@ -263,7 +273,7 @@ ExecutionNode* ExecutionPlan::fromNodeLet (Ast const* ast,
auto expr = new Expression(ast->query()->executor(), const_cast<AstNode*>(expression)); auto expr = new Expression(ast->query()->executor(), const_cast<AstNode*>(expression));
try { try {
plan = new CalculationNode(expr, v); en = addNode(new CalculationNode(expr, v));
} }
catch (...) { catch (...) {
// prevent memleak // prevent memleak
@ -272,7 +282,7 @@ ExecutionNode* ExecutionPlan::fromNodeLet (Ast const* ast,
} }
} }
return addDependency(previous, plan); return addDependency(previous, en);
} }
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
@ -331,9 +341,9 @@ ExecutionNode* ExecutionPlan::fromNodeSort (Ast const* ast,
previous = (*it); previous = (*it);
} }
auto plan = new SortNode(elements); auto en = addNode(new SortNode(elements));
return addDependency(previous, plan); return addDependency(previous, en);
} }
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
@ -370,9 +380,9 @@ ExecutionNode* ExecutionPlan::fromNodeLimit (Ast const* ast,
TRI_ASSERT(offset->type == NODE_TYPE_VALUE); TRI_ASSERT(offset->type == NODE_TYPE_VALUE);
TRI_ASSERT(count->type == NODE_TYPE_VALUE); TRI_ASSERT(count->type == NODE_TYPE_VALUE);
auto plan = new LimitNode(static_cast<size_t>(offset->getIntValue()), static_cast<size_t>(count->getIntValue())); auto en = addNode(new LimitNode(static_cast<size_t>(offset->getIntValue()), static_cast<size_t>(count->getIntValue())));
return addDependency(previous, plan); return addDependency(previous, en);
} }
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
@ -387,21 +397,21 @@ ExecutionNode* ExecutionPlan::fromNodeReturn (Ast const* ast,
auto expression = node->getMember(0); auto expression = node->getMember(0);
ExecutionNode* plan = nullptr; ExecutionNode* en = nullptr;
if (expression->type == NODE_TYPE_REFERENCE) { if (expression->type == NODE_TYPE_REFERENCE) {
// operand is already a variable // operand is already a variable
auto v = static_cast<Variable*>(expression->getData()); auto v = static_cast<Variable*>(expression->getData());
TRI_ASSERT(v != nullptr); TRI_ASSERT(v != nullptr);
plan = new RootNode(v); en = addNode(new ReturnNode(v));
} }
else { else {
// operand is some misc expression // operand is some misc expression
auto calc = createTemporaryCalculation(ast, expression); auto calc = createTemporaryCalculation(ast, expression);
try { try {
plan = new RootNode(calc->outVariable()); en = addNode(new ReturnNode(calc->outVariable()));
plan->addDependency(calc); en->addDependency(calc);
} }
catch (...) { catch (...) {
// prevent memleak // prevent memleak
@ -409,7 +419,7 @@ ExecutionNode* ExecutionPlan::fromNodeReturn (Ast const* ast,
} }
} }
return addDependency(previous, plan); return addDependency(previous, en);
} }
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
@ -480,7 +490,7 @@ ExecutionNode* ExecutionPlan::fromNode (Ast const* ast,
AstNode const* node) { AstNode const* node) {
TRI_ASSERT(node != nullptr); TRI_ASSERT(node != nullptr);
ExecutionNode* plan = new SingletonNode(); ExecutionNode* en = addNode(new SingletonNode());
try { try {
size_t const n = node->numMembers(); size_t const n = node->numMembers();
@ -494,78 +504,78 @@ ExecutionNode* ExecutionPlan::fromNode (Ast const* ast,
switch (member->type) { switch (member->type) {
case NODE_TYPE_FOR: { case NODE_TYPE_FOR: {
plan = fromNodeFor(ast, plan, member); en = fromNodeFor(ast, en, member);
break; break;
} }
case NODE_TYPE_FILTER: { case NODE_TYPE_FILTER: {
plan = fromNodeFilter(ast, plan, member); en = fromNodeFilter(ast, en, member);
break; break;
} }
case NODE_TYPE_LET: { case NODE_TYPE_LET: {
plan = fromNodeLet(ast, plan, member); en = fromNodeLet(ast, en, member);
break; break;
} }
case NODE_TYPE_SORT: { case NODE_TYPE_SORT: {
plan = fromNodeSort(ast, plan, member); en = fromNodeSort(ast, en, member);
break; break;
} }
case NODE_TYPE_COLLECT: { case NODE_TYPE_COLLECT: {
plan = fromNodeCollect(ast, plan, member); en = fromNodeCollect(ast, en, member);
break; break;
} }
case NODE_TYPE_LIMIT: { case NODE_TYPE_LIMIT: {
plan = fromNodeLimit(ast, plan, member); en = fromNodeLimit(ast, en, member);
break; break;
} }
case NODE_TYPE_RETURN: { case NODE_TYPE_RETURN: {
plan = fromNodeReturn(ast, plan, member); en = fromNodeReturn(ast, en, member);
break; break;
} }
case NODE_TYPE_REMOVE: { case NODE_TYPE_REMOVE: {
plan = fromNodeRemove(ast, plan, member); en = fromNodeRemove(ast, en, member);
break; break;
} }
case NODE_TYPE_INSERT: { case NODE_TYPE_INSERT: {
plan = fromNodeInsert(ast, plan, member); en = fromNodeInsert(ast, en, member);
break; break;
} }
case NODE_TYPE_UPDATE: { case NODE_TYPE_UPDATE: {
plan = fromNodeUpdate(ast, plan, member); en = fromNodeUpdate(ast, en, member);
break; break;
} }
case NODE_TYPE_REPLACE: { case NODE_TYPE_REPLACE: {
plan = fromNodeReplace(ast, plan, member); en = fromNodeReplace(ast, en, member);
break; break;
} }
default: { default: {
// node type not implemented // node type not implemented
plan = nullptr; en = nullptr;
break; break;
} }
} }
if (plan == nullptr) { if (en == nullptr) {
THROW_ARANGO_EXCEPTION(TRI_ERROR_INTERNAL); THROW_ARANGO_EXCEPTION(TRI_ERROR_INTERNAL);
} }
} }
return plan; return en;
} }
catch (...) { catch (...) {
// prevent memleak // prevent memleak
if (plan != nullptr) { if (en != nullptr) {
delete plan; delete en;
} }
throw; throw;
} }

View File

@ -94,10 +94,10 @@ namespace triagens {
private: private:
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
/// @brief add a node to the plan /// @brief add a node to the plan, will delete node if addition fails
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
void addNode (ExecutionNode*); ExecutionNode* addNode (ExecutionNode*);
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
/// @brief creates a calculation node for an arbitrary expression /// @brief creates a calculation node for an arbitrary expression