425
425
dict_table_zip_size(index->table),
426
426
field_no, &len, heap);
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. */
439
428
ut_a(len != UNIV_SQL_NULL);
441
430
needs_copy = TRUE;
863
852
trx = thr_get_trx(thr);
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;
869
858
lock_type = LOCK_ORDINARY;
874
863
clust_rec, index, offsets,
875
864
node->row_lock_mode, lock_type, thr);
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);
866
if (err != DB_SUCCESS) {
937
920
when plan->clust_pcur was positioned. The latch will not be
938
921
released until mtr_commit(mtr). */
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;
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 */
958
940
sel_set_rec_lock(
959
941
/*=============*/
960
942
const buf_block_t* block, /*!< in: buffer block of rec */
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
1650
1617
offsets = rec_get_offsets(
1651
1618
rec, index, offsets,
1652
1619
ULINT_UNDEFINED, &heap);
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) */
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)));
2695
2661
if (UNIV_LIKELY_NULL(prebuilt->blob_heap)) {
2696
2662
mem_heap_free(prebuilt->blob_heap);
2697
2663
prebuilt->blob_heap = NULL;
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);
2706
2666
for (i = 0; i < prebuilt->n_template ; i++) {
2708
2668
templ = prebuilt->mysql_template + i;
2738
2698
dict_table_zip_size(prebuilt->table),
2739
2699
templ->rec_field_no, &len, heap);
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
2749
if (extern_field_heap) {
2750
mem_heap_free(extern_field_heap);
2756
2701
ut_a(len != UNIV_SQL_NULL);
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. */
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
2858
@return DB_SUCCESS, DB_SUCCESS_LOCKED_REC, or error code */
2800
@return DB_SUCCESS or error code */
2861
2803
row_sel_get_clust_rec_for_mysql(
2862
2804
/*============================*/
2863
2805
row_prebuilt_t* prebuilt,/*!< in: prebuilt struct in the handle */
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);
2964
case DB_SUCCESS_LOCKED_REC:
2903
if (err != DB_SUCCESS) {
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);
3141
3073
ut_memcpy(buf + templ->mysql_col_offset,
3142
3074
cached_rec + templ->mysql_col_offset,
3143
3075
templ->mysql_col_len);
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);
3161
3088
prebuilt->fetch_cache[prebuilt->fetch_cache_first],
3162
3089
prebuilt->mysql_prefix_len);
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))
3100
Pushes a row for MySQL to the fetch cache. */
3177
3103
row_sel_push_cache_row_for_mysql(
3178
3104
/*=============================*/
3179
3105
row_prebuilt_t* prebuilt, /*!< in: prebuilt struct */
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);
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))) {
3221
3145
prebuilt->n_fetch_cached++;
3225
3148
/*********************************************************************//**
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;
3606
/* Proceed as in case SEL_RETRY. */
3518
/* We let the main loop to do the
3520
goto shortcut_fails_too_big_rec;
3610
3523
mtr_commit(&mtr);
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) {
3734
3647
/* Try to place a gap lock on the next index record
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) {
3834
3743
/* Try to place a lock on the index record */
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) {
3972
3877
/* Try to place a gap lock on the index
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) {
4011
3913
/* Try to place a gap lock on the index
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)))) {
4095
3994
const rec_t* old_vers;
4096
case DB_SUCCESS_LOCKED_REC:
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;
4107
4003
case DB_LOCK_WAIT:
4108
/* Never unlock rows that were part of a conflict. */
4109
prebuilt->new_rec_locks = 0;
4111
4004
if (UNIV_LIKELY(prebuilt->row_read_type
4112
4005
!= ROW_READ_TRY_SEMI_CONSISTENT)
4114
4006
|| index != clust_index) {
4116
4008
goto lock_wait_or_error;
4229
4125
/* The record is delete-marked: we can skip it */
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) {
4283
4179
err = row_sel_get_clust_rec_for_mysql(prebuilt, index, rec,
4284
4180
thr, &clust_rec,
4285
4181
&offsets, &heap, &mtr);
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) {
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
4302
prebuilt->new_rec_locks = 2;
4307
4184
goto lock_wait_or_error;
4187
if (clust_rec == NULL) {
4188
/* The record did not exist in the read view */
4189
ut_ad(prebuilt->select_lock_type == LOCK_NONE);
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;
4310
4203
if (UNIV_UNLIKELY(rec_get_deleted_flag(clust_rec, comp))) {
4312
4205
/* The record is delete marked: we can skip it */
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) {
4318
4211
/* No need to keep a lock on a delete-marked
4370
4263
not cache rows because there the cursor is a scrollable
4373
if (!row_sel_push_cache_row_for_mysql(prebuilt, result_rec,
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
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,
4268
if (prebuilt->n_fetch_cached == MYSQL_FETCH_CACHE_SIZE) {
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);
4284
err = DB_TOO_BIG_RECORD;
4286
goto lock_wait_or_error;