diff --git a/mysql-test/main/mdev_40698.result b/mysql-test/main/mdev_40698.result new file mode 100644 index 0000000000000..3c51bf2d37d84 --- /dev/null +++ b/mysql-test/main/mdev_40698.result @@ -0,0 +1,54 @@ +# +# MDEV-40698: ROLLUP query returns incorrect result with empty result set +# +CREATE TABLE t0(a INT, b INT, c INT); +SELECT *, COUNT(0) FROM t0 GROUP BY a, b, c WITH ROLLUP; +a b c COUNT(0) +NULL NULL NULL 0 +SELECT *, COUNT(0) FROM t0 WHERE 1=0 GROUP BY a, b, c WITH ROLLUP; +a b c COUNT(0) +NULL NULL NULL 0 +SELECT *, COUNT(0), ROW_NUMBER() OVER () FROM t0 GROUP BY a, b, c WITH ROLLUP; +a b c COUNT(0) ROW_NUMBER() OVER () +NULL NULL NULL 0 1 +SELECT 1 IN (SELECT a FROM t0 WHERE a>0 GROUP BY a WITH ROLLUP); +1 IN (SELECT a FROM t0 WHERE a>0 GROUP BY a WITH ROLLUP) +NULL +INSERT INTO t0 VALUES (0, 0, 0),(0, 0, 0); +SELECT *, COUNT(0) FROM t0 WHERE a > 0 GROUP BY a, b, c WITH ROLLUP; +a b c COUNT(0) +NULL NULL NULL 0 +SELECT EXISTS (SELECT t0.a FROM t0 x WHERE 1=0 GROUP BY x.a WITH ROLLUP) AS e +FROM t0; +e +1 +1 +SELECT DISTINCT a FROM t0 GROUP BY a, b WITH ROLLUP; +a +0 +NULL +CREATE TABLE t1 (a INT, b INT, c INT) ENGINE=InnoDB; +SELECT *, COUNT(0) FROM t1 GROUP BY a, b, c WITH ROLLUP; +a b c COUNT(0) +NULL NULL NULL 0 +SELECT *, COUNT(0) FROM t1 WHERE 1=0 GROUP BY a, b, c WITH ROLLUP; +a b c COUNT(0) +NULL NULL NULL 0 +SELECT *, COUNT(0), ROW_NUMBER() OVER () FROM t1 GROUP BY a, b, c WITH ROLLUP; +a b c COUNT(0) ROW_NUMBER() OVER () +NULL NULL NULL 0 1 +INSERT INTO t1 VALUES (0, 0, 0),(0, 0, 0); +SELECT *, COUNT(0) FROM t1 WHERE a > 0 GROUP BY a, b, c WITH ROLLUP; +a b c COUNT(0) +NULL NULL NULL 0 +SELECT EXISTS (SELECT t1.a FROM t1 x WHERE 1=0 GROUP BY x.a WITH ROLLUP) AS e +FROM t1; +e +1 +1 +SELECT DISTINCT a FROM t1 GROUP BY a, b WITH ROLLUP; +a +0 +NULL +DROP TABLE t0, t1; +# End of 10.11 tests diff --git a/mysql-test/main/mdev_40698.test b/mysql-test/main/mdev_40698.test new file mode 100644 index 0000000000000..dfe7a0fe68bdb --- /dev/null +++ b/mysql-test/main/mdev_40698.test @@ -0,0 +1,30 @@ +--source include/have_innodb.inc + +--echo # +--echo # MDEV-40698: ROLLUP query returns incorrect result with empty result set +--echo # + +CREATE TABLE t0(a INT, b INT, c INT); +SELECT *, COUNT(0) FROM t0 GROUP BY a, b, c WITH ROLLUP; +SELECT *, COUNT(0) FROM t0 WHERE 1=0 GROUP BY a, b, c WITH ROLLUP; +SELECT *, COUNT(0), ROW_NUMBER() OVER () FROM t0 GROUP BY a, b, c WITH ROLLUP; +SELECT 1 IN (SELECT a FROM t0 WHERE a>0 GROUP BY a WITH ROLLUP); +INSERT INTO t0 VALUES (0, 0, 0),(0, 0, 0); +SELECT *, COUNT(0) FROM t0 WHERE a > 0 GROUP BY a, b, c WITH ROLLUP; +SELECT EXISTS (SELECT t0.a FROM t0 x WHERE 1=0 GROUP BY x.a WITH ROLLUP) AS e + FROM t0; +SELECT DISTINCT a FROM t0 GROUP BY a, b WITH ROLLUP; + +CREATE TABLE t1 (a INT, b INT, c INT) ENGINE=InnoDB; +SELECT *, COUNT(0) FROM t1 GROUP BY a, b, c WITH ROLLUP; +SELECT *, COUNT(0) FROM t1 WHERE 1=0 GROUP BY a, b, c WITH ROLLUP; +SELECT *, COUNT(0), ROW_NUMBER() OVER () FROM t1 GROUP BY a, b, c WITH ROLLUP; +INSERT INTO t1 VALUES (0, 0, 0),(0, 0, 0); +SELECT *, COUNT(0) FROM t1 WHERE a > 0 GROUP BY a, b, c WITH ROLLUP; +SELECT EXISTS (SELECT t1.a FROM t1 x WHERE 1=0 GROUP BY x.a WITH ROLLUP) AS e + FROM t1; +SELECT DISTINCT a FROM t1 GROUP BY a, b WITH ROLLUP; + +DROP TABLE t0, t1; + +--echo # End of 10.11 tests diff --git a/mysql-test/main/ps_error.result b/mysql-test/main/ps_error.result index ad178f869155a..f3fa78a1bbe36 100644 --- a/mysql-test/main/ps_error.result +++ b/mysql-test/main/ps_error.result @@ -10,6 +10,7 @@ EXECUTE stmt; ERROR 22007: Truncated incorrect DOUBLE value: 'foo' SELECT a FROM t1 GROUP BY NULL WITH ROLLUP; a +NULL DROP TABLE t1; SET sql_mode=DEFAULT; SET SQL_MODE= 'STRICT_ALL_TABLES'; diff --git a/mysql-test/main/win.result b/mysql-test/main/win.result index 8f38c424ddf9c..7891c737dfd43 100644 --- a/mysql-test/main/win.result +++ b/mysql-test/main/win.result @@ -3503,6 +3503,7 @@ id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE NULL NULL NULL NULL NULL NULL NULL Impossible WHERE noticed after reading const tables select distinct 1, row_number() over (order by 1) from t1 where a=0 group by a with rollup; 1 row_number() over (order by 1) +1 1 drop table t1; explain SELECT DISTINCT BIT_OR(100) OVER () FROM dual diff --git a/mysql-test/suite/encryption/r/tempfiles_encrypted.result b/mysql-test/suite/encryption/r/tempfiles_encrypted.result index aff2b9306aa73..f856ff1a465f1 100644 --- a/mysql-test/suite/encryption/r/tempfiles_encrypted.result +++ b/mysql-test/suite/encryption/r/tempfiles_encrypted.result @@ -3509,6 +3509,7 @@ id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE NULL NULL NULL NULL NULL NULL NULL Impossible WHERE noticed after reading const tables select distinct 1, row_number() over (order by 1) from t1 where a=0 group by a with rollup; 1 row_number() over (order by 1) +1 1 drop table t1; explain SELECT DISTINCT BIT_OR(100) OVER () FROM dual diff --git a/sql/opt_subselect.cc b/sql/opt_subselect.cc index d02a7678073af..5a99526a3ab79 100644 --- a/sql/opt_subselect.cc +++ b/sql/opt_subselect.cc @@ -6805,7 +6805,7 @@ bool JOIN::choose_tableless_subquery_plan() */ if (zero_result_cause) { - if (!implicit_grouping) + if (!implicit_grouping && select_lex->olap != ROLLUP_TYPE) { /* Both group by queries and non-group by queries without aggregate diff --git a/sql/sql_select.cc b/sql/sql_select.cc index f0ef090d25059..183c29a933930 100644 --- a/sql/sql_select.cc +++ b/sql/sql_select.cc @@ -16825,6 +16825,10 @@ return_zero_rows(JOIN *join, select_result *result, List *tables, join->thd->set_examined_row_count(0); join->thd->limit_found_rows= 0; } + else + { + join->thd->limit_found_rows= send_row ? 1 : 0; + } if (!(result->send_result_set_metadata(*fields, Protocol::SEND_NUM_ROWS | Protocol::SEND_EOF))) @@ -24711,6 +24715,7 @@ end_send_group(JOIN *join, JOIN_TAB *join_tab, bool end_of_records) join->fields. */ List *fields= join_tab ? (join_tab-1)->fields : join->fields; + bool empty_set_send_rollup_total= false; DBUG_ENTER("end_send_group"); if (!join->items3.is_null() && !join->set_group_rpa) @@ -24726,7 +24731,8 @@ end_send_group(JOIN *join, JOIN_TAB *join_tab, bool end_of_records) if (!join->group_sent && (join->first_record || - (end_of_records && !join->group && !join->group_optimized_away))) + join->need_empty_set_row(end_of_records, + &empty_set_send_rollup_total))) { table_map cleared_tables= (table_map) 0; if (join->procedure) @@ -24782,7 +24788,8 @@ end_send_group(JOIN *join, JOIN_TAB *join_tab, bool end_of_records) join->send_records++; join->group_sent= true; } - if (unlikely(join->rollup.state != ROLLUP::STATE_NONE && error <= 0)) + if (unlikely(join->rollup.state != ROLLUP::STATE_NONE && + !empty_set_send_rollup_total && error <= 0)) { if (join->rollup_send_data((uint) (idx+1))) error= 1; @@ -25103,13 +25110,15 @@ end_write_group(JOIN *join, JOIN_TAB *join_tab __attribute__((unused)), { TABLE *table= join_tab->table; int idx= -1; + bool empty_set_send_rollup_total= false; DBUG_ENTER("end_write_group"); join->accepted_rows++; if (!join->first_record || end_of_records || (idx=test_if_group_changed(join->group_fields)) >= 0) { - if (join->first_record || (end_of_records && !join->group)) + if (join->first_record || + join->need_empty_set_row(end_of_records, &empty_set_send_rollup_total)) { table_map cleared_tables= (table_map) 0; if (join->procedure) @@ -25134,7 +25143,8 @@ end_write_group(JOIN *join, JOIN_TAB *join_tab __attribute__((unused)), error, 0, NULL)) DBUG_RETURN(NESTED_LOOP_ERROR); } - if (unlikely(join->rollup.state != ROLLUP::STATE_NONE)) + if (unlikely(join->rollup.state != ROLLUP::STATE_NONE && + !empty_set_send_rollup_total)) { if (unlikely(join->rollup_write_data((uint) (idx+1), join_tab->tmp_table_param, diff --git a/sql/sql_select.h b/sql/sql_select.h index 1c607883be91e..d03edab058186 100644 --- a/sql/sql_select.h +++ b/sql/sql_select.h @@ -1746,12 +1746,27 @@ class JOIN :public Sql_alloc void cleanup(bool full); void clear(table_map *cleared_tables); void inline clear_sum_funcs(); + bool need_empty_set_row(bool end_of_records, + bool *empty_set_send_rollup_total) const + { + *empty_set_send_rollup_total= + end_of_records && !first_record && rollup.state != ROLLUP::STATE_NONE; + return (end_of_records && !first_record && !group && + !group_optimized_away) || + *empty_set_send_rollup_total; + } bool send_row_on_empty_set() { - return (do_send_rows && implicit_grouping && !group_optimized_away && + return (do_send_rows && + (select_lex->olap == ROLLUP_TYPE || + (implicit_grouping && !group_optimized_away)) && having_value != Item::COND_FALSE); } - bool empty_result() { return (zero_result_cause && !implicit_grouping); } + bool empty_result() + { + return (zero_result_cause && !implicit_grouping && + select_lex->olap != ROLLUP_TYPE); + } bool change_result(select_result *new_result, select_result *old_result); bool is_top_level_join() const {