diff options
author | Mattias Jonsson <mattias.jonsson@oracle.com> | 2010-08-16 14:53:30 +0200 |
---|---|---|
committer | Mattias Jonsson <mattias.jonsson@oracle.com> | 2010-08-16 14:53:30 +0200 |
commit | 36c8248056802958d692749ce20b8503a781ed8c (patch) | |
tree | c70fa0c8e6b1e40f9c93c89eed5cb4337b1b681c /sql/sql_alter_table.cc | |
parent | ca0268fd2c8b84b450643dc949a9289f6ed6673a (diff) | |
download | mariadb-git-36c8248056802958d692749ce20b8503a781ed8c.tar.gz |
Bug#49907: ALTER TABLE ... TRUNCATE PARTITION does not wait for
locks on the table
Fixing the partitioning specifics after TRUNCATE TABLE in
bug-42643 was fixed.
Reorganize of code to decrease the size of the giant switch
in mysql_execute_command, and to prepare for future parser
reengineering. Moved code into Sql_statement objects.
Updated patch according to davi's review comments.
libmysqld/CMakeLists.txt:
Added new files.
libmysqld/Makefile.am:
Added new files.
mysql-test/r/not_partition.result:
now returning error on partitioning commands
if partitioning is not enabled.
mysql-test/r/partition_disabled.result:
There is no partition handlerton, so it cannot
find the specified engine in the .frm file.
mysql-test/r/partition_truncate.result:
Updated test results.
mysql-test/suite/parts/inc/partition_mgm.inc:
Added check that TRUNCATE PARTITION does not delete on failure.
mysql-test/suite/parts/r/partition_debug_sync_innodb.result:
updated results.
mysql-test/suite/parts/r/partition_mgm_lc0_archive.result:
updated results.
mysql-test/suite/parts/r/partition_mgm_lc1_archive.result:
updated results.
mysql-test/suite/parts/r/partition_mgm_lc2_archive.result:
updated results.
mysql-test/suite/parts/t/partition_debug_sync_innodb.test:
Test case for this bug.
mysql-test/t/not_partition.test:
Added check for TRUNCATE PARTITION without partitioning.
mysql-test/t/partition_truncate.test:
Added test of TRUNCATE PARTITION on non partitioned table.
sql/CMakeLists.txt:
Added new files.
sql/Makefile.am:
Added new files.
sql/datadict.cc:
Moved out the storage engine check into an own
function, including assert for lock.
sql/datadict.h:
added dd_frm_storage_engine.
sql/sql_alter_table.cc:
moved the code for SQLCOM_ALTER_TABLE in mysql_execute_command
into its own file, and using the Sql_statement object to
prepare for future parser reengineering.
sql/sql_alter_table.h:
Created Sql_statement object for ALTER TABLE.
sql/sql_lex.cc:
resetting m_stmt.
sql/sql_lex.h:
Temporary hack for forward declaration of enum_alter_table_change_level.
sql/sql_parse.cc:
Moved out ALTER/ANALYZE/CHECK/OPTIMIZE/REPAIR TABLE
from the giant switch into their own Sql_statement
objects.
sql/sql_parse.h:
Exporting check_merge_table_access.
sql/sql_partition_admin.cc:
created Sql_statement for
ALTER TABLE t ANALYZE/CHECK/OPTIMIZE/REPAIR/TRUNCATE
PARTITION. To be able to reuse the TABLE equivalents.
sql/sql_partition_admin.h:
Added Sql_statement of partition admin statements.
sql/sql_table.cc:
Moved table maintenance code into sql_table_maintenance.cc
sql/sql_table.h:
Moved table maintenance code into sql_table_maintenance.h
exporting functions used by sql_table_maintenance.
sql/sql_table_maintenance.cc:
Moved table maintenance code from sql_table.cc
sql/sql_table_maintenance.h:
Sql_statement objects for ANALYZE/CHECK/OPTIMIZE/REPAIR TABLE.
Also declaring the keycache functions.
sql/sql_truncate.cc:
Moved code from SQLCOM_TRUNCATE in mysql_execute_command into
Truncate_statement::execute.
Added check for partitioned table on TRUNCATE PARTITION.
Moved locking fix for partitioned table into
Alter_table_truncate_partition::execute.
sql/sql_truncate.h:
Truncate_statement declaration (sub class of Sql_statement).
sql/sql_yacc.yy:
Using the new Sql_statment objects.
Diffstat (limited to 'sql/sql_alter_table.cc')
-rw-r--r-- | sql/sql_alter_table.cc | 106 |
1 files changed, 106 insertions, 0 deletions
diff --git a/sql/sql_alter_table.cc b/sql/sql_alter_table.cc new file mode 100644 index 00000000000..607a8d5f5df --- /dev/null +++ b/sql/sql_alter_table.cc @@ -0,0 +1,106 @@ +/* Copyright (c) 2010 Oracle and/or its affiliates. All rights reserved. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; version 2 of the License. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ + +#include "sql_parse.h" // check_access, + // check_merge_table_access +#include "sql_table.h" // mysql_alter_table, + // mysql_exchange_partition +#include "sql_alter_table.h" + +bool Alter_table_statement::execute(THD *thd) +{ + LEX *lex= thd->lex; + /* first SELECT_LEX (have special meaning for many of non-SELECTcommands) */ + SELECT_LEX *select_lex= &lex->select_lex; + /* first table of first SELECT_LEX */ + TABLE_LIST *first_table= (TABLE_LIST*) select_lex->table_list.first; + /* + Code in mysql_alter_table() may modify its HA_CREATE_INFO argument, + so we have to use a copy of this structure to make execution + prepared statement- safe. A shallow copy is enough as no memory + referenced from this structure will be modified. + @todo move these into constructor... + */ + HA_CREATE_INFO create_info(lex->create_info); + Alter_info alter_info(lex->alter_info, thd->mem_root); + ulong priv=0; + ulong priv_needed= ALTER_ACL; + bool result; + + DBUG_ENTER("Alter_table_statement::execute"); + + if (thd->is_fatal_error) /* out of memory creating a copy of alter_info */ + DBUG_RETURN(TRUE); + /* + We also require DROP priv for ALTER TABLE ... DROP PARTITION, as well + as for RENAME TO, as being done by SQLCOM_RENAME_TABLE + */ + if (alter_info.flags & (ALTER_DROP_PARTITION | ALTER_RENAME)) + priv_needed|= DROP_ACL; + + /* Must be set in the parser */ + DBUG_ASSERT(select_lex->db); + DBUG_ASSERT(!(alter_info.flags & ALTER_ADMIN_PARTITION)); + if (check_access(thd, priv_needed, first_table->db, + &first_table->grant.privilege, + &first_table->grant.m_internal, + 0, 0) || + check_access(thd, INSERT_ACL | CREATE_ACL, select_lex->db, + &priv, + NULL, /* Don't use first_tab->grant with sel_lex->db */ + 0, 0) || + check_merge_table_access(thd, first_table->db, + create_info.merge_list.first)) + DBUG_RETURN(TRUE); /* purecov: inspected */ + + if (check_grant(thd, priv_needed, first_table, FALSE, UINT_MAX, FALSE)) + DBUG_RETURN(TRUE); /* purecov: inspected */ + + if (lex->name.str && !test_all_bits(priv, INSERT_ACL | CREATE_ACL)) + { + // Rename of table + TABLE_LIST tmp_table; + bzero((char*) &tmp_table,sizeof(tmp_table)); + tmp_table.table_name= lex->name.str; + tmp_table.db= select_lex->db; + tmp_table.grant.privilege= priv; + if (check_grant(thd, INSERT_ACL | CREATE_ACL, &tmp_table, FALSE, + UINT_MAX, FALSE)) + DBUG_RETURN(TRUE); /* purecov: inspected */ + } + + /* Don't yet allow changing of symlinks with ALTER TABLE */ + if (create_info.data_file_name) + push_warning_printf(thd, MYSQL_ERROR::WARN_LEVEL_WARN, + WARN_OPTION_IGNORED, ER(WARN_OPTION_IGNORED), + "DATA DIRECTORY"); + if (create_info.index_file_name) + push_warning_printf(thd, MYSQL_ERROR::WARN_LEVEL_WARN, + WARN_OPTION_IGNORED, ER(WARN_OPTION_IGNORED), + "INDEX DIRECTORY"); + create_info.data_file_name= create_info.index_file_name= NULL; + + thd->enable_slow_log= opt_log_slow_admin_statements; + + result= mysql_alter_table(thd, select_lex->db, lex->name.str, + &create_info, + first_table, + &alter_info, + select_lex->order_list.elements, + select_lex->order_list.first, + lex->ignore); + + DBUG_RETURN(result); +} |