diff --git a/mysql-test/t/disabled.def b/mysql-test/t/disabled.def
index 0d3b7cdfdeb8afadd6557eeffe8575b83b84e021..51f9625e2398e6d3453b812f548beb4a1dbf5640 100644
--- a/mysql-test/t/disabled.def
+++ b/mysql-test/t/disabled.def
@@ -25,7 +25,6 @@ rpl_ndb_ddl              : BUG#18946 result file needs update + test needs to ch
 rpl_ndb_innodb2ndb       : Bug #19710  Cluster replication to partition table fails on DELETE FROM statement
 rpl_ndb_myisam2ndb       : Bug #19710  Cluster replication to partition table fails on DELETE FROM statement
 rpl_row_blob_innodb      : BUG#18980 2006-04-10 kent    Test fails randomly
-rpl_sp                   : BUG#16456 2006-02-16 jmiller
 rpl_multi_engine         : BUG#22583 2006-09-23 lars
 
 # the below testcase have been reworked to avoid the bug, test contains comment, keep bug open
diff --git a/mysql-test/t/rpl_sp.test b/mysql-test/t/rpl_sp.test
index f99b7178eceb8d41acbfddce7d5e2144f8c9017b..877c03af5136d9d313684f1762f0594120819660 100644
--- a/mysql-test/t/rpl_sp.test
+++ b/mysql-test/t/rpl_sp.test
@@ -8,6 +8,7 @@
 # still accepted (this test also checks that the new name is
 # accepted). The old name could be removed in 5.1 or 6.0.
 
+source include/have_binlog_format_mixed.inc;
 source include/master-slave.inc;
 
 # we need a db != test, where we don't have automatic grants
@@ -172,6 +173,15 @@ select * from mysql.proc where name="foo4" and db='mysqltest1';
 sync_slave_with_master;
 select * from mysql.proc where name="foo4" and db='mysqltest1';
 
+# fail if non-deterministic SP is called in SBR, bug#16456
+let $oblf=`select @@SESSION.BINLOG_FORMAT`;
+set binlog_format=STATEMENT;
+--error ER_BINLOG_ROW_RBR_TO_SBR
+call foo();
+--disable_query_log
+eval set binlog_format=$oblf;
+--enable_query_log
+
 # ********************** PART 2 : FUNCTIONS ***************
 
 connection master;
@@ -316,10 +326,31 @@ sync_slave_with_master;
 # check that this failed-in-the-middle replicated right:
 select * from t2;
 
+# fail if non-deterministic SF is called in SBR, bug#16456
+connection master;
+let $oblf=`select @@SESSION.BINLOG_FORMAT`;
+set binlog_format=STATEMENT;
+delimiter |;
+create function fn16456()
+       returns int
+begin
+       return unix_timestamp();
+end|
+delimiter ;|
+--error ER_BINLOG_ROW_RBR_TO_SBR
+select fn16456();
+--disable_query_log
+eval set binlog_format=$oblf;
+--enable_query_log
+drop function fn16456;
+
+
 # ********************** PART 3 : TRIGGERS ***************
 
 connection con1;
---error 1227
+# now fails due to missing trigger grant (err 1142 i/o 1227) due to new
+# check in sql_trigger.cc (v1.44) by anozdrin on 2006/02/01  --azundris
+--error ER_TABLEACCESS_DENIED_ERROR
 create trigger trg before insert on t1 for each row set new.a= 10;
 
 connection master;
diff --git a/sql/item_func.cc b/sql/item_func.cc
index 5712ad38fa43368fd4757c3bc1e3184619040c79..54f679bcf4c01b5ceba6d6fca79db5e5c6328f14 100644
--- a/sql/item_func.cc
+++ b/sql/item_func.cc
@@ -4995,6 +4995,18 @@ Item_func_sp::execute_impl(THD *thd, Field *return_value_fld)
   if (find_and_check_access(thd))
     goto error;
 
+  /*
+    Throw an error if a non-deterministic function is called while
+    statement-based replication (SBR) is active.
+  */
+  if (!m_sp->m_chistics->detistic &&
+      (mysql_bin_log.is_open() &&
+       thd->variables.binlog_format == BINLOG_FORMAT_STMT))
+  {
+    my_error(ER_BINLOG_ROW_RBR_TO_SBR, MYF(0));
+    goto error;
+  }
+
   /*
     Disable the binlogging if this is not a SELECT statement. If this is a
     SELECT, leave binlogging on, so execute_function() code writes the
diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc
index 2a45520af81a6359da36388143cb9c99b4553984..78c4b895eb386f8124a206511eac0b9360973273 100644
--- a/sql/sql_parse.cc
+++ b/sql/sql_parse.cc
@@ -4576,6 +4576,18 @@ mysql_execute_command(THD *thd)
             goto error;
         }
 
+        /*
+          Throw an error if a non-deterministic procedure is called while
+          statement-based replication (SBR) is active.
+         */
+        if (!sp->m_chistics->detistic &&
+            (mysql_bin_log.is_open() &&
+             thd->variables.binlog_format == BINLOG_FORMAT_STMT))
+        {
+          my_error(ER_BINLOG_ROW_RBR_TO_SBR, MYF(0));
+          goto error;
+        }
+
 	my_bool nsok= thd->net.no_send_ok;
 	thd->net.no_send_ok= TRUE;
 	if (sp->m_flags & sp_head::MULTI_RESULTS)