Skip to content

Commit cd66c5c

Browse files
author
Ajo Robert
committed
Bug#37337527 >= 8.0.27 Error 1048 when updating row with empty_sql mode
An UPDATE following an INSERT on tables with before insert trigger can sometime fail with null value error if the INSERT had added a null value to non-null column. This happens when null values are inserted into non-null fields under allowed sql_mode. The before insert trigger sets tmp_null flag for the non-null field indicating the temporary null status as part of the insert. This flag is not reset at the end of trigger processing and used during the subsequent UPDATE command. This unexpected null flag is causing the update to fail with null-value error even though the update is not handling any null. Fix: Reset the tmp_null flag at the end of insert trigger flow processing. Change-Id: If9524a7aee17130ee53becbe47229f50bdbc49d2
1 parent a7ea07e commit cd66c5c

File tree

5 files changed

+42
-1
lines changed

5 files changed

+42
-1
lines changed

mysql-test/r/trigger.result

+15
Original file line numberDiff line numberDiff line change
@@ -3417,3 +3417,18 @@ Trigger sql_mode SQL Original Statement character_set_client collation_connectio
34173417
DROP TRIGGER очень_очень_очень_очень_очень_очень_очень_очень_длинная_строка_é;
34183418
DROP TABLE t1;
34193419
SET NAMES default;
3420+
#
3421+
# Bug#37337527 >= 8.0.27 Error 1048 when updating row with empty_sql mode
3422+
#
3423+
CREATE TABLE t1 (c1 INT, c2 INT NOT NULL);
3424+
CREATE TRIGGER t_t1 BEFORE INSERT ON t1 FOR EACH ROW BEGIN END;
3425+
SET SESSION sql_mode = '';
3426+
INSERT INTO t1(c1) VALUES (1);
3427+
Warnings:
3428+
Warning 1364 Field 'c2' doesn't have a default value
3429+
SELECT * FROM t1;
3430+
c1 c2
3431+
1 0
3432+
UPDATE t1 SET c2=3 WHERE c1=1;
3433+
DROP TABLE t1;
3434+
SET sql_mode=default;

mysql-test/t/trigger.test

+13
Original file line numberDiff line numberDiff line change
@@ -4109,3 +4109,16 @@ DROP TRIGGER очень_очень_очень_очень_очень_очень_
41094109

41104110
DROP TABLE t1;
41114111
SET NAMES default;
4112+
4113+
--echo #
4114+
--echo # Bug#37337527 >= 8.0.27 Error 1048 when updating row with empty_sql mode
4115+
--echo #
4116+
CREATE TABLE t1 (c1 INT, c2 INT NOT NULL);
4117+
CREATE TRIGGER t_t1 BEFORE INSERT ON t1 FOR EACH ROW BEGIN END;
4118+
4119+
SET SESSION sql_mode = '';
4120+
INSERT INTO t1(c1) VALUES (1);
4121+
SELECT * FROM t1;
4122+
UPDATE t1 SET c2=3 WHERE c1=1;
4123+
DROP TABLE t1;
4124+
SET sql_mode=default;

sql/sql_base.cc

+3-1
Original file line numberDiff line numberDiff line change
@@ -9880,8 +9880,10 @@ bool fill_record_n_invoke_before_triggers(
98809880
}
98819881

98829882
table->triggers->disable_fields_temporary_nullability();
9883+
rc = rc || check_inserting_record(thd, table->field);
9884+
table->triggers->reset_field_nulls();
98839885

9884-
return rc || check_inserting_record(thd, table->field);
9886+
return rc;
98859887
} else {
98869888
if (fill_record(thd, table, fields, values, nullptr, nullptr,
98879889
raise_autoinc_has_expl_non_null_val))

sql/table_trigger_dispatcher.cc

+10
Original file line numberDiff line numberDiff line change
@@ -639,6 +639,16 @@ void Table_trigger_dispatcher::disable_fields_temporary_nullability() {
639639
(*next_field)->reset_tmp_nullable();
640640
}
641641

642+
/**
643+
Reset the temporary null values set to the field for triggers.
644+
*/
645+
void Table_trigger_dispatcher::reset_field_nulls() {
646+
assert(m_subject_table);
647+
648+
for (Field **next_field = m_subject_table->field; *next_field; ++next_field)
649+
(*next_field)->reset_tmp_null();
650+
}
651+
642652
/**
643653
Iterate along triggers and print necessary upgrade warnings.
644654

sql/table_trigger_dispatcher.h

+1
Original file line numberDiff line numberDiff line change
@@ -161,6 +161,7 @@ class Table_trigger_dispatcher : public Table_trigger_field_support {
161161

162162
void enable_fields_temporary_nullability(THD *thd);
163163
void disable_fields_temporary_nullability();
164+
void reset_field_nulls();
164165

165166
void print_upgrade_warnings(THD *thd);
166167

0 commit comments

Comments
 (0)