diff --git a/CHANGELOG b/CHANGELOG index 71f838c49a..5a89dffdef 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -1,6 +1,8 @@ v3.5.1 (XXXX-XX-XX) ------------------- +* Fixed issue #10078: FULLTEXT with sort on same field not working. + * Fixed issue #10062: AQL: could not extract custom attribute. * Fix compilation issue with clang 10. diff --git a/arangod/RocksDBEngine/RocksDBFulltextIndex.h b/arangod/RocksDBEngine/RocksDBFulltextIndex.h index 0bff87ab14..483865901b 100644 --- a/arangod/RocksDBEngine/RocksDBFulltextIndex.h +++ b/arangod/RocksDBEngine/RocksDBFulltextIndex.h @@ -67,7 +67,7 @@ class RocksDBFulltextIndex final : public RocksDBIndex { bool canBeDropped() const override { return true; } - bool isSorted() const override { return true; } + bool isSorted() const override { return false; } bool hasSelectivityEstimate() const override { return false; } diff --git a/tests/js/server/aql/aql-optimizer-rule-use-index-for-sort-noncluster.js b/tests/js/server/aql/aql-optimizer-rule-use-index-for-sort-noncluster.js index 52b924a92f..faef7726bb 100644 --- a/tests/js/server/aql/aql-optimizer-rule-use-index-for-sort-noncluster.js +++ b/tests/js/server/aql/aql-optimizer-rule-use-index-for-sort-noncluster.js @@ -37,13 +37,14 @@ var findExecutionNodes = helper.findExecutionNodes; var findReferencedNodes = helper.findReferencedNodes; var getQueryMultiplePlansAndExecutions = helper.getQueryMultiplePlansAndExecutions; var removeAlwaysOnClusterRules = helper.removeAlwaysOnClusterRules; + +const ruleName = "use-index-for-sort"; //////////////////////////////////////////////////////////////////////////////// /// @brief test suite //////////////////////////////////////////////////////////////////////////////// function optimizerRuleTestSuite() { - const ruleName = "use-index-for-sort"; const colName = "UnitTestsUseIndexForSort"; let c; @@ -195,6 +196,48 @@ function optimizerRuleTestSuite() { }; } +function optimizerRuleWithOtherIndexTypesTestSuite() { + const cn = "UnitTestsCollection"; + + return { + setUp : function () { + internal.db._drop(cn); + internal.db._create(cn, { numberOfShards: 3 }); + }, + + tearDown : function () { + internal.db._drop(cn); + }, + + testFulltextAscending : function () { + internal.db[cn].ensureIndex({ type: "fulltext", fields: ["name"] }); + internal.db[cn].insert([ { name: "Agatha" }, { name: "Agathe" }, { name: "Aardvark" }, { name: "Aaron" }, { name: "Astrid" }, { name: "Ana" }, { name: "Anna" }, { name: "Anne" }, { name: "Ali" } ]); + + let query = `FOR doc IN FULLTEXT(${cn}, 'name', 'prefix:a') SORT doc.name RETURN doc.name`; + + let rules = AQL_EXPLAIN(query).plan.rules; + assertEqual(-1, rules.indexOf(ruleName)); + + let results = AQL_EXECUTE(query).json; + assertEqual([ "Aardvark", "Aaron", "Agatha", "Agathe", "Ali", "Ana", "Anna", "Anne", "Astrid" ], results); + }, + + testFulltextDescending : function () { + internal.db[cn].ensureIndex({ type: "fulltext", fields: ["name"] }); + internal.db[cn].insert([ { name: "Agatha" }, { name: "Agathe" }, { name: "Aardvark" }, { name: "Aaron" }, { name: "Astrid" }, { name: "Ana" }, { name: "Anna" }, { name: "Anne" }, { name: "Ali" } ]); + + let query = `FOR doc IN FULLTEXT(${cn}, 'name', 'prefix:a') SORT doc.name DESC RETURN doc.name`; + + let rules = AQL_EXPLAIN(query).plan.rules; + assertEqual(-1, rules.indexOf(ruleName)); + + let results = AQL_EXECUTE(query).json; + assertEqual([ "Astrid", "Anne", "Anna", "Ana", "Ali", "Agathe", "Agatha", "Aaron", "Aardvark" ], results); + }, + }; +} + jsunity.run(optimizerRuleTestSuite); +jsunity.run(optimizerRuleWithOtherIndexTypesTestSuite); return jsunity.done(); diff --git a/tests/js/server/aql/aql-optimizer-rule-use-index-for-sort.js b/tests/js/server/aql/aql-optimizer-rule-use-index-for-sort.js index 3b40c022d1..56b535c2da 100644 --- a/tests/js/server/aql/aql-optimizer-rule-use-index-for-sort.js +++ b/tests/js/server/aql/aql-optimizer-rule-use-index-for-sort.js @@ -37,13 +37,14 @@ var findExecutionNodes = helper.findExecutionNodes; var findReferencedNodes = helper.findReferencedNodes; var getQueryMultiplePlansAndExecutions = helper.getQueryMultiplePlansAndExecutions; var removeAlwaysOnClusterRules = helper.removeAlwaysOnClusterRules; + +const ruleName = "use-index-for-sort"; //////////////////////////////////////////////////////////////////////////////// /// @brief test suite //////////////////////////////////////////////////////////////////////////////// function optimizerRuleTestSuite() { - var ruleName = "use-index-for-sort"; var secondRuleName = "use-indexes"; var removeCalculationNodes = "remove-unnecessary-calculations-2"; var colName = "UnitTestsAqlOptimizer" + ruleName.replace(/-/g, "_");