~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to drizzled/create_field.cc

  • Committer: Stewart Smith
  • Date: 2011-03-29 01:30:47 UTC
  • mto: (2257.1.2 build)
  • mto: This revision was merged to the branch mainline in revision 2258.
  • Revision ID: stewart@flamingspork.com-20110329013047-5ujzfx6pahmwuko2
have CachedDirectory print out a warning if we can't stat() something in a directory. We should always have access to at least stat() things in directories Drizzle is running in (otherwise there is likely a problem)

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/temporal.h>
 
49
#include <drizzled/item/string.h>
 
50
#include <drizzled/table.h>
 
51
 
 
52
#include <drizzled/display.h>
49
53
 
50
54
#include <algorithm>
51
55
 
71
75
 
72
76
  /* Fix if the original table had 4 byte pointer blobs */
73
77
  if (flags & BLOB_FLAG)
74
 
    pack_length= (pack_length - old_field->getTable()->getShare()->blob_ptr_size + portable_sizeof_char_ptr);
 
78
  {
 
79
    pack_length= (pack_length - old_field->getTable()->getShare()->sizeBlobPtr() + portable_sizeof_char_ptr);
 
80
  }
75
81
 
76
82
  switch (sql_type) 
77
83
  {
99
105
  if (!(flags & (NO_DEFAULT_VALUE_FLAG)) &&
100
106
      !(flags & AUTO_INCREMENT_FLAG) &&
101
107
      old_field->ptr && orig_field &&
102
 
      (sql_type != DRIZZLE_TYPE_TIMESTAMP ||                /* set def only if */
 
108
      (not old_field->is_timestamp() ||                /* set def only if */
103
109
       old_field->getTable()->timestamp_field != old_field ||  /* timestamp field */
104
110
       unireg_check == Field::TIMESTAMP_UN_FIELD))        /* has default val */
105
111
  {
140
146
      break;
141
147
    case DRIZZLE_TYPE_DECIMAL:
142
148
      key_length= pack_length=
143
 
        my_decimal_get_binary_size(my_decimal_length_to_precision(length,
 
149
        class_decimal_get_binary_size(class_decimal_length_to_precision(length,
144
150
                  decimals,
145
151
                  flags &
146
152
                  UNSIGNED_FLAG),
180
186
                        char *fld_length,
181
187
                        char *fld_decimals,
182
188
                        uint32_t fld_type_modifier,
183
 
                        Item *fld_default_value,
184
 
                        Item *fld_on_update_value,
185
189
                        LEX_STRING *fld_comment,
186
190
                        char *fld_change,
187
191
                        List<String> *fld_interval_list,
188
 
                        const CHARSET_INFO * const fld_charset,
 
192
                        const charset_info_st * const fld_charset,
189
193
                        uint32_t,
190
194
                        enum column_format_type column_format_in)
191
 
                        
192
195
{
193
196
  uint32_t sign_len= 0;
194
197
  uint32_t allowed_type_modifier= 0;
196
199
 
197
200
  field= 0;
198
201
  field_name= fld_name;
199
 
  def= fld_default_value;
200
202
  flags= fld_type_modifier;
201
203
  flags|= (((uint32_t)column_format_in & COLUMN_FORMAT_MASK) << COLUMN_FORMAT_FLAGS);
202
204
  unireg_check= (fld_type_modifier & AUTO_INCREMENT_FLAG ?
215
217
  interval= 0;
216
218
  pack_length= key_length= 0;
217
219
  charset= fld_charset;
218
 
  interval_list.empty();
 
220
  interval_list.clear();
219
221
 
220
222
  comment= *fld_comment;
221
223
 
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;
229
 
 
230
224
  if (fld_length && !(length= (uint32_t) atoi(fld_length)))
231
225
    fld_length= 0;
232
226
  sign_len= fld_type_modifier & UNSIGNED_FLAG ? 0 : 1;
246
240
    case DRIZZLE_TYPE_NULL:
247
241
      break;
248
242
    case DRIZZLE_TYPE_DECIMAL:
249
 
      my_decimal_trim(&length, &decimals);
 
243
      class_decimal_trim(&length, &decimals);
250
244
      if (length > DECIMAL_MAX_PRECISION)
251
245
      {
252
246
        my_error(ER_TOO_BIG_PRECISION, MYF(0), length, fld_name,
258
252
        my_error(ER_M_BIGGER_THAN_D, MYF(0), fld_name);
259
253
        return(true);
260
254
      }
261
 
      length= my_decimal_precision_to_length(length, decimals, fld_type_modifier & UNSIGNED_FLAG);
262
 
      pack_length= my_decimal_get_binary_size(length, decimals);
 
255
      length= class_decimal_precision_to_length(length, decimals, fld_type_modifier & UNSIGNED_FLAG);
 
256
      pack_length= class_decimal_get_binary_size(length, decimals);
263
257
      break;
264
258
    case DRIZZLE_TYPE_VARCHAR:
265
259
      /*
269
263
      max_field_charlength= MAX_FIELD_VARCHARLENGTH;
270
264
      break;
271
265
    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
266
      flags|= BLOB_FLAG;
285
267
      break;
286
268
    case DRIZZLE_TYPE_DOUBLE:
297
279
        return(true);
298
280
      }
299
281
      break;
 
282
    case DRIZZLE_TYPE_MICROTIME:
 
283
      /* 
 
284
        This assert() should be correct due to absence of length
 
285
        specifiers for timestamp. Previous manipulation also wasn't
 
286
        ever called (from examining lcov)
 
287
      */
 
288
      assert(fld_type);
300
289
    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
 
      }
 
290
      length= MicroTimestamp::MAX_STRING_LENGTH;
350
291
      break;
351
292
    case DRIZZLE_TYPE_DATE:
352
293
      length= Date::MAX_STRING_LENGTH;
354
295
    case DRIZZLE_TYPE_UUID:
355
296
      length= field::Uuid::max_string_length();
356
297
      break;
 
298
    case DRIZZLE_TYPE_BOOLEAN:
 
299
      length= field::Boolean::max_string_length();
 
300
      break;
357
301
    case DRIZZLE_TYPE_DATETIME:
358
302
      length= DateTime::MAX_STRING_LENGTH;
359
303
      break;
 
304
    case DRIZZLE_TYPE_TIME:
 
305
      length= DateTime::MAX_STRING_LENGTH;
 
306
      break;
360
307
    case DRIZZLE_TYPE_ENUM:
361
308
      {
362
309
        /* Should be safe. */
363
310
        pack_length= 4;
364
311
 
365
 
        List_iterator<String> it(*fld_interval_list);
 
312
        List<String>::iterator it(fld_interval_list->begin());
366
313
        String *tmp;
367
314
        while ((tmp= it++))
368
315
          interval_list.push_back(tmp);
375
322
 
376
323
  if (!(flags & BLOB_FLAG) &&
377
324
      ((length > max_field_charlength &&
378
 
        fld_type != DRIZZLE_TYPE_ENUM &&
379
 
        (fld_type != DRIZZLE_TYPE_VARCHAR || fld_default_value)) ||
 
325
        fld_type != DRIZZLE_TYPE_ENUM  &&
 
326
        (fld_type != DRIZZLE_TYPE_VARCHAR)) ||
380
327
       (!length && fld_type != DRIZZLE_TYPE_VARCHAR)))
381
328
  {
382
329
    my_error((fld_type == DRIZZLE_TYPE_VARCHAR) ?  ER_TOO_BIG_FIELDLENGTH : ER_TOO_BIG_DISPLAYWIDTH,
383
330
              MYF(0),
384
 
              fld_name, max_field_charlength);
 
331
             fld_name, max_field_charlength / (charset? charset->mbmaxlen : 1));
385
332
    return true;
386
333
  }
387
334
  fld_type_modifier&= AUTO_INCREMENT_FLAG;
394
341
  return false; /* success */
395
342
}
396
343
 
 
344
bool CreateField::setDefaultValue(Item *default_value_item,
 
345
                                  Item *on_update_item)
 
346
{
 
347
  def= default_value_item;
 
348
 
 
349
  /*
 
350
    Set NO_DEFAULT_VALUE_FLAG if this field doesn't have a default value and
 
351
    it is NOT NULL, not an AUTO_INCREMENT field and not a TIMESTAMP.
 
352
  */
 
353
  if (! default_value_item
 
354
      && ! (flags & AUTO_INCREMENT_FLAG)
 
355
      && (flags & NOT_NULL_FLAG)
 
356
      && (sql_type != DRIZZLE_TYPE_TIMESTAMP
 
357
          and sql_type != DRIZZLE_TYPE_MICROTIME))
 
358
  {
 
359
    flags|= NO_DEFAULT_VALUE_FLAG;
 
360
  }
 
361
  else
 
362
  {
 
363
    flags&= ~NO_DEFAULT_VALUE_FLAG;
 
364
  }
 
365
 
 
366
  if (sql_type == DRIZZLE_TYPE_BLOB && default_value_item)
 
367
  {
 
368
    /* Allow empty as default value. */
 
369
    String str,*res;
 
370
    res= default_value_item->val_str(&str);
 
371
    if (res->length())
 
372
    {
 
373
      my_error(ER_BLOB_CANT_HAVE_DEFAULT, MYF(0), field_name);
 
374
      return(true);
 
375
    }
 
376
  }
 
377
 
 
378
  if (sql_type == DRIZZLE_TYPE_TIMESTAMP
 
379
      || sql_type == DRIZZLE_TYPE_MICROTIME)
 
380
  {
 
381
    bool on_update_now= on_update_item
 
382
      || (unireg_check == Field::TIMESTAMP_DNUN_FIELD
 
383
          || unireg_check == Field::TIMESTAMP_UN_FIELD);
 
384
 
 
385
    if (default_value_item)
 
386
    {
 
387
      /* Grammar allows only NOW() value for ON UPDATE clause */
 
388
      if (default_value_item->type() == Item::FUNC_ITEM &&
 
389
          ((Item_func*)default_value_item)->functype() == Item_func::NOW_FUNC)
 
390
      {
 
391
        unireg_check= (on_update_now ? Field::TIMESTAMP_DNUN_FIELD:
 
392
                       Field::TIMESTAMP_DN_FIELD);
 
393
        /*
 
394
          We don't need default value any longer moreover it is dangerous.
 
395
          Everything handled by unireg_check further.
 
396
        */
 
397
        def= 0;
 
398
      }
 
399
      else
 
400
      {
 
401
        unireg_check= (on_update_now ? Field::TIMESTAMP_UN_FIELD:
 
402
                       Field::NONE);
 
403
      }
 
404
    }
 
405
    else
 
406
    {
 
407
      /*
 
408
        If we have default TIMESTAMP NOT NULL column without explicit DEFAULT
 
409
        or ON UPDATE values then for the sake of compatiblity we should treat
 
410
        this column as having DEFAULT NOW() ON UPDATE NOW() (when we don't
 
411
        have another TIMESTAMP column with auto-set option before this one)
 
412
        or DEFAULT 0 (in other cases).
 
413
        So here we are setting TIMESTAMP_OLD_FIELD only temporary, and will
 
414
        replace this value by TIMESTAMP_DNUN_FIELD or NONE later when
 
415
        information about all TIMESTAMP fields in table will be availiable.
 
416
 
 
417
        If we have TIMESTAMP NULL column without explicit DEFAULT value
 
418
        we treat it as having DEFAULT NULL attribute.
 
419
      */
 
420
      unireg_check= (on_update_now ? Field::TIMESTAMP_UN_FIELD :
 
421
                     (flags & NOT_NULL_FLAG ? Field::TIMESTAMP_OLD_FIELD :
 
422
                      Field::NONE));
 
423
    }
 
424
  }
 
425
 
 
426
  return false;
 
427
}
 
428
 
 
429
std::ostream& operator<<(std::ostream& output, const CreateField &field)
 
430
{
 
431
  output << "CreateField:(";
 
432
  output <<  field.field_name;
 
433
  output << ", ";
 
434
  output << display::type(field.type());
 
435
  output << ", { ";
 
436
 
 
437
  if (field.flags & NOT_NULL_FLAG)
 
438
    output << " NOT_NULL";
 
439
 
 
440
  if (field.flags & PRI_KEY_FLAG)
 
441
    output << ", PRIMARY KEY";
 
442
 
 
443
  if (field.flags & UNIQUE_KEY_FLAG)
 
444
    output << ", UNIQUE KEY";
 
445
 
 
446
  if (field.flags & MULTIPLE_KEY_FLAG)
 
447
    output << ", MULTIPLE KEY";
 
448
 
 
449
  if (field.flags & BLOB_FLAG)
 
450
    output << ", BLOB";
 
451
 
 
452
  if (field.flags & UNSIGNED_FLAG)
 
453
    output << ", UNSIGNED";
 
454
 
 
455
  if (field.flags & BINARY_FLAG)
 
456
    output << ", BINARY";
 
457
  output << "}, ";
 
458
  if (field.field)
 
459
    output << *field.field;
 
460
  output << ")";
 
461
 
 
462
  return output;  // for multiple << operators.
 
463
}
 
464
 
397
465
} /* namespace drizzled */