diff --git a/storage/innobase/handler/ha_innodb.cc b/storage/innobase/handler/ha_innodb.cc index fe3909efccc..a644871aed2 100644 --- a/storage/innobase/handler/ha_innodb.cc +++ b/storage/innobase/handler/ha_innodb.cc @@ -9168,8 +9168,7 @@ ha_innobase::update_row( } /* This is not a delete */ - m_prebuilt->upd_node->is_delete = FALSE; - m_prebuilt->upd_node->vers_delete = false; + m_prebuilt->upd_node->is_delete = NO_DELETE; { const bool vers_set_fields @@ -9181,8 +9180,8 @@ ha_innobase::update_row( || thd_sql_command(m_user_thd) != SQLCOM_ALTER_TABLE); - m_prebuilt->upd_node->vers_delete = vers_set_fields - && !vers_ins_row; + if (vers_set_fields && !vers_ins_row) + m_prebuilt->upd_node->is_delete = VERSIONED_DELETE; innobase_srv_conc_enter_innodb(m_prebuilt); @@ -9306,9 +9305,11 @@ ha_innobase::delete_row( /* This is a delete */ - m_prebuilt->upd_node->is_delete = TRUE; - m_prebuilt->upd_node->vers_delete = table->versioned_write() - && table->vers_end_field()->is_max(); + if (table->versioned_write() && table->vers_end_field()->is_max()) { + m_prebuilt->upd_node->is_delete = VERSIONED_DELETE; + } else { + m_prebuilt->upd_node->is_delete = PLAIN_DELETE; + } innobase_srv_conc_enter_innodb(m_prebuilt); diff --git a/storage/innobase/include/row0upd.h b/storage/innobase/include/row0upd.h index 0b149b63182..ce1f1f3c4c7 100644 --- a/storage/innobase/include/row0upd.h +++ b/storage/innobase/include/row0upd.h @@ -511,12 +511,19 @@ struct upd_t{ }; +/** Kinds of update operation */ +enum delete_mode_t { + NO_DELETE = 0, /*!< this operation does not delete */ + PLAIN_DELETE, /*!< ordinary delete */ + VERSIONED_DELETE /*!< update old and insert a new row */ +}; + /* Update node structure which also implements the delete operation of a row */ struct upd_node_t{ que_common_t common; /*!< node type: QUE_NODE_UPDATE */ - ibool is_delete;/* TRUE if delete, FALSE if update */ + delete_mode_t is_delete; /*!< kind of DELETE */ ibool searched_update; /* TRUE if searched update, FALSE if positioned */ @@ -584,8 +591,6 @@ struct upd_node_t{ compilation; speeds up execution: UPD_NODE_NO_ORD_CHANGE and UPD_NODE_NO_SIZE_CHANGE, ORed */ - /** set sys_trx_end = CUR_TRX_ID */ - bool vers_delete; /*----------------------*/ /* Local storage for this graph node */ ulint state; /*!< node execution state */ diff --git a/storage/innobase/pars/pars0pars.cc b/storage/innobase/pars/pars0pars.cc index d0696ab5cfc..11195287d8f 100644 --- a/storage/innobase/pars/pars0pars.cc +++ b/storage/innobase/pars/pars0pars.cc @@ -1085,7 +1085,7 @@ pars_update_statement_start( node = upd_node_create(pars_sym_tab_global->heap); - node->is_delete = is_delete; + node->is_delete = is_delete ? PLAIN_DELETE : NO_DELETE; node->table_sym = table_sym; node->col_assign_list = col_assign_list; @@ -1250,9 +1250,9 @@ pars_update_statement( node->select = sel_node; ut_a(!node->is_delete || (node->col_assign_list == NULL)); - ut_a(node->is_delete || (node->col_assign_list != NULL)); + ut_a(node->is_delete == PLAIN_DELETE || node->col_assign_list != NULL); - if (node->is_delete) { + if (node->is_delete == PLAIN_DELETE) { node->cmpl_info = 0; } else { pars_process_assign_list(node); diff --git a/storage/innobase/row/row0ins.cc b/storage/innobase/row/row0ins.cc index c6ac4fa2483..88f2ac8ae95 100644 --- a/storage/innobase/row/row0ins.cc +++ b/storage/innobase/row/row0ins.cc @@ -429,8 +429,7 @@ row_ins_cascade_ancestor_updates_table( upd_node = static_cast(parent); - if (upd_node->table == table && !upd_node->is_delete - && !upd_node->vers_delete) { + if (upd_node->table == table && !upd_node->is_delete) { return(TRUE); } @@ -975,8 +974,6 @@ row_ins_foreign_fill_virtual( innobase_init_vc_templ(index->table); } - bool is_delete = node->is_delete || node->vers_delete; - for (ulint i = 0; i < n_v_fld; i++) { dict_v_col_t* col = dict_table_get_nth_v_col( @@ -1008,14 +1005,14 @@ row_ins_foreign_fill_virtual( upd_field_set_v_field_no(upd_field, i, index); - if (is_delete + if (node->is_delete ? (foreign->type & DICT_FOREIGN_ON_DELETE_SET_NULL) : (foreign->type & DICT_FOREIGN_ON_UPDATE_SET_NULL)) { dfield_set_null(&upd_field->new_val); } - if (!is_delete + if (!node->is_delete && (foreign->type & DICT_FOREIGN_ON_UPDATE_CASCADE)) { dfield_t* new_vfield = innobase_get_computed_value( @@ -1108,9 +1105,7 @@ row_ins_foreign_check_on_constraint( node = static_cast(thr->run_node); - bool is_delete = node->is_delete || node->vers_delete; - - if (is_delete && 0 == (foreign->type + if (node->is_delete && 0 == (foreign->type & (DICT_FOREIGN_ON_DELETE_CASCADE | DICT_FOREIGN_ON_DELETE_SET_NULL))) { @@ -1121,7 +1116,7 @@ row_ins_foreign_check_on_constraint( DBUG_RETURN(DB_ROW_IS_REFERENCED); } - if (!is_delete && 0 == (foreign->type + if (!node->is_delete && 0 == (foreign->type & (DICT_FOREIGN_ON_UPDATE_CASCADE | DICT_FOREIGN_ON_UPDATE_SET_NULL))) { @@ -1150,11 +1145,11 @@ row_ins_foreign_check_on_constraint( cascade->foreign = foreign; - if (is_delete + if (node->is_delete && (foreign->type & DICT_FOREIGN_ON_DELETE_CASCADE)) { - cascade->is_delete = TRUE; + cascade->is_delete = PLAIN_DELETE; } else { - cascade->is_delete = FALSE; + cascade->is_delete = NO_DELETE; if (foreign->n_fields > cascade->update_n_fields) { /* We have to make the update vector longer */ @@ -1289,7 +1284,7 @@ row_ins_foreign_check_on_constraint( clust_index, tmp_heap); } - if (is_delete + if (node->is_delete ? (foreign->type & DICT_FOREIGN_ON_DELETE_SET_NULL) : (foreign->type & DICT_FOREIGN_ON_UPDATE_SET_NULL)) { @@ -1351,7 +1346,7 @@ row_ins_foreign_check_on_constraint( goto nonstandard_exit_func; } } - } else if (table->fts && cascade->is_delete) { + } else if (table->fts && cascade->is_delete == PLAIN_DELETE) { /* DICT_FOREIGN_ON_DELETE_CASCADE case */ for (i = 0; i < foreign->n_fields; i++) { if (table->fts && dict_table_is_fts_column( @@ -1369,7 +1364,7 @@ row_ins_foreign_check_on_constraint( } } - if (!is_delete + if (!node->is_delete && (foreign->type & DICT_FOREIGN_ON_UPDATE_CASCADE)) { /* Build the appropriate update vector which sets changing @@ -1709,7 +1704,7 @@ row_ins_check_foreign_constraint( if (que_node_get_type(thr->run_node) == QUE_NODE_UPDATE) { upd_node = static_cast(thr->run_node); - if (!(upd_node->is_delete) && !(upd_node->vers_delete) && upd_node->foreign == foreign) { + if (!(upd_node->is_delete) && upd_node->foreign == foreign) { /* If a cascaded update is done as defined by a foreign key constraint, do not check that constraint for the child row. In ON UPDATE CASCADE diff --git a/storage/innobase/row/row0mysql.cc b/storage/innobase/row/row0mysql.cc index f6eaf6a4a88..7076b640f17 100644 --- a/storage/innobase/row/row0mysql.cc +++ b/storage/innobase/row/row0mysql.cc @@ -1711,7 +1711,7 @@ row_create_update_node_for_mysql( node = upd_node_create(heap); node->in_mysql_interface = TRUE; - node->is_delete = FALSE; + node->is_delete = NO_DELETE; node->searched_update = FALSE; node->select = NULL; node->pcur = btr_pcur_create_for_mysql(); @@ -1806,7 +1806,7 @@ row_fts_update_or_delete( ut_a(dict_table_has_fts_index(node->table)); /* Deletes are simple; get them out of the way first. */ - if (node->is_delete) { + if (node->is_delete == PLAIN_DELETE) { /* A delete affects all FTS indexes, so we pass NULL */ fts_trx_add_op(trx, table, old_doc_id, FTS_DELETE, NULL); } else { @@ -1893,7 +1893,6 @@ row_update_for_mysql(row_prebuilt_t* prebuilt) upd_cascade_t* new_upd_nodes; upd_cascade_t* processed_cascades; bool got_s_lock = false; - const bool vers_delete = prebuilt->upd_node->vers_delete; DBUG_ENTER("row_update_for_mysql"); @@ -1936,7 +1935,7 @@ row_update_for_mysql(row_prebuilt_t* prebuilt) } node = prebuilt->upd_node; - const bool is_delete = node->is_delete; + const bool is_delete = node->is_delete == PLAIN_DELETE; ut_ad(node->table == table); if (node->cascade_heap) { @@ -2006,7 +2005,7 @@ row_update_for_mysql(row_prebuilt_t* prebuilt) bool vers_set_fields = prebuilt->versioned_write && node->table->versioned() - && (node->is_delete ? node->vers_delete + && (node->is_delete ? node->is_delete == VERSIONED_DELETE : node->update->affects_versioned()); run_again: if (vers_set_fields) { @@ -2019,11 +2018,10 @@ run_again: upd_field_t* ufield; dict_col_t* col; unsigned col_idx; - if (node->is_delete || vers_delete) { + if (node->is_delete) { ufield = &uvect->fields[0]; uvect->n_fields = 0; - node->is_delete = false; - node->vers_delete = true; + node->is_delete = VERSIONED_DELETE; col_idx = table->vers_end; } else { ut_ad(uvect->n_fields < table->n_cols); @@ -2145,8 +2143,8 @@ run_again: cascade_upd_nodes->pop_front(); thr->fk_cascade_depth++; vers_set_fields = node->table->versioned() - && (node->is_delete - || node->update->affects_versioned()); + && (node->is_delete == PLAIN_DELETE + || node->update->affects_versioned()); goto run_again; } @@ -2169,7 +2167,7 @@ run_again: node = *i; - if (node->is_delete) { + if (node->is_delete == PLAIN_DELETE) { /* Not protected by dict_table_stats_lock() for performance reasons, we would rather get garbage in stat_n_rows (which is just an estimate anyway) diff --git a/storage/innobase/row/row0upd.cc b/storage/innobase/row/row0upd.cc index 8ceb1c108c6..8e7e70bd793 100644 --- a/storage/innobase/row/row0upd.cc +++ b/storage/innobase/row/row0upd.cc @@ -272,7 +272,6 @@ row_upd_check_references_constraints( if (foreign->referenced_index == index && (node->is_delete - || node->vers_delete || row_upd_changes_first_fields_binary( entry, index, node->update, foreign->n_fields))) { @@ -413,7 +412,6 @@ wsrep_row_upd_check_foreign_constraints( if (foreign->foreign_index == index && (node->is_delete - || node->vers_delete || row_upd_changes_first_fields_binary( entry, index, node->update, foreign->n_fields))) { @@ -2229,11 +2227,13 @@ row_upd_store_row( NULL, NULL, NULL, ext, node->heap); if (node->table->n_v_cols) { - row_upd_store_v_row(node, node->is_delete ? NULL : node->update, - thd, mysql_table); + row_upd_store_v_row( + node, + node->is_delete == PLAIN_DELETE ? NULL : node->update, + thd, mysql_table); } - if (node->is_delete) { + if (node->is_delete == PLAIN_DELETE) { node->upd_row = NULL; node->upd_ext = NULL; } else { @@ -2508,7 +2508,7 @@ row_upd_sec_index_entry( btr_pcur_close(&pcur); mtr_commit(&mtr); - if (node->is_delete || err != DB_SUCCESS) { + if (node->is_delete == PLAIN_DELETE || err != DB_SUCCESS) { goto func_exit; } @@ -2961,7 +2961,7 @@ row_upd_del_mark_clust_rec( ut_ad(node); ut_ad(dict_index_is_clust(index)); - ut_ad(node->is_delete); + ut_ad(node->is_delete == PLAIN_DELETE); pcur = node->pcur; btr_cur = btr_pcur_get_btr_cur(pcur); @@ -3113,7 +3113,8 @@ row_upd_clust_step( then we have to free the file segments of the index tree associated with the index */ - if (node->is_delete && node->table->id == DICT_INDEXES_ID) { + if (node->is_delete == PLAIN_DELETE + && node->table->id == DICT_INDEXES_ID) { ut_ad(!dict_index_is_online_ddl(index)); @@ -3157,7 +3158,7 @@ row_upd_clust_step( /* NOTE: the following function calls will also commit mtr */ - if (node->is_delete) { + if (node->is_delete == PLAIN_DELETE) { err = row_upd_del_mark_clust_rec( node, index, offsets, thr, referenced, foreign, &mtr); @@ -3262,7 +3263,7 @@ row_upd( /* We do not get the cmpl_info value from the MySQL interpreter: we must calculate it on the fly: */ - if (node->is_delete + if (node->is_delete == PLAIN_DELETE || row_upd_changes_some_index_ord_field_binary( node->table, node->update)) { node->cmpl_info = 0;