mirror of https://gitee.com/bigwinds/arangodb
fixed expand nodes
This commit is contained in:
parent
8eb7f5bd8a
commit
6bbc3eaf49
|
@ -41,8 +41,6 @@ namespace triagens {
|
|||
// -----------------------------------------------------------------------------
|
||||
|
||||
struct ParseResult {
|
||||
ParseResult () = delete;
|
||||
|
||||
ParseResult& operator= (ParseResult const& other) = delete;
|
||||
|
||||
ParseResult (ParseResult&& other) {
|
||||
|
@ -60,11 +58,18 @@ namespace triagens {
|
|||
zone(TRI_UNKNOWN_MEM_ZONE),
|
||||
json(nullptr) {
|
||||
}
|
||||
|
||||
explicit ParseResult (int code)
|
||||
: code(code),
|
||||
explanation(""),
|
||||
zone(TRI_UNKNOWN_MEM_ZONE),
|
||||
json(nullptr) {
|
||||
}
|
||||
|
||||
ParseResult (TRI_memory_zone_t* zone)
|
||||
ParseResult ()
|
||||
: code(TRI_ERROR_NO_ERROR),
|
||||
explanation(),
|
||||
zone(zone),
|
||||
zone(TRI_UNKNOWN_MEM_ZONE),
|
||||
json(nullptr) {
|
||||
}
|
||||
|
||||
|
|
|
@ -116,7 +116,7 @@ bool Parser::configureWriteQuery (QueryType type,
|
|||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
ParseResult Parser::parse () {
|
||||
ParseResult result(TRI_UNKNOWN_MEM_ZONE);
|
||||
ParseResult result;
|
||||
|
||||
// start main scope
|
||||
auto scopes = _ast->scopes();
|
||||
|
|
|
@ -174,19 +174,20 @@ ParseResult Query::execute () {
|
|||
parser.ast()->injectBindParameters(_bindParameters);
|
||||
parser.ast()->optimize();
|
||||
|
||||
// TODO: remove
|
||||
std::cout << triagens::basics::JsonHelper::toString(parser.ast()->toJson(TRI_UNKNOWN_MEM_ZONE)) << "\n";
|
||||
ParseResult result(_error.code, _error.explanation);
|
||||
result.json = parser.ast()->toJson(TRI_UNKNOWN_MEM_ZONE);
|
||||
|
||||
return result;
|
||||
}
|
||||
catch (triagens::arango::Exception const& ex) {
|
||||
registerError(ex.code());
|
||||
_error.code = ex.code();
|
||||
_error.explanation = "";
|
||||
|
||||
return ParseResult(ex.code());
|
||||
}
|
||||
catch (...) {
|
||||
registerError(TRI_ERROR_OUT_OF_MEMORY);
|
||||
return ParseResult(TRI_ERROR_OUT_OF_MEMORY);
|
||||
}
|
||||
|
||||
ParseResult result(_error.code, _error.explanation);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
@ -199,10 +200,12 @@ ParseResult Query::parse () {
|
|||
return parser.parse();
|
||||
}
|
||||
catch (triagens::arango::Exception const& ex) {
|
||||
registerError(ex.code());
|
||||
_error.code = ex.code();
|
||||
_error.explanation = "";
|
||||
}
|
||||
catch (...) {
|
||||
registerError(TRI_ERROR_OUT_OF_MEMORY);
|
||||
_error.code = TRI_ERROR_OUT_OF_MEMORY;
|
||||
_error.explanation = "";
|
||||
}
|
||||
|
||||
ParseResult result(_error.code, _error.explanation);
|
||||
|
|
|
@ -169,6 +169,10 @@ char* QueryAst::registerString (char const* p,
|
|||
|
||||
AstNode* QueryAst::createNodeFor (char const* variableName,
|
||||
AstNode const* expression) {
|
||||
if (variableName == nullptr) {
|
||||
THROW_ARANGO_EXCEPTION(TRI_ERROR_OUT_OF_MEMORY);
|
||||
}
|
||||
|
||||
AstNode* node = createNode(NODE_TYPE_FOR);
|
||||
|
||||
AstNode* variable = createNodeVariable(variableName, true);
|
||||
|
@ -183,10 +187,15 @@ AstNode* QueryAst::createNodeFor (char const* variableName,
|
|||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
AstNode* QueryAst::createNodeLet (char const* variableName,
|
||||
AstNode const* expression) {
|
||||
AstNode const* expression,
|
||||
bool isUserDefinedVariable) {
|
||||
if (variableName == nullptr) {
|
||||
THROW_ARANGO_EXCEPTION(TRI_ERROR_OUT_OF_MEMORY);
|
||||
}
|
||||
|
||||
AstNode* node = createNode(NODE_TYPE_LET);
|
||||
|
||||
AstNode* variable = createNodeVariable(variableName, true);
|
||||
AstNode* variable = createNodeVariable(variableName, isUserDefinedVariable);
|
||||
node->addMember(variable);
|
||||
node->addMember(expression);
|
||||
|
||||
|
@ -338,6 +347,10 @@ AstNode* QueryAst::createNodeLimit (AstNode const* offset,
|
|||
|
||||
AstNode* QueryAst::createNodeAssign (char const* name,
|
||||
AstNode const* expression) {
|
||||
if (name == nullptr) {
|
||||
THROW_ARANGO_EXCEPTION(TRI_ERROR_OUT_OF_MEMORY);
|
||||
}
|
||||
|
||||
AstNode* node = createNode(NODE_TYPE_ASSIGN);
|
||||
AstNode* variable = createNodeVariable(name, true);
|
||||
node->addMember(variable);
|
||||
|
@ -402,6 +415,10 @@ AstNode* QueryAst::createNodeCollection (char const* name) {
|
|||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
AstNode* QueryAst::createNodeReference (char const* name) {
|
||||
if (name == nullptr) {
|
||||
THROW_ARANGO_EXCEPTION(TRI_ERROR_OUT_OF_MEMORY);
|
||||
}
|
||||
|
||||
AstNode* node = createNode(NODE_TYPE_REFERENCE);
|
||||
|
||||
auto variable = _scopes.getVariable(name);
|
||||
|
@ -420,6 +437,10 @@ AstNode* QueryAst::createNodeReference (char const* name) {
|
|||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
AstNode* QueryAst::createNodeParameter (char const* name) {
|
||||
if (name == nullptr) {
|
||||
THROW_ARANGO_EXCEPTION(TRI_ERROR_OUT_OF_MEMORY);
|
||||
}
|
||||
|
||||
AstNode* node = createNode(NODE_TYPE_PARAMETER);
|
||||
|
||||
node->setStringValue(name);
|
||||
|
@ -476,6 +497,10 @@ AstNode* QueryAst::createNodeTernaryOperator (AstNode const* condition,
|
|||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
AstNode* QueryAst::createNodeSubquery (char const* tempName) {
|
||||
if (tempName == nullptr) {
|
||||
THROW_ARANGO_EXCEPTION(TRI_ERROR_OUT_OF_MEMORY);
|
||||
}
|
||||
|
||||
AstNode* node = createNode(NODE_TYPE_SUBQUERY);
|
||||
AstNode* variable = createNodeVariable(tempName, false);
|
||||
node->addMember(variable);
|
||||
|
@ -489,6 +514,10 @@ AstNode* QueryAst::createNodeSubquery (char const* tempName) {
|
|||
|
||||
AstNode* QueryAst::createNodeAttributeAccess (AstNode const* accessed,
|
||||
char const* attributeName) {
|
||||
if (attributeName == nullptr) {
|
||||
THROW_ARANGO_EXCEPTION(TRI_ERROR_OUT_OF_MEMORY);
|
||||
}
|
||||
|
||||
AstNode* node = createNode(NODE_TYPE_ATTRIBUTE_ACCESS);
|
||||
node->addMember(accessed);
|
||||
node->setStringValue(attributeName);
|
||||
|
@ -526,17 +555,9 @@ AstNode* QueryAst::createNodeIndexedAccess (AstNode const* accessed,
|
|||
/// @brief create an AST expand node
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
AstNode* QueryAst::createNodeExpand (char const* variableName,
|
||||
char const* tempName,
|
||||
AstNode const* expanded,
|
||||
AstNode const* expansion) {
|
||||
AstNode* QueryAst::createNodeExpand (AstNode const* expanded) {
|
||||
AstNode* node = createNode(NODE_TYPE_EXPAND);
|
||||
AstNode* variable = createNodeVariable(variableName, false);
|
||||
AstNode* temp = createNodeVariable(tempName, false);
|
||||
node->addMember(variable);
|
||||
node->addMember(temp);
|
||||
node->addMember(expanded);
|
||||
node->addMember(expansion);
|
||||
|
||||
return node;
|
||||
}
|
||||
|
@ -593,6 +614,10 @@ AstNode* QueryAst::createNodeValueDouble (double value) {
|
|||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
AstNode* QueryAst::createNodeValueString (char const* value) {
|
||||
if (value == nullptr) {
|
||||
THROW_ARANGO_EXCEPTION(TRI_ERROR_OUT_OF_MEMORY);
|
||||
}
|
||||
|
||||
AstNode* node = createNode(NODE_TYPE_VALUE);
|
||||
node->setValueType(VALUE_TYPE_STRING);
|
||||
node->setStringValue(value);
|
||||
|
@ -626,6 +651,10 @@ AstNode* QueryAst::createNodeArray () {
|
|||
|
||||
AstNode* QueryAst::createNodeArrayElement (char const* attributeName,
|
||||
AstNode const* expression) {
|
||||
if (attributeName == nullptr) {
|
||||
THROW_ARANGO_EXCEPTION(TRI_ERROR_OUT_OF_MEMORY);
|
||||
}
|
||||
|
||||
AstNode* node = createNode(NODE_TYPE_ARRAY_ELEMENT);
|
||||
node->setStringValue(attributeName);
|
||||
node->addMember(expression);
|
||||
|
@ -639,6 +668,9 @@ AstNode* QueryAst::createNodeArrayElement (char const* attributeName,
|
|||
|
||||
AstNode* QueryAst::createNodeFunctionCall (char const* functionName,
|
||||
AstNode const* parameters) {
|
||||
if (functionName == nullptr) {
|
||||
THROW_ARANGO_EXCEPTION(TRI_ERROR_OUT_OF_MEMORY);
|
||||
}
|
||||
|
||||
std::string const normalizedName = normalizeFunctionName(functionName);
|
||||
char* fname = registerString(normalizedName.c_str(), normalizedName.size(), false);
|
||||
|
@ -1041,6 +1073,7 @@ AstNode* QueryAst::optimizeBinaryOperatorRelational (AstNode* node) {
|
|||
}
|
||||
|
||||
auto it = FunctionNames.find(static_cast<int>(node->type));
|
||||
|
||||
if (it == FunctionNames.end()) {
|
||||
THROW_ARANGO_EXCEPTION(TRI_ERROR_INTERNAL);
|
||||
}
|
||||
|
@ -1390,11 +1423,10 @@ AstNode* QueryAst::traverse (AstNode* node,
|
|||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
std::string QueryAst::normalizeFunctionName (char const* name) {
|
||||
if (name == nullptr) {
|
||||
THROW_ARANGO_EXCEPTION(TRI_ERROR_OUT_OF_MEMORY);
|
||||
}
|
||||
TRI_ASSERT(name != nullptr);
|
||||
|
||||
char* upperName = TRI_UpperAsciiStringZ(TRI_UNKNOWN_MEM_ZONE, name);
|
||||
|
||||
if (upperName == nullptr) {
|
||||
THROW_ARANGO_EXCEPTION(TRI_ERROR_OUT_OF_MEMORY);
|
||||
}
|
||||
|
|
|
@ -162,7 +162,8 @@ namespace triagens {
|
|||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
AstNode* createNodeLet (char const*,
|
||||
AstNode const*);
|
||||
AstNode const*,
|
||||
bool);
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief create an AST filter node
|
||||
|
@ -323,10 +324,7 @@ namespace triagens {
|
|||
/// @brief create an AST expand node
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
AstNode* createNodeExpand (char const*,
|
||||
char const*,
|
||||
AstNode const*,
|
||||
AstNode const*);
|
||||
AstNode* createNodeExpand (AstNode const*);
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
/// @brief create an AST null value node
|
||||
|
|
|
@ -256,7 +256,7 @@ let_list:
|
|||
|
||||
let_element:
|
||||
variable_name T_ASSIGN expression {
|
||||
auto node = parser->ast()->createNodeLet($1, $3);
|
||||
auto node = parser->ast()->createNodeLet($1, $3, true);
|
||||
parser->ast()->addOperation(node);
|
||||
}
|
||||
;
|
||||
|
@ -671,34 +671,20 @@ reference:
|
|||
}
|
||||
| reference {
|
||||
// expanded variable access, e.g. variable[*]
|
||||
char* varname = parser->generateName();
|
||||
// push the varname onto the stack
|
||||
parser->pushStack(varname);
|
||||
|
||||
// push on the stack what's going to be expanded (will be popped when we come back)
|
||||
// push on the stack what's going to be expanded (will be popped by the "expansion" subrule)
|
||||
parser->pushStack($1);
|
||||
|
||||
// create a temporary variable for the row iterator (will be popped by "expansion" rule")
|
||||
// TODO:
|
||||
auto node = parser->ast()->createNodeReference(varname);
|
||||
|
||||
// push the variable
|
||||
parser->pushStack(node);
|
||||
} T_EXPAND expansion {
|
||||
// return from the "expansion" subrule
|
||||
auto expanded = static_cast<AstNode*>(parser->popStack());
|
||||
char const* varname = static_cast<char const*>(parser->popStack());
|
||||
|
||||
// push the actual expand node into the statement list
|
||||
char const* tempName = parser->generateName();
|
||||
auto expand = parser->ast()->createNodeExpand(varname, tempName, expanded, $4);
|
||||
parser->ast()->addOperation(expand);
|
||||
|
||||
auto nameNode = expand->getMember(1);
|
||||
|
||||
// push the expand node into the statement list
|
||||
auto expand = parser->ast()->createNodeExpand($4);
|
||||
|
||||
char const* variableName = parser->generateName();
|
||||
auto let = parser->ast()->createNodeLet(variableName, expand, false);
|
||||
parser->ast()->addOperation(let);
|
||||
|
||||
// return a reference only
|
||||
// TODO:
|
||||
$$ = parser->ast()->createNodeReference(nameNode->getStringValue());
|
||||
$$ = parser->ast()->createNodeReference(variableName);
|
||||
}
|
||||
;
|
||||
|
||||
|
|
|
@ -5484,6 +5484,7 @@ static v8::Handle<v8::Value> JS_ExecuteAql (v8::Arguments const& argv) {
|
|||
}
|
||||
|
||||
v8::Handle<v8::Object> result = v8::Object::New();
|
||||
result->Set(TRI_V8_STRING("ast"), TRI_ObjectJson(parseResult.json));
|
||||
|
||||
return scope.Close(result);
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue