~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to server/field_conv.cc

  • Committer: Jay Pipes
  • Date: 2008-07-17 18:48:58 UTC
  • mto: This revision was merged to the branch mainline in revision 182.
  • Revision ID: jay@mysql.com-20080717184858-2mbouxl8xi41gcge
Removed DBUG from CSV and Blackhole storage engines

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