mirror of
https://github.com/MariaDB/server.git
synced 2025-07-30 16:24:05 +03:00
smarter ALTER TABLE - don't copy the table if only comment or default values are changed
sql/handler.cc: do not delete the table in the "unkonwn" handler (makes no sense anyway) sql/handler.h: more HA_CREATE_USED flags sql/sql_lex.h: more ALTER_ flags, no alter_info->is_simple anymore sql/sql_parse.cc: no alter_info->is_simple anymore sql/sql_table.cc: do not rename the table in the "unkonwn" handler (makes no sense anyway) smarter ALTER TABLE - don't copy the table if only comment or default values are changed sql/sql_yacc.yy: specify what ALTER is todo with flags, not alter_info->is_simple sql/unireg.cc: create frm only (but not in the handler) if requested
This commit is contained in:
@ -785,7 +785,7 @@ bool ha_flush_logs()
|
|||||||
int ha_delete_table(enum db_type table_type, const char *path)
|
int ha_delete_table(enum db_type table_type, const char *path)
|
||||||
{
|
{
|
||||||
char tmp_path[FN_REFLEN];
|
char tmp_path[FN_REFLEN];
|
||||||
handler *file=get_new_handler((TABLE*) 0, table_type);
|
handler *file=(table_type== DB_TYPE_UNKNOWN ? 0 : get_new_handler((TABLE*) 0, table_type));
|
||||||
if (!file)
|
if (!file)
|
||||||
return ENOENT;
|
return ENOENT;
|
||||||
if (lower_case_table_names == 2 && !(file->table_flags() & HA_FILE_BASED))
|
if (lower_case_table_names == 2 && !(file->table_flags() & HA_FILE_BASED))
|
||||||
|
@ -139,16 +139,16 @@
|
|||||||
#define HA_CACHE_TBL_TRANSACT 4
|
#define HA_CACHE_TBL_TRANSACT 4
|
||||||
|
|
||||||
|
|
||||||
enum db_type
|
enum db_type
|
||||||
{
|
{
|
||||||
DB_TYPE_UNKNOWN=0,DB_TYPE_DIAB_ISAM=1,
|
DB_TYPE_UNKNOWN=0,DB_TYPE_DIAB_ISAM=1,
|
||||||
DB_TYPE_HASH,DB_TYPE_MISAM,DB_TYPE_PISAM,
|
DB_TYPE_HASH,DB_TYPE_MISAM,DB_TYPE_PISAM,
|
||||||
DB_TYPE_RMS_ISAM, DB_TYPE_HEAP, DB_TYPE_ISAM,
|
DB_TYPE_RMS_ISAM, DB_TYPE_HEAP, DB_TYPE_ISAM,
|
||||||
DB_TYPE_MRG_ISAM, DB_TYPE_MYISAM, DB_TYPE_MRG_MYISAM,
|
DB_TYPE_MRG_ISAM, DB_TYPE_MYISAM, DB_TYPE_MRG_MYISAM,
|
||||||
DB_TYPE_BERKELEY_DB, DB_TYPE_INNODB,
|
DB_TYPE_BERKELEY_DB, DB_TYPE_INNODB,
|
||||||
DB_TYPE_GEMINI, DB_TYPE_NDBCLUSTER,
|
DB_TYPE_GEMINI, DB_TYPE_NDBCLUSTER,
|
||||||
DB_TYPE_EXAMPLE_DB, DB_TYPE_ARCHIVE_DB, DB_TYPE_CSV_DB,
|
DB_TYPE_EXAMPLE_DB, DB_TYPE_ARCHIVE_DB, DB_TYPE_CSV_DB,
|
||||||
|
|
||||||
DB_TYPE_DEFAULT // Must be last
|
DB_TYPE_DEFAULT // Must be last
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -165,16 +165,24 @@ enum row_type { ROW_TYPE_NOT_USED=-1, ROW_TYPE_DEFAULT, ROW_TYPE_FIXED,
|
|||||||
/* struct to hold information about the table that should be created */
|
/* struct to hold information about the table that should be created */
|
||||||
|
|
||||||
/* Bits in used_fields */
|
/* Bits in used_fields */
|
||||||
#define HA_CREATE_USED_AUTO 1
|
#define HA_CREATE_USED_AUTO (1L << 0)
|
||||||
#define HA_CREATE_USED_RAID 2
|
#define HA_CREATE_USED_RAID (1L << 1)
|
||||||
#define HA_CREATE_USED_UNION 4
|
#define HA_CREATE_USED_UNION (1L << 2)
|
||||||
#define HA_CREATE_USED_INSERT_METHOD 8
|
#define HA_CREATE_USED_INSERT_METHOD (1L << 3)
|
||||||
#define HA_CREATE_USED_MIN_ROWS 16
|
#define HA_CREATE_USED_MIN_ROWS (1L << 4)
|
||||||
#define HA_CREATE_USED_MAX_ROWS 32
|
#define HA_CREATE_USED_MAX_ROWS (1L << 5)
|
||||||
#define HA_CREATE_USED_AVG_ROW_LENGTH 64
|
#define HA_CREATE_USED_AVG_ROW_LENGTH (1L << 6)
|
||||||
#define HA_CREATE_USED_PACK_KEYS 128
|
#define HA_CREATE_USED_PACK_KEYS (1L << 7)
|
||||||
#define HA_CREATE_USED_CHARSET 256
|
#define HA_CREATE_USED_CHARSET (1L << 8)
|
||||||
#define HA_CREATE_USED_DEFAULT_CHARSET 512
|
#define HA_CREATE_USED_DEFAULT_CHARSET (1L << 9)
|
||||||
|
#define HA_CREATE_USED_DATADIR (1L << 10)
|
||||||
|
#define HA_CREATE_USED_INDEXDIR (1L << 11)
|
||||||
|
#define HA_CREATE_USED_ENGINE (1L << 12)
|
||||||
|
#define HA_CREATE_USED_CHECKSUM (1L << 13)
|
||||||
|
#define HA_CREATE_USED_DELAY_KEY_WRITE (1L << 14)
|
||||||
|
#define HA_CREATE_USED_ROW_FORMAT (1L << 15)
|
||||||
|
#define HA_CREATE_USED_COMMENT (1L << 16)
|
||||||
|
#define HA_CREATE_USED_PASSWORD (1L << 17)
|
||||||
|
|
||||||
typedef struct st_thd_trans {
|
typedef struct st_thd_trans {
|
||||||
void *bdb_tid;
|
void *bdb_tid;
|
||||||
@ -205,6 +213,7 @@ typedef struct st_ha_create_information
|
|||||||
uint raid_type,raid_chunks;
|
uint raid_type,raid_chunks;
|
||||||
uint merge_insert_method;
|
uint merge_insert_method;
|
||||||
bool table_existed; /* 1 in create if table existed */
|
bool table_existed; /* 1 in create if table existed */
|
||||||
|
bool frm_only; /* 1 if no ha_create_table() */
|
||||||
} HA_CREATE_INFO;
|
} HA_CREATE_INFO;
|
||||||
|
|
||||||
|
|
||||||
|
@ -593,6 +593,9 @@ typedef class st_select_lex SELECT_LEX;
|
|||||||
#define ALTER_RENAME 32
|
#define ALTER_RENAME 32
|
||||||
#define ALTER_ORDER 64
|
#define ALTER_ORDER 64
|
||||||
#define ALTER_OPTIONS 128
|
#define ALTER_OPTIONS 128
|
||||||
|
#define ALTER_CHANGE_COLUMN_DEFAULT 256
|
||||||
|
#define ALTER_KEYS_ONOFF 512
|
||||||
|
#define ALTER_CONVERT 1024
|
||||||
|
|
||||||
typedef struct st_alter_info
|
typedef struct st_alter_info
|
||||||
{
|
{
|
||||||
@ -601,7 +604,6 @@ typedef struct st_alter_info
|
|||||||
uint flags;
|
uint flags;
|
||||||
enum enum_enable_or_disable keys_onoff;
|
enum enum_enable_or_disable keys_onoff;
|
||||||
enum tablespace_op_type tablespace_op;
|
enum tablespace_op_type tablespace_op;
|
||||||
bool is_simple;
|
|
||||||
|
|
||||||
st_alter_info(){clear();}
|
st_alter_info(){clear();}
|
||||||
void clear(){keys_onoff= LEAVE_AS_IS;tablespace_op= NO_TABLESPACE_OP;}
|
void clear(){keys_onoff= LEAVE_AS_IS;tablespace_op= NO_TABLESPACE_OP;}
|
||||||
|
@ -5862,7 +5862,6 @@ int mysql_create_index(THD *thd, TABLE_LIST *table_list, List<Key> &keys)
|
|||||||
List<create_field> fields;
|
List<create_field> fields;
|
||||||
ALTER_INFO alter_info;
|
ALTER_INFO alter_info;
|
||||||
alter_info.flags= ALTER_ADD_INDEX;
|
alter_info.flags= ALTER_ADD_INDEX;
|
||||||
alter_info.is_simple= 0;
|
|
||||||
HA_CREATE_INFO create_info;
|
HA_CREATE_INFO create_info;
|
||||||
DBUG_ENTER("mysql_create_index");
|
DBUG_ENTER("mysql_create_index");
|
||||||
bzero((char*) &create_info,sizeof(create_info));
|
bzero((char*) &create_info,sizeof(create_info));
|
||||||
@ -5886,7 +5885,6 @@ int mysql_drop_index(THD *thd, TABLE_LIST *table_list, ALTER_INFO *alter_info)
|
|||||||
create_info.default_table_charset= thd->variables.collation_database;
|
create_info.default_table_charset= thd->variables.collation_database;
|
||||||
alter_info->clear();
|
alter_info->clear();
|
||||||
alter_info->flags= ALTER_DROP_INDEX;
|
alter_info->flags= ALTER_DROP_INDEX;
|
||||||
alter_info->is_simple= 0;
|
|
||||||
DBUG_RETURN(mysql_alter_table(thd,table_list->db,table_list->real_name,
|
DBUG_RETURN(mysql_alter_table(thd,table_list->db,table_list->real_name,
|
||||||
&create_info, table_list,
|
&create_info, table_list,
|
||||||
fields, keys, 0, (ORDER*)0,
|
fields, keys, 0, (ORDER*)0,
|
||||||
|
122
sql/sql_table.cc
122
sql/sql_table.cc
@ -1093,7 +1093,7 @@ int mysql_prepare_table(THD *thd, HA_CREATE_INFO *create_info,
|
|||||||
(From ALTER TABLE)
|
(From ALTER TABLE)
|
||||||
|
|
||||||
DESCRIPTION
|
DESCRIPTION
|
||||||
If one creates a temporary table, this is automaticly opened
|
If one creates a temporary table, this is automatically opened
|
||||||
|
|
||||||
no_log is needed for the case of CREATE ... SELECT,
|
no_log is needed for the case of CREATE ... SELECT,
|
||||||
as the logging will be done later in sql_insert.cc
|
as the logging will be done later in sql_insert.cc
|
||||||
@ -1424,11 +1424,12 @@ mysql_rename_table(enum db_type base,
|
|||||||
{
|
{
|
||||||
char from[FN_REFLEN], to[FN_REFLEN];
|
char from[FN_REFLEN], to[FN_REFLEN];
|
||||||
char tmp_from[NAME_LEN+1], tmp_to[NAME_LEN+1];
|
char tmp_from[NAME_LEN+1], tmp_to[NAME_LEN+1];
|
||||||
handler *file=get_new_handler((TABLE*) 0, base);
|
handler *file=(base == DB_TYPE_UNKNOWN ? 0 : get_new_handler((TABLE*) 0, base));
|
||||||
int error=0;
|
int error=0;
|
||||||
DBUG_ENTER("mysql_rename_table");
|
DBUG_ENTER("mysql_rename_table");
|
||||||
|
|
||||||
if (lower_case_table_names == 2 && !(file->table_flags() & HA_FILE_BASED))
|
if (lower_case_table_names == 2 && file &&
|
||||||
|
!(file->table_flags() & HA_FILE_BASED))
|
||||||
{
|
{
|
||||||
/* Table handler expects to get all file names as lower case */
|
/* Table handler expects to get all file names as lower case */
|
||||||
strmov(tmp_from, old_name);
|
strmov(tmp_from, old_name);
|
||||||
@ -1446,13 +1447,15 @@ mysql_rename_table(enum db_type base,
|
|||||||
fn_format(from,from,"","",4);
|
fn_format(from,from,"","",4);
|
||||||
fn_format(to,to, "","",4);
|
fn_format(to,to, "","",4);
|
||||||
|
|
||||||
if (!(error=file->rename_table((const char*) from,(const char *) to)))
|
if (!file ||
|
||||||
|
!(error=file->rename_table((const char*) from,(const char *) to)))
|
||||||
{
|
{
|
||||||
if (rename_file_ext(from,to,reg_ext))
|
if (rename_file_ext(from,to,reg_ext))
|
||||||
{
|
{
|
||||||
error=my_errno;
|
error=my_errno;
|
||||||
/* Restore old file name */
|
/* Restore old file name */
|
||||||
file->rename_table((const char*) to,(const char *) from);
|
if (file)
|
||||||
|
file->rename_table((const char*) to,(const char *) from);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
delete file;
|
delete file;
|
||||||
@ -2536,7 +2539,7 @@ int mysql_alter_table(THD *thd,char *new_db, char *new_name,
|
|||||||
enum enum_duplicates handle_duplicates,
|
enum enum_duplicates handle_duplicates,
|
||||||
ALTER_INFO *alter_info, bool do_send_ok)
|
ALTER_INFO *alter_info, bool do_send_ok)
|
||||||
{
|
{
|
||||||
TABLE *table,*new_table;
|
TABLE *table,*new_table=0;
|
||||||
int error;
|
int error;
|
||||||
char tmp_name[80],old_name[32],new_name_buff[FN_REFLEN];
|
char tmp_name[80],old_name[32],new_name_buff[FN_REFLEN];
|
||||||
char new_alias_buff[FN_REFLEN], *table_name, *db, *new_alias, *alias;
|
char new_alias_buff[FN_REFLEN], *table_name, *db, *new_alias, *alias;
|
||||||
@ -2545,6 +2548,7 @@ int mysql_alter_table(THD *thd,char *new_db, char *new_name,
|
|||||||
ulonglong next_insert_id;
|
ulonglong next_insert_id;
|
||||||
uint db_create_options, used_fields;
|
uint db_create_options, used_fields;
|
||||||
enum db_type old_db_type,new_db_type;
|
enum db_type old_db_type,new_db_type;
|
||||||
|
bool need_copy_table;
|
||||||
DBUG_ENTER("mysql_alter_table");
|
DBUG_ENTER("mysql_alter_table");
|
||||||
|
|
||||||
thd->proc_info="init";
|
thd->proc_info="init";
|
||||||
@ -2633,7 +2637,8 @@ int mysql_alter_table(THD *thd,char *new_db, char *new_name,
|
|||||||
create_info->row_type=table->row_type;
|
create_info->row_type=table->row_type;
|
||||||
|
|
||||||
thd->proc_info="setup";
|
thd->proc_info="setup";
|
||||||
if (alter_info->is_simple && !table->tmp_table)
|
if (!(alter_info->flags & ~(ALTER_RENAME | ALTER_KEYS_ONOFF)) &&
|
||||||
|
!table->tmp_table) // no need to touch frm
|
||||||
{
|
{
|
||||||
error=0;
|
error=0;
|
||||||
if (new_name != table_name || new_db != db)
|
if (new_name != table_name || new_db != db)
|
||||||
@ -2661,23 +2666,24 @@ int mysql_alter_table(THD *thd,char *new_db, char *new_name,
|
|||||||
{
|
{
|
||||||
switch (alter_info->keys_onoff) {
|
switch (alter_info->keys_onoff) {
|
||||||
case LEAVE_AS_IS:
|
case LEAVE_AS_IS:
|
||||||
break;
|
break;
|
||||||
case ENABLE:
|
case ENABLE:
|
||||||
VOID(pthread_mutex_lock(&LOCK_open));
|
VOID(pthread_mutex_lock(&LOCK_open));
|
||||||
wait_while_table_is_used(thd, table, HA_EXTRA_FORCE_REOPEN);
|
wait_while_table_is_used(thd, table, HA_EXTRA_FORCE_REOPEN);
|
||||||
VOID(pthread_mutex_unlock(&LOCK_open));
|
VOID(pthread_mutex_unlock(&LOCK_open));
|
||||||
error= table->file->enable_indexes(HA_KEY_SWITCH_NONUNIQ_SAVE);
|
error= table->file->enable_indexes(HA_KEY_SWITCH_NONUNIQ_SAVE);
|
||||||
/* COND_refresh will be signaled in close_thread_tables() */
|
/* COND_refresh will be signaled in close_thread_tables() */
|
||||||
break;
|
break;
|
||||||
case DISABLE:
|
case DISABLE:
|
||||||
VOID(pthread_mutex_lock(&LOCK_open));
|
VOID(pthread_mutex_lock(&LOCK_open));
|
||||||
wait_while_table_is_used(thd, table, HA_EXTRA_FORCE_REOPEN);
|
wait_while_table_is_used(thd, table, HA_EXTRA_FORCE_REOPEN);
|
||||||
VOID(pthread_mutex_unlock(&LOCK_open));
|
VOID(pthread_mutex_unlock(&LOCK_open));
|
||||||
error=table->file->disable_indexes(HA_KEY_SWITCH_NONUNIQ_SAVE);
|
error=table->file->disable_indexes(HA_KEY_SWITCH_NONUNIQ_SAVE);
|
||||||
/* COND_refresh will be signaled in close_thread_tables() */
|
/* COND_refresh will be signaled in close_thread_tables() */
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (error == HA_ERR_WRONG_COMMAND)
|
if (error == HA_ERR_WRONG_COMMAND)
|
||||||
{
|
{
|
||||||
push_warning_printf(thd, MYSQL_ERROR::WARN_LEVEL_NOTE,
|
push_warning_printf(thd, MYSQL_ERROR::WARN_LEVEL_NOTE,
|
||||||
@ -2708,7 +2714,7 @@ int mysql_alter_table(THD *thd,char *new_db, char *new_name,
|
|||||||
|
|
||||||
/* Full alter table */
|
/* Full alter table */
|
||||||
|
|
||||||
/* let new create options override the old ones */
|
/* Let new create options override the old ones */
|
||||||
if (!(used_fields & HA_CREATE_USED_MIN_ROWS))
|
if (!(used_fields & HA_CREATE_USED_MIN_ROWS))
|
||||||
create_info->min_rows=table->min_rows;
|
create_info->min_rows=table->min_rows;
|
||||||
if (!(used_fields & HA_CREATE_USED_MAX_ROWS))
|
if (!(used_fields & HA_CREATE_USED_MAX_ROWS))
|
||||||
@ -2968,6 +2974,16 @@ int mysql_alter_table(THD *thd,char *new_db, char *new_name,
|
|||||||
if (table->tmp_table)
|
if (table->tmp_table)
|
||||||
create_info->options|=HA_LEX_CREATE_TMP_TABLE;
|
create_info->options|=HA_LEX_CREATE_TMP_TABLE;
|
||||||
|
|
||||||
|
/*
|
||||||
|
better have a negative test here, instead of positive, like
|
||||||
|
alter_info->flags & ALTER_ADD_COLUMN|ALTER_ADD_INDEX|...
|
||||||
|
so that ALTER TABLE won't break when somebody will add new flag
|
||||||
|
*/
|
||||||
|
need_copy_table=(alter_info->flags & ~(ALTER_CHANGE_COLUMN_DEFAULT|ALTER_OPTIONS) ||
|
||||||
|
create_info->used_fields & ~(HA_CREATE_USED_COMMENT|HA_CREATE_USED_PASSWORD) ||
|
||||||
|
table->tmp_table);
|
||||||
|
create_info->frm_only= !need_copy_table;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
Handling of symlinked tables:
|
Handling of symlinked tables:
|
||||||
If no rename:
|
If no rename:
|
||||||
@ -3022,45 +3038,49 @@ int mysql_alter_table(THD *thd,char *new_db, char *new_name,
|
|||||||
create_list,key_list,1,0)))
|
create_list,key_list,1,0)))
|
||||||
DBUG_RETURN(error);
|
DBUG_RETURN(error);
|
||||||
}
|
}
|
||||||
if (table->tmp_table)
|
if (need_copy_table)
|
||||||
{
|
{
|
||||||
TABLE_LIST tbl;
|
if (table->tmp_table)
|
||||||
bzero((void*) &tbl, sizeof(tbl));
|
{
|
||||||
tbl.db= new_db;
|
TABLE_LIST tbl;
|
||||||
tbl.real_name= tbl.alias= tmp_name;
|
bzero((void*) &tbl, sizeof(tbl));
|
||||||
new_table= open_table(thd, &tbl, &thd->mem_root, 0);
|
tbl.db= new_db;
|
||||||
|
tbl.real_name= tbl.alias= tmp_name;
|
||||||
|
new_table= open_table(thd, &tbl, &thd->mem_root, 0);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
char path[FN_REFLEN];
|
||||||
|
my_snprintf(path, sizeof(path), "%s/%s/%s", mysql_data_home,
|
||||||
|
new_db, tmp_name);
|
||||||
|
fn_format(path,path,"","",4);
|
||||||
|
new_table=open_temporary_table(thd, path, new_db, tmp_name,0);
|
||||||
|
}
|
||||||
|
if (!new_table)
|
||||||
|
{
|
||||||
|
VOID(quick_rm_table(new_db_type,new_db,tmp_name));
|
||||||
|
goto err;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else
|
|
||||||
{
|
|
||||||
char path[FN_REFLEN];
|
|
||||||
my_snprintf(path, sizeof(path), "%s/%s/%s", mysql_data_home,
|
|
||||||
new_db, tmp_name);
|
|
||||||
fn_format(path,path,"","",4);
|
|
||||||
new_table=open_temporary_table(thd, path, new_db, tmp_name,0);
|
|
||||||
}
|
|
||||||
if (!new_table)
|
|
||||||
{
|
|
||||||
VOID(quick_rm_table(new_db_type,new_db,tmp_name));
|
|
||||||
goto err;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
We don't want update TIMESTAMP fields during ALTER TABLE
|
We don't want update TIMESTAMP fields during ALTER TABLE
|
||||||
and copy_data_between_tables uses only write_row() for new_table so
|
and copy_data_between_tables uses only write_row() for new_table so
|
||||||
don't need to set up timestamp_on_update_now member.
|
don't need to set up timestamp_on_update_now member.
|
||||||
*/
|
*/
|
||||||
new_table->timestamp_default_now= 0;
|
|
||||||
new_table->next_number_field=new_table->found_next_number_field;
|
|
||||||
thd->count_cuted_fields= CHECK_FIELD_WARN; // calc cuted fields
|
thd->count_cuted_fields= CHECK_FIELD_WARN; // calc cuted fields
|
||||||
thd->cuted_fields=0L;
|
thd->cuted_fields=0L;
|
||||||
thd->proc_info="copy to tmp table";
|
thd->proc_info="copy to tmp table";
|
||||||
next_insert_id=thd->next_insert_id; // Remember for loggin
|
next_insert_id=thd->next_insert_id; // Remember for logging
|
||||||
copied=deleted=0;
|
copied=deleted=0;
|
||||||
if (!new_table->is_view)
|
if (new_table && !new_table->is_view)
|
||||||
|
{
|
||||||
|
new_table->timestamp_default_now= 0;
|
||||||
|
new_table->next_number_field=new_table->found_next_number_field;
|
||||||
error=copy_data_between_tables(table,new_table,create_list,
|
error=copy_data_between_tables(table,new_table,create_list,
|
||||||
handle_duplicates,
|
handle_duplicates,
|
||||||
order_num, order, &copied, &deleted);
|
order_num, order, &copied, &deleted);
|
||||||
|
}
|
||||||
thd->last_insert_id=next_insert_id; // Needed for correct log
|
thd->last_insert_id=next_insert_id; // Needed for correct log
|
||||||
thd->count_cuted_fields= CHECK_FIELD_IGNORE;
|
thd->count_cuted_fields= CHECK_FIELD_IGNORE;
|
||||||
|
|
||||||
@ -3099,8 +3119,11 @@ int mysql_alter_table(THD *thd,char *new_db, char *new_name,
|
|||||||
goto end_temporary;
|
goto end_temporary;
|
||||||
}
|
}
|
||||||
|
|
||||||
intern_close_table(new_table); /* close temporary table */
|
if (new_table)
|
||||||
my_free((gptr) new_table,MYF(0));
|
{
|
||||||
|
intern_close_table(new_table); /* close temporary table */
|
||||||
|
my_free((gptr) new_table,MYF(0));
|
||||||
|
}
|
||||||
VOID(pthread_mutex_lock(&LOCK_open));
|
VOID(pthread_mutex_lock(&LOCK_open));
|
||||||
if (error)
|
if (error)
|
||||||
{
|
{
|
||||||
@ -3112,7 +3135,7 @@ int mysql_alter_table(THD *thd,char *new_db, char *new_name,
|
|||||||
/*
|
/*
|
||||||
Data is copied. Now we rename the old table to a temp name,
|
Data is copied. Now we rename the old table to a temp name,
|
||||||
rename the new one to the old name, remove all entries from the old table
|
rename the new one to the old name, remove all entries from the old table
|
||||||
from the cash, free all locks, close the old table and remove it.
|
from the cache, free all locks, close the old table and remove it.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
thd->proc_info="rename result table";
|
thd->proc_info="rename result table";
|
||||||
@ -3151,6 +3174,8 @@ int mysql_alter_table(THD *thd,char *new_db, char *new_name,
|
|||||||
|
|
||||||
|
|
||||||
error=0;
|
error=0;
|
||||||
|
if (!need_copy_table)
|
||||||
|
new_db_type=old_db_type=DB_TYPE_UNKNOWN; // this type cannot happen in regular ALTER
|
||||||
if (mysql_rename_table(old_db_type,db,table_name,db,old_name))
|
if (mysql_rename_table(old_db_type,db,table_name,db,old_name))
|
||||||
{
|
{
|
||||||
error=1;
|
error=1;
|
||||||
@ -3443,7 +3468,6 @@ int mysql_recreate_table(THD *thd, TABLE_LIST *table_list,
|
|||||||
lex->key_list.empty();
|
lex->key_list.empty();
|
||||||
lex->col_list.empty();
|
lex->col_list.empty();
|
||||||
lex->alter_info.reset();
|
lex->alter_info.reset();
|
||||||
lex->alter_info.is_simple= 0; // Force full recreate
|
|
||||||
bzero((char*) &create_info,sizeof(create_info));
|
bzero((char*) &create_info,sizeof(create_info));
|
||||||
create_info.db_type=DB_TYPE_DEFAULT;
|
create_info.db_type=DB_TYPE_DEFAULT;
|
||||||
create_info.row_type=ROW_TYPE_DEFAULT;
|
create_info.row_type=ROW_TYPE_DEFAULT;
|
||||||
|
@ -2499,19 +2499,19 @@ create_table_options:
|
|||||||
| create_table_option ',' create_table_options;
|
| create_table_option ',' create_table_options;
|
||||||
|
|
||||||
create_table_option:
|
create_table_option:
|
||||||
ENGINE_SYM opt_equal storage_engines { Lex->create_info.db_type= $3; }
|
ENGINE_SYM opt_equal storage_engines { Lex->create_info.db_type= $3; Lex->create_info.used_fields|= HA_CREATE_USED_ENGINE; }
|
||||||
| TYPE_SYM opt_equal storage_engines { Lex->create_info.db_type= $3; WARN_DEPRECATED("TYPE=storage_engine","ENGINE=storage_engine"); }
|
| TYPE_SYM opt_equal storage_engines { Lex->create_info.db_type= $3; WARN_DEPRECATED("TYPE=storage_engine","ENGINE=storage_engine"); Lex->create_info.used_fields|= HA_CREATE_USED_ENGINE; }
|
||||||
| MAX_ROWS opt_equal ulonglong_num { Lex->create_info.max_rows= $3; Lex->create_info.used_fields|= HA_CREATE_USED_MAX_ROWS;}
|
| MAX_ROWS opt_equal ulonglong_num { Lex->create_info.max_rows= $3; Lex->create_info.used_fields|= HA_CREATE_USED_MAX_ROWS;}
|
||||||
| MIN_ROWS opt_equal ulonglong_num { Lex->create_info.min_rows= $3; Lex->create_info.used_fields|= HA_CREATE_USED_MIN_ROWS;}
|
| MIN_ROWS opt_equal ulonglong_num { Lex->create_info.min_rows= $3; Lex->create_info.used_fields|= HA_CREATE_USED_MIN_ROWS;}
|
||||||
| AVG_ROW_LENGTH opt_equal ULONG_NUM { Lex->create_info.avg_row_length=$3; Lex->create_info.used_fields|= HA_CREATE_USED_AVG_ROW_LENGTH;}
|
| AVG_ROW_LENGTH opt_equal ULONG_NUM { Lex->create_info.avg_row_length=$3; Lex->create_info.used_fields|= HA_CREATE_USED_AVG_ROW_LENGTH;}
|
||||||
| PASSWORD opt_equal TEXT_STRING_sys { Lex->create_info.password=$3.str; }
|
| PASSWORD opt_equal TEXT_STRING_sys { Lex->create_info.password=$3.str; Lex->create_info.used_fields|= HA_CREATE_USED_PASSWORD; }
|
||||||
| COMMENT_SYM opt_equal TEXT_STRING_sys { Lex->create_info.comment=$3.str; }
|
| COMMENT_SYM opt_equal TEXT_STRING_sys { Lex->create_info.comment=$3.str; Lex->create_info.used_fields|= HA_CREATE_USED_COMMENT; }
|
||||||
| AUTO_INC opt_equal ulonglong_num { Lex->create_info.auto_increment_value=$3; Lex->create_info.used_fields|= HA_CREATE_USED_AUTO;}
|
| AUTO_INC opt_equal ulonglong_num { Lex->create_info.auto_increment_value=$3; Lex->create_info.used_fields|= HA_CREATE_USED_AUTO;}
|
||||||
| PACK_KEYS_SYM opt_equal ULONG_NUM { Lex->create_info.table_options|= $3 ? HA_OPTION_PACK_KEYS : HA_OPTION_NO_PACK_KEYS; Lex->create_info.used_fields|= HA_CREATE_USED_PACK_KEYS;}
|
| PACK_KEYS_SYM opt_equal ULONG_NUM { Lex->create_info.table_options|= $3 ? HA_OPTION_PACK_KEYS : HA_OPTION_NO_PACK_KEYS; Lex->create_info.used_fields|= HA_CREATE_USED_PACK_KEYS;}
|
||||||
| PACK_KEYS_SYM opt_equal DEFAULT { Lex->create_info.table_options&= ~(HA_OPTION_PACK_KEYS | HA_OPTION_NO_PACK_KEYS); Lex->create_info.used_fields|= HA_CREATE_USED_PACK_KEYS;}
|
| PACK_KEYS_SYM opt_equal DEFAULT { Lex->create_info.table_options&= ~(HA_OPTION_PACK_KEYS | HA_OPTION_NO_PACK_KEYS); Lex->create_info.used_fields|= HA_CREATE_USED_PACK_KEYS;}
|
||||||
| CHECKSUM_SYM opt_equal ULONG_NUM { Lex->create_info.table_options|= $3 ? HA_OPTION_CHECKSUM : HA_OPTION_NO_CHECKSUM; }
|
| CHECKSUM_SYM opt_equal ULONG_NUM { Lex->create_info.table_options|= $3 ? HA_OPTION_CHECKSUM : HA_OPTION_NO_CHECKSUM; Lex->create_info.used_fields|= HA_CREATE_USED_CHECKSUM; }
|
||||||
| DELAY_KEY_WRITE_SYM opt_equal ULONG_NUM { Lex->create_info.table_options|= $3 ? HA_OPTION_DELAY_KEY_WRITE : HA_OPTION_NO_DELAY_KEY_WRITE; }
|
| DELAY_KEY_WRITE_SYM opt_equal ULONG_NUM { Lex->create_info.table_options|= $3 ? HA_OPTION_DELAY_KEY_WRITE : HA_OPTION_NO_DELAY_KEY_WRITE; Lex->create_info.used_fields|= HA_CREATE_USED_DELAY_KEY_WRITE; }
|
||||||
| ROW_FORMAT_SYM opt_equal row_types { Lex->create_info.row_type= $3; }
|
| ROW_FORMAT_SYM opt_equal row_types { Lex->create_info.row_type= $3; Lex->create_info.used_fields|= HA_CREATE_USED_ROW_FORMAT; }
|
||||||
| RAID_TYPE opt_equal raid_types { Lex->create_info.raid_type= $3; Lex->create_info.used_fields|= HA_CREATE_USED_RAID;}
|
| RAID_TYPE opt_equal raid_types { Lex->create_info.raid_type= $3; Lex->create_info.used_fields|= HA_CREATE_USED_RAID;}
|
||||||
| RAID_CHUNKS opt_equal ULONG_NUM { Lex->create_info.raid_chunks= $3; Lex->create_info.used_fields|= HA_CREATE_USED_RAID;}
|
| RAID_CHUNKS opt_equal ULONG_NUM { Lex->create_info.raid_chunks= $3; Lex->create_info.used_fields|= HA_CREATE_USED_RAID;}
|
||||||
| RAID_CHUNKSIZE opt_equal ULONG_NUM { Lex->create_info.raid_chunksize= $3*RAID_BLOCK_SIZE; Lex->create_info.used_fields|= HA_CREATE_USED_RAID;}
|
| RAID_CHUNKSIZE opt_equal ULONG_NUM { Lex->create_info.raid_chunksize= $3*RAID_BLOCK_SIZE; Lex->create_info.used_fields|= HA_CREATE_USED_RAID;}
|
||||||
@ -2533,9 +2533,9 @@ create_table_option:
|
|||||||
| default_charset
|
| default_charset
|
||||||
| default_collation
|
| default_collation
|
||||||
| INSERT_METHOD opt_equal merge_insert_types { Lex->create_info.merge_insert_method= $3; Lex->create_info.used_fields|= HA_CREATE_USED_INSERT_METHOD;}
|
| INSERT_METHOD opt_equal merge_insert_types { Lex->create_info.merge_insert_method= $3; Lex->create_info.used_fields|= HA_CREATE_USED_INSERT_METHOD;}
|
||||||
| DATA_SYM DIRECTORY_SYM opt_equal TEXT_STRING_sys
|
| DATA_SYM DIRECTORY_SYM opt_equal TEXT_STRING_sys { Lex->create_info.data_file_name= $4.str; Lex->create_info.used_fields|= HA_CREATE_USED_DATADIR; }
|
||||||
{ Lex->create_info.data_file_name= $4.str; }
|
| INDEX_SYM DIRECTORY_SYM opt_equal TEXT_STRING_sys { Lex->create_info.index_file_name= $4.str; Lex->create_info.used_fields|= HA_CREATE_USED_INDEXDIR; }
|
||||||
| INDEX_SYM DIRECTORY_SYM opt_equal TEXT_STRING_sys { Lex->create_info.index_file_name= $4.str; };
|
;
|
||||||
|
|
||||||
default_charset:
|
default_charset:
|
||||||
opt_default charset opt_equal charset_name_or_default
|
opt_default charset opt_equal charset_name_or_default
|
||||||
@ -3173,8 +3173,7 @@ alter:
|
|||||||
lex->create_info.db_type= DB_TYPE_DEFAULT;
|
lex->create_info.db_type= DB_TYPE_DEFAULT;
|
||||||
lex->create_info.default_table_charset= NULL;
|
lex->create_info.default_table_charset= NULL;
|
||||||
lex->create_info.row_type= ROW_TYPE_NOT_USED;
|
lex->create_info.row_type= ROW_TYPE_NOT_USED;
|
||||||
lex->alter_info.reset();
|
lex->alter_info.reset();
|
||||||
lex->alter_info.is_simple= 1;
|
|
||||||
lex->alter_info.flags= 0;
|
lex->alter_info.flags= 0;
|
||||||
}
|
}
|
||||||
alter_list
|
alter_list
|
||||||
@ -3241,27 +3240,27 @@ alter_list:
|
|||||||
| alter_list ',' alter_list_item;
|
| alter_list ',' alter_list_item;
|
||||||
|
|
||||||
add_column:
|
add_column:
|
||||||
ADD opt_column
|
ADD opt_column
|
||||||
{
|
{
|
||||||
LEX *lex=Lex;
|
LEX *lex=Lex;
|
||||||
lex->change=0;
|
lex->change=0;
|
||||||
lex->alter_info.flags|= ALTER_ADD_COLUMN;
|
lex->alter_info.flags|= ALTER_ADD_COLUMN;
|
||||||
};
|
};
|
||||||
|
|
||||||
alter_list_item:
|
alter_list_item:
|
||||||
add_column column_def opt_place { Lex->alter_info.is_simple= 0; }
|
add_column column_def opt_place { }
|
||||||
| ADD key_def
|
| ADD key_def
|
||||||
{
|
{
|
||||||
LEX *lex=Lex;
|
Lex->alter_info.flags|= ALTER_ADD_INDEX;
|
||||||
lex->alter_info.is_simple= 0;
|
|
||||||
lex->alter_info.flags|= ALTER_ADD_INDEX;
|
|
||||||
}
|
}
|
||||||
| add_column '(' field_list ')' { Lex->alter_info.is_simple= 0; }
|
| add_column '(' field_list ')'
|
||||||
|
{
|
||||||
|
Lex->alter_info.flags|= ALTER_ADD_COLUMN | ALTER_ADD_INDEX;
|
||||||
|
}
|
||||||
| CHANGE opt_column field_ident
|
| CHANGE opt_column field_ident
|
||||||
{
|
{
|
||||||
LEX *lex=Lex;
|
LEX *lex=Lex;
|
||||||
lex->change= $3.str;
|
lex->change= $3.str;
|
||||||
lex->alter_info.is_simple= 0;
|
|
||||||
lex->alter_info.flags|= ALTER_CHANGE_COLUMN;
|
lex->alter_info.flags|= ALTER_CHANGE_COLUMN;
|
||||||
}
|
}
|
||||||
field_spec opt_place
|
field_spec opt_place
|
||||||
@ -3272,7 +3271,6 @@ alter_list_item:
|
|||||||
lex->default_value= lex->on_update_value= 0;
|
lex->default_value= lex->on_update_value= 0;
|
||||||
lex->comment=0;
|
lex->comment=0;
|
||||||
lex->charset= NULL;
|
lex->charset= NULL;
|
||||||
lex->alter_info.is_simple= 0;
|
|
||||||
lex->alter_info.flags|= ALTER_CHANGE_COLUMN;
|
lex->alter_info.flags|= ALTER_CHANGE_COLUMN;
|
||||||
}
|
}
|
||||||
type opt_attribute
|
type opt_attribute
|
||||||
@ -3292,17 +3290,18 @@ alter_list_item:
|
|||||||
{
|
{
|
||||||
LEX *lex=Lex;
|
LEX *lex=Lex;
|
||||||
lex->alter_info.drop_list.push_back(new Alter_drop(Alter_drop::COLUMN,
|
lex->alter_info.drop_list.push_back(new Alter_drop(Alter_drop::COLUMN,
|
||||||
$3.str));
|
$3.str));
|
||||||
lex->alter_info.is_simple= 0;
|
|
||||||
lex->alter_info.flags|= ALTER_DROP_COLUMN;
|
lex->alter_info.flags|= ALTER_DROP_COLUMN;
|
||||||
}
|
}
|
||||||
| DROP FOREIGN KEY_SYM opt_ident { Lex->alter_info.is_simple= 0; }
|
| DROP FOREIGN KEY_SYM opt_ident
|
||||||
|
{
|
||||||
|
Lex->alter_info.flags|= ALTER_DROP_INDEX;
|
||||||
|
}
|
||||||
| DROP PRIMARY_SYM KEY_SYM
|
| DROP PRIMARY_SYM KEY_SYM
|
||||||
{
|
{
|
||||||
LEX *lex=Lex;
|
LEX *lex=Lex;
|
||||||
lex->alter_info.drop_list.push_back(new Alter_drop(Alter_drop::KEY,
|
lex->alter_info.drop_list.push_back(new Alter_drop(Alter_drop::KEY,
|
||||||
primary_key_name));
|
primary_key_name));
|
||||||
lex->alter_info.is_simple= 0;
|
|
||||||
lex->alter_info.flags|= ALTER_DROP_INDEX;
|
lex->alter_info.flags|= ALTER_DROP_INDEX;
|
||||||
}
|
}
|
||||||
| DROP key_or_index field_ident
|
| DROP key_or_index field_ident
|
||||||
@ -3310,25 +3309,32 @@ alter_list_item:
|
|||||||
LEX *lex=Lex;
|
LEX *lex=Lex;
|
||||||
lex->alter_info.drop_list.push_back(new Alter_drop(Alter_drop::KEY,
|
lex->alter_info.drop_list.push_back(new Alter_drop(Alter_drop::KEY,
|
||||||
$3.str));
|
$3.str));
|
||||||
lex->alter_info.is_simple= 0;
|
|
||||||
lex->alter_info.flags|= ALTER_DROP_INDEX;
|
lex->alter_info.flags|= ALTER_DROP_INDEX;
|
||||||
}
|
}
|
||||||
| DISABLE_SYM KEYS { Lex->alter_info.keys_onoff= DISABLE; }
|
| DISABLE_SYM KEYS
|
||||||
| ENABLE_SYM KEYS { Lex->alter_info.keys_onoff= ENABLE; }
|
{
|
||||||
|
LEX *lex=Lex;
|
||||||
|
lex->alter_info.keys_onoff= DISABLE;
|
||||||
|
lex->alter_info.flags|= ALTER_KEYS_ONOFF;
|
||||||
|
}
|
||||||
|
| ENABLE_SYM KEYS
|
||||||
|
{
|
||||||
|
LEX *lex=Lex;
|
||||||
|
lex->alter_info.keys_onoff= ENABLE;
|
||||||
|
lex->alter_info.flags|= ALTER_KEYS_ONOFF;
|
||||||
|
}
|
||||||
| ALTER opt_column field_ident SET DEFAULT signed_literal
|
| ALTER opt_column field_ident SET DEFAULT signed_literal
|
||||||
{
|
{
|
||||||
LEX *lex=Lex;
|
LEX *lex=Lex;
|
||||||
lex->alter_info.alter_list.push_back(new Alter_column($3.str,$6));
|
lex->alter_info.alter_list.push_back(new Alter_column($3.str,$6));
|
||||||
lex->alter_info.is_simple= 0;
|
lex->alter_info.flags|= ALTER_CHANGE_COLUMN_DEFAULT;
|
||||||
lex->alter_info.flags|= ALTER_CHANGE_COLUMN;
|
|
||||||
}
|
}
|
||||||
| ALTER opt_column field_ident DROP DEFAULT
|
| ALTER opt_column field_ident DROP DEFAULT
|
||||||
{
|
{
|
||||||
LEX *lex=Lex;
|
LEX *lex=Lex;
|
||||||
lex->alter_info.alter_list.push_back(new Alter_column($3.str,
|
lex->alter_info.alter_list.push_back(new Alter_column($3.str,
|
||||||
(Item*) 0));
|
(Item*) 0));
|
||||||
lex->alter_info.is_simple= 0;
|
lex->alter_info.flags|= ALTER_CHANGE_COLUMN_DEFAULT;
|
||||||
lex->alter_info.flags|= ALTER_CHANGE_COLUMN;
|
|
||||||
}
|
}
|
||||||
| RENAME opt_to table_ident
|
| RENAME opt_to table_ident
|
||||||
{
|
{
|
||||||
@ -3358,22 +3364,20 @@ alter_list_item:
|
|||||||
YYABORT;
|
YYABORT;
|
||||||
}
|
}
|
||||||
LEX *lex= Lex;
|
LEX *lex= Lex;
|
||||||
lex->create_info.table_charset=
|
lex->create_info.table_charset=
|
||||||
lex->create_info.default_table_charset= $5;
|
lex->create_info.default_table_charset= $5;
|
||||||
lex->create_info.used_fields|= (HA_CREATE_USED_CHARSET |
|
lex->create_info.used_fields|= (HA_CREATE_USED_CHARSET |
|
||||||
HA_CREATE_USED_DEFAULT_CHARSET);
|
HA_CREATE_USED_DEFAULT_CHARSET);
|
||||||
lex->alter_info.is_simple= 0;
|
lex->alter_info.flags|= ALTER_CONVERT;
|
||||||
}
|
}
|
||||||
| create_table_options_space_separated
|
| create_table_options_space_separated
|
||||||
{
|
{
|
||||||
LEX *lex=Lex;
|
LEX *lex=Lex;
|
||||||
lex->alter_info.is_simple= 0;
|
|
||||||
lex->alter_info.flags|= ALTER_OPTIONS;
|
lex->alter_info.flags|= ALTER_OPTIONS;
|
||||||
}
|
}
|
||||||
| order_clause
|
| order_clause
|
||||||
{
|
{
|
||||||
LEX *lex=Lex;
|
LEX *lex=Lex;
|
||||||
lex->alter_info.is_simple= 0;
|
|
||||||
lex->alter_info.flags|= ALTER_ORDER;
|
lex->alter_info.flags|= ALTER_ORDER;
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -3407,7 +3411,7 @@ opt_to:
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
slave:
|
slave:
|
||||||
START_SYM SLAVE slave_thread_opts
|
START_SYM SLAVE slave_thread_opts
|
||||||
{
|
{
|
||||||
LEX *lex=Lex;
|
LEX *lex=Lex;
|
||||||
lex->sql_command = SQLCOM_SLAVE_START;
|
lex->sql_command = SQLCOM_SLAVE_START;
|
||||||
|
@ -199,7 +199,7 @@ err3:
|
|||||||
keys number of keys to create
|
keys number of keys to create
|
||||||
key_info Keys to create
|
key_info Keys to create
|
||||||
db_file Handler to use. May be zero, in which case we use
|
db_file Handler to use. May be zero, in which case we use
|
||||||
create_info->db_type
|
create_info->db_type
|
||||||
RETURN
|
RETURN
|
||||||
0 ok
|
0 ok
|
||||||
1 error
|
1 error
|
||||||
@ -213,11 +213,11 @@ int rea_create_table(THD *thd, my_string file_name,
|
|||||||
DBUG_ENTER("rea_create_table");
|
DBUG_ENTER("rea_create_table");
|
||||||
|
|
||||||
if (mysql_create_frm(thd, file_name, create_info,
|
if (mysql_create_frm(thd, file_name, create_info,
|
||||||
create_fields, keys, key_info, NULL))
|
create_fields, keys, key_info, NULL))
|
||||||
DBUG_RETURN(1);
|
DBUG_RETURN(1);
|
||||||
if (ha_create_table(file_name,create_info,0))
|
if (!create_info->frm_only && ha_create_table(file_name,create_info,0))
|
||||||
{
|
{
|
||||||
my_delete(file_name,MYF(0));
|
my_delete(file_name,MYF(0));
|
||||||
DBUG_RETURN(1);
|
DBUG_RETURN(1);
|
||||||
}
|
}
|
||||||
DBUG_RETURN(0);
|
DBUG_RETURN(0);
|
||||||
|
Reference in New Issue
Block a user