1
/* - mode: c++; c-basic-offset: 2; indent-tabs-mode: nil; -*-
2
* vim:expandtab:shiftwidth=2:tabstop=2:smarttab:
4
* Copyright (C) 2008 MySQL
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.
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.
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
22
#include <drizzled/server_includes.h>
23
#include <drizzled/field/enum.h>
25
/****************************************************************************
27
** This is a string which only can have a selection of different values.
28
** If one uses this string in a number context one gets the type number.
29
****************************************************************************/
31
enum ha_base_keytype Field_enum::key_type() const
34
default: return HA_KEYTYPE_BINARY;
37
case 4: return HA_KEYTYPE_ULONG_INT;
38
case 8: return HA_KEYTYPE_ULONGLONG;
42
void Field_enum::store_type(uint64_t value)
45
case 1: ptr[0]= (unsigned char) value; break;
47
#ifdef WORDS_BIGENDIAN
48
if (table->s->db_low_byte_first)
50
int2store(ptr,(unsigned short) value);
54
shortstore(ptr,(unsigned short) value);
56
case 3: int3store(ptr,(long) value); break;
58
#ifdef WORDS_BIGENDIAN
59
if (table->s->db_low_byte_first)
65
longstore(ptr,(long) value);
68
#ifdef WORDS_BIGENDIAN
69
if (table->s->db_low_byte_first)
75
int64_tstore(ptr,value); break;
82
Storing a empty string in a enum field gives a warning
83
(if there isn't a empty value in the enum)
86
int Field_enum::store(const char *from, uint32_t length, const CHARSET_INFO * const cs)
90
char buff[STRING_BUFFER_USUAL_SIZE];
91
String tmpstr(buff,sizeof(buff), &my_charset_bin);
93
/* Convert character set if necessary */
94
if (String::needs_conversion(length, cs, field_charset, ¬_used))
96
uint32_t dummy_errors;
97
tmpstr.copy(from, length, cs, field_charset, &dummy_errors);
99
length= tmpstr.length();
102
/* Remove end space */
103
length= field_charset->cset->lengthsp(field_charset, from, length);
104
uint32_t tmp=find_type2(typelib, from, length, field_charset);
107
if (length < 6) // Can't be more than 99999 enums
109
/* This is for reading numbers with LOAD DATA INFILE */
111
tmp=(uint) my_strntoul(cs,from,length,10,&end,&err);
112
if (err || end != from+length || tmp > typelib->count)
115
set_warning(DRIZZLE_ERROR::WARN_LEVEL_WARN, ER_WARN_DATA_TRUNCATED, 1);
117
if (!table->in_use->count_cuted_fields)
121
set_warning(DRIZZLE_ERROR::WARN_LEVEL_WARN, ER_WARN_DATA_TRUNCATED, 1);
123
store_type((uint64_t) tmp);
128
int Field_enum::store(double nr)
130
return Field_enum::store((int64_t) nr, false);
134
int Field_enum::store(int64_t nr,
135
bool unsigned_val __attribute__((unused)))
138
if ((uint64_t) nr > typelib->count || nr == 0)
140
set_warning(DRIZZLE_ERROR::WARN_LEVEL_WARN, ER_WARN_DATA_TRUNCATED, 1);
141
if (nr != 0 || table->in_use->count_cuted_fields)
147
store_type((uint64_t) (uint) nr);
152
double Field_enum::val_real(void)
154
return (double) Field_enum::val_int();
158
int64_t Field_enum::val_int(void)
160
switch (packlength) {
162
return (int64_t) ptr[0];
166
#ifdef WORDS_BIGENDIAN
167
if (table->s->db_low_byte_first)
172
return (int64_t) tmp;
175
return (int64_t) uint3korr(ptr);
179
#ifdef WORDS_BIGENDIAN
180
if (table->s->db_low_byte_first)
185
return (int64_t) tmp;
190
#ifdef WORDS_BIGENDIAN
191
if (table->s->db_low_byte_first)
199
return 0; // impossible
204
Save the field metadata for enum fields.
206
Saves the real type in the first byte and the pack length in the
207
second byte of the field metadata array at index of *metadata_ptr and
210
@param metadata_ptr First byte of field metadata
212
@returns number of bytes written to metadata_ptr
214
int Field_enum::do_save_field_metadata(unsigned char *metadata_ptr)
216
*metadata_ptr= real_type();
217
*(metadata_ptr + 1)= pack_length();
222
String *Field_enum::val_str(String *val_buffer __attribute__((unused)),
225
uint32_t tmp=(uint) Field_enum::val_int();
226
if (!tmp || tmp > typelib->count)
227
val_ptr->set("", 0, field_charset);
229
val_ptr->set((const char*) typelib->type_names[tmp-1],
230
typelib->type_lengths[tmp-1],
235
int Field_enum::cmp(const unsigned char *a_ptr, const unsigned char *b_ptr)
237
unsigned char *old= ptr;
238
ptr= (unsigned char*) a_ptr;
239
uint64_t a=Field_enum::val_int();
240
ptr= (unsigned char*) b_ptr;
241
uint64_t b=Field_enum::val_int();
243
return (a < b) ? -1 : (a > b) ? 1 : 0;
246
void Field_enum::sort_string(unsigned char *to,uint32_t length __attribute__((unused)))
248
uint64_t value=Field_enum::val_int();
250
for (uint32_t i=0 ; i < packlength ; i++)
252
*to-- = (unsigned char) (value & 255);
258
void Field_enum::sql_type(String &res) const
261
String enum_item(buffer, sizeof(buffer), res.charset());
264
res.append(STRING_WITH_LEN("enum("));
267
uint32_t *len= typelib->type_lengths;
268
for (const char **pos= typelib->type_names; *pos; pos++, len++)
270
uint32_t dummy_errors;
273
/* convert to res.charset() == utf8, then quote */
274
enum_item.copy(*pos, *len, charset(), res.charset(), &dummy_errors);
275
append_unescaped(&res, enum_item.ptr(), enum_item.length());
282
Field *Field_enum::new_field(MEM_ROOT *root, Table *new_table,
285
Field_enum *res= (Field_enum*) Field::new_field(root, new_table, keep_type);
287
res->typelib= copy_typelib(root, typelib);