1
0
Fork 0

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

This commit is contained in:
Max Neunhoeffer 2014-09-12 15:01:58 +02:00
commit d147be8de3
7 changed files with 168 additions and 32 deletions

View File

@ -119,6 +119,7 @@ AqlValue Expression::execute (AQL_TRANSACTION_V8* trx,
std::vector<Variable*> const& vars,
std::vector<RegisterId> const& regs) {
AqlValue ret;
TRI_ASSERT(_type != UNPROCESSED);
// and execute
@ -130,7 +131,19 @@ AqlValue Expression::execute (AQL_TRANSACTION_V8* trx,
case V8: {
TRI_ASSERT(_func != nullptr);
return _func->execute(trx, docColls, argv, startPos, vars, regs);
try {
ret = _func->execute(trx, docColls, argv, startPos, vars, regs);
}
catch (triagens::arango::Exception ex) {
ex.addToMessage("\nwhile evaluating Expression \n");
#ifdef TRI_ENABLE_MAINTAINER_MODE
ex.addToMessage(toJson(TRI_UNKNOWN_MEM_ZONE, true).toString());
ex.addToMessage("\n");
#endif
throw ex;
}
return ret;
}
case SIMPLE: {

View File

@ -79,7 +79,8 @@ Query::Query (TRI_vocbase_t* vocbase,
Query::Query (TRI_vocbase_t* vocbase,
triagens::basics::Json queryStruct,
QueryType Type)
QueryType Type,
TRI_json_t* options)
: _vocbase(vocbase),
_executor(nullptr),
_queryString(nullptr),
@ -87,7 +88,7 @@ Query::Query (TRI_vocbase_t* vocbase,
_queryJson(queryStruct),
_type(Type),
_bindParameters(nullptr),
_options(nullptr),
_options(options),
_collections(vocbase),
_strings(),
_ast(nullptr) {
@ -276,7 +277,7 @@ QueryResult Query::execute () {
plan = opt.stealBest(); // Now we own the best one again
TRI_ASSERT(plan != nullptr);
/* // for debugging of serialisation/deserialisation . . .
auto JsonPlan = plan->toJson(TRI_UNKNOWN_MEM_ZONE, true);
auto JsonPlan = plan->toJson(parser.ast(),TRI_UNKNOWN_MEM_ZONE, true);
auto JsonString = JsonPlan.toString();
std::cout << "original plan: \n" << JsonString << "\n";

View File

@ -90,7 +90,8 @@ namespace triagens {
Query (struct TRI_vocbase_s*,
triagens::basics::Json queryStruct,
QueryType Type);
QueryType Type,
struct TRI_json_s*);
~Query ();

View File

@ -98,6 +98,10 @@ namespace triagens {
int code () const throw () {
return _code;
}
void addToMessage(std::string More) {
_errorMessage += More;
}
static std::string FillExceptionString (int, ...);

View File

@ -959,6 +959,7 @@ static v8::Handle<v8::Value> JS_ExecuteAqlJson (v8::Arguments const& argv) {
TRI_V8_TYPE_ERROR(scope, "expecting object for <queryjson>");
}
TRI_json_t* queryjson = TRI_ObjectToJson(argv[0]);
TRI_json_t* options = nullptr;
if (argv.Length() > 1) {
// we have options! yikes!
@ -992,9 +993,10 @@ static v8::Handle<v8::Value> JS_ExecuteAqlJson (v8::Arguments const& argv) {
if (argValue->Has(optionName)) {
extra = TRI_ObjectToJson(argValue->Get(optionName));
}
options = TRI_ObjectToJson(argv[1]);
}
triagens::aql::Query query(vocbase, Json(TRI_UNKNOWN_MEM_ZONE, queryjson), triagens::aql::AQL_QUERY_READ);
triagens::aql::Query query(vocbase, Json(TRI_UNKNOWN_MEM_ZONE, queryjson), triagens::aql::AQL_QUERY_READ, options);
auto queryResult = query.execute();

View File

@ -31,6 +31,7 @@
var internal = require("internal");
var arangodb = require("org/arangodb");
var ShapedJson = internal.ShapedJson;
var printYaml = function (plan) { require("internal").print(require("js-yaml").safeDump(plan));};
// -----------------------------------------------------------------------------
// --SECTION-- AQL test helper functions
@ -475,7 +476,7 @@ function findReferencedNodes(plan, testNode) {
return matches;
}
function getQueryMultiplePlansAndExecutions (query, bindVars) {
function getQueryMultiplePlansAndExecutions (query, bindVars, debug) {
var plan;
var i;
var plans = [];
@ -484,19 +485,43 @@ function getQueryMultiplePlansAndExecutions (query, bindVars) {
var paramNone = { optimizer: { rules: [ "-all" ]}, verbosePlans: true};
var paramAllPlans = { allPlans : true, verbosePlans: true};
if (debug === undefined)
debug = false;
// first fetch the unmodified version
if (debug) {
require("internal").print("Analysing Query unoptimized: " + query);
}
plans [0] = AQL_EXPLAIN(query, bindVars, paramNone);
// then all of the ones permuted by by the optimizer.
if (debug) {
require("internal").print("Unoptimized Plan (0):");
printYaml(plans [0]);
}
allPlans = AQL_EXPLAIN(query, bindVars, paramAllPlans);
for (i=0; i < allPlans.plans.length; i++) {
if (debug) {
require("internal").print("Optimized Plan ["+(i+1)+"]:");
printYaml(allPlans.plans [i]);
}
plans[i+1] = {'plan':allPlans.plans[i]};
}
// Now execute each of these variations.
for (i=0; i < plans.length; i++) {
results += AQL_EXECUTEJSON(plans[i].plan, paramNone);
if (debug) {
require("internal").print("Executing Plan No: " + i + "\n");
}
results[i] = AQL_EXECUTEJSON(plans[i].plan, paramNone);
if (debug) {
require("internal").print("\nDONE\n");
}
}
if (debug) {
require("internal").print("done\n");
}
return {'plans': plans, 'results': results};
}

View File

@ -26,12 +26,9 @@
/// @author Jan Steemann
/// @author Copyright 2012, triAGENS GmbH, Cologne, Germany
////////////////////////////////////////////////////////////////////////////////
var PY = function (plan) { require("internal").print(require("js-yaml").safeDump(plan));};
var internal = require("internal");
var jsunity = require("jsunity");
var helper = require("org/arangodb/aql-helper");
// var getQueryResults = helper.getQueryResults2;
// TODO! var assertQueryError = helper.assertQueryError2;
var isEqual = helper.isEqual;
var findExecutionNodes = helper.findExecutionNodes;
var findReferencedNodes = helper.findReferencedNodes;
@ -192,27 +189,37 @@ function optimizerRuleTestSuite() {
/// @brief test that rule has no effect
////////////////////////////////////////////////////////////////////////////////
testRuleNoEffect : function () {
var queries = [
"FOR v IN " + colName + " SORT v.c RETURN [v.a, v.b]",
["FOR v IN " + colName + " SORT v.c RETURN [v.a, v.b]",true],
// todo: we use an index anyways right now.
// currently only ASC supported.
// "FOR v IN " + colName + " SORT v.a DESC RETURN [v.a, v.b]",
"FOR v IN " + colName + " SORT v.b, v.a RETURN [v.a, v.b]",
"FOR v IN " + colName + " SORT v.c RETURN [v.a, v.b]",
"FOR v IN " + colName + " SORT v.a + 1 RETURN [v.a, v.b]",
"FOR v IN " + colName + " SORT CONCAT(TO_STRING(v.a), \"lol\") RETURN [v.a, v.b]",
// "FOR v IN " + colName + " SORT v.a DESC RETURN [v.a, v.b]",true],
["FOR v IN " + colName + " SORT v.b, v.a RETURN [v.a, v.b]",true],
["FOR v IN " + colName + " SORT v.c RETURN [v.a, v.b]",true],
["FOR v IN " + colName + " SORT v.a + 1 RETURN [v.a, v.b]",false],// this will throw...
["FOR v IN " + colName + " SORT CONCAT(TO_STRING(v.a), \"lol\") RETURN [v.a, v.b]",true],
// TODO: limit blocks sort atm.
"FOR v IN " + colName + " FILTER v.a > 2 LIMIT 3 SORT v.a RETURN [v.a, v.b] ",
"FOR v IN " + colName + " FOR w IN " + colNameOther + " SORT v.a RETURN [v.a, v.b]"
["FOR v IN " + colName + " FILTER v.a > 2 LIMIT 3 SORT v.a RETURN [v.a, v.b] ",true],
["FOR v IN " + colName + " FOR w IN " + colNameOther + " SORT v.a RETURN [v.a, v.b]",true]
];
queries.forEach(function(query) {
var result = AQL_EXPLAIN(query, { }, paramIndexFromSort);
var result = AQL_EXPLAIN(query[0], { }, paramIndexFromSort);
assertEqual([], result.plan.rules, query);
if (query[1]) {
allresults = getQueryMultiplePlansAndExecutions(query[0], {});
for (j = 1; j <= allresults.length; j++) {
AssertTrue(isEqual(allresults.results[0],
allresults.results[j]),
"whether the execution of this plan gave the right results: " +
allresults.plans[j]);
}
}
});
},
@ -227,15 +234,17 @@ function optimizerRuleTestSuite() {
// currently only ASC supported, but we use the index range anyways.
// todo: this may change.
"FOR v IN " + colName + " SORT v.d DESC RETURN [v.d]",
"FOR v IN " + colName + " SORT v.d FILTER v.a > 2 LIMIT 3 RETURN [v.d] ",
"FOR v IN " + colName + " FOR w IN 1..10 SORT v.d RETURN [v.d]",
"FOR v IN " + colName + " LET x = (FOR w IN " + colNameOther + " RETURN w.f ) SORT v.a RETURN [v.a]"
];
var QResults = [];
var i = 0;
queries.forEach(function(query) {
var j;
var result = AQL_EXPLAIN(query, { }, paramIndexFromSort);
assertEqual([ ruleName ], result.plan.rules, query);
QResults[0] = AQL_EXECUTE(query, { }, paramNone).json;
@ -244,6 +253,14 @@ function optimizerRuleTestSuite() {
assertTrue(isEqual(QResults[0], QResults[1]), "Result " + i + " is Equal?");
allresults = getQueryMultiplePlansAndExecutions(query, {});
AQL_EXECUTEJSON(allresults.plans[0].plan, paramNone);
for (j = 1; j <= allresults.length; j++) {
AssertTrue(isEqual(allresults.results[0],
allresults.results[j]),
"whether the execution of this plan gave the right results: " +
allresults.plans[j]);
}
i++;
});
@ -263,7 +280,7 @@ function optimizerRuleTestSuite() {
var QResults = [];
var i = 0;
queries.forEach(function(query) {
var j;
var result = AQL_EXPLAIN(query, { }, paramIndexFromSort);
assertEqual([ ruleName ], result.plan.rules);
hasIndexRangeNode_WithRanges(result, false);
@ -271,6 +288,14 @@ function optimizerRuleTestSuite() {
QResults[0] = AQL_EXECUTE(query, { }, paramNone).json;
QResults[1] = AQL_EXECUTE(query, { }, paramIndexFromSort ).json;
assertTrue(isEqual(QResults[0], QResults[1]), "Result " + i + " is Equal?");
allresults = getQueryMultiplePlansAndExecutions(query, {});
for (j = 1; j <= allresults.length; j++) {
AssertTrue(isEqual(allresults.results[0],
allresults.results[j]),
"whether the execution of this plan gave the right results: " +
allresults.plans[j]);
}
i++;
});
@ -291,7 +316,7 @@ function optimizerRuleTestSuite() {
var XPresult;
var QResults=[];
var i;
var i, j;
// we have to re-sort here, because of the index has one more sort criteria.
QResults[0] = AQL_EXECUTE(query, { }, paramNone).json.sort(sortArray);
@ -323,7 +348,13 @@ function optimizerRuleTestSuite() {
for (i = 1; i < 3; i++) {
assertTrue(isEqual(QResults[0], QResults[i]), "Result " + i + " is Equal?");
}
allresults = getQueryMultiplePlansAndExecutions(query, {});
for (j = 1; j <= allresults.length; j++) {
AssertTrue(isEqual(allresults.results[0],
allresults.results[j]),
"whether the execution of this plan gave the right results: " +
allresults.plans[j]);
}
},
@ -387,6 +418,13 @@ function optimizerRuleTestSuite() {
for (i = 1; i < 4; i++) {
assertTrue(isEqual(QResults[0], QResults[i]), "Result " + i + " is Equal?");
}
allresults = getQueryMultiplePlansAndExecutions(query, {});
for (j = 1; j <= allresults.length; j++) {
AssertTrue(isEqual(allresults.results[0],
allresults.results[j]),
"whether the execution of this plan gave the right results: " +
allresults.plans[j]);
}
},
////////////////////////////////////////////////////////////////////////////////
@ -399,7 +437,7 @@ function optimizerRuleTestSuite() {
var XPresult;
var QResults=[];
var i;
var i, j;
// the index we will compare to sorts by a & b, so we need to
// re-sort the result here to accomplish similarity.
@ -456,7 +494,13 @@ function optimizerRuleTestSuite() {
for (i = 1; i < 5; i++) {
assertTrue(isEqual(QResults[0], QResults[i]), "Result " + i + " is Equal?");
}
allresults = getQueryMultiplePlansAndExecutions(query, {});
for (j = 1; j <= allresults.length; j++) {
AssertTrue(isEqual(allresults.results[0],
allresults.results[j]),
"whether the execution of this plan gave the right results: " +
allresults.plans[j]);
}
},
////////////////////////////////////////////////////////////////////////////////
@ -468,7 +512,7 @@ function optimizerRuleTestSuite() {
var query = "FOR v IN " + colName + " FILTER v.a == 1 SORT v.a, v.b RETURN [v.a, v.b, v.c]";
var XPresult;
var QResults=[];
var i;
var i, j;
// the index we will compare to sorts by a & b, so we need to
// re-sort the result here to accomplish similarity.
@ -528,6 +572,13 @@ function optimizerRuleTestSuite() {
for (i = 1; i < 5; i++) {
assertTrue(isEqual(QResults[0], QResults[i]), "Result " + i + " is Equal?");
}
allresults = getQueryMultiplePlansAndExecutions(query, {});
for (j = 1; j <= allresults.length; j++) {
AssertTrue(isEqual(allresults.results[0],
allresults.results[j]),
"whether the execution of this plan gave the right results: " +
allresults.plans[j]);
}
},
@ -545,7 +596,7 @@ function optimizerRuleTestSuite() {
var XPresult;
var QResults=[];
var i;
var i, j;
// the index we will compare to sorts by a & b, so we need to
// re-sort the result here to accomplish similarity.
@ -569,7 +620,13 @@ function optimizerRuleTestSuite() {
for (i = 1; i < 2; i++) {
assertTrue(isEqual(QResults[0].sort(sortArray), QResults[i]), "Result " + i + " is Equal?");
}
allresults = getQueryMultiplePlansAndExecutions(query, {});
for (j = 1; j <= allresults.length; j++) {
AssertTrue(isEqual(allresults.results[0],
allresults.results[j]),
"whether the execution of this plan gave the right results: " +
allresults.plans[j]);
}
},
@ -581,6 +638,7 @@ function optimizerRuleTestSuite() {
var XPresult;
var QResults=[];
var j;
// the index we will compare to sorts by a & b, so we need to
// re-sort the result here to accomplish similarity.
@ -603,6 +661,14 @@ function optimizerRuleTestSuite() {
assertEqual(first.highConst.bound, 5, "proper value was set");
assertTrue(isEqual(QResults[0], QResults[1]), "Results are Equal?");
allresults = getQueryMultiplePlansAndExecutions(query, {});
for (j = 1; j <= allresults.length; j++) {
AssertTrue(isEqual(allresults.results[0],
allresults.results[j]),
"whether the execution of this plan gave the right results: " +
allresults.plans[j]);
}
},
////////////////////////////////////////////////////////////////////////////////
@ -612,6 +678,7 @@ function optimizerRuleTestSuite() {
var query = "FOR v IN " + colName + " FILTER v.a > 5 RETURN [v.a, v.b]";
var XPresult;
var QResults=[];
var j;
// the index we will compare to sorts by a & b, so we need to
// re-sort the result here to accomplish similarity.
@ -636,6 +703,13 @@ function optimizerRuleTestSuite() {
assertTrue(isEqual(QResults[0], QResults[1]), "Results are Equal?");
allresults = getQueryMultiplePlansAndExecutions(query, {});
for (j = 1; j <= allresults.length; j++) {
AssertTrue(isEqual(allresults.results[0],
allresults.results[j]),
"whether the execution of this plan gave the right results: " +
allresults.plans[j]);
}
},
////////////////////////////////////////////////////////////////////////////////
@ -646,6 +720,7 @@ function optimizerRuleTestSuite() {
var query = "FOR v IN " + colName + " FILTER v.a > 4 && v.a < 10 RETURN [v.a, v.b]";
var XPresult;
var QResults=[];
var j;
// the index we will compare to sorts by a & b, so we need to
// re-sort the result here to accomplish similarity.
@ -669,6 +744,14 @@ function optimizerRuleTestSuite() {
assertEqual(first.highConst.bound, 10, "proper value was set");
assertTrue(isEqual(QResults[0], QResults[1]), "Results are Equal?");
allresults = getQueryMultiplePlansAndExecutions(query, {});
for (j = 1; j <= allresults.length; j++) {
AssertTrue(isEqual(allresults.results[0],
allresults.results[j]),
"whether the execution of this plan gave the right results: " +
allresults.plans[j]);
}
},
////////////////////////////////////////////////////////////////////////////////
@ -680,7 +763,7 @@ function optimizerRuleTestSuite() {
testRangeBandpassInvalid: function () {
var query = "FOR v IN " + colName + " FILTER v.a > 7 && v.a < 4 RETURN [v.a, v.b]";
var j;
var XPresult;
var QResults=[];
@ -701,7 +784,13 @@ function optimizerRuleTestSuite() {
hasNoIndexRangeNode(XPresult);
assertTrue(isEqual(QResults[0], QResults[1]), "Results are Equal?");
allresults = getQueryMultiplePlansAndExecutions(query, {});
for (j = 1; j <= allresults.length; j++) {
AssertTrue(isEqual(allresults.results[0],
allresults.results[j]),
"whether the execution of this plan gave the right results: " +
allresults.plans[j]);
}
},
@ -780,6 +869,7 @@ function optimizerRuleTestSuite() {
// assertTrue(isEqual(QResults[0], QResults[1]), "Results are Equal?");
}
};
}