diff --git a/arangod/Ahuacatl/ahuacatl-collections.c b/arangod/Ahuacatl/ahuacatl-collections.c index 94da2d1c07..7dc9ac4f5f 100644 --- a/arangod/Ahuacatl/ahuacatl-collections.c +++ b/arangod/Ahuacatl/ahuacatl-collections.c @@ -270,7 +270,7 @@ TRI_json_t* TRI_GetJsonCollectionHintAql (TRI_aql_collection_hint_t* const hint) TRI_Insert3ArrayJson(TRI_UNKNOWN_MEM_ZONE, result, "limit", - TRI_CreateNumberJson(TRI_UNKNOWN_MEM_ZONE, (double) hint->_limit._limit)); + TRI_CreateNumberJson(TRI_UNKNOWN_MEM_ZONE, (double) hint->_limit._offset + (double) hint->_limit._limit)); } return result; diff --git a/arangod/Ahuacatl/ahuacatl-optimiser.c b/arangod/Ahuacatl/ahuacatl-optimiser.c index 5c0ea72ec2..815c0a4b92 100644 --- a/arangod/Ahuacatl/ahuacatl-optimiser.c +++ b/arangod/Ahuacatl/ahuacatl-optimiser.c @@ -470,16 +470,32 @@ static TRI_aql_node_t* AnnotateLoop (TRI_aql_statement_walker_t* const walker, // check if we can apply a scope limit and push it into the for loop if (scope->_limit._status == TRI_AQL_LIMIT_USE) { // yes! - TRI_aql_for_hint_t* hint = (TRI_aql_for_hint_t*) TRI_AQL_NODE_DATA(node); + TRI_aql_node_t* expression = TRI_AQL_NODE_MEMBER(node, 1); - if (hint != NULL) { - // we'll now modify the hint for the for loop - hint->_limit._offset = scope->_limit._offset; - hint->_limit._limit = scope->_limit._limit; - hint->_limit._status = TRI_AQL_LIMIT_USE; - hint->_limit._hasFilter = scope->_limit._hasFilter; - - LOG_TRACE("using limit hint for for loop"); + if (expression->_type == TRI_AQL_NODE_COLLECTION && ! scope->_limit._hasFilter) { + // move limit into the COLLECTION node + TRI_aql_collection_hint_t* hint = (TRI_aql_collection_hint_t*) TRI_AQL_NODE_DATA(expression); + + if (hint != NULL) { + hint->_limit._offset = scope->_limit._offset; + hint->_limit._limit = scope->_limit._limit; + hint->_limit._status = TRI_AQL_LIMIT_USE; + hint->_limit._hasFilter = scope->_limit._hasFilter; + } + } + else { + // move limit into the FOR node + TRI_aql_for_hint_t* hint = (TRI_aql_for_hint_t*) TRI_AQL_NODE_DATA(node); + + if (hint != NULL) { + // we'll now modify the hint for the for loop + hint->_limit._offset = scope->_limit._offset; + hint->_limit._limit = scope->_limit._limit; + hint->_limit._status = TRI_AQL_LIMIT_USE; + hint->_limit._hasFilter = scope->_limit._hasFilter; + + LOG_TRACE("using limit hint for for loop"); + } } // deactive this limit for any further tries diff --git a/js/server/tests/ahuacatl-queries-optimiser-limit.js b/js/server/tests/ahuacatl-queries-optimiser-limit.js index ebf5284191..bd72ff06c7 100644 --- a/js/server/tests/ahuacatl-queries-optimiser-limit.js +++ b/js/server/tests/ahuacatl-queries-optimiser-limit.js @@ -192,7 +192,7 @@ function ahuacatlQueryOptimiserLimitTestSuite () { var explain = explainQuery(query); assertEqual("for", explain[0].type); - assertEqual(true, explain[0].limit); + assertEqual(test.offset + test.limit, explain[0]["expression"]["extra"]["limit"]); } }, @@ -357,7 +357,7 @@ function ahuacatlQueryOptimiserLimitTestSuite () { var explain = explainQuery(query); assertEqual("for", explain[0].type); - assertEqual(true, explain[0].limit); + assertEqual(test.offset + test.limit, explain[0]["expression"]["extra"]["limit"]); } },