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..358cb8f
--- /dev/null
+++ b/mysql-test/suite/compat/oracle/r/func_replace.result
@@ -0,0 +1,13 @@
+SET sql_mode=ORACLE;
+SELECT replace(null,'a','b') from dual;
+replace(null,'a','b')
+NULL
+SELECT replace('ab',null,'b') from dual;
+replace('ab',null,'b')
+ab
+SELECT replace('ab','a',null) from dual;
+replace('ab','a',null)
+b
+SELECT replace('ab',null,null) from dual;
+replace('ab',null,null)
+ab
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..57d2f5c
--- /dev/null
+++ b/mysql-test/suite/compat/oracle/t/func_replace.test
@@ -0,0 +1,10 @@
+#
+# Testing replace with null args
+#
+
+SET sql_mode=ORACLE;
+
+SELECT replace(null,'a','b') from dual;
+SELECT replace('ab',null,'b') from dual;
+SELECT replace('ab','a',null) from dual;
+SELECT replace('ab',null,null) from dual;
diff --git a/sql/item_strfunc.cc b/sql/item_strfunc.cc
index c88afce..447648c 100644
--- a/sql/item_strfunc.cc
+++ b/sql/item_strfunc.cc
@@ -1199,8 +1199,24 @@ 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_value),
+                       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 +1231,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 +1248,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 +1356,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_value2);
+  String *str3= args[2]->val_str(&tmp_value3);
+
+  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 854a692..c340e32 100644
--- a/sql/item_strfunc.h
+++ b/sql/item_strfunc.h
@@ -364,11 +364,25 @@ class Item_func_replace :public Item_str_func
     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_value2, tmp_value3, 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 dad438d..6d16b21 100644
--- a/sql/sql_lex.cc
+++ b/sql/sql_lex.cc
@@ -7040,3 +7040,13 @@ 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 b90d340..f65f8a1 100644
--- a/sql/sql_lex.h
+++ b/sql/sql_lex.h
@@ -3596,6 +3596,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 59c0450..0eef2b5 100644
--- a/sql/sql_yacc.yy
+++ b/sql/sql_yacc.yy
@@ -9963,8 +9963,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 77ced40..e18c62d 100644
--- a/sql/sql_yacc_ora.yy
+++ b/sql/sql_yacc_ora.yy
@@ -10054,8 +10054,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 ')'
