~drizzle-trunk/drizzle/development

« back to all changes in this revision

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

  • Committer: Brian Aker
  • Date: 2010-12-18 18:24:57 UTC
  • mfrom: (1999.6.3 trunk)
  • Revision ID: brian@tangent.org-20101218182457-yi1wd0so2hml1k1w
Merge in Lee's copyright header fix

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
        const dtuple_t* entry,  /*!< in: index entry, where the memory buffers
 
130
                                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 record
 
171
given. No field size changes are allowed. */
 
172
UNIV_INTERN
 
173
void
 
174
row_upd_rec_in_place(
 
175
/*=================*/
 
176
        rec_t*          rec,    /*!< in/out: record where replaced */
 
177
        dict_index_t*   index,  /*!< in: the index the record belongs to */
 
178
        const ulint*    offsets,/*!< in: array returned by rec_get_offsets() */
 
179
        const upd_t*    update, /*!< in: update vector */
 
180
        page_zip_des_t* page_zip);/*!< in: compressed page with enough space
 
181
                                available, or NULL */
 
182
#ifndef UNIV_HOTBACKUP
 
183
/***************************************************************//**
 
184
Builds an update vector from those fields which in a secondary index entry
 
185
differ from a record that has the equal ordering fields. NOTE: we compare
 
186
the fields as binary strings!
 
187
@return own: update vector of differing fields */
 
188
UNIV_INTERN
 
189
upd_t*
 
190
row_upd_build_sec_rec_difference_binary(
 
191
/*====================================*/
 
192
        dict_index_t*   index,  /*!< in: index */
 
193
        const dtuple_t* entry,  /*!< in: entry to insert */
 
194
        const rec_t*    rec,    /*!< in: secondary index record */
 
195
        trx_t*          trx,    /*!< in: transaction */
 
196
        mem_heap_t*     heap);  /*!< in: memory heap from which allocated */
 
197
/***************************************************************//**
 
198
Builds an update vector from those fields, excluding the roll ptr and
 
199
trx id fields, which in an index entry differ from a record that has
 
200
the equal ordering fields. NOTE: we compare the fields as binary strings!
 
201
@return own: update vector of differing fields, excluding roll ptr and
 
202
trx id */
 
203
UNIV_INTERN
 
204
upd_t*
 
205
row_upd_build_difference_binary(
 
206
/*============================*/
 
207
        dict_index_t*   index,  /*!< in: clustered index */
 
208
        const dtuple_t* entry,  /*!< in: entry to insert */
 
209
        const rec_t*    rec,    /*!< in: clustered index record */
 
210
        trx_t*          trx,    /*!< in: transaction */
 
211
        mem_heap_t*     heap);  /*!< in: memory heap from which allocated */
 
212
/***********************************************************//**
 
213
Replaces the new column values stored in the update vector to the index entry
 
214
given. */
 
215
UNIV_INTERN
 
216
void
 
217
row_upd_index_replace_new_col_vals_index_pos(
 
218
/*=========================================*/
 
219
        dtuple_t*       entry,  /*!< in/out: index entry where replaced;
 
220
                                the clustered index record must be
 
221
                                covered by a lock or a page latch to
 
222
                                prevent deletion (rollback or purge) */
 
223
        dict_index_t*   index,  /*!< in: index; NOTE that this may also be a
 
224
                                non-clustered index */
 
225
        const upd_t*    update, /*!< in: an update vector built for the index so
 
226
                                that the field number in an upd_field is the
 
227
                                index position */
 
228
        ibool           order_only,
 
229
                                /*!< in: if TRUE, limit the replacement to
 
230
                                ordering fields of index; note that this
 
231
                                does not work for non-clustered indexes. */
 
232
        mem_heap_t*     heap)   /*!< in: memory heap for allocating and
 
233
                                copying the new values */
 
234
        __attribute__((nonnull));
 
235
/***********************************************************//**
 
236
Replaces the new column values stored in the update vector to the index entry
 
237
given. */
 
238
UNIV_INTERN
 
239
void
 
240
row_upd_index_replace_new_col_vals(
 
241
/*===============================*/
 
242
        dtuple_t*       entry,  /*!< in/out: index entry where replaced;
 
243
                                the clustered index record must be
 
244
                                covered by a lock or a page latch to
 
245
                                prevent deletion (rollback or purge) */
 
246
        dict_index_t*   index,  /*!< in: index; NOTE that this may also be a
 
247
                                non-clustered index */
 
248
        const upd_t*    update, /*!< in: an update vector built for the
 
249
                                CLUSTERED index so that the field number in
 
250
                                an upd_field is the clustered index position */
 
251
        mem_heap_t*     heap)   /*!< in: memory heap for allocating and
 
252
                                copying the new values */
 
253
        __attribute__((nonnull));
 
254
/***********************************************************//**
 
255
Replaces the new column values stored in the update vector. */
 
256
UNIV_INTERN
 
257
void
 
258
row_upd_replace(
 
259
/*============*/
 
260
        dtuple_t*               row,    /*!< in/out: row where replaced,
 
261
                                        indexed by col_no;
 
262
                                        the clustered index record must be
 
263
                                        covered by a lock or a page latch to
 
264
                                        prevent deletion (rollback or purge) */
 
265
        row_ext_t**             ext,    /*!< out, own: NULL, or externally
 
266
                                        stored column prefixes */
 
267
        const dict_index_t*     index,  /*!< in: clustered index */
 
268
        const upd_t*            update, /*!< in: an update vector built for the
 
269
                                        clustered index */
 
270
        mem_heap_t*             heap);  /*!< in: memory heap */
 
271
/***********************************************************//**
 
272
Checks if an update vector changes an ordering field of an index record.
 
273
 
 
274
This function is fast if the update vector is short or the number of ordering
 
275
fields in the index is small. Otherwise, this can be quadratic.
 
276
NOTE: we compare the fields as binary strings!
 
277
@return TRUE if update vector changes an ordering field in the index record */
 
278
UNIV_INTERN
 
279
ibool
 
280
row_upd_changes_ord_field_binary(
 
281
/*=============================*/
 
282
        const dtuple_t* row,    /*!< in: old value of row, or NULL if the
 
283
                                row and the data values in update are not
 
284
                                known when this function is called, e.g., at
 
285
                                compile time */
 
286
        dict_index_t*   index,  /*!< in: index of the record */
 
287
        const upd_t*    update);/*!< in: update vector for the row; NOTE: the
 
288
                                field numbers in this MUST be clustered index
 
289
                                positions! */
 
290
/***********************************************************//**
 
291
Checks if an update vector changes an ordering field of an index record.
 
292
This function is fast if the update vector is short or the number of ordering
 
293
fields in the index is small. Otherwise, this can be quadratic.
 
294
NOTE: we compare the fields as binary strings!
 
295
@return TRUE if update vector may change an ordering field in an index
 
296
record */
 
297
UNIV_INTERN
 
298
ibool
 
299
row_upd_changes_some_index_ord_field_binary(
 
300
/*========================================*/
 
301
        const dict_table_t*     table,  /*!< in: table */
 
302
        const upd_t*            update);/*!< in: update vector for the row */
 
303
/***********************************************************//**
 
304
Updates a row in a table. This is a high-level function used
 
305
in SQL execution graphs.
 
306
@return query thread to run next or NULL */
 
307
UNIV_INTERN
 
308
que_thr_t*
 
309
row_upd_step(
 
310
/*=========*/
 
311
        que_thr_t*      thr);   /*!< in: query thread */
 
312
#endif /* !UNIV_HOTBACKUP */
 
313
/*********************************************************************//**
 
314
Parses the log data of system field values.
 
315
@return log data end or NULL */
 
316
UNIV_INTERN
 
317
byte*
 
318
row_upd_parse_sys_vals(
 
319
/*===================*/
 
320
        byte*           ptr,    /*!< in: buffer */
 
321
        byte*           end_ptr,/*!< in: buffer end */
 
322
        ulint*          pos,    /*!< out: TRX_ID position in record */
 
323
        trx_id_t*       trx_id, /*!< out: trx id */
 
324
        roll_ptr_t*     roll_ptr);/*!< out: roll ptr */
 
325
/*********************************************************************//**
 
326
Updates the trx id and roll ptr field in a clustered index record in database
 
327
recovery. */
 
328
UNIV_INTERN
 
329
void
 
330
row_upd_rec_sys_fields_in_recovery(
 
331
/*===============================*/
 
332
        rec_t*          rec,    /*!< in/out: record */
 
333
        page_zip_des_t* page_zip,/*!< in/out: compressed page, or NULL */
 
334
        const ulint*    offsets,/*!< in: array returned by rec_get_offsets() */
 
335
        ulint           pos,    /*!< in: TRX_ID position in rec */
 
336
        trx_id_t        trx_id, /*!< in: transaction id */
 
337
        roll_ptr_t      roll_ptr);/*!< in: roll ptr of the undo log record */
 
338
/*********************************************************************//**
 
339
Parses the log data written by row_upd_index_write_log.
 
340
@return log data end or NULL */
 
341
UNIV_INTERN
 
342
byte*
 
343
row_upd_index_parse(
 
344
/*================*/
 
345
        byte*           ptr,    /*!< in: buffer */
 
346
        byte*           end_ptr,/*!< in: buffer end */
 
347
        mem_heap_t*     heap,   /*!< in: memory heap where update vector is
 
348
                                built */
 
349
        upd_t**         update_out);/*!< out: update vector */
 
350
 
 
351
 
 
352
/* Update vector field */
 
353
struct upd_field_struct{
 
354
        unsigned        field_no:16;    /*!< field number in an index, usually
 
355
                                        the clustered index, but in updating
 
356
                                        a secondary index record in btr0cur.c
 
357
                                        this is the position in the secondary
 
358
                                        index */
 
359
#ifndef UNIV_HOTBACKUP
 
360
        unsigned        orig_len:16;    /*!< original length of the locally
 
361
                                        stored part of an externally stored
 
362
                                        column, or 0 */
 
363
        que_node_t*     exp;            /*!< expression for calculating a new
 
364
                                        value: it refers to column values and
 
365
                                        constants in the symbol table of the
 
366
                                        query graph */
 
367
#endif /* !UNIV_HOTBACKUP */
 
368
        dfield_t        new_val;        /*!< new value for the column */
 
369
};
 
370
 
 
371
/* Update vector structure */
 
372
struct upd_struct{
 
373
        ulint           info_bits;      /*!< new value of info bits to record;
 
374
                                        default is 0 */
 
375
        ulint           n_fields;       /*!< number of update fields */
 
376
        upd_field_t*    fields;         /*!< array of update fields */
 
377
};
 
378
 
 
379
#ifndef UNIV_HOTBACKUP
 
380
/* Update node structure which also implements the delete operation
 
381
of a row */
 
382
 
 
383
struct upd_node_struct{
 
384
        que_common_t    common; /*!< node type: QUE_NODE_UPDATE */
 
385
        ibool           is_delete;/* TRUE if delete, FALSE if update */
 
386
        ibool           searched_update;
 
387
                                /* TRUE if searched update, FALSE if
 
388
                                positioned */
 
389
        ibool           in_mysql_interface;
 
390
                                /* TRUE if the update node was created
 
391
                                for the MySQL interface */
 
392
        dict_foreign_t* foreign;/* NULL or pointer to a foreign key
 
393
                                constraint if this update node is used in
 
394
                                doing an ON DELETE or ON UPDATE operation */
 
395
        upd_node_t*     cascade_node;/* NULL or an update node template which
 
396
                                is used to implement ON DELETE/UPDATE CASCADE
 
397
                                or ... SET NULL for foreign keys */
 
398
        mem_heap_t*     cascade_heap;/* NULL or a mem heap where the cascade
 
399
                                node is created */
 
400
        sel_node_t*     select; /*!< query graph subtree implementing a base
 
401
                                table cursor: the rows returned will be
 
402
                                updated */
 
403
        btr_pcur_t*     pcur;   /*!< persistent cursor placed on the clustered
 
404
                                index record which should be updated or
 
405
                                deleted; the cursor is stored in the graph
 
406
                                of 'select' field above, except in the case
 
407
                                of the MySQL interface */
 
408
        dict_table_t*   table;  /*!< table where updated */
 
409
        upd_t*          update; /*!< update vector for the row */
 
410
        ulint           update_n_fields;
 
411
                                /* when this struct is used to implement
 
412
                                a cascade operation for foreign keys, we store
 
413
                                here the size of the buffer allocated for use
 
414
                                as the update vector */
 
415
        sym_node_list_t columns;/* symbol table nodes for the columns
 
416
                                to retrieve from the table */
 
417
        ibool           has_clust_rec_x_lock;
 
418
                                /* TRUE if the select which retrieves the
 
419
                                records to update already sets an x-lock on
 
420
                                the clustered record; note that it must always
 
421
                                set at least an s-lock */
 
422
        ulint           cmpl_info;/* information extracted during query
 
423
                                compilation; speeds up execution:
 
424
                                UPD_NODE_NO_ORD_CHANGE and
 
425
                                UPD_NODE_NO_SIZE_CHANGE, ORed */
 
426
        /*----------------------*/
 
427
        /* Local storage for this graph node */
 
428
        ulint           state;  /*!< node execution state */
 
429
        dict_index_t*   index;  /*!< NULL, or the next index whose record should
 
430
                                be updated */
 
431
        dtuple_t*       row;    /*!< NULL, or a copy (also fields copied to
 
432
                                heap) of the row to update; this must be reset
 
433
                                to NULL after a successful update */
 
434
        row_ext_t*      ext;    /*!< NULL, or prefixes of the externally
 
435
                                stored columns in the old row */
 
436
        dtuple_t*       upd_row;/* NULL, or a copy of the updated row */
 
437
        row_ext_t*      upd_ext;/* NULL, or prefixes of the externally
 
438
                                stored columns in upd_row */
 
439
        mem_heap_t*     heap;   /*!< memory heap used as auxiliary storage;
 
440
                                this must be emptied after a successful
 
441
                                update */
 
442
        /*----------------------*/
 
443
        sym_node_t*     table_sym;/* table node in symbol table */
 
444
        que_node_t*     col_assign_list;
 
445
                                /* column assignment list */
 
446
        ulint           magic_n;
 
447
};
 
448
 
 
449
#define UPD_NODE_MAGIC_N        1579975
 
450
 
 
451
/* Node execution states */
 
452
#define UPD_NODE_SET_IX_LOCK       1    /* execution came to the node from
 
453
                                        a node above and if the field
 
454
                                        has_clust_rec_x_lock is FALSE, we
 
455
                                        should set an intention x-lock on
 
456
                                        the table */
 
457
#define UPD_NODE_UPDATE_CLUSTERED  2    /* clustered index record should be
 
458
                                        updated */
 
459
#define UPD_NODE_INSERT_CLUSTERED  3    /* clustered index record should be
 
460
                                        inserted, old record is already delete
 
461
                                        marked */
 
462
#define UPD_NODE_UPDATE_ALL_SEC    4    /* an ordering field of the clustered
 
463
                                        index record was changed, or this is
 
464
                                        a delete operation: should update
 
465
                                        all the secondary index records */
 
466
#define UPD_NODE_UPDATE_SOME_SEC   5    /* secondary index entries should be
 
467
                                        looked at and updated if an ordering
 
468
                                        field changed */
 
469
 
 
470
/* Compilation info flags: these must fit within 3 bits; see trx0rec.h */
 
471
#define UPD_NODE_NO_ORD_CHANGE  1       /* no secondary index record will be
 
472
                                        changed in the update and no ordering
 
473
                                        field of the clustered index */
 
474
#define UPD_NODE_NO_SIZE_CHANGE 2       /* no record field size will be
 
475
                                        changed in the update */
 
476
 
 
477
#endif /* !UNIV_HOTBACKUP */
 
478
 
 
479
#ifndef UNIV_NONINL
 
480
#include "row0upd.ic"
 
481
#endif
 
482
 
 
483
#endif