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