1
/*****************************************************************************
3
Copyright (c) 1997, 2009, Innobase Oy. All Rights Reserved.
5
This program is free software; you can redistribute it and/or modify it under
6
the terms of the GNU General Public License as published by the Free Software
7
Foundation; version 2 of the License.
9
This program is distributed in the hope that it will be useful, but WITHOUT
10
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
11
FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
13
You should have received a copy of the GNU General Public License along with
14
this program; if not, write to the Free Software Foundation, Inc., 59 Temple
15
Place, Suite 330, Boston, MA 02111-1307 USA
17
*****************************************************************************/
1
19
/******************************************************
6
22
Created 2/6/1997 Heikki Tuuri
7
23
*******************************************************/
157
175
heap, &prev_version);
158
176
mem_heap_free(heap2); /* free version and clust_offsets */
163
clust_offsets = rec_get_offsets(
164
prev_version, clust_index, NULL,
165
ULINT_UNDEFINED, &heap);
167
vers_del = rec_get_deleted_flag(prev_version,
169
prev_trx_id = row_get_rec_trx_id(prev_version,
173
/* If the trx_id and prev_trx_id are
174
different and if the prev_version is marked
175
deleted then the prev_trx_id must have
176
already committed for the trx_id to be able to
177
modify the row. Therefore, prev_trx_id cannot
178
hold any implicit lock. */
179
if (0 != ut_dulint_cmp(trx_id, prev_trx_id)
182
mutex_enter(&kernel_mutex);
178
if (prev_version == NULL) {
179
mutex_enter(&kernel_mutex);
181
if (!trx_is_active(trx_id)) {
182
/* Transaction no longer active: no
186
/* The stack of versions is locked by mtr.
187
Thus, it is safe to fetch the prefixes for
188
externally stored columns. */
189
row = row_build(ROW_COPY_POINTERS, clust_index,
190
prev_version, clust_offsets,
192
entry = row_build_index_entry(row, ext, index, heap);
193
/* entry may be NULL if a record was inserted
194
in place of a deleted record, and the BLOB
195
pointers of the new record were not
196
initialized yet. But in that case,
197
prev_version should be NULL. */
188
/* If the transaction is still active,
189
clust_rec must be a fresh insert, because no
190
previous version was found. */
191
ut_ad(err == DB_SUCCESS);
193
/* It was a freshly inserted version: there is an
194
implicit x-lock on rec */
196
trx = trx_get_on_id(trx_id);
201
clust_offsets = rec_get_offsets(prev_version, clust_index,
202
NULL, ULINT_UNDEFINED, &heap);
204
vers_del = rec_get_deleted_flag(prev_version, comp);
205
prev_trx_id = row_get_rec_trx_id(prev_version, clust_index,
208
/* If the trx_id and prev_trx_id are different and if
209
the prev_version is marked deleted then the
210
prev_trx_id must have already committed for the trx_id
211
to be able to modify the row. Therefore, prev_trx_id
212
cannot hold any implicit lock. */
213
if (vers_del && 0 != ut_dulint_cmp(trx_id, prev_trx_id)) {
215
mutex_enter(&kernel_mutex);
219
/* The stack of versions is locked by mtr. Thus, it
220
is safe to fetch the prefixes for externally stored
222
row = row_build(ROW_COPY_POINTERS, clust_index, prev_version,
223
clust_offsets, NULL, &ext, heap);
224
entry = row_build_index_entry(row, ext, index, heap);
225
/* entry may be NULL if a record was inserted in place
226
of a deleted record, and the BLOB pointers of the new
227
record were not initialized yet. But in that case,
228
prev_version should be NULL. */
201
231
mutex_enter(&kernel_mutex);
209
/* If the transaction is still active, the previous version
210
of clust_rec must be accessible if not a fresh insert; we
211
may assert the following: */
213
ut_ad(err == DB_SUCCESS);
215
if (prev_version == NULL) {
216
/* It was a freshly inserted version: there is an
217
implicit x-lock on rec */
219
trx = trx_get_on_id(trx_id);
224
239
/* If we get here, we know that the trx_id transaction is
225
240
still active and it has modified prev_version. Let us check
226
241
if prev_version would require rec to be in a different
244
/* The previous version of clust_rec must be
245
accessible, because the transaction is still active
246
and clust_rec was not a fresh insert. */
247
ut_ad(err == DB_SUCCESS);
229
249
/* We check if entry and rec are identified in the alphabetical
231
251
if (0 == cmp_dtuple_rec(entry, rec, offsets)) {