mirror of
https://github.com/MariaDB/server.git
synced 2025-01-29 02:05:57 +01:00
ufter revview fix (BUG#2120)
mysql-test/r/derived.result: test of error handling in derived tables with UPDATE & DELETE mysql-test/t/derived.test: test of error handling in derived tables with UPDATE & DELETE sql/mysql_priv.h: opened tables counter added to avoid loop of tables calculating in lock_tables sql/sql_acl.cc: opened tables counter added to avoid loop of tables calculating in lock_tables, here it is just for compatibility sql/sql_base.cc: removed unneeded assignment opened tables counter added to avoid loop of tables calculating in lock_tables commentary fixed sql/sql_derived.cc: mysql_derived made static variable res moved in place where it used priveleges written in correct place sql/sql_handler.cc: opened tables counter added to avoid loop of tables calculating in lock_tables sql/sql_parse.cc: mistyping in commentary fixed
This commit is contained in:
parent
584ddfdab2
commit
61f0e69cb6
8 changed files with 62 additions and 32 deletions
|
@ -267,12 +267,16 @@ N M
|
|||
3 0
|
||||
UPDATE `t1` AS P1 INNER JOIN (SELECT N FROM `t1` GROUP BY N HAVING Count(M) > 1) AS P2 ON P1.N = P2.N SET P1.M = 2, P2.N = 2;
|
||||
ERROR HY000: The target table P2 of the UPDATE is not updatable.
|
||||
UPDATE `t1` AS P1 INNER JOIN (SELECT aaaa FROM `t1` GROUP BY N HAVING Count(M) > 1) AS P2 ON P1.N = P2.N SET P1.M = 2;
|
||||
ERROR 42S22: Unknown column 'aaaa' in 'field list'
|
||||
delete P1.* from `t1` AS P1 INNER JOIN (SELECT N FROM `t1` GROUP BY N HAVING Count(M) > 1) AS P2 ON P1.N = P2.N;
|
||||
select * from t1;
|
||||
N M
|
||||
3 0
|
||||
delete P1.*,P2.* from `t1` AS P1 INNER JOIN (SELECT N FROM `t1` GROUP BY N HAVING Count(M) > 1) AS P2 ON P1.N = P2.N;
|
||||
ERROR HY000: The target table P2 of the DELETE is not updatable.
|
||||
delete P1.* from `t1` AS P1 INNER JOIN (SELECT aaa FROM `t1` GROUP BY N HAVING Count(M) > 1) AS P2 ON P1.N = P2.N;
|
||||
ERROR 42S22: Unknown column 'aaa' in 'field list'
|
||||
drop table t1;
|
||||
CREATE TABLE t1 (
|
||||
OBJECTID int(11) NOT NULL default '0',
|
||||
|
|
|
@ -153,10 +153,14 @@ UPDATE `t1` AS P1 INNER JOIN (SELECT N FROM `t1` GROUP BY N HAVING Count(M) > 1)
|
|||
select * from t1;
|
||||
-- error 1287
|
||||
UPDATE `t1` AS P1 INNER JOIN (SELECT N FROM `t1` GROUP BY N HAVING Count(M) > 1) AS P2 ON P1.N = P2.N SET P1.M = 2, P2.N = 2;
|
||||
-- error 1054
|
||||
UPDATE `t1` AS P1 INNER JOIN (SELECT aaaa FROM `t1` GROUP BY N HAVING Count(M) > 1) AS P2 ON P1.N = P2.N SET P1.M = 2;
|
||||
delete P1.* from `t1` AS P1 INNER JOIN (SELECT N FROM `t1` GROUP BY N HAVING Count(M) > 1) AS P2 ON P1.N = P2.N;
|
||||
select * from t1;
|
||||
-- error 1287
|
||||
delete P1.*,P2.* from `t1` AS P1 INNER JOIN (SELECT N FROM `t1` GROUP BY N HAVING Count(M) > 1) AS P2 ON P1.N = P2.N;
|
||||
-- error 1054
|
||||
delete P1.* from `t1` AS P1 INNER JOIN (SELECT aaa FROM `t1` GROUP BY N HAVING Count(M) > 1) AS P2 ON P1.N = P2.N;
|
||||
drop table t1;
|
||||
|
||||
#
|
||||
|
|
|
@ -675,10 +675,10 @@ int setup_conds(THD *thd,TABLE_LIST *tables,COND **conds);
|
|||
int setup_ftfuncs(SELECT_LEX* select);
|
||||
int init_ftfuncs(THD *thd, SELECT_LEX* select, bool no_order);
|
||||
void wait_for_refresh(THD *thd);
|
||||
int open_tables(THD *thd,TABLE_LIST *tables);
|
||||
int open_tables(THD *thd, TABLE_LIST *tables, uint *counter);
|
||||
int simple_open_n_lock_tables(THD *thd,TABLE_LIST *tables);
|
||||
int open_and_lock_tables(THD *thd,TABLE_LIST *tables);
|
||||
int lock_tables(THD *thd,TABLE_LIST *tables);
|
||||
int lock_tables(THD *thd, TABLE_LIST *tables, uint counter);
|
||||
TABLE *open_temporary_table(THD *thd, const char *path, const char *db,
|
||||
const char *table_name, bool link_in_list);
|
||||
bool rm_temporary_table(enum db_type base, char *path);
|
||||
|
|
|
@ -173,7 +173,8 @@ my_bool acl_init(THD *org_thd, bool dont_read_acl_tables)
|
|||
tables[0].lock_type=tables[1].lock_type=tables[2].lock_type=TL_READ;
|
||||
tables[0].db=tables[1].db=tables[2].db=thd->db;
|
||||
|
||||
if (open_tables(thd,tables))
|
||||
uint counter;
|
||||
if (open_tables(thd, tables, &counter))
|
||||
{
|
||||
sql_print_error("Fatal error: Can't open privilege tables: %s",
|
||||
thd->net.last_error);
|
||||
|
@ -2524,7 +2525,8 @@ my_bool grant_init(THD *org_thd)
|
|||
tables[0].lock_type=tables[1].lock_type=TL_READ;
|
||||
tables[0].db=tables[1].db=thd->db;
|
||||
|
||||
if (open_tables(thd,tables))
|
||||
uint counter;
|
||||
if (open_tables(thd, tables, &counter))
|
||||
goto end;
|
||||
|
||||
TABLE *ptr[2]; // Lock tables for quick update
|
||||
|
|
|
@ -1308,7 +1308,6 @@ static int open_unireg_entry(THD *thd, TABLE *entry, const char *db,
|
|||
bzero((char*) &table_list, sizeof(table_list)); // just for safe
|
||||
table_list.db=(char*) db;
|
||||
table_list.real_name=(char*) name;
|
||||
table_list.next=0;
|
||||
safe_mutex_assert_owner(&LOCK_open);
|
||||
|
||||
if ((error=lock_table_name(thd,&table_list)))
|
||||
|
@ -1357,24 +1356,40 @@ err:
|
|||
DBUG_RETURN(1);
|
||||
}
|
||||
|
||||
/*****************************************************************************
|
||||
** open all tables in list
|
||||
*****************************************************************************/
|
||||
/*
|
||||
Open all tables in list
|
||||
|
||||
int open_tables(THD *thd,TABLE_LIST *start)
|
||||
SYNOPSIS
|
||||
open_tables()
|
||||
thd - thread handler
|
||||
start - list of tables
|
||||
counter - number of opened tables will be return using this parameter
|
||||
|
||||
RETURN
|
||||
0 - OK
|
||||
-1 - error
|
||||
*/
|
||||
|
||||
int open_tables(THD *thd, TABLE_LIST *start, uint *counter)
|
||||
{
|
||||
TABLE_LIST *tables;
|
||||
bool refresh;
|
||||
int result=0;
|
||||
DBUG_ENTER("open_tables");
|
||||
*counter= 0;
|
||||
|
||||
thd->current_tablenr= 0;
|
||||
restart:
|
||||
thd->proc_info="Opening tables";
|
||||
for (tables=start ; tables ; tables=tables->next)
|
||||
{
|
||||
/*
|
||||
Ignore placeholders for derived tables. After derived tables
|
||||
processing, link to created temporary table will be put here.
|
||||
*/
|
||||
if (tables->derived)
|
||||
continue;
|
||||
(*counter)++;
|
||||
if (!tables->table &&
|
||||
!(tables->table= open_table(thd,
|
||||
tables->db,
|
||||
|
@ -1533,14 +1548,19 @@ TABLE *open_ltable(THD *thd, TABLE_LIST *table_list, thr_lock_type lock_type)
|
|||
thd - thread handler
|
||||
tables - list of tables for open&locking
|
||||
|
||||
RETURN
|
||||
0 - ok
|
||||
-1 - error
|
||||
|
||||
NOTE
|
||||
The lock will automaticly be freed by close_thread_tables()
|
||||
*/
|
||||
|
||||
int simple_open_n_lock_tables(THD *thd, TABLE_LIST *tables)
|
||||
{
|
||||
DBUG_ENTER("open_n_lock_tables");
|
||||
if (open_tables(thd, tables) || lock_tables(thd, tables))
|
||||
DBUG_ENTER("simple_open_n_lock_tables");
|
||||
uint counter;
|
||||
if (open_tables(thd, tables, &counter) || lock_tables(thd, tables, counter))
|
||||
DBUG_RETURN(-1); /* purecov: inspected */
|
||||
DBUG_RETURN(0);
|
||||
}
|
||||
|
@ -1551,10 +1571,14 @@ int simple_open_n_lock_tables(THD *thd, TABLE_LIST *tables)
|
|||
tables processing.
|
||||
|
||||
SYNOPSIS
|
||||
simple_open_n_lock_tables()
|
||||
open_and_lock_tables()
|
||||
thd - thread handler
|
||||
tables - list of tables for open&locking
|
||||
|
||||
RETURN
|
||||
0 - ok
|
||||
-1 - error
|
||||
|
||||
NOTE
|
||||
The lock will automaticly be freed by close_thread_tables()
|
||||
*/
|
||||
|
@ -1562,7 +1586,8 @@ int simple_open_n_lock_tables(THD *thd, TABLE_LIST *tables)
|
|||
int open_and_lock_tables(THD *thd, TABLE_LIST *tables)
|
||||
{
|
||||
DBUG_ENTER("open_and_lock_tables");
|
||||
if (open_tables(thd, tables) || lock_tables(thd, tables))
|
||||
uint counter;
|
||||
if (open_tables(thd, tables, &counter) || lock_tables(thd, tables, counter))
|
||||
DBUG_RETURN(-1); /* purecov: inspected */
|
||||
fix_tables_pointers(thd->lex->all_selects_list);
|
||||
DBUG_RETURN(mysql_handle_derived(thd->lex));
|
||||
|
@ -1576,6 +1601,7 @@ int open_and_lock_tables(THD *thd, TABLE_LIST *tables)
|
|||
lock_tables()
|
||||
thd Thread handler
|
||||
tables Tables to lock
|
||||
count umber of opened tables
|
||||
|
||||
NOTES
|
||||
You can't call lock_tables twice, as this would break the dead-lock-free
|
||||
|
@ -1587,7 +1613,7 @@ int open_and_lock_tables(THD *thd, TABLE_LIST *tables)
|
|||
-1 Error
|
||||
*/
|
||||
|
||||
int lock_tables(THD *thd,TABLE_LIST *tables)
|
||||
int lock_tables(THD *thd, TABLE_LIST *tables, uint count)
|
||||
{
|
||||
TABLE_LIST *table;
|
||||
if (!tables)
|
||||
|
@ -1596,12 +1622,6 @@ int lock_tables(THD *thd,TABLE_LIST *tables)
|
|||
if (!thd->locked_tables)
|
||||
{
|
||||
DBUG_ASSERT(thd->lock == 0); // You must lock everything at once
|
||||
uint count=0;
|
||||
for (table = tables ; table ; table=table->next)
|
||||
{
|
||||
if (!table->derived)
|
||||
count++;
|
||||
}
|
||||
TABLE **start,**ptr;
|
||||
if (!(ptr=start=(TABLE**) sql_alloc(sizeof(TABLE*)*count)))
|
||||
return -1;
|
||||
|
@ -2207,7 +2227,6 @@ insert_fields(THD *thd,TABLE_LIST *tables, const char *db_name,
|
|||
#ifndef NO_EMBEDDED_ACCESS_CHECKS
|
||||
/* Ensure that we have access right to all columns */
|
||||
if (!(table->grant.privilege & SELECT_ACL) &&
|
||||
!tables->derived &&
|
||||
check_grant_all_columns(thd,SELECT_ACL,table))
|
||||
DBUG_RETURN(-1);
|
||||
#endif
|
||||
|
|
|
@ -25,7 +25,8 @@
|
|||
#include "sql_select.h"
|
||||
#include "sql_acl.h"
|
||||
|
||||
int mysql_derived(THD *thd, LEX *lex, SELECT_LEX_UNIT *s, TABLE_LIST *t);
|
||||
static int mysql_derived(THD *thd, LEX *lex, SELECT_LEX_UNIT *s,
|
||||
TABLE_LIST *t);
|
||||
|
||||
/*
|
||||
Resolve derived tables in all queries
|
||||
|
@ -39,10 +40,10 @@ int mysql_derived(THD *thd, LEX *lex, SELECT_LEX_UNIT *s, TABLE_LIST *t);
|
|||
-1 Error
|
||||
1 Error and error message given
|
||||
*/
|
||||
|
||||
int
|
||||
mysql_handle_derived(LEX *lex)
|
||||
{
|
||||
int res= 0;
|
||||
if (lex->derived_tables)
|
||||
{
|
||||
for (SELECT_LEX *sl= lex->all_selects_list;
|
||||
|
@ -53,13 +54,12 @@ mysql_handle_derived(LEX *lex)
|
|||
cursor;
|
||||
cursor= cursor->next)
|
||||
{
|
||||
int res;
|
||||
if (cursor->derived && (res=mysql_derived(lex->thd, lex,
|
||||
cursor->derived,
|
||||
cursor)))
|
||||
{
|
||||
if (res < 0 || lex->thd->net.report_error)
|
||||
send_error(lex->thd, lex->thd->killed ? ER_SERVER_SHUTDOWN : 0);
|
||||
return 1;
|
||||
return res;
|
||||
}
|
||||
}
|
||||
if (lex->describe)
|
||||
|
@ -108,8 +108,8 @@ mysql_handle_derived(LEX *lex)
|
|||
*/
|
||||
|
||||
|
||||
int mysql_derived(THD *thd, LEX *lex, SELECT_LEX_UNIT *unit,
|
||||
TABLE_LIST *org_table_list)
|
||||
static int mysql_derived(THD *thd, LEX *lex, SELECT_LEX_UNIT *unit,
|
||||
TABLE_LIST *org_table_list)
|
||||
{
|
||||
SELECT_LEX *first_select= unit->first_select();
|
||||
TABLE *table;
|
||||
|
@ -197,7 +197,7 @@ int mysql_derived(THD *thd, LEX *lex, SELECT_LEX_UNIT *unit,
|
|||
table->derived_select_number= first_select->select_number;
|
||||
table->tmp_table= TMP_TABLE;
|
||||
#ifndef NO_EMBEDDED_ACCESS_CHECKS
|
||||
org_table_list->grant.privilege= SELECT_ACL;
|
||||
table->grant.privilege= SELECT_ACL;
|
||||
#endif
|
||||
org_table_list->db= (char *)"";
|
||||
// Force read of table stats in the optimizer
|
||||
|
|
|
@ -48,7 +48,8 @@ static TABLE **find_table_ptr_by_name(THD *thd,const char *db,
|
|||
int mysql_ha_open(THD *thd, TABLE_LIST *tables)
|
||||
{
|
||||
HANDLER_TABLES_HACK(thd);
|
||||
int err=open_tables(thd,tables);
|
||||
uint counter;
|
||||
int err=open_tables(thd, tables, &counter);
|
||||
HANDLER_TABLES_HACK(thd);
|
||||
if (err)
|
||||
return -1;
|
||||
|
|
|
@ -2669,8 +2669,8 @@ mysql_execute_command(THD *thd)
|
|||
{
|
||||
auxi->table= auxi->table_list->table;
|
||||
/*
|
||||
Multi-delete can't be constucted over-union => we always have
|
||||
single SELECT on top and have to check underlayed SELECTs of it
|
||||
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;
|
||||
|
|
Loading…
Add table
Reference in a new issue