1
0
mirror of https://github.com/MariaDB/server.git synced 2025-07-29 05:21:33 +03:00

Manual merge from mysql-trunk-merge.

This commit is contained in:
Alexander Nozdrin
2009-10-14 12:25:39 +04:00
170 changed files with 7269 additions and 526 deletions

View File

@ -860,22 +860,19 @@ void multi_delete::abort()
/*
/**
Do delete from other tables.
Returns values:
0 ok
1 error
@retval 0 ok
@retval 1 error
@todo Is there any reason not use the normal nested-loops join? If not, and
there is no documentation supporting it, this method and callee should be
removed and there should be hooks within normal execution.
*/
int multi_delete::do_deletes()
{
int local_error= 0, counter= 0, tmp_error;
bool will_batch;
/*
If the IGNORE option is used all non fatal errors will be translated
to warnings and we should not break the row-by-row iteration
*/
bool ignore= thd->lex->current_select->no_error;
DBUG_ENTER("do_deletes");
DBUG_ASSERT(do_delete);
@ -886,79 +883,108 @@ int multi_delete::do_deletes()
table_being_deleted= (delete_while_scanning ? delete_tables->next_local :
delete_tables);
for (; table_being_deleted;
for (uint counter= 0; table_being_deleted;
table_being_deleted= table_being_deleted->next_local, counter++)
{
ha_rows last_deleted= deleted;
TABLE *table = table_being_deleted->table;
if (tempfiles[counter]->get(table))
DBUG_RETURN(1);
int local_error=
do_table_deletes(table, thd->lex->current_select->no_error);
if (thd->killed && !local_error)
DBUG_RETURN(1);
if (local_error == -1) // End of file
local_error = 0;
if (local_error)
DBUG_RETURN(local_error);
}
DBUG_RETURN(0);
}
/**
Implements the inner loop of nested-loops join within multi-DELETE
execution.
@param table The table from which to delete.
@param ignore If used, all non fatal errors will be translated
to warnings and we should not break the row-by-row iteration.
@return Status code
@retval 0 All ok.
@retval 1 Triggers or handler reported error.
@retval -1 End of file from handler.
*/
int multi_delete::do_table_deletes(TABLE *table, bool ignore)
{
int local_error= 0;
READ_RECORD info;
ha_rows last_deleted= deleted;
DBUG_ENTER("do_deletes_for_table");
init_read_record(&info, thd, table, NULL, 0, 1, FALSE);
/*
Ignore any rows not found in reference tables as they may already have
been deleted by foreign key handling
*/
info.ignore_not_found_rows= 1;
bool will_batch= !table->file->start_bulk_delete();
while (!(local_error= info.read_record(&info)) && !thd->killed)
{
if (table->triggers &&
table->triggers->process_triggers(thd, TRG_EVENT_DELETE,
TRG_ACTION_BEFORE, FALSE))
{
local_error=1;
local_error= 1;
break;
}
READ_RECORD info;
init_read_record(&info, thd, table, NULL, 0, 1, FALSE);
/*
Ignore any rows not found in reference tables as they may already have
been deleted by foreign key handling
*/
info.ignore_not_found_rows= 1;
will_batch= !table->file->start_bulk_delete();
while (!(local_error=info.read_record(&info)) && !thd->killed)
local_error= table->file->ha_delete_row(table->record[0]);
if (local_error && !ignore)
{
table->file->print_error(local_error, MYF(0));
break;
}
/*
Increase the reported number of deleted rows only if no error occurred
during ha_delete_row.
Also, don't execute the AFTER trigger if the row operation failed.
*/
if (!local_error)
{
deleted++;
if (table->triggers &&
table->triggers->process_triggers(thd, TRG_EVENT_DELETE,
TRG_ACTION_BEFORE, FALSE))
TRG_ACTION_AFTER, FALSE))
{
local_error= 1;
break;
}
local_error= table->file->ha_delete_row(table->record[0]);
if (local_error && !ignore)
{
table->file->print_error(local_error,MYF(0));
break;
}
/*
Increase the reported number of deleted rows only if no error occurred
during ha_delete_row.
Also, don't execute the AFTER trigger if the row operation failed.
*/
if (!local_error)
{
deleted++;
if (table->triggers &&
table->triggers->process_triggers(thd, TRG_EVENT_DELETE,
TRG_ACTION_AFTER, FALSE))
{
local_error= 1;
break;
}
}
}
if (will_batch && (tmp_error= table->file->end_bulk_delete()))
{
if (!local_error)
{
local_error= tmp_error;
table->file->print_error(local_error,MYF(0));
}
}
if (last_deleted != deleted && !table->file->has_transactions())
thd->transaction.stmt.modified_non_trans_table= TRUE;
end_read_record(&info);
if (thd->killed && !local_error)
local_error= 1;
if (local_error == -1) // End of file
local_error = 0;
}
if (will_batch)
{
int tmp_error= table->file->end_bulk_delete();
if (tmp_error && !local_error)
{
local_error= tmp_error;
table->file->print_error(local_error, MYF(0));
}
}
if (last_deleted != deleted && !table->file->has_transactions())
thd->transaction.stmt.modified_non_trans_table= TRUE;
end_read_record(&info);
DBUG_RETURN(local_error);
}
/*
Send ok to the client