mirror of https://gitee.com/bigwinds/arangodb
Bug fix 3.4/disallow subqueries in prune (#10266)
* backport of #10231 * added derived files
This commit is contained in:
parent
ae508c71ba
commit
69747bc86f
|
@ -1,6 +1,11 @@
|
|||
v3.4.9 (XXX-XX-XX)
|
||||
-------------------
|
||||
|
||||
* Disallow the usage of subqueries inside AQL traversal PRUNE conditions.
|
||||
Using subqueries inside PRUNE conditions causes undefined behavior,
|
||||
so such queries will now be aborted early on with a parse error
|
||||
instead of running into undefined behavior.
|
||||
|
||||
* Fixed search not working in document view while in code mode.
|
||||
|
||||
* Fixed issue #10090: fix repeatable seek to the same document in
|
||||
|
|
|
@ -743,6 +743,23 @@ AstNode* Ast::createNodeReference(Variable const* variable) {
|
|||
return node;
|
||||
}
|
||||
|
||||
/// @brief create an AST subquery reference node
|
||||
AstNode* Ast::createNodeSubqueryReference(std::string const& variableName) {
|
||||
AstNode* node = createNode(NODE_TYPE_REFERENCE);
|
||||
node->setFlag(AstNodeFlagType::FLAG_SUBQUERY_REFERENCE);
|
||||
|
||||
auto variable = _scopes.getVariable(variableName);
|
||||
|
||||
if (variable == nullptr) {
|
||||
THROW_ARANGO_EXCEPTION_MESSAGE(TRI_ERROR_INTERNAL,
|
||||
"variable not found in reference AstNode");
|
||||
}
|
||||
|
||||
node->setData(variable);
|
||||
|
||||
return node;
|
||||
}
|
||||
|
||||
/// @brief create an AST variable access
|
||||
AstNode* Ast::createNodeAccess(Variable const* variable,
|
||||
std::vector<basics::AttributeName> const& field) {
|
||||
|
|
|
@ -246,6 +246,9 @@ class Ast {
|
|||
/// @brief create an AST reference node
|
||||
AstNode* createNodeReference(Variable const* variable);
|
||||
|
||||
/// @brief create an AST subquery reference node
|
||||
AstNode* createNodeSubqueryReference(std::string const& variableName);
|
||||
|
||||
/// @brief create an AST parameter node for a value literal
|
||||
AstNode* createNodeParameter(char const* name, size_t length);
|
||||
|
||||
|
|
|
@ -71,6 +71,7 @@ enum AstNodeFlagType : AstNodeFlagsType {
|
|||
FLAG_KEEP_VARIABLENAME = 0x0010000, // node is a reference to a variable name, not the variable value (used in KEEP nodes)
|
||||
FLAG_BIND_PARAMETER = 0x0020000, // node was created from a bind parameter
|
||||
FLAG_FINALIZED = 0x0040000, // node has been finalized and should not be modified; only set and checked in maintainer mode
|
||||
FLAG_SUBQUERY_REFERENCE = 0x0080000, // node references a subquery
|
||||
};
|
||||
|
||||
/// @brief enumeration of AST node value types
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -1,8 +1,9 @@
|
|||
/* A Bison parser, made by GNU Bison 3.0.4. */
|
||||
/* A Bison parser, made by GNU Bison 3.3.2. */
|
||||
|
||||
/* Bison interface for Yacc-like parsers in C
|
||||
|
||||
Copyright (C) 1984, 1989-1990, 2000-2015 Free Software Foundation, Inc.
|
||||
Copyright (C) 1984, 1989-1990, 2000-2015, 2018-2019 Free Software Foundation,
|
||||
Inc.
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
|
@ -30,6 +31,9 @@
|
|||
This special exception was added by the Free Software Foundation in
|
||||
version 2.2 of Bison. */
|
||||
|
||||
/* Undocumented macros, especially those whose name start with YY_,
|
||||
are private implementation details. Do not rely on them. */
|
||||
|
||||
#ifndef YY_AQL_AQL_GRAMMAR_HPP_INCLUDED
|
||||
# define YY_AQL_AQL_GRAMMAR_HPP_INCLUDED
|
||||
/* Debug traces. */
|
||||
|
@ -125,7 +129,7 @@ extern int Aqldebug;
|
|||
|
||||
union YYSTYPE
|
||||
{
|
||||
#line 34 "Aql/grammar.y" /* yacc.c:1909 */
|
||||
#line 34 "Aql/grammar.y" /* yacc.c:1921 */
|
||||
|
||||
arangodb::aql::AstNode* node;
|
||||
struct {
|
||||
|
@ -135,7 +139,7 @@ union YYSTYPE
|
|||
bool boolval;
|
||||
int64_t intval;
|
||||
|
||||
#line 139 "Aql/grammar.hpp" /* yacc.c:1909 */
|
||||
#line 143 "Aql/grammar.hpp" /* yacc.c:1921 */
|
||||
};
|
||||
|
||||
typedef union YYSTYPE YYSTYPE;
|
||||
|
|
|
@ -1,8 +1,9 @@
|
|||
/* A Bison parser, made by GNU Bison 3.0.4. */
|
||||
/* A Bison parser, made by GNU Bison 3.3.2. */
|
||||
|
||||
/* Bison interface for Yacc-like parsers in C
|
||||
|
||||
Copyright (C) 1984, 1989-1990, 2000-2015 Free Software Foundation, Inc.
|
||||
Copyright (C) 1984, 1989-1990, 2000-2015, 2018-2019 Free Software Foundation,
|
||||
Inc.
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
|
@ -30,6 +31,9 @@
|
|||
This special exception was added by the Free Software Foundation in
|
||||
version 2.2 of Bison. */
|
||||
|
||||
/* Undocumented macros, especially those whose name start with YY_,
|
||||
are private implementation details. Do not rely on them. */
|
||||
|
||||
#ifndef YY_AQL_AQL_GRAMMAR_HPP_INCLUDED
|
||||
# define YY_AQL_AQL_GRAMMAR_HPP_INCLUDED
|
||||
/* Debug traces. */
|
||||
|
@ -125,7 +129,7 @@ extern int Aqldebug;
|
|||
|
||||
union YYSTYPE
|
||||
{
|
||||
#line 34 "Aql/grammar.y" /* yacc.c:1909 */
|
||||
#line 34 "Aql/grammar.y" /* yacc.c:1921 */
|
||||
|
||||
arangodb::aql::AstNode* node;
|
||||
struct {
|
||||
|
@ -135,7 +139,7 @@ union YYSTYPE
|
|||
bool boolval;
|
||||
int64_t intval;
|
||||
|
||||
#line 139 "Aql/grammar.hpp" /* yacc.c:1909 */
|
||||
#line 143 "Aql/grammar.hpp" /* yacc.c:1921 */
|
||||
};
|
||||
|
||||
typedef union YYSTYPE YYSTYPE;
|
||||
|
|
|
@ -566,7 +566,6 @@ prune_and_options:
|
|||
node->addMember($2);
|
||||
// Options
|
||||
node->addMember($4);
|
||||
|
||||
}
|
||||
;
|
||||
|
||||
|
@ -687,6 +686,15 @@ for_statement:
|
|||
} prune_and_options {
|
||||
auto graphInfoNode = static_cast<AstNode*>(parser->popStack());
|
||||
auto variablesNode = static_cast<AstNode*>(parser->popStack());
|
||||
|
||||
auto prune = graphInfoNode->getMember(3);
|
||||
if (prune != nullptr) {
|
||||
Ast::traverseReadOnly(prune, [&](AstNode const* node) {
|
||||
if (node->type == NODE_TYPE_REFERENCE && node->hasFlag(AstNodeFlagType::FLAG_SUBQUERY_REFERENCE)) {
|
||||
parser->registerParseError(TRI_ERROR_QUERY_PARSE, "prune condition must not use a subquery", yylloc.first_line, yylloc.first_column);
|
||||
}
|
||||
});
|
||||
}
|
||||
auto node = parser->ast()->createNodeTraversal(variablesNode, graphInfoNode);
|
||||
parser->ast()->addOperation(node);
|
||||
}
|
||||
|
@ -1416,7 +1424,7 @@ expression_or_query:
|
|||
auto subQuery = parser->ast()->createNodeLet(variableName.c_str(), variableName.size(), node, false);
|
||||
parser->ast()->addOperation(subQuery);
|
||||
|
||||
$$ = parser->ast()->createNodeReference(variableName);
|
||||
$$ = parser->ast()->createNodeSubqueryReference(variableName);
|
||||
}
|
||||
;
|
||||
|
||||
|
|
|
@ -2021,6 +2021,20 @@ function complexFilteringSuite() {
|
|||
|
||||
tearDownAll: cleanup,
|
||||
|
||||
testPruneWithSubquery: function () {
|
||||
let query = `FOR v,e,p IN 1..100 OUTBOUND @start @ecol PRUNE 2 <= LENGTH(FOR w IN p.vertices FILTER w._id == v._id RETURN 1) RETURN p`;
|
||||
try {
|
||||
let bindVars = {
|
||||
'@eCol': en,
|
||||
'start': vertex.Tri1
|
||||
};
|
||||
db._query(query, bindVars);
|
||||
fail();
|
||||
} catch (err) {
|
||||
assertEqual(err.errorNum, errors.ERROR_QUERY_PARSE.code);
|
||||
}
|
||||
},
|
||||
|
||||
testVertexEarlyPruneHighDepth: function () {
|
||||
var query = `WITH ${vn}
|
||||
FOR v, e, p IN 100 OUTBOUND @start @@eCol
|
||||
|
|
Loading…
Reference in New Issue