Drizzled Public API Documentation

numhybrid.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 #include <math.h>
00022 #include <drizzled/function/numhybrid.h>
00023 
00024 namespace drizzled
00025 {
00026 
00027 void Item_func_numhybrid::fix_num_length_and_dec()
00028 {}
00029 
00030 void Item_func_numhybrid::fix_length_and_dec()
00031 {
00032   fix_num_length_and_dec();
00033   find_num_type();
00034 }
00035 
00036 String *Item_func_numhybrid::val_str(String *str)
00037 {
00038   assert(fixed == 1);
00039   switch (hybrid_type) {
00040   case DECIMAL_RESULT:
00041     {
00042       type::Decimal decimal_value, *val;
00043       if (!(val= decimal_op(&decimal_value)))
00044         return 0;                                 // null is set
00045       class_decimal_round(E_DEC_FATAL_ERROR, val, decimals, false, val);
00046       class_decimal2string(val, 0, str);
00047       break;
00048     }
00049   case INT_RESULT:
00050     {
00051       int64_t nr= int_op();
00052       if (null_value)
00053         return 0;
00054       str->set_int(nr, unsigned_flag, &my_charset_bin);
00055       break;
00056     }
00057   case REAL_RESULT:
00058     {
00059       double nr= real_op();
00060       if (null_value)
00061         return 0;
00062       str->set_real(nr,decimals,&my_charset_bin);
00063       break;
00064     }
00065   case STRING_RESULT:
00066     return str_op(&str_value);
00067   case ROW_RESULT:
00068     assert(0);
00069   }
00070   return str;
00071 }
00072 
00073 
00074 double Item_func_numhybrid::val_real()
00075 {
00076   assert(fixed == 1);
00077   switch (hybrid_type) {
00078   case DECIMAL_RESULT:
00079     {
00080       type::Decimal decimal_value, *val;
00081       double result;
00082       if (!(val= decimal_op(&decimal_value)))
00083         return 0.0;                               // null is set
00084       class_decimal2double(E_DEC_FATAL_ERROR, val, &result);
00085       return result;
00086     }
00087   case INT_RESULT:
00088     {
00089       int64_t result= int_op();
00090       return unsigned_flag ? (double) ((uint64_t) result) : (double) result;
00091     }
00092   case REAL_RESULT:
00093     return real_op();
00094   case STRING_RESULT:
00095     {
00096       char *end_not_used;
00097       int err_not_used;
00098       String *res= str_op(&str_value);
00099       return (res ? my_strntod(res->charset(), (char*) res->ptr(), res->length(),
00100                                &end_not_used, &err_not_used) : 0.0);
00101     }
00102   case ROW_RESULT:
00103     assert(0);
00104   }
00105 
00106   return 0.0;
00107 }
00108 
00109 
00110 int64_t Item_func_numhybrid::val_int()
00111 {
00112   assert(fixed == 1);
00113   switch (hybrid_type) {
00114   case DECIMAL_RESULT:
00115     {
00116       type::Decimal decimal_value, *val;
00117       if (!(val= decimal_op(&decimal_value)))
00118         return 0;                                 // null is set
00119       int64_t result;
00120       val->val_int32(E_DEC_FATAL_ERROR, unsigned_flag, &result);
00121       return result;
00122     }
00123   case INT_RESULT:
00124     return int_op();
00125   case REAL_RESULT:
00126     return (int64_t) rint(real_op());
00127   case STRING_RESULT:
00128     {
00129       int err_not_used;
00130       String *res;
00131       if (!(res= str_op(&str_value)))
00132         return 0;
00133 
00134       char *end= (char*) res->ptr() + res->length();
00135       const CHARSET_INFO * const cs= str_value.charset();
00136       return (*(cs->cset->strtoll10))(cs, res->ptr(), &end, &err_not_used);
00137     }
00138   case ROW_RESULT:
00139     assert(0);
00140   }
00141   return 0;
00142 }
00143 
00144 
00145 type::Decimal *Item_func_numhybrid::val_decimal(type::Decimal *decimal_value)
00146 {
00147   type::Decimal *val= decimal_value;
00148   assert(fixed == 1);
00149 
00150   switch (hybrid_type) {
00151   case DECIMAL_RESULT:
00152     val= decimal_op(decimal_value);
00153     break;
00154   case INT_RESULT:
00155     {
00156       int64_t result= int_op();
00157       int2_class_decimal(E_DEC_FATAL_ERROR, result, unsigned_flag, decimal_value);
00158       break;
00159     }
00160   case REAL_RESULT:
00161     {
00162       double result= (double)real_op();
00163       double2_class_decimal(E_DEC_FATAL_ERROR, result, decimal_value);
00164       break;
00165     }
00166   case STRING_RESULT:
00167     {
00168       String *res;
00169       if (!(res= str_op(&str_value)))
00170         return NULL;
00171 
00172       decimal_value->store(E_DEC_FATAL_ERROR, (char*) res->ptr(),
00173                            res->length(), res->charset());
00174       break;
00175     }
00176   case ROW_RESULT:
00177     assert(0);
00178   }
00179 
00180   return val;
00181 }
00182 
00183 } /* namespace drizzled */