1
0
Fork 0

Fix single shard restriction with binary and. (#6549)

This commit is contained in:
Dan Larkin-York 2018-09-19 17:40:55 -04:00 committed by Jan
parent 380bb71192
commit 282159ec2c
2 changed files with 114 additions and 20 deletions

View File

@ -478,27 +478,36 @@ void findShardKeysInExpression(arangodb::aql::AstNode const* root,
return;
}
if (root->type == arangodb::aql::AstNodeType::NODE_TYPE_OPERATOR_NARY_OR) {
if (root->numMembers() != 1) {
return;
}
root = root->getMember(0);
if (root == nullptr ||
root->type != arangodb::aql::AstNodeType::NODE_TYPE_OPERATOR_NARY_AND) {
return;
}
for (size_t i = 0; i < root->numMembers(); ++i) {
if (root->getMember(i) != nullptr &&
root->getMember(i)->type ==
arangodb::aql::AstNodeType::NODE_TYPE_OPERATOR_BINARY_EQ) {
findShardKeyInComparison(root->getMember(i), inputVariable, toFind,
builder);
switch (root->type) {
case arangodb::aql::AstNodeType::NODE_TYPE_OPERATOR_NARY_OR: {
if (root->numMembers() != 1) {
return;
}
root = root->getMember(0);
if (root == nullptr ||
root->type !=
arangodb::aql::AstNodeType::NODE_TYPE_OPERATOR_NARY_AND) {
return;
}
} // falls through
case arangodb::aql::AstNodeType::NODE_TYPE_OPERATOR_BINARY_AND:
case arangodb::aql::AstNodeType::NODE_TYPE_OPERATOR_NARY_AND: {
for (size_t i = 0; i < root->numMembers(); ++i) {
if (root->getMember(i) != nullptr &&
root->getMember(i)->type ==
arangodb::aql::AstNodeType::NODE_TYPE_OPERATOR_BINARY_EQ) {
findShardKeyInComparison(root->getMember(i), inputVariable, toFind,
builder);
}
}
break;
}
} else if (root->type ==
arangodb::aql::AstNodeType::NODE_TYPE_OPERATOR_BINARY_EQ) {
findShardKeyInComparison(root, inputVariable, toFind, builder);
case arangodb::aql::AstNodeType::NODE_TYPE_OPERATOR_BINARY_EQ: {
findShardKeyInComparison(root, inputVariable, toFind, builder);
break;
}
default:
break;
}
}

View File

@ -123,6 +123,7 @@ function ahuacatlShardIdsOptimizationTestSuite() {
const shardKey = "value";
const shardKey1 = "value";
const shardKey2 = "value";
const extraKey = "extra";
const numberOfShards = 9;
const tearDown = () => {
@ -182,7 +183,7 @@ function ahuacatlShardIdsOptimizationTestSuite() {
let docs = [];
for (let i = 0; i < 100; ++i) {
docs.push({ "value" : i % 25, "joinValue" : i % 5 });
docs.push({ "value" : i % 25, "joinValue" : i % 5, "extra": true });
}
collection.save(docs);
@ -428,6 +429,90 @@ function ahuacatlShardIdsOptimizationTestSuite() {
}
},
testMultipleKeysSameFilter: function () {
dropIndexes(collectionByKey);
collectionByKey.ensureHashIndex(shardKey);
for (let i = 0; i < 24; ++i) {
const query = `
FOR doc IN ${cnKey}
FILTER doc.${shardKey} == ${i} && doc.${extraKey} == true
RETURN doc
`;
validatePlan(query, "IndexNode", collectionByKey);
let res = db._query(query, {}, disableSingleDocOp).toArray();
assertEqual(4, res.length);
for (let doc of res) {
assertTrue(i === doc.value);
assertTrue(true === doc.extra);
}
}
},
testMultipleKeysSameFilterNoIndex: function () {
dropIndexes(collectionByKey);
for (let i = 0; i < 24; ++i) {
const query = `
FOR doc IN ${cnKey}
FILTER doc.${shardKey} == ${i} && doc.${extraKey} == true
RETURN doc
`;
validatePlan(query, "EnumerateCollectionNode", collectionByKey);
let res = db._query(query, {}, disableSingleDocOp).toArray();
assertEqual(4, res.length);
for (let doc of res) {
assertTrue(i === doc.value);
assertTrue(true === doc.extra);
}
}
},
testMultipleKeysDifferentFilter: function () {
dropIndexes(collectionByKey);
collectionByKey.ensureHashIndex(shardKey);
for (let i = 0; i < 24; ++i) {
const query = `
FOR doc IN ${cnKey}
FILTER doc.${shardKey} == ${i}
FILTER doc.${extraKey} == true
RETURN doc
`;
validatePlan(query, "IndexNode", collectionByKey);
let res = db._query(query, {}, disableSingleDocOp).toArray();
assertEqual(4, res.length);
for (let doc of res) {
assertTrue(i === doc.value);
assertTrue(true === doc.extra);
}
}
},
testMultipleKeysDifferentFilterNoIndex: function () {
dropIndexes(collectionByKey);
for (let i = 0; i < 24; ++i) {
const query = `
FOR doc IN ${cnKey}
FILTER doc.${shardKey} == ${i}
FILTER doc.${extraKey} == true
RETURN doc
`;
validatePlan(query, "EnumerateCollectionNode", collectionByKey);
let res = db._query(query, {}, disableSingleDocOp).toArray();
assertEqual(4, res.length);
for (let doc of res) {
assertTrue(i === doc.value);
assertTrue(true === doc.extra);
}
}
},
testMultipleShardsOr : function () {
dropIndexes(collectionByKey);
collectionByKey.ensureHashIndex(shardKey);