~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to drizzled/field/enum.cc

  • Committer: Monty Taylor
  • Date: 2008-11-02 03:17:55 UTC
  • mto: (520.4.45 devel)
  • mto: This revision was merged to the branch mainline in revision 573.
  • Revision ID: monty@inaugust.com-20081102031755-cpzp7dlqoa7rcs1v
Removed a bunch of unusued tests and defines from autoconf.
Fixed the way we were doing cmath - and moved it out of global.h. Still probably
isn't right for Sun Studio, but we're getting closer I think.

Show diffs side-by-side

added added

removed removed

Lines of Context:
19
19
 */
20
20
 
21
21
 
22
 
#include "config.h"
23
 
#include "drizzled/field/enum.h"
24
 
#include "drizzled/error.h"
25
 
#include "drizzled/table.h"
26
 
#include "drizzled/session.h"
27
 
#include "drizzled/strfunc.h"
28
 
 
29
 
#include <sstream>
30
 
#include <string>
31
 
 
32
 
namespace drizzled
33
 
{
 
22
#include <drizzled/server_includes.h>
 
23
#include <drizzled/field/enum.h>
 
24
#include <drizzled/error.h>
34
25
 
35
26
/****************************************************************************
36
27
** enum type.
40
31
 
41
32
enum ha_base_keytype Field_enum::key_type() const
42
33
{
43
 
  switch (packlength) 
44
 
  {
45
 
    default: return HA_KEYTYPE_BINARY;
46
 
    case 2: assert(1);
47
 
    case 3: assert(1);
48
 
    case 4: return HA_KEYTYPE_ULONG_INT;
49
 
    case 8: return HA_KEYTYPE_ULONGLONG;
 
34
  switch (packlength) {
 
35
  default: return HA_KEYTYPE_BINARY;
 
36
  case 2: assert(1);
 
37
  case 3: assert(1);
 
38
  case 4: return HA_KEYTYPE_ULONG_INT;
 
39
  case 8: return HA_KEYTYPE_ULONGLONG;
50
40
  }
51
41
}
52
42
 
87
77
  }
88
78
}
89
79
 
 
80
 
90
81
/**
91
 
 * Given a supplied string, looks up the string in the internal typelib
92
 
 * and stores the found key.  Upon not finding an entry in the typelib, 
93
 
 * we always throw an error.
94
 
 */
95
 
int Field_enum::store(const char *from, uint32_t length, const CHARSET_INFO * const)
 
82
  @note
 
83
    Storing a empty string in a enum field gives a warning
 
84
    (if there isn't a empty value in the enum)
 
85
*/
 
86
 
 
87
int Field_enum::store(const char *from, uint32_t length, const CHARSET_INFO * const cs)
96
88
{
97
 
  uint32_t tmp;
 
89
  int err= 0;
 
90
  uint32_t not_used;
 
91
  char buff[STRING_BUFFER_USUAL_SIZE];
 
92
  String tmpstr(buff,sizeof(buff), &my_charset_bin);
98
93
 
99
 
  ASSERT_COLUMN_MARKED_FOR_WRITE;
 
94
  /* Convert character set if necessary */
 
95
  if (String::needs_conversion(length, cs, field_charset, &not_used))
 
96
  { 
 
97
    uint32_t dummy_errors;
 
98
    tmpstr.copy(from, length, cs, field_charset, &dummy_errors);
 
99
    from= tmpstr.ptr();
 
100
    length=  tmpstr.length();
 
101
  }
100
102
 
101
103
  /* Remove end space */
102
104
  length= field_charset->cset->lengthsp(field_charset, from, length);
103
 
  tmp= find_type2(typelib, from, length, field_charset);
104
 
  if (! tmp)
 
105
  uint32_t tmp=find_type2(typelib, from, length, field_charset);
 
106
  if (!tmp)
105
107
  {
106
 
    if (length < 6) /* Can't be more than 99999 enums */
 
108
    if (length < 6) // Can't be more than 99999 enums
107
109
    {
108
110
      /* This is for reading numbers with LOAD DATA INFILE */
109
 
      /* Convert the string to an integer using stringstream */
110
 
      std::stringstream ss;
111
 
      ss << from;
112
 
      ss >> tmp;
113
 
 
114
 
      if (tmp == 0 || tmp > typelib->count)
 
111
      char *end;
 
112
      tmp=(uint) my_strntoul(cs,from,length,10,&end,&err);
 
113
      if (err || end != from+length || tmp > typelib->count)
115
114
      {
116
 
        my_error(ER_INVALID_ENUM_VALUE, MYF(ME_FATALERROR), from);
117
 
        return 1;
 
115
        tmp=0;
 
116
        set_warning(DRIZZLE_ERROR::WARN_LEVEL_WARN, ER_WARN_DATA_TRUNCATED, 1);
118
117
      }
 
118
      if (!table->in_use->count_cuted_fields)
 
119
        err= 0;
119
120
    }
120
121
    else
121
 
    {
122
 
      my_error(ER_INVALID_ENUM_VALUE, MYF(ME_FATALERROR), from);
123
 
      return 1;
124
 
    }
 
122
      set_warning(DRIZZLE_ERROR::WARN_LEVEL_WARN, ER_WARN_DATA_TRUNCATED, 1);
125
123
  }
126
124
  store_type((uint64_t) tmp);
127
 
  return 0;
128
 
}
129
 
 
130
 
int Field_enum::store(double from)
131
 
{
132
 
  return Field_enum::store((int64_t) from, false);
133
 
}
134
 
 
135
 
/**
136
 
 * @note MySQL allows 0 values, saying that 0 is "the index of the
137
 
 * blank string error", whatever that means.  Uhm, Drizzle doesn't
138
 
 * allow this.  To store an ENUM column value using an integer, you
139
 
 * must specify the 1-based index of the enum column definition's 
140
 
 * key.
141
 
 */
142
 
int Field_enum::store(int64_t from, bool)
143
 
{
144
 
  ASSERT_COLUMN_MARKED_FOR_WRITE;
145
 
 
146
 
  if (from <= 0 || (uint64_t) from > typelib->count)
 
125
  return err;
 
126
}
 
127
 
 
128
 
 
129
int Field_enum::store(double nr)
 
130
{
 
131
  return Field_enum::store((int64_t) nr, false);
 
132
}
 
133
 
 
134
 
 
135
int Field_enum::store(int64_t nr,
 
136
                      bool unsigned_val __attribute__((unused)))
 
137
{
 
138
  int error= 0;
 
139
  if ((uint64_t) nr > typelib->count || nr == 0)
147
140
  {
148
 
    /* Convert the integer to a string using stringstream */
149
 
    std::stringstream ss;
150
 
    std::string tmp;
151
 
    ss << from; ss >> tmp;
152
 
 
153
 
    my_error(ER_INVALID_ENUM_VALUE, MYF(ME_FATALERROR), tmp.c_str());
154
 
    return 1;
 
141
    set_warning(DRIZZLE_ERROR::WARN_LEVEL_WARN, ER_WARN_DATA_TRUNCATED, 1);
 
142
    if (nr != 0 || table->in_use->count_cuted_fields)
 
143
    {
 
144
      nr= 0;
 
145
      error= 1;
 
146
    }
155
147
  }
156
 
  store_type((uint64_t) (uint32_t) from);
157
 
  return 0;
 
148
  store_type((uint64_t) (uint) nr);
 
149
  return error;
158
150
}
159
151
 
 
152
 
160
153
double Field_enum::val_real(void)
161
154
{
162
155
  return (double) Field_enum::val_int();
163
156
}
164
157
 
 
158
 
165
159
int64_t Field_enum::val_int(void)
166
160
{
167
 
  ASSERT_COLUMN_MARKED_FOR_READ;
168
 
 
169
161
  switch (packlength) {
170
162
  case 1:
171
163
    return (int64_t) ptr[0];
208
200
  return 0;                                     // impossible
209
201
}
210
202
 
211
 
String *Field_enum::val_str(String *, String *val_ptr)
212
 
{
213
 
  uint32_t tmp=(uint32_t) Field_enum::val_int();
214
 
 
215
 
  ASSERT_COLUMN_MARKED_FOR_READ;
216
 
 
 
203
 
 
204
/**
 
205
   Save the field metadata for enum fields.
 
206
 
 
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
 
209
   *(metadata_ptr + 1).
 
210
 
 
211
   @param   metadata_ptr   First byte of field metadata
 
212
 
 
213
   @returns number of bytes written to metadata_ptr
 
214
*/
 
215
int Field_enum::do_save_field_metadata(unsigned char *metadata_ptr)
 
216
{
 
217
  *metadata_ptr= real_type();
 
218
  *(metadata_ptr + 1)= pack_length();
 
219
  return 2;
 
220
}
 
221
 
 
222
 
 
223
String *Field_enum::val_str(String *val_buffer __attribute__((unused)),
 
224
                            String *val_ptr)
 
225
{
 
226
  uint32_t tmp=(uint) Field_enum::val_int();
217
227
  if (!tmp || tmp > typelib->count)
218
228
    val_ptr->set("", 0, field_charset);
219
229
  else
234
244
  return (a < b) ? -1 : (a > b) ? 1 : 0;
235
245
}
236
246
 
237
 
void Field_enum::sort_string(unsigned char *to,uint32_t )
 
247
void Field_enum::sort_string(unsigned char *to,uint32_t length __attribute__((unused)))
238
248
{
239
249
  uint64_t value=Field_enum::val_int();
240
250
  to+=packlength-1;
245
255
  }
246
256
}
247
257
 
 
258
 
248
259
void Field_enum::sql_type(String &res) const
249
260
{
250
261
  char buffer[255];
262
273
      res.append(',');
263
274
    /* convert to res.charset() == utf8, then quote */
264
275
    enum_item.copy(*pos, *len, charset(), res.charset(), &dummy_errors);
265
 
    append_unescaped(&res, enum_item.c_ptr(), enum_item.length());
 
276
    append_unescaped(&res, enum_item.ptr(), enum_item.length());
266
277
    flag= 1;
267
278
  }
268
279
  res.append(')');
269
280
}
270
281
 
271
 
Field *Field_enum::new_field(memory::Root *root, Table *new_table,
 
282
 
 
283
Field *Field_enum::new_field(MEM_ROOT *root, Table *new_table,
272
284
                             bool keep_type)
273
285
{
274
286
  Field_enum *res= (Field_enum*) Field::new_field(root, new_table, keep_type);
276
288
    res->typelib= copy_typelib(root, typelib);
277
289
  return res;
278
290
}
279
 
 
280
 
} /* namespace drizzled */