List:Commits« Previous MessageNext Message »
From:Mikael Ronström Date:June 27 2006 8:10am
Subject:bk commit - 5.1 tree (mikael:....) BUG#18198
View as plain text  
diff -Nur --exclude=RCS --exclude=CVS --exclude=SCCS 
--exclude=BitKeeper --exclude=ChangeSet 
clean-mysql-5.1/mysql-test/r/partition.result 
clean-bug18198/mysql-test/r/partition.result
--- clean-mysql-5.1/mysql-test/r/partition.result	2006-06-22 10:12:42 
-04:00
+++ clean-bug18198/mysql-test/r/partition.result	2006-06-23 01:28:50 
-04:00
@@ -756,7 +756,7 @@
  ) ENGINE=MyISAM DEFAULT CHARSET=latin1 COMMENT='no comment' /*!50100 
PARTITION BY KEY (a)  */
  drop table t2;
  create table t1 (s1 char(2) character set utf8)
-partition by list (case when s1 > 'cz' then 1 else 2 end)
+partition by list (cast(s1 as signed))
  (partition p1 values in (1),
  partition p2 values in (2));
  drop table t1;
diff -Nur --exclude=RCS --exclude=CVS --exclude=SCCS 
--exclude=BitKeeper --exclude=ChangeSet 
clean-mysql-5.1/mysql-test/r/partition_error.result 
clean-bug18198/mysql-test/r/partition_error.result
--- clean-mysql-5.1/mysql-test/r/partition_error.result	2006-06-22 
10:12:42 -04:00
+++ clean-bug18198/mysql-test/r/partition_error.result	2006-06-23 
01:28:50 -04:00
@@ -1,5 +1,22 @@
  drop table if exists t1;
  create table t1 (a int)
+partition by range (a)
+(partition p0 values less than ((select count(*) from t1)));
+ERROR HY000: This partition function is not allowed
+create table t1 (a int)
+partition by range (a)
+(partition p0 values less than (a);
+ERROR 42S22: Unknown column 'a' in 'partition function'
+create table t1 (a int)
+partition by range (a)
+(partition p0 values less than (1));
+alter table t1 add partition (partition p1 values less than (a));
+ERROR 42S22: Unknown column 'a' in 'partition function'
+alter table t1 add partition
+(partition p1 values less than ((select count(*) from t1)));
+ERROR HY000: This partition function is not allowed
+drop table t1;
+create table t1 (a int)
  engine = x
  partition by key (a);
  Warnings:
diff -Nur --exclude=RCS --exclude=CVS --exclude=SCCS 
--exclude=BitKeeper --exclude=ChangeSet 
clean-mysql-5.1/mysql-test/t/partition.test 
clean-bug18198/mysql-test/t/partition.test
--- clean-mysql-5.1/mysql-test/t/partition.test	2006-06-22 10:12:42 
-04:00
+++ clean-bug18198/mysql-test/t/partition.test	2006-06-23 01:28:50 
-04:00
@@ -891,7 +891,7 @@
  # Bug#14367: Partitions: crash if utf8 column
  #
  create table t1 (s1 char(2) character set utf8)
-partition by list (case when s1 > 'cz' then 1 else 2 end)
+partition by list (cast(s1 as signed))
  (partition p1 values in (1),
   partition p2 values in (2));
  drop table t1;
diff -Nur --exclude=RCS --exclude=CVS --exclude=SCCS 
--exclude=BitKeeper --exclude=ChangeSet 
clean-mysql-5.1/mysql-test/t/partition_error.test 
clean-bug18198/mysql-test/t/partition_error.test
--- clean-mysql-5.1/mysql-test/t/partition_error.test	2006-06-22 
10:12:42 -04:00
+++ clean-bug18198/mysql-test/t/partition_error.test	2006-06-23 
01:28:50 -04:00
@@ -9,6 +9,28 @@
  --enable_warnings

  #
+# Bug 18198: Partitions: Too flexible functions
+#
+-- error ER_PARTITION_FUNCTION_IS_NOT_ALLOWED
+create table t1 (a int)
+partition by range (a)
+(partition p0 values less than ((select count(*) from t1)));
+-- error 1054
+create table t1 (a int)
+partition by range (a)
+(partition p0 values less than (a);
+
+create table t1 (a int)
+partition by range (a)
+(partition p0 values less than (1));
+-- error 1054
+alter table t1 add partition (partition p1 values less than (a));
+-- error ER_PARTITION_FUNCTION_IS_NOT_ALLOWED
+alter table t1 add partition
+(partition p1 values less than ((select count(*) from t1)));
+drop table t1;
+
+#
  # Bug 20397: Partitions: Crash when using non-existing engine
  #
  create table t1 (a int)
diff -Nur --exclude=RCS --exclude=CVS --exclude=SCCS 
--exclude=BitKeeper --exclude=ChangeSet clean-mysql-5.1/sql/item.h 
clean-bug18198/sql/item.h
--- clean-mysql-5.1/sql/item.h	2006-06-19 11:31:11 -04:00
+++ clean-bug18198/sql/item.h	2006-06-23 01:24:20 -04:00
@@ -789,7 +789,7 @@
      Check if a partition function is allowed
      SYNOPSIS
        check_partition_func_processor()
-      bool_arg                        Return argument
+      int_arg                        Return argument
      RETURN VALUE
        0
      DESCRIPTION
@@ -806,8 +806,28 @@
      whether this should be inherited to the new class. If not the 
function
      below should be defined in the new Item class.
    */
-  virtual bool check_partition_func_processor(byte *bool_arg)
-  { *(bool *)bool_arg= FALSE; return 0; }
+
+#define PF_SAFE_BINARY_COLLATION 3
+#define PF_SAFE_SINGLE_CHAR_COLLATION 2
+#define PF_SAFE 1
+#define PF_UNSAFE 0
+  bool safe_for_binary_collation(byte *int_arg)
+  {
+    if (*(int *)int_arg != PF_UNSAFE)
+      *(int*)int_arg= PF_SAFE_BINARY_COLLATION;
+    return 0;
+  }
+  bool safe_for_single_char_collation(byte *int_arg)
+  {
+    if (*(int*)int_arg == PF_SAFE)
+      *(int*)int_arg= PF_SAFE_SINGLE_CHAR_COLLATION;
+    return 0;
+  }
+  virtual bool check_partition_func_processor(byte *int_arg)
+  {
+    *(int *)int_arg= PF_UNSAFE;
+    return 0;
+  }

    virtual Item *equal_fields_propagator(byte * arg) { return this; }
    virtual Item *set_no_const_sub(byte *arg) { return this; }
@@ -1106,7 +1126,8 @@
      Item::maybe_null= TRUE;
    }

-  bool check_partition_func_processor(byte *bool_arg) { return 0; }
+  bool check_partition_func_processor(byte *int_arg)
+  { return safe_for_single_char_collation(int_arg); }
    bool fix_fields(THD *, Item **);

    enum Type type() const;
@@ -1153,7 +1174,7 @@
    Item_num() {}                               /* Remove gcc warning */
    virtual Item_num *neg()= 0;
    Item *safe_charset_converter(CHARSET_INFO *tocs);
-  bool check_partition_func_processor(byte *bool_arg) { return 0;}
+  bool check_partition_func_processor(byte *int_arg) { return 0;}
  };

  #define NO_CACHED_FIELD_INDEX ((uint)(-1))
@@ -1289,7 +1310,7 @@
    bool collect_item_field_processor(byte * arg);
    bool find_item_in_field_list_processor(byte *arg);
    bool register_field_in_read_map(byte *arg);
-  bool check_partition_func_processor(byte *bool_arg) { return 0; }
+  bool check_partition_func_processor(byte *int_arg) { return 0; }
    void cleanup();
    bool result_as_longlong()
    {
@@ -1337,7 +1358,7 @@
    bool is_null() { return 1; }
    void print(String *str) { str->append(STRING_WITH_LEN("NULL")); }
    Item *safe_charset_converter(CHARSET_INFO *tocs);
-  bool check_partition_func_processor(byte *bool_arg) { return 0;}
+  bool check_partition_func_processor(byte *int_arg) { return 0;}
  };

  class Item_null_result :public Item_null
@@ -1350,8 +1371,8 @@
    {
      save_in_field(result_field, no_conversions);
    }
-  bool check_partition_func_processor(byte *bool_arg)
-  { *(bool *)bool_arg= FALSE; return 0; }
+  bool check_partition_func_processor(byte *int_arg)
+  { *(int *)int_arg= PF_UNSAFE; return 0; }
  };

  /* Item represents one placeholder ('?') of prepared statement */
@@ -1642,8 +1663,8 @@
    {}
    void print(String *str) { str->append(func_name); }
    Item *safe_charset_converter(CHARSET_INFO *tocs);
-  bool check_partition_func_processor(byte *bool_arg)
-  { *(bool *)bool_arg= FALSE; return 0; }
+  bool check_partition_func_processor(byte *int_arg)
+  { *(int *)int_arg= PF_UNSAFE; return 0; }
  };


@@ -1721,7 +1742,7 @@
    void print(String *str);
    // to prevent drop fixed flag (no need parent cleanup call)
    void cleanup() {}
-  bool check_partition_func_processor(byte *bool_arg) { return 0;}
+  bool check_partition_func_processor(byte *int_arg) { return 0;}
  };


@@ -1736,8 +1757,8 @@
    {}
    Item *safe_charset_converter(CHARSET_INFO *tocs);
    void print(String *str) { str->append(func_name); }
-  bool check_partition_func_processor(byte *bool_arg)
-  { *(bool *)bool_arg= FALSE; return 0; }
+  bool check_partition_func_processor(byte *int_arg)
+  { *(int *)int_arg= PF_UNSAFE; return 0; }
  };


@@ -1750,8 +1771,8 @@
                                                      &my_charset_bin)
    { max_length=19;}
    enum_field_types field_type() const { return MYSQL_TYPE_DATETIME; }
-  bool check_partition_func_processor(byte *bool_arg)
-  { *(bool *)bool_arg= FALSE; return 0; }
+  bool check_partition_func_processor(byte *int_arg)
+  { *(int *)int_arg= PF_UNSAFE; return 0; }
  };

  class Item_empty_string :public Item_string
@@ -1774,8 +1795,8 @@
      unsigned_flag=1;
    }
    enum_field_types field_type() const { return int_field_type; }
-  bool check_partition_func_processor(byte *bool_arg)
-  { *(bool *)bool_arg= FALSE; return 0; }
+  bool check_partition_func_processor(byte *int_arg)
+  { *(int *)int_arg= PF_UNSAFE; return 0; }
  };


@@ -1799,7 +1820,8 @@
    void cleanup() {}
    bool eq(const Item *item, bool binary_cmp) const;
    virtual Item *safe_charset_converter(CHARSET_INFO *tocs);
-  bool check_partition_func_processor(byte *bool_arg) { return 0;}
+  bool check_partition_func_processor(byte *int_arg)
+  { return safe_for_binary_collation(int_arg);}
  };


@@ -2026,8 +2048,8 @@
    }
    Item *new_item();
    virtual Item *real_item() { return ref; }
-  bool check_partition_func_processor(byte *bool_arg)
-  { *(bool *)bool_arg= FALSE; return 0; }
+  bool check_partition_func_processor(byte *int_arg)
+  { *(int *)int_arg= PF_UNSAFE; return 0; }
  };

  #ifdef MYSQL_SERVER
diff -Nur --exclude=RCS --exclude=CVS --exclude=SCCS 
--exclude=BitKeeper --exclude=ChangeSet 
clean-mysql-5.1/sql/item_cmpfunc.h clean-bug18198/sql/item_cmpfunc.h
--- clean-mysql-5.1/sql/item_cmpfunc.h	2006-06-19 11:31:11 -04:00
+++ clean-bug18198/sql/item_cmpfunc.h	2006-06-23 01:24:20 -04:00
@@ -240,7 +240,8 @@
    }
    Item *neg_transformer(THD *thd);
    virtual Item *negated_item();
-  bool check_partition_func_processor(byte *bool_arg) { return 0;}
+  bool check_partition_func_processor(byte *int_arg)
+  { return safe_for_single_char_collation(int_arg); }
  };

  class Item_func_not :public Item_bool_func
@@ -251,7 +252,8 @@
    enum Functype functype() const { return NOT_FUNC; }
    const char *func_name() const { return "not"; }
    Item *neg_transformer(THD *thd);
-  bool check_partition_func_processor(byte *bool_arg) { return 0;}
+  bool check_partition_func_processor(byte *int_arg)
+  { return safe_for_single_char_collation(int_arg); }
  };

  class Item_maxmin_subselect;
@@ -466,7 +468,8 @@
    bool is_bool_func() { return 1; }
    CHARSET_INFO *compare_collation() { return cmp_collation.collation; }
    uint decimal_precision() const { return 1; }
-  bool check_partition_func_processor(byte *bool_arg) { return 0;}
+  bool check_partition_func_processor(byte *int_arg)
+  { return safe_for_single_char_collation(int_arg); }
  };


@@ -478,7 +481,8 @@
    optimize_type select_optimize() const { return OPTIMIZE_NONE; }
    const char *func_name() const { return "strcmp"; }
    void print(String *str) { Item_func::print(str); }
-  bool check_partition_func_processor(byte *bool_arg) { return 0;}
+  bool check_partition_func_processor(byte *int_arg)
+  { return safe_for_single_char_collation(int_arg); }
  };


@@ -541,7 +545,7 @@
    const char *func_name() const { return "ifnull"; }
    Field *tmp_table_field(TABLE *table);
    uint decimal_precision() const;
-  bool check_partition_func_processor(byte *bool_arg) { return 0;}
+  bool check_partition_func_processor(byte *int_arg) { return 0;}
  };


@@ -582,7 +586,7 @@
    void print(String *str) { Item_func::print(str); }
    table_map not_null_tables() const { return 0; }
    bool is_null();
-  bool check_partition_func_processor(byte *bool_arg) { return 0;}
+  bool check_partition_func_processor(byte *int_arg) { return 0;}
  };


@@ -625,7 +629,8 @@
    void print(String *str);
    Item *find_item(String *str);
    CHARSET_INFO *compare_collation() { return cmp_collation.collation; }
-  bool check_partition_func_processor(byte *bool_arg) { return 0;}
+  bool check_partition_func_processor(byte *int_arg)
+  { return safe_for_single_char_collation(int_arg); }
  };


@@ -976,7 +981,8 @@
    bool nulls_in_row();
    bool is_bool_func() { return 1; }
    CHARSET_INFO *compare_collation() { return cmp_collation.collation; }
-  bool check_partition_func_processor(byte *bool_arg) { return 0;}
+  bool check_partition_func_processor(byte *int_arg)
+  { return safe_for_single_char_collation(int_arg); }
  };

  /* Functions used by where clause */
@@ -1018,7 +1024,7 @@
    optimize_type select_optimize() const { return OPTIMIZE_NULL; }
    Item *neg_transformer(THD *thd);
    CHARSET_INFO *compare_collation() { return 
args[0]->collation.collation; }
-  bool check_partition_func_processor(byte *bool_arg) { return 0;}
+  bool check_partition_func_processor(byte *int_arg) { return 0;}
  };

  /* Functions used by HAVING for rewriting IN subquery */
@@ -1040,8 +1046,8 @@
    */
    table_map used_tables() const
      { return used_tables_cache | RAND_TABLE_BIT; }
-  bool check_partition_func_processor(byte *bool_arg)
-  { *(bool *)bool_arg= FALSE; return 0; }
+  bool check_partition_func_processor(byte *int_arg)
+  { *(int *)int_arg= PF_UNSAFE; return 0; }
  };


@@ -1064,7 +1070,7 @@
    void print(String *str);
    CHARSET_INFO *compare_collation() { return 
args[0]->collation.collation; }
    void top_level_item() { abort_on_null=1; }
-  bool check_partition_func_processor(byte *bool_arg) { return 0;}
+  bool check_partition_func_processor(byte *int_arg) { return 0;}
  };


@@ -1103,7 +1109,8 @@
    const char *func_name() const { return "like"; }
    bool fix_fields(THD *thd, Item **ref);
    void cleanup();
-  bool check_partition_func_processor(byte *bool_arg) { return 0;}
+  bool check_partition_func_processor(byte *int_arg)
+  { return safe_for_single_char_collation(int_arg); }
  };

  #ifdef USE_REGEX
@@ -1126,7 +1133,8 @@
    const char *func_name() const { return "regexp"; }
    void print(String *str) { print_op(str); }
    CHARSET_INFO *compare_collation() { return cmp_collation.collation; }
-  bool check_partition_func_processor(byte *bool_arg) { return 0;}
+  bool check_partition_func_processor(byte *int_arg)
+  { return safe_for_single_char_collation(int_arg); }
  };

  #else
@@ -1183,7 +1191,8 @@
    Item *transform(Item_transformer transformer, byte *arg);
    void traverse_cond(Cond_traverser, void *arg, traverse_order order);
    void neg_arguments(THD *thd);
-  bool check_partition_func_processor(byte *bool_arg) { return 0;}
+  bool check_partition_func_processor(byte *int_arg)
+  { return safe_for_single_char_collation(int_arg); }
  };


diff -Nur --exclude=RCS --exclude=CVS --exclude=SCCS 
--exclude=BitKeeper --exclude=ChangeSet clean-mysql-5.1/sql/item_func.h 
clean-bug18198/sql/item_func.h
--- clean-mysql-5.1/sql/item_func.h	2006-06-12 14:23:08 -04:00
+++ clean-bug18198/sql/item_func.h	2006-06-23 01:24:20 -04:00
@@ -247,7 +247,7 @@
    void fix_num_length_and_dec();
    void find_num_type();
    String *str_op(String *str) { DBUG_ASSERT(0); return 0; }
-  bool check_partition_func_processor(byte *bool_arg) { return 0;}
+  bool check_partition_func_processor(byte *int_arg) { return 0;}
  };


@@ -260,7 +260,7 @@
    void print(String *str) { print_op(str); }
    void find_num_type();
    String *str_op(String *str) { DBUG_ASSERT(0); return 0; }
-  bool check_partition_func_processor(byte *bool_arg) { return 0;}
+  bool check_partition_func_processor(byte *int_arg) { return 0;}
  };


@@ -311,7 +311,7 @@
    { max_length=args[0]->max_length; unsigned_flag=0; }
    void print(String *str);
    uint decimal_precision() const { return 
args[0]->decimal_precision(); }
-  bool check_partition_func_processor(byte *bool_arg) { return 0;}
+  bool check_partition_func_processor(byte *int_arg) { return 0;}
  };


@@ -345,7 +345,7 @@
    void fix_length_and_dec() {};
    const char *func_name() const { return "decimal_typecast"; }
    void print(String *);
-  bool check_partition_func_processor(byte *bool_arg) { return 0;}
+  bool check_partition_func_processor(byte *int_arg) { return 0;}
  };


@@ -414,7 +414,7 @@
    const char *func_name() const { return "DIV"; }
    void fix_length_and_dec();
    void print(String *str) { print_op(str); }
-  bool check_partition_func_processor(byte *bool_arg) { return 0;}
+  bool check_partition_func_processor(byte *int_arg) { return 0;}
  };


@@ -487,7 +487,7 @@
    Item_func_exp(Item *a) :Item_dec_func(a) {}
    double val_real();
    const char *func_name() const { return "exp"; }
-  bool check_partition_func_processor(byte *bool_arg) { return 0;}
+  bool check_partition_func_processor(byte *int_arg) { return 0;}
  };


@@ -497,7 +497,7 @@
    Item_func_ln(Item *a) :Item_dec_func(a) {}
    double val_real();
    const char *func_name() const { return "ln"; }
-  bool check_partition_func_processor(byte *bool_arg) { return 0;}
+  bool check_partition_func_processor(byte *int_arg) { return 0;}
  };


@@ -508,7 +508,7 @@
    Item_func_log(Item *a,Item *b) :Item_dec_func(a,b) {}
    double val_real();
    const char *func_name() const { return "log"; }
-  bool check_partition_func_processor(byte *bool_arg) { return 0;}
+  bool check_partition_func_processor(byte *int_arg) { return 0;}
  };


@@ -518,7 +518,7 @@
    Item_func_log2(Item *a) :Item_dec_func(a) {}
    double val_real();
    const char *func_name() const { return "log2"; }
-  bool check_partition_func_processor(byte *bool_arg) { return 0;}
+  bool check_partition_func_processor(byte *int_arg) { return 0;}
  };


@@ -528,7 +528,7 @@
    Item_func_log10(Item *a) :Item_dec_func(a) {}
    double val_real();
    const char *func_name() const { return "log10"; }
-  bool check_partition_func_processor(byte *bool_arg) { return 0;}
+  bool check_partition_func_processor(byte *int_arg) { return 0;}
  };


@@ -538,7 +538,7 @@
    Item_func_sqrt(Item *a) :Item_dec_func(a) {}
    double val_real();
    const char *func_name() const { return "sqrt"; }
-  bool check_partition_func_processor(byte *bool_arg) { return 0;}
+  bool check_partition_func_processor(byte *int_arg) { return 0;}
  };


@@ -548,7 +548,7 @@
    Item_func_pow(Item *a,Item *b) :Item_dec_func(a,b) {}
    double val_real();
    const char *func_name() const { return "pow"; }
-  bool check_partition_func_processor(byte *bool_arg) { return 0;}
+  bool check_partition_func_processor(byte *int_arg) { return 0;}
  };


@@ -558,7 +558,7 @@
    Item_func_acos(Item *a) :Item_dec_func(a) {}
    double val_real();
    const char *func_name() const { return "acos"; }
-  bool check_partition_func_processor(byte *bool_arg) { return 0;}
+  bool check_partition_func_processor(byte *int_arg) { return 0;}
  };

  class Item_func_asin :public Item_dec_func
@@ -567,7 +567,7 @@
    Item_func_asin(Item *a) :Item_dec_func(a) {}
    double val_real();
    const char *func_name() const { return "asin"; }
-  bool check_partition_func_processor(byte *bool_arg) { return 0;}
+  bool check_partition_func_processor(byte *int_arg) { return 0;}
  };

  class Item_func_atan :public Item_dec_func
@@ -577,7 +577,7 @@
    Item_func_atan(Item *a,Item *b) :Item_dec_func(a,b) {}
    double val_real();
    const char *func_name() const { return "atan"; }
-  bool check_partition_func_processor(byte *bool_arg) { return 0;}
+  bool check_partition_func_processor(byte *int_arg) { return 0;}
  };

  class Item_func_cos :public Item_dec_func
@@ -586,7 +586,7 @@
    Item_func_cos(Item *a) :Item_dec_func(a) {}
    double val_real();
    const char *func_name() const { return "cos"; }
-  bool check_partition_func_processor(byte *bool_arg) { return 0;}
+  bool check_partition_func_processor(byte *int_arg) { return 0;}
  };

  class Item_func_sin :public Item_dec_func
@@ -595,7 +595,7 @@
    Item_func_sin(Item *a) :Item_dec_func(a) {}
    double val_real();
    const char *func_name() const { return "sin"; }
-  bool check_partition_func_processor(byte *bool_arg) { return 0;}
+  bool check_partition_func_processor(byte *int_arg) { return 0;}
  };

  class Item_func_tan :public Item_dec_func
@@ -604,7 +604,7 @@
    Item_func_tan(Item *a) :Item_dec_func(a) {}
    double val_real();
    const char *func_name() const { return "tan"; }
-  bool check_partition_func_processor(byte *bool_arg) { return 0;}
+  bool check_partition_func_processor(byte *int_arg) { return 0;}
  };

  class Item_func_integer :public Item_int_func
@@ -681,7 +681,7 @@
    Item_func_sign(Item *a) :Item_int_func(a) {}
    const char *func_name() const { return "sign"; }
    longlong val_int();
-  bool check_partition_func_processor(byte *bool_arg) { return 0;}
+  bool check_partition_func_processor(byte *int_arg) { return 0;}
  };


@@ -696,7 +696,7 @@
    const char *func_name() const { return name; }
    void fix_length_and_dec()
    { decimals= NOT_FIXED_DEC; max_length= float_length(decimals); }
-  bool check_partition_func_processor(byte *bool_arg) { return 0;}
+  bool check_partition_func_processor(byte *int_arg) { return 0;}
  };


@@ -714,7 +714,7 @@
    my_decimal *val_decimal(my_decimal *);
    void fix_length_and_dec();
    enum Item_result result_type () const { return cmp_type; }
-  bool check_partition_func_processor(byte *bool_arg) { return 0;}
+  bool check_partition_func_processor(byte *int_arg) { return 0;}
  };

  class Item_func_min :public Item_func_min_max
@@ -740,7 +740,8 @@
    longlong val_int();
    const char *func_name() const { return "length"; }
    void fix_length_and_dec() { max_length=10; }
-  bool check_partition_func_processor(byte *bool_arg) { return 0;}
+  bool check_partition_func_processor(byte *int_arg)
+  { return safe_for_single_char_collation(int_arg);}
  };

  class Item_func_bit_length :public Item_func_length
@@ -760,7 +761,8 @@
    longlong val_int();
    const char *func_name() const { return "char_length"; }
    void fix_length_and_dec() { max_length=10; }
-  bool check_partition_func_processor(byte *bool_arg) { return 0;}
+  bool check_partition_func_processor(byte *int_arg)
+  { return safe_for_single_char_collation(int_arg);}
  };

  class Item_func_coercibility :public Item_int_func
@@ -771,7 +773,6 @@
    const char *func_name() const { return "coercibility"; }
    void fix_length_and_dec() { max_length=10; maybe_null= 0; }
    table_map not_null_tables() const { return 0; }
-  bool check_partition_func_processor(byte *bool_arg) { return 0;}
  };

  class Item_func_locate :public Item_int_func
@@ -785,7 +786,8 @@
    longlong val_int();
    void fix_length_and_dec();
    void print(String *str);
-  bool check_partition_func_processor(byte *bool_arg) { return 0;}
+  bool check_partition_func_processor(byte *int_arg)
+  { return safe_for_single_char_collation(int_arg);}
  };


@@ -810,7 +812,8 @@
    longlong val_int();
    const char *func_name() const { return "ascii"; }
    void fix_length_and_dec() { max_length=3; }
-  bool check_partition_func_processor(byte *bool_arg) { return 0;}
+  bool check_partition_func_processor(byte *int_arg)
+  { return safe_for_single_char_collation(int_arg);}
  };

  class Item_func_ord :public Item_int_func
@@ -820,7 +823,8 @@
    Item_func_ord(Item *a) :Item_int_func(a) {}
    longlong val_int();
    const char *func_name() const { return "ord"; }
-  bool check_partition_func_processor(byte *bool_arg) { return 0;}
+  bool check_partition_func_processor(byte *int_arg)
+  { return safe_for_single_char_collation(int_arg);}
  };

  class Item_func_find_in_set :public Item_int_func
@@ -834,7 +838,8 @@
    longlong val_int();
    const char *func_name() const { return "find_in_set"; }
    void fix_length_and_dec();
-  bool check_partition_func_processor(byte *bool_arg) { return 0;}
+  bool check_partition_func_processor(byte *int_arg)
+  { return safe_for_single_char_collation(int_arg);}
  };

  /* Base class for all bit functions: '~', '|', '^', '&', '>>', '<<' */
@@ -846,7 +851,7 @@
    Item_func_bit(Item *a) :Item_int_func(a) {}
    void fix_length_and_dec() { unsigned_flag= 1; }
    void print(String *str) { print_op(str); }
-  bool check_partition_func_processor(byte *bool_arg) { return 0;}
+  bool check_partition_func_processor(byte *int_arg) { return 0;}
  };

  class Item_func_bit_or :public Item_func_bit
@@ -872,7 +877,7 @@
    longlong val_int();
    const char *func_name() const { return "bit_count"; }
    void fix_length_and_dec() { max_length=2; }
-  bool check_partition_func_processor(byte *bool_arg) { return 0;}
+  bool check_partition_func_processor(byte *int_arg) { return 0;}
  };

  class Item_func_shift_left :public Item_func_bit
@@ -1309,7 +1314,7 @@
     longlong val_int();
     const char *func_name() const { return "inet_aton"; }
     void fix_length_and_dec() { decimals = 0; max_length = 21; 
maybe_null=1;}
-  bool check_partition_func_processor(byte *bool_arg) { return 0;}
+  bool check_partition_func_processor(byte *int_arg) { return 0;}
  };


diff -Nur --exclude=RCS --exclude=CVS --exclude=SCCS 
--exclude=BitKeeper --exclude=ChangeSet 
clean-mysql-5.1/sql/item_strfunc.h clean-bug18198/sql/item_strfunc.h
--- clean-mysql-5.1/sql/item_strfunc.h	2006-06-14 19:36:54 -04:00
+++ clean-bug18198/sql/item_strfunc.h	2006-06-23 01:24:20 -04:00
@@ -47,7 +47,8 @@
    String *val_str(String *);
    void fix_length_and_dec();
    const char *func_name() const { return "md5"; }
-  bool check_partition_func_processor(byte *bool_arg) { return 0;}
+  bool check_partition_func_processor(byte *int_arg)
+  { return safe_for_single_char_collation(int_arg);}
  };


@@ -58,7 +59,8 @@
    String *val_str(String *);
    void fix_length_and_dec();
    const char *func_name() const { return "sha"; }	
-  bool check_partition_func_processor(byte *bool_arg) { return 0;}
+  bool check_partition_func_processor(byte *int_arg)
+  { return safe_for_single_char_collation(int_arg);}
  };

  class Item_func_aes_encrypt :public Item_str_func
@@ -89,7 +91,8 @@
    String *val_str(String *);
    void fix_length_and_dec();
    const char *func_name() const { return "concat"; }
-  bool check_partition_func_processor(byte *bool_arg) { return 0;}
+  bool check_partition_func_processor(byte *int_arg)
+  { return safe_for_single_char_collation(int_arg);}
  };

  class Item_func_concat_ws :public Item_str_func
@@ -110,7 +113,8 @@
    String *val_str(String *);
    void fix_length_and_dec();
    const char *func_name() const { return "reverse"; }
-  bool check_partition_func_processor(byte *bool_arg) { return 0;}
+  bool check_partition_func_processor(byte *int_arg)
+  { return safe_for_single_char_collation(int_arg);}
  };


@@ -148,7 +152,8 @@
  public:
    Item_str_conv(Item *item) :Item_str_func(item) {}
    String *val_str(String *);
-  bool check_partition_func_processor(byte *bool_arg) { return 0;}
+  bool check_partition_func_processor(byte *int_arg)
+  { return safe_for_binary_collation(int_arg);}
  };


@@ -212,7 +217,8 @@
    String *val_str(String *);
    void fix_length_and_dec();
    const char *func_name() const { return "substr"; }
-  bool check_partition_func_processor(byte *bool_arg) { return 0;}
+  bool check_partition_func_processor(byte *int_arg)
+  { return safe_for_single_char_collation(int_arg);}
  };


@@ -224,7 +230,8 @@
    String *val_str(String *);
    void fix_length_and_dec();
    const char *func_name() const { return "substring_index"; }
-  bool check_partition_func_processor(byte *bool_arg) { return 0;}
+  bool check_partition_func_processor(byte *int_arg)
+  { return safe_for_single_char_collation(int_arg);}
  };


@@ -239,7 +246,8 @@
    String *val_str(String *);
    void fix_length_and_dec();
    const char *func_name() const { return "trim"; }
-  bool check_partition_func_processor(byte *bool_arg) { return 0;}
+  bool check_partition_func_processor(byte *int_arg)
+  { return safe_for_single_char_collation(int_arg);}
  };


@@ -419,7 +427,8 @@
    String *val_str(String *);
    void fix_length_and_dec();
    const char *func_name() const { return "soundex"; }
-  bool check_partition_func_processor(byte *bool_arg) { return 0;}
+  bool check_partition_func_processor(byte *int_arg)
+  { return safe_for_single_char_collation(int_arg);}
  };


@@ -527,7 +536,8 @@
    String *val_str(String *);
    void fix_length_and_dec();
    const char *func_name() const { return "rpad"; }
-  bool check_partition_func_processor(byte *bool_arg) { return 0;}
+  bool check_partition_func_processor(byte *int_arg)
+  { return safe_for_single_char_collation(int_arg);}
  };


@@ -540,7 +550,8 @@
    String *val_str(String *);
    void fix_length_and_dec();
    const char *func_name() const { return "lpad"; }
-  bool check_partition_func_processor(byte *bool_arg) { return 0;}
+  bool check_partition_func_processor(byte *int_arg)
+  { return safe_for_single_char_collation(int_arg);}
  };


@@ -555,7 +566,8 @@
      collation.set(default_charset());
      max_length= 64;
    }
-  bool check_partition_func_processor(byte *bool_arg) { return 0;}
+  bool check_partition_func_processor(byte *int_arg)
+  { return safe_for_single_char_collation(int_arg);}
  };


@@ -572,7 +584,8 @@
      decimals=0;
      max_length=args[0]->max_length*2*collation.collation->mbmaxlen;
    }
-  bool check_partition_func_processor(byte *bool_arg) { return 0;}
+  bool check_partition_func_processor(byte *int_arg)
+  { return safe_for_binary_collation(int_arg);}
  };

  class Item_func_unhex :public Item_str_func
@@ -588,7 +601,8 @@
      decimals=0;
      max_length=(1+args[0]->max_length)/2;
    }
-  bool check_partition_func_processor(byte *bool_arg) { return 0;}
+  bool check_partition_func_processor(byte *int_arg)
+  { return safe_for_binary_collation(int_arg);}
  };


@@ -612,7 +626,8 @@
    }
    void print(String *str);
    const char *func_name() const { return "cast_as_binary"; }
-  bool check_partition_func_processor(byte *bool_arg) { return 0;}
+  bool check_partition_func_processor(byte *int_arg)
+  { return safe_for_single_char_collation(int_arg);}
  };


@@ -652,7 +667,7 @@
    String* val_str(String* str);
    const char *func_name() const { return "inet_ntoa"; }
    void fix_length_and_dec() { decimals = 0; max_length=3*8+7; }
-  bool check_partition_func_processor(byte *bool_arg) { return 0;}
+  bool check_partition_func_processor(byte *int_arg) { return 0;}
  };

  class Item_func_quote :public Item_str_func
@@ -667,7 +682,7 @@
      collation.set(args[0]->collation);
      max_length= args[0]->max_length * 2 + 2;
    }
-  bool check_partition_func_processor(byte *bool_arg) { return 0;}
+  bool check_partition_func_processor(byte *int_arg) { return 0;}
  };

  class Item_func_conv_charset :public Item_str_func
@@ -711,7 +726,6 @@
    void fix_length_and_dec();
    const char *func_name() const { return "convert"; }
    void print(String *str);
-  bool check_partition_func_processor(byte *bool_arg) { return 0;}
  };

  class Item_func_set_collation :public Item_str_func
@@ -744,7 +758,6 @@
       maybe_null= 0;
    };
    table_map not_null_tables() const { return 0; }
-  bool check_partition_func_processor(byte *bool_arg) { return 0;}
  };

  class Item_func_collation :public Item_str_func
@@ -760,7 +773,6 @@
       maybe_null= 0;
    };
    table_map not_null_tables() const { return 0; }
-  bool check_partition_func_processor(byte *bool_arg) { return 0;}
  };

  class Item_func_crc32 :public Item_int_func
@@ -771,7 +783,8 @@
    const char *func_name() const { return "crc32"; }
    void fix_length_and_dec() { max_length=10; }
    longlong val_int();
-  bool check_partition_func_processor(byte *bool_arg) { return 0;}
+  bool check_partition_func_processor(byte *int_arg)
+  { return safe_for_single_char_collation(int_arg);}
  };

  class Item_func_uncompressed_length : public Item_int_func
@@ -782,7 +795,8 @@
    const char *func_name() const{return "uncompressed_length";}
    void fix_length_and_dec() { max_length=10; }
    longlong val_int();
-  bool check_partition_func_processor(byte *bool_arg) { return 0;}
+  bool check_partition_func_processor(byte *int_arg)
+  { return safe_for_single_char_collation(int_arg);}
  };

  #ifdef HAVE_COMPRESS
@@ -799,7 +813,8 @@
    void fix_length_and_dec(){max_length= 
(args[0]->max_length*120)/100+12;}
    const char *func_name() const{return "compress";}
    String *val_str(String *) ZLIB_DEPENDED_FUNCTION
-  bool check_partition_func_processor(byte *bool_arg) { return 0;}
+  bool check_partition_func_processor(byte *int_arg)
+  { return safe_for_single_char_collation(int_arg);}
  };

  class Item_func_uncompress: public Item_str_func
@@ -810,7 +825,8 @@
    void fix_length_and_dec(){max_length= MAX_BLOB_WIDTH;}
    const char *func_name() const{return "uncompress";}
    String *val_str(String *) ZLIB_DEPENDED_FUNCTION
-  bool check_partition_func_processor(byte *bool_arg) { return 0;}
+  bool check_partition_func_processor(byte *int_arg)
+  { return safe_for_single_char_collation(int_arg);}
  };

  #define UUID_LENGTH (8+1+4+1+4+1+4+1+12)
diff -Nur --exclude=RCS --exclude=CVS --exclude=SCCS 
--exclude=BitKeeper --exclude=ChangeSet 
clean-mysql-5.1/sql/item_timefunc.h clean-bug18198/sql/item_timefunc.h
--- clean-mysql-5.1/sql/item_timefunc.h	2006-06-19 11:31:11 -04:00
+++ clean-bug18198/sql/item_timefunc.h	2006-06-23 01:24:20 -04:00
@@ -39,7 +39,7 @@
    {
      max_length=6*MY_CHARSET_BIN_MB_MAXLEN;
    }
-  bool check_partition_func_processor(byte *bool_arg) { return 0;}
+  bool check_partition_func_processor(byte *int_arg) { return 0;}
  };


@@ -54,7 +54,7 @@
      decimals=0;
      max_length=6*MY_CHARSET_BIN_MB_MAXLEN;
    }
-  bool check_partition_func_processor(byte *bool_arg) { return 0;}
+  bool check_partition_func_processor(byte *int_arg) { return 0;}
  };


@@ -71,7 +71,7 @@
      maybe_null=1;
    }
    enum_monotonicity_info get_monotonicity_info() const;
-  bool check_partition_func_processor(byte *bool_arg) { return 0;}
+  bool check_partition_func_processor(byte *int_arg) { return 0;}
  };


@@ -87,7 +87,7 @@
      max_length=2*MY_CHARSET_BIN_MB_MAXLEN;
      maybe_null=1;
    }
-  bool check_partition_func_processor(byte *bool_arg) { return 0;}
+  bool check_partition_func_processor(byte *int_arg) { return 0;}
  };


@@ -112,7 +112,7 @@
      max_length=2*MY_CHARSET_BIN_MB_MAXLEN;
      maybe_null=1;
    }
-  bool check_partition_func_processor(byte *bool_arg) { return 0;}
+  bool check_partition_func_processor(byte *int_arg) { return 0;}
  };


@@ -145,7 +145,7 @@
      max_length=3*MY_CHARSET_BIN_MB_MAXLEN;
      maybe_null=1;
    }
-  bool check_partition_func_processor(byte *bool_arg) { return 0;}
+  bool check_partition_func_processor(byte *int_arg) { return 0;}
  };


@@ -161,7 +161,7 @@
      max_length=2*MY_CHARSET_BIN_MB_MAXLEN;
      maybe_null=1;
    }
-  bool check_partition_func_processor(byte *bool_arg) { return 0;}
+  bool check_partition_func_processor(byte *int_arg) { return 0;}
  };


@@ -177,7 +177,7 @@
      max_length=2*MY_CHARSET_BIN_MB_MAXLEN;
      maybe_null=1;
    }
-  bool check_partition_func_processor(byte *bool_arg) { return 0;}
+  bool check_partition_func_processor(byte *int_arg) { return 0;}
  };


@@ -193,7 +193,7 @@
       max_length=1*MY_CHARSET_BIN_MB_MAXLEN;
       maybe_null=1;
    }
-  bool check_partition_func_processor(byte *bool_arg) { return 0;}
+  bool check_partition_func_processor(byte *int_arg) { return 0;}
  };


@@ -209,7 +209,7 @@
      max_length=2*MY_CHARSET_BIN_MB_MAXLEN;
      maybe_null=1;
    }
-  bool check_partition_func_processor(byte *bool_arg) { return 0;}
+  bool check_partition_func_processor(byte *int_arg) { return 0;}
  };


@@ -225,7 +225,7 @@
      max_length=2*MY_CHARSET_BIN_MB_MAXLEN;
      maybe_null=1;
    }
-  bool check_partition_func_processor(byte *bool_arg) { return 0;}
+  bool check_partition_func_processor(byte *int_arg) { return 0;}
  };

  class Item_func_yearweek :public Item_int_func
@@ -240,7 +240,7 @@
      max_length=6*MY_CHARSET_BIN_MB_MAXLEN;
      maybe_null=1;
    }
-  bool check_partition_func_processor(byte *bool_arg) { return 0;}
+  bool check_partition_func_processor(byte *int_arg) { return 0;}
  };


@@ -257,7 +257,7 @@
      max_length=4*MY_CHARSET_BIN_MB_MAXLEN;
      maybe_null=1;
    }
-  bool check_partition_func_processor(byte *bool_arg) { return 0;}
+  bool check_partition_func_processor(byte *int_arg) { return 0;}
  };


@@ -287,7 +287,7 @@
      max_length=1*MY_CHARSET_BIN_MB_MAXLEN;
      maybe_null=1;
    }
-  bool check_partition_func_processor(byte *bool_arg) { return 0;}
+  bool check_partition_func_processor(byte *int_arg) { return 0;}
  };

  class Item_func_dayname :public Item_func_weekday
@@ -320,7 +320,7 @@
      decimals=0;
      max_length=10*MY_CHARSET_BIN_MB_MAXLEN;
    }
-  bool check_partition_func_processor(byte *bool_arg) { return 0;}
+  bool check_partition_func_processor(byte *int_arg) { return 0;}
  };


@@ -335,7 +335,7 @@
      decimals=0;
      max_length=10*MY_CHARSET_BIN_MB_MAXLEN;
    }
-  bool check_partition_func_processor(byte *bool_arg) { return 0;}
+  bool check_partition_func_processor(byte *int_arg) { return 0;}
  };


@@ -545,7 +545,7 @@
    Item_func_from_days(Item *a) :Item_date(a) {}
    const char *func_name() const { return "from_days"; }
    bool get_date(TIME *res, uint fuzzy_date);
-  bool check_partition_func_processor(byte *bool_arg) { return 0;}
+  bool check_partition_func_processor(byte *int_arg) { return 0;}
  };


@@ -563,7 +563,7 @@
    void fix_length_and_dec();
    uint format_length(const String *format);
    bool eq(const Item *item, bool binary_cmp) const;
-  bool check_partition_func_processor(byte *bool_arg) { return 0;}
+  bool check_partition_func_processor(byte *int_arg) { return 0;}
  };


@@ -582,7 +582,7 @@
    const char *func_name() const { return "from_unixtime"; }
    void fix_length_and_dec();
    bool get_date(TIME *res, uint fuzzy_date);
-  bool check_partition_func_processor(byte *bool_arg) { return 0;}
+  bool check_partition_func_processor(byte *int_arg) { return 0;}
  };


@@ -651,7 +651,7 @@
      return tmp_table_field_from_field_type(table, 0);
    }
    bool result_as_longlong() { return TRUE; }
-  bool check_partition_func_processor(byte *bool_arg) { return 0;}
+  bool check_partition_func_processor(byte *int_arg) { return 0;}
  };


@@ -674,7 +674,7 @@
    bool get_date(TIME *res, uint fuzzy_date);
    bool eq(const Item *item, bool binary_cmp) const;
    void print(String *str);
-  bool check_partition_func_processor(byte *bool_arg) { return 0;}
+  bool check_partition_func_processor(byte *int_arg) { return 0;}
  };


@@ -692,7 +692,8 @@
    void fix_length_and_dec();
    bool eq(const Item *item, bool binary_cmp) const;
    void print(String *str);
-  bool check_partition_func_processor(byte *bool_arg) { return 0;}
+  bool check_partition_func_processor(byte *int_arg)
+  { return safe_for_single_char_collation(int_arg); }
  };


@@ -729,7 +730,7 @@
      max_length=args[0]->max_length;
      maybe_null= 1;
    }
-  bool check_partition_func_processor(byte *bool_arg) { return 0;}
+  bool check_partition_func_processor(byte *int_arg) { return 0;}
  };


@@ -749,7 +750,8 @@
    String *val_str(String *a);
    void fix_length_and_dec();
    void print(String *str);
-  bool check_partition_func_processor(byte *bool_arg) { return 0;}
+  bool check_partition_func_processor(byte *int_arg)
+  { return safe_for_single_char_collation(int_arg); }
  };


@@ -829,7 +831,7 @@
    }
    bool result_as_longlong() { return TRUE; }
    longlong val_int();
-  bool check_partition_func_processor(byte *bool_arg) { return 0;}
+  bool check_partition_func_processor(byte *int_arg) { return 0;}
  };


@@ -852,7 +854,7 @@
    }
    void print(String *str);
    const char *func_name() const { return "add_time"; }
-  bool check_partition_func_processor(byte *bool_arg) { return 0;}
+  bool check_partition_func_processor(byte *int_arg) { return 0;}
  };

  class Item_func_timediff :public Item_str_func
@@ -892,7 +894,7 @@
    {
      return tmp_table_field_from_field_type(table, 0);
    }
-  bool check_partition_func_processor(byte *bool_arg) { return 0;}
+  bool check_partition_func_processor(byte *int_arg) { return 0;}
  };

  class Item_func_microsecond :public Item_int_func
@@ -906,7 +908,7 @@
      decimals=0;
      maybe_null=1;
    }
-  bool check_partition_func_processor(byte *bool_arg) { return 0;}
+  bool check_partition_func_processor(byte *int_arg) { return 0;}
  };


@@ -924,7 +926,7 @@
      maybe_null=1;
    }
    void print(String *str);
-  bool check_partition_func_processor(byte *bool_arg) { return 0;}
+  bool check_partition_func_processor(byte *int_arg) { return 0;}
  };


@@ -971,7 +973,7 @@
    {
      return tmp_table_field_from_field_type(table, 1);
    }
-  bool check_partition_func_processor(byte *bool_arg) { return 0;}
+  bool check_partition_func_processor(byte *int_arg) { return 0;}
  };


diff -Nur --exclude=RCS --exclude=CVS --exclude=SCCS 
--exclude=BitKeeper --exclude=ChangeSet 
clean-mysql-5.1/sql/item_xmlfunc.h clean-bug18198/sql/item_xmlfunc.h
--- clean-mysql-5.1/sql/item_xmlfunc.h	2006-06-12 14:23:08 -04:00
+++ clean-bug18198/sql/item_xmlfunc.h	2006-06-23 01:24:20 -04:00
@@ -42,7 +42,8 @@
    Item_func_xml_extractvalue(Item *a,Item *b) :Item_xml_str_func(a,b) 
{}
    const char *func_name() const { return "extractvalue"; }
    String *val_str(String *);
-  bool check_partition_func_processor(byte *bool_arg) { return 0;}
+  bool check_partition_func_processor(byte *int_arg)
+  { return safe_for_single_char_collation(int_arg);}
  };


diff -Nur --exclude=RCS --exclude=CVS --exclude=SCCS 
--exclude=BitKeeper --exclude=ChangeSet 
clean-mysql-5.1/sql/partition_info.cc 
clean-bug18198/sql/partition_info.cc
--- clean-mysql-5.1/sql/partition_info.cc	2006-06-15 14:04:29 -04:00
+++ clean-bug18198/sql/partition_info.cc	2006-06-23 01:24:21 -04:00
@@ -694,6 +694,7 @@
      file                A reference to a handler of the table
      max_rows            Maximum number of rows stored in the table
      engine_type         Return value for used engine in partitions
+    check_partition_function Should we check the partition function

    RETURN VALUE
      TRUE                 Error, something went wrong
@@ -708,26 +709,42 @@
  */

  bool partition_info::check_partition_info(THD *thd, handlerton 
**eng_type,
-                                          handler *file, ulonglong 
max_rows)
+                                          handler *file, ulonglong 
max_rows,
+                                          bool 
check_partition_function)
  {
    handlerton **engine_array= NULL;
    uint part_count= 0;
    uint i, tot_partitions;
    bool result= TRUE;
    char *same_name;
-  bool part_expression_ok= TRUE;
+  int part_expression_ok= PF_SAFE;
    DBUG_ENTER("partition_info::check_partition_info");

-  if (part_type != HASH_PARTITION || !list_of_part_fields)
-    part_expr->walk(&Item::check_partition_func_processor, 0,
-                    (byte*)(&part_expression_ok));
-  if (is_sub_partitioned() && !list_of_subpart_fields)
-    subpart_expr->walk(&Item::check_partition_func_processor, 0,
-                       (byte*)(&part_expression_ok));
-  if (!part_expression_ok)
+  pf_collation_allowed= PF_SAFE;
+  spf_collation_allowed= PF_SAFE;
+  if (check_partition_function)
    {
-    my_error(ER_PARTITION_FUNCTION_IS_NOT_ALLOWED, MYF(0));
-    goto end;
+    if (part_type != HASH_PARTITION || !list_of_part_fields)
+    {
+      part_expr->walk(&Item::check_partition_func_processor, 0,
+                      (byte*)(&part_expression_ok));
+      pf_collation_allowed= (char)part_expression_ok;
+      part_expression_ok= PF_SAFE;
+      if (is_sub_partitioned() && !list_of_subpart_fields)
+      {
+        subpart_expr->walk(&Item::check_partition_func_processor, 0,
+                           (byte*)(&part_expression_ok));
+      }
+      spf_collation_allowed= (char)part_expression_ok;
+    }
+    else
+      multi_char_collation_allowed= TRUE;
+    if (!pf_collation_allowed ||
+        !spf_collation_allowed)
+    {
+      my_error(ER_PARTITION_FUNCTION_IS_NOT_ALLOWED, MYF(0));
+      goto end;
+    }
    }
    if (unlikely(!is_sub_partitioned() &&
                 !(use_default_subpartitions && 
use_default_no_subpartitions)))
diff -Nur --exclude=RCS --exclude=CVS --exclude=SCCS 
--exclude=BitKeeper --exclude=ChangeSet 
clean-mysql-5.1/sql/partition_info.h 
clean-bug18198/sql/partition_info.h
--- clean-mysql-5.1/sql/partition_info.h	2006-06-15 14:04:29 -04:00
+++ clean-bug18198/sql/partition_info.h	2006-06-23 01:24:21 -04:00
@@ -188,6 +188,8 @@
    bool is_auto_partitioned;
    bool from_openfrm;
    bool has_null_value;
+  char pf_collation_allowed;
+  char spf_collation_allowed;


    partition_info()
@@ -217,7 +219,9 @@
      list_of_part_fields(FALSE), list_of_subpart_fields(FALSE),
      linear_hash_ind(FALSE), fixed(FALSE),
      is_auto_partitioned(FALSE), from_openfrm(FALSE),
-    has_null_value(FALSE)
+    has_null_value(FALSE),
+    pf_collation_allowed(0),
+    spf_collation_allowed(0)
    {
      all_fields_in_PF.clear_all();
      all_fields_in_PPF.clear_all();
@@ -250,7 +254,8 @@
    bool check_range_constants();
    bool check_list_constants();
    bool check_partition_info(THD *thd, handlerton **eng_type,
-                            handler *file, ulonglong max_rows);
+                            handler *file, ulonglong max_rows,
+                            bool check_partition_function);
    void print_no_partition_found(TABLE *table);
  private:
    static int list_part_cmp(const void* a, const void* b);
diff -Nur --exclude=RCS --exclude=CVS --exclude=SCCS 
--exclude=BitKeeper --exclude=ChangeSet 
clean-mysql-5.1/sql/sql_partition.cc 
clean-bug18198/sql/sql_partition.cc
--- clean-mysql-5.1/sql/sql_partition.cc	2006-06-15 14:04:29 -04:00
+++ clean-bug18198/sql/sql_partition.cc	2006-06-23 01:24:21 -04:00
@@ -525,6 +525,7 @@
  }


+
  /*
    Create a field array including all fields of both the partitioning 
and the
    subpartitioning functions.
@@ -549,6 +550,7 @@
                                           partition_info *part_info)
  {
    bool result= FALSE;
+  Field **ptr;
    DBUG_ENTER("create_full_part_field_array");

    if (!part_info->is_sub_partitioned())
@@ -558,7 +560,7 @@
    }
    else
    {
-    Field **ptr, *field, **field_array;
+    Field *field, **field_array;
      uint no_part_fields=0, size_field_array;
      ptr= table->field;
      while ((field= *(ptr++)))
@@ -1369,6 +1371,38 @@
    return part_id;
  }

+
+/*
+  Check that partition function do not contain any forbidden
+  character sets and collations.
+  SYNOPSIS
+    check_part_func_collation()
+    part_info                           Partition info
+    ptr                                 Array of Field pointers
+  RETURN VALUES
+    FALSE                               Success
+    TRUE                                Error
+*/
+
+static bool check_part_func_collation(int collation_allowed,
+                                      Field **ptr)
+{
+  Field *field;
+  while ((field= *(ptr++)))
+  {
+    if (field->result_type() == STRING_RESULT)
+    {
+      CHARSET_INFO *cs= ((Field_str*)field)->charset();
+      if (use_strnxfrm(cs) ||
+          (collation_allowed == PF_SAFE_BINARY_COLLATION &&
+          (!(cs->state & MY_CS_BINSORT))))
+        return TRUE;
+    }
+  }
+  return FALSE;
+}
+
+
  /*
    fix partition functions

@@ -1514,6 +1548,17 @@
        goto end;
      }
    }
+  if (((part_info->pf_collation_allowed != PF_SAFE) &&
+        check_part_func_collation(part_info->pf_collation_allowed,
+                                  part_info->part_field_array)) ||
+      (part_info->is_sub_partitioned() &&
+       part_info->spf_collation_allowed != PF_SAFE &&
+       check_part_func_collation(part_info->spf_collation_allowed,
+                                 part_info->subpart_field_array)))
+  {
+    my_error(ER_PARTITION_FUNCTION_IS_NOT_ALLOWED, MYF(0));
+    goto end;
+  }
    if (unlikely(create_full_part_field_array(table, part_info)))
      goto end;
    if (unlikely(check_primary_key(table)))
@@ -4545,7 +4590,7 @@
          tab_part_info->use_default_no_subpartitions= FALSE;
        }
        if (tab_part_info->check_partition_info(thd, (handlerton**)NULL,
-                                              table->file, ULL(0)))
+                                              table->file, ULL(0), 
FALSE))
        {
          DBUG_RETURN(TRUE);
        }
diff -Nur --exclude=RCS --exclude=CVS --exclude=SCCS 
--exclude=BitKeeper --exclude=ChangeSet 
clean-mysql-5.1/sql/sql_table.cc clean-bug18198/sql/sql_table.cc
--- clean-mysql-5.1/sql/sql_table.cc	2006-06-22 10:12:42 -04:00
+++ clean-bug18198/sql/sql_table.cc	2006-06-23 01:28:51 -04:00
@@ -3186,7 +3186,7 @@
      DBUG_PRINT("info", ("db_type = %d",
                           
ha_legacy_type(part_info->default_engine_type)));
      if (part_info->check_partition_info(thd, &engine_type, file,
-                                        create_info->max_rows))
+                                        create_info->max_rows, TRUE))
        goto err;
      part_info->default_engine_type= engine_type;

diff -Nur --exclude=RCS --exclude=CVS --exclude=SCCS 
--exclude=BitKeeper --exclude=ChangeSet clean-mysql-5.1/sql/sql_yacc.yy 
clean-bug18198/sql/sql_yacc.yy
--- clean-mysql-5.1/sql/sql_yacc.yy	2006-06-19 11:31:11 -04:00
+++ clean-bug18198/sql/sql_yacc.yy	2006-06-23 01:24:21 -04:00
@@ -3616,6 +3616,7 @@
          {
            Item *part_expr= $1;
            bool not_corr_func;
+          bool part_expression_ok= TRUE;
            LEX *lex= Lex;
            THD *thd= YYTHD;
            longlong item_value;
@@ -3633,13 +3634,19 @@
              mem_alloc_error(sizeof(part_elem_value));
              YYABORT;
            }
-
+          part_expr->walk(&Item::check_partition_func_processor, 0,
+                          (byte*)(&part_expression_ok));
+          if (!part_expression_ok)
+          {
+            my_error(ER_PARTITION_FUNCTION_IS_NOT_ALLOWED, MYF(0));
+            YYABORT;
+          }
            if (part_expr->fix_fields(YYTHD, (Item**)0) ||
                ((context->table_list= save_list), FALSE) ||
                (!part_expr->const_item()) ||
                (!lex->safe_to_cache_query))
            {
-            yyerror(ER(ER_NO_CONST_EXPR_IN_RANGE_OR_LIST_ERROR));
+            my_error(ER_NO_CONST_EXPR_IN_RANGE_OR_LIST_ERROR, MYF(0));
              YYABORT;
            }
            thd->where= save_where;

Mikael Ronstrom, Senior Software Architect
MySQL AB, www.mysql.com

Jumpstart your cluster:
http://www.mysql.com/consulting/packaged/cluster.html
My blog:
http://mikaelronstrom.blogspot.com

Thread
bk commit - 5.1 tree (mikael:....) BUG#18198Mikael Ronström27 Jun