18
18
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
22
#include <boost/lexical_cast.hpp>
22
#include "drizzled/server_includes.h"
23
23
#include "drizzled/field/enum.h"
24
24
#include "drizzled/error.h"
25
25
#include "drizzled/table.h"
26
26
#include "drizzled/session.h"
27
#include "drizzled/strfunc.h"
35
31
/****************************************************************************
37
33
** This is a string which only can have a selection of different values.
38
34
** If one uses this string in a number context one gets the type number.
39
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;
41
49
void Field_enum::store_type(uint64_t value)
43
value--; /* we store as starting from 0, although SQL starts from 1 */
45
#ifdef WORDS_BIGENDIAN
46
if (getTable()->getShare()->db_low_byte_first)
48
int4store(ptr, (unsigned short) value);
52
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;
56
87
* Given a supplied string, looks up the string in the internal typelib
57
* 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,
58
89
* we always throw an error.
60
91
int Field_enum::store(const char *from, uint32_t length, const CHARSET_INFO * const)
101
132
* @note MySQL allows 0 values, saying that 0 is "the index of the
102
133
* blank string error", whatever that means. Uhm, Drizzle doesn't
103
134
* allow this. To store an ENUM column value using an integer, you
104
* 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
107
138
int Field_enum::store(int64_t from, bool)
111
142
if (from <= 0 || (uint64_t) from > typelib->count)
113
/* Convert the integer to a string using boost::lexical_cast */
114
std::string tmp(boost::lexical_cast<std::string>(from));
144
/* Convert the integer to a string using stringstream */
145
std::stringstream ss;
147
ss << from; ss >> tmp;
116
149
my_error(ER_INVALID_ENUM_VALUE, MYF(ME_FATALERROR), tmp.c_str());
130
163
ASSERT_COLUMN_MARKED_FOR_READ;
133
#ifdef WORDS_BIGENDIAN
134
if (getTable()->getShare()->db_low_byte_first)
139
return ((int64_t) tmp) + 1; /* SQL is from 1, we store from 0 */
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
142
207
String *Field_enum::val_str(String *, String *val_ptr)
146
211
ASSERT_COLUMN_MARKED_FOR_READ;
148
if (not tmp || tmp > typelib->count)
213
if (!tmp || tmp > typelib->count)
150
214
val_ptr->set("", 0, field_charset);
154
val_ptr->set((const char*) typelib->type_names[tmp-1], typelib->type_lengths[tmp-1], field_charset);
216
val_ptr->set((const char*) typelib->type_names[tmp-1],
217
typelib->type_lengths[tmp-1],
162
224
unsigned char *old= ptr;
163
225
ptr= (unsigned char*) a_ptr;
164
uint64_t a= Field_enum::val_int();
226
uint64_t a=Field_enum::val_int();
165
227
ptr= (unsigned char*) b_ptr;
166
uint64_t b= Field_enum::val_int();
228
uint64_t b=Field_enum::val_int();
168
230
return (a < b) ? -1 : (a > b) ? 1 : 0;
171
233
void Field_enum::sort_string(unsigned char *to,uint32_t )
173
uint64_t value=Field_enum::val_int()-1; /* SQL is 1 based, stored as 0 based*/
174
to+=pack_length() -1;
175
for (uint32_t i=0 ; i < pack_length() ; i++)
235
uint64_t value=Field_enum::val_int();
237
for (uint32_t i=0 ; i < packlength ; i++)
177
239
*to-- = (unsigned char) (value & 255);
205
Field *Field_enum::new_field(memory::Root *root, Table *new_table,
267
Field *Field_enum::new_field(MEM_ROOT *root, Table *new_table,
208
270
Field_enum *res= (Field_enum*) Field::new_field(root, new_table, keep_type);
211
272
res->typelib= copy_typelib(root, typelib);
216
} /* namespace drizzled */