diff --git a/arangod/Indexes/IndexFactory.cpp b/arangod/Indexes/IndexFactory.cpp index bc240995ceca..f3688940596b 100644 --- a/arangod/Indexes/IndexFactory.cpp +++ b/arangod/Indexes/IndexFactory.cpp @@ -581,4 +581,34 @@ Result IndexFactory::enhanceJsonIndexFulltext(VPackSlice definition, return res; } +/// @brief enhances the json of a fulltext index +Result IndexFactory::enhanceJsonIndexZkd(VPackSlice definition, + VPackBuilder& builder, bool create) { + if (auto fieldValueTypes = definition.get("fieldValueTypes"); + !fieldValueTypes.isString() || !fieldValueTypes.isEqualString("double")) { + return Result( + TRI_ERROR_BAD_PARAMETER, + "zkd index requires `fieldValueTypes` to be set to `double` - future " + "releases might lift this requirement"); + } + + builder.add("fieldValueTypes", VPackValue("double")); + Result res = processIndexFields(definition, builder, 1, INT_MAX, create, false); + + if (res.ok()) { + if (auto isSparse = definition.get(StaticStrings::IndexSparse).isTrue(); isSparse) { + return Result(TRI_ERROR_BAD_PARAMETER, + "zkd index does not support sparse property"); + } + + processIndexUniqueFlag(definition, builder); + + bool bck = basics::VelocyPackHelper::getBooleanValue(definition, StaticStrings::IndexInBackground, + false); + builder.add(StaticStrings::IndexInBackground, VPackValue(bck)); + } + + return res; +} + } // namespace arangodb diff --git a/arangod/Indexes/IndexFactory.h b/arangod/Indexes/IndexFactory.h index 74d18c7eab64..463ee215a478 100644 --- a/arangod/Indexes/IndexFactory.h +++ b/arangod/Indexes/IndexFactory.h @@ -157,11 +157,15 @@ class IndexFactory { static Result enhanceJsonIndexGeo(arangodb::velocypack::Slice definition, arangodb::velocypack::Builder& builder, bool create, int minFields, int maxFields); - + /// @brief enhances the json of a fulltext index static Result enhanceJsonIndexFulltext(arangodb::velocypack::Slice definition, arangodb::velocypack::Builder& builder, bool create); + /// @brief enhances the json of a zkd index + static Result enhanceJsonIndexZkd(arangodb::velocypack::Slice definition, + arangodb::velocypack::Builder& builder, bool create); + protected: /// @brief clear internal factory/normalizer maps void clear(); diff --git a/arangod/RocksDBEngine/RocksDBIndexFactory.cpp b/arangod/RocksDBEngine/RocksDBIndexFactory.cpp index bfd3135c6374..1f5439b25ad8 100644 --- a/arangod/RocksDBEngine/RocksDBIndexFactory.cpp +++ b/arangod/RocksDBEngine/RocksDBIndexFactory.cpp @@ -295,13 +295,7 @@ struct ZkdIndexFactory : public DefaultIndexFactory { arangodb::velocypack::Value(std::to_string(TRI_NewTickServer()))); } - if (auto isSparse = definition.get(StaticStrings::IndexSparse).isTrue(); isSparse) { - THROW_ARANGO_EXCEPTION_MESSAGE( - TRI_ERROR_BAD_PARAMETER, - "zkd index does not support sparse property"); - } - - return IndexFactory::enhanceJsonIndexGeneric(definition, normalized, isCreation); + return IndexFactory::enhanceJsonIndexZkd(definition, normalized, isCreation); } }; diff --git a/tests/js/server/aql/aql-optimizer-zkdindex-multi.js b/tests/js/server/aql/aql-optimizer-zkdindex-multi.js index 97bc0802d5e5..85ce9db2846e 100644 --- a/tests/js/server/aql/aql-optimizer-zkdindex-multi.js +++ b/tests/js/server/aql/aql-optimizer-zkdindex-multi.js @@ -100,7 +100,7 @@ function optimizerRuleZkd2dIndexTestSuite() { let testObject = { setUpAll: function () { col = db._create(colName); - col.ensureIndex({type: 'zkd', name: 'zkdIndex', fields: ['x', 'y', 'z', 'a.w']}); + col.ensureIndex({type: 'zkd', name: 'zkdIndex', fields: ['x', 'y', 'z', 'a.w'], fieldValueTypes: 'double'}); db._query(aql` FOR x IN 0..10 FOR y IN 0..10 diff --git a/tests/js/server/aql/aql-optimizer-zkdindex-restricted.js b/tests/js/server/aql/aql-optimizer-zkdindex-restricted.js new file mode 100644 index 000000000000..8cb64c542670 --- /dev/null +++ b/tests/js/server/aql/aql-optimizer-zkdindex-restricted.js @@ -0,0 +1,74 @@ +/* global AQL_EXPLAIN, AQL_EXECUTE */ +//////////////////////////////////////////////////////////////////////////////// +/// DISCLAIMER +/// +/// Copyright 2021-2021 ArangoDB GmbH, Cologne, Germany +/// +/// Licensed under the Apache License, Version 2.0 (the "License"); +/// you may not use this file except in compliance with the License. +/// You may obtain a copy of the License at +/// +/// http://www.apache.org/licenses/LICENSE-2.0 +/// +/// Unless required by applicable law or agreed to in writing, software +/// distributed under the License is distributed on an "AS IS" BASIS, +/// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +/// See the License for the specific language governing permissions and +/// limitations under the License. +/// +/// Copyright holder is ArangoDB GmbH, Cologne, Germany +/// +/// @author Tobias Gödderz +//////////////////////////////////////////////////////////////////////////////// + +'use strict'; + +const jsunity = require("jsunity"); +const arangodb = require("@arangodb"); +const internal = require("internal"); +const db = arangodb.db; +const {assertEqual} = jsunity.jsUnity.assertions; + +function optimizerRuleZkd2dIndexTestSuite() { + const colName = 'UnitTestZkdIndexCollection'; + let col; + + return { + setUpAll: function () { + col = db._create(colName); + }, + + tearDownAll: function () { + col.drop(); + }, + + testNoFieldValueTypes: function () { + try { + col.ensureIndex({type: 'zkd', name: 'zkdIndex', fields: ['x', 'y']}); + } catch (e) { + assertEqual(e.errorNum, internal.errors.ERROR_BAD_PARAMETER.code); + } + }, + + testSparseProperty: function () { + try { + col.ensureIndex({type: 'zkd', name: 'zkdIndex', fields: ['x', 'y'], fieldValueTypes: 'double', sparse: true}); + } catch (e) { + assertEqual(e.errorNum, internal.errors.ERROR_BAD_PARAMETER.code); + } + }, + + testArrayExpansions: function () { + try { + col.ensureIndex({type: 'zkd', name: 'zkdIndex', fields: ['x[*]', 'y'], fieldValueTypes: 'double'}); + } catch (e) { + assertEqual(e.errorNum, internal.errors.ERROR_BAD_PARAMETER.code); + } + } + + }; +} + +jsunity.run(optimizerRuleZkd2dIndexTestSuite); + +return jsunity.done(); diff --git a/tests/js/server/aql/aql-optimizer-zkdindex-unique.js b/tests/js/server/aql/aql-optimizer-zkdindex-unique.js index 5976e11dbe8f..eb3ab7a14101 100644 --- a/tests/js/server/aql/aql-optimizer-zkdindex-unique.js +++ b/tests/js/server/aql/aql-optimizer-zkdindex-unique.js @@ -42,7 +42,13 @@ function optimizerRuleZkd2dIndexTestSuite() { return { setUpAll: function () { col = db._create(colName); - col.ensureIndex({type: 'zkd', name: 'zkdIndex', fields: ['x', 'y'], unique: true}); + col.ensureIndex({ + type: 'zkd', + name: 'zkdIndex', + fields: ['x', 'y'], + unique: true, + fieldValueTypes: 'double' + }); // Insert 1001 points // (-500, -499.5), (-499.1, -499.4), ..., (0, 0.5), ..., (499.9, 500.4), (500, 500.5) db._query(aql` diff --git a/tests/js/server/aql/aql-optimizer-zkdindex.js b/tests/js/server/aql/aql-optimizer-zkdindex.js index d6795221ade9..a75f21427856 100644 --- a/tests/js/server/aql/aql-optimizer-zkdindex.js +++ b/tests/js/server/aql/aql-optimizer-zkdindex.js @@ -41,7 +41,7 @@ function optimizerRuleZkd2dIndexTestSuite() { return { setUpAll: function () { col = db._create(colName); - col.ensureIndex({type: 'zkd', name: 'zkdIndex', fields: ['x', 'y']}); + col.ensureIndex({type: 'zkd', name: 'zkdIndex', fields: ['x', 'y'], fieldValueTypes: 'double'}); // Insert 1001 points // (-500, -499.5), (-499.1, -499.4), ..., (0, 0.5), ..., (499.9, 500.4), (500, 500.5) db._query(aql`