diff --git a/include/errcode.h b/include/errcode.h index 5d9248d41b75d400218f8806872d97391130cfd9..3f834717c61c91bd4f1e36962a6c207cfbc8e993 100644 --- a/include/errcode.h +++ b/include/errcode.h @@ -55,8 +55,8 @@ enum { TNT_ERRMSG_MAX = 512 }; /* 2 */_(ER_ILLEGAL_PARAMS, 2, "Illegal parameters, %s") \ /* 3 */_(ER_SECONDARY, 2, "Can't modify data upon a request on the secondary port.") \ /* 4 */_(ER_TUPLE_IS_RO, 1, "Tuple is marked as read-only") \ - /* 5 */_(ER_UNUSED5, 2, "Unused5") \ - /* 6 */_(ER_UNUSED6, 2, "Unused6") \ + /* 5 */_(ER_INDEX_TYPE, 2, "Unsupported index type: %s") \ + /* 6 */_(ER_SPACE_EXISTS, 2, "Space %u already exists") \ /* 7 */_(ER_MEMORY_ISSUE, 1, "Failed to allocate %u bytes in %s for %s") \ /* 8 */_(ER_UNUSED8, 2, "Unused8") \ /* 9 */_(ER_INJECTION, 2, "Error injection '%s'") \ diff --git a/src/box/CMakeLists.txt b/src/box/CMakeLists.txt index 9929d5be5da4db8974cc4bbc9ab34fc7c6ea7641..3df5f3144828eb5c131872b6036b960112d847e3 100644 --- a/src/box/CMakeLists.txt +++ b/src/box/CMakeLists.txt @@ -19,6 +19,7 @@ tarantool_module("box" tuple.cc tuple_convert.cc tuple_update.cc + key_def.cc index.cc hash_index.cc tree_index.cc diff --git a/src/box/box_lua.cc b/src/box/box_lua.cc index 761d0e5f17cc95291d33ed691ba04f7551117974..f0aff11d37146f08a7a18738f8d4ebded578556d 100644 --- a/src/box/box_lua.cc +++ b/src/box/box_lua.cc @@ -202,7 +202,7 @@ struct lua_field { uint32_t u32; uint64_t u64; }; - enum field_data_type type; + enum field_type type; }; /** diff --git a/src/box/index.cc b/src/box/index.cc index 9a7c212c5c6a254df8237dc12ce37e803ce5f976..323e200cd9334cb9ad86f4be18a54abcde2f5153 100644 --- a/src/box/index.cc +++ b/src/box/index.cc @@ -35,8 +35,6 @@ #include "exception.h" #include "space.h" -const char *field_data_type_strs[] = {"UNKNOWN", "NUM", "NUM64", "STR", "\0"}; -STRS(index_type, INDEX_TYPE); STRS(iterator_type, ITERATOR_TYPE); /* {{{ Utilities. **********************************************/ @@ -48,7 +46,7 @@ key_validate_parts(struct key_def *key_def, for (uint32_t part = 0; part < part_count; part++) { uint32_t part_size = load_varint32(&key); - enum field_data_type part_type = key_def->parts[part].type; + enum field_type part_type = key_def->parts[part].type; if (part_type == NUM && part_size != sizeof(uint32_t)) tnt_raise(ClientError, ER_KEY_FIELD_TYPE, "u32"); diff --git a/src/box/index.h b/src/box/index.h index bc60a10399d5ff59f16b6aa29a7dd55b49539116..646562b84fec215097c3133d372369cf5fe2f964 100644 --- a/src/box/index.h +++ b/src/box/index.h @@ -32,26 +32,11 @@ #include "tarantool/util.h" #include "object.h" +#include "key_def.h" struct tuple; struct space; -/* - * Possible field data types. Can't use STRS/ENUM macros for them, - * since there is a mismatch between enum name (STRING) and type - * name literal ("STR"). STR is already used as Objective C type. - */ -enum field_data_type { UNKNOWN = 0, NUM, NUM64, STRING, field_data_type_MAX }; -extern const char *field_data_type_strs[]; - -#define INDEX_TYPE(_) \ - _(HASH, 0) /* HASH Index */ \ - _(TREE, 1) /* TREE Index */ \ - _(BITSET, 2) /* BITSET Index */ \ - -ENUM(index_type, INDEX_TYPE); -extern const char *index_type_strs[]; - /** * @abstract Iterator type * Controls how to iterate over tuples in an index. @@ -99,37 +84,6 @@ struct iterator { void (*free)(struct iterator *); }; -/** Descriptor of a single part in a multipart key. */ -struct key_part { - uint32_t fieldno; - enum field_data_type type; -}; - -/* Descriptor of a multipart key. */ -struct key_def { - /* Description of parts of a multipart index. */ - struct key_part *parts; - /* - * An array holding field positions in 'parts' array. - * Imagine there is index[1] = { key_field[0].fieldno=5, - * key_field[1].fieldno=3 }. - * 'parts' array for such index contains data from - * key_field[0] and key_field[1] respectively. - * max_fieldno is 5, and cmp_order array holds offsets of - * field 3 and 5 in 'parts' array: -1, -1, 0, -1, 1. - */ - uint32_t *cmp_order; - /* The size of the 'parts' array. */ - uint32_t part_count; - /* - * The size of 'cmp_order' array (= max fieldno in 'parts' - * array). - */ - uint32_t max_fieldno; - bool is_unique; - enum index_type type; -}; - /** * Check that the key has correct part count and correct part size * for use in an index iterator. @@ -148,7 +102,7 @@ key_validate(struct key_def *key_def, enum iterator_type type, const char *key, * index (i.e. the key must be fully specified). */ void -primary_key_validate(struct key_def *key_deff, const char *key, +primary_key_validate(struct key_def *key_def, const char *key, uint32_t part_count); @@ -175,7 +129,6 @@ enum dup_replace_mode { DUP_REPLACE }; - class Index: public Object { public: diff --git a/src/box/key_def.cc b/src/box/key_def.cc new file mode 100644 index 0000000000000000000000000000000000000000..f668fb23dcaecd1299d6180ae280c321333256f0 --- /dev/null +++ b/src/box/key_def.cc @@ -0,0 +1,100 @@ +/* + * Redistribution and use in source and binary forms, with or + * without modification, are permitted provided that the following + * conditions are met: + * + * 1. Redistributions of source code must retain the above + * copyright notice, this list of conditions and the + * following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY <COPYRIGHT HOLDER> ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL + * <COPYRIGHT HOLDER> OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR + * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF + * THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ +#include "key_def.h" +extern "C" { +#include <cfg/tarantool_box_cfg.h> +} /* extern "C" */ +#include "exception.h" +#include <stddef.h> + +const char *field_type_strs[] = {"UNKNOWN", "NUM", "NUM64", "STR", "\0"}; +STRS(index_type, INDEX_TYPE); + +void +key_def_create(struct key_def *def, struct tarantool_cfg_space_index *cfg_index) +{ + def->max_fieldno = 0; + def->part_count = 0; + + def->type = STR2ENUM(index_type, cfg_index->type); + if (def->type == index_type_MAX) + tnt_raise(LoggedError, ER_INDEX_TYPE, cfg_index->type); + + /* Calculate key part count and maximal field number. */ + for (uint32_t k = 0; cfg_index->key_field[k] != NULL; ++k) { + auto cfg_key = cfg_index->key_field[k]; + + if (cfg_key->fieldno == -1) { + /* last filled key reached */ + break; + } + + def->max_fieldno = MAX(def->max_fieldno, cfg_key->fieldno); + def->part_count++; + } + + /* init def array */ + def->parts = (struct key_part *) malloc(sizeof(struct key_part) * + def->part_count); + + /* init compare order array */ + def->max_fieldno++; + def->cmp_order = (uint32_t *) malloc(def->max_fieldno * sizeof(uint32_t)); + + for (uint32_t fieldno = 0; fieldno < def->max_fieldno; fieldno++) { + def->cmp_order[fieldno] = UINT32_MAX; + } + + /* fill fields and compare order */ + for (uint32_t k = 0; cfg_index->key_field[k] != NULL; ++k) { + auto cfg_key = cfg_index->key_field[k]; + + if (cfg_key->fieldno == -1) { + /* last filled key reached */ + break; + } + + /* fill keys */ + def->parts[k].fieldno = cfg_key->fieldno; + def->parts[k].type = STR2ENUM(field_type, cfg_key->type); + /* fill compare order */ + if (def->cmp_order[cfg_key->fieldno] == UINT32_MAX) + def->cmp_order[cfg_key->fieldno] = k; + } + def->is_unique = cfg_index->unique; +} + +/** Free a key definition. */ +void +key_def_destroy(struct key_def *key_def) +{ + free(key_def->parts); + free(key_def->cmp_order); +} + diff --git a/src/box/key_def.h b/src/box/key_def.h new file mode 100644 index 0000000000000000000000000000000000000000..c25644ae393047d524c1a21b8c6be38353d94f54 --- /dev/null +++ b/src/box/key_def.h @@ -0,0 +1,87 @@ +#ifndef TARANTOOL_BOX_KEY_DEF_H_INCLUDED +#define TARANTOOL_BOX_KEY_DEF_H_INCLUDED +/* + * Redistribution and use in source and binary forms, with or + * without modification, are permitted provided that the following + * conditions are met: + * + * 1. Redistributions of source code must retain the above + * copyright notice, this list of conditions and the + * following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials + * provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY <COPYRIGHT HOLDER> ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED + * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL + * <COPYRIGHT HOLDER> OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, + * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR + * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF + * THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ +#include "tarantool/util.h" +/* + * Possible field data types. Can't use STRS/ENUM macros for them, + * since there is a mismatch between enum name (STRING) and type + * name literal ("STR"). STR is already used as Objective C type. + */ +enum field_type { UNKNOWN = 0, NUM, NUM64, STRING, field_type_MAX }; +extern const char *field_type_strs[]; + +#define INDEX_TYPE(_) \ + _(HASH, 0) /* HASH Index */ \ + _(TREE, 1) /* TREE Index */ \ + _(BITSET, 2) /* BITSET Index */ \ + +ENUM(index_type, INDEX_TYPE); +extern const char *index_type_strs[]; + +/** Descriptor of a single part in a multipart key. */ +struct key_part { + uint32_t fieldno; + enum field_type type; +}; + +/* Descriptor of a multipart key. */ +struct key_def { + /* Description of parts of a multipart index. */ + struct key_part *parts; + /* + * An array holding field positions in 'parts' array. + * Imagine there is index[1] = { key_field[0].fieldno=5, + * key_field[1].fieldno=3 }. + * 'parts' array for such index contains data from + * key_field[0] and key_field[1] respectively. + * max_fieldno is 5, and cmp_order array holds offsets of + * field 3 and 5 in 'parts' array: -1, -1, 0, -1, 1. + */ + uint32_t *cmp_order; + /* The size of the 'parts' array. */ + uint32_t part_count; + /* + * The size of 'cmp_order' array (= max fieldno in 'parts' + * array). + */ + uint32_t max_fieldno; + bool is_unique; + enum index_type type; +}; + +struct tarantool_cfg_space_index; + +void +key_def_create(struct key_def *def, struct tarantool_cfg_space_index *cfg_index); + +void +key_def_destroy(struct key_def *def); + +#endif /* TARANTOOL_BOX_KEY_DEF_H_INCLUDED */ diff --git a/src/box/space.cc b/src/box/space.cc index 19b739d220fd4c7f3496aca6406ba7783b872cc5..4d65ec45292fd5c7de968a95ddc0cae1cc75c5ed 100644 --- a/src/box/space.cc +++ b/src/box/space.cc @@ -117,14 +117,6 @@ space_set_index(struct space *sp, uint32_t index_no, Index *idx) sp->index[index_no] = idx; } -/** Free a key definition. */ -static void -key_free(struct key_def *key_def) -{ - free(key_def->parts); - free(key_def->cmp_order); -} - struct tuple * space_replace(struct space *sp, struct tuple *old_tuple, struct tuple *new_tuple, enum dup_replace_mode mode) @@ -213,7 +205,7 @@ space_free(void) for (uint32_t j = 0 ; j < space->key_count; j++) { Index *index = space->index[j]; delete index; - key_free(&space->key_defs[j]); + key_def_destroy(&space->key_defs[j]); } free(space->key_defs); @@ -223,65 +215,6 @@ space_free(void) } -static void -key_init(struct key_def *def, struct tarantool_cfg_space_index *cfg_index) -{ - def->max_fieldno = 0; - def->part_count = 0; - - def->type = STR2ENUM(index_type, cfg_index->type); - if (def->type == index_type_MAX) - panic("Wrong index type: %s", cfg_index->type); - - /* Calculate key part count and maximal field number. */ - for (uint32_t k = 0; cfg_index->key_field[k] != NULL; ++k) { - auto cfg_key = cfg_index->key_field[k]; - - if (cfg_key->fieldno == -1) { - /* last filled key reached */ - break; - } - - def->max_fieldno = MAX(def->max_fieldno, cfg_key->fieldno); - def->part_count++; - } - - /* init def array */ - def->parts = (struct key_part *) malloc(sizeof(struct key_part) * - def->part_count); - if (def->parts == NULL) { - panic("can't allocate def parts array for index"); - } - - /* init compare order array */ - def->max_fieldno++; - def->cmp_order = (uint32_t *) malloc(def->max_fieldno * sizeof(uint32_t)); - if (def->cmp_order == NULL) { - panic("can't allocate def cmp_order array for index"); - } - for (uint32_t fieldno = 0; fieldno < def->max_fieldno; fieldno++) { - def->cmp_order[fieldno] = BOX_FIELD_MAX; - } - - /* fill fields and compare order */ - for (uint32_t k = 0; cfg_index->key_field[k] != NULL; ++k) { - auto cfg_key = cfg_index->key_field[k]; - - if (cfg_key->fieldno == -1) { - /* last filled key reached */ - break; - } - - /* fill keys */ - def->parts[k].fieldno = cfg_key->fieldno; - def->parts[k].type = STR2ENUM(field_data_type, cfg_key->type); - /* fill compare order */ - if (def->cmp_order[cfg_key->fieldno] == BOX_FIELD_MAX) - def->cmp_order[cfg_key->fieldno] = k; - } - def->is_unique = cfg_index->unique; -} - /** * Extract all available field info from keys * @@ -304,8 +237,8 @@ space_init_field_types(struct space *space) /* alloc & init field type info */ space->max_fieldno = max_fieldno; - space->field_types = (enum field_data_type *) - calloc(max_fieldno, sizeof(enum field_data_type)); + space->field_types = (enum field_type *) + calloc(max_fieldno, sizeof(enum field_type)); /* extract field type info */ for (i = 0; i < key_count; i++) { @@ -329,6 +262,7 @@ space_init_field_types(struct space *space) #endif } + static void space_config() { @@ -373,7 +307,7 @@ space_config() } for (uint32_t j = 0; cfg_space->index[j] != NULL; ++j) { auto cfg_index = cfg_space->index[j]; - key_init(&space->key_defs[j], cfg_index); + key_def_create(&space->key_defs[j], cfg_index); } space_init_field_types(space); @@ -548,7 +482,7 @@ check_spaces(struct tarantool_cfg *conf) } /* key must has valid type */ - if (STR2ENUM(field_data_type, key->type) == field_data_type_MAX) { + if (STR2ENUM(field_type, key->type) == field_type_MAX) { out_warning(CNF_OK, "(space = %zu index = %zu) " "unknown field data type: `%s'", i, j, key->type); return -1; @@ -628,8 +562,8 @@ check_spaces(struct tarantool_cfg *conf) break; uint32_t f = key->fieldno; - enum field_data_type t = STR2ENUM(field_data_type, key->type); - assert(t != field_data_type_MAX); + enum field_type t = STR2ENUM(field_type, key->type); + assert(t != field_type_MAX); if (types[f] != t) { if (types[f] == UNKNOWN) { types[f] = t; diff --git a/src/box/space.h b/src/box/space.h index ec996baa95d21b8baa2a671e834b33d085d1a53e..730f42938a903f70c25d0b19a39f575a6f66186c 100644 --- a/src/box/space.h +++ b/src/box/space.h @@ -29,6 +29,7 @@ * SUCH DAMAGE. */ #include "index.h" +#include "key_def.h" #include <exception.h> #include <box/box.h> @@ -65,7 +66,7 @@ struct space { * XXX: right now UNKNOWN is also set for fields which types * in two indexes contradict each other. */ - enum field_data_type *field_types; + enum field_type *field_types; /** * Max field no which participates in any of the space indexes. @@ -232,7 +233,7 @@ space_max_fieldno(struct space *sp) return sp->max_fieldno; } -static inline enum field_data_type +static inline enum field_type space_field_type(struct space *sp, uint32_t no) { return sp->field_types[no]; diff --git a/src/box/tuple.cc b/src/box/tuple.cc index 126b3ba1e50f694dac21614b9fde3245cfe87bda..db711034283d1a8b4d59ee7bffd75d47cd5c8a17 100644 --- a/src/box/tuple.cc +++ b/src/box/tuple.cc @@ -31,7 +31,7 @@ #include <salloc.h> #include "tbuf.h" -#include "index.h" +#include "key_def.h" #include "tuple_update.h" #include <exception.h> #include <palloc.h> @@ -239,7 +239,7 @@ tuple_new(uint32_t field_count, const char **data, const char *end) static inline int tuple_compare_field(const char *field_a, uint32_t size_a, const char *field_b, uint32_t size_b, - enum field_data_type type) + enum field_type type) { /* * field_a is always a tuple field. diff --git a/test/box/lua_misc.result b/test/box/lua_misc.result index d931d1f6be428a68e8d13331a967c9874d199d82..e4a93593306388d349eb4c4dd1fdc46491e72695 100644 --- a/test/box/lua_misc.result +++ b/test/box/lua_misc.result @@ -105,25 +105,27 @@ box.error.ER_NONMASTER: 258 box.error.ER_PROC_RET: 12290 box.error.ER_TUPLE_IS_TOO_LONG: 11010 box.error.ER_EXACT_MATCH: 11522 -box.error.ER_SECONDARY: 770 +box.error.ER_FIELD_TYPE: 10242 +box.error.ER_PROC_LUA: 13058 +box.error.ER_TUPLE_FOUND: 14082 box.error.ER_OK: 0 -box.error.ER_NO_SUCH_INDEX: 13570 +box.error.ER_NO_SUCH_FIELD: 13826 box.error.ER_TUPLE_NOT_FOUND: 12546 box.error.ER_FIBER_STACK: 6658 -box.error.ER_UNKNOWN_UPDATE_OP: 11266 -box.error.ER_TUPLE_FOUND: 14082 +box.error.ER_SPLICE: 10754 +box.error.ER_NO_SUCH_INDEX: 13570 box.error.ER_UNSUPPORTED: 2562 box.error.ER_INJECTION: 2306 -box.error.ER_NO_SUCH_FIELD: 13826 -box.error.ER_TUPLE_IS_RO: 1025 +box.error.ER_SPACE_DISABLED: 13314 +box.error.ER_INDEX_TYPE: 1282 box.error.ER_ARG_TYPE: 10498 box.error.ER_NO_SUCH_SPACE: 14594 -box.error.ER_SPACE_DISABLED: 13314 -box.error.ER_PROC_LUA: 13058 +box.error.ER_UNKNOWN_UPDATE_OP: 11266 +box.error.ER_SPACE_EXISTS: 1538 box.error.ER_NO_SUCH_PROC: 12802 -box.error.ER_SPLICE: 10754 -box.error.ER_KEY_PART_COUNT: 12034 box.error.ER_WAL_IO: 9986 -box.error.ER_FIELD_TYPE: 10242 +box.error.ER_KEY_PART_COUNT: 12034 +box.error.ER_TUPLE_IS_RO: 1025 +box.error.ER_SECONDARY: 770 box.error.ER_MEMORY_ISSUE: 1793 ... diff --git a/test/lib/sql_ast.py b/test/lib/sql_ast.py index 6bf6e9f59938b4976efa0c2bca1ac35df8afc305..26b6d07e435dc3bd1bb1be0e508603902c5b3755 100644 --- a/test/lib/sql_ast.py +++ b/test/lib/sql_ast.py @@ -30,8 +30,8 @@ ER = { 2: "ER_ILLEGAL_PARAMS" , 3: "ER_SECONDARY" , 4: "ER_TUPLE_IS_RO" , - 5: "ER_UNUSED5" , - 6: "ER_UNUSED6" , + 5: "ER_INDEX_TYPE" , + 6: "ER_SPACE_EXISTS" , 7: "ER_MEMORY_ISSUE" , 8: "ER_UNUSED8" , 9: "ER_INJECTION" ,