Skip to content
Snippets Groups Projects
Commit 7b123296 authored by Andrey Saranchin's avatar Andrey Saranchin Committed by Vladimir Davydov
Browse files

key_def: introduce tuple_validate_key_parts_raw helper

We are going to validate only key parts of passed tuple in pagination.
That is why the patch introduces helper that allows to do it with raw
version of tuple.

Part of #8511
Part of tarantool/tarantool-ee#285

NO_CHANGELOG=internal
NO_DOC=internal

(cherry picked from commit f8bb4ec4)
parent 62b934f6
No related branches found
No related tags found
No related merge requests found
......@@ -916,6 +916,15 @@ tuple_key_is_excluded(struct tuple *tuple, struct key_def *def,
int
tuple_validate_key_parts(struct key_def *key_def, struct tuple *tuple);
/**
* Check that raw tuple fields match with given key definition.
*
* @retval 0 The tuple is valid.
* @retval -1 The tuple is invalid.
*/
int
tuple_validate_key_parts_raw(struct key_def *key_def, const char *tuple);
/**
* Same as tuple_extract_key but accept region to allocate result on.
*/
......
......@@ -507,6 +507,26 @@ tuple_key_is_excluded_slow(struct tuple *tuple, struct key_def *def,
return false;
}
/** Validate tuple field against key part. */
static int
tuple_validate_field(const char *field, struct key_part *part,
uint32_t field_no)
{
if (field == NULL) {
if (key_part_is_nullable(part))
return 0;
diag_set(ClientError, ER_FIELD_MISSING,
tt_sprintf("[%d]%.*s",
part->fieldno + TUPLE_INDEX_BASE,
part->path_len, part->path));
return -1;
}
if (key_part_validate(part->type, field, field_no,
key_part_is_nullable(part)) != 0)
return -1;
return 0;
}
int
tuple_validate_key_parts(struct key_def *key_def, struct tuple *tuple)
{
......@@ -515,17 +535,33 @@ tuple_validate_key_parts(struct key_def *key_def, struct tuple *tuple)
struct key_part *part = &key_def->parts[idx];
const char *field = tuple_field_by_part(tuple, part,
MULTIKEY_NONE);
if (field == NULL) {
if (key_part_is_nullable(part))
continue;
diag_set(ClientError, ER_FIELD_MISSING,
tt_sprintf("[%d]%.*s",
part->fieldno + TUPLE_INDEX_BASE,
part->path_len, part->path));
if (tuple_validate_field(field, part, idx) != 0)
return -1;
}
return 0;
}
int
tuple_validate_key_parts_raw(struct key_def *key_def, const char *tuple)
{
assert(!key_def->is_multikey);
struct key_part *part = NULL;
const char *field = NULL;
uint32_t field_count = mp_decode_array(&tuple);
for (uint32_t idx = 0; idx < key_def->part_count; idx++) {
part = &key_def->parts[idx];
field = NULL;
if (part->fieldno < field_count) {
field = tuple;
for (uint32_t k = 0; k < part->fieldno; k++)
mp_next(&field);
if (part->path != NULL &&
tuple_go_to_path(&field, part->path,
part->path_len, TUPLE_INDEX_BASE,
MULTIKEY_NONE) != 0)
return -1;
}
if (key_part_validate(part->type, field, idx,
key_part_is_nullable(part)) != 0)
if (tuple_validate_field(field, part, idx) != 0)
return -1;
}
return 0;
......
......@@ -292,14 +292,61 @@ test_tuple_extract_key_raw_slowpath_nullable(void)
check_plan();
}
static void
test_tuple_validate_key_parts_raw(void)
{
plan(7);
header();
struct key_def *def = test_key_def_new(
"[{%s%u%s%s}{%s%u%s%s%s%b}]",
"field", 0, "type", "unsigned",
"field", 2, "type", "unsigned", "is_nullable", 1);
fail_if(def == NULL);
struct tuple *invalid_tuples[3] = {
test_tuple_new("[%s]", "abc"),
test_tuple_new("[%u%u%s]", 1, 20, "abc"),
test_tuple_new("[%s%u%u]", "abc", 5, 10),
};
struct tuple *valid_tuples[4] = {
test_tuple_new("[%u]", 10),
test_tuple_new("[%u%u]", 10, 20),
test_tuple_new("[%u%u%u]", 1, 5, 10),
test_tuple_new("[%u%s%u%u]", 1, "dce", 5, 10),
};
for (size_t i = 0; i < lengthof(invalid_tuples); ++i)
fail_if(invalid_tuples[i] == NULL);
for (size_t i = 0; i < lengthof(valid_tuples); ++i)
fail_if(valid_tuples[i] == NULL);
for (size_t i = 0; i < lengthof(invalid_tuples); ++i)
is(tuple_validate_key_parts_raw(def,
tuple_data(invalid_tuples[i])),
-1, "tuple %zu must be invalid", i);
for (size_t i = 0; i < lengthof(valid_tuples); ++i)
is(tuple_validate_key_parts_raw(def,
tuple_data(valid_tuples[i])),
0, "tuple %zu must be valid", i);
key_def_delete(def);
for (size_t i = 0; i < lengthof(invalid_tuples); ++i)
tuple_delete(invalid_tuples[i]);
for (size_t i = 0; i < lengthof(valid_tuples); ++i)
tuple_delete(valid_tuples[i]);
footer();
check_plan();
}
static int
test_main(void)
{
plan(2);
plan(3);
header();
test_func_compare_with_key();
test_tuple_extract_key_raw_slowpath_nullable();
test_tuple_validate_key_parts_raw();
footer();
return check_plan();
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment