summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorIgor Babaev <igor@askmonty.org>2018-07-15 18:40:25 -0700
committerIgor Babaev <igor@askmonty.org>2018-07-15 18:40:25 -0700
commitb75d819604bbb6c461e6363e331bd6bd1ba7a787 (patch)
tree300a1f237cf381270569f0d9697c759e11979f3d
parentae0eb507bda858a13475faef4476dd496c4dbc01 (diff)
downloadmariadb-git-b75d819604bbb6c461e6363e331bd6bd1ba7a787.tar.gz
MDEV-16711 Crash in Field_blob::store() while reading statistics
for the small InnoDB table This bug was introduced by the patch 6c414fcf89510215d6d3466eb9992d444eadae89. 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.
-rw-r--r--mysql-test/r/stat_tables.result20
-rw-r--r--mysql-test/r/stat_tables_innodb.result20
-rw-r--r--mysql-test/t/stat_tables.test20
-rw-r--r--sql/field.cc8
4 files changed, 66 insertions, 2 deletions
diff --git a/mysql-test/r/stat_tables.result b/mysql-test/r/stat_tables.result
index 1f1cad10c23..279c09ff44f 100644
--- a/mysql-test/r/stat_tables.result
+++ b/mysql-test/r/stat_tables.result
@@ -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;
#
@@ -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;
diff --git a/mysql-test/r/stat_tables_innodb.result b/mysql-test/r/stat_tables_innodb.result
index fc1ecdf66c4..1604c413743 100644
--- a/mysql-test/r/stat_tables_innodb.result
+++ b/mysql-test/r/stat_tables_innodb.result
@@ -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;
#
@@ -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;
diff --git a/mysql-test/t/stat_tables.test b/mysql-test/t/stat_tables.test
index b98ca641dc0..51c9995b6fa 100644
--- a/mysql-test/t/stat_tables.test
+++ b/mysql-test/t/stat_tables.test
@@ -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;
@@ -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;
diff --git a/sql/field.cc b/sql/field.cc
index 64c51677c0f..71fc5684d92 100644
--- a/sql/field.cc
+++ b/sql/field.cc
@@ -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);