summaryrefslogtreecommitdiff
path: root/sql/sql_update.cc
diff options
context:
space:
mode:
authorAleksey Midenkov <midenok@gmail.com>2020-04-02 20:48:38 +0300
committerAleksey Midenkov <midenok@gmail.com>2020-04-02 20:48:38 +0300
commit0932c5804d720e1e1ee1d632ad424883dddfeea0 (patch)
tree163e10765c02d78f94e37776a38c5c06679d1c52 /sql/sql_update.cc
parentba34f409ad104471d1f642a86bf192f1d9c3537d (diff)
downloadmariadb-git-0932c5804d720e1e1ee1d632ad424883dddfeea0.tar.gz
MDEV-20515 multi-update tries to position updated table by null reference
Cause Join tmp table inserts null row because of OUTER JOIN, that's expected. Since `multi_update::prepare2()` converted `Item_temptable_rowid` into `Item_field` (28dbdf3) `multi_update::send_data()` accesses join tmp record directly and treats it as a normal row ignoring null status of ref field. NULL ref field is then treated as normal in `multi_update::do_updates()` which tries to position updated table by reference 0. Note that reference 0 may be valid reference and the first row of table can be wrongly updated (see multi_update.test). Fix Do not add row into multi-update tmp table in case of null ref field. Join tmp table does not have null_row status at this time (as well as `STATUS_NULL_ROW`) and cannot be skipped by these properties (see first comment in multi_update::send_data()). But it has all null fields (including the ref field).
Diffstat (limited to 'sql/sql_update.cc')
-rw-r--r--sql/sql_update.cc4
1 files changed, 4 insertions, 0 deletions
diff --git a/sql/sql_update.cc b/sql/sql_update.cc
index 10b62af3d6f..56ff0ee4b34 100644
--- a/sql/sql_update.cc
+++ b/sql/sql_update.cc
@@ -2467,6 +2467,9 @@ int multi_update::send_data(List<Item> &not_used_values)
TABLE *tmp_table= tmp_tables[offset];
if (copy_funcs(tmp_table_param[offset].items_to_copy, thd))
DBUG_RETURN(1);
+ /* rowid field is NULL if join tmp table has null row from outer join */
+ if (tmp_table->field[0]->is_null())
+ continue;
/* Store regular updated fields in the row. */
DBUG_ASSERT(1 + unupdated_check_opt_tables.elements ==
tmp_table_param[offset].func_count);
@@ -2671,6 +2674,7 @@ int multi_update::do_updates()
uint field_num= 0;
do
{
+ DBUG_ASSERT(!tmp_table->field[field_num]->is_null());
if (unlikely((local_error=
tbl->file->ha_rnd_pos(tbl->record[0],
(uchar *) tmp_table->