Below is the list of changes that have just been committed into a local
5.1 repository of mattiasj. When mattiasj does a push these changes will
be propagated to the main repository and, within 24 hours after the
push, to the public repository.
For information on how to access the public repository
see http://dev.mysql.com/doc/mysql/en/installing-source-tree.html
ChangeSet@stripped, 2007-11-21 18:55:33+01:00, mattiasj@stripped +11 -0
Bug#23603: Partitions: reoganize means delete
Problem was that a user with ALTER priv (and without
DROP priv) could do a REORGANIZE PARTITION that could
delete rows.
Added option "WITH NO DELETE" for use with
REORGANIZE PARTITION for non delete operations
(do not require DROP priv).
Requiring DROP priv if "WITH NO DELETE" is NOT used.
mysql-test/r/partition_grant.result@stripped, 2007-11-21 18:55:29+01:00, mattiasj@stripped
+57 -0
Bug#23603: Partitions: reoganize means delete
test result
mysql-test/t/partition_grant.test@stripped, 2007-11-21 18:55:29+01:00, mattiasj@stripped
+54 -0
Bug#23603: Partitions: reorganize means delete
test case
sql/ha_partition.cc@stripped, 2007-11-21 18:55:29+01:00, mattiasj@stripped +24 -6
Bug#23603: Partitions: reorganize means delete
Added parameter in change_partitions and copy_partitions
to allow alter WITH NO DELETE
If delete would occur when "WITH NO DELETE" is given,
return error.
sql/ha_partition.h@stripped, 2007-11-21 18:55:29+01:00, mattiasj@stripped +6 -2
Bug#23603: Partitions: reorgaize means delete
Added a "no delete in reorganize" parameter to
change_partitions and copy_partitions
sql/handler.h@stripped, 2007-11-21 18:55:29+01:00, mattiasj@stripped +3 -1
Bug#23603: Partitions: reorganize means delete
Added a "no delete in reorganize" parameter in
change_partitions
sql/share/errmsg.txt@stripped, 2007-11-21 18:55:30+01:00, mattiasj@stripped +4 -0
Bug#23603: Partitions: reorgnize means delete
Added an error messege if REORGANIZE PARTITION
would mean delete (when using the "WITH NO DELETE"
option)
sql/sql_lex.cc@stripped, 2007-11-21 18:55:29+01:00, mattiasj@stripped +2 -2
Bug#23603: Partitions: reorganize means delete
Flags should not be used for equality comparation,
only by its bits.
sql/sql_lex.h@stripped, 2007-11-21 18:55:29+01:00, mattiasj@stripped +1 -0
Bugs#23603: Partitions: reorganize means delete
Added flag for "WITH NO DELETE" part of
ALTER...REORGANIZE PARTITION [WITH NO DELETE]
sql/sql_parse.cc@stripped, 2007-11-21 18:55:29+01:00, mattiasj@stripped +10 -0
Bug#23603: Partitions: reorganize means delete
require DROP privileges for
ALTER TABLE ... REORGANIZE PARTITION
if not including "WITH NO DELETE" part
sql/sql_partition.cc@stripped, 2007-11-21 18:55:30+01:00, mattiasj@stripped +12 -6
Bug#23603: Partitions: reorganize means delete
Flags should be compared by bits.
Added parameters for change_partitions for use of
WITH NO DELETE in reorg partitions
sql/sql_yacc.yy@stripped, 2007-11-21 18:55:30+01:00, mattiasj@stripped +10 -2
Bug#23603: Partitions: reorganize means delete
Added optional "WITH NO DELETE" for use in
REORGANIZE PARTITION
diff -Nrup a/mysql-test/r/partition_grant.result b/mysql-test/r/partition_grant.result
--- a/mysql-test/r/partition_grant.result 2007-04-04 11:01:44 +02:00
+++ b/mysql-test/r/partition_grant.result 2007-11-21 18:55:29 +01:00
@@ -1,4 +1,61 @@
drop schema if exists mysqltest_1;
+CREATE DATABASE mysqltest_1;
+USE mysqltest_1;
+CREATE TABLE t1 (a INT)
+PARTITION BY LIST (a)
+(PARTITION p0 VALUES IN (2),
+PARTITION p1 VALUES IN (1));
+INSERT INTO t1 VALUES (1);
+CREATE USER mysqltest_1@localhost;
+GRANT ALTER,SELECT ON mysqltest_1.t1 TO mysqltest_1@localhost;
+USE mysqltest_1;
+# User mysqltest_1 DB mysqltest_1 (only ALTER and SELECT privs)
+ALTER TABLE t1 REORGANIZE PARTITION p1 INTO (
+PARTITION p1 VALUES IN (0)
+);
+ERROR 42000: DROP command denied to user 'mysqltest_1'@'localhost' for table 't1'
+ALTER TABLE t1 REORGANIZE PARTITION p1 INTO (
+PARTITION p1 VALUES IN (1,3)
+);
+ERROR 42000: DROP command denied to user 'mysqltest_1'@'localhost' for table 't1'
+SELECT * FROM t1;
+a
+1
+ALTER TABLE t1 REORGANIZE PARTITION WITH NO DELETE p1 INTO (
+PARTITION p1 VALUES IN (1,3)
+);
+SELECT * FROM t1;
+a
+1
+ALTER TABLE t1 REORGANIZE PARTITION WITH NO DELETE p1 INTO (
+PARTITION p1 VALUES IN (4)
+);
+ERROR HY000: Impossible ALTER ... WITH NO DELETE. No partition was specified for some
existing values.
+SELECT * FROM t1;
+a
+1
+ALTER TABLE t1 DROP PARTITION p1;
+ERROR 42000: DROP command denied to user 'mysqltest_1'@'localhost' for table 't1'
+DROP TABLE t1;
+ERROR 42000: DROP command denied to user 'mysqltest_1'@'localhost' for table 't1'
+# User root DB mysqltest_1 (all privs)
+SELECT * FROM t1;
+a
+1
+ALTER TABLE t1 REORGANIZE PARTITION WITH NO DELETE p1 INTO (PARTITION p1 VALUES IN (5));
+ERROR HY000: Impossible ALTER ... WITH NO DELETE. No partition was specified for some
existing values.
+ALTER TABLE t1 REORGANIZE PARTITION WITH NO DELETE p1 INTO (PARTITION p1 VALUES IN
(1,5));
+ALTER TABLE t1 REORGANIZE PARTITION p1 INTO (PARTITION p1 VALUES IN (1,6));
+SELECT * FROM t1;
+a
+1
+ALTER TABLE t1 REORGANIZE PARTITION p1 INTO (PARTITION p1 VALUES IN (7));
+SELECT * FROM t1;
+a
+DROP TABLE t1;
+USE test;
+DROP USER mysqltest_1@localhost;
+DROP DATABASE mysqltest_1;
create schema mysqltest_1;
use mysqltest_1;
create table t1 (a int) partition by list (a) (partition p1 values in (1), partition p2
values in (2), partition p3 values in (3));
diff -Nrup a/mysql-test/t/partition_grant.test b/mysql-test/t/partition_grant.test
--- a/mysql-test/t/partition_grant.test 2007-06-26 13:15:03 +02:00
+++ b/mysql-test/t/partition_grant.test 2007-11-21 18:55:29 +01:00
@@ -6,6 +6,60 @@
drop schema if exists mysqltest_1;
--enable_warnings
+#
+# Bug #23603: PARTITION ALTER could case delete
+# ALTER TABLE t REORGANIZE PARTITION
+# requires DROP privileges, if "WITH NO DELETE" is not
+# specified. Then it only succeed if it do not delete
+# any rows
+CREATE DATABASE mysqltest_1;
+USE mysqltest_1;
+CREATE TABLE t1 (a INT)
+PARTITION BY LIST (a)
+(PARTITION p0 VALUES IN (2),
+PARTITION p1 VALUES IN (1));
+INSERT INTO t1 VALUES (1);
+CREATE USER mysqltest_1@localhost;
+GRANT ALTER,SELECT ON mysqltest_1.t1 TO mysqltest_1@localhost;
+CONNECT (con1,localhost,mysqltest_1,,);
+USE mysqltest_1;
+-- echo # User mysqltest_1 DB mysqltest_1 (only ALTER and SELECT privs)
+--error ER_TABLEACCESS_DENIED_ERROR
+ALTER TABLE t1 REORGANIZE PARTITION p1 INTO (
+ PARTITION p1 VALUES IN (0)
+);
+--error ER_TABLEACCESS_DENIED_ERROR
+ALTER TABLE t1 REORGANIZE PARTITION p1 INTO (
+ PARTITION p1 VALUES IN (1,3)
+);
+SELECT * FROM t1;
+ALTER TABLE t1 REORGANIZE PARTITION WITH NO DELETE p1 INTO (
+ PARTITION p1 VALUES IN (1,3)
+);
+SELECT * FROM t1;
+--error ER_PARTITION_ALTER_CAUSES_DELETE
+ALTER TABLE t1 REORGANIZE PARTITION WITH NO DELETE p1 INTO (
+ PARTITION p1 VALUES IN (4)
+);
+SELECT * FROM t1;
+--error ER_TABLEACCESS_DENIED_ERROR
+ALTER TABLE t1 DROP PARTITION p1;
+--error ER_TABLEACCESS_DENIED_ERROR
+DROP TABLE t1;
+connection default;
+-- echo # User root DB mysqltest_1 (all privs)
+SELECT * FROM t1;
+--error ER_PARTITION_ALTER_CAUSES_DELETE
+ALTER TABLE t1 REORGANIZE PARTITION WITH NO DELETE p1 INTO (PARTITION p1 VALUES IN (5));
+ALTER TABLE t1 REORGANIZE PARTITION WITH NO DELETE p1 INTO (PARTITION p1 VALUES IN
(1,5));
+ALTER TABLE t1 REORGANIZE PARTITION p1 INTO (PARTITION p1 VALUES IN (1,6));
+SELECT * FROM t1;
+ALTER TABLE t1 REORGANIZE PARTITION p1 INTO (PARTITION p1 VALUES IN (7));
+SELECT * FROM t1;
+DROP TABLE t1;
+USE test;
+DROP USER mysqltest_1@localhost;
+DROP DATABASE mysqltest_1;
#
# Bug #17139: ALTER TABLE ... DROP PARTITION should require DROP privilege
diff -Nrup a/sql/ha_partition.cc b/sql/ha_partition.cc
--- a/sql/ha_partition.cc 2007-11-14 14:28:18 +01:00
+++ b/sql/ha_partition.cc 2007-11-21 18:55:29 +01:00
@@ -1212,6 +1212,7 @@ void ha_partition::cleanup_new_partition
SYNOPSIS
change_partitions()
+ thd THD object for mem_root use
create_info HA_CREATE_INFO object describing all
fields and indexes in table
path Complete path of db and table name
@@ -1219,6 +1220,7 @@ void ha_partition::cleanup_new_partition
records are added
out: deleted Output parameter where number of deleted
records are added
+ no_del_in_reorg Do not allow delete in REORG PARTITION
pack_frm_data Reference to packed frm file
pack_frm_len Length of packed frm file
@@ -1236,10 +1238,12 @@ void ha_partition::cleanup_new_partition
get zero length and a NULL reference here.
*/
-int ha_partition::change_partitions(HA_CREATE_INFO *create_info,
+int ha_partition::change_partitions(THD *thd,
+ HA_CREATE_INFO *create_info,
const char *path,
ulonglong *copied,
ulonglong *deleted,
+ bool no_del_in_reorg,
const uchar *pack_frm_data
__attribute__((unused)),
size_t pack_frm_len
@@ -1256,7 +1260,6 @@ int ha_partition::change_partitions(HA_C
int error= 1;
bool first;
uint temp_partitions= m_part_info->temp_partitions.elements;
- THD *thd= current_thd;
DBUG_ENTER("ha_partition::change_partitions");
m_reorged_parts= 0;
@@ -1502,7 +1505,7 @@ int ha_partition::change_partitions(HA_C
part_elem->part_state= PART_TO_BE_DROPPED;
}
m_new_file= new_file_array;
- DBUG_RETURN(copy_partitions(copied, deleted));
+ DBUG_RETURN(copy_partitions(no_del_in_reorg, copied, deleted));
}
@@ -1511,6 +1514,7 @@ int ha_partition::change_partitions(HA_C
SYNOPSIS
copy_partitions()
+ no_del_in_reorg Do not allow delete in REORG PARTITION
out:copied Number of records copied
out:deleted Number of records deleted
@@ -1524,7 +1528,9 @@ int ha_partition::change_partitions(HA_C
partitions.
*/
-int ha_partition::copy_partitions(ulonglong *copied, ulonglong *deleted)
+int ha_partition::copy_partitions(bool no_del_in_reorg,
+ ulonglong *copied,
+ ulonglong *deleted)
{
uint reorg_part= 0;
int result= 0;
@@ -1562,12 +1568,21 @@ int ha_partition::copy_partitions(ulongl
table since it doesn't fit into any partition any longer due to
changed partitioning ranges or list values.
*/
- deleted++;
+ /*
+ If ALTER TABLE ... REORGANIZE PARTITION WITH NO DELETE ...
+ return error that it is impossible to do without delete
+ */
+ if (no_del_in_reorg)
+ {
+ result= ER_PARTITION_ALTER_CAUSES_DELETE;
+ goto error;
+ }
+ (*deleted)++;
}
else
{
/* Copy record to new handler */
- copied++;
+ (*copied)++;
if ((result= m_new_file[new_part]->write_row(m_rec0)))
goto error;
}
@@ -5379,6 +5394,9 @@ void ha_partition::print_error(int error
if (error == HA_ERR_NO_PARTITION_FOUND)
m_part_info->print_no_partition_found(table);
+ else if (error == ER_PARTITION_ALTER_CAUSES_DELETE)
+ my_error(error, MYF(0));
+
else
m_file[m_last_part]->print_error(error, errflag);
DBUG_VOID_RETURN;
diff -Nrup a/sql/ha_partition.h b/sql/ha_partition.h
--- a/sql/ha_partition.h 2007-09-24 15:30:28 +02:00
+++ b/sql/ha_partition.h 2007-11-21 18:55:29 +01:00
@@ -195,10 +195,12 @@ public:
HA_CREATE_INFO *create_info);
virtual void update_create_info(HA_CREATE_INFO *create_info);
virtual char *update_table_comment(const char *comment);
- virtual int change_partitions(HA_CREATE_INFO *create_info,
+ virtual int change_partitions(THD *thd,
+ HA_CREATE_INFO *create_info,
const char *path,
ulonglong *copied,
ulonglong *deleted,
+ bool no_del_in_reorg,
const uchar *pack_frm_data,
size_t pack_frm_len);
virtual int drop_partitions(const char *path);
@@ -212,7 +214,9 @@ public:
virtual void change_table_ptr(TABLE *table_arg, TABLE_SHARE *share);
private:
int prepare_for_delete();
- int copy_partitions(ulonglong *copied, ulonglong *deleted);
+ int copy_partitions(bool no_del_in_reorg,
+ ulonglong *copied,
+ ulonglong *deleted);
void cleanup_new_partition(uint part_count);
int prepare_new_partition(TABLE *table, HA_CREATE_INFO *create_info,
handler *file, const char *part_name,
diff -Nrup a/sql/handler.h b/sql/handler.h
--- a/sql/handler.h 2007-09-07 15:41:46 +02:00
+++ b/sql/handler.h 2007-11-21 18:55:29 +01:00
@@ -1617,10 +1617,12 @@ public:
int action_flag, HA_CREATE_INFO *info)
{ return FALSE; }
- virtual int change_partitions(HA_CREATE_INFO *create_info,
+ virtual int change_partitions(THD *thd,
+ HA_CREATE_INFO *create_info,
const char *path,
ulonglong *copied,
ulonglong *deleted,
+ bool no_del_in_reorg,
const uchar *pack_frm_data,
size_t pack_frm_len)
{ return HA_ERR_WRONG_COMMAND; }
diff -Nrup a/sql/share/errmsg.txt b/sql/share/errmsg.txt
--- a/sql/share/errmsg.txt 2007-11-14 14:28:21 +01:00
+++ b/sql/share/errmsg.txt 2007-11-21 18:55:30 +01:00
@@ -6114,3 +6114,7 @@ ER_TRG_CANT_OPEN_TABLE
ER_CANT_CREATE_SROUTINE
eng "Cannot create stored routine `%-.64s`. Check warnings"
+
+ER_PARTITION_ALTER_CAUSES_DELETE
+ eng "Impossible ALTER ... WITH NO DELETE. No partition was specified for some existing
values."
+ sve "Omöljig ALTER ... WITH NO DELETE, det finns värden som inte har någon partition"
diff -Nrup a/sql/sql_lex.cc b/sql/sql_lex.cc
--- a/sql/sql_lex.cc 2007-11-10 11:58:37 +01:00
+++ b/sql/sql_lex.cc 2007-11-21 18:55:29 +01:00
@@ -2944,7 +2944,7 @@ bool st_select_lex::add_index_hint (THD
bool st_lex::is_partition_management() const
{
return (sql_command == SQLCOM_ALTER_TABLE &&
- (alter_info.flags == ALTER_ADD_PARTITION ||
- alter_info.flags == ALTER_REORGANIZE_PARTITION));
+ (alter_info.flags & ALTER_ADD_PARTITION ||
+ alter_info.flags & ALTER_REORGANIZE_PARTITION));
}
diff -Nrup a/sql/sql_lex.h b/sql/sql_lex.h
--- a/sql/sql_lex.h 2007-11-14 12:25:40 +01:00
+++ b/sql/sql_lex.h 2007-11-21 18:55:29 +01:00
@@ -835,6 +835,7 @@ inline bool st_select_lex_unit::is_union
#define ALTER_REPAIR_PARTITION (1L << 24)
#define ALTER_REMOVE_PARTITIONING (1L << 25)
#define ALTER_FOREIGN_KEY (1L << 26)
+#define ALTER_REORG_PART_NO_DELETE (1L << 27)
enum enum_alter_table_change_level
{
diff -Nrup a/sql/sql_parse.cc b/sql/sql_parse.cc
--- a/sql/sql_parse.cc 2007-11-15 20:25:41 +01:00
+++ b/sql/sql_parse.cc 2007-11-21 18:55:29 +01:00
@@ -2495,6 +2495,16 @@ end_with_restore_list:
*/
if (alter_info.flags & (ALTER_DROP_PARTITION | ALTER_RENAME))
priv_needed|= DROP_ACL;
+ /*
+ For ALTER TABLE ... REORGANIZE PARTITION ...
+ We also require DROP priv
+ For ALTER TABLE ... REORGANIZE PARTITION WITH NO DELETE ...
+ We do not require DROP priv but returns error in copy_partition
+ if delete would occur.
+ */
+ if (alter_info.flags & ALTER_REORGANIZE_PARTITION
+ && !(alter_info.flags & ALTER_REORG_PART_NO_DELETE))
+ priv_needed|= DROP_ACL;
/* Must be set in the parser */
DBUG_ASSERT(select_lex->db);
diff -Nrup a/sql/sql_partition.cc b/sql/sql_partition.cc
--- a/sql/sql_partition.cc 2007-11-16 14:07:55 +01:00
+++ b/sql/sql_partition.cc 2007-11-21 18:55:30 +01:00
@@ -4204,7 +4204,7 @@ uint prep_alter_part_table(THD *thd, TAB
my_error(ER_PARTITION_MGMT_ON_NONPARTITIONED, MYF(0));
DBUG_RETURN(TRUE);
}
- if (alter_info->flags == ALTER_TABLE_REORG)
+ if (alter_info->flags & ALTER_TABLE_REORG)
{
uint new_part_no, curr_part_no;
if (tab_part_info->part_type != HASH_PARTITION ||
@@ -4734,7 +4734,7 @@ state of p1.
tab_part_info->is_auto_partitioned= FALSE;
}
}
- else if (alter_info->flags == ALTER_REORGANIZE_PARTITION)
+ else if (alter_info->flags & ALTER_REORGANIZE_PARTITION)
{
/*
Reorganise partitions takes a number of partitions that are next
@@ -4915,8 +4915,8 @@ the generated partition syntax in a corr
}
*partition_changed= TRUE;
thd->work_part_info= tab_part_info;
- if (alter_info->flags == ALTER_ADD_PARTITION ||
- alter_info->flags == ALTER_REORGANIZE_PARTITION)
+ if (alter_info->flags & ALTER_ADD_PARTITION ||
+ alter_info->flags & ALTER_REORGANIZE_PARTITION)
{
if (tab_part_info->use_default_subpartitions &&
!alt_part_info->use_default_subpartitions)
@@ -5090,6 +5090,8 @@ the generated partition syntax in a corr
records are added
deleted Output parameter where number of deleted
records are added
+ alter_info.flags Flag to copy_partition about ALTER TABLE ...
+ REORGANIZE PARTITION ... [WITH NO DELETE]
*/
static bool mysql_change_partitions(ALTER_PARTITION_PARAM_TYPE *lpt)
@@ -5100,8 +5102,12 @@ static bool mysql_change_partitions(ALTE
DBUG_ENTER("mysql_change_partitions");
build_table_filename(path, sizeof(path), lpt->db, lpt->table_name, "", 0);
- if ((error= file->change_partitions(lpt->create_info, path, &lpt->copied,
- &lpt->deleted, lpt->pack_frm_data,
+ if ((error= file->change_partitions(lpt->thd, lpt->create_info, path,
+ &lpt->copied,
+ &lpt->deleted,
+ lpt->alter_info->flags
+ & ALTER_REORG_PART_NO_DELETE,
+ lpt->pack_frm_data,
lpt->pack_frm_len)))
{
if (error != ER_OUTOFMEMORY)
diff -Nrup a/sql/sql_yacc.yy b/sql/sql_yacc.yy
--- a/sql/sql_yacc.yy 2007-11-16 14:07:55 +01:00
+++ b/sql/sql_yacc.yy 2007-11-21 18:55:30 +01:00
@@ -3858,7 +3858,7 @@ opt_part_values:
LEX *lex= Lex;
if (! lex->is_partition_management())
{
- if (Lex->part_info->part_type != LIST_PARTITION)
+ if (lex->part_info->part_type != LIST_PARTITION)
{
my_error(ER_PARTITION_WRONG_VALUES_ERROR, MYF(0),
"LIST", "IN");
@@ -5541,7 +5541,7 @@ reorg_parts_rule:
{
Lex->alter_info.flags|= ALTER_TABLE_REORG;
}
- | alt_part_name_list
+ | opt_with_no_delete alt_part_name_list
{
Lex->alter_info.flags|= ALTER_REORGANIZE_PARTITION;
}
@@ -5549,6 +5549,14 @@ reorg_parts_rule:
{
LEX *lex= Lex;
lex->part_info->no_parts= lex->part_info->partitions.elements;
+ }
+ ;
+
+opt_with_no_delete:
+ /* empty */
+ | WITH NO_SYM DELETE_SYM
+ {
+ Lex->alter_info.flags|= ALTER_REORG_PART_NO_DELETE;
}
;
| Thread |
|---|
| • bk commit into 5.1 tree (mattiasj:1.2627) BUG#23603 | mattiasj | 21 Nov |