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)
64
ASSERT_COLUMN_MARKED_FOR_WRITE;
66
95
/* Remove end space */
67
96
length= field_charset->cset->lengthsp(field_charset, from, length);
68
97
tmp= find_type2(typelib, from, length, field_charset);
101
130
* @note MySQL allows 0 values, saying that 0 is "the index of the
102
131
* blank string error", whatever that means. Uhm, Drizzle doesn't
103
132
* 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
133
* must specify the 1-based index of the enum column definition's
107
136
int Field_enum::store(int64_t from, bool)
109
ASSERT_COLUMN_MARKED_FOR_WRITE;
111
138
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));
140
/* Convert the integer to a string using stringstream */
141
std::stringstream ss;
143
ss << from; ss >> tmp;
116
145
my_error(ER_INVALID_ENUM_VALUE, MYF(ME_FATALERROR), tmp.c_str());
128
157
int64_t Field_enum::val_int(void)
130
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 */
159
switch (packlength) {
161
return (int64_t) ptr[0];
165
#ifdef WORDS_BIGENDIAN
166
if (table->s->db_low_byte_first)
171
return (int64_t) tmp;
174
return (int64_t) uint3korr(ptr);
178
#ifdef WORDS_BIGENDIAN
179
if (table->s->db_low_byte_first)
184
return (int64_t) tmp;
189
#ifdef WORDS_BIGENDIAN
190
if (table->s->db_low_byte_first)
198
return 0; // impossible
202
Save the field metadata for enum fields.
204
Saves the real type in the first byte and the pack length in the
205
second byte of the field metadata array at index of *metadata_ptr and
208
@param metadata_ptr First byte of field metadata
210
@returns number of bytes written to metadata_ptr
212
int Field_enum::do_save_field_metadata(unsigned char *metadata_ptr)
214
*metadata_ptr= real_type();
215
*(metadata_ptr + 1)= pack_length();
142
219
String *Field_enum::val_str(String *, String *val_ptr)
144
221
uint32_t tmp=(uint32_t) Field_enum::val_int();
146
ASSERT_COLUMN_MARKED_FOR_READ;
148
if (not tmp || tmp > typelib->count)
222
if (!tmp || tmp > typelib->count)
150
223
val_ptr->set("", 0, field_charset);
154
val_ptr->set((const char*) typelib->type_names[tmp-1], typelib->type_lengths[tmp-1], field_charset);
225
val_ptr->set((const char*) typelib->type_names[tmp-1],
226
typelib->type_lengths[tmp-1],
162
233
unsigned char *old= ptr;
163
234
ptr= (unsigned char*) a_ptr;
164
uint64_t a= Field_enum::val_int();
235
uint64_t a=Field_enum::val_int();
165
236
ptr= (unsigned char*) b_ptr;
166
uint64_t b= Field_enum::val_int();
237
uint64_t b=Field_enum::val_int();
168
239
return (a < b) ? -1 : (a > b) ? 1 : 0;
171
242
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++)
244
uint64_t value=Field_enum::val_int();
246
for (uint32_t i=0 ; i < packlength ; i++)
177
248
*to-- = (unsigned char) (value & 255);
205
Field *Field_enum::new_field(memory::Root *root, Table *new_table,
276
Field *Field_enum::new_field(MEM_ROOT *root, Table *new_table,
208
279
Field_enum *res= (Field_enum*) Field::new_field(root, new_table, keep_type);
211
281
res->typelib= copy_typelib(root, typelib);
216
} /* namespace drizzled */