~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to drizzled/field/enum.cc

  • Committer: Mats Kindahl
  • Date: 2008-08-26 07:32:59 UTC
  • mto: (489.1.2 codestyle)
  • mto: This revision was merged to the branch mainline in revision 491.
  • Revision ID: mats@mysql.com-20080826073259-9k4evtajgldgolli
Replaced use of thd_proc_info() macro with calls to
set_proc_info() and get_proc_info() internally.  Introduced
functions set_thd_proc_info() and get_thd_proc_info() for
external users, i.e., plug-ins.

The set_thd_proc_info() accepted callers info that can be used to
print debug output, but the information was not used. The return
value was changed to void and the old value is not fetched any
more. To be able to get the value of proc_info for external
users, the function get_thd_proc_info() was introduced.

The thd_proc_info() macro called set_thd_proc_info() but almost
never used the return value of set_thd_proc_info() so the macro
was replaced with a call of THD::set_proc_info().

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
/* - mode: c++; c-basic-offset: 2; indent-tabs-mode: nil; -*-
2
 
 *  vim:expandtab:shiftwidth=2:tabstop=2:smarttab:
3
 
 *
4
 
 *  Copyright (C) 2008 MySQL
5
 
 *
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.
10
 
 *
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.
15
 
 *
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
19
 
 */
20
 
 
21
 
#include "config.h"
22
 
#include <boost/lexical_cast.hpp>
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
 
{
34
 
 
35
 
/****************************************************************************
36
 
** enum type.
37
 
** This is a string which only can have a selection of different values.
38
 
** If one uses this string in a number context one gets the type number.
39
 
****************************************************************************/
40
 
 
41
 
void Field_enum::store_type(uint64_t value)
42
 
{
43
 
  value--; /* we store as starting from 0, although SQL starts from 1 */
44
 
 
45
 
#ifdef WORDS_BIGENDIAN
46
 
  if (getTable()->getShare()->db_low_byte_first)
47
 
  {
48
 
    int4store(ptr, (unsigned short) value);
49
 
  }
50
 
  else
51
 
#endif
52
 
    longstore(ptr, (unsigned short) value);
53
 
}
54
 
 
55
 
/**
56
 
 * 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,
58
 
 * we always throw an error.
59
 
 */
60
 
int Field_enum::store(const char *from, uint32_t length, const CHARSET_INFO * const)
61
 
{
62
 
  uint32_t tmp;
63
 
 
64
 
  ASSERT_COLUMN_MARKED_FOR_WRITE;
65
 
 
66
 
  /* Remove end space */
67
 
  length= field_charset->cset->lengthsp(field_charset, from, length);
68
 
  tmp= find_type2(typelib, from, length, field_charset);
69
 
  if (! tmp)
70
 
  {
71
 
    if (length < 6) /* Can't be more than 99999 enums */
72
 
    {
73
 
      /* This is for reading numbers with LOAD DATA INFILE */
74
 
      /* Convert the string to an integer using stringstream */
75
 
      std::stringstream ss;
76
 
      ss << from;
77
 
      ss >> tmp;
78
 
 
79
 
      if (tmp == 0 || tmp > typelib->count)
80
 
      {
81
 
        my_error(ER_INVALID_ENUM_VALUE, MYF(ME_FATALERROR), from);
82
 
        return 1;
83
 
      }
84
 
    }
85
 
    else
86
 
    {
87
 
      my_error(ER_INVALID_ENUM_VALUE, MYF(ME_FATALERROR), from);
88
 
      return 1;
89
 
    }
90
 
  }
91
 
  store_type((uint64_t) tmp);
92
 
  return 0;
93
 
}
94
 
 
95
 
int Field_enum::store(double from)
96
 
{
97
 
  return Field_enum::store((int64_t) from, false);
98
 
}
99
 
 
100
 
/**
101
 
 * @note MySQL allows 0 values, saying that 0 is "the index of the
102
 
 * blank string error", whatever that means.  Uhm, Drizzle doesn't
103
 
 * 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
105
 
 * key.
106
 
 */
107
 
int Field_enum::store(int64_t from, bool)
108
 
{
109
 
  ASSERT_COLUMN_MARKED_FOR_WRITE;
110
 
 
111
 
  if (from <= 0 || (uint64_t) from > typelib->count)
112
 
  {
113
 
    /* Convert the integer to a string using boost::lexical_cast */
114
 
    std::string tmp(boost::lexical_cast<std::string>(from));
115
 
 
116
 
    my_error(ER_INVALID_ENUM_VALUE, MYF(ME_FATALERROR), tmp.c_str());
117
 
    return 1;
118
 
  }
119
 
  store_type((uint64_t) (uint32_t) from);
120
 
  return 0;
121
 
}
122
 
 
123
 
double Field_enum::val_real(void)
124
 
{
125
 
  return (double) Field_enum::val_int();
126
 
}
127
 
 
128
 
int64_t Field_enum::val_int(void)
129
 
{
130
 
  ASSERT_COLUMN_MARKED_FOR_READ;
131
 
 
132
 
  uint16_t tmp;
133
 
#ifdef WORDS_BIGENDIAN
134
 
  if (getTable()->getShare()->db_low_byte_first)
135
 
    tmp= sint4korr(ptr);
136
 
  else
137
 
#endif
138
 
    longget(tmp,ptr);
139
 
  return ((int64_t) tmp) + 1; /* SQL is from 1, we store from 0 */
140
 
}
141
 
 
142
 
String *Field_enum::val_str(String *, String *val_ptr)
143
 
{
144
 
  uint32_t tmp=(uint32_t) Field_enum::val_int();
145
 
 
146
 
  ASSERT_COLUMN_MARKED_FOR_READ;
147
 
 
148
 
  if (not tmp || tmp > typelib->count)
149
 
  {
150
 
    val_ptr->set("", 0, field_charset);
151
 
  }
152
 
  else
153
 
  {
154
 
    val_ptr->set((const char*) typelib->type_names[tmp-1], typelib->type_lengths[tmp-1], field_charset);
155
 
  }
156
 
 
157
 
  return val_ptr;
158
 
}
159
 
 
160
 
int Field_enum::cmp(const unsigned char *a_ptr, const unsigned char *b_ptr)
161
 
{
162
 
  unsigned char *old= ptr;
163
 
  ptr= (unsigned char*) a_ptr;
164
 
  uint64_t a= Field_enum::val_int();
165
 
  ptr= (unsigned char*) b_ptr;
166
 
  uint64_t b= Field_enum::val_int();
167
 
  ptr= old;
168
 
  return (a < b) ? -1 : (a > b) ? 1 : 0;
169
 
}
170
 
 
171
 
void Field_enum::sort_string(unsigned char *to,uint32_t )
172
 
{
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++)
176
 
  {
177
 
    *to-- = (unsigned char) (value & 255);
178
 
    value>>=8;
179
 
  }
180
 
}
181
 
 
182
 
void Field_enum::sql_type(String &res) const
183
 
{
184
 
  char buffer[255];
185
 
  String enum_item(buffer, sizeof(buffer), res.charset());
186
 
 
187
 
  res.length(0);
188
 
  res.append(STRING_WITH_LEN("enum("));
189
 
 
190
 
  bool flag=0;
191
 
  uint32_t *len= typelib->type_lengths;
192
 
  for (const char **pos= typelib->type_names; *pos; pos++, len++)
193
 
  {
194
 
    size_t dummy_errors;
195
 
    if (flag)
196
 
      res.append(',');
197
 
    /* convert to res.charset() == utf8, then quote */
198
 
    enum_item.copy(*pos, *len, charset(), res.charset(), &dummy_errors);
199
 
    append_unescaped(&res, enum_item.c_ptr(), enum_item.length());
200
 
    flag= 1;
201
 
  }
202
 
  res.append(')');
203
 
}
204
 
 
205
 
Field *Field_enum::new_field(memory::Root *root, Table *new_table,
206
 
                             bool keep_type)
207
 
{
208
 
  Field_enum *res= (Field_enum*) Field::new_field(root, new_table, keep_type);
209
 
  if (res)
210
 
  {
211
 
    res->typelib= copy_typelib(root, typelib);
212
 
  }
213
 
  return res;
214
 
}
215
 
 
216
 
} /* namespace drizzled */