-
Notifications
You must be signed in to change notification settings - Fork 387
Vinyl unique index by is_nullable = true
field loses tuples
#9769
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Comments
A more compact reproducer: local yaml = require('yaml')
box.cfg{log_level = 'error'}
local s = box.schema.space.create('space', {
engine = 'vinyl',
format = {
{ name = 'a', type = 'unsigned'},
{ name = 'b', type = 'unsigned', is_nullable = true},
},
})
s:create_index('primary', {parts = {'a'}})
s:create_index('secondary', {parts = {'b'}, unique = true})
s:insert({1, 10})
box.begin()
s:replace({1, 20})
s:insert({2, 10})
box.commit()
print(yaml.encode({
primary = s.index.primary:select({}, {fullscan = true}),
secondary = s.index.secondary:select({}, {fullscan = true}),
}))
os.exit(0) Output: ---
primary:
- [1, 20]
- [2, 10]
secondary:
- [1, 20]
... Notes: The problem disappears if any of the following changes is made:
|
locker
added a commit
to locker/tarantool
that referenced
this issue
May 16, 2024
A unique nullable key definition extended with primary key parts (cmp_def) assumes that two tuples are equal *without* comparing primary key fields if all secondary key fields are equal and not nulls, see tuple_compare_slowpath(). This is a hack required to ignore the uniqueness constraint for nulls in memtx. The memtx engine can't use the secondary key definition as is (key_def) for comparing tuples in the index tree, as it does for a non-nullable unique index, because this wouldn't allow insertion of any duplicates, including nulls. It couldn't use cmp_def without this hack, either, because then conflicting tuples with the same secondary key fields would always compare as not equal due to different primary key parts. For Vinyl, this hack isn't required because it explicitly skips the uniqueness check if any of the indexed fields are nulls, see vy_check_is_unique_secondary(). Furthermore, this hack is harmful because Vinyl relies on the fact that two tuples compare as equal by cmp_def if and only if *all* key fields (both secondary and primary) are equal. For example, this is used in the transaction manager, which overwrites statements equal by cmp_def, see vy_tx_set_entry(). Let's disable this hack by resetting unique_part_count in cmp_def. Closes tarantool#9769 NO_DOC=bug fix
locker
added a commit
that referenced
this issue
May 17, 2024
A unique nullable key definition extended with primary key parts (cmp_def) assumes that two tuples are equal *without* comparing primary key fields if all secondary key fields are equal and not nulls, see tuple_compare_slowpath(). This is a hack required to ignore the uniqueness constraint for nulls in memtx. The memtx engine can't use the secondary key definition as is (key_def) for comparing tuples in the index tree, as it does for a non-nullable unique index, because this wouldn't allow insertion of any duplicates, including nulls. It couldn't use cmp_def without this hack, either, because then conflicting tuples with the same secondary key fields would always compare as not equal due to different primary key parts. For Vinyl, this hack isn't required because it explicitly skips the uniqueness check if any of the indexed fields are nulls, see vy_check_is_unique_secondary(). Furthermore, this hack is harmful because Vinyl relies on the fact that two tuples compare as equal by cmp_def if and only if *all* key fields (both secondary and primary) are equal. For example, this is used in the transaction manager, which overwrites statements equal by cmp_def, see vy_tx_set_entry(). Let's disable this hack by resetting unique_part_count in cmp_def. Closes #9769 NO_DOC=bug fix
locker
added a commit
that referenced
this issue
May 17, 2024
A unique nullable key definition extended with primary key parts (cmp_def) assumes that two tuples are equal *without* comparing primary key fields if all secondary key fields are equal and not nulls, see tuple_compare_slowpath(). This is a hack required to ignore the uniqueness constraint for nulls in memtx. The memtx engine can't use the secondary key definition as is (key_def) for comparing tuples in the index tree, as it does for a non-nullable unique index, because this wouldn't allow insertion of any duplicates, including nulls. It couldn't use cmp_def without this hack, either, because then conflicting tuples with the same secondary key fields would always compare as not equal due to different primary key parts. For Vinyl, this hack isn't required because it explicitly skips the uniqueness check if any of the indexed fields are nulls, see vy_check_is_unique_secondary(). Furthermore, this hack is harmful because Vinyl relies on the fact that two tuples compare as equal by cmp_def if and only if *all* key fields (both secondary and primary) are equal. For example, this is used in the transaction manager, which overwrites statements equal by cmp_def, see vy_tx_set_entry(). Let's disable this hack by resetting unique_part_count in cmp_def. Closes #9769 NO_DOC=bug fix (cherry picked from commit 2e68906)
locker
added a commit
that referenced
this issue
May 17, 2024
A unique nullable key definition extended with primary key parts (cmp_def) assumes that two tuples are equal *without* comparing primary key fields if all secondary key fields are equal and not nulls, see tuple_compare_slowpath(). This is a hack required to ignore the uniqueness constraint for nulls in memtx. The memtx engine can't use the secondary key definition as is (key_def) for comparing tuples in the index tree, as it does for a non-nullable unique index, because this wouldn't allow insertion of any duplicates, including nulls. It couldn't use cmp_def without this hack, either, because then conflicting tuples with the same secondary key fields would always compare as not equal due to different primary key parts. For Vinyl, this hack isn't required because it explicitly skips the uniqueness check if any of the indexed fields are nulls, see vy_check_is_unique_secondary(). Furthermore, this hack is harmful because Vinyl relies on the fact that two tuples compare as equal by cmp_def if and only if *all* key fields (both secondary and primary) are equal. For example, this is used in the transaction manager, which overwrites statements equal by cmp_def, see vy_tx_set_entry(). Let's disable this hack by resetting unique_part_count in cmp_def. Closes #9769 NO_DOC=bug fix (cherry picked from commit 2e68906)
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
reproduced with
3.0.1-0-g31c2ddb
,2.11.2-0-g1bac2d257b
Out:
Expected: index (3 line) doesn't lose tuple
Works correctly when
is_nullable = false
,engine = "memtx"
or with other transaction combinations:The text was updated successfully, but these errors were encountered:
8000