~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to drizzled/create_field.cc

  • Committer: Olaf van der Spek
  • Date: 2011-10-10 09:27:50 UTC
  • mto: (2430.1.6 rf)
  • mto: This revision was merged to the branch mainline in revision 2436.
  • Revision ID: olafvdspek@gmail.com-20111010092750-ryxgmn7zj5yvxfkf
Refactor

Show diffs side-by-side

added added

removed removed

Lines of Context:
21
21
 * @file Implementation of CreateField class
22
22
 */
23
23
 
24
 
#include "config.h"
 
24
#include <config.h>
25
25
#include <errno.h>
26
26
#include <float.h>
27
 
#include "drizzled/sql_select.h"
28
 
#include "drizzled/error.h"
29
 
#include "drizzled/field.h"
30
 
#include "drizzled/create_field.h"
31
 
#include "drizzled/field/str.h"
32
 
#include "drizzled/field/num.h"
33
 
#include "drizzled/field/blob.h"
34
 
#include "drizzled/field/enum.h"
35
 
#include "drizzled/field/null.h"
36
 
#include "drizzled/field/date.h"
37
 
#include "drizzled/field/decimal.h"
38
 
#include "drizzled/field/real.h"
39
 
#include "drizzled/field/double.h"
40
 
#include "drizzled/field/int32.h"
41
 
#include "drizzled/field/int64.h"
42
 
#include "drizzled/field/num.h"
43
 
#include "drizzled/field/timestamp.h"
44
 
#include "drizzled/field/datetime.h"
45
 
#include "drizzled/field/varstring.h"
46
 
#include "drizzled/field/uuid.h"
47
 
#include "drizzled/temporal.h"
48
 
#include "drizzled/item/string.h"
 
27
#include <drizzled/sql_select.h>
 
28
#include <drizzled/error.h>
 
29
#include <drizzled/field.h>
 
30
#include <drizzled/create_field.h>
 
31
#include <drizzled/field/str.h>
 
32
#include <drizzled/field/num.h>
 
33
#include <drizzled/field/blob.h>
 
34
#include <drizzled/field/boolean.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/int32.h>
 
42
#include <drizzled/field/int64.h>
 
43
#include <drizzled/field/num.h>
 
44
#include <drizzled/field/epoch.h>
 
45
#include <drizzled/field/datetime.h>
 
46
#include <drizzled/field/varstring.h>
 
47
#include <drizzled/field/uuid.h>
 
48
#include <drizzled/field/ipv6.h>
 
49
#include <drizzled/temporal.h>
 
50
#include <drizzled/item/string.h>
 
51
#include <drizzled/table.h>
 
52
 
 
53
#include <drizzled/display.h>
49
54
 
50
55
#include <algorithm>
51
56
 
71
76
 
72
77
  /* Fix if the original table had 4 byte pointer blobs */
73
78
  if (flags & BLOB_FLAG)
74
 
    pack_length= (pack_length - old_field->getTable()->getShare()->blob_ptr_size + portable_sizeof_char_ptr);
 
79
  {
 
80
    pack_length= (pack_length - old_field->getTable()->getShare()->sizeBlobPtr() + portable_sizeof_char_ptr);
 
81
  }
75
82
 
76
83
  switch (sql_type) 
77
84
  {
99
106
  if (!(flags & (NO_DEFAULT_VALUE_FLAG)) &&
100
107
      !(flags & AUTO_INCREMENT_FLAG) &&
101
108
      old_field->ptr && orig_field &&
102
 
      (sql_type != DRIZZLE_TYPE_TIMESTAMP ||                /* set def only if */
 
109
      (not old_field->is_timestamp() ||                /* set def only if */
103
110
       old_field->getTable()->timestamp_field != old_field ||  /* timestamp field */
104
111
       unireg_check == Field::TIMESTAMP_UN_FIELD))        /* has default val */
105
112
  {
106
 
    ptrdiff_t diff;
107
 
 
108
113
    /* Get the value from default_values */
109
 
    diff= (ptrdiff_t) (orig_field->getTable()->getDefaultValues() - orig_field->getTable()->getInsertRecord());
 
114
    ptrdiff_t diff= (ptrdiff_t) (orig_field->getTable()->getDefaultValues() - orig_field->getTable()->getInsertRecord());
110
115
    orig_field->move_field_offset(diff);        // Points now at default_values
111
116
    if (! orig_field->is_real_null())
112
117
    {
113
 
      char buff[MAX_FIELD_WIDTH], *pos;
114
 
      String tmp(buff, sizeof(buff), charset), *res;
115
 
      res= orig_field->val_str_internal(&tmp);
116
 
      pos= (char*) memory::sql_strmake(res->ptr(), res->length());
 
118
      char buff[MAX_FIELD_WIDTH];
 
119
      String tmp(buff, sizeof(buff), charset);
 
120
      String* res= orig_field->val_str_internal(&tmp);
 
121
      char* pos= memory::sql_strdup(*res);
117
122
      def= new Item_string(pos, res->length(), charset);
118
123
    }
119
124
    orig_field->move_field_offset(-diff);       // Back to getInsertRecord()
140
145
      break;
141
146
    case DRIZZLE_TYPE_DECIMAL:
142
147
      key_length= pack_length=
143
 
        my_decimal_get_binary_size(my_decimal_length_to_precision(length,
 
148
        class_decimal_get_binary_size(class_decimal_length_to_precision(length,
144
149
                  decimals,
145
150
                  flags &
146
151
                  UNSIGNED_FLAG),
168
173
  charset= &my_charset_bin;
169
174
  decimals= decimals_arg & FIELDFLAG_MAX_DEC;
170
175
 
171
 
  if (! maybe_null)
172
 
    flags= NOT_NULL_FLAG;
173
 
  else
174
 
    flags= 0;
 
176
  flags= maybe_null ? 0 : NOT_NULL_FLAG;
175
177
}
176
178
 
177
179
bool CreateField::init(Session *,
178
 
                        char *fld_name,
 
180
                        const char *fld_name,
179
181
                        enum_field_types fld_type,
180
 
                        char *fld_length,
181
 
                        char *fld_decimals,
 
182
                        const char *fld_length,
 
183
                        const char *fld_decimals,
182
184
                        uint32_t fld_type_modifier,
183
 
                        Item *fld_default_value,
184
 
                        Item *fld_on_update_value,
185
 
                        LEX_STRING *fld_comment,
186
 
                        char *fld_change,
 
185
                        str_ref fld_comment,
 
186
                        const char *fld_change,
187
187
                        List<String> *fld_interval_list,
188
 
                        const CHARSET_INFO * const fld_charset,
 
188
                        const charset_info_st* fld_charset,
189
189
                        uint32_t,
190
 
                        enum column_format_type column_format_in)
191
 
                        
 
190
                        column_format_type column_format_in)
192
191
{
193
192
  uint32_t sign_len= 0;
194
193
  uint32_t allowed_type_modifier= 0;
196
195
 
197
196
  field= 0;
198
197
  field_name= fld_name;
199
 
  def= fld_default_value;
200
198
  flags= fld_type_modifier;
201
199
  flags|= (((uint32_t)column_format_in & COLUMN_FORMAT_MASK) << COLUMN_FORMAT_FLAGS);
202
200
  unireg_check= (fld_type_modifier & AUTO_INCREMENT_FLAG ?
206
204
  {
207
205
    my_error(ER_TOO_BIG_SCALE, MYF(0), decimals, fld_name,
208
206
             NOT_FIXED_DEC-1);
209
 
    return(true);
 
207
    return true;
210
208
  }
211
209
 
212
210
  sql_type= fld_type;
215
213
  interval= 0;
216
214
  pack_length= key_length= 0;
217
215
  charset= fld_charset;
218
 
  interval_list.empty();
219
 
 
220
 
  comment= *fld_comment;
221
 
 
222
 
  /*
223
 
    Set NO_DEFAULT_VALUE_FLAG if this field doesn't have a default value and
224
 
    it is NOT NULL, not an AUTO_INCREMENT field and not a TIMESTAMP.
225
 
  */
226
 
  if (!fld_default_value && !(fld_type_modifier & AUTO_INCREMENT_FLAG) &&
227
 
      (fld_type_modifier & NOT_NULL_FLAG) && fld_type != DRIZZLE_TYPE_TIMESTAMP)
228
 
    flags|= NO_DEFAULT_VALUE_FLAG;
 
216
  interval_list.clear();
 
217
 
 
218
  comment= fld_comment;
229
219
 
230
220
  if (fld_length && !(length= (uint32_t) atoi(fld_length)))
231
221
    fld_length= 0;
246
236
    case DRIZZLE_TYPE_NULL:
247
237
      break;
248
238
    case DRIZZLE_TYPE_DECIMAL:
249
 
      my_decimal_trim(&length, &decimals);
 
239
      class_decimal_trim(&length, &decimals);
250
240
      if (length > DECIMAL_MAX_PRECISION)
251
241
      {
252
242
        my_error(ER_TOO_BIG_PRECISION, MYF(0), length, fld_name,
253
243
                DECIMAL_MAX_PRECISION);
254
 
        return(true);
 
244
        return true;
255
245
      }
256
246
      if (length < decimals)
257
247
      {
258
248
        my_error(ER_M_BIGGER_THAN_D, MYF(0), fld_name);
259
 
        return(true);
 
249
        return true;
260
250
      }
261
 
      length= my_decimal_precision_to_length(length, decimals, fld_type_modifier & UNSIGNED_FLAG);
262
 
      pack_length= my_decimal_get_binary_size(length, decimals);
 
251
      length= class_decimal_precision_to_length(length, decimals, fld_type_modifier & UNSIGNED_FLAG);
 
252
      pack_length= class_decimal_get_binary_size(length, decimals);
263
253
      break;
264
254
    case DRIZZLE_TYPE_VARCHAR:
265
255
      /*
269
259
      max_field_charlength= MAX_FIELD_VARCHARLENGTH;
270
260
      break;
271
261
    case DRIZZLE_TYPE_BLOB:
272
 
      if (fld_default_value)
273
 
      {
274
 
        /* Allow empty as default value. */
275
 
        String str,*res;
276
 
        res= fld_default_value->val_str(&str);
277
 
        if (res->length())
278
 
        {
279
 
          my_error(ER_BLOB_CANT_HAVE_DEFAULT, MYF(0), fld_name);
280
 
          return(true);
281
 
        }
282
 
 
283
 
      }
284
262
      flags|= BLOB_FLAG;
285
263
      break;
286
264
    case DRIZZLE_TYPE_DOUBLE:
294
272
          decimals != NOT_FIXED_DEC)
295
273
      {
296
274
        my_error(ER_M_BIGGER_THAN_D, MYF(0), fld_name);
297
 
        return(true);
 
275
        return true;
298
276
      }
299
277
      break;
 
278
    case DRIZZLE_TYPE_MICROTIME:
 
279
      /* 
 
280
        This assert() should be correct due to absence of length
 
281
        specifiers for timestamp. Previous manipulation also wasn't
 
282
        ever called (from examining lcov)
 
283
      */
 
284
      assert(fld_type);
300
285
    case DRIZZLE_TYPE_TIMESTAMP:
301
 
      if (!fld_length)
302
 
      {
303
 
        length= DateTime::MAX_STRING_LENGTH;
304
 
      }
305
 
 
306
 
      /* This assert() should be correct due to absence of length
307
 
         specifiers for timestamp. Previous manipulation also wasn't
308
 
         ever called (from examining lcov)
309
 
      */
310
 
      assert(length == (uint32_t)DateTime::MAX_STRING_LENGTH);
311
 
 
312
 
      flags|= UNSIGNED_FLAG;
313
 
      if (fld_default_value)
314
 
      {
315
 
        /* Grammar allows only NOW() value for ON UPDATE clause */
316
 
        if (fld_default_value->type() == Item::FUNC_ITEM &&
317
 
            ((Item_func*)fld_default_value)->functype() == Item_func::NOW_FUNC)
318
 
        {
319
 
          unireg_check= (fld_on_update_value ? Field::TIMESTAMP_DNUN_FIELD:
320
 
                                              Field::TIMESTAMP_DN_FIELD);
321
 
          /*
322
 
            We don't need default value any longer moreover it is dangerous.
323
 
            Everything handled by unireg_check further.
324
 
          */
325
 
          def= 0;
326
 
        }
327
 
        else
328
 
          unireg_check= (fld_on_update_value ? Field::TIMESTAMP_UN_FIELD:
329
 
                                              Field::NONE);
330
 
      }
331
 
      else
332
 
      {
333
 
        /*
334
 
          If we have default TIMESTAMP NOT NULL column without explicit DEFAULT
335
 
          or ON UPDATE values then for the sake of compatiblity we should treat
336
 
          this column as having DEFAULT NOW() ON UPDATE NOW() (when we don't
337
 
          have another TIMESTAMP column with auto-set option before this one)
338
 
          or DEFAULT 0 (in other cases).
339
 
          So here we are setting TIMESTAMP_OLD_FIELD only temporary, and will
340
 
          replace this value by TIMESTAMP_DNUN_FIELD or NONE later when
341
 
          information about all TIMESTAMP fields in table will be availiable.
342
 
 
343
 
          If we have TIMESTAMP NULL column without explicit DEFAULT value
344
 
          we treat it as having DEFAULT NULL attribute.
345
 
        */
346
 
        unireg_check= (fld_on_update_value ? Field::TIMESTAMP_UN_FIELD :
347
 
                      (flags & NOT_NULL_FLAG ? Field::TIMESTAMP_OLD_FIELD :
348
 
                                                Field::NONE));
349
 
      }
 
286
      length= MicroTimestamp::MAX_STRING_LENGTH;
350
287
      break;
351
288
    case DRIZZLE_TYPE_DATE:
352
289
      length= Date::MAX_STRING_LENGTH;
354
291
    case DRIZZLE_TYPE_UUID:
355
292
      length= field::Uuid::max_string_length();
356
293
      break;
 
294
    case DRIZZLE_TYPE_IPV6:
 
295
      length= field::IPv6::max_string_length();
 
296
      break;
 
297
    case DRIZZLE_TYPE_BOOLEAN:
 
298
      length= field::Boolean::max_string_length();
 
299
      break;
357
300
    case DRIZZLE_TYPE_DATETIME:
358
301
      length= DateTime::MAX_STRING_LENGTH;
359
302
      break;
 
303
    case DRIZZLE_TYPE_TIME:
 
304
      length= DateTime::MAX_STRING_LENGTH;
 
305
      break;
360
306
    case DRIZZLE_TYPE_ENUM:
361
307
      {
362
308
        /* Should be safe. */
363
309
        pack_length= 4;
364
310
 
365
 
        List_iterator<String> it(*fld_interval_list);
366
 
        String *tmp;
367
 
        while ((tmp= it++))
 
311
        List<String>::iterator it(fld_interval_list->begin());
 
312
        while (String* tmp= it++)
368
313
          interval_list.push_back(tmp);
369
314
        length= 1;
370
315
        break;
375
320
 
376
321
  if (!(flags & BLOB_FLAG) &&
377
322
      ((length > max_field_charlength &&
378
 
        fld_type != DRIZZLE_TYPE_ENUM &&
379
 
        (fld_type != DRIZZLE_TYPE_VARCHAR || fld_default_value)) ||
 
323
        fld_type != DRIZZLE_TYPE_ENUM  &&
 
324
        (fld_type != DRIZZLE_TYPE_VARCHAR)) ||
380
325
       (!length && fld_type != DRIZZLE_TYPE_VARCHAR)))
381
326
  {
382
327
    my_error((fld_type == DRIZZLE_TYPE_VARCHAR) ?  ER_TOO_BIG_FIELDLENGTH : ER_TOO_BIG_DISPLAYWIDTH,
383
328
              MYF(0),
384
 
              fld_name, max_field_charlength);
 
329
             fld_name, max_field_charlength / (charset? charset->mbmaxlen : 1));
385
330
    return true;
386
331
  }
387
332
  fld_type_modifier&= AUTO_INCREMENT_FLAG;
394
339
  return false; /* success */
395
340
}
396
341
 
 
342
bool CreateField::setDefaultValue(Item *default_value_item,
 
343
                                  Item *on_update_item)
 
344
{
 
345
  def= default_value_item;
 
346
 
 
347
  /*
 
348
    Set NO_DEFAULT_VALUE_FLAG if this field doesn't have a default value and
 
349
    it is NOT NULL, not an AUTO_INCREMENT field and not a TIMESTAMP.
 
350
  */
 
351
  if (! default_value_item
 
352
      && ! (flags & AUTO_INCREMENT_FLAG)
 
353
      && (flags & NOT_NULL_FLAG)
 
354
      && (sql_type != DRIZZLE_TYPE_TIMESTAMP
 
355
          and sql_type != DRIZZLE_TYPE_MICROTIME))
 
356
  {
 
357
    flags|= NO_DEFAULT_VALUE_FLAG;
 
358
  }
 
359
  else
 
360
  {
 
361
    flags&= ~NO_DEFAULT_VALUE_FLAG;
 
362
  }
 
363
 
 
364
  if (sql_type == DRIZZLE_TYPE_BLOB && default_value_item)
 
365
  {
 
366
    /* Allow empty as default value. */
 
367
    String str;
 
368
    String* res= default_value_item->val_str(&str);
 
369
    if (res->length())
 
370
    {
 
371
      my_error(ER_BLOB_CANT_HAVE_DEFAULT, MYF(0), field_name);
 
372
      return true;
 
373
    }
 
374
  }
 
375
 
 
376
  if (sql_type == DRIZZLE_TYPE_TIMESTAMP
 
377
      || sql_type == DRIZZLE_TYPE_MICROTIME)
 
378
  {
 
379
    bool on_update_now= on_update_item
 
380
      || (unireg_check == Field::TIMESTAMP_DNUN_FIELD
 
381
          || unireg_check == Field::TIMESTAMP_UN_FIELD);
 
382
 
 
383
    if (default_value_item)
 
384
    {
 
385
      /* Grammar allows only NOW() value for ON UPDATE clause */
 
386
      if (default_value_item->type() == Item::FUNC_ITEM &&
 
387
          ((Item_func*)default_value_item)->functype() == Item_func::NOW_FUNC)
 
388
      {
 
389
        unireg_check= (on_update_now ? Field::TIMESTAMP_DNUN_FIELD:
 
390
                       Field::TIMESTAMP_DN_FIELD);
 
391
        /*
 
392
          We don't need default value any longer moreover it is dangerous.
 
393
          Everything handled by unireg_check further.
 
394
        */
 
395
        def= 0;
 
396
      }
 
397
      else
 
398
      {
 
399
        unireg_check= on_update_now ? Field::TIMESTAMP_UN_FIELD : Field::NONE;
 
400
      }
 
401
    }
 
402
    else
 
403
    {
 
404
      /*
 
405
        If we have default TIMESTAMP NOT NULL column without explicit DEFAULT
 
406
        or ON UPDATE values then for the sake of compatiblity we should treat
 
407
        this column as having DEFAULT NOW() ON UPDATE NOW() (when we don't
 
408
        have another TIMESTAMP column with auto-set option before this one)
 
409
        or DEFAULT 0 (in other cases).
 
410
        So here we are setting TIMESTAMP_OLD_FIELD only temporary, and will
 
411
        replace this value by TIMESTAMP_DNUN_FIELD or NONE later when
 
412
        information about all TIMESTAMP fields in table will be availiable.
 
413
 
 
414
        If we have TIMESTAMP NULL column without explicit DEFAULT value
 
415
        we treat it as having DEFAULT NULL attribute.
 
416
      */
 
417
      unireg_check= on_update_now ? Field::TIMESTAMP_UN_FIELD :
 
418
                     (flags & NOT_NULL_FLAG ? Field::TIMESTAMP_OLD_FIELD : Field::NONE);
 
419
    }
 
420
  }
 
421
 
 
422
  return false;
 
423
}
 
424
 
 
425
std::ostream& operator<<(std::ostream& output, const CreateField &field)
 
426
{
 
427
  output << "CreateField:(";
 
428
  output <<  field.field_name;
 
429
  output << ", ";
 
430
  output << display::type(field.type());
 
431
  output << ", { ";
 
432
 
 
433
  if (field.flags & NOT_NULL_FLAG)
 
434
    output << " NOT_NULL";
 
435
 
 
436
  if (field.flags & PRI_KEY_FLAG)
 
437
    output << ", PRIMARY KEY";
 
438
 
 
439
  if (field.flags & UNIQUE_KEY_FLAG)
 
440
    output << ", UNIQUE KEY";
 
441
 
 
442
  if (field.flags & MULTIPLE_KEY_FLAG)
 
443
    output << ", MULTIPLE KEY";
 
444
 
 
445
  if (field.flags & BLOB_FLAG)
 
446
    output << ", BLOB";
 
447
 
 
448
  if (field.flags & UNSIGNED_FLAG)
 
449
    output << ", UNSIGNED";
 
450
 
 
451
  if (field.flags & BINARY_FLAG)
 
452
    output << ", BINARY";
 
453
  output << "}, ";
 
454
  if (field.field)
 
455
    output << *field.field;
 
456
  output << ")";
 
457
 
 
458
  return output;  // for multiple << operators.
 
459
}
 
460
 
397
461
} /* namespace drizzled */