~drizzle-trunk/drizzle/development

« back to all changes in this revision

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

  • Committer: Monty Taylor
  • Date: 2010-12-05 07:35:32 UTC
  • mfrom: (1974 b)
  • mto: (1975.1.1 build)
  • mto: This revision was merged to the branch mainline in revision 1976.
  • Revision ID: mordred@inaugust.com-20101205073532-hehqwv27pbd7byjm
Merged source.

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
1
/*****************************************************************************
2
2
 
3
 
Copyright (C) 2000, 2010, Innobase Oy. All Rights Reserved.
 
3
Copyright (c) 2000, 2010, 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
486
486
                                        row is used, as row may contain
487
487
                                        pointers to this record! */
488
488
{
489
 
        const mysql_row_templ_t*templ;
 
489
        mysql_row_templ_t*      templ;
490
490
        dfield_t*               dfield;
491
491
        ulint                   i;
492
492
 
618
618
                      "InnoDB: " REFMAN "forcing-recovery.html"
619
619
                      " for help.\n", stderr);
620
620
                break;
621
 
        case DB_FOREIGN_EXCEED_MAX_CASCADE:
622
 
                fprintf(stderr, "InnoDB: Cannot delete/update rows with"
623
 
                        " cascading foreign key constraints that exceed max"
624
 
                        " depth of %lu\n"
625
 
                        "Please drop excessive foreign constraints"
626
 
                        " and try again\n", (ulong) DICT_FK_MAX_RECURSIVE_LOAD);
627
 
                break;
628
621
        default:
629
622
                fprintf(stderr, "InnoDB: unknown error code %lu\n",
630
623
                        (ulong) err);
659
652
 
660
653
        heap = mem_heap_create(sizeof *prebuilt + 128);
661
654
 
662
 
        prebuilt = static_cast<row_prebuilt_t *>(mem_heap_zalloc(heap, sizeof *prebuilt));
 
655
        prebuilt = mem_heap_zalloc(heap, sizeof *prebuilt);
663
656
 
664
657
        prebuilt->magic_n = ROW_PREBUILT_ALLOCATED;
665
658
        prebuilt->magic_n2 = ROW_PREBUILT_ALLOCATED;
840
833
        }
841
834
}
842
835
 
843
 
dtuple_t* row_get_prebuilt_insert_row(row_prebuilt_t*   prebuilt);
844
 
 
845
836
/*********************************************************************//**
846
837
Gets pointer to a prebuilt dtuple used in insertions. If the insert graph
847
838
has not yet been built in the prebuilt struct, then this function first
848
839
builds it.
849
840
@return prebuilt dtuple; the column type information is also set in it */
 
841
static
850
842
dtuple_t*
851
843
row_get_prebuilt_insert_row(
852
844
/*========================*/
869
861
                prebuilt->ins_node = node;
870
862
 
871
863
                if (prebuilt->ins_upd_rec_buff == NULL) {
872
 
                        prebuilt->ins_upd_rec_buff = static_cast<byte *>(mem_heap_alloc(
873
 
                                prebuilt->heap, prebuilt->mysql_row_len));
 
864
                        prebuilt->ins_upd_rec_buff = mem_heap_alloc(
 
865
                                prebuilt->heap, prebuilt->mysql_row_len);
874
866
                }
875
867
 
876
868
                row = dtuple_create(prebuilt->heap,
880
872
 
881
873
                ins_node_set_new_row(node, row);
882
874
 
883
 
                prebuilt->ins_graph = static_cast<que_fork_t *>(que_node_get_parent(
 
875
                prebuilt->ins_graph = que_node_get_parent(
884
876
                        pars_complete_graph_for_exec(node,
885
877
                                                     prebuilt->trx,
886
 
                                                     prebuilt->heap)));
 
878
                                                     prebuilt->heap));
887
879
                prebuilt->ins_graph->state = QUE_FORK_ACTIVE;
888
880
        }
889
881
 
914
906
        if (counter > 2000000000
915
907
            || ((ib_int64_t)counter > 16 + table->stat_n_rows / 16)) {
916
908
 
917
 
                dict_update_statistics(table, FALSE /* update even if stats
918
 
                                                    are initialized */);
 
909
                dict_update_statistics(table);
919
910
        }
920
911
}
921
912
 
1066
1057
        trx_start_if_not_started(trx);
1067
1058
 
1068
1059
        if (table) {
1069
 
                err = lock_table(0, table, static_cast<lock_mode>(mode), thr);
 
1060
                err = lock_table(0, table, mode, thr);
1070
1061
        } else {
1071
1062
                err = lock_table(0, prebuilt->table,
1072
 
                                 static_cast<lock_mode>(prebuilt->select_lock_type), thr);
 
1063
                                 prebuilt->select_lock_type, thr);
1073
1064
        }
1074
1065
 
1075
1066
        trx->error_state = err;
1244
1235
 
1245
1236
                node = sel_node_create(prebuilt->heap);
1246
1237
 
1247
 
                prebuilt->sel_graph = static_cast<que_fork_t *>(que_node_get_parent(
 
1238
                prebuilt->sel_graph = que_node_get_parent(
1248
1239
                        pars_complete_graph_for_exec(node,
1249
1240
                                                     prebuilt->trx,
1250
 
                                                     prebuilt->heap)));
 
1241
                                                     prebuilt->heap));
1251
1242
 
1252
1243
                prebuilt->sel_graph->state = QUE_FORK_ACTIVE;
1253
1244
        }
1315
1306
 
1316
1307
                prebuilt->upd_node = node;
1317
1308
 
1318
 
                prebuilt->upd_graph = static_cast<que_fork_t *>(que_node_get_parent(
 
1309
                prebuilt->upd_graph = que_node_get_parent(
1319
1310
                        pars_complete_graph_for_exec(node,
1320
1311
                                                     prebuilt->trx,
1321
 
                                                     prebuilt->heap)));
 
1312
                                                     prebuilt->heap));
1322
1313
                prebuilt->upd_graph->state = QUE_FORK_ACTIVE;
1323
1314
        }
1324
1315
 
1432
1423
run_again:
1433
1424
        thr->run_node = node;
1434
1425
        thr->prev_node = node;
1435
 
        thr->fk_cascade_depth = 0;
1436
1426
 
1437
1427
        row_upd_step(thr);
1438
1428
 
1439
 
        /* The recursive call for cascading update/delete happens
1440
 
        in above row_upd_step(), reset the counter once we come
1441
 
        out of the recursive call, so it does not accumulate for
1442
 
        different row deletes */
1443
 
        thr->fk_cascade_depth = 0;
1444
 
 
1445
1429
        err = trx->error_state;
1446
1430
 
1447
 
        /* Reset fk_cascade_depth back to 0 */
1448
 
        thr->fk_cascade_depth = 0;
1449
 
 
1450
1431
        if (err != DB_SUCCESS) {
1451
1432
                que_thr_stop_for_mysql(thr);
1452
1433
 
1483
1464
                srv_n_rows_updated++;
1484
1465
        }
1485
1466
 
1486
 
        /* We update table statistics only if it is a DELETE or UPDATE
1487
 
        that changes indexed columns, UPDATEs that change only non-indexed
1488
 
        columns would not affect statistics. */
1489
 
        if (node->is_delete || !(node->cmpl_info & UPD_NODE_NO_ORD_CHANGE)) {
1490
 
                row_update_statistics_if_needed(prebuilt->table);
1491
 
        }
 
1467
        row_update_statistics_if_needed(prebuilt->table);
1492
1468
 
1493
1469
        trx->op_info = "";
1494
1470
 
1605
1581
                        index = btr_pcur_get_btr_cur(pcur)->index;
1606
1582
 
1607
1583
                        lock_rec_unlock(trx, btr_pcur_get_block(pcur),
1608
 
                                        rec, static_cast<lock_mode>(prebuilt->select_lock_type));
 
1584
                                        rec, prebuilt->select_lock_type);
1609
1585
 
1610
1586
                        if (prebuilt->new_rec_locks >= 2) {
1611
1587
                                rec = btr_pcur_get_rec(clust_pcur);
1614
1590
                                lock_rec_unlock(trx,
1615
1591
                                                btr_pcur_get_block(clust_pcur),
1616
1592
                                                rec,
1617
 
                                                static_cast<lock_mode>(prebuilt->select_lock_type));
 
1593
                                                prebuilt->select_lock_type);
1618
1594
                        }
1619
1595
                }
1620
1596
no_unlock:
1642
1618
        trx_t*  trx;
1643
1619
 
1644
1620
        trx = thr_get_trx(thr);
1645
 
 
1646
 
        /* Increment fk_cascade_depth to record the recursive call depth on
1647
 
        a single update/delete that affects multiple tables chained
1648
 
        together with foreign key relations. */
1649
 
        thr->fk_cascade_depth++;
1650
 
 
1651
 
        if (thr->fk_cascade_depth > FK_MAX_CASCADE_DEL) {
1652
 
                return (DB_FOREIGN_EXCEED_MAX_CASCADE);
1653
 
        }
1654
1621
run_again:
1655
1622
        thr->run_node = node;
1656
1623
        thr->prev_node = node;
1657
1624
 
1658
1625
        row_upd_step(thr);
1659
1626
 
1660
 
        /* The recursive call for cascading update/delete happens
1661
 
        in above row_upd_step(), reset the counter once we come
1662
 
        out of the recursive call, so it does not accumulate for
1663
 
        different row deletes */
1664
 
        thr->fk_cascade_depth = 0;
1665
 
 
1666
1627
        err = trx->error_state;
1667
1628
 
1668
1629
        /* Note that the cascade node is a subnode of another InnoDB
1912
1873
 
1913
1874
        thr = pars_complete_graph_for_exec(node, trx, heap);
1914
1875
 
1915
 
        ut_a(thr == que_fork_start_command(static_cast<que_fork_t *>(que_node_get_parent(thr))));
 
1876
        ut_a(thr == que_fork_start_command(que_node_get_parent(thr)));
1916
1877
        que_run_threads(thr);
1917
1878
 
1918
1879
        err = trx->error_state;
1919
1880
 
 
1881
        if (UNIV_UNLIKELY(err != DB_SUCCESS)) {
 
1882
                trx->error_state = DB_SUCCESS;
 
1883
                trx_general_rollback_for_mysql(trx, NULL);
 
1884
                /* TO DO: free table?  The code below will dereference
 
1885
                table->name, though. */
 
1886
        }
 
1887
 
1920
1888
        switch (err) {
1921
 
        case DB_SUCCESS:
1922
 
                break;
1923
1889
        case DB_OUT_OF_FILE_SPACE:
1924
 
                trx->error_state = DB_SUCCESS;
1925
 
                trx_general_rollback_for_mysql(trx, NULL);
1926
 
 
1927
1890
                ut_print_timestamp(stderr);
1928
1891
                fputs("  InnoDB: Warning: cannot create table ",
1929
1892
                      stderr);
1938
1901
                break;
1939
1902
 
1940
1903
        case DB_DUPLICATE_KEY:
1941
 
        default:
1942
1904
                /* We may also get err == DB_ERROR if the .ibd file for the
1943
1905
                table already exists */
1944
1906
 
1945
 
                trx->error_state = DB_SUCCESS;
1946
 
                trx_general_rollback_for_mysql(trx, NULL);
1947
 
                dict_mem_table_free(table);
1948
1907
                break;
1949
1908
        }
1950
1909
 
2053
2012
 
2054
2013
        thr = pars_complete_graph_for_exec(node, trx, heap);
2055
2014
 
2056
 
        ut_a(thr == que_fork_start_command(static_cast<que_fork_t *>(que_node_get_parent(thr))));
 
2015
        ut_a(thr == que_fork_start_command(que_node_get_parent(thr)));
2057
2016
        que_run_threads(thr);
2058
2017
 
2059
2018
        err = trx->error_state;
2127
2086
                                              name, reject_fks);
2128
2087
        if (err == DB_SUCCESS) {
2129
2088
                /* Check that also referencing constraints are ok */
2130
 
                err = dict_load_foreigns(name, FALSE, TRUE);
 
2089
                err = dict_load_foreigns(name, TRUE);
2131
2090
        }
2132
2091
 
2133
2092
        if (err != DB_SUCCESS) {
2326
2285
                drop = UT_LIST_GET_NEXT(row_mysql_drop_list, drop);
2327
2286
        }
2328
2287
 
2329
 
        drop = static_cast<row_mysql_drop_t *>(mem_alloc(sizeof(row_mysql_drop_t)));
 
2288
        drop = mem_alloc(sizeof(row_mysql_drop_t));
2330
2289
 
2331
2290
        drop->table_name = mem_strdup(name);
2332
2291
 
2832
2791
 
2833
2792
                        dict_hdr_get_new_id(NULL, NULL, &space);
2834
2793
 
2835
 
                        /* Lock all index trees for this table. We must
2836
 
                        do so after dict_hdr_get_new_id() to preserve
2837
 
                        the latch order */
2838
 
                        dict_table_x_lock_indexes(table);
2839
 
 
2840
2794
                        if (space == ULINT_UNDEFINED
2841
2795
                            || fil_create_new_single_table_tablespace(
2842
2796
                                    space, table->name, FALSE, flags,
2843
2797
                                    FIL_IBD_FILE_INITIAL_SIZE) != DB_SUCCESS) {
2844
 
                                dict_table_x_unlock_indexes(table);
2845
2798
                                ut_print_timestamp(stderr);
2846
2799
                                fprintf(stderr,
2847
2800
                                        "  InnoDB: TRUNCATE TABLE %s failed to"
2870
2823
                                        FIL_IBD_FILE_INITIAL_SIZE, &mtr);
2871
2824
                        mtr_commit(&mtr);
2872
2825
                }
2873
 
        } else {
2874
 
                /* Lock all index trees for this table, as we will
2875
 
                truncate the table/index and possibly change their metadata.
2876
 
                All DML/DDL are blocked by table level lock, with
2877
 
                a few exceptions such as queries into information schema
2878
 
                about the table, MySQL could try to access index stats
2879
 
                for this kind of query, we need to use index locks to
2880
 
                sync up */
2881
 
                dict_table_x_lock_indexes(table);
2882
2826
        }
2883
2827
 
2884
2828
        /* scan SYS_INDEXES for all indexes of the table */
2887
2831
        tuple = dtuple_create(heap, 1);
2888
2832
        dfield = dtuple_get_nth_field(tuple, 0);
2889
2833
 
2890
 
        buf = static_cast<byte *>(mem_heap_alloc(heap, 8));
 
2834
        buf = mem_heap_alloc(heap, 8);
2891
2835
        mach_write_to_8(buf, table->id);
2892
2836
 
2893
2837
        dfield_set_data(dfield, buf, 8);
2954
2898
 
2955
2899
        mem_heap_free(heap);
2956
2900
 
2957
 
        /* Done with index truncation, release index tree locks,
2958
 
        subsequent work relates to table level metadata change */
2959
 
        dict_table_x_unlock_indexes(table);
2960
 
 
2961
2901
        dict_hdr_get_new_id(&new_id, NULL, NULL);
2962
2902
 
2963
2903
        info = pars_info_create();
3004
2944
        dict_table_autoinc_lock(table);
3005
2945
        dict_table_autoinc_initialize(table, 1);
3006
2946
        dict_table_autoinc_unlock(table);
3007
 
        dict_update_statistics(table, FALSE /* update even if stats are
3008
 
                                            initialized */);
 
2947
        dict_update_statistics(table);
3009
2948
 
3010
2949
        trx_commit_for_mysql(trx);
3011
2950
 
3213
3152
 
3214
3153
        if (table->n_foreign_key_checks_running > 0) {
3215
3154
 
3216
 
                const char*     i_table_name = table->name;
 
3155
                const char*     table_name = table->name;
3217
3156
                ibool           added;
3218
3157
 
3219
 
                added = row_add_table_to_background_drop_list(i_table_name);
 
3158
                added = row_add_table_to_background_drop_list(table_name);
3220
3159
 
3221
3160
                if (added) {
3222
3161
                        ut_print_timestamp(stderr);
3223
3162
                        fputs("  InnoDB: You are trying to drop table ",
3224
3163
                              stderr);
3225
 
                        ut_print_name(stderr, trx, TRUE, i_table_name);
 
3164
                        ut_print_name(stderr, trx, TRUE, table_name);
3226
3165
                        fputs("\n"
3227
3166
                              "InnoDB: though there is a"
3228
3167
                              " foreign key check running on it.\n"
4010
3949
                an ALTER, not in a RENAME. */
4011
3950
 
4012
3951
                err = dict_load_foreigns(
4013
 
                        new_name, FALSE, !old_is_tmp || trx->check_foreigns);
 
3952
                        new_name, !old_is_tmp || trx->check_foreigns);
4014
3953
 
4015
3954
                if (err != DB_SUCCESS) {
4016
3955
                        ut_print_timestamp(stderr);
4095
4034
 
4096
4035
        *n_rows = 0;
4097
4036
 
4098
 
        buf = static_cast<byte *>(mem_alloc(UNIV_PAGE_SIZE));
 
4037
        buf = mem_alloc(UNIV_PAGE_SIZE);
4099
4038
        heap = mem_heap_create(100);
4100
4039
 
4101
4040
        cnt = 1000;
4196
4135
                                * sizeof *offsets;
4197
4136
 
4198
4137
                        tmp_heap = mem_heap_create(size);
4199
 
                        offsets = static_cast<ulint *>(mem_heap_dup(tmp_heap, offsets, size));
 
4138
                        offsets = mem_heap_dup(tmp_heap, offsets, size);
4200
4139
                }
4201
4140
 
4202
4141
                mem_heap_empty(heap);