Tarantool development patches archive
 help / color / mirror / Atom feed
From: Alexander Turenko <alexander.turenko@tarantool.org>
To: Vladislav Shpilevoy <v.shpilevoy@tarantool.org>
Cc: tarantool-patches@dev.tarantool.org,
	Alexander Turenko <alexander.turenko@tarantool.org>
Subject: [Tarantool-patches] [PATCH v3 16/16] module api: add box_key_def_validate_full_key()
Date: Tue, 13 Oct 2020 02:23:23 +0300	[thread overview]
Message-ID: <3aa47ada1c270fd7f042627598097cea4ae09750.1602541394.git.alexander.turenko@tarantool.org> (raw)
In-Reply-To: <cover.1602541394.git.alexander.turenko@tarantool.org>

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

  parent reply	other threads:[~2020-10-12 23:23 UTC|newest]

Thread overview: 33+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2020-10-12 23:23 [Tarantool-patches] [PATCH v3 00/16] module api: extend for external key_def Lua module Alexander Turenko
2020-10-12 23:23 ` [Tarantool-patches] [PATCH v3 01/16] module api: get rid of typedef redefinitions Alexander Turenko
2020-10-12 23:23 ` [Tarantool-patches] [PATCH v3 02/16] module api: expose box region Alexander Turenko
2020-10-14 23:41   ` Vladislav Shpilevoy
2020-10-15 13:17     ` Alexander Turenko
2020-10-12 23:23 ` [Tarantool-patches] [PATCH v3 03/16] module api/lua: add luaL_iscdata() function Alexander Turenko
2020-10-12 23:23 ` [Tarantool-patches] [PATCH v3 04/16] lua: factor out tuple encoding from luaT_tuple_new Alexander Turenko
2020-10-12 23:23 ` [Tarantool-patches] [PATCH v3 05/16] lua: don't raise a Lua error from luaT_tuple_new() Alexander Turenko
2020-10-14 23:41   ` Vladislav Shpilevoy
2020-10-15 13:17     ` Alexander Turenko
2020-10-12 23:23 ` [Tarantool-patches] [PATCH v3 06/16] module api/lua: add luaT_tuple_encode() Alexander Turenko
2020-10-12 23:23 ` [Tarantool-patches] [PATCH v3 07/16] module api/lua: expose luaT_tuple_new() Alexander Turenko
2020-10-12 23:23 ` [Tarantool-patches] [PATCH v3 08/16] module api/lua: add API_EXPORT to tuple functions Alexander Turenko
2020-10-14 23:41   ` Vladislav Shpilevoy
2020-10-15  2:35     ` Alexander Turenko
2020-10-12 23:23 ` [Tarantool-patches] [PATCH v3 09/16] module api: add API_EXPORT to key_def functions Alexander Turenko
2020-10-12 23:23 ` [Tarantool-patches] [PATCH v3 10/16] module api: add box_key_def_new_v2() Alexander Turenko
2020-10-12 23:23 ` [Tarantool-patches] [PATCH v3 11/16] module api: add box_key_def_dump_parts() Alexander Turenko
2020-10-12 23:23 ` [Tarantool-patches] [PATCH v3 12/16] module api: expose box_key_def_validate_tuple() Alexander Turenko
2020-10-12 23:23 ` [Tarantool-patches] [PATCH v3 13/16] module api: expose box_key_def_merge() Alexander Turenko
2020-10-14 23:41   ` Vladislav Shpilevoy
2020-10-12 23:23 ` [Tarantool-patches] [PATCH v3 14/16] module api: expose box_key_def_extract_key() Alexander Turenko
2020-10-14 23:41   ` Vladislav Shpilevoy
2020-10-15  2:39     ` Alexander Turenko
2020-10-12 23:23 ` [Tarantool-patches] [PATCH v3 15/16] module api: add box_key_def_validate_key() Alexander Turenko
2020-10-14 23:41   ` Vladislav Shpilevoy
2020-10-15 13:18     ` Alexander Turenko
2020-10-12 23:23 ` Alexander Turenko [this message]
2020-10-14 23:41 ` [Tarantool-patches] [PATCH v3 00/16] module api: extend for external key_def Lua module Vladislav Shpilevoy
2020-10-15  3:09   ` Alexander Turenko
2020-10-15 13:19 ` Alexander Turenko
2020-10-16  6:05   ` Alexander Turenko
2020-10-15 20:12 ` 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=3aa47ada1c270fd7f042627598097cea4ae09750.1602541394.git.alexander.turenko@tarantool.org \
    --to=alexander.turenko@tarantool.org \
    --cc=tarantool-patches@dev.tarantool.org \
    --cc=v.shpilevoy@tarantool.org \
    --subject='Re: [Tarantool-patches] [PATCH v3 16/16] module api: add box_key_def_validate_full_key()' \
    /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