📄 rem0cmp.c
字号:
if (cur_type->mtype >= DATA_FLOAT || (cur_type->mtype == DATA_BLOB && 0 == (cur_type->prtype & DATA_BINARY_TYPE) && dtype_get_charset_coll(cur_type->prtype) != DATA_MYSQL_LATIN1_SWEDISH_CHARSET_COLL)) { ret = cmp_whole_field( cur_type, dfield_get_data(dtuple_field), (unsigned) dtuple_f_len, rec_b_ptr, (unsigned) rec_f_len); if (ret != 0) { cur_bytes = 0; goto order_resolved; } else { goto next_field; } } /* Set the pointers at the current byte */ rec_b_ptr = rec_b_ptr + cur_bytes; dtuple_b_ptr = (byte*)dfield_get_data(dtuple_field) + cur_bytes; /* Compare then the fields */ for (;;) { if (UNIV_UNLIKELY(rec_f_len <= cur_bytes)) { if (dtuple_f_len <= cur_bytes) { goto next_field; } rec_byte = dtype_get_pad_char(cur_type); if (rec_byte == ULINT_UNDEFINED) { ret = 1; goto order_resolved; } } else { rec_byte = *rec_b_ptr; } if (UNIV_UNLIKELY(dtuple_f_len <= cur_bytes)) { dtuple_byte = dtype_get_pad_char(cur_type); if (dtuple_byte == ULINT_UNDEFINED) { ret = -1; goto order_resolved; } } else { dtuple_byte = *dtuple_b_ptr; } if (dtuple_byte == rec_byte) { /* If the bytes are equal, they will remain such even after the collation transformation below */ goto next_byte; } if (cur_type->mtype <= DATA_CHAR || (cur_type->mtype == DATA_BLOB && 0 == (cur_type->prtype & DATA_BINARY_TYPE))) { rec_byte = cmp_collate(rec_byte); dtuple_byte = cmp_collate(dtuple_byte); } ret = dtuple_byte - rec_byte; if (UNIV_UNLIKELY(ret)) { if (ret < 0) { ret = -1; goto order_resolved; } else { ret = 1; goto order_resolved; } } next_byte: /* Next byte */ cur_bytes++; rec_b_ptr++; dtuple_b_ptr++; } next_field: cur_field++; cur_bytes = 0; } ut_ad(cur_bytes == 0); ret = 0; /* If we ran out of fields, dtuple was equal to rec up to the common fields */order_resolved: ut_ad((ret >= - 1) && (ret <= 1)); ut_ad(ret == cmp_debug_dtuple_rec_with_match(dtuple, rec, offsets, matched_fields)); ut_ad(*matched_fields == cur_field); /* In the debug version, the above cmp_debug_... sets *matched_fields to a value */ *matched_fields = cur_field; *matched_bytes = cur_bytes; return(ret);}/******************************************************************Compares a data tuple to a physical record. */intcmp_dtuple_rec(/*===========*/ /* out: 1, 0, -1, if dtuple is greater, equal, less than rec, respectively; see the comments for cmp_dtuple_rec_with_match */ dtuple_t* dtuple, /* in: data tuple */ rec_t* rec, /* in: physical record */ const ulint* offsets)/* in: array returned by rec_get_offsets() */{ ulint matched_fields = 0; ulint matched_bytes = 0; ut_ad(rec_offs_validate(rec, NULL, offsets)); return(cmp_dtuple_rec_with_match(dtuple, rec, offsets, &matched_fields, &matched_bytes));}/******************************************************************Checks if a dtuple is a prefix of a record. The last field in dtupleis allowed to be a prefix of the corresponding field in the record. */iboolcmp_dtuple_is_prefix_of_rec(/*========================*/ /* out: TRUE if prefix */ dtuple_t* dtuple, /* in: data tuple */ rec_t* rec, /* in: physical record */ const ulint* offsets)/* in: array returned by rec_get_offsets() */{ ulint n_fields; ulint matched_fields = 0; ulint matched_bytes = 0; ut_ad(rec_offs_validate(rec, NULL, offsets)); n_fields = dtuple_get_n_fields(dtuple); if (n_fields > rec_offs_n_fields(offsets)) { return(FALSE); } cmp_dtuple_rec_with_match(dtuple, rec, offsets, &matched_fields, &matched_bytes); if (matched_fields == n_fields) { return(TRUE); } if (matched_fields == n_fields - 1 && matched_bytes == dfield_get_len( dtuple_get_nth_field(dtuple, n_fields - 1))) { return(TRUE); } return(FALSE); }/*****************************************************************This function is used to compare two physical records. Only the commonfirst fields are compared, and if an externally stored field isencountered, then 0 is returned. */intcmp_rec_rec_with_match(/*===================*/ /* out: 1, 0 , -1 if rec1 is greater, equal, less, respectively, than rec2; only the common first fields are compared */ rec_t* rec1, /* in: physical record */ rec_t* rec2, /* in: physical record */ const ulint* offsets1,/* in: rec_get_offsets(rec1, index) */ const ulint* offsets2,/* in: rec_get_offsets(rec2, index) */ dict_index_t* index, /* in: data dictionary index */ ulint* matched_fields, /* in/out: number of already completely matched fields; when the function returns, contains the value the for current comparison */ ulint* matched_bytes) /* in/out: number of already matched bytes within the first field not completely matched; when the function returns, contains the value for the current comparison */{ dtype_t* cur_type; /* pointer to type struct of the current field in index */ ulint rec1_n_fields; /* the number of fields in rec */ ulint rec1_f_len; /* length of current field in rec */ byte* rec1_b_ptr; /* pointer to the current byte in rec field */ ulint rec1_byte; /* value of current byte to be compared in rec */ ulint rec2_n_fields; /* the number of fields in rec */ ulint rec2_f_len; /* length of current field in rec */ byte* rec2_b_ptr; /* pointer to the current byte in rec field */ ulint rec2_byte; /* value of current byte to be compared in rec */ ulint cur_field; /* current field number */ ulint cur_bytes; /* number of already matched bytes in current field */ int ret = 3333; /* return value */ ulint comp; ut_ad(rec1 && rec2 && index); ut_ad(rec_offs_validate(rec1, index, offsets1)); ut_ad(rec_offs_validate(rec2, index, offsets2)); ut_ad(rec_offs_comp(offsets1) == rec_offs_comp(offsets2)); comp = rec_offs_comp(offsets1); rec1_n_fields = rec_offs_n_fields(offsets1); rec2_n_fields = rec_offs_n_fields(offsets2); cur_field = *matched_fields; cur_bytes = *matched_bytes; /* Match fields in a loop */ while ((cur_field < rec1_n_fields) && (cur_field < rec2_n_fields)) { if (index->type & DICT_UNIVERSAL) { cur_type = dtype_binary; } else { cur_type = dict_col_get_type( dict_field_get_col( dict_index_get_nth_field(index, cur_field))); } rec1_b_ptr = rec_get_nth_field(rec1, offsets1, cur_field, &rec1_f_len); rec2_b_ptr = rec_get_nth_field(rec2, offsets2, cur_field, &rec2_f_len); if (cur_bytes == 0) { if (cur_field == 0) { /* Test if rec is the predefined minimum record */ if (rec_get_info_bits(rec1, comp) & REC_INFO_MIN_REC_FLAG) { if (rec_get_info_bits(rec2, comp) & REC_INFO_MIN_REC_FLAG) { ret = 0; } else { ret = -1; } goto order_resolved; } else if (rec_get_info_bits(rec2, comp) & REC_INFO_MIN_REC_FLAG) { ret = 1; goto order_resolved; } } if (rec_offs_nth_extern(offsets1, cur_field) || rec_offs_nth_extern(offsets2, cur_field)) { /* We do not compare to an externally stored field */ ret = 0; goto order_resolved; } if (rec1_f_len == UNIV_SQL_NULL || rec2_f_len == UNIV_SQL_NULL) { if (rec1_f_len == rec2_f_len) { goto next_field; } else if (rec2_f_len == UNIV_SQL_NULL) { /* We define the SQL null to be the smallest possible value of a field in the alphabetical order */ ret = 1; } else { ret = -1; } goto order_resolved; } } if (cur_type->mtype >= DATA_FLOAT || (cur_type->mtype == DATA_BLOB && 0 == (cur_type->prtype & DATA_BINARY_TYPE) && dtype_get_charset_coll(cur_type->prtype) != DATA_MYSQL_LATIN1_SWEDISH_CHARSET_COLL)) { ret = cmp_whole_field(cur_type, rec1_b_ptr, (unsigned) rec1_f_len, rec2_b_ptr, (unsigned) rec2_f_len); if (ret != 0) { cur_bytes = 0; goto order_resolved; } else { goto next_field; } } /* Set the pointers at the current byte */ rec1_b_ptr = rec1_b_ptr + cur_bytes; rec2_b_ptr = rec2_b_ptr + cur_bytes; /* Compare then the fields */ for (;;) { if (rec2_f_len <= cur_bytes) { if (rec1_f_len <= cur_bytes) { goto next_field; } rec2_byte = dtype_get_pad_char(cur_type); if (rec2_byte == ULINT_UNDEFINED) { ret = 1; goto order_resolved; } } else { rec2_byte = *rec2_b_ptr; } if (rec1_f_len <= cur_bytes) { rec1_byte = dtype_get_pad_char(cur_type); if (rec1_byte == ULINT_UNDEFINED) { ret = -1; goto order_resolved; } } else { rec1_byte = *rec1_b_ptr; } if (rec1_byte == rec2_byte) { /* If the bytes are equal, they will remain such even after the collation transformation below */ goto next_byte; } if (cur_type->mtype <= DATA_CHAR || (cur_type->mtype == DATA_BLOB && 0 == (cur_type->prtype & DATA_BINARY_TYPE))) { rec1_byte = cmp_collate(rec1_byte); rec2_byte = cmp_collate(rec2_byte); } if (rec1_byte < rec2_byte) { ret = -1; goto order_resolved; } else if (rec1_byte > rec2_byte) { ret = 1; goto order_resolved; } next_byte: /* Next byte */ cur_bytes++; rec1_b_ptr++; rec2_b_ptr++; } next_field: cur_field++; cur_bytes = 0; } ut_ad(cur_bytes == 0); ret = 0; /* If we ran out of fields, rec1 was equal to rec2 up to the common fields */order_resolved: ut_ad((ret >= - 1) && (ret <= 1)); *matched_fields = cur_field; *matched_bytes = cur_bytes; return(ret);}#ifdef UNIV_DEBUG/*****************************************************************Used in debug checking of cmp_dtuple_... .This function is used to compare a data tuple to a physical record. Ifdtuple has n fields then rec must have either m >= n fields, or it mustdiffer from dtuple in some of the m fields rec has. If encounters anexternally stored field, returns 0. */staticintcmp_debug_dtuple_rec_with_match(/*============================*/ /* out: 1, 0, -1, if dtuple is greater, equal, less than rec, respectively, when only the common first fields are compared */ dtuple_t* dtuple, /* in: data tuple */ rec_t* rec, /* in: physical record which differs from dtuple in some of the common fields, or which has an equal number or more fields than dtuple */ const ulint* offsets,/* in: array returned by rec_get_offsets() */ ulint* matched_fields) /* in/out: number of already completely matched fields; when function returns, contains the value for current comparison */{ dtype_t* cur_type; /* pointer to type of the current field in dtuple */ dfield_t* dtuple_field; /* current field in logical record */ ulint dtuple_f_len; /* the length of the current field in the logical record */ byte* dtuple_f_data; /* pointer to the current logical field data */ ulint rec_f_len; /* length of current field in rec */ byte* rec_f_data; /* pointer to the current rec field */ int ret = 3333; /* return value */ ulint cur_field; /* current field number */ ut_ad(dtuple && rec && matched_fields); ut_ad(dtuple_check_typed(dtuple)); ut_ad(rec_offs_validate(rec, NULL, offsets)); ut_ad(*matched_fields <= dtuple_get_n_fields_cmp(dtuple)); ut_ad(*matched_fields <= rec_offs_n_fields(offsets)); cur_field = *matched_fields; if (cur_field == 0) { if (rec_get_info_bits(rec, rec_offs_comp(offsets)) & REC_INFO_MIN_REC_FLAG) { ret = !(dtuple_get_info_bits(dtuple) & REC_INFO_MIN_REC_FLAG); goto order_resolved; } if (dtuple_get_info_bits(dtuple) & REC_INFO_MIN_REC_FLAG) { ret = -1; goto order_resolved; } } /* Match fields in a loop; stop if we run out of fields in dtuple */ while (cur_field < dtuple_get_n_fields_cmp(dtuple)) { dtuple_field = dtuple_get_nth_field(dtuple, cur_field); cur_type = dfield_get_type(dtuple_field); dtuple_f_data = dfield_get_data(dtuple_field); dtuple_f_len = dfield_get_len(dtuple_field); rec_f_data = rec_get_nth_field(rec, offsets, cur_field, &rec_f_len); if (rec_offs_nth_extern(offsets, cur_field)) { /* We do not compare to an externally stored field */ ret = 0; goto order_resolved; } ret = cmp_data_data(cur_type, dtuple_f_data, dtuple_f_len, rec_f_data, rec_f_len); if (ret != 0) { goto order_resolved; } cur_field++; } ret = 0; /* If we ran out of fields, dtuple was equal to rec up to the common fields */order_resolved: ut_ad((ret >= - 1) && (ret <= 1)); *matched_fields = cur_field; return(ret);}#endif /* UNIV_DEBUG */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -