1
0
Fork 0

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

This commit is contained in:
James 2014-10-07 11:19:25 +01:00
commit e17a43f66e
14 changed files with 113 additions and 82 deletions

View File

@ -326,6 +326,13 @@ struct CoordinatorInstanciator : public WalkerWorker<ExecutionNode> {
auto* newPlan = new ExecutionPlan(otherQuery->ast());
otherQuery->setPlan(newPlan);
// clone all variables
for (auto it2 : query->ast()->variables()->variables(true)) {
auto var = query->ast()->variables()->getVariable(it2.first);
TRI_ASSERT(var != nullptr);
otherQuery->ast()->variables()->createVariable(var);
}
ExecutionNode const* current = (*it).nodes.front();
ExecutionNode* previous = nullptr;
@ -366,8 +373,7 @@ struct CoordinatorInstanciator : public WalkerWorker<ExecutionNode> {
// create a remote id for the engine that we can pass to
// the plans to be created for the DBServers
id = TRI_NewTickServer();
std::cout << "REGISTERING QUERY ON COORDINATOR WITH ID: " << id << "\n";
queryRegistry->insert(otherQuery->vocbase(), id, otherQuery, 3600.0);
}
}
@ -496,7 +502,7 @@ std::cout << "REGISTERING QUERY ON COORDINATOR WITH ID: " << id << "\n";
result.set("options", options);
std::unique_ptr<std::string> body(new std::string(triagens::basics::JsonHelper::toString(result.json())));
std::cout << "GENERATED A PLAN FOR THE REMOTE SERVERS: " << *(body.get()) << "\n";
// std::cout << "GENERATED A PLAN FOR THE REMOTE SERVERS: " << *(body.get()) << "\n";
// TODO: pass connectedId to the shard so it can fetch data using the correct query id
auto headers = new std::map<std::string, std::string>;
@ -538,18 +544,18 @@ std::cout << "REGISTERING QUERY ON COORDINATOR WITH ID: " << id << "\n";
triagens::basics::Json response(TRI_UNKNOWN_MEM_ZONE, triagens::basics::JsonHelper::fromString(res->answer->body()));
std::string queryId = triagens::basics::JsonHelper::getStringValue(response.json(), "queryId", "");
std::cout << "DB SERVER ANSWERED WITHOUT ERROR: " << res->answer->body() << ", SHARDID:" << res->shardID << ", QUERYID: " << queryId << "\n";
// std::cout << "DB SERVER ANSWERED WITHOUT ERROR: " << res->answer->body() << ", SHARDID:" << res->shardID << ", QUERYID: " << queryId << "\n";
queryIds.emplace(std::make_pair(res->shardID, queryId));
}
else {
std::cout << "DB SERVER ANSWERED WITH ERROR: " << res->answer->body() << "\n";
// std::cout << "DB SERVER ANSWERED WITH ERROR: " << res->answer->body() << "\n";
}
}
delete res;
}
std::cout << "GOT ALL RESPONSES FROM DB SERVERS: " << nrok << "\n";
// std::cout << "GOT ALL RESPONSES FROM DB SERVERS: " << nrok << "\n";
if (nrok != (int) shardIds.size()) {
// TODO: provide sensible error message with more details

View File

@ -339,7 +339,7 @@ triagens::basics::Json ExecutionNode::toJson (TRI_memory_zone_t* zone,
/// @brief execution Node clone utility to be called by derives
////////////////////////////////////////////////////////////////////////////////
void ExecutionNode::CloneHelper (ExecutionNode *other,
void ExecutionNode::CloneHelper (ExecutionNode* other,
ExecutionPlan* plan,
bool withDependencies,
bool withProperties) const {
@ -349,21 +349,31 @@ void ExecutionNode::CloneHelper (ExecutionNode *other,
other->_varUsageValid = _varUsageValid;
auto allVars = plan->getAst()->variables();
// Create new structures on the new AST...
other->_varsUsedLater.reserve(_varsUsedLater.size());
for (auto orgVar: _varsUsedLater) {
other->_varsUsedLater.insert(allVars->getVariable(orgVar->id));
auto var = allVars->getVariable(orgVar->id);
TRI_ASSERT(var != nullptr);
other->_varsUsedLater.insert(var);
}
other->_varsValid.reserve(_varsValid.size());
for (auto orgVar: _varsValid) {
other->_varsValid.insert(allVars->getVariable(orgVar->id));
auto var = allVars->getVariable(orgVar->id);
TRI_ASSERT(var != nullptr);
other->_varsValid.insert(var);
}
if (_varOverview.get() != nullptr) {
auto othervarOverview = std::shared_ptr<VarOverview>(_varOverview->clone(plan));
other->_varOverview = othervarOverview;
}
}
else {
// point to current AST -> don't do deep copies.
other->_varsUsedLater = _varsUsedLater;
other->_varsValid = _varsValid;
other->_varOverview = _varOverview;
}
if (withDependencies) {
cloneDependencies(plan, other, withProperties);
}
@ -702,15 +712,14 @@ void ExecutionNode::planRegisters (ExecutionNode* super) {
v.reset(new VarOverview(*(super->_varOverview), super->_depth));
}
v->setSharedPtr(&v);
// if (!_varUsageValid) {
walk(v.get());
walk(v.get());
// Now handle the subqueries:
for (auto s : v->subQueryNodes) {
auto sq = static_cast<SubqueryNode*>(s);
sq->getSubquery()->planRegisters(s);
}
v->reset();
// }
for (auto s : v->subQueryNodes) {
auto sq = static_cast<SubqueryNode*>(s);
sq->getSubquery()->planRegisters(s);
}
v->reset();
// Just for debugging:
/*
@ -1003,6 +1012,7 @@ ExecutionNode* EnumerateCollectionNode::clone (ExecutionPlan* plan,
auto outVariable = _outVariable;
if (withProperties) {
outVariable = plan->getAst()->variables()->createVariable(outVariable);
TRI_ASSERT(outVariable != nullptr);
}
auto c = new EnumerateCollectionNode(plan, _id, _vocbase, _collection, outVariable);

View File

@ -574,7 +574,7 @@ namespace triagens {
////////////////////////////////////////////////////////////////////////////////
VarOverview const* getVarOverview () const {
TRI_ASSERT(_varOverview != nullptr);
TRI_ASSERT(_varOverview.get() != nullptr);
return _varOverview.get();
}
@ -2955,7 +2955,7 @@ namespace triagens {
bool withProperties) const {
auto c = new ScatterNode(plan, _id, _vocbase, _collection);
CloneHelper (c, plan, withDependencies, withProperties);
CloneHelper(c, plan, withDependencies, withProperties);
return static_cast<ExecutionNode*>(c);
}

View File

@ -140,8 +140,8 @@ ExecutionPlan* ExecutionPlan::instanciateFromJson (Ast* ast,
}
}
ExecutionPlan* ExecutionPlan::clone (Query &onThatQuery) {
ExecutionPlan *OtherPlan = new ExecutionPlan(onThatQuery.ast());
ExecutionPlan* ExecutionPlan::clone (Query& onThatQuery) {
ExecutionPlan* OtherPlan = new ExecutionPlan(onThatQuery.ast());
for (auto it: _ids) {
OtherPlan->registerNode(it.second->clone(OtherPlan, false, true));
@ -985,7 +985,6 @@ void ExecutionPlan::checkLinkage () {
////////////////////////////////////////////////////////////////////////////////
struct VarUsageFinder : public WalkerWorker<ExecutionNode> {
std::unordered_set<Variable const*> _usedLater;
std::unordered_set<Variable const*> _valid;
std::unordered_map<VariableId, ExecutionNode*> _varSetBy;

View File

@ -242,6 +242,13 @@ Query* Query::clone (QueryPart part) {
if (_plan != nullptr) {
theClone->_plan = _plan->clone(*theClone);
// clone all variables
for (auto it : _ast->variables()->variables(true)) {
auto var = _ast->variables()->getVariable(it.first);
TRI_ASSERT(var != nullptr);
theClone->ast()->variables()->createVariable(var);
}
}
theClone->_trx = _trx;
@ -365,9 +372,6 @@ QueryResult Query::prepare (QueryRegistry* registry) {
std::shared_ptr<AQL_TRANSACTION_V8> trx(new AQL_TRANSACTION_V8(_vocbase, _collections.collections()));
_trx = trx;
// create the transaction object, but do not start it yet
// _trx = new std::shared_ptr<AQL_TRANSACTION_V8>(_vocbase, _collections.collections());
if (_queryString != nullptr) {
// we have an AST
int res = _trx->begin();
@ -527,35 +531,6 @@ QueryResult Query::execute (QueryRegistry* registry) {
}
}
////////////////////////////////////////////////////////////////////////////////
/// @brief close transaction to suspend query
////////////////////////////////////////////////////////////////////////////////
#if 0
int Query::closeTransaction () {
TRI_ASSERT(_trx != nullptr);
_trx->commit();
delete _trx;
_trx = nullptr;
return TRI_ERROR_NO_ERROR;
}
#endif
////////////////////////////////////////////////////////////////////////////////
/// @brief reopen transaction after suspend of query
////////////////////////////////////////////////////////////////////////////////
#if 0
int Query::reOpenTransaction () {
TRI_ASSERT(_trx == nullptr);
_trx = new AQL_TRANSACTION_V8(_vocbase, _collections.collections());
if (_trx == nullptr) {
return TRI_ERROR_INTERNAL;
}
return _trx->begin();
}
#endif
////////////////////////////////////////////////////////////////////////////////
/// @brief parse an AQL query
////////////////////////////////////////////////////////////////////////////////
@ -594,7 +569,7 @@ QueryResult Query::explain () {
// std::cout << "AST: " << triagens::basics::JsonHelper::toString(parser.ast()->toJson(TRI_UNKNOWN_MEM_ZONE)) << "\n";
// create the transaction object, but do not start it yet
std::shared_ptr<AQL_TRANSACTION_V8> trx(new AQL_TRANSACTION_V8(_vocbase, _collections.collections()));
std::shared_ptr<AQL_TRANSACTION_V8> trx(new AQL_TRANSACTION_V8(_vocbase, _collections.collections()));
_trx = trx;
// we have an AST
@ -631,6 +606,7 @@ QueryResult Query::explain () {
TRI_ASSERT(it != nullptr);
it->findVarUsage();
it->planRegisters();
out.add(it->toJson(parser.ast(), TRI_UNKNOWN_MEM_ZONE, verbosePlans()));
}
@ -641,6 +617,7 @@ QueryResult Query::explain () {
plan = opt.stealBest(); // Now we own the best one again
TRI_ASSERT(plan != nullptr);
plan->findVarUsage();
plan->planRegisters();
result.json = plan->toJson(parser.ast(), TRI_UNKNOWN_MEM_ZONE, verbosePlans()).steal();
delete plan;

View File

@ -406,18 +406,6 @@ namespace triagens {
void cleanupPlanAndEngine ();
////////////////////////////////////////////////////////////////////////////////
/// @brief close transaction to suspend query
////////////////////////////////////////////////////////////////////////////////
// int closeTransaction ();
////////////////////////////////////////////////////////////////////////////////
/// @brief reopen transaction after suspend of query
////////////////////////////////////////////////////////////////////////////////
// int reOpenTransaction ();
// -----------------------------------------------------------------------------
// --SECTION-- private variables
// -----------------------------------------------------------------------------

View File

@ -163,7 +163,7 @@ void RestAqlHandler::createQueryFromJson () {
answerBody("queryId", Json(StringUtils::itoa(_qId)))
("ttl", Json(ttl));
// std::cout << "RESPONSE BODY IS: " << answerBody.toString() << "\n";
//std::cout << "RESPONSE BODY IS: " << answerBody.toString() << "\n";
_response->body().appendText(answerBody.toString());
}
@ -588,6 +588,12 @@ triagens::rest::HttpHandler::status_t RestAqlHandler::execute () {
auto context = _applicationV8->enterContext("STANDARD", _vocbase,
false, false);
// assert that everything is cleaned up when we enter the context
TRI_v8_global_t* v8g = static_cast<TRI_v8_global_t*>(context->_isolate->GetData());
TRI_ASSERT(v8g->_currentTransaction == nullptr);
TRI_ASSERT(v8g->_resolver == nullptr);
if (nullptr == context) {
generateError(HttpResponse::SERVER_ERROR, TRI_ERROR_INTERNAL,
"cannot enter V8 context");
@ -661,9 +667,13 @@ triagens::rest::HttpHandler::status_t RestAqlHandler::execute () {
}
}
// must have cleaned everything up
TRI_ASSERT(v8g->_currentTransaction == nullptr);
TRI_ASSERT(v8g->_resolver == nullptr);
_applicationV8->exitContext(context);
// std::cout << "REQUEST HANDLING DONE: " << triagens::arango::ServerState::instance()->getId() << ": " << _request->fullUrl() << ": " << _response->responseCode() << ", CONTENT-LENGTH: " << _response->contentLength() << "\n";
//std::cout << "REQUEST HANDLING DONE: " << triagens::arango::ServerState::instance()->getId() << ": " << _request->fullUrl() << ": " << _response->responseCode() << ", CONTENT-LENGTH: " << _response->contentLength() << "\n";
return status_t(HANDLER_DONE);
}
@ -741,7 +751,7 @@ void RestAqlHandler::handleUseQuery (std::string const& operation,
else {
try {
answerBody = items->toJson(query->trx());
// std::cout << "ANSWERBODY: " << JsonHelper::toString(answerBody.json()) << "\n\n";
//std::cout << "ANSWERBODY: " << JsonHelper::toString(answerBody.json()) << "\n\n";
}
catch (...) {
generateError(HttpResponse::SERVER_ERROR, TRI_ERROR_HTTP_SERVER_ERROR,

View File

@ -222,9 +222,8 @@ triagens::basics::Json VariableGenerator::toJson (TRI_memory_zone_t* zone) const
////////////////////////////////////////////////////////////////////////////////
void VariableGenerator::fromJson (Json const& query) {
Json jsonAllVariablesList = query.get("variables");
if (!jsonAllVariablesList.isList()) {
if (! jsonAllVariablesList.isList()) {
THROW_ARANGO_EXCEPTION_MESSAGE(TRI_ERROR_INTERNAL, "variables needs to be a list");
}

View File

@ -166,6 +166,8 @@ namespace triagens {
////////////////////////////////////////////////////////////////////////////////
int registerTransactionWithContext () {
// modify the v8g globals to match the globals of the current isolate / thread
this->setV8Globals(static_cast<TRI_v8_global_t*>(v8::Isolate::GetCurrent()->GetData()));
// This calls the method in the V8TransactionContext
return this->registerTransaction(this->_trx);
}

View File

@ -77,6 +77,16 @@ namespace triagens {
public:
////////////////////////////////////////////////////////////////////////////////
/// @brief set the thread-specific pointer to the v8 globals
/// it is necessary to update this pointer if the same transaction is going to
/// be used in multiple requests / threads
////////////////////////////////////////////////////////////////////////////////
inline void setV8Globals (TRI_v8_global_t* v8g) {
_v8g = v8g;
}
////////////////////////////////////////////////////////////////////////////////
/// @brief return the resolver
////////////////////////////////////////////////////////////////////////////////

View File

@ -46,6 +46,8 @@ var API = "_api/simple/";
///
/// @RESTHEADER{PUT /_api/simple/by-example-hash, Hash index}
///
/// **Note**: This is only used internally and should not be accesible by the user.
///
/// @RESTBODYPARAM{query,string,required}
/// Contains the query specification.
///
@ -93,6 +95,8 @@ var API = "_api/simple/";
///
/// @RESTHEADER{PUT /_api/simple/by-example-skiplist, Skiplist index}
///
/// **Note**: This is only used internally and should not be accesible by the user.
///
/// @RESTBODYPARAM{query,string,required}
/// Contains the query specification.
///

View File

@ -5556,8 +5556,6 @@ function GRAPH_TRAVERSAL (vertexCollection,
/// `GRAPH_TRAVERSAL (graphName, startVertexExample, direction, options)`
///
/// This function performs traversals on the given graph.
/// For a more detailed documentation on the optional parameters see
/// [Traversals](../Traversals/README.md).
///
/// The complexity of this function strongly depends on the usage.
///
@ -5567,8 +5565,31 @@ function GRAPH_TRAVERSAL (vertexCollection,
/// vertices (see [example](#short_explanation_of_the_example_parameter)).
/// * *direction* : The direction of the edges as a string. Possible values
/// are *outbound*, *inbound* and *any* (default).
/// * *options* (optional) : Object containing optional options, see
/// [Traversals](../Traversals/README.md):
/// * *options*: Object containing optional options.
///
/// *Options*:
///
/// * *strategy*: determines the visitation strategy. Possible values are
/// *depthfirst* and *breadthfirst*. Default is *breadthfirst*.
/// * *order*: determines the visitation order. Possible values are
/// *preorder* and *postorder*.
/// * *itemOrder*: determines the order in which connections returned by the
/// expander will be processed. Possible values are *forward* and *backward*.
/// * *maxDepth*: if set to a value greater than *0*, this will limit the
/// traversal to this maximum depth.
/// * *minDepth*: if set to a value greater than *0*, all vertices found on
/// a level below the *minDepth* level will not be included in the result.
/// * *maxIterations*: the maximum number of iterations that the traversal is
/// allowed to perform. It is sensible to set this number so unbounded traversals
/// will terminate at some point.
/// * *uniqueness*: an object that defines how repeated visitations of vertices should
/// be handled. The *uniqueness* object can have a sub-attribute *vertices*, and a
/// sub-attribute *edges*. Each sub-attribute can have one of the following values:
/// * *"none"*: no uniqueness constraints
/// * *"path"*: element is excluded if it is already contained in the current path.
/// This setting may be sensible for graphs that contain cycles (e.g. A -> B -> C -> A).
/// * *"global"*: element is excluded if it was already found/visited at any
/// point during the traversal.
///
/// @EXAMPLES
///
@ -5746,8 +5767,6 @@ function GENERAL_GRAPH_DISTANCE_TO (graphName,
/// This function creates a tree format from the result for a better visualization of
/// the path.
/// This function performs traversals on the given graph.
/// For a more detailed documentation on the optional parameters see
/// [Traversals](../Traversals/README.md).
///
/// The complexity of this function strongly depends on the usage.
///
@ -5761,7 +5780,7 @@ function GENERAL_GRAPH_DISTANCE_TO (graphName,
/// * *connectName* : The result attribute which
/// contains the connection.
/// * *options* (optional) : An object containing options, see
/// [Traversals](../Traversals/README.md):
/// [Graph Traversals](../AQL/GraphOperations.html#graph_traversal):
///
/// @EXAMPLES
///

View File

@ -1114,6 +1114,8 @@ function unitTestPrettyPrintResults(r) {
var testrun;
var test;
var oneTest;
var testFail = 0;
var testSuiteFail = 0;
try {
for (testrun in r) {
@ -1125,6 +1127,7 @@ function unitTestPrettyPrintResults(r) {
print(" " + test + ": Success");
}
else {
testSuiteFail += 1;
if (r[testrun][test].hasOwnProperty('message')) {
print(" " + test + ": Fail - Whole testsuite failed!");
if (typeof r[testrun][test].message === "object" &&
@ -1141,6 +1144,7 @@ function unitTestPrettyPrintResults(r) {
if ((r[testrun][test].hasOwnProperty(oneTest)) &&
(internalMembers.indexOf(oneTest) === -1) &&
(!r[testrun][test][oneTest].status)) {
testFail =+ 1;
print(" -> " + oneTest + " Failed; Verbose message:");
print(r[testrun][test][oneTest].message);
}
@ -1152,6 +1156,9 @@ function unitTestPrettyPrintResults(r) {
}
}
print("Overall state: " + ((r.all_ok === true) ? "Success" : "Fail"));
if ((r.all_ok !== true) {
print(" Suites failed: " + testSuiteFail + " Tests Failed: " + testFail);
}
}
catch (x) {
print("exception caught while pretty printing result: ");

View File

@ -224,8 +224,8 @@ TRI_v8_global_s::~TRI_v8_global_s () {
/// @brief creates a global context
////////////////////////////////////////////////////////////////////////////////
TRI_v8_global_t* TRI_CreateV8Globals(v8::Isolate* isolate) {
TRI_v8_global_t* v8g = (TRI_v8_global_t*) isolate->GetData();
TRI_v8_global_t* TRI_CreateV8Globals (v8::Isolate* isolate) {
TRI_v8_global_t* v8g = static_cast<TRI_v8_global_t*>(isolate->GetData());
if (v8g == nullptr) {
v8g = new TRI_v8_global_t(isolate);