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

Manual merge of patch fixing several trigger related bugs with main tree.

This commit is contained in:
dlenev@mysql.com
2005-05-24 22:35:41 +04:00
12 changed files with 634 additions and 127 deletions

View File

@ -398,14 +398,13 @@ int mysql_update(THD *thd,
if (!(select && select->skip_record()))
{
store_record(table,record[1]);
if (fill_record(thd, fields, values, 0))
if (fill_record_n_invoke_before_triggers(thd, fields, values, 0,
table->triggers,
TRG_EVENT_UPDATE))
break; /* purecov: inspected */
found++;
if (table->triggers)
table->triggers->process_triggers(thd, TRG_EVENT_UPDATE, TRG_ACTION_BEFORE);
if (compare_record(table, query_id))
{
if ((res= table_list->view_check_option(thd, ignore)) !=
@ -425,6 +424,14 @@ int mysql_update(THD *thd,
{
updated++;
thd->no_trans_update= !transactional_table;
if (table->triggers &&
table->triggers->process_triggers(thd, TRG_EVENT_UPDATE,
TRG_ACTION_AFTER, TRUE))
{
error= 1;
break;
}
}
else if (!ignore || error != HA_ERR_FOUND_DUPP_KEY)
{
@ -435,9 +442,6 @@ int mysql_update(THD *thd,
}
}
if (table->triggers)
table->triggers->process_triggers(thd, TRG_EVENT_UPDATE, TRG_ACTION_AFTER);
if (!--limit && using_limit)
{
error= -1; // Simulate end of file
@ -1073,8 +1077,8 @@ multi_update::initialize_tables(JOIN *join)
NOTES
We can update the first table in join on the fly if we know that
a row in this tabel will never be read twice. This is true under
the folloing conditions:
a row in this table will never be read twice. This is true under
the following conditions:
- We are doing a table scan and the data is in a separate file (MyISAM) or
if we don't update a clustered key.
@ -1082,6 +1086,10 @@ multi_update::initialize_tables(JOIN *join)
- We are doing a range scan and we don't update the scan key or
the primary key for a clustered table handler.
When checking for above cases we also should take into account that
BEFORE UPDATE trigger potentially may change value of any field in row
being updated.
WARNING
This code is a bit dependent of how make_join_readinfo() works.
@ -1100,15 +1108,21 @@ static bool safe_update_on_fly(JOIN_TAB *join_tab, List<Item> *fields)
return TRUE; // At most one matching row
case JT_REF:
case JT_REF_OR_NULL:
return !check_if_key_used(table, join_tab->ref.key, *fields);
return !check_if_key_used(table, join_tab->ref.key, *fields) &&
!(table->triggers &&
table->triggers->has_before_update_triggers());
case JT_ALL:
/* If range search on index */
if (join_tab->quick)
return !join_tab->quick->check_if_keys_used(fields);
return !join_tab->quick->check_if_keys_used(fields) &&
!(table->triggers &&
table->triggers->has_before_update_triggers());
/* If scanning in clustered key */
if ((table->file->table_flags() & HA_PRIMARY_KEY_IN_READ_INDEX) &&
table->s->primary_key < MAX_KEY)
return !check_if_key_used(table, table->s->primary_key, *fields);
return !check_if_key_used(table, table->s->primary_key, *fields) &&
!(table->triggers &&
table->triggers->has_before_update_triggers());
return TRUE;
default:
break; // Avoid compler warning
@ -1171,8 +1185,10 @@ bool multi_update::send_data(List<Item> &not_used_values)
{
table->status|= STATUS_UPDATED;
store_record(table,record[1]);
if (fill_record(thd, *fields_for_table[offset],
*values_for_table[offset], 0))
if (fill_record_n_invoke_before_triggers(thd, *fields_for_table[offset],
*values_for_table[offset], 0,
table->triggers,
TRG_EVENT_UPDATE))
DBUG_RETURN(1);
found++;
@ -1208,8 +1224,15 @@ bool multi_update::send_data(List<Item> &not_used_values)
DBUG_RETURN(1);
}
}
else if (!table->file->has_transactions())
thd->no_trans_update= 1;
else
{
if (!table->file->has_transactions())
thd->no_trans_update= 1;
if (table->triggers &&
table->triggers->process_triggers(thd, TRG_EVENT_UPDATE,
TRG_ACTION_AFTER, TRUE))
DBUG_RETURN(1);
}
}
}
else
@ -1330,6 +1353,11 @@ int multi_update::do_updates(bool from_send_error)
copy_field_ptr++)
(*copy_field_ptr->do_copy)(copy_field_ptr);
if (table->triggers &&
table->triggers->process_triggers(thd, TRG_EVENT_UPDATE,
TRG_ACTION_BEFORE, TRUE))
goto err2;
if (compare_record(table, thd->query_id))
{
if ((local_error=table->file->update_row(table->record[1],
@ -1339,6 +1367,11 @@ int multi_update::do_updates(bool from_send_error)
goto err;
}
updated++;
if (table->triggers &&
table->triggers->process_triggers(thd, TRG_EVENT_UPDATE,
TRG_ACTION_AFTER, TRUE))
goto err2;
}
}
@ -1361,6 +1394,7 @@ err:
table->file->print_error(local_error,MYF(0));
}
err2:
(void) table->file->ha_rnd_end();
(void) tmp_table->file->ha_rnd_end();