~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to drizzled/field/blob.cc

  • Committer: Brian Aker
  • Date: 2009-07-11 19:23:04 UTC
  • mfrom: (1089.1.14 merge)
  • Revision ID: brian@gaz-20090711192304-ootijyl5yf9jq9kd
Merge Brian

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/blob.h>
27
 
 
28
 
#define BLOB_PACK_LENGTH_TO_MAX_LENGH(arg) \
29
 
((uint32_t) ((1LL << min(arg, (uint)4) * 8) - 1LL))
 
24
#include <drizzled/table.h>
 
25
#include <drizzled/session.h>
 
26
 
 
27
#include <string>
 
28
#include <algorithm>
 
29
 
 
30
using namespace std;
 
31
 
 
32
static uint32_t blob_pack_length_to_max_length(uint32_t arg)
 
33
{
 
34
  return max(UINT32_MAX,
 
35
             (uint32_t)((INT64_C(1) << min(arg, 4U) * 8) - INT64_C(1)));
 
36
}
 
37
 
30
38
 
31
39
/****************************************************************************
32
40
** blob type
34
42
** packlength slot and may be from 1-4.
35
43
****************************************************************************/
36
44
 
37
 
Field_blob::Field_blob(uchar *ptr_arg, uchar *null_ptr_arg, uchar null_bit_arg,
 
45
Field_blob::Field_blob(unsigned char *ptr_arg, unsigned char *null_ptr_arg, unsigned char null_bit_arg,
38
46
                       enum utype unireg_check_arg, const char *field_name_arg,
39
 
                       TABLE_SHARE *share, uint blob_pack_length,
 
47
                       TableShare *share, uint32_t blob_pack_length,
40
48
                       const CHARSET_INFO * const cs)
41
 
  :Field_longstr(ptr_arg, BLOB_PACK_LENGTH_TO_MAX_LENGH(blob_pack_length),
 
49
  :Field_str(ptr_arg, blob_pack_length_to_max_length(blob_pack_length),
42
50
                 null_ptr_arg, null_bit_arg, unireg_check_arg, field_name_arg,
43
51
                 cs),
44
52
   packlength(blob_pack_length)
49
57
}
50
58
 
51
59
 
52
 
void Field_blob::store_length(uchar *i_ptr,
53
 
                              uint i_packlength,
 
60
void Field_blob::store_length(unsigned char *i_ptr,
 
61
                              uint32_t i_packlength,
54
62
                              uint32_t i_number,
55
 
                              bool low_byte_first __attribute__((unused)))
 
63
                              bool low_byte_first)
56
64
{
 
65
#ifndef WORDS_BIGENDIAN
 
66
  (void)low_byte_first;
 
67
#endif
57
68
  switch (i_packlength) {
58
69
  case 1:
59
 
    i_ptr[0]= (uchar) i_number;
 
70
    i_ptr[0]= (unsigned char) i_number;
60
71
    break;
61
72
  case 2:
62
73
#ifdef WORDS_BIGENDIAN
84
95
}
85
96
 
86
97
 
87
 
uint32_t Field_blob::get_length(const uchar *pos,
88
 
                              uint packlength_arg,
89
 
                              bool low_byte_first __attribute__((unused)))
90
 
{
 
98
void Field_blob::store_length(unsigned char *i_ptr, uint32_t i_packlength,
 
99
                  uint32_t i_number)
 
100
{
 
101
  store_length(i_ptr, i_packlength, i_number, table->s->db_low_byte_first);
 
102
}
 
103
 
 
104
 
 
105
uint32_t Field_blob::get_length(const unsigned char *pos,
 
106
                                uint32_t packlength_arg,
 
107
                                bool low_byte_first)
 
108
{
 
109
#ifndef WORDS_BIGENDIAN
 
110
  (void)low_byte_first;
 
111
#endif
91
112
  switch (packlength_arg) {
92
113
  case 1:
93
114
    return (uint32_t) pos[0];
120
141
}
121
142
 
122
143
 
 
144
uint32_t Field_blob::get_packed_size(const unsigned char *ptr_arg,
 
145
                                bool low_byte_first)
 
146
{
 
147
  return packlength + get_length(ptr_arg, packlength, low_byte_first);
 
148
}
 
149
 
 
150
 
 
151
uint32_t Field_blob::get_length(uint32_t row_offset)
 
152
{
 
153
  return get_length(ptr+row_offset, this->packlength,
 
154
                    table->s->db_low_byte_first);
 
155
}
 
156
 
 
157
 
 
158
uint32_t Field_blob::get_length(const unsigned char *ptr_arg)
 
159
{
 
160
  return get_length(ptr_arg, this->packlength, table->s->db_low_byte_first);
 
161
}
 
162
 
 
163
 
123
164
/**
124
165
  Put a blob length field into a record buffer.
125
166
 
131
172
  @param length              The length value to put.
132
173
*/
133
174
 
134
 
void Field_blob::put_length(uchar *pos, uint32_t length)
 
175
void Field_blob::put_length(unsigned char *pos, uint32_t length)
135
176
{
136
177
  switch (packlength) {
137
178
  case 1:
150
191
}
151
192
 
152
193
 
153
 
int Field_blob::store(const char *from,uint length, const CHARSET_INFO * const cs)
 
194
int Field_blob::store(const char *from,uint32_t length, const CHARSET_INFO * const cs)
154
195
{
155
 
  uint copy_length, new_length;
 
196
  uint32_t copy_length, new_length;
156
197
  const char *well_formed_error_pos;
157
198
  const char *cannot_convert_error_pos;
158
199
  const char *from_end_pos, *tmp;
159
200
  char buff[STRING_BUFFER_USUAL_SIZE];
160
201
  String tmpstr(buff,sizeof(buff), &my_charset_bin);
161
202
 
 
203
  ASSERT_COLUMN_MARKED_FOR_WRITE;
 
204
 
162
205
  if (!length)
163
206
  {
164
207
    memset(ptr, 0, Field_blob::pack_length());
171
214
    if (!String::needs_conversion(length, cs, field_charset, &dummy_offset))
172
215
    {
173
216
      Field_blob::store_length(length);
174
 
      memcpy(ptr+packlength, &from, sizeof(char*));
 
217
      memmove(ptr+packlength, &from, sizeof(char*));
175
218
      return 0;
176
219
    }
177
220
    if (tmpstr.copy(from, length, cs))
191
234
                                            from, length);
192
235
    Field_blob::store_length(copy_length);
193
236
    tmp= value.ptr();
194
 
    memcpy(ptr + packlength, &tmp, sizeof(char*));
 
237
    memmove(ptr + packlength, &tmp, sizeof(char*));
195
238
    return 0;
196
239
  }
197
240
  /*
209
252
 
210
253
  Field_blob::store_length(copy_length);
211
254
  tmp= value.ptr();
212
 
  memcpy(ptr+packlength, &tmp, sizeof(char*));
 
255
  memmove(ptr+packlength, &tmp, sizeof(char*));
213
256
 
214
257
  if (check_string_copy_error(this, well_formed_error_pos,
215
258
                              cannot_convert_error_pos, from + length, cs))
220
263
oom_error:
221
264
  /* Fatal OOM error */
222
265
  memset(ptr, 0, Field_blob::pack_length());
223
 
  return -1; 
 
266
  return -1;
224
267
}
225
268
 
226
269
 
227
270
int Field_blob::store(double nr)
228
271
{
229
272
  const CHARSET_INFO * const cs=charset();
 
273
  ASSERT_COLUMN_MARKED_FOR_WRITE;
230
274
  value.set_real(nr, NOT_FIXED_DEC, cs);
231
 
  return Field_blob::store(value.ptr(),(uint) value.length(), cs);
 
275
  return Field_blob::store(value.ptr(),(uint32_t) value.length(), cs);
232
276
}
233
277
 
234
278
 
235
279
int Field_blob::store(int64_t nr, bool unsigned_val)
236
280
{
237
281
  const CHARSET_INFO * const cs=charset();
 
282
  ASSERT_COLUMN_MARKED_FOR_WRITE;
238
283
  value.set_int(nr, unsigned_val, cs);
239
 
  return Field_blob::store(value.ptr(), (uint) value.length(), cs);
 
284
  return Field_blob::store(value.ptr(), (uint32_t) value.length(), cs);
240
285
}
241
286
 
242
287
 
247
292
  uint32_t length;
248
293
  const CHARSET_INFO *cs;
249
294
 
 
295
  ASSERT_COLUMN_MARKED_FOR_READ;
 
296
 
250
297
  memcpy(&blob,ptr+packlength,sizeof(char*));
251
298
  if (!blob)
252
299
    return 0.0;
260
307
{
261
308
  int not_used;
262
309
  char *blob;
 
310
 
 
311
  ASSERT_COLUMN_MARKED_FOR_READ;
 
312
 
263
313
  memcpy(&blob,ptr+packlength,sizeof(char*));
264
314
  if (!blob)
265
315
    return 0;
267
317
  return my_strntoll(charset(),blob,length,10,NULL,&not_used);
268
318
}
269
319
 
270
 
String *Field_blob::val_str(String *val_buffer __attribute__((unused)),
 
320
String *Field_blob::val_str(String *,
271
321
                            String *val_ptr)
272
322
{
273
323
  char *blob;
 
324
 
 
325
  ASSERT_COLUMN_MARKED_FOR_READ;
 
326
 
274
327
  memcpy(&blob,ptr+packlength,sizeof(char*));
275
328
  if (!blob)
276
329
    val_ptr->set("",0,charset());       // A bit safer than ->length(0)
284
337
{
285
338
  const char *blob;
286
339
  size_t length;
287
 
  memcpy(&blob, ptr+packlength, sizeof(const uchar*));
 
340
 
 
341
  ASSERT_COLUMN_MARKED_FOR_READ;
 
342
 
 
343
  memcpy(&blob, ptr+packlength, sizeof(const unsigned char*));
288
344
  if (!blob)
289
345
  {
290
346
    blob= "";
299
355
}
300
356
 
301
357
 
302
 
int Field_blob::cmp(const uchar *a,uint32_t a_length, const uchar *b,
 
358
int Field_blob::cmp(const unsigned char *a,uint32_t a_length, const unsigned char *b,
303
359
                    uint32_t b_length)
304
360
{
305
 
  return field_charset->coll->strnncollsp(field_charset, 
 
361
  return field_charset->coll->strnncollsp(field_charset,
306
362
                                          a, a_length, b, b_length,
307
363
                                          0);
308
364
}
309
365
 
310
366
 
311
 
int Field_blob::cmp_max(const uchar *a_ptr, const uchar *b_ptr,
312
 
                        uint max_length)
 
367
int Field_blob::cmp_max(const unsigned char *a_ptr, const unsigned char *b_ptr,
 
368
                        uint32_t max_length)
313
369
{
314
 
  uchar *blob1,*blob2;
 
370
  unsigned char *blob1,*blob2;
315
371
  memcpy(&blob1,a_ptr+packlength,sizeof(char*));
316
372
  memcpy(&blob2,b_ptr+packlength,sizeof(char*));
317
 
  uint a_len= get_length(a_ptr), b_len= get_length(b_ptr);
 
373
  uint32_t a_len= get_length(a_ptr), b_len= get_length(b_ptr);
318
374
  set_if_smaller(a_len, max_length);
319
375
  set_if_smaller(b_len, max_length);
320
376
  return Field_blob::cmp(blob1,a_len,blob2,b_len);
321
377
}
322
378
 
323
379
 
324
 
int Field_blob::cmp_binary(const uchar *a_ptr, const uchar *b_ptr,
325
 
                           uint32_t max_length)
 
380
int Field_blob::cmp_binary(const unsigned char *a_ptr, const unsigned char *b_ptr,
 
381
                           uint32_t max_length)
326
382
{
327
383
  char *a,*b;
328
 
  uint diff;
 
384
  uint32_t diff;
329
385
  uint32_t a_length,b_length;
330
386
  memcpy(&a,a_ptr+packlength,sizeof(char*));
331
387
  memcpy(&b,b_ptr+packlength,sizeof(char*));
332
 
  a_length=get_length(a_ptr);
 
388
 
 
389
  a_length= get_length(a_ptr);
 
390
 
333
391
  if (a_length > max_length)
334
 
    a_length=max_length;
335
 
  b_length=get_length(b_ptr);
 
392
    a_length= max_length;
 
393
 
 
394
  b_length= get_length(b_ptr);
 
395
 
336
396
  if (b_length > max_length)
337
 
    b_length=max_length;
338
 
  diff=memcmp(a,b,min(a_length,b_length));
 
397
    b_length= max_length;
 
398
 
 
399
  diff= memcmp(a,b,min(a_length,b_length));
 
400
 
339
401
  return diff ? diff : (int) (a_length - b_length);
340
402
}
341
403
 
342
 
 
343
404
/* The following is used only when comparing a key */
344
 
 
345
 
uint Field_blob::get_key_image(uchar *buff,
346
 
                               uint length,
347
 
                               imagetype type_arg __attribute__((unused)))
 
405
uint32_t Field_blob::get_key_image(unsigned char *buff, uint32_t length)
348
406
{
349
407
  uint32_t blob_length= get_length(ptr);
350
 
  uchar *blob;
 
408
  unsigned char *blob;
351
409
 
352
410
  get_ptr(&blob);
353
 
  uint local_char_length= length / field_charset->mbmaxlen;
 
411
  uint32_t local_char_length= length / field_charset->mbmaxlen;
354
412
  local_char_length= my_charpos(field_charset, blob, blob + blob_length,
355
413
                          local_char_length);
356
414
  set_if_smaller(blob_length, local_char_length);
362
420
      identical keys
363
421
    */
364
422
    memset(buff+HA_KEY_BLOB_LENGTH+blob_length, 0, (length-blob_length));
365
 
    length=(uint) blob_length;
 
423
    length=(uint32_t) blob_length;
366
424
  }
367
425
  int2store(buff,length);
368
426
  memcpy(buff+HA_KEY_BLOB_LENGTH, blob, length);
370
428
}
371
429
 
372
430
 
373
 
void Field_blob::set_key_image(const uchar *buff,uint length)
 
431
uint32_t Field_blob::get_key_image(basic_string<unsigned char> &buff, uint32_t length)
 
432
{
 
433
  uint32_t blob_length= get_length(ptr);
 
434
  unsigned char *blob;
 
435
 
 
436
  get_ptr(&blob);
 
437
  uint32_t local_char_length= length / field_charset->mbmaxlen;
 
438
  local_char_length= my_charpos(field_charset, blob, blob + blob_length,
 
439
                                local_char_length);
 
440
  set_if_smaller(blob_length, local_char_length);
 
441
 
 
442
  unsigned char len_buff[HA_KEY_BLOB_LENGTH];
 
443
  int2store(len_buff,length);
 
444
  buff.append(len_buff);
 
445
  buff.append(blob, blob_length);
 
446
 
 
447
  if (length > blob_length)
 
448
  {
 
449
    /*
 
450
      Must clear this as we do a memcmp in opt_range.cc to detect
 
451
      identical keys
 
452
    */
 
453
 
 
454
    buff.append(length-blob_length, '0');
 
455
  }
 
456
  return HA_KEY_BLOB_LENGTH+length;
 
457
}
 
458
 
 
459
void Field_blob::set_key_image(const unsigned char *buff,uint32_t length)
374
460
{
375
461
  length= uint2korr(buff);
376
 
  (void) Field_blob::store((const char*) buff+HA_KEY_BLOB_LENGTH, length,
377
 
                           field_charset);
 
462
  (void) Field_blob::store((const char*) buff+HA_KEY_BLOB_LENGTH, length, field_charset);
378
463
}
379
464
 
380
 
 
381
 
int Field_blob::key_cmp(const uchar *key_ptr, uint max_key_length)
 
465
int Field_blob::key_cmp(const unsigned char *key_ptr, uint32_t max_key_length)
382
466
{
383
 
  uchar *blob1;
384
 
  uint blob_length=get_length(ptr);
 
467
  unsigned char *blob1;
 
468
  uint32_t blob_length=get_length(ptr);
385
469
  memcpy(&blob1,ptr+packlength,sizeof(char*));
386
470
  const CHARSET_INFO * const cs= charset();
387
 
  uint local_char_length= max_key_length / cs->mbmaxlen;
 
471
  uint32_t local_char_length= max_key_length / cs->mbmaxlen;
388
472
  local_char_length= my_charpos(cs, blob1, blob1+blob_length,
389
473
                                local_char_length);
390
474
  set_if_smaller(blob_length, local_char_length);
393
477
                         uint2korr(key_ptr));
394
478
}
395
479
 
396
 
int Field_blob::key_cmp(const uchar *a,const uchar *b)
 
480
int Field_blob::key_cmp(const unsigned char *a,const unsigned char *b)
397
481
{
398
482
  return Field_blob::cmp(a+HA_KEY_BLOB_LENGTH, uint2korr(a),
399
483
                         b+HA_KEY_BLOB_LENGTH, uint2korr(b));
400
484
}
401
485
 
402
 
 
403
486
/**
404
487
   Save the field metadata for blob fields.
405
488
 
410
493
 
411
494
   @returns number of bytes written to metadata_ptr
412
495
*/
413
 
int Field_blob::do_save_field_metadata(uchar *metadata_ptr)
 
496
int Field_blob::do_save_field_metadata(unsigned char *metadata_ptr)
414
497
{
415
498
  *metadata_ptr= pack_length_no_ptr();
416
499
  return 1;
417
500
}
418
501
 
419
 
 
420
502
uint32_t Field_blob::sort_length() const
421
503
{
422
 
  return (uint32_t) (current_thd->variables.max_sort_length + 
 
504
  return (uint32_t) (current_session->variables.max_sort_length +
423
505
                   (field_charset == &my_charset_bin ? 0 : packlength));
424
506
}
425
507
 
426
 
 
427
 
void Field_blob::sort_string(uchar *to,uint length)
 
508
void Field_blob::sort_string(unsigned char *to,uint32_t length)
428
509
{
429
 
  uchar *blob;
430
 
  uint blob_length=get_length();
 
510
  unsigned char *blob;
 
511
  uint32_t blob_length=get_length();
431
512
 
432
513
  if (!blob_length)
433
514
    memset(to, 0, length);
435
516
  {
436
517
    if (field_charset == &my_charset_bin)
437
518
    {
438
 
      uchar *pos;
 
519
      unsigned char *pos;
439
520
 
440
521
      /*
441
522
        Store length of blob last in blob to shorter blobs before longer blobs
459
540
      }
460
541
    }
461
542
    memcpy(&blob,ptr+packlength,sizeof(char*));
462
 
    
 
543
 
463
544
    blob_length=my_strnxfrm(field_charset,
464
545
                            to, length, blob, blob_length);
465
546
    assert(blob_length == length);
466
547
  }
467
548
}
468
549
 
 
550
uint32_t Field_blob::pack_length() const
 
551
{
 
552
  return (uint32_t) (packlength+table->s->blob_ptr_size);
 
553
}
469
554
 
470
555
void Field_blob::sql_type(String &res) const
471
556
{
475
560
    res.set_ascii(STRING_WITH_LEN("text"));
476
561
}
477
562
 
478
 
uchar *Field_blob::pack(uchar *to, const uchar *from,
479
 
                        uint max_length, bool low_byte_first)
 
563
unsigned char *Field_blob::pack(unsigned char *to, const unsigned char *from,
 
564
                                uint32_t max_length, bool low_byte_first)
480
565
{
481
 
  uchar *save= ptr;
482
 
  ptr= (uchar*) from;
483
 
  uint32_t length=get_length();                 // Length of from string
 
566
  unsigned char *save= ptr;
 
567
  ptr= (unsigned char*) from;
 
568
  uint32_t length= get_length();                        // Length of from string
484
569
 
485
570
  /*
486
571
    Store max length, which will occupy packlength bytes. If the max
494
579
   */
495
580
  if (length > 0)
496
581
  {
497
 
    get_ptr((uchar**) &from);
 
582
    get_ptr((unsigned char**) &from);
498
583
    memcpy(to+packlength, from,length);
499
584
  }
500
 
  ptr=save;                                     // Restore org row pointer
 
585
 
 
586
  ptr= save;                                    // Restore org row pointer
501
587
  return(to+packlength+length);
502
588
}
503
589
 
504
 
 
505
590
/**
506
591
   Unpack a blob field from row data.
507
592
 
508
 
   This method is used to unpack a blob field from a master whose size of 
 
593
   This method is used to unpack a blob field from a master whose size of
509
594
   the field is less than that of the slave. Note: This method is included
510
595
   to satisfy inheritance rules, but is not needed for blob fields. It
511
596
   simply is used as a pass-through to the original unpack() method for
519
604
 
520
605
   @return  New pointer into memory based on from + length of the data
521
606
*/
522
 
const uchar *Field_blob::unpack(uchar *to __attribute__((unused)),
523
 
                                const uchar *from,
524
 
                                uint param_data,
 
607
const unsigned char *Field_blob::unpack(unsigned char *,
 
608
                                const unsigned char *from,
 
609
                                uint32_t param_data,
525
610
                                bool low_byte_first)
526
611
{
527
 
  uint const master_packlength=
 
612
  uint32_t const master_packlength=
528
613
    param_data > 0 ? param_data & 0xFF : packlength;
529
614
  uint32_t const length= get_length(from, master_packlength, low_byte_first);
530
 
  bitmap_set_bit(table->write_set, field_index);
 
615
  table->setWriteSet(field_index);
531
616
  store(reinterpret_cast<const char*>(from) + master_packlength,
532
617
        length, field_charset);
533
618
  return(from + master_packlength + length);
534
619
}
535
620
 
536
 
/* Keys for blobs are like keys on varchars */
537
 
 
538
 
int Field_blob::pack_cmp(const uchar *a, const uchar *b, uint key_length_arg,
539
 
                         bool insert_or_update)
540
 
{
541
 
  uint a_length, b_length;
542
 
  if (key_length_arg > 255)
543
 
  {
544
 
    a_length=uint2korr(a); a+=2;
545
 
    b_length=uint2korr(b); b+=2;
546
 
  }
547
 
  else
548
 
  {
549
 
    a_length= (uint) *a++;
550
 
    b_length= (uint) *b++;
551
 
  }
552
 
  return field_charset->coll->strnncollsp(field_charset,
553
 
                                          a, a_length,
554
 
                                          b, b_length,
555
 
                                          insert_or_update);
556
 
}
557
 
 
558
 
 
559
 
int Field_blob::pack_cmp(const uchar *b, uint key_length_arg,
560
 
                         bool insert_or_update)
561
 
{
562
 
  uchar *a;
563
 
  uint a_length, b_length;
564
 
  memcpy(&a,ptr+packlength,sizeof(char*));
565
 
  if (!a)
566
 
    return key_length_arg > 0 ? -1 : 0;
567
 
 
568
 
  a_length= get_length(ptr);
569
 
  if (key_length_arg > 255)
570
 
  {
571
 
    b_length= uint2korr(b); b+=2;
572
 
  }
573
 
  else
574
 
    b_length= (uint) *b++;
575
 
  return field_charset->coll->strnncollsp(field_charset,
576
 
                                          a, a_length,
577
 
                                          b, b_length,
578
 
                                          insert_or_update);
579
 
}
580
 
 
581
621
/** Create a packed key that will be used for storage from a MySQL row. */
582
622
 
583
 
uchar *
584
 
Field_blob::pack_key(uchar *to, const uchar *from, uint max_length,
585
 
                     bool low_byte_first __attribute__((unused)))
 
623
unsigned char *
 
624
Field_blob::pack_key(unsigned char *to, const unsigned char *from, uint32_t max_length,
 
625
                     bool )
586
626
{
587
 
  uchar *save= ptr;
588
 
  ptr= (uchar*) from;
 
627
  unsigned char *save= ptr;
 
628
  ptr= (unsigned char*) from;
589
629
  uint32_t length=get_length();        // Length of from string
590
 
  uint local_char_length= ((field_charset->mbmaxlen > 1) ?
 
630
  uint32_t local_char_length= ((field_charset->mbmaxlen > 1) ?
591
631
                           max_length/field_charset->mbmaxlen : max_length);
592
632
  if (length)
593
 
    get_ptr((uchar**) &from);
 
633
    get_ptr((unsigned char**) &from);
594
634
  if (length > local_char_length)
595
635
    local_char_length= my_charpos(field_charset, from, from+length,
596
636
                                  local_char_length);
597
637
  set_if_smaller(length, local_char_length);
598
 
  *to++= (uchar) length;
 
638
  *to++= (unsigned char) length;
599
639
  if (max_length > 255)                         // 2 byte length
600
 
    *to++= (uchar) (length >> 8);
 
640
    *to++= (unsigned char) (length >> 8);
601
641
  memcpy(to, from, length);
602
642
  ptr=save;                                     // Restore org row pointer
603
643
  return to+length;
604
644
}
605
645
 
606
646
 
607
 
/**
608
 
  Unpack a blob key into a record buffer.
609
 
 
610
 
  A blob key has a maximum size of 64K-1.
611
 
  In its packed form, the length field is one or two bytes long,
612
 
  depending on 'max_length'.
613
 
  Depending on the maximum length of a blob, its length field is
614
 
  put into 1 to 4 bytes. This is a property of the blob object,
615
 
  described by 'packlength'.
616
 
  Blobs are internally stored apart from the record buffer, which
617
 
  contains a pointer to the blob buffer.
618
 
 
619
 
 
620
 
  @param to                          Pointer into the record buffer.
621
 
  @param from                        Pointer to the packed key.
622
 
  @param max_length                  Key length limit from key description.
623
 
 
624
 
  @return
625
 
    Pointer into 'from' past the last byte copied from packed key.
626
 
*/
627
 
 
628
 
const uchar *
629
 
Field_blob::unpack_key(uchar *to, const uchar *from, uint max_length,
630
 
                       bool low_byte_first __attribute__((unused)))
631
 
{
632
 
  /* get length of the blob key */
633
 
  uint32_t length= *from++;
634
 
  if (max_length > 255)
635
 
    length+= *from++ << 8;
636
 
 
637
 
  /* put the length into the record buffer */
638
 
  put_length(to, length);
639
 
 
640
 
  /* put the address of the blob buffer or NULL */
641
 
  if (length)
642
 
    memcpy(to + packlength, &from, sizeof(from));
643
 
  else
644
 
    memset(to + packlength, 0, sizeof(from));
645
 
 
646
 
  /* point to first byte of next field in 'from' */
647
 
  return from + length;
648
 
}
649
 
 
650
 
 
651
 
/** Create a packed key that will be used for storage from a MySQL key. */
652
 
 
653
 
uchar *
654
 
Field_blob::pack_key_from_key_image(uchar *to, const uchar *from, uint max_length,
655
 
                                    bool low_byte_first __attribute__((unused)))
656
 
{
657
 
  uint length=uint2korr(from);
658
 
  if (length > max_length)
659
 
    length=max_length;
660
 
  *to++= (char) (length & 255);
661
 
  if (max_length > 255)
662
 
    *to++= (char) (length >> 8);
663
 
  if (length)
664
 
    memcpy(to, from+HA_KEY_BLOB_LENGTH, length);
665
 
  return to+length;
666
 
}
667
 
 
668
 
 
669
 
uint Field_blob::packed_col_length(const uchar *data_ptr, uint length)
670
 
{
671
 
  if (length > 255)
672
 
    return uint2korr(data_ptr)+2;
673
 
  return (uint) *data_ptr + 1;
674
 
}
675
 
 
676
 
 
677
 
uint Field_blob::max_packed_col_length(uint max_length)
678
 
{
679
 
  return (max_length > 255 ? 2 : 1)+max_length;
680
 
}
681
 
 
682
 
 
683
 
uint Field_blob::is_equal(Create_field *new_field)
684
 
{
685
 
  if (compare_str_field_flags(new_field, flags))
 
647
uint32_t Field_blob::is_equal(CreateField *new_field_ptr)
 
648
{
 
649
  if (compare_str_field_flags(new_field_ptr, flags))
686
650
    return 0;
 
651
  Field_blob *blob_field_ptr= static_cast<Field_blob *>(new_field_ptr->field);
687
652
 
688
 
  return ((new_field->sql_type == get_blob_type_from_length(max_data_length()))
689
 
          && new_field->charset == field_charset &&
690
 
          ((Field_blob *)new_field->field)->max_data_length() ==
691
 
          max_data_length());
 
653
  return (new_field_ptr->sql_type == DRIZZLE_TYPE_BLOB
 
654
          && new_field_ptr->charset == field_charset
 
655
          && blob_field_ptr->max_data_length() == max_data_length());
692
656
}
693
657
 
694
658
 
716
680
    return 0;
717
681
  }
718
682
}
719