Drizzled Public API Documentation

float.cc
00001 /* -*- mode: c++; c-basic-offset: 2; indent-tabs-mode: nil; -*-
00002  *  vim:expandtab:shiftwidth=2:tabstop=2:smarttab:
00003  *
00004  *  Copyright (C) 2008 Sun Microsystems, Inc.
00005  *
00006  *  This program is free software; you can redistribute it and/or modify
00007  *  it under the terms of the GNU General Public License as published by
00008  *  the Free Software Foundation; version 2 of the License.
00009  *
00010  *  This program is distributed in the hope that it will be useful,
00011  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
00012  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00013  *  GNU General Public License for more details.
00014  *
00015  *  You should have received a copy of the GNU General Public License
00016  *  along with this program; if not, write to the Free Software
00017  *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
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   /* Find position for '.' */
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   // following assert is redundant, because fixed=1 assigned in constructor
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   // following assert is redundant, because fixed=1 assigned in constructor
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       Note that we depend on that str_arg is null terminated, which is true
00102       when we are in the parser
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   hex item
00138   In string context this is a binary string.
00139   In number context this is a int64_t value.
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       We need to cast off const to call val_int(). This should be OK for
00148       a basic constant.
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 } /* namespace drizzled */