Commit aa8a31da authored by Aditya A's avatar Aditya A Committed by Marko Mäkelä

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
parent e32305e5
/***************************************************************************** /*****************************************************************************
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. Copyright (c) 2018, MariaDB Corporation.
This program is free software; you can redistribute it and/or modify it under 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! ...@@ -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] heap memory heap from which allocated
@param[in,out] mysql_table NULL, or mysql table object when @param[in,out] mysql_table NULL, or mysql table object when
user thread invokes dml user thread invokes dml
@param[out] error error number in case of failure
@return own: update vector of differing fields, excluding roll ptr and @return own: update vector of differing fields, excluding roll ptr and
trx id */ trx id */
upd_t* upd_t*
...@@ -230,8 +231,9 @@ row_upd_build_difference_binary( ...@@ -230,8 +231,9 @@ row_upd_build_difference_binary(
bool no_sys, bool no_sys,
trx_t* trx, trx_t* trx,
mem_heap_t* heap, mem_heap_t* heap,
TABLE* mysql_table) TABLE* mysql_table,
MY_ATTRIBUTE((nonnull(1,2,3,7), warn_unused_result)); 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 Replaces the new column values stored in the update vector to the index entry
given. */ given. */
......
...@@ -326,7 +326,7 @@ row_ins_clust_index_entry_by_modify( ...@@ -326,7 +326,7 @@ row_ins_clust_index_entry_by_modify(
{ {
const rec_t* rec; const rec_t* rec;
upd_t* update; upd_t* update;
dberr_t err; dberr_t err = DB_SUCCESS;
btr_cur_t* cursor = btr_pcur_get_btr_cur(pcur); btr_cur_t* cursor = btr_pcur_get_btr_cur(pcur);
TABLE* mysql_table = NULL; TABLE* mysql_table = NULL;
ut_ad(dict_index_is_clust(cursor->index)); ut_ad(dict_index_is_clust(cursor->index));
...@@ -349,7 +349,11 @@ row_ins_clust_index_entry_by_modify( ...@@ -349,7 +349,11 @@ row_ins_clust_index_entry_by_modify(
update = row_upd_build_difference_binary( update = row_upd_build_difference_binary(
cursor->index, entry, rec, NULL, true, 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) { if (mode != BTR_MODIFY_TREE) {
ut_ad((mode & ~BTR_ALREADY_S_LATCHED) == BTR_MODIFY_LEAF); ut_ad((mode & ~BTR_ALREADY_S_LATCHED) == BTR_MODIFY_LEAF);
......
...@@ -2042,7 +2042,10 @@ row_log_table_apply_update( ...@@ -2042,7 +2042,10 @@ row_log_table_apply_update(
row, NULL, index, heap, ROW_BUILD_NORMAL); row, NULL, index, heap, ROW_BUILD_NORMAL);
upd_t* update = row_upd_build_difference_binary( upd_t* update = row_upd_build_difference_binary(
index, entry, btr_pcur_get_rec(&pcur), cur_offsets, 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) { if (!update->n_fields) {
/* Nothing to do. */ /* Nothing to do. */
......
...@@ -1036,8 +1036,9 @@ the equal ordering fields. NOTE: we compare the fields as binary strings! ...@@ -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] heap memory heap from which allocated
@param[in] mysql_table NULL, or mysql table object when @param[in] mysql_table NULL, or mysql table object when
user thread invokes dml user thread invokes dml
@param[out] error error number in case of failure
@return own: update vector of differing fields, excluding roll ptr and @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* upd_t*
row_upd_build_difference_binary( row_upd_build_difference_binary(
dict_index_t* index, dict_index_t* index,
...@@ -1047,7 +1048,8 @@ row_upd_build_difference_binary( ...@@ -1047,7 +1048,8 @@ row_upd_build_difference_binary(
bool no_sys, bool no_sys,
trx_t* trx, trx_t* trx,
mem_heap_t* heap, mem_heap_t* heap,
TABLE* mysql_table) TABLE* mysql_table,
dberr_t* error)
{ {
upd_field_t* upd_field; upd_field_t* upd_field;
dfield_t* dfield; dfield_t* dfield;
...@@ -1159,6 +1161,10 @@ row_upd_build_difference_binary( ...@@ -1159,6 +1161,10 @@ row_upd_build_difference_binary(
update->old_vrow, col, index, update->old_vrow, col, index,
&v_heap, heap, NULL, thd, mysql_table, record, &v_heap, heap, NULL, thd, mysql_table, record,
NULL, NULL, NULL); NULL, NULL, NULL);
if (vfield == NULL) {
*error = DB_COMPUTE_VALUE_FAILED;
return(NULL);
}
if (!dfield_data_is_binary_equal( if (!dfield_data_is_binary_equal(
dfield, vfield->len, dfield, vfield->len,
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment