mirror of https://gitee.com/bigwinds/arangodb
2861 lines
88 KiB
JavaScript
2861 lines
88 KiB
JavaScript
/*jshint globalstrict:false, strict:false, maxlen: 500 */
|
|
/*global assertEqual, assertTrue, assertFalse, AQL_EXECUTE, AQL_EXPLAIN */
|
|
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
/// @brief tests for query language, limit optimizations
|
|
///
|
|
/// @file
|
|
///
|
|
/// DISCLAIMER
|
|
///
|
|
/// Copyright 2010-2012 triagens GmbH, Cologne, Germany
|
|
///
|
|
/// Licensed under the Apache License, Version 2.0 (the "License");
|
|
/// you may not use this file except in compliance with the License.
|
|
/// You may obtain a copy of the License at
|
|
///
|
|
/// http://www.apache.org/licenses/LICENSE-2.0
|
|
///
|
|
/// Unless required by applicable law or agreed to in writing, software
|
|
/// distributed under the License is distributed on an "AS IS" BASIS,
|
|
/// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
/// See the License for the specific language governing permissions and
|
|
/// limitations under the License.
|
|
///
|
|
/// Copyright holder is triAGENS GmbH, Cologne, Germany
|
|
///
|
|
/// @author Jan Steemann
|
|
/// @author Copyright 2012, triAGENS GmbH, Cologne, Germany
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
|
|
var jsunity = require("jsunity");
|
|
var internal = require("internal");
|
|
var db = internal.db;
|
|
const disableSingleDocOp = {
|
|
optimizer: {
|
|
rules: [ "-optimize-cluster-single-document-operations"]
|
|
}
|
|
};
|
|
const disableSingleShard = {
|
|
optimizer: {
|
|
rules: [ "-restrict-to-single-shard"]
|
|
}
|
|
};
|
|
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
/// @brief test suite
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
|
|
function ahuacatlShardIdsTestSuite () {
|
|
var collection = null;
|
|
var cn = "UnitTestsShardIds";
|
|
|
|
return {
|
|
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
/// @brief set up
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
|
|
setUpAll : function () {
|
|
internal.db._drop(cn);
|
|
collection = internal.db._create(cn, { numberOfShards: 4 });
|
|
|
|
let docs = [];
|
|
for (var i = 0; i < 100; ++i) {
|
|
docs.push({ "value" : i });
|
|
}
|
|
collection.insert(docs);
|
|
|
|
var result = collection.count(true);
|
|
var sum = 0;
|
|
var shards = Object.keys(result);
|
|
assertEqual(4, shards.length);
|
|
shards.forEach(function(key) {
|
|
sum += result[key];
|
|
});
|
|
assertEqual(100, sum);
|
|
},
|
|
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
/// @brief tear down
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
|
|
tearDownAll : function () {
|
|
internal.db._drop(cn);
|
|
},
|
|
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
/// @brief no restriction to a shard
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
|
|
testQueryUnrestricted : function () {
|
|
var query = "FOR doc IN " + cn + " RETURN 1";
|
|
|
|
var actual = AQL_EXECUTE(query);
|
|
assertEqual(100, actual.json.length);
|
|
},
|
|
|
|
testQueryRestrictedToShards : function () {
|
|
var count = collection.count(true);
|
|
var shards = Object.keys(count);
|
|
var query = "FOR doc IN " + cn + " RETURN 1";
|
|
|
|
assertTrue(shards.length > 1);
|
|
var sum = 0;
|
|
shards.forEach(function(s) {
|
|
var actual = AQL_EXECUTE(query, null, { shardIds: [ s ] });
|
|
assertEqual(count[s], actual.json.length);
|
|
sum += actual.json.length;
|
|
});
|
|
|
|
assertEqual(100, sum);
|
|
}
|
|
};
|
|
}
|
|
|
|
function ahuacatlShardIdsOptimizationTestSuite() {
|
|
let collection = null;
|
|
let collectionByKey = null;
|
|
let collectionByKey1 = null;
|
|
let collectionByKey2 = null;
|
|
const cn = "UnitTestsShardIds";
|
|
const cnKey = "UnitTestsShardIdsShardKey";
|
|
const cnKey1 = "UnitTestsShardIdsShardKey1";
|
|
const cnKey2 = "UnitTestsShardIdsShardKey2";
|
|
const shardKey = "value";
|
|
const shardKey1 = "value";
|
|
const shardKey2 = "value";
|
|
const extraKey = "extra";
|
|
const numberOfShards = 9;
|
|
|
|
const tearDown = () => {
|
|
db._drop(cn);
|
|
db._drop(cnKey);
|
|
db._drop(cnKey1);
|
|
db._drop(cnKey2);
|
|
};
|
|
|
|
const allNodesOfTypeAreRestrictedToShard = (nodes, typeName, col) => {
|
|
let relevantNodes = nodes.filter( node =>
|
|
node.type === typeName && node.collection === col.name());
|
|
assertTrue(relevantNodes.length !== 0);
|
|
return relevantNodes.every(
|
|
node => col.shards().indexOf(node.restrictedTo) !== -1);
|
|
};
|
|
|
|
const hasDistributeNode = nodes => {
|
|
return (nodes.filter(node => node.type === 'DistributeNode')).length > 0;
|
|
};
|
|
|
|
const validatePlan = (query, nodeType, c) => {
|
|
const plan = AQL_EXPLAIN(query, {}, disableSingleDocOp).plan;
|
|
assertFalse(hasDistributeNode(plan.nodes));
|
|
const allRestricted = allNodesOfTypeAreRestrictedToShard(plan.nodes,
|
|
nodeType, c);
|
|
if (!allRestricted) {
|
|
db._explain(query, {}, disableSingleDocOp);
|
|
}
|
|
assertTrue(allRestricted);
|
|
};
|
|
|
|
const dropIndexes = (col) => {
|
|
let indexes = col.getIndexes();
|
|
for (const idx of indexes) {
|
|
if (idx.type !== "primary" && idx.type !== "edge") {
|
|
col.dropIndex(idx.id);
|
|
}
|
|
}
|
|
};
|
|
|
|
return {
|
|
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
/// @brief set up
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
|
|
setUpAll : function () {
|
|
tearDown();
|
|
collection = internal.db._create(cn, { numberOfShards });
|
|
collectionByKey = internal.db._create(
|
|
cnKey, { numberOfShards, shardKeys: [shardKey] });
|
|
collectionByKey1 = internal.db._create(
|
|
cnKey1, { numberOfShards, shardKeys: [shardKey1] });
|
|
collectionByKey2 = internal.db._create(
|
|
cnKey2, { numberOfShards, shardKeys: [shardKey2] });
|
|
let docs = [];
|
|
|
|
for (let i = 0; i < 100; ++i) {
|
|
docs.push({ "value" : i % 25, "joinValue" : i % 5, "extra": true });
|
|
}
|
|
|
|
collection.save(docs);
|
|
collectionByKey.save(docs);
|
|
collectionByKey1.save(docs);
|
|
collectionByKey2.save(docs);
|
|
let fullCounts = collection.count(true);
|
|
|
|
let shardsToCount = new Map();
|
|
for (const [shard, count] of Object.entries(fullCounts)) {
|
|
shardsToCount.set(shard, count);
|
|
}
|
|
assertEqual(numberOfShards, shardsToCount.size);
|
|
let sum = 0;
|
|
for (let c of shardsToCount.values()) {
|
|
sum += c;
|
|
}
|
|
assertEqual(100, sum);
|
|
|
|
let shardsByKeyToCount = new Map();
|
|
fullCounts = collectionByKey.count(true);
|
|
for (const [shard, count] of Object.entries(fullCounts)) {
|
|
shardsByKeyToCount.set(shard, count);
|
|
}
|
|
assertEqual(numberOfShards, shardsByKeyToCount.size);
|
|
sum = 0;
|
|
for (let c of shardsByKeyToCount.values()) {
|
|
sum += c;
|
|
}
|
|
assertEqual(100, sum);
|
|
},
|
|
|
|
tearDownAll() {
|
|
tearDown();
|
|
},
|
|
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
/// @brief no restriction to a shard
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
|
|
testRestrictOnPrimaryKey : function () {
|
|
let sample = [];
|
|
for (let i = 0; i < 10; ++i) {
|
|
sample.push(collection.any());
|
|
}
|
|
|
|
for (const doc of sample) {
|
|
const queryKey = `
|
|
FOR doc IN ${cn}
|
|
FILTER doc._key == "${doc._key}"
|
|
RETURN doc`;
|
|
validatePlan(queryKey, "IndexNode", collection);
|
|
let res = db._query(queryKey, {}, disableSingleDocOp).toArray();
|
|
assertEqual(1, res.length);
|
|
assertEqual(doc._key, res[0]._key);
|
|
assertEqual(doc._rev, res[0]._rev);
|
|
}
|
|
},
|
|
|
|
testRestrictOnShardKeyHashIndex : function () {
|
|
dropIndexes(collectionByKey);
|
|
collectionByKey.ensureHashIndex(shardKey);
|
|
|
|
for (let i = 0; i < 25; ++i) {
|
|
const query = `
|
|
FOR doc IN ${cnKey}
|
|
FILTER doc.${shardKey} == ${i}
|
|
RETURN doc`;
|
|
validatePlan(query, "IndexNode", collectionByKey);
|
|
let res = db._query(query, {}, disableSingleDocOp).toArray();
|
|
assertEqual(4, res.length);
|
|
for (let doc of res) {
|
|
assertEqual(i, doc.value);
|
|
}
|
|
}
|
|
},
|
|
|
|
testRestrictOnShardKeySkiplist : function () {
|
|
dropIndexes(collectionByKey);
|
|
collectionByKey.ensureSkiplist(shardKey);
|
|
|
|
for (let i = 0; i < 25; ++i) {
|
|
const query = `
|
|
FOR doc IN ${cnKey}
|
|
FILTER doc.${shardKey} == ${i}
|
|
RETURN doc`;
|
|
validatePlan(query, "IndexNode", collectionByKey);
|
|
let res = db._query(query, {}, disableSingleDocOp).toArray();
|
|
assertEqual(4, res.length);
|
|
for (let doc of res) {
|
|
assertEqual(i, doc.value);
|
|
}
|
|
}
|
|
},
|
|
|
|
testRestrictMultipleShards : function () {
|
|
dropIndexes(collectionByKey);
|
|
collectionByKey.ensureHashIndex(shardKey);
|
|
|
|
for (let i = 0; i < 25; ++i) {
|
|
const query = `
|
|
FOR doc IN ${cnKey}
|
|
FILTER doc.${shardKey} == ${i}
|
|
FOR joined IN ${cnKey}
|
|
FILTER joined.${shardKey} == ${i % 5}
|
|
FILTER joined.joinValue == doc.joinValue
|
|
RETURN [doc, joined]
|
|
`;
|
|
|
|
let res = db._query(query, {}, disableSingleDocOp).toArray();
|
|
// we find 4 in first Loop, and 4 joins each
|
|
assertEqual(16, res.length);
|
|
for (let [doc, joined] of res) {
|
|
assertEqual(i, doc.value);
|
|
assertEqual(i % 5, joined.value);
|
|
assertEqual(doc.joinValue, joined.joinValue);
|
|
}
|
|
}
|
|
},
|
|
|
|
testRestrictMultipleShardsStringKeys : function () {
|
|
dropIndexes(collectionByKey);
|
|
collectionByKey.ensureHashIndex(shardKey);
|
|
|
|
for (let i = 0; i < 25; ++i) {
|
|
const query = `
|
|
FOR doc IN ${cnKey}
|
|
FILTER doc.${shardKey} == "key${i}"
|
|
FOR joined IN ${cnKey}
|
|
FILTER joined.${shardKey} == "key${i}"
|
|
FILTER joined.joinValue == doc.joinValue
|
|
RETURN [doc, joined]
|
|
`;
|
|
|
|
validatePlan(query, "IndexNode", collectionByKey);
|
|
}
|
|
},
|
|
|
|
testRestrictOnPrimaryAndShardKeyNoIndex : function () {
|
|
dropIndexes(collectionByKey);
|
|
let sample = [];
|
|
for (let i = 0; i < 10; ++i) {
|
|
sample.push(collectionByKey.any());
|
|
}
|
|
|
|
for (const doc of sample) {
|
|
const queryKey = `
|
|
FOR doc IN ${cnKey}
|
|
FILTER doc._key == "${doc._key}"
|
|
FILTER doc.${shardKey} == ${doc[shardKey]}
|
|
RETURN doc`;
|
|
validatePlan(queryKey, "IndexNode", collectionByKey);
|
|
let res = db._query(queryKey, {}, disableSingleDocOp).toArray();
|
|
assertEqual(1, res.length);
|
|
assertEqual(doc._key, res[0]._key);
|
|
assertEqual(doc._rev, res[0]._rev);
|
|
}
|
|
},
|
|
|
|
testRestrictOnPrimaryAndShardKeyJoinNoIndex : function () {
|
|
dropIndexes(collectionByKey);
|
|
let sample = [];
|
|
for (let i = 0; i < 10; ++i) {
|
|
sample.push(collectionByKey.any());
|
|
}
|
|
|
|
for (const doc of sample) {
|
|
const queryKey = `
|
|
FOR doc IN ${cnKey}
|
|
FILTER doc._key == "${doc._key}"
|
|
FILTER doc.${shardKey} == ${doc[shardKey]}
|
|
FOR joined IN ${cnKey}
|
|
FILTER joined._key == "${doc._key}"
|
|
FILTER joined.${shardKey} == ${doc[shardKey]}
|
|
RETURN [doc, joined]`;
|
|
validatePlan(queryKey, "IndexNode", collectionByKey);
|
|
let res = db._query(queryKey, {}, disableSingleDocOp).toArray();
|
|
assertEqual(1, res.length);
|
|
assertEqual(doc._key, res[0][0]._key);
|
|
assertEqual(doc._rev, res[0][0]._rev);
|
|
assertEqual(doc._key, res[0][1]._key);
|
|
assertEqual(doc._rev, res[0][1]._rev);
|
|
}
|
|
},
|
|
|
|
testRestrictOnShardKeyNoIndex : function () {
|
|
dropIndexes(collectionByKey);
|
|
|
|
for (let i = 0; i < 25; ++i) {
|
|
const query = `
|
|
FOR doc IN ${cnKey}
|
|
FILTER doc.${shardKey} == ${i}
|
|
RETURN doc`;
|
|
validatePlan(query, "EnumerateCollectionNode", collectionByKey);
|
|
let res = db._query(query, {}, disableSingleDocOp).toArray();
|
|
assertEqual(4, res.length);
|
|
for (let doc of res) {
|
|
assertEqual(i, doc.value);
|
|
}
|
|
}
|
|
},
|
|
|
|
testRestrictMultipleShardsNoIndex : function () {
|
|
dropIndexes(collectionByKey);
|
|
|
|
for (let i = 0; i < 25; ++i) {
|
|
const query = `
|
|
FOR doc IN ${cnKey}
|
|
FILTER doc.${shardKey} == ${i}
|
|
FOR joined IN ${cnKey}
|
|
FILTER joined.${shardKey} == ${i % 5}
|
|
FILTER joined.joinValue == doc.joinValue
|
|
RETURN [doc, joined]
|
|
`;
|
|
|
|
let res = db._query(query, {}, disableSingleDocOp).toArray();
|
|
// we find 4 in first Loop, and 4 joins each
|
|
assertEqual(16, res.length);
|
|
for (let [doc, joined] of res) {
|
|
assertEqual(i, doc.value);
|
|
assertEqual(i % 5, joined.value);
|
|
assertEqual(doc.joinValue, joined.joinValue);
|
|
}
|
|
}
|
|
},
|
|
|
|
testRestrictMultipleShardsStringKeysNoIndex : function () {
|
|
dropIndexes(collectionByKey);
|
|
|
|
for (let i = 0; i < 25; ++i) {
|
|
const query = `
|
|
FOR doc IN ${cnKey}
|
|
FILTER doc.${shardKey} == "key${i}"
|
|
FOR joined IN ${cnKey}
|
|
FILTER joined.${shardKey} == "key${i}"
|
|
FILTER joined.joinValue == doc.joinValue
|
|
RETURN [doc, joined]
|
|
`;
|
|
|
|
validatePlan(query, "EnumerateCollectionNode", collectionByKey);
|
|
}
|
|
},
|
|
|
|
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);
|
|
|
|
for (let i = 0; i < 24; ++i) {
|
|
const query = `
|
|
FOR doc IN ${cnKey}
|
|
FILTER doc.${shardKey} == ${i} || doc.${shardKey} == ${i+1}
|
|
RETURN doc
|
|
`;
|
|
// No restriction yet
|
|
//validatePlan(query, "IndexNode", collectionByKey);
|
|
|
|
let res = db._query(query, {}, disableSingleDocOp).toArray();
|
|
assertEqual(8, res.length);
|
|
for (let doc of res) {
|
|
assertTrue(i === doc.value || i + 1 === doc.value);
|
|
}
|
|
}
|
|
},
|
|
|
|
testMultipleShardsOrNoIndex : function () {
|
|
dropIndexes(collectionByKey);
|
|
|
|
for (let i = 0; i < 24; ++i) {
|
|
const query = `
|
|
FOR doc IN ${cnKey}
|
|
FILTER doc.${shardKey} == ${i} || doc.${shardKey} == ${i+1}
|
|
RETURN doc
|
|
`;
|
|
// Multi-shard not implemented yet
|
|
// validatePlan(query, "EnumerateCollectionNode", collectionByKey);
|
|
|
|
let res = db._query(query, {}, disableSingleDocOp).toArray();
|
|
assertEqual(8, res.length);
|
|
for (let doc of res) {
|
|
assertTrue(i === doc.value || i + 1 === doc.value);
|
|
}
|
|
}
|
|
},
|
|
|
|
testInnerOuterSame1 : function () {
|
|
dropIndexes(collectionByKey);
|
|
|
|
for (let i = 0; i < 24; ++i) {
|
|
const query = `
|
|
FOR doc1 IN ${cnKey}
|
|
FILTER doc1.${shardKey} == ${i}
|
|
FOR doc2 IN ${cnKey}
|
|
FILTER doc2.${shardKey} == ${i}
|
|
RETURN [doc1, doc2]
|
|
`;
|
|
validatePlan(query, "EnumerateCollectionNode", collectionByKey);
|
|
|
|
let raw = db._query(query, {}, disableSingleDocOp);
|
|
let results = raw.toArray();
|
|
assertEqual(16, results.length);
|
|
for (let [doc1, doc2] of results) {
|
|
assertTrue(i === doc1[shardKey]);
|
|
assertTrue(i === doc2[shardKey]);
|
|
}
|
|
}
|
|
},
|
|
|
|
testInnerOuterSameIndex1 : function () {
|
|
dropIndexes(collectionByKey);
|
|
collectionByKey.ensureHashIndex(shardKey);
|
|
|
|
for (let i = 0; i < 24; ++i) {
|
|
const query = `
|
|
FOR doc1 IN ${cnKey}
|
|
FILTER doc1.${shardKey} == ${i}
|
|
FOR doc2 IN ${cnKey}
|
|
FILTER doc2.${shardKey} == ${i}
|
|
RETURN [doc1, doc2]
|
|
`;
|
|
validatePlan(query, "IndexNode", collectionByKey);
|
|
|
|
let raw = db._query(query, {}, disableSingleDocOp);
|
|
let results = raw.toArray();
|
|
assertEqual(16, results.length);
|
|
for (let [doc1, doc2] of results) {
|
|
assertTrue(i === doc1[shardKey]);
|
|
assertTrue(i === doc2[shardKey]);
|
|
}
|
|
}
|
|
},
|
|
|
|
testInnerOuterSame2 : function () {
|
|
dropIndexes(collectionByKey);
|
|
|
|
for (let i = 0; i < 24; ++i) {
|
|
const query = `
|
|
FOR doc1 IN ${cnKey}
|
|
FILTER doc1.${shardKey} == ${i}
|
|
FOR doc2 IN ${cnKey}
|
|
FILTER doc2.${shardKey} == ${i+1}
|
|
RETURN [doc1, doc2]
|
|
`;
|
|
// Multi-shard not implemented yet
|
|
// validatePlan(query, "EnumerateCollectionNode", collectionByKey);
|
|
|
|
let raw = db._query(query, {}, disableSingleDocOp);
|
|
let results = raw.toArray();
|
|
assertEqual(16, results.length);
|
|
for (let [doc1, doc2] of results) {
|
|
assertTrue(i === doc1[shardKey]);
|
|
assertTrue(i + 1 === doc2.value);
|
|
}
|
|
}
|
|
},
|
|
|
|
testInnerOuterSameIndex2 : function () {
|
|
dropIndexes(collectionByKey);
|
|
collectionByKey.ensureHashIndex(shardKey);
|
|
|
|
for (let i = 0; i < 24; ++i) {
|
|
const query = `
|
|
FOR doc1 IN ${cnKey}
|
|
FILTER doc1.${shardKey} == ${i}
|
|
FOR doc2 IN ${cnKey}
|
|
FILTER doc2.${shardKey} == ${i+1}
|
|
RETURN [doc1, doc2]
|
|
`;
|
|
// Multi-shard not implemented yet
|
|
// validatePlan(query, "EnumerateCollectionNode", collectionByKey);
|
|
|
|
let raw = db._query(query, {}, disableSingleDocOp);
|
|
let results = raw.toArray();
|
|
assertEqual(16, results.length);
|
|
for (let [doc1, doc2] of results) {
|
|
assertTrue(i === doc1[shardKey]);
|
|
assertTrue(i + 1 === doc2.value);
|
|
}
|
|
}
|
|
},
|
|
|
|
testInnerOuterSame3 : function () {
|
|
dropIndexes(collectionByKey);
|
|
|
|
for (let i = 0; i < 24; ++i) {
|
|
const query = `
|
|
FOR doc1 IN ${cnKey}
|
|
FILTER doc1.${shardKey} == ${i}
|
|
FOR doc2 IN ${cnKey}
|
|
FILTER doc2.${shardKey} == ${i}
|
|
UPDATE doc1 WITH {test:1} IN ${cnKey}
|
|
RETURN [NEW, doc2]
|
|
`;
|
|
validatePlan(query, "EnumerateCollectionNode", collectionByKey);
|
|
|
|
let raw = db._query(query, {}, disableSingleDocOp);
|
|
let stats = raw.getExtra().stats;
|
|
assertEqual(stats.writesExecuted, 16);
|
|
let results = raw.toArray();
|
|
assertEqual(16, results.length);
|
|
for (let [doc1, doc2] of results) {
|
|
assertTrue(i === doc1[shardKey]);
|
|
assertTrue(i === doc2[shardKey]);
|
|
assertEqual(doc1.test, 1);
|
|
}
|
|
}
|
|
},
|
|
|
|
testInnerOuterSameIndex3 : function () {
|
|
dropIndexes(collectionByKey);
|
|
collectionByKey.ensureHashIndex(shardKey);
|
|
|
|
for (let i = 0; i < 24; ++i) {
|
|
const query = `
|
|
FOR doc1 IN ${cnKey}
|
|
FILTER doc1.${shardKey} == ${i}
|
|
FOR doc2 IN ${cnKey}
|
|
FILTER doc2.${shardKey} == ${i}
|
|
UPDATE doc1 WITH {test:1} IN ${cnKey}
|
|
RETURN [NEW, doc2]
|
|
`;
|
|
validatePlan(query, "IndexNode", collectionByKey);
|
|
|
|
let raw = db._query(query, {}, disableSingleDocOp);
|
|
let stats = raw.getExtra().stats;
|
|
assertEqual(stats.writesExecuted, 16);
|
|
let results = raw.toArray();
|
|
assertEqual(16, results.length);
|
|
for (let [doc1, doc2] of results) {
|
|
assertTrue(i === doc1[shardKey]);
|
|
assertTrue(i === doc2[shardKey]);
|
|
assertEqual(doc1.test, 1);
|
|
}
|
|
}
|
|
},
|
|
|
|
testInnerOuterSame4 : function () {
|
|
dropIndexes(collectionByKey);
|
|
|
|
for (let i = 0; i < 24; ++i) {
|
|
const query = `
|
|
FOR doc1 IN ${cnKey}
|
|
FILTER doc1.${shardKey} == ${i}
|
|
FOR doc2 IN ${cnKey}
|
|
RETURN doc1
|
|
`;
|
|
|
|
let raw = db._query(query, {}, disableSingleDocOp);
|
|
let results = raw.toArray();
|
|
assertEqual(400, results.length);
|
|
for (let doc of results) {
|
|
assertTrue(i === doc.value);
|
|
}
|
|
}
|
|
},
|
|
|
|
testInnerOuterSameIndex4 : function () {
|
|
dropIndexes(collectionByKey);
|
|
collectionByKey.ensureHashIndex(shardKey);
|
|
|
|
for (let i = 0; i < 24; ++i) {
|
|
const query = `
|
|
FOR doc1 IN ${cnKey}
|
|
FILTER doc1.${shardKey} == ${i}
|
|
FOR doc2 IN ${cnKey}
|
|
RETURN doc1
|
|
`;
|
|
|
|
let raw = db._query(query, {}, disableSingleDocOp);
|
|
let results = raw.toArray();
|
|
assertEqual(400, results.length);
|
|
for (let doc of results) {
|
|
assertTrue(i === doc.value);
|
|
}
|
|
}
|
|
},
|
|
|
|
testInnerOuterSame5 : function () {
|
|
dropIndexes(collectionByKey);
|
|
|
|
for (let i = 0; i < 24; ++i) {
|
|
const query = `
|
|
FOR doc1 IN ${cnKey}
|
|
FILTER doc1.${shardKey} == ${i}
|
|
FOR doc2 IN ${cnKey}
|
|
UPDATE doc1 WITH {test:1} IN ${cnKey}
|
|
FILTER doc2.${shardKey} == ${i}
|
|
RETURN [NEW, doc2]
|
|
`;
|
|
|
|
let raw = db._query(query, {}, disableSingleDocOp);
|
|
let stats = raw.getExtra().stats;
|
|
assertEqual(stats.writesExecuted, 400);
|
|
let results = raw.toArray();
|
|
assertEqual(16, results.length);
|
|
for (let [doc1, doc2] of results) {
|
|
assertTrue(i === doc1[shardKey]);
|
|
assertTrue(i === doc2[shardKey]);
|
|
assertEqual(doc1.test, 1);
|
|
}
|
|
}
|
|
},
|
|
|
|
testInnerOuterSameIndex5 : function () {
|
|
dropIndexes(collectionByKey);
|
|
collectionByKey.ensureHashIndex(shardKey);
|
|
|
|
for (let i = 0; i < 24; ++i) {
|
|
const query = `
|
|
FOR doc1 IN ${cnKey}
|
|
FILTER doc1.${shardKey} == ${i}
|
|
FOR doc2 IN ${cnKey}
|
|
UPDATE doc1 WITH {test:1} IN ${cnKey}
|
|
FILTER doc2.${shardKey} == ${i}
|
|
RETURN [NEW, doc2]
|
|
`;
|
|
|
|
let raw = db._query(query, {}, disableSingleShard);
|
|
let stats = raw.getExtra().stats;
|
|
assertEqual(stats.writesExecuted, 400);
|
|
let results = raw.toArray();
|
|
assertEqual(16, results.length);
|
|
for (let [doc1, doc2] of results) {
|
|
assertTrue(i === doc1[shardKey]);
|
|
assertTrue(i === doc2[shardKey]);
|
|
assertEqual(doc1.test, 1);
|
|
}
|
|
}
|
|
},
|
|
|
|
testInnerOuterSame6 : function () {
|
|
dropIndexes(collectionByKey);
|
|
|
|
for (let i = 0; i < 24; ++i) {
|
|
const query = `
|
|
FOR doc1 IN ${cnKey}
|
|
FILTER doc1.${shardKey} == ${i}
|
|
FOR doc2 IN ${cnKey}
|
|
UPDATE doc1 WITH {test:1} IN ${cnKey}
|
|
RETURN [NEW, doc2]
|
|
`;
|
|
|
|
let raw = db._query(query, {}, disableSingleDocOp);
|
|
let stats = raw.getExtra().stats;
|
|
assertEqual(stats.writesExecuted, 400);
|
|
let results = raw.toArray();
|
|
assertEqual(400, results.length);
|
|
for (let [doc1, doc2] of results) {
|
|
assertTrue(i === doc1[shardKey]);
|
|
assertEqual(doc1.test, 1);
|
|
}
|
|
}
|
|
},
|
|
|
|
testInnerOuterSameIndex6 : function () {
|
|
dropIndexes(collectionByKey);
|
|
collectionByKey.ensureHashIndex(shardKey);
|
|
|
|
for (let i = 0; i < 24; ++i) {
|
|
const query = `
|
|
FOR doc1 IN ${cnKey}
|
|
FILTER doc1.${shardKey} == ${i}
|
|
FOR doc2 IN ${cnKey}
|
|
UPDATE doc1 WITH {test:1} IN ${cnKey}
|
|
RETURN [NEW, doc2]
|
|
`;
|
|
|
|
let raw = db._query(query, {}, disableSingleDocOp);
|
|
let stats = raw.getExtra().stats;
|
|
assertEqual(stats.writesExecuted, 400);
|
|
let results = raw.toArray();
|
|
assertEqual(400, results.length);
|
|
for (let [doc1, doc2] of results) {
|
|
assertTrue(i === doc1[shardKey]);
|
|
assertEqual(doc1.test, 1);
|
|
}
|
|
}
|
|
},
|
|
|
|
testInnerOuterSame7 : function () {
|
|
dropIndexes(collectionByKey);
|
|
|
|
for (let i = 0; i < 24; ++i) {
|
|
const query = `
|
|
FOR doc1 IN ${cnKey}
|
|
FILTER doc1.${shardKey} == ${i}
|
|
UPDATE doc1 WITH {test:1} IN ${cnKey}
|
|
RETURN NEW
|
|
`;
|
|
validatePlan(query, "EnumerateCollectionNode", collectionByKey);
|
|
|
|
let raw = db._query(query, {}, disableSingleDocOp);
|
|
let stats = raw.getExtra().stats;
|
|
assertEqual(stats.writesExecuted, 4);
|
|
let results = raw.toArray();
|
|
assertEqual(4, results.length);
|
|
for (let doc of results) {
|
|
assertTrue(i === doc.value);
|
|
assertEqual(doc.test, 1);
|
|
}
|
|
}
|
|
},
|
|
|
|
testInnerOuterSameIndex7 : function () {
|
|
dropIndexes(collectionByKey);
|
|
collectionByKey.ensureHashIndex(shardKey);
|
|
|
|
for (let i = 0; i < 24; ++i) {
|
|
const query = `
|
|
FOR doc1 IN ${cnKey}
|
|
FILTER doc1.${shardKey} == ${i}
|
|
UPDATE doc1 WITH {test:1} IN ${cnKey}
|
|
RETURN NEW
|
|
`;
|
|
validatePlan(query, "IndexNode", collectionByKey);
|
|
|
|
let raw = db._query(query, {}, disableSingleDocOp);
|
|
let stats = raw.getExtra().stats;
|
|
assertEqual(stats.writesExecuted, 4);
|
|
let results = raw.toArray();
|
|
assertEqual(4, results.length);
|
|
for (let doc of results) {
|
|
assertTrue(i === doc.value);
|
|
assertEqual(doc.test, 1);
|
|
}
|
|
}
|
|
},
|
|
|
|
testInnerOuterSame8 : function () {
|
|
dropIndexes(collectionByKey);
|
|
|
|
for (let i = 0; i < 24; ++i) {
|
|
const query = `
|
|
FOR doc1 IN ${cnKey}
|
|
FOR doc2 IN ${cnKey}
|
|
FILTER doc1.${shardKey} == ${i}
|
|
FILTER doc2.${shardKey} == ${i}
|
|
RETURN [doc1, doc2]
|
|
`;
|
|
validatePlan(query, "EnumerateCollectionNode", collectionByKey);
|
|
|
|
let raw = db._query(query, {}, disableSingleDocOp);
|
|
let results = raw.toArray();
|
|
assertEqual(16, results.length);
|
|
for (let [doc1, doc2] of results) {
|
|
assertTrue(i === doc1[shardKey]);
|
|
assertTrue(i === doc2[shardKey]);
|
|
}
|
|
}
|
|
},
|
|
|
|
testInnerOuterSameIndex8 : function () {
|
|
dropIndexes(collectionByKey);
|
|
collectionByKey.ensureHashIndex(shardKey);
|
|
|
|
for (let i = 0; i < 24; ++i) {
|
|
const query = `
|
|
FOR doc1 IN ${cnKey}
|
|
FOR doc2 IN ${cnKey}
|
|
FILTER doc1.${shardKey} == ${i}
|
|
FILTER doc2.${shardKey} == ${i}
|
|
RETURN [doc1, doc2]
|
|
`;
|
|
validatePlan(query, "IndexNode", collectionByKey);
|
|
|
|
let raw = db._query(query, {}, disableSingleDocOp);
|
|
let results = raw.toArray();
|
|
assertEqual(16, results.length);
|
|
for (let [doc1, doc2] of results) {
|
|
assertTrue(i === doc1[shardKey]);
|
|
assertTrue(i === doc2[shardKey]);
|
|
}
|
|
}
|
|
},
|
|
|
|
testInnerOuterSame9 : function () {
|
|
dropIndexes(collectionByKey);
|
|
|
|
for (let i = 0; i < 24; ++i) {
|
|
const query = `
|
|
FOR doc1 IN ${cnKey}
|
|
FOR doc2 IN ${cnKey}
|
|
FILTER doc1.${shardKey} == ${i}
|
|
FILTER doc2.${shardKey} == ${i}
|
|
UPDATE doc1 WITH {test:1} IN ${cnKey}
|
|
RETURN [NEW, doc2]
|
|
`;
|
|
validatePlan(query, "EnumerateCollectionNode", collectionByKey);
|
|
|
|
let raw = db._query(query, {}, disableSingleDocOp);
|
|
let stats = raw.getExtra().stats;
|
|
assertEqual(stats.writesExecuted, 16);
|
|
let results = raw.toArray();
|
|
assertEqual(16, results.length);
|
|
for (let [doc1, doc2] of results) {
|
|
assertTrue(i === doc1[shardKey]);
|
|
assertTrue(i === doc2[shardKey]);
|
|
assertEqual(doc1.test, 1);
|
|
}
|
|
}
|
|
},
|
|
|
|
testInnerOuterSameIndex9 : function () {
|
|
dropIndexes(collectionByKey);
|
|
collectionByKey.ensureHashIndex(shardKey);
|
|
|
|
for (let i = 0; i < 24; ++i) {
|
|
const query = `
|
|
FOR doc1 IN ${cnKey}
|
|
FOR doc2 IN ${cnKey}
|
|
FILTER doc1.${shardKey} == ${i}
|
|
FILTER doc2.${shardKey} == ${i}
|
|
UPDATE doc1 WITH {test:1} IN ${cnKey}
|
|
RETURN [NEW, doc2]
|
|
`;
|
|
validatePlan(query, "IndexNode", collectionByKey);
|
|
|
|
let raw = db._query(query, {}, disableSingleDocOp);
|
|
let stats = raw.getExtra().stats;
|
|
assertEqual(stats.writesExecuted, 16);
|
|
let results = raw.toArray();
|
|
assertEqual(16, results.length);
|
|
for (let [doc1, doc2] of results) {
|
|
assertTrue(i === doc1[shardKey]);
|
|
assertTrue(i === doc2[shardKey]);
|
|
assertEqual(doc1.test, 1);
|
|
}
|
|
}
|
|
},
|
|
|
|
testInnerOuterSame10 : function () {
|
|
dropIndexes(collectionByKey);
|
|
|
|
for (let i = 0; i < 24; ++i) {
|
|
const query = `
|
|
FOR doc1 IN ${cnKey}
|
|
FOR doc2 IN ${cnKey}
|
|
FILTER doc1.${shardKey} == ${i}
|
|
RETURN [doc1, doc2]
|
|
`;
|
|
|
|
let raw = db._query(query, {}, disableSingleDocOp);
|
|
let results = raw.toArray();
|
|
assertEqual(400, results.length);
|
|
for (let [doc1, doc2] of results) {
|
|
assertTrue(i === doc1[shardKey]);
|
|
}
|
|
}
|
|
},
|
|
|
|
testInnerOuterSameIndex10 : function () {
|
|
dropIndexes(collectionByKey);
|
|
collectionByKey.ensureHashIndex(shardKey);
|
|
|
|
for (let i = 0; i < 24; ++i) {
|
|
const query = `
|
|
FOR doc1 IN ${cnKey}
|
|
FOR doc2 IN ${cnKey}
|
|
FILTER doc1.${shardKey} == ${i}
|
|
RETURN [doc1, doc2]
|
|
`;
|
|
|
|
let raw = db._query(query, {}, disableSingleDocOp);
|
|
let results = raw.toArray();
|
|
assertEqual(400, results.length);
|
|
for (let [doc1, doc2] of results) {
|
|
assertTrue(i === doc1[shardKey]);
|
|
}
|
|
}
|
|
},
|
|
|
|
testInnerOuterSame11 : function () {
|
|
dropIndexes(collectionByKey);
|
|
|
|
for (let i = 0; i < 24; ++i) {
|
|
const query = `
|
|
FOR doc1 IN ${cnKey}
|
|
FOR doc2 IN ${cnKey}
|
|
FILTER doc1.${shardKey} == ${i}
|
|
UPDATE doc1 WITH {test:1} IN ${cnKey}
|
|
FILTER doc2.${shardKey} == ${i}
|
|
RETURN [NEW, doc2]
|
|
`;
|
|
|
|
let raw = db._query(query, {}, disableSingleDocOp);
|
|
let stats = raw.getExtra().stats;
|
|
assertEqual(stats.writesExecuted, 400);
|
|
let results = raw.toArray();
|
|
assertEqual(16, results.length);
|
|
for (let [doc1, doc2] of results) {
|
|
assertTrue(i === doc1[shardKey]);
|
|
assertTrue(i === doc2[shardKey]);
|
|
assertEqual(doc1.test, 1);
|
|
}
|
|
}
|
|
},
|
|
|
|
testInnerOuterSameIndex11 : function () {
|
|
dropIndexes(collectionByKey);
|
|
collectionByKey.ensureHashIndex(shardKey);
|
|
|
|
for (let i = 0; i < 24; ++i) {
|
|
const query = `
|
|
FOR doc1 IN ${cnKey}
|
|
FOR doc2 IN ${cnKey}
|
|
FILTER doc1.${shardKey} == ${i}
|
|
UPDATE doc1 WITH {test:1} IN ${cnKey}
|
|
FILTER doc2.${shardKey} == ${i}
|
|
RETURN [NEW, doc2]
|
|
`;
|
|
|
|
let raw = db._query(query, {}, disableSingleShard);
|
|
let stats = raw.getExtra().stats;
|
|
assertEqual(stats.writesExecuted, 400);
|
|
let results = raw.toArray();
|
|
assertEqual(16, results.length);
|
|
for (let [doc1, doc2] of results) {
|
|
assertTrue(i === doc1[shardKey]);
|
|
assertTrue(i === doc2[shardKey]);
|
|
assertEqual(doc1.test, 1);
|
|
}
|
|
}
|
|
},
|
|
|
|
testInnerOuterSame12 : function () {
|
|
dropIndexes(collectionByKey);
|
|
|
|
for (let i = 0; i < 24; ++i) {
|
|
const query = `
|
|
FOR doc1 IN ${cnKey}
|
|
FOR doc2 IN ${cnKey}
|
|
FILTER doc1.${shardKey} == ${i}
|
|
UPDATE doc1 WITH {test:1} IN ${cnKey}
|
|
RETURN [NEW, doc2]
|
|
`;
|
|
|
|
let raw = db._query(query, {}, disableSingleDocOp);
|
|
let stats = raw.getExtra().stats;
|
|
assertEqual(stats.writesExecuted, 400);
|
|
let results = raw.toArray();
|
|
assertEqual(400, results.length);
|
|
for (let [doc1, doc2] of results) {
|
|
assertTrue(i === doc1[shardKey]);
|
|
assertEqual(doc1.test, 1);
|
|
}
|
|
}
|
|
},
|
|
|
|
testInnerOuterSameIndex12 : function () {
|
|
dropIndexes(collectionByKey);
|
|
collectionByKey.ensureHashIndex(shardKey);
|
|
|
|
for (let i = 0; i < 24; ++i) {
|
|
const query = `
|
|
FOR doc1 IN ${cnKey}
|
|
FOR doc2 IN ${cnKey}
|
|
FILTER doc1.${shardKey} == ${i}
|
|
UPDATE doc1 WITH {test:1} IN ${cnKey}
|
|
RETURN [NEW, doc2]
|
|
`;
|
|
|
|
let raw = db._query(query, {}, disableSingleDocOp);
|
|
let stats = raw.getExtra().stats;
|
|
assertEqual(stats.writesExecuted, 400);
|
|
let results = raw.toArray();
|
|
assertEqual(400, results.length);
|
|
for (let [doc1, doc2] of results) {
|
|
assertTrue(i === doc1[shardKey]);
|
|
assertEqual(doc1.test, 1);
|
|
}
|
|
}
|
|
},
|
|
|
|
testInnerOuterSame13 : function () {
|
|
dropIndexes(collectionByKey);
|
|
|
|
for (let i = 0; i < 24; ++i) {
|
|
const query = `
|
|
FOR doc1 IN ${cnKey}
|
|
FOR doc2 IN ${cnKey}
|
|
FILTER doc2.${shardKey} == ${i}
|
|
FILTER doc1.${shardKey} == ${i}
|
|
RETURN [doc1, doc2]
|
|
`;
|
|
validatePlan(query, "EnumerateCollectionNode", collectionByKey);
|
|
|
|
let raw = db._query(query, {}, disableSingleDocOp);
|
|
let results = raw.toArray();
|
|
assertEqual(16, results.length);
|
|
for (let [doc1, doc2] of results) {
|
|
assertTrue(i === doc1[shardKey]);
|
|
assertTrue(i === doc2[shardKey]);
|
|
}
|
|
}
|
|
},
|
|
|
|
testInnerOuterSameIndex13 : function () {
|
|
dropIndexes(collectionByKey);
|
|
collectionByKey.ensureHashIndex(shardKey);
|
|
|
|
for (let i = 0; i < 24; ++i) {
|
|
const query = `
|
|
FOR doc1 IN ${cnKey}
|
|
FOR doc2 IN ${cnKey}
|
|
FILTER doc2.${shardKey} == ${i}
|
|
FILTER doc1.${shardKey} == ${i}
|
|
RETURN [doc1, doc2]
|
|
`;
|
|
validatePlan(query, "IndexNode", collectionByKey);
|
|
|
|
let raw = db._query(query, {}, disableSingleDocOp);
|
|
let results = raw.toArray();
|
|
assertEqual(16, results.length);
|
|
for (let [doc1, doc2] of results) {
|
|
assertTrue(i === doc1[shardKey]);
|
|
assertTrue(i === doc2[shardKey]);
|
|
}
|
|
}
|
|
},
|
|
|
|
testInnerOuterSame14 : function () {
|
|
dropIndexes(collectionByKey);
|
|
|
|
for (let i = 0; i < 24; ++i) {
|
|
const query = `
|
|
FOR doc1 IN ${cnKey}
|
|
FOR doc2 IN ${cnKey}
|
|
FILTER doc2.${shardKey} == ${i}
|
|
FILTER doc1.${shardKey} == ${i}
|
|
UPDATE doc1 WITH {test:1} IN ${cnKey}
|
|
RETURN [NEW, doc2]
|
|
`;
|
|
validatePlan(query, "EnumerateCollectionNode", collectionByKey);
|
|
|
|
let raw = db._query(query, {}, disableSingleDocOp);
|
|
let stats = raw.getExtra().stats;
|
|
assertEqual(stats.writesExecuted, 16);
|
|
let results = raw.toArray();
|
|
assertEqual(16, results.length);
|
|
for (let [doc1, doc2] of results) {
|
|
assertTrue(i === doc1[shardKey]);
|
|
assertTrue(i === doc2[shardKey]);
|
|
assertEqual(doc1.test, 1);
|
|
}
|
|
}
|
|
},
|
|
|
|
testInnerOuterSameIndex14 : function () {
|
|
dropIndexes(collectionByKey);
|
|
collectionByKey.ensureHashIndex(shardKey);
|
|
|
|
for (let i = 0; i < 24; ++i) {
|
|
const query = `
|
|
FOR doc1 IN ${cnKey}
|
|
FOR doc2 IN ${cnKey}
|
|
FILTER doc2.${shardKey} == ${i}
|
|
FILTER doc1.${shardKey} == ${i}
|
|
UPDATE doc1 WITH {test:1} IN ${cnKey}
|
|
RETURN [NEW, doc2]
|
|
`;
|
|
validatePlan(query, "IndexNode", collectionByKey);
|
|
|
|
let raw = db._query(query, {}, disableSingleDocOp);
|
|
let stats = raw.getExtra().stats;
|
|
assertEqual(stats.writesExecuted, 16);
|
|
let results = raw.toArray();
|
|
assertEqual(16, results.length);
|
|
for (let [doc1, doc2] of results) {
|
|
assertTrue(i === doc1[shardKey]);
|
|
assertTrue(i === doc2[shardKey]);
|
|
assertEqual(doc1.test, 1);
|
|
}
|
|
}
|
|
},
|
|
|
|
testInnerOuterSame15 : function () {
|
|
dropIndexes(collectionByKey);
|
|
|
|
for (let i = 0; i < 24; ++i) {
|
|
const query = `
|
|
FOR doc1 IN ${cnKey}
|
|
FOR doc2 IN ${cnKey}
|
|
FILTER doc2.${shardKey} == ${i}
|
|
RETURN [doc1, doc2]
|
|
`;
|
|
|
|
let raw = db._query(query, {}, disableSingleDocOp);
|
|
let results = raw.toArray();
|
|
assertEqual(400, results.length);
|
|
for (let [doc1, doc2] of results) {
|
|
assertTrue(i === doc2[shardKey]);
|
|
}
|
|
}
|
|
},
|
|
|
|
testInnerOuterSameIndex15 : function () {
|
|
dropIndexes(collectionByKey);
|
|
collectionByKey.ensureHashIndex(shardKey);
|
|
|
|
for (let i = 0; i < 24; ++i) {
|
|
const query = `
|
|
FOR doc1 IN ${cnKey}
|
|
FOR doc2 IN ${cnKey}
|
|
FILTER doc2.${shardKey} == ${i}
|
|
RETURN [doc1, doc2]
|
|
`;
|
|
|
|
let raw = db._query(query, {}, disableSingleDocOp);
|
|
let results = raw.toArray();
|
|
assertEqual(400, results.length);
|
|
for (let [doc1, doc2] of results) {
|
|
assertTrue(i === doc2[shardKey]);
|
|
}
|
|
}
|
|
},
|
|
|
|
testInnerOuterSame16 : function () {
|
|
dropIndexes(collectionByKey);
|
|
|
|
for (let i = 0; i < 24; ++i) {
|
|
const query = `
|
|
FOR doc1 IN ${cnKey}
|
|
FOR doc2 IN ${cnKey}
|
|
FILTER doc2.${shardKey} == ${i}
|
|
UPDATE doc1 WITH {test:1} IN ${cnKey}
|
|
FILTER NEW.${shardKey} == ${i}
|
|
RETURN [NEW, doc2]
|
|
`;
|
|
|
|
let raw = db._query(query, {}, disableSingleShard);
|
|
let stats = raw.getExtra().stats;
|
|
assertEqual(stats.writesExecuted, 400);
|
|
let results = raw.toArray();
|
|
assertEqual(16, results.length);
|
|
for (let [doc1, doc2] of results) {
|
|
assertTrue(i === doc1[shardKey]);
|
|
assertTrue(i === doc2[shardKey]);
|
|
assertEqual(doc1.test, 1);
|
|
}
|
|
}
|
|
},
|
|
|
|
testInnerOuterSameIndex16 : function () {
|
|
dropIndexes(collectionByKey);
|
|
collectionByKey.ensureHashIndex(shardKey);
|
|
|
|
for (let i = 0; i < 24; ++i) {
|
|
const query = `
|
|
FOR doc1 IN ${cnKey}
|
|
FOR doc2 IN ${cnKey}
|
|
FILTER doc2.${shardKey} == ${i}
|
|
UPDATE doc1 WITH {test:1} IN ${cnKey}
|
|
FILTER NEW.${shardKey} == ${i}
|
|
RETURN [NEW, doc2]
|
|
`;
|
|
|
|
let raw = db._query(query, {}, disableSingleShard);
|
|
let stats = raw.getExtra().stats;
|
|
assertEqual(stats.writesExecuted, 400);
|
|
let results = raw.toArray();
|
|
assertEqual(16, results.length);
|
|
for (let [doc1, doc2] of results) {
|
|
assertTrue(i === doc1[shardKey]);
|
|
assertTrue(i === doc2[shardKey]);
|
|
assertEqual(doc1.test, 1);
|
|
}
|
|
}
|
|
},
|
|
|
|
testInnerOuterSame17 : function () {
|
|
dropIndexes(collectionByKey);
|
|
|
|
for (let i = 0; i < 24; ++i) {
|
|
const query = `
|
|
FOR doc1 IN ${cnKey}
|
|
FOR doc2 IN ${cnKey}
|
|
FILTER doc2.${shardKey} == ${i}
|
|
UPDATE doc1 WITH {test:1} IN ${cnKey}
|
|
RETURN [NEW, doc2]
|
|
`;
|
|
|
|
let raw = db._query(query, {}, disableSingleDocOp);
|
|
let stats = raw.getExtra().stats;
|
|
assertEqual(stats.writesExecuted, 400);
|
|
let results = raw.toArray();
|
|
assertEqual(400, results.length);
|
|
for (let [doc1, doc2] of results) {
|
|
assertTrue(i === doc2[shardKey]);
|
|
assertEqual(doc1.test, 1);
|
|
}
|
|
}
|
|
},
|
|
|
|
testInnerOuterSameIndex17 : function () {
|
|
dropIndexes(collectionByKey);
|
|
collectionByKey.ensureHashIndex(shardKey);
|
|
|
|
for (let i = 0; i < 24; ++i) {
|
|
const query = `
|
|
FOR doc1 IN ${cnKey}
|
|
FOR doc2 IN ${cnKey}
|
|
FILTER doc2.${shardKey} == ${i}
|
|
UPDATE doc1 WITH {test:1} IN ${cnKey}
|
|
RETURN [NEW, doc2]
|
|
`;
|
|
|
|
let raw = db._query(query, {}, disableSingleDocOp);
|
|
let stats = raw.getExtra().stats;
|
|
assertEqual(stats.writesExecuted, 400);
|
|
let results = raw.toArray();
|
|
assertEqual(400, results.length);
|
|
for (let [doc1, doc2] of results) {
|
|
assertTrue(i === doc2[shardKey]);
|
|
assertEqual(doc1.test, 1);
|
|
}
|
|
}
|
|
},
|
|
|
|
testInnerOuterSame18 : function () {
|
|
dropIndexes(collectionByKey);
|
|
|
|
const i = 18;
|
|
const query = `
|
|
FOR doc1 IN ${cnKey}
|
|
FOR doc2 IN ${cnKey}
|
|
UPDATE doc1 WITH {test:1} IN ${cnKey}
|
|
FILTER NEW.${shardKey} == ${i}
|
|
FILTER doc2.${shardKey} == ${i}
|
|
RETURN [NEW, doc2]
|
|
`;
|
|
|
|
let raw = db._query(query, {}, disableSingleShard);
|
|
let stats = raw.getExtra().stats;
|
|
assertEqual(stats.writesExecuted, 10000);
|
|
let results = raw.toArray();
|
|
assertEqual(16, results.length);
|
|
for (let [doc1, doc2] of results) {
|
|
assertTrue(i === doc1[shardKey]);
|
|
assertTrue(i === doc2[shardKey]);
|
|
assertEqual(doc1.test, 1);
|
|
}
|
|
},
|
|
|
|
testInnerOuterSameIndex18 : function () {
|
|
dropIndexes(collectionByKey);
|
|
collectionByKey.ensureHashIndex(shardKey);
|
|
|
|
const i = 18;
|
|
const query = `
|
|
FOR doc1 IN ${cnKey}
|
|
FOR doc2 IN ${cnKey}
|
|
UPDATE doc1 WITH {test:1} IN ${cnKey}
|
|
FILTER NEW.${shardKey} == ${i}
|
|
FILTER doc2.${shardKey} == ${i}
|
|
RETURN [NEW, doc2]
|
|
`;
|
|
let raw = db._query(query, {}, disableSingleShard);
|
|
let stats = raw.getExtra().stats;
|
|
assertEqual(stats.writesExecuted, 10000);
|
|
let results = raw.toArray();
|
|
assertEqual(16, results.length);
|
|
for (let [doc1, doc2] of results) {
|
|
assertTrue(i === doc1[shardKey]);
|
|
assertTrue(i === doc2[shardKey]);
|
|
assertEqual(doc1.test, 1);
|
|
}
|
|
},
|
|
|
|
testInnerOuterSame19 : function () {
|
|
dropIndexes(collectionByKey);
|
|
|
|
const i = 19;
|
|
const query = `
|
|
FOR doc1 IN ${cnKey}
|
|
FOR doc2 IN ${cnKey}
|
|
UPDATE doc1 WITH {test:1} IN ${cnKey}
|
|
FILTER NEW.${shardKey} == ${i}
|
|
RETURN [NEW, doc2]
|
|
`;
|
|
|
|
let raw = db._query(query, {}, disableSingleDocOp);
|
|
let stats = raw.getExtra().stats;
|
|
assertEqual(stats.writesExecuted, 10000);
|
|
let results = raw.toArray();
|
|
assertEqual(400, results.length);
|
|
for (let [doc1, doc2] of results) {
|
|
assertTrue(i === doc1[shardKey]);
|
|
assertEqual(doc1.test, 1);
|
|
}
|
|
},
|
|
|
|
testInnerOuterSameIndex19 : function () {
|
|
dropIndexes(collectionByKey);
|
|
collectionByKey.ensureHashIndex(shardKey);
|
|
|
|
const i = 19;
|
|
const query = `
|
|
FOR doc1 IN ${cnKey}
|
|
FOR doc2 IN ${cnKey}
|
|
UPDATE doc1 WITH {test:1} IN ${cnKey}
|
|
FILTER NEW.${shardKey} == ${i}
|
|
RETURN [NEW, doc2]
|
|
`;
|
|
|
|
let raw = db._query(query, {}, disableSingleDocOp);
|
|
let stats = raw.getExtra().stats;
|
|
assertEqual(stats.writesExecuted, 10000);
|
|
let results = raw.toArray();
|
|
assertEqual(400, results.length);
|
|
for (let [doc1, doc2] of results) {
|
|
assertTrue(i === doc1[shardKey]);
|
|
assertEqual(doc1.test, 1);
|
|
}
|
|
},
|
|
|
|
testInnerOuterSame20 : function () {
|
|
dropIndexes(collectionByKey);
|
|
|
|
const i = 20;
|
|
const query = `
|
|
FOR doc1 IN ${cnKey}
|
|
FOR doc2 IN ${cnKey}
|
|
UPDATE doc1 WITH {test:1} IN ${cnKey}
|
|
FILTER doc2.${shardKey} == ${i}
|
|
FILTER NEW.${shardKey} == ${i}
|
|
RETURN [NEW, doc2]
|
|
`;
|
|
|
|
let raw = db._query(query, {}, disableSingleDocOp);
|
|
let stats = raw.getExtra().stats;
|
|
assertEqual(stats.writesExecuted, 10000);
|
|
let results = raw.toArray();
|
|
assertEqual(16, results.length);
|
|
for (let [doc1, doc2] of results) {
|
|
assertTrue(i === doc1[shardKey]);
|
|
assertTrue(i === doc2[shardKey]);
|
|
assertEqual(doc1.test, 1);
|
|
}
|
|
},
|
|
|
|
testInnerOuterSameIndex20 : function () {
|
|
dropIndexes(collectionByKey);
|
|
collectionByKey.ensureHashIndex(shardKey);
|
|
|
|
const i = 20;
|
|
const query = `
|
|
FOR doc1 IN ${cnKey}
|
|
FOR doc2 IN ${cnKey}
|
|
UPDATE doc1 WITH {test:1} IN ${cnKey}
|
|
FILTER doc2.${shardKey} == ${i}
|
|
FILTER NEW.${shardKey} == ${i}
|
|
RETURN [NEW, doc2]
|
|
`;
|
|
|
|
let raw = db._query(query, {}, disableSingleDocOp);
|
|
let stats = raw.getExtra().stats;
|
|
assertEqual(stats.writesExecuted, 10000);
|
|
let results = raw.toArray();
|
|
assertEqual(16, results.length);
|
|
for (let [doc1, doc2] of results) {
|
|
assertTrue(i === doc1[shardKey]);
|
|
assertTrue(i === doc2[shardKey]);
|
|
assertEqual(doc1.test, 1);
|
|
}
|
|
},
|
|
|
|
testInnerOuterSame21 : function () {
|
|
dropIndexes(collectionByKey);
|
|
|
|
const i = 21;
|
|
const query = `
|
|
FOR doc1 IN ${cnKey}
|
|
FOR doc2 IN ${cnKey}
|
|
UPDATE doc1 WITH {test:1} IN ${cnKey}
|
|
FILTER doc2.${shardKey} == ${i}
|
|
RETURN [NEW, doc2]
|
|
`;
|
|
|
|
let raw = db._query(query, {}, disableSingleDocOp);
|
|
let stats = raw.getExtra().stats;
|
|
assertEqual(stats.writesExecuted, 10000);
|
|
let results = raw.toArray();
|
|
assertEqual(400, results.length);
|
|
for (let [doc1, doc2] of results) {
|
|
assertTrue(i === doc2[shardKey]);
|
|
assertEqual(doc1.test, 1);
|
|
}
|
|
},
|
|
|
|
testInnerOuterSameIndex21 : function () {
|
|
dropIndexes(collectionByKey);
|
|
collectionByKey.ensureHashIndex(shardKey);
|
|
|
|
const i = 21;
|
|
const query = `
|
|
FOR doc1 IN ${cnKey}
|
|
FOR doc2 IN ${cnKey}
|
|
UPDATE doc1 WITH {test:1} IN ${cnKey}
|
|
FILTER doc2.${shardKey} == ${i}
|
|
RETURN [NEW, doc2]
|
|
`;
|
|
|
|
let raw = db._query(query, {}, disableSingleDocOp);
|
|
let stats = raw.getExtra().stats;
|
|
assertEqual(stats.writesExecuted, 10000);
|
|
let results = raw.toArray();
|
|
assertEqual(400, results.length);
|
|
for (let [doc1, doc2] of results) {
|
|
assertTrue(i === doc2[shardKey]);
|
|
assertEqual(doc1.test, 1);
|
|
}
|
|
},
|
|
|
|
testInnerOuterSame22 : function () {
|
|
dropIndexes(collectionByKey);
|
|
|
|
const i = 22;
|
|
const query = `
|
|
FOR doc1 IN ${cnKey}
|
|
FOR doc2 IN ${cnKey}
|
|
UPDATE doc1 WITH {test:1} IN ${cnKey}
|
|
RETURN [NEW, doc2]
|
|
`;
|
|
|
|
let raw = db._query(query, {}, disableSingleDocOp);
|
|
let stats = raw.getExtra().stats;
|
|
assertEqual(stats.writesExecuted, 10000);
|
|
let results = raw.toArray();
|
|
assertEqual(10000, results.length);
|
|
for (let [doc1, doc2] of results) {
|
|
assertEqual(doc1.test, 1);
|
|
}
|
|
},
|
|
|
|
testInnerOuterSameIndex22 : function () {
|
|
dropIndexes(collectionByKey);
|
|
collectionByKey.ensureHashIndex(shardKey);
|
|
|
|
const i = 22;
|
|
const query = `
|
|
FOR doc1 IN ${cnKey}
|
|
FOR doc2 IN ${cnKey}
|
|
UPDATE doc1 WITH {test:1} IN ${cnKey}
|
|
RETURN [NEW, doc2]
|
|
`;
|
|
|
|
let raw = db._query(query, {}, disableSingleDocOp);
|
|
let stats = raw.getExtra().stats;
|
|
assertEqual(stats.writesExecuted, 10000);
|
|
let results = raw.toArray();
|
|
assertEqual(10000, results.length);
|
|
for (let [doc1, doc2] of results) {
|
|
assertEqual(doc1.test, 1);
|
|
}
|
|
},
|
|
|
|
testInnerOuterSame23 : function () {
|
|
dropIndexes(collectionByKey);
|
|
|
|
for (let i = 0; i < 24; ++i) {
|
|
const query = `
|
|
FOR doc1 IN ${cnKey}
|
|
UPDATE doc1 WITH {test:1} IN ${cnKey}
|
|
FILTER NEW.${shardKey} == ${i}
|
|
RETURN NEW
|
|
`;
|
|
|
|
let raw = db._query(query, {}, disableSingleDocOp);
|
|
let stats = raw.getExtra().stats;
|
|
assertEqual(stats.writesExecuted, 100);
|
|
let results = raw.toArray();
|
|
assertEqual(4, results.length);
|
|
for (let doc of results) {
|
|
assertTrue(i === doc.value);
|
|
assertEqual(doc.test, 1);
|
|
}
|
|
}
|
|
},
|
|
|
|
testInnerOuterSameIndex23 : function () {
|
|
dropIndexes(collectionByKey);
|
|
collectionByKey.ensureHashIndex(shardKey);
|
|
|
|
for (let i = 0; i < 24; ++i) {
|
|
const query = `
|
|
FOR doc1 IN ${cnKey}
|
|
UPDATE doc1 WITH {test:1} IN ${cnKey}
|
|
FILTER NEW.${shardKey} == ${i}
|
|
RETURN NEW
|
|
`;
|
|
|
|
let raw = db._query(query, {}, disableSingleDocOp);
|
|
let stats = raw.getExtra().stats;
|
|
assertEqual(stats.writesExecuted, 100);
|
|
let results = raw.toArray();
|
|
assertEqual(4, results.length);
|
|
for (let doc of results) {
|
|
assertTrue(i === doc.value);
|
|
assertEqual(doc.test, 1);
|
|
}
|
|
}
|
|
},
|
|
|
|
testInnerOuterDifferent1 : function () {
|
|
dropIndexes(collectionByKey1);
|
|
dropIndexes(collectionByKey2);
|
|
|
|
for (let i = 0; i < 24; ++i) {
|
|
const query = `
|
|
FOR doc1 IN ${cnKey1}
|
|
FILTER doc1.${shardKey1} == ${i}
|
|
FOR doc2 IN ${cnKey2}
|
|
FILTER doc2.${shardKey2} == ${i}
|
|
RETURN [doc1, doc2]
|
|
`;
|
|
validatePlan(query, "EnumerateCollectionNode", collectionByKey1);
|
|
validatePlan(query, "EnumerateCollectionNode", collectionByKey2);
|
|
|
|
let raw = db._query(query, {}, disableSingleDocOp);
|
|
let results = raw.toArray();
|
|
assertEqual(16, results.length);
|
|
for (let [doc1, doc2] of results) {
|
|
assertTrue(i === doc1[shardKey1]);
|
|
assertTrue(i === doc2[shardKey2]);
|
|
}
|
|
}
|
|
},
|
|
|
|
testInnerOuterDifferentIndex1 : function () {
|
|
dropIndexes(collectionByKey1);
|
|
dropIndexes(collectionByKey2);
|
|
collectionByKey1.ensureHashIndex(shardKey1);
|
|
collectionByKey2.ensureHashIndex(shardKey2);
|
|
|
|
for (let i = 0; i < 24; ++i) {
|
|
const query = `
|
|
FOR doc1 IN ${cnKey1}
|
|
FILTER doc1.${shardKey1} == ${i}
|
|
FOR doc2 IN ${cnKey2}
|
|
FILTER doc2.${shardKey2} == ${i}
|
|
RETURN [doc1, doc2]
|
|
`;
|
|
validatePlan(query, "IndexNode", collectionByKey1);
|
|
validatePlan(query, "IndexNode", collectionByKey2);
|
|
|
|
let raw = db._query(query, {}, disableSingleDocOp);
|
|
let results = raw.toArray();
|
|
assertEqual(16, results.length);
|
|
for (let [doc1, doc2] of results) {
|
|
assertTrue(i === doc1[shardKey1]);
|
|
assertTrue(i === doc2[shardKey2]);
|
|
}
|
|
}
|
|
},
|
|
|
|
testInnerOuterDifferent2 : function () {
|
|
dropIndexes(collectionByKey1);
|
|
dropIndexes(collectionByKey2);
|
|
|
|
for (let i = 0; i < 24; ++i) {
|
|
const query = `
|
|
FOR doc1 IN ${cnKey1}
|
|
FILTER doc1.${shardKey1} == ${i}
|
|
FOR doc2 IN ${cnKey2}
|
|
FILTER doc2.${shardKey2} == ${i+1}
|
|
RETURN [doc1, doc2]
|
|
`;
|
|
// Multi-shard not implemented yet
|
|
// validatePlan(query, "EnumerateCollectionNode", collectionByKey1);
|
|
// validatePlan(query, "EnumerateCollectionNode", collectionByKey2);
|
|
|
|
let raw = db._query(query, {}, disableSingleDocOp);
|
|
let results = raw.toArray();
|
|
assertEqual(16, results.length);
|
|
for (let [doc1, doc2] of results) {
|
|
assertTrue(i === doc1[shardKey1]);
|
|
assertTrue(i + 1 === doc2.value);
|
|
}
|
|
}
|
|
},
|
|
|
|
testInnerOuterDifferentIndex2 : function () {
|
|
dropIndexes(collectionByKey1);
|
|
dropIndexes(collectionByKey2);
|
|
collectionByKey1.ensureHashIndex(shardKey1);
|
|
collectionByKey2.ensureHashIndex(shardKey2);
|
|
|
|
for (let i = 0; i < 24; ++i) {
|
|
const query = `
|
|
FOR doc1 IN ${cnKey1}
|
|
FILTER doc1.${shardKey1} == ${i}
|
|
FOR doc2 IN ${cnKey2}
|
|
FILTER doc2.${shardKey2} == ${i+1}
|
|
RETURN [doc1, doc2]
|
|
`;
|
|
// Multi-shard not implemented yet
|
|
// validatePlan(query, "EnumerateCollectionNode", collectionByKey1);
|
|
// validatePlan(query, "EnumerateCollectionNode", collectionByKey2);
|
|
|
|
let raw = db._query(query, {}, disableSingleDocOp);
|
|
let results = raw.toArray();
|
|
assertEqual(16, results.length);
|
|
for (let [doc1, doc2] of results) {
|
|
assertTrue(i === doc1[shardKey1]);
|
|
assertTrue(i + 1 === doc2.value);
|
|
}
|
|
}
|
|
},
|
|
|
|
testInnerOuterDifferent3 : function () {
|
|
dropIndexes(collectionByKey1);
|
|
dropIndexes(collectionByKey2);
|
|
|
|
for (let i = 0; i < 24; ++i) {
|
|
const query = `
|
|
FOR doc1 IN ${cnKey1}
|
|
FILTER doc1.${shardKey1} == ${i}
|
|
FOR doc2 IN ${cnKey2}
|
|
FILTER doc2.${shardKey2} == ${i}
|
|
UPDATE doc1 WITH {test:1} IN ${cnKey1}
|
|
RETURN [NEW, doc2]
|
|
`;
|
|
validatePlan(query, "EnumerateCollectionNode", collectionByKey1);
|
|
validatePlan(query, "EnumerateCollectionNode", collectionByKey2);
|
|
|
|
let raw = db._query(query, {}, disableSingleDocOp);
|
|
let stats = raw.getExtra().stats;
|
|
assertEqual(stats.writesExecuted, 16);
|
|
let results = raw.toArray();
|
|
assertEqual(16, results.length);
|
|
for (let [doc1, doc2] of results) {
|
|
assertTrue(i === doc1[shardKey1]);
|
|
assertTrue(i === doc2[shardKey2]);
|
|
assertEqual(doc1.test, 1);
|
|
}
|
|
}
|
|
},
|
|
|
|
testInnerOuterDifferentIndex3 : function () {
|
|
dropIndexes(collectionByKey1);
|
|
dropIndexes(collectionByKey2);
|
|
collectionByKey1.ensureHashIndex(shardKey1);
|
|
collectionByKey2.ensureHashIndex(shardKey2);
|
|
|
|
for (let i = 0; i < 24; ++i) {
|
|
const query = `
|
|
FOR doc1 IN ${cnKey1}
|
|
FILTER doc1.${shardKey1} == ${i}
|
|
FOR doc2 IN ${cnKey2}
|
|
FILTER doc2.${shardKey2} == ${i}
|
|
UPDATE doc1 WITH {test:1} IN ${cnKey1}
|
|
RETURN [NEW, doc2]
|
|
`;
|
|
validatePlan(query, "IndexNode", collectionByKey1);
|
|
validatePlan(query, "IndexNode", collectionByKey2);
|
|
|
|
let raw = db._query(query, {}, disableSingleDocOp);
|
|
let stats = raw.getExtra().stats;
|
|
assertEqual(stats.writesExecuted, 16);
|
|
let results = raw.toArray();
|
|
assertEqual(16, results.length);
|
|
for (let [doc1, doc2] of results) {
|
|
assertTrue(i === doc1[shardKey1]);
|
|
assertTrue(i === doc2[shardKey2]);
|
|
assertEqual(doc1.test, 1);
|
|
}
|
|
}
|
|
},
|
|
|
|
testInnerOuterDifferent4 : function () {
|
|
dropIndexes(collectionByKey1);
|
|
dropIndexes(collectionByKey2);
|
|
|
|
for (let i = 0; i < 24; ++i) {
|
|
const query = `
|
|
FOR doc1 IN ${cnKey1}
|
|
FILTER doc1.${shardKey1} == ${i}
|
|
FOR doc2 IN ${cnKey2}
|
|
RETURN doc1
|
|
`;
|
|
validatePlan(query, "EnumerateCollectionNode", collectionByKey1);
|
|
|
|
let raw = db._query(query, {}, disableSingleDocOp);
|
|
let results = raw.toArray();
|
|
assertEqual(400, results.length);
|
|
for (let doc of results) {
|
|
assertTrue(i === doc.value);
|
|
}
|
|
}
|
|
},
|
|
|
|
testInnerOuterDifferentIndex4 : function () {
|
|
dropIndexes(collectionByKey1);
|
|
dropIndexes(collectionByKey2);
|
|
collectionByKey1.ensureHashIndex(shardKey1);
|
|
collectionByKey2.ensureHashIndex(shardKey2);
|
|
|
|
for (let i = 0; i < 24; ++i) {
|
|
const query = `
|
|
FOR doc1 IN ${cnKey1}
|
|
FILTER doc1.${shardKey1} == ${i}
|
|
FOR doc2 IN ${cnKey2}
|
|
RETURN doc1
|
|
`;
|
|
validatePlan(query, "IndexNode", collectionByKey1);
|
|
|
|
let raw = db._query(query, {}, disableSingleDocOp);
|
|
let results = raw.toArray();
|
|
assertEqual(400, results.length);
|
|
for (let doc of results) {
|
|
assertTrue(i === doc.value);
|
|
}
|
|
}
|
|
},
|
|
|
|
testInnerOuterDifferent5 : function () {
|
|
dropIndexes(collectionByKey1);
|
|
dropIndexes(collectionByKey2);
|
|
|
|
for (let i = 0; i < 24; ++i) {
|
|
const query = `
|
|
FOR doc1 IN ${cnKey1}
|
|
FILTER doc1.${shardKey1} == ${i}
|
|
FOR doc2 IN ${cnKey2}
|
|
UPDATE doc1 WITH {test:1} IN ${cnKey1}
|
|
FILTER doc2.${shardKey2} == ${i}
|
|
RETURN [NEW, doc2]
|
|
`;
|
|
validatePlan(query, "EnumerateCollectionNode", collectionByKey1);
|
|
|
|
let raw = db._query(query, {}, disableSingleDocOp);
|
|
let stats = raw.getExtra().stats;
|
|
assertEqual(stats.writesExecuted, 400);
|
|
let results = raw.toArray();
|
|
assertEqual(16, results.length);
|
|
for (let [doc1, doc2] of results) {
|
|
assertTrue(i === doc1[shardKey1]);
|
|
assertTrue(i === doc2[shardKey2]);
|
|
assertEqual(doc1.test, 1);
|
|
}
|
|
}
|
|
},
|
|
|
|
testInnerOuterDifferentIndex5 : function () {
|
|
dropIndexes(collectionByKey1);
|
|
dropIndexes(collectionByKey2);
|
|
collectionByKey1.ensureHashIndex(shardKey1);
|
|
collectionByKey2.ensureHashIndex(shardKey2);
|
|
|
|
for (let i = 0; i < 24; ++i) {
|
|
const query = `
|
|
FOR doc1 IN ${cnKey1}
|
|
FILTER doc1.${shardKey1} == ${i}
|
|
FOR doc2 IN ${cnKey2}
|
|
UPDATE doc1 WITH {test:1} IN ${cnKey1}
|
|
FILTER doc2.${shardKey2} == ${i}
|
|
RETURN [NEW, doc2]
|
|
`;
|
|
validatePlan(query, "IndexNode", collectionByKey1);
|
|
|
|
let raw = db._query(query, {}, disableSingleShard);
|
|
let stats = raw.getExtra().stats;
|
|
assertEqual(stats.writesExecuted, 400);
|
|
let results = raw.toArray();
|
|
assertEqual(16, results.length);
|
|
for (let [doc1, doc2] of results) {
|
|
assertTrue(i === doc1[shardKey1]);
|
|
assertTrue(i === doc2[shardKey2]);
|
|
assertEqual(doc1.test, 1);
|
|
}
|
|
}
|
|
},
|
|
|
|
testInnerOuterDifferent6 : function () {
|
|
dropIndexes(collectionByKey1);
|
|
dropIndexes(collectionByKey2);
|
|
|
|
for (let i = 0; i < 24; ++i) {
|
|
const query = `
|
|
FOR doc1 IN ${cnKey1}
|
|
FILTER doc1.${shardKey1} == ${i}
|
|
FOR doc2 IN ${cnKey2}
|
|
UPDATE doc1 WITH {test:1} IN ${cnKey1}
|
|
RETURN [NEW, doc2]
|
|
`;
|
|
validatePlan(query, "EnumerateCollectionNode", collectionByKey1);
|
|
|
|
let raw = db._query(query, {}, disableSingleDocOp);
|
|
let stats = raw.getExtra().stats;
|
|
assertEqual(stats.writesExecuted, 400);
|
|
let results = raw.toArray();
|
|
assertEqual(400, results.length);
|
|
for (let [doc1, doc2] of results) {
|
|
assertTrue(i === doc1[shardKey1]);
|
|
assertEqual(doc1.test, 1);
|
|
}
|
|
}
|
|
},
|
|
|
|
testInnerOuterDifferentIndex6 : function () {
|
|
dropIndexes(collectionByKey1);
|
|
dropIndexes(collectionByKey2);
|
|
collectionByKey1.ensureHashIndex(shardKey1);
|
|
collectionByKey2.ensureHashIndex(shardKey2);
|
|
|
|
for (let i = 0; i < 24; ++i) {
|
|
const query = `
|
|
FOR doc1 IN ${cnKey1}
|
|
FILTER doc1.${shardKey1} == ${i}
|
|
FOR doc2 IN ${cnKey2}
|
|
UPDATE doc1 WITH {test:1} IN ${cnKey1}
|
|
RETURN [NEW, doc2]
|
|
`;
|
|
validatePlan(query, "IndexNode", collectionByKey1);
|
|
|
|
let raw = db._query(query, {}, disableSingleDocOp);
|
|
let stats = raw.getExtra().stats;
|
|
assertEqual(stats.writesExecuted, 400);
|
|
let results = raw.toArray();
|
|
assertEqual(400, results.length);
|
|
for (let [doc1, doc2] of results) {
|
|
assertTrue(i === doc1[shardKey1]);
|
|
assertEqual(doc1.test, 1);
|
|
}
|
|
}
|
|
},
|
|
|
|
testInnerOuterDifferent7 : function () {
|
|
dropIndexes(collectionByKey1);
|
|
dropIndexes(collectionByKey2);
|
|
|
|
for (let i = 0; i < 24; ++i) {
|
|
const query = `
|
|
FOR doc1 IN ${cnKey1}
|
|
FOR doc2 IN ${cnKey2}
|
|
FILTER doc1.${shardKey1} == ${i}
|
|
FILTER doc2.${shardKey2} == ${i}
|
|
RETURN [doc1, doc2]
|
|
`;
|
|
validatePlan(query, "EnumerateCollectionNode", collectionByKey1);
|
|
validatePlan(query, "EnumerateCollectionNode", collectionByKey2);
|
|
|
|
let raw = db._query(query, {}, disableSingleDocOp);
|
|
let results = raw.toArray();
|
|
assertEqual(16, results.length);
|
|
for (let [doc1, doc2] of results) {
|
|
assertTrue(i === doc1[shardKey1]);
|
|
assertTrue(i === doc2[shardKey2]);
|
|
}
|
|
}
|
|
},
|
|
|
|
testInnerOuterDifferentIndex7 : function () {
|
|
dropIndexes(collectionByKey1);
|
|
dropIndexes(collectionByKey2);
|
|
collectionByKey1.ensureHashIndex(shardKey1);
|
|
collectionByKey2.ensureHashIndex(shardKey2);
|
|
|
|
for (let i = 0; i < 24; ++i) {
|
|
const query = `
|
|
FOR doc1 IN ${cnKey1}
|
|
FOR doc2 IN ${cnKey2}
|
|
FILTER doc1.${shardKey1} == ${i}
|
|
FILTER doc2.${shardKey2} == ${i}
|
|
RETURN [doc1, doc2]
|
|
`;
|
|
validatePlan(query, "IndexNode", collectionByKey1);
|
|
validatePlan(query, "IndexNode", collectionByKey2);
|
|
|
|
let raw = db._query(query, {}, disableSingleDocOp);
|
|
let results = raw.toArray();
|
|
assertEqual(16, results.length);
|
|
for (let [doc1, doc2] of results) {
|
|
assertTrue(i === doc1[shardKey1]);
|
|
assertTrue(i === doc2[shardKey2]);
|
|
}
|
|
}
|
|
},
|
|
|
|
testInnerOuterDifferent8 : function () {
|
|
dropIndexes(collectionByKey1);
|
|
dropIndexes(collectionByKey2);
|
|
|
|
for (let i = 0; i < 24; ++i) {
|
|
const query = `
|
|
FOR doc1 IN ${cnKey1}
|
|
FOR doc2 IN ${cnKey2}
|
|
FILTER doc1.${shardKey1} == ${i}
|
|
FILTER doc2.${shardKey2} == ${i}
|
|
UPDATE doc1 WITH {test:1} IN ${cnKey1}
|
|
RETURN [NEW, doc2]
|
|
`;
|
|
validatePlan(query, "EnumerateCollectionNode", collectionByKey1);
|
|
validatePlan(query, "EnumerateCollectionNode", collectionByKey2);
|
|
|
|
let raw = db._query(query, {}, disableSingleDocOp);
|
|
let stats = raw.getExtra().stats;
|
|
assertEqual(stats.writesExecuted, 16);
|
|
let results = raw.toArray();
|
|
assertEqual(16, results.length);
|
|
for (let [doc1, doc2] of results) {
|
|
assertTrue(i === doc1[shardKey1]);
|
|
assertTrue(i === doc2[shardKey2]);
|
|
assertEqual(doc1.test, 1);
|
|
}
|
|
}
|
|
},
|
|
|
|
testInnerOuterDifferentIndex8 : function () {
|
|
dropIndexes(collectionByKey1);
|
|
dropIndexes(collectionByKey2);
|
|
collectionByKey1.ensureHashIndex(shardKey1);
|
|
collectionByKey2.ensureHashIndex(shardKey2);
|
|
|
|
for (let i = 0; i < 24; ++i) {
|
|
const query = `
|
|
FOR doc1 IN ${cnKey1}
|
|
FOR doc2 IN ${cnKey2}
|
|
FILTER doc1.${shardKey1} == ${i}
|
|
FILTER doc2.${shardKey2} == ${i}
|
|
UPDATE doc1 WITH {test:1} IN ${cnKey1}
|
|
RETURN [NEW, doc2]
|
|
`;
|
|
validatePlan(query, "IndexNode", collectionByKey1);
|
|
validatePlan(query, "IndexNode", collectionByKey2);
|
|
|
|
let raw = db._query(query, {}, disableSingleDocOp);
|
|
let stats = raw.getExtra().stats;
|
|
assertEqual(stats.writesExecuted, 16);
|
|
let results = raw.toArray();
|
|
assertEqual(16, results.length);
|
|
for (let [doc1, doc2] of results) {
|
|
assertTrue(i === doc1[shardKey1]);
|
|
assertTrue(i === doc2[shardKey2]);
|
|
assertEqual(doc1.test, 1);
|
|
}
|
|
}
|
|
},
|
|
|
|
testInnerOuterDifferent9 : function () {
|
|
dropIndexes(collectionByKey1);
|
|
dropIndexes(collectionByKey2);
|
|
|
|
for (let i = 0; i < 24; ++i) {
|
|
const query = `
|
|
FOR doc1 IN ${cnKey1}
|
|
FOR doc2 IN ${cnKey2}
|
|
FILTER doc1.${shardKey1} == ${i}
|
|
RETURN [doc1, doc2]
|
|
`;
|
|
validatePlan(query, "EnumerateCollectionNode", collectionByKey1);
|
|
|
|
let raw = db._query(query, {}, disableSingleDocOp);
|
|
let results = raw.toArray();
|
|
assertEqual(400, results.length);
|
|
for (let [doc1, doc2] of results) {
|
|
assertTrue(i === doc1[shardKey1]);
|
|
}
|
|
}
|
|
},
|
|
|
|
testInnerOuterDifferentIndex9 : function () {
|
|
dropIndexes(collectionByKey1);
|
|
dropIndexes(collectionByKey2);
|
|
collectionByKey1.ensureHashIndex(shardKey1);
|
|
collectionByKey2.ensureHashIndex(shardKey2);
|
|
|
|
for (let i = 0; i < 24; ++i) {
|
|
const query = `
|
|
FOR doc1 IN ${cnKey1}
|
|
FOR doc2 IN ${cnKey2}
|
|
FILTER doc1.${shardKey1} == ${i}
|
|
RETURN [doc1, doc2]
|
|
`;
|
|
validatePlan(query, "IndexNode", collectionByKey1);
|
|
|
|
let raw = db._query(query, {}, disableSingleDocOp);
|
|
let results = raw.toArray();
|
|
assertEqual(400, results.length);
|
|
for (let [doc1, doc2] of results) {
|
|
assertTrue(i === doc1[shardKey1]);
|
|
}
|
|
}
|
|
},
|
|
|
|
testInnerOuterDifferent10 : function () {
|
|
dropIndexes(collectionByKey1);
|
|
dropIndexes(collectionByKey2);
|
|
|
|
for (let i = 0; i < 24; ++i) {
|
|
const query = `
|
|
FOR doc1 IN ${cnKey1}
|
|
FOR doc2 IN ${cnKey2}
|
|
FILTER doc1.${shardKey1} == ${i}
|
|
UPDATE doc1 WITH {test:1} IN ${cnKey1}
|
|
FILTER doc2.${shardKey2} == ${i}
|
|
RETURN [NEW, doc2]
|
|
`;
|
|
validatePlan(query, "EnumerateCollectionNode", collectionByKey1);
|
|
|
|
let raw = db._query(query, {}, disableSingleDocOp);
|
|
let stats = raw.getExtra().stats;
|
|
assertEqual(stats.writesExecuted, 400);
|
|
let results = raw.toArray();
|
|
assertEqual(16, results.length);
|
|
for (let [doc1, doc2] of results) {
|
|
assertTrue(i === doc1[shardKey1]);
|
|
assertTrue(i === doc2[shardKey2]);
|
|
assertEqual(doc1.test, 1);
|
|
}
|
|
}
|
|
},
|
|
|
|
testInnerOuterDifferentIndex10 : function () {
|
|
dropIndexes(collectionByKey1);
|
|
dropIndexes(collectionByKey2);
|
|
collectionByKey1.ensureHashIndex(shardKey1);
|
|
collectionByKey2.ensureHashIndex(shardKey2);
|
|
|
|
for (let i = 0; i < 24; ++i) {
|
|
const query = `
|
|
FOR doc1 IN ${cnKey1}
|
|
FOR doc2 IN ${cnKey2}
|
|
FILTER doc1.${shardKey1} == ${i}
|
|
UPDATE doc1 WITH {test:1} IN ${cnKey1}
|
|
FILTER doc2.${shardKey2} == ${i}
|
|
RETURN [NEW, doc2]
|
|
`;
|
|
validatePlan(query, "IndexNode", collectionByKey1);
|
|
|
|
let raw = db._query(query, {}, disableSingleShard);
|
|
let stats = raw.getExtra().stats;
|
|
assertEqual(stats.writesExecuted, 400);
|
|
let results = raw.toArray();
|
|
assertEqual(16, results.length);
|
|
for (let [doc1, doc2] of results) {
|
|
assertTrue(i === doc1[shardKey1]);
|
|
assertTrue(i === doc2[shardKey2]);
|
|
assertEqual(doc1.test, 1);
|
|
}
|
|
}
|
|
},
|
|
|
|
testInnerOuterDifferent11 : function () {
|
|
dropIndexes(collectionByKey1);
|
|
dropIndexes(collectionByKey2);
|
|
|
|
for (let i = 0; i < 24; ++i) {
|
|
const query = `
|
|
FOR doc1 IN ${cnKey1}
|
|
FOR doc2 IN ${cnKey2}
|
|
FILTER doc1.${shardKey1} == ${i}
|
|
UPDATE doc1 WITH {test:1} IN ${cnKey1}
|
|
RETURN [NEW, doc2]
|
|
`;
|
|
validatePlan(query, "EnumerateCollectionNode", collectionByKey1);
|
|
|
|
let raw = db._query(query, {}, disableSingleDocOp);
|
|
let stats = raw.getExtra().stats;
|
|
assertEqual(stats.writesExecuted, 400);
|
|
let results = raw.toArray();
|
|
assertEqual(400, results.length);
|
|
for (let [doc1, doc2] of results) {
|
|
assertTrue(i === doc1[shardKey1]);
|
|
assertEqual(doc1.test, 1);
|
|
}
|
|
}
|
|
},
|
|
|
|
testInnerOuterDifferentIndex11 : function () {
|
|
dropIndexes(collectionByKey1);
|
|
dropIndexes(collectionByKey2);
|
|
collectionByKey1.ensureHashIndex(shardKey1);
|
|
collectionByKey2.ensureHashIndex(shardKey2);
|
|
|
|
for (let i = 0; i < 24; ++i) {
|
|
const query = `
|
|
FOR doc1 IN ${cnKey1}
|
|
FOR doc2 IN ${cnKey2}
|
|
FILTER doc1.${shardKey1} == ${i}
|
|
UPDATE doc1 WITH {test:1} IN ${cnKey1}
|
|
RETURN [NEW, doc2]
|
|
`;
|
|
validatePlan(query, "IndexNode", collectionByKey1);
|
|
|
|
let raw = db._query(query, {}, disableSingleDocOp);
|
|
let stats = raw.getExtra().stats;
|
|
assertEqual(stats.writesExecuted, 400);
|
|
let results = raw.toArray();
|
|
assertEqual(400, results.length);
|
|
for (let [doc1, doc2] of results) {
|
|
assertTrue(i === doc1[shardKey1]);
|
|
assertEqual(doc1.test, 1);
|
|
}
|
|
}
|
|
},
|
|
|
|
testInnerOuterDifferent12 : function () {
|
|
dropIndexes(collectionByKey1);
|
|
dropIndexes(collectionByKey2);
|
|
|
|
for (let i = 0; i < 24; ++i) {
|
|
const query = `
|
|
FOR doc1 IN ${cnKey1}
|
|
FOR doc2 IN ${cnKey2}
|
|
FILTER doc2.${shardKey2} == ${i}
|
|
FILTER doc1.${shardKey1} == ${i}
|
|
RETURN [doc1, doc2]
|
|
`;
|
|
validatePlan(query, "EnumerateCollectionNode", collectionByKey1);
|
|
validatePlan(query, "EnumerateCollectionNode", collectionByKey2);
|
|
|
|
let raw = db._query(query, {}, disableSingleDocOp);
|
|
let results = raw.toArray();
|
|
assertEqual(16, results.length);
|
|
for (let [doc1, doc2] of results) {
|
|
assertTrue(i === doc1[shardKey1]);
|
|
assertTrue(i === doc2[shardKey2]);
|
|
}
|
|
}
|
|
},
|
|
|
|
testInnerOuterDifferentIndex12 : function () {
|
|
dropIndexes(collectionByKey1);
|
|
dropIndexes(collectionByKey2);
|
|
collectionByKey1.ensureHashIndex(shardKey1);
|
|
collectionByKey2.ensureHashIndex(shardKey2);
|
|
|
|
for (let i = 0; i < 24; ++i) {
|
|
const query = `
|
|
FOR doc1 IN ${cnKey1}
|
|
FOR doc2 IN ${cnKey2}
|
|
FILTER doc2.${shardKey2} == ${i}
|
|
FILTER doc1.${shardKey1} == ${i}
|
|
RETURN [doc1, doc2]
|
|
`;
|
|
validatePlan(query, "IndexNode", collectionByKey1);
|
|
validatePlan(query, "IndexNode", collectionByKey2);
|
|
|
|
let raw = db._query(query, {}, disableSingleDocOp);
|
|
let results = raw.toArray();
|
|
assertEqual(16, results.length);
|
|
for (let [doc1, doc2] of results) {
|
|
assertTrue(i === doc1[shardKey1]);
|
|
assertTrue(i === doc2[shardKey2]);
|
|
}
|
|
}
|
|
},
|
|
|
|
testInnerOuterDifferent13 : function () {
|
|
dropIndexes(collectionByKey1);
|
|
dropIndexes(collectionByKey2);
|
|
|
|
for (let i = 0; i < 24; ++i) {
|
|
const query = `
|
|
FOR doc1 IN ${cnKey1}
|
|
FOR doc2 IN ${cnKey2}
|
|
FILTER doc2.${shardKey2} == ${i}
|
|
FILTER doc1.${shardKey1} == ${i}
|
|
UPDATE doc1 WITH {test:1} IN ${cnKey1}
|
|
RETURN [NEW, doc2]
|
|
`;
|
|
validatePlan(query, "EnumerateCollectionNode", collectionByKey1);
|
|
validatePlan(query, "EnumerateCollectionNode", collectionByKey2);
|
|
|
|
let raw = db._query(query, {}, disableSingleDocOp);
|
|
let stats = raw.getExtra().stats;
|
|
assertEqual(stats.writesExecuted, 16);
|
|
let results = raw.toArray();
|
|
assertEqual(16, results.length);
|
|
for (let [doc1, doc2] of results) {
|
|
assertTrue(i === doc1[shardKey1]);
|
|
assertTrue(i === doc2[shardKey2]);
|
|
assertEqual(doc1.test, 1);
|
|
}
|
|
}
|
|
},
|
|
|
|
testInnerOuterDifferentIndex13 : function () {
|
|
dropIndexes(collectionByKey1);
|
|
dropIndexes(collectionByKey2);
|
|
collectionByKey1.ensureHashIndex(shardKey1);
|
|
collectionByKey2.ensureHashIndex(shardKey2);
|
|
|
|
for (let i = 0; i < 24; ++i) {
|
|
const query = `
|
|
FOR doc1 IN ${cnKey1}
|
|
FOR doc2 IN ${cnKey2}
|
|
FILTER doc2.${shardKey2} == ${i}
|
|
FILTER doc1.${shardKey1} == ${i}
|
|
UPDATE doc1 WITH {test:1} IN ${cnKey1}
|
|
RETURN [NEW, doc2]
|
|
`;
|
|
validatePlan(query, "IndexNode", collectionByKey1);
|
|
validatePlan(query, "IndexNode", collectionByKey2);
|
|
|
|
let raw = db._query(query, {}, disableSingleDocOp);
|
|
let stats = raw.getExtra().stats;
|
|
assertEqual(stats.writesExecuted, 16);
|
|
let results = raw.toArray();
|
|
assertEqual(16, results.length);
|
|
for (let [doc1, doc2] of results) {
|
|
assertTrue(i === doc1[shardKey1]);
|
|
assertTrue(i === doc2[shardKey2]);
|
|
assertEqual(doc1.test, 1);
|
|
}
|
|
}
|
|
},
|
|
|
|
testInnerOuterDifferent14 : function () {
|
|
dropIndexes(collectionByKey1);
|
|
dropIndexes(collectionByKey2);
|
|
|
|
for (let i = 0; i < 24; ++i) {
|
|
const query = `
|
|
FOR doc1 IN ${cnKey1}
|
|
FOR doc2 IN ${cnKey2}
|
|
FILTER doc2.${shardKey2} == ${i}
|
|
RETURN [doc1, doc2]
|
|
`;
|
|
validatePlan(query, "EnumerateCollectionNode", collectionByKey2);
|
|
|
|
let raw = db._query(query, {}, disableSingleDocOp);
|
|
let results = raw.toArray();
|
|
assertEqual(400, results.length);
|
|
for (let [doc1, doc2] of results) {
|
|
assertTrue(i === doc2[shardKey2]);
|
|
}
|
|
}
|
|
},
|
|
|
|
testInnerOuterDifferentIndex14 : function () {
|
|
dropIndexes(collectionByKey1);
|
|
dropIndexes(collectionByKey2);
|
|
collectionByKey1.ensureHashIndex(shardKey1);
|
|
collectionByKey2.ensureHashIndex(shardKey2);
|
|
|
|
for (let i = 0; i < 24; ++i) {
|
|
const query = `
|
|
FOR doc1 IN ${cnKey1}
|
|
FOR doc2 IN ${cnKey2}
|
|
FILTER doc2.${shardKey2} == ${i}
|
|
RETURN [doc1, doc2]
|
|
`;
|
|
validatePlan(query, "IndexNode", collectionByKey2);
|
|
|
|
let raw = db._query(query, {}, disableSingleDocOp);
|
|
let results = raw.toArray();
|
|
assertEqual(400, results.length);
|
|
for (let [doc1, doc2] of results) {
|
|
assertTrue(i === doc2[shardKey2]);
|
|
}
|
|
}
|
|
},
|
|
|
|
testInnerOuterDifferent15 : function () {
|
|
dropIndexes(collectionByKey1);
|
|
dropIndexes(collectionByKey2);
|
|
|
|
for (let i = 0; i < 24; ++i) {
|
|
const query = `
|
|
FOR doc1 IN ${cnKey1}
|
|
FOR doc2 IN ${cnKey2}
|
|
FILTER doc2.${shardKey2} == ${i}
|
|
UPDATE doc1 WITH {test:1} IN ${cnKey1}
|
|
FILTER NEW.${shardKey1} == ${i}
|
|
RETURN [NEW, doc2]
|
|
`;
|
|
validatePlan(query, "EnumerateCollectionNode", collectionByKey2);
|
|
|
|
let raw = db._query(query, {}, disableSingleShard);
|
|
let stats = raw.getExtra().stats;
|
|
assertEqual(stats.writesExecuted, 400);
|
|
let results = raw.toArray();
|
|
assertEqual(16, results.length);
|
|
for (let [doc1, doc2] of results) {
|
|
assertTrue(i === doc1[shardKey1]);
|
|
assertTrue(i === doc2[shardKey2]);
|
|
assertEqual(doc1.test, 1);
|
|
}
|
|
}
|
|
},
|
|
|
|
testInnerOuterDifferentIndex15 : function () {
|
|
dropIndexes(collectionByKey1);
|
|
dropIndexes(collectionByKey2);
|
|
collectionByKey1.ensureHashIndex(shardKey1);
|
|
collectionByKey2.ensureHashIndex(shardKey2);
|
|
|
|
for (let i = 0; i < 24; ++i) {
|
|
const query = `
|
|
FOR doc1 IN ${cnKey1}
|
|
FOR doc2 IN ${cnKey2}
|
|
FILTER doc2.${shardKey2} == ${i}
|
|
UPDATE doc1 WITH {test:1} IN ${cnKey1}
|
|
FILTER NEW.${shardKey1} == ${i}
|
|
RETURN [NEW, doc2]
|
|
`;
|
|
validatePlan(query, "IndexNode", collectionByKey2);
|
|
|
|
let raw = db._query(query, {}, disableSingleShard);
|
|
let stats = raw.getExtra().stats;
|
|
assertEqual(stats.writesExecuted, 400);
|
|
let results = raw.toArray();
|
|
assertEqual(16, results.length);
|
|
for (let [doc1, doc2] of results) {
|
|
assertTrue(i === doc1[shardKey1]);
|
|
assertTrue(i === doc2[shardKey2]);
|
|
assertEqual(doc1.test, 1);
|
|
}
|
|
}
|
|
},
|
|
|
|
testInnerOuterDifferent16 : function () {
|
|
dropIndexes(collectionByKey1);
|
|
dropIndexes(collectionByKey2);
|
|
|
|
for (let i = 0; i < 24; ++i) {
|
|
const query = `
|
|
FOR doc1 IN ${cnKey1}
|
|
FOR doc2 IN ${cnKey2}
|
|
FILTER doc2.${shardKey2} == ${i}
|
|
UPDATE doc1 WITH {test:1} IN ${cnKey1}
|
|
RETURN [NEW, doc2]
|
|
`;
|
|
validatePlan(query, "EnumerateCollectionNode", collectionByKey2);
|
|
|
|
let raw = db._query(query, {}, disableSingleDocOp);
|
|
let stats = raw.getExtra().stats;
|
|
assertEqual(stats.writesExecuted, 400);
|
|
let results = raw.toArray();
|
|
assertEqual(400, results.length);
|
|
for (let [doc1, doc2] of results) {
|
|
assertTrue(i === doc2[shardKey2]);
|
|
assertEqual(doc1.test, 1);
|
|
}
|
|
}
|
|
},
|
|
|
|
testInnerOuterDifferentIndex16 : function () {
|
|
dropIndexes(collectionByKey1);
|
|
dropIndexes(collectionByKey2);
|
|
collectionByKey1.ensureHashIndex(shardKey1);
|
|
collectionByKey2.ensureHashIndex(shardKey2);
|
|
|
|
for (let i = 0; i < 24; ++i) {
|
|
const query = `
|
|
FOR doc1 IN ${cnKey1}
|
|
FOR doc2 IN ${cnKey2}
|
|
FILTER doc2.${shardKey2} == ${i}
|
|
UPDATE doc1 WITH {test:1} IN ${cnKey1}
|
|
RETURN [NEW, doc2]
|
|
`;
|
|
validatePlan(query, "IndexNode", collectionByKey2);
|
|
|
|
let raw = db._query(query, {}, disableSingleDocOp);
|
|
let stats = raw.getExtra().stats;
|
|
assertEqual(stats.writesExecuted, 400);
|
|
let results = raw.toArray();
|
|
assertEqual(400, results.length);
|
|
for (let [doc1, doc2] of results) {
|
|
assertTrue(i === doc2[shardKey2]);
|
|
assertEqual(doc1.test, 1);
|
|
}
|
|
}
|
|
},
|
|
|
|
testInnerOuterDifferent17 : function () {
|
|
dropIndexes(collectionByKey1);
|
|
dropIndexes(collectionByKey2);
|
|
|
|
const i = 17;
|
|
const query = `
|
|
FOR doc1 IN ${cnKey1}
|
|
FOR doc2 IN ${cnKey2}
|
|
UPDATE doc1 WITH {test:1} IN ${cnKey1}
|
|
FILTER NEW.${shardKey1} == ${i}
|
|
FILTER doc2.${shardKey2} == ${i}
|
|
RETURN [NEW, doc2]
|
|
`;
|
|
|
|
let raw = db._query(query, {}, disableSingleShard);
|
|
let stats = raw.getExtra().stats;
|
|
assertEqual(stats.writesExecuted, 10000);
|
|
let results = raw.toArray();
|
|
assertEqual(16, results.length);
|
|
for (let [doc1, doc2] of results) {
|
|
assertTrue(i === doc1[shardKey1]);
|
|
assertTrue(i === doc2[shardKey2]);
|
|
assertEqual(doc1.test, 1);
|
|
}
|
|
},
|
|
|
|
testInnerOuterDifferentIndex17 : function () {
|
|
dropIndexes(collectionByKey1);
|
|
dropIndexes(collectionByKey2);
|
|
collectionByKey1.ensureHashIndex(shardKey1);
|
|
collectionByKey2.ensureHashIndex(shardKey2);
|
|
|
|
const i = 17;
|
|
const query = `
|
|
FOR doc1 IN ${cnKey1}
|
|
FOR doc2 IN ${cnKey2}
|
|
UPDATE doc1 WITH {test:1} IN ${cnKey1}
|
|
FILTER NEW.${shardKey1} == ${i}
|
|
FILTER doc2.${shardKey2} == ${i}
|
|
RETURN [NEW, doc2]
|
|
`;
|
|
|
|
let raw = db._query(query, {}, disableSingleShard);
|
|
let stats = raw.getExtra().stats;
|
|
assertEqual(stats.writesExecuted, 10000);
|
|
let results = raw.toArray();
|
|
assertEqual(16, results.length);
|
|
for (let [doc1, doc2] of results) {
|
|
assertTrue(i === doc1[shardKey1]);
|
|
assertTrue(i === doc2[shardKey2]);
|
|
assertEqual(doc1.test, 1);
|
|
}
|
|
},
|
|
|
|
testInnerOuterDifferent18 : function () {
|
|
dropIndexes(collectionByKey1);
|
|
dropIndexes(collectionByKey2);
|
|
|
|
const i = 18;
|
|
const query = `
|
|
FOR doc1 IN ${cnKey1}
|
|
FOR doc2 IN ${cnKey2}
|
|
UPDATE doc1 WITH {test:1} IN ${cnKey1}
|
|
FILTER NEW.${shardKey1} == ${i}
|
|
RETURN [NEW, doc2]
|
|
`;
|
|
|
|
let raw = db._query(query, {}, disableSingleDocOp);
|
|
let stats = raw.getExtra().stats;
|
|
assertEqual(stats.writesExecuted, 10000);
|
|
let results = raw.toArray();
|
|
assertEqual(400, results.length);
|
|
for (let [doc1, doc2] of results) {
|
|
assertTrue(i === doc1[shardKey1]);
|
|
assertEqual(doc1.test, 1);
|
|
}
|
|
},
|
|
|
|
testInnerOuterDifferentIndex18 : function () {
|
|
dropIndexes(collectionByKey1);
|
|
dropIndexes(collectionByKey2);
|
|
collectionByKey1.ensureHashIndex(shardKey1);
|
|
collectionByKey2.ensureHashIndex(shardKey2);
|
|
|
|
const i = 18;
|
|
const query = `
|
|
FOR doc1 IN ${cnKey1}
|
|
FOR doc2 IN ${cnKey2}
|
|
UPDATE doc1 WITH {test:1} IN ${cnKey1}
|
|
FILTER NEW.${shardKey1} == ${i}
|
|
RETURN [NEW, doc2]
|
|
`;
|
|
|
|
let raw = db._query(query, {}, disableSingleDocOp);
|
|
let stats = raw.getExtra().stats;
|
|
assertEqual(stats.writesExecuted, 10000);
|
|
let results = raw.toArray();
|
|
assertEqual(400, results.length);
|
|
for (let [doc1, doc2] of results) {
|
|
assertTrue(i === doc1[shardKey1]);
|
|
assertEqual(doc1.test, 1);
|
|
}
|
|
},
|
|
|
|
testInnerOuterDifferent19 : function () {
|
|
dropIndexes(collectionByKey1);
|
|
dropIndexes(collectionByKey2);
|
|
|
|
const i = 19;
|
|
const query = `
|
|
FOR doc1 IN ${cnKey1}
|
|
FOR doc2 IN ${cnKey2}
|
|
UPDATE doc1 WITH {test:1} IN ${cnKey1}
|
|
FILTER doc2.${shardKey2} == ${i}
|
|
FILTER NEW.${shardKey1} == ${i}
|
|
RETURN [NEW, doc2]
|
|
`;
|
|
|
|
let raw = db._query(query, {}, disableSingleDocOp);
|
|
let stats = raw.getExtra().stats;
|
|
assertEqual(stats.writesExecuted, 10000);
|
|
let results = raw.toArray();
|
|
assertEqual(16, results.length);
|
|
for (let [doc1, doc2] of results) {
|
|
assertTrue(i === doc1[shardKey1]);
|
|
assertTrue(i === doc2[shardKey2]);
|
|
assertEqual(doc1.test, 1);
|
|
}
|
|
},
|
|
|
|
testInnerOuterDifferentIndex19 : function () {
|
|
dropIndexes(collectionByKey1);
|
|
dropIndexes(collectionByKey2);
|
|
collectionByKey1.ensureHashIndex(shardKey1);
|
|
collectionByKey2.ensureHashIndex(shardKey2);
|
|
|
|
const i = 19;
|
|
const query = `
|
|
FOR doc1 IN ${cnKey1}
|
|
FOR doc2 IN ${cnKey2}
|
|
UPDATE doc1 WITH {test:1} IN ${cnKey1}
|
|
FILTER doc2.${shardKey2} == ${i}
|
|
FILTER NEW.${shardKey1} == ${i}
|
|
RETURN [NEW, doc2]
|
|
`;
|
|
|
|
let raw = db._query(query, {}, disableSingleDocOp);
|
|
let stats = raw.getExtra().stats;
|
|
assertEqual(stats.writesExecuted, 10000);
|
|
let results = raw.toArray();
|
|
assertEqual(16, results.length);
|
|
for (let [doc1, doc2] of results) {
|
|
assertTrue(i === doc1[shardKey1]);
|
|
assertTrue(i === doc2[shardKey2]);
|
|
assertEqual(doc1.test, 1);
|
|
}
|
|
},
|
|
|
|
testInnerOuterDifferent20 : function () {
|
|
dropIndexes(collectionByKey1);
|
|
dropIndexes(collectionByKey2);
|
|
|
|
const i = 20;
|
|
const query = `
|
|
FOR doc1 IN ${cnKey1}
|
|
FOR doc2 IN ${cnKey2}
|
|
UPDATE doc1 WITH {test:1} IN ${cnKey1}
|
|
FILTER doc2.${shardKey2} == ${i}
|
|
RETURN [NEW, doc2]
|
|
`;
|
|
|
|
let raw = db._query(query, {}, disableSingleDocOp);
|
|
let stats = raw.getExtra().stats;
|
|
assertEqual(stats.writesExecuted, 10000);
|
|
let results = raw.toArray();
|
|
assertEqual(400, results.length);
|
|
for (let [doc1, doc2] of results) {
|
|
assertTrue(i === doc2[shardKey2]);
|
|
assertEqual(doc1.test, 1);
|
|
}
|
|
},
|
|
|
|
testInnerOuterDifferentIndex20 : function () {
|
|
dropIndexes(collectionByKey1);
|
|
dropIndexes(collectionByKey2);
|
|
collectionByKey1.ensureHashIndex(shardKey1);
|
|
collectionByKey2.ensureHashIndex(shardKey2);
|
|
|
|
const i = 20;
|
|
const query = `
|
|
FOR doc1 IN ${cnKey1}
|
|
FOR doc2 IN ${cnKey2}
|
|
UPDATE doc1 WITH {test:1} IN ${cnKey1}
|
|
FILTER doc2.${shardKey2} == ${i}
|
|
RETURN [NEW, doc2]
|
|
`;
|
|
|
|
let raw = db._query(query, {}, disableSingleDocOp);
|
|
let stats = raw.getExtra().stats;
|
|
assertEqual(stats.writesExecuted, 10000);
|
|
let results = raw.toArray();
|
|
assertEqual(400, results.length);
|
|
for (let [doc1, doc2] of results) {
|
|
assertTrue(i === doc2[shardKey2]);
|
|
assertEqual(doc1.test, 1);
|
|
}
|
|
},
|
|
|
|
testInnerOuterDifferent21 : function () {
|
|
dropIndexes(collectionByKey1);
|
|
dropIndexes(collectionByKey2);
|
|
|
|
const i = 21;
|
|
const query = `
|
|
FOR doc1 IN ${cnKey1}
|
|
FOR doc2 IN ${cnKey2}
|
|
UPDATE doc1 WITH {test:1} IN ${cnKey1}
|
|
RETURN [NEW, doc2]
|
|
`;
|
|
|
|
let raw = db._query(query, {}, disableSingleDocOp);
|
|
let stats = raw.getExtra().stats;
|
|
assertEqual(stats.writesExecuted, 10000);
|
|
let results = raw.toArray();
|
|
assertEqual(10000, results.length);
|
|
for (let [doc1, doc2] of results) {
|
|
assertEqual(doc1.test, 1);
|
|
}
|
|
},
|
|
|
|
testInnerOuterDifferentIndex21 : function () {
|
|
dropIndexes(collectionByKey1);
|
|
dropIndexes(collectionByKey2);
|
|
collectionByKey1.ensureHashIndex(shardKey1);
|
|
collectionByKey2.ensureHashIndex(shardKey2);
|
|
|
|
const i = 21;
|
|
const query = `
|
|
FOR doc1 IN ${cnKey1}
|
|
FOR doc2 IN ${cnKey2}
|
|
UPDATE doc1 WITH {test:1} IN ${cnKey1}
|
|
RETURN [NEW, doc2]
|
|
`;
|
|
|
|
let raw = db._query(query, {}, disableSingleDocOp);
|
|
let stats = raw.getExtra().stats;
|
|
assertEqual(stats.writesExecuted, 10000);
|
|
let results = raw.toArray();
|
|
assertEqual(10000, results.length);
|
|
for (let [doc1, doc2] of results) {
|
|
assertEqual(doc1.test, 1);
|
|
}
|
|
},
|
|
|
|
testSeparateLoops : function () {
|
|
dropIndexes(collectionByKey1);
|
|
dropIndexes(collectionByKey2);
|
|
|
|
for (let i = 0; i < 24; ++i) {
|
|
const query = `
|
|
LET ok = (
|
|
FOR doc1 IN ${cnKey1}
|
|
UPDATE doc1 WITH {test:1} IN ${cnKey1}
|
|
)
|
|
FOR doc2 IN ${cnKey2}
|
|
FILTER doc2.${shardKey2} == ${i}
|
|
RETURN doc2
|
|
`;
|
|
validatePlan(query, "EnumerateCollectionNode", collectionByKey2);
|
|
|
|
let raw = db._query(query, {}, disableSingleDocOp);
|
|
let stats = raw.getExtra().stats;
|
|
assertEqual(stats.writesExecuted, 100);
|
|
let results = raw.toArray();
|
|
assertEqual(4, results.length);
|
|
for (let doc of results) {
|
|
assertEqual(i, doc[shardKey2]);
|
|
}
|
|
}
|
|
},
|
|
|
|
testSeparateLoopsIndex : function () {
|
|
dropIndexes(collectionByKey1);
|
|
dropIndexes(collectionByKey2);
|
|
collectionByKey1.ensureHashIndex(shardKey1);
|
|
collectionByKey2.ensureHashIndex(shardKey2);
|
|
|
|
for (let i = 0; i < 24; ++i) {
|
|
const query = `
|
|
LET ok = (
|
|
FOR doc1 IN ${cnKey1}
|
|
UPDATE doc1 WITH {test:1} IN ${cnKey1}
|
|
)
|
|
FOR doc2 IN ${cnKey2}
|
|
FILTER doc2.${shardKey2} == ${i}
|
|
RETURN doc2
|
|
`;
|
|
validatePlan(query, "IndexNode", collectionByKey2);
|
|
|
|
let raw = db._query(query, {}, disableSingleDocOp);
|
|
let stats = raw.getExtra().stats;
|
|
assertEqual(stats.writesExecuted, 100);
|
|
let results = raw.toArray();
|
|
assertEqual(4, results.length);
|
|
for (let doc of results) {
|
|
assertEqual(i, doc[shardKey2]);
|
|
}
|
|
}
|
|
},
|
|
|
|
};
|
|
};
|
|
|
|
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
/// @brief executes the test suite
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
|
|
jsunity.run(ahuacatlShardIdsTestSuite);
|
|
jsunity.run(ahuacatlShardIdsOptimizationTestSuite);
|
|
|
|
return jsunity.done();
|