~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to drizzled/field/varstring.cc

  • Committer: Brian Aker
  • Date: 2009-01-21 05:53:36 UTC
  • mto: This revision was merged to the branch mainline in revision 801.
  • Revision ID: brian@tangent.org-20090121055336-fxoz6wfzreo8gi9x
Removed purge

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
24
21
 
25
22
#include <drizzled/server_includes.h>
26
23
#include <drizzled/field/varstring.h>
 
24
#include <drizzled/table.h>
 
25
#include <drizzled/session.h>
 
26
 
 
27
#include <string>
 
28
 
 
29
using namespace std;
27
30
 
28
31
/****************************************************************************
29
32
  VARCHAR type
41
44
  is 2.
42
45
****************************************************************************/
43
46
 
44
 
const uint Field_varstring::MAX_SIZE= UINT16_MAX;
 
47
const uint32_t Field_varstring::MAX_SIZE= UINT16_MAX;
 
48
 
 
49
Field_varstring::Field_varstring(unsigned char *ptr_arg,
 
50
                                 uint32_t len_arg, uint32_t length_bytes_arg,
 
51
                                 unsigned char *null_ptr_arg,
 
52
                                 unsigned char null_bit_arg,
 
53
                                 enum utype unireg_check_arg,
 
54
                                 const char *field_name_arg,
 
55
                                 TABLE_SHARE *share,
 
56
                                 const CHARSET_INFO * const cs)
 
57
  :Field_longstr(ptr_arg, len_arg, null_ptr_arg, null_bit_arg,
 
58
                 unireg_check_arg, field_name_arg, cs),
 
59
   length_bytes(length_bytes_arg)
 
60
{
 
61
  share->varchar_fields++;
 
62
}
 
63
 
 
64
Field_varstring::Field_varstring(uint32_t len_arg,bool maybe_null_arg,
 
65
                                 const char *field_name_arg,
 
66
                                 TABLE_SHARE *share,
 
67
                                 const CHARSET_INFO * const cs)
 
68
  :Field_longstr((unsigned char*) 0,len_arg,
 
69
                 maybe_null_arg ? (unsigned char*) "": 0, 0,
 
70
                 NONE, field_name_arg, cs),
 
71
   length_bytes(len_arg < 256 ? 1 :2)
 
72
{
 
73
  share->varchar_fields++;
 
74
}
 
75
 
45
76
 
46
77
/**
47
78
   Save the field metadata for varstring fields.
54
85
 
55
86
   @returns number of bytes written to metadata_ptr
56
87
*/
57
 
int Field_varstring::do_save_field_metadata(uchar *metadata_ptr)
 
88
int Field_varstring::do_save_field_metadata(unsigned char *metadata_ptr)
58
89
{
59
90
  char *ptr= (char *)metadata_ptr;
60
91
  assert(field_length <= 65535);
62
93
  return 2;
63
94
}
64
95
 
65
 
int Field_varstring::store(const char *from,uint length, const CHARSET_INFO * const cs)
 
96
int Field_varstring::store(const char *from,uint32_t length, const CHARSET_INFO * const cs)
66
97
{
67
 
  uint copy_length;
 
98
  uint32_t copy_length;
68
99
  const char *well_formed_error_pos;
69
100
  const char *cannot_convert_error_pos;
70
101
  const char *from_end_pos;
79
110
                                       &from_end_pos);
80
111
 
81
112
  if (length_bytes == 1)
82
 
    *ptr= (uchar) copy_length;
 
113
    *ptr= (unsigned char) copy_length;
83
114
  else
84
115
    int2store(ptr, copy_length);
85
116
 
94
125
int Field_varstring::store(int64_t nr, bool unsigned_val)
95
126
{
96
127
  char buff[64];
97
 
  uint  length;
 
128
  uint32_t  length;
98
129
  length= (uint) (field_charset->cset->int64_t10_to_str)(field_charset,
99
130
                                                          buff,
100
131
                                                          sizeof(buff),
109
140
{
110
141
  int not_used;
111
142
  char *end_not_used;
112
 
  uint length= length_bytes == 1 ? (uint) *ptr : uint2korr(ptr);
 
143
  uint32_t length= length_bytes == 1 ? (uint) *ptr : uint2korr(ptr);
113
144
  return my_strntod(field_charset, (char*) ptr+length_bytes, length,
114
145
                    &end_not_used, &not_used);
115
146
}
119
150
{
120
151
  int not_used;
121
152
  char *end_not_used;
122
 
  uint length= length_bytes == 1 ? (uint) *ptr : uint2korr(ptr);
 
153
  uint32_t length= length_bytes == 1 ? (uint) *ptr : uint2korr(ptr);
123
154
  return my_strntoll(field_charset, (char*) ptr+length_bytes, length, 10,
124
155
                     &end_not_used, &not_used);
125
156
}
127
158
String *Field_varstring::val_str(String *val_buffer __attribute__((unused)),
128
159
                                 String *val_ptr)
129
160
{
130
 
  uint length=  length_bytes == 1 ? (uint) *ptr : uint2korr(ptr);
 
161
  uint32_t length=  length_bytes == 1 ? (uint) *ptr : uint2korr(ptr);
131
162
  val_ptr->set((const char*) ptr+length_bytes, length, field_charset);
132
163
  return val_ptr;
133
164
}
135
166
 
136
167
my_decimal *Field_varstring::val_decimal(my_decimal *decimal_value)
137
168
{
138
 
  uint length= length_bytes == 1 ? (uint) *ptr : uint2korr(ptr);
 
169
  uint32_t length= length_bytes == 1 ? (uint) *ptr : uint2korr(ptr);
139
170
  str2my_decimal(E_DEC_FATAL_ERROR, (char*) ptr+length_bytes, length,
140
171
                 charset(), decimal_value);
141
172
  return decimal_value;
142
173
}
143
174
 
144
175
 
145
 
int Field_varstring::cmp_max(const uchar *a_ptr, const uchar *b_ptr,
146
 
                             uint max_len)
 
176
int Field_varstring::cmp_max(const unsigned char *a_ptr, const unsigned char *b_ptr,
 
177
                             uint32_t max_len)
147
178
{
148
 
  uint a_length, b_length;
 
179
  uint32_t a_length, b_length;
149
180
  int diff;
150
181
 
151
182
  if (length_bytes == 1)
176
207
    varstring and blob keys are ALWAYS stored with a 2 byte length prefix
177
208
*/
178
209
 
179
 
int Field_varstring::key_cmp(const uchar *key_ptr, uint max_key_length)
 
210
int Field_varstring::key_cmp(const unsigned char *key_ptr, uint32_t max_key_length)
180
211
{
181
 
  uint length=  length_bytes == 1 ? (uint) *ptr : uint2korr(ptr);
182
 
  uint local_char_length= max_key_length / field_charset->mbmaxlen;
 
212
  uint32_t length=  length_bytes == 1 ? (uint) *ptr : uint2korr(ptr);
 
213
  uint32_t local_char_length= max_key_length / field_charset->mbmaxlen;
183
214
 
184
215
  local_char_length= my_charpos(field_charset, ptr + length_bytes,
185
216
                          ptr + length_bytes + length, local_char_length);
186
217
  set_if_smaller(length, local_char_length);
187
 
  return field_charset->coll->strnncollsp(field_charset, 
 
218
  return field_charset->coll->strnncollsp(field_charset,
188
219
                                          ptr + length_bytes,
189
220
                                          length,
190
221
                                          key_ptr+
201
232
    (keys are created and compared in key.cc)
202
233
*/
203
234
 
204
 
int Field_varstring::key_cmp(const uchar *a,const uchar *b)
 
235
int Field_varstring::key_cmp(const unsigned char *a,const unsigned char *b)
205
236
{
206
237
  return field_charset->coll->strnncollsp(field_charset,
207
238
                                          a + HA_KEY_BLOB_LENGTH,
212
243
}
213
244
 
214
245
 
215
 
void Field_varstring::sort_string(uchar *to,uint length)
 
246
void Field_varstring::sort_string(unsigned char *to,uint32_t length)
216
247
{
217
 
  uint tot_length=  length_bytes == 1 ? (uint) *ptr : uint2korr(ptr);
 
248
  uint32_t tot_length=  length_bytes == 1 ? (uint) *ptr : uint2korr(ptr);
218
249
 
219
250
  if (field_charset == &my_charset_bin)
220
251
  {
225
256
      mi_int2store(to+length-2, tot_length);
226
257
    length-= length_bytes;
227
258
  }
228
 
 
 
259
 
229
260
  tot_length= my_strnxfrm(field_charset,
230
261
                          to, length, ptr + length_bytes,
231
262
                          tot_length);
247
278
 
248
279
void Field_varstring::sql_type(String &res) const
249
280
{
250
 
  THD *thd= table->in_use;
251
281
  const CHARSET_INFO * const cs=res.charset();
252
282
  uint32_t length;
253
283
 
256
286
                              (has_charset() ? "varchar" : "varbinary"),
257
287
                             (int) field_length / charset()->mbmaxlen);
258
288
  res.length(length);
259
 
  if ((thd->variables.sql_mode & (MODE_MYSQL323 | MODE_MYSQL40)) &&
260
 
      has_charset() && (charset()->state & MY_CS_BINSORT))
261
 
    res.append(STRING_WITH_LEN(" binary"));
262
289
}
263
290
 
264
291
 
269
296
 
270
297
uint32_t Field_varstring::used_length()
271
298
{
272
 
  return length_bytes == 1 ? 1 + (uint32_t) (uchar) *ptr : 2 + uint2korr(ptr);
 
299
  return length_bytes == 1 ? 1 + (uint32_t) (unsigned char) *ptr : 2 + uint2korr(ptr);
273
300
}
274
301
 
275
302
/*
277
304
  Here the number of length bytes are depending on the given max_length
278
305
*/
279
306
 
280
 
uchar *Field_varstring::pack(uchar *to, const uchar *from,
281
 
                             uint max_length,
 
307
unsigned char *Field_varstring::pack(unsigned char *to, const unsigned char *from,
 
308
                             uint32_t max_length,
282
309
                             bool low_byte_first __attribute__((unused)))
283
310
{
284
 
  uint length= length_bytes == 1 ? (uint) *from : uint2korr(from);
 
311
  uint32_t length= length_bytes == 1 ? (uint) *from : uint2korr(from);
285
312
  set_if_smaller(max_length, field_length);
286
313
  if (length > max_length)
287
314
    length=max_length;
298
325
}
299
326
 
300
327
 
301
 
uchar *
302
 
Field_varstring::pack_key(uchar *to, const uchar *key, uint max_length,
 
328
unsigned char *
 
329
Field_varstring::pack_key(unsigned char *to, const unsigned char *key, uint32_t max_length,
303
330
                          bool low_byte_first __attribute__((unused)))
304
331
{
305
 
  uint length=  length_bytes == 1 ? (uint) *key : uint2korr(key);
306
 
  uint local_char_length= ((field_charset->mbmaxlen > 1) ?
 
332
  uint32_t length=  length_bytes == 1 ? (uint) *key : uint2korr(key);
 
333
  uint32_t local_char_length= ((field_charset->mbmaxlen > 1) ?
307
334
                     max_length/field_charset->mbmaxlen : max_length);
308
335
  key+= length_bytes;
309
336
  if (length > local_char_length)
336
363
    Pointer to end of 'key' (To the next key part if multi-segment key)
337
364
*/
338
365
 
339
 
const uchar *
340
 
Field_varstring::unpack_key(uchar *to __attribute__((unused)),
341
 
                            const uchar *key, uint max_length,
 
366
const unsigned char *
 
367
Field_varstring::unpack_key(unsigned char *to __attribute__((unused)),
 
368
                            const unsigned char *key, uint32_t max_length,
342
369
                            bool low_byte_first __attribute__((unused)))
343
370
{
344
371
  /* get length of the blob key */
348
375
 
349
376
  /* put the length into the record buffer */
350
377
  if (length_bytes == 1)
351
 
    *ptr= (uchar) length;
 
378
    *ptr= (unsigned char) length;
352
379
  else
353
380
    int2store(ptr, length);
354
381
  memcpy(ptr + length_bytes, key, length);
366
393
    end of key storage
367
394
*/
368
395
 
369
 
uchar *
370
 
Field_varstring::pack_key_from_key_image(uchar *to, const uchar *from, uint max_length,
 
396
unsigned char *
 
397
Field_varstring::pack_key_from_key_image(unsigned char *to, const unsigned char *from, uint32_t max_length,
371
398
                                         bool low_byte_first __attribute__((unused)))
372
399
{
373
400
  /* Key length is always stored as 2 bytes */
374
 
  uint length= uint2korr(from);
 
401
  uint32_t length= uint2korr(from);
375
402
  if (length > max_length)
376
403
    length= max_length;
377
404
  *to++= (char) (length & 255);
391
418
 
392
419
   @note
393
420
   The string length is always packed little-endian.
394
 
  
 
421
 
395
422
   @param   to         Destination of the data
396
423
   @param   from       Source of the data
397
424
   @param   param_data Length bytes from the master's field data
398
425
 
399
426
   @return  New pointer into memory based on from + length of the data
400
427
*/
401
 
const uchar *
402
 
Field_varstring::unpack(uchar *to, const uchar *from,
403
 
                        uint param_data,
 
428
const unsigned char *
 
429
Field_varstring::unpack(unsigned char *to, const unsigned char *from,
 
430
                        uint32_t param_data,
404
431
                        bool low_byte_first __attribute__((unused)))
405
432
{
406
 
  uint length;
407
 
  uint l_bytes= (param_data && (param_data < field_length)) ? 
 
433
  uint32_t length;
 
434
  uint32_t l_bytes= (param_data && (param_data < field_length)) ?
408
435
                (param_data <= 255) ? 1 : 2 : length_bytes;
409
436
  if (l_bytes == 1)
410
437
  {
425
452
}
426
453
 
427
454
 
428
 
int Field_varstring::pack_cmp(const uchar *a, const uchar *b,
429
 
                              uint key_length_arg,
 
455
int Field_varstring::pack_cmp(const unsigned char *a, const unsigned char *b,
 
456
                              uint32_t key_length_arg,
430
457
                              bool insert_or_update)
431
458
{
432
 
  uint a_length, b_length;
 
459
  uint32_t a_length, b_length;
433
460
  if (key_length_arg > 255)
434
461
  {
435
462
    a_length=uint2korr(a); a+= 2;
447
474
}
448
475
 
449
476
 
450
 
int Field_varstring::pack_cmp(const uchar *b, uint key_length_arg,
 
477
int Field_varstring::pack_cmp(const unsigned char *b, uint32_t key_length_arg,
451
478
                              bool insert_or_update)
452
479
{
453
 
  uchar *a= ptr+ length_bytes;
454
 
  uint a_length=  length_bytes == 1 ? (uint) *ptr : uint2korr(ptr);
455
 
  uint b_length;
456
 
  uint local_char_length= ((field_charset->mbmaxlen > 1) ?
 
480
  unsigned char *a= ptr+ length_bytes;
 
481
  uint32_t a_length=  length_bytes == 1 ? (uint) *ptr : uint2korr(ptr);
 
482
  uint32_t b_length;
 
483
  uint32_t local_char_length= ((field_charset->mbmaxlen > 1) ?
457
484
                           key_length_arg / field_charset->mbmaxlen :
458
485
                           key_length_arg);
459
486
 
478
505
}
479
506
 
480
507
 
481
 
uint Field_varstring::packed_col_length(const uchar *data_ptr, uint length)
 
508
uint32_t Field_varstring::packed_col_length(const unsigned char *data_ptr, uint32_t length)
482
509
{
483
510
  if (length > 255)
484
511
    return uint2korr(data_ptr)+2;
486
513
}
487
514
 
488
515
 
489
 
uint Field_varstring::max_packed_col_length(uint max_length)
 
516
uint32_t Field_varstring::max_packed_col_length(uint32_t max_length)
490
517
{
491
518
  return (max_length > 255 ? 2 : 1)+max_length;
492
519
}
493
520
 
494
 
uint Field_varstring::get_key_image(uchar *buff,
495
 
                                    uint length,
 
521
uint32_t Field_varstring::get_key_image(basic_string<unsigned char> &buff,
 
522
                                        uint32_t length, imagetype)
 
523
{
 
524
  /* Key is always stored with 2 bytes */
 
525
  const uint32_t key_len= 2;
 
526
  uint32_t f_length=  length_bytes == 1 ? (uint) *ptr : uint2korr(ptr);
 
527
  uint32_t local_char_length= length / field_charset->mbmaxlen;
 
528
  unsigned char *pos= ptr+length_bytes;
 
529
  local_char_length= my_charpos(field_charset, pos, pos + f_length,
 
530
                                local_char_length);
 
531
  set_if_smaller(f_length, local_char_length);
 
532
  unsigned char len_buff[key_len];
 
533
  int2store(len_buff,f_length);
 
534
  buff.append(len_buff);
 
535
  buff.append(pos, f_length);
 
536
  if (f_length < length)
 
537
  {
 
538
    /*
 
539
      Must clear this as we do a memcmp in opt_range.cc to detect
 
540
      identical keys
 
541
    */
 
542
    buff.append(length-f_length, 0);
 
543
  }
 
544
  return key_len+f_length;
 
545
}
 
546
 
 
547
 
 
548
uint32_t Field_varstring::get_key_image(unsigned char *buff,
 
549
                                    uint32_t length,
496
550
                                    imagetype type __attribute__((unused)))
497
551
{
498
 
  uint f_length=  length_bytes == 1 ? (uint) *ptr : uint2korr(ptr);
499
 
  uint local_char_length= length / field_charset->mbmaxlen;
500
 
  uchar *pos= ptr+length_bytes;
 
552
  uint32_t f_length=  length_bytes == 1 ? (uint) *ptr : uint2korr(ptr);
 
553
  uint32_t local_char_length= length / field_charset->mbmaxlen;
 
554
  unsigned char *pos= ptr+length_bytes;
501
555
  local_char_length= my_charpos(field_charset, pos, pos + f_length,
502
556
                                local_char_length);
503
557
  set_if_smaller(f_length, local_char_length);
516
570
}
517
571
 
518
572
 
519
 
void Field_varstring::set_key_image(const uchar *buff,uint length)
 
573
void Field_varstring::set_key_image(const unsigned char *buff,uint32_t length)
520
574
{
521
575
  length= uint2korr(buff);                      // Real length is here
522
576
  (void) Field_varstring::store((const char*) buff+HA_KEY_BLOB_LENGTH, length,
524
578
}
525
579
 
526
580
 
527
 
int Field_varstring::cmp_binary(const uchar *a_ptr, const uchar *b_ptr,
 
581
int Field_varstring::cmp_binary(const unsigned char *a_ptr, const unsigned char *b_ptr,
528
582
                                uint32_t max_length)
529
583
{
530
584
  uint32_t a_length,b_length;
547
601
}
548
602
 
549
603
 
550
 
Field *Field_varstring::new_field(MEM_ROOT *root, struct st_table *new_table,
551
 
                                  bool keep_type)
 
604
Field *Field_varstring::new_field(MEM_ROOT *root, Table *new_table, bool keep_type)
552
605
{
553
606
  Field_varstring *res= (Field_varstring*) Field::new_field(root, new_table,
554
607
                                                            keep_type);
559
612
 
560
613
 
561
614
Field *Field_varstring::new_key_field(MEM_ROOT *root,
562
 
                                      struct st_table *new_table,
563
 
                                      uchar *new_ptr, uchar *new_null_ptr,
564
 
                                      uint new_null_bit)
 
615
                                      Table *new_table,
 
616
                                      unsigned char *new_ptr, unsigned char *new_null_ptr,
 
617
                                      uint32_t new_null_bit)
565
618
{
566
619
  Field_varstring *res;
567
620
  if ((res= (Field_varstring*) Field::new_key_field(root,
577
630
}
578
631
 
579
632
 
580
 
uint Field_varstring::is_equal(Create_field *new_field)
 
633
uint32_t Field_varstring::is_equal(Create_field *new_field)
581
634
{
582
635
  if (new_field->sql_type == real_type() &&
583
636
      new_field->charset == field_charset)