~drizzle-trunk/drizzle/development

466 by Monty Taylor
Fixed modelines... these files are c++.
1
/* - mode: c++; c-basic-offset: 2; indent-tabs-mode: nil; -*-
438.4.1 by Lee
breaking out enum field classes
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
1241.9.36 by Monty Taylor
ZOMG. I deleted drizzled/server_includes.h.
22
#include "config.h"
934.4.1 by Jay Pipes
Fixes ENUM field type to throw an error on bad data input. 0 is now not
23
#include "drizzled/field/enum.h"
24
#include "drizzled/error.h"
25
#include "drizzled/table.h"
26
#include "drizzled/session.h"
1241.9.12 by Monty Taylor
Trims more out of server_includes.h.
27
#include "drizzled/strfunc.h"
934.4.1 by Jay Pipes
Fixes ENUM field type to throw an error on bad data input. 0 is now not
28
29
#include <sstream>
30
#include <string>
438.4.1 by Lee
breaking out enum field classes
31
1280.1.10 by Monty Taylor
Put everything in drizzled into drizzled namespace.
32
namespace drizzled
33
{
1253.1.3 by Monty Taylor
MEM_ROOT == memory::Root
34
438.4.1 by Lee
breaking out enum field classes
35
/****************************************************************************
36
** enum type.
37
** This is a string which only can have a selection of different values.
38
** If one uses this string in a number context one gets the type number.
39
****************************************************************************/
40
41
enum ha_base_keytype Field_enum::key_type() const
42
{
934.4.1 by Jay Pipes
Fixes ENUM field type to throw an error on bad data input. 0 is now not
43
  switch (packlength) 
44
  {
45
    default: return HA_KEYTYPE_BINARY;
46
    case 2: assert(1);
47
    case 3: assert(1);
48
    case 4: return HA_KEYTYPE_ULONG_INT;
49
    case 8: return HA_KEYTYPE_ULONGLONG;
438.4.1 by Lee
breaking out enum field classes
50
  }
51
}
52
53
void Field_enum::store_type(uint64_t value)
54
{
55
  switch (packlength) {
481 by Brian Aker
Remove all of uchar.
56
  case 1: ptr[0]= (unsigned char) value;  break;
438.4.1 by Lee
breaking out enum field classes
57
  case 2:
58
#ifdef WORDS_BIGENDIAN
59
  if (table->s->db_low_byte_first)
60
  {
61
    int2store(ptr,(unsigned short) value);
62
  }
63
  else
64
#endif
65
    shortstore(ptr,(unsigned short) value);
66
  break;
67
  case 3: int3store(ptr,(long) value); break;
68
  case 4:
69
#ifdef WORDS_BIGENDIAN
70
  if (table->s->db_low_byte_first)
71
  {
72
    int4store(ptr,value);
73
  }
74
  else
75
#endif
76
    longstore(ptr,(long) value);
77
  break;
78
  case 8:
79
#ifdef WORDS_BIGENDIAN
80
  if (table->s->db_low_byte_first)
81
  {
82
    int8store(ptr,value);
83
  }
84
  else
85
#endif
86
    int64_tstore(ptr,value); break;
87
  }
88
}
89
90
/**
934.4.1 by Jay Pipes
Fixes ENUM field type to throw an error on bad data input. 0 is now not
91
 * Given a supplied string, looks up the string in the internal typelib
92
 * and stores the found key.  Upon not finding an entry in the typelib, 
93
 * we always throw an error.
94
 */
95
int Field_enum::store(const char *from, uint32_t length, const CHARSET_INFO * const)
438.4.1 by Lee
breaking out enum field classes
96
{
934.4.1 by Jay Pipes
Fixes ENUM field type to throw an error on bad data input. 0 is now not
97
  uint32_t tmp;
438.4.1 by Lee
breaking out enum field classes
98
1089.1.3 by Brian Aker
Fix protobuf to release memory. Add in assert() for wrong column usage. Fix
99
  ASSERT_COLUMN_MARKED_FOR_WRITE;
100
438.4.1 by Lee
breaking out enum field classes
101
  /* Remove end space */
102
  length= field_charset->cset->lengthsp(field_charset, from, length);
934.4.1 by Jay Pipes
Fixes ENUM field type to throw an error on bad data input. 0 is now not
103
  tmp= find_type2(typelib, from, length, field_charset);
104
  if (! tmp)
438.4.1 by Lee
breaking out enum field classes
105
  {
934.4.1 by Jay Pipes
Fixes ENUM field type to throw an error on bad data input. 0 is now not
106
    if (length < 6) /* Can't be more than 99999 enums */
438.4.1 by Lee
breaking out enum field classes
107
    {
108
      /* This is for reading numbers with LOAD DATA INFILE */
934.4.1 by Jay Pipes
Fixes ENUM field type to throw an error on bad data input. 0 is now not
109
      /* Convert the string to an integer using stringstream */
110
      std::stringstream ss;
111
      ss << from;
112
      ss >> tmp;
113
114
      if (tmp == 0 || tmp > typelib->count)
438.4.1 by Lee
breaking out enum field classes
115
      {
934.4.1 by Jay Pipes
Fixes ENUM field type to throw an error on bad data input. 0 is now not
116
        my_error(ER_INVALID_ENUM_VALUE, MYF(ME_FATALERROR), from);
117
        return 1;
438.4.1 by Lee
breaking out enum field classes
118
      }
119
    }
120
    else
934.4.1 by Jay Pipes
Fixes ENUM field type to throw an error on bad data input. 0 is now not
121
    {
122
      my_error(ER_INVALID_ENUM_VALUE, MYF(ME_FATALERROR), from);
123
      return 1;
124
    }
438.4.1 by Lee
breaking out enum field classes
125
  }
126
  store_type((uint64_t) tmp);
934.4.1 by Jay Pipes
Fixes ENUM field type to throw an error on bad data input. 0 is now not
127
  return 0;
128
}
129
130
int Field_enum::store(double from)
131
{
132
  return Field_enum::store((int64_t) from, false);
133
}
134
135
/**
136
 * @note MySQL allows 0 values, saying that 0 is "the index of the
137
 * blank string error", whatever that means.  Uhm, Drizzle doesn't
138
 * allow this.  To store an ENUM column value using an integer, you
139
 * must specify the 1-based index of the enum column definition's 
140
 * key.
141
 */
142
int Field_enum::store(int64_t from, bool)
143
{
1089.1.3 by Brian Aker
Fix protobuf to release memory. Add in assert() for wrong column usage. Fix
144
  ASSERT_COLUMN_MARKED_FOR_WRITE;
145
934.4.1 by Jay Pipes
Fixes ENUM field type to throw an error on bad data input. 0 is now not
146
  if (from <= 0 || (uint64_t) from > typelib->count)
438.4.1 by Lee
breaking out enum field classes
147
  {
934.4.1 by Jay Pipes
Fixes ENUM field type to throw an error on bad data input. 0 is now not
148
    /* Convert the integer to a string using stringstream */
149
    std::stringstream ss;
150
    std::string tmp;
151
    ss << from; ss >> tmp;
152
153
    my_error(ER_INVALID_ENUM_VALUE, MYF(ME_FATALERROR), tmp.c_str());
154
    return 1;
438.4.1 by Lee
breaking out enum field classes
155
  }
934.4.1 by Jay Pipes
Fixes ENUM field type to throw an error on bad data input. 0 is now not
156
  store_type((uint64_t) (uint32_t) from);
157
  return 0;
438.4.1 by Lee
breaking out enum field classes
158
}
159
160
double Field_enum::val_real(void)
161
{
162
  return (double) Field_enum::val_int();
163
}
164
165
int64_t Field_enum::val_int(void)
166
{
1089.1.3 by Brian Aker
Fix protobuf to release memory. Add in assert() for wrong column usage. Fix
167
  ASSERT_COLUMN_MARKED_FOR_READ;
168
438.4.1 by Lee
breaking out enum field classes
169
  switch (packlength) {
170
  case 1:
171
    return (int64_t) ptr[0];
172
  case 2:
173
  {
174
    uint16_t tmp;
175
#ifdef WORDS_BIGENDIAN
176
    if (table->s->db_low_byte_first)
177
      tmp=sint2korr(ptr);
178
    else
179
#endif
180
      shortget(tmp,ptr);
181
    return (int64_t) tmp;
182
  }
183
  case 3:
184
    return (int64_t) uint3korr(ptr);
185
  case 4:
186
  {
187
    uint32_t tmp;
188
#ifdef WORDS_BIGENDIAN
189
    if (table->s->db_low_byte_first)
190
      tmp=uint4korr(ptr);
191
    else
192
#endif
193
      longget(tmp,ptr);
194
    return (int64_t) tmp;
195
  }
196
  case 8:
197
  {
198
    int64_t tmp;
199
#ifdef WORDS_BIGENDIAN
200
    if (table->s->db_low_byte_first)
201
      tmp=sint8korr(ptr);
202
    else
203
#endif
204
      int64_tget(tmp,ptr);
205
    return tmp;
206
  }
207
  }
208
  return 0;					// impossible
209
}
210
934.4.1 by Jay Pipes
Fixes ENUM field type to throw an error on bad data input. 0 is now not
211
String *Field_enum::val_str(String *, String *val_ptr)
438.4.1 by Lee
breaking out enum field classes
212
{
895 by Brian Aker
Completion (?) of uint conversion.
213
  uint32_t tmp=(uint32_t) Field_enum::val_int();
1089.1.3 by Brian Aker
Fix protobuf to release memory. Add in assert() for wrong column usage. Fix
214
215
  ASSERT_COLUMN_MARKED_FOR_READ;
216
438.4.1 by Lee
breaking out enum field classes
217
  if (!tmp || tmp > typelib->count)
1530.1.1 by Brian Aker
Removes typelib usage from fieldname
218
  {
438.4.1 by Lee
breaking out enum field classes
219
    val_ptr->set("", 0, field_charset);
1530.1.1 by Brian Aker
Removes typelib usage from fieldname
220
  }
438.4.1 by Lee
breaking out enum field classes
221
  else
1530.1.1 by Brian Aker
Removes typelib usage from fieldname
222
  {
223
    val_ptr->set((const char*) typelib->type_names[tmp-1], typelib->type_lengths[tmp-1], field_charset);
224
  }
225
438.4.1 by Lee
breaking out enum field classes
226
  return val_ptr;
227
}
228
481 by Brian Aker
Remove all of uchar.
229
int Field_enum::cmp(const unsigned char *a_ptr, const unsigned char *b_ptr)
438.4.1 by Lee
breaking out enum field classes
230
{
481 by Brian Aker
Remove all of uchar.
231
  unsigned char *old= ptr;
232
  ptr= (unsigned char*) a_ptr;
438.4.1 by Lee
breaking out enum field classes
233
  uint64_t a=Field_enum::val_int();
481 by Brian Aker
Remove all of uchar.
234
  ptr= (unsigned char*) b_ptr;
438.4.1 by Lee
breaking out enum field classes
235
  uint64_t b=Field_enum::val_int();
236
  ptr= old;
237
  return (a < b) ? -1 : (a > b) ? 1 : 0;
238
}
239
779.1.27 by Monty Taylor
Got rid of __attribute__((unused)) and the like from the .cc files.
240
void Field_enum::sort_string(unsigned char *to,uint32_t )
438.4.1 by Lee
breaking out enum field classes
241
{
242
  uint64_t value=Field_enum::val_int();
243
  to+=packlength-1;
482 by Brian Aker
Remove uint.
244
  for (uint32_t i=0 ; i < packlength ; i++)
438.4.1 by Lee
breaking out enum field classes
245
  {
481 by Brian Aker
Remove all of uchar.
246
    *to-- = (unsigned char) (value & 255);
438.4.1 by Lee
breaking out enum field classes
247
    value>>=8;
248
  }
249
}
250
251
void Field_enum::sql_type(String &res) const
252
{
253
  char buffer[255];
254
  String enum_item(buffer, sizeof(buffer), res.charset());
255
256
  res.length(0);
257
  res.append(STRING_WITH_LEN("enum("));
258
259
  bool flag=0;
482 by Brian Aker
Remove uint.
260
  uint32_t *len= typelib->type_lengths;
438.4.1 by Lee
breaking out enum field classes
261
  for (const char **pos= typelib->type_names; *pos; pos++, len++)
262
  {
482 by Brian Aker
Remove uint.
263
    uint32_t dummy_errors;
438.4.1 by Lee
breaking out enum field classes
264
    if (flag)
265
      res.append(',');
266
    /* convert to res.charset() == utf8, then quote */
267
    enum_item.copy(*pos, *len, charset(), res.charset(), &dummy_errors);
814.1.1 by Jay Pipes
Fix for Bug 314502 "show create table crashes with multi-byte character in enum description"
268
    append_unescaped(&res, enum_item.c_ptr(), enum_item.length());
438.4.1 by Lee
breaking out enum field classes
269
    flag= 1;
270
  }
271
  res.append(')');
272
}
273
1253.1.3 by Monty Taylor
MEM_ROOT == memory::Root
274
Field *Field_enum::new_field(memory::Root *root, Table *new_table,
438.4.1 by Lee
breaking out enum field classes
275
                             bool keep_type)
276
{
277
  Field_enum *res= (Field_enum*) Field::new_field(root, new_table, keep_type);
278
  if (res)
1530.1.1 by Brian Aker
Removes typelib usage from fieldname
279
  {
438.4.1 by Lee
breaking out enum field classes
280
    res->typelib= copy_typelib(root, typelib);
1530.1.1 by Brian Aker
Removes typelib usage from fieldname
281
  }
438.4.1 by Lee
breaking out enum field classes
282
  return res;
283
}
1280.1.10 by Monty Taylor
Put everything in drizzled into drizzled namespace.
284
285
} /* namespace drizzled */