00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020 #include <config.h>
00021 #include <drizzled/function/math/decimal_typecast.h>
00022 #include <drizzled/error.h>
00023 #include <drizzled/session.h>
00024 #include <drizzled/internal/m_string.h>
00025
00026 namespace drizzled
00027 {
00028
00029 String *Item_decimal_typecast::val_str(String *str)
00030 {
00031 type::Decimal tmp_buf, *tmp= val_decimal(&tmp_buf);
00032 if (null_value)
00033 return NULL;
00034 class_decimal2string(tmp, 0, str);
00035 return str;
00036 }
00037
00038
00039 double Item_decimal_typecast::val_real()
00040 {
00041 type::Decimal tmp_buf, *tmp= val_decimal(&tmp_buf);
00042 double res;
00043 if (null_value)
00044 return 0.0;
00045 class_decimal2double(E_DEC_FATAL_ERROR, tmp, &res);
00046 return res;
00047 }
00048
00049
00050 int64_t Item_decimal_typecast::val_int()
00051 {
00052 type::Decimal tmp_buf, *tmp= val_decimal(&tmp_buf);
00053 int64_t res;
00054 if (null_value)
00055 return 0;
00056
00057 tmp->val_int32(E_DEC_FATAL_ERROR, unsigned_flag, &res);
00058
00059 return res;
00060 }
00061
00062
00063 type::Decimal *Item_decimal_typecast::val_decimal(type::Decimal *dec)
00064 {
00065 type::Decimal tmp_buf, *tmp= args[0]->val_decimal(&tmp_buf);
00066 bool sign;
00067 uint32_t precision;
00068
00069 if ((null_value= args[0]->null_value))
00070 return NULL;
00071 class_decimal_round(E_DEC_FATAL_ERROR, tmp, decimals, false, dec);
00072 sign= dec->sign();
00073 if (unsigned_flag)
00074 {
00075 if (sign)
00076 {
00077 dec->set_zero();
00078 goto err;
00079 }
00080 }
00081 precision= class_decimal_length_to_precision(max_length,
00082 decimals, unsigned_flag);
00083 if (precision - decimals < (uint) class_decimal_intg(dec))
00084 {
00085 max_Decimal(dec, precision, decimals);
00086 dec->sign(sign);
00087 goto err;
00088 }
00089 return dec;
00090
00091 err:
00092 push_warning_printf(getSessionPtr(), DRIZZLE_ERROR::WARN_LEVEL_ERROR,
00093 ER_WARN_DATA_OUT_OF_RANGE,
00094 ER(ER_WARN_DATA_OUT_OF_RANGE),
00095 name, 1);
00096 return dec;
00097 }
00098
00099
00100 void Item_decimal_typecast::print(String *str)
00101 {
00102 char len_buf[20*3 + 1];
00103 char *end;
00104
00105 uint32_t precision= class_decimal_length_to_precision(max_length, decimals,
00106 unsigned_flag);
00107 str->append(STRING_WITH_LEN("cast("));
00108 args[0]->print(str);
00109 str->append(STRING_WITH_LEN(" as decimal("));
00110
00111 end=internal::int10_to_str(precision, len_buf,10);
00112 str->append(len_buf, (uint32_t) (end - len_buf));
00113
00114 str->append(',');
00115
00116 end=internal::int10_to_str(decimals, len_buf,10);
00117 str->append(len_buf, (uint32_t) (end - len_buf));
00118
00119 str->append(')');
00120 str->append(')');
00121 }
00122
00123 }