1
0
Fork 0

partial implementation

This commit is contained in:
Jan Steemann 2015-06-20 11:21:57 +02:00
parent f7d5a612d9
commit 64089eea75
5 changed files with 98 additions and 17 deletions

View File

@ -1201,16 +1201,23 @@ bool AstNode::isSimple () const {
}
if (type == NODE_TYPE_REFERENCE ||
type == NODE_TYPE_VALUE) {
type == NODE_TYPE_VALUE ||
type == NODE_TYPE_VARIABLE ||
type == NODE_TYPE_NOP) {
setFlag(DETERMINED_SIMPLE, VALUE_SIMPLE);
return true;
}
if (type == NODE_TYPE_ARRAY ||
type == NODE_TYPE_OBJECT) {
type == NODE_TYPE_OBJECT ||
type == NODE_TYPE_EXPANSION ||
type == NODE_TYPE_ITERATOR ||
type == NODE_TYPE_ARRAY_LIMIT) {
size_t const n = numMembers();
for (size_t i = 0; i < n; ++i) {
auto member = getMember(i);
auto member = getMemberUnchecked(i);
if (! member->isSimple()) {
setFlag(DETERMINED_SIMPLE);
return false;

View File

@ -176,8 +176,8 @@ namespace triagens {
NODE_TYPE_ARRAY_LIMIT = 57
};
static_assert(NODE_TYPE_VALUE < NODE_TYPE_ARRAY, "incorrect node types");
static_assert(NODE_TYPE_ARRAY < NODE_TYPE_OBJECT, "incorrect node types");
static_assert(NODE_TYPE_VALUE < NODE_TYPE_ARRAY, "incorrect node types order");
static_assert(NODE_TYPE_ARRAY < NODE_TYPE_OBJECT, "incorrect node types order");
// -----------------------------------------------------------------------------
// --SECTION-- struct AstNode

View File

@ -1059,13 +1059,13 @@ void Executor::generateCodeExpansion (AstNode const* node) {
_buffer->appendText(variable->name);
_buffer->appendText("\"]=v; ");
_buffer->appendText("return ");
size_t projectionNode = 1;
if (node->getMember(4)->type != NODE_TYPE_NOP) {
generateCodeNode(node->getMember(4));
}
else {
generateCodeNode(node->getMember(1));
projectionNode = 4;
}
_buffer->appendText("return ");
generateCodeNode(node->getMember(projectionNode));
_buffer->appendText("; })");
}

View File

@ -305,10 +305,10 @@ bool Expression::findInArray (AqlValue const& left,
while (true) {
// determine midpoint
size_t m = l + ((r - l) / 2);
auto listItem = right.extractArrayMember(trx, rightCollection, m, false);
AqlValue listItemValue(&listItem);
auto arrayItem = right.extractArrayMember(trx, rightCollection, m, false);
AqlValue arrayItemValue(&arrayItem);
int compareResult = AqlValue::Compare(trx, left, leftCollection, listItemValue, nullptr, false);
int compareResult = AqlValue::Compare(trx, left, leftCollection, arrayItemValue, nullptr, false);
if (compareResult == 0) {
// item found in the list
@ -334,10 +334,10 @@ bool Expression::findInArray (AqlValue const& left,
// use linear search
for (size_t i = 0; i < n; ++i) {
// do not copy the list element we're looking at
auto listItem = right.extractArrayMember(trx, rightCollection, i, false);
AqlValue listItemValue(&listItem);
auto arrayItem = right.extractArrayMember(trx, rightCollection, i, false);
AqlValue arrayItemValue(&arrayItem);
int compareResult = AqlValue::Compare(trx, left, leftCollection, listItemValue, nullptr, false);
int compareResult = AqlValue::Compare(trx, left, leftCollection, arrayItemValue, nullptr, false);
if (compareResult == 0) {
// item found in the list
@ -627,6 +627,15 @@ AqlValue Expression::executeSimpleExpression (AstNode const* node,
else if (node->type == NODE_TYPE_REFERENCE) {
auto v = static_cast<Variable const*>(node->getData());
{
auto it = _variables.find(v);
if (it != _variables.end()) {
*collection = nullptr;
return AqlValue(new Json(TRI_UNKNOWN_MEM_ZONE, TRI_CopyJson(TRI_UNKNOWN_MEM_ZONE, (*it).second))); //, Json::NOFREE));
}
}
size_t i = 0;
for (auto it = vars.begin(); it != vars.end(); ++it, ++i) {
if ((*it)->name == v->name) {
@ -634,6 +643,7 @@ AqlValue Expression::executeSimpleExpression (AstNode const* node,
// save the collection info
*collection = argv->getDocumentCollection(regs[i]);
if (doCopy) {
return argv->getValueReference(startPos, regs[i]).clone();
}
@ -820,8 +830,63 @@ AqlValue Expression::executeSimpleExpression (AstNode const* node,
// return false part
return executeSimpleExpression(node->getMember(2), &myCollection, trx, argv, startPos, vars, regs, true);
}
else if (node->type == NODE_TYPE_EXPANSION) {
TRI_ASSERT(node->numMembers() == 5);
auto iterator = node->getMember(0);
auto variable = static_cast<Variable*>(iterator->getMember(0)->getData());
// TODO: implement flatten!
auto levels = node->getIntValue(true);
TRI_document_collection_t const* myCollection = nullptr;
AqlValue value = executeSimpleExpression(node->getMember(0), &myCollection, trx, argv, startPos, vars, regs, false);
if (! value.isArray()) {
value.destroy();
return AqlValue(new triagens::basics::Json(triagens::basics::Json::Array));
}
size_t const n = value.arraySize();
std::unique_ptr<Json> array(new Json(Json::Array, n));
size_t projectionNode = 1;
if (node->getMember(4)->type != NODE_TYPE_NOP) {
projectionNode = 4;
}
for (size_t i = 0; i < n; ++i) {
// TODO: check why we must copy the array member. will crash without copying!
auto arrayItem = value.extractArrayMember(trx, myCollection, i, true);
setVariable(variable, arrayItem.json());
THROW_ARANGO_EXCEPTION_MESSAGE(TRI_ERROR_INTERNAL, "unhandled type in simple expression");
TRI_document_collection_t const* subCollection = nullptr;
AqlValue sub = executeSimpleExpression(node->getMember(projectionNode), &subCollection, trx, argv, startPos, vars, regs, true);
array->add(sub.toJson(trx, subCollection, true));
clearVariable(variable);
arrayItem.destroy();
}
value.destroy();
return AqlValue(array.release());
}
else if (node->type == NODE_TYPE_ITERATOR) {
TRI_ASSERT(node != nullptr);
TRI_ASSERT(node->numMembers() == 2);
// intentionally do not stringify node 0
TRI_document_collection_t const* myCollection = nullptr;
AqlValue value = executeSimpleExpression(node->getMember(1), &myCollection, trx, argv, startPos, vars, regs, true);
return value;
}
std::string msg("unhandled type '");
msg.append(node->getTypeString());
msg.append("' in executeSimpleExpression()");
THROW_ARANGO_EXCEPTION_MESSAGE(TRI_ERROR_INTERNAL, msg.c_str());
}
////////////////////////////////////////////////////////////////////////////////

View File

@ -290,6 +290,13 @@ namespace triagens {
void invalidate ();
void setVariable (Variable const* variable, TRI_json_t const* value) {
_variables.emplace(variable, value);
}
void clearVariable (Variable const* variable) {
_variables.erase(variable);
}
// -----------------------------------------------------------------------------
// --SECTION-- private methods
// -----------------------------------------------------------------------------
@ -420,6 +427,8 @@ namespace triagens {
triagens::basics::StringBuffer _buffer;
std::unordered_map<Variable const*, TRI_json_t const*> _variables;
// -----------------------------------------------------------------------------
// --SECTION-- public static members
// -----------------------------------------------------------------------------