~drizzle-trunk/drizzle/development

« back to all changes in this revision

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

  • Committer: Patrick Crews
  • Date: 2010-12-07 20:02:50 UTC
  • Revision ID: gleebix@gmail.com-20101207200250-6a27jgqalgw5bsb5
Added disabled.def file to disable drizzleslap due to Bug#684269.  Need to skip for tarball release this round

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
1
/*****************************************************************************
2
2
 
3
 
Copyright (C) 1997, 2010, Innobase Oy. All Rights Reserved.
4
 
Copyright (C) 2008, Google Inc.
 
3
Copyright (c) 1997, 2010, Innobase Oy. All Rights Reserved.
 
4
Copyright (c) 2008, Google Inc.
5
5
 
6
6
Portions of this file contain modifications contributed and copyrighted by
7
7
Google, Inc. Those modifications are gratefully acknowledged and are described
104
104
        ulint   len;
105
105
        byte    buf[DICT_MAX_INDEX_COL_LEN];
106
106
 
107
 
        ut_a(clust_len >= BTR_EXTERN_FIELD_REF_SIZE);
108
 
 
109
 
        if (UNIV_UNLIKELY
110
 
            (!memcmp(clust_field + clust_len - BTR_EXTERN_FIELD_REF_SIZE,
111
 
                     field_ref_zero, BTR_EXTERN_FIELD_REF_SIZE))) {
112
 
                /* The externally stored field was not written yet.
113
 
                This record should only be seen by
114
 
                recv_recovery_rollback_active() or any
115
 
                TRX_ISO_READ_UNCOMMITTED transactions. */
116
 
                return(FALSE);
117
 
        }
118
 
 
119
107
        len = btr_copy_externally_stored_field_prefix(buf, sizeof buf,
120
108
                                                      zip_size,
121
109
                                                      clust_field, clust_len);
258
246
{
259
247
        sel_node_t*     node;
260
248
 
261
 
        node = static_cast<sel_node_t *>(mem_heap_alloc(heap, sizeof(sel_node_t)));
 
249
        node = mem_heap_alloc(heap, sizeof(sel_node_t));
262
250
        node->common.type = QUE_NODE_SELECT;
263
251
        node->state = SEL_NODE_OPEN;
264
252
 
338
326
                eval_node_copy_val(var->alias, exp);
339
327
 
340
328
                exp = que_node_get_next(exp);
341
 
                var = static_cast<sym_node_t *>(que_node_get_next(var));
 
329
                var = que_node_get_next(var);
342
330
        }
343
331
}
344
332
 
355
343
 
356
344
        ut_ad(node->is_aggregate);
357
345
 
358
 
        func_node = static_cast<func_node_t *>(node->select_list);
 
346
        func_node = node->select_list;
359
347
 
360
348
        while (func_node) {
361
349
                eval_node_set_int_val(func_node, 0);
362
350
 
363
 
                func_node = static_cast<func_node_t *>(que_node_get_next(func_node));
 
351
                func_node = que_node_get_next(func_node);
364
352
        }
365
353
 
366
354
        node->aggregate_already_fetched = FALSE;
486
474
 
487
475
        ut_ad(que_node_get_type(column) == QUE_NODE_SYMBOL);
488
476
 
489
 
        column->prefetch_buf = static_cast<sel_buf_t *>(mem_alloc(SEL_MAX_N_PREFETCH
490
 
                                                                  * sizeof(sel_buf_t)));
 
477
        column->prefetch_buf = mem_alloc(SEL_MAX_N_PREFETCH
 
478
                                         * sizeof(sel_buf_t));
491
479
        for (i = 0; i < SEL_MAX_N_PREFETCH; i++) {
492
480
                sel_buf = column->prefetch_buf + i;
493
481
 
566
554
                column values to be able to free it later: therefore
567
555
                we swap the values for sel_buf and val */
568
556
 
569
 
                sel_buf->data = static_cast<byte *>(dfield_get_data(val));
 
557
                sel_buf->data = dfield_get_data(val);
570
558
                sel_buf->len = dfield_get_len(val);
571
559
                sel_buf->val_buf_size = que_node_get_val_buf_size(column);
572
560
 
634
622
 
635
623
                val = que_node_get_val(column);
636
624
 
637
 
                data = static_cast<byte *>(dfield_get_data(val));
 
625
                data = dfield_get_data(val);
638
626
                len = dfield_get_len(val);
639
627
                val_buf_size = que_node_get_val_buf_size(column);
640
628
 
746
734
                /* Evaluate the left side of the comparison, i.e., get the
747
735
                column value if there is an indirection */
748
736
 
749
 
          eval_sym(static_cast<sym_node_t *>(cond->args));
 
737
                eval_sym(cond->args);
750
738
 
751
739
                /* Do the comparison */
752
740
 
882
870
                err = lock_clust_rec_read_check_and_lock(
883
871
                        0, btr_pcur_get_block(&plan->clust_pcur),
884
872
                        clust_rec, index, offsets,
885
 
                        static_cast<lock_mode>(node->row_lock_mode), lock_type, thr);
 
873
                        node->row_lock_mode, lock_type, thr);
886
874
 
887
875
                switch (err) {
888
876
                case DB_SUCCESS:
989
977
        }
990
978
 
991
979
        if (dict_index_is_clust(index)) {
992
 
                err = lock_clust_rec_read_check_and_lock(0, block, rec, index,
993
 
                                                         offsets, static_cast<lock_mode>(mode), type, thr);
 
980
                err = lock_clust_rec_read_check_and_lock(
 
981
                        0, block, rec, index, offsets, mode, type, thr);
994
982
        } else {
995
 
                err = lock_sec_rec_read_check_and_lock(0, block, rec, index,
996
 
                                                       offsets, static_cast<lock_mode>(mode), type, thr);
 
983
                err = lock_sec_rec_read_check_and_lock(
 
984
                        0, block, rec, index, offsets, mode, type, thr);
997
985
        }
998
986
 
999
987
        return(err);
2023
2011
 
2024
2012
        ut_ad(thr);
2025
2013
 
2026
 
        node = static_cast<sel_node_t *>(thr->run_node);
 
2014
        node = thr->run_node;
2027
2015
 
2028
2016
        ut_ad(que_node_get_type(node) == QUE_NODE_SELECT);
2029
2017
 
2060
2048
 
2061
2049
                        while (table_node) {
2062
2050
                                err = lock_table(0, table_node->table,
2063
 
                                                 static_cast<lock_mode>(i_lock_mode), thr);
 
2051
                                                 i_lock_mode, thr);
2064
2052
                                if (err != DB_SUCCESS) {
2065
2053
                                        thr_get_trx(thr)->error_state = err;
2066
2054
 
2067
2055
                                        return(NULL);
2068
2056
                                }
2069
2057
 
2070
 
                                table_node = static_cast<sym_node_t *>(que_node_get_next(table_node));
 
2058
                                table_node = que_node_get_next(table_node);
2071
2059
                        }
2072
2060
                }
2073
2061
 
2124
2112
 
2125
2113
        ut_ad(thr);
2126
2114
 
2127
 
        node = static_cast<fetch_node_t *>(thr->run_node);
 
2115
        node = thr->run_node;
2128
2116
        sel_node = node->cursor_def;
2129
2117
 
2130
2118
        ut_ad(que_node_get_type(node) == QUE_NODE_FETCH);
2183
2171
        void*   row,            /*!< in:  sel_node_t* */
2184
2172
        void*   user_arg)       /*!< in:  not used */
2185
2173
{
2186
 
        sel_node_t *node = static_cast<sel_node_t *>(row);
 
2174
        sel_node_t*     node = row;
2187
2175
        que_node_t*     exp;
2188
2176
        ulint           i = 0;
2189
2177
 
2232
2220
 
2233
2221
        ut_ad(thr);
2234
2222
 
2235
 
        node = static_cast<row_printf_node_t *>(thr->run_node);
 
2223
        node = thr->run_node;
2236
2224
 
2237
2225
        sel_node = node->sel_node;
2238
2226
 
2689
2677
        row_prebuilt_t* prebuilt,       /*!< in: prebuilt struct */
2690
2678
        const rec_t*    rec,            /*!< in: Innobase record in the index
2691
2679
                                        which was described in prebuilt's
2692
 
                                        template, or in the clustered index;
2693
 
                                        must be protected by a page latch */
2694
 
        ibool           rec_clust,      /*!< in: TRUE if rec is in the
2695
 
                                        clustered index instead of
2696
 
                                        prebuilt->index */
 
2680
                                        template; must be protected by
 
2681
                                        a page latch */
2697
2682
        const ulint*    offsets)        /*!< in: array returned by
2698
 
                                        rec_get_offsets(rec) */
 
2683
                                        rec_get_offsets() */
2699
2684
{
2700
 
        mem_heap_t*     extern_field_heap       = NULL;
2701
 
        mem_heap_t*     heap;
2702
 
        ulint           i;
 
2685
        mysql_row_templ_t*      templ;
 
2686
        mem_heap_t*             extern_field_heap       = NULL;
 
2687
        mem_heap_t*             heap;
 
2688
        const byte*             data;
 
2689
        ulint                   len;
 
2690
        ulint                   i;
2703
2691
 
2704
2692
        ut_ad(prebuilt->mysql_template);
2705
2693
        ut_ad(prebuilt->default_rec);
2711
2699
                prebuilt->blob_heap = NULL;
2712
2700
        }
2713
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
 
2714
2708
        for (i = 0; i < prebuilt->n_template ; i++) {
2715
2709
 
2716
 
                const mysql_row_templ_t*templ = prebuilt->mysql_template + i;
2717
 
                const byte*             data;
2718
 
                ulint                   len;
2719
 
                ulint                   field_no;
2720
 
 
2721
 
                field_no = rec_clust
2722
 
                        ? templ->clust_rec_field_no : templ->rec_field_no;
2723
 
 
2724
 
                if (UNIV_UNLIKELY(rec_offs_nth_extern(offsets, field_no))) {
 
2710
                templ = prebuilt->mysql_template + i;
 
2711
 
 
2712
                if (UNIV_UNLIKELY(rec_offs_nth_extern(offsets,
 
2713
                                                      templ->rec_field_no))) {
2725
2714
 
2726
2715
                        /* Copy an externally stored field to the temporary
2727
2716
                        heap */
2749
2738
                        data = btr_rec_copy_externally_stored_field(
2750
2739
                                rec, offsets,
2751
2740
                                dict_table_zip_size(prebuilt->table),
2752
 
                                field_no, &len, heap);
 
2741
                                templ->rec_field_no, &len, heap);
2753
2742
 
2754
2743
                        if (UNIV_UNLIKELY(!data)) {
2755
2744
                                /* The externally stored field
2785
2774
                } else {
2786
2775
                        /* Field is stored in the row. */
2787
2776
 
2788
 
                        data = rec_get_nth_field(rec, offsets, field_no, &len);
 
2777
                        data = rec_get_nth_field(rec, offsets,
 
2778
                                                 templ->rec_field_no, &len);
2789
2779
 
2790
2780
                        if (UNIV_UNLIKELY(templ->type == DATA_BLOB)
2791
2781
                            && len != UNIV_SQL_NULL) {
2801
2791
                                                UNIV_PAGE_SIZE);
2802
2792
                                }
2803
2793
 
2804
 
                                data = static_cast<byte *>(memcpy(mem_heap_alloc(
 
2794
                                data = memcpy(mem_heap_alloc(
2805
2795
                                                prebuilt->blob_heap, len),
2806
 
                                                                  data, len));
 
2796
                                                data, len);
2807
2797
                        }
2808
2798
                }
2809
2799
 
2985
2975
                err = lock_clust_rec_read_check_and_lock(
2986
2976
                        0, btr_pcur_get_block(prebuilt->clust_pcur),
2987
2977
                        clust_rec, clust_index, *offsets,
2988
 
                        static_cast<lock_mode>(prebuilt->select_lock_type),
2989
 
                        LOCK_REC_NOT_GAP, thr);
 
2978
                        prebuilt->select_lock_type, LOCK_REC_NOT_GAP, thr);
2990
2979
                switch (err) {
2991
2980
                case DB_SUCCESS:
2992
2981
                case DB_SUCCESS_LOCKED_REC:
3010
2999
 
3011
3000
                        /* The following call returns 'offsets' associated with
3012
3001
                        'old_vers' */
3013
 
                  err = static_cast<db_err>(row_sel_build_prev_vers_for_mysql(
 
3002
                        err = row_sel_build_prev_vers_for_mysql(
3014
3003
                                trx->read_view, clust_index, prebuilt,
3015
3004
                                clust_rec, offsets, offset_heap, &old_vers,
3016
 
                                mtr));
 
3005
                                mtr);
3017
3006
 
3018
3007
                        if (err != DB_SUCCESS || old_vers == NULL) {
3019
3008
 
3148
3137
        row_prebuilt_t* prebuilt)       /*!< in: prebuilt struct */
3149
3138
{
3150
3139
        ulint                   i;
3151
 
        const mysql_row_templ_t*templ;
 
3140
        mysql_row_templ_t*      templ;
3152
3141
        byte*                   cached_rec;
3153
3142
        ut_ad(prebuilt->n_fetch_cached > 0);
3154
3143
        ut_ad(prebuilt->mysql_prefix_len <= prebuilt->mysql_row_len);
3208
3197
row_sel_push_cache_row_for_mysql(
3209
3198
/*=============================*/
3210
3199
        row_prebuilt_t* prebuilt,       /*!< in: prebuilt struct */
3211
 
        const rec_t*    rec,            /*!< in: record to push, in the index
3212
 
                                        which was described in prebuilt's
3213
 
                                        template, or in the clustered index;
3214
 
                                        must be protected by a page latch */
3215
 
        ibool           rec_clust,      /*!< in: TRUE if rec is in the
3216
 
                                        clustered index instead of
3217
 
                                        prebuilt->index */
3218
 
        const ulint*    offsets)        /*!< in: rec_get_offsets(rec) */
 
3200
        const rec_t*    rec,            /*!< in: record to push; must
 
3201
                                        be protected by a page latch */
 
3202
        const ulint*    offsets)        /*!<in: rec_get_offsets() */
3219
3203
{
3220
3204
        byte*   buf;
3221
3205
        ulint   i;
3222
3206
 
3223
3207
        ut_ad(prebuilt->n_fetch_cached < MYSQL_FETCH_CACHE_SIZE);
3224
3208
        ut_ad(rec_offs_validate(rec, NULL, offsets));
3225
 
        ut_ad(!rec_get_deleted_flag(rec, rec_offs_comp(offsets)));
3226
3209
        ut_a(!prebuilt->templ_contains_blob);
3227
3210
 
3228
3211
        if (prebuilt->fetch_cache[0] == NULL) {
3234
3217
                        buffers in Linux. Put magic numbers there to help
3235
3218
                        to track a possible bug. */
3236
3219
 
3237
 
                        buf = static_cast<byte *>(mem_alloc(prebuilt->mysql_row_len + 8));
 
3220
                        buf = mem_alloc(prebuilt->mysql_row_len + 8);
3238
3221
 
3239
3222
                        prebuilt->fetch_cache[i] = buf + 4;
3240
3223
 
3251
3234
        if (UNIV_UNLIKELY(!row_sel_store_mysql_rec(
3252
3235
                                  prebuilt->fetch_cache[
3253
3236
                                          prebuilt->n_fetch_cached],
3254
 
                                  prebuilt, rec, rec_clust, offsets))) {
 
3237
                                  prebuilt, rec, offsets))) {
3255
3238
                return(FALSE);
3256
3239
        }
3257
3240
 
3394
3377
        mem_heap_t*     heap                            = NULL;
3395
3378
        ulint           offsets_[REC_OFFS_NORMAL_SIZE];
3396
3379
        ulint*          offsets                         = offsets_;
3397
 
        ibool           table_lock_waited               = FALSE;
3398
3380
 
3399
3381
        rec_offs_init(offsets_);
3400
3382
 
3625
3607
                                row_sel_try_search_shortcut_for_mysql().
3626
3608
                                The latch will not be released until
3627
3609
                                mtr_commit(&mtr). */
3628
 
                                ut_ad(!rec_get_deleted_flag(rec, comp));
3629
3610
 
3630
3611
                                if (!row_sel_store_mysql_rec(buf, prebuilt,
3631
 
                                                             rec, FALSE,
3632
 
                                                             offsets)) {
 
3612
                                                             rec, offsets)) {
3633
3613
                                        /* Only fresh inserts may contain
3634
3614
                                        incomplete externally stored
3635
3615
                                        columns. Pretend that such
3742
3722
 
3743
3723
        clust_index = dict_table_get_first_index(index->table);
3744
3724
 
3745
 
        /* Do some start-of-statement preparations */
3746
 
 
3747
 
        if (!prebuilt->sql_stat_start) {
3748
 
                /* No need to set an intention lock or assign a read view */
3749
 
 
3750
 
                if (trx->read_view == NULL
3751
 
                    && prebuilt->select_lock_type == LOCK_NONE) {
3752
 
 
3753
 
                        fputs("InnoDB: Error: MySQL is trying to"
3754
 
                              " perform a consistent read\n"
3755
 
                              "InnoDB: but the read view is not assigned!\n",
3756
 
                              stderr);
3757
 
                        trx_print(stderr, trx, 600);
3758
 
                        fputc('\n', stderr);
3759
 
                        ut_error;
3760
 
                }
3761
 
        } else if (prebuilt->select_lock_type == LOCK_NONE) {
3762
 
                /* This is a consistent read */
3763
 
                /* Assign a read view for the query */
3764
 
 
3765
 
                trx_assign_read_view(trx);
3766
 
                prebuilt->sql_stat_start = FALSE;
3767
 
        } else {
3768
 
wait_table_again:
3769
 
                err = lock_table(0, index->table,
3770
 
                                 prebuilt->select_lock_type == LOCK_S
3771
 
                                 ? LOCK_IS : LOCK_IX, thr);
3772
 
 
3773
 
                if (err != DB_SUCCESS) {
3774
 
 
3775
 
                        table_lock_waited = TRUE;
3776
 
                        goto lock_table_wait;
3777
 
                }
3778
 
                prebuilt->sql_stat_start = FALSE;
3779
 
        }
3780
 
 
3781
 
        /* Open or restore index cursor position */
3782
 
 
3783
3725
        if (UNIV_LIKELY(direction != 0)) {
3784
3726
                ibool   need_to_process = sel_restore_position_for_mysql(
3785
3727
                        &same_user_rec, BTR_SEARCH_LEAF,
3855
3797
                }
3856
3798
        }
3857
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
 
3858
3836
rec_loop:
3859
3837
        /*-------------------------------------------------------------*/
3860
3838
        /* PHASE 4: Look for matching records in a loop */
4270
4248
 
4271
4249
                                rec = old_vers;
4272
4250
                        }
4273
 
                } else {
 
4251
                } else if (!lock_sec_rec_cons_read_sees(rec, trx->read_view)) {
4274
4252
                        /* We are looking into a non-clustered index,
4275
4253
                        and to get the right version of the record we
4276
4254
                        have to look also into the clustered index: this
4277
4255
                        is necessary, because we can only get the undo
4278
4256
                        information via the clustered index record. */
4279
4257
 
4280
 
                        ut_ad(!dict_index_is_clust(index));
4281
 
                        if (!lock_sec_rec_cons_read_sees(
4282
 
                                    rec, trx->read_view)) {
4283
 
                                goto requires_clust_rec;
4284
 
                        }
 
4258
                        ut_ad(index != clust_index);
 
4259
                        goto requires_clust_rec;
4285
4260
                }
4286
4261
        }
4287
4262
 
4391
4366
                        goto next_rec;
4392
4367
                }
4393
4368
 
4394
 
                result_rec = clust_rec;
4395
 
                ut_ad(rec_offs_validate(result_rec, clust_index, offsets));
 
4369
                if (prebuilt->need_to_access_clustered) {
 
4370
 
 
4371
                        result_rec = clust_rec;
 
4372
 
 
4373
                        ut_ad(rec_offs_validate(result_rec, clust_index,
 
4374
                                                offsets));
 
4375
                } else {
 
4376
                        /* We used 'offsets' for the clust rec, recalculate
 
4377
                        them for 'rec' */
 
4378
                        offsets = rec_get_offsets(rec, index, offsets,
 
4379
                                                  ULINT_UNDEFINED, &heap);
 
4380
                        result_rec = rec;
 
4381
                }
4396
4382
        } else {
4397
4383
                result_rec = rec;
4398
4384
        }
4403
4389
        ut_ad(rec_offs_validate(result_rec,
4404
4390
                                result_rec != rec ? clust_index : index,
4405
4391
                                offsets));
4406
 
        ut_ad(!rec_get_deleted_flag(result_rec, comp));
4407
4392
 
4408
4393
        /* At this point, the clustered index record is protected
4409
4394
        by a page latch that was acquired when pcur was positioned.
4427
4412
                cursor. */
4428
4413
 
4429
4414
                if (!row_sel_push_cache_row_for_mysql(prebuilt, result_rec,
4430
 
                                                      result_rec != rec,
4431
4415
                                                      offsets)) {
4432
4416
                        /* Only fresh inserts may contain incomplete
4433
4417
                        externally stored columns. Pretend that such
4445
4429
 
4446
4430
                goto next_rec;
4447
4431
        } else {
4448
 
                if (UNIV_UNLIKELY
4449
 
                    (prebuilt->template_type == ROW_MYSQL_DUMMY_TEMPLATE)) {
4450
 
                        /* CHECK TABLE: fetch the row */
4451
 
 
4452
 
                        if (result_rec != rec
4453
 
                            && !prebuilt->need_to_access_clustered) {
4454
 
                                /* We used 'offsets' for the clust
4455
 
                                rec, recalculate them for 'rec' */
4456
 
                                offsets = rec_get_offsets(rec, index, offsets,
4457
 
                                                          ULINT_UNDEFINED,
4458
 
                                                          &heap);
4459
 
                                result_rec = rec;
4460
 
                        }
4461
 
 
 
4432
                if (prebuilt->template_type == ROW_MYSQL_DUMMY_TEMPLATE) {
4462
4433
                        memcpy(buf + 4, result_rec
4463
4434
                               - rec_offs_extra_size(offsets),
4464
4435
                               rec_offs_size(offsets));
4465
4436
                        mach_write_to_4(buf,
4466
4437
                                        rec_offs_extra_size(offsets) + 4);
4467
4438
                } else {
4468
 
                        /* Returning a row to MySQL */
4469
 
 
4470
 
                        if (!row_sel_store_mysql_rec(buf, prebuilt, result_rec,
4471
 
                                                     result_rec != rec,
4472
 
                                                     offsets)) {
 
4439
                        if (!row_sel_store_mysql_rec(buf, prebuilt,
 
4440
                                                     result_rec, offsets)) {
4473
4441
                                /* Only fresh inserts may contain
4474
4442
                                incomplete externally stored
4475
4443
                                columns. Pretend that such records do
4589
4557
 
4590
4558
        btr_pcur_store_position(pcur, &mtr);
4591
4559
 
4592
 
lock_table_wait:
4593
4560
        mtr_commit(&mtr);
4594
4561
        mtr_has_extra_clust_latch = FALSE;
4595
4562
 
4607
4574
                thr->lock_state = QUE_THR_LOCK_NOLOCK;
4608
4575
                mtr_start(&mtr);
4609
4576
 
4610
 
                /* Table lock waited, go try to obtain table lock
4611
 
                again */
4612
 
                if (table_lock_waited) {
4613
 
                        table_lock_waited = FALSE;
4614
 
 
4615
 
                        goto wait_table_again;
4616
 
                }
4617
 
 
4618
4577
                sel_restore_position_for_mysql(&same_user_rec,
4619
4578
                                               BTR_SEARCH_LEAF, pcur,
4620
4579
                                               moves_up, &mtr);