~drizzle-trunk/drizzle/development

« back to all changes in this revision

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

  • Committer: Brian Aker
  • Date: 2010-11-30 00:29:39 UTC
  • mto: (1965.2.2 build)
  • mto: This revision was merged to the branch mainline in revision 1966.
  • Revision ID: brian@tangent.org-20101130002939-8bzz3xpa0aapbq2w
Fix sleep() so that a kill command will kill it.

Show diffs side-by-side

added added

removed removed

Lines of Context:
88
88
/*========================*/
89
89
        ulint           mtype,          /*!< in: main type */
90
90
        ulint           prtype,         /*!< in: precise type */
91
 
        ulint           mbminmaxlen,    /*!< in: minimum and maximum length of
92
 
                                        a multi-byte character */
 
91
        ulint           mbminlen,       /*!< in: minimum length of a
 
92
                                        multi-byte character */
 
93
        ulint           mbmaxlen,       /*!< in: maximum length of a
 
94
                                        multi-byte character */
93
95
        const byte*     clust_field,    /*!< in: the locally stored part of
94
96
                                        the clustered index column, including
95
97
                                        the BLOB pointer; the clustered
117
119
                return(FALSE);
118
120
        }
119
121
 
120
 
        len = dtype_get_at_most_n_mbchars(prtype, mbminmaxlen,
 
122
        len = dtype_get_at_most_n_mbchars(prtype, mbminlen, mbmaxlen,
121
123
                                          sec_len, len, (const char*) buf);
122
124
 
123
125
        return(!cmp_data_data(mtype, prtype, buf, len, sec_field, sec_len));
200
202
                        }
201
203
 
202
204
                        len = dtype_get_at_most_n_mbchars(
203
 
                                col->prtype, col->mbminmaxlen,
 
205
                                col->prtype, col->mbminlen, col->mbmaxlen,
204
206
                                ifield->prefix_len, len, (char*) clust_field);
205
207
 
206
208
                        if (rec_offs_nth_extern(clust_offs, clust_pos)
207
209
                            && len < sec_len) {
208
210
                                if (!row_sel_sec_rec_is_for_blob(
209
211
                                            col->mtype, col->prtype,
210
 
                                            col->mbminmaxlen,
 
212
                                            col->mbminlen, col->mbmaxlen,
211
213
                                            clust_field, clust_len,
212
214
                                            sec_field, sec_len,
213
215
                                            dict_table_zip_size(
1729
1731
                                            &mtr);
1730
1732
                mtr_has_extra_clust_latch = TRUE;
1731
1733
 
1732
 
                switch (err) {
1733
 
                case DB_SUCCESS_LOCKED_REC:
1734
 
                        err = DB_SUCCESS;
1735
 
                case DB_SUCCESS:
1736
 
                        break;
1737
 
                default:
 
1734
                if (err != DB_SUCCESS) {
 
1735
 
1738
1736
                        goto lock_wait_or_error;
1739
1737
                }
1740
1738
 
1919
1917
                        thr->run_node = que_node_get_parent(node);
1920
1918
                }
1921
1919
 
1922
 
                err = DB_SUCCESS;
1923
1920
                goto func_exit;
1924
1921
        }
1925
1922
 
2077
2074
                        /* Reset the aggregate total values */
2078
2075
                        sel_reset_aggregate_vals(node);
2079
2076
                }
2080
 
 
2081
 
                err = DB_SUCCESS;
2082
2077
        }
2083
2078
 
2084
2079
        err = row_sel(node, thr);
2532
2527
        ulint           len)    /*!< in: length of the data */
2533
2528
{
2534
2529
        byte*   ptr;
 
2530
        byte*   field_end;
 
2531
        byte*   pad_ptr;
2535
2532
 
2536
2533
        ut_ad(len != UNIV_SQL_NULL);
2537
2534
        UNIV_MEM_ASSERT_RW(data, len);
2538
2535
 
2539
2536
        switch (templ->type) {
2540
 
                const byte*     field_end;
2541
 
                byte*           pad;
2542
2537
        case DATA_INT:
2543
2538
                /* Convert integer data from Innobase to a little-endian
2544
2539
                format, sign bit restored to normal */
2582
2577
                unused end of a >= 5.0.3 true VARCHAR column, just in case
2583
2578
                MySQL expects its contents to be deterministic. */
2584
2579
 
2585
 
                pad = dest + len;
 
2580
                pad_ptr = dest + len;
2586
2581
 
2587
2582
                ut_ad(templ->mbminlen <= templ->mbmaxlen);
2588
2583
 
2589
 
                /* We treat some Unicode charset strings specially. */
2590
 
                switch (templ->mbminlen) {
2591
 
                case 4:
2592
 
                        /* InnoDB should never have stripped partial
2593
 
                        UTF-32 characters. */
2594
 
                        ut_a(!(len & 3));
2595
 
                        break;
2596
 
                case 2:
2597
 
                        /* A space char is two bytes,
2598
 
                        0x0020 in UCS2 and UTF-16 */
 
2584
                /* We handle UCS2 charset strings differently. */
 
2585
                if (templ->mbminlen == 2) {
 
2586
                        /* A space char is two bytes, 0x0020 in UCS2 */
2599
2587
 
2600
 
                        if (UNIV_UNLIKELY(len & 1)) {
 
2588
                        if (len & 1) {
2601
2589
                                /* A 0x20 has been stripped from the column.
2602
2590
                                Pad it back. */
2603
2591
 
2604
 
                                if (pad < field_end) {
2605
 
                                        *pad++ = 0x20;
 
2592
                                if (pad_ptr < field_end) {
 
2593
                                        *pad_ptr = 0x20;
 
2594
                                        pad_ptr++;
2606
2595
                                }
2607
2596
                        }
 
2597
 
 
2598
                        /* Pad the rest of the string with 0x0020 */
 
2599
 
 
2600
                        while (pad_ptr < field_end) {
 
2601
                                *pad_ptr = 0x00;
 
2602
                                pad_ptr++;
 
2603
                                *pad_ptr = 0x20;
 
2604
                                pad_ptr++;
 
2605
                        }
 
2606
                } else {
 
2607
                        ut_ad(templ->mbminlen == 1);
 
2608
                        /* space=0x20 */
 
2609
 
 
2610
                        memset(pad_ptr, 0x20, field_end - pad_ptr);
2608
2611
                }
2609
 
 
2610
 
                row_mysql_pad_col(templ->mbminlen, pad, field_end - pad);
2611
2612
                break;
2612
2613
 
2613
2614
        case DATA_BLOB:
2632
2633
                      || !(templ->mysql_col_len % templ->mbmaxlen));
2633
2634
                ut_ad(len * templ->mbmaxlen >= templ->mysql_col_len);
2634
2635
 
2635
 
                if (templ->mbminlen == 1 && templ->mbmaxlen != 1) {
 
2636
                if (templ->mbminlen != templ->mbmaxlen) {
2636
2637
                        /* Pad with spaces. This undoes the stripping
2637
 
                        done in row0mysql.c, function
 
2638
                        done in row0mysql.ic, function
2638
2639
                        row_mysql_store_col_in_innobase_format(). */
2639
2640
 
2640
2641
                        memset(dest + len, 0x20, templ->mysql_col_len - len);
2692
2693
        ut_ad(prebuilt->mysql_template);
2693
2694
        ut_ad(prebuilt->default_rec);
2694
2695
        ut_ad(rec_offs_validate(rec, NULL, offsets));
 
2696
        ut_ad(!rec_get_deleted_flag(rec, rec_offs_comp(offsets)));
2695
2697
 
2696
2698
        if (UNIV_LIKELY_NULL(prebuilt->blob_heap)) {
2697
2699
                mem_heap_free(prebuilt->blob_heap);
2698
2700
                prebuilt->blob_heap = NULL;
2699
2701
        }
2700
2702
 
 
2703
        /* init null bytes with default values as they might be
 
2704
        left uninitialized in some cases and these uninited bytes
 
2705
        might be copied into mysql record buffer that leads to
 
2706
        valgrind warnings */
 
2707
        memcpy(mysql_rec, prebuilt->default_rec, prebuilt->null_bitmap_len);
 
2708
 
2701
2709
        for (i = 0; i < prebuilt->n_template ; i++) {
2702
2710
 
2703
2711
                templ = prebuilt->mysql_template + i;
2748
2756
                                return(FALSE);
2749
2757
                        }
2750
2758
 
2751
 
                        if (UNIV_UNLIKELY(!data)) {
2752
 
                                /* The externally stored field
2753
 
                                was not written yet. This
2754
 
                                record should only be seen by
2755
 
                                recv_recovery_rollback_active()
2756
 
                                or any TRX_ISO_READ_UNCOMMITTED
2757
 
                                transactions. */
2758
 
 
2759
 
                                if (extern_field_heap) {
2760
 
                                        mem_heap_free(extern_field_heap);
2761
 
                                }
2762
 
 
2763
 
                                return(FALSE);
2764
 
                        }
2765
 
 
2766
2759
                        ut_a(len != UNIV_SQL_NULL);
2767
2760
                } else {
2768
2761
                        /* Field is stored in the row. */
3370
3363
        mem_heap_t*     heap                            = NULL;
3371
3364
        ulint           offsets_[REC_OFFS_NORMAL_SIZE];
3372
3365
        ulint*          offsets                         = offsets_;
3373
 
        ibool           table_lock_waited               = FALSE;
3374
3366
 
3375
3367
        rec_offs_init(offsets_);
3376
3368
 
3601
3593
                                row_sel_try_search_shortcut_for_mysql().
3602
3594
                                The latch will not be released until
3603
3595
                                mtr_commit(&mtr). */
3604
 
                                ut_ad(!rec_get_deleted_flag(rec, comp));
3605
3596
 
3606
3597
                                if (!row_sel_store_mysql_rec(buf, prebuilt,
3607
3598
                                                             rec, offsets)) {
3717
3708
 
3718
3709
        clust_index = dict_table_get_first_index(index->table);
3719
3710
 
3720
 
        /* Do some start-of-statement preparations */
3721
 
 
3722
 
        if (!prebuilt->sql_stat_start) {
3723
 
                /* No need to set an intention lock or assign a read view */
3724
 
 
3725
 
                if (trx->read_view == NULL
3726
 
                    && prebuilt->select_lock_type == LOCK_NONE) {
3727
 
 
3728
 
                        fputs("InnoDB: Error: MySQL is trying to"
3729
 
                              " perform a consistent read\n"
3730
 
                              "InnoDB: but the read view is not assigned!\n",
3731
 
                              stderr);
3732
 
                        trx_print(stderr, trx, 600);
3733
 
                        fputc('\n', stderr);
3734
 
                        ut_error;
3735
 
                }
3736
 
        } else if (prebuilt->select_lock_type == LOCK_NONE) {
3737
 
                /* This is a consistent read */
3738
 
                /* Assign a read view for the query */
3739
 
 
3740
 
                trx_assign_read_view(trx);
3741
 
                prebuilt->sql_stat_start = FALSE;
3742
 
        } else {
3743
 
wait_table_again:
3744
 
                err = lock_table(0, index->table,
3745
 
                                 prebuilt->select_lock_type == LOCK_S
3746
 
                                 ? LOCK_IS : LOCK_IX, thr);
3747
 
 
3748
 
                if (err != DB_SUCCESS) {
3749
 
 
3750
 
                        table_lock_waited = TRUE;
3751
 
                        goto lock_table_wait;
3752
 
                }
3753
 
                prebuilt->sql_stat_start = FALSE;
3754
 
        }
3755
 
 
3756
 
        /* Open or restore index cursor position */
3757
 
 
3758
3711
        if (UNIV_LIKELY(direction != 0)) {
3759
3712
                ibool   need_to_process = sel_restore_position_for_mysql(
3760
3713
                        &same_user_rec, BTR_SEARCH_LEAF,
3830
3783
                }
3831
3784
        }
3832
3785
 
 
3786
        if (!prebuilt->sql_stat_start) {
 
3787
                /* No need to set an intention lock or assign a read view */
 
3788
 
 
3789
                if (trx->read_view == NULL
 
3790
                    && prebuilt->select_lock_type == LOCK_NONE) {
 
3791
 
 
3792
                        fputs("InnoDB: Error: MySQL is trying to"
 
3793
                              " perform a consistent read\n"
 
3794
                              "InnoDB: but the read view is not assigned!\n",
 
3795
                              stderr);
 
3796
                        trx_print(stderr, trx, 600);
 
3797
                        fputc('\n', stderr);
 
3798
                        ut_a(0);
 
3799
                }
 
3800
        } else if (prebuilt->select_lock_type == LOCK_NONE) {
 
3801
                /* This is a consistent read */
 
3802
                /* Assign a read view for the query */
 
3803
 
 
3804
                trx_assign_read_view(trx);
 
3805
                prebuilt->sql_stat_start = FALSE;
 
3806
        } else {
 
3807
                ulint   lock_mode;
 
3808
                if (prebuilt->select_lock_type == LOCK_S) {
 
3809
                        lock_mode = LOCK_IS;
 
3810
                } else {
 
3811
                        lock_mode = LOCK_IX;
 
3812
                }
 
3813
                err = lock_table(0, index->table, lock_mode, thr);
 
3814
 
 
3815
                if (err != DB_SUCCESS) {
 
3816
 
 
3817
                        goto lock_wait_or_error;
 
3818
                }
 
3819
                prebuilt->sql_stat_start = FALSE;
 
3820
        }
 
3821
 
3833
3822
rec_loop:
3834
3823
        /*-------------------------------------------------------------*/
3835
3824
        /* PHASE 4: Look for matching records in a loop */
4153
4142
                                clust_index, prebuilt, rec,
4154
4143
                                &offsets, &heap, &old_vers, &mtr);
4155
4144
 
4156
 
                        switch (err) {
4157
 
                        case DB_SUCCESS_LOCKED_REC:
4158
 
                                err = DB_SUCCESS;
4159
 
                        case DB_SUCCESS:
4160
 
                                break;
4161
 
                        default:
 
4145
                        if (err != DB_SUCCESS) {
 
4146
 
4162
4147
                                goto lock_wait_or_error;
4163
4148
                        }
4164
4149
 
4228
4213
                                        prebuilt, rec, &offsets, &heap,
4229
4214
                                        &old_vers, &mtr);
4230
4215
 
4231
 
                                switch (err) {
4232
 
                                case DB_SUCCESS_LOCKED_REC:
4233
 
                                case DB_SUCCESS:
4234
 
                                        break;
4235
 
                                default:
 
4216
                                if (err != DB_SUCCESS) {
 
4217
 
4236
4218
                                        goto lock_wait_or_error;
4237
4219
                                }
4238
4220
 
4245
4227
 
4246
4228
                                rec = old_vers;
4247
4229
                        }
4248
 
                } else {
 
4230
                } else if (!lock_sec_rec_cons_read_sees(rec, trx->read_view)) {
4249
4231
                        /* We are looking into a non-clustered index,
4250
4232
                        and to get the right version of the record we
4251
4233
                        have to look also into the clustered index: this
4253
4235
                        information via the clustered index record. */
4254
4236
 
4255
4237
                        ut_ad(index != clust_index);
4256
 
                        ut_ad(!dict_index_is_clust(index));
4257
 
                        if (!lock_sec_rec_cons_read_sees(
4258
 
                                    rec, trx->read_view)) {
4259
 
                                goto requires_clust_rec;
4260
 
                        }
 
4238
                        goto requires_clust_rec;
4261
4239
                }
4262
4240
        }
4263
4241
 
4380
4358
                                                  ULINT_UNDEFINED, &heap);
4381
4359
                        result_rec = rec;
4382
4360
                }
4383
 
 
4384
 
                /* result_rec can legitimately be delete-marked
4385
 
                now that it has been established that it points to a
4386
 
                clustered index record that exists in the read view. */
4387
4361
        } else {
4388
4362
                result_rec = rec;
4389
 
                ut_ad(!rec_get_deleted_flag(rec, comp));
4390
4363
        }
4391
4364
 
4392
4365
        /* We found a qualifying record 'result_rec'. At this point,
4563
4536
 
4564
4537
        btr_pcur_store_position(pcur, &mtr);
4565
4538
 
4566
 
lock_table_wait:
4567
4539
        mtr_commit(&mtr);
4568
4540
        mtr_has_extra_clust_latch = FALSE;
4569
4541
 
4581
4553
                thr->lock_state = QUE_THR_LOCK_NOLOCK;
4582
4554
                mtr_start(&mtr);
4583
4555
 
4584
 
                /* Table lock waited, go try to obtain table lock
4585
 
                again */
4586
 
                if (table_lock_waited) {
4587
 
                        table_lock_waited = FALSE;
4588
 
 
4589
 
                        goto wait_table_again;
4590
 
                }
4591
 
 
4592
4556
                sel_restore_position_for_mysql(&same_user_rec,
4593
4557
                                               BTR_SEARCH_LEAF, pcur,
4594
4558
                                               moves_up, &mtr);
4707
4671
        IX type locks actually would require ret = FALSE. */
4708
4672
 
4709
4673
        if (UT_LIST_GET_LEN(table->locks) == 0
4710
 
            && trx->id >= table->query_cache_inv_trx_id) {
 
4674
            && ut_dulint_cmp(trx->id,
 
4675
                             table->query_cache_inv_trx_id) >= 0) {
4711
4676
 
4712
4677
                ret = TRUE;
4713
4678