~drizzle-trunk/drizzle/development

« back to all changes in this revision

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

  • Committer: Padraig O'Sullivan
  • Date: 2009-09-13 00:53:34 UTC
  • mto: (1126.9.2 captain-20090915-01)
  • mto: This revision was merged to the branch mainline in revision 1133.
  • Revision ID: osullivan.padraig@gmail.com-20090913005334-6wio2sbjugskfbm3
Added calls to the connection start/end dtrace probes.

Show diffs side-by-side

added added

removed removed

Lines of Context:
16
16
 
17
17
*****************************************************************************/
18
18
 
19
 
/**************************************************//**
20
 
@file row/row0ins.c
 
19
/******************************************************
21
20
Insert into a table
22
21
 
23
22
Created 4/20/1996 Heikki Tuuri
29
28
#include "row0ins.ic"
30
29
#endif
31
30
 
32
 
#include "ha_prototypes.h"
33
31
#include "dict0dict.h"
34
32
#include "dict0boot.h"
35
33
#include "trx0undo.h"
52
50
#define ROW_INS_NEXT    2
53
51
 
54
52
 
55
 
/*********************************************************************//**
56
 
Creates an insert node struct.
57
 
@return own: insert node struct */
 
53
/*************************************************************************
 
54
Creates an insert node struct. */
58
55
UNIV_INTERN
59
56
ins_node_t*
60
57
ins_node_create(
61
58
/*============*/
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 */
 
59
                                        /* out, own: insert node struct */
 
60
        ulint           ins_type,       /* in: INS_VALUES, ... */
 
61
        dict_table_t*   table,          /* in: table where to insert */
 
62
        mem_heap_t*     heap)           /* in: mem heap where created */
65
63
{
66
64
        ins_node_t*     node;
67
65
 
87
85
        return(node);
88
86
}
89
87
 
90
 
/***********************************************************//**
 
88
/***************************************************************
91
89
Creates an entry template for each index of a table. */
92
90
UNIV_INTERN
93
91
void
94
92
ins_node_create_entry_list(
95
93
/*=======================*/
96
 
        ins_node_t*     node)   /*!< in: row insert node */
 
94
        ins_node_t*     node)   /* in: row insert node */
97
95
{
98
96
        dict_index_t*   index;
99
97
        dtuple_t*       entry;
113
111
        }
114
112
}
115
113
 
116
 
/*****************************************************************//**
 
114
/*********************************************************************
117
115
Adds system field buffers to a row. */
118
116
static
119
117
void
120
118
row_ins_alloc_sys_fields(
121
119
/*=====================*/
122
 
        ins_node_t*     node)   /*!< in: insert node */
 
120
        ins_node_t*     node)   /* in: insert node */
123
121
{
124
122
        dtuple_t*               row;
125
123
        dict_table_t*           table;
168
166
        dfield_set_data(dfield, ptr, DATA_ROLL_PTR_LEN);
169
167
}
170
168
 
171
 
/*********************************************************************//**
 
169
/*************************************************************************
172
170
Sets a new row to insert for an INS_DIRECT node. This function is only used
173
171
if we have constructed the row separately, which is a rare case; this
174
172
function is quite slow. */
176
174
void
177
175
ins_node_set_new_row(
178
176
/*=================*/
179
 
        ins_node_t*     node,   /*!< in: insert node */
180
 
        dtuple_t*       row)    /*!< in: new row (or first row) for the node */
 
177
        ins_node_t*     node,   /* in: insert node */
 
178
        dtuple_t*       row)    /* in: new row (or first row) for the node */
181
179
{
182
180
        node->state = INS_NODE_SET_IX_LOCK;
183
181
        node->index = NULL;
201
199
        node->trx_id = ut_dulint_zero;
202
200
}
203
201
 
204
 
/*******************************************************************//**
 
202
/***********************************************************************
205
203
Does an insert operation by updating a delete-marked existing record
206
204
in the index. This situation can occur if the delete-marked record is
207
 
kept in the index for consistent reads.
208
 
@return DB_SUCCESS or error code */
 
205
kept in the index for consistent reads. */
209
206
static
210
207
ulint
211
208
row_ins_sec_index_entry_by_modify(
212
209
/*==============================*/
213
 
        ulint           mode,   /*!< in: BTR_MODIFY_LEAF or BTR_MODIFY_TREE,
 
210
                                /* out: DB_SUCCESS or error code */
 
211
        ulint           mode,   /* in: BTR_MODIFY_LEAF or BTR_MODIFY_TREE,
214
212
                                depending on whether mtr holds just a leaf
215
213
                                latch or also a tree latch */
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
 
214
        btr_cur_t*      cursor, /* in: B-tree cursor */
 
215
        const dtuple_t* entry,  /* in: index entry to insert */
 
216
        que_thr_t*      thr,    /* in: query thread */
 
217
        mtr_t*          mtr)    /* in: mtr; must be committed before
220
218
                                latching any further pages */
221
219
{
222
220
        big_rec_t*      dummy_big_rec;
272
270
        return(err);
273
271
}
274
272
 
275
 
/*******************************************************************//**
 
273
/***********************************************************************
276
274
Does an insert operation by delete unmarking and updating a delete marked
277
275
existing record in the index. This situation can occur if the delete marked
278
 
record is kept in the index for consistent reads.
279
 
@return DB_SUCCESS, DB_FAIL, or error code */
 
276
record is kept in the index for consistent reads. */
280
277
static
281
278
ulint
282
279
row_ins_clust_index_entry_by_modify(
283
280
/*================================*/
284
 
        ulint           mode,   /*!< in: BTR_MODIFY_LEAF or BTR_MODIFY_TREE,
 
281
                                /* out: DB_SUCCESS, DB_FAIL, or error code */
 
282
        ulint           mode,   /* in: BTR_MODIFY_LEAF or BTR_MODIFY_TREE,
285
283
                                depending on whether mtr holds just a leaf
286
284
                                latch or also a tree latch */
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
 
285
        btr_cur_t*      cursor, /* in: B-tree cursor */
 
286
        mem_heap_t**    heap,   /* in/out: pointer to memory heap, or NULL */
 
287
        big_rec_t**     big_rec,/* out: possible big rec vector of fields
290
288
                                which have to be stored externally by the
291
289
                                caller */
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
 
290
        const dtuple_t* entry,  /* in: index entry to insert */
 
291
        que_thr_t*      thr,    /* in: query thread */
 
292
        mtr_t*          mtr)    /* in: mtr; must be committed before
295
293
                                latching any further pages */
296
294
{
297
295
        rec_t*          rec;
344
342
        return(err);
345
343
}
346
344
 
347
 
/*********************************************************************//**
 
345
/*************************************************************************
348
346
Returns TRUE if in a cascaded update/delete an ancestor node of node
349
 
updates (not DELETE, but UPDATE) table.
350
 
@return TRUE if an ancestor updates table */
 
347
updates (not DELETE, but UPDATE) table. */
351
348
static
352
349
ibool
353
350
row_ins_cascade_ancestor_updates_table(
354
351
/*===================================*/
355
 
        que_node_t*     node,   /*!< in: node in a query graph */
356
 
        dict_table_t*   table)  /*!< in: table */
 
352
                                /* out: TRUE if an ancestor updates table */
 
353
        que_node_t*     node,   /* in: node in a query graph */
 
354
        dict_table_t*   table)  /* in: table */
357
355
{
358
356
        que_node_t*     parent;
359
357
        upd_node_t*     upd_node;
377
375
        return(FALSE);
378
376
}
379
377
 
380
 
/*********************************************************************//**
 
378
/*************************************************************************
381
379
Returns the number of ancestor UPDATE or DELETE nodes of a
382
 
cascaded update/delete node.
383
 
@return number of ancestors */
 
380
cascaded update/delete node. */
384
381
static
385
382
ulint
386
383
row_ins_cascade_n_ancestors(
387
384
/*========================*/
388
 
        que_node_t*     node)   /*!< in: node in a query graph */
 
385
                                /* out: number of ancestors */
 
386
        que_node_t*     node)   /* in: node in a query graph */
389
387
{
390
388
        que_node_t*     parent;
391
389
        ulint           n_ancestors = 0;
403
401
        return(n_ancestors);
404
402
}
405
403
 
406
 
/******************************************************************//**
 
404
/**********************************************************************
407
405
Calculates the update vector node->cascade->update for a child table in
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 */
 
406
a cascaded update. */
413
407
static
414
408
ulint
415
409
row_ins_cascade_calc_update_vec(
416
410
/*============================*/
417
 
        upd_node_t*     node,           /*!< in: update node of the parent
 
411
                                        /* out: number of fields in the
 
412
                                        calculated update vector; the value
 
413
                                        can also be 0 if no foreign key
 
414
                                        fields changed; the returned value
 
415
                                        is ULINT_UNDEFINED if the column
 
416
                                        type in the child table is too short
 
417
                                        to fit the new value in the parent
 
418
                                        table: that means the update fails */
 
419
        upd_node_t*     node,           /* in: update node of the parent
418
420
                                        table */
419
 
        dict_foreign_t* foreign,        /*!< in: foreign key constraint whose
 
421
        dict_foreign_t* foreign,        /* in: foreign key constraint whose
420
422
                                        type is != 0 */
421
 
        mem_heap_t*     heap)           /*!< in: memory heap to use as
 
423
        mem_heap_t*     heap)           /* in: memory heap to use as
422
424
                                        temporary storage */
423
425
{
424
426
        upd_node_t*     cascade         = node->cascade_node;
587
589
        return(n_fields_updated);
588
590
}
589
591
 
590
 
/*********************************************************************//**
 
592
/*************************************************************************
591
593
Set detailed error message associated with foreign key errors for
592
594
the given transaction. */
593
595
static
594
596
void
595
597
row_ins_set_detailed(
596
598
/*=================*/
597
 
        trx_t*          trx,            /*!< in: transaction */
598
 
        dict_foreign_t* foreign)        /*!< in: foreign key constraint */
 
599
        trx_t*          trx,            /* in: transaction */
 
600
        dict_foreign_t* foreign)        /* in: foreign key constraint */
599
601
{
600
602
        mutex_enter(&srv_misc_tmpfile_mutex);
601
603
        rewind(srv_misc_tmpfile);
613
615
        mutex_exit(&srv_misc_tmpfile_mutex);
614
616
}
615
617
 
616
 
/*********************************************************************//**
 
618
/*************************************************************************
617
619
Reports a foreign key error associated with an update or a delete of a
618
620
parent table index entry. */
619
621
static
620
622
void
621
623
row_ins_foreign_report_err(
622
624
/*=======================*/
623
 
        const char*     errstr,         /*!< in: error string from the viewpoint
 
625
        const char*     errstr,         /* in: error string from the viewpoint
624
626
                                        of the parent table */
625
 
        que_thr_t*      thr,            /*!< in: query thread whose run_node
 
627
        que_thr_t*      thr,            /* in: query thread whose run_node
626
628
                                        is an update node */
627
 
        dict_foreign_t* foreign,        /*!< in: foreign key constraint */
628
 
        const rec_t*    rec,            /*!< in: a matching index record in the
 
629
        dict_foreign_t* foreign,        /* in: foreign key constraint */
 
630
        const rec_t*    rec,            /* in: a matching index record in the
629
631
                                        child table */
630
 
        const dtuple_t* entry)          /*!< in: index entry in the parent
 
632
        const dtuple_t* entry)          /* in: index entry in the parent
631
633
                                        table */
632
634
{
633
635
        FILE*   ef      = dict_foreign_err_file;
669
671
        mutex_exit(&dict_foreign_err_mutex);
670
672
}
671
673
 
672
 
/*********************************************************************//**
 
674
/*************************************************************************
673
675
Reports a foreign key error to dict_foreign_err_file when we are trying
674
676
to add an index entry to a child table. Note that the adding may be the result
675
677
of an update, too. */
677
679
void
678
680
row_ins_foreign_report_add_err(
679
681
/*===========================*/
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:
 
682
        trx_t*          trx,            /* in: transaction */
 
683
        dict_foreign_t* foreign,        /* in: foreign key constraint */
 
684
        const rec_t*    rec,            /* in: a record in the parent table:
683
685
                                        it does not match entry because we
684
686
                                        have an error! */
685
 
        const dtuple_t* entry)          /*!< in: index entry to insert in the
 
687
        const dtuple_t* entry)          /* in: index entry to insert in the
686
688
                                        child table */
687
689
{
688
690
        FILE*   ef      = dict_foreign_err_file;
727
729
        mutex_exit(&dict_foreign_err_mutex);
728
730
}
729
731
 
730
 
/*********************************************************************//**
 
732
/*************************************************************************
731
733
Invalidate the query cache for the given table. */
732
734
static
733
735
void
734
736
row_ins_invalidate_query_cache(
735
737
/*===========================*/
736
 
        que_thr_t*      unused,         /*!< in: query thread whose run_node
 
738
        que_thr_t*      unused,         /* in: query thread whose run_node
737
739
                                        is an update node */
738
 
        const char*     name)           /*!< in: table name prefixed with
 
740
        const char*     name)           /* in: table name prefixed with
739
741
                                        database name and a '/' character */
740
742
{
741
743
        char*   buf;
753
755
        mem_free(buf);
754
756
}
755
757
 
756
 
/*********************************************************************//**
 
758
/*************************************************************************
757
759
Perform referential actions or checks when a parent row is deleted or updated
758
760
and the constraint had an ON DELETE or ON UPDATE condition which was not
759
 
RESTRICT.
760
 
@return DB_SUCCESS, DB_LOCK_WAIT, or error code */
 
761
RESTRICT. */
761
762
static
762
763
ulint
763
764
row_ins_foreign_check_on_constraint(
764
765
/*================================*/
765
 
        que_thr_t*      thr,            /*!< in: query thread whose run_node
 
766
                                        /* out: DB_SUCCESS, DB_LOCK_WAIT,
 
767
                                        or error code */
 
768
        que_thr_t*      thr,            /* in: query thread whose run_node
766
769
                                        is an update node */
767
 
        dict_foreign_t* foreign,        /*!< in: foreign key constraint whose
 
770
        dict_foreign_t* foreign,        /* in: foreign key constraint whose
768
771
                                        type is != 0 */
769
 
        btr_pcur_t*     pcur,           /*!< in: cursor placed on a matching
 
772
        btr_pcur_t*     pcur,           /* in: cursor placed on a matching
770
773
                                        index record in the child table */
771
 
        dtuple_t*       entry,          /*!< in: index entry in the parent
 
774
        dtuple_t*       entry,          /* in: index entry in the parent
772
775
                                        table */
773
 
        mtr_t*          mtr)            /*!< in: mtr holding the latch of pcur
 
776
        mtr_t*          mtr)            /* in: mtr holding the latch of pcur
774
777
                                        page */
775
778
{
776
779
        upd_node_t*     node;
1119
1122
        return(err);
1120
1123
}
1121
1124
 
1122
 
/*********************************************************************//**
 
1125
/*************************************************************************
1123
1126
Sets a shared lock on a record. Used in locking possible duplicate key
1124
 
records and also in checking foreign key constraints.
1125
 
@return DB_SUCCESS or error code */
 
1127
records and also in checking foreign key constraints. */
1126
1128
static
1127
1129
ulint
1128
1130
row_ins_set_shared_rec_lock(
1129
1131
/*========================*/
1130
 
        ulint                   type,   /*!< in: LOCK_ORDINARY, LOCK_GAP, or
 
1132
                                        /* out: DB_SUCCESS or error code */
 
1133
        ulint                   type,   /* in: LOCK_ORDINARY, LOCK_GAP, or
1131
1134
                                        LOCK_REC_NOT_GAP type lock */
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 */
 
1135
        const buf_block_t*      block,  /* in: buffer block of rec */
 
1136
        const rec_t*            rec,    /* in: record */
 
1137
        dict_index_t*           index,  /* in: index */
 
1138
        const ulint*            offsets,/* in: rec_get_offsets(rec, index) */
 
1139
        que_thr_t*              thr)    /* in: query thread */
1137
1140
{
1138
1141
        ulint   err;
1139
1142
 
1150
1153
        return(err);
1151
1154
}
1152
1155
 
1153
 
/*********************************************************************//**
 
1156
#ifndef UNIV_HOTBACKUP
 
1157
/*************************************************************************
1154
1158
Sets a exclusive lock on a record. Used in locking possible duplicate key
1155
 
records
1156
 
@return DB_SUCCESS or error code */
 
1159
records */
1157
1160
static
1158
1161
ulint
1159
1162
row_ins_set_exclusive_rec_lock(
1160
1163
/*===========================*/
1161
 
        ulint                   type,   /*!< in: LOCK_ORDINARY, LOCK_GAP, or
 
1164
                                        /* out: DB_SUCCESS or error code */
 
1165
        ulint                   type,   /* in: LOCK_ORDINARY, LOCK_GAP, or
1162
1166
                                        LOCK_REC_NOT_GAP type lock */
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 */
 
1167
        const buf_block_t*      block,  /* in: buffer block of rec */
 
1168
        const rec_t*            rec,    /* in: record */
 
1169
        dict_index_t*           index,  /* in: index */
 
1170
        const ulint*            offsets,/* in: rec_get_offsets(rec, index) */
 
1171
        que_thr_t*              thr)    /* in: query thread */
1168
1172
{
1169
1173
        ulint   err;
1170
1174
 
1180
1184
 
1181
1185
        return(err);
1182
1186
}
 
1187
#endif /* !UNIV_HOTBACKUP */
1183
1188
 
1184
 
/***************************************************************//**
 
1189
/*******************************************************************
1185
1190
Checks if foreign key constraint fails for an index entry. Sets shared locks
1186
1191
which lock either the success or the failure of the constraint. NOTE that
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 */
 
1192
the caller must have a shared latch on dict_operation_lock. */
1189
1193
UNIV_INTERN
1190
1194
ulint
1191
1195
row_ins_check_foreign_constraint(
1192
1196
/*=============================*/
1193
 
        ibool           check_ref,/*!< in: TRUE if we want to check that
 
1197
                                /* out: DB_SUCCESS,
 
1198
                                DB_NO_REFERENCED_ROW,
 
1199
                                or DB_ROW_IS_REFERENCED */
 
1200
        ibool           check_ref,/* in: TRUE if we want to check that
1194
1201
                                the referenced table is ok, FALSE if we
1195
1202
                                want to to check the foreign key table */
1196
 
        dict_foreign_t* foreign,/*!< in: foreign constraint; NOTE that the
 
1203
        dict_foreign_t* foreign,/* in: foreign constraint; NOTE that the
1197
1204
                                tables mentioned in it must be in the
1198
1205
                                dictionary cache if they exist at all */
1199
 
        dict_table_t*   table,  /*!< in: if check_ref is TRUE, then the foreign
 
1206
        dict_table_t*   table,  /* in: if check_ref is TRUE, then the foreign
1200
1207
                                table, else the referenced table */
1201
 
        dtuple_t*       entry,  /*!< in: index entry for index */
1202
 
        que_thr_t*      thr)    /*!< in: query thread */
 
1208
        dtuple_t*       entry,  /* in: index entry for index */
 
1209
        que_thr_t*      thr)    /* in: query thread */
1203
1210
{
1204
1211
        upd_node_t*     upd_node;
1205
1212
        dict_table_t*   check_table;
1503
1510
        return(err);
1504
1511
}
1505
1512
 
1506
 
/***************************************************************//**
 
1513
/*******************************************************************
1507
1514
Checks if foreign key constraints fail for an index entry. If index
1508
1515
is not mentioned in any constraint, this function does nothing,
1509
1516
Otherwise does searches to the indexes of referenced tables and
1510
1517
sets shared locks which lock either the success or the failure of
1511
 
a constraint.
1512
 
@return DB_SUCCESS or error code */
 
1518
a constraint. */
1513
1519
static
1514
1520
ulint
1515
1521
row_ins_check_foreign_constraints(
1516
1522
/*==============================*/
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 */
 
1523
                                /* out: DB_SUCCESS or error code */
 
1524
        dict_table_t*   table,  /* in: table */
 
1525
        dict_index_t*   index,  /* in: index */
 
1526
        dtuple_t*       entry,  /* in: index entry for index */
 
1527
        que_thr_t*      thr)    /* in: query thread */
1521
1528
{
1522
1529
        dict_foreign_t* foreign;
1523
1530
        ulint           err;
1585
1592
        return(DB_SUCCESS);
1586
1593
}
1587
1594
 
1588
 
/***************************************************************//**
 
1595
#ifndef UNIV_HOTBACKUP
 
1596
/*******************************************************************
1589
1597
Checks if a unique key violation to rec would occur at the index entry
1590
 
insert.
1591
 
@return TRUE if error */
 
1598
insert. */
1592
1599
static
1593
1600
ibool
1594
1601
row_ins_dupl_error_with_rec(
1595
1602
/*========================*/
1596
 
        const rec_t*    rec,    /*!< in: user record; NOTE that we assume
 
1603
                                /* out: TRUE if error */
 
1604
        const rec_t*    rec,    /* in: user record; NOTE that we assume
1597
1605
                                that the caller already has a record lock on
1598
1606
                                the record! */
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) */
 
1607
        const dtuple_t* entry,  /* in: entry to insert */
 
1608
        dict_index_t*   index,  /* in: index */
 
1609
        const ulint*    offsets)/* in: rec_get_offsets(rec, index) */
1602
1610
{
1603
1611
        ulint   matched_fields;
1604
1612
        ulint   matched_bytes;
1636
1644
 
1637
1645
        return(!rec_get_deleted_flag(rec, rec_offs_comp(offsets)));
1638
1646
}
 
1647
#endif /* !UNIV_HOTBACKUP */
1639
1648
 
1640
 
/***************************************************************//**
 
1649
/*******************************************************************
1641
1650
Scans a unique non-clustered index at a given index entry to determine
1642
1651
whether a uniqueness violation has occurred for the key value of the entry.
1643
 
Set shared locks on possible duplicate records.
1644
 
@return DB_SUCCESS, DB_DUPLICATE_KEY, or DB_LOCK_WAIT */
 
1652
Set shared locks on possible duplicate records. */
1645
1653
static
1646
1654
ulint
1647
1655
row_ins_scan_sec_index_for_duplicate(
1648
1656
/*=================================*/
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 */
 
1657
                                /* out: DB_SUCCESS, DB_DUPLICATE_KEY, or
 
1658
                                DB_LOCK_WAIT */
 
1659
        dict_index_t*   index,  /* in: non-clustered unique index */
 
1660
        dtuple_t*       entry,  /* in: index entry */
 
1661
        que_thr_t*      thr)    /* in: query thread */
1652
1662
{
 
1663
#ifndef UNIV_HOTBACKUP
1653
1664
        ulint           n_unique;
1654
1665
        ulint           i;
1655
1666
        int             cmp;
1759
1770
        dtuple_set_n_fields_cmp(entry, n_fields_cmp);
1760
1771
 
1761
1772
        return(err);
 
1773
#else /* UNIV_HOTBACKUP */
 
1774
        /* This function depends on MySQL code that is not included in
 
1775
        InnoDB Hot Backup builds.  Besides, this function should never
 
1776
        be called in InnoDB Hot Backup. */
 
1777
        ut_error;
 
1778
        return(DB_FAIL);
 
1779
#endif /* UNIV_HOTBACKUP */
1762
1780
}
1763
1781
 
1764
 
/***************************************************************//**
 
1782
/*******************************************************************
1765
1783
Checks if a unique key violation error would occur at an index entry
1766
1784
insert. Sets shared locks on possible duplicate records. Works only
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 */
 
1785
for a clustered index! */
1771
1786
static
1772
1787
ulint
1773
1788
row_ins_duplicate_error_in_clust(
1774
1789
/*=============================*/
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 */
 
1790
                                /* out: DB_SUCCESS if no error,
 
1791
                                DB_DUPLICATE_KEY if error, DB_LOCK_WAIT if we
 
1792
                                have to wait for a lock on a possible
 
1793
                                duplicate record */
 
1794
        btr_cur_t*      cursor, /* in: B-tree cursor */
 
1795
        dtuple_t*       entry,  /* in: entry to insert */
 
1796
        que_thr_t*      thr,    /* in: query thread */
 
1797
        mtr_t*          mtr)    /* in: mtr */
1779
1798
{
 
1799
#ifndef UNIV_HOTBACKUP
1780
1800
        ulint   err;
1781
1801
        rec_t*  rec;
1782
1802
        ulint   n_unique;
1900
1920
                mem_heap_free(heap);
1901
1921
        }
1902
1922
        return(err);
 
1923
#else /* UNIV_HOTBACKUP */
 
1924
        /* This function depends on MySQL code that is not included in
 
1925
        InnoDB Hot Backup builds.  Besides, this function should never
 
1926
        be called in InnoDB Hot Backup. */
 
1927
        ut_error;
 
1928
        return(DB_FAIL);
 
1929
#endif /* UNIV_HOTBACKUP */
1903
1930
}
1904
1931
 
1905
 
/***************************************************************//**
 
1932
/*******************************************************************
1906
1933
Checks if an index entry has long enough common prefix with an existing
1907
1934
record so that the intended insert of the entry must be changed to a modify of
1908
1935
the existing record. In the case of a clustered index, the prefix must be
1909
1936
n_unique fields long, and in the case of a secondary index, all fields must be
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 */
 
1937
equal. */
1914
1938
UNIV_INLINE
1915
1939
ulint
1916
1940
row_ins_must_modify(
1917
1941
/*================*/
1918
 
        btr_cur_t*      cursor) /*!< in: B-tree cursor */
 
1942
                                /* out: 0 if no update, ROW_INS_PREV if
 
1943
                                previous should be updated; currently we
 
1944
                                do the search so that only the low_match
 
1945
                                record can match enough to the search tuple,
 
1946
                                not the next record */
 
1947
        btr_cur_t*      cursor) /* in: B-tree cursor */
1919
1948
{
1920
1949
        ulint   enough_match;
1921
1950
        rec_t*  rec;
1942
1971
        return(0);
1943
1972
}
1944
1973
 
1945
 
/***************************************************************//**
 
1974
/*******************************************************************
1946
1975
Tries to insert an index entry to an index. If the index is clustered
1947
1976
and a record with the same unique key is found, the other record is
1948
1977
necessarily marked deleted by a committed transaction, or a unique key
1950
1979
existing record, and we must write an undo log record on the delete
1951
1980
marked record. If the index is secondary, and a record with exactly the
1952
1981
same fields is found, the other record is necessarily marked deleted.
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 */
 
1982
It is then unmarked. Otherwise, the entry is just inserted to the index. */
1956
1983
static
1957
1984
ulint
1958
1985
row_ins_index_entry_low(
1959
1986
/*====================*/
1960
 
        ulint           mode,   /*!< in: BTR_MODIFY_LEAF or BTR_MODIFY_TREE,
 
1987
                                /* out: DB_SUCCESS, DB_LOCK_WAIT, DB_FAIL
 
1988
                                if pessimistic retry needed, or error code */
 
1989
        ulint           mode,   /* in: BTR_MODIFY_LEAF or BTR_MODIFY_TREE,
1961
1990
                                depending on whether we wish optimistic or
1962
1991
                                pessimistic descent down the index tree */
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 */
 
1992
        dict_index_t*   index,  /* in: index */
 
1993
        dtuple_t*       entry,  /* in: index entry to insert */
 
1994
        ulint           n_ext,  /* in: number of externally stored columns */
 
1995
        que_thr_t*      thr)    /* in: query thread */
1967
1996
{
1968
1997
        btr_cur_t       cursor;
1969
1998
        ulint           ignore_sec_unique       = 0;
2129
2158
        return(err);
2130
2159
}
2131
2160
 
2132
 
/***************************************************************//**
 
2161
/*******************************************************************
2133
2162
Inserts an index entry to index. Tries first optimistic, then pessimistic
2134
2163
descent down the tree. If the entry matches enough to a delete marked record,
2135
2164
performs the insert by updating or delete unmarking the delete marked
2136
 
record.
2137
 
@return DB_SUCCESS, DB_LOCK_WAIT, DB_DUPLICATE_KEY, or some other error code */
 
2165
record. */
2138
2166
UNIV_INTERN
2139
2167
ulint
2140
2168
row_ins_index_entry(
2141
2169
/*================*/
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 */
 
2170
                                /* out: DB_SUCCESS, DB_LOCK_WAIT,
 
2171
                                DB_DUPLICATE_KEY, or some other error code */
 
2172
        dict_index_t*   index,  /* in: index */
 
2173
        dtuple_t*       entry,  /* in: index entry to insert */
 
2174
        ulint           n_ext,  /* in: number of externally stored columns */
 
2175
        ibool           foreign,/* in: TRUE=check foreign key constraints */
 
2176
        que_thr_t*      thr)    /* in: query thread */
2147
2177
{
2148
2178
        ulint   err;
2149
2179
 
2172
2202
        return(err);
2173
2203
}
2174
2204
 
2175
 
/***********************************************************//**
 
2205
/***************************************************************
2176
2206
Sets the values of the dtuple fields in entry from the values of appropriate
2177
2207
columns in row. */
2178
2208
static
2179
2209
void
2180
2210
row_ins_index_entry_set_vals(
2181
2211
/*=========================*/
2182
 
        dict_index_t*   index,  /*!< in: index */
2183
 
        dtuple_t*       entry,  /*!< in: index entry to make */
2184
 
        const dtuple_t* row)    /*!< in: row */
 
2212
        dict_index_t*   index,  /* in: index */
 
2213
        dtuple_t*       entry,  /* in: index entry to make */
 
2214
        const dtuple_t* row)    /* in: row */
2185
2215
{
2186
2216
        ulint   n_fields;
2187
2217
        ulint   i;
2224
2254
        }
2225
2255
}
2226
2256
 
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 */
 
2257
/***************************************************************
 
2258
Inserts a single index entry to the table. */
2231
2259
static
2232
2260
ulint
2233
2261
row_ins_index_entry_step(
2234
2262
/*=====================*/
2235
 
        ins_node_t*     node,   /*!< in: row insert node */
2236
 
        que_thr_t*      thr)    /*!< in: query thread */
 
2263
                                /* out: DB_SUCCESS if operation successfully
 
2264
                                completed, else error code or DB_LOCK_WAIT */
 
2265
        ins_node_t*     node,   /* in: row insert node */
 
2266
        que_thr_t*      thr)    /* in: query thread */
2237
2267
{
2238
2268
        ulint   err;
2239
2269
 
2248
2278
        return(err);
2249
2279
}
2250
2280
 
2251
 
/***********************************************************//**
 
2281
/***************************************************************
2252
2282
Allocates a row id for row and inits the node->index field. */
2253
2283
UNIV_INLINE
2254
2284
void
2255
2285
row_ins_alloc_row_id_step(
2256
2286
/*======================*/
2257
 
        ins_node_t*     node)   /*!< in: row insert node */
 
2287
        ins_node_t*     node)   /* in: row insert node */
2258
2288
{
2259
2289
        dulint  row_id;
2260
2290
 
2274
2304
        dict_sys_write_row_id(node->row_id_buf, row_id);
2275
2305
}
2276
2306
 
2277
 
/***********************************************************//**
 
2307
/***************************************************************
2278
2308
Gets a row to insert from the values list. */
2279
2309
UNIV_INLINE
2280
2310
void
2281
2311
row_ins_get_row_from_values(
2282
2312
/*========================*/
2283
 
        ins_node_t*     node)   /*!< in: row insert node */
 
2313
        ins_node_t*     node)   /* in: row insert node */
2284
2314
{
2285
2315
        que_node_t*     list_node;
2286
2316
        dfield_t*       dfield;
2307
2337
        }
2308
2338
}
2309
2339
 
2310
 
/***********************************************************//**
 
2340
/***************************************************************
2311
2341
Gets a row to insert from the select list. */
2312
2342
UNIV_INLINE
2313
2343
void
2314
2344
row_ins_get_row_from_select(
2315
2345
/*========================*/
2316
 
        ins_node_t*     node)   /*!< in: row insert node */
 
2346
        ins_node_t*     node)   /* in: row insert node */
2317
2347
{
2318
2348
        que_node_t*     list_node;
2319
2349
        dfield_t*       dfield;
2338
2368
        }
2339
2369
}
2340
2370
 
2341
 
/***********************************************************//**
2342
 
Inserts a row to a table.
2343
 
@return DB_SUCCESS if operation successfully completed, else error
2344
 
code or DB_LOCK_WAIT */
 
2371
/***************************************************************
 
2372
Inserts a row to a table. */
2345
2373
static
2346
2374
ulint
2347
2375
row_ins(
2348
2376
/*====*/
2349
 
        ins_node_t*     node,   /*!< in: row insert node */
2350
 
        que_thr_t*      thr)    /*!< in: query thread */
 
2377
                                /* out: DB_SUCCESS if operation successfully
 
2378
                                completed, else error code or DB_LOCK_WAIT */
 
2379
        ins_node_t*     node,   /* in: row insert node */
 
2380
        que_thr_t*      thr)    /* in: query thread */
2351
2381
{
2352
2382
        ulint   err;
2353
2383
 
2393
2423
        return(DB_SUCCESS);
2394
2424
}
2395
2425
 
2396
 
/***********************************************************//**
 
2426
/***************************************************************
2397
2427
Inserts a row to a table. This is a high-level function used in SQL execution
2398
 
graphs.
2399
 
@return query thread to run next or NULL */
 
2428
graphs. */
2400
2429
UNIV_INTERN
2401
2430
que_thr_t*
2402
2431
row_ins_step(
2403
2432
/*=========*/
2404
 
        que_thr_t*      thr)    /*!< in: query thread */
 
2433
                                /* out: query thread to run next or NULL */
 
2434
        que_thr_t*      thr)    /* in: query thread */
2405
2435
{
2406
2436
        ins_node_t*     node;
2407
2437
        que_node_t*     parent;