mirror of https://gitee.com/bigwinds/arangodb
node replacement is now working
This commit is contained in:
parent
d1a3e4482d
commit
71be8c215a
|
@ -3928,6 +3928,7 @@ struct GeoIndexInfo{
|
||||||
GeoIndexInfo()
|
GeoIndexInfo()
|
||||||
: collectionNode(nullptr)
|
: collectionNode(nullptr)
|
||||||
, executionNode(nullptr)
|
, executionNode(nullptr)
|
||||||
|
, expressionParent(nullptr)
|
||||||
, expressionNode(nullptr)
|
, expressionNode(nullptr)
|
||||||
, distanceNode(nullptr)
|
, distanceNode(nullptr)
|
||||||
, index(nullptr)
|
, index(nullptr)
|
||||||
|
@ -3936,10 +3937,10 @@ struct GeoIndexInfo{
|
||||||
, within(false)
|
, within(false)
|
||||||
, lessgreaterequal(false)
|
, lessgreaterequal(false)
|
||||||
, valid(true)
|
, valid(true)
|
||||||
, inSubCondition(false)
|
|
||||||
{}
|
{}
|
||||||
EnumerateCollectionNode* collectionNode; // node that will be replaced by (geo) IndexNode
|
EnumerateCollectionNode* collectionNode; // node that will be replaced by (geo) IndexNode
|
||||||
ExecutionNode* executionNode; // start node hat is a sort or filter
|
ExecutionNode* executionNode; // start node hat is a sort or filter
|
||||||
|
AstNode* expressionParent; // AstNode that is the parent of the Node
|
||||||
AstNode* expressionNode; // AstNode that contains the sort/filter condition
|
AstNode* expressionNode; // AstNode that contains the sort/filter condition
|
||||||
AstNode* distanceNode; // AstNode that contains the distance parameters
|
AstNode* distanceNode; // AstNode that contains the distance parameters
|
||||||
std::shared_ptr<arangodb::Index> index; //pointer to geoindex
|
std::shared_ptr<arangodb::Index> index; //pointer to geoindex
|
||||||
|
@ -3948,7 +3949,6 @@ struct GeoIndexInfo{
|
||||||
bool within; // is this a within lookup
|
bool within; // is this a within lookup
|
||||||
bool lessgreaterequal; // is this a check for le/ge (true) or lt/gt (false)
|
bool lessgreaterequal; // is this a check for le/ge (true) or lt/gt (false)
|
||||||
bool valid; // contains this node a valid condition
|
bool valid; // contains this node a valid condition
|
||||||
bool inSubCondition;
|
|
||||||
std::vector<std::string> longitude; // access path to longitude
|
std::vector<std::string> longitude; // access path to longitude
|
||||||
std::vector<std::string> latitude; // access path to latitude
|
std::vector<std::string> latitude; // access path to latitude
|
||||||
};
|
};
|
||||||
|
@ -3961,7 +3961,7 @@ AstNode* isValueOrRefNode(AstNode* node){
|
||||||
return node;
|
return node;
|
||||||
}
|
}
|
||||||
|
|
||||||
GeoIndexInfo isDistanceFunction(AstNode* distanceNode, bool inSubCondition){
|
GeoIndexInfo isDistanceFunction(AstNode* distanceNode, AstNode* expressionParent){
|
||||||
// the expression must exist and it must be a function call
|
// the expression must exist and it must be a function call
|
||||||
auto rv = GeoIndexInfo{};
|
auto rv = GeoIndexInfo{};
|
||||||
if(distanceNode->type != NODE_TYPE_FCALL) {
|
if(distanceNode->type != NODE_TYPE_FCALL) {
|
||||||
|
@ -3979,11 +3979,11 @@ GeoIndexInfo isDistanceFunction(AstNode* distanceNode, bool inSubCondition){
|
||||||
//LOG_TOPIC(DEBUG, Logger::DEVEL) << "FOUND DISTANCE FUNCTION";
|
//LOG_TOPIC(DEBUG, Logger::DEVEL) << "FOUND DISTANCE FUNCTION";
|
||||||
rv.distanceNode = distanceNode;
|
rv.distanceNode = distanceNode;
|
||||||
rv.expressionNode = distanceNode;
|
rv.expressionNode = distanceNode;
|
||||||
rv.inSubCondition = inSubCondition;
|
rv.expressionParent = expressionParent;
|
||||||
return rv;
|
return rv;
|
||||||
}
|
}
|
||||||
|
|
||||||
GeoIndexInfo isGeoFilterExpression(AstNode* node, bool inSubCondition){
|
GeoIndexInfo isGeoFilterExpression(AstNode* node, AstNode* expressionParent){
|
||||||
// binary compare must be on top
|
// binary compare must be on top
|
||||||
bool dist_first = true;
|
bool dist_first = true;
|
||||||
bool lessEqual = true;
|
bool lessEqual = true;
|
||||||
|
@ -4032,10 +4032,10 @@ GeoIndexInfo isGeoFilterExpression(AstNode* node, bool inSubCondition){
|
||||||
|
|
||||||
|
|
||||||
//LOG_TOPIC(DEBUG, Logger::DEVEL) << "frist check";
|
//LOG_TOPIC(DEBUG, Logger::DEVEL) << "frist check";
|
||||||
rv = eval_stuff(dist_first, lessEqual, isDistanceFunction(first, inSubCondition), isValueOrRefNode(second));
|
rv = eval_stuff(dist_first, lessEqual, isDistanceFunction(first, expressionParent), isValueOrRefNode(second));
|
||||||
if (!rv) {
|
if (!rv) {
|
||||||
//LOG_TOPIC(DEBUG, Logger::DEVEL) << "second check";
|
//LOG_TOPIC(DEBUG, Logger::DEVEL) << "second check";
|
||||||
rv = eval_stuff(dist_first, lessEqual, isDistanceFunction(second, inSubCondition), isValueOrRefNode(first));
|
rv = eval_stuff(dist_first, lessEqual, isDistanceFunction(second, expressionParent), isValueOrRefNode(first));
|
||||||
}
|
}
|
||||||
//LOG_TOPIC(DEBUG, Logger::DEVEL) << "result " << (bool) rv;
|
//LOG_TOPIC(DEBUG, Logger::DEVEL) << "result " << (bool) rv;
|
||||||
|
|
||||||
|
@ -4047,27 +4047,25 @@ GeoIndexInfo isGeoFilterExpression(AstNode* node, bool inSubCondition){
|
||||||
return rv;
|
return rv;
|
||||||
}
|
}
|
||||||
|
|
||||||
GeoIndexInfo iterativePreorderWithCondition(AstNode* root, GeoIndexInfo(*condition)(AstNode*, bool)){
|
GeoIndexInfo iterativePreorderWithCondition(AstNode* root, GeoIndexInfo(*condition)(AstNode*, AstNode*)){
|
||||||
// returns on first hit
|
// returns on first hit
|
||||||
if (!root){
|
if (!root){
|
||||||
return GeoIndexInfo{};
|
return GeoIndexInfo{};
|
||||||
}
|
}
|
||||||
bool inSubCondition = false;
|
std::vector<std::pair<AstNode*,AstNode*>> nodestack;
|
||||||
std::vector<AstNode*> nodestack;
|
nodestack.push_back({root,nullptr});
|
||||||
nodestack.push_back(root);
|
|
||||||
|
|
||||||
while(nodestack.size()){
|
while(nodestack.size()){
|
||||||
AstNode* current = nodestack.back();
|
auto current = nodestack.back();
|
||||||
nodestack.pop_back();
|
nodestack.pop_back();
|
||||||
GeoIndexInfo rv = condition(current,inSubCondition);
|
GeoIndexInfo rv = condition(current.first,current.second);
|
||||||
inSubCondition = true; // only false for root
|
|
||||||
if (rv) {
|
if (rv) {
|
||||||
return rv;
|
return rv;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (current->type == NODE_TYPE_OPERATOR_BINARY_AND || current->type == NODE_TYPE_OPERATOR_NARY_AND ){
|
if (current.first->type == NODE_TYPE_OPERATOR_BINARY_AND || current.first->type == NODE_TYPE_OPERATOR_NARY_AND ){
|
||||||
for (std::size_t i = 0; i < current->numMembers(); ++i){
|
for (std::size_t i = 0; i < current.first->numMembers(); ++i){
|
||||||
nodestack.push_back(current->getMember(i));
|
nodestack.push_back({current.first->getMember(i),current.first});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -4143,12 +4141,12 @@ GeoIndexInfo identifyGeoOptimizationCandidate(ExecutionNode::NodeType type, Exec
|
||||||
//FIXME -- technical debt -- code duplication / not all cases covered
|
//FIXME -- technical debt -- code duplication / not all cases covered
|
||||||
switch(type){
|
switch(type){
|
||||||
case EN::SORT: {
|
case EN::SORT: {
|
||||||
rv = isDistanceFunction(node,false);
|
rv = isDistanceFunction(node,nullptr);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case EN::FILTER: {
|
case EN::FILTER: {
|
||||||
rv = iterativePreorderWithCondition(node,isGeoFilterExpression);
|
rv = iterativePreorderWithCondition(node,&isGeoFilterExpression);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
@ -4287,14 +4285,21 @@ std::unique_ptr<Condition> buildGeoCondition(ExecutionPlan* plan, GeoIndexInfo&
|
||||||
|
|
||||||
//replaces the geoCondition with true.
|
//replaces the geoCondition with true.
|
||||||
//void replaceGeoCondition(ExecutionPlan* plan, GeoIndexInfo& info){
|
//void replaceGeoCondition(ExecutionPlan* plan, GeoIndexInfo& info){
|
||||||
void replaceGeoCondition(GeoIndexInfo& info){
|
void replaceGeoCondition(ExecutionPlan* plan, GeoIndexInfo& info){
|
||||||
//auto ast = plan->getAst();
|
|
||||||
//ast->createNodeValueBool(true);
|
if( info.expressionParent ) {
|
||||||
if( info.inSubCondition ) {
|
auto ast = plan->getAst();
|
||||||
info.expressionNode->clearMembers();
|
auto replacement = ast->createNodeValueBool(true);
|
||||||
info.expressionNode->setValueType(VALUE_TYPE_BOOL);
|
info.expressionParent->dump(0);
|
||||||
info.expressionNode->setBoolValue(true);
|
for(std::size_t i = 0; i < info.expressionParent->numMembers(); ++i){
|
||||||
}
|
if(info.expressionParent->getMember(i) == info.expressionNode){
|
||||||
|
info.expressionParent->removeMemberUnchecked(i);
|
||||||
|
info.expressionParent->addMember(replacement);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
info.expressionParent->dump(0);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// applys the optimization for a candidate
|
// applys the optimization for a candidate
|
||||||
|
@ -4353,9 +4358,11 @@ bool applyGeoOptimization(bool near, ExecutionPlan* plan, GeoIndexInfo& info){
|
||||||
plan->registerNode(inode);
|
plan->registerNode(inode);
|
||||||
condition.release();
|
condition.release();
|
||||||
|
|
||||||
//replaceGeoCondition(info);
|
replaceGeoCondition(plan, info);
|
||||||
|
|
||||||
if(info.executionNodeType == EN::SORT){
|
// if executionNode is sort OR a filter without further sub conditions
|
||||||
|
// the node can be unlinked
|
||||||
|
if( info.executionNodeType == EN::SORT || !info.expressionParent){
|
||||||
plan->unlinkNode(info.executionNode);
|
plan->unlinkNode(info.executionNode);
|
||||||
}
|
}
|
||||||
plan->replaceNode(res.collectionNode,inode);
|
plan->replaceNode(res.collectionNode,inode);
|
||||||
|
|
Loading…
Reference in New Issue