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(expression);
|
||||
|
||||
// TODO: handle options
|
||||
return node;
|
||||
}
|
||||
|
||||
|
@ -200,6 +201,7 @@ AstNode* Ast::createNodeInsert (AstNode const* expression,
|
|||
node->addMember(collection);
|
||||
node->addMember(expression);
|
||||
|
||||
// TODO: handle options
|
||||
return node;
|
||||
}
|
||||
|
||||
|
@ -218,6 +220,7 @@ AstNode* Ast::createNodeUpdate (AstNode const* keyExpression,
|
|||
if (keyExpression != nullptr) {
|
||||
node->addMember(keyExpression);
|
||||
}
|
||||
// TODO: handle options
|
||||
|
||||
return node;
|
||||
}
|
||||
|
@ -237,6 +240,7 @@ AstNode* Ast::createNodeReplace (AstNode const* keyExpression,
|
|||
if (keyExpression != nullptr) {
|
||||
node->addMember(keyExpression);
|
||||
}
|
||||
// TODO: handle options
|
||||
|
||||
return node;
|
||||
}
|
||||
|
|
|
@ -276,8 +276,8 @@ bool AstNode::isSimple () const {
|
|||
}
|
||||
|
||||
if (type == NODE_TYPE_ARRAY_ELEMENT) {
|
||||
auto member = getMember(0);
|
||||
return member->isSimple();
|
||||
auto member = getMember(0);
|
||||
return member->isSimple();
|
||||
}
|
||||
|
||||
return false;
|
||||
|
|
|
@ -330,16 +330,6 @@ namespace triagens {
|
|||
totalNrRegs++;
|
||||
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: {
|
||||
nrRegsHere[depth]++;
|
||||
nrRegs[depth]++;
|
||||
|
|
|
@ -30,6 +30,7 @@
|
|||
#include "Aql/ExecutionEngine.h"
|
||||
#include "Aql/ExecutionBlock.h"
|
||||
#include "Aql/ExecutionNode.h"
|
||||
#include "Aql/ExecutionPlan.h"
|
||||
#include "Aql/WalkerWorker.h"
|
||||
#include "Utils/Exception.h"
|
||||
|
||||
|
|
|
@ -32,10 +32,49 @@
|
|||
using namespace triagens::basics;
|
||||
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
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @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
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
@ -45,9 +84,9 @@ Json ExecutionNode::toJson (TRI_memory_zone_t* zone) {
|
|||
Json json;
|
||||
Json nodes;
|
||||
try {
|
||||
nodes = Json(Json::List,10);
|
||||
nodes = Json(Json::List, 10);
|
||||
toJsonHelper(indexTab, nodes, zone);
|
||||
json = Json(Json::Array,1)
|
||||
json = Json(Json::Array, 1)
|
||||
("nodes", nodes);
|
||||
}
|
||||
catch (std::exception& e) {
|
||||
|
@ -71,8 +110,8 @@ void ExecutionNode::appendAsString (std::string& st, int indent) {
|
|||
if (_dependencies.size() != 0) {
|
||||
st.push_back('\n');
|
||||
for (size_t i = 0; i < _dependencies.size(); i++) {
|
||||
_dependencies[i]->appendAsString(st, indent+2);
|
||||
if (i != _dependencies.size()-1) {
|
||||
_dependencies[i]->appendAsString(st, indent + 2);
|
||||
if (i != _dependencies.size() - 1) {
|
||||
st.push_back(',');
|
||||
}
|
||||
else {
|
||||
|
@ -131,7 +170,7 @@ Json ExecutionNode::toJsonHelperGeneric (std::map<ExecutionNode*, int>& indexTab
|
|||
_dependencies[i]->toJsonHelper(indexTab, nodes, zone);
|
||||
}
|
||||
Json json;
|
||||
json = Json(Json::Array,2)
|
||||
json = Json(Json::Array, 2)
|
||||
("type", Json(getTypeString()));
|
||||
Json deps(Json::List, _dependencies.size());
|
||||
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));
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
// --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
|
||||
// -----------------------------------------------------------------------------
|
||||
|
@ -442,6 +451,118 @@ void ReturnNode::toJsonHelper (std::map<ExecutionNode*, int>& indexTab,
|
|||
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:
|
||||
// mode: outline-minor
|
||||
// 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);
|
||||
|
||||
std::cout << plan->_root->toJson().toString() << "\n";
|
||||
std::cout << "ESTIMATED COST = €" << plan->estimateCost() << "\n";
|
||||
std::cout << "ESTIMATED COST = €" << plan->getCost() << "\n";
|
||||
|
||||
return plan;
|
||||
}
|
||||
|
@ -480,11 +480,30 @@ ExecutionNode* ExecutionPlan::fromNodeRemove (Ast const* ast,
|
|||
ExecutionNode* previous,
|
||||
AstNode const* node) {
|
||||
TRI_ASSERT(node != nullptr && node->type == NODE_TYPE_REMOVE);
|
||||
TRI_ASSERT(node->numMembers() == 2);
|
||||
|
||||
auto collection = node->getMember(0);
|
||||
auto expression = node->getMember(1);
|
||||
|
||||
// TODO
|
||||
THROW_ARANGO_EXCEPTION(TRI_ERROR_NOT_IMPLEMENTED);
|
||||
// collection, expression
|
||||
char const* collectionName = collection->getStringValue();
|
||||
ExecutionNode* en = nullptr;
|
||||
|
||||
return 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,
|
||||
AstNode const* node) {
|
||||
TRI_ASSERT(node != nullptr && node->type == NODE_TYPE_INSERT);
|
||||
TRI_ASSERT(node->numMembers() == 2);
|
||||
|
||||
auto collection = node->getMember(0);
|
||||
auto expression = node->getMember(1);
|
||||
|
||||
// TODO
|
||||
THROW_ARANGO_EXCEPTION(TRI_ERROR_NOT_IMPLEMENTED);
|
||||
// collection, expression
|
||||
char const* collectionName = collection->getStringValue();
|
||||
ExecutionNode* en = nullptr;
|
||||
|
||||
return 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,
|
||||
AstNode const* node) {
|
||||
TRI_ASSERT(node != nullptr && node->type == NODE_TYPE_UPDATE);
|
||||
TRI_ASSERT(node->numMembers() >= 2);
|
||||
|
||||
auto collection = node->getMember(0);
|
||||
auto expression = node->getMember(1);
|
||||
|
||||
// TODO
|
||||
THROW_ARANGO_EXCEPTION(TRI_ERROR_NOT_IMPLEMENTED);
|
||||
// collection, expression
|
||||
char const* collectionName = collection->getStringValue();
|
||||
ExecutionNode* en = nullptr;
|
||||
|
||||
return 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,
|
||||
AstNode const* node) {
|
||||
TRI_ASSERT(node != nullptr && node->type == NODE_TYPE_REPLACE);
|
||||
TRI_ASSERT(node->numMembers() >= 2);
|
||||
|
||||
auto collection = node->getMember(0);
|
||||
auto expression = node->getMember(1);
|
||||
|
||||
// TODO
|
||||
THROW_ARANGO_EXCEPTION(TRI_ERROR_NOT_IMPLEMENTED);
|
||||
// collection, expression
|
||||
char const* collectionName = collection->getStringValue();
|
||||
ExecutionNode* en = nullptr;
|
||||
|
||||
return 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 . . .
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
double estimateCost () const {
|
||||
double getCost () const {
|
||||
TRI_ASSERT(_root != nullptr);
|
||||
return _root->estimateCost();
|
||||
return _root->getCost();
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
|
|
Loading…
Reference in New Issue