~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to sql/field_conv.cc

  • Committer: brian
  • Date: 2008-06-25 05:29:13 UTC
  • Revision ID: brian@localhost.localdomain-20080625052913-6upwo0jsrl4lnapl
clean slate

Show diffs side-by-side

added added

removed removed

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