diff options
author | Sergei Petrunia <psergey@askmonty.org> | 2017-07-21 13:53:58 +0300 |
---|---|---|
committer | Sergei Petrunia <psergey@askmonty.org> | 2017-07-21 13:53:58 +0300 |
commit | 17fc288b3054514f139b32c89c62905d374968e4 (patch) | |
tree | 5f6924d08e7e65d914524763f700ce2e6ef192fd | |
parent | bc75c57cfc18be64f167d91c431076f581b0382b (diff) | |
download | mariadb-git-17fc288b3054514f139b32c89c62905d374968e4.tar.gz |
MDEV-13352: Server crashes in st_join_table::remove_duplicates
Do not run the window function computation step when the select
produces no rows (zero_result_cause!=NULL).
This may cause reads from uninitialized memory.
We still need to run the window function computation step when
the output includes just one row (for example
SELECT MAX(col), RANK() OVER (...) FROM t1 WHERE 1=0).
This fix also resolves an issue with queries with window functions
producing an output row where should be none, like in
SELECT ROW_NUMBER() FROM t1 WHERE 1=0.
Updated a few test results in the existing tests to reflect this.
-rw-r--r-- | mysql-test/r/win.result | 12 | ||||
-rw-r--r-- | mysql-test/r/win_insert_select.result | 4 | ||||
-rw-r--r-- | mysql-test/t/win.test | 11 | ||||
-rw-r--r-- | sql/sql_select.cc | 8 |
4 files changed, 28 insertions, 7 deletions
diff --git a/mysql-test/r/win.result b/mysql-test/r/win.result index 7f8777ed491..862d711bce7 100644 --- a/mysql-test/r/win.result +++ b/mysql-test/r/win.result @@ -2762,10 +2762,8 @@ CREATE TABLE t1 (i INT); INSERT INTO t1 VALUES (3), (1), (2); SELECT i, ROW_NUMBER() OVER () FROM t1 WHERE 1 = 2; i ROW_NUMBER() OVER () -NULL 1 SELECT i, COUNT(*) OVER () FROM t1 WHERE 1 = 2; i COUNT(*) OVER () -NULL 1 DROP TABLE t1; # # MDEV-12051: window function in query with implicit grouping @@ -3141,3 +3139,13 @@ sum(i) over (order by i) interval(sum(i) over (order by i), 10, 20) 33 2 63 2 drop table t1; +# +# MDEV-13352: Server crashes in st_join_table::remove_duplicates +# +CREATE TABLE t1 (i INT); +INSERT INTO t1 VALUES (1),(2); +SELECT DISTINCT ROW_NUMBER() OVER(), i FROM t1 WHERE 0; +ROW_NUMBER() OVER() i +SELECT ROW_NUMBER() OVER(), i FROM t1 WHERE 0; +ROW_NUMBER() OVER() i +DROP TABLE t1; diff --git a/mysql-test/r/win_insert_select.result b/mysql-test/r/win_insert_select.result index c86576df6ae..93545e6de30 100644 --- a/mysql-test/r/win_insert_select.result +++ b/mysql-test/r/win_insert_select.result @@ -11,10 +11,6 @@ c1 c2 4 manual_insert_2 11 should repeat 4 times [11-14] 12 should repeat 4 times [11-14] -13 should repeat 4 times [11-14] -14 should repeat 4 times [11-14] -0 should_have_0 -2 should_have_2 DELETE FROM t1; EXECUTE populate_table; INSERT INTO t1 diff --git a/mysql-test/t/win.test b/mysql-test/t/win.test index aff717e3151..1db2354a442 100644 --- a/mysql-test/t/win.test +++ b/mysql-test/t/win.test @@ -1923,3 +1923,14 @@ insert into t1 values (1),(2),(10),(20),(30); select sum(i) over (order by i), interval(sum(i) over (order by i), 10, 20) from t1; drop table t1; + +--echo # +--echo # MDEV-13352: Server crashes in st_join_table::remove_duplicates +--echo # +CREATE TABLE t1 (i INT); +INSERT INTO t1 VALUES (1),(2); +SELECT DISTINCT ROW_NUMBER() OVER(), i FROM t1 WHERE 0; +SELECT ROW_NUMBER() OVER(), i FROM t1 WHERE 0; +DROP TABLE t1; + + diff --git a/sql/sql_select.cc b/sql/sql_select.cc index e8e399868db..90f5e11dd16 100644 --- a/sql/sql_select.cc +++ b/sql/sql_select.cc @@ -3398,8 +3398,14 @@ void JOIN::exec_inner() if (zero_result_cause) { - if (select_lex->have_window_funcs()) + if (select_lex->have_window_funcs() && send_row_on_empty_set()) { + /* + The query produces just one row but it has window functions. + + The only way to compute the value of window function(s) is to + run the entire window function computation step (there is no shortcut). + */ const_tables= table_count; first_select= sub_select_postjoin_aggr; } |