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 */
16
#include <drizzled/server_includes.h>
17
#include <drizzled/current_session.h>
19
#include <drizzled/error.h>
23
report result of decimal operation.
25
@param result decimal library return code (E_DEC_* see include/decimal.h)
34
int decimal_operation_results(int result)
40
push_warning_printf(current_session, DRIZZLE_ERROR::WARN_LEVEL_WARN,
41
ER_WARN_DATA_TRUNCATED, ER(ER_WARN_DATA_TRUNCATED),
45
push_warning_printf(current_session, DRIZZLE_ERROR::WARN_LEVEL_ERROR,
46
ER_TRUNCATED_WRONG_VALUE,
47
ER(ER_TRUNCATED_WRONG_VALUE),
51
push_warning_printf(current_session, DRIZZLE_ERROR::WARN_LEVEL_ERROR,
52
ER_DIVISION_BY_ZERO, ER(ER_DIVISION_BY_ZERO));
55
push_warning_printf(current_session, DRIZZLE_ERROR::WARN_LEVEL_ERROR,
56
ER_TRUNCATED_WRONG_VALUE_FOR_FIELD,
57
ER(ER_TRUNCATED_WRONG_VALUE_FOR_FIELD),
58
"decimal", "", "", (long)-1);
61
my_error(ER_OUT_OF_RESOURCES, MYF(0));
71
@brief Converting decimal to string
73
@details Convert given my_decimal to String; allocate buffer as needed.
75
@param[in] mask what problems to warn on (mask of E_DEC_* values)
76
@param[in] d the decimal to print
77
@param[in] fixed_prec overall number of digits if ZEROFILL, 0 otherwise
78
@param[in] fixed_dec number of decimal places (if fixed_prec != 0)
79
@param[in] filler what char to pad with (ZEROFILL et al.)
80
@param[out] *str where to store the resulting string
84
@retval E_DEC_TRUNCATED
85
@retval E_DEC_OVERFLOW
89
int my_decimal2string(uint32_t mask, const my_decimal *d,
90
uint32_t fixed_prec, uint32_t fixed_dec,
91
char filler, String *str)
94
Calculate the size of the string: For DECIMAL(a,b), fixed_prec==a
95
holds true iff the type is also ZEROFILL, which in turn implies
96
UNSIGNED. Hence the buffer for a ZEROFILLed value is the length
97
the user requested, plus one for a possible decimal point, plus
98
one if the user only wanted decimal places, but we force a leading
99
zero on them. Because the type is implicitly UNSIGNED, we do not
100
need to reserve a character for the sign. For all other cases,
101
fixed_prec will be 0, and my_decimal_string_length() will be called
102
instead to calculate the required size of the buffer.
104
int length= (fixed_prec
105
? (fixed_prec + ((fixed_prec == fixed_dec) ? 1 : 0) + 1)
106
: my_decimal_string_length(d));
108
if (str->alloc(length))
109
return check_result(mask, E_DEC_OOM);
110
result= decimal2string((decimal_t*) d, (char*) str->ptr(),
111
&length, (int)fixed_prec, fixed_dec,
114
return check_result(mask, result);
119
Convert from decimal to binary representation
123
mask error processing mask
124
d number for conversion
125
bin pointer to buffer where to write result
126
prec overall number of decimal digits
127
scale number of decimal digits after decimal point
130
Before conversion we round number if it need but produce truncation
139
int my_decimal2binary(uint32_t mask, const my_decimal *d, unsigned char *bin, int prec,
142
int err1= E_DEC_OK, err2;
144
my_decimal2decimal(d, &rounded);
145
rounded.frac= decimal_actual_fraction(&rounded);
146
if (scale < rounded.frac)
148
err1= E_DEC_TRUNCATED;
149
/* decimal_round can return only E_DEC_TRUNCATED */
150
decimal_round(&rounded, &rounded, scale, HALF_UP);
152
err2= decimal2bin(&rounded, bin, prec, scale);
155
return check_result(mask, err2);
160
Convert string for decimal when string can be in some multibyte charset
164
mask error processing mask
165
from string to process
166
length length of given string
167
charset charset of given string
168
decimal_value buffer for result storing
178
int str2my_decimal(uint32_t mask, const char *from, uint32_t length,
179
const CHARSET_INFO * charset, my_decimal *decimal_value)
181
char *end, *from_end;
183
char buff[STRING_BUFFER_USUAL_SIZE];
184
String tmp(buff, sizeof(buff), &my_charset_bin);
185
if (charset->mbminlen > 1)
187
uint32_t dummy_errors;
188
tmp.copy(from, length, charset, &my_charset_utf8_general_ci, &dummy_errors);
190
length= tmp.length();
191
charset= &my_charset_bin;
193
from_end= end= (char*) from+length;
194
err= string2decimal((char *)from, (decimal_t*) decimal_value, &end);
195
if (end != from_end && !err)
197
/* Give warning if there is something other than end space */
198
for ( ; end < from_end; end++)
200
if (!my_isspace(&my_charset_utf8_general_ci, *end))
202
err= E_DEC_TRUNCATED;
207
check_result_and_overflow(mask, err, decimal_value);
212
my_decimal *date2my_decimal(DRIZZLE_TIME *ltime, my_decimal *dec)
215
date = (ltime->year*100L + ltime->month)*100L + ltime->day;
216
if (ltime->time_type > DRIZZLE_TIMESTAMP_DATE)
217
date= ((date*100L + ltime->hour)*100L+ ltime->minute)*100L + ltime->second;
218
if (int2my_decimal(E_DEC_FATAL_ERROR, date, false, dec))
220
if (ltime->second_part)
222
dec->buf[(dec->intg-1) / 9 + 1]= ltime->second_part * 1000;
229
void my_decimal_trim(uint32_t *precision, uint32_t *scale)
231
if (!(*precision) && !(*scale))