1
0
mirror of https://github.com/MariaDB/server.git synced 2025-08-01 03:47:19 +03:00

MDEV-31247 Assertion `c >= 0' failed in COST_MULT upon query with many joins

Problem was an overflow when calculating number of join cache refills.
This commit is contained in:
Monty
2023-05-27 14:39:17 +03:00
parent 209fed8eed
commit 661141948f
4 changed files with 131 additions and 3 deletions

View File

@ -0,0 +1,38 @@
#
# MDEV-31247 Assertion `c >= 0' failed in COST_MULT upon query with
# many joins
#
CREATE TABLE t1 (a INT) ENGINE=MyISAM;
INSERT INTO t1 VALUES (1),(2);
CREATE TABLE t2 (b INT) ENGINE=MyISAM;
CREATE TABLE t3 (c INT) ENGINE=MyISAM;
INSERT INTO t3 VALUES (1),(2),(3);
CREATE TABLE t4 (d CHAR(200), e INT, KEY(e)) ENGINE=Aria;
INSERT INTO t4 (e) VALUES (1),(2),(3);
CREATE TABLE t5 (f INT) ENGINE=MyISAM;
INSERT INTO t5 VALUES (1),(2),(3),(4),(5),(6);
create table t1000 engine=memory select seq from seq_1_to_1000;
create table t2000 engine=memory select seq from seq_1_to_2000;
CREATE ALGORITHM=TEMPTABLE VIEW v AS select t1000.seq
from t1000 ml1
join t1000 ml2
join t1000;
set @@max_statement_time=10;
SELECT * FROM information_schema.TABLES
JOIN t1000 ts
JOIN t1000 d1
JOIN t2000 d3
LEFT JOIN (t1 JOIN t2) ON 1
JOIN t1000 d5
JOIN t1000 PROCESSLIST
JOIN t1000 d2
JOIN t1000 event_name
JOIN t3
JOIN t4 ON ts.seq = t4.e
JOIN v ON ts.seq+1 = v.seq
JOIN t5 limit rows examined 1000;
TABLE_CATALOG TABLE_SCHEMA TABLE_NAME TABLE_TYPE ENGINE VERSION ROW_FORMAT TABLE_ROWS AVG_ROW_LENGTH DATA_LENGTH MAX_DATA_LENGTH INDEX_LENGTH DATA_FREE AUTO_INCREMENT CREATE_TIME UPDATE_TIME CHECK_TIME TABLE_COLLATION CHECKSUM CREATE_OPTIONS TABLE_COMMENT MAX_INDEX_LENGTH TEMPORARY seq seq seq a b seq seq seq seq c d e seq f
Warnings:
Warning 1931 Query execution was interrupted. The query examined at least ### rows, which exceeds LIMIT ROWS EXAMINED (1000). The query result may be incomplete
DROP VIEW v;
DROP TABLE t1, t2, t3, t4, t5, t1000, t2000;

View File

@ -0,0 +1,48 @@
--source include/have_innodb.inc
--source include/have_sequence.inc
--echo #
--echo # MDEV-31247 Assertion `c >= 0' failed in COST_MULT upon query with
--echo # many joins
--echo #
CREATE TABLE t1 (a INT) ENGINE=MyISAM;
INSERT INTO t1 VALUES (1),(2);
CREATE TABLE t2 (b INT) ENGINE=MyISAM;
CREATE TABLE t3 (c INT) ENGINE=MyISAM;
INSERT INTO t3 VALUES (1),(2),(3);
CREATE TABLE t4 (d CHAR(200), e INT, KEY(e)) ENGINE=Aria;
INSERT INTO t4 (e) VALUES (1),(2),(3);
CREATE TABLE t5 (f INT) ENGINE=MyISAM;
INSERT INTO t5 VALUES (1),(2),(3),(4),(5),(6);
create table t1000 engine=memory select seq from seq_1_to_1000;
create table t2000 engine=memory select seq from seq_1_to_2000;
CREATE ALGORITHM=TEMPTABLE VIEW v AS select t1000.seq
from t1000 ml1
join t1000 ml2
join t1000;
set @@max_statement_time=10;
--replace_regex /least \d* rows/least ### rows/
SELECT * FROM information_schema.TABLES
JOIN t1000 ts
JOIN t1000 d1
JOIN t2000 d3
LEFT JOIN (t1 JOIN t2) ON 1
JOIN t1000 d5
JOIN t1000 PROCESSLIST
JOIN t1000 d2
JOIN t1000 event_name
JOIN t3
JOIN t4 ON ts.seq = t4.e
JOIN v ON ts.seq+1 = v.seq
JOIN t5 limit rows examined 1000;
# Cleanup
DROP VIEW v;
DROP TABLE t1, t2, t3, t4, t5, t1000, t2000;

View File

@ -3783,4 +3783,44 @@ DROP TABLE t1;
set global innodb_stats_persistent= @innodb_stats_persistent_save;
set global innodb_stats_persistent_sample_pages=
@innodb_stats_persistent_sample_pages_save;
#
# MDEV-31258 Assertion `cond_selectivity <= 1.000000001' upon range
# query
#
CREATE TABLE t1 (id int, a int, b char(3), PRIMARY KEY (id), KEY idx (a,b)) ENGINE=InnoDB;
INSERT INTO t1 VALUES
(1,8,'UT'),(2,0,'NU'),(3,1,'SD'),(4,0,'QU'),(5,0,'FL'),(6,0,'ZR'),
(7,3,'LA'),(8,5,'NU'),(9,0,'NU'),(10,0,'SD'),(11,0,'NU'),(12,1,'SD'),
(13,0,'BD'),(14,0,'PA'),(15,0,'VT'),(16,4,'WA'),(17,0,'ME'),(18,6,'OH'),
(19,0,'ME'),(20,4,'NU'),(21,0,'SC'),(22,0,'GA'),(23,1,'CO'),(24,0,'IL'),
(25,0,'GA'),(26,0,'HI'),(27,0,'BU'),(28,0,'NU'),(29,7,'LA'),(30,0,'NU'),
(31,0,'JR'),(32,6,'BR'),(33,0,'NU'),(34,6,'CO'),(35,7,'NU'),(36,2,'LA'),
(37,0,'PR'),(38,1,'UT'),(39,2,'BR'),(40,1,'HI'),(41,0,'SD'),(42,0,'RI'),
(43,2,'LA'),(44,0,'TN'),(45,4,'HI'),(46,0,'VT'),(47,1,'NU'),(48,0,'SC'),
(49,0,'TX'),(50,8,'DC'),(51,4,'NU'),(52,0,'AL'),(53,0,'CO'),(54,9,'PR'),
(55,0,'AR'),(56,0,'SD'),(57,0,'RI'),(58,0,'XE'),(59,0,'NU'),(60,4,'EL'),
(61,2,'LA'),(62,5,'UT'),(63,3,'NU'),(64,0,'RI'),(65,1,'NU'),(66,0,'BR'),
(67,3,'WA'),(68,0,'TN'),(69,3,'HI'),(70,0,'OH'),(71,8,'GA'),(72,6,'AL'),
(73,6,'NU'),(74,1,'HI'),(75,5,'JR'),(76,3,'RI'),(77,0,'DC'),(78,0,'SC'),
(79,0,'CO'),(80,2,'BO'),(81,8,'XE'),(82,1,'NU'),(83,0,'SD'),(84,0,'PA'),
(85,5,'PA'),(86,0,'QU'),(87,0,'PA'),(88,0,'NU'),(89,0,'ND'),(90,0,'UT'),
(91,0,'NU'),(92,0,'NU'),(93,6,'ZR'),(94,0,'NU'),(95,2,'EL'),(96,0,'NU'),
(97,0,'RI'),(98,5,'DC'),(99,7,'JR'),(100,5,'CO'),(101,0,'UT'),(102,0,'QU'),
(103,0,'NU'),(104,0,'GA'),(105,7,'AK'),(106,0,'ZR'),(107,0,'YT'),(108,0,'MD'),
(109,0,'NU'),(110,1,'EL'),(111,0,'ME'),(112,0,'VT'),(113,2,'NU'),(114,0,'CO'),
(115,5,'TN'),(116,0,'OH'),(117,0,'GA'),(118,9,'GA'),(119,0,'CO'),(120,0,'AL'),
(121,0,'NU'),(122,2,'NE'),(123,2,'TX'),(124,3,'CO'),(125,0,'TN'),(126,0,'WA'),
(127,0,'NE'),(128,6,'TN'),(129,0,'BR'),(130,0,'ID'),(131,0,'NU'),(132,2,'EL'),
(133,0,'PR'),(134,0,'NU'),(135,1,'AZ'),(136,7,'EL'),(137,0,'TN'),(138,0,'PA'),
(139,5,'QU'),(140,0,'AR'),(141,0,'DC'),(142,2,'WA'),(143,7,'OH'),(144,2,'CO'),
(145,6,'NU'),(146,9,'FL'),(147,0,'HI'),(148,0,'WA'),(149,1,'BR'),(150,3,'QU');
SELECT id, MIN(id) FROM t1
WHERE (b > 'TX' OR b BETWEEN 'NE' AND 'SC') AND id IN (1,7,8) AND a = 5
GROUP BY id;
id MIN(id)
8 8
DROP TABLE t1;
#
# End of 11.0 tests
#
set optimizer_switch=@mrr_icp_extra_tmp;

View File

@ -104,6 +104,8 @@
#define double_to_rows(A) ((A) >= ((double)HA_ROWS_MAX) ? HA_ROWS_MAX : (ha_rows) (A))
#define double_to_ulonglong(A) ((A) >= ((double)ULONGLONG_MAX) ? ULONGLONG_MAX : (ulonglong) (A))
inline double safe_filtered(double a, double b)
{
return b != 0 ? a/b*100.0 : 0.0;
@ -9168,7 +9170,7 @@ best_access_path(JOIN *join,
best.use_join_buffer= TRUE;
best.filter= 0;
best.type= JT_HASH;
best.refills= (ulonglong) ceil(refills);
best.refills= double_to_ulonglong(ceil(refills));
if (unlikely(trace_access_hash.trace_started()))
trace_access_hash.
add("type", "hash").
@ -9443,7 +9445,7 @@ best_access_path(JOIN *join,
(record_count /
(double) thd->variables.join_buff_size)));
cur_cost= COST_MULT(cur_cost, tmp_refills);
refills= (ulonglong) tmp_refills;
refills= double_to_ulonglong(ceil(tmp_refills));
/* We come here only if there are already rows in the join cache */
DBUG_ASSERT(idx != join->const_tables);
@ -9523,7 +9525,7 @@ best_access_path(JOIN *join,
/* range/index_merge/ALL/index access method are "independent", so: */
best.ref_depends_map= 0;
best.use_join_buffer= use_join_buffer;
best.refills= (ulonglong) ceil(refills);
best.refills= refills;
best.spl_plan= 0;
best.type= type;
trace_access_scan.add("chosen", true);