diff --git a/mysql-test/r/sp.result b/mysql-test/r/sp.result
index 2f9f4fbdad2bbc54043a4843d5e3b0211095db29..afc3b95eb5f77bac7ef55c9b4ca273e2edf07b99 100644
--- a/mysql-test/r/sp.result
+++ b/mysql-test/r/sp.result
@@ -5647,6 +5647,32 @@ call proc_bug19733()|
 call proc_bug19733()|
 drop procedure proc_bug19733|
 drop table t3|
+DROP PROCEDURE IF EXISTS p1|
+DROP VIEW IF EXISTS v1, v2|
+DROP TABLE IF EXISTS t3, t4|
+CREATE TABLE t3 (t3_id INT)|
+INSERT INTO t3 VALUES (0)|
+INSERT INTO t3 VALUES (1)|
+CREATE TABLE t4 (t4_id INT)|
+INSERT INTO t4 VALUES (2)|
+CREATE VIEW v1 AS
+SELECT t3.t3_id, t4.t4_id
+FROM t3 JOIN t4 ON t3.t3_id = 0|
+CREATE VIEW v2 AS
+SELECT t3.t3_id AS t3_id_1, v1.t3_id AS t3_id_2, v1.t4_id
+FROM t3 LEFT JOIN v1 ON t3.t3_id = 0|
+CREATE PROCEDURE p1() SELECT * FROM v2|
+CALL p1()|
+t3_id_1	t3_id_2	t4_id
+0	0	2
+1	NULL	NULL
+CALL p1()|
+t3_id_1	t3_id_2	t4_id
+0	0	2
+1	NULL	NULL
+DROP PROCEDURE p1|
+DROP VIEW v1, v2|
+DROP TABLE t3, t4|
 End of 5.0 tests
 DROP TABLE IF EXISTS bug23760|
 DROP TABLE IF EXISTS bug23760_log|
diff --git a/mysql-test/t/sp.test b/mysql-test/t/sp.test
index 157d0b7c1189efd50a5b1984bf4e158f5dab831b..80fb1354b16d767621f91bc3bc61542c20e6f03b 100644
--- a/mysql-test/t/sp.test
+++ b/mysql-test/t/sp.test
@@ -6613,6 +6613,47 @@ call proc_bug19733()|
 drop procedure proc_bug19733|
 drop table t3|
 
+
+#
+# BUG#20492: Subsequent calls to stored procedure yeild incorrect
+# result if join is used 
+#
+# Optimized ON expression in join wasn't properly saved for reuse.
+#
+--disable_warnings
+DROP PROCEDURE IF EXISTS p1|
+DROP VIEW IF EXISTS v1, v2|
+DROP TABLE IF EXISTS t3, t4|
+--enable_warnings
+
+CREATE TABLE t3 (t3_id INT)|
+
+INSERT INTO t3 VALUES (0)|
+INSERT INTO t3 VALUES (1)|
+
+CREATE TABLE t4 (t4_id INT)|
+
+INSERT INTO t4 VALUES (2)|
+
+CREATE VIEW v1 AS
+SELECT t3.t3_id, t4.t4_id
+FROM t3 JOIN t4 ON t3.t3_id = 0|
+
+CREATE VIEW v2 AS
+SELECT t3.t3_id AS t3_id_1, v1.t3_id AS t3_id_2, v1.t4_id
+FROM t3 LEFT JOIN v1 ON t3.t3_id = 0|
+
+CREATE PROCEDURE p1() SELECT * FROM v2|
+
+# Results should not differ.
+CALL p1()|
+CALL p1()|
+
+DROP PROCEDURE p1|
+DROP VIEW v1, v2|
+DROP TABLE t3, t4|
+
+
 --echo End of 5.0 tests
 
 
diff --git a/sql/sql_select.cc b/sql/sql_select.cc
index 5202f35f4de43303319490d9947176873274d817..346b8c13940a139dc9cac8bbf6213365b210ef9b 100644
--- a/sql/sql_select.cc
+++ b/sql/sql_select.cc
@@ -7983,9 +7983,14 @@ simplify_joins(JOIN *join, List<TABLE_LIST> *join_list, COND *conds, bool top)
 	*/ 
         expr= simplify_joins(join, &nested_join->join_list,
                              expr, FALSE);
-        table->on_expr= expr;
-        if (!table->prep_on_expr)
+
+        if (!table->prep_on_expr || expr != table->on_expr)
+        {
+          DBUG_ASSERT(expr);
+
+          table->on_expr= expr;
           table->prep_on_expr= expr->copy_andor_structure(join->thd);
+        }
       }
       nested_join->used_tables= (table_map) 0;
       nested_join->not_null_tables=(table_map) 0;
@@ -7995,7 +8000,7 @@ simplify_joins(JOIN *join, List<TABLE_LIST> *join_list, COND *conds, bool top)
     }
     else
     {
-      if (!(table->prep_on_expr))
+      if (!table->prep_on_expr)
         table->prep_on_expr= table->on_expr;
       used_tables= table->table->map;
       if (conds)