00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
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;
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;
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;
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 }