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>
25
#include <drizzled/table.h>
26
#include <drizzled/session.h>
28
/****************************************************************************
30
** This is a string which only can have a selection of different values.
31
** If one uses this string in a number context one gets the type number.
32
****************************************************************************/
34
enum ha_base_keytype Field_enum::key_type() const
37
default: return HA_KEYTYPE_BINARY;
40
case 4: return HA_KEYTYPE_ULONG_INT;
41
case 8: return HA_KEYTYPE_ULONGLONG;
45
void Field_enum::store_type(uint64_t value)
48
case 1: ptr[0]= (unsigned char) value; break;
50
#ifdef WORDS_BIGENDIAN
51
if (table->s->db_low_byte_first)
53
int2store(ptr,(unsigned short) value);
57
shortstore(ptr,(unsigned short) value);
59
case 3: int3store(ptr,(long) value); break;
61
#ifdef WORDS_BIGENDIAN
62
if (table->s->db_low_byte_first)
68
longstore(ptr,(long) value);
71
#ifdef WORDS_BIGENDIAN
72
if (table->s->db_low_byte_first)
78
int64_tstore(ptr,value); break;
85
Storing a empty string in a enum field gives a warning
86
(if there isn't a empty value in the enum)
89
int Field_enum::store(const char *from, uint32_t length, const CHARSET_INFO * const cs)
93
char buff[STRING_BUFFER_USUAL_SIZE];
94
String tmpstr(buff,sizeof(buff), &my_charset_bin);
96
/* Convert character set if necessary */
97
if (String::needs_conversion(length, cs, field_charset, ¬_used))
99
uint32_t dummy_errors;
100
tmpstr.copy(from, length, cs, field_charset, &dummy_errors);
102
length= tmpstr.length();
105
/* Remove end space */
106
length= field_charset->cset->lengthsp(field_charset, from, length);
107
uint32_t tmp=find_type2(typelib, from, length, field_charset);
110
if (length < 6) // Can't be more than 99999 enums
112
/* This is for reading numbers with LOAD DATA INFILE */
114
tmp=(uint) my_strntoul(cs,from,length,10,&end,&err);
115
if (err || end != from+length || tmp > typelib->count)
118
set_warning(DRIZZLE_ERROR::WARN_LEVEL_WARN, ER_WARN_DATA_TRUNCATED, 1);
120
if (!table->in_use->count_cuted_fields)
124
set_warning(DRIZZLE_ERROR::WARN_LEVEL_WARN, ER_WARN_DATA_TRUNCATED, 1);
126
store_type((uint64_t) tmp);
131
int Field_enum::store(double nr)
133
return Field_enum::store((int64_t) nr, false);
137
int Field_enum::store(int64_t nr,
138
bool unsigned_val __attribute__((unused)))
141
if ((uint64_t) nr > typelib->count || nr == 0)
143
set_warning(DRIZZLE_ERROR::WARN_LEVEL_WARN, ER_WARN_DATA_TRUNCATED, 1);
144
if (nr != 0 || table->in_use->count_cuted_fields)
150
store_type((uint64_t) (uint) nr);
155
double Field_enum::val_real(void)
157
return (double) Field_enum::val_int();
161
int64_t Field_enum::val_int(void)
163
switch (packlength) {
165
return (int64_t) ptr[0];
169
#ifdef WORDS_BIGENDIAN
170
if (table->s->db_low_byte_first)
175
return (int64_t) tmp;
178
return (int64_t) uint3korr(ptr);
182
#ifdef WORDS_BIGENDIAN
183
if (table->s->db_low_byte_first)
188
return (int64_t) tmp;
193
#ifdef WORDS_BIGENDIAN
194
if (table->s->db_low_byte_first)
202
return 0; // impossible
207
Save the field metadata for enum fields.
209
Saves the real type in the first byte and the pack length in the
210
second byte of the field metadata array at index of *metadata_ptr and
213
@param metadata_ptr First byte of field metadata
215
@returns number of bytes written to metadata_ptr
217
int Field_enum::do_save_field_metadata(unsigned char *metadata_ptr)
219
*metadata_ptr= real_type();
220
*(metadata_ptr + 1)= pack_length();
225
String *Field_enum::val_str(String *val_buffer __attribute__((unused)),
228
uint32_t tmp=(uint) Field_enum::val_int();
229
if (!tmp || tmp > typelib->count)
230
val_ptr->set("", 0, field_charset);
232
val_ptr->set((const char*) typelib->type_names[tmp-1],
233
typelib->type_lengths[tmp-1],
238
int Field_enum::cmp(const unsigned char *a_ptr, const unsigned char *b_ptr)
240
unsigned char *old= ptr;
241
ptr= (unsigned char*) a_ptr;
242
uint64_t a=Field_enum::val_int();
243
ptr= (unsigned char*) b_ptr;
244
uint64_t b=Field_enum::val_int();
246
return (a < b) ? -1 : (a > b) ? 1 : 0;
249
void Field_enum::sort_string(unsigned char *to,uint32_t length __attribute__((unused)))
251
uint64_t value=Field_enum::val_int();
253
for (uint32_t i=0 ; i < packlength ; i++)
255
*to-- = (unsigned char) (value & 255);
261
void Field_enum::sql_type(String &res) const
264
String enum_item(buffer, sizeof(buffer), res.charset());
267
res.append(STRING_WITH_LEN("enum("));
270
uint32_t *len= typelib->type_lengths;
271
for (const char **pos= typelib->type_names; *pos; pos++, len++)
273
uint32_t dummy_errors;
276
/* convert to res.charset() == utf8, then quote */
277
enum_item.copy(*pos, *len, charset(), res.charset(), &dummy_errors);
278
append_unescaped(&res, enum_item.ptr(), enum_item.length());
285
Field *Field_enum::new_field(MEM_ROOT *root, Table *new_table,
288
Field_enum *res= (Field_enum*) Field::new_field(root, new_table, keep_type);
290
res->typelib= copy_typelib(root, typelib);