Commit 64a3827b authored by unknown's avatar unknown

check of using same table for changing and select


mysql-test/r/subselect.result:
  test of using same table for changing and select
mysql-test/t/subselect.test:
  test of using same table for changing and select
sql/mysql_priv.h:
  new function
sql/sql_base.cc:
  new function
parent 8e02b39a
...@@ -411,6 +411,8 @@ a b ...@@ -411,6 +411,8 @@ a b
0 10 0 10
1 11 1 11
2 12 2 12
update t1 set b= (select b from t1);
INSERT TABLE 't1' isn't allowed in FROM table list
update t1 set b= (select b from t2 where t1.a = t2.a); update t1 set b= (select b from t2 where t1.a = t2.a);
select * from t1; select * from t1;
a b a b
...@@ -430,6 +432,8 @@ a b ...@@ -430,6 +432,8 @@ a b
select * from t1 where b = (select b from t2 where t1.a = t2.a); select * from t1 where b = (select b from t2 where t1.a = t2.a);
a b a b
2 12 2 12
delete from t1 where b = (select b from t1);
INSERT TABLE 't1' isn't allowed in FROM table list
delete from t1 where b = (select b from t2 where t1.a = t2.a); delete from t1 where b = (select b from t2 where t1.a = t2.a);
select * from t1; select * from t1;
a b a b
...@@ -453,6 +457,8 @@ a b ...@@ -453,6 +457,8 @@ a b
33 10 33 10
22 11 22 11
2 12 2 12
delete t11.*, t12.* from t11,t12 where t11.a = t12.a and t11.b = (select b from t12 where t11.a = t12.a);
INSERT TABLE 't12' isn't allowed in FROM table list
delete t11.*, t12.* from t11,t12 where t11.a = t12.a and t11.b = (select b from t2 where t11.a = t2.a); delete t11.*, t12.* from t11,t12 where t11.a = t12.a and t11.b = (select b from t2 where t11.a = t2.a);
select * from t11; select * from t11;
a b a b
...@@ -466,6 +472,8 @@ drop table t11, t12, t2; ...@@ -466,6 +472,8 @@ drop table t11, t12, t2;
CREATE TABLE t1 (x int); CREATE TABLE t1 (x int);
create table t2 (a int); create table t2 (a int);
insert into t2 values (1); insert into t2 values (1);
INSERT INTO t1 (x) VALUES ((SELECT x FROM t1));
INSERT TABLE 't1' isn't allowed in FROM table list
INSERT INTO t1 (x) VALUES ((SELECT a FROM t2)); INSERT INTO t1 (x) VALUES ((SELECT a FROM t2));
select * from t1; select * from t1;
x x
...@@ -485,20 +493,22 @@ x ...@@ -485,20 +493,22 @@ x
3 3
INSERT INTO t1 (x) select (SELECT SUM(x)+2 FROM t1) FROM t2; INSERT INTO t1 (x) select (SELECT SUM(x)+2 FROM t1) FROM t2;
INSERT TABLE 't1' isn't allowed in FROM table list INSERT TABLE 't1' isn't allowed in FROM table list
INSERT DELAYED INTO t1 (x) VALUES ((SELECT SUM(x) FROM t1)); INSERT DELAYED INTO t1 (x) VALUES ((SELECT SUM(x) FROM t2));
select * from t1; select * from t1;
x x
1 1
2 2
3 3
3 3
9 0
drop table t1, t2; drop table t1, t2;
CREATE TABLE t1 (x int not null, y int, primary key (x)); CREATE TABLE t1 (x int not null, y int, primary key (x));
create table t2 (a int); create table t2 (a int);
insert into t2 values (1); insert into t2 values (1);
select * from t1; select * from t1;
x y x y
replace into t1 (x, y) VALUES ((SELECT x FROM t1), (SELECT a+1 FROM t2));
INSERT TABLE 't1' isn't allowed in FROM table list
replace into t1 (x, y) VALUES ((SELECT a FROM t2), (SELECT a+1 FROM t2)); replace into t1 (x, y) VALUES ((SELECT a FROM t2), (SELECT a+1 FROM t2));
select * from t1; select * from t1;
x y x y
...@@ -559,4 +569,10 @@ id ...@@ -559,4 +569,10 @@ id
SELECT * FROM t WHERE id IN (SELECT 5 UNION SELECT 2); SELECT * FROM t WHERE id IN (SELECT 5 UNION SELECT 2);
id id
2 2
drop table if exists t; INSERT INTO t VALUES ((SELECT * FROM t));
INSERT TABLE 't' isn't allowed in FROM table list
SELECT * FROM t;
id
1
2
drop table t;
...@@ -245,6 +245,8 @@ create table t2 (a int NOT NULL, b int, primary key (a)); ...@@ -245,6 +245,8 @@ create table t2 (a int NOT NULL, b int, primary key (a));
insert into t1 values (0, 10),(1, 11),(2, 12); insert into t1 values (0, 10),(1, 11),(2, 12);
insert into t2 values (1, 21),(2, 22),(3, 23); insert into t2 values (1, 21),(2, 22),(3, 23);
select * from t1; select * from t1;
-- error 1093
update t1 set b= (select b from t1);
update t1 set b= (select b from t2 where t1.a = t2.a); update t1 set b= (select b from t2 where t1.a = t2.a);
select * from t1; select * from t1;
drop table t1, t2; drop table t1, t2;
...@@ -256,6 +258,8 @@ insert into t1 values (0, 10),(1, 11),(2, 12); ...@@ -256,6 +258,8 @@ insert into t1 values (0, 10),(1, 11),(2, 12);
insert into t2 values (1, 21),(2, 12),(3, 23); insert into t2 values (1, 21),(2, 12),(3, 23);
select * from t1; select * from t1;
select * from t1 where b = (select b from t2 where t1.a = t2.a); select * from t1 where b = (select b from t2 where t1.a = t2.a);
-- error 1093
delete from t1 where b = (select b from t1);
delete from t1 where b = (select b from t2 where t1.a = t2.a); delete from t1 where b = (select b from t2 where t1.a = t2.a);
select * from t1; select * from t1;
drop table t1, t2; drop table t1, t2;
...@@ -270,6 +274,8 @@ insert into t12 values (33, 10),(22, 11),(2, 12); ...@@ -270,6 +274,8 @@ insert into t12 values (33, 10),(22, 11),(2, 12);
insert into t2 values (1, 21),(2, 12),(3, 23); insert into t2 values (1, 21),(2, 12),(3, 23);
select * from t11; select * from t11;
select * from t12; select * from t12;
-- error 1093
delete t11.*, t12.* from t11,t12 where t11.a = t12.a and t11.b = (select b from t12 where t11.a = t12.a);
delete t11.*, t12.* from t11,t12 where t11.a = t12.a and t11.b = (select b from t2 where t11.a = t2.a); delete t11.*, t12.* from t11,t12 where t11.a = t12.a and t11.b = (select b from t2 where t11.a = t2.a);
select * from t11; select * from t11;
select * from t12; select * from t12;
...@@ -279,6 +285,8 @@ drop table t11, t12, t2; ...@@ -279,6 +285,8 @@ drop table t11, t12, t2;
CREATE TABLE t1 (x int); CREATE TABLE t1 (x int);
create table t2 (a int); create table t2 (a int);
insert into t2 values (1); insert into t2 values (1);
-- error 1093
INSERT INTO t1 (x) VALUES ((SELECT x FROM t1));
INSERT INTO t1 (x) VALUES ((SELECT a FROM t2)); INSERT INTO t1 (x) VALUES ((SELECT a FROM t2));
select * from t1; select * from t1;
insert into t2 values (1); insert into t2 values (1);
...@@ -289,7 +297,7 @@ INSERT INTO t1 (x) select (SELECT SUM(a)+1 FROM t2) FROM t2; ...@@ -289,7 +297,7 @@ INSERT INTO t1 (x) select (SELECT SUM(a)+1 FROM t2) FROM t2;
select * from t1; select * from t1;
-- error 1093 -- error 1093
INSERT INTO t1 (x) select (SELECT SUM(x)+2 FROM t1) FROM t2; INSERT INTO t1 (x) select (SELECT SUM(x)+2 FROM t1) FROM t2;
INSERT DELAYED INTO t1 (x) VALUES ((SELECT SUM(x) FROM t1)); INSERT DELAYED INTO t1 (x) VALUES ((SELECT SUM(x) FROM t2));
-- sleep 1 -- sleep 1
select * from t1; select * from t1;
drop table t1, t2; drop table t1, t2;
...@@ -299,6 +307,8 @@ CREATE TABLE t1 (x int not null, y int, primary key (x)); ...@@ -299,6 +307,8 @@ CREATE TABLE t1 (x int not null, y int, primary key (x));
create table t2 (a int); create table t2 (a int);
insert into t2 values (1); insert into t2 values (1);
select * from t1; select * from t1;
-- error 1093
replace into t1 (x, y) VALUES ((SELECT x FROM t1), (SELECT a+1 FROM t2));
replace into t1 (x, y) VALUES ((SELECT a FROM t2), (SELECT a+1 FROM t2)); replace into t1 (x, y) VALUES ((SELECT a FROM t2), (SELECT a+1 FROM t2));
select * from t1; select * from t1;
replace into t1 (x, y) VALUES ((SELECT a FROM t2), (SELECT a+2 FROM t2)); replace into t1 (x, y) VALUES ((SELECT a FROM t2), (SELECT a+2 FROM t2));
...@@ -326,5 +336,7 @@ EXPLAIN SELECT * FROM t WHERE id IN (SELECT 1+(select 1)); ...@@ -326,5 +336,7 @@ EXPLAIN SELECT * FROM t WHERE id IN (SELECT 1+(select 1));
EXPLAIN SELECT * FROM t WHERE id IN (SELECT 1 UNION SELECT 3); EXPLAIN SELECT * FROM t WHERE id IN (SELECT 1 UNION SELECT 3);
SELECT * FROM t WHERE id IN (SELECT 5 UNION SELECT 3); SELECT * FROM t WHERE id IN (SELECT 5 UNION SELECT 3);
SELECT * FROM t WHERE id IN (SELECT 5 UNION SELECT 2); SELECT * FROM t WHERE id IN (SELECT 5 UNION SELECT 2);
drop table if exists t; -- error 1093
INSERT INTO t VALUES ((SELECT * FROM t));
SELECT * FROM t;
drop table t;
...@@ -580,6 +580,9 @@ bool close_thread_table(THD *thd, TABLE **table_ptr); ...@@ -580,6 +580,9 @@ bool close_thread_table(THD *thd, TABLE **table_ptr);
void close_temporary_tables(THD *thd); void close_temporary_tables(THD *thd);
TABLE_LIST * find_table_in_list(TABLE_LIST *table, TABLE_LIST * find_table_in_list(TABLE_LIST *table,
const char *db_name, const char *table_name); const char *db_name, const char *table_name);
TABLE_LIST * find_real_table_in_list(TABLE_LIST *table,
const char *db_name,
const char *table_name);
TABLE **find_temporary_table(THD *thd, const char *db, const char *table_name); TABLE **find_temporary_table(THD *thd, const char *db, const char *table_name);
bool close_temporary_table(THD *thd, const char *db, const char *table_name); bool close_temporary_table(THD *thd, const char *db, const char *table_name);
void close_temporary(TABLE *table, bool delete_table=1); void close_temporary(TABLE *table, bool delete_table=1);
......
...@@ -744,7 +744,7 @@ void close_temporary_tables(THD *thd) ...@@ -744,7 +744,7 @@ void close_temporary_tables(THD *thd)
} }
/* /*
Find first suitable table in given list. Find first suitable table by alias in given list.
SYNOPSIS SYNOPSIS
find_table_in_list() find_table_in_list()
...@@ -767,6 +767,31 @@ TABLE_LIST * find_table_in_list(TABLE_LIST *table, ...@@ -767,6 +767,31 @@ TABLE_LIST * find_table_in_list(TABLE_LIST *table,
return table; return table;
} }
/*
Find real table in given list.
SYNOPSIS
find_table_in_list()
table - pointer to table list
db_name - data base name
table_name - table name
RETURN VALUES
NULL Table not found
# Pointer to found table.
*/
TABLE_LIST * find_real_table_in_list(TABLE_LIST *table,
const char *db_name,
const char *table_name)
{
for (; table; table= table->next)
if (!strcmp(table->db, db_name) &&
!strcmp(table->real_name, table_name))
break;
return table;
}
TABLE **find_temporary_table(THD *thd, const char *db, const char *table_name) TABLE **find_temporary_table(THD *thd, const char *db, const char *table_name)
{ {
char key[MAX_DBKEY_LENGTH]; char key[MAX_DBKEY_LENGTH];
......
...@@ -51,6 +51,12 @@ int mysql_delete(THD *thd, TABLE_LIST *table_list, COND *conds, ORDER *order, ...@@ -51,6 +51,12 @@ int mysql_delete(THD *thd, TABLE_LIST *table_list, COND *conds, ORDER *order,
if (setup_conds(thd, delete_table_list, &conds) || if (setup_conds(thd, delete_table_list, &conds) ||
setup_ftfuncs(&thd->lex.select_lex)) setup_ftfuncs(&thd->lex.select_lex))
DBUG_RETURN(-1); DBUG_RETURN(-1);
if (find_real_table_in_list(table_list->next,
table_list->db, table_list->real_name))
{
my_error(ER_INSERT_TABLE_USED, MYF(0), table_list->real_name);
DBUG_RETURN(-1);
}
const_cond= (!conds || conds->const_item()); const_cond= (!conds || conds->const_item());
safe_update=test(thd->options & OPTION_SAFE_UPDATES); safe_update=test(thd->options & OPTION_SAFE_UPDATES);
......
...@@ -171,6 +171,13 @@ int mysql_insert(THD *thd,TABLE_LIST *table_list, List<Item> &fields, ...@@ -171,6 +171,13 @@ int mysql_insert(THD *thd,TABLE_LIST *table_list, List<Item> &fields,
table->time_stamp= save_time_stamp; table->time_stamp= save_time_stamp;
goto abort; goto abort;
} }
if (find_real_table_in_list(table_list->next,
table_list->db, table_list->real_name))
{
my_error(ER_INSERT_TABLE_USED, MYF(0), table_list->real_name);
goto abort;
}
value_count= values->elements; value_count= values->elements;
while ((values= its++)) while ((values= its++))
{ {
......
...@@ -61,7 +61,6 @@ static int check_for_max_user_connections(THD *thd, USER_CONN *uc); ...@@ -61,7 +61,6 @@ static int check_for_max_user_connections(THD *thd, USER_CONN *uc);
static void decrease_user_connections(USER_CONN *uc); static void decrease_user_connections(USER_CONN *uc);
static bool check_db_used(THD *thd,TABLE_LIST *tables); static bool check_db_used(THD *thd,TABLE_LIST *tables);
static bool check_merge_table_access(THD *thd, char *db, TABLE_LIST *tables); static bool check_merge_table_access(THD *thd, char *db, TABLE_LIST *tables);
static bool check_dup(const char *db, const char *name, TABLE_LIST *tables);
static void remove_escape(char *name); static void remove_escape(char *name);
static void refresh_status(void); static void refresh_status(void);
static bool append_file_to_dir(THD *thd, char **filename_ptr, static bool append_file_to_dir(THD *thd, char **filename_ptr,
...@@ -1645,7 +1644,7 @@ mysql_execute_command(THD *thd) ...@@ -1645,7 +1644,7 @@ mysql_execute_command(THD *thd)
select_result *result; select_result *result;
if (!(lex->create_info.options & HA_LEX_CREATE_TMP_TABLE) && if (!(lex->create_info.options & HA_LEX_CREATE_TMP_TABLE) &&
check_dup(tables->db, tables->real_name, tables->next)) find_real_table_in_list(tables->next, tables->db, tables->real_name))
{ {
net_printf(thd,ER_INSERT_TABLE_USED,tables->real_name); net_printf(thd,ER_INSERT_TABLE_USED,tables->real_name);
DBUG_VOID_RETURN; DBUG_VOID_RETURN;
...@@ -2007,7 +2006,7 @@ mysql_execute_command(THD *thd) ...@@ -2007,7 +2006,7 @@ mysql_execute_command(THD *thd)
if (unit->select_limit_cnt < select_lex->select_limit) if (unit->select_limit_cnt < select_lex->select_limit)
unit->select_limit_cnt= HA_POS_ERROR; // No limit unit->select_limit_cnt= HA_POS_ERROR; // No limit
if (check_dup(tables->db, tables->real_name, tables->next)) if (find_real_table_in_list(tables->next, tables->db, tables->real_name))
{ {
net_printf(thd,ER_INSERT_TABLE_USED,tables->real_name); net_printf(thd,ER_INSERT_TABLE_USED,tables->real_name);
DBUG_VOID_RETURN; DBUG_VOID_RETURN;
...@@ -2100,6 +2099,17 @@ mysql_execute_command(THD *thd) ...@@ -2100,6 +2099,17 @@ mysql_execute_command(THD *thd)
/* Fix tables-to-be-deleted-from list to point at opened tables */ /* Fix tables-to-be-deleted-from list to point at opened tables */
for (auxi=(TABLE_LIST*) aux_tables ; auxi ; auxi=auxi->next) for (auxi=(TABLE_LIST*) aux_tables ; auxi ; auxi=auxi->next)
auxi->table= auxi->table_list->table; auxi->table= auxi->table_list->table;
if (&lex->select_lex != lex->all_selects_list)
for (TABLE_LIST *t= select_lex->get_table_list();
t; t= t->next)
{
if (find_real_table_in_list(t->table_list->next, t->db, t->real_name))
{
my_error(ER_INSERT_TABLE_USED, MYF(0), t->real_name);
res= -1;
break;
}
}
fix_tables_pointers(lex->all_selects_list); fix_tables_pointers(lex->all_selects_list);
if (!thd->fatal_error && (result= new multi_delete(thd,aux_tables, if (!thd->fatal_error && (result= new multi_delete(thd,aux_tables,
table_count))) table_count)))
...@@ -3521,16 +3531,6 @@ void add_join_natural(TABLE_LIST *a,TABLE_LIST *b) ...@@ -3521,16 +3531,6 @@ void add_join_natural(TABLE_LIST *a,TABLE_LIST *b)
b->natural_join=a; b->natural_join=a;
} }
/* Check if name is used in table list */
static bool check_dup(const char *db, const char *name, TABLE_LIST *tables)
{
for (; tables ; tables=tables->next)
if (!strcmp(name,tables->real_name) && !strcmp(db,tables->db))
return 1;
return 0;
}
bool reload_acl_and_cache(THD *thd, ulong options, TABLE_LIST *tables) bool reload_acl_and_cache(THD *thd, ulong options, TABLE_LIST *tables)
{ {
bool result=0; bool result=0;
......
...@@ -86,6 +86,13 @@ int mysql_update(THD *thd, ...@@ -86,6 +86,13 @@ int mysql_update(THD *thd,
setup_conds(thd,update_table_list,&conds) setup_conds(thd,update_table_list,&conds)
|| setup_ftfuncs(&thd->lex.select_lex)) || setup_ftfuncs(&thd->lex.select_lex))
DBUG_RETURN(-1); /* purecov: inspected */ DBUG_RETURN(-1); /* purecov: inspected */
if (find_real_table_in_list(table_list->next,
table_list->db, table_list->real_name))
{
my_error(ER_INSERT_TABLE_USED, MYF(0), table_list->real_name);
DBUG_RETURN(-1);
}
old_used_keys=table->used_keys; // Keys used in WHERE old_used_keys=table->used_keys; // Keys used in WHERE
/* /*
......
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