[Tarantool-patches] [PATCH v3 16/16] module api: add box_key_def_validate_full_key()
Alexander Turenko
alexander.turenko at tarantool.org
Tue Oct 13 02:23:23 MSK 2020
box_key_def_validate_key() verifies a probably partial key, while the
new function is to apply the extra restriction on the key part count: it
should be the same as in a given key definition.
Fixes #5273
---
src/box/key_def.c | 13 +++++++
src/box/key_def.h | 20 ++++++++++
src/exports.h | 1 +
test/app-tap/module_api.c | 79 +++++++++++++++++++++++----------------
4 files changed, 80 insertions(+), 33 deletions(-)
diff --git a/src/box/key_def.c b/src/box/key_def.c
index 55ac79362..3df67fa3b 100644
--- a/src/box/key_def.c
+++ b/src/box/key_def.c
@@ -640,6 +640,19 @@ box_key_def_validate_key(const box_key_def_t *key_def, const char *key)
return key_validate_parts(key_def, key, part_count, true, &key_end);
}
+int
+box_key_def_validate_full_key(const box_key_def_t *key_def, const char *key)
+{
+ uint32_t part_count = mp_decode_array(&key);
+ if (part_count != key_def->part_count) {
+ diag_set(ClientError, ER_EXACT_MATCH, key_def->part_count,
+ part_count);
+ return -1;
+ }
+ const char *key_end;
+ return key_validate_parts(key_def, key, part_count, true, &key_end);
+}
+
/* }}} Module API functions */
int
diff --git a/src/box/key_def.h b/src/box/key_def.h
index 440f2fb13..ec60152d1 100644
--- a/src/box/key_def.h
+++ b/src/box/key_def.h
@@ -566,6 +566,26 @@ box_key_def_extract_key(box_key_def_t *key_def, box_tuple_t *tuple,
API_EXPORT int
box_key_def_validate_key(const box_key_def_t *key_def, const char *key);
+/**
+ * Check a full key against given key definition.
+ *
+ * Verifies key parts against given key_def's field types with
+ * respect to nullability.
+ *
+ * Imposes the same parts count in @a key as in @a key_def.
+ * Absense of trailing key parts fails the check.
+ *
+ * Note: nil is accepted for nullable fields, but only for them.
+ *
+ * @param key_def Key definition.
+ * @param key MessagePack'ed data for matching.
+ *
+ * @retval 0 The key is valid.
+ * @retval -1 The key is invalid.
+ */
+API_EXPORT int
+box_key_def_validate_full_key(const box_key_def_t *key_def, const char *key);
+
/** \endcond public */
/*
diff --git a/src/exports.h b/src/exports.h
index 1d7deb518..ad5f3f08e 100644
--- a/src/exports.h
+++ b/src/exports.h
@@ -35,6 +35,7 @@ EXPORT(box_key_def_extract_key)
EXPORT(box_key_def_merge)
EXPORT(box_key_def_new)
EXPORT(box_key_def_new_v2)
+EXPORT(box_key_def_validate_full_key)
EXPORT(box_key_def_validate_key)
EXPORT(box_key_def_validate_tuple)
EXPORT(box_key_part_def_create)
diff --git a/test/app-tap/module_api.c b/test/app-tap/module_api.c
index 778e7c3c0..a3c4850cd 100644
--- a/test/app-tap/module_api.c
+++ b/test/app-tap/module_api.c
@@ -1706,7 +1706,8 @@ test_key_def_extract_key(struct lua_State *L)
}
/**
- * Basic <box_key_def_validate_key>() test.
+ * Basic <box_key_def_validate_key>() and
+ * <box_key_def_validate_full_key>() test.
*/
static int
test_key_def_validate_key(struct lua_State *L)
@@ -1736,15 +1737,16 @@ test_key_def_validate_key(struct lua_State *L)
/*
* Create keys to validate them against given key_def.
*
- * | # | key | Is valid? |
- * | - | -------------- | --------- |
- * | 0 | [1, 1] | valid |
- * | 1 | [1, null] | valid |
- * | 2 | [1] | valid |
- * | 3 | [] | valid |
- * | 4 | [null] | invalid |
- * | 5 | [1, 2, 3] | invalid |
- * | 6 | [1, -1] | invalid |
+ * | # | key | Is valid? | Is valid? |
+ * | | | (partial) | (full) |
+ * | - | -------------- | --------- | --------- |
+ * | 0 | [1, 1] | valid | valid |
+ * | 1 | [1, null] | valid | valid |
+ * | 2 | [1] | valid | invalid |
+ * | 3 | [] | valid | invalid |
+ * | 4 | [null] | invalid | invalid |
+ * | 5 | [1, 2, 3] | invalid | invalid |
+ * | 6 | [1, -1] | invalid | invalid |
*/
const char *keys[] = {
/* [0] = */ "\x92\x01\x01",
@@ -1755,33 +1757,44 @@ test_key_def_validate_key(struct lua_State *L)
/* [5] = */ "\x93\x01\x02\x03",
/* [6] = */ "\x92\x01\xff",
};
- int expected_results[] = {
- /* [0] = */ 0,
- /* [1] = */ 0,
- /* [2] = */ 0,
- /* [3] = */ 0,
- /* [4] = */ -1,
- /* [5] = */ -1,
- /* [6] = */ -1,
+ int expected_results[][2] = {
+ /* [0] = */ {0, 0 },
+ /* [1] = */ {0, 0 },
+ /* [2] = */ {0, -1},
+ /* [3] = */ {0, -1},
+ /* [4] = */ {-1, -1},
+ /* [5] = */ {-1, -1},
+ /* [6] = */ {-1, -1},
};
- uint32_t expected_error_codes[] = {
- /* [0] = */ box_error_code_MAX,
- /* [1] = */ box_error_code_MAX,
- /* [2] = */ box_error_code_MAX,
- /* [3] = */ box_error_code_MAX,
- /* [4] = */ ER_KEY_PART_TYPE,
- /* [5] = */ ER_KEY_PART_COUNT,
- /* [6] = */ ER_KEY_PART_TYPE,
+ uint32_t expected_error_codes[][2] = {
+ /* [0] = */ {box_error_code_MAX, box_error_code_MAX},
+ /* [1] = */ {box_error_code_MAX, box_error_code_MAX},
+ /* [2] = */ {box_error_code_MAX, ER_EXACT_MATCH },
+ /* [3] = */ {box_error_code_MAX, ER_EXACT_MATCH },
+ /* [4] = */ {ER_KEY_PART_TYPE, ER_EXACT_MATCH },
+ /* [5] = */ {ER_KEY_PART_COUNT, ER_EXACT_MATCH },
+ /* [6] = */ {ER_KEY_PART_TYPE, ER_KEY_PART_TYPE },
};
- for (size_t i = 0; i < lengthof(keys); ++i) {
- int rc = box_key_def_validate_key(key_def, keys[i]);
- assert(rc == expected_results[i]);
+ typedef int (*key_def_validate_key_f)(const box_key_def_t *key_def,
+ const char *key);
+ key_def_validate_key_f funcs[] = {
+ box_key_def_validate_key,
+ box_key_def_validate_full_key,
+ };
- if (expected_error_codes[i] != box_error_code_MAX) {
- assert(rc != 0);
- box_error_t *e = box_error_last();
- assert(box_error_code(e) == expected_error_codes[i]);
+ for (size_t i = 0; i < lengthof(keys); ++i) {
+ for (size_t f = 0; f < lengthof(funcs); ++f) {
+ int exp_res = expected_results[i][f];
+ uint32_t exp_err_code = expected_error_codes[i][f];
+ int rc = funcs[f](key_def, keys[i]);
+ assert(rc == exp_res);
+
+ if (exp_err_code != box_error_code_MAX) {
+ assert(rc != 0);
+ box_error_t *e = box_error_last();
+ assert(box_error_code(e) == exp_err_code);
+ }
}
}
--
2.25.0
More information about the Tarantool-patches
mailing list