mirror of https://gitee.com/bigwinds/arangodb
Merge branch 'aql2' of ssh://github.com/triAGENS/ArangoDB into aql2
Conflicts: arangod/Aql/ExecutionNode.h
This commit is contained in:
commit
8bb501468f
|
@ -186,6 +186,7 @@ AstNode* Ast::createNodeRemove (AstNode const* expression,
|
||||||
node->addMember(collection);
|
node->addMember(collection);
|
||||||
node->addMember(expression);
|
node->addMember(expression);
|
||||||
|
|
||||||
|
// TODO: handle options
|
||||||
return node;
|
return node;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -200,6 +201,7 @@ AstNode* Ast::createNodeInsert (AstNode const* expression,
|
||||||
node->addMember(collection);
|
node->addMember(collection);
|
||||||
node->addMember(expression);
|
node->addMember(expression);
|
||||||
|
|
||||||
|
// TODO: handle options
|
||||||
return node;
|
return node;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -218,6 +220,7 @@ AstNode* Ast::createNodeUpdate (AstNode const* keyExpression,
|
||||||
if (keyExpression != nullptr) {
|
if (keyExpression != nullptr) {
|
||||||
node->addMember(keyExpression);
|
node->addMember(keyExpression);
|
||||||
}
|
}
|
||||||
|
// TODO: handle options
|
||||||
|
|
||||||
return node;
|
return node;
|
||||||
}
|
}
|
||||||
|
@ -237,6 +240,7 @@ AstNode* Ast::createNodeReplace (AstNode const* keyExpression,
|
||||||
if (keyExpression != nullptr) {
|
if (keyExpression != nullptr) {
|
||||||
node->addMember(keyExpression);
|
node->addMember(keyExpression);
|
||||||
}
|
}
|
||||||
|
// TODO: handle options
|
||||||
|
|
||||||
return node;
|
return node;
|
||||||
}
|
}
|
||||||
|
|
|
@ -276,8 +276,8 @@ bool AstNode::isSimple () const {
|
||||||
}
|
}
|
||||||
|
|
||||||
if (type == NODE_TYPE_ARRAY_ELEMENT) {
|
if (type == NODE_TYPE_ARRAY_ELEMENT) {
|
||||||
auto member = getMember(0);
|
auto member = getMember(0);
|
||||||
return member->isSimple();
|
return member->isSimple();
|
||||||
}
|
}
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
|
|
|
@ -330,16 +330,6 @@ namespace triagens {
|
||||||
totalNrRegs++;
|
totalNrRegs++;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case ExecutionNode::PROJECTION: {
|
|
||||||
nrRegsHere[depth]++;
|
|
||||||
nrRegs[depth]++;
|
|
||||||
auto ep = static_cast<ProjectionNode const*>(eb->getPlanNode());
|
|
||||||
TRI_ASSERT(ep != nullptr);
|
|
||||||
varInfo.insert(make_pair(ep->_outVariable->id,
|
|
||||||
VarInfo(depth, totalNrRegs)));
|
|
||||||
totalNrRegs++;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
case ExecutionNode::SUBQUERY: {
|
case ExecutionNode::SUBQUERY: {
|
||||||
nrRegsHere[depth]++;
|
nrRegsHere[depth]++;
|
||||||
nrRegs[depth]++;
|
nrRegs[depth]++;
|
||||||
|
|
|
@ -30,6 +30,7 @@
|
||||||
#include "Aql/ExecutionEngine.h"
|
#include "Aql/ExecutionEngine.h"
|
||||||
#include "Aql/ExecutionBlock.h"
|
#include "Aql/ExecutionBlock.h"
|
||||||
#include "Aql/ExecutionNode.h"
|
#include "Aql/ExecutionNode.h"
|
||||||
|
#include "Aql/ExecutionPlan.h"
|
||||||
#include "Aql/WalkerWorker.h"
|
#include "Aql/WalkerWorker.h"
|
||||||
#include "Utils/Exception.h"
|
#include "Utils/Exception.h"
|
||||||
|
|
||||||
|
|
|
@ -32,10 +32,49 @@
|
||||||
using namespace triagens::basics;
|
using namespace triagens::basics;
|
||||||
using namespace triagens::aql;
|
using namespace triagens::aql;
|
||||||
|
|
||||||
|
// -----------------------------------------------------------------------------
|
||||||
|
// --SECTION-- static initialization
|
||||||
|
// -----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
/// @brief type names
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
std::unordered_map<int, std::string const> const ExecutionNode::TypeNames{
|
||||||
|
{ static_cast<int>(ILLEGAL), "ExecutionNode (abstract)" },
|
||||||
|
{ static_cast<int>(SINGLETON), "SingletonNode" },
|
||||||
|
{ static_cast<int>(ENUMERATE_COLLECTION), "EnumerateCollectionNode" },
|
||||||
|
{ static_cast<int>(ENUMERATE_LIST), "EnumerateListNode" },
|
||||||
|
{ static_cast<int>(LIMIT), "LimitNode" },
|
||||||
|
{ static_cast<int>(CALCULATION), "CalculationNode" },
|
||||||
|
{ static_cast<int>(SUBQUERY), "SubqueryNode" },
|
||||||
|
{ static_cast<int>(FILTER), "FilterNode" },
|
||||||
|
{ static_cast<int>(SORT), "SortNode" },
|
||||||
|
{ static_cast<int>(AGGREGATE), "AggregateNode" },
|
||||||
|
{ static_cast<int>(RETURN), "ReturnNode" },
|
||||||
|
{ static_cast<int>(REMOVE), "RemoveNode" },
|
||||||
|
{ static_cast<int>(INSERT), "InsertNode" },
|
||||||
|
{ static_cast<int>(UPDATE), "UpdateNode" },
|
||||||
|
{ static_cast<int>(REPLACE), "ReplaceNode" }
|
||||||
|
};
|
||||||
|
|
||||||
// -----------------------------------------------------------------------------
|
// -----------------------------------------------------------------------------
|
||||||
// --SECTION-- methods of ExecutionNode
|
// --SECTION-- methods of ExecutionNode
|
||||||
// -----------------------------------------------------------------------------
|
// -----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
/// @brief returns the type name of the node
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
std::string ExecutionNode::getTypeString () const {
|
||||||
|
auto it = TypeNames.find(static_cast<int>(getType()));
|
||||||
|
if (it != TypeNames.end()) {
|
||||||
|
return std::string((*it).second);
|
||||||
|
}
|
||||||
|
|
||||||
|
THROW_ARANGO_EXCEPTION_MESSAGE(TRI_ERROR_NOT_IMPLEMENTED, "missing type in TypeNames");
|
||||||
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
/// @brief toJson, export an ExecutionNode to JSON
|
/// @brief toJson, export an ExecutionNode to JSON
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
@ -45,9 +84,9 @@ Json ExecutionNode::toJson (TRI_memory_zone_t* zone) {
|
||||||
Json json;
|
Json json;
|
||||||
Json nodes;
|
Json nodes;
|
||||||
try {
|
try {
|
||||||
nodes = Json(Json::List,10);
|
nodes = Json(Json::List, 10);
|
||||||
toJsonHelper(indexTab, nodes, zone);
|
toJsonHelper(indexTab, nodes, zone);
|
||||||
json = Json(Json::Array,1)
|
json = Json(Json::Array, 1)
|
||||||
("nodes", nodes);
|
("nodes", nodes);
|
||||||
}
|
}
|
||||||
catch (std::exception& e) {
|
catch (std::exception& e) {
|
||||||
|
@ -71,8 +110,8 @@ void ExecutionNode::appendAsString (std::string& st, int indent) {
|
||||||
if (_dependencies.size() != 0) {
|
if (_dependencies.size() != 0) {
|
||||||
st.push_back('\n');
|
st.push_back('\n');
|
||||||
for (size_t i = 0; i < _dependencies.size(); i++) {
|
for (size_t i = 0; i < _dependencies.size(); i++) {
|
||||||
_dependencies[i]->appendAsString(st, indent+2);
|
_dependencies[i]->appendAsString(st, indent + 2);
|
||||||
if (i != _dependencies.size()-1) {
|
if (i != _dependencies.size() - 1) {
|
||||||
st.push_back(',');
|
st.push_back(',');
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
|
@ -131,7 +170,7 @@ Json ExecutionNode::toJsonHelperGeneric (std::map<ExecutionNode*, int>& indexTab
|
||||||
_dependencies[i]->toJsonHelper(indexTab, nodes, zone);
|
_dependencies[i]->toJsonHelper(indexTab, nodes, zone);
|
||||||
}
|
}
|
||||||
Json json;
|
Json json;
|
||||||
json = Json(Json::Array,2)
|
json = Json(Json::Array, 2)
|
||||||
("type", Json(getTypeString()));
|
("type", Json(getTypeString()));
|
||||||
Json deps(Json::List, _dependencies.size());
|
Json deps(Json::List, _dependencies.size());
|
||||||
for (size_t i = 0; i < _dependencies.size(); i++) {
|
for (size_t i = 0; i < _dependencies.size(); i++) {
|
||||||
|
@ -297,36 +336,6 @@ void SubqueryNode::toJsonHelper (std::map<ExecutionNode*, int>& indexTab,
|
||||||
indexTab.insert(make_pair(this, len));
|
indexTab.insert(make_pair(this, len));
|
||||||
}
|
}
|
||||||
|
|
||||||
// -----------------------------------------------------------------------------
|
|
||||||
// --SECTION-- methods of ProjectionNode
|
|
||||||
// -----------------------------------------------------------------------------
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
|
||||||
/// @brief toJson, for ProjectionNode
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
void ProjectionNode::toJsonHelper (std::map<ExecutionNode*, int>& indexTab,
|
|
||||||
triagens::basics::Json& nodes,
|
|
||||||
TRI_memory_zone_t* zone) {
|
|
||||||
Json json(ExecutionNode::toJsonHelperGeneric(indexTab, nodes, zone)); // call base class method
|
|
||||||
if (json.isEmpty()) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
Json vec(Json::List,_keepAttributes.size());
|
|
||||||
for (auto it = _keepAttributes.begin(); it != _keepAttributes.end(); ++it) {
|
|
||||||
vec(Json(*it));
|
|
||||||
}
|
|
||||||
|
|
||||||
json("inVariable", _inVariable->toJson())
|
|
||||||
("outVariable", _outVariable->toJson())
|
|
||||||
("keepAttributes", vec);
|
|
||||||
|
|
||||||
// And add it:
|
|
||||||
int len = static_cast<int>(nodes.size());
|
|
||||||
nodes(json);
|
|
||||||
indexTab.insert(make_pair(this, len));
|
|
||||||
}
|
|
||||||
|
|
||||||
// -----------------------------------------------------------------------------
|
// -----------------------------------------------------------------------------
|
||||||
// --SECTION-- methods of FilterNode
|
// --SECTION-- methods of FilterNode
|
||||||
// -----------------------------------------------------------------------------
|
// -----------------------------------------------------------------------------
|
||||||
|
@ -442,6 +451,118 @@ void ReturnNode::toJsonHelper (std::map<ExecutionNode*, int>& indexTab,
|
||||||
indexTab.insert(make_pair(this, len));
|
indexTab.insert(make_pair(this, len));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// -----------------------------------------------------------------------------
|
||||||
|
// --SECTION-- methods of RemoveNode
|
||||||
|
// -----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
/// @brief toJson
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
void RemoveNode::toJsonHelper (std::map<ExecutionNode*, int>& indexTab,
|
||||||
|
triagens::basics::Json& nodes,
|
||||||
|
TRI_memory_zone_t* zone) {
|
||||||
|
Json json(ExecutionNode::toJsonHelperGeneric(indexTab, nodes, zone)); // call base class method
|
||||||
|
|
||||||
|
if (json.isEmpty()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Now put info about vocbase and cid in there
|
||||||
|
json("database", Json(_vocbase->_name))
|
||||||
|
("collection", Json(_collname))
|
||||||
|
("outVariable", _outVariable->toJson());
|
||||||
|
|
||||||
|
// And add it:
|
||||||
|
int len = static_cast<int>(nodes.size());
|
||||||
|
nodes(json);
|
||||||
|
indexTab.insert(make_pair(this, len));
|
||||||
|
}
|
||||||
|
|
||||||
|
// -----------------------------------------------------------------------------
|
||||||
|
// --SECTION-- methods of InsertNode
|
||||||
|
// -----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
/// @brief toJson
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
void InsertNode::toJsonHelper (std::map<ExecutionNode*, int>& indexTab,
|
||||||
|
triagens::basics::Json& nodes,
|
||||||
|
TRI_memory_zone_t* zone) {
|
||||||
|
Json json(ExecutionNode::toJsonHelperGeneric(indexTab, nodes, zone)); // call base class method
|
||||||
|
|
||||||
|
if (json.isEmpty()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Now put info about vocbase and cid in there
|
||||||
|
json("database", Json(_vocbase->_name))
|
||||||
|
("collection", Json(_collname))
|
||||||
|
("outVariable", _outVariable->toJson());
|
||||||
|
|
||||||
|
// And add it:
|
||||||
|
int len = static_cast<int>(nodes.size());
|
||||||
|
nodes(json);
|
||||||
|
indexTab.insert(make_pair(this, len));
|
||||||
|
}
|
||||||
|
|
||||||
|
// -----------------------------------------------------------------------------
|
||||||
|
// --SECTION-- methods of UpdateNode
|
||||||
|
// -----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
/// @brief toJson
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
void UpdateNode::toJsonHelper (std::map<ExecutionNode*, int>& indexTab,
|
||||||
|
triagens::basics::Json& nodes,
|
||||||
|
TRI_memory_zone_t* zone) {
|
||||||
|
Json json(ExecutionNode::toJsonHelperGeneric(indexTab, nodes, zone)); // call base class method
|
||||||
|
|
||||||
|
if (json.isEmpty()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Now put info about vocbase and cid in there
|
||||||
|
json("database", Json(_vocbase->_name))
|
||||||
|
("collection", Json(_collname))
|
||||||
|
("outVariable", _outVariable->toJson());
|
||||||
|
|
||||||
|
// And add it:
|
||||||
|
int len = static_cast<int>(nodes.size());
|
||||||
|
nodes(json);
|
||||||
|
indexTab.insert(make_pair(this, len));
|
||||||
|
}
|
||||||
|
|
||||||
|
// -----------------------------------------------------------------------------
|
||||||
|
// --SECTION-- methods of ReplaceNode
|
||||||
|
// -----------------------------------------------------------------------------
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
/// @brief toJson
|
||||||
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
|
void ReplaceNode::toJsonHelper (std::map<ExecutionNode*, int>& indexTab,
|
||||||
|
triagens::basics::Json& nodes,
|
||||||
|
TRI_memory_zone_t* zone) {
|
||||||
|
Json json(ExecutionNode::toJsonHelperGeneric(indexTab, nodes, zone)); // call base class method
|
||||||
|
|
||||||
|
if (json.isEmpty()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Now put info about vocbase and cid in there
|
||||||
|
json("database", Json(_vocbase->_name))
|
||||||
|
("collection", Json(_collname))
|
||||||
|
("outVariable", _outVariable->toJson());
|
||||||
|
|
||||||
|
// And add it:
|
||||||
|
int len = static_cast<int>(nodes.size());
|
||||||
|
nodes(json);
|
||||||
|
indexTab.insert(make_pair(this, len));
|
||||||
|
}
|
||||||
|
|
||||||
// Local Variables:
|
// Local Variables:
|
||||||
// mode: outline-minor
|
// mode: outline-minor
|
||||||
// outline-regexp: "^\\(/// @brief\\|/// {@inheritDoc}\\|/// @addtogroup\\|// --SECTION--\\|/// @\\}\\)"
|
// outline-regexp: "^\\(/// @brief\\|/// {@inheritDoc}\\|/// @addtogroup\\|// --SECTION--\\|/// @\\}\\)"
|
||||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -84,7 +84,7 @@ ExecutionPlan* ExecutionPlan::instanciateFromAst (Ast const* ast) {
|
||||||
plan->_root = plan->fromNode(ast, root);
|
plan->_root = plan->fromNode(ast, root);
|
||||||
|
|
||||||
std::cout << plan->_root->toJson().toString() << "\n";
|
std::cout << plan->_root->toJson().toString() << "\n";
|
||||||
std::cout << "ESTIMATED COST = €" << plan->estimateCost() << "\n";
|
std::cout << "ESTIMATED COST = €" << plan->getCost() << "\n";
|
||||||
|
|
||||||
return plan;
|
return plan;
|
||||||
}
|
}
|
||||||
|
@ -480,11 +480,30 @@ ExecutionNode* ExecutionPlan::fromNodeRemove (Ast const* ast,
|
||||||
ExecutionNode* previous,
|
ExecutionNode* previous,
|
||||||
AstNode const* node) {
|
AstNode const* node) {
|
||||||
TRI_ASSERT(node != nullptr && node->type == NODE_TYPE_REMOVE);
|
TRI_ASSERT(node != nullptr && node->type == NODE_TYPE_REMOVE);
|
||||||
|
TRI_ASSERT(node->numMembers() == 2);
|
||||||
|
|
||||||
// TODO
|
auto collection = node->getMember(0);
|
||||||
THROW_ARANGO_EXCEPTION(TRI_ERROR_NOT_IMPLEMENTED);
|
auto expression = node->getMember(1);
|
||||||
|
|
||||||
return nullptr;
|
// collection, expression
|
||||||
|
char const* collectionName = collection->getStringValue();
|
||||||
|
ExecutionNode* en = nullptr;
|
||||||
|
|
||||||
|
if (expression->type == NODE_TYPE_REFERENCE) {
|
||||||
|
// operand is already a variable
|
||||||
|
auto v = static_cast<Variable*>(expression->getData());
|
||||||
|
TRI_ASSERT(v != nullptr);
|
||||||
|
en = addNode(new RemoveNode(ast->query()->vocbase(), std::string(collectionName), v));
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
// operand is some misc expression
|
||||||
|
auto calc = createTemporaryCalculation(ast, expression);
|
||||||
|
calc->addDependency(previous);
|
||||||
|
en = addNode(new RemoveNode(ast->query()->vocbase(), std::string(collectionName), calc->outVariable()));
|
||||||
|
previous = calc;
|
||||||
|
}
|
||||||
|
|
||||||
|
return addDependency(previous, en);
|
||||||
}
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
@ -495,11 +514,30 @@ ExecutionNode* ExecutionPlan::fromNodeInsert (Ast const* ast,
|
||||||
ExecutionNode* previous,
|
ExecutionNode* previous,
|
||||||
AstNode const* node) {
|
AstNode const* node) {
|
||||||
TRI_ASSERT(node != nullptr && node->type == NODE_TYPE_INSERT);
|
TRI_ASSERT(node != nullptr && node->type == NODE_TYPE_INSERT);
|
||||||
|
TRI_ASSERT(node->numMembers() == 2);
|
||||||
|
|
||||||
// TODO
|
auto collection = node->getMember(0);
|
||||||
THROW_ARANGO_EXCEPTION(TRI_ERROR_NOT_IMPLEMENTED);
|
auto expression = node->getMember(1);
|
||||||
|
|
||||||
return nullptr;
|
// collection, expression
|
||||||
|
char const* collectionName = collection->getStringValue();
|
||||||
|
ExecutionNode* en = nullptr;
|
||||||
|
|
||||||
|
if (expression->type == NODE_TYPE_REFERENCE) {
|
||||||
|
// operand is already a variable
|
||||||
|
auto v = static_cast<Variable*>(expression->getData());
|
||||||
|
TRI_ASSERT(v != nullptr);
|
||||||
|
en = addNode(new InsertNode(ast->query()->vocbase(), std::string(collectionName), v));
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
// operand is some misc expression
|
||||||
|
auto calc = createTemporaryCalculation(ast, expression);
|
||||||
|
calc->addDependency(previous);
|
||||||
|
en = addNode(new InsertNode(ast->query()->vocbase(), std::string(collectionName), calc->outVariable()));
|
||||||
|
previous = calc;
|
||||||
|
}
|
||||||
|
|
||||||
|
return addDependency(previous, en);
|
||||||
}
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
@ -510,11 +548,30 @@ ExecutionNode* ExecutionPlan::fromNodeUpdate (Ast const* ast,
|
||||||
ExecutionNode* previous,
|
ExecutionNode* previous,
|
||||||
AstNode const* node) {
|
AstNode const* node) {
|
||||||
TRI_ASSERT(node != nullptr && node->type == NODE_TYPE_UPDATE);
|
TRI_ASSERT(node != nullptr && node->type == NODE_TYPE_UPDATE);
|
||||||
|
TRI_ASSERT(node->numMembers() >= 2);
|
||||||
|
|
||||||
// TODO
|
auto collection = node->getMember(0);
|
||||||
THROW_ARANGO_EXCEPTION(TRI_ERROR_NOT_IMPLEMENTED);
|
auto expression = node->getMember(1);
|
||||||
|
|
||||||
return nullptr;
|
// collection, expression
|
||||||
|
char const* collectionName = collection->getStringValue();
|
||||||
|
ExecutionNode* en = nullptr;
|
||||||
|
|
||||||
|
if (expression->type == NODE_TYPE_REFERENCE) {
|
||||||
|
// operand is already a variable
|
||||||
|
auto v = static_cast<Variable*>(expression->getData());
|
||||||
|
TRI_ASSERT(v != nullptr);
|
||||||
|
en = addNode(new UpdateNode(ast->query()->vocbase(), std::string(collectionName), v));
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
// operand is some misc expression
|
||||||
|
auto calc = createTemporaryCalculation(ast, expression);
|
||||||
|
calc->addDependency(previous);
|
||||||
|
en = addNode(new UpdateNode(ast->query()->vocbase(), std::string(collectionName), calc->outVariable()));
|
||||||
|
previous = calc;
|
||||||
|
}
|
||||||
|
|
||||||
|
return addDependency(previous, en);
|
||||||
}
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
@ -525,11 +582,30 @@ ExecutionNode* ExecutionPlan::fromNodeReplace (Ast const* ast,
|
||||||
ExecutionNode* previous,
|
ExecutionNode* previous,
|
||||||
AstNode const* node) {
|
AstNode const* node) {
|
||||||
TRI_ASSERT(node != nullptr && node->type == NODE_TYPE_REPLACE);
|
TRI_ASSERT(node != nullptr && node->type == NODE_TYPE_REPLACE);
|
||||||
|
TRI_ASSERT(node->numMembers() >= 2);
|
||||||
|
|
||||||
// TODO
|
auto collection = node->getMember(0);
|
||||||
THROW_ARANGO_EXCEPTION(TRI_ERROR_NOT_IMPLEMENTED);
|
auto expression = node->getMember(1);
|
||||||
|
|
||||||
return nullptr;
|
// collection, expression
|
||||||
|
char const* collectionName = collection->getStringValue();
|
||||||
|
ExecutionNode* en = nullptr;
|
||||||
|
|
||||||
|
if (expression->type == NODE_TYPE_REFERENCE) {
|
||||||
|
// operand is already a variable
|
||||||
|
auto v = static_cast<Variable*>(expression->getData());
|
||||||
|
TRI_ASSERT(v != nullptr);
|
||||||
|
en = addNode(new ReplaceNode(ast->query()->vocbase(), std::string(collectionName), v));
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
// operand is some misc expression
|
||||||
|
auto calc = createTemporaryCalculation(ast, expression);
|
||||||
|
calc->addDependency(previous);
|
||||||
|
en = addNode(new ReplaceNode(ast->query()->vocbase(), std::string(collectionName), calc->outVariable()));
|
||||||
|
previous = calc;
|
||||||
|
}
|
||||||
|
|
||||||
|
return addDependency(previous, en);
|
||||||
}
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
|
@ -92,9 +92,9 @@ namespace triagens {
|
||||||
/// @brief get the estimated cost . . .
|
/// @brief get the estimated cost . . .
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
double estimateCost () const {
|
double getCost () const {
|
||||||
TRI_ASSERT(_root != nullptr);
|
TRI_ASSERT(_root != nullptr);
|
||||||
return _root->estimateCost();
|
return _root->getCost();
|
||||||
}
|
}
|
||||||
|
|
||||||
// -----------------------------------------------------------------------------
|
// -----------------------------------------------------------------------------
|
||||||
|
|
Loading…
Reference in New Issue