[tarantool-patches] [PATCH v3 2/7] box: move checks for key findability from space_vtab

  • From: imeevma@xxxxxxxxxxxxx
  • To: tarantool-patches@xxxxxxxxxxxxx
  • Date: Tue, 24 Jul 2018 14:58:12 +0300

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


Other related posts:

  • » [tarantool-patches] [PATCH v3 2/7] box: move checks for key findability from space_vtab - imeevma