summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorIgor Babaev <igor@askmonty.org>2018-09-18 23:31:19 -0700
committerIgor Babaev <igor@askmonty.org>2018-09-18 23:31:19 -0700
commitd3f01f64f0e0031dd684f0c700c84b58568276d3 (patch)
tree49e97cedce31c3ab8a06fee3eefea3456885d754
parent809d8837ac6abd2b31a287927c978e41b0ddecf6 (diff)
downloadmariadb-git-d3f01f64f0e0031dd684f0c700c84b58568276d3.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.result52
-rw-r--r--mysql-test/r/stat_tables_innodb.result52
-rw-r--r--mysql-test/t/stat_tables.test39
-rw-r--r--sql/field.cc5
4 files changed, 101 insertions, 47 deletions
diff --git a/mysql-test/r/stat_tables.result b/mysql-test/r/stat_tables.result
index 0ee0d698bcc..279c09ff44f 100644
--- a/mysql-test/r/stat_tables.result
+++ b/mysql-test/r/stat_tables.result
@@ -518,6 +518,34 @@ drop database db2;
drop table t1;
set use_stat_tables=@save_use_stat_tables;
#
+# MDEV-16757: manual addition of min/max statistics for BLOB
+#
+SET use_stat_tables= PREFERABLY;
+CREATE TABLE t1 (pk INT PRIMARY KEY, t TEXT);
+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 Warning Engine-independent statistics are not collected for column 't'
+test.t1 analyze status OK
+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
+DELETE FROM mysql.column_stats
+WHERE db_name='test' AND table_name='t1' AND column_name='t';
+INSERT INTO mysql.column_stats VALUES
+('test','t1','t','bar','foo', 0.0, 3.0, 1.0, 0, NULL, NULL);
+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;
+#
# MDEV-16760: CREATE OR REPLACE TABLE after ANALYZE TABLE
#
SET use_stat_tables= PREFERABLY;
@@ -543,30 +571,18 @@ db_name table_name column_name min_value max_value nulls_ratio avg_length avg_fr
DROP TABLE t1;
set use_stat_tables=@save_use_stat_tables;
#
-# MDEV-16757: manual addition of min/max statistics for BLOB
+# MDEV-16711:CREATE OR REPLACE TABLE introducing BLOB column
#
SET use_stat_tables= PREFERABLY;
-CREATE TABLE t1 (pk INT PRIMARY KEY, t TEXT);
+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 Warning Engine-independent statistics are not collected for column 't'
test.t1 analyze status OK
-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
-DELETE FROM mysql.column_stats
-WHERE db_name='test' AND table_name='t1' AND column_name='t';
-INSERT INTO mysql.column_stats VALUES
-('test','t1','t','bar','foo', 0.0, 3.0, 1.0, 0, NULL, NULL);
-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
+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 b0319508ede..d551afdb282 100644
--- a/mysql-test/r/stat_tables_innodb.result
+++ b/mysql-test/r/stat_tables_innodb.result
@@ -545,6 +545,34 @@ drop database db2;
drop table t1;
set use_stat_tables=@save_use_stat_tables;
#
+# MDEV-16757: manual addition of min/max statistics for BLOB
+#
+SET use_stat_tables= PREFERABLY;
+CREATE TABLE t1 (pk INT PRIMARY KEY, t TEXT);
+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 Warning Engine-independent statistics are not collected for column 't'
+test.t1 analyze status OK
+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
+DELETE FROM mysql.column_stats
+WHERE db_name='test' AND table_name='t1' AND column_name='t';
+INSERT INTO mysql.column_stats VALUES
+('test','t1','t','bar','foo', 0.0, 3.0, 1.0, 0, NULL, NULL);
+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;
+#
# MDEV-16760: CREATE OR REPLACE TABLE after ANALYZE TABLE
#
SET use_stat_tables= PREFERABLY;
@@ -570,31 +598,19 @@ db_name table_name column_name min_value max_value nulls_ratio avg_length avg_fr
DROP TABLE t1;
set use_stat_tables=@save_use_stat_tables;
#
-# MDEV-16757: manual addition of min/max statistics for BLOB
+# MDEV-16711:CREATE OR REPLACE TABLE introducing BLOB column
#
SET use_stat_tables= PREFERABLY;
-CREATE TABLE t1 (pk INT PRIMARY KEY, t TEXT);
+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 Warning Engine-independent statistics are not collected for column 't'
test.t1 analyze status OK
-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
-DELETE FROM mysql.column_stats
-WHERE db_name='test' AND table_name='t1' AND column_name='t';
-INSERT INTO mysql.column_stats VALUES
-('test','t1','t','bar','foo', 0.0, 3.0, 1.0, 0, NULL, NULL);
-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
+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;
diff --git a/mysql-test/t/stat_tables.test b/mysql-test/t/stat_tables.test
index 7660acf6e42..cfe9255891a 100644
--- a/mysql-test/t/stat_tables.test
+++ b/mysql-test/t/stat_tables.test
@@ -308,6 +308,30 @@ drop table t1;
set use_stat_tables=@save_use_stat_tables;
--echo #
+--echo # MDEV-16757: manual addition of min/max statistics for BLOB
+--echo #
+
+SET use_stat_tables= PREFERABLY;
+
+CREATE TABLE t1 (pk INT PRIMARY KEY, t TEXT);
+INSERT INTO t1 VALUES (1,'foo'),(2,'bar');
+ANALYZE TABLE t1;
+--sorted_result
+SELECT * FROM mysql.column_stats;
+DELETE FROM mysql.column_stats
+ WHERE db_name='test' AND table_name='t1' AND column_name='t';
+INSERT INTO mysql.column_stats VALUES
+ ('test','t1','t','bar','foo', 0.0, 3.0, 1.0, 0, NULL, NULL);
+--sorted_result
+SELECT * FROM mysql.column_stats;
+
+SELECT pk FROM t1;
+
+DROP TABLE t1;
+
+set use_stat_tables=@save_use_stat_tables;
+
+--echo #
--echo # MDEV-16760: CREATE OR REPLACE TABLE after ANALYZE TABLE
--echo #
@@ -328,24 +352,17 @@ DROP TABLE t1;
set use_stat_tables=@save_use_stat_tables;
--echo #
---echo # MDEV-16757: manual addition of min/max statistics for BLOB
+--echo # MDEV-16711:CREATE OR REPLACE TABLE introducing BLOB column
--echo #
SET use_stat_tables= PREFERABLY;
-CREATE TABLE t1 (pk INT PRIMARY KEY, t TEXT);
+CREATE TABLE t1 (pk INT PRIMARY KEY, t CHAR(60));
INSERT INTO t1 VALUES (1,'foo'),(2,'bar');
ANALYZE TABLE t1;
---sorted_result
-SELECT * FROM mysql.column_stats;
-DELETE FROM mysql.column_stats
- WHERE db_name='test' AND table_name='t1' AND column_name='t';
-INSERT INTO mysql.column_stats VALUES
- ('test','t1','t','bar','foo', 0.0, 3.0, 1.0, 0, NULL, NULL);
---sorted_result
-SELECT * FROM mysql.column_stats;
+CREATE OR REPLACE TABLE t1 (pk INT PRIMARY KEY, t TEXT);
-SELECT pk FROM t1;
+SELECT MAX(pk) FROM t1;
DROP TABLE t1;
diff --git a/sql/field.cc b/sql/field.cc
index 50edec4a1db..f4717de7b35 100644
--- a/sql/field.cc
+++ b/sql/field.cc
@@ -7924,6 +7924,11 @@ int Field_blob::store(const char *from,uint length,CHARSET_INFO *cs)
return 0;
}
+ /*
+ 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));