00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00024 #include <config.h>
00025 #include <errno.h>
00026 #include <float.h>
00027 #include <drizzled/sql_select.h>
00028 #include <drizzled/error.h>
00029 #include <drizzled/field.h>
00030 #include <drizzled/create_field.h>
00031 #include <drizzled/field/str.h>
00032 #include <drizzled/field/num.h>
00033 #include <drizzled/field/blob.h>
00034 #include <drizzled/field/boolean.h>
00035 #include <drizzled/field/enum.h>
00036 #include <drizzled/field/null.h>
00037 #include <drizzled/field/date.h>
00038 #include <drizzled/field/decimal.h>
00039 #include <drizzled/field/real.h>
00040 #include <drizzled/field/double.h>
00041 #include <drizzled/field/int32.h>
00042 #include <drizzled/field/int64.h>
00043 #include <drizzled/field/num.h>
00044 #include <drizzled/field/epoch.h>
00045 #include <drizzled/field/datetime.h>
00046 #include <drizzled/field/varstring.h>
00047 #include <drizzled/field/uuid.h>
00048 #include <drizzled/temporal.h>
00049 #include <drizzled/item/string.h>
00050 #include <drizzled/table.h>
00051
00052 #include <drizzled/display.h>
00053
00054 #include <algorithm>
00055
00056 using namespace std;
00057
00058 namespace drizzled
00059 {
00060
00062 CreateField::CreateField(Field *old_field, Field *orig_field)
00063 {
00064 field= old_field;
00065 field_name= change= old_field->field_name;
00066 length= old_field->field_length;
00067 flags= old_field->flags;
00068 unireg_check= old_field->unireg_check;
00069 pack_length= old_field->pack_length();
00070 key_length= old_field->key_length();
00071 sql_type= old_field->real_type();
00072 charset= old_field->charset();
00073 comment= old_field->comment;
00074 decimals= old_field->decimals();
00075
00076
00077 if (flags & BLOB_FLAG)
00078 {
00079 pack_length= (pack_length - old_field->getTable()->getShare()->sizeBlobPtr() + portable_sizeof_char_ptr);
00080 }
00081
00082 switch (sql_type)
00083 {
00084 case DRIZZLE_TYPE_BLOB:
00085 sql_type= DRIZZLE_TYPE_BLOB;
00086 length/= charset->mbmaxlen;
00087 key_length/= charset->mbmaxlen;
00088 break;
00089 case DRIZZLE_TYPE_ENUM:
00090 case DRIZZLE_TYPE_VARCHAR:
00091
00092 length= (length+charset->mbmaxlen-1) / charset->mbmaxlen;
00093 break;
00094 default:
00095 break;
00096 }
00097
00098 if (flags & ENUM_FLAG)
00099 interval= ((Field_enum*) old_field)->typelib;
00100 else
00101 interval= 0;
00102 def= 0;
00103 char_length= length;
00104
00105 if (!(flags & (NO_DEFAULT_VALUE_FLAG)) &&
00106 !(flags & AUTO_INCREMENT_FLAG) &&
00107 old_field->ptr && orig_field &&
00108 (not old_field->is_timestamp() ||
00109 old_field->getTable()->timestamp_field != old_field ||
00110 unireg_check == Field::TIMESTAMP_UN_FIELD))
00111 {
00112 ptrdiff_t diff;
00113
00114
00115 diff= (ptrdiff_t) (orig_field->getTable()->getDefaultValues() - orig_field->getTable()->getInsertRecord());
00116 orig_field->move_field_offset(diff);
00117 if (! orig_field->is_real_null())
00118 {
00119 char buff[MAX_FIELD_WIDTH], *pos;
00120 String tmp(buff, sizeof(buff), charset), *res;
00121 res= orig_field->val_str_internal(&tmp);
00122 pos= (char*) memory::sql_strmake(res->ptr(), res->length());
00123 def= new Item_string(pos, res->length(), charset);
00124 }
00125 orig_field->move_field_offset(-diff);
00126 }
00127 }
00128
00132 void CreateField::create_length_to_internal_length(void)
00133 {
00134 switch (sql_type)
00135 {
00136 case DRIZZLE_TYPE_BLOB:
00137 case DRIZZLE_TYPE_VARCHAR:
00138 length*= charset->mbmaxlen;
00139 key_length= length;
00140 pack_length= calc_pack_length(sql_type, length);
00141 break;
00142 case DRIZZLE_TYPE_ENUM:
00143
00144 length*= charset->mbmaxlen;
00145 key_length= pack_length;
00146 break;
00147 case DRIZZLE_TYPE_DECIMAL:
00148 key_length= pack_length=
00149 class_decimal_get_binary_size(class_decimal_length_to_precision(length,
00150 decimals,
00151 flags &
00152 UNSIGNED_FLAG),
00153 decimals);
00154 break;
00155 default:
00156 key_length= pack_length= calc_pack_length(sql_type, length);
00157 break;
00158 }
00159 }
00160
00164 void CreateField::init_for_tmp_table(enum_field_types sql_type_arg,
00165 uint32_t length_arg,
00166 uint32_t decimals_arg,
00167 bool maybe_null)
00168 {
00169 field_name= "";
00170 sql_type= sql_type_arg;
00171 char_length= length= length_arg;;
00172 unireg_check= Field::NONE;
00173 interval= 0;
00174 charset= &my_charset_bin;
00175 decimals= decimals_arg & FIELDFLAG_MAX_DEC;
00176
00177 if (! maybe_null)
00178 flags= NOT_NULL_FLAG;
00179 else
00180 flags= 0;
00181 }
00182
00183 bool CreateField::init(Session *,
00184 char *fld_name,
00185 enum_field_types fld_type,
00186 char *fld_length,
00187 char *fld_decimals,
00188 uint32_t fld_type_modifier,
00189 Item *fld_default_value,
00190 Item *fld_on_update_value,
00191 LEX_STRING *fld_comment,
00192 char *fld_change,
00193 List<String> *fld_interval_list,
00194 const CHARSET_INFO * const fld_charset,
00195 uint32_t,
00196 enum column_format_type column_format_in)
00197
00198 {
00199 uint32_t sign_len= 0;
00200 uint32_t allowed_type_modifier= 0;
00201 uint32_t max_field_charlength= MAX_FIELD_CHARLENGTH;
00202
00203 field= 0;
00204 field_name= fld_name;
00205 def= fld_default_value;
00206 flags= fld_type_modifier;
00207 flags|= (((uint32_t)column_format_in & COLUMN_FORMAT_MASK) << COLUMN_FORMAT_FLAGS);
00208 unireg_check= (fld_type_modifier & AUTO_INCREMENT_FLAG ?
00209 Field::NEXT_NUMBER : Field::NONE);
00210 decimals= fld_decimals ? (uint32_t)atoi(fld_decimals) : 0;
00211 if (decimals >= NOT_FIXED_DEC)
00212 {
00213 my_error(ER_TOO_BIG_SCALE, MYF(0), decimals, fld_name,
00214 NOT_FIXED_DEC-1);
00215 return(true);
00216 }
00217
00218 sql_type= fld_type;
00219 length= 0;
00220 change= fld_change;
00221 interval= 0;
00222 pack_length= key_length= 0;
00223 charset= fld_charset;
00224 interval_list.clear();
00225
00226 comment= *fld_comment;
00227
00228
00229
00230
00231
00232 if (!fld_default_value && !(fld_type_modifier & AUTO_INCREMENT_FLAG) &&
00233 (fld_type_modifier & NOT_NULL_FLAG) && (fld_type != DRIZZLE_TYPE_TIMESTAMP and fld_type != DRIZZLE_TYPE_MICROTIME))
00234 {
00235 flags|= NO_DEFAULT_VALUE_FLAG;
00236 }
00237
00238 if (fld_length && !(length= (uint32_t) atoi(fld_length)))
00239 fld_length= 0;
00240 sign_len= fld_type_modifier & UNSIGNED_FLAG ? 0 : 1;
00241
00242 switch (fld_type)
00243 {
00244 case DRIZZLE_TYPE_LONG:
00245 if (!fld_length)
00246 length= MAX_INT_WIDTH+sign_len;
00247 allowed_type_modifier= AUTO_INCREMENT_FLAG;
00248 break;
00249 case DRIZZLE_TYPE_LONGLONG:
00250 if (!fld_length)
00251 length= MAX_BIGINT_WIDTH;
00252 allowed_type_modifier= AUTO_INCREMENT_FLAG;
00253 break;
00254 case DRIZZLE_TYPE_NULL:
00255 break;
00256 case DRIZZLE_TYPE_DECIMAL:
00257 class_decimal_trim(&length, &decimals);
00258 if (length > DECIMAL_MAX_PRECISION)
00259 {
00260 my_error(ER_TOO_BIG_PRECISION, MYF(0), length, fld_name,
00261 DECIMAL_MAX_PRECISION);
00262 return(true);
00263 }
00264 if (length < decimals)
00265 {
00266 my_error(ER_M_BIGGER_THAN_D, MYF(0), fld_name);
00267 return(true);
00268 }
00269 length= class_decimal_precision_to_length(length, decimals, fld_type_modifier & UNSIGNED_FLAG);
00270 pack_length= class_decimal_get_binary_size(length, decimals);
00271 break;
00272 case DRIZZLE_TYPE_VARCHAR:
00273
00274
00275
00276
00277 max_field_charlength= MAX_FIELD_VARCHARLENGTH;
00278 break;
00279 case DRIZZLE_TYPE_BLOB:
00280 if (fld_default_value)
00281 {
00282
00283 String str,*res;
00284 res= fld_default_value->val_str(&str);
00285 if (res->length())
00286 {
00287 my_error(ER_BLOB_CANT_HAVE_DEFAULT, MYF(0), fld_name);
00288 return(true);
00289 }
00290
00291 }
00292 flags|= BLOB_FLAG;
00293 break;
00294 case DRIZZLE_TYPE_DOUBLE:
00295 allowed_type_modifier= AUTO_INCREMENT_FLAG;
00296 if (!fld_length && !fld_decimals)
00297 {
00298 length= DBL_DIG+7;
00299 decimals= NOT_FIXED_DEC;
00300 }
00301 if (length < decimals &&
00302 decimals != NOT_FIXED_DEC)
00303 {
00304 my_error(ER_M_BIGGER_THAN_D, MYF(0), fld_name);
00305 return(true);
00306 }
00307 break;
00308 case DRIZZLE_TYPE_MICROTIME:
00309
00310
00311
00312
00313
00314 assert(fld_type);
00315 case DRIZZLE_TYPE_TIMESTAMP:
00316 length= MicroTimestamp::MAX_STRING_LENGTH;
00317
00318 if (fld_default_value)
00319 {
00320
00321 if (fld_default_value->type() == Item::FUNC_ITEM &&
00322 ((Item_func*)fld_default_value)->functype() == Item_func::NOW_FUNC)
00323 {
00324 unireg_check= (fld_on_update_value ? Field::TIMESTAMP_DNUN_FIELD:
00325 Field::TIMESTAMP_DN_FIELD);
00326
00327
00328
00329
00330 def= 0;
00331 }
00332 else
00333 {
00334 unireg_check= (fld_on_update_value ? Field::TIMESTAMP_UN_FIELD:
00335 Field::NONE);
00336 }
00337 }
00338 else
00339 {
00340
00341
00342
00343
00344
00345
00346
00347
00348
00349
00350
00351
00352
00353 unireg_check= (fld_on_update_value ? Field::TIMESTAMP_UN_FIELD :
00354 (flags & NOT_NULL_FLAG ? Field::TIMESTAMP_OLD_FIELD :
00355 Field::NONE));
00356 }
00357 break;
00358 case DRIZZLE_TYPE_DATE:
00359 length= Date::MAX_STRING_LENGTH;
00360 break;
00361 case DRIZZLE_TYPE_UUID:
00362 length= field::Uuid::max_string_length();
00363 break;
00364 case DRIZZLE_TYPE_BOOLEAN:
00365 length= field::Boolean::max_string_length();
00366 break;
00367 case DRIZZLE_TYPE_DATETIME:
00368 length= DateTime::MAX_STRING_LENGTH;
00369 break;
00370 case DRIZZLE_TYPE_TIME:
00371 length= DateTime::MAX_STRING_LENGTH;
00372 break;
00373 case DRIZZLE_TYPE_ENUM:
00374 {
00375
00376 pack_length= 4;
00377
00378 List<String>::iterator it(fld_interval_list->begin());
00379 String *tmp;
00380 while ((tmp= it++))
00381 interval_list.push_back(tmp);
00382 length= 1;
00383 break;
00384 }
00385 }
00386
00387 char_length= length;
00388
00389 if (!(flags & BLOB_FLAG) &&
00390 ((length > max_field_charlength &&
00391 fld_type != DRIZZLE_TYPE_ENUM &&
00392 (fld_type != DRIZZLE_TYPE_VARCHAR || fld_default_value)) ||
00393 (!length && fld_type != DRIZZLE_TYPE_VARCHAR)))
00394 {
00395 my_error((fld_type == DRIZZLE_TYPE_VARCHAR) ? ER_TOO_BIG_FIELDLENGTH : ER_TOO_BIG_DISPLAYWIDTH,
00396 MYF(0),
00397 fld_name, max_field_charlength);
00398 return true;
00399 }
00400 fld_type_modifier&= AUTO_INCREMENT_FLAG;
00401 if ((~allowed_type_modifier) & fld_type_modifier)
00402 {
00403 my_error(ER_WRONG_FIELD_SPEC, MYF(0), fld_name);
00404 return true;
00405 }
00406
00407 return false;
00408 }
00409
00410 std::ostream& operator<<(std::ostream& output, const CreateField &field)
00411 {
00412 output << "CreateField:(";
00413 output << field.field_name;
00414 output << ", ";
00415 output << drizzled::display::type(field.type());
00416 output << ", { ";
00417
00418 if (field.flags & NOT_NULL_FLAG)
00419 output << " NOT_NULL";
00420
00421 if (field.flags & PRI_KEY_FLAG)
00422 output << ", PRIMARY KEY";
00423
00424 if (field.flags & UNIQUE_KEY_FLAG)
00425 output << ", UNIQUE KEY";
00426
00427 if (field.flags & MULTIPLE_KEY_FLAG)
00428 output << ", MULTIPLE KEY";
00429
00430 if (field.flags & BLOB_FLAG)
00431 output << ", BLOB";
00432
00433 if (field.flags & UNSIGNED_FLAG)
00434 output << ", UNSIGNED";
00435
00436 if (field.flags & BINARY_FLAG)
00437 output << ", BINARY";
00438 output << "}, ";
00439 if (field.field)
00440 output << *field.field;
00441 output << ")";
00442
00443 return output;
00444 }
00445
00446 }