1
0
Fork 0
arangodb/tests/js/server/aql/aql-optimizer-collect-into.js

276 lines
11 KiB
JavaScript

/*jshint globalstrict:false, strict:false, maxlen: 500 */
/*global assertEqual, assertTrue, fail, AQL_EXECUTE */
////////////////////////////////////////////////////////////////////////////////
/// @brief tests for COLLECT w/ INTO var = expr
///
/// @file
///
/// DISCLAIMER
///
/// Copyright 2010-2012 triagens GmbH, Cologne, Germany
///
/// Licensed under the Apache License, Version 2.0 (the "License");
/// you may not use this file except in compliance with the License.
/// You may obtain a copy of the License at
///
/// http://www.apache.org/licenses/LICENSE-2.0
///
/// Unless required by applicable law or agreed to in writing, software
/// distributed under the License is distributed on an "AS IS" BASIS,
/// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
/// See the License for the specific language governing permissions and
/// limitations under the License.
///
/// Copyright holder is triAGENS GmbH, Cologne, Germany
///
/// @author Jan Steemann
/// @author Copyright 2012, triAGENS GmbH, Cologne, Germany
////////////////////////////////////////////////////////////////////////////////
var jsunity = require("jsunity");
var db = require("@arangodb").db;
var internal = require("internal");
////////////////////////////////////////////////////////////////////////////////
/// @brief test suite
////////////////////////////////////////////////////////////////////////////////
function optimizerCollectExpressionTestSuite () {
var assertFailingQuery = function (query, code) {
if (code === undefined) {
code = internal.errors.ERROR_QUERY_PARSE.code;
}
try {
AQL_EXECUTE(query);
fail();
} catch (err) {
assertEqual(code, err.errorNum);
}
};
var c;
return {
setUp : function () {
db._drop("UnitTestsCollection");
c = db._create("UnitTestsCollection");
for (var i = 0; i < 1000; ++i) {
c.save({ gender: (i % 2 === 0 ? "m" : "f"), age: 11 + (i % 71), value: i });
}
},
tearDown : function () {
db._drop("UnitTestsCollection");
},
////////////////////////////////////////////////////////////////////////////////
/// @brief test expression
////////////////////////////////////////////////////////////////////////////////
testReference : function () {
var query = "FOR i IN " + c.name() + " COLLECT gender = i.gender INTO docs = i RETURN { gender: gender, age: MIN(docs[*].age) }";
var results = AQL_EXECUTE(query);
assertEqual(2, results.json.length);
assertEqual("f", results.json[0].gender);
assertEqual(11, results.json[0].age);
assertEqual("m", results.json[1].gender);
assertEqual(11, results.json[1].age);
},
////////////////////////////////////////////////////////////////////////////////
/// @brief test expression
////////////////////////////////////////////////////////////////////////////////
testSubAttribute : function () {
var query = "FOR i IN " + c.name() + " COLLECT gender = i.gender INTO ages = i.age RETURN { gender: gender, age: MIN(ages) }";
var results = AQL_EXECUTE(query);
assertEqual(2, results.json.length);
assertEqual("f", results.json[0].gender);
assertEqual(11, results.json[0].age);
assertEqual("m", results.json[1].gender);
assertEqual(11, results.json[1].age);
},
////////////////////////////////////////////////////////////////////////////////
/// @brief test expression
////////////////////////////////////////////////////////////////////////////////
testConst : function () {
var query = "FOR i IN " + c.name() + " COLLECT gender = i.gender INTO values = 1 RETURN { gender: gender, values: values }";
var values = [ ];
for (var i = 0; i < 500; ++i) {
values.push(1);
}
var results = AQL_EXECUTE(query);
assertEqual(2, results.json.length);
assertEqual("f", results.json[0].gender);
assertEqual(values, results.json[0].values);
assertEqual("m", results.json[1].gender);
assertEqual(values, results.json[1].values);
},
////////////////////////////////////////////////////////////////////////////////
/// @brief test expression
////////////////////////////////////////////////////////////////////////////////
testDocAttribute : function () {
var query = "FOR i IN " + c.name() + " COLLECT gender = i.gender INTO values = i.value RETURN { gender: gender, values: values }";
var f = [ ], m = [ ];
for (var i = 0; i < 500; ++i) {
m.push(i * 2);
f.push((i * 2) + 1);
}
var results = AQL_EXECUTE(query);
assertEqual(2, results.json.length);
assertEqual("f", results.json[0].gender);
assertEqual(f, results.json[0].values.sort(function (l, r) { return l - r; }));
assertEqual("m", results.json[1].gender);
assertEqual(m, results.json[1].values.sort(function (l, r) { return l - r; }));
},
////////////////////////////////////////////////////////////////////////////////
/// @brief test expression
////////////////////////////////////////////////////////////////////////////////
testCalculation : function () {
var query = "FOR i IN " + c.name() + " COLLECT gender = i.gender INTO names = (i.gender == 'f' ? 'female' : 'male') RETURN { gender: gender, names: names }";
var m = [ ], f = [ ];
for (var i = 0; i < 500; ++i) {
m.push('male');
f.push('female');
}
var results = AQL_EXECUTE(query);
assertEqual(2, results.json.length);
assertEqual("f", results.json[0].gender);
assertEqual(f, results.json[0].names);
assertEqual("m", results.json[1].gender);
assertEqual(m, results.json[1].names);
},
////////////////////////////////////////////////////////////////////////////////
/// @brief test expression
////////////////////////////////////////////////////////////////////////////////
testIntoWithGrouping : function () {
var query = "FOR i IN " + c.name() + " COLLECT gender = i.gender INTO g RETURN { gender: gender, ages: g[*].i.age }";
var i;
var results = AQL_EXECUTE(query);
assertEqual(2, results.json.length);
assertEqual("f", results.json[0].gender);
for (i = 0; i < 500; ++i) {
assertTrue(typeof results.json[0].ages[i] === 'number');
}
assertEqual("m", results.json[1].gender);
for (i = 0; i < 500; ++i) {
assertTrue(typeof results.json[1].ages[i] === 'number');
}
},
////////////////////////////////////////////////////////////////////////////////
/// @brief test expression
////////////////////////////////////////////////////////////////////////////////
testIntoWithGroupingInSubquery : function () {
var query = "LET values = (FOR i IN " + c.name() + " COLLECT gender = i.gender INTO g RETURN { gender: gender, ages: g[*].i.age }) RETURN values";
var i;
var results = AQL_EXECUTE(query);
assertEqual(2, results.json[0].length);
assertEqual("f", results.json[0][0].gender);
for (i = 0; i < 500; ++i) {
assertTrue(typeof results.json[0][0].ages[i] === 'number');
}
assertEqual("m", results.json[0][1].gender);
for (i = 0; i < 500; ++i) {
assertTrue(typeof results.json[0][1].ages[i] === 'number');
}
},
////////////////////////////////////////////////////////////////////////////////
/// @brief test expression
////////////////////////////////////////////////////////////////////////////////
testIntoWithGroupingInSupportFollowingFor : function () {
var query = "LET values = (FOR i IN " + c.name() + " COLLECT gender = i.gender INTO g RETURN { gender: gender, ages: g[*].i.age }) FOR i IN values RETURN i";
var i;
var results = AQL_EXECUTE(query);
assertEqual(2, results.json.length);
assertEqual("f", results.json[0].gender);
for (i = 0; i < 500; ++i) {
assertTrue(typeof results.json[0].ages[i] === 'number');
}
assertEqual("m", results.json[1].gender);
for (i = 0; i < 500; ++i) {
assertTrue(typeof results.json[1].ages[i] === 'number');
}
},
////////////////////////////////////////////////////////////////////////////////
/// @brief test expression
////////////////////////////////////////////////////////////////////////////////
testIntoWithOutVariableUsedInAssignment : function () {
assertFailingQuery("FOR doc IN [{ age: 1, value: 1 }, { age: 1, value: 2 }, { age: 2, value: 1 }, { age: 2, value: 2 }] COLLECT v1 = doc.age, v2 = doc.value INTO g = v1 RETURN [v1,v2,g]", internal.errors.ERROR_QUERY_VARIABLE_NAME_UNKNOWN.code);
assertFailingQuery("FOR doc IN [{ age: 1, value: 1 }, { age: 1, value: 2 }, { age: 2, value: 1 }, { age: 2, value: 2 }] COLLECT v1 = doc.age AGGREGATE v2 = MAX(doc.value) INTO g = v2 RETURN [v1,v2,g]", internal.errors.ERROR_QUERY_VARIABLE_NAME_UNKNOWN.code);
},
testMultiCollectWithConstExpression : function () {
var query = "LET values = [ {time:1}, {time:1}, {time:2}, {time:2}, {time:3}, {time:4}, {time:2}, {time:3}, {time:6} ] FOR p1 IN values COLLECT t = FLOOR(p1.time / 2) AGGREGATE m = MAX(p1.time) FOR p2 IN values FILTER m != p2.time COLLECT q = 0 INTO qs = p2 RETURN {q}";
var results = AQL_EXECUTE(query);
assertEqual([ { q: 0 } ], results.json);
query = "LET values = [ {time:1}, {time:1}, {time:2}, {time:2}, {time:3}, {time:4}, {time:2}, {time:3}, {time:6} ] FOR p1 IN values COLLECT t = FLOOR(p1.time / 2) AGGREGATE m = MAX(p1.time) FOR p2 IN values FILTER m == p2.time COLLECT q = 0 INTO qs = p2 RETURN {q}";
results = AQL_EXECUTE(query);
assertEqual([ { q: 0 } ], results.json);
},
testCollectWithEmptyInput : function () {
let query = "FOR v IN [] COLLECT w = 1 INTO x RETURN w";
let results = AQL_EXECUTE(query);
assertEqual([ ], results.json);
query = "FOR v IN [] COLLECT w = 1 INTO x RETURN {x}";
results = AQL_EXECUTE(query);
assertEqual([ ], results.json);
query = "FOR v IN [] COLLECT w = 1 INTO x RETURN x";
results = AQL_EXECUTE(query);
assertEqual([ ], results.json);
query = "FOR v IN 1..3 FILTER v > 9 COLLECT w = 1 INTO x RETURN w";
results = AQL_EXECUTE(query);
assertEqual([ ], results.json);
query = "FOR v IN 1..3 FILTER v > 9 COLLECT w = v INTO x RETURN w";
results = AQL_EXECUTE(query);
assertEqual([ ], results.json);
query = "FOR v IN 1..3 COLLECT w = v INTO x RETURN w";
results = AQL_EXECUTE(query);
assertEqual([ 1, 2, 3 ], results.json);
}
};
}
////////////////////////////////////////////////////////////////////////////////
/// @brief executes the test suite
////////////////////////////////////////////////////////////////////////////////
jsunity.run(optimizerCollectExpressionTestSuite);
return jsunity.done();