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

MDEV-10172: UNION query returns incorrect rows outside conditional evaluation

count duplicate of UNION SELECT separately to awoid influence on lokal LIMIT clause.
This commit is contained in:
Oleksandr Byelkin
2016-12-20 10:25:25 +01:00
parent f23b41b9b8
commit aaff3d6c35
4 changed files with 61 additions and 12 deletions

View File

@ -362,7 +362,7 @@ a
2 2
select found_rows(); select found_rows();
found_rows() found_rows()
6 5
SELECT SQL_CALC_FOUND_ROWS * FROM t1 UNION SELECT * FROM t2 LIMIT 100; SELECT SQL_CALC_FOUND_ROWS * FROM t1 UNION SELECT * FROM t2 LIMIT 100;
a a
1 1
@ -1169,12 +1169,9 @@ a b
select * from ((select * from t1 limit 1) union (select * from t1 limit 1)) a; select * from ((select * from t1 limit 1) union (select * from t1 limit 1)) a;
a b a b
1 a 1 a
2 b
select * from ((select * from t1 limit 1) union (select * from t1 limit 1) union (select * from t1 limit 1)) a; select * from ((select * from t1 limit 1) union (select * from t1 limit 1) union (select * from t1 limit 1)) a;
a b a b
1 a 1 a
2 b
3 c
select * from ((((select * from t1))) union (select * from t1) union (select * from t1)) a; select * from ((((select * from t1))) union (select * from t1) union (select * from t1)) a;
a b a b
1 a 1 a
@ -1553,7 +1550,6 @@ NULL UNION RESULT <union1,2> ALL NULL NULL NULL NULL NULL NULL Using filesort
Warnings: Warnings:
Note 1003 select NULL AS `a` from `test`.`t1` union select NULL AS `a` from `test`.`t1` order by `a` Note 1003 select NULL AS `a` from `test`.`t1` union select NULL AS `a` from `test`.`t1` order by `a`
DROP TABLE t1; DROP TABLE t1;
End of 5.0 tests
# #
# Bug#32858: Error: "Incorrect usage of UNION and INTO" does not take # Bug#32858: Error: "Incorrect usage of UNION and INTO" does not take
# subselects into account # subselects into account
@ -1659,6 +1655,14 @@ a
4 4
5 5
6 6
(select a from t1 where false) UNION (select a from t1) limit 8;
a
10
2
3
4
5
6
7 7
8 8
drop table t1; drop table t1;
@ -1955,3 +1959,22 @@ cccc
bbbb bbbb
dddd dddd
drop table t1; 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

View File

@ -1022,7 +1022,6 @@ ORDER BY a;
DROP TABLE t1; DROP TABLE t1;
--echo End of 5.0 tests
-- echo # -- echo #
-- echo # Bug#32858: Error: "Incorrect usage of UNION and INTO" does not take -- echo # Bug#32858: Error: "Incorrect usage of UNION and INTO" does not take
-- echo # subselects into account -- 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); insert into t1 values (10),(10),(10),(2),(3),(4),(5),(6),(7),(8),(9),(1),(10);
--sorted_result --sorted_result
select a from t1 where false UNION select a from t1 limit 8; 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; drop table t1;
--echo # --echo #
@ -1350,3 +1351,22 @@ UNION
; ;
drop table t1; 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

View File

@ -2871,7 +2871,7 @@ JOIN::exec()
*curr_fields_list), *curr_fields_list),
Protocol::SEND_NUM_ROWS | Protocol::SEND_EOF); Protocol::SEND_NUM_ROWS | Protocol::SEND_EOF);
error= do_select(curr_join, curr_fields_list, NULL, procedure); 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. */ /* Accumulate the counts from all join iterations of all join parts. */
thd->examined_row_count+= curr_join->examined_rows; 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->join_tab[join->top_join_tab_count - 1].next_select= end_select;
join_tab=join->join_tab+join->const_tables; 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) if (join->table_count == join->const_tables)
{ {
/* /*
@ -18089,7 +18089,12 @@ end_send(JOIN *join, JOIN_TAB *join_tab __attribute__((unused)),
int error; int error;
/* result < 0 if row was not accepted and should not be counted */ /* result < 0 if row was not accepted and should not be counted */
if ((error= join->result->send_data(*join->fields))) 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 && if (++join->send_records >= join->unit->select_limit_cnt &&
join->do_send_rows) join->do_send_rows)
@ -18205,7 +18210,7 @@ end_send_group(JOIN *join, JOIN_TAB *join_tab __attribute__((unused)),
if (error < 0) if (error < 0)
{ {
/* Duplicate row, don't count */ /* Duplicate row, don't count */
join->send_records--; join->duplicate_rows++;
error= 0; error= 0;
} }
} }

View File

@ -1018,7 +1018,8 @@ public:
table_map outer_join; table_map outer_join;
/* Bitmap of tables used in the select list items */ /* Bitmap of tables used in the select list items */
table_map select_list_used_tables; 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 Used to fetch no more than given amount of rows per one
fetch operation of server side cursor. fetch operation of server side cursor.
@ -1272,7 +1273,7 @@ public:
sort_and_group= 0; sort_and_group= 0;
first_record= 0; first_record= 0;
do_send_rows= 1; do_send_rows= 1;
send_records= 0; duplicate_rows= send_records= 0;
found_records= 0; found_records= 0;
fetch_limit= HA_POS_ERROR; fetch_limit= HA_POS_ERROR;
examined_rows= 0; examined_rows= 0;