From 8e343e91c953ed928e9b8cc36d7aea2245a2c6c1 Mon Sep 17 00:00:00 2001 From: Zardosht Kasheff Date: Wed, 17 Apr 2013 00:01:47 -0400 Subject: [PATCH] addresses #1619 check in some comparison code for integers. It is not running yet, that is the next step git-svn-id: file:///svn/mysql/tokudb-engine/src@10725 c7de825b-a66e-492c-adef-691d508d4ae1 --- storage/tokudb/ha_tokudb.cc | 13 +-- storage/tokudb/hatoku_cmp.cc | 157 +++++++++++++++++++++++++++++++++++ storage/tokudb/hatoku_cmp.h | 18 ++++ 3 files changed, 179 insertions(+), 9 deletions(-) diff --git a/storage/tokudb/ha_tokudb.cc b/storage/tokudb/ha_tokudb.cc index da7caffd20a..1efc90ec32b 100644 --- a/storage/tokudb/ha_tokudb.cc +++ b/storage/tokudb/ha_tokudb.cc @@ -1263,8 +1263,6 @@ void ha_tokudb::unpack_row(uchar * record, DBT const *row, DBT const *key, bool } } - - u_int32_t ha_tokudb::place_key_into_mysql_buff(KEY* key_info, uchar * record, uchar* data) { KEY_PART_INFO *key_part = key_info->key_part, *end = key_part + key_info->key_parts; uchar *pos = data; @@ -1272,10 +1270,10 @@ u_int32_t ha_tokudb::place_key_into_mysql_buff(KEY* key_info, uchar * record, uc for (; key_part != end; key_part++) { if (key_part->null_bit) { if (*pos++ == NULL_COL_VAL) { // Null value - /* - We don't need to reset the record data as we will not access it - if the null data is set - */ + // + // We don't need to reset the record data as we will not access it + // if the null data is set + // record[key_part->null_offset] |= key_part->null_bit; continue; } @@ -1320,9 +1318,6 @@ void ha_tokudb::unpack_key(uchar * record, DBT const *key, uint index) { } } - - - u_int32_t ha_tokudb::place_key_into_dbt_buff(KEY* key_info, uchar * buff, const uchar * record, bool* has_null, int key_length) { KEY_PART_INFO *key_part = key_info->key_part; KEY_PART_INFO *end = key_part + key_info->key_parts; diff --git a/storage/tokudb/hatoku_cmp.cc b/storage/tokudb/hatoku_cmp.cc index 6645fd9eb7d..4b0417dd6c5 100755 --- a/storage/tokudb/hatoku_cmp.cc +++ b/storage/tokudb/hatoku_cmp.cc @@ -6,6 +6,163 @@ extern "C" { #include "hatoku_cmp.h" +inline TOKU_TYPE mysql_to_toku_type (enum_field_types mysql_type) { + TOKU_TYPE ret_val = toku_type_unknown; + switch (mysql_type) { + case MYSQL_TYPE_LONG: + case MYSQL_TYPE_LONGLONG: + case MYSQL_TYPE_TINY: + case MYSQL_TYPE_SHORT: + case MYSQL_TYPE_INT24: + case MYSQL_TYPE_DATE: + case MYSQL_TYPE_DATETIME: + case MYSQL_TYPE_YEAR: + case MYSQL_TYPE_NEWDATE: + case MYSQL_TYPE_TIME: + case MYSQL_TYPE_TIMESTAMP: + ret_val = toku_type_int; + break; + default: + ret_val = toku_type_unknown; + } + return ret_val; +} + + + +// +// assuming MySQL in little endian, and we are storing in little endian +// +uchar* pack_toku_int (uchar* to_tokudb, uchar* from_mysql, int num_bytes) { + switch (num_bytes) { + case (1): + case (2): + case (3): + case (4): + case (8): + memcpy(to_tokudb, from_mysql, num_bytes); + default: + assert(false); + } + return to_tokudb+num_bytes; +} + +// +// assuming MySQL in little endian, and we are unpacking to little endian +// +uchar* unpack_toku_int(uchar* to_mysql, uchar* from_tokudb, int num_bytes) { + switch (num_bytes) { + case (1): + case (2): + case (3): + case (4): + case (8): + memcpy(to_mysql, from_tokudb, num_bytes); + default: + assert(false); + } + return from_tokudb+num_bytes; +} + +int cmp_toku_int (uchar* a, uchar* b, bool is_signed, int num_bytes) { + int ret_val = 0; + // + // case for unsigned integers + // + if (!is_signed) { + u_int32_t a_num, b_num = 0; + u_int64_t a_big_num, b_big_num = 0; + switch (num_bytes) { + case (1): + a_num = *a; + b_num = *b; + case (2): + a_num = uint2korr(a); + b_num = uint2korr(b); + case (3): + a_num = uint3korr(a); + b_num = uint3korr(b); + ret_val = a-b; + goto exit; + case (4): + a_num = uint4korr(a); + b_num = uint4korr(b); + if (a < b) { + ret_val = -1; goto exit; + } + if (a > b) { + ret_val = 1; goto exit; + } + ret_val = 0; + goto exit; + case (8): + a_big_num = uint8korr(a); + b_big_num = uint8korr(b); + if (a_big_num < b_big_num) { + ret_val = -1; goto exit; + } + else if (a_big_num > b_big_num) { + ret_val = 1; goto exit; + } + ret_val = 0; + goto exit; + default: + assert(false); + } + } + // + // case for signed integers + // + else { + int32_t a_num, b_num = 0; + int64_t a_big_num, b_big_num = 0; + switch (num_bytes) { + case (1): + a_num = *(signed char *)a; + b_num = *(signed char *)b; + case (2): + a_num = sint2korr(a); + b_num = sint2korr(b); + case (3): + a_num = sint3korr(a); + b_num = sint3korr(b); + ret_val = a-b; + goto exit; + case (4): + a_num = sint4korr(a); + b_num = sint4korr(b); + if (a_num < b_num) { + ret_val = -1; goto exit; + } + if (a_num > b_num) { + ret_val = 1; goto exit; + } + ret_val = 0; + goto exit; + case (8): + a_big_num = sint8korr(a); + b_big_num = sint8korr(b); + if (a_big_num < b_big_num) { + ret_val = -1; goto exit; + } + else if (a_big_num > b_big_num) { + ret_val = 1; goto exit; + } + ret_val = 0; + goto exit; + default: + assert(false); + } + } + // + // if this is hit, indicates bug in writing of this function + // + assert(false); +exit: + return ret_val; +} + + inline int tokudb_compare_two_hidden_keys( const void* new_key_data, const u_int32_t new_key_size, diff --git a/storage/tokudb/hatoku_cmp.h b/storage/tokudb/hatoku_cmp.h index 15075550440..c40187de93b 100755 --- a/storage/tokudb/hatoku_cmp.h +++ b/storage/tokudb/hatoku_cmp.h @@ -11,6 +11,24 @@ extern "C" { #include + + +typedef enum { + toku_type_int = 0, + toku_type_double, + toku_type_float, + toku_type_unknown +} TOKU_TYPE; + + +inline TOKU_TYPE mysql_to_toku_type (enum_field_types mysql_type); + + +uchar* pack_toku_int (uchar* to_tokudb, uchar* from_mysql, int num_bytes); +uchar* unpack_toku_int(uchar* to_mysql, uchar* from_tokudb, int num_bytes); +int cmp_toku_int (uchar* a, uchar* b, bool is_signed, int num_bytes); + + // // for storing NULL byte in keys //