~drizzle-trunk/drizzle/development

« back to all changes in this revision

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

  • Committer: Stewart Smith
  • Author(s): Marko Mäkelä, Stewart Smith
  • Date: 2010-11-17 05:52:09 UTC
  • mto: (2021.1.2 build)
  • mto: This revision was merged to the branch mainline in revision 1971.
  • Revision ID: stewart@flamingspork.com-20101117055209-69m035q6h7e1txrc
Merge Revision revid:marko.makela@oracle.com-20100629113248-fvl48lnzr44z94gg from MySQL InnoDB

Original revid:marko.makela@oracle.com-20100629113248-fvl48lnzr44z94gg

Original Authors: Marko Mkel <marko.makela@oracle.com>
Original commit message:
Bug#52199 utf32: mbminlen=4, mbmaxlen=4, type->mbminlen=0, type->mbmaxlen=4

Merge and adjust a forgotten change to fix this bug.
rb://393 approved by Jimmy Yang
  ------------------------------------------------------------------------
  r3794 | marko | 2009-01-07 14:14:53 +0000 (Wed, 07 Jan 2009) | 18 lines

  branches/6.0: Allow the minimum length of a multi-byte character to be
  up to 4 bytes. (Bug #35391)

  dtype_t, dict_col_t: Replace mbminlen:2, mbmaxlen:3 with mbminmaxlen:5.
  In this way, the 5 bits can hold two values of 0..4, and the storage size
  of the fields will not cross the 64-bit boundary.  Encode the values as
  DATA_MBMAX * mbmaxlen + mbminlen.  Define the auxiliary macros
  DB_MBMINLEN(mbminmaxlen), DB_MBMAXLEN(mbminmaxlen), and
  DB_MINMAXLEN(mbminlen, mbmaxlen).

  Try to trim and pad UTF-16 and UTF-32 with spaces as appropriate.

  Alexander Barkov suggested the use of cs->cset->fill(cs, buff, len, 0x20).
  ha_innobase::store_key_val_for_row() now does that, but the added function
  row_mysql_pad_col() does not, because it doesn't have the MySQL TABLE object.

  rb://49 approved by Heikki Tuuri
  ------------------------------------------------------------------------

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
1
/*****************************************************************************
2
2
 
3
 
Copyright (C) 2005, 2010, Innobase Oy. All Rights Reserved.
 
3
Copyright (c) 2005, 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
187
187
        ut_ad(max_tuples <= sizeof(row_merge_block_t));
188
188
        ut_ad(max_tuples < buf_size);
189
189
 
190
 
        buf = static_cast<row_merge_buf_t *>(mem_heap_zalloc(heap, buf_size));
 
190
        buf = mem_heap_zalloc(heap, buf_size);
191
191
        buf->heap = heap;
192
192
        buf->index = index;
193
193
        buf->max_tuples = max_tuples;
194
 
        buf->tuples = static_cast<const dfield_t **>(mem_heap_alloc(heap,
195
 
                                     2 * max_tuples * sizeof *buf->tuples));
 
194
        buf->tuples = mem_heap_alloc(heap,
 
195
                                     2 * max_tuples * sizeof *buf->tuples);
196
196
        buf->tmp_tuples = buf->tuples + max_tuples;
197
197
 
198
198
        return(buf);
287
287
 
288
288
        n_fields = dict_index_get_n_fields(index);
289
289
 
290
 
        entry = static_cast<dfield_t *>(mem_heap_alloc(buf->heap, n_fields * sizeof *entry));
 
290
        entry = mem_heap_alloc(buf->heap, n_fields * sizeof *entry);
291
291
        buf->tuples[buf->n_tuples] = entry;
292
292
        field = entry;
293
293
 
314
314
                } else if (UNIV_LIKELY(!ext)) {
315
315
                } else if (dict_index_is_clust(index)) {
316
316
                        /* Flag externally stored fields. */
317
 
                        const byte*     row_buf = row_ext_lookup(ext, col_no,
 
317
                        const byte*     buf = row_ext_lookup(ext, col_no,
318
318
                                                             &len);
319
 
                        if (UNIV_LIKELY_NULL(row_buf)) {
320
 
                                ut_a(row_buf != field_ref_zero);
 
319
                        if (UNIV_LIKELY_NULL(buf)) {
 
320
                                ut_a(buf != field_ref_zero);
321
321
                                if (i < dict_index_get_n_unique(index)) {
322
 
                                        dfield_set_data(field, row_buf, len);
 
322
                                        dfield_set_data(field, buf, len);
323
323
                                } else {
324
324
                                        dfield_set_ext(field);
325
325
                                        len = dfield_get_len(field);
326
326
                                }
327
327
                        }
328
328
                } else {
329
 
                        const byte*     row_buf = row_ext_lookup(ext, col_no,
 
329
                        const byte*     buf = row_ext_lookup(ext, col_no,
330
330
                                                             &len);
331
 
                        if (UNIV_LIKELY_NULL(row_buf)) {
332
 
                                ut_a(row_buf != field_ref_zero);
333
 
                                dfield_set_data(field, row_buf, len);
 
331
                        if (UNIV_LIKELY_NULL(buf)) {
 
332
                                ut_a(buf != field_ref_zero);
 
333
                                dfield_set_data(field, buf, len);
334
334
                        }
335
335
                }
336
336
 
341
341
                                col->prtype,
342
342
                                col->mbminmaxlen,
343
343
                                ifield->prefix_len,
344
 
                                len, static_cast<const char *>(dfield_get_data(field)));
 
344
                                len, dfield_get_data(field));
345
345
                        dfield_set_len(field, len);
346
346
                }
347
347
 
415
415
/** Structure for reporting duplicate records. */
416
416
struct row_merge_dup_struct {
417
417
        const dict_index_t*     index;          /*!< index being sorted */
418
 
        TABLE*          table;          /*!< MySQL table object */
 
418
        struct TABLE*           table;          /*!< MySQL table object */
419
419
        ulint                   n_dup;          /*!< number of duplicates */
420
420
};
421
421
 
452
452
                               * sizeof *offsets
453
453
                               + sizeof *buf);
454
454
 
455
 
        buf = static_cast<mrec_buf_t *>(mem_heap_alloc(heap, sizeof *buf));
 
455
        buf = mem_heap_alloc(heap, sizeof *buf);
456
456
 
457
457
        tuple = dtuple_from_fields(&tuple_store, entry, n_fields);
458
458
        n_ext = dict_index_is_clust(index) ? dtuple_get_n_ext(tuple) : 0;
650
650
        mem_heap_t*     heap    = mem_heap_create(2 * i * sizeof **offsets1
651
651
                                                  + 3 * sizeof **buf);
652
652
 
653
 
        *buf = static_cast<mrec_buf_t*>(mem_heap_alloc(heap, 3 * sizeof **buf));
654
 
        *offsets1 = static_cast<ulint*>(mem_heap_alloc(heap, i * sizeof **offsets1));
655
 
        *offsets2 = static_cast<ulint*>(mem_heap_alloc(heap, i * sizeof **offsets2));
 
653
        *buf = mem_heap_alloc(heap, 3 * sizeof **buf);
 
654
        *offsets1 = mem_heap_alloc(heap, i * sizeof **offsets1);
 
655
        *offsets2 = mem_heap_alloc(heap, i * sizeof **offsets2);
656
656
 
657
657
        (*offsets1)[0] = (*offsets2)[0] = i;
658
658
        (*offsets1)[1] = (*offsets2)[1] = dict_index_get_n_fields(index);
675
675
        dict_index_t*   index;
676
676
        const char**    column_names;
677
677
 
678
 
        column_names = static_cast<const char **>(mem_alloc(index_def->n_fields * sizeof *column_names));
 
678
        column_names = mem_alloc(index_def->n_fields * sizeof *column_names);
679
679
 
680
680
        for (i = 0; i < index_def->n_fields; ++i) {
681
681
                column_names[i] = index_def->fields[i].field_name;
1130
1130
row_merge_read_clustered_index(
1131
1131
/*===========================*/
1132
1132
        trx_t*                  trx,    /*!< in: transaction */
1133
 
        TABLE*          table,  /*!< in/out: MySQL table object,
 
1133
        struct TABLE*           table,  /*!< in/out: MySQL table object,
1134
1134
                                        for reporting erroneous records */
1135
1135
        const dict_table_t*     old_table,/*!< in: table where rows are
1136
1136
                                        read from */
1165
1165
 
1166
1166
        /* Create and initialize memory for record buffers */
1167
1167
 
1168
 
        merge_buf = static_cast<row_merge_buf_t **>(mem_alloc(n_index * sizeof *merge_buf));
 
1168
        merge_buf = mem_alloc(n_index * sizeof *merge_buf);
1169
1169
 
1170
1170
        for (i = 0; i < n_index; i++) {
1171
1171
                merge_buf[i] = row_merge_buf_create(index[i]);
1192
1192
 
1193
1193
                ut_a(n_cols == dict_table_get_n_cols(new_table));
1194
1194
 
1195
 
                nonnull = static_cast<ulint*>(mem_alloc(n_cols * sizeof *nonnull));
 
1195
                nonnull = mem_alloc(n_cols * sizeof *nonnull);
1196
1196
 
1197
1197
                for (i = 0; i < n_cols; i++) {
1198
1198
                        if (dict_table_get_nth_col(old_table, i)->prtype
1290
1290
                for (i = 0; i < n_index; i++) {
1291
1291
                        row_merge_buf_t*        buf     = merge_buf[i];
1292
1292
                        merge_file_t*           file    = &files[i];
1293
 
                        const dict_index_t*     buf_index       = buf->index;
 
1293
                        const dict_index_t*     index   = buf->index;
1294
1294
 
1295
1295
                        if (UNIV_LIKELY
1296
1296
                            (row && row_merge_buf_add(buf, row, ext))) {
1306
1306
                        Sort them and write to disk. */
1307
1307
 
1308
1308
                        if (buf->n_tuples) {
1309
 
                                if (dict_index_is_unique(buf_index)) {
 
1309
                                if (dict_index_is_unique(index)) {
1310
1310
                                        row_merge_dup_t dup;
1311
1311
                                        dup.index = buf->index;
1312
1312
                                        dup.table = table;
1418
1418
        ulint*                  foffs1, /*!< in/out: offset of second
1419
1419
                                        source list in the file */
1420
1420
        merge_file_t*           of,     /*!< in/out: output file */
1421
 
        TABLE*          table)  /*!< in/out: MySQL table, for
 
1421
        struct TABLE*           table)  /*!< in/out: MySQL table, for
1422
1422
                                        reporting erroneous key value
1423
1423
                                        if applicable */
1424
1424
{
1447
1447
 
1448
1448
        heap = row_merge_heap_create(index, &buf, &offsets0, &offsets1);
1449
1449
 
1450
 
        buf = static_cast<mrec_buf_t *>(mem_heap_alloc(heap, sizeof(mrec_buf_t) * 3));
 
1450
        buf = mem_heap_alloc(heap, sizeof(mrec_buf_t) * 3);
1451
1451
 
1452
1452
        /* Write a record and read the next record.  Split the output
1453
1453
        file in two halves, which can be merged on the following pass. */
1554
1554
#endif /* UNIV_DEBUG */
1555
1555
 
1556
1556
        heap = row_merge_heap_create(index, &buf, &offsets0, &offsets1);
1557
 
        buf = static_cast<mrec_buf_t *>(mem_heap_alloc(heap, sizeof(mrec_buf_t) * 3));
 
1557
        buf = mem_heap_alloc(heap, sizeof(mrec_buf_t) * 3);
1558
1558
 
1559
1559
        /* Write a record and read the next record.  Split the output
1560
1560
        file in two halves, which can be merged on the following pass. */
1605
1605
                                        index entries */
1606
1606
        row_merge_block_t*      block,  /*!< in/out: 3 buffers */
1607
1607
        int*                    tmpfd,  /*!< in/out: temporary file handle */
1608
 
        TABLE*          table,  /*!< in/out: MySQL table, for
 
1608
        struct TABLE*           table,  /*!< in/out: MySQL table, for
1609
1609
                                        reporting erroneous key value
1610
1610
                                        if applicable */
1611
1611
        ulint*                  num_run,/*!< in/out: Number of runs remain
1735
1735
                                        index entries */
1736
1736
        row_merge_block_t*      block,  /*!< in/out: 3 buffers */
1737
1737
        int*                    tmpfd,  /*!< in/out: temporary file handle */
1738
 
        TABLE*          table)  /*!< in/out: MySQL table, for
 
1738
        struct TABLE*           table)  /*!< in/out: MySQL table, for
1739
1739
                                        reporting erroneous key value
1740
1740
                                        if applicable */
1741
1741
{
1813
1813
                (below). */
1814
1814
                data = btr_rec_copy_externally_stored_field(
1815
1815
                        mrec, offsets, zip_size, i, &len, heap);
1816
 
                /* Because we have locked the table, any records
1817
 
                written by incomplete transactions must have been
1818
 
                rolled back already. There must not be any incomplete
1819
 
                BLOB columns. */
1820
 
                ut_a(data);
1821
1816
 
1822
1817
                dfield_set_data(field, data, len);
1823
1818
        }
1869
1864
        {
1870
1865
                ulint i = 1 + REC_OFFS_HEADER_SIZE
1871
1866
                        + dict_index_get_n_fields(index);
1872
 
                offsets = static_cast<ulint *>(mem_heap_alloc(graph_heap, i * sizeof *offsets));
 
1867
                offsets = mem_heap_alloc(graph_heap, i * sizeof *offsets);
1873
1868
                offsets[0] = i;
1874
1869
                offsets[1] = dict_index_get_n_fields(index);
1875
1870
        }
1879
1874
        if (!row_merge_read(fd, foffs, block)) {
1880
1875
                error = DB_CORRUPTION;
1881
1876
        } else {
1882
 
                mrec_buf_t*     buf = static_cast<mrec_buf_t *>(mem_heap_alloc(graph_heap, sizeof *buf));
 
1877
                mrec_buf_t*     buf = mem_heap_alloc(graph_heap, sizeof *buf);
1883
1878
 
1884
1879
                for (;;) {
1885
1880
                        const mrec_t*   mrec;
1977
1972
        /* We use the select query graph as the dummy graph needed
1978
1973
        in the lock module call */
1979
1974
 
1980
 
        thr = que_fork_get_first_thr(static_cast<que_fork_t *>(que_node_get_parent(thr)));
 
1975
        thr = que_fork_get_first_thr(que_node_get_parent(thr));
1981
1976
        que_thr_move_to_run_state_for_mysql(thr, trx);
1982
1977
 
1983
1978
run_again:
2007
2002
                        que_node_t*     parent;
2008
2003
 
2009
2004
                        parent = que_node_get_parent(thr);
2010
 
                        run_thr = que_fork_start_command(static_cast<que_fork_t *>(parent));
 
2005
                        run_thr = que_fork_start_command(parent);
2011
2006
 
2012
2007
                        ut_a(run_thr == thr);
2013
2008
 
2076
2071
        /* Replace this index with another equivalent index for all
2077
2072
        foreign key constraints on this table where this index is used */
2078
2073
 
2079
 
        dict_table_replace_index_in_foreign_list(table, index, trx);
 
2074
        dict_table_replace_index_in_foreign_list(table, index);
2080
2075
        dict_index_remove_from_cache(table, index);
2081
2076
 
2082
2077
        trx->op_info = "";
2464
2459
                goto err_exit;
2465
2460
        }
2466
2461
 
2467
 
        err = dict_load_foreigns(old_name, FALSE, TRUE);
 
2462
        err = dict_load_foreigns(old_name, TRUE);
2468
2463
 
2469
2464
        if (err != DB_SUCCESS) {
2470
2465
err_exit:
2504
2499
        node = ind_create_graph_create(index, heap);
2505
2500
        thr = pars_complete_graph_for_exec(node, trx, heap);
2506
2501
 
2507
 
        ut_a(thr == que_fork_start_command(static_cast<que_fork_t *>(que_node_get_parent(thr))));
 
2502
        ut_a(thr == que_fork_start_command(que_node_get_parent(thr)));
2508
2503
 
2509
2504
        que_run_threads(thr);
2510
2505
 
2637
2632
        /* Allocate memory for merge file data structure and initialize
2638
2633
        fields */
2639
2634
 
2640
 
        merge_files = static_cast<merge_file_t *>(mem_alloc(n_indexes * sizeof *merge_files));
 
2635
        merge_files = mem_alloc(n_indexes * sizeof *merge_files);
2641
2636
        block_size = 3 * sizeof *block;
2642
 
        block = static_cast<row_merge_block_t *>(os_mem_alloc_large(&block_size));
 
2637
        block = os_mem_alloc_large(&block_size);
2643
2638
 
2644
2639
        for (i = 0; i < n_indexes; i++) {
2645
2640