~stewart/drizzle/embedded-innodb-create-select-transaction-arrgh

« back to all changes in this revision

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

  • Committer: brian
  • Date: 2008-06-25 05:29:13 UTC
  • Revision ID: brian@localhost.localdomain-20080625052913-6upwo0jsrl4lnapl
clean slate

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
        upd_t*  update);        /* in: update vector */
 
40
/*************************************************************************
 
41
Returns the nth field of an update vector. */
 
42
UNIV_INLINE
 
43
upd_field_t*
 
44
upd_get_nth_field(
 
45
/*==============*/
 
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. */
 
51
UNIV_INLINE
 
52
void
 
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
 
57
                                        index */
 
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. */
 
63
 
 
64
byte*
 
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
 
72
                                in mlog */
 
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. */
 
77
UNIV_INLINE
 
78
void
 
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. */
 
88
 
 
89
void
 
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
 
95
                                them */
 
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. */
 
101
 
 
102
upd_node_t*
 
103
upd_node_create(
 
104
/*============*/
 
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. */
 
109
 
 
110
void
 
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. */
 
121
 
 
122
ibool
 
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
 
127
                                in rec or update */
 
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
 
134
a clustered index */
 
135
 
 
136
void
 
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! */
 
146
 
 
147
upd_t*
 
148
row_upd_build_sec_rec_difference_binary(
 
149
/*====================================*/
 
150
                                /* out, own: update vector of differing
 
151
                                fields */
 
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! */
 
161
 
 
162
upd_t*
 
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
 
177
given. */
 
178
 
 
179
void
 
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
 
187
                                index position */
 
188
        ibool           order_only,
 
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
 
197
given. */
 
198
 
 
199
void
 
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! */
 
216
 
 
217
ibool
 
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
 
223
                                strings */
 
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
 
227
                                compile time */
 
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
 
231
                                positions! */
 
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! */
 
237
 
 
238
ibool
 
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. */
 
248
 
 
249
que_thr_t*
 
250
row_upd_step(
 
251
/*=========*/
 
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
 
256
select. */
 
257
 
 
258
void
 
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. */
 
266
 
 
267
byte*
 
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
 
278
recovery. */
 
279
 
 
280
void
 
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. */
 
290
 
 
291
byte*
 
292
row_upd_index_parse(
 
293
/*================*/
 
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
 
298
                                built */
 
299
        upd_t**         update_out);/* out: update vector */
 
300
 
 
301
 
 
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
 
308
                                        index */
 
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
 
312
                                        query graph */
 
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 */
 
317
};
 
318
 
 
319
/* Update vector structure */
 
320
struct upd_struct{
 
321
        ulint           info_bits;      /* new value of info bits to record;
 
322
                                        default is 0 */
 
323
        ulint           n_fields;       /* number of update fields */
 
324
        upd_field_t*    fields;         /* array of update fields */
 
325
};
 
326
 
 
327
/* Update node structure which also implements the delete operation
 
328
of a row */
 
329
 
 
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
 
335
                                positioned */
 
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
 
351
                                node is created */
 
352
        sel_node_t*     select; /* query graph subtree implementing a base
 
353
                                table cursor: the rows returned will be
 
354
                                updated */
 
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
 
382
                                be updated */
 
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
 
388
                                row */
 
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
 
392
                                update */
 
393
        /*----------------------*/
 
394
        sym_node_t*     table_sym;/* table node in symbol table */
 
395
        que_node_t*     col_assign_list;
 
396
                                /* column assignment list */
 
397
        ulint           magic_n;
 
398
};
 
399
 
 
400
#define UPD_NODE_MAGIC_N        1579975
 
401
 
 
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
 
407
                                        the table */
 
408
#define UPD_NODE_UPDATE_CLUSTERED  2    /* clustered index record should be
 
409
                                        updated */
 
410
#define UPD_NODE_INSERT_CLUSTERED  3    /* clustered index record should be
 
411
                                        inserted, old record is already delete
 
412
                                        marked */
 
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
 
419
                                        field changed */
 
420
 
 
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 */
 
427
 
 
428
#ifndef UNIV_NONINL
 
429
#include "row0upd.ic"
 
430
#endif
 
431
 
 
432
#endif