00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020 #include <config.h>
00021
00022 #include <math.h>
00023
00024 #include <drizzled/error.h>
00025 #include <drizzled/field.h>
00026 #include <drizzled/item/float.h>
00027 #include <drizzled/item/num.h>
00028 #include <drizzled/item/string.h>
00029
00030 namespace drizzled {
00031
00032 extern const charset_info_st *system_charset_info;
00033
00034 static uint32_t nr_of_decimals(const char *str, const char *end)
00035 {
00036 const char *decimal_point;
00037
00038
00039 for (;;)
00040 {
00041 if (str == end)
00042 return 0;
00043 if (*str == 'e' || *str == 'E')
00044 return NOT_FIXED_DEC;
00045 if (*str++ == '.')
00046 break;
00047 }
00048 decimal_point= str;
00049 for (; system_charset_info->isdigit(*str) ; str++)
00050 ;
00051 if (*str == 'e' || *str == 'E')
00052 return NOT_FIXED_DEC;
00053 return (uint32_t) (str - decimal_point);
00054 }
00055
00056 String *Item_float::val_str(String *str)
00057 {
00058
00059 assert(fixed == 1);
00060 str->set_real(value,decimals,&my_charset_bin);
00061 return str;
00062 }
00063
00064
00065 int64_t Item_float::val_int()
00066 {
00067 assert(fixed == 1);
00068 if (value <= (double) INT64_MIN)
00069 {
00070 return INT64_MIN;
00071 }
00072 else if (value >= (double) (uint64_t) INT64_MAX)
00073 {
00074 return INT64_MAX;
00075 }
00076 return (int64_t) rint(value);
00077 }
00078
00079 type::Decimal *Item_float::val_decimal(type::Decimal *decimal_value)
00080 {
00081
00082 assert(fixed == 1);
00083 double2_class_decimal(E_DEC_FATAL_ERROR, value, decimal_value);
00084 return (decimal_value);
00085 }
00086
00092 Item_float::Item_float(const char *str_arg, uint32_t length)
00093 {
00094 int error;
00095 char *end_not_used;
00096 value= my_strntod(&my_charset_bin, (char*) str_arg, length, &end_not_used,
00097 &error);
00098 if (error)
00099 {
00100
00101
00102
00103
00104 assert(str_arg[length] == 0);
00105 my_error(ER_ILLEGAL_VALUE_FOR_TYPE, MYF(0), "double", (char*) str_arg);
00106 }
00107 presentation= name=(char*) str_arg;
00108 decimals=(uint8_t) nr_of_decimals(str_arg, str_arg+length);
00109 max_length=length;
00110 fixed= 1;
00111 }
00112
00113 int Item_float::save_in_field(Field *field, bool)
00114 {
00115 double nr= val_real();
00116 if (null_value)
00117 return set_field_to_null(field);
00118 field->set_notnull();
00119 return field->store(nr);
00120 }
00121
00122
00123 void Item_float::print(String *str)
00124 {
00125 if (presentation)
00126 {
00127 str->append(presentation);
00128 return;
00129 }
00130 char buffer[20];
00131 String num(buffer, sizeof(buffer), &my_charset_bin);
00132 num.set_real(value, decimals, &my_charset_bin);
00133 str->append(num);
00134 }
00135
00136
00137
00138
00139
00140
00141
00142 bool Item_float::eq(const Item *arg, bool) const
00143 {
00144 if (arg->basic_const_item() && arg->type() == type())
00145 {
00146
00147
00148
00149
00150 Item *item= (Item*) arg;
00151 return item->val_real() == value;
00152 }
00153 return false;
00154 }
00155
00156 Item *Item_static_float_func::safe_charset_converter(const charset_info_st*)
00157 {
00158 char buf[64];
00159 String tmp(buf, sizeof(buf), &my_charset_bin);
00160 String* s= val_str(&tmp);
00161 Item_string* conv= new Item_static_string_func(func_name, *s, s->charset());
00162 conv->str_value.copy();
00163 conv->str_value.mark_as_const();
00164 return conv;
00165 }
00166
00167 }