~drizzle-trunk/drizzle/development

« back to all changes in this revision

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

  • Committer: Monty Taylor
  • Date: 2010-11-25 01:53:19 UTC
  • mto: (1953.1.2 build)
  • mto: This revision was merged to the branch mainline in revision 1955.
  • Revision ID: mordred@inaugust.com-20101125015319-ia85msn25uemopgc
Re-enabled -Wformat and then cleaned up the carnage.

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
1
/*****************************************************************************
2
2
 
3
 
Copyright (c) 1996, 2010, Innobase Oy. All Rights Reserved.
 
3
Copyright (c) 1996, 2009, Innobase Oy. All Rights Reserved.
4
4
 
5
5
This program is free software; you can redistribute it and/or modify it under
6
6
the terms of the GNU General Public License as published by the Free Software
92
92
searched delete is obviously to keep the x-latch for several
93
93
steps of query graph execution. */
94
94
 
95
 
/*************************************************************************
96
 
IMPORTANT NOTE: Any operation that generates redo MUST check that there
97
 
is enough space in the redo log before for that operation. This is
98
 
done by calling log_free_check(). The reason for checking the
99
 
availability of the redo log space before the start of the operation is
100
 
that we MUST not hold any synchonization objects when performing the
101
 
check.
102
 
If you make a change in this module make sure that no codepath is
103
 
introduced where a call to log_free_check() is bypassed. */
104
 
 
105
 
/*************************************************************************
106
 
IMPORTANT NOTE: Any operation that generates redo MUST check that there
107
 
is enough space in the redo log before for that operation. This is
108
 
done by calling log_free_check(). The reason for checking the
109
 
availability of the redo log space before the start of the operation is
110
 
that we MUST not hold any synchonization objects when performing the
111
 
check.
112
 
If you make a change in this module make sure that no codepath is
113
 
introduced where a call to log_free_check() is bypassed. */
114
 
 
115
95
/***********************************************************//**
116
96
Checks if an update vector changes some of the first ordering fields of an
117
97
index record. This is only used in foreign key checks and we can assume
387
367
                                them */
388
368
        dict_index_t*   index,  /*!< in: clustered index */
389
369
        ulint           type,   /*!< in: DATA_TRX_ID or DATA_ROLL_PTR */
390
 
        ib_uint64_t     val)    /*!< in: value to write */
 
370
        dulint          val)    /*!< in: value to write */
391
371
{
392
372
        dfield_t*       dfield;
393
373
        byte*           field;
546
526
        trx_write_roll_ptr(log_ptr, roll_ptr);
547
527
        log_ptr += DATA_ROLL_PTR_LEN;
548
528
 
549
 
        log_ptr += mach_ull_write_compressed(log_ptr, trx->id);
 
529
        log_ptr += mach_dulint_write_compressed(log_ptr, trx->id);
550
530
 
551
531
        return(log_ptr);
552
532
}
580
560
        *roll_ptr = trx_read_roll_ptr(ptr);
581
561
        ptr += DATA_ROLL_PTR_LEN;
582
562
 
583
 
        ptr = mach_ull_parse_compressed(ptr, end_ptr, trx_id);
 
563
        ptr = mach_dulint_parse_compressed(ptr, end_ptr, trx_id);
584
564
 
585
565
        return(ptr);
586
566
}
959
939
                }
960
940
 
961
941
                len = dtype_get_at_most_n_mbchars(col->prtype,
962
 
                                                  col->mbminmaxlen,
 
942
                                                  col->mbminlen, col->mbmaxlen,
963
943
                                                  field->prefix_len, len,
964
944
                                                  (const char*) data);
965
945
 
1408
1388
        dict_index_t*   clust_index;
1409
1389
        rec_t*          rec;
1410
1390
        mem_heap_t*     heap            = NULL;
1411
 
        row_ext_t**     ext;
1412
1391
        ulint           offsets_[REC_OFFS_NORMAL_SIZE];
1413
1392
        const ulint*    offsets;
1414
1393
        rec_offs_init(offsets_);
1425
1404
 
1426
1405
        offsets = rec_get_offsets(rec, clust_index, offsets_,
1427
1406
                                  ULINT_UNDEFINED, &heap);
1428
 
 
1429
 
        if (dict_table_get_format(node->table) >= DICT_TF_FORMAT_ZIP) {
1430
 
                /* In DYNAMIC or COMPRESSED format, there is no prefix
1431
 
                of externally stored columns in the clustered index
1432
 
                record. Build a cache of column prefixes. */
1433
 
                ext = &node->ext;
1434
 
        } else {
1435
 
                /* REDUNDANT and COMPACT formats store a local
1436
 
                768-byte prefix of each externally stored column.
1437
 
                No cache is needed. */
1438
 
                ext = NULL;
1439
 
                node->ext = NULL;
1440
 
        }
1441
 
 
1442
1407
        node->row = row_build(ROW_COPY_DATA, clust_index, rec, offsets,
1443
 
                              NULL, ext, node->heap);
 
1408
                              NULL, &node->ext, node->heap);
1444
1409
        if (node->is_delete) {
1445
1410
                node->upd_row = NULL;
1446
1411
                node->upd_ext = NULL;
1466
1431
        upd_node_t*     node,   /*!< in: row update node */
1467
1432
        que_thr_t*      thr)    /*!< in: query thread */
1468
1433
{
1469
 
        mtr_t                   mtr;
1470
 
        const rec_t*            rec;
1471
 
        btr_pcur_t              pcur;
1472
 
        mem_heap_t*             heap;
1473
 
        dtuple_t*               entry;
1474
 
        dict_index_t*           index;
1475
 
        btr_cur_t*              btr_cur;
1476
 
        ibool                   referenced;
1477
 
        ulint                   err     = DB_SUCCESS;
1478
 
        trx_t*                  trx     = thr_get_trx(thr);
1479
 
        ulint                   mode    = BTR_MODIFY_LEAF;
1480
 
        enum row_search_result  search_result;
 
1434
        ibool           check_ref;
 
1435
        ibool           found;
 
1436
        dict_index_t*   index;
 
1437
        dtuple_t*       entry;
 
1438
        btr_pcur_t      pcur;
 
1439
        btr_cur_t*      btr_cur;
 
1440
        mem_heap_t*     heap;
 
1441
        rec_t*          rec;
 
1442
        ulint           err     = DB_SUCCESS;
 
1443
        mtr_t           mtr;
 
1444
        trx_t*          trx     = thr_get_trx(thr);
1481
1445
 
1482
1446
        index = node->index;
1483
1447
 
1484
 
        referenced = row_upd_index_is_referenced(index, trx);
 
1448
        check_ref = row_upd_index_is_referenced(index, trx);
1485
1449
 
1486
1450
        heap = mem_heap_create(1024);
1487
1451
 
1489
1453
        entry = row_build_index_entry(node->row, node->ext, index, heap);
1490
1454
        ut_a(entry);
1491
1455
 
 
1456
        log_free_check();
1492
1457
        mtr_start(&mtr);
1493
1458
 
1494
 
        /* Set the query thread, so that ibuf_insert_low() will be
1495
 
        able to invoke thd_get_trx(). */
1496
 
        btr_pcur_get_btr_cur(&pcur)->thr = thr;
1497
 
 
1498
 
        /* We can only try to use the insert/delete buffer to buffer
1499
 
        delete-mark operations if the index we're modifying has no foreign
1500
 
        key constraints referring to it. */
1501
 
        if (!referenced) {
1502
 
                mode |= BTR_DELETE_MARK;
1503
 
        }
1504
 
 
1505
 
        search_result = row_search_index_entry(index, entry, mode,
1506
 
                                               &pcur, &mtr);
1507
 
 
 
1459
        found = row_search_index_entry(index, entry, BTR_MODIFY_LEAF, &pcur,
 
1460
                                       &mtr);
1508
1461
        btr_cur = btr_pcur_get_btr_cur(&pcur);
1509
1462
 
1510
1463
        rec = btr_cur_get_rec(btr_cur);
1511
1464
 
1512
 
        switch (search_result) {
1513
 
        case ROW_NOT_DELETED_REF:       /* should only occur for BTR_DELETE */
1514
 
                ut_error;
1515
 
                break;
1516
 
        case ROW_BUFFERED:
1517
 
                /* Entry was delete marked already. */
1518
 
                break;
1519
 
 
1520
 
        case ROW_NOT_FOUND:
 
1465
        if (UNIV_UNLIKELY(!found)) {
1521
1466
                fputs("InnoDB: error in sec index entry update in\n"
1522
1467
                      "InnoDB: ", stderr);
1523
1468
                dict_index_name_print(stderr, trx, index);
1534
1479
                fputs("\n"
1535
1480
                      "InnoDB: Submit a detailed bug report"
1536
1481
                      " to http://bugs.mysql.com\n", stderr);
1537
 
                break;
1538
 
        case ROW_FOUND:
 
1482
        } else {
1539
1483
                /* Delete mark the old index record; it can already be
1540
1484
                delete marked if we return after a lock wait in
1541
1485
                row_ins_index_entry below */
1542
1486
 
1543
 
                if (!rec_get_deleted_flag(
1544
 
                        rec, dict_table_is_comp(index->table))) {
1545
 
 
1546
 
                        err = btr_cur_del_mark_set_sec_rec(
1547
 
                                0, btr_cur, TRUE, thr, &mtr);
1548
 
 
1549
 
                        if (err == DB_SUCCESS && referenced) {
1550
 
 
1551
 
                                ulint*  offsets;
1552
 
 
1553
 
                                offsets = rec_get_offsets(
1554
 
                                        rec, index, NULL, ULINT_UNDEFINED,
1555
 
                                        &heap);
1556
 
 
 
1487
                if (!rec_get_deleted_flag(rec,
 
1488
                                          dict_table_is_comp(index->table))) {
 
1489
                        err = btr_cur_del_mark_set_sec_rec(0, btr_cur, TRUE,
 
1490
                                                           thr, &mtr);
 
1491
                        if (err == DB_SUCCESS && check_ref) {
 
1492
 
 
1493
                                ulint*  offsets = rec_get_offsets(
 
1494
                                        rec, index, NULL,
 
1495
                                        ULINT_UNDEFINED, &heap);
1557
1496
                                /* NOTE that the following call loses
1558
1497
                                the position of pcur ! */
1559
1498
                                err = row_upd_check_references_constraints(
1561
1500
                                        index, offsets, thr, &mtr);
1562
1501
                        }
1563
1502
                }
1564
 
                break;
1565
1503
        }
1566
1504
 
1567
1505
        btr_pcur_close(&pcur);
1591
1529
deletes it if this is a delete.
1592
1530
@return DB_SUCCESS if operation successfully completed, else error
1593
1531
code or DB_LOCK_WAIT */
1594
 
static
 
1532
UNIV_INLINE
1595
1533
ulint
1596
1534
row_upd_sec_step(
1597
1535
/*=============*/
1625
1563
        upd_node_t*     node,   /*!< in: row update node */
1626
1564
        dict_index_t*   index,  /*!< in: clustered index of the record */
1627
1565
        que_thr_t*      thr,    /*!< in: query thread */
1628
 
        ibool           referenced,/*!< in: TRUE if index may be referenced in
 
1566
        ibool           check_ref,/*!< in: TRUE if index may be referenced in
1629
1567
                                a foreign key constraint */
1630
1568
        mtr_t*          mtr)    /*!< in: mtr; gets committed here */
1631
1569
{
1636
1574
        dict_table_t*   table;
1637
1575
        dtuple_t*       entry;
1638
1576
        ulint           err;
1639
 
        ibool           change_ownership = FALSE;
1640
1577
 
1641
1578
        ut_ad(node);
1642
1579
        ut_ad(dict_index_is_clust(index));
1669
1606
                index = dict_table_get_first_index(table);
1670
1607
                offsets = rec_get_offsets(rec, index, offsets_,
1671
1608
                                          ULINT_UNDEFINED, &heap);
1672
 
                change_ownership = btr_cur_mark_extern_inherited_fields(
1673
 
                        btr_cur_get_page_zip(btr_cur), rec, index, offsets,
1674
 
                        node->update, mtr);
1675
 
                if (referenced) {
 
1609
                btr_cur_mark_extern_inherited_fields(
 
1610
                        btr_cur_get_page_zip(btr_cur),
 
1611
                        rec, index, offsets, node->update, mtr);
 
1612
                if (check_ref) {
1676
1613
                        /* NOTE that the following call loses
1677
1614
                        the position of pcur ! */
1678
 
 
1679
1615
                        err = row_upd_check_references_constraints(
1680
1616
                                node, pcur, table, index, offsets, thr, mtr);
1681
 
 
1682
1617
                        if (err != DB_SUCCESS) {
1683
 
 
1684
1618
                                mtr_commit(mtr);
1685
 
 
1686
1619
                                if (UNIV_LIKELY_NULL(heap)) {
1687
1620
                                        mem_heap_free(heap);
1688
1621
                                }
1689
 
 
1690
1622
                                return(err);
1691
1623
                        }
1692
1624
                }
1705
1637
 
1706
1638
        row_upd_index_entry_sys_field(entry, index, DATA_TRX_ID, trx->id);
1707
1639
 
1708
 
        if (change_ownership) {
 
1640
        if (node->upd_ext) {
1709
1641
                /* If we return from a lock wait, for example, we may have
1710
1642
                extern fields marked as not-owned in entry (marked in the
1711
 
                if-branch above). We must unmark them, take the ownership
1712
 
                back. */
 
1643
                if-branch above). We must unmark them. */
1713
1644
 
1714
1645
                btr_cur_unmark_dtuple_extern_fields(entry);
1715
1646
 
1842
1773
        ulint*          offsets,/*!< in/out: rec_get_offsets() for the
1843
1774
                                record under the cursor */
1844
1775
        que_thr_t*      thr,    /*!< in: query thread */
1845
 
        ibool           referenced,
1846
 
                                /*!< in: TRUE if index may be referenced in
 
1776
        ibool           check_ref,/*!< in: TRUE if index may be referenced in
1847
1777
                                a foreign key constraint */
1848
1778
        mtr_t*          mtr)    /*!< in: mtr; gets committed here */
1849
1779
{
1868
1798
 
1869
1799
        err = btr_cur_del_mark_set_clust_rec(BTR_NO_LOCKING_FLAG,
1870
1800
                                             btr_cur, TRUE, thr, mtr);
1871
 
        if (err == DB_SUCCESS && referenced) {
 
1801
        if (err == DB_SUCCESS && check_ref) {
1872
1802
                /* NOTE that the following call loses the position of pcur ! */
1873
1803
 
1874
 
                err = row_upd_check_references_constraints(
1875
 
                        node, pcur, index->table, index, offsets, thr, mtr);
 
1804
                err = row_upd_check_references_constraints(node,
 
1805
                                                           pcur, index->table,
 
1806
                                                           index, offsets,
 
1807
                                                           thr, mtr);
1876
1808
        }
1877
1809
 
1878
1810
        mtr_commit(mtr);
1894
1826
        dict_index_t*   index;
1895
1827
        btr_pcur_t*     pcur;
1896
1828
        ibool           success;
 
1829
        ibool           check_ref;
1897
1830
        ulint           err;
1898
1831
        mtr_t*          mtr;
1899
1832
        mtr_t           mtr_buf;
1901
1834
        mem_heap_t*     heap            = NULL;
1902
1835
        ulint           offsets_[REC_OFFS_NORMAL_SIZE];
1903
1836
        ulint*          offsets;
1904
 
        ibool           referenced;
1905
1837
        rec_offs_init(offsets_);
1906
1838
 
1907
1839
        index = dict_table_get_first_index(node->table);
1908
1840
 
1909
 
        referenced = row_upd_index_is_referenced(index, thr_get_trx(thr));
 
1841
        check_ref = row_upd_index_is_referenced(index, thr_get_trx(thr));
1910
1842
 
1911
1843
        pcur = node->pcur;
1912
1844
 
1939
1871
        then we have to free the file segments of the index tree associated
1940
1872
        with the index */
1941
1873
 
1942
 
        if (node->is_delete && node->table->id == DICT_INDEXES_ID) {
 
1874
        if (node->is_delete
 
1875
            && ut_dulint_cmp(node->table->id, DICT_INDEXES_ID) == 0) {
1943
1876
 
1944
1877
                dict_drop_index_tree(btr_pcur_get_rec(pcur), mtr);
1945
1878
 
1975
1908
        /* NOTE: the following function calls will also commit mtr */
1976
1909
 
1977
1910
        if (node->is_delete) {
1978
 
                err = row_upd_del_mark_clust_rec(
1979
 
                        node, index, offsets, thr, referenced, mtr);
1980
 
 
 
1911
                err = row_upd_del_mark_clust_rec(node, index, offsets,
 
1912
                                                 thr, check_ref, mtr);
1981
1913
                if (err == DB_SUCCESS) {
1982
1914
                        node->state = UPD_NODE_UPDATE_ALL_SEC;
1983
1915
                        node->index = dict_table_get_next_index(index);
2025
1957
                choosing records to update. MySQL solves now the problem
2026
1958
                externally! */
2027
1959
 
2028
 
                err = row_upd_clust_rec_by_insert(
2029
 
                        node, index, thr, referenced, mtr);
2030
 
 
 
1960
                err = row_upd_clust_rec_by_insert(node, index, thr, check_ref,
 
1961
                                                  mtr);
2031
1962
                if (err != DB_SUCCESS) {
2032
1963
 
2033
1964
                        return(err);
2084
2015
        if (node->state == UPD_NODE_UPDATE_CLUSTERED
2085
2016
            || node->state == UPD_NODE_INSERT_CLUSTERED) {
2086
2017
 
2087
 
                log_free_check();
2088
2018
                err = row_upd_clust_step(node, thr);
2089
2019
 
2090
2020
                if (err != DB_SUCCESS) {
2099
2029
        }
2100
2030
 
2101
2031
        while (node->index != NULL) {
2102
 
 
2103
 
                log_free_check();
2104
2032
                err = row_upd_sec_step(node, thr);
2105
2033
 
2106
2034
                if (err != DB_SUCCESS) {