mirror of https://gitee.com/bigwinds/arangodb
Merge branch 'aql2' of ssh://github.com/triAGENS/ArangoDB into aql2
This commit is contained in:
commit
450a27a15d
|
@ -0,0 +1,291 @@
|
|||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief Aql, AST node
|
||||
///
|
||||
/// @file
|
||||
///
|
||||
/// DISCLAIMER
|
||||
///
|
||||
/// Copyright 2014 ArangoDB GmbH, Cologne, Germany
|
||||
/// Copyright 2004-2014 triAGENS GmbH, Cologne, Germany
|
||||
///
|
||||
/// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
/// you may not use this file except in compliance with the License.
|
||||
/// You may obtain a copy of the License at
|
||||
///
|
||||
/// http://www.apache.org/licenses/LICENSE-2.0
|
||||
///
|
||||
/// Unless required by applicable law or agreed to in writing, software
|
||||
/// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
/// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
/// See the License for the specific language governing permissions and
|
||||
/// limitations under the License.
|
||||
///
|
||||
/// Copyright holder is ArangoDB GmbH, Cologne, Germany
|
||||
///
|
||||
/// @author Jan Steemann
|
||||
/// @author Copyright 2014, ArangoDB GmbH, Cologne, Germany
|
||||
/// @author Copyright 2012-2013, triAGENS GmbH, Cologne, Germany
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#ifndef ARANGODB_AQL_ASTNODE_H
|
||||
#define ARANGODB_AQL_ASTNODE_H 1
|
||||
|
||||
#include "Basics/Common.h"
|
||||
#include "BasicsC/vector.h"
|
||||
#include "Utils/Exception.h"
|
||||
|
||||
namespace triagens {
|
||||
namespace aql {
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief enumeration of AST node value types
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
enum AstNodeValueType {
|
||||
VALUE_TYPE_FAIL = 0,
|
||||
VALUE_TYPE_NULL,
|
||||
VALUE_TYPE_INT,
|
||||
VALUE_TYPE_DOUBLE,
|
||||
VALUE_TYPE_BOOL,
|
||||
VALUE_TYPE_STRING
|
||||
};
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief AST node value
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
struct AstNodeValue {
|
||||
union {
|
||||
int64_t _int;
|
||||
double _double;
|
||||
bool _bool;
|
||||
char const* _string;
|
||||
} value;
|
||||
AstNodeValueType type;
|
||||
};
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief enumeration of AST node types
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
enum AstNodeType {
|
||||
NODE_TYPE_ROOT,
|
||||
NODE_TYPE_SCOPE_START,
|
||||
NODE_TYPE_SCOPE_END,
|
||||
NODE_TYPE_FOR,
|
||||
NODE_TYPE_LET,
|
||||
NODE_TYPE_FILTER,
|
||||
NODE_TYPE_RETURN,
|
||||
NODE_TYPE_REMOVE,
|
||||
NODE_TYPE_INSERT,
|
||||
NODE_TYPE_UPDATE,
|
||||
NODE_TYPE_REPLACE,
|
||||
NODE_TYPE_COLLECT,
|
||||
NODE_TYPE_SORT,
|
||||
NODE_TYPE_SORT_ELEMENT,
|
||||
NODE_TYPE_LIMIT,
|
||||
NODE_TYPE_VARIABLE,
|
||||
NODE_TYPE_ASSIGN,
|
||||
NODE_TYPE_OPERATOR_UNARY_PLUS,
|
||||
NODE_TYPE_OPERATOR_UNARY_MINUS,
|
||||
NODE_TYPE_OPERATOR_UNARY_NOT,
|
||||
NODE_TYPE_OPERATOR_BINARY_AND,
|
||||
NODE_TYPE_OPERATOR_BINARY_OR,
|
||||
NODE_TYPE_OPERATOR_BINARY_PLUS,
|
||||
NODE_TYPE_OPERATOR_BINARY_MINUS,
|
||||
NODE_TYPE_OPERATOR_BINARY_TIMES,
|
||||
NODE_TYPE_OPERATOR_BINARY_DIV,
|
||||
NODE_TYPE_OPERATOR_BINARY_MOD,
|
||||
NODE_TYPE_OPERATOR_BINARY_EQ,
|
||||
NODE_TYPE_OPERATOR_BINARY_NE,
|
||||
NODE_TYPE_OPERATOR_BINARY_LT,
|
||||
NODE_TYPE_OPERATOR_BINARY_LE,
|
||||
NODE_TYPE_OPERATOR_BINARY_GT,
|
||||
NODE_TYPE_OPERATOR_BINARY_GE,
|
||||
NODE_TYPE_OPERATOR_BINARY_IN,
|
||||
NODE_TYPE_OPERATOR_TERNARY,
|
||||
NODE_TYPE_SUBQUERY,
|
||||
NODE_TYPE_ATTRIBUTE_ACCESS,
|
||||
NODE_TYPE_BOUND_ATTRIBUTE_ACCESS,
|
||||
NODE_TYPE_INDEXED_ACCESS,
|
||||
NODE_TYPE_EXPAND,
|
||||
NODE_TYPE_VALUE,
|
||||
NODE_TYPE_LIST,
|
||||
NODE_TYPE_ARRAY,
|
||||
NODE_TYPE_ARRAY_ELEMENT,
|
||||
NODE_TYPE_COLLECTION,
|
||||
NODE_TYPE_REFERENCE,
|
||||
NODE_TYPE_ATTRIBUTE,
|
||||
NODE_TYPE_PARAMETER,
|
||||
NODE_TYPE_FCALL,
|
||||
NODE_TYPE_FCALL_USER
|
||||
};
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
// --SECTION-- struct AstNode
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief the node
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
struct AstNode {
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
// --SECTION-- constructors / destructors
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief create a node
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
AstNode (AstNodeType type)
|
||||
: type(type) {
|
||||
|
||||
TRI_InitVectorPointer(&members, TRI_UNKNOWN_MEM_ZONE);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief destroy the node
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
~AstNode () {
|
||||
TRI_DestroyVectorPointer(&members);
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
// --SECTION-- public methods
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
public:
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief add a member to the node
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
void addMember (AstNode* node) {
|
||||
TRI_ASSERT(node != nullptr);
|
||||
|
||||
int res = TRI_PushBackVectorPointer(&members, static_cast<void*>(node));
|
||||
|
||||
if (res != TRI_ERROR_NO_ERROR) {
|
||||
THROW_ARANGO_EXCEPTION(res);
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief add a member to the node
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
void addMember (AstNode const* node) {
|
||||
addMember(const_cast<AstNode*>(node));
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief return a member of the node
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
AstNode* getMember (size_t i) {
|
||||
if (i >= members._length) {
|
||||
THROW_ARANGO_EXCEPTION(TRI_ERROR_INTERNAL);
|
||||
}
|
||||
return static_cast<AstNode*>(members._buffer[i]);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief set the node's value type
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
void setValueType (AstNodeValueType type) {
|
||||
value.type = type;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief return the bool value of a node
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
int64_t getBoolValue () const {
|
||||
return value.value._bool;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief set the bool value of a node
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
void setBoolValue (bool v) {
|
||||
value.value._bool = v;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief return the int value of a node
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
int64_t getIntValue () const {
|
||||
return value.value._int;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief set the int value of a node
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
void setIntValue (int64_t v) {
|
||||
value.value._int = v;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief return the double value of a node
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
double getDoubleValue () const {
|
||||
return value.value._double;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief set the string value of a node
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
void setDoubleValue (double v) {
|
||||
value.value._double = v;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief return the string value of a node
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
char const* getStringValue () const {
|
||||
return value.value._string;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief set the string value of a node
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
void setStringValue (char const* v) {
|
||||
value.value._string = v;
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
// --SECTION-- public variables
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
public:
|
||||
|
||||
TRI_vector_pointer_t members;
|
||||
AstNodeType const type;
|
||||
AstNodeValue value;
|
||||
|
||||
};
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
// --SECTION-- END-OF-FILE
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
// Local Variables:
|
||||
// mode: outline-minor
|
||||
// outline-regexp: "/// @brief\\|/// {@inheritDoc}\\|/// @page\\|// --SECTION--\\|/// @\\}"
|
||||
// End:
|
|
@ -28,6 +28,7 @@
|
|||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#include "Aql/Parser.h"
|
||||
#include "Aql/AstNode.h"
|
||||
|
||||
using namespace triagens::aql;
|
||||
|
||||
|
@ -46,6 +47,7 @@ Parser::Parser (Query* query)
|
|||
_remainingLength(query->queryLength()),
|
||||
_offset(0),
|
||||
_marker(nullptr),
|
||||
_subQueryCount(0),
|
||||
_uniqueId(0),
|
||||
_stack() {
|
||||
|
||||
|
@ -67,6 +69,41 @@ Parser::~Parser () {
|
|||
// --SECTION-- public functions
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief set data for write queries
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
bool Parser::configureWriteQuery (QueryType type,
|
||||
AstNode const* collectionNode,
|
||||
AstNode* optionNode) {
|
||||
TRI_ASSERT(type != AQL_QUERY_READ);
|
||||
|
||||
// check if we currently are in a subquery
|
||||
if (isInSubQuery()) {
|
||||
// data modification not allowed in sub-queries
|
||||
registerError(TRI_ERROR_QUERY_MODIFY_IN_SUBQUERY);
|
||||
return false;
|
||||
}
|
||||
|
||||
// check current query type
|
||||
auto oldType = _query->type();
|
||||
|
||||
if (oldType != AQL_QUERY_READ) {
|
||||
// already a data-modification query, cannot have two data-modification operations in one query
|
||||
registerError(TRI_ERROR_QUERY_MULTI_MODIFY);
|
||||
return false;
|
||||
}
|
||||
|
||||
// now track which collection is going to be modified
|
||||
ast()->setWriteCollection(collectionNode);
|
||||
ast()->setWriteOptions(optionNode);
|
||||
|
||||
// register type
|
||||
_query->type(type);
|
||||
return true;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief parse the query
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
@ -94,7 +131,7 @@ char* Parser::generateName () {
|
|||
int n = snprintf(buffer, sizeof(buffer) - 1, "_%d", (int) ++_uniqueId);
|
||||
|
||||
// register the string and return a copy of it
|
||||
return registerString(buffer, static_cast<size_t>(n), false);
|
||||
return ast()->registerString(buffer, static_cast<size_t>(n), false);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
@ -137,6 +174,28 @@ void Parser::registerError (int code,
|
|||
}
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief push an AstNode into the list element on top of the stack
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
void Parser::pushList (AstNode* node) {
|
||||
auto list = static_cast<AstNode*>(peekStack());
|
||||
TRI_ASSERT(list->type == NODE_TYPE_LIST);
|
||||
list->addMember(node);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief push an AstNode into the array element on top of the stack
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
void Parser::pushArray (char const* attributeName,
|
||||
AstNode* node) {
|
||||
auto array = static_cast<AstNode*>(peekStack());
|
||||
TRI_ASSERT(array->type == NODE_TYPE_ARRAY);
|
||||
auto element = ast()->createNodeArrayElement(attributeName, node);
|
||||
array->addMember(element);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief push a temporary value on the parser's stack
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
|
|
@ -41,6 +41,7 @@
|
|||
namespace triagens {
|
||||
namespace aql {
|
||||
|
||||
struct AstNode;
|
||||
class Query;
|
||||
class Parser;
|
||||
}
|
||||
|
@ -116,6 +117,31 @@ namespace triagens {
|
|||
return _query->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
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
@ -184,23 +210,12 @@ namespace triagens {
|
|||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief register a string
|
||||
/// @brief set data for write queries
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
char* registerString (char const* p,
|
||||
size_t length,
|
||||
bool mustEscape) {
|
||||
// TODO
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief set the query type
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
void type (QueryType type) {
|
||||
_query->type(type);
|
||||
}
|
||||
bool configureWriteQuery (QueryType,
|
||||
AstNode const*,
|
||||
AstNode*);
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief parse the query
|
||||
|
@ -229,6 +244,19 @@ namespace triagens {
|
|||
void registerError (int,
|
||||
char const* = nullptr);
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief push an AstNode into the list element on top of the stack
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
void pushList (AstNode*);
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief push an AstNode into the array element on top of the stack
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
void pushArray (char const*,
|
||||
AstNode*);
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief push a temporary value on the parser's stack
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
@ -261,6 +289,7 @@ 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
|
||||
|
||||
|
||||
|
|
|
@ -28,7 +28,7 @@
|
|||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#include "Aql/QueryAst.h"
|
||||
#include "Ahuacatl/ahuacatl-ast-node.h"
|
||||
#include "BasicsC/tri-strings.h"
|
||||
#include "Utils/Exception.h"
|
||||
|
||||
using namespace triagens::aql;
|
||||
|
@ -42,19 +42,15 @@ using namespace triagens::aql;
|
|||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
QueryAst::QueryAst ()
|
||||
: _root(nullptr),
|
||||
_scopes() {
|
||||
: _nodes(),
|
||||
_strings(),
|
||||
_scopes(),
|
||||
_root(nullptr),
|
||||
_writeCollection(nullptr),
|
||||
_writeOptions(nullptr) {
|
||||
|
||||
TRI_aql_node_t* root = new TRI_aql_node_t;
|
||||
root->_type = TRI_AQL_NODE_ROOT;
|
||||
int res = TRI_InitVectorPointer2(&root->_members, TRI_UNKNOWN_MEM_ZONE, 16);
|
||||
|
||||
if (res != TRI_ERROR_NO_ERROR) {
|
||||
delete root;
|
||||
THROW_ARANGO_EXCEPTION(TRI_ERROR_OUT_OF_MEMORY);
|
||||
}
|
||||
|
||||
_root = root;
|
||||
_nodes.reserve(32);
|
||||
_root = createNode(NODE_TYPE_ROOT);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
@ -62,6 +58,15 @@ QueryAst::QueryAst ()
|
|||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
QueryAst::~QueryAst () {
|
||||
// free strings
|
||||
for (auto it = _strings.begin(); it != _strings.end(); ++it) {
|
||||
TRI_FreeString(TRI_UNKNOWN_MEM_ZONE, const_cast<char*>(*it));
|
||||
}
|
||||
|
||||
// free nodes
|
||||
for (auto it = _nodes.begin(); it != _nodes.end(); ++it) {
|
||||
delete (*it);
|
||||
}
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
|
@ -72,10 +77,563 @@ QueryAst::~QueryAst () {
|
|||
/// @brief destroy the AST
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
void QueryAst::addOperation (TRI_aql_node_t* node) {
|
||||
void QueryAst::addOperation (AstNode* node) {
|
||||
TRI_ASSERT(_root != nullptr);
|
||||
|
||||
TRI_PushBackVectorPointer(&_root->_members, (void*) node);
|
||||
TRI_PushBackVectorPointer(&_root->members, (void*) node);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief register a string
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
char* QueryAst::registerString (char const* p,
|
||||
size_t length,
|
||||
bool mustUnescape) {
|
||||
|
||||
if (p == nullptr) {
|
||||
THROW_ARANGO_EXCEPTION(TRI_ERROR_OUT_OF_MEMORY);
|
||||
}
|
||||
|
||||
char* copy = nullptr;
|
||||
if (mustUnescape && length > 0) {
|
||||
size_t outLength;
|
||||
copy = TRI_UnescapeUtf8StringZ(TRI_UNKNOWN_MEM_ZONE, p, length, &outLength);
|
||||
}
|
||||
else {
|
||||
copy = TRI_DuplicateString2Z(TRI_UNKNOWN_MEM_ZONE, p, length);
|
||||
}
|
||||
|
||||
if (copy == nullptr) {
|
||||
THROW_ARANGO_EXCEPTION(TRI_ERROR_OUT_OF_MEMORY);
|
||||
}
|
||||
|
||||
try {
|
||||
_strings.push_back(copy);
|
||||
}
|
||||
catch (...) {
|
||||
THROW_ARANGO_EXCEPTION(TRI_ERROR_OUT_OF_MEMORY);
|
||||
}
|
||||
|
||||
return copy;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief create an AST scope start node
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
AstNode* QueryAst::createNodeScopeStart () {
|
||||
// TODO: re-add hint??
|
||||
return createNode(NODE_TYPE_SCOPE_START);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief create an AST scope end node
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
AstNode* QueryAst::createNodeScopeEnd () {
|
||||
// TODO: re-add hint??
|
||||
return createNode(NODE_TYPE_SCOPE_END);
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief create an AST for node
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
AstNode* QueryAst::createNodeFor (char const* variableName,
|
||||
AstNode const* expression) {
|
||||
|
||||
// TODO:
|
||||
/*
|
||||
if (! TRI_IsValidVariableNameAql(variableName)) {
|
||||
// TRI_SetErrorContextAql(__FILE__, __LINE__, context, TRI_ERROR_QUERY_VARIABLE_NAME_INVALID, name);
|
||||
}
|
||||
*/
|
||||
AstNode* node = createNode(NODE_TYPE_FOR);
|
||||
|
||||
AstNode* variable = createNodeVariable(variableName);
|
||||
node->addMember(variable);
|
||||
node->addMember(expression);
|
||||
|
||||
return node;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief create an AST let node
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
AstNode* QueryAst::createNodeLet (char const* variableName,
|
||||
AstNode const* expression) {
|
||||
|
||||
// TODO:
|
||||
/*
|
||||
if (! TRI_IsValidVariableNameAql(variableName)) {
|
||||
// TRI_SetErrorContextAql(__FILE__, __LINE__, context, TRI_ERROR_QUERY_VARIABLE_NAME_INVALID, name);
|
||||
}
|
||||
*/
|
||||
AstNode* node = createNode(NODE_TYPE_LET);
|
||||
|
||||
AstNode* variable = createNodeVariable(variableName);
|
||||
node->addMember(variable);
|
||||
node->addMember(expression);
|
||||
|
||||
return node;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief create an AST filter node
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
AstNode* QueryAst::createNodeFilter (AstNode const* expression) {
|
||||
AstNode* node = createNode(NODE_TYPE_FILTER);
|
||||
node->addMember(expression);
|
||||
|
||||
return node;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief create an AST return node
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
AstNode* QueryAst::createNodeReturn (AstNode const* expression) {
|
||||
AstNode* node = createNode(NODE_TYPE_RETURN);
|
||||
node->addMember(expression);
|
||||
|
||||
return node;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief create an AST remove node
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
AstNode* QueryAst::createNodeRemove (AstNode const* expression,
|
||||
AstNode const* collection,
|
||||
AstNode* options) {
|
||||
AstNode* node = createNode(NODE_TYPE_REMOVE);
|
||||
node->addMember(expression);
|
||||
|
||||
return node;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief create an AST insert node
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
AstNode* QueryAst::createNodeInsert (AstNode const* expression,
|
||||
AstNode const* collection,
|
||||
AstNode* options) {
|
||||
AstNode* node = createNode(NODE_TYPE_INSERT);
|
||||
node->addMember(expression);
|
||||
|
||||
return node;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief create an AST update node
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
AstNode* QueryAst::createNodeUpdate (AstNode const* keyExpression,
|
||||
AstNode const* docExpression,
|
||||
AstNode const* collection,
|
||||
AstNode* options) {
|
||||
AstNode* node = createNode(NODE_TYPE_UPDATE);
|
||||
node->addMember(docExpression);
|
||||
|
||||
if (keyExpression != nullptr) {
|
||||
node->addMember(keyExpression);
|
||||
}
|
||||
|
||||
return node;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief create an AST replace node
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
AstNode* QueryAst::createNodeReplace (AstNode const* keyExpression,
|
||||
AstNode const* docExpression,
|
||||
AstNode const* collection,
|
||||
AstNode* options) {
|
||||
AstNode* node = createNode(NODE_TYPE_REPLACE);
|
||||
node->addMember(docExpression);
|
||||
|
||||
if (keyExpression != nullptr) {
|
||||
node->addMember(keyExpression);
|
||||
}
|
||||
|
||||
return node;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief create an AST collect node
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
AstNode* QueryAst::createNodeCollect (AstNode const* list,
|
||||
char const* name) {
|
||||
AstNode* node = createNode(NODE_TYPE_COLLECT);
|
||||
node->addMember(list);
|
||||
|
||||
if (name != nullptr) {
|
||||
AstNode* variable = createNodeVariable(name);
|
||||
node->addMember(variable);
|
||||
}
|
||||
|
||||
return node;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief create an AST sort node
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
AstNode* QueryAst::createNodeSort (AstNode const* list) {
|
||||
AstNode* node = createNode(NODE_TYPE_SORT);
|
||||
node->addMember(list);
|
||||
|
||||
return node;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief create an AST sort element node
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
AstNode* QueryAst::createNodeSortElement (AstNode const* expression,
|
||||
bool ascending) {
|
||||
AstNode* node = createNode(NODE_TYPE_SORT_ELEMENT);
|
||||
node->addMember(expression);
|
||||
node->setBoolValue(ascending);
|
||||
|
||||
return node;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief create an AST limit node
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
AstNode* QueryAst::createNodeLimit (AstNode const* offset,
|
||||
AstNode const* count) {
|
||||
AstNode* node = createNode(NODE_TYPE_LIMIT);
|
||||
node->addMember(offset);
|
||||
node->addMember(count);
|
||||
|
||||
return node;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief create an AST assign node
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
AstNode* QueryAst::createNodeAssign (char const* name,
|
||||
AstNode const* expression) {
|
||||
// TODO: look up what an assign node is!!!!!!!!!
|
||||
AstNode* node = createNode(NODE_TYPE_ASSIGN);
|
||||
AstNode* variable = createNodeVariable(name);
|
||||
node->addMember(variable);
|
||||
node->addMember(expression);
|
||||
|
||||
return node;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief create an AST variable node
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
AstNode* QueryAst::createNodeVariable (char const* name) {
|
||||
// TODO: check for duplicate names here!!
|
||||
// TRI_SetErrorContextAql(__FILE__, __LINE__, context, TRI_ERROR_QUERY_VARIABLE_REDECLARED, name);
|
||||
AstNode* node = createNode(NODE_TYPE_VARIABLE);
|
||||
node->setStringValue(name);
|
||||
|
||||
return node;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief create an AST collection node
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
AstNode* QueryAst::createNodeCollection (char const* name) {
|
||||
if (name == nullptr || *name == '\0') {
|
||||
// TODO
|
||||
// TRI_SetErrorContextAql(__FILE__, __LINE__, context, TRI_ERROR_ARANGO_COLLECTION_NOT_FOUND, name);
|
||||
return nullptr;
|
||||
}
|
||||
/*
|
||||
if (! TRI_IsAllowedNameCollection(true, name)) {
|
||||
// TODO
|
||||
// TRI_SetErrorContextAql(__FILE__, __LINE__, context, TRI_ERROR_ARANGO_ILLEGAL_NAME, name);
|
||||
return nullptr;
|
||||
}
|
||||
*/
|
||||
AstNode* node = createNode(NODE_TYPE_COLLECTION);
|
||||
AstNode* nameNode = createNodeValueString(name);
|
||||
|
||||
// TODO: check if we can store the name inline
|
||||
// TODO: add the collection to the query
|
||||
node->addMember(nameNode);
|
||||
|
||||
return node;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief create an AST reference node
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
AstNode* QueryAst::createNodeReference (char const* name) {
|
||||
AstNode* node = createNode(NODE_TYPE_REFERENCE);
|
||||
node->setStringValue(name);
|
||||
|
||||
return node;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief create an AST parameter node
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
AstNode* QueryAst::createNodeParameter (char const* name) {
|
||||
AstNode* node = createNode(NODE_TYPE_PARAMETER);
|
||||
|
||||
// TODO: insert bind parameter name into list of found parameters
|
||||
// (so we can check which ones are missing)
|
||||
node->setStringValue(name);
|
||||
|
||||
return node;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief create an AST unary operator node
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
AstNode* QueryAst::createNodeUnaryOperator (AstNodeType type,
|
||||
AstNode const* operand) {
|
||||
AstNode* node = createNode(type);
|
||||
node->addMember(operand);
|
||||
|
||||
return node;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief create an AST binary operator node
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
AstNode* QueryAst::createNodeBinaryOperator (AstNodeType type,
|
||||
AstNode const* lhs,
|
||||
AstNode const* rhs) {
|
||||
AstNode* node = createNode(type);
|
||||
node->addMember(lhs);
|
||||
node->addMember(rhs);
|
||||
|
||||
return node;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief create an AST ternary operator node
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
AstNode* QueryAst::createNodeTernaryOperator (AstNode const* condition,
|
||||
AstNode const* truePart,
|
||||
AstNode const* falsePart) {
|
||||
AstNode* node = createNode(NODE_TYPE_OPERATOR_TERNARY);
|
||||
node->addMember(condition);
|
||||
node->addMember(truePart);
|
||||
node->addMember(falsePart);
|
||||
|
||||
return node;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief create an AST subquery node
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
AstNode* QueryAst::createNodeSubquery () {
|
||||
AstNode* node = createNode(NODE_TYPE_SUBQUERY);
|
||||
// TODO: let the parser create a dynamic name here
|
||||
AstNode* variable = createNodeVariable("tempName");
|
||||
node->addMember(variable);
|
||||
|
||||
return node;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief create an AST attribute access node
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
AstNode* QueryAst::createNodeAttributeAccess (AstNode const* accessed,
|
||||
char const* attributeName) {
|
||||
AstNode* node = createNode(NODE_TYPE_ATTRIBUTE_ACCESS);
|
||||
node->addMember(accessed);
|
||||
node->setStringValue(attributeName);
|
||||
|
||||
return node;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief create an AST attribute access node w/ bind parameter
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
AstNode* QueryAst::createNodeBoundAttributeAccess (AstNode const* accessed,
|
||||
AstNode const* parameter) {
|
||||
AstNode* node = createNode(NODE_TYPE_BOUND_ATTRIBUTE_ACCESS);
|
||||
node->addMember(accessed);
|
||||
node->addMember(parameter);
|
||||
|
||||
return node;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief create an AST indexed access node
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
AstNode* QueryAst::createNodeIndexedAccess (AstNode const* accessed,
|
||||
AstNode const* indexValue) {
|
||||
AstNode* node = createNode(NODE_TYPE_INDEXED_ACCESS);
|
||||
node->addMember(accessed);
|
||||
node->addMember(indexValue);
|
||||
|
||||
return node;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief create an AST expand node
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
AstNode* QueryAst::createNodeExpand (char const* variableName,
|
||||
AstNode const* expanded,
|
||||
AstNode const* expansion) {
|
||||
AstNode* node = createNode(NODE_TYPE_EXPAND);
|
||||
AstNode* variable = createNodeVariable(variableName);
|
||||
// TODO: let the parser create a temporary variable name
|
||||
AstNode* temp = createNodeVariable("temp");
|
||||
node->addMember(variable);
|
||||
node->addMember(temp);
|
||||
node->addMember(expanded);
|
||||
node->addMember(expansion);
|
||||
|
||||
return node;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief create an AST null value node
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
AstNode* QueryAst::createNodeValueNull () {
|
||||
AstNode* node = createNode(NODE_TYPE_VALUE);
|
||||
node->setValueType(VALUE_TYPE_NULL);
|
||||
|
||||
return node;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief create an AST bool value node
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
AstNode* QueryAst::createNodeValueBool (bool value) {
|
||||
AstNode* node = createNode(NODE_TYPE_VALUE);
|
||||
node->setValueType(VALUE_TYPE_BOOL);
|
||||
node->setBoolValue(value);
|
||||
|
||||
return node;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief create an AST int value node
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
AstNode* QueryAst::createNodeValueInt (int64_t value) {
|
||||
AstNode* node = createNode(NODE_TYPE_VALUE);
|
||||
node->setValueType(VALUE_TYPE_INT);
|
||||
node->setIntValue(value);
|
||||
|
||||
return node;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief create an AST double value node
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
AstNode* QueryAst::createNodeValueDouble (double value) {
|
||||
AstNode* node = createNode(NODE_TYPE_VALUE);
|
||||
node->setValueType(VALUE_TYPE_DOUBLE);
|
||||
node->setDoubleValue(value);
|
||||
|
||||
return node;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief create an AST string value node
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
AstNode* QueryAst::createNodeValueString (char const* value) {
|
||||
AstNode* node = createNode(NODE_TYPE_VALUE);
|
||||
node->setValueType(VALUE_TYPE_STRING);
|
||||
node->setStringValue(value);
|
||||
|
||||
return node;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief create an AST list node
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
AstNode* QueryAst::createNodeList () {
|
||||
AstNode* node = createNode(NODE_TYPE_LIST);
|
||||
|
||||
return node;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief create an AST array node
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
AstNode* QueryAst::createNodeArray () {
|
||||
AstNode* node = createNode(NODE_TYPE_ARRAY);
|
||||
|
||||
return node;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief create an AST array element node
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
AstNode* QueryAst::createNodeArrayElement (char const* attributeName,
|
||||
AstNode const* expression) {
|
||||
AstNode* node = createNode(NODE_TYPE_ARRAY_ELEMENT);
|
||||
node->setStringValue(attributeName);
|
||||
node->addMember(expression);
|
||||
|
||||
return node;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief create an AST function call node
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
AstNode* QueryAst::createNodeFunctionCall (char const* functionName,
|
||||
AstNode const* parameters) {
|
||||
|
||||
// TODO: support function calls!
|
||||
TRI_ASSERT(false);
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
// --SECTION-- private methods
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief create a node of the specified type
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
AstNode* QueryAst::createNode (AstNodeType type) {
|
||||
auto node = new AstNode(type);
|
||||
|
||||
try {
|
||||
_nodes.push_back(node);
|
||||
}
|
||||
catch (...) {
|
||||
delete node;
|
||||
THROW_ARANGO_EXCEPTION(TRI_ERROR_OUT_OF_MEMORY);
|
||||
}
|
||||
|
||||
return node;
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
|
|
|
@ -31,8 +31,8 @@
|
|||
#define ARANGODB_AQL_QUERY_AST_H 1
|
||||
|
||||
#include "Basics/Common.h"
|
||||
#include "Aql/AstNode.h"
|
||||
#include "Aql/Scopes.h"
|
||||
#include "Ahuacatl/ahuacatl-ast-node.h"
|
||||
|
||||
namespace triagens {
|
||||
namespace aql {
|
||||
|
@ -79,11 +79,293 @@ namespace triagens {
|
|||
return &_scopes;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief track the write collection
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
inline void setWriteCollection (AstNode const* node) {
|
||||
TRI_ASSERT(node->type == NODE_TYPE_COLLECTION ||
|
||||
node->type == NODE_TYPE_PARAMETER);
|
||||
_writeCollection = node;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief track the write query options
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
inline void setWriteOptions (AstNode const* node) {
|
||||
_writeOptions = node;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief add an operation to the root node
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
void addOperation (TRI_aql_node_t*);
|
||||
void addOperation (AstNode*);
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief register a string
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
char* registerString (char const*,
|
||||
size_t,
|
||||
bool);
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief create an AST scope start node
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
AstNode* createNodeScopeStart ();
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief create an AST scope end node
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
AstNode* createNodeScopeEnd ();
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief create an AST for node
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
AstNode* createNodeFor (char const*,
|
||||
AstNode const*);
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief create an AST let node
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
AstNode* createNodeLet (char const*,
|
||||
AstNode const*);
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief create an AST filter node
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
AstNode* createNodeFilter (AstNode const*);
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief create an AST return node
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
AstNode* createNodeReturn (AstNode const*);
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief create an AST remove node
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
AstNode* createNodeRemove (AstNode const*,
|
||||
AstNode const*,
|
||||
AstNode*);
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief create an AST insert node
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
AstNode* createNodeInsert (AstNode const*,
|
||||
AstNode const*,
|
||||
AstNode*);
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief create an AST update node
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
AstNode* createNodeUpdate (AstNode const*,
|
||||
AstNode const*,
|
||||
AstNode const*,
|
||||
AstNode*);
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief create an AST replace node
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
AstNode* createNodeReplace (AstNode const*,
|
||||
AstNode const*,
|
||||
AstNode const*,
|
||||
AstNode*);
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief create an AST collect node
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
AstNode* createNodeCollect (AstNode const*,
|
||||
char const*);
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief create an AST sort node
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
AstNode* createNodeSort (AstNode const*);
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief create an AST sort element node
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
AstNode* createNodeSortElement (AstNode const*,
|
||||
bool);
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief create an AST limit node
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
AstNode* createNodeLimit (AstNode const*,
|
||||
AstNode const*);
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief create an AST assign node
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
AstNode* createNodeAssign (char const*,
|
||||
AstNode const*);
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief create an AST variable node
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
AstNode* createNodeVariable (char const*);
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief create an AST collection node
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
AstNode* createNodeCollection (char const*);
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief create an AST reference node
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
AstNode* createNodeReference (char const*);
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief create an AST parameter node
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
AstNode* createNodeParameter (char const*);
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief create an AST unary operator
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
AstNode* createNodeUnaryOperator (AstNodeType type,
|
||||
AstNode const*);
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief create an AST binary operator
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
AstNode* createNodeBinaryOperator (AstNodeType type,
|
||||
AstNode const*,
|
||||
AstNode const*);
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief create an AST ternary operator
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
AstNode* createNodeTernaryOperator (AstNode const*,
|
||||
AstNode const*,
|
||||
AstNode const*);
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief create an AST subquery node
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
AstNode* createNodeSubquery ();
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief create an AST attribute access node
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
AstNode* createNodeAttributeAccess (AstNode const*,
|
||||
char const*);
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief create an AST attribute access node w/ bind parameter
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
AstNode* createNodeBoundAttributeAccess (AstNode const*,
|
||||
AstNode const*);
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief create an AST index access node
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
AstNode* createNodeIndexedAccess (AstNode const*,
|
||||
AstNode const*);
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief create an AST expand node
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
AstNode* createNodeExpand (char const*,
|
||||
AstNode const*,
|
||||
AstNode const*);
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief create an AST null value node
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
AstNode* createNodeValueNull ();
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief create an AST bool value node
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
AstNode* createNodeValueBool (bool);
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief create an AST int value node
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
AstNode* createNodeValueInt (int64_t);
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief create an AST double value node
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
AstNode* createNodeValueDouble (double);
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief create an AST string value node
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
AstNode* createNodeValueString (char const*);
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief create an AST list node
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
AstNode* createNodeList ();
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief create an AST array node
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
AstNode* createNodeArray ();
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief create an AST array element node
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
AstNode* createNodeArrayElement (char const*,
|
||||
AstNode const*);
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief create an AST function call node
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
AstNode* createNodeFunctionCall (char const*,
|
||||
AstNode const*);
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
// --SECTION-- private methods
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
private:
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief create a node of the specified type
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
AstNode* createNode (AstNodeType);
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
// --SECTION-- private variables
|
||||
|
@ -92,16 +374,40 @@ namespace triagens {
|
|||
private:
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief root node of the AST
|
||||
/// @brief all nodes created in the AST - will be used for freeing them later
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
TRI_aql_node_t* _root;
|
||||
std::vector<AstNode*> _nodes;
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief all strings created in the AST - will be used for freeing them later
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
std::vector<char const*> _strings;
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief all scopes used in the query
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
Scopes _scopes;
|
||||
Scopes _scopes;
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief root node of the AST
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
AstNode* _root;
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief which collection is going to be modified in the query
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
AstNode const* _writeCollection;
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief which options are used for write queries
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
AstNode const* _writeOptions;
|
||||
|
||||
};
|
||||
|
||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -625,6 +625,7 @@ namespace triagens {
|
|||
}
|
||||
}
|
||||
|
||||
#include "Aql/AstNode.h"
|
||||
#include "Aql/grammar.h"
|
||||
#include "Aql/Parser.h"
|
||||
|
||||
|
@ -1283,7 +1284,7 @@ case 47:
|
|||
YY_RULE_SETUP
|
||||
{
|
||||
/* unquoted string */
|
||||
yylval->strval = yyextra->registerString(yytext, yyleng, false);
|
||||
yylval->strval = yyextra->ast()->registerString(yytext, yyleng, false);
|
||||
return T_STRING;
|
||||
}
|
||||
YY_BREAK
|
||||
|
@ -1300,7 +1301,7 @@ YY_RULE_SETUP
|
|||
{
|
||||
/* end of backtick-enclosed string */
|
||||
BEGIN(INITIAL);
|
||||
yylval->strval = yyextra->registerString(yyextra->marker(), yyextra->offset() - (yyextra->marker() - yyextra->queryString()) - 1, true);
|
||||
yylval->strval = yyextra->ast()->registerString(yyextra->marker(), yyextra->offset() - (yyextra->marker() - yyextra->queryString()) - 1, true);
|
||||
return T_STRING;
|
||||
}
|
||||
YY_BREAK
|
||||
|
@ -1338,7 +1339,7 @@ YY_RULE_SETUP
|
|||
{
|
||||
/* end of quote-enclosed string */
|
||||
BEGIN(INITIAL);
|
||||
yylval->strval = yyextra->registerString(yyextra->marker(), yyextra->offset() - (yyextra->marker() - yyextra->queryString()) - 1, true);
|
||||
yylval->strval = yyextra->ast()->registerString(yyextra->marker(), yyextra->offset() - (yyextra->marker() - yyextra->queryString()) - 1, true);
|
||||
return T_QUOTED_STRING;
|
||||
}
|
||||
YY_BREAK
|
||||
|
@ -1376,7 +1377,7 @@ YY_RULE_SETUP
|
|||
{
|
||||
/* end of quote-enclosed string */
|
||||
BEGIN(INITIAL);
|
||||
yylval->strval = yyextra->registerString(yyextra->marker(), yyextra->offset() - (yyextra->marker() - yyextra->queryString()) - 1, true);
|
||||
yylval->strval = yyextra->ast()->registerString(yyextra->marker(), yyextra->offset() - (yyextra->marker() - yyextra->queryString()) - 1, true);
|
||||
return T_QUOTED_STRING;
|
||||
}
|
||||
YY_BREAK
|
||||
|
@ -1406,7 +1407,7 @@ case 63:
|
|||
YY_RULE_SETUP
|
||||
{
|
||||
/* a numeric integer value */
|
||||
yylval->strval = yyextra->registerString(yytext, yyleng, false);
|
||||
yylval->strval = yyextra->ast()->registerString(yytext, yyleng, false);
|
||||
return T_INTEGER;
|
||||
}
|
||||
YY_BREAK
|
||||
|
@ -1414,7 +1415,7 @@ case 64:
|
|||
YY_RULE_SETUP
|
||||
{
|
||||
/* a numeric double value */
|
||||
yylval->strval = yyextra->registerString(yytext, yyleng, false);
|
||||
yylval->strval = yyextra->ast()->registerString(yytext, yyleng, false);
|
||||
return T_DOUBLE;
|
||||
}
|
||||
YY_BREAK
|
||||
|
@ -1426,7 +1427,7 @@ YY_RULE_SETUP
|
|||
{
|
||||
/* bind parameters must start with a @
|
||||
if followed by another @, this is a collection name parameter */
|
||||
yylval->strval = yyextra->registerString(yytext + 1, yyleng - 1, false);
|
||||
yylval->strval = yyextra->ast()->registerString(yytext + 1, yyleng - 1, false);
|
||||
return T_PARAMETER;
|
||||
}
|
||||
YY_BREAK
|
||||
|
|
|
@ -26,6 +26,7 @@ namespace triagens {
|
|||
}
|
||||
|
||||
|
||||
#include "Aql/AstNode.h"
|
||||
#include "Aql/grammar.h"
|
||||
#include "Aql/Parser.h"
|
||||
|
||||
|
@ -258,7 +259,7 @@ namespace triagens {
|
|||
|
||||
([a-zA-Z][_a-zA-Z0-9]*|_+[a-zA-Z]+[_a-zA-Z0-9]*) {
|
||||
/* unquoted string */
|
||||
yylval->strval = yyextra->registerString(yytext, yyleng, false);
|
||||
yylval->strval = yyextra->ast()->registerString(yytext, yyleng, false);
|
||||
return T_STRING;
|
||||
}
|
||||
|
||||
|
@ -271,7 +272,7 @@ namespace triagens {
|
|||
<BACKTICK>` {
|
||||
/* end of backtick-enclosed string */
|
||||
BEGIN(INITIAL);
|
||||
yylval->strval = yyextra->registerString(yyextra->marker(), yyextra->offset() - (yyextra->marker() - yyextra->queryString()) - 1, true);
|
||||
yylval->strval = yyextra->ast()->registerString(yyextra->marker(), yyextra->offset() - (yyextra->marker() - yyextra->queryString()) - 1, true);
|
||||
return T_STRING;
|
||||
}
|
||||
|
||||
|
@ -298,7 +299,7 @@ namespace triagens {
|
|||
<DOUBLE_QUOTE>\" {
|
||||
/* end of quote-enclosed string */
|
||||
BEGIN(INITIAL);
|
||||
yylval->strval = yyextra->registerString(yyextra->marker(), yyextra->offset() - (yyextra->marker() - yyextra->queryString()) - 1, true);
|
||||
yylval->strval = yyextra->ast()->registerString(yyextra->marker(), yyextra->offset() - (yyextra->marker() - yyextra->queryString()) - 1, true);
|
||||
return T_QUOTED_STRING;
|
||||
}
|
||||
|
||||
|
@ -325,7 +326,7 @@ namespace triagens {
|
|||
<SINGLE_QUOTE>' {
|
||||
/* end of quote-enclosed string */
|
||||
BEGIN(INITIAL);
|
||||
yylval->strval = yyextra->registerString(yyextra->marker(), yyextra->offset() - (yyextra->marker() - yyextra->queryString()) - 1, true);
|
||||
yylval->strval = yyextra->ast()->registerString(yyextra->marker(), yyextra->offset() - (yyextra->marker() - yyextra->queryString()) - 1, true);
|
||||
return T_QUOTED_STRING;
|
||||
}
|
||||
|
||||
|
@ -346,13 +347,13 @@ namespace triagens {
|
|||
|
||||
(0|[1-9][0-9]*) {
|
||||
/* a numeric integer value */
|
||||
yylval->strval = yyextra->registerString(yytext, yyleng, false);
|
||||
yylval->strval = yyextra->ast()->registerString(yytext, yyleng, false);
|
||||
return T_INTEGER;
|
||||
}
|
||||
|
||||
(0|[1-9][0-9]*)(\.[0-9]+([eE]([\-\+])?[0-9]+)?) {
|
||||
/* a numeric double value */
|
||||
yylval->strval = yyextra->registerString(yytext, yyleng, false);
|
||||
yylval->strval = yyextra->ast()->registerString(yytext, yyleng, false);
|
||||
return T_DOUBLE;
|
||||
}
|
||||
|
||||
|
@ -363,7 +364,7 @@ namespace triagens {
|
|||
@@?[a-zA-Z0-9][a-zA-Z0-9_]* {
|
||||
/* bind parameters must start with a @
|
||||
if followed by another @, this is a collection name parameter */
|
||||
yylval->strval = yyextra->registerString(yytext + 1, yyleng - 1, false);
|
||||
yylval->strval = yyextra->ast()->registerString(yytext + 1, yyleng - 1, false);
|
||||
return T_PARAMETER;
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue