1
0
Fork 0

fixed subquery nodes

This commit is contained in:
Jan Steemann 2014-07-29 16:23:21 +02:00
parent 92654e3d06
commit f6dc5243ce
6 changed files with 77 additions and 39 deletions

View File

@ -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)));

View File

@ -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;

View File

@ -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

View File

@ -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;
}

View File

@ -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
////////////////////////////////////////////////////////////////////////////////

View File

@ -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;