8000 Fix single shard restriction with binary and. (#6549) · soualid/arangodb@282159e · GitHub
[go: up one dir, main page]

Skip to content

Commit 282159e

Browse files
Dan Larkin-Yorkjsteemann
Dan Larkin-York
authored andcommitted
Fix single shard restriction with binary and. (arangodb#6549)
1 parent 380bb71 commit 282159e

File tree

2 files changed

+114
-20
lines changed

2 files changed

+114
-20
lines changed

arangod/Aql/OptimizerRules.cpp

Lines changed: 28 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -478,27 +478,36 @@ void findShardKeysInExpression(arangodb::aql::AstNode const* root,
478478
return;
479479
}
480480

481-
if (root->type == arangodb::aql::AstNodeType::NODE_TYPE_OPERATOR_NARY_OR) {
482-
if (root->numMembers() != 1) {
483-
return;
484-
}
485-
root = root->getMember(0);
486-
if (root == nullptr ||
487-
root->type != arangodb::aql::AstNodeType::NODE_TYPE_OPERATOR_NARY_AND) {
488-
return;
489-
}
490-
491-
for (size_t i = 0; i < root->numMembers(); ++i) {
492-
if (root->getMember(i) != nullptr &&
493-
root->getMember(i)->type ==
494-
arangodb::aql::AstNodeType::NODE_TYPE_OPERATOR_BINARY_EQ) {
495-
findShardKeyInComparison(root->getMember(i), inputVariable, toFind,
496-
builder);
481+
switch (root->type) {
482+
case arangodb::aql::AstNodeType::NODE_TYPE_OPERATOR_NARY_OR: {
483+
if (root->numMembers() != 1) {
484+
return;
485+
}
486+
root = root->getMember(0);
487+
if (root == nullptr ||
488+
root->type !=
489+
arangodb::aql::AstNodeType::NODE_TYPE_OPERATOR_NARY_AND) {
490+
return;
497491
}
492+
} // falls through
493+
case arangodb::aql::AstNodeType::NODE_TYPE_OPERATOR_BINARY_AND:
494+
case arangodb::aql::AstNodeType::NODE_TYPE_OPERATOR_NARY_AND: {
495+
for (size_t i = 0; i < root->numMembers(); ++i) {
496+
if (root->getMember(i) != nullptr &&
497+
root->getMember(i)->type ==
498+
arangodb::aql::AstNodeType::NODE_TYPE_OPERATOR_BINARY_EQ) {
499+
findShardKeyInComparison(root->getMember(i), inputVariable, toFind,
500+
builder);
501+
}
502+
}
503+
break;
498504
}
499-
} else if (root->type ==
500-
arangodb::aql::AstNodeType::NODE_TYPE_OPERATOR_BINARY_EQ) {
501-
findShardKeyInComparison(root, inputVariable, toFind, builder);
505+
case arangodb::aql::AstNodeType::NODE_TYPE_OPERATOR_BINARY_EQ: {
506+
findShardKeyInComparison(root, inputVariable, toFind, builder);
507+
break;
508+
}
509+
default:
510+
break;
502511
}
503512
}
504513

tests/js/server/aql/aql-shardids-cluster.js

Lines changed: 86 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -123,6 +123,7 @@ function ahuacatlShardIdsOptimizationTestSuite() {
123123
const shardKey = "value";
124124
const shardKey1 = "value";
125125
const shardKey2 = "value";
126+
const extraKey = "extra";
126127
const numberOfShards = 9;
127128

128129
const tearDown = () => {
@@ -182,7 +183,7 @@ function ahuacatlShardIdsOptimizationTestSuite() {
182183
let docs = [];
183184

184185
for (let i = 0; i < 100; ++i) {
185-
docs.push({ "value" : i % 25, "joinValue" : i % 5 });
186+
docs.push({ "value" : i % 25, "joinValue" : i % 5, "extra": true });
186187
}
187188

188189
collection.save(docs);
@@ -428,6 +429,90 @@ function ahuacatlShardIdsOptimizationTestSuite() {
428429
}
429430
},
430431

432+
testMultipleKeysSameFilter: function () {
433+
dropIndexes(collectionByKey);
434+
collectionByKey.ensureHashIndex(shardKey);
435+
436+
for (let i = 0; i < 24; ++i) {
437+
const query = `
438+
FOR doc IN ${cnKey}
439+
FILTER doc.${shardKey} == ${i} && doc.${extraKey} == true
440+
RETURN doc
441+
`;
442+
validatePlan(query, "IndexNode", collectionByKey);
443+
444+
let res = db._query(query, {}, disableSingleDocOp).toArray();
445+
assertEqual(4, res.length);
446+
for (let doc of res) {
447+
assertTrue(i === doc.value);
448+
assertTrue(true === doc.extra);
449+
}
450+
}
451+
},
452+
453+
testMultipleKeysSameFilterNoIndex: function () {
454+
dropIndexes(collectionByKey);
455+
456+
for (let i = 0; i < 24; ++i) {
457+
const query = `
458+
FOR doc IN ${cnKey}
459+
FILTER doc.${shardKey} == ${i} && doc.${extraKey} == true
460+
RETURN doc
461+
`;
462+
validatePlan(query, "EnumerateCollectionNode", collectionByKey);
463+
464+
let res = db._query(query, {}, disableSingleDocOp).toArray();
465+
assertEqual(4, res.length);
466+
for (let doc of res) {
467+
assertTrue(i === doc.value);
468+
assertTrue(true === doc.extra);
469+
}
470+
}
471+
},
472+
473+
testMultipleKeysDifferentFilter: function () {
474+
dropIndexes(collectionByKey);
475+
collectionByKey.ensureHashIndex(shardKey);
476+
477+
for (let i = 0; i < 24; ++i) {
478+
const query = `
479+
FOR doc IN ${cnKey}
480+
FILTER doc.${shardKey} == ${i}
481+
FILTER doc.${extraKey} == true
482+
RETURN doc
483+
`;
484+
validatePlan(query, "IndexNode", collectionByKey);
485+
486+
let res = db._query(query, {}, disableSingleDocOp).toArray();
487+
assertEqual(4, res.length);
488+
for (let doc of res) {
489+
assertTrue(i === doc.value);
490+
assertTrue(true === doc.extra);
491+
}
492+
}
493+
},
494+
495+
testMultipleKeysDifferentFilterNoIndex: function () {
496+
dropIndexes(collectionByKey);
497+
498+
for (let i = 0; i < 24; ++i) {
499+
const query = `
500+
FOR doc IN ${cnKey}
501+
FILTER doc.${shardKey} == ${i}
502+
FILTER doc.${extraKey} == true
503+
RETURN doc
504+
`;
505+
validatePlan(query, "EnumerateCollectionNode", collectionByKey);
506+
507+
let res = db._query(query, {}, disableSingleDocOp).toArray();
508+
assertEqual(4, res.length);
509+
for (let doc of res) {
510+
assertTrue(i === doc.value);
511+
assertTrue(true === doc.extra);
512+
}
513+
}
514+
},
515+
431516
testMultipleShardsOr : function () {
432517
dropIndexes(collectionByKey);
433518
collectionByKey.ensureHashIndex(shardKey);

0 commit comments

Comments
 (0)
0