1
0
Fork 0

Merge branch 'JHMH' of github.com:arangodb/arangodb into JHMH

This commit is contained in:
Michael Hackstein 2015-11-13 17:12:36 +01:00
commit eec9c02a36
3 changed files with 161 additions and 19 deletions

View File

@ -34,26 +34,38 @@
using namespace triagens::aql; using namespace triagens::aql;
using EN = triagens::aql::ExecutionNode; using EN = triagens::aql::ExecutionNode;
bool checkPathVariableAccessFeasible(CalculationNode const* cn, TraversalNode * tn, Variable const* var, bool &conditionIsImpossible) { bool checkPathVariableAccessFeasible(CalculationNode const* cn,
TraversalNode * tn,
Variable const* var,
bool &conditionIsImpossible,
Ast* ast) {
auto node = cn->expression()->node(); auto node = cn->expression()->node();
std::vector<AstNode const*> currentPath; std::vector<AstNode const*> currentPath;
std::vector<std::vector<AstNode const*>> paths; std::vector<std::vector<AstNode const*>> paths;
std::vector<std::vector<AstNode const*>> clonePath;
node->findVariableAccess(currentPath, paths, var); node->findVariableAccess(currentPath, paths, var);
for (auto onePath : paths) { for (auto onePath : paths) {
size_t len = onePath.size(); size_t len = onePath.size();
bool isEdgeAccess = false;
bool isVertexAccess = false;
bool isAsterisc = false;
size_t attrAccessTo = 0;
if ((onePath[len - 2]->type == NODE_TYPE_ATTRIBUTE_ACCESS) && if (onePath[len - 2]->type == NODE_TYPE_ATTRIBUTE_ACCESS) {
strcmp(onePath[len - 2]->getStringValue(), "edges") && isEdgeAccess = strcmp(onePath[len - 2]->getStringValue(), "edges") == 0;
strcmp(onePath[len - 2]->getStringValue(), "vertices")) { isVertexAccess = strcmp(onePath[len - 2]->getStringValue(), "vertices") == 0;
/* We can't catch all cases in which this error would occur, so we don't throw here. if (!isEdgeAccess && ! isVertexAccess) {
std::string message("TRAVERSAL: path only knows 'edges' and 'vertices', not ");
message += onePath[len - 2]->getStringValue(); /* We can't catch all cases in which this error would occur, so we don't throw here.
THROW_ARANGO_EXCEPTION_MESSAGE(TRI_ERROR_QUERY_PARSE, message); std::string message("TRAVERSAL: path only knows 'edges' and 'vertices', not ");
*/ message += onePath[len - 2]->getStringValue();
return false; THROW_ARANGO_EXCEPTION_MESSAGE(TRI_ERROR_QUERY_PARSE, message);
*/
return false;
}
} }
// we now need to check for p.edges[n] whether n is >= 0 // we now need to check for p.edges[n] whether n is >= 0
@ -65,21 +77,83 @@ bool checkPathVariableAccessFeasible(CalculationNode const* cn, TraversalNode *
return false; return false;
} }
conditionIsImpossible = !tn->isInRange(indexAccessNode->value.value._int); conditionIsImpossible = !tn->isInRange(indexAccessNode->value.value._int);
attrAccessTo = indexAccessNode->value.value._int;
} }
else if ((onePath[len - 3]->type == NODE_TYPE_ITERATOR) && else if ((onePath[len - 3]->type == NODE_TYPE_ITERATOR) &&
(onePath[len - 4]->type == NODE_TYPE_EXPANSION)){ (onePath[len - 4]->type == NODE_TYPE_EXPANSION)){
// we now need to check for p.edges[*] which becomes a fancy structure // we now need to check for p.edges[*] which becomes a fancy structure
isAsterisc = true;
} }
else { else {
return false; return false;
} }
// OR? don't know howto continue. // OR? don't know howto continue.
AstNode const * compareNode = nullptr;
AstNode const * accessNodeBranch = nullptr;
for (auto oneNode : onePath) { for (auto oneNode : onePath) {
if (oneNode->type == NODE_TYPE_OPERATOR_BINARY_OR) { if (oneNode->type == NODE_TYPE_OPERATOR_BINARY_OR) {
return false; return false;
} }
if (compareNode != nullptr && accessNodeBranch == nullptr) {
accessNodeBranch = oneNode;
}
if (oneNode->type == NODE_TYPE_OPERATOR_BINARY_EQ) {
compareNode = oneNode;
}
}
if (compareNode != NULL) {
AstNode const * pathAccessNode;
AstNode const * filterByNode;
if (compareNode->getMember(0) == accessNodeBranch) {
pathAccessNode = accessNodeBranch;
filterByNode = compareNode->getMember(1);
}
else {
pathAccessNode = accessNodeBranch;
filterByNode = compareNode->getMember(0);
}
if (accessNodeBranch->isSimple() && filterByNode->type == NODE_TYPE_VALUE) {
AstNode *newNode = accessNodeBranch->clone(ast);
// since we just copied one path, we should only find one.
newNode->findVariableAccess(currentPath, clonePath, var);
newNode->dump(20);
if (isAsterisc) {
}
else {
auto len = clonePath[0].size();
/// todo len < 4
AstNode* firstRefNode = (AstNode*) clonePath[0][len - 4];
TRI_ASSERT(firstRefNode->type == NODE_TYPE_ATTRIBUTE_ACCESS);
auto varRefNode = new AstNode(NODE_TYPE_REFERENCE);
ast->query()->addNode(varRefNode);
varRefNode->setData(isEdgeAccess ? tn->edgeOutVariable(): tn->vertexOutVariable());
firstRefNode->changeMember(0, varRefNode);
tn->storeSimpleExpression(isAsterisc,
isEdgeAccess,
attrAccessTo,
NODE_TYPE_OPERATOR_BINARY_EQ,
newNode,
filterByNode);
printf("\n xxxxx: %s\n", newNode->toString().c_str());
printf("\n yyyy: %s\n", accessNodeBranch->toString().c_str());
printf("\n yyyy: %s\n", filterByNode->toString().c_str());
}
}
printf("\na: %s\n", compareNode->toString().c_str());
printf("\na: %s\n", accessNodeBranch->toString().c_str());
triagens::basics::Json j(TRI_UNKNOWN_MEM_ZONE, accessNodeBranch->toJson(TRI_UNKNOWN_MEM_ZONE, true));
printf("sanotuh %s\n", j.toString().c_str());
} }
} }
@ -189,7 +263,7 @@ bool TraversalConditionFinder::before (ExecutionNode* en) {
int variableType = node->checkIsOutVariable(conditionVar->id); int variableType = node->checkIsOutVariable(conditionVar->id);
if (variableType >= 0) { if (variableType >= 0) {
if ((variableType == 2) && if ((variableType == 2) &&
checkPathVariableAccessFeasible(cn, node, conditionVar, conditionIsImpossible)) checkPathVariableAccessFeasible(cn, node, conditionVar, conditionIsImpossible, _plan->getAst()))
{ {
condition->andCombine(it.second->expression()->node()); condition->andCombine(it.second->expression()->node());
foundCondition = true; foundCondition = true;

View File

@ -32,6 +32,19 @@ using namespace std;
using namespace triagens::basics; using namespace triagens::basics;
using namespace triagens::aql; using namespace triagens::aql;
void TraversalNode::simpleTravererExpression::toJson(triagens::basics::Json& json,
TRI_memory_zone_t* zone) const
{
json("isAsteriscAccess", triagens::basics::Json(isAsteriscAccess))
("isEdgeAccess", triagens::basics::Json(isEdgeAccess))
("indexAccess", triagens::basics::Json((int32_t)indexAccess))
("comparisonType", triagens::basics::Json("==")) /// TODO more comparison types?
("varAccess", varAccess->toJson(zone, true))
("compareTo", compareTo->toJson(zone, true));
}
TraversalNode::TraversalNode (ExecutionPlan* plan, TraversalNode::TraversalNode (ExecutionPlan* plan,
size_t id, size_t id,
TRI_vocbase_t* vocbase, TRI_vocbase_t* vocbase,
@ -185,13 +198,13 @@ TraversalNode::TraversalNode (ExecutionPlan* plan,
} }
int TraversalNode::checkIsOutVariable(size_t variableId) { int TraversalNode::checkIsOutVariable(size_t variableId) {
if (_vertexOutVariable->id == variableId) { if (_vertexOutVariable != nullptr && _vertexOutVariable->id == variableId) {
return 0; return 0;
} }
if (_edgeOutVariable->id == variableId) { if (_edgeOutVariable != nullptr && _edgeOutVariable->id == variableId) {
return 1; return 1;
} }
if (_pathOutVariable->id == variableId) { if (_pathOutVariable != nullptr && _pathOutVariable->id == variableId) {
return 2; return 2;
} }
return -1; return -1;
@ -304,6 +317,16 @@ void TraversalNode::toJsonHelper (triagens::basics::Json& nodes,
json("pathOutVariable", pathOutVariable()->toJson()); json("pathOutVariable", pathOutVariable()->toJson());
} }
if (expressions.size() > 0) {
triagens::basics::Json expressionArray = triagens::basics::Json(triagens::basics::Json::Array,
expressions.size());
for (auto x : expressions) {
triagens::basics::Json exp(zone, triagens::basics::Json::Object);
x.toJson(exp, zone);
expressionArray(exp);
}
json("simpleExpressions", expressionArray);
}
// And add it: // And add it:
nodes(json); nodes(json);
} }
@ -380,10 +403,10 @@ void TraversalNode::setCondition(triagens::aql::Condition* condition){
Ast::getReferencedVariables(condition->root(), varsUsedByCondition); Ast::getReferencedVariables(condition->root(), varsUsedByCondition);
for (auto oneVar : varsUsedByCondition) { for (auto oneVar : varsUsedByCondition) {
if ((oneVar->id != _vertexOutVariable->id) && if ((_vertexOutVariable != nullptr && oneVar->id != _vertexOutVariable->id) &&
(oneVar->id != _edgeOutVariable->id) && (_edgeOutVariable != nullptr && oneVar->id != _edgeOutVariable->id) &&
(oneVar->id != _pathOutVariable->id) && (_pathOutVariable != nullptr && oneVar->id != _pathOutVariable->id) &&
(oneVar->id != _inVariable->id)) { (_inVariable != nullptr && oneVar->id != _inVariable->id)) {
_conditionVariables.push_back(oneVar); _conditionVariables.push_back(oneVar);
} }
@ -392,6 +415,22 @@ void TraversalNode::setCondition(triagens::aql::Condition* condition){
_condition = condition; _condition = condition;
} }
void TraversalNode::storeSimpleExpression(bool isAsteriscAccess,
bool isEdgeAccess,
size_t indexAccess,
AstNodeType comparisonType,
AstNode const* varAccess,
AstNode const* compareTo) {
simpleTravererExpression e {
isAsteriscAccess,
isEdgeAccess,
indexAccess,
comparisonType,
varAccess,
compareTo};
expressions.emplace_back(e);
}
// Local Variables: // Local Variables:

View File

@ -49,6 +49,18 @@ namespace triagens {
friend class ExecutionBlock; friend class ExecutionBlock;
friend class TraversalCollectionBlock; friend class TraversalCollectionBlock;
struct simpleTravererExpression {
bool isAsteriscAccess;
bool isEdgeAccess;
size_t indexAccess;
AstNodeType comparisonType;
AstNode const* varAccess;
AstNode const* compareTo;
void toJson(triagens::basics::Json& json,
TRI_memory_zone_t* zone) const;
};
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
/// @brief constructor with a vocbase and a collection name /// @brief constructor with a vocbase and a collection name
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
@ -325,6 +337,17 @@ namespace triagens {
return _maxDepth >= _minDepth; return _maxDepth >= _minDepth;
} }
////////////////////////////////////////////////////////////////////////////////
/// @brief Remember a simple comparator filter
////////////////////////////////////////////////////////////////////////////////
void storeSimpleExpression(bool isAsteriscAccess,
bool isEdgeAccess,
size_t indexAccess,
AstNodeType comparisonType,
AstNode const* varAccess,
AstNode const* compareTo);
// ----------------------------------------------------------------------------- // -----------------------------------------------------------------------------
// --SECTION-- private variables // --SECTION-- private variables
// ----------------------------------------------------------------------------- // -----------------------------------------------------------------------------
@ -421,6 +444,12 @@ namespace triagens {
//////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////
std::vector<Variable const*> _conditionVariables; std::vector<Variable const*> _conditionVariables;
////////////////////////////////////////////////////////////////////////////////
/// @brief store a simple comparator filter
////////////////////////////////////////////////////////////////////////////////
std::vector<simpleTravererExpression> expressions;
}; };
} // namespace triagens::aql } // namespace triagens::aql