mirror of
				https://github.com/MariaDB/server.git
				synced 2025-10-30 04:26:45 +03:00 
			
		
		
		
	check_merge_table_access() used to do two things: - set proper database for every merge table child; - check SELECT | UPDATE | DELETE for merge table children. Setting database is not needed anymore, since it's done on the parsing stage. Thus, check_merge_table_access() can be removed; needed privileges can be checked using check_table_access().
		
			
				
	
	
		
			110 lines
		
	
	
		
			4.4 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
			
		
		
	
	
			110 lines
		
	
	
		
			4.4 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
| /* 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
 | |
| #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))
 | |
|     DBUG_RETURN(TRUE);                  /* purecov: inspected */
 | |
| 
 | |
|   /* If it is a merge table, check privileges for merge children. */
 | |
|   if (create_info.merge_list.first &&
 | |
|       check_table_access(thd, SELECT_ACL | UPDATE_ACL | DELETE_ACL,
 | |
|                          create_info.merge_list.first, FALSE, UINT_MAX, FALSE))
 | |
|     DBUG_RETURN(TRUE);
 | |
| 
 | |
|   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);
 | |
| }
 |