23 #include "sql_table.h"
24 #include "sql_rename.h"
25 #include "sql_parse.h"
26 #include "sql_cache.h"
31 #include "sql_truncate.h"
32 #include "sql_partition.h"
42 #include "sql_handler.h"
44 #include "my_pthread.h"
51 #include "sql_trigger.h"
52 #include "sql_parse.h"
54 #include "transaction.h"
56 #include "sql_resolver.h"
57 #include "table_cache.h"
68 const char *primary_key_name=
"PRIMARY";
71 bool symdir_warning_emitted=
false;
74 static bool check_if_keyname_exists(
const char *
name,
KEY *start,
KEY *end);
75 static char *make_unique_key_name(
const char *field_name,
KEY *start,
KEY *end);
76 static int copy_data_between_tables(
TABLE *from,
TABLE *
to,
78 uint order_num,
ORDER *order,
79 ha_rows *copied,ha_rows *deleted,
80 Alter_info::enum_enable_or_disable keys_onoff,
83 static bool prepare_blob_field(THD *thd,
Create_field *sql_field);
84 static void sp_prepare_create_field(THD *thd,
Create_field *sql_field);
85 static bool check_engine(THD *thd,
const char *db_name,
95 uint *key_count,
int select_field_count);
106 static char* add_identifier(THD* thd,
char *to_p,
const char * end_p,
107 const char*
name, uint name_len)
111 const char *conv_name;
112 char tmp_name[FN_REFLEN];
113 char conv_string[FN_REFLEN];
116 DBUG_ENTER(
"add_identifier");
121 strnmov(tmp_name, name, name_len);
122 tmp_name[name_len]= 0;
125 res= strconvert(&my_charset_filename, conv_name, system_charset_info,
126 conv_string, FN_REFLEN, &errors);
129 DBUG_PRINT(
"error", (
"strconvert of '%s' failed with %u (errors: %u)", conv_name, res, errors));
134 DBUG_PRINT(
"info", (
"conv '%s' -> '%s'", conv_name, conv_string));
135 conv_name= conv_string;
138 quote = thd ? get_quote_char_for_identifier(thd, conv_name, res - 1) :
'"';
140 if (quote != EOF && (end_p - to_p > 2))
142 *(to_p++)= (
char) quote;
143 while (*conv_name && (end_p - to_p - 1) > 0)
145 uint length= my_mbcharlen(system_charset_info, *conv_name);
148 if (length == 1 && *conv_name == (
char) quote)
150 if ((end_p - to_p) < 3)
152 *(to_p++)= (
char) quote;
153 *(to_p++)= *(conv_name++);
155 else if (((
long) length) < (end_p - to_p))
157 to_p= strnmov(to_p, conv_name, length);
164 *(to_p++)= (
char) quote;
170 to_p= strnmov(to_p, conv_name, end_p - to_p);
208 uint explain_filename(THD* thd,
212 enum_explain_filename_mode explain_mode)
215 char *end_p= to_p + to_length;
216 const char *db_name= NULL;
219 int table_name_len= 0;
220 const char *part_name= NULL;
221 int part_name_len= 0;
222 const char *subpart_name= NULL;
223 int subpart_name_len= 0;
224 enum enum_part_name_type {NORMAL, TEMP, RENAMED} part_type= NORMAL;
227 DBUG_ENTER(
"explain_filename");
228 DBUG_PRINT(
"enter", (
"from '%s'", from));
235 while ((tmp_p= strchr(tmp_p,
'/')))
239 db_name_len= tmp_p - db_name;
245 while ((tmp_p= strchr(tmp_p,
'#')))
253 part_name= tmp_p + 2;
259 if ((tmp_p[1] ==
'P' || tmp_p[1] ==
'p') && tmp_p[2] ==
'#')
261 part_name_len= tmp_p - part_name - 1;
262 subpart_name= tmp_p + 3;
268 if ((tmp_p[1] ==
'M' || tmp_p[1] ==
'm') &&
269 (tmp_p[2] ==
'P' || tmp_p[2] ==
'p') &&
270 tmp_p[3] ==
'#' && !tmp_p[4])
278 if ((tmp_p[1] ==
'E' || tmp_p[1] ==
'e') &&
279 (tmp_p[2] ==
'N' || tmp_p[2] ==
'n') &&
280 tmp_p[3] ==
'#' && !tmp_p[4])
293 table_name_len= part_name - table_name - 3;
295 subpart_name_len= strlen(subpart_name);
297 part_name_len= strlen(part_name);
298 if (part_type != NORMAL)
301 subpart_name_len-= 5;
307 table_name_len= strlen(table_name);
310 if (explain_mode == EXPLAIN_ALL_VERBOSE)
312 to_p= strnmov(to_p, ER_THD_OR_DEFAULT(thd, ER_DATABASE_NAME),
315 to_p= add_identifier(thd, to_p, end_p, db_name, db_name_len);
316 to_p= strnmov(to_p,
", ", end_p - to_p);
320 to_p= add_identifier(thd, to_p, end_p, db_name, db_name_len);
321 to_p= strnmov(to_p,
".", end_p - to_p);
324 if (explain_mode == EXPLAIN_ALL_VERBOSE)
326 to_p= strnmov(to_p, ER_THD_OR_DEFAULT(thd, ER_TABLE_NAME), end_p - to_p);
328 to_p= add_identifier(thd, to_p, end_p, table_name, table_name_len);
331 to_p= add_identifier(thd, to_p, end_p, table_name, table_name_len);
334 if (explain_mode == EXPLAIN_PARTITIONS_AS_COMMENT)
335 to_p= strnmov(to_p,
" /* ", end_p - to_p);
336 else if (explain_mode == EXPLAIN_PARTITIONS_VERBOSE)
337 to_p= strnmov(to_p,
" ", end_p - to_p);
339 to_p= strnmov(to_p,
", ", end_p - to_p);
340 if (part_type != NORMAL)
342 if (part_type == TEMP)
343 to_p= strnmov(to_p, ER_THD_OR_DEFAULT(thd, ER_TEMPORARY_NAME),
346 to_p= strnmov(to_p, ER_THD_OR_DEFAULT(thd, ER_RENAMED_NAME),
348 to_p= strnmov(to_p,
" ", end_p - to_p);
350 to_p= strnmov(to_p, ER_THD_OR_DEFAULT(thd, ER_PARTITION_NAME),
353 to_p= add_identifier(thd, to_p, end_p, part_name, part_name_len);
356 to_p= strnmov(to_p,
", ", end_p - to_p);
357 to_p= strnmov(to_p, ER_THD_OR_DEFAULT(thd, ER_SUBPARTITION_NAME),
360 to_p= add_identifier(thd, to_p, end_p, subpart_name, subpart_name_len);
362 if (explain_mode == EXPLAIN_PARTITIONS_AS_COMMENT)
363 to_p= strnmov(to_p,
" */", end_p - to_p);
365 DBUG_PRINT(
"exit", (
"to '%s'", to));
366 DBUG_RETURN(to_p - to);
383 uint filename_to_tablename(
const char *from,
char *to, uint to_length
391 DBUG_ENTER(
"filename_to_tablename");
392 DBUG_PRINT(
"enter", (
"from '%s'", from));
394 if (strlen(from) >= tmp_file_prefix_length &&
398 res= (strnmov(to, from, to_length) -
to);
402 res= strconvert(&my_charset_filename, from,
403 system_charset_info, to, to_length, &errors);
406 res= (strxnmov(to, to_length, MYSQL50_TABLE_NAME_PREFIX, from, NullS) -
411 sql_print_error(
"Invalid (old?) table or database name '%s'", from);
422 DBUG_PRINT(
"exit", (
"to '%s'", to));
438 bool check_mysql50_prefix(
const char *name)
440 return (name[0] ==
'#' &&
441 !strncmp(name, MYSQL50_TABLE_NAME_PREFIX,
442 MYSQL50_TABLE_NAME_PREFIX_LENGTH));
459 uint check_n_cut_mysql50_prefix(
const char *from,
char *to, uint to_length)
461 if (check_mysql50_prefix(from))
462 return (uint) (strmake(to, from + MYSQL50_TABLE_NAME_PREFIX_LENGTH,
463 to_length - 1) -
to);
481 uint tablename_to_filename(
const char *from,
char *to, uint to_length)
484 DBUG_ENTER(
"tablename_to_filename");
485 DBUG_PRINT(
"enter", (
"from '%s'", from));
487 if ((length= check_n_cut_mysql50_prefix(from, to, to_length)))
496 if (check_table_name(to, length, TRUE) != IDENT_NAME_OK)
503 length= strconvert(system_charset_info, from,
504 &my_charset_filename, to, to_length, &errors);
505 if (check_if_legal_tablename(to) &&
506 length + 4 < to_length)
508 memcpy(to + length,
"@@@", 4);
511 DBUG_PRINT(
"exit", (
"to '%s'", to));
549 uint build_table_filename(
char *buff,
size_t bufflen,
const char *db,
550 const char *table_name,
const char *ext,
551 uint
flags,
bool *was_truncated)
553 char tbbuff[FN_REFLEN], dbbuff[FN_REFLEN];
554 uint tab_len, db_len;
555 DBUG_ENTER(
"build_table_filename");
556 DBUG_PRINT(
"enter", (
"db: '%s' table_name: '%s' ext: '%s' flags: %x",
557 db, table_name, ext, flags));
559 if (flags & FN_IS_TMP)
560 tab_len= strnmov(tbbuff, table_name,
sizeof(tbbuff)) - tbbuff;
562 tab_len= tablename_to_filename(table_name, tbbuff,
sizeof(tbbuff));
564 db_len= tablename_to_filename(db, dbbuff,
sizeof(dbbuff));
566 char *end = buff + bufflen;
568 char *pos = strnmov(buff, mysql_data_home, bufflen);
569 size_t rootdir_len= strlen(FN_ROOTDIR);
570 if (pos - rootdir_len >= buff &&
571 memcmp(pos - rootdir_len, FN_ROOTDIR, rootdir_len) != 0)
572 pos= strnmov(pos, FN_ROOTDIR, end - pos);
575 pos= strxnmov(pos, end - pos, dbbuff, FN_ROOTDIR, NullS);
577 if (!(flags & SKIP_SYMDIR_ACCESS))
581 unpack_dirname(buff, buff, &is_symdir);
587 if (is_symdir && !symdir_warning_emitted)
589 symdir_warning_emitted=
true;
590 sql_print_warning(
"Symbolic links based on .sym files are deprecated. "
591 "Please use native Windows symbolic links instead "
592 "(see MKLINK command).");
597 pos= strxnmov(pos, end - pos, tbbuff, ext, NullS);
605 *was_truncated=
false;
607 (bufflen < mysql_data_home_len + rootdir_len + db_len +
608 strlen(FN_ROOTDIR) + tab_len + strlen(ext)))
609 *was_truncated=
true;
611 DBUG_PRINT(
"exit", (
"buff: '%s'", buff));
612 DBUG_RETURN(pos - buff);
631 uint build_tmptable_filename(THD* thd,
char *buff,
size_t bufflen)
633 DBUG_ENTER(
"build_tmptable_filename");
635 char *p= strnmov(buff, mysql_tmpdir, bufflen);
636 my_snprintf(p, bufflen - (p - buff),
"/%s%lx_%lx_%x",
638 thd->thread_id, thd->tmp_table++);
640 if (lower_case_table_names)
643 my_casedn_str(files_charset_info, p);
646 size_t length= unpack_filename(buff, buff);
647 DBUG_PRINT(
"exit", (
"buff: '%s'", buff));
685 char file_entry_buf[4*IO_SIZE];
686 char file_name_str[FN_REFLEN];
704 #define DDL_LOG_ENTRY_TYPE_POS 0
705 #define DDL_LOG_ACTION_TYPE_POS 1
706 #define DDL_LOG_PHASE_POS 2
707 #define DDL_LOG_NEXT_ENTRY_POS 4
708 #define DDL_LOG_NAME_POS 8
710 #define DDL_LOG_NUM_ENTRY_POS 0
711 #define DDL_LOG_NAME_LEN_POS 4
712 #define DDL_LOG_IO_SIZE_POS 8
724 static bool read_ddl_log_file_entry(uint entry_no)
727 File file_id= global_ddl_log.file_id;
728 uchar *file_entry_buf= (uchar*)global_ddl_log.file_entry_buf;
729 uint io_size= global_ddl_log.io_size;
730 DBUG_ENTER(
"read_ddl_log_file_entry");
734 MYF(MY_WME)) != io_size)
750 static bool write_ddl_log_file_entry(uint entry_no)
753 File file_id= global_ddl_log.file_id;
754 uchar *file_entry_buf= (uchar*)global_ddl_log.file_entry_buf;
755 DBUG_ENTER(
"write_ddl_log_file_entry");
759 IO_SIZE, IO_SIZE * entry_no, MYF(MY_WME)) != IO_SIZE)
773 static bool sync_ddl_log_file()
775 DBUG_ENTER(
"sync_ddl_log_file");
788 static bool write_ddl_log_header()
791 DBUG_ENTER(
"write_ddl_log_header");
793 int4store(&global_ddl_log.file_entry_buf[DDL_LOG_NUM_ENTRY_POS],
794 global_ddl_log.num_entries);
795 const_var= FN_REFLEN;
796 int4store(&global_ddl_log.file_entry_buf[DDL_LOG_NAME_LEN_POS],
799 int4store(&global_ddl_log.file_entry_buf[DDL_LOG_IO_SIZE_POS],
801 if (write_ddl_log_file_entry(0UL))
803 sql_print_error(
"Error writing ddl log header");
806 DBUG_RETURN(sync_ddl_log_file());
815 static inline void create_ddl_log_file_name(
char *file_name)
817 strxmov(file_name, mysql_data_home,
"/",
"ddl_log.log", NullS);
831 static uint read_ddl_log_header()
833 uchar *file_entry_buf= (uchar*)global_ddl_log.file_entry_buf;
834 char file_name[FN_REFLEN];
836 bool successful_open= FALSE;
837 DBUG_ENTER(
"read_ddl_log_header");
841 create_ddl_log_file_name(file_name);
844 O_RDWR | O_BINARY, MYF(0))) >= 0)
846 if (read_ddl_log_file_entry(0UL))
849 sql_print_error(
"Failed to read ddl log file in recovery");
852 successful_open= TRUE;
856 entry_no= uint4korr(&file_entry_buf[DDL_LOG_NUM_ENTRY_POS]);
857 global_ddl_log.name_len= uint4korr(&file_entry_buf[DDL_LOG_NAME_LEN_POS]);
858 global_ddl_log.io_size= uint4korr(&file_entry_buf[DDL_LOG_IO_SIZE_POS]);
859 DBUG_ASSERT(global_ddl_log.io_size <=
860 sizeof(global_ddl_log.file_entry_buf));
866 global_ddl_log.first_free= NULL;
867 global_ddl_log.first_used= NULL;
868 global_ddl_log.num_entries= 0;
869 global_ddl_log.do_release=
true;
871 DBUG_RETURN(entry_no);
881 static void set_global_from_ddl_log_entry(
const DDL_LOG_ENTRY *ddl_log_entry)
884 global_ddl_log.file_entry_buf[DDL_LOG_ENTRY_TYPE_POS]=
885 (char)DDL_LOG_ENTRY_CODE;
886 global_ddl_log.file_entry_buf[DDL_LOG_ACTION_TYPE_POS]=
887 (char)ddl_log_entry->action_type;
888 global_ddl_log.file_entry_buf[DDL_LOG_PHASE_POS]= 0;
889 int4store(&global_ddl_log.file_entry_buf[DDL_LOG_NEXT_ENTRY_POS],
890 ddl_log_entry->next_entry);
891 DBUG_ASSERT(strlen(ddl_log_entry->name) < FN_REFLEN);
892 strmake(&global_ddl_log.file_entry_buf[DDL_LOG_NAME_POS],
893 ddl_log_entry->name, FN_REFLEN - 1);
894 if (ddl_log_entry->action_type == DDL_LOG_RENAME_ACTION ||
895 ddl_log_entry->action_type == DDL_LOG_REPLACE_ACTION ||
896 ddl_log_entry->action_type == DDL_LOG_EXCHANGE_ACTION)
898 DBUG_ASSERT(strlen(ddl_log_entry->from_name) < FN_REFLEN);
899 strmake(&global_ddl_log.file_entry_buf[DDL_LOG_NAME_POS + FN_REFLEN],
900 ddl_log_entry->from_name, FN_REFLEN - 1);
903 global_ddl_log.file_entry_buf[DDL_LOG_NAME_POS + FN_REFLEN]= 0;
904 DBUG_ASSERT(strlen(ddl_log_entry->handler_name) < FN_REFLEN);
905 strmake(&global_ddl_log.file_entry_buf[DDL_LOG_NAME_POS + (2*FN_REFLEN)],
906 ddl_log_entry->handler_name, FN_REFLEN - 1);
907 if (ddl_log_entry->action_type == DDL_LOG_EXCHANGE_ACTION)
909 DBUG_ASSERT(strlen(ddl_log_entry->tmp_name) < FN_REFLEN);
910 strmake(&global_ddl_log.file_entry_buf[DDL_LOG_NAME_POS + (3*FN_REFLEN)],
911 ddl_log_entry->tmp_name, FN_REFLEN - 1);
914 global_ddl_log.file_entry_buf[DDL_LOG_NAME_POS + (3*FN_REFLEN)]= 0;
927 static void set_ddl_log_entry_from_global(
DDL_LOG_ENTRY *ddl_log_entry,
928 const uint read_entry)
930 char *file_entry_buf= (
char*) global_ddl_log.file_entry_buf;
935 ddl_log_entry->entry_pos= read_entry;
936 single_char= file_entry_buf[DDL_LOG_ENTRY_TYPE_POS];
937 ddl_log_entry->entry_type= (
enum ddl_log_entry_code)single_char;
938 single_char= file_entry_buf[DDL_LOG_ACTION_TYPE_POS];
939 ddl_log_entry->action_type= (
enum ddl_log_action_code)single_char;
940 ddl_log_entry->phase= file_entry_buf[DDL_LOG_PHASE_POS];
941 ddl_log_entry->next_entry= uint4korr(&file_entry_buf[DDL_LOG_NEXT_ENTRY_POS]);
942 ddl_log_entry->name= &file_entry_buf[DDL_LOG_NAME_POS];
943 inx= DDL_LOG_NAME_POS + global_ddl_log.name_len;
944 ddl_log_entry->from_name= &file_entry_buf[inx];
945 inx+= global_ddl_log.name_len;
946 ddl_log_entry->handler_name= &file_entry_buf[inx];
947 if (ddl_log_entry->action_type == DDL_LOG_EXCHANGE_ACTION)
949 inx+= global_ddl_log.name_len;
950 ddl_log_entry->tmp_name= &file_entry_buf[inx];
953 ddl_log_entry->tmp_name= NULL;
970 static bool read_ddl_log_entry(uint read_entry,
DDL_LOG_ENTRY *ddl_log_entry)
972 DBUG_ENTER(
"read_ddl_log_entry");
974 if (read_ddl_log_file_entry(read_entry))
978 set_ddl_log_entry_from_global(ddl_log_entry, read_entry);
994 static bool init_ddl_log()
996 char file_name[FN_REFLEN];
997 DBUG_ENTER(
"init_ddl_log");
999 if (global_ddl_log.inited)
1002 global_ddl_log.io_size= IO_SIZE;
1003 global_ddl_log.name_len= FN_REFLEN;
1004 create_ddl_log_file_name(file_name);
1006 file_name, CREATE_MODE,
1007 O_RDWR | O_TRUNC | O_BINARY,
1011 sql_print_error(
"Failed to open ddl log file");
1014 global_ddl_log.inited= TRUE;
1015 if (write_ddl_log_header())
1018 global_ddl_log.inited= FALSE;
1035 static bool sync_ddl_log_no_lock()
1037 DBUG_ENTER(
"sync_ddl_log_no_lock");
1040 if ((!global_ddl_log.recovery_phase) &&
1045 DBUG_RETURN(sync_ddl_log_file());
1076 static bool deactivate_ddl_log_entry_no_lock(uint entry_no)
1078 uchar *file_entry_buf= (uchar*)global_ddl_log.file_entry_buf;
1079 DBUG_ENTER(
"deactivate_ddl_log_entry_no_lock");
1082 if (!read_ddl_log_file_entry(entry_no))
1084 if (file_entry_buf[DDL_LOG_ENTRY_TYPE_POS] == DDL_LOG_ENTRY_CODE)
1090 if (file_entry_buf[DDL_LOG_ACTION_TYPE_POS] == DDL_LOG_DELETE_ACTION ||
1091 file_entry_buf[DDL_LOG_ACTION_TYPE_POS] == DDL_LOG_RENAME_ACTION ||
1092 (file_entry_buf[DDL_LOG_ACTION_TYPE_POS] == DDL_LOG_REPLACE_ACTION &&
1093 file_entry_buf[DDL_LOG_PHASE_POS] == 1) ||
1094 (file_entry_buf[DDL_LOG_ACTION_TYPE_POS] == DDL_LOG_EXCHANGE_ACTION &&
1095 file_entry_buf[DDL_LOG_PHASE_POS] >= EXCH_PHASE_TEMP_TO_FROM))
1096 file_entry_buf[DDL_LOG_ENTRY_TYPE_POS]= DDL_IGNORE_LOG_ENTRY_CODE;
1097 else if (file_entry_buf[DDL_LOG_ACTION_TYPE_POS] == DDL_LOG_REPLACE_ACTION)
1099 DBUG_ASSERT(file_entry_buf[DDL_LOG_PHASE_POS] == 0);
1100 file_entry_buf[DDL_LOG_PHASE_POS]= 1;
1102 else if (file_entry_buf[DDL_LOG_ACTION_TYPE_POS] == DDL_LOG_EXCHANGE_ACTION)
1104 DBUG_ASSERT(file_entry_buf[DDL_LOG_PHASE_POS] <=
1105 EXCH_PHASE_FROM_TO_NAME);
1106 file_entry_buf[DDL_LOG_PHASE_POS]++;
1112 if (write_ddl_log_file_entry(entry_no))
1114 sql_print_error(
"Error in deactivating log entry. Position = %u",
1122 sql_print_error(
"Failed in reading entry before deactivating it");
1139 static int execute_ddl_log_action(THD *thd,
DDL_LOG_ENTRY *ddl_log_entry)
1141 bool frm_action= FALSE;
1146 char to_path[FN_REFLEN];
1147 char from_path[FN_REFLEN];
1148 #ifdef WITH_PARTITION_STORAGE_ENGINE
1149 char *par_ext= (
char*)
".par";
1152 DBUG_ENTER(
"execute_ddl_log_action");
1155 if (ddl_log_entry->entry_type == DDL_IGNORE_LOG_ENTRY_CODE)
1159 DBUG_PRINT(
"ddl_log",
1160 (
"execute type %c next %u name '%s' from_name '%s' handler '%s'"
1162 ddl_log_entry->action_type,
1163 ddl_log_entry->next_entry,
1164 ddl_log_entry->name,
1165 ddl_log_entry->from_name,
1166 ddl_log_entry->handler_name,
1167 ddl_log_entry->tmp_name));
1168 handler_name.str= (
char*)ddl_log_entry->handler_name;
1169 handler_name.length= strlen(ddl_log_entry->handler_name);
1170 init_sql_alloc(&mem_root, TABLE_ALLOC_BLOCK_SIZE, 0);
1171 if (!strcmp(ddl_log_entry->handler_name, reg_ext))
1178 my_error(ER_ILLEGAL_HA, MYF(0), ddl_log_entry->handler_name);
1182 file= get_new_handler((
TABLE_SHARE*)0, &mem_root, hton);
1185 mem_alloc_error(
sizeof(
handler));
1189 switch (ddl_log_entry->action_type)
1191 case DDL_LOG_REPLACE_ACTION:
1192 case DDL_LOG_DELETE_ACTION:
1194 if (ddl_log_entry->phase == 0)
1198 strxmov(to_path, ddl_log_entry->name, reg_ext, NullS);
1201 if (my_errno != ENOENT)
1204 #ifdef WITH_PARTITION_STORAGE_ENGINE
1205 strxmov(to_path, ddl_log_entry->name, par_ext, NullS);
1213 if (error != ENOENT && error != HA_ERR_NO_SUCH_TABLE)
1217 if ((deactivate_ddl_log_entry_no_lock(ddl_log_entry->entry_pos)))
1219 (void) sync_ddl_log_no_lock();
1221 if (ddl_log_entry->action_type == DDL_LOG_DELETE_ACTION)
1224 DBUG_ASSERT(ddl_log_entry->action_type == DDL_LOG_REPLACE_ACTION);
1231 case DDL_LOG_RENAME_ACTION:
1236 strxmov(to_path, ddl_log_entry->name, reg_ext, NullS);
1237 strxmov(from_path, ddl_log_entry->from_name, reg_ext, NullS);
1240 #ifdef WITH_PARTITION_STORAGE_ENGINE
1241 strxmov(to_path, ddl_log_entry->name, par_ext, NullS);
1242 strxmov(from_path, ddl_log_entry->from_name, par_ext, NullS);
1249 ddl_log_entry->name))
1252 if ((deactivate_ddl_log_entry_no_lock(ddl_log_entry->entry_pos)))
1254 (void) sync_ddl_log_no_lock();
1258 case DDL_LOG_EXCHANGE_ACTION:
1261 char *file_entry_buf= (
char*)&global_ddl_log.file_entry_buf;
1263 DBUG_ASSERT(!frm_action);
1268 switch (ddl_log_entry->phase) {
1269 case EXCH_PHASE_TEMP_TO_FROM:
1272 ddl_log_entry->tmp_name);
1274 file_entry_buf[DDL_LOG_PHASE_POS]--;
1275 if (write_ddl_log_file_entry(ddl_log_entry->entry_pos))
1277 if (sync_ddl_log_no_lock())
1280 case EXCH_PHASE_FROM_TO_NAME:
1283 ddl_log_entry->from_name);
1285 file_entry_buf[DDL_LOG_PHASE_POS]--;
1286 if (write_ddl_log_file_entry(ddl_log_entry->entry_pos))
1288 if (sync_ddl_log_no_lock())
1291 case EXCH_PHASE_NAME_TO_TEMP:
1294 ddl_log_entry->name);
1296 file_entry_buf[DDL_LOG_ENTRY_TYPE_POS]= DDL_IGNORE_LOG_ENTRY_CODE;
1297 if (write_ddl_log_file_entry(ddl_log_entry->entry_pos))
1299 if (sync_ddl_log_no_lock())
1316 free_root(&mem_root, MYF(0));
1336 DBUG_ENTER(
"get_free_ddl_log_entry");
1338 if (global_ddl_log.first_free == NULL)
1343 sql_print_error(
"Failed to allocate memory for ddl log free list");
1346 global_ddl_log.num_entries++;
1347 used_entry->entry_pos= global_ddl_log.num_entries;
1348 *write_header= TRUE;
1352 used_entry= global_ddl_log.first_free;
1353 global_ddl_log.first_free= used_entry->next_log_entry;
1354 *write_header= FALSE;
1359 used_entry->next_log_entry= first_used;
1360 used_entry->prev_log_entry= NULL;
1361 used_entry->next_active_log_entry= NULL;
1362 global_ddl_log.first_used= used_entry;
1364 first_used->prev_log_entry= used_entry;
1366 *active_entry= used_entry;
1383 static bool execute_ddl_log_entry_no_lock(THD *thd, uint first_entry)
1386 uint read_entry= first_entry;
1387 DBUG_ENTER(
"execute_ddl_log_entry_no_lock");
1392 if (read_ddl_log_entry(read_entry, &ddl_log_entry))
1395 sql_print_error(
"Failed to read entry = %u from ddl log",
1399 DBUG_ASSERT(ddl_log_entry.entry_type == DDL_LOG_ENTRY_CODE ||
1400 ddl_log_entry.entry_type == DDL_IGNORE_LOG_ENTRY_CODE);
1402 if (execute_ddl_log_action(thd, &ddl_log_entry))
1405 sql_print_error(
"Failed to execute action for entry = %u from ddl log",
1409 read_entry= ddl_log_entry.next_entry;
1410 }
while (read_entry);
1437 bool error, write_header;
1438 DBUG_ENTER(
"write_ddl_log_entry");
1445 set_global_from_ddl_log_entry(ddl_log_entry);
1446 if (get_free_ddl_log_entry(active_entry, &write_header))
1451 DBUG_PRINT(
"ddl_log",
1452 (
"write type %c next %u name '%s' from_name '%s' handler '%s'"
1454 (
char) global_ddl_log.file_entry_buf[DDL_LOG_ACTION_TYPE_POS],
1455 ddl_log_entry->next_entry,
1456 (
char*) &global_ddl_log.file_entry_buf[DDL_LOG_NAME_POS],
1457 (
char*) &global_ddl_log.file_entry_buf[DDL_LOG_NAME_POS
1459 (
char*) &global_ddl_log.file_entry_buf[DDL_LOG_NAME_POS
1461 (
char*) &global_ddl_log.file_entry_buf[DDL_LOG_NAME_POS
1463 if (write_ddl_log_file_entry((*active_entry)->entry_pos))
1466 sql_print_error(
"Failed to write entry_no = %u",
1467 (*active_entry)->entry_pos);
1469 if (write_header && !error)
1471 (void) sync_ddl_log_no_lock();
1472 if (write_ddl_log_header())
1476 release_ddl_log_memory_entry(*active_entry);
1507 bool write_execute_ddl_log_entry(uint first_entry,
1511 bool write_header= FALSE;
1512 char *file_entry_buf= (
char*)global_ddl_log.file_entry_buf;
1513 DBUG_ENTER(
"write_execute_ddl_log_entry");
1528 (void) sync_ddl_log_no_lock();
1529 file_entry_buf[DDL_LOG_ENTRY_TYPE_POS]= (char)DDL_LOG_EXECUTE_CODE;
1532 file_entry_buf[DDL_LOG_ENTRY_TYPE_POS]= (char)DDL_IGNORE_LOG_ENTRY_CODE;
1533 file_entry_buf[DDL_LOG_ACTION_TYPE_POS]= 0;
1534 file_entry_buf[DDL_LOG_PHASE_POS]= 0;
1535 int4store(&file_entry_buf[DDL_LOG_NEXT_ENTRY_POS], first_entry);
1536 file_entry_buf[DDL_LOG_NAME_POS]= 0;
1537 file_entry_buf[DDL_LOG_NAME_POS + FN_REFLEN]= 0;
1538 file_entry_buf[DDL_LOG_NAME_POS + 2*FN_REFLEN]= 0;
1539 if (!(*active_entry))
1541 if (get_free_ddl_log_entry(active_entry, &write_header))
1547 if (write_ddl_log_file_entry((*active_entry)->entry_pos))
1549 sql_print_error(
"Error writing execute entry in ddl log");
1550 release_ddl_log_memory_entry(*active_entry);
1553 (void) sync_ddl_log_no_lock();
1556 if (write_ddl_log_header())
1558 release_ddl_log_memory_entry(*active_entry);
1578 bool deactivate_ddl_log_entry(uint entry_no)
1581 DBUG_ENTER(
"deactivate_ddl_log_entry");
1584 error= deactivate_ddl_log_entry_no_lock(entry_no);
1601 DBUG_ENTER(
"sync_ddl_log");
1604 error= sync_ddl_log_no_lock();
1621 DBUG_ENTER(
"release_ddl_log_memory_entry");
1624 global_ddl_log.first_free= log_entry;
1625 log_entry->next_log_entry= first_free;
1628 prev_log_entry->next_log_entry= next_log_entry;
1630 global_ddl_log.first_used= next_log_entry;
1632 next_log_entry->prev_log_entry= prev_log_entry;
1649 bool execute_ddl_log_entry(THD *thd, uint first_entry)
1652 DBUG_ENTER(
"execute_ddl_log_entry");
1655 error= execute_ddl_log_entry_no_lock(thd, first_entry);
1665 static void close_ddl_log()
1667 DBUG_ENTER(
"close_ddl_log");
1668 if (global_ddl_log.file_id >= 0)
1671 global_ddl_log.file_id= (File) -1;
1681 void execute_ddl_log_recovery()
1683 uint num_entries,
i;
1686 char file_name[FN_REFLEN];
1687 static char recover_query_string[]=
"INTERNAL DDL LOG RECOVER IN PROGRESS";
1688 DBUG_ENTER(
"execute_ddl_log_recovery");
1693 memset(global_ddl_log.file_entry_buf, 0,
sizeof(global_ddl_log.file_entry_buf));
1694 global_ddl_log.inited= FALSE;
1695 global_ddl_log.recovery_phase= TRUE;
1696 global_ddl_log.io_size= IO_SIZE;
1697 global_ddl_log.file_id= (File) -1;
1704 thd->thread_stack= (
char*) &thd;
1705 thd->store_globals();
1707 thd->set_query(recover_query_string, strlen(recover_query_string));
1710 num_entries= read_ddl_log_header();
1712 for (i= 1; i < num_entries + 1; i++)
1714 if (read_ddl_log_entry(i, &ddl_log_entry))
1716 sql_print_error(
"Failed to read entry no = %u from ddl log", i);
1719 if (ddl_log_entry.entry_type == DDL_LOG_EXECUTE_CODE)
1721 if (execute_ddl_log_entry_no_lock(thd, ddl_log_entry.next_entry))
1729 create_ddl_log_file_name(file_name);
1731 global_ddl_log.recovery_phase= FALSE;
1735 my_pthread_setspecific_ptr(THR_THD, 0);
1744 void release_ddl_log()
1748 DBUG_ENTER(
"release_ddl_log");
1750 if (!global_ddl_log.do_release)
1754 free_list= global_ddl_log.first_free;
1755 used_list= global_ddl_log.first_used;
1769 global_ddl_log.inited= 0;
1772 global_ddl_log.do_release=
false;
1802 uint build_table_shadow_filename(
char *buff,
size_t bufflen,
1805 char tmp_name[FN_REFLEN];
1808 return build_table_filename(buff, bufflen, lpt->db, tmp_name,
"", FN_IS_TMP);
1847 char path[FN_REFLEN+1];
1848 char shadow_path[FN_REFLEN+1];
1849 char shadow_frm_name[FN_REFLEN+1];
1850 char frm_name[FN_REFLEN+1];
1851 #ifdef WITH_PARTITION_STORAGE_ENGINE
1852 char *part_syntax_buf;
1855 DBUG_ENTER(
"mysql_write_frm");
1860 build_table_shadow_filename(shadow_path,
sizeof(shadow_path) - 1, lpt);
1861 strxmov(shadow_frm_name, shadow_path, reg_ext, NullS);
1862 if (flags & WFRM_WRITE_SHADOW)
1864 if (mysql_prepare_create_table(lpt->thd, lpt->create_info,
1869 &lpt->key_info_buffer,
1875 #ifdef WITH_PARTITION_STORAGE_ENGINE
1880 if (!(part_syntax_buf= generate_partition_syntax(part_info,
1889 part_info->part_info_string= part_syntax_buf;
1890 part_info->part_info_len= syntax_len;
1895 lpt->create_info->table_options= lpt->db_options;
1896 if ((mysql_create_frm(lpt->thd, shadow_frm_name, lpt->db,
1897 lpt->table_name, lpt->create_info,
1898 lpt->alter_info->create_list, lpt->key_count,
1899 lpt->key_info_buffer, lpt->table->file)) ||
1909 if (flags & WFRM_PACK_FRM)
1919 if (
readfrm(shadow_path, &data, &length) ||
1920 packfrm(data, length, &lpt->pack_frm_data, &lpt->pack_frm_len))
1923 my_free(lpt->pack_frm_data);
1924 mem_alloc_error(length);
1930 if (flags & WFRM_INSTALL_SHADOW)
1932 #ifdef WITH_PARTITION_STORAGE_ENGINE
1938 build_table_filename(path,
sizeof(path) - 1, lpt->db,
1939 lpt->table_name,
"", 0);
1940 strxmov(frm_name, path, reg_ext, NullS);
1952 #ifdef WITH_PARTITION_STORAGE_ENGINE
1954 CHF_DELETE_FLAG, NULL) ||
1955 deactivate_ddl_log_entry(part_info->frm_log_entry->entry_pos) ||
1956 (sync_ddl_log(), FALSE) ||
1958 shadow_frm_name, frm_name, MYF(MY_WME)) ||
1960 CHF_RENAME_FLAG, NULL))
1963 shadow_frm_name, frm_name, MYF(MY_WME)))
1969 #ifdef WITH_PARTITION_STORAGE_ENGINE
1970 if (part_info && (flags & WFRM_KEEP_SHARE))
1973 char *tmp_part_syntax_str;
1974 if (!(part_syntax_buf= generate_partition_syntax(part_info,
1984 if (share->partition_info_buffer_size < syntax_len + 1)
1986 share->partition_info_buffer_size= syntax_len+1;
1987 if (!(tmp_part_syntax_str= (
char*) strmake_root(&share->mem_root,
1994 share->partition_info_str= tmp_part_syntax_str;
1997 memcpy((
char*) share->partition_info_str, part_syntax_buf,
1999 share->partition_info_str_len= part_info->part_info_len= syntax_len;
2000 part_info->part_info_string= part_syntax_buf;
2005 #ifdef WITH_PARTITION_STORAGE_ENGINE
2006 deactivate_ddl_log_entry(part_info->frm_log_entry->entry_pos);
2007 part_info->frm_log_entry= NULL;
2008 (void) sync_ddl_log();
2036 int write_bin_log(THD *thd,
bool clear_error,
2037 char const *
query, ulong query_length,
bool is_trans)
2040 if (mysql_bin_log.is_open())
2046 errcode= query_error_code(thd, TRUE);
2047 error= thd->binlog_query(THD::STMT_QUERY_TYPE,
2048 query, query_length, is_trans, FALSE, FALSE,
2079 bool mysql_rm_table(THD *thd,
TABLE_LIST *tables, my_bool if_exists,
2080 my_bool drop_temporary)
2083 Drop_table_error_handler err_handler;
2086 DBUG_ENTER(
"mysql_rm_table");
2089 for (table= tables;
table; table= table->next_local)
2091 if (check_if_log_table(table->db_length, table->db,
2092 table->table_name_length, table->table_name,
true))
2094 my_error(ER_BAD_LOG_STATEMENT, MYF(0),
"DROP");
2099 if (!drop_temporary)
2101 if (!thd->locked_tables_mode)
2104 thd->variables.lock_wait_timeout, 0))
2106 for (table= tables;
table; table= table->next_local)
2108 if (is_temporary_table(table))
2117 for (table= tables;
table; table= table->next_local)
2118 if (is_temporary_table(table))
2133 DBUG_ASSERT(table->mdl_request.
ticket == NULL);
2145 table->table_name,
false);
2148 table->mdl_request.
ticket= table->table->mdl_ticket;
2154 thd->push_internal_handler(&err_handler);
2155 error= mysql_rm_table_no_locks(thd, tables, if_exists, drop_temporary,
2157 thd->pop_internal_handler();
2197 int mysql_rm_table_no_locks(THD *thd,
TABLE_LIST *tables,
bool if_exists,
2198 bool drop_temporary,
bool drop_view,
2199 bool dont_log_query)
2202 char path[FN_REFLEN + 1], *alias= NULL;
2203 uint path_length= 0;
2206 int non_temp_tables_count= 0;
2207 bool foreign_key_error=0;
2208 bool non_tmp_error= 0;
2209 bool trans_tmp_table_deleted= 0, non_trans_tmp_table_deleted= 0;
2210 bool non_tmp_table_deleted= 0;
2211 bool is_drop_tmp_if_exists_added= 0;
2213 String built_trans_tmp_query, built_non_trans_tmp_query;
2214 DBUG_ENTER(
"mysql_rm_table_no_locks");
2250 if (!dont_log_query)
2252 if (!drop_temporary)
2254 built_query.set_charset(system_charset_info);
2256 built_query.append(
"DROP TABLE IF EXISTS ");
2258 built_query.append(
"DROP TABLE ");
2261 if (thd->is_current_stmt_binlog_format_row() || if_exists)
2263 is_drop_tmp_if_exists_added=
true;
2264 built_trans_tmp_query.set_charset(system_charset_info);
2265 built_trans_tmp_query.append(
"DROP TEMPORARY TABLE IF EXISTS ");
2266 built_non_trans_tmp_query.set_charset(system_charset_info);
2267 built_non_trans_tmp_query.append(
"DROP TEMPORARY TABLE IF EXISTS ");
2271 built_trans_tmp_query.set_charset(system_charset_info);
2272 built_trans_tmp_query.append(
"DROP TEMPORARY TABLE ");
2273 built_non_trans_tmp_query.set_charset(system_charset_info);
2274 built_non_trans_tmp_query.append(
"DROP TEMPORARY TABLE ");
2278 for (table= tables;
table; table= table->next_local)
2282 int db_len= table->db_length;
2284 enum legacy_db_type frm_db_type= DB_TYPE_UNKNOWN;
2286 DBUG_PRINT(
"table", (
"table_l: '%s'.'%s' table: 0x%lx s: 0x%lx",
2287 table->db, table->table_name, (
long) table->table,
2288 table->table ? (
long) table->table->s : (
long) -1));
2295 DBUG_ASSERT(!(thd->locked_tables_mode &&
2298 table->mdl_request.
ticket != NULL));
2300 thd->add_to_binlog_accessed_dbs(table->db);
2312 DBUG_ASSERT(thd->in_sub_stmt);
2316 if ((drop_temporary && if_exists) || !error)
2328 if (!dont_log_query)
2334 is_trans= error ? TRUE : is_trans;
2336 trans_tmp_table_deleted= TRUE;
2338 non_trans_tmp_table_deleted= TRUE;
2341 (is_trans ? &built_trans_tmp_query : &built_non_trans_tmp_query);
2347 if (thd->db == NULL || strcmp(db,thd->db) != 0
2348 || is_drop_tmp_if_exists_added )
2350 append_identifier(thd, built_ptr_query, db, db_len);
2351 built_ptr_query->append(
".");
2353 append_identifier(thd, built_ptr_query, table->table_name,
2354 strlen(table->table_name));
2355 built_ptr_query->append(
",");
2362 if (!error)
continue;
2364 else if (!drop_temporary)
2366 non_temp_tables_count++;
2368 if (thd->locked_tables_mode)
2380 DBUG_ASSERT(thd->mdl_context.is_lock_owner(MDL_key::TABLE, table->db,
2388 alias= (lower_case_table_names == 2) ? table->alias : table->table_name;
2390 path_length= build_table_filename(path,
sizeof(path) - 1, db, alias,
2392 table->internal_tmp_table ?
2402 if (!dont_log_query)
2409 non_tmp_table_deleted= (if_exists ? TRUE : non_tmp_table_deleted);
2414 if (thd->db == NULL || strcmp(db,thd->db) != 0)
2416 append_identifier(thd, &built_query, db, db_len);
2417 built_query.append(
".");
2420 append_identifier(thd, &built_query, table->table_name,
2421 strlen(table->table_name));
2422 built_query.append(
",");
2425 DEBUG_SYNC(thd,
"rm_table_no_locks_before_delete_table");
2426 DBUG_EXECUTE_IF(
"sleep_before_no_locks_delete_table",
2429 if (drop_temporary ||
2430 ((access(path, F_OK) &&
2433 dd_frm_type(thd, path, &frm_db_type) != FRMTYPE_TABLE)))
2445 tbl_name.append(
String(db,system_charset_info));
2446 tbl_name.append(
'.');
2447 tbl_name.append(
String(table->table_name,system_charset_info));
2449 push_warning_printf(thd, Sql_condition::WARN_LEVEL_NOTE,
2450 ER_BAD_TABLE_ERROR, ER(ER_BAD_TABLE_ERROR),
2455 non_tmp_error = (drop_temporary ? non_tmp_error : TRUE);
2462 if (frm_db_type == DB_TYPE_UNKNOWN)
2464 dd_frm_type(thd, path, &frm_db_type);
2465 DBUG_PRINT(
"info", (
"frm_db_type %d from %s", frm_db_type, path));
2467 table_type= ha_resolve_by_legacy_type(thd, frm_db_type);
2469 *(end= path + path_length - reg_ext_length)=
'\0';
2470 DBUG_PRINT(
"info", (
"deleting table of type %d",
2471 (table_type ? table_type->db_type : 0)));
2476 if ((error == ENOENT || error == HA_ERR_NO_SUCH_TABLE) &&
2477 (if_exists || table_type == NULL))
2482 if (error == HA_ERR_ROW_IS_REFERENCED)
2485 foreign_key_error= 1;
2487 if (!error || error == ENOENT || error == HA_ERR_NO_SUCH_TABLE)
2491 strmov(end,reg_ext);
2494 non_tmp_table_deleted= TRUE;
2500 non_tmp_error= error ? TRUE : non_tmp_error;
2504 if (error == HA_ERR_TOO_MANY_CONCURRENT_TRXS)
2506 my_error(HA_ERR_TOO_MANY_CONCURRENT_TRXS, MYF(0));
2507 wrong_tables.free();
2512 if (wrong_tables.length())
2513 wrong_tables.append(
',');
2515 wrong_tables.append(
String(db,system_charset_info));
2516 wrong_tables.append(
'.');
2517 wrong_tables.append(
String(table->table_name,system_charset_info));
2519 DBUG_PRINT(
"table", (
"table: 0x%lx s: 0x%lx", (
long) table->table,
2520 table->table ? (
long) table->table->s : (
long) -1));
2522 DBUG_EXECUTE_IF(
"bug43138",
2523 my_printf_error(ER_BAD_TABLE_ERROR,
2524 ER(ER_BAD_TABLE_ERROR), MYF(0),
2525 table->table_name););
2526 #ifdef HAVE_PSI_TABLE_INTERFACE
2527 if (drop_temporary && likely(error == 0))
2529 (
true, table->db, table->db_length, table->table_name, table->table_name_length);
2532 DEBUG_SYNC(thd,
"rm_table_no_locks_before_binlog");
2533 thd->thread_specific_used|= (trans_tmp_table_deleted ||
2534 non_trans_tmp_table_deleted);
2537 if (wrong_tables.length())
2539 if (!foreign_key_error)
2540 my_printf_error(ER_BAD_TABLE_ERROR, ER(ER_BAD_TABLE_ERROR), MYF(0),
2541 wrong_tables.c_ptr());
2543 my_message(ER_ROW_IS_REFERENCED, ER(ER_ROW_IS_REFERENCED), MYF(0));
2547 if (non_trans_tmp_table_deleted ||
2548 trans_tmp_table_deleted || non_tmp_table_deleted)
2550 query_cache_invalidate3(thd, tables, 0);
2552 if (non_trans_tmp_table_deleted ||
2553 trans_tmp_table_deleted)
2554 thd->transaction.stmt.mark_dropped_temp_table();
2556 if (!dont_log_query && mysql_bin_log.is_open())
2558 if (non_trans_tmp_table_deleted)
2561 built_non_trans_tmp_query.chop();
2562 built_non_trans_tmp_query.append(
" /* generated by server */");
2563 error |= thd->binlog_query(THD::STMT_QUERY_TYPE,
2564 built_non_trans_tmp_query.ptr(),
2565 built_non_trans_tmp_query.length(),
2567 is_drop_tmp_if_exists_added,
2578 if (gtid_mode > 0 && (trans_tmp_table_deleted || non_tmp_table_deleted))
2579 error |= mysql_bin_log.
commit(thd,
true);
2581 if (trans_tmp_table_deleted)
2584 built_trans_tmp_query.chop();
2585 built_trans_tmp_query.append(
" /* generated by server */");
2586 error |= thd->binlog_query(THD::STMT_QUERY_TYPE,
2587 built_trans_tmp_query.ptr(),
2588 built_trans_tmp_query.length(),
2590 is_drop_tmp_if_exists_added,
2600 if (gtid_mode > 0 && non_tmp_table_deleted)
2601 error |= mysql_bin_log.
commit(thd,
true);
2603 if (non_tmp_table_deleted)
2607 built_query.append(
" /* generated by server */");
2608 int error_code = (non_tmp_error ?
2609 (foreign_key_error ? ER_ROW_IS_REFERENCED : ER_BAD_TABLE_ERROR) : 0);
2610 error |= thd->binlog_query(THD::STMT_QUERY_TYPE,
2612 built_query.length(),
2619 if (!drop_temporary)
2629 if (thd->locked_tables_mode)
2631 if (thd->lock && thd->lock->table_count == 0 && non_temp_tables_count > 0)
2633 thd->locked_tables_list.unlock_locked_tables(thd);
2636 for (table= tables;
table; table= table->next_local)
2639 if (table->table == NULL && table->mdl_request.
ticket)
2646 thd->mdl_context.release_all_locks_for_name(table->mdl_request.
ticket);
2674 bool quick_rm_table(THD *thd,
handlerton *base,
const char *db,
2675 const char *table_name, uint flags)
2677 char path[FN_REFLEN + 1];
2679 DBUG_ENTER(
"quick_rm_table");
2681 uint path_length= build_table_filename(path,
sizeof(path) - 1,
2682 db, table_name, reg_ext, flags);
2685 path[path_length - reg_ext_length]=
'\0';
2686 if (flags & NO_HA_TABLE)
2694 if (!(flags & (FRM_ONLY|NO_HA_TABLE)))
2712 static int sort_keys(
KEY *a,
KEY *b)
2716 if (a_flags & HA_NOSAME)
2718 if (!(b_flags & HA_NOSAME))
2720 if ((a_flags ^ b_flags) & HA_NULL_PART_KEY)
2723 return (a_flags & HA_NULL_PART_KEY) ? 1 : -1;
2725 if (a->
name == primary_key_name)
2727 if (b->
name == primary_key_name)
2730 if ((a_flags ^ b_flags) & HA_KEY_HAS_PART_KEY_SEG)
2731 return (a_flags & HA_KEY_HAS_PART_KEY_SEG) ? 1 : -1;
2733 else if (b_flags & HA_NOSAME)
2736 if ((a_flags ^ b_flags) & HA_FULLTEXT)
2738 return (a_flags & HA_FULLTEXT) ? 1 : -1;
2768 bool check_duplicates_in_interval(
const char *set_or_name,
2769 const char *name,
TYPELIB *typelib,
2773 const char **cur_value= typelib->type_names;
2774 unsigned int *cur_length= typelib->type_lengths;
2777 for ( ; tmp.count > 1; cur_value++, cur_length++)
2782 if (find_type2(&tmp, (
const char*)*cur_value, *cur_length, cs))
2784 THD *thd= current_thd;
2786 if (current_thd->is_strict_mode())
2788 my_error(ER_DUPLICATED_VALUE_IN_TYPE, MYF(0),
2789 name, err.ptr(), set_or_name);
2792 push_warning_printf(thd,Sql_condition::WARN_LEVEL_NOTE,
2793 ER_DUPLICATED_VALUE_IN_TYPE,
2794 ER(ER_DUPLICATED_VALUE_IN_TYPE),
2795 name, err.ptr(), set_or_name);
2821 static void calculate_interval_lengths(
const CHARSET_INFO *cs,
2828 *max_length= *tot_length= 0;
2829 for (pos= interval->type_names, len= interval->type_lengths;
2830 *pos ; pos++, len++)
2832 size_t length= cs->cset->numchars(cs, *pos, *pos + *len);
2833 *tot_length+= length;
2834 set_if_bigger(*max_length, (uint32)length);
2859 longlong table_flags)
2861 unsigned int dup_val_count;
2862 DBUG_ENTER(
"prepare_field");
2868 DBUG_ASSERT(sql_field->charset);
2870 switch (sql_field->sql_type) {
2871 case MYSQL_TYPE_BLOB:
2872 case MYSQL_TYPE_MEDIUM_BLOB:
2873 case MYSQL_TYPE_TINY_BLOB:
2874 case MYSQL_TYPE_LONG_BLOB:
2875 sql_field->pack_flag=FIELDFLAG_BLOB |
2876 pack_length_to_packflag(sql_field->pack_length -
2877 portable_sizeof_char_ptr);
2878 if (sql_field->charset->state & MY_CS_BINSORT)
2879 sql_field->pack_flag|=FIELDFLAG_BINARY;
2880 sql_field->length=8;
2881 sql_field->unireg_check=Field::BLOB_FIELD;
2884 case MYSQL_TYPE_GEOMETRY:
2886 if (!(table_flags & HA_CAN_GEOMETRY))
2888 my_printf_error(ER_CHECK_NOT_IMPLEMENTED, ER(ER_CHECK_NOT_IMPLEMENTED),
2889 MYF(0),
"GEOMETRY");
2892 sql_field->pack_flag=FIELDFLAG_GEOM |
2893 pack_length_to_packflag(sql_field->pack_length -
2894 portable_sizeof_char_ptr);
2895 if (sql_field->charset->state & MY_CS_BINSORT)
2896 sql_field->pack_flag|=FIELDFLAG_BINARY;
2897 sql_field->length=8;
2898 sql_field->unireg_check=Field::BLOB_FIELD;
2902 my_printf_error(ER_FEATURE_DISABLED,ER(ER_FEATURE_DISABLED), MYF(0),
2903 sym_group_geom.name, sym_group_geom.needed_define);
2906 case MYSQL_TYPE_VARCHAR:
2907 #ifndef QQ_ALL_HANDLERS_SUPPORT_VARCHAR
2908 if (table_flags & HA_NO_VARCHAR)
2911 sql_field->sql_type= MYSQL_TYPE_VAR_STRING;
2912 sql_field->pack_length= calc_pack_length(sql_field->sql_type,
2913 (uint) sql_field->length);
2914 if ((sql_field->length / sql_field->charset->mbmaxlen) >
2915 MAX_FIELD_CHARLENGTH)
2917 my_printf_error(ER_TOO_BIG_FIELDLENGTH, ER(ER_TOO_BIG_FIELDLENGTH),
2918 MYF(0), sql_field->field_name,
2919 static_cast<ulong>(MAX_FIELD_CHARLENGTH));
2925 case MYSQL_TYPE_STRING:
2926 sql_field->pack_flag=0;
2927 if (sql_field->charset->state & MY_CS_BINSORT)
2928 sql_field->pack_flag|=FIELDFLAG_BINARY;
2930 case MYSQL_TYPE_ENUM:
2931 sql_field->pack_flag=pack_length_to_packflag(sql_field->pack_length) |
2933 if (sql_field->charset->state & MY_CS_BINSORT)
2934 sql_field->pack_flag|=FIELDFLAG_BINARY;
2935 sql_field->unireg_check=Field::INTERVAL_FIELD;
2936 if (check_duplicates_in_interval(
"ENUM",sql_field->field_name,
2937 sql_field->interval,
2938 sql_field->charset, &dup_val_count))
2941 case MYSQL_TYPE_SET:
2942 sql_field->pack_flag=pack_length_to_packflag(sql_field->pack_length) |
2944 if (sql_field->charset->state & MY_CS_BINSORT)
2945 sql_field->pack_flag|=FIELDFLAG_BINARY;
2946 sql_field->unireg_check=Field::BIT_FIELD;
2947 if (check_duplicates_in_interval(
"SET",sql_field->field_name,
2948 sql_field->interval,
2949 sql_field->charset, &dup_val_count))
2952 if (sql_field->interval->count - dup_val_count >
sizeof(longlong)*8)
2954 my_error(ER_TOO_BIG_SET, MYF(0), sql_field->field_name);
2958 case MYSQL_TYPE_DATE:
2959 case MYSQL_TYPE_NEWDATE:
2960 case MYSQL_TYPE_TIME:
2961 case MYSQL_TYPE_DATETIME:
2962 case MYSQL_TYPE_TIME2:
2963 case MYSQL_TYPE_DATETIME2:
2964 case MYSQL_TYPE_NULL:
2965 sql_field->pack_flag=f_settype((uint) sql_field->sql_type);
2967 case MYSQL_TYPE_BIT:
2973 case MYSQL_TYPE_NEWDECIMAL:
2974 sql_field->pack_flag=(FIELDFLAG_NUMBER |
2975 (sql_field->flags & UNSIGNED_FLAG ? 0 :
2976 FIELDFLAG_DECIMAL) |
2977 (sql_field->flags & ZEROFILL_FLAG ?
2978 FIELDFLAG_ZEROFILL : 0) |
2979 (sql_field->decimals << FIELDFLAG_DEC_SHIFT));
2981 case MYSQL_TYPE_TIMESTAMP:
2982 case MYSQL_TYPE_TIMESTAMP2:
2985 sql_field->pack_flag=(FIELDFLAG_NUMBER |
2986 (sql_field->flags & UNSIGNED_FLAG ? 0 :
2987 FIELDFLAG_DECIMAL) |
2988 (sql_field->flags & ZEROFILL_FLAG ?
2989 FIELDFLAG_ZEROFILL : 0) |
2990 f_settype((uint) sql_field->sql_type) |
2991 (sql_field->decimals << FIELDFLAG_DEC_SHIFT));
2994 if (!(sql_field->flags & NOT_NULL_FLAG))
2995 sql_field->pack_flag|= FIELDFLAG_MAYBE_NULL;
2996 if (sql_field->flags & NO_DEFAULT_VALUE_FLAG)
2997 sql_field->pack_flag|= FIELDFLAG_NO_DEFAULT;
3012 result->count= src->elements;
3014 if (!(result->type_names=(
const char **)
3015 alloc_root(mem_root,(
sizeof(
char *)+
sizeof(
int))*(result->count+1))))
3017 result->type_lengths= (uint*)(result->type_names + result->count+1);
3020 for (uint i=0; i < result->count; i++)
3026 if (String::needs_conversion(tmp->length(), tmp->charset(),
3030 conv.copy(tmp->ptr(), tmp->length(), tmp->charset(), cs, &cnv_errs);
3032 length= conv.length();
3033 result->type_names[
i]= (
char*) strmake_root(mem_root, conv.ptr(),
3038 length= tmp->length();
3039 result->type_names[
i]= strmake_root(mem_root, tmp->ptr(), length);
3043 length= cs->cset->lengthsp(cs, result->type_names[i], length);
3044 result->type_lengths[
i]= length;
3045 ((uchar *)result->type_names[i])[length]=
'\0';
3047 result->type_names[result->count]= 0;
3048 result->type_lengths[result->count]= 0;
3066 bool fill_field_definition(THD *thd,
3068 enum enum_field_types field_type,
3075 if (field_def->
init(thd, (
char*)
"", field_type, lex->length, lex->dec,
3076 lex->type, (
Item*) 0, (
Item*) 0, &cmt, 0,
3077 &lex->interval_list,
3078 lex->charset ? lex->charset :
3079 thd->variables.collation_database,
3080 lex->uint_geom_type))
3085 if (field_def->interval_list.elements)
3089 &field_def->interval_list);
3092 sp_prepare_create_field(thd, field_def);
3094 return prepare_create_field(field_def, &unused1, HA_CAN_GEOMETRY);
3116 cs= create_info->default_table_charset;
3123 if (create_info->table_charset && cs != &my_charset_bin)
3124 cs= create_info->table_charset;
3141 while ((column_definition= it++) != NULL)
3143 if (column_definition->sql_type == MYSQL_TYPE_TIMESTAMP ||
3144 column_definition->sql_type == MYSQL_TYPE_TIMESTAMP2 ||
3145 column_definition->unireg_check == Field::TIMESTAMP_OLD_FIELD)
3147 if ((column_definition->flags & NOT_NULL_FLAG) != 0 &&
3148 column_definition->
def == NULL &&
3149 column_definition->unireg_check == Field::NONE)
3151 DBUG_PRINT(
"info", (
"First TIMESTAMP column '%s' was promoted to "
3152 "DEFAULT CURRENT_TIMESTAMP ON UPDATE "
3153 "CURRENT_TIMESTAMP",
3154 column_definition->field_name
3156 column_definition->unireg_check= Field::TIMESTAMP_DNUN_FIELD;
3172 static void check_duplicate_key(THD *thd,
3191 while ((k= key_list_iterator++))
3203 if (alter_info->flags & Alter_info::ALTER_DROP_COLUMN)
3210 (key->type != k->type) ||
3211 (key->key_create_info.algorithm != k->key_create_info.algorithm) ||
3212 (key->columns.elements != k->columns.elements))
3225 bool all_columns_are_identical=
true;
3227 key_column_iterator.rewind();
3229 for (uint i= 0; i < key->columns.elements; ++
i)
3234 DBUG_ASSERT(c1 && c2);
3236 if (my_strcasecmp(system_charset_info,
3237 c1->field_name.str, c2->field_name.str) ||
3238 (c1->length != c2->length))
3240 all_columns_are_identical=
false;
3247 if (all_columns_are_identical)
3249 push_warning_printf(thd, Sql_condition::WARN_LEVEL_NOTE,
3250 ER_DUP_INDEX, ER(ER_DUP_INDEX),
3252 thd->lex->query_tables->db,
3253 thd->lex->query_tables->table_name);
3287 mysql_prepare_create_table(THD *thd,
HA_CREATE_INFO *create_info,
3292 uint *key_count,
int select_field_count)
3294 const char *key_name;
3296 uint field,null_fields,blob_columns,max_key_length;
3297 ulong record_offset= 0;
3300 int field_no,dup_no;
3301 int select_field_pos,auto_increment=0;
3304 uint total_uneven_bit_length= 0;
3305 DBUG_ENTER(
"mysql_prepare_create_table");
3307 select_field_pos= alter_info->create_list.elements - select_field_count;
3308 null_fields=blob_columns=0;
3309 create_info->varchar= 0;
3310 max_key_length= file->max_key_length();
3312 for (field_no=0; (sql_field=it++) ; field_no++)
3321 sql_field->length= sql_field->char_length;
3323 save_cs= sql_field->charset= get_sql_field_charset(sql_field,
3325 if ((sql_field->flags & BINCMP_FLAG) &&
3326 !(sql_field->charset= get_charset_by_csname(sql_field->charset->csname,
3327 MY_CS_BINSORT,MYF(0))))
3330 strmake(strmake(tmp, save_cs->csname,
sizeof(tmp)-4),
3331 STRING_WITH_LEN(
"_bin"));
3332 my_error(ER_UNKNOWN_COLLATION, MYF(0), tmp);
3340 if (sql_field->
def &&
3341 save_cs != sql_field->
def->collation.collation &&
3342 (sql_field->sql_type == MYSQL_TYPE_VAR_STRING ||
3343 sql_field->sql_type == MYSQL_TYPE_STRING ||
3344 sql_field->sql_type == MYSQL_TYPE_SET ||
3345 sql_field->sql_type == MYSQL_TYPE_ENUM))
3357 sql_field->
def= sql_field->
def->safe_charset_converter(save_cs);
3359 if (sql_field->
def == NULL)
3362 my_error(ER_INVALID_DEFAULT, MYF(0), sql_field->field_name);
3367 if (sql_field->sql_type == MYSQL_TYPE_SET ||
3368 sql_field->sql_type == MYSQL_TYPE_ENUM)
3372 TYPELIB *interval= sql_field->interval;
3386 interval= sql_field->interval= typelib(thd->mem_root,
3387 sql_field->interval_list);
3391 int comma_length= cs->cset->wc_mb(cs,
',', (uchar*) comma_buf,
3392 (uchar*) comma_buf +
3394 DBUG_ASSERT(comma_length > 0);
3395 for (uint i= 0; (tmp= int_it++); i++)
3398 if (String::needs_conversion(tmp->length(), tmp->charset(),
3402 conv.copy(tmp->ptr(), tmp->length(), tmp->charset(), cs, &cnv_errs);
3403 interval->type_names[
i]= strmake_root(thd->mem_root, conv.ptr(),
3405 interval->type_lengths[
i]= conv.length();
3409 lengthsp= cs->cset->lengthsp(cs, interval->type_names[i],
3410 interval->type_lengths[i]);
3411 interval->type_lengths[
i]= lengthsp;
3412 ((uchar *)interval->type_names[i])[lengthsp]=
'\0';
3413 if (sql_field->sql_type == MYSQL_TYPE_SET)
3415 if (cs->coll->instr(cs, interval->type_names[i],
3416 interval->type_lengths[i],
3417 comma_buf, comma_length, NULL, 0))
3420 my_error(ER_ILLEGAL_VALUE_FOR_TYPE, MYF(0),
"set", err.ptr());
3425 sql_field->interval_list.empty();
3428 if (sql_field->sql_type == MYSQL_TYPE_SET)
3430 uint32 field_length;
3431 if (sql_field->
def != NULL)
3436 String str, *def= sql_field->
def->val_str(&str);
3439 if ((sql_field->flags & NOT_NULL_FLAG) != 0)
3441 my_error(ER_INVALID_DEFAULT, MYF(0), sql_field->field_name);
3446 (void) find_set(interval, NULL, 0,
3447 cs, ¬_used, ¬_used2, ¬_found);
3451 (void) find_set(interval, def->ptr(), def->length(),
3452 cs, ¬_used, ¬_used2, ¬_found);
3457 my_error(ER_INVALID_DEFAULT, MYF(0), sql_field->field_name);
3461 calculate_interval_lengths(cs, interval, &dummy, &field_length);
3462 sql_field->length= field_length + (interval->count - 1);
3466 uint32 field_length;
3467 DBUG_ASSERT(sql_field->sql_type == MYSQL_TYPE_ENUM);
3468 if (sql_field->
def != NULL)
3470 String str, *def= sql_field->
def->val_str(&str);
3473 if ((sql_field->flags & NOT_NULL_FLAG) != 0)
3475 my_error(ER_INVALID_DEFAULT, MYF(0), sql_field->field_name);
3483 def->length(cs->cset->lengthsp(cs, def->ptr(), def->length()));
3484 if (find_type2(interval, def->ptr(), def->length(), cs) == 0)
3486 my_error(ER_INVALID_DEFAULT, MYF(0), sql_field->field_name);
3491 calculate_interval_lengths(cs, interval, &field_length, &dummy);
3492 sql_field->length= field_length;
3494 set_if_smaller(sql_field->length, MAX_FIELD_WIDTH-1);
3497 if (sql_field->sql_type == MYSQL_TYPE_BIT)
3499 sql_field->pack_flag= FIELDFLAG_NUMBER;
3501 total_uneven_bit_length+= sql_field->length & 7;
3503 sql_field->pack_flag|= FIELDFLAG_TREAT_BIT_AS_CHAR;
3507 if (prepare_blob_field(thd, sql_field))
3510 if (!(sql_field->flags & NOT_NULL_FLAG))
3513 if (check_column_name(sql_field->field_name))
3515 my_error(ER_WRONG_COLUMN_NAME, MYF(0), sql_field->field_name);
3520 for (dup_no=0; (dup_field=it2++) != sql_field; dup_no++)
3522 if (my_strcasecmp(system_charset_info,
3523 sql_field->field_name,
3524 dup_field->field_name) == 0)
3530 if (field_no < select_field_pos || dup_no >= select_field_pos)
3532 my_error(ER_DUP_FIELDNAME, MYF(0), sql_field->field_name);
3538 sql_field->
def= dup_field->
def;
3539 sql_field->sql_type= dup_field->sql_type;
3540 sql_field->charset= (dup_field->charset ?
3541 dup_field->charset :
3542 create_info->default_table_charset);
3543 sql_field->length= dup_field->char_length;
3544 sql_field->pack_length= dup_field->pack_length;
3545 sql_field->key_length= dup_field->key_length;
3546 sql_field->decimals= dup_field->decimals;
3548 sql_field->unireg_check= dup_field->unireg_check;
3554 if (!(sql_field->flags & NOT_NULL_FLAG))
3556 sql_field->flags= dup_field->flags;
3557 sql_field->interval= dup_field->interval;
3565 if ((sql_field->flags & BLOB_FLAG) ||
3566 (sql_field->sql_type == MYSQL_TYPE_VARCHAR &&
3567 create_info->
row_type != ROW_TYPE_FIXED))
3568 (*db_options)|= HA_OPTION_PACK_RECORD;
3574 null_fields+= total_uneven_bit_length;
3577 while ((sql_field=it++))
3579 DBUG_ASSERT(sql_field->charset != 0);
3581 if (prepare_create_field(sql_field, &blob_columns,
3584 if (sql_field->sql_type == MYSQL_TYPE_VARCHAR)
3585 create_info->varchar= TRUE;
3586 sql_field->offset= record_offset;
3587 if (MTYP_TYPENR(sql_field->unireg_check) == Field::NEXT_NUMBER)
3589 record_offset+= sql_field->pack_length;
3591 if (auto_increment > 1)
3593 my_message(ER_WRONG_AUTO_KEY, ER(ER_WRONG_AUTO_KEY), MYF(0));
3596 if (auto_increment &&
3599 my_message(ER_TABLE_CANT_HANDLE_AUTO_INCREMENT,
3600 ER(ER_TABLE_CANT_HANDLE_AUTO_INCREMENT), MYF(0));
3606 my_message(ER_TABLE_CANT_HANDLE_BLOB, ER(ER_TABLE_CANT_HANDLE_BLOB),
3617 if (select_field_count > 0 && auto_increment)
3618 thd->lex->set_stmt_unsafe(LEX::BINLOG_STMT_UNSAFE_CREATE_SELECT_AUTOINC);
3624 uint key_parts=0, fk_key_count=0;
3625 bool primary_key=0,unique_key=0;
3627 uint tmp, key_number;
3629 static char ignore_key[1];
3634 while ((key=key_iterator++))
3636 DBUG_PRINT(
"info", (
"key name: '%s' type: %d", key->name.str ? key->name.str :
3637 "(none)" , key->type));
3638 if (key->type == Key::FOREIGN_KEY)
3642 if (fk_key->ref_columns.elements &&
3643 fk_key->ref_columns.elements != fk_key->columns.elements)
3645 my_error(ER_WRONG_FK_DEF, MYF(0),
3646 (fk_key->name.str ? fk_key->name.str :
3647 "foreign key without name"),
3648 ER(ER_KEY_REF_DO_NOT_MATCH_TABLE_REF));
3654 tmp=file->max_key_parts();
3655 if (key->columns.elements > tmp)
3657 my_error(ER_TOO_MANY_KEY_PARTS,MYF(0),tmp);
3660 if (check_string_char_length(&key->name,
"", NAME_CHAR_LEN,
3661 system_charset_info, 1))
3663 my_error(ER_TOO_LONG_IDENT, MYF(0), key->name.str);
3666 key_iterator2.rewind ();
3667 if (key->type != Key::FOREIGN_KEY)
3669 while ((key2 = key_iterator2++) != key)
3676 if ((key2->type != Key::FOREIGN_KEY &&
3677 key2->name.str != ignore_key &&
3678 !foreign_key_prefix(key, key2)))
3682 if (!key2->generated ||
3683 (key->generated && key->columns.elements <
3684 key2->columns.elements))
3685 key->name.str= ignore_key;
3688 key2->name.str= ignore_key;
3689 key_parts-= key2->columns.elements;
3696 if (key->name.str != ignore_key)
3697 key_parts+=key->columns.elements;
3700 if (key->name.str && !tmp_table && (key->type != Key::PRIMARY) &&
3701 !my_strcasecmp(system_charset_info, key->name.str, primary_key_name))
3703 my_error(ER_WRONG_NAME_FOR_INDEX, MYF(0), key->name.str);
3707 tmp=file->max_keys();
3708 if (*key_count > tmp)
3710 my_error(ER_TOO_MANY_KEYS,MYF(0),tmp);
3714 (*key_info_buffer)= key_info= (
KEY*) sql_calloc(
sizeof(
KEY) * (*key_count));
3716 if (!*key_info_buffer || ! key_part_info)
3719 key_iterator.rewind();
3721 for (; (key=key_iterator++) ; key_number++)
3726 if (key->name.str == ignore_key)
3731 while (key && key->name.str == ignore_key);
3736 switch (key->type) {
3741 key_info->
flags= HA_FULLTEXT;
3742 if ((key_info->
parser_name= &key->key_create_info.parser_name)->str)
3743 key_info->
flags|= HA_USES_PARSER;
3749 key_info->
flags= HA_SPATIAL;
3752 my_error(ER_FEATURE_DISABLED, MYF(0),
3753 sym_group_geom.name, sym_group_geom.needed_define);
3756 case Key::FOREIGN_KEY:
3760 key_info->
flags = HA_NOSAME;
3764 key_info->
flags|= HA_GENERATED_KEY;
3768 key_info->key_part=key_part_info;
3770 key_info->algorithm= key->key_create_info.algorithm;
3772 if (key->type == Key::FULLTEXT)
3776 #ifdef WITH_PARTITION_STORAGE_ENGINE
3777 if (file->ht == partition_hton)
3779 my_message(ER_FULLTEXT_NOT_SUPPORTED_WITH_PARTITIONING,
3780 ER(ER_FULLTEXT_NOT_SUPPORTED_WITH_PARTITIONING),
3785 my_message(ER_TABLE_CANT_HANDLE_FT, ER(ER_TABLE_CANT_HANDLE_FT),
3799 if (key_info->
flags & HA_SPATIAL)
3803 my_message(ER_TABLE_CANT_HANDLE_SPKEYS, ER(ER_TABLE_CANT_HANDLE_SPKEYS),
3809 my_error(ER_WRONG_ARGUMENTS, MYF(0),
"SPATIAL INDEX");
3813 else if (key_info->algorithm == HA_KEY_ALG_RTREE)
3815 #ifdef HAVE_RTREE_KEYS
3818 my_error(ER_WRONG_ARGUMENTS, MYF(0),
"RTREE INDEX");
3822 my_error(ER_NOT_SUPPORTED_YET, MYF(0),
"RTREE INDEX");
3825 my_error(ER_FEATURE_DISABLED, MYF(0),
3826 sym_group_rtree.name, sym_group_rtree.needed_define);
3836 key_info->block_size= (key->key_create_info.block_size ?
3837 key->key_create_info.block_size :
3838 create_info->key_block_size);
3840 if (key_info->block_size)
3841 key_info->
flags|= HA_USES_BLOCK_SIZE;
3845 for (uint column_nr=0 ; (column=cols++) ; column_nr++)
3851 while ((sql_field=it++) &&
3852 my_strcasecmp(system_charset_info,
3853 column->field_name.str,
3854 sql_field->field_name))
3858 my_error(ER_KEY_COLUMN_DOES_NOT_EXITS, MYF(0), column->field_name.str);
3861 while ((dup_column= cols2++) != column)
3863 if (!my_strcasecmp(system_charset_info,
3864 column->field_name.str, dup_column->field_name.str))
3866 my_printf_error(ER_DUP_FIELDNAME,
3867 ER(ER_DUP_FIELDNAME),MYF(0),
3868 column->field_name.str);
3873 if (key->type == Key::FULLTEXT)
3875 if ((sql_field->sql_type != MYSQL_TYPE_STRING &&
3876 sql_field->sql_type != MYSQL_TYPE_VARCHAR &&
3877 !f_is_blob(sql_field->pack_flag)) ||
3878 sql_field->charset == &my_charset_bin ||
3879 sql_field->charset->mbminlen > 1 ||
3880 (ft_key_charset && sql_field->charset != ft_key_charset))
3882 my_error(ER_BAD_FT_COLUMN, MYF(0), column->field_name.str);
3885 ft_key_charset=sql_field->charset;
3893 column->length=
test(f_is_blob(sql_field->pack_flag));
3897 column->length*= sql_field->charset->mbmaxlen;
3899 if (key->type == Key::SPATIAL)
3903 my_error(ER_WRONG_SUB_KEY, MYF(0));
3906 if (!f_is_geom(sql_field->pack_flag))
3908 my_error(ER_SPATIAL_MUST_HAVE_GEOM_COL, MYF(0));
3913 if (f_is_blob(sql_field->pack_flag) ||
3914 (f_is_geom(sql_field->pack_flag) && key->type != Key::SPATIAL))
3918 my_error(ER_BLOB_USED_AS_KEY, MYF(0), column->field_name.str);
3921 if (f_is_geom(sql_field->pack_flag) && sql_field->geom_type ==
3924 if (!column->length)
3926 my_error(ER_BLOB_KEY_WITHOUT_LENGTH, MYF(0), column->field_name.str);
3931 if (key->type == Key::SPATIAL)
3933 if (!column->length)
3939 column->length= 4*
sizeof(double);
3943 if (!(sql_field->flags & NOT_NULL_FLAG))
3945 if (key->type == Key::PRIMARY)
3948 sql_field->flags|= NOT_NULL_FLAG;
3949 sql_field->pack_flag&= ~FIELDFLAG_MAYBE_NULL;
3954 key_info->
flags|= HA_NULL_PART_KEY;
3957 my_error(ER_NULL_COLUMN_IN_INDEX, MYF(0), column->field_name.str);
3960 if (key->type == Key::SPATIAL)
3962 my_message(ER_SPATIAL_CANT_HAVE_NULL,
3963 ER(ER_SPATIAL_CANT_HAVE_NULL), MYF(0));
3968 if (MTYP_TYPENR(sql_field->unireg_check) == Field::NEXT_NUMBER)
3970 if (column_nr == 0 || (file->
ha_table_flags() & HA_AUTO_PART_KEY))
3975 key_part_info->fieldnr= field;
3976 key_part_info->offset= (uint16) sql_field->offset;
3977 key_part_info->key_type=sql_field->pack_flag;
3978 uint key_part_length= sql_field->key_length;
3982 if (f_is_blob(sql_field->pack_flag))
3984 key_part_length= column->length;
3991 uint max_field_size= sql_field->key_length * sql_field->charset->mbmaxlen;
3992 if ((max_field_size && key_part_length > max_field_size) ||
3993 key_part_length > max_key_length ||
3994 key_part_length > file->max_key_part_length())
3997 key_part_length= min(max_key_length, file->max_key_part_length());
3999 key_part_length= min(key_part_length, max_field_size);
4000 if (key->type == Key::MULTIPLE)
4003 push_warning_printf(thd, Sql_condition::WARN_LEVEL_WARN,
4004 ER_TOO_LONG_KEY, ER(ER_TOO_LONG_KEY),
4007 key_part_length-= key_part_length % sql_field->charset->mbmaxlen;
4012 if (thd->is_error())
4017 my_error(ER_TOO_LONG_KEY, MYF(0), key_part_length);
4023 else if (!f_is_geom(sql_field->pack_flag) &&
4025 column->length != key_part_length &&
4027 (column->length > key_part_length ||
4031 f_is_packed(sql_field->pack_flag) ||
4035 (key_info->
flags & HA_NOSAME))))
4037 my_message(ER_WRONG_SUB_KEY, ER(ER_WRONG_SUB_KEY), MYF(0));
4041 key_part_length= column->length;
4043 else if (key_part_length == 0)
4045 my_error(ER_WRONG_KEY_COLUMN, MYF(0), column->field_name.str);
4048 if (key_part_length > file->max_key_part_length() &&
4049 key->type != Key::FULLTEXT)
4051 key_part_length= file->max_key_part_length();
4052 if (key->type == Key::MULTIPLE)
4055 push_warning_printf(thd, Sql_condition::WARN_LEVEL_WARN,
4056 ER_TOO_LONG_KEY, ER(ER_TOO_LONG_KEY),
4059 key_part_length-= key_part_length % sql_field->charset->mbmaxlen;
4064 if (thd->is_error())
4069 my_error(ER_TOO_LONG_KEY, MYF(0), key_part_length);
4073 key_part_info->length= (uint16) key_part_length;
4075 if (!((*db_options) & HA_OPTION_NO_PACK_KEYS) &&
4076 !((create_info->table_options & HA_OPTION_NO_PACK_KEYS)) &&
4078 (sql_field->sql_type == MYSQL_TYPE_STRING ||
4079 sql_field->sql_type == MYSQL_TYPE_VARCHAR ||
4080 sql_field->pack_flag & FIELDFLAG_BLOB)))
4082 if ((column_nr == 0 && (sql_field->pack_flag & FIELDFLAG_BLOB)) ||
4083 sql_field->sql_type == MYSQL_TYPE_VARCHAR)
4084 key_info->
flags|= HA_BINARY_PACK_KEY | HA_VAR_LENGTH_KEY;
4086 key_info->
flags|= HA_PACK_KEY;
4089 if (key_part_length != sql_field->key_length)
4090 key_info->
flags|= HA_KEY_HAS_PART_KEY_SEG;
4092 key_length+= key_part_length;
4098 if (key->type == Key::PRIMARY)
4102 my_message(ER_MULTIPLE_PRI_KEY, ER(ER_MULTIPLE_PRI_KEY),
4106 key_name=primary_key_name;
4109 else if (!(key_name= key->name.str))
4110 key_name=make_unique_key_name(sql_field->field_name,
4111 *key_info_buffer, key_info);
4112 if (check_if_keyname_exists(key_name, *key_info_buffer, key_info))
4114 my_error(ER_DUP_KEYNAME, MYF(0), key_name);
4117 key_info->
name=(
char*) key_name;
4121 if (!key_info->
name || check_column_name(key_info->
name))
4123 my_error(ER_WRONG_NAME_FOR_INDEX, MYF(0), key_info->
name);
4126 if (!(key_info->
flags & HA_NULL_PART_KEY))
4129 if (key_length > max_key_length && key->type != Key::FULLTEXT)
4131 my_error(ER_TOO_LONG_KEY,MYF(0),max_key_length);
4134 if (validate_comment_length(thd, key->key_create_info.comment.str,
4135 &key->key_create_info.comment.length,
4136 INDEX_COMMENT_MAXLEN,
4137 ER_TOO_LONG_INDEX_COMMENT,
4140 key_info->comment.length= key->key_create_info.comment.length;
4141 if (key_info->comment.length > 0)
4143 key_info->
flags|= HA_USES_COMMENT;
4144 key_info->comment.str= key->key_create_info.comment.str;
4148 check_duplicate_key(thd, key, key_info, alter_info);
4153 if (!unique_key && !primary_key &&
4156 my_message(ER_REQUIRES_PRIMARY_KEY, ER(ER_REQUIRES_PRIMARY_KEY), MYF(0));
4159 if (auto_increment > 0)
4161 my_message(ER_WRONG_AUTO_KEY, ER(ER_WRONG_AUTO_KEY), MYF(0));
4165 my_qsort((uchar*) *key_info_buffer, *key_count,
sizeof(
KEY),
4166 (qsort_cmp) sort_keys);
4167 create_info->null_bits= null_fields;
4171 while ((sql_field=it++))
4173 Field::utype
type= (Field::utype) MTYP_TYPENR(sql_field->unireg_check);
4175 if (thd->variables.sql_mode & MODE_NO_ZERO_DATE &&
4177 is_timestamp_type(sql_field->sql_type) &&
4178 (sql_field->flags & NOT_NULL_FLAG) &&
4179 (type == Field::NONE || type == Field::TIMESTAMP_UN_FIELD))
4195 my_error(ER_INVALID_DEFAULT, MYF(0), sql_field->field_name);
4222 bool validate_comment_length(THD *thd,
const char *comment_str,
4223 size_t *comment_len, uint max_len,
4224 uint err_code,
const char *comment_name)
4227 DBUG_ENTER(
"validate_comment_length");
4228 uint tmp_len= system_charset_info->cset->charpos(system_charset_info,
4233 if (tmp_len < *comment_len)
4235 if (thd->is_strict_mode())
4237 my_error(err_code, MYF(0),
4238 comment_name, static_cast<ulong>(max_len));
4241 char warn_buff[MYSQL_ERRMSG_SIZE];
4242 length= my_snprintf(warn_buff,
sizeof(warn_buff), ER(err_code),
4243 comment_name, static_cast<ulong>(max_len));
4245 if (!thd->get_stmt_da()->has_sql_condition(warn_buff, length))
4246 push_warning(thd, Sql_condition::WARN_LEVEL_WARN,
4247 err_code, warn_buff);
4248 *comment_len= tmp_len;
4267 static void set_table_default_charset(THD *thd,
4275 if (!create_info->default_table_charset)
4279 load_db_opt_by_name(thd, db, &db_info);
4281 create_info->default_table_charset= db_info.default_table_charset;
4299 static bool prepare_blob_field(THD *thd,
Create_field *sql_field)
4301 DBUG_ENTER(
"prepare_blob_field");
4303 if (sql_field->length > MAX_FIELD_VARCHARLENGTH &&
4304 !(sql_field->flags & BLOB_FLAG))
4307 char warn_buff[MYSQL_ERRMSG_SIZE];
4309 if (sql_field->
def || thd->is_strict_mode())
4311 my_error(ER_TOO_BIG_FIELDLENGTH, MYF(0), sql_field->field_name,
4312 static_cast<ulong>(MAX_FIELD_VARCHARLENGTH /
4313 sql_field->charset->mbmaxlen));
4316 sql_field->sql_type= MYSQL_TYPE_BLOB;
4317 sql_field->flags|= BLOB_FLAG;
4318 my_snprintf(warn_buff,
sizeof(warn_buff), ER(ER_AUTO_CONVERT), sql_field->field_name,
4319 (sql_field->charset == &my_charset_bin) ?
"VARBINARY" :
"VARCHAR",
4320 (sql_field->charset == &my_charset_bin) ?
"BLOB" :
"TEXT");
4321 push_warning(thd, Sql_condition::WARN_LEVEL_NOTE, ER_AUTO_CONVERT,
4325 if ((sql_field->flags & BLOB_FLAG) && sql_field->length)
4327 if (sql_field->sql_type == FIELD_TYPE_BLOB ||
4328 sql_field->sql_type == FIELD_TYPE_TINY_BLOB ||
4329 sql_field->sql_type == FIELD_TYPE_MEDIUM_BLOB)
4332 sql_field->sql_type= get_blob_type_from_length(sql_field->length);
4333 sql_field->pack_length= calc_pack_length(sql_field->sql_type, 0);
4335 sql_field->length= 0;
4356 static void sp_prepare_create_field(THD *thd,
Create_field *sql_field)
4358 if (sql_field->sql_type == MYSQL_TYPE_SET ||
4359 sql_field->sql_type == MYSQL_TYPE_ENUM)
4361 uint32 field_length, dummy;
4362 if (sql_field->sql_type == MYSQL_TYPE_SET)
4364 calculate_interval_lengths(sql_field->charset,
4365 sql_field->interval, &dummy,
4367 sql_field->length= field_length +
4368 (sql_field->interval->count - 1);
4372 calculate_interval_lengths(sql_field->charset,
4373 sql_field->interval,
4374 &field_length, &dummy);
4375 sql_field->length= field_length;
4377 set_if_smaller(sql_field->length, MAX_FIELD_WIDTH-1);
4380 if (sql_field->sql_type == MYSQL_TYPE_BIT)
4382 sql_field->pack_flag= FIELDFLAG_NUMBER |
4383 FIELDFLAG_TREAT_BIT_AS_CHAR;
4386 DBUG_ASSERT(sql_field->
def == 0);
4388 (void) prepare_blob_field(thd, sql_field);
4428 bool create_table_impl(THD *thd,
4429 const char *db,
const char *table_name,
4433 bool internal_tmp_table,
4434 uint select_field_count,
4444 DBUG_ENTER(
"create_table_impl");
4445 DBUG_PRINT(
"enter", (
"db: '%s' table: '%s' tmp: %d",
4446 db, table_name, internal_tmp_table));
4450 if (!alter_info->create_list.elements)
4452 my_message(ER_TABLE_MUST_HAVE_COLUMNS, ER(ER_TABLE_MUST_HAVE_COLUMNS),
4456 if (check_engine(thd, db, table_name, create_info))
4459 set_table_default_charset(thd, create_info, (
char*) db);
4461 db_options= create_info->table_options;
4462 if (create_info->
row_type == ROW_TYPE_DYNAMIC)
4463 db_options|=HA_OPTION_PACK_RECORD;
4464 alias= table_case_name(create_info, table_name);
4465 if (!(file= get_new_handler((
TABLE_SHARE*) 0, thd->mem_root,
4466 create_info->db_type)))
4468 mem_alloc_error(
sizeof(
handler));
4471 #ifdef WITH_PARTITION_STORAGE_ENGINE
4474 if (!part_info && create_info->db_type->partition_flags &&
4475 (create_info->db_type->partition_flags() & HA_USE_AUTO_PARTITION))
4488 file->set_auto_partitions(part_info);
4489 part_info->default_engine_type= create_info->db_type;
4490 part_info->is_auto_partitioned= TRUE;
4503 handlerton *part_engine_type= create_info->db_type;
4504 char *part_syntax_buf;
4510 while ((part_elem= part_it++))
4512 if (part_elem->part_comment)
4514 size_t comment_len= strlen(part_elem->part_comment);
4515 if (validate_comment_length(thd, part_elem->part_comment,
4517 TABLE_PARTITION_COMMENT_MAXLEN,
4518 ER_TOO_LONG_TABLE_PARTITION_COMMENT,
4519 part_elem->partition_name))
4521 part_elem->part_comment[comment_len]=
'\0';
4523 if (part_elem->subpartitions.elements)
4527 while ((subpart_elem= sub_it++))
4529 if (subpart_elem->part_comment)
4531 size_t comment_len= strlen(subpart_elem->part_comment);
4532 if (validate_comment_length(thd, subpart_elem->part_comment,
4534 TABLE_PARTITION_COMMENT_MAXLEN,
4535 ER_TOO_LONG_TABLE_PARTITION_COMMENT,
4536 subpart_elem->partition_name))
4538 subpart_elem->part_comment[comment_len]=
'\0';
4543 if (create_info->options & HA_LEX_CREATE_TMP_TABLE)
4545 my_error(ER_PARTITION_NO_TEMPORARY, MYF(0));
4548 if ((part_engine_type == partition_hton) &&
4549 part_info->default_engine_type)
4560 if (create_info->used_fields & HA_CREATE_USED_ENGINE)
4562 part_info->default_engine_type= create_info->db_type;
4566 if (part_info->default_engine_type == NULL)
4569 DB_TYPE_DEFAULT, 0, 0);
4573 DBUG_PRINT(
"info", (
"db_type = %s create_info->db_type = %s",
4574 ha_resolve_storage_engine_name(part_info->default_engine_type),
4575 ha_resolve_storage_engine_name(create_info->db_type)));
4576 if (part_info->check_partition_info(thd, &engine_type, file,
4577 create_info, FALSE))
4579 part_info->default_engine_type= engine_type;
4585 if (!(part_syntax_buf= generate_partition_syntax(part_info,
4592 part_info->part_info_string= part_syntax_buf;
4593 part_info->part_info_len= syntax_len;
4594 if ((!(engine_type->partition_flags &&
4595 engine_type->partition_flags() & HA_CAN_PARTITION)) ||
4596 create_info->db_type == partition_hton)
4602 DBUG_PRINT(
"info", (
"db_type: %s",
4603 ha_resolve_storage_engine_name(create_info->db_type)));
4605 create_info->db_type= partition_hton;
4606 if (!(file= get_ha_partition(part_info)))
4616 if (part_info->use_default_num_partitions &&
4617 part_info->num_parts &&
4618 (
int)part_info->num_parts !=
4619 file->get_default_no_partitions(create_info))
4624 DBUG_ASSERT(thd->lex->sql_command != SQLCOM_CREATE_TABLE);
4625 for (i= 1; i < part_info->partitions.elements; i++)
4626 (part_it++)->part_state= PART_TO_BE_DROPPED;
4628 else if (part_info->is_sub_partitioned() &&
4629 part_info->use_default_num_subpartitions &&
4630 part_info->num_subparts &&
4631 (int)part_info->num_subparts !=
4632 file->get_default_no_partitions(create_info))
4634 DBUG_ASSERT(thd->lex->sql_command != SQLCOM_CREATE_TABLE);
4635 part_info->num_subparts= file->get_default_no_partitions(create_info);
4638 else if (create_info->db_type != engine_type)
4647 if (!(file= get_new_handler((
TABLE_SHARE*) 0, thd->mem_root,
4650 mem_alloc_error(
sizeof(
handler));
4661 if (create_info->db_type == partition_hton)
4664 while ((key= key_iterator++))
4666 if (key->type == Key::FOREIGN_KEY)
4668 my_error(ER_FOREIGN_KEY_ON_PARTITIONED, MYF(0));
4676 if (mysql_prepare_create_table(thd, create_info, alter_info,
4679 key_info, key_count,
4680 select_field_count))
4683 if (create_info->options & HA_LEX_CREATE_TMP_TABLE)
4684 create_info->table_options|=HA_CREATE_DELAY_KEY_WRITE;
4687 if ((create_info->options & HA_LEX_CREATE_TMP_TABLE) &&
4690 if (create_info->options & HA_LEX_CREATE_IF_NOT_EXISTS)
4692 push_warning_printf(thd, Sql_condition::WARN_LEVEL_NOTE,
4693 ER_TABLE_EXISTS_ERROR, ER(ER_TABLE_EXISTS_ERROR),
4698 my_error(ER_TABLE_EXISTS_ERROR, MYF(0), alias);
4702 if (!internal_tmp_table && !(create_info->options & HA_LEX_CREATE_TMP_TABLE))
4704 char frm_name[FN_REFLEN+1];
4705 strxnmov(frm_name,
sizeof(frm_name) - 1, path, reg_ext, NullS);
4707 if (!access(frm_name, F_OK))
4709 if (create_info->options & HA_LEX_CREATE_IF_NOT_EXISTS)
4711 my_error(ER_TABLE_EXISTS_ERROR,MYF(0),table_name);
4723 if (get_cached_table_share(db, table_name))
4726 my_error(ER_TABLE_EXISTS_ERROR, MYF(0), table_name);
4741 if (!(create_info->options & HA_LEX_CREATE_TMP_TABLE))
4743 bool create_if_not_exists =
4744 create_info->options & HA_LEX_CREATE_IF_NOT_EXISTS;
4745 int retcode = ha_table_exists_in_engine(thd, db, table_name);
4746 DBUG_PRINT(
"info", (
"exists_in_engine: %u",retcode));
4749 case HA_ERR_NO_SUCH_TABLE:
4752 case HA_ERR_TABLE_EXIST:
4753 DBUG_PRINT(
"info", (
"Table existed in handler"));
4755 if (create_if_not_exists)
4757 my_error(ER_TABLE_EXISTS_ERROR,MYF(0),table_name);
4761 DBUG_PRINT(
"info", (
"error: %u from storage engine", retcode));
4762 my_error(retcode, MYF(0),table_name);
4767 THD_STAGE_INFO(thd, stage_creating_table);
4771 char dirpath[FN_REFLEN];
4788 if (create_info->data_file_name)
4790 dirname_part(dirpath, create_info->data_file_name, &dirlen);
4791 if (test_if_data_home_dir(dirpath))
4793 my_error(ER_WRONG_ARGUMENTS, MYF(0),
"DATA DIRECTORY");
4797 if (create_info->index_file_name)
4799 dirname_part(dirpath, create_info->index_file_name, &dirlen);
4800 if (test_if_data_home_dir(dirpath))
4802 my_error(ER_WRONG_ARGUMENTS, MYF(0),
"INDEX DIRECTORY");
4808 #ifdef WITH_PARTITION_STORAGE_ENGINE
4809 if (check_partition_dirs(thd->lex->part_info))
4815 if (thd->variables.sql_mode & MODE_NO_DIR_IN_CREATE)
4817 if (create_info->data_file_name)
4818 push_warning_printf(thd, Sql_condition::WARN_LEVEL_WARN,
4819 WARN_OPTION_IGNORED, ER(WARN_OPTION_IGNORED),
4821 if (create_info->index_file_name)
4822 push_warning_printf(thd, Sql_condition::WARN_LEVEL_WARN,
4823 WARN_OPTION_IGNORED, ER(WARN_OPTION_IGNORED),
4825 create_info->data_file_name= create_info->index_file_name= 0;
4827 create_info->table_options=db_options;
4833 if (rea_create_table(thd, path, db, table_name,
4834 create_info, alter_info->create_list,
4835 *key_count, *key_info, file, no_ha_table))
4838 if (!no_ha_table && create_info->options & HA_LEX_CREATE_TMP_TABLE)
4853 if (is_trans != NULL)
4854 *is_trans= table->file->has_transactions();
4856 thd->thread_specific_used= TRUE;
4858 #ifdef WITH_PARTITION_STORAGE_ENGINE
4859 else if (part_info && no_ha_table)
4874 init_tmp_table_share(thd, &share, db, 0, table_name, path);
4876 bool result= (open_table_def(thd, &share, 0) ||
4877 open_table_from_share(thd, &share,
"", 0, (uint) READ_ALL,
4880 (void) closefrm(&table, 0);
4882 free_table_share(&share);
4886 char frm_name[FN_REFLEN + 1];
4887 strxnmov(frm_name,
sizeof(frm_name) - 1, path, reg_ext, NullS);
4898 THD_STAGE_INFO(thd, stage_after_create);
4904 push_warning_printf(thd, Sql_condition::WARN_LEVEL_NOTE,
4905 ER_TABLE_EXISTS_ERROR, ER(ER_TABLE_EXISTS_ERROR),
4915 bool mysql_create_table_no_lock(THD *thd,
4916 const char *db,
const char *table_name,
4919 uint select_field_count,
4924 char path[FN_REFLEN + 1];
4926 if (create_info->options & HA_LEX_CREATE_TMP_TABLE)
4927 build_tmptable_filename(thd, path,
sizeof(path));
4932 const char *alias= table_case_name(create_info, table_name);
4933 length= build_table_filename(path,
sizeof(path) - 1, db, alias,
4934 "", 0, &was_truncated);
4936 if (was_truncated || length+reg_ext_length > FN_REFLEN)
4938 my_error(ER_IDENT_CAUSES_TOO_LONG_PATH, MYF(0),
sizeof(path)-1, path);
4943 return create_table_impl(thd, db, table_name, path, create_info, alter_info,
4944 false, select_field_count,
false, is_trans,
4945 ¬_used_1, ¬_used_2);
4964 bool is_trans= FALSE;
4966 DBUG_ENTER(
"mysql_create_table");
4973 if (
open_tables(thd, &thd->lex->query_tables, ¬_used, 0))
4980 DEBUG_SYNC(thd,
"locked_table_name");
4983 thd->abort_on_warning= thd->is_strict_mode();
4989 if (!thd->variables.explicit_defaults_for_timestamp)
4990 promote_first_timestamp_column(&alter_info->create_list);
4992 result= mysql_create_table_no_lock(thd, create_table->db,
4993 create_table->table_name, create_info,
4994 alter_info, 0, &is_trans);
5008 if (create_info->options & HA_LEX_CREATE_TMP_TABLE)
5009 thd->transaction.stmt.mark_created_temp_table();
5011 if (!thd->is_current_stmt_binlog_format_row() ||
5012 (thd->is_current_stmt_binlog_format_row() &&
5013 !(create_info->options & HA_LEX_CREATE_TMP_TABLE)))
5015 thd->add_to_binlog_accessed_dbs(create_table->db);
5016 result= write_bin_log(thd, TRUE, thd->query(), thd->query_length(), is_trans);
5020 thd->abort_on_warning=
false;
5022 DBUG_RETURN(result);
5031 check_if_keyname_exists(
const char *name,
KEY *start,
KEY *end)
5033 for (
KEY *key=start ; key != end ; key++)
5034 if (!my_strcasecmp(system_charset_info,name,key->name))
5041 make_unique_key_name(
const char *field_name,
KEY *start,
KEY *end)
5043 char buff[MAX_FIELD_NAME],*buff_end;
5045 if (!check_if_keyname_exists(field_name,start,end) &&
5046 my_strcasecmp(system_charset_info,field_name,primary_key_name))
5047 return (
char*) field_name;
5048 buff_end=strmake(buff,field_name,
sizeof(buff)-4);
5054 for (uint i=2 ; i< 100; i++)
5057 int10_to_str(i, buff_end+1, 10);
5058 if (!check_if_keyname_exists(buff,start,end))
5059 return sql_strdup(buff);
5061 return (
char*)
"not_specified";
5091 mysql_rename_table(
handlerton *base,
const char *old_db,
5092 const char *old_name,
const char *new_db,
5093 const char *new_name, uint flags)
5095 THD *thd= current_thd;
5096 char from[FN_REFLEN + 1], to[FN_REFLEN + 1],
5097 lc_from[FN_REFLEN + 1], lc_to[FN_REFLEN + 1];
5098 char *from_base= from, *to_base=
to;
5099 char tmp_name[NAME_LEN+1];
5102 ulonglong save_bits= thd->variables.option_bits;
5105 DBUG_ENTER(
"mysql_rename_table");
5106 DBUG_PRINT(
"enter", (
"old: '%s'.'%s' new: '%s'.'%s'",
5107 old_db, old_name, new_db, new_name));
5110 if (flags & NO_FK_CHECKS)
5113 file= (base == NULL ? 0 :
5114 get_new_handler((
TABLE_SHARE*) 0, thd->mem_root, base));
5116 build_table_filename(from,
sizeof(from) - 1, old_db, old_name,
"",
5117 flags & FN_FROM_IS_TMP);
5118 length= build_table_filename(to,
sizeof(to) - 1, new_db, new_name,
"",
5119 flags & FN_TO_IS_TMP, &was_truncated);
5121 if (was_truncated || length+reg_ext_length > FN_REFLEN)
5123 my_error(ER_IDENT_CAUSES_TOO_LONG_PATH, MYF(0),
sizeof(to)-1, to);
5132 if (lower_case_table_names == 2 && file &&
5135 strmov(tmp_name, old_name);
5136 my_casedn_str(files_charset_info, tmp_name);
5137 build_table_filename(lc_from,
sizeof(lc_from) - 1, old_db, tmp_name,
"",
5138 flags & FN_FROM_IS_TMP);
5141 strmov(tmp_name, new_name);
5142 my_casedn_str(files_charset_info, tmp_name);
5143 build_table_filename(lc_to,
sizeof(lc_to) - 1, new_db, tmp_name,
"",
5144 flags & FN_TO_IS_TMP);
5148 if (flags & NO_HA_TABLE)
5150 if (rename_file_ext(from,to,reg_ext))
5156 if (!(flags & NO_FRM_RENAME) && rename_file_ext(from,to,reg_ext))
5165 if (error == HA_ERR_WRONG_COMMAND)
5166 my_error(ER_NOT_SUPPORTED_YET, MYF(0),
"ALTER TABLE");
5169 char errbuf[MYSYS_STRERROR_SIZE];
5170 my_error(ER_ERROR_ON_RENAME, MYF(0), from, to,
5171 error, my_strerror(errbuf,
sizeof(errbuf), error));
5174 #ifdef HAVE_PSI_TABLE_INTERFACE
5179 if (likely(error == 0))
5183 (temp_table, old_db, strlen(old_db), old_name, strlen(old_name));
5188 thd->variables.option_bits= save_bits;
5190 DBUG_RETURN(error != 0);
5216 bool is_trans= FALSE;
5218 DBUG_ENTER(
"mysql_create_like_table");
5232 if (
open_tables(thd, &thd->lex->query_tables, ¬_used, 0))
5234 src_table->table->use_all_columns();
5236 DEBUG_SYNC(thd,
"create_table_like_after_open");
5239 memset(&local_create_info, 0,
sizeof(local_create_info));
5240 local_create_info.db_type= src_table->table->s->db_type();
5241 local_create_info.
row_type= src_table->table->s->row_type;
5242 if (mysql_prepare_alter_table(thd, src_table->table, &local_create_info,
5243 &local_alter_info, &local_alter_ctx))
5245 #ifdef WITH_PARTITION_STORAGE_ENGINE
5247 if (src_table->table->part_info)
5248 thd->work_part_info= src_table->table->part_info->get_clone();
5258 if (src_table->schema_table)
5259 local_create_info.max_rows= 0;
5261 local_create_info.options|= create_info->options&HA_LEX_CREATE_IF_NOT_EXISTS;
5263 local_create_info.options&= ~HA_LEX_CREATE_TMP_TABLE;
5264 local_create_info.options|= create_info->options & HA_LEX_CREATE_TMP_TABLE;
5266 local_create_info.auto_increment_value= 0;
5271 local_create_info.data_file_name= local_create_info.index_file_name= NULL;
5272 local_create_info.alias= create_info->alias;
5274 if ((res= mysql_create_table_no_lock(thd, table->db, table->table_name,
5275 &local_create_info, &local_alter_info,
5286 DBUG_ASSERT(table->table || table->view ||
5287 (create_info->options & HA_LEX_CREATE_TMP_TABLE) ||
5288 (thd->locked_tables_mode != LTM_LOCK_TABLES &&
5289 thd->mdl_context.is_lock_owner(MDL_key::TABLE, table->db,
5292 (thd->locked_tables_mode == LTM_LOCK_TABLES &&
5293 (create_info->options & HA_LEX_CREATE_IF_NOT_EXISTS) &&
5294 thd->mdl_context.is_lock_owner(MDL_key::TABLE, table->db,
5296 MDL_SHARED_NO_WRITE)));
5298 DEBUG_SYNC(thd,
"create_table_like_before_binlog");
5305 if (create_info->options & HA_LEX_CREATE_TMP_TABLE)
5306 thd->transaction.stmt.mark_created_temp_table();
5311 if (thd->is_current_stmt_binlog_format_row())
5328 if (!(create_info->options & HA_LEX_CREATE_TMP_TABLE))
5330 if (src_table->table->s->tmp_table)
5333 String query(buf,
sizeof(buf), system_charset_info);
5336 bool new_table= FALSE;
5360 int result __attribute__((unused))=
5361 store_create_info(thd, table, &query,
5362 create_info, FALSE );
5364 DBUG_ASSERT(result == 0);
5365 if (write_bin_log(thd, TRUE, query.ptr(), query.length()))
5370 DBUG_ASSERT(thd->open_tables == table->table);
5376 close_thread_table(thd, &thd->open_tables);
5381 if (write_bin_log(thd, TRUE, thd->query(), thd->query_length()))
5388 else if (write_bin_log(thd, TRUE, thd->query(), thd->query_length(), is_trans))
5397 int mysql_discard_or_import_tablespace(THD *thd,
5403 DBUG_ENTER(
"mysql_discard_or_import_tablespace");
5410 THD_STAGE_INFO(thd, stage_discard_or_import_tablespace);
5416 thd->tablespace_op= TRUE;
5421 table_list->mdl_request.
set_type(MDL_EXCLUSIVE);
5422 table_list->lock_type= TL_WRITE;
5424 table_list->required_type= FRMTYPE_TABLE;
5427 &alter_prelocking_strategy))
5429 thd->tablespace_op=FALSE;
5435 THD_STAGE_INFO(thd, stage_end);
5444 query_cache_invalidate3(thd, table_list, 0);
5447 error= trans_commit_stmt(thd);
5448 if (trans_commit_implicit(thd))
5452 error= write_bin_log(thd, FALSE, thd->query(), thd->query_length());
5455 thd->tablespace_op=FALSE;
5463 table_list->table->file->
print_error(error, MYF(0));
5474 static bool is_candidate_key(
KEY *key)
5479 if (!(key->
flags & HA_NOSAME) || (key->
flags & HA_NULL_PART_KEY))
5482 for (key_part= key->key_part; key_part < key_part_end; key_part++)
5484 if (key_part->key_part_flag & HA_PART_KEY_SEG)
5505 while ((field= field_it++) && field_idx < idx)
5512 static int compare_uint(
const uint *s,
const uint *t)
5514 return (*s < *t) ? -1 : ((*s > *t) ? 1 : 0);
5560 static bool fill_alter_inplace_info(THD *thd,
5565 Field **f_ptr, *field;
5570 uint candidate_key_count= 0;
5572 DBUG_ENTER(
"fill_alter_inplace_info");
5576 (
KEY**) thd->alloc(
sizeof(
KEY*) * table->s->keys)) ||
5578 (uint*) thd->alloc(
sizeof(uint) *
5579 alter_info->key_list.elements)))
5583 if (alter_info->flags & Alter_info::ALTER_ADD_COLUMN)
5584 ha_alter_info->
handler_flags|= Alter_inplace_info::ADD_COLUMN;
5585 if (alter_info->flags & Alter_info::ALTER_DROP_COLUMN)
5586 ha_alter_info->
handler_flags|= Alter_inplace_info::DROP_COLUMN;
5593 if (alter_info->flags & (Alter_info::ALTER_CHANGE_COLUMN |
5594 Alter_info::ALTER_CHANGE_COLUMN_DEFAULT))
5595 ha_alter_info->
handler_flags|= Alter_inplace_info::ALTER_COLUMN_DEFAULT;
5596 if (alter_info->flags & Alter_info::ADD_FOREIGN_KEY)
5597 ha_alter_info->
handler_flags|= Alter_inplace_info::ADD_FOREIGN_KEY;
5598 if (alter_info->flags & Alter_info::DROP_FOREIGN_KEY)
5599 ha_alter_info->
handler_flags|= Alter_inplace_info::DROP_FOREIGN_KEY;
5600 if (alter_info->flags & Alter_info::ALTER_OPTIONS)
5601 ha_alter_info->
handler_flags|= Alter_inplace_info::CHANGE_CREATE_OPTION;
5602 if (alter_info->flags & Alter_info::ALTER_RENAME)
5603 ha_alter_info->
handler_flags|= Alter_inplace_info::ALTER_RENAME;
5605 if (alter_info->flags & Alter_info::ALTER_ADD_PARTITION)
5606 ha_alter_info->
handler_flags|= Alter_inplace_info::ADD_PARTITION;
5607 if (alter_info->flags & Alter_info::ALTER_DROP_PARTITION)
5608 ha_alter_info->
handler_flags|= Alter_inplace_info::DROP_PARTITION;
5609 if (alter_info->flags & Alter_info::ALTER_PARTITION)
5610 ha_alter_info->
handler_flags|= Alter_inplace_info::ALTER_PARTITION;
5611 if (alter_info->flags & Alter_info::ALTER_COALESCE_PARTITION)
5612 ha_alter_info->
handler_flags|= Alter_inplace_info::COALESCE_PARTITION;
5613 if (alter_info->flags & Alter_info::ALTER_REORGANIZE_PARTITION)
5614 ha_alter_info->
handler_flags|= Alter_inplace_info::REORGANIZE_PARTITION;
5615 if (alter_info->flags & Alter_info::ALTER_TABLE_REORG)
5616 ha_alter_info->
handler_flags|= Alter_inplace_info::ALTER_TABLE_REORG;
5617 if (alter_info->flags & Alter_info::ALTER_REMOVE_PARTITIONING)
5618 ha_alter_info->
handler_flags|= Alter_inplace_info::ALTER_REMOVE_PARTITIONING;
5619 if (alter_info->flags & Alter_info::ALTER_ALL_PARTITION)
5620 ha_alter_info->
handler_flags|= Alter_inplace_info::ALTER_ALL_PARTITION;
5626 if (table->s->frm_version < FRM_VER_TRUE_VARCHAR && varchar)
5627 ha_alter_info->
handler_flags|= Alter_inplace_info::ALTER_COLUMN_TYPE;
5640 for (f_ptr= table->field; (field= *f_ptr); f_ptr++)
5644 field->flags&= ~(FIELD_IS_RENAMED | FIELD_IS_DROPPED);
5647 uint new_field_index= 0;
5648 new_field_it.init(alter_info->create_list);
5649 while ((new_field= new_field_it++))
5651 if (new_field->field == field)
5663 switch (field->
is_equal(new_field))
5667 ha_alter_info->
handler_flags|= Alter_inplace_info::ALTER_COLUMN_TYPE;
5678 case IS_EQUAL_PACK_LENGTH:
5691 ha_alter_info->
handler_flags|= Alter_inplace_info::ALTER_COLUMN_TYPE;
5695 if (my_strcasecmp(system_charset_info, field->field_name,
5696 new_field->field_name))
5698 field->flags|= FIELD_IS_RENAMED;
5699 ha_alter_info->
handler_flags|= Alter_inplace_info::ALTER_COLUMN_NAME;
5703 if ((new_field->flags & NOT_NULL_FLAG) !=
5704 (uint) (field->flags & NOT_NULL_FLAG))
5706 if (new_field->flags & NOT_NULL_FLAG)
5708 Alter_inplace_info::ALTER_COLUMN_NOT_NULLABLE;
5711 Alter_inplace_info::ALTER_COLUMN_NULLABLE;
5722 if (field->field_index != new_field_index)
5723 ha_alter_info->
handler_flags|= Alter_inplace_info::ALTER_COLUMN_ORDER;
5726 if (new_field->field_storage_type() != field->field_storage_type())
5728 Alter_inplace_info::ALTER_COLUMN_STORAGE_TYPE;
5731 if (new_field->column_format() != field->column_format())
5733 Alter_inplace_info::ALTER_COLUMN_COLUMN_FORMAT;
5741 DBUG_ASSERT(ha_alter_info->
handler_flags & Alter_inplace_info::DROP_COLUMN);
5742 field->flags|= FIELD_IS_DROPPED;
5747 new_field_it.init(alter_info->create_list);
5748 while ((new_field= new_field_it++))
5750 if (! new_field->field)
5756 DBUG_ASSERT(ha_alter_info->
handler_flags & Alter_inplace_info::ADD_COLUMN);
5767 KEY *table_key_end= table->key_info + table->s->keys;
5772 DBUG_PRINT(
"info", (
"index count old: %d new: %d",
5773 table->s->keys, ha_alter_info->
key_count));
5780 for (table_key= table->key_info; table_key < table_key_end; table_key++)
5784 new_key < new_key_end;
5787 if (! strcmp(table_key->
name, new_key->
name))
5790 if (new_key >= new_key_end)
5796 DBUG_PRINT(
"info", (
"index dropped: '%s'", table_key->
name));
5801 if ((table_key->algorithm != new_key->algorithm) ||
5802 ((table_key->
flags & HA_KEYFLAG_MASK) !=
5803 (new_key->
flags & HA_KEYFLAG_MASK)) ||
5812 for (key_part= table_key->key_part, new_part= new_key->key_part;
5814 key_part++, new_part++)
5823 if (key_part->length != new_part->length)
5826 new_field= get_field_by_index(alter_info, new_part->fieldnr);
5833 if (! new_field->field ||
5834 new_field->field->field_index != key_part->fieldnr - 1)
5848 DBUG_PRINT(
"info", (
"index changed: '%s'", table_key->
name));
5856 new_key < new_key_end;
5860 for (table_key= table->key_info; table_key < table_key_end; table_key++)
5862 if (! strcmp(table_key->
name, new_key->
name))
5865 if (table_key >= table_key_end)
5871 DBUG_PRINT(
"info", (
"index added: '%s'", new_key->
name));
5881 sizeof(uint), (qsort_cmp) compare_uint);
5886 for (table_key= table->key_info; table_key < table_key_end; table_key++)
5896 if (((uint) (table_key - table->key_info) == table->s->primary_key) ||
5897 is_candidate_key(table_key))
5898 candidate_key_count++;
5907 dropped_key < dropped_key_end; dropped_key++)
5909 table_key= *dropped_key;
5911 if (table_key->
flags & HA_NOSAME)
5917 if ((uint) (table_key - table->key_info) == table->s->primary_key)
5919 ha_alter_info->
handler_flags|= Alter_inplace_info::DROP_PK_INDEX;
5920 candidate_key_count--;
5924 ha_alter_info->
handler_flags|= Alter_inplace_info::DROP_UNIQUE_INDEX;
5925 if (is_candidate_key(table_key))
5926 candidate_key_count--;
5930 ha_alter_info->
handler_flags|= Alter_inplace_info::DROP_INDEX;
5934 for (uint add_key_idx= 0; add_key_idx < ha_alter_info->
index_add_count; add_key_idx++)
5938 if (new_key->
flags & HA_NOSAME)
5940 bool is_pk= !my_strcasecmp(system_charset_info, new_key->
name, primary_key_name);
5942 if ((!(new_key->
flags & HA_KEY_HAS_PART_KEY_SEG) &&
5943 !(new_key->
flags & HA_NULL_PART_KEY)) ||
5947 if (candidate_key_count == 0 || is_pk)
5948 ha_alter_info->
handler_flags|= Alter_inplace_info::ADD_PK_INDEX;
5950 ha_alter_info->
handler_flags|= Alter_inplace_info::ADD_UNIQUE_INDEX;
5951 candidate_key_count++;
5955 ha_alter_info->
handler_flags|= Alter_inplace_info::ADD_UNIQUE_INDEX;
5959 ha_alter_info->
handler_flags|= Alter_inplace_info::ADD_INDEX;
5976 TABLE *altered_table)
5978 uint field_idx, add_key_idx;
5986 for (field_idx= 0; field_idx < altered_table->s->fields; ++field_idx)
5987 altered_table->field[field_idx]->flags&= ~FIELD_IN_ADD_INDEX;
6000 for (key_part= key->key_part; key_part < end; key_part++)
6001 altered_table->field[key_part->fieldnr]->flags|= FIELD_IN_ADD_INDEX;
6015 static void set_column_defaults(
TABLE *altered_table,
6019 restore_record(altered_table, s->default_values);
6022 for (uint i= 0; i < altered_table->s->fields; ++
i)
6025 if (definition->field == NULL)
6046 bool mysql_compare_tables(
TABLE *table,
6049 bool *metadata_equal)
6051 DBUG_ENTER(
"mysql_compare_tables");
6053 uint changes= IS_EQUAL_NO;
6056 THD *thd= table->in_use;
6057 *metadata_equal=
false;
6071 Alter_info tmp_alter_info(*alter_info, thd->mem_root);
6073 KEY *key_info_buffer= NULL;
6076 if (mysql_prepare_create_table(thd, create_info,
6078 (table->s->tmp_table != NO_TMP_TABLE),
6080 table->file, &key_info_buffer,
6085 if (table->s->fields != alter_info->create_list.elements ||
6086 table->s->db_type() != create_info->db_type ||
6087 table->s->tmp_table ||
6088 (table->s->row_type != create_info->
row_type))
6092 tmp_new_field_it.init(tmp_alter_info.create_list);
6093 for (
Field **f_ptr= table->field; *f_ptr; f_ptr++)
6095 Field *field= *f_ptr;
6099 if ((tmp_new_field->flags & NOT_NULL_FLAG) !=
6100 (uint) (field->flags & NOT_NULL_FLAG))
6110 if (create_info->
row_type == ROW_TYPE_DYNAMIC ||
6111 (tmp_new_field->flags & BLOB_FLAG) ||
6112 (tmp_new_field->sql_type == MYSQL_TYPE_VARCHAR &&
6113 create_info->
row_type != ROW_TYPE_FIXED))
6114 create_info->table_options|= HA_OPTION_PACK_RECORD;
6117 if (my_strcasecmp(system_charset_info,
6119 tmp_new_field->field_name))
6123 uint field_changes= field->
is_equal(tmp_new_field);
6124 if (field_changes != IS_EQUAL_YES)
6127 changes|= field_changes;
6136 KEY *table_key_end= table->key_info + table->s->keys;
6138 KEY *new_key_end= key_info_buffer + key_count;
6141 for (table_key= table->key_info; table_key < table_key_end; table_key++)
6144 for (new_key= key_info_buffer; new_key < new_key_end; new_key++)
6146 if (! strcmp(table_key->
name, new_key->
name))
6149 if (new_key >= new_key_end)
6153 if ((table_key->algorithm != new_key->algorithm) ||
6154 ((table_key->
flags & HA_KEYFLAG_MASK) !=
6155 (new_key->
flags & HA_KEYFLAG_MASK)) ||
6164 for (table_part= table_key->key_part, new_part= new_key->key_part;
6165 table_part < table_part_end;
6166 table_part++, new_part++)
6173 if ((table_part->length != new_part->length) ||
6174 (table_part->fieldnr - 1 != new_part->fieldnr))
6180 for (new_key= key_info_buffer; new_key < new_key_end; new_key++)
6183 for (table_key= table->key_info; table_key < table_key_end; table_key++)
6185 if (! strcmp(table_key->
name, new_key->
name))
6188 if (table_key >= table_key_end)
6192 *metadata_equal=
true;
6213 bool alter_table_manage_keys(
TABLE *table,
int indexes_were_disabled,
6214 Alter_info::enum_enable_or_disable keys_onoff)
6217 DBUG_ENTER(
"alter_table_manage_keys");
6218 DBUG_PRINT(
"enter", (
"table=%p were_disabled=%d on_off=%d",
6219 table, indexes_were_disabled, keys_onoff));
6221 switch (keys_onoff) {
6222 case Alter_info::ENABLE:
6225 case Alter_info::LEAVE_AS_IS:
6226 if (!indexes_were_disabled)
6229 case Alter_info::DISABLE:
6233 if (error == HA_ERR_WRONG_COMMAND)
6235 push_warning_printf(current_thd, Sql_condition::WARN_LEVEL_NOTE,
6236 ER_ILLEGAL_HA, ER(ER_ILLEGAL_HA),
6237 table->s->table_name.str);
6261 static bool is_inplace_alter_impossible(
TABLE *table,
6265 DBUG_ENTER(
"is_inplace_alter_impossible");
6268 if (table->s->tmp_table)
6286 if (alter_info->flags & (Alter_info::ALTER_RECREATE |
6287 Alter_info::ALTER_ORDER |
6288 Alter_info::ALTER_KEYS_ONOFF))
6304 if (create_info->db_type != table->s->db_type() ||
6305 create_info->used_fields & HA_CREATE_USED_ENGINE)
6317 if (!table->s->mysql_version)
6354 static bool mysql_inplace_alter_table(THD *thd,
6357 TABLE *altered_table,
6359 enum_alter_inplace_result inplace_supported,
6368 bool reopen_tables=
false;
6370 DBUG_ENTER(
"mysql_inplace_alter_table");
6383 if (inplace_supported == HA_ALTER_INPLACE_EXCLUSIVE_LOCK ||
6384 ((inplace_supported == HA_ALTER_INPLACE_SHARED_LOCK_AFTER_PREPARE ||
6385 inplace_supported == HA_ALTER_INPLACE_NO_LOCK_AFTER_PREPARE) &&
6386 (thd->locked_tables_mode == LTM_LOCK_TABLES ||
6387 thd->locked_tables_mode == LTM_PRELOCKED_UNDER_LOCK_TABLES)) ||
6388 alter_info->requested_lock == Alter_info::ALTER_TABLE_LOCK_EXCLUSIVE)
6404 reopen_tables=
true;
6406 else if (inplace_supported == HA_ALTER_INPLACE_SHARED_LOCK_AFTER_PREPARE ||
6407 inplace_supported == HA_ALTER_INPLACE_NO_LOCK_AFTER_PREPARE)
6415 if (thd->mdl_context.upgrade_shared_lock(table->mdl_ticket, MDL_EXCLUSIVE,
6416 thd->variables.lock_wait_timeout))
6420 table->s->db.str, table->s->table_name.str,
6430 if ((inplace_supported == HA_ALTER_INPLACE_SHARED_LOCK ||
6431 alter_info->requested_lock == Alter_info::ALTER_TABLE_LOCK_SHARED) &&
6432 thd->mdl_context.upgrade_shared_lock(table->mdl_ticket,
6433 MDL_SHARED_NO_WRITE,
6434 thd->variables.lock_wait_timeout))
6440 if (
lock_tables(thd, table_list, alter_ctx->tables_opened, 0))
6443 DEBUG_SYNC(thd,
"alter_table_inplace_after_lock_upgrade");
6444 THD_STAGE_INFO(thd, stage_alter_inplace_prepare);
6446 switch (inplace_supported) {
6447 case HA_ALTER_ERROR:
6448 case HA_ALTER_INPLACE_NOT_SUPPORTED:
6451 case HA_ALTER_INPLACE_NO_LOCK:
6452 case HA_ALTER_INPLACE_NO_LOCK_AFTER_PREPARE:
6453 switch (alter_info->requested_lock) {
6454 case Alter_info::ALTER_TABLE_LOCK_DEFAULT:
6455 case Alter_info::ALTER_TABLE_LOCK_NONE:
6456 ha_alter_info->
online=
true;
6458 case Alter_info::ALTER_TABLE_LOCK_SHARED:
6459 case Alter_info::ALTER_TABLE_LOCK_EXCLUSIVE:
6463 case HA_ALTER_INPLACE_EXCLUSIVE_LOCK:
6464 case HA_ALTER_INPLACE_SHARED_LOCK_AFTER_PREPARE:
6465 case HA_ALTER_INPLACE_SHARED_LOCK:
6480 if ((inplace_supported == HA_ALTER_INPLACE_SHARED_LOCK_AFTER_PREPARE ||
6481 inplace_supported == HA_ALTER_INPLACE_NO_LOCK_AFTER_PREPARE) &&
6482 !(thd->locked_tables_mode == LTM_LOCK_TABLES ||
6483 thd->locked_tables_mode == LTM_PRELOCKED_UNDER_LOCK_TABLES) &&
6484 (alter_info->requested_lock != Alter_info::ALTER_TABLE_LOCK_EXCLUSIVE))
6487 if (inplace_supported == HA_ALTER_INPLACE_SHARED_LOCK_AFTER_PREPARE ||
6488 alter_info->requested_lock == Alter_info::ALTER_TABLE_LOCK_SHARED)
6492 DBUG_ASSERT(inplace_supported == HA_ALTER_INPLACE_NO_LOCK_AFTER_PREPARE);
6497 DEBUG_SYNC(thd,
"alter_table_inplace_after_lock_downgrade");
6498 THD_STAGE_INFO(thd, stage_alter_inplace);
6516 DBUG_EXECUTE_IF(
"alter_table_rollback_new_index", {
6520 my_error(ER_UNKNOWN_ERROR, MYF(0));
6524 DEBUG_SYNC(thd,
"alter_table_inplace_before_commit");
6525 THD_STAGE_INFO(thd, stage_alter_inplace_commit);
6535 table_list->table= table= NULL;
6536 close_temporary_table(thd, altered_table,
true,
false);
6542 if (mysql_rename_table(db_type, alter_ctx->new_db, alter_ctx->tmp_name,
6543 alter_ctx->db, alter_ctx->alias,
6544 FN_FROM_IS_TMP | NO_HA_TABLE))
6547 (void) quick_rm_table(thd, db_type,
6548 alter_ctx->new_db, alter_ctx->tmp_name,
6549 FN_IS_TMP | NO_HA_TABLE);
6553 table_list->mdl_request.
ticket= mdl_ticket;
6568 close_thread_table(thd, &thd->open_tables);
6569 table_list->table= NULL;
6576 alter_ctx->db, alter_ctx->table_name,
false);
6578 if (mysql_rename_table(db_type, alter_ctx->db, alter_ctx->table_name,
6579 alter_ctx->new_db, alter_ctx->new_alias, 0))
6590 alter_ctx->table_name,
6592 alter_ctx->new_alias))
6598 (void) mysql_rename_table(db_type,
6599 alter_ctx->new_db, alter_ctx->new_alias,
6600 alter_ctx->db, alter_ctx->alias, NO_FK_CHECKS);
6616 if (thd->locked_tables_list.reopen_tables(thd))
6617 thd->locked_tables_list.unlink_all_closed_tables(thd, NULL, 0);
6620 close_temporary_table(thd, altered_table,
true,
false);
6622 (void) quick_rm_table(thd, create_info->db_type, alter_ctx->new_db,
6623 alter_ctx->tmp_name, FN_IS_TMP | NO_HA_TABLE);
6637 blob_length_by_type(enum_field_types type)
6641 case MYSQL_TYPE_TINY_BLOB:
6643 case MYSQL_TYPE_BLOB:
6645 case MYSQL_TYPE_MEDIUM_BLOB:
6647 case MYSQL_TYPE_LONG_BLOB:
6699 mysql_prepare_alter_table(THD *thd,
TABLE *table,
6715 uint db_create_options= (table->s->db_create_options
6716 & ~(HA_OPTION_PACK_RECORD));
6717 uint used_fields= create_info->used_fields;
6718 KEY *key_info=table->key_info;
6721 DBUG_ENTER(
"mysql_prepare_alter_table");
6723 create_info->varchar= FALSE;
6725 if (!(used_fields & HA_CREATE_USED_MIN_ROWS))
6726 create_info->min_rows= table->s->min_rows;
6727 if (!(used_fields & HA_CREATE_USED_MAX_ROWS))
6728 create_info->max_rows= table->s->max_rows;
6729 if (!(used_fields & HA_CREATE_USED_AVG_ROW_LENGTH))
6730 create_info->avg_row_length= table->s->avg_row_length;
6731 if (!(used_fields & HA_CREATE_USED_DEFAULT_CHARSET))
6732 create_info->default_table_charset= table->s->table_charset;
6733 if (!(used_fields & HA_CREATE_USED_AUTO) && table->found_next_number_field)
6736 table->file->info(HA_STATUS_AUTO);
6737 create_info->auto_increment_value= table->file->stats.auto_increment_value;
6739 if (!(used_fields & HA_CREATE_USED_KEY_BLOCK_SIZE))
6740 create_info->key_block_size= table->s->key_block_size;
6742 if (!(used_fields & HA_CREATE_USED_STATS_SAMPLE_PAGES))
6743 create_info->stats_sample_pages= table->s->stats_sample_pages;
6745 if (!(used_fields & HA_CREATE_USED_STATS_AUTO_RECALC))
6746 create_info->stats_auto_recalc= table->s->stats_auto_recalc;
6748 if (!create_info->tablespace)
6749 create_info->tablespace= table->s->tablespace;
6751 if (create_info->storage_media == HA_SM_DEFAULT)
6752 create_info->storage_media= table->s->default_storage_media;
6754 restore_record(table, s->default_values);
6760 Field **f_ptr,*field;
6761 for (f_ptr=table->field ; (field= *f_ptr) ; f_ptr++)
6763 if (field->type() == MYSQL_TYPE_STRING)
6764 create_info->varchar= TRUE;
6768 while ((drop=drop_it++))
6770 if (drop->type == Alter_drop::COLUMN &&
6771 !my_strcasecmp(system_charset_info,field->field_name, drop->name))
6774 if (MTYP_TYPENR(field->unireg_check) == Field::NEXT_NUMBER &&
6775 !(used_fields & HA_CREATE_USED_AUTO))
6777 create_info->auto_increment_value=0;
6778 create_info->used_fields|=HA_CREATE_USED_AUTO;
6790 while ((def=def_it++))
6793 !my_strcasecmp(system_charset_info,field->field_name, def->change))
6804 new_create_list.push_back(def);
6824 new_create_list.push_back(def);
6827 while ((alter=alter_it++))
6829 if (!my_strcasecmp(system_charset_info,field->field_name, alter->name))
6834 if (def->flags & BLOB_FLAG)
6836 my_error(ER_BLOB_CANT_HAVE_DEFAULT, MYF(0), def->change);
6839 if ((def->
def=alter->def))
6840 def->flags&= ~NO_DEFAULT_VALUE_FLAG;
6842 def->flags|= NO_DEFAULT_VALUE_FLAG;
6848 while ((def=def_it++))
6850 if (def->change && ! def->field)
6852 my_error(ER_BAD_FIELD_ERROR, MYF(0), def->change, table->s->table_name.str);
6862 if ((def->sql_type == MYSQL_TYPE_DATE ||
6863 def->sql_type == MYSQL_TYPE_NEWDATE ||
6864 def->sql_type == MYSQL_TYPE_DATETIME ||
6865 def->sql_type == MYSQL_TYPE_DATETIME2) &&
6866 !alter_ctx->datetime_field &&
6867 !(~def->flags & (NO_DEFAULT_VALUE_FLAG | NOT_NULL_FLAG)) &&
6868 thd->variables.sql_mode & MODE_NO_ZERO_DATE)
6870 alter_ctx->datetime_field= def;
6871 alter_ctx->error_if_not_empty=
true;
6874 new_create_list.push_back(def);
6886 while ((find=find_it++))
6901 if (def->after == first_keyword)
6902 new_create_list.push_front(def);
6906 while ((find=find_it++))
6908 if (!my_strcasecmp(system_charset_info, def->after, find->field_name))
6913 my_error(ER_BAD_FIELD_ERROR, MYF(0), def->after, table->s->table_name.str);
6920 if (alter_info->alter_list.elements)
6922 my_error(ER_BAD_FIELD_ERROR, MYF(0),
6923 alter_info->alter_list.head()->name, table->s->table_name.str);
6926 if (!new_create_list.elements)
6928 my_message(ER_CANT_REMOVE_ALL_FIELDS, ER(ER_CANT_REMOVE_ALL_FIELDS),
6938 for (uint i=0 ; i < table->s->keys ; i++,key_info++)
6940 char *key_name= key_info->
name;
6941 bool index_column_dropped=
false;
6944 while ((drop=drop_it++))
6946 if (drop->type == Alter_drop::KEY &&
6947 !my_strcasecmp(system_charset_info,key_name, drop->name))
6960 if (!key_part->field)
6962 const char *key_part_name=key_part->field->field_name;
6965 while ((cfield=field_it++))
6969 if (!my_strcasecmp(system_charset_info, key_part_name,
6973 else if (!my_strcasecmp(system_charset_info,
6974 key_part_name, cfield->field_name))
6982 index_column_dropped=
true;
6985 uint key_part_length=key_part->length;
7011 (key_info->
flags & HA_SPATIAL) ||
7012 (cfield->field->field_length == key_part_length &&
7013 !f_is_blob(key_part->key_type)) ||
7014 (cfield->length && (((cfield->sql_type >= MYSQL_TYPE_TINY_BLOB &&
7015 cfield->sql_type <= MYSQL_TYPE_BLOB) ?
7016 blob_length_by_type(cfield->sql_type) :
7018 key_part_length / key_part->field->charset()->mbmaxlen)))
7021 key_part_length /= key_part->field->charset()->mbmaxlen;
7023 strlen(cfield->field_name),
7026 if (key_parts.elements)
7030 enum Key::Keytype key_type;
7031 memset(&key_create_info, 0,
sizeof(key_create_info));
7033 key_create_info.algorithm= key_info->algorithm;
7034 if (key_info->
flags & HA_USES_BLOCK_SIZE)
7035 key_create_info.block_size= key_info->block_size;
7036 if (key_info->
flags & HA_USES_PARSER)
7037 key_create_info.parser_name= *plugin_name(key_info->
parser);
7038 if (key_info->
flags & HA_USES_COMMENT)
7039 key_create_info.comment= key_info->comment;
7041 if (key_info->
flags & HA_SPATIAL)
7042 key_type= Key::SPATIAL;
7043 else if (key_info->
flags & HA_NOSAME)
7045 if (! my_strcasecmp(system_charset_info, key_name, primary_key_name))
7046 key_type= Key::PRIMARY;
7048 key_type= Key::UNIQUE;
7050 else if (key_info->
flags & HA_FULLTEXT)
7051 key_type= Key::FULLTEXT;
7053 key_type= Key::MULTIPLE;
7055 if (index_column_dropped)
7064 key=
new Key(key_type, key_name, strlen(key_name),
7066 test(key_info->
flags & HA_GENERATED_KEY),
7068 new_key_list.push_back(key);
7073 while ((key=key_it++))
7075 new_key_list.push_back(key);
7076 if (key->name.str &&
7077 !my_strcasecmp(system_charset_info, key->name.str, primary_key_name))
7079 my_error(ER_WRONG_NAME_FOR_INDEX, MYF(0), key->name.str);
7085 if (alter_info->drop_list.elements)
7089 while ((drop=drop_it++)) {
7090 switch (drop->type) {
7091 case Alter_drop::KEY:
7092 case Alter_drop::COLUMN:
7093 my_error(ER_CANT_DROP_FIELD_OR_KEY, MYF(0),
7094 alter_info->drop_list.head()->name);
7096 case Alter_drop::FOREIGN_KEY:
7102 if (alter_info->alter_list.elements)
7104 my_error(ER_CANT_DROP_FIELD_OR_KEY, MYF(0),
7105 alter_info->alter_list.head()->name);
7109 if (!create_info->comment.str)
7111 create_info->comment.str= table->s->comment.str;
7112 create_info->comment.length= table->s->comment.length;
7116 if (table->file->ht->db_type == DB_TYPE_PARTITION_DB)
7117 create_info->data_file_name = (
char*) -1;
7119 table->file->update_create_info(create_info);
7120 if ((create_info->table_options &
7121 (HA_OPTION_PACK_KEYS | HA_OPTION_NO_PACK_KEYS)) ||
7122 (used_fields & HA_CREATE_USED_PACK_KEYS))
7123 db_create_options&= ~(HA_OPTION_PACK_KEYS | HA_OPTION_NO_PACK_KEYS);
7124 if ((create_info->table_options &
7125 (HA_OPTION_STATS_PERSISTENT | HA_OPTION_NO_STATS_PERSISTENT)) ||
7126 (used_fields & HA_CREATE_USED_STATS_PERSISTENT))
7127 db_create_options&= ~(HA_OPTION_STATS_PERSISTENT | HA_OPTION_NO_STATS_PERSISTENT);
7128 if (create_info->table_options &
7129 (HA_OPTION_CHECKSUM | HA_OPTION_NO_CHECKSUM))
7130 db_create_options&= ~(HA_OPTION_CHECKSUM | HA_OPTION_NO_CHECKSUM);
7131 if (create_info->table_options &
7132 (HA_OPTION_DELAY_KEY_WRITE | HA_OPTION_NO_DELAY_KEY_WRITE))
7133 db_create_options&= ~(HA_OPTION_DELAY_KEY_WRITE |
7134 HA_OPTION_NO_DELAY_KEY_WRITE);
7135 create_info->table_options|= db_create_options;
7137 if (table->s->tmp_table)
7138 create_info->options|=HA_LEX_CREATE_TMP_TABLE;
7141 alter_info->create_list.
swap(new_create_list);
7142 alter_info->key_list.
swap(new_key_list);
7160 const char *old_name)
7165 while ((new_field= new_field_it++))
7167 if (new_field->field &&
7168 (my_strcasecmp(system_charset_info,
7169 new_field->field->field_name,
7179 enum fk_column_change_type
7181 FK_COLUMN_NO_CHANGE, FK_COLUMN_DATA_CHANGE,
7182 FK_COLUMN_RENAMED, FK_COLUMN_DROPPED
7208 static enum fk_column_change_type
7209 fk_check_column_changes(THD *thd,
Alter_info *alter_info,
7211 const char **bad_column_name)
7216 *bad_column_name= NULL;
7218 while ((column= column_it++))
7220 Create_field *new_field= get_field_by_old_name(alter_info, column->str);
7224 Field *old_field= new_field->field;
7226 if (my_strcasecmp(system_charset_info, old_field->field_name,
7227 new_field->field_name))
7235 *bad_column_name= column->str;
7236 return FK_COLUMN_RENAMED;
7239 if ((old_field->
is_equal(new_field) == IS_EQUAL_NO) ||
7240 ((new_field->flags & NOT_NULL_FLAG) &&
7241 !(old_field->flags & NOT_NULL_FLAG)))
7251 *bad_column_name= column->str;
7252 return FK_COLUMN_DATA_CHANGE;
7267 *bad_column_name= column->str;
7268 return FK_COLUMN_DROPPED;
7272 return FK_COLUMN_NO_CHANGE;
7300 static bool fk_prepare_copy_alter_table(THD *thd,
TABLE *table,
7308 DBUG_ENTER(
"fk_prepare_copy_alter_table");
7313 if (thd->is_error())
7323 while ((f_key= fk_parent_key_it++))
7328 while ((drop= drop_it++))
7337 if ((drop->type == Alter_drop::FOREIGN_KEY) &&
7338 (my_strcasecmp(system_charset_info, f_key->foreign_id->str,
7339 drop->name) == 0) &&
7340 (my_strcasecmp(table_alias_charset, f_key->foreign_db->str,
7341 table->s->db.str) == 0) &&
7342 (my_strcasecmp(table_alias_charset, f_key->foreign_table->str,
7343 table->s->table_name.str) == 0))
7344 fk_parent_key_it.remove();
7354 if (!fk_parent_key_list.is_empty() &&
7358 fk_parent_key_it.rewind();
7359 while ((f_key= fk_parent_key_it++))
7361 enum fk_column_change_type changes;
7362 const char *bad_column_name;
7364 changes= fk_check_column_changes(thd, alter_info,
7365 f_key->referenced_fields,
7370 case FK_COLUMN_NO_CHANGE:
7373 case FK_COLUMN_DATA_CHANGE:
7375 char buff[NAME_LEN*2+2];
7376 strxnmov(buff,
sizeof(buff)-1, f_key->foreign_db->str,
".",
7377 f_key->foreign_table->str, NullS);
7378 my_error(ER_FK_COLUMN_CANNOT_CHANGE_CHILD, MYF(0), bad_column_name,
7379 f_key->foreign_id->str, buff);
7382 case FK_COLUMN_RENAMED:
7383 my_error(ER_ALTER_OPERATION_NOT_SUPPORTED_REASON, MYF(0),
7385 ER(ER_ALTER_OPERATION_NOT_SUPPORTED_REASON_FK_RENAME),
7386 "ALGORITHM=INPLACE");
7388 case FK_COLUMN_DROPPED:
7390 char buff[NAME_LEN*2+2];
7391 strxnmov(buff,
sizeof(buff)-1, f_key->foreign_db->str,
".",
7392 f_key->foreign_table->str, NullS);
7393 my_error(ER_FK_COLUMN_CANNOT_DROP_CHILD, MYF(0), bad_column_name,
7394 f_key->foreign_id->str, buff);
7405 if (thd->is_error())
7414 while ((f_key= fk_key_it++))
7419 while ((drop= drop_it++))
7422 if ((drop->type == Alter_drop::FOREIGN_KEY) &&
7423 (my_strcasecmp(system_charset_info, f_key->foreign_id->str,
7430 while ((f_key= fk_key_it++))
7432 enum fk_column_change_type changes;
7433 const char *bad_column_name;
7435 changes= fk_check_column_changes(thd, alter_info,
7436 f_key->foreign_fields,
7441 case FK_COLUMN_NO_CHANGE:
7444 case FK_COLUMN_DATA_CHANGE:
7445 my_error(ER_FK_COLUMN_CANNOT_CHANGE, MYF(0), bad_column_name,
7446 f_key->foreign_id->str);
7448 case FK_COLUMN_RENAMED:
7449 my_error(ER_ALTER_OPERATION_NOT_SUPPORTED_REASON, MYF(0),
7451 ER(ER_ALTER_OPERATION_NOT_SUPPORTED_REASON_FK_RENAME),
7452 "ALGORITHM=INPLACE");
7454 case FK_COLUMN_DROPPED:
7455 my_error(ER_FK_COLUMN_CANNOT_DROP, MYF(0), bad_column_name,
7456 f_key->foreign_id->str);
7481 simple_rename_or_index_change(THD *thd,
TABLE_LIST *table_list,
7482 Alter_info::enum_enable_or_disable keys_onoff,
7485 TABLE *table= table_list->table;
7488 DBUG_ENTER(
"simple_rename_or_index_change");
7490 if (keys_onoff != Alter_info::LEAVE_AS_IS)
7496 if (
lock_tables(thd, table_list, alter_ctx->tables_opened, 0))
7499 if (keys_onoff == Alter_info::ENABLE)
7501 DEBUG_SYNC(thd,
"alter_table_enable_indexes");
7502 DBUG_EXECUTE_IF(
"sleep_alter_enable_indexes", my_sleep(6000000););
7505 else if (keys_onoff == Alter_info::DISABLE)
7508 if (error == HA_ERR_WRONG_COMMAND)
7510 push_warning_printf(thd, Sql_condition::WARN_LEVEL_NOTE,
7511 ER_ILLEGAL_HA, ER(ER_ILLEGAL_HA),
7524 THD_STAGE_INFO(thd, stage_rename);
7525 handlerton *old_db_type= table->s->db_type();
7538 if (mysql_rename_table(old_db_type, alter_ctx->db, alter_ctx->table_name,
7539 alter_ctx->new_db, alter_ctx->new_alias, 0))
7544 alter_ctx->table_name,
7546 alter_ctx->new_alias))
7548 (void) mysql_rename_table(old_db_type,
7549 alter_ctx->new_db, alter_ctx->new_alias,
7550 alter_ctx->db, alter_ctx->table_name,
7558 error= write_bin_log(thd, TRUE, thd->query(), thd->query_length());
7562 table_list->table= NULL;
7563 query_cache_invalidate3(thd, table_list, 0);
7565 if ((thd->locked_tables_mode == LTM_LOCK_TABLES ||
7566 thd->locked_tables_mode == LTM_PRELOCKED_UNDER_LOCK_TABLES))
7574 thd->mdl_context.release_all_locks_for_name(mdl_ticket);
7578 DBUG_RETURN(error != 0);
7620 bool mysql_alter_table(THD *thd,
char *new_db,
char *new_name,
7624 uint order_num,
ORDER *order,
bool ignore)
7626 DBUG_ENTER(
"mysql_alter_table");
7634 int table_kind= check_if_log_table(table_list->db_length, table_list->db,
7635 table_list->table_name_length,
7636 table_list->table_name,
false);
7641 if (logger.is_log_table_enabled(table_kind))
7643 my_error(ER_BAD_LOG_STATEMENT, MYF(0),
"ALTER");
7648 if ((create_info->used_fields & HA_CREATE_USED_ENGINE) &&
7649 (!create_info->db_type ||
7650 !(create_info->db_type->flags & HTON_SUPPORT_LOG_TABLES)))
7652 my_error(ER_UNSUPORTED_LOG_ENGINE, MYF(0));
7656 #ifdef WITH_PARTITION_STORAGE_ENGINE
7657 if (alter_info->flags & Alter_info::ALTER_PARTITION)
7659 my_error(ER_WRONG_USAGE, MYF(0),
"PARTITION",
"log table");
7665 THD_STAGE_INFO(thd, stage_init);
7672 table_list->required_type= FRMTYPE_TABLE;
7676 DEBUG_SYNC(thd,
"alter_table_before_open_tables");
7678 bool error=
open_tables(thd, &table_list, &tables_opened, 0,
7679 &alter_prelocking_strategy);
7681 DEBUG_SYNC(thd,
"alter_opened_table");
7686 TABLE *table= table_list->table;
7687 table->use_all_columns();
7696 if ((thd->locked_tables_mode == LTM_LOCK_TABLES ||
7697 thd->locked_tables_mode == LTM_PRELOCKED_UNDER_LOCK_TABLES) &&
7698 (create_info->used_fields & HA_CREATE_USED_UNION) &&
7699 (table->s->tmp_table == NO_TMP_TABLE))
7701 my_error(ER_LOCK_OR_ACTIVE_TRANSACTION, MYF(0));
7705 Alter_table_ctx alter_ctx(thd, table_list, tables_opened, new_db, new_name);
7711 thd->add_to_binlog_accessed_dbs(alter_ctx.db);
7713 thd->add_to_binlog_accessed_dbs(alter_ctx.new_db);
7720 if (table->s->tmp_table != NO_TMP_TABLE)
7724 my_error(ER_TABLE_EXISTS_ERROR, MYF(0), alter_ctx.new_alias);
7733 target_mdl_request.
init(MDL_key::TABLE,
7734 alter_ctx.new_db, alter_ctx.new_name,
7735 MDL_EXCLUSIVE, MDL_TRANSACTION);
7736 mdl_requests.push_front(&target_mdl_request);
7745 target_db_mdl_request.
init(MDL_key::SCHEMA, alter_ctx.new_db,
"",
7746 MDL_INTENTION_EXCLUSIVE,
7748 mdl_requests.push_front(&target_db_mdl_request);
7755 DBUG_ASSERT(thd->mdl_context.is_lock_owner(MDL_key::GLOBAL,
7757 MDL_INTENTION_EXCLUSIVE));
7759 if (thd->mdl_context.acquire_locks(&mdl_requests,
7760 thd->variables.lock_wait_timeout))
7763 DEBUG_SYNC(thd,
"locked_table_name");
7771 my_error(ER_TABLE_EXISTS_ERROR, MYF(0), alter_ctx.new_alias);
7777 if (!create_info->db_type)
7779 #ifdef WITH_PARTITION_STORAGE_ENGINE
7780 if (table->part_info &&
7781 create_info->used_fields & HA_CREATE_USED_ENGINE)
7790 create_info->db_type= table->part_info->default_engine_type;
7794 create_info->db_type= table->s->db_type();
7797 if (check_engine(thd, alter_ctx.new_db, alter_ctx.new_name, create_info))
7800 if ((create_info->db_type != table->s->db_type() ||
7801 alter_info->flags & Alter_info::ALTER_PARTITION) &&
7804 my_error(ER_ROW_IS_REFERENCED, MYF(0));
7813 if (create_info->
row_type == ROW_TYPE_NOT_USED)
7816 create_info->
row_type= table->s->row_type;
7821 create_info->used_fields |= HA_CREATE_USED_ROW_FORMAT;
7824 DBUG_PRINT(
"info", (
"old type: %s new type: %s",
7825 ha_resolve_storage_engine_name(table->s->db_type()),
7826 ha_resolve_storage_engine_name(create_info->db_type)));
7827 if (ha_check_storage_engine_flag(table->s->db_type(), HTON_ALTER_NOT_SUPPORTED) ||
7828 ha_check_storage_engine_flag(create_info->db_type, HTON_ALTER_NOT_SUPPORTED))
7830 DBUG_PRINT(
"info", (
"doesn't support alter"));
7831 my_error(ER_ILLEGAL_HA, MYF(0), table_list->table_name);
7835 THD_STAGE_INFO(thd, stage_setup);
7836 if (!(alter_info->flags & ~(Alter_info::ALTER_RENAME |
7837 Alter_info::ALTER_KEYS_ONOFF)) &&
7838 alter_info->requested_algorithm !=
7839 Alter_info::ALTER_TABLE_ALGORITHM_COPY &&
7840 !table->s->tmp_table)
7843 if (alter_info->requested_lock != Alter_info::ALTER_TABLE_LOCK_DEFAULT &&
7844 alter_info->requested_lock != Alter_info::ALTER_TABLE_LOCK_EXCLUSIVE)
7846 my_error(ER_ALTER_OPERATION_NOT_SUPPORTED, MYF(0),
7847 "LOCK=NONE/SHARED",
"LOCK=EXCLUSIVE");
7850 DBUG_RETURN(simple_rename_or_index_change(thd, table_list,
7851 alter_info->keys_onoff,
7857 #ifdef WITH_PARTITION_STORAGE_ENGINE
7858 bool partition_changed=
false;
7859 bool fast_alter_partition=
false;
7861 if (prep_alter_part_table(thd, table, alter_info, create_info,
7862 &alter_ctx, &partition_changed,
7863 &fast_alter_partition))
7870 if (mysql_prepare_alter_table(thd, table, create_info, alter_info,
7876 set_table_default_charset(thd, create_info, alter_ctx.db);
7878 #ifdef WITH_PARTITION_STORAGE_ENGINE
7879 if (fast_alter_partition)
7887 if (alter_info->requested_lock !=
7888 Alter_info::ALTER_TABLE_LOCK_DEFAULT)
7890 my_error(ER_ALTER_OPERATION_NOT_SUPPORTED_REASON, MYF(0),
7891 "LOCK=NONE/SHARED/EXCLUSIVE",
7892 ER(ER_ALTER_OPERATION_NOT_SUPPORTED_REASON_PARTITION),
7896 else if (alter_info->requested_algorithm !=
7897 Alter_info::ALTER_TABLE_ALGORITHM_DEFAULT)
7899 my_error(ER_ALTER_OPERATION_NOT_SUPPORTED_REASON, MYF(0),
7900 "ALGORITHM=COPY/INPLACE",
7901 ER(ER_ALTER_OPERATION_NOT_SUPPORTED_REASON_PARTITION),
7902 "ALGORITHM=DEFAULT");
7910 if (thd->mdl_context.upgrade_shared_lock(mdl_ticket, MDL_SHARED_NO_WRITE,
7911 thd->variables.lock_wait_timeout)
7912 ||
lock_tables(thd, table_list, alter_ctx.tables_opened, 0))
7918 DBUG_RETURN(fast_alter_partition_table(thd, table, alter_info,
7919 create_info, table_list,
7921 alter_ctx.table_name));
7935 if ((thd->variables.old_alter_table &&
7936 alter_info->requested_algorithm !=
7937 Alter_info::ALTER_TABLE_ALGORITHM_INPLACE)
7938 || is_inplace_alter_impossible(table, create_info, alter_info)
7939 #ifdef WITH_PARTITION_STORAGE_ENGINE
7940 || (partition_changed &&
7941 !(table->s->db_type()->partition_flags() & HA_USE_AUTO_PARTITION))
7945 if (alter_info->requested_algorithm ==
7946 Alter_info::ALTER_TABLE_ALGORITHM_INPLACE)
7948 my_error(ER_ALTER_OPERATION_NOT_SUPPORTED, MYF(0),
7949 "ALGORITHM=INPLACE",
"ALGORITHM=COPY");
7952 alter_info->requested_algorithm= Alter_info::ALTER_TABLE_ALGORITHM_COPY;
7965 handlerton *new_db_type= create_info->db_type;
7966 handlerton *old_db_type= table->s->db_type();
7967 TABLE *new_table= NULL;
7968 ha_rows copied=0,deleted=0;
7994 char index_file[FN_REFLEN], data_file[FN_REFLEN];
7998 if (create_info->index_file_name)
8001 strmov(index_file, alter_ctx.tmp_name);
8002 create_info->index_file_name=fn_same(index_file,
8003 create_info->index_file_name,
8006 if (create_info->data_file_name)
8009 strmov(data_file, alter_ctx.tmp_name);
8010 create_info->data_file_name=fn_same(data_file,
8011 create_info->data_file_name,
8018 create_info->data_file_name=create_info->index_file_name=0;
8021 DEBUG_SYNC(thd,
"alter_table_before_create_table_no_lock");
8022 DBUG_EXECUTE_IF(
"sleep_before_create_table_no_lock",
8025 thd->abort_on_warning= !ignore && thd->is_strict_mode();
8031 if (!thd->variables.explicit_defaults_for_timestamp)
8032 promote_first_timestamp_column(&alter_info->create_list);
8049 bool varchar= create_info->varchar;
8051 tmp_disable_binlog(thd);
8052 error= create_table_impl(thd, alter_ctx.new_db, alter_ctx.tmp_name,
8054 create_info, alter_info,
8055 true, 0,
true, NULL,
8056 &key_info, &key_count);
8057 reenable_binlog(thd);
8058 thd->abort_on_warning=
false;
8063 bool no_ha_table=
true;
8065 if (alter_info->requested_algorithm != Alter_info::ALTER_TABLE_ALGORITHM_COPY)
8068 key_info, key_count,
8069 #ifdef WITH_PARTITION_STORAGE_ENGINE
8070 thd->work_part_info,
8075 TABLE *altered_table= NULL;
8076 bool use_inplace=
true;
8079 if (fill_alter_inplace_info(thd, table, varchar, &ha_alter_info))
8080 goto err_new_table_cleanup;
8083 DBUG_ASSERT(!table->s->tmp_table);
8089 goto err_new_table_cleanup;
8092 update_altered_table(ha_alter_info, altered_table);
8099 altered_table->column_bitmaps_set_no_signal(&altered_table->s->all_set,
8100 &altered_table->s->all_set);
8102 set_column_defaults(altered_table, alter_info->create_list);
8118 close_temporary_table(thd, altered_table,
true,
false);
8123 enum_alter_inplace_result inplace_supported=
8127 switch (inplace_supported) {
8128 case HA_ALTER_INPLACE_EXCLUSIVE_LOCK:
8130 if (alter_info->requested_lock ==
8131 Alter_info::ALTER_TABLE_LOCK_SHARED &&
8132 alter_info->requested_algorithm ==
8133 Alter_info::ALTER_TABLE_ALGORITHM_DEFAULT)
8138 else if (alter_info->requested_lock ==
8139 Alter_info::ALTER_TABLE_LOCK_NONE ||
8140 alter_info->requested_lock ==
8141 Alter_info::ALTER_TABLE_LOCK_SHARED)
8145 close_temporary_table(thd, altered_table,
true,
false);
8146 goto err_new_table_cleanup;
8149 case HA_ALTER_INPLACE_SHARED_LOCK_AFTER_PREPARE:
8150 case HA_ALTER_INPLACE_SHARED_LOCK:
8152 if (alter_info->requested_lock ==
8153 Alter_info::ALTER_TABLE_LOCK_NONE)
8156 close_temporary_table(thd, altered_table,
true,
false);
8157 goto err_new_table_cleanup;
8160 case HA_ALTER_INPLACE_NO_LOCK_AFTER_PREPARE:
8161 case HA_ALTER_INPLACE_NO_LOCK:
8163 case HA_ALTER_INPLACE_NOT_SUPPORTED:
8165 if (alter_info->requested_algorithm ==
8166 Alter_info::ALTER_TABLE_ALGORITHM_INPLACE)
8170 close_temporary_table(thd, altered_table,
true,
false);
8171 goto err_new_table_cleanup;
8174 if (alter_info->requested_lock ==
8175 Alter_info::ALTER_TABLE_LOCK_NONE)
8178 close_temporary_table(thd, altered_table,
true,
false);
8179 goto err_new_table_cleanup;
8184 case HA_ALTER_ERROR:
8186 close_temporary_table(thd, altered_table,
true,
false);
8187 goto err_new_table_cleanup;
8192 if (mysql_inplace_alter_table(thd, table_list, table,
8195 inplace_supported, &target_mdl_request,
8205 close_temporary_table(thd, altered_table,
true,
false);
8212 if (fk_prepare_copy_alter_table(thd, table, alter_info, &alter_ctx))
8213 goto err_new_table_cleanup;
8215 if (!table->s->tmp_table)
8218 if (alter_info->requested_lock == Alter_info::ALTER_TABLE_LOCK_NONE)
8220 my_error(ER_ALTER_OPERATION_NOT_SUPPORTED_REASON, MYF(0),
8222 ER(ER_ALTER_OPERATION_NOT_SUPPORTED_REASON_COPY),
8224 goto err_new_table_cleanup;
8228 if (alter_info->requested_lock == Alter_info::ALTER_TABLE_LOCK_EXCLUSIVE &&
8230 goto err_new_table_cleanup;
8236 if (alter_info->requested_lock != Alter_info::ALTER_TABLE_LOCK_EXCLUSIVE &&
8237 thd->mdl_context.upgrade_shared_lock(mdl_ticket, MDL_SHARED_NO_WRITE,
8238 thd->variables.lock_wait_timeout))
8239 goto err_new_table_cleanup;
8241 DEBUG_SYNC(thd,
"alter_table_copy_after_lock_upgrade");
8245 if (
lock_tables(thd, table_list, alter_ctx.tables_opened, 0))
8246 goto err_new_table_cleanup;
8250 alter_ctx.new_db, alter_ctx.tmp_name,
8251 create_info,
false))
8252 goto err_new_table_cleanup;
8257 if (create_info->options & HA_LEX_CREATE_TMP_TABLE)
8260 alter_ctx.new_db, alter_ctx.tmp_name,
8262 goto err_new_table_cleanup;
8268 if (table->s->tmp_table != NO_TMP_TABLE)
8272 alter_ctx.tmp_name, strlen(alter_ctx.tmp_name),
8273 alter_ctx.tmp_name, TL_READ_NO_INSERT);
8276 new_table= tbl.table;
8283 alter_ctx.new_db, alter_ctx.tmp_name,
8287 goto err_new_table_cleanup;
8294 thd->count_cuted_fields= CHECK_FIELD_WARN;
8295 thd->cuted_fields=0L;
8303 new_table->next_number_field=new_table->found_next_number_field;
8304 THD_STAGE_INFO(thd, stage_copy_to_tmp_table);
8305 DBUG_EXECUTE_IF(
"abort_copy_table", {
8306 my_error(ER_LOCK_WAIT_TIMEOUT, MYF(0));
8307 goto err_new_table_cleanup;
8309 if (copy_data_between_tables(table, new_table,
8310 alter_info->create_list, ignore,
8311 order_num, order, &copied, &deleted,
8312 alter_info->keys_onoff,
8314 goto err_new_table_cleanup;
8319 DBUG_ASSERT(new_table->file->ht->db_type == DB_TYPE_MRG_MYISAM);
8320 if (!table->s->tmp_table &&
8322 goto err_new_table_cleanup;
8323 THD_STAGE_INFO(thd, stage_manage_keys);
8324 DEBUG_SYNC(thd,
"alter_table_manage_keys");
8325 alter_table_manage_keys(table, table->file->indexes_are_disabled(),
8326 alter_info->keys_onoff);
8327 if (trans_commit_stmt(thd) || trans_commit_implicit(thd))
8328 goto err_new_table_cleanup;
8330 thd->count_cuted_fields= CHECK_FIELD_IGNORE;
8332 if (table->s->tmp_table != NO_TMP_TABLE)
8337 if (thd->locked_tables_mode != LTM_LOCK_TABLES &&
8338 thd->locked_tables_mode != LTM_PRELOCKED_UNDER_LOCK_TABLES)
8340 mysql_unlock_tables(thd, thd->lock);
8353 close_temporary_table(thd, table,
true,
true);
8355 if (rename_temporary_table(thd, new_table,
8356 alter_ctx.new_db, alter_ctx.new_name))
8357 goto err_new_table_cleanup;
8359 if (!thd->is_current_stmt_binlog_format_row() &&
8360 write_bin_log(thd,
true, thd->query(), thd->query_length()))
8370 close_temporary_table(thd, new_table,
true,
false);
8373 DEBUG_SYNC(thd,
"alter_table_before_rename_result_table");
8392 THD_STAGE_INFO(thd, stage_rename_result_table);
8395 goto err_new_table_cleanup;
8398 table_list->table= table= NULL;
8404 char backup_name[32];
8405 my_snprintf(backup_name,
sizeof(backup_name),
"%s2-%lx-%lx",
tmp_file_prefix,
8406 current_pid, thd->thread_id);
8407 if (lower_case_table_names)
8408 my_casedn_str(files_charset_info, backup_name);
8409 if (mysql_rename_table(old_db_type, alter_ctx.db, alter_ctx.table_name,
8410 alter_ctx.db, backup_name, FN_TO_IS_TMP))
8413 (void) quick_rm_table(thd, new_db_type, alter_ctx.new_db,
8414 alter_ctx.tmp_name, FN_IS_TMP);
8419 if (mysql_rename_table(new_db_type, alter_ctx.new_db, alter_ctx.tmp_name,
8420 alter_ctx.new_db, alter_ctx.new_alias,
8424 (void) quick_rm_table(thd, new_db_type, alter_ctx.new_db,
8425 alter_ctx.tmp_name, FN_IS_TMP);
8428 (void) mysql_rename_table(old_db_type, alter_ctx.db, backup_name,
8429 alter_ctx.db, alter_ctx.alias,
8430 FN_FROM_IS_TMP | NO_FK_CHECKS);
8440 alter_ctx.table_name,
8442 alter_ctx.new_alias))
8445 (void) quick_rm_table(thd, new_db_type,
8446 alter_ctx.new_db, alter_ctx.new_alias, 0);
8448 (void) mysql_rename_table(old_db_type, alter_ctx.db, backup_name,
8449 alter_ctx.db, alter_ctx.alias,
8450 FN_FROM_IS_TMP | NO_FK_CHECKS);
8455 if (quick_rm_table(thd, old_db_type, alter_ctx.db, backup_name, FN_IS_TMP))
8467 if (thd->locked_tables_list.reopen_tables(thd))
8470 THD_STAGE_INFO(thd, stage_end);
8472 DBUG_EXECUTE_IF(
"sleep_alter_before_main_binlog", my_sleep(6000000););
8473 DEBUG_SYNC(thd,
"alter_table_before_main_binlog");
8475 ha_binlog_log_query(thd, create_info->db_type, LOGCOM_ALTER_TABLE,
8476 thd->query(), thd->query_length(),
8477 alter_ctx.db, alter_ctx.table_name);
8479 DBUG_ASSERT(!(mysql_bin_log.is_open() &&
8480 thd->is_current_stmt_binlog_format_row() &&
8481 (create_info->options & HA_LEX_CREATE_TMP_TABLE)));
8482 if (write_bin_log(thd,
true, thd->query(), thd->query_length()))
8485 if (ha_check_storage_engine_flag(old_db_type, HTON_FLUSH_AFTER_RENAME))
8494 alter_ctx.new_db, alter_ctx.new_name,
8497 intern_close_table(t_table);
8499 sql_print_warning(
"Could not open table %s.%s after rename\n",
8500 alter_ctx.new_db, alter_ctx.table_name);
8501 ha_flush_logs(old_db_type);
8503 table_list->table= NULL;
8504 query_cache_invalidate3(thd, table_list,
false);
8506 if (thd->locked_tables_mode == LTM_LOCK_TABLES ||
8507 thd->locked_tables_mode == LTM_PRELOCKED_UNDER_LOCK_TABLES)
8510 thd->mdl_context.release_all_locks_for_name(mdl_ticket);
8516 my_snprintf(alter_ctx.tmp_name,
sizeof(alter_ctx.tmp_name),
8518 (ulong) (copied + deleted), (ulong) deleted,
8519 (ulong) thd->get_stmt_da()->current_statement_warn_count());
8520 my_ok(thd, copied + deleted, 0L, alter_ctx.tmp_name);
8523 err_new_table_cleanup:
8527 close_temporary_table(thd, new_table,
true,
true);
8530 (
void) quick_rm_table(thd, new_db_type,
8531 alter_ctx.new_db, alter_ctx.tmp_name,
8532 (FN_IS_TMP | (no_ha_table ? NO_HA_TABLE : 0)));
8540 if (alter_ctx.error_if_not_empty &&
8541 thd->get_stmt_da()->current_row_for_warning())
8544 enum enum_mysql_timestamp_type t_type= MYSQL_TIMESTAMP_DATE;
8545 switch (alter_ctx.datetime_field->sql_type)
8547 case MYSQL_TYPE_DATE:
8548 case MYSQL_TYPE_NEWDATE:
8549 f_length= MAX_DATE_WIDTH;
8550 t_type= MYSQL_TIMESTAMP_DATE;
8552 case MYSQL_TYPE_DATETIME:
8553 case MYSQL_TYPE_DATETIME2:
8554 f_length= MAX_DATETIME_WIDTH;
8555 t_type= MYSQL_TIMESTAMP_DATETIME;
8562 bool save_abort_on_warning= thd->abort_on_warning;
8563 thd->abort_on_warning=
true;
8564 make_truncated_value_warning(thd, Sql_condition::WARN_LEVEL_WARN,
8567 alter_ctx.datetime_field->field_name);
8568 thd->abort_on_warning= save_abort_on_warning;
8580 thd->locked_tables_list.unlink_all_closed_tables(thd, NULL, 0);
8581 thd->mdl_context.release_all_locks_for_name(mdl_ticket);
8592 bool mysql_trans_prepare_alter_copy_data(THD *thd)
8594 DBUG_ENTER(
"mysql_prepare_alter_copy_data");
8611 bool mysql_trans_commit_alter_copy_data(THD *thd)
8614 DBUG_ENTER(
"mysql_commit_alter_copy_data");
8625 if (trans_commit_stmt(thd))
8627 if (trans_commit_implicit(thd))
8635 copy_data_between_tables(
TABLE *from,
TABLE *to,
8638 uint order_num,
ORDER *order,
8641 Alter_info::enum_enable_or_disable keys_onoff,
8646 ulong found_count,delete_count;
8647 THD *thd= current_thd;
8652 ha_rows examined_rows;
8654 bool auto_increment_field_copied= 0;
8655 sql_mode_t save_sql_mode;
8657 DBUG_ENTER(
"copy_data_between_tables");
8659 if (mysql_trans_prepare_alter_copy_data(thd))
8669 alter_table_manage_keys(to, from->file->indexes_are_disabled(), keys_onoff);
8672 thd->abort_on_warning= !ignore && thd->is_strict_mode();
8674 from->file->info(HA_STATUS_VARIABLE);
8677 save_sql_mode= thd->variables.sql_mode;
8682 for (
Field **ptr=to->field ; *ptr ; ptr++)
8687 if (*ptr == to->next_number_field)
8689 auto_increment_field_copied= TRUE;
8696 if (def->field == from->found_next_number_field)
8697 thd->variables.sql_mode|= MODE_NO_AUTO_VALUE_ON_ZERO;
8699 (copy_end++)->
set(*ptr,def->field,0);
8704 found_count=delete_count=0;
8708 if (to->s->primary_key != MAX_KEY && to->file->primary_key_is_clustered())
8710 char warn_buff[MYSQL_ERRMSG_SIZE];
8711 my_snprintf(warn_buff,
sizeof(warn_buff),
8712 "ORDER BY ignored as there is a user-defined clustered index"
8713 " in the table '%-.192s'", from->s->table_name.str);
8714 push_warning(thd, Sql_condition::WARN_LEVEL_WARN, ER_UNKNOWN_ERROR,
8720 MYF(MY_FAE | MY_ZEROFILL));
8721 memset(&tables, 0,
sizeof(tables));
8723 tables.alias= tables.table_name= from->s->table_name.str;
8724 tables.db= from->s->db.str;
8727 if (thd->lex->select_lex.setup_ref_array(thd, order_num) ||
8728 setup_order(thd, thd->lex->select_lex.ref_pointer_array,
8729 &tables, fields, all_fields, order))
8731 Filesort fsort(order, HA_POS_ERROR, NULL);
8732 if ((from->sort.found_records=
filesort(thd, from, &fsort,
8734 &examined_rows, &found_rows)) ==
8741 to->use_all_columns();
8742 if (init_read_record(&info, thd, from, (
SQL_SELECT *) 0, 1, 1, FALSE))
8748 to->file->extra(HA_EXTRA_IGNORE_DUP_KEY);
8749 thd->get_stmt_da()->reset_current_row_for_warning();
8751 set_column_defaults(to, create);
8753 while (!(error=info.read_record(&info)))
8757 thd->send_kill_message();
8762 if (alter_ctx->error_if_not_empty)
8767 if (to->next_number_field)
8769 if (auto_increment_field_copied)
8770 to->auto_increment_field_not_null= TRUE;
8772 to->next_number_field->reset();
8775 for (
Copy_field *copy_ptr=copy ; copy_ptr != copy_end ; copy_ptr++)
8777 copy_ptr->do_copy(copy_ptr);
8781 error=to->file->ha_write_row(to->record[0]);
8782 to->auto_increment_field_not_null= FALSE;
8803 my_error(ER_FK_CANNOT_DELETE_PARENT, MYF(0),
8812 to->file->restore_auto_increment(prev_insert_id);
8819 if ((
int) key_nr >= 0)
8821 const char *err_msg= ER(ER_DUP_ENTRY_WITH_KEY_NAME);
8823 (to->key_info[0].key_part[0].field->flags &
8824 AUTO_INCREMENT_FLAG))
8825 err_msg= ER(ER_DUP_ENTRY_AUTOINCREMENT_CASE);
8827 &to->key_info[key_nr],
8838 thd->get_stmt_da()->inc_current_row_for_warning();
8840 end_read_record(&info);
8841 free_io_cache(from);
8849 to->file->extra(HA_EXTRA_NO_IGNORE_DUP_KEY);
8851 if (mysql_trans_commit_alter_copy_data(thd))
8855 thd->variables.sql_mode= save_sql_mode;
8856 thd->abort_on_warning= 0;
8857 free_io_cache(from);
8858 *copied= found_count;
8859 *deleted=delete_count;
8860 to->file->ha_release_auto_increment();
8863 if (error < 0 && to->file->extra(HA_EXTRA_PREPARE_FOR_RENAME))
8865 DBUG_RETURN(error > 0 ? -1 : 0);
8880 bool mysql_recreate_table(THD *thd,
TABLE_LIST *table_list)
8885 DBUG_ENTER(
"mysql_recreate_table");
8886 DBUG_ASSERT(!table_list->next_global);
8888 table_list->lock_type= TL_READ_NO_INSERT;
8890 table_list->mdl_request.
set_type(MDL_SHARED_NO_WRITE);
8892 memset(&create_info, 0,
sizeof(create_info));
8893 create_info.
row_type=ROW_TYPE_NOT_USED;
8894 create_info.default_table_charset=default_charset_info;
8896 alter_info.flags= (Alter_info::ALTER_CHANGE_COLUMN |
8897 Alter_info::ALTER_RECREATE);
8898 DBUG_RETURN(mysql_alter_table(thd, NullS, NullS, &create_info,
8899 table_list, &alter_info, 0,
8904 bool mysql_checksum_table(THD *thd,
TABLE_LIST *tables,
8911 DBUG_ENTER(
"mysql_checksum_table");
8917 DBUG_ASSERT(! thd->in_sub_stmt);
8920 item->maybe_null= 1;
8921 field_list.push_back(item=
new Item_int(NAME_STRING(
"Checksum"),
8923 MY_INT64_NUM_DECIMAL_DIGITS));
8924 item->maybe_null= 1;
8926 Protocol::SEND_NUM_ROWS | Protocol::SEND_EOF))
8933 close_thread_tables(thd);
8934 for (table= tables;
table; table= table->next_local)
8938 for (table= tables;
table; table= table->next_local)
8940 char table_name[NAME_LEN*2+2];
8944 strxmov(table_name, table->db ,
".", table->table_name, NullS);
8947 save_next_global= table->next_global;
8948 table->next_global= NULL;
8949 table->lock_type= TL_READ;
8951 table->required_type= FRMTYPE_TABLE;
8961 table->next_global= save_next_global;
8963 protocol->prepare_for_resend();
8964 protocol->
store(table_name, system_charset_info);
8969 protocol->store_null();
8974 !(check_opt->flags & T_EXTEND))
8975 protocol->
store((ulonglong)t->file->checksum());
8977 (check_opt->flags & T_QUICK))
8978 protocol->store_null();
8983 uchar null_mask=256 - (1 << t->s->last_null_bit_pos);
8985 t->use_all_columns();
8988 protocol->store_null();
9000 thd->protocol->remove_last_row();
9003 ha_checksum row_crc= 0;
9005 if (unlikely(error))
9007 if (error == HA_ERR_RECORD_DELETED)
9011 if (t->s->null_bytes)
9014 t->record[0][t->s->null_bytes-1] |= null_mask;
9015 if (!(t->s->db_create_options & HA_OPTION_PACK_RECORD))
9016 t->record[0][0] |= 1;
9018 row_crc= my_checksum(row_crc, t->record[0], t->s->null_bytes);
9021 for (uint i= 0; i < t->s->fields; i++ )
9030 switch (f->type()) {
9031 case MYSQL_TYPE_BLOB:
9032 case MYSQL_TYPE_VARCHAR:
9033 case MYSQL_TYPE_GEOMETRY:
9034 case MYSQL_TYPE_BIT:
9038 row_crc= my_checksum(row_crc, (uchar*) tmp.ptr(),
9043 row_crc= my_checksum(row_crc, f->ptr, f->pack_length());
9050 protocol->
store((ulonglong)crc);
9054 trans_rollback_stmt(thd);
9055 close_thread_tables(thd);
9058 if (thd->transaction_rollback_request)
9065 thd->protocol->remove_last_row();
9072 if (protocol->write())
9098 static bool check_engine(THD *thd,
const char *db_name,
9101 DBUG_ENTER(
"check_engine");
9102 handlerton **new_engine= &create_info->db_type;
9104 bool no_substitution=
9105 test(thd->variables.sql_mode & MODE_NO_ENGINE_SUBSTITUTION);
9106 if (!(*new_engine=
ha_checktype(thd, ha_legacy_type(req_engine),
9107 no_substitution, 1)))
9110 if (req_engine && req_engine != *new_engine)
9112 push_warning_printf(thd, Sql_condition::WARN_LEVEL_NOTE,
9113 ER_WARN_USING_OTHER_HANDLER,
9114 ER(ER_WARN_USING_OTHER_HANDLER),
9115 ha_resolve_storage_engine_name(*new_engine),
9118 if (create_info->options & HA_LEX_CREATE_TMP_TABLE &&
9119 ha_check_storage_engine_flag(*new_engine, HTON_TEMPORARY_NOT_SUPPORTED))
9121 if (create_info->used_fields & HA_CREATE_USED_ENGINE)
9123 my_error(ER_ILLEGAL_HA_CREATE_OPTION, MYF(0),
9124 ha_resolve_storage_engine_name(*new_engine),
"TEMPORARY");
9128 *new_engine= myisam_hton;
9135 if ((create_info->used_fields & HA_CREATE_USED_ENGINE) &&
9138 my_error(ER_UNSUPPORTED_ENGINE, MYF(0),
9139 ha_resolve_storage_engine_name(*new_engine), db_name, table_name);