~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to drizzled/field/short.cc

Merged in changes from Andrey.

Show diffs side-by-side

added added

removed removed

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