diff options
Diffstat (limited to 'sql/my_decimal.h')
-rw-r--r-- | sql/my_decimal.h | 92 |
1 files changed, 55 insertions, 37 deletions
diff --git a/sql/my_decimal.h b/sql/my_decimal.h index ee023438f20..a5f2aaada09 100644 --- a/sql/my_decimal.h +++ b/sql/my_decimal.h @@ -1,4 +1,5 @@ -/* Copyright (C) 2005-2006 MySQL AB +/* + Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -11,9 +12,12 @@ You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software - Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +*/ + +/** + @file -/* It is interface module to fixed precision decimals library. Most functions use 'uint mask' as parameter, if during operation error @@ -34,13 +38,14 @@ C_MODE_END #define DECIMAL_LONG_DIGITS 10 #define DECIMAL_LONG3_DIGITS 8 -/* maximum length of buffer in our big digits (uint32) */ +/** maximum length of buffer in our big digits (uint32). */ #define DECIMAL_BUFF_LENGTH 9 /* the number of digits that my_decimal can possibly contain */ #define DECIMAL_MAX_POSSIBLE_PRECISION (DECIMAL_BUFF_LENGTH * 9) -/* + +/** maximum guaranteed precision of number in decimal digits (number of our digits * number of decimal digits in one our big digit - number of decimal digits in one our big digit decreased by 1 (because we always put decimal @@ -50,13 +55,14 @@ C_MODE_END #define DECIMAL_MAX_SCALE 30 #define DECIMAL_NOT_SPECIFIED 31 -/* +/** maximum length of string representation (number of maximum decimal - digits + 1 position for sign + 1 position for decimal point) + digits + 1 position for sign + 1 position for decimal point, no terminator) */ #define DECIMAL_MAX_STR_LENGTH (DECIMAL_MAX_POSSIBLE_PRECISION + 2) -/* - maximum size of packet length + +/** + maximum size of packet length. */ #define DECIMAL_MAX_FIELD_SIZE DECIMAL_MAX_PRECISION @@ -77,11 +83,12 @@ inline int my_decimal_int_part(uint precision, uint decimals) } -/* - my_decimal class limits 'decimal_t' type to what we need in MySQL +/** + my_decimal class limits 'decimal_t' type to what we need in MySQL. + It contains internally all necessary space needed by the instance so no extra memory is needed. One should call fix_buffer_pointer() function - when he moves my_decimal objects in memory + when he moves my_decimal objects in memory. */ class my_decimal :public decimal_t @@ -113,12 +120,8 @@ public: #endif len= DECIMAL_BUFF_LENGTH; buf= buffer; -#if !defined (HAVE_purify) && !defined(DBUG_OFF) - /* Set buffer to 'random' value to find wrong buffer usage */ - for (uint i= 0; i < DECIMAL_BUFF_LENGTH; i++) - buffer[i]= i; -#endif } + my_decimal() { init(); @@ -139,12 +142,20 @@ public: bool sign() const { return decimal_t::sign; } void sign(bool s) { decimal_t::sign= s; } uint precision() const { return intg + frac; } + + /** Swap two my_decimal values */ + void swap(my_decimal &rhs) + { + swap_variables(my_decimal, *this, rhs); + /* Swap the buffer pointers back */ + swap_variables(decimal_digit_t *, buf, rhs.buf); + } }; #ifndef DBUG_OFF void print_decimal(const my_decimal *dec); -void print_decimal_buff(const my_decimal *dec, const byte* ptr, int length); +void print_decimal_buff(const my_decimal *dec, const uchar* ptr, int length); const char *dbug_decimal_as_string(char *buff, const my_decimal *val); #else #define dbug_decimal_as_string(A) NULL @@ -200,6 +211,19 @@ inline uint my_decimal_length_to_precision(uint length, uint scale, (unsigned_flag || !length ? 0:1)); } +inline uint32 my_decimal_precision_to_length_no_truncation(uint precision, + uint8 scale, + bool unsigned_flag) +{ + /* + When precision is 0 it means that original length was also 0. Thus + unsigned_flag is ignored in this case. + */ + DBUG_ASSERT(precision || !scale); + return (uint32)(precision + (scale > 0 ? 1 : 0) + + (unsigned_flag || !precision ? 0 : 1)); +} + inline uint32 my_decimal_precision_to_length(uint precision, uint8 scale, bool unsigned_flag) { @@ -209,13 +233,14 @@ inline uint32 my_decimal_precision_to_length(uint precision, uint8 scale, */ DBUG_ASSERT(precision || !scale); set_if_smaller(precision, DECIMAL_MAX_PRECISION); - return (uint32)(precision + (scale>0 ? 1:0) + - (unsigned_flag || !precision ? 0:1)); + return my_decimal_precision_to_length_no_truncation(precision, scale, + unsigned_flag); } inline int my_decimal_string_length(const my_decimal *d) { + /* length of string representation including terminating '\0' */ return decimal_string_size(d); } @@ -243,16 +268,15 @@ void my_decimal2decimal(const my_decimal *from, my_decimal *to) } -int my_decimal2binary(uint mask, const my_decimal *d, char *bin, int prec, +int my_decimal2binary(uint mask, const my_decimal *d, uchar *bin, int prec, int scale); inline -int binary2my_decimal(uint mask, const char *bin, my_decimal *d, int prec, +int binary2my_decimal(uint mask, const uchar *bin, my_decimal *d, int prec, int scale) { - return check_result(mask, bin2decimal((char *)bin, (decimal_t*) d, prec, - scale)); + return check_result(mask, bin2decimal(bin, (decimal_t*) d, prec, scale)); } @@ -313,7 +337,7 @@ int my_decimal2int(uint mask, const my_decimal *d, my_bool unsigned_flag, inline -int my_decimal2double(uint mask, const my_decimal *d, double *result) +int my_decimal2double(uint, const my_decimal *d, double *result) { /* No need to call check_result as this will always succeed */ return decimal2double((decimal_t*) d, result); @@ -423,7 +447,10 @@ int my_decimal_mod(uint mask, my_decimal *res, const my_decimal *a, } -/* Returns -1 if a<b, 1 if a>b and 0 if a==b */ +/** + @return + -1 if a<b, 1 if a>b and 0 if a==b +*/ inline int my_decimal_cmp(const my_decimal *a, const my_decimal *b) { @@ -434,20 +461,11 @@ int my_decimal_cmp(const my_decimal *a, const my_decimal *b) inline int my_decimal_intg(const my_decimal *a) { - return decimal_intg((decimal_t*) a); + return decimal_intg((decimal_t*) a); } -inline -void my_decimal_trim(ulong *precision, uint *scale) -{ - if (!(*precision) && !(*scale)) - { - *precision= 10; - *scale= 0; - return; - } -} +void my_decimal_trim(ulong *precision, uint *scale); #endif /*my_decimal_h*/ |