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"
27
report result of decimal operation.
29
@param result decimal library return code (E_DEC_* see include/decimal.h)
38
int decimal_operation_results(int result)
44
push_warning_printf(current_session, DRIZZLE_ERROR::WARN_LEVEL_WARN,
45
ER_WARN_DATA_TRUNCATED, ER(ER_WARN_DATA_TRUNCATED),
49
push_warning_printf(current_session, DRIZZLE_ERROR::WARN_LEVEL_ERROR,
50
ER_TRUNCATED_WRONG_VALUE,
51
ER(ER_TRUNCATED_WRONG_VALUE),
55
push_warning_printf(current_session, DRIZZLE_ERROR::WARN_LEVEL_ERROR,
56
ER_DIVISION_BY_ZERO, ER(ER_DIVISION_BY_ZERO));
59
push_warning_printf(current_session, DRIZZLE_ERROR::WARN_LEVEL_ERROR,
60
ER_TRUNCATED_WRONG_VALUE_FOR_FIELD,
61
ER(ER_TRUNCATED_WRONG_VALUE_FOR_FIELD),
62
"decimal", "", "", (long)-1);
65
my_error(ER_OUT_OF_RESOURCES, MYF(0));
75
@brief Converting decimal to string
77
@details Convert given my_decimal to String; allocate buffer as needed.
79
@param[in] mask what problems to warn on (mask of E_DEC_* values)
80
@param[in] d the decimal to print
81
@param[in] fixed_prec overall number of digits if ZEROFILL, 0 otherwise
82
@param[in] fixed_dec number of decimal places (if fixed_prec != 0)
83
@param[in] filler what char to pad with (ZEROFILL et al.)
84
@param[out] *str where to store the resulting string
88
@retval E_DEC_TRUNCATED
89
@retval E_DEC_OVERFLOW
93
int my_decimal2string(uint32_t mask, const my_decimal *d,
94
uint32_t fixed_prec, uint32_t fixed_dec,
95
char filler, String *str)
98
Calculate the size of the string: For DECIMAL(a,b), fixed_prec==a
99
holds true iff the type is also ZEROFILL, which in turn implies
100
UNSIGNED. Hence the buffer for a ZEROFILLed value is the length
101
the user requested, plus one for a possible decimal point, plus
102
one if the user only wanted decimal places, but we force a leading
103
zero on them. Because the type is implicitly UNSIGNED, we do not
104
need to reserve a character for the sign. For all other cases,
105
fixed_prec will be 0, and my_decimal_string_length() will be called
106
instead to calculate the required size of the buffer.
108
int length= (fixed_prec
109
? (fixed_prec + ((fixed_prec == fixed_dec) ? 1 : 0) + 1)
110
: my_decimal_string_length(d));
112
if (str->alloc(length))
113
return check_result(mask, E_DEC_OOM);
114
result= decimal2string((decimal_t*) d, (char*) str->ptr(),
115
&length, (int)fixed_prec, fixed_dec,
118
return check_result(mask, result);
123
Convert from decimal to binary representation
127
mask error processing mask
128
d number for conversion
129
bin pointer to buffer where to write result
130
prec overall number of decimal digits
131
scale number of decimal digits after decimal point
134
Before conversion we round number if it need but produce truncation
143
int my_decimal2binary(uint32_t mask, const my_decimal *d, unsigned char *bin, int prec,
146
int err1= E_DEC_OK, err2;
148
my_decimal2decimal(d, &rounded);
149
rounded.frac= decimal_actual_fraction(&rounded);
150
if (scale < rounded.frac)
152
err1= E_DEC_TRUNCATED;
153
/* decimal_round can return only E_DEC_TRUNCATED */
154
decimal_round(&rounded, &rounded, scale, HALF_UP);
156
err2= decimal2bin(&rounded, bin, prec, scale);
159
return check_result(mask, err2);
164
Convert string for decimal when string can be in some multibyte charset
168
mask error processing mask
169
from string to process
170
length length of given string
171
charset charset of given string
172
decimal_value buffer for result storing
182
int str2my_decimal(uint32_t mask, const char *from, uint32_t length,
183
const CHARSET_INFO * charset, my_decimal *decimal_value)
185
char *end, *from_end;
187
char buff[STRING_BUFFER_USUAL_SIZE];
188
String tmp(buff, sizeof(buff), &my_charset_bin);
189
if (charset->mbminlen > 1)
191
uint32_t dummy_errors;
192
tmp.copy(from, length, charset, &my_charset_utf8_general_ci, &dummy_errors);
194
length= tmp.length();
195
charset= &my_charset_bin;
197
from_end= end= (char*) from+length;
198
err= string2decimal((char *)from, (decimal_t*) decimal_value, &end);
199
if (end != from_end && !err)
201
/* Give warning if there is something other than end space */
202
for ( ; end < from_end; end++)
204
if (!my_isspace(&my_charset_utf8_general_ci, *end))
206
err= E_DEC_TRUNCATED;
211
check_result_and_overflow(mask, err, decimal_value);
216
my_decimal *date2my_decimal(DRIZZLE_TIME *ltime, my_decimal *dec)
219
date = (ltime->year*100L + ltime->month)*100L + ltime->day;
220
if (ltime->time_type > DRIZZLE_TIMESTAMP_DATE)
221
date= ((date*100L + ltime->hour)*100L+ ltime->minute)*100L + ltime->second;
222
if (int2my_decimal(E_DEC_FATAL_ERROR, date, false, dec))
224
if (ltime->second_part)
226
dec->buf[(dec->intg-1) / 9 + 1]= ltime->second_part * 1000;
233
void my_decimal_trim(uint32_t *precision, uint32_t *scale)
235
if (!(*precision) && !(*scale))
243
} /* namespace drizzled */