mirror of
https://github.com/MariaDB/server.git
synced 2026-04-27 18:55:31 +02:00
Backport of Bug#27525 to mysql-next-mr
------------------------------------------------------------ revno: 2572.2.1 revision-id: sp1r-davi@mysql.com/endora.local-20080227225948-16317 parent: sp1r-anozdrin/alik@quad.-20080226165712-10409 committer: davi@mysql.com/endora.local timestamp: Wed 2008-02-27 19:59:48 -0300 message: Bug#27525 table not found when using multi-table-deletes with aliases over several databas Bug#30234 Unexpected behavior using DELETE with AS and USING The multi-delete statement has a documented limitation that cross-database multiple-table deletes using aliases are not supported because it fails to find the tables by alias if it belongs to a different database. The problem is that when building the list of tables to delete from, if a database name is not specified (maybe an alias) it defaults to the name of the current selected database, making impossible to to properly resolve tables by alias later. Another problem is a inconsistency of the multiple table delete syntax that permits ambiguities in a delete statement (aliases that refer to multiple different tables or vice-versa). The first step for a solution and proper implementation of the cross-databse multiple table delete is to get rid of any ambiguities in a multiple table statement. Currently, the parser is accepting multiple table delete statements that have no obvious meaning, such as: DELETE a1 FROM db1.t1 AS a1, db2.t2 AS a1; DELETE a1 AS a1 FROM db1.t1 AS a1, db2.t2 AS a1; The solution is to resolve the left part of a delete statement using the right part, if the a table on right has an alias, it must be referenced in the left using the given alias. Also, each table on the left side must match unambiguously only one table in the right side. mysql-test/r/delete.result: Add test case result for Bug#27525 and Bug#21148 mysql-test/r/derived.result: Update error. mysql-test/suite/rpl/r/rpl_multi_delete2.result: Update syntax. mysql-test/suite/rpl/t/rpl_multi_delete2.test: Update syntax. mysql-test/t/delete.test: Add test case for Bug#27525 and Bug#21148 mysql-test/t/derived.test: Update statement error, alias is properly resolved now. sql/sql_parse.cc: Implement new algorithm for the resolution of alias in a multiple table delete statement. sql/sql_yacc.yy: Rework multi-delete parser rules to not accept table alias for the table source list. sql/table.h: Add flag to signal that the table has a alias set or that fully qualified table name was given.
This commit is contained in:
parent
c809048c64
commit
e26de1ca16
9 changed files with 378 additions and 28 deletions
|
|
@ -6486,13 +6486,17 @@ TABLE_LIST *st_select_lex::add_table_to_list(THD *thd,
|
|||
DBUG_RETURN(0); /* purecov: inspected */
|
||||
if (table->db.str)
|
||||
{
|
||||
ptr->is_fqtn= TRUE;
|
||||
ptr->db= table->db.str;
|
||||
ptr->db_length= table->db.length;
|
||||
}
|
||||
else if (lex->copy_db_to(&ptr->db, &ptr->db_length))
|
||||
DBUG_RETURN(0);
|
||||
else
|
||||
ptr->is_fqtn= FALSE;
|
||||
|
||||
ptr->alias= alias_str;
|
||||
ptr->is_alias= alias ? TRUE : FALSE;
|
||||
if (lower_case_table_names && table->table.length)
|
||||
table->table.length= my_casedn_str(files_charset_info, table->table.str);
|
||||
ptr->table_name=table->table.str;
|
||||
|
|
@ -7539,6 +7543,63 @@ bool multi_delete_precheck(THD *thd, TABLE_LIST *tables)
|
|||
}
|
||||
|
||||
|
||||
/*
|
||||
Given a table in the source list, find a correspondent table in the
|
||||
table references list.
|
||||
|
||||
@param lex Pointer to LEX representing multi-delete.
|
||||
@param src Source table to match.
|
||||
@param ref Table references list.
|
||||
|
||||
@remark The source table list (tables listed before the FROM clause
|
||||
or tables listed in the FROM clause before the USING clause) may
|
||||
contain table names or aliases that must match unambiguously one,
|
||||
and only one, table in the target table list (table references list,
|
||||
after FROM/USING clause).
|
||||
|
||||
@return Matching table, NULL otherwise.
|
||||
*/
|
||||
|
||||
static TABLE_LIST *multi_delete_table_match(LEX *lex, TABLE_LIST *tbl,
|
||||
TABLE_LIST *tables)
|
||||
{
|
||||
TABLE_LIST *match= NULL;
|
||||
DBUG_ENTER("multi_delete_table_match");
|
||||
|
||||
for (TABLE_LIST *elem= tables; elem; elem= elem->next_local)
|
||||
{
|
||||
int cmp;
|
||||
|
||||
if (tbl->is_fqtn && elem->is_alias)
|
||||
continue; /* no match */
|
||||
if (tbl->is_fqtn && elem->is_fqtn)
|
||||
cmp= my_strcasecmp(table_alias_charset, tbl->table_name, elem->table_name) ||
|
||||
strcmp(tbl->db, elem->db);
|
||||
else if (elem->is_alias)
|
||||
cmp= my_strcasecmp(table_alias_charset, tbl->alias, elem->alias);
|
||||
else
|
||||
cmp= my_strcasecmp(table_alias_charset, tbl->table_name, elem->table_name) ||
|
||||
strcmp(tbl->db, elem->db);
|
||||
|
||||
if (cmp)
|
||||
continue;
|
||||
|
||||
if (match)
|
||||
{
|
||||
my_error(ER_NONUNIQ_TABLE, MYF(0), elem->alias);
|
||||
DBUG_RETURN(NULL);
|
||||
}
|
||||
|
||||
match= elem;
|
||||
}
|
||||
|
||||
if (!match)
|
||||
my_error(ER_UNKNOWN_TABLE, MYF(0), tbl->table_name, "MULTI DELETE");
|
||||
|
||||
DBUG_RETURN(match);
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
Link tables in auxilary table list of multi-delete with corresponding
|
||||
elements in main table list, and set proper locks for them.
|
||||
|
|
@ -7564,20 +7625,9 @@ bool multi_delete_set_locks_and_link_aux_tables(LEX *lex)
|
|||
{
|
||||
lex->table_count++;
|
||||
/* All tables in aux_tables must be found in FROM PART */
|
||||
TABLE_LIST *walk;
|
||||
for (walk= tables; walk; walk= walk->next_local)
|
||||
{
|
||||
if (!my_strcasecmp(table_alias_charset,
|
||||
target_tbl->alias, walk->alias) &&
|
||||
!strcmp(walk->db, target_tbl->db))
|
||||
break;
|
||||
}
|
||||
TABLE_LIST *walk= multi_delete_table_match(lex, target_tbl, tables);
|
||||
if (!walk)
|
||||
{
|
||||
my_error(ER_UNKNOWN_TABLE, MYF(0),
|
||||
target_tbl->table_name, "MULTI DELETE");
|
||||
DBUG_RETURN(TRUE);
|
||||
}
|
||||
if (!walk->derived)
|
||||
{
|
||||
target_tbl->table_name= walk->table_name;
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue