📄 rem0rec.ic
字号:
voidrec_set_nth_field_extern_bit(/*=========================*/ rec_t* rec, /* in: record */ dict_index_t* index, /* in: record descriptor */ 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 */{ if (UNIV_LIKELY(index->table->comp)) { rec_set_nth_field_extern_bit_new(rec, index, i, val, mtr); } else { rec_set_nth_field_extern_bit_old(rec, i, val, mtr); }}/**********************************************************Returns the offset of n - 1th field end if the record is stored in the 1-byteoffsets form. If the field is SQL null, the flag is ORed in the returnedvalue. This function and the 2-byte counterpart are defined here because theC-compiler was not able to sum negative and positive constant offsets, andwarned of constant arithmetic overflow within the compiler. */UNIV_INLINEulintrec_1_get_prev_field_end_info(/*==========================*/ /* out: offset of the start of the PREVIOUS field, SQL null flag ORed */ rec_t* rec, /* in: record */ ulint n) /* in: field index */{ ut_ad(rec_get_1byte_offs_flag(rec)); ut_ad(n <= rec_get_n_fields_old(rec)); return(mach_read_from_1(rec - (REC_N_OLD_EXTRA_BYTES + n)));} /**********************************************************Returns the offset of n - 1th field end if the record is stored in the 2-byteoffsets form. If the field is SQL null, the flag is ORed in the returnedvalue. */UNIV_INLINEulintrec_2_get_prev_field_end_info(/*==========================*/ /* out: offset of the start of the PREVIOUS field, SQL null flag ORed */ rec_t* rec, /* in: record */ ulint n) /* in: field index */{ ut_ad(!rec_get_1byte_offs_flag(rec)); ut_ad(n <= rec_get_n_fields_old(rec)); return(mach_read_from_2(rec - (REC_N_OLD_EXTRA_BYTES + 2 * n)));}/**********************************************************Sets the field end info for the nth field if the record is stored in the1-byte format. */UNIV_INLINEvoidrec_1_set_field_end_info(/*=====================*/ rec_t* rec, /* in: record */ ulint n, /* in: field index */ ulint info) /* in: value to set */{ ut_ad(rec_get_1byte_offs_flag(rec)); ut_ad(n < rec_get_n_fields_old(rec)); mach_write_to_1(rec - (REC_N_OLD_EXTRA_BYTES + n + 1), info);}/**********************************************************Sets the field end info for the nth field if the record is stored in the2-byte format. */UNIV_INLINEvoidrec_2_set_field_end_info(/*=====================*/ rec_t* rec, /* in: record */ ulint n, /* in: field index */ ulint info) /* in: value to set */{ ut_ad(!rec_get_1byte_offs_flag(rec)); ut_ad(n < rec_get_n_fields_old(rec)); mach_write_to_2(rec - (REC_N_OLD_EXTRA_BYTES + 2 * n + 2), info);}/**********************************************************Returns the offset of nth field start if the record is stored in the 1-byteoffsets form. */UNIV_INLINEulintrec_1_get_field_start_offs(/*=======================*/ /* out: offset of the start of the field */ rec_t* rec, /* in: record */ ulint n) /* in: field index */{ ut_ad(rec_get_1byte_offs_flag(rec)); ut_ad(n <= rec_get_n_fields_old(rec)); if (n == 0) { return(0); } return(rec_1_get_prev_field_end_info(rec, n) & ~REC_1BYTE_SQL_NULL_MASK);} /**********************************************************Returns the offset of nth field start if the record is stored in the 2-byteoffsets form. */UNIV_INLINEulintrec_2_get_field_start_offs(/*=======================*/ /* out: offset of the start of the field */ rec_t* rec, /* in: record */ ulint n) /* in: field index */{ ut_ad(!rec_get_1byte_offs_flag(rec)); ut_ad(n <= rec_get_n_fields_old(rec)); if (n == 0) { return(0); } return(rec_2_get_prev_field_end_info(rec, n) & ~(REC_2BYTE_SQL_NULL_MASK | REC_2BYTE_EXTERN_MASK));} /**********************************************************The following function is used to read the offset of the start of a data fieldin the record. The start of an SQL null field is the end offset of theprevious non-null field, or 0, if none exists. If n is the number of the lastfield + 1, then the end offset of the last field is returned. */UNIV_INLINEulintrec_get_field_start_offs(/*=====================*/ /* out: offset of the start of the field */ rec_t* rec, /* in: record */ ulint n) /* in: field index */{ ut_ad(rec); ut_ad(n <= rec_get_n_fields_old(rec)); if (n == 0) { return(0); } if (rec_get_1byte_offs_flag(rec)) { return(rec_1_get_field_start_offs(rec, n)); } return(rec_2_get_field_start_offs(rec, n));}/****************************************************************Gets the physical size of an old-style field.Also an SQL null may have a field of size > 0,if the data type is of a fixed size. */UNIV_INLINEulintrec_get_nth_field_size(/*===================*/ /* out: field size in bytes */ rec_t* rec, /* in: record */ ulint n) /* in: index of the field */{ ulint os; ulint next_os; os = rec_get_field_start_offs(rec, n); next_os = rec_get_field_start_offs(rec, n + 1); ut_ad(next_os - os < UNIV_PAGE_SIZE); return(next_os - os);}/*************************************************************** This is used to modify the value of an already existing field in a record.The previous value must have exactly the same size as the new value. If lenis UNIV_SQL_NULL then the field is treated as an SQL null for old-stylerecords. For new-style records, len must not be UNIV_SQL_NULL. */UNIV_INLINEvoidrec_set_nth_field(/*==============*/ rec_t* rec, /* in: record */ const ulint* offsets,/* in: array returned by rec_get_offsets() */ ulint n, /* in: index number of the field */ const void* data, /* in: pointer to the data if not SQL null */ ulint len) /* in: length of the data or UNIV_SQL_NULL. If not SQL null, must have the same length as the previous value. If SQL null, previous value must be SQL null. */{ byte* data2; ulint len2; ut_ad(rec); ut_ad(rec_offs_validate(rec, NULL, offsets)); if (len == UNIV_SQL_NULL) { ut_ad(!rec_offs_comp(offsets)); rec_set_nth_field_sql_null(rec, n); return; } data2 = rec_get_nth_field(rec, offsets, n, &len2); if (len2 == UNIV_SQL_NULL) { ut_ad(!rec_offs_comp(offsets)); rec_set_nth_field_null_bit(rec, n, FALSE); ut_ad(len == rec_get_nth_field_size(rec, n)); } else { ut_ad(len2 == len); } ut_memcpy(data2, data, len);}/************************************************************** The following function returns the data size of an old-style physicalrecord, that is the sum of field lengths. SQL null fieldsare counted as length 0 fields. The value returned by the functionis the distance from record origin to record end in bytes. */UNIV_INLINEulintrec_get_data_size_old(/*==================*/ /* out: size */ rec_t* rec) /* in: physical record */{ ut_ad(rec); return(rec_get_field_start_offs(rec, rec_get_n_fields_old(rec)));}/************************************************************** The following function sets the number of fields in offsets. */UNIV_INLINEvoidrec_offs_set_n_fields(/*==================*/ ulint* offsets, /* in: array returned by rec_get_offsets() */ ulint n_fields) /* in: number of fields */{ ut_ad(offsets); ut_ad(n_fields > 0); ut_ad(n_fields <= REC_MAX_N_FIELDS); ut_ad(n_fields + REC_OFFS_HEADER_SIZE <= rec_offs_get_n_alloc(offsets)); offsets[1] = n_fields;}/**************************************************************The following function returns the data size of a physicalrecord, that is the sum of field lengths. SQL null fieldsare counted as length 0 fields. The value returned by the functionis the distance from record origin to record end in bytes. */UNIV_INLINEulintrec_offs_data_size(/*===============*/ /* out: size */ const ulint* offsets)/* in: array returned by rec_get_offsets() */{ ulint size; ut_ad(rec_offs_validate(NULL, NULL, offsets)); size = rec_offs_base(offsets)[rec_offs_n_fields(offsets)] & REC_OFFS_MASK; ut_ad(size < UNIV_PAGE_SIZE); return(size);}/**************************************************************Returns the total size of record minus data size of record. The valuereturned by the function is the distance from record start to record originin bytes. */UNIV_INLINEulintrec_offs_extra_size(/*================*/ /* out: size */ const ulint* offsets)/* in: array returned by rec_get_offsets() */{ ulint size; ut_ad(rec_offs_validate(NULL, NULL, offsets)); size = *rec_offs_base(offsets) & ~REC_OFFS_COMPACT; ut_ad(size < UNIV_PAGE_SIZE); return(size);}/**************************************************************Returns the total size of a physical record. */UNIV_INLINEulintrec_offs_size(/*==========*/ /* out: size */ const ulint* offsets)/* in: array returned by rec_get_offsets() */{ return(rec_offs_data_size(offsets) + rec_offs_extra_size(offsets));} /**************************************************************Returns a pointer to the end of the record. */UNIV_INLINEbyte*rec_get_end(/*========*/ /* out: pointer to end */ rec_t* rec, /* in: pointer to record */ const ulint* offsets)/* in: array returned by rec_get_offsets() */{ return(rec + rec_offs_data_size(offsets));}/**************************************************************Returns a pointer to the start of the record. */UNIV_INLINEbyte*rec_get_start(/*==========*/ /* out: pointer to start */ rec_t* rec, /* in: pointer to record */ const ulint* offsets)/* in: array returned by rec_get_offsets() */{ return(rec - rec_offs_extra_size(offsets));}/*******************************************************************Copies a physical record to a buffer. */UNIV_INLINErec_t*rec_copy(/*=====*/ /* out: pointer to the origin of the copy */ void* buf, /* in: buffer */ const rec_t* rec, /* in: physical record */ const ulint* offsets)/* in: array returned by rec_get_offsets() */{ ulint extra_len; ulint data_len; ut_ad(rec && buf); ut_ad(rec_offs_validate((rec_t*) rec, NULL, offsets)); ut_ad(rec_validate((rec_t*) rec, offsets)); extra_len = rec_offs_extra_size(offsets); data_len = rec_offs_data_size(offsets); ut_memcpy(buf, rec - extra_len, extra_len + data_len); return((byte*)buf + extra_len);}/**************************************************************Returns the extra size of an old-style physical record if we know itsdata size and number of fields. */UNIV_INLINEulintrec_get_converted_extra_size(/*=========================*/ /* out: extra size */ ulint data_size, /* in: data size */ ulint n_fields) /* in: number of fields */{ if (data_size <= REC_1BYTE_OFFS_LIMIT) { return(REC_N_OLD_EXTRA_BYTES + n_fields); } return(REC_N_OLD_EXTRA_BYTES + 2 * n_fields);}/**************************************************************The following function returns the size of a data tuple when converted toa new-style physical record. */ulintrec_get_converted_size_new(/*=======================*/ /* out: size */ dict_index_t* index, /* in: record descriptor */ dtuple_t* dtuple);/* in: data tuple *//**************************************************************The following function returns the size of a data tuple when converted toa physical record. */UNIV_INLINEulintrec_get_converted_size(/*===================*/ /* out: size */ dict_index_t* index, /* in: record descriptor */ dtuple_t* dtuple) /* in: data tuple */{ ulint data_size; ulint extra_size; ut_ad(index); ut_ad(dtuple); ut_ad(dtuple_check_typed(dtuple)); ut_ad(index->type & DICT_UNIVERSAL || dtuple_get_n_fields(dtuple) == (((dtuple_get_info_bits(dtuple) & REC_NEW_STATUS_MASK) == REC_STATUS_NODE_PTR) ? dict_index_get_n_unique_in_tree(index) + 1 : dict_index_get_n_fields(index))); if (UNIV_LIKELY(index->table->comp)) { return(rec_get_converted_size_new(index, dtuple)); } data_size = dtuple_get_data_size(dtuple); extra_size = rec_get_converted_extra_size( data_size, dtuple_get_n_fields(dtuple)); return(data_size + extra_size);}/****************************************************************Folds a prefix of a physical record to a ulint. Folds only existing fields,that is, checks that we do not run out of the record. */UNIV_INLINEulintrec_fold(/*=====*/ /* out: the folded value */ rec_t* rec, /* in: the physical record */ const ulint* offsets, /* in: array returned by rec_get_offsets() */ ulint n_fields, /* in: number of complete fields to fold */ ulint n_bytes, /* in: number of bytes to fold in an incomplete last field */ dulint tree_id) /* in: index tree id */{ ulint i; byte* data; ulint len; ulint fold; ulint n_fields_rec; ut_ad(rec_offs_validate(rec, NULL, offsets)); ut_ad(rec_validate((rec_t*) rec, offsets)); ut_ad(n_fields + n_bytes > 0); n_fields_rec = rec_offs_n_fields(offsets); ut_ad(n_fields <= n_fields_rec); ut_ad(n_fields < n_fields_rec || n_bytes == 0); if (n_fields > n_fields_rec) { n_fields = n_fields_rec; } if (n_fields == n_fields_rec) { n_bytes = 0; } fold = ut_fold_dulint(tree_id); for (i = 0; i < n_fields; i++) { data = rec_get_nth_field(rec, offsets, i, &len); if (len != UNIV_SQL_NULL) { fold = ut_fold_ulint_pair(fold, ut_fold_binary(data, len)); } } if (n_bytes > 0) { data = rec_get_nth_field(rec, offsets, i, &len); if (len != UNIV_SQL_NULL) { if (len > n_bytes) { len = n_bytes; } fold = ut_fold_ulint_pair(fold, ut_fold_binary(data, len)); } } return(fold);}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -