Bug #22990029 GCOLS: INCORRECT BEHAVIOR AFTER DATA INSERTED WITH IGNORE KEYWORD

PROBLEM
-------

1. We are inserting a base column entry which causes an invalid value
   by the function provided to generate virtual column,but we go ahead
   and insert this due to ignore keyword.
2. We then delete this record, making this record delete marked in innodb.
   If we try to insert another record with the same pk as the deleted
   record and if the rec is not purged ,then we try to undelete mark this
   record and try to build a update vector with previous and updated value
   and while calculating the value of virtual column we get error from
   server that we cannot calculate this from base column.
   Innodb assumes that innobase_get_computed_value() Should always return
   a valid value for the base column present in the row. The failure of
   this call was not handled ,so we were crashing.

FIX
This commit is contained in:
Aditya A 2018-10-10 18:05:02 +05:30 committed by Marko Mäkelä
parent e32305e505
commit aa8a31dadd
4 changed files with 23 additions and 8 deletions

View file

@ -1,6 +1,6 @@
/*****************************************************************************
Copyright (c) 1996, 2016, Oracle and/or its affiliates. All Rights Reserved.
Copyright (c) 1996, 2018, Oracle and/or its affiliates. All Rights Reserved.
Copyright (c) 2018, MariaDB Corporation.
This program is free software; you can redistribute it and/or modify it under
@ -219,6 +219,7 @@ the equal ordering fields. NOTE: we compare the fields as binary strings!
@param[in] heap memory heap from which allocated
@param[in,out] mysql_table NULL, or mysql table object when
user thread invokes dml
@param[out] error error number in case of failure
@return own: update vector of differing fields, excluding roll ptr and
trx id */
upd_t*
@ -230,8 +231,9 @@ row_upd_build_difference_binary(
bool no_sys,
trx_t* trx,
mem_heap_t* heap,
TABLE* mysql_table)
MY_ATTRIBUTE((nonnull(1,2,3,7), warn_unused_result));
TABLE* mysql_table,
dberr_t* error)
MY_ATTRIBUTE((nonnull(1,2,3,7,9), warn_unused_result));
/***********************************************************//**
Replaces the new column values stored in the update vector to the index entry
given. */

View file

@ -326,7 +326,7 @@ row_ins_clust_index_entry_by_modify(
{
const rec_t* rec;
upd_t* update;
dberr_t err;
dberr_t err = DB_SUCCESS;
btr_cur_t* cursor = btr_pcur_get_btr_cur(pcur);
TABLE* mysql_table = NULL;
ut_ad(dict_index_is_clust(cursor->index));
@ -349,7 +349,11 @@ row_ins_clust_index_entry_by_modify(
update = row_upd_build_difference_binary(
cursor->index, entry, rec, NULL, true,
thr_get_trx(thr), heap, mysql_table);
thr_get_trx(thr), heap, mysql_table, &err);
if (err != DB_SUCCESS) {
return(err);
}
if (mode != BTR_MODIFY_TREE) {
ut_ad((mode & ~BTR_ALREADY_S_LATCHED) == BTR_MODIFY_LEAF);

View file

@ -2042,7 +2042,10 @@ func_exit_committed:
row, NULL, index, heap, ROW_BUILD_NORMAL);
upd_t* update = row_upd_build_difference_binary(
index, entry, btr_pcur_get_rec(&pcur), cur_offsets,
false, NULL, heap, dup->table);
false, NULL, heap, dup->table, &error);
if (error != DB_SUCCESS) {
goto func_exit;
}
if (!update->n_fields) {
/* Nothing to do. */

View file

@ -1036,8 +1036,9 @@ the equal ordering fields. NOTE: we compare the fields as binary strings!
@param[in] heap memory heap from which allocated
@param[in] mysql_table NULL, or mysql table object when
user thread invokes dml
@param[out] error error number in case of failure
@return own: update vector of differing fields, excluding roll ptr and
trx id */
trx id,if error is not equal to DB_SUCCESS, return NULL */
upd_t*
row_upd_build_difference_binary(
dict_index_t* index,
@ -1047,7 +1048,8 @@ row_upd_build_difference_binary(
bool no_sys,
trx_t* trx,
mem_heap_t* heap,
TABLE* mysql_table)
TABLE* mysql_table,
dberr_t* error)
{
upd_field_t* upd_field;
dfield_t* dfield;
@ -1159,6 +1161,10 @@ row_upd_build_difference_binary(
update->old_vrow, col, index,
&v_heap, heap, NULL, thd, mysql_table, record,
NULL, NULL, NULL);
if (vfield == NULL) {
*error = DB_COMPUTE_VALUE_FAILED;
return(NULL);
}
if (!dfield_data_is_binary_equal(
dfield, vfield->len,