diff --git a/doc/user/errcode.xml b/doc/user/errcode.xml index c882838da5a0fb44a31f3ead9b6451ebf9bcfc42..affe269ee40413b5213e88a0ecdf4741068b3986 100644 --- a/doc/user/errcode.xml +++ b/doc/user/errcode.xml @@ -55,6 +55,12 @@ of existing codes.</para> </para></listitem> </varlistentry> + <varlistentry> + <term xml:id="ER_KEY_CARDINALITY" xreflabel="ER_KEY_CARDINALITY">ER_KEY_CARDINALITY</term> + <listitem><para>Key cardinality is greater than index cardinality + </para></listitem> + </varlistentry> + <varlistentry> <term xml:id="ER_NO_SUCH_SPACE" xreflabel="ER_NO_SUCH_SPACE">ER_NO_SUCH_SPACE</term> <listitem><para>Attempt to access a space that is not diff --git a/include/errcode.h b/include/errcode.h index 8c7a22bf221196b9019a5eea4b0847d1230f28d3..19edbd1e34522cbefb6f94dc8e7e1abb3c38856c 100644 --- a/include/errcode.h +++ b/include/errcode.h @@ -101,7 +101,7 @@ enum { TNT_ERRMSG_MAX = 512 }; /* 44 */_(ER_UNKNOWN_UPDATE_OP, 2, "Unknown UPDATE operation") \ /* 45 */_(ER_UNUSED45, 0, "Unused45") \ /* 46 */_(ER_UNUSED46, 0, "Unused46") \ - /* 47 */_(ER_UNUSED47, 0, "Unused47") \ + /* 47 */_(ER_KEY_CARDINALITY, 2, "Key cardinality %d is greater than index cardinality %d") \ /* 48 */_(ER_PROC_RET, 2, "Return type '%s' is not supported in the binary protocol") \ /* 49 */_(ER_TUPLE_NOT_FOUND, 2, "Tuple doesn't exist") \ /* 50 */_(ER_NO_SUCH_PROC, 2, "Procedure '%.*s' is not defined") \ diff --git a/mod/box/box.m b/mod/box/box.m index 3673757696828525e08a594b8fba1f6c8a50b42e..75673f25b8ecaeb97fa8045023e524d9dd98cce9 100644 --- a/mod/box/box.m +++ b/mod/box/box.m @@ -897,6 +897,12 @@ process_select(struct box_txn *txn, u32 limit, u32 offset, struct tbuf *data) void *key = NULL; if (key_cardinality) { + if (key_cardinality > index->key_def->part_count) { + tnt_raise(ClientError, :ER_KEY_CARDINALITY, + key_cardinality, + index->key_def->part_count); + } + key = read_field(data); /* advance remaining fields of a key */ diff --git a/mod/box/tree.m b/mod/box/tree.m index 17b191c0858b9864a1fa909c4cab59ed5495ea1f..c1b75a31d49bd2ee8b9961798995fc8e218396c1 100644 --- a/mod/box/tree.m +++ b/mod/box/tree.m @@ -323,7 +323,8 @@ fold_with_key_parts(struct key_def *key_def, struct key_data *key_data) memset(parts, 0, sizeof(parts[0]) * key_data->part_count); - for (int part = 0; part < key_data->part_count; ++part) { + int part_count = MIN(key_def->part_count, key_data->part_count); + for (int part = 0; part < part_count; ++part) { u8 *data = part_data; u32 len = load_varint32((void**) &data); diff --git a/test/box_big/lua.result b/test/box_big/lua.result index 5d6f808e4a056249dcf179348fd3907ae2eb26ad..354aae4839578abfca70aca423aa7e87a21e48e8 100644 --- a/test/box_big/lua.result +++ b/test/box_big/lua.result @@ -11,6 +11,13 @@ lua box.space[1].index[1]:max() call box.select(1, 1, 'new', 'world') Found 1 tuple: ['brave', 'new', 'world'] +# +# A test case for Bug #904208 +# "assert failed, when key cardinality is greater than index cardinality" +# https://bugs.launchpad.net/tarantool/+bug/904208 +# +call box.select(1, 1, 'new', 'world', 'order') +An error occurred: ER_KEY_CARDINALITY, 'Key cardinality 3 is greater than index cardinality 2' call box.delete(1, 'brave') Found 1 tuple: ['brave', 'new', 'world'] diff --git a/test/box_big/lua.test b/test/box_big/lua.test index 220fba99827287267e60ad19b3acfafdefc5d95c..6f6ae9891f1d3b2af0f58706ea260c8a54de8c0b 100644 --- a/test/box_big/lua.test +++ b/test/box_big/lua.test @@ -3,6 +3,12 @@ exec sql "insert into t1 values ('brave', 'new', 'world')" exec admin "lua box.space[1].index[1]:min()" exec admin "lua box.space[1].index[1]:max()" exec sql "call box.select(1, 1, 'new', 'world')" +print """# +# A test case for Bug #904208 +# "assert failed, when key cardinality is greater than index cardinality" +# https://bugs.launchpad.net/tarantool/+bug/904208 +#""" +exec sql "call box.select(1, 1, 'new', 'world', 'order')" exec sql "call box.delete(1, 'brave')" # diff --git a/test/lib/sql_ast.py b/test/lib/sql_ast.py index 2830a0330f39cd27cc13d2510e5eaeed230a8f8e..6e81abd6793bf517f045221100a69645c265bd66 100644 --- a/test/lib/sql_ast.py +++ b/test/lib/sql_ast.py @@ -49,6 +49,7 @@ ER = { 37: "ER_UPDATE_ID" , 38: "ER_WRONG_VERSION" , 39: "ER_WAL_IO" , + 47: "ER_KEY_CARDINALITY" , 48: "ER_PROC_RET" , 49: "ER_TUPLE_NOT_FOUND" , 50: "ER_NO_SUCH_PROC" ,