From 00fa5b86768f819de5aab5c381c931fb67a59385 Mon Sep 17 00:00:00 2001 From: Dave Gosselin Date: Tue, 4 Feb 2025 13:42:18 -0500 Subject: [PATCH] MDEV-35721 UBSAN: runtime error: -nan outside range Prevent division by zero when reading table statistics --- mysql-test/main/mdev-35721-ubsan.result | 21 +++++++++++++++++++++ mysql-test/main/mdev-35721-ubsan.test | 22 ++++++++++++++++++++++ sql/sql_statistics.cc | 2 +- 3 files changed, 44 insertions(+), 1 deletion(-) create mode 100644 mysql-test/main/mdev-35721-ubsan.result create mode 100644 mysql-test/main/mdev-35721-ubsan.test diff --git a/mysql-test/main/mdev-35721-ubsan.result b/mysql-test/main/mdev-35721-ubsan.result new file mode 100644 index 00000000000..8a3e61ad6ac --- /dev/null +++ b/mysql-test/main/mdev-35721-ubsan.result @@ -0,0 +1,21 @@ +CREATE TABLE t (c1 VARCHAR(10),c2 VARCHAR(10),PRIMARY KEY(c1,c2),FULLTEXT KEY k (c2)) ENGINE=InnoDB; +INSERT INTO t VALUES ('a','b'); +DROP TABLE t; +CREATE TABLE t (c1 VARCHAR(10),c2 VARCHAR(10),PRIMARY KEY(c1,c2),FULLTEXT KEY k (c2)) ENGINE=InnoDB; +DELETE FROM t; +DROP TABLE t; +CREATE TABLE t (a INT(1),d INT(1),b VARCHAR(1),c CHAR(1),c3 INT(1) GENERATED ALWAYS AS ((a + LENGTH (d))) STORED,c2 CHAR(1) GENERATED ALWAYS AS (SUBSTR(b,0,0)) VIRTUAL,k1 CHAR(1) GENERATED ALWAYS AS (SUBSTR(b,0,0)) VIRTUAL,PRIMARY KEY(b (1),a,d),KEY d (d),KEY a (a),KEY c_renamed (c (1),b (1)),KEY b (b (1),c (1),a),KEY k1 (k1),KEY a_2 (a,k1),KEY k1_2 (k1,d)) DEFAULT CHARSET=latin1 ENGINE=InnoDB; +DELETE FROM t; +DROP TABLE t; +CREATE TABLE t (a INT,ROW_START TIMESTAMP(6) AS ROW START,ROW_END TIMESTAMP(6) AS ROW END,PERIOD FOR SYSTEM_TIME(ROW_START,ROW_END),INDEX (ROW_START),INDEX (ROW_END),PRIMARY KEY(ROW_END,a,ROW_START),INDEX (ROW_END,ROW_START,a)) WITH SYSTEM VERSIONING ENGINE=InnoDB; +SHOW INDEX FROM t; +Table Non_unique Key_name Seq_in_index Column_name Collation Cardinality Sub_part Packed Null Index_type Comment Index_comment Ignored +t 0 PRIMARY 1 ROW_END A 0 NULL NULL BTREE NO +t 0 PRIMARY 2 a A 0 NULL NULL BTREE NO +t 0 PRIMARY 3 ROW_START A 0 NULL NULL BTREE NO +t 1 ROW_START 1 ROW_START A 0 NULL NULL BTREE NO +t 1 ROW_END 1 ROW_END A 0 NULL NULL BTREE NO +t 1 ROW_END_2 1 ROW_END A 0 NULL NULL BTREE NO +t 1 ROW_END_2 2 ROW_START A 0 NULL NULL BTREE NO +t 1 ROW_END_2 3 a A 0 NULL NULL BTREE NO +DROP TABLE t; diff --git a/mysql-test/main/mdev-35721-ubsan.test b/mysql-test/main/mdev-35721-ubsan.test new file mode 100644 index 00000000000..24f580f82b4 --- /dev/null +++ b/mysql-test/main/mdev-35721-ubsan.test @@ -0,0 +1,22 @@ + +--source include/have_innodb.inc + +CREATE TABLE t (c1 VARCHAR(10),c2 VARCHAR(10),PRIMARY KEY(c1,c2),FULLTEXT KEY k (c2)) ENGINE=InnoDB; +INSERT INTO t VALUES ('a','b'); + +DROP TABLE t; + +CREATE TABLE t (c1 VARCHAR(10),c2 VARCHAR(10),PRIMARY KEY(c1,c2),FULLTEXT KEY k (c2)) ENGINE=InnoDB; +DELETE FROM t; + +DROP TABLE t; + +CREATE TABLE t (a INT(1),d INT(1),b VARCHAR(1),c CHAR(1),c3 INT(1) GENERATED ALWAYS AS ((a + LENGTH (d))) STORED,c2 CHAR(1) GENERATED ALWAYS AS (SUBSTR(b,0,0)) VIRTUAL,k1 CHAR(1) GENERATED ALWAYS AS (SUBSTR(b,0,0)) VIRTUAL,PRIMARY KEY(b (1),a,d),KEY d (d),KEY a (a),KEY c_renamed (c (1),b (1)),KEY b (b (1),c (1),a),KEY k1 (k1),KEY a_2 (a,k1),KEY k1_2 (k1,d)) DEFAULT CHARSET=latin1 ENGINE=InnoDB; +DELETE FROM t; + +DROP TABLE t; + +CREATE TABLE t (a INT,ROW_START TIMESTAMP(6) AS ROW START,ROW_END TIMESTAMP(6) AS ROW END,PERIOD FOR SYSTEM_TIME(ROW_START,ROW_END),INDEX (ROW_START),INDEX (ROW_END),PRIMARY KEY(ROW_END,a,ROW_START),INDEX (ROW_END,ROW_START,a)) WITH SYSTEM VERSIONING ENGINE=InnoDB; +SHOW INDEX FROM t; + +DROP TABLE t; diff --git a/sql/sql_statistics.cc b/sql/sql_statistics.cc index 163cb8da9fc..de4bdeeaa31 100644 --- a/sql/sql_statistics.cc +++ b/sql/sql_statistics.cc @@ -3139,7 +3139,7 @@ read_statistics_for_table(THD *thd, TABLE *table, double avg_frequency= pk_read_stats->get_avg_frequency(j-1); set_if_smaller(avg_frequency, 1); double val= (pk_read_stats->get_avg_frequency(j) / - avg_frequency); + avg_frequency > 0 ? avg_frequency : 1); index_statistics->set_avg_frequency (l, val); } }