diff options
author | Mattias Jonsson <mattias.jonsson@oracle.com> | 2010-08-16 16:25:23 +0200 |
---|---|---|
committer | Mattias Jonsson <mattias.jonsson@oracle.com> | 2010-08-16 16:25:23 +0200 |
commit | b67924eb4e6c29dd9f9e4ceddfc30b6f0a93ef0e (patch) | |
tree | 36fdffc104f31ab707ace2dda5265ed73d578f4d /sql/sql_alter.cc | |
parent | 4b20ccafaa3bacfd11c5fcc61e1647dbbefe7bad (diff) | |
download | mariadb-git-b67924eb4e6c29dd9f9e4ceddfc30b6f0a93ef0e.tar.gz |
Rename of sql_alter_table -> sql_alter and sql_table_maintenance -> sql_admin
Diffstat (limited to 'sql/sql_alter.cc')
-rw-r--r-- | sql/sql_alter.cc | 106 |
1 files changed, 106 insertions, 0 deletions
diff --git a/sql/sql_alter.cc b/sql/sql_alter.cc new file mode 100644 index 00000000000..046e09b20a3 --- /dev/null +++ b/sql/sql_alter.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.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); +} |