Loading innobase/btr/btr0cur.c +6 −2 Original line number Diff line number Diff line Loading @@ -316,7 +316,9 @@ btr_cur_search_to_nth_level( if (btr_search_latch.writer == RW_LOCK_NOT_LOCKED && latch_mode <= BTR_MODIFY_LEAF && info->last_hash_succ && !estimate #ifdef PAGE_CUR_LE_OR_EXTENDS && mode != PAGE_CUR_LE_OR_EXTENDS #endif /* PAGE_CUR_LE_OR_EXTENDS */ && srv_use_adaptive_hash_indexes && btr_search_guess_on_hash(index, info, tuple, mode, latch_mode, cursor, Loading Loading @@ -391,8 +393,10 @@ btr_cur_search_to_nth_level( break; default: ut_ad(mode == PAGE_CUR_L || mode == PAGE_CUR_LE || mode == PAGE_CUR_LE_OR_EXTENDS); #ifdef PAGE_CUR_LE_OR_EXTENDS || mode == PAGE_CUR_LE_OR_EXTENDS #endif /* PAGE_CUR_LE_OR_EXTENDS */ || mode == PAGE_CUR_LE); page_mode = mode; break; } Loading innobase/include/page0cur.h +4 −2 Original line number Diff line number Diff line Loading @@ -26,11 +26,13 @@ Created 10/4/1994 Heikki Tuuri #define PAGE_CUR_GE 2 #define PAGE_CUR_L 3 #define PAGE_CUR_LE 4 #define PAGE_CUR_LE_OR_EXTENDS 5 /* This is a search mode used in /*#define PAGE_CUR_LE_OR_EXTENDS 5*/ /* This is a search mode used in "column LIKE 'abc%' ORDER BY column DESC"; we have to find strings which are <= 'abc' or which extend it */ #define PAGE_CUR_DBG 6 #ifdef UNIV_SEARCH_DEBUG # define PAGE_CUR_DBG 6 /* As PAGE_CUR_LE, but skips search shortcut */ #endif /* UNIV_SEARCH_DEBUG */ #ifdef PAGE_CUR_ADAPT # ifdef UNIV_SEARCH_PERF_STAT Loading innobase/page/page0cur.c +56 −44 Original line number Diff line number Diff line Loading @@ -47,7 +47,6 @@ page_cur_try_search_shortcut( not yet completely matched */ page_cur_t* cursor) /* out: page cursor */ { int cmp; rec_t* rec; rec_t* next_rec; ulint low_match; Loading Loading @@ -79,9 +78,8 @@ page_cur_try_search_shortcut( up_match = low_match; up_bytes = low_bytes; cmp = page_cmp_dtuple_rec_with_match(tuple, rec, offsets, &low_match, &low_bytes); if (cmp == -1) { if (page_cmp_dtuple_rec_with_match(tuple, rec, offsets, &low_match, &low_bytes) < 0) { goto exit_func; } Loading @@ -89,9 +87,8 @@ page_cur_try_search_shortcut( offsets = rec_get_offsets(next_rec, index, offsets, dtuple_get_n_fields(tuple), &heap); cmp = page_cmp_dtuple_rec_with_match(tuple, next_rec, offsets, &up_match, &up_bytes); if (cmp != -1) { if (page_cmp_dtuple_rec_with_match(tuple, next_rec, offsets, &up_match, &up_bytes) >= 0) { goto exit_func; } Loading @@ -115,7 +112,7 @@ page_cur_try_search_shortcut( ut_a(*ilow_matched_fields == low_match); ut_a(*ilow_matched_bytes == low_bytes); #endif if (next_rec != page_get_supremum_rec(page)) { if (!page_rec_is_supremum(next_rec)) { *iup_matched_fields = up_match; *iup_matched_bytes = up_bytes; Loading @@ -137,6 +134,7 @@ page_cur_try_search_shortcut( #endif #ifdef PAGE_CUR_LE_OR_EXTENDS /******************************************************************** Checks if the nth field in a record is a character type field which extends the nth field in tuple, i.e., the field is longer or equal in length and has Loading Loading @@ -185,6 +183,7 @@ page_cur_rec_field_extends( return(FALSE); } #endif /* PAGE_CUR_LE_OR_EXTENDS */ /******************************************************************** Searches the right position for a page cursor. */ Loading Loading @@ -240,8 +239,13 @@ page_cur_search_with_match( ut_ad(dtuple_validate(tuple)); ut_ad(dtuple_check_typed(tuple)); ut_ad((mode == PAGE_CUR_L) || (mode == PAGE_CUR_LE) || (mode == PAGE_CUR_G) || (mode == PAGE_CUR_GE) || (mode == PAGE_CUR_LE_OR_EXTENDS) || (mode == PAGE_CUR_DBG)); #ifdef PAGE_CUR_DBG || (mode == PAGE_CUR_DBG) #endif /* PAGE_CUR_DBG */ #ifdef PAGE_CUR_LE_OR_EXTENDS || (mode == PAGE_CUR_LE_OR_EXTENDS) #endif /* PAGE_CUR_LE_OR_EXTENDS */ || (mode == PAGE_CUR_G) || (mode == PAGE_CUR_GE)); page_check_dir(page); Loading @@ -261,16 +265,18 @@ page_cur_search_with_match( return; } } /*#ifdef UNIV_SEARCH_DEBUG */ # ifdef PAGE_CUR_DBG if (mode == PAGE_CUR_DBG) { mode = PAGE_CUR_LE; } /*#endif */ # endif #endif /* The following flag does not work for non-latin1 char sets because cmp_full_field does not tell how many bytes matched */ #ifdef PAGE_CUR_LE_OR_EXTENDS ut_a(mode != PAGE_CUR_LE_OR_EXTENDS); #endif /* PAGE_CUR_LE_OR_EXTENDS */ /* If mode PAGE_CUR_G is specified, we are trying to position the cursor to answer a query of the form "tuple < X", where tuple is Loading Loading @@ -308,33 +314,36 @@ page_cur_search_with_match( cmp = cmp_dtuple_rec_with_match(tuple, mid_rec, offsets, &cur_matched_fields, &cur_matched_bytes); if (cmp == 1) { if (UNIV_LIKELY(cmp > 0)) { low_slot_match: low = mid; low_matched_fields = cur_matched_fields; low_matched_bytes = cur_matched_bytes; } else if (cmp == -1) { } else if (UNIV_LIKELY(cmp /* == -1 */)) { #ifdef PAGE_CUR_LE_OR_EXTENDS if (mode == PAGE_CUR_LE_OR_EXTENDS && page_cur_rec_field_extends(tuple, mid_rec, offsets, cur_matched_fields)) { low = mid; low_matched_fields = cur_matched_fields; low_matched_bytes = cur_matched_bytes; } else { goto low_slot_match; } #endif /* PAGE_CUR_LE_OR_EXTENDS */ up_slot_match: up = mid; up_matched_fields = cur_matched_fields; up_matched_bytes = cur_matched_bytes; } } else if (mode == PAGE_CUR_G || mode == PAGE_CUR_LE || mode == PAGE_CUR_LE_OR_EXTENDS) { low = mid; low_matched_fields = cur_matched_fields; low_matched_bytes = cur_matched_bytes; #ifdef PAGE_CUR_LE_OR_EXTENDS || mode == PAGE_CUR_LE_OR_EXTENDS #endif /* PAGE_CUR_LE_OR_EXTENDS */ ) { goto low_slot_match; } else { up = mid; up_matched_fields = cur_matched_fields; up_matched_bytes = cur_matched_bytes; goto up_slot_match; } } Loading @@ -360,32 +369,35 @@ page_cur_search_with_match( cmp = cmp_dtuple_rec_with_match(tuple, mid_rec, offsets, &cur_matched_fields, &cur_matched_bytes); if (cmp == 1) { if (UNIV_LIKELY(cmp > 0)) { low_rec_match: low_rec = mid_rec; low_matched_fields = cur_matched_fields; low_matched_bytes = cur_matched_bytes; } else if (cmp == -1) { } else if (UNIV_LIKELY(cmp /* == -1 */)) { #ifdef PAGE_CUR_LE_OR_EXTENDS if (mode == PAGE_CUR_LE_OR_EXTENDS && page_cur_rec_field_extends(tuple, mid_rec, offsets, cur_matched_fields)) { low_rec = mid_rec; low_matched_fields = cur_matched_fields; low_matched_bytes = cur_matched_bytes; } else { goto low_rec_match; } #endif /* PAGE_CUR_LE_OR_EXTENDS */ up_rec_match: up_rec = mid_rec; up_matched_fields = cur_matched_fields; up_matched_bytes = cur_matched_bytes; } } else if (mode == PAGE_CUR_G || mode == PAGE_CUR_LE || mode == PAGE_CUR_LE_OR_EXTENDS) { low_rec = mid_rec; low_matched_fields = cur_matched_fields; low_matched_bytes = cur_matched_bytes; #ifdef PAGE_CUR_LE_OR_EXTENDS || mode == PAGE_CUR_LE_OR_EXTENDS #endif /* PAGE_CUR_LE_OR_EXTENDS */ ) { goto low_rec_match; } else { up_rec = mid_rec; up_matched_fields = cur_matched_fields; up_matched_bytes = cur_matched_bytes; goto up_rec_match; } } Loading innobase/rem/rem0rec.c +67 −38 Original line number Diff line number Diff line Loading @@ -601,30 +601,38 @@ rec_set_nth_field_extern_bit_new( /* read the lengths of fields 0..n */ for (i = 0; i < n_fields; i++) { ibool is_null; ulint len; field = dict_index_get_nth_field(index, i); type = dict_col_get_type(dict_field_get_col(field)); is_null = !(dtype_get_prtype(type) & DATA_NOT_NULL); if (is_null) { /* nullable field => read the null flag */ is_null = !!(*nulls & null_mask); if (!(dtype_get_prtype(type) & DATA_NOT_NULL)) { if (UNIV_UNLIKELY(!(byte) null_mask)) { nulls--; null_mask = 1; } if (*nulls & null_mask) { null_mask <<= 1; if (null_mask == 0x100) nulls--, null_mask = 1; /* NULL fields cannot be external. */ ut_ad(i != ith); continue; } if (is_null || field->fixed_len) { /* No length (or extern bit) is stored for fields that are NULL or fixed-length. */ null_mask <<= 1; } if (field->fixed_len) { /* fixed-length fields cannot be external (Fixed-length fields longer than DICT_MAX_COL_PREFIX_LEN will be treated as variable-length ones in dict_index_add_col().) */ ut_ad(i != ith); continue; } len = *lens--; lens--; if (dtype_get_len(type) > 255 || dtype_get_mtype(type) == DATA_BLOB) { ulint len = lens[1]; if (len & 0x80) { /* 1exxxxxx: 2-byte length */ if (i == ith) { if (!val == !(len & 0x20)) { if (!val == !(len & 0x40)) { return; /* no change */ } /* toggle the extern bit */ Loading Loading @@ -823,6 +831,7 @@ rec_convert_dtuple_to_rec_new( byte* lens; ulint len; ulint i; ulint n_node_ptr_field; ulint fixed_len; ulint null_mask = 1; const ulint n_fields = dtuple_get_n_fields(dtuple); Loading @@ -831,16 +840,26 @@ rec_convert_dtuple_to_rec_new( ut_ad(index->table->comp); ut_ad(n_fields > 0); switch (status) { /* Try to ensure that the memset() between the for() loops completes fast. The address is not exact, but UNIV_PREFETCH should never generate a memory fault. */ UNIV_PREFETCH_RW(rec - REC_N_NEW_EXTRA_BYTES - n_fields); UNIV_PREFETCH_RW(rec); switch (UNIV_EXPECT(status, REC_STATUS_ORDINARY)) { case REC_STATUS_ORDINARY: ut_ad(n_fields <= dict_index_get_n_fields(index)); n_node_ptr_field = ULINT_UNDEFINED; break; case REC_STATUS_NODE_PTR: ut_ad(n_fields == dict_index_get_n_unique_in_tree(index) + 1); n_node_ptr_field = n_fields - 1; break; case REC_STATUS_INFIMUM: case REC_STATUS_SUPREMUM: ut_ad(n_fields == 1); n_node_ptr_field = ULINT_UNDEFINED; goto init; default: ut_a(0); Loading @@ -852,15 +871,18 @@ rec_convert_dtuple_to_rec_new( rec += (index->n_nullable + 7) / 8; for (i = 0; i < n_fields; i++) { if (UNIV_UNLIKELY(i == n_node_ptr_field)) { #ifdef UNIV_DEBUG field = dtuple_get_nth_field(dtuple, i); type = dfield_get_type(field); len = dfield_get_len(field); if (status == REC_STATUS_NODE_PTR && i == n_fields - 1) { fixed_len = 4; ut_ad(dtype_get_prtype(type) & DATA_NOT_NULL); ut_ad(len == 4); continue; ut_ad(dfield_get_len(field) == 4); #endif /* UNIV_DEBUG */ goto init; } field = dtuple_get_nth_field(dtuple, i); type = dfield_get_type(field); len = dfield_get_len(field); fixed_len = dict_index_get_nth_field(index, i)->fixed_len; if (!(dtype_get_prtype(type) & DATA_NOT_NULL)) { Loading Loading @@ -902,28 +924,34 @@ rec_convert_dtuple_to_rec_new( type = dfield_get_type(field); len = dfield_get_len(field); if (status == REC_STATUS_NODE_PTR && i == n_fields - 1) { fixed_len = 4; if (UNIV_UNLIKELY(i == n_node_ptr_field)) { ut_ad(dtype_get_prtype(type) & DATA_NOT_NULL); ut_ad(len == 4); goto copy; memcpy(end, dfield_get_data(field), len); break; } fixed_len = dict_index_get_nth_field(index, i)->fixed_len; if (!(dtype_get_prtype(type) & DATA_NOT_NULL)) { /* nullable field */ ut_ad(index->n_nullable > 0); if (UNIV_UNLIKELY(!(byte) null_mask)) { nulls--; null_mask = 1; } ut_ad(*nulls < null_mask); /* set the null flag if necessary */ if (len == UNIV_SQL_NULL) { *nulls |= null_mask; } null_mask <<= 1; if (null_mask == 0x100) nulls--, null_mask = 1; if (len == UNIV_SQL_NULL) continue; } null_mask <<= 1; } /* only nullable fields can be null */ ut_ad(len != UNIV_SQL_NULL); if (fixed_len) { Loading @@ -942,7 +970,7 @@ rec_convert_dtuple_to_rec_new( *lens-- = (byte) len; } } copy: memcpy(end, dfield_get_data(field), len); end += len; } Loading Loading @@ -1105,7 +1133,6 @@ rec_copy_prefix_to_buf( dtype_t* type; ulint i; ulint prefix_len; ibool is_null; ulint null_mask; ulint status; Loading Loading @@ -1146,20 +1173,22 @@ rec_copy_prefix_to_buf( for (i = 0; i < n_fields; i++) { field = dict_index_get_nth_field(index, i); type = dict_col_get_type(dict_field_get_col(field)); is_null = !(dtype_get_prtype(type) & DATA_NOT_NULL); if (is_null) { if (!(dtype_get_prtype(type) & DATA_NOT_NULL)) { /* nullable field => read the null flag */ is_null = !!(*nulls & null_mask); null_mask <<= 1; if (null_mask == 0x100) { --nulls; UNIV_PREFETCH_R(nulls); if (UNIV_UNLIKELY(!(byte) null_mask)) { nulls--; null_mask = 1; } if (*nulls & null_mask) { null_mask <<= 1; continue; } null_mask <<= 1; } if (is_null) { } else if (field->fixed_len) { if (field->fixed_len) { prefix_len += field->fixed_len; } else { ulint len = *lens--; Loading sql/ha_innodb.cc +32 −9 Original line number Diff line number Diff line Loading @@ -2955,21 +2955,44 @@ build_template( templ = prebuilt->mysql_template + n_requested_fields; field = table->field[i]; ibool index_contains_field= if (UNIV_LIKELY(templ_type == ROW_MYSQL_REC_FIELDS)) { /* Decide which columns we should fetch and which we can skip. */ register const ibool index_contains_field = dict_index_contains_col_or_prefix(index, i); if (templ_type == ROW_MYSQL_REC_FIELDS && ((prebuilt->read_just_key && !index_contains_field) || (!(fetch_all_in_key && index_contains_field) && !(fetch_primary_key_cols && dict_table_col_in_clustered_key(index->table, i)) && thd->query_id != field->query_id))) { if (!index_contains_field && prebuilt->read_just_key) { /* If this is a 'key read', we do not need columns that are not in the key */ goto skip_field; } if (index_contains_field && fetch_all_in_key) { /* This field is needed in the query */ goto include_field; } if (thd->query_id == field->query_id) { /* This field is needed in the query */ goto include_field; } if (fetch_primary_key_cols && dict_table_col_in_clustered_key(index->table, i)) { /* This field is needed in the query */ goto include_field; } /* This field is not needed in the query, skip it */ goto skip_field; } include_field: n_requested_fields++; templ->col_no = i; Loading Loading
innobase/btr/btr0cur.c +6 −2 Original line number Diff line number Diff line Loading @@ -316,7 +316,9 @@ btr_cur_search_to_nth_level( if (btr_search_latch.writer == RW_LOCK_NOT_LOCKED && latch_mode <= BTR_MODIFY_LEAF && info->last_hash_succ && !estimate #ifdef PAGE_CUR_LE_OR_EXTENDS && mode != PAGE_CUR_LE_OR_EXTENDS #endif /* PAGE_CUR_LE_OR_EXTENDS */ && srv_use_adaptive_hash_indexes && btr_search_guess_on_hash(index, info, tuple, mode, latch_mode, cursor, Loading Loading @@ -391,8 +393,10 @@ btr_cur_search_to_nth_level( break; default: ut_ad(mode == PAGE_CUR_L || mode == PAGE_CUR_LE || mode == PAGE_CUR_LE_OR_EXTENDS); #ifdef PAGE_CUR_LE_OR_EXTENDS || mode == PAGE_CUR_LE_OR_EXTENDS #endif /* PAGE_CUR_LE_OR_EXTENDS */ || mode == PAGE_CUR_LE); page_mode = mode; break; } Loading
innobase/include/page0cur.h +4 −2 Original line number Diff line number Diff line Loading @@ -26,11 +26,13 @@ Created 10/4/1994 Heikki Tuuri #define PAGE_CUR_GE 2 #define PAGE_CUR_L 3 #define PAGE_CUR_LE 4 #define PAGE_CUR_LE_OR_EXTENDS 5 /* This is a search mode used in /*#define PAGE_CUR_LE_OR_EXTENDS 5*/ /* This is a search mode used in "column LIKE 'abc%' ORDER BY column DESC"; we have to find strings which are <= 'abc' or which extend it */ #define PAGE_CUR_DBG 6 #ifdef UNIV_SEARCH_DEBUG # define PAGE_CUR_DBG 6 /* As PAGE_CUR_LE, but skips search shortcut */ #endif /* UNIV_SEARCH_DEBUG */ #ifdef PAGE_CUR_ADAPT # ifdef UNIV_SEARCH_PERF_STAT Loading
innobase/page/page0cur.c +56 −44 Original line number Diff line number Diff line Loading @@ -47,7 +47,6 @@ page_cur_try_search_shortcut( not yet completely matched */ page_cur_t* cursor) /* out: page cursor */ { int cmp; rec_t* rec; rec_t* next_rec; ulint low_match; Loading Loading @@ -79,9 +78,8 @@ page_cur_try_search_shortcut( up_match = low_match; up_bytes = low_bytes; cmp = page_cmp_dtuple_rec_with_match(tuple, rec, offsets, &low_match, &low_bytes); if (cmp == -1) { if (page_cmp_dtuple_rec_with_match(tuple, rec, offsets, &low_match, &low_bytes) < 0) { goto exit_func; } Loading @@ -89,9 +87,8 @@ page_cur_try_search_shortcut( offsets = rec_get_offsets(next_rec, index, offsets, dtuple_get_n_fields(tuple), &heap); cmp = page_cmp_dtuple_rec_with_match(tuple, next_rec, offsets, &up_match, &up_bytes); if (cmp != -1) { if (page_cmp_dtuple_rec_with_match(tuple, next_rec, offsets, &up_match, &up_bytes) >= 0) { goto exit_func; } Loading @@ -115,7 +112,7 @@ page_cur_try_search_shortcut( ut_a(*ilow_matched_fields == low_match); ut_a(*ilow_matched_bytes == low_bytes); #endif if (next_rec != page_get_supremum_rec(page)) { if (!page_rec_is_supremum(next_rec)) { *iup_matched_fields = up_match; *iup_matched_bytes = up_bytes; Loading @@ -137,6 +134,7 @@ page_cur_try_search_shortcut( #endif #ifdef PAGE_CUR_LE_OR_EXTENDS /******************************************************************** Checks if the nth field in a record is a character type field which extends the nth field in tuple, i.e., the field is longer or equal in length and has Loading Loading @@ -185,6 +183,7 @@ page_cur_rec_field_extends( return(FALSE); } #endif /* PAGE_CUR_LE_OR_EXTENDS */ /******************************************************************** Searches the right position for a page cursor. */ Loading Loading @@ -240,8 +239,13 @@ page_cur_search_with_match( ut_ad(dtuple_validate(tuple)); ut_ad(dtuple_check_typed(tuple)); ut_ad((mode == PAGE_CUR_L) || (mode == PAGE_CUR_LE) || (mode == PAGE_CUR_G) || (mode == PAGE_CUR_GE) || (mode == PAGE_CUR_LE_OR_EXTENDS) || (mode == PAGE_CUR_DBG)); #ifdef PAGE_CUR_DBG || (mode == PAGE_CUR_DBG) #endif /* PAGE_CUR_DBG */ #ifdef PAGE_CUR_LE_OR_EXTENDS || (mode == PAGE_CUR_LE_OR_EXTENDS) #endif /* PAGE_CUR_LE_OR_EXTENDS */ || (mode == PAGE_CUR_G) || (mode == PAGE_CUR_GE)); page_check_dir(page); Loading @@ -261,16 +265,18 @@ page_cur_search_with_match( return; } } /*#ifdef UNIV_SEARCH_DEBUG */ # ifdef PAGE_CUR_DBG if (mode == PAGE_CUR_DBG) { mode = PAGE_CUR_LE; } /*#endif */ # endif #endif /* The following flag does not work for non-latin1 char sets because cmp_full_field does not tell how many bytes matched */ #ifdef PAGE_CUR_LE_OR_EXTENDS ut_a(mode != PAGE_CUR_LE_OR_EXTENDS); #endif /* PAGE_CUR_LE_OR_EXTENDS */ /* If mode PAGE_CUR_G is specified, we are trying to position the cursor to answer a query of the form "tuple < X", where tuple is Loading Loading @@ -308,33 +314,36 @@ page_cur_search_with_match( cmp = cmp_dtuple_rec_with_match(tuple, mid_rec, offsets, &cur_matched_fields, &cur_matched_bytes); if (cmp == 1) { if (UNIV_LIKELY(cmp > 0)) { low_slot_match: low = mid; low_matched_fields = cur_matched_fields; low_matched_bytes = cur_matched_bytes; } else if (cmp == -1) { } else if (UNIV_LIKELY(cmp /* == -1 */)) { #ifdef PAGE_CUR_LE_OR_EXTENDS if (mode == PAGE_CUR_LE_OR_EXTENDS && page_cur_rec_field_extends(tuple, mid_rec, offsets, cur_matched_fields)) { low = mid; low_matched_fields = cur_matched_fields; low_matched_bytes = cur_matched_bytes; } else { goto low_slot_match; } #endif /* PAGE_CUR_LE_OR_EXTENDS */ up_slot_match: up = mid; up_matched_fields = cur_matched_fields; up_matched_bytes = cur_matched_bytes; } } else if (mode == PAGE_CUR_G || mode == PAGE_CUR_LE || mode == PAGE_CUR_LE_OR_EXTENDS) { low = mid; low_matched_fields = cur_matched_fields; low_matched_bytes = cur_matched_bytes; #ifdef PAGE_CUR_LE_OR_EXTENDS || mode == PAGE_CUR_LE_OR_EXTENDS #endif /* PAGE_CUR_LE_OR_EXTENDS */ ) { goto low_slot_match; } else { up = mid; up_matched_fields = cur_matched_fields; up_matched_bytes = cur_matched_bytes; goto up_slot_match; } } Loading @@ -360,32 +369,35 @@ page_cur_search_with_match( cmp = cmp_dtuple_rec_with_match(tuple, mid_rec, offsets, &cur_matched_fields, &cur_matched_bytes); if (cmp == 1) { if (UNIV_LIKELY(cmp > 0)) { low_rec_match: low_rec = mid_rec; low_matched_fields = cur_matched_fields; low_matched_bytes = cur_matched_bytes; } else if (cmp == -1) { } else if (UNIV_LIKELY(cmp /* == -1 */)) { #ifdef PAGE_CUR_LE_OR_EXTENDS if (mode == PAGE_CUR_LE_OR_EXTENDS && page_cur_rec_field_extends(tuple, mid_rec, offsets, cur_matched_fields)) { low_rec = mid_rec; low_matched_fields = cur_matched_fields; low_matched_bytes = cur_matched_bytes; } else { goto low_rec_match; } #endif /* PAGE_CUR_LE_OR_EXTENDS */ up_rec_match: up_rec = mid_rec; up_matched_fields = cur_matched_fields; up_matched_bytes = cur_matched_bytes; } } else if (mode == PAGE_CUR_G || mode == PAGE_CUR_LE || mode == PAGE_CUR_LE_OR_EXTENDS) { low_rec = mid_rec; low_matched_fields = cur_matched_fields; low_matched_bytes = cur_matched_bytes; #ifdef PAGE_CUR_LE_OR_EXTENDS || mode == PAGE_CUR_LE_OR_EXTENDS #endif /* PAGE_CUR_LE_OR_EXTENDS */ ) { goto low_rec_match; } else { up_rec = mid_rec; up_matched_fields = cur_matched_fields; up_matched_bytes = cur_matched_bytes; goto up_rec_match; } } Loading
innobase/rem/rem0rec.c +67 −38 Original line number Diff line number Diff line Loading @@ -601,30 +601,38 @@ rec_set_nth_field_extern_bit_new( /* read the lengths of fields 0..n */ for (i = 0; i < n_fields; i++) { ibool is_null; ulint len; field = dict_index_get_nth_field(index, i); type = dict_col_get_type(dict_field_get_col(field)); is_null = !(dtype_get_prtype(type) & DATA_NOT_NULL); if (is_null) { /* nullable field => read the null flag */ is_null = !!(*nulls & null_mask); if (!(dtype_get_prtype(type) & DATA_NOT_NULL)) { if (UNIV_UNLIKELY(!(byte) null_mask)) { nulls--; null_mask = 1; } if (*nulls & null_mask) { null_mask <<= 1; if (null_mask == 0x100) nulls--, null_mask = 1; /* NULL fields cannot be external. */ ut_ad(i != ith); continue; } if (is_null || field->fixed_len) { /* No length (or extern bit) is stored for fields that are NULL or fixed-length. */ null_mask <<= 1; } if (field->fixed_len) { /* fixed-length fields cannot be external (Fixed-length fields longer than DICT_MAX_COL_PREFIX_LEN will be treated as variable-length ones in dict_index_add_col().) */ ut_ad(i != ith); continue; } len = *lens--; lens--; if (dtype_get_len(type) > 255 || dtype_get_mtype(type) == DATA_BLOB) { ulint len = lens[1]; if (len & 0x80) { /* 1exxxxxx: 2-byte length */ if (i == ith) { if (!val == !(len & 0x20)) { if (!val == !(len & 0x40)) { return; /* no change */ } /* toggle the extern bit */ Loading Loading @@ -823,6 +831,7 @@ rec_convert_dtuple_to_rec_new( byte* lens; ulint len; ulint i; ulint n_node_ptr_field; ulint fixed_len; ulint null_mask = 1; const ulint n_fields = dtuple_get_n_fields(dtuple); Loading @@ -831,16 +840,26 @@ rec_convert_dtuple_to_rec_new( ut_ad(index->table->comp); ut_ad(n_fields > 0); switch (status) { /* Try to ensure that the memset() between the for() loops completes fast. The address is not exact, but UNIV_PREFETCH should never generate a memory fault. */ UNIV_PREFETCH_RW(rec - REC_N_NEW_EXTRA_BYTES - n_fields); UNIV_PREFETCH_RW(rec); switch (UNIV_EXPECT(status, REC_STATUS_ORDINARY)) { case REC_STATUS_ORDINARY: ut_ad(n_fields <= dict_index_get_n_fields(index)); n_node_ptr_field = ULINT_UNDEFINED; break; case REC_STATUS_NODE_PTR: ut_ad(n_fields == dict_index_get_n_unique_in_tree(index) + 1); n_node_ptr_field = n_fields - 1; break; case REC_STATUS_INFIMUM: case REC_STATUS_SUPREMUM: ut_ad(n_fields == 1); n_node_ptr_field = ULINT_UNDEFINED; goto init; default: ut_a(0); Loading @@ -852,15 +871,18 @@ rec_convert_dtuple_to_rec_new( rec += (index->n_nullable + 7) / 8; for (i = 0; i < n_fields; i++) { if (UNIV_UNLIKELY(i == n_node_ptr_field)) { #ifdef UNIV_DEBUG field = dtuple_get_nth_field(dtuple, i); type = dfield_get_type(field); len = dfield_get_len(field); if (status == REC_STATUS_NODE_PTR && i == n_fields - 1) { fixed_len = 4; ut_ad(dtype_get_prtype(type) & DATA_NOT_NULL); ut_ad(len == 4); continue; ut_ad(dfield_get_len(field) == 4); #endif /* UNIV_DEBUG */ goto init; } field = dtuple_get_nth_field(dtuple, i); type = dfield_get_type(field); len = dfield_get_len(field); fixed_len = dict_index_get_nth_field(index, i)->fixed_len; if (!(dtype_get_prtype(type) & DATA_NOT_NULL)) { Loading Loading @@ -902,28 +924,34 @@ rec_convert_dtuple_to_rec_new( type = dfield_get_type(field); len = dfield_get_len(field); if (status == REC_STATUS_NODE_PTR && i == n_fields - 1) { fixed_len = 4; if (UNIV_UNLIKELY(i == n_node_ptr_field)) { ut_ad(dtype_get_prtype(type) & DATA_NOT_NULL); ut_ad(len == 4); goto copy; memcpy(end, dfield_get_data(field), len); break; } fixed_len = dict_index_get_nth_field(index, i)->fixed_len; if (!(dtype_get_prtype(type) & DATA_NOT_NULL)) { /* nullable field */ ut_ad(index->n_nullable > 0); if (UNIV_UNLIKELY(!(byte) null_mask)) { nulls--; null_mask = 1; } ut_ad(*nulls < null_mask); /* set the null flag if necessary */ if (len == UNIV_SQL_NULL) { *nulls |= null_mask; } null_mask <<= 1; if (null_mask == 0x100) nulls--, null_mask = 1; if (len == UNIV_SQL_NULL) continue; } null_mask <<= 1; } /* only nullable fields can be null */ ut_ad(len != UNIV_SQL_NULL); if (fixed_len) { Loading @@ -942,7 +970,7 @@ rec_convert_dtuple_to_rec_new( *lens-- = (byte) len; } } copy: memcpy(end, dfield_get_data(field), len); end += len; } Loading Loading @@ -1105,7 +1133,6 @@ rec_copy_prefix_to_buf( dtype_t* type; ulint i; ulint prefix_len; ibool is_null; ulint null_mask; ulint status; Loading Loading @@ -1146,20 +1173,22 @@ rec_copy_prefix_to_buf( for (i = 0; i < n_fields; i++) { field = dict_index_get_nth_field(index, i); type = dict_col_get_type(dict_field_get_col(field)); is_null = !(dtype_get_prtype(type) & DATA_NOT_NULL); if (is_null) { if (!(dtype_get_prtype(type) & DATA_NOT_NULL)) { /* nullable field => read the null flag */ is_null = !!(*nulls & null_mask); null_mask <<= 1; if (null_mask == 0x100) { --nulls; UNIV_PREFETCH_R(nulls); if (UNIV_UNLIKELY(!(byte) null_mask)) { nulls--; null_mask = 1; } if (*nulls & null_mask) { null_mask <<= 1; continue; } null_mask <<= 1; } if (is_null) { } else if (field->fixed_len) { if (field->fixed_len) { prefix_len += field->fixed_len; } else { ulint len = *lens--; Loading
sql/ha_innodb.cc +32 −9 Original line number Diff line number Diff line Loading @@ -2955,21 +2955,44 @@ build_template( templ = prebuilt->mysql_template + n_requested_fields; field = table->field[i]; ibool index_contains_field= if (UNIV_LIKELY(templ_type == ROW_MYSQL_REC_FIELDS)) { /* Decide which columns we should fetch and which we can skip. */ register const ibool index_contains_field = dict_index_contains_col_or_prefix(index, i); if (templ_type == ROW_MYSQL_REC_FIELDS && ((prebuilt->read_just_key && !index_contains_field) || (!(fetch_all_in_key && index_contains_field) && !(fetch_primary_key_cols && dict_table_col_in_clustered_key(index->table, i)) && thd->query_id != field->query_id))) { if (!index_contains_field && prebuilt->read_just_key) { /* If this is a 'key read', we do not need columns that are not in the key */ goto skip_field; } if (index_contains_field && fetch_all_in_key) { /* This field is needed in the query */ goto include_field; } if (thd->query_id == field->query_id) { /* This field is needed in the query */ goto include_field; } if (fetch_primary_key_cols && dict_table_col_in_clustered_key(index->table, i)) { /* This field is needed in the query */ goto include_field; } /* This field is not needed in the query, skip it */ goto skip_field; } include_field: n_requested_fields++; templ->col_no = i; Loading