1/***************************************************************************** 2 3Copyright (c) 1996, 2012, Oracle and/or its affiliates. All Rights Reserved. 4 5This program is free software; you can redistribute it and/or modify 6it under the terms of the GNU General Public License, version 2.0, 7as published by the Free Software Foundation. 8 9This program is also distributed with certain software (including 10but not limited to OpenSSL) that is licensed under separate terms, 11as designated in a particular file or component or in included license 12documentation. The authors of MySQL hereby grant you an additional 13permission to link the program and your derivative works with the 14separately licensed software that they have included with MySQL. 15 16This program is distributed in the hope that it will be useful, 17but WITHOUT ANY WARRANTY; without even the implied warranty of 18MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 19GNU General Public License, version 2.0, for more details. 20 21You should have received a copy of the GNU General Public License along with 22this program; if not, write to the Free Software Foundation, Inc., 2351 Franklin Street, Suite 500, Boston, MA 02110-1335 USA 24 25*****************************************************************************/ 26 27/**************************************************//** 28@file include/row0upd.ic 29Update of a row 30 31Created 12/27/1996 Heikki Tuuri 32*******************************************************/ 33 34#include "mtr0log.h" 35#ifndef UNIV_HOTBACKUP 36# include "trx0trx.h" 37# include "trx0undo.h" 38# include "row0row.h" 39# include "lock0lock.h" 40#endif /* !UNIV_HOTBACKUP */ 41#include "page0zip.h" 42 43/*********************************************************************//** 44Creates an update vector object. 45@return own: update vector object */ 46UNIV_INLINE 47upd_t* 48upd_create( 49/*=======*/ 50 ulint n, /*!< in: number of fields */ 51 mem_heap_t* heap) /*!< in: heap from which memory allocated */ 52{ 53 upd_t* update; 54 55 update = (upd_t*) mem_heap_zalloc(heap, sizeof(upd_t)); 56 57 update->n_fields = n; 58 update->fields = (upd_field_t*) 59 mem_heap_zalloc(heap, sizeof(upd_field_t) * n); 60 61 return(update); 62} 63 64/*********************************************************************//** 65Returns the number of fields in the update vector == number of columns 66to be updated by an update vector. 67@return number of fields */ 68UNIV_INLINE 69ulint 70upd_get_n_fields( 71/*=============*/ 72 const upd_t* update) /*!< in: update vector */ 73{ 74 ut_ad(update); 75 76 return(update->n_fields); 77} 78 79#ifdef UNIV_DEBUG 80/*********************************************************************//** 81Returns the nth field of an update vector. 82@return update vector field */ 83UNIV_INLINE 84upd_field_t* 85upd_get_nth_field( 86/*==============*/ 87 const upd_t* update, /*!< in: update vector */ 88 ulint n) /*!< in: field position in update vector */ 89{ 90 ut_ad(update); 91 ut_ad(n < update->n_fields); 92 93 return((upd_field_t*) update->fields + n); 94} 95#endif /* UNIV_DEBUG */ 96 97#ifndef UNIV_HOTBACKUP 98/*********************************************************************//** 99Sets an index field number to be updated by an update vector field. */ 100UNIV_INLINE 101void 102upd_field_set_field_no( 103/*===================*/ 104 upd_field_t* upd_field, /*!< in: update vector field */ 105 ulint field_no, /*!< in: field number in a clustered 106 index */ 107 dict_index_t* index, /*!< in: index */ 108 trx_t* trx) /*!< in: transaction */ 109{ 110 upd_field->field_no = field_no; 111 upd_field->orig_len = 0; 112 113 if (field_no >= dict_index_get_n_fields(index)) { 114 fprintf(stderr, 115 "InnoDB: Error: trying to access field %lu in ", 116 (ulong) field_no); 117 dict_index_name_print(stderr, trx, index); 118 fprintf(stderr, "\n" 119 "InnoDB: but index only has %lu fields\n", 120 (ulong) dict_index_get_n_fields(index)); 121 ut_ad(0); 122 } 123 124 dict_col_copy_type(dict_index_get_nth_col(index, field_no), 125 dfield_get_type(&upd_field->new_val)); 126} 127 128/*********************************************************************//** 129Returns a field of an update vector by field_no. 130@return update vector field, or NULL */ 131UNIV_INLINE 132const upd_field_t* 133upd_get_field_by_field_no( 134/*======================*/ 135 const upd_t* update, /*!< in: update vector */ 136 ulint no) /*!< in: field_no */ 137{ 138 ulint i; 139 for (i = 0; i < upd_get_n_fields(update); i++) { 140 const upd_field_t* uf = upd_get_nth_field(update, i); 141 142 if (uf->field_no == no) { 143 144 return(uf); 145 } 146 } 147 148 return(NULL); 149} 150 151/*********************************************************************//** 152Updates the trx id and roll ptr field in a clustered index record when 153a row is updated or marked deleted. */ 154UNIV_INLINE 155void 156row_upd_rec_sys_fields( 157/*===================*/ 158 rec_t* rec, /*!< in/out: record */ 159 page_zip_des_t* page_zip,/*!< in/out: compressed page whose 160 uncompressed part will be updated, or NULL */ 161 dict_index_t* index, /*!< in: clustered index */ 162 const ulint* offsets,/*!< in: rec_get_offsets(rec, index) */ 163 const trx_t* trx, /*!< in: transaction */ 164 roll_ptr_t roll_ptr)/*!< in: roll ptr of the undo log record, 165 can be 0 during IMPORT */ 166{ 167 ut_ad(dict_index_is_clust(index)); 168 ut_ad(rec_offs_validate(rec, index, offsets)); 169 170 if (page_zip) { 171 ulint pos = dict_index_get_sys_col_pos(index, DATA_TRX_ID); 172 page_zip_write_trx_id_and_roll_ptr(page_zip, rec, offsets, 173 pos, trx->id, roll_ptr); 174 } else { 175 ulint offset = index->trx_id_offset; 176 177 if (!offset) { 178 offset = row_get_trx_id_offset(index, offsets); 179 } 180 181#if DATA_TRX_ID + 1 != DATA_ROLL_PTR 182# error "DATA_TRX_ID + 1 != DATA_ROLL_PTR" 183#endif 184 /* During IMPORT the trx id in the record can be in the 185 future, if the .ibd file is being imported from another 186 instance. During IMPORT roll_ptr will be 0. */ 187 ut_ad(roll_ptr == 0 188 || lock_check_trx_id_sanity( 189 trx_read_trx_id(rec + offset), 190 rec, index, offsets)); 191 192 trx_write_trx_id(rec + offset, trx->id); 193 trx_write_roll_ptr(rec + offset + DATA_TRX_ID_LEN, roll_ptr); 194 } 195} 196#endif /* !UNIV_HOTBACKUP */ 197