mirror of https://gitee.com/bigwinds/arangodb
1959 lines
85 KiB
JavaScript
1959 lines
85 KiB
JavaScript
/*jshint globalstrict:false, strict:false, maxlen: 500 */
|
|
/*global assertTrue, assertFalse, assertNull, assertEqual, assertNotEqual, AQL_EXECUTE, AQL_EXPLAIN */
|
|
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
/// @brief tests for COLLECT w/ COUNT
|
|
///
|
|
/// @file
|
|
///
|
|
/// DISCLAIMER
|
|
///
|
|
/// Copyright 2010-2012 triagens GmbH, Cologne, Germany
|
|
///
|
|
/// Licensed under the Apache License, Version 2.0 (the "License");
|
|
/// you may not use this file except in compliance with the License.
|
|
/// You may obtain a copy of the License at
|
|
///
|
|
/// http://www.apache.org/licenses/LICENSE-2.0
|
|
///
|
|
/// Unless required by applicable law or agreed to in writing, software
|
|
/// distributed under the License is distributed on an "AS IS" BASIS,
|
|
/// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
/// See the License for the specific language governing permissions and
|
|
/// limitations under the License.
|
|
///
|
|
/// Copyright holder is triAGENS GmbH, Cologne, Germany
|
|
///
|
|
/// @author Jan Steemann
|
|
/// @author Copyright 2012, triAGENS GmbH, Cologne, Germany
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
|
|
const jsunity = require("jsunity");
|
|
const internal = require("internal");
|
|
const errors = internal.errors;
|
|
const db = require("@arangodb").db;
|
|
const helper = require("@arangodb/aql-helper");
|
|
const assertQueryError = helper.assertQueryError;
|
|
const isCluster = require("@arangodb/cluster").isCluster();
|
|
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
/// @brief test suite
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
|
|
function optimizerAggregateTestSuite () {
|
|
let c;
|
|
|
|
return {
|
|
setUp : function () {
|
|
db._drop("UnitTestsCollection");
|
|
c = db._create("UnitTestsCollection", { numberOfShards: 5 });
|
|
|
|
for (var i = 0; i < 2000; ++i) {
|
|
c.save({ group: "test" + (i % 10), value1: i, value2: i % 5 });
|
|
}
|
|
},
|
|
|
|
tearDown : function () {
|
|
db._drop("UnitTestsCollection");
|
|
},
|
|
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
/// @brief test invalid queries
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
|
|
testInvalidSyntax : function () {
|
|
assertQueryError(errors.ERROR_QUERY_PARSE.code, "FOR i IN " + c.name() + " AGGREGATE RETURN 1");
|
|
assertQueryError(errors.ERROR_QUERY_PARSE.code, "FOR i IN " + c.name() + " AGGREGATE length = LENGTH(i) RETURN 1");
|
|
assertQueryError(errors.ERROR_QUERY_PARSE.code, "FOR i IN " + c.name() + " COLLECT AGGREGATE RETURN 1");
|
|
assertQueryError(errors.ERROR_QUERY_PARSE.code, "FOR i IN " + c.name() + " COLLECT COUNT AGGREGATE length = LENGTH(i) RETURN 1");
|
|
assertQueryError(errors.ERROR_QUERY_PARSE.code, "FOR i IN " + c.name() + " COLLECT AGGREGATE length = LENGTH(i) WITH COUNT RETURN 1");
|
|
assertQueryError(errors.ERROR_QUERY_PARSE.code, "FOR i IN " + c.name() + " COLLECT AGGREGATE length = LENGTH(i) WITH COUNT INTO x RETURN 1");
|
|
assertQueryError(errors.ERROR_QUERY_PARSE.code, "FOR i IN " + c.name() + " COLLECT WITH COUNT g AGGREGATE length = LENGTH(i) RETURN 1");
|
|
assertQueryError(errors.ERROR_QUERY_PARSE.code, "FOR i IN " + c.name() + " COLLECT class = i.group AGGREGATE WITH COUNT RETURN 1");
|
|
assertQueryError(errors.ERROR_QUERY_PARSE.code, "FOR i IN " + c.name() + " COLLECT class = i.group AGGREGATE length = LENGTH(i) WITH COUNT RETURN 1");
|
|
},
|
|
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
/// @brief test invalid queries
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
|
|
testInvalidAggregateFunctions : function () {
|
|
assertQueryError(errors.ERROR_QUERY_INVALID_AGGREGATE_EXPRESSION.code, "FOR i IN " + c.name() + " COLLECT AGGREGATE c = 1 RETURN 1");
|
|
assertQueryError(errors.ERROR_QUERY_INVALID_AGGREGATE_EXPRESSION.code, "FOR i IN " + c.name() + " COLLECT AGGREGATE c = i.test RETURN 1");
|
|
assertQueryError(errors.ERROR_QUERY_INVALID_AGGREGATE_EXPRESSION.code, "FOR i IN " + c.name() + " COLLECT AGGREGATE c = i.test + 1 RETURN 1");
|
|
assertQueryError(errors.ERROR_QUERY_INVALID_AGGREGATE_EXPRESSION.code, "FOR i IN " + c.name() + " COLLECT AGGREGATE c = LENGTH(i) + 1 RETURN 1");
|
|
assertQueryError(errors.ERROR_QUERY_INVALID_AGGREGATE_EXPRESSION.code, "FOR i IN " + c.name() + " COLLECT AGGREGATE c = 1 + LENGTH(i) RETURN 1");
|
|
assertQueryError(errors.ERROR_QUERY_INVALID_AGGREGATE_EXPRESSION.code, "FOR i IN " + c.name() + " COLLECT AGGREGATE c = IS_NUMBER(i) RETURN 1");
|
|
assertQueryError(errors.ERROR_QUERY_INVALID_AGGREGATE_EXPRESSION.code, "FOR i IN " + c.name() + " COLLECT AGGREGATE c = IS_STRING(i) RETURN 1");
|
|
assertQueryError(errors.ERROR_QUERY_INVALID_AGGREGATE_EXPRESSION.code, "FOR i IN " + c.name() + " COLLECT AGGREGATE c = IS_ARRAY(i) RETURN 1");
|
|
assertQueryError(errors.ERROR_QUERY_INVALID_AGGREGATE_EXPRESSION.code, "FOR i IN " + c.name() + " COLLECT AGGREGATE c = IS_OBJECT(i) RETURN 1");
|
|
assertQueryError(errors.ERROR_QUERY_INVALID_AGGREGATE_EXPRESSION.code, "FOR i IN " + c.name() + " COLLECT AGGREGATE length = LENGTH(i), c = IS_OBJECT(i) RETURN 1");
|
|
assertQueryError(errors.ERROR_QUERY_INVALID_AGGREGATE_EXPRESSION.code, "FOR i IN " + c.name() + " COLLECT group = i.group AGGREGATE c = IS_OBJECT(i) RETURN 1");
|
|
},
|
|
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
/// @brief test aggregate
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
|
|
testAggregateAll : function () {
|
|
var query = "FOR i IN " + c.name() + " COLLECT group = i.group AGGREGATE length = LENGTH(i.value1), min = MIN(i.value1), max = MAX(i.value1), sum = SUM(i.value1), avg = AVERAGE(i.value1) RETURN { group, length, min, max, sum, avg }";
|
|
|
|
var results = AQL_EXECUTE(query);
|
|
assertEqual(10, results.json.length);
|
|
for (var i = 0; i < 10; ++i) {
|
|
assertEqual("test" + i, results.json[i].group);
|
|
assertEqual(200, results.json[i].length);
|
|
assertEqual(i, results.json[i].min);
|
|
assertEqual(1990 + i, results.json[i].max);
|
|
assertEqual(199000 + i * 200, results.json[i].sum);
|
|
assertEqual(995 + i, results.json[i].avg);
|
|
}
|
|
|
|
var plan = AQL_EXPLAIN(query).plan;
|
|
// must have a SortNode
|
|
assertNotEqual(-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("hash", collectNode.collectOptions.method);
|
|
assertFalse(collectNode.count);
|
|
assertFalse(collectNode.isDistinctCommand);
|
|
|
|
assertEqual(1, collectNode.groups.length);
|
|
|
|
assertEqual(5, collectNode.aggregates.length);
|
|
assertEqual("LENGTH", collectNode.aggregates[0].type);
|
|
assertEqual("MIN", collectNode.aggregates[1].type);
|
|
assertEqual("MAX", collectNode.aggregates[2].type);
|
|
assertEqual("SUM", collectNode.aggregates[3].type);
|
|
assertEqual("AVERAGE_STEP1", collectNode.aggregates[4].type);
|
|
|
|
collectNode = collectNodes[1];
|
|
}
|
|
|
|
assertEqual("hash", collectNode.collectOptions.method);
|
|
assertFalse(collectNode.count);
|
|
assertFalse(collectNode.isDistinctCommand);
|
|
|
|
assertEqual(1, collectNode.groups.length);
|
|
assertEqual("group", collectNode.groups[0].outVariable.name);
|
|
|
|
assertEqual(5, collectNode.aggregates.length);
|
|
assertEqual("length", collectNode.aggregates[0].outVariable.name);
|
|
assertEqual(isCluster ? "SUM" : "LENGTH", collectNode.aggregates[0].type);
|
|
assertEqual("min", collectNode.aggregates[1].outVariable.name);
|
|
assertEqual("MIN", collectNode.aggregates[1].type);
|
|
assertEqual("max", collectNode.aggregates[2].outVariable.name);
|
|
assertEqual("MAX", collectNode.aggregates[2].type);
|
|
assertEqual("sum", collectNode.aggregates[3].outVariable.name);
|
|
assertEqual("SUM", collectNode.aggregates[3].type);
|
|
assertEqual("avg", collectNode.aggregates[4].outVariable.name);
|
|
assertEqual(isCluster ? "AVERAGE_STEP2" : "AVERAGE", collectNode.aggregates[4].type);
|
|
},
|
|
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
/// @brief test aggregate
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
|
|
testAggregateExpression : function () {
|
|
var query = "FOR i IN " + c.name() + " COLLECT group = i.group AGGREGATE length = LENGTH(1), min = MIN(i.value1 + 1), max = MAX(i.value1 * 2) RETURN { group, length, min, max }";
|
|
|
|
var results = AQL_EXECUTE(query);
|
|
assertEqual(10, results.json.length);
|
|
for (var i = 0; i < 10; ++i) {
|
|
assertEqual("test" + i, results.json[i].group);
|
|
assertEqual(200, results.json[i].length);
|
|
assertEqual(i + 1, results.json[i].min);
|
|
assertEqual((1990 + i) * 2, results.json[i].max);
|
|
}
|
|
|
|
var plan = AQL_EXPLAIN(query).plan;
|
|
// must have a SortNode
|
|
assertNotEqual(-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("hash", collectNode.collectOptions.method);
|
|
assertFalse(collectNode.count);
|
|
assertFalse(collectNode.isDistinctCommand);
|
|
|
|
assertEqual(1, collectNode.groups.length);
|
|
|
|
assertEqual(3, collectNode.aggregates.length);
|
|
assertEqual("LENGTH", collectNode.aggregates[0].type);
|
|
assertEqual("MIN", collectNode.aggregates[1].type);
|
|
assertEqual("MAX", collectNode.aggregates[2].type);
|
|
|
|
collectNode = collectNodes[1];
|
|
}
|
|
assertEqual("hash", collectNode.collectOptions.method);
|
|
assertFalse(collectNode.count);
|
|
assertFalse(collectNode.isDistinctCommand);
|
|
|
|
assertEqual(1, collectNode.groups.length);
|
|
assertEqual("group", collectNode.groups[0].outVariable.name);
|
|
|
|
assertEqual(3, collectNode.aggregates.length);
|
|
assertEqual("length", collectNode.aggregates[0].outVariable.name);
|
|
assertEqual(isCluster ? "SUM" : "LENGTH", collectNode.aggregates[0].type);
|
|
assertEqual("min", collectNode.aggregates[1].outVariable.name);
|
|
assertEqual("MIN", collectNode.aggregates[1].type);
|
|
assertEqual("max", collectNode.aggregates[2].outVariable.name);
|
|
assertEqual("MAX", collectNode.aggregates[2].type);
|
|
},
|
|
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
/// @brief test aggregate
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
|
|
testAggregateUnique : function () {
|
|
var query = "FOR i IN " + c.name() + " COLLECT group = i.group AGGREGATE length = LENGTH(1), unique1 = UNIQUE(i.value1), unique2 = UNIQUE(i.value2), uniqueGroup = UNIQUE(i.group) RETURN { group, length, unique1, unique2, uniqueGroup }";
|
|
|
|
var results = AQL_EXECUTE(query);
|
|
assertEqual(10, results.json.length);
|
|
for (var i = 0; i < 10; ++i) {
|
|
assertEqual("test" + i, results.json[i].group);
|
|
assertEqual(200, results.json[i].length);
|
|
assertEqual(200, results.json[i].unique1.length);
|
|
assertEqual([ i % 5 ], results.json[i].unique2);
|
|
assertEqual([ "test" + i ], results.json[i].uniqueGroup);
|
|
}
|
|
|
|
let plan = AQL_EXPLAIN(query).plan;
|
|
// must have a SortNode
|
|
assertNotEqual(-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("hash", collectNode.collectOptions.method);
|
|
assertFalse(collectNode.count);
|
|
assertFalse(collectNode.isDistinctCommand);
|
|
|
|
assertEqual(1, collectNode.groups.length);
|
|
|
|
assertEqual(4, collectNode.aggregates.length);
|
|
assertEqual("LENGTH", collectNode.aggregates[0].type);
|
|
assertEqual("UNIQUE", collectNode.aggregates[1].type);
|
|
assertEqual("UNIQUE", collectNode.aggregates[2].type);
|
|
assertEqual("UNIQUE", collectNode.aggregates[3].type);
|
|
|
|
collectNode = collectNodes[1];
|
|
}
|
|
assertEqual("hash", collectNode.collectOptions.method);
|
|
assertFalse(collectNode.count);
|
|
assertFalse(collectNode.isDistinctCommand);
|
|
|
|
assertEqual(1, collectNode.groups.length);
|
|
assertEqual("group", collectNode.groups[0].outVariable.name);
|
|
|
|
assertEqual(4, collectNode.aggregates.length);
|
|
assertEqual("length", collectNode.aggregates[0].outVariable.name);
|
|
assertEqual(isCluster ? "SUM" : "LENGTH", collectNode.aggregates[0].type);
|
|
assertEqual("unique1", collectNode.aggregates[1].outVariable.name);
|
|
assertEqual(isCluster ? "UNIQUE_STEP2" : "UNIQUE", collectNode.aggregates[1].type);
|
|
assertEqual("unique2", collectNode.aggregates[2].outVariable.name);
|
|
assertEqual(isCluster ? "UNIQUE_STEP2" : "UNIQUE", collectNode.aggregates[2].type);
|
|
assertEqual("uniqueGroup", collectNode.aggregates[3].outVariable.name);
|
|
assertEqual(isCluster ? "UNIQUE_STEP2" : "UNIQUE", collectNode.aggregates[3].type);
|
|
},
|
|
|
|
testAggregateUnique2 : function () {
|
|
var query = "FOR i IN " + c.name() + " COLLECT AGGREGATE unique1 = UNIQUE(i.value1), unique2 = UNIQUE(i.value2) RETURN { unique1, unique2 }";
|
|
|
|
var results = AQL_EXECUTE(query);
|
|
assertEqual(1, results.json.length);
|
|
let expected = [];
|
|
for (let i = 0; i < 2000; ++i) {
|
|
expected.push(i);
|
|
}
|
|
assertEqual(expected.sort(), results.json[0].unique1.sort());
|
|
assertEqual([ 0, 1, 2, 3, 4 ], results.json[0].unique2.sort());
|
|
|
|
let plan = AQL_EXPLAIN(query).plan;
|
|
|
|
let collectNodes = plan.nodes.filter(function(node) { return node.type === 'CollectNode'; });
|
|
assertEqual(isCluster ? 2 : 1, collectNodes.length);
|
|
|
|
let collectNode = collectNodes[0];
|
|
if (isCluster) {
|
|
assertFalse(collectNode.count);
|
|
assertFalse(collectNode.isDistinctCommand);
|
|
|
|
assertEqual(0, collectNode.groups.length);
|
|
|
|
assertEqual(2, collectNode.aggregates.length);
|
|
assertEqual("UNIQUE", collectNode.aggregates[0].type);
|
|
assertEqual("UNIQUE", collectNode.aggregates[0].type);
|
|
|
|
collectNode = collectNodes[1];
|
|
}
|
|
assertFalse(collectNode.count);
|
|
assertFalse(collectNode.isDistinctCommand);
|
|
|
|
assertEqual(0, collectNode.groups.length);
|
|
|
|
assertEqual(2, collectNode.aggregates.length);
|
|
assertEqual("unique1", collectNode.aggregates[0].outVariable.name);
|
|
assertEqual(isCluster ? "UNIQUE_STEP2" : "UNIQUE", collectNode.aggregates[0].type);
|
|
assertEqual("unique2", collectNode.aggregates[1].outVariable.name);
|
|
assertEqual(isCluster ? "UNIQUE_STEP2" : "UNIQUE", collectNode.aggregates[1].type);
|
|
},
|
|
|
|
testAggregateSortedUnique : function () {
|
|
var query = "FOR i IN " + c.name() + " COLLECT group = i.group AGGREGATE length = LENGTH(1), unique1 = SORTED_UNIQUE(i.value1), unique2 = SORTED_UNIQUE(i.value2), uniqueGroup = SORTED_UNIQUE(i.group) RETURN { group, length, unique1, unique2, uniqueGroup }";
|
|
|
|
var results = AQL_EXECUTE(query);
|
|
assertEqual(10, results.json.length);
|
|
for (var i = 0; i < 10; ++i) {
|
|
let values = [];
|
|
for (let j = 0; j < 200; ++j) {
|
|
values.push((10 * j) + i);
|
|
}
|
|
assertEqual("test" + i, results.json[i].group);
|
|
assertEqual(200, results.json[i].length);
|
|
assertEqual(200, results.json[i].unique1.length);
|
|
assertEqual(values, results.json[i].unique1);
|
|
assertEqual([ i % 5 ], results.json[i].unique2);
|
|
assertEqual([ "test" + i ], results.json[i].uniqueGroup);
|
|
}
|
|
|
|
let plan = AQL_EXPLAIN(query).plan;
|
|
// must have a SortNode
|
|
assertNotEqual(-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("hash", collectNode.collectOptions.method);
|
|
assertFalse(collectNode.count);
|
|
assertFalse(collectNode.isDistinctCommand);
|
|
|
|
assertEqual(1, collectNode.groups.length);
|
|
|
|
assertEqual(4, collectNode.aggregates.length);
|
|
assertEqual("LENGTH", collectNode.aggregates[0].type);
|
|
assertEqual("SORTED_UNIQUE", collectNode.aggregates[1].type);
|
|
assertEqual("SORTED_UNIQUE", collectNode.aggregates[2].type);
|
|
assertEqual("SORTED_UNIQUE", collectNode.aggregates[3].type);
|
|
|
|
collectNode = collectNodes[1];
|
|
}
|
|
assertEqual("hash", collectNode.collectOptions.method);
|
|
assertFalse(collectNode.count);
|
|
assertFalse(collectNode.isDistinctCommand);
|
|
|
|
assertEqual(1, collectNode.groups.length);
|
|
assertEqual("group", collectNode.groups[0].outVariable.name);
|
|
|
|
assertEqual(4, collectNode.aggregates.length);
|
|
assertEqual("length", collectNode.aggregates[0].outVariable.name);
|
|
assertEqual(isCluster ? "SUM" : "LENGTH", collectNode.aggregates[0].type);
|
|
assertEqual("unique1", collectNode.aggregates[1].outVariable.name);
|
|
assertEqual(isCluster ? "SORTED_UNIQUE_STEP2" : "SORTED_UNIQUE", collectNode.aggregates[1].type);
|
|
assertEqual("unique2", collectNode.aggregates[2].outVariable.name);
|
|
assertEqual(isCluster ? "SORTED_UNIQUE_STEP2" : "SORTED_UNIQUE", collectNode.aggregates[2].type);
|
|
assertEqual("uniqueGroup", collectNode.aggregates[3].outVariable.name);
|
|
assertEqual(isCluster ? "SORTED_UNIQUE_STEP2" : "SORTED_UNIQUE", collectNode.aggregates[3].type);
|
|
},
|
|
|
|
testAggregateCountUnique : function () {
|
|
var query = "FOR i IN " + c.name() + " COLLECT group = i.group AGGREGATE length = LENGTH(1), unique1 = COUNT_UNIQUE(i.value1), unique2 = COUNT_UNIQUE(i.value2), uniqueGroup = COUNT_DISTINCT(i.group) RETURN { group, length, unique1, unique2, uniqueGroup }";
|
|
|
|
var results = AQL_EXECUTE(query);
|
|
assertEqual(10, results.json.length);
|
|
for (var i = 0; i < 10; ++i) {
|
|
assertEqual("test" + i, results.json[i].group);
|
|
assertEqual(200, results.json[i].length);
|
|
assertEqual(200, results.json[i].unique1);
|
|
assertEqual(1, results.json[i].unique2);
|
|
assertEqual(1, results.json[i].uniqueGroup);
|
|
}
|
|
|
|
let plan = AQL_EXPLAIN(query).plan;
|
|
// must have a SortNode
|
|
assertNotEqual(-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("hash", collectNode.collectOptions.method);
|
|
assertFalse(collectNode.count);
|
|
assertFalse(collectNode.isDistinctCommand);
|
|
|
|
assertEqual(1, collectNode.groups.length);
|
|
|
|
assertEqual(4, collectNode.aggregates.length);
|
|
assertEqual("LENGTH", collectNode.aggregates[0].type);
|
|
assertEqual("UNIQUE", collectNode.aggregates[1].type);
|
|
assertEqual("UNIQUE", collectNode.aggregates[2].type);
|
|
assertEqual("UNIQUE", collectNode.aggregates[3].type);
|
|
|
|
collectNode = collectNodes[1];
|
|
}
|
|
assertEqual("hash", collectNode.collectOptions.method);
|
|
assertFalse(collectNode.count);
|
|
assertFalse(collectNode.isDistinctCommand);
|
|
|
|
assertEqual(1, collectNode.groups.length);
|
|
assertEqual("group", collectNode.groups[0].outVariable.name);
|
|
|
|
assertEqual(4, collectNode.aggregates.length);
|
|
assertEqual("length", collectNode.aggregates[0].outVariable.name);
|
|
assertEqual(isCluster ? "SUM" : "LENGTH", collectNode.aggregates[0].type);
|
|
assertEqual("unique1", collectNode.aggregates[1].outVariable.name);
|
|
assertEqual(isCluster ? "COUNT_DISTINCT_STEP2" : "COUNT_DISTINCT", collectNode.aggregates[1].type);
|
|
assertEqual("unique2", collectNode.aggregates[2].outVariable.name);
|
|
assertEqual(isCluster ? "COUNT_DISTINCT_STEP2" : "COUNT_DISTINCT", collectNode.aggregates[2].type);
|
|
assertEqual("uniqueGroup", collectNode.aggregates[3].outVariable.name);
|
|
assertEqual(isCluster ? "COUNT_DISTINCT_STEP2" : "COUNT_DISTINCT", collectNode.aggregates[3].type);
|
|
},
|
|
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
/// @brief test aggregate
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
|
|
testAggregateAllReferToCollectvariable : function () {
|
|
assertQueryError(errors.ERROR_QUERY_VARIABLE_NAME_UNKNOWN.code, "FOR i IN " + c.name() + " COLLECT group = i.group AGGREGATE length = LENGTH(group) RETURN { group, length }");
|
|
assertQueryError(errors.ERROR_QUERY_VARIABLE_NAME_UNKNOWN.code, "FOR j IN " + c.name() + " COLLECT doc = j AGGREGATE length = LENGTH(doc) RETURN doc");
|
|
assertQueryError(errors.ERROR_QUERY_VARIABLE_NAME_UNKNOWN.code, "FOR j IN " + c.name() + " COLLECT doc = j AGGREGATE length1 = LENGTH(1), length2 = LENGTH(length1) RETURN doc");
|
|
},
|
|
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
/// @brief test aggregate
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
|
|
testAggregateFiltered : function () {
|
|
var query = "FOR i IN " + c.name() + " FILTER i.group == 'test4' COLLECT group = i.group AGGREGATE length = LENGTH(i.value1), min = MIN(i.value1), max = MAX(i.value1), sum = SUM(i.value1), avg = AVERAGE(i.value1) RETURN { group, length, min, max, sum, avg }";
|
|
|
|
var results = AQL_EXECUTE(query);
|
|
assertEqual(1, results.json.length);
|
|
assertEqual("test4", results.json[0].group);
|
|
assertEqual(200, results.json[0].length);
|
|
assertEqual(4, results.json[0].min);
|
|
assertEqual(1994, results.json[0].max);
|
|
assertEqual(199800, results.json[0].sum);
|
|
assertEqual(999, results.json[0].avg);
|
|
|
|
var plan = AQL_EXPLAIN(query).plan;
|
|
// must have a SortNode
|
|
assertNotEqual(-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("hash", collectNode.collectOptions.method);
|
|
assertFalse(collectNode.count);
|
|
assertFalse(collectNode.isDistinctCommand);
|
|
|
|
assertEqual(5, collectNode.aggregates.length);
|
|
assertEqual("LENGTH", collectNode.aggregates[0].type);
|
|
assertEqual("MIN", collectNode.aggregates[1].type);
|
|
assertEqual("MAX", collectNode.aggregates[2].type);
|
|
assertEqual("SUM", collectNode.aggregates[3].type);
|
|
assertEqual("AVERAGE_STEP1", collectNode.aggregates[4].type);
|
|
collectNode = collectNodes[1];
|
|
}
|
|
|
|
assertEqual("hash", collectNode.collectOptions.method);
|
|
assertFalse(collectNode.count);
|
|
assertFalse(collectNode.isDistinctCommand);
|
|
|
|
assertEqual(1, collectNode.groups.length);
|
|
assertEqual("group", collectNode.groups[0].outVariable.name);
|
|
|
|
assertEqual(5, collectNode.aggregates.length);
|
|
assertEqual("length", collectNode.aggregates[0].outVariable.name);
|
|
assertEqual(isCluster ? "SUM" : "LENGTH", collectNode.aggregates[0].type);
|
|
assertEqual("min", collectNode.aggregates[1].outVariable.name);
|
|
assertEqual("MIN", collectNode.aggregates[1].type);
|
|
assertEqual("max", collectNode.aggregates[2].outVariable.name);
|
|
assertEqual("MAX", collectNode.aggregates[2].type);
|
|
assertEqual("sum", collectNode.aggregates[3].outVariable.name);
|
|
assertEqual("SUM", collectNode.aggregates[3].type);
|
|
assertEqual("avg", collectNode.aggregates[4].outVariable.name);
|
|
assertEqual(isCluster ? "AVERAGE_STEP2" : "AVERAGE", collectNode.aggregates[4].type);
|
|
},
|
|
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
/// @brief test aggregate
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
|
|
testAggregateFilteredMulti : function () {
|
|
var query = "FOR i IN " + c.name() + " FILTER i.group >= 'test2' && i.group <= 'test4' COLLECT group = i.group AGGREGATE length = LENGTH(i.value1), min = MIN(i.value1), max = MAX(i.value1), sum = SUM(i.value1), avg = AVERAGE(i.value1) RETURN { group, length, min, max, sum, avg }";
|
|
|
|
var results = AQL_EXECUTE(query);
|
|
assertEqual(3, results.json.length);
|
|
for (var i = 2; i <= 4; ++i) {
|
|
assertEqual("test" + i, results.json[i - 2].group);
|
|
assertEqual(200, results.json[i - 2].length);
|
|
assertEqual(i, results.json[i - 2].min);
|
|
assertEqual(1990 + i, results.json[i - 2].max);
|
|
assertEqual(199000 + i * 200, results.json[i - 2].sum);
|
|
assertEqual(995 + i, results.json[i - 2].avg);
|
|
}
|
|
|
|
var plan = AQL_EXPLAIN(query).plan;
|
|
// must have a SortNode
|
|
assertNotEqual(-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("hash", collectNode.collectOptions.method);
|
|
assertFalse(collectNode.count);
|
|
assertFalse(collectNode.isDistinctCommand);
|
|
|
|
assertEqual(5, collectNode.aggregates.length);
|
|
assertEqual("LENGTH", collectNode.aggregates[0].type);
|
|
assertEqual("MIN", collectNode.aggregates[1].type);
|
|
assertEqual("MAX", collectNode.aggregates[2].type);
|
|
assertEqual("SUM", collectNode.aggregates[3].type);
|
|
assertEqual("AVERAGE_STEP1", collectNode.aggregates[4].type);
|
|
collectNode = collectNodes[1];
|
|
}
|
|
|
|
assertEqual(1, collectNode.groups.length);
|
|
assertEqual("group", collectNode.groups[0].outVariable.name);
|
|
|
|
assertEqual(5, collectNode.aggregates.length);
|
|
assertEqual("length", collectNode.aggregates[0].outVariable.name);
|
|
assertEqual(isCluster ? "SUM" : "LENGTH", collectNode.aggregates[0].type);
|
|
assertEqual("min", collectNode.aggregates[1].outVariable.name);
|
|
assertEqual("MIN", collectNode.aggregates[1].type);
|
|
assertEqual("max", collectNode.aggregates[2].outVariable.name);
|
|
assertEqual("MAX", collectNode.aggregates[2].type);
|
|
assertEqual("sum", collectNode.aggregates[3].outVariable.name);
|
|
assertEqual("SUM", collectNode.aggregates[3].type);
|
|
assertEqual("avg", collectNode.aggregates[4].outVariable.name);
|
|
assertEqual(isCluster ? "AVERAGE_STEP2" : "AVERAGE", collectNode.aggregates[4].type);
|
|
},
|
|
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
/// @brief test aggregate
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
|
|
testAggregateFilteredEmpty : function () {
|
|
var query = "FOR i IN " + c.name() + " FILTER i.group >= 'test99' COLLECT group = i.group AGGREGATE length = LENGTH(i.value1), min = MIN(i.value1), max = MAX(i.value1), sum = SUM(i.value1), avg = AVERAGE(i.value1) RETURN { group, length, min, max, sum, avg }";
|
|
|
|
var results = AQL_EXECUTE(query);
|
|
assertEqual(0, results.json.length);
|
|
|
|
var plan = AQL_EXPLAIN(query).plan;
|
|
// must have a SortNode
|
|
assertNotEqual(-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("hash", collectNode.collectOptions.method);
|
|
assertFalse(collectNode.count);
|
|
assertFalse(collectNode.isDistinctCommand);
|
|
|
|
assertEqual(5, collectNode.aggregates.length);
|
|
assertEqual("LENGTH", collectNode.aggregates[0].type);
|
|
assertEqual("MIN", collectNode.aggregates[1].type);
|
|
assertEqual("MAX", collectNode.aggregates[2].type);
|
|
assertEqual("SUM", collectNode.aggregates[3].type);
|
|
assertEqual("AVERAGE_STEP1", collectNode.aggregates[4].type);
|
|
collectNode = collectNodes[1];
|
|
}
|
|
|
|
assertEqual("hash", collectNode.collectOptions.method);
|
|
assertFalse(collectNode.count);
|
|
assertFalse(collectNode.isDistinctCommand);
|
|
|
|
assertEqual(1, collectNode.groups.length);
|
|
assertEqual("group", collectNode.groups[0].outVariable.name);
|
|
|
|
assertEqual(5, collectNode.aggregates.length);
|
|
assertEqual("length", collectNode.aggregates[0].outVariable.name);
|
|
assertEqual(isCluster ? "SUM" : "LENGTH", collectNode.aggregates[0].type);
|
|
assertEqual("min", collectNode.aggregates[1].outVariable.name);
|
|
assertEqual("MIN", collectNode.aggregates[1].type);
|
|
assertEqual("max", collectNode.aggregates[2].outVariable.name);
|
|
assertEqual("MAX", collectNode.aggregates[2].type);
|
|
assertEqual("sum", collectNode.aggregates[3].outVariable.name);
|
|
assertEqual("SUM", collectNode.aggregates[3].type);
|
|
assertEqual("avg", collectNode.aggregates[4].outVariable.name);
|
|
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
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
|
|
testAggregateNested : function () {
|
|
var query = "FOR i IN 1..2 FOR j IN " + c.name() + " COLLECT AGGREGATE length = LENGTH(j) RETURN length";
|
|
|
|
let opts = { optimizer: { rules: ["-interchange-adjacent-enumerations"] } };
|
|
var results = AQL_EXECUTE(query, null, opts);
|
|
assertEqual(1, results.json.length);
|
|
assertEqual(4000, results.json[0]);
|
|
|
|
var plan = AQL_EXPLAIN(query, null, opts).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(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
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
|
|
testAggregateSimple : function () {
|
|
var query = "FOR i IN " + c.name() + " COLLECT class = i.group AGGREGATE length = LENGTH(i) RETURN [ class, length ]";
|
|
|
|
var results = AQL_EXECUTE(query);
|
|
assertEqual(10, results.json.length);
|
|
for (var i = 0; i < results.json.length; ++i) {
|
|
var group = results.json[i];
|
|
assertTrue(Array.isArray(group));
|
|
assertEqual("test" + i, group[0]);
|
|
assertEqual(200, group[1]);
|
|
}
|
|
|
|
var plan = AQL_EXPLAIN(query).plan;
|
|
// must have a SortNode
|
|
assertNotEqual(-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("hash", collectNode.collectOptions.method);
|
|
assertFalse(collectNode.count);
|
|
assertFalse(collectNode.isDistinctCommand);
|
|
|
|
assertEqual(1, collectNode.groups.length);
|
|
|
|
assertEqual(1, collectNode.aggregates.length);
|
|
assertEqual("LENGTH", collectNode.aggregates[0].type);
|
|
|
|
collectNode = collectNodes[1];
|
|
}
|
|
assertEqual("hash", collectNode.collectOptions.method);
|
|
assertFalse(collectNode.count);
|
|
assertFalse(collectNode.isDistinctCommand);
|
|
|
|
assertEqual(1, collectNode.groups.length);
|
|
assertEqual("class", collectNode.groups[0].outVariable.name);
|
|
|
|
assertEqual(1, collectNode.aggregates.length);
|
|
assertEqual("length", collectNode.aggregates[0].outVariable.name);
|
|
assertEqual(isCluster ? "SUM" : "LENGTH", collectNode.aggregates[0].type);
|
|
},
|
|
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
/// @brief test aggregate shaped
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
|
|
testAggregateShaped : function () {
|
|
var query = "FOR j IN " + c.name() + " COLLECT doc = j AGGREGATE length = LENGTH(j) RETURN { doc, length }";
|
|
|
|
var results = AQL_EXECUTE(query);
|
|
// expectation is that we get 1000 different docs and do not crash (issue #1265)
|
|
assertEqual(2000, results.json.length);
|
|
|
|
var plan = AQL_EXPLAIN(query).plan;
|
|
// must have a SortNode
|
|
assertNotEqual(-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("hash", collectNode.collectOptions.method);
|
|
assertFalse(collectNode.count);
|
|
assertFalse(collectNode.isDistinctCommand);
|
|
|
|
assertEqual(1, collectNode.groups.length);
|
|
assertEqual(1, collectNode.aggregates.length);
|
|
assertEqual("LENGTH", collectNode.aggregates[0].type);
|
|
|
|
collectNode = collectNodes[1];
|
|
}
|
|
assertEqual("hash", collectNode.collectOptions.method);
|
|
assertFalse(collectNode.count);
|
|
assertFalse(collectNode.isDistinctCommand);
|
|
|
|
assertEqual(1, collectNode.groups.length);
|
|
assertEqual("doc", collectNode.groups[0].outVariable.name);
|
|
|
|
assertEqual(1, collectNode.aggregates.length);
|
|
assertEqual("length", collectNode.aggregates[0].outVariable.name);
|
|
assertEqual(isCluster ? "SUM" : "LENGTH", collectNode.aggregates[0].type);
|
|
},
|
|
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
/// @brief test aggregate
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
|
|
testMultiKey : function () {
|
|
var query = "FOR i IN " + c.name() + " COLLECT group1 = i.group, group2 = i.value2 AGGREGATE length = LENGTH(i.value1) RETURN { group1, group2, length }";
|
|
|
|
var results = AQL_EXECUTE(query);
|
|
assertEqual(10, results.json.length);
|
|
for (var i = 0; i < 10; ++i) {
|
|
assertEqual("test" + i, results.json[i].group1);
|
|
assertEqual(i % 5, results.json[i].group2);
|
|
assertEqual(200, results.json[i].length);
|
|
}
|
|
|
|
var plan = AQL_EXPLAIN(query).plan;
|
|
// must have a SortNode
|
|
assertNotEqual(-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("hash", collectNode.collectOptions.method);
|
|
assertFalse(collectNode.count);
|
|
assertFalse(collectNode.isDistinctCommand);
|
|
|
|
assertEqual(2, collectNode.groups.length);
|
|
assertEqual(1, collectNode.aggregates.length);
|
|
assertEqual("LENGTH", collectNode.aggregates[0].type);
|
|
|
|
collectNode = collectNodes[1];
|
|
}
|
|
assertEqual("hash", collectNode.collectOptions.method);
|
|
assertFalse(collectNode.count);
|
|
assertFalse(collectNode.isDistinctCommand);
|
|
|
|
assertEqual(2, collectNode.groups.length);
|
|
assertEqual("group1", collectNode.groups[0].outVariable.name);
|
|
assertEqual("group2", collectNode.groups[1].outVariable.name);
|
|
|
|
assertEqual(1, collectNode.aggregates.length);
|
|
assertEqual("length", collectNode.aggregates[0].outVariable.name);
|
|
assertEqual(isCluster ? "SUM" : "LENGTH", collectNode.aggregates[0].type);
|
|
},
|
|
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
/// @brief test aggregate
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
|
|
testCross : function () {
|
|
var query = "FOR i IN " + c.name() + " COLLECT group = i.group AGGREGATE total = LENGTH(1), c100 = SUM(i.value1 >= 100 ? 1 : 0), c500 = SUM(i.value1 >= 500 ? 1 : 0), c1000 = SUM(i.value1 >= 1000 ? 1 : null) RETURN { group, total, c100, c500, c1000 }";
|
|
|
|
var results = AQL_EXECUTE(query);
|
|
assertEqual(10, results.json.length);
|
|
for (var i = 0; i < 10; ++i) {
|
|
assertEqual("test" + i, results.json[i].group);
|
|
assertEqual(200, results.json[i].total);
|
|
assertEqual(190, results.json[i].c100);
|
|
assertEqual(150, results.json[i].c500);
|
|
assertEqual(100, results.json[i].c1000);
|
|
}
|
|
|
|
var plan = AQL_EXPLAIN(query).plan;
|
|
// must have a SortNode
|
|
assertNotEqual(-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("hash", collectNode.collectOptions.method);
|
|
assertFalse(collectNode.count);
|
|
assertFalse(collectNode.isDistinctCommand);
|
|
|
|
assertEqual(1, collectNode.groups.length);
|
|
assertEqual(4, collectNode.aggregates.length);
|
|
assertEqual("LENGTH", collectNode.aggregates[0].type);
|
|
assertEqual("SUM", collectNode.aggregates[1].type);
|
|
assertEqual("SUM", collectNode.aggregates[2].type);
|
|
assertEqual("SUM", collectNode.aggregates[3].type);
|
|
|
|
collectNode = collectNodes[1];
|
|
}
|
|
assertEqual("hash", collectNode.collectOptions.method);
|
|
assertFalse(collectNode.count);
|
|
assertFalse(collectNode.isDistinctCommand);
|
|
|
|
assertEqual(1, collectNode.groups.length);
|
|
assertEqual("group", collectNode.groups[0].outVariable.name);
|
|
|
|
assertEqual(4, collectNode.aggregates.length);
|
|
assertEqual("total", collectNode.aggregates[0].outVariable.name);
|
|
assertEqual(isCluster ? "SUM" : "LENGTH", collectNode.aggregates[0].type);
|
|
assertEqual("c100", collectNode.aggregates[1].outVariable.name);
|
|
assertEqual("SUM", collectNode.aggregates[1].type);
|
|
assertEqual("c500", collectNode.aggregates[2].outVariable.name);
|
|
assertEqual("SUM", collectNode.aggregates[2].type);
|
|
assertEqual("c1000", collectNode.aggregates[3].outVariable.name);
|
|
assertEqual("SUM", collectNode.aggregates[3].type);
|
|
},
|
|
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
/// @brief test min
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
|
|
testMinEmpty : function () {
|
|
var query = "FOR i IN [ ] COLLECT AGGREGATE m = MIN(i) RETURN m";
|
|
|
|
var results = AQL_EXECUTE(query);
|
|
assertEqual(1, results.json.length);
|
|
assertNull(results.json[0]);
|
|
assertEqual(results.json[0], AQL_EXECUTE("RETURN MIN([ ])").json[0]);
|
|
},
|
|
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
/// @brief test min
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
|
|
testMinOnlyNull : function () {
|
|
var query = "FOR i IN [ null, null, null, null ] COLLECT AGGREGATE m = MIN(i) RETURN m";
|
|
|
|
var results = AQL_EXECUTE(query);
|
|
assertEqual(1, results.json.length);
|
|
assertNull(results.json[0]);
|
|
assertEqual(results.json[0], AQL_EXECUTE("RETURN MIN([ null, null, null, null ])").json[0]);
|
|
},
|
|
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
/// @brief test min
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
|
|
testMinNotOnlyNullButStartsWithNull : function () {
|
|
var query = "FOR i IN [ null, null, null, null, 35 ] COLLECT AGGREGATE m = MIN(i) RETURN m";
|
|
|
|
var results = AQL_EXECUTE(query);
|
|
assertEqual(1, results.json.length);
|
|
assertEqual(35, results.json[0]);
|
|
assertEqual(results.json[0], AQL_EXECUTE("RETURN MIN([ null, null, null, null, 35 ])").json[0]);
|
|
},
|
|
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
/// @brief test min
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
|
|
testMinMixed : function () {
|
|
var query = "FOR i IN [ 'foo', 'bar', 'baz', true, 'bachelor', null, [ ], false, { }, { zzz: 15 }, { zzz: 2 }, 9999, -9999 ] COLLECT AGGREGATE m = MIN(i) RETURN m";
|
|
|
|
var results = AQL_EXECUTE(query);
|
|
assertEqual(1, results.json.length);
|
|
assertEqual(false, 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"));
|
|
|
|
var collectNode = plan.nodes[plan.nodes.map(function(node) { return node.type; }).indexOf("CollectNode")];
|
|
assertEqual("sorted", collectNode.collectOptions.method);
|
|
assertFalse(collectNode.count);
|
|
assertFalse(collectNode.isDistinctCommand);
|
|
|
|
assertEqual(0, collectNode.groups.length);
|
|
|
|
assertEqual(1, collectNode.aggregates.length);
|
|
assertEqual("m", collectNode.aggregates[0].outVariable.name);
|
|
assertEqual("MIN", collectNode.aggregates[0].type);
|
|
},
|
|
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
/// @brief test min
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
|
|
testMinStrings : function () {
|
|
var query = "FOR i IN [ 'foo', 'bar', 'baz', 'bachelor' ] COLLECT AGGREGATE m = MIN(i) RETURN m";
|
|
|
|
var results = AQL_EXECUTE(query);
|
|
assertEqual(1, results.json.length);
|
|
assertEqual('bachelor', 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"));
|
|
|
|
var collectNode = plan.nodes[plan.nodes.map(function(node) { return node.type; }).indexOf("CollectNode")];
|
|
assertEqual("sorted", collectNode.collectOptions.method);
|
|
assertFalse(collectNode.count);
|
|
assertFalse(collectNode.isDistinctCommand);
|
|
|
|
assertEqual(0, collectNode.groups.length);
|
|
|
|
assertEqual(1, collectNode.aggregates.length);
|
|
assertEqual("m", collectNode.aggregates[0].outVariable.name);
|
|
assertEqual("MIN", collectNode.aggregates[0].type);
|
|
},
|
|
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
/// @brief test max
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
|
|
testMaxEmpty : function () {
|
|
var query = "FOR i IN [ ] COLLECT AGGREGATE m = MAX(i) RETURN m";
|
|
|
|
var results = AQL_EXECUTE(query);
|
|
assertEqual(1, results.json.length);
|
|
assertNull(results.json[0]);
|
|
assertEqual(results.json[0], AQL_EXECUTE("RETURN MAX([ ])").json[0]);
|
|
},
|
|
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
/// @brief test max
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
|
|
testMaxOnlyNull : function () {
|
|
var query = "FOR i IN [ null, null, null, null ] COLLECT AGGREGATE m = MAX(i) RETURN m";
|
|
|
|
var results = AQL_EXECUTE(query);
|
|
assertEqual(1, results.json.length);
|
|
assertNull(results.json[0]);
|
|
assertEqual(results.json[0], AQL_EXECUTE("RETURN MAX([ null, null, null, null ])").json[0]);
|
|
},
|
|
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
/// @brief test max
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
|
|
testMaxMixed : function () {
|
|
var query = "FOR i IN [ 'foo', 'bar', 'baz', true, 'bachelor', null, [ ], false, { }, { zzz: 15 }, { zzz : 2 }, 9999, -9999 ] COLLECT AGGREGATE m = MAX(i) RETURN m";
|
|
|
|
var results = AQL_EXECUTE(query);
|
|
assertEqual(1, results.json.length);
|
|
assertEqual({ zzz : 15 }, 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"));
|
|
|
|
var collectNode = plan.nodes[plan.nodes.map(function(node) { return node.type; }).indexOf("CollectNode")];
|
|
assertEqual("sorted", collectNode.collectOptions.method);
|
|
assertFalse(collectNode.count);
|
|
assertFalse(collectNode.isDistinctCommand);
|
|
|
|
assertEqual(0, collectNode.groups.length);
|
|
|
|
assertEqual(1, collectNode.aggregates.length);
|
|
assertEqual("m", collectNode.aggregates[0].outVariable.name);
|
|
assertEqual("MAX", collectNode.aggregates[0].type);
|
|
},
|
|
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
/// @brief test max
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
|
|
testMaxStrings : function () {
|
|
var query = "FOR i IN [ 'foo', 'bar', 'baz', 'bachelor' ] COLLECT AGGREGATE m = MAX(i) RETURN m";
|
|
|
|
var results = AQL_EXECUTE(query);
|
|
assertEqual(1, results.json.length);
|
|
assertEqual('foo', 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"));
|
|
|
|
var collectNode = plan.nodes[plan.nodes.map(function(node) { return node.type; }).indexOf("CollectNode")];
|
|
assertEqual("sorted", collectNode.collectOptions.method);
|
|
assertFalse(collectNode.count);
|
|
assertFalse(collectNode.isDistinctCommand);
|
|
|
|
assertEqual(0, collectNode.groups.length);
|
|
|
|
assertEqual(1, collectNode.aggregates.length);
|
|
assertEqual("m", collectNode.aggregates[0].outVariable.name);
|
|
assertEqual("MAX", collectNode.aggregates[0].type);
|
|
},
|
|
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
/// @brief test sum
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
|
|
testSumEmpty : function () {
|
|
var query = "FOR i IN [ ] COLLECT AGGREGATE m = SUM(i) RETURN m";
|
|
|
|
var results = AQL_EXECUTE(query);
|
|
assertEqual(1, results.json.length);
|
|
assertNull(results.json[0]);
|
|
// notable difference: regular SUM([ ]) returns 0, but as an aggregate
|
|
// function it returns null
|
|
assertEqual(0, AQL_EXECUTE("RETURN SUM([ ])").json[0]);
|
|
},
|
|
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
/// @brief test sum
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
|
|
testSumOnlyNull : function () {
|
|
var query = "FOR i IN [ null, null, null, null ] COLLECT AGGREGATE m = SUM(i) RETURN m";
|
|
|
|
var results = AQL_EXECUTE(query);
|
|
assertEqual(1, results.json.length);
|
|
assertEqual(0, results.json[0]);
|
|
assertEqual(results.json[0], AQL_EXECUTE("RETURN SUM([ null, null, null, null ])").json[0]);
|
|
},
|
|
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
/// @brief test sum
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
|
|
testSumMixed : function () {
|
|
var query = "FOR i IN [ 'foo', 'bar', 'baz', true, 'bachelor', null, [ ], false, { }, { zzz: 1 }, { aaa : 2 }, 9999, -9999 ] COLLECT AGGREGATE m = SUM(i) RETURN m";
|
|
|
|
var results = AQL_EXECUTE(query);
|
|
assertEqual(1, results.json.length);
|
|
assertNull(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"));
|
|
|
|
var collectNode = plan.nodes[plan.nodes.map(function(node) { return node.type; }).indexOf("CollectNode")];
|
|
assertEqual("sorted", collectNode.collectOptions.method);
|
|
assertFalse(collectNode.count);
|
|
assertFalse(collectNode.isDistinctCommand);
|
|
|
|
assertEqual(0, collectNode.groups.length);
|
|
|
|
assertEqual(1, collectNode.aggregates.length);
|
|
assertEqual("m", collectNode.aggregates[0].outVariable.name);
|
|
assertEqual("SUM", collectNode.aggregates[0].type);
|
|
},
|
|
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
/// @brief test sum
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
|
|
testSumNumbers : function () {
|
|
var values = [ 1, 42, 23, 19.5, 4, -28 ];
|
|
var expected = values.reduce(function(a, b) { return a + b; }, 0);
|
|
var query = "FOR i IN " + JSON.stringify(values) + " COLLECT AGGREGATE m = SUM(i) RETURN m";
|
|
|
|
var results = AQL_EXECUTE(query);
|
|
assertEqual(1, results.json.length);
|
|
assertEqual(expected, results.json[0]);
|
|
assertEqual(expected, AQL_EXECUTE("RETURN SUM(" + JSON.stringify(values) + ")").json[0]);
|
|
},
|
|
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
/// @brief test avg
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
|
|
testAvgEmpty : function () {
|
|
var query = "FOR i IN [ ] COLLECT AGGREGATE m = AVERAGE(i) RETURN m";
|
|
|
|
var results = AQL_EXECUTE(query);
|
|
assertEqual(1, results.json.length);
|
|
assertNull(results.json[0]);
|
|
assertEqual(results.json[0], AQL_EXECUTE("RETURN AVERAGE([ ])").json[0]);
|
|
},
|
|
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
/// @brief test avg
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
|
|
testAvgOnlyNull : function () {
|
|
var query = "FOR i IN [ null, null, null, null ] COLLECT AGGREGATE m = AVERAGE(i) RETURN m";
|
|
|
|
var results = AQL_EXECUTE(query);
|
|
assertEqual(1, results.json.length);
|
|
assertNull(results.json[0]);
|
|
assertEqual(results.json[0], AQL_EXECUTE("RETURN AVERAGE([ null, null, null, null ])").json[0]);
|
|
},
|
|
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
/// @brief test avg
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
|
|
testAvgSingle : function () {
|
|
var query = "FOR i IN [ -42.5 ] COLLECT AGGREGATE m = AVERAGE(i) RETURN m";
|
|
|
|
var results = AQL_EXECUTE(query);
|
|
assertEqual(1, results.json.length);
|
|
assertEqual(-42.5, results.json[0]);
|
|
assertEqual(results.json[0], AQL_EXECUTE("RETURN AVERAGE([ -42.5 ])").json[0]);
|
|
},
|
|
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
/// @brief test avg
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
|
|
testAvgSingleString : function () {
|
|
var query = "FOR i IN [ '-42.5foo' ] COLLECT AGGREGATE m = AVERAGE(i) RETURN m";
|
|
|
|
var results = AQL_EXECUTE(query);
|
|
assertEqual(1, results.json.length);
|
|
assertNull(results.json[0]);
|
|
assertEqual(results.json[0], AQL_EXECUTE("RETURN AVERAGE([ '-42.5foo' ])").json[0]);
|
|
},
|
|
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
/// @brief test avg
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
|
|
testAvgSingleWithNulls : function () {
|
|
var query = "FOR i IN [ -42.5, null, null, null ] COLLECT AGGREGATE m = AVERAGE(i) RETURN m";
|
|
|
|
var results = AQL_EXECUTE(query);
|
|
assertEqual(1, results.json.length);
|
|
assertEqual(-42.5, results.json[0]);
|
|
assertEqual(results.json[0], AQL_EXECUTE("RETURN AVERAGE([ -42.5, null, null, null ])").json[0]);
|
|
},
|
|
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
/// @brief test avg
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
|
|
testAvgMixed : function () {
|
|
var query = "FOR i IN [ 'foo', 'bar', 'baz', true, 'bachelor', null, [ ], false, { }, { zzz: 1 }, { aaa : 2 }, 9999, -9999 ] COLLECT AGGREGATE m = AVERAGE(i) RETURN m";
|
|
|
|
var results = AQL_EXECUTE(query);
|
|
assertEqual(1, results.json.length);
|
|
assertNull(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"));
|
|
|
|
var collectNode = plan.nodes[plan.nodes.map(function(node) { return node.type; }).indexOf("CollectNode")];
|
|
assertEqual("sorted", collectNode.collectOptions.method);
|
|
assertFalse(collectNode.count);
|
|
assertFalse(collectNode.isDistinctCommand);
|
|
|
|
assertEqual(0, collectNode.groups.length);
|
|
|
|
assertEqual(1, collectNode.aggregates.length);
|
|
assertEqual("m", collectNode.aggregates[0].outVariable.name);
|
|
assertEqual("AVERAGE", collectNode.aggregates[0].type);
|
|
},
|
|
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
/// @brief test avg
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
|
|
testAvgNumbers : function () {
|
|
var values = [ 1, 42, 23, 19.5, 4, -28 ];
|
|
var expected = values.reduce(function(a, b) { return a + b; }, 0);
|
|
var query = "FOR i IN " + JSON.stringify(values) + " COLLECT AGGREGATE m = AVERAGE(i) RETURN m";
|
|
|
|
var results = AQL_EXECUTE(query);
|
|
assertEqual(1, results.json.length);
|
|
assertEqual(expected / 6, results.json[0]);
|
|
assertEqual(results.json[0], AQL_EXECUTE("RETURN AVERAGE(" + JSON.stringify(values) + ")").json[0]);
|
|
},
|
|
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
/// @brief test variance
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
|
|
testVarianceEmpty : function () {
|
|
var query = "FOR i IN [ ] COLLECT AGGREGATE m = VARIANCE(i) RETURN m";
|
|
|
|
var results = AQL_EXECUTE(query);
|
|
assertEqual(1, results.json.length);
|
|
assertNull(results.json[0]);
|
|
assertEqual(results.json[0], AQL_EXECUTE("RETURN VARIANCE([ ])").json[0]);
|
|
},
|
|
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
/// @brief test variance
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
|
|
testVarianceSampleEmpty : function () {
|
|
var query = "FOR i IN [ ] COLLECT AGGREGATE m = VARIANCE_SAMPLE(i) RETURN m";
|
|
|
|
var results = AQL_EXECUTE(query);
|
|
assertEqual(1, results.json.length);
|
|
assertNull(results.json[0]);
|
|
assertEqual(results.json[0], AQL_EXECUTE("RETURN VARIANCE_SAMPLE([ ])").json[0]);
|
|
},
|
|
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
/// @brief test variance
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
|
|
testVarianceOnlyNull : function () {
|
|
var query = "FOR i IN [ null, null, null, null ] COLLECT AGGREGATE m = VARIANCE(i) RETURN m";
|
|
|
|
var results = AQL_EXECUTE(query);
|
|
assertEqual(1, results.json.length);
|
|
assertNull(results.json[0]);
|
|
assertEqual(results.json[0], AQL_EXECUTE("RETURN VARIANCE([ null, null, null, null ])").json[0]);
|
|
},
|
|
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
/// @brief test variance
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
|
|
testVarianceSampleOnlyNull : function () {
|
|
var query = "FOR i IN [ null, null, null, null ] COLLECT AGGREGATE m = VARIANCE_SAMPLE(i) RETURN m";
|
|
|
|
var results = AQL_EXECUTE(query);
|
|
assertEqual(1, results.json.length);
|
|
assertNull(results.json[0]);
|
|
assertEqual(results.json[0], AQL_EXECUTE("RETURN VARIANCE_SAMPLE([ null, null, null, null ])").json[0]);
|
|
},
|
|
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
/// @brief test variance
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
|
|
testVarianceSingle : function () {
|
|
var query = "FOR i IN [ -42.5 ] COLLECT AGGREGATE m = VARIANCE(i) RETURN m";
|
|
|
|
var results = AQL_EXECUTE(query);
|
|
assertEqual(1, results.json.length);
|
|
assertEqual(0, results.json[0]);
|
|
assertEqual(results.json[0], AQL_EXECUTE("RETURN VARIANCE([ -42.5 ])").json[0]);
|
|
},
|
|
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
/// @brief test variance
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
|
|
testVarianceSampleSingle : function () {
|
|
var query = "FOR i IN [ -42.5 ] COLLECT AGGREGATE m = VARIANCE_SAMPLE(i) RETURN m";
|
|
|
|
var results = AQL_EXECUTE(query);
|
|
assertEqual(1, results.json.length);
|
|
assertNull(results.json[0]);
|
|
assertEqual(results.json[0], AQL_EXECUTE("RETURN VARIANCE_SAMPLE([ -42.5 ])").json[0]);
|
|
},
|
|
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
/// @brief test variance
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
|
|
testVarianceSampleSingleWithNull : function () {
|
|
var query = "FOR i IN [ -42.5, null ] COLLECT AGGREGATE m = VARIANCE_SAMPLE(i) RETURN m";
|
|
|
|
var results = AQL_EXECUTE(query);
|
|
assertEqual(1, results.json.length);
|
|
assertNull(results.json[0]);
|
|
assertEqual(results.json[0], AQL_EXECUTE("RETURN VARIANCE_SAMPLE([ -42.5, null ])").json[0]);
|
|
},
|
|
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
/// @brief test variance
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
|
|
testVarianceSampleTwoValues : function () {
|
|
var query = "FOR i IN [ 19, 23 ] COLLECT AGGREGATE m = VARIANCE(i) RETURN m";
|
|
|
|
var results = AQL_EXECUTE(query);
|
|
assertEqual(1, results.json.length);
|
|
assertEqual(4, results.json[0]);
|
|
assertEqual(results.json[0], AQL_EXECUTE("RETURN VARIANCE([ 19, 23 ])").json[0]);
|
|
},
|
|
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
/// @brief test variance
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
|
|
testVarianceSampleSingleTwoValues : function () {
|
|
var query = "FOR i IN [ 19, 23 ] COLLECT AGGREGATE m = VARIANCE_SAMPLE(i) RETURN m";
|
|
|
|
var results = AQL_EXECUTE(query);
|
|
assertEqual(1, results.json.length);
|
|
assertEqual(8, results.json[0]);
|
|
assertEqual(results.json[0], AQL_EXECUTE("RETURN VARIANCE_SAMPLE([ 19, 23 ])").json[0]);
|
|
},
|
|
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
/// @brief test variance
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
|
|
testVarianceSingleString : function () {
|
|
var query = "FOR i IN [ '-42.5foo' ] COLLECT AGGREGATE m = VARIANCE(i) RETURN m";
|
|
|
|
var results = AQL_EXECUTE(query);
|
|
assertEqual(1, results.json.length);
|
|
assertNull(results.json[0]);
|
|
assertEqual(results.json[0], AQL_EXECUTE("RETURN VARIANCE([ '-42.5foo' ])").json[0]);
|
|
},
|
|
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
/// @brief test variance
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
|
|
testVarianceSampleSingleString : function () {
|
|
var query = "FOR i IN [ '-42.5foo' ] COLLECT AGGREGATE m = VARIANCE_SAMPLE(i) RETURN m";
|
|
|
|
var results = AQL_EXECUTE(query);
|
|
assertEqual(1, results.json.length);
|
|
assertNull(results.json[0]);
|
|
assertEqual(results.json[0], AQL_EXECUTE("RETURN VARIANCE_SAMPLE([ '-42.5foo' ])").json[0]);
|
|
},
|
|
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
/// @brief test variance
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
|
|
testVarianceSampleTwoStrings : function () {
|
|
var query = "FOR i IN [ '-42.5foo', '99baz' ] COLLECT AGGREGATE m = VARIANCE_SAMPLE(i) RETURN m";
|
|
|
|
var results = AQL_EXECUTE(query);
|
|
assertEqual(1, results.json.length);
|
|
assertNull(results.json[0]);
|
|
assertEqual(results.json[0], AQL_EXECUTE("RETURN VARIANCE_SAMPLE([ '-42.5foo', '99baz' ])").json[0]);
|
|
},
|
|
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
/// @brief test variance
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
|
|
testVarianceSingleWithNulls : function () {
|
|
var query = "FOR i IN [ -42.5, null, null, null ] COLLECT AGGREGATE m = VARIANCE(i) RETURN m";
|
|
|
|
var results = AQL_EXECUTE(query);
|
|
assertEqual(1, results.json.length);
|
|
assertEqual(0, results.json[0]);
|
|
assertEqual(results.json[0], AQL_EXECUTE("RETURN VARIANCE([ -42.5, null, null, null ])").json[0]);
|
|
},
|
|
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
/// @brief test variance
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
|
|
testVarianceSampleSingleWithNulls : function () {
|
|
var query = "FOR i IN [ -42.5, null, null, null ] COLLECT AGGREGATE m = VARIANCE_SAMPLE(i) RETURN m";
|
|
|
|
var results = AQL_EXECUTE(query);
|
|
assertEqual(1, results.json.length);
|
|
assertNull(results.json[0]);
|
|
assertEqual(results.json[0], AQL_EXECUTE("RETURN VARIANCE_SAMPLE([ -42.5, null, null, null ])").json[0]);
|
|
},
|
|
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
/// @brief test variance
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
|
|
testVarianceMixed : function () {
|
|
var query = "FOR i IN [ 'foo', 'bar', 'baz', true, 'bachelor', null, [ ], false, { }, { zzz: 1 }, { aaa : 2 }, 9999, -9999 ] COLLECT AGGREGATE m = VARIANCE(i) RETURN m";
|
|
|
|
var results = AQL_EXECUTE(query);
|
|
assertEqual(1, results.json.length);
|
|
assertNull(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"));
|
|
|
|
var collectNode = plan.nodes[plan.nodes.map(function(node) { return node.type; }).indexOf("CollectNode")];
|
|
assertEqual("sorted", collectNode.collectOptions.method);
|
|
assertFalse(collectNode.count);
|
|
assertFalse(collectNode.isDistinctCommand);
|
|
|
|
assertEqual(0, collectNode.groups.length);
|
|
|
|
assertEqual(1, collectNode.aggregates.length);
|
|
assertEqual("m", collectNode.aggregates[0].outVariable.name);
|
|
assertEqual("VARIANCE_POPULATION", collectNode.aggregates[0].type);
|
|
},
|
|
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
/// @brief test variance
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
|
|
testVarianceNumbers : function () {
|
|
var values = [ 1, 2, 3, 4, null, 23, 42, 19, 32, 44, -34];
|
|
var expected = 495.03999999999996;
|
|
var query = "FOR i IN " + JSON.stringify(values) + " COLLECT AGGREGATE m = VARIANCE(i) RETURN m";
|
|
|
|
var results = AQL_EXECUTE(query);
|
|
assertEqual(1, results.json.length);
|
|
assertTrue(Math.abs(expected - results.json[0]) < 0.01);
|
|
assertTrue(Math.abs(results.json[0] - AQL_EXECUTE("RETURN VARIANCE(" + JSON.stringify(values) + ")").json[0]) < 0.01);
|
|
},
|
|
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
/// @brief test variance
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
|
|
testVarianceSampleNumbers : function () {
|
|
var values = [ 1, 2, 3, 4, null, 23, 42, 19, 32, 44, -34];
|
|
var expected = 550.0444444444444;
|
|
var query = "FOR i IN " + JSON.stringify(values) + " COLLECT AGGREGATE m = VARIANCE_SAMPLE(i) RETURN m";
|
|
|
|
var results = AQL_EXECUTE(query);
|
|
assertEqual(1, results.json.length);
|
|
assertTrue(Math.abs(expected - results.json[0]) < 0.01);
|
|
assertTrue(Math.abs(results.json[0] - AQL_EXECUTE("RETURN VARIANCE_SAMPLE(" + JSON.stringify(values) + ")").json[0]) < 0.01);
|
|
},
|
|
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
/// @brief test variance
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
|
|
testVarianceNumbersOthers : function () {
|
|
var values = [ 1, 42, 23, 19.5, 4, -28 ];
|
|
var expected = 473.9791666666667;
|
|
var query = "FOR i IN " + JSON.stringify(values) + " COLLECT AGGREGATE m = VARIANCE(i) RETURN m";
|
|
|
|
var results = AQL_EXECUTE(query);
|
|
assertEqual(1, results.json.length);
|
|
assertTrue(Math.abs(expected - results.json[0]) < 0.01);
|
|
assertTrue(Math.abs(results.json[0] - AQL_EXECUTE("RETURN VARIANCE(" + JSON.stringify(values) + ")").json[0]) < 0.01);
|
|
},
|
|
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
/// @brief test variance
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
|
|
testVarianceSampleNumbersOthers : function () {
|
|
var values = [ 1, 42, 23, 19.5, 4, -28 ];
|
|
var expected = 568.775;
|
|
var query = "FOR i IN " + JSON.stringify(values) + " COLLECT AGGREGATE m = VARIANCE_SAMPLE(i) RETURN m";
|
|
|
|
var results = AQL_EXECUTE(query);
|
|
assertEqual(1, results.json.length);
|
|
assertTrue(Math.abs(expected - results.json[0]) < 0.01);
|
|
assertTrue(Math.abs(results.json[0] - AQL_EXECUTE("RETURN VARIANCE_SAMPLE(" + JSON.stringify(values) + ")").json[0]) < 0.01);
|
|
},
|
|
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
/// @brief test stddev
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
|
|
testStddevEmpty : function () {
|
|
var query = "FOR i IN [ ] COLLECT AGGREGATE m = STDDEV(i) RETURN m";
|
|
|
|
var results = AQL_EXECUTE(query);
|
|
assertEqual(1, results.json.length);
|
|
assertNull(results.json[0]);
|
|
assertEqual(results.json[0], AQL_EXECUTE("RETURN STDDEV([ ])").json[0]);
|
|
},
|
|
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
/// @brief test stddev
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
|
|
testStddevSampleEmpty : function () {
|
|
var query = "FOR i IN [ ] COLLECT AGGREGATE m = STDDEV_SAMPLE(i) RETURN m";
|
|
|
|
var results = AQL_EXECUTE(query);
|
|
assertEqual(1, results.json.length);
|
|
assertNull(results.json[0]);
|
|
assertEqual(results.json[0], AQL_EXECUTE("RETURN STDDEV_SAMPLE([ ])").json[0]);
|
|
},
|
|
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
/// @brief test stddev
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
|
|
testStddevOnlyNull : function () {
|
|
var query = "FOR i IN [ null, null, null, null ] COLLECT AGGREGATE m = STDDEV(i) RETURN m";
|
|
|
|
var results = AQL_EXECUTE(query);
|
|
assertEqual(1, results.json.length);
|
|
assertNull(results.json[0]);
|
|
assertEqual(results.json[0], AQL_EXECUTE("RETURN STDDEV([ null, null, null, null ])").json[0]);
|
|
},
|
|
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
/// @brief test stddev
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
|
|
testStddevSampleOnlyNull : function () {
|
|
var query = "FOR i IN [ null, null, null, null ] COLLECT AGGREGATE m = STDDEV_SAMPLE(i) RETURN m";
|
|
|
|
var results = AQL_EXECUTE(query);
|
|
assertEqual(1, results.json.length);
|
|
assertNull(results.json[0]);
|
|
assertEqual(results.json[0], AQL_EXECUTE("RETURN STDDEV_SAMPLE([ null, null, null, null ])").json[0]);
|
|
},
|
|
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
/// @brief test stddev
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
|
|
testStddevSingle : function () {
|
|
var query = "FOR i IN [ -42.5 ] COLLECT AGGREGATE m = STDDEV(i) RETURN m";
|
|
|
|
var results = AQL_EXECUTE(query);
|
|
assertEqual(1, results.json.length);
|
|
assertEqual(0, results.json[0]);
|
|
assertEqual(results.json[0], AQL_EXECUTE("RETURN STDDEV([ -42.5 ])").json[0]);
|
|
},
|
|
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
/// @brief test stddev
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
|
|
testStddevSampleSingle : function () {
|
|
var query = "FOR i IN [ -42.5 ] COLLECT AGGREGATE m = STDDEV_SAMPLE(i) RETURN m";
|
|
|
|
var results = AQL_EXECUTE(query);
|
|
assertEqual(1, results.json.length);
|
|
assertNull(results.json[0]);
|
|
assertEqual(results.json[0], AQL_EXECUTE("RETURN STDDEV_SAMPLE([ -42.5 ])").json[0]);
|
|
},
|
|
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
/// @brief test stddev
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
|
|
testStddevSampleSingleWithNull : function () {
|
|
var query = "FOR i IN [ -42.5, null ] COLLECT AGGREGATE m = STDDEV_SAMPLE(i) RETURN m";
|
|
|
|
var results = AQL_EXECUTE(query);
|
|
assertEqual(1, results.json.length);
|
|
assertNull(results.json[0]);
|
|
assertEqual(results.json[0], AQL_EXECUTE("RETURN STDDEV_SAMPLE([ -42.5, null ])").json[0]);
|
|
},
|
|
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
/// @brief test stddev
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
|
|
testStddevSampleTwoValues : function () {
|
|
var query = "FOR i IN [ 19, 23 ] COLLECT AGGREGATE m = STDDEV(i) RETURN m";
|
|
|
|
var results = AQL_EXECUTE(query);
|
|
assertEqual(1, results.json.length);
|
|
assertEqual(2, results.json[0]);
|
|
assertEqual(results.json[0], AQL_EXECUTE("RETURN STDDEV([ 19, 23 ])").json[0]);
|
|
},
|
|
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
/// @brief test stddev
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
|
|
testStddevSampleSingleTwoValues : function () {
|
|
var expected = 2.8284271247461903;
|
|
var query = "FOR i IN [ 19, 23 ] COLLECT AGGREGATE m = STDDEV_SAMPLE(i) RETURN m";
|
|
|
|
var results = AQL_EXECUTE(query);
|
|
assertEqual(1, results.json.length);
|
|
assertTrue(Math.abs(results.json[0] - expected) < 0.01);
|
|
assertTrue(Math.abs(results.json[0] - AQL_EXECUTE("RETURN STDDEV_SAMPLE([ 19, 23 ])").json[0]) < 0.01);
|
|
},
|
|
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
/// @brief test stddev
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
|
|
testStddevSingleString : function () {
|
|
var query = "FOR i IN [ '-42.5foo' ] COLLECT AGGREGATE m = STDDEV(i) RETURN m";
|
|
|
|
var results = AQL_EXECUTE(query);
|
|
assertEqual(1, results.json.length);
|
|
assertNull(results.json[0]);
|
|
assertEqual(results.json[0], AQL_EXECUTE("RETURN STDDEV([ '-42.5foo' ])").json[0]);
|
|
},
|
|
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
/// @brief test stddev
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
|
|
testStddevSampleSingleString : function () {
|
|
var query = "FOR i IN [ '-42.5foo' ] COLLECT AGGREGATE m = STDDEV_SAMPLE(i) RETURN m";
|
|
|
|
var results = AQL_EXECUTE(query);
|
|
assertEqual(1, results.json.length);
|
|
assertNull(results.json[0]);
|
|
assertEqual(results.json[0], AQL_EXECUTE("RETURN STDDEV_SAMPLE([ '-42.5foo' ])").json[0]);
|
|
},
|
|
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
/// @brief test stddev
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
|
|
testStddevSampleTwoStrings : function () {
|
|
var query = "FOR i IN [ '-42.5foo', '99baz' ] COLLECT AGGREGATE m = STDDEV_SAMPLE(i) RETURN m";
|
|
|
|
var results = AQL_EXECUTE(query);
|
|
assertEqual(1, results.json.length);
|
|
assertNull(results.json[0]);
|
|
assertEqual(results.json[0], AQL_EXECUTE("RETURN STDDEV_SAMPLE([ '-42.5foo', '99baz' ])").json[0]);
|
|
},
|
|
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
/// @brief test stddev
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
|
|
testStddevSingleWithNulls : function () {
|
|
var query = "FOR i IN [ -42.5, null, null, null ] COLLECT AGGREGATE m = STDDEV(i) RETURN m";
|
|
|
|
var results = AQL_EXECUTE(query);
|
|
assertEqual(1, results.json.length);
|
|
assertEqual(0, results.json[0]);
|
|
assertEqual(results.json[0], AQL_EXECUTE("RETURN STDDEV([ -42.5, null, null, null ])").json[0]);
|
|
},
|
|
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
/// @brief test stddev
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
|
|
testStddevSampleSingleWithNulls : function () {
|
|
var query = "FOR i IN [ -42.5, null, null, null ] COLLECT AGGREGATE m = STDDEV_SAMPLE(i) RETURN m";
|
|
|
|
var results = AQL_EXECUTE(query);
|
|
assertEqual(1, results.json.length);
|
|
assertNull(results.json[0]);
|
|
assertEqual(results.json[0], AQL_EXECUTE("RETURN STDDEV_SAMPLE([ -42.5, null, null, null ])").json[0]);
|
|
},
|
|
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
/// @brief test stddev
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
|
|
testStddevMixed : function () {
|
|
var query = "FOR i IN [ 'foo', 'bar', 'baz', true, 'bachelor', null, [ ], false, { }, { zzz: 1 }, { aaa : 2 }, 9999, -9999 ] COLLECT AGGREGATE m = STDDEV(i) RETURN m";
|
|
|
|
var results = AQL_EXECUTE(query);
|
|
assertEqual(1, results.json.length);
|
|
assertNull(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"));
|
|
|
|
var collectNode = plan.nodes[plan.nodes.map(function(node) { return node.type; }).indexOf("CollectNode")];
|
|
assertEqual("sorted", collectNode.collectOptions.method);
|
|
assertFalse(collectNode.count);
|
|
assertFalse(collectNode.isDistinctCommand);
|
|
|
|
assertEqual(0, collectNode.groups.length);
|
|
|
|
assertEqual(1, collectNode.aggregates.length);
|
|
assertEqual("m", collectNode.aggregates[0].outVariable.name);
|
|
assertEqual("STDDEV_POPULATION", collectNode.aggregates[0].type);
|
|
},
|
|
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
/// @brief test stddev
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
|
|
testStddevNumbers : function () {
|
|
var values = [ 1, 2, 3, 4, null, 23, 42, 19, 32, 44, -34];
|
|
var expected = 22.249494376277408;
|
|
var query = "FOR i IN " + JSON.stringify(values) + " COLLECT AGGREGATE m = STDDEV(i) RETURN m";
|
|
|
|
var results = AQL_EXECUTE(query);
|
|
assertEqual(1, results.json.length);
|
|
assertTrue(Math.abs(expected - results.json[0]) < 0.01);
|
|
assertTrue(Math.abs(results.json[0] - AQL_EXECUTE("RETURN STDDEV(" + JSON.stringify(values) + ")").json[0]) < 0.01);
|
|
},
|
|
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
/// @brief test stddev
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
|
|
testStddevSampleNumbers : function () {
|
|
var values = [ 1, 2, 3, 4, null, 23, 42, 19, 32, 44, -34];
|
|
var expected = 23.453026338714675;
|
|
var query = "FOR i IN " + JSON.stringify(values) + " COLLECT AGGREGATE m = STDDEV_SAMPLE(i) RETURN m";
|
|
|
|
var results = AQL_EXECUTE(query);
|
|
assertEqual(1, results.json.length);
|
|
assertTrue(Math.abs(expected - results.json[0]) < 0.01);
|
|
assertTrue(Math.abs(results.json[0] - AQL_EXECUTE("RETURN STDDEV_SAMPLE(" + JSON.stringify(values) + ")").json[0]) < 0.01);
|
|
},
|
|
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
/// @brief test stddev
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
|
|
testStddevNumbersOthers : function () {
|
|
var values = [ 1, 42, 23, 19.5, 4, -28 ];
|
|
var expected = 21.771062598473844;
|
|
var query = "FOR i IN " + JSON.stringify(values) + " COLLECT AGGREGATE m = STDDEV(i) RETURN m";
|
|
|
|
var results = AQL_EXECUTE(query);
|
|
assertEqual(1, results.json.length);
|
|
assertTrue(Math.abs(expected - results.json[0]) < 0.01);
|
|
assertTrue(Math.abs(results.json[0] - AQL_EXECUTE("RETURN STDDEV(" + JSON.stringify(values) + ")").json[0]) < 0.01);
|
|
},
|
|
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
/// @brief test stddev
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
|
|
testStddevSampleNumbersOthers : function () {
|
|
var values = [ 1, 42, 23, 19.5, 4, -28 ];
|
|
var expected = 23.84900417208232;
|
|
var query = "FOR i IN " + JSON.stringify(values) + " COLLECT AGGREGATE m = STDDEV_SAMPLE(i) RETURN m";
|
|
|
|
var results = AQL_EXECUTE(query);
|
|
assertEqual(1, results.json.length);
|
|
assertTrue(Math.abs(expected - results.json[0]) < 0.01);
|
|
assertTrue(Math.abs(results.json[0] - AQL_EXECUTE("RETURN STDDEV_SAMPLE(" + JSON.stringify(values) + ")").json[0]) < 0.01);
|
|
}
|
|
|
|
};
|
|
}
|
|
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
/// @brief test suite
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
|
|
function optimizerAggregateCollectionTestSuite () {
|
|
return {
|
|
setUp : function () {
|
|
db._drop("UnitTestsCollectionA");
|
|
var c = db._create("UnitTestsCollectionA");
|
|
|
|
var values = [
|
|
{ "_key" : "t1" },
|
|
{ "_key" : "t2" },
|
|
{ "_key" : "t3" }
|
|
];
|
|
values.forEach(function(doc) {
|
|
c.insert(doc);
|
|
|
|
});
|
|
|
|
db._drop("UnitTestsCollectionB");
|
|
c = db._create("UnitTestsCollectionB");
|
|
|
|
values = [
|
|
{ "tlm" : 1456480062167, "ct" : 0, "rev" : "t2", "_key" : "5" },
|
|
{ "tlm" : 1460377620213, "ct" : 0, "rev" : "t3", "_key" : "14" },
|
|
{ "tlm" : 1456480264467, "ct" : 0, "rev" : "t2", "_key" : "6" },
|
|
{ "tlm" : 1461698920149, "ct" : 0, "rev" : "t1", "_key" : "17" },
|
|
{ "tlm" : 1455815267983, "ct" : 0, "rev" : "t2", "_key" : "3" },
|
|
{ "tlm" : 1457427632487, "ct" : 0, "rev" : "t2", "_key" : "12" },
|
|
{ "tlm" : 1455867727519, "ct" : 0, "rev" : "t2", "_key" : "4" },
|
|
{ "tlm" : 1461697990707, "ct" : 0, "rev" : "t1", "_key" : "15" },
|
|
{ "tlm" : 1455867750978, "ct" : 0, "rev" : "t2", "_key" : "1" },
|
|
{ "tlm" : 1457340889219, "ct" : 0, "rev" : "t2", "_key" : "10" },
|
|
{ "tlm" : 1456488586444, "ct" : 0, "rev" : "t3", "_key" : "9" },
|
|
{ "tlm" : 1461876187642, "ct" : 0, "rev" : "t3", "_key" : "18" },
|
|
{ "tlm" : 1455878231589, "ct" : 0, "rev" : "t2", "_key" : "2" },
|
|
{ "tlm" : 1463214385088, "ct" : 5, "rev" : "t2", "_key" : "13" },
|
|
{ "tlm" : 1463216196030, "ct" : 1, "rev" : "t2", "_key" : "7" },
|
|
{ "tlm" : 1461698190283, "ct" : 0, "rev" : "t1", "_key" : "16" },
|
|
{ "tlm" : 1460381974860, "ct" : 0, "rev" : "t2", "_key" : "11" },
|
|
{ "tlm" : 1460382104593, "ct" : 0, "rev" : "t3", "_key" : "8" }
|
|
];
|
|
|
|
values.forEach(function(doc) {
|
|
c.insert(doc);
|
|
});
|
|
},
|
|
|
|
tearDown : function () {
|
|
db._drop("UnitTestsCollectionA");
|
|
db._drop("UnitTestsCollectionB");
|
|
},
|
|
|
|
testWithData : function () {
|
|
var query = "FOR a IN UnitTestsCollectionA LET c = (FOR b IN UnitTestsCollectionB FILTER b.rev == a._key && b.tlm > NOOPT(1463476452512) - 864000000 COLLECT AGGREGATE t = SUM(b.ct) RETURN t)[0] UPDATE a WITH {c} IN UnitTestsCollectionA RETURN NEW";
|
|
var results = AQL_EXECUTE(query).json;
|
|
assertEqual(3, results.length); // should just work
|
|
}
|
|
};
|
|
}
|
|
|
|
function optimizerAggregateResultsSuite () {
|
|
const opt = { optimizer: { rules: ["-collect-in-cluster"] } };
|
|
let compare = function(query) {
|
|
let expected = AQL_EXECUTE(query, null, opt).json[0];
|
|
if (typeof expected === 'number') {
|
|
expected = expected.toFixed(6);
|
|
}
|
|
|
|
let plan = AQL_EXPLAIN(query, null, opt).plan;
|
|
let collectNodes = plan.nodes.filter(function(node) { return node.type === 'CollectNode'; });
|
|
assertEqual(1, collectNodes.length);
|
|
assertEqual(-1, plan.rules.indexOf("collect-in-cluster"));
|
|
|
|
let actual = AQL_EXECUTE(query).json[0];
|
|
if (typeof actual === 'number') {
|
|
actual = actual.toFixed(6);
|
|
}
|
|
assertEqual(expected, actual, query);
|
|
|
|
plan = AQL_EXPLAIN(query).plan;
|
|
collectNodes = plan.nodes.filter(function(node) { return node.type === 'CollectNode'; });
|
|
assertEqual(2, collectNodes.length);
|
|
assertNotEqual(-1, plan.rules.indexOf("collect-in-cluster"));
|
|
};
|
|
|
|
let c;
|
|
|
|
return {
|
|
setUp : function () {
|
|
db._drop("UnitTestsCollection");
|
|
c = db._create("UnitTestsCollection", { numberOfShards: 5 });
|
|
|
|
for (var i = 0; i < 2000; ++i) {
|
|
c.save({ group: "test" + (i % 10), value1: i, value2: i % 5 });
|
|
}
|
|
},
|
|
|
|
tearDown : function () {
|
|
db._drop("UnitTestsCollection");
|
|
},
|
|
|
|
testCount : function () {
|
|
compare("FOR doc IN " + c.name() + " COLLECT AGGREGATE v = COUNT(doc.value1) RETURN v");
|
|
},
|
|
|
|
testAvg1 : function () {
|
|
compare("FOR doc IN " + c.name() + " COLLECT AGGREGATE v = AVG(doc.value1) RETURN v");
|
|
},
|
|
|
|
testAvg2 : function () {
|
|
compare("FOR doc IN " + c.name() + " COLLECT AGGREGATE v = AVG(doc.value2) RETURN v");
|
|
},
|
|
|
|
testVariance1 : function () {
|
|
compare("FOR doc IN " + c.name() + " COLLECT AGGREGATE v = VARIANCE(doc.value1) RETURN v");
|
|
},
|
|
|
|
testVariance2 : function () {
|
|
compare("FOR doc IN " + c.name() + " COLLECT AGGREGATE v = VARIANCE(doc.value2) RETURN v");
|
|
},
|
|
|
|
testVarianceSample1 : function () {
|
|
compare("FOR doc IN " + c.name() + " COLLECT AGGREGATE v = VARIANCE_SAMPLE(doc.value1) RETURN v");
|
|
},
|
|
|
|
testVarianceSample2 : function () {
|
|
compare("FOR doc IN " + c.name() + " COLLECT AGGREGATE v = VARIANCE_SAMPLE(doc.value2) RETURN v");
|
|
},
|
|
|
|
testStddev1 : function () {
|
|
compare("FOR doc IN " + c.name() + " COLLECT AGGREGATE v = STDDEV(doc.value1) RETURN v");
|
|
},
|
|
|
|
testStddev2 : function () {
|
|
compare("FOR doc IN " + c.name() + " COLLECT AGGREGATE v = STDDEV(doc.value2) RETURN v");
|
|
},
|
|
|
|
testStddevSample1 : function () {
|
|
compare("FOR doc IN " + c.name() + " COLLECT AGGREGATE v = STDDEV_SAMPLE(doc.value1) RETURN v");
|
|
},
|
|
|
|
testStddevSample2 : function () {
|
|
compare("FOR doc IN " + c.name() + " COLLECT AGGREGATE v = STDDEV_SAMPLE(doc.value2) RETURN v");
|
|
},
|
|
|
|
testUnique1 : function () {
|
|
compare("FOR doc IN " + c.name() + " COLLECT AGGREGATE v = UNIQUE(doc.value1) RETURN v");
|
|
},
|
|
|
|
testUnique2 : function () {
|
|
compare("FOR doc IN " + c.name() + " COLLECT AGGREGATE v = UNIQUE(doc.value2) RETURN v");
|
|
},
|
|
|
|
testSortedUnique1 : function () {
|
|
compare("FOR doc IN " + c.name() + " COLLECT AGGREGATE v = SORTED_UNIQUE(doc.value1) RETURN v");
|
|
},
|
|
|
|
testSortedUnique2 : function () {
|
|
compare("FOR doc IN " + c.name() + " COLLECT AGGREGATE v = SORTED_UNIQUE(doc.value2) RETURN v");
|
|
},
|
|
|
|
testCountDistinct1 : function () {
|
|
compare("FOR doc IN " + c.name() + " COLLECT AGGREGATE v = COUNT_DISTINCT(doc.value1) RETURN v");
|
|
},
|
|
|
|
testCountDistinct2 : function () {
|
|
compare("FOR doc IN " + c.name() + " COLLECT AGGREGATE v = COUNT_DISTINCT(doc.value2) RETURN v");
|
|
}
|
|
|
|
};
|
|
}
|
|
|
|
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
/// @brief executes the test suite
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
|
|
jsunity.run(optimizerAggregateTestSuite);
|
|
jsunity.run(optimizerAggregateCollectionTestSuite);
|
|
if (isCluster) {
|
|
jsunity.run(optimizerAggregateResultsSuite);
|
|
}
|
|
|
|
return jsunity.done();
|
|
|