~drizzle-trunk/drizzle/development

520.1.25 by Monty Taylor
Removed the split.
1
/* -*- mode: c++; c-basic-offset: 2; indent-tabs-mode: nil; -*-
173.1.2 by Toru Maesaka
forgot to bzr-add new files in the previous push
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
243.1.17 by Jay Pipes
FINAL PHASE removal of mysql_priv.h (Bye, bye my friend.)
22
#include <drizzled/server_includes.h>
214 by Brian Aker
Rename of fields (fix issue with string and decimal .h clashing).
23
#include <drizzled/field/blob.h>
173.1.2 by Toru Maesaka
forgot to bzr-add new files in the previous push
24
322.2.2 by Mats Kindahl
Hiding THD::proc_info field and providing a setter and getter.
25
uint32_t
482 by Brian Aker
Remove uint.
26
blob_pack_length_to_max_length(uint32_t arg)
322.2.2 by Mats Kindahl
Hiding THD::proc_info field and providing a setter and getter.
27
{
422 by Monty
Various int64 constant fixes.
28
  return (INT64_C(1) << cmin(arg, 4U) * 8) - INT64_C(1);
322.2.2 by Mats Kindahl
Hiding THD::proc_info field and providing a setter and getter.
29
}
30
173.1.2 by Toru Maesaka
forgot to bzr-add new files in the previous push
31
32
/****************************************************************************
33
** blob type
34
** A blob is saved as a length and a pointer. The length is stored in the
35
** packlength slot and may be from 1-4.
36
****************************************************************************/
37
481 by Brian Aker
Remove all of uchar.
38
Field_blob::Field_blob(unsigned char *ptr_arg, unsigned char *null_ptr_arg, unsigned char null_bit_arg,
173.1.2 by Toru Maesaka
forgot to bzr-add new files in the previous push
39
		       enum utype unireg_check_arg, const char *field_name_arg,
482 by Brian Aker
Remove uint.
40
                       TABLE_SHARE *share, uint32_t blob_pack_length,
264.2.6 by Andrey Hristov
Constify the usage of CHARSET_INFO almost to the last place in the code.
41
		       const CHARSET_INFO * const cs)
322.2.2 by Mats Kindahl
Hiding THD::proc_info field and providing a setter and getter.
42
  :Field_longstr(ptr_arg, blob_pack_length_to_max_length(blob_pack_length),
173.1.2 by Toru Maesaka
forgot to bzr-add new files in the previous push
43
                 null_ptr_arg, null_bit_arg, unireg_check_arg, field_name_arg,
44
                 cs),
45
   packlength(blob_pack_length)
46
{
47
  flags|= BLOB_FLAG;
48
  share->blob_fields++;
49
  /* TODO: why do not fill table->s->blob_field array here? */
50
}
51
52
481 by Brian Aker
Remove all of uchar.
53
void Field_blob::store_length(unsigned char *i_ptr,
482 by Brian Aker
Remove uint.
54
                              uint32_t i_packlength,
173.1.2 by Toru Maesaka
forgot to bzr-add new files in the previous push
55
                              uint32_t i_number,
212.1.3 by Monty Taylor
Renamed __attribute__((__unused__)) to __attribute__((unused)).
56
                              bool low_byte_first __attribute__((unused)))
173.1.2 by Toru Maesaka
forgot to bzr-add new files in the previous push
57
{
58
  switch (i_packlength) {
59
  case 1:
481 by Brian Aker
Remove all of uchar.
60
    i_ptr[0]= (unsigned char) i_number;
173.1.2 by Toru Maesaka
forgot to bzr-add new files in the previous push
61
    break;
62
  case 2:
63
#ifdef WORDS_BIGENDIAN
64
    if (low_byte_first)
65
    {
66
      int2store(i_ptr,(unsigned short) i_number);
67
    }
68
    else
69
#endif
70
      shortstore(i_ptr,(unsigned short) i_number);
71
    break;
72
  case 3:
73
    int3store(i_ptr,i_number);
74
    break;
75
  case 4:
76
#ifdef WORDS_BIGENDIAN
77
    if (low_byte_first)
78
    {
79
      int4store(i_ptr,i_number);
80
    }
81
    else
82
#endif
83
      longstore(i_ptr,i_number);
84
  }
85
}
86
87
481 by Brian Aker
Remove all of uchar.
88
uint32_t Field_blob::get_length(const unsigned char *pos,
482 by Brian Aker
Remove uint.
89
                              uint32_t packlength_arg,
212.1.3 by Monty Taylor
Renamed __attribute__((__unused__)) to __attribute__((unused)).
90
                              bool low_byte_first __attribute__((unused)))
173.1.2 by Toru Maesaka
forgot to bzr-add new files in the previous push
91
{
92
  switch (packlength_arg) {
93
  case 1:
94
    return (uint32_t) pos[0];
95
  case 2:
96
    {
206 by Brian Aker
Removed final uint dead types.
97
      uint16_t tmp;
173.1.2 by Toru Maesaka
forgot to bzr-add new files in the previous push
98
#ifdef WORDS_BIGENDIAN
99
      if (low_byte_first)
100
	tmp=sint2korr(pos);
101
      else
102
#endif
103
	shortget(tmp,pos);
104
      return (uint32_t) tmp;
105
    }
106
  case 3:
107
    return (uint32_t) uint3korr(pos);
108
  case 4:
109
    {
110
      uint32_t tmp;
111
#ifdef WORDS_BIGENDIAN
112
      if (low_byte_first)
113
	tmp=uint4korr(pos);
114
      else
115
#endif
116
	longget(tmp,pos);
117
      return (uint32_t) tmp;
118
    }
119
  }
120
  return 0;					// Impossible
121
}
122
123
124
/**
125
  Put a blob length field into a record buffer.
126
127
  Depending on the maximum length of a blob, its length field is
128
  put into 1 to 4 bytes. This is a property of the blob object,
129
  described by 'packlength'.
130
131
  @param pos                 Pointer into the record buffer.
132
  @param length              The length value to put.
133
*/
134
481 by Brian Aker
Remove all of uchar.
135
void Field_blob::put_length(unsigned char *pos, uint32_t length)
173.1.2 by Toru Maesaka
forgot to bzr-add new files in the previous push
136
{
137
  switch (packlength) {
138
  case 1:
139
    *pos= (char) length;
140
    break;
141
  case 2:
142
    int2store(pos, length);
143
    break;
144
  case 3:
145
    int3store(pos, length);
146
    break;
147
  case 4:
148
    int4store(pos, length);
149
    break;
150
  }
151
}
152
153
482 by Brian Aker
Remove uint.
154
int Field_blob::store(const char *from,uint32_t length, const CHARSET_INFO * const cs)
173.1.2 by Toru Maesaka
forgot to bzr-add new files in the previous push
155
{
482 by Brian Aker
Remove uint.
156
  uint32_t copy_length, new_length;
173.1.2 by Toru Maesaka
forgot to bzr-add new files in the previous push
157
  const char *well_formed_error_pos;
158
  const char *cannot_convert_error_pos;
159
  const char *from_end_pos, *tmp;
160
  char buff[STRING_BUFFER_USUAL_SIZE];
161
  String tmpstr(buff,sizeof(buff), &my_charset_bin);
162
163
  if (!length)
164
  {
212.6.1 by Mats Kindahl
Replacing all bzero() calls with memset() calls and removing the bzero.c file.
165
    memset(ptr, 0, Field_blob::pack_length());
173.1.2 by Toru Maesaka
forgot to bzr-add new files in the previous push
166
    return 0;
167
  }
168
169
  if (from == value.ptr())
170
  {
171
    uint32_t dummy_offset;
172
    if (!String::needs_conversion(length, cs, field_charset, &dummy_offset))
173
    {
174
      Field_blob::store_length(length);
212.6.6 by Mats Kindahl
Removing redundant use of casts in drizzled/ for memcmp(), memcpy(), memset(), and memmove().
175
      memcpy(ptr+packlength, &from, sizeof(char*));
173.1.2 by Toru Maesaka
forgot to bzr-add new files in the previous push
176
      return 0;
177
    }
178
    if (tmpstr.copy(from, length, cs))
179
      goto oom_error;
180
    from= tmpstr.ptr();
181
  }
182
398.1.4 by Monty Taylor
Renamed max/min.
183
  new_length= cmin(max_data_length(), field_charset->mbmaxlen * length);
173.1.2 by Toru Maesaka
forgot to bzr-add new files in the previous push
184
  if (value.alloc(new_length))
185
    goto oom_error;
186
187
188
  if (f_is_hex_escape(flags))
189
  {
190
    copy_length= my_copy_with_hex_escaping(field_charset,
191
                                           (char*) value.ptr(), new_length,
192
                                            from, length);
193
    Field_blob::store_length(copy_length);
194
    tmp= value.ptr();
212.6.6 by Mats Kindahl
Removing redundant use of casts in drizzled/ for memcmp(), memcpy(), memset(), and memmove().
195
    memcpy(ptr + packlength, &tmp, sizeof(char*));
173.1.2 by Toru Maesaka
forgot to bzr-add new files in the previous push
196
    return 0;
197
  }
198
  /*
199
    "length" is OK as "nchars" argument to well_formed_copy_nchars as this
200
    is never used to limit the length of the data. The cut of long data
201
    is done with the new_length value.
202
  */
203
  copy_length= well_formed_copy_nchars(field_charset,
204
                                       (char*) value.ptr(), new_length,
205
                                       cs, from, length,
206
                                       length,
207
                                       &well_formed_error_pos,
208
                                       &cannot_convert_error_pos,
209
                                       &from_end_pos);
210
211
  Field_blob::store_length(copy_length);
212
  tmp= value.ptr();
212.6.6 by Mats Kindahl
Removing redundant use of casts in drizzled/ for memcmp(), memcpy(), memset(), and memmove().
213
  memcpy(ptr+packlength, &tmp, sizeof(char*));
173.1.2 by Toru Maesaka
forgot to bzr-add new files in the previous push
214
215
  if (check_string_copy_error(this, well_formed_error_pos,
216
                              cannot_convert_error_pos, from + length, cs))
217
    return 2;
218
219
  return report_if_important_data(from_end_pos, from + length);
220
221
oom_error:
222
  /* Fatal OOM error */
212.6.1 by Mats Kindahl
Replacing all bzero() calls with memset() calls and removing the bzero.c file.
223
  memset(ptr, 0, Field_blob::pack_length());
173.1.2 by Toru Maesaka
forgot to bzr-add new files in the previous push
224
  return -1; 
225
}
226
227
228
int Field_blob::store(double nr)
229
{
264.2.6 by Andrey Hristov
Constify the usage of CHARSET_INFO almost to the last place in the code.
230
  const CHARSET_INFO * const cs=charset();
173.1.2 by Toru Maesaka
forgot to bzr-add new files in the previous push
231
  value.set_real(nr, NOT_FIXED_DEC, cs);
232
  return Field_blob::store(value.ptr(),(uint) value.length(), cs);
233
}
234
235
236
int Field_blob::store(int64_t nr, bool unsigned_val)
237
{
264.2.6 by Andrey Hristov
Constify the usage of CHARSET_INFO almost to the last place in the code.
238
  const CHARSET_INFO * const cs=charset();
173.1.2 by Toru Maesaka
forgot to bzr-add new files in the previous push
239
  value.set_int(nr, unsigned_val, cs);
240
  return Field_blob::store(value.ptr(), (uint) value.length(), cs);
241
}
242
243
244
double Field_blob::val_real(void)
245
{
246
  int not_used;
247
  char *end_not_used, *blob;
248
  uint32_t length;
264.2.6 by Andrey Hristov
Constify the usage of CHARSET_INFO almost to the last place in the code.
249
  const CHARSET_INFO *cs;
173.1.2 by Toru Maesaka
forgot to bzr-add new files in the previous push
250
212.6.3 by Mats Kindahl
Removing deprecated functions from code and replacing them with C99 equivalents:
251
  memcpy(&blob,ptr+packlength,sizeof(char*));
173.1.2 by Toru Maesaka
forgot to bzr-add new files in the previous push
252
  if (!blob)
253
    return 0.0;
254
  length= get_length(ptr);
255
  cs= charset();
256
  return my_strntod(cs, blob, length, &end_not_used, &not_used);
257
}
258
259
260
int64_t Field_blob::val_int(void)
261
{
262
  int not_used;
263
  char *blob;
212.6.3 by Mats Kindahl
Removing deprecated functions from code and replacing them with C99 equivalents:
264
  memcpy(&blob,ptr+packlength,sizeof(char*));
173.1.2 by Toru Maesaka
forgot to bzr-add new files in the previous push
265
  if (!blob)
266
    return 0;
267
  uint32_t length=get_length(ptr);
268
  return my_strntoll(charset(),blob,length,10,NULL,&not_used);
269
}
270
271
String *Field_blob::val_str(String *val_buffer __attribute__((unused)),
272
			    String *val_ptr)
273
{
274
  char *blob;
212.6.3 by Mats Kindahl
Removing deprecated functions from code and replacing them with C99 equivalents:
275
  memcpy(&blob,ptr+packlength,sizeof(char*));
173.1.2 by Toru Maesaka
forgot to bzr-add new files in the previous push
276
  if (!blob)
277
    val_ptr->set("",0,charset());	// A bit safer than ->length(0)
278
  else
279
    val_ptr->set((const char*) blob,get_length(ptr),charset());
280
  return val_ptr;
281
}
282
283
284
my_decimal *Field_blob::val_decimal(my_decimal *decimal_value)
285
{
286
  const char *blob;
287
  size_t length;
481 by Brian Aker
Remove all of uchar.
288
  memcpy(&blob, ptr+packlength, sizeof(const unsigned char*));
173.1.2 by Toru Maesaka
forgot to bzr-add new files in the previous push
289
  if (!blob)
290
  {
291
    blob= "";
292
    length= 0;
293
  }
294
  else
295
    length= get_length(ptr);
296
297
  str2my_decimal(E_DEC_FATAL_ERROR, blob, length, charset(),
298
                 decimal_value);
299
  return decimal_value;
300
}
301
302
481 by Brian Aker
Remove all of uchar.
303
int Field_blob::cmp(const unsigned char *a,uint32_t a_length, const unsigned char *b,
173.1.2 by Toru Maesaka
forgot to bzr-add new files in the previous push
304
		    uint32_t b_length)
305
{
306
  return field_charset->coll->strnncollsp(field_charset, 
307
                                          a, a_length, b, b_length,
308
                                          0);
309
}
310
311
481 by Brian Aker
Remove all of uchar.
312
int Field_blob::cmp_max(const unsigned char *a_ptr, const unsigned char *b_ptr,
482 by Brian Aker
Remove uint.
313
                        uint32_t max_length)
173.1.2 by Toru Maesaka
forgot to bzr-add new files in the previous push
314
{
481 by Brian Aker
Remove all of uchar.
315
  unsigned char *blob1,*blob2;
212.6.3 by Mats Kindahl
Removing deprecated functions from code and replacing them with C99 equivalents:
316
  memcpy(&blob1,a_ptr+packlength,sizeof(char*));
317
  memcpy(&blob2,b_ptr+packlength,sizeof(char*));
482 by Brian Aker
Remove uint.
318
  uint32_t a_len= get_length(a_ptr), b_len= get_length(b_ptr);
173.1.2 by Toru Maesaka
forgot to bzr-add new files in the previous push
319
  set_if_smaller(a_len, max_length);
320
  set_if_smaller(b_len, max_length);
321
  return Field_blob::cmp(blob1,a_len,blob2,b_len);
322
}
323
324
481 by Brian Aker
Remove all of uchar.
325
int Field_blob::cmp_binary(const unsigned char *a_ptr, const unsigned char *b_ptr,
173.1.2 by Toru Maesaka
forgot to bzr-add new files in the previous push
326
			   uint32_t max_length)
327
{
328
  char *a,*b;
482 by Brian Aker
Remove uint.
329
  uint32_t diff;
173.1.2 by Toru Maesaka
forgot to bzr-add new files in the previous push
330
  uint32_t a_length,b_length;
212.6.3 by Mats Kindahl
Removing deprecated functions from code and replacing them with C99 equivalents:
331
  memcpy(&a,a_ptr+packlength,sizeof(char*));
332
  memcpy(&b,b_ptr+packlength,sizeof(char*));
173.1.2 by Toru Maesaka
forgot to bzr-add new files in the previous push
333
  a_length=get_length(a_ptr);
334
  if (a_length > max_length)
335
    a_length=max_length;
336
  b_length=get_length(b_ptr);
337
  if (b_length > max_length)
338
    b_length=max_length;
398.1.4 by Monty Taylor
Renamed max/min.
339
  diff=memcmp(a,b,cmin(a_length,b_length));
173.1.2 by Toru Maesaka
forgot to bzr-add new files in the previous push
340
  return diff ? diff : (int) (a_length - b_length);
341
}
342
343
344
/* The following is used only when comparing a key */
345
482 by Brian Aker
Remove uint.
346
uint32_t Field_blob::get_key_image(unsigned char *buff,
347
                               uint32_t length,
212.1.3 by Monty Taylor
Renamed __attribute__((__unused__)) to __attribute__((unused)).
348
                               imagetype type_arg __attribute__((unused)))
173.1.2 by Toru Maesaka
forgot to bzr-add new files in the previous push
349
{
350
  uint32_t blob_length= get_length(ptr);
481 by Brian Aker
Remove all of uchar.
351
  unsigned char *blob;
173.1.2 by Toru Maesaka
forgot to bzr-add new files in the previous push
352
353
  get_ptr(&blob);
482 by Brian Aker
Remove uint.
354
  uint32_t local_char_length= length / field_charset->mbmaxlen;
173.1.2 by Toru Maesaka
forgot to bzr-add new files in the previous push
355
  local_char_length= my_charpos(field_charset, blob, blob + blob_length,
356
                          local_char_length);
357
  set_if_smaller(blob_length, local_char_length);
358
359
  if ((uint32_t) length > blob_length)
360
  {
361
    /*
362
      Must clear this as we do a memcmp in opt_range.cc to detect
363
      identical keys
364
    */
212.6.1 by Mats Kindahl
Replacing all bzero() calls with memset() calls and removing the bzero.c file.
365
    memset(buff+HA_KEY_BLOB_LENGTH+blob_length, 0, (length-blob_length));
173.1.2 by Toru Maesaka
forgot to bzr-add new files in the previous push
366
    length=(uint) blob_length;
367
  }
368
  int2store(buff,length);
369
  memcpy(buff+HA_KEY_BLOB_LENGTH, blob, length);
370
  return HA_KEY_BLOB_LENGTH+length;
371
}
372
373
482 by Brian Aker
Remove uint.
374
void Field_blob::set_key_image(const unsigned char *buff,uint32_t length)
173.1.2 by Toru Maesaka
forgot to bzr-add new files in the previous push
375
{
376
  length= uint2korr(buff);
377
  (void) Field_blob::store((const char*) buff+HA_KEY_BLOB_LENGTH, length,
378
                           field_charset);
379
}
380
381
482 by Brian Aker
Remove uint.
382
int Field_blob::key_cmp(const unsigned char *key_ptr, uint32_t max_key_length)
173.1.2 by Toru Maesaka
forgot to bzr-add new files in the previous push
383
{
481 by Brian Aker
Remove all of uchar.
384
  unsigned char *blob1;
482 by Brian Aker
Remove uint.
385
  uint32_t blob_length=get_length(ptr);
212.6.3 by Mats Kindahl
Removing deprecated functions from code and replacing them with C99 equivalents:
386
  memcpy(&blob1,ptr+packlength,sizeof(char*));
264.2.6 by Andrey Hristov
Constify the usage of CHARSET_INFO almost to the last place in the code.
387
  const CHARSET_INFO * const cs= charset();
482 by Brian Aker
Remove uint.
388
  uint32_t local_char_length= max_key_length / cs->mbmaxlen;
173.1.2 by Toru Maesaka
forgot to bzr-add new files in the previous push
389
  local_char_length= my_charpos(cs, blob1, blob1+blob_length,
390
                                local_char_length);
391
  set_if_smaller(blob_length, local_char_length);
392
  return Field_blob::cmp(blob1, blob_length,
393
			 key_ptr+HA_KEY_BLOB_LENGTH,
394
			 uint2korr(key_ptr));
395
}
396
481 by Brian Aker
Remove all of uchar.
397
int Field_blob::key_cmp(const unsigned char *a,const unsigned char *b)
173.1.2 by Toru Maesaka
forgot to bzr-add new files in the previous push
398
{
399
  return Field_blob::cmp(a+HA_KEY_BLOB_LENGTH, uint2korr(a),
400
			 b+HA_KEY_BLOB_LENGTH, uint2korr(b));
401
}
402
403
404
/**
405
   Save the field metadata for blob fields.
406
407
   Saves the pack length in the first byte of the field metadata array
408
   at index of *metadata_ptr.
409
410
   @param   metadata_ptr   First byte of field metadata
411
412
   @returns number of bytes written to metadata_ptr
413
*/
481 by Brian Aker
Remove all of uchar.
414
int Field_blob::do_save_field_metadata(unsigned char *metadata_ptr)
173.1.2 by Toru Maesaka
forgot to bzr-add new files in the previous push
415
{
416
  *metadata_ptr= pack_length_no_ptr();
417
  return 1;
418
}
419
420
421
uint32_t Field_blob::sort_length() const
422
{
520.1.22 by Brian Aker
Second pass of thd cleanup
423
  return (uint32_t) (current_session->variables.max_sort_length + 
173.1.2 by Toru Maesaka
forgot to bzr-add new files in the previous push
424
                   (field_charset == &my_charset_bin ? 0 : packlength));
425
}
426
427
482 by Brian Aker
Remove uint.
428
void Field_blob::sort_string(unsigned char *to,uint32_t length)
173.1.2 by Toru Maesaka
forgot to bzr-add new files in the previous push
429
{
481 by Brian Aker
Remove all of uchar.
430
  unsigned char *blob;
482 by Brian Aker
Remove uint.
431
  uint32_t blob_length=get_length();
173.1.2 by Toru Maesaka
forgot to bzr-add new files in the previous push
432
433
  if (!blob_length)
212.6.1 by Mats Kindahl
Replacing all bzero() calls with memset() calls and removing the bzero.c file.
434
    memset(to, 0, length);
173.1.2 by Toru Maesaka
forgot to bzr-add new files in the previous push
435
  else
436
  {
437
    if (field_charset == &my_charset_bin)
438
    {
481 by Brian Aker
Remove all of uchar.
439
      unsigned char *pos;
173.1.2 by Toru Maesaka
forgot to bzr-add new files in the previous push
440
441
      /*
442
        Store length of blob last in blob to shorter blobs before longer blobs
443
      */
444
      length-= packlength;
445
      pos= to+length;
446
447
      switch (packlength) {
448
      case 1:
449
        *pos= (char) blob_length;
450
        break;
451
      case 2:
452
        mi_int2store(pos, blob_length);
453
        break;
454
      case 3:
455
        mi_int3store(pos, blob_length);
456
        break;
457
      case 4:
458
        mi_int4store(pos, blob_length);
459
        break;
460
      }
461
    }
212.6.3 by Mats Kindahl
Removing deprecated functions from code and replacing them with C99 equivalents:
462
    memcpy(&blob,ptr+packlength,sizeof(char*));
173.1.2 by Toru Maesaka
forgot to bzr-add new files in the previous push
463
    
464
    blob_length=my_strnxfrm(field_charset,
465
                            to, length, blob, blob_length);
466
    assert(blob_length == length);
467
  }
468
}
469
470
471
void Field_blob::sql_type(String &res) const
472
{
473
  if (charset() == &my_charset_bin)
221 by Brian Aker
First pass of removing length types for ints.
474
    res.set_ascii(STRING_WITH_LEN("blob"));
173.1.2 by Toru Maesaka
forgot to bzr-add new files in the previous push
475
  else
221 by Brian Aker
First pass of removing length types for ints.
476
    res.set_ascii(STRING_WITH_LEN("text"));
173.1.2 by Toru Maesaka
forgot to bzr-add new files in the previous push
477
}
478
481 by Brian Aker
Remove all of uchar.
479
unsigned char *Field_blob::pack(unsigned char *to, const unsigned char *from,
482 by Brian Aker
Remove uint.
480
                        uint32_t max_length, bool low_byte_first)
173.1.2 by Toru Maesaka
forgot to bzr-add new files in the previous push
481
{
481 by Brian Aker
Remove all of uchar.
482
  unsigned char *save= ptr;
483
  ptr= (unsigned char*) from;
173.1.2 by Toru Maesaka
forgot to bzr-add new files in the previous push
484
  uint32_t length=get_length();			// Length of from string
485
486
  /*
487
    Store max length, which will occupy packlength bytes. If the max
488
    length given is smaller than the actual length of the blob, we
489
    just store the initial bytes of the blob.
490
  */
398.1.4 by Monty Taylor
Renamed max/min.
491
  store_length(to, packlength, cmin(length, max_length), low_byte_first);
173.1.2 by Toru Maesaka
forgot to bzr-add new files in the previous push
492
493
  /*
494
    Store the actual blob data, which will occupy 'length' bytes.
495
   */
496
  if (length > 0)
497
  {
481 by Brian Aker
Remove all of uchar.
498
    get_ptr((unsigned char**) &from);
173.1.2 by Toru Maesaka
forgot to bzr-add new files in the previous push
499
    memcpy(to+packlength, from,length);
500
  }
501
  ptr=save;					// Restore org row pointer
502
  return(to+packlength+length);
503
}
504
505
506
/**
507
   Unpack a blob field from row data.
508
509
   This method is used to unpack a blob field from a master whose size of 
510
   the field is less than that of the slave. Note: This method is included
511
   to satisfy inheritance rules, but is not needed for blob fields. It
512
   simply is used as a pass-through to the original unpack() method for
513
   blob fields.
514
515
   @param   to         Destination of the data
516
   @param   from       Source of the data
517
   @param   param_data @c true if base types should be stored in little-
518
                       endian format, @c false if native format should
519
                       be used.
520
521
   @return  New pointer into memory based on from + length of the data
522
*/
481 by Brian Aker
Remove all of uchar.
523
const unsigned char *Field_blob::unpack(unsigned char *to __attribute__((unused)),
524
                                const unsigned char *from,
482 by Brian Aker
Remove uint.
525
                                uint32_t param_data,
173.1.2 by Toru Maesaka
forgot to bzr-add new files in the previous push
526
                                bool low_byte_first)
527
{
482 by Brian Aker
Remove uint.
528
  uint32_t const master_packlength=
173.1.2 by Toru Maesaka
forgot to bzr-add new files in the previous push
529
    param_data > 0 ? param_data & 0xFF : packlength;
530
  uint32_t const length= get_length(from, master_packlength, low_byte_first);
531
  bitmap_set_bit(table->write_set, field_index);
532
  store(reinterpret_cast<const char*>(from) + master_packlength,
533
        length, field_charset);
534
  return(from + master_packlength + length);
535
}
536
537
/* Keys for blobs are like keys on varchars */
538
482 by Brian Aker
Remove uint.
539
int Field_blob::pack_cmp(const unsigned char *a, const unsigned char *b, uint32_t key_length_arg,
275 by Brian Aker
Full removal of my_bool from central server.
540
                         bool insert_or_update)
173.1.2 by Toru Maesaka
forgot to bzr-add new files in the previous push
541
{
482 by Brian Aker
Remove uint.
542
  uint32_t a_length, b_length;
173.1.2 by Toru Maesaka
forgot to bzr-add new files in the previous push
543
  if (key_length_arg > 255)
544
  {
545
    a_length=uint2korr(a); a+=2;
546
    b_length=uint2korr(b); b+=2;
547
  }
548
  else
549
  {
550
    a_length= (uint) *a++;
551
    b_length= (uint) *b++;
552
  }
553
  return field_charset->coll->strnncollsp(field_charset,
554
                                          a, a_length,
555
                                          b, b_length,
556
                                          insert_or_update);
557
}
558
559
482 by Brian Aker
Remove uint.
560
int Field_blob::pack_cmp(const unsigned char *b, uint32_t key_length_arg,
275 by Brian Aker
Full removal of my_bool from central server.
561
                         bool insert_or_update)
173.1.2 by Toru Maesaka
forgot to bzr-add new files in the previous push
562
{
481 by Brian Aker
Remove all of uchar.
563
  unsigned char *a;
482 by Brian Aker
Remove uint.
564
  uint32_t a_length, b_length;
212.6.3 by Mats Kindahl
Removing deprecated functions from code and replacing them with C99 equivalents:
565
  memcpy(&a,ptr+packlength,sizeof(char*));
173.1.2 by Toru Maesaka
forgot to bzr-add new files in the previous push
566
  if (!a)
567
    return key_length_arg > 0 ? -1 : 0;
568
569
  a_length= get_length(ptr);
570
  if (key_length_arg > 255)
571
  {
572
    b_length= uint2korr(b); b+=2;
573
  }
574
  else
575
    b_length= (uint) *b++;
576
  return field_charset->coll->strnncollsp(field_charset,
577
                                          a, a_length,
578
                                          b, b_length,
579
                                          insert_or_update);
580
}
581
582
/** Create a packed key that will be used for storage from a MySQL row. */
583
481 by Brian Aker
Remove all of uchar.
584
unsigned char *
482 by Brian Aker
Remove uint.
585
Field_blob::pack_key(unsigned char *to, const unsigned char *from, uint32_t max_length,
173.1.2 by Toru Maesaka
forgot to bzr-add new files in the previous push
586
                     bool low_byte_first __attribute__((unused)))
587
{
481 by Brian Aker
Remove all of uchar.
588
  unsigned char *save= ptr;
589
  ptr= (unsigned char*) from;
173.1.2 by Toru Maesaka
forgot to bzr-add new files in the previous push
590
  uint32_t length=get_length();        // Length of from string
482 by Brian Aker
Remove uint.
591
  uint32_t local_char_length= ((field_charset->mbmaxlen > 1) ?
173.1.2 by Toru Maesaka
forgot to bzr-add new files in the previous push
592
                           max_length/field_charset->mbmaxlen : max_length);
593
  if (length)
481 by Brian Aker
Remove all of uchar.
594
    get_ptr((unsigned char**) &from);
173.1.2 by Toru Maesaka
forgot to bzr-add new files in the previous push
595
  if (length > local_char_length)
596
    local_char_length= my_charpos(field_charset, from, from+length,
597
                                  local_char_length);
598
  set_if_smaller(length, local_char_length);
481 by Brian Aker
Remove all of uchar.
599
  *to++= (unsigned char) length;
173.1.2 by Toru Maesaka
forgot to bzr-add new files in the previous push
600
  if (max_length > 255)				// 2 byte length
481 by Brian Aker
Remove all of uchar.
601
    *to++= (unsigned char) (length >> 8);
173.1.2 by Toru Maesaka
forgot to bzr-add new files in the previous push
602
  memcpy(to, from, length);
603
  ptr=save;					// Restore org row pointer
604
  return to+length;
605
}
606
607
608
/**
609
  Unpack a blob key into a record buffer.
610
611
  A blob key has a maximum size of 64K-1.
612
  In its packed form, the length field is one or two bytes long,
613
  depending on 'max_length'.
614
  Depending on the maximum length of a blob, its length field is
615
  put into 1 to 4 bytes. This is a property of the blob object,
616
  described by 'packlength'.
617
  Blobs are internally stored apart from the record buffer, which
618
  contains a pointer to the blob buffer.
619
620
621
  @param to                          Pointer into the record buffer.
622
  @param from                        Pointer to the packed key.
623
  @param max_length                  Key length limit from key description.
624
625
  @return
626
    Pointer into 'from' past the last byte copied from packed key.
627
*/
628
481 by Brian Aker
Remove all of uchar.
629
const unsigned char *
482 by Brian Aker
Remove uint.
630
Field_blob::unpack_key(unsigned char *to, const unsigned char *from, uint32_t max_length,
173.1.2 by Toru Maesaka
forgot to bzr-add new files in the previous push
631
                       bool low_byte_first __attribute__((unused)))
632
{
633
  /* get length of the blob key */
634
  uint32_t length= *from++;
635
  if (max_length > 255)
636
    length+= *from++ << 8;
637
638
  /* put the length into the record buffer */
639
  put_length(to, length);
640
641
  /* put the address of the blob buffer or NULL */
642
  if (length)
212.6.3 by Mats Kindahl
Removing deprecated functions from code and replacing them with C99 equivalents:
643
    memcpy(to + packlength, &from, sizeof(from));
173.1.2 by Toru Maesaka
forgot to bzr-add new files in the previous push
644
  else
212.6.1 by Mats Kindahl
Replacing all bzero() calls with memset() calls and removing the bzero.c file.
645
    memset(to + packlength, 0, sizeof(from));
173.1.2 by Toru Maesaka
forgot to bzr-add new files in the previous push
646
647
  /* point to first byte of next field in 'from' */
648
  return from + length;
649
}
650
651
652
/** Create a packed key that will be used for storage from a MySQL key. */
653
481 by Brian Aker
Remove all of uchar.
654
unsigned char *
482 by Brian Aker
Remove uint.
655
Field_blob::pack_key_from_key_image(unsigned char *to, const unsigned char *from, uint32_t max_length,
173.1.2 by Toru Maesaka
forgot to bzr-add new files in the previous push
656
                                    bool low_byte_first __attribute__((unused)))
657
{
482 by Brian Aker
Remove uint.
658
  uint32_t length=uint2korr(from);
173.1.2 by Toru Maesaka
forgot to bzr-add new files in the previous push
659
  if (length > max_length)
660
    length=max_length;
661
  *to++= (char) (length & 255);
662
  if (max_length > 255)
663
    *to++= (char) (length >> 8);
664
  if (length)
665
    memcpy(to, from+HA_KEY_BLOB_LENGTH, length);
666
  return to+length;
667
}
668
669
482 by Brian Aker
Remove uint.
670
uint32_t Field_blob::packed_col_length(const unsigned char *data_ptr, uint32_t length)
173.1.2 by Toru Maesaka
forgot to bzr-add new files in the previous push
671
{
672
  if (length > 255)
673
    return uint2korr(data_ptr)+2;
674
  return (uint) *data_ptr + 1;
675
}
676
677
482 by Brian Aker
Remove uint.
678
uint32_t Field_blob::max_packed_col_length(uint32_t max_length)
173.1.2 by Toru Maesaka
forgot to bzr-add new files in the previous push
679
{
680
  return (max_length > 255 ? 2 : 1)+max_length;
681
}
682
683
482 by Brian Aker
Remove uint.
684
uint32_t Field_blob::is_equal(Create_field *new_field)
173.1.2 by Toru Maesaka
forgot to bzr-add new files in the previous push
685
{
686
  if (compare_str_field_flags(new_field, flags))
687
    return 0;
688
689
  return ((new_field->sql_type == get_blob_type_from_length(max_data_length()))
690
          && new_field->charset == field_charset &&
691
          ((Field_blob *)new_field->field)->max_data_length() ==
692
          max_data_length());
693
}
694
695
696
/**
697
  maximum possible display length for blob.
698
699
  @return
700
    length
701
*/
702
703
uint32_t Field_blob::max_display_length()
704
{
705
  switch (packlength)
706
  {
707
  case 1:
708
    return 255 * field_charset->mbmaxlen;
709
  case 2:
710
    return 65535 * field_charset->mbmaxlen;
711
  case 3:
712
    return 16777215 * field_charset->mbmaxlen;
713
  case 4:
714
    return (uint32_t) 4294967295U;
715
  default:
716
    assert(0); // we should never go here
717
    return 0;
718
  }
719
}
720