mirror of https://gitee.com/bigwinds/arangodb
Merge branch 'aql2' of https://github.com/triAGENS/ArangoDB into aql2
This commit is contained in:
commit
0b018d26cf
|
@ -442,7 +442,7 @@ void SingletonNode::toJsonHelper (triagens::basics::Json& nodes,
|
|||
EnumerateCollectionNode::EnumerateCollectionNode (Ast* ast, basics::Json const& base)
|
||||
: ExecutionNode(base),
|
||||
_vocbase(ast->query()->vocbase()),
|
||||
_collection(ast->query()->collections()->add(JsonHelper::checkAndGetStringValue(base.json(), "collection"), TRI_TRANSACTION_READ)),
|
||||
_collection(ast->query()->collections()->get(JsonHelper::checkAndGetStringValue(base.json(), "collection"))),
|
||||
_outVariable(varFromJson(ast, base, "outVariable")) {
|
||||
}
|
||||
|
||||
|
@ -660,8 +660,8 @@ void IndexRangeNode::toJsonHelper (triagens::basics::Json& nodes,
|
|||
IndexRangeNode::IndexRangeNode (Ast* ast, basics::Json const& json)
|
||||
: ExecutionNode(json),
|
||||
_vocbase(ast->query()->vocbase()),
|
||||
_collection(ast->query()->collections()->add(JsonHelper::checkAndGetStringValue(json.json(),
|
||||
"collection"), TRI_TRANSACTION_READ)),
|
||||
_collection(ast->query()->collections()->get(JsonHelper::checkAndGetStringValue(json.json(),
|
||||
"collection"))),
|
||||
_outVariable(varFromJson(ast, json, "outVariable")), _ranges() {
|
||||
|
||||
Json ranges(TRI_UNKNOWN_MEM_ZONE, JsonHelper::checkAndGetListValue(json.json(), "ranges"));
|
||||
|
@ -1215,7 +1215,7 @@ ModificationNode::ModificationNode (Ast* ast,
|
|||
basics::Json const& base)
|
||||
: ExecutionNode(base),
|
||||
_vocbase(ast->query()->vocbase()),
|
||||
_collection(ast->query()->collections()->add(JsonHelper::checkAndGetStringValue(base.json(), "collection"), TRI_TRANSACTION_WRITE)),
|
||||
_collection(ast->query()->collections()->get(JsonHelper::checkAndGetStringValue(base.json(), "collection"))),
|
||||
_options(base) {
|
||||
TRI_ASSERT(_vocbase != nullptr);
|
||||
TRI_ASSERT(_collection != nullptr);
|
||||
|
|
|
@ -101,6 +101,28 @@ ExecutionPlan* ExecutionPlan::instanciateFromAst (Ast* ast) {
|
|||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief create an execution plan from JSON
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
void ExecutionPlan::getCollectionsFromJson(Ast *ast,
|
||||
triagens::basics::Json const& json)
|
||||
{
|
||||
Json jsonCollectionList = json.get("collections");
|
||||
|
||||
auto const size = jsonCollectionList.size();
|
||||
|
||||
if (! jsonCollectionList.isList()) {
|
||||
THROW_ARANGO_EXCEPTION_MESSAGE(TRI_ERROR_INTERNAL, "json collections is not list");
|
||||
}
|
||||
|
||||
for (size_t i = 0; i < size; i++) {
|
||||
Json oneJsonCollection = jsonCollectionList.at(i);
|
||||
auto typeStr = JsonHelper::checkAndGetStringValue(oneJsonCollection.json(), "type");
|
||||
|
||||
ast->query()->collections()->add(
|
||||
JsonHelper::checkAndGetStringValue(oneJsonCollection.json(), "name"),
|
||||
TRI_GetTransactionTypeFromStr(JsonHelper::checkAndGetStringValue(oneJsonCollection.json(), "type").c_str()));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
ExecutionPlan* ExecutionPlan::instanciateFromJson (Ast* ast,
|
||||
triagens::basics::Json const& json) {
|
||||
|
@ -121,7 +143,8 @@ ExecutionPlan* ExecutionPlan::instanciateFromJson (Ast* ast,
|
|||
/// @brief export to JSON, returns an AUTOFREE Json object
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
triagens::basics::Json ExecutionPlan::toJson (TRI_memory_zone_t* zone,
|
||||
triagens::basics::Json ExecutionPlan::toJson (Ast* ast,
|
||||
TRI_memory_zone_t* zone,
|
||||
bool verbose) const {
|
||||
triagens::basics::Json result = _root->toJson(zone, verbose);
|
||||
|
||||
|
@ -133,6 +156,17 @@ triagens::basics::Json ExecutionPlan::toJson (TRI_memory_zone_t* zone,
|
|||
}
|
||||
result.set("rules", rules);
|
||||
|
||||
triagens::basics::Json jsonCollectionList(Json::List);
|
||||
auto usedCollections = *ast->query()->collections()->collections();
|
||||
|
||||
for (auto c : usedCollections) {
|
||||
Json json(Json::Array);
|
||||
|
||||
jsonCollectionList(json("name", Json(c.first))
|
||||
("type", Json(TRI_TransactionTypeGetStr(c.second->accessType))));
|
||||
|
||||
}
|
||||
result.set("collections", jsonCollectionList);
|
||||
return result;
|
||||
}
|
||||
|
||||
|
@ -1180,6 +1214,7 @@ ExecutionNode* ExecutionPlan::fromJson (Ast* ast,
|
|||
Json const& json) {
|
||||
ExecutionNode* ret = nullptr;
|
||||
Json nodes = json.get("nodes");
|
||||
std::cout << nodes.toString() << "\n";
|
||||
|
||||
if (! nodes.isList()) {
|
||||
THROW_ARANGO_EXCEPTION_MESSAGE(TRI_ERROR_INTERNAL, "nodes is not a list");
|
||||
|
|
|
@ -85,6 +85,9 @@ namespace triagens {
|
|||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief create an execution plan from JSON
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
static void getCollectionsFromJson(Ast *ast,
|
||||
triagens::basics::Json const& Json);
|
||||
|
||||
|
||||
static ExecutionPlan* instanciateFromJson (Ast* ast,
|
||||
triagens::basics::Json const& Json);
|
||||
|
@ -93,7 +96,8 @@ namespace triagens {
|
|||
/// @brief export to JSON, returns an AUTOFREE Json object
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
triagens::basics::Json toJson (TRI_memory_zone_t* zone,
|
||||
triagens::basics::Json toJson (Ast* ast,
|
||||
TRI_memory_zone_t* zone,
|
||||
bool verbose) const;
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
|
|
@ -200,6 +200,7 @@ void Query::registerError (int code,
|
|||
}
|
||||
}
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief execute an AQL query
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
@ -236,12 +237,7 @@ QueryResult Query::execute () {
|
|||
}
|
||||
}
|
||||
else {
|
||||
// we have an execution plan in JSON format
|
||||
plan = ExecutionPlan::instanciateFromJson(parser.ast(), _queryJson);
|
||||
if (plan == nullptr) {
|
||||
// oops
|
||||
return QueryResult(TRI_ERROR_INTERNAL);
|
||||
}
|
||||
ExecutionPlan::getCollectionsFromJson(parser.ast(), _queryJson);
|
||||
|
||||
// creating the plan may have produced some collections
|
||||
// we need to add them to the transaction now (otherwise the query will fail)
|
||||
|
@ -254,6 +250,14 @@ QueryResult Query::execute () {
|
|||
if (res != TRI_ERROR_NO_ERROR) {
|
||||
return transactionError(res, trx);
|
||||
}
|
||||
|
||||
// we have an execution plan in JSON format
|
||||
plan = ExecutionPlan::instanciateFromJson(parser.ast(), _queryJson);
|
||||
if (plan == nullptr) {
|
||||
// oops
|
||||
return QueryResult(TRI_ERROR_INTERNAL);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// get enabled/disabled rules
|
||||
|
@ -405,7 +409,7 @@ QueryResult Query::explain () {
|
|||
for (auto it : plans) {
|
||||
TRI_ASSERT(it != nullptr);
|
||||
|
||||
out.add(it->toJson(TRI_UNKNOWN_MEM_ZONE, verbosePlans()));
|
||||
out.add(it->toJson(parser.ast(), TRI_UNKNOWN_MEM_ZONE, verbosePlans()));
|
||||
}
|
||||
|
||||
result.json = out.steal();
|
||||
|
@ -415,7 +419,7 @@ QueryResult Query::explain () {
|
|||
plan = opt.stealBest(); // Now we own the best one again
|
||||
TRI_ASSERT(plan != nullptr);
|
||||
|
||||
result.json = plan->toJson(TRI_UNKNOWN_MEM_ZONE, verbosePlans()).steal();
|
||||
result.json = plan->toJson(parser.ast(), TRI_UNKNOWN_MEM_ZONE, verbosePlans()).steal();
|
||||
|
||||
delete plan;
|
||||
}
|
||||
|
|
|
@ -64,6 +64,19 @@
|
|||
/// @brief whether or not a transaction consists of a single operation
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
TRI_transaction_type_e TRI_GetTransactionTypeFromStr(const char* s) {
|
||||
if (!strcmp(s, "read")) {
|
||||
return TRI_TRANSACTION_READ;
|
||||
}
|
||||
else if (!strcmp(s, "write")) {
|
||||
return TRI_TRANSACTION_WRITE;
|
||||
}
|
||||
else {
|
||||
THROW_ARANGO_EXCEPTION_MESSAGE(TRI_ERROR_INTERNAL, "invalid transaction type");
|
||||
}
|
||||
}
|
||||
|
||||
static triagens::wal::LogfileManager* GetLogfileManager () {
|
||||
return triagens::wal::LogfileManager::instance();
|
||||
}
|
||||
|
|
|
@ -177,6 +177,17 @@ TRI_transaction_collection_t;
|
|||
// -----------------------------------------------------------------------------
|
||||
// --SECTION-- constructors / destructors
|
||||
// -----------------------------------------------------------------------------
|
||||
inline const char* TRI_TransactionTypeGetStr(TRI_transaction_type_e t) {
|
||||
switch (t) {
|
||||
case TRI_TRANSACTION_READ:
|
||||
return "read";
|
||||
case TRI_TRANSACTION_WRITE:
|
||||
return "write";
|
||||
}
|
||||
return "";
|
||||
}
|
||||
|
||||
TRI_transaction_type_e TRI_GetTransactionTypeFromStr(const char* s);
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief create a new transaction
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*jslint indent: 2, nomen: true, maxlen: 200, sloppy: true, vars: true, white: true, plusplus: true */
|
||||
/*global require, exports, assertTrue, assertEqual, AQL_EXECUTE, AQL_EXPLAIN, fail, loopmax */
|
||||
/*global require, exports, assertTrue, assertEqual, AQL_EXECUTE, AQL_EXECUTEJSON, AQL_EXPLAIN, fail, loopmax */
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief tests for optimizer rules
|
||||
|
@ -37,6 +37,35 @@ var assertQueryError = helper.assertQueryError2;
|
|||
var isEqual = helper.isEqual;
|
||||
var findExecutionNodes = helper.findExecutionNodes;
|
||||
var findReferencedNodes = helper.findReferencedNodes;
|
||||
//var getQueryMultiplePlansAndExecutions = helper.getQueryMultiplePlansAndExecutions;
|
||||
|
||||
function getQueryMultiplePlansAndExecutions (query, bindVars) {
|
||||
var plan;
|
||||
var i;
|
||||
var plans = [];
|
||||
var allPlans = [];
|
||||
var results = [];
|
||||
var paramNone = { optimizer: { rules: [ "-all" ]}, verbosePlans: true};
|
||||
var paramAllPlans = { allPlans : true, verbosePlans: true};
|
||||
PY(query);
|
||||
// first fetch the unmodified version
|
||||
plans [0] = AQL_EXPLAIN(query, bindVars, paramNone);
|
||||
// then all of the ones permuted by by the optimizer.
|
||||
allPlans = AQL_EXPLAIN(query, bindVars, paramAllPlans);
|
||||
|
||||
PY(allPlans.plans[0]);
|
||||
|
||||
for (i=0; i < allPlans.plans.length; i++) {
|
||||
plans[i+1] = {'plan':allPlans.plans[i]};
|
||||
}
|
||||
// Now execute each of these variations.
|
||||
for (i=0; i < plans.length; i++) {
|
||||
PY(plans[i]);
|
||||
results += AQL_EXECUTEJSON(plans[i].plan, {});
|
||||
}
|
||||
|
||||
return {'plans': plans, 'results': results};
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief test suite
|
||||
|
@ -223,7 +252,7 @@ function optimizerRuleTestSuite() {
|
|||
/// @brief test that rule has an effect
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
testRuleHasEffect : function () {
|
||||
|
||||
var allresults;
|
||||
var queries = [
|
||||
|
||||
"FOR v IN " + colName + " SORT v.d DESC RETURN [v.d]",// currently only ASC supported, but we use the index range anyways. todo: this may change.
|
||||
|
@ -242,11 +271,14 @@ function optimizerRuleTestSuite() {
|
|||
QResults[1] = AQL_EXECUTE(query, { }, paramIndexFromSort ).json;
|
||||
|
||||
assertTrue(isEqual(QResults[0], QResults[1]), "Result " + i + " is Equal?");
|
||||
|
||||
allresults = getQueryMultiplePlansAndExecutions(query, {});
|
||||
PY(allresults);
|
||||
i++;
|
||||
});
|
||||
|
||||
},
|
||||
|
||||
/*
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief test that rule has an effect, but the sort is kept in place since
|
||||
|
@ -768,7 +800,7 @@ function optimizerRuleTestSuite() {
|
|||
// assertTrue(isEqual(QResults[0], QResults[1]), "Results are Equal?");
|
||||
|
||||
}
|
||||
|
||||
*/
|
||||
};
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue