/******************************************************//**
The following function determines the offsets to each field in the
record. The offsets are written to a previously allocated array of
ulint, where rec_offs_n_fields(offsets) has been initialized to the
number of fields in the record. The rest of the array will be
initialized by this function. rec_offs_base(offsets)[0] will be set
to the extra size (if REC_OFFS_COMPACT is set, the record is in the
new format; if REC_OFFS_EXTERNAL is set, the record contains externally
stored columns), and rec_offs_base(offsets)[1..n_fields] will be set to
offsets past the end of fields 0..n_fields, or to the beginning of
fields 1..n_fields+1. When the high-order bit of the offset at [i+1]
is set (REC_OFFS_SQL_NULL), the field i is NULL. When the second
high-order bit of the offset at [i+1] is set (REC_OFFS_EXTERNAL), the
field i is being stored externally. */
static
void
rec_init_offsets(
/*=============*/
const rec_t* rec, /*!< in: physical record */
const dict_index_t* index, /*!< in: record descriptor */
ulint* offsets)/*!< in/out: array of offsets;
in: n=rec_offs_n_fields(offsets) */
{
ulint i = 0;
ulint offs;
rec_offs_make_valid(rec, index, offsets);
if (dict_table_is_comp(index->table)) {
const byte* nulls;
const byte* lens;
dict_field_t* field;
ulint null_mask;
ulint status = rec_get_status(rec);
ulint n_node_ptr_field = ULINT_UNDEFINED;
switch (UNIV_EXPECT(status, REC_STATUS_ORDINARY)) {
case REC_STATUS_INFIMUM:
case REC_STATUS_SUPREMUM:
/* the field is 8 bytes long */
rec_offs_base(offsets)[0]
= REC_N_NEW_EXTRA_BYTES | REC_OFFS_COMPACT;
rec_offs_base(offsets)[1] = 8;
return;
case REC_STATUS_NODE_PTR:
n_node_ptr_field
= dict_index_get_n_unique_in_tree(index);
break;
case REC_STATUS_ORDINARY:
rec_init_offsets_comp_ordinary(rec,
REC_N_NEW_EXTRA_BYTES,
index, offsets);
return;
}
nulls = rec - (REC_N_NEW_EXTRA_BYTES + 1);
lens = nulls - UT_BITS_IN_BYTES(index->n_nullable);
offs = 0;
null_mask = 1;
/* read the lengths of fields 0..n */
do {
ulint len;
if (UNIV_UNLIKELY(i == n_node_ptr_field)) {
len = offs += REC_NODE_PTR_SIZE;
goto resolved;
}
field = dict_index_get_nth_field(index, i);
if (!(dict_field_get_col(field)->prtype
& DATA_NOT_NULL)) {
/* nullable field => read the null flag */
if (UNIV_UNLIKELY(!(byte) null_mask)) {
nulls--;
null_mask = 1;
}
if (*nulls & null_mask) {
null_mask <<= 1;
/* No length is stored for NULL fields.
We do not advance offs, and we set
the length to zero and enable the
SQL NULL flag in offsets[]. */
len = offs | REC_OFFS_SQL_NULL;
goto resolved;
}
null_mask <<= 1;
}
if (UNIV_UNLIKELY(!field->fixed_len)) {
/* Variable-length field: read the length */
const dict_col_t* col
= dict_field_get_col(field);
len = *lens--;
/* If the maximum length of the field
is up to 255 bytes, the actual length
is always stored in one byte. If the
maximum length is more than 255 bytes,
the actual length is stored in one
byte for 0..127. The length will be
encoded in two bytes when it is 128 or
more, or when the field is stored
externally. */
if (UNIV_UNLIKELY(col->len > 255)
|| UNIV_UNLIKELY(col->mtype
== DATA_BLOB)) {
if (len & 0x80) {
/* 1exxxxxxx xxxxxxxx */
len <<= 8;
len |= *lens--;
/* B-tree node pointers
must not contain externally
stored columns. Thus
the "e" flag must be 0. */
ut_a(!(len & 0x4000));
offs += len & 0x3fff;
len = offs;
goto resolved;
}
}
len = offs += len;
} else {
len = offs += field->fixed_len;
}
resolved:
rec_offs_base(offsets)[i + 1] = len;
} while (++i < rec_offs_n_fields(offsets));
*rec_offs_base(offsets)
= (rec - (lens + 1)) | REC_OFFS_COMPACT;
} else {
/* Old-style record: determine extra size and end offsets */
offs = REC_N_OLD_EXTRA_BYTES;
if (rec_get_1byte_offs_flag(rec)) {
offs += rec_offs_n_fields(offsets);
*rec_offs_base(offsets) = offs;
/* Determine offsets to fields */
do {
offs = rec_1_get_field_end_info(rec, i);
if (offs & REC_1BYTE_SQL_NULL_MASK) {
offs &= ~REC_1BYTE_SQL_NULL_MASK;
offs |= REC_OFFS_SQL_NULL;
}
rec_offs_base(offsets)[1 + i] = offs;
} while (++i < rec_offs_n_fields(offsets));
} else {
offs += 2 * rec_offs_n_fields(offsets);
*rec_offs_base(offsets) = offs;
/* Determine offsets to fields */
do {
offs = rec_2_get_field_end_info(rec, i);
if (offs & REC_2BYTE_SQL_NULL_MASK) {
offs &= ~REC_2BYTE_SQL_NULL_MASK;
offs |= REC_OFFS_SQL_NULL;
}
if (offs & REC_2BYTE_EXTERN_MASK) {
offs &= ~REC_2BYTE_EXTERN_MASK;
offs |= REC_OFFS_EXTERNAL;
*rec_offs_base(offsets) |= REC_OFFS_EXTERNAL;
}
rec_offs_base(offsets)[1 + i] = offs;
} while (++i < rec_offs_n_fields(offsets));
}
}
}
mysqld.exe!rec_get_nth_field_offs(const unsigned long * offsets=0x2203aecc, unsigned long n=0, unsigned long * len=0x2203ae80) 行1052 C
mysqld.exe!cmp_dtuple_rec_with_match(const dtuple_struct * dtuple=0x1f1f9b20, const unsigned char * rec=0x16f74088, const unsigned long * offsets=0x2203aecc, unsigned long * matched_fields=0x2203b080, unsigned long * matched_bytes=0x2203b074) 行489 + 0x11 字节 C
> mysqld.exe!page_cur_search_with_match(const buf_block_struct * block=0x16acb040, const dict_index_struct * index=0x1f0d4240, const dtuple_struct * tuple=0x1f1f9b20, unsigned long mode=2, unsigned long * iup_matched_fields=0x2203b334, unsigned long * iup_matched_bytes=0x2203b328, unsigned long * ilow_matched_fields=0x2203b31c, unsigned long * ilow_matched_bytes=0x2203b310, page_cur_struct * cursor=0x2203bc8c) 行439 + 0x1c 字节 C
mysqld.exe!btr_cur_search_to_nth_level(dict_index_struct * index=0x1f0d4240, unsigned long level=0, const dtuple_struct * tuple=0x1f1f9b20, unsigned long mode=2, unsigned long latch_mode=1, btr_cur_struct * cursor=0x2203bc88, unsigned long has_search_latch=0, const char * file=0x01992e58, unsigned long line=1181, mtr_struct * mtr=0x2203b7f4) 行722 + 0x29 字节 C
mysqld.exe!btr_pcur_open_func(dict_index_struct * index=0x1f0d4240, const dtuple_struct * tuple=0x1f1f9b20, unsigned long mode=2, unsigned long latch_mode=1, btr_pcur_struct * cursor=0x2203bc88, const char * file=0x01992e58, unsigned long line=1181, mtr_struct * mtr=0x2203b7f4) 行439 + 0x29 字节 C
mysqld.exe!btr_pcur_open_on_user_rec_func(dict_index_struct * index=0x1f0d4240, const dtuple_struct * tuple=0x1f1f9b20, unsigned long mode=2, unsigned long latch_mode=1, btr_pcur_struct * cursor=0x2203bc88, const char * file=0x01992e58, unsigned long line=1181, mtr_struct * mtr=0x2203b7f4) 行586 + 0x25 字节 C
mysqld.exe!dict_load_fields(dict_index_struct * index=0x1f201c00, mem_block_info_struct * heap=0x1f1f9aa0) 行1181 + 0x2c 字节 C
mysqld.exe!dict_load_indexes(dict_table_struct * table=0x00ab34e8, mem_block_info_struct * heap=0x1f1f9aa0, dict_err_ignore ignore_err=DICT_ERR_IGNORE_NONE) 行1533 + 0x10 字节 C
mysqld.exe!dict_load_table(const char * name=0x2203cad4, unsigned long cached=1, dict_err_ignore ignore_err=DICT_ERR_IGNORE_NONE) 行1858 + 0x14 字节 C
mysqld.exe!dict_table_get_low(const char * table_name=0x2203cad4) 行876 + 0xd 字节 C
mysqld.exe!dict_table_get(const char * table_name=0x2203cad4, unsigned long inc_mysql_count=1) 行744 + 0x9 字节 C
mysqld.exe!ha_innobase::open(const char * name=0x1f1ea040, int mode=2, unsigned int test_if_locked=2) 行3868 + 0xe 字节 C++
mysqld.exe!handler::ha_open(TABLE * table_arg=0x1f1f75c0, const char * name=0x1f1ea040, int mode=2, int test_if_locked=2) 行2238 + 0x1e 字节 C++
mysqld.exe!open_table_from_share(THD * thd=0x1f170880, TABLE_SHARE * share=0x1f1e9e18, const char * alias=0x1f1f2898, unsigned int db_stat=39, unsigned int prgflag=44, unsigned int ha_open_flags=0, TABLE * outparam=0x1f1f75c0, bool is_create_table=false) 行2073 + 0x8f 字节 C++
mysqld.exe!open_table(THD * thd=0x1f170880, TABLE_LIST * table_list=0x1f1f28a0, st_mem_root * mem_root=0x2203d740, Open_table_context * ot_ctx=0x2203d76c) 行3098 + 0x2b 字节 C++
mysqld.exe!open_and_process_table(THD * thd=0x1f170880, LEX * lex=0x1f171820, TABLE_LIST * tables=0x1f1f28a0, unsigned int * counter=0x2203d7e8, unsigned int flags=0, Prelocking_strategy * prelocking_strategy=0x2203d814, bool has_prelocking_list=false, Open_table_context * ot_ctx=0x2203d76c, st_mem_root * new_frm_mem=0x2203d740) 行4460 + 0x15 字节 C++
mysqld.exe!open_tables(THD * thd=0x1f170880, TABLE_LIST * * start=0x2203d7fc, unsigned int * counter=0x2203d7e8, unsigned int flags=0, Prelocking_strategy * prelocking_strategy=0x2203d814) 行4908 + 0x2d 字节 C++
mysqld.exe!open_and_lock_tables(THD * thd=0x1f170880, TABLE_LIST * tables=0x1f1f28a0, bool derived=true, unsigned int flags=0, Prelocking_strategy * prelocking_strategy=0x2203d814) 行5512 + 0x19 字节 C++
mysqld.exe!open_and_lock_tables(THD * thd=0x1f170880, TABLE_LIST * tables=0x1f1f28a0, bool derived=true, unsigned int flags=0) 行475 + 0x1a 字节 C++
mysqld.exe!execute_sqlcom_select(THD * thd=0x1f170880, TABLE_LIST * all_tables=0x1f1f28a0) 行4547 + 0x11 字节 C++
mysqld.exe!mysql_execute_command(THD * thd=0x1f170880) 行2151 + 0xd 字节 C++
mysqld.exe!mysql_parse(THD * thd=0x1f170880, char * rawbuf=0x1f1f2758, unsigned int length=16, Parser_state * parser_state=0x2203f760) 行5627 + 0x9 字节 C++
mysqld.exe!dispatch_command(enum_server_command command=COM_QUERY, THD * thd=0x1f170880, char * packet=0x1f1ea469, unsigned int packet_length=16) 行1037 + 0x22 字节 C++
mysqld.exe!do_command(THD * thd=0x1f170880) 行773 + 0x1b 字节 C++
mysqld.exe!do_handle_one_connection(THD * thd_arg=0x1f170880) 行840 + 0x9 字节 C++
mysqld.exe!handle_one_connection(void * arg=0x1f170880) 行759 + 0x9 字节 C++
mysqld.exe!pfs_spawn_thread(void * arg=0x1f1ce0d8) 行1015 + 0x9 字节 C++
mysqld.exe!pthread_start(void * p=0x1f1d5f78) 行61 + 0x9 字节 C
mysqld.exe!_callthreadstartex() 行348 + 0xf 字节 C
mysqld.exe!_threadstartex(void * ptd=0x1f1ee4b0) 行331 C
kernel32.dll!76daed6c()
[下面的框架可能不正确和/或缺失,没有为 kernel32.dll 加载符号]
ntdll.dll!7723377b()
ntdll.dll!7723374e()