diff --git a/src/box/alter.cc b/src/box/alter.cc index a6299a12e09fbaee56a29b4f29e02f4090d3180c..f08592e847e42597b33af318e46a97ce8f92a8df 100644 --- a/src/box/alter.cc +++ b/src/box/alter.cc @@ -339,31 +339,31 @@ index_def_new_from_tuple(struct tuple *tuple, struct space *space) } identifier_check_xc(name, name_len); struct key_def *key_def = NULL; - struct key_part_def *part_def = (struct key_part_def *) - malloc(sizeof(*part_def) * part_count); - if (part_def == NULL) { - tnt_raise(OutOfMemory, sizeof(*part_def) * part_count, - "malloc", "key_part_def"); + struct key_part *part = (struct key_part *) + malloc(sizeof(*part) * part_count); + if (part == NULL) { + tnt_raise(OutOfMemory, sizeof(*part) * part_count, + "malloc", "key_part"); } auto key_def_guard = make_scoped_guard([&] { - free(part_def); + free(part); if (key_def != NULL) key_def_delete(key_def); }); if (is_166plus) { /* 1.6.6+ */ - if (key_def_decode_parts(part_def, part_count, &parts, + if (key_def_decode_parts(part, part_count, &parts, space->def->fields, space->def->field_count) != 0) diag_raise(); } else { /* 1.6.5- TODO: remove it in newer versions, find all 1.6.5- */ - if (key_def_decode_parts_160(part_def, part_count, &parts, + if (key_def_decode_parts_160(part, part_count, &parts, space->def->fields, space->def->field_count) != 0) diag_raise(); } - key_def = key_def_new_with_parts(part_def, part_count); + key_def = key_def_new_with_parts(part, part_count); if (key_def == NULL) diag_raise(); struct index_def *index_def = diff --git a/src/box/key_def.c b/src/box/key_def.c index e8a6fa44186c28ee858008e46d10b7aa400b2469..c7f28e249c1d31b49a05067e5abc003ab837c9e9 100644 --- a/src/box/key_def.c +++ b/src/box/key_def.c @@ -36,10 +36,11 @@ #include "schema_def.h" #include "coll_id_cache.h" -static const struct key_part_def key_part_def_default = { +static const struct key_part key_part_default = { 0, field_type_MAX, COLL_NONE, + NULL, false, }; @@ -54,13 +55,12 @@ part_type_by_name_wrapper(const char *str, uint32_t len) #define PART_OPT_COLLATION "collation" #define PART_OPT_NULLABILITY "is_nullable" -const struct opt_def part_def_reg[] = { - OPT_DEF_ENUM(PART_OPT_TYPE, field_type, struct key_part_def, type, +const struct opt_def key_part_reg[] = { + OPT_DEF_ENUM(PART_OPT_TYPE, field_type, struct key_part, type, part_type_by_name_wrapper), - OPT_DEF(PART_OPT_FIELD, OPT_UINT32, struct key_part_def, fieldno), - OPT_DEF(PART_OPT_COLLATION, OPT_UINT32, struct key_part_def, coll_id), - OPT_DEF(PART_OPT_NULLABILITY, OPT_BOOL, struct key_part_def, - is_nullable), + OPT_DEF(PART_OPT_FIELD, OPT_UINT32, struct key_part, fieldno), + OPT_DEF(PART_OPT_COLLATION, OPT_UINT32, struct key_part, coll_id), + OPT_DEF(PART_OPT_NULLABILITY, OPT_BOOL, struct key_part, is_nullable), OPT_END, }; @@ -146,14 +146,14 @@ key_def_new(uint32_t part_count) } struct key_def * -key_def_new_with_parts(struct key_part_def *parts, uint32_t part_count) +key_def_new_with_parts(const struct key_part *parts, uint32_t part_count) { struct key_def *def = key_def_new(part_count); if (def == NULL) return NULL; for (uint32_t i = 0; i < part_count; i++) { - struct key_part_def *part = &parts[i]; + const struct key_part *part = &parts[i]; struct coll *coll = NULL; if (part->coll_id != COLL_NONE) { struct coll_id *coll_id = coll_by_id(part->coll_id); @@ -172,15 +172,16 @@ key_def_new_with_parts(struct key_part_def *parts, uint32_t part_count) } void -key_def_dump_parts(const struct key_def *def, struct key_part_def *parts) +key_def_dump_parts(const struct key_def *def, struct key_part *parts) { for (uint32_t i = 0; i < def->part_count; i++) { - const struct key_part *part = &def->parts[i]; - struct key_part_def *part_def = &parts[i]; - part_def->fieldno = part->fieldno; - part_def->type = part->type; - part_def->is_nullable = part->is_nullable; - part_def->coll_id = part->coll_id; + const struct key_part *src = &def->parts[i]; + struct key_part *dest = &parts[i]; + *dest = key_part_default; + dest->fieldno = src->fieldno; + dest->type = src->type; + dest->is_nullable = src->is_nullable; + dest->coll_id = src->coll_id; } } @@ -194,8 +195,7 @@ box_key_def_new(uint32_t *fields, uint32_t *types, uint32_t part_count) for (uint32_t item = 0; item < part_count; ++item) { key_def_set_part(key_def, item, fields[item], (enum field_type)types[item], - key_part_def_default.is_nullable, NULL, - COLL_NONE); + false, NULL, COLL_NONE); } return key_def; } @@ -294,13 +294,13 @@ key_def_update_optionality(struct key_def *def, uint32_t min_field_count) } int -key_def_snprint_parts(char *buf, int size, const struct key_part_def *parts, +key_def_snprint_parts(char *buf, int size, const struct key_part *parts, uint32_t part_count) { int total = 0; SNPRINT(total, snprintf, buf, size, "["); for (uint32_t i = 0; i < part_count; i++) { - const struct key_part_def *part = &parts[i]; + const struct key_part *part = &parts[i]; assert(part->type < field_type_MAX); SNPRINT(total, snprintf, buf, size, "%d, '%s'", (int)part->fieldno, field_type_strs[part->type]); @@ -312,11 +312,11 @@ key_def_snprint_parts(char *buf, int size, const struct key_part_def *parts, } size_t -key_def_sizeof_parts(const struct key_part_def *parts, uint32_t part_count) +key_def_sizeof_parts(const struct key_part *parts, uint32_t part_count) { size_t size = 0; for (uint32_t i = 0; i < part_count; i++) { - const struct key_part_def *part = &parts[i]; + const struct key_part *part = &parts[i]; int count = 2; if (part->coll_id != COLL_NONE) count++; @@ -341,11 +341,11 @@ key_def_sizeof_parts(const struct key_part_def *parts, uint32_t part_count) } char * -key_def_encode_parts(char *data, const struct key_part_def *parts, +key_def_encode_parts(char *data, const struct key_part *parts, uint32_t part_count) { for (uint32_t i = 0; i < part_count; i++) { - const struct key_part_def *part = &parts[i]; + const struct key_part *part = &parts[i]; int count = 2; if (part->coll_id != COLL_NONE) count++; @@ -383,12 +383,12 @@ key_def_encode_parts(char *data, const struct key_part_def *parts, * [NUM, STR, ..][NUM, STR, ..].., */ static int -key_def_decode_parts_166(struct key_part_def *parts, uint32_t part_count, +key_def_decode_parts_166(struct key_part *parts, uint32_t part_count, const char **data, const struct field_def *fields, uint32_t field_count) { for (uint32_t i = 0; i < part_count; i++) { - struct key_part_def *part = &parts[i]; + struct key_part *part = &parts[i]; if (mp_typeof(**data) != MP_ARRAY) { diag_set(ClientError, ER_WRONG_INDEX_PARTS, "expected an array"); @@ -410,6 +410,7 @@ key_def_decode_parts_166(struct key_part_def *parts, uint32_t part_count, "field id must be an integer"); return -1; } + *part = key_part_default; part->fieldno = (uint32_t) mp_decode_uint(data); if (mp_typeof(**data) != MP_STR) { diag_set(ClientError, ER_WRONG_INDEX_PARTS, @@ -426,16 +427,14 @@ key_def_decode_parts_166(struct key_part_def *parts, uint32_t part_count, "unknown field type"); return -1; } - part->is_nullable = (part->fieldno < field_count ? - fields[part->fieldno].is_nullable : - key_part_def_default.is_nullable); - part->coll_id = COLL_NONE; + if (part->fieldno < field_count) + part->is_nullable = fields[part->fieldno].is_nullable; } return 0; } int -key_def_decode_parts(struct key_part_def *parts, uint32_t part_count, +key_def_decode_parts(struct key_part *parts, uint32_t part_count, const char **data, const struct field_def *fields, uint32_t field_count) { @@ -444,15 +443,15 @@ key_def_decode_parts(struct key_part_def *parts, uint32_t part_count, fields, field_count); } for (uint32_t i = 0; i < part_count; i++) { - struct key_part_def *part = &parts[i]; + struct key_part *part = &parts[i]; if (mp_typeof(**data) != MP_MAP) { diag_set(ClientError, ER_WRONG_INDEX_OPTIONS, i + TUPLE_INDEX_BASE, "index part is expected to be a map"); return -1; } - *part = key_part_def_default; - if (opts_decode(part, part_def_reg, data, + *part = key_part_default; + if (opts_decode(part, key_part_reg, data, ER_WRONG_INDEX_OPTIONS, i + TUPLE_INDEX_BASE, NULL) != 0) return -1; @@ -476,12 +475,13 @@ key_def_decode_parts(struct key_part_def *parts, uint32_t part_count, } int -key_def_decode_parts_160(struct key_part_def *parts, uint32_t part_count, +key_def_decode_parts_160(struct key_part *parts, uint32_t part_count, const char **data, const struct field_def *fields, uint32_t field_count) { for (uint32_t i = 0; i < part_count; i++) { - struct key_part_def *part = &parts[i]; + struct key_part *part = &parts[i]; + *part = key_part_default; part->fieldno = (uint32_t) mp_decode_uint(data); uint32_t len; const char *str = mp_decode_str(data, &len); @@ -491,10 +491,8 @@ key_def_decode_parts_160(struct key_part_def *parts, uint32_t part_count, "unknown field type"); return -1; } - part->is_nullable = (part->fieldno < field_count ? - fields[part->fieldno].is_nullable : - key_part_def_default.is_nullable); - part->coll_id = COLL_NONE; + if (part->fieldno < field_count) + part->is_nullable = fields[part->fieldno].is_nullable; } return 0; } diff --git a/src/box/key_def.h b/src/box/key_def.h index 6cc705b8287084190c49d558caee64ac92088c22..eb891143eabe3085dcaf365de4a8d185e7b9a3b0 100644 --- a/src/box/key_def.h +++ b/src/box/key_def.h @@ -45,19 +45,8 @@ extern "C" { /* MsgPack type names */ extern const char *mp_type_strs[]; -struct key_part_def { - /** Tuple field index for this part. */ - uint32_t fieldno; - /** Type of the tuple field. */ - enum field_type type; - /** Collation ID for string comparison. */ - uint32_t coll_id; - /** True if a key part can store NULLs. */ - bool is_nullable; -}; - /** - * Set key_part_def.coll_id to COLL_NONE if + * Set key_part.coll_id to COLL_NONE if * the field does not have a collation. */ #define COLL_NONE UINT32_MAX @@ -70,7 +59,16 @@ struct key_part { enum field_type type; /** Collation ID for string comparison. */ uint32_t coll_id; - /** Collation definition for string comparison */ + /** + * Pointer to the collation corresponding to @coll_id. + * + * The only purpose of this pointer is to avoid collation + * lookup on tuple comparison. So it is only set if the + * part is used for tuple comparisons, i.e. attached to a + * key_def. If the part is needed just to store a decoded + * key part definition, it will be set to NULL, because + * the collation with the given id may not exist. + */ struct coll *coll; /** True if a part can store NULLs. */ bool is_nullable; @@ -237,13 +235,13 @@ key_def_new(uint32_t part_count); * and initialize its parts. */ struct key_def * -key_def_new_with_parts(struct key_part_def *parts, uint32_t part_count); +key_def_new_with_parts(const struct key_part *parts, uint32_t part_count); /** * Dump part definitions of the given key def. */ void -key_def_dump_parts(const struct key_def *def, struct key_part_def *parts); +key_def_dump_parts(const struct key_def *def, struct key_part *parts); /** * Set a single key part in a key def. @@ -268,7 +266,7 @@ key_def_update_optionality(struct key_def *def, uint32_t min_field_count); * An snprint-style function to print a key definition. */ int -key_def_snprint_parts(char *buf, int size, const struct key_part_def *parts, +key_def_snprint_parts(char *buf, int size, const struct key_part *parts, uint32_t part_count); /** @@ -276,14 +274,14 @@ key_def_snprint_parts(char *buf, int size, const struct key_part_def *parts, * See also key_def_encode_parts(). */ size_t -key_def_sizeof_parts(const struct key_part_def *parts, uint32_t part_count); +key_def_sizeof_parts(const struct key_part *parts, uint32_t part_count); /** * Encode key parts array in MsgPack and return a pointer following * the end of encoded data. */ char * -key_def_encode_parts(char *data, const struct key_part_def *parts, +key_def_encode_parts(char *data, const struct key_part *parts, uint32_t part_count); /** @@ -297,7 +295,7 @@ key_def_encode_parts(char *data, const struct key_part_def *parts, * {field=NUM, type=STR, ..}{field=NUM, type=STR, ..}.., */ int -key_def_decode_parts(struct key_part_def *parts, uint32_t part_count, +key_def_decode_parts(struct key_part *parts, uint32_t part_count, const char **data, const struct field_def *fields, uint32_t field_count); @@ -310,7 +308,7 @@ key_def_decode_parts(struct key_part_def *parts, uint32_t part_count, * NUM, STR, NUM, STR, .., */ int -key_def_decode_parts_160(struct key_part_def *parts, uint32_t part_count, +key_def_decode_parts_160(struct key_part *parts, uint32_t part_count, const char **data, const struct field_def *fields, uint32_t field_count); diff --git a/src/box/vy_log.c b/src/box/vy_log.c index fc8ede598dfed2f52e8367befd8817b0b7f758d4..5dbb7a3a007ac29d8285318d5cc860a31cce3759 100644 --- a/src/box/vy_log.c +++ b/src/box/vy_log.c @@ -588,12 +588,12 @@ vy_log_record_decode(struct vy_log_record *record, break; case VY_LOG_KEY_DEF: { uint32_t part_count = mp_decode_array(&pos); - struct key_part_def *parts = region_alloc(&fiber()->gc, + struct key_part *parts = region_alloc(&fiber()->gc, sizeof(*parts) * part_count); if (parts == NULL) { diag_set(OutOfMemory, sizeof(*parts) * part_count, - "region", "struct key_part_def"); + "region", "struct key_part"); return -1; } if (key_def_decode_parts(parts, part_count, &pos, @@ -704,11 +704,11 @@ vy_log_record_dup(struct region *pool, const struct vy_log_record *src) } if (src->key_def != NULL) { size_t size = src->key_def->part_count * - sizeof(struct key_part_def); + sizeof(struct key_part); dst->key_parts = region_alloc(pool, size); if (dst->key_parts == NULL) { diag_set(OutOfMemory, size, "region", - "struct key_part_def"); + "struct key_part"); goto err; } key_def_dump_parts(src->key_def, dst->key_parts); @@ -1281,7 +1281,7 @@ static struct vy_lsm_recovery_info * vy_recovery_do_create_lsm(struct vy_recovery *recovery, int64_t id, uint32_t space_id, uint32_t index_id, uint32_t group_id, - const struct key_part_def *key_parts, + const struct key_part *key_parts, uint32_t key_part_count) { if (key_parts == NULL) { @@ -1299,7 +1299,7 @@ vy_recovery_do_create_lsm(struct vy_recovery *recovery, int64_t id, lsm->key_parts = malloc(sizeof(*key_parts) * key_part_count); if (lsm->key_parts == NULL) { diag_set(OutOfMemory, sizeof(*key_parts) * key_part_count, - "malloc", "struct key_part_def"); + "malloc", "struct key_part"); free(lsm); return NULL; } @@ -1359,7 +1359,7 @@ static int vy_recovery_prepare_lsm(struct vy_recovery *recovery, int64_t id, uint32_t space_id, uint32_t index_id, uint32_t group_id, - const struct key_part_def *key_parts, + const struct key_part *key_parts, uint32_t key_part_count) { if (vy_recovery_lookup_lsm(recovery, id) != NULL) { @@ -1387,7 +1387,7 @@ vy_recovery_prepare_lsm(struct vy_recovery *recovery, int64_t id, static int vy_recovery_create_lsm(struct vy_recovery *recovery, int64_t id, uint32_t space_id, uint32_t index_id, uint32_t group_id, - const struct key_part_def *key_parts, + const struct key_part *key_parts, uint32_t key_part_count, int64_t create_lsn, int64_t modify_lsn, int64_t dump_lsn) { @@ -1426,7 +1426,7 @@ vy_recovery_create_lsm(struct vy_recovery *recovery, int64_t id, */ static int vy_recovery_modify_lsm(struct vy_recovery *recovery, int64_t id, - const struct key_part_def *key_parts, + const struct key_part *key_parts, uint32_t key_part_count, int64_t modify_lsn) { struct vy_lsm_recovery_info *lsm; @@ -1447,7 +1447,7 @@ vy_recovery_modify_lsm(struct vy_recovery *recovery, int64_t id, lsm->key_parts = malloc(sizeof(*key_parts) * key_part_count); if (lsm->key_parts == NULL) { diag_set(OutOfMemory, sizeof(*key_parts) * key_part_count, - "malloc", "struct key_part_def"); + "malloc", "struct key_part"); return -1; } memcpy(lsm->key_parts, key_parts, sizeof(*key_parts) * key_part_count); diff --git a/src/box/vy_log.h b/src/box/vy_log.h index 7718d9c689d7a753c41c5dc36246d0d4a0301a18..eeb345969eb31cd20eb065c169aafe52dc63cb95 100644 --- a/src/box/vy_log.h +++ b/src/box/vy_log.h @@ -58,7 +58,7 @@ extern "C" { struct xlog; struct vclock; struct key_def; -struct key_part_def; +struct key_part; struct mh_i64ptr_t; /** Type of a metadata log record. */ @@ -252,7 +252,7 @@ struct vy_log_record { /** Index key definition, as defined by the user. */ const struct key_def *key_def; /** Array of key part definitions. */ - struct key_part_def *key_parts; + struct key_part *key_parts; /** Number of key parts. */ uint32_t key_part_count; /** LSN of the WAL row that created the LSM tree. */ @@ -318,7 +318,7 @@ struct vy_lsm_recovery_info { /** Replication group ID. */ uint32_t group_id; /** Array of key part definitions. */ - struct key_part_def *key_parts; + struct key_part *key_parts; /** Number of key parts. */ uint32_t key_part_count; /**