mirror of
https://github.com/MariaDB/server.git
synced 2025-07-29 05:21:33 +03:00
Merge with 4.1.3-beta
This commit is contained in:
137
sql/sql_table.cc
137
sql/sql_table.cc
@ -191,7 +191,7 @@ int mysql_rm_table_part2(THD *thd, TABLE_LIST *tables, bool if_exists,
|
||||
for (table=tables ; table ; table=table->next)
|
||||
{
|
||||
char *db=table->db;
|
||||
mysql_ha_closeall(thd, table);
|
||||
mysql_ha_close(thd, table, /*dont_send_ok*/ 1, /*dont_lock*/ 1);
|
||||
if (!close_temporary_table(thd, db, table->real_name))
|
||||
{
|
||||
tmp_table_deleted=1;
|
||||
@ -254,12 +254,23 @@ int mysql_rm_table_part2(THD *thd, TABLE_LIST *tables, bool if_exists,
|
||||
}
|
||||
}
|
||||
thd->tmp_table_used= tmp_table_deleted;
|
||||
if (some_tables_deleted || tmp_table_deleted)
|
||||
error= 0;
|
||||
if (wrong_tables.length())
|
||||
{
|
||||
if (!foreign_key_error)
|
||||
my_error(ER_BAD_TABLE_ERROR,MYF(0), wrong_tables.c_ptr());
|
||||
else
|
||||
my_error(ER_ROW_IS_REFERENCED, MYF(0));
|
||||
error= 1;
|
||||
}
|
||||
|
||||
if (some_tables_deleted || tmp_table_deleted || !error)
|
||||
{
|
||||
query_cache_invalidate3(thd, tables, 0);
|
||||
if (!dont_log_query && mysql_bin_log.is_open())
|
||||
{
|
||||
thd->clear_error();
|
||||
if (!error)
|
||||
thd->clear_error();
|
||||
Query_log_event qinfo(thd, thd->query, thd->query_length,
|
||||
tmp_table_deleted && !some_tables_deleted);
|
||||
mysql_bin_log.write(&qinfo);
|
||||
@ -267,15 +278,6 @@ int mysql_rm_table_part2(THD *thd, TABLE_LIST *tables, bool if_exists,
|
||||
}
|
||||
|
||||
unlock_table_names(thd, tables);
|
||||
error= 0;
|
||||
if (wrong_tables.length())
|
||||
{
|
||||
if (!foreign_key_error)
|
||||
my_error(ER_BAD_TABLE_ERROR,MYF(0),wrong_tables.c_ptr());
|
||||
else
|
||||
my_error(ER_ROW_IS_REFERENCED,MYF(0));
|
||||
error= 1;
|
||||
}
|
||||
DBUG_RETURN(error);
|
||||
}
|
||||
|
||||
@ -525,7 +527,7 @@ int mysql_prepare_table(THD *thd, HA_CREATE_INFO *create_info,
|
||||
break;
|
||||
case FIELD_TYPE_GEOMETRY:
|
||||
#ifdef HAVE_SPATIAL
|
||||
if (!(file->table_flags() & HA_HAS_GEOMETRY))
|
||||
if (!(file->table_flags() & HA_CAN_GEOMETRY))
|
||||
{
|
||||
my_printf_error(ER_CHECK_NOT_IMPLEMENTED, ER(ER_CHECK_NOT_IMPLEMENTED),
|
||||
MYF(0), "GEOMETRY");
|
||||
@ -663,7 +665,7 @@ int mysql_prepare_table(THD *thd, HA_CREATE_INFO *create_info,
|
||||
continue;
|
||||
}
|
||||
(*key_count)++;
|
||||
tmp=max(file->max_key_parts(),MAX_REF_PARTS);
|
||||
tmp=file->max_key_parts();
|
||||
if (key->columns.elements > tmp)
|
||||
{
|
||||
my_error(ER_TOO_MANY_KEY_PARTS,MYF(0),tmp);
|
||||
@ -715,7 +717,7 @@ int mysql_prepare_table(THD *thd, HA_CREATE_INFO *create_info,
|
||||
DBUG_RETURN(-1);
|
||||
}
|
||||
}
|
||||
tmp=min(file->max_keys(), MAX_KEY);
|
||||
tmp=file->max_keys();
|
||||
if (*key_count > tmp)
|
||||
{
|
||||
my_error(ER_TOO_MANY_KEYS,MYF(0),tmp);
|
||||
@ -852,7 +854,7 @@ int mysql_prepare_table(THD *thd, HA_CREATE_INFO *create_info,
|
||||
sql_field->sql_type != FIELD_TYPE_VAR_STRING &&
|
||||
!f_is_blob(sql_field->pack_flag)) ||
|
||||
sql_field->charset == &my_charset_bin ||
|
||||
sql_field->charset->state & MY_CS_NONTEXT || // ucs2 doesn't work yet
|
||||
sql_field->charset->mbminlen > 1 || // ucs2 doesn't work yet
|
||||
(ft_key_charset && sql_field->charset != ft_key_charset))
|
||||
{
|
||||
my_printf_error(ER_BAD_FT_COLUMN,ER(ER_BAD_FT_COLUMN),MYF(0),
|
||||
@ -875,7 +877,7 @@ int mysql_prepare_table(THD *thd, HA_CREATE_INFO *create_info,
|
||||
|
||||
if (f_is_blob(sql_field->pack_flag))
|
||||
{
|
||||
if (!(file->table_flags() & HA_BLOB_KEY))
|
||||
if (!(file->table_flags() & HA_CAN_INDEX_BLOBS))
|
||||
{
|
||||
my_printf_error(ER_BLOB_USED_AS_KEY,ER(ER_BLOB_USED_AS_KEY),MYF(0),
|
||||
column->field_name);
|
||||
@ -912,7 +914,7 @@ int mysql_prepare_table(THD *thd, HA_CREATE_INFO *create_info,
|
||||
}
|
||||
else
|
||||
key_info->flags|= HA_NULL_PART_KEY;
|
||||
if (!(file->table_flags() & HA_NULL_KEY))
|
||||
if (!(file->table_flags() & HA_NULL_IN_KEY))
|
||||
{
|
||||
my_printf_error(ER_NULL_COLUMN_IN_INDEX,ER(ER_NULL_COLUMN_IN_INDEX),
|
||||
MYF(0),column->field_name);
|
||||
@ -1044,7 +1046,7 @@ int mysql_prepare_table(THD *thd, HA_CREATE_INFO *create_info,
|
||||
if (!(key_info->flags & HA_NULL_PART_KEY))
|
||||
unique_key=1;
|
||||
key_info->key_length=(uint16) key_length;
|
||||
uint max_key_length= min(file->max_key_length(), MAX_KEY_LENGTH);
|
||||
uint max_key_length= file->max_key_length();
|
||||
if (key_length > max_key_length && key->type != Key::FULLTEXT)
|
||||
{
|
||||
my_error(ER_TOO_LONG_KEY,MYF(0),max_key_length);
|
||||
@ -1136,12 +1138,21 @@ int mysql_create_table(THD *thd,const char *db, const char *table_name,
|
||||
alias= table_case_name(create_info, table_name);
|
||||
file=get_new_handler((TABLE*) 0, create_info->db_type);
|
||||
|
||||
#ifdef NOT_USED
|
||||
/*
|
||||
if there is a technical reason for a handler not to have support
|
||||
for temp. tables this code can be re-enabled.
|
||||
Otherwise, if a handler author has a wish to prohibit usage of
|
||||
temporary tables for his handler he should implement a check in
|
||||
::create() method
|
||||
*/
|
||||
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);
|
||||
}
|
||||
#endif
|
||||
|
||||
if (mysql_prepare_table(thd, create_info, fields,
|
||||
keys, tmp_table, db_options, file,
|
||||
@ -1707,7 +1718,7 @@ static int mysql_admin_table(THD* thd, TABLE_LIST* tables,
|
||||
if (protocol->send_fields(&field_list, 1))
|
||||
DBUG_RETURN(-1);
|
||||
|
||||
mysql_ha_closeall(thd, tables);
|
||||
mysql_ha_close(thd, tables, /*dont_send_ok*/ 1, /*dont_lock*/ 1);
|
||||
for (table = tables; table; table = table->next)
|
||||
{
|
||||
char table_name[NAME_LEN*2+2];
|
||||
@ -1793,6 +1804,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);
|
||||
|
||||
send_result_message:
|
||||
|
||||
DBUG_PRINT("info", ("result_code: %d", result_code));
|
||||
switch (result_code) {
|
||||
case HA_ADMIN_NOT_IMPLEMENTED:
|
||||
{
|
||||
@ -1836,6 +1850,29 @@ static int mysql_admin_table(THD* thd, TABLE_LIST* tables,
|
||||
protocol->store("Invalid argument",16, system_charset_info);
|
||||
break;
|
||||
|
||||
case HA_ADMIN_TRY_ALTER:
|
||||
{
|
||||
/*
|
||||
This is currently used only by InnoDB. ha_innobase::optimize() answers
|
||||
"try with alter", so here we close the table, do an ALTER TABLE,
|
||||
reopen the table and do ha_innobase::analyze() on it.
|
||||
*/
|
||||
close_thread_tables(thd);
|
||||
TABLE_LIST *save_next= table->next;
|
||||
table->next= 0;
|
||||
result_code= mysql_recreate_table(thd, table, 0);
|
||||
close_thread_tables(thd);
|
||||
if (!result_code) // recreation went ok
|
||||
{
|
||||
if ((table->table= open_ltable(thd, table, lock_type)) &&
|
||||
((result_code= table->table->file->analyze(thd, check_opt)) > 0))
|
||||
result_code= 0; // analyze went ok
|
||||
}
|
||||
result_code= result_code ? HA_ADMIN_FAILED : HA_ADMIN_OK;
|
||||
table->next= save_next;
|
||||
goto send_result_message;
|
||||
}
|
||||
|
||||
default: // Probably HA_ADMIN_INTERNAL_ERROR
|
||||
protocol->store("error", 5, system_charset_info);
|
||||
protocol->store("Unknown - internal error during operation", 41
|
||||
@ -2207,7 +2244,7 @@ int mysql_discard_or_import_tablespace(THD *thd,
|
||||
thd->tablespace_op=TRUE; /* we set this flag so that ha_innobase::open
|
||||
and ::external_lock() do not complain when we
|
||||
lock the table */
|
||||
mysql_ha_closeall(thd, table_list);
|
||||
mysql_ha_close(thd, table_list, /*dont_send_ok*/ 1, /*dont_lock*/ 1);
|
||||
|
||||
if (!(table=open_ltable(thd,table_list,TL_WRITE)))
|
||||
{
|
||||
@ -2463,7 +2500,7 @@ int mysql_alter_table(THD *thd,char *new_db, char *new_name,
|
||||
List<create_field> &fields, List<Key> &keys,
|
||||
uint order_num, ORDER *order,
|
||||
enum enum_duplicates handle_duplicates,
|
||||
ALTER_INFO *alter_info)
|
||||
ALTER_INFO *alter_info, bool do_send_ok)
|
||||
{
|
||||
TABLE *table,*new_table;
|
||||
int error;
|
||||
@ -2485,7 +2522,7 @@ int mysql_alter_table(THD *thd,char *new_db, char *new_name,
|
||||
new_db= db;
|
||||
used_fields=create_info->used_fields;
|
||||
|
||||
mysql_ha_closeall(thd, table_list);
|
||||
mysql_ha_close(thd, table_list, /*dont_send_ok*/ 1, /*dont_lock*/ 1);
|
||||
|
||||
/* DISCARD/IMPORT TABLESPACE is always alone in an ALTER TABLE */
|
||||
if (alter_info->tablespace_op != NO_TABLESPACE_OP)
|
||||
@ -2540,7 +2577,10 @@ int mysql_alter_table(THD *thd,char *new_db, char *new_name,
|
||||
}
|
||||
}
|
||||
else
|
||||
new_alias= new_name= table_name;
|
||||
{
|
||||
new_alias= (lower_case_table_names == 2) ? alias : table_name;
|
||||
new_name= table_name;
|
||||
}
|
||||
|
||||
old_db_type=table->db_type;
|
||||
if (create_info->db_type == DB_TYPE_DEFAULT)
|
||||
@ -2619,7 +2659,8 @@ int mysql_alter_table(THD *thd,char *new_db, char *new_name,
|
||||
Query_log_event qinfo(thd, thd->query, thd->query_length, 0);
|
||||
mysql_bin_log.write(&qinfo);
|
||||
}
|
||||
send_ok(thd);
|
||||
if (do_send_ok)
|
||||
send_ok(thd);
|
||||
}
|
||||
else
|
||||
{
|
||||
@ -3180,7 +3221,8 @@ end_temporary:
|
||||
my_snprintf(tmp_name, sizeof(tmp_name), ER(ER_INSERT_INFO),
|
||||
(ulong) (copied + deleted), (ulong) deleted,
|
||||
(ulong) thd->cuted_fields);
|
||||
send_ok(thd,copied+deleted,0L,tmp_name);
|
||||
if (do_send_ok)
|
||||
send_ok(thd,copied+deleted,0L,tmp_name);
|
||||
thd->some_tables_deleted=0;
|
||||
DBUG_RETURN(0);
|
||||
|
||||
@ -3261,7 +3303,11 @@ copy_data_between_tables(TABLE *from,TABLE *to,
|
||||
error= 1;
|
||||
goto err;
|
||||
}
|
||||
|
||||
|
||||
/* Handler must be told explicitly to retrieve all columns, because
|
||||
this function does not set field->query_id in the columns to the
|
||||
current query id */
|
||||
from->file->extra(HA_EXTRA_RETRIEVE_ALL_COLS);
|
||||
init_read_record(&info, thd, from, (SQL_SELECT *) 0, 1,1);
|
||||
if (handle_duplicates == DUP_IGNORE ||
|
||||
handle_duplicates == DUP_REPLACE)
|
||||
@ -3326,6 +3372,40 @@ copy_data_between_tables(TABLE *from,TABLE *to,
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
Recreates tables by calling mysql_alter_table().
|
||||
|
||||
SYNOPSIS
|
||||
mysql_recreate_table()
|
||||
thd Thread handler
|
||||
tables Tables to recreate
|
||||
do_send_ok If we should send_ok() or leave it to caller
|
||||
|
||||
RETURN
|
||||
Like mysql_alter_table().
|
||||
*/
|
||||
int mysql_recreate_table(THD *thd, TABLE_LIST *table_list,
|
||||
bool do_send_ok)
|
||||
{
|
||||
DBUG_ENTER("mysql_recreate_table");
|
||||
LEX *lex= thd->lex;
|
||||
HA_CREATE_INFO create_info;
|
||||
lex->create_list.empty();
|
||||
lex->key_list.empty();
|
||||
lex->col_list.empty();
|
||||
lex->alter_info.reset();
|
||||
lex->alter_info.is_simple= 0; // Force full recreate
|
||||
bzero((char*) &create_info,sizeof(create_info));
|
||||
create_info.db_type=DB_TYPE_DEFAULT;
|
||||
create_info.row_type=ROW_TYPE_DEFAULT;
|
||||
create_info.default_table_charset=default_charset_info;
|
||||
DBUG_RETURN(mysql_alter_table(thd, NullS, NullS, &create_info,
|
||||
table_list, lex->create_list,
|
||||
lex->key_list, 0, (ORDER *) 0,
|
||||
DUP_ERROR, &lex->alter_info, do_send_ok));
|
||||
}
|
||||
|
||||
|
||||
int mysql_checksum_table(THD *thd, TABLE_LIST *tables, HA_CHECK_OPT *check_opt)
|
||||
{
|
||||
TABLE_LIST *table;
|
||||
@ -3380,7 +3460,7 @@ int mysql_checksum_table(THD *thd, TABLE_LIST *tables, HA_CHECK_OPT *check_opt)
|
||||
current query id */
|
||||
t->file->extra(HA_EXTRA_RETRIEVE_ALL_COLS);
|
||||
|
||||
if (t->file->rnd_init(1))
|
||||
if (t->file->ha_rnd_init(1))
|
||||
protocol->store_null();
|
||||
else
|
||||
{
|
||||
@ -3408,6 +3488,7 @@ int mysql_checksum_table(THD *thd, TABLE_LIST *tables, HA_CHECK_OPT *check_opt)
|
||||
crc+= row_crc;
|
||||
}
|
||||
protocol->store((ulonglong)crc);
|
||||
t->file->ha_rnd_end();
|
||||
}
|
||||
}
|
||||
thd->clear_error();
|
||||
|
Reference in New Issue
Block a user