~drizzle-trunk/drizzle/development

« back to all changes in this revision

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

Merge initial InnoDB+ import.

This was applied by generating a patch between MySQL 5.1.50 InnoDB plugin and
the just-merged innodb+ from mysql-trunk revision-id: vasil.dimov@oracle.com-20100422110752-1zowoqxel5xx3z2e

Then, some manual merge resolving and it worked. This should make it much
easier to merge the rest of InnoDB 1.1 and 1.2 from the mysql tree using
my bzr-reapply script.

This takes us to InnoDB 1.1.1(ish).

Show diffs side-by-side

added added

removed removed

Lines of Context:
416
416
                                                              field_no))) {
417
417
 
418
418
                                /* Copy an externally stored field to the
419
 
                                temporary heap, if possible. */
 
419
                                temporary heap */
420
420
 
421
421
                                heap = mem_heap_create(1);
422
422
 
425
425
                                        dict_table_zip_size(index->table),
426
426
                                        field_no, &len, heap);
427
427
 
428
 
                                /* data == NULL means that the
429
 
                                externally stored field was not
430
 
                                written yet. This record
431
 
                                should only be seen by
432
 
                                recv_recovery_rollback_active() or any
433
 
                                TRX_ISO_READ_UNCOMMITTED
434
 
                                transactions. The InnoDB SQL parser
435
 
                                (the sole caller of this function)
436
 
                                does not implement READ UNCOMMITTED,
437
 
                                and it is not involved during rollback. */
438
 
                                ut_a(data);
439
428
                                ut_a(len != UNIV_SQL_NULL);
440
429
 
441
430
                                needs_copy = TRUE;
863
852
                trx = thr_get_trx(thr);
864
853
 
865
854
                if (srv_locks_unsafe_for_binlog
866
 
                    || trx->isolation_level <= TRX_ISO_READ_COMMITTED) {
 
855
                    || trx->isolation_level == TRX_ISO_READ_COMMITTED) {
867
856
                        lock_type = LOCK_REC_NOT_GAP;
868
857
                } else {
869
858
                        lock_type = LOCK_ORDINARY;
874
863
                        clust_rec, index, offsets,
875
864
                        node->row_lock_mode, lock_type, thr);
876
865
 
877
 
                switch (err) {
878
 
                case DB_SUCCESS:
879
 
                case DB_SUCCESS_LOCKED_REC:
880
 
                        /* Declare the variable uninitialized in Valgrind.
881
 
                        It should be set to DB_SUCCESS at func_exit. */
882
 
                        UNIV_MEM_INVALID(&err, sizeof err);
883
 
                        break;
884
 
                default:
 
866
                if (err != DB_SUCCESS) {
 
867
 
885
868
                        goto err_exit;
886
869
                }
887
870
        } else {
937
920
        when plan->clust_pcur was positioned.  The latch will not be
938
921
        released until mtr_commit(mtr). */
939
922
 
940
 
        ut_ad(!rec_get_deleted_flag(clust_rec, rec_offs_comp(offsets)));
941
923
        row_sel_fetch_columns(index, clust_rec, offsets,
942
924
                              UT_LIST_GET_FIRST(plan->columns));
943
925
        *out_rec = clust_rec;
952
934
 
953
935
/*********************************************************************//**
954
936
Sets a lock on a record.
955
 
@return DB_SUCCESS, DB_SUCCESS_LOCKED_REC, or error code */
 
937
@return DB_SUCCESS or error code */
956
938
UNIV_INLINE
957
 
enum db_err
 
939
ulint
958
940
sel_set_rec_lock(
959
941
/*=============*/
960
942
        const buf_block_t*      block,  /*!< in: buffer block of rec */
966
948
                                        LOC_REC_NOT_GAP */
967
949
        que_thr_t*              thr)    /*!< in: query thread */
968
950
{
969
 
        trx_t*          trx;
970
 
        enum db_err     err;
 
951
        trx_t*  trx;
 
952
        ulint   err;
971
953
 
972
954
        trx = thr_get_trx(thr);
973
955
 
1483
1465
 
1484
1466
                        if (srv_locks_unsafe_for_binlog
1485
1467
                            || trx->isolation_level
1486
 
                            <= TRX_ISO_READ_COMMITTED) {
 
1468
                            == TRX_ISO_READ_COMMITTED) {
1487
1469
 
1488
1470
                                if (page_rec_is_supremum(next_rec)) {
1489
1471
 
1500
1482
                                               node->row_lock_mode,
1501
1483
                                               lock_type, thr);
1502
1484
 
1503
 
                        switch (err) {
1504
 
                        case DB_SUCCESS_LOCKED_REC:
1505
 
                                err = DB_SUCCESS;
1506
 
                        case DB_SUCCESS:
1507
 
                                break;
1508
 
                        default:
 
1485
                        if (err != DB_SUCCESS) {
1509
1486
                                /* Note that in this case we will store in pcur
1510
1487
                                the PREDECESSOR of the record we are waiting
1511
1488
                                the lock for */
 
1489
 
1512
1490
                                goto lock_wait_or_error;
1513
1491
                        }
1514
1492
                }
1544
1522
                trx = thr_get_trx(thr);
1545
1523
 
1546
1524
                if (srv_locks_unsafe_for_binlog
1547
 
                    || trx->isolation_level <= TRX_ISO_READ_COMMITTED) {
 
1525
                    || trx->isolation_level == TRX_ISO_READ_COMMITTED) {
1548
1526
 
1549
1527
                        if (page_rec_is_supremum(rec)) {
1550
1528
 
1560
1538
                                       rec, index, offsets,
1561
1539
                                       node->row_lock_mode, lock_type, thr);
1562
1540
 
1563
 
                switch (err) {
1564
 
                case DB_SUCCESS_LOCKED_REC:
1565
 
                        err = DB_SUCCESS;
1566
 
                case DB_SUCCESS:
1567
 
                        break;
1568
 
                default:
 
1541
                if (err != DB_SUCCESS) {
 
1542
 
1569
1543
                        goto lock_wait_or_error;
1570
1544
                }
1571
1545
        }
1640
1614
                                }
1641
1615
 
1642
1616
                                if (old_vers == NULL) {
1643
 
                                        /* The record does not exist
1644
 
                                        in our read view. Skip it, but
1645
 
                                        first attempt to determine
1646
 
                                        whether the index segment we
1647
 
                                        are searching through has been
1648
 
                                        exhausted. */
1649
 
 
1650
1617
                                        offsets = rec_get_offsets(
1651
1618
                                                rec, index, offsets,
1652
1619
                                                ULINT_UNDEFINED, &heap);
2531
2498
        byte*   pad_ptr;
2532
2499
 
2533
2500
        ut_ad(len != UNIV_SQL_NULL);
2534
 
        UNIV_MEM_ASSERT_RW(data, len);
2535
2501
 
2536
2502
        switch (templ->type) {
2537
2503
        case DATA_INT:
2666
2632
Note that the template in prebuilt may advise us to copy only a few
2667
2633
columns to mysql_rec, other columns are left blank. All columns may not
2668
2634
be needed in the query.
2669
 
@return TRUE on success, FALSE if not all columns could be retrieved */
2670
 
static __attribute__((warn_unused_result))
 
2635
@return TRUE if success, FALSE if could not allocate memory for a BLOB
 
2636
(though we may also assert in that case) */
 
2637
static
2671
2638
ibool
2672
2639
row_sel_store_mysql_rec(
2673
2640
/*====================*/
2690
2657
        ut_ad(prebuilt->mysql_template);
2691
2658
        ut_ad(prebuilt->default_rec);
2692
2659
        ut_ad(rec_offs_validate(rec, NULL, offsets));
2693
 
        ut_ad(!rec_get_deleted_flag(rec, rec_offs_comp(offsets)));
2694
2660
 
2695
2661
        if (UNIV_LIKELY_NULL(prebuilt->blob_heap)) {
2696
2662
                mem_heap_free(prebuilt->blob_heap);
2697
2663
                prebuilt->blob_heap = NULL;
2698
2664
        }
2699
2665
 
2700
 
        /* init null bytes with default values as they might be
2701
 
        left uninitialized in some cases and this uninited bytes
2702
 
        might be copied into mysql record buffer that leads to
2703
 
        valgrind warnings */
2704
 
        memcpy(mysql_rec, prebuilt->default_rec, prebuilt->null_bitmap_len);
2705
 
 
2706
2666
        for (i = 0; i < prebuilt->n_template ; i++) {
2707
2667
 
2708
2668
                templ = prebuilt->mysql_template + i;
2738
2698
                                dict_table_zip_size(prebuilt->table),
2739
2699
                                templ->rec_field_no, &len, heap);
2740
2700
 
2741
 
                        if (UNIV_UNLIKELY(!data)) {
2742
 
                                /* The externally stored field
2743
 
                                was not written yet. This
2744
 
                                record should only be seen by
2745
 
                                recv_recovery_rollback_active()
2746
 
                                or any TRX_ISO_READ_UNCOMMITTED
2747
 
                                transactions. */
2748
 
 
2749
 
                                if (extern_field_heap) {
2750
 
                                        mem_heap_free(extern_field_heap);
2751
 
                                }
2752
 
 
2753
 
                                return(FALSE);
2754
 
                        }
2755
 
 
2756
2701
                        ut_a(len != UNIV_SQL_NULL);
2757
2702
                } else {
2758
2703
                        /* Field is stored in the row. */
2801
2746
                        /* MySQL assumes that the field for an SQL
2802
2747
                        NULL value is set to the default value. */
2803
2748
 
2804
 
                        UNIV_MEM_ASSERT_RW(prebuilt->default_rec
2805
 
                                           + templ->mysql_col_offset,
2806
 
                                           templ->mysql_col_len);
2807
2749
                        mysql_rec[templ->mysql_null_byte_offset]
2808
2750
                                |= (byte) templ->mysql_null_bit_mask;
2809
2751
                        memcpy(mysql_rec + templ->mysql_col_offset,
2855
2797
Retrieves the clustered index record corresponding to a record in a
2856
2798
non-clustered index. Does the necessary locking. Used in the MySQL
2857
2799
interface.
2858
 
@return DB_SUCCESS, DB_SUCCESS_LOCKED_REC, or error code */
 
2800
@return DB_SUCCESS or error code */
2859
2801
static
2860
 
enum db_err
 
2802
ulint
2861
2803
row_sel_get_clust_rec_for_mysql(
2862
2804
/*============================*/
2863
2805
        row_prebuilt_t* prebuilt,/*!< in: prebuilt struct in the handle */
2884
2826
        dict_index_t*   clust_index;
2885
2827
        const rec_t*    clust_rec;
2886
2828
        rec_t*          old_vers;
2887
 
        enum db_err     err;
 
2829
        ulint           err;
2888
2830
        trx_t*          trx;
2889
2831
 
2890
2832
        *out_rec = NULL;
2943
2885
 
2944
2886
                clust_rec = NULL;
2945
2887
 
2946
 
                err = DB_SUCCESS;
2947
2888
                goto func_exit;
2948
2889
        }
2949
2890
 
2959
2900
                        0, btr_pcur_get_block(prebuilt->clust_pcur),
2960
2901
                        clust_rec, clust_index, *offsets,
2961
2902
                        prebuilt->select_lock_type, LOCK_REC_NOT_GAP, thr);
2962
 
                switch (err) {
2963
 
                case DB_SUCCESS:
2964
 
                case DB_SUCCESS_LOCKED_REC:
2965
 
                        break;
2966
 
                default:
 
2903
                if (err != DB_SUCCESS) {
 
2904
 
2967
2905
                        goto err_exit;
2968
2906
                }
2969
2907
        } else {
3023
2961
                                     rec, sec_index, clust_rec, clust_index));
3024
2962
#endif
3025
2963
                }
3026
 
 
3027
 
                err = DB_SUCCESS;
3028
2964
        }
3029
2965
 
3030
2966
func_exit:
3037
2973
                btr_pcur_store_position(prebuilt->clust_pcur, mtr);
3038
2974
        }
3039
2975
 
 
2976
        err = DB_SUCCESS;
3040
2977
err_exit:
3041
2978
        return(err);
3042
2979
}
3133
3070
 
3134
3071
                for (i = 0; i < prebuilt->n_template; i++) {
3135
3072
                        templ = prebuilt->mysql_template + i;
3136
 
#if 0 /* Some of the cached_rec may legitimately be uninitialized. */
3137
 
                        UNIV_MEM_ASSERT_RW(cached_rec
3138
 
                                           + templ->mysql_col_offset,
3139
 
                                           templ->mysql_col_len);
3140
 
#endif
3141
3073
                        ut_memcpy(buf + templ->mysql_col_offset,
3142
3074
                                  cached_rec + templ->mysql_col_offset,
3143
3075
                                  templ->mysql_col_len);
3152
3084
                }
3153
3085
        }
3154
3086
        else {
3155
 
#if 0 /* Some of the cached_rec may legitimately be uninitialized. */
3156
 
                UNIV_MEM_ASSERT_RW(prebuilt->fetch_cache
3157
 
                                   [prebuilt->fetch_cache_first],
3158
 
                                   prebuilt->mysql_prefix_len);
3159
 
#endif
3160
3087
                ut_memcpy(buf,
3161
3088
                          prebuilt->fetch_cache[prebuilt->fetch_cache_first],
3162
3089
                          prebuilt->mysql_prefix_len);
3170
3097
}
3171
3098
 
3172
3099
/********************************************************************//**
3173
 
Pushes a row for MySQL to the fetch cache.
3174
 
@return TRUE on success, FALSE if the record contains incomplete BLOBs */
3175
 
UNIV_INLINE __attribute__((warn_unused_result))
3176
 
ibool
 
3100
Pushes a row for MySQL to the fetch cache. */
 
3101
UNIV_INLINE
 
3102
void
3177
3103
row_sel_push_cache_row_for_mysql(
3178
3104
/*=============================*/
3179
3105
        row_prebuilt_t* prebuilt,       /*!< in: prebuilt struct */
3208
3134
        }
3209
3135
 
3210
3136
        ut_ad(prebuilt->fetch_cache_first == 0);
3211
 
        UNIV_MEM_INVALID(prebuilt->fetch_cache[prebuilt->n_fetch_cached],
3212
 
                         prebuilt->mysql_row_len);
3213
3137
 
3214
3138
        if (UNIV_UNLIKELY(!row_sel_store_mysql_rec(
3215
3139
                                  prebuilt->fetch_cache[
3216
3140
                                          prebuilt->n_fetch_cached],
3217
3141
                                  prebuilt, rec, offsets))) {
3218
 
                return(FALSE);
 
3142
                ut_error;
3219
3143
        }
3220
3144
 
3221
3145
        prebuilt->n_fetch_cached++;
3222
 
        return(TRUE);
3223
3146
}
3224
3147
 
3225
3148
/*********************************************************************//**
3590
3513
 
3591
3514
                                if (!row_sel_store_mysql_rec(buf, prebuilt,
3592
3515
                                                             rec, offsets)) {
3593
 
                                        /* Only fresh inserts may contain
3594
 
                                        incomplete externally stored
3595
 
                                        columns. Pretend that such
3596
 
                                        records do not exist. Such
3597
 
                                        records may only be accessed
3598
 
                                        at the READ UNCOMMITTED
3599
 
                                        isolation level or when
3600
 
                                        rolling back a recovered
3601
 
                                        transaction. Rollback happens
3602
 
                                        at a lower level, not here. */
3603
 
                                        ut_a(trx->isolation_level
3604
 
                                             == TRX_ISO_READ_UNCOMMITTED);
 
3516
                                        err = DB_TOO_BIG_RECORD;
3605
3517
 
3606
 
                                        /* Proceed as in case SEL_RETRY. */
3607
 
                                        break;
 
3518
                                        /* We let the main loop to do the
 
3519
                                        error handling */
 
3520
                                        goto shortcut_fails_too_big_rec;
3608
3521
                                }
3609
3522
 
3610
3523
                                mtr_commit(&mtr);
3644
3557
                        default:
3645
3558
                                ut_ad(0);
3646
3559
                        }
3647
 
 
 
3560
shortcut_fails_too_big_rec:
3648
3561
                        mtr_commit(&mtr);
3649
3562
                        mtr_start(&mtr);
3650
3563
                }
3728
3641
                    && !page_rec_is_supremum(rec)
3729
3642
                    && set_also_gap_locks
3730
3643
                    && !(srv_locks_unsafe_for_binlog
3731
 
                         || trx->isolation_level <= TRX_ISO_READ_COMMITTED)
 
3644
                         || trx->isolation_level == TRX_ISO_READ_COMMITTED)
3732
3645
                    && prebuilt->select_lock_type != LOCK_NONE) {
3733
3646
 
3734
3647
                        /* Try to place a gap lock on the next index record
3742
3655
                                               prebuilt->select_lock_type,
3743
3656
                                               LOCK_GAP, thr);
3744
3657
 
3745
 
                        switch (err) {
3746
 
                        case DB_SUCCESS_LOCKED_REC:
3747
 
                                err = DB_SUCCESS;
3748
 
                        case DB_SUCCESS:
3749
 
                                break;
3750
 
                        default:
 
3658
                        if (err != DB_SUCCESS) {
 
3659
 
3751
3660
                                goto lock_wait_or_error;
3752
3661
                        }
3753
3662
                }
3828
3737
 
3829
3738
                if (set_also_gap_locks
3830
3739
                    && !(srv_locks_unsafe_for_binlog
3831
 
                         || trx->isolation_level <= TRX_ISO_READ_COMMITTED)
 
3740
                         || trx->isolation_level == TRX_ISO_READ_COMMITTED)
3832
3741
                    && prebuilt->select_lock_type != LOCK_NONE) {
3833
3742
 
3834
3743
                        /* Try to place a lock on the index record */
3845
3754
                                               prebuilt->select_lock_type,
3846
3755
                                               LOCK_ORDINARY, thr);
3847
3756
 
3848
 
                        switch (err) {
3849
 
                        case DB_SUCCESS_LOCKED_REC:
3850
 
                                err = DB_SUCCESS;
3851
 
                        case DB_SUCCESS:
3852
 
                                break;
3853
 
                        default:
 
3757
                        if (err != DB_SUCCESS) {
 
3758
 
3854
3759
                                goto lock_wait_or_error;
3855
3760
                        }
3856
3761
                }
3966
3871
                        if (set_also_gap_locks
3967
3872
                            && !(srv_locks_unsafe_for_binlog
3968
3873
                                 || trx->isolation_level
3969
 
                                 <= TRX_ISO_READ_COMMITTED)
 
3874
                                 == TRX_ISO_READ_COMMITTED)
3970
3875
                            && prebuilt->select_lock_type != LOCK_NONE) {
3971
3876
 
3972
3877
                                /* Try to place a gap lock on the index
3980
3885
                                        prebuilt->select_lock_type, LOCK_GAP,
3981
3886
                                        thr);
3982
3887
 
3983
 
                                switch (err) {
3984
 
                                case DB_SUCCESS_LOCKED_REC:
3985
 
                                case DB_SUCCESS:
3986
 
                                        break;
3987
 
                                default:
 
3888
                                if (err != DB_SUCCESS) {
 
3889
 
3988
3890
                                        goto lock_wait_or_error;
3989
3891
                                }
3990
3892
                        }
4005
3907
                        if (set_also_gap_locks
4006
3908
                            && !(srv_locks_unsafe_for_binlog
4007
3909
                                 || trx->isolation_level
4008
 
                                 <= TRX_ISO_READ_COMMITTED)
 
3910
                                 == TRX_ISO_READ_COMMITTED)
4009
3911
                            && prebuilt->select_lock_type != LOCK_NONE) {
4010
3912
 
4011
3913
                                /* Try to place a gap lock on the index
4019
3921
                                        prebuilt->select_lock_type, LOCK_GAP,
4020
3922
                                        thr);
4021
3923
 
4022
 
                                switch (err) {
4023
 
                                case DB_SUCCESS_LOCKED_REC:
4024
 
                                case DB_SUCCESS:
4025
 
                                        break;
4026
 
                                default:
 
3924
                                if (err != DB_SUCCESS) {
 
3925
 
4027
3926
                                        goto lock_wait_or_error;
4028
3927
                                }
4029
3928
                        }
4056
3955
 
4057
3956
                if (!set_also_gap_locks
4058
3957
                    || srv_locks_unsafe_for_binlog
4059
 
                    || trx->isolation_level <= TRX_ISO_READ_COMMITTED
 
3958
                    || trx->isolation_level == TRX_ISO_READ_COMMITTED
4060
3959
                    || (unique_search
4061
3960
                        && !UNIV_UNLIKELY(rec_get_deleted_flag(rec, comp)))) {
4062
3961
 
4093
3992
 
4094
3993
                switch (err) {
4095
3994
                        const rec_t*    old_vers;
4096
 
                case DB_SUCCESS_LOCKED_REC:
 
3995
                case DB_SUCCESS:
4097
3996
                        if (srv_locks_unsafe_for_binlog
4098
 
                            || trx->isolation_level
4099
 
                            <= TRX_ISO_READ_COMMITTED) {
 
3997
                            || trx->isolation_level == TRX_ISO_READ_COMMITTED) {
4100
3998
                                /* Note that a record of
4101
3999
                                prebuilt->index was locked. */
4102
4000
                                prebuilt->new_rec_locks = 1;
4103
4001
                        }
4104
 
                        err = DB_SUCCESS;
4105
 
                case DB_SUCCESS:
4106
4002
                        break;
4107
4003
                case DB_LOCK_WAIT:
4108
 
                        /* Never unlock rows that were part of a conflict. */
4109
 
                        prebuilt->new_rec_locks = 0;
4110
 
 
4111
4004
                        if (UNIV_LIKELY(prebuilt->row_read_type
4112
4005
                                        != ROW_READ_TRY_SEMI_CONSISTENT)
4113
 
                            || unique_search
4114
4006
                            || index != clust_index) {
4115
4007
 
4116
4008
                                goto lock_wait_or_error;
4137
4029
                        if (UNIV_LIKELY(trx->wait_lock != NULL)) {
4138
4030
                                lock_cancel_waiting_and_release(
4139
4031
                                        trx->wait_lock);
 
4032
                                prebuilt->new_rec_locks = 0;
4140
4033
                        } else {
4141
4034
                                mutex_exit(&kernel_mutex);
4142
4035
 
4148
4041
                                                          ULINT_UNDEFINED,
4149
4042
                                                          &heap);
4150
4043
                                err = DB_SUCCESS;
 
4044
                                /* Note that a record of
 
4045
                                prebuilt->index was locked. */
 
4046
                                prebuilt->new_rec_locks = 1;
4151
4047
                                break;
4152
4048
                        }
4153
4049
                        mutex_exit(&kernel_mutex);
4229
4125
                /* The record is delete-marked: we can skip it */
4230
4126
 
4231
4127
                if ((srv_locks_unsafe_for_binlog
4232
 
                     || trx->isolation_level <= TRX_ISO_READ_COMMITTED)
 
4128
                     || trx->isolation_level == TRX_ISO_READ_COMMITTED)
4233
4129
                    && prebuilt->select_lock_type != LOCK_NONE
4234
4130
                    && !did_semi_consistent_read) {
4235
4131
 
4283
4179
                err = row_sel_get_clust_rec_for_mysql(prebuilt, index, rec,
4284
4180
                                                      thr, &clust_rec,
4285
4181
                                                      &offsets, &heap, &mtr);
4286
 
                switch (err) {
4287
 
                case DB_SUCCESS:
4288
 
                        if (clust_rec == NULL) {
4289
 
                                /* The record did not exist in the read view */
4290
 
                                ut_ad(prebuilt->select_lock_type == LOCK_NONE);
 
4182
                if (err != DB_SUCCESS) {
4291
4183
 
4292
 
                                goto next_rec;
4293
 
                        }
4294
 
                        break;
4295
 
                case DB_SUCCESS_LOCKED_REC:
4296
 
                        ut_a(clust_rec != NULL);
4297
 
                        if (srv_locks_unsafe_for_binlog
4298
 
                             || trx->isolation_level
4299
 
                            <= TRX_ISO_READ_COMMITTED) {
4300
 
                                /* Note that the clustered index record
4301
 
                                was locked. */
4302
 
                                prebuilt->new_rec_locks = 2;
4303
 
                        }
4304
 
                        err = DB_SUCCESS;
4305
 
                        break;
4306
 
                default:
4307
4184
                        goto lock_wait_or_error;
4308
4185
                }
4309
4186
 
 
4187
                if (clust_rec == NULL) {
 
4188
                        /* The record did not exist in the read view */
 
4189
                        ut_ad(prebuilt->select_lock_type == LOCK_NONE);
 
4190
 
 
4191
                        goto next_rec;
 
4192
                }
 
4193
 
 
4194
                if ((srv_locks_unsafe_for_binlog
 
4195
                     || trx->isolation_level == TRX_ISO_READ_COMMITTED)
 
4196
                    && prebuilt->select_lock_type != LOCK_NONE) {
 
4197
                        /* Note that both the secondary index record
 
4198
                        and the clustered index record were locked. */
 
4199
                        ut_ad(prebuilt->new_rec_locks == 1);
 
4200
                        prebuilt->new_rec_locks = 2;
 
4201
                }
 
4202
 
4310
4203
                if (UNIV_UNLIKELY(rec_get_deleted_flag(clust_rec, comp))) {
4311
4204
 
4312
4205
                        /* The record is delete marked: we can skip it */
4313
4206
 
4314
4207
                        if ((srv_locks_unsafe_for_binlog
4315
 
                             || trx->isolation_level <= TRX_ISO_READ_COMMITTED)
 
4208
                             || trx->isolation_level == TRX_ISO_READ_COMMITTED)
4316
4209
                            && prebuilt->select_lock_type != LOCK_NONE) {
4317
4210
 
4318
4211
                                /* No need to keep a lock on a delete-marked
4370
4263
                not cache rows because there the cursor is a scrollable
4371
4264
                cursor. */
4372
4265
 
4373
 
                if (!row_sel_push_cache_row_for_mysql(prebuilt, result_rec,
4374
 
                                                      offsets)) {
4375
 
                        /* Only fresh inserts may contain incomplete
4376
 
                        externally stored columns. Pretend that such
4377
 
                        records do not exist. Such records may only be
4378
 
                        accessed at the READ UNCOMMITTED isolation
4379
 
                        level or when rolling back a recovered
4380
 
                        transaction. Rollback happens at a lower
4381
 
                        level, not here. */
4382
 
                        ut_a(trx->isolation_level == TRX_ISO_READ_UNCOMMITTED);
4383
 
                } else if (prebuilt->n_fetch_cached
4384
 
                           == MYSQL_FETCH_CACHE_SIZE) {
 
4266
                row_sel_push_cache_row_for_mysql(prebuilt, result_rec,
 
4267
                                                 offsets);
 
4268
                if (prebuilt->n_fetch_cached == MYSQL_FETCH_CACHE_SIZE) {
4385
4269
 
4386
4270
                        goto got_row;
4387
4271
                }
4397
4281
                } else {
4398
4282
                        if (!row_sel_store_mysql_rec(buf, prebuilt,
4399
4283
                                                     result_rec, offsets)) {
4400
 
                                /* Only fresh inserts may contain
4401
 
                                incomplete externally stored
4402
 
                                columns. Pretend that such records do
4403
 
                                not exist. Such records may only be
4404
 
                                accessed at the READ UNCOMMITTED
4405
 
                                isolation level or when rolling back a
4406
 
                                recovered transaction. Rollback
4407
 
                                happens at a lower level, not here. */
4408
 
                                ut_a(trx->isolation_level
4409
 
                                     == TRX_ISO_READ_UNCOMMITTED);
4410
 
                                goto next_rec;
 
4284
                                err = DB_TOO_BIG_RECORD;
 
4285
 
 
4286
                                goto lock_wait_or_error;
4411
4287
                        }
4412
4288
                }
4413
4289
 
4538
4414
                                               moves_up, &mtr);
4539
4415
 
4540
4416
                if ((srv_locks_unsafe_for_binlog
4541
 
                     || trx->isolation_level <= TRX_ISO_READ_COMMITTED)
 
4417
                     || trx->isolation_level == TRX_ISO_READ_COMMITTED)
4542
4418
                    && !same_user_rec) {
4543
4419
 
4544
4420
                        /* Since we were not able to restore the cursor