Commit bc37b287 authored by unknown's avatar unknown
Browse files

Merge mronstrom@bk-internal.mysql.com:/home/bk/mysql-5.1-new

into  c-3d08e253.1238-1-64736c10.cust.bredbandsbolaget.se:/home/pappa/bug18198


sql/item_cmpfunc.h:
  Auto merged
sql/item_func.h:
  Auto merged
sql/item_strfunc.h:
  Auto merged
sql/item_timefunc.h:
  Auto merged
sql/partition_info.cc:
  Auto merged
sql/item.h:
  manual merge
sql/share/errmsg.txt:
  manual merge
parents c402b006 a706b2a3
Loading
Loading
Loading
Loading
+23 −0
Original line number Diff line number Diff line
@@ -554,3 +554,26 @@ PARTITION BY RANGE (a) (PARTITION p1 VALUES LESS THAN(5));
insert into t1 values (10);
ERROR HY000: Table has no partition for value 10
drop table t1;
create table t1 (v varchar(12))
partition by range (ascii(v))
(partition p0 values less than (10));
drop table t1;
create table t1 (a int)
partition by hash (rand(a));
ERROR 42000: Constant/Random expression in (sub)partitioning function is not allowed near ')' at line 2
create table t1 (a int)
partition by hash(CURTIME() + a);
ERROR 42000: Constant/Random expression in (sub)partitioning function is not allowed near ')' at line 2
create table t1 (a int)
partition by hash (NOW()+a);
ERROR 42000: Constant/Random expression in (sub)partitioning function is not allowed near ')' at line 2
create table t1 (a int)
partition by hash (extract(hour from convert_tz(a, '+00:00', '+00:00')));
ERROR HY000: This partition function is not allowed
create table t1 (a int)
partition by range (a + (select count(*) from t1))
(partition p1 values less than (1));
ERROR HY000: This partition function is not allowed
create table t1 (a char(10))
partition by hash (extractvalue(a,'a'));
ERROR HY000: The PARTITION function returns the wrong type
+28 −0
Original line number Diff line number Diff line
@@ -747,3 +747,31 @@ CREATE TABLE t1(a int)
--error ER_NO_PARTITION_FOR_GIVEN_VALUE
insert into t1 values (10);
drop table t1;

#
# Bug 18198 Partitions: Verify that erroneus partition functions doesn't work
#
create table t1 (v varchar(12))
partition by range (ascii(v))
(partition p0 values less than (10));
drop table t1;

-- error 1064
create table t1 (a int)
partition by hash (rand(a));
-- error 1064
create table t1 (a int)
partition by hash(CURTIME() + a);
-- error 1064
create table t1 (a int)
partition by hash (NOW()+a);
-- error ER_PARTITION_FUNCTION_IS_NOT_ALLOWED
create table t1 (a int)
partition by hash (extract(hour from convert_tz(a, '+00:00', '+00:00')));
-- error ER_PARTITION_FUNCTION_IS_NOT_ALLOWED
create table t1 (a int)
partition by range (a + (select count(*) from t1))
(partition p1 values less than (1));
-- error ER_PARTITION_FUNC_NOT_ALLOWED_ERROR
create table t1 (a char(10))
partition by hash (extractvalue(a,'a'));
+41 −0
Original line number Diff line number Diff line
@@ -783,6 +783,29 @@ class Item {
  virtual bool find_item_in_field_list_processor(byte *arg) { return 0; }
  virtual bool change_context_processor(byte *context) { return 0; }
  virtual bool reset_query_id_processor(byte *query_id) { return 0; }
  /*
    Check if a partition function is allowed
    SYNOPSIS
      check_partition_func_processor()
      bool_arg                        Return argument
    RETURN VALUE
      0
    DESCRIPTION
    check_partition_func_processor is used to check if a partition function
    uses an allowed function. The default is that an item is not allowed
    in a partition function. However all mathematical functions, string
    manipulation functions, date functions are allowed. Allowed functions
    can never depend on server version, they cannot depend on anything
    related to the environment. They can also only depend on a set of
    fields in the table itself. They cannot depend on other tables and
    cannot contain any queries and cannot contain udf's or similar.
    If a new Item class is defined and it inherits from a class that is
    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.
  */
  virtual bool check_partition_func_processor(byte *bool_arg)
  { *(bool *)bool_arg= FALSE; return 0; }

  virtual Item *equal_fields_propagator(byte * arg) { return this; }
  virtual Item *set_no_const_sub(byte *arg) { return this; }
@@ -1073,6 +1096,7 @@ class Item_name_const : public Item
    Item::maybe_null= TRUE;
  }

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

  enum Type type() const;
@@ -1119,6 +1143,7 @@ class Item_num: public Item
  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;}
};

#define NO_CACHED_FIELD_INDEX ((uint)(-1))
@@ -1260,6 +1285,7 @@ class Item_field :public Item_ident
      result_field->query_id= field->query_id;
    return 0;
  }
  bool check_partition_func_processor(byte *bool_arg) { return 0; }
  void cleanup();
  Item_equal *find_item_equal(COND_EQUAL *cond_equal);
  Item *equal_fields_propagator(byte *arg);
@@ -1303,6 +1329,7 @@ class Item_null :public Item
  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;}
};

class Item_null_result :public Item_null
@@ -1315,6 +1342,8 @@ class Item_null_result :public Item_null
  {
    save_in_field(result_field, no_conversions);
  }
  bool check_partition_func_processor(byte *bool_arg)
  { *(bool *)bool_arg= FALSE; return 0; }
};  

/* Item represents one placeholder ('?') of prepared statement */
@@ -1605,6 +1634,8 @@ class Item_static_float_func :public Item_float
  {}
  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; }
};


@@ -1682,6 +1713,7 @@ class Item_string :public Item
  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;}
};


@@ -1696,6 +1728,8 @@ class Item_static_string_func :public Item_string
  {}
  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; }
};


@@ -1708,6 +1742,8 @@ class Item_datetime :public Item_string
                                                    &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; }
};

class Item_empty_string :public Item_string
@@ -1730,6 +1766,8 @@ class Item_return_int :public Item_int
    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; }
};


@@ -1753,6 +1791,7 @@ class Item_hex_string: public Item
  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;}
};


@@ -1975,6 +2014,8 @@ class Item_int_with_ref :public Item_int
  }
  Item *new_item();
  virtual Item *real_item() { return ref; }
  bool check_partition_func_processor(byte *bool_arg)
  { *(bool *)bool_arg= FALSE; return 0; }
};

#ifdef MYSQL_SERVER
+15 −0
Original line number Diff line number Diff line
@@ -239,6 +239,7 @@ class Item_bool_rowready_func2 :public Item_bool_func2
  }
  Item *neg_transformer(THD *thd);
  virtual Item *negated_item();
  bool check_partition_func_processor(byte *bool_arg) { return 0;}
};

class Item_func_not :public Item_bool_func
@@ -249,6 +250,7 @@ class Item_func_not :public Item_bool_func
  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;}
};

class Item_maxmin_subselect;
@@ -463,6 +465,7 @@ class Item_func_between :public Item_func_opt_neg
  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;}
};


@@ -474,6 +477,7 @@ class Item_func_strcmp :public Item_bool_func2
  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;}
};


@@ -536,6 +540,7 @@ class Item_func_ifnull :public Item_func_coalesce
  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;}
};


@@ -576,6 +581,7 @@ class Item_func_nullif :public Item_bool_func2
  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;}
};


@@ -618,6 +624,7 @@ class Item_func_case :public Item_func
  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;}
};


@@ -968,6 +975,7 @@ class Item_func_in :public Item_func_opt_neg
  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;}
};

/* Functions used by where clause */
@@ -1009,6 +1017,7 @@ class Item_func_isnull :public Item_bool_func
  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;}
};

/* Functions used by HAVING for rewriting IN subquery */
@@ -1030,6 +1039,8 @@ class Item_is_not_null_test :public Item_func_isnull
  */
  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; }
};


@@ -1052,6 +1063,7 @@ class Item_func_isnotnull :public Item_bool_func
  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;}
};


@@ -1090,6 +1102,7 @@ class Item_func_like :public Item_bool_func2
  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;}
};

#ifdef USE_REGEX
@@ -1112,6 +1125,7 @@ class Item_func_regex :public Item_bool_func
  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;}
};

#else
@@ -1168,6 +1182,7 @@ class Item_cond :public Item_bool_func
  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;}
};


+31 −1
Original line number Diff line number Diff line
@@ -247,6 +247,7 @@ class Item_func_num1: public Item_func_numhybrid
  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;}
};


@@ -259,6 +260,7 @@ class Item_num_op :public Item_func_numhybrid
  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;}
};


@@ -309,7 +311,7 @@ class Item_func_signed :public Item_int_func
  { 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;}
};


@@ -343,6 +345,7 @@ class Item_decimal_typecast :public Item_func
  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;}
};


@@ -411,6 +414,7 @@ class Item_func_int_div :public Item_int_func
  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;}
};


@@ -483,6 +487,7 @@ class Item_func_exp :public Item_dec_func
  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;}
};


@@ -492,6 +497,7 @@ class Item_func_ln :public Item_dec_func
  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;}
};


@@ -502,6 +508,7 @@ class Item_func_log :public Item_dec_func
  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;}
};


@@ -511,6 +518,7 @@ class Item_func_log2 :public Item_dec_func
  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;}
};


@@ -520,6 +528,7 @@ class Item_func_log10 :public Item_dec_func
  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;}
};


@@ -529,6 +538,7 @@ class Item_func_sqrt :public Item_dec_func
  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;}
};


@@ -538,6 +548,7 @@ class Item_func_pow :public Item_dec_func
  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;}
};


@@ -547,6 +558,7 @@ class Item_func_acos :public Item_dec_func
  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;}
};

class Item_func_asin :public Item_dec_func
@@ -555,6 +567,7 @@ class Item_func_asin :public Item_dec_func
  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;}
};

class Item_func_atan :public Item_dec_func
@@ -564,6 +577,7 @@ class Item_func_atan :public Item_dec_func
  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;}
};

class Item_func_cos :public Item_dec_func
@@ -572,6 +586,7 @@ class Item_func_cos :public Item_dec_func
  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;}
};

class Item_func_sin :public Item_dec_func
@@ -580,6 +595,7 @@ class Item_func_sin :public Item_dec_func
  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;}
};

class Item_func_tan :public Item_dec_func
@@ -588,6 +604,7 @@ class Item_func_tan :public Item_dec_func
  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;}
};

class Item_func_integer :public Item_int_func
@@ -664,6 +681,7 @@ class Item_func_sign :public Item_int_func
  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;}
};


@@ -678,6 +696,7 @@ class Item_func_units :public Item_real_func
  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;}
};


@@ -695,6 +714,7 @@ class Item_func_min_max :public Item_func
  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;}
};

class Item_func_min :public Item_func_min_max
@@ -720,6 +740,7 @@ class Item_func_length :public Item_int_func
  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;}
};

class Item_func_bit_length :public Item_func_length
@@ -739,6 +760,7 @@ class Item_func_char_length :public Item_int_func
  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;}
};

class Item_func_coercibility :public Item_int_func
@@ -749,6 +771,7 @@ class Item_func_coercibility :public Item_int_func
  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
@@ -762,6 +785,7 @@ class Item_func_locate :public Item_int_func
  longlong val_int();
  void fix_length_and_dec();
  void print(String *str);
  bool check_partition_func_processor(byte *bool_arg) { return 0;}
};


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

class Item_func_ord :public Item_int_func
@@ -795,6 +820,7 @@ class Item_func_ord :public Item_int_func
  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;}
};

class Item_func_find_in_set :public Item_int_func
@@ -808,6 +834,7 @@ class Item_func_find_in_set :public Item_int_func
  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;}
};

/* Base class for all bit functions: '~', '|', '^', '&', '>>', '<<' */
@@ -819,6 +846,7 @@ class Item_func_bit: public Item_int_func
  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;}
};

class Item_func_bit_or :public Item_func_bit
@@ -844,6 +872,7 @@ class Item_func_bit_count :public Item_int_func
  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;}
};

class Item_func_shift_left :public Item_func_bit
@@ -1280,6 +1309,7 @@ class Item_func_inet_aton : public Item_int_func
   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;}
};


Loading