summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--mysql-test/r/stat_tables.result57
-rw-r--r--mysql-test/r/stat_tables_innodb.result57
-rw-r--r--mysql-test/t/stat_tables.test40
-rw-r--r--sql/field.cc7
-rw-r--r--sql/sql_statistics.cc10
5 files changed, 166 insertions, 5 deletions
diff --git a/mysql-test/r/stat_tables.result b/mysql-test/r/stat_tables.result
index 3ebc3b47833..be868e55e84 100644
--- a/mysql-test/r/stat_tables.result
+++ b/mysql-test/r/stat_tables.result
@@ -624,4 +624,61 @@ SELECT MAX(pk) FROM t1;
MAX(pk)
NULL
DROP TABLE t1;
+#
+# MDEV-18899: Server crashes in Field::set_warning_truncated_wrong_value
+#
+set names utf8;
+set @save_optimizer_use_condition_selectivity=@@optimizer_use_condition_selectivity;
+set optimizer_use_condition_selectivity=4;
+set use_stat_tables=preferably;
+set @save_histogram_size= @@histogram_size;
+set histogram_size=255;
+create table t1 ( a varchar(255) character set utf8);
+insert into t1 values (REPEAT('ӥ',255)), (REPEAT('ç',255));
+analyze table t1;
+Table Op Msg_type Msg_text
+test.t1 analyze status Engine-independent statistics collected
+test.t1 analyze status OK
+select HEX(RIGHT(min_value, 1)), length(min_value) from mysql.column_stats where db_name='test' and table_name='t1';
+HEX(RIGHT(min_value, 1)) length(min_value)
+A7 254
+select HEX(RIGHT(max_value, 1)), length(max_value) from mysql.column_stats where db_name='test' and table_name='t1';
+HEX(RIGHT(max_value, 1)) length(max_value)
+A5 254
+analyze select * from t1 where a >= 'ӥ';
+id select_type table type possible_keys key key_len ref rows r_rows filtered r_filtered Extra
+1 SIMPLE t1 ALL NULL NULL NULL NULL 2 2.00 50.00 50.00 Using where
+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('ӥ',255) where db_name='test' and table_name='t1';
+Warnings:
+Warning 1265 Data truncated for column 'min_value' at row 1
+select HEX(RIGHT(min_value, 1)), length(min_value) from mysql.column_stats where db_name='test' and table_name='t1';
+HEX(RIGHT(min_value, 1)) length(min_value)
+D3 255
+analyze select * from t1 where a >= 'ӥ';
+id select_type table type possible_keys key key_len ref rows r_rows filtered r_filtered Extra
+1 SIMPLE t1 ALL NULL NULL NULL NULL 2 2.00 50.00 50.00 Using where
+set names latin1;
+drop table t1;
+CREATE TABLE t1 (col1 date);
+INSERT INTO t1 VALUES('2004-01-01'),('2004-02-29');
+INSERT INTO t1 VALUES('0000-10-31');
+analyze table t1;
+Table Op Msg_type Msg_text
+test.t1 analyze status Engine-independent statistics collected
+test.t1 analyze status OK
+update mysql.column_stats set min_value='2004-0-31123' where db_name='test' and table_name='t1';
+select min_value from mysql.column_stats where db_name='test' and table_name='t1';
+min_value
+2004-0-31123
+select * from t1;
+col1
+2004-01-01
+2004-02-29
+0000-10-31
+drop table t1;
+set @@sql_mode= @save_sql_mode;
set use_stat_tables=@save_use_stat_tables;
+set @@histogram_size= @save_histogram_size;
+set @@optimizer_use_condition_selectivity=@save_optimizer_use_condition_selectivity;
diff --git a/mysql-test/r/stat_tables_innodb.result b/mysql-test/r/stat_tables_innodb.result
index a6c5525a0d3..86088490871 100644
--- a/mysql-test/r/stat_tables_innodb.result
+++ b/mysql-test/r/stat_tables_innodb.result
@@ -651,6 +651,63 @@ SELECT MAX(pk) FROM t1;
MAX(pk)
NULL
DROP TABLE t1;
+#
+# MDEV-18899: Server crashes in Field::set_warning_truncated_wrong_value
+#
+set names utf8;
+set @save_optimizer_use_condition_selectivity=@@optimizer_use_condition_selectivity;
+set optimizer_use_condition_selectivity=4;
+set use_stat_tables=preferably;
+set @save_histogram_size= @@histogram_size;
+set histogram_size=255;
+create table t1 ( a varchar(255) character set utf8);
+insert into t1 values (REPEAT('ӥ',255)), (REPEAT('ç',255));
+analyze table t1;
+Table Op Msg_type Msg_text
+test.t1 analyze status Engine-independent statistics collected
+test.t1 analyze status OK
+select HEX(RIGHT(min_value, 1)), length(min_value) from mysql.column_stats where db_name='test' and table_name='t1';
+HEX(RIGHT(min_value, 1)) length(min_value)
+A7 254
+select HEX(RIGHT(max_value, 1)), length(max_value) from mysql.column_stats where db_name='test' and table_name='t1';
+HEX(RIGHT(max_value, 1)) length(max_value)
+A5 254
+analyze select * from t1 where a >= 'ӥ';
+id select_type table type possible_keys key key_len ref rows r_rows filtered r_filtered Extra
+1 SIMPLE t1 ALL NULL NULL NULL NULL 2 2.00 50.00 50.00 Using where
+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('ӥ',255) where db_name='test' and table_name='t1';
+Warnings:
+Warning 1265 Data truncated for column 'min_value' at row 1
+select HEX(RIGHT(min_value, 1)), length(min_value) from mysql.column_stats where db_name='test' and table_name='t1';
+HEX(RIGHT(min_value, 1)) length(min_value)
+D3 255
+analyze select * from t1 where a >= 'ӥ';
+id select_type table type possible_keys key key_len ref rows r_rows filtered r_filtered Extra
+1 SIMPLE t1 ALL NULL NULL NULL NULL 2 2.00 50.00 50.00 Using where
+set names latin1;
+drop table t1;
+CREATE TABLE t1 (col1 date);
+INSERT INTO t1 VALUES('2004-01-01'),('2004-02-29');
+INSERT INTO t1 VALUES('0000-10-31');
+analyze table t1;
+Table Op Msg_type Msg_text
+test.t1 analyze status Engine-independent statistics collected
+test.t1 analyze status OK
+update mysql.column_stats set min_value='2004-0-31123' where db_name='test' and table_name='t1';
+select min_value from mysql.column_stats where db_name='test' and table_name='t1';
+min_value
+2004-0-31123
+select * from t1;
+col1
+2004-01-01
+2004-02-29
+0000-10-31
+drop table t1;
+set @@sql_mode= @save_sql_mode;
set use_stat_tables=@save_use_stat_tables;
+set @@histogram_size= @save_histogram_size;
+set @@optimizer_use_condition_selectivity=@save_optimizer_use_condition_selectivity;
set optimizer_switch=@save_optimizer_switch_for_stat_tables_test;
SET SESSION STORAGE_ENGINE=DEFAULT;
diff --git a/mysql-test/t/stat_tables.test b/mysql-test/t/stat_tables.test
index b89ab2bbd2d..89c11ed4acf 100644
--- a/mysql-test/t/stat_tables.test
+++ b/mysql-test/t/stat_tables.test
@@ -401,4 +401,44 @@ SELECT MAX(pk) FROM t1;
DROP TABLE t1;
+--echo #
+--echo # MDEV-18899: Server crashes in Field::set_warning_truncated_wrong_value
+--echo #
+
+set names utf8;
+set @save_optimizer_use_condition_selectivity=@@optimizer_use_condition_selectivity;
+set optimizer_use_condition_selectivity=4;
+set use_stat_tables=preferably;
+set @save_histogram_size= @@histogram_size;
+set histogram_size=255;
+
+create table t1 ( a varchar(255) character set utf8);
+insert into t1 values (REPEAT('ӥ',255)), (REPEAT('ç',255));
+
+analyze table t1;
+select HEX(RIGHT(min_value, 1)), length(min_value) from mysql.column_stats where db_name='test' and table_name='t1';
+select HEX(RIGHT(max_value, 1)), length(max_value) from mysql.column_stats where db_name='test' and table_name='t1';
+analyze select * from t1 where a >= 'ӥ';
+
+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('ӥ',255) where db_name='test' and table_name='t1';
+select HEX(RIGHT(min_value, 1)), length(min_value) from mysql.column_stats where db_name='test' and table_name='t1';
+analyze select * from t1 where a >= 'ӥ';
+
+set names latin1;
+drop table t1;
+
+CREATE TABLE t1 (col1 date);
+INSERT INTO t1 VALUES('2004-01-01'),('2004-02-29');
+INSERT INTO t1 VALUES('0000-10-31');
+analyze table t1;
+update mysql.column_stats set min_value='2004-0-31123' where db_name='test' and table_name='t1';
+select min_value from mysql.column_stats where db_name='test' and table_name='t1';
+select * from t1;
+drop table t1;
+
+set @@sql_mode= @save_sql_mode;
set use_stat_tables=@save_use_stat_tables;
+set @@histogram_size= @save_histogram_size;
+set @@optimizer_use_condition_selectivity=@save_optimizer_use_condition_selectivity;
diff --git a/sql/field.cc b/sql/field.cc
index 080cf34c76d..0621015c0e4 100644
--- a/sql/field.cc
+++ b/sql/field.cc
@@ -7027,8 +7027,11 @@ Field_longstr::check_string_copy_error(const String_copier *copier,
if (!(pos= copier->most_important_error_pos()))
return FALSE;
- convert_to_printable(tmp, sizeof(tmp), pos, (end - pos), cs, 6);
- set_warning_truncated_wrong_value("string", tmp);
+ if (!is_stat_field)
+ {
+ convert_to_printable(tmp, sizeof(tmp), pos, (end - pos), cs, 6);
+ set_warning_truncated_wrong_value("string", tmp);
+ }
return TRUE;
}
diff --git a/sql/sql_statistics.cc b/sql/sql_statistics.cc
index b5811c683e8..0a51346adb2 100644
--- a/sql/sql_statistics.cc
+++ b/sql/sql_statistics.cc
@@ -1060,7 +1060,9 @@ public:
else
{
table_field->collected_stats->min_value->val_str(&val);
- stat_field->store(val.ptr(), val.length(), &my_charset_bin);
+ uint32 length= Well_formed_prefix(val.charset(), val.ptr(),
+ MY_MIN(val.length(), stat_field->field_length)).length();
+ stat_field->store(val.ptr(), length, &my_charset_bin);
}
break;
case COLUMN_STAT_MAX_VALUE:
@@ -1069,7 +1071,9 @@ public:
else
{
table_field->collected_stats->max_value->val_str(&val);
- stat_field->store(val.ptr(), val.length(), &my_charset_bin);
+ uint32 length= Well_formed_prefix(val.charset(), val.ptr(),
+ MY_MIN(val.length(), stat_field->field_length)).length();
+ stat_field->store(val.ptr(), length, &my_charset_bin);
}
break;
case COLUMN_STAT_NULLS_RATIO:
@@ -3059,7 +3063,7 @@ int read_statistics_for_table(THD *thd, TABLE *table, TABLE_LIST *stat_tables)
}
}
}
-
+
table->stats_is_read= TRUE;
DBUG_RETURN(0);