From cb0264c3cac00c288f9a0b4614f203d1c4b157ab Mon Sep 17 00:00:00 2001 From: Ilya Verbin <iverbin@tarantool.org> Date: Tue, 6 Feb 2024 18:25:18 +0300 Subject: [PATCH] key_def: ignore json path in key_def_find_by_fieldno This function returns a key_def part by a field number. However, currently it returns NULL for parts that contain a JSON path to indexed data. Fix it. Needed for tarantool/tarantool-ee#671 NO_DOC=bugfix NO_CHANGELOG=not visible in CE --- src/box/key_def.c | 10 ++++++---- src/box/key_def.h | 4 +++- test/unit/key_def.cc | 31 ++++++++++++++++++++++++++++++- 3 files changed, 39 insertions(+), 6 deletions(-) diff --git a/src/box/key_def.c b/src/box/key_def.c index bdd6561d5e..8097cf3036 100644 --- a/src/box/key_def.c +++ b/src/box/key_def.c @@ -1016,10 +1016,12 @@ key_def_decode_parts(struct key_part_def *parts, uint32_t part_count, const struct key_part * key_def_find_by_fieldno(const struct key_def *key_def, uint32_t fieldno) { - struct key_part part; - memset(&part, 0, sizeof(struct key_part)); - part.fieldno = fieldno; - return key_def_find(key_def, &part); + const struct key_part *part = key_def->parts; + const struct key_part *end = part + key_def->part_count; + for (; part != end; part++) + if (part->fieldno == fieldno) + return part; + return NULL; } const struct key_part * diff --git a/src/box/key_def.h b/src/box/key_def.h index 4d90a0a000..1170399542 100644 --- a/src/box/key_def.h +++ b/src/box/key_def.h @@ -730,7 +730,9 @@ key_def_decode_parts(struct key_part_def *parts, uint32_t part_count, uint32_t field_count, struct region *region); /** - * Returns the part in index_def->parts for the specified fieldno. + * Returns the first part in index_def->parts for the specified fieldno. + * The part is returned regardless of whether it is indexed by JSON path or not. + * * If fieldno is not in index_def->parts returns NULL. */ const struct key_part * diff --git a/test/unit/key_def.cc b/test/unit/key_def.cc index 7f1d4fc96e..e96c2b9946 100644 --- a/test/unit/key_def.cc +++ b/test/unit/key_def.cc @@ -1367,10 +1367,38 @@ test_tuple_compare_sequential_no_optional_parts_unique(bool ascending_key, check_plan(); } +static void +test_key_def_find_by_fieldno(void) +{ + plan(3); + header(); + + const struct key_part *key_part; + struct key_def *key_def = test_key_def_new( + "[{%s%u%s%s}{%s%u%s%s}{%s%u%s%s%s%s}]", + "field", 1, "type", "unsigned", + "field", 2, "type", "string", + "field", 3, "type", "string", "path", "foo"); + + key_part = key_def_find_by_fieldno(key_def, 2); + isnt(key_part, NULL, "field 2 (no path) found"); + + key_part = key_def_find_by_fieldno(key_def, 3); + isnt(key_part, NULL, "field 3 (with path) found"); + + key_part = key_def_find_by_fieldno(key_def, 100); + is(key_part, NULL, "field 100 not found"); + + key_def_delete(key_def); + + footer(); + check_plan(); +} + static int test_main(void) { - plan(50); + plan(51); header(); test_func_compare(); @@ -1423,6 +1451,7 @@ test_main(void) test_key_compare_singlepart(true, false); test_key_compare_singlepart(false, true); test_key_compare_singlepart(false, false); + test_key_def_find_by_fieldno(); footer(); return check_plan(); -- GitLab