List:Commits« Previous MessageNext Message »
From:Mattias Jonsson Date:December 19 2011 2:01pm
Subject:bzr push into mysql-trunk branch (mattias.jonsson:3677 to 3678)
View as plain text  
 3678 Mattias Jonsson	2011-12-19 [merge]
      merge

    modified:
      mysql-test/r/partition_list.result
      mysql-test/r/partition_mgm.result
      mysql-test/t/partition_list.test
      mysql-test/t/partition_mgm.test
      sql/ha_partition.cc
      sql/partition_element.h
      sql/partition_info.cc
      sql/partition_info.h
      sql/sql_admin.cc
      sql/sql_partition.cc
      sql/sql_partition.h
      sql/sql_yacc.yy
 3677 Alexander Nozdrin	2011-12-19
      A patch for Bug#11748352 - 36002: PREPARED STATEMENTS:
      IF A VIEW USED IN A STATEMENT IS REPLACED, BAD DATA.
      
      The problem was that changes in view meta-data were not
      detected by prepared statements.
      
      There were the following technical causes for this problem:
      
        - TABLE_SHARE ref-version was always set to 0 for views;
      
        - ALTER VIEW did not flush corresponding TABLE_SHARE-object
          from the table definition cache.
      
      The patch has the following fixes:
      
        - use TABLE_SHARE::table_map_id as ref-version for views
          (like it is done for regular tables).
      
        - explicitly flush TABLE_SHARE-object of the view after
          ALTER VIEW statement.
      
        - check "table version" when opening a view under LOCK TABLES.
      
      The test case for Bug#36002 was already in ps_ddl.test, so no need
      for adding a new test case. The results however were corrected.
      Also, tests for altering views and handling changes in the locked
      table mode were added.
      
      Note, that this patch introduces a minor backward-incompatible change:
      instead of successfully returning wrong data, the server now may throw
      a table-not-found error. It happens in cases like the following:
        - create a base table;
        - create a trigger on that table (let's say after-insert-trigger);
        - access a view (do SELECT or a DML-statement) inside that trigger;
        - prepare a statement that inserts data into the base table;
        - execute the prepared statement at least once;
        - re-create the view, or alter it so that it uses a different set of
          base tables;
        - execute the prepared statement.
          This execution used to lead to wrong data, because the outdated
          view definition was used. Now, it leads to table-not-found error.
          It's expected that such scenarios will be fixed by WL#4179.
      
      So, to generalize the scenario:
        - there need to be a stored program, using a view;
        - there need to be a prepared statement causing the stored program
          invocation;
        - if the view gets altered (or re-created) in the way that it
          uses a different set of base tables, further executions of
          the prepare statements result in a table-not-found error.
      
      A workaround is to use FLUSH TABLES after meta-data changes
      (the workaround is not affected by the patch).

    modified:
      mysql-test/r/ps_ddl.result
      mysql-test/t/ps_ddl.test
      sql/sql_base.cc
      sql/sql_view.cc
      sql/table.h
      sql/unireg.h
=== modified file 'mysql-test/r/partition_list.result'
--- a/mysql-test/r/partition_list.result	2009-10-21 18:04:34 +0000
+++ b/mysql-test/r/partition_list.result	2011-10-12 11:33:18 +0000
@@ -1,4 +1,136 @@
 drop table if exists t1;
+#
+# Bug#62505: ALTER TABLE ADD PARTITION fails for LIST partitions with
+#            more than 16 items
+#
+CREATE TABLE t1 (a INT);
+# SUCCESS with 20 items because this is initial partitioning action
+# (The parser already knows that it is only on column)
+ALTER TABLE t1
+PARTITION BY LIST(a)
+(PARTITION p1 VALUES IN (1,2,3,4,5,6,7,8,9,10,
+11,12,13,14,15,16,17,18,19,20));
+# BUG: FAILED, because number of items > 16 during partition add
+# (The parser do not know how many columns the table is partitioned on)
+ALTER TABLE t1 ADD PARTITION
+(PARTITION p2 VALUES IN (21,22,23,24,25,26,27,28,29,30,
+31,32,33,34,35,36,37,38,39,40));
+SHOW CREATE TABLE t1;
+Table	Create Table
+t1	CREATE TABLE `t1` (
+  `a` int(11) DEFAULT NULL
+) ENGINE=MyISAM DEFAULT CHARSET=latin1
+/*!50100 PARTITION BY LIST (a)
+(PARTITION p1 VALUES IN (1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20) ENGINE = MyISAM,
+ PARTITION p2 VALUES IN (21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40) ENGINE = MyISAM) */
+# Test with single column LIST COLUMNS too
+ALTER TABLE t1
+PARTITION BY LIST COLUMNS (a)
+(PARTITION p1 VALUES IN (1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20));
+ALTER TABLE t1 ADD PARTITION
+(PARTITION p2 VALUES IN ((71),(72),(73),(74),(75),(76),(77),(78),(79),(80),
+(81),(82),(83),(84),(85),(86),(87),(88),(89),(90)));
+ERROR 42000: Row expressions in VALUES IN only allowed for multi-field column partitioning near '))' at line 3
+ALTER TABLE t1 ADD PARTITION
+(PARTITION p2 VALUES IN (21,22,23,24,25,26,27,28,29,30,
+31,32,33,34,35,36,37,38,39,40));
+SHOW CREATE TABLE t1;
+Table	Create Table
+t1	CREATE TABLE `t1` (
+  `a` int(11) DEFAULT NULL
+) ENGINE=MyISAM DEFAULT CHARSET=latin1
+/*!50500 PARTITION BY LIST  COLUMNS(a)
+(PARTITION p1 VALUES IN (1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20) ENGINE = MyISAM,
+ PARTITION p2 VALUES IN (21,22,23,24,25,26,27,28,29,30,31,32,33,34,35,36,37,38,39,40) ENGINE = MyISAM) */
+DROP TABLE t1;
+# Test with two columns in LIST COLUMNS partitioning
+CREATE TABLE t1
+(a INT,
+b CHAR(2))
+PARTITION BY LIST COLUMNS (a, b)
+(PARTITION p0_a VALUES IN
+((0, "a0"), (0, "a1"), (0, "a2"), (0, "a3"), (0, "a4"), (0, "a5"), (0, "a6"),
+(0, "a7"), (0, "a8"), (0, "a9"), (0, "aa"), (0, "ab"), (0, "ac"), (0, "ad"),
+(0, "ae"), (0, "af"), (0, "ag"), (0, "ah"), (0, "ai"), (0, "aj"), (0, "ak"),
+(0, "al")));
+ALTER TABLE t1 ADD PARTITION
+(PARTITION p1_a VALUES IN
+((1, "a0"), (1, "a1"), (1, "a2"), (1, "a3"), (1, "a4"), (1, "a5"), (1, "a6"),
+(1, "a7"), (1, "a8"), (1, "a9"), (1, "aa"), (1, "ab"), (1, "ac"), (1, "ad"),
+(1, "ae"), (1, "af"), (1, "ag"), (1, "ah"), (1, "ai"), (1, "aj"), (1, "ak"),
+(1, "al")));
+SHOW CREATE TABLE t1;
+Table	Create Table
+t1	CREATE TABLE `t1` (
+  `a` int(11) DEFAULT NULL,
+  `b` char(2) DEFAULT NULL
+) ENGINE=MyISAM DEFAULT CHARSET=latin1
+/*!50500 PARTITION BY LIST  COLUMNS(a,b)
+(PARTITION p0_a VALUES IN ((0,'a0'),(0,'a1'),(0,'a2'),(0,'a3'),(0,'a4'),(0,'a5'),(0,'a6'),(0,'a7'),(0,'a8'),(0,'a9'),(0,'aa'),(0,'ab'),(0,'ac'),(0,'ad'),(0,'ae'),(0,'af'),(0,'ag'),(0,'ah'),(0,'ai'),(0,'aj'),(0,'ak'),(0,'al')) ENGINE = MyISAM,
+ PARTITION p1_a VALUES IN ((1,'a0'),(1,'a1'),(1,'a2'),(1,'a3'),(1,'a4'),(1,'a5'),(1,'a6'),(1,'a7'),(1,'a8'),(1,'a9'),(1,'aa'),(1,'ab'),(1,'ac'),(1,'ad'),(1,'ae'),(1,'af'),(1,'ag'),(1,'ah'),(1,'ai'),(1,'aj'),(1,'ak'),(1,'al')) ENGINE = MyISAM) */
+# Test of the parser for '('
+ALTER TABLE t1 ADD PARTITION
+(PARTITION p2_a VALUES IN
+(((1 + 1), "a0"), (2, "a1"), (2, "a2"), (2, "a3"), (2, "a4"), (2, "a5"),
+(2, "a6"), (2, "a7"), (2, "a8"), (2, "a9"), (2, "aa"), (2, "ab"), (2, "ac"),
+(2, "ad"), (2, "ae"), (2, "af"), (2, "ag"), (2, "ah"), (2, "ai"), (2, "aj"),
+(2, "ak"), (2, "al")));
+SHOW CREATE TABLE t1;
+Table	Create Table
+t1	CREATE TABLE `t1` (
+  `a` int(11) DEFAULT NULL,
+  `b` char(2) DEFAULT NULL
+) ENGINE=MyISAM DEFAULT CHARSET=latin1
+/*!50500 PARTITION BY LIST  COLUMNS(a,b)
+(PARTITION p0_a VALUES IN ((0,'a0'),(0,'a1'),(0,'a2'),(0,'a3'),(0,'a4'),(0,'a5'),(0,'a6'),(0,'a7'),(0,'a8'),(0,'a9'),(0,'aa'),(0,'ab'),(0,'ac'),(0,'ad'),(0,'ae'),(0,'af'),(0,'ag'),(0,'ah'),(0,'ai'),(0,'aj'),(0,'ak'),(0,'al')) ENGINE = MyISAM,
+ PARTITION p1_a VALUES IN ((1,'a0'),(1,'a1'),(1,'a2'),(1,'a3'),(1,'a4'),(1,'a5'),(1,'a6'),(1,'a7'),(1,'a8'),(1,'a9'),(1,'aa'),(1,'ab'),(1,'ac'),(1,'ad'),(1,'ae'),(1,'af'),(1,'ag'),(1,'ah'),(1,'ai'),(1,'aj'),(1,'ak'),(1,'al')) ENGINE = MyISAM,
+ PARTITION p2_a VALUES IN ((2,'a0'),(2,'a1'),(2,'a2'),(2,'a3'),(2,'a4'),(2,'a5'),(2,'a6'),(2,'a7'),(2,'a8'),(2,'a9'),(2,'aa'),(2,'ab'),(2,'ac'),(2,'ad'),(2,'ae'),(2,'af'),(2,'ag'),(2,'ah'),(2,'ai'),(2,'aj'),(2,'ak'),(2,'al')) ENGINE = MyISAM) */
+ALTER TABLE t1 ADD PARTITION
+(PARTITION p3_a VALUES IN ((1 + 1 + 1), "a0"));
+ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near '"a0"))' at line 2
+ALTER TABLE t1 ADD PARTITION
+(PARTITION p3_a VALUES IN (1 + 1 + 1, "a0"));
+ERROR HY000: Inconsistency in usage of column lists for partitioning
+# Test with 3 columns when it only has 2.
+ALTER TABLE t1 ADD PARTITION
+(PARTITION p3_a VALUES IN ((3, "a1", 0), (3, "a2", 0)));
+ERROR HY000: Inconsistency in usage of column lists for partitioning
+ALTER TABLE t1 ADD PARTITION
+(PARTITION p3_a VALUES IN ((1 + 1 + 1, "a0")));
+SHOW CREATE TABLE t1;
+Table	Create Table
+t1	CREATE TABLE `t1` (
+  `a` int(11) DEFAULT NULL,
+  `b` char(2) DEFAULT NULL
+) ENGINE=MyISAM DEFAULT CHARSET=latin1
+/*!50500 PARTITION BY LIST  COLUMNS(a,b)
+(PARTITION p0_a VALUES IN ((0,'a0'),(0,'a1'),(0,'a2'),(0,'a3'),(0,'a4'),(0,'a5'),(0,'a6'),(0,'a7'),(0,'a8'),(0,'a9'),(0,'aa'),(0,'ab'),(0,'ac'),(0,'ad'),(0,'ae'),(0,'af'),(0,'ag'),(0,'ah'),(0,'ai'),(0,'aj'),(0,'ak'),(0,'al')) ENGINE = MyISAM,
+ PARTITION p1_a VALUES IN ((1,'a0'),(1,'a1'),(1,'a2'),(1,'a3'),(1,'a4'),(1,'a5'),(1,'a6'),(1,'a7'),(1,'a8'),(1,'a9'),(1,'aa'),(1,'ab'),(1,'ac'),(1,'ad'),(1,'ae'),(1,'af'),(1,'ag'),(1,'ah'),(1,'ai'),(1,'aj'),(1,'ak'),(1,'al')) ENGINE = MyISAM,
+ PARTITION p2_a VALUES IN ((2,'a0'),(2,'a1'),(2,'a2'),(2,'a3'),(2,'a4'),(2,'a5'),(2,'a6'),(2,'a7'),(2,'a8'),(2,'a9'),(2,'aa'),(2,'ab'),(2,'ac'),(2,'ad'),(2,'ae'),(2,'af'),(2,'ag'),(2,'ah'),(2,'ai'),(2,'aj'),(2,'ak'),(2,'al')) ENGINE = MyISAM,
+ PARTITION p3_a VALUES IN ((3,'a0')) ENGINE = MyISAM) */
+# Test with more than 16 columns (cause of regression)
+ALTER TABLE t1 ADD PARTITION
+(PARTITION part_2 VALUES IN ((21 ,22, 23, 24, 25, 26, 27, 28, 29, 30,
+31 ,32, 33, 34, 35, 36, 37, 38, 39, 40),
+(41 ,42, 43, 44, 45, 46, 47, 48, 49, 50,
+51 ,52, 53, 54, 55, 56, 57, 58, 59, 60)));
+ERROR 42000: Row expressions in VALUES IN only allowed for multi-field column partitioning near '))' at line 5
+ALTER TABLE t1 ADD PARTITION
+(PARTITION part_2 VALUES IN (21 ,22, 23, 24, 25, 26, 27, 28, 29, 30,
+31 ,32, 33, 34, 35, 36, 37, 38, 39, 40));
+ERROR HY000: Inconsistency in usage of column lists for partitioning
+SHOW CREATE TABLE t1;
+Table	Create Table
+t1	CREATE TABLE `t1` (
+  `a` int(11) DEFAULT NULL,
+  `b` char(2) DEFAULT NULL
+) ENGINE=MyISAM DEFAULT CHARSET=latin1
+/*!50500 PARTITION BY LIST  COLUMNS(a,b)
+(PARTITION p0_a VALUES IN ((0,'a0'),(0,'a1'),(0,'a2'),(0,'a3'),(0,'a4'),(0,'a5'),(0,'a6'),(0,'a7'),(0,'a8'),(0,'a9'),(0,'aa'),(0,'ab'),(0,'ac'),(0,'ad'),(0,'ae'),(0,'af'),(0,'ag'),(0,'ah'),(0,'ai'),(0,'aj'),(0,'ak'),(0,'al')) ENGINE = MyISAM,
+ PARTITION p1_a VALUES IN ((1,'a0'),(1,'a1'),(1,'a2'),(1,'a3'),(1,'a4'),(1,'a5'),(1,'a6'),(1,'a7'),(1,'a8'),(1,'a9'),(1,'aa'),(1,'ab'),(1,'ac'),(1,'ad'),(1,'ae'),(1,'af'),(1,'ag'),(1,'ah'),(1,'ai'),(1,'aj'),(1,'ak'),(1,'al')) ENGINE = MyISAM,
+ PARTITION p2_a VALUES IN ((2,'a0'),(2,'a1'),(2,'a2'),(2,'a3'),(2,'a4'),(2,'a5'),(2,'a6'),(2,'a7'),(2,'a8'),(2,'a9'),(2,'aa'),(2,'ab'),(2,'ac'),(2,'ad'),(2,'ae'),(2,'af'),(2,'ag'),(2,'ah'),(2,'ai'),(2,'aj'),(2,'ak'),(2,'al')) ENGINE = MyISAM,
+ PARTITION p3_a VALUES IN ((3,'a0')) ENGINE = MyISAM) */
+DROP TABLE t1;
 create table t1 (a int unsigned)
 partition by list (a)
 (partition p0 values in (0),

=== modified file 'mysql-test/r/partition_mgm.result'
--- a/mysql-test/r/partition_mgm.result	2011-10-14 12:28:58 +0000
+++ b/mysql-test/r/partition_mgm.result	2011-12-19 13:21:37 +0000
@@ -1,5 +1,16 @@
 DROP TABLE IF EXISTS t1;
 #
+# Bug#13357766: ASSERT IN HANDLER::HA_CREATE
+#
+CREATE TABLE t1
+(a INT)
+PARTITION BY KEY(a) PARTITIONS 3;
+ALTER TABLE t1 REPAIR PARTITION p2,p3,p1;
+Table	Op	Msg_type	Msg_text
+test.t1	repair	error	Error in list of partitions to test.t1
+ALTER TABLE t1 ORDER BY a;
+DROP TABLE t1;
+#
 # Bug#11764110/bug#56909: REORGANIZE PARTITION is allowed on
 #                         HASH/KEY partitioned tables
 #

=== modified file 'mysql-test/t/partition_list.test'
--- a/mysql-test/t/partition_list.test	2009-10-21 18:04:34 +0000
+++ b/mysql-test/t/partition_list.test	2011-10-12 11:33:18 +0000
@@ -9,6 +9,101 @@
 drop table if exists t1;
 --enable_warnings
 
+--echo #
+--echo # Bug#62505: ALTER TABLE ADD PARTITION fails for LIST partitions with
+--echo #            more than 16 items
+--echo #
+
+CREATE TABLE t1 (a INT);
+
+--echo # SUCCESS with 20 items because this is initial partitioning action
+--echo # (The parser already knows that it is only on column)
+ALTER TABLE t1
+PARTITION BY LIST(a)
+(PARTITION p1 VALUES IN (1,2,3,4,5,6,7,8,9,10,
+                         11,12,13,14,15,16,17,18,19,20));
+
+--echo # BUG: FAILED, because number of items > 16 during partition add
+--echo # (The parser do not know how many columns the table is partitioned on)
+ALTER TABLE t1 ADD PARTITION
+(PARTITION p2 VALUES IN (21,22,23,24,25,26,27,28,29,30,
+                         31,32,33,34,35,36,37,38,39,40));
+
+
+SHOW CREATE TABLE t1;
+
+--echo # Test with single column LIST COLUMNS too
+ALTER TABLE t1
+PARTITION BY LIST COLUMNS (a)
+(PARTITION p1 VALUES IN (1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20));
+
+--error ER_PARSE_ERROR
+ALTER TABLE t1 ADD PARTITION
+(PARTITION p2 VALUES IN ((71),(72),(73),(74),(75),(76),(77),(78),(79),(80),
+                         (81),(82),(83),(84),(85),(86),(87),(88),(89),(90)));
+
+ALTER TABLE t1 ADD PARTITION
+(PARTITION p2 VALUES IN (21,22,23,24,25,26,27,28,29,30,
+                         31,32,33,34,35,36,37,38,39,40));
+SHOW CREATE TABLE t1;
+DROP TABLE t1;
+
+--echo # Test with two columns in LIST COLUMNS partitioning
+CREATE TABLE t1
+(a INT,
+ b CHAR(2))
+PARTITION BY LIST COLUMNS (a, b)
+(PARTITION p0_a VALUES IN
+((0, "a0"), (0, "a1"), (0, "a2"), (0, "a3"), (0, "a4"), (0, "a5"), (0, "a6"),
+ (0, "a7"), (0, "a8"), (0, "a9"), (0, "aa"), (0, "ab"), (0, "ac"), (0, "ad"),
+ (0, "ae"), (0, "af"), (0, "ag"), (0, "ah"), (0, "ai"), (0, "aj"), (0, "ak"),
+ (0, "al")));
+ALTER TABLE t1 ADD PARTITION
+(PARTITION p1_a VALUES IN
+((1, "a0"), (1, "a1"), (1, "a2"), (1, "a3"), (1, "a4"), (1, "a5"), (1, "a6"),
+ (1, "a7"), (1, "a8"), (1, "a9"), (1, "aa"), (1, "ab"), (1, "ac"), (1, "ad"),
+ (1, "ae"), (1, "af"), (1, "ag"), (1, "ah"), (1, "ai"), (1, "aj"), (1, "ak"),
+ (1, "al")));
+SHOW CREATE TABLE t1;
+
+--echo # Test of the parser for '('
+ALTER TABLE t1 ADD PARTITION
+(PARTITION p2_a VALUES IN
+(((1 + 1), "a0"), (2, "a1"), (2, "a2"), (2, "a3"), (2, "a4"), (2, "a5"),
+ (2, "a6"), (2, "a7"), (2, "a8"), (2, "a9"), (2, "aa"), (2, "ab"), (2, "ac"),
+ (2, "ad"), (2, "ae"), (2, "af"), (2, "ag"), (2, "ah"), (2, "ai"), (2, "aj"),
+ (2, "ak"), (2, "al")));
+
+SHOW CREATE TABLE t1;
+
+--error ER_PARSE_ERROR
+ALTER TABLE t1 ADD PARTITION
+(PARTITION p3_a VALUES IN ((1 + 1 + 1), "a0"));
+--error ER_PARTITION_COLUMN_LIST_ERROR
+ALTER TABLE t1 ADD PARTITION
+(PARTITION p3_a VALUES IN (1 + 1 + 1, "a0"));
+
+--echo # Test with 3 columns when it only has 2.
+--error ER_PARTITION_COLUMN_LIST_ERROR
+ALTER TABLE t1 ADD PARTITION
+(PARTITION p3_a VALUES IN ((3, "a1", 0), (3, "a2", 0)));
+ALTER TABLE t1 ADD PARTITION
+(PARTITION p3_a VALUES IN ((1 + 1 + 1, "a0")));
+SHOW CREATE TABLE t1;
+--echo # Test with more than 16 columns (cause of regression)
+--error ER_PARSE_ERROR
+ALTER TABLE t1 ADD PARTITION
+(PARTITION part_2 VALUES IN ((21 ,22, 23, 24, 25, 26, 27, 28, 29, 30,
+                              31 ,32, 33, 34, 35, 36, 37, 38, 39, 40),
+                             (41 ,42, 43, 44, 45, 46, 47, 48, 49, 50,
+                              51 ,52, 53, 54, 55, 56, 57, 58, 59, 60)));
+--error ER_PARTITION_COLUMN_LIST_ERROR
+ALTER TABLE t1 ADD PARTITION
+(PARTITION part_2 VALUES IN (21 ,22, 23, 24, 25, 26, 27, 28, 29, 30,
+                             31 ,32, 33, 34, 35, 36, 37, 38, 39, 40));
+SHOW CREATE TABLE t1;
+DROP TABLE t1;
+
 #
 # Bug 20733: Zerofill columns gives wrong result with partitioned tables
 #

=== modified file 'mysql-test/t/partition_mgm.test'
--- a/mysql-test/t/partition_mgm.test	2011-10-14 12:28:58 +0000
+++ b/mysql-test/t/partition_mgm.test	2011-12-19 13:21:37 +0000
@@ -4,6 +4,16 @@ DROP TABLE IF EXISTS t1;
 --enable_warnings
 
 --echo #
+--echo # Bug#13357766: ASSERT IN HANDLER::HA_CREATE
+--echo #
+CREATE TABLE t1
+(a INT)
+PARTITION BY KEY(a) PARTITIONS 3;
+ALTER TABLE t1 REPAIR PARTITION p2,p3,p1;
+ALTER TABLE t1 ORDER BY a; 
+DROP TABLE t1;
+
+--echo #
 --echo # Bug#11764110/bug#56909: REORGANIZE PARTITION is allowed on
 --echo #                         HASH/KEY partitioned tables
 --echo #

=== modified file 'sql/ha_partition.cc'
--- a/sql/ha_partition.cc	2011-12-14 16:49:31 +0000
+++ b/sql/ha_partition.cc	2011-12-19 13:21:37 +0000
@@ -3801,11 +3801,11 @@ int ha_partition::truncate_partition(Alt
   uint num_parts= m_part_info->num_parts;
   uint num_subparts= m_part_info->num_subparts;
   uint i= 0;
-  uint num_parts_set= alter_info->partition_names.elements;
-  uint num_parts_found= set_part_state(alter_info, m_part_info,
-                                        PART_ADMIN);
   DBUG_ENTER("ha_partition::truncate_partition");
 
+  if (set_part_state(alter_info, m_part_info, PART_ADMIN))
+    DBUG_RETURN(HA_ERR_NO_PARTITION_FOUND);
+
   /* Only binlog when it starts any call to the partitions handlers */
   *binlog_stmt= false;
 
@@ -3818,10 +3818,6 @@ int ha_partition::truncate_partition(Alt
   table_share->ha_part_data->auto_inc_initialized= FALSE;
   unlock_auto_increment();
 
-  if (num_parts_set != num_parts_found &&
-      (!(alter_info->flags & ALTER_ALL_PARTITION)))
-    DBUG_RETURN(HA_ERR_NO_PARTITION_FOUND);
-
   *binlog_stmt= true;
 
   do

=== modified file 'sql/partition_element.h'
--- a/sql/partition_element.h	2011-06-30 15:50:45 +0000
+++ b/sql/partition_element.h	2011-12-19 12:53:11 +0000
@@ -92,7 +92,7 @@ struct st_ddl_log_memory_entry;
 class partition_element :public Sql_alloc {
 public:
   List<partition_element> subpartitions;
-  List<part_elem_value> list_val_list;
+  List<part_elem_value> list_val_list;  // list of LIST values/column arrays
   ha_rows part_max_rows;
   ha_rows part_min_rows;
   longlong range_value;

=== modified file 'sql/partition_info.cc'
--- a/sql/partition_info.cc	2011-07-28 10:54:44 +0000
+++ b/sql/partition_info.cc	2011-12-19 12:53:11 +0000
@@ -900,6 +900,7 @@ bool partition_info::check_range_constan
         List_iterator<part_elem_value> list_val_it(part_def->list_val_list);
         part_elem_value *range_val= list_val_it++;
         part_column_list_val *col_val= range_val->col_val_array;
+        DBUG_ASSERT(part_def->list_val_list.elements == 1);
 
         if (fix_column_value_functions(thd, range_val, i))
           goto end;
@@ -1788,11 +1789,11 @@ id_err:
 
 
 /**
-  Check what kind of error to report
+  Check what kind of error to report.
 
   @param use_subpart_expr Use the subpart_expr instead of part_expr
-  @param part_str         Name of partition to report error (or NULL)
 */
+
 void partition_info::report_part_expr_error(bool use_subpart_expr)
 {
   Item *expr= part_expr;
@@ -1832,18 +1833,17 @@ void partition_info::report_part_expr_er
 }
  
 
-/*
-  Create a new column value in current list with maxvalue
-  Called from parser
+/**
+  Create a new column value in current list with maxvalue.
 
-  SYNOPSIS
-    add_max_value()
-  RETURN
-    TRUE               Error
-    FALSE              Success
+  @return Operation status
+    @retval TRUE   Error
+    @retval FALSE  Success
+
+  @note Called from parser.
 */
 
-int partition_info::add_max_value()
+bool partition_info::add_max_value()
 {
   DBUG_ENTER("partition_info::add_max_value");
 
@@ -1856,16 +1856,16 @@ int partition_info::add_max_value()
   DBUG_RETURN(FALSE);
 }
 
-/*
-  Create a new column value in current list
-  Called from parser
 
-  SYNOPSIS
-    add_column_value()
-  RETURN
-    >0                 A part_column_list_val object which have been
-                       inserted into its list
-    0                  Memory allocation failure
+/**
+  Create a new column value in current list.
+
+  @return Pointer to a new part_column_list_val
+    @retval  != 0  A part_column_list_val object which have been
+                   inserted into its list
+    @retval  NULL  Memory allocation failure
+    
+  @note Called from parser.
 */
 
 part_column_list_val *partition_info::add_column_value()
@@ -1890,7 +1890,7 @@ part_column_list_val *partition_info::ad
       into the structure used for 1 column. After this we call
       ourselves recursively which should always succeed.
     */
-    if (!reorganize_into_single_field_col_val())
+    if (!reorganize_into_single_field_col_val() && !init_column_part())
     {
       DBUG_RETURN(add_column_value());
     }
@@ -1911,19 +1911,19 @@ part_column_list_val *partition_info::ad
 }
 
 
-/*
-  Initialise part_elem_value object at setting of a new object
-  (Helper functions to functions called by parser)
+/**
+  Initialise part_elem_value object at setting of a new object.
 
-  SYNOPSIS
-    init_col_val
-    col_val                  Column value object to be initialised
-    item                     Item object representing column value
+  @param col_val  Column value object to be initialised
+  @param item     Item object representing column value
 
-  RETURN VALUES
-    TRUE                     Failure
-    FALSE                    Success
+  @return Operation status
+    @retval TRUE   Failure
+    @retval FALSE  Success
+
+  @note Helper functions to functions called by parser.
 */
+
 void partition_info::init_col_val(part_column_list_val *col_val, Item *item)
 {
   DBUG_ENTER("partition_info::init_col_val");
@@ -1948,20 +1948,21 @@ void partition_info::init_col_val(part_c
   col_val->part_info= NULL;
   DBUG_VOID_RETURN;
 }
-/*
-  Add a column value in VALUES LESS THAN or VALUES IN
-  (Called from parser)
 
-  SYNOPSIS
-    add_column_list_value()
-    lex                      Parser's lex object
-    thd                      Thread object
-    item                     Item object representing column value
 
-  RETURN VALUES
-    TRUE                     Failure
-    FALSE                    Success
+/**
+  Add a column value in VALUES LESS THAN or VALUES IN.
+
+  @param thd   Thread object
+  @param item  Item object representing column value
+
+  @return Operation status
+    @retval TRUE   Failure
+    @retval FALSE  Success
+
+  @note Called from parser.
 */
+
 bool partition_info::add_column_list_value(THD *thd, Item *item)
 {
   part_column_list_val *col_val;
@@ -2010,19 +2011,19 @@ bool partition_info::add_column_list_val
   DBUG_RETURN(FALSE);
 }
 
-/*
-  Initialise part_info object for receiving a set of column values
+
+/**
+  Initialize a new column for VALUES {LESS THAN|IN}.
+
+  Initialize part_info object for receiving a set of column values
   for a partition, called when parser reaches VALUES LESS THAN or
   VALUES IN.
 
-  SYNOPSIS
-    init_column_part()
-    lex                    Parser's lex object
-
-  RETURN VALUES
-    TRUE                     Failure
-    FALSE                    Success
+  @return Operation status
+    @retval TRUE   Failure
+    @retval FALSE  Success
 */
+
 bool partition_info::init_column_part()
 {
   partition_element *p_elem= curr_part_elem;
@@ -2056,8 +2057,15 @@ bool partition_info::init_column_part()
   DBUG_RETURN(FALSE);
 }
 
-/*
-  In the case of ALTER TABLE ADD/REORGANIZE PARTITION for LIST
+
+/**
+  Reorganize the preallocated buffer into a single field col list.
+
+  @return Operation status
+    @retval  true   Failure
+    @retval  false  Success
+
+  @note In the case of ALTER TABLE ADD/REORGANIZE PARTITION for LIST
   partitions we can specify list values as:
   VALUES IN (v1, v2,,,, v17) if we're using the first partitioning
   variant with a function or a column list partitioned table with
@@ -2069,30 +2077,27 @@ bool partition_info::init_column_part()
   partitioning and we used a VALUES IN like above where number of
   values was smaller than MAX_REF_PARTS or equal, then we will
   reorganize after discovering this in the parser.
-
-  SYNOPSIS
-    reorganize_into_single_field_col_val()
-
-  RETURN VALUES
-    TRUE                     Failure
-    FALSE                    Success
 */
-int partition_info::reorganize_into_single_field_col_val()
+
+bool partition_info::reorganize_into_single_field_col_val()
 {
   part_column_list_val *col_val, *new_col_val;
   part_elem_value *val= curr_list_val;
-  uint loc_num_columns= num_columns;
+  uint num_values= num_columns;
   uint i;
   DBUG_ENTER("partition_info::reorganize_into_single_field_col_val");
+  DBUG_ASSERT(part_type == LIST_PARTITION);
+  DBUG_ASSERT(!num_columns || num_columns == val->added_items);
 
+  if (!num_values)
+    num_values= val->added_items;
   num_columns= 1;
   val->added_items= 1U;
   col_val= &val->col_val_array[0];
   init_col_val(col_val, col_val->item_expression);
-  for (i= 1; i < loc_num_columns; i++)
+  for (i= 1; i < num_values; i++)
   {
     col_val= &val->col_val_array[i];
-    DBUG_ASSERT(part_type == LIST_PARTITION);
     if (init_column_part())
     {
       DBUG_RETURN(TRUE);
@@ -2108,27 +2113,28 @@ int partition_info::reorganize_into_sing
   DBUG_RETURN(FALSE);
 }
 
-/*
+
+/**
   This function handles the case of function-based partitioning.
+  
   It fixes some data structures created in the parser and puts
   them in the format required by the rest of the partitioning
   code.
 
-  SYNOPSIS
-  fix_partition_values()
-  thd                             Thread object
-  col_val                         Array of one value
-  part_elem                       The partition instance
-  part_id                         Id of partition instance
-
-  RETURN VALUES
-    TRUE                     Failure
-    FALSE                    Success
+  @param thd        Thread object
+  @param col_val    Array of one value
+  @param part_elem  The partition instance
+  @param part_id    Id of partition instance
+
+  @return Operation status
+    @retval TRUE   Failure
+    @retval FALSE  Success
 */
-int partition_info::fix_partition_values(THD *thd,
-                                         part_elem_value *val,
-                                         partition_element *part_elem,
-                                         uint part_id)
+
+bool partition_info::fix_partition_values(THD *thd,
+                                          part_elem_value *val,
+                                          partition_element *part_elem,
+                                          uint part_id)
 {
   part_column_list_val *col_val= val->col_val_array;
   DBUG_ENTER("partition_info::fix_partition_values");
@@ -2195,17 +2201,16 @@ int partition_info::fix_partition_values
   DBUG_RETURN(FALSE);
 }
 
-/*
-  Get column item with a proper character set according to the field
 
-  SYNOPSIS
-    get_column_item()
-    item                     Item object to start with
-    field                    Field for which the item will be compared to
+/**
+  Get column item with a proper character set according to the field.
 
-  RETURN VALUES
-    NULL                     Error
-    item                     Returned item
+  @param item   Item object to start with
+  @param field  Field for which the item will be compared to
+
+  @return Column item
+    @retval NULL  Error
+    @retval item  Returned item
 */
 
 Item* partition_info::get_column_item(Item *item, Field *field)
@@ -2224,19 +2229,18 @@ Item* partition_info::get_column_item(It
 }
 
 
-/*
-  Evaluate VALUES functions for column list values
-  SYNOPSIS
-    fix_column_value_functions()
-    thd                              Thread object
-    col_val                          List of column values
-    part_id                          Partition id we are fixing
+/**
+  Evaluate VALUES functions for column list values.
 
-  RETURN VALUES
-    TRUE                             Error
-    FALSE                            Success
-  DESCRIPTION
-    Fix column VALUES and store in memory array adapted to the data type
+  @param thd      Thread object
+  @param col_val  List of column values
+  @param part_id  Partition id we are fixing
+
+  @return Operation status
+    @retval TRUE   Error
+    @retval FALSE  Success
+  
+  @note Fix column VALUES and store in memory array adapted to the data type.
 */
 
 bool partition_info::fix_column_value_functions(THD *thd,
@@ -2306,9 +2310,11 @@ end:
   DBUG_RETURN(result);
 }
 
-/*
-  The parser generates generic data structures, we need to set them up
-  as the rest of the code expects to find them. This is in reality part
+/**
+  Fix partition data from parser.
+
+  @details The parser generates generic data structures, we need to set them
+  up as the rest of the code expects to find them. This is in reality part
   of the syntax check of the parser code.
 
   It is necessary to call this function in the case of a CREATE TABLE
@@ -2340,16 +2346,14 @@ end:
   and number of elements are in synch with each other. So only partitioning
   using functions need to be set-up to their data structures.
 
-  SYNOPSIS
-    fix_parser_data()
-    thd                      Thread object
+  @param thd  Thread object
 
-  RETURN VALUES
-    TRUE                     Failure
-    FALSE                    Success
+  @return Operation status
+    @retval TRUE   Failure
+    @retval FALSE  Success
 */
 
-int partition_info::fix_parser_data(THD *thd)
+bool partition_info::fix_parser_data(THD *thd)
 {
   List_iterator<partition_element> it(partitions);
   partition_element *part_elem;
@@ -2411,6 +2415,7 @@ int partition_info::fix_parser_data(THD 
   DBUG_RETURN(FALSE);
 }
 
+
 void partition_info::print_debug(const char *str, uint *value)
 {
   DBUG_ENTER("print_debug");
@@ -2442,7 +2447,7 @@ bool partition_info::set_part_expr(char 
   return FALSE;
 }
 
-int partition_info::reorganize_into_single_field_col_val()
+bool partition_info::reorganize_into_single_field_col_val()
 {
   return 0;
 }
@@ -2456,9 +2461,10 @@ bool partition_info::add_column_list_val
 {
   return FALSE;
 }
-int partition_info::add_max_value()
+
+bool partition_info::add_max_value()
 {
-  return 0;
+  return false;
 }
 
 void partition_info::print_debug(const char *str, uint *value)

=== modified file 'sql/partition_info.h'
--- a/sql/partition_info.h	2011-06-30 15:50:45 +0000
+++ b/sql/partition_info.h	2011-12-19 12:53:11 +0000
@@ -164,8 +164,8 @@ public:
   char *part_func_string;
   char *subpart_func_string;
 
-  partition_element *curr_part_elem;
-  partition_element *current_partition;
+  partition_element *curr_part_elem;     // part or sub part
+  partition_element *current_partition;  // partition
   part_elem_value *curr_list_val;
   uint curr_list_object;
   uint num_columns;
@@ -213,14 +213,14 @@ public:
   bool use_default_num_subpartitions;
   bool default_partitions_setup;
   bool defined_max_value;
-  bool list_of_part_fields;
-  bool list_of_subpart_fields;
-  bool linear_hash_ind;
+  bool list_of_part_fields;                  // KEY or COLUMNS PARTITIONING
+  bool list_of_subpart_fields;               // KEY SUBPARTITIONING
+  bool linear_hash_ind;                      // LINEAR HASH/KEY
   bool fixed;
   bool is_auto_partitioned;
   bool from_openfrm;
   bool has_null_value;
-  bool column_list;
+  bool column_list;                          // COLUMNS PARTITIONING, 5.5+
 
   partition_info()
   : get_partition_id(NULL), get_part_partition_id(NULL),
@@ -289,17 +289,17 @@ public:
   void print_no_partition_found(TABLE *table);
   void print_debug(const char *str, uint*);
   Item* get_column_item(Item *item, Field *field);
-  int fix_partition_values(THD *thd,
-                           part_elem_value *val,
-                           partition_element *part_elem,
-                           uint part_id);
+  bool fix_partition_values(THD *thd,
+                            part_elem_value *val,
+                            partition_element *part_elem,
+                            uint part_id);
   bool fix_column_value_functions(THD *thd,
                                   part_elem_value *val,
                                   uint part_id);
-  int fix_parser_data(THD *thd);
-  int add_max_value();
+  bool fix_parser_data(THD *thd);
+  bool add_max_value();
   void init_col_val(part_column_list_val *col_val, Item *item);
-  int reorganize_into_single_field_col_val();
+  bool reorganize_into_single_field_col_val();
   part_column_list_val *add_column_value();
   bool set_part_expr(char *start_token, Item *item_ptr,
                      char *end_token, bool is_subpart);

=== modified file 'sql/sql_admin.cc'
--- a/sql/sql_admin.cc	2011-07-28 10:54:44 +0000
+++ b/sql/sql_admin.cc	2011-11-08 12:55:37 +0000
@@ -379,6 +379,10 @@ static bool mysql_admin_table(THD* thd, 
           open_error= open_and_lock_tables(thd, table, TRUE, 0);
       }
 
+      /* Make sure this table instance is not reused after the operation. */
+      if (table->table)
+        table->table->m_needs_reopen= true;
+
       table->next_global= save_next_global;
       table->next_local= save_next_local;
       thd->open_options&= ~extra_open_options;
@@ -417,12 +421,8 @@ static bool mysql_admin_table(THD* thd, 
             my_error(ER_PARTITION_MGMT_ON_NONPARTITIONED, MYF(0));
             DBUG_RETURN(TRUE);
           }
-          uint num_parts_found;
-          uint num_parts_opt= alter_info->partition_names.elements;
-          num_parts_found= set_part_state(alter_info, table->table->part_info,
-                                          PART_ADMIN);
-          if (num_parts_found != num_parts_opt &&
-              (!(alter_info->flags & ALTER_ALL_PARTITION)))
+          
+          if (set_part_state(alter_info, table->table->part_info, PART_ADMIN))
           {
             char buff[FN_REFLEN + MYSQL_ERRMSG_SIZE];
             size_t length;

=== modified file 'sql/sql_partition.cc'
--- a/sql/sql_partition.cc	2011-12-15 12:13:36 +0000
+++ b/sql/sql_partition.cc	2011-12-19 13:21:37 +0000
@@ -4550,11 +4550,20 @@ error:
 }
 
 
-/*
-  Sets which partitions to be used in the command
+/**
+  Sets which partitions to be used in the command.
+
+  @param alter_info     Alter_info pointer holding partition names and flags.
+  @param tab_part_info  partition_info holding all partitions.
+  @param part_state     Which state to set for the named partitions.
+
+  @return Operation status
+    @retval false  Success
+    @retval true   Failure
 */
-uint set_part_state(Alter_info *alter_info, partition_info *tab_part_info,
-               enum partition_state part_state)
+
+bool set_part_state(Alter_info *alter_info, partition_info *tab_part_info,
+                    enum partition_state part_state)
 {
   uint part_count= 0;
   uint num_parts_found= 0;
@@ -4580,7 +4589,21 @@ uint set_part_state(Alter_info *alter_in
     else
       part_elem->part_state= PART_NORMAL;
   } while (++part_count < tab_part_info->num_parts);
-  return num_parts_found;
+
+  if (num_parts_found != alter_info->partition_names.elements &&
+      !(alter_info->flags & ALTER_ALL_PARTITION))
+  {
+    /* Not all given partitions found, revert and return failure */
+    part_it.rewind();
+    part_count= 0;
+    do
+    {
+      partition_element *part_elem= part_it++;
+      part_elem->part_state= PART_NORMAL;
+    } while (++part_count < tab_part_info->num_parts);
+    return true;
+  }
+  return false;
 }
 
 
@@ -5149,11 +5172,7 @@ that are reorganised.
     }
     else if (alter_info->flags & ALTER_REBUILD_PARTITION)
     {
-      uint num_parts_found;
-      uint num_parts_opt= alter_info->partition_names.elements;
-      num_parts_found= set_part_state(alter_info, tab_part_info, PART_CHANGED);
-      if (num_parts_found != num_parts_opt &&
-          (!(alter_info->flags & ALTER_ALL_PARTITION)))
+      if (set_part_state(alter_info, tab_part_info, PART_CHANGED))
       {
         my_error(ER_DROP_PARTITION_NON_EXISTENT, MYF(0), "REBUILD");
         goto err;

=== modified file 'sql/sql_partition.h'
--- a/sql/sql_partition.h	2011-06-30 15:50:45 +0000
+++ b/sql/sql_partition.h	2011-11-08 12:55:37 +0000
@@ -250,7 +250,7 @@ uint fast_alter_partition_table(THD *thd
                                 char *db,
                                 const char *table_name,
                                 TABLE  *fast_alter_table);
-uint set_part_state(Alter_info *alter_info, partition_info *tab_part_info,
+bool set_part_state(Alter_info *alter_info, partition_info *tab_part_info,
                     enum partition_state part_state);
 uint prep_alter_part_table(THD *thd, TABLE *table, Alter_info *alter_info,
                            HA_CREATE_INFO *create_info,

=== modified file 'sql/sql_yacc.yy'
--- a/sql/sql_yacc.yy	2011-12-14 15:55:30 +0000
+++ b/sql/sql_yacc.yy	2011-12-19 12:53:11 +0000
@@ -5029,7 +5029,7 @@ part_values_in:
                 arrays with one entry in each array. This can happen
                 in the first partition of an ALTER TABLE statement where
                 we ADD or REORGANIZE partitions. Also can only happen
-                for LIST partitions.
+                for LIST [COLUMNS] partitions.
               */
               if (part_info->reorganize_into_single_field_col_val())
               {

No bundle (reason: useless for push emails).
Thread
bzr push into mysql-trunk branch (mattias.jonsson:3677 to 3678) Mattias Jonsson19 Dec