97
99
implementation-defined.
102
#include "drizzled/definitions.h"
103
#include "drizzled/internal/m_string.h"
104
#include "drizzled/charset_info.h"
105
#include "drizzled/decimal.h"
107
#include <plugin/myisam/myisampack.h>
108
#include <drizzled/util/test.h>
116
#include "drizzled/current_session.h"
117
#include "drizzled/error.h"
118
#include "drizzled/field.h"
119
#include "drizzled/internal/my_sys.h"
126
report result of decimal operation.
128
@param result decimal library return code (E_DEC_* see include/decimal.h)
137
int decimal_operation_results(int result)
142
case E_DEC_TRUNCATED:
143
push_warning_printf(current_session, DRIZZLE_ERROR::WARN_LEVEL_WARN,
144
ER_WARN_DATA_TRUNCATED, ER(ER_WARN_DATA_TRUNCATED),
148
push_warning_printf(current_session, DRIZZLE_ERROR::WARN_LEVEL_ERROR,
149
ER_TRUNCATED_WRONG_VALUE,
150
ER(ER_TRUNCATED_WRONG_VALUE),
154
push_warning_printf(current_session, DRIZZLE_ERROR::WARN_LEVEL_ERROR,
155
ER_DIVISION_BY_ZERO, ER(ER_DIVISION_BY_ZERO));
158
push_warning_printf(current_session, DRIZZLE_ERROR::WARN_LEVEL_ERROR,
159
ER_TRUNCATED_WRONG_VALUE_FOR_FIELD,
160
ER(ER_TRUNCATED_WRONG_VALUE_FOR_FIELD),
161
"decimal", "", "", (long)-1);
164
my_error(ER_OUT_OF_RESOURCES, MYF(0));
174
@brief Converting decimal to string
176
@details Convert given my_decimal to String; allocate buffer as needed.
178
@param[in] mask what problems to warn on (mask of E_DEC_* values)
179
@param[in] d the decimal to print
180
@param[in] fixed_prec overall number of digits if ZEROFILL, 0 otherwise
181
@param[in] fixed_dec number of decimal places (if fixed_prec != 0)
182
@param[in] filler what char to pad with (ZEROFILL et al.)
183
@param[out] *str where to store the resulting string
187
@retval E_DEC_TRUNCATED
188
@retval E_DEC_OVERFLOW
192
int my_decimal2string(uint32_t mask, const my_decimal *d,
193
uint32_t fixed_prec, uint32_t fixed_dec,
194
char filler, String *str)
197
Calculate the size of the string: For DECIMAL(a,b), fixed_prec==a
198
holds true iff the type is also ZEROFILL, which in turn implies
199
UNSIGNED. Hence the buffer for a ZEROFILLed value is the length
200
the user requested, plus one for a possible decimal point, plus
201
one if the user only wanted decimal places, but we force a leading
202
zero on them. Because the type is implicitly UNSIGNED, we do not
203
need to reserve a character for the sign. For all other cases,
204
fixed_prec will be 0, and my_decimal_string_length() will be called
205
instead to calculate the required size of the buffer.
207
int length= (fixed_prec
208
? (fixed_prec + ((fixed_prec == fixed_dec) ? 1 : 0) + 1)
209
: my_decimal_string_length(d));
211
if (str->alloc(length))
212
return check_result(mask, E_DEC_OOM);
213
result= decimal2string((decimal_t*) d, (char*) str->ptr(),
214
&length, (int)fixed_prec, fixed_dec,
217
return check_result(mask, result);
222
Convert from decimal to binary representation
226
mask error processing mask
227
d number for conversion
228
bin pointer to buffer where to write result
229
prec overall number of decimal digits
230
scale number of decimal digits after decimal point
233
Before conversion we round number if it need but produce truncation
242
int my_decimal2binary(uint32_t mask, const my_decimal *d, unsigned char *bin, int prec,
245
int err1= E_DEC_OK, err2;
247
my_decimal2decimal(d, &rounded);
248
rounded.frac= decimal_actual_fraction(&rounded);
249
if (scale < rounded.frac)
251
err1= E_DEC_TRUNCATED;
252
/* decimal_round can return only E_DEC_TRUNCATED */
253
decimal_round(&rounded, &rounded, scale, HALF_UP);
255
err2= decimal2bin(&rounded, bin, prec, scale);
258
return check_result(mask, err2);
263
Convert string for decimal when string can be in some multibyte charset
267
mask error processing mask
268
from string to process
269
length length of given string
270
charset charset of given string
271
decimal_value buffer for result storing
281
int str2my_decimal(uint32_t mask, const char *from, uint32_t length,
282
const CHARSET_INFO * charset, my_decimal *decimal_value)
284
char *end, *from_end;
286
char buff[STRING_BUFFER_USUAL_SIZE];
287
String tmp(buff, sizeof(buff), &my_charset_bin);
288
if (charset->mbminlen > 1)
290
uint32_t dummy_errors;
291
tmp.copy(from, length, charset, &my_charset_utf8_general_ci, &dummy_errors);
293
length= tmp.length();
294
charset= &my_charset_bin;
296
from_end= end= (char*) from+length;
297
err= string2decimal((char *)from, (decimal_t*) decimal_value, &end);
298
if (end != from_end && !err)
300
/* Give warning if there is something other than end space */
301
for ( ; end < from_end; end++)
303
if (!my_isspace(&my_charset_utf8_general_ci, *end))
305
err= E_DEC_TRUNCATED;
310
check_result_and_overflow(mask, err, decimal_value);
315
my_decimal *date2my_decimal(DRIZZLE_TIME *ltime, my_decimal *dec)
318
date = (ltime->year*100L + ltime->month)*100L + ltime->day;
319
if (ltime->time_type > DRIZZLE_TIMESTAMP_DATE)
320
date= ((date*100L + ltime->hour)*100L+ ltime->minute)*100L + ltime->second;
321
if (int2my_decimal(E_DEC_FATAL_ERROR, date, false, dec))
323
if (ltime->second_part)
325
dec->buf[(dec->intg-1) / 9 + 1]= ltime->second_part * 1000;
332
void my_decimal_trim(uint32_t *precision, uint32_t *scale)
334
if (!(*precision) && !(*scale))
102
#include <my_global.h>
104
#include <myisampack.h>
105
#include <my_sys.h> /* for my_alloca */
106
#include <m_string.h>
344
110
Internally decimal numbers are stored base 10^9 (see DIG_BASE below)
1884
static int do_add(const decimal_t *from1, const decimal_t *from2, decimal_t *to)
1657
Returns the size of the result of the operation
1660
decimal_result_size()
1661
from1 - operand of the unary operation or first operand of the
1663
from2 - second operand of the binary operation
1664
op - operation. one char '+', '-', '*', '/' are allowed
1665
others may be added later
1666
param - extra param to the operation. unused for '+', '-', '*'
1667
scale increment for '/'
1670
returned valued may be larger than the actual buffer requred
1671
in the operation, as decimal_result_size, by design, operates on
1672
precision/scale values only and not on the actual decimal number
1675
size of to->buf array in dec1 elements. to get size in bytes
1676
multiply by sizeof(dec1)
1679
int decimal_result_size(decimal_t *from1, decimal_t *from2, char op, int param)
1683
return ROUND_UP(max(from1->intg, from2->intg)) +
1684
ROUND_UP(max(from1->frac, from2->frac));
1686
return ROUND_UP(max(from1->intg, from2->intg)+1) +
1687
ROUND_UP(max(from1->frac, from2->frac));
1689
return ROUND_UP(from1->intg+from2->intg)+
1690
ROUND_UP(from1->frac)+ROUND_UP(from2->frac);
1692
return ROUND_UP(from1->intg+from2->intg+1+from1->frac+from2->frac+param);
1693
default: DBUG_ASSERT(0);
1695
return -1; /* shut up the warning */
1698
static int do_add(decimal_t *from1, decimal_t *from2, decimal_t *to)
1886
1700
int intg1=ROUND_UP(from1->intg), intg2=ROUND_UP(from2->intg),
1887
1701
frac1=ROUND_UP(from1->frac), frac2=ROUND_UP(from2->frac),
2109
int decimal_add(const decimal_t *from1, const decimal_t *from2, decimal_t *to)
1923
int decimal_add(decimal_t *from1, decimal_t *from2, decimal_t *to)
2111
1925
if (likely(from1->sign == from2->sign))
2112
1926
return do_add(from1, from2, to);
2113
1927
return do_sub(from1, from2, to);
2116
int decimal_sub(const decimal_t *from1, const decimal_t *from2, decimal_t *to)
1930
int decimal_sub(decimal_t *from1, decimal_t *from2, decimal_t *to)
2118
1932
if (likely(from1->sign == from2->sign))
2119
1933
return do_sub(from1, from2, to);
2120
1934
return do_add(from1, from2, to);
2123
int decimal_cmp(const decimal_t *from1, const decimal_t *from2)
1937
int decimal_cmp(decimal_t *from1, decimal_t *from2)
2125
1939
if (likely(from1->sign == from2->sign))
2126
1940
return do_sub(from1, from2, 0);
2127
1941
return from1->sign > from2->sign ? -1 : 1;
2130
int decimal_is_zero(const decimal_t *from)
1944
int decimal_is_zero(decimal_t *from)
2132
1946
dec1 *buf1=from->buf,
2133
1947
*end=buf1+ROUND_UP(from->intg)+ROUND_UP(from->frac);
2712
void test_ull2d(uint64_t from, const char *orig, int ex)
2525
void test_ull2d(ulonglong from, const char *orig, int ex)
2717
res=uint64_t2decimal(from, &a);
2718
internal::int64_t10_to_str(from,s,10);
2530
res=ulonglong2decimal(from, &a);
2531
longlong10_to_str(from,s,10);
2719
2532
printf("%-40s => res=%d ", s, res);
2720
2533
print_decimal(&a, orig, res, ex);
2724
void test_ll2d(int64_t from, const char *orig, int ex)
2537
void test_ll2d(longlong from, const char *orig, int ex)
2729
res=int64_t2decimal(from, &a);
2730
internal::int64_t10_to_str(from,s,-10);
2542
res=longlong2decimal(from, &a);
2543
longlong10_to_str(from,s,-10);
2731
2544
printf("%-40s => res=%d ", s, res);
2732
2545
print_decimal(&a, orig, res, ex);