summaryrefslogtreecommitdiff
path: root/sql/sql_parse.cc
diff options
context:
space:
mode:
authordlenev@brandersnatch.localdomain <>2005-06-09 01:07:52 +0400
committerdlenev@brandersnatch.localdomain <>2005-06-09 01:07:52 +0400
commit5394a1a4bddc7fad8d8d490c5d1a902152916a2f (patch)
tree5f8aa229b96ac3ed689847d17b87a35fd44cff21 /sql/sql_parse.cc
parent620d42318bc8235342c502263e031d4a714f1c79 (diff)
downloadmariadb-git-5394a1a4bddc7fad8d8d490c5d1a902152916a2f.tar.gz
Fix for bug #11158 "Can't perform multi-delete in stored procedure".
In order to make multi-delete SP friendly we need to have all table locks for the elements of main statement table list properly set at the end of parsing. Also performed small cleanup: We don't need relink_tables_for_multidelete() any longer since the only case now when TABLE_LIST::correspondent_table is non-zero are tables in auxilary table list of multi-delete and these tables are handled specially in mysql_multi_delete_prepare().
Diffstat (limited to 'sql/sql_parse.cc')
-rw-r--r--sql/sql_parse.cc49
1 files changed, 31 insertions, 18 deletions
diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc
index 7d00cfa4c98..ba316e84c73 100644
--- a/sql/sql_parse.cc
+++ b/sql/sql_parse.cc
@@ -3291,10 +3291,9 @@ end_with_restore_list:
DBUG_ASSERT(first_table == all_tables && first_table != 0);
TABLE_LIST *aux_tables=
(TABLE_LIST *)thd->lex->auxilliary_table_list.first;
- uint table_count;
multi_delete *result;
- if ((res= multi_delete_precheck(thd, all_tables, &table_count)))
+ if ((res= multi_delete_precheck(thd, all_tables)))
break;
/* condition will be TRUE on SP re-excuting */
@@ -3311,7 +3310,7 @@ end_with_restore_list:
goto error;
if (!thd->is_fatal_error && (result= new multi_delete(thd,aux_tables,
- table_count)))
+ lex->table_count)))
{
res= mysql_select(thd, &select_lex->ref_pointer_array,
select_lex->get_table_list(),
@@ -6799,23 +6798,19 @@ bool multi_update_precheck(THD *thd, TABLE_LIST *tables)
multi_delete_precheck()
thd Thread handler
tables Global/local table list
- table_count Pointer to table counter
RETURN VALUE
FALSE OK
TRUE error
*/
-bool multi_delete_precheck(THD *thd, TABLE_LIST *tables, uint *table_count)
+bool multi_delete_precheck(THD *thd, TABLE_LIST *tables)
{
SELECT_LEX *select_lex= &thd->lex->select_lex;
TABLE_LIST *aux_tables=
(TABLE_LIST *)thd->lex->auxilliary_table_list.first;
- TABLE_LIST *target_tbl;
DBUG_ENTER("multi_delete_precheck");
- *table_count= 0;
-
/* sql_yacc guarantees that tables and aux_tables are not zero */
DBUG_ASSERT(aux_tables != 0);
if (check_db_used(thd, tables) || check_db_used(thd,aux_tables) ||
@@ -6828,9 +6823,35 @@ bool multi_delete_precheck(THD *thd, TABLE_LIST *tables, uint *table_count)
ER(ER_UPDATE_WITHOUT_KEY_IN_SAFE_MODE), MYF(0));
DBUG_RETURN(TRUE);
}
- for (target_tbl= aux_tables; target_tbl; target_tbl= target_tbl->next_local)
+ DBUG_RETURN(FALSE);
+}
+
+
+/*
+ Link tables in auxilary table list of multi-delete with corresponding
+ elements in main table list, and set proper locks for them.
+
+ SYNOPSIS
+ multi_delete_set_locks_and_link_aux_tables()
+ lex - pointer to LEX representing multi-delete
+
+ RETURN VALUE
+ FALSE - success
+ TRUE - error
+*/
+
+bool multi_delete_set_locks_and_link_aux_tables(LEX *lex)
+{
+ TABLE_LIST *tables= (TABLE_LIST*)lex->select_lex.table_list.first;
+ TABLE_LIST *target_tbl;
+ DBUG_ENTER("multi_delete_set_locks_and_link_aux_tables");
+
+ lex->table_count= 0;
+
+ for (target_tbl= (TABLE_LIST *)lex->auxilliary_table_list.first;
+ target_tbl; target_tbl= target_tbl->next_local)
{
- (*table_count)++;
+ 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)
@@ -6848,14 +6869,6 @@ bool multi_delete_precheck(THD *thd, TABLE_LIST *tables, uint *table_count)
}
walk->lock_type= target_tbl->lock_type;
target_tbl->correspondent_table= walk; // Remember corresponding table
-
- /* in case of subselects, we need to set lock_type in
- * corresponding table in list of all tables */
- if (walk->correspondent_table)
- {
- target_tbl->correspondent_table= walk->correspondent_table;
- walk->correspondent_table->lock_type= walk->lock_type;
- }
}
DBUG_RETURN(FALSE);
}