mirror of https://gitee.com/bigwinds/arangodb
205 lines
7.5 KiB
JavaScript
205 lines
7.5 KiB
JavaScript
/*jshint globalstrict:false, strict:false, maxlen: 500 */
|
|
/*global assertTrue, assertEqual, assertNotEqual, AQL_EXPLAIN, AQL_EXECUTE */
|
|
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
/// @brief tests for optimizer rules
|
|
///
|
|
/// @file
|
|
///
|
|
/// DISCLAIMER
|
|
///
|
|
/// Copyright 2010-2014 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
|
|
/// @author Copyright 2014, triAGENS GmbH, Cologne, Germany
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
|
|
let db = require("@arangodb").db;
|
|
let jsunity = require("jsunity");
|
|
|
|
function optimizerRuleTestSuite () {
|
|
const ruleName = "parallelize-gather";
|
|
const cn = "UnitTestsAqlOptimizerRule";
|
|
|
|
return {
|
|
|
|
setUpAll : function () {
|
|
db._drop(cn);
|
|
let c = db._create(cn, { numberOfShards: 5 });
|
|
let docs = [];
|
|
for (let i = 0; i < 50000; ++i) {
|
|
docs.push({ _key: "test" + i, value1: i, value2: "test" + i });
|
|
if (docs.length === 5000) {
|
|
c.insert(docs);
|
|
docs = [];
|
|
}
|
|
}
|
|
c.ensureIndex({ type: "skiplist", fields: ["value1"] });
|
|
},
|
|
|
|
tearDownAll : function () {
|
|
db._drop(cn);
|
|
},
|
|
|
|
testDisabled : function () {
|
|
let queries = [
|
|
"FOR doc IN " + cn + " RETURN doc",
|
|
"FOR doc IN " + cn + " LIMIT 100 RETURN doc",
|
|
"FOR doc IN " + cn + " SORT doc.value1 RETURN doc",
|
|
"FOR doc IN " + cn + " REMOVE doc IN " + cn + " RETURN doc",
|
|
"FOR doc IN " + cn + " REPLACE doc WITH {} IN " + cn + " RETURN doc",
|
|
"FOR doc IN " + cn + " UPDATE doc WITH {} IN " + cn + " RETURN doc",
|
|
];
|
|
|
|
queries.forEach(function(query) {
|
|
let result = AQL_EXPLAIN(query, null, { optimizer: { rules: ["-" + ruleName ] } });
|
|
assertEqual(-1, result.plan.rules.indexOf(ruleName), query);
|
|
});
|
|
},
|
|
|
|
testRuleNoEffect : function () {
|
|
let queries = [
|
|
"FOR i IN 1..1000 IN " + cn + " INSERT {} IN " + cn,
|
|
];
|
|
|
|
queries.forEach(function(query) {
|
|
let result = AQL_EXPLAIN(query);
|
|
assertEqual(-1, result.plan.rules.indexOf(ruleName), query);
|
|
});
|
|
},
|
|
|
|
testRuleHasEffect : function () {
|
|
let queries = [
|
|
"FOR doc IN " + cn + " RETURN doc",
|
|
"FOR doc IN " + cn + " LIMIT 1000 RETURN doc",
|
|
"FOR doc IN " + cn + " LIMIT 1000, 1000 RETURN doc",
|
|
"FOR doc IN " + cn + " SORT doc.value1 RETURN doc",
|
|
"FOR doc IN " + cn + " SORT doc.value1 LIMIT 1000 RETURN doc",
|
|
"FOR doc IN " + cn + " SORT doc.value1 LIMIT 1000, 1000 RETURN doc",
|
|
];
|
|
|
|
if (require("internal").options()["query.parallelize-gather-writes"]) {
|
|
queries.concat([
|
|
"FOR doc IN " + cn + " REMOVE doc IN " + cn,
|
|
"FOR doc IN " + cn + " REMOVE doc._key IN " + cn,
|
|
"FOR doc IN " + cn + " REPLACE doc WITH {} IN " + cn,
|
|
"FOR doc IN " + cn + " REPLACE doc WITH {a: 1} IN " + cn,
|
|
"FOR doc IN " + cn + " REPLACE doc._key WITH {} IN " + cn,
|
|
"FOR doc IN " + cn + " REPLACE doc._key WITH {a:1} IN " + cn,
|
|
"FOR doc IN " + cn + " UPDATE doc WITH {} IN " + cn,
|
|
"FOR doc IN " + cn + " UPDATE doc WITH {a: 1} IN " + cn,
|
|
"FOR doc IN " + cn + " UPDATE doc._key WITH {} IN " + cn,
|
|
"FOR doc IN " + cn + " UPDATE doc._key WITH {a:1} IN " + cn,
|
|
]);
|
|
}
|
|
|
|
queries.forEach(function(query) {
|
|
let result = AQL_EXPLAIN(query,);
|
|
assertNotEqual(-1, result.plan.rules.indexOf(ruleName), query);
|
|
});
|
|
},
|
|
|
|
testRuleHasEffectWrites : function () {
|
|
let queries = [
|
|
"FOR doc IN " + cn + " RETURN doc",
|
|
"FOR doc IN " + cn + " LIMIT 1000 RETURN doc",
|
|
"FOR doc IN " + cn + " LIMIT 1000, 1000 RETURN doc",
|
|
"FOR doc IN " + cn + " SORT doc.value1 RETURN doc",
|
|
"FOR doc IN " + cn + " SORT doc.value1 LIMIT 1000 RETURN doc",
|
|
"FOR doc IN " + cn + " SORT doc.value1 LIMIT 1000, 1000 RETURN doc",
|
|
];
|
|
|
|
if (require("internal").options()["query.parallelize-gather-writes"]) {
|
|
queries.concat([
|
|
"FOR doc IN " + cn + " REMOVE doc IN " + cn,
|
|
"FOR doc IN " + cn + " REMOVE doc._key IN " + cn,
|
|
"FOR doc IN " + cn + " REPLACE doc WITH {} IN " + cn,
|
|
"FOR doc IN " + cn + " REPLACE doc WITH {a: 1} IN " + cn,
|
|
"FOR doc IN " + cn + " REPLACE doc._key WITH {} IN " + cn,
|
|
"FOR doc IN " + cn + " REPLACE doc._key WITH {a:1} IN " + cn,
|
|
"FOR doc IN " + cn + " UPDATE doc WITH {} IN " + cn,
|
|
"FOR doc IN " + cn + " UPDATE doc WITH {a: 1} IN " + cn,
|
|
"FOR doc IN " + cn + " UPDATE doc._key WITH {} IN " + cn,
|
|
"FOR doc IN " + cn + " UPDATE doc._key WITH {a:1} IN " + cn,
|
|
]);
|
|
}
|
|
|
|
queries.forEach(function(query) {
|
|
let result = AQL_EXPLAIN(query,);
|
|
assertNotEqual(-1, result.plan.rules.indexOf(ruleName), query);
|
|
});
|
|
},
|
|
|
|
testResults : function () {
|
|
let queries = [
|
|
[ "FOR doc IN " + cn + " RETURN doc", 50000 ],
|
|
[ "FOR doc IN " + cn + " LIMIT 1000 RETURN doc", 1000 ],
|
|
[ "FOR doc IN " + cn + " LIMIT 1000, 1000 RETURN doc", 1000 ],
|
|
[ "FOR doc IN " + cn + " LIMIT 49500, 1000 RETURN doc", 500 ],
|
|
[ "FOR doc IN " + cn + " SORT doc.value1 RETURN doc", 50000 ],
|
|
[ "FOR doc IN " + cn + " SORT doc.value1 LIMIT 1000 RETURN doc", 1000 ],
|
|
[ "FOR doc IN " + cn + " SORT doc.value1 LIMIT 1000, 1000 RETURN doc", 1000 ],
|
|
[ "FOR doc IN " + cn + " SORT doc.value1 LIMIT 49500, 1000 RETURN doc", 500 ],
|
|
];
|
|
|
|
queries.forEach(function(query) {
|
|
let result = AQL_EXPLAIN(query[0]);
|
|
assertNotEqual(-1, result.plan.rules.indexOf(ruleName), query);
|
|
|
|
result = AQL_EXECUTE(query[0]).json;
|
|
assertEqual(query[1], result.length);
|
|
|
|
// compare if keys are unique and matching our expectations
|
|
let found = {};
|
|
result.forEach(function(doc) {
|
|
found[doc._key] = true;
|
|
});
|
|
assertEqual(query[1], Object.keys(found).length);
|
|
});
|
|
},
|
|
|
|
testSortedResults : function () {
|
|
let queries = [
|
|
[ "FOR doc IN " + cn + " SORT doc.value1 RETURN doc", 0, 50000 ],
|
|
[ "FOR doc IN " + cn + " SORT doc.value1 LIMIT 1000 RETURN doc", 0, 1000 ],
|
|
[ "FOR doc IN " + cn + " SORT doc.value1 LIMIT 1000, 1000 RETURN doc", 1000, 2000 ],
|
|
[ "FOR doc IN " + cn + " SORT doc.value1 LIMIT 49500, 1000 RETURN doc", 49500, 50000 ],
|
|
];
|
|
|
|
queries.forEach(function(query) {
|
|
let result = AQL_EXPLAIN(query[0]);
|
|
assertNotEqual(-1, result.plan.rules.indexOf(ruleName), query);
|
|
|
|
result = AQL_EXECUTE(query[0]).json;
|
|
|
|
// compare if keys are unique and matching our expectations
|
|
let expected = query[1];
|
|
result.forEach(function(doc) {
|
|
assertEqual(expected, doc.value1);
|
|
++expected;
|
|
});
|
|
assertEqual(query[2], expected);
|
|
});
|
|
},
|
|
|
|
};
|
|
}
|
|
|
|
jsunity.run(optimizerRuleTestSuite);
|
|
|
|
return jsunity.done();
|