From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from localhost (localhost [127.0.0.1]) by turing.freelists.org (Avenir Technologies Mail Multiplex) with ESMTP id 5929224910 for ; Tue, 24 Jul 2018 07:58:15 -0400 (EDT) Received: from turing.freelists.org ([127.0.0.1]) by localhost (turing.freelists.org [127.0.0.1]) (amavisd-new, port 10024) with ESMTP id 2uoGnYWXS4z9 for ; Tue, 24 Jul 2018 07:58:15 -0400 (EDT) Received: from smtp62.i.mail.ru (smtp62.i.mail.ru [217.69.128.42]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by turing.freelists.org (Avenir Technologies Mail Multiplex) with ESMTPS id DD16523518 for ; Tue, 24 Jul 2018 07:58:14 -0400 (EDT) Received: from [185.6.245.156] (port=43304 helo=mimeev-ThinkPad-T460p.mail.msk) by smtp62.i.mail.ru with esmtpa (envelope-from ) id 1fhvxF-0007jP-7I for tarantool-patches@freelists.org; Tue, 24 Jul 2018 14:58:13 +0300 From: imeevma@tarantool.org Subject: [tarantool-patches] [PATCH v3 2/7] box: move checks for key findability from space_vtab Date: Tue, 24 Jul 2018 14:58:12 +0300 Message-Id: <0ebcfc51d88c82ba1a6a00f898bb082ea5e38c73.1532433235.git.imeevma@gmail.com> In-Reply-To: References: Sender: tarantool-patches-bounce@freelists.org Errors-to: tarantool-patches-bounce@freelists.org Reply-To: tarantool-patches@freelists.org List-help: List-unsubscribe: List-software: Ecartis version 1.0.0 List-Id: tarantool-patches List-subscribe: List-owner: List-post: List-archive: To: tarantool-patches@freelists.org In this patch checks exact_key_validate for memtx and vy_unique_key_validate for vinyl were moved from space_vtab to box.cc. This is needed for creation _impl versions of some space functions. Part of #3375. --- src/box/box.cc | 74 ++++++++++++++++++++++++++++++++++++++++++++------- src/box/memtx_space.c | 4 --- src/box/vinyl.c | 40 ---------------------------- 3 files changed, 64 insertions(+), 54 deletions(-) diff --git a/src/box/box.cc b/src/box/box.cc index 3ed2a4a..71f3a51 100644 --- a/src/box/box.cc +++ b/src/box/box.cc @@ -993,16 +993,52 @@ box_index_id_by_name(uint32_t space_id, const char *name, uint32_t len) } /** \endcond public */ +/** + * Check space for writeability. + * + * @param space space for this check. + * + * @retval 0 space is writeable. + * @retval -1 error. + */ +static inline int +space_check_writable(struct space *space) +{ + if (!space_is_temporary(space) && + space_group_id(space) != GROUP_LOCAL && + box_check_writable() != 0) + return -1; + return 0; +} + +/** + * Check if key is good enough to be used to find tuple. + * + * @param space space for this check. + * @param index_id id of index for this check. + * @param key key to check. + * + * @retval 0 key is findable. + * @retval -1 error. + */ +static inline int +key_check_findable(struct space *space, uint32_t index_id, const char *key) +{ + struct index *pk = index_find_unique(space, index_id); + if (pk == NULL) + return -1; + uint32_t part_count = mp_decode_array(&key); + if (exact_key_validate(pk->def->key_def, key, part_count) != 0) + return -1; + return 0; +} + int box_process1(struct request *request, box_tuple_t **result) { /* Allow to write to temporary spaces in read-only mode. */ struct space *space = space_cache_find(request->space_id); - if (space == NULL) - return -1; - if (!space_is_temporary(space) && - space_group_id(space) != GROUP_LOCAL && - box_check_writable() != 0) + if (space == NULL || space_check_writable(space) != 0) return -1; return box_process_rw(request, space, result); } @@ -1087,13 +1123,16 @@ box_insert(uint32_t space_id, const char *tuple, const char *tuple_end, box_tuple_t **result) { mp_tuple_assert(tuple, tuple_end); + struct space *space = space_cache_find(space_id); + if (space == NULL || space_check_writable(space) != 0) + return -1; struct request request; memset(&request, 0, sizeof(request)); request.type = IPROTO_INSERT; request.space_id = space_id; request.tuple = tuple; request.tuple_end = tuple_end; - return box_process1(&request, result); + return box_process_rw(&request, space, result); } int @@ -1101,13 +1140,16 @@ box_replace(uint32_t space_id, const char *tuple, const char *tuple_end, box_tuple_t **result) { mp_tuple_assert(tuple, tuple_end); + struct space *space = space_cache_find(space_id); + if (space == NULL || space_check_writable(space) != 0) + return -1; struct request request; memset(&request, 0, sizeof(request)); request.type = IPROTO_REPLACE; request.space_id = space_id; request.tuple = tuple; request.tuple_end = tuple_end; - return box_process1(&request, result); + return box_process_rw(&request, space, result); } int @@ -1115,6 +1157,10 @@ box_delete(uint32_t space_id, uint32_t index_id, const char *key, const char *key_end, box_tuple_t **result) { mp_tuple_assert(key, key_end); + struct space *space = space_cache_find(space_id); + if (space == NULL || space_check_writable(space) != 0 || + key_check_findable(space, index_id, key) != 0) + return -1; struct request request; memset(&request, 0, sizeof(request)); request.type = IPROTO_DELETE; @@ -1122,7 +1168,7 @@ box_delete(uint32_t space_id, uint32_t index_id, const char *key, request.index_id = index_id; request.key = key; request.key_end = key_end; - return box_process1(&request, result); + return box_process_rw(&request, space, result); } int @@ -1132,6 +1178,10 @@ box_update(uint32_t space_id, uint32_t index_id, const char *key, { mp_tuple_assert(key, key_end); mp_tuple_assert(ops, ops_end); + struct space *space = space_cache_find(space_id); + if (space == NULL || space_check_writable(space) != 0 || + key_check_findable(space, index_id, key) != 0) + return -1; struct request request; memset(&request, 0, sizeof(request)); request.type = IPROTO_UPDATE; @@ -1143,7 +1193,8 @@ box_update(uint32_t space_id, uint32_t index_id, const char *key, /** Legacy: in case of update, ops are passed in in request tuple */ request.tuple = ops; request.tuple_end = ops_end; - return box_process1(&request, result); + + return box_process_rw(&request, space, result); } int @@ -1153,6 +1204,9 @@ box_upsert(uint32_t space_id, uint32_t index_id, const char *tuple, { mp_tuple_assert(ops, ops_end); mp_tuple_assert(tuple, tuple_end); + struct space *space = space_cache_find(space_id); + if (space == NULL || space_check_writable(space) != 0) + return -1; struct request request; memset(&request, 0, sizeof(request)); request.type = IPROTO_UPSERT; @@ -1163,7 +1217,7 @@ box_upsert(uint32_t space_id, uint32_t index_id, const char *tuple, request.tuple = tuple; request.tuple_end = tuple_end; request.index_base = index_base; - return box_process1(&request, result); + return box_process_rw(&request, space, result); } /** diff --git a/src/box/memtx_space.c b/src/box/memtx_space.c index 1571a0e..0d00b90 100644 --- a/src/box/memtx_space.c +++ b/src/box/memtx_space.c @@ -365,8 +365,6 @@ memtx_space_execute_delete(struct space *space, struct txn *txn, return -1; const char *key = request->key; uint32_t part_count = mp_decode_array(&key); - if (exact_key_validate(pk->def->key_def, key, part_count) != 0) - return -1; struct tuple *old_tuple; if (index_get(pk, key, part_count, &old_tuple) != 0) return -1; @@ -391,8 +389,6 @@ memtx_space_execute_update(struct space *space, struct txn *txn, return -1; const char *key = request->key; uint32_t part_count = mp_decode_array(&key); - if (exact_key_validate(pk->def->key_def, key, part_count) != 0) - return -1; struct tuple *old_tuple; if (index_get(pk, key, part_count, &old_tuple) != 0) return -1; diff --git a/src/box/vinyl.c b/src/box/vinyl.c index 6e24071..05321cd 100644 --- a/src/box/vinyl.c +++ b/src/box/vinyl.c @@ -1589,42 +1589,6 @@ error: } /** - * Check that the key can be used for search in a unique index - * LSM tree. - * @param lsm LSM tree for checking. - * @param key MessagePack'ed data, the array without a - * header. - * @param part_count Part count of the key. - * - * @retval 0 The key is valid. - * @retval -1 The key is not valid, the appropriate error is set - * in the diagnostics area. - */ -static inline int -vy_unique_key_validate(struct vy_lsm *lsm, const char *key, - uint32_t part_count) -{ - assert(lsm->opts.is_unique); - assert(key != NULL || part_count == 0); - /* - * The LSM tree contains tuples with concatenation of - * secondary and primary key fields, while the key - * supplied by the user only contains the secondary key - * fields. Use the correct key def to validate the key. - * The key can be used to look up in the LSM tree since - * the supplied key parts uniquely identify the tuple, - * as long as the index is unique. - */ - uint32_t original_part_count = lsm->key_def->part_count; - if (original_part_count != part_count) { - diag_set(ClientError, ER_EXACT_MATCH, - original_part_count, part_count); - return -1; - } - return key_validate_parts(lsm->cmp_def, key, part_count, false); -} - -/** * Find a tuple in the primary index LSM tree by the key of the * specified LSM tree. * @param lsm LSM tree for which the key is specified. @@ -1738,8 +1702,6 @@ vy_delete(struct vy_env *env, struct vy_tx *tx, struct txn_stmt *stmt, bool has_secondary = space->index_count > 1; const char *key = request->key; uint32_t part_count = mp_decode_array(&key); - if (vy_unique_key_validate(lsm, key, part_count)) - return -1; /* * There are two cases when need to get the full tuple * before deletion. @@ -1830,8 +1792,6 @@ vy_update(struct vy_env *env, struct vy_tx *tx, struct txn_stmt *stmt, return -1; const char *key = request->key; uint32_t part_count = mp_decode_array(&key); - if (vy_unique_key_validate(lsm, key, part_count)) - return -1; if (vy_lsm_full_by_key(lsm, tx, vy_tx_read_view(tx), key, part_count, &stmt->old_tuple) != 0) -- 2.7.4