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(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(
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(table->getSchemaName(), table->getTableName());
130 error= session->open_tables.drop_temporary_table(tmp_identifier);
144 if (drop_temporary ==
false)
146 abort_locked_tables(session, tmp_identifier);
147 table::Cache::removeTable(*session, tmp_identifier, RTFC_WAIT_OTHER_THREAD_FLAG | RTFC_CHECK_KILLED_FLAG);
152 Table *locked_table= drop_locked_tables(session, tmp_identifier);
154 table->table= locked_table;
156 if (session->getKilled())
162 identifier::Table identifier(table->getSchemaName(), table->getTableName(), table->getInternalTmpTable() ? message::Table::INTERNAL : message::Table::STANDARD);
164 message::table::shared_ptr message= plugin::StorageEngine::getTableMessage(*session, identifier,
true);
166 if (drop_temporary || not plugin::StorageEngine::doesTableExist(*session, identifier))
171 push_warning_printf(session, DRIZZLE_ERROR::WARN_LEVEL_NOTE,
172 ER_BAD_TABLE_ERROR, ER(ER_BAD_TABLE_ERROR),
173 table->getTableName());
182 drizzled::error_t local_error;
185 if (plugin::StorageEngine::dropTable(*session, identifier, local_error))
189 TransactionServices::dropTable(*session, identifier, *message, if_exists);
194 if (local_error == HA_ERR_NO_SUCH_TABLE and if_exists)
197 session->clear_error();
200 if (local_error == HA_ERR_ROW_IS_REFERENCED)
203 foreign_key_error=
true;
211 wrong_tables.push_back(table->getTableName());
215 tables->unlock_table_names();
219 if (wrong_tables.size())
221 if (not foreign_key_error)
223 std::string table_error;
225 BOOST_FOREACH(util::string::vector::reference iter, wrong_tables)
230 table_error.resize(table_error.size() -1);
232 my_printf_error(ER_BAD_TABLE_ERROR, ER(ER_BAD_TABLE_ERROR), MYF(0),
233 table_error.c_str());
237 my_message(ER_ROW_IS_REFERENCED, ER(ER_ROW_IS_REFERENCED), MYF(0));
242 session->no_warnings_for_error= 0;
260 static int sort_keys(KeyInfo *a, KeyInfo *b)
262 ulong a_flags= a->flags, b_flags= b->flags;
264 if (a_flags & HA_NOSAME)
266 if (!(b_flags & HA_NOSAME))
268 if ((a_flags ^ b_flags) & (HA_NULL_PART_KEY))
271 return (a_flags & (HA_NULL_PART_KEY)) ? 1 : -1;
273 if (is_primary_key(a->name))
275 if (is_primary_key(b->name))
278 if ((a_flags ^ b_flags) & HA_KEY_HAS_PART_KEY_SEG)
279 return (a_flags & HA_KEY_HAS_PART_KEY_SEG) ? 1 : -1;
281 else if (b_flags & HA_NOSAME)
288 return ((a->usable_key_parts < b->usable_key_parts) ? -1 :
289 (a->usable_key_parts > b->usable_key_parts) ? 1 :
327 return (my_strnncoll(a.cs,
328 (
const unsigned char*)a.s.c_str(), a.s.length(),
329 (
const unsigned char*)b.s.c_str(), b.s.length())==0);
335 class typelib_set_member_hasher
337 boost::hash<string> hasher;
339 std::size_t operator()(
const typelib_set_member& t)
const
346 static bool check_duplicates_in_interval(
const char *set_or_name,
347 const char *name, TYPELIB *typelib,
348 const charset_info_st *
const cs,
349 unsigned int *dup_val_count)
351 TYPELIB tmp= *typelib;
352 const char **cur_value= typelib->type_names;
353 unsigned int *cur_length= typelib->type_lengths;
356 boost::unordered_set<typelib_set_member, typelib_set_member_hasher> interval_set;
358 for ( ; tmp.count > 0; cur_value++, cur_length++)
363 if (interval_set.count(typelib_set_member(*cur_value, *cur_length, cs)))
365 my_error(ER_DUPLICATED_VALUE_IN_TYPE, MYF(0),
366 name,*cur_value,set_or_name);
370 interval_set.insert(typelib_set_member(*cur_value, *cur_length, cs));
394 static void calculate_interval_lengths(
const charset_info_st *
const cs,
396 uint32_t *max_length,
397 uint32_t *tot_length)
401 *max_length= *tot_length= 0;
402 for (pos= interval->type_names, len= interval->type_lengths;
405 uint32_t length= cs->cset->numchars(cs, *pos, *pos + *len);
406 *tot_length+= length;
407 set_if_bigger(*max_length, (uint32_t)length);
428 int prepare_create_field(CreateField *sql_field,
429 uint32_t *blob_columns,
431 int *timestamps_with_niladic)
433 unsigned int dup_val_count;
439 assert(sql_field->charset);
441 switch (sql_field->sql_type) {
442 case DRIZZLE_TYPE_BLOB:
443 sql_field->length= 8;
447 case DRIZZLE_TYPE_ENUM:
449 if (check_duplicates_in_interval(
"ENUM",
450 sql_field->field_name,
460 case DRIZZLE_TYPE_MICROTIME:
461 case DRIZZLE_TYPE_TIMESTAMP:
463 if (sql_field->unireg_check == Field::TIMESTAMP_OLD_FIELD)
467 sql_field->unireg_check= Field::TIMESTAMP_DNUN_FIELD;
468 (*timestamps_with_niladic)++;
472 sql_field->unireg_check= Field::NONE;
475 else if (sql_field->unireg_check != Field::NONE)
477 (*timestamps_with_niladic)++;
484 case DRIZZLE_TYPE_BOOLEAN:
485 case DRIZZLE_TYPE_DATE:
486 case DRIZZLE_TYPE_DATETIME:
487 case DRIZZLE_TYPE_DECIMAL:
488 case DRIZZLE_TYPE_DOUBLE:
489 case DRIZZLE_TYPE_LONG:
490 case DRIZZLE_TYPE_LONGLONG:
491 case DRIZZLE_TYPE_NULL:
492 case DRIZZLE_TYPE_TIME:
493 case DRIZZLE_TYPE_UUID:
494 case DRIZZLE_TYPE_IPV6:
495 case DRIZZLE_TYPE_VARCHAR:
507 uint32_t *db_options,
510 int select_field_count)
512 const char *key_name;
514 uint field,null_fields,blob_columns,max_key_length;
515 ulong record_offset= 0;
518 int timestamps= 0, timestamps_with_niladic= 0;
520 int select_field_pos,auto_increment=0;
523 uint32_t total_uneven_bit_length= 0;
527 select_field_pos= alter_info->create_list.size() - select_field_count;
528 null_fields=blob_columns=0;
529 max_key_length= engine->max_key_length();
531 for (int32_t field_no=0; (sql_field=it++) ; field_no++)
543 sql_field->
charset= create_info->default_table_charset;
551 if (create_info->table_charset && sql_field->
charset != &my_charset_bin)
552 sql_field->
charset= create_info->table_charset;
555 if ((sql_field->flags & BINCMP_FLAG) &&
556 !(sql_field->
charset= get_charset_by_csname(sql_field->
charset->csname, MY_CS_BINSORT)))
560 strncpy(tmp_pos, save_cs->csname,
sizeof(tmp)-4);
561 tmp_pos+= strlen(tmp);
562 strncpy(tmp_pos, STRING_WITH_LEN(
"_bin"));
563 my_error(ER_UNKNOWN_COLLATION, MYF(0), tmp);
571 if (sql_field->
def &&
572 save_cs != sql_field->
def->collation.collation &&
573 (sql_field->
sql_type == DRIZZLE_TYPE_ENUM))
585 sql_field->
def= sql_field->
def->safe_charset_converter(save_cs);
587 if (sql_field->
def == NULL)
590 my_error(ER_INVALID_DEFAULT, MYF(0), sql_field->
field_name);
595 if (sql_field->
sql_type == DRIZZLE_TYPE_ENUM)
612 interval= sql_field->
interval= typelib(*session->
mem_root, sql_field->interval_list);
617 int comma_length= cs->cset->wc_mb(cs,
',', (
unsigned char*) comma_buf, (
unsigned char*) comma_buf +
sizeof(comma_buf));
618 assert(comma_length > 0);
620 for (uint32_t i= 0; (tmp= int_it++); i++)
623 if (String::needs_conversion(tmp->length(), tmp->charset(), cs))
625 conv.copy(tmp->ptr(), tmp->length(), cs);
626 interval->type_names[i]= session->mem.
strdup(conv);
627 interval->type_lengths[i]= conv.length();
631 lengthsp= cs->cset->lengthsp(cs, interval->type_names[i], interval->type_lengths[i]);
632 interval->type_lengths[i]= lengthsp;
633 ((
unsigned char *)interval->type_names[i])[lengthsp]=
'\0';
635 sql_field->interval_list.clear();
640 uint32_t field_length;
641 assert(sql_field->
sql_type == DRIZZLE_TYPE_ENUM);
642 if (sql_field->
def != NULL)
647 if (sql_field->flags & NOT_NULL_FLAG)
649 my_error(ER_INVALID_DEFAULT, MYF(0), sql_field->
field_name);
657 def->length(cs->cset->lengthsp(cs, def->ptr(), def->length()));
658 if (interval->find_type2(def->ptr(), def->length(), cs) == 0)
660 my_error(ER_INVALID_DEFAULT, MYF(0), sql_field->
field_name);
666 calculate_interval_lengths(cs, interval, &field_length, &new_dummy);
667 sql_field->
length= field_length;
669 set_if_smaller(sql_field->
length, (uint32_t)MAX_FIELD_WIDTH-1);
673 if (prepare_blob_field(session, sql_field))
676 if (!(sql_field->flags & NOT_NULL_FLAG))
681 my_error(ER_WRONG_COLUMN_NAME, MYF(0), sql_field->
field_name);
686 for (dup_no=0; (dup_field=it2++) != sql_field; dup_no++)
694 if (field_no < select_field_pos || dup_no >= select_field_pos)
696 my_error(ER_DUP_FIELDNAME, MYF(0), sql_field->
field_name);
702 sql_field->
def= dup_field->
def;
706 create_info->default_table_charset);
708 sql_field->pack_length= dup_field->pack_length;
709 sql_field->key_length= dup_field->key_length;
710 sql_field->decimals= dup_field->decimals;
718 if (!(sql_field->flags & NOT_NULL_FLAG))
720 sql_field->flags= dup_field->flags;
730 if (not create_proto.engine().name().compare(
"MyISAM") &&
731 ((sql_field->flags & BLOB_FLAG) ||
732 (sql_field->
sql_type == DRIZZLE_TYPE_VARCHAR)))
734 (*db_options)|= HA_OPTION_PACK_RECORD;
737 it2= alter_info->create_list.begin();
742 null_fields+= total_uneven_bit_length;
744 it= alter_info->create_list.begin();
745 while ((sql_field=it++))
747 assert(sql_field->
charset != 0);
749 if (prepare_create_field(sql_field, &blob_columns,
750 ×tamps, ×tamps_with_niladic))
752 sql_field->offset= record_offset;
753 if (MTYP_TYPENR(sql_field->
unireg_check) == Field::NEXT_NUMBER)
756 if (timestamps_with_niladic > 1)
758 my_message(ER_TOO_MUCH_AUTO_TIMESTAMP_COLS,
759 ER(ER_TOO_MUCH_AUTO_TIMESTAMP_COLS), MYF(0));
762 if (auto_increment > 1)
764 my_message(ER_WRONG_AUTO_KEY, ER(ER_WRONG_AUTO_KEY), MYF(0));
767 if (auto_increment &&
768 (engine->check_flag(HTON_BIT_NO_AUTO_INCREMENT)))
770 my_message(ER_TABLE_CANT_HANDLE_AUTO_INCREMENT,
771 ER(ER_TABLE_CANT_HANDLE_AUTO_INCREMENT), MYF(0));
775 if (blob_columns && (engine->check_flag(HTON_BIT_NO_BLOBS)))
777 my_message(ER_TABLE_CANT_HANDLE_BLOB, ER(ER_TABLE_CANT_HANDLE_BLOB),
786 uint32_t key_parts=0, fk_key_count=0;
787 bool primary_key=0,unique_key=0;
789 uint32_t tmp, key_number;
791 static char ignore_key[1];
796 while ((key=key_iterator++))
798 if (key->type == Key::FOREIGN_KEY)
801 if (((
Foreign_key *)key)->validate(alter_info->create_list))
806 add_foreign_key_to_table_message(&create_proto,
815 if (fk_key->ref_columns.size() &&
816 fk_key->ref_columns.size() != fk_key->columns.size())
818 my_error(ER_WRONG_FK_DEF, MYF(0),
819 (fk_key->name.data() ? fk_key->name.data() :
"foreign key without name"),
820 ER(ER_KEY_REF_DO_NOT_MATCH_TABLE_REF));
826 tmp= engine->max_key_parts();
827 if (key->columns.size() > tmp)
829 my_error(ER_TOO_MANY_KEY_PARTS,MYF(0),tmp);
832 if (check_identifier_name(key->name, ER_TOO_LONG_IDENT))
834 key_iterator2= alter_info->key_list.begin();
835 if (key->type != Key::FOREIGN_KEY)
837 while ((key2 = key_iterator2++) != key)
844 if ((key2->type != Key::FOREIGN_KEY &&
845 key2->name.data() != ignore_key &&
846 !foreign_key_prefix(key, key2)))
850 if (!key2->generated ||
851 (key->generated && key->columns.size() <
852 key2->columns.size()))
853 key->name.assign(ignore_key, 1);
856 key2->name.assign(ignore_key, 1);
857 key_parts-= key2->columns.size();
864 if (key->name.data() != ignore_key)
865 key_parts+=key->columns.size();
868 if (key->name.data() && !tmp_table && (key->type != Key::PRIMARY) && is_primary_key(key->name.data()))
870 my_error(ER_WRONG_NAME_FOR_INDEX, MYF(0), key->name.data());
874 tmp= engine->max_keys();
875 if (*key_count > tmp)
877 my_error(ER_TOO_MANY_KEYS,MYF(0),tmp);
881 (*key_info_buffer)= key_info= (
KeyInfo*) memory::sql_calloc(
sizeof(
KeyInfo) * (*key_count));
884 key_iterator= alter_info->key_list.begin();
886 for (; (key=key_iterator++) ; key_number++)
888 uint32_t key_length=0;
891 if (key->name.data() == ignore_key)
896 while (key && key->name.data() == ignore_key);
905 case Key::FOREIGN_KEY:
909 key_info->flags = HA_NOSAME;
913 key_info->flags|= HA_GENERATED_KEY;
915 key_info->key_parts=(uint8_t) key->columns.size();
916 key_info->key_part=key_part_info;
917 key_info->usable_key_parts= key_number;
918 key_info->algorithm= key->key_create_info.algorithm;
920 uint32_t tmp_len= system_charset_info->cset->charpos(system_charset_info,
921 key->key_create_info.comment.begin(),
922 key->key_create_info.comment.end(),
923 INDEX_COMMENT_MAXLEN);
925 if (tmp_len < key->key_create_info.comment.size())
927 my_error(ER_WRONG_STRING_LENGTH, MYF(0), key->key_create_info.comment.data(),
"INDEX COMMENT", (uint32_t) INDEX_COMMENT_MAXLEN);
931 key_info->comment.assign(key_info->comment.data(), key->key_create_info.comment.size());
932 if (key_info->comment.size() > 0)
934 key_info->flags|= HA_USES_COMMENT;
935 key_info->comment.assign(key->key_create_info.comment.data(), key_info->comment.size());
942 for (uint32_t column_nr=0 ; (column=cols++) ; column_nr++)
946 int proto_field_nr= 0;
948 it= alter_info->create_list.begin();
950 while ((sql_field=it++) && ++proto_field_nr &&
951 system_charset_info->strcasecmp(column->field_name.data(), sql_field->
field_name))
958 my_error(ER_KEY_COLUMN_DOES_NOT_EXITS, MYF(0), column->field_name.data());
962 while ((dup_column= cols2++) != column)
964 if (!system_charset_info->strcasecmp(column->field_name.data(), dup_column->field_name.data()))
966 my_printf_error(ER_DUP_FIELDNAME,
967 ER(ER_DUP_FIELDNAME),MYF(0),
968 column->field_name.data());
972 cols2= key->columns.begin();
974 if (create_proto.field_size() > 0)
975 protofield= create_proto.mutable_field(proto_field_nr - 1);
978 column->length*= sql_field->
charset->mbmaxlen;
980 if (sql_field->
sql_type == DRIZZLE_TYPE_BLOB)
982 if (! (engine->check_flag(HTON_BIT_CAN_INDEX_BLOBS)))
984 my_error(ER_BLOB_USED_AS_KEY, MYF(0), column->field_name.data());
987 if (! column->length)
989 my_error(ER_BLOB_KEY_WITHOUT_LENGTH, MYF(0), column->field_name.data());
994 if (! (sql_field->flags & NOT_NULL_FLAG))
996 if (key->type == Key::PRIMARY)
999 sql_field->flags|= NOT_NULL_FLAG;
1005 constraints= protofield->mutable_constraints();
1006 constraints->set_is_notnull(
true);
1012 key_info->flags|= HA_NULL_PART_KEY;
1013 if (! (engine->check_flag(HTON_BIT_NULL_IN_KEY)))
1015 my_error(ER_NULL_COLUMN_IN_INDEX, MYF(0), column->field_name.data());
1021 if (MTYP_TYPENR(sql_field->
unireg_check) == Field::NEXT_NUMBER)
1023 if (column_nr == 0 || (engine->check_flag(HTON_BIT_AUTO_PART_KEY)))
1028 key_part_info->fieldnr= field;
1029 key_part_info->offset= (uint16_t) sql_field->offset;
1030 key_part_info->key_type= 0;
1031 length= sql_field->key_length;
1035 if (sql_field->
sql_type == DRIZZLE_TYPE_BLOB)
1037 if ((length=column->length) > max_key_length ||
1038 length > engine->max_key_part_length())
1040 length= min(max_key_length, engine->max_key_part_length());
1041 if (key->type == Key::MULTIPLE)
1044 char warn_buff[DRIZZLE_ERRMSG_SIZE];
1045 snprintf(warn_buff,
sizeof(warn_buff), ER(ER_TOO_LONG_KEY),
1047 push_warning(session, DRIZZLE_ERROR::WARN_LEVEL_WARN,
1048 ER_TOO_LONG_KEY, warn_buff);
1050 length-= length % sql_field->
charset->mbmaxlen;
1054 my_error(ER_TOO_LONG_KEY,MYF(0),length);
1059 else if ((column->length > length ||
1060 ! Field::type_can_have_key_part(sql_field->
sql_type)))
1062 my_message(ER_WRONG_SUB_KEY, ER(ER_WRONG_SUB_KEY), MYF(0));
1065 else if (! (engine->check_flag(HTON_BIT_NO_PREFIX_CHAR_KEYS)))
1067 length=column->length;
1070 else if (length == 0)
1072 my_error(ER_WRONG_KEY_COLUMN, MYF(0), column->field_name.data());
1075 if (length > engine->max_key_part_length())
1077 length= engine->max_key_part_length();
1078 if (key->type == Key::MULTIPLE)
1081 char warn_buff[DRIZZLE_ERRMSG_SIZE];
1082 snprintf(warn_buff,
sizeof(warn_buff), ER(ER_TOO_LONG_KEY),
1084 push_warning(session, DRIZZLE_ERROR::WARN_LEVEL_WARN,
1085 ER_TOO_LONG_KEY, warn_buff);
1087 length-= length % sql_field->
charset->mbmaxlen;
1091 my_error(ER_TOO_LONG_KEY,MYF(0),length);
1095 key_part_info->length=(uint16_t) length;
1097 if (!((*db_options) & HA_OPTION_NO_PACK_KEYS) &&
1099 (sql_field->
sql_type == DRIZZLE_TYPE_VARCHAR ||
1100 sql_field->
sql_type == DRIZZLE_TYPE_BLOB)))
1102 if ((column_nr == 0 && sql_field->
sql_type == DRIZZLE_TYPE_BLOB) ||
1103 sql_field->
sql_type == DRIZZLE_TYPE_VARCHAR)
1105 key_info->flags|= HA_BINARY_PACK_KEY | HA_VAR_LENGTH_KEY;
1109 key_info->flags|= HA_PACK_KEY;
1113 if (length != sql_field->key_length)
1114 key_info->flags|= HA_KEY_HAS_PART_KEY_SEG;
1122 if (key->type == Key::PRIMARY)
1126 my_message(ER_MULTIPLE_PRI_KEY, ER(ER_MULTIPLE_PRI_KEY),
1130 static const char pkey_name[]=
"PRIMARY";
1134 else if (!(key_name= key->name.data()))
1135 key_name=make_unique_key_name(sql_field->
field_name,
1136 *key_info_buffer, key_info);
1137 if (check_if_keyname_exists(key_name, *key_info_buffer, key_info))
1139 my_error(ER_DUP_KEYNAME, MYF(0), key_name);
1142 key_info->name=(
char*) key_name;
1146 if (!key_info->name || check_column_name(key_info->name))
1148 my_error(ER_WRONG_NAME_FOR_INDEX, MYF(0), key_info->name);
1152 if (!(key_info->flags & HA_NULL_PART_KEY))
1157 key_info->key_length=(uint16_t) key_length;
1159 if (key_length > max_key_length)
1161 my_error(ER_TOO_LONG_KEY,MYF(0),max_key_length);
1168 if (!unique_key && !primary_key &&
1169 (engine->check_flag(HTON_BIT_REQUIRE_PRIMARY_KEY)))
1171 my_message(ER_REQUIRES_PRIMARY_KEY, ER(ER_REQUIRES_PRIMARY_KEY), MYF(0));
1175 if (auto_increment > 0)
1177 my_message(ER_WRONG_AUTO_KEY, ER(ER_WRONG_AUTO_KEY), MYF(0));
1181 internal::my_qsort((
unsigned char*) *key_info_buffer, *key_count,
sizeof(
KeyInfo),
1185 it= alter_info->create_list.begin();
1186 while ((sql_field=it++))
1188 Field::utype type= (Field::utype) MTYP_TYPENR(sql_field->
unireg_check);
1190 if (session->
variables.sql_mode & MODE_NO_ZERO_DATE &&
1192 (sql_field->
sql_type == DRIZZLE_TYPE_TIMESTAMP or sql_field->
sql_type == DRIZZLE_TYPE_MICROTIME) &&
1193 (sql_field->flags & NOT_NULL_FLAG) &&
1194 (type == Field::NONE || type == Field::TIMESTAMP_UN_FIELD))
1210 my_error(ER_INVALID_DEFAULT, MYF(0), sql_field->
field_name);
1231 static bool prepare_blob_field(Session *,
1232 CreateField *sql_field)
1235 if (sql_field->length > MAX_FIELD_VARCHARLENGTH &&
1236 !(sql_field->flags & BLOB_FLAG))
1238 my_error(ER_TOO_BIG_FIELDLENGTH, MYF(0), sql_field->field_name,
1239 MAX_FIELD_VARCHARLENGTH / sql_field->charset->mbmaxlen);
1243 if ((sql_field->flags & BLOB_FLAG) && sql_field->length)
1245 if (sql_field->sql_type == DRIZZLE_TYPE_BLOB)
1248 sql_field->pack_length= calc_pack_length(sql_field->sql_type, 0);
1250 sql_field->length= 0;
1255 static bool locked_create_event(Session *session,
1256 const identifier::Table &identifier,
1257 HA_CREATE_INFO *create_info,
1258 message::Table &table_proto,
1259 AlterInfo *alter_info,
1260 bool is_if_not_exists,
1261 bool internal_tmp_table,
1264 KeyInfo *key_info_buffer)
1276 plugin::StorageEngine::doesTableExist(*session, identifier,
1277 identifier.getType() != message::Table::STANDARD );
1281 if (is_if_not_exists)
1284 push_warning_printf(session, DRIZZLE_ERROR::WARN_LEVEL_NOTE,
1285 ER_TABLE_EXISTS_ERROR, ER(ER_TABLE_EXISTS_ERROR),
1286 identifier.getTableName().c_str());
1287 create_info->table_existed= 1;
1291 my_error(ER_TABLE_EXISTS_ERROR, identifier);
1296 if (identifier.getType() == message::Table::STANDARD)
1309 if (definition::Cache::find(identifier.getKey()))
1311 my_error(ER_TABLE_EXISTS_ERROR, identifier);
1318 session->set_proc_info(
"creating table");
1319 create_info->table_existed= 0;
1321 create_info->table_options= db_options;
1323 if (not rea_create_table(session, identifier,
1325 create_info, alter_info->create_list,
1326 key_count, key_info_buffer))
1331 if (identifier.getType() == message::Table::TEMPORARY)
1334 if (not (session->open_temporary_table(identifier)))
1336 (void) session->open_tables.rm_temporary_table(identifier);
1347 if (table_proto.type() == message::Table::STANDARD && not internal_tmp_table)
1349 TransactionServices::createTable(*session, table_proto);
1386 bool create_table_no_lock(Session *session,
1387 const identifier::Table &identifier,
1388 HA_CREATE_INFO *create_info,
1389 message::Table &table_proto,
1390 AlterInfo *alter_info,
1391 bool internal_tmp_table,
1392 uint32_t select_field_count,
1393 bool is_if_not_exists)
1395 uint db_options, key_count;
1396 KeyInfo *key_info_buffer;
1400 if (not alter_info->create_list.size())
1402 my_message(ER_TABLE_MUST_HAVE_COLUMNS, ER(ER_TABLE_MUST_HAVE_COLUMNS),
1406 assert(identifier.getTableName() == table_proto.name());
1407 db_options= create_info->table_options;
1409 set_table_default_charset(create_info, identifier.getSchemaName().c_str());
1415 &key_info_buffer, &key_count,
1416 select_field_count))
1418 boost::mutex::scoped_lock lock(table::Cache::mutex());
1419 error= locked_create_event(session,
1426 db_options, key_count,
1430 session->set_proc_info(
"After create");
1443 bool internal_tmp_table,
1444 uint32_t select_field_count,
1445 bool is_if_not_exists)
1449 if (name_lock == NULL)
1451 if (is_if_not_exists)
1453 push_warning_printf(session, DRIZZLE_ERROR::WARN_LEVEL_NOTE,
1454 ER_TABLE_EXISTS_ERROR, ER(ER_TABLE_EXISTS_ERROR),
1455 identifier.getTableName().c_str());
1456 create_info->table_existed= 1;
1461 my_error(ER_TABLE_EXISTS_ERROR, identifier);
1467 result= create_table_no_lock(session,
1479 boost::mutex::scoped_lock lock(table::Cache::mutex());
1490 bool create_table(Session *session,
1491 const identifier::Table &identifier,
1492 HA_CREATE_INFO *create_info,
1493 message::Table &table_proto,
1494 AlterInfo *alter_info,
1495 bool internal_tmp_table,
1496 uint32_t select_field_count,
1497 bool is_if_not_exists)
1499 if (identifier.isTmp())
1501 return create_table_no_lock(session,
1527 check_if_keyname_exists(
const char *name, KeyInfo *start, KeyInfo *end)
1529 for (KeyInfo *key= start; key != end; key++)
1531 if (!system_charset_info->strcasecmp(name, key->name))
1539 make_unique_key_name(
const char *field_name,KeyInfo *start,KeyInfo *end)
1541 char buff[MAX_FIELD_NAME],*buff_end;
1543 if (not check_if_keyname_exists(field_name,start,end) && not is_primary_key(field_name))
1548 buff_end= strncpy(buff, field_name,
sizeof(buff)-4);
1549 buff_end+= strlen(buff);
1555 for (uint32_t i=2 ; i< 100; i++)
1558 internal::int10_to_str(i, buff_end+1, 10);
1559 if (!check_if_keyname_exists(buff,start,end))
1560 return memory::sql_strdup(buff);
1562 return (
char*)
"not_specified";
1588 rename_table(Session &session,
1589 plugin::StorageEngine *base,
1590 const identifier::Table &from,
1591 const identifier::Table &to)
1593 if (not plugin::StorageEngine::doesSchemaExist(to))
1595 my_error(ER_NO_DB_ERROR, MYF(0), to.getSchemaName().c_str());
1599 int error= base->renameTable(session, from, to);
1600 if (error == HA_ERR_WRONG_COMMAND)
1601 my_error(ER_NOT_SUPPORTED_YET, MYF(0),
"ALTER Table");
1604 my_error(ER_ERROR_ON_RENAME, MYF(0),
1605 from.isTmp() ?
"#sql-temporary" : from.getSQLPath().c_str(),
1606 to.isTmp() ?
"#sql-temporary" : to.getSQLPath().c_str(), error);
1631 void wait_while_table_is_used(Session *session, Table *table,
1632 enum ha_extra_function
function)
1635 safe_mutex_assert_owner(table::Cache::mutex().native_handle());
1637 table->cursor->extra(
function);
1639 session->abortLock(table);
1642 identifier::Table identifier(table->getShare()->getSchemaName(), table->getShare()->getTableName());
1643 table::Cache::removeTable(*session, identifier, RTFC_WAIT_OTHER_THREAD_FLAG);
1663 void Session::close_cached_table(Table *table)
1666 wait_while_table_is_used(
this, table, HA_EXTRA_FORCE_REOPEN);
1668 if (open_tables.lock)
1670 unlockTables(open_tables.lock);
1671 open_tables.lock= NULL;
1674 unlink_open_table(table);
1686 static bool admin_table(Session* session, TableList* tables,
1687 const char *operator_name,
1688 thr_lock_type lock_type,
1689 bool open_for_modify,
1690 int (Cursor::*operator_func)(Session*))
1693 Select_Lex *select= &session->lex().select_lex;
1694 List<Item> field_list;
1697 const charset_info_st *
const cs= system_charset_info;
1699 if (! session->endActiveTransaction())
1702 field_list.push_back(item =
new Item_empty_string(
"Table", NAME_CHAR_LEN * 2, cs));
1703 item->maybe_null = 1;
1704 field_list.push_back(item =
new Item_empty_string(
"Op", 10, cs));
1705 item->maybe_null = 1;
1706 field_list.push_back(item =
new Item_empty_string(
"Msg_type", 10, cs));
1707 item->maybe_null = 1;
1708 field_list.push_back(item =
new Item_empty_string(
"Msg_text", 255, cs));
1709 item->maybe_null = 1;
1710 session->getClient()->sendFields(field_list);
1712 for (table= tables; table; table= table->next_local)
1714 identifier::Table table_identifier(table->getSchemaName(), table->getTableName());
1717 std::string table_name = table_identifier.getSQLPath();
1719 table->lock_type= lock_type;
1722 TableList *save_next_global, *save_next_local;
1723 save_next_global= table->next_global;
1724 table->next_global= 0;
1725 save_next_local= table->next_local;
1726 table->next_local= 0;
1727 select->table_list.first= (
unsigned char*)table;
1733 session->lex().query_tables= table;
1734 session->lex().query_tables_last= &table->next_global;
1735 session->lex().query_tables_own_last= 0;
1736 session->no_warnings_for_error= 0;
1738 session->openTablesLock(table);
1739 session->no_warnings_for_error= 0;
1740 table->next_global= save_next_global;
1741 table->next_local= save_next_local;
1754 if (!session->main_da().m_warn_list.size())
1755 push_warning(session, DRIZZLE_ERROR::WARN_LEVEL_ERROR,
1756 ER_CHECK_NO_SUCH_TABLE, ER(ER_CHECK_NO_SUCH_TABLE));
1757 result_code= HA_ADMIN_CORRUPT;
1761 if ((table->table->db_stat & HA_READ_ONLY) && open_for_modify)
1763 char buff[FN_REFLEN + DRIZZLE_ERRMSG_SIZE];
1765 session->getClient()->store(table_name.c_str());
1766 session->getClient()->store(operator_name);
1767 session->getClient()->store(STRING_WITH_LEN(
"error"));
1768 length= snprintf(buff,
sizeof(buff), ER(ER_OPEN_AS_READONLY),
1769 table_name.c_str());
1770 session->getClient()->store(buff, length);
1771 TransactionServices::autocommitOrRollback(*session,
false);
1772 session->endTransaction(COMMIT);
1773 session->close_thread_tables();
1774 session->lex().reset_query_tables_list(
false);
1776 if (session->getClient()->flush())
1782 if (lock_type == TL_WRITE && table->table->getShare()->getVersion())
1784 table::Cache::mutex().lock();
1785 const char *old_message=session->enter_cond(COND_refresh, table::Cache::mutex(),
1786 "Waiting to get writelock");
1787 session->abortLock(table->table);
1788 identifier::Table identifier(table->table->getShare()->getSchemaName(), table->table->getShare()->getTableName());
1789 table::Cache::removeTable(*session, identifier, RTFC_WAIT_OTHER_THREAD_FLAG | RTFC_CHECK_KILLED_FLAG);
1790 session->exit_cond(old_message);
1791 if (session->getKilled())
1796 result_code = (table->table->cursor->*operator_func)(session);
1800 session->lex().cleanup_after_one_table_open();
1801 session->clear_error();
1803 BOOST_FOREACH(DRIZZLE_ERROR* err, session->main_da().m_warn_list)
1805 session->getClient()->store(table_name.c_str());
1806 session->getClient()->store(operator_name);
1807 session->getClient()->store(warning_level_names[err->level].data(), warning_level_names[err->level].size());
1808 session->getClient()->store(err->msg);
1809 if (session->getClient()->flush())
1812 drizzle_reset_errors(*session,
true);
1814 session->getClient()->store(table_name.c_str());
1815 session->getClient()->store(operator_name);
1817 switch (result_code) {
1818 case HA_ADMIN_NOT_IMPLEMENTED:
1820 char buf[ERRMSGSIZE+20];
1821 uint32_t length=snprintf(buf, ERRMSGSIZE,
1822 ER(ER_CHECK_NOT_IMPLEMENTED), operator_name);
1823 session->getClient()->store(STRING_WITH_LEN(
"note"));
1824 session->getClient()->store(buf, length);
1829 session->getClient()->store(STRING_WITH_LEN(
"status"));
1830 session->getClient()->store(STRING_WITH_LEN(
"OK"));
1833 case HA_ADMIN_FAILED:
1834 session->getClient()->store(STRING_WITH_LEN(
"status"));
1835 session->getClient()->store(STRING_WITH_LEN(
"Operation failed"));
1838 case HA_ADMIN_REJECT:
1839 session->getClient()->store(STRING_WITH_LEN(
"status"));
1840 session->getClient()->store(STRING_WITH_LEN(
"Operation need committed state"));
1841 open_for_modify=
false;
1844 case HA_ADMIN_ALREADY_DONE:
1845 session->getClient()->store(STRING_WITH_LEN(
"status"));
1846 session->getClient()->store(STRING_WITH_LEN(
"Table is already up to date"));
1849 case HA_ADMIN_CORRUPT:
1850 session->getClient()->store(STRING_WITH_LEN(
"error"));
1851 session->getClient()->store(STRING_WITH_LEN(
"Corrupt"));
1855 case HA_ADMIN_INVALID:
1856 session->getClient()->store(STRING_WITH_LEN(
"error"));
1857 session->getClient()->store(STRING_WITH_LEN(
"Invalid argument"));
1862 char buf[ERRMSGSIZE+20];
1863 uint32_t length=snprintf(buf, ERRMSGSIZE,
1864 _(
"Unknown - internal error %d during operation"),
1866 session->getClient()->store(STRING_WITH_LEN(
"error"));
1867 session->getClient()->store(buf, length);
1876 table->table->getMutableShare()->resetVersion();
1878 else if (open_for_modify)
1880 if (table->table->getShare()->getType())
1882 table->table->cursor->info(HA_STATUS_CONST);
1886 boost::unique_lock<boost::mutex> lock(table::Cache::mutex());
1887 identifier::Table identifier(table->table->getShare()->getSchemaName(), table->table->getShare()->getTableName());
1888 table::Cache::removeTable(*session, identifier, RTFC_NO_FLAG);
1892 TransactionServices::autocommitOrRollback(*session,
false);
1893 session->endTransaction(COMMIT);
1894 session->close_thread_tables();
1896 if (session->getClient()->flush())
1904 TransactionServices::autocommitOrRollback(*session,
true);
1905 session->endTransaction(ROLLBACK);
1906 session->close_thread_tables();
1927 static bool create_table_wrapper(Session &session,
1928 const message::Table& create_table_proto,
1929 const identifier::Table& destination_identifier,
1930 const identifier::Table& source_identifier,
1936 message::Table new_table_message;
1938 message::table::shared_ptr source_table_message= plugin::StorageEngine::getTableMessage(session, source_identifier);
1940 if (not source_table_message)
1942 my_error(ER_TABLE_UNKNOWN, source_identifier);
1946 new_table_message.CopyFrom(*source_table_message);
1947 new_table_message.set_type(destination_identifier.isTmp() ? message::Table::TEMPORARY : message::Table::STANDARD);
1951 new_table_message.mutable_engine()->set_name(create_table_proto.engine().name());
1955 new_table_message.set_name(create_table_proto.name());
1956 new_table_message.set_schema(create_table_proto.schema());
1957 new_table_message.set_catalog(create_table_proto.catalog());
1961 for (int32_t j= 0; j < new_table_message.fk_constraint_size(); j++)
1963 if (new_table_message.fk_constraint(j).has_name())
1965 std::string name(new_table_message.name());
1968 name.append(
"_ibfk_");
1969 snprintf(number,
sizeof(number),
"%d", j+1);
1970 name.append(number);
1972 message::Table::ForeignKeyConstraint *pfkey= new_table_message.mutable_fk_constraint(j);
1973 pfkey->set_name(name);
1981 bool success= plugin::StorageEngine::createTable(session, destination_identifier, new_table_message);
1983 if (success && not destination_identifier.isTmp())
1985 TransactionServices::createTable(session, new_table_message);
2006 bool create_like_table(Session* session,
2007 const identifier::Table& destination_identifier,
2008 const identifier::Table& source_identifier,
2009 message::Table &create_table_proto,
2010 bool is_if_not_exists,
2014 bool table_exists=
false;
2022 if (destination_identifier.isTmp())
2024 if (session->open_tables.find_temporary_table(destination_identifier))
2030 bool was_created= create_table_wrapper(*session,
2032 destination_identifier,
2035 if (not was_created)
2037 (void) session->open_tables.rm_temporary_table(destination_identifier,
true);
2039 else if (not session->open_temporary_table(destination_identifier))
2042 (void) session->open_tables.rm_temporary_table(destination_identifier,
true);
2052 Table *name_lock= session->lock_table_name_if_not_cached(destination_identifier);
2057 else if (plugin::StorageEngine::doesTableExist(*session, destination_identifier))
2065 boost::mutex::scoped_lock lock(table::Cache::mutex());
2066 was_created= create_table_wrapper(*session, create_table_proto, destination_identifier,
2067 source_identifier, is_engine_set);
2072 if (not was_created)
2074 plugin::StorageEngine::dropTable(*session, destination_identifier);
2084 boost::mutex::scoped_lock lock(table::Cache::mutex());
2085 session->unlink_open_table(name_lock);
2091 if (is_if_not_exists)
2093 char warn_buff[DRIZZLE_ERRMSG_SIZE];
2094 snprintf(warn_buff,
sizeof(warn_buff),
2095 ER(ER_TABLE_EXISTS_ERROR), destination_identifier.getTableName().c_str());
2096 push_warning(session, DRIZZLE_ERROR::WARN_LEVEL_NOTE,
2097 ER_TABLE_EXISTS_ERROR, warn_buff);
2101 my_error(ER_TABLE_EXISTS_ERROR, destination_identifier);
2110 bool analyze_table(Session* session, TableList* tables)
2112 return admin_table(session, tables,
"analyze", TL_READ_NO_INSERT,
true, &Cursor::ha_analyze);
2116 bool check_table(Session* session, TableList* tables)
2118 return admin_table(session, tables,
"check", TL_READ_NO_INSERT,
false, &Cursor::ha_check);