summaryrefslogtreecommitdiff
path: root/sql/sql_table.cc
diff options
context:
space:
mode:
Diffstat (limited to 'sql/sql_table.cc')
-rw-r--r--sql/sql_table.cc99
1 files changed, 58 insertions, 41 deletions
diff --git a/sql/sql_table.cc b/sql/sql_table.cc
index 896b681fc08..a43344e902b 100644
--- a/sql/sql_table.cc
+++ b/sql/sql_table.cc
@@ -1521,6 +1521,8 @@ int mysql_rm_table_part2(THD *thd, TABLE_LIST *tables, bool if_exists,
built_query.append("DROP TABLE ");
}
+ mysql_ha_rm_tables(thd, tables, FALSE);
+
pthread_mutex_lock(&LOCK_open);
/*
@@ -1556,9 +1558,6 @@ int mysql_rm_table_part2(THD *thd, TABLE_LIST *tables, bool if_exists,
/* Don't give warnings for not found errors, as we already generate notes */
thd->no_warnings_for_error= 1;
- /* Remove the tables from the HANDLER list, if they are in it. */
- mysql_ha_flush(thd, tables, MYSQL_HA_CLOSE_FINAL, 1);
-
for (table= tables; table; table= table->next_local)
{
char *db=table->db;
@@ -1577,13 +1576,7 @@ int mysql_rm_table_part2(THD *thd, TABLE_LIST *tables, bool if_exists,
tmp_table_deleted= 1;
continue;
case -1:
- // table already in use
- /*
- XXX: This branch should never be taken outside of SF, trigger or
- prelocked mode.
-
- DBUG_ASSERT(thd->in_sub_stmt);
- */
+ DBUG_ASSERT(thd->in_sub_stmt);
error= 1;
goto err_with_placeholders;
default:
@@ -1805,7 +1798,8 @@ bool quick_rm_table(handlerton *base,const char *db,
/*
Sort keys in the following order:
- PRIMARY KEY
- - UNIQUE keyws where all column are NOT NULL
+ - UNIQUE keys where all column are NOT NULL
+ - UNIQUE keys that don't contain partial segments
- Other UNIQUE keys
- Normal keys
- Fulltext keys
@@ -1816,26 +1810,31 @@ bool quick_rm_table(handlerton *base,const char *db,
static int sort_keys(KEY *a, KEY *b)
{
- if (a->flags & HA_NOSAME)
+ ulong a_flags= a->flags, b_flags= b->flags;
+
+ if (a_flags & HA_NOSAME)
{
- if (!(b->flags & HA_NOSAME))
+ if (!(b_flags & HA_NOSAME))
return -1;
- if ((a->flags ^ b->flags) & (HA_NULL_PART_KEY | HA_END_SPACE_KEY))
+ if ((a_flags ^ b_flags) & (HA_NULL_PART_KEY | HA_END_SPACE_KEY))
{
/* Sort NOT NULL keys before other keys */
- return (a->flags & (HA_NULL_PART_KEY | HA_END_SPACE_KEY)) ? 1 : -1;
+ return (a_flags & (HA_NULL_PART_KEY | HA_END_SPACE_KEY)) ? 1 : -1;
}
if (a->name == primary_key_name)
return -1;
if (b->name == primary_key_name)
return 1;
+ /* Sort keys don't containing partial segments before others */
+ if ((a_flags ^ b_flags) & HA_KEY_HAS_PART_KEY_SEG)
+ return (a_flags & HA_KEY_HAS_PART_KEY_SEG) ? 1 : -1;
}
- else if (b->flags & HA_NOSAME)
+ else if (b_flags & HA_NOSAME)
return 1; // Prefer b
- if ((a->flags ^ b->flags) & HA_FULLTEXT)
+ if ((a_flags ^ b_flags) & HA_FULLTEXT)
{
- return (a->flags & HA_FULLTEXT) ? 1 : -1;
+ return (a_flags & HA_FULLTEXT) ? 1 : -1;
}
/*
Prefer original key order. usable_key_parts contains here
@@ -2899,6 +2898,10 @@ mysql_prepare_create_table(THD *thd, HA_CREATE_INFO *create_info,
else
key_info->flags|= HA_PACK_KEY;
}
+ /* Check if the key segment is partial, set the key flag accordingly */
+ if (length != sql_field->key_length)
+ key_info->flags|= HA_KEY_HAS_PART_KEY_SEG;
+
key_length+=length;
key_part_info++;
@@ -2954,8 +2957,8 @@ mysql_prepare_create_table(THD *thd, HA_CREATE_INFO *create_info,
DBUG_RETURN(TRUE);
}
/* Sort keys in optimized order */
- qsort((uchar*) *key_info_buffer, *key_count, sizeof(KEY),
- (qsort_cmp) sort_keys);
+ my_qsort((uchar*) *key_info_buffer, *key_count, sizeof(KEY),
+ (qsort_cmp) sort_keys);
create_info->null_bits= null_fields;
DBUG_RETURN(FALSE);
@@ -3712,14 +3715,16 @@ mysql_rename_table(handlerton *base, const char *old_db,
Win32 clients must also have a WRITE LOCK on the table !
*/
-static void wait_while_table_is_used(THD *thd,TABLE *table,
- enum ha_extra_function function)
+void wait_while_table_is_used(THD *thd, TABLE *table,
+ enum ha_extra_function function)
{
DBUG_ENTER("wait_while_table_is_used");
DBUG_PRINT("enter", ("table: '%s' share: 0x%lx db_stat: %u version: %lu",
table->s->table_name.str, (ulong) table->s,
table->db_stat, table->s->version));
+ safe_mutex_assert_owner(&LOCK_open);
+
VOID(table->file->extra(function));
/* Mark all tables that are in use as 'old' */
mysql_lock_abort(thd, table, TRUE); /* end threads waiting on lock */
@@ -4038,7 +4043,8 @@ static bool mysql_admin_table(THD* thd, TABLE_LIST* tables,
Protocol::SEND_NUM_ROWS | Protocol::SEND_EOF))
DBUG_RETURN(TRUE);
- mysql_ha_flush(thd, tables, MYSQL_HA_CLOSE_FINAL, FALSE);
+ mysql_ha_rm_tables(thd, tables, FALSE);
+
for (table= tables; table; table= table->next_local)
{
char table_name[NAME_LEN*2+2];
@@ -5801,8 +5807,7 @@ bool mysql_alter_table(THD *thd,char *new_db, char *new_name,
build_table_filename(reg_path, sizeof(reg_path), db, table_name, reg_ext, 0);
build_table_filename(path, sizeof(path), db, table_name, "", 0);
-
- mysql_ha_flush(thd, table_list, MYSQL_HA_CLOSE_FINAL, FALSE);
+ mysql_ha_rm_tables(thd, table_list, FALSE);
/* DISCARD/IMPORT TABLESPACE is always alone in an ALTER TABLE */
if (alter_info->tablespace_op != NO_TABLESPACE_OP)
@@ -6885,23 +6890,35 @@ copy_data_between_tables(TABLE *from,TABLE *to,
if (order)
{
- from->sort.io_cache=(IO_CACHE*) my_malloc(sizeof(IO_CACHE),
- MYF(MY_FAE | MY_ZEROFILL));
- bzero((char*) &tables,sizeof(tables));
- tables.table= from;
- tables.alias= tables.table_name= from->s->table_name.str;
- tables.db= from->s->db.str;
- error=1;
+ if (to->s->primary_key != MAX_KEY && to->file->primary_key_is_clustered())
+ {
+ char warn_buff[MYSQL_ERRMSG_SIZE];
+ my_snprintf(warn_buff, sizeof(warn_buff),
+ "ORDER BY ignored as there is a user-defined clustered index"
+ " in the table '%-.192s'", from->s->table_name.str);
+ push_warning(thd, MYSQL_ERROR::WARN_LEVEL_WARN, ER_UNKNOWN_ERROR,
+ warn_buff);
+ }
+ else
+ {
+ from->sort.io_cache=(IO_CACHE*) my_malloc(sizeof(IO_CACHE),
+ MYF(MY_FAE | MY_ZEROFILL));
+ bzero((char *) &tables, sizeof(tables));
+ tables.table= from;
+ tables.alias= tables.table_name= from->s->table_name.str;
+ tables.db= from->s->db.str;
+ error= 1;
- if (thd->lex->select_lex.setup_ref_array(thd, order_num) ||
- setup_order(thd, thd->lex->select_lex.ref_pointer_array,
- &tables, fields, all_fields, order) ||
- !(sortorder=make_unireg_sortorder(order, &length, NULL)) ||
- (from->sort.found_records = filesort(thd, from, sortorder, length,
- (SQL_SELECT *) 0, HA_POS_ERROR, 1,
- &examined_rows)) ==
- HA_POS_ERROR)
- goto err;
+ if (thd->lex->select_lex.setup_ref_array(thd, order_num) ||
+ setup_order(thd, thd->lex->select_lex.ref_pointer_array,
+ &tables, fields, all_fields, order) ||
+ !(sortorder= make_unireg_sortorder(order, &length, NULL)) ||
+ (from->sort.found_records= filesort(thd, from, sortorder, length,
+ (SQL_SELECT *) 0, HA_POS_ERROR,
+ 1, &examined_rows)) ==
+ HA_POS_ERROR)
+ goto err;
+ }
};
/* Tell handler that we have values for all columns in the to table */