mirror of https://gitee.com/bigwinds/arangodb
revert unification of collection name validation
This commit is contained in:
parent
cd95185cad
commit
9959218d1d
|
@ -213,14 +213,6 @@ APIs:
|
|||
AQL user functions on the top level of the response.
|
||||
Each AQL user function description now also contains the 'isDeterministic' attribute.
|
||||
|
||||
- the REST API for parsing AQL queries at endpoint `POST /_api/query` now may
|
||||
return other error codes than HTTP 400 in case the query cannot be parsed.
|
||||
|
||||
Previous versions of ArangoDB always returned HTTP code 400 (Bad request) when a
|
||||
query could not be parsed. ArangoDB 3.4 will return HTTP 400 in case of regular parse
|
||||
errors, but may also return more specific HTTP status codes, such as HTTP 404
|
||||
(Not found) if the query refers to an unknown collection or view.
|
||||
|
||||
- if authentication is turned on, requests to databases by users with insufficient
|
||||
access rights will be answered with HTTP 401 (Forbidden) instead of HTTP 404 (Not found).
|
||||
|
||||
|
@ -401,20 +393,13 @@ instead of error 1582 (`ERROR_QUERY_FUNCTION_NOT_FOUND`) in some situations.
|
|||
often what is desired anyway, but the change makes `DATE_NOW` useless to measure
|
||||
time differences inside a single query.
|
||||
|
||||
- the AQL function `PASSTHRU` (which simply returns its call argument)
|
||||
- the internal AQL function `PASSTHRU` (which simply returns its call argument)
|
||||
has been changed from being non-deterministic to being deterministic, provided its
|
||||
call argument is also deterministic. This change should not affect end users, as
|
||||
`PASSTHRU` is intended to be used for internal testing only. Should end users use
|
||||
this AQL function in any query and need a wrapper to make query parts non-deterministic,
|
||||
the `NOOPT` AQL function can stand in as a non-deterministic variant of `PASSTHRU`
|
||||
|
||||
- when only parsing an AQL query via the `db._parse()` function or the REST API at
|
||||
endpoint `POST /_api/query`, parsing will now fail and return error code 1203
|
||||
("collection or view not found") when referring to a non-existing collection or view.
|
||||
|
||||
Previous versions of ArangoDB continued with parsing even if referenced collections
|
||||
did not exist, and did not return an error in this case.
|
||||
|
||||
|
||||
|
||||
Usage of V8
|
||||
-----------
|
||||
|
|
|
@ -31,10 +31,6 @@ The server will respond with *HTTP 400* in case of a malformed request,
|
|||
or if the query contains a parse error. The body of the response will
|
||||
contain the error details embedded in a JSON object.
|
||||
|
||||
@RESTRETURNCODE{404}
|
||||
The server will respond with *HTTP 404* in case the query refers to an
|
||||
unknown collection or view.
|
||||
|
||||
@EXAMPLES
|
||||
|
||||
a valid query
|
||||
|
@ -60,19 +56,6 @@ an invalid query
|
|||
|
||||
assert(response.code === 400);
|
||||
|
||||
logJsonResponse(response);
|
||||
@END_EXAMPLE_ARANGOSH_RUN
|
||||
|
||||
an query referring to a non-existing collection
|
||||
|
||||
@EXAMPLE_ARANGOSH_RUN{RestQueryNonExisting}
|
||||
var url = "/_api/query";
|
||||
var body = '{ "query" : "FOR doc IN collectionThatDoesNotExist RETURN doc._key" }';
|
||||
|
||||
var response = logCurlRequest('POST', url, body);
|
||||
|
||||
assert(response.code === 404);
|
||||
|
||||
logJsonResponse(response);
|
||||
@END_EXAMPLE_ARANGOSH_RUN
|
||||
@endDocuBlock
|
||||
|
|
|
@ -620,17 +620,29 @@ AstNode* Ast::createNodeVariable(char const* name, size_t nameLength,
|
|||
AstNode* Ast::createNodeDataSource(arangodb::CollectionNameResolver const& resolver,
|
||||
char const* name,
|
||||
size_t nameLength,
|
||||
AccessMode::Type accessType) {
|
||||
std::string const nameString = validateDataSourceName(name, nameLength);
|
||||
AccessMode::Type accessType,
|
||||
bool validateName,
|
||||
bool failIfDoesNotExist) {
|
||||
std::string const nameString = validateDataSourceName(name, nameLength, validateName);
|
||||
|
||||
auto const dataSource = resolver.getDataSource(nameString);
|
||||
|
||||
if (!dataSource) {
|
||||
// datasource not found...
|
||||
THROW_ARANGO_EXCEPTION_FORMAT(
|
||||
TRI_ERROR_ARANGO_DATA_SOURCE_NOT_FOUND,
|
||||
"name: %s",
|
||||
nameString.c_str());
|
||||
if (failIfDoesNotExist) {
|
||||
THROW_ARANGO_EXCEPTION_FORMAT(
|
||||
TRI_ERROR_ARANGO_DATA_SOURCE_NOT_FOUND,
|
||||
"name: %s",
|
||||
nameString.c_str());
|
||||
}
|
||||
|
||||
// still add datasource to query, simply because the AST will also be built
|
||||
// for queries that are parsed-only (e.g. via `db._parse(query);`. In this
|
||||
// case it is ok that the datasource does not exist, but we need to track
|
||||
// the names of datasources used in the query
|
||||
_query->collections()->add(nameString, accessType);
|
||||
|
||||
return createNodeCollectionNoValidation(name, nameLength, nameString, accessType);
|
||||
}
|
||||
|
||||
// query actual name from datasource... this may be different to the
|
||||
|
@ -662,7 +674,7 @@ AstNode* Ast::createNodeDataSource(arangodb::CollectionNameResolver const& resol
|
|||
AstNode* Ast::createNodeCollection(char const* name,
|
||||
size_t nameLength,
|
||||
AccessMode::Type accessType) {
|
||||
std::string const nameString = validateDataSourceName(name, nameLength);
|
||||
std::string const nameString = validateDataSourceName(name, nameLength, true);
|
||||
|
||||
// add collection to query
|
||||
_query->collections()->add(nameString, accessType);
|
||||
|
@ -1535,7 +1547,7 @@ void Ast::injectBindParameters(
|
|||
}
|
||||
|
||||
node = createNodeDataSource(resolver, name, l,
|
||||
isWriteCollection ? AccessMode::Type::WRITE : AccessMode::Type::READ
|
||||
isWriteCollection ? AccessMode::Type::WRITE : AccessMode::Type::READ, false, true
|
||||
);
|
||||
|
||||
if (isWriteCollection) {
|
||||
|
@ -3648,7 +3660,8 @@ AstNode* Ast::createNode(AstNodeType type) {
|
|||
|
||||
/// @brief validate the name of the given datasource
|
||||
std::string Ast::validateDataSourceName(char const* name,
|
||||
size_t nameLength) {
|
||||
size_t nameLength,
|
||||
bool validateStrict) {
|
||||
// common validation
|
||||
if (name == nullptr) {
|
||||
THROW_ARANGO_EXCEPTION(TRI_ERROR_OUT_OF_MEMORY);
|
||||
|
@ -3657,7 +3670,7 @@ std::string Ast::validateDataSourceName(char const* name,
|
|||
std::string const nameString(name, nameLength);
|
||||
|
||||
if (*name == '\0' || nameLength == 0 ||
|
||||
!TRI_vocbase_t::IsAllowedNameForExistingCollection(arangodb::velocypack::StringRef(name, nameLength))) {
|
||||
(validateStrict && !TRI_vocbase_t::IsAllowedName(true, arangodb::velocypack::StringRef(name, nameLength)))) {
|
||||
_query->registerErrorCustom(TRI_ERROR_ARANGO_ILLEGAL_NAME, nameString.c_str());
|
||||
return nullptr;
|
||||
}
|
||||
|
|
|
@ -227,10 +227,11 @@ class Ast {
|
|||
|
||||
/// @brief create an AST datasource
|
||||
/// this function will return either an AST collection or an AST view node
|
||||
/// the function will throw if the specified data source does not exist
|
||||
/// if failIfDoesNotExist is true, the function will throw if the specified
|
||||
/// data source does not exist
|
||||
AstNode* createNodeDataSource(arangodb::CollectionNameResolver const& resolver,
|
||||
char const* name, size_t nameLength,
|
||||
AccessMode::Type accessType);
|
||||
AccessMode::Type accessType, bool validateName, bool failIfDoesNotExist);
|
||||
|
||||
/// @brief create an AST collection node
|
||||
AstNode* createNodeCollection(char const* name, size_t nameLength, AccessMode::Type accessType);
|
||||
|
@ -564,7 +565,7 @@ class Ast {
|
|||
AstNode* createNode(AstNodeType);
|
||||
|
||||
/// @brief validate the name of the given datasource
|
||||
std::string validateDataSourceName(char const* name, size_t nameLength);
|
||||
std::string validateDataSourceName(char const* name, size_t nameLength, bool validateStrict);
|
||||
|
||||
/// @brief create an AST collection node
|
||||
/// private function, does no validation
|
||||
|
|
|
@ -757,7 +757,9 @@ void arangodb::aql::removeCollectVariablesRule(
|
|||
if (outVariable != nullptr &&
|
||||
varsUsedLater.find(outVariable) == varsUsedLater.end()) {
|
||||
// outVariable not used later
|
||||
collectNode->clearOutVariable();
|
||||
if (!collectNode->count()) {
|
||||
collectNode->clearOutVariable();
|
||||
}
|
||||
modified = true;
|
||||
} else if (outVariable != nullptr && !collectNode->count() &&
|
||||
!collectNode->hasExpressionVariable() &&
|
||||
|
|
|
@ -4062,7 +4062,7 @@ yyreduce:
|
|||
if (node == nullptr) {
|
||||
// variable not found. so it must have been a collection or view
|
||||
auto const& resolver = parser->query()->resolver();
|
||||
node = ast->createNodeDataSource(resolver, (yyvsp[0].strval).value, (yyvsp[0].strval).length, arangodb::AccessMode::Type::READ);
|
||||
node = ast->createNodeDataSource(resolver, (yyvsp[0].strval).value, (yyvsp[0].strval).length, arangodb::AccessMode::Type::READ, true, false);
|
||||
}
|
||||
|
||||
TRI_ASSERT(node != nullptr);
|
||||
|
|
|
@ -1540,7 +1540,7 @@ reference:
|
|||
if (node == nullptr) {
|
||||
// variable not found. so it must have been a collection or view
|
||||
auto const& resolver = parser->query()->resolver();
|
||||
node = ast->createNodeDataSource(resolver, $1.value, $1.length, arangodb::AccessMode::Type::READ);
|
||||
node = ast->createNodeDataSource(resolver, $1.value, $1.length, arangodb::AccessMode::Type::READ, true, false);
|
||||
}
|
||||
|
||||
TRI_ASSERT(node != nullptr);
|
||||
|
|
|
@ -1855,71 +1855,37 @@ bool TRI_vocbase_t::IsAllowedName(
|
|||
bool allowSystem,
|
||||
arangodb::velocypack::StringRef const& name
|
||||
) noexcept {
|
||||
size_t const length = name.size();
|
||||
|
||||
// invalid name length
|
||||
if (length == 0 || length > TRI_COL_NAME_LENGTH) {
|
||||
return false;
|
||||
}
|
||||
size_t length = 0;
|
||||
|
||||
char const* s = name.data();
|
||||
char const* e = name.data() + length;
|
||||
|
||||
// check allowed characters: must start with letter or underscore if system is
|
||||
// check allow characters: must start with letter or underscore if system is
|
||||
// allowed
|
||||
char const* p = s;
|
||||
|
||||
while (p < e) {
|
||||
for (char const* ptr = name.data(); length < name.size(); ++ptr, ++length) {
|
||||
bool ok;
|
||||
if (s == p) {
|
||||
// first byte of name
|
||||
if (length == 0) {
|
||||
if (allowSystem) {
|
||||
ok = (*p == '_') || ('a' <= *p && *p <= 'z') ||
|
||||
('A' <= *p && *p <= 'Z');
|
||||
ok = (*ptr == '_') || ('a' <= *ptr && *ptr <= 'z') ||
|
||||
('A' <= *ptr && *ptr <= 'Z');
|
||||
} else {
|
||||
ok = ('a' <= *p && *p <= 'z') || ('A' <= *p && *p <= 'Z');
|
||||
ok = ('a' <= *ptr && *ptr <= 'z') || ('A' <= *ptr && *ptr <= 'Z');
|
||||
}
|
||||
} else {
|
||||
ok = (*p == '_') || (*p == '-') || ('0' <= *p && *p <= '9') ||
|
||||
('a' <= *p && *p <= 'z') || ('A' <= *p && *p <= 'Z');
|
||||
ok = (*ptr == '_') || (*ptr == '-') || ('0' <= *ptr && *ptr <= '9') ||
|
||||
('a' <= *ptr && *ptr <= 'z') || ('A' <= *ptr && *ptr <= 'Z');
|
||||
}
|
||||
|
||||
if (!ok) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
++p;
|
||||
// invalid name length
|
||||
if (length == 0 || length > TRI_COL_NAME_LENGTH) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/// @brief checks if collection name is valid when referring to an existing collection
|
||||
/// this is different to the above method because here we also allow accessing
|
||||
/// collections by their numeric ID
|
||||
bool TRI_vocbase_t::IsAllowedNameForExistingCollection(
|
||||
arangodb::velocypack::StringRef const& name
|
||||
) noexcept {
|
||||
if (!name.empty()) {
|
||||
char const* p = name.data();
|
||||
char const* e = p + name.size();
|
||||
|
||||
// check if the name is just a numeric collection ID
|
||||
while (p < e && *p >= '0' && *p <= '9') {
|
||||
++p;
|
||||
}
|
||||
|
||||
if (p == e) {
|
||||
// name consisted of only numeric digits
|
||||
return true;
|
||||
}
|
||||
// not only numeric digits
|
||||
}
|
||||
|
||||
// fall back to regular check method
|
||||
return IsAllowedName(true, name);
|
||||
}
|
||||
|
||||
/// @brief determine whether a collection name is a system collection name
|
||||
/*static*/ bool TRI_vocbase_t::IsSystemName(std::string const& name) noexcept {
|
||||
return !name.empty() && name[0] == '_';
|
||||
|
|
|
@ -186,20 +186,13 @@ struct TRI_vocbase_t {
|
|||
void* _userStructures;
|
||||
|
||||
public:
|
||||
/// @brief checks if a database or collection name is allowed
|
||||
/// @brief checks if a database name is allowed
|
||||
/// returns true if the name is allowed and false otherwise
|
||||
static bool IsAllowedName(arangodb::velocypack::Slice slice) noexcept;
|
||||
static bool IsAllowedName(
|
||||
bool allowSystem,
|
||||
arangodb::velocypack::StringRef const& name
|
||||
) noexcept;
|
||||
|
||||
/// @brief checks if collection name is valid when referring to an existing collection
|
||||
/// this is different to the above method because here we also allow accessing
|
||||
/// collections by their numeric ID
|
||||
static bool IsAllowedNameForExistingCollection(
|
||||
arangodb::velocypack::StringRef const& name
|
||||
) noexcept;
|
||||
|
||||
/// @brief determine whether a data-source name is a system data-source name
|
||||
static bool IsSystemName(std::string const& name) noexcept;
|
||||
|
@ -450,4 +443,4 @@ void TRI_SanitizeObject(arangodb::velocypack::Slice const slice,
|
|||
void TRI_SanitizeObjectWithEdges(arangodb::velocypack::Slice const slice,
|
||||
arangodb::velocypack::Builder& builder);
|
||||
|
||||
#endif
|
||||
#endif
|
|
@ -180,10 +180,10 @@ function StatementSuite () {
|
|||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
testParseOk1 : function () {
|
||||
var st = db._createStatement({ query : "for u in _graphs return u" });
|
||||
var st = db._createStatement({ query : "for u in users return u" });
|
||||
var result = st.parse();
|
||||
|
||||
assertEqual([ "_graphs" ], result.collections);
|
||||
assertEqual([ "users" ], result.collections);
|
||||
assertEqual([ ], result.bindVars);
|
||||
assertTrue(result.hasOwnProperty("ast"));
|
||||
},
|
||||
|
@ -193,10 +193,10 @@ function StatementSuite () {
|
|||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
testParseOk2 : function () {
|
||||
var st = db._createStatement({ query : "for u in _graphs for f in _apps return u" });
|
||||
var st = db._createStatement({ query : "for u in users for f in friends return u" });
|
||||
var result = st.parse();
|
||||
|
||||
assertEqual([ "_apps", "_graphs" ], result.collections.sort());
|
||||
assertEqual([ "friends", "users" ], result.collections.sort());
|
||||
assertEqual([ ], result.bindVars);
|
||||
assertTrue(result.hasOwnProperty("ast"));
|
||||
},
|
||||
|
@ -220,11 +220,11 @@ function StatementSuite () {
|
|||
|
||||
testParseBind2 : function () {
|
||||
var st = db._createStatement({
|
||||
query : "for u in @@users for f in _users filter u.name == @name && f.friendId == u._id return u"
|
||||
query : "for u in @@users for f in friends filter u.name == @name && f.friendId == u._id return u"
|
||||
});
|
||||
var result = st.parse();
|
||||
|
||||
assertEqual([ "_users" ], result.collections);
|
||||
assertEqual([ "friends" ], result.collections);
|
||||
assertEqual([ "@users", "name" ], result.bindVars.sort());
|
||||
assertTrue(result.hasOwnProperty("ast"));
|
||||
},
|
||||
|
|
|
@ -118,7 +118,7 @@ function ahuacatlParseTestSuite () {
|
|||
assertParseError(errors.ERROR_QUERY_PARSE.code, "return 1 +");
|
||||
assertParseError(errors.ERROR_QUERY_PARSE.code, "return 1 + 1 +");
|
||||
assertParseError(errors.ERROR_QUERY_PARSE.code, "return (1");
|
||||
assertParseError(errors.ERROR_QUERY_PARSE.code, "for f1 in _graphs");
|
||||
assertParseError(errors.ERROR_QUERY_PARSE.code, "for f1 in x1");
|
||||
},
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
@ -128,8 +128,8 @@ function ahuacatlParseTestSuite () {
|
|||
testParameterNames : function () {
|
||||
assertEqual([ ], getParameters(getParseResults("return 1")));
|
||||
assertEqual([ ], getParameters(getParseResults("for u in [ 1, 2, 3] return 1")));
|
||||
assertEqual([ "u" ], getParameters(getParseResults("for u in _graphs return @u")));
|
||||
assertEqual([ "b" ], getParameters(getParseResults("for a in _graphs return @b")));
|
||||
assertEqual([ "u" ], getParameters(getParseResults("for u in users return @u")));
|
||||
assertEqual([ "b" ], getParameters(getParseResults("for a in b return @b")));
|
||||
assertEqual([ "b", "c" ], getParameters(getParseResults("for a in @b return @c")));
|
||||
assertEqual([ "friends", "relations", "u", "users" ], getParameters(getParseResults("for u in @users for f in @friends for r in @relations return @u")));
|
||||
assertEqual([ "friends", "relations", "u", "users" ], getParameters(getParseResults("for r in @relations for f in @friends for u in @users return @u")));
|
||||
|
@ -146,12 +146,12 @@ function ahuacatlParseTestSuite () {
|
|||
testCollectionNames : function () {
|
||||
assertEqual([ ], getCollections(getParseResults("return 1")));
|
||||
assertEqual([ ], getCollections(getParseResults("for u in [ 1, 2, 3] return 1")));
|
||||
assertEqual([ "_graphs" ], getCollections(getParseResults("for u in _graphs return u")));
|
||||
assertEqual([ "_graphs" ], getCollections(getParseResults("for a in _graphs return _graphs")));
|
||||
assertEqual([ "_apps", "_graphs", "_users" ], getCollections(getParseResults("for u in _graphs for f in _users for r in _apps return u")));
|
||||
assertEqual([ "_apps", "_graphs", "_users" ], getCollections(getParseResults("for r in _apps for f in _users for u in _graphs return u")));
|
||||
assertEqual([ "_graphs" ], getCollections(getParseResults("for r in (for x in _graphs return 1) return r")));
|
||||
assertEqual([ "_graphs" ], getCollections(getParseResults("for r in [ 1, 2 ] return _graphs")));
|
||||
assertEqual([ "users" ], getCollections(getParseResults("for u in users return u")));
|
||||
assertEqual([ "b" ], getCollections(getParseResults("for a in b return b")));
|
||||
assertEqual([ "friends", "relations", "users" ], getCollections(getParseResults("for u in users for f in friends for r in relations return u")));
|
||||
assertEqual([ "friends", "relations", "users" ], getCollections(getParseResults("for r in relations for f in friends for u in users return u")));
|
||||
assertEqual([ "hans" ], getCollections(getParseResults("for r in (for x in hans return 1) return r")));
|
||||
assertEqual([ "hans" ], getCollections(getParseResults("for r in [ 1, 2 ] return hans")));
|
||||
},
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
@ -232,24 +232,7 @@ function ahuacatlParseTestSuite () {
|
|||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
testTooManyCollections : function () {
|
||||
try {
|
||||
for (let y = 0; y <= 257; ++y) {
|
||||
internal.db._create("y" + y, { replicationFactor: 1, numberOfShards: 1 });
|
||||
}
|
||||
assertParseError(errors.ERROR_QUERY_TOO_MANY_COLLECTIONS.code, "for x0 in y0 for x1 in y1 for x2 in y2 for x3 in y3 for x4 in y4 for x5 in y5 for x6 in y6 for x7 in y7 for x8 in y8 for x9 in y9 for x10 in y10 for x11 in y11 for x12 in y12 for x13 in y13 for x14 in y14 for x15 in y15 for x16 in y16 for x17 in y17 for x18 in y18 for x19 in y19 for x20 in y20 for x21 in y21 for x22 in y22 for x23 in y23 for x24 in y24 for x25 in y25 for x26 in y26 for x27 in y27 for x28 in y28 for x29 in y29 for x30 in y30 for x31 in y31 for x32 in y32 for x33 in y33 for x34 in y34 for x35 in y35 for x36 in y36 for x37 in y37 for x38 in y38 for x39 in y39 for x40 in y40 for x41 in y41 for x42 in y42 for x43 in y43 for x44 in y44 for x45 in y45 for x46 in y46 for x47 in y47 for x48 in y48 for x49 in y49 for x50 in y50 for x51 in y51 for x52 in y52 for x53 in y53 for x54 in y54 for x55 in y55 for x56 in y56 for x57 in y57 for x58 in y58 for x59 in y59 for x60 in y60 for x61 in y61 for x62 in y62 for x63 in y63 for x64 in y64 for x65 in y65 for x66 in y66 for x67 in y67 for x68 in y68 for x69 in y69 for x70 in y70 for x71 in y71 for x72 in y72 for x73 in y73 for x74 in y74 for x75 in y75 for x76 in y76 for x77 in y77 for x78 in y78 for x79 in y79 for x80 in y80 for x81 in y81 for x82 in y82 for x83 in y83 for x84 in y84 for x85 in y85 for x86 in y86 for x87 in y87 for x88 in y88 for x89 in y89 for x90 in y90 for x91 in y91 for x92 in y92 for x93 in y93 for x94 in y94 for x95 in y95 for x96 in y96 for x97 in y97 for x98 in y98 for x99 in y99 for x100 in y100 for x101 in y101 for x102 in y102 for x103 in y103 for x104 in y104 for x105 in y105 for x106 in y106 for x107 in y107 for x108 in y108 for x109 in y109 for x110 in y110 for x111 in y111 for x112 in y112 for x113 in y113 for x114 in y114 for x115 in y115 for x116 in y116 for x117 in y117 for x118 in y118 for x119 in y119 for x120 in y120 for x121 in y121 for x122 in y122 for x123 in y123 for x124 in y124 for x125 in y125 for x126 in y126 for x127 in y127 for x128 in y128 for x129 in y129 for x130 in y130 for x131 in y131 for x132 in y132 for x133 in y133 for x134 in y134 for x135 in y135 for x136 in y136 for x137 in y137 for x138 in y138 for x139 in y139 for x140 in y140 for x141 in y141 for x142 in y142 for x143 in y143 for x144 in y144 for x145 in y145 for x146 in y146 for x147 in y147 for x148 in y148 for x149 in y149 for x150 in y150 for x151 in y151 for x152 in y152 for x153 in y153 for x154 in y154 for x155 in y155 for x156 in y156 for x157 in y157 for x158 in y158 for x159 in y159 for x160 in y160 for x161 in y161 for x162 in y162 for x163 in y163 for x164 in y164 for x165 in y165 for x166 in y166 for x167 in y167 for x168 in y168 for x169 in y169 for x170 in y170 for x171 in y171 for x172 in y172 for x173 in y173 for x174 in y174 for x175 in y175 for x176 in y176 for x177 in y177 for x178 in y178 for x179 in y179 for x180 in y180 for x181 in y181 for x182 in y182 for x183 in y183 for x184 in y184 for x185 in y185 for x186 in y186 for x187 in y187 for x188 in y188 for x189 in y189 for x190 in y190 for x191 in y191 for x192 in y192 for x193 in y193 for x194 in y194 for x195 in y195 for x196 in y196 for x197 in y197 for x198 in y198 for x199 in y199 for x200 in y200 for x201 in y201 for x202 in y202 for x203 in y203 for x204 in y204 for x205 in y205 for x206 in y206 for x207 in y207 for x208 in y208 for x209 in y209 for x210 in y210 for x211 in y211 for x212 in y212 for x213 in y213 for x214 in y214 for x215 in y215 for x216 in y216 for x217 in y217 for x218 in y218 for x219 in y219 for x220 in y220 for x221 in y221 for x222 in y222 for x223 in y223 for x224 in y224 for x225 in y225 for x226 in y226 for x227 in y227 for x228 in y228 for x229 in y229 for x230 in y230 for x231 in y231 for x232 in y232 for x233 in y233 for x234 in y234 for x235 in y235 for x236 in y236 for x237 in y237 for x238 in y238 for x239 in y239 for x240 in y240 for x241 in y241 for x242 in y242 for x243 in y243 for x244 in y244 for x245 in y245 for x246 in y246 for x247 in y247 for x248 in y248 for x249 in y249 for x250 in y250 for x251 in y251 for x252 in y252 for x253 in y253 for x254 in y254 for x255 in y255 for x256 in y256 for x257 in y257 return x1");
|
||||
} finally {
|
||||
for (let y = 0; y <= 257; ++y) {
|
||||
internal.db._drop("y" + y);
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief test too many collections
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
testTooManyCollectionsNonExisting : function () {
|
||||
assertParseError(errors.ERROR_ARANGO_DATA_SOURCE_NOT_FOUND.code, "for x0 in y0 for x1 in y1 for x2 in y2 for x3 in y3 for x4 in y4 for x5 in y5 for x6 in y6 for x7 in y7 for x8 in y8 for x9 in y9 for x10 in y10 for x11 in y11 for x12 in y12 for x13 in y13 for x14 in y14 for x15 in y15 for x16 in y16 for x17 in y17 for x18 in y18 for x19 in y19 for x20 in y20 for x21 in y21 for x22 in y22 for x23 in y23 for x24 in y24 for x25 in y25 for x26 in y26 for x27 in y27 for x28 in y28 for x29 in y29 for x30 in y30 for x31 in y31 for x32 in y32 for x33 in y33 for x34 in y34 for x35 in y35 for x36 in y36 for x37 in y37 for x38 in y38 for x39 in y39 for x40 in y40 for x41 in y41 for x42 in y42 for x43 in y43 for x44 in y44 for x45 in y45 for x46 in y46 for x47 in y47 for x48 in y48 for x49 in y49 for x50 in y50 for x51 in y51 for x52 in y52 for x53 in y53 for x54 in y54 for x55 in y55 for x56 in y56 for x57 in y57 for x58 in y58 for x59 in y59 for x60 in y60 for x61 in y61 for x62 in y62 for x63 in y63 for x64 in y64 for x65 in y65 for x66 in y66 for x67 in y67 for x68 in y68 for x69 in y69 for x70 in y70 for x71 in y71 for x72 in y72 for x73 in y73 for x74 in y74 for x75 in y75 for x76 in y76 for x77 in y77 for x78 in y78 for x79 in y79 for x80 in y80 for x81 in y81 for x82 in y82 for x83 in y83 for x84 in y84 for x85 in y85 for x86 in y86 for x87 in y87 for x88 in y88 for x89 in y89 for x90 in y90 for x91 in y91 for x92 in y92 for x93 in y93 for x94 in y94 for x95 in y95 for x96 in y96 for x97 in y97 for x98 in y98 for x99 in y99 for x100 in y100 for x101 in y101 for x102 in y102 for x103 in y103 for x104 in y104 for x105 in y105 for x106 in y106 for x107 in y107 for x108 in y108 for x109 in y109 for x110 in y110 for x111 in y111 for x112 in y112 for x113 in y113 for x114 in y114 for x115 in y115 for x116 in y116 for x117 in y117 for x118 in y118 for x119 in y119 for x120 in y120 for x121 in y121 for x122 in y122 for x123 in y123 for x124 in y124 for x125 in y125 for x126 in y126 for x127 in y127 for x128 in y128 for x129 in y129 for x130 in y130 for x131 in y131 for x132 in y132 for x133 in y133 for x134 in y134 for x135 in y135 for x136 in y136 for x137 in y137 for x138 in y138 for x139 in y139 for x140 in y140 for x141 in y141 for x142 in y142 for x143 in y143 for x144 in y144 for x145 in y145 for x146 in y146 for x147 in y147 for x148 in y148 for x149 in y149 for x150 in y150 for x151 in y151 for x152 in y152 for x153 in y153 for x154 in y154 for x155 in y155 for x156 in y156 for x157 in y157 for x158 in y158 for x159 in y159 for x160 in y160 for x161 in y161 for x162 in y162 for x163 in y163 for x164 in y164 for x165 in y165 for x166 in y166 for x167 in y167 for x168 in y168 for x169 in y169 for x170 in y170 for x171 in y171 for x172 in y172 for x173 in y173 for x174 in y174 for x175 in y175 for x176 in y176 for x177 in y177 for x178 in y178 for x179 in y179 for x180 in y180 for x181 in y181 for x182 in y182 for x183 in y183 for x184 in y184 for x185 in y185 for x186 in y186 for x187 in y187 for x188 in y188 for x189 in y189 for x190 in y190 for x191 in y191 for x192 in y192 for x193 in y193 for x194 in y194 for x195 in y195 for x196 in y196 for x197 in y197 for x198 in y198 for x199 in y199 for x200 in y200 for x201 in y201 for x202 in y202 for x203 in y203 for x204 in y204 for x205 in y205 for x206 in y206 for x207 in y207 for x208 in y208 for x209 in y209 for x210 in y210 for x211 in y211 for x212 in y212 for x213 in y213 for x214 in y214 for x215 in y215 for x216 in y216 for x217 in y217 for x218 in y218 for x219 in y219 for x220 in y220 for x221 in y221 for x222 in y222 for x223 in y223 for x224 in y224 for x225 in y225 for x226 in y226 for x227 in y227 for x228 in y228 for x229 in y229 for x230 in y230 for x231 in y231 for x232 in y232 for x233 in y233 for x234 in y234 for x235 in y235 for x236 in y236 for x237 in y237 for x238 in y238 for x239 in y239 for x240 in y240 for x241 in y241 for x242 in y242 for x243 in y243 for x244 in y244 for x245 in y245 for x246 in y246 for x247 in y247 for x248 in y248 for x249 in y249 for x250 in y250 for x251 in y251 for x252 in y252 for x253 in y253 for x254 in y254 for x255 in y255 for x256 in y256 for x257 in y257 return x1");
|
||||
assertParseError(errors.ERROR_QUERY_TOO_MANY_COLLECTIONS.code, "for x0 in y0 for x1 in y1 for x2 in y2 for x3 in y3 for x4 in y4 for x5 in y5 for x6 in y6 for x7 in y7 for x8 in y8 for x9 in y9 for x10 in y10 for x11 in y11 for x12 in y12 for x13 in y13 for x14 in y14 for x15 in y15 for x16 in y16 for x17 in y17 for x18 in y18 for x19 in y19 for x20 in y20 for x21 in y21 for x22 in y22 for x23 in y23 for x24 in y24 for x25 in y25 for x26 in y26 for x27 in y27 for x28 in y28 for x29 in y29 for x30 in y30 for x31 in y31 for x32 in y32 for x33 in y33 for x34 in y34 for x35 in y35 for x36 in y36 for x37 in y37 for x38 in y38 for x39 in y39 for x40 in y40 for x41 in y41 for x42 in y42 for x43 in y43 for x44 in y44 for x45 in y45 for x46 in y46 for x47 in y47 for x48 in y48 for x49 in y49 for x50 in y50 for x51 in y51 for x52 in y52 for x53 in y53 for x54 in y54 for x55 in y55 for x56 in y56 for x57 in y57 for x58 in y58 for x59 in y59 for x60 in y60 for x61 in y61 for x62 in y62 for x63 in y63 for x64 in y64 for x65 in y65 for x66 in y66 for x67 in y67 for x68 in y68 for x69 in y69 for x70 in y70 for x71 in y71 for x72 in y72 for x73 in y73 for x74 in y74 for x75 in y75 for x76 in y76 for x77 in y77 for x78 in y78 for x79 in y79 for x80 in y80 for x81 in y81 for x82 in y82 for x83 in y83 for x84 in y84 for x85 in y85 for x86 in y86 for x87 in y87 for x88 in y88 for x89 in y89 for x90 in y90 for x91 in y91 for x92 in y92 for x93 in y93 for x94 in y94 for x95 in y95 for x96 in y96 for x97 in y97 for x98 in y98 for x99 in y99 for x100 in y100 for x101 in y101 for x102 in y102 for x103 in y103 for x104 in y104 for x105 in y105 for x106 in y106 for x107 in y107 for x108 in y108 for x109 in y109 for x110 in y110 for x111 in y111 for x112 in y112 for x113 in y113 for x114 in y114 for x115 in y115 for x116 in y116 for x117 in y117 for x118 in y118 for x119 in y119 for x120 in y120 for x121 in y121 for x122 in y122 for x123 in y123 for x124 in y124 for x125 in y125 for x126 in y126 for x127 in y127 for x128 in y128 for x129 in y129 for x130 in y130 for x131 in y131 for x132 in y132 for x133 in y133 for x134 in y134 for x135 in y135 for x136 in y136 for x137 in y137 for x138 in y138 for x139 in y139 for x140 in y140 for x141 in y141 for x142 in y142 for x143 in y143 for x144 in y144 for x145 in y145 for x146 in y146 for x147 in y147 for x148 in y148 for x149 in y149 for x150 in y150 for x151 in y151 for x152 in y152 for x153 in y153 for x154 in y154 for x155 in y155 for x156 in y156 for x157 in y157 for x158 in y158 for x159 in y159 for x160 in y160 for x161 in y161 for x162 in y162 for x163 in y163 for x164 in y164 for x165 in y165 for x166 in y166 for x167 in y167 for x168 in y168 for x169 in y169 for x170 in y170 for x171 in y171 for x172 in y172 for x173 in y173 for x174 in y174 for x175 in y175 for x176 in y176 for x177 in y177 for x178 in y178 for x179 in y179 for x180 in y180 for x181 in y181 for x182 in y182 for x183 in y183 for x184 in y184 for x185 in y185 for x186 in y186 for x187 in y187 for x188 in y188 for x189 in y189 for x190 in y190 for x191 in y191 for x192 in y192 for x193 in y193 for x194 in y194 for x195 in y195 for x196 in y196 for x197 in y197 for x198 in y198 for x199 in y199 for x200 in y200 for x201 in y201 for x202 in y202 for x203 in y203 for x204 in y204 for x205 in y205 for x206 in y206 for x207 in y207 for x208 in y208 for x209 in y209 for x210 in y210 for x211 in y211 for x212 in y212 for x213 in y213 for x214 in y214 for x215 in y215 for x216 in y216 for x217 in y217 for x218 in y218 for x219 in y219 for x220 in y220 for x221 in y221 for x222 in y222 for x223 in y223 for x224 in y224 for x225 in y225 for x226 in y226 for x227 in y227 for x228 in y228 for x229 in y229 for x230 in y230 for x231 in y231 for x232 in y232 for x233 in y233 for x234 in y234 for x235 in y235 for x236 in y236 for x237 in y237 for x238 in y238 for x239 in y239 for x240 in y240 for x241 in y241 for x242 in y242 for x243 in y243 for x244 in y244 for x245 in y245 for x246 in y246 for x247 in y247 for x248 in y248 for x249 in y249 for x250 in y250 for x251 in y251 for x252 in y252 for x253 in y253 for x254 in y254 for x255 in y255 for x256 in y256 for x257 in y257 return x1");
|
||||
},
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
|
Loading…
Reference in New Issue