Drizzled Public API Documentation

num.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 MySQL
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; either version 2 of the License, or
00009  *  (at your option) any later version.
00010  *
00011  *  This program is distributed in the hope that it will be useful,
00012  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
00013  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00014  *  GNU General Public License for more details.
00015  *
00016  *  You should have received a copy of the GNU General Public License
00017  *  along with this program; if not, write to the Free Software
00018  *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
00019  */
00020 
00021 
00022 #include <config.h>
00023 #include <drizzled/field/num.h>
00024 #include <drizzled/error.h>
00025 #include <drizzled/table.h>
00026 #include <drizzled/session.h>
00027 #include <drizzled/internal/my_sys.h>
00028 #include <drizzled/util/test.h>
00029 #include <drizzled/create_field.h>
00030 
00031 namespace drizzled {
00032 
00036 Field_num::Field_num(unsigned char *ptr_arg,
00037                      uint32_t len_arg,
00038                      unsigned char *null_ptr_arg,
00039                      unsigned char null_bit_arg,
00040                      utype unireg_check_arg,
00041                      const char *field_name_arg,
00042                      uint8_t dec_arg,
00043                      bool zero_arg,
00044                      bool unsigned_arg) :
00045   Field(ptr_arg,
00046         len_arg,
00047         null_ptr_arg,
00048         null_bit_arg,
00049         unireg_check_arg,
00050         field_name_arg),
00051   dec(dec_arg),
00052   decimal_precision(zero_arg),
00053   unsigned_flag(unsigned_arg)
00054   {
00055 }
00056 
00057 
00080 int Field_num::check_int(const charset_info_st * const cs, const char *str, int length,
00081                          const char *int_end, int error)
00082 {
00083   /* Test if we get an empty string or wrong integer */
00084   if (str == int_end || error == EDOM)
00085   {
00086     char buff[128];
00087     String tmp(buff, (uint32_t) sizeof(buff), system_charset_info);
00088     tmp.copy(str, length, system_charset_info);
00089     push_warning_printf(getTable()->in_use, DRIZZLE_ERROR::WARN_LEVEL_WARN,
00090                         ER_TRUNCATED_WRONG_VALUE_FOR_FIELD,
00091                         ER(ER_TRUNCATED_WRONG_VALUE_FOR_FIELD),
00092                         "integer", tmp.c_ptr(), field_name,
00093                         (uint32_t) getTable()->in_use->row_count);
00094     return 1;
00095   }
00096   /* Test if we have garbage at the end of the given string. */
00097   if (test_if_important_data(cs, int_end, str + length))
00098   {
00099     set_warning(DRIZZLE_ERROR::WARN_LEVEL_WARN, ER_WARN_DATA_TRUNCATED, 1);
00100     return 2;
00101   }
00102   return 0;
00103 }
00104 
00105 /*
00106   Conver a string to an integer then check bounds.
00107 
00108   SYNOPSIS
00109     Field_num::get_int
00110     cs            Character set
00111     from          String to convert
00112     len           Length of the string
00113     rnd           OUT int64_t value
00114     unsigned_max  max unsigned value
00115     signed_min    min signed value
00116     signed_max    max signed value
00117 
00118   DESCRIPTION
00119     The function calls strntoull10rnd() to get an integer value then
00120     check bounds and errors returned. In case of any error a warning
00121     is raised.
00122 
00123   RETURN
00124     0   ok
00125     1   error
00126 */
00127 
00128 bool Field_num::get_int(const charset_info_st * const cs, const char *from, uint32_t len,
00129                         int64_t *rnd, uint64_t ,
00130                         int64_t signed_min, int64_t signed_max)
00131 {
00132   char *end;
00133   int error;
00134 
00135   *rnd= (int64_t) cs->cset->strntoull10rnd(cs, from, len, false, &end, &error);
00136   if (*rnd < signed_min)
00137   {
00138     *rnd= signed_min;
00139     goto out_of_range;
00140   }
00141   else if (*rnd > signed_max)
00142   {
00143     *rnd= signed_max;
00144     goto out_of_range;
00145   }
00146 
00147   if (getTable()->in_use->count_cuted_fields &&
00148       check_int(cs, from, len, end, error))
00149     return 1;
00150 
00151   return 0;
00152 
00153 out_of_range:
00154   set_warning(DRIZZLE_ERROR::WARN_LEVEL_WARN, ER_WARN_DATA_OUT_OF_RANGE, 1);
00155   return 1;
00156 }
00157 
00172 int Field_num::store_decimal(const type::Decimal *val)
00173 {
00174   int err= 0;
00175   int64_t i= convert_decimal2int64_t(val, false, &err);
00176   return test(err | store(i, false));
00177 }
00178 
00193 type::Decimal* Field_num::val_decimal(type::Decimal *decimal_value) const
00194 {
00195   assert(result_type() == INT_RESULT);
00196 
00197   int64_t nr= val_int();
00198   int2_class_decimal(E_DEC_FATAL_ERROR, nr, false, decimal_value);
00199   return decimal_value;
00200 }
00201 
00202 
00203 void Field_num::make_field(SendField *field)
00204 {
00205   Field::make_field(field);
00206   field->decimals= dec;
00207 }
00208 
00213 bool Field_num::eq_def(Field *field)
00214 {
00215   if (!Field::eq_def(field))
00216     return 0;
00217   Field_num *from_num= (Field_num*) field;
00218 
00219   if (dec != from_num->dec)
00220     return 0;
00221   return 1;
00222 }
00223 
00224 uint32_t Field_num::is_equal(CreateField *new_field_ptr)
00225 {
00226   return ((new_field_ptr->sql_type == real_type()) &&
00227           ((new_field_ptr->flags & UNSIGNED_FLAG) == (uint32_t) (flags & UNSIGNED_FLAG)) &&
00228           ((new_field_ptr->flags & AUTO_INCREMENT_FLAG) == (uint32_t) (flags & AUTO_INCREMENT_FLAG)) &&
00229           (new_field_ptr->length <= max_display_length()));
00230 }
00231 
00232 
00233 } /* namespace drizzled */