diff options
author | Oleksandr Byelkin <sanja@mariadb.com> | 2016-12-20 10:25:25 +0100 |
---|---|---|
committer | Oleksandr Byelkin <sanja@mariadb.com> | 2016-12-20 11:25:47 +0100 |
commit | aaff3d6c35f51dde60907f3c0fc4b2a40bc63c38 (patch) | |
tree | dbdfd49a88cfeb441626fddc929d2951a17e625f | |
parent | f23b41b9b8a30e0e54a1ec7a8923057b0e57e0f5 (diff) | |
download | mariadb-git-aaff3d6c35f51dde60907f3c0fc4b2a40bc63c38.tar.gz |
MDEV-10172: UNION query returns incorrect rows outside conditional evaluation
count duplicate of UNION SELECT separately to awoid influence on lokal LIMIT clause.
-rw-r--r-- | mysql-test/r/union.result | 33 | ||||
-rw-r--r-- | mysql-test/t/union.test | 22 | ||||
-rw-r--r-- | sql/sql_select.cc | 13 | ||||
-rw-r--r-- | sql/sql_select.h | 5 |
4 files changed, 61 insertions, 12 deletions
diff --git a/mysql-test/r/union.result b/mysql-test/r/union.result index 40f5a77e3d0..5a6cd8907e9 100644 --- a/mysql-test/r/union.result +++ b/mysql-test/r/union.result @@ -362,7 +362,7 @@ a 2 select found_rows(); found_rows() -6 +5 SELECT SQL_CALC_FOUND_ROWS * FROM t1 UNION SELECT * FROM t2 LIMIT 100; a 1 @@ -1169,12 +1169,9 @@ a b select * from ((select * from t1 limit 1) union (select * from t1 limit 1)) a; a b 1 a -2 b select * from ((select * from t1 limit 1) union (select * from t1 limit 1) union (select * from t1 limit 1)) a; a b 1 a -2 b -3 c select * from ((((select * from t1))) union (select * from t1) union (select * from t1)) a; a b 1 a @@ -1553,7 +1550,6 @@ NULL UNION RESULT <union1,2> ALL NULL NULL NULL NULL NULL NULL Using filesort Warnings: Note 1003 select NULL AS `a` from `test`.`t1` union select NULL AS `a` from `test`.`t1` order by `a` DROP TABLE t1; -End of 5.0 tests # # Bug#32858: Error: "Incorrect usage of UNION and INTO" does not take # subselects into account @@ -1659,6 +1655,14 @@ a 4 5 6 +(select a from t1 where false) UNION (select a from t1) limit 8; +a +10 +2 +3 +4 +5 +6 7 8 drop table t1; @@ -1955,3 +1959,22 @@ cccc bbbb dddd drop table t1; +# +# MDEV-10172: UNION query returns incorrect rows outside +# conditional evaluation +# +create table t1 (d datetime not null primary key); +insert into t1(d) values ('2016-06-01'),('2016-06-02'),('2016-06-03'),('2016-06-04'); +select * from +( +select * from t1 where d between '2016-06-02' and '2016-06-05' + union +(select * from t1 where d < '2016-06-05' order by d desc limit 1) +) onlyJun2toJun4 +order by d; +d +2016-06-02 00:00:00 +2016-06-03 00:00:00 +2016-06-04 00:00:00 +drop table t1; +End of 5.0 tests diff --git a/mysql-test/t/union.test b/mysql-test/t/union.test index 9204ddd22e5..f4dc6a5d449 100644 --- a/mysql-test/t/union.test +++ b/mysql-test/t/union.test @@ -1022,7 +1022,6 @@ ORDER BY a; DROP TABLE t1; ---echo End of 5.0 tests -- echo # -- echo # Bug#32858: Error: "Incorrect usage of UNION and INTO" does not take -- echo # subselects into account @@ -1126,6 +1125,8 @@ create table t1 (a int); insert into t1 values (10),(10),(10),(2),(3),(4),(5),(6),(7),(8),(9),(1),(10); --sorted_result select a from t1 where false UNION select a from t1 limit 8; +--sorted_result +(select a from t1 where false) UNION (select a from t1) limit 8; drop table t1; --echo # @@ -1350,3 +1351,22 @@ UNION ; drop table t1; + + +--echo # +--echo # MDEV-10172: UNION query returns incorrect rows outside +--echo # conditional evaluation +--echo # + +create table t1 (d datetime not null primary key); +insert into t1(d) values ('2016-06-01'),('2016-06-02'),('2016-06-03'),('2016-06-04'); +select * from +( + select * from t1 where d between '2016-06-02' and '2016-06-05' + union + (select * from t1 where d < '2016-06-05' order by d desc limit 1) +) onlyJun2toJun4 +order by d; +drop table t1; + +--echo End of 5.0 tests diff --git a/sql/sql_select.cc b/sql/sql_select.cc index 8c994964d59..839665f3a9f 100644 --- a/sql/sql_select.cc +++ b/sql/sql_select.cc @@ -2871,7 +2871,7 @@ JOIN::exec() *curr_fields_list), Protocol::SEND_NUM_ROWS | Protocol::SEND_EOF); error= do_select(curr_join, curr_fields_list, NULL, procedure); - thd->limit_found_rows= curr_join->send_records; + thd->limit_found_rows= curr_join->send_records - curr_join->duplicate_rows; /* Accumulate the counts from all join iterations of all join parts. */ thd->examined_row_count+= curr_join->examined_rows; @@ -16578,7 +16578,7 @@ do_select(JOIN *join,List<Item> *fields,TABLE *table,Procedure *procedure) join->join_tab[join->top_join_tab_count - 1].next_select= end_select; join_tab=join->join_tab+join->const_tables; } - join->send_records=0; + join->duplicate_rows= join->send_records=0; if (join->table_count == join->const_tables) { /* @@ -18089,7 +18089,12 @@ end_send(JOIN *join, JOIN_TAB *join_tab __attribute__((unused)), int error; /* result < 0 if row was not accepted and should not be counted */ if ((error= join->result->send_data(*join->fields))) - DBUG_RETURN(error < 0 ? NESTED_LOOP_OK : NESTED_LOOP_ERROR); + { + if (error > 0) + DBUG_RETURN(NESTED_LOOP_ERROR); + // error < 0 => duplicate row + join->duplicate_rows++; + } } if (++join->send_records >= join->unit->select_limit_cnt && join->do_send_rows) @@ -18205,7 +18210,7 @@ end_send_group(JOIN *join, JOIN_TAB *join_tab __attribute__((unused)), if (error < 0) { /* Duplicate row, don't count */ - join->send_records--; + join->duplicate_rows++; error= 0; } } diff --git a/sql/sql_select.h b/sql/sql_select.h index 4650bc24c68..0623672840e 100644 --- a/sql/sql_select.h +++ b/sql/sql_select.h @@ -1018,7 +1018,8 @@ public: table_map outer_join; /* Bitmap of tables used in the select list items */ table_map select_list_used_tables; - ha_rows send_records,found_records,examined_rows,row_limit, select_limit; + ha_rows send_records, found_records, examined_rows, + row_limit, select_limit, duplicate_rows; /** Used to fetch no more than given amount of rows per one fetch operation of server side cursor. @@ -1272,7 +1273,7 @@ public: sort_and_group= 0; first_record= 0; do_send_rows= 1; - send_records= 0; + duplicate_rows= send_records= 0; found_records= 0; fetch_limit= HA_POS_ERROR; examined_rows= 0; |