~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/long.h>
173.1.12 by Toru Maesaka
Moved out SHORT, LONG and INT64_T to field/
26
27
/****************************************************************************
28
** long int
29
****************************************************************************/
30
31
int Field_long::store(const char *from,uint len,CHARSET_INFO *cs)
32
{
33
  long store_tmp;
34
  int error;
35
  int64_t rnd;
36
  
37
  error= get_int(cs, from, len, &rnd, UINT32_MAX, INT32_MIN, INT32_MAX);
38
  store_tmp= unsigned_flag ? (long) (uint64_t) rnd : (long) rnd;
39
#ifdef WORDS_BIGENDIAN
40
  if (table->s->db_low_byte_first)
41
  {
42
    int4store(ptr, store_tmp);
43
  }
44
  else
45
#endif
46
    longstore(ptr, store_tmp);
47
  return error;
48
}
49
50
51
int Field_long::store(double nr)
52
{
53
  int error= 0;
205 by Brian Aker
uint32 -> uin32_t
54
  int32_t res;
173.1.12 by Toru Maesaka
Moved out SHORT, LONG and INT64_T to field/
55
  nr=rint(nr);
56
  if (unsigned_flag)
57
  {
58
    if (nr < 0)
59
    {
60
      res=0;
61
      error= 1;
62
    }
63
    else if (nr > (double) UINT32_MAX)
64
    {
65
      res= INT32_MAX;
66
      set_warning(MYSQL_ERROR::WARN_LEVEL_WARN, ER_WARN_DATA_OUT_OF_RANGE, 1);
67
      error= 1;
68
    }
69
    else
205 by Brian Aker
uint32 -> uin32_t
70
      res=(int32_t) (ulong) nr;
173.1.12 by Toru Maesaka
Moved out SHORT, LONG and INT64_T to field/
71
  }
72
  else
73
  {
74
    if (nr < (double) INT32_MIN)
75
    {
205 by Brian Aker
uint32 -> uin32_t
76
      res=(int32_t) INT32_MIN;
173.1.12 by Toru Maesaka
Moved out SHORT, LONG and INT64_T to field/
77
      error= 1;
78
    }
79
    else if (nr > (double) INT32_MAX)
80
    {
205 by Brian Aker
uint32 -> uin32_t
81
      res=(int32_t) INT32_MAX;
173.1.12 by Toru Maesaka
Moved out SHORT, LONG and INT64_T to field/
82
      error= 1;
83
    }
84
    else
205 by Brian Aker
uint32 -> uin32_t
85
      res=(int32_t) (int64_t) nr;
173.1.12 by Toru Maesaka
Moved out SHORT, LONG and INT64_T to field/
86
  }
87
  if (error)
88
    set_warning(MYSQL_ERROR::WARN_LEVEL_WARN, ER_WARN_DATA_OUT_OF_RANGE, 1);
89
90
#ifdef WORDS_BIGENDIAN
91
  if (table->s->db_low_byte_first)
92
  {
93
    int4store(ptr,res);
94
  }
95
  else
96
#endif
97
    longstore(ptr,res);
98
  return error;
99
}
100
101
102
int Field_long::store(int64_t nr, bool unsigned_val)
103
{
104
  int error= 0;
205 by Brian Aker
uint32 -> uin32_t
105
  int32_t res;
173.1.12 by Toru Maesaka
Moved out SHORT, LONG and INT64_T to field/
106
107
  if (unsigned_flag)
108
  {
109
    if (nr < 0 && !unsigned_val)
110
    {
111
      res=0;
112
      error= 1;
113
    }
114
    else if ((uint64_t) nr >= (1LL << 32))
115
    {
205 by Brian Aker
uint32 -> uin32_t
116
      res=(int32_t) (uint32_t) ~0L;
173.1.12 by Toru Maesaka
Moved out SHORT, LONG and INT64_T to field/
117
      error= 1;
118
    }
119
    else
205 by Brian Aker
uint32 -> uin32_t
120
      res=(int32_t) (uint32_t) nr;
173.1.12 by Toru Maesaka
Moved out SHORT, LONG and INT64_T to field/
121
  }
122
  else
123
  {
124
    if (nr < 0 && unsigned_val)
125
      nr= ((int64_t) INT32_MAX) + 1;           // Generate overflow
126
    if (nr < (int64_t) INT32_MIN) 
127
    {
205 by Brian Aker
uint32 -> uin32_t
128
      res=(int32_t) INT32_MIN;
173.1.12 by Toru Maesaka
Moved out SHORT, LONG and INT64_T to field/
129
      error= 1;
130
    }
131
    else if (nr > (int64_t) INT32_MAX)
132
    {
205 by Brian Aker
uint32 -> uin32_t
133
      res=(int32_t) INT32_MAX;
173.1.12 by Toru Maesaka
Moved out SHORT, LONG and INT64_T to field/
134
      error= 1;
135
    }
136
    else
205 by Brian Aker
uint32 -> uin32_t
137
      res=(int32_t) nr;
173.1.12 by Toru Maesaka
Moved out SHORT, LONG and INT64_T to field/
138
  }
139
  if (error)
140
    set_warning(MYSQL_ERROR::WARN_LEVEL_WARN, ER_WARN_DATA_OUT_OF_RANGE, 1);
141
142
#ifdef WORDS_BIGENDIAN
143
  if (table->s->db_low_byte_first)
144
  {
145
    int4store(ptr,res);
146
  }
147
  else
148
#endif
149
    longstore(ptr,res);
150
  return error;
151
}
152
153
154
double Field_long::val_real(void)
155
{
205 by Brian Aker
uint32 -> uin32_t
156
  int32_t j;
173.1.12 by Toru Maesaka
Moved out SHORT, LONG and INT64_T to field/
157
#ifdef WORDS_BIGENDIAN
158
  if (table->s->db_low_byte_first)
159
    j=sint4korr(ptr);
160
  else
161
#endif
162
    longget(j,ptr);
205 by Brian Aker
uint32 -> uin32_t
163
  return unsigned_flag ? (double) (uint32_t) j : (double) j;
173.1.12 by Toru Maesaka
Moved out SHORT, LONG and INT64_T to field/
164
}
165
166
int64_t Field_long::val_int(void)
167
{
205 by Brian Aker
uint32 -> uin32_t
168
  int32_t j;
173.1.12 by Toru Maesaka
Moved out SHORT, LONG and INT64_T to field/
169
  /* See the comment in Field_long::store(long long) */
170
  assert(table->in_use == current_thd);
171
#ifdef WORDS_BIGENDIAN
172
  if (table->s->db_low_byte_first)
173
    j=sint4korr(ptr);
174
  else
175
#endif
176
    longget(j,ptr);
205 by Brian Aker
uint32 -> uin32_t
177
  return unsigned_flag ? (int64_t) (uint32_t) j : (int64_t) j;
173.1.12 by Toru Maesaka
Moved out SHORT, LONG and INT64_T to field/
178
}
179
180
String *Field_long::val_str(String *val_buffer,
181
			    String *val_ptr __attribute__((unused)))
182
{
183
  CHARSET_INFO *cs= &my_charset_bin;
184
  uint length;
185
  uint mlength=max(field_length+1,12*cs->mbmaxlen);
186
  val_buffer->alloc(mlength);
187
  char *to=(char*) val_buffer->ptr();
205 by Brian Aker
uint32 -> uin32_t
188
  int32_t j;
173.1.12 by Toru Maesaka
Moved out SHORT, LONG and INT64_T to field/
189
#ifdef WORDS_BIGENDIAN
190
  if (table->s->db_low_byte_first)
191
    j=sint4korr(ptr);
192
  else
193
#endif
194
    longget(j,ptr);
195
196
  if (unsigned_flag)
205 by Brian Aker
uint32 -> uin32_t
197
    length=cs->cset->long10_to_str(cs,to,mlength, 10,(long) (uint32_t)j);
173.1.12 by Toru Maesaka
Moved out SHORT, LONG and INT64_T to field/
198
  else
199
    length=cs->cset->long10_to_str(cs,to,mlength,-10,(long) j);
200
  val_buffer->length(length);
201
  if (zerofill)
202
    prepend_zeros(val_buffer);
203
  return val_buffer;
204
}
205
206
207
bool Field_long::send_binary(Protocol *protocol)
208
{
209
  return protocol->store_long(Field_long::val_int());
210
}
211
212
int Field_long::cmp(const uchar *a_ptr, const uchar *b_ptr)
213
{
205 by Brian Aker
uint32 -> uin32_t
214
  int32_t a,b;
173.1.12 by Toru Maesaka
Moved out SHORT, LONG and INT64_T to field/
215
#ifdef WORDS_BIGENDIAN
216
  if (table->s->db_low_byte_first)
217
  {
218
    a=sint4korr(a_ptr);
219
    b=sint4korr(b_ptr);
220
  }
221
  else
222
#endif
223
  {
224
    longget(a,a_ptr);
225
    longget(b,b_ptr);
226
  }
227
  if (unsigned_flag)
205 by Brian Aker
uint32 -> uin32_t
228
    return ((uint32_t) a < (uint32_t) b) ? -1 : ((uint32_t) a > (uint32_t) b) ? 1 : 0;
173.1.12 by Toru Maesaka
Moved out SHORT, LONG and INT64_T to field/
229
  return (a < b) ? -1 : (a > b) ? 1 : 0;
230
}
231
232
void Field_long::sort_string(uchar *to,uint length __attribute__((unused)))
233
{
234
#ifdef WORDS_BIGENDIAN
235
  if (!table->s->db_low_byte_first)
236
  {
237
    if (unsigned_flag)
238
      to[0] = ptr[0];
239
    else
240
      to[0] = (char) (ptr[0] ^ 128);		/* Revers signbit */
241
    to[1]   = ptr[1];
242
    to[2]   = ptr[2];
243
    to[3]   = ptr[3];
244
  }
245
  else
246
#endif
247
  {
248
    if (unsigned_flag)
249
      to[0] = ptr[3];
250
    else
251
      to[0] = (char) (ptr[3] ^ 128);		/* Revers signbit */
252
    to[1]   = ptr[2];
253
    to[2]   = ptr[1];
254
    to[3]   = ptr[0];
255
  }
256
}
257
258
259
void Field_long::sql_type(String &res) const
260
{
261
  CHARSET_INFO *cs=res.charset();
262
  res.length(cs->cset->snprintf(cs,(char*) res.ptr(),res.alloced_length(),
263
			  "int(%d)",(int) field_length));
264
  add_zerofill_and_unsigned(res);
265
}
266