mirror of
https://github.com/MariaDB/server.git
synced 2025-07-30 16:24:05 +03:00
Hand-resolved auto merge
BitKeeper/etc/ignore: auto-union sql/handler.h: Auto merged sql/mysql_priv.h: Auto merged sql/sql_base.cc: Auto merged sql/sql_lex.h: Auto merged sql/unireg.cc: Auto merged sql/sql_parse.cc: Auto merged sql/sql_table.cc: Hand-merged sql/sql_yacc.yy: Hand-merged
This commit is contained in:
@ -250,6 +250,7 @@ client/thimble
|
||||
client/thread_test
|
||||
client_test
|
||||
cmd-line-utils/libedit/common.h
|
||||
cmd-line-utils/libedit/makelist
|
||||
comon.h
|
||||
config.cache
|
||||
config.h
|
||||
@ -300,6 +301,7 @@ innobase/ib_config.h
|
||||
innobase/ib_config.h.in
|
||||
innobase/stamp-h1
|
||||
insert_test
|
||||
install
|
||||
isam/isamchk
|
||||
isam/isamlog
|
||||
isam/pack_isam
|
||||
@ -504,6 +506,7 @@ mysys/main.cc
|
||||
mysys/ste5KbMa
|
||||
mysys/test_charset
|
||||
mysys/test_dir
|
||||
mysys/test_gethwaddr
|
||||
mysys/test_io_cache
|
||||
mysys/test_thr_alarm
|
||||
mysys/test_thr_lock
|
||||
@ -646,5 +649,3 @@ vio/test-ssl
|
||||
vio/test-sslclient
|
||||
vio/test-sslserver
|
||||
vio/viotest-ssl
|
||||
mysys/test_gethwaddr
|
||||
cmd-line-utils/libedit/makelist
|
||||
|
@ -90,6 +90,20 @@
|
||||
#define HA_NOT_READ_PREFIX_LAST 32 /* No support for index_read_last() */
|
||||
#define HA_KEY_READ_ONLY 64 /* Support HA_EXTRA_KEYREAD */
|
||||
|
||||
|
||||
/*
|
||||
Bits in index_ddl_flags(KEY *wanted_index)
|
||||
for what ddl you can do with index
|
||||
If none is set, the wanted type of index is not supported
|
||||
by the handler at all. See WorkLog 1563.
|
||||
*/
|
||||
#define HA_DDL_SUPPORT 1 /* Supported by handler */
|
||||
#define HA_DDL_WITH_LOCK 2 /* Can create/drop with locked table */
|
||||
#define HA_DDL_ONLINE 4 /* Can create/drop without lock */
|
||||
|
||||
/* Return value for ddl methods */
|
||||
#define HA_DDL_NOT_IMPLEMENTED -1
|
||||
|
||||
/*
|
||||
Parameters for open() (in register form->filestat)
|
||||
HA_GET_INFO does an implicit HA_ABORT_IF_LOCKED
|
||||
@ -355,6 +369,20 @@ public:
|
||||
{
|
||||
return (HA_READ_NEXT | HA_READ_PREV | HA_READ_ORDER | HA_KEY_READ_ONLY);
|
||||
}
|
||||
virtual ulong index_ddl_flags(KEY *wanted_index) const
|
||||
{
|
||||
return (HA_DDL_SUPPORT);
|
||||
}
|
||||
virtual int add_index(TABLE *table, KEY *key_info, uint num_of_keys)
|
||||
{
|
||||
my_error(ER_NOT_SUPPORTED_YET, MYF(0), "online add index");
|
||||
return (HA_DDL_NOT_IMPLEMENTED);
|
||||
}
|
||||
virtual int drop_index(TABLE *table, uint *key_num, uint num_of_keys)
|
||||
{
|
||||
my_error(ER_NOT_SUPPORTED_YET, MYF(0), "online drop index");
|
||||
return (HA_DDL_NOT_IMPLEMENTED);
|
||||
}
|
||||
virtual uint max_record_length() const =0;
|
||||
virtual uint max_keys() const =0;
|
||||
virtual uint max_key_parts() const =0;
|
||||
|
@ -488,6 +488,11 @@ int mysql_handle_derived(LEX *lex);
|
||||
Field *create_tmp_field(THD *thd, TABLE *table,Item *item, Item::Type type,
|
||||
Item ***copy_func, Field **from_field,
|
||||
bool group,bool modify_item);
|
||||
int mysql_prepare_table(THD *thd, HA_CREATE_INFO *create_info,
|
||||
List<create_field> &fields,
|
||||
List<Key> &keys, uint &db_options,
|
||||
handler *file, KEY *&key_info_buffer,
|
||||
uint &key_count, int select_field_count);
|
||||
int mysql_create_table(THD *thd,const char *db, const char *table_name,
|
||||
HA_CREATE_INFO *create_info,
|
||||
List<create_field> &fields, List<Key> &keys,
|
||||
@ -504,7 +509,19 @@ int mysql_alter_table(THD *thd, char *new_db, char *new_name,
|
||||
List<create_field> &fields,
|
||||
List<Key> &keys,List<Alter_drop> &drop_list,
|
||||
List<Alter_column> &alter_list,
|
||||
uint order_num, ORDER *order,
|
||||
uint order_num, ORDER *order, int alter_flags,
|
||||
enum enum_duplicates handle_duplicates,
|
||||
enum enum_enable_or_disable keys_onoff=LEAVE_AS_IS,
|
||||
enum tablespace_op_type tablespace_op=NO_TABLESPACE_OP,
|
||||
bool simple_alter=0);
|
||||
int real_alter_table(THD *thd, char *new_db, char *new_name,
|
||||
HA_CREATE_INFO *create_info,
|
||||
TABLE_LIST *table_list,
|
||||
TABLE *table,
|
||||
List<create_field> &fields,
|
||||
List<Key> &keys,List<Alter_drop> &drop_list,
|
||||
List<Alter_column> &alter_list,
|
||||
uint order_num, ORDER *order, int alter_flags,
|
||||
enum enum_duplicates handle_duplicates,
|
||||
enum enum_enable_or_disable keys_onoff=LEAVE_AS_IS,
|
||||
enum tablespace_op_type tablespace_op=NO_TABLESPACE_OP,
|
||||
@ -520,6 +537,10 @@ bool mysql_rename_table(enum db_type base,
|
||||
int mysql_create_index(THD *thd, TABLE_LIST *table_list, List<Key> &keys);
|
||||
int mysql_drop_index(THD *thd, TABLE_LIST *table_list,
|
||||
List<Alter_drop> &drop_list);
|
||||
int mysql_add_column(THD *thd, TABLE_LIST *table_list,
|
||||
List<create_field> &fields);
|
||||
int mysql_drop_column(THD *thd, TABLE_LIST *table_list,
|
||||
List<Alter_drop> &drop_list);
|
||||
int mysql_update(THD *thd,TABLE_LIST *tables,List<Item> &fields,
|
||||
List<Item> &values,COND *conds,
|
||||
uint order_num, ORDER *order, ha_rows limit,
|
||||
@ -923,6 +944,9 @@ void unlock_table_names(THD *thd, TABLE_LIST *table_list,
|
||||
|
||||
void unireg_init(ulong options);
|
||||
void unireg_end(void);
|
||||
int mysql_create_frm(THD *thd, my_string file_name,HA_CREATE_INFO *create_info,
|
||||
List<create_field> &create_field,
|
||||
uint key_count,KEY *key_info,handler *db_type);
|
||||
int rea_create_table(THD *thd, my_string file_name,HA_CREATE_INFO *create_info,
|
||||
List<create_field> &create_field,
|
||||
uint key_count,KEY *key_info);
|
||||
|
@ -2604,45 +2604,6 @@ static void mysql_rm_tmp_tables(void)
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
CREATE INDEX and DROP INDEX are implemented by calling ALTER TABLE with
|
||||
the proper arguments. This isn't very fast but it should work for most
|
||||
cases.
|
||||
One should normally create all indexes with CREATE TABLE or ALTER TABLE.
|
||||
*/
|
||||
|
||||
int mysql_create_index(THD *thd, TABLE_LIST *table_list, List<Key> &keys)
|
||||
{
|
||||
List<create_field> fields;
|
||||
List<Alter_drop> drop;
|
||||
List<Alter_column> alter;
|
||||
HA_CREATE_INFO create_info;
|
||||
DBUG_ENTER("mysql_create_index");
|
||||
bzero((char*) &create_info,sizeof(create_info));
|
||||
create_info.db_type=DB_TYPE_DEFAULT;
|
||||
create_info.default_table_charset= thd->variables.collation_database;
|
||||
DBUG_RETURN(mysql_alter_table(thd,table_list->db,table_list->real_name,
|
||||
&create_info, table_list,
|
||||
fields, keys, drop, alter, 0, (ORDER*)0,
|
||||
DUP_ERROR));
|
||||
}
|
||||
|
||||
|
||||
int mysql_drop_index(THD *thd, TABLE_LIST *table_list, List<Alter_drop> &drop)
|
||||
{
|
||||
List<create_field> fields;
|
||||
List<Key> keys;
|
||||
List<Alter_column> alter;
|
||||
HA_CREATE_INFO create_info;
|
||||
DBUG_ENTER("mysql_drop_index");
|
||||
bzero((char*) &create_info,sizeof(create_info));
|
||||
create_info.db_type=DB_TYPE_DEFAULT;
|
||||
create_info.default_table_charset= thd->variables.collation_database;
|
||||
DBUG_RETURN(mysql_alter_table(thd,table_list->db,table_list->real_name,
|
||||
&create_info, table_list,
|
||||
fields, keys, drop, alter, 0, (ORDER*)0,
|
||||
DUP_ERROR));
|
||||
}
|
||||
|
||||
/*****************************************************************************
|
||||
unireg support functions
|
||||
|
@ -509,6 +509,14 @@ public:
|
||||
};
|
||||
typedef class st_select_lex SELECT_LEX;
|
||||
|
||||
#define ALTER_ADD_COLUMN 1
|
||||
#define ALTER_DROP_COLUMN 2
|
||||
#define ALTER_CHANGE_COLUMN 4
|
||||
#define ALTER_ADD_INDEX 8
|
||||
#define ALTER_DROP_INDEX 16
|
||||
#define ALTER_RENAME 32
|
||||
#define ALTER_ORDER 64
|
||||
#define ALTER_OPTIONS 128
|
||||
|
||||
/* The state of the lex parsing. This is saved in the THD struct */
|
||||
|
||||
@ -578,6 +586,7 @@ typedef struct st_lex
|
||||
uint grant, grant_tot_col, which_columns;
|
||||
uint fk_delete_opt, fk_update_opt, fk_match_option;
|
||||
uint slave_thd_opt;
|
||||
uint alter_flags;
|
||||
uint8 describe;
|
||||
bool drop_if_exists, drop_temporary, local_file;
|
||||
bool in_comment, ignore_space, verbose, simple_alter, no_write_to_binlog;
|
||||
|
@ -2391,6 +2391,7 @@ unsent_create_error:
|
||||
lex->key_list, lex->drop_list, lex->alter_list,
|
||||
select_lex->order_list.elements,
|
||||
(ORDER *) select_lex->order_list.first,
|
||||
lex->alter_flags,
|
||||
lex->duplicates,
|
||||
lex->alter_keys_onoff,
|
||||
lex->tablespace_op,
|
||||
@ -2541,7 +2542,7 @@ unsent_create_error:
|
||||
res= mysql_alter_table(thd, NullS, NullS, &create_info,
|
||||
tables, lex->create_list,
|
||||
lex->key_list, lex->drop_list, lex->alter_list,
|
||||
0, (ORDER *) 0,
|
||||
0, (ORDER *) 0, 0,
|
||||
DUP_ERROR);
|
||||
}
|
||||
else
|
||||
|
551
sql/sql_table.cc
551
sql/sql_table.cc
@ -289,11 +289,15 @@ int quick_rm_table(enum db_type base,const char *db,
|
||||
{
|
||||
char path[FN_REFLEN];
|
||||
int error=0;
|
||||
(void) sprintf(path,"%s/%s/%s%s",mysql_data_home,db,table_name,reg_ext);
|
||||
if (snprintf(path, sizeof(path), "%s/%s/%s%s",
|
||||
mysql_data_home, db, table_name, reg_ext)>= (int)sizeof(path))
|
||||
return 1;
|
||||
unpack_filename(path,path);
|
||||
if (my_delete(path,MYF(0)))
|
||||
error=1; /* purecov: inspected */
|
||||
sprintf(path,"%s/%s/%s",mysql_data_home,db,table_name);
|
||||
if (snprintf(path, sizeof(path), "%s/%s/%s",
|
||||
mysql_data_home, db, table_name)>= (int)sizeof(path))
|
||||
return 1;
|
||||
unpack_filename(path,path);
|
||||
return ha_delete_table(base,path) || error;
|
||||
}
|
||||
@ -385,85 +389,45 @@ void check_duplicates_in_interval(const char *set_or_name,
|
||||
}
|
||||
|
||||
/*
|
||||
Create a table
|
||||
Preparation for table creation
|
||||
|
||||
SYNOPSIS
|
||||
mysql_create_table()
|
||||
mysql_prepare_table()
|
||||
thd Thread object
|
||||
db Database
|
||||
table_name Table name
|
||||
create_info Create information (like MAX_ROWS)
|
||||
fields List of fields to create
|
||||
keys List of keys to create
|
||||
tmp_table Set to 1 if this is an internal temporary table
|
||||
(From ALTER TABLE)
|
||||
no_log Don't log the query to binary log.
|
||||
|
||||
DESCRIPTION
|
||||
If one creates a temporary table, this is automaticly opened
|
||||
|
||||
no_log is needed for the case of CREATE ... SELECT,
|
||||
as the logging will be done later in sql_insert.cc
|
||||
select_field_count is also used for CREATE ... SELECT,
|
||||
and must be zero for standard create of table.
|
||||
Prepares the table and key structures for table creation.
|
||||
|
||||
RETURN VALUES
|
||||
0 ok
|
||||
-1 error
|
||||
*/
|
||||
|
||||
int mysql_create_table(THD *thd,const char *db, const char *table_name,
|
||||
HA_CREATE_INFO *create_info,
|
||||
int mysql_prepare_table(THD *thd, HA_CREATE_INFO *create_info,
|
||||
List<create_field> &fields,
|
||||
List<Key> &keys,bool tmp_table,bool no_log,
|
||||
uint select_field_count)
|
||||
List<Key> &keys, bool tmp_table, uint &db_options,
|
||||
handler *file, KEY *&key_info_buffer,
|
||||
uint &key_count, int select_field_count)
|
||||
{
|
||||
char path[FN_REFLEN];
|
||||
const char *key_name, *alias;
|
||||
const char *key_name;
|
||||
create_field *sql_field,*dup_field;
|
||||
int error= -1;
|
||||
uint db_options,field,null_fields,blob_columns;
|
||||
uint field,null_fields,blob_columns;
|
||||
ulong pos;
|
||||
KEY *key_info,*key_info_buffer;
|
||||
KEY *key_info;
|
||||
KEY_PART_INFO *key_part_info;
|
||||
int auto_increment=0;
|
||||
int timestamps= 0, timestamps_with_niladic= 0;
|
||||
handler *file;
|
||||
int field_no,dup_no;
|
||||
enum db_type new_db_type;
|
||||
DBUG_ENTER("mysql_create_table");
|
||||
int select_field_pos,auto_increment=0;
|
||||
DBUG_ENTER("mysql_prepare_table");
|
||||
|
||||
/* Check for duplicate fields and check type of table to create */
|
||||
if (!fields.elements)
|
||||
{
|
||||
my_error(ER_TABLE_MUST_HAVE_COLUMNS,MYF(0));
|
||||
DBUG_RETURN(-1);
|
||||
}
|
||||
List_iterator<create_field> it(fields),it2(fields);
|
||||
int select_field_pos=fields.elements - select_field_count;
|
||||
select_field_pos=fields.elements - select_field_count;
|
||||
null_fields=blob_columns=0;
|
||||
if ((new_db_type= ha_checktype(create_info->db_type)) !=
|
||||
create_info->db_type)
|
||||
{
|
||||
create_info->db_type= new_db_type;
|
||||
push_warning_printf(thd, MYSQL_ERROR::WARN_LEVEL_WARN,
|
||||
ER_WARN_USING_OTHER_HANDLER,
|
||||
ER(ER_WARN_USING_OTHER_HANDLER),
|
||||
ha_get_storage_engine(new_db_type),
|
||||
table_name);
|
||||
}
|
||||
db_options=create_info->table_options;
|
||||
if (create_info->row_type == ROW_TYPE_DYNAMIC)
|
||||
db_options|=HA_OPTION_PACK_RECORD;
|
||||
alias= table_case_name(create_info, table_name);
|
||||
file=get_new_handler((TABLE*) 0, create_info->db_type);
|
||||
|
||||
if ((create_info->options & HA_LEX_CREATE_TMP_TABLE) &&
|
||||
(file->table_flags() & HA_NO_TEMP_TABLES))
|
||||
{
|
||||
my_error(ER_ILLEGAL_HA,MYF(0),table_name);
|
||||
DBUG_RETURN(-1);
|
||||
}
|
||||
|
||||
for (field_no=0; (sql_field=it++) ; field_no++)
|
||||
{
|
||||
@ -681,13 +645,14 @@ int mysql_create_table(THD *thd,const char *db, const char *table_name,
|
||||
/* Create keys */
|
||||
|
||||
List_iterator<Key> key_iterator(keys);
|
||||
uint key_parts=0, key_count=0, fk_key_count=0;
|
||||
uint key_parts=0, fk_key_count=0;
|
||||
List<Key> keys_in_order; // Add new keys here
|
||||
bool primary_key=0,unique_key=0;
|
||||
Key *key;
|
||||
uint tmp, key_number;
|
||||
|
||||
/* Calculate number of key segements */
|
||||
key_count=0;
|
||||
|
||||
while ((key=key_iterator++))
|
||||
{
|
||||
@ -944,7 +909,9 @@ int mysql_create_table(THD *thd,const char *db, const char *table_name,
|
||||
{
|
||||
/* not a critical problem */
|
||||
char warn_buff[MYSQL_ERRMSG_SIZE];
|
||||
sprintf(warn_buff,ER(ER_TOO_LONG_KEY),length);
|
||||
if (snprintf(warn_buff, sizeof(warn_buff), ER(ER_TOO_LONG_KEY),
|
||||
length)>= (int)sizeof(warn_buff))
|
||||
DBUG_RETURN(-1);
|
||||
push_warning(thd, MYSQL_ERROR::WARN_LEVEL_WARN,
|
||||
ER_TOO_LONG_KEY, warn_buff);
|
||||
}
|
||||
@ -981,7 +948,9 @@ int mysql_create_table(THD *thd,const char *db, const char *table_name,
|
||||
{
|
||||
/* not a critical problem */
|
||||
char warn_buff[MYSQL_ERRMSG_SIZE];
|
||||
sprintf(warn_buff,ER(ER_TOO_LONG_KEY),length);
|
||||
if (snprintf(warn_buff, sizeof(warn_buff), ER(ER_TOO_LONG_KEY),
|
||||
length)>= (int)sizeof(warn_buff))
|
||||
DBUG_RETURN(-1);
|
||||
push_warning(thd, MYSQL_ERROR::WARN_LEVEL_WARN,
|
||||
ER_TOO_LONG_KEY, warn_buff);
|
||||
}
|
||||
@ -1061,15 +1030,100 @@ int mysql_create_table(THD *thd,const char *db, const char *table_name,
|
||||
/* Sort keys in optimized order */
|
||||
qsort((gptr) key_info_buffer, key_count, sizeof(KEY), (qsort_cmp) sort_keys);
|
||||
|
||||
DBUG_RETURN(0);
|
||||
}
|
||||
|
||||
/*
|
||||
Create a table
|
||||
|
||||
SYNOPSIS
|
||||
mysql_create_table()
|
||||
thd Thread object
|
||||
db Database
|
||||
table_name Table name
|
||||
create_info Create information (like MAX_ROWS)
|
||||
fields List of fields to create
|
||||
keys List of keys to create
|
||||
tmp_table Set to 1 if this is an internal temporary table
|
||||
(From ALTER TABLE)
|
||||
no_log Don't log the query to binary log.
|
||||
|
||||
DESCRIPTION
|
||||
If one creates a temporary table, this is automaticly opened
|
||||
|
||||
no_log is needed for the case of CREATE ... SELECT,
|
||||
as the logging will be done later in sql_insert.cc
|
||||
select_field_count is also used for CREATE ... SELECT,
|
||||
and must be zero for standard create of table.
|
||||
|
||||
RETURN VALUES
|
||||
0 ok
|
||||
-1 error
|
||||
*/
|
||||
|
||||
int mysql_create_table(THD *thd,const char *db, const char *table_name,
|
||||
HA_CREATE_INFO *create_info,
|
||||
List<create_field> &fields,
|
||||
List<Key> &keys,bool tmp_table,bool no_log,
|
||||
uint select_field_count)
|
||||
{
|
||||
char path[FN_REFLEN];
|
||||
const char *alias;
|
||||
int error= -1;
|
||||
uint db_options, key_count;
|
||||
KEY *key_info_buffer;
|
||||
handler *file;
|
||||
enum db_type new_db_type;
|
||||
DBUG_ENTER("mysql_create_table");
|
||||
|
||||
/* Check for duplicate fields and check type of table to create */
|
||||
if (!fields.elements)
|
||||
{
|
||||
my_error(ER_TABLE_MUST_HAVE_COLUMNS,MYF(0));
|
||||
DBUG_RETURN(-1);
|
||||
}
|
||||
if ((new_db_type= ha_checktype(create_info->db_type)) !=
|
||||
create_info->db_type)
|
||||
{
|
||||
create_info->db_type= new_db_type;
|
||||
push_warning_printf(thd, MYSQL_ERROR::WARN_LEVEL_WARN,
|
||||
ER_WARN_USING_OTHER_HANDLER,
|
||||
ER(ER_WARN_USING_OTHER_HANDLER),
|
||||
ha_get_storage_engine(new_db_type),
|
||||
table_name);
|
||||
}
|
||||
db_options=create_info->table_options;
|
||||
if (create_info->row_type == ROW_TYPE_DYNAMIC)
|
||||
db_options|=HA_OPTION_PACK_RECORD;
|
||||
alias= table_case_name(create_info, table_name);
|
||||
file=get_new_handler((TABLE*) 0, create_info->db_type);
|
||||
|
||||
if ((create_info->options & HA_LEX_CREATE_TMP_TABLE) &&
|
||||
(file->table_flags() & HA_NO_TEMP_TABLES))
|
||||
{
|
||||
my_error(ER_ILLEGAL_HA,MYF(0),table_name);
|
||||
DBUG_RETURN(-1);
|
||||
}
|
||||
|
||||
if (mysql_prepare_table(thd, create_info, fields,
|
||||
keys, tmp_table, db_options, file,
|
||||
key_info_buffer, key_count,
|
||||
select_field_count))
|
||||
DBUG_RETURN(-1);
|
||||
|
||||
/* Check if table exists */
|
||||
if (create_info->options & HA_LEX_CREATE_TMP_TABLE)
|
||||
{
|
||||
sprintf(path,"%s%s%lx_%lx_%x%s",mysql_tmpdir,tmp_file_prefix,
|
||||
current_pid, thd->thread_id, thd->tmp_table++,reg_ext);
|
||||
if (snprintf(path, sizeof(path), "%s%s%lx_%lx_%x%s",
|
||||
mysql_tmpdir, tmp_file_prefix, current_pid, thd->thread_id,
|
||||
thd->tmp_table++, reg_ext)>= (int)sizeof(path))
|
||||
DBUG_RETURN(-1);
|
||||
create_info->table_options|=HA_CREATE_DELAY_KEY_WRITE;
|
||||
}
|
||||
else
|
||||
(void) sprintf(path,"%s/%s/%s%s",mysql_data_home,db,alias,reg_ext);
|
||||
if (snprintf(path, sizeof(path), "%s/%s/%s%s", mysql_data_home, db,
|
||||
alias, reg_ext)>= (int)sizeof(path))
|
||||
DBUG_RETURN(-1);
|
||||
unpack_filename(path,path);
|
||||
/* Check if table already exists */
|
||||
if ((create_info->options & HA_LEX_CREATE_TMP_TABLE)
|
||||
@ -1163,17 +1217,23 @@ static char *
|
||||
make_unique_key_name(const char *field_name,KEY *start,KEY *end)
|
||||
{
|
||||
char buff[MAX_FIELD_NAME],*buff_end;
|
||||
int remain;
|
||||
|
||||
if (!check_if_keyname_exists(field_name,start,end) &&
|
||||
my_strcasecmp(system_charset_info,field_name,primary_key_name))
|
||||
return (char*) field_name; // Use fieldname
|
||||
buff_end=strmake(buff,field_name,MAX_FIELD_NAME-4);
|
||||
for (uint i=2 ; ; i++)
|
||||
/*ingo 2004-04-07 only 3 chars + '\0' left, so need to limit to 2 digit*/
|
||||
for (uint i=2 ; i< 100; i++)
|
||||
{
|
||||
sprintf(buff_end,"_%d",i);
|
||||
remain= (int)sizeof(buff)- (buff_end- buff);
|
||||
if (snprintf(buff_end, remain, "_%d", i)>= remain)
|
||||
return NULL;
|
||||
if (!check_if_keyname_exists(buff,start,end))
|
||||
return sql_strdup(buff);
|
||||
}
|
||||
/*ingo 2004-04-07 dedicated return is inevitable*/
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/****************************************************************************
|
||||
@ -1271,8 +1331,12 @@ mysql_rename_table(enum db_type base,
|
||||
my_casedn_str(system_charset_info, tmp_to);
|
||||
new_name= tmp_to;
|
||||
}
|
||||
(void) sprintf(from,"%s/%s/%s",mysql_data_home,old_db,old_name);
|
||||
(void) sprintf(to,"%s/%s/%s",mysql_data_home,new_db,new_name);
|
||||
if (snprintf(from, sizeof(from), "%s/%s/%s",
|
||||
mysql_data_home, old_db, old_name)>= (int)sizeof(from))
|
||||
DBUG_RETURN(1);
|
||||
if (snprintf(to, sizeof(to), "%s/%s/%s",
|
||||
mysql_data_home, new_db, new_name)>= (int)sizeof(to))
|
||||
DBUG_RETURN(1);
|
||||
fn_format(from,from,"","",4);
|
||||
fn_format(to,to, "","",4);
|
||||
|
||||
@ -1407,7 +1471,9 @@ static int prepare_for_restore(THD* thd, TABLE_LIST* table,
|
||||
reg_ext))
|
||||
DBUG_RETURN(-1); // protect buffer overflow
|
||||
|
||||
sprintf(dst_path, "%s/%s/%s", mysql_real_data_home, db, table_name);
|
||||
if (snprintf(dst_path, sizeof(dst_path), "%s/%s/%s",
|
||||
mysql_real_data_home, db, table_name)>= (int)sizeof(dst_path))
|
||||
DBUG_RETURN(-1);
|
||||
|
||||
if (lock_and_wait_for_table_name(thd,table))
|
||||
DBUG_RETURN(-1);
|
||||
@ -1491,7 +1557,12 @@ static int prepare_for_repair(THD* thd, TABLE_LIST *table_list,
|
||||
if (!my_stat(from, &stat_info, MYF(0)))
|
||||
goto end; // Can't use USE_FRM flag
|
||||
|
||||
sprintf(tmp,"%s-%lx_%lx", from, current_pid, thd->thread_id);
|
||||
if (snprintf(tmp, sizeof(tmp), "%s-%lx_%lx",
|
||||
from, current_pid, thd->thread_id)>= (int)sizeof(tmp))
|
||||
{
|
||||
error= -1;
|
||||
goto end;
|
||||
}
|
||||
|
||||
/* If we could open the table, close it */
|
||||
if (table_list->table)
|
||||
@ -1626,7 +1697,9 @@ static int mysql_admin_table(THD* thd, TABLE_LIST* tables,
|
||||
protocol->store(table_name, system_charset_info);
|
||||
protocol->store(operator_name, system_charset_info);
|
||||
protocol->store("error", 5, system_charset_info);
|
||||
sprintf(buff, ER(ER_OPEN_AS_READONLY), table_name);
|
||||
if (snprintf(buff, sizeof(buff), ER(ER_OPEN_AS_READONLY),
|
||||
table_name)>= (int)sizeof(buff))
|
||||
goto err;
|
||||
protocol->store(buff, system_charset_info);
|
||||
close_thread_tables(thd);
|
||||
table->table=0; // For query cache
|
||||
@ -1948,8 +2021,11 @@ int mysql_create_like_table(THD* thd, TABLE_LIST* table,
|
||||
{
|
||||
if (find_temporary_table(thd, db, table_name))
|
||||
goto table_exists;
|
||||
sprintf(dst_path,"%s%s%lx_%lx_%x%s",mysql_tmpdir,tmp_file_prefix,
|
||||
current_pid, thd->thread_id, thd->tmp_table++,reg_ext);
|
||||
if (snprintf(dst_path, sizeof(dst_path), "%s%s%lx_%lx_%x%s",
|
||||
mysql_tmpdir, tmp_file_prefix, current_pid,
|
||||
thd->thread_id, thd->tmp_table++, reg_ext)>=
|
||||
(int)sizeof(dst_path))
|
||||
DBUG_RETURN(-1);
|
||||
create_info->table_options|= HA_CREATE_DELAY_KEY_WRITE;
|
||||
}
|
||||
else
|
||||
@ -2007,7 +2083,9 @@ table_exists:
|
||||
if (create_info->options & HA_LEX_CREATE_IF_NOT_EXISTS)
|
||||
{
|
||||
char warn_buff[MYSQL_ERRMSG_SIZE];
|
||||
sprintf(warn_buff,ER(ER_TABLE_EXISTS_ERROR),table_name);
|
||||
if (snprintf(warn_buff, sizeof(warn_buff),
|
||||
ER(ER_TABLE_EXISTS_ERROR), table_name)>= (int)sizeof(warn_buff))
|
||||
DBUG_RETURN(-1);
|
||||
push_warning(thd, MYSQL_ERROR::WARN_LEVEL_WARN,
|
||||
ER_TABLE_EXISTS_ERROR,warn_buff);
|
||||
res= 0;
|
||||
@ -2118,19 +2196,307 @@ err:
|
||||
DBUG_RETURN(error);
|
||||
}
|
||||
|
||||
/*
|
||||
CREATE INDEX and DROP INDEX are implemented by calling ALTER TABLE with
|
||||
the proper arguments. This isn't very fast but it should work for most
|
||||
cases.
|
||||
One should normally create all indexes with CREATE TABLE or ALTER TABLE.
|
||||
*/
|
||||
|
||||
int mysql_create_index(THD *thd, TABLE_LIST *table_list, List<Key> &keys)
|
||||
{
|
||||
List<create_field> fields;
|
||||
List<Alter_drop> drop;
|
||||
List<Alter_column> alter;
|
||||
HA_CREATE_INFO create_info;
|
||||
int rc;
|
||||
uint idx;
|
||||
uint db_options;
|
||||
uint key_count;
|
||||
TABLE *table;
|
||||
Field **f_ptr;
|
||||
KEY *key_info_buffer;
|
||||
char path[FN_REFLEN];
|
||||
DBUG_ENTER("mysql_create_index");
|
||||
|
||||
/*
|
||||
Try to use online generation of index.
|
||||
This requires that all indexes can be created online.
|
||||
Otherwise, the old alter table procedure is executed.
|
||||
|
||||
Open the table to have access to the correct table handler.
|
||||
*/
|
||||
if (!(table=open_ltable(thd,table_list,TL_WRITE_ALLOW_READ)))
|
||||
DBUG_RETURN(-1);
|
||||
|
||||
/*
|
||||
The add_index method takes an array of KEY structs for the new indexes.
|
||||
Preparing a new table structure generates this array.
|
||||
It needs a list with all fields of the table, which does not need to
|
||||
be correct in every respect. The field names are important.
|
||||
*/
|
||||
for (f_ptr= table->field; *f_ptr; f_ptr++)
|
||||
{
|
||||
create_field *c_fld= new create_field(*f_ptr, *f_ptr);
|
||||
c_fld->unireg_check= Field::NONE; /*avoid multiple auto_increments*/
|
||||
fields.push_back(c_fld);
|
||||
}
|
||||
bzero((char*) &create_info,sizeof(create_info));
|
||||
create_info.db_type=DB_TYPE_DEFAULT;
|
||||
create_info.default_table_charset= thd->variables.collation_database;
|
||||
db_options= 0;
|
||||
if (mysql_prepare_table(thd, &create_info, fields,
|
||||
keys, /*tmp_table*/ 0, db_options, table->file,
|
||||
key_info_buffer, key_count,
|
||||
/*select_field_count*/ 0))
|
||||
DBUG_RETURN(-1);
|
||||
|
||||
/*
|
||||
Check if all keys can be generated with the add_index method.
|
||||
If anyone cannot, then take the old way.
|
||||
*/
|
||||
for (idx=0; idx< key_count; idx++)
|
||||
{
|
||||
DBUG_PRINT("info", ("creating index %s", key_info_buffer[idx].name));
|
||||
if (!(table->file->index_ddl_flags(key_info_buffer+idx)&
|
||||
(HA_DDL_ONLINE| HA_DDL_WITH_LOCK)))
|
||||
break ;
|
||||
}
|
||||
if ((idx < key_count)|| !key_count)
|
||||
{
|
||||
/* Re-initialize the create_info, which was changed by prepare table. */
|
||||
bzero((char*) &create_info,sizeof(create_info));
|
||||
create_info.db_type=DB_TYPE_DEFAULT;
|
||||
create_info.default_table_charset= thd->variables.collation_database;
|
||||
/* Cleanup the fields list. We do not want to create existing fields. */
|
||||
fields.delete_elements();
|
||||
if (real_alter_table(thd, table_list->db, table_list->real_name,
|
||||
&create_info, table_list, table,
|
||||
fields, keys, drop, alter, 0, (ORDER*)0,
|
||||
ALTER_ADD_INDEX, DUP_ERROR))
|
||||
/*don't need to free((gptr) key_info_buffer);*/
|
||||
DBUG_RETURN(-1);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (table->file->add_index(table, key_info_buffer, key_count)||
|
||||
(snprintf(path, sizeof(path), "%s/%s/%s%s", mysql_data_home,
|
||||
table_list->db, (lower_case_table_names == 2)?
|
||||
table_list->alias: table_list->real_name, reg_ext)>=
|
||||
(int)sizeof(path))||
|
||||
! unpack_filename(path, path)||
|
||||
mysql_create_frm(thd, path, &create_info,
|
||||
fields, key_count, key_info_buffer, table->file))
|
||||
/*don't need to free((gptr) key_info_buffer);*/
|
||||
DBUG_RETURN(-1);
|
||||
}
|
||||
|
||||
/*don't need to free((gptr) key_info_buffer);*/
|
||||
DBUG_RETURN(0);
|
||||
}
|
||||
|
||||
|
||||
int mysql_drop_index(THD *thd, TABLE_LIST *table_list, List<Alter_drop> &drop)
|
||||
{
|
||||
List<create_field> fields;
|
||||
List<Key> keys;
|
||||
List<Alter_column> alter;
|
||||
HA_CREATE_INFO create_info;
|
||||
uint idx;
|
||||
uint db_options;
|
||||
uint key_count;
|
||||
uint *key_numbers;
|
||||
TABLE *table;
|
||||
Field **f_ptr;
|
||||
KEY *key_info;
|
||||
KEY *key_info_buffer;
|
||||
char path[FN_REFLEN];
|
||||
DBUG_ENTER("mysql_drop_index");
|
||||
|
||||
/*
|
||||
Try to use online generation of index.
|
||||
This requires that all indexes can be created online.
|
||||
Otherwise, the old alter table procedure is executed.
|
||||
|
||||
Open the table to have access to the correct table handler.
|
||||
*/
|
||||
if (!(table=open_ltable(thd,table_list,TL_WRITE_ALLOW_READ)))
|
||||
DBUG_RETURN(-1);
|
||||
|
||||
/*
|
||||
The drop_index method takes an array of key numbers.
|
||||
It cannot get more entries than keys in the table.
|
||||
*/
|
||||
key_numbers= (uint*) thd->alloc(sizeof(uint*)*table->keys);
|
||||
key_count= 0;
|
||||
|
||||
/*
|
||||
Get the number of each key and check if it can be created online.
|
||||
*/
|
||||
List_iterator<Alter_drop> drop_it(drop);
|
||||
Alter_drop *drop_key;
|
||||
while ((drop_key= drop_it++))
|
||||
{
|
||||
/* Find the key in the table. */
|
||||
key_info=table->key_info;
|
||||
for (idx=0; idx< table->keys; idx++, key_info++)
|
||||
{
|
||||
if (!my_strcasecmp(system_charset_info, key_info->name, drop_key->name))
|
||||
break;
|
||||
}
|
||||
if (idx>= table->keys)
|
||||
{
|
||||
my_error(ER_CANT_DROP_FIELD_OR_KEY, MYF(0), drop_key->name);
|
||||
/*don't need to free((gptr) key_numbers);*/
|
||||
DBUG_RETURN(-1);
|
||||
}
|
||||
/*
|
||||
Check if the key can be generated with the add_index method.
|
||||
If anyone cannot, then take the old way.
|
||||
*/
|
||||
DBUG_PRINT("info", ("dropping index %s", table->key_info[idx].name));
|
||||
if (!(table->file->index_ddl_flags(table->key_info+idx)&
|
||||
(HA_DDL_ONLINE| HA_DDL_WITH_LOCK)))
|
||||
break ;
|
||||
key_numbers[key_count++]= idx;
|
||||
}
|
||||
|
||||
bzero((char*) &create_info,sizeof(create_info));
|
||||
create_info.db_type=DB_TYPE_DEFAULT;
|
||||
create_info.default_table_charset= thd->variables.collation_database;
|
||||
|
||||
if ((drop_key)|| (drop.elements<= 0))
|
||||
{
|
||||
if (real_alter_table(thd, table_list->db, table_list->real_name,
|
||||
&create_info, table_list, table,
|
||||
fields, keys, drop, alter, 0, (ORDER*)0,
|
||||
ALTER_DROP_INDEX, DUP_ERROR))
|
||||
/*don't need to free((gptr) key_numbers);*/
|
||||
DBUG_RETURN(-1);
|
||||
}
|
||||
else
|
||||
{
|
||||
db_options= 0;
|
||||
if (table->file->drop_index(table, key_numbers, key_count)||
|
||||
mysql_prepare_table(thd, &create_info, fields,
|
||||
keys, /*tmp_table*/ 0, db_options, table->file,
|
||||
key_info_buffer, key_count,
|
||||
/*select_field_count*/ 0)||
|
||||
(snprintf(path, sizeof(path), "%s/%s/%s%s", mysql_data_home,
|
||||
table_list->db, (lower_case_table_names == 2)?
|
||||
table_list->alias: table_list->real_name, reg_ext)>=
|
||||
(int)sizeof(path))||
|
||||
! unpack_filename(path, path)||
|
||||
mysql_create_frm(thd, path, &create_info,
|
||||
fields, key_count, key_info_buffer, table->file))
|
||||
/*don't need to free((gptr) key_numbers);*/
|
||||
DBUG_RETURN(-1);
|
||||
}
|
||||
|
||||
/*don't need to free((gptr) key_numbers);*/
|
||||
DBUG_RETURN(0);
|
||||
}
|
||||
|
||||
int mysql_add_column(THD *thd, TABLE_LIST *table_list,
|
||||
List<create_field> &fields)
|
||||
{
|
||||
List<Alter_drop> drop;
|
||||
List<Key> keys;
|
||||
List<Alter_column> alter;
|
||||
HA_CREATE_INFO create_info;
|
||||
DBUG_ENTER("mysql_add_column");
|
||||
bzero((char*) &create_info,sizeof(create_info));
|
||||
create_info.db_type=DB_TYPE_DEFAULT;
|
||||
create_info.default_table_charset= thd->variables.collation_database;
|
||||
TABLE *table;
|
||||
if (!(table=open_ltable(thd,table_list,TL_WRITE_ALLOW_READ)))
|
||||
DBUG_RETURN(-1);
|
||||
|
||||
DBUG_RETURN(real_alter_table(thd,table_list->db,table_list->real_name,
|
||||
&create_info, table_list, table,
|
||||
fields, keys, drop, alter, 0, (ORDER*)0,
|
||||
ALTER_ADD_COLUMN, DUP_ERROR));
|
||||
}
|
||||
|
||||
int mysql_drop_column(THD *thd, TABLE_LIST *table_list, List<Alter_drop> &drop)
|
||||
{
|
||||
List<create_field> fields;
|
||||
List<Key> keys;
|
||||
List<Alter_column> alter;
|
||||
HA_CREATE_INFO create_info;
|
||||
DBUG_ENTER("mysql_drop_column");
|
||||
bzero((char*) &create_info,sizeof(create_info));
|
||||
create_info.db_type=DB_TYPE_DEFAULT;
|
||||
create_info.default_table_charset= thd->variables.collation_database;
|
||||
TABLE *table;
|
||||
if (!(table=open_ltable(thd,table_list,TL_WRITE_ALLOW_READ)))
|
||||
DBUG_RETURN(-1);
|
||||
|
||||
DBUG_RETURN(real_alter_table(thd,table_list->db,table_list->real_name,
|
||||
&create_info, table_list, table,
|
||||
fields, keys, drop, alter, 0, (ORDER*)0,
|
||||
ALTER_DROP_COLUMN, DUP_ERROR));
|
||||
}
|
||||
|
||||
int mysql_alter_table(THD *thd,char *new_db, char *new_name,
|
||||
HA_CREATE_INFO *create_info,
|
||||
TABLE_LIST *table_list,
|
||||
List<create_field> &fields,
|
||||
List<Key> &keys,List<Alter_drop> &drop_list,
|
||||
List<Alter_column> &alter_list,
|
||||
uint order_num, ORDER *order,
|
||||
uint order_num, ORDER *order, int alter_flags,
|
||||
enum enum_duplicates handle_duplicates,
|
||||
enum enum_enable_or_disable keys_onoff,
|
||||
enum tablespace_op_type tablespace_op,
|
||||
bool simple_alter)
|
||||
{
|
||||
TABLE *table,*new_table;
|
||||
DBUG_ENTER("mysql_alter_table");
|
||||
|
||||
mysql_ha_closeall(thd, table_list);
|
||||
|
||||
/* DISCARD/IMPORT TABLESPACE is always alone in an ALTER TABLE */
|
||||
if (tablespace_op != NO_TABLESPACE_OP)
|
||||
DBUG_RETURN(mysql_discard_or_import_tablespace(thd,table_list,
|
||||
tablespace_op));
|
||||
|
||||
if (alter_flags == ALTER_ADD_INDEX)
|
||||
DBUG_RETURN(mysql_create_index(thd, table_list, keys));
|
||||
|
||||
if (alter_flags == ALTER_DROP_INDEX)
|
||||
DBUG_RETURN(mysql_drop_index(thd, table_list, drop_list));
|
||||
|
||||
if (alter_flags == ALTER_ADD_COLUMN)
|
||||
DBUG_RETURN(mysql_add_column(thd, table_list, fields));
|
||||
|
||||
if (alter_flags == ALTER_DROP_COLUMN)
|
||||
DBUG_RETURN(mysql_drop_column(thd, table_list, drop_list));
|
||||
|
||||
TABLE *table;
|
||||
if (!(table=open_ltable(thd,table_list,TL_WRITE_ALLOW_READ)))
|
||||
DBUG_RETURN(-1);
|
||||
|
||||
DBUG_RETURN(real_alter_table(thd, new_db, new_name,
|
||||
create_info, table_list, table, fields,
|
||||
keys, drop_list, alter_list,
|
||||
order_num, order, alter_flags,
|
||||
handle_duplicates, keys_onoff,
|
||||
tablespace_op, simple_alter));
|
||||
}
|
||||
|
||||
int real_alter_table(THD *thd,char *new_db, char *new_name,
|
||||
HA_CREATE_INFO *create_info,
|
||||
TABLE_LIST *table_list,
|
||||
TABLE *table,
|
||||
List<create_field> &fields,
|
||||
List<Key> &keys,List<Alter_drop> &drop_list,
|
||||
List<Alter_column> &alter_list,
|
||||
uint order_num, ORDER *order, int alter_flags,
|
||||
enum enum_duplicates handle_duplicates,
|
||||
enum enum_enable_or_disable keys_onoff,
|
||||
enum tablespace_op_type tablespace_op,
|
||||
bool simple_alter)
|
||||
{
|
||||
TABLE *new_table;
|
||||
int error;
|
||||
char tmp_name[80],old_name[32],new_name_buff[FN_REFLEN];
|
||||
char new_alias_buff[FN_REFLEN], *table_name, *db, *new_alias, *alias;
|
||||
@ -2139,7 +2505,7 @@ int mysql_alter_table(THD *thd,char *new_db, char *new_name,
|
||||
ulonglong next_insert_id;
|
||||
uint db_create_options, used_fields;
|
||||
enum db_type old_db_type,new_db_type;
|
||||
DBUG_ENTER("mysql_alter_table");
|
||||
DBUG_ENTER("real_alter_table");
|
||||
|
||||
thd->proc_info="init";
|
||||
table_name=table_list->real_name;
|
||||
@ -2152,15 +2518,6 @@ int mysql_alter_table(THD *thd,char *new_db, char *new_name,
|
||||
}
|
||||
used_fields=create_info->used_fields;
|
||||
|
||||
mysql_ha_closeall(thd, table_list);
|
||||
|
||||
/* DISCARD/IMPORT TABLESPACE is always alone in an ALTER TABLE */
|
||||
if (tablespace_op != NO_TABLESPACE_OP)
|
||||
DBUG_RETURN(mysql_discard_or_import_tablespace(thd,table_list,
|
||||
tablespace_op));
|
||||
if (!(table=open_ltable(thd,table_list,TL_WRITE_ALLOW_READ)))
|
||||
DBUG_RETURN(-1);
|
||||
|
||||
/* Check that we are not trying to rename to an existing table */
|
||||
if (new_name)
|
||||
{
|
||||
@ -2355,6 +2712,8 @@ int mysql_alter_table(THD *thd,char *new_db, char *new_name,
|
||||
if (def)
|
||||
{ // Field is changed
|
||||
def->field=field;
|
||||
if (def->sql_type == FIELD_TYPE_TIMESTAMP)
|
||||
use_timestamp=1;
|
||||
if (!def->after)
|
||||
{
|
||||
create_list.push_back(def);
|
||||
@ -2364,6 +2723,8 @@ int mysql_alter_table(THD *thd,char *new_db, char *new_name,
|
||||
else
|
||||
{ // Use old field value
|
||||
create_list.push_back(def=new create_field(field,field));
|
||||
if (def->sql_type == FIELD_TYPE_TIMESTAMP)
|
||||
use_timestamp=1;
|
||||
alter_it.rewind(); // Change default if ALTER
|
||||
Alter_column *alter;
|
||||
while ((alter=alter_it++))
|
||||
@ -2526,8 +2887,9 @@ int mysql_alter_table(THD *thd,char *new_db, char *new_name,
|
||||
}
|
||||
|
||||
db_create_options=table->db_create_options & ~(HA_OPTION_PACK_RECORD);
|
||||
(void) sprintf(tmp_name,"%s-%lx_%lx", tmp_file_prefix, current_pid,
|
||||
thd->thread_id);
|
||||
if (snprintf(tmp_name, sizeof(tmp_name), "%s-%lx_%lx", tmp_file_prefix,
|
||||
current_pid, thd->thread_id)>= (int)sizeof(tmp_name))
|
||||
goto err;
|
||||
create_info->db_type=new_db_type;
|
||||
if (!create_info->comment)
|
||||
create_info->comment=table->comment;
|
||||
@ -2606,7 +2968,9 @@ int mysql_alter_table(THD *thd,char *new_db, char *new_name,
|
||||
else
|
||||
{
|
||||
char path[FN_REFLEN];
|
||||
(void) sprintf(path,"%s/%s/%s",mysql_data_home,new_db,tmp_name);
|
||||
if (snprintf(path, sizeof(path), "%s/%s/%s", mysql_data_home,
|
||||
new_db, tmp_name)>= (int)sizeof(path))
|
||||
goto err;
|
||||
fn_format(path,path,"","",4);
|
||||
new_table=open_temporary_table(thd, path, new_db, tmp_name,0);
|
||||
}
|
||||
@ -2689,8 +3053,9 @@ int mysql_alter_table(THD *thd,char *new_db, char *new_name,
|
||||
*/
|
||||
|
||||
thd->proc_info="rename result table";
|
||||
sprintf(old_name,"%s2-%lx-%lx", tmp_file_prefix, current_pid,
|
||||
thd->thread_id);
|
||||
if (snprintf(old_name, sizeof(old_name), "%s2-%lx-%lx", tmp_file_prefix,
|
||||
current_pid, thd->thread_id)>= (int)sizeof(old_name))
|
||||
goto err;
|
||||
if (new_name != table_name || new_db != db)
|
||||
{
|
||||
if (!access(new_name_buff,F_OK))
|
||||
@ -2813,7 +3178,9 @@ int mysql_alter_table(THD *thd,char *new_db, char *new_name,
|
||||
shutdown.
|
||||
*/
|
||||
char path[FN_REFLEN];
|
||||
(void) sprintf(path,"%s/%s/%s",mysql_data_home,new_db,table_name);
|
||||
if (snprintf(path, sizeof(path), "%s/%s/%s", mysql_data_home,
|
||||
new_db, table_name)>= (int)sizeof(path))
|
||||
goto err;
|
||||
fn_format(path,path,"","",4);
|
||||
table=open_temporary_table(thd, path, new_db, tmp_name,0);
|
||||
if (table)
|
||||
@ -2831,8 +3198,10 @@ int mysql_alter_table(THD *thd,char *new_db, char *new_name,
|
||||
query_cache_invalidate3(thd, table_list, 0);
|
||||
|
||||
end_temporary:
|
||||
sprintf(tmp_name, ER(ER_INSERT_INFO), (ulong) (copied + deleted),
|
||||
(ulong) deleted, (ulong) thd->cuted_fields);
|
||||
if (snprintf(tmp_name, sizeof(tmp_name), ER(ER_INSERT_INFO),
|
||||
(ulong) (copied + deleted), (ulong) deleted,
|
||||
(ulong) thd->cuted_fields)>= (int)sizeof(tmp_name))
|
||||
goto err;
|
||||
send_ok(thd,copied+deleted,0L,tmp_name);
|
||||
thd->some_tables_deleted=0;
|
||||
DBUG_RETURN(0);
|
||||
|
@ -1439,10 +1439,29 @@ attribute:
|
||||
{ Lex->on_update_value= new Item_func_now_local(); }
|
||||
| AUTO_INC { Lex->type|= AUTO_INCREMENT_FLAG | NOT_NULL_FLAG; }
|
||||
| SERIAL_SYM DEFAULT VALUE_SYM
|
||||
{ Lex->type|= AUTO_INCREMENT_FLAG | NOT_NULL_FLAG | UNIQUE_FLAG; }
|
||||
| opt_primary KEY_SYM { Lex->type|= PRI_KEY_FLAG | NOT_NULL_FLAG; }
|
||||
| UNIQUE_SYM { Lex->type|= UNIQUE_FLAG; }
|
||||
| UNIQUE_SYM KEY_SYM { Lex->type|= UNIQUE_KEY_FLAG; }
|
||||
{
|
||||
LEX *lex=Lex;
|
||||
lex->type|= AUTO_INCREMENT_FLAG | NOT_NULL_FLAG | UNIQUE_FLAG;
|
||||
lex->alter_flags|= ALTER_ADD_INDEX;
|
||||
}
|
||||
| opt_primary KEY_SYM
|
||||
{
|
||||
LEX *lex=Lex;
|
||||
lex->type|= PRI_KEY_FLAG | NOT_NULL_FLAG;
|
||||
lex->alter_flags|= ALTER_ADD_INDEX;
|
||||
}
|
||||
| UNIQUE_SYM
|
||||
{
|
||||
LEX *lex=Lex;
|
||||
lex->type|= UNIQUE_FLAG;
|
||||
lex->alter_flags|= ALTER_ADD_INDEX;
|
||||
}
|
||||
| UNIQUE_SYM KEY_SYM
|
||||
{
|
||||
LEX *lex=Lex;
|
||||
lex->type|= UNIQUE_KEY_FLAG;
|
||||
lex->alter_flags|= ALTER_ADD_INDEX;
|
||||
}
|
||||
| COMMENT_SYM TEXT_STRING_sys { Lex->comment= &$2; }
|
||||
| BINARY { Lex->type|= BINCMP_FLAG; }
|
||||
| COLLATE_SYM collation_name
|
||||
@ -1700,6 +1719,7 @@ alter:
|
||||
lex->alter_keys_onoff=LEAVE_AS_IS;
|
||||
lex->tablespace_op=NO_TABLESPACE_OP;
|
||||
lex->simple_alter=1;
|
||||
lex->alter_flags=0;
|
||||
}
|
||||
alter_list
|
||||
{}
|
||||
@ -1718,16 +1738,28 @@ alter_list:
|
||||
| alter_list ',' alter_list_item;
|
||||
|
||||
add_column:
|
||||
ADD opt_column { Lex->change=0; };
|
||||
ADD opt_column
|
||||
{
|
||||
LEX *lex=Lex;
|
||||
lex->change=0;
|
||||
lex->alter_flags|= ALTER_ADD_COLUMN;
|
||||
};
|
||||
|
||||
alter_list_item:
|
||||
add_column column_def opt_place { Lex->simple_alter=0; }
|
||||
| ADD key_def { Lex->simple_alter=0; }
|
||||
| ADD key_def
|
||||
{
|
||||
LEX *lex=Lex;
|
||||
lex->simple_alter=0;
|
||||
lex->alter_flags|= ALTER_ADD_INDEX;
|
||||
}
|
||||
| add_column '(' field_list ')' { Lex->simple_alter=0; }
|
||||
| CHANGE opt_column field_ident
|
||||
{
|
||||
LEX *lex=Lex;
|
||||
lex->change= $3.str; lex->simple_alter=0;
|
||||
lex->change= $3.str;
|
||||
lex->simple_alter=0;
|
||||
lex->alter_flags|= ALTER_CHANGE_COLUMN;
|
||||
}
|
||||
field_spec opt_place
|
||||
| MODIFY_SYM opt_column field_ident
|
||||
@ -1738,6 +1770,7 @@ alter_list_item:
|
||||
lex->comment=0;
|
||||
lex->charset= NULL;
|
||||
lex->simple_alter=0;
|
||||
lex->alter_flags|= ALTER_CHANGE_COLUMN;
|
||||
}
|
||||
type opt_attribute
|
||||
{
|
||||
@ -1756,7 +1789,9 @@ alter_list_item:
|
||||
{
|
||||
LEX *lex=Lex;
|
||||
lex->drop_list.push_back(new Alter_drop(Alter_drop::COLUMN,
|
||||
$3.str)); lex->simple_alter=0;
|
||||
$3.str));
|
||||
lex->simple_alter=0;
|
||||
lex->alter_flags|= ALTER_DROP_COLUMN;
|
||||
}
|
||||
| DROP FOREIGN KEY_SYM opt_ident { Lex->simple_alter=0; }
|
||||
| DROP PRIMARY_SYM KEY_SYM
|
||||
@ -1765,6 +1800,7 @@ alter_list_item:
|
||||
lex->drop_list.push_back(new Alter_drop(Alter_drop::KEY,
|
||||
primary_key_name));
|
||||
lex->simple_alter=0;
|
||||
lex->alter_flags|= ALTER_DROP_INDEX;
|
||||
}
|
||||
| DROP key_or_index field_ident
|
||||
{
|
||||
@ -1772,6 +1808,7 @@ alter_list_item:
|
||||
lex->drop_list.push_back(new Alter_drop(Alter_drop::KEY,
|
||||
$3.str));
|
||||
lex->simple_alter=0;
|
||||
lex->alter_flags|= ALTER_DROP_INDEX;
|
||||
}
|
||||
| DISABLE_SYM KEYS { Lex->alter_keys_onoff=DISABLE; }
|
||||
| ENABLE_SYM KEYS { Lex->alter_keys_onoff=ENABLE; }
|
||||
@ -1780,18 +1817,21 @@ alter_list_item:
|
||||
LEX *lex=Lex;
|
||||
lex->alter_list.push_back(new Alter_column($3.str,$6));
|
||||
lex->simple_alter=0;
|
||||
lex->alter_flags|= ALTER_CHANGE_COLUMN;
|
||||
}
|
||||
| ALTER opt_column field_ident DROP DEFAULT
|
||||
{
|
||||
LEX *lex=Lex;
|
||||
lex->alter_list.push_back(new Alter_column($3.str,(Item*) 0));
|
||||
lex->simple_alter=0;
|
||||
lex->alter_flags|= ALTER_CHANGE_COLUMN;
|
||||
}
|
||||
| RENAME opt_to table_ident
|
||||
{
|
||||
LEX *lex=Lex;
|
||||
lex->select_lex.db=$3->db.str;
|
||||
lex->name= $3->table.str;
|
||||
lex->alter_flags|= ALTER_RENAME;
|
||||
}
|
||||
| CONVERT_SYM TO_SYM charset charset_name_or_default opt_collate
|
||||
{
|
||||
@ -1814,8 +1854,18 @@ alter_list_item:
|
||||
HA_CREATE_USED_DEFAULT_CHARSET);
|
||||
lex->simple_alter= 0;
|
||||
}
|
||||
| create_table_options_space_separated { Lex->simple_alter=0; }
|
||||
| order_clause { Lex->simple_alter=0; };
|
||||
| create_table_options_space_separated
|
||||
{
|
||||
LEX *lex=Lex;
|
||||
lex->simple_alter=0;
|
||||
lex->alter_flags|= ALTER_OPTIONS;
|
||||
}
|
||||
| order_clause
|
||||
{
|
||||
LEX *lex=Lex;
|
||||
lex->simple_alter=0;
|
||||
lex->alter_flags|= ALTER_ORDER;
|
||||
};
|
||||
|
||||
opt_column:
|
||||
/* empty */ {}
|
||||
|
@ -47,10 +47,11 @@ static bool make_empty_rec(int file, enum db_type table_type,
|
||||
uint reclength,uint null_fields);
|
||||
|
||||
|
||||
int rea_create_table(THD *thd, my_string file_name,
|
||||
int mysql_create_frm(THD *thd, my_string file_name,
|
||||
HA_CREATE_INFO *create_info,
|
||||
List<create_field> &create_fields,
|
||||
uint keys, KEY *key_info)
|
||||
uint keys, KEY *key_info,
|
||||
handler *db_file)
|
||||
{
|
||||
uint reclength,info_length,screens,key_info_length,maxlength,null_fields;
|
||||
File file;
|
||||
@ -58,12 +59,12 @@ int rea_create_table(THD *thd, my_string file_name,
|
||||
uchar fileinfo[64],forminfo[288],*keybuff;
|
||||
TYPELIB formnames;
|
||||
uchar *screen_buff;
|
||||
handler *db_file;
|
||||
DBUG_ENTER("rea_create_table");
|
||||
|
||||
formnames.type_names=0;
|
||||
if (!(screen_buff=pack_screens(create_fields,&info_length,&screens,0)))
|
||||
DBUG_RETURN(1);
|
||||
if (db_file == NULL)
|
||||
db_file=get_new_handler((TABLE*) 0, create_info->db_type);
|
||||
if (pack_header(forminfo, create_info->db_type,create_fields,info_length,
|
||||
screens, create_info->table_options, db_file))
|
||||
@ -155,8 +156,7 @@ int rea_create_table(THD *thd, my_string file_name,
|
||||
if (opt_sync_frm && !(create_info->options & HA_LEX_CREATE_TMP_TABLE) &&
|
||||
my_sync(file, MYF(MY_WME)))
|
||||
goto err2;
|
||||
if (my_close(file,MYF(MY_WME)) ||
|
||||
ha_create_table(file_name,create_info,0))
|
||||
if (my_close(file,MYF(MY_WME)))
|
||||
goto err3;
|
||||
DBUG_RETURN(0);
|
||||
|
||||
@ -166,6 +166,23 @@ err:
|
||||
err2:
|
||||
VOID(my_close(file,MYF(MY_WME)));
|
||||
err3:
|
||||
DBUG_RETURN(1);
|
||||
} /* mysql_create_frm */
|
||||
|
||||
int rea_create_table(THD *thd, my_string file_name,
|
||||
HA_CREATE_INFO *create_info,
|
||||
List<create_field> &create_fields,
|
||||
uint keys, KEY *key_info)
|
||||
{
|
||||
DBUG_ENTER("rea_create_table");
|
||||
|
||||
if (mysql_create_frm(thd, file_name, create_info,
|
||||
create_fields, keys, key_info, NULL) ||
|
||||
ha_create_table(file_name,create_info,0))
|
||||
goto err;
|
||||
DBUG_RETURN(0);
|
||||
|
||||
err:
|
||||
my_delete(file_name,MYF(0));
|
||||
DBUG_RETURN(1);
|
||||
} /* rea_create_table */
|
||||
|
Reference in New Issue
Block a user