From: Vladislav Shpilevoy <v.shpilevoy@tarantool.org>
To: tarantool-patches@freelists.org
Cc: vdavydov.dev@gmail.com
Subject: [PATCH 3/8] Add 'exact_field_count' parameter to options decoder
Date: Wed, 8 Aug 2018 01:03:46 +0300 [thread overview]
Message-ID: <eb2fd1e6f6c7bc44310014ce6277bb926e7e0fe2.1533679264.git.v.shpilevoy@tarantool.org> (raw)
In-Reply-To: <cover.1533679264.git.v.shpilevoy@tarantool.org>
In-Reply-To: <cover.1533679264.git.v.shpilevoy@tarantool.org>
Needed for promotion. Promotion uses system space
_promotion, into which a user can write tuples directly
with not API usage (and we can not do anything with it),
so _promotion should do severe validation of each field
of each tuple since it affects the cluster state.
For this a new parameter of options decoder is introduced,
that checks for exact field count.
Needed for #3055
---
src/box/alter.cc | 10 +++++-----
src/box/key_def.c | 2 +-
src/box/opt_def.c | 13 ++++++++-----
src/box/opt_def.h | 16 +++++++++++++++-
4 files changed, 29 insertions(+), 12 deletions(-)
diff --git a/src/box/alter.cc b/src/box/alter.cc
index 3007a131d..d13ecb783 100644
--- a/src/box/alter.cc
+++ b/src/box/alter.cc
@@ -239,7 +239,7 @@ index_opts_decode(struct index_opts *opts, const char *map)
{
index_opts_create(opts);
if (opts_decode(opts, index_opts_reg, &map, ER_WRONG_INDEX_OPTIONS,
- BOX_INDEX_FIELD_OPTS, NULL) != 0)
+ BOX_INDEX_FIELD_OPTS, NULL, 0) != 0)
diag_raise();
if (opts->distance == rtree_index_distance_type_MAX) {
tnt_raise(ClientError, ER_WRONG_INDEX_OPTIONS,
@@ -403,8 +403,8 @@ space_opts_decode(struct space_opts *opts, const char *data)
flags++;
}
} else if (opts_decode(opts, space_opts_reg, &data,
- ER_WRONG_SPACE_OPTIONS,
- BOX_SPACE_FIELD_OPTS, NULL) != 0) {
+ ER_WRONG_SPACE_OPTIONS, BOX_SPACE_FIELD_OPTS,
+ NULL, 0) != 0) {
diag_raise();
}
}
@@ -2382,8 +2382,8 @@ coll_id_def_new_from_tuple(const struct tuple *tuple, struct coll_id_def *def)
assert(base->type == COLL_TYPE_ICU);
if (opts_decode(&base->icu, coll_icu_opts_reg, &options,
- ER_WRONG_COLLATION_OPTIONS,
- BOX_COLLATION_FIELD_OPTIONS, NULL) != 0)
+ ER_WRONG_COLLATION_OPTIONS, BOX_COLLATION_FIELD_OPTIONS,
+ NULL, 0) != 0)
diag_raise();
if (base->icu.french_collation == coll_icu_on_off_MAX) {
diff --git a/src/box/key_def.c b/src/box/key_def.c
index ee09dc99d..bc0c1ba35 100644
--- a/src/box/key_def.c
+++ b/src/box/key_def.c
@@ -454,7 +454,7 @@ key_def_decode_parts(struct key_part_def *parts, uint32_t part_count,
*part = key_part_def_default;
if (opts_decode(part, part_def_reg, data,
ER_WRONG_INDEX_OPTIONS, i + TUPLE_INDEX_BASE,
- NULL) != 0)
+ NULL, 0) != 0)
return -1;
if (part->type == field_type_MAX) {
diag_set(ClientError, ER_WRONG_INDEX_OPTIONS,
diff --git a/src/box/opt_def.c b/src/box/opt_def.c
index cd93c23b8..6710f8187 100644
--- a/src/box/opt_def.c
+++ b/src/box/opt_def.c
@@ -176,13 +176,10 @@ opts_parse_key(void *opts, const struct opt_def *reg, const char *key,
return 0;
}
-/**
- * Populate key options from their msgpack-encoded representation
- * (msgpack map).
- */
int
opts_decode(void *opts, const struct opt_def *reg, const char **map,
- uint32_t errcode, uint32_t field_no, struct region *region)
+ uint32_t errcode, uint32_t field_no, struct region *region,
+ uint32_t exact_field_count)
{
assert(mp_typeof(**map) == MP_MAP);
@@ -191,6 +188,12 @@ opts_decode(void *opts, const struct opt_def *reg, const char **map,
* DDL is not performance-critical, so this is not a problem.
*/
uint32_t map_size = mp_decode_map(map);
+ if (map_size != exact_field_count && exact_field_count != 0) {
+ diag_set(ClientError, errcode, field_no,
+ tt_sprintf("expected %u keys but got %u",
+ exact_field_count, map_size));
+ return -1;
+ }
for (uint32_t i = 0; i < map_size; i++) {
if (mp_typeof(**map) != MP_STR) {
diag_set(ClientError, errcode, field_no,
diff --git a/src/box/opt_def.h b/src/box/opt_def.h
index 633832af9..4cfebf62a 100644
--- a/src/box/opt_def.h
+++ b/src/box/opt_def.h
@@ -83,10 +83,24 @@ struct region;
/**
* Populate key options from their msgpack-encoded representation
* (msgpack map).
+ * @param[out] opts Where decode options to.
+ * @param reg Field definitions array.
+ * @param map MessagePack to decode.
+ * @param errcode Error code to set on any error. The error code
+ * has to accept field number and description as
+ * parameters.
+ * @param field_no Field number to set for @a errcode.
+ * @param region Region for dynamic allocations such as strings.
+ * @param exact_field_count If non-zero, then @a map should
+ * contain exactly this count of fields.
+ *
+ * @retval 0 Success.
+ * @retval -1 Error.
*/
int
opts_decode(void *opts, const struct opt_def *reg, const char **map,
- uint32_t errcode, uint32_t field_no, struct region *region);
+ uint32_t errcode, uint32_t field_no, struct region *region,
+ uint32_t exact_field_count);
/**
* Decode one option and store it into @a opts struct as a field.
--
2.15.2 (Apple Git-101.1)
next prev parent reply other threads:[~2018-08-07 22:03 UTC|newest]
Thread overview: 13+ messages / expand[flat|nested] mbox.gz Atom feed top
2018-08-07 22:03 [PATCH 0/8] box.ctl.promote Vladislav Shpilevoy
2018-08-07 22:03 ` [PATCH 1/8] rfc: describe box.ctl.promote protocol Vladislav Shpilevoy
2018-08-07 22:03 ` [PATCH 2/8] box: rename process_rw to process_dml Vladislav Shpilevoy
2018-08-13 8:20 ` Vladimir Davydov
2018-08-07 22:03 ` Vladislav Shpilevoy [this message]
2018-08-13 8:30 ` [PATCH 3/8] Add 'exact_field_count' parameter to options decoder Vladimir Davydov
2018-08-07 22:03 ` [PATCH 4/8] box: remove orphan check from box_is_ro() Vladislav Shpilevoy
2018-08-13 8:34 ` Vladimir Davydov
2018-08-07 22:03 ` [PATCH 5/8] Fix gcov on Mac Vladislav Shpilevoy
2018-08-07 22:03 ` [PATCH 6/8] box: introduce _promotion space Vladislav Shpilevoy
2018-08-07 22:03 ` [PATCH 7/8] box: introduce box.ctl.promote Vladislav Shpilevoy
2018-08-13 8:58 ` Vladimir Davydov
2018-08-07 22:03 ` [PATCH 8/8] box: introduce promotion GC Vladislav Shpilevoy
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=eb2fd1e6f6c7bc44310014ce6277bb926e7e0fe2.1533679264.git.v.shpilevoy@tarantool.org \
--to=v.shpilevoy@tarantool.org \
--cc=tarantool-patches@freelists.org \
--cc=vdavydov.dev@gmail.com \
--subject='Re: [PATCH 3/8] Add '\''exact_field_count'\'' parameter to options decoder' \
/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