Commit e754501a authored by unknown's avatar unknown
Browse files

Merge sanja.is.com.ua:/home/bell/mysql/bk/mysql-4.1

into sanja.is.com.ua:/home/bell/mysql/bk/work-update-4.1


sql/sql_lex.cc:
  Auto merged
sql/sql_parse.cc:
  Auto merged
parents 3b4c3833 6c233040
Loading
Loading
Loading
Loading
+7 −0
Original line number Diff line number Diff line
@@ -455,3 +455,10 @@ create table t3 (a int, primary key (a));
delete t1,t3 from t1,t2 where t1.a=t2.a and t2.a=(select t3.a from t3 where t1.a=t3.a);
ERROR 42S02: Unknown table 't3' in MULTI DELETE
drop table t1, t2, t3;
create table t1 (col1 int);
create table t2 (col1 int);
update t1,t2 set t1.col1 = (select max(col1) from t1) where t1.col1 = t2.col1;
ERROR HY000: You can't specify target table 't1' for update in FROM clause
delete t1 from t1,t2 where t1.col1 < (select max(col1) from t1) and t1.col1 = t2.col1;
ERROR HY000: You can't specify target table 't1' for update in FROM clause
drop table t1,t2;
+11 −0
Original line number Diff line number Diff line
@@ -417,3 +417,14 @@ create table t3 (a int, primary key (a));
-- error 1109
delete t1,t3 from t1,t2 where t1.a=t2.a and t2.a=(select t3.a from t3 where t1.a=t3.a);
drop table t1, t2, t3;

#
# multi* unique updating table check
#
create table t1 (col1 int); 
create table t2 (col1 int);
-- error 1093
update t1,t2 set t1.col1 = (select max(col1) from t1) where t1.col1 = t2.col1;
-- error 1093
delete t1 from t1,t2 where t1.col1 < (select max(col1) from t1) and t1.col1 = t2.col1;
drop table t1,t2;
+21 −1
Original line number Diff line number Diff line
@@ -1550,6 +1550,7 @@ bool st_select_lex::setup_ref_array(THD *thd, uint order_group_num)
    1 - found
    0 - OK (table did not found)
*/

bool st_select_lex_unit::check_updateable(char *db, char *table)
{
  for (SELECT_LEX *sl= first_select(); sl; sl= sl->next_select())
@@ -1561,7 +1562,7 @@ bool st_select_lex_unit::check_updateable(char *db, char *table)

/*
  Find db.table which will be updated in this select and 
  underlayed ones (except derived tables)
  underlaying ones (except derived tables)

  SYNOPSIS
    st_select_lex::check_updateable()
@@ -1572,11 +1573,30 @@ bool st_select_lex_unit::check_updateable(char *db, char *table)
    1 - found
    0 - OK (table did not found)
*/

bool st_select_lex::check_updateable(char *db, char *table)
{
  if (find_real_table_in_list(get_table_list(), db, table))
    return 1;

  return check_updateable_in_subqueries(db, table);
}

/*
   Find db.table which will be updated in underlaying subqueries

   SYNOPSIS
    st_select_lex::check_updateable_in_subqueries()
    db		- data base name
    table	- real table name

  RETURN
    1 - found
    0 - OK (table did not found)
*/

bool st_select_lex::check_updateable_in_subqueries(char *db, char *table)
{
  for (SELECT_LEX_UNIT *un= first_inner_unit();
       un;
       un= un->next_unit())
+1 −0
Original line number Diff line number Diff line
@@ -517,6 +517,7 @@ class st_select_lex: public st_select_lex_node
  }
  bool setup_ref_array(THD *thd, uint order_group_num);
  bool check_updateable(char *db, char *table);
  bool check_updateable_in_subqueries(char *db, char *table);
  void print(THD *thd, String *str);
  static void print_order(String *str, ORDER *order);
  void print_limit(THD *thd, String *str);
+9 −14
Original line number Diff line number Diff line
@@ -2796,26 +2796,21 @@ mysql_execute_command(THD *thd)
	 target_tbl;
	 target_tbl= target_tbl->next)
    {
      target_tbl->table= target_tbl->table_list->table;
      TABLE_LIST *orig= target_tbl->table_list;
      target_tbl->table= orig->table;
      /*
	 Multi-delete can't be constructed over-union => we always have
	 single SELECT on top and have to check underlaying SELECTs of it
      */
      for (SELECT_LEX_UNIT *un= lex->select_lex.first_inner_unit();
	   un;
	   un= un->next_unit())
      {
	if (un->first_select()->linkage != DERIVED_TABLE_TYPE &&
	    un->check_updateable(target_tbl->table_list->db,
				 target_tbl->table_list->real_name))
      if (lex->select_lex.check_updateable_in_subqueries(orig->db,
                                                         orig->real_name))
      {
        my_error(ER_UPDATE_TABLE_USED, MYF(0),
		   target_tbl->table_list->real_name);
                 orig->real_name);
        res= -1;
        break;
      }
    }
    }

    if (!thd->is_fatal_error && (result= new multi_delete(thd,aux_tables,
							  table_count)))
Loading