~drizzle-trunk/drizzle/development

« back to all changes in this revision

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

  • Committer: Brian Aker
  • Date: 2010-12-07 09:12:12 UTC
  • mto: This revision was merged to the branch mainline in revision 1985.
  • Revision ID: brian@tangent.org-20101207091212-1m0w20tck6z7632m
This is a fix for bug lp:686197

Show diffs side-by-side

added added

removed removed

Lines of Context:
2692
2692
        ut_ad(prebuilt->mysql_template);
2693
2693
        ut_ad(prebuilt->default_rec);
2694
2694
        ut_ad(rec_offs_validate(rec, NULL, offsets));
 
2695
        ut_ad(!rec_get_deleted_flag(rec, rec_offs_comp(offsets)));
2695
2696
 
2696
2697
        if (UNIV_LIKELY_NULL(prebuilt->blob_heap)) {
2697
2698
                mem_heap_free(prebuilt->blob_heap);
2698
2699
                prebuilt->blob_heap = NULL;
2699
2700
        }
2700
2701
 
 
2702
        /* init null bytes with default values as they might be
 
2703
        left uninitialized in some cases and these uninited bytes
 
2704
        might be copied into mysql record buffer that leads to
 
2705
        valgrind warnings */
 
2706
        memcpy(mysql_rec, prebuilt->default_rec, prebuilt->null_bitmap_len);
 
2707
 
2701
2708
        for (i = 0; i < prebuilt->n_template ; i++) {
2702
2709
 
2703
2710
                templ = prebuilt->mysql_template + i;
3370
3377
        mem_heap_t*     heap                            = NULL;
3371
3378
        ulint           offsets_[REC_OFFS_NORMAL_SIZE];
3372
3379
        ulint*          offsets                         = offsets_;
3373
 
        ibool           table_lock_waited               = FALSE;
3374
3380
 
3375
3381
        rec_offs_init(offsets_);
3376
3382
 
3601
3607
                                row_sel_try_search_shortcut_for_mysql().
3602
3608
                                The latch will not be released until
3603
3609
                                mtr_commit(&mtr). */
3604
 
                                ut_ad(!rec_get_deleted_flag(rec, comp));
3605
3610
 
3606
3611
                                if (!row_sel_store_mysql_rec(buf, prebuilt,
3607
3612
                                                             rec, offsets)) {
3717
3722
 
3718
3723
        clust_index = dict_table_get_first_index(index->table);
3719
3724
 
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
3725
        if (UNIV_LIKELY(direction != 0)) {
3759
3726
                ibool   need_to_process = sel_restore_position_for_mysql(
3760
3727
                        &same_user_rec, BTR_SEARCH_LEAF,
3830
3797
                }
3831
3798
        }
3832
3799
 
 
3800
        if (!prebuilt->sql_stat_start) {
 
3801
                /* No need to set an intention lock or assign a read view */
 
3802
 
 
3803
                if (trx->read_view == NULL
 
3804
                    && prebuilt->select_lock_type == LOCK_NONE) {
 
3805
 
 
3806
                        fputs("InnoDB: Error: MySQL is trying to"
 
3807
                              " perform a consistent read\n"
 
3808
                              "InnoDB: but the read view is not assigned!\n",
 
3809
                              stderr);
 
3810
                        trx_print(stderr, trx, 600);
 
3811
                        fputc('\n', stderr);
 
3812
                        ut_a(0);
 
3813
                }
 
3814
        } else if (prebuilt->select_lock_type == LOCK_NONE) {
 
3815
                /* This is a consistent read */
 
3816
                /* Assign a read view for the query */
 
3817
 
 
3818
                trx_assign_read_view(trx);
 
3819
                prebuilt->sql_stat_start = FALSE;
 
3820
        } else {
 
3821
                ulint   lock_mode;
 
3822
                if (prebuilt->select_lock_type == LOCK_S) {
 
3823
                        lock_mode = LOCK_IS;
 
3824
                } else {
 
3825
                        lock_mode = LOCK_IX;
 
3826
                }
 
3827
                err = lock_table(0, index->table, lock_mode, thr);
 
3828
 
 
3829
                if (err != DB_SUCCESS) {
 
3830
 
 
3831
                        goto lock_wait_or_error;
 
3832
                }
 
3833
                prebuilt->sql_stat_start = FALSE;
 
3834
        }
 
3835
 
3833
3836
rec_loop:
3834
3837
        /*-------------------------------------------------------------*/
3835
3838
        /* PHASE 4: Look for matching records in a loop */
4245
4248
 
4246
4249
                                rec = old_vers;
4247
4250
                        }
4248
 
                } else {
 
4251
                } else if (!lock_sec_rec_cons_read_sees(rec, trx->read_view)) {
4249
4252
                        /* We are looking into a non-clustered index,
4250
4253
                        and to get the right version of the record we
4251
4254
                        have to look also into the clustered index: this
4253
4256
                        information via the clustered index record. */
4254
4257
 
4255
4258
                        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
 
                        }
 
4259
                        goto requires_clust_rec;
4261
4260
                }
4262
4261
        }
4263
4262
 
4380
4379
                                                  ULINT_UNDEFINED, &heap);
4381
4380
                        result_rec = rec;
4382
4381
                }
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
4382
        } else {
4388
4383
                result_rec = rec;
4389
 
                ut_ad(!rec_get_deleted_flag(rec, comp));
4390
4384
        }
4391
4385
 
4392
4386
        /* We found a qualifying record 'result_rec'. At this point,
4563
4557
 
4564
4558
        btr_pcur_store_position(pcur, &mtr);
4565
4559
 
4566
 
lock_table_wait:
4567
4560
        mtr_commit(&mtr);
4568
4561
        mtr_has_extra_clust_latch = FALSE;
4569
4562
 
4581
4574
                thr->lock_state = QUE_THR_LOCK_NOLOCK;
4582
4575
                mtr_start(&mtr);
4583
4576
 
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
4577
                sel_restore_position_for_mysql(&same_user_rec,
4593
4578
                                               BTR_SEARCH_LEAF, pcur,
4594
4579
                                               moves_up, &mtr);