~drizzle-trunk/drizzle/development

« back to all changes in this revision

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

  • Committer: Brian Aker
  • Date: 2010-12-18 10:14:05 UTC
  • mfrom: (2008.1.3 clean)
  • Revision ID: brian@tangent.org-20101218101405-qjbse29shi9coklg
Merge of user identifier work

Show diffs side-by-side

added added

removed removed

Lines of Context:
249
249
}
250
250
 
251
251
/**************************************************************//**
 
252
Pad a column with spaces. */
 
253
UNIV_INTERN
 
254
void
 
255
row_mysql_pad_col(
 
256
/*==============*/
 
257
        ulint   mbminlen,       /*!< in: minimum size of a character,
 
258
                                in bytes */
 
259
        byte*   pad,            /*!< out: padded buffer */
 
260
        ulint   len)            /*!< in: number of bytes to pad */
 
261
{
 
262
        const byte*     pad_end;
 
263
 
 
264
        switch (UNIV_EXPECT(mbminlen, 1)) {
 
265
        default:
 
266
                ut_error;
 
267
        case 1:
 
268
                /* space=0x20 */
 
269
                memset(pad, 0x20, len);
 
270
                break;
 
271
        case 2:
 
272
                /* space=0x0020 */
 
273
                pad_end = pad + len;
 
274
                ut_a(!(len % 2));
 
275
                do {
 
276
                        *pad++ = 0x00;
 
277
                        *pad++ = 0x20;
 
278
                } while (pad < pad_end);
 
279
                break;
 
280
        case 4:
 
281
                /* space=0x00000020 */
 
282
                pad_end = pad + len;
 
283
                ut_a(!(len % 4));
 
284
                do {
 
285
                        *pad++ = 0x00;
 
286
                        *pad++ = 0x00;
 
287
                        *pad++ = 0x00;
 
288
                        *pad++ = 0x20;
 
289
                } while (pad < pad_end);
 
290
                break;
 
291
        }
 
292
}
 
293
 
 
294
/**************************************************************//**
252
295
Stores a non-SQL-NULL field given in the MySQL format in the InnoDB format.
253
296
The counterpart of this function is row_sel_field_store_in_mysql_format() in
254
297
row0sel.c.
340
383
                        /* Remove trailing spaces from old style VARCHAR
341
384
                        columns. */
342
385
 
343
 
                        /* Handle UCS2 strings differently. */
 
386
                        /* Handle Unicode strings differently. */
344
387
                        ulint   mbminlen        = dtype_get_mbminlen(dtype);
345
388
 
346
389
                        ptr = mysql_data;
347
390
 
348
 
                        if (mbminlen == 2) {
 
391
                        switch (mbminlen) {
 
392
                        default:
 
393
                                ut_error;
 
394
                        case 4:
 
395
                                /* space=0x00000020 */
 
396
                                /* Trim "half-chars", just in case. */
 
397
                                col_len &= ~3;
 
398
 
 
399
                                while (col_len >= 4
 
400
                                       && ptr[col_len - 4] == 0x00
 
401
                                       && ptr[col_len - 3] == 0x00
 
402
                                       && ptr[col_len - 2] == 0x00
 
403
                                       && ptr[col_len - 1] == 0x20) {
 
404
                                        col_len -= 4;
 
405
                                }
 
406
                                break;
 
407
                        case 2:
349
408
                                /* space=0x0020 */
350
409
                                /* Trim "half-chars", just in case. */
351
410
                                col_len &= ~1;
354
413
                                       && ptr[col_len - 1] == 0x20) {
355
414
                                        col_len -= 2;
356
415
                                }
357
 
                        } else {
358
 
                                ut_a(mbminlen == 1);
 
416
                                break;
 
417
                        case 1:
359
418
                                /* space=0x20 */
360
419
                                while (col_len > 0
361
420
                                       && ptr[col_len - 1] == 0x20) {
559
618
                      "InnoDB: " REFMAN "forcing-recovery.html"
560
619
                      " for help.\n", stderr);
561
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;
562
628
        default:
563
629
                fprintf(stderr, "InnoDB: unknown error code %lu\n",
564
630
                        (ulong) err);
774
840
        }
775
841
}
776
842
 
 
843
dtuple_t* row_get_prebuilt_insert_row(row_prebuilt_t*   prebuilt);
 
844
 
777
845
/*********************************************************************//**
778
846
Gets pointer to a prebuilt dtuple used in insertions. If the insert graph
779
847
has not yet been built in the prebuilt struct, then this function first
780
848
builds it.
781
849
@return prebuilt dtuple; the column type information is also set in it */
782
 
static
783
850
dtuple_t*
784
851
row_get_prebuilt_insert_row(
785
852
/*========================*/
1364
1431
run_again:
1365
1432
        thr->run_node = node;
1366
1433
        thr->prev_node = node;
 
1434
        thr->fk_cascade_depth = 0;
1367
1435
 
1368
1436
        row_upd_step(thr);
1369
1437
 
 
1438
        /* The recursive call for cascading update/delete happens
 
1439
        in above row_upd_step(), reset the counter once we come
 
1440
        out of the recursive call, so it does not accumulate for
 
1441
        different row deletes */
 
1442
        thr->fk_cascade_depth = 0;
 
1443
 
1370
1444
        err = trx->error_state;
1371
1445
 
 
1446
        /* Reset fk_cascade_depth back to 0 */
 
1447
        thr->fk_cascade_depth = 0;
 
1448
 
1372
1449
        if (err != DB_SUCCESS) {
1373
1450
                que_thr_stop_for_mysql(thr);
1374
1451
 
1405
1482
                srv_n_rows_updated++;
1406
1483
        }
1407
1484
 
1408
 
        row_update_statistics_if_needed(prebuilt->table);
 
1485
        /* We update table statistics only if it is a DELETE or UPDATE
 
1486
        that changes indexed columns, UPDATEs that change only non-indexed
 
1487
        columns would not affect statistics. */
 
1488
        if (node->is_delete || !(node->cmpl_info & UPD_NODE_NO_ORD_CHANGE)) {
 
1489
                row_update_statistics_if_needed(prebuilt->table);
 
1490
        }
1409
1491
 
1410
1492
        trx->op_info = "";
1411
1493
 
1515
1597
                        }
1516
1598
                }
1517
1599
 
1518
 
                if (ut_dulint_cmp(rec_trx_id, trx->id) != 0) {
 
1600
                if (rec_trx_id != trx->id) {
1519
1601
                        /* We did not update the record: unlock it */
1520
1602
 
1521
1603
                        rec = btr_pcur_get_rec(pcur);
1559
1641
        trx_t*  trx;
1560
1642
 
1561
1643
        trx = thr_get_trx(thr);
 
1644
 
 
1645
        /* Increment fk_cascade_depth to record the recursive call depth on
 
1646
        a single update/delete that affects multiple tables chained
 
1647
        together with foreign key relations. */
 
1648
        thr->fk_cascade_depth++;
 
1649
 
 
1650
        if (thr->fk_cascade_depth > FK_MAX_CASCADE_DEL) {
 
1651
                return (DB_FOREIGN_EXCEED_MAX_CASCADE);
 
1652
        }
1562
1653
run_again:
1563
1654
        thr->run_node = node;
1564
1655
        thr->prev_node = node;
1565
1656
 
1566
1657
        row_upd_step(thr);
1567
1658
 
 
1659
        /* The recursive call for cascading update/delete happens
 
1660
        in above row_upd_step(), reset the counter once we come
 
1661
        out of the recursive call, so it does not accumulate for
 
1662
        different row deletes */
 
1663
        thr->fk_cascade_depth = 0;
 
1664
 
1568
1665
        err = trx->error_state;
1569
1666
 
1570
1667
        /* Note that the cascade node is a subnode of another InnoDB
2027
2124
                                              name, reject_fks);
2028
2125
        if (err == DB_SUCCESS) {
2029
2126
                /* Check that also referencing constraints are ok */
2030
 
                err = dict_load_foreigns(name, TRUE);
 
2127
                err = dict_load_foreigns(name, FALSE, TRUE);
2031
2128
        }
2032
2129
 
2033
2130
        if (err != DB_SUCCESS) {
2254
2351
        trx_t*          trx)    /*!< in: transaction handle */
2255
2352
{
2256
2353
        dict_foreign_t* foreign;
2257
 
        dulint          new_id;
 
2354
        table_id_t      new_id;
2258
2355
        dict_table_t*   table;
2259
2356
        ibool           success;
2260
2357
        ulint           err;
2376
2473
        info = pars_info_create();
2377
2474
 
2378
2475
        pars_info_add_str_literal(info, "table_name", name);
2379
 
        pars_info_add_dulint_literal(info, "new_id", new_id);
 
2476
        pars_info_add_ull_literal(info, "new_id", new_id);
2380
2477
 
2381
2478
        err = que_eval_sql(info,
2382
2479
                           "PROCEDURE DISCARD_TABLESPACE_PROC () IS\n"
2590
2687
        dict_index_t*   sys_index;
2591
2688
        btr_pcur_t      pcur;
2592
2689
        mtr_t           mtr;
2593
 
        dulint          new_id;
 
2690
        table_id_t      new_id;
2594
2691
        ulint           recreate_space = 0;
2595
2692
        pars_info_t*    info = NULL;
2596
2693
 
2720
2817
 
2721
2818
        trx->table_id = table->id;
2722
2819
 
 
2820
        /* Lock all index trees for this table, as we will
 
2821
        truncate the table/index and possibly change their metadata.
 
2822
        All DML/DDL are blocked by table level lock, with
 
2823
        a few exceptions such as queries into information schema
 
2824
        about the table, MySQL could try to access index stats
 
2825
        for this kind of query, we need to use index locks to
 
2826
        sync up */
 
2827
        dict_table_x_lock_indexes(table);
 
2828
 
2723
2829
        if (table->space && !table->dir_path_of_temp_table) {
2724
2830
                /* Discard and create the single-table tablespace. */
2725
2831
                ulint   space   = table->space;
2736
2842
                            || fil_create_new_single_table_tablespace(
2737
2843
                                    space, table->name, FALSE, flags,
2738
2844
                                    FIL_IBD_FILE_INITIAL_SIZE) != DB_SUCCESS) {
 
2845
                                dict_table_x_unlock_indexes(table);
2739
2846
                                ut_print_timestamp(stderr);
2740
2847
                                fprintf(stderr,
2741
2848
                                        "  InnoDB: TRUNCATE TABLE %s failed to"
2839
2946
 
2840
2947
        mem_heap_free(heap);
2841
2948
 
 
2949
        /* Done with index truncation, release index tree locks,
 
2950
        subsequent work relates to table level metadata change */
 
2951
        dict_table_x_unlock_indexes(table);
 
2952
 
2842
2953
        dict_hdr_get_new_id(&new_id, NULL, NULL);
2843
2954
 
2844
2955
        info = pars_info_create();
2845
2956
 
2846
2957
        pars_info_add_int4_literal(info, "space", (lint) table->space);
2847
 
        pars_info_add_dulint_literal(info, "old_id", table->id);
2848
 
        pars_info_add_dulint_literal(info, "new_id", new_id);
 
2958
        pars_info_add_ull_literal(info, "old_id", table->id);
 
2959
        pars_info_add_ull_literal(info, "new_id", new_id);
2849
2960
 
2850
2961
        err = que_eval_sql(info,
2851
2962
                           "PROCEDURE RENUMBER_TABLESPACE_PROC () IS\n"
3890
4001
                an ALTER, not in a RENAME. */
3891
4002
 
3892
4003
                err = dict_load_foreigns(
3893
 
                        new_name, !old_is_tmp || trx->check_foreigns);
 
4004
                        new_name, FALSE, !old_is_tmp || trx->check_foreigns);
3894
4005
 
3895
4006
                if (err != DB_SUCCESS) {
3896
4007
                        ut_print_timestamp(stderr);