mirror of https://gitee.com/bigwinds/arangodb
Merge branch 'aql2' of ssh://github.com/triAGENS/ArangoDB into aql2
This commit is contained in:
commit
82a403cda2
|
@ -46,9 +46,9 @@ var jsUnity = exports.jsUnity = (function () {
|
|||
assertException: function (fn, message) {
|
||||
counter++;
|
||||
try {
|
||||
fn instanceof Function && fn();
|
||||
fn instanceof Function && fn();
|
||||
} catch (e) {
|
||||
return;
|
||||
return;
|
||||
}
|
||||
var err = new Error();
|
||||
|
||||
|
@ -58,7 +58,8 @@ var jsUnity = exports.jsUnity = (function () {
|
|||
|
||||
assertTrue: function (actual, message) {
|
||||
counter++;
|
||||
if (!actual) {
|
||||
if (! actual) {
|
||||
var err = new Error();
|
||||
throw fmt("?: (?) does not evaluate to true\n(?)",
|
||||
message || "assertTrue", actual, err.stack);
|
||||
}
|
||||
|
@ -112,7 +113,7 @@ var jsUnity = exports.jsUnity = (function () {
|
|||
|
||||
assertMatch: function (re, actual, message) {
|
||||
counter++;
|
||||
if (!re.test(actual)) {
|
||||
if (! re.test(actual)) {
|
||||
var err = new Error();
|
||||
throw fmt("?: (?) does not match (?)\n(?)",
|
||||
message || "assertMatch", actual, re, err.stack);
|
||||
|
|
|
@ -39,8 +39,8 @@ function optimizerRuleTestSuite () {
|
|||
var ruleName = "move-calculations-up";
|
||||
// various choices to control the optimizer:
|
||||
var paramNone = { optimizer: { rules: [ "-all" ] } };
|
||||
var paramMCU = { optimizer: { rules: [ "-all", "+" + ruleName ] } };
|
||||
var paramNoMCU = { optimizer: { rules: [ "+all", "-" + ruleName ] } };
|
||||
var paramEnabled = { optimizer: { rules: [ "-all", "+" + ruleName ] } };
|
||||
var paramDisabled = { optimizer: { rules: [ "+all", "-" + ruleName ] } };
|
||||
return {
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
@ -70,7 +70,7 @@ function optimizerRuleTestSuite () {
|
|||
|
||||
queries.forEach(function(query) {
|
||||
var result = AQL_EXPLAIN(query, { }, paramNone);
|
||||
assertEqual([ ], result.plan.rules);
|
||||
assertEqual([ ], result.plan.rules, query);
|
||||
});
|
||||
},
|
||||
|
||||
|
@ -87,7 +87,7 @@ function optimizerRuleTestSuite () {
|
|||
];
|
||||
|
||||
queries.forEach(function(query) {
|
||||
var result = AQL_EXPLAIN(query, { }, paramMCU);
|
||||
var result = AQL_EXPLAIN(query, { }, paramEnabled);
|
||||
assertEqual([ ], result.plan.rules, query);
|
||||
});
|
||||
},
|
||||
|
@ -107,7 +107,7 @@ function optimizerRuleTestSuite () {
|
|||
];
|
||||
|
||||
queries.forEach(function(query) {
|
||||
var result = AQL_EXPLAIN(query, { }, paramMCU);
|
||||
var result = AQL_EXPLAIN(query, { }, paramEnabled);
|
||||
assertEqual([ ruleName ], result.plan.rules);
|
||||
});
|
||||
},
|
||||
|
@ -123,7 +123,7 @@ function optimizerRuleTestSuite () {
|
|||
];
|
||||
|
||||
plans.forEach(function(plan) {
|
||||
var result = AQL_EXPLAIN(plan[0], { }, paramMCU);
|
||||
var result = AQL_EXPLAIN(plan[0], { }, paramEnabled);
|
||||
assertEqual([ ruleName ], result.plan.rules, plan[0]);
|
||||
assertEqual(plan[1], helper.getCompactPlan(result).map(function(node) { return node.type; }), plan[0]);
|
||||
});
|
||||
|
@ -142,11 +142,11 @@ function optimizerRuleTestSuite () {
|
|||
];
|
||||
|
||||
queries.forEach(function(query) {
|
||||
var planDisabled = AQL_EXPLAIN(query[0], { }, paramNoMCU);
|
||||
var planEnabled = AQL_EXPLAIN(query[0], { }, paramMCU);
|
||||
var planDisabled = AQL_EXPLAIN(query[0], { }, paramDisabled);
|
||||
var planEnabled = AQL_EXPLAIN(query[0], { }, paramEnabled);
|
||||
|
||||
var resultDisabled = AQL_EXECUTE(query[0], { }, paramNoMCU);
|
||||
var resultEnabled = AQL_EXECUTE(query[0], { }, paramMCU);
|
||||
var resultDisabled = AQL_EXECUTE(query[0], { }, paramDisabled);
|
||||
var resultEnabled = AQL_EXECUTE(query[0], { }, paramEnabled);
|
||||
|
||||
assertTrue(planDisabled.plan.rules.indexOf(ruleName) === -1, query[0]);
|
||||
assertTrue(planEnabled.plan.rules.indexOf(ruleName) !== -1, query[0]);
|
||||
|
|
|
@ -0,0 +1,188 @@
|
|||
/*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 */
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief tests for optimizer rules
|
||||
///
|
||||
/// @file
|
||||
///
|
||||
/// DISCLAIMER
|
||||
///
|
||||
/// Copyright 2010-2012 triagens GmbH, Cologne, Germany
|
||||
///
|
||||
/// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
/// you may not use this file except in compliance with the License.
|
||||
/// You may obtain a copy of the License at
|
||||
///
|
||||
/// http://www.apache.org/licenses/LICENSE-2.0
|
||||
///
|
||||
/// Unless required by applicable law or agreed to in writing, software
|
||||
/// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
/// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
/// See the License for the specific language governing permissions and
|
||||
/// limitations under the License.
|
||||
///
|
||||
/// Copyright holder is triAGENS GmbH, Cologne, Germany
|
||||
///
|
||||
/// @author Jan Steemann
|
||||
/// @author Copyright 2012, triAGENS GmbH, Cologne, Germany
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
var jsunity = require("jsunity");
|
||||
var errors = require("internal").errors;
|
||||
var helper = require("org/arangodb/aql-helper");
|
||||
var getQueryResults = helper.getQueryResults2;
|
||||
var assertQueryError = helper.assertQueryError2;
|
||||
var isEqual = helper.isEqual;
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief test suite
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
function optimizerRuleTestSuite () {
|
||||
var ruleName = "remove-redundant-sorts";
|
||||
|
||||
// various choices to control the optimizer:
|
||||
var paramNone = { optimizer: { rules: [ "-all" ] } };
|
||||
var paramEnabled = { optimizer: { rules: [ "-all", "+" + ruleName ] } };
|
||||
var paramDisabled = { optimizer: { rules: [ "+all", "-" + ruleName ] } };
|
||||
|
||||
return {
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief set up
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
setUp : function () {
|
||||
},
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief tear down
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
tearDown : function () {
|
||||
},
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief test that rule has no effect when explicitly disabled
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
testRuleDisabled : function () {
|
||||
var queries = [
|
||||
"FOR i IN [ { a: 1 }, { a: 2 }, { a: 3 } ] SORT i.a SORT i.a RETURN i",
|
||||
"FOR i IN [ { a: 1 }, { a: 2 }, { a: 3 } ] SORT i.a FILTER i.a == 1 SORT i.a RETURN i",
|
||||
"FOR i IN [ { a: 1 }, { a: 2 }, { a: 3 } ] SORT i.a LIMIT 1 SORT i.a RETURN i"
|
||||
];
|
||||
|
||||
queries.forEach(function(query) {
|
||||
var result = AQL_EXPLAIN(query, { }, paramNone);
|
||||
assertEqual([ ], result.plan.rules);
|
||||
});
|
||||
},
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief test that rule has no effect
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
testRuleNoEffect : function () {
|
||||
var queries = [
|
||||
"FOR i IN [ { a: 1 }, { a: 2 }, { a: 3 } ] SORT i.a RETURN i",
|
||||
"FOR i IN [ { a: 1 }, { a: 2 }, { a: 3 } ] SORT i.a SORT i.b RETURN i",
|
||||
"FOR i IN [ { a: 1 }, { a: 2 }, { a: 3 } ] SORT i.a SORT i.b RETURN i",
|
||||
"FOR i IN [ { a: 1 }, { a: 2 }, { a: 3 } ] SORT i.a SORT i.c RETURN i"
|
||||
];
|
||||
|
||||
queries.forEach(function(query) {
|
||||
var result = AQL_EXPLAIN(query, { }, paramEnabled);
|
||||
assertEqual([ ], result.plan.rules, query);
|
||||
});
|
||||
},
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief test that rule has an effect
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
testRuleHasEffect : function () {
|
||||
var queries = [
|
||||
"FOR i IN [ { a: 1 }, { a: 2 }, { a: 3 } ] SORT i.a SORT i.a RETURN i",
|
||||
"FOR i IN [ { a: 1 }, { a: 2 }, { a: 3 } ] SORT i.a, i.b SORT i.a, i.b RETURN i",
|
||||
"FOR i IN [ { a: 1 }, { a: 2 }, { a: 3 } ] SORT i.a DESC SORT i.a DESC RETURN i",
|
||||
"FOR i IN [ { a: 1 }, { a: 2 }, { a: 3 } ] SORT i.a, i.b DESC SORT i.a, i.b DESC RETURN i",
|
||||
"FOR i IN [ { a: 1 }, { a: 2 }, { a: 3 } ] SORT i.a FILTER i.a == 1 SORT i.a RETURN i",
|
||||
"FOR i IN [ { a: 1 }, { a: 2 }, { a: 3 } ] SORT i.a DESC FILTER i.a == 1 SORT i.a DESC RETURN i"
|
||||
];
|
||||
|
||||
queries.forEach(function(query) {
|
||||
var result = AQL_EXPLAIN(query, { }, paramEnabled);
|
||||
//require("internal").print(result);
|
||||
assertEqual([ ruleName ], result.plan.rules);
|
||||
});
|
||||
},
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief test generated plans
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
testPlans : function () {
|
||||
var plans = [
|
||||
];
|
||||
|
||||
plans.forEach(function(plan) {
|
||||
var result = AQL_EXPLAIN(plan[0], { }, paramEnabled);
|
||||
assertEqual([ ruleName ], result.plan.rules, plan[0]);
|
||||
//require("internal").print(helper.getCompactPlan(result).map(function(node) { return node.type; }));
|
||||
assertEqual(plan[1], helper.getCompactPlan(result).map(function(node) { return node.type; }), plan[0]);
|
||||
});
|
||||
},
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief test results
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
testResults : function () {
|
||||
var queries = [
|
||||
[ "FOR i IN [ { a: 1 }, { a: 2 }, { a: 3 } ] SORT i.a SORT i.a RETURN i", [ { a: 1 }, { a: 2 }, { a: 3 } ] ],
|
||||
[ "FOR i IN [ { a: 1 }, { a: 2 }, { a: 3 } ] SORT i.a DESC SORT i.a DESC RETURN i", [ { a: 3 }, { a: 2 }, { a: 1 } ] ],
|
||||
[ "FOR i IN [ { a: 1, b: 1 }, { a: 1, b: 2 }, { a: 2, b: 1 }, { a: 2, b: 2 }, { a: 3, b: 1 }, { a: 3, b: 2 } ] SORT i.a, i.b ASC SORT i.a, i.b ASC RETURN i", [ { a: 1, b: 1 }, { a: 1, b: 2 }, { a: 2, b: 1 }, { a: 2, b: 2 }, { a: 3, b: 1 }, { a: 3, b: 2 } ] ],
|
||||
[ "FOR i IN [ { a: 1, b: 1 }, { a: 1, b: 2 }, { a: 2, b: 1 }, { a: 2, b: 2 }, { a: 3, b: 1 }, { a: 3, b: 2 } ] SORT i.a, i.b DESC SORT i.a, i.b DESC RETURN i", [ { a: 1, b: 2 }, { a: 1, b: 1 }, { a: 2, b: 2 }, { a: 2, b: 1 }, { a: 3, b: 2 }, { a: 3, b: 1 } ] ],
|
||||
[ "FOR i IN [ { a: 1, b: 1 }, { a: 1, b: 2 }, { a: 2, b: 1 }, { a: 2, b: 2 }, { a: 3, b: 1 }, { a: 3, b: 2 } ] SORT i.a DESC, i.b DESC SORT i.a DESC, i.b DESC RETURN i", [ { a: 3, b: 2 }, { a: 3, b: 1 }, { a: 2, b: 2 }, { a: 2, b: 1 }, { a: 1, b: 2 }, { a: 1, b: 1 } ] ]
|
||||
];
|
||||
|
||||
// note: the optimizer currently cannot optimize these queries:
|
||||
// [ "FOR i IN [ { a: 1 }, { a: 2 }, { a: 3 } ] SORT i.a DESC SORT i.a RETURN i", [ { a: 1 }, { a: 2 }, { a: 3 } ] ],
|
||||
// [ "FOR i IN [ { a: 1 }, { a: 2 }, { a: 3 } ] SORT i.a ASC SORT i.a DESC RETURN i", [ { a: 3 }, { a: 2 }, { a: 1 } ] ],
|
||||
// [ "FOR i IN [ { a: 1, b: 1 }, { a: 1, b: 2 }, { a: 2, b: 1 }, { a: 2, b: 2 }, { a: 3, b: 1 }, { a: 3, b: 2 } ] SORT i.a, i.b DESC SORT i.a, i.b ASC RETURN i", [ { a: 1, b: 1 }, { a: 1, b: 2 }, { a: 2, b: 1 }, { a: 2, b: 2 }, { a: 3, b: 1 }, { a: 3, b: 2 } ] ],
|
||||
// [ "FOR i IN [ { a: 1, b: 1 }, { a: 1, b: 2 }, { a: 2, b: 1 }, { a: 2, b: 2 }, { a: 3, b: 1 }, { a: 3, b: 2 } ] SORT i.a, i.b ASC SORT i.a, i.b DESC RETURN i", [ { a: 1, b: 2 }, { a: 1, b: 1 }, { a: 2, b: 2 }, { a: 2, b: 1 }, { a: 3, b: 2 }, { a: 3, b: 1 } ] ],
|
||||
// [ "FOR i IN [ { a: 1, b: 1 }, { a: 1, b: 2 }, { a: 2, b: 1 }, { a: 2, b: 2 }, { a: 3, b: 1 }, { a: 3, b: 2 } ] SORT i.a, i.b ASC SORT i.a DESC, i.b DESC RETURN i", [ { a: 3, b: 2 }, { a: 3, b: 1 }, { a: 2, b: 2 }, { a: 2, b: 1 }, { a: 1, b: 2 }, { a: 1, b: 1 } ] ],
|
||||
|
||||
queries.forEach(function(query) {
|
||||
var planDisabled = AQL_EXPLAIN(query[0], { }, paramDisabled);
|
||||
var planEnabled = AQL_EXPLAIN(query[0], { }, paramEnabled);
|
||||
var resultDisabled = AQL_EXECUTE(query[0], { }, paramDisabled).json;
|
||||
var resultEnabled = AQL_EXECUTE(query[0], { }, paramEnabled).json;
|
||||
|
||||
assertTrue(isEqual(resultDisabled, resultEnabled), query[0]);
|
||||
|
||||
assertTrue(planDisabled.plan.rules.indexOf(ruleName) === -1, query[0]);
|
||||
assertTrue(planEnabled.plan.rules.indexOf(ruleName) !== -1, query[0]);
|
||||
|
||||
assertEqual(resultDisabled, query[1]);
|
||||
assertEqual(resultEnabled, query[1]);
|
||||
});
|
||||
}
|
||||
|
||||
};
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief executes the test suite
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
jsunity.run(optimizerRuleTestSuite);
|
||||
|
||||
return jsunity.done();
|
||||
|
||||
// Local Variables:
|
||||
// mode: outline-minor
|
||||
// outline-regexp: "^\\(/// @brief\\|/// @addtogroup\\|// --SECTION--\\|/// @page\\|/// @}\\)"
|
||||
// End:
|
|
@ -42,8 +42,8 @@ function optimizerRuleTestSuite () {
|
|||
var ruleName = "remove-unnecessary-calculations";
|
||||
// various choices to control the optimizer:
|
||||
var paramNone = { optimizer: { rules: [ "-all" ] } };
|
||||
var paramMCU = { optimizer: { rules: [ "-all", "+" + ruleName ] } };
|
||||
var paramNoMCU = { optimizer: { rules: [ "+all", "-" + ruleName ] } };
|
||||
var paramEnabled = { optimizer: { rules: [ "-all", "+" + ruleName ] } };
|
||||
var paramDisabled = { optimizer: { rules: [ "+all", "-" + ruleName ] } };
|
||||
return {
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
@ -65,7 +65,10 @@ function optimizerRuleTestSuite () {
|
|||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
testRuleDisabled : function () {
|
||||
/*
|
||||
var queries = [
|
||||
"FOR a IN 1 LET b=a+1 RETURN b+2",
|
||||
|
||||
"FOR a IN 1 RETURN a + 1",
|
||||
"FOR a IN 1 RETURN a + 0",
|
||||
"FOR a IN 1 RETURN a - 1",
|
||||
|
@ -117,10 +120,11 @@ function optimizerRuleTestSuite () {
|
|||
|
||||
queries.forEach(function(query) {
|
||||
var result = AQL_EXPLAIN(query, { }, paramNone);
|
||||
assertEqual([ ], result.plan.rules);
|
||||
assertEqual([ ], result.plan.rules, query);
|
||||
});
|
||||
*/
|
||||
},
|
||||
|
||||
/*
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief test that rule has no effect
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
@ -177,17 +181,19 @@ function optimizerRuleTestSuite () {
|
|||
];
|
||||
|
||||
queries.forEach(function(query) {
|
||||
var result = AQL_EXPLAIN(query, { }, paramMCU);
|
||||
var result = AQL_EXPLAIN(query, { }, paramEnabled);
|
||||
assertEqual([ ], result.plan.rules, query);
|
||||
});
|
||||
},
|
||||
|
||||
*/
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief test that rule has an effect
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
/// AQL_EXPLAIN("FOR a IN 1 LET b=a+1 RETURN a+2"); -> tuts nur kombiniert
|
||||
testRuleHasEffect : function () {
|
||||
var queries = [
|
||||
"FOR a IN 1 LET b=a+1 RETURN b+2"
|
||||
/*
|
||||
"LET a = 1 RETURN a + 1",
|
||||
"LET a = 1 RETURN a + 0",
|
||||
"LET a = 1 RETURN a - 1",
|
||||
|
@ -195,6 +201,7 @@ function optimizerRuleTestSuite () {
|
|||
"LET a = 4 RETURN a / 2",
|
||||
"LET a = 4 RETURN a % 3",
|
||||
"LET a = 4 RETURN a == 8",
|
||||
"LET a = 4 RETURN a == 8 && a != 7 ",
|
||||
"LET a = 4 RETURN 2",
|
||||
"LET a = [1, 2, 3, 4, 5, 6] RETURN SLICE(a, 4, 1)",
|
||||
"LET a = 17.33 RETURN FLOOR(a)",
|
||||
|
@ -235,14 +242,15 @@ function optimizerRuleTestSuite () {
|
|||
"LET a = 5 RETURN DATE_TIMESTAMP(a)",
|
||||
"LET a = 5 RETURN DATE_ISO8601(a)",
|
||||
"LET a = 1975 RETURN DATE_YEAR(a)",
|
||||
"FOR i IN 1..10 LET a = 1 FILTER i == a RETURN i"
|
||||
*/
|
||||
//"FOR i IN 1..10 LET a = 1 FILTER i == a RETURN i"
|
||||
// "FOR i IN 1..10 LET a = i + 1 FILTER i != a RETURN i"
|
||||
];
|
||||
|
||||
queries.forEach(function(query) {
|
||||
var result = AQL_EXPLAIN(query, { }, paramMCU);
|
||||
//require("internal").print(result);
|
||||
assertEqual([ ruleName ], result.plan.rules);
|
||||
var result = AQL_EXPLAIN(query);///, { }, paramEnabled);
|
||||
require("internal").print(result);
|
||||
//assertEqual([ ruleName ], result.plan.rules);
|
||||
});
|
||||
},
|
||||
|
||||
|
@ -250,7 +258,7 @@ function optimizerRuleTestSuite () {
|
|||
/// @brief test generated plans
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
/*
|
||||
testPlans : function () {
|
||||
var plans = [
|
||||
["LET a = 1 RETURN a + 1", ["SingletonNode", "CalculationNode", "ReturnNode"]],
|
||||
|
@ -304,7 +312,7 @@ function optimizerRuleTestSuite () {
|
|||
];
|
||||
|
||||
plans.forEach(function(plan) {
|
||||
var result = AQL_EXPLAIN(plan[0], { }, paramMCU);
|
||||
var result = AQL_EXPLAIN(plan[0], { }, paramEnabled);
|
||||
assertEqual([ ruleName ], result.plan.rules, plan[0]);
|
||||
//require("internal").print(helper.getCompactPlan(result).map(function(node) { return node.type; }));
|
||||
assertEqual(plan[1], helper.getCompactPlan(result).map(function(node) { return node.type; }), plan[0]);
|
||||
|
@ -368,13 +376,13 @@ function optimizerRuleTestSuite () {
|
|||
];
|
||||
|
||||
queries.forEach(function(query) {
|
||||
var resultDisabled = AQL_EXECUTE(query[0], { }, paramNoMCU).json;
|
||||
var resultEnabled = AQL_EXECUTE(query[0], { }, paramMCU).json;
|
||||
var resultDisabled = AQL_EXECUTE(query[0], { }, paramDisabled).json;
|
||||
var resultEnabled = AQL_EXECUTE(query[0], { }, paramEnabled).json;
|
||||
|
||||
assertTrue(isEqual(resultDisabled, resultEnabled), query[0]);
|
||||
});
|
||||
}
|
||||
|
||||
*/
|
||||
};
|
||||
}
|
||||
|
||||
|
|
|
@ -27,7 +27,7 @@
|
|||
/// @author Jan Steemann
|
||||
/// @author Copyright 2012, triAGENS GmbH, Cologne, Germany
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
var yaml = require("js-yaml")
|
||||
var internal = require("internal");
|
||||
var jsunity = require("jsunity");
|
||||
var errors = require("internal").errors;
|
||||
|
@ -51,10 +51,10 @@ function optimizerRuleTestSuite() {
|
|||
|
||||
// various choices to control the optimizer:
|
||||
var paramNone = { optimizer: { rules: [ "-all" ] } };
|
||||
var paramIFS = { optimizer: { rules: [ "-all", "+" + ruleName ] } };
|
||||
var paramIR = { optimizer: { rules: [ "-all", "+" + secondRuleName ] } };
|
||||
var paramRS = { optimizer: { rules: [ "-all", "+" + thirdRuleName ] } };
|
||||
var paramBoth = { optimizer: { rules: [ "-all", "+" + ruleName, "+" + secondRuleName ] } };
|
||||
var paramIndexFromSort = { optimizer: { rules: [ "-all", "+" + ruleName ] } };
|
||||
var paramIndexRange = { optimizer: { rules: [ "-all", "+" + secondRuleName ] } };
|
||||
var paramRedundantSort = { optimizer: { rules: [ "-all", "+" + thirdRuleName ] } };
|
||||
var paramIndexFromSort_IndexRange = { optimizer: { rules: [ "-all", "+" + ruleName, "+" + secondRuleName ] } };
|
||||
|
||||
var skiplist;
|
||||
var skiplist2;
|
||||
|
@ -196,7 +196,7 @@ function optimizerRuleTestSuite() {
|
|||
|
||||
queries.forEach(function(query) {
|
||||
|
||||
var result = AQL_EXPLAIN(query, { }, paramIFS);
|
||||
var result = AQL_EXPLAIN(query, { }, paramIndexFromSort);
|
||||
assertEqual([], result.plan.rules, query);
|
||||
});
|
||||
|
||||
|
@ -220,10 +220,10 @@ function optimizerRuleTestSuite() {
|
|||
var i = 0;
|
||||
queries.forEach(function(query) {
|
||||
|
||||
var result = AQL_EXPLAIN(query, { }, paramIFS);
|
||||
var result = AQL_EXPLAIN(query, { }, paramIndexFromSort);
|
||||
assertEqual([ ruleName ], result.plan.rules, query);
|
||||
QResults[0] = AQL_EXECUTE(query, { }, paramNone).json;
|
||||
QResults[1] = AQL_EXECUTE(query, { }, paramIFS ).json;
|
||||
QResults[1] = AQL_EXECUTE(query, { }, paramIndexFromSort ).json;
|
||||
|
||||
assertTrue(isEqual(QResults[0], QResults[1]), "Result " + i + " is Equal?");
|
||||
i++;
|
||||
|
@ -246,12 +246,12 @@ function optimizerRuleTestSuite() {
|
|||
var i = 0;
|
||||
queries.forEach(function(query) {
|
||||
|
||||
var result = AQL_EXPLAIN(query, { }, paramIFS);
|
||||
var result = AQL_EXPLAIN(query, { }, paramIndexFromSort);
|
||||
assertEqual([ ruleName ], result.plan.rules);
|
||||
hasIndexRangeNode_WithRanges(result, false);
|
||||
hasSortNode(result);
|
||||
QResults[0] = AQL_EXECUTE(query, { }, paramNone).json;
|
||||
QResults[1] = AQL_EXECUTE(query, { }, paramIFS ).json;
|
||||
QResults[1] = AQL_EXECUTE(query, { }, paramIndexFromSort ).json;
|
||||
assertTrue(isEqual(QResults[0], QResults[1]), "Result " + i + " is Equal?");
|
||||
i++;
|
||||
});
|
||||
|
@ -278,8 +278,8 @@ function optimizerRuleTestSuite() {
|
|||
QResults[0] = AQL_EXECUTE(query, { }, paramNone).json.sort(sortArray);
|
||||
|
||||
// -> use-index-for-sort alone.
|
||||
XPresult = AQL_EXPLAIN(query, { }, paramIFS);
|
||||
QResults[1] = AQL_EXECUTE(query, { }, paramIFS).json;
|
||||
XPresult = AQL_EXPLAIN(query, { }, paramIndexFromSort);
|
||||
QResults[1] = AQL_EXECUTE(query, { }, paramIndexFromSort).json;
|
||||
// our rule should have been applied.
|
||||
assertEqual([ ruleName ], XPresult.plan.rules);
|
||||
// The sortnode and its calculation node should have been removed.
|
||||
|
@ -310,8 +310,8 @@ function optimizerRuleTestSuite() {
|
|||
|
||||
|
||||
// -> use-index-for-sort alone.
|
||||
QResults[1] = AQL_EXECUTE(query, { }, paramIFS).json;
|
||||
XPresult = AQL_EXPLAIN(query, { }, paramIFS);
|
||||
QResults[1] = AQL_EXECUTE(query, { }, paramIndexFromSort).json;
|
||||
XPresult = AQL_EXPLAIN(query, { }, paramIndexFromSort);
|
||||
// our rule should be there.
|
||||
assertEqual([ ruleName ], XPresult.plan.rules);
|
||||
// The sortnode and its calculation node should have been removed.
|
||||
|
@ -323,8 +323,8 @@ function optimizerRuleTestSuite() {
|
|||
|
||||
// -> combined use-index-for-sort and use-index-range
|
||||
// use-index-range superseedes use-index-for-sort
|
||||
QResults[2] = AQL_EXECUTE(query, { }, paramBoth).json;
|
||||
XPresult = AQL_EXPLAIN(query, { }, paramBoth);
|
||||
QResults[2] = AQL_EXECUTE(query, { }, paramIndexFromSort_IndexRange).json;
|
||||
XPresult = AQL_EXPLAIN(query, { }, paramIndexFromSort_IndexRange);
|
||||
|
||||
assertEqual([ secondRuleName ], XPresult.plan.rules.sort());
|
||||
// The sortnode and its calculation node should not have been removed.
|
||||
|
@ -334,8 +334,8 @@ function optimizerRuleTestSuite() {
|
|||
hasIndexRangeNode_WithRanges(XPresult, true);
|
||||
|
||||
// -> use-index-range alone.
|
||||
QResults[3] = AQL_EXECUTE(query, { }, paramIR).json;
|
||||
XPresult = AQL_EXPLAIN(query, { }, paramIR);
|
||||
QResults[3] = AQL_EXECUTE(query, { }, paramIndexRange).json;
|
||||
XPresult = AQL_EXPLAIN(query, { }, paramIndexRange);
|
||||
assertEqual([ secondRuleName ], XPresult.plan.rules);
|
||||
// the sortnode and its calculation node should be there.
|
||||
|
||||
|
@ -370,8 +370,8 @@ function optimizerRuleTestSuite() {
|
|||
QResults[0] = AQL_EXECUTE(query, { }, paramNone).json.sort(sortArray);
|
||||
|
||||
// -> use-index-for-sort alone.
|
||||
QResults[1] = AQL_EXECUTE(query, { }, paramIFS).json;
|
||||
XPresult = AQL_EXPLAIN(query, { }, paramIFS);
|
||||
QResults[1] = AQL_EXECUTE(query, { }, paramIndexFromSort).json;
|
||||
XPresult = AQL_EXPLAIN(query, { }, paramIndexFromSort);
|
||||
// our rule should be there.
|
||||
assertEqual([ ruleName ], XPresult.plan.rules);
|
||||
// The sortnode and its calculation node should have been removed.
|
||||
|
@ -381,8 +381,8 @@ function optimizerRuleTestSuite() {
|
|||
hasIndexRangeNode_WithRanges(XPresult, false);
|
||||
|
||||
// -> combined use-index-for-sort and use-index-range
|
||||
QResults[2] = AQL_EXECUTE(query, { }, paramBoth).json;
|
||||
XPresult = AQL_EXPLAIN(query, { }, paramBoth);
|
||||
QResults[2] = AQL_EXECUTE(query, { }, paramIndexFromSort_IndexRange).json;
|
||||
XPresult = AQL_EXPLAIN(query, { }, paramIndexFromSort_IndexRange);
|
||||
assertEqual([ secondRuleName, ruleName ].sort(), XPresult.plan.rules.sort());
|
||||
// The sortnode and its calculation node should have been removed.
|
||||
hasNoSortNode(XPresult);
|
||||
|
@ -391,8 +391,8 @@ function optimizerRuleTestSuite() {
|
|||
hasIndexRangeNode_WithRanges(XPresult, true);
|
||||
|
||||
// -> use-index-range alone.
|
||||
QResults[3] = AQL_EXECUTE(query, { }, paramIR).json;
|
||||
XPresult = AQL_EXPLAIN(query, { }, paramIR);
|
||||
QResults[3] = AQL_EXECUTE(query, { }, paramIndexRange).json;
|
||||
XPresult = AQL_EXPLAIN(query, { }, paramIndexRange);
|
||||
assertEqual([ secondRuleName ], XPresult.plan.rules);
|
||||
// the sortnode and its calculation node should be there.
|
||||
hasSortNode(XPresult);
|
||||
|
@ -427,8 +427,8 @@ function optimizerRuleTestSuite() {
|
|||
QResults[0] = AQL_EXECUTE(query, { }, paramNone).json;
|
||||
|
||||
// -> use-index-for-sort alone.
|
||||
QResults[1] = AQL_EXECUTE(query, { }, paramIFS).json;
|
||||
XPresult = AQL_EXPLAIN(query, { }, paramIFS);
|
||||
QResults[1] = AQL_EXECUTE(query, { }, paramIndexFromSort).json;
|
||||
XPresult = AQL_EXPLAIN(query, { }, paramIndexFromSort);
|
||||
// our rule should be there.
|
||||
assertEqual([ ruleName ], XPresult.plan.rules);
|
||||
// The sortnode and its calculation node should have been removed.
|
||||
|
@ -438,9 +438,9 @@ function optimizerRuleTestSuite() {
|
|||
hasIndexRangeNode_WithRanges(XPresult, false);
|
||||
|
||||
// -> combined use-index-for-sort and use-index-range
|
||||
QResults[2] = AQL_EXECUTE(query, { }, paramBoth).json;
|
||||
QResults[2] = AQL_EXECUTE(query, { }, paramIndexFromSort_IndexRange).json;
|
||||
|
||||
XPresult = AQL_EXPLAIN(query, { }, paramBoth);
|
||||
XPresult = AQL_EXPLAIN(query, { }, paramIndexFromSort_IndexRange);
|
||||
|
||||
assertEqual([ secondRuleName, ruleName ].sort(), XPresult.plan.rules.sort());
|
||||
// The sortnode and its calculation node should have been removed.
|
||||
|
@ -450,8 +450,8 @@ function optimizerRuleTestSuite() {
|
|||
hasIndexRangeNode_WithRanges(XPresult, true);
|
||||
|
||||
// -> use-index-range alone.
|
||||
QResults[3] = AQL_EXECUTE(query, { }, paramIR).json;
|
||||
XPresult = AQL_EXPLAIN(query, { }, paramIR);
|
||||
QResults[3] = AQL_EXECUTE(query, { }, paramIndexRange).json;
|
||||
XPresult = AQL_EXPLAIN(query, { }, paramIndexRange);
|
||||
assertEqual([ secondRuleName ], XPresult.plan.rules);
|
||||
// the sortnode and its calculation node should be there.
|
||||
hasSortNode(XPresult);
|
||||
|
@ -491,8 +491,8 @@ function optimizerRuleTestSuite() {
|
|||
QResults[0] = AQL_EXECUTE(query, { }, paramNone).json;
|
||||
|
||||
// -> use-index-range alone.
|
||||
QResults[1] = AQL_EXECUTE(query, { }, paramIR).json;
|
||||
XPresult = AQL_EXPLAIN(query, { }, paramIR);
|
||||
QResults[1] = AQL_EXECUTE(query, { }, paramIndexRange).json;
|
||||
XPresult = AQL_EXPLAIN(query, { }, paramIndexRange);
|
||||
assertEqual([ secondRuleName ], XPresult.plan.rules);
|
||||
// the sortnode and its calculation node should be there.
|
||||
hasCalculationNodes(XPresult, 2);
|
||||
|
@ -527,9 +527,9 @@ function optimizerRuleTestSuite() {
|
|||
QResults[0] = AQL_EXECUTE(query, { }, paramNone).json.sort(sortArray);
|
||||
|
||||
// -> use-index-range alone.
|
||||
QResults[1] = AQL_EXECUTE(query, { }, paramIR).json;
|
||||
QResults[1] = AQL_EXECUTE(query, { }, paramIndexRange).json;
|
||||
|
||||
XPresult = AQL_EXPLAIN(query, { }, paramIR);
|
||||
XPresult = AQL_EXPLAIN(query, { }, paramIndexRange);
|
||||
assertEqual([ secondRuleName ], XPresult.plan.rules);
|
||||
// the sortnode and its calculation node should be there.
|
||||
hasCalculationNodes(XPresult, 2);
|
||||
|
@ -555,9 +555,9 @@ function optimizerRuleTestSuite() {
|
|||
QResults[0] = AQL_EXECUTE(query, { }, paramNone).json.sort(sortArray);
|
||||
|
||||
// -> use-index-range alone.
|
||||
QResults[1] = AQL_EXECUTE(query, { }, paramIR).json;
|
||||
QResults[1] = AQL_EXECUTE(query, { }, paramIndexRange).json;
|
||||
|
||||
XPresult = AQL_EXPLAIN(query, { }, paramIR);
|
||||
XPresult = AQL_EXPLAIN(query, { }, paramIndexRange);
|
||||
assertEqual([ secondRuleName ], XPresult.plan.rules);
|
||||
// the sortnode and its calculation node should be there.
|
||||
hasCalculationNodes(XPresult, 2);
|
||||
|
@ -586,9 +586,9 @@ function optimizerRuleTestSuite() {
|
|||
QResults[0] = AQL_EXECUTE(query, { }, paramNone).json.sort(sortArray);
|
||||
|
||||
// -> use-index-range alone.
|
||||
QResults[1] = AQL_EXECUTE(query, { }, paramIR).json;
|
||||
QResults[1] = AQL_EXECUTE(query, { }, paramIndexRange).json;
|
||||
|
||||
XPresult = AQL_EXPLAIN(query, { }, paramIR);
|
||||
XPresult = AQL_EXPLAIN(query, { }, paramIndexRange);
|
||||
assertEqual([ secondRuleName ], XPresult.plan.rules);
|
||||
// the sortnode and its calculation node should be there.
|
||||
hasCalculationNodes(XPresult, 2);
|
||||
|
@ -620,10 +620,10 @@ function optimizerRuleTestSuite() {
|
|||
// QResults[0] = AQL_EXECUTE(query, { }, paramNone).json.sort(sortArray);
|
||||
//
|
||||
// // -> use-index-range alone.
|
||||
// QResults[1] = AQL_EXECUTE(query, { }, paramIR).json;
|
||||
// QResults[1] = AQL_EXECUTE(query, { }, paramIndexRange).json;
|
||||
//
|
||||
//
|
||||
// XPresult = AQL_EXPLAIN(query, { }, paramIR);
|
||||
// XPresult = AQL_EXPLAIN(query, { }, paramIndexRange);
|
||||
// require("internal").print(XPresult);
|
||||
// assertEqual([ secondRuleName ], XPresult.plan.rules);
|
||||
// // the sortnode and its calculation node should be there.
|
||||
|
@ -661,9 +661,9 @@ function optimizerRuleTestSuite() {
|
|||
// QResults[0] = AQL_EXECUTE(query, { }, paramNone).json.sort(sortArray);
|
||||
//
|
||||
// // -> use-index-range alone.
|
||||
// QResults[1] = AQL_EXECUTE(query, { }, paramIR).json;
|
||||
// QResults[1] = AQL_EXECUTE(query, { }, paramIndexRange).json;
|
||||
//
|
||||
// XPresult = AQL_EXPLAIN(query, { }, paramIR);
|
||||
// XPresult = AQL_EXPLAIN(query, { }, paramIndexRange);
|
||||
// assertEqual([ secondRuleName ], XPresult.plan.rules);
|
||||
// // the sortnode and its calculation node should be there.
|
||||
// hasCalculationNodes(XPresult, 2);
|
||||
|
@ -697,9 +697,9 @@ function optimizerRuleTestSuite() {
|
|||
// QResults[0] = AQL_EXECUTE(query, { }, paramNone).json.sort(sortArray);
|
||||
//
|
||||
// // -> use-index-range alone.
|
||||
// QResults[1] = AQL_EXECUTE(query, { }, paramIR).json;
|
||||
// QResults[1] = AQL_EXECUTE(query, { }, paramIndexRange).json;
|
||||
//
|
||||
// XPresult = AQL_EXPLAIN(query, { }, paramIR);
|
||||
// XPresult = AQL_EXPLAIN(query, { }, paramIndexRange);
|
||||
// assertEqual([ secondRuleName ], XPresult.plan.rules);
|
||||
// // the sortnode and its calculation node should be there.
|
||||
// hasCalculationNodes(XPresult, 2);
|
||||
|
@ -728,44 +728,49 @@ function optimizerRuleTestSuite() {
|
|||
/// TODO: asc/desc? -> desc should win; doesn't work now!
|
||||
/// "FOR v IN " + colName + " SORT v.c ASC SORT v.c DESC RETURN [v.a, v.b]",
|
||||
var queries = [
|
||||
|
||||
"FOR v IN " + colName + " SORT v.c SORT v.c RETURN [v.a, v.b]",
|
||||
"FOR v IN " + colName + " SORT v.c SORT v.c , v.d RETURN [v.a, v.b]",
|
||||
"FOR v IN " + colName + " SORT v.c, v.d SORT v.c RETURN [v.a, v.b]",
|
||||
"FOR v IN " + colName + " SORT v.c SORT v.c, v.d SORT v.c RETURN [v.a, v.b]",
|
||||
"FOR v IN " + colName + " SORT v.c, v.d SORT v.c SORT v.c, v.d SORT v.c RETURN [v.a, v.b]",
|
||||
"FOR v IN " + colName + " SORT v.c FILTER v.c > 3 SORT v.c RETURN [v.a, v.b]",
|
||||
"FOR v IN " + colName + " SORT v.c ASC SORT v.c DESC RETURN [v.a, v.b]",
|
||||
|
||||
"FOR v IN " + colName + " SORT v.c ASC LIMIT 0,3 SORT v.c ASC RETURN [v.a, v.b]"
|
||||
|
||||
"FOR v IN " + colName + " SORT v.c FILTER v.c > 3 SORT v.c RETURN [v.a, v.b]"
|
||||
];
|
||||
|
||||
queries.forEach(function(query) {
|
||||
|
||||
// require("internal").print(query);
|
||||
var result = AQL_EXPLAIN(query, { }, paramRS);
|
||||
// require("internal").print(result);
|
||||
var result = AQL_EXPLAIN(query, { }, paramRedundantSort);
|
||||
require("internal").print(yaml.safeDump(result));
|
||||
assertEqual([thirdRuleName], result.plan.rules, query);
|
||||
});
|
||||
|
||||
},
|
||||
testDSRuleHasNoEffect : function () {
|
||||
// TODO: howto have "dependencies" on a sort node?
|
||||
// var queries = [
|
||||
// "FOR v IN " + colName + " SORT v.c SORT v.c RETURN [v.a, v.b]",
|
||||
// "FOR v IN " + colName + " SORT v.c SORT v.c , v.d RETURN [v.a, v.b]",
|
||||
// "FOR v IN " + colName + " SORT v.c, v.d SORT v.c RETURN [v.a, v.b]",
|
||||
// "FOR v IN " + colName + " SORT v.c SORT v.c, v.d SORT v.c RETURN [v.a, v.b]",
|
||||
// "FOR v IN " + colName + " SORT v.c, v.d SORT v.c SORT v.c, v.d SORT v.c RETURN [v.a, v.b]",
|
||||
//
|
||||
// "FOR v IN " + colName + " SORT v.c FILTER v.c > 3 SORT v.c RETURN [v.a, v.b]"
|
||||
// ];
|
||||
//
|
||||
// queries.forEach(function(query) {
|
||||
//
|
||||
//// require("internal").print(query);
|
||||
// var result = AQL_EXPLAIN(query, { }, paramRS);
|
||||
//// require("internal").print(result);
|
||||
// assertEqual([thirdRuleName], result.plan.rules, query);
|
||||
// });
|
||||
//
|
||||
// TODO: if we implement nodes with multiple pre-nodes, we need to test this here.
|
||||
// - Cluster
|
||||
var queries = [
|
||||
/* "FOR v IN " + colName + " SORT v.c SORT v.c RETURN [v.a, v.b]",
|
||||
"FOR v IN " + colName + " SORT v.c SORT v.c , v.d RETURN [v.a, v.b]",
|
||||
"FOR v IN " + colName + " SORT v.c, v.d SORT v.c RETURN [v.a, v.b]",
|
||||
"FOR v IN " + colName + " SORT v.c SORT v.c, v.d SORT v.c RETURN [v.a, v.b]",
|
||||
"FOR v IN " + colName + " SORT v.c, v.d SORT v.c SORT v.c, v.d SORT v.c RETURN [v.a, v.b]",
|
||||
*/
|
||||
"FOR v IN " + colName + " SORT v.c ASC LIMIT 0,3 SORT v.c DESC RETURN [v.a, v.b]"
|
||||
];
|
||||
|
||||
queries.forEach(function(query) {
|
||||
|
||||
// require("internal").print(query);
|
||||
var result = AQL_EXPLAIN(query, { }, paramRedundantSort);
|
||||
require("internal").print(yaml.safeDump(result));
|
||||
assertEqual(result.plan.rules, query);
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
};
|
||||
|
|
Loading…
Reference in New Issue