1
/* -*- mode: c++; c-basic-offset: 2; indent-tabs-mode: nil; -*-
2
* vim:expandtab:shiftwidth=2:tabstop=2:smarttab:
4
* Copyright (C) 2008-2009 Sun Microsystems
6
* This program is free software; you can redistribute it and/or modify
7
* it under the terms of the GNU General Public License as published by
8
* the Free Software Foundation; version 2 of the License.
10
* This program is distributed in the hope that it will be useful,
11
* but WITHOUT ANY WARRANTY; without even the implied warranty of
12
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13
* GNU General Public License for more details.
15
* You should have received a copy of the GNU General Public License
16
* along with this program; if not, write to the Free Software
17
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
21
* @file Implementation of CreateField class
24
#include "drizzled/server_includes.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"
52
/** Create a field suitable for create of table. */
53
CreateField::CreateField(Field *old_field, Field *orig_field)
56
field_name= change= old_field->field_name;
57
length= old_field->field_length;
58
flags= old_field->flags;
59
unireg_check= old_field->unireg_check;
60
pack_length= old_field->pack_length();
61
key_length= old_field->key_length();
62
sql_type= old_field->real_type();
63
charset= old_field->charset(); // May be NULL ptr
64
comment= old_field->comment;
65
decimals= old_field->decimals();
67
/* Fix if the original table had 4 byte pointer blobs */
68
if (flags & BLOB_FLAG)
69
pack_length= (pack_length - old_field->table->s->blob_ptr_size + portable_sizeof_char_ptr);
73
case DRIZZLE_TYPE_BLOB:
74
sql_type= DRIZZLE_TYPE_BLOB;
75
length/= charset->mbmaxlen;
76
key_length/= charset->mbmaxlen;
78
case DRIZZLE_TYPE_ENUM:
79
case DRIZZLE_TYPE_VARCHAR:
80
/* This is corrected in create_length_to_internal_length */
81
length= (length+charset->mbmaxlen-1) / charset->mbmaxlen;
87
if (flags & (ENUM_FLAG | SET_FLAG))
88
interval= ((Field_enum*) old_field)->typelib;
94
if (!(flags & (NO_DEFAULT_VALUE_FLAG )) &&
95
old_field->ptr && orig_field &&
96
(sql_type != DRIZZLE_TYPE_TIMESTAMP || /* set def only if */
97
old_field->table->timestamp_field != old_field || /* timestamp field */
98
unireg_check == Field::TIMESTAMP_UN_FIELD)) /* has default val */
102
/* Get the value from default_values */
103
diff= (ptrdiff_t) (orig_field->table->s->default_values - orig_field->table->record[0]);
104
orig_field->move_field_offset(diff); // Points now at default_values
105
if (! orig_field->is_real_null())
107
char buff[MAX_FIELD_WIDTH], *pos;
108
String tmp(buff, sizeof(buff), charset), *res;
109
res= orig_field->val_str(&tmp);
110
pos= (char*) sql_strmake(res->ptr(), res->length());
111
def= new Item_string(pos, res->length(), charset);
113
orig_field->move_field_offset(-diff); // Back to record[0]
118
Convert CreateField::length from number of characters to number of bytes.
120
void CreateField::create_length_to_internal_length(void)
124
case DRIZZLE_TYPE_BLOB:
125
case DRIZZLE_TYPE_VARCHAR:
126
length*= charset->mbmaxlen;
128
pack_length= calc_pack_length(sql_type, length);
130
case DRIZZLE_TYPE_ENUM:
131
/* Pack_length already calculated in ::init() */
132
length*= charset->mbmaxlen;
133
key_length= pack_length;
135
case DRIZZLE_TYPE_NEWDECIMAL:
136
key_length= pack_length=
137
my_decimal_get_binary_size(my_decimal_length_to_precision(length,
144
key_length= pack_length= calc_pack_length(sql_type, length);
150
Init for a tmp table field. To be extended if need be.
152
void CreateField::init_for_tmp_table(enum_field_types sql_type_arg,
153
uint32_t length_arg, uint32_t decimals_arg,
154
bool maybe_null, bool is_unsigned)
157
sql_type= sql_type_arg;
158
char_length= length= length_arg;;
159
unireg_check= Field::NONE;
161
charset= &my_charset_bin;
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));
168
bool CreateField::init(Session *,
170
enum_field_types fld_type,
173
uint32_t fld_type_modifier,
174
Item *fld_default_value,
175
Item *fld_on_update_value,
176
LEX_STRING *fld_comment,
178
List<String> *fld_interval_list,
179
const CHARSET_INFO * const fld_charset,
181
enum column_format_type column_format_in)
184
uint32_t sign_len= 0;
185
uint32_t allowed_type_modifier= 0;
186
uint32_t max_field_charlength= MAX_FIELD_CHARLENGTH;
189
field_name= fld_name;
190
def= fld_default_value;
191
flags= fld_type_modifier;
192
flags|= (((uint32_t)column_format_in & COLUMN_FORMAT_MASK) << COLUMN_FORMAT_FLAGS);
193
unireg_check= (fld_type_modifier & AUTO_INCREMENT_FLAG ?
194
Field::NEXT_NUMBER : Field::NONE);
195
decimals= fld_decimals ? (uint32_t)atoi(fld_decimals) : 0;
196
if (decimals >= NOT_FIXED_DEC)
198
my_error(ER_TOO_BIG_SCALE, MYF(0), decimals, fld_name,
207
pack_length= key_length= 0;
208
charset= fld_charset;
209
interval_list.empty();
211
comment= *fld_comment;
214
Set NO_DEFAULT_VALUE_FLAG if this field doesn't have a default value and
215
it is NOT NULL, not an AUTO_INCREMENT field and not a TIMESTAMP.
217
if (!fld_default_value && !(fld_type_modifier & AUTO_INCREMENT_FLAG) &&
218
(fld_type_modifier & NOT_NULL_FLAG) && fld_type != DRIZZLE_TYPE_TIMESTAMP)
219
flags|= NO_DEFAULT_VALUE_FLAG;
221
if (fld_length && !(length= (uint32_t) atoi(fld_length)))
223
sign_len= fld_type_modifier & UNSIGNED_FLAG ? 0 : 1;
227
case DRIZZLE_TYPE_TINY:
229
length= MAX_TINYINT_WIDTH+sign_len;
230
allowed_type_modifier= AUTO_INCREMENT_FLAG;
232
case DRIZZLE_TYPE_LONG:
234
length= MAX_INT_WIDTH+sign_len;
235
allowed_type_modifier= AUTO_INCREMENT_FLAG;
237
case DRIZZLE_TYPE_LONGLONG:
239
length= MAX_BIGINT_WIDTH;
240
allowed_type_modifier= AUTO_INCREMENT_FLAG;
242
case DRIZZLE_TYPE_NULL:
244
case DRIZZLE_TYPE_NEWDECIMAL:
245
my_decimal_trim(&length, &decimals);
246
if (length > DECIMAL_MAX_PRECISION)
248
my_error(ER_TOO_BIG_PRECISION, MYF(0), length, fld_name,
249
DECIMAL_MAX_PRECISION);
252
if (length < decimals)
254
my_error(ER_M_BIGGER_THAN_D, MYF(0), fld_name);
257
length= my_decimal_precision_to_length(length, decimals, fld_type_modifier & UNSIGNED_FLAG);
258
pack_length= my_decimal_get_binary_size(length, decimals);
260
case DRIZZLE_TYPE_VARCHAR:
262
Long VARCHAR's are automaticly converted to blobs in mysql_prepare_table
263
if they don't have a default value
265
max_field_charlength= MAX_FIELD_VARCHARLENGTH;
267
case DRIZZLE_TYPE_BLOB:
268
if (fld_default_value)
270
/* Allow empty as default value. */
272
res= fld_default_value->val_str(&str);
275
my_error(ER_BLOB_CANT_HAVE_DEFAULT, MYF(0), fld_name);
282
case DRIZZLE_TYPE_DOUBLE:
283
allowed_type_modifier= AUTO_INCREMENT_FLAG;
284
if (!fld_length && !fld_decimals)
287
decimals= NOT_FIXED_DEC;
289
if (length < decimals &&
290
decimals != NOT_FIXED_DEC)
292
my_error(ER_M_BIGGER_THAN_D, MYF(0), fld_name);
296
case DRIZZLE_TYPE_TIMESTAMP:
299
length= drizzled::DateTime::MAX_STRING_LENGTH;
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)
306
assert(length == (uint32_t)drizzled::DateTime::MAX_STRING_LENGTH);
308
flags|= UNSIGNED_FLAG;
309
if (fld_default_value)
311
/* Grammar allows only NOW() value for ON UPDATE clause */
312
if (fld_default_value->type() == Item::FUNC_ITEM &&
313
((Item_func*)fld_default_value)->functype() == Item_func::NOW_FUNC)
315
unireg_check= (fld_on_update_value ? Field::TIMESTAMP_DNUN_FIELD:
316
Field::TIMESTAMP_DN_FIELD);
318
We don't need default value any longer moreover it is dangerous.
319
Everything handled by unireg_check further.
324
unireg_check= (fld_on_update_value ? Field::TIMESTAMP_UN_FIELD:
330
If we have default TIMESTAMP NOT NULL column without explicit DEFAULT
331
or ON UPDATE values then for the sake of compatiblity we should treat
332
this column as having DEFAULT NOW() ON UPDATE NOW() (when we don't
333
have another TIMESTAMP column with auto-set option before this one)
334
or DEFAULT 0 (in other cases).
335
So here we are setting TIMESTAMP_OLD_FIELD only temporary, and will
336
replace this value by TIMESTAMP_DNUN_FIELD or NONE later when
337
information about all TIMESTAMP fields in table will be availiable.
339
If we have TIMESTAMP NULL column without explicit DEFAULT value
340
we treat it as having DEFAULT NULL attribute.
342
unireg_check= (fld_on_update_value ? Field::TIMESTAMP_UN_FIELD :
343
(flags & NOT_NULL_FLAG ? Field::TIMESTAMP_OLD_FIELD :
347
case DRIZZLE_TYPE_DATE:
348
length= drizzled::Date::MAX_STRING_LENGTH;
350
case DRIZZLE_TYPE_DATETIME:
351
length= drizzled::DateTime::MAX_STRING_LENGTH;
353
case DRIZZLE_TYPE_ENUM:
355
/* Should be safe. */
356
pack_length= get_enum_pack_length(fld_interval_list->elements);
358
List_iterator<String> it(*fld_interval_list);
361
interval_list.push_back(tmp);
366
/* Remember the value of length */
369
if (!(flags & BLOB_FLAG) &&
370
((length > max_field_charlength &&
371
fld_type != DRIZZLE_TYPE_ENUM &&
372
(fld_type != DRIZZLE_TYPE_VARCHAR || fld_default_value)) ||
373
(!length && fld_type != DRIZZLE_TYPE_VARCHAR)))
375
my_error((fld_type == DRIZZLE_TYPE_VARCHAR) ? ER_TOO_BIG_FIELDLENGTH : ER_TOO_BIG_DISPLAYWIDTH,
377
fld_name, max_field_charlength);
380
fld_type_modifier&= AUTO_INCREMENT_FLAG;
381
if ((~allowed_type_modifier) & fld_type_modifier)
383
my_error(ER_WRONG_FIELD_SPEC, MYF(0), fld_name);
387
return false; /* success */