1
0
mirror of https://github.com/MariaDB/server.git synced 2025-12-24 11:21:21 +03:00

Merge maria-5.5-mwl248 -> 10.0-base.

This commit is contained in:
Igor Babaev
2012-12-16 21:33:17 -08:00
89 changed files with 8929 additions and 128 deletions

View File

@@ -43,6 +43,7 @@
#include "discover.h" // readfrm
#include "my_pthread.h" // pthread_mutex_t
#include "log_event.h" // Query_log_event
#include "sql_statistics.h"
#include <hash.h>
#include <myisam.h>
#include <my_dir.h>
@@ -1886,6 +1887,17 @@ bool mysql_rm_table(THD *thd,TABLE_LIST *tables, my_bool if_exists,
}
}
if (!in_bootstrap)
{
for (table= tables; table; table= table->next_local)
{
LEX_STRING db_name= { table->db, table->db_length };
LEX_STRING table_name= { table->table_name, table->table_name_length };
if (table->open_type == OT_BASE_ONLY || !find_temporary_table(thd, table))
(void) delete_statistics_for_table(thd, &db_name, &table_name);
}
}
mysql_ha_rm_tables(thd, tables);
if (!drop_temporary)
@@ -1896,6 +1908,7 @@ bool mysql_rm_table(THD *thd,TABLE_LIST *tables, my_bool if_exists,
MYSQL_OPEN_SKIP_TEMPORARY))
DBUG_RETURN(true);
for (table= tables; table; table= table->next_local)
tdc_remove_table(thd, TDC_RT_REMOVE_ALL, table->db, table->table_name,
false);
}
@@ -5156,6 +5169,21 @@ mysql_compare_tables(TABLE *table,
thd->calloc(sizeof(void*) * table->s->keys)) == NULL)
DBUG_RETURN(1);
tmp_new_field_it.init(tmp_alter_info.create_list);
for (i= 0, f_ptr= table->field, tmp_new_field= tmp_new_field_it++;
(field= *f_ptr);
i++, f_ptr++, tmp_new_field= tmp_new_field_it++)
{
if (field->is_equal(tmp_new_field) == IS_EQUAL_NO &&
table->s->tmp_table == NO_TMP_TABLE)
(void) delete_statistics_for_column(thd, table, field);
else if (my_strcasecmp(system_charset_info,
field->field_name,
tmp_new_field->field_name))
(void) rename_column_in_stat_tables(thd, table, field,
tmp_new_field->field_name);
}
/*
Use transformed info to evaluate possibility of in-place ALTER TABLE
but use the preserved field to persist modifications.
@@ -5216,11 +5244,36 @@ mysql_compare_tables(TABLE *table,
if (my_strcasecmp(system_charset_info,
field->field_name,
tmp_new_field->field_name))
field->flags|= FIELD_IS_RENAMED;
{
field->flags|= FIELD_IS_RENAMED;
if (table->s->tmp_table == NO_TMP_TABLE)
rename_column_in_stat_tables(thd, table, field,
tmp_new_field->field_name);
}
/* Evaluate changes bitmap and send to check_if_incompatible_data() */
if (!(tmp= field->is_equal(tmp_new_field)))
{
if (table->s->tmp_table == NO_TMP_TABLE)
{
KEY *key_info= table->key_info;
for (uint i=0; i < table->s->keys; i++, key_info++)
{
if (field->part_of_key.is_set(i))
{
uint key_parts= table->actual_n_key_parts(key_info);
for (uint j= 0; j < key_parts; j++)
{
if (key_info->key_part[j].fieldnr-1 == field->field_index)
{
(void) delete_statistics_for_index(thd, table, key_info,
j >= key_info->key_parts);
break;
}
}
}
}
}
DBUG_PRINT("info", ("!field_is_equal('%s') -> ALTER_TABLE_DATA_CHANGED",
new_field->field_name));
DBUG_RETURN(0);
@@ -5319,6 +5372,21 @@ mysql_compare_tables(TABLE *table,
field= table->field[key_part->fieldnr];
field->flags|= FIELD_IN_ADD_INDEX;
}
if (table->s->tmp_table == NO_TMP_TABLE)
{
(void) delete_statistics_for_index(thd, table, table_key, FALSE);
if (table_key - table->key_info == table->s->primary_key)
{
KEY *tab_key_info= table->key_info;
for (uint j=0; j < table->s->keys; j++, tab_key_info++)
{
if (tab_key_info->key_parts != tab_key_info->ext_key_parts)
(void) delete_statistics_for_index(thd, table, tab_key_info,
TRUE);
}
}
}
DBUG_PRINT("info", ("index changed: '%s'", table_key->name));
}
/*end of for (; table_key < table_key_end;) */
@@ -5520,6 +5588,7 @@ mysql_prepare_alter_table(THD *thd, TABLE *table,
uint used_fields= create_info->used_fields;
KEY *key_info=table->key_info;
bool rc= TRUE;
bool modified_primary_key= FALSE;
Create_field *def;
Field **f_ptr,*field;
DBUG_ENTER("mysql_prepare_alter_table");
@@ -5576,6 +5645,8 @@ mysql_prepare_alter_table(THD *thd, TABLE *table,
}
if (drop)
{
if (table->s->tmp_table == NO_TMP_TABLE)
(void) delete_statistics_for_column(thd, table, field);
drop_it.remove();
/*
ALTER TABLE DROP COLUMN always changes table data even in cases
@@ -5714,7 +5785,7 @@ mysql_prepare_alter_table(THD *thd, TABLE *table,
Collect all keys which isn't in drop list. Add only those
for which some fields exists.
*/
for (uint i=0 ; i < table->s->keys ; i++,key_info++)
{
char *key_name= key_info->name;
@@ -5728,12 +5799,27 @@ mysql_prepare_alter_table(THD *thd, TABLE *table,
}
if (drop)
{
if (table->s->tmp_table == NO_TMP_TABLE)
{
(void) delete_statistics_for_index(thd, table, key_info, FALSE);
if (i == table->s->primary_key)
{
KEY *tab_key_info= table->key_info;
for (uint j=0; j < table->s->keys; j++, tab_key_info++)
{
if (tab_key_info->key_parts != tab_key_info->ext_key_parts)
(void) delete_statistics_for_index(thd, table, tab_key_info,
TRUE);
}
}
}
drop_it.remove();
continue;
}
KEY_PART_INFO *key_part= key_info->key_part;
key_parts.empty();
bool delete_index_stat= FALSE;
for (uint j=0 ; j < key_info->key_parts ; j++,key_part++)
{
if (!key_part->field)
@@ -5756,7 +5842,12 @@ mysql_prepare_alter_table(THD *thd, TABLE *table,
break;
}
if (!cfield)
{
if (table->s->primary_key == i)
modified_primary_key= TRUE;
delete_index_stat= TRUE;
continue; // Field is removed
}
key_part_length= key_part->length;
if (cfield->field) // Not new field
{
@@ -5798,6 +5889,15 @@ mysql_prepare_alter_table(THD *thd, TABLE *table,
strlen(cfield->field_name),
key_part_length));
}
if (table->s->tmp_table == NO_TMP_TABLE)
{
if (delete_index_stat)
(void) delete_statistics_for_index(thd, table, key_info, FALSE);
else if (modified_primary_key &&
key_info->key_parts != key_info->ext_key_parts)
(void) delete_statistics_for_index(thd, table, key_info, TRUE);
}
if (key_parts.elements)
{
KEY_CREATE_INFO key_create_info;
@@ -5977,6 +6077,9 @@ bool mysql_alter_table(THD *thd,char *new_db, char *new_name,
enum ha_extra_function extra_func= thd->locked_tables_mode
? HA_EXTRA_NOT_USED
: HA_EXTRA_FORCE_REOPEN;
LEX_STRING old_db_name= { table_list->db, table_list->db_length };
LEX_STRING old_table_name= { table_list->table_name,
table_list->table_name_length };
DBUG_ENTER("mysql_alter_table");
/*
@@ -6295,6 +6398,12 @@ bool mysql_alter_table(THD *thd,char *new_db, char *new_name,
else
{
*fn_ext(new_name)=0;
LEX_STRING new_db_name= { new_db, strlen(new_db) };
LEX_STRING new_table_name= { new_alias, strlen(new_alias) };
(void) rename_table_in_stat_tables(thd, &old_db_name, &old_table_name,
&new_db_name, &new_table_name);
if (mysql_rename_table(old_db_type,db,table_name,new_db,new_alias, 0))
error= -1;
else if (Table_triggers_list::change_table_name(thd, db,
@@ -7038,6 +7147,15 @@ bool mysql_alter_table(THD *thd,char *new_db, char *new_name,
table is renamed and the SE is also changed, then an intermediate table
is created and the additional call will not take place.
*/
if (new_name != table_name || new_db != db)
{
LEX_STRING new_db_name= { new_db, strlen(new_db) };
LEX_STRING new_table_name= { new_name, strlen(new_name) };
(void) rename_table_in_stat_tables(thd, &old_db_name, &old_table_name,
&new_db_name, &new_table_name);
}
if (need_copy_table == ALTER_TABLE_METADATA_ONLY)
{
DBUG_ASSERT(new_db_type == old_db_type);