62 #define SEL_MAX_N_PREFETCH 16
66 #define SEL_PREFETCH_LIMIT 1
71 #define SEL_COST_LIMIT 100
75 #define SEL_EXHAUSTED 1
87 row_sel_sec_rec_is_for_blob(
93 const byte* clust_field,
100 const byte* sec_field,
119 len = btr_copy_externally_stored_field_prefix(buf,
sizeof buf,
121 clust_field, clust_len);
123 if (UNIV_UNLIKELY(len == 0)) {
132 len = dtype_get_at_most_n_mbchars(prtype, mbminmaxlen,
133 sec_len, len, (
const char*) buf);
135 return(!
cmp_data_data(mtype, prtype, buf, len, sec_field, sec_len));
149 row_sel_sec_rec_is_for_clust_rec(
151 const rec_t* sec_rec,
153 const rec_t* clust_rec,
159 const byte* sec_field;
161 const byte* clust_field;
165 ulint clust_offsets_[REC_OFFS_NORMAL_SIZE];
166 ulint sec_offsets_[REC_OFFS_SMALL_SIZE];
167 ulint* clust_offs = clust_offsets_;
168 ulint* sec_offs = sec_offsets_;
169 ibool is_equal = TRUE;
171 rec_offs_init(clust_offsets_);
172 rec_offs_init(sec_offsets_);
184 clust_offs = rec_get_offsets(clust_rec, clust_index, clust_offs,
185 ULINT_UNDEFINED, &heap);
186 sec_offs = rec_get_offsets(sec_rec, sec_index, sec_offs,
187 ULINT_UNDEFINED, &heap);
191 for (i = 0; i < n; i++) {
198 ifield = dict_index_get_nth_field(sec_index, i);
202 clust_field = rec_get_nth_field(
203 clust_rec, clust_offs, clust_pos, &clust_len);
204 sec_field = rec_get_nth_field(sec_rec, sec_offs, i, &sec_len);
208 if (ifield->
prefix_len > 0 && len != UNIV_SQL_NULL) {
214 len = dtype_get_at_most_n_mbchars(
216 ifield->
prefix_len, len, (
char*) clust_field);
220 if (!row_sel_sec_rec_is_for_blob(
223 clust_field, clust_len,
226 clust_index->
table))) {
236 sec_field, sec_len)) {
244 if (UNIV_LIKELY_NULL(heap)) {
282 if (node->
plans != NULL) {
283 for (i = 0; i < node->
n_tables; i++) {
301 sel_eval_select_list(
321 sel_assign_into_var_values(
350 sel_reset_aggregate_vals(
373 row_sel_copy_input_variable_vals(
394 row_sel_fetch_columns(
399 const ulint* offsets,
421 field_no = column->
field_nos[index_type];
423 if (field_no != ULINT_UNDEFINED) {
433 data = btr_rec_copy_externally_stored_field(
436 field_no, &len, heap);
449 ut_a(len != UNIV_SQL_NULL);
453 data = rec_get_nth_field(rec, offsets,
467 if (UNIV_LIKELY_NULL(heap)) {
480 sel_col_prefetch_buf_alloc(
491 for (i = 0; i < SEL_MAX_N_PREFETCH; i++) {
494 sel_buf->
data = NULL;
512 for (i = 0; i < SEL_MAX_N_PREFETCH; i++) {
513 sel_buf = prefetch_buf + i;
527 sel_pop_prefetched_row(
561 data = sel_buf->
data;
569 sel_buf->
data =
static_cast<byte *
>(dfield_get_data(val));
589 sel_push_prefetched_row(
615 ut_ad(pos < SEL_MAX_N_PREFETCH);
630 sel_col_prefetch_buf_alloc(column);
637 data =
static_cast<byte *
>(dfield_get_data(val));
648 sel_buf->
data = data;
661 row_sel_build_prev_vers(
679 if (*old_vers_heap) {
686 rec, mtr, index, offsets, read_view, offset_heap,
687 *old_vers_heap, old_vers);
697 row_sel_build_committed_vers_for_mysql(
706 const rec_t** old_vers,
721 rec, mtr, clust_index, offsets, offset_heap,
732 row_sel_test_end_conds(
753 if (!eval_cmp(cond)) {
769 row_sel_test_other_conds(
798 row_sel_get_clust_rec(
817 ulint offsets_[REC_OFFS_NORMAL_SIZE];
818 ulint* offsets = offsets_;
819 rec_offs_init(offsets_);
823 offsets = rec_get_offsets(rec,
824 btr_pcur_get_btr_cur(&plan->
pcur)->index,
825 offsets, ULINT_UNDEFINED, &heap);
829 index = dict_table_get_first_index(plan->
table);
831 btr_pcur_open_with_no_init(index, plan->
clust_ref, PAGE_CUR_LE,
835 clust_rec = btr_pcur_get_rec(&(plan->
clust_pcur));
860 offsets = rec_get_offsets(clust_rec, index, offsets,
861 ULINT_UNDEFINED, &heap);
875 if (srv_locks_unsafe_for_binlog
876 || trx->isolation_level <= TRX_ISO_READ_COMMITTED) {
884 clust_rec, index, offsets,
885 static_cast<lock_mode>(node->
row_lock_mode), lock_type, thr);
892 UNIV_MEM_INVALID(&err,
sizeof err);
906 err = row_sel_build_prev_vers(
911 if (err != DB_SUCCESS) {
916 clust_rec = old_vers;
918 if (clust_rec == NULL) {
939 && !row_sel_sec_rec_is_for_clust_rec(rec, plan->
index,
951 row_sel_fetch_columns(index, clust_rec, offsets,
953 *out_rec = clust_rec;
957 if (UNIV_LIKELY_NULL(heap)) {
973 const ulint* offsets,
985 if (buf_LRU_buf_pool_running_out()) {
987 return(DB_LOCK_TABLE_FULL);
993 offsets, static_cast<lock_mode>(mode), type, thr);
996 offsets, static_cast<lock_mode>(mode), type, thr);
1009 ibool search_latch_locked,
1019 ulint has_search_latch = 0;
1022 if (search_latch_locked) {
1023 has_search_latch = RW_S_LATCH;
1026 index = plan->
index;
1050 for (i = 0; i < n_fields; i++) {
1059 btr_pcur_open_with_no_init(index, plan->
tuple, plan->
mode,
1061 has_search_latch, mtr);
1067 &(plan->
pcur), FALSE, mtr);
1085 row_sel_restore_pcur_pos(
1090 ibool equal_position;
1091 ulint relative_position;
1098 &(plan->
pcur), mtr);
1117 if (relative_position == BTR_PCUR_ON) {
1119 if (equal_position) {
1127 ut_ad(relative_position == BTR_PCUR_AFTER
1128 || relative_position == BTR_PCUR_AFTER_LAST_IN_TREE);
1150 if (relative_position == BTR_PCUR_BEFORE
1151 || relative_position == BTR_PCUR_BEFORE_FIRST_IN_TREE) {
1156 if (relative_position == BTR_PCUR_ON) {
1158 if (equal_position) {
1166 ut_ad(relative_position == BTR_PCUR_AFTER
1167 || relative_position == BTR_PCUR_AFTER_LAST_IN_TREE);
1192 row_sel_try_search_shortcut(
1202 ulint offsets_[REC_OFFS_NORMAL_SIZE];
1203 ulint* offsets = offsets_;
1205 rec_offs_init(offsets_);
1207 index = plan->
index;
1212 #ifdef UNIV_SYNC_DEBUG
1216 row_sel_open_pcur(plan, TRUE, mtr);
1218 rec = btr_pcur_get_rec(&(plan->
pcur));
1233 return(SEL_EXHAUSTED);
1239 offsets = rec_get_offsets(rec, index, offsets, ULINT_UNDEFINED, &heap);
1257 ret = SEL_EXHAUSTED;
1266 row_sel_fetch_columns(index, rec, offsets,
1271 if (!row_sel_test_other_conds(plan)) {
1273 ret = SEL_EXHAUSTED;
1282 if (UNIV_LIKELY_NULL(heap)) {
1305 ibool search_latch_locked;
1306 ibool consistent_read;
1313 ibool cons_read_requires_clust_rec = FALSE;
1314 ulint cost_counter = 0;
1315 ibool cursor_just_opened;
1316 ibool must_go_to_next;
1317 ibool mtr_has_extra_clust_latch = FALSE;
1327 ulint offsets_[REC_OFFS_NORMAL_SIZE];
1328 ulint* offsets = offsets_;
1329 rec_offs_init(offsets_);
1333 search_latch_locked = FALSE;
1343 consistent_read = TRUE;
1345 consistent_read = FALSE;
1355 ut_ad(mtr_has_extra_clust_latch == FALSE);
1358 index = plan->
index;
1361 sel_pop_prefetched_row(plan);
1363 goto next_table_no_mtr;
1373 goto table_exhausted_no_mtr;
1383 if (!search_latch_locked) {
1386 search_latch_locked = TRUE;
1400 found_flag = row_sel_try_search_shortcut(node, plan, &mtr);
1402 if (found_flag == SEL_FOUND) {
1406 }
else if (found_flag == SEL_EXHAUSTED) {
1408 goto table_exhausted;
1411 ut_ad(found_flag == SEL_RETRY);
1413 plan_reset_cursor(plan);
1419 if (search_latch_locked) {
1422 search_latch_locked = FALSE;
1429 row_sel_open_pcur(plan, search_latch_locked, &mtr);
1431 cursor_just_opened = TRUE;
1438 must_go_to_next = row_sel_restore_pcur_pos(plan, &mtr);
1440 cursor_just_opened = FALSE;
1442 if (must_go_to_next) {
1463 ut_ad(mtr_has_extra_clust_latch == FALSE);
1465 rec = btr_pcur_get_rec(&(plan->
pcur));
1469 if (!node->
asc && cursor_just_opened
1478 if (!consistent_read) {
1491 offsets = rec_get_offsets(next_rec, index, offsets,
1492 ULINT_UNDEFINED, &heap);
1494 if (srv_locks_unsafe_for_binlog
1495 || trx->isolation_level
1496 <= TRX_ISO_READ_COMMITTED) {
1508 err = sel_set_rec_lock(btr_pcur_get_block(&plan->
pcur),
1509 next_rec, index, offsets,
1522 goto lock_wait_or_error;
1540 if (!consistent_read) {
1551 offsets = rec_get_offsets(rec, index, offsets,
1552 ULINT_UNDEFINED, &heap);
1556 if (srv_locks_unsafe_for_binlog
1557 || trx->isolation_level <= TRX_ISO_READ_COMMITTED) {
1569 err = sel_set_rec_lock(btr_pcur_get_block(&plan->
pcur),
1570 rec, index, offsets,
1579 goto lock_wait_or_error;
1593 if (cost_counter > SEL_COST_LIMIT) {
1602 goto stop_for_a_while;
1618 goto table_exhausted;
1630 cons_read_requires_clust_rec = FALSE;
1631 offsets = rec_get_offsets(rec, index, offsets, ULINT_UNDEFINED, &heap);
1633 if (consistent_read) {
1642 err = row_sel_build_prev_vers(
1647 if (err != DB_SUCCESS) {
1649 goto lock_wait_or_error;
1652 if (old_vers == NULL) {
1660 offsets = rec_get_offsets(
1661 rec, index, offsets,
1662 ULINT_UNDEFINED, &heap);
1673 row_sel_fetch_columns(
1674 index, rec, offsets,
1678 if (!row_sel_test_end_conds(plan)) {
1680 goto table_exhausted;
1690 cons_read_requires_clust_rec = TRUE;
1701 row_sel_fetch_columns(index, rec, offsets,
1712 }
else if (!row_sel_test_end_conds(plan)) {
1714 goto table_exhausted;
1718 && !cons_read_requires_clust_rec) {
1726 goto table_exhausted;
1740 err = row_sel_get_clust_rec(node, plan, rec, thr, &clust_rec,
1742 mtr_has_extra_clust_latch = TRUE;
1750 goto lock_wait_or_error;
1758 if (clust_rec == NULL) {
1760 ut_ad(consistent_read);
1775 btr_pcur_store_position(&(plan->
clust_pcur), &mtr);
1781 if (!row_sel_test_other_conds(plan)) {
1785 goto table_exhausted;
1807 sel_push_prefetched_row(plan);
1813 sel_pop_prefetched_row(plan);
1819 ut_ad(!search_latch_locked);
1821 if (mtr_has_extra_clust_latch) {
1828 goto commit_mtr_for_a_while;
1834 moved = btr_pcur_move_to_prev(&(plan->
pcur), &mtr);
1839 goto table_exhausted;
1842 cursor_just_opened = FALSE;
1858 ut_ad(!search_latch_locked);
1862 btr_pcur_store_position(&(plan->
pcur), &mtr);
1867 mtr_has_extra_clust_latch = FALSE;
1875 sel_eval_select_list(node);
1882 sel_assign_into_var_values(node->
into_list, node);
1907 mtr_has_extra_clust_latch = FALSE;
1912 sel_pop_prefetched_row(plan);
1914 goto next_table_no_mtr;
1917 table_exhausted_no_mtr:
1925 sel_assign_into_var_values(node->
into_list, node);
1951 ut_ad(!search_latch_locked);
1954 btr_pcur_store_position(&(plan->
pcur), &mtr);
1958 #ifdef UNIV_SYNC_DEBUG
1959 ut_ad(sync_thread_levels_empty_gen(TRUE));
1964 commit_mtr_for_a_while:
1971 ut_ad(!search_latch_locked);
1972 btr_pcur_store_position(&(plan->
pcur), &mtr);
1976 mtr_has_extra_clust_latch = FALSE;
1978 #ifdef UNIV_SYNC_DEBUG
1979 ut_ad(sync_thread_levels_empty_gen(TRUE));
1988 ut_ad(!search_latch_locked);
1991 btr_pcur_store_position(&(plan->
pcur), &mtr);
1995 #ifdef UNIV_SYNC_DEBUG
1996 ut_ad(sync_thread_levels_empty_gen(TRUE));
2000 if (search_latch_locked) {
2003 if (UNIV_LIKELY_NULL(heap)) {
2054 i_lock_mode = LOCK_IX;
2056 i_lock_mode = LOCK_IS;
2061 while (table_node) {
2063 static_cast<lock_mode>(i_lock_mode), thr);
2064 if (err != DB_SUCCESS) {
2082 row_sel_copy_input_variable_vals(node);
2090 sel_reset_aggregate_vals(node);
2096 err = row_sel(node, thr);
2104 if (err != DB_SUCCESS) {
2137 sel_assign_into_var_values(node->
into_list,
2164 "InnoDB: Error: fetch called on a closed cursor\n");
2192 fprintf(stderr,
"row_fetch_print: row %p\n", row);
2198 const dtype_t* type = dfield_get_type(dfield);
2200 fprintf(stderr,
" column %lu:\n", (ulong)i);
2210 fputs(
" <NULL>;\n", stderr);
2269 fputs(
" ::: ", stderr);
2302 const byte* key_ptr,
2306 byte* original_buf = buf;
2307 const byte* original_key_ptr = key_ptr;
2312 ulint data_field_len;
2314 const byte* key_end;
2320 key_end = key_ptr + key_len;
2324 dtuple_set_n_fields(tuple, ULINT_MAX);
2326 dfield = dtuple_get_nth_field(tuple, 0);
2327 field = dict_index_get_nth_field(index, 0);
2329 if (UNIV_UNLIKELY(dfield_get_type(dfield)->mtype == DATA_SYS)) {
2336 ut_a(key_len == DATA_ROW_ID_LEN);
2340 dtuple_set_n_fields(tuple, 1);
2345 while (key_ptr < key_end) {
2347 ulint type = dfield_get_type(dfield)->mtype;
2353 if (!(dfield_get_type(dfield)->prtype & DATA_NOT_NULL)) {
2359 if (*key_ptr != 0) {
2368 if (type == DATA_BLOB) {
2383 data_len = key_ptr[data_offset]
2384 + 256 * key_ptr[data_offset + 1];
2385 data_field_len = data_offset + 2 + field->
prefix_len;
2405 data_field_len = data_offset + data_len;
2407 data_len = dfield_get_type(dfield)->len;
2408 data_field_len = data_offset + data_len;
2413 == DATA_MYSQL_TRUE_VARCHAR)
2414 && UNIV_LIKELY(type != DATA_INT)) {
2425 data_field_len += 2;
2430 if (UNIV_LIKELY(!is_null)) {
2434 key_ptr + data_offset, data_len,
2439 key_ptr += data_field_len;
2441 if (UNIV_UNLIKELY(key_ptr > key_end)) {
2453 fputs(
" InnoDB: Warning: using a partial-field"
2454 " key prefix in search.\n"
2455 "InnoDB: ", stderr);
2456 dict_index_name_print(stderr, trx, index);
2457 fprintf(stderr,
". Last data field length %lu bytes,\n"
2458 "InnoDB: key ptr now exceeds"
2459 " key end by %lu bytes.\n"
2460 "InnoDB: Key value in the MySQL format:\n",
2461 (ulong) data_field_len,
2462 (ulong) (key_ptr - key_end));
2470 - (ulint) (key_ptr - key_end));
2479 ut_a(buf <= original_buf + buf_len);
2484 dtuple_set_n_fields(tuple, n_fields);
2491 row_sel_store_row_id_to_prebuilt(
2494 const rec_t* index_rec,
2496 const ulint* offsets)
2504 data = rec_get_nth_field(
2508 if (UNIV_UNLIKELY(len != DATA_ROW_ID_LEN)) {
2510 "InnoDB: Error: Row id field is"
2511 " wrong length %lu in ", (ulong) len);
2512 dict_index_name_print(stderr, prebuilt->
trx, index);
2513 fprintf(stderr,
"\n"
2514 "InnoDB: Field number %lu, record:\n",
2530 row_sel_field_store_in_mysql_format(
2548 ut_ad(len != UNIV_SQL_NULL);
2549 UNIV_MEM_ASSERT_RW(data, len);
2551 switch (templ->
type) {
2552 const byte* field_end;
2570 dest[len - 1] = (byte) (dest[len - 1] ^ 128);
2581 if (templ->
mysql_type == DATA_MYSQL_TRUE_VARCHAR) {
2612 if (UNIV_UNLIKELY(len & 1)) {
2616 if (pad < field_end) {
2634 memcpy(dest, data, len);
2658 case DATA_SYS_CHILD:
2664 case DATA_FIXBINARY:
2671 memcpy(dest, data, len);
2683 __attribute__((warn_unused_result))
2686 row_sel_store_mysql_rec(
2697 const ulint* offsets)
2709 if (UNIV_LIKELY_NULL(prebuilt->
blob_heap)) {
2714 for (i = 0; i < prebuilt->
n_template ; i++) {
2721 field_no = rec_clust
2729 ut_a(!prebuilt->
trx->has_search_latch);
2731 if (UNIV_UNLIKELY(templ->
type == DATA_BLOB)) {
2742 heap = extern_field_heap;
2749 data = btr_rec_copy_externally_stored_field(
2752 field_no, &len, heap);
2754 if (UNIV_UNLIKELY(!data)) {
2762 if (extern_field_heap) {
2769 if (UNIV_UNLIKELY(!data)) {
2777 if (extern_field_heap) {
2784 ut_a(len != UNIV_SQL_NULL);
2788 data = rec_get_nth_field(rec, offsets, field_no, &len);
2790 if (UNIV_UNLIKELY(templ->
type == DATA_BLOB)
2791 && len != UNIV_SQL_NULL) {
2810 if (len != UNIV_SQL_NULL) {
2811 row_sel_field_store_in_mysql_format(
2816 if (extern_field_heap) {
2818 extern_field_heap = NULL;
2851 row_sel_build_prev_vers_for_mysql(
2876 rec, mtr, clust_index, offsets, read_view, offset_heap,
2888 row_sel_get_clust_rec_for_mysql(
2897 const rec_t** out_rec,
2912 const rec_t* clust_rec;
2921 sec_index, *offsets, trx);
2923 clust_index = dict_table_get_first_index(sec_index->
table);
2925 btr_pcur_open_with_no_init(clust_index, prebuilt->
clust_ref,
2929 clust_rec = btr_pcur_get_rec(prebuilt->
clust_pcur);
2953 fputs(
" InnoDB: error clustered record"
2954 " for sec rec not found\n"
2955 "InnoDB: ", stderr);
2956 dict_index_name_print(stderr, trx, sec_index);
2958 "InnoDB: sec index record ", stderr);
2961 "InnoDB: clust index record ", stderr);
2962 rec_print(stderr, clust_rec, clust_index);
2967 "InnoDB: Submit a detailed bug report"
2968 " to http://bugs.mysql.com\n", stderr);
2977 *offsets = rec_get_offsets(clust_rec, clust_index, *offsets,
2978 ULINT_UNDEFINED, offset_heap);
2987 clust_rec, clust_index, *offsets,
3006 if (trx->isolation_level > TRX_ISO_READ_UNCOMMITTED
3008 clust_rec, clust_index, *offsets,
3013 err =
static_cast<db_err>(row_sel_build_prev_vers_for_mysql(
3015 clust_rec, offsets, offset_heap, &old_vers,
3018 if (err != DB_SUCCESS || old_vers == NULL) {
3023 clust_rec = old_vers;
3041 || trx->isolation_level <= TRX_ISO_READ_UNCOMMITTED
3044 && !row_sel_sec_rec_is_for_clust_rec(
3045 rec, sec_index, clust_rec, clust_index)) {
3047 #ifdef UNIV_SEARCH_DEBUG
3049 ut_a(clust_rec == NULL
3050 || row_sel_sec_rec_is_for_clust_rec(
3051 rec, sec_index, clust_rec, clust_index));
3059 *out_rec = clust_rec;
3065 btr_pcur_store_position(prebuilt->
clust_pcur, mtr);
3080 sel_restore_position_for_mysql(
3082 ibool* same_user_rec,
3096 ulint relative_position;
3098 relative_position = pcur->
rel_pos;
3100 success = btr_pcur_restore_position(latch_mode, pcur, mtr);
3102 *same_user_rec = success;
3104 if (relative_position == BTR_PCUR_ON) {
3116 if (relative_position == BTR_PCUR_AFTER
3117 || relative_position == BTR_PCUR_AFTER_LAST_IN_TREE) {
3124 btr_pcur_move_to_prev(pcur, mtr);
3130 ut_ad(relative_position == BTR_PCUR_BEFORE
3131 || relative_position == BTR_PCUR_BEFORE_FIRST_IN_TREE);
3144 row_sel_pop_cached_row_for_mysql(
3165 UNIV_MEM_ASSERT_RW(cached_rec
3205 __attribute__((warn_unused_result))
3208 row_sel_push_cache_row_for_mysql(
3218 const ulint* offsets)
3231 for (i = 0; i < MYSQL_FETCH_CACHE_SIZE; i++) {
3237 buf =
static_cast<byte *
>(mem_alloc(prebuilt->
mysql_row_len + 8));
3243 ROW_PREBUILT_FETCH_MAGIC_N);
3251 if (UNIV_UNLIKELY(!row_sel_store_mysql_rec(
3254 prebuilt, rec, rec_clust, offsets))) {
3270 row_sel_try_search_shortcut_for_mysql(
3272 const rec_t** out_rec,
3287 #ifndef UNIV_SEARCH_DEBUG
3288 btr_pcur_open_with_no_init(index, search_tuple, PAGE_CUR_GE,
3293 btr_pcur_open_with_no_init(index, search_tuple, PAGE_CUR_GE,
3298 rec = btr_pcur_get_rec(pcur);
3311 return(SEL_EXHAUSTED);
3317 *offsets = rec_get_offsets(rec, index, *offsets,
3318 ULINT_UNDEFINED, heap);
3328 return(SEL_EXHAUSTED);
3374 const rec_t* result_rec;
3375 const rec_t* clust_rec;
3376 ulint err = DB_SUCCESS;
3377 ibool unique_search = FALSE;
3378 ibool unique_search_from_clust_index = FALSE;
3379 ibool mtr_has_extra_clust_latch = FALSE;
3380 ibool moves_up = FALSE;
3381 ibool set_also_gap_locks = TRUE;
3384 ibool did_semi_consistent_read = FALSE;
3388 #ifdef UNIV_SEARCH_DEBUG
3392 ibool same_user_rec;
3395 ulint offsets_[REC_OFFS_NORMAL_SIZE];
3396 ulint* offsets = offsets_;
3397 ibool table_lock_waited = FALSE;
3399 rec_offs_init(offsets_);
3401 ut_ad(index && pcur && search_tuple);
3406 fprintf(stderr,
" InnoDB: Error:\n"
3407 "InnoDB: MySQL is trying to use a table handle"
3408 " but the .ibd file for\n"
3409 "InnoDB: table %s does not exist.\n"
3410 "InnoDB: Have you deleted the .ibd file"
3411 " from the database directory under\n"
3412 "InnoDB: the MySQL datadir, or have you used"
3413 " DISCARD TABLESPACE?\n"
3414 "InnoDB: Look from\n"
3415 "InnoDB: " REFMAN
"innodb-troubleshooting.html\n"
3416 "InnoDB: how you can resolve the problem.\n",
3424 return(DB_MISSING_HISTORY);
3427 if (UNIV_UNLIKELY(prebuilt->
magic_n != ROW_PREBUILT_ALLOCATED)) {
3429 "InnoDB: Error: trying to free a corrupt\n"
3430 "InnoDB: table handle. Magic n %lu, table name ",
3441 fprintf(stderr,
"Match mode %lu\n search tuple ",
3442 (ulong) match_mode);
3443 dtuple_print(search_tuple);
3444 fprintf(stderr,
"N tables locked %lu\n",
3445 (ulong) trx->mysql_n_tables_locked);
3452 && trx->has_search_latch) {
3460 trx->has_search_latch = FALSE;
3474 if (UNIV_UNLIKELY(direction == 0)) {
3475 trx->
op_info =
"starting index read";
3486 trx->
op_info =
"fetching rows";
3506 row_sel_pop_cached_row_for_mysql(buf, prebuilt);
3522 err = DB_RECORD_NOT_FOUND;
3558 unique_search = TRUE;
3564 if (UNIV_UNLIKELY(direction != 0)) {
3566 err = DB_RECORD_NOT_FOUND;
3582 if (UNIV_UNLIKELY(direction == 0)
3590 unique_search_from_clust_index = TRUE;
3592 if (trx->mysql_n_tables_locked == 0
3594 && trx->isolation_level > TRX_ISO_READ_UNCOMMITTED
3609 #ifndef UNIV_SEARCH_DEBUG
3610 if (!trx->has_search_latch) {
3612 trx->has_search_latch = TRUE;
3615 switch (row_sel_try_search_shortcut_for_mysql(
3616 &rec, prebuilt, &offsets, &heap,
3619 #ifdef UNIV_SEARCH_DEBUG
3630 if (!row_sel_store_mysql_rec(buf, prebuilt,
3643 ut_a(trx->isolation_level
3644 == TRX_ISO_READ_UNCOMMITTED);
3658 goto release_search_latch_if_needed;
3666 err = DB_RECORD_NOT_FOUND;
3667 release_search_latch_if_needed:
3668 if (trx->search_latch_timeout > 0
3669 && trx->has_search_latch) {
3671 trx->search_latch_timeout--;
3674 trx->has_search_latch = FALSE;
3696 if (trx->has_search_latch) {
3698 trx->has_search_latch = FALSE;
3717 if (trx->isolation_level <= TRX_ISO_READ_COMMITTED
3724 set_also_gap_locks = FALSE;
3731 if (UNIV_UNLIKELY(direction == 0)) {
3732 if (mode == PAGE_CUR_GE || mode == PAGE_CUR_G) {
3743 clust_index = dict_table_get_first_index(index->
table);
3753 fputs(
"InnoDB: Error: MySQL is trying to"
3754 " perform a consistent read\n"
3755 "InnoDB: but the read view is not assigned!\n",
3758 fputc(
'\n', stderr);
3771 ? LOCK_IS : LOCK_IX, thr);
3773 if (err != DB_SUCCESS) {
3775 table_lock_waited = TRUE;
3776 goto lock_table_wait;
3783 if (UNIV_LIKELY(direction != 0)) {
3784 ibool need_to_process = sel_restore_position_for_mysql(
3786 pcur, moves_up, &mtr);
3788 if (UNIV_UNLIKELY(need_to_process)) {
3790 == ROW_READ_DID_SEMI_CONSISTENT)) {
3795 = ROW_READ_TRY_SEMI_CONSISTENT;
3798 != ROW_READ_DID_SEMI_CONSISTENT)) {
3811 btr_pcur_open_with_no_init(index, search_tuple, mode,
3817 rec = btr_pcur_get_rec(pcur);
3821 && set_also_gap_locks
3823 || trx->isolation_level <= TRX_ISO_READ_COMMITTED)
3830 offsets = rec_get_offsets(next, index, offsets,
3831 ULINT_UNDEFINED, &heap);
3832 err = sel_set_rec_lock(btr_pcur_get_block(pcur),
3833 next, index, offsets,
3843 goto lock_wait_or_error;
3847 if (mode == PAGE_CUR_G) {
3851 }
else if (mode == PAGE_CUR_L) {
3862 rec = btr_pcur_get_rec(pcur);
3864 #ifdef UNIV_SEARCH_DEBUG
3885 if (set_also_gap_locks
3887 || trx->isolation_level <= TRX_ISO_READ_COMMITTED)
3897 offsets = rec_get_offsets(rec, index, offsets,
3898 ULINT_UNDEFINED, &heap);
3899 err = sel_set_rec_lock(btr_pcur_get_block(pcur),
3900 rec, index, offsets,
3910 goto lock_wait_or_error;
3925 if (UNIV_UNLIKELY(next_offs < PAGE_NEW_SUPREMUM)) {
3931 if (UNIV_UNLIKELY(next_offs < PAGE_OLD_SUPREMUM)) {
3937 if (UNIV_UNLIKELY(next_offs >= UNIV_PAGE_SIZE - PAGE_DIR)) {
3940 if (srv_force_recovery == 0 || moves_up == FALSE) {
3944 "\nInnoDB: rec address %p,"
3945 " buf block fix count %lu\n",
3946 (
void*) rec, (ulong)
3948 ->page.buf_fix_count);
3950 "InnoDB: Index corruption: rec offs %lu"
3951 " next offs %lu, page no %lu,\n"
3956 dict_index_name_print(stderr, trx, index);
3957 fputs(
". Run CHECK TABLE. You may need to\n"
3958 "InnoDB: restore from a backup, or"
3959 " dump + drop + reimport the table.\n",
3962 err = DB_CORRUPTION;
3964 goto lock_wait_or_error;
3970 "InnoDB: Index corruption: rec offs %lu"
3971 " next offs %lu, page no %lu,\n"
3976 dict_index_name_print(stderr, trx, index);
3977 fputs(
". We try to skip the rest of the page.\n",
3989 offsets = rec_get_offsets(rec, index, offsets, ULINT_UNDEFINED, &heap);
3991 if (UNIV_UNLIKELY(srv_force_recovery > 0)) {
3993 || !btr_index_rec_validate(rec, index, FALSE)) {
3995 "InnoDB: Index corruption: rec offs %lu"
3996 " next offs %lu, page no %lu,\n"
4001 dict_index_name_print(stderr, trx, index);
4002 fputs(
". We try to skip the record.\n",
4022 if (set_also_gap_locks
4024 || trx->isolation_level
4025 <= TRX_ISO_READ_COMMITTED)
4033 err = sel_set_rec_lock(
4034 btr_pcur_get_block(pcur),
4035 rec, index, offsets,
4044 goto lock_wait_or_error;
4048 btr_pcur_store_position(pcur, &mtr);
4050 err = DB_RECORD_NOT_FOUND;
4061 if (set_also_gap_locks
4063 || trx->isolation_level
4064 <= TRX_ISO_READ_COMMITTED)
4072 err = sel_set_rec_lock(
4073 btr_pcur_get_block(pcur),
4074 rec, index, offsets,
4083 goto lock_wait_or_error;
4087 btr_pcur_store_position(pcur, &mtr);
4089 err = DB_RECORD_NOT_FOUND;
4113 if (!set_also_gap_locks
4115 || trx->isolation_level <= TRX_ISO_READ_COMMITTED
4135 if (index == clust_index
4136 && mode == PAGE_CUR_GE
4145 err = sel_set_rec_lock(btr_pcur_get_block(pcur),
4146 rec, index, offsets,
4151 const rec_t* old_vers;
4154 || trx->isolation_level
4155 <= TRX_ISO_READ_COMMITTED) {
4168 != ROW_READ_TRY_SEMI_CONSISTENT)
4170 || index != clust_index) {
4172 goto lock_wait_or_error;
4177 err = row_sel_build_committed_vers_for_mysql(
4178 clust_index, prebuilt, rec,
4179 &offsets, &heap, &old_vers, &mtr);
4187 goto lock_wait_or_error;
4190 mutex_enter(&kernel_mutex);
4191 if (trx->was_chosen_as_deadlock_victim) {
4192 mutex_exit(&kernel_mutex);
4195 goto lock_wait_or_error;
4197 if (UNIV_LIKELY(trx->
wait_lock != NULL)) {
4201 mutex_exit(&kernel_mutex);
4207 offsets = rec_get_offsets(rec, index, offsets,
4213 mutex_exit(&kernel_mutex);
4215 if (old_vers == NULL) {
4221 did_semi_consistent_read = TRUE;
4226 goto lock_wait_or_error;
4232 if (trx->isolation_level == TRX_ISO_READ_UNCOMMITTED) {
4237 }
else if (index == clust_index) {
4244 if (UNIV_LIKELY(srv_force_recovery < 5)
4251 err = row_sel_build_prev_vers_for_mysql(
4253 prebuilt, rec, &offsets, &heap,
4261 goto lock_wait_or_error;
4264 if (old_vers == NULL) {
4283 goto requires_clust_rec;
4298 || trx->isolation_level <= TRX_ISO_READ_COMMITTED)
4300 && !did_semi_consistent_read) {
4319 if (index == clust_index && unique_search) {
4320 err = DB_RECORD_NOT_FOUND;
4343 mtr_has_extra_clust_latch = TRUE;
4349 err = row_sel_get_clust_rec_for_mysql(prebuilt, index, rec,
4351 &offsets, &heap, &mtr);
4354 if (clust_rec == NULL) {
4362 ut_a(clust_rec != NULL);
4364 || trx->isolation_level
4365 <= TRX_ISO_READ_COMMITTED) {
4373 goto lock_wait_or_error;
4381 || trx->isolation_level <= TRX_ISO_READ_COMMITTED)
4394 result_rec = clust_rec;
4404 result_rec != rec ? clust_index : index,
4418 != ROW_MYSQL_DUMMY_TEMPLATE) {
4429 if (!row_sel_push_cache_row_for_mysql(prebuilt, result_rec,
4439 ut_a(trx->isolation_level == TRX_ISO_READ_UNCOMMITTED);
4441 == MYSQL_FETCH_CACHE_SIZE) {
4452 if (result_rec != rec
4456 offsets = rec_get_offsets(rec, index, offsets,
4462 memcpy(buf + 4, result_rec
4470 if (!row_sel_store_mysql_rec(buf, prebuilt, result_rec,
4481 ut_a(trx->isolation_level
4482 == TRX_ISO_READ_UNCOMMITTED);
4488 if (result_rec != rec) {
4489 offsets = rec_get_offsets(
4490 rec, index, offsets, ULINT_UNDEFINED,
4493 row_sel_store_row_id_to_prebuilt(prebuilt, rec,
4508 if (!unique_search_from_clust_index
4513 btr_pcur_store_position(pcur, &mtr);
4523 == ROW_READ_DID_SEMI_CONSISTENT)) {
4526 did_semi_consistent_read = FALSE;
4532 if (UNIV_UNLIKELY(mtr_has_extra_clust_latch)) {
4538 btr_pcur_store_position(pcur, &mtr);
4541 mtr_has_extra_clust_latch = FALSE;
4544 if (sel_restore_position_for_mysql(&same_user_rec,
4546 pcur, moves_up, &mtr)) {
4547 #ifdef UNIV_SEARCH_DEBUG
4558 btr_pcur_store_position(pcur, &mtr);
4560 if (match_mode != 0) {
4561 err = DB_RECORD_NOT_FOUND;
4563 err = DB_END_OF_INDEX;
4569 if (UNIV_UNLIKELY(!btr_pcur_move_to_prev(pcur, &mtr))) {
4574 #ifdef UNIV_SEARCH_DEBUG
4583 == ROW_READ_DID_SEMI_CONSISTENT)) {
4586 did_semi_consistent_read = FALSE;
4590 btr_pcur_store_position(pcur, &mtr);
4594 mtr_has_extra_clust_latch = FALSE;
4612 if (table_lock_waited) {
4613 table_lock_waited = FALSE;
4615 goto wait_table_again;
4618 sel_restore_position_for_mysql(&same_user_rec,
4623 || trx->isolation_level <= TRX_ISO_READ_COMMITTED)
4624 && !same_user_rec) {
4652 #ifdef UNIV_SEARCH_DEBUG
4666 row_sel_pop_cached_row_for_mysql(buf, prebuilt);
4671 #ifdef UNIV_SEARCH_DEBUG
4676 if (err == DB_SUCCESS) {
4682 if (UNIV_LIKELY_NULL(heap)) {
4690 || !did_semi_consistent_read);
4692 if (UNIV_UNLIKELY(prebuilt->
row_read_type != ROW_READ_WITH_LOCKS)) {
4693 if (UNIV_UNLIKELY(did_semi_consistent_read)) {
4711 const char* norm_name)
4717 table = dict_table_get(norm_name, FALSE);
4719 if (table == NULL) {
4724 mutex_enter(&kernel_mutex);
4743 if (trx->isolation_level >= TRX_ISO_REPEATABLE_READ
4747 trx->
id, trx->global_read_view_heap);
4752 mutex_exit(&kernel_mutex);
4763 row_search_autoinc_read_column(
4769 ibool unsigned_type)
4775 ulint offsets_[REC_OFFS_NORMAL_SIZE];
4776 ulint* offsets = offsets_;
4778 rec_offs_init(offsets_);
4780 offsets = rec_get_offsets(rec, index, offsets, ULINT_UNDEFINED, &heap);
4782 data = rec_get_nth_field(rec, offsets, col_no, &len);
4784 ut_a(len != UNIV_SQL_NULL);
4788 ut_a(len <=
sizeof value);
4793 ut_a(len ==
sizeof(
float));
4798 ut_a(len ==
sizeof(
double));
4806 if (UNIV_LIKELY_NULL(heap)) {
4810 if (!unsigned_type && (ib_int64_t) value < 0) {
4822 row_search_autoinc_get_rec(
4828 const rec_t* rec = btr_pcur_get_rec(pcur);
4833 }
while (btr_pcur_move_to_prev(pcur, mtr));
4847 const char* col_name,
4853 ulint error = DB_SUCCESS;
4858 for (i = 0; i < n_cols; ++i) {
4859 dfield = dict_index_get_nth_field(index, i);
4861 if (strcmp(col_name, dfield->
name) == 0) {
4869 if (i < n_cols && dfield) {
4883 rec = row_search_autoinc_get_rec(&pcur, &mtr);
4886 ibool unsigned_type = (
4889 *value = row_search_autoinc_read_column(
4891 dfield->
col->
mtype, unsigned_type);
4899 error = DB_RECORD_NOT_FOUND;