~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to plugin/innobase/row/row0ins.c

  • Committer: Brian Aker
  • Date: 2010-04-05 23:46:43 UTC
  • Revision ID: brian@gaz-20100405234643-0he3xnj902rc70r8
Fixing tests to work with PBXT.

Show diffs side-by-side

added added

removed removed

Lines of Context:
16
16
 
17
17
*****************************************************************************/
18
18
 
19
 
/******************************************************
 
19
/**************************************************//**
 
20
@file row/row0ins.c
20
21
Insert into a table
21
22
 
22
23
Created 4/20/1996 Heikki Tuuri
28
29
#include "row0ins.ic"
29
30
#endif
30
31
 
 
32
#include "ha_prototypes.h"
31
33
#include "dict0dict.h"
32
34
#include "dict0boot.h"
33
35
#include "trx0undo.h"
50
52
#define ROW_INS_NEXT    2
51
53
 
52
54
 
53
 
/*********************************************************************
54
 
This prototype is copied from /mysql/sql/ha_innodb.cc.
55
 
Invalidates the MySQL query cache for the table.
56
 
NOTE that the exact prototype of this function has to be in
57
 
/innobase/row/row0ins.c! */
58
 
extern
59
 
void
60
 
innobase_invalidate_query_cache(
61
 
/*============================*/
62
 
        trx_t*  trx,            /* in: transaction which modifies the table */
63
 
        char*   full_name,      /* in: concatenation of database name, null
64
 
                                char '\0', table name, null char'\0';
65
 
                                NOTE that in Windows this is always
66
 
                                in LOWER CASE! */
67
 
        ulint   full_name_len); /* in: full name length where also the null
68
 
                                chars count */
69
 
 
70
 
/*************************************************************************
71
 
Creates an insert node struct. */
 
55
/*********************************************************************//**
 
56
Creates an insert node struct.
 
57
@return own: insert node struct */
72
58
UNIV_INTERN
73
59
ins_node_t*
74
60
ins_node_create(
75
61
/*============*/
76
 
                                        /* out, own: insert node struct */
77
 
        ulint           ins_type,       /* in: INS_VALUES, ... */
78
 
        dict_table_t*   table,          /* in: table where to insert */
79
 
        mem_heap_t*     heap)           /* in: mem heap where created */
 
62
        ulint           ins_type,       /*!< in: INS_VALUES, ... */
 
63
        dict_table_t*   table,          /*!< in: table where to insert */
 
64
        mem_heap_t*     heap)           /*!< in: mem heap where created */
80
65
{
81
66
        ins_node_t*     node;
82
67
 
102
87
        return(node);
103
88
}
104
89
 
105
 
/***************************************************************
 
90
/***********************************************************//**
106
91
Creates an entry template for each index of a table. */
107
92
UNIV_INTERN
108
93
void
109
94
ins_node_create_entry_list(
110
95
/*=======================*/
111
 
        ins_node_t*     node)   /* in: row insert node */
 
96
        ins_node_t*     node)   /*!< in: row insert node */
112
97
{
113
98
        dict_index_t*   index;
114
99
        dtuple_t*       entry;
128
113
        }
129
114
}
130
115
 
131
 
/*********************************************************************
 
116
/*****************************************************************//**
132
117
Adds system field buffers to a row. */
133
118
static
134
119
void
135
120
row_ins_alloc_sys_fields(
136
121
/*=====================*/
137
 
        ins_node_t*     node)   /* in: insert node */
 
122
        ins_node_t*     node)   /*!< in: insert node */
138
123
{
139
124
        dtuple_t*               row;
140
125
        dict_table_t*           table;
183
168
        dfield_set_data(dfield, ptr, DATA_ROLL_PTR_LEN);
184
169
}
185
170
 
186
 
/*************************************************************************
 
171
/*********************************************************************//**
187
172
Sets a new row to insert for an INS_DIRECT node. This function is only used
188
173
if we have constructed the row separately, which is a rare case; this
189
174
function is quite slow. */
191
176
void
192
177
ins_node_set_new_row(
193
178
/*=================*/
194
 
        ins_node_t*     node,   /* in: insert node */
195
 
        dtuple_t*       row)    /* in: new row (or first row) for the node */
 
179
        ins_node_t*     node,   /*!< in: insert node */
 
180
        dtuple_t*       row)    /*!< in: new row (or first row) for the node */
196
181
{
197
182
        node->state = INS_NODE_SET_IX_LOCK;
198
183
        node->index = NULL;
216
201
        node->trx_id = ut_dulint_zero;
217
202
}
218
203
 
219
 
/***********************************************************************
 
204
/*******************************************************************//**
220
205
Does an insert operation by updating a delete-marked existing record
221
206
in the index. This situation can occur if the delete-marked record is
222
 
kept in the index for consistent reads. */
 
207
kept in the index for consistent reads.
 
208
@return DB_SUCCESS or error code */
223
209
static
224
210
ulint
225
211
row_ins_sec_index_entry_by_modify(
226
212
/*==============================*/
227
 
                                /* out: DB_SUCCESS or error code */
228
 
        ulint           mode,   /* in: BTR_MODIFY_LEAF or BTR_MODIFY_TREE,
 
213
        ulint           mode,   /*!< in: BTR_MODIFY_LEAF or BTR_MODIFY_TREE,
229
214
                                depending on whether mtr holds just a leaf
230
215
                                latch or also a tree latch */
231
 
        btr_cur_t*      cursor, /* in: B-tree cursor */
232
 
        const dtuple_t* entry,  /* in: index entry to insert */
233
 
        que_thr_t*      thr,    /* in: query thread */
234
 
        mtr_t*          mtr)    /* in: mtr; must be committed before
 
216
        btr_cur_t*      cursor, /*!< in: B-tree cursor */
 
217
        const dtuple_t* entry,  /*!< in: index entry to insert */
 
218
        que_thr_t*      thr,    /*!< in: query thread */
 
219
        mtr_t*          mtr)    /*!< in: mtr; must be committed before
235
220
                                latching any further pages */
236
221
{
237
222
        big_rec_t*      dummy_big_rec;
287
272
        return(err);
288
273
}
289
274
 
290
 
/***********************************************************************
 
275
/*******************************************************************//**
291
276
Does an insert operation by delete unmarking and updating a delete marked
292
277
existing record in the index. This situation can occur if the delete marked
293
 
record is kept in the index for consistent reads. */
 
278
record is kept in the index for consistent reads.
 
279
@return DB_SUCCESS, DB_FAIL, or error code */
294
280
static
295
281
ulint
296
282
row_ins_clust_index_entry_by_modify(
297
283
/*================================*/
298
 
                                /* out: DB_SUCCESS, DB_FAIL, or error code */
299
 
        ulint           mode,   /* in: BTR_MODIFY_LEAF or BTR_MODIFY_TREE,
 
284
        ulint           mode,   /*!< in: BTR_MODIFY_LEAF or BTR_MODIFY_TREE,
300
285
                                depending on whether mtr holds just a leaf
301
286
                                latch or also a tree latch */
302
 
        btr_cur_t*      cursor, /* in: B-tree cursor */
303
 
        mem_heap_t**    heap,   /* in/out: pointer to memory heap, or NULL */
304
 
        big_rec_t**     big_rec,/* out: possible big rec vector of fields
 
287
        btr_cur_t*      cursor, /*!< in: B-tree cursor */
 
288
        mem_heap_t**    heap,   /*!< in/out: pointer to memory heap, or NULL */
 
289
        big_rec_t**     big_rec,/*!< out: possible big rec vector of fields
305
290
                                which have to be stored externally by the
306
291
                                caller */
307
 
        const dtuple_t* entry,  /* in: index entry to insert */
308
 
        que_thr_t*      thr,    /* in: query thread */
309
 
        mtr_t*          mtr)    /* in: mtr; must be committed before
 
292
        const dtuple_t* entry,  /*!< in: index entry to insert */
 
293
        que_thr_t*      thr,    /*!< in: query thread */
 
294
        mtr_t*          mtr)    /*!< in: mtr; must be committed before
310
295
                                latching any further pages */
311
296
{
312
297
        rec_t*          rec;
359
344
        return(err);
360
345
}
361
346
 
362
 
/*************************************************************************
 
347
/*********************************************************************//**
363
348
Returns TRUE if in a cascaded update/delete an ancestor node of node
364
 
updates (not DELETE, but UPDATE) table. */
 
349
updates (not DELETE, but UPDATE) table.
 
350
@return TRUE if an ancestor updates table */
365
351
static
366
352
ibool
367
353
row_ins_cascade_ancestor_updates_table(
368
354
/*===================================*/
369
 
                                /* out: TRUE if an ancestor updates table */
370
 
        que_node_t*     node,   /* in: node in a query graph */
371
 
        dict_table_t*   table)  /* in: table */
 
355
        que_node_t*     node,   /*!< in: node in a query graph */
 
356
        dict_table_t*   table)  /*!< in: table */
372
357
{
373
358
        que_node_t*     parent;
374
359
        upd_node_t*     upd_node;
392
377
        return(FALSE);
393
378
}
394
379
 
395
 
/*************************************************************************
 
380
/*********************************************************************//**
396
381
Returns the number of ancestor UPDATE or DELETE nodes of a
397
 
cascaded update/delete node. */
 
382
cascaded update/delete node.
 
383
@return number of ancestors */
398
384
static
399
385
ulint
400
386
row_ins_cascade_n_ancestors(
401
387
/*========================*/
402
 
                                /* out: number of ancestors */
403
 
        que_node_t*     node)   /* in: node in a query graph */
 
388
        que_node_t*     node)   /*!< in: node in a query graph */
404
389
{
405
390
        que_node_t*     parent;
406
391
        ulint           n_ancestors = 0;
418
403
        return(n_ancestors);
419
404
}
420
405
 
421
 
/**********************************************************************
 
406
/******************************************************************//**
422
407
Calculates the update vector node->cascade->update for a child table in
423
 
a cascaded update. */
 
408
a cascaded update.
 
409
@return number of fields in the calculated update vector; the value
 
410
can also be 0 if no foreign key fields changed; the returned value is
 
411
ULINT_UNDEFINED if the column type in the child table is too short to
 
412
fit the new value in the parent table: that means the update fails */
424
413
static
425
414
ulint
426
415
row_ins_cascade_calc_update_vec(
427
416
/*============================*/
428
 
                                        /* out: number of fields in the
429
 
                                        calculated update vector; the value
430
 
                                        can also be 0 if no foreign key
431
 
                                        fields changed; the returned value
432
 
                                        is ULINT_UNDEFINED if the column
433
 
                                        type in the child table is too short
434
 
                                        to fit the new value in the parent
435
 
                                        table: that means the update fails */
436
 
        upd_node_t*     node,           /* in: update node of the parent
 
417
        upd_node_t*     node,           /*!< in: update node of the parent
437
418
                                        table */
438
 
        dict_foreign_t* foreign,        /* in: foreign key constraint whose
 
419
        dict_foreign_t* foreign,        /*!< in: foreign key constraint whose
439
420
                                        type is != 0 */
440
 
        mem_heap_t*     heap)           /* in: memory heap to use as
 
421
        mem_heap_t*     heap)           /*!< in: memory heap to use as
441
422
                                        temporary storage */
442
423
{
443
424
        upd_node_t*     cascade         = node->cascade_node;
606
587
        return(n_fields_updated);
607
588
}
608
589
 
609
 
/*************************************************************************
 
590
/*********************************************************************//**
610
591
Set detailed error message associated with foreign key errors for
611
592
the given transaction. */
612
593
static
613
594
void
614
595
row_ins_set_detailed(
615
596
/*=================*/
616
 
        trx_t*          trx,            /* in: transaction */
617
 
        dict_foreign_t* foreign)        /* in: foreign key constraint */
 
597
        trx_t*          trx,            /*!< in: transaction */
 
598
        dict_foreign_t* foreign)        /*!< in: foreign key constraint */
618
599
{
619
600
        mutex_enter(&srv_misc_tmpfile_mutex);
620
601
        rewind(srv_misc_tmpfile);
632
613
        mutex_exit(&srv_misc_tmpfile_mutex);
633
614
}
634
615
 
635
 
/*************************************************************************
 
616
/*********************************************************************//**
636
617
Reports a foreign key error associated with an update or a delete of a
637
618
parent table index entry. */
638
619
static
639
620
void
640
621
row_ins_foreign_report_err(
641
622
/*=======================*/
642
 
        const char*     errstr,         /* in: error string from the viewpoint
 
623
        const char*     errstr,         /*!< in: error string from the viewpoint
643
624
                                        of the parent table */
644
 
        que_thr_t*      thr,            /* in: query thread whose run_node
 
625
        que_thr_t*      thr,            /*!< in: query thread whose run_node
645
626
                                        is an update node */
646
 
        dict_foreign_t* foreign,        /* in: foreign key constraint */
647
 
        const rec_t*    rec,            /* in: a matching index record in the
 
627
        dict_foreign_t* foreign,        /*!< in: foreign key constraint */
 
628
        const rec_t*    rec,            /*!< in: a matching index record in the
648
629
                                        child table */
649
 
        const dtuple_t* entry)          /* in: index entry in the parent
 
630
        const dtuple_t* entry)          /*!< in: index entry in the parent
650
631
                                        table */
651
632
{
652
633
        FILE*   ef      = dict_foreign_err_file;
688
669
        mutex_exit(&dict_foreign_err_mutex);
689
670
}
690
671
 
691
 
/*************************************************************************
 
672
/*********************************************************************//**
692
673
Reports a foreign key error to dict_foreign_err_file when we are trying
693
674
to add an index entry to a child table. Note that the adding may be the result
694
675
of an update, too. */
696
677
void
697
678
row_ins_foreign_report_add_err(
698
679
/*===========================*/
699
 
        trx_t*          trx,            /* in: transaction */
700
 
        dict_foreign_t* foreign,        /* in: foreign key constraint */
701
 
        const rec_t*    rec,            /* in: a record in the parent table:
 
680
        trx_t*          trx,            /*!< in: transaction */
 
681
        dict_foreign_t* foreign,        /*!< in: foreign key constraint */
 
682
        const rec_t*    rec,            /*!< in: a record in the parent table:
702
683
                                        it does not match entry because we
703
684
                                        have an error! */
704
 
        const dtuple_t* entry)          /* in: index entry to insert in the
 
685
        const dtuple_t* entry)          /*!< in: index entry to insert in the
705
686
                                        child table */
706
687
{
707
688
        FILE*   ef      = dict_foreign_err_file;
746
727
        mutex_exit(&dict_foreign_err_mutex);
747
728
}
748
729
 
749
 
/*************************************************************************
 
730
/*********************************************************************//**
750
731
Invalidate the query cache for the given table. */
751
732
static
752
733
void
753
734
row_ins_invalidate_query_cache(
754
735
/*===========================*/
755
 
        que_thr_t*      thr,            /* in: query thread whose run_node
 
736
        que_thr_t*      unused,         /*!< in: query thread whose run_node
756
737
                                        is an update node */
757
 
        const char*     name)           /* in: table name prefixed with
 
738
        const char*     name)           /*!< in: table name prefixed with
758
739
                                        database name and a '/' character */
759
740
{
760
741
        char*   buf;
761
742
        char*   ptr;
762
743
        ulint   len = strlen(name) + 1;
763
744
 
 
745
        (void)unused;
 
746
 
764
747
        buf = mem_strdupl(name, len);
765
748
 
766
749
        ptr = strchr(buf, '/');
767
750
        ut_a(ptr);
768
751
        *ptr = '\0';
769
752
 
770
 
        /* We call a function in ha_innodb.cc */
771
 
#ifndef UNIV_HOTBACKUP
772
 
        innobase_invalidate_query_cache(thr_get_trx(thr), buf, len);
773
 
#endif
774
753
        mem_free(buf);
775
754
}
776
755
 
777
 
/*************************************************************************
 
756
/*********************************************************************//**
778
757
Perform referential actions or checks when a parent row is deleted or updated
779
758
and the constraint had an ON DELETE or ON UPDATE condition which was not
780
 
RESTRICT. */
 
759
RESTRICT.
 
760
@return DB_SUCCESS, DB_LOCK_WAIT, or error code */
781
761
static
782
762
ulint
783
763
row_ins_foreign_check_on_constraint(
784
764
/*================================*/
785
 
                                        /* out: DB_SUCCESS, DB_LOCK_WAIT,
786
 
                                        or error code */
787
 
        que_thr_t*      thr,            /* in: query thread whose run_node
 
765
        que_thr_t*      thr,            /*!< in: query thread whose run_node
788
766
                                        is an update node */
789
 
        dict_foreign_t* foreign,        /* in: foreign key constraint whose
 
767
        dict_foreign_t* foreign,        /*!< in: foreign key constraint whose
790
768
                                        type is != 0 */
791
 
        btr_pcur_t*     pcur,           /* in: cursor placed on a matching
 
769
        btr_pcur_t*     pcur,           /*!< in: cursor placed on a matching
792
770
                                        index record in the child table */
793
 
        dtuple_t*       entry,          /* in: index entry in the parent
 
771
        dtuple_t*       entry,          /*!< in: index entry in the parent
794
772
                                        table */
795
 
        mtr_t*          mtr)            /* in: mtr holding the latch of pcur
 
773
        mtr_t*          mtr)            /*!< in: mtr holding the latch of pcur
796
774
                                        page */
797
775
{
798
776
        upd_node_t*     node;
1141
1119
        return(err);
1142
1120
}
1143
1121
 
1144
 
/*************************************************************************
 
1122
/*********************************************************************//**
1145
1123
Sets a shared lock on a record. Used in locking possible duplicate key
1146
 
records and also in checking foreign key constraints. */
 
1124
records and also in checking foreign key constraints.
 
1125
@return DB_SUCCESS or error code */
1147
1126
static
1148
1127
ulint
1149
1128
row_ins_set_shared_rec_lock(
1150
1129
/*========================*/
1151
 
                                        /* out: DB_SUCCESS or error code */
1152
 
        ulint                   type,   /* in: LOCK_ORDINARY, LOCK_GAP, or
 
1130
        ulint                   type,   /*!< in: LOCK_ORDINARY, LOCK_GAP, or
1153
1131
                                        LOCK_REC_NOT_GAP type lock */
1154
 
        const buf_block_t*      block,  /* in: buffer block of rec */
1155
 
        const rec_t*            rec,    /* in: record */
1156
 
        dict_index_t*           index,  /* in: index */
1157
 
        const ulint*            offsets,/* in: rec_get_offsets(rec, index) */
1158
 
        que_thr_t*              thr)    /* in: query thread */
 
1132
        const buf_block_t*      block,  /*!< in: buffer block of rec */
 
1133
        const rec_t*            rec,    /*!< in: record */
 
1134
        dict_index_t*           index,  /*!< in: index */
 
1135
        const ulint*            offsets,/*!< in: rec_get_offsets(rec, index) */
 
1136
        que_thr_t*              thr)    /*!< in: query thread */
1159
1137
{
1160
1138
        ulint   err;
1161
1139
 
1172
1150
        return(err);
1173
1151
}
1174
1152
 
1175
 
#ifndef UNIV_HOTBACKUP
1176
 
/*************************************************************************
 
1153
/*********************************************************************//**
1177
1154
Sets a exclusive lock on a record. Used in locking possible duplicate key
1178
 
records */
 
1155
records
 
1156
@return DB_SUCCESS or error code */
1179
1157
static
1180
1158
ulint
1181
1159
row_ins_set_exclusive_rec_lock(
1182
1160
/*===========================*/
1183
 
                                        /* out: DB_SUCCESS or error code */
1184
 
        ulint                   type,   /* in: LOCK_ORDINARY, LOCK_GAP, or
 
1161
        ulint                   type,   /*!< in: LOCK_ORDINARY, LOCK_GAP, or
1185
1162
                                        LOCK_REC_NOT_GAP type lock */
1186
 
        const buf_block_t*      block,  /* in: buffer block of rec */
1187
 
        const rec_t*            rec,    /* in: record */
1188
 
        dict_index_t*           index,  /* in: index */
1189
 
        const ulint*            offsets,/* in: rec_get_offsets(rec, index) */
1190
 
        que_thr_t*              thr)    /* in: query thread */
 
1163
        const buf_block_t*      block,  /*!< in: buffer block of rec */
 
1164
        const rec_t*            rec,    /*!< in: record */
 
1165
        dict_index_t*           index,  /*!< in: index */
 
1166
        const ulint*            offsets,/*!< in: rec_get_offsets(rec, index) */
 
1167
        que_thr_t*              thr)    /*!< in: query thread */
1191
1168
{
1192
1169
        ulint   err;
1193
1170
 
1203
1180
 
1204
1181
        return(err);
1205
1182
}
1206
 
#endif /* !UNIV_HOTBACKUP */
1207
1183
 
1208
 
/*******************************************************************
 
1184
/***************************************************************//**
1209
1185
Checks if foreign key constraint fails for an index entry. Sets shared locks
1210
1186
which lock either the success or the failure of the constraint. NOTE that
1211
 
the caller must have a shared latch on dict_operation_lock. */
 
1187
the caller must have a shared latch on dict_operation_lock.
 
1188
@return DB_SUCCESS, DB_NO_REFERENCED_ROW, or DB_ROW_IS_REFERENCED */
1212
1189
UNIV_INTERN
1213
1190
ulint
1214
1191
row_ins_check_foreign_constraint(
1215
1192
/*=============================*/
1216
 
                                /* out: DB_SUCCESS,
1217
 
                                DB_NO_REFERENCED_ROW,
1218
 
                                or DB_ROW_IS_REFERENCED */
1219
 
        ibool           check_ref,/* in: TRUE if we want to check that
 
1193
        ibool           check_ref,/*!< in: TRUE if we want to check that
1220
1194
                                the referenced table is ok, FALSE if we
1221
1195
                                want to to check the foreign key table */
1222
 
        dict_foreign_t* foreign,/* in: foreign constraint; NOTE that the
 
1196
        dict_foreign_t* foreign,/*!< in: foreign constraint; NOTE that the
1223
1197
                                tables mentioned in it must be in the
1224
1198
                                dictionary cache if they exist at all */
1225
 
        dict_table_t*   table,  /* in: if check_ref is TRUE, then the foreign
 
1199
        dict_table_t*   table,  /*!< in: if check_ref is TRUE, then the foreign
1226
1200
                                table, else the referenced table */
1227
 
        dtuple_t*       entry,  /* in: index entry for index */
1228
 
        que_thr_t*      thr)    /* in: query thread */
 
1201
        dtuple_t*       entry,  /*!< in: index entry for index */
 
1202
        que_thr_t*      thr)    /*!< in: query thread */
1229
1203
{
1230
1204
        upd_node_t*     upd_node;
1231
1205
        dict_table_t*   check_table;
1529
1503
        return(err);
1530
1504
}
1531
1505
 
1532
 
/*******************************************************************
 
1506
/***************************************************************//**
1533
1507
Checks if foreign key constraints fail for an index entry. If index
1534
1508
is not mentioned in any constraint, this function does nothing,
1535
1509
Otherwise does searches to the indexes of referenced tables and
1536
1510
sets shared locks which lock either the success or the failure of
1537
 
a constraint. */
 
1511
a constraint.
 
1512
@return DB_SUCCESS or error code */
1538
1513
static
1539
1514
ulint
1540
1515
row_ins_check_foreign_constraints(
1541
1516
/*==============================*/
1542
 
                                /* out: DB_SUCCESS or error code */
1543
 
        dict_table_t*   table,  /* in: table */
1544
 
        dict_index_t*   index,  /* in: index */
1545
 
        dtuple_t*       entry,  /* in: index entry for index */
1546
 
        que_thr_t*      thr)    /* in: query thread */
 
1517
        dict_table_t*   table,  /*!< in: table */
 
1518
        dict_index_t*   index,  /*!< in: index */
 
1519
        dtuple_t*       entry,  /*!< in: index entry for index */
 
1520
        que_thr_t*      thr)    /*!< in: query thread */
1547
1521
{
1548
1522
        dict_foreign_t* foreign;
1549
1523
        ulint           err;
1611
1585
        return(DB_SUCCESS);
1612
1586
}
1613
1587
 
1614
 
#ifndef UNIV_HOTBACKUP
1615
 
/*******************************************************************
 
1588
/***************************************************************//**
1616
1589
Checks if a unique key violation to rec would occur at the index entry
1617
 
insert. */
 
1590
insert.
 
1591
@return TRUE if error */
1618
1592
static
1619
1593
ibool
1620
1594
row_ins_dupl_error_with_rec(
1621
1595
/*========================*/
1622
 
                                /* out: TRUE if error */
1623
 
        const rec_t*    rec,    /* in: user record; NOTE that we assume
 
1596
        const rec_t*    rec,    /*!< in: user record; NOTE that we assume
1624
1597
                                that the caller already has a record lock on
1625
1598
                                the record! */
1626
 
        const dtuple_t* entry,  /* in: entry to insert */
1627
 
        dict_index_t*   index,  /* in: index */
1628
 
        const ulint*    offsets)/* in: rec_get_offsets(rec, index) */
 
1599
        const dtuple_t* entry,  /*!< in: entry to insert */
 
1600
        dict_index_t*   index,  /*!< in: index */
 
1601
        const ulint*    offsets)/*!< in: rec_get_offsets(rec, index) */
1629
1602
{
1630
1603
        ulint   matched_fields;
1631
1604
        ulint   matched_bytes;
1663
1636
 
1664
1637
        return(!rec_get_deleted_flag(rec, rec_offs_comp(offsets)));
1665
1638
}
1666
 
#endif /* !UNIV_HOTBACKUP */
1667
1639
 
1668
 
/*******************************************************************
 
1640
/***************************************************************//**
1669
1641
Scans a unique non-clustered index at a given index entry to determine
1670
1642
whether a uniqueness violation has occurred for the key value of the entry.
1671
 
Set shared locks on possible duplicate records. */
 
1643
Set shared locks on possible duplicate records.
 
1644
@return DB_SUCCESS, DB_DUPLICATE_KEY, or DB_LOCK_WAIT */
1672
1645
static
1673
1646
ulint
1674
1647
row_ins_scan_sec_index_for_duplicate(
1675
1648
/*=================================*/
1676
 
                                /* out: DB_SUCCESS, DB_DUPLICATE_KEY, or
1677
 
                                DB_LOCK_WAIT */
1678
 
        dict_index_t*   index,  /* in: non-clustered unique index */
1679
 
        dtuple_t*       entry,  /* in: index entry */
1680
 
        que_thr_t*      thr)    /* in: query thread */
 
1649
        dict_index_t*   index,  /*!< in: non-clustered unique index */
 
1650
        dtuple_t*       entry,  /*!< in: index entry */
 
1651
        que_thr_t*      thr)    /*!< in: query thread */
1681
1652
{
1682
 
#ifndef UNIV_HOTBACKUP
1683
1653
        ulint           n_unique;
1684
1654
        ulint           i;
1685
1655
        int             cmp;
1789
1759
        dtuple_set_n_fields_cmp(entry, n_fields_cmp);
1790
1760
 
1791
1761
        return(err);
1792
 
#else /* UNIV_HOTBACKUP */
1793
 
        /* This function depends on MySQL code that is not included in
1794
 
        InnoDB Hot Backup builds.  Besides, this function should never
1795
 
        be called in InnoDB Hot Backup. */
1796
 
        ut_error;
1797
 
        return(DB_FAIL);
1798
 
#endif /* UNIV_HOTBACKUP */
1799
1762
}
1800
1763
 
1801
 
/*******************************************************************
 
1764
/***************************************************************//**
1802
1765
Checks if a unique key violation error would occur at an index entry
1803
1766
insert. Sets shared locks on possible duplicate records. Works only
1804
 
for a clustered index! */
 
1767
for a clustered index!
 
1768
@return DB_SUCCESS if no error, DB_DUPLICATE_KEY if error,
 
1769
DB_LOCK_WAIT if we have to wait for a lock on a possible duplicate
 
1770
record */
1805
1771
static
1806
1772
ulint
1807
1773
row_ins_duplicate_error_in_clust(
1808
1774
/*=============================*/
1809
 
                                /* out: DB_SUCCESS if no error,
1810
 
                                DB_DUPLICATE_KEY if error, DB_LOCK_WAIT if we
1811
 
                                have to wait for a lock on a possible
1812
 
                                duplicate record */
1813
 
        btr_cur_t*      cursor, /* in: B-tree cursor */
1814
 
        dtuple_t*       entry,  /* in: entry to insert */
1815
 
        que_thr_t*      thr,    /* in: query thread */
1816
 
        mtr_t*          mtr)    /* in: mtr */
 
1775
        btr_cur_t*      cursor, /*!< in: B-tree cursor */
 
1776
        dtuple_t*       entry,  /*!< in: entry to insert */
 
1777
        que_thr_t*      thr,    /*!< in: query thread */
 
1778
        mtr_t*          mtr)    /*!< in: mtr */
1817
1779
{
1818
 
#ifndef UNIV_HOTBACKUP
1819
1780
        ulint   err;
1820
1781
        rec_t*  rec;
1821
1782
        ulint   n_unique;
1939
1900
                mem_heap_free(heap);
1940
1901
        }
1941
1902
        return(err);
1942
 
#else /* UNIV_HOTBACKUP */
1943
 
        /* This function depends on MySQL code that is not included in
1944
 
        InnoDB Hot Backup builds.  Besides, this function should never
1945
 
        be called in InnoDB Hot Backup. */
1946
 
        ut_error;
1947
 
        return(DB_FAIL);
1948
 
#endif /* UNIV_HOTBACKUP */
1949
1903
}
1950
1904
 
1951
 
/*******************************************************************
 
1905
/***************************************************************//**
1952
1906
Checks if an index entry has long enough common prefix with an existing
1953
1907
record so that the intended insert of the entry must be changed to a modify of
1954
1908
the existing record. In the case of a clustered index, the prefix must be
1955
1909
n_unique fields long, and in the case of a secondary index, all fields must be
1956
 
equal. */
 
1910
equal.
 
1911
@return 0 if no update, ROW_INS_PREV if previous should be updated;
 
1912
currently we do the search so that only the low_match record can match
 
1913
enough to the search tuple, not the next record */
1957
1914
UNIV_INLINE
1958
1915
ulint
1959
1916
row_ins_must_modify(
1960
1917
/*================*/
1961
 
                                /* out: 0 if no update, ROW_INS_PREV if
1962
 
                                previous should be updated; currently we
1963
 
                                do the search so that only the low_match
1964
 
                                record can match enough to the search tuple,
1965
 
                                not the next record */
1966
 
        btr_cur_t*      cursor) /* in: B-tree cursor */
 
1918
        btr_cur_t*      cursor) /*!< in: B-tree cursor */
1967
1919
{
1968
1920
        ulint   enough_match;
1969
1921
        rec_t*  rec;
1990
1942
        return(0);
1991
1943
}
1992
1944
 
1993
 
/*******************************************************************
 
1945
/***************************************************************//**
1994
1946
Tries to insert an index entry to an index. If the index is clustered
1995
1947
and a record with the same unique key is found, the other record is
1996
1948
necessarily marked deleted by a committed transaction, or a unique key
1998
1950
existing record, and we must write an undo log record on the delete
1999
1951
marked record. If the index is secondary, and a record with exactly the
2000
1952
same fields is found, the other record is necessarily marked deleted.
2001
 
It is then unmarked. Otherwise, the entry is just inserted to the index. */
 
1953
It is then unmarked. Otherwise, the entry is just inserted to the index.
 
1954
@return DB_SUCCESS, DB_LOCK_WAIT, DB_FAIL if pessimistic retry needed,
 
1955
or error code */
2002
1956
static
2003
1957
ulint
2004
1958
row_ins_index_entry_low(
2005
1959
/*====================*/
2006
 
                                /* out: DB_SUCCESS, DB_LOCK_WAIT, DB_FAIL
2007
 
                                if pessimistic retry needed, or error code */
2008
 
        ulint           mode,   /* in: BTR_MODIFY_LEAF or BTR_MODIFY_TREE,
 
1960
        ulint           mode,   /*!< in: BTR_MODIFY_LEAF or BTR_MODIFY_TREE,
2009
1961
                                depending on whether we wish optimistic or
2010
1962
                                pessimistic descent down the index tree */
2011
 
        dict_index_t*   index,  /* in: index */
2012
 
        dtuple_t*       entry,  /* in: index entry to insert */
2013
 
        ulint           n_ext,  /* in: number of externally stored columns */
2014
 
        que_thr_t*      thr)    /* in: query thread */
 
1963
        dict_index_t*   index,  /*!< in: index */
 
1964
        dtuple_t*       entry,  /*!< in: index entry to insert */
 
1965
        ulint           n_ext,  /*!< in: number of externally stored columns */
 
1966
        que_thr_t*      thr)    /*!< in: query thread */
2015
1967
{
2016
1968
        btr_cur_t       cursor;
2017
1969
        ulint           ignore_sec_unique       = 0;
2177
2129
        return(err);
2178
2130
}
2179
2131
 
2180
 
/*******************************************************************
 
2132
/***************************************************************//**
2181
2133
Inserts an index entry to index. Tries first optimistic, then pessimistic
2182
2134
descent down the tree. If the entry matches enough to a delete marked record,
2183
2135
performs the insert by updating or delete unmarking the delete marked
2184
 
record. */
 
2136
record.
 
2137
@return DB_SUCCESS, DB_LOCK_WAIT, DB_DUPLICATE_KEY, or some other error code */
2185
2138
UNIV_INTERN
2186
2139
ulint
2187
2140
row_ins_index_entry(
2188
2141
/*================*/
2189
 
                                /* out: DB_SUCCESS, DB_LOCK_WAIT,
2190
 
                                DB_DUPLICATE_KEY, or some other error code */
2191
 
        dict_index_t*   index,  /* in: index */
2192
 
        dtuple_t*       entry,  /* in: index entry to insert */
2193
 
        ulint           n_ext,  /* in: number of externally stored columns */
2194
 
        ibool           foreign,/* in: TRUE=check foreign key constraints */
2195
 
        que_thr_t*      thr)    /* in: query thread */
 
2142
        dict_index_t*   index,  /*!< in: index */
 
2143
        dtuple_t*       entry,  /*!< in: index entry to insert */
 
2144
        ulint           n_ext,  /*!< in: number of externally stored columns */
 
2145
        ibool           foreign,/*!< in: TRUE=check foreign key constraints */
 
2146
        que_thr_t*      thr)    /*!< in: query thread */
2196
2147
{
2197
2148
        ulint   err;
2198
2149
 
2221
2172
        return(err);
2222
2173
}
2223
2174
 
2224
 
/***************************************************************
 
2175
/***********************************************************//**
2225
2176
Sets the values of the dtuple fields in entry from the values of appropriate
2226
2177
columns in row. */
2227
2178
static
2228
2179
void
2229
2180
row_ins_index_entry_set_vals(
2230
2181
/*=========================*/
2231
 
        dict_index_t*   index,  /* in: index */
2232
 
        dtuple_t*       entry,  /* in: index entry to make */
2233
 
        const dtuple_t* row)    /* in: row */
 
2182
        dict_index_t*   index,  /*!< in: index */
 
2183
        dtuple_t*       entry,  /*!< in: index entry to make */
 
2184
        const dtuple_t* row)    /*!< in: row */
2234
2185
{
2235
2186
        ulint   n_fields;
2236
2187
        ulint   i;
2273
2224
        }
2274
2225
}
2275
2226
 
2276
 
/***************************************************************
2277
 
Inserts a single index entry to the table. */
 
2227
/***********************************************************//**
 
2228
Inserts a single index entry to the table.
 
2229
@return DB_SUCCESS if operation successfully completed, else error
 
2230
code or DB_LOCK_WAIT */
2278
2231
static
2279
2232
ulint
2280
2233
row_ins_index_entry_step(
2281
2234
/*=====================*/
2282
 
                                /* out: DB_SUCCESS if operation successfully
2283
 
                                completed, else error code or DB_LOCK_WAIT */
2284
 
        ins_node_t*     node,   /* in: row insert node */
2285
 
        que_thr_t*      thr)    /* in: query thread */
 
2235
        ins_node_t*     node,   /*!< in: row insert node */
 
2236
        que_thr_t*      thr)    /*!< in: query thread */
2286
2237
{
2287
2238
        ulint   err;
2288
2239
 
2297
2248
        return(err);
2298
2249
}
2299
2250
 
2300
 
/***************************************************************
 
2251
/***********************************************************//**
2301
2252
Allocates a row id for row and inits the node->index field. */
2302
2253
UNIV_INLINE
2303
2254
void
2304
2255
row_ins_alloc_row_id_step(
2305
2256
/*======================*/
2306
 
        ins_node_t*     node)   /* in: row insert node */
 
2257
        ins_node_t*     node)   /*!< in: row insert node */
2307
2258
{
2308
2259
        dulint  row_id;
2309
2260
 
2323
2274
        dict_sys_write_row_id(node->row_id_buf, row_id);
2324
2275
}
2325
2276
 
2326
 
/***************************************************************
 
2277
/***********************************************************//**
2327
2278
Gets a row to insert from the values list. */
2328
2279
UNIV_INLINE
2329
2280
void
2330
2281
row_ins_get_row_from_values(
2331
2282
/*========================*/
2332
 
        ins_node_t*     node)   /* in: row insert node */
 
2283
        ins_node_t*     node)   /*!< in: row insert node */
2333
2284
{
2334
2285
        que_node_t*     list_node;
2335
2286
        dfield_t*       dfield;
2356
2307
        }
2357
2308
}
2358
2309
 
2359
 
/***************************************************************
 
2310
/***********************************************************//**
2360
2311
Gets a row to insert from the select list. */
2361
2312
UNIV_INLINE
2362
2313
void
2363
2314
row_ins_get_row_from_select(
2364
2315
/*========================*/
2365
 
        ins_node_t*     node)   /* in: row insert node */
 
2316
        ins_node_t*     node)   /*!< in: row insert node */
2366
2317
{
2367
2318
        que_node_t*     list_node;
2368
2319
        dfield_t*       dfield;
2387
2338
        }
2388
2339
}
2389
2340
 
2390
 
/***************************************************************
2391
 
Inserts a row to a table. */
 
2341
/***********************************************************//**
 
2342
Inserts a row to a table.
 
2343
@return DB_SUCCESS if operation successfully completed, else error
 
2344
code or DB_LOCK_WAIT */
2392
2345
static
2393
2346
ulint
2394
2347
row_ins(
2395
2348
/*====*/
2396
 
                                /* out: DB_SUCCESS if operation successfully
2397
 
                                completed, else error code or DB_LOCK_WAIT */
2398
 
        ins_node_t*     node,   /* in: row insert node */
2399
 
        que_thr_t*      thr)    /* in: query thread */
 
2349
        ins_node_t*     node,   /*!< in: row insert node */
 
2350
        que_thr_t*      thr)    /*!< in: query thread */
2400
2351
{
2401
2352
        ulint   err;
2402
2353
 
2442
2393
        return(DB_SUCCESS);
2443
2394
}
2444
2395
 
2445
 
/***************************************************************
 
2396
/***********************************************************//**
2446
2397
Inserts a row to a table. This is a high-level function used in SQL execution
2447
 
graphs. */
 
2398
graphs.
 
2399
@return query thread to run next or NULL */
2448
2400
UNIV_INTERN
2449
2401
que_thr_t*
2450
2402
row_ins_step(
2451
2403
/*=========*/
2452
 
                                /* out: query thread to run next or NULL */
2453
 
        que_thr_t*      thr)    /* in: query thread */
 
2404
        que_thr_t*      thr)    /*!< in: query thread */
2454
2405
{
2455
2406
        ins_node_t*     node;
2456
2407
        que_node_t*     parent;