summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorIgor Babaev <igor@askmonty.org>2019-05-28 23:26:36 -0700
committerIgor Babaev <igor@askmonty.org>2019-05-28 23:26:36 -0700
commitcbb90f77cdbf57c02145dc6cd86acf8ebb8a88f0 (patch)
treedd5a613a38a95a9a4f05144ac10e1b96c945a6ab
parenteb09580b67ee19f7ac30c1a41c8307b9c7d482d1 (diff)
downloadmariadb-git-cbb90f77cdbf57c02145dc6cd86acf8ebb8a88f0.tar.gz
MDEV-18479 Complement
This patch complements the patch that fixes bug MDEV-18479. This patch takes care of possible overflow when calculating the estimated number of rows in a materialized derived table / view.
-rw-r--r--include/my_base.h1
-rw-r--r--mysql-test/r/derived_view.result20
-rw-r--r--mysql-test/t/derived_view.test2
-rw-r--r--sql/sql_lex.cc5
-rw-r--r--sql/sql_select.cc21
5 files changed, 29 insertions, 20 deletions
diff --git a/include/my_base.h b/include/my_base.h
index 54e8443d86c..86be94399d6 100644
--- a/include/my_base.h
+++ b/include/my_base.h
@@ -586,6 +586,7 @@ typedef ulong ha_rows;
#define HA_POS_ERROR (~ (ha_rows) 0)
#define HA_OFFSET_ERROR (~ (my_off_t) 0)
+#define HA_ROWS_MAX HA_POS_ERROR
#if SYSTEM_SIZEOF_OFF_T == 4
#define MAX_FILE_SIZE INT_MAX32
diff --git a/mysql-test/r/derived_view.result b/mysql-test/r/derived_view.result
index ab363934e8f..d74b532d5e8 100644
--- a/mysql-test/r/derived_view.result
+++ b/mysql-test/r/derived_view.result
@@ -2641,7 +2641,7 @@ DROP TABLE t1, t2;
set optimizer_switch=@exit_optimizer_switch;
set join_cache_level=@exit_join_cache_level;
#
-# Bug mdev-12812: EXPLAIN for query with many expensive derived
+# Bug mdev-18479: EXPLAIN for query with many expensive derived
#
CREATE TABLE t1
(id int auto_increment primary key,
@@ -2942,15 +2942,15 @@ id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE p10 ALL NULL NULL NULL NULL 550 Using where; Using join buffer (incremental, BNL join)
1 SIMPLE <derived17> ALL NULL NULL NULL NULL 50328437500000 Using where; Using join buffer (incremental, BNL join)
1 SIMPLE <derived14> ALL NULL NULL NULL NULL 27680640625000000 Using where; Using join buffer (incremental, BNL join)
-1 SIMPLE <derived7> ALL NULL NULL NULL NULL 7798774269472204288 Using where; Using join buffer (incremental, BNL join)
-1 SIMPLE <derived8> ALL NULL NULL NULL NULL 7798774269472204288 Using where; Using join buffer (incremental, BNL join)
-1 SIMPLE <derived9> ALL NULL NULL NULL NULL -3222391729959551616 Using where; Using join buffer (incremental, BNL join)
-1 SIMPLE <derived10> ALL NULL NULL NULL NULL -3222391729959551616 Using where; Using join buffer (incremental, BNL join)
-1 SIMPLE <derived11> ALL NULL NULL NULL NULL -3222391729959551616 Using where; Using join buffer (incremental, BNL join)
-1 SIMPLE <derived12> ALL NULL NULL NULL NULL -3222391729959551616 Using where; Using join buffer (incremental, BNL join)
-1 SIMPLE <derived13> ALL NULL NULL NULL NULL -3222391729959551616 Using where; Using join buffer (incremental, BNL join)
-1 SIMPLE <derived15> ALL NULL NULL NULL NULL -3222391729959551616 Using where; Using join buffer (incremental, BNL join)
-1 SIMPLE <derived16> ALL NULL NULL NULL NULL -3222391729959551616 Using where; Using join buffer (incremental, BNL join)
+1 SIMPLE <derived9> ALL NULL NULL NULL NULL 9223372036854775807 Using where; Using join buffer (incremental, BNL join)
+1 SIMPLE <derived10> ALL NULL NULL NULL NULL 9223372036854775807 Using where; Using join buffer (incremental, BNL join)
+1 SIMPLE <derived11> ALL NULL NULL NULL NULL 9223372036854775807 Using where; Using join buffer (incremental, BNL join)
+1 SIMPLE <derived12> ALL NULL NULL NULL NULL 9223372036854775807 Using where; Using join buffer (incremental, BNL join)
+1 SIMPLE <derived13> ALL NULL NULL NULL NULL 9223372036854775807 Using where; Using join buffer (incremental, BNL join)
+1 SIMPLE <derived15> ALL NULL NULL NULL NULL 9223372036854775807 Using where; Using join buffer (incremental, BNL join)
+1 SIMPLE <derived16> ALL NULL NULL NULL NULL 9223372036854775807 Using where; Using join buffer (incremental, BNL join)
+1 SIMPLE <derived7> ALL NULL NULL NULL NULL 9223372036854775807 Using where; Using join buffer (incremental, BNL join)
+1 SIMPLE <derived8> ALL NULL NULL NULL NULL 9223372036854775807 Using where; Using join buffer (incremental, BNL join)
17 DERIVED t2 system NULL NULL NULL NULL 1
17 DERIVED p4 ALL NULL NULL NULL NULL 550 Using where
17 DERIVED p5 ALL NULL NULL NULL NULL 550 Using where; Using join buffer (flat, BNL join)
diff --git a/mysql-test/t/derived_view.test b/mysql-test/t/derived_view.test
index f6613e2593a..61c4278b43f 100644
--- a/mysql-test/t/derived_view.test
+++ b/mysql-test/t/derived_view.test
@@ -1936,7 +1936,7 @@ set optimizer_switch=@exit_optimizer_switch;
set join_cache_level=@exit_join_cache_level;
--echo #
---echo # Bug mdev-12812: EXPLAIN for query with many expensive derived
+--echo # Bug mdev-18479: EXPLAIN for query with many expensive derived
--echo #
CREATE TABLE t1
diff --git a/sql/sql_lex.cc b/sql/sql_lex.cc
index 3e20cdb48da..28f56282bad 100644
--- a/sql/sql_lex.cc
+++ b/sql/sql_lex.cc
@@ -4100,7 +4100,10 @@ void SELECT_LEX::increase_derived_records(ha_rows records)
DBUG_ASSERT(unit->derived);
select_union *result= (select_union*)unit->result;
- result->records+= records;
+ if (HA_ROWS_MAX - records > result->records)
+ result->records+= records;
+ else
+ result->records= HA_ROWS_MAX;
}
diff --git a/sql/sql_select.cc b/sql/sql_select.cc
index 961a7dac265..37f8292b563 100644
--- a/sql/sql_select.cc
+++ b/sql/sql_select.cc
@@ -3830,7 +3830,7 @@ make_join_statistics(JOIN *join, List<TABLE_LIST> &tables_list,
DBUG_RETURN(TRUE); /* purecov: inspected */
{
- ha_rows records= 1;
+ double records= 1;
SELECT_LEX_UNIT *unit= join->select_lex->master_unit();
/* Find an optimal join order of the non-constant tables. */
@@ -3855,10 +3855,14 @@ make_join_statistics(JOIN *join, List<TABLE_LIST> &tables_list,
table/view.
*/
for (i= 0; i < join->table_count ; i++)
- records*= join->best_positions[i].records_read ?
- (ha_rows)join->best_positions[i].records_read : 1;
- set_if_smaller(records, unit->select_limit_cnt);
- join->select_lex->increase_derived_records(records);
+ {
+ records= COST_MULT(records,
+ join->best_positions[i].records_read ?
+ join->best_positions[i].records_read : 1);
+ }
+ ha_rows rows= records > HA_ROWS_MAX ? HA_ROWS_MAX : (ha_rows) records;
+ set_if_smaller(rows, unit->select_limit_cnt);
+ join->select_lex->increase_derived_records(rows);
}
}
@@ -10795,7 +10799,7 @@ ha_rows JOIN_TAB::get_examined_rows()
}
}
else
- examined_rows= (ha_rows) records_read;
+ examined_rows= (ha_rows) records_read;
return examined_rows;
}
@@ -22924,8 +22928,9 @@ static void select_describe(JOIN *join, bool need_tmp_table, bool need_order,
else
{
ha_rows examined_rows= tab->get_examined_rows();
-
- item_list.push_back(new Item_int((longlong) (ulonglong) examined_rows,
+ ha_rows displ_rows= examined_rows;
+ set_if_smaller(displ_rows, HA_ROWS_MAX/2);
+ item_list.push_back(new Item_int((longlong) (ulonglong) displ_rows,
MY_INT64_NUM_DECIMAL_DIGITS));
/* Add "filtered" field to item_list. */