1
/* Copyright (C) 2005-2006 MySQL AB
3
This program is free software; you can redistribute it and/or modify
4
it under the terms of the GNU General Public License as published by
5
the Free Software Foundation; version 2 of the License.
7
This program is distributed in the hope that it will be useful,
8
but WITHOUT ANY WARRANTY; without even the implied warranty of
9
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10
GNU General Public License for more details.
12
You should have received a copy of the GNU General Public License
13
along with this program; if not, write to the Free Software
14
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
18
#include "drizzled/current_session.h"
19
#include "drizzled/error.h"
20
#include "drizzled/field.h"
21
#include "drizzled/internal/my_sys.h"
24
report result of decimal operation.
26
@param result decimal library return code (E_DEC_* see include/decimal.h)
35
int decimal_operation_results(int result)
41
push_warning_printf(current_session, DRIZZLE_ERROR::WARN_LEVEL_WARN,
42
ER_WARN_DATA_TRUNCATED, ER(ER_WARN_DATA_TRUNCATED),
46
push_warning_printf(current_session, DRIZZLE_ERROR::WARN_LEVEL_ERROR,
47
ER_TRUNCATED_WRONG_VALUE,
48
ER(ER_TRUNCATED_WRONG_VALUE),
52
push_warning_printf(current_session, DRIZZLE_ERROR::WARN_LEVEL_ERROR,
53
ER_DIVISION_BY_ZERO, ER(ER_DIVISION_BY_ZERO));
56
push_warning_printf(current_session, DRIZZLE_ERROR::WARN_LEVEL_ERROR,
57
ER_TRUNCATED_WRONG_VALUE_FOR_FIELD,
58
ER(ER_TRUNCATED_WRONG_VALUE_FOR_FIELD),
59
"decimal", "", "", (long)-1);
62
my_error(ER_OUT_OF_RESOURCES, MYF(0));
72
@brief Converting decimal to string
74
@details Convert given my_decimal to String; allocate buffer as needed.
76
@param[in] mask what problems to warn on (mask of E_DEC_* values)
77
@param[in] d the decimal to print
78
@param[in] fixed_prec overall number of digits if ZEROFILL, 0 otherwise
79
@param[in] fixed_dec number of decimal places (if fixed_prec != 0)
80
@param[in] filler what char to pad with (ZEROFILL et al.)
81
@param[out] *str where to store the resulting string
85
@retval E_DEC_TRUNCATED
86
@retval E_DEC_OVERFLOW
90
int my_decimal2string(uint32_t mask, const my_decimal *d,
91
uint32_t fixed_prec, uint32_t fixed_dec,
92
char filler, String *str)
95
Calculate the size of the string: For DECIMAL(a,b), fixed_prec==a
96
holds true iff the type is also ZEROFILL, which in turn implies
97
UNSIGNED. Hence the buffer for a ZEROFILLed value is the length
98
the user requested, plus one for a possible decimal point, plus
99
one if the user only wanted decimal places, but we force a leading
100
zero on them. Because the type is implicitly UNSIGNED, we do not
101
need to reserve a character for the sign. For all other cases,
102
fixed_prec will be 0, and my_decimal_string_length() will be called
103
instead to calculate the required size of the buffer.
105
int length= (fixed_prec
106
? (fixed_prec + ((fixed_prec == fixed_dec) ? 1 : 0) + 1)
107
: my_decimal_string_length(d));
109
if (str->alloc(length))
110
return check_result(mask, E_DEC_OOM);
111
result= decimal2string((decimal_t*) d, (char*) str->ptr(),
112
&length, (int)fixed_prec, fixed_dec,
115
return check_result(mask, result);
120
Convert from decimal to binary representation
124
mask error processing mask
125
d number for conversion
126
bin pointer to buffer where to write result
127
prec overall number of decimal digits
128
scale number of decimal digits after decimal point
131
Before conversion we round number if it need but produce truncation
140
int my_decimal2binary(uint32_t mask, const my_decimal *d, unsigned char *bin, int prec,
143
int err1= E_DEC_OK, err2;
145
my_decimal2decimal(d, &rounded);
146
rounded.frac= decimal_actual_fraction(&rounded);
147
if (scale < rounded.frac)
149
err1= E_DEC_TRUNCATED;
150
/* decimal_round can return only E_DEC_TRUNCATED */
151
decimal_round(&rounded, &rounded, scale, HALF_UP);
153
err2= decimal2bin(&rounded, bin, prec, scale);
156
return check_result(mask, err2);
161
Convert string for decimal when string can be in some multibyte charset
165
mask error processing mask
166
from string to process
167
length length of given string
168
charset charset of given string
169
decimal_value buffer for result storing
179
int str2my_decimal(uint32_t mask, const char *from, uint32_t length,
180
const CHARSET_INFO * charset, my_decimal *decimal_value)
182
char *end, *from_end;
184
char buff[STRING_BUFFER_USUAL_SIZE];
185
String tmp(buff, sizeof(buff), &my_charset_bin);
186
if (charset->mbminlen > 1)
188
uint32_t dummy_errors;
189
tmp.copy(from, length, charset, &my_charset_utf8_general_ci, &dummy_errors);
191
length= tmp.length();
192
charset= &my_charset_bin;
194
from_end= end= (char*) from+length;
195
err= string2decimal((char *)from, (decimal_t*) decimal_value, &end);
196
if (end != from_end && !err)
198
/* Give warning if there is something other than end space */
199
for ( ; end < from_end; end++)
201
if (!my_isspace(&my_charset_utf8_general_ci, *end))
203
err= E_DEC_TRUNCATED;
208
check_result_and_overflow(mask, err, decimal_value);
213
my_decimal *date2my_decimal(DRIZZLE_TIME *ltime, my_decimal *dec)
216
date = (ltime->year*100L + ltime->month)*100L + ltime->day;
217
if (ltime->time_type > DRIZZLE_TIMESTAMP_DATE)
218
date= ((date*100L + ltime->hour)*100L+ ltime->minute)*100L + ltime->second;
219
if (int2my_decimal(E_DEC_FATAL_ERROR, date, false, dec))
221
if (ltime->second_part)
223
dec->buf[(dec->intg-1) / 9 + 1]= ltime->second_part * 1000;
230
void my_decimal_trim(uint32_t *precision, uint32_t *scale)
232
if (!(*precision) && !(*scale))