summaryrefslogtreecommitdiff
path: root/sql/sql_alter.cc
diff options
context:
space:
mode:
authorMattias Jonsson <mattias.jonsson@oracle.com>2010-08-16 16:25:23 +0200
committerMattias Jonsson <mattias.jonsson@oracle.com>2010-08-16 16:25:23 +0200
commitb67924eb4e6c29dd9f9e4ceddfc30b6f0a93ef0e (patch)
tree36fdffc104f31ab707ace2dda5265ed73d578f4d /sql/sql_alter.cc
parent4b20ccafaa3bacfd11c5fcc61e1647dbbefe7bad (diff)
downloadmariadb-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.cc106
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);
+}