1/***************************************************************************** 2 3Copyright (c) 1996, 2011, 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/row0row.ic 29General row routines 30 31Created 4/20/1996 Heikki Tuuri 32*******************************************************/ 33 34#include "dict0dict.h" 35#include "rem0rec.h" 36#include "trx0undo.h" 37 38/*********************************************************************//** 39Gets the offset of the DB_TRX_ID field, in bytes relative to the origin of 40a clustered index record. 41@return offset of DATA_TRX_ID */ 42UNIV_INLINE 43ulint 44row_get_trx_id_offset( 45/*==================*/ 46 const dict_index_t* index, /*!< in: clustered index */ 47 const ulint* offsets)/*!< in: record offsets */ 48{ 49 ulint pos; 50 ulint offset; 51 ulint len; 52 53 ut_ad(dict_index_is_clust(index)); 54 ut_ad(rec_offs_validate(NULL, index, offsets)); 55 56 pos = dict_index_get_sys_col_pos(index, DATA_TRX_ID); 57 58 offset = rec_get_nth_field_offs(offsets, pos, &len); 59 60 ut_ad(len == DATA_TRX_ID_LEN); 61 62 return(offset); 63} 64 65/*********************************************************************//** 66Reads the trx id field from a clustered index record. 67@return value of the field */ 68UNIV_INLINE 69trx_id_t 70row_get_rec_trx_id( 71/*===============*/ 72 const rec_t* rec, /*!< in: record */ 73 const dict_index_t* index, /*!< in: clustered index */ 74 const ulint* offsets)/*!< in: rec_get_offsets(rec, index) */ 75{ 76 ulint offset; 77 78 ut_ad(dict_index_is_clust(index)); 79 ut_ad(rec_offs_validate(rec, index, offsets)); 80 81 offset = index->trx_id_offset; 82 83 if (!offset) { 84 offset = row_get_trx_id_offset(index, offsets); 85 } 86 87 return(trx_read_trx_id(rec + offset)); 88} 89 90/*********************************************************************//** 91Reads the roll pointer field from a clustered index record. 92@return value of the field */ 93UNIV_INLINE 94roll_ptr_t 95row_get_rec_roll_ptr( 96/*=================*/ 97 const rec_t* rec, /*!< in: record */ 98 const dict_index_t* index, /*!< in: clustered index */ 99 const ulint* offsets)/*!< in: rec_get_offsets(rec, index) */ 100{ 101 ulint offset; 102 103 ut_ad(dict_index_is_clust(index)); 104 ut_ad(rec_offs_validate(rec, index, offsets)); 105 106 offset = index->trx_id_offset; 107 108 if (!offset) { 109 offset = row_get_trx_id_offset(index, offsets); 110 } 111 112 return(trx_read_roll_ptr(rec + offset + DATA_TRX_ID_LEN)); 113} 114 115/*****************************************************************//** 116When an insert or purge to a table is performed, this function builds 117the entry to be inserted into or purged from an index on the table. 118@return index entry which should be inserted or purged, or NULL if the 119externally stored columns in the clustered index record are 120unavailable and ext != NULL */ 121UNIV_INLINE 122dtuple_t* 123row_build_index_entry( 124/*==================*/ 125 const dtuple_t* row, /*!< in: row which should be 126 inserted or purged */ 127 const row_ext_t* ext, /*!< in: externally stored column 128 prefixes, or NULL */ 129 dict_index_t* index, /*!< in: index on the table */ 130 mem_heap_t* heap) /*!< in: memory heap from which 131 the memory for the index entry 132 is allocated */ 133{ 134 dtuple_t* entry; 135 136 ut_ad(dtuple_check_typed(row)); 137 entry = row_build_index_entry_low(row, ext, index, heap); 138 ut_ad(!entry || dtuple_check_typed(entry)); 139 return(entry); 140} 141 142/*******************************************************************//** 143Builds from a secondary index record a row reference with which we can 144search the clustered index record. */ 145UNIV_INLINE 146void 147row_build_row_ref_fast( 148/*===================*/ 149 dtuple_t* ref, /*!< in/out: typed data tuple where the 150 reference is built */ 151 const ulint* map, /*!< in: array of field numbers in rec 152 telling how ref should be built from 153 the fields of rec */ 154 const rec_t* rec, /*!< in: record in the index; must be 155 preserved while ref is used, as we do 156 not copy field values to heap */ 157 const ulint* offsets)/*!< in: array returned by rec_get_offsets() */ 158{ 159 dfield_t* dfield; 160 const byte* field; 161 ulint len; 162 ulint ref_len; 163 ulint field_no; 164 ulint i; 165 166 ut_ad(rec_offs_validate(rec, NULL, offsets)); 167 ut_ad(!rec_offs_any_extern(offsets)); 168 ref_len = dtuple_get_n_fields(ref); 169 170 for (i = 0; i < ref_len; i++) { 171 dfield = dtuple_get_nth_field(ref, i); 172 173 field_no = *(map + i); 174 175 if (field_no != ULINT_UNDEFINED) { 176 177 field = rec_get_nth_field(rec, offsets, 178 field_no, &len); 179 dfield_set_data(dfield, field, len); 180 } 181 } 182} 183