From: imeevma@tarantool.org To: korablev@tarantool.org, tsafin@tarantool.org, tarantool-patches@dev.tarantool.org Subject: [Tarantool-patches] [PATCH v1 1/1] sql: specify field types in ephemeral space format Date: Sat, 11 Apr 2020 00:54:22 +0300 [thread overview] Message-ID: <c5fb9dd0fc114fe60184a653726c38a9e50c3c26.1586555569.git.imeevma@gmail.com> (raw) This patch allows to specify field types in ephemeral space format. Prior to this patch, all fields had a SCALAR field type. This patch allows us to not use the primary index to obtain field types, since now the ephemeral space has field types in the format. This allows us to change the structure of the primary index, which helps to solve the issue #4256. In addition, since we can now set the field types of the ephemeral space, we can use this feature to set the field types according to the left value of the IN operator. This will fix issue #4692. Needed for #4256 Needed for #4692 Closes #3841 --- https://github.com/tarantool/tarantool/issues/3841 https://github.com/tarantool/tarantool/tree/imeevma/gh-3841-format-for-ephemeral-space src/box/space_def.c | 5 ++--- src/box/space_def.h | 3 ++- src/box/sql.c | 52 +++++++++++++++++++++++++++++++++++--------------- src/box/tuple_format.c | 22 ++++++++++----------- 4 files changed, 51 insertions(+), 31 deletions(-) diff --git a/src/box/space_def.c b/src/box/space_def.c index 6611312..5af0f38 100644 --- a/src/box/space_def.c +++ b/src/box/space_def.c @@ -233,7 +233,7 @@ space_def_new(uint32_t id, uint32_t uid, uint32_t exact_field_count, } struct space_def* -space_def_new_ephemeral(uint32_t field_count) +space_def_new_ephemeral(uint32_t field_count, struct field_def *fields) { struct space_opts opts = space_opts_default; opts.is_temporary = true; @@ -242,8 +242,7 @@ space_def_new_ephemeral(uint32_t field_count) "ephemeral", strlen("ephemeral"), "memtx", strlen("memtx"), - &opts, &field_def_default, - 0); + &opts, fields, field_count); return space_def; } diff --git a/src/box/space_def.h b/src/box/space_def.h index ac6d226..61bbdb4 100644 --- a/src/box/space_def.h +++ b/src/box/space_def.h @@ -173,11 +173,12 @@ space_def_new(uint32_t id, uint32_t uid, uint32_t exact_field_count, /** * Create a new ephemeral space definition. * @param field_count Number of fields in the space. + * @param fields Field definitions. * * @retval Space definition. */ struct space_def * -space_def_new_ephemeral(uint32_t field_count); +space_def_new_ephemeral(uint32_t field_count, struct field_def *fields); /** * Size of the space_def. diff --git a/src/box/sql.c b/src/box/sql.c index 1256df8..e4434b2 100644 --- a/src/box/sql.c +++ b/src/box/sql.c @@ -330,13 +330,41 @@ sql_ephemeral_space_create(uint32_t field_count, struct sql_key_info *key_info) return NULL; } - struct key_part_def *ephemer_key_parts = region_alloc(&fiber()->gc, - sizeof(*ephemer_key_parts) * field_count); - if (ephemer_key_parts == NULL) { - diag_set(OutOfMemory, sizeof(*ephemer_key_parts) * field_count, - "region", "key parts"); - return NULL; + struct region *region = &fiber()->gc; + /* + * Name of the fields will be "_COLUMN_1", "_COLUMN_2" + * and so on. Since number of columns no more than 2000, + * length of each name is no more than strlen("_COLUMN_") + * + 5. + */ + assert(SQL_MAX_COLUMN <= 2000); + uint32_t name_len = strlen("_COLUMN_") + 5; + uint32_t size = field_count * (sizeof(struct field_def) + name_len + + sizeof(struct key_part_def)); + struct field_def *fields = region_alloc(region, size); + struct key_part_def *ephemer_key_parts = (void *)fields + + field_count * sizeof(struct field_def); + char *names = (char *)ephemer_key_parts + + field_count * sizeof(struct key_part_def); + for (uint32_t i = 0; i < field_count; ++i) { + struct field_def *field = &fields[i]; + field->name = names; + names += name_len; + sprintf(field->name, "_COLUMN_%d", i); + field->is_nullable = true; + field->nullable_action = ON_CONFLICT_ACTION_NONE; + field->default_value = NULL; + field->default_value_expr = NULL; + if (def != NULL && i < def->part_count) { + assert(def->parts[i].type < field_type_MAX); + field->type = def->parts[i].type; + field->coll_id = def->parts[i].coll_id; + } else { + field->coll_id = COLL_NONE; + field->type = FIELD_TYPE_SCALAR; + } } + for (uint32_t i = 0; i < field_count; ++i) { struct key_part_def *part = &ephemer_key_parts[i]; part->fieldno = i; @@ -344,14 +372,8 @@ sql_ephemeral_space_create(uint32_t field_count, struct sql_key_info *key_info) part->is_nullable = true; part->sort_order = SORT_ORDER_ASC; part->path = NULL; - if (def != NULL && i < def->part_count) { - assert(def->parts[i].type < field_type_MAX); - part->type = def->parts[i].type; - part->coll_id = def->parts[i].coll_id; - } else { - part->coll_id = COLL_NONE; - part->type = FIELD_TYPE_SCALAR; - } + part->type = fields[i].type; + part->coll_id = fields[i].coll_id; } struct key_def *ephemer_key_def = key_def_new(ephemer_key_parts, field_count, false); @@ -370,7 +392,7 @@ sql_ephemeral_space_create(uint32_t field_count, struct sql_key_info *key_info) rlist_add_entry(&key_list, ephemer_index_def, link); struct space_def *ephemer_space_def = - space_def_new_ephemeral(field_count); + space_def_new_ephemeral(field_count, fields); if (ephemer_space_def == NULL) { index_def_delete(ephemer_index_def); return NULL; diff --git a/src/box/tuple_format.c b/src/box/tuple_format.c index 312c966..beaeb0f 100644 --- a/src/box/tuple_format.c +++ b/src/box/tuple_format.c @@ -698,6 +698,12 @@ tuple_format_destroy(struct tuple_format *format) * dictionary will never be altered. If it can, then alter can * affect another space, which shares a format with one which is * altered. + * + * The only way to change the format of the space is to recreate + * space with the new format inside of BOX. Since there is no + * mechanism for recreating the ephemeral space, we need not worry + * about changing the format of the ephemeral space. + * * @param p_format Double pointer to format. It is updated with * hashed value, if corresponding format was found * in hash table @@ -709,13 +715,7 @@ static bool tuple_format_reuse(struct tuple_format **p_format) { struct tuple_format *format = *p_format; - if (!format->is_ephemeral) - return false; - /* - * These fields do not participate in hashing. - * Make sure they're unset. - */ - assert(format->dict->name_count == 0); + assert(format->is_ephemeral); assert(format->is_temporary); mh_int_t key = mh_tuple_format_find(tuple_formats_hash, format, NULL); @@ -739,9 +739,7 @@ tuple_format_reuse(struct tuple_format **p_format) static int tuple_format_add_to_hash(struct tuple_format *format) { - if(!format->is_ephemeral) - return 0; - assert(format->dict->name_count == 0); + assert(format->is_ephemeral); assert(format->is_temporary); mh_int_t key = mh_tuple_format_put(tuple_formats_hash, (const struct tuple_format **)&format, @@ -795,11 +793,11 @@ tuple_format_new(struct tuple_format_vtab *vtab, void *engine, if (tuple_format_create(format, keys, key_count, space_fields, space_field_count) < 0) goto err; - if (tuple_format_reuse(&format)) + if (is_ephemeral && tuple_format_reuse(&format)) return format; if (tuple_format_register(format) < 0) goto err; - if (tuple_format_add_to_hash(format) < 0) { + if (is_ephemeral && tuple_format_add_to_hash(format) < 0) { tuple_format_deregister(format); goto err; } -- 2.7.4
next reply other threads:[~2020-04-10 21:54 UTC|newest] Thread overview: 7+ messages / expand[flat|nested] mbox.gz Atom feed top 2020-04-10 21:54 imeevma [this message] -- strict thread matches above, loose matches on Subject: below -- 2020-04-02 10:41 imeevma 2020-04-03 13:00 ` Nikita Pettik 2020-04-04 18:34 ` Vladislav Shpilevoy 2020-04-10 0:04 ` Mergen Imeev 2020-04-10 19:16 ` Vladislav Shpilevoy 2020-04-10 21:52 ` Mergen Imeev
Reply instructions: You may reply publicly to this message via plain-text email using any one of the following methods: * Save the following mbox file, import it into your mail client, and reply-to-all from there: mbox Avoid top-posting and favor interleaved quoting: https://en.wikipedia.org/wiki/Posting_style#Interleaved_style * Reply using the --to, --cc, and --in-reply-to switches of git-send-email(1): git send-email \ --in-reply-to=c5fb9dd0fc114fe60184a653726c38a9e50c3c26.1586555569.git.imeevma@gmail.com \ --to=imeevma@tarantool.org \ --cc=korablev@tarantool.org \ --cc=tarantool-patches@dev.tarantool.org \ --cc=tsafin@tarantool.org \ --subject='Re: [Tarantool-patches] [PATCH v1 1/1] sql: specify field types in ephemeral space format' \ /path/to/YOUR_REPLY https://kernel.org/pub/software/scm/git/docs/git-send-email.html * If your mail client supports setting the In-Reply-To header via mailto: links, try the mailto: link
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox