~drizzle-trunk/drizzle/development

« back to all changes in this revision

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

  • Committer: Lee
  • Date: 2008-10-30 22:02:01 UTC
  • mto: (572.1.2 devel)
  • mto: This revision was merged to the branch mainline in revision 573.
  • Revision ID: lbieber@lbieber-desktop-20081030220201-elb6qprbzpn7c5a4
add my name to the AUTHORS file

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
/*****************************************************************************
2
 
 
3
 
Copyright (C) 1996, 2009, Innobase Oy. All Rights Reserved.
4
 
 
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.
8
 
 
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.
12
 
 
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
16
 
 
17
 
*****************************************************************************/
18
 
 
19
 
/**************************************************//**
20
 
@file include/row0upd.h
21
 
Update of a row
22
 
 
23
 
Created 12/27/1996 Heikki Tuuri
24
 
*******************************************************/
25
 
 
26
 
#ifndef row0upd_h
27
 
#define row0upd_h
28
 
 
29
 
#include "univ.i"
30
 
#include "data0data.h"
31
 
#include "row0types.h"
32
 
#include "btr0types.h"
33
 
#include "dict0types.h"
34
 
#include "trx0types.h"
35
 
 
36
 
#ifndef UNIV_HOTBACKUP
37
 
# include "btr0pcur.h"
38
 
# include "que0types.h"
39
 
# include "pars0types.h"
40
 
#endif /* !UNIV_HOTBACKUP */
41
 
 
42
 
/*********************************************************************//**
43
 
Creates an update vector object.
44
 
@return own: update vector object */
45
 
UNIV_INLINE
46
 
upd_t*
47
 
upd_create(
48
 
/*=======*/
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 */
55
 
UNIV_INLINE
56
 
ulint
57
 
upd_get_n_fields(
58
 
/*=============*/
59
 
        const upd_t*    update);        /*!< in: update vector */
60
 
#ifdef UNIV_DEBUG
61
 
/*********************************************************************//**
62
 
Returns the nth field of an update vector.
63
 
@return update vector field */
64
 
UNIV_INLINE
65
 
upd_field_t*
66
 
upd_get_nth_field(
67
 
/*==============*/
68
 
        const upd_t*    update, /*!< in: update vector */
69
 
        ulint           n);     /*!< in: field position in update vector */
70
 
#else
71
 
# define upd_get_nth_field(update, n) ((update)->fields + (n))
72
 
#endif
73
 
#ifndef UNIV_HOTBACKUP
74
 
/*********************************************************************//**
75
 
Sets an index field number to be updated by an update vector field. */
76
 
UNIV_INLINE
77
 
void
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
82
 
                                        index */
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 */
88
 
UNIV_INLINE
89
 
const upd_field_t*
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 */
99
 
UNIV_INTERN
100
 
byte*
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
107
 
                                in mlog */
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. */
112
 
UNIV_INLINE
113
 
void
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. */
125
 
UNIV_INTERN
126
 
void
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
132
 
                                them */
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 */
139
 
UNIV_INTERN
140
 
upd_node_t*
141
 
upd_node_create(
142
 
/*============*/
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. */
146
 
UNIV_INTERN
147
 
void
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 */
161
 
UNIV_INTERN
162
 
ibool
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(). */
175
 
UNIV_INTERN
176
 
void
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 */
191
 
UNIV_INTERN
192
 
upd_t*
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
205
 
trx id */
206
 
UNIV_INTERN
207
 
upd_t*
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
217
 
given. */
218
 
UNIV_INTERN
219
 
void
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
230
 
                                index position */
231
 
        ibool           order_only,
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
240
 
given. */
241
 
UNIV_INTERN
242
 
void
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. */
259
 
UNIV_INTERN
260
 
void
261
 
row_upd_replace(
262
 
/*============*/
263
 
        dtuple_t*               row,    /*!< in/out: row where replaced,
264
 
                                        indexed by col_no;
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
272
 
                                        clustered index */
273
 
        mem_heap_t*             heap);  /*!< in: memory heap */
274
 
/***********************************************************//**
275
 
Checks if an update vector changes an ordering field of an index record.
276
 
 
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 */
281
 
UNIV_INTERN
282
 
ibool
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
288
 
                                compile time */
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
292
 
                                positions! */
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
299
 
record */
300
 
UNIV_INTERN
301
 
ibool
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 */
310
 
UNIV_INTERN
311
 
que_thr_t*
312
 
row_upd_step(
313
 
/*=========*/
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 */
319
 
UNIV_INTERN
320
 
byte*
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
330
 
recovery. */
331
 
UNIV_INTERN
332
 
void
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 */
344
 
UNIV_INTERN
345
 
byte*
346
 
row_upd_index_parse(
347
 
/*================*/
348
 
        byte*           ptr,    /*!< in: buffer */
349
 
        byte*           end_ptr,/*!< in: buffer end */
350
 
        mem_heap_t*     heap,   /*!< in: memory heap where update vector is
351
 
                                built */
352
 
        upd_t**         update_out);/*!< out: update vector */
353
 
 
354
 
 
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
361
 
                                        index */
362
 
#ifndef UNIV_HOTBACKUP
363
 
        unsigned        orig_len:16;    /*!< original length of the locally
364
 
                                        stored part of an externally stored
365
 
                                        column, or 0 */
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
369
 
                                        query graph */
370
 
#endif /* !UNIV_HOTBACKUP */
371
 
        dfield_t        new_val;        /*!< new value for the column */
372
 
};
373
 
 
374
 
/* Update vector structure */
375
 
struct upd_struct{
376
 
        ulint           info_bits;      /*!< new value of info bits to record;
377
 
                                        default is 0 */
378
 
        ulint           n_fields;       /*!< number of update fields */
379
 
        upd_field_t*    fields;         /*!< array of update fields */
380
 
};
381
 
 
382
 
#ifndef UNIV_HOTBACKUP
383
 
/* Update node structure which also implements the delete operation
384
 
of a row */
385
 
 
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
391
 
                                positioned */
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
402
 
                                node is created */
403
 
        sel_node_t*     select; /*!< query graph subtree implementing a base
404
 
                                table cursor: the rows returned will be
405
 
                                updated */
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
433
 
                                be updated */
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
444
 
                                update */
445
 
        /*----------------------*/
446
 
        sym_node_t*     table_sym;/* table node in symbol table */
447
 
        que_node_t*     col_assign_list;
448
 
                                /* column assignment list */
449
 
        ulint           magic_n;
450
 
};
451
 
 
452
 
#define UPD_NODE_MAGIC_N        1579975
453
 
 
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
459
 
                                        the table */
460
 
#define UPD_NODE_UPDATE_CLUSTERED  2    /* clustered index record should be
461
 
                                        updated */
462
 
#define UPD_NODE_INSERT_CLUSTERED  3    /* clustered index record should be
463
 
                                        inserted, old record is already delete
464
 
                                        marked */
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
471
 
                                        field changed */
472
 
 
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 */
479
 
 
480
 
#endif /* !UNIV_HOTBACKUP */
481
 
 
482
 
#ifndef UNIV_NONINL
483
 
#include "row0upd.ic"
484
 
#endif
485
 
 
486
 
#endif