~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to drizzled/create_field.cc

  • Committer: Brian Aker
  • Date: 2009-08-18 07:19:56 UTC
  • mfrom: (1116.1.3 stewart)
  • mto: This revision was merged to the branch mainline in revision 1118.
  • Revision ID: brian@gaz-20090818071956-nfpoe9rp3i7p50kx
Merge my branch from Stewart into one branch

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
1
/* -*- mode: c++; c-basic-offset: 2; indent-tabs-mode: nil; -*-
2
2
 *  vim:expandtab:shiftwidth=2:tabstop=2:smarttab:
3
3
 *
4
 
 *  Copyright (C) 2008-2009 Sun Microsystems, Inc.
 
4
 *  Copyright (C) 2008-2009 Sun Microsystems
5
5
 *
6
6
 *  This program is free software; you can redistribute it and/or modify
7
7
 *  it under the terms of the GNU General Public License as published by
21
21
 * @file Implementation of CreateField class
22
22
 */
23
23
 
24
 
#include <config.h>
 
24
#include "drizzled/server_includes.h"
25
25
#include <errno.h>
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/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>
 
26
#include "drizzled/sql_select.h"
 
27
#include "drizzled/error.h"
 
28
#include "drizzled/field.h"
 
29
#include "drizzled/create_field.h"
 
30
#include "drizzled/field/str.h"
 
31
#include "drizzled/field/num.h"
 
32
#include "drizzled/field/blob.h"
 
33
#include "drizzled/field/enum.h"
 
34
#include "drizzled/field/null.h"
 
35
#include "drizzled/field/date.h"
 
36
#include "drizzled/field/decimal.h"
 
37
#include "drizzled/field/real.h"
 
38
#include "drizzled/field/double.h"
 
39
#include "drizzled/field/long.h"
 
40
#include "drizzled/field/int64_t.h"
 
41
#include "drizzled/field/num.h"
 
42
#include "drizzled/field/timestamp.h"
 
43
#include "drizzled/field/datetime.h"
 
44
#include "drizzled/field/varstring.h"
 
45
#include "drizzled/temporal.h"
53
46
 
54
47
#include <algorithm>
55
48
 
56
49
using namespace std;
57
50
 
58
 
namespace drizzled
59
 
{
60
51
 
61
52
/** Create a field suitable for create of table. */
62
53
CreateField::CreateField(Field *old_field, Field *orig_field)
75
66
 
76
67
  /* Fix if the original table had 4 byte pointer blobs */
77
68
  if (flags & BLOB_FLAG)
78
 
  {
79
 
    pack_length= (pack_length - old_field->getTable()->getShare()->sizeBlobPtr() + portable_sizeof_char_ptr);
80
 
  }
 
69
    pack_length= (pack_length - old_field->table->s->blob_ptr_size + portable_sizeof_char_ptr);
81
70
 
82
71
  switch (sql_type) 
83
72
  {
95
84
      break;
96
85
  }
97
86
 
98
 
  if (flags & ENUM_FLAG)
 
87
  if (flags & (ENUM_FLAG | SET_FLAG))
99
88
    interval= ((Field_enum*) old_field)->typelib;
100
89
  else
101
90
    interval= 0;
102
91
  def= 0;
103
92
  char_length= length;
104
93
 
105
 
  if (!(flags & (NO_DEFAULT_VALUE_FLAG)) &&
106
 
      !(flags & AUTO_INCREMENT_FLAG) &&
 
94
  if (!(flags & (NO_DEFAULT_VALUE_FLAG )) &&
107
95
      old_field->ptr && orig_field &&
108
 
      (not old_field->is_timestamp() ||                /* set def only if */
109
 
       old_field->getTable()->timestamp_field != old_field ||  /* timestamp field */
 
96
      (sql_type != DRIZZLE_TYPE_TIMESTAMP ||                /* set def only if */
 
97
       old_field->table->timestamp_field != old_field ||  /* timestamp field */
110
98
       unireg_check == Field::TIMESTAMP_UN_FIELD))        /* has default val */
111
99
  {
112
100
    ptrdiff_t diff;
113
101
 
114
102
    /* Get the value from default_values */
115
 
    diff= (ptrdiff_t) (orig_field->getTable()->getDefaultValues() - orig_field->getTable()->getInsertRecord());
 
103
    diff= (ptrdiff_t) (orig_field->table->s->default_values - orig_field->table->record[0]);
116
104
    orig_field->move_field_offset(diff);        // Points now at default_values
117
105
    if (! orig_field->is_real_null())
118
106
    {
119
107
      char buff[MAX_FIELD_WIDTH], *pos;
120
108
      String tmp(buff, sizeof(buff), charset), *res;
121
 
      res= orig_field->val_str_internal(&tmp);
122
 
      pos= (char*) memory::sql_strmake(res->ptr(), res->length());
 
109
      res= orig_field->val_str(&tmp);
 
110
      pos= (char*) sql_strmake(res->ptr(), res->length());
123
111
      def= new Item_string(pos, res->length(), charset);
124
112
    }
125
 
    orig_field->move_field_offset(-diff);       // Back to getInsertRecord()
 
113
    orig_field->move_field_offset(-diff);       // Back to record[0]
126
114
  }
127
115
}
128
116
 
144
132
      length*= charset->mbmaxlen;
145
133
      key_length= pack_length;
146
134
      break;
147
 
    case DRIZZLE_TYPE_DECIMAL:
 
135
    case DRIZZLE_TYPE_NEWDECIMAL:
148
136
      key_length= pack_length=
149
 
        class_decimal_get_binary_size(class_decimal_length_to_precision(length,
 
137
        my_decimal_get_binary_size(my_decimal_length_to_precision(length,
150
138
                  decimals,
151
139
                  flags &
152
140
                  UNSIGNED_FLAG),
162
150
  Init for a tmp table field. To be extended if need be.
163
151
*/
164
152
void CreateField::init_for_tmp_table(enum_field_types sql_type_arg,
165
 
                                     uint32_t length_arg,
166
 
                                     uint32_t decimals_arg,
167
 
                                     bool maybe_null)
 
153
                                      uint32_t length_arg, uint32_t decimals_arg,
 
154
                                      bool maybe_null, bool is_unsigned)
168
155
{
169
156
  field_name= "";
170
157
  sql_type= sql_type_arg;
172
159
  unireg_check= Field::NONE;
173
160
  interval= 0;
174
161
  charset= &my_charset_bin;
175
 
  decimals= decimals_arg & FIELDFLAG_MAX_DEC;
176
 
 
177
 
  if (! maybe_null)
178
 
    flags= NOT_NULL_FLAG;
179
 
  else
180
 
    flags= 0;
 
162
  pack_flag= (FIELDFLAG_NUMBER |
 
163
              ((decimals_arg & FIELDFLAG_MAX_DEC) << FIELDFLAG_DEC_SHIFT) |
 
164
              (maybe_null ? FIELDFLAG_MAYBE_NULL : 0) |
 
165
              (is_unsigned ? 0 : FIELDFLAG_DECIMAL));
181
166
}
182
167
 
183
168
bool CreateField::init(Session *,
221
206
  interval= 0;
222
207
  pack_length= key_length= 0;
223
208
  charset= fld_charset;
224
 
  interval_list.clear();
 
209
  interval_list.empty();
225
210
 
226
211
  comment= *fld_comment;
227
212
 
230
215
    it is NOT NULL, not an AUTO_INCREMENT field and not a TIMESTAMP.
231
216
  */
232
217
  if (!fld_default_value && !(fld_type_modifier & AUTO_INCREMENT_FLAG) &&
233
 
      (fld_type_modifier & NOT_NULL_FLAG) && (fld_type != DRIZZLE_TYPE_TIMESTAMP and fld_type != DRIZZLE_TYPE_MICROTIME))
234
 
  {
 
218
      (fld_type_modifier & NOT_NULL_FLAG) && fld_type != DRIZZLE_TYPE_TIMESTAMP)
235
219
    flags|= NO_DEFAULT_VALUE_FLAG;
236
 
  }
237
220
 
238
221
  if (fld_length && !(length= (uint32_t) atoi(fld_length)))
239
 
    fld_length= 0;
 
222
    fld_length= 0; /* purecov: inspected */
240
223
  sign_len= fld_type_modifier & UNSIGNED_FLAG ? 0 : 1;
241
224
 
242
225
  switch (fld_type) 
243
226
  {
 
227
    case DRIZZLE_TYPE_TINY:
 
228
      if (!fld_length)
 
229
        length= MAX_TINYINT_WIDTH+sign_len;
 
230
      allowed_type_modifier= AUTO_INCREMENT_FLAG;
 
231
      break;
244
232
    case DRIZZLE_TYPE_LONG:
245
233
      if (!fld_length)
246
234
        length= MAX_INT_WIDTH+sign_len;
253
241
      break;
254
242
    case DRIZZLE_TYPE_NULL:
255
243
      break;
256
 
    case DRIZZLE_TYPE_DECIMAL:
257
 
      class_decimal_trim(&length, &decimals);
 
244
    case DRIZZLE_TYPE_NEWDECIMAL:
 
245
      my_decimal_trim(&length, &decimals);
258
246
      if (length > DECIMAL_MAX_PRECISION)
259
247
      {
260
248
        my_error(ER_TOO_BIG_PRECISION, MYF(0), length, fld_name,
266
254
        my_error(ER_M_BIGGER_THAN_D, MYF(0), fld_name);
267
255
        return(true);
268
256
      }
269
 
      length= class_decimal_precision_to_length(length, decimals, fld_type_modifier & UNSIGNED_FLAG);
270
 
      pack_length= class_decimal_get_binary_size(length, decimals);
 
257
      length= my_decimal_precision_to_length(length, decimals, fld_type_modifier & UNSIGNED_FLAG);
 
258
      pack_length= my_decimal_get_binary_size(length, decimals);
271
259
      break;
272
260
    case DRIZZLE_TYPE_VARCHAR:
273
261
      /*
305
293
        return(true);
306
294
      }
307
295
      break;
308
 
    case DRIZZLE_TYPE_MICROTIME:
309
 
      /* 
310
 
        This assert() should be correct due to absence of length
311
 
        specifiers for timestamp. Previous manipulation also wasn't
312
 
        ever called (from examining lcov)
313
 
      */
314
 
      assert(fld_type);
315
296
    case DRIZZLE_TYPE_TIMESTAMP:
316
 
      length= MicroTimestamp::MAX_STRING_LENGTH;
317
 
 
 
297
      if (!fld_length)
 
298
      {
 
299
        length= drizzled::DateTime::MAX_STRING_LENGTH;
 
300
      }
 
301
 
 
302
      /* This assert() should be correct due to absence of length
 
303
         specifiers for timestamp. Previous manipulation also wasn't
 
304
         ever called (from examining lcov)
 
305
      */
 
306
      assert(length == (uint32_t)drizzled::DateTime::MAX_STRING_LENGTH);
 
307
 
 
308
      flags|= UNSIGNED_FLAG;
318
309
      if (fld_default_value)
319
310
      {
320
311
        /* Grammar allows only NOW() value for ON UPDATE clause */
330
321
          def= 0;
331
322
        }
332
323
        else
333
 
        {
334
324
          unireg_check= (fld_on_update_value ? Field::TIMESTAMP_UN_FIELD:
335
 
                         Field::NONE);
336
 
        }
 
325
                                              Field::NONE);
337
326
      }
338
327
      else
339
328
      {
356
345
      }
357
346
      break;
358
347
    case DRIZZLE_TYPE_DATE:
359
 
      length= Date::MAX_STRING_LENGTH;
360
 
      break;
361
 
    case DRIZZLE_TYPE_UUID:
362
 
      length= field::Uuid::max_string_length();
363
 
      break;
364
 
    case DRIZZLE_TYPE_BOOLEAN:
365
 
      length= field::Boolean::max_string_length();
 
348
      length= drizzled::Date::MAX_STRING_LENGTH;
366
349
      break;
367
350
    case DRIZZLE_TYPE_DATETIME:
368
 
      length= DateTime::MAX_STRING_LENGTH;
369
 
      break;
370
 
    case DRIZZLE_TYPE_TIME:
371
 
      length= DateTime::MAX_STRING_LENGTH;
 
351
      length= drizzled::DateTime::MAX_STRING_LENGTH;
372
352
      break;
373
353
    case DRIZZLE_TYPE_ENUM:
374
354
      {
375
355
        /* Should be safe. */
376
 
        pack_length= 4;
 
356
        pack_length= get_enum_pack_length(fld_interval_list->elements);
377
357
 
378
 
        List<String>::iterator it(fld_interval_list->begin());
 
358
        List_iterator<String> it(*fld_interval_list);
379
359
        String *tmp;
380
360
        while ((tmp= it++))
381
361
          interval_list.push_back(tmp);
394
374
  {
395
375
    my_error((fld_type == DRIZZLE_TYPE_VARCHAR) ?  ER_TOO_BIG_FIELDLENGTH : ER_TOO_BIG_DISPLAYWIDTH,
396
376
              MYF(0),
397
 
              fld_name, max_field_charlength);
 
377
              fld_name, max_field_charlength); /* purecov: inspected */
398
378
    return true;
399
379
  }
400
380
  fld_type_modifier&= AUTO_INCREMENT_FLAG;
406
386
 
407
387
  return false; /* success */
408
388
}
409
 
 
410
 
std::ostream& operator<<(std::ostream& output, const CreateField &field)
411
 
{
412
 
  output << "CreateField:(";
413
 
  output <<  field.field_name;
414
 
  output << ", ";
415
 
  output << drizzled::display::type(field.type());
416
 
  output << ", { ";
417
 
 
418
 
  if (field.flags & NOT_NULL_FLAG)
419
 
    output << " NOT_NULL";
420
 
 
421
 
  if (field.flags & PRI_KEY_FLAG)
422
 
    output << ", PRIMARY KEY";
423
 
 
424
 
  if (field.flags & UNIQUE_KEY_FLAG)
425
 
    output << ", UNIQUE KEY";
426
 
 
427
 
  if (field.flags & MULTIPLE_KEY_FLAG)
428
 
    output << ", MULTIPLE KEY";
429
 
 
430
 
  if (field.flags & BLOB_FLAG)
431
 
    output << ", BLOB";
432
 
 
433
 
  if (field.flags & UNSIGNED_FLAG)
434
 
    output << ", UNSIGNED";
435
 
 
436
 
  if (field.flags & BINARY_FLAG)
437
 
    output << ", BINARY";
438
 
  output << "}, ";
439
 
  if (field.field)
440
 
    output << *field.field;
441
 
  output << ")";
442
 
 
443
 
  return output;  // for multiple << operators.
444
 
}
445
 
 
446
 
} /* namespace drizzled */