18
18
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
22
#include <boost/lexical_cast.hpp>
23
#include <drizzled/field/enum.h>
24
#include <drizzled/error.h>
25
#include <drizzled/table.h>
26
#include <drizzled/session.h>
27
#include <drizzled/strfunc.h>
28
#include <drizzled/typelib.h>
22
#include "drizzled/server_includes.h"
23
#include "drizzled/field/enum.h"
24
#include "drizzled/error.h"
25
#include "drizzled/table.h"
26
#include "drizzled/session.h"
36
31
/****************************************************************************
38
33
** This is a string which only can have a selection of different values.
39
34
** If one uses this string in a number context one gets the type number.
40
35
****************************************************************************/
37
enum ha_base_keytype Field_enum::key_type() const
41
default: return HA_KEYTYPE_BINARY;
44
case 4: return HA_KEYTYPE_ULONG_INT;
45
case 8: return HA_KEYTYPE_ULONGLONG;
42
49
void Field_enum::store_type(uint64_t value)
44
value--; /* we store as starting from 0, although SQL starts from 1 */
46
#ifdef WORDS_BIGENDIAN
47
if (getTable()->getShare()->db_low_byte_first)
49
int4store(ptr, (unsigned short) value);
53
longstore(ptr, (unsigned short) value);
52
case 1: ptr[0]= (unsigned char) value; break;
54
#ifdef WORDS_BIGENDIAN
55
if (table->s->db_low_byte_first)
57
int2store(ptr,(unsigned short) value);
61
shortstore(ptr,(unsigned short) value);
63
case 3: int3store(ptr,(long) value); break;
65
#ifdef WORDS_BIGENDIAN
66
if (table->s->db_low_byte_first)
72
longstore(ptr,(long) value);
75
#ifdef WORDS_BIGENDIAN
76
if (table->s->db_low_byte_first)
82
int64_tstore(ptr,value); break;
57
87
* Given a supplied string, looks up the string in the internal typelib
58
* and stores the found key. Upon not finding an entry in the typelib,
88
* and stores the found key. Upon not finding an entry in the typelib,
59
89
* we always throw an error.
61
91
int Field_enum::store(const char *from, uint32_t length, const CHARSET_INFO * const)
67
97
/* Remove end space */
68
98
length= field_charset->cset->lengthsp(field_charset, from, length);
69
tmp= typelib->find_type2(from, length, field_charset);
99
tmp= find_type2(typelib, from, length, field_charset);
72
102
if (length < 6) /* Can't be more than 99999 enums */
102
132
* @note MySQL allows 0 values, saying that 0 is "the index of the
103
133
* blank string error", whatever that means. Uhm, Drizzle doesn't
104
134
* allow this. To store an ENUM column value using an integer, you
105
* must specify the 1-based index of the enum column definition's
135
* must specify the 1-based index of the enum column definition's
108
138
int Field_enum::store(int64_t from, bool)
124
double Field_enum::val_real(void) const
156
double Field_enum::val_real(void)
126
158
return (double) Field_enum::val_int();
129
int64_t Field_enum::val_int(void) const
161
int64_t Field_enum::val_int(void)
131
163
ASSERT_COLUMN_MARKED_FOR_READ;
134
#ifdef WORDS_BIGENDIAN
135
if (getTable()->getShare()->db_low_byte_first)
140
return ((int64_t) tmp) + 1; /* SQL is from 1, we store from 0 */
143
String *Field_enum::val_str(String *, String *val_ptr) const
165
switch (packlength) {
167
return (int64_t) ptr[0];
171
#ifdef WORDS_BIGENDIAN
172
if (table->s->db_low_byte_first)
177
return (int64_t) tmp;
180
return (int64_t) uint3korr(ptr);
184
#ifdef WORDS_BIGENDIAN
185
if (table->s->db_low_byte_first)
190
return (int64_t) tmp;
195
#ifdef WORDS_BIGENDIAN
196
if (table->s->db_low_byte_first)
204
return 0; // impossible
208
Save the field metadata for enum fields.
210
Saves the real type in the first byte and the pack length in the
211
second byte of the field metadata array at index of *metadata_ptr and
214
@param metadata_ptr First byte of field metadata
216
@returns number of bytes written to metadata_ptr
218
int Field_enum::do_save_field_metadata(unsigned char *metadata_ptr)
220
*metadata_ptr= real_type();
221
*(metadata_ptr + 1)= pack_length();
225
String *Field_enum::val_str(String *, String *val_ptr)
145
227
uint32_t tmp=(uint32_t) Field_enum::val_int();
147
229
ASSERT_COLUMN_MARKED_FOR_READ;
149
if (not tmp || tmp > typelib->count)
231
if (!tmp || tmp > typelib->count)
151
232
val_ptr->set("", 0, field_charset);
155
val_ptr->set((const char*) typelib->type_names[tmp-1], typelib->type_lengths[tmp-1], field_charset);
234
val_ptr->set((const char*) typelib->type_names[tmp-1],
235
typelib->type_lengths[tmp-1],
163
242
unsigned char *old= ptr;
164
243
ptr= (unsigned char*) a_ptr;
165
uint64_t a= Field_enum::val_int();
244
uint64_t a=Field_enum::val_int();
166
245
ptr= (unsigned char*) b_ptr;
167
uint64_t b= Field_enum::val_int();
246
uint64_t b=Field_enum::val_int();
169
248
return (a < b) ? -1 : (a > b) ? 1 : 0;
172
251
void Field_enum::sort_string(unsigned char *to,uint32_t )
174
uint64_t value=Field_enum::val_int()-1; /* SQL is 1 based, stored as 0 based*/
175
to+=pack_length() -1;
176
for (uint32_t i=0 ; i < pack_length() ; i++)
253
uint64_t value=Field_enum::val_int();
255
for (uint32_t i=0 ; i < packlength ; i++)
178
257
*to-- = (unsigned char) (value & 255);
206
Field *Field_enum::new_field(memory::Root *root, Table *new_table,
285
Field *Field_enum::new_field(MEM_ROOT *root, Table *new_table,
209
288
Field_enum *res= (Field_enum*) Field::new_field(root, new_table, keep_type);
212
res->typelib= typelib->copy_typelib(root);
290
res->typelib= copy_typelib(root, typelib);
217
} /* namespace drizzled */