~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to drizzled/field_conv.cc

  • Committer: Monty Taylor
  • Date: 2008-10-14 21:20:42 UTC
  • mto: (511.1.4 codestyle)
  • mto: This revision was merged to the branch mainline in revision 521.
  • Revision ID: monty@inaugust.com-20081014212042-tef3njx3368b6lwt
Override copy ctr and op= because we have pointer members.

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