1
0
Fork 0

Merge branch 'devel' of github.com:triAGENS/ArangoDB into devel

This commit is contained in:
Michael Hackstein 2014-11-05 16:25:31 +00:00
commit 5d020b7ab7
8 changed files with 282 additions and 41 deletions

View File

@ -1,11 +1,14 @@
v2.3.0 (XXXX-XX-XX) v2.3.0 (XXXX-XX-XX)
------------------- -------------------
* performance improvements for AQL queries that use JavaScript-based expressions
internally
* added AQL geo functions `WITHIN_RECTANGLE` and `IS_IN_POLYGON` * added AQL geo functions `WITHIN_RECTANGLE` and `IS_IN_POLYGON`
* fixed non-working query results download in AQL editor of web interface * fixed non-working query results download in AQL editor of web interface
* removed debug print message in AQL query export routine * removed debug print message in AQL editor query export routine
* fixed issue #1075: Aardvark: user name required even if auth is off #1075 * fixed issue #1075: Aardvark: user name required even if auth is off #1075

View File

@ -23,11 +23,13 @@ These operators accept any data types for the first and second operands.
Each of the comparison operators returns a boolean value if the comparison can Each of the comparison operators returns a boolean value if the comparison can
be evaluated and returns *true* if the comparison evaluates to true, and *false* be evaluated and returns *true* if the comparison evaluates to true, and *false*
otherwise. otherwise. Please note that the comparsion operators will not perform any
implicit type casts if the compared operands have different types.
Some examples for comparison operations in AQL: Some examples for comparison operations in AQL:
``` ```
0 == null // false
1 > 0 // true 1 > 0 // true
true != null // true true != null // true
45 <= "yikes!" // true 45 <= "yikes!" // true

View File

@ -2,7 +2,7 @@
The default installation directory is *c:\Program Files\ArangoDB-1.x.y*. During the The default installation directory is *c:\Program Files\ArangoDB-1.x.y*. During the
installation process you may change this. In the following description we will assume installation process you may change this. In the following description we will assume
that ArangoDB has been installed in the location *<ROOTDIR>*. that ArangoDB has been installed in the location *&lt;ROOTDIR&gt;*.
You have to be careful when choosing an installation directory. You need either You have to be careful when choosing an installation directory. You need either
write permission to this directory or you need to modify the config file for the write permission to this directory or you need to modify the config file for the
@ -10,17 +10,17 @@ server process. In the latter case the database directory and the Foxx directory
has to be writable by the user. has to be writable by the user.
Installing for a single user: Select a different directory during Installing for a single user: Select a different directory during
installation. For example *C:/Users/<username>/arangodb* or *C:/ArangoDB*. installation. For example *c:\Users\&lt;Username&gt;\ArangoDB* or *c:\ArangoDB*.
Installing for multiple users: Keep the default directory. After the Installing for multiple users: Keep the default directory. After the
installation edit the file *<ROOTDIR>/etc/arangodb/arangod.conf*. Adjust the installation edit the file *&lt;ROOTDIR&gt;\etc\Arangodb\arangod.conf*. Adjust the
*directory* and *app-path* so that these paths point into your home directory. *directory* and *app-path* so that these paths point into your home directory.
[database] [database]
directory = @HOMEDRIVE@/@HOMEPATH@/arangodb/databases directory = @HOMEDRIVE@\@HOMEPATH@\arangodb\databases
[javascript] [javascript]
app-path = @HOMEDRIVE@/@HOMEPATH@/arangodb/apps app-path = @HOMEDRIVE@\@HOMEPATH@\arangodb\apps
Create the directories for each user that wants to use ArangoDB. Create the directories for each user that wants to use ArangoDB.
@ -28,16 +28,16 @@ Installing as Service: Keep the default directory. After the installation open
a command line as administrator (search for *cmd* and right click *run as a command line as administrator (search for *cmd* and right click *run as
administrator*). administrator*).
cmd> arangod --install-service cmd&gt; arangod --install-service
INFO: adding service 'ArangoDB - the multi-purpose database' (internal 'ArangoDB') INFO: adding service 'ArangoDB - the multi-purpose database' (internal 'ArangoDB')
INFO: added service with command line '"C:\Program Files (x86)\ArangoDB 1.4.4\bin\arangod.exe" --start-service' INFO: added service with command line '"C:\Program Files (x86)\ArangoDB 1.4.4\bin\arangod.exe" --start-service'
Open the service manager and start ArangoDB. In order to enable logging Open the service manager and start ArangoDB. In order to enable logging
edit the file "<ROOTDIR>/etc/arangodb/arangod.conf" and uncomment the file edit the file "<ROOTDIR>\etc\arangodb\arangod.conf" and uncomment the file
option. option.
[log] [log]
file = @ROOTDIR@/var/log/arangodb/arangod.log file = @ROOTDIR@\var\log\arangodb\arangod.log
!SUBSECTION Client, Server and Lock-Files !SUBSECTION Client, Server and Lock-Files
@ -51,9 +51,9 @@ not proceed correctly or if the server terminated unexpectedly.
!SUBSECTION Starting !SUBSECTION Starting
To start an ArangoDB server instance with networking enabled, use the executable To start an ArangoDB server instance with networking enabled, use the executable
*arangod.exe* located in *<ROOTDIR>/bin*. This will use the configuration *arangod.exe* located in *&lt;ROOTDIR&gt;\bin*. This will use the configuration
file *arangod.conf* located in *<ROOTDIR>/etc/arangodb*, which you can adjust file *arangod.conf* located in *&lt;ROOTDIR&gt;\etc\arangodb*, which you can adjust
to your needs and use the data directory *<ROOTDIR>/var/lib/arangodb*. This to your needs and use the data directory *&lt;ROOTDIR&gt;\var\lib\arangodb*. This
is the place where all your data (databases and collections) will be stored is the place where all your data (databases and collections) will be stored
by default. by default.
@ -85,7 +85,7 @@ containing the configuration files.
!SUBSECTION Using the Client !SUBSECTION Using the Client
To connect to an already running ArangoDB server instance, there is a shell To connect to an already running ArangoDB server instance, there is a shell
*arangosh.exe* located in *<ROOTDIR>/bin*. This starts a shell which can be *arangosh.exe* located in *&lt;ROOTDIR&gt;\bin*. This starts a shell which can be
used amongst other things to administer and query a local or remote used amongst other things to administer and query a local or remote
ArangoDB server. ArangoDB server.
@ -94,7 +94,7 @@ shell. To use it you must have a server running somewhere, e.g. by using
the *arangod.exe* executable. the *arangod.exe* executable.
*arangosh.exe* uses configuration from the file *arangosh.conf* located in *arangosh.exe* uses configuration from the file *arangosh.conf* located in
*<ROOTDIR>/etc/arangodb/*. Please adjust this to your needs if you want to *&lt;ROOTDIR&gt;\etc\arangodb\*. Please adjust this to your needs if you want to
use different connection settings etc. use different connection settings etc.
!SUBSECTION 32bit !SUBSECTION 32bit
@ -121,9 +121,9 @@ completed successfully.
To uninstall the Arango server application you can use the windows control panel To uninstall the Arango server application you can use the windows control panel
(as you would normally uninstall an application). Note however, that any data (as you would normally uninstall an application). Note however, that any data
files created by the Arango server will remain as well as the *<ROOTDIR>* files created by the Arango server will remain as well as the *&lt;ROOTDIR&gt;*
directory. To complete the uninstallation process, remove the data files and directory. To complete the uninstallation process, remove the data files and
the *<ROOTDIR>* directory manually. the *&lt;ROOTDIR&gt;* directory manually.
!SUBSECTION Limitations for Cygwin !SUBSECTION Limitations for Cygwin

View File

@ -418,7 +418,8 @@ void Executor::generateCodeExpression (AstNode const* node) {
TRI_ASSERT(_buffer != nullptr); TRI_ASSERT(_buffer != nullptr);
// write prologue // write prologue
_buffer->appendText("(function (vars) { var aql = require(\"org/arangodb/aql\"); return "); // this checks if global variable _AQL is set and populates if it not
_buffer->appendText("(function (vars) { if (_AQL === undefined) { _AQL = require(\"org/arangodb/aql\"); } return ");
generateCodeNode(node); generateCodeNode(node);
@ -509,7 +510,7 @@ void Executor::generateCodeUnaryOperator (AstNode const* node) {
THROW_ARANGO_EXCEPTION_MESSAGE(TRI_ERROR_INTERNAL, "function not found"); THROW_ARANGO_EXCEPTION_MESSAGE(TRI_ERROR_INTERNAL, "function not found");
} }
_buffer->appendText("aql.", 4); _buffer->appendText("_AQL.", 5);
_buffer->appendText((*it).second); _buffer->appendText((*it).second);
_buffer->appendChar('('); _buffer->appendChar('(');
@ -535,7 +536,7 @@ void Executor::generateCodeBinaryOperator (AstNode const* node) {
bool wrap = (node->type == NODE_TYPE_OPERATOR_BINARY_AND || bool wrap = (node->type == NODE_TYPE_OPERATOR_BINARY_AND ||
node->type == NODE_TYPE_OPERATOR_BINARY_OR); node->type == NODE_TYPE_OPERATOR_BINARY_OR);
_buffer->appendText("aql.", 4); _buffer->appendText("_AQL.", 5);
_buffer->appendText((*it).second); _buffer->appendText((*it).second);
_buffer->appendChar('('); _buffer->appendChar('(');
@ -570,7 +571,7 @@ void Executor::generateCodeTernaryOperator (AstNode const* node) {
THROW_ARANGO_EXCEPTION_MESSAGE(TRI_ERROR_INTERNAL, "function not found"); THROW_ARANGO_EXCEPTION_MESSAGE(TRI_ERROR_INTERNAL, "function not found");
} }
_buffer->appendText("aql.", 4); _buffer->appendText("_AQL.", 5);
_buffer->appendText((*it).second); _buffer->appendText((*it).second);
_buffer->appendChar('('); _buffer->appendChar('(');
@ -622,7 +623,7 @@ void Executor::generateCodeCollection (AstNode const* node) {
char const* name = node->getStringValue(); char const* name = node->getStringValue();
_buffer->appendText("aql.GET_DOCUMENTS("); _buffer->appendText("_AQL.GET_DOCUMENTS(");
generateCodeString(name); generateCodeString(name);
_buffer->appendChar(')'); _buffer->appendChar(')');
} }
@ -641,7 +642,7 @@ void Executor::generateCodeFunctionCall (AstNode const* node) {
TRI_ASSERT(args != nullptr); TRI_ASSERT(args != nullptr);
TRI_ASSERT(args->type == NODE_TYPE_LIST); TRI_ASSERT(args->type == NODE_TYPE_LIST);
_buffer->appendText("aql.", 4); _buffer->appendText("_AQL.", 5);
_buffer->appendText(func->internalName); _buffer->appendText(func->internalName);
_buffer->appendChar('('); _buffer->appendChar('(');
@ -693,7 +694,7 @@ void Executor::generateCodeUserFunctionCall (AstNode const* node) {
TRI_ASSERT(args != nullptr); TRI_ASSERT(args != nullptr);
TRI_ASSERT(args->type == NODE_TYPE_LIST); TRI_ASSERT(args->type == NODE_TYPE_LIST);
_buffer->appendText("aql.FCALL_USER("); _buffer->appendText("_AQL.FCALL_USER(");
generateCodeString(name); generateCodeString(name);
_buffer->appendText(",[", 2); _buffer->appendText(",[", 2);
@ -750,7 +751,7 @@ void Executor::generateCodeRange (AstNode const* node) {
TRI_ASSERT(node != nullptr); TRI_ASSERT(node != nullptr);
TRI_ASSERT(node->numMembers() == 2); TRI_ASSERT(node->numMembers() == 2);
_buffer->appendText("aql.AQL_RANGE("); _buffer->appendText("_AQL.AQL_RANGE(");
generateCodeNode(node->getMember(0)); generateCodeNode(node->getMember(0));
_buffer->appendChar(','); _buffer->appendChar(',');
generateCodeNode(node->getMember(1)); generateCodeNode(node->getMember(1));
@ -765,7 +766,7 @@ void Executor::generateCodeNamedAccess (AstNode const* node) {
TRI_ASSERT(node != nullptr); TRI_ASSERT(node != nullptr);
TRI_ASSERT(node->numMembers() == 1); TRI_ASSERT(node->numMembers() == 1);
_buffer->appendText("aql.DOCUMENT_MEMBER("); _buffer->appendText("_AQL.DOCUMENT_MEMBER(");
generateCodeNode(node->getMember(0)); generateCodeNode(node->getMember(0));
_buffer->appendChar(','); _buffer->appendChar(',');
generateCodeString(node->getStringValue()); generateCodeString(node->getStringValue());
@ -780,7 +781,7 @@ void Executor::generateCodeBoundAccess (AstNode const* node) {
TRI_ASSERT(node != nullptr); TRI_ASSERT(node != nullptr);
TRI_ASSERT(node->numMembers() == 2); TRI_ASSERT(node->numMembers() == 2);
_buffer->appendText("aql.DOCUMENT_MEMBER("); _buffer->appendText("_AQL.DOCUMENT_MEMBER(");
generateCodeNode(node->getMember(0)); generateCodeNode(node->getMember(0));
_buffer->appendChar(','); _buffer->appendChar(',');
generateCodeNode(node->getMember(1)); generateCodeNode(node->getMember(1));
@ -795,7 +796,7 @@ void Executor::generateCodeIndexedAccess (AstNode const* node) {
TRI_ASSERT(node != nullptr); TRI_ASSERT(node != nullptr);
TRI_ASSERT(node->numMembers() == 2); TRI_ASSERT(node->numMembers() == 2);
_buffer->appendText("aql.GET_INDEX("); _buffer->appendText("_AQL.GET_INDEX(");
generateCodeNode(node->getMember(0)); generateCodeNode(node->getMember(0));
_buffer->appendChar(','); _buffer->appendChar(',');
generateCodeNode(node->getMember(1)); generateCodeNode(node->getMember(1));

View File

@ -2561,6 +2561,10 @@ void TRI_InitV8VocBridge (triagens::arango::ApplicationV8* applicationV8,
// whether or not statistics are enabled // whether or not statistics are enabled
context->Global()->Set(TRI_V8_SYMBOL("ENABLE_STATISTICS"), v8::Boolean::New(TRI_ENABLE_STATISTICS), v8::ReadOnly); context->Global()->Set(TRI_V8_SYMBOL("ENABLE_STATISTICS"), v8::Boolean::New(TRI_ENABLE_STATISTICS), v8::ReadOnly);
// a thread-global variable that will is supposed to contain the AQL module
// do not remove this, otherwise AQL queries will break
context->Global()->Set(TRI_V8_SYMBOL("_AQL"), v8::Undefined(), v8::DontEnum);
} }
// ----------------------------------------------------------------------------- // -----------------------------------------------------------------------------

View File

@ -357,7 +357,8 @@ function require (path) {
id: id, id: id,
path: normalizeModuleName(path + "/.."), path: normalizeModuleName(path + "/.."),
origin: path2FileUri(filename), origin: path2FileUri(filename),
type: type }; type: type
};
} }
// try to append ".js" // try to append ".js"
@ -379,7 +380,8 @@ function require (path) {
id: path, id: path,
path: normalizeModuleName(path + "/.."), path: normalizeModuleName(path + "/.."),
origin: path2FileUri(agumented), origin: path2FileUri(agumented),
type: "json" }; type: "json"
};
} }
// try to append ".coffee" // try to append ".coffee"
@ -390,7 +392,8 @@ function require (path) {
id: path, id: path,
path: normalizeModuleName(path + "/.."), path: normalizeModuleName(path + "/.."),
origin: path2FileUri(agumented), origin: path2FileUri(agumented),
type: "coffee" }; type: "coffee"
};
} }
// maybe this is a directory with an index file // maybe this is a directory with an index file
@ -402,7 +405,8 @@ function require (path) {
id: fs.join(path, "index"), id: fs.join(path, "index"),
path: path, path: path,
origin: path2FileUri(agumented), origin: path2FileUri(agumented),
type: "js" }; type: "js"
};
} }
} }

View File

@ -130,6 +130,7 @@ function StatementSuite () {
try { try {
st.parse(); st.parse();
fail();
} }
catch (e) { catch (e) {
assertEqual(ERRORS.ERROR_QUERY_PARSE.code, e.errorNum); assertEqual(ERRORS.ERROR_QUERY_PARSE.code, e.errorNum);
@ -146,6 +147,7 @@ function StatementSuite () {
assertEqual([ "users" ], result.collections); assertEqual([ "users" ], result.collections);
assertEqual([ ], result.bindVars); assertEqual([ ], result.bindVars);
assertTrue(result.hasOwnProperty("ast"));
}, },
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
@ -158,6 +160,7 @@ function StatementSuite () {
assertEqual([ "friends", "users" ], result.collections.sort()); assertEqual([ "friends", "users" ], result.collections.sort());
assertEqual([ ], result.bindVars); assertEqual([ ], result.bindVars);
assertTrue(result.hasOwnProperty("ast"));
}, },
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
@ -170,6 +173,7 @@ function StatementSuite () {
assertEqual([ ], result.collections); assertEqual([ ], result.collections);
assertEqual([ "@users", "name" ], result.bindVars.sort()); assertEqual([ "@users", "name" ], result.bindVars.sort());
assertTrue(result.hasOwnProperty("ast"));
}, },
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
@ -182,6 +186,185 @@ function StatementSuite () {
assertEqual([ "friends" ], result.collections); assertEqual([ "friends" ], result.collections);
assertEqual([ "@users", "name" ], result.bindVars.sort()); assertEqual([ "@users", "name" ], result.bindVars.sort());
assertTrue(result.hasOwnProperty("ast"));
},
////////////////////////////////////////////////////////////////////////////////
/// @brief test explain method
////////////////////////////////////////////////////////////////////////////////
testExplainError : function () {
var st = new ArangoStatement(db, { query : "for u in" });
try {
st.explain();
fail();
}
catch (e) {
assertEqual(ERRORS.ERROR_QUERY_PARSE.code, e.errorNum);
}
},
////////////////////////////////////////////////////////////////////////////////
/// @brief test explain method
////////////////////////////////////////////////////////////////////////////////
testExplainOk : function () {
var st = new ArangoStatement(db, { query : "FOR i IN 1..10 RETURN i" });
var result = st.explain();
assertEqual([ ], result.warnings);
assertTrue(result.hasOwnProperty("plan"));
assertFalse(result.hasOwnProperty("plans"));
var plan = result.plan;
assertTrue(plan.hasOwnProperty("estimatedCost"));
assertTrue(plan.hasOwnProperty("rules"));
assertEqual([ ], plan.rules);
assertTrue(plan.hasOwnProperty("nodes"));
assertTrue(plan.hasOwnProperty("collections"));
assertEqual([ ], plan.collections);
assertTrue(plan.hasOwnProperty("variables"));
},
////////////////////////////////////////////////////////////////////////////////
/// @brief test explain method
////////////////////////////////////////////////////////////////////////////////
testExplainAllPlans : function () {
var st = new ArangoStatement(db, { query : "FOR i IN 1..10 RETURN i" });
var result = st.explain({ allPlans: true });
assertEqual([ ], result.warnings);
assertFalse(result.hasOwnProperty("plan"));
assertTrue(result.hasOwnProperty("plans"));
assertEqual(1, result.plans.length);
var plan = result.plans[0];
assertTrue(plan.hasOwnProperty("estimatedCost"));
assertTrue(plan.hasOwnProperty("rules"));
assertEqual([ ], plan.rules);
assertTrue(plan.hasOwnProperty("nodes"));
assertTrue(plan.hasOwnProperty("collections"));
assertEqual([ ], plan.collections);
assertTrue(plan.hasOwnProperty("variables"));
},
////////////////////////////////////////////////////////////////////////////////
/// @brief test explain method, bind variables
////////////////////////////////////////////////////////////////////////////////
testExplainBindMissing : function () {
var st = new ArangoStatement(db, { query : "FOR i IN @@list FILTER i == @value RETURN i" });
try {
st.explain();
}
catch (e) {
assertEqual(ERRORS.ERROR_QUERY_BIND_PARAMETER_MISSING.code, e.errorNum);
}
},
////////////////////////////////////////////////////////////////////////////////
/// @brief test explain method, bind variables
////////////////////////////////////////////////////////////////////////////////
testExplainBindInvalidType : function () {
var st = new ArangoStatement(db, { query : "FOR i IN @@list RETURN i" });
st.bind("@list", [ 1, 2, 3 ]);
try {
st.explain();
}
catch (e) {
assertEqual(ERRORS.ERROR_QUERY_BIND_PARAMETER_TYPE.code, e.errorNum);
}
},
////////////////////////////////////////////////////////////////////////////////
/// @brief test explain method, bind variables
////////////////////////////////////////////////////////////////////////////////
testExplainBindInvalid : function () {
var st = new ArangoStatement(db, { query : "FOR i IN @list FILTER i == @value RETURN i" });
st.bind("list", [ 1, 2, 3 ]);
st.bind("value", 3);
st.bind("foo", "bar");
try {
st.explain();
}
catch (e) {
assertEqual(ERRORS.ERROR_QUERY_BIND_PARAMETER_UNDECLARED.code, e.errorNum);
}
},
////////////////////////////////////////////////////////////////////////////////
/// @brief test bind method, bind variables
////////////////////////////////////////////////////////////////////////////////
testExplainBind : function () {
var st = new ArangoStatement(db, { query : "FOR i IN @list FILTER i == @value RETURN i" });
st.bind("list", [ 1, 2, 3 ]);
st.bind("value", 3);
var result = st.explain();
assertEqual([ ], result.warnings);
assertTrue(result.hasOwnProperty("plan"));
assertFalse(result.hasOwnProperty("plans"));
var plan = result.plan;
assertTrue(plan.hasOwnProperty("estimatedCost"));
assertTrue(plan.hasOwnProperty("rules"));
assertEqual([ ], plan.rules);
assertTrue(plan.hasOwnProperty("nodes"));
assertTrue(plan.hasOwnProperty("collections"));
assertEqual([ ], plan.collections);
assertTrue(plan.hasOwnProperty("variables"));
},
////////////////////////////////////////////////////////////////////////////////
/// @brief test bind method, bind variables
////////////////////////////////////////////////////////////////////////////////
testExplainBindCollection : function () {
var st = new ArangoStatement(db, { query : "FOR i IN @@collection RETURN i" });
st.bind("@collection", "_users");
var result = st.explain();
assertEqual([ ], result.warnings);
assertTrue(result.hasOwnProperty("plan"));
assertFalse(result.hasOwnProperty("plans"));
var plan = result.plan;
assertTrue(plan.hasOwnProperty("estimatedCost"));
assertTrue(plan.hasOwnProperty("rules"));
assertEqual([ ], plan.rules);
assertTrue(plan.hasOwnProperty("nodes"));
assertTrue(plan.hasOwnProperty("collections"));
assertEqual([ { "name" : "_users", "type" : "read" } ], plan.collections);
assertTrue(plan.hasOwnProperty("variables"));
},
////////////////////////////////////////////////////////////////////////////////
/// @brief test bind method, bind variables
////////////////////////////////////////////////////////////////////////////////
testExplainBindWarnings : function () {
var st = new ArangoStatement(db, { query : "FOR i IN 1..10 RETURN 1 / 0" });
var result = st.explain();
assertEqual(1, result.warnings.length);
assertEqual(ERRORS.ERROR_QUERY_DIVISION_BY_ZERO.code, result.warnings[0].code);
assertTrue(result.hasOwnProperty("plan"));
assertFalse(result.hasOwnProperty("plans"));
var plan = result.plan;
assertTrue(plan.hasOwnProperty("estimatedCost"));
assertTrue(plan.hasOwnProperty("rules"));
assertTrue(plan.hasOwnProperty("nodes"));
assertTrue(plan.hasOwnProperty("collections"));
assertEqual([ ], plan.collections);
assertTrue(plan.hasOwnProperty("variables"));
}, },
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
@ -192,6 +375,7 @@ function StatementSuite () {
var st = new ArangoStatement(db, { query : "for u in" }); var st = new ArangoStatement(db, { query : "for u in" });
try { try {
result = st.execute(); result = st.execute();
fail();
} }
catch (e) { catch (e) {
assertEqual(ERRORS.ERROR_QUERY_PARSE.code, e.errorNum); assertEqual(ERRORS.ERROR_QUERY_PARSE.code, e.errorNum);

View File

@ -43,19 +43,17 @@ var colName = "perf_" + ruleName.replace(/-/g, "_");
var theCollection; var theCollection;
var dbdApi = function (query, plan, bindVars) { var dbdApi = function (query, plan, bindVars) {
db._query(query, bindVars); db._query(query, bindVars).toArray();
return {}; return {};
}; };
var setUp = function (options) { var setUp = function (options) {
var loopto = options.dbcols; var loopto = options.dbcols;
var contentmultipy = options.contentmultiply; var contentmultiply = options.contentmultiply;
var Content = Array(contentmultiply).join('abcdefghijklmnopqrstuvwxyz')
var Content = [];
for (j = 0; j < contentmultipy; j ++ ) {
Content = Content.concat(['abcdefghijklmnopqrstuvwxyz']);
}
internal.db._drop(colName); internal.db._drop(colName);
theCollection = internal.db._create(colName); theCollection = internal.db._create(colName);
var i, j; var i, j;
@ -75,6 +73,7 @@ var setUp = function (options) {
var tearDown = function () { var tearDown = function () {
internal.db._drop(colName); internal.db._drop(colName);
require("internal").wait(0);
theCollection = null; theCollection = null;
}; };
@ -103,6 +102,15 @@ var testNonIndexedPartialRead = function (testParams, testMethodStr, testMethod,
return testMethod.executeQuery(query, {}, {}); return testMethod.executeQuery(query, {}, {});
}; };
////////////////////////////////////////////////////////////////////////////////
/// @brief Testcase: dump 10% of a table without using an index
////////////////////////////////////////////////////////////////////////////////
var testNonIndexedPartialReadCalcJS = function (testParams, testMethodStr, testMethod, runOptions) {
var tenPercent = (runOptions.dbcols / 10) * 9;
var query = "FOR i IN " + colName + " FILTER i.Key + 1 > " + tenPercent + " RETURN i";
return testMethod.executeQuery(query, {}, {});
};
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
/// @brief Testcase: dump a full table sorted by an unindexed key. /// @brief Testcase: dump a full table sorted by an unindexed key.
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
@ -119,6 +127,33 @@ var testIndexedFullSort = function (testParams, testMethodStr, testMethod) {
return testMethod.executeQuery(query, {}, {}); return testMethod.executeQuery(query, {}, {});
}; };
////////////////////////////////////////////////////////////////////////////////
/// @brief Testcase: dump a full table sorted by an indexed key.
////////////////////////////////////////////////////////////////////////////////
var testIndexedFullSortReverse = function (testParams, testMethodStr, testMethod) {
var query = "FOR i IN " + colName + " SORT i.indexedKey DESC RETURN i";
return testMethod.executeQuery(query, {}, {});
};
////////////////////////////////////////////////////////////////////////////////
/// @brief Testcase: dump a full table sorted by an indexed key - use filter
/// so the old also has
////////////////////////////////////////////////////////////////////////////////
var testIndexedFullSortFilter = function (testParams, testMethodStr, testMethod) {
var query = "FOR i IN " + colName + " FILTER i.indexedKey > 0 SORT i.indexedKey RETURN i";
return testMethod.executeQuery(query, {}, {});
};
////////////////////////////////////////////////////////////////////////////////
/// @brief Testcase: dump a full table sorted by an indexed key - use filter
/// so the old also has
////////////////////////////////////////////////////////////////////////////////
var testIndexedFullSortReverseFilter = function (testParams, testMethodStr, testMethod) {
var query = "FOR i IN " + colName + " FILTER i.indexedKey > 0 SORT i.indexedKey DESC RETURN i";
return testMethod.executeQuery(query, {}, {});
};
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
/// @brief Simple join testsuite /// @brief Simple join testsuite
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
@ -126,12 +161,20 @@ var testIndexedFullSort = function (testParams, testMethodStr, testMethod) {
var testSuite = [ var testSuite = [
{ name: "setup", setUp: setUp, teardown: null, params: null, func: null}, { name: "setup", setUp: setUp, teardown: null, params: null, func: null},
{ name: "testFullRead", func: testFullRead}, { name: "testFullRead", func: testFullRead},
{ name: "testNonIndexedPartialRead", func: testNonIndexedPartialRead}, { name: "testNonIndexedPartialRead", func: testNonIndexedPartialRead},
{ name: "testNonIndexedPartialReadCalcJS", func: testNonIndexedPartialReadCalcJS},
{ name: "testNonIndexedFullSort", func: testNonIndexedFullSort}, { name: "testNonIndexedFullSort", func: testNonIndexedFullSort},
{ name: "testIndexedFullSort", func: testIndexedFullSort}, { name: "testIndexedFullSort", func: testIndexedFullSort},
{ name: "testIndexedFullSortReverse", func: testIndexedFullSortReverse},
{ name: "testIndexedFullSortFilter", func: testIndexedFullSortFilter},
{ name: "testIndexedFullSortReverseFilter", func: testIndexedFullSortReverseFilter},
{ name: "teardown", setUp: null, teardown: tearDown, params: null, func: null} { name: "teardown", setUp: null, teardown: tearDown, params: null, func: null}
]; ];
@ -141,8 +184,8 @@ var testSuite = [
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
var k, l; var k, l;
for (k = 4; k < 10; k++) { for (k = 1; k < 22; k+=5) {
for (l = 4; l < 10; l++) { for (l = 1; l < 22; l+=5) {
var testOptions = { var testOptions = {
enableIndex: true, enableIndex: true,
dbcols: 10000 * k, dbcols: 10000 * k,