1
0
mirror of https://github.com/MariaDB/server.git synced 2025-07-30 16:24:05 +03:00

MDEV-19761 Before Trigger not processed for Not Null Columns if no explicit value and no DEFAULT

it's incorrect to zero out table->triggers->extra_null_bitmap
before a statement, because if insert uses an explicit field list
and omits a field that has no default value, the field should
get NULL implicitly. So extra_null_bitmap should have 1s for all
fields that have no defaults

* create extra_null_bitmap_init and initialize it as above
* copy extra_null_bitmap_init to extra_null_bitmap for inserts
* still zero out extra_null_bitmap for updates/deletes where
  all fields definitely have a value
* make not_null_fields_have_null_values() to send
  ER_NO_DEFAULT_FOR_FIELD for fields with no default and no value,
  otherwise creation of a trigger with an empty body would change the
  error message
This commit is contained in:
Sergei Golubchik
2024-12-23 21:27:00 +01:00
parent 350cc77fee
commit a69da0c31e
15 changed files with 127 additions and 74 deletions

View File

@ -1019,7 +1019,7 @@ bool mysql_insert(THD *thd, TABLE_LIST *table_list,
INSERT INTO t1 (fields) VALUES ...
INSERT INTO t1 VALUES ()
*/
restore_record(table,s->default_values); // Get empty record
restore_default_record_for_insert(table);
table->reset_default_fields();
if (unlikely(fill_record_n_invoke_before_triggers(thd, table, fields,
@ -1048,7 +1048,7 @@ bool mysql_insert(THD *thd, TABLE_LIST *table_list,
*/
if (thd->lex->used_tables || // Column used in values()
table->s->visible_fields != table->s->fields)
restore_record(table,s->default_values); // Get empty record
restore_default_record_for_insert(table);
else
{
TABLE_SHARE *share= table->s;
@ -1085,24 +1085,6 @@ bool mysql_insert(THD *thd, TABLE_LIST *table_list,
}
}
/*
with triggers a field can get a value *conditionally*, so we have to
repeat has_no_default_value() check for every row
*/
if (table->triggers &&
table->triggers->has_triggers(TRG_EVENT_INSERT, TRG_ACTION_BEFORE))
{
for (Field **f=table->field ; *f ; f++)
{
if (unlikely(!(*f)->has_explicit_value() &&
has_no_default_value(thd, *f, table_list)))
{
error= 1;
goto values_loop_end;
}
}
}
if ((res= table_list->view_check_option(thd,
(values_list.elements == 1 ?
0 :
@ -4081,7 +4063,7 @@ select_insert::prepare(List<Item> &values, SELECT_LEX_UNIT *u)
*/
table->file->ha_start_bulk_insert((ha_rows) 0);
}
restore_record(table,s->default_values); // Get empty record
restore_default_record_for_insert(table);
table->reset_default_fields();
table->next_number_field=table->found_next_number_field;
@ -4226,7 +4208,7 @@ int select_insert::send_data(List<Item> &values)
originally touched by INSERT ... SELECT, so we have to restore
their original values for the next row.
*/
restore_record(table, s->default_values);
restore_default_record_for_insert(table);
}
if (table->next_number_field)
{