1
/******************************************************
6
Created 12/27/1996 Heikki Tuuri
7
*******************************************************/
13
#include "data0data.h"
14
#include "btr0types.h"
16
#include "dict0types.h"
17
#include "trx0types.h"
18
#include "que0types.h"
19
#include "row0types.h"
20
#include "pars0types.h"
22
/*************************************************************************
23
Creates an update vector object. */
28
/* out, own: update vector object */
29
ulint n, /* in: number of fields */
30
mem_heap_t* heap); /* in: heap from which memory allocated */
31
/*************************************************************************
32
Returns the number of fields in the update vector == number of columns
33
to be updated by an update vector. */
38
/* out: number of fields */
39
upd_t* update); /* in: update vector */
40
/*************************************************************************
41
Returns the nth field of an update vector. */
46
/* out: update vector field */
47
upd_t* update, /* in: update vector */
48
ulint n); /* in: field position in update vector */
49
/*************************************************************************
50
Sets an index field number to be updated by an update vector field. */
53
upd_field_set_field_no(
54
/*===================*/
55
upd_field_t* upd_field, /* in: update vector field */
56
ulint field_no, /* in: field number in a clustered
58
dict_index_t* index, /* in: index */
59
trx_t* trx); /* in: transaction */
60
/*************************************************************************
61
Writes into the redo log the values of trx id and roll ptr and enough info
62
to determine their positions within a clustered index record. */
65
row_upd_write_sys_vals_to_log(
66
/*==========================*/
67
/* out: new pointer to mlog */
68
dict_index_t* index, /* in: clustered index */
69
trx_t* trx, /* in: transaction */
70
dulint roll_ptr,/* in: roll ptr of the undo log record */
71
byte* log_ptr,/* pointer to a buffer of size > 20 opened
73
mtr_t* mtr); /* in: mtr */
74
/*************************************************************************
75
Updates the trx id and roll ptr field in a clustered index record when
76
a row is updated or marked deleted. */
79
row_upd_rec_sys_fields(
80
/*===================*/
81
rec_t* rec, /* in: record */
82
dict_index_t* index, /* in: clustered index */
83
const ulint* offsets,/* in: rec_get_offsets(rec, index) */
84
trx_t* trx, /* in: transaction */
85
dulint roll_ptr);/* in: roll ptr of the undo log record */
86
/*************************************************************************
87
Sets the trx id or roll ptr field of a clustered index entry. */
90
row_upd_index_entry_sys_field(
91
/*==========================*/
92
dtuple_t* entry, /* in: index entry, where the memory buffers
93
for sys fields are already allocated:
94
the function just copies the new values to
96
dict_index_t* index, /* in: clustered index */
97
ulint type, /* in: DATA_TRX_ID or DATA_ROLL_PTR */
98
dulint val); /* in: value to write */
99
/*************************************************************************
100
Creates an update node for a query graph. */
105
/* out, own: update node */
106
mem_heap_t* heap); /* in: mem heap where created */
107
/***************************************************************
108
Writes to the redo log the new values of the fields occurring in the index. */
111
row_upd_index_write_log(
112
/*====================*/
113
upd_t* update, /* in: update vector */
114
byte* log_ptr,/* in: pointer to mlog buffer: must contain at least
115
MLOG_BUF_MARGIN bytes of free space; the buffer is
116
closed within this function */
117
mtr_t* mtr); /* in: mtr into whose log to write */
118
/***************************************************************
119
Returns TRUE if row update changes size of some field in index or if some
120
field to be updated is stored externally in rec or update. */
123
row_upd_changes_field_size_or_external(
124
/*===================================*/
125
/* out: TRUE if the update changes the size of
126
some field in index or the field is external
128
dict_index_t* index, /* in: index */
129
const ulint* offsets,/* in: rec_get_offsets(rec, index) */
130
upd_t* update);/* in: update vector */
131
/***************************************************************
132
Replaces the new column values stored in the update vector to the record
133
given. No field size changes are allowed. This function is used only for
137
row_upd_rec_in_place(
138
/*=================*/
139
rec_t* rec, /* in/out: record where replaced */
140
const ulint* offsets,/* in: array returned by rec_get_offsets() */
141
upd_t* update);/* in: update vector */
142
/*******************************************************************
143
Builds an update vector from those fields which in a secondary index entry
144
differ from a record that has the equal ordering fields. NOTE: we compare
145
the fields as binary strings! */
148
row_upd_build_sec_rec_difference_binary(
149
/*====================================*/
150
/* out, own: update vector of differing
152
dict_index_t* index, /* in: index */
153
dtuple_t* entry, /* in: entry to insert */
154
rec_t* rec, /* in: secondary index record */
155
trx_t* trx, /* in: transaction */
156
mem_heap_t* heap); /* in: memory heap from which allocated */
157
/*******************************************************************
158
Builds an update vector from those fields, excluding the roll ptr and
159
trx id fields, which in an index entry differ from a record that has
160
the equal ordering fields. NOTE: we compare the fields as binary strings! */
163
row_upd_build_difference_binary(
164
/*============================*/
165
/* out, own: update vector of differing
166
fields, excluding roll ptr and trx id */
167
dict_index_t* index, /* in: clustered index */
168
dtuple_t* entry, /* in: entry to insert */
169
ulint* ext_vec,/* in: array containing field numbers of
170
externally stored fields in entry, or NULL */
171
ulint n_ext_vec,/* in: number of fields in ext_vec */
172
rec_t* rec, /* in: clustered index record */
173
trx_t* trx, /* in: transaction */
174
mem_heap_t* heap); /* in: memory heap from which allocated */
175
/***************************************************************
176
Replaces the new column values stored in the update vector to the index entry
180
row_upd_index_replace_new_col_vals_index_pos(
181
/*=========================================*/
182
dtuple_t* entry, /* in/out: index entry where replaced */
183
dict_index_t* index, /* in: index; NOTE that this may also be a
184
non-clustered index */
185
upd_t* update, /* in: an update vector built for the index so
186
that the field number in an upd_field is the
189
/* in: if TRUE, limit the replacement to
190
ordering fields of index; note that this
191
does not work for non-clustered indexes. */
192
mem_heap_t* heap); /* in: memory heap to which we allocate and
193
copy the new values, set this as NULL if you
194
do not want allocation */
195
/***************************************************************
196
Replaces the new column values stored in the update vector to the index entry
200
row_upd_index_replace_new_col_vals(
201
/*===============================*/
202
dtuple_t* entry, /* in/out: index entry where replaced */
203
dict_index_t* index, /* in: index; NOTE that this may also be a
204
non-clustered index */
205
upd_t* update, /* in: an update vector built for the
206
CLUSTERED index so that the field number in
207
an upd_field is the clustered index position */
208
mem_heap_t* heap); /* in: memory heap to which we allocate and
209
copy the new values, set this as NULL if you
210
do not want allocation */
211
/***************************************************************
212
Checks if an update vector changes an ordering field of an index record.
213
This function is fast if the update vector is short or the number of ordering
214
fields in the index is small. Otherwise, this can be quadratic.
215
NOTE: we compare the fields as binary strings! */
218
row_upd_changes_ord_field_binary(
219
/*=============================*/
220
/* out: TRUE if update vector changes
221
an ordering field in the index record;
222
NOTE: the fields are compared as binary
224
dtuple_t* row, /* in: old value of row, or NULL if the
225
row and the data values in update are not
226
known when this function is called, e.g., at
228
dict_index_t* index, /* in: index of the record */
229
upd_t* update);/* in: update vector for the row; NOTE: the
230
field numbers in this MUST be clustered index
232
/***************************************************************
233
Checks if an update vector changes an ordering field of an index record.
234
This function is fast if the update vector is short or the number of ordering
235
fields in the index is small. Otherwise, this can be quadratic.
236
NOTE: we compare the fields as binary strings! */
239
row_upd_changes_some_index_ord_field_binary(
240
/*========================================*/
241
/* out: TRUE if update vector may change
242
an ordering field in an index record */
243
dict_table_t* table, /* in: table */
244
upd_t* update);/* in: update vector for the row */
245
/***************************************************************
246
Updates a row in a table. This is a high-level function used
247
in SQL execution graphs. */
252
/* out: query thread to run next or NULL */
253
que_thr_t* thr); /* in: query thread */
254
/*************************************************************************
255
Performs an in-place update for the current clustered index record in
259
row_upd_in_place_in_select(
260
/*=======================*/
261
sel_node_t* sel_node, /* in: select node */
262
que_thr_t* thr, /* in: query thread */
263
mtr_t* mtr); /* in: mtr */
264
/*************************************************************************
265
Parses the log data of system field values. */
268
row_upd_parse_sys_vals(
269
/*===================*/
270
/* out: log data end or NULL */
271
byte* ptr, /* in: buffer */
272
byte* end_ptr,/* in: buffer end */
273
ulint* pos, /* out: TRX_ID position in record */
274
dulint* trx_id, /* out: trx id */
275
dulint* roll_ptr);/* out: roll ptr */
276
/*************************************************************************
277
Updates the trx id and roll ptr field in a clustered index record in database
281
row_upd_rec_sys_fields_in_recovery(
282
/*===============================*/
283
rec_t* rec, /* in: record */
284
const ulint* offsets,/* in: array returned by rec_get_offsets() */
285
ulint pos, /* in: TRX_ID position in rec */
286
dulint trx_id, /* in: transaction id */
287
dulint roll_ptr);/* in: roll ptr of the undo log record */
288
/*************************************************************************
289
Parses the log data written by row_upd_index_write_log. */
294
/* out: log data end or NULL */
295
byte* ptr, /* in: buffer */
296
byte* end_ptr,/* in: buffer end */
297
mem_heap_t* heap, /* in: memory heap where update vector is
299
upd_t** update_out);/* out: update vector */
302
/* Update vector field */
303
struct upd_field_struct{
304
ulint field_no; /* field number in an index, usually
305
the clustered index, but in updating
306
a secondary index record in btr0cur.c
307
this is the position in the secondary
309
que_node_t* exp; /* expression for calculating a new
310
value: it refers to column values and
311
constants in the symbol table of the
313
dfield_t new_val; /* new value for the column */
314
ibool extern_storage; /* this is set to TRUE if dfield
315
actually contains a reference to
316
an externally stored field */
319
/* Update vector structure */
321
ulint info_bits; /* new value of info bits to record;
323
ulint n_fields; /* number of update fields */
324
upd_field_t* fields; /* array of update fields */
327
/* Update node structure which also implements the delete operation
330
struct upd_node_struct{
331
que_common_t common; /* node type: QUE_NODE_UPDATE */
332
ibool is_delete;/* TRUE if delete, FALSE if update */
333
ibool searched_update;
334
/* TRUE if searched update, FALSE if
336
ibool select_will_do_update;
337
/* TRUE if a searched update where ordering
338
fields will not be updated, and the size of
339
the fields will not change: in this case the
340
select node will take care of the update */
341
ibool in_mysql_interface;
342
/* TRUE if the update node was created
343
for the MySQL interface */
344
dict_foreign_t* foreign;/* NULL or pointer to a foreign key
345
constraint if this update node is used in
346
doing an ON DELETE or ON UPDATE operation */
347
upd_node_t* cascade_node;/* NULL or an update node template which
348
is used to implement ON DELETE/UPDATE CASCADE
349
or ... SET NULL for foreign keys */
350
mem_heap_t* cascade_heap;/* NULL or a mem heap where the cascade
352
sel_node_t* select; /* query graph subtree implementing a base
353
table cursor: the rows returned will be
355
btr_pcur_t* pcur; /* persistent cursor placed on the clustered
356
index record which should be updated or
357
deleted; the cursor is stored in the graph
358
of 'select' field above, except in the case
359
of the MySQL interface */
360
dict_table_t* table; /* table where updated */
361
upd_t* update; /* update vector for the row */
362
ulint update_n_fields;
363
/* when this struct is used to implement
364
a cascade operation for foreign keys, we store
365
here the size of the buffer allocated for use
366
as the update vector */
367
sym_node_list_t columns;/* symbol table nodes for the columns
368
to retrieve from the table */
369
ibool has_clust_rec_x_lock;
370
/* TRUE if the select which retrieves the
371
records to update already sets an x-lock on
372
the clustered record; note that it must always
373
set at least an s-lock */
374
ulint cmpl_info;/* information extracted during query
375
compilation; speeds up execution:
376
UPD_NODE_NO_ORD_CHANGE and
377
UPD_NODE_NO_SIZE_CHANGE, ORed */
378
/*----------------------*/
379
/* Local storage for this graph node */
380
ulint state; /* node execution state */
381
dict_index_t* index; /* NULL, or the next index whose record should
383
dtuple_t* row; /* NULL, or a copy (also fields copied to
384
heap) of the row to update; this must be reset
385
to NULL after a successful update */
386
ulint* ext_vec;/* array describing which fields are stored
387
externally in the clustered index record of
389
ulint n_ext_vec;/* number of fields in ext_vec */
390
mem_heap_t* heap; /* memory heap used as auxiliary storage;
391
this must be emptied after a successful
393
/*----------------------*/
394
sym_node_t* table_sym;/* table node in symbol table */
395
que_node_t* col_assign_list;
396
/* column assignment list */
400
#define UPD_NODE_MAGIC_N 1579975
402
/* Node execution states */
403
#define UPD_NODE_SET_IX_LOCK 1 /* execution came to the node from
404
a node above and if the field
405
has_clust_rec_x_lock is FALSE, we
406
should set an intention x-lock on
408
#define UPD_NODE_UPDATE_CLUSTERED 2 /* clustered index record should be
410
#define UPD_NODE_INSERT_CLUSTERED 3 /* clustered index record should be
411
inserted, old record is already delete
413
#define UPD_NODE_UPDATE_ALL_SEC 4 /* an ordering field of the clustered
414
index record was changed, or this is
415
a delete operation: should update
416
all the secondary index records */
417
#define UPD_NODE_UPDATE_SOME_SEC 5 /* secondary index entries should be
418
looked at and updated if an ordering
421
/* Compilation info flags: these must fit within 3 bits; see trx0rec.h */
422
#define UPD_NODE_NO_ORD_CHANGE 1 /* no secondary index record will be
423
changed in the update and no ordering
424
field of the clustered index */
425
#define UPD_NODE_NO_SIZE_CHANGE 2 /* no record field size will be
426
changed in the update */
429
#include "row0upd.ic"