mirror of
https://github.com/MariaDB/server.git
synced 2026-01-06 05:22:24 +03:00
After merge fixes for patch solving bug#18437 "Wrong values inserted with a
before update trigger on NDB table".
Two main changes:
- We use TABLE::read_set/write_set bitmaps for marking fields used by
statement instead of Field::query_id in 5.1.
- Now when we mark columns used by statement we take into account columns
used by table's triggers instead of marking all columns as used if table
has triggers.
mysql-test/r/federated.result:
Changed test in order to make it work with RBR.
RBR changes the way in which we execute "DELETE FROM t1" statement - we don't
use handler::delete_all_rows() method if RBR is enabled (see bug#19066).
As result federated engine produces different sequences of statements for
remote server in non-RBR and in RBR cases. And this changes order of the
rows inserted by following INSERT statements.
mysql-test/t/federated.test:
Changed test in order to make it work with RBR.
RBR changes the way in which we execute "DELETE FROM t1" statement - we don't
use handler::delete_all_rows() method if RBR is enabled (see bug#19066).
As result federated engine produces different sequences of statements for
remote server in non-RBR and in RBR cases. And this changes order of the
rows inserted by following INSERT statements.
sql/ha_partition.cc:
Added handling of HA_EXTRA_WRITE_CAN_REPLACE/HA_EXTRA_WRITE_CANNOT_REPLACE
to ha_partition::extra().
sql/item.cc:
Adjusted comment after merge. In 5.1 we use TABLE::read_set/write_set
bitmaps instead of Field::query_id for marking columns used.
sql/log_event.cc:
Write_rows_log_event::do_before_row_operations():
Now we explicitly inform handler that we want to replace rows so it can
promote operation done by write_row() to replace.
sql/mysql_priv.h:
Removed declaration of mark_fields_used_by_triggers_for_insert_stmt() which
is no longer used (we have TABLE::mark_columns_needed_for_insert() instead).
sql/sql_insert.cc:
Adjusted code after merge. Get rid of mark_fields_used_by_triggers_for_insert_stmt()
as now we use TABLE::mark_columns_needed_for_insert() for the same purprose.
Aligned places where we call this method with places where we call
mark_fields_used_by_triggers_for_insert() in 5.0.
Finally we no longer need to call handler::extra(HA_EXTRA_WRITE_CAN_REPLACE)
in case of REPLACE statement since in 5.1 write_record() marks all columns
as used before doing actual row replacement.
sql/sql_load.cc:
Adjusted code after merge. In 5.1 we use TABLE::mark_columns_needed_for_insert() instead of
mark_fields_used_by_triggers_for_insert_stmt() routine. We also no longer
need to call handler::extra(HA_EXTRA_RETRIEVE_ALL_COLS) if we execute LOAD
DATA REPLACE since in 5.1 write_record() will mark all columns as used before
doing actual row replacement.
sql/sql_trigger.cc:
Table_triggers_list::mark_fields_used():
We use TABLE::read_set/write_set bitmaps for marking fields used instead
of Field::query_id in 5.1.
sql/sql_trigger.h:
TABLE::mark_columns_needed_for_* methods no longer need to be friends of
Table_triggers_list class as intead of dirrectly accessing its private
members they can use public Table_triggers_list::mark_fields_used() method.
Also Table_triggers)list::mark_fields_used() no longer needs THD argument.
sql/table.cc:
TABLE::mark_columns_needed_for_*():
Now we mark columns which are really used by table's triggers instead of
marking all columns as used if table has triggers.
This commit is contained in:
@@ -181,9 +181,6 @@ static int check_insert_fields(THD *thd, TABLE_LIST *table_list,
|
||||
}
|
||||
}
|
||||
}
|
||||
if (table->found_next_number_field)
|
||||
table->mark_auto_increment_column();
|
||||
table->mark_columns_needed_for_insert();
|
||||
// For the values we need select_priv
|
||||
#ifndef NO_EMBEDDED_ACCESS_CHECKS
|
||||
table->grant.want_privilege= (SELECT_ACL & ~table->grant.privilege);
|
||||
@@ -255,33 +252,6 @@ static int check_update_fields(THD *thd, TABLE_LIST *insert_table_list,
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
Mark fields used by triggers for INSERT-like statement.
|
||||
|
||||
SYNOPSIS
|
||||
mark_fields_used_by_triggers_for_insert_stmt()
|
||||
thd The current thread
|
||||
table Table to which insert will happen
|
||||
duplic Type of duplicate handling for insert which will happen
|
||||
|
||||
NOTE
|
||||
For REPLACE there is no sense in marking particular fields
|
||||
used by ON DELETE trigger as to execute it properly we have
|
||||
to retrieve and store values for all table columns anyway.
|
||||
*/
|
||||
|
||||
void mark_fields_used_by_triggers_for_insert_stmt(THD *thd, TABLE *table,
|
||||
enum_duplicates duplic)
|
||||
{
|
||||
if (table->triggers)
|
||||
{
|
||||
table->triggers->mark_fields_used(thd, TRG_EVENT_INSERT);
|
||||
if (duplic == DUP_UPDATE)
|
||||
table->triggers->mark_fields_used(thd, TRG_EVENT_UPDATE);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
bool mysql_insert(THD *thd,TABLE_LIST *table_list,
|
||||
List<Item> &fields,
|
||||
List<List_item> &values_list,
|
||||
@@ -442,17 +412,9 @@ bool mysql_insert(THD *thd,TABLE_LIST *table_list,
|
||||
thd->proc_info="update";
|
||||
if (duplic != DUP_ERROR || ignore)
|
||||
table->file->extra(HA_EXTRA_IGNORE_DUP_KEY);
|
||||
if (duplic == DUP_REPLACE)
|
||||
{
|
||||
if (!table->triggers || !table->triggers->has_delete_triggers())
|
||||
table->file->extra(HA_EXTRA_WRITE_CAN_REPLACE);
|
||||
/*
|
||||
REPLACE should change values of all columns so we should mark
|
||||
all columns as columns to be set. As nice side effect we will
|
||||
retrieve columns which values are needed for ON DELETE triggers.
|
||||
*/
|
||||
table->file->extra(HA_EXTRA_RETRIEVE_ALL_COLS);
|
||||
}
|
||||
if (duplic == DUP_REPLACE &&
|
||||
(!table->triggers || !table->triggers->has_delete_triggers()))
|
||||
table->file->extra(HA_EXTRA_WRITE_CAN_REPLACE);
|
||||
/*
|
||||
let's *try* to start bulk inserts. It won't necessary
|
||||
start them as values_list.elements should be greater than
|
||||
@@ -481,7 +443,7 @@ bool mysql_insert(THD *thd,TABLE_LIST *table_list,
|
||||
error= 1;
|
||||
}
|
||||
|
||||
mark_fields_used_by_triggers_for_insert_stmt(thd, table, duplic);
|
||||
table->mark_columns_needed_for_insert();
|
||||
|
||||
if (table_list->prepare_where(thd, 0, TRUE) ||
|
||||
table_list->prepare_check_option(thd))
|
||||
@@ -2346,12 +2308,9 @@ select_insert::prepare(List<Item> &values, SELECT_LEX_UNIT *u)
|
||||
thd->cuted_fields=0;
|
||||
if (info.ignore || info.handle_duplicates != DUP_ERROR)
|
||||
table->file->extra(HA_EXTRA_IGNORE_DUP_KEY);
|
||||
if (info.handle_duplicates == DUP_REPLACE)
|
||||
{
|
||||
if (!table->triggers || !table->triggers->has_delete_triggers())
|
||||
table->file->extra(HA_EXTRA_WRITE_CAN_REPLACE);
|
||||
table->file->extra(HA_EXTRA_RETRIEVE_ALL_COLS);
|
||||
}
|
||||
if (info.handle_duplicates == DUP_REPLACE &&
|
||||
(!table->triggers || !table->triggers->has_delete_triggers()))
|
||||
table->file->extra(HA_EXTRA_WRITE_CAN_REPLACE);
|
||||
thd->no_trans_update= 0;
|
||||
thd->abort_on_warning= (!info.ignore &&
|
||||
(thd->variables.sql_mode &
|
||||
@@ -2363,8 +2322,8 @@ select_insert::prepare(List<Item> &values, SELECT_LEX_UNIT *u)
|
||||
table_list->prepare_check_option(thd));
|
||||
|
||||
if (!res)
|
||||
mark_fields_used_by_triggers_for_insert_stmt(thd, table,
|
||||
info.handle_duplicates);
|
||||
table->mark_columns_needed_for_insert();
|
||||
|
||||
DBUG_RETURN(res);
|
||||
}
|
||||
|
||||
@@ -2840,12 +2799,9 @@ select_create::prepare(List<Item> &values, SELECT_LEX_UNIT *u)
|
||||
thd->cuted_fields=0;
|
||||
if (info.ignore || info.handle_duplicates != DUP_ERROR)
|
||||
table->file->extra(HA_EXTRA_IGNORE_DUP_KEY);
|
||||
if (info.handle_duplicates == DUP_REPLACE)
|
||||
{
|
||||
if (!table->triggers || !table->triggers->has_delete_triggers())
|
||||
table->file->extra(HA_EXTRA_WRITE_CAN_REPLACE);
|
||||
table->file->extra(HA_EXTRA_RETRIEVE_ALL_COLS);
|
||||
}
|
||||
if (info.handle_duplicates == DUP_REPLACE &&
|
||||
(!table->triggers || !table->triggers->has_delete_triggers()))
|
||||
table->file->extra(HA_EXTRA_WRITE_CAN_REPLACE);
|
||||
if (!thd->prelocked_mode)
|
||||
table->file->ha_start_bulk_insert((ha_rows) 0);
|
||||
thd->no_trans_update= 0;
|
||||
@@ -2853,8 +2809,10 @@ select_create::prepare(List<Item> &values, SELECT_LEX_UNIT *u)
|
||||
(thd->variables.sql_mode &
|
||||
(MODE_STRICT_TRANS_TABLES |
|
||||
MODE_STRICT_ALL_TABLES)));
|
||||
DBUG_RETURN(check_that_all_fields_are_given_values(thd, table,
|
||||
table_list));
|
||||
if (check_that_all_fields_are_given_values(thd, table, table_list))
|
||||
DBUG_RETURN(1);
|
||||
table->mark_columns_needed_for_insert();
|
||||
DBUG_RETURN(0);
|
||||
}
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user