~drizzle-trunk/drizzle/development

« back to all changes in this revision

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

Merge Stewart - InnoDB 1.1.1

Show diffs side-by-side

added added

removed removed

Lines of Context:
1122
1122
/*********************************************************************//**
1123
1123
Sets a shared lock on a record. Used in locking possible duplicate key
1124
1124
records and also in checking foreign key constraints.
1125
 
@return DB_SUCCESS or error code */
 
1125
@return DB_SUCCESS, DB_SUCCESS_LOCKED_REC, or error code */
1126
1126
static
1127
 
ulint
 
1127
enum db_err
1128
1128
row_ins_set_shared_rec_lock(
1129
1129
/*========================*/
1130
1130
        ulint                   type,   /*!< in: LOCK_ORDINARY, LOCK_GAP, or
1135
1135
        const ulint*            offsets,/*!< in: rec_get_offsets(rec, index) */
1136
1136
        que_thr_t*              thr)    /*!< in: query thread */
1137
1137
{
1138
 
        ulint   err;
 
1138
        enum db_err     err;
1139
1139
 
1140
1140
        ut_ad(rec_offs_validate(rec, index, offsets));
1141
1141
 
1153
1153
/*********************************************************************//**
1154
1154
Sets a exclusive lock on a record. Used in locking possible duplicate key
1155
1155
records
1156
 
@return DB_SUCCESS or error code */
 
1156
@return DB_SUCCESS, DB_SUCCESS_LOCKED_REC, or error code */
1157
1157
static
1158
 
ulint
 
1158
enum db_err
1159
1159
row_ins_set_exclusive_rec_lock(
1160
1160
/*===========================*/
1161
1161
        ulint                   type,   /*!< in: LOCK_ORDINARY, LOCK_GAP, or
1166
1166
        const ulint*            offsets,/*!< in: rec_get_offsets(rec, index) */
1167
1167
        que_thr_t*              thr)    /*!< in: query thread */
1168
1168
{
1169
 
        ulint   err;
 
1169
        enum db_err     err;
1170
1170
 
1171
1171
        ut_ad(rec_offs_validate(rec, index, offsets));
1172
1172
 
1206
1206
        dict_index_t*   check_index;
1207
1207
        ulint           n_fields_cmp;
1208
1208
        btr_pcur_t      pcur;
1209
 
        ibool           moved;
1210
1209
        int             cmp;
1211
1210
        ulint           err;
1212
1211
        ulint           i;
1337
1336
 
1338
1337
        /* Scan index records and check if there is a matching record */
1339
1338
 
1340
 
        for (;;) {
 
1339
        do {
1341
1340
                const rec_t*            rec = btr_pcur_get_rec(&pcur);
1342
1341
                const buf_block_t*      block = btr_pcur_get_block(&pcur);
1343
1342
 
1344
1343
                if (page_rec_is_infimum(rec)) {
1345
1344
 
1346
 
                        goto next_rec;
 
1345
                        continue;
1347
1346
                }
1348
1347
 
1349
1348
                offsets = rec_get_offsets(rec, check_index,
1354
1353
                        err = row_ins_set_shared_rec_lock(LOCK_ORDINARY, block,
1355
1354
                                                          rec, check_index,
1356
1355
                                                          offsets, thr);
1357
 
                        if (err != DB_SUCCESS) {
1358
 
 
1359
 
                                break;
 
1356
                        switch (err) {
 
1357
                        case DB_SUCCESS_LOCKED_REC:
 
1358
                        case DB_SUCCESS:
 
1359
                                continue;
 
1360
                        default:
 
1361
                                goto end_scan;
1360
1362
                        }
1361
 
 
1362
 
                        goto next_rec;
1363
1363
                }
1364
1364
 
1365
1365
                cmp = cmp_dtuple_rec(entry, rec, offsets);
1370
1370
                                err = row_ins_set_shared_rec_lock(
1371
1371
                                        LOCK_ORDINARY, block,
1372
1372
                                        rec, check_index, offsets, thr);
1373
 
                                if (err != DB_SUCCESS) {
1374
 
 
 
1373
                                switch (err) {
 
1374
                                case DB_SUCCESS_LOCKED_REC:
 
1375
                                case DB_SUCCESS:
1375
1376
                                        break;
 
1377
                                default:
 
1378
                                        goto end_scan;
1376
1379
                                }
1377
1380
                        } else {
1378
1381
                                /* Found a matching record. Lock only
1383
1386
                                        LOCK_REC_NOT_GAP, block,
1384
1387
                                        rec, check_index, offsets, thr);
1385
1388
 
1386
 
                                if (err != DB_SUCCESS) {
1387
 
 
 
1389
                                switch (err) {
 
1390
                                case DB_SUCCESS_LOCKED_REC:
 
1391
                                case DB_SUCCESS:
1388
1392
                                        break;
 
1393
                                default:
 
1394
                                        goto end_scan;
1389
1395
                                }
1390
1396
 
1391
1397
                                if (check_ref) {
1392
1398
                                        err = DB_SUCCESS;
1393
1399
 
1394
 
                                        break;
 
1400
                                        goto end_scan;
1395
1401
                                } else if (foreign->type != 0) {
1396
1402
                                        /* There is an ON UPDATE or ON DELETE
1397
1403
                                        condition: check them in a separate
1417
1423
                                                        err = DB_FOREIGN_DUPLICATE_KEY;
1418
1424
                                                }
1419
1425
 
1420
 
                                                break;
 
1426
                                                goto end_scan;
1421
1427
                                        }
1422
1428
 
1423
1429
                                        /* row_ins_foreign_check_on_constraint
1430
1436
                                                thr, foreign, rec, entry);
1431
1437
 
1432
1438
                                        err = DB_ROW_IS_REFERENCED;
1433
 
                                        break;
 
1439
                                        goto end_scan;
1434
1440
                                }
1435
1441
                        }
1436
 
                }
 
1442
                } else {
 
1443
                        ut_a(cmp < 0);
1437
1444
 
1438
 
                if (cmp < 0) {
1439
1445
                        err = row_ins_set_shared_rec_lock(
1440
1446
                                LOCK_GAP, block,
1441
1447
                                rec, check_index, offsets, thr);
1442
 
                        if (err != DB_SUCCESS) {
1443
 
 
1444
 
                                break;
1445
 
                        }
1446
 
 
1447
 
                        if (check_ref) {
1448
 
                                err = DB_NO_REFERENCED_ROW;
1449
 
                                row_ins_foreign_report_add_err(
1450
 
                                        trx, foreign, rec, entry);
1451
 
                        } else {
1452
 
                                err = DB_SUCCESS;
1453
 
                        }
1454
 
 
1455
 
                        break;
1456
 
                }
1457
 
 
1458
 
                ut_a(cmp == 0);
1459
 
next_rec:
1460
 
                moved = btr_pcur_move_to_next(&pcur, &mtr);
1461
 
 
1462
 
                if (!moved) {
1463
 
                        if (check_ref) {
1464
 
                                rec = btr_pcur_get_rec(&pcur);
1465
 
                                row_ins_foreign_report_add_err(
1466
 
                                        trx, foreign, rec, entry);
1467
 
                                err = DB_NO_REFERENCED_ROW;
1468
 
                        } else {
1469
 
                                err = DB_SUCCESS;
1470
 
                        }
1471
 
 
1472
 
                        break;
1473
 
                }
 
1448
 
 
1449
                        switch (err) {
 
1450
                        case DB_SUCCESS_LOCKED_REC:
 
1451
                        case DB_SUCCESS:
 
1452
                                if (check_ref) {
 
1453
                                        err = DB_NO_REFERENCED_ROW;
 
1454
                                        row_ins_foreign_report_add_err(
 
1455
                                                trx, foreign, rec, entry);
 
1456
                                } else {
 
1457
                                        err = DB_SUCCESS;
 
1458
                                }
 
1459
                        }
 
1460
 
 
1461
                        goto end_scan;
 
1462
                }
 
1463
        } while (btr_pcur_move_to_next(&pcur, &mtr));
 
1464
 
 
1465
        if (check_ref) {
 
1466
                row_ins_foreign_report_add_err(
 
1467
                        trx, foreign, btr_pcur_get_rec(&pcur), entry);
 
1468
                err = DB_NO_REFERENCED_ROW;
 
1469
        } else {
 
1470
                err = DB_SUCCESS;
1474
1471
        }
1475
1472
 
 
1473
end_scan:
1476
1474
        btr_pcur_close(&pcur);
1477
1475
 
1478
1476
        mtr_commit(&mtr);
1720
1718
                                rec, index, offsets, thr);
1721
1719
                }
1722
1720
 
1723
 
                if (err != DB_SUCCESS) {
1724
 
 
 
1721
                switch (err) {
 
1722
                case DB_SUCCESS_LOCKED_REC:
 
1723
                        err = DB_SUCCESS;
 
1724
                case DB_SUCCESS:
1725
1725
                        break;
 
1726
                default:
 
1727
                        goto end_scan;
1726
1728
                }
1727
1729
 
1728
1730
                if (page_rec_is_supremum(rec)) {
1739
1741
 
1740
1742
                                thr_get_trx(thr)->error_info = index;
1741
1743
 
1742
 
                                break;
 
1744
                                goto end_scan;
1743
1745
                        }
1744
 
                }
1745
 
 
1746
 
                if (cmp < 0) {
1747
 
                        break;
1748
 
                }
1749
 
 
1750
 
                ut_a(cmp == 0);
 
1746
                } else {
 
1747
                        ut_a(cmp < 0);
 
1748
                        goto end_scan;
 
1749
                }
1751
1750
        } while (btr_pcur_move_to_next(&pcur, &mtr));
1752
1751
 
 
1752
end_scan:
1753
1753
        if (UNIV_LIKELY_NULL(heap)) {
1754
1754
                mem_heap_free(heap);
1755
1755
        }
1838
1838
                                        cursor->index, offsets, thr);
1839
1839
                        }
1840
1840
 
1841
 
                        if (err != DB_SUCCESS) {
 
1841
                        switch (err) {
 
1842
                        case DB_SUCCESS_LOCKED_REC:
 
1843
                        case DB_SUCCESS:
 
1844
                                break;
 
1845
                        default:
1842
1846
                                goto func_exit;
1843
1847
                        }
1844
1848
 
1878
1882
                                        rec, cursor->index, offsets, thr);
1879
1883
                        }
1880
1884
 
1881
 
                        if (err != DB_SUCCESS) {
 
1885
                        switch (err) {
 
1886
                        case DB_SUCCESS_LOCKED_REC:
 
1887
                        case DB_SUCCESS:
 
1888
                                break;
 
1889
                        default:
1882
1890
                                goto func_exit;
1883
1891
                        }
1884
1892
 
1966
1974
        que_thr_t*      thr)    /*!< in: query thread */
1967
1975
{
1968
1976
        btr_cur_t       cursor;
1969
 
        ulint           ignore_sec_unique       = 0;
 
1977
        ulint           search_mode;
1970
1978
        ulint           modify = 0; /* remove warning */
1971
1979
        rec_t*          insert_rec;
1972
1980
        rec_t*          rec;
1986
1994
        the function will return in both low_match and up_match of the
1987
1995
        cursor sensible values */
1988
1996
 
1989
 
        if (!(thr_get_trx(thr)->check_unique_secondary)) {
1990
 
                ignore_sec_unique = BTR_IGNORE_SEC_UNIQUE;
 
1997
        if (dict_index_is_clust(index)) {
 
1998
                search_mode = mode;
 
1999
        } else if (!(thr_get_trx(thr)->check_unique_secondary)) {
 
2000
                search_mode = mode | BTR_INSERT | BTR_IGNORE_SEC_UNIQUE;
 
2001
        } else {
 
2002
                search_mode = mode | BTR_INSERT;
1991
2003
        }
1992
2004
 
1993
2005
        btr_cur_search_to_nth_level(index, 0, entry, PAGE_CUR_LE,
1994
 
                                    mode | BTR_INSERT | ignore_sec_unique,
 
2006
                                    search_mode,
1995
2007
                                    &cursor, 0, __FILE__, __LINE__, &mtr);
1996
2008
 
1997
2009
        if (cursor.flag == BTR_CUR_INSERT_TO_IBUF) {
1998
2010
                /* The insertion was made to the insert buffer already during
1999
2011
                the search: we are done */
2000
2012
 
 
2013
                ut_ad(search_mode & BTR_INSERT);
2001
2014
                err = DB_SUCCESS;
2002
2015
 
2003
2016
                goto function_exit;