summaryrefslogtreecommitdiff
path: root/sql/my_decimal.cc
diff options
context:
space:
mode:
Diffstat (limited to 'sql/my_decimal.cc')
-rw-r--r--sql/my_decimal.cc83
1 files changed, 69 insertions, 14 deletions
diff --git a/sql/my_decimal.cc b/sql/my_decimal.cc
index b338750c5fb..85872f52194 100644
--- a/sql/my_decimal.cc
+++ b/sql/my_decimal.cc
@@ -1,5 +1,4 @@
-/*
- Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
+/* Copyright (c) 2005, 2010, Oracle and/or its affiliates. All rights reserved.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -12,12 +11,15 @@
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
- Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
-*/
+ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */
-#include "mysql_priv.h"
+#include <my_global.h>
+#include "sql_priv.h"
#include <time.h>
+#ifndef MYSQL_CLIENT
+#include "sql_class.h" // THD
+#endif
#ifndef MYSQL_CLIENT
/**
@@ -43,17 +45,17 @@ int decimal_operation_results(int result)
"", (long)-1);
break;
case E_DEC_OVERFLOW:
- push_warning_printf(current_thd, MYSQL_ERROR::WARN_LEVEL_ERROR,
+ push_warning_printf(current_thd, MYSQL_ERROR::WARN_LEVEL_WARN,
ER_TRUNCATED_WRONG_VALUE,
ER(ER_TRUNCATED_WRONG_VALUE),
"DECIMAL", "");
break;
case E_DEC_DIV_ZERO:
- push_warning_printf(current_thd, MYSQL_ERROR::WARN_LEVEL_ERROR,
+ push_warning_printf(current_thd, MYSQL_ERROR::WARN_LEVEL_WARN,
ER_DIVISION_BY_ZERO, ER(ER_DIVISION_BY_ZERO));
break;
case E_DEC_BAD_NUM:
- push_warning_printf(current_thd, MYSQL_ERROR::WARN_LEVEL_ERROR,
+ push_warning_printf(current_thd, MYSQL_ERROR::WARN_LEVEL_WARN,
ER_TRUNCATED_WRONG_VALUE_FOR_FIELD,
ER(ER_TRUNCATED_WRONG_VALUE_FOR_FIELD),
"decimal", "", "", (long)-1);
@@ -97,10 +99,11 @@ int my_decimal2string(uint mask, const my_decimal *d,
UNSIGNED. Hence the buffer for a ZEROFILLed value is the length
the user requested, plus one for a possible decimal point, plus
one if the user only wanted decimal places, but we force a leading
- zero on them. Because the type is implicitly UNSIGNED, we do not
- need to reserve a character for the sign. For all other cases,
- fixed_prec will be 0, and my_decimal_string_length() will be called
- instead to calculate the required size of the buffer.
+ zero on them, plus one for the '\0' terminator. Because the type
+ is implicitly UNSIGNED, we do not need to reserve a character for
+ the sign. For all other cases, fixed_prec will be 0, and
+ my_decimal_string_length() will be called instead to calculate the
+ required size of the buffer.
*/
int length= (fixed_prec
? (fixed_prec + ((fixed_prec == fixed_dec) ? 1 : 0) + 1)
@@ -111,12 +114,64 @@ int my_decimal2string(uint mask, const my_decimal *d,
result= decimal2string((decimal_t*) d, (char*) str->ptr(),
&length, (int)fixed_prec, fixed_dec,
filler);
- str->set_charset(&my_charset_bin);
str->length(length);
+ str->set_charset(&my_charset_numeric);
return check_result(mask, result);
}
+/**
+ @brief Converting decimal to string with character set conversion
+
+ @details Convert given my_decimal to String; allocate buffer as needed.
+
+ @param[in] mask what problems to warn on (mask of E_DEC_* values)
+ @param[in] val the decimal to print
+ @param[in] fixed_prec overall number of digits if ZEROFILL, 0 otherwise
+ @param[in] fixed_dec number of decimal places (if fixed_prec != 0)
+ @param[in] filler what char to pad with (ZEROFILL et al.)
+ @param[out] *str where to store the resulting string
+ @param[in] cs character set
+
+ @return error coce
+ @retval E_DEC_OK
+ @retval E_DEC_TRUNCATED
+ @retval E_DEC_OVERFLOW
+ @retval E_DEC_OOM
+
+ Would be great to make it a method of the String class,
+ but this would need to include
+ my_decimal.h from sql_string.h and sql_string.cc, which is not desirable.
+*/
+bool
+str_set_decimal(uint mask, const my_decimal *val,
+ uint fixed_prec, uint fixed_dec, char filler,
+ String *str, CHARSET_INFO *cs)
+{
+ if (!(cs->state & MY_CS_NONASCII))
+ {
+ /* For ASCII-compatible character sets we can use my_decimal2string */
+ my_decimal2string(mask, val, fixed_prec, fixed_dec, filler, str);
+ str->set_charset(cs);
+ return FALSE;
+ }
+ else
+ {
+ /*
+ For ASCII-incompatible character sets (like UCS2) we
+ call my_decimal2string() on a temporary buffer first,
+ and then convert the result to the target character
+ with help of str->copy().
+ */
+ uint errors;
+ char buf[DECIMAL_MAX_STR_LENGTH];
+ String tmp(buf, sizeof(buf), &my_charset_latin1);
+ my_decimal2string(mask, val, fixed_prec, fixed_dec, filler, &tmp);
+ return str->copy(tmp.ptr(), tmp.length(), &my_charset_latin1, cs, &errors);
+ }
+}
+
+
/*
Convert from decimal to binary representation
@@ -278,7 +333,7 @@ print_decimal_buff(const my_decimal *dec, const uchar* ptr, int length)
const char *dbug_decimal_as_string(char *buff, const my_decimal *val)
{
- int length= DECIMAL_MAX_STR_LENGTH;
+ int length= DECIMAL_MAX_STR_LENGTH + 1; /* minimum size for buff */
if (!val)
return "NULL";
(void)decimal2string((decimal_t*) val, buff, &length, 0,0,0);