diff --git a/mysql-test/r/partition_error.result b/mysql-test/r/partition_error.result
index 1a0b1dd9b3a071965ec1a3525df9cdb028c61364..a7ca3d9b2fa7bad3ca58b4d86da9489946a17a8f 100644
--- a/mysql-test/r/partition_error.result
+++ b/mysql-test/r/partition_error.result
@@ -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
diff --git a/mysql-test/t/partition_error.test b/mysql-test/t/partition_error.test
index 03a2ab4180747518b8980e7a1d10d13b9deac059..659f0b8cef4885ec8aad2330ebc0112dae7ddc5f 100644
--- a/mysql-test/t/partition_error.test
+++ b/mysql-test/t/partition_error.test
@@ -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'));
diff --git a/sql/item.h b/sql/item.h
index 2f99034130acecbc5a7a31d73fe7b172bc712799..685da3014efd4be1b4e6b31b1d6befff263d1190 100644
--- a/sql/item.h
+++ b/sql/item.h
@@ -783,6 +783,29 @@ public:
   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 @@ public:
     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 @@ public:
   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 @@ public:
       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 @@ public:
   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 @@ public:
   {
     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 @@ public:
   {}
   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 @@ public:
   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 @@ public:
   {}
   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 @@ public:
                                                     &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 @@ public:
     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 @@ public:
   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 @@ public:
   }
   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
diff --git a/sql/item_cmpfunc.h b/sql/item_cmpfunc.h
index 1cfdcef02d0a7c849559dd02934d2cb204c8bdf0..f7da1e5e297e5ad678e99da8341c0d498dc9c9a3 100644
--- a/sql/item_cmpfunc.h
+++ b/sql/item_cmpfunc.h
@@ -239,6 +239,7 @@ public:
   }
   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 @@ public:
   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 @@ public:
   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 @@ public:
   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 @@ public:
   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 @@ public:
   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 @@ public:
   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 @@ public:
   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 @@ public:
   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 @@ public:
   */
   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 @@ public:
   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 @@ public:
   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 @@ public:
   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 @@ public:
   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;}
 };
 
 
diff --git a/sql/item_func.h b/sql/item_func.h
index 1d8a1bd5e220373cbd58238f47d1a58815e763be..9d31b57838c8fea93fd525ae584fd3c2de7a2040 100644
--- a/sql/item_func.h
+++ b/sql/item_func.h
@@ -247,6 +247,7 @@ public:
   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 @@ public:
   { 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 @@ public:
   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 @@ public:
   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 @@ public:
   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 @@ public:
   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 @@ public:
   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 @@ public:
   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 @@ public:
   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 @@ public:
   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 @@ public:
   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 @@ public:
   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 @@ public:
   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 @@ public:
   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 @@ public:
   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 @@ public:
   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 @@ public:
   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 @@ public:
   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 @@ public:
   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 @@ public:
   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 @@ public:
   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 @@ public:
   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 @@ public:
   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 @@ public:
   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 @@ public:
   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 @@ public:
   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 @@ public:
   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 @@ public:
   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 @@ public:
   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 @@ public:
    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;}
 };
 
 
diff --git a/sql/item_strfunc.h b/sql/item_strfunc.h
index 90d421a2c68a150d9ffceec6c49c03799c852ea3..212c06c45ffde9454a83411a30aa9053af048ba6 100644
--- a/sql/item_strfunc.h
+++ b/sql/item_strfunc.h
@@ -47,6 +47,7 @@ public:
   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;}
 };
 
 
@@ -57,6 +58,7 @@ public:
   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
@@ -87,6 +89,7 @@ public:
   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;}
 };
 
 class Item_func_concat_ws :public Item_str_func
@@ -107,6 +110,7 @@ public:
   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;}
 };
 
 
@@ -144,6 +148,7 @@ protected:
 public:
   Item_str_conv(Item *item) :Item_str_func(item) {}
   String *val_str(String *);
+  bool check_partition_func_processor(byte *bool_arg) { return 0;}
 };
 
 
@@ -207,6 +212,7 @@ public:
   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;}
 };
 
 
@@ -218,6 +224,7 @@ public:
   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;}
 };
 
 
@@ -232,6 +239,7 @@ public:
   String *val_str(String *);
   void fix_length_and_dec();
   const char *func_name() const { return "trim"; }
+  bool check_partition_func_processor(byte *bool_arg) { return 0;}
 };
 
 
@@ -411,6 +419,7 @@ public:
   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;}
 };
 
 
@@ -518,6 +527,7 @@ public:
   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;}
 };
 
 
@@ -530,6 +540,7 @@ public:
   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;}
 };
 
 
@@ -544,6 +555,7 @@ public:
     collation.set(default_charset());
     max_length= 64;
   }
+  bool check_partition_func_processor(byte *bool_arg) { return 0;}
 };
 
 
@@ -560,6 +572,7 @@ public:
     decimals=0;
     max_length=args[0]->max_length*2*collation.collation->mbmaxlen;
   }
+  bool check_partition_func_processor(byte *bool_arg) { return 0;}
 };
 
 class Item_func_unhex :public Item_str_func
@@ -575,6 +588,7 @@ public:
     decimals=0;
     max_length=(1+args[0]->max_length)/2;
   }
+  bool check_partition_func_processor(byte *bool_arg) { return 0;}
 };
 
 
@@ -598,6 +612,7 @@ public:
   }
   void print(String *str);
   const char *func_name() const { return "cast_as_binary"; }
+  bool check_partition_func_processor(byte *bool_arg) { return 0;}
 };
 
 
@@ -637,6 +652,7 @@ public:
   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;}
 };
 
 class Item_func_quote :public Item_str_func
@@ -651,6 +667,7 @@ public:
     collation.set(args[0]->collation);
     max_length= args[0]->max_length * 2 + 2;
   }
+  bool check_partition_func_processor(byte *bool_arg) { return 0;}
 };
 
 class Item_func_conv_charset :public Item_str_func
@@ -693,6 +710,7 @@ public:
   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
@@ -725,6 +743,7 @@ public:
      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
@@ -740,6 +759,7 @@ public:
      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
@@ -750,6 +770,7 @@ public:
   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;}
 };
 
 class Item_func_uncompressed_length : public Item_int_func
@@ -760,6 +781,7 @@ public:
   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
@@ -776,6 +798,7 @@ public:
   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
@@ -786,6 +809,7 @@ public:
   void fix_length_and_dec(){max_length= MAX_BLOB_WIDTH;}
   const char *func_name() const{return "uncompress";}
   String *val_str(String *) ZLIB_DEPENDED_FUNCTION
+  bool check_partition_func_processor(byte *bool_arg) { return 0;}
 };
 
 #define UUID_LENGTH (8+1+4+1+4+1+4+1+12)
diff --git a/sql/item_timefunc.h b/sql/item_timefunc.h
index ae0ca1a0445da6793ed3728ae9a4ed96dd4eeea3..69c8ec5959abdd3ecb24aec3eaf8047c1f25bb4d 100644
--- a/sql/item_timefunc.h
+++ b/sql/item_timefunc.h
@@ -39,6 +39,7 @@ public:
   { 
     max_length=6*MY_CHARSET_BIN_MB_MAXLEN;
   }
+  bool check_partition_func_processor(byte *bool_arg) { return 0;}
 };
 
 
@@ -53,6 +54,7 @@ public:
     decimals=0;
     max_length=6*MY_CHARSET_BIN_MB_MAXLEN;
   }
+  bool check_partition_func_processor(byte *bool_arg) { return 0;}
 };
 
 
@@ -69,6 +71,7 @@ public:
     maybe_null=1; 
   }
   enum_monotonicity_info get_monotonicity_info() const;
+  bool check_partition_func_processor(byte *bool_arg) { return 0;}
 };
 
 
@@ -84,6 +87,7 @@ public:
     max_length=2*MY_CHARSET_BIN_MB_MAXLEN;
     maybe_null=1; 
   }
+  bool check_partition_func_processor(byte *bool_arg) { return 0;}
 };
 
 
@@ -108,6 +112,7 @@ public:
     max_length=2*MY_CHARSET_BIN_MB_MAXLEN;
     maybe_null=1; 
   }
+  bool check_partition_func_processor(byte *bool_arg) { return 0;}
 };
 
 
@@ -140,6 +145,7 @@ public:
     max_length=3*MY_CHARSET_BIN_MB_MAXLEN;
     maybe_null=1; 
   }
+  bool check_partition_func_processor(byte *bool_arg) { return 0;}
 };
 
 
@@ -155,6 +161,7 @@ public:
     max_length=2*MY_CHARSET_BIN_MB_MAXLEN;
     maybe_null=1;
   }
+  bool check_partition_func_processor(byte *bool_arg) { return 0;}
 };
 
 
@@ -170,6 +177,7 @@ public:
     max_length=2*MY_CHARSET_BIN_MB_MAXLEN;
     maybe_null=1;
   }
+  bool check_partition_func_processor(byte *bool_arg) { return 0;}
 };
 
 
@@ -185,6 +193,7 @@ public:
      max_length=1*MY_CHARSET_BIN_MB_MAXLEN;
      maybe_null=1;
   }
+  bool check_partition_func_processor(byte *bool_arg) { return 0;}
 };
 
 
@@ -200,6 +209,7 @@ public:
     max_length=2*MY_CHARSET_BIN_MB_MAXLEN;
     maybe_null=1;
   }
+  bool check_partition_func_processor(byte *bool_arg) { return 0;}
 };
 
 
@@ -215,6 +225,7 @@ public:
     max_length=2*MY_CHARSET_BIN_MB_MAXLEN;
     maybe_null=1;
   }
+  bool check_partition_func_processor(byte *bool_arg) { return 0;}
 };
 
 class Item_func_yearweek :public Item_int_func
@@ -229,6 +240,7 @@ public:
     max_length=6*MY_CHARSET_BIN_MB_MAXLEN;
     maybe_null=1;
   }
+  bool check_partition_func_processor(byte *bool_arg) { return 0;}
 };
 
 
@@ -245,6 +257,7 @@ public:
     max_length=4*MY_CHARSET_BIN_MB_MAXLEN;
     maybe_null=1;
   }
+  bool check_partition_func_processor(byte *bool_arg) { return 0;}
 };
 
 
@@ -274,6 +287,7 @@ public:
     max_length=1*MY_CHARSET_BIN_MB_MAXLEN;
     maybe_null=1;
   }
+  bool check_partition_func_processor(byte *bool_arg) { return 0;}
 };
 
 class Item_func_dayname :public Item_func_weekday
@@ -306,6 +320,7 @@ public:
     decimals=0;
     max_length=10*MY_CHARSET_BIN_MB_MAXLEN;
   }
+  bool check_partition_func_processor(byte *bool_arg) { return 0;}
 };
 
 
@@ -320,6 +335,7 @@ public:
     decimals=0;
     max_length=10*MY_CHARSET_BIN_MB_MAXLEN;
   }
+  bool check_partition_func_processor(byte *bool_arg) { return 0;}
 };
 
 
@@ -526,6 +542,7 @@ public:
   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;}
 };
 
 
@@ -543,6 +560,7 @@ public:
   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;}
 };
 
 
@@ -561,6 +579,7 @@ class Item_func_from_unixtime :public Item_date_func
   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;}
 };
 
 
@@ -627,6 +646,7 @@ public:
   {
     return tmp_table_field_from_field_type(table, 0);
   }
+  bool check_partition_func_processor(byte *bool_arg) { return 0;}
 };
 
 
@@ -649,6 +669,7 @@ public:
   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;}
 };
 
 
@@ -666,6 +687,7 @@ class Item_extract :public Item_int_func
   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;}
 };
 
 
@@ -702,6 +724,7 @@ public:
     max_length=args[0]->max_length;
     maybe_null= 1;
   }
+  bool check_partition_func_processor(byte *bool_arg) { return 0;}
 };
 
 
@@ -721,6 +744,7 @@ public:
   String *val_str(String *a);
   void fix_length_and_dec();
   void print(String *str);
+  bool check_partition_func_processor(byte *bool_arg) { return 0;}
 };
 
 
@@ -792,6 +816,7 @@ public:
   {
     return tmp_table_field_from_field_type(table, 0);
   }
+  bool check_partition_func_processor(byte *bool_arg) { return 0;}
 };
 
 
@@ -814,6 +839,7 @@ public:
   }
   void print(String *str);
   const char *func_name() const { return "add_time"; }
+  bool check_partition_func_processor(byte *bool_arg) { return 0;}
 };
 
 class Item_func_timediff :public Item_str_func
@@ -853,6 +879,7 @@ public:
   {
     return tmp_table_field_from_field_type(table, 0);
   }
+  bool check_partition_func_processor(byte *bool_arg) { return 0;}
 };
 
 class Item_func_microsecond :public Item_int_func
@@ -866,6 +893,7 @@ public:
     decimals=0;
     maybe_null=1;
   }
+  bool check_partition_func_processor(byte *bool_arg) { return 0;}
 };
 
 
@@ -883,6 +911,7 @@ public:
     maybe_null=1;
   }
   void print(String *str);
+  bool check_partition_func_processor(byte *bool_arg) { return 0;}
 };
 
 
@@ -929,6 +958,7 @@ public:
   {
     return tmp_table_field_from_field_type(table, 1);
   }
+  bool check_partition_func_processor(byte *bool_arg) { return 0;}
 };
 
 
diff --git a/sql/item_xmlfunc.h b/sql/item_xmlfunc.h
index bc47e9c5bb14d6099f2e7a9444bb1ae5a150b53e..e11b4eac1e2fd406eaff5e6df9d29d8288903e91 100644
--- a/sql/item_xmlfunc.h
+++ b/sql/item_xmlfunc.h
@@ -42,6 +42,7 @@ public:
   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;}
 };
 
 
diff --git a/sql/partition_info.cc b/sql/partition_info.cc
index 0924a8adf6e09d5935f380f92d25f135290e0fd2..289296fcac3efa68c89908edbce9a5caff985552 100644
--- a/sql/partition_info.cc
+++ b/sql/partition_info.cc
@@ -685,8 +685,20 @@ bool partition_info::check_partition_info(handlerton **eng_type,
   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,
+                    (byte*)(&part_expression_ok));
+  if (is_sub_partitioned() && !list_of_subpart_fields)
+    subpart_expr->walk(&Item::check_partition_func_processor,
+                       (byte*)(&part_expression_ok));
+  if (!part_expression_ok)
+  {
+    my_error(ER_PARTITION_FUNCTION_IS_NOT_ALLOWED, MYF(0));
+    goto end;
+  }
   if (unlikely(!is_sub_partitioned() && 
                !(use_default_subpartitions && use_default_no_subpartitions)))
   {
diff --git a/sql/share/errmsg.txt b/sql/share/errmsg.txt
index 5aab951b2ca8024cf87200549b60bcdd773c4688..58dc107900a90a6f7ff103d259c5c97b7adb92f4 100644
--- a/sql/share/errmsg.txt
+++ b/sql/share/errmsg.txt
@@ -5832,6 +5832,9 @@ ER_NDB_CANT_SWITCH_BINLOG_FORMAT
 	eng "The NDB cluster engine does not support changing the binlog format on the fly yet"
 ER_PARTITION_NO_TEMPORARY
 	eng "Cannot create temporary table with partitions"
+ER_PARTITION_FUNCTION_IS_NOT_ALLOWED
+        eng "This partition function is not allowed"
+        swe "Denna partitioneringsfunktion är inte tillåten"
 ER_DDL_LOG_ERROR
         eng "Error in DDL log"
 ER_NULL_IN_VALUES_LESS_THAN