diff --git a/mysql-test/r/ps.result b/mysql-test/r/ps.result
index 7d80d08e6633e76d2cc271b5d8225927ac19e232..7b3b051fffb4b7415d98a0ef839efe26a3ff2376 100644
--- a/mysql-test/r/ps.result
+++ b/mysql-test/r/ps.result
@@ -137,3 +137,45 @@ execute stmt1;
 FOUND_ROWS()
 0
 deallocate prepare stmt1;
+drop table t1;
+create table t1 
+(
+c1  tinyint, c2  smallint, c3  mediumint, c4  int,
+c5  integer, c6  bigint, c7  float, c8  double,
+c9  double precision, c10 real, c11 decimal(7, 4), c12 numeric(8, 4),
+c13 date, c14 datetime, c15 timestamp(14), c16 time,
+c17 year, c18 bit, c19 bool, c20 char,
+c21 char(10), c22 varchar(30), c23 tinyblob, c24 tinytext,
+c25 blob, c26 text, c27 mediumblob, c28 mediumtext,
+c29 longblob, c30 longtext, c31 enum('one', 'two', 'three'),
+c32 set('monday', 'tuesday', 'wednesday')
+) engine = MYISAM ;
+create table t2 like t1;
+set @stmt= ' explain SELECT (SELECT SUM(c1 + c12 + 0.0) FROM t2 where (t1.c2 - 0e-3) = t2.c2 GROUP BY t1.c15 LIMIT 1) as scalar_s, exists (select 1.0e+0 from t2 where t2.c3 * 9.0000000000 = t1.c4) as exists_s, c5 * 4 in (select c6 + 0.3e+1 from t2) as in_s, (c7 - 4, c8 - 4) in (select c9 + 4.0, c10 + 40e-1 from t2) as in_row_s FROM t1, (select c25 x, c32 y from t2) tt WHERE x * 1 = c25 ' ;
+prepare stmt1 from @stmt ;
+execute stmt1 ;
+id	select_type	table	type	possible_keys	key	key_len	ref	rows	Extra
+1	PRIMARY	NULL	NULL	NULL	NULL	NULL	NULL	NULL	Impossible WHERE noticed after reading const tables
+6	DERIVED	NULL	NULL	NULL	NULL	NULL	NULL	NULL	no matching row in const table
+5	DEPENDENT SUBQUERY	t2	system	NULL	NULL	NULL	NULL	0	const row not found
+4	DEPENDENT SUBQUERY	t2	system	NULL	NULL	NULL	NULL	0	const row not found
+3	DEPENDENT SUBQUERY	t2	system	NULL	NULL	NULL	NULL	0	const row not found
+2	DEPENDENT SUBQUERY	t2	system	NULL	NULL	NULL	NULL	0	const row not found
+execute stmt1 ;
+id	select_type	table	type	possible_keys	key	key_len	ref	rows	Extra
+1	PRIMARY	NULL	NULL	NULL	NULL	NULL	NULL	NULL	Impossible WHERE noticed after reading const tables
+6	DERIVED	NULL	NULL	NULL	NULL	NULL	NULL	NULL	no matching row in const table
+5	DEPENDENT SUBQUERY	t2	system	NULL	NULL	NULL	NULL	0	const row not found
+4	DEPENDENT SUBQUERY	t2	system	NULL	NULL	NULL	NULL	0	const row not found
+3	DEPENDENT SUBQUERY	t2	system	NULL	NULL	NULL	NULL	0	const row not found
+2	DEPENDENT SUBQUERY	t2	system	NULL	NULL	NULL	NULL	0	const row not found
+explain SELECT (SELECT SUM(c1 + c12 + 0.0) FROM t2 where (t1.c2 - 0e-3) = t2.c2 GROUP BY t1.c15 LIMIT 1) as scalar_s, exists (select 1.0e+0 from t2 where t2.c3 * 9.0000000000 = t1.c4) as exists_s, c5 * 4 in (select c6 + 0.3e+1 from t2) as in_s, (c7 - 4, c8 - 4) in (select c9 + 4.0, c10 + 40e-1 from t2) as in_row_s FROM t1, (select c25 x, c32 y from t2) tt WHERE x * 1 = c25;
+id	select_type	table	type	possible_keys	key	key_len	ref	rows	Extra
+1	PRIMARY	NULL	NULL	NULL	NULL	NULL	NULL	NULL	Impossible WHERE noticed after reading const tables
+6	DERIVED	NULL	NULL	NULL	NULL	NULL	NULL	NULL	no matching row in const table
+5	DEPENDENT SUBQUERY	t2	system	NULL	NULL	NULL	NULL	0	const row not found
+4	DEPENDENT SUBQUERY	t2	system	NULL	NULL	NULL	NULL	0	const row not found
+3	DEPENDENT SUBQUERY	t2	system	NULL	NULL	NULL	NULL	0	const row not found
+2	DEPENDENT SUBQUERY	t2	system	NULL	NULL	NULL	NULL	0	const row not found
+deallocate prepare stmt1;
+drop tables t1,t2;
diff --git a/mysql-test/t/ps.test b/mysql-test/t/ps.test
index 8881d6b9eecee1de8134545ca44f497b4c82664d..3dc6e10f55d3efbfabb81668a7c83f88d8c962af 100644
--- a/mysql-test/t/ps.test
+++ b/mysql-test/t/ps.test
@@ -114,8 +114,8 @@ set @str1 = 'select ?';
 set @str2 = convert(@str1 using ucs2);
 prepare stmt1 from @str2;
 execute stmt1 using @ivar;
-
 drop table t1,t2;
+
 #
 # Bug #4105: Server crash on attempt to prepare a statement with character
 # set introducer
@@ -140,3 +140,29 @@ execute stmt1;
 # Expect 0
 execute stmt1;
 deallocate prepare stmt1;
+drop table t1;
+
+#
+# prepared EXPLAIN
+#
+create table t1 
+(
+  c1  tinyint, c2  smallint, c3  mediumint, c4  int,
+  c5  integer, c6  bigint, c7  float, c8  double,
+  c9  double precision, c10 real, c11 decimal(7, 4), c12 numeric(8, 4),
+  c13 date, c14 datetime, c15 timestamp(14), c16 time,
+  c17 year, c18 bit, c19 bool, c20 char,
+  c21 char(10), c22 varchar(30), c23 tinyblob, c24 tinytext,
+  c25 blob, c26 text, c27 mediumblob, c28 mediumtext,
+  c29 longblob, c30 longtext, c31 enum('one', 'two', 'three'),
+  c32 set('monday', 'tuesday', 'wednesday')
+) engine = MYISAM ;
+create table t2 like t1;
+
+set @stmt= ' explain SELECT (SELECT SUM(c1 + c12 + 0.0) FROM t2 where (t1.c2 - 0e-3) = t2.c2 GROUP BY t1.c15 LIMIT 1) as scalar_s, exists (select 1.0e+0 from t2 where t2.c3 * 9.0000000000 = t1.c4) as exists_s, c5 * 4 in (select c6 + 0.3e+1 from t2) as in_s, (c7 - 4, c8 - 4) in (select c9 + 4.0, c10 + 40e-1 from t2) as in_row_s FROM t1, (select c25 x, c32 y from t2) tt WHERE x * 1 = c25 ' ;
+prepare stmt1 from @stmt ;
+execute stmt1 ;
+execute stmt1 ;
+explain SELECT (SELECT SUM(c1 + c12 + 0.0) FROM t2 where (t1.c2 - 0e-3) = t2.c2 GROUP BY t1.c15 LIMIT 1) as scalar_s, exists (select 1.0e+0 from t2 where t2.c3 * 9.0000000000 = t1.c4) as exists_s, c5 * 4 in (select c6 + 0.3e+1 from t2) as in_s, (c7 - 4, c8 - 4) in (select c9 + 4.0, c10 + 40e-1 from t2) as in_row_s FROM t1, (select c25 x, c32 y from t2) tt WHERE x * 1 = c25;
+deallocate prepare stmt1;
+drop tables t1,t2;
diff --git a/sql/sql_prepare.cc b/sql/sql_prepare.cc
index bb5cd755139dc87b6e4258e4910044012b4e938d..91df364e531e2e08489bda0edb3719cf210ca3c3 100644
--- a/sql/sql_prepare.cc
+++ b/sql/sql_prepare.cc
@@ -1082,22 +1082,22 @@ static int mysql_test_select(Prepared_statement *stmt,
     goto err;
   }
 
+  thd->used_tables= 0;                        // Updated by setup_fields
+
+  // JOIN::prepare calls
+  if (unit->prepare(thd, 0, 0))
+  {
+    send_error(thd);
+    goto err_prep;
+  }
   if (lex->describe)
   {
     if (!text_protocol && send_prep_stmt(stmt, 0))
-      goto err;
+      goto err_prep;
+    unit->cleanup();
   }
   else
   {
-    thd->used_tables= 0;                        // Updated by setup_fields
-
-    // JOIN::prepare calls
-    if (unit->prepare(thd, 0, 0))
-    {
-      send_error(thd);
-      goto err_prep;
-    }
-
     if (!text_protocol)
     {
       if (send_prep_stmt(stmt, lex->select_lex.item_list.elements) ||
@@ -1665,6 +1665,8 @@ static void reset_stmt_for_execute(Prepared_statement *stmt)
 
   for (; sl; sl= sl->next_select_in_list())
   {
+    /* remove option which was put by mysql_explain_union() */
+    sl->options&= ~SELECT_DESCRIBE;
     /*
       Copy WHERE clause pointers to avoid damaging they by optimisation
     */
diff --git a/sql/sql_select.cc b/sql/sql_select.cc
index f7f7f24ccf48964ad69484fbb5ddd4ef757c9cbb..d8662af1d399c8569b1674c552f263aa692ef50a 100644
--- a/sql/sql_select.cc
+++ b/sql/sql_select.cc
@@ -603,7 +603,6 @@ JOIN::optimize()
   {
     zero_result_cause= "no matching row in const table";
     DBUG_PRINT("error",("Error: %s", zero_result_cause));
-    select_options= 0; //TODO why option in return_zero_rows was droped
     error= 0;
     DBUG_RETURN(0);
   }