MySQL 5.6.14 Source Code Document
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
rem0cmp.cc
Go to the documentation of this file.
1 /*****************************************************************************
2 
3 Copyright (c) 1994, 2012, Oracle and/or its affiliates. All Rights Reserved.
4 
5 This program is free software; you can redistribute it and/or modify it under
6 the terms of the GNU General Public License as published by the Free Software
7 Foundation; version 2 of the License.
8 
9 This program is distributed in the hope that it will be useful, but WITHOUT
10 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
11 FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
12 
13 You should have received a copy of the GNU General Public License along with
14 this program; if not, write to the Free Software Foundation, Inc.,
15 51 Franklin Street, Suite 500, Boston, MA 02110-1335 USA
16 
17 *****************************************************************************/
18 
19 /*******************************************************************/
26 #include "rem0cmp.h"
27 
28 #ifdef UNIV_NONINL
29 #include "rem0cmp.ic"
30 #endif
31 
32 #include "ha_prototypes.h"
33 #include "handler0alter.h"
34 #include "srv0srv.h"
35 
36 /* ALPHABETICAL ORDER
37  ==================
38 
39 The records are put into alphabetical order in the following
40 way: let F be the first field where two records disagree.
41 If there is a character in some position n where the
42 records disagree, the order is determined by comparison of
43 the characters at position n, possibly after
44 collating transformation. If there is no such character,
45 but the corresponding fields have different lengths, then
46 if the data type of the fields is paddable,
47 shorter field is padded with a padding character. If the
48 data type is not paddable, longer field is considered greater.
49 Finally, the SQL null is bigger than any other value.
50 
51 At the present, the comparison functions return 0 in the case,
52 where two records disagree only in the way that one
53 has more fields than the other. */
54 
55 #ifdef UNIV_DEBUG
56 /*************************************************************/
63 static
64 int
65 cmp_debug_dtuple_rec_with_match(
66 /*============================*/
67  const dtuple_t* dtuple,
68  const rec_t* rec,
72  const ulint* offsets,
73  ulint n_cmp,
74  ulint* matched_fields)
78  __attribute__((nonnull, warn_unused_result));
79 #endif /* UNIV_DEBUG */
80 /*************************************************************/
85 extern
86 int
88 /*===============*/
89  int mysql_type,
90  uint charset_number,
91  const unsigned char* a,
92  unsigned int a_length,
94  const unsigned char* b,
95  unsigned int b_length);
97 /*************************************************************/
102 extern
103 int
105 /*======================*/
106  int mysql_type,
107  uint charset_number,
108  const unsigned char* a,
109  unsigned int a_length,
111  const unsigned char* b,
112  unsigned int b_length);
114 /*********************************************************************/
119 UNIV_INLINE
120 ulint
122 /*========*/
123  ulint code)
124 {
125  return((ulint) srv_latin1_ordering[code]);
126 }
127 
128 /*************************************************************/
131 UNIV_INTERN
132 ibool
134 /*===============*/
135  const dict_col_t* col1,
136  const dict_col_t* col2,
137  ibool check_charsets)
139 {
141  && dtype_is_non_binary_string_type(col2->mtype, col2->prtype)) {
142 
143  /* Both are non-binary string types: they can be compared if
144  and only if the charset-collation is the same */
145 
146  if (check_charsets) {
147  return(dtype_get_charset_coll(col1->prtype)
148  == dtype_get_charset_coll(col2->prtype));
149  } else {
150  return(TRUE);
151  }
152  }
153 
154  if (dtype_is_binary_string_type(col1->mtype, col1->prtype)
155  && dtype_is_binary_string_type(col2->mtype, col2->prtype)) {
156 
157  /* Both are binary string types: they can be compared */
158 
159  return(TRUE);
160  }
161 
162  if (col1->mtype != col2->mtype) {
163 
164  return(FALSE);
165  }
166 
167  if (col1->mtype == DATA_INT
168  && (col1->prtype & DATA_UNSIGNED)
169  != (col2->prtype & DATA_UNSIGNED)) {
170 
171  /* The storage format of an unsigned integer is different
172  from a signed integer: in a signed integer we OR
173  0x8000... to the value of positive integers. */
174 
175  return(FALSE);
176  }
177 
178  return(col1->mtype != DATA_INT || col1->len == col2->len);
179 }
180 
181 /*************************************************************/
185 static
186 int
187 cmp_whole_field(
188 /*============*/
189  ulint mtype,
190  ulint prtype,
191  const byte* a,
192  unsigned int a_length,
194  const byte* b,
195  unsigned int b_length)
197 {
198  float f_1;
199  float f_2;
200  double d_1;
201  double d_2;
202  int swap_flag = 1;
203 
204  switch (mtype) {
205 
206  case DATA_DECIMAL:
207  /* Remove preceding spaces */
208  for (; a_length && *a == ' '; a++, a_length--) { }
209  for (; b_length && *b == ' '; b++, b_length--) { }
210 
211  if (*a == '-') {
212  if (*b != '-') {
213  return(-1);
214  }
215 
216  a++; b++;
217  a_length--;
218  b_length--;
219 
220  swap_flag = -1;
221 
222  } else if (*b == '-') {
223 
224  return(1);
225  }
226 
227  while (a_length > 0 && (*a == '+' || *a == '0')) {
228  a++; a_length--;
229  }
230 
231  while (b_length > 0 && (*b == '+' || *b == '0')) {
232  b++; b_length--;
233  }
234 
235  if (a_length != b_length) {
236  if (a_length < b_length) {
237  return(-swap_flag);
238  }
239 
240  return(swap_flag);
241  }
242 
243  while (a_length > 0 && *a == *b) {
244 
245  a++; b++; a_length--;
246  }
247 
248  if (a_length == 0) {
249 
250  return(0);
251  }
252 
253  if (*a > *b) {
254  return(swap_flag);
255  }
256 
257  return(-swap_flag);
258  case DATA_DOUBLE:
259  d_1 = mach_double_read(a);
260  d_2 = mach_double_read(b);
261 
262  if (d_1 > d_2) {
263  return(1);
264  } else if (d_2 > d_1) {
265  return(-1);
266  }
267 
268  return(0);
269 
270  case DATA_FLOAT:
271  f_1 = mach_float_read(a);
272  f_2 = mach_float_read(b);
273 
274  if (f_1 > f_2) {
275  return(1);
276  } else if (f_2 > f_1) {
277  return(-1);
278  }
279 
280  return(0);
281  case DATA_BLOB:
282  if (prtype & DATA_BINARY_TYPE) {
283 
284  ut_print_timestamp(stderr);
285  fprintf(stderr,
286  " InnoDB: Error: comparing a binary BLOB"
287  " with a character set sensitive\n"
288  "InnoDB: comparison!\n");
289  }
290  /* fall through */
291  case DATA_VARMYSQL:
292  case DATA_MYSQL:
293  return(innobase_mysql_cmp(
294  (int)(prtype & DATA_MYSQL_TYPE_MASK),
295  (uint) dtype_get_charset_coll(prtype),
296  a, a_length, b, b_length));
297  default:
298  fprintf(stderr,
299  "InnoDB: unknown type number %lu\n",
300  (ulong) mtype);
301  ut_error;
302  }
303 
304  return(0);
305 }
306 
307 /*****************************************************************
308 This function is used to compare two dfields where at least the first
309 has its data type field set. */
310 UNIV_INTERN
311 int
312 cmp_dfield_dfield_like_prefix(
313 /*==========================*/
314  /* out: 1, 0, -1, if dfield1 is greater, equal,
315  less than dfield2, respectively */
316  dfield_t* dfield1,/* in: data field; must have type field set */
317  dfield_t* dfield2)/* in: data field */
318 {
319  const dtype_t* type;
320  ulint ret;
321 
322  ut_ad(dfield_check_typed(dfield1));
323 
324  type = dfield_get_type(dfield1);
325 
326  if (type->mtype >= DATA_FLOAT) {
328  (int)(type->prtype & DATA_MYSQL_TYPE_MASK),
329  (uint) dtype_get_charset_coll(type->prtype),
330  static_cast<byte*>(dfield_get_data(dfield1)),
331  dfield_get_len(dfield1),
332  static_cast<byte*>(dfield_get_data(dfield2)),
333  dfield_get_len(dfield2));
334  } else {
335  ret = (cmp_data_data_like_prefix(
336  static_cast<byte*>(dfield_get_data(dfield1)),
337  dfield_get_len(dfield1),
338  static_cast<byte*>(dfield_get_data(dfield2)),
339  dfield_get_len(dfield2)));
340  }
341 
342  return(ret);
343 }
344 
345 /*************************************************************/
349 UNIV_INTERN
350 int
352 /*===============*/
353  ulint mtype,
354  ulint prtype,
355  const byte* data1,
357  ulint len1,
358  const byte* data2,
360  ulint len2)
361 {
362  ulint data1_byte;
363  ulint data2_byte;
364  ulint cur_bytes;
365 
366  if (len1 == UNIV_SQL_NULL || len2 == UNIV_SQL_NULL) {
367 
368  if (len1 == len2) {
369 
370  return(0);
371  }
372 
373  if (len1 == UNIV_SQL_NULL) {
374  /* We define the SQL null to be the smallest possible
375  value of a field in the alphabetical order */
376 
377  return(-1);
378  }
379 
380  return(1);
381  }
382 
383  if (mtype >= DATA_FLOAT
384  || (mtype == DATA_BLOB
385  && 0 == (prtype & DATA_BINARY_TYPE)
386  && dtype_get_charset_coll(prtype)
387  != DATA_MYSQL_LATIN1_SWEDISH_CHARSET_COLL)) {
388 
389  return(cmp_whole_field(mtype, prtype,
390  data1, (unsigned) len1,
391  data2, (unsigned) len2));
392  }
393 
394  /* Compare then the fields */
395 
396  cur_bytes = 0;
397 
398  for (;;) {
399  if (len1 <= cur_bytes) {
400  if (len2 <= cur_bytes) {
401 
402  return(0);
403  }
404 
405  data1_byte = dtype_get_pad_char(mtype, prtype);
406 
407  if (data1_byte == ULINT_UNDEFINED) {
408 
409  return(-1);
410  }
411  } else {
412  data1_byte = *data1;
413  }
414 
415  if (len2 <= cur_bytes) {
416  data2_byte = dtype_get_pad_char(mtype, prtype);
417 
418  if (data2_byte == ULINT_UNDEFINED) {
419 
420  return(1);
421  }
422  } else {
423  data2_byte = *data2;
424  }
425 
426  if (data1_byte == data2_byte) {
427  /* If the bytes are equal, they will remain such even
428  after the collation transformation below */
429 
430  goto next_byte;
431  }
432 
433  if (mtype <= DATA_CHAR
434  || (mtype == DATA_BLOB
435  && 0 == (prtype & DATA_BINARY_TYPE))) {
436 
437  data1_byte = cmp_collate(data1_byte);
438  data2_byte = cmp_collate(data2_byte);
439  }
440 
441  if (data1_byte > data2_byte) {
442 
443  return(1);
444  } else if (data1_byte < data2_byte) {
445 
446  return(-1);
447  }
448 next_byte:
449  /* Next byte */
450  cur_bytes++;
451  data1++;
452  data2++;
453  }
454 
455  return(0); /* Not reached */
456 }
457 
458 /*****************************************************************
459 This function is used to compare two data fields for which we know the
460 data type to be VARCHAR */
461 
462 int
463 cmp_data_data_slow_varchar(
464 /*=======================*/
465  /* out: 1, 0, -1, if lhs is greater, equal,
466  less than rhs, respectively */
467  const byte* lhs, /* in: data field (== a pointer to a memory
468  buffer) */
469  ulint lhs_len,/* in: data field length or UNIV_SQL_NULL */
470  const byte* rhs, /* in: data field (== a pointer to a memory
471  buffer) */
472  ulint rhs_len)/* in: data field length or UNIV_SQL_NULL */
473 {
474  ulint i;
475 
476  ut_a(rhs_len != UNIV_SQL_NULL);
477 
478  if (lhs_len == UNIV_SQL_NULL) {
479 
480  /* We define the SQL null to be the smallest possible
481  value of a field in the alphabetical order */
482 
483  return(-1);
484  }
485 
486  /* Compare the values.*/
487 
488  for (i = 0; i < lhs_len && i < rhs_len; ++i, ++rhs, ++lhs) {
489  ulint lhs_byte = *lhs;
490  ulint rhs_byte = *rhs;
491 
492  if (lhs_byte != rhs_byte) {
493  /* If the bytes are equal, they will remain such even
494  after the collation transformation below */
495 
496  lhs_byte = cmp_collate(lhs_byte);
497  rhs_byte = cmp_collate(rhs_byte);
498 
499  if (lhs_byte > rhs_byte) {
500 
501  return(1);
502  } else if (lhs_byte < rhs_byte) {
503 
504  return(-1);
505  }
506  }
507  }
508 
509  return(i == lhs_len && i == rhs_len) ? 0 : rhs_len - lhs_len;
510 }
511 
512 /*****************************************************************
513 This function is used to compare two data fields for which we know the
514 data type. The comparison is done for the LIKE operator.*/
515 
516 int
517 cmp_data_data_slow_like_prefix(
518 /*===========================*/
519  /* out: 1, 0, -1, if lhs is greater, equal,
520  less than rhs, respectively */
521  const byte* lhs, /* in: data field (== a pointer to a memory
522  buffer) */
523  ulint len1, /* in: data field length or UNIV_SQL_NULL */
524  const byte* rhs, /* in: data field (== a pointer to a memory
525  buffer) */
526  ulint len2) /* in: data field length or UNIV_SQL_NULL */
527 {
528  ulint i;
529 
530  ut_a(len2 != UNIV_SQL_NULL);
531 
532  if (len1 == UNIV_SQL_NULL) {
533 
534  /* We define the SQL null to be the smallest possible
535  value of a field in the alphabetical order */
536 
537  return(-1);
538  }
539 
540  /* Compare the values.*/
541 
542  for (i = 0; i < len1 && i < len2; ++i, ++rhs, ++lhs) {
543  ulint lhs_byte = *lhs;
544  ulint rhs_byte = *rhs;
545 
546  if (lhs_byte != rhs_byte) {
547  /* If the bytes are equal, they will remain such even
548  after the collation transformation below */
549 
550  lhs_byte = cmp_collate(lhs_byte);
551  rhs_byte = cmp_collate(rhs_byte);
552 
553  if (lhs_byte > rhs_byte) {
554 
555  return(1);
556  } else if (lhs_byte < rhs_byte) {
557 
558  return(-1);
559  }
560  }
561  }
562 
563  return(i == len2 ? 0 : 1);
564 }
565 
566 /*****************************************************************
567 This function is used to compare two data fields for which we know the
568 data type. The comparison is done for the LIKE operator.*/
569 
570 int
571 cmp_data_data_slow_like_suffix(
572 /*===========================*/
573  /* out: 1, 0, -1, if data1 is greater, equal,
574  less than data2, respectively */
575  /* in: data field (== a pointer to a
576  memory buffer) */
577  const byte* data1 UNIV_UNUSED,
578  /* in: data field length or UNIV_SQL_NULL */
579  ulint len1 UNIV_UNUSED,
580  /* in: data field (== a pointer to a memory
581  buffer) */
582  const byte* data2 UNIV_UNUSED,
583  /* in: data field length or UNIV_SQL_NULL */
584  ulint len2 UNIV_UNUSED)
585 
586 {
587  ut_error; // FIXME:
588  return(1);
589 }
590 
591 /*****************************************************************
592 This function is used to compare two data fields for which we know the
593 data type. The comparison is done for the LIKE operator.*/
594 
595 int
596 cmp_data_data_slow_like_substr(
597 /*===========================*/
598  /* out: 1, 0, -1, if data1 is greater, equal,
599  less than data2, respectively */
600  /* in: data field (== a pointer to a
601  memory buffer) */
602  const byte* data1 UNIV_UNUSED,
603  /* in: data field length or UNIV_SQL_NULL */
604  ulint len1 UNIV_UNUSED,
605  /* in: data field (== a pointer to a memory
606  buffer) */
607  const byte* data2 UNIV_UNUSED,
608  /* in: data field length or UNIV_SQL_NULL */
609  ulint len2 UNIV_UNUSED)
610 {
611  ut_error; // FIXME:
612  return(1);
613 }
614 /*************************************************************/
625 UNIV_INTERN
626 int
628 /*==========================*/
629  const dtuple_t* dtuple,
630  const rec_t* rec,
634  const ulint* offsets,
635  ulint n_cmp,
636  ulint* matched_fields,
639  ulint* matched_bytes)
643 {
644  const dfield_t* dtuple_field; /* current field in logical record */
645  ulint dtuple_f_len; /* the length of the current field
646  in the logical record */
647  const byte* dtuple_b_ptr; /* pointer to the current byte in
648  logical field data */
649  ulint dtuple_byte; /* value of current byte to be compared
650  in dtuple*/
651  ulint rec_f_len; /* length of current field in rec */
652  const byte* rec_b_ptr; /* pointer to the current byte in
653  rec field */
654  ulint rec_byte; /* value of current byte to be
655  compared in rec */
656  ulint cur_field; /* current field number */
657  ulint cur_bytes; /* number of already matched bytes
658  in current field */
659  int ret; /* return value */
660 
661  ut_ad(dtuple && rec && matched_fields && matched_bytes);
662  ut_ad(dtuple_check_typed(dtuple));
663  ut_ad(rec_offs_validate(rec, NULL, offsets));
664 
665  cur_field = *matched_fields;
666  cur_bytes = *matched_bytes;
667 
668  ut_ad(n_cmp > 0);
669  ut_ad(n_cmp <= dtuple_get_n_fields(dtuple));
670  ut_ad(cur_field <= n_cmp);
671  ut_ad(cur_field <= rec_offs_n_fields(offsets));
672 
673  if (cur_bytes == 0 && cur_field == 0) {
674  ulint rec_info = rec_get_info_bits(rec,
675  rec_offs_comp(offsets));
676  ulint tup_info = dtuple_get_info_bits(dtuple);
677 
678  if (UNIV_UNLIKELY(rec_info & REC_INFO_MIN_REC_FLAG)) {
679  ret = !(tup_info & REC_INFO_MIN_REC_FLAG);
680  goto order_resolved;
681  } else if (UNIV_UNLIKELY(tup_info & REC_INFO_MIN_REC_FLAG)) {
682  ret = -1;
683  goto order_resolved;
684  }
685  }
686 
687  /* Match fields in a loop; stop if we run out of fields in dtuple
688  or find an externally stored field */
689 
690  while (cur_field < n_cmp) {
691 
692  ulint mtype;
693  ulint prtype;
694 
695  dtuple_field = dtuple_get_nth_field(dtuple, cur_field);
696  {
697  const dtype_t* type
698  = dfield_get_type(dtuple_field);
699 
700  mtype = type->mtype;
701  prtype = type->prtype;
702  }
703 
704  dtuple_f_len = dfield_get_len(dtuple_field);
705 
706  rec_b_ptr = rec_get_nth_field(rec, offsets,
707  cur_field, &rec_f_len);
708 
709  /* If we have matched yet 0 bytes, it may be that one or
710  both the fields are SQL null, or the record or dtuple may be
711  the predefined minimum record, or the field is externally
712  stored */
713 
714  if (UNIV_LIKELY(cur_bytes == 0)) {
715  if (rec_offs_nth_extern(offsets, cur_field)) {
716  /* We do not compare to an externally
717  stored field */
718 
719  ret = 0;
720 
721  goto order_resolved;
722  }
723 
724  if (dtuple_f_len == UNIV_SQL_NULL) {
725  if (rec_f_len == UNIV_SQL_NULL) {
726 
727  goto next_field;
728  }
729 
730  ret = -1;
731  goto order_resolved;
732  } else if (rec_f_len == UNIV_SQL_NULL) {
733  /* We define the SQL null to be the
734  smallest possible value of a field
735  in the alphabetical order */
736 
737  ret = 1;
738  goto order_resolved;
739  }
740  }
741 
742  if (mtype >= DATA_FLOAT
743  || (mtype == DATA_BLOB
744  && 0 == (prtype & DATA_BINARY_TYPE)
745  && dtype_get_charset_coll(prtype)
746  != DATA_MYSQL_LATIN1_SWEDISH_CHARSET_COLL)) {
747 
748  ret = cmp_whole_field(
749  mtype, prtype,
750  static_cast<const byte*>(
751  dfield_get_data(dtuple_field)),
752  (unsigned) dtuple_f_len,
753  rec_b_ptr, (unsigned) rec_f_len);
754 
755  if (ret != 0) {
756  cur_bytes = 0;
757 
758  goto order_resolved;
759  } else {
760  goto next_field;
761  }
762  }
763 
764  /* Set the pointers at the current byte */
765 
766  rec_b_ptr = rec_b_ptr + cur_bytes;
767  dtuple_b_ptr = (byte*) dfield_get_data(dtuple_field)
768  + cur_bytes;
769  /* Compare then the fields */
770 
771  for (;;) {
772  if (UNIV_UNLIKELY(rec_f_len <= cur_bytes)) {
773  if (dtuple_f_len <= cur_bytes) {
774 
775  goto next_field;
776  }
777 
778  rec_byte = dtype_get_pad_char(mtype, prtype);
779 
780  if (rec_byte == ULINT_UNDEFINED) {
781  ret = 1;
782 
783  goto order_resolved;
784  }
785  } else {
786  rec_byte = *rec_b_ptr;
787  }
788 
789  if (UNIV_UNLIKELY(dtuple_f_len <= cur_bytes)) {
790  dtuple_byte = dtype_get_pad_char(mtype,
791  prtype);
792 
793  if (dtuple_byte == ULINT_UNDEFINED) {
794  ret = -1;
795 
796  goto order_resolved;
797  }
798  } else {
799  dtuple_byte = *dtuple_b_ptr;
800  }
801 
802  if (dtuple_byte == rec_byte) {
803  /* If the bytes are equal, they will
804  remain such even after the collation
805  transformation below */
806 
807  goto next_byte;
808  }
809 
810  if (mtype <= DATA_CHAR
811  || (mtype == DATA_BLOB
812  && !(prtype & DATA_BINARY_TYPE))) {
813 
814  rec_byte = cmp_collate(rec_byte);
815  dtuple_byte = cmp_collate(dtuple_byte);
816  }
817 
818  ret = (int) (dtuple_byte - rec_byte);
819  if (UNIV_LIKELY(ret)) {
820  if (ret < 0) {
821  ret = -1;
822  goto order_resolved;
823  } else {
824  ret = 1;
825  goto order_resolved;
826  }
827  }
828 next_byte:
829  /* Next byte */
830  cur_bytes++;
831  rec_b_ptr++;
832  dtuple_b_ptr++;
833  }
834 
835 next_field:
836  cur_field++;
837  cur_bytes = 0;
838  }
839 
840  ut_ad(cur_bytes == 0);
841 
842  ret = 0; /* If we ran out of fields, dtuple was equal to rec
843  up to the common fields */
844 order_resolved:
845  ut_ad((ret >= - 1) && (ret <= 1));
846  ut_ad(ret == cmp_debug_dtuple_rec_with_match(dtuple, rec, offsets,
847  n_cmp, matched_fields));
848  ut_ad(*matched_fields == cur_field); /* In the debug version, the
849  above cmp_debug_... sets
850  *matched_fields to a value */
851  *matched_fields = cur_field;
852  *matched_bytes = cur_bytes;
853 
854  return(ret);
855 }
856 
857 /**************************************************************/
861 UNIV_INTERN
862 int
864 /*===========*/
865  const dtuple_t* dtuple,
866  const rec_t* rec,
867  const ulint* offsets)
868 {
869  ulint matched_fields = 0;
870  ulint matched_bytes = 0;
871 
872  ut_ad(rec_offs_validate(rec, NULL, offsets));
873  return(cmp_dtuple_rec_with_match(dtuple, rec, offsets,
874  &matched_fields, &matched_bytes));
875 }
876 
877 /**************************************************************/
881 UNIV_INTERN
882 ibool
884 /*========================*/
885  const dtuple_t* dtuple,
886  const rec_t* rec,
887  const ulint* offsets)
888 {
889  ulint n_fields;
890  ulint matched_fields = 0;
891  ulint matched_bytes = 0;
892 
893  ut_ad(rec_offs_validate(rec, NULL, offsets));
894  n_fields = dtuple_get_n_fields(dtuple);
895 
896  if (n_fields > rec_offs_n_fields(offsets)) {
897 
898  return(FALSE);
899  }
900 
901  cmp_dtuple_rec_with_match(dtuple, rec, offsets,
902  &matched_fields, &matched_bytes);
903  if (matched_fields == n_fields) {
904 
905  return(TRUE);
906  }
907 
908  if (matched_fields == n_fields - 1
909  && matched_bytes == dfield_get_len(
910  dtuple_get_nth_field(dtuple, n_fields - 1))) {
911  return(TRUE);
912  }
913 
914  return(FALSE);
915 }
916 
917 /*************************************************************/
922 static __attribute__((nonnull, warn_unused_result))
923 int
924 cmp_rec_rec_simple_field(
925 /*=====================*/
926  const rec_t* rec1,
927  const rec_t* rec2,
928  const ulint* offsets1,
929  const ulint* offsets2,
930  const dict_index_t* index,
931  ulint n)
932 {
933  const byte* rec1_b_ptr;
934  const byte* rec2_b_ptr;
935  ulint rec1_f_len;
936  ulint rec2_f_len;
937  const dict_col_t* col = dict_index_get_nth_col(index, n);
938 
939  ut_ad(!rec_offs_nth_extern(offsets1, n));
940  ut_ad(!rec_offs_nth_extern(offsets2, n));
941 
942  rec1_b_ptr = rec_get_nth_field(rec1, offsets1, n, &rec1_f_len);
943  rec2_b_ptr = rec_get_nth_field(rec2, offsets2, n, &rec2_f_len);
944 
945  if (rec1_f_len == UNIV_SQL_NULL || rec2_f_len == UNIV_SQL_NULL) {
946  if (rec1_f_len == rec2_f_len) {
947  return(0);
948  }
949  /* We define the SQL null to be the smallest possible
950  value of a field in the alphabetical order */
951  return(rec1_f_len == UNIV_SQL_NULL ? -1 : 1);
952  }
953 
954  if (col->mtype >= DATA_FLOAT
955  || (col->mtype == DATA_BLOB
956  && !(col->prtype & DATA_BINARY_TYPE)
958  != DATA_MYSQL_LATIN1_SWEDISH_CHARSET_COLL)) {
959  return(cmp_whole_field(col->mtype, col->prtype,
960  rec1_b_ptr, (unsigned) rec1_f_len,
961  rec2_b_ptr, (unsigned) rec2_f_len));
962  }
963 
964  /* Compare the fields */
965  for (ulint cur_bytes = 0;; cur_bytes++, rec1_b_ptr++, rec2_b_ptr++) {
966  ulint rec1_byte;
967  ulint rec2_byte;
968 
969  if (rec2_f_len <= cur_bytes) {
970  if (rec1_f_len <= cur_bytes) {
971  return(0);
972  }
973 
974  rec2_byte = dtype_get_pad_char(
975  col->mtype, col->prtype);
976 
977  if (rec2_byte == ULINT_UNDEFINED) {
978  return(1);
979  }
980  } else {
981  rec2_byte = *rec2_b_ptr;
982  }
983 
984  if (rec1_f_len <= cur_bytes) {
985  rec1_byte = dtype_get_pad_char(
986  col->mtype, col->prtype);
987 
988  if (rec1_byte == ULINT_UNDEFINED) {
989  return(-1);
990  }
991  } else {
992  rec1_byte = *rec1_b_ptr;
993  }
994 
995  if (rec1_byte == rec2_byte) {
996  /* If the bytes are equal, they will remain such
997  even after the collation transformation below */
998  continue;
999  }
1000 
1001  if (col->mtype <= DATA_CHAR
1002  || (col->mtype == DATA_BLOB
1003  && !(col->prtype & DATA_BINARY_TYPE))) {
1004 
1005  rec1_byte = cmp_collate(rec1_byte);
1006  rec2_byte = cmp_collate(rec2_byte);
1007  }
1008 
1009  if (rec1_byte < rec2_byte) {
1010  return(-1);
1011  } else if (rec1_byte > rec2_byte) {
1012  return(1);
1013  }
1014  }
1015 }
1016 
1017 /*************************************************************/
1023 UNIV_INTERN
1024 int
1026 /*===============*/
1027  const rec_t* rec1,
1028  const rec_t* rec2,
1029  const ulint* offsets1,
1030  const ulint* offsets2,
1031  const dict_index_t* index,
1032  struct TABLE* table)
1035 {
1036  ulint n;
1037  ulint n_uniq = dict_index_get_n_unique(index);
1038  bool null_eq = false;
1039 
1040  ut_ad(rec_offs_n_fields(offsets1) >= n_uniq);
1041  ut_ad(rec_offs_n_fields(offsets2) == rec_offs_n_fields(offsets2));
1042 
1043  ut_ad(rec_offs_comp(offsets1) == rec_offs_comp(offsets2));
1044 
1045  for (n = 0; n < n_uniq; n++) {
1046  int cmp = cmp_rec_rec_simple_field(
1047  rec1, rec2, offsets1, offsets2, index, n);
1048 
1049  if (cmp) {
1050  return(cmp);
1051  }
1052 
1053  /* If the fields are internally equal, they must both
1054  be NULL or non-NULL. */
1055  ut_ad(rec_offs_nth_sql_null(offsets1, n)
1056  == rec_offs_nth_sql_null(offsets2, n));
1057 
1058  if (rec_offs_nth_sql_null(offsets1, n)) {
1059  ut_ad(!(dict_index_get_nth_col(index, n)->prtype
1060  & DATA_NOT_NULL));
1061  null_eq = true;
1062  }
1063  }
1064 
1065  /* If we ran out of fields, the ordering columns of rec1 were
1066  equal to rec2. Issue a duplicate key error if needed. */
1067 
1068  if (!null_eq && table && dict_index_is_unique(index)) {
1069  /* Report erroneous row using new version of table. */
1070  innobase_rec_to_mysql(table, rec1, index, offsets1);
1071  return(0);
1072  }
1073 
1074  /* Else, keep comparing so that we have the full internal
1075  order. */
1076  for (; n < dict_index_get_n_fields(index); n++) {
1077  int cmp = cmp_rec_rec_simple_field(
1078  rec1, rec2, offsets1, offsets2, index, n);
1079 
1080  if (cmp) {
1081  return(cmp);
1082  }
1083 
1084  /* If the fields are internally equal, they must both
1085  be NULL or non-NULL. */
1086  ut_ad(rec_offs_nth_sql_null(offsets1, n)
1087  == rec_offs_nth_sql_null(offsets2, n));
1088  }
1089 
1090  /* This should never be reached. Internally, an index must
1091  never contain duplicate entries. */
1092  ut_ad(0);
1093  return(0);
1094 }
1095 
1096 /*************************************************************/
1101 UNIV_INTERN
1102 int
1104 /*===================*/
1105  const rec_t* rec1,
1106  const rec_t* rec2,
1107  const ulint* offsets1,
1108  const ulint* offsets2,
1109  dict_index_t* index,
1110  ibool nulls_unequal,
1111  /* in: TRUE if this is for index statistics
1112  cardinality estimation, and innodb_stats_method
1113  is "nulls_unequal" or "nulls_ignored" */
1114  ulint* matched_fields,
1118  ulint* matched_bytes)
1122 {
1123  ulint rec1_n_fields; /* the number of fields in rec */
1124  ulint rec1_f_len; /* length of current field in rec */
1125  const byte* rec1_b_ptr; /* pointer to the current byte
1126  in rec field */
1127  ulint rec1_byte; /* value of current byte to be
1128  compared in rec */
1129  ulint rec2_n_fields; /* the number of fields in rec */
1130  ulint rec2_f_len; /* length of current field in rec */
1131  const byte* rec2_b_ptr; /* pointer to the current byte
1132  in rec field */
1133  ulint rec2_byte; /* value of current byte to be
1134  compared in rec */
1135  ulint cur_field; /* current field number */
1136  ulint cur_bytes; /* number of already matched
1137  bytes in current field */
1138  int ret = 0; /* return value */
1139  ulint comp;
1140 
1141  ut_ad(rec1 && rec2 && index);
1142  ut_ad(rec_offs_validate(rec1, index, offsets1));
1143  ut_ad(rec_offs_validate(rec2, index, offsets2));
1144  ut_ad(rec_offs_comp(offsets1) == rec_offs_comp(offsets2));
1145 
1146  comp = rec_offs_comp(offsets1);
1147  rec1_n_fields = rec_offs_n_fields(offsets1);
1148  rec2_n_fields = rec_offs_n_fields(offsets2);
1149 
1150  cur_field = *matched_fields;
1151  cur_bytes = *matched_bytes;
1152 
1153  /* Match fields in a loop */
1154 
1155  while ((cur_field < rec1_n_fields) && (cur_field < rec2_n_fields)) {
1156 
1157  ulint mtype;
1158  ulint prtype;
1159 
1160  if (dict_index_is_univ(index)) {
1161  /* This is for the insert buffer B-tree. */
1162  mtype = DATA_BINARY;
1163  prtype = 0;
1164  } else {
1165  const dict_col_t* col
1166  = dict_index_get_nth_col(index, cur_field);
1167 
1168  mtype = col->mtype;
1169  prtype = col->prtype;
1170  }
1171 
1172  rec1_b_ptr = rec_get_nth_field(rec1, offsets1,
1173  cur_field, &rec1_f_len);
1174  rec2_b_ptr = rec_get_nth_field(rec2, offsets2,
1175  cur_field, &rec2_f_len);
1176 
1177  if (cur_bytes == 0) {
1178  if (cur_field == 0) {
1179  /* Test if rec is the predefined minimum
1180  record */
1181  if (UNIV_UNLIKELY(rec_get_info_bits(rec1, comp)
1182  & REC_INFO_MIN_REC_FLAG)) {
1183 
1184  if (!(rec_get_info_bits(rec2, comp)
1185  & REC_INFO_MIN_REC_FLAG)) {
1186  ret = -1;
1187  }
1188 
1189  goto order_resolved;
1190 
1191  } else if (UNIV_UNLIKELY
1192  (rec_get_info_bits(rec2, comp)
1193  & REC_INFO_MIN_REC_FLAG)) {
1194 
1195  ret = 1;
1196 
1197  goto order_resolved;
1198  }
1199  }
1200 
1201  if (rec_offs_nth_extern(offsets1, cur_field)
1202  || rec_offs_nth_extern(offsets2, cur_field)) {
1203  /* We do not compare to an externally
1204  stored field */
1205 
1206  goto order_resolved;
1207  }
1208 
1209  if (rec1_f_len == UNIV_SQL_NULL
1210  || rec2_f_len == UNIV_SQL_NULL) {
1211 
1212  if (rec1_f_len == rec2_f_len) {
1213  /* This is limited to stats collection,
1214  cannot use it for regular search */
1215  if (nulls_unequal) {
1216  ret = -1;
1217  } else {
1218  goto next_field;
1219  }
1220  } else if (rec2_f_len == UNIV_SQL_NULL) {
1221 
1222  /* We define the SQL null to be the
1223  smallest possible value of a field
1224  in the alphabetical order */
1225 
1226  ret = 1;
1227  } else {
1228  ret = -1;
1229  }
1230 
1231  goto order_resolved;
1232  }
1233  }
1234 
1235  if (mtype >= DATA_FLOAT
1236  || (mtype == DATA_BLOB
1237  && 0 == (prtype & DATA_BINARY_TYPE)
1238  && dtype_get_charset_coll(prtype)
1239  != DATA_MYSQL_LATIN1_SWEDISH_CHARSET_COLL)) {
1240 
1241  ret = cmp_whole_field(mtype, prtype,
1242  rec1_b_ptr,
1243  (unsigned) rec1_f_len,
1244  rec2_b_ptr,
1245  (unsigned) rec2_f_len);
1246  if (ret != 0) {
1247  cur_bytes = 0;
1248 
1249  goto order_resolved;
1250  } else {
1251  goto next_field;
1252  }
1253  }
1254 
1255  /* Set the pointers at the current byte */
1256  rec1_b_ptr = rec1_b_ptr + cur_bytes;
1257  rec2_b_ptr = rec2_b_ptr + cur_bytes;
1258 
1259  /* Compare then the fields */
1260  for (;;) {
1261  if (rec2_f_len <= cur_bytes) {
1262 
1263  if (rec1_f_len <= cur_bytes) {
1264 
1265  goto next_field;
1266  }
1267 
1268  rec2_byte = dtype_get_pad_char(mtype, prtype);
1269 
1270  if (rec2_byte == ULINT_UNDEFINED) {
1271  ret = 1;
1272 
1273  goto order_resolved;
1274  }
1275  } else {
1276  rec2_byte = *rec2_b_ptr;
1277  }
1278 
1279  if (rec1_f_len <= cur_bytes) {
1280  rec1_byte = dtype_get_pad_char(mtype, prtype);
1281 
1282  if (rec1_byte == ULINT_UNDEFINED) {
1283  ret = -1;
1284 
1285  goto order_resolved;
1286  }
1287  } else {
1288  rec1_byte = *rec1_b_ptr;
1289  }
1290 
1291  if (rec1_byte == rec2_byte) {
1292  /* If the bytes are equal, they will remain
1293  such even after the collation transformation
1294  below */
1295 
1296  goto next_byte;
1297  }
1298 
1299  if (mtype <= DATA_CHAR
1300  || (mtype == DATA_BLOB
1301  && !(prtype & DATA_BINARY_TYPE))) {
1302 
1303  rec1_byte = cmp_collate(rec1_byte);
1304  rec2_byte = cmp_collate(rec2_byte);
1305  }
1306 
1307  if (rec1_byte < rec2_byte) {
1308  ret = -1;
1309  goto order_resolved;
1310  } else if (rec1_byte > rec2_byte) {
1311  ret = 1;
1312  goto order_resolved;
1313  }
1314 next_byte:
1315  /* Next byte */
1316 
1317  cur_bytes++;
1318  rec1_b_ptr++;
1319  rec2_b_ptr++;
1320  }
1321 
1322 next_field:
1323  cur_field++;
1324  cur_bytes = 0;
1325  }
1326 
1327  ut_ad(cur_bytes == 0);
1328 
1329  /* If we ran out of fields, rec1 was equal to rec2 up
1330  to the common fields */
1331  ut_ad(ret == 0);
1332 order_resolved:
1333 
1334  ut_ad((ret >= - 1) && (ret <= 1));
1335 
1336  *matched_fields = cur_field;
1337  *matched_bytes = cur_bytes;
1338 
1339  return(ret);
1340 }
1341 
1342 #ifdef UNIV_DEBUG
1343 /*************************************************************/
1351 static
1352 int
1353 cmp_debug_dtuple_rec_with_match(
1354 /*============================*/
1355  const dtuple_t* dtuple,
1356  const rec_t* rec,
1360  const ulint* offsets,
1361  ulint n_cmp,
1362  ulint* matched_fields)
1366 {
1367  const dfield_t* dtuple_field; /* current field in logical record */
1368  ulint dtuple_f_len; /* the length of the current field
1369  in the logical record */
1370  const byte* dtuple_f_data; /* pointer to the current logical
1371  field data */
1372  ulint rec_f_len; /* length of current field in rec */
1373  const byte* rec_f_data; /* pointer to the current rec field */
1374  int ret; /* return value */
1375  ulint cur_field; /* current field number */
1376 
1377  ut_ad(dtuple && rec && matched_fields);
1378  ut_ad(dtuple_check_typed(dtuple));
1379  ut_ad(rec_offs_validate(rec, NULL, offsets));
1380 
1381  ut_ad(n_cmp > 0);
1382  ut_ad(n_cmp <= dtuple_get_n_fields(dtuple));
1383  ut_ad(*matched_fields <= n_cmp);
1384  ut_ad(*matched_fields <= rec_offs_n_fields(offsets));
1385 
1386  cur_field = *matched_fields;
1387 
1388  if (cur_field == 0) {
1389  if (UNIV_UNLIKELY
1390  (rec_get_info_bits(rec, rec_offs_comp(offsets))
1391  & REC_INFO_MIN_REC_FLAG)) {
1392 
1393  ret = !(dtuple_get_info_bits(dtuple)
1394  & REC_INFO_MIN_REC_FLAG);
1395 
1396  goto order_resolved;
1397  }
1398 
1399  if (UNIV_UNLIKELY
1400  (dtuple_get_info_bits(dtuple) & REC_INFO_MIN_REC_FLAG)) {
1401  ret = -1;
1402 
1403  goto order_resolved;
1404  }
1405  }
1406 
1407  /* Match fields in a loop; stop if we run out of fields in dtuple */
1408 
1409  while (cur_field < n_cmp) {
1410 
1411  ulint mtype;
1412  ulint prtype;
1413 
1414  dtuple_field = dtuple_get_nth_field(dtuple, cur_field);
1415  {
1416  const dtype_t* type
1417  = dfield_get_type(dtuple_field);
1418 
1419  mtype = type->mtype;
1420  prtype = type->prtype;
1421  }
1422 
1423  dtuple_f_data = static_cast<const byte*>(
1424  dfield_get_data(dtuple_field));
1425 
1426  dtuple_f_len = dfield_get_len(dtuple_field);
1427 
1428  rec_f_data = rec_get_nth_field(rec, offsets,
1429  cur_field, &rec_f_len);
1430 
1431  if (rec_offs_nth_extern(offsets, cur_field)) {
1432  /* We do not compare to an externally stored field */
1433 
1434  ret = 0;
1435 
1436  goto order_resolved;
1437  }
1438 
1439  ret = cmp_data_data(mtype, prtype, dtuple_f_data, dtuple_f_len,
1440  rec_f_data, rec_f_len);
1441  if (ret != 0) {
1442  goto order_resolved;
1443  }
1444 
1445  cur_field++;
1446  }
1447 
1448  ret = 0; /* If we ran out of fields, dtuple was equal to rec
1449  up to the common fields */
1450 order_resolved:
1451  ut_ad((ret >= - 1) && (ret <= 1));
1452 
1453  *matched_fields = cur_field;
1454 
1455  return(ret);
1456 }
1457 #endif /* UNIV_DEBUG */