~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to drizzled/field/blob.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/blob.h>
24
 
#include <drizzled/table.h>
25
 
#include <drizzled/session.h>
26
 
 
27
 
 
28
 
uint32_t
29
 
blob_pack_length_to_max_length(uint32_t arg)
30
 
{
31
 
  return (INT64_C(1) << cmin(arg, 4U) * 8) - INT64_C(1);
32
 
}
33
 
 
 
26
 
 
27
#define BLOB_PACK_LENGTH_TO_MAX_LENGH(arg) \
 
28
((ulong) ((1LL << min(arg, 4) * 8) - 1LL))
34
29
 
35
30
/****************************************************************************
36
31
** blob type
38
33
** packlength slot and may be from 1-4.
39
34
****************************************************************************/
40
35
 
41
 
Field_blob::Field_blob(unsigned char *ptr_arg, unsigned char *null_ptr_arg, unsigned char null_bit_arg,
 
36
Field_blob::Field_blob(uchar *ptr_arg, uchar *null_ptr_arg, uchar null_bit_arg,
42
37
                       enum utype unireg_check_arg, const char *field_name_arg,
43
 
                       TABLE_SHARE *share, uint32_t blob_pack_length,
44
 
                       const CHARSET_INFO * const cs)
45
 
  :Field_longstr(ptr_arg, blob_pack_length_to_max_length(blob_pack_length),
 
38
                       TABLE_SHARE *share, uint blob_pack_length,
 
39
                       CHARSET_INFO *cs)
 
40
  :Field_longstr(ptr_arg, BLOB_PACK_LENGTH_TO_MAX_LENGH(blob_pack_length),
46
41
                 null_ptr_arg, null_bit_arg, unireg_check_arg, field_name_arg,
47
42
                 cs),
48
43
   packlength(blob_pack_length)
53
48
}
54
49
 
55
50
 
56
 
void Field_blob::store_length(unsigned char *i_ptr,
57
 
                              uint32_t i_packlength,
 
51
void Field_blob::store_length(uchar *i_ptr,
 
52
                              uint i_packlength,
58
53
                              uint32_t i_number,
59
54
                              bool low_byte_first __attribute__((unused)))
60
55
{
61
56
  switch (i_packlength) {
62
57
  case 1:
63
 
    i_ptr[0]= (unsigned char) i_number;
 
58
    i_ptr[0]= (uchar) i_number;
64
59
    break;
65
60
  case 2:
66
61
#ifdef WORDS_BIGENDIAN
88
83
}
89
84
 
90
85
 
91
 
void Field_blob::store_length(unsigned char *i_ptr, uint32_t i_packlength,
92
 
                  uint32_t i_number)
93
 
{
94
 
  store_length(i_ptr, i_packlength, i_number, table->s->db_low_byte_first);
95
 
}
96
 
 
97
 
 
98
 
uint32_t Field_blob::get_length(const unsigned char *pos,
99
 
                              uint32_t packlength_arg,
 
86
uint32_t Field_blob::get_length(const uchar *pos,
 
87
                              uint packlength_arg,
100
88
                              bool low_byte_first __attribute__((unused)))
101
89
{
102
90
  switch (packlength_arg) {
131
119
}
132
120
 
133
121
 
134
 
uint32_t Field_blob::get_packed_size(const unsigned char *ptr_arg,
135
 
                                bool low_byte_first)
136
 
{
137
 
  return packlength + get_length(ptr_arg, packlength, low_byte_first);
138
 
}
139
 
 
140
 
 
141
 
uint32_t Field_blob::get_length(uint32_t row_offset)
142
 
{
143
 
  return get_length(ptr+row_offset, this->packlength,
144
 
                    table->s->db_low_byte_first);
145
 
}
146
 
 
147
 
 
148
 
uint32_t Field_blob::get_length(const unsigned char *ptr_arg)
149
 
{
150
 
  return get_length(ptr_arg, this->packlength, table->s->db_low_byte_first);
151
 
}
152
 
 
153
 
 
154
122
/**
155
123
  Put a blob length field into a record buffer.
156
124
 
162
130
  @param length              The length value to put.
163
131
*/
164
132
 
165
 
void Field_blob::put_length(unsigned char *pos, uint32_t length)
 
133
void Field_blob::put_length(uchar *pos, uint32_t length)
166
134
{
167
135
  switch (packlength) {
168
136
  case 1:
181
149
}
182
150
 
183
151
 
184
 
int Field_blob::store(const char *from,uint32_t length, const CHARSET_INFO * const cs)
 
152
int Field_blob::store(const char *from,uint length,CHARSET_INFO *cs)
185
153
{
186
 
  uint32_t copy_length, new_length;
 
154
  uint copy_length, new_length;
187
155
  const char *well_formed_error_pos;
188
156
  const char *cannot_convert_error_pos;
189
157
  const char *from_end_pos, *tmp;
202
170
    if (!String::needs_conversion(length, cs, field_charset, &dummy_offset))
203
171
    {
204
172
      Field_blob::store_length(length);
205
 
      memcpy(ptr+packlength, &from, sizeof(char*));
 
173
      memcpy(ptr+packlength, (char*) &from, sizeof(char*));
206
174
      return 0;
207
175
    }
208
176
    if (tmpstr.copy(from, length, cs))
210
178
    from= tmpstr.ptr();
211
179
  }
212
180
 
213
 
  new_length= cmin(max_data_length(), field_charset->mbmaxlen * length);
 
181
  new_length= min(max_data_length(), field_charset->mbmaxlen * length);
214
182
  if (value.alloc(new_length))
215
183
    goto oom_error;
216
184
 
222
190
                                            from, length);
223
191
    Field_blob::store_length(copy_length);
224
192
    tmp= value.ptr();
225
 
    memcpy(ptr + packlength, &tmp, sizeof(char*));
 
193
    memcpy(ptr + packlength, (uchar*) &tmp, sizeof(char*));
226
194
    return 0;
227
195
  }
228
196
  /*
240
208
 
241
209
  Field_blob::store_length(copy_length);
242
210
  tmp= value.ptr();
243
 
  memcpy(ptr+packlength, &tmp, sizeof(char*));
 
211
  memcpy(ptr+packlength, (uchar*) &tmp, sizeof(char*));
244
212
 
245
213
  if (check_string_copy_error(this, well_formed_error_pos,
246
214
                              cannot_convert_error_pos, from + length, cs))
257
225
 
258
226
int Field_blob::store(double nr)
259
227
{
260
 
  const CHARSET_INFO * const cs=charset();
 
228
  CHARSET_INFO *cs=charset();
261
229
  value.set_real(nr, NOT_FIXED_DEC, cs);
262
230
  return Field_blob::store(value.ptr(),(uint) value.length(), cs);
263
231
}
265
233
 
266
234
int Field_blob::store(int64_t nr, bool unsigned_val)
267
235
{
268
 
  const CHARSET_INFO * const cs=charset();
 
236
  CHARSET_INFO *cs=charset();
269
237
  value.set_int(nr, unsigned_val, cs);
270
238
  return Field_blob::store(value.ptr(), (uint) value.length(), cs);
271
239
}
276
244
  int not_used;
277
245
  char *end_not_used, *blob;
278
246
  uint32_t length;
279
 
  const CHARSET_INFO *cs;
 
247
  CHARSET_INFO *cs;
280
248
 
281
249
  memcpy(&blob,ptr+packlength,sizeof(char*));
282
250
  if (!blob)
315
283
{
316
284
  const char *blob;
317
285
  size_t length;
318
 
  memcpy(&blob, ptr+packlength, sizeof(const unsigned char*));
 
286
  memcpy(&blob, ptr+packlength, sizeof(const uchar*));
319
287
  if (!blob)
320
288
  {
321
289
    blob= "";
330
298
}
331
299
 
332
300
 
333
 
int Field_blob::cmp(const unsigned char *a,uint32_t a_length, const unsigned char *b,
 
301
int Field_blob::cmp(const uchar *a,uint32_t a_length, const uchar *b,
334
302
                    uint32_t b_length)
335
303
{
336
304
  return field_charset->coll->strnncollsp(field_charset, 
339
307
}
340
308
 
341
309
 
342
 
int Field_blob::cmp_max(const unsigned char *a_ptr, const unsigned char *b_ptr,
343
 
                        uint32_t max_length)
 
310
int Field_blob::cmp_max(const uchar *a_ptr, const uchar *b_ptr,
 
311
                        uint max_length)
344
312
{
345
 
  unsigned char *blob1,*blob2;
 
313
  uchar *blob1,*blob2;
346
314
  memcpy(&blob1,a_ptr+packlength,sizeof(char*));
347
315
  memcpy(&blob2,b_ptr+packlength,sizeof(char*));
348
 
  uint32_t a_len= get_length(a_ptr), b_len= get_length(b_ptr);
 
316
  uint a_len= get_length(a_ptr), b_len= get_length(b_ptr);
349
317
  set_if_smaller(a_len, max_length);
350
318
  set_if_smaller(b_len, max_length);
351
319
  return Field_blob::cmp(blob1,a_len,blob2,b_len);
352
320
}
353
321
 
354
322
 
355
 
int Field_blob::cmp_binary(const unsigned char *a_ptr, const unsigned char *b_ptr,
 
323
int Field_blob::cmp_binary(const uchar *a_ptr, const uchar *b_ptr,
356
324
                           uint32_t max_length)
357
325
{
358
326
  char *a,*b;
359
 
  uint32_t diff;
 
327
  uint diff;
360
328
  uint32_t a_length,b_length;
361
329
  memcpy(&a,a_ptr+packlength,sizeof(char*));
362
330
  memcpy(&b,b_ptr+packlength,sizeof(char*));
366
334
  b_length=get_length(b_ptr);
367
335
  if (b_length > max_length)
368
336
    b_length=max_length;
369
 
  diff=memcmp(a,b,cmin(a_length,b_length));
 
337
  diff=memcmp(a,b,min(a_length,b_length));
370
338
  return diff ? diff : (int) (a_length - b_length);
371
339
}
372
340
 
373
341
 
374
342
/* The following is used only when comparing a key */
375
343
 
376
 
uint32_t Field_blob::get_key_image(unsigned char *buff,
377
 
                               uint32_t length,
 
344
uint Field_blob::get_key_image(uchar *buff,
 
345
                               uint length,
378
346
                               imagetype type_arg __attribute__((unused)))
379
347
{
380
348
  uint32_t blob_length= get_length(ptr);
381
 
  unsigned char *blob;
 
349
  uchar *blob;
382
350
 
383
351
  get_ptr(&blob);
384
 
  uint32_t local_char_length= length / field_charset->mbmaxlen;
 
352
  uint local_char_length= length / field_charset->mbmaxlen;
385
353
  local_char_length= my_charpos(field_charset, blob, blob + blob_length,
386
354
                          local_char_length);
387
355
  set_if_smaller(blob_length, local_char_length);
401
369
}
402
370
 
403
371
 
404
 
void Field_blob::set_key_image(const unsigned char *buff,uint32_t length)
 
372
void Field_blob::set_key_image(const uchar *buff,uint length)
405
373
{
406
374
  length= uint2korr(buff);
407
375
  (void) Field_blob::store((const char*) buff+HA_KEY_BLOB_LENGTH, length,
409
377
}
410
378
 
411
379
 
412
 
int Field_blob::key_cmp(const unsigned char *key_ptr, uint32_t max_key_length)
 
380
int Field_blob::key_cmp(const uchar *key_ptr, uint max_key_length)
413
381
{
414
 
  unsigned char *blob1;
415
 
  uint32_t blob_length=get_length(ptr);
 
382
  uchar *blob1;
 
383
  uint blob_length=get_length(ptr);
416
384
  memcpy(&blob1,ptr+packlength,sizeof(char*));
417
 
  const CHARSET_INFO * const cs= charset();
418
 
  uint32_t local_char_length= max_key_length / cs->mbmaxlen;
 
385
  CHARSET_INFO *cs= charset();
 
386
  uint local_char_length= max_key_length / cs->mbmaxlen;
419
387
  local_char_length= my_charpos(cs, blob1, blob1+blob_length,
420
388
                                local_char_length);
421
389
  set_if_smaller(blob_length, local_char_length);
424
392
                         uint2korr(key_ptr));
425
393
}
426
394
 
427
 
int Field_blob::key_cmp(const unsigned char *a,const unsigned char *b)
 
395
int Field_blob::key_cmp(const uchar *a,const uchar *b)
428
396
{
429
397
  return Field_blob::cmp(a+HA_KEY_BLOB_LENGTH, uint2korr(a),
430
398
                         b+HA_KEY_BLOB_LENGTH, uint2korr(b));
441
409
 
442
410
   @returns number of bytes written to metadata_ptr
443
411
*/
444
 
int Field_blob::do_save_field_metadata(unsigned char *metadata_ptr)
 
412
int Field_blob::do_save_field_metadata(uchar *metadata_ptr)
445
413
{
446
414
  *metadata_ptr= pack_length_no_ptr();
447
415
  return 1;
450
418
 
451
419
uint32_t Field_blob::sort_length() const
452
420
{
453
 
  return (uint32_t) (current_session->variables.max_sort_length +
 
421
  return (uint32_t) (current_thd->variables.max_sort_length + 
454
422
                   (field_charset == &my_charset_bin ? 0 : packlength));
455
423
}
456
424
 
457
425
 
458
 
void Field_blob::sort_string(unsigned char *to,uint32_t length)
 
426
void Field_blob::sort_string(uchar *to,uint length)
459
427
{
460
 
  unsigned char *blob;
461
 
  uint32_t blob_length=get_length();
 
428
  uchar *blob;
 
429
  uint blob_length=get_length();
462
430
 
463
431
  if (!blob_length)
464
432
    memset(to, 0, length);
466
434
  {
467
435
    if (field_charset == &my_charset_bin)
468
436
    {
469
 
      unsigned char *pos;
 
437
      uchar *pos;
470
438
 
471
439
      /*
472
440
        Store length of blob last in blob to shorter blobs before longer blobs
490
458
      }
491
459
    }
492
460
    memcpy(&blob,ptr+packlength,sizeof(char*));
493
 
 
 
461
    
494
462
    blob_length=my_strnxfrm(field_charset,
495
463
                            to, length, blob, blob_length);
496
464
    assert(blob_length == length);
498
466
}
499
467
 
500
468
 
501
 
uint32_t Field_blob::pack_length() const
502
 
{
503
 
  return (uint32_t) (packlength+table->s->blob_ptr_size);
504
 
}
505
 
 
506
 
 
507
469
void Field_blob::sql_type(String &res) const
508
470
{
509
471
  if (charset() == &my_charset_bin)
512
474
    res.set_ascii(STRING_WITH_LEN("text"));
513
475
}
514
476
 
515
 
unsigned char *Field_blob::pack(unsigned char *to, const unsigned char *from,
516
 
                        uint32_t max_length, bool low_byte_first)
 
477
uchar *Field_blob::pack(uchar *to, const uchar *from,
 
478
                        uint max_length, bool low_byte_first)
517
479
{
518
 
  unsigned char *save= ptr;
519
 
  ptr= (unsigned char*) from;
 
480
  uchar *save= ptr;
 
481
  ptr= (uchar*) from;
520
482
  uint32_t length=get_length();                 // Length of from string
521
483
 
522
484
  /*
524
486
    length given is smaller than the actual length of the blob, we
525
487
    just store the initial bytes of the blob.
526
488
  */
527
 
  store_length(to, packlength, cmin(length, max_length), low_byte_first);
 
489
  store_length(to, packlength, min(length, max_length), low_byte_first);
528
490
 
529
491
  /*
530
492
    Store the actual blob data, which will occupy 'length' bytes.
531
493
   */
532
494
  if (length > 0)
533
495
  {
534
 
    get_ptr((unsigned char**) &from);
 
496
    get_ptr((uchar**) &from);
535
497
    memcpy(to+packlength, from,length);
536
498
  }
537
499
  ptr=save;                                     // Restore org row pointer
556
518
 
557
519
   @return  New pointer into memory based on from + length of the data
558
520
*/
559
 
const unsigned char *Field_blob::unpack(unsigned char *to __attribute__((unused)),
560
 
                                const unsigned char *from,
561
 
                                uint32_t param_data,
 
521
const uchar *Field_blob::unpack(uchar *to __attribute__((unused)),
 
522
                                const uchar *from,
 
523
                                uint param_data,
562
524
                                bool low_byte_first)
563
525
{
564
 
  uint32_t const master_packlength=
 
526
  uint const master_packlength=
565
527
    param_data > 0 ? param_data & 0xFF : packlength;
566
528
  uint32_t const length= get_length(from, master_packlength, low_byte_first);
567
529
  bitmap_set_bit(table->write_set, field_index);
572
534
 
573
535
/* Keys for blobs are like keys on varchars */
574
536
 
575
 
int Field_blob::pack_cmp(const unsigned char *a, const unsigned char *b, uint32_t key_length_arg,
576
 
                         bool insert_or_update)
 
537
int Field_blob::pack_cmp(const uchar *a, const uchar *b, uint key_length_arg,
 
538
                         my_bool insert_or_update)
577
539
{
578
 
  uint32_t a_length, b_length;
 
540
  uint a_length, b_length;
579
541
  if (key_length_arg > 255)
580
542
  {
581
543
    a_length=uint2korr(a); a+=2;
593
555
}
594
556
 
595
557
 
596
 
int Field_blob::pack_cmp(const unsigned char *b, uint32_t key_length_arg,
597
 
                         bool insert_or_update)
 
558
int Field_blob::pack_cmp(const uchar *b, uint key_length_arg,
 
559
                         my_bool insert_or_update)
598
560
{
599
 
  unsigned char *a;
600
 
  uint32_t a_length, b_length;
 
561
  uchar *a;
 
562
  uint a_length, b_length;
601
563
  memcpy(&a,ptr+packlength,sizeof(char*));
602
564
  if (!a)
603
565
    return key_length_arg > 0 ? -1 : 0;
617
579
 
618
580
/** Create a packed key that will be used for storage from a MySQL row. */
619
581
 
620
 
unsigned char *
621
 
Field_blob::pack_key(unsigned char *to, const unsigned char *from, uint32_t max_length,
 
582
uchar *
 
583
Field_blob::pack_key(uchar *to, const uchar *from, uint max_length,
622
584
                     bool low_byte_first __attribute__((unused)))
623
585
{
624
 
  unsigned char *save= ptr;
625
 
  ptr= (unsigned char*) from;
 
586
  uchar *save= ptr;
 
587
  ptr= (uchar*) from;
626
588
  uint32_t length=get_length();        // Length of from string
627
 
  uint32_t local_char_length= ((field_charset->mbmaxlen > 1) ?
 
589
  uint local_char_length= ((field_charset->mbmaxlen > 1) ?
628
590
                           max_length/field_charset->mbmaxlen : max_length);
629
591
  if (length)
630
 
    get_ptr((unsigned char**) &from);
 
592
    get_ptr((uchar**) &from);
631
593
  if (length > local_char_length)
632
594
    local_char_length= my_charpos(field_charset, from, from+length,
633
595
                                  local_char_length);
634
596
  set_if_smaller(length, local_char_length);
635
 
  *to++= (unsigned char) length;
 
597
  *to++= (uchar) length;
636
598
  if (max_length > 255)                         // 2 byte length
637
 
    *to++= (unsigned char) (length >> 8);
 
599
    *to++= (uchar) (length >> 8);
638
600
  memcpy(to, from, length);
639
601
  ptr=save;                                     // Restore org row pointer
640
602
  return to+length;
662
624
    Pointer into 'from' past the last byte copied from packed key.
663
625
*/
664
626
 
665
 
const unsigned char *
666
 
Field_blob::unpack_key(unsigned char *to, const unsigned char *from, uint32_t max_length,
 
627
const uchar *
 
628
Field_blob::unpack_key(uchar *to, const uchar *from, uint max_length,
667
629
                       bool low_byte_first __attribute__((unused)))
668
630
{
669
631
  /* get length of the blob key */
687
649
 
688
650
/** Create a packed key that will be used for storage from a MySQL key. */
689
651
 
690
 
unsigned char *
691
 
Field_blob::pack_key_from_key_image(unsigned char *to, const unsigned char *from, uint32_t max_length,
 
652
uchar *
 
653
Field_blob::pack_key_from_key_image(uchar *to, const uchar *from, uint max_length,
692
654
                                    bool low_byte_first __attribute__((unused)))
693
655
{
694
 
  uint32_t length=uint2korr(from);
 
656
  uint length=uint2korr(from);
695
657
  if (length > max_length)
696
658
    length=max_length;
697
659
  *to++= (char) (length & 255);
703
665
}
704
666
 
705
667
 
706
 
uint32_t Field_blob::packed_col_length(const unsigned char *data_ptr, uint32_t length)
 
668
uint Field_blob::packed_col_length(const uchar *data_ptr, uint length)
707
669
{
708
670
  if (length > 255)
709
671
    return uint2korr(data_ptr)+2;
711
673
}
712
674
 
713
675
 
714
 
uint32_t Field_blob::max_packed_col_length(uint32_t max_length)
 
676
uint Field_blob::max_packed_col_length(uint max_length)
715
677
{
716
678
  return (max_length > 255 ? 2 : 1)+max_length;
717
679
}
718
680
 
719
681
 
720
 
uint32_t Field_blob::is_equal(Create_field *new_field)
 
682
uint Field_blob::is_equal(Create_field *new_field)
721
683
{
722
684
  if (compare_str_field_flags(new_field, flags))
723
685
    return 0;
754
716
  }
755
717
}
756
718
 
757
 
bool Field_blob::in_read_set()
758
 
{
759
 
  return bitmap_is_set(table->read_set, field_index);
760
 
}
761
 
 
762
 
 
763
 
bool Field_blob::in_write_set()
764
 
{
765
 
  return bitmap_is_set(table->write_set, field_index);
766
 
}