From: Kirill Shcherbatov <kshcherbatov@tarantool.org> To: tarantool-patches@freelists.org, vdavydov.dev@gmail.com Cc: Kirill Shcherbatov <kshcherbatov@tarantool.org> Subject: [PATCH v2 3/5] box: refactor key_validate_parts to return key_end Date: Mon, 24 Jun 2019 17:27:02 +0300 [thread overview] Message-ID: <139210ab31590bb7827e8f9c1791d131b88babd7.1561384554.git.kshcherbatov@tarantool.org> (raw) In-Reply-To: <cover.1561384554.git.kshcherbatov@tarantool.org> The key_validate_parts helper is refactored to return a pointer to the end of a given key argument in case of success. This is required to effectively validate a sequence of keys in scope of functional multikey indexes. Needed for #1260 --- src/box/index.cc | 10 ++++++---- src/box/index.h | 3 ++- src/box/key_def.c | 4 +++- src/box/key_def.h | 4 +++- src/box/lua/key_def.c | 5 +++-- src/box/memtx_space.c | 10 ++++++---- src/box/space.c | 4 ++-- src/box/sysview.c | 4 +++- src/box/vinyl.c | 4 +++- 9 files changed, 31 insertions(+), 17 deletions(-) diff --git a/src/box/index.cc b/src/box/index.cc index 4a444e5d0..b5419cc70 100644 --- a/src/box/index.cc +++ b/src/box/index.cc @@ -126,8 +126,9 @@ key_validate(const struct index_def *index_def, enum iterator_type type, part_count); return -1; } + const char *key_end; if (key_validate_parts(index_def->key_def, key, - part_count, true) != 0) + part_count, true, &key_end) != 0) return -1; } return 0; @@ -135,7 +136,7 @@ key_validate(const struct index_def *index_def, enum iterator_type type, int exact_key_validate(struct key_def *key_def, const char *key, - uint32_t part_count) + uint32_t part_count, const char **key_end) { assert(key != NULL || part_count == 0); if (key_def->part_count != part_count) { @@ -143,7 +144,7 @@ exact_key_validate(struct key_def *key_def, const char *key, part_count); return -1; } - return key_validate_parts(key_def, key, part_count, false); + return key_validate_parts(key_def, key, part_count, false, key_end); } char * @@ -233,7 +234,8 @@ box_index_get(uint32_t space_id, uint32_t index_id, const char *key, return -1; } uint32_t part_count = mp_decode_array(&key); - if (exact_key_validate(index->def->key_def, key, part_count)) + if (exact_key_validate(index->def->key_def, key, part_count, + &key_end)) return -1; /* Start transaction in the engine. */ struct txn *txn; diff --git a/src/box/index.h b/src/box/index.h index 97d600c96..0d7ddc16a 100644 --- a/src/box/index.h +++ b/src/box/index.h @@ -319,12 +319,13 @@ key_validate(const struct index_def *index_def, enum iterator_type type, /** * Check that the supplied key is valid for a search in a unique * index (i.e. the key must be fully specified). + * Update the pointer key_end to the end of the validated key. * @retval 0 The key is valid. * @retval -1 The key is invalid. */ int exact_key_validate(struct key_def *key_def, const char *key, - uint32_t part_count); + uint32_t part_count, const char **key_end); /** * The manner in which replace in a unique index must treat diff --git a/src/box/key_def.c b/src/box/key_def.c index 2aa095091..ee758eefa 100644 --- a/src/box/key_def.c +++ b/src/box/key_def.c @@ -834,7 +834,8 @@ out: int key_validate_parts(const struct key_def *key_def, const char *key, - uint32_t part_count, bool allow_nullable) + uint32_t part_count, bool allow_nullable, + const char **key_end) { for (uint32_t i = 0; i < part_count; i++) { const struct key_part *part = &key_def->parts[i]; @@ -844,5 +845,6 @@ key_validate_parts(const struct key_def *key_def, const char *key, return -1; mp_next(&key); } + *key_end = key; return 0; } diff --git a/src/box/key_def.h b/src/box/key_def.h index ab4b7c087..df83d055c 100644 --- a/src/box/key_def.h +++ b/src/box/key_def.h @@ -443,13 +443,15 @@ key_def_find_pk_in_cmp_def(const struct key_def *cmp_def, * @param key MessagePack'ed data for matching. * @param part_count Field count in the key. * @param allow_nullable True if nullable parts are allowed. + * @param key_end[out] The end of the validated key. * * @retval 0 The key is valid. * @retval -1 The key is invalid. */ int key_validate_parts(const struct key_def *key_def, const char *key, - uint32_t part_count, bool allow_nullable); + uint32_t part_count, bool allow_nullable, + const char **key_end); /** * Return true if @a index_def defines a sequential key without diff --git a/src/box/lua/key_def.c b/src/box/lua/key_def.c index dfcc89442..810ce5375 100644 --- a/src/box/lua/key_def.c +++ b/src/box/lua/key_def.c @@ -337,9 +337,10 @@ lbox_key_def_compare_with_key(struct lua_State *L) struct region *region = &fiber()->gc; size_t region_svp = region_used(region); size_t key_len; - const char *key = lbox_encode_tuple_on_gc(L, 3, &key_len); + const char *key_end, *key = lbox_encode_tuple_on_gc(L, 3, &key_len); uint32_t part_count = mp_decode_array(&key); - if (key_validate_parts(key_def, key, part_count, true) != 0) { + if (key_validate_parts(key_def, key, part_count, true, + &key_end) != 0) { region_truncate(region, region_svp); tuple_unref(tuple); return luaT_error(L); diff --git a/src/box/memtx_space.c b/src/box/memtx_space.c index 01091dcdc..15492a09f 100644 --- a/src/box/memtx_space.c +++ b/src/box/memtx_space.c @@ -376,9 +376,10 @@ memtx_space_execute_delete(struct space *space, struct txn *txn, struct index *pk = index_find_unique(space, request->index_id); if (pk == NULL) return -1; - const char *key = request->key; + const char *key_end, *key = request->key; uint32_t part_count = mp_decode_array(&key); - if (exact_key_validate(pk->def->key_def, key, part_count) != 0) + if (exact_key_validate(pk->def->key_def, key, part_count, + &key_end) != 0) return -1; struct tuple *old_tuple; if (index_get(pk, key, part_count, &old_tuple) != 0) @@ -402,9 +403,10 @@ memtx_space_execute_update(struct space *space, struct txn *txn, struct index *pk = index_find_unique(space, request->index_id); if (pk == NULL) return -1; - const char *key = request->key; + const char *key_end, *key = request->key; uint32_t part_count = mp_decode_array(&key); - if (exact_key_validate(pk->def->key_def, key, part_count) != 0) + if (exact_key_validate(pk->def->key_def, key, part_count, + &key_end) != 0) return -1; struct tuple *old_tuple; if (index_get(pk, key, part_count, &old_tuple) != 0) diff --git a/src/box/space.c b/src/box/space.c index b6ad87bf7..e9196284f 100644 --- a/src/box/space.c +++ b/src/box/space.c @@ -298,7 +298,7 @@ space_before_replace(struct space *space, struct txn *txn, enum iproto_type type = request->type; struct index *pk = space_index(space, 0); - const char *key = NULL; + const char *key_end, *key = NULL; uint32_t part_count = 0; struct index *index = NULL; @@ -314,7 +314,7 @@ space_before_replace(struct space *space, struct txn *txn, key = request->key; part_count = mp_decode_array(&key); if (exact_key_validate(index->def->key_def, - key, part_count) != 0) + key, part_count, &key_end) != 0) return -1; break; case IPROTO_INSERT: diff --git a/src/box/sysview.c b/src/box/sysview.c index 46cf1e13f..9c9a2bc89 100644 --- a/src/box/sysview.c +++ b/src/box/sysview.c @@ -164,7 +164,9 @@ sysview_index_get(struct index *base, const char *key, diag_set(ClientError, ER_MORE_THAN_ONE_TUPLE); return -1; } - if (exact_key_validate(pk->def->key_def, key, part_count) != 0) + const char *key_end; + if (exact_key_validate(pk->def->key_def, key, part_count, + &key_end) != 0) return -1; struct tuple *tuple; if (index_get(pk, key, part_count, &tuple) != 0) diff --git a/src/box/vinyl.c b/src/box/vinyl.c index 3e686b080..a03132310 100644 --- a/src/box/vinyl.c +++ b/src/box/vinyl.c @@ -1748,7 +1748,9 @@ vy_unique_key_validate(struct vy_lsm *lsm, const char *key, original_part_count, part_count); return -1; } - return key_validate_parts(lsm->cmp_def, key, part_count, false); + const char *key_end; + return key_validate_parts(lsm->cmp_def, key, part_count, false, + &key_end); } /** -- 2.21.0
next prev parent reply other threads:[~2019-06-24 14:27 UTC|newest] Thread overview: 5+ messages / expand[flat|nested] mbox.gz Atom feed top [not found] <cover.1561384554.git.kshcherbatov@tarantool.org> 2019-06-24 14:27 ` [PATCH v2 1/5] box: introduce tuple_extra infrastructure Kirill Shcherbatov 2019-06-24 14:27 ` [PATCH v2 2/5] box: introduce key_def->is_multikey flag Kirill Shcherbatov 2019-06-24 14:27 ` Kirill Shcherbatov [this message] 2019-06-24 14:27 ` [PATCH v2 4/5] box: move the function hash to the tuple library Kirill Shcherbatov 2019-06-24 14:27 ` [PATCH v2 5/5] box: introduce functional indexes in memtx Kirill Shcherbatov
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=139210ab31590bb7827e8f9c1791d131b88babd7.1561384554.git.kshcherbatov@tarantool.org \ --to=kshcherbatov@tarantool.org \ --cc=tarantool-patches@freelists.org \ --cc=vdavydov.dev@gmail.com \ --subject='Re: [PATCH v2 3/5] box: refactor key_validate_parts to return key_end' \ /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