diff --git a/arangod/Aql/Optimizer.cpp b/arangod/Aql/Optimizer.cpp index 12a621b2a2..e45a4134e2 100644 --- a/arangod/Aql/Optimizer.cpp +++ b/arangod/Aql/Optimizer.cpp @@ -117,6 +117,7 @@ int Optimizer::createPlans (ExecutionPlan* plan, return TRI_ERROR_NO_ERROR; } + bool runOnlyRequiredRules = false; int leastDoneLevel = 0; TRI_ASSERT(! _rules.empty()); @@ -169,9 +170,10 @@ int Optimizer::createPlans (ExecutionPlan* plan, */ level = (*it).first; - if (disabledIds.find(level) != disabledIds.end() && + if ((runOnlyRequiredRules || disabledIds.find(level) != disabledIds.end()) && (*it).second.canBeDisabled) { - // we picked a disabled rule + // we picked a disabled rule or we have reached the max number of plans + // and just skip this rule level = it->first; _newPlans.push_back(p, level); // nothing to do, just keep it @@ -210,13 +212,12 @@ int Optimizer::createPlans (ExecutionPlan* plan, // std::cout << "Least done level is " << leastDoneLevel << std::endl; // Stop if the result gets out of hand: - if (_plans.size() >= _maxNumberOfPlans) { - // TODO: must iterate over all REQUIRED remaining transformation rules + if (! runOnlyRequiredRules && + _plans.size() >= _maxNumberOfPlans) { + // must still iterate over all REQUIRED remaining transformation rules // because there are some rules which are required to make the query // work in cluster mode - // rules that have their canBeDisabled flag set to false must still - // be carried out! - break; + runOnlyRequiredRules = true; } } diff --git a/js/server/tests/aql-optimizer-rule-distribute-in-cluster.js b/js/server/tests/aql-optimizer-rule-distribute-in-cluster.js index 77ffb28468..535ea4232c 100644 --- a/js/server/tests/aql-optimizer-rule-distribute-in-cluster.js +++ b/js/server/tests/aql-optimizer-rule-distribute-in-cluster.js @@ -43,6 +43,7 @@ function optimizerRuleTestSuite () { var rulesAll = { optimizer: { rules: [ "+all" ] } }; var thisRuleEnabled = { optimizer: { rules: [ "-all", "+" + ruleName ] } }; var thisRuleDisabled = { optimizer: { rules: [ "+all", "-" + ruleName ] } }; + var maxPlans = { optimizer: { rules: [ "-all" ] }, maxNumberOfPlans: 1 }; var cn1 = "UnitTestsAqlOptimizerRuleUndist1"; var cn2 = "UnitTestsAqlOptimizerRuleUndist2"; @@ -79,6 +80,43 @@ function optimizerRuleTestSuite () { db._drop(cn1); db._drop(cn2); }, + + //////////////////////////////////////////////////////////////////////////////// + /// @brief test that the rules fire even if the max number of plans is reached + //////////////////////////////////////////////////////////////////////////////// + + testThisRuleEnabledMaxNumberOfPlans : function () { + var queries = [ + "FOR d IN " + cn1 + " REMOVE d in " + cn1, + "FOR d IN " + cn1 + " REMOVE d._key in " + cn1, + "FOR d IN " + cn1 + " INSERT d in " + cn2, + "FOR d IN " + cn1 + " INSERT d._key in " + cn2 + ]; + + var expectedRules = [ + [ + "distribute-in-cluster", + "scatter-in-cluster", + ], + [ + "distribute-in-cluster", + "scatter-in-cluster" + ], + [ + "distribute-in-cluster", + "scatter-in-cluster" + ], + [ + "distribute-in-cluster", + "scatter-in-cluster" + ] + ]; + + queries.forEach(function(query, i) { + var result = AQL_EXPLAIN(query, { }, maxPlans); + assertEqual(expectedRules[i], result.plan.rules, query); + }); + }, //////////////////////////////////////////////////////////////////////////////// /// @brief test that the rule fires when it is enabled @@ -100,7 +138,6 @@ function optimizerRuleTestSuite () { [ "distribute-in-cluster", "scatter-in-cluster", - "distribute-filtercalc-to-cluster" ], [ "distribute-in-cluster", @@ -109,7 +146,6 @@ function optimizerRuleTestSuite () { [ "distribute-in-cluster", "scatter-in-cluster", - "distribute-filtercalc-to-cluster" ] ]; @@ -132,9 +168,9 @@ function optimizerRuleTestSuite () { "ScatterNode", "RemoteNode", "EnumerateCollectionNode", - "CalculationNode", "RemoteNode", "GatherNode", + "CalculationNode", "DistributeNode", "RemoteNode", "RemoveNode", @@ -159,9 +195,9 @@ function optimizerRuleTestSuite () { "ScatterNode", "RemoteNode", "EnumerateCollectionNode", - "CalculationNode", "RemoteNode", "GatherNode", + "CalculationNode", "DistributeNode", "RemoteNode", "InsertNode", @@ -375,7 +411,6 @@ function optimizerRuleTestSuite () { [ "distribute-in-cluster", "scatter-in-cluster", - "distribute-filtercalc-to-cluster", ], [ "distribute-in-cluster", @@ -384,7 +419,6 @@ function optimizerRuleTestSuite () { [ "distribute-in-cluster", "scatter-in-cluster", - "distribute-filtercalc-to-cluster", ] ]; @@ -407,9 +441,9 @@ function optimizerRuleTestSuite () { "ScatterNode", "RemoteNode", "EnumerateCollectionNode", - "CalculationNode", "RemoteNode", "GatherNode", + "CalculationNode", "DistributeNode", "RemoteNode", "RemoveNode", @@ -434,9 +468,9 @@ function optimizerRuleTestSuite () { "ScatterNode", "RemoteNode", "EnumerateCollectionNode", - "CalculationNode", "RemoteNode", "GatherNode", + "CalculationNode", "DistributeNode", "RemoteNode", "InsertNode", diff --git a/m4/configure.information b/m4/configure.information index 6ae2f0771d..cab2deabeb 100644 --- a/m4/configure.information +++ b/m4/configure.information @@ -46,6 +46,8 @@ AC_MSG_NOTICE([LIBS: ${LIBS}]) CC_VERSION=`${CC} --version 2>&1` AC_MSG_NOTICE([CC: ${CC_VERSION}]) +CXX_VERSION=`${CXX} --version 2>&1` +AC_MSG_NOTICE([CXX: ${CXX_VERSION}]) echo $FLAG_INFO | tr "|" "\n" | while read a; do if test "x$a" != "x"; then