~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to storage/innobase/include/row0upd.h

Tags: innodb-plugin-1.0.1
Imported 1.0.1 with clean - with no changes.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/******************************************************
 
2
Update of a row
 
3
 
 
4
(c) 1996 Innobase Oy
 
5
 
 
6
Created 12/27/1996 Heikki Tuuri
 
7
*******************************************************/
 
8
 
 
9
#ifndef row0upd_h
 
10
#define row0upd_h
 
11
 
 
12
#include "univ.i"
 
13
#include "data0data.h"
 
14
#include "btr0types.h"
 
15
#include "btr0pcur.h"
 
16
#include "dict0types.h"
 
17
#include "trx0types.h"
 
18
#include "que0types.h"
 
19
#include "row0types.h"
 
20
#include "pars0types.h"
 
21
 
 
22
/*************************************************************************
 
23
Creates an update vector object. */
 
24
UNIV_INLINE
 
25
upd_t*
 
26
upd_create(
 
27
/*=======*/
 
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. */
 
34
UNIV_INLINE
 
35
ulint
 
36
upd_get_n_fields(
 
37
/*=============*/
 
38
                                        /* out: number of fields */
 
39
        const upd_t*    update);        /* in: update vector */
 
40
#ifdef UNIV_DEBUG
 
41
/*************************************************************************
 
42
Returns the nth field of an update vector. */
 
43
UNIV_INLINE
 
44
upd_field_t*
 
45
upd_get_nth_field(
 
46
/*==============*/
 
47
                                /* out: update vector field */
 
48
        const upd_t*    update, /* in: update vector */
 
49
        ulint           n);     /* in: field position in update vector */
 
50
#else
 
51
# define upd_get_nth_field(update, n) ((update)->fields + (n))
 
52
#endif
 
53
/*************************************************************************
 
54
Sets an index field number to be updated by an update vector field. */
 
55
UNIV_INLINE
 
56
void
 
57
upd_field_set_field_no(
 
58
/*===================*/
 
59
        upd_field_t*    upd_field,      /* in: update vector field */
 
60
        ulint           field_no,       /* in: field number in a clustered
 
61
                                        index */
 
62
        dict_index_t*   index,          /* in: index */
 
63
        trx_t*          trx);           /* in: transaction */
 
64
/*************************************************************************
 
65
Returns a field of an update vector by field_no. */
 
66
UNIV_INLINE
 
67
const upd_field_t*
 
68
upd_get_field_by_field_no(
 
69
/*======================*/
 
70
                                /* out: update vector field, or NULL */
 
71
        const upd_t*    update, /* in: update vector */
 
72
        ulint           no)     /* in: field_no */
 
73
        __attribute__((nonnull, pure));
 
74
/*************************************************************************
 
75
Writes into the redo log the values of trx id and roll ptr and enough info
 
76
to determine their positions within a clustered index record. */
 
77
UNIV_INTERN
 
78
byte*
 
79
row_upd_write_sys_vals_to_log(
 
80
/*==========================*/
 
81
                                /* out: new pointer to mlog */
 
82
        dict_index_t*   index,  /* in: clustered index */
 
83
        trx_t*          trx,    /* in: transaction */
 
84
        dulint          roll_ptr,/* in: roll ptr of the undo log record */
 
85
        byte*           log_ptr,/* pointer to a buffer of size > 20 opened
 
86
                                in mlog */
 
87
        mtr_t*          mtr);   /* in: mtr */
 
88
/*************************************************************************
 
89
Updates the trx id and roll ptr field in a clustered index record when
 
90
a row is updated or marked deleted. */
 
91
UNIV_INLINE
 
92
void
 
93
row_upd_rec_sys_fields(
 
94
/*===================*/
 
95
        rec_t*          rec,    /* in/out: record */
 
96
        page_zip_des_t* page_zip,/* in/out: compressed page whose
 
97
                                uncompressed part will be updated, or NULL */
 
98
        dict_index_t*   index,  /* in: clustered index */
 
99
        const ulint*    offsets,/* in: rec_get_offsets(rec, index) */
 
100
        trx_t*          trx,    /* in: transaction */
 
101
        dulint          roll_ptr);/* in: roll ptr of the undo log record */
 
102
/*************************************************************************
 
103
Sets the trx id or roll ptr field of a clustered index entry. */
 
104
UNIV_INTERN
 
105
void
 
106
row_upd_index_entry_sys_field(
 
107
/*==========================*/
 
108
        const dtuple_t* entry,  /* in: index entry, where the memory buffers
 
109
                                for sys fields are already allocated:
 
110
                                the function just copies the new values to
 
111
                                them */
 
112
        dict_index_t*   index,  /* in: clustered index */
 
113
        ulint           type,   /* in: DATA_TRX_ID or DATA_ROLL_PTR */
 
114
        dulint          val);   /* in: value to write */
 
115
/*************************************************************************
 
116
Creates an update node for a query graph. */
 
117
UNIV_INTERN
 
118
upd_node_t*
 
119
upd_node_create(
 
120
/*============*/
 
121
                                /* out, own: update node */
 
122
        mem_heap_t*     heap);  /* in: mem heap where created */
 
123
/***************************************************************
 
124
Writes to the redo log the new values of the fields occurring in the index. */
 
125
UNIV_INTERN
 
126
void
 
127
row_upd_index_write_log(
 
128
/*====================*/
 
129
        const upd_t*    update, /* in: update vector */
 
130
        byte*           log_ptr,/* in: pointer to mlog buffer: must
 
131
                                contain at least MLOG_BUF_MARGIN bytes
 
132
                                of free space; the buffer is closed
 
133
                                within this function */
 
134
        mtr_t*          mtr);   /* in: mtr into whose log to write */
 
135
/***************************************************************
 
136
Returns TRUE if row update changes size of some field in index or if some
 
137
field to be updated is stored externally in rec or update. */
 
138
UNIV_INTERN
 
139
ibool
 
140
row_upd_changes_field_size_or_external(
 
141
/*===================================*/
 
142
                                /* out: TRUE if the update changes the size of
 
143
                                some field in index or the field is external
 
144
                                in rec or update */
 
145
        dict_index_t*   index,  /* in: index */
 
146
        const ulint*    offsets,/* in: rec_get_offsets(rec, index) */
 
147
        const upd_t*    update);/* in: update vector */
 
148
/***************************************************************
 
149
Replaces the new column values stored in the update vector to the record
 
150
given. No field size changes are allowed. */
 
151
UNIV_INTERN
 
152
void
 
153
row_upd_rec_in_place(
 
154
/*=================*/
 
155
        rec_t*          rec,    /* in/out: record where replaced */
 
156
        dict_index_t*   index,  /* in: the index the record belongs to */
 
157
        const ulint*    offsets,/* in: array returned by rec_get_offsets() */
 
158
        const upd_t*    update, /* in: update vector */
 
159
        page_zip_des_t* page_zip);/* in: compressed page with enough space
 
160
                                available, or NULL */
 
161
/*******************************************************************
 
162
Builds an update vector from those fields which in a secondary index entry
 
163
differ from a record that has the equal ordering fields. NOTE: we compare
 
164
the fields as binary strings! */
 
165
UNIV_INTERN
 
166
upd_t*
 
167
row_upd_build_sec_rec_difference_binary(
 
168
/*====================================*/
 
169
                                /* out, own: update vector of differing
 
170
                                fields */
 
171
        dict_index_t*   index,  /* in: index */
 
172
        const dtuple_t* entry,  /* in: entry to insert */
 
173
        const rec_t*    rec,    /* in: secondary index record */
 
174
        trx_t*          trx,    /* in: transaction */
 
175
        mem_heap_t*     heap);  /* in: memory heap from which allocated */
 
176
/*******************************************************************
 
177
Builds an update vector from those fields, excluding the roll ptr and
 
178
trx id fields, which in an index entry differ from a record that has
 
179
the equal ordering fields. NOTE: we compare the fields as binary strings! */
 
180
UNIV_INTERN
 
181
upd_t*
 
182
row_upd_build_difference_binary(
 
183
/*============================*/
 
184
                                /* out, own: update vector of differing
 
185
                                fields, excluding roll ptr and trx id */
 
186
        dict_index_t*   index,  /* in: clustered index */
 
187
        const dtuple_t* entry,  /* in: entry to insert */
 
188
        const rec_t*    rec,    /* in: clustered index record */
 
189
        trx_t*          trx,    /* in: transaction */
 
190
        mem_heap_t*     heap);  /* in: memory heap from which allocated */
 
191
/***************************************************************
 
192
Replaces the new column values stored in the update vector to the index entry
 
193
given. */
 
194
UNIV_INTERN
 
195
void
 
196
row_upd_index_replace_new_col_vals_index_pos(
 
197
/*=========================================*/
 
198
        dtuple_t*       entry,  /* in/out: index entry where replaced;
 
199
                                the clustered index record must be
 
200
                                covered by a lock or a page latch to
 
201
                                prevent deletion (rollback or purge) */
 
202
        dict_index_t*   index,  /* in: index; NOTE that this may also be a
 
203
                                non-clustered index */
 
204
        const upd_t*    update, /* in: an update vector built for the index so
 
205
                                that the field number in an upd_field is the
 
206
                                index position */
 
207
        ibool           order_only,
 
208
                                /* in: if TRUE, limit the replacement to
 
209
                                ordering fields of index; note that this
 
210
                                does not work for non-clustered indexes. */
 
211
        mem_heap_t*     heap)   /* in: memory heap for allocating and
 
212
                                copying the new values */
 
213
        __attribute__((nonnull));
 
214
/***************************************************************
 
215
Replaces the new column values stored in the update vector to the index entry
 
216
given. */
 
217
UNIV_INTERN
 
218
void
 
219
row_upd_index_replace_new_col_vals(
 
220
/*===============================*/
 
221
        dtuple_t*       entry,  /* in/out: index entry where replaced;
 
222
                                the clustered index record must be
 
223
                                covered by a lock or a page latch to
 
224
                                prevent deletion (rollback or purge) */
 
225
        dict_index_t*   index,  /* in: index; NOTE that this may also be a
 
226
                                non-clustered index */
 
227
        const upd_t*    update, /* in: an update vector built for the
 
228
                                CLUSTERED index so that the field number in
 
229
                                an upd_field is the clustered index position */
 
230
        mem_heap_t*     heap)   /* in: memory heap for allocating and
 
231
                                copying the new values */
 
232
        __attribute__((nonnull));
 
233
/***************************************************************
 
234
Replaces the new column values stored in the update vector. */
 
235
UNIV_INTERN
 
236
void
 
237
row_upd_replace(
 
238
/*============*/
 
239
        dtuple_t*               row,    /* in/out: row where replaced,
 
240
                                        indexed by col_no;
 
241
                                        the clustered index record must be
 
242
                                        covered by a lock or a page latch to
 
243
                                        prevent deletion (rollback or purge) */
 
244
        row_ext_t**             ext,    /* out, own: NULL, or externally
 
245
                                        stored column prefixes */
 
246
        const dict_index_t*     index,  /* in: clustered index */
 
247
        const upd_t*            update, /* in: an update vector built for the
 
248
                                        clustered index */
 
249
        mem_heap_t*             heap);  /* in: memory heap */
 
250
/***************************************************************
 
251
Checks if an update vector changes an ordering field of an index record.
 
252
This function is fast if the update vector is short or the number of ordering
 
253
fields in the index is small. Otherwise, this can be quadratic.
 
254
NOTE: we compare the fields as binary strings! */
 
255
UNIV_INTERN
 
256
ibool
 
257
row_upd_changes_ord_field_binary(
 
258
/*=============================*/
 
259
                                /* out: TRUE if update vector changes
 
260
                                an ordering field in the index record;
 
261
                                NOTE: the fields are compared as binary
 
262
                                strings */
 
263
        const dtuple_t* row,    /* in: old value of row, or NULL if the
 
264
                                row and the data values in update are not
 
265
                                known when this function is called, e.g., at
 
266
                                compile time */
 
267
        dict_index_t*   index,  /* in: index of the record */
 
268
        const upd_t*    update);/* in: update vector for the row; NOTE: the
 
269
                                field numbers in this MUST be clustered index
 
270
                                positions! */
 
271
/***************************************************************
 
272
Checks if an update vector changes an ordering field of an index record.
 
273
This function is fast if the update vector is short or the number of ordering
 
274
fields in the index is small. Otherwise, this can be quadratic.
 
275
NOTE: we compare the fields as binary strings! */
 
276
UNIV_INTERN
 
277
ibool
 
278
row_upd_changes_some_index_ord_field_binary(
 
279
/*========================================*/
 
280
                                        /* out: TRUE if update vector
 
281
                                        may change an ordering field
 
282
                                        in an index record */
 
283
        const dict_table_t*     table,  /* in: table */
 
284
        const upd_t*            update);/* in: update vector for the row */
 
285
/***************************************************************
 
286
Updates a row in a table. This is a high-level function used
 
287
in SQL execution graphs. */
 
288
UNIV_INTERN
 
289
que_thr_t*
 
290
row_upd_step(
 
291
/*=========*/
 
292
                                /* out: query thread to run next or NULL */
 
293
        que_thr_t*      thr);   /* in: query thread */
 
294
/*************************************************************************
 
295
Performs an in-place update for the current clustered index record in
 
296
select. */
 
297
UNIV_INTERN
 
298
void
 
299
row_upd_in_place_in_select(
 
300
/*=======================*/
 
301
        sel_node_t*     sel_node,       /* in: select node */
 
302
        que_thr_t*      thr,            /* in: query thread */
 
303
        mtr_t*          mtr);           /* in: mtr */
 
304
/*************************************************************************
 
305
Parses the log data of system field values. */
 
306
UNIV_INTERN
 
307
byte*
 
308
row_upd_parse_sys_vals(
 
309
/*===================*/
 
310
                        /* out: log data end or NULL */
 
311
        byte*   ptr,    /* in: buffer */
 
312
        byte*   end_ptr,/* in: buffer end */
 
313
        ulint*  pos,    /* out: TRX_ID position in record */
 
314
        dulint* trx_id, /* out: trx id */
 
315
        dulint* roll_ptr);/* out: roll ptr */
 
316
/*************************************************************************
 
317
Updates the trx id and roll ptr field in a clustered index record in database
 
318
recovery. */
 
319
UNIV_INTERN
 
320
void
 
321
row_upd_rec_sys_fields_in_recovery(
 
322
/*===============================*/
 
323
        rec_t*          rec,    /* in/out: record */
 
324
        page_zip_des_t* page_zip,/* in/out: compressed page, or NULL */
 
325
        const ulint*    offsets,/* in: array returned by rec_get_offsets() */
 
326
        ulint           pos,    /* in: TRX_ID position in rec */
 
327
        dulint          trx_id, /* in: transaction id */
 
328
        dulint          roll_ptr);/* in: roll ptr of the undo log record */
 
329
/*************************************************************************
 
330
Parses the log data written by row_upd_index_write_log. */
 
331
UNIV_INTERN
 
332
byte*
 
333
row_upd_index_parse(
 
334
/*================*/
 
335
                                /* out: log data end or NULL */
 
336
        byte*           ptr,    /* in: buffer */
 
337
        byte*           end_ptr,/* in: buffer end */
 
338
        mem_heap_t*     heap,   /* in: memory heap where update vector is
 
339
                                built */
 
340
        upd_t**         update_out);/* out: update vector */
 
341
 
 
342
 
 
343
/* Update vector field */
 
344
struct upd_field_struct{
 
345
        unsigned        field_no:16;    /* field number in an index, usually
 
346
                                        the clustered index, but in updating
 
347
                                        a secondary index record in btr0cur.c
 
348
                                        this is the position in the secondary
 
349
                                        index */
 
350
        unsigned        orig_len:16;    /* original length of the locally
 
351
                                        stored part of an externally stored
 
352
                                        column, or 0 */
 
353
        que_node_t*     exp;            /* expression for calculating a new
 
354
                                        value: it refers to column values and
 
355
                                        constants in the symbol table of the
 
356
                                        query graph */
 
357
        dfield_t        new_val;        /* new value for the column */
 
358
};
 
359
 
 
360
/* Update vector structure */
 
361
struct upd_struct{
 
362
        ulint           info_bits;      /* new value of info bits to record;
 
363
                                        default is 0 */
 
364
        ulint           n_fields;       /* number of update fields */
 
365
        upd_field_t*    fields;         /* array of update fields */
 
366
};
 
367
 
 
368
/* Update node structure which also implements the delete operation
 
369
of a row */
 
370
 
 
371
struct upd_node_struct{
 
372
        que_common_t    common; /* node type: QUE_NODE_UPDATE */
 
373
        ibool           is_delete;/* TRUE if delete, FALSE if update */
 
374
        ibool           searched_update;
 
375
                                /* TRUE if searched update, FALSE if
 
376
                                positioned */
 
377
        ibool           select_will_do_update;
 
378
                                /* TRUE if a searched update where ordering
 
379
                                fields will not be updated, and the size of
 
380
                                the fields will not change: in this case the
 
381
                                select node will take care of the update */
 
382
        ibool           in_mysql_interface;
 
383
                                /* TRUE if the update node was created
 
384
                                for the MySQL interface */
 
385
        dict_foreign_t* foreign;/* NULL or pointer to a foreign key
 
386
                                constraint if this update node is used in
 
387
                                doing an ON DELETE or ON UPDATE operation */
 
388
        upd_node_t*     cascade_node;/* NULL or an update node template which
 
389
                                is used to implement ON DELETE/UPDATE CASCADE
 
390
                                or ... SET NULL for foreign keys */
 
391
        mem_heap_t*     cascade_heap;/* NULL or a mem heap where the cascade
 
392
                                node is created */
 
393
        sel_node_t*     select; /* query graph subtree implementing a base
 
394
                                table cursor: the rows returned will be
 
395
                                updated */
 
396
        btr_pcur_t*     pcur;   /* persistent cursor placed on the clustered
 
397
                                index record which should be updated or
 
398
                                deleted; the cursor is stored in the graph
 
399
                                of 'select' field above, except in the case
 
400
                                of the MySQL interface */
 
401
        dict_table_t*   table;  /* table where updated */
 
402
        upd_t*          update; /* update vector for the row */
 
403
        ulint           update_n_fields;
 
404
                                /* when this struct is used to implement
 
405
                                a cascade operation for foreign keys, we store
 
406
                                here the size of the buffer allocated for use
 
407
                                as the update vector */
 
408
        sym_node_list_t columns;/* symbol table nodes for the columns
 
409
                                to retrieve from the table */
 
410
        ibool           has_clust_rec_x_lock;
 
411
                                /* TRUE if the select which retrieves the
 
412
                                records to update already sets an x-lock on
 
413
                                the clustered record; note that it must always
 
414
                                set at least an s-lock */
 
415
        ulint           cmpl_info;/* information extracted during query
 
416
                                compilation; speeds up execution:
 
417
                                UPD_NODE_NO_ORD_CHANGE and
 
418
                                UPD_NODE_NO_SIZE_CHANGE, ORed */
 
419
        /*----------------------*/
 
420
        /* Local storage for this graph node */
 
421
        ulint           state;  /* node execution state */
 
422
        dict_index_t*   index;  /* NULL, or the next index whose record should
 
423
                                be updated */
 
424
        dtuple_t*       row;    /* NULL, or a copy (also fields copied to
 
425
                                heap) of the row to update; this must be reset
 
426
                                to NULL after a successful update */
 
427
        row_ext_t*      ext;    /* NULL, or prefixes of the externally
 
428
                                stored columns in the old row */
 
429
        dtuple_t*       upd_row;/* NULL, or a copy of the updated row */
 
430
        row_ext_t*      upd_ext;/* NULL, or prefixes of the externally
 
431
                                stored columns in upd_row */
 
432
        mem_heap_t*     heap;   /* memory heap used as auxiliary storage;
 
433
                                this must be emptied after a successful
 
434
                                update */
 
435
        /*----------------------*/
 
436
        sym_node_t*     table_sym;/* table node in symbol table */
 
437
        que_node_t*     col_assign_list;
 
438
                                /* column assignment list */
 
439
        ulint           magic_n;
 
440
};
 
441
 
 
442
#define UPD_NODE_MAGIC_N        1579975
 
443
 
 
444
/* Node execution states */
 
445
#define UPD_NODE_SET_IX_LOCK       1    /* execution came to the node from
 
446
                                        a node above and if the field
 
447
                                        has_clust_rec_x_lock is FALSE, we
 
448
                                        should set an intention x-lock on
 
449
                                        the table */
 
450
#define UPD_NODE_UPDATE_CLUSTERED  2    /* clustered index record should be
 
451
                                        updated */
 
452
#define UPD_NODE_INSERT_CLUSTERED  3    /* clustered index record should be
 
453
                                        inserted, old record is already delete
 
454
                                        marked */
 
455
#define UPD_NODE_UPDATE_ALL_SEC    4    /* an ordering field of the clustered
 
456
                                        index record was changed, or this is
 
457
                                        a delete operation: should update
 
458
                                        all the secondary index records */
 
459
#define UPD_NODE_UPDATE_SOME_SEC   5    /* secondary index entries should be
 
460
                                        looked at and updated if an ordering
 
461
                                        field changed */
 
462
 
 
463
/* Compilation info flags: these must fit within 3 bits; see trx0rec.h */
 
464
#define UPD_NODE_NO_ORD_CHANGE  1       /* no secondary index record will be
 
465
                                        changed in the update and no ordering
 
466
                                        field of the clustered index */
 
467
#define UPD_NODE_NO_SIZE_CHANGE 2       /* no record field size will be
 
468
                                        changed in the update */
 
469
 
 
470
#ifndef UNIV_NONINL
 
471
#include "row0upd.ic"
 
472
#endif
 
473
 
 
474
#endif