Skip to content

Commit

Permalink
MDEV-16711 Crash in Field_blob::store() while reading statistics
Browse files Browse the repository at this point in the history
          for the small InnoDB table

This bug was introduced by the patch 6c414fc.
The patch has not taken into account that some objects of the Field_* types
are created only for TABLE_SHARE and the field 'table' is set to NULL
for them. In particular such are objects created to store statistical
min/max values for columns.
  • Loading branch information
igorbabaev committed Jul 16, 2018
1 parent ae0eb50 commit b75d819
Show file tree
Hide file tree
Showing 4 changed files with 66 additions and 2 deletions.
20 changes: 20 additions & 0 deletions mysql-test/r/stat_tables.result
Expand Up @@ -539,6 +539,10 @@ SELECT * FROM mysql.column_stats;
db_name table_name column_name min_value max_value nulls_ratio avg_length avg_frequency hist_size hist_type histogram
test t1 pk 1 2 0.0000 4.0000 1.0000 0 NULL NULL
test t1 t bar foo 0.0000 3.0000 1.0000 0 NULL NULL
SELECT pk FROM t1;
pk
1
2
DROP TABLE t1;
set use_stat_tables=@save_use_stat_tables;
#
Expand Down Expand Up @@ -566,3 +570,19 @@ SELECT * FROM mysql.column_stats;
db_name table_name column_name min_value max_value nulls_ratio avg_length avg_frequency hist_size hist_type histogram
DROP TABLE t1;
set use_stat_tables=@save_use_stat_tables;
#
# MDEV-16711:CREATE OR REPLACE TABLE introducing BLOB column
#
SET use_stat_tables= PREFERABLY;
CREATE TABLE t1 (pk INT PRIMARY KEY, t CHAR(60));
INSERT INTO t1 VALUES (1,'foo'),(2,'bar');
ANALYZE TABLE t1;
Table Op Msg_type Msg_text
test.t1 analyze status Engine-independent statistics collected
test.t1 analyze status OK
CREATE OR REPLACE TABLE t1 (pk INT PRIMARY KEY, t TEXT);
SELECT MAX(pk) FROM t1;
MAX(pk)
NULL
DROP TABLE t1;
set use_stat_tables=@save_use_stat_tables;
20 changes: 20 additions & 0 deletions mysql-test/r/stat_tables_innodb.result
Expand Up @@ -566,6 +566,10 @@ SELECT * FROM mysql.column_stats;
db_name table_name column_name min_value max_value nulls_ratio avg_length avg_frequency hist_size hist_type histogram
test t1 pk 1 2 0.0000 4.0000 1.0000 0 NULL NULL
test t1 t bar foo 0.0000 3.0000 1.0000 0 NULL NULL
SELECT pk FROM t1;
pk
1
2
DROP TABLE t1;
set use_stat_tables=@save_use_stat_tables;
#
Expand Down Expand Up @@ -593,5 +597,21 @@ SELECT * FROM mysql.column_stats;
db_name table_name column_name min_value max_value nulls_ratio avg_length avg_frequency hist_size hist_type histogram
DROP TABLE t1;
set use_stat_tables=@save_use_stat_tables;
#
# MDEV-16711:CREATE OR REPLACE TABLE introducing BLOB column
#
SET use_stat_tables= PREFERABLY;
CREATE TABLE t1 (pk INT PRIMARY KEY, t CHAR(60));
INSERT INTO t1 VALUES (1,'foo'),(2,'bar');
ANALYZE TABLE t1;
Table Op Msg_type Msg_text
test.t1 analyze status Engine-independent statistics collected
test.t1 analyze status OK
CREATE OR REPLACE TABLE t1 (pk INT PRIMARY KEY, t TEXT);
SELECT MAX(pk) FROM t1;
MAX(pk)
NULL
DROP TABLE t1;
set use_stat_tables=@save_use_stat_tables;
set optimizer_switch=@save_optimizer_switch_for_stat_tables_test;
SET SESSION STORAGE_ENGINE=DEFAULT;
20 changes: 19 additions & 1 deletion mysql-test/t/stat_tables.test
Expand Up @@ -325,7 +325,7 @@ INSERT INTO mysql.column_stats VALUES
--sorted_result
SELECT * FROM mysql.column_stats;

# SELECT pk FROM t1;
SELECT pk FROM t1;

DROP TABLE t1;

Expand All @@ -350,3 +350,21 @@ SELECT * FROM mysql.column_stats;
DROP TABLE t1;

set use_stat_tables=@save_use_stat_tables;


--echo #
--echo # MDEV-16711:CREATE OR REPLACE TABLE introducing BLOB column
--echo #

SET use_stat_tables= PREFERABLY;

CREATE TABLE t1 (pk INT PRIMARY KEY, t CHAR(60));
INSERT INTO t1 VALUES (1,'foo'),(2,'bar');
ANALYZE TABLE t1;
CREATE OR REPLACE TABLE t1 (pk INT PRIMARY KEY, t TEXT);

SELECT MAX(pk) FROM t1;

DROP TABLE t1;

set use_stat_tables=@save_use_stat_tables;
8 changes: 7 additions & 1 deletion sql/field.cc
Expand Up @@ -7942,7 +7942,13 @@ int Field_blob::store(const char *from,uint length,CHARSET_INFO *cs)
return 0;
}

if (table->blob_storage) // GROUP_CONCAT with ORDER BY | DISTINCT
/*
For min/max fields of statistical data 'table' is set to NULL.
It could not be otherwise as this data is shared by many instances
of the same base table.
*/

if (table && table->blob_storage) // GROUP_CONCAT with ORDER BY | DISTINCT
{
DBUG_ASSERT(!f_is_hex_escape(flags));
DBUG_ASSERT(field_charset == cs);
Expand Down

0 comments on commit b75d819

Please sign in to comment.