Commit aaff3d6c authored by Oleksandr Byelkin's avatar Oleksandr Byelkin

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

count duplicate of UNION SELECT separately to awoid influence on lokal LIMIT clause.
parent f23b41b9
......@@ -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
......@@ -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
......@@ -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;
}
}
......
......@@ -1018,7 +1018,8 @@ class JOIN :public Sql_alloc
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 @@ class JOIN :public Sql_alloc
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;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment