00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022 #include <config.h>
00023 #include <drizzled/field/size.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 #include <math.h>
00030
00031 #include <algorithm>
00032
00033 using namespace std;
00034
00035 namespace drizzled
00036 {
00037
00038 namespace field
00039 {
00040
00041
00042
00043
00044
00045 Size::Size(unsigned char *ptr_arg, uint32_t len_arg,
00046 unsigned char *null_ptr_arg,
00047 unsigned char null_bit_arg,
00048 enum utype unireg_check_arg,
00049 const char *field_name_arg) :
00050 Field_num(ptr_arg,
00051 len_arg,
00052 null_ptr_arg,
00053 null_bit_arg,
00054 unireg_check_arg,
00055 field_name_arg,
00056 0, false, true)
00057 {
00058 flags|= UNSIGNED_FLAG;
00059 }
00060
00061 Size::Size(uint32_t len_arg,bool maybe_null_arg,
00062 const char *field_name_arg,
00063 bool unsigned_arg) :
00064 Field_num((unsigned char*) 0,
00065 len_arg, maybe_null_arg ? (unsigned char*) "": 0,
00066 0,
00067 NONE,
00068 field_name_arg,
00069 0,
00070 0,
00071 unsigned_arg)
00072 {
00073 flags|= UNSIGNED_FLAG;
00074 assert(unsigned_arg);
00075 }
00076
00077 int Size::store(const char *from,uint32_t len, const CHARSET_INFO * const cs)
00078 {
00079 int error= 0;
00080 char *end;
00081 uint64_t tmp;
00082
00083 ASSERT_COLUMN_MARKED_FOR_WRITE;
00084
00085 tmp= cs->cset->strntoull10rnd(cs, from, len, false, &end,&error);
00086 if (error == MY_ERRNO_ERANGE)
00087 {
00088 set_warning(DRIZZLE_ERROR::WARN_LEVEL_WARN, ER_WARN_DATA_OUT_OF_RANGE, 1);
00089 error= 1;
00090 }
00091 else if (getTable()->in_use->count_cuted_fields && check_int(cs, from, len, end, error))
00092 {
00093 error= 1;
00094 }
00095 else
00096 {
00097 error= 0;
00098 }
00099
00100 int64_tstore(ptr,tmp);
00101
00102 return error;
00103 }
00104
00105
00106 int Size::store(double nr)
00107 {
00108 int error= 0;
00109 int64_t res;
00110
00111 ASSERT_COLUMN_MARKED_FOR_WRITE;
00112
00113 nr= rint(nr);
00114
00115 if (nr <= (double) INT64_MIN)
00116 {
00117 res= INT64_MIN;
00118 error= (nr < (double) INT64_MIN);
00119 }
00120 else if (nr >= (double) (uint64_t) INT64_MAX)
00121 {
00122 res= INT64_MAX;
00123 error= (nr > (double) INT64_MAX);
00124 }
00125 else
00126 {
00127 res=(int64_t) nr;
00128 }
00129
00130 if (error)
00131 {
00132 set_warning(DRIZZLE_ERROR::WARN_LEVEL_WARN, ER_WARN_DATA_OUT_OF_RANGE, 1);
00133 return 0;
00134 }
00135
00136 int64_tstore(ptr, res);
00137
00138 return error;
00139 }
00140
00141
00142 int Size::store(int64_t nr, bool arg)
00143 {
00144 int error= 0;
00145
00146 ASSERT_COLUMN_MARKED_FOR_WRITE;
00147
00148 if (not arg and nr < 0)
00149 {
00150 set_warning(DRIZZLE_ERROR::WARN_LEVEL_WARN, ER_WARN_DATA_OUT_OF_RANGE, 1);
00151 return 0;
00152 }
00153
00154 int64_tstore(ptr,nr);
00155
00156 return error;
00157 }
00158
00159
00160 double Size::val_real(void) const
00161 {
00162 int64_t j;
00163
00164 ASSERT_COLUMN_MARKED_FOR_READ;
00165
00166 int64_tget(j,ptr);
00167
00168 return (double) j;
00169 }
00170
00171
00172 int64_t Size::val_int(void) const
00173 {
00174 int64_t j;
00175
00176 ASSERT_COLUMN_MARKED_FOR_READ;
00177
00178 int64_tget(j,ptr);
00179
00180 return j;
00181 }
00182
00183
00184 String *Size::val_str(String *val_buffer, String *) const
00185 {
00186 const CHARSET_INFO * const cs= &my_charset_bin;
00187 uint32_t length;
00188 uint32_t mlength= max(field_length+1,22*cs->mbmaxlen);
00189 val_buffer->alloc(mlength);
00190 char *to=(char*) val_buffer->ptr();
00191 int64_t j;
00192
00193 ASSERT_COLUMN_MARKED_FOR_READ;
00194
00195 int64_tget(j,ptr);
00196
00197 length=(uint32_t) (cs->cset->int64_t10_to_str)(cs,to,mlength, -10, j);
00198 val_buffer->length(length);
00199
00200 return val_buffer;
00201 }
00202
00203 int Size::cmp(const unsigned char *a_ptr, const unsigned char *b_ptr)
00204 {
00205 int64_t a,b;
00206
00207 int64_tget(a,a_ptr);
00208 int64_tget(b,b_ptr);
00209
00210 return (a < b) ? -1 : (a > b) ? 1 : 0;
00211 }
00212
00213 void Size::sort_string(unsigned char *to,uint32_t )
00214 {
00215 #ifdef WORDS_BIGENDIAN
00216 {
00217 to[0] = (char) (ptr[0] ^ 128);
00218 to[1] = ptr[1];
00219 to[2] = ptr[2];
00220 to[3] = ptr[3];
00221 to[4] = ptr[4];
00222 to[5] = ptr[5];
00223 to[6] = ptr[6];
00224 to[7] = ptr[7];
00225 }
00226 #else
00227 {
00228 to[0] = (char) (ptr[7] ^ 128);
00229 to[1] = ptr[6];
00230 to[2] = ptr[5];
00231 to[3] = ptr[4];
00232 to[4] = ptr[3];
00233 to[5] = ptr[2];
00234 to[6] = ptr[1];
00235 to[7] = ptr[0];
00236 }
00237 #endif
00238 }
00239
00240
00241 void Size::sql_type(String &res) const
00242 {
00243 const CHARSET_INFO * const cs=res.charset();
00244 res.length(cs->cset->snprintf(cs,(char*) res.ptr(),res.alloced_length(), "unsigned integer"));
00245 }
00246
00247
00248 unsigned char *Size::pack(unsigned char* to, const unsigned char *from, uint32_t, bool)
00249 {
00250 int64_t val;
00251
00252 int64_tget(val, from);
00253 int64_tstore(to, val);
00254
00255 return to + sizeof(val);
00256 }
00257
00258
00259 const unsigned char *Size::unpack(unsigned char* to, const unsigned char *from, uint32_t, bool)
00260 {
00261 int64_t val;
00262
00263 int64_tget(val, from);
00264 int64_tstore(to, val);
00265
00266 return from + sizeof(val);
00267 }
00268
00269 }
00270 }