00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00026 #include "rem0cmp.h"
00027
00028 #ifdef UNIV_NONINL
00029 #include "rem0cmp.ic"
00030 #endif
00031
00032 #include "srv0srv.h"
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053 #ifdef UNIV_DEBUG
00054
00061 static
00062 int
00063 cmp_debug_dtuple_rec_with_match(
00064
00065 const dtuple_t* dtuple,
00066 const rec_t* rec,
00070 const ulint* offsets,
00071 ulint* matched_fields);
00075 #endif
00076
00081 extern
00082 int
00083 innobase_mysql_cmp(
00084
00085 int mysql_type,
00086 uint charset_number,
00087 const unsigned char* a,
00088 unsigned int a_length,
00090 const unsigned char* b,
00091 unsigned int b_length);
00093
00098 UNIV_INLINE
00099 ulint
00100 cmp_collate(
00101
00102 ulint code)
00103 {
00104 return((ulint) srv_latin1_ordering[code]);
00105 }
00106
00107
00110 UNIV_INTERN
00111 ibool
00112 cmp_cols_are_equal(
00113
00114 const dict_col_t* col1,
00115 const dict_col_t* col2,
00116 ibool check_charsets)
00118 {
00119 if (dtype_is_non_binary_string_type(col1->mtype, col1->prtype)
00120 && dtype_is_non_binary_string_type(col2->mtype, col2->prtype)) {
00121
00122
00123
00124
00125 if (check_charsets) {
00126 return(dtype_get_charset_coll(col1->prtype)
00127 == dtype_get_charset_coll(col2->prtype));
00128 } else {
00129 return(TRUE);
00130 }
00131 }
00132
00133 if (dtype_is_binary_string_type(col1->mtype, col1->prtype)
00134 && dtype_is_binary_string_type(col2->mtype, col2->prtype)) {
00135
00136
00137
00138 return(TRUE);
00139 }
00140
00141 if (col1->mtype != col2->mtype) {
00142
00143 return(FALSE);
00144 }
00145
00146 if (col1->mtype == DATA_INT
00147 && (col1->prtype & DATA_UNSIGNED)
00148 != (col2->prtype & DATA_UNSIGNED)) {
00149
00150
00151
00152
00153
00154 return(FALSE);
00155 }
00156
00157 return(col1->mtype != DATA_INT || col1->len == col2->len);
00158 }
00159
00160
00164 static
00165 int
00166 cmp_whole_field(
00167
00168 ulint mtype,
00169 ulint prtype,
00170 const byte* a,
00171 unsigned int a_length,
00173 const byte* b,
00174 unsigned int b_length)
00176 {
00177 float f_1;
00178 float f_2;
00179 double d_1;
00180 double d_2;
00181 int swap_flag = 1;
00182
00183 switch (mtype) {
00184
00185 case DATA_DECIMAL:
00186
00187 for (; a_length && *a == ' '; a++, a_length--) {}
00188 for (; b_length && *b == ' '; b++, b_length--) {}
00189
00190 if (*a == '-') {
00191 if (*b != '-') {
00192 return(-1);
00193 }
00194
00195 a++; b++;
00196 a_length--;
00197 b_length--;
00198
00199 swap_flag = -1;
00200
00201 } else if (*b == '-') {
00202
00203 return(1);
00204 }
00205
00206 while (a_length > 0 && (*a == '+' || *a == '0')) {
00207 a++; a_length--;
00208 }
00209
00210 while (b_length > 0 && (*b == '+' || *b == '0')) {
00211 b++; b_length--;
00212 }
00213
00214 if (a_length != b_length) {
00215 if (a_length < b_length) {
00216 return(-swap_flag);
00217 }
00218
00219 return(swap_flag);
00220 }
00221
00222 while (a_length > 0 && *a == *b) {
00223
00224 a++; b++; a_length--;
00225 }
00226
00227 if (a_length == 0) {
00228
00229 return(0);
00230 }
00231
00232 if (*a > *b) {
00233 return(swap_flag);
00234 }
00235
00236 return(-swap_flag);
00237 case DATA_DOUBLE:
00238 d_1 = mach_double_read(a);
00239 d_2 = mach_double_read(b);
00240
00241 if (d_1 > d_2) {
00242 return(1);
00243 } else if (d_2 > d_1) {
00244 return(-1);
00245 }
00246
00247 return(0);
00248
00249 case DATA_FLOAT:
00250 f_1 = mach_float_read(a);
00251 f_2 = mach_float_read(b);
00252
00253 if (f_1 > f_2) {
00254 return(1);
00255 } else if (f_2 > f_1) {
00256 return(-1);
00257 }
00258
00259 return(0);
00260 case DATA_BLOB:
00261 if (prtype & DATA_BINARY_TYPE) {
00262
00263 ut_print_timestamp(stderr);
00264 fprintf(stderr,
00265 " InnoDB: Error: comparing a binary BLOB"
00266 " with a character set sensitive\n"
00267 "InnoDB: comparison!\n");
00268 }
00269
00270 case DATA_VARMYSQL:
00271 case DATA_MYSQL:
00272 return(innobase_mysql_cmp(
00273 (int)(prtype & DATA_MYSQL_TYPE_MASK),
00274 (uint)dtype_get_charset_coll(prtype),
00275 a, a_length, b, b_length));
00276 default:
00277 fprintf(stderr,
00278 "InnoDB: unknown type number %lu\n",
00279 (ulong) mtype);
00280 ut_error;
00281 }
00282
00283 return(0);
00284 }
00285
00286
00290 UNIV_INTERN
00291 int
00292 cmp_data_data_slow(
00293
00294 ulint mtype,
00295 ulint prtype,
00296 const byte* data1,
00298 ulint len1,
00299 const byte* data2,
00301 ulint len2)
00302 {
00303 ulint data1_byte;
00304 ulint data2_byte;
00305 ulint cur_bytes;
00306
00307 if (len1 == UNIV_SQL_NULL || len2 == UNIV_SQL_NULL) {
00308
00309 if (len1 == len2) {
00310
00311 return(0);
00312 }
00313
00314 if (len1 == UNIV_SQL_NULL) {
00315
00316
00317
00318 return(-1);
00319 }
00320
00321 return(1);
00322 }
00323
00324 if (mtype >= DATA_FLOAT
00325 || (mtype == DATA_BLOB
00326 && 0 == (prtype & DATA_BINARY_TYPE)
00327 && dtype_get_charset_coll(prtype)
00328 != DATA_MYSQL_LATIN1_SWEDISH_CHARSET_COLL)) {
00329
00330 return(cmp_whole_field(mtype, prtype,
00331 data1, (unsigned) len1,
00332 data2, (unsigned) len2));
00333 }
00334
00335
00336
00337 cur_bytes = 0;
00338
00339 for (;;) {
00340 if (len1 <= cur_bytes) {
00341 if (len2 <= cur_bytes) {
00342
00343 return(0);
00344 }
00345
00346 data1_byte = dtype_get_pad_char(mtype, prtype);
00347
00348 if (data1_byte == ULINT_UNDEFINED) {
00349
00350 return(-1);
00351 }
00352 } else {
00353 data1_byte = *data1;
00354 }
00355
00356 if (len2 <= cur_bytes) {
00357 data2_byte = dtype_get_pad_char(mtype, prtype);
00358
00359 if (data2_byte == ULINT_UNDEFINED) {
00360
00361 return(1);
00362 }
00363 } else {
00364 data2_byte = *data2;
00365 }
00366
00367 if (data1_byte == data2_byte) {
00368
00369
00370
00371 goto next_byte;
00372 }
00373
00374 if (mtype <= DATA_CHAR
00375 || (mtype == DATA_BLOB
00376 && 0 == (prtype & DATA_BINARY_TYPE))) {
00377
00378 data1_byte = cmp_collate(data1_byte);
00379 data2_byte = cmp_collate(data2_byte);
00380 }
00381
00382 if (data1_byte > data2_byte) {
00383
00384 return(1);
00385 } else if (data1_byte < data2_byte) {
00386
00387 return(-1);
00388 }
00389 next_byte:
00390
00391 cur_bytes++;
00392 data1++;
00393 data2++;
00394 }
00395
00396 }
00397
00398
00409 UNIV_INTERN
00410 int
00411 cmp_dtuple_rec_with_match(
00412
00413 const dtuple_t* dtuple,
00414 const rec_t* rec,
00418 const ulint* offsets,
00419 ulint* matched_fields,
00422 ulint* matched_bytes)
00426 {
00427 const dfield_t* dtuple_field;
00428 ulint dtuple_f_len;
00429
00430 const byte* dtuple_b_ptr;
00431
00432 ulint dtuple_byte;
00433
00434 ulint rec_f_len;
00435 const byte* rec_b_ptr;
00436
00437 ulint rec_byte;
00438
00439 ulint cur_field;
00440 ulint cur_bytes;
00441
00442 int ret = 3333;
00443
00444 ut_ad(dtuple && rec && matched_fields && matched_bytes);
00445 ut_ad(dtuple_check_typed(dtuple));
00446 ut_ad(rec_offs_validate(rec, NULL, offsets));
00447
00448 cur_field = *matched_fields;
00449 cur_bytes = *matched_bytes;
00450
00451 ut_ad(cur_field <= dtuple_get_n_fields_cmp(dtuple));
00452 ut_ad(cur_field <= rec_offs_n_fields(offsets));
00453
00454 if (cur_bytes == 0 && cur_field == 0) {
00455 ulint rec_info = rec_get_info_bits(rec,
00456 rec_offs_comp(offsets));
00457 ulint tup_info = dtuple_get_info_bits(dtuple);
00458
00459 if (UNIV_UNLIKELY(rec_info & REC_INFO_MIN_REC_FLAG)) {
00460 ret = !(tup_info & REC_INFO_MIN_REC_FLAG);
00461 goto order_resolved;
00462 } else if (UNIV_UNLIKELY(tup_info & REC_INFO_MIN_REC_FLAG)) {
00463 ret = -1;
00464 goto order_resolved;
00465 }
00466 }
00467
00468
00469
00470
00471 while (cur_field < dtuple_get_n_fields_cmp(dtuple)) {
00472
00473 ulint mtype;
00474 ulint prtype;
00475
00476 dtuple_field = dtuple_get_nth_field(dtuple, cur_field);
00477 {
00478 const dtype_t* type
00479 = dfield_get_type(dtuple_field);
00480
00481 mtype = type->mtype;
00482 prtype = type->prtype;
00483 }
00484
00485 dtuple_f_len = dfield_get_len(dtuple_field);
00486
00487 rec_b_ptr = rec_get_nth_field(rec, offsets,
00488 cur_field, &rec_f_len);
00489
00490
00491
00492
00493
00494
00495 if (UNIV_LIKELY(cur_bytes == 0)) {
00496 if (rec_offs_nth_extern(offsets, cur_field)) {
00497
00498
00499
00500 ret = 0;
00501
00502 goto order_resolved;
00503 }
00504
00505 if (dtuple_f_len == UNIV_SQL_NULL) {
00506 if (rec_f_len == UNIV_SQL_NULL) {
00507
00508 goto next_field;
00509 }
00510
00511 ret = -1;
00512 goto order_resolved;
00513 } else if (rec_f_len == UNIV_SQL_NULL) {
00514
00515
00516
00517
00518 ret = 1;
00519 goto order_resolved;
00520 }
00521 }
00522
00523 if (mtype >= DATA_FLOAT
00524 || (mtype == DATA_BLOB
00525 && 0 == (prtype & DATA_BINARY_TYPE)
00526 && dtype_get_charset_coll(prtype)
00527 != DATA_MYSQL_LATIN1_SWEDISH_CHARSET_COLL)) {
00528
00529 ret = cmp_whole_field(mtype, prtype,
00530 static_cast<const unsigned char *>(dfield_get_data(dtuple_field)),
00531 (unsigned) dtuple_f_len,
00532 rec_b_ptr, (unsigned) rec_f_len);
00533
00534 if (ret != 0) {
00535 cur_bytes = 0;
00536
00537 goto order_resolved;
00538 } else {
00539 goto next_field;
00540 }
00541 }
00542
00543
00544
00545 rec_b_ptr = rec_b_ptr + cur_bytes;
00546 dtuple_b_ptr = (byte*)dfield_get_data(dtuple_field)
00547 + cur_bytes;
00548
00549
00550 for (;;) {
00551 if (UNIV_UNLIKELY(rec_f_len <= cur_bytes)) {
00552 if (dtuple_f_len <= cur_bytes) {
00553
00554 goto next_field;
00555 }
00556
00557 rec_byte = dtype_get_pad_char(mtype, prtype);
00558
00559 if (rec_byte == ULINT_UNDEFINED) {
00560 ret = 1;
00561
00562 goto order_resolved;
00563 }
00564 } else {
00565 rec_byte = *rec_b_ptr;
00566 }
00567
00568 if (UNIV_UNLIKELY(dtuple_f_len <= cur_bytes)) {
00569 dtuple_byte = dtype_get_pad_char(mtype,
00570 prtype);
00571
00572 if (dtuple_byte == ULINT_UNDEFINED) {
00573 ret = -1;
00574
00575 goto order_resolved;
00576 }
00577 } else {
00578 dtuple_byte = *dtuple_b_ptr;
00579 }
00580
00581 if (dtuple_byte == rec_byte) {
00582
00583
00584
00585
00586 goto next_byte;
00587 }
00588
00589 if (mtype <= DATA_CHAR
00590 || (mtype == DATA_BLOB
00591 && !(prtype & DATA_BINARY_TYPE))) {
00592
00593 rec_byte = cmp_collate(rec_byte);
00594 dtuple_byte = cmp_collate(dtuple_byte);
00595 }
00596
00597 ret = (int) (dtuple_byte - rec_byte);
00598 if (UNIV_LIKELY(ret)) {
00599 if (ret < 0) {
00600 ret = -1;
00601 goto order_resolved;
00602 } else {
00603 ret = 1;
00604 goto order_resolved;
00605 }
00606 }
00607 next_byte:
00608
00609 cur_bytes++;
00610 rec_b_ptr++;
00611 dtuple_b_ptr++;
00612 }
00613
00614 next_field:
00615 cur_field++;
00616 cur_bytes = 0;
00617 }
00618
00619 ut_ad(cur_bytes == 0);
00620
00621 ret = 0;
00622
00623 order_resolved:
00624 ut_ad((ret >= - 1) && (ret <= 1));
00625 ut_ad(ret == cmp_debug_dtuple_rec_with_match(dtuple, rec, offsets,
00626 matched_fields));
00627 ut_ad(*matched_fields == cur_field);
00628
00629
00630 *matched_fields = cur_field;
00631 *matched_bytes = cur_bytes;
00632
00633 return(ret);
00634 }
00635
00636
00640 UNIV_INTERN
00641 int
00642 cmp_dtuple_rec(
00643
00644 const dtuple_t* dtuple,
00645 const rec_t* rec,
00646 const ulint* offsets)
00647 {
00648 ulint matched_fields = 0;
00649 ulint matched_bytes = 0;
00650
00651 ut_ad(rec_offs_validate(rec, NULL, offsets));
00652 return(cmp_dtuple_rec_with_match(dtuple, rec, offsets,
00653 &matched_fields, &matched_bytes));
00654 }
00655
00656
00660 UNIV_INTERN
00661 ibool
00662 cmp_dtuple_is_prefix_of_rec(
00663
00664 const dtuple_t* dtuple,
00665 const rec_t* rec,
00666 const ulint* offsets)
00667 {
00668 ulint n_fields;
00669 ulint matched_fields = 0;
00670 ulint matched_bytes = 0;
00671
00672 ut_ad(rec_offs_validate(rec, NULL, offsets));
00673 n_fields = dtuple_get_n_fields(dtuple);
00674
00675 if (n_fields > rec_offs_n_fields(offsets)) {
00676
00677 return(FALSE);
00678 }
00679
00680 cmp_dtuple_rec_with_match(dtuple, rec, offsets,
00681 &matched_fields, &matched_bytes);
00682 if (matched_fields == n_fields) {
00683
00684 return(TRUE);
00685 }
00686
00687 if (matched_fields == n_fields - 1
00688 && matched_bytes == dfield_get_len(
00689 dtuple_get_nth_field(dtuple, n_fields - 1))) {
00690 return(TRUE);
00691 }
00692
00693 return(FALSE);
00694 }
00695
00696
00700 UNIV_INTERN
00701 int
00702 cmp_rec_rec_simple(
00703
00704 const rec_t* rec1,
00705 const rec_t* rec2,
00706 const ulint* offsets1,
00707 const ulint* offsets2,
00708 const dict_index_t* index,
00709 ibool* null_eq)
00711 {
00712 ulint rec1_f_len;
00713 const byte* rec1_b_ptr;
00715 ulint rec1_byte;
00717 ulint rec2_f_len;
00718 const byte* rec2_b_ptr;
00720 ulint rec2_byte;
00722 ulint cur_field;
00723 ulint n_uniq;
00724
00725 n_uniq = dict_index_get_n_unique(index);
00726 ut_ad(rec_offs_n_fields(offsets1) >= n_uniq);
00727 ut_ad(rec_offs_n_fields(offsets2) >= n_uniq);
00728
00729 ut_ad(rec_offs_comp(offsets1) == rec_offs_comp(offsets2));
00730
00731 for (cur_field = 0; cur_field < n_uniq; cur_field++) {
00732
00733 ulint cur_bytes;
00734 ulint mtype;
00735 ulint prtype;
00736
00737 {
00738 const dict_col_t* col
00739 = dict_index_get_nth_col(index, cur_field);
00740
00741 mtype = col->mtype;
00742 prtype = col->prtype;
00743 }
00744
00745 ut_ad(!rec_offs_nth_extern(offsets1, cur_field));
00746 ut_ad(!rec_offs_nth_extern(offsets2, cur_field));
00747
00748 rec1_b_ptr = rec_get_nth_field(rec1, offsets1,
00749 cur_field, &rec1_f_len);
00750 rec2_b_ptr = rec_get_nth_field(rec2, offsets2,
00751 cur_field, &rec2_f_len);
00752
00753 if (rec1_f_len == UNIV_SQL_NULL
00754 || rec2_f_len == UNIV_SQL_NULL) {
00755
00756 if (rec1_f_len == rec2_f_len) {
00757 if (null_eq) {
00758 *null_eq = TRUE;
00759 }
00760
00761 goto next_field;
00762
00763 } else if (rec2_f_len == UNIV_SQL_NULL) {
00764
00765
00766
00767
00768
00769 return(1);
00770 } else {
00771 return(-1);
00772 }
00773 }
00774
00775 if (mtype >= DATA_FLOAT
00776 || (mtype == DATA_BLOB
00777 && 0 == (prtype & DATA_BINARY_TYPE)
00778 && dtype_get_charset_coll(prtype)
00779 != DATA_MYSQL_LATIN1_SWEDISH_CHARSET_COLL)) {
00780 int ret = cmp_whole_field(mtype, prtype,
00781 rec1_b_ptr,
00782 (unsigned) rec1_f_len,
00783 rec2_b_ptr,
00784 (unsigned) rec2_f_len);
00785 if (ret) {
00786 return(ret);
00787 }
00788
00789 goto next_field;
00790 }
00791
00792
00793 for (cur_bytes = 0;; cur_bytes++, rec1_b_ptr++, rec2_b_ptr++) {
00794 if (rec2_f_len <= cur_bytes) {
00795
00796 if (rec1_f_len <= cur_bytes) {
00797
00798 goto next_field;
00799 }
00800
00801 rec2_byte = dtype_get_pad_char(mtype, prtype);
00802
00803 if (rec2_byte == ULINT_UNDEFINED) {
00804 return(1);
00805 }
00806 } else {
00807 rec2_byte = *rec2_b_ptr;
00808 }
00809
00810 if (rec1_f_len <= cur_bytes) {
00811 rec1_byte = dtype_get_pad_char(mtype, prtype);
00812
00813 if (rec1_byte == ULINT_UNDEFINED) {
00814 return(-1);
00815 }
00816 } else {
00817 rec1_byte = *rec1_b_ptr;
00818 }
00819
00820 if (rec1_byte == rec2_byte) {
00821
00822
00823
00824
00825 continue;
00826 }
00827
00828 if (mtype <= DATA_CHAR
00829 || (mtype == DATA_BLOB
00830 && !(prtype & DATA_BINARY_TYPE))) {
00831
00832 rec1_byte = cmp_collate(rec1_byte);
00833 rec2_byte = cmp_collate(rec2_byte);
00834 }
00835
00836 if (rec1_byte < rec2_byte) {
00837 return(-1);
00838 } else if (rec1_byte > rec2_byte) {
00839 return(1);
00840 }
00841 }
00842 next_field:
00843 continue;
00844 }
00845
00846
00847 return(0);
00848 }
00849
00850
00855 UNIV_INTERN
00856 int
00857 cmp_rec_rec_with_match(
00858
00859 const rec_t* rec1,
00860 const rec_t* rec2,
00861 const ulint* offsets1,
00862 const ulint* offsets2,
00863 dict_index_t* index,
00864 ulint* matched_fields,
00868 ulint* matched_bytes)
00872 {
00873 ulint rec1_n_fields;
00874 ulint rec1_f_len;
00875 const byte* rec1_b_ptr;
00876
00877 ulint rec1_byte;
00878
00879 ulint rec2_n_fields;
00880 ulint rec2_f_len;
00881 const byte* rec2_b_ptr;
00882
00883 ulint rec2_byte;
00884
00885 ulint cur_field;
00886 ulint cur_bytes;
00887
00888 int ret = 0;
00889 ulint comp;
00890
00891 ut_ad(rec1 && rec2 && index);
00892 ut_ad(rec_offs_validate(rec1, index, offsets1));
00893 ut_ad(rec_offs_validate(rec2, index, offsets2));
00894 ut_ad(rec_offs_comp(offsets1) == rec_offs_comp(offsets2));
00895
00896 comp = rec_offs_comp(offsets1);
00897 rec1_n_fields = rec_offs_n_fields(offsets1);
00898 rec2_n_fields = rec_offs_n_fields(offsets2);
00899
00900 cur_field = *matched_fields;
00901 cur_bytes = *matched_bytes;
00902
00903
00904
00905 while ((cur_field < rec1_n_fields) && (cur_field < rec2_n_fields)) {
00906
00907 ulint mtype;
00908 ulint prtype;
00909
00910 if (UNIV_UNLIKELY(index->type & DICT_UNIVERSAL)) {
00911
00912 mtype = DATA_BINARY;
00913 prtype = 0;
00914 } else {
00915 const dict_col_t* col
00916 = dict_index_get_nth_col(index, cur_field);
00917
00918 mtype = col->mtype;
00919 prtype = col->prtype;
00920 }
00921
00922 rec1_b_ptr = rec_get_nth_field(rec1, offsets1,
00923 cur_field, &rec1_f_len);
00924 rec2_b_ptr = rec_get_nth_field(rec2, offsets2,
00925 cur_field, &rec2_f_len);
00926
00927 if (cur_bytes == 0) {
00928 if (cur_field == 0) {
00929
00930
00931 if (UNIV_UNLIKELY(rec_get_info_bits(rec1, comp)
00932 & REC_INFO_MIN_REC_FLAG)) {
00933
00934 if (!(rec_get_info_bits(rec2, comp)
00935 & REC_INFO_MIN_REC_FLAG)) {
00936 ret = -1;
00937 }
00938
00939 goto order_resolved;
00940
00941 } else if (UNIV_UNLIKELY
00942 (rec_get_info_bits(rec2, comp)
00943 & REC_INFO_MIN_REC_FLAG)) {
00944
00945 ret = 1;
00946
00947 goto order_resolved;
00948 }
00949 }
00950
00951 if (rec_offs_nth_extern(offsets1, cur_field)
00952 || rec_offs_nth_extern(offsets2, cur_field)) {
00953
00954
00955
00956 goto order_resolved;
00957 }
00958
00959 if (rec1_f_len == UNIV_SQL_NULL
00960 || rec2_f_len == UNIV_SQL_NULL) {
00961
00962 if (rec1_f_len == rec2_f_len) {
00963
00964 goto next_field;
00965
00966 } else if (rec2_f_len == UNIV_SQL_NULL) {
00967
00968
00969
00970
00971
00972 ret = 1;
00973 } else {
00974 ret = -1;
00975 }
00976
00977 goto order_resolved;
00978 }
00979 }
00980
00981 if (mtype >= DATA_FLOAT
00982 || (mtype == DATA_BLOB
00983 && 0 == (prtype & DATA_BINARY_TYPE)
00984 && dtype_get_charset_coll(prtype)
00985 != DATA_MYSQL_LATIN1_SWEDISH_CHARSET_COLL)) {
00986
00987 ret = cmp_whole_field(mtype, prtype,
00988 rec1_b_ptr,
00989 (unsigned) rec1_f_len,
00990 rec2_b_ptr,
00991 (unsigned) rec2_f_len);
00992 if (ret != 0) {
00993 cur_bytes = 0;
00994
00995 goto order_resolved;
00996 } else {
00997 goto next_field;
00998 }
00999 }
01000
01001
01002 rec1_b_ptr = rec1_b_ptr + cur_bytes;
01003 rec2_b_ptr = rec2_b_ptr + cur_bytes;
01004
01005
01006 for (;;) {
01007 if (rec2_f_len <= cur_bytes) {
01008
01009 if (rec1_f_len <= cur_bytes) {
01010
01011 goto next_field;
01012 }
01013
01014 rec2_byte = dtype_get_pad_char(mtype, prtype);
01015
01016 if (rec2_byte == ULINT_UNDEFINED) {
01017 ret = 1;
01018
01019 goto order_resolved;
01020 }
01021 } else {
01022 rec2_byte = *rec2_b_ptr;
01023 }
01024
01025 if (rec1_f_len <= cur_bytes) {
01026 rec1_byte = dtype_get_pad_char(mtype, prtype);
01027
01028 if (rec1_byte == ULINT_UNDEFINED) {
01029 ret = -1;
01030
01031 goto order_resolved;
01032 }
01033 } else {
01034 rec1_byte = *rec1_b_ptr;
01035 }
01036
01037 if (rec1_byte == rec2_byte) {
01038
01039
01040
01041
01042 goto next_byte;
01043 }
01044
01045 if (mtype <= DATA_CHAR
01046 || (mtype == DATA_BLOB
01047 && !(prtype & DATA_BINARY_TYPE))) {
01048
01049 rec1_byte = cmp_collate(rec1_byte);
01050 rec2_byte = cmp_collate(rec2_byte);
01051 }
01052
01053 if (rec1_byte < rec2_byte) {
01054 ret = -1;
01055 goto order_resolved;
01056 } else if (rec1_byte > rec2_byte) {
01057 ret = 1;
01058 goto order_resolved;
01059 }
01060 next_byte:
01061
01062
01063 cur_bytes++;
01064 rec1_b_ptr++;
01065 rec2_b_ptr++;
01066 }
01067
01068 next_field:
01069 cur_field++;
01070 cur_bytes = 0;
01071 }
01072
01073 ut_ad(cur_bytes == 0);
01074
01075
01076
01077 ut_ad(ret == 0);
01078 order_resolved:
01079
01080 ut_ad((ret >= - 1) && (ret <= 1));
01081
01082 *matched_fields = cur_field;
01083 *matched_bytes = cur_bytes;
01084
01085 return(ret);
01086 }
01087
01088 #ifdef UNIV_DEBUG
01089
01097 static
01098 int
01099 cmp_debug_dtuple_rec_with_match(
01100
01101 const dtuple_t* dtuple,
01102 const rec_t* rec,
01106 const ulint* offsets,
01107 ulint* matched_fields)
01111 {
01112 const dfield_t* dtuple_field;
01113 ulint dtuple_f_len;
01114
01115 const byte* dtuple_f_data;
01116
01117 ulint rec_f_len;
01118 const byte* rec_f_data;
01119 int ret = 3333;
01120 ulint cur_field;
01121
01122 ut_ad(dtuple && rec && matched_fields);
01123 ut_ad(dtuple_check_typed(dtuple));
01124 ut_ad(rec_offs_validate(rec, NULL, offsets));
01125
01126 ut_ad(*matched_fields <= dtuple_get_n_fields_cmp(dtuple));
01127 ut_ad(*matched_fields <= rec_offs_n_fields(offsets));
01128
01129 cur_field = *matched_fields;
01130
01131 if (cur_field == 0) {
01132 if (UNIV_UNLIKELY
01133 (rec_get_info_bits(rec, rec_offs_comp(offsets))
01134 & REC_INFO_MIN_REC_FLAG)) {
01135
01136 ret = !(dtuple_get_info_bits(dtuple)
01137 & REC_INFO_MIN_REC_FLAG);
01138
01139 goto order_resolved;
01140 }
01141
01142 if (UNIV_UNLIKELY
01143 (dtuple_get_info_bits(dtuple) & REC_INFO_MIN_REC_FLAG)) {
01144 ret = -1;
01145
01146 goto order_resolved;
01147 }
01148 }
01149
01150
01151
01152 while (cur_field < dtuple_get_n_fields_cmp(dtuple)) {
01153
01154 ulint mtype;
01155 ulint prtype;
01156
01157 dtuple_field = dtuple_get_nth_field(dtuple, cur_field);
01158 {
01159 const dtype_t* type
01160 = dfield_get_type(dtuple_field);
01161
01162 mtype = type->mtype;
01163 prtype = type->prtype;
01164 }
01165
01166 dtuple_f_data = dfield_get_data(dtuple_field);
01167 dtuple_f_len = dfield_get_len(dtuple_field);
01168
01169 rec_f_data = rec_get_nth_field(rec, offsets,
01170 cur_field, &rec_f_len);
01171
01172 if (rec_offs_nth_extern(offsets, cur_field)) {
01173
01174
01175 ret = 0;
01176
01177 goto order_resolved;
01178 }
01179
01180 ret = cmp_data_data(mtype, prtype, dtuple_f_data, dtuple_f_len,
01181 rec_f_data, rec_f_len);
01182 if (ret != 0) {
01183 goto order_resolved;
01184 }
01185
01186 cur_field++;
01187 }
01188
01189 ret = 0;
01190
01191 order_resolved:
01192 ut_ad((ret >= - 1) && (ret <= 1));
01193
01194 *matched_fields = cur_field;
01195
01196 return(ret);
01197 }
01198 #endif