19 #include <plugin/myisam/myisam.h>
21 #include <drizzled/error.h>
22 #include <drizzled/gettext.h>
23 #include <drizzled/data_home.h>
24 #include <drizzled/sql_parse.h>
25 #include <drizzled/sql_lex.h>
26 #include <drizzled/session.h>
27 #include <drizzled/sql_base.h>
28 #include <drizzled/lock.h>
29 #include <drizzled/item/int.h>
30 #include <drizzled/item/empty_string.h>
31 #include <drizzled/transaction_services.h>
32 #include <drizzled/transaction_services.h>
33 #include <drizzled/table_proto.h>
34 #include <drizzled/plugin/client.h>
35 #include <drizzled/identifier.h>
36 #include <drizzled/internal/m_string.h>
37 #include <drizzled/charset.h>
38 #include <drizzled/definition/cache.h>
39 #include <drizzled/system_variables.h>
40 #include <drizzled/statement/alter_table.h>
42 #include <drizzled/pthread_globals.h>
43 #include <drizzled/typelib.h>
44 #include <drizzled/plugin/storage_engine.h>
45 #include <drizzled/diagnostics_area.h>
46 #include <drizzled/open_tables_state.h>
47 #include <drizzled/table/cache.h>
48 #include <drizzled/create_field.h>
53 #include <boost/unordered_set.hpp>
59 bool is_primary_key(
const char* name)
61 return strcmp(name,
"PRIMARY") == 0;
64 static bool check_if_keyname_exists(
const char *name,KeyInfo *start, KeyInfo *end);
65 static const char *make_unique_key_name(
const char *field_name,KeyInfo *start,KeyInfo *end);
66 static bool prepare_blob_field(Session *session, CreateField *sql_field);
68 void set_table_default_charset(
const identifier::Catalog &catalog, HA_CREATE_INFO *create_info,
const char *db)
75 if (not create_info->default_table_charset)
76 create_info->default_table_charset= plugin::StorageEngine::getSchemaCollation(identifier::Schema(catalog,
str_ref(db)));
106 int rm_table_part2(Session *session, TableList *tables,
bool if_exists,
110 util::string::vector wrong_tables;
112 bool foreign_key_error=
false;
116 boost::mutex::scoped_lock scopedLock(table::Cache::mutex());
118 if (not drop_temporary && session->lock_table_names_exclusively(tables))
124 session->no_warnings_for_error= 1;
126 for (table= tables; table; table= table->next_local)
128 identifier::Table tmp_identifier(session->catalog().identifier(),
129 table->getSchemaName(),
130 table->getTableName());
132 error= session->open_tables.drop_temporary_table(tmp_identifier);
146 if (drop_temporary ==
false)
148 abort_locked_tables(session, tmp_identifier);
149 table::Cache::removeTable(*session, tmp_identifier, RTFC_WAIT_OTHER_THREAD_FLAG | RTFC_CHECK_KILLED_FLAG);
154 Table *locked_table= drop_locked_tables(session, tmp_identifier);
156 table->table= locked_table;
158 if (session->getKilled())
164 identifier::Table identifier(session->catalog().identifier(),
165 table->getSchemaName(),
166 table->getTableName(),
167 table->getInternalTmpTable() ? message::Table::INTERNAL : message::Table::STANDARD);
169 message::table::shared_ptr message= plugin::StorageEngine::getTableMessage(*session, identifier,
true);
171 if (drop_temporary || not plugin::StorageEngine::doesTableExist(*session, identifier))
176 push_warning_printf(session, DRIZZLE_ERROR::WARN_LEVEL_NOTE,
177 ER_BAD_TABLE_ERROR, ER(ER_BAD_TABLE_ERROR),
178 table->getTableName());
187 drizzled::error_t local_error;
190 if (plugin::StorageEngine::dropTable(*session, identifier, local_error))
194 TransactionServices::dropTable(*session, identifier, *message, if_exists);
199 if (local_error == HA_ERR_NO_SUCH_TABLE and if_exists)
202 session->clear_error();
205 if (local_error == HA_ERR_ROW_IS_REFERENCED)
208 foreign_key_error=
true;
216 wrong_tables.push_back(table->getTableName());
220 tables->unlock_table_names();
224 if (wrong_tables.size())
226 if (not foreign_key_error)
228 std::string table_error;
230 BOOST_FOREACH(util::string::vector::reference iter, wrong_tables)
235 table_error.resize(table_error.size() -1);
237 my_printf_error(ER_BAD_TABLE_ERROR, ER(ER_BAD_TABLE_ERROR), MYF(0),
238 table_error.c_str());
242 my_message(ER_ROW_IS_REFERENCED, ER(ER_ROW_IS_REFERENCED), MYF(0));
247 session->no_warnings_for_error= 0;
265 static int sort_keys(KeyInfo *a, KeyInfo *b)
267 ulong a_flags= a->flags, b_flags= b->flags;
269 if (a_flags & HA_NOSAME)
271 if (!(b_flags & HA_NOSAME))
273 if ((a_flags ^ b_flags) & (HA_NULL_PART_KEY))
276 return (a_flags & (HA_NULL_PART_KEY)) ? 1 : -1;
278 if (is_primary_key(a->name))
280 if (is_primary_key(b->name))
283 if ((a_flags ^ b_flags) & HA_KEY_HAS_PART_KEY_SEG)
284 return (a_flags & HA_KEY_HAS_PART_KEY_SEG) ? 1 : -1;
286 else if (b_flags & HA_NOSAME)
293 return ((a->usable_key_parts < b->usable_key_parts) ? -1 :
294 (a->usable_key_parts > b->usable_key_parts) ? 1 :
332 return (my_strnncoll(a.cs,
333 (
const unsigned char*)a.s.c_str(), a.s.length(),
334 (
const unsigned char*)b.s.c_str(), b.s.length())==0);
340 class typelib_set_member_hasher
342 boost::hash<string> hasher;
344 std::size_t operator()(
const typelib_set_member& t)
const
351 static bool check_duplicates_in_interval(
const char *set_or_name,
352 const char *name, TYPELIB *typelib,
353 const charset_info_st *
const cs,
354 unsigned int *dup_val_count)
356 TYPELIB tmp= *typelib;
357 const char **cur_value= typelib->type_names;
358 unsigned int *cur_length= typelib->type_lengths;
361 boost::unordered_set<typelib_set_member, typelib_set_member_hasher> interval_set;
363 for ( ; tmp.count > 0; cur_value++, cur_length++)
368 if (interval_set.count(typelib_set_member(*cur_value, *cur_length, cs)))
370 my_error(ER_DUPLICATED_VALUE_IN_TYPE, MYF(0),
371 name,*cur_value,set_or_name);
375 interval_set.insert(typelib_set_member(*cur_value, *cur_length, cs));
399 static void calculate_interval_lengths(
const charset_info_st *
const cs,
401 uint32_t *max_length,
402 uint32_t *tot_length)
406 *max_length= *tot_length= 0;
407 for (pos= interval->type_names, len= interval->type_lengths;
410 uint32_t length= cs->cset->numchars(cs, *pos, *pos + *len);
411 *tot_length+= length;
412 set_if_bigger(*max_length, (uint32_t)length);
433 int prepare_create_field(CreateField *sql_field,
434 uint32_t *blob_columns,
436 int *timestamps_with_niladic)
438 unsigned int dup_val_count;
444 assert(sql_field->charset);
446 switch (sql_field->sql_type) {
447 case DRIZZLE_TYPE_BLOB:
448 sql_field->length= 8;
452 case DRIZZLE_TYPE_ENUM:
454 if (check_duplicates_in_interval(
"ENUM",
455 sql_field->field_name,
465 case DRIZZLE_TYPE_MICROTIME:
466 case DRIZZLE_TYPE_TIMESTAMP:
468 if (sql_field->unireg_check == Field::TIMESTAMP_OLD_FIELD)
472 sql_field->unireg_check= Field::TIMESTAMP_DNUN_FIELD;
473 (*timestamps_with_niladic)++;
477 sql_field->unireg_check= Field::NONE;
480 else if (sql_field->unireg_check != Field::NONE)
482 (*timestamps_with_niladic)++;
489 case DRIZZLE_TYPE_BOOLEAN:
490 case DRIZZLE_TYPE_DATE:
491 case DRIZZLE_TYPE_DATETIME:
492 case DRIZZLE_TYPE_DECIMAL:
493 case DRIZZLE_TYPE_DOUBLE:
494 case DRIZZLE_TYPE_LONG:
495 case DRIZZLE_TYPE_LONGLONG:
496 case DRIZZLE_TYPE_NULL:
497 case DRIZZLE_TYPE_TIME:
498 case DRIZZLE_TYPE_UUID:
499 case DRIZZLE_TYPE_IPV6:
500 case DRIZZLE_TYPE_VARCHAR:
512 uint32_t *db_options,
515 int select_field_count)
517 const char *key_name;
519 uint field,null_fields,blob_columns,max_key_length;
520 ulong record_offset= 0;
523 int timestamps= 0, timestamps_with_niladic= 0;
525 int select_field_pos,auto_increment=0;
528 uint32_t total_uneven_bit_length= 0;
532 select_field_pos= alter_info->create_list.size() - select_field_count;
533 null_fields=blob_columns=0;
534 max_key_length= engine->max_key_length();
536 for (int32_t field_no=0; (sql_field=it++) ; field_no++)
548 sql_field->
charset= create_info->default_table_charset;
556 if (create_info->table_charset && sql_field->
charset != &my_charset_bin)
557 sql_field->
charset= create_info->table_charset;
560 if ((sql_field->flags & BINCMP_FLAG) &&
561 !(sql_field->
charset= get_charset_by_csname(sql_field->
charset->csname, MY_CS_BINSORT)))
565 strncpy(tmp_pos, save_cs->csname,
sizeof(tmp)-4);
566 tmp_pos+= strlen(tmp);
567 strncpy(tmp_pos, STRING_WITH_LEN(
"_bin"));
568 my_error(ER_UNKNOWN_COLLATION, MYF(0), tmp);
576 if (sql_field->
def &&
577 save_cs != sql_field->
def->collation.collation &&
578 (sql_field->
sql_type == DRIZZLE_TYPE_ENUM))
590 sql_field->
def= sql_field->
def->safe_charset_converter(save_cs);
592 if (sql_field->
def == NULL)
595 my_error(ER_INVALID_DEFAULT, MYF(0), sql_field->
field_name);
600 if (sql_field->
sql_type == DRIZZLE_TYPE_ENUM)
617 interval= sql_field->
interval= typelib(*session->
mem_root, sql_field->interval_list);
622 int comma_length= cs->cset->wc_mb(cs,
',', (
unsigned char*) comma_buf, (
unsigned char*) comma_buf +
sizeof(comma_buf));
623 assert(comma_length > 0);
625 for (uint32_t i= 0; (tmp= int_it++); i++)
628 if (String::needs_conversion(tmp->length(), tmp->charset(), cs))
630 conv.copy(tmp->ptr(), tmp->length(), cs);
631 interval->type_names[i]= session->mem.
strdup(conv);
632 interval->type_lengths[i]= conv.length();
636 lengthsp= cs->cset->lengthsp(cs, interval->type_names[i], interval->type_lengths[i]);
637 interval->type_lengths[i]= lengthsp;
638 ((
unsigned char *)interval->type_names[i])[lengthsp]=
'\0';
640 sql_field->interval_list.clear();
645 uint32_t field_length;
646 assert(sql_field->
sql_type == DRIZZLE_TYPE_ENUM);
647 if (sql_field->
def != NULL)
652 if (sql_field->flags & NOT_NULL_FLAG)
654 my_error(ER_INVALID_DEFAULT, MYF(0), sql_field->
field_name);
662 def->length(cs->cset->lengthsp(cs, def->ptr(), def->length()));
663 if (interval->find_type2(def->ptr(), def->length(), cs) == 0)
665 my_error(ER_INVALID_DEFAULT, MYF(0), sql_field->
field_name);
671 calculate_interval_lengths(cs, interval, &field_length, &new_dummy);
672 sql_field->
length= field_length;
674 set_if_smaller(sql_field->
length, (uint32_t)MAX_FIELD_WIDTH-1);
678 if (prepare_blob_field(session, sql_field))
681 if (!(sql_field->flags & NOT_NULL_FLAG))
686 my_error(ER_WRONG_COLUMN_NAME, MYF(0), sql_field->
field_name);
691 for (dup_no=0; (dup_field=it2++) != sql_field; dup_no++)
699 if (field_no < select_field_pos || dup_no >= select_field_pos)
701 my_error(ER_DUP_FIELDNAME, MYF(0), sql_field->
field_name);
707 sql_field->
def= dup_field->
def;
711 create_info->default_table_charset);
713 sql_field->pack_length= dup_field->pack_length;
714 sql_field->key_length= dup_field->key_length;
715 sql_field->decimals= dup_field->decimals;
723 if (!(sql_field->flags & NOT_NULL_FLAG))
725 sql_field->flags= dup_field->flags;
735 if (not create_proto.engine().name().compare(
"MyISAM") &&
736 ((sql_field->flags & BLOB_FLAG) ||
737 (sql_field->
sql_type == DRIZZLE_TYPE_VARCHAR)))
739 (*db_options)|= HA_OPTION_PACK_RECORD;
742 it2= alter_info->create_list.begin();
747 null_fields+= total_uneven_bit_length;
749 it= alter_info->create_list.begin();
750 while ((sql_field=it++))
752 assert(sql_field->
charset != 0);
754 if (prepare_create_field(sql_field, &blob_columns,
755 ×tamps, ×tamps_with_niladic))
757 sql_field->offset= record_offset;
758 if (MTYP_TYPENR(sql_field->
unireg_check) == Field::NEXT_NUMBER)
761 if (timestamps_with_niladic > 1)
763 my_message(ER_TOO_MUCH_AUTO_TIMESTAMP_COLS,
764 ER(ER_TOO_MUCH_AUTO_TIMESTAMP_COLS), MYF(0));
767 if (auto_increment > 1)
769 my_message(ER_WRONG_AUTO_KEY, ER(ER_WRONG_AUTO_KEY), MYF(0));
772 if (auto_increment &&
773 (engine->check_flag(HTON_BIT_NO_AUTO_INCREMENT)))
775 my_message(ER_TABLE_CANT_HANDLE_AUTO_INCREMENT,
776 ER(ER_TABLE_CANT_HANDLE_AUTO_INCREMENT), MYF(0));
780 if (blob_columns && (engine->check_flag(HTON_BIT_NO_BLOBS)))
782 my_message(ER_TABLE_CANT_HANDLE_BLOB, ER(ER_TABLE_CANT_HANDLE_BLOB),
791 uint32_t key_parts=0, fk_key_count=0;
792 bool primary_key=0,unique_key=0;
794 uint32_t tmp, key_number;
796 static char ignore_key[1];
801 while ((key=key_iterator++))
803 if (key->type == Key::FOREIGN_KEY)
806 if (((
Foreign_key *)key)->validate(alter_info->create_list))
811 add_foreign_key_to_table_message(&create_proto,
820 if (fk_key->ref_columns.size() &&
821 fk_key->ref_columns.size() != fk_key->columns.size())
823 my_error(ER_WRONG_FK_DEF, MYF(0),
824 (fk_key->name.data() ? fk_key->name.data() :
"foreign key without name"),
825 ER(ER_KEY_REF_DO_NOT_MATCH_TABLE_REF));
831 tmp= engine->max_key_parts();
832 if (key->columns.size() > tmp)
834 my_error(ER_TOO_MANY_KEY_PARTS,MYF(0),tmp);
837 if (check_identifier_name(key->name, ER_TOO_LONG_IDENT))
839 key_iterator2= alter_info->key_list.begin();
840 if (key->type != Key::FOREIGN_KEY)
842 while ((key2 = key_iterator2++) != key)
849 if ((key2->type != Key::FOREIGN_KEY &&
850 key2->name.data() != ignore_key &&
851 !foreign_key_prefix(key, key2)))
855 if (!key2->generated ||
856 (key->generated && key->columns.size() <
857 key2->columns.size()))
858 key->name.assign(ignore_key, 1);
861 key2->name.assign(ignore_key, 1);
862 key_parts-= key2->columns.size();
869 if (key->name.data() != ignore_key)
870 key_parts+=key->columns.size();
873 if (key->name.data() && !tmp_table && (key->type != Key::PRIMARY) && is_primary_key(key->name.data()))
875 my_error(ER_WRONG_NAME_FOR_INDEX, MYF(0), key->name.data());
879 tmp= engine->max_keys();
880 if (*key_count > tmp)
882 my_error(ER_TOO_MANY_KEYS,MYF(0),tmp);
886 (*key_info_buffer)= key_info= (
KeyInfo*) memory::sql_calloc(
sizeof(
KeyInfo) * (*key_count));
889 key_iterator= alter_info->key_list.begin();
891 for (; (key=key_iterator++) ; key_number++)
893 uint32_t key_length=0;
896 if (key->name.data() == ignore_key)
901 while (key && key->name.data() == ignore_key);
910 case Key::FOREIGN_KEY:
914 key_info->flags = HA_NOSAME;
918 key_info->flags|= HA_GENERATED_KEY;
920 key_info->key_parts=(uint8_t) key->columns.size();
921 key_info->key_part=key_part_info;
922 key_info->usable_key_parts= key_number;
923 key_info->algorithm= key->key_create_info.algorithm;
925 uint32_t tmp_len= system_charset_info->cset->charpos(system_charset_info,
926 key->key_create_info.comment.begin(),
927 key->key_create_info.comment.end(),
928 INDEX_COMMENT_MAXLEN);
930 if (tmp_len < key->key_create_info.comment.size())
932 my_error(ER_WRONG_STRING_LENGTH, MYF(0), key->key_create_info.comment.data(),
"INDEX COMMENT", (uint32_t) INDEX_COMMENT_MAXLEN);
936 key_info->comment.assign(key_info->comment.data(), key->key_create_info.comment.size());
937 if (key_info->comment.size() > 0)
939 key_info->flags|= HA_USES_COMMENT;
940 key_info->comment.assign(key->key_create_info.comment.data(), key_info->comment.size());
947 for (uint32_t column_nr=0 ; (column=cols++) ; column_nr++)
951 int proto_field_nr= 0;
953 it= alter_info->create_list.begin();
955 while ((sql_field=it++) && ++proto_field_nr &&
956 system_charset_info->strcasecmp(column->field_name.data(), sql_field->
field_name))
963 my_error(ER_KEY_COLUMN_DOES_NOT_EXITS, MYF(0), column->field_name.data());
967 while ((dup_column= cols2++) != column)
969 if (!system_charset_info->strcasecmp(column->field_name.data(), dup_column->field_name.data()))
971 my_printf_error(ER_DUP_FIELDNAME,
972 ER(ER_DUP_FIELDNAME),MYF(0),
973 column->field_name.data());
977 cols2= key->columns.begin();
979 if (create_proto.field_size() > 0)
980 protofield= create_proto.mutable_field(proto_field_nr - 1);
983 column->length*= sql_field->
charset->mbmaxlen;
985 if (sql_field->
sql_type == DRIZZLE_TYPE_BLOB)
987 if (! (engine->check_flag(HTON_BIT_CAN_INDEX_BLOBS)))
989 my_error(ER_BLOB_USED_AS_KEY, MYF(0), column->field_name.data());
992 if (! column->length)
994 my_error(ER_BLOB_KEY_WITHOUT_LENGTH, MYF(0), column->field_name.data());
999 if (! (sql_field->flags & NOT_NULL_FLAG))
1001 if (key->type == Key::PRIMARY)
1004 sql_field->flags|= NOT_NULL_FLAG;
1010 constraints= protofield->mutable_constraints();
1011 constraints->set_is_notnull(
true);
1017 key_info->flags|= HA_NULL_PART_KEY;
1018 if (! (engine->check_flag(HTON_BIT_NULL_IN_KEY)))
1020 my_error(ER_NULL_COLUMN_IN_INDEX, MYF(0), column->field_name.data());
1026 if (MTYP_TYPENR(sql_field->
unireg_check) == Field::NEXT_NUMBER)
1028 if (column_nr == 0 || (engine->check_flag(HTON_BIT_AUTO_PART_KEY)))
1033 key_part_info->fieldnr= field;
1034 key_part_info->offset= (uint16_t) sql_field->offset;
1035 key_part_info->key_type= 0;
1036 length= sql_field->key_length;
1040 if (sql_field->
sql_type == DRIZZLE_TYPE_BLOB)
1042 if ((length=column->length) > max_key_length ||
1043 length > engine->max_key_part_length())
1045 length= min(max_key_length, engine->max_key_part_length());
1046 if (key->type == Key::MULTIPLE)
1049 char warn_buff[DRIZZLE_ERRMSG_SIZE];
1050 snprintf(warn_buff,
sizeof(warn_buff), ER(ER_TOO_LONG_KEY),
1052 push_warning(session, DRIZZLE_ERROR::WARN_LEVEL_WARN,
1053 ER_TOO_LONG_KEY, warn_buff);
1055 length-= length % sql_field->
charset->mbmaxlen;
1059 my_error(ER_TOO_LONG_KEY,MYF(0),length);
1064 else if ((column->length > length ||
1065 ! Field::type_can_have_key_part(sql_field->
sql_type)))
1067 my_message(ER_WRONG_SUB_KEY, ER(ER_WRONG_SUB_KEY), MYF(0));
1070 else if (! (engine->check_flag(HTON_BIT_NO_PREFIX_CHAR_KEYS)))
1072 length=column->length;
1075 else if (length == 0)
1077 my_error(ER_WRONG_KEY_COLUMN, MYF(0), column->field_name.data());
1080 if (length > engine->max_key_part_length())
1082 length= engine->max_key_part_length();
1083 if (key->type == Key::MULTIPLE)
1086 char warn_buff[DRIZZLE_ERRMSG_SIZE];
1087 snprintf(warn_buff,
sizeof(warn_buff), ER(ER_TOO_LONG_KEY),
1089 push_warning(session, DRIZZLE_ERROR::WARN_LEVEL_WARN,
1090 ER_TOO_LONG_KEY, warn_buff);
1092 length-= length % sql_field->
charset->mbmaxlen;
1096 my_error(ER_TOO_LONG_KEY,MYF(0),length);
1100 key_part_info->length=(uint16_t) length;
1102 if (!((*db_options) & HA_OPTION_NO_PACK_KEYS) &&
1104 (sql_field->
sql_type == DRIZZLE_TYPE_VARCHAR ||
1105 sql_field->
sql_type == DRIZZLE_TYPE_BLOB)))
1107 if ((column_nr == 0 && sql_field->
sql_type == DRIZZLE_TYPE_BLOB) ||
1108 sql_field->
sql_type == DRIZZLE_TYPE_VARCHAR)
1110 key_info->flags|= HA_BINARY_PACK_KEY | HA_VAR_LENGTH_KEY;
1114 key_info->flags|= HA_PACK_KEY;
1118 if (length != sql_field->key_length)
1119 key_info->flags|= HA_KEY_HAS_PART_KEY_SEG;
1127 if (key->type == Key::PRIMARY)
1131 my_message(ER_MULTIPLE_PRI_KEY, ER(ER_MULTIPLE_PRI_KEY),
1135 static const char pkey_name[]=
"PRIMARY";
1139 else if (!(key_name= key->name.data()))
1140 key_name=make_unique_key_name(sql_field->
field_name,
1141 *key_info_buffer, key_info);
1142 if (check_if_keyname_exists(key_name, *key_info_buffer, key_info))
1144 my_error(ER_DUP_KEYNAME, MYF(0), key_name);
1147 key_info->name=(
char*) key_name;
1151 if (!key_info->name || check_column_name(key_info->name))
1153 my_error(ER_WRONG_NAME_FOR_INDEX, MYF(0), key_info->name);
1157 if (!(key_info->flags & HA_NULL_PART_KEY))
1162 key_info->key_length=(uint16_t) key_length;
1164 if (key_length > max_key_length)
1166 my_error(ER_TOO_LONG_KEY,MYF(0),max_key_length);
1173 if (!unique_key && !primary_key &&
1174 (engine->check_flag(HTON_BIT_REQUIRE_PRIMARY_KEY)))
1176 my_message(ER_REQUIRES_PRIMARY_KEY, ER(ER_REQUIRES_PRIMARY_KEY), MYF(0));
1180 if (auto_increment > 0)
1182 my_message(ER_WRONG_AUTO_KEY, ER(ER_WRONG_AUTO_KEY), MYF(0));
1186 internal::my_qsort((
unsigned char*) *key_info_buffer, *key_count,
sizeof(
KeyInfo),
1190 it= alter_info->create_list.begin();
1191 while ((sql_field=it++))
1193 Field::utype type= (Field::utype) MTYP_TYPENR(sql_field->
unireg_check);
1195 if (session->
variables.sql_mode & MODE_NO_ZERO_DATE &&
1197 (sql_field->
sql_type == DRIZZLE_TYPE_TIMESTAMP or sql_field->
sql_type == DRIZZLE_TYPE_MICROTIME) &&
1198 (sql_field->flags & NOT_NULL_FLAG) &&
1199 (type == Field::NONE || type == Field::TIMESTAMP_UN_FIELD))
1215 my_error(ER_INVALID_DEFAULT, MYF(0), sql_field->
field_name);
1236 static bool prepare_blob_field(Session *,
1237 CreateField *sql_field)
1240 if (sql_field->length > MAX_FIELD_VARCHARLENGTH &&
1241 !(sql_field->flags & BLOB_FLAG))
1243 my_error(ER_TOO_BIG_FIELDLENGTH, MYF(0), sql_field->field_name,
1244 MAX_FIELD_VARCHARLENGTH / sql_field->charset->mbmaxlen);
1248 if ((sql_field->flags & BLOB_FLAG) && sql_field->length)
1250 if (sql_field->sql_type == DRIZZLE_TYPE_BLOB)
1253 sql_field->pack_length= calc_pack_length(sql_field->sql_type, 0);
1255 sql_field->length= 0;
1260 static bool locked_create_event(Session *session,
1261 const identifier::Table &identifier,
1262 HA_CREATE_INFO *create_info,
1263 message::Table &table_proto,
1264 AlterInfo *alter_info,
1265 bool is_if_not_exists,
1266 bool internal_tmp_table,
1269 KeyInfo *key_info_buffer)
1281 plugin::StorageEngine::doesTableExist(*session, identifier,
1282 identifier.getType() != message::Table::STANDARD );
1286 if (is_if_not_exists)
1289 push_warning_printf(session, DRIZZLE_ERROR::WARN_LEVEL_NOTE,
1290 ER_TABLE_EXISTS_ERROR, ER(ER_TABLE_EXISTS_ERROR),
1291 identifier.getTableName().c_str());
1292 create_info->table_existed= 1;
1296 my_error(ER_TABLE_EXISTS_ERROR, identifier);
1301 if (identifier.getType() == message::Table::STANDARD)
1314 if (definition::Cache::find(identifier.getKey()))
1316 my_error(ER_TABLE_EXISTS_ERROR, identifier);
1323 session->set_proc_info(
"creating table");
1324 create_info->table_existed= 0;
1326 create_info->table_options= db_options;
1328 if (not rea_create_table(session, identifier,
1330 create_info, alter_info->create_list,
1331 key_count, key_info_buffer))
1336 if (identifier.getType() == message::Table::TEMPORARY)
1339 if (not (session->open_temporary_table(identifier)))
1341 (void) session->open_tables.rm_temporary_table(identifier);
1352 if (table_proto.type() == message::Table::STANDARD && not internal_tmp_table)
1354 TransactionServices::createTable(*session, table_proto);
1391 bool create_table_no_lock(Session *session,
1392 const identifier::Table &identifier,
1393 HA_CREATE_INFO *create_info,
1394 message::Table &table_proto,
1395 AlterInfo *alter_info,
1396 bool internal_tmp_table,
1397 uint32_t select_field_count,
1398 bool is_if_not_exists)
1400 uint db_options, key_count;
1401 KeyInfo *key_info_buffer;
1405 if (not alter_info->create_list.size())
1407 my_message(ER_TABLE_MUST_HAVE_COLUMNS, ER(ER_TABLE_MUST_HAVE_COLUMNS),
1411 assert(identifier.getTableName() == table_proto.name());
1412 db_options= create_info->table_options;
1414 set_table_default_charset(session->catalog().identifier(),create_info, identifier.getSchemaName().c_str());
1420 &key_info_buffer, &key_count,
1421 select_field_count))
1423 boost::mutex::scoped_lock lock(table::Cache::mutex());
1424 error= locked_create_event(session,
1431 db_options, key_count,
1435 session->set_proc_info(
"After create");
1448 bool internal_tmp_table,
1449 uint32_t select_field_count,
1450 bool is_if_not_exists)
1454 if (name_lock == NULL)
1456 if (is_if_not_exists)
1458 push_warning_printf(session, DRIZZLE_ERROR::WARN_LEVEL_NOTE,
1459 ER_TABLE_EXISTS_ERROR, ER(ER_TABLE_EXISTS_ERROR),
1460 identifier.getTableName().c_str());
1461 create_info->table_existed= 1;
1466 my_error(ER_TABLE_EXISTS_ERROR, identifier);
1472 result= create_table_no_lock(session,
1484 boost::mutex::scoped_lock lock(table::Cache::mutex());
1495 bool create_table(Session *session,
1496 const identifier::Table &identifier,
1497 HA_CREATE_INFO *create_info,
1498 message::Table &table_proto,
1499 AlterInfo *alter_info,
1500 bool internal_tmp_table,
1501 uint32_t select_field_count,
1502 bool is_if_not_exists)
1504 if (identifier.isTmp())
1506 return create_table_no_lock(session,
1532 check_if_keyname_exists(
const char *name, KeyInfo *start, KeyInfo *end)
1534 for (KeyInfo *key= start; key != end; key++)
1536 if (!system_charset_info->strcasecmp(name, key->name))
1544 make_unique_key_name(
const char *field_name,KeyInfo *start,KeyInfo *end)
1546 char buff[MAX_FIELD_NAME],*buff_end;
1548 if (not check_if_keyname_exists(field_name,start,end) && not is_primary_key(field_name))
1553 buff_end= strncpy(buff, field_name,
sizeof(buff)-4);
1554 buff_end+= strlen(buff);
1560 for (uint32_t i=2 ; i< 100; i++)
1563 internal::int10_to_str(i, buff_end+1, 10);
1564 if (!check_if_keyname_exists(buff,start,end))
1565 return memory::sql_strdup(buff);
1567 return (
char*)
"not_specified";
1593 rename_table(Session &session,
1594 plugin::StorageEngine *base,
1595 const identifier::Table &from,
1596 const identifier::Table &to)
1598 if (not plugin::StorageEngine::doesSchemaExist(to))
1600 my_error(ER_NO_DB_ERROR, MYF(0), to.getSchemaName().c_str());
1604 int error= base->renameTable(session, from, to);
1605 if (error == HA_ERR_WRONG_COMMAND)
1606 my_error(ER_NOT_SUPPORTED_YET, MYF(0),
"ALTER Table");
1609 my_error(ER_ERROR_ON_RENAME, MYF(0),
1610 from.isTmp() ?
"#sql-temporary" : from.getSQLPath().c_str(),
1611 to.isTmp() ?
"#sql-temporary" : to.getSQLPath().c_str(), error);
1636 void wait_while_table_is_used(Session *session, Table *table,
1637 enum ha_extra_function
function)
1640 safe_mutex_assert_owner(table::Cache::mutex().native_handle());
1642 table->cursor->extra(
function);
1644 session->abortLock(table);
1647 identifier::Table identifier(session->catalog().identifier(),table->getShare()->getSchemaName(), table->getShare()->getTableName());
1648 table::Cache::removeTable(*session, identifier, RTFC_WAIT_OTHER_THREAD_FLAG);
1668 void Session::close_cached_table(Table *table)
1671 wait_while_table_is_used(
this, table, HA_EXTRA_FORCE_REOPEN);
1673 if (open_tables.lock)
1675 unlockTables(open_tables.lock);
1676 open_tables.lock= NULL;
1679 unlink_open_table(table);
1691 static bool admin_table(Session* session, TableList* tables,
1692 const char *operator_name,
1693 thr_lock_type lock_type,
1694 bool open_for_modify,
1695 int (Cursor::*operator_func)(Session*))
1698 Select_Lex *select= &session->lex().select_lex;
1699 List<Item> field_list;
1702 const charset_info_st *
const cs= system_charset_info;
1704 if (! session->endActiveTransaction())
1707 field_list.push_back(item =
new Item_empty_string(
"Table", NAME_CHAR_LEN * 2, cs));
1708 item->maybe_null = 1;
1709 field_list.push_back(item =
new Item_empty_string(
"Op", 10, cs));
1710 item->maybe_null = 1;
1711 field_list.push_back(item =
new Item_empty_string(
"Msg_type", 10, cs));
1712 item->maybe_null = 1;
1713 field_list.push_back(item =
new Item_empty_string(
"Msg_text", 255, cs));
1714 item->maybe_null = 1;
1715 session->getClient()->sendFields(field_list);
1717 for (table= tables; table; table= table->next_local)
1719 identifier::Table table_identifier(session->catalog().identifier(), table->getSchemaName(), table->getTableName());
1722 std::string table_name = table_identifier.getSQLPath();
1724 table->lock_type= lock_type;
1727 TableList *save_next_global, *save_next_local;
1728 save_next_global= table->next_global;
1729 table->next_global= 0;
1730 save_next_local= table->next_local;
1731 table->next_local= 0;
1732 select->table_list.first= (
unsigned char*)table;
1738 session->lex().query_tables= table;
1739 session->lex().query_tables_last= &table->next_global;
1740 session->lex().query_tables_own_last= 0;
1741 session->no_warnings_for_error= 0;
1743 session->openTablesLock(table);
1744 session->no_warnings_for_error= 0;
1745 table->next_global= save_next_global;
1746 table->next_local= save_next_local;
1759 if (!session->main_da().m_warn_list.size())
1760 push_warning(session, DRIZZLE_ERROR::WARN_LEVEL_ERROR,
1761 ER_CHECK_NO_SUCH_TABLE, ER(ER_CHECK_NO_SUCH_TABLE));
1762 result_code= HA_ADMIN_CORRUPT;
1766 if ((table->table->db_stat & HA_READ_ONLY) && open_for_modify)
1768 char buff[FN_REFLEN + DRIZZLE_ERRMSG_SIZE];
1770 session->getClient()->store(table_name.c_str());
1771 session->getClient()->store(operator_name);
1772 session->getClient()->store(STRING_WITH_LEN(
"error"));
1773 length= snprintf(buff,
sizeof(buff), ER(ER_OPEN_AS_READONLY),
1774 table_name.c_str());
1775 session->getClient()->store(buff, length);
1776 TransactionServices::autocommitOrRollback(*session,
false);
1777 session->endTransaction(COMMIT);
1778 session->close_thread_tables();
1779 session->lex().reset_query_tables_list(
false);
1781 if (session->getClient()->flush())
1787 if (lock_type == TL_WRITE && table->table->getShare()->getVersion())
1789 table::Cache::mutex().lock();
1790 const char *old_message=session->enter_cond(COND_refresh, table::Cache::mutex(),
1791 "Waiting to get writelock");
1792 session->abortLock(table->table);
1793 identifier::Table identifier(session->catalog().identifier(),table->table->getShare()->getSchemaName(), table->table->getShare()->getTableName());
1794 table::Cache::removeTable(*session, identifier, RTFC_WAIT_OTHER_THREAD_FLAG | RTFC_CHECK_KILLED_FLAG);
1795 session->exit_cond(old_message);
1796 if (session->getKilled())
1801 result_code = (table->table->cursor->*operator_func)(session);
1805 session->lex().cleanup_after_one_table_open();
1806 session->clear_error();
1808 BOOST_FOREACH(DRIZZLE_ERROR* err, session->main_da().m_warn_list)
1810 session->getClient()->store(table_name.c_str());
1811 session->getClient()->store(operator_name);
1812 session->getClient()->store(warning_level_names[err->level].data(), warning_level_names[err->level].size());
1813 session->getClient()->store(err->msg);
1814 if (session->getClient()->flush())
1817 drizzle_reset_errors(*session,
true);
1819 session->getClient()->store(table_name.c_str());
1820 session->getClient()->store(operator_name);
1822 switch (result_code) {
1823 case HA_ADMIN_NOT_IMPLEMENTED:
1825 char buf[ERRMSGSIZE+20];
1826 uint32_t length=snprintf(buf, ERRMSGSIZE,
1827 ER(ER_CHECK_NOT_IMPLEMENTED), operator_name);
1828 session->getClient()->store(STRING_WITH_LEN(
"note"));
1829 session->getClient()->store(buf, length);
1834 session->getClient()->store(STRING_WITH_LEN(
"status"));
1835 session->getClient()->store(STRING_WITH_LEN(
"OK"));
1838 case HA_ADMIN_FAILED:
1839 session->getClient()->store(STRING_WITH_LEN(
"status"));
1840 session->getClient()->store(STRING_WITH_LEN(
"Operation failed"));
1843 case HA_ADMIN_REJECT:
1844 session->getClient()->store(STRING_WITH_LEN(
"status"));
1845 session->getClient()->store(STRING_WITH_LEN(
"Operation need committed state"));
1846 open_for_modify=
false;
1849 case HA_ADMIN_ALREADY_DONE:
1850 session->getClient()->store(STRING_WITH_LEN(
"status"));
1851 session->getClient()->store(STRING_WITH_LEN(
"Table is already up to date"));
1854 case HA_ADMIN_CORRUPT:
1855 session->getClient()->store(STRING_WITH_LEN(
"error"));
1856 session->getClient()->store(STRING_WITH_LEN(
"Corrupt"));
1860 case HA_ADMIN_INVALID:
1861 session->getClient()->store(STRING_WITH_LEN(
"error"));
1862 session->getClient()->store(STRING_WITH_LEN(
"Invalid argument"));
1867 char buf[ERRMSGSIZE+20];
1868 uint32_t length=snprintf(buf, ERRMSGSIZE,
1869 _(
"Unknown - internal error %d during operation"),
1871 session->getClient()->store(STRING_WITH_LEN(
"error"));
1872 session->getClient()->store(buf, length);
1881 table->table->getMutableShare()->resetVersion();
1883 else if (open_for_modify)
1885 if (table->table->getShare()->getType())
1887 table->table->cursor->info(HA_STATUS_CONST);
1891 boost::unique_lock<boost::mutex> lock(table::Cache::mutex());
1892 identifier::Table identifier(session->catalog().identifier(),
1893 table->table->getShare()->getSchemaName(),
1894 table->table->getShare()->getTableName());
1895 table::Cache::removeTable(*session, identifier, RTFC_NO_FLAG);
1899 TransactionServices::autocommitOrRollback(*session,
false);
1900 session->endTransaction(COMMIT);
1901 session->close_thread_tables();
1903 if (session->getClient()->flush())
1911 TransactionServices::autocommitOrRollback(*session,
true);
1912 session->endTransaction(ROLLBACK);
1913 session->close_thread_tables();
1934 static bool create_table_wrapper(Session &session,
1935 const message::Table& create_table_proto,
1936 const identifier::Table& destination_identifier,
1937 const identifier::Table& source_identifier,
1943 message::Table new_table_message;
1945 message::table::shared_ptr source_table_message= plugin::StorageEngine::getTableMessage(session, source_identifier);
1947 if (not source_table_message)
1949 my_error(ER_TABLE_UNKNOWN, source_identifier);
1953 new_table_message.CopyFrom(*source_table_message);
1954 new_table_message.set_type(destination_identifier.isTmp() ? message::Table::TEMPORARY : message::Table::STANDARD);
1958 new_table_message.mutable_engine()->set_name(create_table_proto.engine().name());
1962 new_table_message.set_name(create_table_proto.name());
1963 new_table_message.set_schema(create_table_proto.schema());
1964 new_table_message.set_catalog(create_table_proto.catalog());
1968 for (int32_t j= 0; j < new_table_message.fk_constraint_size(); j++)
1970 if (new_table_message.fk_constraint(j).has_name())
1972 std::string name(new_table_message.name());
1975 name.append(
"_ibfk_");
1976 snprintf(number,
sizeof(number),
"%d", j+1);
1977 name.append(number);
1979 message::Table::ForeignKeyConstraint *pfkey= new_table_message.mutable_fk_constraint(j);
1980 pfkey->set_name(name);
1988 bool success= plugin::StorageEngine::createTable(session, destination_identifier, new_table_message);
1990 if (success && not destination_identifier.isTmp())
1992 TransactionServices::createTable(session, new_table_message);
2013 bool create_like_table(Session* session,
2014 const identifier::Table& destination_identifier,
2015 const identifier::Table& source_identifier,
2016 message::Table &create_table_proto,
2017 bool is_if_not_exists,
2021 bool table_exists=
false;
2029 if (destination_identifier.isTmp())
2031 if (session->open_tables.find_temporary_table(destination_identifier))
2037 bool was_created= create_table_wrapper(*session,
2039 destination_identifier,
2042 if (not was_created)
2044 (void) session->open_tables.rm_temporary_table(destination_identifier,
true);
2046 else if (not session->open_temporary_table(destination_identifier))
2049 (void) session->open_tables.rm_temporary_table(destination_identifier,
true);
2059 Table *name_lock= session->lock_table_name_if_not_cached(destination_identifier);
2064 else if (plugin::StorageEngine::doesTableExist(*session, destination_identifier))
2072 boost::mutex::scoped_lock lock(table::Cache::mutex());
2073 was_created= create_table_wrapper(*session, create_table_proto, destination_identifier,
2074 source_identifier, is_engine_set);
2079 if (not was_created)
2081 plugin::StorageEngine::dropTable(*session, destination_identifier);
2091 boost::mutex::scoped_lock lock(table::Cache::mutex());
2092 session->unlink_open_table(name_lock);
2098 if (is_if_not_exists)
2100 char warn_buff[DRIZZLE_ERRMSG_SIZE];
2101 snprintf(warn_buff,
sizeof(warn_buff),
2102 ER(ER_TABLE_EXISTS_ERROR), destination_identifier.getTableName().c_str());
2103 push_warning(session, DRIZZLE_ERROR::WARN_LEVEL_NOTE,
2104 ER_TABLE_EXISTS_ERROR, warn_buff);
2108 my_error(ER_TABLE_EXISTS_ERROR, destination_identifier);
2117 bool analyze_table(Session* session, TableList* tables)
2119 return admin_table(session, tables,
"analyze", TL_READ_NO_INSERT,
true, &Cursor::ha_analyze);
2123 bool check_table(Session* session, TableList* tables)
2125 return admin_table(session, tables,
"check", TL_READ_NO_INSERT,
false, &Cursor::ha_check);
static bool drizzle_create_table(Session *session, const identifier::Table &identifier, HA_CREATE_INFO *create_info, message::Table &table_proto, AlterInfo *alter_info, bool internal_tmp_table, uint32_t select_field_count, bool is_if_not_exists)
void broadcast_refresh(void)
static int prepare_create_table(Session *session, HA_CREATE_INFO *create_info, message::Table &create_proto, AlterInfo *alter_info, bool tmp_table, uint32_t *db_options, KeyInfo **key_info_buffer, uint32_t *key_count, int select_field_count)
TODO: Rename this file - func.h is stupid.
void unlink_open_table(Table *find)
void create_length_to_internal_length(void)
int(* qsort_cmp)(const void *, const void *)
virtual String * val_str(String *str)=0
Field::utype unireg_check
Table * lock_table_name_if_not_cached(const identifier::Table &)
enum_field_types sql_type
#define KEY_DEFAULT_PACK_LENGTH
drizzle_system_variables & variables
char * strdup(const char *)
Duplicate a null-terminated string into memory allocated from within the specified Root...
const charset_info_st * charset