List:Commits« Previous MessageNext Message »
From:Mattias Jonsson Date:August 30 2010 3:34pm
Subject:bzr commit into mysql-5.5-bugfixing branch (mattias.jonsson:3193) Bug#50036
View as plain text  
#At file:///Users/mattiasj/mysql-bzr/b50036-55-bf/ based on revid:bar@stripped

 3193 Mattias Jonsson	2010-08-30
      Bug#50036: Inconsistent errors when using TIMESTAMP columns/expressions
      
      It was hard to understand what the error really meant.
      
      The error checking in partitioning is done in several different
      parts during the execution of a query which can make it
      hard to return useful errors.
      
      Added a new error for bad VALUES part in the per PARTITION clause.
      Using the more verbose error that a column is not allowed in
      the partitioning function instead of just that the function is
      not allowed.
     @ mysql-test/r/partition.result
        changed error to be more specific
     @ mysql-test/r/partition_error.result
        updated result
     @ mysql-test/std_data/parts/t1TIMESTAMP.frm
        .frm file of CREATE TABLE t1 (a TIMESTAMP) PARTITION BY HASH(TO_DAYS(a));
     @ mysql-test/t/partition.test
        changed error to be more specific
     @ mysql-test/t/partition_error.test
        Added test (also for verifying behaviour of previously
        created tables which is no longer allowed).
        
        Updated expected errors in other places
     @ sql/partition_info.cc
        Added function report_part_expr_error to
        be able to return a more specific error.
        
        Renamed fix_func_partition to fix_partition_values
        since the function really fixes/checks the VALUES clause.
     @ sql/partition_info.h
        removed part_result_type, since it was unused.
        renamed fix_funk_partition->fix_partition_values
        added report_part_expr_error
     @ sql/share/errmsg-utf8.txt
        Added a more specific error.
     @ sql/sql_partition.cc
        made use of report_part_expr_error to get a more specific error.
     @ sql/sql_yacc.yy
        Changed error message to be more specific. And return an other error code.

    added:
      mysql-test/std_data/parts/t1TIMESTAMP.frm
    modified:
      mysql-test/r/partition.result
      mysql-test/r/partition_error.result
      mysql-test/t/partition.test
      mysql-test/t/partition_error.test
      sql/partition_info.cc
      sql/partition_info.h
      sql/share/errmsg-utf8.txt
      sql/sql_partition.cc
      sql/sql_yacc.yy
=== modified file 'mysql-test/r/partition.result'
--- a/mysql-test/r/partition.result	2010-05-28 05:47:58 +0000
+++ b/mysql-test/r/partition.result	2010-08-30 15:33:55 +0000
@@ -520,12 +520,12 @@ create table t1 (a bigint)
 partition by range (a)
 (partition p0 values less than (0xFFFFFFFFFFFFFFFF),
 partition p1 values less than (10));
-ERROR HY000: VALUES value must be of same type as partition function
+ERROR HY000: VALUES value for partition 'p0' must have type INT
 create table t1 (a bigint)
 partition by list (a)
 (partition p0 values in (0xFFFFFFFFFFFFFFFF),
 partition p1 values in (10));
-ERROR HY000: VALUES value must be of same type as partition function
+ERROR HY000: VALUES value for partition 'p0' must have type INT
 create table t1 (a bigint unsigned)
 partition by range (a)
 (partition p0 values less than (100),

=== modified file 'mysql-test/r/partition_error.result'
--- a/mysql-test/r/partition_error.result	2010-06-07 08:47:04 +0000
+++ b/mysql-test/r/partition_error.result	2010-08-30 15:33:55 +0000
@@ -1,4 +1,124 @@
-drop table if exists t1;
+drop table if exists t1, t2;
+#
+# Bug#50036: Inconsistent errors when using TIMESTAMP
+#            columns/expressions
+# 1. correct and appropriate errors in light of
+#    the fix for BUG#42849:
+CREATE TABLE t1 (c TIMESTAMP)
+PARTITION BY RANGE (TO_DAYS(c))
+(PARTITION p0 VALUES LESS THAN (10000),
+PARTITION p1 VALUES LESS THAN (MAXVALUE));
+ERROR HY000: Constant, random or timezone-dependent expressions in (sub)partitioning function are not allowed
+CREATE TABLE t2 (c TIMESTAMP);
+ALTER TABLE t2
+PARTITION BY RANGE (TO_DAYS(c))
+(PARTITION p0 VALUES LESS THAN (10000),
+PARTITION p1 VALUES LESS THAN (MAXVALUE));
+ERROR HY000: Constant, random or timezone-dependent expressions in (sub)partitioning function are not allowed
+CREATE TABLE t1 (c TIMESTAMP)
+PARTITION BY RANGE COLUMNS(c)
+(PARTITION p0 VALUES LESS THAN ('2000-01-01 00:00:00'),
+PARTITION p1 VALUES LESS THAN (MAXVALUE));
+ERROR HY000: Field 'c' is of a not allowed type for this type of partitioning
+ALTER TABLE t2 PARTITION BY RANGE COLUMNS(c)
+(PARTITION p0 VALUES LESS THAN ('2000-01-01 00:00:00'),
+PARTITION p1 VALUES LESS THAN (MAXVALUE));
+ERROR HY000: Field 'c' is of a not allowed type for this type of partitioning
+DROP TABLE t2;
+# 2. These errors where questionable before the fix:
+# VALUES clause are checked first, clearified the error message.
+CREATE TABLE t1 (c TIMESTAMP)
+PARTITION BY RANGE (c)
+(PARTITION p0 VALUES LESS THAN ('2000-01-01 00:00:00'),
+PARTITION p1 VALUES LESS THAN (MAXVALUE));
+ERROR HY000: VALUES value for partition 'p0' must have type INT
+# TIMESTAMP is not INT (e.g. UNIX_TIMESTAMP).
+CREATE TABLE t1 (c TIMESTAMP)
+PARTITION BY RANGE (UNIX_TIMESTAMP(c))
+(PARTITION p0 VALUES LESS THAN ('2000-01-01 00:00:00'),
+PARTITION p1 VALUES LESS THAN (MAXVALUE));
+ERROR HY000: VALUES value for partition 'p0' must have type INT
+CREATE TABLE t1 (c TIMESTAMP)
+PARTITION BY RANGE (UNIX_TIMESTAMP(c))
+(PARTITION p0 VALUES LESS THAN (UNIX_TIMESTAMP('2000-01-01 00:00:00')),
+PARTITION p1 VALUES LESS THAN (MAXVALUE));
+DROP TABLE t1;
+# Changed error from ER_INCONSISTENT_TYPE_OF_FUNCTIONS_ERROR
+CREATE TABLE t1 (c TIMESTAMP)
+PARTITION BY HASH (c) PARTITIONS 4;
+ERROR HY000: Field 'c' is of a not allowed type for this type of partitioning
+# Added test with existing TIMESTAMP partitioning (when it was allowed).
+CREATE TABLE t1 (a TIMESTAMP)
+PARTITION BY HASH (UNIX_TIMESTAMP(a));
+INSERT INTO t1 VALUES ('2000-01-02 03:04:05');
+SELECT * FROM t1;
+a
+2000-01-02 03:04:05
+FLUSH TABLES;
+SELECT * FROM t1;
+a
+2000-01-02 03:04:05
+Warning	1486	Constant, random or timezone-dependent expressions in (sub)partitioning function are not allowed
+Warnings:
+SHOW CREATE TABLE t1;
+Table	Create Table
+t1	CREATE TABLE `t1` (
+  `a` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP
+) ENGINE=MyISAM DEFAULT CHARSET=latin1
+/*!50100 PARTITION BY HASH (TO_DAYS(a)) */
+INSERT INTO t1 VALUES ('2001-02-03 04:05:06');
+SELECT * FROM t1;
+a
+2000-01-02 03:04:05
+2001-02-03 04:05:06
+ALTER TABLE t1 ADD PARTITION PARTITIONS 2;
+ALTER TABLE t1
+PARTITION BY RANGE (TO_DAYS(a))
+(PARTITION p0 VALUES LESS THAN (10000),
+PARTITION p1 VALUES LESS THAN (MAXVALUE));
+ERROR HY000: Constant, random or timezone-dependent expressions in (sub)partitioning function are not allowed
+SHOW CREATE TABLE t1;
+Table	Create Table
+t1	CREATE TABLE `t1` (
+  `a` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP
+) ENGINE=MyISAM DEFAULT CHARSET=latin1
+/*!50100 PARTITION BY HASH (TO_DAYS(a))
+PARTITIONS 3 */
+Warnings:
+Warning	1486	Constant, random or timezone-dependent expressions in (sub)partitioning function are not allowed
+CREATE TABLE t2 LIKE t1;
+SHOW CREATE TABLE t2;
+Table	Create Table
+t2	CREATE TABLE `t2` (
+  `a` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP
+) ENGINE=MyISAM DEFAULT CHARSET=latin1
+/*!50100 PARTITION BY HASH (TO_DAYS(a))
+PARTITIONS 3 */
+Warnings:
+Warning	1486	Constant, random or timezone-dependent expressions in (sub)partitioning function are not allowed
+DROP TABLE t2;
+CREATE TABLE t2 SELECT * FROM t1;
+DROP TABLE t2;
+ALTER TABLE t1 PARTITION BY HASH (UNIX_TIMESTAMP(a));
+SHOW CREATE TABLE t1;
+Table	Create Table
+t1	CREATE TABLE `t1` (
+  `a` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP
+) ENGINE=MyISAM DEFAULT CHARSET=latin1
+/*!50100 PARTITION BY HASH (UNIX_TIMESTAMP(a)) */
+ALTER TABLE t1 ADD PARTITION PARTITIONS 2;
+SHOW CREATE TABLE t1;
+Table	Create Table
+t1	CREATE TABLE `t1` (
+  `a` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP
+) ENGINE=MyISAM DEFAULT CHARSET=latin1
+/*!50100 PARTITION BY HASH (UNIX_TIMESTAMP(a))
+PARTITIONS 3 */
+SELECT * FROM t1;
+a
+2000-01-02 03:04:05
+2001-02-03 04:05:06
+DROP TABLE t1;
 #
 # Bug#49161: Out of memory; restart server and try again (needed 2 bytes)
 #
@@ -497,7 +617,7 @@ partition by range (a)
 partitions 2
 (partition x1 values less than (4.0) tablespace ts1,
 partition x2 values less than (8) tablespace ts2);
-ERROR HY000: VALUES value must be of same type as partition function
+ERROR HY000: VALUES value for partition 'x1' must have type INT
 CREATE TABLE t1 (
 a int not null,
 b int not null,
@@ -736,7 +856,7 @@ partition by list (a)
 partitions 2
 (partition x1 values in (4.0, 12+8),
 partition x2 values in (3, 21));
-ERROR HY000: VALUES value must be of same type as partition function
+ERROR HY000: VALUES value for partition 'x1' must have type INT
 CREATE TABLE t1 (
 a int not null,
 b int not null,
@@ -796,12 +916,12 @@ CREATE TABLE new (a TIMESTAMP NOT NULL P
 PARTITION BY RANGE (a) (
 PARTITION p VALUES LESS THAN (20080819),
 PARTITION pmax VALUES LESS THAN MAXVALUE);
-ERROR HY000: The PARTITION function returns the wrong type
+ERROR HY000: Field 'a' is of a not allowed type for this type of partitioning
 ALTER TABLE old
 PARTITION BY RANGE (a) (
 PARTITION p VALUES LESS THAN (20080819),
 PARTITION pmax VALUES LESS THAN MAXVALUE);
-ERROR HY000: The PARTITION function returns the wrong type
+ERROR HY000: Field 'a' is of a not allowed type for this type of partitioning
 CREATE TABLE new (a TIMESTAMP NOT NULL PRIMARY KEY)
 PARTITION BY RANGE (a+0) (
 PARTITION p VALUES LESS THAN (20080819),

=== added file 'mysql-test/std_data/parts/t1TIMESTAMP.frm'
Binary files a/mysql-test/std_data/parts/t1TIMESTAMP.frm	1970-01-01 00:00:00 +0000 and b/mysql-test/std_data/parts/t1TIMESTAMP.frm	2010-08-30 15:33:55 +0000 differ

=== modified file 'mysql-test/t/partition.test'
--- a/mysql-test/t/partition.test	2010-05-28 05:47:58 +0000
+++ b/mysql-test/t/partition.test	2010-08-30 15:33:55 +0000
@@ -430,12 +430,12 @@ drop table t1;
 #
 # BUG 16002: Handle unsigned integer functions properly
 #
---error ER_INCONSISTENT_TYPE_OF_FUNCTIONS_ERROR
+--error ER_VALUES_IS_NOT_INT_TYPE_ERROR
 create table t1 (a bigint)
 partition by range (a)
 (partition p0 values less than (0xFFFFFFFFFFFFFFFF),
  partition p1 values less than (10));
---error ER_INCONSISTENT_TYPE_OF_FUNCTIONS_ERROR
+--error ER_VALUES_IS_NOT_INT_TYPE_ERROR
 create table t1 (a bigint)
 partition by list (a)
 (partition p0 values in (0xFFFFFFFFFFFFFFFF),

=== modified file 'mysql-test/t/partition_error.test'
--- a/mysql-test/t/partition_error.test	2010-06-07 08:47:04 +0000
+++ b/mysql-test/t/partition_error.test	2010-08-30 15:33:55 +0000
@@ -5,12 +5,104 @@
 -- source include/have_partition.inc
 
 --disable_warnings
-drop table if exists t1;
+drop table if exists t1, t2;
 --enable_warnings
 
 let $MYSQLD_DATADIR= `SELECT @@datadir`;
 
 --echo #
+--echo # Bug#50036: Inconsistent errors when using TIMESTAMP
+--echo #            columns/expressions
+
+--echo # 1. correct and appropriate errors in light of
+--echo #    the fix for BUG#42849:
+--error ER_WRONG_EXPR_IN_PARTITION_FUNC_ERROR
+CREATE TABLE t1 (c TIMESTAMP)
+PARTITION BY RANGE (TO_DAYS(c))
+(PARTITION p0 VALUES LESS THAN (10000),
+ PARTITION p1 VALUES LESS THAN (MAXVALUE));
+CREATE TABLE t2 (c TIMESTAMP);
+--error ER_WRONG_EXPR_IN_PARTITION_FUNC_ERROR
+ALTER TABLE t2
+PARTITION BY RANGE (TO_DAYS(c))
+(PARTITION p0 VALUES LESS THAN (10000),
+ PARTITION p1 VALUES LESS THAN (MAXVALUE));
+
+--error ER_FIELD_TYPE_NOT_ALLOWED_AS_PARTITION_FIELD
+CREATE TABLE t1 (c TIMESTAMP)
+PARTITION BY RANGE COLUMNS(c)
+(PARTITION p0 VALUES LESS THAN ('2000-01-01 00:00:00'),
+ PARTITION p1 VALUES LESS THAN (MAXVALUE));
+--error ER_FIELD_TYPE_NOT_ALLOWED_AS_PARTITION_FIELD
+ALTER TABLE t2 PARTITION BY RANGE COLUMNS(c)
+(PARTITION p0 VALUES LESS THAN ('2000-01-01 00:00:00'),
+ PARTITION p1 VALUES LESS THAN (MAXVALUE));
+DROP TABLE t2;
+
+--echo # 2. These errors where questionable before the fix:
+
+--echo # VALUES clause are checked first, clearified the error message.
+--error ER_VALUES_IS_NOT_INT_TYPE_ERROR
+CREATE TABLE t1 (c TIMESTAMP)
+PARTITION BY RANGE (c)
+(PARTITION p0 VALUES LESS THAN ('2000-01-01 00:00:00'),
+ PARTITION p1 VALUES LESS THAN (MAXVALUE));
+
+--echo # TIMESTAMP is not INT (e.g. UNIX_TIMESTAMP).
+--error ER_VALUES_IS_NOT_INT_TYPE_ERROR
+CREATE TABLE t1 (c TIMESTAMP)
+PARTITION BY RANGE (UNIX_TIMESTAMP(c))
+(PARTITION p0 VALUES LESS THAN ('2000-01-01 00:00:00'),
+ PARTITION p1 VALUES LESS THAN (MAXVALUE));
+
+CREATE TABLE t1 (c TIMESTAMP)
+PARTITION BY RANGE (UNIX_TIMESTAMP(c))
+(PARTITION p0 VALUES LESS THAN (UNIX_TIMESTAMP('2000-01-01 00:00:00')),
+ PARTITION p1 VALUES LESS THAN (MAXVALUE));
+DROP TABLE t1;
+
+--echo # Changed error from ER_INCONSISTENT_TYPE_OF_FUNCTIONS_ERROR
+--error ER_FIELD_TYPE_NOT_ALLOWED_AS_PARTITION_FIELD
+CREATE TABLE t1 (c TIMESTAMP)
+PARTITION BY HASH (c) PARTITIONS 4;
+
+--echo # Added test with existing TIMESTAMP partitioning (when it was allowed).
+
+CREATE TABLE t1 (a TIMESTAMP)
+PARTITION BY HASH (UNIX_TIMESTAMP(a));
+INSERT INTO t1 VALUES ('2000-01-02 03:04:05');
+--sorted_result
+SELECT * FROM t1;
+FLUSH TABLES;
+--remove_file $MYSQLD_DATADIR/test/t1.frm
+--copy_file std_data/parts/t1TIMESTAMP.frm $MYSQLD_DATADIR/test/t1.frm
+--sorted_result
+SELECT * FROM t1;
+SHOW CREATE TABLE t1;
+INSERT INTO t1 VALUES ('2001-02-03 04:05:06');
+--sorted_result
+SELECT * FROM t1;
+ALTER TABLE t1 ADD PARTITION PARTITIONS 2;
+--error ER_WRONG_EXPR_IN_PARTITION_FUNC_ERROR
+ALTER TABLE t1
+PARTITION BY RANGE (TO_DAYS(a))
+(PARTITION p0 VALUES LESS THAN (10000),
+ PARTITION p1 VALUES LESS THAN (MAXVALUE));
+SHOW CREATE TABLE t1;
+CREATE TABLE t2 LIKE t1;
+SHOW CREATE TABLE t2;
+DROP TABLE t2;
+CREATE TABLE t2 SELECT * FROM t1;
+DROP TABLE t2;
+ALTER TABLE t1 PARTITION BY HASH (UNIX_TIMESTAMP(a));
+SHOW CREATE TABLE t1;
+ALTER TABLE t1 ADD PARTITION PARTITIONS 2;
+SHOW CREATE TABLE t1;
+--sorted_result
+SELECT * FROM t1;
+DROP TABLE t1;
+
+--echo #
 --echo # Bug#49161: Out of memory; restart server and try again (needed 2 bytes)
 --echo #
 CREATE TABLE t1 (a INT) PARTITION BY HASH (a);
@@ -536,7 +628,7 @@ partitions 2
 #
 # Partition by range, inconsistent partition function and constants
 #
---error ER_INCONSISTENT_TYPE_OF_FUNCTIONS_ERROR
+--error ER_VALUES_IS_NOT_INT_TYPE_ERROR
 CREATE TABLE t1 (
 a int not null,
 b int not null,
@@ -849,7 +941,7 @@ partitions 2
 #
 # Partition by list, wrong constant result type (not INT)
 #
---error ER_INCONSISTENT_TYPE_OF_FUNCTIONS_ERROR
+--error ER_VALUES_IS_NOT_INT_TYPE_ERROR
 CREATE TABLE t1 (
 a int not null,
 b int not null,
@@ -939,13 +1031,13 @@ PARTITION pmax VALUES LESS THAN MAXVALUE
 # Check that allowed arithmetic/math functions involving TIMESTAMP values result
 # in ER_PARTITION_FUNC_NOT_ALLOWED_ERROR when used as a partitioning function
 
---error ER_PARTITION_FUNC_NOT_ALLOWED_ERROR
+--error ER_FIELD_TYPE_NOT_ALLOWED_AS_PARTITION_FIELD
 CREATE TABLE new (a TIMESTAMP NOT NULL PRIMARY KEY)
 PARTITION BY RANGE (a) (
 PARTITION p VALUES LESS THAN (20080819),
 PARTITION pmax VALUES LESS THAN MAXVALUE);
 
---error ER_PARTITION_FUNC_NOT_ALLOWED_ERROR
+--error ER_FIELD_TYPE_NOT_ALLOWED_AS_PARTITION_FIELD
 ALTER TABLE old
 PARTITION BY RANGE (a) (
 PARTITION p VALUES LESS THAN (20080819),

=== modified file 'sql/partition_info.cc'
--- a/sql/partition_info.cc	2010-08-05 12:53:09 +0000
+++ b/sql/partition_info.cc	2010-08-30 15:33:55 +0000
@@ -742,7 +742,6 @@ bool partition_info::check_range_constan
     longlong part_range_value;
     bool signed_flag= !part_expr->unsigned_flag;
 
-    part_result_type= INT_RESULT;
     range_int_array= (longlong*)sql_alloc(num_parts * sizeof(longlong));
     if (unlikely(range_int_array == NULL))
     {
@@ -917,7 +916,6 @@ bool partition_info::check_list_constant
   List_iterator<partition_element> list_func_it(partitions);
   DBUG_ENTER("partition_info::check_list_constants");
 
-  part_result_type= INT_RESULT;
   num_list_values= 0;
   /*
     We begin by calculating the number of list values that have been
@@ -1608,6 +1606,52 @@ id_err:
   return 1;
 }
 
+
+/**
+  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;
+  DBUG_ENTER("partition_info::report_part_expr_error");
+  if (use_subpart_expr)
+    expr= subpart_expr;
+
+  if (expr->type() == Item::FIELD_ITEM)
+  {
+    partition_type type= part_type;
+    bool list_of_fields= list_of_part_fields;
+    Item_field *item_field= (Item_field*) expr;
+    /*
+      The expression consists of a single field.
+      It must be of integer type unless KEY or COLUMNS partitioning.
+    */
+    if (use_subpart_expr)
+    {
+      type= subpart_type;
+      list_of_fields= list_of_subpart_fields;
+    }
+    if (!column_list &&
+        item_field->field &&
+        item_field->field->result_type() != INT_RESULT &&
+        !(type == HASH_PARTITION && list_of_fields))
+    {
+      my_error(ER_FIELD_TYPE_NOT_ALLOWED_AS_PARTITION_FIELD, MYF(0),
+               item_field->name);
+      DBUG_VOID_RETURN;
+    }
+  }
+  if (use_subpart_expr)
+    my_error(ER_PARTITION_FUNC_NOT_ALLOWED_ERROR, MYF(0), "SUBPARTITION");
+  else
+    my_error(ER_PARTITION_FUNC_NOT_ALLOWED_ERROR, MYF(0), "PARTITION");
+  DBUG_VOID_RETURN;
+}
+ 
+
 /*
   Create a new column value in current list with maxvalue
   Called from parser
@@ -1891,7 +1935,7 @@ int partition_info::reorganize_into_sing
   code.
 
   SYNOPSIS
-  fix_func_partition()
+  fix_partition_values()
   thd                             Thread object
   col_val                         Array of one value
   part_elem                       The partition instance
@@ -1901,13 +1945,13 @@ int partition_info::reorganize_into_sing
     TRUE                     Failure
     FALSE                    Success
 */
-int partition_info::fix_func_partition(THD *thd,
-                                       part_elem_value *val,
-                                       partition_element *part_elem,
-                                       uint part_id)
+int 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_func_partition");
+  DBUG_ENTER("partition_info::fix_partition_values");
 
   if (col_val->fixed)
   {
@@ -1953,7 +1997,9 @@ int partition_info::fix_func_partition(T
     }
     else if (item_expr->result_type() != INT_RESULT)
     {
-      my_error(ER_INCONSISTENT_TYPE_OF_FUNCTIONS_ERROR, MYF(0));
+      /* VALUES clause only allowed on partitions, not subpartitions */
+      my_error(ER_VALUES_IS_NOT_INT_TYPE_ERROR, MYF(0),
+               part_elem->partition_name);
       DBUG_RETURN(TRUE);
     }
     if (part_type == RANGE_PARTITION)
@@ -2168,7 +2214,7 @@ int partition_info::fix_parser_data(THD 
       }
       else
       {
-        if (fix_func_partition(thd, val, part_elem, i))
+        if (fix_partition_values(thd, val, part_elem, i))
         {
           DBUG_RETURN(TRUE);
         }

=== modified file 'sql/partition_info.h'
--- a/sql/partition_info.h	2010-03-30 20:52:45 +0000
+++ b/sql/partition_info.h	2010-08-30 15:33:55 +0000
@@ -166,7 +166,6 @@ public:
   key_map some_fields_in_PF;
 
   handlerton *default_engine_type;
-  Item_result part_result_type;
   partition_type part_type;
   partition_type subpart_type;
 
@@ -226,7 +225,6 @@ public:
     curr_part_elem(NULL), current_partition(NULL),
     curr_list_object(0), num_columns(0),
     default_engine_type(NULL),
-    part_result_type(INT_RESULT),
     part_type(NOT_A_PARTITION), subpart_type(NOT_A_PARTITION),
     part_info_len(0),
     part_func_len(0), subpart_func_len(0),
@@ -279,10 +277,10 @@ 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_func_partition(THD *thd,
-                         part_elem_value *val,
-                         partition_element *part_elem,
-                         uint part_id);
+  int 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);
@@ -299,6 +297,7 @@ public:
   bool init_column_part();
   bool add_column_list_value(THD *thd, Item *item);
   void set_show_version_string(String *packet);
+  void report_part_expr_error(bool use_subpart_expr);
 private:
   static int list_part_cmp(const void* a, const void* b);
   bool set_up_default_partitions(handler *file, HA_CREATE_INFO *info,

=== modified file 'sql/share/errmsg-utf8.txt'
--- a/sql/share/errmsg-utf8.txt	2010-06-07 08:47:04 +0000
+++ b/sql/share/errmsg-utf8.txt	2010-08-30 15:33:55 +0000
@@ -6346,3 +6346,7 @@ ER_STORED_FUNCTION_PREVENTS_SWITCH_SQL_L
 ER_FAILED_READ_FROM_PAR_FILE
   eng "Failed to read from the .par file"
   swe "Misslyckades läsa från .par filen"
+
+ER_VALUES_IS_NOT_INT_TYPE_ERROR
+  eng "VALUES value for partition '%-.64s' must have type INT"
+  swe "Värden i VALUES för partition '%-.64s' måste ha typen INT"

=== modified file 'sql/sql_partition.cc'
--- a/sql/sql_partition.cc	2010-08-20 17:15:48 +0000
+++ b/sql/sql_partition.cc	2010-08-30 15:33:55 +0000
@@ -1762,8 +1762,7 @@ bool fix_partition_func(THD *thd, TABLE 
         goto end;
       if (unlikely(part_info->subpart_expr->result_type() != INT_RESULT))
       {
-        my_error(ER_PARTITION_FUNCTION_IS_NOT_ALLOWED, MYF(0),
-                 subpart_str);
+        part_info->report_part_expr_error(TRUE);
         goto end;
       }
     }
@@ -1790,10 +1789,9 @@ bool fix_partition_func(THD *thd, TABLE 
         goto end;
       if (unlikely(part_info->part_expr->result_type() != INT_RESULT))
       {
-        my_error(ER_PARTITION_FUNCTION_IS_NOT_ALLOWED, MYF(0), part_str);
+        part_info->report_part_expr_error(FALSE);
         goto end;
       }
-      part_info->part_result_type= INT_RESULT;
     }
     part_info->fixed= TRUE;
   }
@@ -1839,18 +1837,22 @@ bool fix_partition_func(THD *thd, TABLE 
     if (unlikely(!part_info->column_list &&
                   part_info->part_expr->result_type() != INT_RESULT))
     {
-      my_error(ER_PARTITION_FUNC_NOT_ALLOWED_ERROR, MYF(0), part_str);
+      part_info->report_part_expr_error(FALSE);
       goto end;
     }
   }
   if (((part_info->part_type != HASH_PARTITION ||
-      part_info->list_of_part_fields == FALSE) &&
-      (!part_info->column_list &&
-      check_part_func_fields(part_info->part_field_array, TRUE))) ||
+        part_info->list_of_part_fields == FALSE) &&
+       !part_info->column_list &&
+       check_part_func_fields(part_info->part_field_array, TRUE)) ||
       (part_info->list_of_subpart_fields == FALSE &&
        part_info->is_sub_partitioned() &&
        check_part_func_fields(part_info->subpart_field_array, TRUE)))
   {
+    /*
+      Range/List/HASH (but not KEY) and not COLUMNS or HASH subpartitioning
+      with columns in the partitioning expression using unallowed charset.
+    */
     my_error(ER_PARTITION_FUNCTION_IS_NOT_ALLOWED, MYF(0));
     goto end;
   }

=== modified file 'sql/sql_yacc.yy'
--- a/sql/sql_yacc.yy	2010-08-18 11:55:37 +0000
+++ b/sql/sql_yacc.yy	2010-08-30 15:33:55 +0000
@@ -4813,7 +4813,7 @@ part_value_expr_item:
 
             if (!lex->safe_to_cache_query)
             {
-              my_error(ER_PARTITION_FUNCTION_IS_NOT_ALLOWED, MYF(0));
+              my_parse_error(ER(ER_WRONG_EXPR_IN_PARTITION_FUNC_ERROR));
               MYSQL_YYABORT;
             }
             if (part_info->add_column_list_value(YYTHD, part_expr))

Attachment: [text/bzr-bundle] bzr/mattias.jonsson@oracle.com-20100830153355-9r3def4u5ht5xw5k.bundle
Thread
bzr commit into mysql-5.5-bugfixing branch (mattias.jonsson:3193) Bug#50036Mattias Jonsson30 Aug