List:Commits« Previous MessageNext Message »
From:Mikael Ronström Date:September 26 2006 8:58pm
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-09-14 03:08:15  
-04:00
+++ clean-bug18198/mysql-test/r/partition.result	2006-09-26 16:36:15  
-04:00
@@ -1,9 +1,4 @@
  drop table if exists t1;
-create table t1 (s1 char(2) character set utf8)
-partition by list (case when s1 > 'cz' then 1 else 2 end)
-(partition p1 values in (1),
-partition p2 values in (2));
-drop table t1;
  create table t1 (a int)
  partition by key(a)
  partitions 0.2+e1;
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-21  
18:53:30 -04:00
+++ clean-bug18198/mysql-test/r/partition_error.result	2006-08-02  
08:40:01 -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/r/partition_pruning.result  
clean-bug18198/mysql-test/r/partition_pruning.result
--- clean-mysql-5.1/mysql-test/r/partition_pruning.result	2006-08-02  
06:59:22 -04:00
+++ clean-bug18198/mysql-test/r/partition_pruning.result	2006-08-02  
08:40:01 -04:00
@@ -284,13 +284,6 @@
   
id	select_type	table	partitions	type	possible_keys	key	key_len	ref	rows 
	Extra
  1	SIMPLE	t9	p0,p1	ALL	NULL	NULL	NULL	NULL	2	Using where
  drop table t5,t6,t7,t8,t9;
-create table t1 (a enum('a','b','c','d') default 'a')
-partition by hash (ascii(a)) partitions 2;
-insert into t1 values ('a'),('b'),('c');
-explain partitions select * from t1 where a='b';
-id	select_type	table	partitions	type	possible_keys	key	key_len	ref	 
rows	Extra
-1	SIMPLE	t1	p0,p1	ALL	NULL	NULL	NULL	NULL	3	Using where
-drop table t1;
  create table t1 (
  a1 int not null
  )
@@ -683,8 +676,9 @@
  8	8
  9	9
  drop table t1;
-create table t1 (a char(10)) partition by list(length(a)) (
-partition p1 values in (1),
+create table t1 (a char(10) binary)
+partition by list(length(a))
+(partition p1 values in (1),
  partition p2 values in (2),
  partition p3 values in (3),
  partition p4 values in (4),
diff -Nur --exclude=RCS --exclude=CVS --exclude=SCCS  
--exclude=BitKeeper --exclude=ChangeSet  
clean-mysql-5.1/mysql-test/r/partition_range.result  
clean-bug18198/mysql-test/r/partition_range.result
--- clean-mysql-5.1/mysql-test/r/partition_range.result	2006-09-04  
07:19:52 -04:00
+++ clean-bug18198/mysql-test/r/partition_range.result	2006-09-26  
16:36:15 -04:00
@@ -719,3 +719,45 @@
   
id	select_type	table	partitions	type	possible_keys	key	key_len	ref	rows 
	Extra
   
1	SIMPLE	t1	p407,p408,p409,p507,p508,p509	ALL	NULL	NULL	NULL	NULL	18	 
Using where
  DROP TABLE t1;
+create table t1 (a varchar(20))
+partition by range (crc32(md5(a)))
+(partition p0 values less than (100),
+partition p1 values less than maxvalue);
+insert into t1 values ("12345678901234567890");
+insert into t1 values ("A2345678901234567890");
+insert into t1 values ("B2345678901234567890");
+insert into t1 values ("1234567890123456789");
+insert into t1 values ("1234567890123456");
+select * from t1;
+a
+12345678901234567890
+A2345678901234567890
+B2345678901234567890
+1234567890123456789
+1234567890123456
+explain partitions select * from t1 where a = "12345678901234567890";
+id	select_type	table	partitions	type	possible_keys	key	key_len	ref	 
rows	Extra
+1	SIMPLE	t1	p1	ALL	NULL	NULL	NULL	NULL	5	Using where
+explain partitions select * from t1 where a = "12345678901234567890" OR
+a = "A2345678901234567890" OR
+a = "B2345678901234567890" OR
+a = "C2345678901234567890";
+id	select_type	table	partitions	type	possible_keys	key	key_len	ref	 
rows	Extra
+1	SIMPLE	t1	p1	ALL	NULL	NULL	NULL	NULL	5	Using where
+explain partitions select * from t1 where a = "01234567890123456";
+id	select_type	table	partitions	type	possible_keys	key	key_len	ref	 
rows	Extra
+1	SIMPLE	t1	p1	ALL	NULL	NULL	NULL	NULL	5	Using where
+select * from t1 where a = "01234567890123456";
+a
+select * from t1 where a = "12345678901234567890" OR
+a = "A2345678901234567890" OR
+a = "B2345678901234567890" OR
+a = "C2345678901234567890";
+a
+12345678901234567890
+A2345678901234567890
+B2345678901234567890
+select * from t1 where a = "12345678901234567890";
+a
+12345678901234567890
+drop table t1;
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-09-14 03:08:15  
-04:00
+++ clean-bug18198/mysql-test/t/partition.test	2006-09-26 16:36:15  
-04:00
@@ -14,15 +14,6 @@
  --enable_warnings

  #
-# 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 p1 values in (1),
- partition p2 values in (2));
-drop table t1;
-
-#
  # Bug 15890: Strange number of partitions accepted
  #
  -- error 1064
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-20  
16:38:38 -04:00
+++ clean-bug18198/mysql-test/t/partition_error.test	2006-08-02  
08:40:01 -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/mysql-test/t/partition_pruning.test  
clean-bug18198/mysql-test/t/partition_pruning.test
--- clean-mysql-5.1/mysql-test/t/partition_pruning.test	2006-08-02  
06:59:22 -04:00
+++ clean-bug18198/mysql-test/t/partition_pruning.test	2006-08-02  
08:40:01 -04:00
@@ -238,11 +238,14 @@
  drop table t5,t6,t7,t8,t9;

  # Test the case where we can't create partitioning 'index'
-create table t1 (a enum('a','b','c','d') default 'a')
-  partition by hash (ascii(a)) partitions 2;
-insert into t1 values ('a'),('b'),('c');
-explain partitions select * from t1 where a='b';
-drop table t1;
+#
+# Not supported after bug#18198 is fixed
+#
+#create table t1 (a enum('a','b','c','d') default 'a')
+#  partition by hash (ascii(a)) partitions 2;
+#insert into t1 values ('a'),('b'),('c');
+#explain partitions select * from t1 where a='b';
+#drop table t1;

  #
  # Test cases for bugs found in code review:
@@ -535,8 +538,9 @@
  drop table t1;

  #  part2: bug in pruning code
-create table t1 (a char(10)) partition by list(length(a)) (
-  partition p1 values in (1),
+create table t1 (a char(10) binary)
+partition by list(length(a))
+ (partition p1 values in (1),
    partition p2 values in (2),
    partition p3 values in (3),
    partition p4 values in (4),
diff -Nur --exclude=RCS --exclude=CVS --exclude=SCCS  
--exclude=BitKeeper --exclude=ChangeSet  
clean-mysql-5.1/mysql-test/t/partition_range.test  
clean-bug18198/mysql-test/t/partition_range.test
--- clean-mysql-5.1/mysql-test/t/partition_range.test	2006-09-04  
07:19:52 -04:00
+++ clean-bug18198/mysql-test/t/partition_range.test	2006-09-26  
16:36:15 -04:00
@@ -699,3 +699,32 @@
        (a >= '2005-07-01' AND a <= '2005-09-30');
  DROP TABLE t1;

+#
+# Bug 18198: Try with a couple of cases using VARCHAR fields in
+#            partition function.
+create table t1 (a varchar(20))
+partition by range (crc32(md5(a)))
+(partition p0 values less than (100),
+ partition p1 values less than maxvalue);
+
+insert into t1 values ("12345678901234567890");
+insert into t1 values ("A2345678901234567890");
+insert into t1 values ("B2345678901234567890");
+insert into t1 values ("1234567890123456789");
+insert into t1 values ("1234567890123456");
+select * from t1;
+explain partitions select * from t1 where a = "12345678901234567890";
+explain partitions select * from t1 where a = "12345678901234567890" OR
+                                          a = "A2345678901234567890" OR
+                                          a = "B2345678901234567890" OR
+                                          a = "C2345678901234567890";
+explain partitions select * from t1 where a = "01234567890123456";
+select * from t1 where a = "01234567890123456";
+select * from t1 where a = "12345678901234567890" OR
+                       a = "A2345678901234567890" OR
+                       a = "B2345678901234567890" OR
+                       a = "C2345678901234567890";
+select * from t1 where a = "12345678901234567890";
+
+
+drop table t1;
Binary files clean-mysql-5.1/sql/.sql_select.cc.swp and  
clean-bug18198/sql/.sql_select.cc.swp differ
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-09-19 07:41:22 -04:00
+++ clean-bug18198/sql/item.h	2006-09-26 16:36:15 -04:00
@@ -830,7 +830,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
@@ -846,9 +846,31 @@
      allowed in a partition function then it is very important to  
consider
      whether this should be inherited to the new class. If not the  
function
      below should be defined in the new Item class.
+
+    The general behaviour is that most integer functions are allowed.
+    If the partition function contains any multi-byte collations then
+    the function check_part_func_fields will report an error on the
+    partition function independent of what functions are used. So the
+    only character sets allowed are single character collation and
+    even for those only a limited set of functions are allowed. The
+    problem with multi-byte collations is that almost every string
+    function has the ability to change things such that two strings
+    that are equal will not be equal after manipulated by a string
+    function. E.g. two strings one contains a double s, there is a
+    special german character that is equal to two s. Now assume a
+    string function removes one character at this place, then in
+    one the double s will be removed and in the other there will
+    still be one s remaining and the strings are no longer equal
+    and thus the partition function will not sort equal strings into
+    the same partitions.
+
+    So the check if a partition function is valid is two steps. First
+    check that the field types are valid, next check that the partition
+    function is valid. The current set of partition functions valid
+    assumes that there are no multi-byte collations amongst the  
partition
+    fields.
    */
-  virtual bool check_partition_func_processor(byte *bool_arg)
-  { *(bool *)bool_arg= FALSE; return 0; }
+  virtual bool check_partition_func_processor(byte *bool_arg) { return  
TRUE;}
    virtual bool subst_argument_checker(byte **arg)
    {
      if (*arg)
@@ -1146,7 +1168,6 @@
      Item::maybe_null= TRUE;
    }

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

    enum Type type() const;
@@ -1192,7 +1213,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 FALSE;}
  };

  #define NO_CACHED_FIELD_INDEX ((uint)(-1))
@@ -1350,7 +1371,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 FALSE;}
    void cleanup();
    bool result_as_longlong()
    {
@@ -1399,7 +1420,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 FALSE;}
  };

  class Item_null_result :public Item_null
@@ -1412,8 +1433,7 @@
    {
      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) {return TRUE;}
  };

  /* Item represents one placeholder ('?') of prepared statement */
@@ -1704,8 +1724,7 @@
    {}
    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) {return TRUE;}
  };


@@ -1783,7 +1802,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 FALSE;}
  };


@@ -1798,8 +1817,7 @@
    {}
    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) {return TRUE;}
  };


@@ -1812,8 +1830,7 @@
                                                      &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) {return TRUE;}
  };

  class Item_empty_string :public Item_string
@@ -1836,8 +1853,7 @@
      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) {return TRUE;}
  };


@@ -1861,7 +1877,7 @@
    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 FALSE;}
  };


@@ -2088,8 +2104,7 @@
    }
    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) {return TRUE;}
  };

  #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-09-19 07:41:22 -04:00
+++ clean-bug18198/sql/item_cmpfunc.h	2006-09-26 16:36:15 -04:00
@@ -240,7 +240,7 @@
    }
    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 FALSE;}
    bool subst_argument_checker(byte **arg) { return TRUE; }
  };

@@ -252,7 +252,7 @@
    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 FALSE;}
  };

  class Item_maxmin_subselect;
@@ -469,7 +469,7 @@
    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 FALSE;}
  };


@@ -481,7 +481,7 @@
    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 FALSE;}
  };


@@ -544,7 +544,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 FALSE;}
  };


@@ -585,7 +585,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 FALSE;}
  };


@@ -628,7 +628,7 @@
    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 FALSE;}
  };


@@ -979,7 +979,7 @@
    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 FALSE;}
  };

  /* Functions used by where clause */
@@ -1021,7 +1021,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 FALSE;}
  };

  /* Functions used by HAVING for rewriting IN subquery */
@@ -1043,8 +1043,7 @@
    */
    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) {return TRUE;}
  };


@@ -1067,7 +1066,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 FALSE;}
  };


@@ -1106,7 +1105,7 @@
    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 FALSE;}
  };

  #ifdef USE_REGEX
@@ -1129,7 +1128,7 @@
    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 FALSE;}
  };

  #else
@@ -1186,7 +1185,7 @@
    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 FALSE;}
    bool subst_argument_checker(byte **arg) { return TRUE; }
    Item *compile(Item_analyzer analyzer, byte **arg_p,
                  Item_transformer transformer, byte *arg_t);
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-09-19 07:41:22 -04:00
+++ clean-bug18198/sql/item_func.h	2006-09-26 16:36:15 -04:00
@@ -254,7 +254,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 FALSE;}
  };


@@ -267,7 +267,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 FALSE;}
  };


@@ -318,7 +318,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 FALSE;}
  };


@@ -352,7 +352,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 FALSE;}
  };


@@ -421,7 +421,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 FALSE;}
  };


@@ -494,7 +494,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 FALSE;}
  };


@@ -504,7 +504,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 FALSE;}
  };


@@ -515,7 +515,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 FALSE;}
  };


@@ -525,7 +525,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 FALSE;}
  };


@@ -535,7 +535,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 FALSE;}
  };


@@ -545,7 +545,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 FALSE;}
  };


@@ -555,7 +555,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 FALSE;}
  };


@@ -565,7 +565,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 FALSE;}
  };

  class Item_func_asin :public Item_dec_func
@@ -574,7 +574,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 FALSE;}
  };

  class Item_func_atan :public Item_dec_func
@@ -584,7 +584,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 FALSE;}
  };

  class Item_func_cos :public Item_dec_func
@@ -593,7 +593,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 FALSE;}
  };

  class Item_func_sin :public Item_dec_func
@@ -602,7 +602,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 FALSE;}
  };

  class Item_func_tan :public Item_dec_func
@@ -611,7 +611,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 FALSE;}
  };

  class Item_func_integer :public Item_int_func
@@ -688,7 +688,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 FALSE;}
  };


@@ -703,7 +703,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 FALSE;}
  };


@@ -721,7 +721,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 FALSE;}
  };

  class Item_func_min :public Item_func_min_max
@@ -747,7 +747,7 @@
    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 FALSE;}
  };

  class Item_func_bit_length :public Item_func_length
@@ -767,7 +767,7 @@
    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 FALSE;}
  };

  class Item_func_coercibility :public Item_int_func
@@ -778,7 +778,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
@@ -792,7 +791,7 @@
    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 FALSE;}
  };


@@ -817,7 +816,7 @@
    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 FALSE;}
  };

  class Item_func_ord :public Item_int_func
@@ -827,7 +826,7 @@
    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 FALSE;}
  };

  class Item_func_find_in_set :public Item_int_func
@@ -841,7 +840,7 @@
    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 FALSE;}
  };

  /* Base class for all bit functions: '~', '|', '^', '&', '>>', '<<' */
@@ -853,7 +852,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 FALSE;}
  };

  class Item_func_bit_or :public Item_func_bit
@@ -879,7 +878,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 FALSE;}
  };

  class Item_func_shift_left :public Item_func_bit
@@ -1319,7 +1318,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 FALSE;}
  };


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-09-19 02:38:45 -04:00
+++ clean-bug18198/sql/item_strfunc.h	2006-09-26 16:36:15 -04:00
@@ -50,7 +50,7 @@
    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 FALSE;}
  };


@@ -64,7 +64,6 @@
    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;}
  };

  class Item_func_aes_encrypt :public Item_str_func
@@ -95,7 +94,7 @@
    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 FALSE;}
  };

  class Item_func_concat_ws :public Item_str_func
@@ -117,7 +116,7 @@
    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 FALSE;}
  };


@@ -155,7 +154,7 @@
  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 FALSE;}
  };


@@ -219,7 +218,6 @@
    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;}
  };


@@ -231,7 +229,6 @@
    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;}
  };


@@ -248,7 +245,6 @@
    const char *func_name() const { return "trim"; }
    void print(String *str);
    virtual const char *mode_name() const { return "both"; }
-  bool check_partition_func_processor(byte *bool_arg) { return 0;}
  };


@@ -461,7 +457,7 @@
    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 FALSE;}
  };


@@ -562,7 +558,7 @@
    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 FALSE;}
  };


@@ -575,7 +571,7 @@
    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 FALSE;}
  };


@@ -590,7 +586,7 @@
      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 FALSE;}
  };


@@ -607,7 +603,7 @@
      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 FALSE;}
  };

  class Item_func_unhex :public Item_str_func
@@ -623,7 +619,7 @@
      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 FALSE;}
  };


@@ -647,7 +643,7 @@
    }
    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 FALSE;}
  };


@@ -687,7 +683,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 FALSE;}
  };

  class Item_func_quote :public Item_str_func
@@ -702,7 +698,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 FALSE;}
  };

  class Item_func_conv_charset :public Item_str_func
@@ -746,7 +742,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
@@ -779,7 +774,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
@@ -795,7 +789,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
@@ -806,7 +799,7 @@
    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 FALSE;}
  };

  class Item_func_uncompressed_length : public Item_int_func
@@ -817,7 +810,6 @@
    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;}
  };

  #ifdef HAVE_COMPRESS
@@ -834,7 +826,6 @@
    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;}
  };

  class Item_func_uncompress: public Item_str_func
@@ -845,7 +836,6 @@
    void fix_length_and_dec(){ maybe_null= 1; 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;}
  };

  #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-18 06:56:31 -04:00
+++ clean-bug18198/sql/item_timefunc.h	2006-09-26 16:36:15 -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 FALSE;}
  };


@@ -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 FALSE;}
  };


@@ -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 FALSE;}
  };


@@ -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 FALSE;}
  };


@@ -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 FALSE;}
  };


@@ -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 FALSE;}
  };


@@ -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 FALSE;}
  };


@@ -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 FALSE;}
  };


@@ -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 FALSE;}
  };


@@ -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 FALSE;}
  };


@@ -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 FALSE;}
  };

  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 FALSE;}
  };


@@ -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 FALSE;}
  };


@@ -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 FALSE;}
  };

  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 FALSE;}
  };


@@ -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 FALSE;}
  };


@@ -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 FALSE;}
  };


@@ -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 FALSE;}
  };


@@ -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 FALSE;}
  };


@@ -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 FALSE;}
  };


@@ -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 FALSE;}
  };


@@ -692,7 +692,7 @@
    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 FALSE;}
  };


@@ -729,7 +729,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 FALSE;}
  };


@@ -749,7 +749,7 @@
    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 FALSE;}
  };


@@ -829,7 +829,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 FALSE;}
  };


@@ -852,7 +852,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 FALSE;}
  };

  class Item_func_timediff :public Item_str_func
@@ -892,7 +892,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 FALSE;}
  };

  class Item_func_microsecond :public Item_int_func
@@ -906,7 +906,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 FALSE;}
  };


@@ -924,7 +924,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 FALSE;}
  };


@@ -971,7 +971,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 FALSE;}
  };


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-05-31 13:32:08 -04:00
+++ clean-bug18198/sql/item_xmlfunc.h	2006-09-26 16:36:15 -04:00
@@ -42,7 +42,7 @@
    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 FALSE;}
  };


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-09-19 02:38:45 -04:00
+++ clean-bug18198/sql/partition_info.cc	2006-09-26 16:36:15 -04:00
@@ -695,6 +695,7 @@
      file                A reference to a handler of the table
      info                Create info
      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
@@ -709,26 +710,33 @@
  */

  bool partition_info::check_partition_info(THD *thd, handlerton  
**eng_type,
-                                          handler *file,  
HA_CREATE_INFO *info)
+                                          handler *file,  
HA_CREATE_INFO *info,
+                                          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;
    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)
+  if (check_partition_function)
    {
-    my_error(ER_PARTITION_FUNCTION_IS_NOT_ALLOWED, MYF(0));
-    goto end;
+    int err= 0;
+
+    if (part_type != HASH_PARTITION || !list_of_part_fields)
+    {
+      err= part_expr->walk(&Item::check_partition_func_processor, 0,
+                           NULL);
+      if (!err && is_sub_partitioned() && !list_of_subpart_fields)
+        err= subpart_expr->walk(&Item::check_partition_func_processor,  
0,
+                                NULL);
+    }
+    if (err)
+    {
+      my_error(ER_PARTITION_FUNCTION_IS_NOT_ALLOWED, MYF(0));
+      goto end;
+    }
    }
    if (unlikely(!is_sub_partitioned() &&
                 !(use_default_subpartitions &&  
use_default_no_subpartitions)))
@@ -851,5 +859,171 @@
    my_error(ER_NO_PARTITION_FOR_GIVEN_VALUE, MYF(0), buf_ptr);
    dbug_tmp_restore_column_map(table->read_set, old_map);
  }
+/*
+  Set up buffers and arrays for fields requiring preparation
+  SYNOPSIS
+    set_up_charset_field_preps()
+    part_info                        Partition info object
+  RETURN VALUES
+    TRUE                             Memory Allocation error
+    FALSE                            Success
+  DESCRIPTION
+    Set up arrays and buffers for fields that require special care for
+    calculation of partition id. This is used for string fields with
+    variable length or string fields with fixed length that isn't using
+    the binary collation.
+*/

-#endif /* WITH_PARTITION_STORAGE_ENGINE */
+bool partition_info::set_up_charset_field_preps()
+{
+  Field *field, **ptr;
+  char *field_buf;
+  char **char_ptrs;
+  unsigned i;
+  bool found;
+  size_t size;
+  uint tot_fields= 0;
+  uint tot_part_fields= 0;
+  uint tot_subpart_fields= 0;
+  DBUG_ENTER("set_up_charset_field_preps");
+
+  if (!(part_type == HASH_PARTITION &&
+        list_of_part_fields) &&
+        check_part_func_fields(part_field_array, FALSE))
+  {
+    ptr= part_field_array;
+    /* Set up arrays and buffers for those fields */
+    i= 0;
+    while ((field= *(ptr++)))
+    {
+      if (field_is_partition_charset(field))
+      {
+        tot_part_fields++;
+        tot_fields++;
+      }
+    }
+    size= tot_part_fields * sizeof(char*);
+    if (!(char_ptrs= (char**)sql_calloc(size)))
+      goto error;
+    part_field_buffers= char_ptrs;
+    if (!(char_ptrs= (char**)sql_calloc(size)))
+      goto error;
+    restore_part_field_ptrs= char_ptrs;
+    size= (tot_part_fields + 1) * sizeof(Field*);
+    if (!(char_ptrs= (char**)sql_alloc(size)))
+      goto error;
+    part_charset_field_array= (Field**)char_ptrs;
+    ptr= part_field_array;
+    i= 0;
+    while ((field= *(ptr++)))
+    {
+      if (field_is_partition_charset(field))
+      {
+        CHARSET_INFO *cs= ((Field_str*)field)->charset();
+        size= field->pack_length();
+        if (!(field_buf= sql_calloc(size)))
+          goto error;
+        part_charset_field_array[i]= field;
+        part_field_buffers[i++]= field_buf;
+      }
+    }
+    part_charset_field_array[i]= NULL;
+  }
+  if (is_sub_partitioned() && list_of_subpart_fields &&
+      check_part_func_fields(subpart_field_array, FALSE))
+  {
+    /* Set up arrays and buffers for those fields */
+    ptr= subpart_field_array;
+    while ((field= *(ptr++)))
+    {
+      if (field_is_partition_charset(field))
+        tot_subpart_fields++;
+    }
+    size= tot_subpart_fields * sizeof(char*);
+    if (!(char_ptrs= (char**)sql_calloc(size)))
+      goto error;
+    subpart_field_buffers= char_ptrs;
+    if (!(char_ptrs= (char**)sql_calloc(size)))
+      goto error;
+    restore_subpart_field_ptrs= char_ptrs;
+    size= (tot_subpart_fields + 1) * sizeof(Field*);
+    if (!(char_ptrs= (char**)sql_alloc(size)))
+      goto error;
+    subpart_charset_field_array= (Field**)char_ptrs;
+    i= 0;
+    while ((field= *(ptr++)))
+    {
+      unsigned j= 0;
+      Field *part_field;
+      CHARSET_INFO *cs;
+
+      if (!field_is_partition_charset(field))
+        continue;
+      cs= ((Field_str*)field)->charset();
+      size= field->pack_length();
+      found= FALSE;
+      for (j= 0; j < tot_part_fields; j++)
+      {
+        if (field == part_charset_field_array[i])
+          found= TRUE;
+      }
+      if (!found)
+      {
+        tot_fields++;
+        if (!(field_buf= sql_calloc(size)))
+          goto error;
+      }
+      subpart_field_buffers[i++]= field_buf;
+    }
+    if (!(char_ptrs= (char**)sql_calloc(size)))
+      goto error;
+    restore_subpart_field_ptrs= char_ptrs;
+  }
+  if (tot_fields)
+  {
+    Field *part_field, *subpart_field;
+    uint j,k,l;
+
+    size= tot_fields*sizeof(char**);
+    if (!(char_ptrs= (char**)sql_calloc(size)))
+      goto error;
+    full_part_field_buffers= char_ptrs;
+    if (!(char_ptrs= (char**)sql_calloc(size)))
+      goto error;
+    restore_full_part_field_ptrs= char_ptrs;
+    size= (tot_fields + 1) * sizeof(char**);
+    if (!(char_ptrs= (char**)sql_calloc(size)))
+      goto error;
+    full_part_charset_field_array= (Field**)char_ptrs;
+    for (i= 0; i < tot_part_fields; i++)
+    {
+      full_part_charset_field_array[i]= part_charset_field_array[i];
+      full_part_field_buffers[i]= part_field_buffers[i];
+    }
+    k= tot_part_fields;
+    l= 0;
+    for (i= 0; i < tot_subpart_fields; i++)
+    {
+      field= subpart_charset_field_array[i];
+      found= FALSE;
+      for (j= 0; j < tot_part_fields; j++)
+      {
+        if (field == part_charset_field_array[i])
+          found= TRUE;
+      }
+      if (!found)
+      {
+        full_part_charset_field_array[l]=  
subpart_charset_field_array[k];
+        full_part_field_buffers[l]= subpart_field_buffers[k];
+        k++; l++;
+      }
+    }
+    full_part_charset_field_array[tot_fields]= NULL;
+  }
+  DBUG_RETURN(FALSE);
+error:
+  mem_alloc_error(size);
+  DBUG_RETURN(TRUE);
+}
+#endif
+                                                                        
                                                                         
/* WITH_PARTITION_STORAGE_ENGINE */
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-27 16:19:18 -04:00
+++ clean-bug18198/sql/partition_info.h	2006-09-26 16:36:15 -04:00
@@ -60,17 +60,40 @@
      same in all subpartitions
    */
    get_subpart_id_func get_subpartition_id;
-
+
+  /*
+    When we have various string fields we might need some preparation
+    before and clean-up after calling the get_part_id_func's. We need
+    one such method for get_partition_id and one for
+    get_part_partition_id and one for get_subpartition_id.
+  */
+  get_part_id_func get_partition_id_charset;
+  get_part_id_func get_part_partition_id_charset;
+  get_subpart_id_func get_subpartition_id_charset;
+
    /* NULL-terminated array of fields used in partitioned expression */
    Field **part_field_array;
-  /* NULL-terminated array of fields used in subpartitioned expression  
*/
    Field **subpart_field_array;
-
+  Field **part_charset_field_array;
+  Field **subpart_charset_field_array;
    /*
      Array of all fields used in partition and subpartition expression,
      without duplicates, NULL-terminated.
    */
    Field **full_part_field_array;
+  Field **full_part_charset_field_array;
+
+  /*
+    When we have a field that requires transformation before calling  
the
+    partition functions we must allocate field buffers for the field of
+    the fields in the partition function.
+  */
+  char **part_field_buffers;
+  char **subpart_field_buffers;
+  char **full_part_field_buffers;
+  char **restore_part_field_ptrs;
+  char **restore_subpart_field_ptrs;
+  char **restore_full_part_field_ptrs;

    Item *part_expr;
    Item *subpart_expr;
@@ -194,7 +217,14 @@
    : get_partition_id(NULL), get_part_partition_id(NULL),
      get_subpartition_id(NULL),
      part_field_array(NULL), subpart_field_array(NULL),
+    part_charset_field_array(NULL),
+    subpart_charset_field_array(NULL),
      full_part_field_array(NULL),
+    full_part_charset_field_array(NULL),
+    part_field_buffers(NULL), subpart_field_buffers(NULL),
+    full_part_field_buffers(NULL),
+    restore_part_field_ptrs(NULL), restore_subpart_field_ptrs(NULL),
+    restore_full_part_field_ptrs(NULL),
      part_expr(NULL), subpart_expr(NULL), item_free_list(NULL),
      first_log_entry(NULL), exec_log_entry(NULL), frm_log_entry(NULL),
      list_array(NULL),
@@ -250,8 +280,10 @@
    bool check_range_constants();
    bool check_list_constants();
    bool check_partition_info(THD *thd, handlerton **eng_type,
-                            handler *file, HA_CREATE_INFO *info);
+                            handler *file, HA_CREATE_INFO *info,
+                            bool check_partition_function);
    void print_no_partition_found(TABLE *table);
+  bool set_up_charset_field_preps();
  private:
    static int list_part_cmp(const void* a, const void* b);
    static int list_part_cmp_unsigned(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-09-19 02:38:45 -04:00
+++ clean-bug18198/sql/sql_partition.cc	2006-09-26 16:36:15 -04:00
@@ -62,48 +62,64 @@
  static const char *begin_paren_str= "(";
  static const char *comma_str= ",";

+static int get_part_id_charset_func_all(partition_info *part_info,
+                                        uint32 *part_id,
+                                        longlong *func_value);
+static int get_part_id_charset_func_part(partition_info *part_info,
+                                         uint32 *part_id,
+                                         longlong *func_value);
+static int get_part_id_charset_func_subpart(partition_info *part_info,
+                                            uint32 *part_id,
+                                            longlong *func_value);
+static int get_part_part_id_charset_func(partition_info *part_info,
+                                         uint32 *part_id,
+                                         longlong *func_value);
+static uint32 get_subpart_id_charset_func(partition_info *part_info);
  int get_partition_id_list(partition_info *part_info,
+                          uint32 *part_id,
+                          longlong *func_value);
+int get_partition_id_list(partition_info *part_info,
+                          uint32 *part_id,
+                          longlong *func_value);
+int get_partition_id_range(partition_info *part_info,
                             uint32 *part_id,
                             longlong *func_value);
-int get_partition_id_range(partition_info *part_info,
-                            uint32 *part_id,
-                            longlong *func_value);
  int get_partition_id_hash_nosub(partition_info *part_info,
-                                 uint32 *part_id,
-                                 longlong *func_value);
-int get_partition_id_key_nosub(partition_info *part_info,
                                  uint32 *part_id,
                                  longlong *func_value);
+int get_partition_id_key_nosub(partition_info *part_info,
+                               uint32 *part_id,
+                               longlong *func_value);
  int get_partition_id_linear_hash_nosub(partition_info *part_info,
-                                        uint32 *part_id,
-                                        longlong *func_value);
-int get_partition_id_linear_key_nosub(partition_info *part_info,
                                         uint32 *part_id,
                                         longlong *func_value);
+int get_partition_id_linear_key_nosub(partition_info *part_info,
+                                      uint32 *part_id,
+                                      longlong *func_value);
  int get_partition_id_range_sub_hash(partition_info *part_info,
-                                     uint32 *part_id,
-                                     longlong *func_value);
-int get_partition_id_range_sub_key(partition_info *part_info,
                                      uint32 *part_id,
                                      longlong *func_value);
+int get_partition_id_range_sub_key(partition_info *part_info,
+                                   uint32 *part_id,
+                                   longlong *func_value);
  int get_partition_id_range_sub_linear_hash(partition_info *part_info,
-                                            uint32 *part_id,
-                                            longlong *func_value);
-int get_partition_id_range_sub_linear_key(partition_info *part_info,
                                             uint32 *part_id,
                                             longlong *func_value);
+int get_partition_id_range_sub_linear_key(partition_info *part_info,
+                                          uint32 *part_id,
+                                          longlong *func_value);
  int get_partition_id_list_sub_hash(partition_info *part_info,
-                                    uint32 *part_id,
-                                    longlong *func_value);
-int get_partition_id_list_sub_key(partition_info *part_info,
                                     uint32 *part_id,
                                     longlong *func_value);
+int get_partition_id_list_sub_key(partition_info *part_info,
+                                  uint32 *part_id,
+                                  longlong *func_value);
  int get_partition_id_list_sub_linear_hash(partition_info *part_info,
-                                           uint32 *part_id,
-                                           longlong *func_value);
-int get_partition_id_list_sub_linear_key(partition_info *part_info,
                                            uint32 *part_id,
                                            longlong *func_value);
+int get_partition_id_list_sub_linear_key(partition_info *part_info,
+                                         uint32 *part_id,
+                                         longlong *func_value);
  uint32 get_partition_id_hash_sub(partition_info *part_info);
  uint32 get_partition_id_key_sub(partition_info *part_info);
  uint32 get_partition_id_linear_hash_sub(partition_info *part_info);
@@ -525,6 +541,7 @@
  }


+
  /*
    Create a field array including all fields of both the partitioning  
and the
    subpartitioning functions.
@@ -549,6 +566,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 +576,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++)))
@@ -1328,6 +1346,33 @@
        }
      }
    }
+  if (part_info->full_part_charset_field_array)
+  {
+    DBUG_ASSERT(part_info->get_partition_id);
+    part_info->get_partition_id_charset= part_info->get_partition_id;
+    if (part_info->part_charset_field_array &&
+        part_info->subpart_charset_field_array)
+      part_info->get_partition_id= get_part_id_charset_func_all;
+    else if (part_info->part_charset_field_array)
+      part_info->get_partition_id= get_part_id_charset_func_part;
+    else
+      part_info->get_partition_id= get_part_id_charset_func_subpart;
+  }
+  if (part_info->part_charset_field_array &&
+      part_info->is_sub_partitioned())
+  {
+    DBUG_ASSERT(part_info->get_part_partition_id);
+    part_info->get_part_partition_id_charset=
+          part_info->get_part_partition_id;
+    part_info->get_part_partition_id= get_part_part_id_charset_func;
+  }
+  if (part_info->subpart_charset_field_array)
+  {
+    DBUG_ASSERT(part_info->get_subpartition_id);
+    part_info->get_subpartition_id_charset=
+          part_info->get_subpartition_id;
+    part_info->get_subpartition_id= get_subpart_id_charset_func;
+  }
    DBUG_VOID_RETURN;
  }

@@ -1388,6 +1433,78 @@
    return part_id;
  }

+
+/*
+  Check if a particular field is in need of character set
+  handling for partition functions.
+  SYNOPSIS
+    field_is_partition_charset()
+    field                         The field to check
+  RETURN VALUES
+    FALSE                        Not in need of character set handling
+    TRUE                         In need of character set handling
+*/
+
+bool field_is_partition_charset(Field *field)
+{
+  if (!field->type() == MYSQL_TYPE_STRING &&
+      !field->type() == MYSQL_TYPE_VARCHAR)
+    return FALSE;
+  {
+    CHARSET_INFO *cs= ((Field_str*)field)->charset();
+    if (!field->type() == MYSQL_TYPE_STRING ||
+        !(cs->state & MY_CS_BINSORT))
+      return TRUE;
+    return FALSE;
+  }
+}
+
+
+/*
+  Check that partition function do not contain any forbidden
+  character sets and collations.
+  SYNOPSIS
+    check_part_func_fields()
+    ptr                                 Array of Field pointers
+    ok_with_charsets                    Will we report allowed charset
+                                        fields as ok
+  RETURN VALUES
+    FALSE                               Success
+    TRUE                                Error
+  DESCRIPTION
+    We will check in this routine that the fields of the partition  
functions
+    do not contain unallowed parts. It can also be used to check if  
there
+    are fields that require special care by calling my_strnxfrm before
+    calling the functions to calculate partition id.
+*/
+
+bool check_part_func_fields(Field **ptr, bool ok_with_charsets)
+{
+  Field *field;
+  DBUG_ENTER("check_part_func_field");
+
+  while ((field= *(ptr++)))
+  {
+    /*
+      For CHAR/VARCHAR fields we need to take special precautions.
+      Binary collation with CHAR is automatically supported. Other
+      types need some kind of standardisation function handling
+    */
+    if (field_is_partition_charset(field))
+    {
+      CHARSET_INFO *cs= ((Field_str*)field)->charset();
+      if (!ok_with_charsets ||
+          cs->mbmaxlen > 1 ||
+          cs->strxfrm_multiply > 1)
+      {
+        DBUG_RETURN(TRUE);
+      }
+    }
+  }
+  DBUG_RETURN(FALSE);
+}
+
+
  /*
    fix partition functions

@@ -1531,6 +1648,16 @@
        goto end;
      }
    }
+  if (((part_info->part_type != HASH_PARTITION ||
+      part_info->list_of_part_fields == FALSE) &&
+      check_part_func_fields(part_info->part_field_array, TRUE)) ||
+      (part_info->list_of_part_fields == FALSE &&
+       part_info->is_sub_partitioned() &&
+       check_part_func_fields(part_info->subpart_field_array, TRUE)))
+  {
+    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)))
@@ -1541,6 +1668,11 @@
      goto end;
    if (unlikely(set_up_partition_bitmap(thd, part_info)))
      goto end;
+  if (unlikely(part_info->set_up_charset_field_preps()))
+  {
+    my_error(ER_PARTITION_FUNCTION_IS_NOT_ALLOWED, MYF(0));
+    goto end;
+  }
    check_range_capable_PF(table);
    set_up_partition_key_maps(table, part_info);
    set_up_partition_func_pointers(part_info);
@@ -2257,6 +2389,83 @@
  }

  /*
+  Copy to field buffers and set up field pointers
+  SYNOPSIS
+    copy_to_part_field_buffers()
+    ptr                          Array of fields to copy
+  RETURN VALUES
+    NONE
+  DESCRIPTION
+    This routine is used to take the data from field pointer, convert
+    it to a standard format and store this format in a field buffer
+    allocated for this purpose. Next the field pointers are moved to
+    point to the field buffers. There is a separate to restore the
+    field pointers after this call.
+*/
+
+static void copy_to_part_field_buffers(Field **ptr,
+                                       char **field_bufs,
+                                       char **restore_ptr)
+{
+  Field *field;
+  while ((field= *(ptr++)))
+  {
+    *restore_ptr= field->ptr;
+    restore_ptr++;
+    if (!field->maybe_null() || !field->is_null())
+    {
+      CHARSET_INFO *cs= ((Field_str*)field)->charset();
+      uint len= field->pack_length();
+      char *field_buf= *field_bufs;
+      /*
+         We only use the field buffer for VARCHAR and CHAR strings
+         which isn't of a binary collation. We also only use the
+         field buffer for fields which are not currently NULL.
+         The field buffer will store a normalised string. We use
+         the strnxfrm method to normalise the string.
+       */
+      if (field->type() == MYSQL_TYPE_VARCHAR)
+      {
+        uint len_bytes= ((Field_varstring*)field)->length_bytes;
+        my_strnxfrm(cs, (uchar*)(field_buf + len_bytes), (len -  
len_bytes),
+                    (uchar*)(field->ptr + len_bytes),  
field->field_length);
+        if (len_bytes == 1)
+          *field_buf= (uchar)field->field_length;
+        else
+          int2store(field_buf, field->field_length);
+      }
+      else
+      {
+        my_strnxfrm(cs, (uchar*)field_buf, len,
+                    (uchar*)field->ptr, field->field_length);
+      }
+      field->ptr= field_buf;
+    }
+    field_bufs++;
+  }
+  return;
+}
+
+/*
+  Restore field pointers
+  SYNOPSIS
+    restore_part_field_pointers()
+    ptr                            Array of fields to restore
+  RETURN VALUES
+    NONE
+*/
+
+static void restore_part_field_pointers(Field **ptr, char  
**restore_ptr)
+{
+  Field *field;
+  while ((field= *(ptr++)))
+  {
+    field->ptr= *restore_ptr;
+    restore_ptr++;
+  }
+  return;
+}
+/*
    This function is used to calculate the partition id where all  
partition
    fields have been prepared to point to a record where the partition  
field
    values are bound.
@@ -2266,6 +2475,7 @@
      part_info           A reference to the partition_info struct where  
all the
                          desired information is given
      out:part_id         The partition id is returned through this  
pointer
+    out: func_value     Value of partition function (longlong)

    RETURN VALUE
      part_id                     Partition id of partition that would  
contain
@@ -2309,6 +2519,7 @@
      part_info           A reference to the partition_info struct where  
all the
                          desired information is given
      out:part_id         The partition id is returned through this  
pointer
+    out: func_value     The value calculated by partition function

    RETURN VALUE
      part_id                     Partition id of partition that would  
contain
@@ -2330,6 +2541,79 @@
      get_partition_id_linear_key_nosub
  */

+static int get_part_id_charset_func_subpart(partition_info *part_info,
+                                            uint32 *part_id,
+                                            longlong *func_value)
+{
+  int res;
+  copy_to_part_field_buffers(part_info->subpart_charset_field_array,
+                             part_info->subpart_field_buffers,
+                             part_info->restore_subpart_field_ptrs);
+  res= part_info->get_partition_id_charset(part_info, part_id,  
func_value);
+  restore_part_field_pointers(part_info->subpart_charset_field_array,
+                              part_info->restore_subpart_field_ptrs);
+  return res;
+}
+
+
+static int get_part_id_charset_func_part(partition_info *part_info,
+                                         uint32 *part_id,
+                                         longlong *func_value)
+{
+  int res;
+  copy_to_part_field_buffers(part_info->part_charset_field_array,
+                             part_info->part_field_buffers,
+                             part_info->restore_part_field_ptrs);
+  res= part_info->get_partition_id_charset(part_info, part_id,  
func_value);
+  restore_part_field_pointers(part_info->part_charset_field_array,
+                              part_info->restore_part_field_ptrs);
+  return res;
+}
+
+
+static int get_part_id_charset_func_all(partition_info *part_info,
+                                        uint32 *part_id,
+                                        longlong *func_value)
+{
+  int res;
+  copy_to_part_field_buffers(part_info->full_part_field_array,
+                             part_info->full_part_field_buffers,
+                             part_info->restore_full_part_field_ptrs);
+  res= part_info->get_partition_id_charset(part_info, part_id,  
func_value);
+  restore_part_field_pointers(part_info->full_part_field_array,
+                              part_info->restore_full_part_field_ptrs);
+  return res;
+}
+
+
+static int get_part_part_id_charset_func(partition_info *part_info,
+                                         uint32 *part_id,
+                                         longlong *func_value)
+{
+  int res;
+  copy_to_part_field_buffers(part_info->part_charset_field_array,
+                             part_info->part_field_buffers,
+                             part_info->restore_part_field_ptrs);
+  res= part_info->get_part_partition_id_charset(part_info,
+                                                part_id, func_value);
+  restore_part_field_pointers(part_info->part_charset_field_array,
+                              part_info->restore_part_field_ptrs);
+  return res;
+}
+
+
+static uint32 get_subpart_id_charset_func(partition_info *part_info)
+{
+  int res;
+  copy_to_part_field_buffers(part_info->subpart_charset_field_array,
+                             part_info->subpart_field_buffers,
+                             part_info->restore_subpart_field_ptrs);
+  res= part_info->get_subpartition_id_charset(part_info);
+  restore_part_field_pointers(part_info->subpart_charset_field_array,
+                              part_info->restore_subpart_field_ptrs);
+  return res;
+}
+

  int get_partition_id_list(partition_info *part_info,
                            uint32 *part_id,
@@ -2418,6 +2702,21 @@
      The edge of corresponding sub-array of part_info->list_array
  */

+uint32 get_list_array_idx_for_endpoint_charset(partition_info  
*part_info,
+                                               bool left_endpoint,
+                                               bool include_endpoint)
+{
+  uint32 res;
+  copy_to_part_field_buffers(part_info->part_field_array,
+                             part_info->part_field_buffers,
+                             part_info->restore_part_field_ptrs);
+  res= get_list_array_idx_for_endpoint(part_info, left_endpoint,
+                                       include_endpoint);
+  restore_part_field_pointers(part_info->part_field_array,
+                              part_info->restore_part_field_ptrs);
+  return res;
+}
+
  uint32 get_list_array_idx_for_endpoint(partition_info *part_info,
                                         bool left_endpoint,
                                         bool include_endpoint)
@@ -2547,6 +2846,22 @@
      The edge of corresponding part_info->range_int_array sub-array.
  */

+static uint32
+get_partition_id_range_for_endpoint_charset(partition_info *part_info,
+                                            bool left_endpoint,
+                                            bool include_endpoint)
+{
+  uint32 res;
+  copy_to_part_field_buffers(part_info->part_field_array,
+                             part_info->part_field_buffers,
+                             part_info->restore_part_field_ptrs);
+  res= get_partition_id_range_for_endpoint(part_info, left_endpoint,
+                                           include_endpoint);
+  restore_part_field_pointers(part_info->part_field_array,
+                              part_info->restore_part_field_ptrs);
+  return res;
+}
+
  uint32 get_partition_id_range_for_endpoint(partition_info *part_info,
                                             bool left_endpoint,
                                             bool include_endpoint)
@@ -4559,7 +4874,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);
        }
@@ -6386,13 +6701,20 @@

    if (part_info->part_type == RANGE_PARTITION)
    {
-    get_endpoint=        get_partition_id_range_for_endpoint;
+    if (part_info->part_charset_field_array)
+      get_endpoint=        get_partition_id_range_for_endpoint_charset;
+    else
+      get_endpoint=        get_partition_id_range_for_endpoint;
      max_endpoint_val=    part_info->no_parts;
      part_iter->get_next= get_next_partition_id_range;
    }
    else if (part_info->part_type == LIST_PARTITION)
    {
-    get_endpoint=        get_list_array_idx_for_endpoint;
+
+    if (part_info->part_charset_field_array)
+      get_endpoint=        get_list_array_idx_for_endpoint_charset;
+    else
+      get_endpoint=        get_list_array_idx_for_endpoint;
      max_endpoint_val=    part_info->no_list_values;
      part_iter->get_next= get_next_partition_id_list;
      part_iter->part_info= part_info;
diff -Nur --exclude=RCS --exclude=CVS --exclude=SCCS  
--exclude=BitKeeper --exclude=ChangeSet  
clean-mysql-5.1/sql/sql_partition.h clean-bug18198/sql/sql_partition.h
--- clean-mysql-5.1/sql/sql_partition.h	2006-06-27 16:19:18 -04:00
+++ clean-bug18198/sql/sql_partition.h	2006-09-26 16:36:15 -04:00
@@ -93,6 +93,9 @@
  bool fix_fields_part_func(THD *thd, Item* func_expr, TABLE *table,
                            bool is_sub_part, bool is_field_to_be_setup);

+bool check_part_func_fields(Field **ptr, bool ok_with_charsets);
+bool field_is_partition_charset(Field *field);
+
  /*
    A "Get next" function for partition iterator.

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-09-19 02:38:45 -04:00
+++ clean-bug18198/sql/sql_table.cc	2006-09-26 16:36:16 -04:00
@@ -3303,7 +3303,8 @@
      }
      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))
+    if (part_info->check_partition_info(thd, &engine_type, file,
+                                        create_info, 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-09-26 01:35:34 -04:00
+++ clean-bug18198/sql/sql_yacc.yy	2006-09-26 16:36:16 -04:00
@@ -3600,6 +3600,7 @@
          {
            Item *part_expr= $1;
            bool not_corr_func;
+          int part_expression_ok= 1;
            LEX *lex= Lex;
            THD *thd= YYTHD;
            longlong item_value;
@@ -3617,13 +3618,18 @@
              mem_alloc_error(sizeof(part_elem_value));
              YYABORT;
            }
-
+          if (part_expr->walk(&Item::check_partition_func_processor, 0,
+                              NULL))
+          {
+            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öm26 Sep