Skip to content

Commit 9a0b8b9

Browse files
committed
Fix rownum in subquery
Description ========== When rownum used in subquery 1. Forbid subquery transformed to semi join. 2. New conditions must be added into having clause when doing in2exists.
1 parent d4d0dd0 commit 9a0b8b9

File tree

4 files changed

+52
-18
lines changed

4 files changed

+52
-18
lines changed

mysql-test/main/rownum.result

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1015,5 +1015,24 @@ ERROR HY000: The target table v of the UPDATE is not updatable
10151015
DROP VIEW v;
10161016
DROP TABLE t;
10171017
#
1018+
# rownum in subquery
1019+
#
1020+
create table t1 (a int primary key, b int);
1021+
insert into t1 values (1, 1), (2, 1), (3, 1), (4, 2), (5, 2), (6, 2);
1022+
explain select * from t1 where a in (select rownum() from t1);
1023+
id select_type table type possible_keys key key_len ref rows Extra
1024+
1 PRIMARY <subquery2> ALL distinct_key NULL NULL NULL 6
1025+
1 PRIMARY t1 eq_ref PRIMARY PRIMARY 4 <subquery2>.rownum() 1 Using index condition
1026+
2 MATERIALIZED t1 index NULL PRIMARY 4 NULL 6 Using index
1027+
select * from t1 where a in (select rownum() from t1);
1028+
a b
1029+
1 1
1030+
2 1
1031+
3 1
1032+
4 2
1033+
5 2
1034+
6 2
1035+
drop table t1;
1036+
#
10181037
# End of 10.6 tests
10191038
#

mysql-test/main/rownum.test

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -617,6 +617,19 @@ UPDATE v SET f = 10 WHERE e > 42 LIMIT 1;
617617
DROP VIEW v;
618618
DROP TABLE t;
619619

620+
--echo #
621+
--echo # rownum in subquery
622+
--echo #
623+
624+
create table t1 (a int primary key, b int);
625+
insert into t1 values (1, 1), (2, 1), (3, 1), (4, 2), (5, 2), (6, 2);
626+
627+
# When rownum used in subquery, the subquery shouldn't be transformed to semijoin
628+
explain select * from t1 where a in (select rownum() from t1);
629+
select * from t1 where a in (select rownum() from t1);
630+
631+
drop table t1;
632+
620633
--echo #
621634
--echo # End of 10.6 tests
622635
--echo #

sql/item_subselect.cc

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2369,7 +2369,7 @@ Item_in_subselect::create_single_in_to_exists_cond(JOIN *join,
23692369
*having_item= NULL;
23702370

23712371
if (join_having || select_lex->with_sum_func ||
2372-
select_lex->group_list.elements)
2372+
select_lex->group_list.elements || select_lex->with_rownum)
23732373
{
23742374
LEX_CSTRING field_name= this->full_name_cstring();
23752375
Item *item= func->create(thd, expr,
@@ -2616,9 +2616,10 @@ Item_in_subselect::create_row_in_to_exists_cond(JOIN * join,
26162616
during JOIN::optimize: this->tmp_having= this->having; this->having= 0;
26172617
*/
26182618
Item* join_having= join->having ? join->having : join->tmp_having;
2619-
bool is_having_used= (join_having || select_lex->with_sum_func ||
2620-
select_lex->group_list.first ||
2621-
!select_lex->table_list.elements);
2619+
bool is_having_used=
2620+
(join_having || select_lex->with_sum_func ||
2621+
select_lex->group_list.first || !select_lex->table_list.elements ||
2622+
select_lex->with_rownum);
26222623
LEX_CSTRING list_ref= { STRING_WITH_LEN("<list ref>")};
26232624
DBUG_ENTER("Item_in_subselect::create_row_in_to_exists_cond");
26242625
DBUG_ASSERT(thd == join->thd);

sql/opt_subselect.cc

Lines changed: 15 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -737,25 +737,26 @@ int check_and_do_in_subquery_rewrites(JOIN *join)
737737
11. It is first optimisation (the subquery could be moved from ON
738738
clause during first optimisation and then be considered for SJ
739739
on the second when it is too late)
740+
12. Subquery does not have ROWNUM
740741
741742
There are also other requirements which cannot be checked at this phase,
742743
yet. They are checked later in convert_join_subqueries_to_semijoins(),
743744
look for calls to block_conversion_to_sj().
744745
*/
745-
if (select_lex->semijoin_enabled(thd) &&
746-
in_subs && // 1
747-
!select_lex->is_part_of_union() && // 2
748-
!select_lex->group_list.elements && !join->order && // 3
749-
!join->having && !select_lex->with_sum_func && // 4
750-
in_subs->emb_on_expr_nest && // 5
751-
!select_lex->is_sj_conversion_prohibited(thd) && // 6
752-
parent_unit->first_select()->leaf_tables.elements && // 7
753-
!in_subs->has_strategy() && // 8
754-
select_lex->outer_select()->table_list.first && // 9
755-
!((join->select_options | // 10
756-
select_lex->outer_select()->join->select_options) // 10
757-
& SELECT_STRAIGHT_JOIN) && // 10
758-
select_lex->first_cond_optimization) // 11
746+
if (select_lex->semijoin_enabled(thd) && in_subs && // 1
747+
!select_lex->is_part_of_union() && // 2
748+
!select_lex->group_list.elements && !join->order && // 3
749+
!join->having && !select_lex->with_sum_func && // 4
750+
in_subs->emb_on_expr_nest && // 5
751+
!select_lex->is_sj_conversion_prohibited(thd) && // 6
752+
parent_unit->first_select()->leaf_tables.elements && // 7
753+
!in_subs->has_strategy() && // 8
754+
select_lex->outer_select()->table_list.first && // 9
755+
!((join->select_options | // 10
756+
select_lex->outer_select()->join->select_options) // 10
757+
& SELECT_STRAIGHT_JOIN) && // 10
758+
select_lex->first_cond_optimization && // 11
759+
!select_lex->with_rownum) // 12
759760
{
760761
DBUG_PRINT("info", ("Subquery is semi-join conversion candidate"));
761762

0 commit comments

Comments
 (0)