From ad1e5d2e51aec2d843e95d672df92f6ef2218dfb Mon Sep 17 00:00:00 2001 From: Jan Date: Fri, 30 Aug 2019 18:31:55 +0200 Subject: [PATCH] fixed issue #9862 (#9865) --- CHANGELOG | 8 +++- arangod/RocksDBEngine/RocksDBPrimaryIndex.cpp | 3 +- .../aql/aql-primary-index-noncluster.js | 38 ++++++++++++++++++- 3 files changed, 46 insertions(+), 3 deletions(-) diff --git a/CHANGELOG b/CHANGELOG index a6262880aa..b2d8a2c8d0 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -1,7 +1,13 @@ v3.5.1 (XXXX-XX-XX) ------------------- -* Fixed adding an orphan collections as the first collection in a SmartGraph. +* Fixed issue #9862: ServerException: RestHandler/RestCursorHandler.cpp:279 + + This fixes an issue with the RocksDB primary index IN iterator not resetting its + internal iterator after being rearmed with new lookup values (which only happens + if the IN iterator is called from an inner FOR loop). + +* Fixed adding an orphan collection as the first collection in a SmartGraph. * Geo functions will now have better error reporting on invalid input. diff --git a/arangod/RocksDBEngine/RocksDBPrimaryIndex.cpp b/arangod/RocksDBEngine/RocksDBPrimaryIndex.cpp index 7c564cc0d6..f20f757a78 100644 --- a/arangod/RocksDBEngine/RocksDBPrimaryIndex.cpp +++ b/arangod/RocksDBEngine/RocksDBPrimaryIndex.cpp @@ -207,9 +207,10 @@ class RocksDBPrimaryIndexInIterator final : public IndexIterator { if (aap.value->isArray()) { _index->fillInLookupValues(_trx, *(_keys.get()), aap.value, opts.ascending, !_allowCoveringIndexOptimization); + _iterator = VPackArrayIterator(_keys->slice()); return true; } - + return false; } diff --git a/tests/js/server/aql/aql-primary-index-noncluster.js b/tests/js/server/aql/aql-primary-index-noncluster.js index 569eb60958..a9ebfcd440 100644 --- a/tests/js/server/aql/aql-primary-index-noncluster.js +++ b/tests/js/server/aql/aql-primary-index-noncluster.js @@ -189,7 +189,43 @@ function explainSuite () { ] }; assertEqual([ 1, 2, 3], AQL_EXECUTE(query, bindParams).json); - } + }, + + testInIteratorJustNumeric : function () { + let query = "FOR i IN 1..10 FOR doc IN " + cn + " FILTER doc._id IN [i, i + 1] RETURN doc._key"; + + assertEqual([ ], AQL_EXECUTE(query).json); + }, + + testInIteratorString : function () { + let query = "FOR i IN 1..5 LET key = CONCAT('testkey', i) FOR doc IN " + cn + " FILTER doc._key IN [key, 'foo'] RETURN doc._key"; + + assertEqual(["testkey1", "testkey2", "testkey3", "testkey4", "testkey5"], AQL_EXECUTE(query).json); + }, + + testInIteratorStringId : function () { + let query = "FOR i IN 1..5 LET key = CONCAT('" + cn + "/testkey', i) FOR doc IN " + cn + " FILTER doc._id IN [key, 'foo'] RETURN doc._key"; + + assertEqual(["testkey1", "testkey2", "testkey3", "testkey4", "testkey5"], AQL_EXECUTE(query).json); + }, + + testInIteratorStringAndNumericReturnId : function () { + let query = "FOR i IN 1..5 LET key = CONCAT('" + cn + "/testkey', i) FOR doc IN " + cn + " FILTER doc._id IN [key, i] RETURN doc._id"; + + assertEqual([cn + "/testkey1", cn + "/testkey2", cn + "/testkey3", cn + "/testkey4", cn + "/testkey5"], AQL_EXECUTE(query).json); + }, + + testInIteratorStringAndNumeric : function () { + let query = "FOR i IN 1..5 LET key = CONCAT('" + cn + "/testkey', i) FOR doc IN " + cn + " FILTER doc._id IN [key, i] RETURN doc._key"; + + assertEqual(["testkey1", "testkey2", "testkey3", "testkey4", "testkey5"], AQL_EXECUTE(query).json); + }, + + testInIteratorStringDuplicate : function () { + let query = "FOR i IN 1..5 LET key = CONCAT('" + cn + "/testkey', i) FOR doc IN " + cn + " FILTER doc._id IN [key, key] RETURN doc._id"; + + assertEqual([cn + "/testkey1", cn + "/testkey2", cn + "/testkey3", cn + "/testkey4", cn + "/testkey5"], AQL_EXECUTE(query).json); + }, }; }