1
/*****************************************************************************
3
Copyright (C) 1996, 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., 51 Franklin
15
St, Fifth Floor, Boston, MA 02110-1301 USA
17
*****************************************************************************/
19
/**************************************************//**
20
@file include/row0upd.h
23
Created 12/27/1996 Heikki Tuuri
24
*******************************************************/
30
#include "data0data.h"
31
#include "row0types.h"
32
#include "btr0types.h"
33
#include "dict0types.h"
34
#include "trx0types.h"
36
#ifndef UNIV_HOTBACKUP
37
# include "btr0pcur.h"
38
# include "que0types.h"
39
# include "pars0types.h"
40
#endif /* !UNIV_HOTBACKUP */
42
/*********************************************************************//**
43
Creates an update vector object.
44
@return own: update vector object */
49
ulint n, /*!< in: number of fields */
50
mem_heap_t* heap); /*!< in: heap from which memory allocated */
51
/*********************************************************************//**
52
Returns the number of fields in the update vector == number of columns
53
to be updated by an update vector.
54
@return number of fields */
59
const upd_t* update); /*!< in: update vector */
61
/*********************************************************************//**
62
Returns the nth field of an update vector.
63
@return update vector field */
68
const upd_t* update, /*!< in: update vector */
69
ulint n); /*!< in: field position in update vector */
71
# define upd_get_nth_field(update, n) ((update)->fields + (n))
73
#ifndef UNIV_HOTBACKUP
74
/*********************************************************************//**
75
Sets an index field number to be updated by an update vector field. */
78
upd_field_set_field_no(
79
/*===================*/
80
upd_field_t* upd_field, /*!< in: update vector field */
81
ulint field_no, /*!< in: field number in a clustered
83
dict_index_t* index, /*!< in: index */
84
trx_t* trx); /*!< in: transaction */
85
/*********************************************************************//**
86
Returns a field of an update vector by field_no.
87
@return update vector field, or NULL */
90
upd_get_field_by_field_no(
91
/*======================*/
92
const upd_t* update, /*!< in: update vector */
93
ulint no) /*!< in: field_no */
94
__attribute__((nonnull, pure));
95
/*********************************************************************//**
96
Writes into the redo log the values of trx id and roll ptr and enough info
97
to determine their positions within a clustered index record.
98
@return new pointer to mlog */
101
row_upd_write_sys_vals_to_log(
102
/*==========================*/
103
dict_index_t* index, /*!< in: clustered index */
104
trx_t* trx, /*!< in: transaction */
105
roll_ptr_t roll_ptr,/*!< in: roll ptr of the undo log record */
106
byte* log_ptr,/*!< pointer to a buffer of size > 20 opened
108
mtr_t* mtr); /*!< in: mtr */
109
/*********************************************************************//**
110
Updates the trx id and roll ptr field in a clustered index record when
111
a row is updated or marked deleted. */
114
row_upd_rec_sys_fields(
115
/*===================*/
116
rec_t* rec, /*!< in/out: record */
117
page_zip_des_t* page_zip,/*!< in/out: compressed page whose
118
uncompressed part will be updated, or NULL */
119
dict_index_t* index, /*!< in: clustered index */
120
const ulint* offsets,/*!< in: rec_get_offsets(rec, index) */
121
trx_t* trx, /*!< in: transaction */
122
roll_ptr_t roll_ptr);/*!< in: roll ptr of the undo log record */
123
/*********************************************************************//**
124
Sets the trx id or roll ptr field of a clustered index entry. */
127
row_upd_index_entry_sys_field(
128
/*==========================*/
129
dtuple_t* entry, /*!< in/out: index entry, where the memory
130
buffers for sys fields are already allocated:
131
the function just copies the new values to
133
dict_index_t* index, /*!< in: clustered index */
134
ulint type, /*!< in: DATA_TRX_ID or DATA_ROLL_PTR */
135
ib_uint64_t val); /*!< in: value to write */
136
/*********************************************************************//**
137
Creates an update node for a query graph.
138
@return own: update node */
143
mem_heap_t* heap); /*!< in: mem heap where created */
144
/***********************************************************//**
145
Writes to the redo log the new values of the fields occurring in the index. */
148
row_upd_index_write_log(
149
/*====================*/
150
const upd_t* update, /*!< in: update vector */
151
byte* log_ptr,/*!< in: pointer to mlog buffer: must
152
contain at least MLOG_BUF_MARGIN bytes
153
of free space; the buffer is closed
154
within this function */
155
mtr_t* mtr); /*!< in: mtr into whose log to write */
156
/***********************************************************//**
157
Returns TRUE if row update changes size of some field in index or if some
158
field to be updated is stored externally in rec or update.
159
@return TRUE if the update changes the size of some field in index or
160
the field is external in rec or update */
163
row_upd_changes_field_size_or_external(
164
/*===================================*/
165
dict_index_t* index, /*!< in: index */
166
const ulint* offsets,/*!< in: rec_get_offsets(rec, index) */
167
const upd_t* update);/*!< in: update vector */
168
#endif /* !UNIV_HOTBACKUP */
169
/***********************************************************//**
170
Replaces the new column values stored in the update vector to the
171
record given. No field size changes are allowed. This function is
172
usually invoked on a clustered index. The only use case for a
173
secondary index is row_ins_sec_index_entry_by_modify() or its
174
counterpart in ibuf_insert_to_index_page(). */
177
row_upd_rec_in_place(
178
/*=================*/
179
rec_t* rec, /*!< in/out: record where replaced */
180
dict_index_t* index, /*!< in: the index the record belongs to */
181
const ulint* offsets,/*!< in: array returned by rec_get_offsets() */
182
const upd_t* update, /*!< in: update vector */
183
page_zip_des_t* page_zip);/*!< in: compressed page with enough space
184
available, or NULL */
185
#ifndef UNIV_HOTBACKUP
186
/***************************************************************//**
187
Builds an update vector from those fields which in a secondary index entry
188
differ from a record that has the equal ordering fields. NOTE: we compare
189
the fields as binary strings!
190
@return own: update vector of differing fields */
193
row_upd_build_sec_rec_difference_binary(
194
/*====================================*/
195
dict_index_t* index, /*!< in: index */
196
const dtuple_t* entry, /*!< in: entry to insert */
197
const rec_t* rec, /*!< in: secondary index record */
198
trx_t* trx, /*!< in: transaction */
199
mem_heap_t* heap); /*!< in: memory heap from which allocated */
200
/***************************************************************//**
201
Builds an update vector from those fields, excluding the roll ptr and
202
trx id fields, which in an index entry differ from a record that has
203
the equal ordering fields. NOTE: we compare the fields as binary strings!
204
@return own: update vector of differing fields, excluding roll ptr and
208
row_upd_build_difference_binary(
209
/*============================*/
210
dict_index_t* index, /*!< in: clustered index */
211
const dtuple_t* entry, /*!< in: entry to insert */
212
const rec_t* rec, /*!< in: clustered index record */
213
trx_t* trx, /*!< in: transaction */
214
mem_heap_t* heap); /*!< in: memory heap from which allocated */
215
/***********************************************************//**
216
Replaces the new column values stored in the update vector to the index entry
220
row_upd_index_replace_new_col_vals_index_pos(
221
/*=========================================*/
222
dtuple_t* entry, /*!< in/out: index entry where replaced;
223
the clustered index record must be
224
covered by a lock or a page latch to
225
prevent deletion (rollback or purge) */
226
dict_index_t* index, /*!< in: index; NOTE that this may also be a
227
non-clustered index */
228
const upd_t* update, /*!< in: an update vector built for the index so
229
that the field number in an upd_field is the
232
/*!< in: if TRUE, limit the replacement to
233
ordering fields of index; note that this
234
does not work for non-clustered indexes. */
235
mem_heap_t* heap) /*!< in: memory heap for allocating and
236
copying the new values */
237
__attribute__((nonnull));
238
/***********************************************************//**
239
Replaces the new column values stored in the update vector to the index entry
243
row_upd_index_replace_new_col_vals(
244
/*===============================*/
245
dtuple_t* entry, /*!< in/out: index entry where replaced;
246
the clustered index record must be
247
covered by a lock or a page latch to
248
prevent deletion (rollback or purge) */
249
dict_index_t* index, /*!< in: index; NOTE that this may also be a
250
non-clustered index */
251
const upd_t* update, /*!< in: an update vector built for the
252
CLUSTERED index so that the field number in
253
an upd_field is the clustered index position */
254
mem_heap_t* heap) /*!< in: memory heap for allocating and
255
copying the new values */
256
__attribute__((nonnull));
257
/***********************************************************//**
258
Replaces the new column values stored in the update vector. */
263
dtuple_t* row, /*!< in/out: row where replaced,
265
the clustered index record must be
266
covered by a lock or a page latch to
267
prevent deletion (rollback or purge) */
268
row_ext_t** ext, /*!< out, own: NULL, or externally
269
stored column prefixes */
270
const dict_index_t* index, /*!< in: clustered index */
271
const upd_t* update, /*!< in: an update vector built for the
273
mem_heap_t* heap); /*!< in: memory heap */
274
/***********************************************************//**
275
Checks if an update vector changes an ordering field of an index record.
277
This function is fast if the update vector is short or the number of ordering
278
fields in the index is small. Otherwise, this can be quadratic.
279
NOTE: we compare the fields as binary strings!
280
@return TRUE if update vector changes an ordering field in the index record */
283
row_upd_changes_ord_field_binary(
284
/*=============================*/
285
const dtuple_t* row, /*!< in: old value of row, or NULL if the
286
row and the data values in update are not
287
known when this function is called, e.g., at
289
dict_index_t* index, /*!< in: index of the record */
290
const upd_t* update);/*!< in: update vector for the row; NOTE: the
291
field numbers in this MUST be clustered index
293
/***********************************************************//**
294
Checks if an update vector changes an ordering field of an index record.
295
This function is fast if the update vector is short or the number of ordering
296
fields in the index is small. Otherwise, this can be quadratic.
297
NOTE: we compare the fields as binary strings!
298
@return TRUE if update vector may change an ordering field in an index
302
row_upd_changes_some_index_ord_field_binary(
303
/*========================================*/
304
const dict_table_t* table, /*!< in: table */
305
const upd_t* update);/*!< in: update vector for the row */
306
/***********************************************************//**
307
Updates a row in a table. This is a high-level function used
308
in SQL execution graphs.
309
@return query thread to run next or NULL */
314
que_thr_t* thr); /*!< in: query thread */
315
#endif /* !UNIV_HOTBACKUP */
316
/*********************************************************************//**
317
Parses the log data of system field values.
318
@return log data end or NULL */
321
row_upd_parse_sys_vals(
322
/*===================*/
323
byte* ptr, /*!< in: buffer */
324
byte* end_ptr,/*!< in: buffer end */
325
ulint* pos, /*!< out: TRX_ID position in record */
326
trx_id_t* trx_id, /*!< out: trx id */
327
roll_ptr_t* roll_ptr);/*!< out: roll ptr */
328
/*********************************************************************//**
329
Updates the trx id and roll ptr field in a clustered index record in database
333
row_upd_rec_sys_fields_in_recovery(
334
/*===============================*/
335
rec_t* rec, /*!< in/out: record */
336
page_zip_des_t* page_zip,/*!< in/out: compressed page, or NULL */
337
const ulint* offsets,/*!< in: array returned by rec_get_offsets() */
338
ulint pos, /*!< in: TRX_ID position in rec */
339
trx_id_t trx_id, /*!< in: transaction id */
340
roll_ptr_t roll_ptr);/*!< in: roll ptr of the undo log record */
341
/*********************************************************************//**
342
Parses the log data written by row_upd_index_write_log.
343
@return log data end or NULL */
348
byte* ptr, /*!< in: buffer */
349
byte* end_ptr,/*!< in: buffer end */
350
mem_heap_t* heap, /*!< in: memory heap where update vector is
352
upd_t** update_out);/*!< out: update vector */
355
/* Update vector field */
356
struct upd_field_struct{
357
unsigned field_no:16; /*!< field number in an index, usually
358
the clustered index, but in updating
359
a secondary index record in btr0cur.c
360
this is the position in the secondary
362
#ifndef UNIV_HOTBACKUP
363
unsigned orig_len:16; /*!< original length of the locally
364
stored part of an externally stored
366
que_node_t* exp; /*!< expression for calculating a new
367
value: it refers to column values and
368
constants in the symbol table of the
370
#endif /* !UNIV_HOTBACKUP */
371
dfield_t new_val; /*!< new value for the column */
374
/* Update vector structure */
376
ulint info_bits; /*!< new value of info bits to record;
378
ulint n_fields; /*!< number of update fields */
379
upd_field_t* fields; /*!< array of update fields */
382
#ifndef UNIV_HOTBACKUP
383
/* Update node structure which also implements the delete operation
386
struct upd_node_struct{
387
que_common_t common; /*!< node type: QUE_NODE_UPDATE */
388
ibool is_delete;/* TRUE if delete, FALSE if update */
389
ibool searched_update;
390
/* TRUE if searched update, FALSE if
392
ibool in_mysql_interface;
393
/* TRUE if the update node was created
394
for the MySQL interface */
395
dict_foreign_t* foreign;/* NULL or pointer to a foreign key
396
constraint if this update node is used in
397
doing an ON DELETE or ON UPDATE operation */
398
upd_node_t* cascade_node;/* NULL or an update node template which
399
is used to implement ON DELETE/UPDATE CASCADE
400
or ... SET NULL for foreign keys */
401
mem_heap_t* cascade_heap;/* NULL or a mem heap where the cascade
403
sel_node_t* select; /*!< query graph subtree implementing a base
404
table cursor: the rows returned will be
406
btr_pcur_t* pcur; /*!< persistent cursor placed on the clustered
407
index record which should be updated or
408
deleted; the cursor is stored in the graph
409
of 'select' field above, except in the case
410
of the MySQL interface */
411
dict_table_t* table; /*!< table where updated */
412
upd_t* update; /*!< update vector for the row */
413
ulint update_n_fields;
414
/* when this struct is used to implement
415
a cascade operation for foreign keys, we store
416
here the size of the buffer allocated for use
417
as the update vector */
418
sym_node_list_t columns;/* symbol table nodes for the columns
419
to retrieve from the table */
420
ibool has_clust_rec_x_lock;
421
/* TRUE if the select which retrieves the
422
records to update already sets an x-lock on
423
the clustered record; note that it must always
424
set at least an s-lock */
425
ulint cmpl_info;/* information extracted during query
426
compilation; speeds up execution:
427
UPD_NODE_NO_ORD_CHANGE and
428
UPD_NODE_NO_SIZE_CHANGE, ORed */
429
/*----------------------*/
430
/* Local storage for this graph node */
431
ulint state; /*!< node execution state */
432
dict_index_t* index; /*!< NULL, or the next index whose record should
434
dtuple_t* row; /*!< NULL, or a copy (also fields copied to
435
heap) of the row to update; this must be reset
436
to NULL after a successful update */
437
row_ext_t* ext; /*!< NULL, or prefixes of the externally
438
stored columns in the old row */
439
dtuple_t* upd_row;/* NULL, or a copy of the updated row */
440
row_ext_t* upd_ext;/* NULL, or prefixes of the externally
441
stored columns in upd_row */
442
mem_heap_t* heap; /*!< memory heap used as auxiliary storage;
443
this must be emptied after a successful
445
/*----------------------*/
446
sym_node_t* table_sym;/* table node in symbol table */
447
que_node_t* col_assign_list;
448
/* column assignment list */
452
#define UPD_NODE_MAGIC_N 1579975
454
/* Node execution states */
455
#define UPD_NODE_SET_IX_LOCK 1 /* execution came to the node from
456
a node above and if the field
457
has_clust_rec_x_lock is FALSE, we
458
should set an intention x-lock on
460
#define UPD_NODE_UPDATE_CLUSTERED 2 /* clustered index record should be
462
#define UPD_NODE_INSERT_CLUSTERED 3 /* clustered index record should be
463
inserted, old record is already delete
465
#define UPD_NODE_UPDATE_ALL_SEC 4 /* an ordering field of the clustered
466
index record was changed, or this is
467
a delete operation: should update
468
all the secondary index records */
469
#define UPD_NODE_UPDATE_SOME_SEC 5 /* secondary index entries should be
470
looked at and updated if an ordering
473
/* Compilation info flags: these must fit within 3 bits; see trx0rec.h */
474
#define UPD_NODE_NO_ORD_CHANGE 1 /* no secondary index record will be
475
changed in the update and no ordering
476
field of the clustered index */
477
#define UPD_NODE_NO_SIZE_CHANGE 2 /* no record field size will be
478
changed in the update */
480
#endif /* !UNIV_HOTBACKUP */
483
#include "row0upd.ic"