MDEV-29954 Unique hash key on column prefix is computed incorrectly
use the original, not the truncated, field in the long unique prefix, that is, in the hash(left(field, length)) expression. because MyISAM CHECK/REPAIR in compute_vcols() moves table->field but not prefix fields from keyparts. Also, implement Field_string::cmp_prefix() for prefix comparison of CHAR columns to work.
This commit is contained in:
parent
14d00fdb15
commit
a7ee3bc58b
@ -651,5 +651,14 @@ f1 f2 f3 f4 f5 f6 f7
|
||||
4 00004 0001009089999 netstes psit e
|
||||
drop table t1;
|
||||
#
|
||||
# MDEV-29954 Unique hash key on column prefix is computed incorrectly
|
||||
#
|
||||
create table t1 (c char(10),unique key a using hash (c(1)));
|
||||
insert into t1 values (0);
|
||||
check table t1 extended;
|
||||
Table Op Msg_type Msg_text
|
||||
test.t1 check status OK
|
||||
drop table t1;
|
||||
#
|
||||
# End of 10.5 tests
|
||||
#
|
||||
|
@ -634,6 +634,14 @@ replace t1 (f2, f3, f4, f5, f6, f7) values ('00004', '0001009089999', '', 'netst
|
||||
select * from t1;
|
||||
drop table t1;
|
||||
|
||||
--echo #
|
||||
--echo # MDEV-29954 Unique hash key on column prefix is computed incorrectly
|
||||
--echo #
|
||||
create table t1 (c char(10),unique key a using hash (c(1)));
|
||||
insert into t1 values (0);
|
||||
check table t1 extended;
|
||||
drop table t1;
|
||||
|
||||
--echo #
|
||||
--echo # End of 10.5 tests
|
||||
--echo #
|
||||
|
13
sql/field.cc
13
sql/field.cc
@ -7566,6 +7566,19 @@ int Field_string::cmp(const uchar *a_ptr, const uchar *b_ptr) const
|
||||
}
|
||||
|
||||
|
||||
int Field_string::cmp_prefix(const uchar *a_ptr, const uchar *b_ptr,
|
||||
size_t prefix_char_len) const
|
||||
{
|
||||
size_t field_len= table->field[field_index]->field_length;
|
||||
|
||||
return field_charset()->coll->strnncollsp_nchars(field_charset(),
|
||||
a_ptr, field_len,
|
||||
b_ptr, field_len,
|
||||
prefix_char_len,
|
||||
0);
|
||||
}
|
||||
|
||||
|
||||
void Field_string::sort_string(uchar *to,uint length)
|
||||
{
|
||||
#ifdef DBUG_ASSERT_EXISTS
|
||||
|
@ -4038,6 +4038,8 @@ public:
|
||||
String *val_str(String *, String *) override;
|
||||
my_decimal *val_decimal(my_decimal *) override;
|
||||
int cmp(const uchar *,const uchar *) const override;
|
||||
int cmp_prefix(const uchar *a, const uchar *b, size_t prefix_char_len) const
|
||||
override;
|
||||
void sort_string(uchar *buff,uint length) override;
|
||||
void update_data_type_statistics(Data_type_statistics *st) const override
|
||||
{
|
||||
|
@ -605,7 +605,7 @@ int key_rec_cmp(void *key_p, uchar *first_rec, uchar *second_rec)
|
||||
}
|
||||
/*
|
||||
No null values in the fields
|
||||
We use the virtual method cmp_max with a max length parameter.
|
||||
We use the virtual method cmp_prefix with a max length parameter.
|
||||
For most field types this translates into a cmp without
|
||||
max length. The exceptions are the BLOB and VARCHAR field types
|
||||
that take the max length into account.
|
||||
|
@ -1272,12 +1272,11 @@ bool parse_vcol_defs(THD *thd, MEM_ROOT *mem_root, TABLE *table,
|
||||
if (keypart->key_part_flag & HA_PART_KEY_SEG)
|
||||
{
|
||||
int length= keypart->length/keypart->field->charset()->mbmaxlen;
|
||||
Field *kpf= table->field[keypart->field->field_index];
|
||||
list_item= new (mem_root) Item_func_left(thd,
|
||||
new (mem_root) Item_field(thd, keypart->field),
|
||||
new (mem_root) Item_field(thd, kpf),
|
||||
new (mem_root) Item_int(thd, length));
|
||||
list_item->fix_fields(thd, NULL);
|
||||
keypart->field->vcol_info=
|
||||
table->field[keypart->field->field_index]->vcol_info;
|
||||
}
|
||||
else
|
||||
list_item= new (mem_root) Item_field(thd, keypart->field);
|
||||
|
Loading…
x
Reference in New Issue
Block a user