summaryrefslogtreecommitdiff
path: root/storage/innobase/row/row0ins.c
diff options
context:
space:
mode:
Diffstat (limited to 'storage/innobase/row/row0ins.c')
-rw-r--r--storage/innobase/row/row0ins.c153
1 files changed, 84 insertions, 69 deletions
diff --git a/storage/innobase/row/row0ins.c b/storage/innobase/row/row0ins.c
index fe51fce82c4..c882a065cd1 100644
--- a/storage/innobase/row/row0ins.c
+++ b/storage/innobase/row/row0ins.c
@@ -1,6 +1,6 @@
/*****************************************************************************
-Copyright (c) 1996, 2009, Innobase Oy. All Rights Reserved.
+Copyright (c) 1996, 2010, Innobase Oy. All Rights Reserved.
This program is free software; you can redistribute it and/or modify it under
the terms of the GNU General Public License as published by the Free Software
@@ -1121,9 +1121,9 @@ nonstandard_exit_func:
/*********************************************************************//**
Sets a shared lock on a record. Used in locking possible duplicate key
records and also in checking foreign key constraints.
-@return DB_SUCCESS or error code */
+@return DB_SUCCESS, DB_SUCCESS_LOCKED_REC, or error code */
static
-ulint
+enum db_err
row_ins_set_shared_rec_lock(
/*========================*/
ulint type, /*!< in: LOCK_ORDINARY, LOCK_GAP, or
@@ -1134,7 +1134,7 @@ row_ins_set_shared_rec_lock(
const ulint* offsets,/*!< in: rec_get_offsets(rec, index) */
que_thr_t* thr) /*!< in: query thread */
{
- ulint err;
+ enum db_err err;
ut_ad(rec_offs_validate(rec, index, offsets));
@@ -1152,9 +1152,9 @@ row_ins_set_shared_rec_lock(
/*********************************************************************//**
Sets a exclusive lock on a record. Used in locking possible duplicate key
records
-@return DB_SUCCESS or error code */
+@return DB_SUCCESS, DB_SUCCESS_LOCKED_REC, or error code */
static
-ulint
+enum db_err
row_ins_set_exclusive_rec_lock(
/*===========================*/
ulint type, /*!< in: LOCK_ORDINARY, LOCK_GAP, or
@@ -1165,7 +1165,7 @@ row_ins_set_exclusive_rec_lock(
const ulint* offsets,/*!< in: rec_get_offsets(rec, index) */
que_thr_t* thr) /*!< in: query thread */
{
- ulint err;
+ enum db_err err;
ut_ad(rec_offs_validate(rec, index, offsets));
@@ -1205,7 +1205,6 @@ row_ins_check_foreign_constraint(
dict_index_t* check_index;
ulint n_fields_cmp;
btr_pcur_t pcur;
- ibool moved;
int cmp;
ulint err;
ulint i;
@@ -1336,13 +1335,13 @@ run_again:
/* Scan index records and check if there is a matching record */
- for (;;) {
+ do {
const rec_t* rec = btr_pcur_get_rec(&pcur);
const buf_block_t* block = btr_pcur_get_block(&pcur);
if (page_rec_is_infimum(rec)) {
- goto next_rec;
+ continue;
}
offsets = rec_get_offsets(rec, check_index,
@@ -1353,12 +1352,13 @@ run_again:
err = row_ins_set_shared_rec_lock(LOCK_ORDINARY, block,
rec, check_index,
offsets, thr);
- if (err != DB_SUCCESS) {
-
- break;
+ switch (err) {
+ case DB_SUCCESS_LOCKED_REC:
+ case DB_SUCCESS:
+ continue;
+ default:
+ goto end_scan;
}
-
- goto next_rec;
}
cmp = cmp_dtuple_rec(entry, rec, offsets);
@@ -1369,9 +1369,12 @@ run_again:
err = row_ins_set_shared_rec_lock(
LOCK_ORDINARY, block,
rec, check_index, offsets, thr);
- if (err != DB_SUCCESS) {
-
+ switch (err) {
+ case DB_SUCCESS_LOCKED_REC:
+ case DB_SUCCESS:
break;
+ default:
+ goto end_scan;
}
} else {
/* Found a matching record. Lock only
@@ -1382,15 +1385,18 @@ run_again:
LOCK_REC_NOT_GAP, block,
rec, check_index, offsets, thr);
- if (err != DB_SUCCESS) {
-
+ switch (err) {
+ case DB_SUCCESS_LOCKED_REC:
+ case DB_SUCCESS:
break;
+ default:
+ goto end_scan;
}
if (check_ref) {
err = DB_SUCCESS;
- break;
+ goto end_scan;
} else if (foreign->type != 0) {
/* There is an ON UPDATE or ON DELETE
condition: check them in a separate
@@ -1416,7 +1422,7 @@ run_again:
err = DB_FOREIGN_DUPLICATE_KEY;
}
- break;
+ goto end_scan;
}
/* row_ins_foreign_check_on_constraint
@@ -1429,49 +1435,41 @@ run_again:
thr, foreign, rec, entry);
err = DB_ROW_IS_REFERENCED;
- break;
+ goto end_scan;
}
}
- }
+ } else {
+ ut_a(cmp < 0);
- if (cmp < 0) {
err = row_ins_set_shared_rec_lock(
LOCK_GAP, block,
rec, check_index, offsets, thr);
- if (err != DB_SUCCESS) {
-
- break;
- }
- if (check_ref) {
- err = DB_NO_REFERENCED_ROW;
- row_ins_foreign_report_add_err(
- trx, foreign, rec, entry);
- } else {
- err = DB_SUCCESS;
+ switch (err) {
+ case DB_SUCCESS_LOCKED_REC:
+ case DB_SUCCESS:
+ if (check_ref) {
+ err = DB_NO_REFERENCED_ROW;
+ row_ins_foreign_report_add_err(
+ trx, foreign, rec, entry);
+ } else {
+ err = DB_SUCCESS;
+ }
}
- break;
+ goto end_scan;
}
+ } while (btr_pcur_move_to_next(&pcur, &mtr));
- ut_a(cmp == 0);
-next_rec:
- moved = btr_pcur_move_to_next(&pcur, &mtr);
-
- if (!moved) {
- if (check_ref) {
- rec = btr_pcur_get_rec(&pcur);
- row_ins_foreign_report_add_err(
- trx, foreign, rec, entry);
- err = DB_NO_REFERENCED_ROW;
- } else {
- err = DB_SUCCESS;
- }
-
- break;
- }
+ if (check_ref) {
+ row_ins_foreign_report_add_err(
+ trx, foreign, btr_pcur_get_rec(&pcur), entry);
+ err = DB_NO_REFERENCED_ROW;
+ } else {
+ err = DB_SUCCESS;
}
+end_scan:
btr_pcur_close(&pcur);
mtr_commit(&mtr);
@@ -1719,9 +1717,13 @@ row_ins_scan_sec_index_for_duplicate(
rec, index, offsets, thr);
}
- if (err != DB_SUCCESS) {
-
+ switch (err) {
+ case DB_SUCCESS_LOCKED_REC:
+ err = DB_SUCCESS;
+ case DB_SUCCESS:
break;
+ default:
+ goto end_scan;
}
if (page_rec_is_supremum(rec)) {
@@ -1738,17 +1740,15 @@ row_ins_scan_sec_index_for_duplicate(
thr_get_trx(thr)->error_info = index;
- break;
+ goto end_scan;
}
+ } else {
+ ut_a(cmp < 0);
+ goto end_scan;
}
-
- if (cmp < 0) {
- break;
- }
-
- ut_a(cmp == 0);
} while (btr_pcur_move_to_next(&pcur, &mtr));
+end_scan:
if (UNIV_LIKELY_NULL(heap)) {
mem_heap_free(heap);
}
@@ -1837,7 +1837,11 @@ row_ins_duplicate_error_in_clust(
cursor->index, offsets, thr);
}
- if (err != DB_SUCCESS) {
+ switch (err) {
+ case DB_SUCCESS_LOCKED_REC:
+ case DB_SUCCESS:
+ break;
+ default:
goto func_exit;
}
@@ -1877,7 +1881,11 @@ row_ins_duplicate_error_in_clust(
rec, cursor->index, offsets, thr);
}
- if (err != DB_SUCCESS) {
+ switch (err) {
+ case DB_SUCCESS_LOCKED_REC:
+ case DB_SUCCESS:
+ break;
+ default:
goto func_exit;
}
@@ -1965,7 +1973,7 @@ row_ins_index_entry_low(
que_thr_t* thr) /*!< in: query thread */
{
btr_cur_t cursor;
- ulint ignore_sec_unique = 0;
+ ulint search_mode;
ulint modify = 0; /* remove warning */
rec_t* insert_rec;
rec_t* rec;
@@ -1985,18 +1993,23 @@ row_ins_index_entry_low(
the function will return in both low_match and up_match of the
cursor sensible values */
- if (!(thr_get_trx(thr)->check_unique_secondary)) {
- ignore_sec_unique = BTR_IGNORE_SEC_UNIQUE;
+ if (dict_index_is_clust(index)) {
+ search_mode = mode;
+ } else if (!(thr_get_trx(thr)->check_unique_secondary)) {
+ search_mode = mode | BTR_INSERT | BTR_IGNORE_SEC_UNIQUE;
+ } else {
+ search_mode = mode | BTR_INSERT;
}
btr_cur_search_to_nth_level(index, 0, entry, PAGE_CUR_LE,
- mode | BTR_INSERT | ignore_sec_unique,
- &cursor, 0, &mtr);
+ search_mode,
+ &cursor, 0, __FILE__, __LINE__, &mtr);
if (cursor.flag == BTR_CUR_INSERT_TO_IBUF) {
/* The insertion was made to the insert buffer already during
the search: we are done */
+ ut_ad(search_mode & BTR_INSERT);
err = DB_SUCCESS;
goto function_exit;
@@ -2049,7 +2062,8 @@ row_ins_index_entry_low(
btr_cur_search_to_nth_level(index, 0, entry,
PAGE_CUR_LE,
mode | BTR_INSERT,
- &cursor, 0, &mtr);
+ &cursor, 0,
+ __FILE__, __LINE__, &mtr);
}
}
@@ -2104,7 +2118,8 @@ function_exit:
mtr_start(&mtr);
btr_cur_search_to_nth_level(index, 0, entry, PAGE_CUR_LE,
- BTR_MODIFY_TREE, &cursor, 0, &mtr);
+ BTR_MODIFY_TREE, &cursor, 0,
+ __FILE__, __LINE__, &mtr);
rec = btr_cur_get_rec(&cursor);
offsets = rec_get_offsets(rec, index, NULL,
ULINT_UNDEFINED, &heap);