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, Inc.
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/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>
52
#include <drizzled/display.h>
61
/** Create a field suitable for create of table. */
62
CreateField::CreateField(Field *old_field, Field *orig_field)
65
field_name= change= old_field->field_name;
66
length= old_field->field_length;
67
flags= old_field->flags;
68
unireg_check= old_field->unireg_check;
69
pack_length= old_field->pack_length();
70
key_length= old_field->key_length();
71
sql_type= old_field->real_type();
72
charset= old_field->charset(); // May be NULL ptr
73
comment= old_field->comment;
74
decimals= old_field->decimals();
76
/* Fix if the original table had 4 byte pointer blobs */
77
if (flags & BLOB_FLAG)
79
pack_length= (pack_length - old_field->getTable()->getShare()->sizeBlobPtr() + portable_sizeof_char_ptr);
84
case DRIZZLE_TYPE_BLOB:
85
sql_type= DRIZZLE_TYPE_BLOB;
86
length/= charset->mbmaxlen;
87
key_length/= charset->mbmaxlen;
89
case DRIZZLE_TYPE_ENUM:
90
case DRIZZLE_TYPE_VARCHAR:
91
/* This is corrected in create_length_to_internal_length */
92
length= (length+charset->mbmaxlen-1) / charset->mbmaxlen;
98
if (flags & ENUM_FLAG)
99
interval= ((Field_enum*) old_field)->typelib;
105
if (!(flags & (NO_DEFAULT_VALUE_FLAG)) &&
106
!(flags & AUTO_INCREMENT_FLAG) &&
107
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 */
110
unireg_check == Field::TIMESTAMP_UN_FIELD)) /* has default val */
114
/* Get the value from default_values */
115
diff= (ptrdiff_t) (orig_field->getTable()->getDefaultValues() - orig_field->getTable()->getInsertRecord());
116
orig_field->move_field_offset(diff); // Points now at default_values
117
if (! orig_field->is_real_null())
119
char buff[MAX_FIELD_WIDTH], *pos;
120
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());
123
def= new Item_string(pos, res->length(), charset);
125
orig_field->move_field_offset(-diff); // Back to getInsertRecord()
130
Convert CreateField::length from number of characters to number of bytes.
132
void CreateField::create_length_to_internal_length(void)
136
case DRIZZLE_TYPE_BLOB:
137
case DRIZZLE_TYPE_VARCHAR:
138
length*= charset->mbmaxlen;
140
pack_length= calc_pack_length(sql_type, length);
142
case DRIZZLE_TYPE_ENUM:
143
/* Pack_length already calculated in ::init() */
144
length*= charset->mbmaxlen;
145
key_length= pack_length;
147
case DRIZZLE_TYPE_DECIMAL:
148
key_length= pack_length=
149
class_decimal_get_binary_size(class_decimal_length_to_precision(length,
156
key_length= pack_length= calc_pack_length(sql_type, length);
162
Init for a tmp table field. To be extended if need be.
164
void CreateField::init_for_tmp_table(enum_field_types sql_type_arg,
166
uint32_t decimals_arg,
170
sql_type= sql_type_arg;
171
char_length= length= length_arg;;
172
unireg_check= Field::NONE;
174
charset= &my_charset_bin;
175
decimals= decimals_arg & FIELDFLAG_MAX_DEC;
178
flags= NOT_NULL_FLAG;
183
bool CreateField::init(Session *,
185
enum_field_types fld_type,
188
uint32_t fld_type_modifier,
189
Item *fld_default_value,
190
Item *fld_on_update_value,
191
LEX_STRING *fld_comment,
193
List<String> *fld_interval_list,
194
const CHARSET_INFO * const fld_charset,
196
enum column_format_type column_format_in)
199
uint32_t sign_len= 0;
200
uint32_t allowed_type_modifier= 0;
201
uint32_t max_field_charlength= MAX_FIELD_CHARLENGTH;
204
field_name= fld_name;
205
def= fld_default_value;
206
flags= fld_type_modifier;
207
flags|= (((uint32_t)column_format_in & COLUMN_FORMAT_MASK) << COLUMN_FORMAT_FLAGS);
208
unireg_check= (fld_type_modifier & AUTO_INCREMENT_FLAG ?
209
Field::NEXT_NUMBER : Field::NONE);
210
decimals= fld_decimals ? (uint32_t)atoi(fld_decimals) : 0;
211
if (decimals >= NOT_FIXED_DEC)
213
my_error(ER_TOO_BIG_SCALE, MYF(0), decimals, fld_name,
222
pack_length= key_length= 0;
223
charset= fld_charset;
224
interval_list.clear();
226
comment= *fld_comment;
229
Set NO_DEFAULT_VALUE_FLAG if this field doesn't have a default value and
230
it is NOT NULL, not an AUTO_INCREMENT field and not a TIMESTAMP.
232
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))
235
flags|= NO_DEFAULT_VALUE_FLAG;
238
if (fld_length && !(length= (uint32_t) atoi(fld_length)))
240
sign_len= fld_type_modifier & UNSIGNED_FLAG ? 0 : 1;
244
case DRIZZLE_TYPE_LONG:
246
length= MAX_INT_WIDTH+sign_len;
247
allowed_type_modifier= AUTO_INCREMENT_FLAG;
249
case DRIZZLE_TYPE_LONGLONG:
251
length= MAX_BIGINT_WIDTH;
252
allowed_type_modifier= AUTO_INCREMENT_FLAG;
254
case DRIZZLE_TYPE_NULL:
256
case DRIZZLE_TYPE_DECIMAL:
257
class_decimal_trim(&length, &decimals);
258
if (length > DECIMAL_MAX_PRECISION)
260
my_error(ER_TOO_BIG_PRECISION, MYF(0), length, fld_name,
261
DECIMAL_MAX_PRECISION);
264
if (length < decimals)
266
my_error(ER_M_BIGGER_THAN_D, MYF(0), fld_name);
269
length= class_decimal_precision_to_length(length, decimals, fld_type_modifier & UNSIGNED_FLAG);
270
pack_length= class_decimal_get_binary_size(length, decimals);
272
case DRIZZLE_TYPE_VARCHAR:
274
Long VARCHAR's are automaticly converted to blobs in mysql_prepare_table
275
if they don't have a default value
277
max_field_charlength= MAX_FIELD_VARCHARLENGTH;
279
case DRIZZLE_TYPE_BLOB:
280
if (fld_default_value)
282
/* Allow empty as default value. */
284
res= fld_default_value->val_str(&str);
287
my_error(ER_BLOB_CANT_HAVE_DEFAULT, MYF(0), fld_name);
294
case DRIZZLE_TYPE_DOUBLE:
295
allowed_type_modifier= AUTO_INCREMENT_FLAG;
296
if (!fld_length && !fld_decimals)
299
decimals= NOT_FIXED_DEC;
301
if (length < decimals &&
302
decimals != NOT_FIXED_DEC)
304
my_error(ER_M_BIGGER_THAN_D, MYF(0), fld_name);
308
case DRIZZLE_TYPE_MICROTIME:
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)
315
case DRIZZLE_TYPE_TIMESTAMP:
316
length= MicroTimestamp::MAX_STRING_LENGTH;
318
if (fld_default_value)
320
/* Grammar allows only NOW() value for ON UPDATE clause */
321
if (fld_default_value->type() == Item::FUNC_ITEM &&
322
((Item_func*)fld_default_value)->functype() == Item_func::NOW_FUNC)
324
unireg_check= (fld_on_update_value ? Field::TIMESTAMP_DNUN_FIELD:
325
Field::TIMESTAMP_DN_FIELD);
327
We don't need default value any longer moreover it is dangerous.
328
Everything handled by unireg_check further.
334
unireg_check= (fld_on_update_value ? Field::TIMESTAMP_UN_FIELD:
341
If we have default TIMESTAMP NOT NULL column without explicit DEFAULT
342
or ON UPDATE values then for the sake of compatiblity we should treat
343
this column as having DEFAULT NOW() ON UPDATE NOW() (when we don't
344
have another TIMESTAMP column with auto-set option before this one)
345
or DEFAULT 0 (in other cases).
346
So here we are setting TIMESTAMP_OLD_FIELD only temporary, and will
347
replace this value by TIMESTAMP_DNUN_FIELD or NONE later when
348
information about all TIMESTAMP fields in table will be availiable.
350
If we have TIMESTAMP NULL column without explicit DEFAULT value
351
we treat it as having DEFAULT NULL attribute.
353
unireg_check= (fld_on_update_value ? Field::TIMESTAMP_UN_FIELD :
354
(flags & NOT_NULL_FLAG ? Field::TIMESTAMP_OLD_FIELD :
358
case DRIZZLE_TYPE_DATE:
359
length= Date::MAX_STRING_LENGTH;
361
case DRIZZLE_TYPE_UUID:
362
length= field::Uuid::max_string_length();
364
case DRIZZLE_TYPE_BOOLEAN:
365
length= field::Boolean::max_string_length();
367
case DRIZZLE_TYPE_DATETIME:
368
length= DateTime::MAX_STRING_LENGTH;
370
case DRIZZLE_TYPE_TIME:
371
length= DateTime::MAX_STRING_LENGTH;
373
case DRIZZLE_TYPE_ENUM:
375
/* Should be safe. */
378
List<String>::iterator it(fld_interval_list->begin());
381
interval_list.push_back(tmp);
386
/* Remember the value of length */
389
if (!(flags & BLOB_FLAG) &&
390
((length > max_field_charlength &&
391
fld_type != DRIZZLE_TYPE_ENUM &&
392
(fld_type != DRIZZLE_TYPE_VARCHAR || fld_default_value)) ||
393
(!length && fld_type != DRIZZLE_TYPE_VARCHAR)))
395
my_error((fld_type == DRIZZLE_TYPE_VARCHAR) ? ER_TOO_BIG_FIELDLENGTH : ER_TOO_BIG_DISPLAYWIDTH,
397
fld_name, max_field_charlength);
400
fld_type_modifier&= AUTO_INCREMENT_FLAG;
401
if ((~allowed_type_modifier) & fld_type_modifier)
403
my_error(ER_WRONG_FIELD_SPEC, MYF(0), fld_name);
407
return false; /* success */
410
std::ostream& operator<<(std::ostream& output, const CreateField &field)
412
output << "CreateField:(";
413
output << field.field_name;
415
output << drizzled::display::type(field.type());
418
if (field.flags & NOT_NULL_FLAG)
419
output << " NOT_NULL";
421
if (field.flags & PRI_KEY_FLAG)
422
output << ", PRIMARY KEY";
424
if (field.flags & UNIQUE_KEY_FLAG)
425
output << ", UNIQUE KEY";
427
if (field.flags & MULTIPLE_KEY_FLAG)
428
output << ", MULTIPLE KEY";
430
if (field.flags & BLOB_FLAG)
433
if (field.flags & UNSIGNED_FLAG)
434
output << ", UNSIGNED";
436
if (field.flags & BINARY_FLAG)
437
output << ", BINARY";
440
output << *field.field;
443
return output; // for multiple << operators.
446
} /* namespace drizzled */