Skip to content

Commit e73385c

Browse files
committed
Bug#32803211: 8.0.22+ triggers fail in Item::mark_field_in_map
The problem was that when INSERT ... SET ... statement or UPDATE statement was used in a trigger we have accepted reference to column in the table on which trigger was defined (using NEW or OLD designator) as an assigment target in its SET clause. This always led to assertion failures in debug builds and sometimes server failures in production builds. The problem stemmed from two facts: 1) INSERT and UPDATE statement code expects only references to their target table columns as assignment targets of the SET clause 2) we didn't block usage of trigger fields as target for such assignment, due to omission which has happened during early days of implementation of triggers. This patch solves the problem by rejecting trigger fields as SET clause assignment targets in both INSERT and UPDATE. This is an incompatible change which breaks rare user's triggers which use this syntax (which might have been working somehow due to luck). Such triggers produce an error during attempt to execute them. However, the new behavior is in line with both our documentation and SQL standard, and supporting old non-standard and non-documented behavor will require quite some efforts. The fix for the problem is to reject trigger fields as SET clause assignment targets in INSERT and UPDATE statements. Reviewed by: Dmitry Lenev <Dmitry.Lenev@oracle.com>
1 parent c57c9d9 commit e73385c

File tree

3 files changed

+14
-3
lines changed

3 files changed

+14
-3
lines changed

share/messages_to_clients.txt

+3
Original file line numberDiff line numberDiff line change
@@ -9571,6 +9571,9 @@ ER_DA_ERROR_LOG_COMPONENT_FLUSH_FAILED
95719571
ER_WARN_SQL_AFTER_MTS_GAPS_GAP_NOT_CALCULATED
95729572
eng "The until clause SQL_AFTER_MTS_GAPS is being used for channel '%.192s' when GTID_MODE = ON and SOURCE_AUTO_POSITION=1 meaning the server did not compute internally what gaps may exist in the relay log transaction execution. To close any execution gaps use either the SQL_BEFORE_GTIDS or SQL_AFTER_GTIDS until clause."
95739573

9574+
ER_INVALID_ASSIGNMENT_TARGET 42000
9575+
eng "Invalid target for assignment in INSERT or UPDATE statement '%.192s'."
9576+
95749577
#
95759578
# End of 8.0 error messages (server-to-client).
95769579
# Do NOT add messages intended for the error log above!

sql/parse_tree_items.cc

+3-3
Original file line numberDiff line numberDiff line change
@@ -410,9 +410,9 @@ bool PTI_simple_ident_q_2d::itemize(Parse_context *pc, Item **res) {
410410
sp_head *sp = lex->sphead;
411411

412412
/*
413-
FIXME This will work ok in simple_ident_nospvar case because
414-
we can't meet simple_ident_nospvar in trigger now. But it
415-
should be changed in future.
413+
References with OLD and NEW designators can be used in expressions in
414+
triggers. Semantic checks must ensure they are not used in invalid
415+
contexts, such as assignment targets.
416416
*/
417417
if (sp && sp->m_type == enum_sp_type::TRIGGER &&
418418
(!my_strcasecmp(system_charset_info, table, "NEW") ||

sql/sql_base.cc

+8
Original file line numberDiff line numberDiff line change
@@ -9033,6 +9033,14 @@ bool setup_fields(THD *thd, ulong want_privilege, bool allow_sum_func,
90339033
my_error(ER_NONUPDATEABLE_COLUMN, MYF(0), item->item_name.ptr());
90349034
return true;
90359035
}
9036+
if (item->type() == Item::TRIGGER_FIELD_ITEM) {
9037+
char buff[NAME_LEN * 2];
9038+
String str(buff, sizeof(buff), &my_charset_bin);
9039+
str.length(0);
9040+
item->print(thd, &str, QT_ORDINARY);
9041+
my_error(ER_INVALID_ASSIGNMENT_TARGET, MYF(0), str.c_ptr());
9042+
return true;
9043+
}
90369044
TABLE_LIST *tr = field->table_ref;
90379045
if ((want_privilege & UPDATE_ACL) && !tr->is_updatable()) {
90389046
/*

0 commit comments

Comments
 (0)