Drizzled Public API Documentation

row0row.cc
1 /*****************************************************************************
2 
3 Copyright (C) 1996, 2010, Innobase Oy. 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., 51 Franklin
15 St, Fifth Floor, Boston, MA 02110-1301 USA
16 
17 *****************************************************************************/
18 
19 /**************************************************/
26 #include "row0row.h"
27 
28 #ifdef UNIV_NONINL
29 #include "row0row.ic"
30 #endif
31 
32 #include "data0type.h"
33 #include "dict0dict.h"
34 #include "btr0btr.h"
35 #include "ha_prototypes.h"
36 #include "mach0data.h"
37 #include "trx0rseg.h"
38 #include "trx0trx.h"
39 #include "trx0roll.h"
40 #include "trx0undo.h"
41 #include "trx0purge.h"
42 #include "trx0rec.h"
43 #include "que0que.h"
44 #include "row0ext.h"
45 #include "row0upd.h"
46 #include "rem0cmp.h"
47 #include "read0read.h"
48 #include "ut0mem.h"
49 
50 /*********************************************************************/
54 UNIV_INTERN
55 ulint
57 /*==================*/
58  const rec_t* /*rec __attribute__((unused))*/,
60  dict_index_t* index,
61  const ulint* offsets)
62 {
63  ulint pos;
64  ulint offset;
65  ulint len;
66 
67  ut_ad(dict_index_is_clust(index));
68  ut_ad(rec_offs_validate(rec, index, offsets));
69 
70  pos = dict_index_get_sys_col_pos(index, DATA_TRX_ID);
71 
72  offset = rec_get_nth_field_offs(offsets, pos, &len);
73 
74  ut_ad(len == DATA_TRX_ID_LEN);
75 
76  return(offset);
77 }
78 
79 /*****************************************************************/
85 UNIV_INTERN
86 dtuple_t*
88 /*==================*/
89  const dtuple_t* row,
91  row_ext_t* ext,
93  dict_index_t* index,
94  mem_heap_t* heap)
96 {
97  dtuple_t* entry;
98  ulint entry_len;
99  ulint i;
100 
101  ut_ad(row && index && heap);
103 
104  entry_len = dict_index_get_n_fields(index);
105  entry = dtuple_create(heap, entry_len);
106 
107  if (UNIV_UNLIKELY(index->type & DICT_UNIVERSAL)) {
108  dtuple_set_n_fields_cmp(entry, entry_len);
109  /* There may only be externally stored columns
110  in a clustered index B-tree of a user table. */
111  ut_a(!ext);
112  } else {
114  entry, dict_index_get_n_unique_in_tree(index));
115  }
116 
117  for (i = 0; i < entry_len; i++) {
118  const dict_field_t* ind_field
119  = dict_index_get_nth_field(index, i);
120  const dict_col_t* col
121  = ind_field->col;
122  ulint col_no
123  = dict_col_get_no(col);
124  dfield_t* dfield
125  = dtuple_get_nth_field(entry, i);
126  const dfield_t* dfield2
127  = dtuple_get_nth_field(row, col_no);
128  ulint len
129  = dfield_get_len(dfield2);
130 
131  dfield_copy(dfield, dfield2);
132 
133  if (dfield_is_null(dfield) || ind_field->prefix_len == 0) {
134  continue;
135  }
136 
137  /* If a column prefix index, take only the prefix.
138  Prefix-indexed columns may be externally stored. */
139  ut_ad(col->ord_part);
140 
141  if (UNIV_LIKELY_NULL(ext)) {
142  /* See if the column is stored externally. */
143  const byte* buf = row_ext_lookup(ext, col_no,
144  &len);
145  if (UNIV_LIKELY_NULL(buf)) {
146  if (UNIV_UNLIKELY(buf == field_ref_zero)) {
147  return(NULL);
148  }
149  dfield_set_data(dfield, buf, len);
150  }
151  } else if (dfield_is_ext(dfield)) {
154  ut_a(ind_field->prefix_len <= len
155  || dict_index_is_clust(index));
156  }
157 
159  col->prtype, col->mbminmaxlen,
160  ind_field->prefix_len, len, static_cast<const char *>(dfield_get_data(dfield)));
161  dfield_set_len(dfield, len);
162  }
163 
164  ut_ad(dtuple_check_typed(entry));
165 
166  return(entry);
167 }
168 
169 /*******************************************************************/
173 UNIV_INTERN
174 dtuple_t*
176 /*======*/
177  ulint type,
184  const dict_index_t* index,
185  const rec_t* rec,
194  const ulint* offsets,
197  const dict_table_t* col_table,
204  row_ext_t** ext,
207  mem_heap_t* heap)
209 {
210  dtuple_t* row;
211  const dict_table_t* table;
212  ulint n_fields;
213  ulint n_ext_cols;
214  ulint* ext_cols = NULL; /* remove warning */
215  ulint len;
216  ulint row_len;
217  byte* buf;
218  ulint i;
219  ulint j;
220  mem_heap_t* tmp_heap = NULL;
221  ulint offsets_[REC_OFFS_NORMAL_SIZE];
222  rec_offs_init(offsets_);
223 
224  ut_ad(index && rec && heap);
225  ut_ad(dict_index_is_clust(index));
226 
227  if (!offsets) {
228  offsets = rec_get_offsets(rec, index, offsets_,
229  ULINT_UNDEFINED, &tmp_heap);
230  } else {
231  ut_ad(rec_offs_validate(rec, index, offsets));
232  }
233 
234  if (type != ROW_COPY_POINTERS) {
235  /* Take a copy of rec to heap */
236  buf = static_cast<byte *>(mem_heap_alloc(heap, rec_offs_size(offsets)));
237  rec = rec_copy(buf, rec, offsets);
238  /* Avoid a debug assertion in rec_offs_validate(). */
239  rec_offs_make_valid(rec, index, (ulint*) offsets);
240  }
241 
242  table = index->table;
243  row_len = dict_table_get_n_cols(table);
244 
245  row = dtuple_create(heap, row_len);
246 
247  dict_table_copy_types(row, table);
248 
250  rec, dict_table_is_comp(table)));
251 
252  n_fields = rec_offs_n_fields(offsets);
253  n_ext_cols = rec_offs_n_extern(offsets);
254  if (n_ext_cols) {
255  ext_cols = static_cast<ulint *>(mem_heap_alloc(heap, n_ext_cols * sizeof *ext_cols));
256  }
257 
258  for (i = j = 0; i < n_fields; i++) {
259  dict_field_t* ind_field
260  = dict_index_get_nth_field(index, i);
261  const dict_col_t* col
262  = dict_field_get_col(ind_field);
263  ulint col_no
264  = dict_col_get_no(col);
265  dfield_t* dfield
266  = dtuple_get_nth_field(row, col_no);
267 
268  if (ind_field->prefix_len == 0) {
269 
270  const byte* field = rec_get_nth_field(
271  rec, offsets, i, &len);
272 
273  dfield_set_data(dfield, field, len);
274  }
275 
276  if (rec_offs_nth_extern(offsets, i)) {
277  dfield_set_ext(dfield);
278 
279  if (UNIV_LIKELY_NULL(col_table)) {
280  ut_a(col_no
281  < dict_table_get_n_cols(col_table));
282  col = dict_table_get_nth_col(
283  col_table, col_no);
284  }
285 
286  if (col->ord_part) {
287  /* We will have to fetch prefixes of
288  externally stored columns that are
289  referenced by column prefixes. */
290  ext_cols[j++] = col_no;
291  }
292  }
293  }
294 
296 
297  if (!ext) {
298  /* REDUNDANT and COMPACT formats store a local
299  768-byte prefix of each externally stored
300  column. No cache is needed. */
303  } else if (j) {
304  *ext = row_ext_create(j, ext_cols, row,
305  dict_table_zip_size(index->table),
306  heap);
307  } else {
308  *ext = NULL;
309  }
310 
311  if (tmp_heap) {
312  mem_heap_free(tmp_heap);
313  }
314 
315  return(row);
316 }
317 
318 /*******************************************************************/
322 UNIV_INTERN
323 dtuple_t*
325 /*=======================*/
326  const rec_t* rec,
327  const dict_index_t* index,
328  const ulint* offsets,
329  ulint* n_ext,
331  mem_heap_t* heap)
333 {
334  dtuple_t* entry;
335  dfield_t* dfield;
336  ulint i;
337  const byte* field;
338  ulint len;
339  ulint rec_len;
340 
341  ut_ad(rec && heap && index);
342  /* Because this function may be invoked by row0merge.c
343  on a record whose header is in different format, the check
344  rec_offs_validate(rec, index, offsets) must be avoided here. */
345  ut_ad(n_ext);
346  *n_ext = 0;
347 
348  rec_len = rec_offs_n_fields(offsets);
349 
350  entry = dtuple_create(heap, rec_len);
351 
354  ut_ad(rec_len == dict_index_get_n_fields(index));
355 
356  dict_index_copy_types(entry, index, rec_len);
357 
358  for (i = 0; i < rec_len; i++) {
359 
360  dfield = dtuple_get_nth_field(entry, i);
361  field = rec_get_nth_field(rec, offsets, i, &len);
362 
363  dfield_set_data(dfield, field, len);
364 
365  if (rec_offs_nth_extern(offsets, i)) {
366  dfield_set_ext(dfield);
367  (*n_ext)++;
368  }
369  }
370 
371  ut_ad(dtuple_check_typed(entry));
372 
373  return(entry);
374 }
375 
376 /*******************************************************************/
380 UNIV_INTERN
381 dtuple_t*
383 /*===================*/
384  ulint type,
390  const rec_t* rec,
399  const dict_index_t* index,
400  ulint* offsets,
401  ulint* n_ext,
403  mem_heap_t* heap)
405 {
406  dtuple_t* entry;
407  byte* buf;
408 
409  ut_ad(rec && heap && index);
410  ut_ad(rec_offs_validate(rec, index, offsets));
411 
412  if (type == ROW_COPY_DATA) {
413  /* Take a copy of rec to heap */
414  buf = static_cast<byte *>(mem_heap_alloc(heap, rec_offs_size(offsets)));
415  rec = rec_copy(buf, rec, offsets);
416  /* Avoid a debug assertion in rec_offs_validate(). */
417  rec_offs_make_valid(rec, index, offsets);
418  }
419 
420  entry = row_rec_to_index_entry_low(rec, index, offsets, n_ext, heap);
421 
422  dtuple_set_info_bits(entry,
423  rec_get_info_bits(rec, rec_offs_comp(offsets)));
424 
425  return(entry);
426 }
427 
428 /*******************************************************************/
432 UNIV_INTERN
433 dtuple_t*
435 /*==============*/
436  ulint type,
440  dict_index_t* index,
441  const rec_t* rec,
448  mem_heap_t* heap)
450 {
451  dict_table_t* table;
452  dict_index_t* clust_index;
453  dfield_t* dfield;
454  dtuple_t* ref;
455  const byte* field;
456  ulint len;
457  ulint ref_len;
458  ulint pos;
459  byte* buf;
460  ulint clust_col_prefix_len;
461  ulint i;
462  mem_heap_t* tmp_heap = NULL;
463  ulint offsets_[REC_OFFS_NORMAL_SIZE];
464  ulint* offsets = offsets_;
465  rec_offs_init(offsets_);
466 
467  ut_ad(index && rec && heap);
468  ut_ad(!dict_index_is_clust(index));
469 
470  offsets = rec_get_offsets(rec, index, offsets,
471  ULINT_UNDEFINED, &tmp_heap);
472  /* Secondary indexes must not contain externally stored columns. */
473  ut_ad(!rec_offs_any_extern(offsets));
474 
475  if (type == ROW_COPY_DATA) {
476  /* Take a copy of rec to heap */
477 
478  buf = static_cast<byte *>(mem_heap_alloc(heap, rec_offs_size(offsets)));
479 
480  rec = rec_copy(buf, rec, offsets);
481  /* Avoid a debug assertion in rec_offs_validate(). */
482  rec_offs_make_valid(rec, index, offsets);
483  }
484 
485  table = index->table;
486 
487  clust_index = dict_table_get_first_index(table);
488 
489  ref_len = dict_index_get_n_unique(clust_index);
490 
491  ref = dtuple_create(heap, ref_len);
492 
493  dict_index_copy_types(ref, clust_index, ref_len);
494 
495  for (i = 0; i < ref_len; i++) {
496  dfield = dtuple_get_nth_field(ref, i);
497 
498  pos = dict_index_get_nth_field_pos(index, clust_index, i);
499 
500  ut_a(pos != ULINT_UNDEFINED);
501 
502  field = rec_get_nth_field(rec, offsets, pos, &len);
503 
504  dfield_set_data(dfield, field, len);
505 
506  /* If the primary key contains a column prefix, then the
507  secondary index may contain a longer prefix of the same
508  column, or the full column, and we must adjust the length
509  accordingly. */
510 
511  clust_col_prefix_len = dict_index_get_nth_field(
512  clust_index, i)->prefix_len;
513 
514  if (clust_col_prefix_len > 0) {
515  if (len != UNIV_SQL_NULL) {
516 
517  const dtype_t* dtype
518  = dfield_get_type(dfield);
519 
520  dfield_set_len(dfield,
522  dtype->prtype,
523  dtype->mbminmaxlen,
524  clust_col_prefix_len,
525  len, (char*) field));
526  }
527  }
528  }
529 
531  if (tmp_heap) {
532  mem_heap_free(tmp_heap);
533  }
534 
535  return(ref);
536 }
537 
538 /*******************************************************************/
541 UNIV_INTERN
542 void
544 /*=======================*/
545  dtuple_t* ref,
547  const rec_t* rec,
555  const dict_index_t* index,
556  ulint* offsets,
558  trx_t* trx)
559 {
560  const dict_index_t* clust_index;
561  dfield_t* dfield;
562  const byte* field;
563  ulint len;
564  ulint ref_len;
565  ulint pos;
566  ulint clust_col_prefix_len;
567  ulint i;
568  mem_heap_t* heap = NULL;
569  ulint offsets_[REC_OFFS_NORMAL_SIZE];
570  rec_offs_init(offsets_);
571 
572  ut_a(ref);
573  ut_a(index);
574  ut_a(rec);
575  ut_ad(!dict_index_is_clust(index));
576 
577  if (UNIV_UNLIKELY(!index->table)) {
578  fputs("InnoDB: table ", stderr);
579 notfound:
580  ut_print_name(stderr, trx, TRUE, index->table_name);
581  fputs(" for index ", stderr);
582  ut_print_name(stderr, trx, FALSE, index->name);
583  fputs(" not found\n", stderr);
584  ut_error;
585  }
586 
587  clust_index = dict_table_get_first_index(index->table);
588 
589  if (UNIV_UNLIKELY(!clust_index)) {
590  fputs("InnoDB: clust index for table ", stderr);
591  goto notfound;
592  }
593 
594  if (!offsets) {
595  offsets = rec_get_offsets(rec, index, offsets_,
596  ULINT_UNDEFINED, &heap);
597  } else {
598  ut_ad(rec_offs_validate(rec, index, offsets));
599  }
600 
601  /* Secondary indexes must not contain externally stored columns. */
602  ut_ad(!rec_offs_any_extern(offsets));
603  ref_len = dict_index_get_n_unique(clust_index);
604 
605  ut_ad(ref_len == dtuple_get_n_fields(ref));
606 
607  dict_index_copy_types(ref, clust_index, ref_len);
608 
609  for (i = 0; i < ref_len; i++) {
610  dfield = dtuple_get_nth_field(ref, i);
611 
612  pos = dict_index_get_nth_field_pos(index, clust_index, i);
613 
614  ut_a(pos != ULINT_UNDEFINED);
615 
616  field = rec_get_nth_field(rec, offsets, pos, &len);
617 
618  dfield_set_data(dfield, field, len);
619 
620  /* If the primary key contains a column prefix, then the
621  secondary index may contain a longer prefix of the same
622  column, or the full column, and we must adjust the length
623  accordingly. */
624 
625  clust_col_prefix_len = dict_index_get_nth_field(
626  clust_index, i)->prefix_len;
627 
628  if (clust_col_prefix_len > 0) {
629  if (len != UNIV_SQL_NULL) {
630 
631  const dtype_t* dtype
632  = dfield_get_type(dfield);
633 
634  dfield_set_len(dfield,
636  dtype->prtype,
637  dtype->mbminmaxlen,
638  clust_col_prefix_len,
639  len, (char*) field));
640  }
641  }
642  }
643 
645  if (UNIV_LIKELY_NULL(heap)) {
646  mem_heap_free(heap);
647  }
648 }
649 
650 /***************************************************************/
653 UNIV_INTERN
654 ibool
656 /*==================*/
657  btr_pcur_t* pcur,
659  ulint mode,
660  const dict_table_t* table,
661  const dtuple_t* ref,
662  mtr_t* mtr)
663 {
664  ulint low_match;
665  rec_t* rec;
666  dict_index_t* index;
667 
669 
670  index = dict_table_get_first_index(table);
671 
673 
674  btr_pcur_open(index, ref, PAGE_CUR_LE, mode, pcur, mtr);
675 
676  low_match = btr_pcur_get_low_match(pcur);
677 
678  rec = btr_pcur_get_rec(pcur);
679 
680  if (page_rec_is_infimum(rec)) {
681 
682  return(FALSE);
683  }
684 
685  if (low_match != dtuple_get_n_fields(ref)) {
686 
687  return(FALSE);
688  }
689 
690  return(TRUE);
691 }
692 
693 /*********************************************************************/
697 UNIV_INTERN
698 rec_t*
700 /*==============*/
701  ulint mode,
702  const rec_t* rec,
703  dict_index_t* index,
704  dict_index_t** clust_index,
705  mtr_t* mtr)
706 {
707  mem_heap_t* heap;
708  dtuple_t* ref;
709  dict_table_t* table;
710  btr_pcur_t pcur;
711  ibool found;
712  rec_t* clust_rec;
713 
714  ut_ad(!dict_index_is_clust(index));
715 
716  table = index->table;
717 
718  heap = mem_heap_create(256);
719 
720  ref = row_build_row_ref(ROW_COPY_POINTERS, index, rec, heap);
721 
722  found = row_search_on_row_ref(&pcur, mode, table, ref, mtr);
723 
724  clust_rec = found ? btr_pcur_get_rec(&pcur) : NULL;
725 
726  mem_heap_free(heap);
727 
728  btr_pcur_close(&pcur);
729 
730  *clust_index = dict_table_get_first_index(table);
731 
732  return(clust_rec);
733 }
734 
735 /***************************************************************/
738 UNIV_INTERN
741 /*===================*/
742  dict_index_t* index,
743  const dtuple_t* entry,
744  ulint mode,
745  btr_pcur_t* pcur,
747  mtr_t* mtr)
748 {
749  ulint n_fields;
750  ulint low_match;
751  rec_t* rec;
752 
753  ut_ad(dtuple_check_typed(entry));
754 
755  btr_pcur_open(index, entry, PAGE_CUR_LE, mode, pcur, mtr);
756 
757  switch (btr_pcur_get_btr_cur(pcur)->flag) {
758  case BTR_CUR_DELETE_REF:
759  ut_a(mode & BTR_DELETE);
760  return(ROW_NOT_DELETED_REF);
761 
763  case BTR_CUR_DELETE_IBUF:
765  return(ROW_BUFFERED);
766 
767  case BTR_CUR_HASH:
768  case BTR_CUR_HASH_FAIL:
769  case BTR_CUR_BINARY:
770  break;
771  }
772 
773  low_match = btr_pcur_get_low_match(pcur);
774 
775  rec = btr_pcur_get_rec(pcur);
776 
777  n_fields = dtuple_get_n_fields(entry);
778 
779  if (page_rec_is_infimum(rec)) {
780 
781  return(ROW_NOT_FOUND);
782  } else if (low_match != n_fields) {
783 
784  return(ROW_NOT_FOUND);
785  }
786 
787  return(ROW_FOUND);
788 }
789 
790 #if !defined(BUILD_DRIZZLE)
791 # include "my_sys.h"
792 #endif
793 
794 
795 /*******************************************************************/
806 static
807 ulint
808 row_raw_format_int(
809 /*===============*/
810  const char* data,
811  ulint data_len,
813  ulint prtype,
814  char* buf,
815  ulint buf_size,
817  ibool* format_in_hex)
819 {
820  ulint ret;
821 
822  if (data_len <= sizeof(ullint)) {
823 
824  ullint value;
825  ibool unsigned_type = prtype & DATA_UNSIGNED;
826 
827  value = mach_read_int_type((const byte*) data,
828  data_len, unsigned_type);
829 
830  if (unsigned_type) {
831 
832  ret = ut_snprintf(buf, buf_size, "%llu",
833  value) + 1;
834  } else {
835 
836  ret = ut_snprintf(buf, buf_size, "%lld",
837  (long long) value) + 1;
838  }
839 
840  } else {
841 
842  *format_in_hex = TRUE;
843  ret = 0;
844  }
845 
846  return(ut_min(ret, buf_size));
847 }
848 
849 /*******************************************************************/
861 static
862 ulint
863 row_raw_format_str(
864 /*===============*/
865  const char* data,
866  ulint data_len,
868  ulint prtype,
869  char* buf,
870  ulint buf_size,
872  ibool* format_in_hex)
874 {
875  ulint charset_coll;
876 
877  if (buf_size == 0) {
878 
879  return(0);
880  }
881 
882  /* we assume system_charset_info is UTF-8 */
883 
884  charset_coll = dtype_get_charset_coll(prtype);
885 
886  if (UNIV_LIKELY(dtype_is_utf8(prtype))) {
887 
888  return(ut_str_sql_format(data, data_len, buf, buf_size));
889  }
890  /* else */
891 
892  if (charset_coll == DATA_MYSQL_BINARY_CHARSET_COLL) {
893 
894  *format_in_hex = TRUE;
895  return(0);
896  }
897  /* else */
898 
899  return(innobase_raw_format(data, data_len, charset_coll,
900  buf, buf_size));
901 }
902 
903 /*******************************************************************/
911 UNIV_INTERN
912 ulint
914 /*===========*/
915  const char* data,
916  ulint data_len,
918  const dict_field_t* dict_field,
919  char* buf,
920  ulint buf_size)
922 {
923  ulint mtype;
924  ulint prtype;
925  ulint ret= 0;
926  ibool format_in_hex;
927 
928  if (buf_size == 0) {
929 
930  return(ret);
931  }
932 
933  if (data_len == UNIV_SQL_NULL) {
934 
935  ret = ut_snprintf((char*) buf, buf_size, "NULL") + 1;
936 
937  return(ut_min(ret, buf_size));
938  }
939 
940  mtype = dict_field->col->mtype;
941  prtype = dict_field->col->prtype;
942 
943  format_in_hex = FALSE;
944 
945  switch (mtype) {
946  case DATA_INT:
947 
948  ret = row_raw_format_int(data, data_len, prtype,
949  buf, buf_size, &format_in_hex);
950  if (format_in_hex) {
951 
952  goto format_in_hex;
953  }
954  break;
955  case DATA_CHAR:
956  case DATA_VARCHAR:
957  case DATA_MYSQL:
958  case DATA_VARMYSQL:
959 
960  ret = row_raw_format_str(data, data_len, prtype,
961  buf, buf_size, &format_in_hex);
962  if (format_in_hex) {
963 
964  goto format_in_hex;
965  }
966 
967  break;
968  /* XXX support more data types */
969  default:
970  format_in_hex:
971 
972  if (UNIV_LIKELY(buf_size > 2)) {
973 
974  memcpy(buf, "0x", 2);
975  buf += 2;
976  buf_size -= 2;
977  ret = 2 + ut_raw_to_hex(data, data_len,
978  buf, buf_size);
979  } else {
980 
981  buf[0] = '\0';
982  ret = 1;
983  }
984  }
985 
986  return(ret);
987 }
988 
989 #ifdef UNIV_COMPILE_TEST_FUNCS
990 
991 #include "ut0dbg.h"
992 
993 void
994 test_row_raw_format_int()
995 {
996  ulint ret;
997  char buf[128];
998  ibool format_in_hex;
999 
1000 #define CALL_AND_TEST(data, data_len, prtype, buf, buf_size,\
1001  ret_expected, buf_expected, format_in_hex_expected)\
1002  do {\
1003  ibool ok = TRUE;\
1004  ulint i;\
1005  memset(buf, 'x', 10);\
1006  buf[10] = '\0';\
1007  format_in_hex = FALSE;\
1008  fprintf(stderr, "TESTING \"\\x");\
1009  for (i = 0; i < data_len; i++) {\
1010  fprintf(stderr, "%02hhX", data[i]);\
1011  }\
1012  fprintf(stderr, "\", %lu, %lu, %lu\n",\
1013  (ulint) data_len, (ulint) prtype,\
1014  (ulint) buf_size);\
1015  ret = row_raw_format_int(data, data_len, prtype,\
1016  buf, buf_size, &format_in_hex);\
1017  if (ret != ret_expected) {\
1018  fprintf(stderr, "expected ret %lu, got %lu\n",\
1019  (ulint) ret_expected, ret);\
1020  ok = FALSE;\
1021  }\
1022  if (strcmp((char*) buf, buf_expected) != 0) {\
1023  fprintf(stderr, "expected buf \"%s\", got \"%s\"\n",\
1024  buf_expected, buf);\
1025  ok = FALSE;\
1026  }\
1027  if (format_in_hex != format_in_hex_expected) {\
1028  fprintf(stderr, "expected format_in_hex %d, got %d\n",\
1029  (int) format_in_hex_expected,\
1030  (int) format_in_hex);\
1031  ok = FALSE;\
1032  }\
1033  if (ok) {\
1034  fprintf(stderr, "OK: %lu, \"%s\" %d\n\n",\
1035  (ulint) ret, buf, (int) format_in_hex);\
1036  } else {\
1037  return;\
1038  }\
1039  } while (0)
1040 
1041 #if 1
1042  /* min values for signed 1-8 byte integers */
1043 
1044  CALL_AND_TEST("\x00", 1, 0,
1045  buf, sizeof(buf), 5, "-128", 0);
1046 
1047  CALL_AND_TEST("\x00\x00", 2, 0,
1048  buf, sizeof(buf), 7, "-32768", 0);
1049 
1050  CALL_AND_TEST("\x00\x00\x00", 3, 0,
1051  buf, sizeof(buf), 9, "-8388608", 0);
1052 
1053  CALL_AND_TEST("\x00\x00\x00\x00", 4, 0,
1054  buf, sizeof(buf), 12, "-2147483648", 0);
1055 
1056  CALL_AND_TEST("\x00\x00\x00\x00\x00", 5, 0,
1057  buf, sizeof(buf), 14, "-549755813888", 0);
1058 
1059  CALL_AND_TEST("\x00\x00\x00\x00\x00\x00", 6, 0,
1060  buf, sizeof(buf), 17, "-140737488355328", 0);
1061 
1062  CALL_AND_TEST("\x00\x00\x00\x00\x00\x00\x00", 7, 0,
1063  buf, sizeof(buf), 19, "-36028797018963968", 0);
1064 
1065  CALL_AND_TEST("\x00\x00\x00\x00\x00\x00\x00\x00", 8, 0,
1066  buf, sizeof(buf), 21, "-9223372036854775808", 0);
1067 
1068  /* min values for unsigned 1-8 byte integers */
1069 
1070  CALL_AND_TEST("\x00", 1, DATA_UNSIGNED,
1071  buf, sizeof(buf), 2, "0", 0);
1072 
1073  CALL_AND_TEST("\x00\x00", 2, DATA_UNSIGNED,
1074  buf, sizeof(buf), 2, "0", 0);
1075 
1076  CALL_AND_TEST("\x00\x00\x00", 3, DATA_UNSIGNED,
1077  buf, sizeof(buf), 2, "0", 0);
1078 
1079  CALL_AND_TEST("\x00\x00\x00\x00", 4, DATA_UNSIGNED,
1080  buf, sizeof(buf), 2, "0", 0);
1081 
1082  CALL_AND_TEST("\x00\x00\x00\x00\x00", 5, DATA_UNSIGNED,
1083  buf, sizeof(buf), 2, "0", 0);
1084 
1085  CALL_AND_TEST("\x00\x00\x00\x00\x00\x00", 6, DATA_UNSIGNED,
1086  buf, sizeof(buf), 2, "0", 0);
1087 
1088  CALL_AND_TEST("\x00\x00\x00\x00\x00\x00\x00", 7, DATA_UNSIGNED,
1089  buf, sizeof(buf), 2, "0", 0);
1090 
1091  CALL_AND_TEST("\x00\x00\x00\x00\x00\x00\x00\x00", 8, DATA_UNSIGNED,
1092  buf, sizeof(buf), 2, "0", 0);
1093 
1094  /* max values for signed 1-8 byte integers */
1095 
1096  CALL_AND_TEST("\xFF", 1, 0,
1097  buf, sizeof(buf), 4, "127", 0);
1098 
1099  CALL_AND_TEST("\xFF\xFF", 2, 0,
1100  buf, sizeof(buf), 6, "32767", 0);
1101 
1102  CALL_AND_TEST("\xFF\xFF\xFF", 3, 0,
1103  buf, sizeof(buf), 8, "8388607", 0);
1104 
1105  CALL_AND_TEST("\xFF\xFF\xFF\xFF", 4, 0,
1106  buf, sizeof(buf), 11, "2147483647", 0);
1107 
1108  CALL_AND_TEST("\xFF\xFF\xFF\xFF\xFF", 5, 0,
1109  buf, sizeof(buf), 13, "549755813887", 0);
1110 
1111  CALL_AND_TEST("\xFF\xFF\xFF\xFF\xFF\xFF", 6, 0,
1112  buf, sizeof(buf), 16, "140737488355327", 0);
1113 
1114  CALL_AND_TEST("\xFF\xFF\xFF\xFF\xFF\xFF\xFF", 7, 0,
1115  buf, sizeof(buf), 18, "36028797018963967", 0);
1116 
1117  CALL_AND_TEST("\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF", 8, 0,
1118  buf, sizeof(buf), 20, "9223372036854775807", 0);
1119 
1120  /* max values for unsigned 1-8 byte integers */
1121 
1122  CALL_AND_TEST("\xFF", 1, DATA_UNSIGNED,
1123  buf, sizeof(buf), 4, "255", 0);
1124 
1125  CALL_AND_TEST("\xFF\xFF", 2, DATA_UNSIGNED,
1126  buf, sizeof(buf), 6, "65535", 0);
1127 
1128  CALL_AND_TEST("\xFF\xFF\xFF", 3, DATA_UNSIGNED,
1129  buf, sizeof(buf), 9, "16777215", 0);
1130 
1131  CALL_AND_TEST("\xFF\xFF\xFF\xFF", 4, DATA_UNSIGNED,
1132  buf, sizeof(buf), 11, "4294967295", 0);
1133 
1134  CALL_AND_TEST("\xFF\xFF\xFF\xFF\xFF", 5, DATA_UNSIGNED,
1135  buf, sizeof(buf), 14, "1099511627775", 0);
1136 
1137  CALL_AND_TEST("\xFF\xFF\xFF\xFF\xFF\xFF", 6, DATA_UNSIGNED,
1138  buf, sizeof(buf), 16, "281474976710655", 0);
1139 
1140  CALL_AND_TEST("\xFF\xFF\xFF\xFF\xFF\xFF\xFF", 7, DATA_UNSIGNED,
1141  buf, sizeof(buf), 18, "72057594037927935", 0);
1142 
1143  CALL_AND_TEST("\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF", 8, DATA_UNSIGNED,
1144  buf, sizeof(buf), 21, "18446744073709551615", 0);
1145 
1146  /* some random values */
1147 
1148  CALL_AND_TEST("\x52", 1, 0,
1149  buf, sizeof(buf), 4, "-46", 0);
1150 
1151  CALL_AND_TEST("\x0E", 1, DATA_UNSIGNED,
1152  buf, sizeof(buf), 3, "14", 0);
1153 
1154  CALL_AND_TEST("\x62\xCE", 2, 0,
1155  buf, sizeof(buf), 6, "-7474", 0);
1156 
1157  CALL_AND_TEST("\x29\xD6", 2, DATA_UNSIGNED,
1158  buf, sizeof(buf), 6, "10710", 0);
1159 
1160  CALL_AND_TEST("\x7F\xFF\x90", 3, 0,
1161  buf, sizeof(buf), 5, "-112", 0);
1162 
1163  CALL_AND_TEST("\x00\xA1\x16", 3, DATA_UNSIGNED,
1164  buf, sizeof(buf), 6, "41238", 0);
1165 
1166  CALL_AND_TEST("\x7F\xFF\xFF\xF7", 4, 0,
1167  buf, sizeof(buf), 3, "-9", 0);
1168 
1169  CALL_AND_TEST("\x00\x00\x00\x5C", 4, DATA_UNSIGNED,
1170  buf, sizeof(buf), 3, "92", 0);
1171 
1172  CALL_AND_TEST("\x7F\xFF\xFF\xFF\xFF\xFF\xDC\x63", 8, 0,
1173  buf, sizeof(buf), 6, "-9117", 0);
1174 
1175  CALL_AND_TEST("\x00\x00\x00\x00\x00\x01\x64\x62", 8, DATA_UNSIGNED,
1176  buf, sizeof(buf), 6, "91234", 0);
1177 #endif
1178 
1179  /* speed test */
1180 
1181  speedo_t speedo;
1182  ulint i;
1183 
1184  speedo_reset(&speedo);
1185 
1186  for (i = 0; i < 1000000; i++) {
1187  row_raw_format_int("\x23", 1,
1188  0, buf, sizeof(buf),
1189  &format_in_hex);
1190  row_raw_format_int("\x23", 1,
1191  DATA_UNSIGNED, buf, sizeof(buf),
1192  &format_in_hex);
1193 
1194  row_raw_format_int("\x00\x00\x00\x00\x00\x01\x64\x62", 8,
1195  0, buf, sizeof(buf),
1196  &format_in_hex);
1197  row_raw_format_int("\x00\x00\x00\x00\x00\x01\x64\x62", 8,
1198  DATA_UNSIGNED, buf, sizeof(buf),
1199  &format_in_hex);
1200  }
1201 
1202  speedo_show(&speedo);
1203 }
1204 
1205 #endif /* UNIV_COMPILE_TEST_FUNCS */
UNIV_INTERN ulint row_get_trx_id_offset(const rec_t *rec, dict_index_t *index, const ulint *offsets)
Definition: row0row.cc:56
UNIV_INTERN rec_t * row_get_clust_rec(ulint mode, const rec_t *rec, dict_index_t *index, dict_index_t **clust_index, mtr_t *mtr)
Definition: row0row.cc:699
UNIV_INLINE ulint btr_pcur_get_low_match(const btr_pcur_t *cursor)
#define BTR_DELETE
Definition: btr0btr.h:94
const char * name
Definition: dict0mem.h:339
UNIV_INTERN row_ext_t * row_ext_create(ulint n_ext, const ulint *ext, const dtuple_t *tuple, ulint zip_size, mem_heap_t *heap)
Definition: row0ext.cc:75
UNIV_INTERN ulint dict_index_get_nth_field_pos(const dict_index_t *index, const dict_index_t *index2, ulint n)
Definition: dict0dict.cc:585
UNIV_INLINE ulint dict_index_get_n_fields(const dict_index_t *index)
UNIV_INLINE void dfield_set_len(dfield_t *field, ulint len)
unsigned type
Definition: dict0mem.h:347
UNIV_INLINE dtuple_t * dtuple_create(mem_heap_t *heap, ulint n_fields)
UNIV_INLINE ulint rec_offs_any_extern(const ulint *offsets)
UNIV_INLINE ulint dfield_is_ext(const dfield_t *field)
UNIV_INTERN dtuple_t * row_build(ulint type, const dict_index_t *index, const rec_t *rec, const ulint *offsets, const dict_table_t *col_table, row_ext_t **ext, mem_heap_t *heap)
Definition: row0row.cc:175
#define ut_snprintf
Definition: ut0ut.h:398
UNIV_INTERN ulint dtype_get_at_most_n_mbchars(ulint prtype, ulint mbminmaxlen, ulint prefix_len, ulint data_len, const char *str)
Definition: data0type.cc:49
UNIV_INLINE ibool dict_table_is_comp(const dict_table_t *table)
UNIV_INLINE ulint rec_offs_nth_extern(const ulint *offsets, ulint n)
unsigned prtype
Definition: dict0mem.h:273
UNIV_INTERN dtuple_t * row_build_index_entry(const dtuple_t *row, row_ext_t *ext, dict_index_t *index, mem_heap_t *heap)
Definition: row0row.cc:87
UNIV_INLINE rec_t * rec_copy(void *buf, const rec_t *rec, const ulint *offsets)
#define DICT_TF_FORMAT_ZIP
Definition: dict0mem.h:88
#define mem_heap_free(heap)
Definition: mem0mem.h:117
UNIV_INLINE void dfield_copy(dfield_t *field1, const dfield_t *field2)
UNIV_INTERN void dict_index_copy_types(dtuple_t *tuple, const dict_index_t *index, ulint n_fields)
Definition: dict0dict.cc:1932
UNIV_INLINE ulint dtuple_get_n_fields(const dtuple_t *tuple)
unsigned ord_part
Definition: dict0mem.h:303
UNIV_INLINE void btr_pcur_close(btr_pcur_t *cursor)
UNIV_INTERN void dict_table_copy_types(dtuple_t *tuple, const dict_table_t *table)
Definition: dict0dict.cc:1963
UNIV_INLINE ulint ut_min(ulint n1, ulint n2)
UNIV_INLINE ulint dict_index_get_n_unique_in_tree(const dict_index_t *index)
UNIV_INLINE ulint rec_get_nth_field_offs(const ulint *offsets, ulint n, ulint *len)
UNIV_INLINE void dfield_set_data(dfield_t *field, const void *data, ulint len)
UNIV_INLINE ulint dict_table_zip_size(const dict_table_t *table)
UNIV_INLINE ulint dfield_get_len(const dfield_t *field)
UNIV_INLINE ulint dict_table_get_format(const dict_table_t *table)
UNIV_INLINE ulint rec_offs_comp(const ulint *offsets)
UNIV_INTERN ulint innobase_raw_format(const char *data, ulint data_len, ulint, char *buf, ulint buf_size)
Definition: ha_innodb.cc:1518
UNIV_INTERN dtuple_t * row_rec_to_index_entry_low(const rec_t *rec, const dict_index_t *index, const ulint *offsets, ulint *n_ext, mem_heap_t *heap)
Definition: row0row.cc:324
UNIV_INTERN ulint row_raw_format(const char *data, ulint data_len, const dict_field_t *dict_field, char *buf, ulint buf_size)
Definition: row0row.cc:913
row_search_result
Definition: row0row.h:263
unsigned prefix_len
Definition: dict0mem.h:322
UNIV_INTERN enum row_search_result row_search_index_entry(dict_index_t *index, const dtuple_t *entry, ulint mode, btr_pcur_t *pcur, mtr_t *mtr)
Definition: row0row.cc:740
UNIV_INLINE ulint dict_col_get_no(const dict_col_t *col)
UNIV_INLINE ulint dict_index_is_clust(const dict_index_t *index) __attribute__((pure))
UNIV_INLINE ibool dtype_is_utf8(ulint prtype)
UNIV_INTERN ibool dtuple_check_typed(const dtuple_t *tuple)
#define ut_a(EXPR)
Definition: ut0dbg.h:105
UNIV_INLINE void dtuple_set_info_bits(dtuple_t *tuple, ulint info_bits)
UNIV_INTERN void ut_print_name(FILE *f, struct trx_struct *trx, ibool table_id, const char *name)
Definition: ut0ut.cc:528
UNIV_INLINE const dict_col_t * dict_field_get_col(const dict_field_t *field)
UNIV_INLINE void * mem_heap_alloc(mem_heap_t *heap, ulint n)
#define mem_heap_create(N)
Definition: mem0mem.h:97
dict_table_t * table
Definition: dict0mem.h:341
UNIV_INTERN void row_build_row_ref_in_tuple(dtuple_t *ref, const rec_t *rec, const dict_index_t *index, ulint *offsets, trx_t *trx)
Definition: row0row.cc:543
UNIV_INLINE ulint ut_str_sql_format(const char *str, ulint str_len, char *buf, ulint buf_size)
UNIV_INLINE ulint rec_offs_n_fields(const ulint *offsets)
#define DICT_UNIVERSAL
Definition: dict0mem.h:53
UNIV_INLINE const byte * row_ext_lookup(const row_ext_t *ext, ulint col, ulint *len)
UNIV_INTERN dtuple_t * row_build_row_ref(ulint type, dict_index_t *index, const rec_t *rec, mem_heap_t *heap)
Definition: row0row.cc:434
UNIV_INLINE ulint dfield_is_null(const dfield_t *field)
#define ut_ad(EXPR)
Definition: ut0dbg.h:127
UNIV_INLINE void dtuple_set_n_fields_cmp(dtuple_t *tuple, ulint n_fields_cmp)
UNIV_INLINE ulint dict_table_get_n_cols(const dict_table_t *table)
#define ut_error
Definition: ut0dbg.h:115
unsigned prtype
Definition: data0type.h:486
unsigned mbminmaxlen
Definition: data0type.h:505
#define BTR_EXTERN_FIELD_REF_SIZE
Definition: btr0types.h:170
UNIV_INLINE ulint dict_index_get_n_unique(const dict_index_t *index)
UNIV_INLINE ulint rec_offs_n_extern(const ulint *offsets)
const char * table_name
Definition: dict0mem.h:340
UNIV_INLINE ulint dtype_get_charset_coll(ulint prtype)
UNIV_INLINE ulint dict_index_get_sys_col_pos(const dict_index_t *index, ulint type)
dict_col_t * col
Definition: dict0mem.h:320
UNIV_INLINE ulint rec_get_info_bits(const rec_t *rec, ulint comp)
UNIV_INLINE ibool page_rec_is_infimum(const rec_t *rec) __attribute__((const ))
UNIV_INTERN dtuple_t * row_rec_to_index_entry(ulint type, const rec_t *rec, const dict_index_t *index, ulint *offsets, ulint *n_ext, mem_heap_t *heap)
Definition: row0row.cc:382
UNIV_INLINE ulint rec_offs_size(const ulint *offsets)
UNIV_INTERN ibool row_search_on_row_ref(btr_pcur_t *pcur, ulint mode, const dict_table_t *table, const dtuple_t *ref, mtr_t *mtr)
Definition: row0row.cc:655
UNIV_INLINE void dfield_set_ext(dfield_t *field)
UNIV_INLINE ulint ut_raw_to_hex(const void *raw, ulint raw_size, char *hex, ulint hex_size)
const byte field_ref_zero[BTR_EXTERN_FIELD_REF_SIZE]
Definition: btr0cur.cc:135
unsigned mbminmaxlen
Definition: dict0mem.h:292
UNIV_INLINE ullint mach_read_int_type(const byte *src, ulint len, ibool unsigned_type)
unsigned mtype
Definition: dict0mem.h:272
UNIV_INLINE ibool rec_offs_validate(const rec_t *rec, const dict_index_t *index, const ulint *offsets)