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