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 
00029 namespace drizzled
00030 {
00031 
00035 Field_num::Field_num(unsigned char *ptr_arg,
00036                      uint32_t len_arg,
00037                      unsigned char *null_ptr_arg,
00038                      unsigned char null_bit_arg,
00039                      utype unireg_check_arg,
00040                      const char *field_name_arg,
00041                      uint8_t dec_arg,
00042                      bool zero_arg,
00043                      bool unsigned_arg) :
00044   Field(ptr_arg,
00045         len_arg,
00046         null_ptr_arg,
00047         null_bit_arg,
00048         unireg_check_arg,
00049         field_name_arg),
00050   dec(dec_arg),
00051   decimal_precision(zero_arg),
00052   unsigned_flag(unsigned_arg)
00053   {
00054 }
00055 
00056 
00079 int Field_num::check_int(const CHARSET_INFO * const cs, const char *str, int length,
00080                          const char *int_end, int error)
00081 {
00082   /* Test if we get an empty string or wrong integer */
00083   if (str == int_end || error == MY_ERRNO_EDOM)
00084   {
00085     char buff[128];
00086     String tmp(buff, (uint32_t) sizeof(buff), system_charset_info);
00087     tmp.copy(str, length, system_charset_info);
00088     push_warning_printf(getTable()->in_use, DRIZZLE_ERROR::WARN_LEVEL_WARN,
00089                         ER_TRUNCATED_WRONG_VALUE_FOR_FIELD,
00090                         ER(ER_TRUNCATED_WRONG_VALUE_FOR_FIELD),
00091                         "integer", tmp.c_ptr(), field_name,
00092                         (uint32_t) getTable()->in_use->row_count);
00093     return 1;
00094   }
00095   /* Test if we have garbage at the end of the given string. */
00096   if (test_if_important_data(cs, int_end, str + length))
00097   {
00098     set_warning(DRIZZLE_ERROR::WARN_LEVEL_WARN, ER_WARN_DATA_TRUNCATED, 1);
00099     return 2;
00100   }
00101   return 0;
00102 }
00103 
00104 /*
00105   Conver a string to an integer then check bounds.
00106 
00107   SYNOPSIS
00108     Field_num::get_int
00109     cs            Character set
00110     from          String to convert
00111     len           Length of the string
00112     rnd           OUT int64_t value
00113     unsigned_max  max unsigned value
00114     signed_min    min signed value
00115     signed_max    max signed value
00116 
00117   DESCRIPTION
00118     The function calls strntoull10rnd() to get an integer value then
00119     check bounds and errors returned. In case of any error a warning
00120     is raised.
00121 
00122   RETURN
00123     0   ok
00124     1   error
00125 */
00126 
00127 bool Field_num::get_int(const CHARSET_INFO * const cs, const char *from, uint32_t len,
00128                         int64_t *rnd, uint64_t ,
00129                         int64_t signed_min, int64_t signed_max)
00130 {
00131   char *end;
00132   int error;
00133 
00134   *rnd= (int64_t) cs->cset->strntoull10rnd(cs, from, len, false, &end, &error);
00135   if (*rnd < signed_min)
00136   {
00137     *rnd= signed_min;
00138     goto out_of_range;
00139   }
00140   else if (*rnd > signed_max)
00141   {
00142     *rnd= signed_max;
00143     goto out_of_range;
00144   }
00145 
00146   if (getTable()->in_use->count_cuted_fields &&
00147       check_int(cs, from, len, end, error))
00148     return 1;
00149 
00150   return 0;
00151 
00152 out_of_range:
00153   set_warning(DRIZZLE_ERROR::WARN_LEVEL_WARN, ER_WARN_DATA_OUT_OF_RANGE, 1);
00154   return 1;
00155 }
00156 
00171 int Field_num::store_decimal(const type::Decimal *val)
00172 {
00173   int err= 0;
00174   int64_t i= convert_decimal2int64_t(val, false, &err);
00175   return test(err | store(i, false));
00176 }
00177 
00192 type::Decimal* Field_num::val_decimal(type::Decimal *decimal_value) const
00193 {
00194   assert(result_type() == INT_RESULT);
00195 
00196   int64_t nr= val_int();
00197   int2_class_decimal(E_DEC_FATAL_ERROR, nr, false, decimal_value);
00198   return decimal_value;
00199 }
00200 
00201 
00202 void Field_num::make_field(SendField *field)
00203 {
00204   Field::make_field(field);
00205   field->decimals= dec;
00206 }
00207 
00212 bool Field_num::eq_def(Field *field)
00213 {
00214   if (!Field::eq_def(field))
00215     return 0;
00216   Field_num *from_num= (Field_num*) field;
00217 
00218   if (dec != from_num->dec)
00219     return 0;
00220   return 1;
00221 }
00222 
00223 uint32_t Field_num::is_equal(CreateField *new_field_ptr)
00224 {
00225   return ((new_field_ptr->sql_type == real_type()) &&
00226           ((new_field_ptr->flags & UNSIGNED_FLAG) ==
00227            (uint32_t) (flags & UNSIGNED_FLAG)) &&
00228           ((new_field_ptr->flags & AUTO_INCREMENT_FLAG) ==
00229            (uint32_t) (flags & AUTO_INCREMENT_FLAG)) &&
00230           (new_field_ptr->length <= max_display_length()));
00231 }
00232 
00233 
00234 } /* namespace drizzled */