16 #include <my_global.h>
21 #include "sql_class.h"
37 int decimal_operation_results(
int result)
43 push_warning_printf(current_thd, Sql_condition::WARN_LEVEL_WARN,
44 WARN_DATA_TRUNCATED, ER(WARN_DATA_TRUNCATED),
48 push_warning_printf(current_thd, Sql_condition::WARN_LEVEL_WARN,
49 ER_TRUNCATED_WRONG_VALUE,
50 ER(ER_TRUNCATED_WRONG_VALUE),
54 push_warning_printf(current_thd, Sql_condition::WARN_LEVEL_WARN,
55 ER_DIVISION_BY_ZERO, ER(ER_DIVISION_BY_ZERO));
58 push_warning_printf(current_thd, Sql_condition::WARN_LEVEL_WARN,
59 ER_TRUNCATED_WRONG_VALUE_FOR_FIELD,
60 ER(ER_TRUNCATED_WRONG_VALUE_FOR_FIELD),
61 "decimal",
"",
"", (
long)-1);
64 my_error(ER_OUT_OF_RESOURCES, MYF(0));
93 uint fixed_prec, uint fixed_dec,
108 int length= (fixed_prec
109 ? (fixed_prec + ((fixed_prec == fixed_dec) ? 1 : 0) + 1 + 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 str->set_charset(&my_charset_numeric);
119 return check_result(mask, result);
148 uint fixed_prec, uint fixed_dec,
char filler,
151 if (!(cs->state & MY_CS_NONASCII))
154 my_decimal2string(mask, val, fixed_prec, fixed_dec, filler, str);
155 str->set_charset(cs);
168 String tmp(buf,
sizeof(buf), &my_charset_latin1);
169 my_decimal2string(mask, val, fixed_prec, fixed_dec, filler, &tmp);
170 return str->copy(tmp.ptr(), tmp.length(), &my_charset_latin1, cs, &errors);
196 int my_decimal2binary(uint mask,
const my_decimal *d, uchar *bin,
int prec,
199 int err1= E_DEC_OK, err2;
201 my_decimal2decimal(d, &rounded);
202 rounded.frac= decimal_actual_fraction(&rounded);
203 if (scale < rounded.frac)
205 err1= E_DEC_TRUNCATED;
207 decimal_round(&rounded, &rounded, scale, HALF_UP);
209 err2= decimal2bin(&rounded, bin, prec, scale);
212 return check_result(mask, err2);
235 int str2my_decimal(uint mask,
const char *from, uint length,
238 char *end, *from_end;
240 char buff[STRING_BUFFER_USUAL_SIZE];
241 String tmp(buff,
sizeof(buff), &my_charset_bin);
242 if (charset->mbminlen > 1)
245 tmp.copy(from, length, charset, &my_charset_latin1, &dummy_errors);
247 length= tmp.length();
248 charset= &my_charset_bin;
250 from_end= end= (
char*) from+length;
251 err= string2decimal((
char *)from, (
decimal_t*) decimal_value, &end);
252 if (end != from_end && !err)
255 for ( ; end < from_end; end++)
257 if (!my_isspace(&my_charset_latin1, *end))
259 err= E_DEC_TRUNCATED;
264 check_result_and_overflow(mask, err, decimal_value);
278 static my_decimal *lldiv_t2my_decimal(
const lldiv_t *lld,
bool neg,
281 if (int2my_decimal(E_DEC_FATAL_ERROR, lld->quot, FALSE, dec))
287 dec->buf[(dec->intg-1) / 9 + 1]= lld->rem;
302 lld.quot= ltime->time_type > MYSQL_TIMESTAMP_DATE ?
303 TIME_to_ulonglong_datetime(ltime) :
304 TIME_to_ulonglong_date(ltime);
306 return lldiv_t2my_decimal(&lld, ltime->neg, dec);
318 lld.quot= TIME_to_ulonglong_time(ltime);
320 return lldiv_t2my_decimal(&lld, ltime->neg, dec);
330 lld.quot= tm->tv_sec;
331 lld.rem= (longlong) tm->tv_usec * 1000;
332 return lldiv_t2my_decimal(&lld, 0, dec);
336 void my_decimal_trim(ulong *precision, uint *scale)
338 if (!(*precision) && !(*scale))
350 #define DIG_PER_DEC1 9
351 #define ROUND_UP(X) (((X)+DIG_PER_DEC1-1)/DIG_PER_DEC1)
358 char buff[512], *pos;
360 pos+= sprintf(buff,
"Decimal: sign: %d intg: %d frac: %d { ",
361 dec->sign(), dec->intg, dec->frac);
362 end= ROUND_UP(dec->frac)+ROUND_UP(dec->intg)-1;
363 for (i=0; i < end; i++)
364 pos+= sprintf(pos,
"%09d, ", dec->buf[i]);
365 pos+= sprintf(pos,
"%09d }\n", dec->buf[i]);
366 fputs(buff, DBUG_FILE);
372 print_decimal_buff(
const my_decimal *dec,
const uchar* ptr,
int length)
375 fprintf(DBUG_FILE,
"Record: ");
376 for (
int i= 0; i < length; i++)
378 fprintf(DBUG_FILE,
"%02X ", (uint)((uchar *)ptr)[i]);
380 fprintf(DBUG_FILE,
"\n");
384 const char *dbug_decimal_as_string(
char *buff,
const my_decimal *val)
389 (void)decimal2string((
decimal_t*) val, buff, &length, 0,0,0);