~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to drizzled/field_conv.cc

  • Committer: Brian Aker
  • Date: 2009-01-09 22:07:54 UTC
  • Revision ID: brian@tangent.org-20090109220754-1y50h7lqi9i1ifcs
Dead test/wrong test.

Show diffs side-by-side

added added

removed removed

Lines of Context:
11
11
 
12
12
   You should have received a copy of the GNU General Public License
13
13
   along with this program; if not, write to the Free Software
14
 
   Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA */
 
14
   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA */
15
15
 
16
16
 
17
17
/**
24
24
    gives much more speed.
25
25
*/
26
26
 
27
 
#include "config.h"
 
27
#include <drizzled/server_includes.h>
28
28
#include <drizzled/error.h>
29
29
#include <drizzled/table.h>
30
30
#include <drizzled/session.h>
31
31
 
32
32
#include <drizzled/field/str.h>
 
33
#include <drizzled/field/longstr.h>
33
34
#include <drizzled/field/num.h>
34
35
#include <drizzled/field/blob.h>
35
36
#include <drizzled/field/enum.h>
38
39
#include <drizzled/field/decimal.h>
39
40
#include <drizzled/field/real.h>
40
41
#include <drizzled/field/double.h>
41
 
#include <drizzled/field/int32.h>
42
 
#include <drizzled/field/int64.h>
 
42
#include <drizzled/field/long.h>
 
43
#include <drizzled/field/int64_t.h>
43
44
#include <drizzled/field/num.h>
 
45
#include <drizzled/field/timetype.h>
44
46
#include <drizzled/field/timestamp.h>
45
47
#include <drizzled/field/datetime.h>
46
48
#include <drizzled/field/varstring.h>
47
49
 
48
 
namespace drizzled
49
 
{
50
 
 
51
 
static void do_field_eq(CopyField *copy)
52
 
{
53
 
  memcpy(copy->to_ptr, copy->from_ptr, copy->from_length);
54
 
}
55
 
 
56
 
static void do_field_1(CopyField *copy)
57
 
{
58
 
  copy->to_ptr[0]= copy->from_ptr[0];
59
 
}
60
 
 
61
 
static void do_field_2(CopyField *copy)
62
 
{
63
 
  copy->to_ptr[0]= copy->from_ptr[0];
64
 
  copy->to_ptr[1]= copy->from_ptr[1];
65
 
}
66
 
 
67
 
static void do_field_3(CopyField *copy)
68
 
{
69
 
  copy->to_ptr[0]= copy->from_ptr[0];
70
 
  copy->to_ptr[1]= copy->from_ptr[1];
71
 
  copy->to_ptr[2]= copy->from_ptr[2];
72
 
}
73
 
 
74
 
static void do_field_4(CopyField *copy)
75
 
{
76
 
  copy->to_ptr[0]= copy->from_ptr[0];
77
 
  copy->to_ptr[1]= copy->from_ptr[1];
78
 
  copy->to_ptr[2]= copy->from_ptr[2];
79
 
  copy->to_ptr[3]= copy->from_ptr[3];
80
 
}
81
 
 
82
 
static void do_field_6(CopyField *copy)
83
 
{                  // For blob field
84
 
  copy->to_ptr[0]= copy->from_ptr[0];
85
 
  copy->to_ptr[1]= copy->from_ptr[1];
86
 
  copy->to_ptr[2]= copy->from_ptr[2];
87
 
  copy->to_ptr[3]= copy->from_ptr[3];
88
 
  copy->to_ptr[4]= copy->from_ptr[4];
89
 
  copy->to_ptr[5]= copy->from_ptr[5];
90
 
}
91
 
 
92
 
static void do_field_8(CopyField *copy)
93
 
{
94
 
  copy->to_ptr[0]= copy->from_ptr[0];
95
 
  copy->to_ptr[1]= copy->from_ptr[1];
96
 
  copy->to_ptr[2]= copy->from_ptr[2];
97
 
  copy->to_ptr[3]= copy->from_ptr[3];
98
 
  copy->to_ptr[4]= copy->from_ptr[4];
99
 
  copy->to_ptr[5]= copy->from_ptr[5];
100
 
  copy->to_ptr[6]= copy->from_ptr[6];
101
 
  copy->to_ptr[7]= copy->from_ptr[7];
102
 
}
103
 
 
104
 
 
105
 
static void do_field_to_null_str(CopyField *copy)
 
50
 
 
51
static void do_field_eq(Copy_field *copy)
 
52
{
 
53
  memcpy(copy->to_ptr,copy->from_ptr,copy->from_length);
 
54
}
 
55
 
 
56
static void do_field_1(Copy_field *copy)
 
57
{
 
58
  copy->to_ptr[0]=copy->from_ptr[0];
 
59
}
 
60
 
 
61
static void do_field_2(Copy_field *copy)
 
62
{
 
63
  copy->to_ptr[0]=copy->from_ptr[0];
 
64
  copy->to_ptr[1]=copy->from_ptr[1];
 
65
}
 
66
 
 
67
static void do_field_3(Copy_field *copy)
 
68
{
 
69
  copy->to_ptr[0]=copy->from_ptr[0];
 
70
  copy->to_ptr[1]=copy->from_ptr[1];
 
71
  copy->to_ptr[2]=copy->from_ptr[2];
 
72
}
 
73
 
 
74
static void do_field_4(Copy_field *copy)
 
75
{
 
76
  copy->to_ptr[0]=copy->from_ptr[0];
 
77
  copy->to_ptr[1]=copy->from_ptr[1];
 
78
  copy->to_ptr[2]=copy->from_ptr[2];
 
79
  copy->to_ptr[3]=copy->from_ptr[3];
 
80
}
 
81
 
 
82
static void do_field_6(Copy_field *copy)
 
83
{                                               // For blob field
 
84
  copy->to_ptr[0]=copy->from_ptr[0];
 
85
  copy->to_ptr[1]=copy->from_ptr[1];
 
86
  copy->to_ptr[2]=copy->from_ptr[2];
 
87
  copy->to_ptr[3]=copy->from_ptr[3];
 
88
  copy->to_ptr[4]=copy->from_ptr[4];
 
89
  copy->to_ptr[5]=copy->from_ptr[5];
 
90
}
 
91
 
 
92
static void do_field_8(Copy_field *copy)
 
93
{
 
94
  copy->to_ptr[0]=copy->from_ptr[0];
 
95
  copy->to_ptr[1]=copy->from_ptr[1];
 
96
  copy->to_ptr[2]=copy->from_ptr[2];
 
97
  copy->to_ptr[3]=copy->from_ptr[3];
 
98
  copy->to_ptr[4]=copy->from_ptr[4];
 
99
  copy->to_ptr[5]=copy->from_ptr[5];
 
100
  copy->to_ptr[6]=copy->from_ptr[6];
 
101
  copy->to_ptr[7]=copy->from_ptr[7];
 
102
}
 
103
 
 
104
 
 
105
static void do_field_to_null_str(Copy_field *copy)
106
106
{
107
107
  if (*copy->from_null_ptr & copy->from_bit)
108
108
  {
109
109
    memset(copy->to_ptr, 0, copy->from_length);
110
 
    copy->to_null_ptr[0]= 1;  // Always bit 1
 
110
    copy->to_null_ptr[0]=1;                     // Always bit 1
111
111
  }
112
112
  else
113
113
  {
114
 
    copy->to_null_ptr[0]= 0;
115
 
    memcpy(copy->to_ptr, copy->from_ptr, copy->from_length);
 
114
    copy->to_null_ptr[0]=0;
 
115
    memcpy(copy->to_ptr,copy->from_ptr,copy->from_length);
116
116
  }
117
117
}
118
118
 
119
119
 
120
 
static void do_outer_field_to_null_str(CopyField *copy)
 
120
static void do_outer_field_to_null_str(Copy_field *copy)
121
121
{
122
122
  if (*copy->null_row ||
123
123
      (copy->from_null_ptr && (*copy->from_null_ptr & copy->from_bit)))
124
124
  {
125
125
    memset(copy->to_ptr, 0, copy->from_length);
126
 
    copy->to_null_ptr[0]= 1;  // Always bit 1
 
126
    copy->to_null_ptr[0]=1;                     // Always bit 1
127
127
  }
128
128
  else
129
129
  {
130
 
    copy->to_null_ptr[0]= 0;
131
 
    memcpy(copy->to_ptr, copy->from_ptr, copy->from_length);
 
130
    copy->to_null_ptr[0]=0;
 
131
    memcpy(copy->to_ptr,copy->from_ptr,copy->from_length);
132
132
  }
133
133
}
134
134
 
143
143
    return 0;
144
144
  }
145
145
  field->reset();
146
 
  if (field->getTable()->in_use->count_cuted_fields == CHECK_FIELD_WARN)
 
146
  if (field->table->in_use->count_cuted_fields == CHECK_FIELD_WARN)
147
147
  {
148
148
    field->set_warning(DRIZZLE_ERROR::WARN_LEVEL_WARN, ER_WARN_DATA_TRUNCATED, 1);
149
149
    return 0;
150
150
  }
151
 
  if (!field->getTable()->in_use->no_errors)
 
151
  if (!field->table->in_use->no_errors)
152
152
    my_error(ER_BAD_NULL_ERROR, MYF(0), field->field_name);
153
153
  return -1;
154
154
}
194
194
    return 0;                                   // Ok to set time to NULL
195
195
  }
196
196
  field->reset();
197
 
  if (field == field->getTable()->next_number_field)
 
197
  if (field == field->table->next_number_field)
198
198
  {
199
 
    field->getTable()->auto_increment_field_not_null= false;
 
199
    field->table->auto_increment_field_not_null= false;
200
200
    return 0;                             // field is set in fill_record()
201
201
  }
202
 
  if (field->getTable()->in_use->count_cuted_fields == CHECK_FIELD_WARN)
 
202
  if (field->table->in_use->count_cuted_fields == CHECK_FIELD_WARN)
203
203
  {
204
204
    field->set_warning(DRIZZLE_ERROR::WARN_LEVEL_WARN, ER_BAD_NULL_ERROR, 1);
205
205
    return 0;
206
206
  }
207
 
  if (!field->getTable()->in_use->no_errors)
 
207
  if (!field->table->in_use->no_errors)
208
208
    my_error(ER_BAD_NULL_ERROR, MYF(0), field->field_name);
209
209
  return -1;
210
210
}
211
211
 
212
212
 
213
 
static void do_skip(CopyField *)
 
213
static void do_skip(Copy_field *copy __attribute__((unused)))
214
214
{
215
215
}
216
216
 
217
217
 
218
 
static void do_copy_null(CopyField *copy)
 
218
static void do_copy_null(Copy_field *copy)
219
219
{
220
220
  if (*copy->from_null_ptr & copy->from_bit)
221
221
  {
222
 
    *copy->to_null_ptr|= copy->to_bit;
 
222
    *copy->to_null_ptr|=copy->to_bit;
223
223
    copy->to_field->reset();
224
224
  }
225
225
  else
230
230
}
231
231
 
232
232
 
233
 
static void do_outer_field_null(CopyField *copy)
 
233
static void do_outer_field_null(Copy_field *copy)
234
234
{
235
235
  if (*copy->null_row ||
236
236
      (copy->from_null_ptr && (*copy->from_null_ptr & copy->from_bit)))
246
246
}
247
247
 
248
248
 
249
 
static void do_copy_not_null(CopyField *copy)
 
249
static void do_copy_not_null(Copy_field *copy)
250
250
{
251
 
  if (copy->to_field->hasDefault() and *copy->from_null_ptr & copy->from_bit)
252
 
  {
253
 
    copy->to_field->set_default();
254
 
  }
255
 
  else if (*copy->from_null_ptr & copy->from_bit)
 
251
  if (*copy->from_null_ptr & copy->from_bit)
256
252
  {
257
253
    copy->to_field->set_warning(DRIZZLE_ERROR::WARN_LEVEL_WARN,
258
254
                                ER_WARN_DATA_TRUNCATED, 1);
259
255
    copy->to_field->reset();
260
256
  }
261
257
  else
262
 
  {
263
258
    (copy->do_copy2)(copy);
264
 
  }
265
259
}
266
260
 
267
261
 
268
 
static void do_copy_maybe_null(CopyField *copy)
 
262
static void do_copy_maybe_null(Copy_field *copy)
269
263
{
270
264
  *copy->to_null_ptr&= ~copy->to_bit;
271
265
  (copy->do_copy2)(copy);
273
267
 
274
268
/* timestamp and next_number has special handling in case of NULL values */
275
269
 
276
 
static void do_copy_timestamp(CopyField *copy)
 
270
static void do_copy_timestamp(Copy_field *copy)
277
271
{
278
272
  if (*copy->from_null_ptr & copy->from_bit)
279
273
  {
285
279
}
286
280
 
287
281
 
288
 
static void do_copy_next_number(CopyField *copy)
 
282
static void do_copy_next_number(Copy_field *copy)
289
283
{
290
284
  if (*copy->from_null_ptr & copy->from_bit)
291
285
  {
292
286
    /* Same as in set_field_to_null_with_conversions() */
293
 
    copy->to_field->getTable()->auto_increment_field_not_null= false;
 
287
    copy->to_field->table->auto_increment_field_not_null= false;
294
288
    copy->to_field->reset();
295
289
  }
296
290
  else
298
292
}
299
293
 
300
294
 
301
 
static void do_copy_blob(CopyField *copy)
 
295
static void do_copy_blob(Copy_field *copy)
302
296
{
303
 
  ulong length= ((Field_blob*) copy->from_field)->get_length();
 
297
  ulong length=((Field_blob*) copy->from_field)->get_length();
304
298
  ((Field_blob*) copy->to_field)->store_length(length);
305
 
  memcpy(copy->to_ptr, copy->from_ptr, sizeof(char*));
 
299
  memcpy(copy->to_ptr,copy->from_ptr,sizeof(char*));
306
300
}
307
301
 
308
 
static void do_conv_blob(CopyField *copy)
 
302
static void do_conv_blob(Copy_field *copy)
309
303
{
310
 
  copy->from_field->val_str_internal(&copy->tmp);
 
304
  copy->from_field->val_str(&copy->tmp);
311
305
  ((Field_blob *) copy->to_field)->store(copy->tmp.ptr(),
312
 
                                         copy->tmp.length(),
313
 
                                         copy->tmp.charset());
 
306
                                         copy->tmp.length(),
 
307
                                         copy->tmp.charset());
314
308
}
315
309
 
316
310
/** Save blob in copy->tmp for GROUP BY. */
317
311
 
318
 
static void do_save_blob(CopyField *copy)
 
312
static void do_save_blob(Copy_field *copy)
319
313
{
320
314
  char buff[MAX_FIELD_WIDTH];
321
 
  String res(buff, sizeof(buff), copy->tmp.charset());
322
 
  copy->from_field->val_str_internal(&res);
 
315
  String res(buff,sizeof(buff),copy->tmp.charset());
 
316
  copy->from_field->val_str(&res);
323
317
  copy->tmp.copy(res);
324
318
  ((Field_blob *) copy->to_field)->store(copy->tmp.ptr(),
325
 
                                         copy->tmp.length(),
326
 
                                         copy->tmp.charset());
 
319
                                         copy->tmp.length(),
 
320
                                         copy->tmp.charset());
327
321
}
328
322
 
329
323
 
330
 
static void do_field_string(CopyField *copy)
 
324
static void do_field_string(Copy_field *copy)
331
325
{
332
326
  char buff[MAX_FIELD_WIDTH];
333
327
  copy->tmp.set_quick(buff,sizeof(buff),copy->tmp.charset());
334
 
  copy->from_field->val_str_internal(&copy->tmp);
 
328
  copy->from_field->val_str(&copy->tmp);
335
329
  copy->to_field->store(copy->tmp.c_ptr_quick(),copy->tmp.length(),
336
330
                        copy->tmp.charset());
337
331
}
338
332
 
339
333
 
340
 
static void do_field_enum(CopyField *copy)
 
334
static void do_field_enum(Copy_field *copy)
341
335
{
342
336
  if (copy->from_field->val_int() == 0)
343
337
    ((Field_enum *) copy->to_field)->store_type((uint64_t) 0);
346
340
}
347
341
 
348
342
 
349
 
static void do_field_int(CopyField *copy)
 
343
static void do_field_int(Copy_field *copy)
350
344
{
351
345
  int64_t value= copy->from_field->val_int();
352
346
  copy->to_field->store(value,
353
347
                        test(copy->from_field->flags & UNSIGNED_FLAG));
354
348
}
355
349
 
356
 
static void do_field_real(CopyField *copy)
 
350
static void do_field_real(Copy_field *copy)
357
351
{
358
352
  double value=copy->from_field->val_real();
359
353
  copy->to_field->store(value);
360
354
}
361
355
 
362
356
 
363
 
static void do_field_decimal(CopyField *copy)
 
357
static void do_field_decimal(Copy_field *copy)
364
358
{
365
359
  my_decimal value;
366
360
  copy->to_field->store_decimal(copy->from_field->val_decimal(&value));
372
366
  from string.
373
367
*/
374
368
 
375
 
static void do_cut_string(CopyField *copy)
 
369
static void do_cut_string(Copy_field *copy)
376
370
{
377
371
  const CHARSET_INFO * const cs= copy->from_field->charset();
378
372
  memcpy(copy->to_ptr,copy->from_ptr,copy->to_length);
394
388
  from string.
395
389
*/
396
390
 
397
 
static void do_cut_string_complex(CopyField *copy)
 
391
static void do_cut_string_complex(Copy_field *copy)
398
392
{                                               // Shorter string field
399
393
  int well_formed_error;
400
394
  const CHARSET_INFO * const cs= copy->from_field->charset();
426
420
 
427
421
 
428
422
 
429
 
static void do_expand_binary(CopyField *copy)
430
 
{
431
 
  const CHARSET_INFO * const cs= copy->from_field->charset();
432
 
  memcpy(copy->to_ptr, copy->from_ptr, copy->from_length);
433
 
  cs->cset->fill(cs, (char*) copy->to_ptr+copy->from_length,
434
 
                 copy->to_length-copy->from_length, '\0');
435
 
}
436
 
 
437
 
 
438
 
 
439
 
static void do_expand_string(CopyField *copy)
440
 
{
441
 
  const CHARSET_INFO * const cs= copy->from_field->charset();
442
 
  memcpy(copy->to_ptr,copy->from_ptr,copy->from_length);
443
 
  cs->cset->fill(cs, (char*) copy->to_ptr+copy->from_length,
444
 
                 copy->to_length-copy->from_length, ' ');
445
 
}
446
 
 
447
 
 
448
 
static void do_varstring1(CopyField *copy)
449
 
{
450
 
  uint32_t length= (uint32_t) *(unsigned char*) copy->from_ptr;
 
423
static void do_expand_binary(Copy_field *copy)
 
424
{
 
425
  const CHARSET_INFO * const cs= copy->from_field->charset();
 
426
  memcpy(copy->to_ptr,copy->from_ptr,copy->from_length);
 
427
  cs->cset->fill(cs, (char*) copy->to_ptr+copy->from_length,
 
428
                     copy->to_length-copy->from_length, '\0');
 
429
}
 
430
 
 
431
 
 
432
 
 
433
static void do_expand_string(Copy_field *copy)
 
434
{
 
435
  const CHARSET_INFO * const cs= copy->from_field->charset();
 
436
  memcpy(copy->to_ptr,copy->from_ptr,copy->from_length);
 
437
  cs->cset->fill(cs, (char*) copy->to_ptr+copy->from_length,
 
438
                     copy->to_length-copy->from_length, ' ');
 
439
}
 
440
 
 
441
 
 
442
static void do_varstring1(Copy_field *copy)
 
443
{
 
444
  uint32_t length= (uint) *(unsigned char*) copy->from_ptr;
451
445
  if (length > copy->to_length- 1)
452
446
  {
453
 
    length= copy->to_length - 1;
454
 
    if (copy->from_field->getTable()->in_use->count_cuted_fields)
 
447
    length=copy->to_length - 1;
 
448
    if (copy->from_field->table->in_use->count_cuted_fields)
455
449
      copy->to_field->set_warning(DRIZZLE_ERROR::WARN_LEVEL_WARN,
456
450
                                  ER_WARN_DATA_TRUNCATED, 1);
457
451
  }
460
454
}
461
455
 
462
456
 
463
 
static void do_varstring1_mb(CopyField *copy)
 
457
static void do_varstring1_mb(Copy_field *copy)
464
458
{
465
459
  int well_formed_error;
466
460
  const CHARSET_INFO * const cs= copy->from_field->charset();
467
 
  uint32_t from_length= (uint32_t) *(unsigned char*) copy->from_ptr;
 
461
  uint32_t from_length= (uint) *(unsigned char*) copy->from_ptr;
468
462
  const unsigned char *from_ptr= copy->from_ptr + 1;
469
463
  uint32_t to_char_length= (copy->to_length - 1) / cs->mbmaxlen;
470
464
  uint32_t length= cs->cset->well_formed_len(cs, (char*) from_ptr,
481
475
}
482
476
 
483
477
 
484
 
static void do_varstring2(CopyField *copy)
 
478
static void do_varstring2(Copy_field *copy)
485
479
{
486
 
  uint32_t length= uint2korr(copy->from_ptr);
 
480
  uint32_t length=uint2korr(copy->from_ptr);
487
481
  if (length > copy->to_length- HA_KEY_BLOB_LENGTH)
488
482
  {
489
483
    length=copy->to_length-HA_KEY_BLOB_LENGTH;
490
 
    if (copy->from_field->getTable()->in_use->count_cuted_fields)
 
484
    if (copy->from_field->table->in_use->count_cuted_fields)
491
485
      copy->to_field->set_warning(DRIZZLE_ERROR::WARN_LEVEL_WARN,
492
486
                                  ER_WARN_DATA_TRUNCATED, 1);
493
487
  }
497
491
}
498
492
 
499
493
 
500
 
static void do_varstring2_mb(CopyField *copy)
 
494
static void do_varstring2_mb(Copy_field *copy)
501
495
{
502
496
  int well_formed_error;
503
497
  const CHARSET_INFO * const cs= copy->from_field->charset();
505
499
  uint32_t from_length= uint2korr(copy->from_ptr);
506
500
  const unsigned char *from_beg= copy->from_ptr + HA_KEY_BLOB_LENGTH;
507
501
  uint32_t length= cs->cset->well_formed_len(cs, (char*) from_beg,
508
 
                                             (char*) from_beg + from_length,
509
 
                                             char_length, &well_formed_error);
 
502
                                         (char*) from_beg + from_length,
 
503
                                         char_length, &well_formed_error);
510
504
  if (length < from_length)
511
505
  {
512
506
    if (current_session->count_cuted_fields)
519
513
 
520
514
 
521
515
/***************************************************************************
522
 
** The different functions that fills in a CopyField class
 
516
** The different functions that fills in a Copy_field class
523
517
***************************************************************************/
524
518
 
525
519
/**
530
524
  The 'to' buffer should have a size of field->pack_length()+1
531
525
*/
532
526
 
533
 
void CopyField::set(unsigned char *to,Field *from)
 
527
void Copy_field::set(unsigned char *to,Field *from)
534
528
{
535
 
  from_ptr= from->ptr;
536
 
  to_ptr= to;
537
 
  from_length= from->pack_length();
 
529
  from_ptr=from->ptr;
 
530
  to_ptr=to;
 
531
  from_length=from->pack_length();
538
532
  if (from->maybe_null())
539
533
  {
540
 
    from_null_ptr= from->null_ptr;
541
 
    from_bit= from->null_bit;
542
 
    to_ptr[0]= 1;                             // Null as default value
543
 
    to_null_ptr= (unsigned char*) to_ptr++;
544
 
    to_bit= 1;
545
 
    if (from->getTable()->maybe_null)
 
534
    from_null_ptr=from->null_ptr;
 
535
    from_bit=     from->null_bit;
 
536
    to_ptr[0]=    1;                            // Null as default value
 
537
    to_null_ptr=  (unsigned char*) to_ptr++;
 
538
    to_bit=       1;
 
539
    if (from->table->maybe_null)
546
540
    {
547
 
      null_row= &from->getTable()->null_row;
548
 
      do_copy= do_outer_field_to_null_str;
 
541
      null_row=   &from->table->null_row;
 
542
      do_copy=    do_outer_field_to_null_str;
549
543
    }
550
544
    else
551
 
      do_copy= do_field_to_null_str;
 
545
      do_copy=    do_field_to_null_str;
552
546
  }
553
547
  else
554
548
  {
555
 
    to_null_ptr= 0;                           // For easy debugging
556
 
    do_copy= do_field_eq;
 
549
    to_null_ptr=  0;                            // For easy debugging
 
550
    do_copy=      do_field_eq;
557
551
  }
558
552
}
559
553
 
573
567
  - The above causes a truncation to MAX_FIELD_WIDTH. Is this the intended
574
568
    effect? Truncation is handled by well_formed_copy_nchars anyway.
575
569
 */
576
 
void CopyField::set(Field *to,Field *from,bool save)
 
570
void Copy_field::set(Field *to,Field *from,bool save)
577
571
{
578
572
  if (to->type() == DRIZZLE_TYPE_NULL)
579
573
  {
580
 
    to_null_ptr= 0;           // For easy debugging
581
 
    to_ptr= 0;
582
 
    do_copy= do_skip;
 
574
    to_null_ptr=0;                              // For easy debugging
 
575
    to_ptr=0;
 
576
    do_copy=do_skip;
583
577
    return;
584
578
  }
585
 
  from_field= from;
586
 
  to_field= to;
587
 
  from_ptr= from->ptr;
588
 
  from_length= from->pack_length();
589
 
  to_ptr= to->ptr;
590
 
  to_length= to_field->pack_length();
 
579
  from_field=from;
 
580
  to_field=to;
 
581
  from_ptr=from->ptr;
 
582
  from_length=from->pack_length();
 
583
  to_ptr=  to->ptr;
 
584
  to_length=to_field->pack_length();
591
585
 
592
586
  // set up null handling
593
 
  from_null_ptr= to_null_ptr= 0;
 
587
  from_null_ptr=to_null_ptr=0;
594
588
  if (from->maybe_null())
595
589
  {
596
 
    from_null_ptr= from->null_ptr;
597
 
    from_bit= from->null_bit;
 
590
    from_null_ptr=      from->null_ptr;
 
591
    from_bit=           from->null_bit;
598
592
    if (to_field->real_maybe_null())
599
593
    {
600
 
      to_null_ptr= to->null_ptr;
601
 
      to_bit= to->null_bit;
 
594
      to_null_ptr=      to->null_ptr;
 
595
      to_bit=           to->null_bit;
602
596
      if (from_null_ptr)
603
 
      {
604
 
        do_copy= do_copy_null;
605
 
      }
 
597
        do_copy=        do_copy_null;
606
598
      else
607
599
      {
608
 
        null_row= &from->getTable()->null_row;
609
 
        do_copy= do_outer_field_null;
 
600
        null_row=       &from->table->null_row;
 
601
        do_copy=        do_outer_field_null;
610
602
      }
611
603
    }
612
604
    else
613
605
    {
614
606
      if (to_field->type() == DRIZZLE_TYPE_TIMESTAMP)
615
 
      {
616
607
        do_copy= do_copy_timestamp;               // Automatic timestamp
617
 
      }
618
 
      else if (to_field == to_field->getTable()->next_number_field)
619
 
      {
 
608
      else if (to_field == to_field->table->next_number_field)
620
609
        do_copy= do_copy_next_number;
621
 
      }
622
610
      else
623
 
      {
624
611
        do_copy= do_copy_not_null;
625
 
      }
626
612
    }
627
613
  }
628
614
  else if (to_field->real_maybe_null())
629
615
  {
630
 
    to_null_ptr= to->null_ptr;
631
 
    to_bit= to->null_bit;
 
616
    to_null_ptr=        to->null_ptr;
 
617
    to_bit=             to->null_bit;
632
618
    do_copy= do_copy_maybe_null;
633
619
  }
634
620
  else
635
 
   do_copy= 0;
 
621
   do_copy=0;
636
622
 
637
623
  if ((to->flags & BLOB_FLAG) && save)
638
624
    do_copy2= do_save_blob;
639
625
  else
640
626
    do_copy2= get_copy_func(to,from);
641
 
  if (!do_copy)         // Not null
642
 
    do_copy= do_copy2;
 
627
  if (!do_copy)                                 // Not null
 
628
    do_copy=do_copy2;
643
629
}
644
630
 
645
631
 
646
 
CopyField::Copy_func *
647
 
CopyField::get_copy_func(Field *to,Field *from)
 
632
Copy_field::Copy_func *
 
633
Copy_field::get_copy_func(Field *to,Field *from)
648
634
{
649
 
  bool compatible_db_low_byte_first= (to->getTable()->getShare()->db_low_byte_first ==
650
 
                                     from->getTable()->getShare()->db_low_byte_first);
 
635
  bool compatible_db_low_byte_first= (to->table->s->db_low_byte_first ==
 
636
                                     from->table->s->db_low_byte_first);
651
637
  if (to->flags & BLOB_FLAG)
652
638
  {
653
639
    if (!(from->flags & BLOB_FLAG) || from->charset() != to->charset())
655
641
    if (from_length != to_length || !compatible_db_low_byte_first)
656
642
    {
657
643
      // Correct pointer to point at char pointer
658
 
      to_ptr+= to_length - to->getTable()->getShare()->blob_ptr_size;
659
 
      from_ptr+= from_length- from->getTable()->getShare()->blob_ptr_size;
 
644
      to_ptr+=   to_length - to->table->s->blob_ptr_size;
 
645
      from_ptr+= from_length- from->table->s->blob_ptr_size;
660
646
      return do_copy_blob;
661
647
    }
662
648
  }
664
650
  {
665
651
    if (to->result_type() == DECIMAL_RESULT)
666
652
      return do_field_decimal;
667
 
      
668
653
    // Check if identical fields
669
654
    if (from->result_type() == STRING_RESULT)
670
655
    {
674
659
      */
675
660
      if (to->real_type() != from->real_type() ||
676
661
          !compatible_db_low_byte_first ||
677
 
          (((to->getTable()->in_use->variables.sql_mode & (MODE_NO_ZERO_DATE | MODE_INVALID_DATES)) && to->type() == DRIZZLE_TYPE_DATE) || to->type() == DRIZZLE_TYPE_DATETIME))
 
662
          (((to->table->in_use->variables.sql_mode & (MODE_NO_ZERO_DATE | MODE_INVALID_DATES)) && to->type() == DRIZZLE_TYPE_DATE) || to->type() == DRIZZLE_TYPE_DATETIME))
678
663
      {
679
 
        if (from->real_type() == DRIZZLE_TYPE_ENUM)
680
 
        {
681
 
          if (to->result_type() != STRING_RESULT)
682
 
          {
683
 
            return do_field_int;  // Convert SET to number
684
 
          }
685
 
 
686
 
          return do_field_string;
687
 
        }
 
664
        if (from->real_type() == DRIZZLE_TYPE_ENUM)
 
665
          if (to->result_type() != STRING_RESULT)
 
666
            return do_field_int;                // Convert SET to number
 
667
        return do_field_string;
688
668
      }
689
 
 
690
669
      if (to->real_type() == DRIZZLE_TYPE_ENUM)
691
670
      {
692
 
        if (!to->eq_def(from))
 
671
        if (!to->eq_def(from))
693
672
        {
694
673
          if (from->real_type() == DRIZZLE_TYPE_ENUM &&
695
674
              to->real_type() == DRIZZLE_TYPE_ENUM)
699
678
        }
700
679
      }
701
680
      else if (to->charset() != from->charset())
702
 
        return do_field_string;
 
681
        return do_field_string;
703
682
      else if (to->real_type() == DRIZZLE_TYPE_VARCHAR)
704
683
      {
705
 
        /* Field_blob is not part of the Field_varstring hierarchy,
706
 
          and casting to varstring for calling pack_length_no_ptr()
707
 
          is always incorrect. Previously the below comparison has
708
 
          always evaluated to false as pack_length_no_ptr() for BLOB
709
 
          will return 4 and varstring can only be <= 2.
710
 
          If your brain slightly bleeds as to why this worked for
711
 
          so many years, you are in no way alone.
712
 
        */
713
 
        if (from->flags & BLOB_FLAG)
714
 
          return do_field_string;
715
 
 
716
 
        if ((static_cast<Field_varstring*>(to))->pack_length_no_ptr() !=
717
 
            (static_cast<Field_varstring*>(from))->pack_length_no_ptr())
718
 
        {
719
 
          return do_field_string;
720
 
        }
721
 
 
 
684
        if (((Field_varstring*) to)->length_bytes !=
 
685
            ((Field_varstring*) from)->length_bytes)
 
686
          return do_field_string;
722
687
        if (to_length != from_length)
723
 
        {
724
 
          return (((Field_varstring*) to)->pack_length_no_ptr() == 1 ?
 
688
          return (((Field_varstring*) to)->length_bytes == 1 ?
725
689
                  (from->charset()->mbmaxlen == 1 ? do_varstring1 :
726
 
                   do_varstring1_mb) :
 
690
                                                    do_varstring1_mb) :
727
691
                  (from->charset()->mbmaxlen == 1 ? do_varstring2 :
728
 
                   do_varstring2_mb));
729
 
        }
 
692
                                                    do_varstring2_mb));
730
693
      }
731
694
      else if (to_length < from_length)
732
 
      {
733
 
        return (from->charset()->mbmaxlen == 1 ?
 
695
        return (from->charset()->mbmaxlen == 1 ?
734
696
                do_cut_string : do_cut_string_complex);
735
 
      }
736
697
      else if (to_length > from_length)
737
698
      {
738
699
        if (to->charset() == &my_charset_bin)
740
701
        else
741
702
          return do_expand_string;
742
703
      }
 
704
 
743
705
    }
744
706
    else if (to->real_type() != from->real_type() ||
745
 
             to_length != from_length ||
 
707
             to_length != from_length ||
746
708
             !compatible_db_low_byte_first)
747
709
    {
748
710
      if (to->result_type() == STRING_RESULT)
749
 
        return do_field_string;
 
711
        return do_field_string;
750
712
      if (to->result_type() == INT_RESULT)
751
 
        return do_field_int;
752
 
 
 
713
        return do_field_int;
753
714
      return do_field_real;
754
715
    }
755
716
    else
756
717
    {
757
718
      if (!to->eq_def(from) || !compatible_db_low_byte_first)
758
719
      {
759
 
        if (to->result_type() == INT_RESULT)
760
 
          return do_field_int;
761
 
        else
762
 
          return do_field_real;
 
720
        if (to->result_type() == INT_RESULT)
 
721
          return do_field_int;
 
722
        else
 
723
          return do_field_real;
763
724
      }
764
725
    }
765
726
  }
766
 
  
767
727
    /* Eq fields */
768
 
  switch (to_length)
769
 
  {
 
728
  switch (to_length) {
770
729
  case 1: return do_field_1;
771
730
  case 2: return do_field_2;
772
731
  case 3: return do_field_3;
774
733
  case 6: return do_field_6;
775
734
  case 8: return do_field_8;
776
735
  }
777
 
  
778
736
  return do_field_eq;
779
737
}
780
738
 
784
742
int field_conv(Field *to,Field *from)
785
743
{
786
744
  if (to->real_type() == from->real_type() &&
787
 
      !(to->type() == DRIZZLE_TYPE_BLOB && to->getTable()->copy_blobs))
 
745
      !(to->type() == DRIZZLE_TYPE_BLOB && to->table->copy_blobs))
788
746
  {
789
747
    /* Please god, will someone rewrite this to be readable :( */
790
748
    if (to->pack_length() == from->pack_length() &&
791
749
        !(to->flags & UNSIGNED_FLAG && !(from->flags & UNSIGNED_FLAG)) &&
792
750
        to->real_type() != DRIZZLE_TYPE_ENUM &&
793
 
        (to->real_type() != DRIZZLE_TYPE_DECIMAL || (to->field_length == from->field_length && (((Field_num*)to)->dec == ((Field_num*)from)->dec))) &&
 
751
        (to->real_type() != DRIZZLE_TYPE_NEWDECIMAL || (to->field_length == from->field_length && (((Field_num*)to)->dec == ((Field_num*)from)->dec))) &&
794
752
        from->charset() == to->charset() &&
795
 
        to->getTable()->getShare()->db_low_byte_first == from->getTable()->getShare()->db_low_byte_first &&
796
 
        (!(to->getTable()->in_use->variables.sql_mode & (MODE_NO_ZERO_DATE | MODE_INVALID_DATES)) || (to->type() != DRIZZLE_TYPE_DATE && to->type() != DRIZZLE_TYPE_DATETIME)) &&
797
 
        (from->real_type() != DRIZZLE_TYPE_VARCHAR || ((Field_varstring*)from)->pack_length_no_ptr() == ((Field_varstring*)to)->pack_length_no_ptr()))
 
753
        to->table->s->db_low_byte_first == from->table->s->db_low_byte_first &&
 
754
        (!(to->table->in_use->variables.sql_mode & (MODE_NO_ZERO_DATE | MODE_INVALID_DATES)) || (to->type() != DRIZZLE_TYPE_DATE && to->type() != DRIZZLE_TYPE_DATETIME)) &&
 
755
        (from->real_type() != DRIZZLE_TYPE_VARCHAR || ((Field_varstring*)from)->length_bytes == ((Field_varstring*)to)->length_bytes))
798
756
    {                                           // Identical fields
799
757
      /* This may happen if one does 'UPDATE ... SET x=x' */
800
758
      if (to->ptr != from->ptr)
805
763
  if (to->type() == DRIZZLE_TYPE_BLOB)
806
764
  {                                             // Be sure the value is stored
807
765
    Field_blob *blob=(Field_blob*) to;
808
 
    from->val_str_internal(&blob->value);
 
766
    from->val_str(&blob->value);
809
767
    /*
810
768
      Copy value if copy_blobs is set, or source is not a string and
811
769
      we have a pointer to its internal string conversion buffer.
812
770
    */
813
 
    if (to->getTable()->copy_blobs ||
 
771
    if (to->table->copy_blobs ||
814
772
        (!blob->value.is_alloced() &&
815
773
         from->real_type() != DRIZZLE_TYPE_VARCHAR))
816
774
      blob->value.copy();
829
787
  {
830
788
    char buff[MAX_FIELD_WIDTH];
831
789
    String result(buff,sizeof(buff),from->charset());
832
 
    from->val_str_internal(&result);
 
790
    from->val_str(&result);
833
791
    /*
834
792
      We use c_ptr_quick() here to make it easier if to is a float/double
835
793
      as the conversion routines will do a copy of the result doesn't
848
806
  else
849
807
    return to->store(from->val_int(), test(from->flags & UNSIGNED_FLAG));
850
808
}
851
 
 
852
 
} /* namespace drizzled */