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>
24
#include <drizzled/error.h>
26
/****************************************************************************
28
** This is a string which only can have a selection of different values.
29
** If one uses this string in a number context one gets the type number.
30
****************************************************************************/
32
enum ha_base_keytype Field_enum::key_type() const
35
default: return HA_KEYTYPE_BINARY;
38
case 4: return HA_KEYTYPE_ULONG_INT;
39
case 8: return HA_KEYTYPE_ULONGLONG;
43
void Field_enum::store_type(uint64_t value)
46
case 1: ptr[0]= (unsigned char) value; break;
48
#ifdef WORDS_BIGENDIAN
49
if (table->s->db_low_byte_first)
51
int2store(ptr,(unsigned short) value);
55
shortstore(ptr,(unsigned short) value);
57
case 3: int3store(ptr,(long) value); break;
59
#ifdef WORDS_BIGENDIAN
60
if (table->s->db_low_byte_first)
66
longstore(ptr,(long) value);
69
#ifdef WORDS_BIGENDIAN
70
if (table->s->db_low_byte_first)
76
int64_tstore(ptr,value); break;
83
Storing a empty string in a enum field gives a warning
84
(if there isn't a empty value in the enum)
87
int Field_enum::store(const char *from, uint32_t length, const CHARSET_INFO * const cs)
91
char buff[STRING_BUFFER_USUAL_SIZE];
92
String tmpstr(buff,sizeof(buff), &my_charset_bin);
94
/* Convert character set if necessary */
95
if (String::needs_conversion(length, cs, field_charset, ¬_used))
97
uint32_t dummy_errors;
98
tmpstr.copy(from, length, cs, field_charset, &dummy_errors);
100
length= tmpstr.length();
103
/* Remove end space */
104
length= field_charset->cset->lengthsp(field_charset, from, length);
105
uint32_t tmp=find_type2(typelib, from, length, field_charset);
108
if (length < 6) // Can't be more than 99999 enums
110
/* This is for reading numbers with LOAD DATA INFILE */
112
tmp=(uint) my_strntoul(cs,from,length,10,&end,&err);
113
if (err || end != from+length || tmp > typelib->count)
116
set_warning(DRIZZLE_ERROR::WARN_LEVEL_WARN, ER_WARN_DATA_TRUNCATED, 1);
118
if (!table->in_use->count_cuted_fields)
122
set_warning(DRIZZLE_ERROR::WARN_LEVEL_WARN, ER_WARN_DATA_TRUNCATED, 1);
124
store_type((uint64_t) tmp);
129
int Field_enum::store(double nr)
131
return Field_enum::store((int64_t) nr, false);
135
int Field_enum::store(int64_t nr,
136
bool unsigned_val __attribute__((unused)))
139
if ((uint64_t) nr > typelib->count || nr == 0)
141
set_warning(DRIZZLE_ERROR::WARN_LEVEL_WARN, ER_WARN_DATA_TRUNCATED, 1);
142
if (nr != 0 || table->in_use->count_cuted_fields)
148
store_type((uint64_t) (uint) nr);
153
double Field_enum::val_real(void)
155
return (double) Field_enum::val_int();
159
int64_t Field_enum::val_int(void)
161
switch (packlength) {
163
return (int64_t) ptr[0];
167
#ifdef WORDS_BIGENDIAN
168
if (table->s->db_low_byte_first)
173
return (int64_t) tmp;
176
return (int64_t) uint3korr(ptr);
180
#ifdef WORDS_BIGENDIAN
181
if (table->s->db_low_byte_first)
186
return (int64_t) tmp;
191
#ifdef WORDS_BIGENDIAN
192
if (table->s->db_low_byte_first)
200
return 0; // impossible
205
Save the field metadata for enum fields.
207
Saves the real type in the first byte and the pack length in the
208
second byte of the field metadata array at index of *metadata_ptr and
211
@param metadata_ptr First byte of field metadata
213
@returns number of bytes written to metadata_ptr
215
int Field_enum::do_save_field_metadata(unsigned char *metadata_ptr)
217
*metadata_ptr= real_type();
218
*(metadata_ptr + 1)= pack_length();
223
String *Field_enum::val_str(String *val_buffer __attribute__((unused)),
226
uint32_t tmp=(uint) Field_enum::val_int();
227
if (!tmp || tmp > typelib->count)
228
val_ptr->set("", 0, field_charset);
230
val_ptr->set((const char*) typelib->type_names[tmp-1],
231
typelib->type_lengths[tmp-1],
236
int Field_enum::cmp(const unsigned char *a_ptr, const unsigned char *b_ptr)
238
unsigned char *old= ptr;
239
ptr= (unsigned char*) a_ptr;
240
uint64_t a=Field_enum::val_int();
241
ptr= (unsigned char*) b_ptr;
242
uint64_t b=Field_enum::val_int();
244
return (a < b) ? -1 : (a > b) ? 1 : 0;
247
void Field_enum::sort_string(unsigned char *to,uint32_t length __attribute__((unused)))
249
uint64_t value=Field_enum::val_int();
251
for (uint32_t i=0 ; i < packlength ; i++)
253
*to-- = (unsigned char) (value & 255);
259
void Field_enum::sql_type(String &res) const
262
String enum_item(buffer, sizeof(buffer), res.charset());
265
res.append(STRING_WITH_LEN("enum("));
268
uint32_t *len= typelib->type_lengths;
269
for (const char **pos= typelib->type_names; *pos; pos++, len++)
271
uint32_t dummy_errors;
274
/* convert to res.charset() == utf8, then quote */
275
enum_item.copy(*pos, *len, charset(), res.charset(), &dummy_errors);
276
append_unescaped(&res, enum_item.ptr(), enum_item.length());
283
Field *Field_enum::new_field(MEM_ROOT *root, Table *new_table,
286
Field_enum *res= (Field_enum*) Field::new_field(root, new_table, keep_type);
288
res->typelib= copy_typelib(root, typelib);