diff --git a/mysql-test/r/func_str.result b/mysql-test/r/func_str.result
index 97c0686..a6933e0 100644
--- a/mysql-test/r/func_str.result
+++ b/mysql-test/r/func_str.result
@@ -4843,5 +4843,20 @@ YQ==	61
 Yq==	62
 DROP TABLE t1;
 #
+# Function CHR(n) : returns the character having the binary equivalent to n in the database character set
+#
+select chr(65);
+chr(65)
+A
+create database mysqltest1 CHARACTER SET = 'utf8' COLLATE = 'utf8_bin';
+use mysqltest1;
+select charset(chr(65)), length(chr(65)),char_length(chr(65));
+charset(chr(65))	length(chr(65))	char_length(chr(65))
+utf8	1	1
+select charset(chr(14844588)), length(chr(14844588)),char_length(chr(14844588));
+charset(chr(14844588))	length(chr(14844588))	char_length(chr(14844588))
+utf8	3	1
+drop database mysqltest1;
+#
 # End of 10.1 tests
 #
diff --git a/mysql-test/t/func_str.test b/mysql-test/t/func_str.test
index 10ab510..3bcd32e 100644
--- a/mysql-test/t/func_str.test
+++ b/mysql-test/t/func_str.test
@@ -1853,6 +1853,15 @@ SELECT f1,HEX(f2) FROM t1                  WHERE f1='YQ==' AND (f2= from_base64(
 SELECT f1,HEX(f2) FROM t1                  WHERE f1='YQ==' AND (f2= from_base64("Yq==") OR f2= from_base64("YQ=="));
 DROP TABLE t1;
 
+--echo #
+--echo # Function CHR(n) : returns the character having the binary equivalent to n in the database character set
+--echo #
+select chr(65);
+create database mysqltest1 CHARACTER SET = 'utf8' COLLATE = 'utf8_bin';
+use mysqltest1;
+select charset(chr(65)), length(chr(65)),char_length(chr(65));
+select charset(chr(14844588)), length(chr(14844588)),char_length(chr(14844588));
+drop database mysqltest1;
 
 --echo #
 --echo # End of 10.1 tests
diff --git a/sql/item_create.cc b/sql/item_create.cc
index 4c03723..039994c 100644
--- a/sql/item_create.cc
+++ b/sql/item_create.cc
@@ -517,6 +517,19 @@ class Create_func_centroid : public Create_func_arg1
 };
 
 
+class Create_func_chr : public Create_func_arg1
+{
+public:
+  virtual Item *create_1_arg(THD *thd, Item *arg1);
+
+  static Create_func_chr s_singleton;
+
+protected:
+  Create_func_chr() {}
+  virtual ~Create_func_chr() {}
+};
+
+
 class Create_func_convexhull : public Create_func_arg1
 {
 public:
@@ -3786,6 +3799,16 @@ Create_func_centroid::create_1_arg(THD *thd, Item *arg1)
 }
 
 
+Create_func_chr Create_func_chr::s_singleton;
+
+Item*
+Create_func_chr::create_1_arg(THD *thd, Item *arg1)
+{
+  CHARSET_INFO *cs_db= thd->variables.collation_database;
+  return new (thd->mem_root) Item_func_chr(thd, arg1, cs_db);
+}
+
+
 Create_func_convexhull Create_func_convexhull::s_singleton;
 
 Item*
@@ -6835,6 +6858,7 @@ static Native_func_registry func_array[] =
   { { C_STRING_WITH_LEN("CONV") }, BUILDER(Create_func_conv)},
   { { C_STRING_WITH_LEN("CONVERT_TZ") }, BUILDER(Create_func_convert_tz)},
   { { C_STRING_WITH_LEN("CONVEXHULL") }, GEOM_BUILDER(Create_func_convexhull)},
+  { { C_STRING_WITH_LEN("CHR") }, BUILDER(Create_func_chr)},
   { { C_STRING_WITH_LEN("COS") }, BUILDER(Create_func_cos)},
   { { C_STRING_WITH_LEN("COT") }, BUILDER(Create_func_cot)},
   { { C_STRING_WITH_LEN("CRC32") }, BUILDER(Create_func_crc32)},
diff --git a/sql/item_strfunc.cc b/sql/item_strfunc.cc
index dd2259f..c88afce 100644
--- a/sql/item_strfunc.cc
+++ b/sql/item_strfunc.cc
@@ -2905,29 +2905,51 @@ String *Item_func_char::val_str(String *str)
   {
     int32 num=(int32) args[i]->val_int();
     if (!args[i]->null_value)
-    {
-      char tmp[4];
-      if (num & 0xFF000000L)
-      {
-        mi_int4store(tmp, num);
-        str->append(tmp, 4, &my_charset_bin);
-      }
-      else if (num & 0xFF0000L)
-      {
-        mi_int3store(tmp, num);
-        str->append(tmp, 3, &my_charset_bin);
-      }
-      else if (num & 0xFF00L)
-      {
-        mi_int2store(tmp, num);
-        str->append(tmp, 2, &my_charset_bin);
-      }
-      else
-      {
-        tmp[0]= (char) num;
-        str->append(tmp, 1, &my_charset_bin);
-      }
-    }
+      append_char(str, num);
+  }
+  str->realloc(str->length());			// Add end 0 (for Purify)
+  return check_well_formed_result(str);
+}
+
+
+void Item_func_char::append_char(String *str, int32 num)
+{
+  char tmp[4];
+  if (num & 0xFF000000L)
+  {
+    mi_int4store(tmp, num);
+    str->append(tmp, 4, &my_charset_bin);
+  }
+  else if (num & 0xFF0000L)
+  {
+    mi_int3store(tmp, num);
+    str->append(tmp, 3, &my_charset_bin);
+  }
+  else if (num & 0xFF00L)
+  {
+    mi_int2store(tmp, num);
+    str->append(tmp, 2, &my_charset_bin);
+  }
+  else
+  {
+    tmp[0]= (char) num;
+    str->append(tmp, 1, &my_charset_bin);
+  }
+}
+
+
+String *Item_func_chr::val_str(String *str)
+{
+  DBUG_ASSERT(fixed == 1);
+  str->length(0);
+  str->set_charset(collation.collation);
+  int32 num=(int32) args[0]->val_int();
+  if (!args[0]->null_value)
+    append_char(str, num);
+  else
+  {
+    null_value= 1;
+    return 0;
   }
   str->realloc(str->length());			// Add end 0 (for Purify)
   return check_well_formed_result(str);
diff --git a/sql/item_strfunc.h b/sql/item_strfunc.h
index 58bd6c9..854a692 100644
--- a/sql/item_strfunc.h
+++ b/sql/item_strfunc.h
@@ -947,7 +947,11 @@ class Item_func_char :public Item_str_func
   Item_func_char(THD *thd, List<Item> &list, CHARSET_INFO *cs):
     Item_str_func(thd, list)
   { collation.set(cs); }
+  Item_func_char(THD *thd, Item *arg1, CHARSET_INFO *cs):
+    Item_str_func(thd, arg1)
+  { collation.set(cs); }
   String *val_str(String *);
+  void append_char(String * str, int32 num);
   void fix_length_and_dec()
   {
     max_length= arg_count * 4;
@@ -957,6 +961,20 @@ class Item_func_char :public Item_str_func
   { return get_item_copy<Item_func_char>(thd, mem_root, this); }
 };
 
+class Item_func_chr :public Item_func_char
+{
+public:
+  Item_func_chr(THD *thd, Item *arg1, CHARSET_INFO *cs):
+    Item_func_char(thd, arg1, cs) {}
+  String *val_str(String *);
+  void fix_length_and_dec()
+  {
+    max_length= 4;
+  }
+  const char *func_name() const { return "chr"; }
+  Item *get_copy(THD *thd, MEM_ROOT *mem_root)
+  { return get_item_copy<Item_func_chr>(thd, mem_root, this); }
+};
 
 class Item_func_repeat :public Item_str_func
 {
