diff --git a/mysql-test/suite/compat/oracle/r/func_replace.result b/mysql-test/suite/compat/oracle/r/func_replace.result
new file mode 100644
index 0000000..609507a
--- /dev/null
+++ b/mysql-test/suite/compat/oracle/r/func_replace.result
@@ -0,0 +1,26 @@
+SET sql_mode=ORACLE;
+SELECT REPLACE(null,'a','b') ;
+REPLACE(null,'a','b')
+NULL
+SELECT REPLACE('ab',null,'b') ;
+REPLACE('ab',null,'b')
+ab
+SELECT REPLACE('ab','a',null) ;
+REPLACE('ab','a',null)
+b
+SELECT REPLACE('ab',null,null) ;
+REPLACE('ab',null,null)
+ab
+EXPLAIN EXTENDED SELECT REPLACE('ab','a',null) ;
+id	select_type	table	type	possible_keys	key	key_len	ref	rows	filtered	Extra
+1	SIMPLE	NULL	NULL	NULL	NULL	NULL	NULL	NULL	NULL	No tables used
+Warnings:
+Note	1003	select replace_oracle('ab','a',NULL) AS "REPLACE('ab','a',null)"
+CREATE VIEW v1 AS SELECT REPLACE('ab','a',null) ;
+SHOW CREATE VIEW v1;
+View	Create View	character_set_client	collation_connection
+v1	CREATE VIEW "v1" AS select replace_oracle('ab','a',NULL) AS "REPLACE('ab','a',null)"	latin1	latin1_swedish_ci
+SELECT * FROM v1;
+REPLACE('ab','a',null)
+b
+DROP VIEW v1;
diff --git a/mysql-test/suite/compat/oracle/t/func_replace.test b/mysql-test/suite/compat/oracle/t/func_replace.test
new file mode 100644
index 0000000..e253ca7
--- /dev/null
+++ b/mysql-test/suite/compat/oracle/t/func_replace.test
@@ -0,0 +1,17 @@
+#
+# Testing replace with null args
+#
+
+SET sql_mode=ORACLE;
+
+SELECT REPLACE(null,'a','b') ;
+SELECT REPLACE('ab',null,'b') ;
+SELECT REPLACE('ab','a',null) ;
+SELECT REPLACE('ab',null,null) ;
+
+EXPLAIN EXTENDED SELECT REPLACE('ab','a',null) ;
+
+CREATE VIEW v1 AS SELECT REPLACE('ab','a',null) ;
+SHOW CREATE VIEW v1;
+SELECT * FROM v1;
+DROP VIEW v1;
diff --git a/sql/item_create.cc b/sql/item_create.cc
index 50e7fcc..c76b9b0 100644
--- a/sql/item_create.cc
+++ b/sql/item_create.cc
@@ -2686,6 +2686,19 @@ class Create_func_release_lock : public Create_func_arg1
 };
 
 
+class Create_func_replace_oracle : public Create_func_arg3
+{
+public:
+  virtual Item *create_3_arg(THD *thd, Item *arg1, Item *arg2, Item *arg3);
+
+  static Create_func_replace_oracle s_singleton;
+
+protected:
+  Create_func_replace_oracle() {}
+  virtual ~Create_func_replace_oracle() {}
+};
+
+
 class Create_func_reverse : public Create_func_arg1
 {
 public:
@@ -6276,6 +6289,16 @@ Create_func_release_lock::create_1_arg(THD *thd, Item *arg1)
 }
 
 
+Create_func_replace_oracle Create_func_replace_oracle::s_singleton;
+
+Item*
+Create_func_replace_oracle::create_3_arg(THD *thd, Item *arg1, Item *arg2,
+                                        Item *arg3)
+{
+  return new (thd->mem_root) Item_func_replace_oracle(thd, arg1, arg2, arg3);
+}
+
+
 Create_func_reverse Create_func_reverse::s_singleton;
 
 Item*
@@ -6864,6 +6887,7 @@ static Native_func_registry func_array[] =
   { { C_STRING_WITH_LEN("CENTROID") }, GEOM_BUILDER(Create_func_centroid)},
   { { C_STRING_WITH_LEN("CHARACTER_LENGTH") }, BUILDER(Create_func_char_length)},
   { { C_STRING_WITH_LEN("CHAR_LENGTH") }, BUILDER(Create_func_char_length)},
+  { { C_STRING_WITH_LEN("CHR") }, BUILDER(Create_func_chr)},
   { { C_STRING_WITH_LEN("COERCIBILITY") }, BUILDER(Create_func_coercibility)},
   { { C_STRING_WITH_LEN("COLUMN_CHECK") }, BUILDER(Create_func_dyncol_check)},
   { { C_STRING_WITH_LEN("COLUMN_EXISTS") }, BUILDER(Create_func_dyncol_exists)},
@@ -6877,7 +6901,6 @@ 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)},
@@ -7052,6 +7075,8 @@ static Native_func_registry func_array[] =
   { { C_STRING_WITH_LEN("RADIANS") }, BUILDER(Create_func_radians)},
   { { C_STRING_WITH_LEN("RAND") }, BUILDER(Create_func_rand)},
   { { C_STRING_WITH_LEN("RELEASE_LOCK") }, BUILDER(Create_func_release_lock)},
+  { { C_STRING_WITH_LEN("REPLACE_ORACLE") },
+      BUILDER(Create_func_replace_oracle)},
   { { C_STRING_WITH_LEN("REVERSE") }, BUILDER(Create_func_reverse)},
   { { C_STRING_WITH_LEN("ROUND") }, BUILDER(Create_func_round)},
   { { C_STRING_WITH_LEN("RPAD") }, BUILDER(Create_func_rpad)},
diff --git a/sql/item_strfunc.cc b/sql/item_strfunc.cc
index ee5646b..e4452a4 100644
--- a/sql/item_strfunc.cc
+++ b/sql/item_strfunc.cc
@@ -1199,8 +1199,23 @@ void Item_func_reverse::fix_length_and_dec()
 
 String *Item_func_replace::val_str(String *str)
 {
+  if (args[1]->null_value)
+  {
+    null_value= 1;
+    return 0;
+  }
+  return replace_value(str,
+                       args[1]->val_str(&tmp_value1),
+                       args[2]->val_str(&tmp_value2));
+}
+
+
+String *Item_func_replace::replace_value(String *str,
+                                         String *res2,
+                                         String *res3)
+{
   DBUG_ASSERT(fixed == 1);
-  String *res,*res2,*res3;
+  String *res;
   int offset;
   uint from_length,to_length;
   bool alloced=0;
@@ -1215,9 +1230,6 @@ String *Item_func_replace::val_str(String *str)
   res=args[0]->val_str(str);
   if (args[0]->null_value)
     goto null;
-  res2=args[1]->val_str(&tmp_value);
-  if (args[1]->null_value)
-    goto null;
 
   res->set_charset(collation.collation);
 
@@ -1235,7 +1247,7 @@ String *Item_func_replace::val_str(String *str)
   if (binary_cmp && (offset=res->strstr(*res2)) < 0)
     return res;
 #endif
-  if (!(res3=args[2]->val_str(&tmp_value2)))
+  if (!res3)
     goto null;
   from_length= res2->length();
   to_length=   res3->length();
@@ -1343,6 +1355,24 @@ void Item_func_replace::fix_length_and_dec()
 }
 
 
+String *Item_func_replace_oracle::val_str(String *str)
+{
+  String *res;
+  String *str2= args[1]->val_str(&tmp_value1);
+  String *str3= args[2]->val_str(&tmp_value2);
+
+  if ((res = replace_value(str,
+                           str2 ? str2 : &tmp_emtpystr,
+                           str3 ? str3 : &tmp_emtpystr)))
+  {
+    if (res->length())
+      return res ;
+  }
+  null_value= 1;
+  return 0;
+}
+
+
 /*********************************************************************/
 void Item_func_regexp_replace::fix_length_and_dec()
 {
diff --git a/sql/item_strfunc.h b/sql/item_strfunc.h
index 6e31d48..f588584 100644
--- a/sql/item_strfunc.h
+++ b/sql/item_strfunc.h
@@ -357,17 +357,32 @@ class Item_func_reverse :public Item_str_func
 
 class Item_func_replace :public Item_str_func
 {
-  String tmp_value,tmp_value2;
+protected:
+  String tmp_value1,tmp_value2;
 public:
   Item_func_replace(THD *thd, Item *org, Item *find, Item *replace):
     Item_str_func(thd, org, find, replace) {}
   String *val_str(String *);
   void fix_length_and_dec();
+  String *replace_value(String *str, String *res2, String *res3);
   const char *func_name() const { return "replace"; }
   Item *get_copy(THD *thd, MEM_ROOT *mem_root)
   { return get_item_copy<Item_func_replace>(thd, mem_root, this); }
 };
 
+class Item_func_replace_oracle :public Item_func_replace
+{
+  String tmp_emtpystr;
+public:
+  Item_func_replace_oracle(THD *thd, Item *org, Item *find, Item *replace):
+    Item_func_replace(thd, org, find, replace) {}
+  String *val_str(String *);
+  void fix_args(THD *thd, Item *org, Item *find, Item *replace);
+  const char *func_name() const { return "replace_oracle"; }
+  Item *get_copy(THD *thd, MEM_ROOT *mem_root)
+  { return get_item_copy<Item_func_replace_oracle>(thd, mem_root, this); }
+};
+
 
 class Item_func_regexp_replace :public Item_str_func
 {
diff --git a/sql/sql_lex.cc b/sql/sql_lex.cc
index 8cabe79..e4956b9 100644
--- a/sql/sql_lex.cc
+++ b/sql/sql_lex.cc
@@ -7055,3 +7055,14 @@ bool LEX::sp_add_cfetch(THD *thd, const LEX_CSTRING *name)
     return true;
   return false;
 }
+
+
+Item *LEX::make_item_func_replace(THD *thd,
+                                  Item *org,
+                                  Item *find,
+                                  Item *replace)
+{
+  return (thd->variables.sql_mode & MODE_ORACLE) ?
+    new (thd->mem_root) Item_func_replace_oracle(thd, org, find, replace) :
+    new (thd->mem_root) Item_func_replace(thd, org, find, replace);
+}
diff --git a/sql/sql_lex.h b/sql/sql_lex.h
index 85ce07b..71f7a88 100644
--- a/sql/sql_lex.h
+++ b/sql/sql_lex.h
@@ -3602,6 +3602,9 @@ struct LEX: public Query_tables_list
   SELECT_LEX *exclude_last_select();
   bool add_unit_in_brackets(SELECT_LEX *nselect);
   void check_automatic_up(enum sub_select_type type);
+
+  Item *make_item_func_replace(THD *thd, Item *org, Item *find, Item *replace);
+
 };
 
 
diff --git a/sql/sql_yacc.yy b/sql/sql_yacc.yy
index c401a1d..fdf4557 100644
--- a/sql/sql_yacc.yy
+++ b/sql/sql_yacc.yy
@@ -10079,8 +10079,7 @@ function_call_conflict:
           }
         | REPLACE '(' expr ',' expr ',' expr ')'
           {
-            $$= new (thd->mem_root) Item_func_replace(thd, $3, $5, $7);
-            if ($$ == NULL)
+            if (!($$= Lex->make_item_func_replace(thd, $3, $5, $7)))
               MYSQL_YYABORT;
           }
         | REVERSE_SYM '(' expr ')'
diff --git a/sql/sql_yacc_ora.yy b/sql/sql_yacc_ora.yy
index e4cdd81..526059e 100644
--- a/sql/sql_yacc_ora.yy
+++ b/sql/sql_yacc_ora.yy
@@ -10134,8 +10134,7 @@ function_call_conflict:
           }
         | REPLACE '(' expr ',' expr ',' expr ')'
           {
-            $$= new (thd->mem_root) Item_func_replace(thd, $3, $5, $7);
-            if ($$ == NULL)
+            if (!($$= Lex->make_item_func_replace(thd, $3, $5, $7)))
               MYSQL_YYABORT;
           }
         | REVERSE_SYM '(' expr ')'
