~drizzle-trunk/drizzle/development

173.1.12 by Toru Maesaka
Moved out SHORT, LONG and INT64_T to field/
1
/* - mode: c; c-basic-offset: 2; indent-tabs-mode: nil; -*-
2
 *  vim:expandtab:shiftwidth=2:tabstop=2:smarttab:
3
 *
4
 *  Copyright (C) 2008 MySQL
5
 *
6
 *  This program is free software; you can redistribute it and/or modify
7
 *  it under the terms of the GNU General Public License as published by
8
 *  the Free Software Foundation; either version 2 of the License, or
9
 *  (at your option) any later version.
10
 *
11
 *  This program is distributed in the hope that it will be useful,
12
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
13
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14
 *  GNU General Public License for more details.
15
 *
16
 *  You should have received a copy of the GNU General Public License
17
 *  along with this program; if not, write to the Free Software
18
 *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
19
 */
20
21
#ifdef USE_PRAGMA_IMPLEMENTATION
22
#pragma implementation				// gcc: Class implementation
23
#endif
24
214 by Brian Aker
Rename of fields (fix issue with string and decimal .h clashing).
25
#include <drizzled/field/int64_t.h>
173.1.12 by Toru Maesaka
Moved out SHORT, LONG and INT64_T to field/
26
27
/****************************************************************************
28
 Field type int64_t int (8 bytes)
29
****************************************************************************/
30
31
int Field_int64_t::store(const char *from,uint len,CHARSET_INFO *cs)
32
{
33
  int error= 0;
34
  char *end;
35
  uint64_t tmp;
36
37
  tmp= cs->cset->strntoull10rnd(cs,from,len,unsigned_flag,&end,&error);
38
  if (error == MY_ERRNO_ERANGE)
39
  {
40
    set_warning(MYSQL_ERROR::WARN_LEVEL_WARN, ER_WARN_DATA_OUT_OF_RANGE, 1);
41
    error= 1;
42
  }
43
  else if (table->in_use->count_cuted_fields && 
44
           check_int(cs, from, len, end, error))
45
    error= 1;
46
  else
47
    error= 0;
48
#ifdef WORDS_BIGENDIAN
49
  if (table->s->db_low_byte_first)
50
  {
51
    int8store(ptr,tmp);
52
  }
53
  else
54
#endif
55
    int64_tstore(ptr,tmp);
56
  return error;
57
}
58
59
60
int Field_int64_t::store(double nr)
61
{
62
  int error= 0;
63
  int64_t res;
64
65
  nr= rint(nr);
66
  if (unsigned_flag)
67
  {
68
    if (nr < 0)
69
    {
70
      res=0;
71
      error= 1;
72
    }
73
    else if (nr >= (double) UINT64_MAX)
74
    {
75
      res= ~(int64_t) 0;
76
      error= 1;
77
    }
78
    else
79
      res=(int64_t) (uint64_t) nr;
80
  }
81
  else
82
  {
83
    if (nr <= (double) INT64_MIN)
84
    {
85
      res= INT64_MIN;
86
      error= (nr < (double) INT64_MIN);
87
    }
88
    else if (nr >= (double) (uint64_t) INT64_MAX)
89
    {
90
      res= INT64_MAX;
91
      error= (nr > (double) INT64_MAX);
92
    }
93
    else
94
      res=(int64_t) nr;
95
  }
96
  if (error)
97
    set_warning(MYSQL_ERROR::WARN_LEVEL_WARN, ER_WARN_DATA_OUT_OF_RANGE, 1);
98
99
#ifdef WORDS_BIGENDIAN
100
  if (table->s->db_low_byte_first)
101
  {
102
    int8store(ptr,res);
103
  }
104
  else
105
#endif
106
    int64_tstore(ptr,res);
107
  return error;
108
}
109
110
111
int Field_int64_t::store(int64_t nr, bool unsigned_val)
112
{
113
  int error= 0;
114
115
  if (nr < 0)                                   // Only possible error
116
  {
117
    /*
118
      if field is unsigned and value is signed (< 0) or
119
      if field is signed and value is unsigned we have an overflow
120
    */
121
    if (unsigned_flag != unsigned_val)
122
    {
123
      nr= unsigned_flag ? (uint64_t) 0 : (uint64_t) INT64_MAX;
124
      set_warning(MYSQL_ERROR::WARN_LEVEL_WARN, ER_WARN_DATA_OUT_OF_RANGE, 1);
125
      error= 1;
126
    }
127
  }
128
129
#ifdef WORDS_BIGENDIAN
130
  if (table->s->db_low_byte_first)
131
  {
132
    int8store(ptr,nr);
133
  }
134
  else
135
#endif
136
    int64_tstore(ptr,nr);
137
  return error;
138
}
139
140
141
double Field_int64_t::val_real(void)
142
{
143
  int64_t j;
144
#ifdef WORDS_BIGENDIAN
145
  if (table->s->db_low_byte_first)
146
  {
147
    j=sint8korr(ptr);
148
  }
149
  else
150
#endif
151
    int64_tget(j,ptr);
152
  /* The following is open coded to avoid a bug in gcc 3.3 */
153
  if (unsigned_flag)
154
  {
155
    uint64_t tmp= (uint64_t) j;
156
    return uint64_t2double(tmp);
157
  }
158
  return (double) j;
159
}
160
161
162
int64_t Field_int64_t::val_int(void)
163
{
164
  int64_t j;
165
#ifdef WORDS_BIGENDIAN
166
  if (table->s->db_low_byte_first)
167
    j=sint8korr(ptr);
168
  else
169
#endif
170
    int64_tget(j,ptr);
171
  return j;
172
}
173
174
175
String *Field_int64_t::val_str(String *val_buffer,
176
				String *val_ptr __attribute__((unused)))
177
{
178
  CHARSET_INFO *cs= &my_charset_bin;
179
  uint length;
180
  uint mlength=max(field_length+1,22*cs->mbmaxlen);
181
  val_buffer->alloc(mlength);
182
  char *to=(char*) val_buffer->ptr();
183
  int64_t j;
184
#ifdef WORDS_BIGENDIAN
185
  if (table->s->db_low_byte_first)
186
    j=sint8korr(ptr);
187
  else
188
#endif
189
    int64_tget(j,ptr);
190
191
  length=(uint) (cs->cset->int64_t10_to_str)(cs,to,mlength,
192
					unsigned_flag ? 10 : -10, j);
193
  val_buffer->length(length);
194
  if (zerofill)
195
    prepend_zeros(val_buffer);
196
  return val_buffer;
197
}
198
199
200
bool Field_int64_t::send_binary(Protocol *protocol)
201
{
202
  return protocol->store_int64_t(Field_int64_t::val_int(), unsigned_flag);
203
}
204
205
206
int Field_int64_t::cmp(const uchar *a_ptr, const uchar *b_ptr)
207
{
208
  int64_t a,b;
209
#ifdef WORDS_BIGENDIAN
210
  if (table->s->db_low_byte_first)
211
  {
212
    a=sint8korr(a_ptr);
213
    b=sint8korr(b_ptr);
214
  }
215
  else
216
#endif
217
  {
218
    int64_tget(a,a_ptr);
219
    int64_tget(b,b_ptr);
220
  }
221
  if (unsigned_flag)
222
    return ((uint64_t) a < (uint64_t) b) ? -1 :
223
    ((uint64_t) a > (uint64_t) b) ? 1 : 0;
224
  return (a < b) ? -1 : (a > b) ? 1 : 0;
225
}
226
227
void Field_int64_t::sort_string(uchar *to,uint length __attribute__((unused)))
228
{
229
#ifdef WORDS_BIGENDIAN
230
  if (!table->s->db_low_byte_first)
231
  {
232
    if (unsigned_flag)
233
      to[0] = ptr[0];
234
    else
235
      to[0] = (char) (ptr[0] ^ 128);		/* Revers signbit */
236
    to[1]   = ptr[1];
237
    to[2]   = ptr[2];
238
    to[3]   = ptr[3];
239
    to[4]   = ptr[4];
240
    to[5]   = ptr[5];
241
    to[6]   = ptr[6];
242
    to[7]   = ptr[7];
243
  }
244
  else
245
#endif
246
  {
247
    if (unsigned_flag)
248
      to[0] = ptr[7];
249
    else
250
      to[0] = (char) (ptr[7] ^ 128);		/* Revers signbit */
251
    to[1]   = ptr[6];
252
    to[2]   = ptr[5];
253
    to[3]   = ptr[4];
254
    to[4]   = ptr[3];
255
    to[5]   = ptr[2];
256
    to[6]   = ptr[1];
257
    to[7]   = ptr[0];
258
  }
259
}
260
261
262
void Field_int64_t::sql_type(String &res) const
263
{
264
  CHARSET_INFO *cs=res.charset();
265
  res.length(cs->cset->snprintf(cs,(char*) res.ptr(),res.alloced_length(),
266
			  "bigint(%d)",(int) field_length));
267
  add_zerofill_and_unsigned(res);
268
}
269
270
271
/*
272
  Floating-point numbers
273
 */
274
275
uchar *
276
Field_real::pack(uchar *to, const uchar *from,
277
                 uint max_length, bool low_byte_first)
278
{
279
  assert(max_length >= pack_length());
280
#ifdef WORDS_BIGENDIAN
281
  if (low_byte_first != table->s->db_low_byte_first)
282
  {
283
    const uchar *dptr= from + pack_length();
284
    while (dptr-- > from)
285
      *to++ = *dptr;
286
    return(to);
287
  }
288
  else
289
#endif
290
    return(Field::pack(to, from, max_length, low_byte_first));
291
}
292
293
const uchar *
294
Field_real::unpack(uchar *to, const uchar *from,
295
                   uint param_data, bool low_byte_first)
296
{
297
#ifdef WORDS_BIGENDIAN
298
  if (low_byte_first != table->s->db_low_byte_first)
299
  {
300
    const uchar *dptr= from + pack_length();
301
    while (dptr-- > from)
302
      *to++ = *dptr;
303
    return(from + pack_length());
304
  }
305
  else
306
#endif
307
    return(Field::unpack(to, from, param_data, low_byte_first));
308
}
309