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/Parser.h"
|
||||||
|
#include "Aql/AstNode.h"
|
||||||
|
|
||||||
using namespace triagens::aql;
|
using namespace triagens::aql;
|
||||||
|
|
||||||
|
@ -46,6 +47,7 @@ Parser::Parser (Query* query)
|
||||||
_remainingLength(query->queryLength()),
|
_remainingLength(query->queryLength()),
|
||||||
_offset(0),
|
_offset(0),
|
||||||
_marker(nullptr),
|
_marker(nullptr),
|
||||||
|
_subQueryCount(0),
|
||||||
_uniqueId(0),
|
_uniqueId(0),
|
||||||
_stack() {
|
_stack() {
|
||||||
|
|
||||||
|
@ -67,6 +69,41 @@ Parser::~Parser () {
|
||||||
// --SECTION-- public functions
|
// --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
|
/// @brief parse the query
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
@ -94,7 +131,7 @@ char* Parser::generateName () {
|
||||||
int n = snprintf(buffer, sizeof(buffer) - 1, "_%d", (int) ++_uniqueId);
|
int n = snprintf(buffer, sizeof(buffer) - 1, "_%d", (int) ++_uniqueId);
|
||||||
|
|
||||||
// register the string and return a copy of it
|
// 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
|
/// @brief push a temporary value on the parser's stack
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
|
@ -41,6 +41,7 @@
|
||||||
namespace triagens {
|
namespace triagens {
|
||||||
namespace aql {
|
namespace aql {
|
||||||
|
|
||||||
|
struct AstNode;
|
||||||
class Query;
|
class Query;
|
||||||
class Parser;
|
class Parser;
|
||||||
}
|
}
|
||||||
|
@ -116,6 +117,31 @@ namespace triagens {
|
||||||
return _query->ast();
|
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
|
/// @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,
|
bool configureWriteQuery (QueryType,
|
||||||
size_t length,
|
AstNode const*,
|
||||||
bool mustEscape) {
|
AstNode*);
|
||||||
// TODO
|
|
||||||
return nullptr;
|
|
||||||
}
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
|
||||||
/// @brief set the query type
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
void type (QueryType type) {
|
|
||||||
_query->type(type);
|
|
||||||
}
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
/// @brief parse the query
|
/// @brief parse the query
|
||||||
|
@ -229,6 +244,19 @@ namespace triagens {
|
||||||
void registerError (int,
|
void registerError (int,
|
||||||
char const* = nullptr);
|
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
|
/// @brief push a temporary value on the parser's stack
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
@ -261,6 +289,7 @@ namespace triagens {
|
||||||
size_t _offset; // current parse position
|
size_t _offset; // current parse position
|
||||||
char const* _marker; // a position used temporarily during parsing
|
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
|
size_t _uniqueId; // a counter to generate unique (temporary) variable names
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -28,7 +28,7 @@
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
#include "Aql/QueryAst.h"
|
#include "Aql/QueryAst.h"
|
||||||
#include "Ahuacatl/ahuacatl-ast-node.h"
|
#include "BasicsC/tri-strings.h"
|
||||||
#include "Utils/Exception.h"
|
#include "Utils/Exception.h"
|
||||||
|
|
||||||
using namespace triagens::aql;
|
using namespace triagens::aql;
|
||||||
|
@ -42,19 +42,15 @@ using namespace triagens::aql;
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
QueryAst::QueryAst ()
|
QueryAst::QueryAst ()
|
||||||
: _root(nullptr),
|
: _nodes(),
|
||||||
_scopes() {
|
_strings(),
|
||||||
|
_scopes(),
|
||||||
|
_root(nullptr),
|
||||||
|
_writeCollection(nullptr),
|
||||||
|
_writeOptions(nullptr) {
|
||||||
|
|
||||||
TRI_aql_node_t* root = new TRI_aql_node_t;
|
_nodes.reserve(32);
|
||||||
root->_type = TRI_AQL_NODE_ROOT;
|
_root = createNode(NODE_TYPE_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;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
@ -62,6 +58,15 @@ QueryAst::QueryAst ()
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
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
|
/// @brief destroy the AST
|
||||||
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
void QueryAst::addOperation (TRI_aql_node_t* node) {
|
void QueryAst::addOperation (AstNode* node) {
|
||||||
TRI_ASSERT(_root != nullptr);
|
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
|
#define ARANGODB_AQL_QUERY_AST_H 1
|
||||||
|
|
||||||
#include "Basics/Common.h"
|
#include "Basics/Common.h"
|
||||||
|
#include "Aql/AstNode.h"
|
||||||
#include "Aql/Scopes.h"
|
#include "Aql/Scopes.h"
|
||||||
#include "Ahuacatl/ahuacatl-ast-node.h"
|
|
||||||
|
|
||||||
namespace triagens {
|
namespace triagens {
|
||||||
namespace aql {
|
namespace aql {
|
||||||
|
@ -79,11 +79,293 @@ namespace triagens {
|
||||||
return &_scopes;
|
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
|
/// @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
|
// --SECTION-- private variables
|
||||||
|
@ -92,16 +374,40 @@ namespace triagens {
|
||||||
private:
|
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
|
/// @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/grammar.h"
|
||||||
#include "Aql/Parser.h"
|
#include "Aql/Parser.h"
|
||||||
|
|
||||||
|
@ -1283,7 +1284,7 @@ case 47:
|
||||||
YY_RULE_SETUP
|
YY_RULE_SETUP
|
||||||
{
|
{
|
||||||
/* unquoted string */
|
/* unquoted string */
|
||||||
yylval->strval = yyextra->registerString(yytext, yyleng, false);
|
yylval->strval = yyextra->ast()->registerString(yytext, yyleng, false);
|
||||||
return T_STRING;
|
return T_STRING;
|
||||||
}
|
}
|
||||||
YY_BREAK
|
YY_BREAK
|
||||||
|
@ -1300,7 +1301,7 @@ YY_RULE_SETUP
|
||||||
{
|
{
|
||||||
/* end of backtick-enclosed string */
|
/* end of backtick-enclosed string */
|
||||||
BEGIN(INITIAL);
|
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;
|
return T_STRING;
|
||||||
}
|
}
|
||||||
YY_BREAK
|
YY_BREAK
|
||||||
|
@ -1338,7 +1339,7 @@ YY_RULE_SETUP
|
||||||
{
|
{
|
||||||
/* end of quote-enclosed string */
|
/* end of quote-enclosed string */
|
||||||
BEGIN(INITIAL);
|
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;
|
return T_QUOTED_STRING;
|
||||||
}
|
}
|
||||||
YY_BREAK
|
YY_BREAK
|
||||||
|
@ -1376,7 +1377,7 @@ YY_RULE_SETUP
|
||||||
{
|
{
|
||||||
/* end of quote-enclosed string */
|
/* end of quote-enclosed string */
|
||||||
BEGIN(INITIAL);
|
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;
|
return T_QUOTED_STRING;
|
||||||
}
|
}
|
||||||
YY_BREAK
|
YY_BREAK
|
||||||
|
@ -1406,7 +1407,7 @@ case 63:
|
||||||
YY_RULE_SETUP
|
YY_RULE_SETUP
|
||||||
{
|
{
|
||||||
/* a numeric integer value */
|
/* a numeric integer value */
|
||||||
yylval->strval = yyextra->registerString(yytext, yyleng, false);
|
yylval->strval = yyextra->ast()->registerString(yytext, yyleng, false);
|
||||||
return T_INTEGER;
|
return T_INTEGER;
|
||||||
}
|
}
|
||||||
YY_BREAK
|
YY_BREAK
|
||||||
|
@ -1414,7 +1415,7 @@ case 64:
|
||||||
YY_RULE_SETUP
|
YY_RULE_SETUP
|
||||||
{
|
{
|
||||||
/* a numeric double value */
|
/* a numeric double value */
|
||||||
yylval->strval = yyextra->registerString(yytext, yyleng, false);
|
yylval->strval = yyextra->ast()->registerString(yytext, yyleng, false);
|
||||||
return T_DOUBLE;
|
return T_DOUBLE;
|
||||||
}
|
}
|
||||||
YY_BREAK
|
YY_BREAK
|
||||||
|
@ -1426,7 +1427,7 @@ YY_RULE_SETUP
|
||||||
{
|
{
|
||||||
/* bind parameters must start with a @
|
/* bind parameters must start with a @
|
||||||
if followed by another @, this is a collection name parameter */
|
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;
|
return T_PARAMETER;
|
||||||
}
|
}
|
||||||
YY_BREAK
|
YY_BREAK
|
||||||
|
|
|
@ -26,6 +26,7 @@ namespace triagens {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#include "Aql/AstNode.h"
|
||||||
#include "Aql/grammar.h"
|
#include "Aql/grammar.h"
|
||||||
#include "Aql/Parser.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]*) {
|
([a-zA-Z][_a-zA-Z0-9]*|_+[a-zA-Z]+[_a-zA-Z0-9]*) {
|
||||||
/* unquoted string */
|
/* unquoted string */
|
||||||
yylval->strval = yyextra->registerString(yytext, yyleng, false);
|
yylval->strval = yyextra->ast()->registerString(yytext, yyleng, false);
|
||||||
return T_STRING;
|
return T_STRING;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -271,7 +272,7 @@ namespace triagens {
|
||||||
<BACKTICK>` {
|
<BACKTICK>` {
|
||||||
/* end of backtick-enclosed string */
|
/* end of backtick-enclosed string */
|
||||||
BEGIN(INITIAL);
|
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;
|
return T_STRING;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -298,7 +299,7 @@ namespace triagens {
|
||||||
<DOUBLE_QUOTE>\" {
|
<DOUBLE_QUOTE>\" {
|
||||||
/* end of quote-enclosed string */
|
/* end of quote-enclosed string */
|
||||||
BEGIN(INITIAL);
|
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;
|
return T_QUOTED_STRING;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -325,7 +326,7 @@ namespace triagens {
|
||||||
<SINGLE_QUOTE>' {
|
<SINGLE_QUOTE>' {
|
||||||
/* end of quote-enclosed string */
|
/* end of quote-enclosed string */
|
||||||
BEGIN(INITIAL);
|
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;
|
return T_QUOTED_STRING;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -346,13 +347,13 @@ namespace triagens {
|
||||||
|
|
||||||
(0|[1-9][0-9]*) {
|
(0|[1-9][0-9]*) {
|
||||||
/* a numeric integer value */
|
/* a numeric integer value */
|
||||||
yylval->strval = yyextra->registerString(yytext, yyleng, false);
|
yylval->strval = yyextra->ast()->registerString(yytext, yyleng, false);
|
||||||
return T_INTEGER;
|
return T_INTEGER;
|
||||||
}
|
}
|
||||||
|
|
||||||
(0|[1-9][0-9]*)(\.[0-9]+([eE]([\-\+])?[0-9]+)?) {
|
(0|[1-9][0-9]*)(\.[0-9]+([eE]([\-\+])?[0-9]+)?) {
|
||||||
/* a numeric double value */
|
/* a numeric double value */
|
||||||
yylval->strval = yyextra->registerString(yytext, yyleng, false);
|
yylval->strval = yyextra->ast()->registerString(yytext, yyleng, false);
|
||||||
return T_DOUBLE;
|
return T_DOUBLE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -363,7 +364,7 @@ namespace triagens {
|
||||||
@@?[a-zA-Z0-9][a-zA-Z0-9_]* {
|
@@?[a-zA-Z0-9][a-zA-Z0-9_]* {
|
||||||
/* bind parameters must start with a @
|
/* bind parameters must start with a @
|
||||||
if followed by another @, this is a collection name parameter */
|
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;
|
return T_PARAMETER;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue