MDEV-13911 Support ORDER BY and LIMIT in multi-table update
This commit is contained in:
parent
b6a5be9eaa
commit
26ff92f7ac
@ -942,3 +942,30 @@ deallocate prepare stmt1;
|
|||||||
drop view v3,v2,v1;
|
drop view v3,v2,v1;
|
||||||
drop table t1,t2,t3;
|
drop table t1,t2,t3;
|
||||||
end of 5.5 tests
|
end of 5.5 tests
|
||||||
|
create table t1 (c1 int, c3 int);
|
||||||
|
insert t1(c3) values (1), (2), (3), (4), (5), (6), (7), (8);
|
||||||
|
create table t2 select * from t1;
|
||||||
|
update t1, t2 set t1.c1=t2.c3 where t1.c3=t2.c3 order by t1.c3 limit 3;
|
||||||
|
select * from t1;
|
||||||
|
c1 c3
|
||||||
|
1 1
|
||||||
|
2 2
|
||||||
|
3 3
|
||||||
|
NULL 4
|
||||||
|
NULL 5
|
||||||
|
NULL 6
|
||||||
|
NULL 7
|
||||||
|
NULL 8
|
||||||
|
update t1 set c1=NULL;
|
||||||
|
update t1, t2 set t1.c1=t2.c3 where t1.c3=t2.c3 order by t1.c3 desc limit 2;
|
||||||
|
select * from t1;
|
||||||
|
c1 c3
|
||||||
|
NULL 1
|
||||||
|
NULL 2
|
||||||
|
NULL 3
|
||||||
|
NULL 4
|
||||||
|
NULL 5
|
||||||
|
NULL 6
|
||||||
|
7 7
|
||||||
|
8 8
|
||||||
|
drop table t1, t2;
|
||||||
|
@ -901,3 +901,17 @@ deallocate prepare stmt1;
|
|||||||
drop view v3,v2,v1;
|
drop view v3,v2,v1;
|
||||||
drop table t1,t2,t3;
|
drop table t1,t2,t3;
|
||||||
--echo end of 5.5 tests
|
--echo end of 5.5 tests
|
||||||
|
|
||||||
|
#
|
||||||
|
# MDEV-13911 Support ORDER BY and LIMIT in multi-table update
|
||||||
|
#
|
||||||
|
|
||||||
|
create table t1 (c1 int, c3 int);
|
||||||
|
insert t1(c3) values (1), (2), (3), (4), (5), (6), (7), (8);
|
||||||
|
create table t2 select * from t1;
|
||||||
|
update t1, t2 set t1.c1=t2.c3 where t1.c3=t2.c3 order by t1.c3 limit 3;
|
||||||
|
select * from t1;
|
||||||
|
update t1 set c1=NULL;
|
||||||
|
update t1, t2 set t1.c1=t2.c3 where t1.c3=t2.c3 order by t1.c3 desc limit 2;
|
||||||
|
select * from t1;
|
||||||
|
drop table t1, t2;
|
||||||
|
@ -4525,6 +4525,7 @@ end_with_restore_list:
|
|||||||
else
|
else
|
||||||
res= 0;
|
res= 0;
|
||||||
|
|
||||||
|
unit->set_limit(select_lex);
|
||||||
res= mysql_multi_update_prepare(thd);
|
res= mysql_multi_update_prepare(thd);
|
||||||
|
|
||||||
#ifdef HAVE_REPLICATION
|
#ifdef HAVE_REPLICATION
|
||||||
@ -9059,7 +9060,6 @@ Item * all_any_subquery_creator(THD *thd, Item *left_expr,
|
|||||||
|
|
||||||
bool multi_update_precheck(THD *thd, TABLE_LIST *tables)
|
bool multi_update_precheck(THD *thd, TABLE_LIST *tables)
|
||||||
{
|
{
|
||||||
const char *msg= 0;
|
|
||||||
TABLE_LIST *table;
|
TABLE_LIST *table;
|
||||||
LEX *lex= thd->lex;
|
LEX *lex= thd->lex;
|
||||||
SELECT_LEX *select_lex= &lex->select_lex;
|
SELECT_LEX *select_lex= &lex->select_lex;
|
||||||
@ -9115,15 +9115,6 @@ bool multi_update_precheck(THD *thd, TABLE_LIST *tables)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (select_lex->order_list.elements)
|
|
||||||
msg= "ORDER BY";
|
|
||||||
else if (select_lex->select_limit)
|
|
||||||
msg= "LIMIT";
|
|
||||||
if (msg)
|
|
||||||
{
|
|
||||||
my_error(ER_WRONG_USAGE, MYF(0), "UPDATE", msg);
|
|
||||||
DBUG_RETURN(TRUE);
|
|
||||||
}
|
|
||||||
DBUG_RETURN(FALSE);
|
DBUG_RETURN(FALSE);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1988,7 +1988,8 @@ int JOIN::optimize_stage2()
|
|||||||
FORCE INDEX FOR ORDER BY can be used to prevent join buffering when
|
FORCE INDEX FOR ORDER BY can be used to prevent join buffering when
|
||||||
sorting on the first table.
|
sorting on the first table.
|
||||||
*/
|
*/
|
||||||
if (!stable || !stable->force_index_order)
|
if (!stable || (!stable->force_index_order &&
|
||||||
|
!map2table[stable->tablenr]->keep_current_rowid))
|
||||||
{
|
{
|
||||||
if (group_list)
|
if (group_list)
|
||||||
simple_group= 0;
|
simple_group= 0;
|
||||||
|
@ -1595,10 +1595,9 @@ bool mysql_multi_update(THD *thd,
|
|||||||
List<Item> total_list;
|
List<Item> total_list;
|
||||||
|
|
||||||
res= mysql_select(thd,
|
res= mysql_select(thd,
|
||||||
table_list, select_lex->with_wild,
|
table_list, select_lex->with_wild, total_list, conds,
|
||||||
total_list,
|
select_lex->order_list.elements, select_lex->order_list.first,
|
||||||
conds, 0, (ORDER *) NULL, (ORDER *)NULL, (Item *) NULL,
|
(ORDER *)NULL, (Item *) NULL, (ORDER *)NULL,
|
||||||
(ORDER *)NULL,
|
|
||||||
options | SELECT_NO_JOIN_CACHE | SELECT_NO_UNLOCK |
|
options | SELECT_NO_JOIN_CACHE | SELECT_NO_UNLOCK |
|
||||||
OPTION_SETUP_TABLES_DONE,
|
OPTION_SETUP_TABLES_DONE,
|
||||||
*result, unit, select_lex);
|
*result, unit, select_lex);
|
||||||
@ -1857,6 +1856,8 @@ static bool safe_update_on_fly(THD *thd, JOIN_TAB *join_tab,
|
|||||||
TABLE *table= join_tab->table;
|
TABLE *table= join_tab->table;
|
||||||
if (unique_table(thd, table_ref, all_tables, 0))
|
if (unique_table(thd, table_ref, all_tables, 0))
|
||||||
return 0;
|
return 0;
|
||||||
|
if (join_tab->join->order) // FIXME this is probably too strong
|
||||||
|
return 0;
|
||||||
switch (join_tab->type) {
|
switch (join_tab->type) {
|
||||||
case JT_SYSTEM:
|
case JT_SYSTEM:
|
||||||
case JT_CONST:
|
case JT_CONST:
|
||||||
@ -1934,6 +1935,7 @@ multi_update::initialize_tables(JOIN *join)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
table->prepare_for_position();
|
table->prepare_for_position();
|
||||||
|
join->map2table[table->tablenr]->keep_current_rowid= true;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
enable uncacheable flag if we update a view with check option
|
enable uncacheable flag if we update a view with check option
|
||||||
@ -2001,6 +2003,7 @@ loop_end:
|
|||||||
that we need a position to be read first.
|
that we need a position to be read first.
|
||||||
*/
|
*/
|
||||||
tbl->prepare_for_position();
|
tbl->prepare_for_position();
|
||||||
|
join->map2table[tbl->tablenr]->keep_current_rowid= true;
|
||||||
|
|
||||||
Field_string *field= new Field_string(tbl->file->ref_length, 0,
|
Field_string *field= new Field_string(tbl->file->ref_length, 0,
|
||||||
&field_name,
|
&field_name,
|
||||||
|
Loading…
x
Reference in New Issue
Block a user