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
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/long.h"
41
#include "drizzled/field/int64_t.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/temporal.h"
55
/** Create a field suitable for create of table. */
56
CreateField::CreateField(Field *old_field, Field *orig_field)
59
field_name= change= old_field->field_name;
60
length= old_field->field_length;
61
flags= old_field->flags;
62
unireg_check= old_field->unireg_check;
63
pack_length= old_field->pack_length();
64
key_length= old_field->key_length();
65
sql_type= old_field->real_type();
66
charset= old_field->charset(); // May be NULL ptr
67
comment= old_field->comment;
68
decimals= old_field->decimals();
70
/* Fix if the original table had 4 byte pointer blobs */
71
if (flags & BLOB_FLAG)
72
pack_length= (pack_length - old_field->getTable()->getShare()->blob_ptr_size + portable_sizeof_char_ptr);
76
case DRIZZLE_TYPE_BLOB:
77
sql_type= DRIZZLE_TYPE_BLOB;
78
length/= charset->mbmaxlen;
79
key_length/= charset->mbmaxlen;
81
case DRIZZLE_TYPE_ENUM:
82
case DRIZZLE_TYPE_VARCHAR:
83
/* This is corrected in create_length_to_internal_length */
84
length= (length+charset->mbmaxlen-1) / charset->mbmaxlen;
90
if (flags & ENUM_FLAG)
91
interval= ((Field_enum*) old_field)->typelib;
97
if (!(flags & (NO_DEFAULT_VALUE_FLAG)) &&
98
!(flags & AUTO_INCREMENT_FLAG) &&
99
old_field->ptr && orig_field &&
100
(sql_type != DRIZZLE_TYPE_TIMESTAMP || /* set def only if */
101
old_field->getTable()->timestamp_field != old_field || /* timestamp field */
102
unireg_check == Field::TIMESTAMP_UN_FIELD)) /* has default val */
106
/* Get the value from default_values */
107
diff= (ptrdiff_t) (orig_field->getTable()->getDefaultValues() - orig_field->getTable()->getInsertRecord());
108
orig_field->move_field_offset(diff); // Points now at default_values
109
if (! orig_field->is_real_null())
111
char buff[MAX_FIELD_WIDTH], *pos;
112
String tmp(buff, sizeof(buff), charset), *res;
113
res= orig_field->val_str(&tmp);
114
pos= (char*) memory::sql_strmake(res->ptr(), res->length());
115
def= new Item_string(pos, res->length(), charset);
117
orig_field->move_field_offset(-diff); // Back to getInsertRecord()
122
Convert CreateField::length from number of characters to number of bytes.
124
void CreateField::create_length_to_internal_length(void)
128
case DRIZZLE_TYPE_BLOB:
129
case DRIZZLE_TYPE_VARCHAR:
130
length*= charset->mbmaxlen;
132
pack_length= calc_pack_length(sql_type, length);
134
case DRIZZLE_TYPE_ENUM:
135
/* Pack_length already calculated in ::init() */
136
length*= charset->mbmaxlen;
137
key_length= pack_length;
139
case DRIZZLE_TYPE_DECIMAL:
140
key_length= pack_length=
141
my_decimal_get_binary_size(my_decimal_length_to_precision(length,
148
key_length= pack_length= calc_pack_length(sql_type, length);
154
Init for a tmp table field. To be extended if need be.
156
void CreateField::init_for_tmp_table(enum_field_types sql_type_arg,
158
uint32_t decimals_arg,
162
sql_type= sql_type_arg;
163
char_length= length= length_arg;;
164
unireg_check= Field::NONE;
166
charset= &my_charset_bin;
167
decimals= decimals_arg & FIELDFLAG_MAX_DEC;
170
flags= NOT_NULL_FLAG;
175
bool CreateField::init(Session *,
177
enum_field_types fld_type,
180
uint32_t fld_type_modifier,
181
Item *fld_default_value,
182
Item *fld_on_update_value,
183
LEX_STRING *fld_comment,
185
List<String> *fld_interval_list,
186
const CHARSET_INFO * const fld_charset,
188
enum column_format_type column_format_in)
191
uint32_t sign_len= 0;
192
uint32_t allowed_type_modifier= 0;
193
uint32_t max_field_charlength= MAX_FIELD_CHARLENGTH;
196
field_name= fld_name;
197
def= fld_default_value;
198
flags= fld_type_modifier;
199
flags|= (((uint32_t)column_format_in & COLUMN_FORMAT_MASK) << COLUMN_FORMAT_FLAGS);
200
unireg_check= (fld_type_modifier & AUTO_INCREMENT_FLAG ?
201
Field::NEXT_NUMBER : Field::NONE);
202
decimals= fld_decimals ? (uint32_t)atoi(fld_decimals) : 0;
203
if (decimals >= NOT_FIXED_DEC)
205
my_error(ER_TOO_BIG_SCALE, MYF(0), decimals, fld_name,
214
pack_length= key_length= 0;
215
charset= fld_charset;
216
interval_list.empty();
218
comment= *fld_comment;
221
Set NO_DEFAULT_VALUE_FLAG if this field doesn't have a default value and
222
it is NOT NULL, not an AUTO_INCREMENT field and not a TIMESTAMP.
224
if (!fld_default_value && !(fld_type_modifier & AUTO_INCREMENT_FLAG) &&
225
(fld_type_modifier & NOT_NULL_FLAG) && fld_type != DRIZZLE_TYPE_TIMESTAMP)
226
flags|= NO_DEFAULT_VALUE_FLAG;
228
if (fld_length && !(length= (uint32_t) atoi(fld_length)))
230
sign_len= fld_type_modifier & UNSIGNED_FLAG ? 0 : 1;
234
case DRIZZLE_TYPE_LONG:
236
length= MAX_INT_WIDTH+sign_len;
237
allowed_type_modifier= AUTO_INCREMENT_FLAG;
239
case DRIZZLE_TYPE_LONGLONG:
241
length= MAX_BIGINT_WIDTH;
242
allowed_type_modifier= AUTO_INCREMENT_FLAG;
244
case DRIZZLE_TYPE_NULL:
246
case DRIZZLE_TYPE_DECIMAL:
247
my_decimal_trim(&length, &decimals);
248
if (length > DECIMAL_MAX_PRECISION)
250
my_error(ER_TOO_BIG_PRECISION, MYF(0), length, fld_name,
251
DECIMAL_MAX_PRECISION);
254
if (length < decimals)
256
my_error(ER_M_BIGGER_THAN_D, MYF(0), fld_name);
259
length= my_decimal_precision_to_length(length, decimals, fld_type_modifier & UNSIGNED_FLAG);
260
pack_length= my_decimal_get_binary_size(length, decimals);
262
case DRIZZLE_TYPE_VARCHAR:
264
Long VARCHAR's are automaticly converted to blobs in mysql_prepare_table
265
if they don't have a default value
267
max_field_charlength= MAX_FIELD_VARCHARLENGTH;
269
case DRIZZLE_TYPE_BLOB:
270
if (fld_default_value)
272
/* Allow empty as default value. */
274
res= fld_default_value->val_str(&str);
277
my_error(ER_BLOB_CANT_HAVE_DEFAULT, MYF(0), fld_name);
284
case DRIZZLE_TYPE_DOUBLE:
285
allowed_type_modifier= AUTO_INCREMENT_FLAG;
286
if (!fld_length && !fld_decimals)
289
decimals= NOT_FIXED_DEC;
291
if (length < decimals &&
292
decimals != NOT_FIXED_DEC)
294
my_error(ER_M_BIGGER_THAN_D, MYF(0), fld_name);
298
case DRIZZLE_TYPE_TIMESTAMP:
301
length= DateTime::MAX_STRING_LENGTH;
304
/* This assert() should be correct due to absence of length
305
specifiers for timestamp. Previous manipulation also wasn't
306
ever called (from examining lcov)
308
assert(length == (uint32_t)DateTime::MAX_STRING_LENGTH);
310
flags|= UNSIGNED_FLAG;
311
if (fld_default_value)
313
/* Grammar allows only NOW() value for ON UPDATE clause */
314
if (fld_default_value->type() == Item::FUNC_ITEM &&
315
((Item_func*)fld_default_value)->functype() == Item_func::NOW_FUNC)
317
unireg_check= (fld_on_update_value ? Field::TIMESTAMP_DNUN_FIELD:
318
Field::TIMESTAMP_DN_FIELD);
320
We don't need default value any longer moreover it is dangerous.
321
Everything handled by unireg_check further.
326
unireg_check= (fld_on_update_value ? Field::TIMESTAMP_UN_FIELD:
332
If we have default TIMESTAMP NOT NULL column without explicit DEFAULT
333
or ON UPDATE values then for the sake of compatiblity we should treat
334
this column as having DEFAULT NOW() ON UPDATE NOW() (when we don't
335
have another TIMESTAMP column with auto-set option before this one)
336
or DEFAULT 0 (in other cases).
337
So here we are setting TIMESTAMP_OLD_FIELD only temporary, and will
338
replace this value by TIMESTAMP_DNUN_FIELD or NONE later when
339
information about all TIMESTAMP fields in table will be availiable.
341
If we have TIMESTAMP NULL column without explicit DEFAULT value
342
we treat it as having DEFAULT NULL attribute.
344
unireg_check= (fld_on_update_value ? Field::TIMESTAMP_UN_FIELD :
345
(flags & NOT_NULL_FLAG ? Field::TIMESTAMP_OLD_FIELD :
349
case DRIZZLE_TYPE_DATE:
350
length= Date::MAX_STRING_LENGTH;
352
case DRIZZLE_TYPE_DATETIME:
353
length= DateTime::MAX_STRING_LENGTH;
355
case DRIZZLE_TYPE_ENUM:
357
/* Should be safe. */
360
List_iterator<String> it(*fld_interval_list);
363
interval_list.push_back(tmp);
368
/* Remember the value of length */
371
if (!(flags & BLOB_FLAG) &&
372
((length > max_field_charlength &&
373
fld_type != DRIZZLE_TYPE_ENUM &&
374
(fld_type != DRIZZLE_TYPE_VARCHAR || fld_default_value)) ||
375
(!length && fld_type != DRIZZLE_TYPE_VARCHAR)))
377
my_error((fld_type == DRIZZLE_TYPE_VARCHAR) ? ER_TOO_BIG_FIELDLENGTH : ER_TOO_BIG_DISPLAYWIDTH,
379
fld_name, max_field_charlength);
382
fld_type_modifier&= AUTO_INCREMENT_FLAG;
383
if ((~allowed_type_modifier) & fld_type_modifier)
385
my_error(ER_WRONG_FIELD_SPEC, MYF(0), fld_name);
389
return false; /* success */
392
} /* namespace drizzled */