~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to drizzled/field/fstring.cc

  • Committer: Monty Taylor
  • Date: 2008-08-04 19:37:18 UTC
  • mto: (261.2.2 codestyle)
  • mto: This revision was merged to the branch mainline in revision 262.
  • Revision ID: monty@inaugust.com-20080804193718-f0rz13uli4429ozb
Changed gettext_noop() to N_()

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
/* - mode: c++ c-basic-offset: 2; indent-tabs-mode: nil; -*-
 
1
/* - mode: c; c-basic-offset: 2; indent-tabs-mode: nil; -*-
2
2
 *  vim:expandtab:shiftwidth=2:tabstop=2:smarttab:
3
3
 *
4
4
 *  Copyright (C) 2008 MySQL
18
18
 *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
19
19
 */
20
20
 
 
21
#ifdef USE_PRAGMA_IMPLEMENTATION
 
22
#pragma implementation                          // gcc: Class implementation
 
23
#endif
21
24
 
22
 
#include <drizzled/server_includes.h>
23
25
#include <drizzled/field/fstring.h>
24
 
#include <drizzled/error.h>
25
 
#include <drizzled/table.h>
26
 
#include <drizzled/session.h>
27
 
 
 
26
#include <drizzled/drizzled_error_messages.h>
28
27
 
29
28
#define LONGLONG_TO_STRING_CONVERSION_BUFFER_SIZE 128
30
29
#define DECIMAL_TO_STRING_CONVERSION_BUFFER_SIZE 128
35
34
****************************************************************************/
36
35
 
37
36
/* Copy a string and fill with space */
38
 
int Field_string::store(const char *from,uint32_t length, const CHARSET_INFO * const cs)
 
37
int Field_string::store(const char *from,uint length,CHARSET_INFO *cs)
39
38
{
40
 
  uint32_t copy_length;
 
39
  uint copy_length;
41
40
  const char *well_formed_error_pos;
42
41
  const char *cannot_convert_error_pos;
43
42
  const char *from_end_pos;
44
43
 
45
 
  /* See the comment for Field_long::store(int64_t) */
46
 
  assert(table->in_use == current_session);
 
44
  /* See the comment for Field_long::store(long long) */
 
45
  assert(table->in_use == current_thd);
47
46
 
48
47
  copy_length= well_formed_copy_nchars(field_charset,
49
48
                                       (char*) ptr, field_length,
71
70
{
72
71
  char buff[64];
73
72
  int  l;
74
 
  const CHARSET_INFO * const cs= charset();
 
73
  CHARSET_INFO *cs=charset();
75
74
  l= (cs->cset->int64_t10_to_str)(cs,buff,sizeof(buff),
76
75
                                   unsigned_val ? 10 : -10, nr);
77
76
  return Field_string::store(buff,(uint)l,cs);
82
81
{
83
82
  int error;
84
83
  char *end;
85
 
  const CHARSET_INFO * const cs= charset();
 
84
  CHARSET_INFO *cs= charset();
86
85
  double result;
87
86
  
88
87
  result=  my_strntod(cs,(char*) ptr,field_length,&end,&error);
94
93
    char buf[DOUBLE_TO_STRING_CONVERSION_BUFFER_SIZE];
95
94
    String tmp(buf, sizeof(buf), cs);
96
95
    tmp.copy((char*) ptr, field_length, cs);
97
 
    push_warning_printf(current_session, DRIZZLE_ERROR::WARN_LEVEL_WARN,
 
96
    push_warning_printf(current_thd, MYSQL_ERROR::WARN_LEVEL_WARN,
98
97
                        ER_TRUNCATED_WRONG_VALUE, 
99
98
                        ER(ER_TRUNCATED_WRONG_VALUE),
100
99
                        "DOUBLE", tmp.c_ptr());
107
106
{
108
107
  int error;
109
108
  char *end;
110
 
  const CHARSET_INFO * const cs= charset();
 
109
  CHARSET_INFO *cs= charset();
111
110
  int64_t result;
112
111
 
113
112
  result= my_strntoll(cs, (char*) ptr,field_length,10,&end,&error);
119
118
    char buf[LONGLONG_TO_STRING_CONVERSION_BUFFER_SIZE];
120
119
    String tmp(buf, sizeof(buf), cs);
121
120
    tmp.copy((char*) ptr, field_length, cs);
122
 
    push_warning_printf(current_session, DRIZZLE_ERROR::WARN_LEVEL_WARN,
 
121
    push_warning_printf(current_thd, MYSQL_ERROR::WARN_LEVEL_WARN,
123
122
                        ER_TRUNCATED_WRONG_VALUE, 
124
123
                        ER(ER_TRUNCATED_WRONG_VALUE),
125
124
                        "INTEGER", tmp.c_ptr());
131
130
String *Field_string::val_str(String *val_buffer __attribute__((unused)),
132
131
                              String *val_ptr)
133
132
{
134
 
  /* See the comment for Field_long::store(int64_t) */
135
 
  assert(table->in_use == current_session);
136
 
  uint32_t length;
137
 
 
138
 
  length= field_charset->cset->lengthsp(field_charset, (const char*) ptr, field_length);
 
133
  /* See the comment for Field_long::store(long long) */
 
134
  assert(table->in_use == current_thd);
 
135
  uint length;
 
136
  if (table->in_use->variables.sql_mode &
 
137
      MODE_PAD_CHAR_TO_FULL_LENGTH)
 
138
    length= my_charpos(field_charset, ptr, ptr + field_length, field_length);
 
139
  else
 
140
    length= field_charset->cset->lengthsp(field_charset, (const char*) ptr,
 
141
                                          field_length);
139
142
  val_ptr->set((const char*) ptr, length, field_charset);
140
 
 
141
143
  return val_ptr;
142
144
}
143
145
 
149
151
  if (!table->in_use->no_errors && err)
150
152
  {
151
153
    char buf[DECIMAL_TO_STRING_CONVERSION_BUFFER_SIZE];
152
 
    const CHARSET_INFO * const cs= charset();
 
154
    CHARSET_INFO *cs= charset();
153
155
    String tmp(buf, sizeof(buf), cs);
154
156
    tmp.copy((char*) ptr, field_length, cs);
155
 
    push_warning_printf(current_session, DRIZZLE_ERROR::WARN_LEVEL_WARN,
 
157
    push_warning_printf(current_thd, MYSQL_ERROR::WARN_LEVEL_WARN,
156
158
                        ER_TRUNCATED_WRONG_VALUE, 
157
159
                        ER(ER_TRUNCATED_WRONG_VALUE),
158
160
                        "DECIMAL", tmp.c_ptr());
162
164
}
163
165
 
164
166
 
165
 
int Field_string::cmp(const unsigned char *a_ptr, const unsigned char *b_ptr)
 
167
int Field_string::cmp(const uchar *a_ptr, const uchar *b_ptr)
166
168
{
167
 
  uint32_t a_len, b_len;
 
169
  uint a_len, b_len;
168
170
 
169
171
  if (field_charset->mbmaxlen != 1)
170
172
  {
171
 
    uint32_t char_len= field_length/field_charset->mbmaxlen;
 
173
    uint char_len= field_length/field_charset->mbmaxlen;
172
174
    a_len= my_charpos(field_charset, a_ptr, a_ptr + field_length, char_len);
173
175
    b_len= my_charpos(field_charset, b_ptr, b_ptr + field_length, char_len);
174
176
  }
185
187
}
186
188
 
187
189
 
188
 
void Field_string::sort_string(unsigned char *to,uint32_t length)
 
190
void Field_string::sort_string(uchar *to,uint length)
189
191
{
190
 
  uint32_t tmp= my_strnxfrm(field_charset,
 
192
  uint tmp= my_strnxfrm(field_charset,
191
193
                                 to, length,
192
194
                                 ptr, field_length);
193
195
  assert(tmp == length);
196
198
 
197
199
void Field_string::sql_type(String &res) const
198
200
{
199
 
  Session *session= table->in_use;
200
 
  const CHARSET_INFO * const cs= res.charset();
201
 
  uint32_t length;
 
201
  THD *thd= table->in_use;
 
202
  CHARSET_INFO *cs=res.charset();
 
203
  ulong length;
202
204
 
203
205
  length= cs->cset->snprintf(cs,(char*) res.ptr(),
204
206
                             res.alloced_length(), "%s(%d)",
205
207
                             ((type() == DRIZZLE_TYPE_VARCHAR &&
206
 
                               !session->variables.new_mode) ?
 
208
                               !thd->variables.new_mode) ?
207
209
                              (has_charset() ? "varchar" : "varbinary") :
208
210
                              (has_charset() ? "char" : "binary")),
209
211
                             (int) field_length / charset()->mbmaxlen);
211
213
}
212
214
 
213
215
 
214
 
unsigned char *Field_string::pack(unsigned char *to, const unsigned char *from,
215
 
                          uint32_t max_length,
 
216
uchar *Field_string::pack(uchar *to, const uchar *from,
 
217
                          uint max_length,
216
218
                          bool low_byte_first __attribute__((unused)))
217
219
{
218
 
  uint32_t length=      cmin(field_length,max_length);
219
 
  uint32_t local_char_length= max_length/field_charset->mbmaxlen;
 
220
  uint length=      min(field_length,max_length);
 
221
  uint local_char_length= max_length/field_charset->mbmaxlen;
220
222
  if (length > local_char_length)
221
223
    local_char_length= my_charpos(field_charset, from, from+length,
222
224
                                  local_char_length);
225
227
    length--;
226
228
 
227
229
  // Length always stored little-endian
228
 
  *to++= (unsigned char) length;
 
230
  *to++= (uchar) length;
229
231
  if (field_length > 255)
230
 
    *to++= (unsigned char) (length >> 8);
 
232
    *to++= (uchar) (length >> 8);
231
233
 
232
234
  // Store the actual bytes of the string
233
235
  memcpy(to, from, length);
251
253
 
252
254
   @return  New pointer into memory based on from + length of the data
253
255
*/
254
 
const unsigned char *
255
 
Field_string::unpack(unsigned char *to,
256
 
                     const unsigned char *from,
257
 
                     uint32_t param_data,
 
256
const uchar *
 
257
Field_string::unpack(uchar *to,
 
258
                     const uchar *from,
 
259
                     uint param_data,
258
260
                     bool low_byte_first __attribute__((unused)))
259
261
{
260
 
  uint32_t from_length=
261
 
    param_data ? cmin(param_data & 0x00ff, field_length) : field_length;
262
 
  uint32_t length;
 
262
  uint from_length=
 
263
    param_data ? min(param_data & 0x00ff, field_length) : field_length;
 
264
  uint length;
263
265
 
264
266
  if (from_length > 255)
265
267
  {
287
289
 
288
290
   @returns number of bytes written to metadata_ptr
289
291
*/
290
 
int Field_string::do_save_field_metadata(unsigned char *metadata_ptr)
 
292
int Field_string::do_save_field_metadata(uchar *metadata_ptr)
291
293
{
292
294
  *metadata_ptr= real_type();
293
295
  *(metadata_ptr + 1)= field_length;
311
313
    > 0   a > b
312
314
*/
313
315
 
314
 
int Field_string::pack_cmp(const unsigned char *a, const unsigned char *b, uint32_t length,
315
 
                           bool insert_or_update)
 
316
int Field_string::pack_cmp(const uchar *a, const uchar *b, uint length,
 
317
                           my_bool insert_or_update)
316
318
{
317
 
  uint32_t a_length, b_length;
 
319
  uint a_length, b_length;
318
320
  if (length > 255)
319
321
  {
320
322
    a_length= uint2korr(a);
349
351
    > 0   row > key
350
352
*/
351
353
 
352
 
int Field_string::pack_cmp(const unsigned char *key, uint32_t length,
353
 
                           bool insert_or_update)
 
354
int Field_string::pack_cmp(const uchar *key, uint length,
 
355
                           my_bool insert_or_update)
354
356
{
355
 
  uint32_t row_length, local_key_length;
356
 
  unsigned char *end;
 
357
  uint row_length, local_key_length;
 
358
  uchar *end;
357
359
  if (length > 255)
358
360
  {
359
361
    local_key_length= uint2korr(key);
375
377
}
376
378
 
377
379
 
378
 
uint32_t Field_string::packed_col_length(const unsigned char *data_ptr, uint32_t length)
 
380
uint Field_string::packed_col_length(const uchar *data_ptr, uint length)
379
381
{
380
382
  if (length > 255)
381
383
    return uint2korr(data_ptr)+2;
383
385
}
384
386
 
385
387
 
386
 
uint32_t Field_string::max_packed_col_length(uint32_t max_length)
 
388
uint Field_string::max_packed_col_length(uint max_length)
387
389
{
388
390
  return (max_length > 255 ? 2 : 1)+max_length;
389
391
}
390
392
 
391
393
 
392
 
uint32_t Field_string::get_key_image(unsigned char *buff,
393
 
                                 uint32_t length,
 
394
uint Field_string::get_key_image(uchar *buff,
 
395
                                 uint length,
394
396
                                 imagetype type_arg __attribute__((unused)))
395
397
{
396
 
  uint32_t bytes = my_charpos(field_charset, (char*) ptr,
 
398
  uint bytes = my_charpos(field_charset, (char*) ptr,
397
399
                          (char*) ptr + field_length,
398
400
                          length / field_charset->mbmaxlen);
399
401
  memcpy(buff, ptr, bytes);
404
406
}
405
407
 
406
408
 
407
 
Field *Field_string::new_field(MEM_ROOT *root, Table *new_table, bool keep_type)
 
409
Field *Field_string::new_field(MEM_ROOT *root, struct st_table *new_table,
 
410
                               bool keep_type)
408
411
{
409
412
  Field *field;
410
413
  field= Field::new_field(root, new_table, keep_type);