~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to drizzled/field/blob.cc

pandora-build v0.71. Added check for avahi.

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,
38
 
                       enum utype unireg_check_arg, const char *field_name_arg,
39
 
                       TABLE_SHARE *share, uint blob_pack_length,
40
 
                       const CHARSET_INFO * const cs)
41
 
  :Field_longstr(ptr_arg, BLOB_PACK_LENGTH_TO_MAX_LENGH(blob_pack_length),
42
 
                 null_ptr_arg, null_bit_arg, unireg_check_arg, field_name_arg,
43
 
                 cs),
 
45
Field_blob::Field_blob(unsigned char *ptr_arg,
 
46
                       unsigned char *null_ptr_arg,
 
47
                       unsigned char null_bit_arg,
 
48
                                   const char *field_name_arg,
 
49
                       TableShare *share,
 
50
                       uint32_t blob_pack_length,
 
51
                       const CHARSET_INFO * const cs)
 
52
  :Field_str(ptr_arg,
 
53
             blob_pack_length_to_max_length(blob_pack_length),
 
54
             null_ptr_arg,
 
55
             null_bit_arg,
 
56
             field_name_arg,
 
57
             cs),
44
58
   packlength(blob_pack_length)
45
59
{
46
60
  flags|= BLOB_FLAG;
48
62
  /* TODO: why do not fill table->s->blob_field array here? */
49
63
}
50
64
 
51
 
 
52
 
void Field_blob::store_length(uchar *i_ptr,
53
 
                              uint i_packlength,
 
65
void Field_blob::store_length(unsigned char *i_ptr,
 
66
                              uint32_t i_packlength,
54
67
                              uint32_t i_number,
55
 
                              bool low_byte_first __attribute__((unused)))
 
68
                              bool low_byte_first)
56
69
{
 
70
#ifndef WORDS_BIGENDIAN
 
71
  (void)low_byte_first;
 
72
#endif
57
73
  switch (i_packlength) {
58
74
  case 1:
59
 
    i_ptr[0]= (uchar) i_number;
 
75
    i_ptr[0]= (unsigned char) i_number;
60
76
    break;
61
77
  case 2:
62
78
#ifdef WORDS_BIGENDIAN
84
100
}
85
101
 
86
102
 
87
 
uint32_t Field_blob::get_length(const uchar *pos,
88
 
                              uint packlength_arg,
89
 
                              bool low_byte_first __attribute__((unused)))
90
 
{
 
103
void Field_blob::store_length(unsigned char *i_ptr, uint32_t i_packlength,
 
104
                  uint32_t i_number)
 
105
{
 
106
  store_length(i_ptr, i_packlength, i_number, table->s->db_low_byte_first);
 
107
}
 
108
 
 
109
 
 
110
uint32_t Field_blob::get_length(const unsigned char *pos,
 
111
                                uint32_t packlength_arg,
 
112
                                bool low_byte_first)
 
113
{
 
114
#ifndef WORDS_BIGENDIAN
 
115
  (void)low_byte_first;
 
116
#endif
91
117
  switch (packlength_arg) {
92
118
  case 1:
93
119
    return (uint32_t) pos[0];
120
146
}
121
147
 
122
148
 
 
149
uint32_t Field_blob::get_packed_size(const unsigned char *ptr_arg,
 
150
                                bool low_byte_first)
 
151
{
 
152
  return packlength + get_length(ptr_arg, packlength, low_byte_first);
 
153
}
 
154
 
 
155
 
 
156
uint32_t Field_blob::get_length(uint32_t row_offset)
 
157
{
 
158
  return get_length(ptr+row_offset, this->packlength,
 
159
                    table->s->db_low_byte_first);
 
160
}
 
161
 
 
162
 
 
163
uint32_t Field_blob::get_length(const unsigned char *ptr_arg)
 
164
{
 
165
  return get_length(ptr_arg, this->packlength, table->s->db_low_byte_first);
 
166
}
 
167
 
 
168
 
123
169
/**
124
170
  Put a blob length field into a record buffer.
125
171
 
131
177
  @param length              The length value to put.
132
178
*/
133
179
 
134
 
void Field_blob::put_length(uchar *pos, uint32_t length)
 
180
void Field_blob::put_length(unsigned char *pos, uint32_t length)
135
181
{
136
182
  switch (packlength) {
137
183
  case 1:
150
196
}
151
197
 
152
198
 
153
 
int Field_blob::store(const char *from,uint length, const CHARSET_INFO * const cs)
 
199
int Field_blob::store(const char *from,uint32_t length, const CHARSET_INFO * const cs)
154
200
{
155
 
  uint copy_length, new_length;
 
201
  uint32_t copy_length, new_length;
156
202
  const char *well_formed_error_pos;
157
203
  const char *cannot_convert_error_pos;
158
204
  const char *from_end_pos, *tmp;
159
205
  char buff[STRING_BUFFER_USUAL_SIZE];
160
206
  String tmpstr(buff,sizeof(buff), &my_charset_bin);
161
207
 
 
208
  ASSERT_COLUMN_MARKED_FOR_WRITE;
 
209
 
162
210
  if (!length)
163
211
  {
164
212
    memset(ptr, 0, Field_blob::pack_length());
171
219
    if (!String::needs_conversion(length, cs, field_charset, &dummy_offset))
172
220
    {
173
221
      Field_blob::store_length(length);
174
 
      memcpy(ptr+packlength, &from, sizeof(char*));
 
222
      memmove(ptr+packlength, &from, sizeof(char*));
175
223
      return 0;
176
224
    }
177
225
    if (tmpstr.copy(from, length, cs))
183
231
  if (value.alloc(new_length))
184
232
    goto oom_error;
185
233
 
186
 
 
187
 
  if (f_is_hex_escape(flags))
188
 
  {
189
 
    copy_length= my_copy_with_hex_escaping(field_charset,
190
 
                                           (char*) value.ptr(), new_length,
191
 
                                            from, length);
192
 
    Field_blob::store_length(copy_length);
193
 
    tmp= value.ptr();
194
 
    memcpy(ptr + packlength, &tmp, sizeof(char*));
195
 
    return 0;
196
 
  }
197
234
  /*
198
235
    "length" is OK as "nchars" argument to well_formed_copy_nchars as this
199
236
    is never used to limit the length of the data. The cut of long data
209
246
 
210
247
  Field_blob::store_length(copy_length);
211
248
  tmp= value.ptr();
212
 
  memcpy(ptr+packlength, &tmp, sizeof(char*));
 
249
  memmove(ptr+packlength, &tmp, sizeof(char*));
213
250
 
214
251
  if (check_string_copy_error(this, well_formed_error_pos,
215
252
                              cannot_convert_error_pos, from + length, cs))
220
257
oom_error:
221
258
  /* Fatal OOM error */
222
259
  memset(ptr, 0, Field_blob::pack_length());
223
 
  return -1; 
 
260
  return -1;
224
261
}
225
262
 
226
263
 
227
264
int Field_blob::store(double nr)
228
265
{
229
266
  const CHARSET_INFO * const cs=charset();
 
267
  ASSERT_COLUMN_MARKED_FOR_WRITE;
230
268
  value.set_real(nr, NOT_FIXED_DEC, cs);
231
 
  return Field_blob::store(value.ptr(),(uint) value.length(), cs);
 
269
  return Field_blob::store(value.ptr(),(uint32_t) value.length(), cs);
232
270
}
233
271
 
234
272
 
235
273
int Field_blob::store(int64_t nr, bool unsigned_val)
236
274
{
237
275
  const CHARSET_INFO * const cs=charset();
 
276
  ASSERT_COLUMN_MARKED_FOR_WRITE;
238
277
  value.set_int(nr, unsigned_val, cs);
239
 
  return Field_blob::store(value.ptr(), (uint) value.length(), cs);
 
278
  return Field_blob::store(value.ptr(), (uint32_t) value.length(), cs);
240
279
}
241
280
 
242
281
 
247
286
  uint32_t length;
248
287
  const CHARSET_INFO *cs;
249
288
 
 
289
  ASSERT_COLUMN_MARKED_FOR_READ;
 
290
 
250
291
  memcpy(&blob,ptr+packlength,sizeof(char*));
251
292
  if (!blob)
252
293
    return 0.0;
260
301
{
261
302
  int not_used;
262
303
  char *blob;
 
304
 
 
305
  ASSERT_COLUMN_MARKED_FOR_READ;
 
306
 
263
307
  memcpy(&blob,ptr+packlength,sizeof(char*));
264
308
  if (!blob)
265
309
    return 0;
267
311
  return my_strntoll(charset(),blob,length,10,NULL,&not_used);
268
312
}
269
313
 
270
 
String *Field_blob::val_str(String *val_buffer __attribute__((unused)),
 
314
String *Field_blob::val_str(String *,
271
315
                            String *val_ptr)
272
316
{
273
317
  char *blob;
 
318
 
 
319
  ASSERT_COLUMN_MARKED_FOR_READ;
 
320
 
274
321
  memcpy(&blob,ptr+packlength,sizeof(char*));
275
322
  if (!blob)
276
323
    val_ptr->set("",0,charset());       // A bit safer than ->length(0)
284
331
{
285
332
  const char *blob;
286
333
  size_t length;
287
 
  memcpy(&blob, ptr+packlength, sizeof(const uchar*));
 
334
 
 
335
  ASSERT_COLUMN_MARKED_FOR_READ;
 
336
 
 
337
  memcpy(&blob, ptr+packlength, sizeof(const unsigned char*));
288
338
  if (!blob)
289
339
  {
290
340
    blob= "";
299
349
}
300
350
 
301
351
 
302
 
int Field_blob::cmp(const uchar *a,uint32_t a_length, const uchar *b,
 
352
int Field_blob::cmp(const unsigned char *a,uint32_t a_length, const unsigned char *b,
303
353
                    uint32_t b_length)
304
354
{
305
 
  return field_charset->coll->strnncollsp(field_charset, 
 
355
  return field_charset->coll->strnncollsp(field_charset,
306
356
                                          a, a_length, b, b_length,
307
357
                                          0);
308
358
}
309
359
 
310
360
 
311
 
int Field_blob::cmp_max(const uchar *a_ptr, const uchar *b_ptr,
312
 
                        uint max_length)
 
361
int Field_blob::cmp_max(const unsigned char *a_ptr, const unsigned char *b_ptr,
 
362
                        uint32_t max_length)
313
363
{
314
 
  uchar *blob1,*blob2;
 
364
  unsigned char *blob1,*blob2;
315
365
  memcpy(&blob1,a_ptr+packlength,sizeof(char*));
316
366
  memcpy(&blob2,b_ptr+packlength,sizeof(char*));
317
 
  uint a_len= get_length(a_ptr), b_len= get_length(b_ptr);
 
367
  uint32_t a_len= get_length(a_ptr), b_len= get_length(b_ptr);
318
368
  set_if_smaller(a_len, max_length);
319
369
  set_if_smaller(b_len, max_length);
320
370
  return Field_blob::cmp(blob1,a_len,blob2,b_len);
321
371
}
322
372
 
323
373
 
324
 
int Field_blob::cmp_binary(const uchar *a_ptr, const uchar *b_ptr,
325
 
                           uint32_t max_length)
 
374
int Field_blob::cmp_binary(const unsigned char *a_ptr, const unsigned char *b_ptr,
 
375
                           uint32_t max_length)
326
376
{
327
377
  char *a,*b;
328
 
  uint diff;
 
378
  uint32_t diff;
329
379
  uint32_t a_length,b_length;
330
380
  memcpy(&a,a_ptr+packlength,sizeof(char*));
331
381
  memcpy(&b,b_ptr+packlength,sizeof(char*));
332
 
  a_length=get_length(a_ptr);
 
382
 
 
383
  a_length= get_length(a_ptr);
 
384
 
333
385
  if (a_length > max_length)
334
 
    a_length=max_length;
335
 
  b_length=get_length(b_ptr);
 
386
    a_length= max_length;
 
387
 
 
388
  b_length= get_length(b_ptr);
 
389
 
336
390
  if (b_length > max_length)
337
 
    b_length=max_length;
338
 
  diff=memcmp(a,b,min(a_length,b_length));
 
391
    b_length= max_length;
 
392
 
 
393
  diff= memcmp(a,b,min(a_length,b_length));
 
394
 
339
395
  return diff ? diff : (int) (a_length - b_length);
340
396
}
341
397
 
342
 
 
343
398
/* 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)))
 
399
uint32_t Field_blob::get_key_image(unsigned char *buff, uint32_t length)
348
400
{
349
401
  uint32_t blob_length= get_length(ptr);
350
 
  uchar *blob;
 
402
  unsigned char *blob;
351
403
 
352
404
  get_ptr(&blob);
353
 
  uint local_char_length= length / field_charset->mbmaxlen;
 
405
  uint32_t local_char_length= length / field_charset->mbmaxlen;
354
406
  local_char_length= my_charpos(field_charset, blob, blob + blob_length,
355
407
                          local_char_length);
356
408
  set_if_smaller(blob_length, local_char_length);
362
414
      identical keys
363
415
    */
364
416
    memset(buff+HA_KEY_BLOB_LENGTH+blob_length, 0, (length-blob_length));
365
 
    length=(uint) blob_length;
 
417
    length=(uint32_t) blob_length;
366
418
  }
367
419
  int2store(buff,length);
368
420
  memcpy(buff+HA_KEY_BLOB_LENGTH, blob, length);
370
422
}
371
423
 
372
424
 
373
 
void Field_blob::set_key_image(const uchar *buff,uint length)
 
425
uint32_t Field_blob::get_key_image(basic_string<unsigned char> &buff, uint32_t length)
 
426
{
 
427
  uint32_t blob_length= get_length(ptr);
 
428
  unsigned char *blob;
 
429
 
 
430
  get_ptr(&blob);
 
431
  uint32_t local_char_length= length / field_charset->mbmaxlen;
 
432
  local_char_length= my_charpos(field_charset, blob, blob + blob_length,
 
433
                                local_char_length);
 
434
  set_if_smaller(blob_length, local_char_length);
 
435
 
 
436
  unsigned char len_buff[HA_KEY_BLOB_LENGTH];
 
437
  int2store(len_buff,length);
 
438
  buff.append(len_buff);
 
439
  buff.append(blob, blob_length);
 
440
 
 
441
  if (length > blob_length)
 
442
  {
 
443
    /*
 
444
      Must clear this as we do a memcmp in opt_range.cc to detect
 
445
      identical keys
 
446
    */
 
447
 
 
448
    buff.append(length-blob_length, '0');
 
449
  }
 
450
  return HA_KEY_BLOB_LENGTH+length;
 
451
}
 
452
 
 
453
void Field_blob::set_key_image(const unsigned char *buff,uint32_t length)
374
454
{
375
455
  length= uint2korr(buff);
376
 
  (void) Field_blob::store((const char*) buff+HA_KEY_BLOB_LENGTH, length,
377
 
                           field_charset);
 
456
  (void) Field_blob::store((const char*) buff+HA_KEY_BLOB_LENGTH, length, field_charset);
378
457
}
379
458
 
380
 
 
381
 
int Field_blob::key_cmp(const uchar *key_ptr, uint max_key_length)
 
459
int Field_blob::key_cmp(const unsigned char *key_ptr, uint32_t max_key_length)
382
460
{
383
 
  uchar *blob1;
384
 
  uint blob_length=get_length(ptr);
 
461
  unsigned char *blob1;
 
462
  uint32_t blob_length=get_length(ptr);
385
463
  memcpy(&blob1,ptr+packlength,sizeof(char*));
386
464
  const CHARSET_INFO * const cs= charset();
387
 
  uint local_char_length= max_key_length / cs->mbmaxlen;
 
465
  uint32_t local_char_length= max_key_length / cs->mbmaxlen;
388
466
  local_char_length= my_charpos(cs, blob1, blob1+blob_length,
389
467
                                local_char_length);
390
468
  set_if_smaller(blob_length, local_char_length);
393
471
                         uint2korr(key_ptr));
394
472
}
395
473
 
396
 
int Field_blob::key_cmp(const uchar *a,const uchar *b)
 
474
int Field_blob::key_cmp(const unsigned char *a,const unsigned char *b)
397
475
{
398
476
  return Field_blob::cmp(a+HA_KEY_BLOB_LENGTH, uint2korr(a),
399
477
                         b+HA_KEY_BLOB_LENGTH, uint2korr(b));
400
478
}
401
479
 
402
 
 
403
480
/**
404
481
   Save the field metadata for blob fields.
405
482
 
410
487
 
411
488
   @returns number of bytes written to metadata_ptr
412
489
*/
413
 
int Field_blob::do_save_field_metadata(uchar *metadata_ptr)
 
490
int Field_blob::do_save_field_metadata(unsigned char *metadata_ptr)
414
491
{
415
492
  *metadata_ptr= pack_length_no_ptr();
416
493
  return 1;
417
494
}
418
495
 
419
 
 
420
496
uint32_t Field_blob::sort_length() const
421
497
{
422
 
  return (uint32_t) (current_thd->variables.max_sort_length + 
 
498
  return (uint32_t) (current_session->variables.max_sort_length +
423
499
                   (field_charset == &my_charset_bin ? 0 : packlength));
424
500
}
425
501
 
426
 
 
427
 
void Field_blob::sort_string(uchar *to,uint length)
 
502
void Field_blob::sort_string(unsigned char *to,uint32_t length)
428
503
{
429
 
  uchar *blob;
430
 
  uint blob_length=get_length();
 
504
  unsigned char *blob;
 
505
  uint32_t blob_length=get_length();
431
506
 
432
507
  if (!blob_length)
433
508
    memset(to, 0, length);
435
510
  {
436
511
    if (field_charset == &my_charset_bin)
437
512
    {
438
 
      uchar *pos;
 
513
      unsigned char *pos;
439
514
 
440
515
      /*
441
516
        Store length of blob last in blob to shorter blobs before longer blobs
459
534
      }
460
535
    }
461
536
    memcpy(&blob,ptr+packlength,sizeof(char*));
462
 
    
 
537
 
463
538
    blob_length=my_strnxfrm(field_charset,
464
539
                            to, length, blob, blob_length);
465
540
    assert(blob_length == length);
466
541
  }
467
542
}
468
543
 
 
544
uint32_t Field_blob::pack_length() const
 
545
{
 
546
  return (uint32_t) (packlength+table->s->blob_ptr_size);
 
547
}
469
548
 
470
549
void Field_blob::sql_type(String &res) const
471
550
{
475
554
    res.set_ascii(STRING_WITH_LEN("text"));
476
555
}
477
556
 
478
 
uchar *Field_blob::pack(uchar *to, const uchar *from,
479
 
                        uint max_length, bool low_byte_first)
 
557
unsigned char *Field_blob::pack(unsigned char *to, const unsigned char *from,
 
558
                                uint32_t max_length, bool low_byte_first)
480
559
{
481
 
  uchar *save= ptr;
482
 
  ptr= (uchar*) from;
483
 
  uint32_t length=get_length();                 // Length of from string
 
560
  unsigned char *save= ptr;
 
561
  ptr= (unsigned char*) from;
 
562
  uint32_t length= get_length();                        // Length of from string
484
563
 
485
564
  /*
486
565
    Store max length, which will occupy packlength bytes. If the max
494
573
   */
495
574
  if (length > 0)
496
575
  {
497
 
    get_ptr((uchar**) &from);
 
576
    get_ptr((unsigned char**) &from);
498
577
    memcpy(to+packlength, from,length);
499
578
  }
500
 
  ptr=save;                                     // Restore org row pointer
 
579
 
 
580
  ptr= save;                                    // Restore org row pointer
501
581
  return(to+packlength+length);
502
582
}
503
583
 
504
 
 
505
584
/**
506
585
   Unpack a blob field from row data.
507
586
 
508
 
   This method is used to unpack a blob field from a master whose size of 
 
587
   This method is used to unpack a blob field from a master whose size of
509
588
   the field is less than that of the slave. Note: This method is included
510
589
   to satisfy inheritance rules, but is not needed for blob fields. It
511
590
   simply is used as a pass-through to the original unpack() method for
519
598
 
520
599
   @return  New pointer into memory based on from + length of the data
521
600
*/
522
 
const uchar *Field_blob::unpack(uchar *to __attribute__((unused)),
523
 
                                const uchar *from,
524
 
                                uint param_data,
 
601
const unsigned char *Field_blob::unpack(unsigned char *,
 
602
                                const unsigned char *from,
 
603
                                uint32_t param_data,
525
604
                                bool low_byte_first)
526
605
{
527
 
  uint const master_packlength=
 
606
  uint32_t const master_packlength=
528
607
    param_data > 0 ? param_data & 0xFF : packlength;
529
608
  uint32_t const length= get_length(from, master_packlength, low_byte_first);
530
 
  bitmap_set_bit(table->write_set, field_index);
 
609
  table->setWriteSet(field_index);
531
610
  store(reinterpret_cast<const char*>(from) + master_packlength,
532
611
        length, field_charset);
533
612
  return(from + master_packlength + length);
534
613
}
535
614
 
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
615
/** Create a packed key that will be used for storage from a MySQL row. */
582
616
 
583
 
uchar *
584
 
Field_blob::pack_key(uchar *to, const uchar *from, uint max_length,
585
 
                     bool low_byte_first __attribute__((unused)))
 
617
unsigned char *
 
618
Field_blob::pack_key(unsigned char *to, const unsigned char *from, uint32_t max_length,
 
619
                     bool )
586
620
{
587
 
  uchar *save= ptr;
588
 
  ptr= (uchar*) from;
 
621
  unsigned char *save= ptr;
 
622
  ptr= (unsigned char*) from;
589
623
  uint32_t length=get_length();        // Length of from string
590
 
  uint local_char_length= ((field_charset->mbmaxlen > 1) ?
 
624
  uint32_t local_char_length= ((field_charset->mbmaxlen > 1) ?
591
625
                           max_length/field_charset->mbmaxlen : max_length);
592
626
  if (length)
593
 
    get_ptr((uchar**) &from);
 
627
    get_ptr((unsigned char**) &from);
594
628
  if (length > local_char_length)
595
629
    local_char_length= my_charpos(field_charset, from, from+length,
596
630
                                  local_char_length);
597
631
  set_if_smaller(length, local_char_length);
598
 
  *to++= (uchar) length;
 
632
  *to++= (unsigned char) length;
599
633
  if (max_length > 255)                         // 2 byte length
600
 
    *to++= (uchar) (length >> 8);
 
634
    *to++= (unsigned char) (length >> 8);
601
635
  memcpy(to, from, length);
602
636
  ptr=save;                                     // Restore org row pointer
603
637
  return to+length;
604
638
}
605
639
 
606
640
 
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))
 
641
uint32_t Field_blob::is_equal(CreateField *new_field_ptr)
 
642
{
 
643
  if (compare_str_field_flags(new_field_ptr, flags))
686
644
    return 0;
 
645
  Field_blob *blob_field_ptr= static_cast<Field_blob *>(new_field_ptr->field);
687
646
 
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());
 
647
  return (new_field_ptr->sql_type == DRIZZLE_TYPE_BLOB
 
648
          && new_field_ptr->charset == field_charset
 
649
          && blob_field_ptr->max_data_length() == max_data_length());
692
650
}
693
651
 
694
652
 
716
674
    return 0;
717
675
  }
718
676
}
719