📄 rem0rec.c
字号:
} return(size);}/***************************************************************Sets the value of the ith field SQL null bit of an old-style record. */voidrec_set_nth_field_null_bit(/*=======================*/ rec_t* rec, /* in: record */ ulint i, /* in: ith field */ ibool val) /* in: value to set */{ ulint info; if (rec_get_1byte_offs_flag(rec)) { info = rec_1_get_field_end_info(rec, i); if (val) { info = info | REC_1BYTE_SQL_NULL_MASK; } else { info = info & ~REC_1BYTE_SQL_NULL_MASK; } rec_1_set_field_end_info(rec, i, info); return; } info = rec_2_get_field_end_info(rec, i); if (val) { info = info | REC_2BYTE_SQL_NULL_MASK; } else { info = info & ~REC_2BYTE_SQL_NULL_MASK; } rec_2_set_field_end_info(rec, i, info);}/***************************************************************Sets the value of the ith field extern storage bit of an old-style record. */voidrec_set_nth_field_extern_bit_old(/*=============================*/ rec_t* rec, /* in: old-style record */ ulint i, /* in: ith field */ ibool val, /* in: value to set */ mtr_t* mtr) /* in: mtr holding an X-latch to the page where rec is, or NULL; in the NULL case we do not write to log about the change */{ ulint info; ut_a(!rec_get_1byte_offs_flag(rec)); ut_a(i < rec_get_n_fields_old(rec)); info = rec_2_get_field_end_info(rec, i); if (val) { info = info | REC_2BYTE_EXTERN_MASK; } else { info = info & ~REC_2BYTE_EXTERN_MASK; } if (mtr) { mlog_write_ulint(rec - REC_N_OLD_EXTRA_BYTES - 2 * (i + 1), info, MLOG_2BYTES, mtr); } else { rec_2_set_field_end_info(rec, i, info); }}/***************************************************************Sets the value of the ith field extern storage bit of a new-style record. */voidrec_set_nth_field_extern_bit_new(/*=============================*/ rec_t* rec, /* in: record */ dict_index_t* index, /* in: record descriptor */ ulint ith, /* in: ith field */ ibool val, /* in: value to set */ mtr_t* mtr) /* in: mtr holding an X-latch to the page where rec is, or NULL; in the NULL case we do not write to log about the change */{ byte* nulls = rec - (REC_N_NEW_EXTRA_BYTES + 1); byte* lens = nulls - (index->n_nullable + 7) / 8; dict_field_t* field; dtype_t* type; ulint i; ulint n_fields; ulint null_mask = 1; ut_ad(rec && index); ut_ad(index->table->comp); ut_ad(rec_get_status(rec) == REC_STATUS_ORDINARY); n_fields = dict_index_get_n_fields(index); ut_ad(ith < n_fields); /* 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)) { if (UNIV_UNLIKELY(!(byte) null_mask)) { nulls--; null_mask = 1; } if (*nulls & null_mask) { null_mask <<= 1; /* NULL fields cannot be external. */ ut_ad(i != ith); continue; } null_mask <<= 1; } if (field->fixed_len) { /* fixed-length fields cannot be external (Fixed-length fields longer than DICT_MAX_INDEX_COL_LEN will be treated as variable-length ones in dict_index_add_col().) */ ut_ad(i != ith); continue; } 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 & 0x40)) { return; /* no change */ } /* toggle the extern bit */ len ^= 0x40; if (mtr) { mlog_write_ulint(lens + 1, len, MLOG_1BYTE, mtr); } else { lens[1] = (byte) len; } return; } lens--; } else { /* short fields cannot be external */ ut_ad(i != ith); } } else { /* short fields cannot be external */ ut_ad(i != ith); } }}/***************************************************************Sets TRUE the extern storage bits of fields mentioned in an array. */voidrec_set_field_extern_bits(/*======================*/ rec_t* rec, /* in: record */ dict_index_t* index, /* in: record descriptor */ const ulint* vec, /* in: array of field numbers */ ulint n_fields,/* in: number of fields numbers */ mtr_t* mtr) /* in: mtr holding an X-latch to the page where rec is, or NULL; in the NULL case we do not write to log about the change */{ ulint i; if (UNIV_LIKELY(index->table->comp)) { for (i = 0; i < n_fields; i++) { rec_set_nth_field_extern_bit_new(rec, index, vec[i], TRUE, mtr); } } else { for (i = 0; i < n_fields; i++) { rec_set_nth_field_extern_bit_old(rec, vec[i], TRUE, mtr); } }}/*************************************************************** Sets an old-style record field to SQL null.The physical size of the field is not changed. */voidrec_set_nth_field_sql_null(/*=======================*/ rec_t* rec, /* in: record */ ulint n) /* in: index of the field */{ ulint offset; offset = rec_get_field_start_offs(rec, n); data_write_sql_null(rec + offset, rec_get_nth_field_size(rec, n)); rec_set_nth_field_null_bit(rec, n, TRUE);}/*************************************************************Builds an old-style physical record out of a data tuple andstores it beginning from the start of the given buffer. */staticrec_t*rec_convert_dtuple_to_rec_old(/*==========================*/ /* out: pointer to the origin of physical record */ byte* buf, /* in: start address of the physical record */ dtuple_t* dtuple)/* in: data tuple */{ dfield_t* field; ulint n_fields; ulint data_size; rec_t* rec; ulint end_offset; ulint ored_offset; byte* data; ulint len; ulint i; ut_ad(buf && dtuple); ut_ad(dtuple_validate(dtuple)); ut_ad(dtuple_check_typed(dtuple)); n_fields = dtuple_get_n_fields(dtuple); data_size = dtuple_get_data_size(dtuple); ut_ad(n_fields > 0); /* Calculate the offset of the origin in the physical record */ rec = buf + rec_get_converted_extra_size(data_size, n_fields); /* Store the number of fields */ rec_set_n_fields_old(rec, n_fields); /* Set the info bits of the record */ rec_set_info_bits(rec, FALSE, dtuple_get_info_bits(dtuple) & REC_INFO_BITS_MASK); /* Store the data and the offsets */ end_offset = 0; if (data_size <= REC_1BYTE_OFFS_LIMIT) { rec_set_1byte_offs_flag(rec, TRUE); for (i = 0; i < n_fields; i++) { field = dtuple_get_nth_field(dtuple, i); data = dfield_get_data(field); len = dfield_get_len(field); if (len == UNIV_SQL_NULL) { len = dtype_get_sql_null_size(dfield_get_type(field)); data_write_sql_null(rec + end_offset, len); end_offset += len; ored_offset = end_offset | REC_1BYTE_SQL_NULL_MASK; } else { /* If the data is not SQL null, store it */ ut_memcpy(rec + end_offset, data, len); end_offset += len; ored_offset = end_offset; } rec_1_set_field_end_info(rec, i, ored_offset); } } else { rec_set_1byte_offs_flag(rec, FALSE); for (i = 0; i < n_fields; i++) { field = dtuple_get_nth_field(dtuple, i); data = dfield_get_data(field); len = dfield_get_len(field); if (len == UNIV_SQL_NULL) { len = dtype_get_sql_null_size(dfield_get_type(field)); data_write_sql_null(rec + end_offset, len); end_offset += len; ored_offset = end_offset | REC_2BYTE_SQL_NULL_MASK; } else { /* If the data is not SQL null, store it */ ut_memcpy(rec + end_offset, data, len); end_offset += len; ored_offset = end_offset; } rec_2_set_field_end_info(rec, i, ored_offset); } } return(rec);}/*************************************************************Builds a new-style physical record out of a data tuple andstores it beginning from the start of the given buffer. */staticrec_t*rec_convert_dtuple_to_rec_new(/*==========================*/ /* out: pointer to the origin of physical record */ byte* buf, /* in: start address of the physical record */ dict_index_t* index, /* in: record descriptor */ dtuple_t* dtuple) /* in: data tuple */{ dfield_t* field; dtype_t* type; rec_t* rec = buf + REC_N_NEW_EXTRA_BYTES; byte* end; byte* nulls; 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); const ulint status = dtuple_get_info_bits(dtuple) & REC_NEW_STATUS_MASK; ut_ad(index->table->comp); ut_ad(n_fields > 0); /* 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); return(0); } /* Calculate the offset of the origin in the physical record. We must loop over all fields to do this. */ 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); ut_ad(dtype_get_prtype(type) & DATA_NOT_NULL); 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)) { if (len == UNIV_SQL_NULL) continue; } /* only nullable fields can be null */ ut_ad(len != UNIV_SQL_NULL); if (fixed_len) { ut_ad(len == fixed_len); } else { ut_ad(len <= dtype_get_len(type) || dtype_get_mtype(type) == DATA_BLOB); rec++; if (len >= 128 && (dtype_get_len(type) >= 256 || dtype_get_mtype(type) == DATA_BLOB)) { rec++; } } }init: end = rec; nulls = rec - (REC_N_NEW_EXTRA_BYTES + 1); lens = nulls - (index->n_nullable + 7) / 8; /* clear the SQL-null flags */ memset (lens + 1, 0, nulls - lens); /* Set the info bits of the record */ rec_set_status(rec, status); rec_set_info_bits(rec, TRUE, dtuple_get_info_bits(dtuple) & REC_INFO_BITS_MASK); /* Store the data and the offsets */ for (i = 0; i < n_fields; i++) { field = dtuple_get_nth_field(dtuple, i); type = dfield_get_type(field); len = dfield_get_len(field); if (UNIV_UNLIKELY(i == n_node_ptr_field)) { ut_ad(dtype_get_prtype(type) & DATA_NOT_NULL); ut_ad(len == 4); 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; continue; } null_mask <<= 1; } /* only nullable fields can be null */ ut_ad(len != UNIV_SQL_NULL); if (fixed_len) { ut_ad(len == fixed_len); } else { ut_ad(len <= dtype_get_len(type) || dtype_get_mtype(type) == DATA_BLOB); if (len < 128 || (dtype_get_len(type) < 256 && dtype_get_mtype(type) != DATA_BLOB)) { *lens-- = (byte) len; } else { /* the extern bits will be set later */ ut_ad(len < 16384); *lens-- = (byte) (len >> 8) | 0x80; *lens-- = (byte) len; } } memcpy(end, dfield_get_data(field), len); end += len; } return(rec);}/*************************************************************Builds a physical record out of a data tuple andstores it beginning from the start of the given buffer. */rec_t*rec_convert_dtuple_to_rec(/*======================*/ /* out: pointer to the origin of physical record */ byte* buf, /* in: start address of the
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -