1
1
/*****************************************************************************
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.
6
6
Portions of this file contain modifications contributed and copyrighted by
7
7
Google, Inc. Those modifications are gratefully acknowledged and are described
105
105
byte buf[DICT_MAX_INDEX_COL_LEN];
107
ut_a(clust_len >= BTR_EXTERN_FIELD_REF_SIZE);
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. */
119
107
len = btr_copy_externally_stored_field_prefix(buf, sizeof buf,
121
109
clust_field, clust_len);
259
247
sel_node_t* node;
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;
338
326
eval_node_copy_val(var->alias, exp);
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);
356
344
ut_ad(node->is_aggregate);
358
func_node = static_cast<func_node_t *>(node->select_list);
346
func_node = node->select_list;
360
348
while (func_node) {
361
349
eval_node_set_int_val(func_node, 0);
363
func_node = static_cast<func_node_t *>(que_node_get_next(func_node));
351
func_node = que_node_get_next(func_node);
366
354
node->aggregate_already_fetched = FALSE;
487
475
ut_ad(que_node_get_type(column) == QUE_NODE_SYMBOL);
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;
566
554
column values to be able to free it later: therefore
567
555
we swap the values for sel_buf and val */
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);
635
623
val = que_node_get_val(column);
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);
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);
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);
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);
2061
2049
while (table_node) {
2062
2050
err = lock_table(0, table_node->table,
2063
static_cast<lock_mode>(i_lock_mode), thr);
2064
2052
if (err != DB_SUCCESS) {
2065
2053
thr_get_trx(thr)->error_state = err;
2070
table_node = static_cast<sym_node_t *>(que_node_get_next(table_node));
2058
table_node = que_node_get_next(table_node);
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
2680
template; must be protected by
2697
2682
const ulint* offsets) /*!< in: array returned by
2698
rec_get_offsets(rec) */
2683
rec_get_offsets() */
2700
mem_heap_t* extern_field_heap = NULL;
2685
mysql_row_templ_t* templ;
2686
mem_heap_t* extern_field_heap = NULL;
2704
2692
ut_ad(prebuilt->mysql_template);
2705
2693
ut_ad(prebuilt->default_rec);
2711
2699
prebuilt->blob_heap = NULL;
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);
2714
2708
for (i = 0; i < prebuilt->n_template ; i++) {
2716
const mysql_row_templ_t*templ = prebuilt->mysql_template + i;
2721
field_no = rec_clust
2722
? templ->clust_rec_field_no : templ->rec_field_no;
2724
if (UNIV_UNLIKELY(rec_offs_nth_extern(offsets, field_no))) {
2710
templ = prebuilt->mysql_template + i;
2712
if (UNIV_UNLIKELY(rec_offs_nth_extern(offsets,
2713
templ->rec_field_no))) {
2726
2715
/* Copy an externally stored field to the temporary
2749
2738
data = btr_rec_copy_externally_stored_field(
2751
2740
dict_table_zip_size(prebuilt->table),
2752
field_no, &len, heap);
2741
templ->rec_field_no, &len, heap);
2754
2743
if (UNIV_UNLIKELY(!data)) {
2755
2744
/* The externally stored field
2786
2775
/* Field is stored in the row. */
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);
2790
2780
if (UNIV_UNLIKELY(templ->type == DATA_BLOB)
2791
2781
&& len != UNIV_SQL_NULL) {
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);
2991
2980
case DB_SUCCESS:
2992
2981
case DB_SUCCESS_LOCKED_REC:
3011
3000
/* The following call returns 'offsets' associated with
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,
3018
3007
if (err != DB_SUCCESS || old_vers == NULL) {
3148
3137
row_prebuilt_t* prebuilt) /*!< in: prebuilt struct */
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
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() */
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);
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. */
3237
buf = static_cast<byte *>(mem_alloc(prebuilt->mysql_row_len + 8));
3220
buf = mem_alloc(prebuilt->mysql_row_len + 8);
3239
3222
prebuilt->fetch_cache[i] = buf + 4;
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))) {
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));
3630
3611
if (!row_sel_store_mysql_rec(buf, prebuilt,
3633
3613
/* Only fresh inserts may contain
3634
3614
incomplete externally stored
3635
3615
columns. Pretend that such
3743
3723
clust_index = dict_table_get_first_index(index->table);
3745
/* Do some start-of-statement preparations */
3747
if (!prebuilt->sql_stat_start) {
3748
/* No need to set an intention lock or assign a read view */
3750
if (trx->read_view == NULL
3751
&& prebuilt->select_lock_type == LOCK_NONE) {
3753
fputs("InnoDB: Error: MySQL is trying to"
3754
" perform a consistent read\n"
3755
"InnoDB: but the read view is not assigned!\n",
3757
trx_print(stderr, trx, 600);
3758
fputc('\n', stderr);
3761
} else if (prebuilt->select_lock_type == LOCK_NONE) {
3762
/* This is a consistent read */
3763
/* Assign a read view for the query */
3765
trx_assign_read_view(trx);
3766
prebuilt->sql_stat_start = FALSE;
3769
err = lock_table(0, index->table,
3770
prebuilt->select_lock_type == LOCK_S
3771
? LOCK_IS : LOCK_IX, thr);
3773
if (err != DB_SUCCESS) {
3775
table_lock_waited = TRUE;
3776
goto lock_table_wait;
3778
prebuilt->sql_stat_start = FALSE;
3781
/* Open or restore index cursor position */
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,
3800
if (!prebuilt->sql_stat_start) {
3801
/* No need to set an intention lock or assign a read view */
3803
if (trx->read_view == NULL
3804
&& prebuilt->select_lock_type == LOCK_NONE) {
3806
fputs("InnoDB: Error: MySQL is trying to"
3807
" perform a consistent read\n"
3808
"InnoDB: but the read view is not assigned!\n",
3810
trx_print(stderr, trx, 600);
3811
fputc('\n', stderr);
3814
} else if (prebuilt->select_lock_type == LOCK_NONE) {
3815
/* This is a consistent read */
3816
/* Assign a read view for the query */
3818
trx_assign_read_view(trx);
3819
prebuilt->sql_stat_start = FALSE;
3822
if (prebuilt->select_lock_type == LOCK_S) {
3823
lock_mode = LOCK_IS;
3825
lock_mode = LOCK_IX;
3827
err = lock_table(0, index->table, lock_mode, thr);
3829
if (err != DB_SUCCESS) {
3831
goto lock_wait_or_error;
3833
prebuilt->sql_stat_start = FALSE;
3859
3837
/*-------------------------------------------------------------*/
3860
3838
/* PHASE 4: Look for matching records in a loop */
4271
4249
rec = old_vers;
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. */
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;
4258
ut_ad(index != clust_index);
4259
goto requires_clust_rec;
4394
result_rec = clust_rec;
4395
ut_ad(rec_offs_validate(result_rec, clust_index, offsets));
4369
if (prebuilt->need_to_access_clustered) {
4371
result_rec = clust_rec;
4373
ut_ad(rec_offs_validate(result_rec, clust_index,
4376
/* We used 'offsets' for the clust rec, recalculate
4378
offsets = rec_get_offsets(rec, index, offsets,
4379
ULINT_UNDEFINED, &heap);
4397
4383
result_rec = rec;
4403
4389
ut_ad(rec_offs_validate(result_rec,
4404
4390
result_rec != rec ? clust_index : index,
4406
ut_ad(!rec_get_deleted_flag(result_rec, comp));
4408
4393
/* At this point, the clustered index record is protected
4409
4394
by a page latch that was acquired when pcur was positioned.
4449
(prebuilt->template_type == ROW_MYSQL_DUMMY_TEMPLATE)) {
4450
/* CHECK TABLE: fetch the row */
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,
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);
4468
/* Returning a row to MySQL */
4470
if (!row_sel_store_mysql_rec(buf, prebuilt, result_rec,
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
4607
4574
thr->lock_state = QUE_THR_LOCK_NOLOCK;
4608
4575
mtr_start(&mtr);
4610
/* Table lock waited, go try to obtain table lock
4612
if (table_lock_waited) {
4613
table_lock_waited = FALSE;
4615
goto wait_table_again;
4618
4577
sel_restore_position_for_mysql(&same_user_rec,
4619
4578
BTR_SEARCH_LEAF, pcur,
4620
4579
moves_up, &mtr);