00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00026 #include "row0row.h"
00027
00028 #ifdef UNIV_NONINL
00029 #include "row0row.ic"
00030 #endif
00031
00032 #include "data0type.h"
00033 #include "dict0dict.h"
00034 #include "btr0btr.h"
00035 #include "ha_prototypes.h"
00036 #include "mach0data.h"
00037 #include "trx0rseg.h"
00038 #include "trx0trx.h"
00039 #include "trx0roll.h"
00040 #include "trx0undo.h"
00041 #include "trx0purge.h"
00042 #include "trx0rec.h"
00043 #include "que0que.h"
00044 #include "row0ext.h"
00045 #include "row0upd.h"
00046 #include "rem0cmp.h"
00047 #include "read0read.h"
00048 #include "ut0mem.h"
00049
00050
00054 UNIV_INTERN
00055 ulint
00056 row_get_trx_id_offset(
00057
00058 const rec_t* ,
00060 dict_index_t* index,
00061 const ulint* offsets)
00062 {
00063 ulint pos;
00064 ulint offset;
00065 ulint len;
00066
00067 ut_ad(dict_index_is_clust(index));
00068 ut_ad(rec_offs_validate(rec, index, offsets));
00069
00070 pos = dict_index_get_sys_col_pos(index, DATA_TRX_ID);
00071
00072 offset = rec_get_nth_field_offs(offsets, pos, &len);
00073
00074 ut_ad(len == DATA_TRX_ID_LEN);
00075
00076 return(offset);
00077 }
00078
00079
00085 UNIV_INTERN
00086 dtuple_t*
00087 row_build_index_entry(
00088
00089 const dtuple_t* row,
00091 row_ext_t* ext,
00093 dict_index_t* index,
00094 mem_heap_t* heap)
00096 {
00097 dtuple_t* entry;
00098 ulint entry_len;
00099 ulint i;
00100
00101 ut_ad(row && index && heap);
00102 ut_ad(dtuple_check_typed(row));
00103
00104 entry_len = dict_index_get_n_fields(index);
00105 entry = dtuple_create(heap, entry_len);
00106
00107 if (UNIV_UNLIKELY(index->type & DICT_UNIVERSAL)) {
00108 dtuple_set_n_fields_cmp(entry, entry_len);
00109
00110
00111 ut_a(!ext);
00112 } else {
00113 dtuple_set_n_fields_cmp(
00114 entry, dict_index_get_n_unique_in_tree(index));
00115 }
00116
00117 for (i = 0; i < entry_len; i++) {
00118 const dict_field_t* ind_field
00119 = dict_index_get_nth_field(index, i);
00120 const dict_col_t* col
00121 = ind_field->col;
00122 ulint col_no
00123 = dict_col_get_no(col);
00124 dfield_t* dfield
00125 = dtuple_get_nth_field(entry, i);
00126 const dfield_t* dfield2
00127 = dtuple_get_nth_field(row, col_no);
00128 ulint len
00129 = dfield_get_len(dfield2);
00130
00131 dfield_copy(dfield, dfield2);
00132
00133 if (dfield_is_null(dfield) || ind_field->prefix_len == 0) {
00134 continue;
00135 }
00136
00137
00138
00139 ut_ad(col->ord_part);
00140
00141 if (UNIV_LIKELY_NULL(ext)) {
00142
00143 const byte* buf = row_ext_lookup(ext, col_no,
00144 &len);
00145 if (UNIV_LIKELY_NULL(buf)) {
00146 if (UNIV_UNLIKELY(buf == field_ref_zero)) {
00147 return(NULL);
00148 }
00149 dfield_set_data(dfield, buf, len);
00150 }
00151 } else if (dfield_is_ext(dfield)) {
00152 ut_a(len >= BTR_EXTERN_FIELD_REF_SIZE);
00153 len -= BTR_EXTERN_FIELD_REF_SIZE;
00154 ut_a(ind_field->prefix_len <= len
00155 || dict_index_is_clust(index));
00156 }
00157
00158 len = dtype_get_at_most_n_mbchars(
00159 col->prtype, col->mbminmaxlen,
00160 ind_field->prefix_len, len, static_cast<const char *>(dfield_get_data(dfield)));
00161 dfield_set_len(dfield, len);
00162 }
00163
00164 ut_ad(dtuple_check_typed(entry));
00165
00166 return(entry);
00167 }
00168
00169
00173 UNIV_INTERN
00174 dtuple_t*
00175 row_build(
00176
00177 ulint type,
00184 const dict_index_t* index,
00185 const rec_t* rec,
00194 const ulint* offsets,
00197 const dict_table_t* col_table,
00204 row_ext_t** ext,
00207 mem_heap_t* heap)
00209 {
00210 dtuple_t* row;
00211 const dict_table_t* table;
00212 ulint n_fields;
00213 ulint n_ext_cols;
00214 ulint* ext_cols = NULL;
00215 ulint len;
00216 ulint row_len;
00217 byte* buf;
00218 ulint i;
00219 ulint j;
00220 mem_heap_t* tmp_heap = NULL;
00221 ulint offsets_[REC_OFFS_NORMAL_SIZE];
00222 rec_offs_init(offsets_);
00223
00224 ut_ad(index && rec && heap);
00225 ut_ad(dict_index_is_clust(index));
00226
00227 if (!offsets) {
00228 offsets = rec_get_offsets(rec, index, offsets_,
00229 ULINT_UNDEFINED, &tmp_heap);
00230 } else {
00231 ut_ad(rec_offs_validate(rec, index, offsets));
00232 }
00233
00234 if (type != ROW_COPY_POINTERS) {
00235
00236 buf = static_cast<byte *>(mem_heap_alloc(heap, rec_offs_size(offsets)));
00237 rec = rec_copy(buf, rec, offsets);
00238
00239 rec_offs_make_valid(rec, index, (ulint*) offsets);
00240 }
00241
00242 table = index->table;
00243 row_len = dict_table_get_n_cols(table);
00244
00245 row = dtuple_create(heap, row_len);
00246
00247 dict_table_copy_types(row, table);
00248
00249 dtuple_set_info_bits(row, rec_get_info_bits(
00250 rec, dict_table_is_comp(table)));
00251
00252 n_fields = rec_offs_n_fields(offsets);
00253 n_ext_cols = rec_offs_n_extern(offsets);
00254 if (n_ext_cols) {
00255 ext_cols = static_cast<ulint *>(mem_heap_alloc(heap, n_ext_cols * sizeof *ext_cols));
00256 }
00257
00258 for (i = j = 0; i < n_fields; i++) {
00259 dict_field_t* ind_field
00260 = dict_index_get_nth_field(index, i);
00261 const dict_col_t* col
00262 = dict_field_get_col(ind_field);
00263 ulint col_no
00264 = dict_col_get_no(col);
00265 dfield_t* dfield
00266 = dtuple_get_nth_field(row, col_no);
00267
00268 if (ind_field->prefix_len == 0) {
00269
00270 const byte* field = rec_get_nth_field(
00271 rec, offsets, i, &len);
00272
00273 dfield_set_data(dfield, field, len);
00274 }
00275
00276 if (rec_offs_nth_extern(offsets, i)) {
00277 dfield_set_ext(dfield);
00278
00279 if (UNIV_LIKELY_NULL(col_table)) {
00280 ut_a(col_no
00281 < dict_table_get_n_cols(col_table));
00282 col = dict_table_get_nth_col(
00283 col_table, col_no);
00284 }
00285
00286 if (col->ord_part) {
00287
00288
00289
00290 ext_cols[j++] = col_no;
00291 }
00292 }
00293 }
00294
00295 ut_ad(dtuple_check_typed(row));
00296
00297 if (!ext) {
00298
00299
00300
00301 ut_ad(dict_table_get_format(index->table)
00302 < DICT_TF_FORMAT_ZIP);
00303 } else if (j) {
00304 *ext = row_ext_create(j, ext_cols, row,
00305 dict_table_zip_size(index->table),
00306 heap);
00307 } else {
00308 *ext = NULL;
00309 }
00310
00311 if (tmp_heap) {
00312 mem_heap_free(tmp_heap);
00313 }
00314
00315 return(row);
00316 }
00317
00318
00322 UNIV_INTERN
00323 dtuple_t*
00324 row_rec_to_index_entry_low(
00325
00326 const rec_t* rec,
00327 const dict_index_t* index,
00328 const ulint* offsets,
00329 ulint* n_ext,
00331 mem_heap_t* heap)
00333 {
00334 dtuple_t* entry;
00335 dfield_t* dfield;
00336 ulint i;
00337 const byte* field;
00338 ulint len;
00339 ulint rec_len;
00340
00341 ut_ad(rec && heap && index);
00342
00343
00344
00345 ut_ad(n_ext);
00346 *n_ext = 0;
00347
00348 rec_len = rec_offs_n_fields(offsets);
00349
00350 entry = dtuple_create(heap, rec_len);
00351
00352 dtuple_set_n_fields_cmp(entry,
00353 dict_index_get_n_unique_in_tree(index));
00354 ut_ad(rec_len == dict_index_get_n_fields(index));
00355
00356 dict_index_copy_types(entry, index, rec_len);
00357
00358 for (i = 0; i < rec_len; i++) {
00359
00360 dfield = dtuple_get_nth_field(entry, i);
00361 field = rec_get_nth_field(rec, offsets, i, &len);
00362
00363 dfield_set_data(dfield, field, len);
00364
00365 if (rec_offs_nth_extern(offsets, i)) {
00366 dfield_set_ext(dfield);
00367 (*n_ext)++;
00368 }
00369 }
00370
00371 ut_ad(dtuple_check_typed(entry));
00372
00373 return(entry);
00374 }
00375
00376
00380 UNIV_INTERN
00381 dtuple_t*
00382 row_rec_to_index_entry(
00383
00384 ulint type,
00390 const rec_t* rec,
00399 const dict_index_t* index,
00400 ulint* offsets,
00401 ulint* n_ext,
00403 mem_heap_t* heap)
00405 {
00406 dtuple_t* entry;
00407 byte* buf;
00408
00409 ut_ad(rec && heap && index);
00410 ut_ad(rec_offs_validate(rec, index, offsets));
00411
00412 if (type == ROW_COPY_DATA) {
00413
00414 buf = static_cast<byte *>(mem_heap_alloc(heap, rec_offs_size(offsets)));
00415 rec = rec_copy(buf, rec, offsets);
00416
00417 rec_offs_make_valid(rec, index, offsets);
00418 }
00419
00420 entry = row_rec_to_index_entry_low(rec, index, offsets, n_ext, heap);
00421
00422 dtuple_set_info_bits(entry,
00423 rec_get_info_bits(rec, rec_offs_comp(offsets)));
00424
00425 return(entry);
00426 }
00427
00428
00432 UNIV_INTERN
00433 dtuple_t*
00434 row_build_row_ref(
00435
00436 ulint type,
00440 dict_index_t* index,
00441 const rec_t* rec,
00448 mem_heap_t* heap)
00450 {
00451 dict_table_t* table;
00452 dict_index_t* clust_index;
00453 dfield_t* dfield;
00454 dtuple_t* ref;
00455 const byte* field;
00456 ulint len;
00457 ulint ref_len;
00458 ulint pos;
00459 byte* buf;
00460 ulint clust_col_prefix_len;
00461 ulint i;
00462 mem_heap_t* tmp_heap = NULL;
00463 ulint offsets_[REC_OFFS_NORMAL_SIZE];
00464 ulint* offsets = offsets_;
00465 rec_offs_init(offsets_);
00466
00467 ut_ad(index && rec && heap);
00468 ut_ad(!dict_index_is_clust(index));
00469
00470 offsets = rec_get_offsets(rec, index, offsets,
00471 ULINT_UNDEFINED, &tmp_heap);
00472
00473 ut_ad(!rec_offs_any_extern(offsets));
00474
00475 if (type == ROW_COPY_DATA) {
00476
00477
00478 buf = static_cast<byte *>(mem_heap_alloc(heap, rec_offs_size(offsets)));
00479
00480 rec = rec_copy(buf, rec, offsets);
00481
00482 rec_offs_make_valid(rec, index, offsets);
00483 }
00484
00485 table = index->table;
00486
00487 clust_index = dict_table_get_first_index(table);
00488
00489 ref_len = dict_index_get_n_unique(clust_index);
00490
00491 ref = dtuple_create(heap, ref_len);
00492
00493 dict_index_copy_types(ref, clust_index, ref_len);
00494
00495 for (i = 0; i < ref_len; i++) {
00496 dfield = dtuple_get_nth_field(ref, i);
00497
00498 pos = dict_index_get_nth_field_pos(index, clust_index, i);
00499
00500 ut_a(pos != ULINT_UNDEFINED);
00501
00502 field = rec_get_nth_field(rec, offsets, pos, &len);
00503
00504 dfield_set_data(dfield, field, len);
00505
00506
00507
00508
00509
00510
00511 clust_col_prefix_len = dict_index_get_nth_field(
00512 clust_index, i)->prefix_len;
00513
00514 if (clust_col_prefix_len > 0) {
00515 if (len != UNIV_SQL_NULL) {
00516
00517 const dtype_t* dtype
00518 = dfield_get_type(dfield);
00519
00520 dfield_set_len(dfield,
00521 dtype_get_at_most_n_mbchars(
00522 dtype->prtype,
00523 dtype->mbminmaxlen,
00524 clust_col_prefix_len,
00525 len, (char*) field));
00526 }
00527 }
00528 }
00529
00530 ut_ad(dtuple_check_typed(ref));
00531 if (tmp_heap) {
00532 mem_heap_free(tmp_heap);
00533 }
00534
00535 return(ref);
00536 }
00537
00538
00541 UNIV_INTERN
00542 void
00543 row_build_row_ref_in_tuple(
00544
00545 dtuple_t* ref,
00547 const rec_t* rec,
00555 const dict_index_t* index,
00556 ulint* offsets,
00558 trx_t* trx)
00559 {
00560 const dict_index_t* clust_index;
00561 dfield_t* dfield;
00562 const byte* field;
00563 ulint len;
00564 ulint ref_len;
00565 ulint pos;
00566 ulint clust_col_prefix_len;
00567 ulint i;
00568 mem_heap_t* heap = NULL;
00569 ulint offsets_[REC_OFFS_NORMAL_SIZE];
00570 rec_offs_init(offsets_);
00571
00572 ut_a(ref);
00573 ut_a(index);
00574 ut_a(rec);
00575 ut_ad(!dict_index_is_clust(index));
00576
00577 if (UNIV_UNLIKELY(!index->table)) {
00578 fputs("InnoDB: table ", stderr);
00579 notfound:
00580 ut_print_name(stderr, trx, TRUE, index->table_name);
00581 fputs(" for index ", stderr);
00582 ut_print_name(stderr, trx, FALSE, index->name);
00583 fputs(" not found\n", stderr);
00584 ut_error;
00585 }
00586
00587 clust_index = dict_table_get_first_index(index->table);
00588
00589 if (UNIV_UNLIKELY(!clust_index)) {
00590 fputs("InnoDB: clust index for table ", stderr);
00591 goto notfound;
00592 }
00593
00594 if (!offsets) {
00595 offsets = rec_get_offsets(rec, index, offsets_,
00596 ULINT_UNDEFINED, &heap);
00597 } else {
00598 ut_ad(rec_offs_validate(rec, index, offsets));
00599 }
00600
00601
00602 ut_ad(!rec_offs_any_extern(offsets));
00603 ref_len = dict_index_get_n_unique(clust_index);
00604
00605 ut_ad(ref_len == dtuple_get_n_fields(ref));
00606
00607 dict_index_copy_types(ref, clust_index, ref_len);
00608
00609 for (i = 0; i < ref_len; i++) {
00610 dfield = dtuple_get_nth_field(ref, i);
00611
00612 pos = dict_index_get_nth_field_pos(index, clust_index, i);
00613
00614 ut_a(pos != ULINT_UNDEFINED);
00615
00616 field = rec_get_nth_field(rec, offsets, pos, &len);
00617
00618 dfield_set_data(dfield, field, len);
00619
00620
00621
00622
00623
00624
00625 clust_col_prefix_len = dict_index_get_nth_field(
00626 clust_index, i)->prefix_len;
00627
00628 if (clust_col_prefix_len > 0) {
00629 if (len != UNIV_SQL_NULL) {
00630
00631 const dtype_t* dtype
00632 = dfield_get_type(dfield);
00633
00634 dfield_set_len(dfield,
00635 dtype_get_at_most_n_mbchars(
00636 dtype->prtype,
00637 dtype->mbminmaxlen,
00638 clust_col_prefix_len,
00639 len, (char*) field));
00640 }
00641 }
00642 }
00643
00644 ut_ad(dtuple_check_typed(ref));
00645 if (UNIV_LIKELY_NULL(heap)) {
00646 mem_heap_free(heap);
00647 }
00648 }
00649
00650
00653 UNIV_INTERN
00654 ibool
00655 row_search_on_row_ref(
00656
00657 btr_pcur_t* pcur,
00659 ulint mode,
00660 const dict_table_t* table,
00661 const dtuple_t* ref,
00662 mtr_t* mtr)
00663 {
00664 ulint low_match;
00665 rec_t* rec;
00666 dict_index_t* index;
00667
00668 ut_ad(dtuple_check_typed(ref));
00669
00670 index = dict_table_get_first_index(table);
00671
00672 ut_a(dtuple_get_n_fields(ref) == dict_index_get_n_unique(index));
00673
00674 btr_pcur_open(index, ref, PAGE_CUR_LE, mode, pcur, mtr);
00675
00676 low_match = btr_pcur_get_low_match(pcur);
00677
00678 rec = btr_pcur_get_rec(pcur);
00679
00680 if (page_rec_is_infimum(rec)) {
00681
00682 return(FALSE);
00683 }
00684
00685 if (low_match != dtuple_get_n_fields(ref)) {
00686
00687 return(FALSE);
00688 }
00689
00690 return(TRUE);
00691 }
00692
00693
00697 UNIV_INTERN
00698 rec_t*
00699 row_get_clust_rec(
00700
00701 ulint mode,
00702 const rec_t* rec,
00703 dict_index_t* index,
00704 dict_index_t** clust_index,
00705 mtr_t* mtr)
00706 {
00707 mem_heap_t* heap;
00708 dtuple_t* ref;
00709 dict_table_t* table;
00710 btr_pcur_t pcur;
00711 ibool found;
00712 rec_t* clust_rec;
00713
00714 ut_ad(!dict_index_is_clust(index));
00715
00716 table = index->table;
00717
00718 heap = mem_heap_create(256);
00719
00720 ref = row_build_row_ref(ROW_COPY_POINTERS, index, rec, heap);
00721
00722 found = row_search_on_row_ref(&pcur, mode, table, ref, mtr);
00723
00724 clust_rec = found ? btr_pcur_get_rec(&pcur) : NULL;
00725
00726 mem_heap_free(heap);
00727
00728 btr_pcur_close(&pcur);
00729
00730 *clust_index = dict_table_get_first_index(table);
00731
00732 return(clust_rec);
00733 }
00734
00735
00738 UNIV_INTERN
00739 enum row_search_result
00740 row_search_index_entry(
00741
00742 dict_index_t* index,
00743 const dtuple_t* entry,
00744 ulint mode,
00745 btr_pcur_t* pcur,
00747 mtr_t* mtr)
00748 {
00749 ulint n_fields;
00750 ulint low_match;
00751 rec_t* rec;
00752
00753 ut_ad(dtuple_check_typed(entry));
00754
00755 btr_pcur_open(index, entry, PAGE_CUR_LE, mode, pcur, mtr);
00756
00757 switch (btr_pcur_get_btr_cur(pcur)->flag) {
00758 case BTR_CUR_DELETE_REF:
00759 ut_a(mode & BTR_DELETE);
00760 return(ROW_NOT_DELETED_REF);
00761
00762 case BTR_CUR_DEL_MARK_IBUF:
00763 case BTR_CUR_DELETE_IBUF:
00764 case BTR_CUR_INSERT_TO_IBUF:
00765 return(ROW_BUFFERED);
00766
00767 case BTR_CUR_HASH:
00768 case BTR_CUR_HASH_FAIL:
00769 case BTR_CUR_BINARY:
00770 break;
00771 }
00772
00773 low_match = btr_pcur_get_low_match(pcur);
00774
00775 rec = btr_pcur_get_rec(pcur);
00776
00777 n_fields = dtuple_get_n_fields(entry);
00778
00779 if (page_rec_is_infimum(rec)) {
00780
00781 return(ROW_NOT_FOUND);
00782 } else if (low_match != n_fields) {
00783
00784 return(ROW_NOT_FOUND);
00785 }
00786
00787 return(ROW_FOUND);
00788 }
00789
00790 #if !defined(BUILD_DRIZZLE)
00791 # include "my_sys.h"
00792 #endif
00793
00794
00795
00806 static
00807 ulint
00808 row_raw_format_int(
00809
00810 const char* data,
00811 ulint data_len,
00813 ulint prtype,
00814 char* buf,
00815 ulint buf_size,
00817 ibool* format_in_hex)
00819 {
00820 ulint ret;
00821
00822 if (data_len <= sizeof(ullint)) {
00823
00824 ullint value;
00825 ibool unsigned_type = prtype & DATA_UNSIGNED;
00826
00827 value = mach_read_int_type((const byte*) data,
00828 data_len, unsigned_type);
00829
00830 if (unsigned_type) {
00831
00832 ret = ut_snprintf(buf, buf_size, "%llu",
00833 value) + 1;
00834 } else {
00835
00836 ret = ut_snprintf(buf, buf_size, "%lld",
00837 (long long) value) + 1;
00838 }
00839
00840 } else {
00841
00842 *format_in_hex = TRUE;
00843 ret = 0;
00844 }
00845
00846 return(ut_min(ret, buf_size));
00847 }
00848
00849
00861 static
00862 ulint
00863 row_raw_format_str(
00864
00865 const char* data,
00866 ulint data_len,
00868 ulint prtype,
00869 char* buf,
00870 ulint buf_size,
00872 ibool* format_in_hex)
00874 {
00875 ulint charset_coll;
00876
00877 if (buf_size == 0) {
00878
00879 return(0);
00880 }
00881
00882
00883
00884 charset_coll = dtype_get_charset_coll(prtype);
00885
00886 if (UNIV_LIKELY(dtype_is_utf8(prtype))) {
00887
00888 return(ut_str_sql_format(data, data_len, buf, buf_size));
00889 }
00890
00891
00892 if (charset_coll == DATA_MYSQL_BINARY_CHARSET_COLL) {
00893
00894 *format_in_hex = TRUE;
00895 return(0);
00896 }
00897
00898
00899 return(innobase_raw_format(data, data_len, charset_coll,
00900 buf, buf_size));
00901 }
00902
00903
00911 UNIV_INTERN
00912 ulint
00913 row_raw_format(
00914
00915 const char* data,
00916 ulint data_len,
00918 const dict_field_t* dict_field,
00919 char* buf,
00920 ulint buf_size)
00922 {
00923 ulint mtype;
00924 ulint prtype;
00925 ulint ret= 0;
00926 ibool format_in_hex;
00927
00928 if (buf_size == 0) {
00929
00930 return(ret);
00931 }
00932
00933 if (data_len == UNIV_SQL_NULL) {
00934
00935 ret = ut_snprintf((char*) buf, buf_size, "NULL") + 1;
00936
00937 return(ut_min(ret, buf_size));
00938 }
00939
00940 mtype = dict_field->col->mtype;
00941 prtype = dict_field->col->prtype;
00942
00943 format_in_hex = FALSE;
00944
00945 switch (mtype) {
00946 case DATA_INT:
00947
00948 ret = row_raw_format_int(data, data_len, prtype,
00949 buf, buf_size, &format_in_hex);
00950 if (format_in_hex) {
00951
00952 goto format_in_hex;
00953 }
00954 break;
00955 case DATA_CHAR:
00956 case DATA_VARCHAR:
00957 case DATA_MYSQL:
00958 case DATA_VARMYSQL:
00959
00960 ret = row_raw_format_str(data, data_len, prtype,
00961 buf, buf_size, &format_in_hex);
00962 if (format_in_hex) {
00963
00964 goto format_in_hex;
00965 }
00966
00967 break;
00968
00969 default:
00970 format_in_hex:
00971
00972 if (UNIV_LIKELY(buf_size > 2)) {
00973
00974 memcpy(buf, "0x", 2);
00975 buf += 2;
00976 buf_size -= 2;
00977 ret = 2 + ut_raw_to_hex(data, data_len,
00978 buf, buf_size);
00979 } else {
00980
00981 buf[0] = '\0';
00982 ret = 1;
00983 }
00984 }
00985
00986 return(ret);
00987 }
00988
00989 #ifdef UNIV_COMPILE_TEST_FUNCS
00990
00991 #include "ut0dbg.h"
00992
00993 void
00994 test_row_raw_format_int()
00995 {
00996 ulint ret;
00997 char buf[128];
00998 ibool format_in_hex;
00999
01000 #define CALL_AND_TEST(data, data_len, prtype, buf, buf_size,\
01001 ret_expected, buf_expected, format_in_hex_expected)\
01002 do {\
01003 ibool ok = TRUE;\
01004 ulint i;\
01005 memset(buf, 'x', 10);\
01006 buf[10] = '\0';\
01007 format_in_hex = FALSE;\
01008 fprintf(stderr, "TESTING \"\\x");\
01009 for (i = 0; i < data_len; i++) {\
01010 fprintf(stderr, "%02hhX", data[i]);\
01011 }\
01012 fprintf(stderr, "\", %lu, %lu, %lu\n",\
01013 (ulint) data_len, (ulint) prtype,\
01014 (ulint) buf_size);\
01015 ret = row_raw_format_int(data, data_len, prtype,\
01016 buf, buf_size, &format_in_hex);\
01017 if (ret != ret_expected) {\
01018 fprintf(stderr, "expected ret %lu, got %lu\n",\
01019 (ulint) ret_expected, ret);\
01020 ok = FALSE;\
01021 }\
01022 if (strcmp((char*) buf, buf_expected) != 0) {\
01023 fprintf(stderr, "expected buf \"%s\", got \"%s\"\n",\
01024 buf_expected, buf);\
01025 ok = FALSE;\
01026 }\
01027 if (format_in_hex != format_in_hex_expected) {\
01028 fprintf(stderr, "expected format_in_hex %d, got %d\n",\
01029 (int) format_in_hex_expected,\
01030 (int) format_in_hex);\
01031 ok = FALSE;\
01032 }\
01033 if (ok) {\
01034 fprintf(stderr, "OK: %lu, \"%s\" %d\n\n",\
01035 (ulint) ret, buf, (int) format_in_hex);\
01036 } else {\
01037 return;\
01038 }\
01039 } while (0)
01040
01041 #if 1
01042
01043
01044 CALL_AND_TEST("\x00", 1, 0,
01045 buf, sizeof(buf), 5, "-128", 0);
01046
01047 CALL_AND_TEST("\x00\x00", 2, 0,
01048 buf, sizeof(buf), 7, "-32768", 0);
01049
01050 CALL_AND_TEST("\x00\x00\x00", 3, 0,
01051 buf, sizeof(buf), 9, "-8388608", 0);
01052
01053 CALL_AND_TEST("\x00\x00\x00\x00", 4, 0,
01054 buf, sizeof(buf), 12, "-2147483648", 0);
01055
01056 CALL_AND_TEST("\x00\x00\x00\x00\x00", 5, 0,
01057 buf, sizeof(buf), 14, "-549755813888", 0);
01058
01059 CALL_AND_TEST("\x00\x00\x00\x00\x00\x00", 6, 0,
01060 buf, sizeof(buf), 17, "-140737488355328", 0);
01061
01062 CALL_AND_TEST("\x00\x00\x00\x00\x00\x00\x00", 7, 0,
01063 buf, sizeof(buf), 19, "-36028797018963968", 0);
01064
01065 CALL_AND_TEST("\x00\x00\x00\x00\x00\x00\x00\x00", 8, 0,
01066 buf, sizeof(buf), 21, "-9223372036854775808", 0);
01067
01068
01069
01070 CALL_AND_TEST("\x00", 1, DATA_UNSIGNED,
01071 buf, sizeof(buf), 2, "0", 0);
01072
01073 CALL_AND_TEST("\x00\x00", 2, DATA_UNSIGNED,
01074 buf, sizeof(buf), 2, "0", 0);
01075
01076 CALL_AND_TEST("\x00\x00\x00", 3, DATA_UNSIGNED,
01077 buf, sizeof(buf), 2, "0", 0);
01078
01079 CALL_AND_TEST("\x00\x00\x00\x00", 4, DATA_UNSIGNED,
01080 buf, sizeof(buf), 2, "0", 0);
01081
01082 CALL_AND_TEST("\x00\x00\x00\x00\x00", 5, DATA_UNSIGNED,
01083 buf, sizeof(buf), 2, "0", 0);
01084
01085 CALL_AND_TEST("\x00\x00\x00\x00\x00\x00", 6, DATA_UNSIGNED,
01086 buf, sizeof(buf), 2, "0", 0);
01087
01088 CALL_AND_TEST("\x00\x00\x00\x00\x00\x00\x00", 7, DATA_UNSIGNED,
01089 buf, sizeof(buf), 2, "0", 0);
01090
01091 CALL_AND_TEST("\x00\x00\x00\x00\x00\x00\x00\x00", 8, DATA_UNSIGNED,
01092 buf, sizeof(buf), 2, "0", 0);
01093
01094
01095
01096 CALL_AND_TEST("\xFF", 1, 0,
01097 buf, sizeof(buf), 4, "127", 0);
01098
01099 CALL_AND_TEST("\xFF\xFF", 2, 0,
01100 buf, sizeof(buf), 6, "32767", 0);
01101
01102 CALL_AND_TEST("\xFF\xFF\xFF", 3, 0,
01103 buf, sizeof(buf), 8, "8388607", 0);
01104
01105 CALL_AND_TEST("\xFF\xFF\xFF\xFF", 4, 0,
01106 buf, sizeof(buf), 11, "2147483647", 0);
01107
01108 CALL_AND_TEST("\xFF\xFF\xFF\xFF\xFF", 5, 0,
01109 buf, sizeof(buf), 13, "549755813887", 0);
01110
01111 CALL_AND_TEST("\xFF\xFF\xFF\xFF\xFF\xFF", 6, 0,
01112 buf, sizeof(buf), 16, "140737488355327", 0);
01113
01114 CALL_AND_TEST("\xFF\xFF\xFF\xFF\xFF\xFF\xFF", 7, 0,
01115 buf, sizeof(buf), 18, "36028797018963967", 0);
01116
01117 CALL_AND_TEST("\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF", 8, 0,
01118 buf, sizeof(buf), 20, "9223372036854775807", 0);
01119
01120
01121
01122 CALL_AND_TEST("\xFF", 1, DATA_UNSIGNED,
01123 buf, sizeof(buf), 4, "255", 0);
01124
01125 CALL_AND_TEST("\xFF\xFF", 2, DATA_UNSIGNED,
01126 buf, sizeof(buf), 6, "65535", 0);
01127
01128 CALL_AND_TEST("\xFF\xFF\xFF", 3, DATA_UNSIGNED,
01129 buf, sizeof(buf), 9, "16777215", 0);
01130
01131 CALL_AND_TEST("\xFF\xFF\xFF\xFF", 4, DATA_UNSIGNED,
01132 buf, sizeof(buf), 11, "4294967295", 0);
01133
01134 CALL_AND_TEST("\xFF\xFF\xFF\xFF\xFF", 5, DATA_UNSIGNED,
01135 buf, sizeof(buf), 14, "1099511627775", 0);
01136
01137 CALL_AND_TEST("\xFF\xFF\xFF\xFF\xFF\xFF", 6, DATA_UNSIGNED,
01138 buf, sizeof(buf), 16, "281474976710655", 0);
01139
01140 CALL_AND_TEST("\xFF\xFF\xFF\xFF\xFF\xFF\xFF", 7, DATA_UNSIGNED,
01141 buf, sizeof(buf), 18, "72057594037927935", 0);
01142
01143 CALL_AND_TEST("\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF", 8, DATA_UNSIGNED,
01144 buf, sizeof(buf), 21, "18446744073709551615", 0);
01145
01146
01147
01148 CALL_AND_TEST("\x52", 1, 0,
01149 buf, sizeof(buf), 4, "-46", 0);
01150
01151 CALL_AND_TEST("\x0E", 1, DATA_UNSIGNED,
01152 buf, sizeof(buf), 3, "14", 0);
01153
01154 CALL_AND_TEST("\x62\xCE", 2, 0,
01155 buf, sizeof(buf), 6, "-7474", 0);
01156
01157 CALL_AND_TEST("\x29\xD6", 2, DATA_UNSIGNED,
01158 buf, sizeof(buf), 6, "10710", 0);
01159
01160 CALL_AND_TEST("\x7F\xFF\x90", 3, 0,
01161 buf, sizeof(buf), 5, "-112", 0);
01162
01163 CALL_AND_TEST("\x00\xA1\x16", 3, DATA_UNSIGNED,
01164 buf, sizeof(buf), 6, "41238", 0);
01165
01166 CALL_AND_TEST("\x7F\xFF\xFF\xF7", 4, 0,
01167 buf, sizeof(buf), 3, "-9", 0);
01168
01169 CALL_AND_TEST("\x00\x00\x00\x5C", 4, DATA_UNSIGNED,
01170 buf, sizeof(buf), 3, "92", 0);
01171
01172 CALL_AND_TEST("\x7F\xFF\xFF\xFF\xFF\xFF\xDC\x63", 8, 0,
01173 buf, sizeof(buf), 6, "-9117", 0);
01174
01175 CALL_AND_TEST("\x00\x00\x00\x00\x00\x01\x64\x62", 8, DATA_UNSIGNED,
01176 buf, sizeof(buf), 6, "91234", 0);
01177 #endif
01178
01179
01180
01181 speedo_t speedo;
01182 ulint i;
01183
01184 speedo_reset(&speedo);
01185
01186 for (i = 0; i < 1000000; i++) {
01187 row_raw_format_int("\x23", 1,
01188 0, buf, sizeof(buf),
01189 &format_in_hex);
01190 row_raw_format_int("\x23", 1,
01191 DATA_UNSIGNED, buf, sizeof(buf),
01192 &format_in_hex);
01193
01194 row_raw_format_int("\x00\x00\x00\x00\x00\x01\x64\x62", 8,
01195 0, buf, sizeof(buf),
01196 &format_in_hex);
01197 row_raw_format_int("\x00\x00\x00\x00\x00\x01\x64\x62", 8,
01198 DATA_UNSIGNED, buf, sizeof(buf),
01199 &format_in_hex);
01200 }
01201
01202 speedo_show(&speedo);
01203 }
01204
01205 #endif