From 541675504964002a41d5ac11cf6dc68f93eab4b5 Mon Sep 17 00:00:00 2001 From: Jan Christoph Uhde Date: Wed, 7 Dec 2016 15:06:44 +0100 Subject: [PATCH] avoid use of geo-index-rule in cases where it could yield an invalid result --- arangod/Aql/Optimizer.h | 2 +- arangod/Aql/OptimizerRules.cpp | 30 ++++++++++++++++++++++++++++++ 2 files changed, 31 insertions(+), 1 deletion(-) diff --git a/arangod/Aql/Optimizer.h b/arangod/Aql/Optimizer.h index 502b173602..0ec7d6661a 100644 --- a/arangod/Aql/Optimizer.h +++ b/arangod/Aql/Optimizer.h @@ -145,7 +145,7 @@ class Optimizer { // remove redundant OR conditions removeRedundantOrRule_pass6 = 820, - applyGeoIndexRule = 1060, + applyGeoIndexRule = 825, useIndexesRule_pass6 = 830, diff --git a/arangod/Aql/OptimizerRules.cpp b/arangod/Aql/OptimizerRules.cpp index 368257fd12..a683928e06 100644 --- a/arangod/Aql/OptimizerRules.cpp +++ b/arangod/Aql/OptimizerRules.cpp @@ -4201,6 +4201,7 @@ GeoIndexInfo geoDistanceFunctionArgCheck(std::pair const& pai if(setter1 == setter2){ if(setter1->getType() == EN::ENUMERATE_COLLECTION){ auto collNode = reinterpret_cast(setter1); + auto coll = collNode->collection(); //what kind of indexes does it have on what attributes auto lcoll = coll->getCollection(); // TODO - check collection for suitable geo-indexes @@ -4339,6 +4340,35 @@ bool applyGeoOptimization(bool near, ExecutionPlan* plan, GeoIndexInfo& info){ constantPair = &argPair1; } + // We are not allowed to be a inner loop + if(res.collectionNode->isInInnerLoop()){ + return false; + } + + //// this works only as long as we just use lists of ExecutionNodes + // avoid other constructs between sort/filter and enumerate collection + ExecutionNode* current = res.executionNode->getFirstDependency(); + ExecutionNode* end = res.collectionNode; + while(current != end){ + if( current->getType() == EN::SORT + || current->getType() == EN::COLLECT + || current->getType() == EN::FILTER + || current->getType() == EN::ENUMERATE_COLLECTION + || current->getType() == EN::INDEX + ){ + return false; + } + current = current->getFirstDependency(); + } + + // avoid sorts above index node + while(current != plan->root()){ + if(current->getType() == EN::SORT){ + return false; + } + current = current->getFirstDependency(); + } + //LOG_TOPIC(DEBUG, Logger::DEVEL) << " attributes: " << res.longitude[0] // << ", " << res.longitude // << " of collection:" << res.collectionNode->collection()->getName()