summaryrefslogtreecommitdiff
path: root/sql/my_decimal.h
diff options
context:
space:
mode:
Diffstat (limited to 'sql/my_decimal.h')
-rw-r--r--sql/my_decimal.h92
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*/