diff --git a/src/box/tuple_format.c b/src/box/tuple_format.c index 1d6499748db996ea9812180b3ea9e37ff66bf574..f0eca24bb32e490f316206df89ae7fb6d79f3bb0 100644 --- a/src/box/tuple_format.c +++ b/src/box/tuple_format.c @@ -93,11 +93,16 @@ tuple_format_create(struct tuple_format *format, struct key_def * const *keys, /* * Check that there are no conflicts * between index part types and space - * fields. + * fields. If a part type is compatible + * with field's one, then the part type is + * more strict and the part type must be + * used in tuple_format. */ - if (field->type == FIELD_TYPE_ANY) { + if (field_type1_contains_type2(field->type, + part->type)) { field->type = part->type; - } else if (field->type != part->type) { + } else if (! field_type1_contains_type2(part->type, + field->type)) { const char *name; int fieldno = part->fieldno + TUPLE_INDEX_BASE; if (part->fieldno >= field_count) { diff --git a/test/box/alter.result b/test/box/alter.result index e69dbc6ecfc07ca712cfb52f636a838e0d30578c..eaf79f1d0a8cdfc1ffb83aee4a0ca8d3f1097364 100644 --- a/test/box/alter.result +++ b/test/box/alter.result @@ -896,11 +896,6 @@ sk1 = s:create_index('sk1', { parts = { 2, 'unsigned' } }) - error: Field 'field2' has type 'string' in space format, but type 'unsigned' in index definition ... -sk2 = s:create_index('sk2', { parts = { 3, 'number' } }) ---- -- error: Field 'field3' has type 'scalar' in space format, but type 'number' in index - definition -... -- Check space format conflicting with index parts. sk3 = s:create_index('sk3', { parts = { 2, 'string' } }) --- @@ -1952,6 +1947,190 @@ s:drop() --- ... -- +-- gh-3008: allow multiple types on the same field. +-- +format = {} +--- +... +format[1] = {name = 'field1', type = 'unsigned'} +--- +... +format[2] = {name = 'field2', type = 'scalar'} +--- +... +format[3] = {name = 'field3', type = 'integer'} +--- +... +s = box.schema.create_space('test', {format = format}) +--- +... +pk = s:create_index('pk') +--- +... +sk1 = s:create_index('sk1', {parts = {{2, 'number'}}}) +--- +... +sk2 = s:create_index('sk2', {parts = {{2, 'integer'}}}) +--- +... +sk3 = s:create_index('sk3', {parts = {{2, 'unsigned'}}}) +--- +... +sk4 = s:create_index('sk4', {parts = {{3, 'number'}}}) +--- +... +s:format() +--- +- [{'name': 'field1', 'type': 'unsigned'}, {'name': 'field2', 'type': 'scalar'}, { + 'name': 'field3', 'type': 'integer'}] +... +s:replace{1, '100', -20.2} +--- +- error: 'Tuple field 2 type does not match one required by operation: expected unsigned' +... +s:replace{1, 100, -20.2} +--- +- error: 'Tuple field 3 type does not match one required by operation: expected integer' +... +s:replace{1, 100, -20} +--- +- [1, 100, -20] +... +s:replace{2, 50, 0} +--- +- [2, 50, 0] +... +s:replace{3, 150, -60} +--- +- [3, 150, -60] +... +s:replace{4, 0, 120} +--- +- [4, 0, 120] +... +pk:select{} +--- +- - [1, 100, -20] + - [2, 50, 0] + - [3, 150, -60] + - [4, 0, 120] +... +sk1:select{} +--- +- - [4, 0, 120] + - [2, 50, 0] + - [1, 100, -20] + - [3, 150, -60] +... +sk2:select{} +--- +- - [4, 0, 120] + - [2, 50, 0] + - [1, 100, -20] + - [3, 150, -60] +... +sk3:select{} +--- +- - [4, 0, 120] + - [2, 50, 0] + - [1, 100, -20] + - [3, 150, -60] +... +sk4:select{} +--- +- - [3, 150, -60] + - [1, 100, -20] + - [2, 50, 0] + - [4, 0, 120] +... +sk1:alter{parts = {{2, 'unsigned'}}} +--- +... +sk2:alter{parts = {{2, 'unsigned'}}} +--- +... +sk4:alter{parts = {{3, 'integer'}}} +--- +... +s:replace{1, 50.5, 1.5} +--- +- error: 'Tuple field 2 type does not match one required by operation: expected unsigned' +... +s:replace{1, 50, 1.5} +--- +- error: 'Tuple field 3 type does not match one required by operation: expected integer' +... +s:replace{5, 5, 5} +--- +- [5, 5, 5] +... +sk1:select{} +--- +- - [4, 0, 120] + - [5, 5, 5] + - [2, 50, 0] + - [1, 100, -20] + - [3, 150, -60] +... +sk2:select{} +--- +- - [4, 0, 120] + - [5, 5, 5] + - [2, 50, 0] + - [1, 100, -20] + - [3, 150, -60] +... +sk3:select{} +--- +- - [4, 0, 120] + - [5, 5, 5] + - [2, 50, 0] + - [1, 100, -20] + - [3, 150, -60] +... +sk4:select{} +--- +- - [3, 150, -60] + - [1, 100, -20] + - [2, 50, 0] + - [5, 5, 5] + - [4, 0, 120] +... +sk1:drop() +--- +... +sk2:drop() +--- +... +sk3:drop() +--- +... +-- Remove 'unsigned' constraints from indexes, and 'scalar' now +-- can be inserted in the second field. +s:replace{1, true, 100} +--- +- [1, true, 100] +... +s:select{} +--- +- - [1, true, 100] + - [2, 50, 0] + - [3, 150, -60] + - [4, 0, 120] + - [5, 5, 5] +... +sk4:select{} +--- +- - [3, 150, -60] + - [2, 50, 0] + - [5, 5, 5] + - [1, true, 100] + - [4, 0, 120] +... +s:drop() +--- +... +-- -- gh-2914: Allow any space name which consists of printable characters -- identifier = require("identifier") diff --git a/test/box/alter.test.lua b/test/box/alter.test.lua index 0050ecd12a4698f0aecaf6341ab8826fa486ff79..eb0739aad930f4ebd15c8540817053ced474fd08 100644 --- a/test/box/alter.test.lua +++ b/test/box/alter.test.lua @@ -344,7 +344,6 @@ format = { { name='field1', type='unsigned' }, { name='field2', type='string' }, s = box.schema.space.create('test', { format = format }) pk = s:create_index('pk') sk1 = s:create_index('sk1', { parts = { 2, 'unsigned' } }) -sk2 = s:create_index('sk2', { parts = { 3, 'number' } }) -- Check space format conflicting with index parts. sk3 = s:create_index('sk3', { parts = { 2, 'string' } }) @@ -747,6 +746,53 @@ sk1:select{} sk2:select{} s:drop() +-- +-- gh-3008: allow multiple types on the same field. +-- +format = {} +format[1] = {name = 'field1', type = 'unsigned'} +format[2] = {name = 'field2', type = 'scalar'} +format[3] = {name = 'field3', type = 'integer'} +s = box.schema.create_space('test', {format = format}) +pk = s:create_index('pk') +sk1 = s:create_index('sk1', {parts = {{2, 'number'}}}) +sk2 = s:create_index('sk2', {parts = {{2, 'integer'}}}) +sk3 = s:create_index('sk3', {parts = {{2, 'unsigned'}}}) +sk4 = s:create_index('sk4', {parts = {{3, 'number'}}}) +s:format() +s:replace{1, '100', -20.2} +s:replace{1, 100, -20.2} +s:replace{1, 100, -20} +s:replace{2, 50, 0} +s:replace{3, 150, -60} +s:replace{4, 0, 120} +pk:select{} +sk1:select{} +sk2:select{} +sk3:select{} +sk4:select{} + +sk1:alter{parts = {{2, 'unsigned'}}} +sk2:alter{parts = {{2, 'unsigned'}}} +sk4:alter{parts = {{3, 'integer'}}} +s:replace{1, 50.5, 1.5} +s:replace{1, 50, 1.5} +s:replace{5, 5, 5} +sk1:select{} +sk2:select{} +sk3:select{} +sk4:select{} + +sk1:drop() +sk2:drop() +sk3:drop() +-- Remove 'unsigned' constraints from indexes, and 'scalar' now +-- can be inserted in the second field. +s:replace{1, true, 100} +s:select{} +sk4:select{} +s:drop() + -- -- gh-2914: Allow any space name which consists of printable characters --