diff --git a/tests/js/client/authentication/user-access-right-task-update-view-arangosearch.js b/tests/js/client/authentication/user-access-right-task-update-view-arangosearch.js index f0104042be..1f6220edf5 100644 --- a/tests/js/client/authentication/user-access-right-task-update-view-arangosearch.js +++ b/tests/js/client/authentication/user-access-right-task-update-view-arangosearch.js @@ -234,7 +234,7 @@ const checkError = (e) => { function UserRightsManagement(name) { return { - setUp: function() { + setUpAll: function() { helper.switchUser(name, dbName); db._useDatabase(dbName); assertEqual(createKeySpace(keySpaceId), true, 'keySpace creation failed for user: ' + name); @@ -242,21 +242,24 @@ function UserRightsManagement(name) { rootCreateCollection(testCol2Name); rootPrepareCollection(testCol1Name); rootPrepareCollection(testCol2Name); + }, - rootCreateView(testViewName, { links: { [testCol1Name] : {includeAllFields: true } } }); - helper.switchUser('root', dbName); + setUp: function() { + rootCreateView(testViewName, { links: { [testCol1Name] : {includeAllFields: true } } }); + helper.switchUser('root', dbName); }, - tearDown: function() { - rootDropView(testViewRename); - rootDropView(testViewName); - + tearDownAll: function() { rootDropCollection(testCol1Name); rootDropCollection(testCol2Name); dropKeySpace(keySpaceId); }, - + tearDown: function() { + rootDropView(testViewRename); + rootDropView(testViewName); + }, + testCheckAllUsersAreCreated: function() { helper.switchUser('root', '_system'); assertTrue(userSet.size > 0); diff --git a/tests/js/client/authentication/user-access-right-update-view-arangosearch.js b/tests/js/client/authentication/user-access-right-update-view-arangosearch.js index 968b5c9f21..4f57d3275f 100644 --- a/tests/js/client/authentication/user-access-right-update-view-arangosearch.js +++ b/tests/js/client/authentication/user-access-right-update-view-arangosearch.js @@ -118,13 +118,15 @@ function rootCreateCollection (colName) { function rootPrepareCollection (colName, numDocs = 1, defKey = true) { if (rootTestCollection(colName, false)) { db._collection(colName).truncate({ compact: false }); + let docs = []; for(var i = 0; i < numDocs; ++i) { var doc = {prop1: colName + "_1", propI: i, plink: "lnk" + i}; if (!defKey) { doc._key = colName + i; } - db._collection(colName).save(doc, {waitForSync: true}); + docs.push(doc); } + db._collection(colName).insert(docs, {waitForSync: true}); } helper.switchUser(name, dbName); }; @@ -217,21 +219,23 @@ function hasIResearch (db) { function UserRightsManagement(name) { return { - setUp: function() { + setUpAll: function() { rootCreateCollection(testCol1Name); rootCreateCollection(testCol2Name); rootPrepareCollection(testCol1Name); rootPrepareCollection(testCol2Name); - + }, + setUp: function() { rootCreateView(testViewName, { links: { [testCol1Name] : {includeAllFields: true } } }); db._useDatabase(dbName); helper.switchUser('root', dbName); }, - tearDown: function () { + tearDown: function() { rootDropView(testViewRename); rootDropView(testViewName); - + }, + tearDownAll: function () { rootDropCollection(testCol1Name); rootDropCollection(testCol2Name); }, diff --git a/tests/js/server/aql/aql-failures-noncluster.js b/tests/js/server/aql/aql-failures-noncluster.js index 57aa0be5fc..64fb1bb672 100644 --- a/tests/js/server/aql/aql-failures-noncluster.js +++ b/tests/js/server/aql/aql-failures-noncluster.js @@ -45,6 +45,7 @@ function ahuacatlFailureSuite () { var c; var e; var count = 5000; + var idx = null; var assertFailingQuery = function (query, rulesToExclude) { if (!rulesToExclude) { @@ -60,21 +61,29 @@ function ahuacatlFailureSuite () { return { - setUp: function () { + setUpAll: function () { internal.debugClearFailAt(); db._drop(cn); c = db._create(cn); db._drop(en); e = db._createEdgeCollection(en); + let docs = []; for (var i = 0; i < count; ++i) { - c.save({ _key: String(i), value: i, value2: i % 10 }); + docs.push({ _key: String(i), value: i, value2: i % 10 }); } + c.insert(docs); + docs = []; for (var j = 0; j < count / 10; ++j) { - e.save(cn + "/" + j, cn + "/" + (j + 1), { }); + docs.push({'_from': cn + "/" + j, '_to': cn + "/" + (j + 1) }); } + e.insert(docs); }, - tearDown: function () { + setUp: function () { + idx = null; + }, + + tearDownAll: function () { internal.debugClearFailAt(); db._drop(cn); c = null; @@ -82,6 +91,13 @@ function ahuacatlFailureSuite () { e = null; }, + tearDown: function() { + internal.debugClearFailAt(); + if (idx != null) { + db._dropIndex(idx); + idx = null; + } + }, //////////////////////////////////////////////////////////////////////////////// /// @brief test UNION for memleaks //////////////////////////////////////////////////////////////////////////////// @@ -285,20 +301,6 @@ function ahuacatlFailureSuite () { assertFailingQuery("FOR i IN [1,2,3,4] FILTER i IN [1,2,3,4] RETURN i"); }, -//////////////////////////////////////////////////////////////////////////////// -/// @brief test failure -//////////////////////////////////////////////////////////////////////////////// - - testModificationBlock : function () { - internal.debugSetFailAt("ModificationBlock::getSome"); - assertFailingQuery("FOR i IN " + c.name() + " REMOVE i IN " + c.name()); - assertFailingQuery("FOR i IN 1..10000 REMOVE CONCAT('test' + i) IN " + c.name() + " OPTIONS { ignoreErrors: true }"); - assertFailingQuery("FOR i IN " + c.name() + " REMOVE i IN " + c.name()); - assertFailingQuery("FOR i IN 1..10000 INSERT { value3: i } IN " + c.name()); - - assertEqual(count, c.count()); - }, - //////////////////////////////////////////////////////////////////////////////// /// @brief test failure //////////////////////////////////////////////////////////////////////////////// @@ -418,7 +420,7 @@ function ahuacatlFailureSuite () { //////////////////////////////////////////////////////////////////////////////// testIndexBlock1 : function () { - c.ensureHashIndex("value"); + idx = c.ensureHashIndex("value"); internal.debugSetFailAt("IndexBlock::initialize"); assertFailingQuery("LET f = NOOPT(1) FOR j IN 1..10 FOR i IN " + c.name() + " FILTER i.value == j FILTER i.value == f RETURN i"); assertFailingQuery("FOR j IN 1..10 FOR i IN " + c.name() + " FILTER i.value == j RETURN i"); @@ -429,13 +431,13 @@ function ahuacatlFailureSuite () { //////////////////////////////////////////////////////////////////////////////// testIndexBlock2 : function () { - c.ensureHashIndex("value"); + idx = c.ensureHashIndex("value"); internal.debugSetFailAt("IndexBlock::initializeExpressions"); assertFailingQuery("LET f = NOOPT(1) FOR j IN 1..10 FOR i IN " + c.name() + " FILTER i.value == j FILTER i.value == f RETURN i"); }, testIndexBlock3 : function () { - c.ensureSkiplist("value", "value2"); + idx = c.ensureSkiplist("value", "value2"); internal.debugSetFailAt("IndexBlock::readIndex"); assertFailingQuery("FOR i IN " + c.name() + " FILTER i.value == 25 RETURN i"); assertFailingQuery("FOR j IN 1..10 FOR i IN " + c.name() + " FILTER i.value == j RETURN i"); @@ -447,7 +449,7 @@ function ahuacatlFailureSuite () { //////////////////////////////////////////////////////////////////////////////// testIndexBlock4 : function () { - c.ensureHashIndex("value", "value2"); + idx = c.ensureHashIndex("value", "value2"); internal.debugSetFailAt("IndexBlock::readIndex"); assertFailingQuery("FOR i IN " + c.name() + " FILTER i.value == 25 && i.value2 == 5 RETURN i"); }, @@ -457,13 +459,13 @@ function ahuacatlFailureSuite () { //////////////////////////////////////////////////////////////////////////////// testIndexBlock5 : function () { - c.ensureSkiplist("value", "value2"); + idx = c.ensureSkiplist("value", "value2"); internal.debugSetFailAt("IndexBlock::readIndex"); assertFailingQuery("FOR i IN " + c.name() + " FILTER i.value == 25 && i.value2 == 5 RETURN i"); }, testIndexBlock6 : function () { - c.ensureHashIndex("value"); + idx = c.ensureHashIndex("value"); internal.debugSetFailAt("IndexBlock::executeExpression"); // CONCAT is an arbitrary non v8 function and can be replaced assertFailingQuery("FOR i IN " + c.name() + " FILTER i.value == NOOPT(CONCAT('1','2')) RETURN i"); @@ -490,79 +492,79 @@ function ahuacatlFailureSuite () { }, testIndexNodeSkiplist1 : function () { - c.ensureSkiplist("value"); + idx = c.ensureSkiplist("value"); internal.debugSetFailAt("SkiplistIndex::noSortIterator"); assertFailingQuery("FOR i IN " + c.name() + " SORT i.value RETURN i"); }, testIndexNodeSkiplist2 : function () { - c.ensureSkiplist("value"); + idx = c.ensureSkiplist("value"); internal.debugSetFailAt("SkiplistIndex::noIterator"); assertFailingQuery("FOR i IN " + c.name() + " FILTER i.value == 1 RETURN i"); }, testIndexNodeSkiplist3 : function () { - c.ensureSkiplist("value"); + idx = c.ensureSkiplist("value"); internal.debugSetFailAt("SkiplistIndex::permutationEQ"); assertFailingQuery("FOR i IN " + c.name() + " FILTER i.value == 1 RETURN i"); }, testIndexNodeSkiplist4 : function () { - c.ensureSkiplist("value"); + idx = c.ensureSkiplist("value"); internal.debugSetFailAt("Index::permutationIN"); assertFailingQuery("FOR i IN " + c.name() + " FILTER i.value IN [1, 2] RETURN i"); }, testIndexNodeSkiplist5 : function () { - c.ensureSkiplist("value[*]"); + idx = c.ensureSkiplist("value[*]"); internal.debugSetFailAt("SkiplistIndex::permutationArrayIN"); assertFailingQuery("FOR i IN " + c.name() + " FILTER 1 IN i.value[*] RETURN i"); }, testIndexNodeSkiplist6 : function () { - c.ensureSkiplist("value"); + idx = c.ensureSkiplist("value"); internal.debugSetFailAt("SkiplistIndex::accessFitsIndex"); assertFailingQuery("FOR i IN " + c.name() + " FILTER i.value == 1 RETURN i"); }, testIndexNodeHashIndex1 : function () { - c.ensureHashIndex("value"); + idx = c.ensureHashIndex("value"); internal.debugSetFailAt("HashIndex::noIterator"); assertFailingQuery("FOR i IN " + c.name() + " FILTER i.value == 1 RETURN i"); }, testIndexNodeHashIndex2 : function () { - c.ensureHashIndex("value"); + idx = c.ensureHashIndex("value"); internal.debugSetFailAt("HashIndex::permutationEQ"); assertFailingQuery("FOR i IN " + c.name() + " FILTER i.value == 1 RETURN i"); }, testIndexNodeHashIndex3 : function () { - c.ensureHashIndex("value"); + idx = c.ensureHashIndex("value"); internal.debugSetFailAt("Index::permutationIN"); assertFailingQuery("FOR i IN " + c.name() + " FILTER i.value IN [1, 2] RETURN i"); }, testIndexNodeHashIndex4 : function () { - c.ensureHashIndex("value[*]"); + idx = c.ensureHashIndex("value[*]"); internal.debugSetFailAt("HashIndex::permutationArrayIN"); assertFailingQuery("FOR i IN " + c.name() + " FILTER 1 IN i.value[*] RETURN i"); }, testSimpleAttributeMatcher2 : function () { - c.ensureHashIndex("value"); + idx = c.ensureHashIndex("value"); internal.debugSetFailAt("SimpleAttributeMatcher::specializeAllChildrenEQ"); assertFailingQuery("FOR i IN " + c.name() + " FILTER i.value == 1 RETURN i"); }, testSimpleAttributeMatcher3 : function () { - c.ensureHashIndex("value"); + idx = c.ensureHashIndex("value"); internal.debugSetFailAt("SimpleAttributeMatcher::specializeAllChildrenIN"); assertFailingQuery("FOR i IN " + c.name() + " FILTER i.value IN [1, 2] RETURN i"); }, testSimpleAttributeMatcher4 : function () { - c.ensureHashIndex("value"); + idx = c.ensureHashIndex("value"); internal.debugSetFailAt("SimpleAttributeMatcher::accessFitsIndex"); assertFailingQuery("FOR i IN " + c.name() + " FILTER i.value == 1 RETURN i"); }, @@ -602,12 +604,80 @@ function ahuacatlFailureSuite () { }; } +function ahuacatlFailureModifySuite () { + 'use strict'; + var cn = "UnitTestsAhuacatlFailures"; + var en = "UnitTestsAhuacatlEdgeFailures"; + var c; + var e; + var count = 5000; + + var assertFailingQuery = function (query, rulesToExclude) { + if (!rulesToExclude) { + rulesToExclude = []; + } + try { + AQL_EXECUTE(query, null, { optimizer: { rules: rulesToExclude } }); + fail(); + } catch (err) { + assertEqual(internal.errors.ERROR_DEBUG.code, err.errorNum, query); + } + }; + + return { + + setUpAll: function () { + internal.debugClearFailAt(); + db._drop(cn); + c = db._create(cn); + db._drop(en); + e = db._createEdgeCollection(en); + let docs = []; + for (var i = 0; i < count; ++i) { + docs.push({ _key: String(i), value: i, value2: i % 10 }); + } + c.insert(docs); + docs = []; + for (var j = 0; j < count / 10; ++j) { + docs.push({'_from': cn + "/" + j, '_to': cn + "/" + (j + 1) }); + } + e.insert(docs); + }, + + tearDownAll: function () { + internal.debugClearFailAt(); + db._drop(cn); + c = null; + db._drop(en); + e = null; + }, + + tearDown: function() { + internal.debugClearFailAt(); + }, +//////////////////////////////////////////////////////////////////////////////// +/// @brief test failure +//////////////////////////////////////////////////////////////////////////////// + + testModificationBlock : function () { + internal.debugSetFailAt("ModificationBlock::getSome"); + assertFailingQuery("FOR i IN " + c.name() + " REMOVE i IN " + c.name()); + assertFailingQuery("FOR i IN 1..10000 REMOVE CONCAT('test' + i) IN " + c.name() + " OPTIONS { ignoreErrors: true }"); + assertFailingQuery("FOR i IN " + c.name() + " REMOVE i IN " + c.name()); + assertFailingQuery("FOR i IN 1..10000 INSERT { value3: i } IN " + c.name()); + + assertEqual(count, c.count()); + } + }; +} + //////////////////////////////////////////////////////////////////////////////// /// @brief executes the test suites //////////////////////////////////////////////////////////////////////////////// if (internal.debugCanUseFailAt()) { + jsunity.run(ahuacatlFailureModifySuite); jsunity.run(ahuacatlFailureSuite); } diff --git a/tests/js/server/aql/aql-gather-block-cluster.js b/tests/js/server/aql/aql-gather-block-cluster.js index 115ab19785..a53c62939f 100644 --- a/tests/js/server/aql/aql-gather-block-cluster.js +++ b/tests/js/server/aql/aql-gather-block-cluster.js @@ -40,7 +40,9 @@ function gatherBlockTestSuite () { var cn1 = "UnitTestsGatherBlock1"; var cn2 = "UnitTestsGatherBlock2"; var cn3 = "UnitTestsGatherBlock3"; - var c1, c2, c3; + var cn4 = "UnitTestsGatherBlock4"; + var c1, c2, c3, c4; + var idx; var explain = function (result) { return helper.getCompactPlan(result).map(function(node) @@ -53,46 +55,69 @@ function gatherBlockTestSuite () { /// @brief set up //////////////////////////////////////////////////////////////////////////////// - setUp : function () { + setUpAll: function() { var j, k; db._drop(cn1); db._drop(cn2); db._drop(cn3); c1 = db._create(cn1, {numberOfShards:3}); + let docs1 = []; c2 = db._create(cn2); + let docs2 = []; for (j = 0; j < 400; j++) { for (k = 0; k < 10; k++){ - c1.insert({Hallo:k}); - c2.insert({Hallo:k}); + docs1.push({Hallo:k}); + docs2.push({Hallo:k}); } } + c1.insert(docs1); + c2.insert(docs2); c3 = db._create(cn3, {numberOfShards:3}); + let docs3 = []; for (k = 0; k < 10; k++){ - c3.insert({Hallo:k}); + docs3.push({Hallo:k}); } + c3.insert(docs3); + }, + + setUp: function() { + idx = null; }, //////////////////////////////////////////////////////////////////////////////// /// @brief tear down //////////////////////////////////////////////////////////////////////////////// - tearDown : function () { + tearDownAll: function () { db._drop(cn1); db._drop(cn2); db._drop(cn3); + db._drop(cn4); c1 = null; c2 = null; c3 = null; + c4 = null; }, - - testMoreShardsThanDocumentsHeapSort : function () { - db._drop(cn3); - c3 = db._create(cn3, {numberOfShards:40}); - for (let i = 0; i < 39; ++i) { - c3.insert({ value : i }); + + tearDown: function() { + assertEqual(c1.count(), 4000); + if (idx !== null) { + db._dropIndex(idx); + idx = null; } + db._drop(cn4); + }, + + testMoreShardsThanDocumentsHeapSort : function () { + db._drop(cn4); + c4 = db._create(cn4, {numberOfShards:40}); + let docs = []; + for (let i = 0; i < 39; ++i) { + docs.push({ value : i }); + } + c4.insert(docs); - let query = "FOR doc IN " + cn3 + " SORT doc.value RETURN doc.value"; + let query = "FOR doc IN " + cn4 + " SORT doc.value RETURN doc.value"; // check the return value let result = AQL_EXECUTE(query).json; assertEqual(39, result.length); @@ -116,13 +141,15 @@ function gatherBlockTestSuite () { }, testMoreShardsThanDocumentsMinElementSort : function () { - db._drop(cn3); - c3 = db._create(cn3, {numberOfShards:4}); + db._drop(cn4); + c4 = db._create(cn4, {numberOfShards:4}); + let docs = []; for (let i = 0; i < 3; ++i) { - c3.insert({ value : i }); + docs.push({ value : i }); } - - let query = "FOR doc IN " + cn3 + " SORT doc.value RETURN doc.value"; + c4.insert(docs); + + let query = "FOR doc IN " + cn4 + " SORT doc.value RETURN doc.value"; // check the return value let result = AQL_EXECUTE(query).json; assertEqual(3, result.length); @@ -146,13 +173,15 @@ function gatherBlockTestSuite () { }, testMoreShardsThanDocumentsNoSort : function () { - db._drop(cn3); - c3 = db._create(cn3, {numberOfShards:40}); + db._drop(cn4); + c4 = db._create(cn4, {numberOfShards:40}); + let docs = []; for (let i = 0; i < 39; ++i) { - c3.insert({ value : i }); + docs.push({ value : i }); } + c4.save(docs); - let query = "FOR doc IN " + cn3 + " RETURN doc.value"; + let query = "FOR doc IN " + cn4 + " RETURN doc.value"; // check the return value let result = AQL_EXECUTE(query).json; assertEqual(39, result.length); @@ -168,18 +197,19 @@ function gatherBlockTestSuite () { }, testMoreDocumentsThanShardsHeapSort : function () { - db._drop(cn3); - c3 = db._create(cn3, {numberOfShards:10}); + db._drop(cn4); + c4 = db._create(cn4, {numberOfShards:10}); let docs = []; for (let i = 0; i < 20000; ++i) { docs.push({ value: i }); if (docs.length === 1000) { - c3.insert(docs); + c4.insert(docs); docs = []; } } + c4.insert(docs); - let query = "FOR doc IN " + cn3 + " SORT doc.value RETURN doc.value"; + let query = "FOR doc IN " + cn4 + " SORT doc.value RETURN doc.value"; // check the return value let result = AQL_EXECUTE(query).json; assertEqual(20000, result.length); @@ -203,18 +233,19 @@ function gatherBlockTestSuite () { }, testMoreDocumentsThanShardsMinElementSort : function () { - db._drop(cn3); - c3 = db._create(cn3, {numberOfShards:4}); + db._drop(cn4); + c4 = db._create(cn4, {numberOfShards:4}); let docs = []; for (let i = 0; i < 20000; ++i) { docs.push({ value: i }); if (docs.length === 1000) { - c3.insert(docs); + c4.insert(docs); docs = []; } } + c4.insert(docs); - let query = "FOR doc IN " + cn3 + " SORT doc.value RETURN doc.value"; + let query = "FOR doc IN " + cn4 + " SORT doc.value RETURN doc.value"; // check the return value let result = AQL_EXECUTE(query).json; assertEqual(20000, result.length); @@ -238,18 +269,19 @@ function gatherBlockTestSuite () { }, testMoreDocumentsThanShardsNoSort : function () { - db._drop(cn3); - c3 = db._create(cn3, {numberOfShards:20}); + db._drop(cn4); + c4 = db._create(cn4, {numberOfShards:20}); let docs = []; for (let i = 0; i < 20000; ++i) { docs.push({ value: i }); if (docs.length === 1000) { - c3.insert(docs); + c4.insert(docs); docs = []; } } + c4.insert(docs); - let query = "FOR doc IN " + cn3 + " RETURN doc.value"; + let query = "FOR doc IN " + cn4 + " RETURN doc.value"; // check the return value let result = AQL_EXECUTE(query).json; assertEqual(20000, result.length); @@ -309,7 +341,7 @@ function gatherBlockTestSuite () { }, testSingleShardWithIndex : function () { - c2.ensureIndex({ type: "skiplist", fields: ["Hallo"] }); + idx = c2.ensureIndex({ type: "skiplist", fields: ["Hallo"] }); let query = "FOR doc IN " + cn2 + " SORT doc.Hallo RETURN doc.Hallo"; // check the return value let result = AQL_EXECUTE(query).json; @@ -332,7 +364,7 @@ function gatherBlockTestSuite () { }, testSingleShardWithIndexDescending : function () { - c2.ensureIndex({ type: "skiplist", fields: ["Hallo"] }); + idx = c2.ensureIndex({ type: "skiplist", fields: ["Hallo"] }); let query = "FOR doc IN " + cn2 + " SORT doc.Hallo DESC RETURN doc.Hallo"; // check the return value let result = AQL_EXECUTE(query).json; @@ -397,9 +429,9 @@ function gatherBlockTestSuite () { assertEqual(1, gatherNode.elements.length); // must do sorting in GatherNode assertFalse(gatherNode.elements[0].ascending); }, - + testMultipleShardsWithIndex : function () { - c1.ensureIndex({ type: "skiplist", fields: ["Hallo"] }); + idx = c1.ensureIndex({ type: "skiplist", fields: ["Hallo"] }); let query = "FOR doc IN " + cn1 + " SORT doc.Hallo RETURN doc.Hallo"; // check the return value let result = AQL_EXECUTE(query).json; @@ -424,7 +456,7 @@ function gatherBlockTestSuite () { }, testMultipleShardsWithIndexDescending : function () { - c1.ensureIndex({ type: "skiplist", fields: ["Hallo"] }); + idx = c1.ensureIndex({ type: "skiplist", fields: ["Hallo"] }); let query = "FOR doc IN " + cn1 + " SORT doc.Hallo DESC RETURN doc.Hallo"; // check the return value let result = AQL_EXECUTE(query).json; @@ -449,7 +481,7 @@ function gatherBlockTestSuite () { }, testMultipleShardsCollect : function () { - c1.ensureIndex({ type: "skiplist", fields: ["Hallo"] }); + idx = c1.ensureIndex({ type: "skiplist", fields: ["Hallo"] }); let query = "FOR doc IN " + cn1 + " FILTER doc.Hallo == 10 COLLECT WITH COUNT INTO length RETURN length"; let nodes = AQL_EXPLAIN(query).plan.nodes; @@ -462,11 +494,11 @@ function gatherBlockTestSuite () { let gatherNode = nodes[nodeTypes.indexOf("GatherNode")]; assertEqual(0, gatherNode.elements.length); // no sorting here }, - + testSubqueryValuePropagation : function () { - c3.truncate(); - c3.insert({Hallo:1}); - var query = "FOR i IN 1..1 LET s = (FOR j IN 1..i FOR k IN " + cn3 + " RETURN j) RETURN s"; + c4 = db._create(cn4, {numberOfShards:3}); + c4.insert({Hallo:1}); + var query = "FOR i IN 1..1 LET s = (FOR j IN 1..i FOR k IN " + cn4 + " RETURN j) RETURN s"; // check the return value var expected = [ [ 1 ] ]; var actual = AQL_EXECUTE(query).json; @@ -475,9 +507,9 @@ function gatherBlockTestSuite () { }, testCalculationNotMovedOverBoundary : function () { - c3.truncate(); - c3.insert({Hallo:1}); - var query = "FOR i IN " + cn3 + " FOR j IN 1..1 FOR k IN " + cn3 + " RETURN j"; + c4 = db._create(cn4, {numberOfShards:3}); + c4.insert({Hallo:1}); + var query = "FOR i IN " + cn4 + " FOR j IN 1..1 FOR k IN " + cn4 + " RETURN j"; // check the GatherNode is in the plan! assertTrue(explain(AQL_EXPLAIN(query)).indexOf("GatherNode") !== -1, query); @@ -497,7 +529,7 @@ function gatherBlockTestSuite () { // check the return value var expected = 10; var actual = AQL_EXECUTE(query).json.length; - + assertEqual(expected, actual, query); }, diff --git a/tests/js/server/aql/aql-modify-cluster.js b/tests/js/server/aql/aql-modify-cluster.js index 4a10bf4c77..37762f9cbd 100644 --- a/tests/js/server/aql/aql-modify-cluster.js +++ b/tests/js/server/aql/aql-modify-cluster.js @@ -1160,18 +1160,26 @@ function ahuacatlUpdateSuite () { c3 = db._create(cn3, {numberOfShards: 1}); c4 = db._create(cn4, {numberOfShards: 1}); + let docs = []; for (i = 0; i < 100; ++i) { - c1.save({ _key: "test" + i, value1: i, value2: "test" + i }); + docs.push({ _key: "test" + i, value1: i, value2: "test" + i }); } + c1.insert(docs); + docs = []; for (i = 0; i < 50; ++i) { - c2.save({ _key: "test" + i, value1: i, value2: "test" + i }); + docs.push({ _key: "test" + i, value1: i, value2: "test" + i }); } + c2.insert(docs); + docs = []; for (i = 0; i < 100; ++i) { - c3.save({ _key: "test" + i, value1: i, value2: "test" + i }); + docs.push({ _key: "test" + i, value1: i, value2: "test" + i }); } + c3.insert(docs); + docs = []; for (i = 0; i < 50; ++i) { - c4.save({ _key: "test" + i, value1: i, value2: "test" + i }); + docs.push({ _key: "test" + i, value1: i, value2: "test" + i }); } + c4.insert(docs); }, //////////////////////////////////////////////////////////////////////////////// diff --git a/tests/js/server/aql/aql-optimizer-collect-aggregate.js b/tests/js/server/aql/aql-optimizer-collect-aggregate.js index fa25827c9c..8b4a52f722 100644 --- a/tests/js/server/aql/aql-optimizer-collect-aggregate.js +++ b/tests/js/server/aql/aql-optimizer-collect-aggregate.js @@ -44,16 +44,18 @@ function optimizerAggregateTestSuite () { let c; return { - setUp : function () { + setUpAll : function () { db._drop("UnitTestsCollection"); c = db._create("UnitTestsCollection", { numberOfShards: 5 }); + let docs = []; for (var i = 0; i < 2000; ++i) { - c.save({ group: "test" + (i % 10), value1: i, value2: i % 5 }); + docs.push({ group: "test" + (i % 10), value1: i, value2: i % 5 }); } + c.insert(docs); }, - tearDown : function () { + tearDownAll : function () { db._drop("UnitTestsCollection"); }, @@ -596,53 +598,6 @@ function optimizerAggregateTestSuite () { assertEqual(isCluster ? "AVERAGE_STEP2" : "AVERAGE", collectNode.aggregates[4].type); }, -//////////////////////////////////////////////////////////////////////////////// -/// @brief test aggregate -//////////////////////////////////////////////////////////////////////////////// - - testAggregateFilteredBig : function () { - var i; - for (i = 0; i < 10000; ++i) { - c.save({ age: 10 + (i % 80), type: 1 }); - } - for (i = 0; i < 10000; ++i) { - c.save({ age: 10 + (i % 80), type: 2 }); - } - - var query = "FOR i IN " + c.name() + " FILTER i.age >= 20 && i.age < 50 && i.type == 1 COLLECT AGGREGATE length = LENGTH(i) RETURN length"; - - var results = AQL_EXECUTE(query); - assertEqual(1, results.json.length); - assertEqual(125 * 30, results.json[0]); - - var plan = AQL_EXPLAIN(query).plan; - // must not have a SortNode - assertEqual(-1, plan.nodes.map(function(node) { return node.type; }).indexOf("SortNode")); - - let collectNodes = plan.nodes.filter(function(node) { return node.type === 'CollectNode'; }); - assertEqual(isCluster ? 2 : 1, collectNodes.length); - - let collectNode = collectNodes[0]; - if (isCluster) { - assertEqual("sorted", collectNode.collectOptions.method); - assertFalse(collectNode.count); - assertFalse(collectNode.isDistinctCommand); - - assertEqual(0, collectNode.groups.length); - assertEqual(1, collectNode.aggregates.length); - assertEqual("LENGTH", collectNode.aggregates[0].type); - collectNode = collectNodes[1]; - } - assertEqual("sorted", collectNode.collectOptions.method); - assertFalse(collectNode.count); - assertFalse(collectNode.isDistinctCommand); - - assertEqual(0, collectNode.groups.length); - assertEqual(1, collectNode.aggregates.length); - assertEqual("length", collectNode.aggregates[0].outVariable.name); - assertEqual(isCluster ? "SUM" : "LENGTH", collectNode.aggregates[0].type); - }, - //////////////////////////////////////////////////////////////////////////////// /// @brief test aggregate //////////////////////////////////////////////////////////////////////////////// @@ -1769,13 +1724,86 @@ function optimizerAggregateTestSuite () { }; } +function optimizerAggregateModifyTestSuite () { + let c; + + return { + setUp : function () { + db._drop("UnitTestsCollection"); + c = db._create("UnitTestsCollection", { numberOfShards: 5 }); + + let docs = []; + for (var i = 0; i < 2000; ++i) { + docs.push({ group: "test" + (i % 10), value1: i, value2: i % 5 }); + } + c.insert(docs); + }, + + tearDown : function () { + db._drop("UnitTestsCollection"); + }, + + +//////////////////////////////////////////////////////////////////////////////// +/// @brief test aggregate +//////////////////////////////////////////////////////////////////////////////// + + testAggregateFilteredBig : function () { + var i; + let docs = []; + for (i = 0; i < 10000; ++i) { + docs.push({ age: 10 + (i % 80), type: 1 }); + } + for (i = 0; i < 10000; ++i) { + docs.push({ age: 10 + (i % 80), type: 2 }); + } + c.insert(docs); + + var query = "FOR i IN " + c.name() + " FILTER i.age >= 20 && i.age < 50 && i.type == 1 COLLECT AGGREGATE length = LENGTH(i) RETURN length"; + + var results = AQL_EXECUTE(query); + assertEqual(1, results.json.length); + assertEqual(125 * 30, results.json[0]); + + var plan = AQL_EXPLAIN(query).plan; + // must not have a SortNode + assertEqual(-1, plan.nodes.map(function(node) { return node.type; }).indexOf("SortNode")); + + let collectNodes = plan.nodes.filter(function(node) { return node.type === 'CollectNode'; }); + assertEqual(isCluster ? 2 : 1, collectNodes.length); + + let collectNode = collectNodes[0]; + if (isCluster) { + assertEqual("sorted", collectNode.collectOptions.method); + assertFalse(collectNode.count); + assertFalse(collectNode.isDistinctCommand); + + assertEqual(0, collectNode.groups.length); + assertEqual(1, collectNode.aggregates.length); + assertEqual("LENGTH", collectNode.aggregates[0].type); + collectNode = collectNodes[1]; + } + assertEqual("sorted", collectNode.collectOptions.method); + assertFalse(collectNode.count); + assertFalse(collectNode.isDistinctCommand); + + assertEqual(0, collectNode.groups.length); + assertEqual(1, collectNode.aggregates.length); + assertEqual("length", collectNode.aggregates[0].outVariable.name); + assertEqual(isCluster ? "SUM" : "LENGTH", collectNode.aggregates[0].type); + } + }; +} + + + //////////////////////////////////////////////////////////////////////////////// /// @brief test suite //////////////////////////////////////////////////////////////////////////////// function optimizerAggregateCollectionTestSuite () { return { - setUp : function () { + setUpAll : function () { db._drop("UnitTestsCollectionA"); var c = db._create("UnitTestsCollectionA"); @@ -1784,10 +1812,7 @@ function optimizerAggregateCollectionTestSuite () { { "_key" : "t2" }, { "_key" : "t3" } ]; - values.forEach(function(doc) { - c.insert(doc); - - }); + c.insert(values); db._drop("UnitTestsCollectionB"); c = db._create("UnitTestsCollectionB"); @@ -1813,12 +1838,10 @@ function optimizerAggregateCollectionTestSuite () { { "tlm" : 1460382104593, "ct" : 0, "rev" : "t3", "_key" : "8" } ]; - values.forEach(function(doc) { - c.insert(doc); - }); + c.insert(values); }, - tearDown : function () { + tearDownAll : function () { db._drop("UnitTestsCollectionA"); db._drop("UnitTestsCollectionB"); }, @@ -1859,16 +1882,17 @@ function optimizerAggregateResultsSuite () { let c; return { - setUp : function () { + setUpAll : function () { db._drop("UnitTestsCollection"); c = db._create("UnitTestsCollection", { numberOfShards: 5 }); - + let docs = []; for (var i = 0; i < 2000; ++i) { - c.save({ group: "test" + (i % 10), value1: i, value2: i % 5 }); + docs.push({ group: "test" + (i % 10), value1: i, value2: i % 5 }); } + c.save(docs); }, - tearDown : function () { + tearDownAll : function () { db._drop("UnitTestsCollection"); }, @@ -1949,6 +1973,7 @@ function optimizerAggregateResultsSuite () { //////////////////////////////////////////////////////////////////////////////// jsunity.run(optimizerAggregateTestSuite); +jsunity.run(optimizerAggregateModifyTestSuite); jsunity.run(optimizerAggregateCollectionTestSuite); if (isCluster) { jsunity.run(optimizerAggregateResultsSuite); diff --git a/tests/js/server/aql/aql-optimizer-edge-index.js b/tests/js/server/aql/aql-optimizer-edge-index.js index d43618ee81..2cbb880406 100644 --- a/tests/js/server/aql/aql-optimizer-edge-index.js +++ b/tests/js/server/aql/aql-optimizer-edge-index.js @@ -46,16 +46,18 @@ function optimizerEdgeIndexTestSuite () { db._create('UnitTestsCollection'); e = db._createEdgeCollection('UnitTestsEdgeCollection'); + let edocs = []; for (var i = 0; i < 2000; i += 100) { var j; for (j = 0; j < i; ++j) { - e.save('UnitTestsCollection/from' + i, 'UnitTestsCollection/nono', { value: i + '-' + j }); + edocs.push({'_from': 'UnitTestsCollection/from' + i, '_to': 'UnitTestsCollection/nono', value: i + '-' + j }); } for (j = 0; j < i; ++j) { - e.save('UnitTestsCollection/nono', 'UnitTestsCollection/to' + i, { value: i + '-' + j }); + edocs.push({'_from': 'UnitTestsCollection/nono', '_to': 'UnitTestsCollection/to' + i, value: i + '-' + j }); } } + e.insert(edocs); internal.waitForEstimatorSync(); }, diff --git a/tests/js/server/aql/aql-optimizer-geoindex.js b/tests/js/server/aql/aql-optimizer-geoindex.js index c08c44e18e..116693736e 100644 --- a/tests/js/server/aql/aql-optimizer-geoindex.js +++ b/tests/js/server/aql/aql-optimizer-geoindex.js @@ -101,7 +101,7 @@ function legacyOptimizerRuleTestSuite() { /// @brief set up //////////////////////////////////////////////////////////////////////////////// - setUp : function () { + setUpAll : function () { var loopto = 10; internal.db._drop(colName); @@ -110,19 +110,21 @@ function legacyOptimizerRuleTestSuite() { geocol.ensureIndex({type:"geo1", fields:["geo"]}); geocol.ensureIndex({type:"geo2", fields:["loca.tion.lat","loca.tion.lon"]}); var lat, lon; + let docs = []; for (lat=-40; lat <=40 ; ++lat) { for (lon=-40; lon <= 40; ++lon) { //geocol.insert({lat,lon}); - geocol.insert({lat, lon, "geo":[lat,lon], "loca":{"tion":{ lat, lon }} }); + docs.push({lat, lon, "geo":[lat,lon], "loca":{"tion":{ lat, lon }} }); } } + geocol.insert(docs); }, //////////////////////////////////////////////////////////////////////////////// /// @brief tear down //////////////////////////////////////////////////////////////////////////////// - tearDown : function () { + tearDownAll : function () { internal.db._drop(colName); geocol = null; }, @@ -278,7 +280,7 @@ function legacyGeoVariationsTestSuite() { return { - setUp : function () { + setUpAll : function () { internal.db._drop(colName); geocol = internal.db._create(colName); geocol.ensureIndex({ type:"geo1", fields: ["location"] }); @@ -292,7 +294,7 @@ function legacyGeoVariationsTestSuite() { geocol.insert(documents); }, - tearDown : function () { + tearDownAll : function () { internal.db._drop(colName); }, @@ -338,6 +340,7 @@ function optimizerRuleTestSuite() { var ruleName = "geoindex"; var colName = "UnitTestsAqlOptimizer" + ruleName.replace(/-/g, "_"); var colName2 = colName2; + var colName3 = "UnitTestsGeoJsonTestSuite"; var sortArray = function (l, r) { if (l[0] !== r[0]) { @@ -413,7 +416,7 @@ function optimizerRuleTestSuite() { //////////////////////////////////////////////////////////////////////////// /// @brief set up //////////////////////////////////////////////////////////////////////////// - setUp: function () { + setUpAll: function () { var loopto = 10; internal.db._drop(colName); @@ -429,8 +432,8 @@ function optimizerRuleTestSuite() { } } - db._drop("UnitTestsGeoJsonTestSuite"); - locations = db._create("UnitTestsGeoJsonTestSuite"); + db._drop(colName3); + locations = db._create(colName3); locations.ensureIndex({ type: "geo", fields: ["geometry"], geoJson: true, legacy: false }); indonesiaKeys = indonesia.map(doc => locations.save({ geometry: doc })._key); @@ -440,10 +443,10 @@ function optimizerRuleTestSuite() { //////////////////////////////////////////////////////////////////////////// /// @brief tear down //////////////////////////////////////////////////////////////////////////// - tearDown: function () { + tearDownAll: function () { internal.db._drop(colName); geocol = null; - db._drop("UnitTestsGeoJsonTestSuite"); + db._drop(colName3); }, testRuleMultiIndexesInLoops: function () { diff --git a/tests/js/server/aql/aql-optimizer-indexes-multi.js b/tests/js/server/aql/aql-optimizer-indexes-multi.js index edf23a087a..35181328e0 100644 --- a/tests/js/server/aql/aql-optimizer-indexes-multi.js +++ b/tests/js/server/aql/aql-optimizer-indexes-multi.js @@ -67,31 +67,46 @@ function makeResult (f) { function optimizerIndexesMultiTestSuite () { let c; + let idx0 = null; + let idx1 = null; let noProjections = { optimizer: { rules: ["-reduce-extraction-to-projection"] } }; return { - setUp : function () { + setUpAll: function (){ db._drop("UnitTestsCollection"); c = db._create("UnitTestsCollection"); + let docs = []; for (var i = 0; i < 8000; ++i) { - c.save(makeObj(i)); + docs.push(makeObj(i)); } + c.insert(docs); }, - tearDown : function () { + tearDownAll: function() { db._drop("UnitTestsCollection"); }, + tearDown: function() { + if (idx0 !== null) { + db._dropIndex(idx0); + idx0 = null; + } + if (idx1 !== null) { + db._dropIndex(idx1); + idx1 = null; + } + }, + //////////////////////////////////////////////////////////////////////////////// /// @brief test use of two hash indexes for "||" and one for "&&" //////////////////////////////////////////////////////////////////////////////// testUseTwoHashIndexesOr : function () { - c.ensureIndex( { type: "hash", sparse: false, unique: false, - fields: ["b"] } ); - c.ensureIndex( { type: "hash", sparse: false, unique: false, - fields: ["c"] } ); + idx0 = c.ensureIndex( { type: "hash", sparse: false, unique: false, + fields: ["b"] } ); + idx1 = c.ensureIndex( { type: "hash", sparse: false, unique: false, + fields: ["c"] } ); var queries = []; var makers = []; @@ -197,10 +212,10 @@ function optimizerIndexesMultiTestSuite () { //////////////////////////////////////////////////////////////////////////////// testUseTwoSkiplistIndexesOr : function () { - c.ensureIndex( { type: "skiplist", sparse: false, unique: false, - fields: ["b"] } ); - c.ensureIndex( { type: "skiplist", sparse: false, unique: false, - fields: ["c"] } ); + idx0 = c.ensureIndex( { type: "skiplist", sparse: false, unique: false, + fields: ["b"] } ); + idx1 = c.ensureIndex( { type: "skiplist", sparse: false, unique: false, + fields: ["c"] } ); var queries = []; var makers = []; @@ -306,10 +321,10 @@ function optimizerIndexesMultiTestSuite () { //////////////////////////////////////////////////////////////////////////////// testUseSkipAndHashIndexForOr : function () { - c.ensureIndex( { type: "hash", sparse: false, unique: false, - fields: ["b"] } ); - c.ensureIndex( { type: "skiplist", sparse: false, unique: false, - fields: ["c"] } ); + idx0 = c.ensureIndex( { type: "hash", sparse: false, unique: false, + fields: ["b"] } ); + idx1 = c.ensureIndex( { type: "skiplist", sparse: false, unique: false, + fields: ["c"] } ); var queries = []; var makers = []; @@ -423,8 +438,8 @@ function optimizerIndexesMultiTestSuite () { //////////////////////////////////////////////////////////////////////////////// testUseHashIndexForDNF : function () { - c.ensureIndex( { type: "hash", sparse: false, unique: false, - fields: ["b", "c"] } ); + idx0 = c.ensureIndex( { type: "hash", sparse: false, unique: false, + fields: ["b", "c"] } ); var queries = []; var makers = []; @@ -477,8 +492,8 @@ function optimizerIndexesMultiTestSuite () { //////////////////////////////////////////////////////////////////////////////// testUseHashIndexForDNF2 : function () { - c.ensureIndex( { type: "hash", sparse: false, unique: false, - fields: ["b"] } ); + idx0 = c.ensureIndex( { type: "hash", sparse: false, unique: false, + fields: ["b"] } ); var queries = []; var makers = []; @@ -531,8 +546,8 @@ function optimizerIndexesMultiTestSuite () { //////////////////////////////////////////////////////////////////////////////// testUseHashIndexForDNF3 : function () { - c.ensureIndex( { type: "hash", sparse: false, unique: false, - fields: ["c"] } ); + idx0 = c.ensureIndex( { type: "hash", sparse: false, unique: false, + fields: ["c"] } ); var queries = []; var makers = []; @@ -585,10 +600,10 @@ function optimizerIndexesMultiTestSuite () { //////////////////////////////////////////////////////////////////////////////// testUseHashIndexForDNF4: function () { - c.ensureIndex( { type: "hash", sparse: false, unique: false, - fields: ["b"] } ); - c.ensureIndex( { type: "hash", sparse: false, unique: false, - fields: ["c"] } ); + idx0 = c.ensureIndex( { type: "hash", sparse: false, unique: false, + fields: ["b"] } ); + idx1 = c.ensureIndex( { type: "hash", sparse: false, unique: false, + fields: ["c"] } ); var queries = []; var makers = []; @@ -641,8 +656,8 @@ function optimizerIndexesMultiTestSuite () { //////////////////////////////////////////////////////////////////////////////// testUseHashIndexForDNF5 : function () { - c.ensureIndex( { type: "hash", sparse: false, unique: false, - fields: ["c", "b"] } ); + idx0 = c.ensureIndex( { type: "hash", sparse: false, unique: false, + fields: ["c", "b"] } ); var queries = []; var makers = []; @@ -695,8 +710,8 @@ function optimizerIndexesMultiTestSuite () { //////////////////////////////////////////////////////////////////////////////// testUseSkiplistIndexForDNF : function () { - c.ensureIndex( { type: "skiplist", sparse: false, unique: false, - fields: ["b", "c"] } ); + idx0 = c.ensureIndex( { type: "skiplist", sparse: false, unique: false, + fields: ["b", "c"] } ); var queries = []; var makers = []; @@ -749,8 +764,8 @@ function optimizerIndexesMultiTestSuite () { //////////////////////////////////////////////////////////////////////////////// testUseSkiplistIndexForDNF2 : function () { - c.ensureIndex( { type: "skiplist", sparse: false, unique: false, - fields: ["b"] } ); + idx0 = c.ensureIndex( { type: "skiplist", sparse: false, unique: false, + fields: ["b"] } ); var queries = []; var makers = []; @@ -803,8 +818,8 @@ function optimizerIndexesMultiTestSuite () { //////////////////////////////////////////////////////////////////////////////// testUseSkiplistIndexForDNF3: function () { - c.ensureIndex( { type: "skiplist", sparse: false, unique: false, - fields: ["c"] } ); + idx0 = c.ensureIndex( { type: "skiplist", sparse: false, unique: false, + fields: ["c"] } ); var queries = []; var makers = []; @@ -857,10 +872,10 @@ function optimizerIndexesMultiTestSuite () { //////////////////////////////////////////////////////////////////////////////// testUseSkiplistIndexForDNF4 : function () { - c.ensureIndex( { type: "skiplist", sparse: false, unique: false, - fields: ["b"] } ); - c.ensureIndex( { type: "skiplist", sparse: false, unique: false, - fields: ["c"] } ); + idx0 = c.ensureIndex( { type: "skiplist", sparse: false, unique: false, + fields: ["b"] } ); + idx1 = c.ensureIndex( { type: "skiplist", sparse: false, unique: false, + fields: ["c"] } ); var queries = []; var makers = []; @@ -913,8 +928,8 @@ function optimizerIndexesMultiTestSuite () { //////////////////////////////////////////////////////////////////////////////// testUseSkiplistIndexForDNF5 : function () { - c.ensureIndex( { type: "skiplist", sparse: false, unique: false, - fields: ["c", "b"] } ); + idx0 = c.ensureIndex( { type: "skiplist", sparse: false, unique: false, + fields: ["c", "b"] } ); var queries = []; var makers = []; @@ -967,8 +982,8 @@ function optimizerIndexesMultiTestSuite () { //////////////////////////////////////////////////////////////////////////////// testUseSkiplistIndexForMultipleOr : function () { - c.ensureIndex( { type: "skiplist", sparse: false, unique: false, - fields: ["a"] } ); + idx0 = c.ensureIndex( { type: "skiplist", sparse: false, unique: false, + fields: ["a"] } ); var queries = []; var makers = []; @@ -1030,8 +1045,8 @@ function optimizerIndexesMultiTestSuite () { //////////////////////////////////////////////////////////////////////////////// testUseSkiplistIndexForMultipleOr2 : function () { - c.ensureIndex( { type: "skiplist", sparse: false, unique: false, - fields: ["a"] } ); + idx0 = c.ensureIndex( { type: "skiplist", sparse: false, unique: false, + fields: ["a"] } ); var queries = []; var makers = []; @@ -1104,8 +1119,8 @@ function optimizerIndexesMultiTestSuite () { //////////////////////////////////////////////////////////////////////////////// testUseSkiplistIndexForMultipleOr3: function () { - c.ensureIndex( { type: "skiplist", sparse: false, unique: false, - fields: ["a"] } ); + idx0 = c.ensureIndex( { type: "skiplist", sparse: false, unique: false, + fields: ["a"] } ); var queries = []; var makers = []; @@ -1189,8 +1204,8 @@ function optimizerIndexesMultiTestSuite () { //////////////////////////////////////////////////////////////////////////////// testUseSkiplistIndexForIn : function () { - c.ensureIndex( { type: "skiplist", sparse: false, unique: false, - fields: ["a"] } ); + idx0 = c.ensureIndex( { type: "skiplist", sparse: false, unique: false, + fields: ["a"] } ); var queries = []; var makers = []; @@ -1246,8 +1261,8 @@ function optimizerIndexesMultiTestSuite () { //////////////////////////////////////////////////////////////////////////////// testUseHashIndexForMultipleOr : function () { - c.ensureIndex( { type: "hash", sparse: false, unique: false, - fields: ["a"] } ); + idx0 = c.ensureIndex( { type: "hash", sparse: false, unique: false, + fields: ["a"] } ); var queries = []; var makers = []; @@ -1310,8 +1325,8 @@ function optimizerIndexesMultiTestSuite () { //////////////////////////////////////////////////////////////////////////////// testUseHashIndexForIn : function () { - c.ensureIndex( { type: "hash", sparse: false, unique: false, - fields: ["a"] } ); + idx0 = c.ensureIndex( { type: "hash", sparse: false, unique: false, + fields: ["a"] } ); var queries = []; var makers = []; @@ -1369,10 +1384,10 @@ function optimizerIndexesMultiTestSuite () { //////////////////////////////////////////////////////////////////////////////// testUseHashIndexesForInOrIn : function () { - c.ensureIndex( { type: "hash", sparse: false, unique: false, - fields: ["b"] } ); - c.ensureIndex( { type: "hash", sparse: false, unique: false, - fields: ["c"] } ); + idx0 = c.ensureIndex( { type: "hash", sparse: false, unique: false, + fields: ["b"] } ); + idx1 = c.ensureIndex( { type: "hash", sparse: false, unique: false, + fields: ["c"] } ); var queries = []; var makers = []; @@ -1467,10 +1482,10 @@ function optimizerIndexesMultiTestSuite () { //////////////////////////////////////////////////////////////////////////////// testUseSkiplistIndexesForInOrIn : function () { - c.ensureIndex( { type: "skiplist", sparse: false, unique: false, - fields: ["b"] } ); - c.ensureIndex( { type: "skiplist", sparse: false, unique: false, - fields: ["c"] } ); + idx0 = c.ensureIndex( { type: "skiplist", sparse: false, unique: false, + fields: ["b"] } ); + idx1 = c.ensureIndex( { type: "skiplist", sparse: false, unique: false, + fields: ["c"] } ); var queries = []; var makers = []; @@ -1565,10 +1580,10 @@ function optimizerIndexesMultiTestSuite () { //////////////////////////////////////////////////////////////////////////////// testUseSkiplistRespHashIndexesForInOrEq : function () { - c.ensureIndex( { type: "skiplist", sparse: false, unique: false, - fields: ["b"] } ); - c.ensureIndex( { type: "hash", sparse: false, unique: false, - fields: ["c"] } ); + idx0 = c.ensureIndex( { type: "skiplist", sparse: false, unique: false, + fields: ["b"] } ); + idx1 = c.ensureIndex( { type: "hash", sparse: false, unique: false, + fields: ["c"] } ); var queries = []; var makers = []; @@ -1659,8 +1674,8 @@ function optimizerIndexesMultiTestSuite () { //////////////////////////////////////////////////////////////////////////////// testUseSkiplistForOverlappingRanges : function () { - c.ensureIndex( { type: "skiplist", sparse: false, unique: false, - fields: ["a"] } ); + idx0 = c.ensureIndex( { type: "skiplist", sparse: false, unique: false, + fields: ["a"] } ); var queries = []; var makers = []; @@ -1737,8 +1752,8 @@ function optimizerIndexesMultiTestSuite () { //////////////////////////////////////////////////////////////////////////////// testUseSkiplistForMultipleRangesWithOr: function () { - c.ensureIndex( { type: "skiplist", sparse: false, unique: false, - fields: ["a"] } ); + idx0 = c.ensureIndex( { type: "skiplist", sparse: false, unique: false, + fields: ["a"] } ); var queries = []; var makers = []; diff --git a/tests/js/server/aql/aql-optimizer-indexes-sort.js b/tests/js/server/aql/aql-optimizer-indexes-sort.js index 66498a6e40..511360c35e 100644 --- a/tests/js/server/aql/aql-optimizer-indexes-sort.js +++ b/tests/js/server/aql/aql-optimizer-indexes-sort.js @@ -44,9 +44,11 @@ function optimizerIndexesSortTestSuite () { db._drop("UnitTestsCollection"); c = db._create("UnitTestsCollection"); + let docs = []; for (var i = 0; i < 2000; ++i) { - c.save({ _key: "test" + i, value: i % 10 }); + docs.push({ _key: "test" + i, value: i % 10 }); } + c.insert(docs); c.ensureSkiplist("value"); }, diff --git a/tests/js/server/aql/aql-optimizer-indexes.js b/tests/js/server/aql/aql-optimizer-indexes.js index 44c37fe706..838fc3f150 100644 --- a/tests/js/server/aql/aql-optimizer-indexes.js +++ b/tests/js/server/aql/aql-optimizer-indexes.js @@ -39,53 +39,42 @@ const opt = { optimizer: { rules: ["-reduce-extraction-to-projection"] } }; function optimizerIndexesTestSuite () { var c; + var idx = null; + var idx1 = null; + let deleteDefaultIdx = function() { + db._dropIndex(idx); + idx = null; + }; return { - setUp : function () { + setUpAll: function() { db._drop("UnitTestsCollection"); c = db._create("UnitTestsCollection"); + let docs = []; for (var i = 0; i < 2000; ++i) { - c.save({ _key: "test" + i, value: i }); + docs.push({ _key: "test" + i, value: i }); + } + c.insert(docs); + + idx = c.ensureSkiplist("value"); + }, + + setUp: function() { + if (idx === null) { + idx = c.ensureSkiplist("value"); } - - c.ensureSkiplist("value"); }, - tearDown : function () { + tearDownAll: function() { db._drop("UnitTestsCollection"); }, - testMultiIndexesOrCondition : function () { - let values = [ - [ "abc", true, true ], - [ "abc", false, true ], - [ "abc", true, false ] - ]; - - values.forEach(function(v) { - c.update("test2", { test1: v[0], test2: v[1], test3: v[2] }); - let q = "FOR doc IN UnitTestsCollection FILTER doc.value == 2 && doc.test1 == 'abc' && (doc.test2 || doc.test3) RETURN doc"; - var results = AQL_EXECUTE(q); - assertEqual(1, results.json.length); - assertEqual(2, results.json[0].value); - assertEqual(v[0], results.json[0].test1); - assertEqual(v[1], results.json[0].test2); - assertEqual(v[2], results.json[0].test3); - - let plan = AQL_EXPLAIN(q).plan; - let nodes = plan.nodes; - let nodeTypes = plan.nodes.map(function(node) { - return node.type; - }); - let indexNode = nodes[nodeTypes.indexOf("IndexNode")]; - assertEqual("n-ary or", indexNode.condition.type); - assertEqual(2, indexNode.condition.subNodes.length); - assertEqual("n-ary and", indexNode.condition.subNodes[0].type); - assertEqual("compare ==", indexNode.condition.subNodes[0].subNodes[0].type); - assertEqual("n-ary and", indexNode.condition.subNodes[1].type); - assertEqual("compare ==", indexNode.condition.subNodes[1].subNodes[0].type); - }); + tearDown: function() { + if (idx1 !== null) { + db._dropIndex(idx1); + idx1 = null; + } }, //////////////////////////////////////////////////////////////////////////////// @@ -624,181 +613,6 @@ function optimizerIndexesTestSuite () { assertEqual(1, results.stats.scannedIndex); }, -//////////////////////////////////////////////////////////////////////////////// -/// @brief test index usage -//////////////////////////////////////////////////////////////////////////////// - - testUseIndexMultipleFiltersWithLimit : function () { - c.insert({ value: "one" }); - c.insert({ value: "two" }); - c.insert({ value: "one" }); - c.insert({ value: "two" }); - var query = "FOR i IN " + c.name() + " FILTER i.value IN ['one', 'two'] SORT i.value DESC LIMIT 0, 2 FILTER i.value == 'one' RETURN i.value"; - - var plan = AQL_EXPLAIN(query, {}, opt).plan; - var nodeTypes = plan.nodes.map(function(node) { - return node.type; - }); - - assertEqual("SingletonNode", nodeTypes[0], query); - assertNotEqual(-1, nodeTypes.indexOf("IndexNode"), query); - - var results = AQL_EXECUTE(query, {}, opt); - assertEqual([ ], results.json, query); - assertEqual(0, results.stats.scannedFull); - assertTrue(results.stats.scannedIndex > 0); - - // retry without index - var idx = c.lookupIndex({ type: "skiplist", fields: [ "value" ] }); - c.dropIndex(idx); - - results = AQL_EXECUTE(query, {}, opt); - assertEqual([ ], results.json, query); - assertTrue(results.stats.scannedFull > 0); - assertEqual(0, results.stats.scannedIndex); - }, - -//////////////////////////////////////////////////////////////////////////////// -/// @brief test index usage -//////////////////////////////////////////////////////////////////////////////// - - testUseIndexMultipleFilters1 : function () { - c.insert({ value: "one" }); - c.insert({ value: "one" }); - c.insert({ value: "two" }); - c.insert({ value: "two" }); - var query = "FOR i IN " + c.name() + " FILTER i.value IN ['one', 'two'] FILTER i.value == 'one' RETURN i.value"; - - var plan = AQL_EXPLAIN(query, {}, opt).plan; - var nodeTypes = plan.nodes.map(function(node) { - return node.type; - }); - - assertEqual("SingletonNode", nodeTypes[0], query); - assertNotEqual(-1, nodeTypes.indexOf("IndexNode"), query); - - var results = AQL_EXECUTE(query, {}, opt); - assertEqual([ 'one', 'one' ], results.json, query); - assertEqual(0, results.stats.scannedFull); - assertTrue(results.stats.scannedIndex > 0); - - // retry without index - var idx = c.lookupIndex({ type: "skiplist", fields: [ "value" ] }); - c.dropIndex(idx); - - results = AQL_EXECUTE(query, {}, opt); - assertEqual([ 'one', 'one' ], results.json, query); - assertTrue(results.stats.scannedFull > 0); - assertEqual(0, results.stats.scannedIndex); - }, - -//////////////////////////////////////////////////////////////////////////////// -/// @brief test index usage -//////////////////////////////////////////////////////////////////////////////// - - testUseIndexMultipleFilters2 : function () { - c.insert({ value: "one" }); - c.insert({ value: "one" }); - c.insert({ value: "two" }); - c.insert({ value: "two" }); - var query = "FOR i IN " + c.name() + " FILTER i.value IN ['one', 'two'] LIMIT 0, 4 FILTER i.value == 'one' RETURN i.value"; - - var plan = AQL_EXPLAIN(query, {}, opt).plan; - var nodeTypes = plan.nodes.map(function(node) { - return node.type; - }); - - assertEqual("SingletonNode", nodeTypes[0], query); - assertNotEqual(-1, nodeTypes.indexOf("IndexNode"), query); - assertNotEqual(-1, nodeTypes.indexOf("LimitNode"), query); - - var results = AQL_EXECUTE(query, {}, opt); - assertEqual([ 'one', 'one' ], results.json, query); - assertEqual(0, results.stats.scannedFull); - assertTrue(results.stats.scannedIndex > 0); - - // retry without index - var idx = c.lookupIndex({ type: "skiplist", fields: [ "value" ] }); - c.dropIndex(idx); - - results = AQL_EXECUTE(query, {}, opt); - assertEqual([ 'one', 'one' ], results.json, query); - assertTrue(results.stats.scannedFull > 0); - assertEqual(0, results.stats.scannedIndex); - }, - -//////////////////////////////////////////////////////////////////////////////// -/// @brief test index usage -//////////////////////////////////////////////////////////////////////////////// - - testUseIndexMultipleFiltersInvalid1 : function () { - c.insert({ value: "one" }); - c.insert({ value: "one" }); - c.insert({ value: "two" }); - c.insert({ value: "two" }); - var query = "FOR i IN " + c.name() + " FILTER i.value IN ['one', 'two'] FILTER i.value == 'three' RETURN i.value"; - - var plan = AQL_EXPLAIN(query, {}, opt).plan; - var nodeTypes = plan.nodes.map(function(node) { - return node.type; - }); - - assertEqual("SingletonNode", nodeTypes[0], query); - assertEqual(-1, nodeTypes.indexOf("IndexNode"), query); - assertNotEqual(-1, nodeTypes.indexOf("NoResultsNode"), query); - - var results = AQL_EXECUTE(query, {}, opt); - assertEqual([ ], results.json, query); - assertEqual(0, results.stats.scannedFull); - assertEqual(0, results.stats.scannedIndex); - - // retry without index - var idx = c.lookupIndex({ type: "skiplist", fields: [ "value" ] }); - c.dropIndex(idx); - - results = AQL_EXECUTE(query, {}, opt); - assertEqual([ ], results.json, query); - assertEqual(0, results.stats.scannedFull); - assertEqual(0, results.stats.scannedIndex); - }, - -//////////////////////////////////////////////////////////////////////////////// -/// @brief test index usage -//////////////////////////////////////////////////////////////////////////////// - - testUseIndexMultipleFiltersInvalid2 : function () { - c.insert({ value: "one" }); - c.insert({ value: "one" }); - c.insert({ value: "two" }); - c.insert({ value: "two" }); - var query = "FOR i IN " + c.name() + " FILTER i.value IN ['one', 'two'] LIMIT 0, 4 FILTER i.value == 'three' RETURN i.value"; - - var plan = AQL_EXPLAIN(query, {}, opt).plan; - var nodeTypes = plan.nodes.map(function(node) { - if (node.type === 'IndexNode') { - assertTrue(node.producesResult); - } - return node.type; - }); - - assertEqual("SingletonNode", nodeTypes[0], query); - assertEqual(1, nodeTypes.indexOf("IndexNode"), query); - - var results = AQL_EXECUTE(query, {}, opt); - assertEqual([ ], results.json, query); - assertEqual(0, results.stats.scannedFull); - assertTrue(results.stats.scannedIndex > 0); - - // retry without index - var idx = c.lookupIndex({ type: "skiplist", fields: [ "value" ] }); - c.dropIndex(idx); - - results = AQL_EXECUTE(query, {}, opt); - assertEqual([ ], results.json, query); - assertTrue(results.stats.scannedFull > 0); - assertEqual(0, results.stats.scannedIndex); - }, - //////////////////////////////////////////////////////////////////////////////// /// @brief test index usage //////////////////////////////////////////////////////////////////////////////// @@ -1109,7 +923,7 @@ function optimizerIndexesTestSuite () { //////////////////////////////////////////////////////////////////////////////// testMultipleSubqueriesMultipleIndexes : function () { - c.ensureHashIndex("value"); // now we have a hash and a skiplist index + idx1 = c.ensureHashIndex("value"); // now we have a hash and a skiplist index var query = "LET a = (FOR x IN " + c.name() + " FILTER x.value == 1 RETURN x._key) " + "LET b = (FOR x IN " + c.name() + " FILTER x.value == 2 RETURN x._key) " + "LET c = (FOR x IN " + c.name() + " FILTER x.value == 3 RETURN x._key) " + @@ -1165,8 +979,8 @@ function optimizerIndexesTestSuite () { //////////////////////////////////////////////////////////////////////////////// testMultipleSubqueriesHashIndexes : function () { - c.dropIndex(c.getIndexes()[1]); // drop skiplist index - c.ensureHashIndex("value"); + deleteDefaultIdx(); // drop skiplist index + idx1 = c.ensureHashIndex("value"); var query = "LET a = (FOR x IN " + c.name() + " FILTER x.value == 1 RETURN x._key) " + "LET b = (FOR x IN " + c.name() + " FILTER x.value == 2 RETURN x._key) " + "LET c = (FOR x IN " + c.name() + " FILTER x.value == 3 RETURN x._key) " + @@ -1217,7 +1031,7 @@ function optimizerIndexesTestSuite () { //////////////////////////////////////////////////////////////////////////////// testJoinMultipleIndexes : function () { - c.ensureHashIndex("value"); // now we have a hash and a skiplist index + idx1 = c.ensureHashIndex("value"); // now we have a hash and a skiplist index var query = "FOR i IN " + c.name() + " FILTER i.value < 10 FOR j IN " + c.name() + " FILTER j.value == i.value RETURN j._key"; var explain = AQL_EXPLAIN(query, {}, opt); @@ -1264,7 +1078,7 @@ function optimizerIndexesTestSuite () { //////////////////////////////////////////////////////////////////////////////// testJoinRangesMultipleIndexes : function () { - c.ensureHashIndex("value"); // now we have a hash and a skiplist index + idx1 = c.ensureHashIndex("value"); // now we have a hash and a skiplist index var query = "FOR i IN " + c.name() + " FILTER i.value < 5 FOR j IN " + c.name() + " FILTER j.value < i.value RETURN j._key"; var explain = AQL_EXPLAIN(query, {}, opt); @@ -1303,7 +1117,7 @@ function optimizerIndexesTestSuite () { //////////////////////////////////////////////////////////////////////////////// testTripleJoin : function () { - c.ensureHashIndex("value"); // now we have a hash and a skiplist index + idx1 = c.ensureHashIndex("value"); // now we have a hash and a skiplist index var query = "FOR i IN " + c.name() + " FILTER i.value == 4 FOR j IN " + c.name() + " FILTER j.value == i.value FOR k IN " + c.name() + " FILTER k.value < j.value RETURN k._key"; var explain = AQL_EXPLAIN(query, {}, opt); @@ -1354,7 +1168,7 @@ function optimizerIndexesTestSuite () { //////////////////////////////////////////////////////////////////////////////// testSubqueryMadness : function () { - c.ensureHashIndex("value"); // now we have a hash and a skiplist index + idx1 = c.ensureHashIndex("value"); // now we have a hash and a skiplist index var query = "LET a = (FOR x IN " + c.name() + " FILTER x.value == 1 FOR y IN " + c.name() + " FILTER y.value == x.value RETURN x._key) " + "LET b = (FOR x IN " + c.name() + " FILTER x.value == 2 FOR y IN " + c.name() + " FILTER y.value == x.value RETURN x._key) " + "LET c = (FOR x IN " + c.name() + " FILTER x.value == 3 FOR y IN " + c.name() + " FILTER y.value == x.value RETURN x._key) " + @@ -1429,7 +1243,7 @@ function optimizerIndexesTestSuite () { }, testIndexOrHashNoDocuments : function () { - c.ensureHashIndex("value"); + idx1 = c.ensureHashIndex("value"); var query = "FOR i IN " + c.name() + " FILTER i.value == 1 || i.value == 9 RETURN 1"; var plan = AQL_EXPLAIN(query, {}, opt).plan; @@ -1498,7 +1312,7 @@ function optimizerIndexesTestSuite () { //////////////////////////////////////////////////////////////////////////////// testIndexOrHash : function () { - c.ensureHashIndex("value"); + idx1 = c.ensureHashIndex("value"); var query = "FOR i IN " + c.name() + " FILTER i.value == 1 || i.value == 9 RETURN i.value"; var plan = AQL_EXPLAIN(query, {}, opt).plan; @@ -1528,7 +1342,7 @@ function optimizerIndexesTestSuite () { //////////////////////////////////////////////////////////////////////////////// testIndexOrUniqueHash : function () { - c.ensureUniqueConstraint("value"); + idx1 = c.ensureUniqueConstraint("value"); var query = "FOR i IN " + c.name() + " FILTER i.value == 1 || i.value == 9 RETURN i.value"; var plan = AQL_EXPLAIN(query, {}, opt).plan; @@ -1573,88 +1387,6 @@ function optimizerIndexesTestSuite () { assertEqual(0, results.stats.scannedFull); }, -//////////////////////////////////////////////////////////////////////////////// -/// @brief test index usage -//////////////////////////////////////////////////////////////////////////////// - - testIndexSkiplistMultiple : function () { - c.truncate(); - for (var i = 0; i < 10; ++i) { - c.insert({ value1: i, value2: i }); - } - c.ensureIndex({ type: "skiplist", fields: [ "value1", "value2" ] }); - - var query = "FOR i IN " + c.name() + " FILTER (i.value2 > 1 && i.value2 < 9) && (i.value1 == 3) RETURN i.value1"; - - var plan = AQL_EXPLAIN(query, {}, opt).plan; - var nodeTypes = plan.nodes.map(function(node) { - if (node.type === "IndexNode") { - assertEqual("skiplist", node.indexes[0].type); - assertFalse(node.indexes[0].unique); - } - return node.type; - }); - - assertNotEqual(-1, nodeTypes.indexOf("IndexNode"), query); - assertEqual(-1, nodeTypes.indexOf("FilterNode"), query); - - var results = AQL_EXECUTE(query, {}, opt); - assertEqual([ 3 ], results.json.sort(), query); - assertEqual(1, results.stats.scannedIndex); - assertEqual(0, results.stats.scannedFull); - }, - -//////////////////////////////////////////////////////////////////////////////// -/// @brief test index usage -//////////////////////////////////////////////////////////////////////////////// - - testIndexSkiplistMultiple2 : function () { - c.truncate(); - for (var i = 0; i < 10; ++i) { - c.insert({ value1: i, value2: i }); - } - c.ensureIndex({ type: "skiplist", fields: [ "value1", "value2" ] }); - - var query = "FOR i IN " + c.name() + " FILTER (i.value2 > 1 && i.value2 < 9) && (i.value1 == 2 || i.value1 == 3) RETURN i.value1"; - - var plan = AQL_EXPLAIN(query, {}, opt).plan; - var nodeTypes = plan.nodes.map(function(node) { - if (node.type === "IndexNode") { - assertEqual("skiplist", node.indexes[0].type); - assertFalse(node.indexes[0].unique); - } - return node.type; - }); - - assertNotEqual(-1, nodeTypes.indexOf("IndexNode"), query); - - var results = AQL_EXECUTE(query, {}, opt); - assertEqual([ 2, 3 ], results.json.sort(), query); - assertEqual(2, results.stats.scannedIndex); - assertEqual(0, results.stats.scannedFull); - }, - - testIndexOrSkiplistNoDocuments : function () { - var query = "FOR i IN " + c.name() + " FILTER i.value == 1 || i.value == 9 RETURN 1"; - - var plan = AQL_EXPLAIN(query, {}, opt).plan; - var nodeTypes = plan.nodes.map(function(node) { - if (node.type === "IndexNode") { - assertFalse(node.producesResult); - assertEqual("skiplist", node.indexes[0].type); - assertFalse(node.indexes[0].unique); - } - return node.type; - }); - - assertNotEqual(-1, nodeTypes.indexOf("IndexNode"), query); - - var results = AQL_EXECUTE(query, {}, opt); - assertEqual([ 1, 1 ], results.json.sort(), query); - assertEqual(2, results.stats.scannedIndex); - assertEqual(0, results.stats.scannedFull); - }, - //////////////////////////////////////////////////////////////////////////////// /// @brief test index usage //////////////////////////////////////////////////////////////////////////////// @@ -1685,7 +1417,7 @@ function optimizerIndexesTestSuite () { //////////////////////////////////////////////////////////////////////////////// testIndexOrUniqueSkiplist : function () { - c.ensureUniqueSkiplist("value"); + idx1 = c.ensureUniqueSkiplist("value"); var query = "FOR i IN " + c.name() + " FILTER i.value == 1 || i.value == 9 RETURN i.value"; var plan = AQL_EXPLAIN(query, {}, opt).plan; @@ -1704,397 +1436,6 @@ function optimizerIndexesTestSuite () { assertEqual(2, results.stats.scannedIndex); assertEqual(0, results.stats.scannedFull); }, - -//////////////////////////////////////////////////////////////////////////////// -/// @brief test index usage -//////////////////////////////////////////////////////////////////////////////// - - testIndexOrNoIndex : function () { - c.ensureSkiplist("value2"); - AQL_EXECUTE("FOR i IN " + c.name() + " UPDATE i WITH { value2: i.value } IN " + c.name()); - - var query = "FOR i IN " + c.name() + " FILTER i.value == 1 || i.value2 == 1 RETURN i.value2"; - - var plan = AQL_EXPLAIN(query, {}, opt).plan; - var nodeTypes = plan.nodes.map(function(node) { - return node.type; - }); - - assertNotEqual(-1, nodeTypes.indexOf("IndexNode"), query); - - var results = AQL_EXECUTE(query, {}, opt); - assertEqual([ 1 ], results.json, query); - assertTrue(results.stats.scannedIndex > 0); - assertEqual(0, results.stats.scannedFull); - }, - -//////////////////////////////////////////////////////////////////////////////// -/// @brief test index usage -//////////////////////////////////////////////////////////////////////////////// - - testIndexOrNoIndexComplexConditionEq : function () { - c.ensureSkiplist("value2"); - AQL_EXECUTE("FOR i IN " + c.name() + " UPDATE i WITH { value2: [ i.value ] } IN " + c.name()); - - var query = "FOR i IN " + c.name() + " FILTER i.value == -1 || [ i.value ] == i.value2 RETURN i.value2"; - - var plan = AQL_EXPLAIN(query, {}, opt).plan; - var nodeTypes = plan.nodes.map(function(node) { - return node.type; - }); - - assertEqual(-1, nodeTypes.indexOf("IndexNode"), query); - - var results = AQL_EXECUTE(query, {}, opt); - assertEqual(2000, results.json.length); - assertEqual(0, results.stats.scannedIndex); - assertTrue(results.stats.scannedFull > 0); - }, - -//////////////////////////////////////////////////////////////////////////////// -/// @brief test index usage -//////////////////////////////////////////////////////////////////////////////// - - testIndexOrNoIndexComplexConditionIn : function () { - c.ensureSkiplist("value2"); - AQL_EXECUTE("FOR i IN " + c.name() + " UPDATE i WITH { value2: [ i.value ] } IN " + c.name()); - - var query = "FOR i IN " + c.name() + " FILTER i.value == -1 || i.value IN i.value2 RETURN i.value2"; - - var plan = AQL_EXPLAIN(query, {}, opt).plan; - var nodeTypes = plan.nodes.map(function(node) { - return node.type; - }); - - assertEqual(-1, nodeTypes.indexOf("IndexNode"), query); - - var results = AQL_EXECUTE(query, {}, opt); - assertEqual(2000, results.json.length); - assertEqual(0, results.stats.scannedIndex); - assertTrue(results.stats.scannedFull > 0); - }, - -//////////////////////////////////////////////////////////////////////////////// -/// @brief test index usage -//////////////////////////////////////////////////////////////////////////////// - - testIndexOrNoIndexComplexConditionLt1 : function () { - c.ensureSkiplist("value2"); - AQL_EXECUTE("FOR i IN " + c.name() + " UPDATE i WITH { value2: i.value - 1 } IN " + c.name()); - - var query = "FOR i IN " + c.name() + " FILTER i.value == -1 || i.value2 < i.value RETURN i.value2"; - - var plan = AQL_EXPLAIN(query, {}, opt).plan; - var nodeTypes = plan.nodes.map(function(node) { - return node.type; - }); - - assertEqual(-1, nodeTypes.indexOf("IndexNode"), query); - - var results = AQL_EXECUTE(query, {}, opt); - assertEqual(2000, results.json.length); - assertEqual(0, results.stats.scannedIndex); - assertTrue(results.stats.scannedFull > 0); - }, - -//////////////////////////////////////////////////////////////////////////////// -/// @brief test index usage -//////////////////////////////////////////////////////////////////////////////// - - testIndexOrNoIndexComplexConditionLt2 : function () { - c.ensureSkiplist("value2"); - AQL_EXECUTE("FOR i IN " + c.name() + " UPDATE i WITH { value2: i.value - 1 } IN " + c.name()); - - var query = "FOR i IN " + c.name() + " FILTER i.value == -1 || i.value2 < NOOPT(i.value) RETURN i.value2"; - - var plan = AQL_EXPLAIN(query, {}, opt).plan; - var nodeTypes = plan.nodes.map(function(node) { - return node.type; - }); - - assertEqual(-1, nodeTypes.indexOf("IndexNode"), query); - - var results = AQL_EXECUTE(query, {}, opt); - assertEqual(2000, results.json.length); - assertEqual(0, results.stats.scannedIndex); - assertTrue(results.stats.scannedFull > 0); - }, - -//////////////////////////////////////////////////////////////////////////////// -/// @brief test index usage -//////////////////////////////////////////////////////////////////////////////// - - testIndexOrNoIndexComplexConditionGt : function () { - c.ensureSkiplist("value2"); - AQL_EXECUTE("FOR i IN " + c.name() + " UPDATE i WITH { value2: i.value + 1 } IN " + c.name()); - - var query = "FOR i IN " + c.name() + " FILTER i.value == -1 || i.value2 > i.value RETURN i.value2"; - - var plan = AQL_EXPLAIN(query, {}, opt).plan; - var nodeTypes = plan.nodes.map(function(node) { - return node.type; - }); - - assertEqual(-1, nodeTypes.indexOf("IndexNode"), query); - - var results = AQL_EXECUTE(query, {}, opt); - assertEqual(2000, results.json.length); - assertEqual(0, results.stats.scannedIndex); - assertTrue(results.stats.scannedFull > 0); - }, - -//////////////////////////////////////////////////////////////////////////////// -/// @brief test index usage -//////////////////////////////////////////////////////////////////////////////// - - testIndexOrHashMultipleRanges : function () { - c.ensureHashIndex("value2", "value3"); - AQL_EXECUTE("FOR i IN " + c.name() + " UPDATE i WITH { value2: i.value, value3: i.value } IN " + c.name()); - - var query = "FOR i IN " + c.name() + " FILTER (i.value2 == 2 && i.value3 == 2) || (i.value2 == 3 && i.value3 == 3) RETURN i.value2"; - - var plan = AQL_EXPLAIN(query, {}, opt).plan; - var nodeTypes = plan.nodes.map(function(node) { - if (node.type === "IndexNode") { - assertEqual("hash", node.indexes[0].type); - assertFalse(node.indexes[0].unique); - assertEqual([ "value2", "value3" ], node.indexes[0].fields); - } - return node.type; - }); - - assertNotEqual(-1, nodeTypes.indexOf("IndexNode"), query); - - var results = AQL_EXECUTE(query, {}, opt); - assertEqual([ 2, 3 ], results.json.sort(), query); - assertEqual(2, results.stats.scannedIndex); - assertEqual(0, results.stats.scannedFull); - }, - -//////////////////////////////////////////////////////////////////////////////// -/// @brief test index usage -//////////////////////////////////////////////////////////////////////////////// - - testIndexOrSkiplistMultipleRanges : function () { - c.ensureSkiplist("value2", "value3"); - AQL_EXECUTE("FOR i IN " + c.name() + " UPDATE i WITH { value2: i.value, value3: i.value } IN " + c.name()); - - var query = "FOR i IN " + c.name() + " FILTER (i.value2 == 2 && i.value3 == 2) || (i.value2 == 3 && i.value3 == 3) RETURN i.value2"; - - var plan = AQL_EXPLAIN(query, {}, opt).plan; - var nodeTypes = plan.nodes.map(function(node) { - if (node.type === "IndexNode") { - assertEqual("skiplist", node.indexes[0].type); - assertFalse(node.indexes[0].unique); - assertEqual([ "value2", "value3" ], node.indexes[0].fields); - } - return node.type; - }); - - assertNotEqual(-1, nodeTypes.indexOf("IndexNode"), query); - - var results = AQL_EXECUTE(query, {}, opt); - assertEqual([ 2, 3 ], results.json.sort(), query); - assertEqual(2, results.stats.scannedIndex); - assertEqual(0, results.stats.scannedFull); - }, - -//////////////////////////////////////////////////////////////////////////////// -/// @brief test index usage -//////////////////////////////////////////////////////////////////////////////// - - testIndexOrHashMultipleRangesPartialNoIndex1 : function () { - c.ensureHashIndex("value2", "value3"); - AQL_EXECUTE("FOR i IN " + c.name() + " UPDATE i WITH { value2: i.value, value3: i.value } IN " + c.name()); - - var query = "FOR i IN " + c.name() + " FILTER (i.value2 == 1 && i.value3 == 1) || (i.value2 == 2) RETURN i.value2"; - - var plan = AQL_EXPLAIN(query, {}, opt).plan; - var nodeTypes = plan.nodes.map(function(node) { - return node.type; - }); - // rocksdb supports prefix filtering in the hash index - if (db._engine().name !== "rocksdb") { - assertEqual(-1, nodeTypes.indexOf("IndexNode"), query); - } - - var results = AQL_EXECUTE(query, {}, opt); - assertEqual([ 1, 2 ], results.json.sort(), query); - if (db._engine().name === "rocksdb") { - assertEqual(2, results.stats.scannedIndex); - assertEqual(0, results.stats.scannedFull); - } else { - assertEqual(0, results.stats.scannedIndex); - assertTrue(results.stats.scannedFull > 0); - } - }, - -//////////////////////////////////////////////////////////////////////////////// -/// @brief test index usage -//////////////////////////////////////////////////////////////////////////////// - - testIndexOrHashMultipleRangesPartialNoIndex2 : function () { - c.ensureHashIndex("value2", "value3"); - AQL_EXECUTE("FOR i IN " + c.name() + " UPDATE i WITH { value2: i.value, value3: i.value } IN " + c.name()); - - var query = "FOR i IN " + c.name() + " FILTER (i.value2 == 1 && i.value3 == 1) || (i.value3 == 2) RETURN i.value2"; - - var plan = AQL_EXPLAIN(query, {}, opt).plan; - var nodeTypes = plan.nodes.map(function(node) { - return node.type; - }); - assertEqual(-1, nodeTypes.indexOf("IndexNode"), query); - - var results = AQL_EXECUTE(query, {}, opt); - assertEqual([ 1, 2 ], results.json.sort(), query); - assertEqual(0, results.stats.scannedIndex); - assertTrue(results.stats.scannedFull > 0); - }, - -//////////////////////////////////////////////////////////////////////////////// -/// @brief test index usage -//////////////////////////////////////////////////////////////////////////////// - - testIndexOrSkiplistMultipleRangesPartialIndex : function () { - c.ensureSkiplist("value2", "value3"); - AQL_EXECUTE("FOR i IN " + c.name() + " UPDATE i WITH { value2: i.value, value3: i.value } IN " + c.name()); - - var query = "FOR i IN " + c.name() + " FILTER (i.value2 == 1 && i.value3 == 1) || (i.value2 == 2) RETURN i.value2"; - - var plan = AQL_EXPLAIN(query, {}, opt).plan; - var nodeTypes = plan.nodes.map(function(node) { - if (node.type === "IndexNode") { - assertEqual("skiplist", node.indexes[0].type); - assertFalse(node.indexes[0].unique); - assertEqual([ "value2", "value3" ], node.indexes[0].fields); - } - return node.type; - }); - assertNotEqual(-1, nodeTypes.indexOf("IndexNode"), query); - - var results = AQL_EXECUTE(query, {}, opt); - assertEqual([ 1, 2 ], results.json.sort(), query); - assertEqual(2, results.stats.scannedIndex); - assertEqual(0, results.stats.scannedFull); - }, - -//////////////////////////////////////////////////////////////////////////////// -/// @brief test index usage -//////////////////////////////////////////////////////////////////////////////// - - testIndexOrSkiplistMultipleRangesPartialNoIndex : function () { - c.ensureSkiplist("value2", "value3"); - AQL_EXECUTE("FOR i IN " + c.name() + " UPDATE i WITH { value2: i.value, value3: i.value } IN " + c.name()); - - var query = "FOR i IN " + c.name() + " FILTER (i.value2 == 1 && i.value3 == 1) || (i.value3 == 2) RETURN i.value2"; - - var plan = AQL_EXPLAIN(query, {}, opt).plan; - var nodeTypes = plan.nodes.map(function(node) { - return node.type; - }); - assertEqual(-1, nodeTypes.indexOf("IndexNode"), query); - - var results = AQL_EXECUTE(query, {}, opt); - assertEqual([ 1, 2 ], results.json.sort(), query); - assertEqual(0, results.stats.scannedIndex); - assertTrue(results.stats.scannedFull > 0); - }, - -//////////////////////////////////////////////////////////////////////////////// -/// @brief test index usage -//////////////////////////////////////////////////////////////////////////////// - - testIndexAndUseIndex : function () { - c.ensureSkiplist("value2"); - AQL_EXECUTE("FOR i IN " + c.name() + " UPDATE i WITH { value2: i.value } IN " + c.name()); - - var query = "FOR i IN " + c.name() + " FILTER i.value == 1 && i.value2 == 1 RETURN i.value2"; - - var plan = AQL_EXPLAIN(query, {}, opt).plan; - var nodeTypes = plan.nodes.map(function(node) { - return node.type; - }); - - assertNotEqual(-1, nodeTypes.indexOf("IndexNode"), query); - - var results = AQL_EXECUTE(query, {}, opt); - assertEqual([ 1 ], results.json, query); - assertEqual(0, results.stats.scannedFull); - assertTrue(results.stats.scannedIndex > 0); - }, - -//////////////////////////////////////////////////////////////////////////////// -/// @brief test index usage -//////////////////////////////////////////////////////////////////////////////// - - testIndexOrNoIndexBecauseOfDifferentAttributes : function () { - AQL_EXECUTE("FOR i IN " + c.name() + " UPDATE i WITH { value2: i.value, value3: 1 } IN " + c.name()); - - var queries = [ - "FOR i IN " + c.name() + " FILTER i.value == 1 || i.value2 == 2 RETURN i.value", - "FOR i IN " + c.name() + " FILTER i.value2 == 2 || i.value == 1 RETURN i.value", - "FOR i IN " + c.name() + " FILTER (i.value == 1 || i.value == 2) || i.value2 == 2 RETURN i.value", - "FOR i IN " + c.name() + " FILTER i.value2 == 2 || (i.value == 1 || i.value == 2) RETURN i.value", - "FOR i IN " + c.name() + " FILTER i.value == 1 || (i.value == 2 || i.value2 == 2) RETURN i.value", - "FOR i IN " + c.name() + " FILTER (i.value2 == 2 || i.value == 1) || i.value == 2 RETURN i.value", - "FOR i IN " + c.name() + " FILTER (i.value == 1 && i.value2 == 1) || (i.value == 2 || i.value3 != 1) RETURN i.value", - "FOR i IN " + c.name() + " FILTER (i.value2 == 1 && i.value == 1) || (i.value3 != 1 || i.value == 2) RETURN i.value", - "FOR i IN " + c.name() + " FILTER (i.value == 1 && i.value2 == 1) || (i.value == 2 || i.value3 == 0) RETURN i.value", - "FOR i IN " + c.name() + " FILTER (i.value2 == 1 && i.value == 1) || (i.value3 == 0 || i.value == 2) RETURN i.value" - ]; - - queries.forEach(function(query) { - var plan = AQL_EXPLAIN(query, {}, opt).plan; - var nodeTypes = plan.nodes.map(function(node) { - return node.type; - }); - - assertEqual(-1, nodeTypes.indexOf("IndexNode"), query); - var results = AQL_EXECUTE(query, {}, opt); - assertEqual(2, results.json.length); - assertTrue(results.stats.scannedFull > 0); - assertEqual(0, results.stats.scannedIndex); - }); - }, - -//////////////////////////////////////////////////////////////////////////////// -/// @brief test index usage -//////////////////////////////////////////////////////////////////////////////// - - testIndexOrNoIndexBecauseOfOperator : function () { - AQL_EXECUTE("FOR i IN " + c.name() + " UPDATE i WITH { value2: i.value, value3: 1 } IN " + c.name()); - - var queries = [ - "FOR i IN " + c.name() + " FILTER i.value == 1 || i.value2 != i.value RETURN i.value", - "FOR i IN " + c.name() + " FILTER i.value2 != i.value || i.value == 1 RETURN i.value", - "FOR i IN " + c.name() + " FILTER i.value != 1 && NOOPT(i.value2) == 2 RETURN i.value", - "FOR i IN " + c.name() + " FILTER i.value != 1 FILTER NOOPT(i.value2) == 2 RETURN i.value", - "FOR i IN " + c.name() + " FILTER NOOPT(i.value2) == 2 && i.value != 1 RETURN i.value", - "FOR i IN " + c.name() + " FILTER NOOPT(i.value2) == 2 FILTER i.value != 1 RETURN i.value", - "FOR i IN " + c.name() + " FILTER i.value2 != 2 && NOOPT(i.value) == 1 RETURN i.value", - "FOR i IN " + c.name() + " FILTER i.value2 != 2 FILTER NOOPT(i.value) == 1 RETURN i.value", - "FOR i IN " + c.name() + " FILTER NOOPT(i.value) == 1 && i.value2 != 2 RETURN i.value", - "FOR i IN " + c.name() + " FILTER NOOPT(i.value) == 1 FILTER i.value2 != 2 RETURN i.value", - "FOR i IN " + c.name() + " FILTER i.value == 1 || i.value3 != 1 RETURN i.value", - "FOR i IN " + c.name() + " FILTER i.value3 != 1 || i.value == 1 RETURN i.value", - "FOR i IN " + c.name() + " FILTER i.value3 != 1 || i.value2 == 2 RETURN i.value", - "FOR i IN " + c.name() + " FILTER i.value2 == 2 || i.value3 != 1 RETURN i.value" - ]; - - queries.forEach(function(query) { - var plan = AQL_EXPLAIN(query, {}, opt).plan; - var nodeTypes = plan.nodes.map(function(node) { - return node.type; - }); - - assertEqual(-1, nodeTypes.indexOf("IndexNode"), query); - var results = AQL_EXECUTE(query, {}, opt); - assertEqual(1, results.json.length, query); - assertTrue(results.stats.scannedFull > 0); - assertEqual(0, results.stats.scannedIndex); - }); - }, - //////////////////////////////////////////////////////////////////////////////// /// @brief test index usage //////////////////////////////////////////////////////////////////////////////// @@ -2487,6 +1828,720 @@ function optimizerIndexesTestSuite () { assertTrue(results.stats.scannedFull > 0); }); }, + }; +} + +function optimizerIndexesModifyTestSuite () { + var c; + var idx = null; + var idx1 = null; + var idx2 = null; + + return { + setUp: function() { + db._drop("UnitTestsCollection"); + c = db._create("UnitTestsCollection"); + + let docs = []; + for (var i = 0; i < 2000; ++i) { + docs.push({ _key: "test" + i, value: i }); + } + c.insert(docs); + + idx = c.ensureSkiplist("value"); + }, + + tearDown: function() { + db._drop("UnitTestsCollection"); + }, + + testMultiIndexesOrCondition : function () { + let values = [ + [ "abc", true, true ], + [ "abc", false, true ], + [ "abc", true, false ] + ]; + + values.forEach(function(v) { + c.update("test2", { test1: v[0], test2: v[1], test3: v[2] }); + let q = "FOR doc IN UnitTestsCollection FILTER doc.value == 2 && doc.test1 == 'abc' && (doc.test2 || doc.test3) RETURN doc"; + var results = AQL_EXECUTE(q); + assertEqual(1, results.json.length); + assertEqual(2, results.json[0].value); + assertEqual(v[0], results.json[0].test1); + assertEqual(v[1], results.json[0].test2); + assertEqual(v[2], results.json[0].test3); + + let plan = AQL_EXPLAIN(q).plan; + let nodes = plan.nodes; + let nodeTypes = plan.nodes.map(function(node) { + return node.type; + }); + let indexNode = nodes[nodeTypes.indexOf("IndexNode")]; + assertEqual("n-ary or", indexNode.condition.type); + assertEqual(2, indexNode.condition.subNodes.length); + assertEqual("n-ary and", indexNode.condition.subNodes[0].type); + assertEqual("compare ==", indexNode.condition.subNodes[0].subNodes[0].type); + assertEqual("n-ary and", indexNode.condition.subNodes[1].type); + assertEqual("compare ==", indexNode.condition.subNodes[1].subNodes[0].type); + }); + }, +//////////////////////////////////////////////////////////////////////////////// +/// @brief test index usage +//////////////////////////////////////////////////////////////////////////////// + + testUseIndexMultipleFiltersWithLimit : function () { + c.insert([{ value: "one" }, + { value: "two" }, + { value: "one" }, + { value: "two" }]); + var query = "FOR i IN " + c.name() + " FILTER i.value IN ['one', 'two'] SORT i.value DESC LIMIT 0, 2 FILTER i.value == 'one' RETURN i.value"; + + var plan = AQL_EXPLAIN(query, {}, opt).plan; + var nodeTypes = plan.nodes.map(function(node) { + return node.type; + }); + + assertEqual("SingletonNode", nodeTypes[0], query); + assertNotEqual(-1, nodeTypes.indexOf("IndexNode"), query); + + var results = AQL_EXECUTE(query, {}, opt); + assertEqual([ ], results.json, query); + assertEqual(0, results.stats.scannedFull); + assertTrue(results.stats.scannedIndex > 0); + + // retry without index + var idx = c.lookupIndex({ type: "skiplist", fields: [ "value" ] }); + c.dropIndex(idx); + idx = null; + + results = AQL_EXECUTE(query, {}, opt); + assertEqual([ ], results.json, query); + assertTrue(results.stats.scannedFull > 0); + assertEqual(0, results.stats.scannedIndex); + }, + +//////////////////////////////////////////////////////////////////////////////// +/// @brief test index usage +//////////////////////////////////////////////////////////////////////////////// + + testUseIndexMultipleFilters1 : function () { + c.insert([{ value: "one" }, + { value: "one" }, + { value: "two" }, + { value: "two" }]); + var query = "FOR i IN " + c.name() + " FILTER i.value IN ['one', 'two'] FILTER i.value == 'one' RETURN i.value"; + + var plan = AQL_EXPLAIN(query, {}, opt).plan; + var nodeTypes = plan.nodes.map(function(node) { + return node.type; + }); + + assertEqual("SingletonNode", nodeTypes[0], query); + assertNotEqual(-1, nodeTypes.indexOf("IndexNode"), query); + + var results = AQL_EXECUTE(query, {}, opt); + assertEqual([ 'one', 'one' ], results.json, query); + assertEqual(0, results.stats.scannedFull); + assertTrue(results.stats.scannedIndex > 0); + + // retry without index + var idx = c.lookupIndex({ type: "skiplist", fields: [ "value" ] }); + c.dropIndex(idx); + idx = null; + + results = AQL_EXECUTE(query, {}, opt); + assertEqual([ 'one', 'one' ], results.json, query); + assertTrue(results.stats.scannedFull > 0); + assertEqual(0, results.stats.scannedIndex); + }, + +//////////////////////////////////////////////////////////////////////////////// +/// @brief test index usage +//////////////////////////////////////////////////////////////////////////////// + + testUseIndexMultipleFilters2 : function () { + c.insert([{ value: "one" }, + { value: "one" }, + { value: "two" }, + { value: "two" }]); + var query = "FOR i IN " + c.name() + " FILTER i.value IN ['one', 'two'] LIMIT 0, 4 FILTER i.value == 'one' RETURN i.value"; + + var plan = AQL_EXPLAIN(query, {}, opt).plan; + var nodeTypes = plan.nodes.map(function(node) { + return node.type; + }); + + assertEqual("SingletonNode", nodeTypes[0], query); + assertNotEqual(-1, nodeTypes.indexOf("IndexNode"), query); + assertNotEqual(-1, nodeTypes.indexOf("LimitNode"), query); + + var results = AQL_EXECUTE(query, {}, opt); + assertEqual([ 'one', 'one' ], results.json, query); + assertEqual(0, results.stats.scannedFull); + assertTrue(results.stats.scannedIndex > 0); + + // retry without index + var idx = c.lookupIndex({ type: "skiplist", fields: [ "value" ] }); + c.dropIndex(idx); + idx = null; + + results = AQL_EXECUTE(query, {}, opt); + assertEqual([ 'one', 'one' ], results.json, query); + assertTrue(results.stats.scannedFull > 0); + assertEqual(0, results.stats.scannedIndex); + }, + +//////////////////////////////////////////////////////////////////////////////// +/// @brief test index usage +//////////////////////////////////////////////////////////////////////////////// + + testUseIndexMultipleFiltersInvalid1 : function () { + c.insert([{ value: "one" }, + { value: "one" }, + { value: "two" }, + { value: "two" }]); + var query = "FOR i IN " + c.name() + " FILTER i.value IN ['one', 'two'] FILTER i.value == 'three' RETURN i.value"; + + var plan = AQL_EXPLAIN(query, {}, opt).plan; + var nodeTypes = plan.nodes.map(function(node) { + return node.type; + }); + + assertEqual("SingletonNode", nodeTypes[0], query); + assertEqual(-1, nodeTypes.indexOf("IndexNode"), query); + assertNotEqual(-1, nodeTypes.indexOf("NoResultsNode"), query); + + var results = AQL_EXECUTE(query, {}, opt); + assertEqual([ ], results.json, query); + assertEqual(0, results.stats.scannedFull); + assertEqual(0, results.stats.scannedIndex); + + // retry without index + var idx = c.lookupIndex({ type: "skiplist", fields: [ "value" ] }); + c.dropIndex(idx); + idx = null; + + results = AQL_EXECUTE(query, {}, opt); + assertEqual([ ], results.json, query); + assertEqual(0, results.stats.scannedFull); + assertEqual(0, results.stats.scannedIndex); + }, + +//////////////////////////////////////////////////////////////////////////////// +/// @brief test index usage +//////////////////////////////////////////////////////////////////////////////// + + testUseIndexMultipleFiltersInvalid2 : function () { + c.insert([{ value: "one" }, + { value: "one" }, + { value: "two" }, + { value: "two" }]); + var query = "FOR i IN " + c.name() + " FILTER i.value IN ['one', 'two'] LIMIT 0, 4 FILTER i.value == 'three' RETURN i.value"; + + var plan = AQL_EXPLAIN(query, {}, opt).plan; + var nodeTypes = plan.nodes.map(function(node) { + if (node.type === 'IndexNode') { + assertTrue(node.producesResult); + } + return node.type; + }); + + assertEqual("SingletonNode", nodeTypes[0], query); + assertEqual(1, nodeTypes.indexOf("IndexNode"), query); + + var results = AQL_EXECUTE(query, {}, opt); + assertEqual([ ], results.json, query); + assertEqual(0, results.stats.scannedFull); + assertTrue(results.stats.scannedIndex > 0); + + // retry without index + var idx = c.lookupIndex({ type: "skiplist", fields: [ "value" ] }); + c.dropIndex(idx); + idx = null; + + results = AQL_EXECUTE(query, {}, opt); + assertEqual([ ], results.json, query); + assertTrue(results.stats.scannedFull > 0); + assertEqual(0, results.stats.scannedIndex); + }, + +//////////////////////////////////////////////////////////////////////////////// +/// @brief test index usage +//////////////////////////////////////////////////////////////////////////////// + + testIndexSkiplistMultiple : function () { + c.truncate(); + let docs = []; + for (var i = 0; i < 10; ++i) { + docs.push({ value1: i, value2: i }); + } + c.insert(docs); + c.ensureIndex({ type: "skiplist", fields: [ "value1", "value2" ] }); + + var query = "FOR i IN " + c.name() + " FILTER (i.value2 > 1 && i.value2 < 9) && (i.value1 == 3) RETURN i.value1"; + + var plan = AQL_EXPLAIN(query, {}, opt).plan; + var nodeTypes = plan.nodes.map(function(node) { + if (node.type === "IndexNode") { + assertEqual("skiplist", node.indexes[0].type); + assertFalse(node.indexes[0].unique); + } + return node.type; + }); + + assertNotEqual(-1, nodeTypes.indexOf("IndexNode"), query); + assertEqual(-1, nodeTypes.indexOf("FilterNode"), query); + + var results = AQL_EXECUTE(query, {}, opt); + assertEqual([ 3 ], results.json.sort(), query); + assertEqual(1, results.stats.scannedIndex); + assertEqual(0, results.stats.scannedFull); + }, + +//////////////////////////////////////////////////////////////////////////////// +/// @brief test index usage +//////////////////////////////////////////////////////////////////////////////// + + testIndexSkiplistMultiple2 : function () { + c.truncate(); + let docs = []; + for (var i = 0; i < 10; ++i) { + docs.push({ value1: i, value2: i }); + } + c.insert(docs); + c.ensureIndex({ type: "skiplist", fields: [ "value1", "value2" ] }); + + var query = "FOR i IN " + c.name() + " FILTER (i.value2 > 1 && i.value2 < 9) && (i.value1 == 2 || i.value1 == 3) RETURN i.value1"; + + var plan = AQL_EXPLAIN(query, {}, opt).plan; + var nodeTypes = plan.nodes.map(function(node) { + if (node.type === "IndexNode") { + assertEqual("skiplist", node.indexes[0].type); + assertFalse(node.indexes[0].unique); + } + return node.type; + }); + + assertNotEqual(-1, nodeTypes.indexOf("IndexNode"), query); + + var results = AQL_EXECUTE(query, {}, opt); + assertEqual([ 2, 3 ], results.json.sort(), query); + assertEqual(2, results.stats.scannedIndex); + assertEqual(0, results.stats.scannedFull); + }, + + testIndexOrSkiplistNoDocuments : function () { + var query = "FOR i IN " + c.name() + " FILTER i.value == 1 || i.value == 9 RETURN 1"; + + var plan = AQL_EXPLAIN(query, {}, opt).plan; + var nodeTypes = plan.nodes.map(function(node) { + if (node.type === "IndexNode") { + assertFalse(node.producesResult); + assertEqual("skiplist", node.indexes[0].type); + assertFalse(node.indexes[0].unique); + } + return node.type; + }); + + assertNotEqual(-1, nodeTypes.indexOf("IndexNode"), query); + + var results = AQL_EXECUTE(query, {}, opt); + assertEqual([ 1, 1 ], results.json.sort(), query); + assertEqual(2, results.stats.scannedIndex); + assertEqual(0, results.stats.scannedFull); + }, + + +//////////////////////////////////////////////////////////////////////////////// +/// @brief test index usage +//////////////////////////////////////////////////////////////////////////////// + + testIndexOrNoIndex : function () { + c.ensureSkiplist("value2"); + AQL_EXECUTE("FOR i IN " + c.name() + " UPDATE i WITH { value2: i.value } IN " + c.name()); + + var query = "FOR i IN " + c.name() + " FILTER i.value == 1 || i.value2 == 1 RETURN i.value2"; + + var plan = AQL_EXPLAIN(query, {}, opt).plan; + var nodeTypes = plan.nodes.map(function(node) { + return node.type; + }); + + assertNotEqual(-1, nodeTypes.indexOf("IndexNode"), query); + + var results = AQL_EXECUTE(query, {}, opt); + assertEqual([ 1 ], results.json, query); + assertTrue(results.stats.scannedIndex > 0); + assertEqual(0, results.stats.scannedFull); + }, + +//////////////////////////////////////////////////////////////////////////////// +/// @brief test index usage +//////////////////////////////////////////////////////////////////////////////// + + testIndexOrNoIndexComplexConditionEq : function () { + c.ensureSkiplist("value2"); + AQL_EXECUTE("FOR i IN " + c.name() + " UPDATE i WITH { value2: [ i.value ] } IN " + c.name()); + + var query = "FOR i IN " + c.name() + " FILTER i.value == -1 || [ i.value ] == i.value2 RETURN i.value2"; + + var plan = AQL_EXPLAIN(query, {}, opt).plan; + var nodeTypes = plan.nodes.map(function(node) { + return node.type; + }); + + assertEqual(-1, nodeTypes.indexOf("IndexNode"), query); + + var results = AQL_EXECUTE(query, {}, opt); + assertEqual(2000, results.json.length); + assertEqual(0, results.stats.scannedIndex); + assertTrue(results.stats.scannedFull > 0); + }, + +//////////////////////////////////////////////////////////////////////////////// +/// @brief test index usage +//////////////////////////////////////////////////////////////////////////////// + + testIndexOrNoIndexComplexConditionIn : function () { + c.ensureSkiplist("value2"); + AQL_EXECUTE("FOR i IN " + c.name() + " UPDATE i WITH { value2: [ i.value ] } IN " + c.name()); + + var query = "FOR i IN " + c.name() + " FILTER i.value == -1 || i.value IN i.value2 RETURN i.value2"; + + var plan = AQL_EXPLAIN(query, {}, opt).plan; + var nodeTypes = plan.nodes.map(function(node) { + return node.type; + }); + + assertEqual(-1, nodeTypes.indexOf("IndexNode"), query); + + var results = AQL_EXECUTE(query, {}, opt); + assertEqual(2000, results.json.length); + assertEqual(0, results.stats.scannedIndex); + assertTrue(results.stats.scannedFull > 0); + }, + +//////////////////////////////////////////////////////////////////////////////// +/// @brief test index usage +//////////////////////////////////////////////////////////////////////////////// + + testIndexOrNoIndexComplexConditionLt1 : function () { + c.ensureSkiplist("value2"); + AQL_EXECUTE("FOR i IN " + c.name() + " UPDATE i WITH { value2: i.value - 1 } IN " + c.name()); + + var query = "FOR i IN " + c.name() + " FILTER i.value == -1 || i.value2 < i.value RETURN i.value2"; + + var plan = AQL_EXPLAIN(query, {}, opt).plan; + var nodeTypes = plan.nodes.map(function(node) { + return node.type; + }); + + assertEqual(-1, nodeTypes.indexOf("IndexNode"), query); + + var results = AQL_EXECUTE(query, {}, opt); + assertEqual(2000, results.json.length); + assertEqual(0, results.stats.scannedIndex); + assertTrue(results.stats.scannedFull > 0); + }, + +//////////////////////////////////////////////////////////////////////////////// +/// @brief test index usage +//////////////////////////////////////////////////////////////////////////////// + + testIndexOrNoIndexComplexConditionLt2 : function () { + c.ensureSkiplist("value2"); + AQL_EXECUTE("FOR i IN " + c.name() + " UPDATE i WITH { value2: i.value - 1 } IN " + c.name()); + + var query = "FOR i IN " + c.name() + " FILTER i.value == -1 || i.value2 < NOOPT(i.value) RETURN i.value2"; + + var plan = AQL_EXPLAIN(query, {}, opt).plan; + var nodeTypes = plan.nodes.map(function(node) { + return node.type; + }); + + assertEqual(-1, nodeTypes.indexOf("IndexNode"), query); + + var results = AQL_EXECUTE(query, {}, opt); + assertEqual(2000, results.json.length); + assertEqual(0, results.stats.scannedIndex); + assertTrue(results.stats.scannedFull > 0); + }, + +//////////////////////////////////////////////////////////////////////////////// +/// @brief test index usage +//////////////////////////////////////////////////////////////////////////////// + + testIndexOrNoIndexComplexConditionGt : function () { + c.ensureSkiplist("value2"); + AQL_EXECUTE("FOR i IN " + c.name() + " UPDATE i WITH { value2: i.value + 1 } IN " + c.name()); + + var query = "FOR i IN " + c.name() + " FILTER i.value == -1 || i.value2 > i.value RETURN i.value2"; + + var plan = AQL_EXPLAIN(query, {}, opt).plan; + var nodeTypes = plan.nodes.map(function(node) { + return node.type; + }); + + assertEqual(-1, nodeTypes.indexOf("IndexNode"), query); + + var results = AQL_EXECUTE(query, {}, opt); + assertEqual(2000, results.json.length); + assertEqual(0, results.stats.scannedIndex); + assertTrue(results.stats.scannedFull > 0); + }, + +//////////////////////////////////////////////////////////////////////////////// +/// @brief test index usage +//////////////////////////////////////////////////////////////////////////////// + + testIndexOrHashMultipleRanges : function () { + c.ensureHashIndex("value2", "value3"); + AQL_EXECUTE("FOR i IN " + c.name() + " UPDATE i WITH { value2: i.value, value3: i.value } IN " + c.name()); + + var query = "FOR i IN " + c.name() + " FILTER (i.value2 == 2 && i.value3 == 2) || (i.value2 == 3 && i.value3 == 3) RETURN i.value2"; + + var plan = AQL_EXPLAIN(query, {}, opt).plan; + var nodeTypes = plan.nodes.map(function(node) { + if (node.type === "IndexNode") { + assertEqual("hash", node.indexes[0].type); + assertFalse(node.indexes[0].unique); + assertEqual([ "value2", "value3" ], node.indexes[0].fields); + } + return node.type; + }); + + assertNotEqual(-1, nodeTypes.indexOf("IndexNode"), query); + + var results = AQL_EXECUTE(query, {}, opt); + assertEqual([ 2, 3 ], results.json.sort(), query); + assertEqual(2, results.stats.scannedIndex); + assertEqual(0, results.stats.scannedFull); + }, + +//////////////////////////////////////////////////////////////////////////////// +/// @brief test index usage +//////////////////////////////////////////////////////////////////////////////// + + testIndexOrSkiplistMultipleRanges : function () { + c.ensureSkiplist("value2", "value3"); + AQL_EXECUTE("FOR i IN " + c.name() + " UPDATE i WITH { value2: i.value, value3: i.value } IN " + c.name()); + + var query = "FOR i IN " + c.name() + " FILTER (i.value2 == 2 && i.value3 == 2) || (i.value2 == 3 && i.value3 == 3) RETURN i.value2"; + + var plan = AQL_EXPLAIN(query, {}, opt).plan; + var nodeTypes = plan.nodes.map(function(node) { + if (node.type === "IndexNode") { + assertEqual("skiplist", node.indexes[0].type); + assertFalse(node.indexes[0].unique); + assertEqual([ "value2", "value3" ], node.indexes[0].fields); + } + return node.type; + }); + + assertNotEqual(-1, nodeTypes.indexOf("IndexNode"), query); + + var results = AQL_EXECUTE(query, {}, opt); + assertEqual([ 2, 3 ], results.json.sort(), query); + assertEqual(2, results.stats.scannedIndex); + assertEqual(0, results.stats.scannedFull); + }, + +//////////////////////////////////////////////////////////////////////////////// +/// @brief test index usage +//////////////////////////////////////////////////////////////////////////////// + + testIndexOrHashMultipleRangesPartialNoIndex1 : function () { + c.ensureHashIndex("value2", "value3"); + AQL_EXECUTE("FOR i IN " + c.name() + " UPDATE i WITH { value2: i.value, value3: i.value } IN " + c.name()); + + var query = "FOR i IN " + c.name() + " FILTER (i.value2 == 1 && i.value3 == 1) || (i.value2 == 2) RETURN i.value2"; + + var plan = AQL_EXPLAIN(query, {}, opt).plan; + var nodeTypes = plan.nodes.map(function(node) { + return node.type; + }); + // rocksdb supports prefix filtering in the hash index + if (db._engine().name !== "rocksdb") { + assertEqual(-1, nodeTypes.indexOf("IndexNode"), query); + } + + var results = AQL_EXECUTE(query, {}, opt); + assertEqual([ 1, 2 ], results.json.sort(), query); + if (db._engine().name === "rocksdb") { + assertEqual(2, results.stats.scannedIndex); + assertEqual(0, results.stats.scannedFull); + } else { + assertEqual(0, results.stats.scannedIndex); + assertTrue(results.stats.scannedFull > 0); + } + }, + +//////////////////////////////////////////////////////////////////////////////// +/// @brief test index usage +//////////////////////////////////////////////////////////////////////////////// + + testIndexOrHashMultipleRangesPartialNoIndex2 : function () { + c.ensureHashIndex("value2", "value3"); + AQL_EXECUTE("FOR i IN " + c.name() + " UPDATE i WITH { value2: i.value, value3: i.value } IN " + c.name()); + + var query = "FOR i IN " + c.name() + " FILTER (i.value2 == 1 && i.value3 == 1) || (i.value3 == 2) RETURN i.value2"; + + var plan = AQL_EXPLAIN(query, {}, opt).plan; + var nodeTypes = plan.nodes.map(function(node) { + return node.type; + }); + assertEqual(-1, nodeTypes.indexOf("IndexNode"), query); + + var results = AQL_EXECUTE(query, {}, opt); + assertEqual([ 1, 2 ], results.json.sort(), query); + assertEqual(0, results.stats.scannedIndex); + assertTrue(results.stats.scannedFull > 0); + }, + +//////////////////////////////////////////////////////////////////////////////// +/// @brief test index usage +//////////////////////////////////////////////////////////////////////////////// + + testIndexOrSkiplistMultipleRangesPartialIndex : function () { + c.ensureSkiplist("value2", "value3"); + AQL_EXECUTE("FOR i IN " + c.name() + " UPDATE i WITH { value2: i.value, value3: i.value } IN " + c.name()); + + var query = "FOR i IN " + c.name() + " FILTER (i.value2 == 1 && i.value3 == 1) || (i.value2 == 2) RETURN i.value2"; + + var plan = AQL_EXPLAIN(query, {}, opt).plan; + var nodeTypes = plan.nodes.map(function(node) { + if (node.type === "IndexNode") { + assertEqual("skiplist", node.indexes[0].type); + assertFalse(node.indexes[0].unique); + assertEqual([ "value2", "value3" ], node.indexes[0].fields); + } + return node.type; + }); + assertNotEqual(-1, nodeTypes.indexOf("IndexNode"), query); + + var results = AQL_EXECUTE(query, {}, opt); + assertEqual([ 1, 2 ], results.json.sort(), query); + assertEqual(2, results.stats.scannedIndex); + assertEqual(0, results.stats.scannedFull); + }, + +//////////////////////////////////////////////////////////////////////////////// +/// @brief test index usage +//////////////////////////////////////////////////////////////////////////////// + + testIndexOrSkiplistMultipleRangesPartialNoIndex : function () { + c.ensureSkiplist("value2", "value3"); + AQL_EXECUTE("FOR i IN " + c.name() + " UPDATE i WITH { value2: i.value, value3: i.value } IN " + c.name()); + + var query = "FOR i IN " + c.name() + " FILTER (i.value2 == 1 && i.value3 == 1) || (i.value3 == 2) RETURN i.value2"; + + var plan = AQL_EXPLAIN(query, {}, opt).plan; + var nodeTypes = plan.nodes.map(function(node) { + return node.type; + }); + assertEqual(-1, nodeTypes.indexOf("IndexNode"), query); + + var results = AQL_EXECUTE(query, {}, opt); + assertEqual([ 1, 2 ], results.json.sort(), query); + assertEqual(0, results.stats.scannedIndex); + assertTrue(results.stats.scannedFull > 0); + }, + +//////////////////////////////////////////////////////////////////////////////// +/// @brief test index usage +//////////////////////////////////////////////////////////////////////////////// + + testIndexAndUseIndex : function () { + c.ensureSkiplist("value2"); + AQL_EXECUTE("FOR i IN " + c.name() + " UPDATE i WITH { value2: i.value } IN " + c.name()); + + var query = "FOR i IN " + c.name() + " FILTER i.value == 1 && i.value2 == 1 RETURN i.value2"; + + var plan = AQL_EXPLAIN(query, {}, opt).plan; + var nodeTypes = plan.nodes.map(function(node) { + return node.type; + }); + + assertNotEqual(-1, nodeTypes.indexOf("IndexNode"), query); + + var results = AQL_EXECUTE(query, {}, opt); + assertEqual([ 1 ], results.json, query); + assertEqual(0, results.stats.scannedFull); + assertTrue(results.stats.scannedIndex > 0); + }, + +//////////////////////////////////////////////////////////////////////////////// +/// @brief test index usage +//////////////////////////////////////////////////////////////////////////////// + + testIndexOrNoIndexBecauseOfDifferentAttributes : function () { + AQL_EXECUTE("FOR i IN " + c.name() + " UPDATE i WITH { value2: i.value, value3: 1 } IN " + c.name()); + + var queries = [ + "FOR i IN " + c.name() + " FILTER i.value == 1 || i.value2 == 2 RETURN i.value", + "FOR i IN " + c.name() + " FILTER i.value2 == 2 || i.value == 1 RETURN i.value", + "FOR i IN " + c.name() + " FILTER (i.value == 1 || i.value == 2) || i.value2 == 2 RETURN i.value", + "FOR i IN " + c.name() + " FILTER i.value2 == 2 || (i.value == 1 || i.value == 2) RETURN i.value", + "FOR i IN " + c.name() + " FILTER i.value == 1 || (i.value == 2 || i.value2 == 2) RETURN i.value", + "FOR i IN " + c.name() + " FILTER (i.value2 == 2 || i.value == 1) || i.value == 2 RETURN i.value", + "FOR i IN " + c.name() + " FILTER (i.value == 1 && i.value2 == 1) || (i.value == 2 || i.value3 != 1) RETURN i.value", + "FOR i IN " + c.name() + " FILTER (i.value2 == 1 && i.value == 1) || (i.value3 != 1 || i.value == 2) RETURN i.value", + "FOR i IN " + c.name() + " FILTER (i.value == 1 && i.value2 == 1) || (i.value == 2 || i.value3 == 0) RETURN i.value", + "FOR i IN " + c.name() + " FILTER (i.value2 == 1 && i.value == 1) || (i.value3 == 0 || i.value == 2) RETURN i.value" + ]; + + queries.forEach(function(query) { + var plan = AQL_EXPLAIN(query, {}, opt).plan; + var nodeTypes = plan.nodes.map(function(node) { + return node.type; + }); + + assertEqual(-1, nodeTypes.indexOf("IndexNode"), query); + var results = AQL_EXECUTE(query, {}, opt); + assertEqual(2, results.json.length); + assertTrue(results.stats.scannedFull > 0); + assertEqual(0, results.stats.scannedIndex); + }); + }, + +//////////////////////////////////////////////////////////////////////////////// +/// @brief test index usage +//////////////////////////////////////////////////////////////////////////////// + + testIndexOrNoIndexBecauseOfOperator : function () { + AQL_EXECUTE("FOR i IN " + c.name() + " UPDATE i WITH { value2: i.value, value3: 1 } IN " + c.name()); + + var queries = [ + "FOR i IN " + c.name() + " FILTER i.value == 1 || i.value2 != i.value RETURN i.value", + "FOR i IN " + c.name() + " FILTER i.value2 != i.value || i.value == 1 RETURN i.value", + "FOR i IN " + c.name() + " FILTER i.value != 1 && NOOPT(i.value2) == 2 RETURN i.value", + "FOR i IN " + c.name() + " FILTER i.value != 1 FILTER NOOPT(i.value2) == 2 RETURN i.value", + "FOR i IN " + c.name() + " FILTER NOOPT(i.value2) == 2 && i.value != 1 RETURN i.value", + "FOR i IN " + c.name() + " FILTER NOOPT(i.value2) == 2 FILTER i.value != 1 RETURN i.value", + "FOR i IN " + c.name() + " FILTER i.value2 != 2 && NOOPT(i.value) == 1 RETURN i.value", + "FOR i IN " + c.name() + " FILTER i.value2 != 2 FILTER NOOPT(i.value) == 1 RETURN i.value", + "FOR i IN " + c.name() + " FILTER NOOPT(i.value) == 1 && i.value2 != 2 RETURN i.value", + "FOR i IN " + c.name() + " FILTER NOOPT(i.value) == 1 FILTER i.value2 != 2 RETURN i.value", + "FOR i IN " + c.name() + " FILTER i.value == 1 || i.value3 != 1 RETURN i.value", + "FOR i IN " + c.name() + " FILTER i.value3 != 1 || i.value == 1 RETURN i.value", + "FOR i IN " + c.name() + " FILTER i.value3 != 1 || i.value2 == 2 RETURN i.value", + "FOR i IN " + c.name() + " FILTER i.value2 == 2 || i.value3 != 1 RETURN i.value" + ]; + + queries.forEach(function(query) { + var plan = AQL_EXPLAIN(query, {}, opt).plan; + var nodeTypes = plan.nodes.map(function(node) { + return node.type; + }); + + assertEqual(-1, nodeTypes.indexOf("IndexNode"), query); + var results = AQL_EXECUTE(query, {}, opt); + assertEqual(1, results.json.length, query); + assertTrue(results.stats.scannedFull > 0); + assertEqual(0, results.stats.scannedIndex); + }); + }, //////////////////////////////////////////////////////////////////////////////// /// @brief test index usage @@ -3591,6 +3646,10 @@ function optimizerIndexesTestSuite () { }; } + + + + //////////////////////////////////////////////////////////////////////////////// /// @brief test suite //////////////////////////////////////////////////////////////////////////////// @@ -3910,6 +3969,7 @@ function optimizerIndexesMultiCollectionTestSuite () { //////////////////////////////////////////////////////////////////////////////// jsunity.run(optimizerIndexesTestSuite); +jsunity.run(optimizerIndexesModifyTestSuite); jsunity.run(optimizerIndexesMultiCollectionTestSuite); return jsunity.done(); diff --git a/tests/js/server/aql/aql-optimizer-rule-remove-unnecessary-remote-scatter-cluster.js b/tests/js/server/aql/aql-optimizer-rule-remove-unnecessary-remote-scatter-cluster.js index 340782cb4d..6576447261 100644 --- a/tests/js/server/aql/aql-optimizer-rule-remove-unnecessary-remote-scatter-cluster.js +++ b/tests/js/server/aql/aql-optimizer-rule-remove-unnecessary-remote-scatter-cluster.js @@ -66,10 +66,14 @@ function optimizerRuleTestSuite () { db._drop(cn2); c1 = db._create(cn1, {numberOfShards:9}); c2 = db._create(cn2); + let docs1 = []; + let docs2 = []; for (i = 0; i < 10; i++){ - c1.insert({Hallo1:i}); - c2.insert({Hallo2:i}); + docs1.push({Hallo1:i}); + docs2.push({Hallo2:i}); } + c1.insert(docs1); + c2.insert(docs2); }, //////////////////////////////////////////////////////////////////////////////// diff --git a/tests/js/server/aql/aql-optimizer-rule-replace-or-with-in.js b/tests/js/server/aql/aql-optimizer-rule-replace-or-with-in.js index cdadfeddb4..9bdeef38db 100644 --- a/tests/js/server/aql/aql-optimizer-rule-replace-or-with-in.js +++ b/tests/js/server/aql/aql-optimizer-rule-replace-or-with-in.js @@ -67,16 +67,36 @@ function NewAqlReplaceORWithINTestSuite () { /// @brief set up //////////////////////////////////////////////////////////////////////////////// - setUp : function () { + setUpAll : function () { internal.debugClearFailAt(); internal.db._drop("UnitTestsNewAqlReplaceORWithINTestSuite"); replace = internal.db._create("UnitTestsNewAqlReplaceORWithINTestSuite"); + let docs = []; for (var i = 1; i <= 10; ++i) { - replace.save({ "value" : i, x: [i]}); - replace.save({"a" : {"b" : i}}); - replace.save({"value": i + 10, "bb": i, "cc": 10 - i }); + docs.push({ "value" : i, x: [i]}); + docs.push({"a" : {"b" : i}}); + docs.push({"value": i + 10, "bb": i, "cc": 10 - i }); } + replace.insert(docs); + }, + +//////////////////////////////////////////////////////////////////////////////// +/// @brief tear down +//////////////////////////////////////////////////////////////////////////////// + + tearDownAll : function () { + internal.debugClearFailAt(); + internal.db._drop("UnitTestsNewAqlReplaceORWithINTestSuite"); + replace = null; + }, + +//////////////////////////////////////////////////////////////////////////////// +/// @brief set up +//////////////////////////////////////////////////////////////////////////////// + + setUp : function () { + internal.debugClearFailAt(); }, //////////////////////////////////////////////////////////////////////////////// @@ -85,8 +105,6 @@ function NewAqlReplaceORWithINTestSuite () { tearDown : function () { internal.debugClearFailAt(); - internal.db._drop("UnitTestsNewAqlReplaceORWithINTestSuite"); - replace = null; }, //////////////////////////////////////////////////////////////////////////////// diff --git a/tests/js/server/aql/aql-optimizer-rule-undistribute-remove-after-enum-coll-cluster.js b/tests/js/server/aql/aql-optimizer-rule-undistribute-remove-after-enum-coll-cluster.js index 82f16c59a3..edf0270099 100644 --- a/tests/js/server/aql/aql-optimizer-rule-undistribute-remove-after-enum-coll-cluster.js +++ b/tests/js/server/aql/aql-optimizer-rule-undistribute-remove-after-enum-coll-cluster.js @@ -64,10 +64,14 @@ function optimizerRuleTestSuite () { db._drop(cn2); c1 = db._create(cn1, {numberOfShards:9}); c2 = db._create(cn2); + let docs1 = []; + let docs2 = []; for (i = 0; i < 10; i++){ - c1.insert({Hallo1:i}); - c2.insert({Hallo2:i}); + docs1.push({Hallo1:i}); + docs2.push({Hallo2:i}); } + c1.insert(docs1); + c2.insert(docs2); }, //////////////////////////////////////////////////////////////////////////////// diff --git a/tests/js/server/aql/aql-optimizer-rule-use-index-for-sort-cluster.js b/tests/js/server/aql/aql-optimizer-rule-use-index-for-sort-cluster.js index 2243dcc0a5..f319ed59e4 100644 --- a/tests/js/server/aql/aql-optimizer-rule-use-index-for-sort-cluster.js +++ b/tests/js/server/aql/aql-optimizer-rule-use-index-for-sort-cluster.js @@ -52,9 +52,12 @@ function optimizerRuleTestSuite() { setUp : function () { internal.db._drop(colName); c = internal.db._create(colName, {numberOfShards: 5}); + let docs = []; for (let i = 0; i < 2000; ++i) { - c.insert({ value: i }); + docs.push({ value: i }); } + c.insert(docs); + c.ensureIndex({ type: "skiplist", fields: [ "value" ] }); }, @@ -106,9 +109,11 @@ function optimizerRuleTestSuite() { testSortAscKeepGatherNonUnique : function () { // add the same values again + let docs = []; for (let i = 0; i < 2000; ++i) { - c.insert({ value: i }); + docs.push({ value: i }); } + c.insert(docs); let query = "FOR doc IN " + colName + " SORT doc.value ASC RETURN doc"; let plan = AQL_EXPLAIN(query).plan; let nodes = plan.nodes.filter(function(n) { return n.type === 'GatherNode'; }); @@ -211,9 +216,11 @@ function optimizerRuleTestSuite() { testCollectIntoSortedKeepGatherNonUnique : function () { // add the same values again + let docs = []; for (let i = 0; i < 2000; ++i) { - c.insert({ value: i }); + docs.push({ value: i }); } + c.insert(docs); let query = "FOR doc IN " + colName + " COLLECT value = doc.value INTO g OPTIONS { method: 'sorted' } RETURN { value, g }"; let plan = AQL_EXPLAIN(query).plan; let nodes = plan.nodes.filter(function(n) { return n.type === 'CollectNode'; }); @@ -243,9 +250,11 @@ function optimizerRuleTestSuite() { testCollectHashKeepGatherNonUnique : function () { // add the same values again + let docs = []; for (let i = 0; i < 2000; ++i) { - c.insert({ value: i }); + docs.push({ value: i }); } + c.insert(docs); let query = "FOR doc IN " + colName + " COLLECT value = doc.value WITH COUNT INTO l OPTIONS { method: 'hash' } RETURN { value, l }"; let plan = AQL_EXPLAIN(query).plan; let nodes = plan.nodes.filter(function(n) { return n.type === 'CollectNode'; }); @@ -272,9 +281,11 @@ function optimizerRuleTestSuite() { testCollectSortedKeepGatherNonUnique : function () { // add the same values again + let docs = []; for (let i = 0; i < 2000; ++i) { - c.insert({ value: i }); + docs.push({ value: i }); } + c.insert(docs); let query = "FOR doc IN " + colName + " COLLECT value = doc.value WITH COUNT INTO l OPTIONS { method: 'sorted' } RETURN { value, l }"; let plan = AQL_EXPLAIN(query).plan; let nodes = plan.nodes.filter(function(n) { return n.type === 'CollectNode'; }); diff --git a/tests/js/server/aql/aql-optimizer-rule-use-index-for-sort.js b/tests/js/server/aql/aql-optimizer-rule-use-index-for-sort.js index 56b535c2da..ccfde4f71e 100644 --- a/tests/js/server/aql/aql-optimizer-rule-use-index-for-sort.js +++ b/tests/js/server/aql/aql-optimizer-rule-use-index-for-sort.js @@ -116,13 +116,15 @@ function optimizerRuleTestSuite() { internal.db._drop(colName); skiplist = internal.db._create(colName, {numberOfShards: 1}); var i, j; + let docs = []; for (j = 1; j <= loopto; ++j) { for (i = 1; i <= loopto; ++i) { - skiplist.save({ "a" : i, "b": j , "c": j, "d": i, "e": i, "joinme" : "aoeu " + j}); + docs.push({ "a" : i, "b": j , "c": j, "d": i, "e": i, "joinme" : "aoeu " + j}); } - skiplist.save( { "a" : i, "c": j, "d": i, "e": i, "joinme" : "aoeu " + j}); - skiplist.save( { "c": j, "joinme" : "aoeu " + j}); + docs.push( { "a" : i, "c": j, "d": i, "e": i, "joinme" : "aoeu " + j}); + docs.push( { "c": j, "joinme" : "aoeu " + j}); } + skiplist.insert(docs); skiplist.ensureSkiplist("a", "b"); skiplist.ensureSkiplist("d"); @@ -130,13 +132,16 @@ function optimizerRuleTestSuite() { internal.db._drop(colNameOther); skiplist2 = internal.db._create(colNameOther, {numberOfShards: 1}); + docs = []; for (j = 1; j <= loopto; ++j) { for (i = 1; i <= loopto; ++i) { - skiplist2.save({ "f" : i, "g": j , "h": j, "i": i, "j": i, "joinme" : "aoeu " + j}); + docs.push({ "f" : i, "g": j , "h": j, "i": i, "j": i, "joinme" : "aoeu " + j}); } - skiplist2.save( { "f" : i, "g": j, "i": i, "j": i, "joinme" : "aoeu " + j}); - skiplist2.save( { "h": j, "joinme" : "aoeu " + j}); + docs.push( { "f" : i, "g": j, "i": i, "j": i, "joinme" : "aoeu " + j}); + docs.push( { "h": j, "joinme" : "aoeu " + j}); } + skiplist2.insert(docs); + skiplist2.ensureSkiplist("f", "g"); skiplist2.ensureSkiplist("i"); skiplist2.ensureIndex({ type: "hash", fields: [ "h" ], unique: false }); diff --git a/tests/js/server/aql/aql-primary-index-cluster.js b/tests/js/server/aql/aql-primary-index-cluster.js index 2f33596daf..36399ae4a1 100644 --- a/tests/js/server/aql/aql-primary-index-cluster.js +++ b/tests/js/server/aql/aql-primary-index-cluster.js @@ -54,9 +54,11 @@ function explainSuite () { db._drop(cn); c = db._create(cn); + let docs = []; for (var i = 0; i < 100; ++i) { - c.save({ _key: "testkey" + i, value: i }); + docs.push({ _key: "testkey" + i, value: i }); } + c.insert(docs); }, //////////////////////////////////////////////////////////////////////////////// diff --git a/tests/js/server/aql/aql-queries-collection.js b/tests/js/server/aql/aql-queries-collection.js index 2c6fe9ea06..89fabe54b7 100644 --- a/tests/js/server/aql/aql-queries-collection.js +++ b/tests/js/server/aql/aql-queries-collection.js @@ -47,82 +47,82 @@ function ahuacatlQueryCollectionTestSuite () { /// @brief set up //////////////////////////////////////////////////////////////////////////////// - setUp : function () { + setUpAll : function () { internal.db._drop("UnitTestsAhuacatlUsers"); internal.db._drop("UnitTestsAhuacatlUserRelations"); users = internal.db._create("UnitTestsAhuacatlUsers"); relations = internal.db._create("UnitTestsAhuacatlUserRelations"); - users.save({ "id" : 100, "name" : "John", "age" : 37, "active" : true, "gender" : "m" }); - users.save({ "id" : 101, "name" : "Fred", "age" : 36, "active" : true, "gender" : "m" }); - users.save({ "id" : 102, "name" : "Jacob", "age" : 35, "active" : false, "gender" : "m" }); - users.save({ "id" : 103, "name" : "Ethan", "age" : 34, "active" : false, "gender" : "m" }); - users.save({ "id" : 104, "name" : "Michael", "age" : 33, "active" : true, "gender" : "m" }); - users.save({ "id" : 105, "name" : "Alexander", "age" : 32, "active" : true, "gender" : "m" }); - users.save({ "id" : 106, "name" : "Daniel", "age" : 31, "active" : true, "gender" : "m" }); - users.save({ "id" : 107, "name" : "Anthony", "age" : 30, "active" : true, "gender" : "m" }); - users.save({ "id" : 108, "name" : "Jim", "age" : 29, "active" : true, "gender" : "m" }); - users.save({ "id" : 109, "name" : "Diego", "age" : 28, "active" : true, "gender" : "m" }); + users.insert([{ "id" : 100, "name" : "John", "age" : 37, "active" : true, "gender" : "m" }, + { "id" : 101, "name" : "Fred", "age" : 36, "active" : true, "gender" : "m" }, + { "id" : 102, "name" : "Jacob", "age" : 35, "active" : false, "gender" : "m" }, + { "id" : 103, "name" : "Ethan", "age" : 34, "active" : false, "gender" : "m" }, + { "id" : 104, "name" : "Michael", "age" : 33, "active" : true, "gender" : "m" }, + { "id" : 105, "name" : "Alexander", "age" : 32, "active" : true, "gender" : "m" }, + { "id" : 106, "name" : "Daniel", "age" : 31, "active" : true, "gender" : "m" }, + { "id" : 107, "name" : "Anthony", "age" : 30, "active" : true, "gender" : "m" }, + { "id" : 108, "name" : "Jim", "age" : 29, "active" : true, "gender" : "m" }, + { "id" : 109, "name" : "Diego", "age" : 28, "active" : true, "gender" : "m" }, - users.save({ "id" : 200, "name" : "Sophia", "age" : 37, "active" : true, "gender" : "f" }); - users.save({ "id" : 201, "name" : "Emma", "age" : 36, "active" : true, "gender" : "f" }); - users.save({ "id" : 202, "name" : "Olivia", "age" : 35, "active" : false, "gender" : "f" }); - users.save({ "id" : 203, "name" : "Madison", "age" : 34, "active" : true, "gender": "f" }); - users.save({ "id" : 204, "name" : "Chloe", "age" : 33, "active" : true, "gender" : "f" }); - users.save({ "id" : 205, "name" : "Eva", "age" : 32, "active" : false, "gender" : "f" }); - users.save({ "id" : 206, "name" : "Abigail", "age" : 31, "active" : true, "gender" : "f" }); - users.save({ "id" : 207, "name" : "Isabella", "age" : 30, "active" : true, "gender" : "f" }); - users.save({ "id" : 208, "name" : "Mary", "age" : 29, "active" : true, "gender" : "f" }); - users.save({ "id" : 209, "name" : "Mariah", "age" : 28, "active" : true, "gender" : "f" }); + { "id" : 200, "name" : "Sophia", "age" : 37, "active" : true, "gender" : "f" }, + { "id" : 201, "name" : "Emma", "age" : 36, "active" : true, "gender" : "f" }, + { "id" : 202, "name" : "Olivia", "age" : 35, "active" : false, "gender" : "f" }, + { "id" : 203, "name" : "Madison", "age" : 34, "active" : true, "gender": "f" }, + { "id" : 204, "name" : "Chloe", "age" : 33, "active" : true, "gender" : "f" }, + { "id" : 205, "name" : "Eva", "age" : 32, "active" : false, "gender" : "f" }, + { "id" : 206, "name" : "Abigail", "age" : 31, "active" : true, "gender" : "f" }, + { "id" : 207, "name" : "Isabella", "age" : 30, "active" : true, "gender" : "f" }, + { "id" : 208, "name" : "Mary", "age" : 29, "active" : true, "gender" : "f" }, + { "id" : 209, "name" : "Mariah", "age" : 28, "active" : true, "gender" : "f" }]); - relations.save({ "from" : 209, "to" : 205, "type" : "friend" }); - relations.save({ "from" : 206, "to" : 108, "type" : "friend" }); - relations.save({ "from" : 202, "to" : 204, "type" : "friend" }); - relations.save({ "from" : 200, "to" : 100, "type" : "friend" }); - relations.save({ "from" : 205, "to" : 101, "type" : "friend" }); - relations.save({ "from" : 209, "to" : 203, "type" : "friend" }); - relations.save({ "from" : 200, "to" : 203, "type" : "friend" }); - relations.save({ "from" : 100, "to" : 208, "type" : "friend" }); - relations.save({ "from" : 101, "to" : 209, "type" : "friend" }); - relations.save({ "from" : 206, "to" : 102, "type" : "friend" }); - relations.save({ "from" : 104, "to" : 100, "type" : "friend" }); - relations.save({ "from" : 104, "to" : 108, "type" : "friend" }); - relations.save({ "from" : 108, "to" : 209, "type" : "friend" }); - relations.save({ "from" : 206, "to" : 106, "type" : "friend" }); - relations.save({ "from" : 204, "to" : 105, "type" : "friend" }); - relations.save({ "from" : 208, "to" : 207, "type" : "friend" }); - relations.save({ "from" : 102, "to" : 108, "type" : "friend" }); - relations.save({ "from" : 207, "to" : 203, "type" : "friend" }); - relations.save({ "from" : 203, "to" : 106, "type" : "friend" }); - relations.save({ "from" : 202, "to" : 108, "type" : "friend" }); - relations.save({ "from" : 201, "to" : 203, "type" : "friend" }); - relations.save({ "from" : 105, "to" : 100, "type" : "friend" }); - relations.save({ "from" : 100, "to" : 109, "type" : "friend" }); - relations.save({ "from" : 207, "to" : 109, "type" : "friend" }); - relations.save({ "from" : 103, "to" : 203, "type" : "friend" }); - relations.save({ "from" : 208, "to" : 104, "type" : "friend" }); - relations.save({ "from" : 105, "to" : 104, "type" : "friend" }); - relations.save({ "from" : 103, "to" : 208, "type" : "friend" }); - relations.save({ "from" : 203, "to" : 107, "type" : "boyfriend" }); - relations.save({ "from" : 107, "to" : 203, "type" : "girlfriend" }); - relations.save({ "from" : 208, "to" : 109, "type" : "boyfriend" }); - relations.save({ "from" : 109, "to" : 208, "type" : "girlfriend" }); - relations.save({ "from" : 106, "to" : 205, "type" : "girlfriend" }); - relations.save({ "from" : 205, "to" : 106, "type" : "boyfriend" }); - relations.save({ "from" : 103, "to" : 209, "type" : "girlfriend" }); - relations.save({ "from" : 209, "to" : 103, "type" : "boyfriend" }); - relations.save({ "from" : 201, "to" : 102, "type" : "boyfriend" }); - relations.save({ "from" : 102, "to" : 201, "type" : "girlfriend" }); - relations.save({ "from" : 206, "to" : 100, "type" : "boyfriend" }); - relations.save({ "from" : 100, "to" : 206, "type" : "girlfriend" }); + relations.insert([{ "from" : 209, "to" : 205, "type" : "friend" }, + { "from" : 206, "to" : 108, "type" : "friend" }, + { "from" : 202, "to" : 204, "type" : "friend" }, + { "from" : 200, "to" : 100, "type" : "friend" }, + { "from" : 205, "to" : 101, "type" : "friend" }, + { "from" : 209, "to" : 203, "type" : "friend" }, + { "from" : 200, "to" : 203, "type" : "friend" }, + { "from" : 100, "to" : 208, "type" : "friend" }, + { "from" : 101, "to" : 209, "type" : "friend" }, + { "from" : 206, "to" : 102, "type" : "friend" }, + { "from" : 104, "to" : 100, "type" : "friend" }, + { "from" : 104, "to" : 108, "type" : "friend" }, + { "from" : 108, "to" : 209, "type" : "friend" }, + { "from" : 206, "to" : 106, "type" : "friend" }, + { "from" : 204, "to" : 105, "type" : "friend" }, + { "from" : 208, "to" : 207, "type" : "friend" }, + { "from" : 102, "to" : 108, "type" : "friend" }, + { "from" : 207, "to" : 203, "type" : "friend" }, + { "from" : 203, "to" : 106, "type" : "friend" }, + { "from" : 202, "to" : 108, "type" : "friend" }, + { "from" : 201, "to" : 203, "type" : "friend" }, + { "from" : 105, "to" : 100, "type" : "friend" }, + { "from" : 100, "to" : 109, "type" : "friend" }, + { "from" : 207, "to" : 109, "type" : "friend" }, + { "from" : 103, "to" : 203, "type" : "friend" }, + { "from" : 208, "to" : 104, "type" : "friend" }, + { "from" : 105, "to" : 104, "type" : "friend" }, + { "from" : 103, "to" : 208, "type" : "friend" }, + { "from" : 203, "to" : 107, "type" : "boyfriend" }, + { "from" : 107, "to" : 203, "type" : "girlfriend" }, + { "from" : 208, "to" : 109, "type" : "boyfriend" }, + { "from" : 109, "to" : 208, "type" : "girlfriend" }, + { "from" : 106, "to" : 205, "type" : "girlfriend" }, + { "from" : 205, "to" : 106, "type" : "boyfriend" }, + { "from" : 103, "to" : 209, "type" : "girlfriend" }, + { "from" : 209, "to" : 103, "type" : "boyfriend" }, + { "from" : 201, "to" : 102, "type" : "boyfriend" }, + { "from" : 102, "to" : 201, "type" : "girlfriend" }, + { "from" : 206, "to" : 100, "type" : "boyfriend" }, + { "from" : 100, "to" : 206, "type" : "girlfriend" }]); }, //////////////////////////////////////////////////////////////////////////////// /// @brief tear down //////////////////////////////////////////////////////////////////////////////// - tearDown : function () { + tearDownAll: function () { internal.db._drop("UnitTestsAhuacatlUsers"); internal.db._drop("UnitTestsAhuacatlUserRelations"); }, @@ -844,18 +844,6 @@ function ahuacatlQueryCollectionTestSuite () { assertEqual(expected, actual); }, -//////////////////////////////////////////////////////////////////////////////// -/// @brief test querying attributes -//////////////////////////////////////////////////////////////////////////////// - - testAttributesQuery3 : function () { - users.save({ "hobbies" : [ "riding", "skating", "swimming" ] }); - - var expected = [ [ "riding", "skating", "swimming", null, "swimming" ] ]; - var actual = getQueryResults("FOR u in " + users.name() + " FILTER HAS(u, 'hobbies') RETURN [ u.hobbies[0], u.hobbies[1], u.hobbies[2], u.hobbies[3], u.hobbies[-1] ]"); - assertEqual(expected, actual); - }, - //////////////////////////////////////////////////////////////////////////////// /// @brief test hashing the documents //////////////////////////////////////////////////////////////////////////////// @@ -895,8 +883,20 @@ function ahuacatlQueryCollectionTestSuite () { var expected = [ 1815371496337334 ]; var actual = getQueryResults("RETURN HASH(FOR u in " + users.name() + " SORT u.id RETURN UNSET(u, ['_key', '_rev', '_id']))"); assertEqual(expected, actual); - } + }, +//////////////////////////////////////////////////////////////////////////////// +/// @brief test querying attributes +//////////////////////////////////////////////////////////////////////////////// + + testAttributesQuery3 : function () { + let doc = users.save({ "hobbies" : [ "riding", "skating", "swimming" ] }); + + var expected = [ [ "riding", "skating", "swimming", null, "swimming" ] ]; + var actual = getQueryResults("FOR u in " + users.name() + " FILTER HAS(u, 'hobbies') RETURN [ u.hobbies[0], u.hobbies[1], u.hobbies[2], u.hobbies[3], u.hobbies[-1] ]"); + assertEqual(expected, actual); + users.remove(doc); + } }; } diff --git a/tests/js/server/aql/aql-queries-document.js b/tests/js/server/aql/aql-queries-document.js index b576190a9a..ee99f9dcb8 100644 --- a/tests/js/server/aql/aql-queries-document.js +++ b/tests/js/server/aql/aql-queries-document.js @@ -37,9 +37,11 @@ function ahuacatlDocumentsTestSuite () { c = internal.db._create("UnitTestsDocument", { numberOfShards }); let i; + let docs = []; for (i = 1; i <= 2000; ++i) { - c.insert({ _key: "test" + i, value: i }); - } + docs.push({ _key: "test" + i, value: i }); + } + c.insert(docs); var query = "FOR i IN 1..2000 RETURN DOCUMENT(CONCAT('" + cn + "/test', TO_NUMBER(i)))"; var nodes = helper.removeClusterNodesFromPlan(AQL_EXPLAIN(query).plan.nodes); diff --git a/tests/js/server/aql/aql-queries-fulltext.js b/tests/js/server/aql/aql-queries-fulltext.js index 17f67afdfb..fd2e3f1051 100644 --- a/tests/js/server/aql/aql-queries-fulltext.js +++ b/tests/js/server/aql/aql-queries-fulltext.js @@ -71,9 +71,10 @@ function ahuacatlFulltextTestSuite () { testFulltext1 : function () { var actual; - fulltext.save({ id : 1, text : "some rubbish text" }); - fulltext.save({ id : 2, text : "More rubbish test data. The index should be able to handle all this." }); - fulltext.save({ id : 3, text : "even MORE rubbish. Nevertheless this should be handled well, too." }); + fulltext.insert([ + { id : 1, text : "some rubbish text" }, + { id : 2, text : "More rubbish test data. The index should be able to handle all this." }, + { id : 3, text : "even MORE rubbish. Nevertheless this should be handled well, too." }]); actual = getQueryResults("FOR d IN FULLTEXT(" + fulltext.name() + ", 'text', 'some') SORT d.id RETURN d.id"); assertEqual([ 1 ], actual); @@ -115,10 +116,12 @@ function ahuacatlFulltextTestSuite () { "Loewenschuetzer moechten maechtige Mueller koedern", "Moechten boese wichte wenig mueller melken?" ]; - + + let docs = []; for (var i = 0; i < texts.length; ++i) { - fulltext.save({ id : (i + 1), text : texts[i] }); + docs.push({ id : (i + 1), text : texts[i] }); } + fulltext.insert(docs); var actual; actual = getQueryResults("FOR d IN FULLTEXT(" + fulltext.name() + ", 'text', 'prefix:möchten,müller') SORT d.id RETURN d.id"); @@ -147,9 +150,9 @@ function ahuacatlFulltextTestSuite () { }, testLimit : function () { - fulltext.save({ id : 1, text : "some rubbish text" }); - fulltext.save({ id : 2, text : "More rubbish test data. The index should be able to handle all this." }); - fulltext.save({ id : 3, text : "even MORE rubbish. Nevertheless this should be handled well, too." }); + fulltext.insert([{ id : 1, text : "some rubbish text" }, + { id : 2, text : "More rubbish test data. The index should be able to handle all this." }, + { id : 3, text : "even MORE rubbish. Nevertheless this should be handled well, too." }]); let actual = getQueryResults("FOR d IN FULLTEXT(" + fulltext.name() + ", 'text', 'some') LIMIT 1, 1 RETURN d._id"); assertEqual([ ], actual); @@ -186,9 +189,11 @@ function ahuacatlFulltextTestSuite () { }, testLimitMany : function () { + let docs = []; for (let i = 0; i < 2000; ++i) { - fulltext.save({ text : "some rubbish text" }); + docs.push({ text : "some rubbish text" }); } + fulltext.insert(docs); let actual = getQueryResults("FOR d IN FULLTEXT(" + fulltext.name() + ", 'text', 'some') LIMIT 999, 1 RETURN 1"); assertEqual([ 1 ], actual); diff --git a/tests/js/server/aql/aql-queries-geo.js b/tests/js/server/aql/aql-queries-geo.js index c072b1ceb6..5da3005096 100644 --- a/tests/js/server/aql/aql-queries-geo.js +++ b/tests/js/server/aql/aql-queries-geo.js @@ -73,27 +73,31 @@ function ahuacatlLegacyGeoTestSuite () { /// @brief set up //////////////////////////////////////////////////////////////////////////////// - setUp : function () { + setUpAll : function () { var lat, lon; db._drop("UnitTestsAhuacatlLocations"); db._drop("UnitTestsAhuacatlLocationsNon"); locations = db._create("UnitTestsAhuacatlLocations"); + let docs = []; for (lat = -40; lat <= 40; ++lat) { for (lon = -40; lon <= 40; ++lon) { - locations.save({"latitude" : lat, "longitude" : lon }); + docs.push({"latitude" : lat, "longitude" : lon }); } } + locations.insert(docs); locations.ensureGeoIndex("latitude", "longitude"); //locations without index locationsNon = db._create("UnitTestsAhuacatlLocationsNon"); + docs = []; for (lat = -40; lat <= 40; ++lat) { for (lon = -40; lon <= 40; ++lon) { - locationsNon.save({"latitude" : lat, "longitude" : lon }); + docs.push({"latitude" : lat, "longitude" : lon }); } } + locationsNon.insert(docs); }, //////////////////////////////////////////////////////////////////////////////// diff --git a/tests/js/server/aql/aql-queries-optimizer-in-cluster.js b/tests/js/server/aql/aql-queries-optimizer-in-cluster.js index f8e7d07b54..ab66c114e8 100644 --- a/tests/js/server/aql/aql-queries-optimizer-in-cluster.js +++ b/tests/js/server/aql/aql-queries-optimizer-in-cluster.js @@ -38,8 +38,15 @@ var getQueryResults = helper.getQueryResults; //////////////////////////////////////////////////////////////////////////////// function ahuacatlQueryOptimizerInTestSuite () { + var e = null; var c = null; + var c2 = null; + var c3 = null; var cn = "UnitTestsAhuacatlOptimizerIn"; + var cn2 = cn + "UniqueConstraint"; + var cn3 = cn + "UniqueSkiplist"; + var cn4 = cn + "Colors"; + var en = cn + "Edge"; var explain = function (query, params) { return helper.getCompactPlan(AQL_EXPLAIN(query, params, { optimizer: { rules: [ "-all", "+use-indexes" ] } })).map(function(node) { return node.type; }); @@ -51,17 +58,56 @@ function ahuacatlQueryOptimizerInTestSuite () { /// @brief set up //////////////////////////////////////////////////////////////////////////////// - setUp : function () { + setUpAll : function () { + let docs = []; + let i; internal.db._drop(cn); + internal.db._drop(en); + c = internal.db._create(cn); + docs.push({ _key: "test0" }); + for (i = 1; i < 100; ++i) { + docs.push({ _key: "test" + i, parent: "test" + (i - 1), parents: [ "test" + (i - 1) ], ids: [ cn + "/test" + i ] }); + } + c.insert(docs); + + c2 = internal.db._create(cn2); + docs = []; + docs.push({ code: "test0" }); + for (i = 1; i < 100; ++i) { + docs.push({ code: "test" + i, parent: "test" + (i - 1), parents: [ "test" + (i - 1) ] }); + } + c2.insert(docs); + c2.ensureUniqueConstraint("code"); + + c3 = internal.db._create(cn3); + docs = []; + docs.push({ code: "test0" }); + for (i = 1; i < 100; ++i) { + docs.push({ code: "test" + i, parent: "test" + (i - 1), parents: [ "test" + (i - 1) ] }); + } + c3.insert(docs); + c3.ensureUniqueSkiplist("code"); + + + docs = []; + e = internal.db._createEdgeCollection(en); + for (i = 1; i < 100; ++i) { + docs.push({'_from': cn + "/test" + i, '_to': cn + "/test" + (i - 1)}); + } + e.insert(docs); }, //////////////////////////////////////////////////////////////////////////////// /// @brief tear down //////////////////////////////////////////////////////////////////////////////// - tearDown : function () { + tearDownAll : function () { internal.db._drop(cn); + internal.db._drop(cn2); + internal.db._drop(cn3); + internal.db._drop(cn4); + internal.db._drop(en); }, //////////////////////////////////////////////////////////////////////////////// @@ -69,10 +115,6 @@ function ahuacatlQueryOptimizerInTestSuite () { //////////////////////////////////////////////////////////////////////////////// testInMergeOr : function () { - c.save({ _key: "test0" }); - for (var i = 1; i < 100; ++i) { - c.save({ _key: "test" + i, parent: "test" + (i - 1), parents: [ "test" + (i - 1) ] }); - } var expected = [ 'test1', 'test2', 'test5', 'test7' ]; var actual = getQueryResults("LET parents = [ 'test5', 'test7' ] FOR c IN " + cn + " FILTER c._key IN parents || c._key IN [ 'test1' ] || c._key IN [ 'test2' ] || c._key IN parents SORT c._key RETURN c._key"); @@ -84,11 +126,6 @@ function ahuacatlQueryOptimizerInTestSuite () { //////////////////////////////////////////////////////////////////////////////// testInMergeAnd : function () { - c.save({ _key: "test0" }); - for (var i = 1; i < 100; ++i) { - c.save({ _key: "test" + i, parent: "test" + (i - 1), parents: [ "test" + (i - 1) ] }); - } - var expected = [ 'test5', 'test7' ]; var actual = getQueryResults("LET parents = [ 'test5', 'test7' ] FOR c IN " + cn + " FILTER c._key IN parents && c._key IN [ 'test5', 'test7' ] && c._key IN [ 'test7', 'test5' ] && c._key IN parents SORT c._key RETURN c._key"); assertEqual(expected, actual); @@ -99,11 +136,6 @@ function ahuacatlQueryOptimizerInTestSuite () { //////////////////////////////////////////////////////////////////////////////// testInPrimaryConst : function () { - c.save({ _key: "test0" }); - for (var i = 1; i < 100; ++i) { - c.save({ _key: "test" + i, parent: "test" + (i - 1), parents: [ "test" + (i - 1) ] }); - } - var expected = [ 'test5', 'test7' ]; var query = "LET parents = [ 'test5', 'test7' ] FOR c IN " + cn + " FILTER c._key IN parents SORT c._key RETURN c._key"; var actual = getQueryResults(query); @@ -117,11 +149,6 @@ function ahuacatlQueryOptimizerInTestSuite () { //////////////////////////////////////////////////////////////////////////////// testInPrimaryDynamic : function () { - c.save({ _key: "test0" }); - for (var i = 1; i < 100; ++i) { - c.save({ _key: "test" + i, parent: "test" + (i - 1), parents: [ "test" + (i - 1) ] }); - } - var expected = [ 'test5', 'test7' ]; var query = "LET parents = (FOR c IN " + cn + " FILTER c._key IN [ 'test5', 'test7' ] RETURN c._key) FOR c IN " + cn + " FILTER c._key IN parents SORT c._key RETURN c._key"; var actual = getQueryResults(query); @@ -135,11 +162,6 @@ function ahuacatlQueryOptimizerInTestSuite () { //////////////////////////////////////////////////////////////////////////////// testInPrimaryDynamicRef : function () { - c.save({ _key: "test0" }); - for (var i = 1; i < 100; ++i) { - c.save({ _key: "test" + i, parent: "test" + (i - 1), parents: [ "test" + (i - 1) ] }); - } - var expected = [ { keys: [ 'test4' ] }, { keys: [ 'test6' ] } ]; var actual = getQueryResults("FOR c IN " + cn + " FILTER c._key IN [ 'test5', 'test7' ] SORT c._key RETURN { keys: (FOR c2 IN " + cn + " FILTER c2._key IN [ c.parent ] RETURN c2._key) }"); assertEqual(expected, actual); @@ -150,11 +172,6 @@ function ahuacatlQueryOptimizerInTestSuite () { //////////////////////////////////////////////////////////////////////////////// testInPrimaryRef : function () { - c.save({ _key: "test0" }); - for (var i = 1; i < 100; ++i) { - c.save({ _key: "test" + i, parent: "test" + (i - 1), parents: [ "test" + (i - 1) ] }); - } - var expected = [ { keys: [ 'test4' ] }, { keys: [ 'test6' ] } ]; var actual = getQueryResults("FOR c IN " + cn + " FILTER c._key IN [ 'test5', 'test7' ] SORT c._key RETURN { keys: (FOR c2 IN " + cn + " FILTER c2._key IN c.parents SORT c2._key RETURN c2._key) }"); assertEqual(expected, actual); @@ -165,14 +182,8 @@ function ahuacatlQueryOptimizerInTestSuite () { //////////////////////////////////////////////////////////////////////////////// testInHashConst : function () { - c.save({ code: "test0" }); - for (var i = 1; i < 100; ++i) { - c.save({ code: "test" + i, parent: "test" + (i - 1), parents: [ "test" + (i - 1) ] }); - } - c.ensureUniqueConstraint("code"); - var expected = [ 'test5', 'test7' ]; - var query = "LET parents = [ 'test5', 'test7' ] FOR c IN " + cn + " FILTER c.code IN parents SORT c.code RETURN c.code"; + var query = "LET parents = [ 'test5', 'test7' ] FOR c IN " + cn2 + " FILTER c.code IN parents SORT c.code RETURN c.code"; var actual = getQueryResults(query); assertEqual(expected, actual); @@ -184,14 +195,8 @@ function ahuacatlQueryOptimizerInTestSuite () { //////////////////////////////////////////////////////////////////////////////// testInHashDynamic : function () { - c.save({ code: "test0" }); - for (var i = 1; i < 100; ++i) { - c.save({ code: "test" + i, parent: "test" + (i - 1), parents: [ "test" + (i - 1) ] }); - } - c.ensureUniqueConstraint("code"); - var expected = [ 'test5', 'test7' ]; - var query = "LET parents = (FOR c IN " + cn + " FILTER c.code IN [ 'test5', 'test7' ] RETURN c.code) FOR c IN " + cn + " FILTER c.code IN parents SORT c.code RETURN c.code"; + var query = "LET parents = (FOR c IN " + cn2 + " FILTER c.code IN [ 'test5', 'test7' ] RETURN c.code) FOR c IN " + cn2 + " FILTER c.code IN parents SORT c.code RETURN c.code"; var actual = getQueryResults(query); assertEqual(expected, actual); @@ -203,14 +208,8 @@ function ahuacatlQueryOptimizerInTestSuite () { //////////////////////////////////////////////////////////////////////////////// testInHashDynamicRef : function () { - c.save({ code: "test0" }); - for (var i = 1; i < 100; ++i) { - c.save({ code: "test" + i, parent: "test" + (i - 1), parents: [ "test" + (i - 1) ] }); - } - c.ensureUniqueConstraint("code"); - var expected = [ { keys: [ 'test4' ] }, { keys: [ 'test6' ] } ]; - var actual = getQueryResults("FOR c IN " + cn + " FILTER c.code IN [ 'test5', 'test7' ] SORT c.code RETURN { keys: (FOR c2 IN " + cn + " FILTER c2.code IN [ c.parent ] RETURN c2.code) }"); + var actual = getQueryResults("FOR c IN " + cn2 + " FILTER c.code IN [ 'test5', 'test7' ] SORT c.code RETURN { keys: (FOR c2 IN " + cn2 + " FILTER c2.code IN [ c.parent ] RETURN c2.code) }"); assertEqual(expected, actual); }, @@ -219,14 +218,8 @@ function ahuacatlQueryOptimizerInTestSuite () { //////////////////////////////////////////////////////////////////////////////// testInHashRef : function () { - c.save({ code: "test0" }); - for (var i = 1; i < 100; ++i) { - c.save({ code: "test" + i, parent: "test" + (i - 1), parents: [ "test" + (i - 1) ] }); - } - c.ensureUniqueConstraint("code"); - var expected = [ { keys: [ 'test4' ] }, { keys: [ 'test6' ] } ]; - var actual = getQueryResults("FOR c IN " + cn + " FILTER c.code IN [ 'test5', 'test7' ] SORT c.code RETURN { keys: (FOR c2 IN " + cn + " FILTER c2.code IN c.parents SORT c2.code RETURN c2.code) }"); + var actual = getQueryResults("FOR c IN " + cn2 + " FILTER c.code IN [ 'test5', 'test7' ] SORT c.code RETURN { keys: (FOR c2 IN " + cn2 + " FILTER c2.code IN c.parents SORT c2.code RETURN c2.code) }"); assertEqual(expected, actual); }, @@ -235,14 +228,8 @@ function ahuacatlQueryOptimizerInTestSuite () { //////////////////////////////////////////////////////////////////////////////// testInSkipConst : function () { - c.save({ code: "test0" }); - for (var i = 1; i < 100; ++i) { - c.save({ code: "test" + i, parent: "test" + (i - 1), parents: [ "test" + (i - 1) ] }); - } - c.ensureUniqueSkiplist("code"); - var expected = [ 'test5', 'test7' ]; - var query = "LET parents = [ 'test5', 'test7' ] FOR c IN " + cn + " FILTER c.code IN parents SORT c.code RETURN c.code"; + var query = "LET parents = [ 'test5', 'test7' ] FOR c IN " + cn3 + " FILTER c.code IN parents SORT c.code RETURN c.code"; var actual = getQueryResults(query); assertEqual(expected, actual); @@ -254,14 +241,8 @@ function ahuacatlQueryOptimizerInTestSuite () { //////////////////////////////////////////////////////////////////////////////// testInSkipDynamic : function () { - c.save({ code: "test0" }); - for (var i = 1; i < 100; ++i) { - c.save({ code: "test" + i, parent: "test" + (i - 1), parents: [ "test" + (i - 1) ] }); - } - c.ensureUniqueSkiplist("code"); - var expected = [ 'test5', 'test7' ]; - var query = "LET parents = (FOR c IN " + cn + " FILTER c.code IN [ 'test5', 'test7' ] RETURN c.code) FOR c IN " + cn + " FILTER c.code IN parents SORT c.code RETURN c.code"; + var query = "LET parents = (FOR c IN " + cn3 + " FILTER c.code IN [ 'test5', 'test7' ] RETURN c.code) FOR c IN " + cn3 + " FILTER c.code IN parents SORT c.code RETURN c.code"; var actual = getQueryResults(query); assertEqual(expected, actual); @@ -273,14 +254,8 @@ function ahuacatlQueryOptimizerInTestSuite () { //////////////////////////////////////////////////////////////////////////////// testInSkipDynamicRef : function () { - c.save({ code: "test0" }); - for (var i = 1; i < 100; ++i) { - c.save({ code: "test" + i, parent: "test" + (i - 1), parents: [ "test" + (i - 1) ] }); - } - c.ensureUniqueSkiplist("code"); - var expected = [ { keys: [ 'test4' ] }, { keys: [ 'test6' ] } ]; - var actual = getQueryResults("FOR c IN " + cn + " FILTER c.code IN [ 'test5', 'test7' ] SORT c.code RETURN { keys: (FOR c2 IN " + cn + " FILTER c2.code IN [ c.parent ] RETURN c2.code) }"); + var actual = getQueryResults("FOR c IN " + cn3 + " FILTER c.code IN [ 'test5', 'test7' ] SORT c.code RETURN { keys: (FOR c2 IN " + cn3 + " FILTER c2.code IN [ c.parent ] RETURN c2.code) }"); assertEqual(expected, actual); }, @@ -289,14 +264,8 @@ function ahuacatlQueryOptimizerInTestSuite () { //////////////////////////////////////////////////////////////////////////////// testInSkipRef : function () { - c.save({ code: "test0" }); - for (var i = 1; i < 100; ++i) { - c.save({ code: "test" + i, parent: "test" + (i - 1), parents: [ "test" + (i - 1) ] }); - } - c.ensureUniqueSkiplist("code"); - var expected = [ { keys: [ 'test4' ] }, { keys: [ 'test6' ] } ]; - var actual = getQueryResults("FOR c IN " + cn + " FILTER c.code IN [ 'test5', 'test7' ] SORT c.code RETURN { keys: (FOR c2 IN " + cn + " FILTER c2.code IN c.parents SORT c2.code RETURN c2.code) }"); + var actual = getQueryResults("FOR c IN " + cn3 + " FILTER c.code IN [ 'test5', 'test7' ] SORT c.code RETURN { keys: (FOR c2 IN " + cn3 + " FILTER c2.code IN c.parents SORT c2.code RETURN c2.code) }"); assertEqual(expected, actual); }, @@ -305,28 +274,12 @@ function ahuacatlQueryOptimizerInTestSuite () { //////////////////////////////////////////////////////////////////////////////// testInEdgeConst : function () { - var i; - c.save({ _key: "test0" }); - for (i = 1; i < 100; ++i) { - c.save({ _key: "test" + i }); - } - - var en = cn + "Edge"; - internal.db._drop(en); - var e = internal.db._createEdgeCollection(en); - - for (i = 1; i < 100; ++i) { - e.save(cn + "/test" + i, cn + "/test" + (i - 1), { }); - } - var expected = [ cn + '/test4', cn + '/test6' ]; var query = "LET parents = [ '" + cn + "/test5', '" + cn + "/test7' ] FOR c IN " + en + " FILTER c._from IN parents SORT c._to RETURN c._to"; var actual = getQueryResults(query); assertEqual(expected, actual); assertEqual([ "SingletonNode", "CalculationNode", "ScatterNode", "RemoteNode", "IndexNode", "RemoteNode", "GatherNode", "CalculationNode", "FilterNode", "CalculationNode", "SortNode", "CalculationNode", "ReturnNode" ], explain(query)); - - internal.db._drop(en); }, //////////////////////////////////////////////////////////////////////////////// @@ -334,28 +287,12 @@ function ahuacatlQueryOptimizerInTestSuite () { //////////////////////////////////////////////////////////////////////////////// testInEdgeDynamic : function () { - var i; - c.save({ _key: "test0" }); - for (i = 1; i < 100; ++i) { - c.save({ _key: "test" + i }); - } - - var en = cn + "Edge"; - internal.db._drop(en); - var e = internal.db._createEdgeCollection(en); - - for (i = 1; i < 100; ++i) { - e.save(cn + "/test" + i, cn + "/test" + (i - 1), { }); - } - var expected = [ cn + '/test4', cn + '/test6' ]; var query = "LET parents = (FOR c IN " + cn + " FILTER c._key IN [ 'test5', 'test7' ] RETURN c._id) FOR c IN " + en + " FILTER c._from IN parents SORT c._to RETURN c._to"; var actual = getQueryResults(query); assertEqual(expected, actual); assertEqual([ "SingletonNode", "SubqueryNode", "ScatterNode", "RemoteNode", "IndexNode", "RemoteNode", "GatherNode", "CalculationNode", "FilterNode", "CalculationNode", "SortNode", "CalculationNode", "ReturnNode" ], explain(query)); - - internal.db._drop(en); }, //////////////////////////////////////////////////////////////////////////////// @@ -363,25 +300,9 @@ function ahuacatlQueryOptimizerInTestSuite () { //////////////////////////////////////////////////////////////////////////////// testInEdgeDynamicRef : function () { - var i; - c.save({ _key: "test0" }); - for (i = 1; i < 100; ++i) { - c.save({ _key: "test" + i }); - } - - var en = cn + "Edge"; - internal.db._drop(en); - var e = internal.db._createEdgeCollection(en); - - for (i = 1; i < 100; ++i) { - e.save(cn + "/test" + i, cn + "/test" + (i - 1), { }); - } - var expected = [ { keys: [ cn + '/test4' ] }, { keys: [ cn + '/test6' ] } ]; var actual = getQueryResults("FOR c IN " + cn + " FILTER c._key IN [ 'test5', 'test7' ] SORT c._key RETURN { keys: (FOR c2 IN " + en + " FILTER c2._from IN [ c._id ] RETURN c2._to) }"); assertEqual(expected, actual); - - internal.db._drop(en); }, //////////////////////////////////////////////////////////////////////////////// @@ -389,25 +310,9 @@ function ahuacatlQueryOptimizerInTestSuite () { //////////////////////////////////////////////////////////////////////////////// testInEdgeRef : function () { - var i; - c.save({ _key: "test0" }); - for (i = 1; i < 100; ++i) { - c.save({ _key: "test" + i, ids: [ cn + "/test" + i ] }); - } - - var en = cn + "Edge"; - internal.db._drop(en); - var e = internal.db._createEdgeCollection(en); - - for (i = 1; i < 100; ++i) { - e.save(cn + "/test" + i, cn + "/test" + (i - 1), { }); - } - var expected = [ { keys: [ cn + '/test4' ] }, { keys: [ cn + '/test6' ] } ]; var actual = getQueryResults("FOR c IN " + cn + " FILTER c._key IN [ 'test5', 'test7' ] SORT c._key RETURN { keys: (FOR c2 IN " + en + " FILTER c2._from IN c.ids RETURN c2._to) }"); assertEqual(expected, actual); - - internal.db._drop(en); }, //////////////////////////////////////////////////////////////////////////////// @@ -500,6 +405,8 @@ function ahuacatlQueryOptimizerInTestSuite () { //////////////////////////////////////////////////////////////////////////////// testValidIn : function () { + internal.db._drop(cn4); + c = internal.db._create(cn4); c.save({ value: "red" }); c.save({ value: "green" }); c.save({ value: "blue" }); @@ -507,60 +414,60 @@ function ahuacatlQueryOptimizerInTestSuite () { c.save({ value: false }); c.save({ value: null }); - var actual = getQueryResults("FOR i IN " + cn + " FILTER i.value IN [ 'red', 'green' ] SORT i.value RETURN i.value"); + var actual = getQueryResults("FOR i IN " + cn4 + " FILTER i.value IN [ 'red', 'green' ] SORT i.value RETURN i.value"); assertEqual([ "green", "red" ], actual); - actual = getQueryResults("FOR i IN " + cn + " FILTER i.value NOT IN [ 'red', 'green' ] SORT i.value RETURN i.value"); + actual = getQueryResults("FOR i IN " + cn4 + " FILTER i.value NOT IN [ 'red', 'green' ] SORT i.value RETURN i.value"); assertEqual([ null, false, 12, "blue" ], actual); - actual = getQueryResults("FOR i IN " + cn + " FILTER i.value IN [ 'green', 'blue' ] SORT i.value RETURN i.value"); + actual = getQueryResults("FOR i IN " + cn4 + " FILTER i.value IN [ 'green', 'blue' ] SORT i.value RETURN i.value"); assertEqual([ "blue", "green" ], actual); - actual = getQueryResults("FOR i IN " + cn + " FILTER i.value NOT IN [ 'green', 'blue' ] SORT i.value RETURN i.value"); + actual = getQueryResults("FOR i IN " + cn4 + " FILTER i.value NOT IN [ 'green', 'blue' ] SORT i.value RETURN i.value"); assertEqual([ null, false, 12, "red" ], actual); - actual = getQueryResults("FOR i IN " + cn + " FILTER i.value IN [ 'foo', 'bar' ] SORT i.value RETURN i.value"); + actual = getQueryResults("FOR i IN " + cn4 + " FILTER i.value IN [ 'foo', 'bar' ] SORT i.value RETURN i.value"); assertEqual([ ], actual); - actual = getQueryResults("FOR i IN " + cn + " FILTER i.value NOT IN [ 'foo', 'bar' ] SORT i.value RETURN i.value"); + actual = getQueryResults("FOR i IN " + cn4 + " FILTER i.value NOT IN [ 'foo', 'bar' ] SORT i.value RETURN i.value"); assertEqual([ null, false, 12, "blue", "green", "red" ], actual); - actual = getQueryResults("FOR i IN " + cn + " FILTER i.value IN [ 12, false ] SORT i.value RETURN i.value"); + actual = getQueryResults("FOR i IN " + cn4 + " FILTER i.value IN [ 12, false ] SORT i.value RETURN i.value"); assertEqual([ false, 12 ], actual); - actual = getQueryResults("FOR i IN " + cn + " FILTER i.value NOT IN [ 12, false ] SORT i.value RETURN i.value"); + actual = getQueryResults("FOR i IN " + cn4 + " FILTER i.value NOT IN [ 12, false ] SORT i.value RETURN i.value"); assertEqual([ null, "blue", "green", "red" ], actual); - actual = getQueryResults("FOR i IN " + cn + " FILTER i.value IN [ 23, 'black', 'red', null ] SORT i.value RETURN i.value"); + actual = getQueryResults("FOR i IN " + cn4 + " FILTER i.value IN [ 23, 'black', 'red', null ] SORT i.value RETURN i.value"); assertEqual([ null, 'red' ], actual); - actual = getQueryResults("FOR i IN " + cn + " FILTER i.value NOT IN [ 23, 'black', 'red', null ] SORT i.value RETURN i.value"); + actual = getQueryResults("FOR i IN " + cn4 + " FILTER i.value NOT IN [ 23, 'black', 'red', null ] SORT i.value RETURN i.value"); assertEqual([ false, 12, "blue", "green" ], actual); c.truncate(); c.save({ value: [ 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, "red", "blue" ]}); - actual = getQueryResults("FOR i IN " + cn + " FILTER 12 IN i.value SORT i.value RETURN LENGTH(i.value)"); + actual = getQueryResults("FOR i IN " + cn4 + " FILTER 12 IN i.value SORT i.value RETURN LENGTH(i.value)"); assertEqual([ 14 ], actual); - actual = getQueryResults("FOR i IN " + cn + " FILTER 99 NOT IN i.value SORT i.value RETURN LENGTH(i.value)"); + actual = getQueryResults("FOR i IN " + cn4 + " FILTER 99 NOT IN i.value SORT i.value RETURN LENGTH(i.value)"); assertEqual([ 14 ], actual); - actual = getQueryResults("FOR i IN " + cn + " FILTER 12 NOT IN i.value SORT i.value RETURN LENGTH(i.value)"); + actual = getQueryResults("FOR i IN " + cn4 + " FILTER 12 NOT IN i.value SORT i.value RETURN LENGTH(i.value)"); assertEqual([ ], actual); - actual = getQueryResults("FOR i IN " + cn + " FILTER 13 IN i.value SORT i.value RETURN LENGTH(i.value)"); + actual = getQueryResults("FOR i IN " + cn4 + " FILTER 13 IN i.value SORT i.value RETURN LENGTH(i.value)"); assertEqual([ ], actual); - actual = getQueryResults("FOR i IN " + cn + " FILTER 13 NOT IN i.value SORT i.value RETURN LENGTH(i.value)"); + actual = getQueryResults("FOR i IN " + cn4 + " FILTER 13 NOT IN i.value SORT i.value RETURN LENGTH(i.value)"); assertEqual([ 14 ], actual); - actual = getQueryResults("FOR i IN " + cn + " FILTER 'red' IN i.value SORT i.value RETURN LENGTH(i.value)"); + actual = getQueryResults("FOR i IN " + cn4 + " FILTER 'red' IN i.value SORT i.value RETURN LENGTH(i.value)"); assertEqual([ 14 ], actual); - actual = getQueryResults("FOR i IN " + cn + " FILTER 'red' NOT IN i.value SORT i.value RETURN LENGTH(i.value)"); + actual = getQueryResults("FOR i IN " + cn4 + " FILTER 'red' NOT IN i.value SORT i.value RETURN LENGTH(i.value)"); assertEqual([ ], actual); - actual = getQueryResults("FOR i IN " + cn + " FILTER 'fuchsia' NOT IN i.value SORT i.value RETURN LENGTH(i.value)"); + actual = getQueryResults("FOR i IN " + cn4 + " FILTER 'fuchsia' NOT IN i.value SORT i.value RETURN LENGTH(i.value)"); assertEqual([ 14 ], actual); }, diff --git a/tests/js/server/aql/aql-queries-optimizer-limit-cluster.js b/tests/js/server/aql/aql-queries-optimizer-limit-cluster.js index fbd0c51608..f73ca97040 100644 --- a/tests/js/server/aql/aql-queries-optimizer-limit-cluster.js +++ b/tests/js/server/aql/aql-queries-optimizer-limit-cluster.js @@ -40,6 +40,7 @@ var getQueryResults = helper.getQueryResults; function ahuacatlQueryOptimizerLimitTestSuite () { var collection = null; + var idx = null; var cn = "UnitTestsAhuacatlOptimizerLimit"; var explain = function (query) { @@ -52,23 +53,32 @@ function ahuacatlQueryOptimizerLimitTestSuite () { /// @brief set up //////////////////////////////////////////////////////////////////////////////// - setUp : function () { + setUpAll : function () { internal.db._drop(cn); collection = internal.db._create(cn); + let docs = []; for (var i = 0; i < 100; ++i) { - collection.save({ "value" : i }); + docs.push({ "value" : i }); } + collection.insert(docs); }, //////////////////////////////////////////////////////////////////////////////// /// @brief tear down //////////////////////////////////////////////////////////////////////////////// - tearDown : function () { + tearDownAll : function () { internal.db._drop(cn); }, + tearDown: function () { + if (idx !== null) { + internal.db._dropIndex(idx); + } + idx = null; + }, + //////////////////////////////////////////////////////////////////////////////// /// @brief check limit optimization for non-collection access, limit > 0 //////////////////////////////////////////////////////////////////////////////// @@ -445,7 +455,7 @@ function ahuacatlQueryOptimizerLimitTestSuite () { //////////////////////////////////////////////////////////////////////////////// testLimitFullCollectionHashIndex1 : function () { - collection.ensureHashIndex("value"); + idx = collection.ensureHashIndex("value"); var query = "FOR c IN " + cn + " FILTER c.value == 23 || c.value == 24 LIMIT 0, 10 SORT c.value RETURN c"; @@ -462,7 +472,7 @@ function ahuacatlQueryOptimizerLimitTestSuite () { //////////////////////////////////////////////////////////////////////////////// testLimitFullCollectionHashIndex2 : function () { - collection.ensureHashIndex("value"); + idx = collection.ensureHashIndex("value"); var query = "FOR c IN " + cn + " FILTER c.value >= 20 && c.value < 30 LIMIT 0, 10 SORT c.value RETURN c"; @@ -485,7 +495,7 @@ function ahuacatlQueryOptimizerLimitTestSuite () { //////////////////////////////////////////////////////////////////////////////// testLimitFilterFilterCollectionHashIndex : function () { - collection.ensureHashIndex("value"); + idx = collection.ensureHashIndex("value"); var query = "FOR c IN " + cn + " FILTER c.value >= 20 && c.value < 30 FILTER c.value <= 9999 LIMIT 0, 10 SORT c.value RETURN c"; @@ -508,7 +518,7 @@ function ahuacatlQueryOptimizerLimitTestSuite () { //////////////////////////////////////////////////////////////////////////////// testLimitFullCollectionSkiplistIndex1 : function () { - collection.ensureSkiplist("value"); + idx = collection.ensureSkiplist("value"); var query = "FOR c IN " + cn + " FILTER c.value == 23 || c.value == 24 LIMIT 0, 10 SORT c.value RETURN c"; @@ -525,7 +535,7 @@ function ahuacatlQueryOptimizerLimitTestSuite () { //////////////////////////////////////////////////////////////////////////////// testLimitFullCollectionSkiplistIndex2 : function () { - collection.ensureSkiplist("value"); + idx = collection.ensureSkiplist("value"); var query = "FOR c IN " + cn + " FILTER c.value >= 20 && c.value < 30 LIMIT 0, 10 SORT c.value RETURN c"; @@ -543,8 +553,7 @@ function ahuacatlQueryOptimizerLimitTestSuite () { //////////////////////////////////////////////////////////////////////////////// testLimitFilterFilterSkiplistIndex : function () { - collection.ensureSkiplist("value"); - + idx = collection.ensureSkiplist("value"); var query = "FOR c IN " + cn + " FILTER c.value >= 20 && c.value < 30 FILTER c.value <= 9999 LIMIT 0, 10 SORT c.value RETURN c"; var actual = getQueryResults(query); diff --git a/tests/js/server/aql/aql-queries-optimizer-ref-cluster.js b/tests/js/server/aql/aql-queries-optimizer-ref-cluster.js index 1ea68000b9..98bba2a238 100644 --- a/tests/js/server/aql/aql-queries-optimizer-ref-cluster.js +++ b/tests/js/server/aql/aql-queries-optimizer-ref-cluster.js @@ -51,26 +51,28 @@ function ahuacatlQueryOptimizerRefTestSuite () { /// @brief set up //////////////////////////////////////////////////////////////////////////////// - setUp : function () { + setUpAll : function () { internal.db._drop(cn); users = internal.db._create(cn); - users.save({ "id" : 100, "name" : "John", "age" : 37, "active" : true, "gender" : "m" }); - users.save({ "id" : 101, "name" : "Fred", "age" : 36, "active" : true, "gender" : "m" }); - users.save({ "id" : 102, "name" : "Jacob", "age" : 35, "active" : false, "gender" : "m" }); - users.save({ "id" : 103, "name" : "Ethan", "age" : 34, "active" : false, "gender" : "m" }); - users.save({ "id" : 104, "name" : "Michael", "age" : 33, "active" : true, "gender" : "m" }); - users.save({ "id" : 105, "name" : "Alexander", "age" : 32, "active" : true, "gender" : "m" }); - users.save({ "id" : 106, "name" : "Daniel", "age" : 31, "active" : true, "gender" : "m" }); - users.save({ "id" : 107, "name" : "Anthony", "age" : 30, "active" : true, "gender" : "m" }); - users.save({ "id" : 108, "name" : "Jim", "age" : 29, "active" : true, "gender" : "m" }); - users.save({ "id" : 109, "name" : "Diego", "age" : 28, "active" : true, "gender" : "m" }); + users.insert([ + { "id" : 100, "name" : "John", "age" : 37, "active" : true, "gender" : "m" }, + { "id" : 101, "name" : "Fred", "age" : 36, "active" : true, "gender" : "m" }, + { "id" : 102, "name" : "Jacob", "age" : 35, "active" : false, "gender" : "m" }, + { "id" : 103, "name" : "Ethan", "age" : 34, "active" : false, "gender" : "m" }, + { "id" : 104, "name" : "Michael", "age" : 33, "active" : true, "gender" : "m" }, + { "id" : 105, "name" : "Alexander", "age" : 32, "active" : true, "gender" : "m" }, + { "id" : 106, "name" : "Daniel", "age" : 31, "active" : true, "gender" : "m" }, + { "id" : 107, "name" : "Anthony", "age" : 30, "active" : true, "gender" : "m" }, + { "id" : 108, "name" : "Jim", "age" : 29, "active" : true, "gender" : "m" }, + { "id" : 109, "name" : "Diego", "age" : 28, "active" : true, "gender" : "m" }, + ]); }, //////////////////////////////////////////////////////////////////////////////// /// @brief tear down //////////////////////////////////////////////////////////////////////////////// - tearDown : function () { + tearDownAll : function () { internal.db._drop(cn); }, diff --git a/tests/js/server/aql/aql-queries-optimizer-sort-cluster.js b/tests/js/server/aql/aql-queries-optimizer-sort-cluster.js index 1075baa1e1..ffa6e39871 100644 --- a/tests/js/server/aql/aql-queries-optimizer-sort-cluster.js +++ b/tests/js/server/aql/aql-queries-optimizer-sort-cluster.js @@ -34,6 +34,7 @@ var helper = require("@arangodb/aql-helper"); var isEqual = helper.isEqual; var findExecutionNodes = helper.findExecutionNodes; var getQueryResults = helper.getQueryResults; +var db = require("internal").db; //////////////////////////////////////////////////////////////////////////////// /// @brief test suite @@ -42,7 +43,8 @@ var getQueryResults = helper.getQueryResults; function ahuacatlQueryOptimizerSortTestSuite () { var collection = null; var cn = "UnitTestsAhuacatlOptimizerSort"; - + var idx = null; + var explain = function (query, params) { return helper.getCompactPlan(AQL_EXPLAIN(query, params, { optimizer: { rules: [ "-all", "+use-index-for-sort", "+use-indexes", "+remove-redundant-sorts" ] } })).map(function(node) { return node.type; }); }; @@ -53,23 +55,36 @@ function ahuacatlQueryOptimizerSortTestSuite () { /// @brief set up //////////////////////////////////////////////////////////////////////////////// - setUp : function () { + setUpAll : function () { internal.db._drop(cn); collection = internal.db._create(cn); + let docs = []; for (var i = 0; i < 100; ++i) { - collection.save({ "value" : i, "value2" : i }); + docs.push({ "value" : i, "value2" : i }); } + collection.insert(docs); + }, + + setUp: function() { + var idx = null; }, //////////////////////////////////////////////////////////////////////////////// /// @brief tear down //////////////////////////////////////////////////////////////////////////////// - tearDown : function () { + tearDownAll : function () { internal.db._drop(cn); }, + tearDown: function() { + if (idx != null) { + db._dropIndex(idx); + idx = null; + } + }, + //////////////////////////////////////////////////////////////////////////////// /// @brief check sort optimization without index //////////////////////////////////////////////////////////////////////////////// @@ -133,7 +148,7 @@ function ahuacatlQueryOptimizerSortTestSuite () { //////////////////////////////////////////////////////////////////////////////// testSkiplist1 : function () { - collection.ensureSkiplist("value"); + idx = collection.ensureSkiplist("value"); var query = "FOR c IN " + cn + " SORT c.value RETURN c"; @@ -163,7 +178,7 @@ function ahuacatlQueryOptimizerSortTestSuite () { //////////////////////////////////////////////////////////////////////////////// testSkiplist2 : function () { - collection.ensureSkiplist("value"); + idx = collection.ensureSkiplist("value"); var query = "FOR c IN " + cn + " FILTER c.value >= 15 SORT c.value RETURN c"; @@ -194,7 +209,7 @@ function ahuacatlQueryOptimizerSortTestSuite () { //////////////////////////////////////////////////////////////////////////////// testSkiplist3 : function () { - collection.ensureSkiplist("value"); + idx = collection.ensureSkiplist("value"); var query = "FOR c IN " + cn + " FILTER c.value >= 15 SORT c.value DESC RETURN c"; @@ -225,7 +240,7 @@ function ahuacatlQueryOptimizerSortTestSuite () { //////////////////////////////////////////////////////////////////////////////// testMultipleSorts1 : function () { - collection.ensureSkiplist("value"); + idx = collection.ensureSkiplist("value"); var query = "FOR c IN " + cn + " FILTER c.value >= 0 SORT c.value SORT c.value RETURN c"; @@ -258,7 +273,7 @@ function ahuacatlQueryOptimizerSortTestSuite () { //////////////////////////////////////////////////////////////////////////////// testMultipleSorts2 : function () { - collection.ensureSkiplist("value"); + idx = collection.ensureSkiplist("value"); var query = "FOR c IN " + cn + " FILTER c.value >= 0 SORT c.value SORT c.value DESC RETURN c"; @@ -291,7 +306,7 @@ function ahuacatlQueryOptimizerSortTestSuite () { //////////////////////////////////////////////////////////////////////////////// testMultipleSorts3 : function () { - collection.ensureSkiplist("value"); + idx = collection.ensureSkiplist("value"); var query = "FOR c IN " + cn + " FILTER c.value >= 0 SORT c.value DESC SORT c.value RETURN c"; @@ -324,7 +339,7 @@ function ahuacatlQueryOptimizerSortTestSuite () { //////////////////////////////////////////////////////////////////////////////// testMultipleFields1 : function () { - collection.ensureSkiplist("value", "value2"); + idx = collection.ensureSkiplist("value", "value2"); var query = "FOR c IN " + cn + " FILTER c.value >= 0 SORT c.value RETURN c"; @@ -374,7 +389,7 @@ function ahuacatlQueryOptimizerSortTestSuite () { //////////////////////////////////////////////////////////////////////////////// testMultipleFields2 : function () { - collection.ensureSkiplist("value", "value2"); + idx = collection.ensureSkiplist("value", "value2"); var query = "FOR c IN " + cn + " FILTER c.value >= 0 SORT c.value, c.value2 RETURN c"; @@ -426,7 +441,7 @@ function ahuacatlQueryOptimizerSortTestSuite () { //////////////////////////////////////////////////////////////////////////////// testMultipleFields3 : function () { - collection.ensureSkiplist("value", "value2"); + idx = collection.ensureSkiplist("value", "value2"); var query = "FOR c IN " + cn + " FILTER c.value2 >= 0 SORT c.value RETURN c"; @@ -458,7 +473,7 @@ function ahuacatlQueryOptimizerSortTestSuite () { //////////////////////////////////////////////////////////////////////////////// testMultipleFields4 : function () { - collection.ensureSkiplist("value", "value2"); + idx = collection.ensureSkiplist("value", "value2"); var query = "FOR c IN " + cn + " FILTER c.value >= 0 && c.value2 >= 0 SORT c.value RETURN c"; @@ -490,7 +505,7 @@ function ahuacatlQueryOptimizerSortTestSuite () { //////////////////////////////////////////////////////////////////////////////// testMultipleFields5 : function () { - collection.ensureSkiplist("value2", "value"); + idx = collection.ensureSkiplist("value2", "value"); var query = "FOR c IN " + cn + " FILTER c.value >= 0 SORT c.value RETURN c"; @@ -523,7 +538,7 @@ function ahuacatlQueryOptimizerSortTestSuite () { //////////////////////////////////////////////////////////////////////////////// testNonFieldSort1 : function () { - collection.ensureSkiplist("value"); + idx = collection.ensureSkiplist("value"); var query = "FOR c IN " + cn + " FILTER c.value >= 0 SORT c.value + 1 RETURN c"; @@ -556,7 +571,7 @@ function ahuacatlQueryOptimizerSortTestSuite () { //////////////////////////////////////////////////////////////////////////////// testNonFieldSort2 : function () { - collection.ensureSkiplist("value"); + idx = collection.ensureSkiplist("value"); var query = "FOR c IN " + cn + " FILTER c.value >= 0 SORT 1 + c.value RETURN c"; @@ -589,7 +604,7 @@ function ahuacatlQueryOptimizerSortTestSuite () { //////////////////////////////////////////////////////////////////////////////// testNonFieldSort3 : function () { - collection.ensureSkiplist("value"); + idx = collection.ensureSkiplist("value"); var query = "FOR c IN " + cn + " FILTER c.value >= 0 SORT c.value * 2 RETURN c"; @@ -637,13 +652,15 @@ function sortTestsuite () { /// @brief set up //////////////////////////////////////////////////////////////////////////////// - setUp : function () { + setUpAll : function () { internal.db._drop(cn); collection = internal.db._create(cn, { numberOfShards : 9 }); + let docs = []; for (var i = 0; i < testStrings.length; i++) { - collection.save({ "value" : i, "testString" : testStrings[i] }); + docs.push({ "value" : i, "testString" : testStrings[i] }); } + collection.insert(docs); testStringsSorted=AQL_EXECUTE("FOR t IN @bla SORT t RETURN t", {"bla": testStrings}).json; @@ -653,7 +670,7 @@ function sortTestsuite () { /// @brief tear down //////////////////////////////////////////////////////////////////////////////// - tearDown : function () { + tearDownAll : function () { internal.db._drop(cn); }, diff --git a/tests/js/server/aql/aql-queries-optimizer-sort-limit.js b/tests/js/server/aql/aql-queries-optimizer-sort-limit.js index 0b2cb6f826..337005fdc1 100644 --- a/tests/js/server/aql/aql-queries-optimizer-sort-limit.js +++ b/tests/js/server/aql/aql-queries-optimizer-sort-limit.js @@ -56,9 +56,11 @@ function ahuacatlQueryOptimizerLimitTestSuite () { internal.db._drop(cn); collection = internal.db._create(cn, {numberOfShards: 9}); + let docs = []; for (var i = 0; i < docCount; ++i) { - collection.save({ _key: "test" + i, value : i }); + docs.push({ _key: "test" + i, value : i }); } + collection.insert(docs); }, //////////////////////////////////////////////////////////////////////////////// diff --git a/tests/js/server/aql/aql-refaccess-attribute.js b/tests/js/server/aql/aql-refaccess-attribute.js index 05ef45dfc0..e7e32d8ea7 100644 --- a/tests/js/server/aql/aql-refaccess-attribute.js +++ b/tests/js/server/aql/aql-refaccess-attribute.js @@ -58,9 +58,11 @@ function ahuacatlRefAccessAttributeTestSuite () { internal.db._drop("UnitTestsAhuacatlRefAccess"); collection = internal.db._create("UnitTestsAhuacatlRefAccess"); + let docs = []; for (var i = 1; i <= 10; ++i) { - collection.save({ "val" : i }); + docs.push({ "val" : i }); } + collection.insert(docs); collection.ensureSkiplist("val"); }, diff --git a/tests/js/server/aql/aql-regex.js b/tests/js/server/aql/aql-regex.js index f00135bc5e..ea4386bfee 100644 --- a/tests/js/server/aql/aql-regex.js +++ b/tests/js/server/aql/aql-regex.js @@ -48,10 +48,12 @@ function ahuacatlRegexTestSuite () { setUpAll : function () { db._drop("UnitTestsAhuacatlRegex"); c = db._create("UnitTestsAhuacatlRegex"); - + + let docs = []; for (var i = 0; i < 1000; ++i) { - c.insert({ _key: "test" + i }); + docs.push({ _key: "test" + i }); } + c.insert(docs); }, //////////////////////////////////////////////////////////////////////////////// diff --git a/tests/js/server/aql/aql-shardids-cluster.js b/tests/js/server/aql/aql-shardids-cluster.js index b1a4fd2a9d..f582422dfd 100644 --- a/tests/js/server/aql/aql-shardids-cluster.js +++ b/tests/js/server/aql/aql-shardids-cluster.js @@ -60,9 +60,11 @@ function ahuacatlShardIdsTestSuite () { internal.db._drop(cn); collection = internal.db._create(cn, { numberOfShards: 4 }); + let docs = []; for (var i = 0; i < 100; ++i) { - collection.save({ "value" : i }); + docs.push({ "value" : i }); } + collection.insert(docs); var result = collection.count(true); var sum = 0; @@ -171,7 +173,7 @@ function ahuacatlShardIdsOptimizationTestSuite() { /// @brief set up //////////////////////////////////////////////////////////////////////////////// - setUp : function () { + setUpAll : function () { tearDown(); collection = internal.db._create(cn, { numberOfShards }); collectionByKey = internal.db._create( @@ -216,11 +218,9 @@ function ahuacatlShardIdsOptimizationTestSuite() { assertEqual(100, sum); }, -//////////////////////////////////////////////////////////////////////////////// -/// @brief tear down -//////////////////////////////////////////////////////////////////////////////// - - tearDown, + tearDownAll() { + tearDown(); + }, //////////////////////////////////////////////////////////////////////////////// /// @brief no restriction to a shard diff --git a/tests/js/server/aql/aql-skiplist-cluster.js b/tests/js/server/aql/aql-skiplist-cluster.js index b724ab6293..302b6d9101 100644 --- a/tests/js/server/aql/aql-skiplist-cluster.js +++ b/tests/js/server/aql/aql-skiplist-cluster.js @@ -54,11 +54,13 @@ function ahuacatlSkiplistTestSuite () { internal.db._drop("UnitTestsAhuacatlSkiplist"); skiplist = internal.db._create("UnitTestsAhuacatlSkiplist"); + let docs = []; for (var i = 1; i <= 5; ++i) { for (var j = 1; j <= 5; ++j) { - skiplist.save({ "a" : i, "b": j }); + docs.push({ "a" : i, "b": j }); } } + skiplist.insert(docs); skiplist.ensureSkiplist("a", "b"); }, diff --git a/tests/js/server/aql/aql-skiplist.js b/tests/js/server/aql/aql-skiplist.js index 4579f9cbe2..a027c8c9d4 100644 --- a/tests/js/server/aql/aql-skiplist.js +++ b/tests/js/server/aql/aql-skiplist.js @@ -52,9 +52,11 @@ function ahuacatlSkiplistOverlappingTestSuite () { skiplist = internal.db._create("UnitTestsAhuacatlSkiplist"); skiplist.ensureSkiplist("a"); + let docs = []; for (var i = 0; i < 10000; ++i) { - skiplist.save({a: i}); + docs.push({a: i}); } + skiplist.insert(docs); }, tearDown : function () { diff --git a/tests/js/server/aql/aql-skipping.js b/tests/js/server/aql/aql-skipping.js index 064c503661..321e4eb836 100644 --- a/tests/js/server/aql/aql-skipping.js +++ b/tests/js/server/aql/aql-skipping.js @@ -50,9 +50,11 @@ function aqlSkippingTestsuite () { setUpAll : function () { var c = db._createDocumentCollection('skipCollection', { numberOfShards: 5 }); // c size > 1000 because of internal batchSize of 1000 + let docs = []; for (var i = 0; i < 2000; i++) { - c.save({i: i}); + docs.push({i: i}); } + c.insert(docs); }, //////////////////////////////////////////////////////////////////////////////// @@ -214,15 +216,17 @@ function aqlSkippingIndexTestsuite () { const values = _.range(7); // 0..6 // insert a total of 7^4 = 2401 documents: + let docs = []; for (const a of values) { for (const b of values) { for (const c of values) { for (const d of values) { - col.insert({a, b, c, d}); + docs.push({a, b, c, d}); } } } } + col.insert(docs); }, //////////////////////////////////////////////////////////////////////////////// @@ -485,26 +489,30 @@ function aqlSkippingIResearchTestsuite () { ac.save({ a: "foo", id : 0 }); ac.save({ a: "ba", id : 1 }); + let docs = []; + let docs2 = []; for (let i = 0; i < 5; i++) { - c.save({ a: "foo", b: "bar", c: i }); - c.save({ a: "foo", b: "baz", c: i }); - c.save({ a: "bar", b: "foo", c: i }); - c.save({ a: "baz", b: "foo", c: i }); + docs.push({ a: "foo", b: "bar", c: i }); + docs.push({ a: "foo", b: "baz", c: i }); + docs.push({ a: "bar", b: "foo", c: i }); + docs.push({ a: "baz", b: "foo", c: i }); - c2.save({ a: "foo", b: "bar", c: i }); - c2.save({ a: "bar", b: "foo", c: i }); - c2.save({ a: "baz", b: "foo", c: i }); + docs2.push({ a: "foo", b: "bar", c: i }); + docs2.push({ a: "bar", b: "foo", c: i }); + docs2.push({ a: "baz", b: "foo", c: i }); } - c.save({ name: "full", text: "the quick brown fox jumps over the lazy dog" }); - c.save({ name: "half", text: "quick fox over lazy" }); - c.save({ name: "other half", text: "the brown jumps the dog" }); - c.save({ name: "quarter", text: "quick over" }); + docs.push({ name: "full", text: "the quick brown fox jumps over the lazy dog" }); + docs.push({ name: "half", text: "quick fox over lazy" }); + docs.push({ name: "other half", text: "the brown jumps the dog" }); + docs.push({ name: "quarter", text: "quick over" }); - c.save({ name: "numeric", anotherNumericField: 0 }); - c.save({ name: "null", anotherNullField: null }); - c.save({ name: "bool", anotherBoolField: true }); - c.save({ _key: "foo", xyz: 1 }); + docs2.push({ name: "numeric", anotherNumericField: 0 }); + docs2.push({ name: "null", anotherNullField: null }); + docs2.push({ name: "bool", anotherBoolField: true }); + docs2.push({ _key: "foo", xyz: 1 }); + c.insert(docs); + c2.insert(docs2); }, //////////////////////////////////////////////////////////////////////////////// diff --git a/tests/js/server/aql/aql-sort.js b/tests/js/server/aql/aql-sort.js index 7432a96cd6..26596ff09d 100644 --- a/tests/js/server/aql/aql-sort.js +++ b/tests/js/server/aql/aql-sort.js @@ -56,16 +56,18 @@ function sortTestSuite () { var c; return { - setUp : function () { + setUpAll : function () { db._drop("UnitTestsCollection"); c = db._create("UnitTestsCollection", { numberOfShards: 8 }); + let docs = []; for (var i = 0; i < 11111; ++i) { - c.save({ _key: "test" + i, value: i }); + docs.push({ _key: "test" + i, value: i }); } + c.insert(docs); }, - tearDown : function () { + tearDownAll : function () { db._drop("UnitTestsCollection"); }, diff --git a/tests/js/server/aql/aql-sparse.js b/tests/js/server/aql/aql-sparse.js index f09ee18e70..931c86bd77 100644 --- a/tests/js/server/aql/aql-sparse.js +++ b/tests/js/server/aql/aql-sparse.js @@ -35,16 +35,18 @@ function optimizerSparseTestSuite () { let c; return { - setUp : function () { + setUpAll : function () { db._drop("UnitTestsCollection"); c = db._create("UnitTestsCollection", { numberOfShards: 5 }); + let docs = []; for (let i = 0; i < 2000; ++i) { - c.insert({ _key: "test" + i, value1: i }); + docs.push({ _key: "test" + i, value1: i }); } + c.insert(docs); }, - tearDown : function () { + tearDownAll : function () { db._drop("UnitTestsCollection"); }, diff --git a/tests/js/server/aql/aql-upsert-cluster.js b/tests/js/server/aql/aql-upsert-cluster.js index 42f2f407a8..f34393b183 100644 --- a/tests/js/server/aql/aql-upsert-cluster.js +++ b/tests/js/server/aql/aql-upsert-cluster.js @@ -58,10 +58,11 @@ function ahuacatlClusterUpsertKeySuite () { setUp : function () { db._drop(cn1); c1 = db._create(cn1, { numberOfShards: 5 }); - + let docs = []; for (var i = 0; i < 20; ++i) { - c1.save({ _key: "test" + i, value: i }); + docs.push({ _key: "test" + i, value: i }); } + c1.insert(docs); }, //////////////////////////////////////////////////////////////////////////////// @@ -170,9 +171,11 @@ function ahuacatlClusterUpsertNonKeySuite () { db._drop(cn1); c1 = db._create(cn1, { numberOfShards: 5, shardKeys: [ "value" ] }); + let docs = []; for (var i = 0; i < 20; ++i) { - c1.save({ value: i }); + docs.push({ value: i }); } + c1.insert(docs); }, //////////////////////////////////////////////////////////////////////////////// diff --git a/tests/js/server/aql/aql-vpack-externals.js b/tests/js/server/aql/aql-vpack-externals.js index 197f877bbc..290056d38f 100644 --- a/tests/js/server/aql/aql-vpack-externals.js +++ b/tests/js/server/aql/aql-vpack-externals.js @@ -39,29 +39,31 @@ function aqlVPackExternalsTestSuite () { const collName = "UnitTestsVPackExternals"; const edgeColl = "UnitTestsVPackEdges"; - const cleanUp = function () { - db._drop(collName); - db._drop(edgeColl); - }; return { - setUp: function () { - cleanUp(); + setUpAll: function () { + db._drop(collName); + db._drop(edgeColl); let coll = db._create(collName); - + let docs = []; for (let i = 1000; i < 5000; ++i) { - coll.save({_key: "test" + i, value: "test" + i}); + docs.push({_key: "test" + i, value: "test" + i}); } + coll.insert(docs); let ecoll = db._createEdgeCollection(edgeColl); - + docs = []; for(let i = 1001; i < 3000; ++i) { - ecoll.save({_from: collName + "/test1000", _to: collName + "/test" + i}); + docs.push({_from: collName + "/test1000", _to: collName + "/test" + i}); } + ecoll.insert(docs); }, - tearDown: cleanUp, + tearDownAll: function () { + db._drop(collName); + db._drop(edgeColl); + }, testCustom: function () { const query = `FOR x IN ${collName} FILTER x IN [${JSON.stringify(db[collName].any())}] RETURN x`; @@ -75,13 +77,6 @@ function aqlVPackExternalsTestSuite () { assertTrue(cursor.hasNext()); }, - testCustomSubquery2: function () { - db[collName].insert({ value: db[collName].any() }); - const query = `FOR x IN ${collName} FILTER x.value IN (FOR doc IN ${collName} RETURN doc) RETURN x`; - const cursor = db._query(query); - assertTrue(cursor.hasNext()); - }, - testPlainExternal: function () { const query = `FOR x IN ${collName} SORT x._key RETURN x`; const cursor = db._query(query); @@ -155,6 +150,56 @@ function aqlVPackExternalsTestSuite () { } }, + testExternalInTraversalMerge: function () { + const query = `WITH ${collName} LET s = (FOR n IN OUTBOUND "${collName}/test1000" ${edgeColl} RETURN n) RETURN MERGE(s)`; + const cursor = db._query(query); + const doc = cursor.next(); + assertTrue(doc.hasOwnProperty('_key')); + assertTrue(doc.hasOwnProperty('_rev')); + assertTrue(doc.hasOwnProperty('_id')); + assertFalse(cursor.hasNext()); + } + }; +} + + +function aqlVPackExternalsModifyTestSuite () { + + const collName = "UnitTestsVPackExternals"; + const edgeColl = "UnitTestsVPackEdges"; + + return { + + setUp: function () { + db._drop(collName); + db._drop(edgeColl); + let coll = db._create(collName); + let docs = []; + for (let i = 1000; i < 5000; ++i) { + docs.push({_key: "test" + i, value: "test" + i}); + } + coll.insert(docs); + + let ecoll = db._createEdgeCollection(edgeColl); + docs = []; + for(let i = 1001; i < 3000; ++i) { + docs.push({_from: collName + "/test1000", _to: collName + "/test" + i}); + } + ecoll.insert(docs); + }, + + tearDown: function () { + db._drop(collName); + db._drop(edgeColl); + }, + + testCustomSubquery2: function () { + db[collName].insert({ value: db[collName].any() }); + const query = `FOR x IN ${collName} FILTER x.value IN (FOR doc IN ${collName} RETURN doc) RETURN x`; + const cursor = db._query(query); + assertTrue(cursor.hasNext()); + }, + testExternalAttributeAccess: function () { let coll = db._collection(collName); let ecoll = db._collection(edgeColl); @@ -207,21 +252,9 @@ function aqlVPackExternalsTestSuite () { const query = `LET us = (FOR u1 IN ${collName} FILTER u1.username == "test1" FOR u2 IN ${collName} FILTER u2.username == "test2" RETURN { u1, u2 }) FOR u IN us FOR msg IN ${edgeColl} FILTER msg._from == u.u1._id && msg._to == u.u2._id RETURN msg._id`; const result = db._query(query).toArray(); assertEqual(edgeColl + "/test1", result[0]); - }, - - testExternalInTraversalMerge: function () { - const query = `WITH ${collName} LET s = (FOR n IN OUTBOUND "${collName}/test1000" ${edgeColl} RETURN n) RETURN MERGE(s)`; - const cursor = db._query(query); - const doc = cursor.next(); - assertTrue(doc.hasOwnProperty('_key')); - assertTrue(doc.hasOwnProperty('_rev')); - assertTrue(doc.hasOwnProperty('_id')); - assertFalse(cursor.hasNext()); } - }; - } - -jsunity.run(aqlVPackExternalsTestSuite); + jsunity.run(aqlVPackExternalsTestSuite); + jsunity.run(aqlVPackExternalsModifyTestSuite); return jsunity.done(); diff --git a/tests/js/server/aql/aql-within-rectangle.js b/tests/js/server/aql/aql-within-rectangle.js index ef18f96d54..3ca0a02f41 100644 --- a/tests/js/server/aql/aql-within-rectangle.js +++ b/tests/js/server/aql/aql-within-rectangle.js @@ -52,21 +52,24 @@ function withinRectangleSuite () { var i, j ; db._create("geo"); indexId = db.geo.ensureGeoIndex("lat", "lon"); - + let geodocs = []; for (i = -40; i < 40; ++i) { for (j = -40; j < 40; ++j) { - db.geo.save({ lat: i, lon: j }); + geodocs.push({ lat: i, lon: j }); } } + db.geo.insert(geodocs); + geodocs = []; db._create("geo2"); indexId = db.geo2.ensureGeoIndex("pos"); for (i = -40; i < 40; ++i) { for (j = -40; j < 40; ++j) { - db.geo2.save({ pos : [i, j] }); + geodocs.push({ pos : [i, j] }); } } + db.geo2.insert(geodocs); }, diff --git a/tests/js/server/shell/shell-pregel.js b/tests/js/server/shell/shell-pregel.js index 2673d15d88..edb5b208bd 100644 --- a/tests/js/server/shell/shell-pregel.js +++ b/tests/js/server/shell/shell-pregel.js @@ -100,35 +100,36 @@ function basicTestSuite() { var edges = db[eColl]; - var A = vertices.insert({ _key: 'A', sssp: 3, pagerank: 0.027645934 })._id; - var B = vertices.insert({ _key: 'B', sssp: 2, pagerank: 0.3241496 })._id; - var C = vertices.insert({ _key: 'C', sssp: 3, pagerank: 0.289220 })._id; - var D = vertices.insert({ _key: 'D', sssp: 2, pagerank: 0.0329636 })._id; - var E = vertices.insert({ _key: 'E', sssp: 1, pagerank: 0.0682141 })._id; - var F = vertices.insert({ _key: 'F', sssp: 2, pagerank: 0.0329636 })._id; - var G = vertices.insert({ _key: 'G', sssp: -1, pagerank: 0.0136363 })._id; - var H = vertices.insert({ _key: 'H', sssp: -1, pagerank: 0.01363636 })._id; - var I = vertices.insert({ _key: 'I', sssp: -1, pagerank: 0.01363636 })._id; - var J = vertices.insert({ _key: 'J', sssp: -1, pagerank: 0.01363636 })._id; - var K = vertices.insert({ _key: 'K', sssp: 0, pagerank: 0.013636363 })._id; + vertices.insert([{ _key: 'A', sssp: 3, pagerank: 0.027645934 }, + { _key: 'B', sssp: 2, pagerank: 0.3241496 }, + { _key: 'C', sssp: 3, pagerank: 0.289220 }, + { _key: 'D', sssp: 2, pagerank: 0.0329636 }, + { _key: 'E', sssp: 1, pagerank: 0.0682141 }, + { _key: 'F', sssp: 2, pagerank: 0.0329636 }, + { _key: 'G', sssp: -1, pagerank: 0.0136363 }, + { _key: 'H', sssp: -1, pagerank: 0.01363636 }, + { _key: 'I', sssp: -1, pagerank: 0.01363636 }, + { _key: 'J', sssp: -1, pagerank: 0.01363636 }, + { _key: 'K', sssp: 0, pagerank: 0.013636363 }]); - edges.insert({ _from: B, _to: C, vertex: 'B' }); - edges.insert({ _from: C, _to: B, vertex: 'C' }); - edges.insert({ _from: D, _to: A, vertex: 'D' }); - edges.insert({ _from: D, _to: B, vertex: 'D' }); - edges.insert({ _from: E, _to: B, vertex: 'E' }); - edges.insert({ _from: E, _to: D, vertex: 'E' }); - edges.insert({ _from: E, _to: F, vertex: 'E' }); - edges.insert({ _from: F, _to: B, vertex: 'F' }); - edges.insert({ _from: F, _to: E, vertex: 'F' }); - edges.insert({ _from: G, _to: B, vertex: 'G' }); - edges.insert({ _from: G, _to: E, vertex: 'G' }); - edges.insert({ _from: H, _to: B, vertex: 'H' }); - edges.insert({ _from: H, _to: E, vertex: 'H' }); - edges.insert({ _from: I, _to: B, vertex: 'I' }); - edges.insert({ _from: I, _to: E, vertex: 'I' }); - edges.insert({ _from: J, _to: E, vertex: 'J' }); - edges.insert({ _from: K, _to: E, vertex: 'K' }); + edges.insert([{ _from: vColl + '/B', _to: vColl + '/C', vertex: 'B' }, + { _from: vColl + '/C', _to: vColl + '/B', vertex: 'C' }, + { _from: vColl + '/D', _to: vColl + '/A', vertex: 'D' }, + { _from: vColl + '/D', _to: vColl + '/B', vertex: 'D' }, + { _from: vColl + '/E', _to: vColl + '/B', vertex: 'E' }, + { _from: vColl + '/E', _to: vColl + '/D', vertex: 'E' }, + { _from: vColl + '/E', _to: vColl + '/F', vertex: 'E' }, + { _from: vColl + '/F', _to: vColl + '/B', vertex: 'F' }, + { _from: vColl + '/F', _to: vColl + '/E', vertex: 'F' }, + { _from: vColl + '/G', _to: vColl + '/B', vertex: 'G' }, + { _from: vColl + '/G', _to: vColl + '/E', vertex: 'G' }, + { _from: vColl + '/H', _to: vColl + '/B', vertex: 'H' }, + { _from: vColl + '/H', _to: vColl + '/E', vertex: 'H' }, + { _from: vColl + '/I', _to: vColl + '/B', vertex: 'I' }, + { _from: vColl + '/I', _to: vColl + '/E', vertex: 'I' }, + { _from: vColl + '/J', _to: vColl + '/E', vertex: 'J' }, + { _from: vColl + '/K', _to: vColl + '/E', vertex: 'K' }]); + edges.toArray(); }, //////////////////////////////////////////////////////////////////////////////// diff --git a/tests/js/server/shell/shell-transactions.js b/tests/js/server/shell/shell-transactions.js index a77644dafd..ab6133bd7d 100644 --- a/tests/js/server/shell/shell-transactions.js +++ b/tests/js/server/shell/shell-transactions.js @@ -1809,10 +1809,10 @@ function transactionOperationsSuite () { testUpdate: function () { c1 = db._create(cn1); - c1.save({ _key: 'foo', a: 1 }); - c1.save({ _key: 'bar', b: 2 }); - c1.save({ _key: 'baz', c: 3 }); - c1.save({ _key: 'bam', d: 4 }); + c1.insert([{ _key: 'foo', a: 1 }, + { _key: 'bar', b: 2 }, + { _key: 'baz', c: 3 }, + { _key: 'bam', d: 4 }]); var obj = { collections: { @@ -1849,9 +1849,9 @@ function transactionOperationsSuite () { testRemove: function () { c1 = db._create(cn1); - c1.save({ _key: 'foo', a: 1 }); - c1.save({ _key: 'bar', b: 2 }); - c1.save({ _key: 'baz', c: 3 }); + c1.insert([{ _key: 'foo', a: 1 }, + { _key: 'bar', b: 2 }, + { _key: 'baz', c: 3 }]); var obj = { collections: { @@ -1898,9 +1898,11 @@ function transactionOperationsSuite () { testTruncateNonEmpty: function () { c1 = db._create(cn1); + let docs = []; for (var i = 0; i < 100; ++i) { - c1.save({ a: i }); + docs.push({ a: i }); } + c1.insert(docs); var obj = { collections: { @@ -1924,9 +1926,11 @@ function transactionOperationsSuite () { testTruncateAndAdd: function () { c1 = db._create(cn1); + let docs = []; for (var i = 0; i < 100; ++i) { - c1.save({ a: i }); + docs.push({ a: i }); } + c1.insert(docs); var obj = { collections: { @@ -1978,9 +1982,11 @@ function transactionOperationsSuite () { c1 = db._create(cn1); c1.ensureUniqueConstraint('name'); + let docs = []; for (var i = 0; i < 100; ++i) { - c1.save({ name: 'test' + i }); + docs.push({ name: 'test' + i }); } + c1.insert(docs); var obj = { collections: { @@ -2003,9 +2009,11 @@ function transactionOperationsSuite () { c1 = db._create(cn1); c1.ensureHashIndex('name'); + let docs = []; for (var i = 0; i < 100; ++i) { - c1.save({ name: 'test' + i }); + docs.push({ name: 'test' + i }); } + c1.insert(docs); var obj = { collections: { @@ -2028,9 +2036,11 @@ function transactionOperationsSuite () { c1 = db._create(cn1); c1.ensureUniqueSkiplist('name'); + let docs = []; for (var i = 0; i < 100; ++i) { - c1.save({ name: 'test' + i }); + docs.push({ name: 'test' + i }); } + c1.insert(docs); var obj = { collections: { @@ -2053,9 +2063,11 @@ function transactionOperationsSuite () { c1 = db._create(cn1); c1.ensureSkiplist('name'); + let docs = []; for (var i = 0; i < 100; ++i) { - c1.save({ name: 'test' + i }); + docs.push({ name: 'test' + i }); } + c1.insert(docs); var obj = { collections: { @@ -3036,9 +3048,11 @@ function transactionRollbackSuite () { testRollbackTruncateNonEmpty: function () { c1 = db._create(cn1); + let docs = []; for (var i = 0; i < 100; ++i) { - c1.save({ _key: 'foo' + i }); + docs.push({ _key: 'foo' + i }); } + c1.insert(docs); assertEqual(100, c1.count()); var obj = { @@ -3134,10 +3148,11 @@ function transactionRollbackSuite () { c1 = db._create(cn1); var i; - + let docs = []; for (i = 0; i < 100; ++i) { - c1.save({ _key: 'key' + i, value: i }); + docs.push({_key: 'key' + i, value: i }); } + c1.insert(docs); var obj = { collections: { @@ -3543,10 +3558,14 @@ function transactionCrossCollectionSuite () { c2 = db._create(cn2); var i; + let docs1 = []; + let docs2 = []; for (i = 0; i < 10; ++i) { - c1.save({ _key: 'a' + i, a: i }); - c2.save({ _key: 'b' + i, b: i }); + docs1.push({ _key: 'a' + i, a: i }); + docs2.push({ _key: 'b' + i, b: i }); } + c1.insert(docs1); + c2.insert(docs2); var obj = { collections: { @@ -3578,10 +3597,14 @@ function transactionCrossCollectionSuite () { c2 = db._create(cn2); var i; + let docs1 = []; + let docs2 = []; for (i = 0; i < 10; ++i) { - c1.save({ _key: 'a' + i, a: i }); - c2.save({ _key: 'b' + i, b: i }); + docs1.push({ _key: 'a' + i, a: i }); + docs2.push({ _key: 'b' + i, b: i }); } + c1.insert(docs1); + c2.insert(docs2); var obj = { collections: { @@ -3611,10 +3634,14 @@ function transactionCrossCollectionSuite () { c2 = db._create(cn2); var i; + let docs1 = []; + let docs2 = []; for (i = 0; i < 10; ++i) { - c1.save({ _key: 'a' + i, a: i }); - c2.save({ _key: 'b' + i, b: i }); + docs1.push({ _key: 'a' + i, a: i }); + docs2.push({ _key: 'b' + i, b: i }); } + c1.insert(docs1); + c2.insert(docs2); var obj = { collections: { @@ -3746,9 +3773,11 @@ function transactionCrossCollectionSuite () { c1 = db._create(cn1); var i; + let docs1 = []; for (i = 0; i < 10; ++i) { - c1.save({ _key: 'a' + i, a: i }); + docs1.push({ _key: 'a' + i, a: i }); } + c1.insert(docs1); var obj = { collections: { @@ -3825,9 +3854,11 @@ function transactionConstraintsSuite () { c.ensureUniqueConstraint('value2'); var i; + let docs = []; for (i = 0; i < 10; ++i) { - c.save({ _key: 'test' + i, value1: i, value2: i }); + docs.push({ _key: 'test' + i, value1: i, value2: i }); } + c.insert(docs); assertEqual(10, c.count()); try { @@ -3852,9 +3883,11 @@ function transactionConstraintsSuite () { c.ensureUniqueConstraint('value2'); var i; + let docs = []; for (i = 0; i < 10; ++i) { - c.save({ _key: 'test' + i, value1: i, value2: i }); + docs.push({ _key: 'test' + i, value1: i, value2: i }); } + c.insert(docs); assertEqual(10, c.count()); try { @@ -3879,9 +3912,11 @@ function transactionConstraintsSuite () { c.ensureUniqueSkiplist('value2'); var i; + let docs = []; for (i = 0; i < 10; ++i) { - c.save({ _key: 'test' + i, value1: i, value2: i }); + docs.push({ _key: 'test' + i, value1: i, value2: i }); } + c.insert(docs); assertEqual(10, c.count()); try { @@ -3906,9 +3941,11 @@ function transactionConstraintsSuite () { c.ensureUniqueSkiplist('value2'); var i; + let docs = []; for (i = 0; i < 10; ++i) { - c.save({ _key: 'test' + i, value1: i, value2: i }); + docs.push({ _key: 'test' + i, value1: i, value2: i }); } + c.insert(docs); assertEqual(10, c.count()); try { @@ -3947,13 +3984,17 @@ function transactionTraversalSuite () { db._createEdgeCollection(cn + 'Edge'); var i; + let docs = []; for (i = 0; i < 100; ++i) { - db.UnitTestsTransactionVertex.insert({ _key: String(i) }); + docs.push({ _key: String(i) }); } + db.UnitTestsTransactionVertex.insert(docs); + docs = []; for (i = 1; i < 100; ++i) { - db.UnitTestsTransactionEdge.insert(cn + 'Vertex/' + i, cn + 'Vertex/' + (i + 1), { }); + docs.push({_from: cn + 'Vertex/' + i, _to: cn + 'Vertex/' + (i + 1) }); } + db.UnitTestsTransactionEdge.insert(docs); }, // //////////////////////////////////////////////////////////////////////////////