1
0
Fork 0

Allow the optimizer to use indexes

when a collection attribute is compared to anexpansion followed by an attribute name, e.g. `doc.value IN something[*].name`.
This commit is contained in:
jsteemann 2019-11-25 17:08:04 +01:00
parent c4a4f6154d
commit 2ad9e7e65e
3 changed files with 38 additions and 2 deletions

View File

@ -1,6 +1,9 @@
v3.4.9 (XXXX-XX-XX)
-------------------
* Allow the optimizer to use indexes when a collection attribute is compared to an
expansion followed by an attribute name, e.g. `doc.value IN something[*].name`.
* Make the timeouts for replication requests (for active failover and master-slave
replication configurable via startup options:

View File

@ -798,8 +798,7 @@ bool Index::canUseConditionPart(arangodb::aql::AstNode const* access,
other->type == arangodb::aql::NODE_TYPE_ATTRIBUTE_ACCESS)) {
// value IN a.b OR value IN a.b[*]
arangodb::aql::Ast::getReferencedVariables(access, variables);
if (other->type == arangodb::aql::NODE_TYPE_ATTRIBUTE_ACCESS &&
variables.find(reference) != variables.end()) {
if (variables.find(reference) != variables.end()) {
variables.clear();
arangodb::aql::Ast::getReferencedVariables(other, variables);
}

View File

@ -54,6 +54,40 @@ function optimizerIndexesTestSuite () {
db._drop("UnitTestsCollection");
},
testIndexUsedForExpansion1 : function () {
let query = "LET test = NOOPT([{ value: 1 }, { value : 2 }]) FOR doc IN " + c.name() + " FILTER doc.value IN test[*].value SORT doc.value RETURN doc.value";
let plan = AQL_EXPLAIN(query).plan;
let nodeTypes = plan.nodes.map(function(node) {
return node.type;
});
assertEqual("SingletonNode", nodeTypes[0], query);
assertNotEqual(-1, nodeTypes.indexOf("IndexNode"), query);
let results = AQL_EXECUTE(query);
assertEqual([ 1, 2 ], results.json, query);
assertEqual(0, results.stats.scannedFull);
assertTrue(results.stats.scannedIndex > 0);
},
testIndexUsedForExpansion2 : function () {
let query = "LET test = NOOPT([1, 2]) FOR doc IN " + c.name() + " FILTER doc.value IN test[*] SORT doc.value RETURN doc.value";
let plan = AQL_EXPLAIN(query).plan;
let nodeTypes = plan.nodes.map(function(node) {
return node.type;
});
assertEqual("SingletonNode", nodeTypes[0], query);
assertNotEqual(-1, nodeTypes.indexOf("IndexNode"), query);
let results = AQL_EXECUTE(query);
assertEqual([ 1, 2 ], results.json, query);
assertEqual(0, results.stats.scannedFull);
assertTrue(results.stats.scannedIndex > 0);
},
testMultiIndexesOrCondition : function () {
let values = [
[ "abc", true, true ],