~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to drizzled/field/blob.cc

  • Committer: Monty Taylor
  • Date: 2009-04-14 19:16:51 UTC
  • mto: (997.2.5 mordred)
  • mto: This revision was merged to the branch mainline in revision 994.
  • Revision ID: mordred@inaugust.com-20090414191651-ltbww6hpqks8k7qk
Clarified instructions in README.

Show diffs side-by-side

added added

removed removed

Lines of Context:
19
19
 */
20
20
 
21
21
 
22
 
#include "config.h"
 
22
#include <drizzled/server_includes.h>
23
23
#include <drizzled/field/blob.h>
24
24
#include <drizzled/table.h>
25
25
#include <drizzled/session.h>
26
 
#include "plugin/myisam/myisam.h"
27
26
 
28
27
#include <string>
29
 
#include <algorithm>
30
28
 
31
29
using namespace std;
32
30
 
33
 
namespace drizzled
34
 
{
35
 
 
36
 
static uint32_t blob_pack_length_to_max_length(uint32_t arg)
37
 
{
38
 
  return max(UINT32_MAX,
39
 
             (uint32_t)((INT64_C(1) << min(arg, 4U) * 8) - INT64_C(1)));
 
31
uint32_t
 
32
blob_pack_length_to_max_length(uint32_t arg)
 
33
{
 
34
  return (uint32_t)cmax(UINT32_MAX,
 
35
                        (INT64_C(1) << cmin(arg, 4U) * 8) - INT64_C(1));
40
36
}
41
37
 
42
38
 
46
42
** packlength slot and may be from 1-4.
47
43
****************************************************************************/
48
44
 
49
 
Field_blob::Field_blob(unsigned char *ptr_arg,
50
 
                       unsigned char *null_ptr_arg,
51
 
                       unsigned char null_bit_arg,
52
 
                                   const char *field_name_arg,
53
 
                       TableShare *share,
54
 
                       uint32_t blob_pack_length,
55
 
                       const CHARSET_INFO * const cs)
56
 
  :Field_str(ptr_arg,
57
 
             blob_pack_length_to_max_length(blob_pack_length),
58
 
             null_ptr_arg,
59
 
             null_bit_arg,
60
 
             field_name_arg,
61
 
             cs),
 
45
Field_blob::Field_blob(unsigned char *ptr_arg, unsigned char *null_ptr_arg, unsigned char null_bit_arg,
 
46
                       enum utype unireg_check_arg, const char *field_name_arg,
 
47
                       TABLE_SHARE *share, uint32_t blob_pack_length,
 
48
                       const CHARSET_INFO * const cs)
 
49
  :Field_longstr(ptr_arg, blob_pack_length_to_max_length(blob_pack_length),
 
50
                 null_ptr_arg, null_bit_arg, unireg_check_arg, field_name_arg,
 
51
                 cs),
62
52
   packlength(blob_pack_length)
63
53
{
64
54
  flags|= BLOB_FLAG;
66
56
  /* TODO: why do not fill table->s->blob_field array here? */
67
57
}
68
58
 
 
59
 
69
60
void Field_blob::store_length(unsigned char *i_ptr,
70
61
                              uint32_t i_packlength,
71
62
                              uint32_t i_number,
209
200
  char buff[STRING_BUFFER_USUAL_SIZE];
210
201
  String tmpstr(buff,sizeof(buff), &my_charset_bin);
211
202
 
212
 
  ASSERT_COLUMN_MARKED_FOR_WRITE;
213
 
 
214
203
  if (!length)
215
204
  {
216
205
    memset(ptr, 0, Field_blob::pack_length());
231
220
    from= tmpstr.ptr();
232
221
  }
233
222
 
234
 
  new_length= min(max_data_length(), field_charset->mbmaxlen * length);
 
223
  new_length= cmin(max_data_length(), field_charset->mbmaxlen * length);
235
224
  if (value.alloc(new_length))
236
225
    goto oom_error;
237
226
 
 
227
 
 
228
  if (f_is_hex_escape(flags))
 
229
  {
 
230
    copy_length= my_copy_with_hex_escaping(field_charset,
 
231
                                           (char*) value.ptr(), new_length,
 
232
                                            from, length);
 
233
    Field_blob::store_length(copy_length);
 
234
    tmp= value.ptr();
 
235
    memmove(ptr + packlength, &tmp, sizeof(char*));
 
236
    return 0;
 
237
  }
238
238
  /*
239
239
    "length" is OK as "nchars" argument to well_formed_copy_nchars as this
240
240
    is never used to limit the length of the data. The cut of long data
268
268
int Field_blob::store(double nr)
269
269
{
270
270
  const CHARSET_INFO * const cs=charset();
271
 
  ASSERT_COLUMN_MARKED_FOR_WRITE;
272
271
  value.set_real(nr, NOT_FIXED_DEC, cs);
273
272
  return Field_blob::store(value.ptr(),(uint32_t) value.length(), cs);
274
273
}
277
276
int Field_blob::store(int64_t nr, bool unsigned_val)
278
277
{
279
278
  const CHARSET_INFO * const cs=charset();
280
 
  ASSERT_COLUMN_MARKED_FOR_WRITE;
281
279
  value.set_int(nr, unsigned_val, cs);
282
280
  return Field_blob::store(value.ptr(), (uint32_t) value.length(), cs);
283
281
}
290
288
  uint32_t length;
291
289
  const CHARSET_INFO *cs;
292
290
 
293
 
  ASSERT_COLUMN_MARKED_FOR_READ;
294
 
 
295
291
  memcpy(&blob,ptr+packlength,sizeof(char*));
296
292
  if (!blob)
297
293
    return 0.0;
305
301
{
306
302
  int not_used;
307
303
  char *blob;
308
 
 
309
 
  ASSERT_COLUMN_MARKED_FOR_READ;
310
 
 
311
304
  memcpy(&blob,ptr+packlength,sizeof(char*));
312
305
  if (!blob)
313
306
    return 0;
319
312
                            String *val_ptr)
320
313
{
321
314
  char *blob;
322
 
 
323
 
  ASSERT_COLUMN_MARKED_FOR_READ;
324
 
 
325
315
  memcpy(&blob,ptr+packlength,sizeof(char*));
326
316
  if (!blob)
327
317
    val_ptr->set("",0,charset());       // A bit safer than ->length(0)
335
325
{
336
326
  const char *blob;
337
327
  size_t length;
338
 
 
339
 
  ASSERT_COLUMN_MARKED_FOR_READ;
340
 
 
341
328
  memcpy(&blob, ptr+packlength, sizeof(const unsigned char*));
342
329
  if (!blob)
343
330
  {
376
363
 
377
364
 
378
365
int Field_blob::cmp_binary(const unsigned char *a_ptr, const unsigned char *b_ptr,
379
 
                           uint32_t max_length)
 
366
                           uint32_t max_length)
380
367
{
381
368
  char *a,*b;
382
369
  uint32_t diff;
383
370
  uint32_t a_length,b_length;
384
371
  memcpy(&a,a_ptr+packlength,sizeof(char*));
385
372
  memcpy(&b,b_ptr+packlength,sizeof(char*));
386
 
 
387
 
  a_length= get_length(a_ptr);
388
 
 
 
373
  a_length=get_length(a_ptr);
389
374
  if (a_length > max_length)
390
 
    a_length= max_length;
391
 
 
392
 
  b_length= get_length(b_ptr);
393
 
 
 
375
    a_length=max_length;
 
376
  b_length=get_length(b_ptr);
394
377
  if (b_length > max_length)
395
 
    b_length= max_length;
396
 
 
397
 
  diff= memcmp(a,b,min(a_length,b_length));
398
 
 
 
378
    b_length=max_length;
 
379
  diff=memcmp(a,b,cmin(a_length,b_length));
399
380
  return diff ? diff : (int) (a_length - b_length);
400
381
}
401
382
 
 
383
 
402
384
/* The following is used only when comparing a key */
403
 
uint32_t Field_blob::get_key_image(unsigned char *buff, uint32_t length)
 
385
 
 
386
uint32_t Field_blob::get_key_image(unsigned char *buff,
 
387
                                   uint32_t length,
 
388
                                   imagetype)
404
389
{
405
390
  uint32_t blob_length= get_length(ptr);
406
391
  unsigned char *blob;
414
399
  if ((uint32_t) length > blob_length)
415
400
  {
416
401
    /*
417
 
      Must clear this as we do a memcmp in optimizer/range.cc to detect
 
402
      Must clear this as we do a memcmp in opt_range.cc to detect
418
403
      identical keys
419
404
    */
420
405
    memset(buff+HA_KEY_BLOB_LENGTH+blob_length, 0, (length-blob_length));
426
411
}
427
412
 
428
413
 
429
 
uint32_t Field_blob::get_key_image(basic_string<unsigned char> &buff, uint32_t length)
 
414
uint32_t Field_blob::get_key_image(basic_string<unsigned char> &buff,
 
415
                                   uint32_t length,
 
416
                                   imagetype)
430
417
{
431
418
  uint32_t blob_length= get_length(ptr);
432
419
  unsigned char *blob;
445
432
  if (length > blob_length)
446
433
  {
447
434
    /*
448
 
      Must clear this as we do a memcmp in optimizer/range.cc to detect
 
435
      Must clear this as we do a memcmp in opt_range.cc to detect
449
436
      identical keys
450
437
    */
451
438
 
454
441
  return HA_KEY_BLOB_LENGTH+length;
455
442
}
456
443
 
 
444
 
457
445
void Field_blob::set_key_image(const unsigned char *buff,uint32_t length)
458
446
{
459
447
  length= uint2korr(buff);
460
 
  (void) Field_blob::store((const char*) buff+HA_KEY_BLOB_LENGTH, length, field_charset);
 
448
  (void) Field_blob::store((const char*) buff+HA_KEY_BLOB_LENGTH, length,
 
449
                           field_charset);
461
450
}
462
451
 
 
452
 
463
453
int Field_blob::key_cmp(const unsigned char *key_ptr, uint32_t max_key_length)
464
454
{
465
455
  unsigned char *blob1;
481
471
                         b+HA_KEY_BLOB_LENGTH, uint2korr(b));
482
472
}
483
473
 
 
474
 
 
475
/**
 
476
   Save the field metadata for blob fields.
 
477
 
 
478
   Saves the pack length in the first byte of the field metadata array
 
479
   at index of *metadata_ptr.
 
480
 
 
481
   @param   metadata_ptr   First byte of field metadata
 
482
 
 
483
   @returns number of bytes written to metadata_ptr
 
484
*/
 
485
int Field_blob::do_save_field_metadata(unsigned char *metadata_ptr)
 
486
{
 
487
  *metadata_ptr= pack_length_no_ptr();
 
488
  return 1;
 
489
}
 
490
 
 
491
 
484
492
uint32_t Field_blob::sort_length() const
485
493
{
486
494
  return (uint32_t) (current_session->variables.max_sort_length +
487
495
                   (field_charset == &my_charset_bin ? 0 : packlength));
488
496
}
489
497
 
 
498
 
490
499
void Field_blob::sort_string(unsigned char *to,uint32_t length)
491
500
{
492
501
  unsigned char *blob;
529
538
  }
530
539
}
531
540
 
 
541
 
532
542
uint32_t Field_blob::pack_length() const
533
543
{
534
544
  return (uint32_t) (packlength+table->s->blob_ptr_size);
535
545
}
536
546
 
 
547
 
537
548
void Field_blob::sql_type(String &res) const
538
549
{
539
550
  if (charset() == &my_charset_bin)
543
554
}
544
555
 
545
556
unsigned char *Field_blob::pack(unsigned char *to, const unsigned char *from,
546
 
                                uint32_t max_length, bool low_byte_first)
 
557
                        uint32_t max_length, bool low_byte_first)
547
558
{
548
559
  unsigned char *save= ptr;
549
560
  ptr= (unsigned char*) from;
550
 
  uint32_t length= get_length();                        // Length of from string
 
561
  uint32_t length=get_length();                 // Length of from string
551
562
 
552
563
  /*
553
564
    Store max length, which will occupy packlength bytes. If the max
554
565
    length given is smaller than the actual length of the blob, we
555
566
    just store the initial bytes of the blob.
556
567
  */
557
 
  store_length(to, packlength, min(length, max_length), low_byte_first);
 
568
  store_length(to, packlength, cmin(length, max_length), low_byte_first);
558
569
 
559
570
  /*
560
571
    Store the actual blob data, which will occupy 'length' bytes.
564
575
    get_ptr((unsigned char**) &from);
565
576
    memcpy(to+packlength, from,length);
566
577
  }
567
 
 
568
 
  ptr= save;                                    // Restore org row pointer
 
578
  ptr=save;                                     // Restore org row pointer
569
579
  return(to+packlength+length);
570
580
}
571
581
 
 
582
 
572
583
/**
573
584
   Unpack a blob field from row data.
574
585
 
587
598
   @return  New pointer into memory based on from + length of the data
588
599
*/
589
600
const unsigned char *Field_blob::unpack(unsigned char *,
590
 
                                        const unsigned char *from,
591
 
                                        uint32_t param_data,
592
 
                                        bool low_byte_first)
 
601
                                const unsigned char *from,
 
602
                                uint32_t param_data,
 
603
                                bool low_byte_first)
593
604
{
594
605
  uint32_t const master_packlength=
595
606
    param_data > 0 ? param_data & 0xFF : packlength;
596
607
  uint32_t const length= get_length(from, master_packlength, low_byte_first);
597
 
  table->setWriteSet(field_index);
 
608
  table->write_set->set(field_index);
598
609
  store(reinterpret_cast<const char*>(from) + master_packlength,
599
610
        length, field_charset);
600
611
  return(from + master_packlength + length);
626
637
}
627
638
 
628
639
 
 
640
uint32_t Field_blob::is_equal(Create_field *new_field_ptr)
 
641
{
 
642
  if (compare_str_field_flags(new_field_ptr, flags))
 
643
    return 0;
 
644
  Field_blob *blob_field_ptr= static_cast<Field_blob *>(new_field_ptr->field);
 
645
 
 
646
  return ((new_field_ptr->sql_type == 
 
647
             get_blob_type_from_length(max_data_length()))
 
648
          && new_field_ptr->charset == field_charset
 
649
          && blob_field_ptr->max_data_length() == max_data_length());
 
650
}
 
651
 
 
652
 
629
653
/**
630
654
  maximum possible display length for blob.
631
655
 
651
675
  }
652
676
}
653
677
 
654
 
} /* namespace drizzled */
 
678
bool Field_blob::in_read_set()
 
679
{
 
680
  return (table->read_set->test(field_index));
 
681
}
 
682
 
 
683
 
 
684
bool Field_blob::in_write_set()
 
685
{
 
686
  return (table->write_set->test(field_index));
 
687
}