~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to drizzled/field/varstring.cc

Merged build changes from Antony.

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
#ifdef USE_PRAGMA_IMPLEMENTATION
 
22
#pragma implementation                          // gcc: Class implementation
 
23
#endif
 
24
 
 
25
#include <drizzled/field/varstring.h>
 
26
 
 
27
/****************************************************************************
 
28
  VARCHAR type
 
29
  Data in field->ptr is stored as:
 
30
    1 or 2 bytes length-prefix-header  (from Field_varstring::length_bytes)
 
31
    data
 
32
 
 
33
  NOTE:
 
34
  When VARCHAR is stored in a key (for handler::index_read() etc) it's always
 
35
  stored with a 2 byte prefix. (Just like blob keys).
 
36
 
 
37
  Normally length_bytes is calculated as (field_length < 256 : 1 ? 2)
 
38
  The exception is if there is a prefix key field that is part of a long
 
39
  VARCHAR, in which case field_length for this may be 1 but the length_bytes
 
40
  is 2.
 
41
****************************************************************************/
 
42
 
 
43
const uint Field_varstring::MAX_SIZE= UINT16_MAX;
 
44
 
 
45
/**
 
46
   Save the field metadata for varstring fields.
 
47
 
 
48
   Saves the field length in the first byte. Note: may consume
 
49
   2 bytes. Caller must ensure second byte is contiguous with
 
50
   first byte (e.g. array index 0,1).
 
51
 
 
52
   @param   metadata_ptr   First byte of field metadata
 
53
 
 
54
   @returns number of bytes written to metadata_ptr
 
55
*/
 
56
int Field_varstring::do_save_field_metadata(uchar *metadata_ptr)
 
57
{
 
58
  char *ptr= (char *)metadata_ptr;
 
59
  assert(field_length <= 65535);
 
60
  int2store(ptr, field_length);
 
61
  return 2;
 
62
}
 
63
 
 
64
int Field_varstring::store(const char *from,uint length,CHARSET_INFO *cs)
 
65
{
 
66
  uint copy_length;
 
67
  const char *well_formed_error_pos;
 
68
  const char *cannot_convert_error_pos;
 
69
  const char *from_end_pos;
 
70
 
 
71
  copy_length= well_formed_copy_nchars(field_charset,
 
72
                                       (char*) ptr + length_bytes,
 
73
                                       field_length,
 
74
                                       cs, from, length,
 
75
                                       field_length / field_charset->mbmaxlen,
 
76
                                       &well_formed_error_pos,
 
77
                                       &cannot_convert_error_pos,
 
78
                                       &from_end_pos);
 
79
 
 
80
  if (length_bytes == 1)
 
81
    *ptr= (uchar) copy_length;
 
82
  else
 
83
    int2store(ptr, copy_length);
 
84
 
 
85
  if (check_string_copy_error(this, well_formed_error_pos,
 
86
                              cannot_convert_error_pos, from + length, cs))
 
87
    return 2;
 
88
 
 
89
  return report_if_important_data(from_end_pos, from + length);
 
90
}
 
91
 
 
92
 
 
93
int Field_varstring::store(int64_t nr, bool unsigned_val)
 
94
{
 
95
  char buff[64];
 
96
  uint  length;
 
97
  length= (uint) (field_charset->cset->int64_t10_to_str)(field_charset,
 
98
                                                          buff,
 
99
                                                          sizeof(buff),
 
100
                                                          (unsigned_val ? 10:
 
101
                                                           -10),
 
102
                                                           nr);
 
103
  return Field_varstring::store(buff, length, field_charset);
 
104
}
 
105
 
 
106
 
 
107
double Field_varstring::val_real(void)
 
108
{
 
109
  int not_used;
 
110
  char *end_not_used;
 
111
  uint length= length_bytes == 1 ? (uint) *ptr : uint2korr(ptr);
 
112
  return my_strntod(field_charset, (char*) ptr+length_bytes, length,
 
113
                    &end_not_used, &not_used);
 
114
}
 
115
 
 
116
 
 
117
int64_t Field_varstring::val_int(void)
 
118
{
 
119
  int not_used;
 
120
  char *end_not_used;
 
121
  uint length= length_bytes == 1 ? (uint) *ptr : uint2korr(ptr);
 
122
  return my_strntoll(field_charset, (char*) ptr+length_bytes, length, 10,
 
123
                     &end_not_used, &not_used);
 
124
}
 
125
 
 
126
String *Field_varstring::val_str(String *val_buffer __attribute__((unused)),
 
127
                                 String *val_ptr)
 
128
{
 
129
  uint length=  length_bytes == 1 ? (uint) *ptr : uint2korr(ptr);
 
130
  val_ptr->set((const char*) ptr+length_bytes, length, field_charset);
 
131
  return val_ptr;
 
132
}
 
133
 
 
134
 
 
135
my_decimal *Field_varstring::val_decimal(my_decimal *decimal_value)
 
136
{
 
137
  uint length= length_bytes == 1 ? (uint) *ptr : uint2korr(ptr);
 
138
  str2my_decimal(E_DEC_FATAL_ERROR, (char*) ptr+length_bytes, length,
 
139
                 charset(), decimal_value);
 
140
  return decimal_value;
 
141
}
 
142
 
 
143
 
 
144
int Field_varstring::cmp_max(const uchar *a_ptr, const uchar *b_ptr,
 
145
                             uint max_len)
 
146
{
 
147
  uint a_length, b_length;
 
148
  int diff;
 
149
 
 
150
  if (length_bytes == 1)
 
151
  {
 
152
    a_length= (uint) *a_ptr;
 
153
    b_length= (uint) *b_ptr;
 
154
  }
 
155
  else
 
156
  {
 
157
    a_length= uint2korr(a_ptr);
 
158
    b_length= uint2korr(b_ptr);
 
159
  }
 
160
  set_if_smaller(a_length, max_len);
 
161
  set_if_smaller(b_length, max_len);
 
162
  diff= field_charset->coll->strnncollsp(field_charset,
 
163
                                         a_ptr+
 
164
                                         length_bytes,
 
165
                                         a_length,
 
166
                                         b_ptr+
 
167
                                         length_bytes,
 
168
                                         b_length,0);
 
169
  return diff;
 
170
}
 
171
 
 
172
 
 
173
/**
 
174
  @note
 
175
    varstring and blob keys are ALWAYS stored with a 2 byte length prefix
 
176
*/
 
177
 
 
178
int Field_varstring::key_cmp(const uchar *key_ptr, uint max_key_length)
 
179
{
 
180
  uint length=  length_bytes == 1 ? (uint) *ptr : uint2korr(ptr);
 
181
  uint local_char_length= max_key_length / field_charset->mbmaxlen;
 
182
 
 
183
  local_char_length= my_charpos(field_charset, ptr + length_bytes,
 
184
                          ptr + length_bytes + length, local_char_length);
 
185
  set_if_smaller(length, local_char_length);
 
186
  return field_charset->coll->strnncollsp(field_charset, 
 
187
                                          ptr + length_bytes,
 
188
                                          length,
 
189
                                          key_ptr+
 
190
                                          HA_KEY_BLOB_LENGTH,
 
191
                                          uint2korr(key_ptr), 0);
 
192
}
 
193
 
 
194
 
 
195
/**
 
196
  Compare to key segments (always 2 byte length prefix).
 
197
 
 
198
  @note
 
199
    This is used only to compare key segments created for index_read().
 
200
    (keys are created and compared in key.cc)
 
201
*/
 
202
 
 
203
int Field_varstring::key_cmp(const uchar *a,const uchar *b)
 
204
{
 
205
  return field_charset->coll->strnncollsp(field_charset,
 
206
                                          a + HA_KEY_BLOB_LENGTH,
 
207
                                          uint2korr(a),
 
208
                                          b + HA_KEY_BLOB_LENGTH,
 
209
                                          uint2korr(b),
 
210
                                          0);
 
211
}
 
212
 
 
213
 
 
214
void Field_varstring::sort_string(uchar *to,uint length)
 
215
{
 
216
  uint tot_length=  length_bytes == 1 ? (uint) *ptr : uint2korr(ptr);
 
217
 
 
218
  if (field_charset == &my_charset_bin)
 
219
  {
 
220
    /* Store length last in high-byte order to sort longer strings first */
 
221
    if (length_bytes == 1)
 
222
      to[length-1]= tot_length;
 
223
    else
 
224
      mi_int2store(to+length-2, tot_length);
 
225
    length-= length_bytes;
 
226
  }
 
227
 
 
228
  tot_length= my_strnxfrm(field_charset,
 
229
                          to, length, ptr + length_bytes,
 
230
                          tot_length);
 
231
  assert(tot_length == length);
 
232
}
 
233
 
 
234
 
 
235
enum ha_base_keytype Field_varstring::key_type() const
 
236
{
 
237
  enum ha_base_keytype res;
 
238
 
 
239
  if (binary())
 
240
    res= length_bytes == 1 ? HA_KEYTYPE_VARBINARY1 : HA_KEYTYPE_VARBINARY2;
 
241
  else
 
242
    res= length_bytes == 1 ? HA_KEYTYPE_VARTEXT1 : HA_KEYTYPE_VARTEXT2;
 
243
  return res;
 
244
}
 
245
 
 
246
 
 
247
void Field_varstring::sql_type(String &res) const
 
248
{
 
249
  THD *thd= table->in_use;
 
250
  CHARSET_INFO *cs=res.charset();
 
251
  ulong length;
 
252
 
 
253
  length= cs->cset->snprintf(cs,(char*) res.ptr(),
 
254
                             res.alloced_length(), "%s(%d)",
 
255
                              (has_charset() ? "varchar" : "varbinary"),
 
256
                             (int) field_length / charset()->mbmaxlen);
 
257
  res.length(length);
 
258
  if ((thd->variables.sql_mode & (MODE_MYSQL323 | MODE_MYSQL40)) &&
 
259
      has_charset() && (charset()->state & MY_CS_BINSORT))
 
260
    res.append(STRING_WITH_LEN(" binary"));
 
261
}
 
262
 
 
263
 
 
264
uint32_t Field_varstring::data_length()
 
265
{
 
266
  return length_bytes == 1 ? (uint32_t) *ptr : uint2korr(ptr);
 
267
}
 
268
 
 
269
uint32_t Field_varstring::used_length()
 
270
{
 
271
  return length_bytes == 1 ? 1 + (uint32_t) (uchar) *ptr : 2 + uint2korr(ptr);
 
272
}
 
273
 
 
274
/*
 
275
  Functions to create a packed row.
 
276
  Here the number of length bytes are depending on the given max_length
 
277
*/
 
278
 
 
279
uchar *Field_varstring::pack(uchar *to, const uchar *from,
 
280
                             uint max_length,
 
281
                             bool low_byte_first __attribute__((unused)))
 
282
{
 
283
  uint length= length_bytes == 1 ? (uint) *from : uint2korr(from);
 
284
  set_if_smaller(max_length, field_length);
 
285
  if (length > max_length)
 
286
    length=max_length;
 
287
 
 
288
  /* Length always stored little-endian */
 
289
  *to++= length & 0xFF;
 
290
  if (max_length > 255)
 
291
    *to++= (length >> 8) & 0xFF;
 
292
 
 
293
  /* Store bytes of string */
 
294
  if (length > 0)
 
295
    memcpy(to, from+length_bytes, length);
 
296
  return to+length;
 
297
}
 
298
 
 
299
 
 
300
uchar *
 
301
Field_varstring::pack_key(uchar *to, const uchar *key, uint max_length,
 
302
                          bool low_byte_first __attribute__((unused)))
 
303
{
 
304
  uint length=  length_bytes == 1 ? (uint) *key : uint2korr(key);
 
305
  uint local_char_length= ((field_charset->mbmaxlen > 1) ?
 
306
                     max_length/field_charset->mbmaxlen : max_length);
 
307
  key+= length_bytes;
 
308
  if (length > local_char_length)
 
309
  {
 
310
    local_char_length= my_charpos(field_charset, key, key+length,
 
311
                                  local_char_length);
 
312
    set_if_smaller(length, local_char_length);
 
313
  }
 
314
  *to++= (char) (length & 255);
 
315
  if (max_length > 255)
 
316
    *to++= (char) (length >> 8);
 
317
  if (length)
 
318
    memcpy(to, key, length);
 
319
  return to+length;
 
320
}
 
321
 
 
322
 
 
323
/**
 
324
  Unpack a key into a record buffer.
 
325
 
 
326
  A VARCHAR key has a maximum size of 64K-1.
 
327
  In its packed form, the length field is one or two bytes long,
 
328
  depending on 'max_length'.
 
329
 
 
330
  @param to                          Pointer into the record buffer.
 
331
  @param key                         Pointer to the packed key.
 
332
  @param max_length                  Key length limit from key description.
 
333
 
 
334
  @return
 
335
    Pointer to end of 'key' (To the next key part if multi-segment key)
 
336
*/
 
337
 
 
338
const uchar *
 
339
Field_varstring::unpack_key(uchar *to __attribute__((unused)),
 
340
                            const uchar *key, uint max_length,
 
341
                            bool low_byte_first __attribute__((unused)))
 
342
{
 
343
  /* get length of the blob key */
 
344
  uint32_t length= *key++;
 
345
  if (max_length > 255)
 
346
    length+= (*key++) << 8;
 
347
 
 
348
  /* put the length into the record buffer */
 
349
  if (length_bytes == 1)
 
350
    *ptr= (uchar) length;
 
351
  else
 
352
    int2store(ptr, length);
 
353
  memcpy(ptr + length_bytes, key, length);
 
354
  return key + length;
 
355
}
 
356
 
 
357
/**
 
358
  Create a packed key that will be used for storage in the index tree.
 
359
 
 
360
  @param to             Store packed key segment here
 
361
  @param from           Key segment (as given to index_read())
 
362
  @param max_length     Max length of key
 
363
 
 
364
  @return
 
365
    end of key storage
 
366
*/
 
367
 
 
368
uchar *
 
369
Field_varstring::pack_key_from_key_image(uchar *to, const uchar *from, uint max_length,
 
370
                                         bool low_byte_first __attribute__((unused)))
 
371
{
 
372
  /* Key length is always stored as 2 bytes */
 
373
  uint length= uint2korr(from);
 
374
  if (length > max_length)
 
375
    length= max_length;
 
376
  *to++= (char) (length & 255);
 
377
  if (max_length > 255)
 
378
    *to++= (char) (length >> 8);
 
379
  if (length)
 
380
    memcpy(to, from+HA_KEY_BLOB_LENGTH, length);
 
381
  return to+length;
 
382
}
 
383
 
 
384
 
 
385
/**
 
386
   Unpack a varstring field from row data.
 
387
 
 
388
   This method is used to unpack a varstring field from a master
 
389
   whose size of the field is less than that of the slave.
 
390
 
 
391
   @note
 
392
   The string length is always packed little-endian.
 
393
  
 
394
   @param   to         Destination of the data
 
395
   @param   from       Source of the data
 
396
   @param   param_data Length bytes from the master's field data
 
397
 
 
398
   @return  New pointer into memory based on from + length of the data
 
399
*/
 
400
const uchar *
 
401
Field_varstring::unpack(uchar *to, const uchar *from,
 
402
                        uint param_data,
 
403
                        bool low_byte_first __attribute__((unused)))
 
404
{
 
405
  uint length;
 
406
  uint l_bytes= (param_data && (param_data < field_length)) ? 
 
407
                (param_data <= 255) ? 1 : 2 : length_bytes;
 
408
  if (l_bytes == 1)
 
409
  {
 
410
    to[0]= *from++;
 
411
    length= to[0];
 
412
    if (length_bytes == 2)
 
413
      to[1]= 0;
 
414
  }
 
415
  else /* l_bytes == 2 */
 
416
  {
 
417
    length= uint2korr(from);
 
418
    to[0]= *from++;
 
419
    to[1]= *from++;
 
420
  }
 
421
  if (length)
 
422
    memcpy(to+ length_bytes, from, length);
 
423
  return from+length;
 
424
}
 
425
 
 
426
 
 
427
int Field_varstring::pack_cmp(const uchar *a, const uchar *b,
 
428
                              uint key_length_arg,
 
429
                              my_bool insert_or_update)
 
430
{
 
431
  uint a_length, b_length;
 
432
  if (key_length_arg > 255)
 
433
  {
 
434
    a_length=uint2korr(a); a+= 2;
 
435
    b_length=uint2korr(b); b+= 2;
 
436
  }
 
437
  else
 
438
  {
 
439
    a_length= (uint) *a++;
 
440
    b_length= (uint) *b++;
 
441
  }
 
442
  return field_charset->coll->strnncollsp(field_charset,
 
443
                                          a, a_length,
 
444
                                          b, b_length,
 
445
                                          insert_or_update);
 
446
}
 
447
 
 
448
 
 
449
int Field_varstring::pack_cmp(const uchar *b, uint key_length_arg,
 
450
                              my_bool insert_or_update)
 
451
{
 
452
  uchar *a= ptr+ length_bytes;
 
453
  uint a_length=  length_bytes == 1 ? (uint) *ptr : uint2korr(ptr);
 
454
  uint b_length;
 
455
  uint local_char_length= ((field_charset->mbmaxlen > 1) ?
 
456
                           key_length_arg / field_charset->mbmaxlen :
 
457
                           key_length_arg);
 
458
 
 
459
  if (key_length_arg > 255)
 
460
  {
 
461
    b_length=uint2korr(b); b+= HA_KEY_BLOB_LENGTH;
 
462
  }
 
463
  else
 
464
    b_length= (uint) *b++;
 
465
 
 
466
  if (a_length > local_char_length)
 
467
  {
 
468
    local_char_length= my_charpos(field_charset, a, a+a_length,
 
469
                                  local_char_length);
 
470
    set_if_smaller(a_length, local_char_length);
 
471
  }
 
472
 
 
473
  return field_charset->coll->strnncollsp(field_charset,
 
474
                                          a, a_length,
 
475
                                          b, b_length,
 
476
                                          insert_or_update);
 
477
}
 
478
 
 
479
 
 
480
uint Field_varstring::packed_col_length(const uchar *data_ptr, uint length)
 
481
{
 
482
  if (length > 255)
 
483
    return uint2korr(data_ptr)+2;
 
484
  return (uint) *data_ptr + 1;
 
485
}
 
486
 
 
487
 
 
488
uint Field_varstring::max_packed_col_length(uint max_length)
 
489
{
 
490
  return (max_length > 255 ? 2 : 1)+max_length;
 
491
}
 
492
 
 
493
uint Field_varstring::get_key_image(uchar *buff,
 
494
                                    uint length,
 
495
                                    imagetype type __attribute__((unused)))
 
496
{
 
497
  uint f_length=  length_bytes == 1 ? (uint) *ptr : uint2korr(ptr);
 
498
  uint local_char_length= length / field_charset->mbmaxlen;
 
499
  uchar *pos= ptr+length_bytes;
 
500
  local_char_length= my_charpos(field_charset, pos, pos + f_length,
 
501
                                local_char_length);
 
502
  set_if_smaller(f_length, local_char_length);
 
503
  /* Key is always stored with 2 bytes */
 
504
  int2store(buff,f_length);
 
505
  memcpy(buff+HA_KEY_BLOB_LENGTH, pos, f_length);
 
506
  if (f_length < length)
 
507
  {
 
508
    /*
 
509
      Must clear this as we do a memcmp in opt_range.cc to detect
 
510
      identical keys
 
511
    */
 
512
    memset(buff+HA_KEY_BLOB_LENGTH+f_length, 0, (length-f_length));
 
513
  }
 
514
  return HA_KEY_BLOB_LENGTH+f_length;
 
515
}
 
516
 
 
517
 
 
518
void Field_varstring::set_key_image(const uchar *buff,uint length)
 
519
{
 
520
  length= uint2korr(buff);                      // Real length is here
 
521
  (void) Field_varstring::store((const char*) buff+HA_KEY_BLOB_LENGTH, length,
 
522
                                field_charset);
 
523
}
 
524
 
 
525
 
 
526
int Field_varstring::cmp_binary(const uchar *a_ptr, const uchar *b_ptr,
 
527
                                uint32_t max_length)
 
528
{
 
529
  uint32_t a_length,b_length;
 
530
 
 
531
  if (length_bytes == 1)
 
532
  {
 
533
    a_length= (uint) *a_ptr;
 
534
    b_length= (uint) *b_ptr;
 
535
  }
 
536
  else
 
537
  {
 
538
    a_length= uint2korr(a_ptr);
 
539
    b_length= uint2korr(b_ptr);
 
540
  }
 
541
  set_if_smaller(a_length, max_length);
 
542
  set_if_smaller(b_length, max_length);
 
543
  if (a_length != b_length)
 
544
    return 1;
 
545
  return memcmp(a_ptr+length_bytes, b_ptr+length_bytes, a_length);
 
546
}
 
547
 
 
548
 
 
549
Field *Field_varstring::new_field(MEM_ROOT *root, struct st_table *new_table,
 
550
                                  bool keep_type)
 
551
{
 
552
  Field_varstring *res= (Field_varstring*) Field::new_field(root, new_table,
 
553
                                                            keep_type);
 
554
  if (res)
 
555
    res->length_bytes= length_bytes;
 
556
  return res;
 
557
}
 
558
 
 
559
 
 
560
Field *Field_varstring::new_key_field(MEM_ROOT *root,
 
561
                                      struct st_table *new_table,
 
562
                                      uchar *new_ptr, uchar *new_null_ptr,
 
563
                                      uint new_null_bit)
 
564
{
 
565
  Field_varstring *res;
 
566
  if ((res= (Field_varstring*) Field::new_key_field(root,
 
567
                                                    new_table,
 
568
                                                    new_ptr,
 
569
                                                    new_null_ptr,
 
570
                                                    new_null_bit)))
 
571
  {
 
572
    /* Keys length prefixes are always packed with 2 bytes */
 
573
    res->length_bytes= 2;
 
574
  }
 
575
  return res;
 
576
}
 
577
 
 
578
 
 
579
uint Field_varstring::is_equal(Create_field *new_field)
 
580
{
 
581
  if (new_field->sql_type == real_type() &&
 
582
      new_field->charset == field_charset)
 
583
  {
 
584
    if (new_field->length == max_display_length())
 
585
      return IS_EQUAL_YES;
 
586
    if (new_field->length > max_display_length() &&
 
587
        ((new_field->length <= 255 && max_display_length() <= 255) ||
 
588
         (new_field->length > 255 && max_display_length() > 255)))
 
589
      return IS_EQUAL_PACK_LENGTH; // VARCHAR, longer variable length
 
590
  }
 
591
  return IS_EQUAL_NO;
 
592
}
 
593
 
 
594
 
 
595
void Field_varstring::hash(ulong *nr, ulong *nr2)
 
596
{
 
597
  if (is_null())
 
598
  {
 
599
    *nr^= (*nr << 1) | 1;
 
600
  }
 
601
  else
 
602
  {
 
603
    uint len=  length_bytes == 1 ? (uint) *ptr : uint2korr(ptr);
 
604
    CHARSET_INFO *cs= charset();
 
605
    cs->coll->hash_sort(cs, ptr + length_bytes, len, nr, nr2);
 
606
  }
 
607
}
 
608
 
 
609