mirror of https://gitee.com/bigwinds/arangodb
fixed subquery nodes
This commit is contained in:
parent
92654e3d06
commit
f6dc5243ce
|
@ -92,7 +92,7 @@ void AstNode::toJson (TRI_json_t* json,
|
|||
TRI_Insert3ArrayJson(zone, node, "value", TRI_CreateStringCopyJson(zone, "null"));
|
||||
break;
|
||||
case VALUE_TYPE_BOOL:
|
||||
TRI_Insert3ArrayJson(zone, node, "value", TRI_CreateStringCopyJson(zone, value.value._bool ? "true" : "false"));
|
||||
TRI_Insert3ArrayJson(zone, node, "value", TRI_CreateBooleanJson(zone, value.value._bool));
|
||||
break;
|
||||
case VALUE_TYPE_INT:
|
||||
TRI_Insert3ArrayJson(zone, node, "value", TRI_CreateNumberJson(zone, static_cast<double>(value.value._int)));
|
||||
|
|
|
@ -49,7 +49,6 @@ Parser::Parser (Query* query)
|
|||
_remainingLength(query->queryLength()),
|
||||
_offset(0),
|
||||
_marker(nullptr),
|
||||
_subQueryCount(0),
|
||||
_uniqueId(0),
|
||||
_stack() {
|
||||
|
||||
|
@ -87,7 +86,7 @@ bool Parser::configureWriteQuery (QueryType type,
|
|||
TRI_ASSERT(type != AQL_QUERY_READ);
|
||||
|
||||
// check if we currently are in a subquery
|
||||
if (isInSubQuery()) {
|
||||
if (_ast->isInSubQuery()) {
|
||||
// data modification not allowed in sub-queries
|
||||
registerError(TRI_ERROR_QUERY_MODIFY_IN_SUBQUERY);
|
||||
return false;
|
||||
|
|
|
@ -117,31 +117,6 @@ namespace triagens {
|
|||
return _ast;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief start a subquery
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
inline void startSubQuery () {
|
||||
++_subQueryCount;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief end a subquery
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
inline void endSubQuery () {
|
||||
TRI_ASSERT(_subQueryCount > 0);
|
||||
--_subQueryCount;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief whether or not we are in a subquery
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
inline bool isInSubQuery () const {
|
||||
return (_subQueryCount > 0);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief return the scanner
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
@ -290,7 +265,6 @@ namespace triagens {
|
|||
size_t _offset; // current parse position
|
||||
char const* _marker; // a position used temporarily during parsing
|
||||
|
||||
size_t _subQueryCount; // number of active subqueries
|
||||
size_t _uniqueId; // a counter to generate unique (temporary) variable names
|
||||
|
||||
|
||||
|
|
|
@ -64,6 +64,7 @@ QueryAst::QueryAst (Query* query,
|
|||
_bindParameters(),
|
||||
_collectionNames(),
|
||||
_root(nullptr),
|
||||
_queries(),
|
||||
_writeCollection(nullptr),
|
||||
_writeOptions(nullptr) {
|
||||
|
||||
|
@ -71,7 +72,11 @@ QueryAst::QueryAst (Query* query,
|
|||
TRI_ASSERT(_parser != nullptr);
|
||||
|
||||
_nodes.reserve(32);
|
||||
_root = createNode(NODE_TYPE_ROOT);
|
||||
_strings.reserve(32);
|
||||
|
||||
startSubQuery();
|
||||
|
||||
TRI_ASSERT(_root != nullptr);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
@ -496,14 +501,16 @@ AstNode* QueryAst::createNodeTernaryOperator (AstNode const* condition,
|
|||
/// @brief create an AST subquery node
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
AstNode* QueryAst::createNodeSubquery (char const* tempName) {
|
||||
if (tempName == nullptr) {
|
||||
AstNode* QueryAst::createNodeSubquery (char const* variableName,
|
||||
AstNode const* subQuery) {
|
||||
if (variableName == nullptr) {
|
||||
THROW_ARANGO_EXCEPTION(TRI_ERROR_OUT_OF_MEMORY);
|
||||
}
|
||||
|
||||
AstNode* node = createNode(NODE_TYPE_SUBQUERY);
|
||||
AstNode* variable = createNodeVariable(tempName, false);
|
||||
AstNode* variable = createNodeVariable(variableName, false);
|
||||
node->addMember(variable);
|
||||
node->addMember(subQuery);
|
||||
|
||||
return node;
|
||||
}
|
||||
|
|
|
@ -87,6 +87,57 @@ namespace triagens {
|
|||
|
||||
public:
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief begin a subquery
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
void startSubQuery () {
|
||||
// insert a new root node
|
||||
AstNodeType type;
|
||||
|
||||
if (_queries.empty()) {
|
||||
// root node of query
|
||||
type = NODE_TYPE_ROOT;
|
||||
}
|
||||
else {
|
||||
// sub query node
|
||||
type = NODE_TYPE_SUBQUERY;
|
||||
}
|
||||
|
||||
auto root = createNode(type);
|
||||
|
||||
// save the root node
|
||||
_queries.push_back(root);
|
||||
|
||||
// set the current root node if everything went well
|
||||
_root = root;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief end a subquery
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
AstNode* endSubQuery () {
|
||||
// get the current root node
|
||||
AstNode* root = _queries.back();
|
||||
// remove it from the stack
|
||||
_queries.pop_back();
|
||||
|
||||
// set root node to previous root node
|
||||
_root = _queries.back();
|
||||
|
||||
// return the root node we just popped from the stack
|
||||
return root;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief whether or not we currently are in a subquery
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
bool isInSubQuery () const {
|
||||
return (_queries.size() > 1);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief return a copy of our own bind parameters
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
@ -297,7 +348,8 @@ namespace triagens {
|
|||
/// @brief create an AST subquery node
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
AstNode* createNodeSubquery (char const*);
|
||||
AstNode* createNodeSubquery (char const*,
|
||||
AstNode const*);
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief create an AST attribute access node
|
||||
|
@ -563,6 +615,12 @@ namespace triagens {
|
|||
|
||||
AstNode* _root;
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief root nodes of queries and subqueries
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
std::vector<AstNode*> _queries;
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief which collection is going to be modified in the query
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
|
|
@ -434,16 +434,16 @@ expression:
|
|||
}
|
||||
| T_OPEN {
|
||||
parser->ast()->scopes()->start(triagens::aql::AQL_SCOPE_SUBQUERY);
|
||||
parser->startSubQuery();
|
||||
parser->ast()->startSubQuery();
|
||||
} query T_CLOSE {
|
||||
parser->endSubQuery();
|
||||
AstNode* node = parser->ast()->endSubQuery();
|
||||
parser->ast()->scopes()->endCurrent();
|
||||
|
||||
char const* tempName = parser->generateName();
|
||||
auto subQuery = parser->ast()->createNodeSubquery(tempName);
|
||||
char const* variableName = parser->generateName();
|
||||
auto subQuery = parser->ast()->createNodeLet(variableName, node, false);
|
||||
parser->ast()->addOperation(subQuery);
|
||||
|
||||
$$ = parser->ast()->createNodeReference(tempName);
|
||||
$$ = parser->ast()->createNodeReference(variableName);
|
||||
}
|
||||
| operator_unary {
|
||||
$$ = $1;
|
||||
|
|
Loading…
Reference in New Issue