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