📄 rem0rec.c
字号:
physical record */ dict_index_t* index, /* in: record descriptor */ dtuple_t* dtuple) /* in: data tuple */{ rec_t* rec; ut_ad(buf && index && dtuple); ut_ad(dtuple_validate(dtuple)); ut_ad(dtuple_check_typed(dtuple)); if (UNIV_LIKELY(index->table->comp)) { rec = rec_convert_dtuple_to_rec_new(buf, index, dtuple); } else { rec = rec_convert_dtuple_to_rec_old(buf, dtuple); }#ifdef UNIV_DEBUG { mem_heap_t* heap = NULL; ulint offsets_[REC_OFFS_NORMAL_SIZE]; const ulint* offsets; *offsets_ = (sizeof offsets_) / sizeof *offsets_; offsets = rec_get_offsets(rec, index, offsets_, ULINT_UNDEFINED, &heap); ut_ad(rec_validate(rec, offsets)); if (UNIV_LIKELY_NULL(heap)) { mem_heap_free(heap); } }#endif /* UNIV_DEBUG */ return(rec);}/******************************************************************Copies the first n fields of a physical record to a data tuple. The fieldsare copied to the memory heap. */voidrec_copy_prefix_to_dtuple(/*======================*/ dtuple_t* tuple, /* in: data tuple */ rec_t* rec, /* in: physical record */ dict_index_t* index, /* in: record descriptor */ ulint n_fields, /* in: number of fields to copy */ mem_heap_t* heap) /* in: memory heap */{ dfield_t* field; byte* data; ulint len; byte* buf = NULL; ulint i; ulint offsets_[REC_OFFS_NORMAL_SIZE]; ulint* offsets = offsets_; *offsets_ = (sizeof offsets_) / sizeof *offsets_; offsets = rec_get_offsets(rec, index, offsets, n_fields, &heap); ut_ad(rec_validate(rec, offsets)); ut_ad(dtuple_check_typed(tuple)); dtuple_set_info_bits(tuple, rec_get_info_bits(rec, index->table->comp)); for (i = 0; i < n_fields; i++) { field = dtuple_get_nth_field(tuple, i); data = rec_get_nth_field(rec, offsets, i, &len); if (len != UNIV_SQL_NULL) { buf = mem_heap_alloc(heap, len); ut_memcpy(buf, data, len); } dfield_set_data(field, buf, len); }}/******************************************************************Copies the first n fields of an old-style physical recordto a new physical record in a buffer. */staticrec_t*rec_copy_prefix_to_buf_old(/*=======================*/ /* out, own: copied record */ rec_t* rec, /* in: physical record */ ulint n_fields, /* in: number of fields to copy */ ulint area_end, /* in: end of the prefix data */ byte** buf, /* in/out: memory buffer for the copied prefix, or NULL */ ulint* buf_size) /* in/out: buffer size */{ rec_t* copy_rec; ulint area_start; ulint prefix_len; if (rec_get_1byte_offs_flag(rec)) { area_start = REC_N_OLD_EXTRA_BYTES + n_fields; } else { area_start = REC_N_OLD_EXTRA_BYTES + 2 * n_fields; } prefix_len = area_start + area_end; if ((*buf == NULL) || (*buf_size < prefix_len)) { if (*buf != NULL) { mem_free(*buf); } *buf = mem_alloc(prefix_len); *buf_size = prefix_len; } ut_memcpy(*buf, rec - area_start, prefix_len); copy_rec = *buf + area_start; rec_set_n_fields_old(copy_rec, n_fields); return(copy_rec);}/******************************************************************Copies the first n fields of a physical record to a new physical record ina buffer. */rec_t*rec_copy_prefix_to_buf(/*===================*/ /* out, own: copied record */ rec_t* rec, /* in: physical record */ dict_index_t* index, /* in: record descriptor */ ulint n_fields, /* in: number of fields to copy */ byte** buf, /* in/out: memory buffer for the copied prefix, or NULL */ ulint* buf_size) /* in/out: buffer size */{ byte* nulls; byte* lens; dict_field_t* field; dtype_t* type; ulint i; ulint prefix_len; ulint null_mask; ulint status; UNIV_PREFETCH_RW(*buf); if (UNIV_UNLIKELY(!index->table->comp)) { ut_ad(rec_validate_old(rec)); return(rec_copy_prefix_to_buf_old(rec, n_fields, rec_get_field_start_offs(rec, n_fields), buf, buf_size)); } status = rec_get_status(rec); switch (status) { case REC_STATUS_ORDINARY: ut_ad(n_fields <= dict_index_get_n_fields(index)); break; case REC_STATUS_NODE_PTR: /* it doesn't make sense to copy the child page number field */ ut_ad(n_fields <= dict_index_get_n_unique_in_tree(index)); break; case REC_STATUS_INFIMUM: case REC_STATUS_SUPREMUM: /* infimum or supremum record: no sense to copy anything */ default: ut_error; return(NULL); } nulls = rec - (REC_N_NEW_EXTRA_BYTES + 1); lens = nulls - (index->n_nullable + 7) / 8; UNIV_PREFETCH_R(lens); prefix_len = 0; null_mask = 1; /* read the lengths of fields 0..n */ 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)); if (!(dtype_get_prtype(type) & 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; continue; } null_mask <<= 1; } if (field->fixed_len) { prefix_len += field->fixed_len; } else { ulint len = *lens--; if (dtype_get_len(type) > 255 || dtype_get_mtype(type) == DATA_BLOB) { if (len & 0x80) { /* 1exxxxxx */ len &= 0x3f; len <<= 8; len |= *lens--; UNIV_PREFETCH_R(lens); } } prefix_len += len; } } UNIV_PREFETCH_R(rec + prefix_len); prefix_len += rec - (lens + 1); if ((*buf == NULL) || (*buf_size < prefix_len)) { if (*buf != NULL) { mem_free(*buf); } *buf = mem_alloc(prefix_len); *buf_size = prefix_len; } memcpy(*buf, lens + 1, prefix_len); return(*buf + (rec - (lens + 1)));}/*******************************************************************Validates the consistency of an old-style physical record. */staticiboolrec_validate_old(/*=============*/ /* out: TRUE if ok */ rec_t* rec) /* in: physical record */{ byte* data; ulint len; ulint n_fields; ulint len_sum = 0; ulint sum = 0; ulint i; ut_a(rec); n_fields = rec_get_n_fields_old(rec); if ((n_fields == 0) || (n_fields > REC_MAX_N_FIELDS)) { fprintf(stderr, "InnoDB: Error: record has %lu fields\n", (ulong) n_fields); return(FALSE); } for (i = 0; i < n_fields; i++) { data = rec_get_nth_field_old(rec, i, &len); if (!((len < UNIV_PAGE_SIZE) || (len == UNIV_SQL_NULL))) { fprintf(stderr, "InnoDB: Error: record field %lu len %lu\n", (ulong) i, (ulong) len); return(FALSE); } if (len != UNIV_SQL_NULL) { len_sum += len; sum += *(data + len -1); /* dereference the end of the field to cause a memory trap if possible */ } else { len_sum += rec_get_nth_field_size(rec, i); } } if (len_sum != rec_get_data_size_old(rec)) { fprintf(stderr, "InnoDB: Error: record len should be %lu, len %lu\n", (ulong) len_sum, rec_get_data_size_old(rec)); return(FALSE); } rec_dummy = sum; /* This is here only to fool the compiler */ return(TRUE);}/*******************************************************************Validates the consistency of a physical record. */iboolrec_validate(/*=========*/ /* out: TRUE if ok */ rec_t* rec, /* in: physical record */ const ulint* offsets)/* in: array returned by rec_get_offsets() */{ const byte* data; ulint len; ulint n_fields; ulint len_sum = 0; ulint sum = 0; ulint i; ut_a(rec); n_fields = rec_offs_n_fields(offsets); if ((n_fields == 0) || (n_fields > REC_MAX_N_FIELDS)) { fprintf(stderr, "InnoDB: Error: record has %lu fields\n", (ulong) n_fields); return(FALSE); } ut_a(rec_offs_comp(offsets) || n_fields <= rec_get_n_fields_old(rec)); for (i = 0; i < n_fields; i++) { data = rec_get_nth_field(rec, offsets, i, &len); if (!((len < UNIV_PAGE_SIZE) || (len == UNIV_SQL_NULL))) { fprintf(stderr, "InnoDB: Error: record field %lu len %lu\n", (ulong) i, (ulong) len); return(FALSE); } if (len != UNIV_SQL_NULL) { len_sum += len; sum += *(data + len -1); /* dereference the end of the field to cause a memory trap if possible */ } else if (!rec_offs_comp(offsets)) { len_sum += rec_get_nth_field_size(rec, i); } } if (len_sum != (ulint)(rec_get_end(rec, offsets) - rec)) { fprintf(stderr, "InnoDB: Error: record len should be %lu, len %lu\n", (ulong) len_sum, (ulong) (rec_get_end(rec, offsets) - rec)); return(FALSE); } rec_dummy = sum; /* This is here only to fool the compiler */ if (!rec_offs_comp(offsets)) { ut_a(rec_validate_old(rec)); } return(TRUE);}/*******************************************************************Prints an old-style physical record. */voidrec_print_old(/*==========*/ FILE* file, /* in: file where to print */ rec_t* rec) /* in: physical record */{ const byte* data; ulint len; ulint n; ulint i; ut_ad(rec); n = rec_get_n_fields_old(rec); fprintf(file, "PHYSICAL RECORD: n_fields %lu;" " %u-byte offsets; info bits %lu\n", (ulong) n, rec_get_1byte_offs_flag(rec) ? 1 : 2, (ulong) rec_get_info_bits(rec, FALSE)); for (i = 0; i < n; i++) { data = rec_get_nth_field_old(rec, i, &len); fprintf(file, " %lu:", (ulong) i); if (len != UNIV_SQL_NULL) { if (len <= 30) { ut_print_buf(file, data, len); } else { ut_print_buf(file, data, 30); fputs("...(truncated)", file); } } else { fprintf(file, " SQL NULL, size %lu ", rec_get_nth_field_size(rec, i)); } putc(';', file); } putc('\n', file); rec_validate_old(rec);}/*******************************************************************Prints a physical record. */voidrec_print_new(/*==========*/ FILE* file, /* in: file where to print */ rec_t* rec, /* in: physical record */ const ulint* offsets)/* in: array returned by rec_get_offsets() */{ const byte* data; ulint len; ulint i; ut_ad(rec_offs_validate(rec, NULL, offsets)); if (!rec_offs_comp(offsets)) { rec_print_old(file, rec); return; } ut_ad(rec); fprintf(file, "PHYSICAL RECORD: n_fields %lu;" " compact format; info bits %lu\n", (ulong) rec_offs_n_fields(offsets), (ulong) rec_get_info_bits(rec, TRUE)); for (i = 0; i < rec_offs_n_fields(offsets); i++) { data = rec_get_nth_field(rec, offsets, i, &len); fprintf(file, " %lu:", (ulong) i); if (len != UNIV_SQL_NULL) { if (len <= 30) { ut_print_buf(file, data, len); } else { ut_print_buf(file, data, 30); fputs("...(truncated)", file); } } else { fputs(" SQL NULL", file); } putc(';', file); } putc('\n', file); rec_validate(rec, offsets);}/*******************************************************************Prints a physical record. */voidrec_print(/*======*/ FILE* file, /* in: file where to print */ rec_t* rec, /* in: physical record */ dict_index_t* index) /* in: record descriptor */{ ut_ad(index); if (!index->table->comp) { rec_print_old(file, rec); return; } else { mem_heap_t* heap = NULL; ulint offsets_[REC_OFFS_NORMAL_SIZE]; *offsets_ = (sizeof offsets_) / sizeof *offsets_; rec_print_new(file, rec, rec_get_offsets(rec, index, offsets_, ULINT_UNDEFINED, &heap)); if (UNIV_LIKELY_NULL(heap)) { mem_heap_free(heap); } }}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -