~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to drizzled/field_conv.cc

Merge of Jay

Show diffs side-by-side

added added

removed removed

Lines of Context:
25
25
*/
26
26
 
27
27
#include <drizzled/server_includes.h>
28
 
 
29
 
static void do_field_eq(Copy_field *copy)
30
 
{
31
 
  memcpy(copy->to_ptr,copy->from_ptr,copy->from_length);
32
 
}
33
 
 
34
 
static void do_field_1(Copy_field *copy)
35
 
{
36
 
  copy->to_ptr[0]=copy->from_ptr[0];
37
 
}
38
 
 
39
 
static void do_field_2(Copy_field *copy)
40
 
{
41
 
  copy->to_ptr[0]=copy->from_ptr[0];
42
 
  copy->to_ptr[1]=copy->from_ptr[1];
43
 
}
44
 
 
45
 
static void do_field_3(Copy_field *copy)
46
 
{
47
 
  copy->to_ptr[0]=copy->from_ptr[0];
48
 
  copy->to_ptr[1]=copy->from_ptr[1];
49
 
  copy->to_ptr[2]=copy->from_ptr[2];
50
 
}
51
 
 
52
 
static void do_field_4(Copy_field *copy)
53
 
{
54
 
  copy->to_ptr[0]=copy->from_ptr[0];
55
 
  copy->to_ptr[1]=copy->from_ptr[1];
56
 
  copy->to_ptr[2]=copy->from_ptr[2];
57
 
  copy->to_ptr[3]=copy->from_ptr[3];
58
 
}
59
 
 
60
 
static void do_field_6(Copy_field *copy)
61
 
{                                               // For blob field
62
 
  copy->to_ptr[0]=copy->from_ptr[0];
63
 
  copy->to_ptr[1]=copy->from_ptr[1];
64
 
  copy->to_ptr[2]=copy->from_ptr[2];
65
 
  copy->to_ptr[3]=copy->from_ptr[3];
66
 
  copy->to_ptr[4]=copy->from_ptr[4];
67
 
  copy->to_ptr[5]=copy->from_ptr[5];
68
 
}
69
 
 
70
 
static void do_field_8(Copy_field *copy)
71
 
{
72
 
  copy->to_ptr[0]=copy->from_ptr[0];
73
 
  copy->to_ptr[1]=copy->from_ptr[1];
74
 
  copy->to_ptr[2]=copy->from_ptr[2];
75
 
  copy->to_ptr[3]=copy->from_ptr[3];
76
 
  copy->to_ptr[4]=copy->from_ptr[4];
77
 
  copy->to_ptr[5]=copy->from_ptr[5];
78
 
  copy->to_ptr[6]=copy->from_ptr[6];
79
 
  copy->to_ptr[7]=copy->from_ptr[7];
80
 
}
81
 
 
82
 
 
83
 
static void do_field_to_null_str(Copy_field *copy)
 
28
#include <drizzled/error.h>
 
29
#include <drizzled/table.h>
 
30
#include <drizzled/session.h>
 
31
 
 
32
#include <drizzled/field/str.h>
 
33
#include <drizzled/field/num.h>
 
34
#include <drizzled/field/blob.h>
 
35
#include <drizzled/field/enum.h>
 
36
#include <drizzled/field/null.h>
 
37
#include <drizzled/field/date.h>
 
38
#include <drizzled/field/decimal.h>
 
39
#include <drizzled/field/real.h>
 
40
#include <drizzled/field/double.h>
 
41
#include <drizzled/field/long.h>
 
42
#include <drizzled/field/int64_t.h>
 
43
#include <drizzled/field/num.h>
 
44
#include <drizzled/field/timestamp.h>
 
45
#include <drizzled/field/datetime.h>
 
46
#include <drizzled/field/varstring.h>
 
47
 
 
48
 
 
49
static void do_field_eq(CopyField *copy)
 
50
{
 
51
  memcpy(copy->to_ptr, copy->from_ptr, copy->from_length);
 
52
}
 
53
 
 
54
static void do_field_1(CopyField *copy)
 
55
{
 
56
  copy->to_ptr[0]= copy->from_ptr[0];
 
57
}
 
58
 
 
59
static void do_field_2(CopyField *copy)
 
60
{
 
61
  copy->to_ptr[0]= copy->from_ptr[0];
 
62
  copy->to_ptr[1]= copy->from_ptr[1];
 
63
}
 
64
 
 
65
static void do_field_3(CopyField *copy)
 
66
{
 
67
  copy->to_ptr[0]= copy->from_ptr[0];
 
68
  copy->to_ptr[1]= copy->from_ptr[1];
 
69
  copy->to_ptr[2]= copy->from_ptr[2];
 
70
}
 
71
 
 
72
static void do_field_4(CopyField *copy)
 
73
{
 
74
  copy->to_ptr[0]= copy->from_ptr[0];
 
75
  copy->to_ptr[1]= copy->from_ptr[1];
 
76
  copy->to_ptr[2]= copy->from_ptr[2];
 
77
  copy->to_ptr[3]= copy->from_ptr[3];
 
78
}
 
79
 
 
80
static void do_field_6(CopyField *copy)
 
81
{                  // For blob field
 
82
  copy->to_ptr[0]= copy->from_ptr[0];
 
83
  copy->to_ptr[1]= copy->from_ptr[1];
 
84
  copy->to_ptr[2]= copy->from_ptr[2];
 
85
  copy->to_ptr[3]= copy->from_ptr[3];
 
86
  copy->to_ptr[4]= copy->from_ptr[4];
 
87
  copy->to_ptr[5]= copy->from_ptr[5];
 
88
}
 
89
 
 
90
static void do_field_8(CopyField *copy)
 
91
{
 
92
  copy->to_ptr[0]= copy->from_ptr[0];
 
93
  copy->to_ptr[1]= copy->from_ptr[1];
 
94
  copy->to_ptr[2]= copy->from_ptr[2];
 
95
  copy->to_ptr[3]= copy->from_ptr[3];
 
96
  copy->to_ptr[4]= copy->from_ptr[4];
 
97
  copy->to_ptr[5]= copy->from_ptr[5];
 
98
  copy->to_ptr[6]= copy->from_ptr[6];
 
99
  copy->to_ptr[7]= copy->from_ptr[7];
 
100
}
 
101
 
 
102
 
 
103
static void do_field_to_null_str(CopyField *copy)
84
104
{
85
105
  if (*copy->from_null_ptr & copy->from_bit)
86
106
  {
87
107
    memset(copy->to_ptr, 0, copy->from_length);
88
 
    copy->to_null_ptr[0]=1;                     // Always bit 1
 
108
    copy->to_null_ptr[0]= 1;  // Always bit 1
89
109
  }
90
110
  else
91
111
  {
92
 
    copy->to_null_ptr[0]=0;
93
 
    memcpy(copy->to_ptr,copy->from_ptr,copy->from_length);
 
112
    copy->to_null_ptr[0]= 0;
 
113
    memcpy(copy->to_ptr, copy->from_ptr, copy->from_length);
94
114
  }
95
115
}
96
116
 
97
117
 
98
 
static void do_outer_field_to_null_str(Copy_field *copy)
 
118
static void do_outer_field_to_null_str(CopyField *copy)
99
119
{
100
120
  if (*copy->null_row ||
101
121
      (copy->from_null_ptr && (*copy->from_null_ptr & copy->from_bit)))
102
122
  {
103
123
    memset(copy->to_ptr, 0, copy->from_length);
104
 
    copy->to_null_ptr[0]=1;                     // Always bit 1
 
124
    copy->to_null_ptr[0]= 1;  // Always bit 1
105
125
  }
106
126
  else
107
127
  {
108
 
    copy->to_null_ptr[0]=0;
109
 
    memcpy(copy->to_ptr,copy->from_ptr,copy->from_length);
 
128
    copy->to_null_ptr[0]= 0;
 
129
    memcpy(copy->to_ptr, copy->from_ptr, copy->from_length);
110
130
  }
111
131
}
112
132
 
188
208
}
189
209
 
190
210
 
191
 
static void do_skip(Copy_field *copy __attribute__((unused)))
 
211
static void do_skip(CopyField *)
192
212
{
193
213
}
194
214
 
195
215
 
196
 
static void do_copy_null(Copy_field *copy)
 
216
static void do_copy_null(CopyField *copy)
197
217
{
198
218
  if (*copy->from_null_ptr & copy->from_bit)
199
219
  {
200
 
    *copy->to_null_ptr|=copy->to_bit;
 
220
    *copy->to_null_ptr|= copy->to_bit;
201
221
    copy->to_field->reset();
202
222
  }
203
223
  else
208
228
}
209
229
 
210
230
 
211
 
static void do_outer_field_null(Copy_field *copy)
 
231
static void do_outer_field_null(CopyField *copy)
212
232
{
213
233
  if (*copy->null_row ||
214
234
      (copy->from_null_ptr && (*copy->from_null_ptr & copy->from_bit)))
224
244
}
225
245
 
226
246
 
227
 
static void do_copy_not_null(Copy_field *copy)
 
247
static void do_copy_not_null(CopyField *copy)
228
248
{
229
249
  if (*copy->from_null_ptr & copy->from_bit)
230
250
  {
237
257
}
238
258
 
239
259
 
240
 
static void do_copy_maybe_null(Copy_field *copy)
 
260
static void do_copy_maybe_null(CopyField *copy)
241
261
{
242
262
  *copy->to_null_ptr&= ~copy->to_bit;
243
263
  (copy->do_copy2)(copy);
245
265
 
246
266
/* timestamp and next_number has special handling in case of NULL values */
247
267
 
248
 
static void do_copy_timestamp(Copy_field *copy)
 
268
static void do_copy_timestamp(CopyField *copy)
249
269
{
250
270
  if (*copy->from_null_ptr & copy->from_bit)
251
271
  {
257
277
}
258
278
 
259
279
 
260
 
static void do_copy_next_number(Copy_field *copy)
 
280
static void do_copy_next_number(CopyField *copy)
261
281
{
262
282
  if (*copy->from_null_ptr & copy->from_bit)
263
283
  {
270
290
}
271
291
 
272
292
 
273
 
static void do_copy_blob(Copy_field *copy)
 
293
static void do_copy_blob(CopyField *copy)
274
294
{
275
 
  ulong length=((Field_blob*) copy->from_field)->get_length();
 
295
  ulong length= ((Field_blob*) copy->from_field)->get_length();
276
296
  ((Field_blob*) copy->to_field)->store_length(length);
277
 
  memcpy(copy->to_ptr,copy->from_ptr,sizeof(char*));
 
297
  memcpy(copy->to_ptr, copy->from_ptr, sizeof(char*));
278
298
}
279
299
 
280
 
static void do_conv_blob(Copy_field *copy)
 
300
static void do_conv_blob(CopyField *copy)
281
301
{
282
302
  copy->from_field->val_str(&copy->tmp);
283
303
  ((Field_blob *) copy->to_field)->store(copy->tmp.ptr(),
284
 
                                         copy->tmp.length(),
285
 
                                         copy->tmp.charset());
 
304
                                         copy->tmp.length(),
 
305
                                         copy->tmp.charset());
286
306
}
287
307
 
288
308
/** Save blob in copy->tmp for GROUP BY. */
289
309
 
290
 
static void do_save_blob(Copy_field *copy)
 
310
static void do_save_blob(CopyField *copy)
291
311
{
292
312
  char buff[MAX_FIELD_WIDTH];
293
 
  String res(buff,sizeof(buff),copy->tmp.charset());
 
313
  String res(buff, sizeof(buff), copy->tmp.charset());
294
314
  copy->from_field->val_str(&res);
295
315
  copy->tmp.copy(res);
296
316
  ((Field_blob *) copy->to_field)->store(copy->tmp.ptr(),
297
 
                                         copy->tmp.length(),
298
 
                                         copy->tmp.charset());
 
317
                                         copy->tmp.length(),
 
318
                                         copy->tmp.charset());
299
319
}
300
320
 
301
321
 
302
 
static void do_field_string(Copy_field *copy)
 
322
static void do_field_string(CopyField *copy)
303
323
{
304
324
  char buff[MAX_FIELD_WIDTH];
305
325
  copy->tmp.set_quick(buff,sizeof(buff),copy->tmp.charset());
309
329
}
310
330
 
311
331
 
312
 
static void do_field_enum(Copy_field *copy)
 
332
static void do_field_enum(CopyField *copy)
313
333
{
314
334
  if (copy->from_field->val_int() == 0)
315
335
    ((Field_enum *) copy->to_field)->store_type((uint64_t) 0);
318
338
}
319
339
 
320
340
 
321
 
static void do_field_int(Copy_field *copy)
 
341
static void do_field_int(CopyField *copy)
322
342
{
323
343
  int64_t value= copy->from_field->val_int();
324
344
  copy->to_field->store(value,
325
345
                        test(copy->from_field->flags & UNSIGNED_FLAG));
326
346
}
327
347
 
328
 
static void do_field_real(Copy_field *copy)
 
348
static void do_field_real(CopyField *copy)
329
349
{
330
350
  double value=copy->from_field->val_real();
331
351
  copy->to_field->store(value);
332
352
}
333
353
 
334
354
 
335
 
static void do_field_decimal(Copy_field *copy)
 
355
static void do_field_decimal(CopyField *copy)
336
356
{
337
357
  my_decimal value;
338
358
  copy->to_field->store_decimal(copy->from_field->val_decimal(&value));
344
364
  from string.
345
365
*/
346
366
 
347
 
static void do_cut_string(Copy_field *copy)
 
367
static void do_cut_string(CopyField *copy)
348
368
{
349
369
  const CHARSET_INFO * const cs= copy->from_field->charset();
350
370
  memcpy(copy->to_ptr,copy->from_ptr,copy->to_length);
366
386
  from string.
367
387
*/
368
388
 
369
 
static void do_cut_string_complex(Copy_field *copy)
 
389
static void do_cut_string_complex(CopyField *copy)
370
390
{                                               // Shorter string field
371
391
  int well_formed_error;
372
392
  const CHARSET_INFO * const cs= copy->from_field->charset();
373
 
  const uchar *from_end= copy->from_ptr + copy->from_length;
374
 
  uint copy_length= cs->cset->well_formed_len(cs,
 
393
  const unsigned char *from_end= copy->from_ptr + copy->from_length;
 
394
  uint32_t copy_length= cs->cset->well_formed_len(cs,
375
395
                                              (char*) copy->from_ptr,
376
 
                                              (char*) from_end, 
 
396
                                              (char*) from_end,
377
397
                                              copy->to_length / cs->mbmaxlen,
378
398
                                              &well_formed_error);
379
399
  if (copy->to_length < copy_length)
398
418
 
399
419
 
400
420
 
401
 
static void do_expand_binary(Copy_field *copy)
402
 
{
403
 
  const CHARSET_INFO * const cs= copy->from_field->charset();
404
 
  memcpy(copy->to_ptr,copy->from_ptr,copy->from_length);
405
 
  cs->cset->fill(cs, (char*) copy->to_ptr+copy->from_length,
406
 
                     copy->to_length-copy->from_length, '\0');
407
 
}
408
 
 
409
 
 
410
 
 
411
 
static void do_expand_string(Copy_field *copy)
412
 
{
413
 
  const CHARSET_INFO * const cs= copy->from_field->charset();
414
 
  memcpy(copy->to_ptr,copy->from_ptr,copy->from_length);
415
 
  cs->cset->fill(cs, (char*) copy->to_ptr+copy->from_length,
416
 
                     copy->to_length-copy->from_length, ' ');
417
 
}
418
 
 
419
 
 
420
 
static void do_varstring1(Copy_field *copy)
421
 
{
422
 
  uint length= (uint) *(uchar*) copy->from_ptr;
 
421
static void do_expand_binary(CopyField *copy)
 
422
{
 
423
  const CHARSET_INFO * const cs= copy->from_field->charset();
 
424
  memcpy(copy->to_ptr, copy->from_ptr, copy->from_length);
 
425
  cs->cset->fill(cs, (char*) copy->to_ptr+copy->from_length,
 
426
                 copy->to_length-copy->from_length, '\0');
 
427
}
 
428
 
 
429
 
 
430
 
 
431
static void do_expand_string(CopyField *copy)
 
432
{
 
433
  const CHARSET_INFO * const cs= copy->from_field->charset();
 
434
  memcpy(copy->to_ptr,copy->from_ptr,copy->from_length);
 
435
  cs->cset->fill(cs, (char*) copy->to_ptr+copy->from_length,
 
436
                 copy->to_length-copy->from_length, ' ');
 
437
}
 
438
 
 
439
 
 
440
static void do_varstring1(CopyField *copy)
 
441
{
 
442
  uint32_t length= (uint32_t) *(unsigned char*) copy->from_ptr;
423
443
  if (length > copy->to_length- 1)
424
444
  {
425
 
    length=copy->to_length - 1;
 
445
    length= copy->to_length - 1;
426
446
    if (copy->from_field->table->in_use->count_cuted_fields)
427
447
      copy->to_field->set_warning(DRIZZLE_ERROR::WARN_LEVEL_WARN,
428
448
                                  ER_WARN_DATA_TRUNCATED, 1);
429
449
  }
430
 
  *(uchar*) copy->to_ptr= (uchar) length;
 
450
  *(unsigned char*) copy->to_ptr= (unsigned char) length;
431
451
  memcpy(copy->to_ptr+1, copy->from_ptr + 1, length);
432
452
}
433
453
 
434
454
 
435
 
static void do_varstring1_mb(Copy_field *copy)
 
455
static void do_varstring1_mb(CopyField *copy)
436
456
{
437
457
  int well_formed_error;
438
458
  const CHARSET_INFO * const cs= copy->from_field->charset();
439
 
  uint from_length= (uint) *(uchar*) copy->from_ptr;
440
 
  const uchar *from_ptr= copy->from_ptr + 1;
441
 
  uint to_char_length= (copy->to_length - 1) / cs->mbmaxlen;
442
 
  uint length= cs->cset->well_formed_len(cs, (char*) from_ptr,
 
459
  uint32_t from_length= (uint32_t) *(unsigned char*) copy->from_ptr;
 
460
  const unsigned char *from_ptr= copy->from_ptr + 1;
 
461
  uint32_t to_char_length= (copy->to_length - 1) / cs->mbmaxlen;
 
462
  uint32_t length= cs->cset->well_formed_len(cs, (char*) from_ptr,
443
463
                                         (char*) from_ptr + from_length,
444
464
                                         to_char_length, &well_formed_error);
445
465
  if (length < from_length)
446
466
  {
447
 
    if (current_thd->count_cuted_fields)
 
467
    if (current_session->count_cuted_fields)
448
468
      copy->to_field->set_warning(DRIZZLE_ERROR::WARN_LEVEL_WARN,
449
469
                                  ER_WARN_DATA_TRUNCATED, 1);
450
470
  }
451
 
  *copy->to_ptr= (uchar) length;
 
471
  *copy->to_ptr= (unsigned char) length;
452
472
  memcpy(copy->to_ptr + 1, from_ptr, length);
453
473
}
454
474
 
455
475
 
456
 
static void do_varstring2(Copy_field *copy)
 
476
static void do_varstring2(CopyField *copy)
457
477
{
458
 
  uint length=uint2korr(copy->from_ptr);
 
478
  uint32_t length= uint2korr(copy->from_ptr);
459
479
  if (length > copy->to_length- HA_KEY_BLOB_LENGTH)
460
480
  {
461
481
    length=copy->to_length-HA_KEY_BLOB_LENGTH;
469
489
}
470
490
 
471
491
 
472
 
static void do_varstring2_mb(Copy_field *copy)
 
492
static void do_varstring2_mb(CopyField *copy)
473
493
{
474
494
  int well_formed_error;
475
495
  const CHARSET_INFO * const cs= copy->from_field->charset();
476
 
  uint char_length= (copy->to_length - HA_KEY_BLOB_LENGTH) / cs->mbmaxlen;
477
 
  uint from_length= uint2korr(copy->from_ptr);
478
 
  const uchar *from_beg= copy->from_ptr + HA_KEY_BLOB_LENGTH;
479
 
  uint length= cs->cset->well_formed_len(cs, (char*) from_beg,
480
 
                                         (char*) from_beg + from_length,
481
 
                                         char_length, &well_formed_error);
 
496
  uint32_t char_length= (copy->to_length - HA_KEY_BLOB_LENGTH) / cs->mbmaxlen;
 
497
  uint32_t from_length= uint2korr(copy->from_ptr);
 
498
  const unsigned char *from_beg= copy->from_ptr + HA_KEY_BLOB_LENGTH;
 
499
  uint32_t length= cs->cset->well_formed_len(cs, (char*) from_beg,
 
500
                                             (char*) from_beg + from_length,
 
501
                                             char_length, &well_formed_error);
482
502
  if (length < from_length)
483
503
  {
484
 
    if (current_thd->count_cuted_fields)
 
504
    if (current_session->count_cuted_fields)
485
505
      copy->to_field->set_warning(DRIZZLE_ERROR::WARN_LEVEL_WARN,
486
506
                                  ER_WARN_DATA_TRUNCATED, 1);
487
 
  }  
 
507
  }
488
508
  int2store(copy->to_ptr, length);
489
509
  memcpy(copy->to_ptr+HA_KEY_BLOB_LENGTH, from_beg, length);
490
510
}
491
 
 
 
511
 
492
512
 
493
513
/***************************************************************************
494
 
** The different functions that fills in a Copy_field class
 
514
** The different functions that fills in a CopyField class
495
515
***************************************************************************/
496
516
 
497
517
/**
502
522
  The 'to' buffer should have a size of field->pack_length()+1
503
523
*/
504
524
 
505
 
void Copy_field::set(uchar *to,Field *from)
 
525
void CopyField::set(unsigned char *to,Field *from)
506
526
{
507
 
  from_ptr=from->ptr;
508
 
  to_ptr=to;
509
 
  from_length=from->pack_length();
 
527
  from_ptr= from->ptr;
 
528
  to_ptr= to;
 
529
  from_length= from->pack_length();
510
530
  if (from->maybe_null())
511
531
  {
512
 
    from_null_ptr=from->null_ptr;
513
 
    from_bit=     from->null_bit;
514
 
    to_ptr[0]=    1;                            // Null as default value
515
 
    to_null_ptr=  (uchar*) to_ptr++;
516
 
    to_bit=       1;
 
532
    from_null_ptr= from->null_ptr;
 
533
    from_bit= from->null_bit;
 
534
    to_ptr[0]= 1;                             // Null as default value
 
535
    to_null_ptr= (unsigned char*) to_ptr++;
 
536
    to_bit= 1;
517
537
    if (from->table->maybe_null)
518
538
    {
519
 
      null_row=   &from->table->null_row;
520
 
      do_copy=    do_outer_field_to_null_str;
 
539
      null_row= &from->table->null_row;
 
540
      do_copy= do_outer_field_to_null_str;
521
541
    }
522
542
    else
523
 
      do_copy=    do_field_to_null_str;
 
543
      do_copy= do_field_to_null_str;
524
544
  }
525
545
  else
526
546
  {
527
 
    to_null_ptr=  0;                            // For easy debugging
528
 
    do_copy=      do_field_eq;
 
547
    to_null_ptr= 0;                           // For easy debugging
 
548
    do_copy= do_field_eq;
529
549
  }
530
550
}
531
551
 
532
552
 
533
553
/*
534
 
  To do: 
 
554
  To do:
535
555
 
536
556
  If 'save\ is set to true and the 'from' is a blob field, do_copy is set to
537
557
  do_save_blob rather than do_conv_blob.  The only differences between them
538
558
  appears to be:
539
559
 
540
 
  - do_save_blob allocates and uses an intermediate buffer before calling 
541
 
    Field_blob::store. Is this in order to trigger the call to 
 
560
  - do_save_blob allocates and uses an intermediate buffer before calling
 
561
    Field_blob::store. Is this in order to trigger the call to
542
562
    well_formed_copy_nchars, by changing the pointer copy->tmp.ptr()?
543
563
    That call will take place anyway in all known cases.
544
564
 
545
 
  - The above causes a truncation to MAX_FIELD_WIDTH. Is this the intended 
 
565
  - The above causes a truncation to MAX_FIELD_WIDTH. Is this the intended
546
566
    effect? Truncation is handled by well_formed_copy_nchars anyway.
547
567
 */
548
 
void Copy_field::set(Field *to,Field *from,bool save)
 
568
void CopyField::set(Field *to,Field *from,bool save)
549
569
{
550
570
  if (to->type() == DRIZZLE_TYPE_NULL)
551
571
  {
552
 
    to_null_ptr=0;                              // For easy debugging
553
 
    to_ptr=0;
554
 
    do_copy=do_skip;
 
572
    to_null_ptr= 0;           // For easy debugging
 
573
    to_ptr= 0;
 
574
    do_copy= do_skip;
555
575
    return;
556
576
  }
557
 
  from_field=from;
558
 
  to_field=to;
559
 
  from_ptr=from->ptr;
560
 
  from_length=from->pack_length();
561
 
  to_ptr=  to->ptr;
562
 
  to_length=to_field->pack_length();
 
577
  from_field= from;
 
578
  to_field= to;
 
579
  from_ptr= from->ptr;
 
580
  from_length= from->pack_length();
 
581
  to_ptr= to->ptr;
 
582
  to_length= to_field->pack_length();
563
583
 
564
584
  // set up null handling
565
 
  from_null_ptr=to_null_ptr=0;
 
585
  from_null_ptr= to_null_ptr= 0;
566
586
  if (from->maybe_null())
567
587
  {
568
 
    from_null_ptr=      from->null_ptr;
569
 
    from_bit=           from->null_bit;
 
588
    from_null_ptr= from->null_ptr;
 
589
    from_bit= from->null_bit;
570
590
    if (to_field->real_maybe_null())
571
591
    {
572
 
      to_null_ptr=      to->null_ptr;
573
 
      to_bit=           to->null_bit;
 
592
      to_null_ptr= to->null_ptr;
 
593
      to_bit= to->null_bit;
574
594
      if (from_null_ptr)
575
 
        do_copy=        do_copy_null;
 
595
        do_copy= do_copy_null;
576
596
      else
577
597
      {
578
 
        null_row=       &from->table->null_row;
579
 
        do_copy=        do_outer_field_null;
 
598
        null_row= &from->table->null_row;
 
599
        do_copy= do_outer_field_null;
580
600
      }
581
601
    }
582
602
    else
591
611
  }
592
612
  else if (to_field->real_maybe_null())
593
613
  {
594
 
    to_null_ptr=        to->null_ptr;
595
 
    to_bit=             to->null_bit;
 
614
    to_null_ptr= to->null_ptr;
 
615
    to_bit= to->null_bit;
596
616
    do_copy= do_copy_maybe_null;
597
617
  }
598
618
  else
599
 
   do_copy=0;
 
619
   do_copy= 0;
600
620
 
601
621
  if ((to->flags & BLOB_FLAG) && save)
602
622
    do_copy2= do_save_blob;
603
623
  else
604
624
    do_copy2= get_copy_func(to,from);
605
 
  if (!do_copy)                                 // Not null
606
 
    do_copy=do_copy2;
 
625
  if (!do_copy)         // Not null
 
626
    do_copy= do_copy2;
607
627
}
608
628
 
609
629
 
610
 
Copy_field::Copy_func *
611
 
Copy_field::get_copy_func(Field *to,Field *from)
 
630
CopyField::Copy_func *
 
631
CopyField::get_copy_func(Field *to,Field *from)
612
632
{
613
633
  bool compatible_db_low_byte_first= (to->table->s->db_low_byte_first ==
614
634
                                     from->table->s->db_low_byte_first);
619
639
    if (from_length != to_length || !compatible_db_low_byte_first)
620
640
    {
621
641
      // Correct pointer to point at char pointer
622
 
      to_ptr+=   to_length - to->table->s->blob_ptr_size;
 
642
      to_ptr+= to_length - to->table->s->blob_ptr_size;
623
643
      from_ptr+= from_length- from->table->s->blob_ptr_size;
624
644
      return do_copy_blob;
625
645
    }
628
648
  {
629
649
    if (to->result_type() == DECIMAL_RESULT)
630
650
      return do_field_decimal;
 
651
      
631
652
    // Check if identical fields
632
653
    if (from->result_type() == STRING_RESULT)
633
654
    {
637
658
      */
638
659
      if (to->real_type() != from->real_type() ||
639
660
          !compatible_db_low_byte_first ||
640
 
          (((to->table->in_use->variables.sql_mode & (MODE_NO_ZERO_IN_DATE | MODE_NO_ZERO_DATE | MODE_INVALID_DATES)) && to->type() == DRIZZLE_TYPE_NEWDATE) || to->type() == DRIZZLE_TYPE_DATETIME))
 
661
          (((to->table->in_use->variables.sql_mode & (MODE_NO_ZERO_DATE | MODE_INVALID_DATES)) && to->type() == DRIZZLE_TYPE_DATE) || to->type() == DRIZZLE_TYPE_DATETIME))
641
662
      {
642
 
        if (from->real_type() == DRIZZLE_TYPE_ENUM)
643
 
          if (to->result_type() != STRING_RESULT)
644
 
            return do_field_int;                // Convert SET to number
645
 
        return do_field_string;
 
663
        if (from->real_type() == DRIZZLE_TYPE_ENUM)
 
664
        {
 
665
          if (to->result_type() != STRING_RESULT)
 
666
          {
 
667
            return do_field_int;  // Convert SET to number
 
668
          }
 
669
          
 
670
          return do_field_string;
 
671
        }
646
672
      }
 
673
      
647
674
      if (to->real_type() == DRIZZLE_TYPE_ENUM)
648
675
      {
649
 
        if (!to->eq_def(from))
 
676
        if (!to->eq_def(from))
650
677
        {
651
678
          if (from->real_type() == DRIZZLE_TYPE_ENUM &&
652
679
              to->real_type() == DRIZZLE_TYPE_ENUM)
656
683
        }
657
684
      }
658
685
      else if (to->charset() != from->charset())
659
 
        return do_field_string;
 
686
        return do_field_string;
660
687
      else if (to->real_type() == DRIZZLE_TYPE_VARCHAR)
661
688
      {
662
689
        if (((Field_varstring*) to)->length_bytes !=
663
690
            ((Field_varstring*) from)->length_bytes)
 
691
        {
664
692
          return do_field_string;
 
693
        }
 
694
        
665
695
        if (to_length != from_length)
 
696
        {
666
697
          return (((Field_varstring*) to)->length_bytes == 1 ?
667
698
                  (from->charset()->mbmaxlen == 1 ? do_varstring1 :
668
699
                                                    do_varstring1_mb) :
669
700
                  (from->charset()->mbmaxlen == 1 ? do_varstring2 :
670
701
                                                    do_varstring2_mb));
 
702
        }
671
703
      }
672
704
      else if (to_length < from_length)
673
 
        return (from->charset()->mbmaxlen == 1 ?
 
705
      {
 
706
        return (from->charset()->mbmaxlen == 1 ?
674
707
                do_cut_string : do_cut_string_complex);
 
708
      }
675
709
      else if (to_length > from_length)
676
710
      {
677
711
        if (to->charset() == &my_charset_bin)
679
713
        else
680
714
          return do_expand_string;
681
715
      }
682
 
 
683
716
    }
684
717
    else if (to->real_type() != from->real_type() ||
685
 
             to_length != from_length ||
 
718
             to_length != from_length ||
686
719
             !compatible_db_low_byte_first)
687
720
    {
688
721
      if (to->result_type() == STRING_RESULT)
689
 
        return do_field_string;
 
722
        return do_field_string;
690
723
      if (to->result_type() == INT_RESULT)
691
 
        return do_field_int;
 
724
        return do_field_int;
 
725
 
692
726
      return do_field_real;
693
727
    }
694
728
    else
695
729
    {
696
730
      if (!to->eq_def(from) || !compatible_db_low_byte_first)
697
731
      {
698
 
        if (to->result_type() == INT_RESULT)
699
 
          return do_field_int;
700
 
        else
701
 
          return do_field_real;
 
732
        if (to->result_type() == INT_RESULT)
 
733
          return do_field_int;
 
734
        else
 
735
          return do_field_real;
702
736
      }
703
737
    }
704
738
  }
 
739
  
705
740
    /* Eq fields */
706
 
  switch (to_length) {
 
741
  switch (to_length)
 
742
  {
707
743
  case 1: return do_field_1;
708
744
  case 2: return do_field_2;
709
745
  case 3: return do_field_3;
711
747
  case 6: return do_field_6;
712
748
  case 8: return do_field_8;
713
749
  }
 
750
  
714
751
  return do_field_eq;
715
752
}
716
753
 
723
760
      !(to->type() == DRIZZLE_TYPE_BLOB && to->table->copy_blobs))
724
761
  {
725
762
    /* Please god, will someone rewrite this to be readable :( */
726
 
    if (to->pack_length() == from->pack_length() && 
727
 
        !(to->flags & UNSIGNED_FLAG && !(from->flags & UNSIGNED_FLAG)) && 
728
 
        to->real_type() != DRIZZLE_TYPE_ENUM && 
 
763
    if (to->pack_length() == from->pack_length() &&
 
764
        !(to->flags & UNSIGNED_FLAG && !(from->flags & UNSIGNED_FLAG)) &&
 
765
        to->real_type() != DRIZZLE_TYPE_ENUM &&
729
766
        (to->real_type() != DRIZZLE_TYPE_NEWDECIMAL || (to->field_length == from->field_length && (((Field_num*)to)->dec == ((Field_num*)from)->dec))) &&
730
767
        from->charset() == to->charset() &&
731
768
        to->table->s->db_low_byte_first == from->table->s->db_low_byte_first &&
732
 
        (!(to->table->in_use->variables.sql_mode & (MODE_NO_ZERO_IN_DATE | MODE_NO_ZERO_DATE | MODE_INVALID_DATES)) || (to->type() != DRIZZLE_TYPE_NEWDATE && to->type() != DRIZZLE_TYPE_DATETIME)) && 
 
769
        (!(to->table->in_use->variables.sql_mode & (MODE_NO_ZERO_DATE | MODE_INVALID_DATES)) || (to->type() != DRIZZLE_TYPE_DATE && to->type() != DRIZZLE_TYPE_DATETIME)) &&
733
770
        (from->real_type() != DRIZZLE_TYPE_VARCHAR || ((Field_varstring*)from)->length_bytes == ((Field_varstring*)to)->length_bytes))
734
771
    {                                           // Identical fields
735
 
#ifdef HAVE_purify
736
772
      /* This may happen if one does 'UPDATE ... SET x=x' */
737
773
      if (to->ptr != from->ptr)
738
 
#endif
739
774
        memcpy(to->ptr,from->ptr,to->pack_length());
740
775
      return 0;
741
776
    }