mirror of
https://github.com/MariaDB/server.git
synced 2025-01-15 19:42:28 +01:00
MDEV-20589: Server still crashes in Field::set_warning_truncated_wrong_value
The flag is_stat_field is not set for the min_value and max_value of field items inside table share. This is a must requirement as we don't want to throw warnings of truncation when we read values from the statistics table to the column statistics of table share fields.
This commit is contained in:
parent
c471bfb34e
commit
273d8eb12c
6 changed files with 73 additions and 14 deletions
|
@ -802,5 +802,28 @@ set use_stat_tables=@save_use_stat_tables;
|
|||
set @@histogram_size= @save_histogram_size;
|
||||
set @@optimizer_use_condition_selectivity=@save_optimizer_use_condition_selectivity;
|
||||
drop table t1;
|
||||
#
|
||||
# MDEV-20589: Server still crashes in Field::set_warning_truncated_wrong_value
|
||||
#
|
||||
set names utf8;
|
||||
create table t1 ( a varchar(255) character set utf8);
|
||||
insert into t1 values (REPEAT('ӥ',255)), (REPEAT('ç',255));
|
||||
set use_stat_tables='preferably';
|
||||
analyze table t1 persistent for all;
|
||||
Table Op Msg_type Msg_text
|
||||
test.t1 analyze status Engine-independent statistics collected
|
||||
test.t1 analyze status OK
|
||||
set @save_sql_mode= @@sql_mode;
|
||||
set sql_mode='ERROR_FOR_DIVISION_BY_ZERO,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION';
|
||||
update mysql.column_stats set min_value= REPEAT('ӥ',256) where db_name='test' and table_name='t1';
|
||||
Warnings:
|
||||
Warning 1265 Data truncated for column 'min_value' at row 1
|
||||
set @@sql_mode= @save_sql_mode;
|
||||
select length(a) from t1 where a=REPEAT('ӥ',255);
|
||||
length(a)
|
||||
510
|
||||
set names latin1;
|
||||
set @@use_stat_tables=@save_use_stat_tables;
|
||||
drop table t1;
|
||||
# please keep this at the last
|
||||
set @@global.histogram_size=@save_histogram_size;
|
||||
|
|
|
@ -829,6 +829,29 @@ set use_stat_tables=@save_use_stat_tables;
|
|||
set @@histogram_size= @save_histogram_size;
|
||||
set @@optimizer_use_condition_selectivity=@save_optimizer_use_condition_selectivity;
|
||||
drop table t1;
|
||||
#
|
||||
# MDEV-20589: Server still crashes in Field::set_warning_truncated_wrong_value
|
||||
#
|
||||
set names utf8;
|
||||
create table t1 ( a varchar(255) character set utf8);
|
||||
insert into t1 values (REPEAT('ӥ',255)), (REPEAT('ç',255));
|
||||
set use_stat_tables='preferably';
|
||||
analyze table t1 persistent for all;
|
||||
Table Op Msg_type Msg_text
|
||||
test.t1 analyze status Engine-independent statistics collected
|
||||
test.t1 analyze status OK
|
||||
set @save_sql_mode= @@sql_mode;
|
||||
set sql_mode='ERROR_FOR_DIVISION_BY_ZERO,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION';
|
||||
update mysql.column_stats set min_value= REPEAT('ӥ',256) where db_name='test' and table_name='t1';
|
||||
Warnings:
|
||||
Warning 1265 Data truncated for column 'min_value' at row 1
|
||||
set @@sql_mode= @save_sql_mode;
|
||||
select length(a) from t1 where a=REPEAT('ӥ',255);
|
||||
length(a)
|
||||
510
|
||||
set names latin1;
|
||||
set @@use_stat_tables=@save_use_stat_tables;
|
||||
drop table t1;
|
||||
# please keep this at the last
|
||||
set @@global.histogram_size=@save_histogram_size;
|
||||
set optimizer_switch=@save_optimizer_switch_for_stat_tables_test;
|
||||
|
|
|
@ -546,5 +546,27 @@ set @@histogram_size= @save_histogram_size;
|
|||
set @@optimizer_use_condition_selectivity=@save_optimizer_use_condition_selectivity;
|
||||
drop table t1;
|
||||
|
||||
--echo #
|
||||
--echo # MDEV-20589: Server still crashes in Field::set_warning_truncated_wrong_value
|
||||
--echo #
|
||||
|
||||
set names utf8;
|
||||
create table t1 ( a varchar(255) character set utf8);
|
||||
insert into t1 values (REPEAT('ӥ',255)), (REPEAT('ç',255));
|
||||
|
||||
set use_stat_tables='preferably';
|
||||
analyze table t1 persistent for all;
|
||||
|
||||
set @save_sql_mode= @@sql_mode;
|
||||
set sql_mode='ERROR_FOR_DIVISION_BY_ZERO,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION';
|
||||
update mysql.column_stats set min_value= REPEAT('ӥ',256) where db_name='test' and table_name='t1';
|
||||
set @@sql_mode= @save_sql_mode;
|
||||
|
||||
select length(a) from t1 where a=REPEAT('ӥ',255);
|
||||
|
||||
set names latin1;
|
||||
set @@use_stat_tables=@save_use_stat_tables;
|
||||
drop table t1;
|
||||
|
||||
--echo # please keep this at the last
|
||||
set @@global.histogram_size=@save_histogram_size;
|
||||
|
|
14
sql/field.cc
14
sql/field.cc
|
@ -2436,14 +2436,14 @@ Field *Field::clone(MEM_ROOT *root, TABLE *new_table)
|
|||
}
|
||||
|
||||
|
||||
|
||||
Field *Field::clone(MEM_ROOT *root, TABLE *new_table, my_ptrdiff_t diff,
|
||||
bool stat_flag)
|
||||
{
|
||||
Field *tmp;
|
||||
if ((tmp= (Field*) memdup_root(root,(char*) this,size_of())))
|
||||
{
|
||||
tmp->init(new_table);
|
||||
if (new_table)
|
||||
tmp->init(new_table);
|
||||
tmp->move_field_offset(diff);
|
||||
}
|
||||
tmp->is_stat_field= stat_flag;
|
||||
|
@ -2451,16 +2451,6 @@ Field *Field::clone(MEM_ROOT *root, TABLE *new_table, my_ptrdiff_t diff,
|
|||
}
|
||||
|
||||
|
||||
Field *Field::clone(MEM_ROOT *root, my_ptrdiff_t diff)
|
||||
{
|
||||
Field *tmp;
|
||||
if ((tmp= (Field*) memdup_root(root,(char*) this,size_of())))
|
||||
{
|
||||
tmp->move_field_offset(diff);
|
||||
}
|
||||
return tmp;
|
||||
}
|
||||
|
||||
int Field::set_default()
|
||||
{
|
||||
if (default_value)
|
||||
|
|
|
@ -1220,7 +1220,6 @@ public:
|
|||
Field *clone(MEM_ROOT *mem_root, TABLE *new_table);
|
||||
Field *clone(MEM_ROOT *mem_root, TABLE *new_table, my_ptrdiff_t diff,
|
||||
bool stat_flag= FALSE);
|
||||
Field *clone(MEM_ROOT *mem_root, my_ptrdiff_t diff);
|
||||
inline void move_field(uchar *ptr_arg,uchar *null_ptr_arg,uchar null_bit_arg)
|
||||
{
|
||||
ptr=ptr_arg; null_ptr=null_ptr_arg; null_bit=null_bit_arg;
|
||||
|
|
|
@ -1153,12 +1153,14 @@ public:
|
|||
case COLUMN_STAT_MIN_VALUE:
|
||||
table_field->read_stats->min_value->set_notnull();
|
||||
stat_field->val_str(&val);
|
||||
DBUG_ASSERT(table_field->read_stats->min_value->is_stat_field);
|
||||
table_field->read_stats->min_value->store(val.ptr(), val.length(),
|
||||
&my_charset_bin);
|
||||
break;
|
||||
case COLUMN_STAT_MAX_VALUE:
|
||||
table_field->read_stats->max_value->set_notnull();
|
||||
stat_field->val_str(&val);
|
||||
DBUG_ASSERT(table_field->read_stats->min_value->is_stat_field);
|
||||
table_field->read_stats->max_value->store(val.ptr(), val.length(),
|
||||
&my_charset_bin);
|
||||
break;
|
||||
|
@ -2045,7 +2047,7 @@ void create_min_max_statistical_fields_for_table_share(THD *thd,
|
|||
Field *fld;
|
||||
Field *table_field= *field_ptr;
|
||||
my_ptrdiff_t diff= record - table_share->default_values;
|
||||
if (!(fld= table_field->clone(&stats_cb->mem_root, diff)))
|
||||
if (!(fld= table_field->clone(&stats_cb->mem_root, NULL, diff, TRUE)))
|
||||
continue;
|
||||
if (i == 0)
|
||||
table_field->read_stats->min_value= fld;
|
||||
|
|
Loading…
Reference in a new issue