mirror of https://gitee.com/bigwinds/arangodb
Merge branch 'devel' of https://github.com/arangodb/arangodb into vpack
This commit is contained in:
commit
1faaaa0632
|
@ -251,6 +251,7 @@ class Builder {
|
|||
std::shared_ptr<Buffer<uint8_t>> steal() {
|
||||
std::shared_ptr<Buffer<uint8_t>> res = std::move(_buffer);
|
||||
_buffer.reset(new Buffer<uint8_t>());
|
||||
_pos = 0;
|
||||
return res;
|
||||
}
|
||||
|
||||
|
@ -298,6 +299,8 @@ class Builder {
|
|||
return _pos;
|
||||
}
|
||||
|
||||
bool isEmpty() const throw() { return _pos == 0; }
|
||||
|
||||
bool isClosed() const throw() { return _stack.empty(); }
|
||||
|
||||
bool isOpenArray() const throw() {
|
||||
|
|
|
@ -479,6 +479,10 @@ AqlItemBlock* TraversalBlock::getSome (size_t, // atLeast,
|
|||
return res.release();
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief skipSome
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
size_t TraversalBlock::skipSome (size_t atLeast, size_t atMost) {
|
||||
size_t skipped = 0;
|
||||
|
||||
|
|
|
@ -444,6 +444,31 @@ function multiCollectionGraphSuite () {
|
|||
});
|
||||
},
|
||||
|
||||
testNoBindParameterSingleForFilter: function () {
|
||||
var query = "FOR s IN " + vn + " SORT s FOR x, e, p IN OUTBOUND s " +
|
||||
en + " FILTER p.vertices[1]._key == s._key SORT x RETURN x";
|
||||
var result = db._query(query).toArray();
|
||||
assertEqual(result.length, 0);
|
||||
var plans = AQL_EXPLAIN(query, { }, opts).plans;
|
||||
plans.forEach(function(plan) {
|
||||
var jsonResult = AQL_EXECUTEJSON(plan, { optimizer: { rules: [ "-all" ] } }).json;
|
||||
assertEqual(jsonResult.length, 0);
|
||||
});
|
||||
},
|
||||
|
||||
testNoBindParameterV8Function: function () {
|
||||
var query = "FOR s IN " + vn + " SORT s FOR x, e, p IN OUTBOUND s " +
|
||||
en + " FILTER p.vertices[1]._key == NOOPT(V8(RAND())) SORT x RETURN x";
|
||||
var result = db._query(query).toArray();
|
||||
assertEqual(result.length, 0);
|
||||
var plans = AQL_EXPLAIN(query, { }, opts).plans;
|
||||
plans.forEach(function(plan) {
|
||||
var jsonResult = AQL_EXECUTEJSON(plan, { optimizer: { rules: [ "-all" ] } }).json;
|
||||
assertEqual(jsonResult.length, 0);
|
||||
});
|
||||
},
|
||||
|
||||
|
||||
testNoBindParameter: function () {
|
||||
var query = "FOR x, e, p IN OUTBOUND '" + vertex.B + "' " + en + " RETURN {vertex: x, path: p}";
|
||||
var result = db._query(query).toArray();
|
||||
|
@ -744,6 +769,89 @@ function multiCollectionGraphSuite () {
|
|||
};
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
function multiEdgeCollectionGraphSuite () {
|
||||
|
||||
/***********************************************************************
|
||||
* Graph under test:
|
||||
*
|
||||
* B<----+ <- B & C via edge collection A
|
||||
* |
|
||||
* D<----A----<C
|
||||
* |
|
||||
* +----<E <- D & E via edge colltion B
|
||||
*
|
||||
***********************************************************************/
|
||||
|
||||
var g;
|
||||
const gn = "UnitTestGraph";
|
||||
const en2 = "UnitTestEdgeCollection2";
|
||||
var ruleName = "merge-traversal-filter";
|
||||
var paramEnabled = { optimizer: { rules: [ "-all", "+" + ruleName ] } };
|
||||
var opts = _.clone(paramEnabled);
|
||||
|
||||
return {
|
||||
|
||||
setUp: function() {
|
||||
opts.allPlans = true;
|
||||
opts.verbosePlans = true;
|
||||
cleanup();
|
||||
try {
|
||||
gm._drop(gn);
|
||||
} catch (e) {
|
||||
// It is expected that this graph does not exist.
|
||||
}
|
||||
|
||||
vc = db._create(vn, {numberOfShards: 4});
|
||||
ec = db._createEdgeCollection(en, {numberOfShards: 4});
|
||||
var ec2 = db._createEdgeCollection(en2, {numberOfShards: 4});
|
||||
|
||||
g = gm._create(gn, [gm._relation(en, vn, vn), gm._relation(en2, vn, vn)]);
|
||||
|
||||
vertex.A = vc.save({_key: "A"})._id;
|
||||
vertex.B = vc.save({_key: "B"})._id;
|
||||
vertex.C = vc.save({_key: "C"})._id;
|
||||
vertex.D = vc.save({_key: "D"})._id;
|
||||
vertex.E = vc.save({_key: "E"})._id;
|
||||
|
||||
edge.AB = ec.save(vertex.A, vertex.B, {})._id;
|
||||
edge.CA = ec.save(vertex.C, vertex.A, {})._id;
|
||||
edge.AD = ec2.save(vertex.A, vertex.D, {})._id;
|
||||
edge.EA = ec2.save(vertex.E, vertex.A, {})._id;
|
||||
},
|
||||
|
||||
tearDown: function() {
|
||||
gm._drop(gn);
|
||||
db._drop(vn);
|
||||
db._drop(en);
|
||||
db._drop(en2);
|
||||
cleanup();
|
||||
},
|
||||
|
||||
testTwoVertexCollectionsInOutbound: function () {
|
||||
/* this test is intended to trigger the clone functionality. */
|
||||
var expectResult = ['B', 'C', 'D', 'E'];
|
||||
var query = "FOR x IN ANY @startId GRAPH @graph SORT x._id RETURN x._key";
|
||||
var bindVars = {
|
||||
graph: gn,
|
||||
startId: vertex.A
|
||||
};
|
||||
|
||||
var result = db._query(query, bindVars).toArray();
|
||||
|
||||
assertEqual(result, expectResult, query);
|
||||
var plans = AQL_EXPLAIN(query, bindVars, opts).plans;
|
||||
plans.forEach(function(plan) {
|
||||
var jsonResult = AQL_EXECUTEJSON(plan, { optimizer: { rules: [ "-all" ] } }).json;
|
||||
assertEqual(jsonResult, result, query);
|
||||
});
|
||||
},
|
||||
|
||||
};
|
||||
}
|
||||
|
||||
function potentialErrorsSuite () {
|
||||
var vc, ec;
|
||||
|
||||
|
@ -1557,6 +1665,7 @@ function brokenGraphSuite () {
|
|||
|
||||
jsunity.run(namedGraphSuite);
|
||||
jsunity.run(multiCollectionGraphSuite);
|
||||
jsunity.run(multiEdgeCollectionGraphSuite);
|
||||
jsunity.run(potentialErrorsSuite);
|
||||
jsunity.run(complexInternaSuite);
|
||||
jsunity.run(complexFilteringSuite);
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*jshint globalstrict:false, strict:false, maxlen: 500 */
|
||||
/*global assertEqual, assertTrue, assertNotEqual, AQL_EXPLAIN, AQL_EXECUTE */
|
||||
/*global assertEqual, assertTrue, assertNotEqual, AQL_EXPLAIN, AQL_EXECUTE, AQL_EXECUTEJSON */
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief tests for optimizer rules
|
||||
|
@ -31,6 +31,7 @@
|
|||
var jsunity = require("jsunity");
|
||||
var helper = require("@arangodb/aql-helper");
|
||||
var isEqual = helper.isEqual;
|
||||
var _ = require("underscore");
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief test suite
|
||||
|
@ -41,7 +42,9 @@ function optimizerRuleTestSuite () {
|
|||
// various choices to control the optimizer:
|
||||
var paramEnabled = { optimizer: { rules: [ "-all", "+" + ruleName ] } };
|
||||
var paramDisabled = { optimizer: { rules: [ "+all", "-" + ruleName ] } };
|
||||
var graphName = "myGraph";
|
||||
var graphName = "myUnittestGraph";
|
||||
var opts = _.clone(paramEnabled);
|
||||
|
||||
return {
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
@ -50,7 +53,10 @@ function optimizerRuleTestSuite () {
|
|||
|
||||
setUp : function () {
|
||||
var graph_module = require("@arangodb/general-graph");
|
||||
opts.allPlans = true;
|
||||
opts.verbosePlans = true;
|
||||
|
||||
try { graph_module._drop(graphName, true); } catch (x) {}
|
||||
|
||||
var graph = graph_module._create(graphName, [
|
||||
graph_module._relation("edges", "circles", ["circles"])]);
|
||||
|
@ -72,8 +78,6 @@ function optimizerRuleTestSuite () {
|
|||
graph.edges.save("circles/B", "circles/E", {theFalse: false, theTruth: true, "label": 'blub'});
|
||||
graph.edges.save("circles/C", "circles/F", {theFalse: false, theTruth: true, "label": 'schubi'});
|
||||
graph.edges.save("circles/C", "circles/G", {theFalse: false, theTruth: true, "label": 'doo'});
|
||||
|
||||
|
||||
},
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
@ -92,11 +96,11 @@ function optimizerRuleTestSuite () {
|
|||
|
||||
testRuleNoEffect : function () {
|
||||
var queries = [
|
||||
"FOR v, e, p IN 1..5 OUTBOUND 'circles/A' GRAPH 'myGraph' LET localScopeVar = NOOPT(true) FILTER p.edges[0].theTruth == localScopeVar return {v:v,e:e,p:p}",
|
||||
"FOR v, e, p IN 1..5 OUTBOUND 'circles/A' GRAPH 'myGraph' FILTER p.edges[-1].theTruth == true return {v:v,e:e,p:p}",
|
||||
"FOR v, e, p IN 1..5 OUTBOUND 'circles/A' GRAPH 'myGraph' FILTER p.edges[*].theTruth == true or p.edges[1].label == 'bar' return {v:v,e:e,p:p}",
|
||||
"FOR v, e, p IN 1..5 OUTBOUND 'circles/A' GRAPH 'myGraph' FILTER p.edges[RAND()].theFalse == false return {v:v,e:e,p:p}",
|
||||
"FOR v, e, p IN 1..5 OUTBOUND 'circles/A' GRAPH 'myGraph' FILTER p.edges[p.edges.length - 1].theFalse == false return {v:v,e:e,p:p}"
|
||||
"FOR v, e, p IN 1..5 OUTBOUND 'circles/A' GRAPH '" + graphName + "' LET localScopeVar = NOOPT(true) FILTER p.edges[0].theTruth == localScopeVar return {v:v,e:e,p:p}",
|
||||
"FOR v, e, p IN 1..5 OUTBOUND 'circles/A' GRAPH '" + graphName + "' FILTER p.edges[-1].theTruth == true return {v:v,e:e,p:p}",
|
||||
"FOR v, e, p IN 1..5 OUTBOUND 'circles/A' GRAPH '" + graphName + "' FILTER p.edges[*].theTruth == true or p.edges[1].label == 'bar' return {v:v,e:e,p:p}",
|
||||
"FOR v, e, p IN 1..5 OUTBOUND 'circles/A' GRAPH '" + graphName + "' FILTER p.edges[RAND()].theFalse == false return {v:v,e:e,p:p}",
|
||||
"FOR v, e, p IN 1..5 OUTBOUND 'circles/A' GRAPH '" + graphName + "' FILTER p.edges[p.edges.length - 1].theFalse == false return {v:v,e:e,p:p}"
|
||||
];
|
||||
|
||||
queries.forEach(function(query) {
|
||||
|
@ -111,11 +115,11 @@ function optimizerRuleTestSuite () {
|
|||
|
||||
testRuleHasEffect : function () {
|
||||
var queries = [
|
||||
"FOR v, e, p IN 1..5 OUTBOUND 'circles/A' GRAPH 'myGraph' FILTER p.edges[0].theTruth == true return {v:v,e:e,p:p}",
|
||||
"FOR v, e, p IN 1..5 OUTBOUND 'circles/A' GRAPH 'myGraph' FILTER p.edges[1].theTruth == true return {v:v,e:e,p:p}",
|
||||
"FOR v, e, p IN 1..5 OUTBOUND 'circles/A' GRAPH 'myGraph' FILTER p.edges[2].theTruth == true return {v:v,e:e,p:p}",
|
||||
"FOR v, e, p IN 1..5 OUTBOUND 'circles/A' GRAPH 'myGraph' FILTER p.edges[2].theTruth == true AND p.edges[1].label == 'bar' return {v:v,e:e,p:p}",
|
||||
"FOR v, e, p IN 1..5 OUTBOUND 'circles/A' GRAPH 'myGraph' FILTER p.edges[0].theTruth == true FILTER p.edges[1].label == 'bar' return {v:v,e:e,p:p}"
|
||||
"FOR v, e, p IN 1..5 OUTBOUND 'circles/A' GRAPH '" + graphName + "' FILTER p.edges[0].theTruth == true return {v:v,e:e,p:p}",
|
||||
"FOR v, e, p IN 1..5 OUTBOUND 'circles/A' GRAPH '" + graphName + "' FILTER p.edges[1].theTruth == true return {v:v,e:e,p:p}",
|
||||
"FOR v, e, p IN 1..5 OUTBOUND 'circles/A' GRAPH '" + graphName + "' FILTER p.edges[2].theTruth == true return {v:v,e:e,p:p}",
|
||||
"FOR v, e, p IN 1..5 OUTBOUND 'circles/A' GRAPH '" + graphName + "' FILTER p.edges[2].theTruth == true AND p.edges[1].label == 'bar' return {v:v,e:e,p:p}",
|
||||
"FOR v, e, p IN 1..5 OUTBOUND 'circles/A' GRAPH '" + graphName + "' FILTER p.edges[0].theTruth == true FILTER p.edges[1].label == 'bar' return {v:v,e:e,p:p}"
|
||||
];
|
||||
|
||||
queries.forEach(function(query) {
|
||||
|
@ -130,12 +134,12 @@ function optimizerRuleTestSuite () {
|
|||
|
||||
testResults : function () {
|
||||
var queries = [
|
||||
"FOR v, e, p IN 1..5 OUTBOUND 'circles/A' GRAPH 'myGraph' FILTER p.edges[0].label == 'foo' return {v:v,e:e,p:p}",
|
||||
"FOR v, e, p IN 1..5 OUTBOUND 'circles/A' GRAPH 'myGraph' FILTER p.edges[1].label == 'foo' return {v:v,e:e,p:p}",
|
||||
"FOR v, e, p IN 1..5 OUTBOUND 'circles/A' GRAPH 'myGraph' FILTER p.edges[0].theTruth == true FILTER p.edges[0].label == 'foo' return {v:v,e:e,p:p}",
|
||||
"FOR v, e, p IN 1..5 OUTBOUND 'circles/A' GRAPH 'myGraph' FILTER p.edges[0].theTruth == true FILTER p.edges[1].label == 'foo' return {v:v,e:e,p:p}",
|
||||
"FOR v, e, p IN 1..5 OUTBOUND 'circles/A' GRAPH 'myGraph' FILTER p.edges[0].theTruth == true FILTER p.edges[0].label == 'foo' return {v:v,e:e,p:p}",
|
||||
"FOR v, e, p IN 1..5 OUTBOUND 'circles/A' GRAPH 'myGraph' FILTER p.edges[1].theTruth == true FILTER p.edges[1].label == 'foo' return {v:v,e:e,p:p}",
|
||||
"FOR v, e, p IN 1..5 OUTBOUND 'circles/A' GRAPH '" + graphName + "' FILTER p.edges[0].label == 'foo' return {v:v,e:e,p:p}",
|
||||
"FOR v, e, p IN 1..5 OUTBOUND 'circles/A' GRAPH '" + graphName + "' FILTER p.edges[1].label == 'foo' return {v:v,e:e,p:p}",
|
||||
"FOR v, e, p IN 1..5 OUTBOUND 'circles/A' GRAPH '" + graphName + "' FILTER p.edges[0].theTruth == true FILTER p.edges[0].label == 'foo' return {v:v,e:e,p:p}",
|
||||
"FOR v, e, p IN 1..5 OUTBOUND 'circles/A' GRAPH '" + graphName + "' FILTER p.edges[0].theTruth == true FILTER p.edges[1].label == 'foo' return {v:v,e:e,p:p}",
|
||||
"FOR v, e, p IN 1..5 OUTBOUND 'circles/A' GRAPH '" + graphName + "' FILTER p.edges[0].theTruth == true FILTER p.edges[0].label == 'foo' return {v:v,e:e,p:p}",
|
||||
"FOR v, e, p IN 1..5 OUTBOUND 'circles/A' GRAPH '" + graphName + "' FILTER p.edges[1].theTruth == true FILTER p.edges[1].label == 'foo' return {v:v,e:e,p:p}",
|
||||
];
|
||||
|
||||
queries.forEach(function(query) {
|
||||
|
@ -149,6 +153,12 @@ function optimizerRuleTestSuite () {
|
|||
assertEqual(-1, planDisabled.plan.rules.indexOf(ruleName), query);
|
||||
assertNotEqual(-1, planEnabled.plan.rules.indexOf(ruleName), query);
|
||||
|
||||
var plans = AQL_EXPLAIN(query, {}, opts).plans;
|
||||
plans.forEach(function(plan) {
|
||||
var jsonResult = AQL_EXECUTEJSON(plan, { optimizer: { rules: [ "-all" ] } }).json;
|
||||
assertEqual(jsonResult, resultDisabled, query);
|
||||
});
|
||||
|
||||
});
|
||||
},
|
||||
|
||||
|
@ -160,10 +170,10 @@ function optimizerRuleTestSuite () {
|
|||
testNoResults : function () {
|
||||
var queries = [
|
||||
// sure shot: 5 < 7
|
||||
"FOR v, e, p IN 1..5 OUTBOUND 'circles/A' GRAPH 'myGraph' FILTER p.edges[7].label == 'foo' return {v:v,e:e,p:p}",
|
||||
"FOR v, e, p IN 1..5 OUTBOUND 'circles/A' GRAPH '" + graphName + "' FILTER p.edges[7].label == 'foo' return {v:v,e:e,p:p}",
|
||||
// indexed access starts with 0 - this is also forbidden since it will look for the 6th!
|
||||
"FOR v, e, p IN 1..5 OUTBOUND 'circles/A' GRAPH 'myGraph' FILTER p.edges[5].label == 'foo' return {v:v,e:e,p:p}",
|
||||
"FOR v, e, p IN 5..1 OUTBOUND 'circles/A' GRAPH 'myGraph' FILTER p.edges[1].label == 'foo' return {v:v,e:e,p:p}"
|
||||
"FOR v, e, p IN 1..5 OUTBOUND 'circles/A' GRAPH '" + graphName + "' FILTER p.edges[5].label == 'foo' return {v:v,e:e,p:p}",
|
||||
"FOR v, e, p IN 5..1 OUTBOUND 'circles/A' GRAPH '" + graphName + "' FILTER p.edges[1].label == 'foo' return {v:v,e:e,p:p}"
|
||||
// TODO: right now we're not clever enough to find this:
|
||||
// "FOR v, e, p IN 1..5 OUTBOUND 'circles/A' GRAPH 'myGraph' FILTER p.edges[1].label == 'foo' AND p.edges[1].label == 'bar' return {v:v,e:e,p:p}"
|
||||
];
|
||||
|
|
Loading…
Reference in New Issue