1
0
Fork 0

refactoring

This commit is contained in:
Jan Steemann 2014-07-31 10:38:49 +02:00
parent 6ebfbfef49
commit 2aad264e77
11 changed files with 248 additions and 240 deletions

View File

@ -58,8 +58,8 @@ Ast::Ast (Query* query,
Parser* parser)
: _query(query),
_parser(parser),
_variableId(0),
_nodes(),
_strings(),
_scopes(),
_bindParameters(),
_collectionNames(),
@ -72,7 +72,6 @@ Ast::Ast (Query* query,
TRI_ASSERT(_parser != nullptr);
_nodes.reserve(32);
_strings.reserve(32);
startSubQuery();
@ -84,11 +83,6 @@ Ast::Ast (Query* query,
////////////////////////////////////////////////////////////////////////////////
Ast::~Ast () {
// 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);
@ -99,8 +93,20 @@ Ast::~Ast () {
// --SECTION-- public functions
// -----------------------------------------------------------------------------
////////////////////////////////////////////////////////////////////////////////
/// @brief generate a new unique variable name
////////////////////////////////////////////////////////////////////////////////
char const* Ast::generateName () {
std::string const variableName(std::to_string(nextVariableId())); // to_string: c++11
// register the string and return a copy of it
return _query->registerString(variableName.c_str(), variableName.size(), false);
}
////////////////////////////////////////////////////////////////////////////////
/// @brief convert the AST into JSON
/// the caller is responsible for freeing the JSON later
////////////////////////////////////////////////////////////////////////////////
TRI_json_t* Ast::toJson (TRI_memory_zone_t* zone) {
@ -127,47 +133,6 @@ void Ast::addOperation (AstNode* node) {
_root->addMember(node);
}
////////////////////////////////////////////////////////////////////////////////
/// @brief register a string
////////////////////////////////////////////////////////////////////////////////
char* Ast::registerString (char const* p,
size_t length,
bool mustUnescape) {
if (p == nullptr) {
THROW_ARANGO_EXCEPTION(TRI_ERROR_OUT_OF_MEMORY);
}
if (length == 0) {
static char const* empty = "";
// optimisation for the empty string
return const_cast<char*>(empty);
}
char* copy = nullptr;
if (mustUnescape) {
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 for node
////////////////////////////////////////////////////////////////////////////////
@ -187,27 +152,6 @@ AstNode* Ast::createNodeFor (char const* variableName,
return node;
}
////////////////////////////////////////////////////////////////////////////////
/// @brief create an AST for node
////////////////////////////////////////////////////////////////////////////////
AstNode* Ast::createNodeFor (char const* variable1Name,
char const* variable2Name) {
if (variable1Name == nullptr) {
THROW_ARANGO_EXCEPTION(TRI_ERROR_OUT_OF_MEMORY);
}
AstNode* node = createNode(NODE_TYPE_FOR);
AstNode* variable = createNodeVariable(variable1Name, true);
node->addMember(variable);
auto reference = createNodeReference(variable2Name);
node->addMember(reference);
return node;
}
////////////////////////////////////////////////////////////////////////////////
/// @brief create an AST let node
////////////////////////////////////////////////////////////////////////////////
@ -241,24 +185,6 @@ AstNode* Ast::createNodeFilter (AstNode const* expression) {
return node;
}
////////////////////////////////////////////////////////////////////////////////
/// @brief create an AST filter node
////////////////////////////////////////////////////////////////////////////////
AstNode* Ast::createNodeFilter (char const* variableName) {
if (variableName == nullptr) {
THROW_ARANGO_EXCEPTION(TRI_ERROR_OUT_OF_MEMORY);
}
AstNode* node = createNode(NODE_TYPE_FILTER);
node->setIntValue(static_cast<int64_t>(FILTER_UNKNOWN));
auto reference = createNodeReference(variableName);
node->addMember(reference);
return node;
}
////////////////////////////////////////////////////////////////////////////////
/// @brief create an AST return node
////////////////////////////////////////////////////////////////////////////////
@ -427,7 +353,7 @@ AstNode* Ast::createNodeVariable (char const* name,
AstNode* node = createNode(NODE_TYPE_VARIABLE);
node->setStringValue(name);
auto variable = _scopes.addVariable(name, isUserDefined);
auto variable = _scopes.addVariable(nextVariableId(), name, isUserDefined);
node->setData(static_cast<void*>(variable));
return node;
@ -742,7 +668,7 @@ AstNode* Ast::createNodeFunctionCall (char const* functionName,
}
std::string const normalizedName = normalizeFunctionName(functionName);
char* fname = registerString(normalizedName.c_str(), normalizedName.size(), false);
char* fname = _query->registerString(normalizedName.c_str(), normalizedName.size(), false);
AstNode* node;
@ -824,7 +750,7 @@ void Ast::injectBindParameters (BindParameters& parameters) {
}
// turn node into a collection node
char const* name = registerString(value->_value._string.data, value->_value._string.length - 1, false);
char const* name = _query->registerString(value->_value._string.data, value->_value._string.length - 1, false);
node = createNodeCollection(name);
@ -1300,6 +1226,7 @@ AstNode* Ast::optimizeTernaryOperator (AstNode* node) {
////////////////////////////////////////////////////////////////////////////////
/// @brief optimizes a reference to a variable
/// references are replaced with constants if possible
////////////////////////////////////////////////////////////////////////////////
AstNode* Ast::optimizeReference (AstNode* node) {
@ -1312,6 +1239,7 @@ AstNode* Ast::optimizeReference (AstNode* node) {
THROW_ARANGO_EXCEPTION(TRI_ERROR_OUT_OF_MEMORY);
}
// constant propagation
if (variable->constValue() == nullptr) {
// note which variables we are reading
variable->increaseReferenceCount();
@ -1319,8 +1247,6 @@ AstNode* Ast::optimizeReference (AstNode* node) {
return node;
}
// TODO: re-activate constant propagation??
return node;
return static_cast<AstNode*>(variable->constValue());
}
@ -1387,8 +1313,6 @@ AstNode* Ast::optimizeLet (AstNode* node,
}
}
else if (pass == 1) {
/* TODO: re-add reference counting
if (! v->isReferenceCounted()) {
// this optimizes away the assignment of variables which are never read
// (i.e. assigned-only variables). this is currently not free of side-effects:
@ -1403,7 +1327,6 @@ AstNode* Ast::optimizeLet (AstNode* node,
// variables
return createNodeNop();
}
*/
}
return node;
@ -1452,7 +1375,7 @@ AstNode* Ast::nodeFromJson (TRI_json_t const* json) {
}
if (json->_type == TRI_JSON_STRING) {
char const* value = registerString(json->_value._string.data, json->_value._string.length - 1, false);
char const* value = _query->registerString(json->_value._string.data, json->_value._string.length - 1, false);
return createNodeValueString(value);
}
@ -1479,7 +1402,7 @@ AstNode* Ast::nodeFromJson (TRI_json_t const* json) {
THROW_ARANGO_EXCEPTION(TRI_ERROR_INTERNAL);
}
char const* attributeName = registerString(key->_value._string.data, key->_value._string.length - 1, false);
char const* attributeName = _query->registerString(key->_value._string.data, key->_value._string.length - 1, false);
node->addMember(createNodeArrayElement(attributeName, nodeFromJson(value)));
}

View File

@ -74,7 +74,7 @@ namespace triagens {
////////////////////////////////////////////////////////////////////////////////
Ast (Query*,
Parser*);
Parser*);
////////////////////////////////////////////////////////////////////////////////
/// @brief destroy the AST
@ -190,8 +190,23 @@ namespace triagens {
_writeOptions = node;
}
////////////////////////////////////////////////////////////////////////////////
/// @brief returns the next variable id
////////////////////////////////////////////////////////////////////////////////
inline VariableId nextVariableId () {
return ++_variableId;
}
////////////////////////////////////////////////////////////////////////////////
/// @brief generate a new unique variable name
////////////////////////////////////////////////////////////////////////////////
char const* generateName ();
////////////////////////////////////////////////////////////////////////////////
/// @brief convert the AST into JSON
/// the caller is responsible for freeing the JSON later
////////////////////////////////////////////////////////////////////////////////
struct TRI_json_s* toJson (TRI_memory_zone_t*);
@ -202,14 +217,6 @@ namespace triagens {
void addOperation (AstNode*);
////////////////////////////////////////////////////////////////////////////////
/// @brief register a string
////////////////////////////////////////////////////////////////////////////////
char* registerString (char const*,
size_t,
bool);
////////////////////////////////////////////////////////////////////////////////
/// @brief create an AST for node
////////////////////////////////////////////////////////////////////////////////
@ -217,13 +224,6 @@ namespace triagens {
AstNode* createNodeFor (char const*,
AstNode const*);
////////////////////////////////////////////////////////////////////////////////
/// @brief create an AST for node
////////////////////////////////////////////////////////////////////////////////
AstNode* createNodeFor (char const*,
char const*);
////////////////////////////////////////////////////////////////////////////////
/// @brief create an AST let node
////////////////////////////////////////////////////////////////////////////////
@ -238,12 +238,6 @@ namespace triagens {
AstNode* createNodeFilter (AstNode const*);
////////////////////////////////////////////////////////////////////////////////
/// @brief create an AST filter node
////////////////////////////////////////////////////////////////////////////////
AstNode* createNodeFilter (char const*);
////////////////////////////////////////////////////////////////////////////////
/// @brief create an AST return node
////////////////////////////////////////////////////////////////////////////////
@ -614,7 +608,7 @@ namespace triagens {
/// @brief the query
////////////////////////////////////////////////////////////////////////////////
Query* _query;
Query* _query;
////////////////////////////////////////////////////////////////////////////////
/// @brief the query parser
@ -622,18 +616,18 @@ namespace triagens {
Parser* _parser;
////////////////////////////////////////////////////////////////////////////////
/// @brief the next assigned variable id
////////////////////////////////////////////////////////////////////////////////
VariableId _variableId;
////////////////////////////////////////////////////////////////////////////////
/// @brief all nodes created in the AST - will be used for freeing them later
////////////////////////////////////////////////////////////////////////////////
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
////////////////////////////////////////////////////////////////////////////////

View File

@ -29,7 +29,6 @@
#include "Aql/Parser.h"
#include "Aql/AstNode.h"
#include "Basics/StringUtils.h"
using namespace triagens::aql;
@ -49,12 +48,8 @@ Parser::Parser (Query* query)
_remainingLength(query->queryLength()),
_offset(0),
_marker(nullptr),
_uniqueId(0),
_stack() {
Aqllex_init(&_scanner);
Aqlset_extra(this, _scanner);
_ast = new Ast(query, this);
_stack.reserve(16);
@ -65,8 +60,6 @@ Parser::Parser (Query* query)
////////////////////////////////////////////////////////////////////////////////
Parser::~Parser () {
Aqllex_destroy(_scanner);
if (_ast != nullptr) {
delete _ast;
}
@ -118,16 +111,29 @@ ParseResult Parser::parse () {
// start main scope
auto scopes = _ast->scopes();
scopes->start(AQL_SCOPE_MAIN);
Aqllex_init(&_scanner);
Aqlset_extra(this, _scanner);
// parse the query string
if (Aqlparse(this)) {
// lexing/parsing failed
THROW_ARANGO_EXCEPTION(TRI_ERROR_QUERY_PARSE);
try {
// parse the query string
if (Aqlparse(this)) {
// lexing/parsing failed
THROW_ARANGO_EXCEPTION(TRI_ERROR_QUERY_PARSE);
}
Aqllex_destroy(_scanner);
}
catch (...) {
Aqllex_destroy(_scanner);
throw;
}
// end main scope
scopes->endCurrent();
TRI_ASSERT(scopes->numActive() == 0);
ParseResult result;
result.collectionNames = _ast->collectionNames();
result.bindParameters = _ast->bindParameters();
@ -136,17 +142,6 @@ ParseResult Parser::parse () {
return result;
}
////////////////////////////////////////////////////////////////////////////////
/// @brief generate a new unique name
////////////////////////////////////////////////////////////////////////////////
char* Parser::generateName () {
std::string const variableName(std::to_string(++_uniqueId)); // c++11
// register the string and return a copy of it
return _ast->registerString(variableName.c_str(), variableName.size(), false);
}
////////////////////////////////////////////////////////////////////////////////
/// @brief register a parse error, position is specified as line / column
////////////////////////////////////////////////////////////////////////////////

View File

@ -117,6 +117,14 @@ namespace triagens {
return _ast;
}
////////////////////////////////////////////////////////////////////////////////
/// @brief return the query during parsing
////////////////////////////////////////////////////////////////////////////////
inline Query* query () {
return _query;
}
////////////////////////////////////////////////////////////////////////////////
/// @brief return the scanner
////////////////////////////////////////////////////////////////////////////////
@ -198,12 +206,6 @@ namespace triagens {
ParseResult parse ();
////////////////////////////////////////////////////////////////////////////////
/// @brief generate a new unique name
////////////////////////////////////////////////////////////////////////////////
char* generateName ();
////////////////////////////////////////////////////////////////////////////////
/// @brief register a parse error, position is specified as line / column
////////////////////////////////////////////////////////////////////////////////
@ -265,19 +267,53 @@ namespace triagens {
private:
Query* _query; // the query object
Ast* _ast; // abstract syntax tree
////////////////////////////////////////////////////////////////////////////////
/// @brief the query
////////////////////////////////////////////////////////////////////////////////
void* _scanner; // the lexer generated by flex
char const* _buffer; // the currently processed part of the query string
size_t _remainingLength; // remaining length of the query string, modified during parsing
size_t _offset; // current parse position
char const* _marker; // a position used temporarily during parsing
Query* _query;
size_t _uniqueId; // a counter to generate unique (temporary) variable names
////////////////////////////////////////////////////////////////////////////////
/// @brief abstract syntax tree for the query, build during parsing
////////////////////////////////////////////////////////////////////////////////
Ast* _ast;
std::vector<void*> _stack;
////////////////////////////////////////////////////////////////////////////////
/// @brief lexer / scanner used when parsing the query (Aql/tokens.ll)
////////////////////////////////////////////////////////////////////////////////
void* _scanner;
////////////////////////////////////////////////////////////////////////////////
/// @brief currently processed part of the query string
////////////////////////////////////////////////////////////////////////////////
char const* _buffer;
////////////////////////////////////////////////////////////////////////////////
/// @brief remaining length of the query string, used during parsing
////////////////////////////////////////////////////////////////////////////////
size_t _remainingLength;
////////////////////////////////////////////////////////////////////////////////
/// @brief current offset into query string, used during parsing
////////////////////////////////////////////////////////////////////////////////
size_t _offset;
////////////////////////////////////////////////////////////////////////////////
/// @brief pointer into query string, used temporarily during parsing
////////////////////////////////////////////////////////////////////////////////
char const* _marker;
////////////////////////////////////////////////////////////////////////////////
/// @brief a stack of things, used temporarily during parsing
////////////////////////////////////////////////////////////////////////////////
std::vector<void*> _stack;
};
}

View File

@ -31,11 +31,10 @@
#include "Aql/Parser.h"
#include "Aql/V8Executor.h"
#include "BasicsC/json.h"
#include "BasicsC/tri-strings.h"
#include "Utils/Exception.h"
#include "VocBase/vocbase.h"
#include "Basics/JsonHelper.h"
using namespace triagens::aql;
// -----------------------------------------------------------------------------
@ -55,9 +54,12 @@ Query::Query (TRI_vocbase_t* vocbase,
_queryString(queryString),
_queryLength(queryLength),
_type(AQL_QUERY_READ),
_bindParameters(bindParameters) {
_bindParameters(bindParameters),
_strings() {
TRI_ASSERT(_vocbase != nullptr);
_strings.reserve(32);
}
////////////////////////////////////////////////////////////////////////////////
@ -69,6 +71,11 @@ Query::~Query () {
delete _executor;
_executor = nullptr;
}
// free strings
for (auto it = _strings.begin(); it != _strings.end(); ++it) {
TRI_FreeString(TRI_UNKNOWN_MEM_ZONE, const_cast<char*>(*it));
}
}
// -----------------------------------------------------------------------------
@ -206,6 +213,7 @@ void Query::explain () {
V8Executor* Query::getExecutor () {
if (_executor == nullptr) {
// the executor is a singleton per query
_executor = new V8Executor;
}
@ -213,6 +221,48 @@ V8Executor* Query::getExecutor () {
return _executor;
}
////////////////////////////////////////////////////////////////////////////////
/// @brief register a string
/// the string is freed when the query is destroyed
////////////////////////////////////////////////////////////////////////////////
char* Query::registerString (char const* p,
size_t length,
bool mustUnescape) {
if (p == nullptr) {
THROW_ARANGO_EXCEPTION(TRI_ERROR_OUT_OF_MEMORY);
}
if (length == 0) {
static char const* empty = "";
// optimisation for the empty string
return const_cast<char*>(empty);
}
char* copy = nullptr;
if (mustUnescape) {
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;
}
// -----------------------------------------------------------------------------
// --SECTION-- END-OF-FILE
// -----------------------------------------------------------------------------

View File

@ -165,6 +165,15 @@ namespace triagens {
V8Executor* getExecutor ();
////////////////////////////////////////////////////////////////////////////////
/// @brief register a string
/// the string is freed when the query is destroyed
////////////////////////////////////////////////////////////////////////////////
char* registerString (char const*,
size_t,
bool);
// -----------------------------------------------------------------------------
// --SECTION-- private methods
// -----------------------------------------------------------------------------
@ -177,15 +186,47 @@ namespace triagens {
private:
struct TRI_vocbase_s* _vocbase;
////////////////////////////////////////////////////////////////////////////////
/// @brief pointer to vocbase the query runs in
////////////////////////////////////////////////////////////////////////////////
struct TRI_vocbase_s* _vocbase;
////////////////////////////////////////////////////////////////////////////////
/// @brief V8 code executor
////////////////////////////////////////////////////////////////////////////////
V8Executor* _executor;
V8Executor* _executor;
char const* _queryString;
size_t const _queryLength;
QueryType _type;
////////////////////////////////////////////////////////////////////////////////
/// @brief the actual query string
////////////////////////////////////////////////////////////////////////////////
BindParameters _bindParameters;
char const* _queryString;
////////////////////////////////////////////////////////////////////////////////
/// @brief length of the query string in bytes
////////////////////////////////////////////////////////////////////////////////
size_t const _queryLength;
////////////////////////////////////////////////////////////////////////////////
/// @brief type of the query
////////////////////////////////////////////////////////////////////////////////
QueryType _type;
////////////////////////////////////////////////////////////////////////////////
/// @brief bind parameters for the query
////////////////////////////////////////////////////////////////////////////////
BindParameters _bindParameters;
////////////////////////////////////////////////////////////////////////////////
/// @brief all strings created in the AST - will be used for freeing them later
////////////////////////////////////////////////////////////////////////////////
std::vector<char const*> _strings;
};

View File

@ -79,9 +79,8 @@ std::string Scope::typeName () const {
/// @brief adds a variable to the scope
////////////////////////////////////////////////////////////////////////////////
void Scope::addVariable (std::string const& name,
Variable* variable) {
_variables.insert(std::make_pair(name, variable));
void Scope::addVariable (Variable* variable) {
_variables.insert(std::make_pair(variable->name, variable));
}
////////////////////////////////////////////////////////////////////////////////
@ -118,9 +117,7 @@ Variable* Scope::getVariable (char const* name) const {
Scopes::Scopes ()
: _variables(),
_activeScopes(),
_nextId(0) {
_activeScopes() {
_activeScopes.reserve(4);
}
@ -203,7 +200,8 @@ void Scopes::endNested () {
/// @brief adds a variable to the current scope
////////////////////////////////////////////////////////////////////////////////
Variable* Scopes::addVariable (char const* name,
Variable* Scopes::addVariable (VariableId id,
char const* name,
bool isUserDefined) {
TRI_ASSERT(! _activeScopes.empty());
TRI_ASSERT(name != nullptr);
@ -217,8 +215,6 @@ Variable* Scopes::addVariable (char const* name,
}
}
VariableId id = ++_nextId;
// if this fails, the exception will propagate and be caught somewhere else
auto variable = new Variable(name, id, isUserDefined);
@ -233,7 +229,7 @@ Variable* Scopes::addVariable (char const* name,
}
// if this fails, there won't be a memleak
_activeScopes.back()->addVariable(std::string(name), variable);
_activeScopes.back()->addVariable(variable);
return variable;
}

View File

@ -95,8 +95,7 @@ namespace triagens {
/// @brief adds a variable to the scope
////////////////////////////////////////////////////////////////////////////////
void addVariable (std::string const&,
Variable*);
void addVariable (Variable*);
////////////////////////////////////////////////////////////////////////////////
/// @brief checks if a variable exists in the scope
@ -163,6 +162,14 @@ namespace triagens {
public:
////////////////////////////////////////////////////////////////////////////////
/// @brief number of currently active scopes
////////////////////////////////////////////////////////////////////////////////
inline size_t numActive () const {
return _activeScopes.size();
}
////////////////////////////////////////////////////////////////////////////////
/// @brief start a new scope
////////////////////////////////////////////////////////////////////////////////
@ -185,7 +192,8 @@ namespace triagens {
/// @brief adds a variable to the current scope
////////////////////////////////////////////////////////////////////////////////
Variable* addVariable (char const*,
Variable* addVariable (VariableId,
char const*,
bool);
////////////////////////////////////////////////////////////////////////////////
@ -222,19 +230,7 @@ namespace triagens {
/// @brief currently active scopes
////////////////////////////////////////////////////////////////////////////////
std::vector<Scope*> _activeScopes;
////////////////////////////////////////////////////////////////////////////////
/// @brief all scopes
////////////////////////////////////////////////////////////////////////////////
std::vector<Scope*> _allScopes;
////////////////////////////////////////////////////////////////////////////////
/// @brief next variable id
////////////////////////////////////////////////////////////////////////////////
VariableId _nextId;
std::vector<Scope*> _activeScopes;
};

View File

@ -230,39 +230,16 @@ for_statement:
T_FOR variable_name T_IN expression {
parser->ast()->scopes()->start(triagens::aql::AQL_SCOPE_FOR);
if ($4->type == NODE_TYPE_COLLECTION || $4->type == NODE_TYPE_REFERENCE) {
// right operand of FOR is a collection or a reference. can use it directly
auto node = parser->ast()->createNodeFor($2, $4);
parser->ast()->addOperation(node);
}
else {
char const* variableName = parser->generateName();
// right operand of FOR is an expression. use a temporary variable
auto letNode = parser->ast()->createNodeLet(variableName, $4, false);
parser->ast()->addOperation(letNode);
auto forNode = parser->ast()->createNodeFor($2, variableName);
parser->ast()->addOperation(forNode);
}
auto node = parser->ast()->createNodeFor($2, $4);
parser->ast()->addOperation(node);
}
;
filter_statement:
T_FILTER expression {
if ($2->type == NODE_TYPE_REFERENCE) {
// operand is a reference. can use it directly
auto node = parser->ast()->createNodeFilter($2);
parser->ast()->addOperation(node);
}
else {
// operand is not a reference. use a temporary variable
char const* variableName = parser->generateName();
auto letNode = parser->ast()->createNodeLet(variableName, $2, false);
parser->ast()->addOperation(letNode);
auto filterNode = parser->ast()->createNodeFilter(variableName);
parser->ast()->addOperation(filterNode);
}
// operand is a reference. can use it directly
auto node = parser->ast()->createNodeFilter($2);
parser->ast()->addOperation(node);
}
;

View File

@ -1284,7 +1284,7 @@ case 47:
YY_RULE_SETUP
{
/* unquoted string */
yylval->strval = yyextra->ast()->registerString(yytext, yyleng, false);
yylval->strval = yyextra->query()->registerString(yytext, yyleng, false);
return T_STRING;
}
YY_BREAK
@ -1301,7 +1301,7 @@ YY_RULE_SETUP
{
/* end of backtick-enclosed string */
BEGIN(INITIAL);
yylval->strval = yyextra->ast()->registerString(yyextra->marker(), yyextra->offset() - (yyextra->marker() - yyextra->queryString()) - 1, true);
yylval->strval = yyextra->query()->registerString(yyextra->marker(), yyextra->offset() - (yyextra->marker() - yyextra->queryString()) - 1, true);
return T_STRING;
}
YY_BREAK
@ -1339,7 +1339,7 @@ YY_RULE_SETUP
{
/* end of quote-enclosed string */
BEGIN(INITIAL);
yylval->strval = yyextra->ast()->registerString(yyextra->marker(), yyextra->offset() - (yyextra->marker() - yyextra->queryString()) - 1, true);
yylval->strval = yyextra->query()->registerString(yyextra->marker(), yyextra->offset() - (yyextra->marker() - yyextra->queryString()) - 1, true);
return T_QUOTED_STRING;
}
YY_BREAK
@ -1377,7 +1377,7 @@ YY_RULE_SETUP
{
/* end of quote-enclosed string */
BEGIN(INITIAL);
yylval->strval = yyextra->ast()->registerString(yyextra->marker(), yyextra->offset() - (yyextra->marker() - yyextra->queryString()) - 1, true);
yylval->strval = yyextra->query()->registerString(yyextra->marker(), yyextra->offset() - (yyextra->marker() - yyextra->queryString()) - 1, true);
return T_QUOTED_STRING;
}
YY_BREAK
@ -1407,7 +1407,7 @@ case 63:
YY_RULE_SETUP
{
/* a numeric integer value */
yylval->strval = yyextra->ast()->registerString(yytext, yyleng, false);
yylval->strval = yyextra->query()->registerString(yytext, yyleng, false);
return T_INTEGER;
}
YY_BREAK
@ -1415,7 +1415,7 @@ case 64:
YY_RULE_SETUP
{
/* a numeric double value */
yylval->strval = yyextra->ast()->registerString(yytext, yyleng, false);
yylval->strval = yyextra->query()->registerString(yytext, yyleng, false);
return T_DOUBLE;
}
YY_BREAK
@ -1427,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->ast()->registerString(yytext + 1, yyleng - 1, false);
yylval->strval = yyextra->query()->registerString(yytext + 1, yyleng - 1, false);
return T_PARAMETER;
}
YY_BREAK

View File

@ -259,7 +259,7 @@ namespace triagens {
([a-zA-Z][_a-zA-Z0-9]*|_+[a-zA-Z]+[_a-zA-Z0-9]*) {
/* unquoted string */
yylval->strval = yyextra->ast()->registerString(yytext, yyleng, false);
yylval->strval = yyextra->query()->registerString(yytext, yyleng, false);
return T_STRING;
}
@ -272,7 +272,7 @@ namespace triagens {
<BACKTICK>` {
/* end of backtick-enclosed string */
BEGIN(INITIAL);
yylval->strval = yyextra->ast()->registerString(yyextra->marker(), yyextra->offset() - (yyextra->marker() - yyextra->queryString()) - 1, true);
yylval->strval = yyextra->query()->registerString(yyextra->marker(), yyextra->offset() - (yyextra->marker() - yyextra->queryString()) - 1, true);
return T_STRING;
}
@ -299,7 +299,7 @@ namespace triagens {
<DOUBLE_QUOTE>\" {
/* end of quote-enclosed string */
BEGIN(INITIAL);
yylval->strval = yyextra->ast()->registerString(yyextra->marker(), yyextra->offset() - (yyextra->marker() - yyextra->queryString()) - 1, true);
yylval->strval = yyextra->query()->registerString(yyextra->marker(), yyextra->offset() - (yyextra->marker() - yyextra->queryString()) - 1, true);
return T_QUOTED_STRING;
}
@ -326,7 +326,7 @@ namespace triagens {
<SINGLE_QUOTE>' {
/* end of quote-enclosed string */
BEGIN(INITIAL);
yylval->strval = yyextra->ast()->registerString(yyextra->marker(), yyextra->offset() - (yyextra->marker() - yyextra->queryString()) - 1, true);
yylval->strval = yyextra->query()->registerString(yyextra->marker(), yyextra->offset() - (yyextra->marker() - yyextra->queryString()) - 1, true);
return T_QUOTED_STRING;
}
@ -347,13 +347,13 @@ namespace triagens {
(0|[1-9][0-9]*) {
/* a numeric integer value */
yylval->strval = yyextra->ast()->registerString(yytext, yyleng, false);
yylval->strval = yyextra->query()->registerString(yytext, yyleng, false);
return T_INTEGER;
}
(0|[1-9][0-9]*)(\.[0-9]+([eE]([\-\+])?[0-9]+)?) {
/* a numeric double value */
yylval->strval = yyextra->ast()->registerString(yytext, yyleng, false);
yylval->strval = yyextra->query()->registerString(yytext, yyleng, false);
return T_DOUBLE;
}
@ -364,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->ast()->registerString(yytext + 1, yyleng - 1, false);
yylval->strval = yyextra->query()->registerString(yytext + 1, yyleng - 1, false);
return T_PARAMETER;
}