mirror of https://gitee.com/bigwinds/arangodb
Fix single shard restriction with binary and. (#6549)
This commit is contained in:
parent
380bb71192
commit
282159ec2c
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
|
Loading…
Reference in New Issue