diff --git a/Makefile.am b/Makefile.am
index 19d7678e611fa0cc550e9db60cb64d94cc92b3fa..36175ce55e43a90ce9692adc2ee62c378e4dc2f8 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -91,6 +91,7 @@ bin-dist:		all
 # Remove BK's "SCCS" subdirectories from source distribution
 dist-hook:
 	rm -rf `find $(distdir) -type d -name SCCS -print`
+	rm -f  `find $(distdir) -type l -print`
 
 tags:
 	support-files/build-tags
diff --git a/client/mysqltest.c b/client/mysqltest.c
index 2dcf718918e6f4f54e8d2c52142e3b43f5b9e8ae..c6cbf6aabe0a2d27b9d1cc2e1e67c0775a05aa07 100644
--- a/client/mysqltest.c
+++ b/client/mysqltest.c
@@ -222,11 +222,13 @@ struct st_connection
   char *name;
   MYSQL_STMT* stmt;
 
+#ifdef EMBEDDED_LIBRARY
   const char *cur_query;
   int cur_query_len;
   pthread_mutex_t mutex;
   pthread_cond_t cond;
   int query_done;
+#endif /*EMBEDDED_LIBRARY*/
 };
 struct st_connection connections[128];
 struct st_connection* cur_con, *next_con, *connections_end;
diff --git a/libmysql/libmysql.c b/libmysql/libmysql.c
index 5577ecdb556cbb516a9d9e0e39aa34e3b9d11aaf..e963c0e429cbc0cfe9447fa600b3f5b2dcd3a10c 100644
--- a/libmysql/libmysql.c
+++ b/libmysql/libmysql.c
@@ -2496,6 +2496,8 @@ static my_bool execute(MYSQL_STMT *stmt, char *packet, ulong length)
   NET	*net= &mysql->net;
   char buff[4 /* size of stmt id */ +
             5 /* execution flags */];
+  my_bool res;
+
   DBUG_ENTER("execute");
   DBUG_PRINT("enter",("packet: %s, length :%d",packet ? packet :" ", length));
 
@@ -2503,15 +2505,17 @@ static my_bool execute(MYSQL_STMT *stmt, char *packet, ulong length)
   int4store(buff, stmt->stmt_id);		/* Send stmt id to server */
   buff[4]= (char) 0;                            /* no flags */
   int4store(buff+5, 1);                         /* iteration count */
-  if (cli_advanced_command(mysql, COM_EXECUTE, buff, sizeof(buff),
-                           packet, length, 1, NULL) ||
-      (*mysql->methods->read_query_result)(mysql))
+
+  res= test(cli_advanced_command(mysql, COM_EXECUTE, buff, sizeof(buff),
+                                 packet, length, 1, NULL) ||
+            (*mysql->methods->read_query_result)(mysql));
+  stmt->affected_rows= mysql->affected_rows;
+  stmt->insert_id= mysql->insert_id;
+  if (res)
   {
     set_stmt_errmsg(stmt, net->last_error, net->last_errno, net->sqlstate);
     DBUG_RETURN(1);
   }
-  stmt->affected_rows= mysql->affected_rows;
-  stmt->insert_id= mysql->insert_id;
   DBUG_RETURN(0);
 }
 
diff --git a/libmysqld/lib_sql.cc b/libmysqld/lib_sql.cc
index 64bc37fb40d5a6b962c1deb200280769e9e757a9..804c4e001d2bd8c95a3be9e9a9bf177652eb12d4 100644
--- a/libmysqld/lib_sql.cc
+++ b/libmysqld/lib_sql.cc
@@ -224,20 +224,24 @@ static int emb_stmt_execute(MYSQL_STMT *stmt)
 {
   DBUG_ENTER("emb_stmt_execute");
   char header[4];
+  my_bool res;
+
   int4store(header, stmt->stmt_id);
   THD *thd= (THD*)stmt->mysql->thd;
   thd->client_param_count= stmt->param_count;
   thd->client_params= stmt->params;
-  if (emb_advanced_command(stmt->mysql, COM_EXECUTE,0,0,
-                           header, sizeof(header), 1, stmt) ||
-      emb_mysql_read_query_result(stmt->mysql))
+
+  res= test(emb_advanced_command(stmt->mysql, COM_EXECUTE,0,0,
+                                 header, sizeof(header), 1, stmt) ||
+            emb_mysql_read_query_result(stmt->mysql));
+  stmt->affected_rows= stmt->mysql->affected_rows;
+  stmt->insert_id= stmt->mysql->insert_id;
+  if (res)
   {
     NET *net= &stmt->mysql->net;
     set_stmt_errmsg(stmt, net->last_error, net->last_errno, net->sqlstate);
     DBUG_RETURN(1);
   }
-  stmt->affected_rows= stmt->mysql->affected_rows;
-  stmt->insert_id= stmt->mysql->insert_id;
   DBUG_RETURN(0);
 }
 
diff --git a/mysql-test/lib/mtr_process.pl b/mysql-test/lib/mtr_process.pl
index 37a82177f4668bf0eeeebd3f6aa20a18b9cb909b..cf0dc0dc6f8b644c4a362da2b44eb89f2b2e23ba 100644
--- a/mysql-test/lib/mtr_process.pl
+++ b/mysql-test/lib/mtr_process.pl
@@ -1052,7 +1052,7 @@ sub sleep_until_file_created ($$$) {
 
     # Print extra message every 60 seconds
     my $seconds= ($loop * $sleeptime) / 1000;
-    if ( $seconds > 1 and int($seconds) % 60 == 0 )
+    if ( $seconds > 1 and int($seconds * 10) % 600 == 0 )
     {
       my $left= $timeout - $seconds;
       mtr_warning("Waited $seconds seconds for $pidfile to be created, " .
diff --git a/mysql-test/mysql-test-run.pl b/mysql-test/mysql-test-run.pl
index 7ed84f9cc3fe74b9aa2183dabdda9cc2b0b1e53c..5002f778da5be05e0358ff344292424f62c2dd1a 100755
--- a/mysql-test/mysql-test-run.pl
+++ b/mysql-test/mysql-test-run.pl
@@ -63,7 +63,6 @@ use Getopt::Long;
 use Sys::Hostname;
 use IO::Socket;
 use IO::Socket::INET;
-use Data::Dumper;
 use strict;
 use warnings;
 
diff --git a/mysql-test/r/func_in.result b/mysql-test/r/func_in.result
index 3cf2afc83d1deb638c6970c7a1f0394251a77866..f74c63f7260b1d1f77fc7d066fccdc729b225bcd 100644
--- a/mysql-test/r/func_in.result
+++ b/mysql-test/r/func_in.result
@@ -202,3 +202,11 @@ select count(*) from t1 where id not in (1,2);
 count(*)
 1
 drop table t1;
+DROP TABLE IF EXISTS t1;
+CREATE TABLE t1 SELECT 1 IN (2, NULL);
+SELECT should return NULL.
+SELECT * FROM t1;
+1 IN (2, NULL)
+NULL
+DROP TABLE t1;
+End of 4.1 tests
diff --git a/mysql-test/r/ps.result b/mysql-test/r/ps.result
index 2bb5df6e6cf0b9de60247384e0a1d4bb9853d75d..94c51fdc18bce810cbfabdf603d17b499bf5a2ee 100644
--- a/mysql-test/r/ps.result
+++ b/mysql-test/r/ps.result
@@ -775,12 +775,12 @@ set @old_max_prepared_stmt_count= @@max_prepared_stmt_count;
 show variables like 'max_prepared_stmt_count';
 Variable_name	Value
 max_prepared_stmt_count	16382
-show variables like 'prepared_stmt_count';
+show status like 'prepared_stmt_count';
 Variable_name	Value
-prepared_stmt_count	0
-select @@max_prepared_stmt_count, @@prepared_stmt_count;
-@@max_prepared_stmt_count	@@prepared_stmt_count
-16382	0
+Prepared_stmt_count	0
+select @@max_prepared_stmt_count;
+@@max_prepared_stmt_count
+16382
 set global max_prepared_stmt_count=-1;
 select @@max_prepared_stmt_count;
 @@max_prepared_stmt_count
@@ -799,67 +799,70 @@ set max_prepared_stmt_count=1;
 ERROR HY000: Variable 'max_prepared_stmt_count' is a GLOBAL variable and should be set with SET GLOBAL
 set local max_prepared_stmt_count=1;
 ERROR HY000: Variable 'max_prepared_stmt_count' is a GLOBAL variable and should be set with SET GLOBAL
-set local prepared_stmt_count=0;
-ERROR HY000: Variable 'prepared_stmt_count' is a GLOBAL variable and should be set with SET GLOBAL
-set @@prepared_stmt_count=0;
-ERROR HY000: Variable 'prepared_stmt_count' is a GLOBAL variable and should be set with SET GLOBAL
-set global prepared_stmt_count=1;
-ERROR 42000: Incorrect argument type to variable 'prepared_stmt_count'
 set global max_prepared_stmt_count=1;
 select @@max_prepared_stmt_count;
 @@max_prepared_stmt_count
 1
 set global max_prepared_stmt_count=0;
-select @@max_prepared_stmt_count, @@prepared_stmt_count;
-@@max_prepared_stmt_count	@@prepared_stmt_count
-0	0
+select @@max_prepared_stmt_count;
+@@max_prepared_stmt_count
+0
+show status like 'prepared_stmt_count';
+Variable_name	Value
+Prepared_stmt_count	0
 prepare stmt from "select 1";
 ERROR HY000: Unknown error
-select @@prepared_stmt_count;
-@@prepared_stmt_count
-0
+show status like 'prepared_stmt_count';
+Variable_name	Value
+Prepared_stmt_count	0
 set global max_prepared_stmt_count=1;
 prepare stmt from "select 1";
-select @@prepared_stmt_count;
-@@prepared_stmt_count
-1
+show status like 'prepared_stmt_count';
+Variable_name	Value
+Prepared_stmt_count	1
 prepare stmt1 from "select 1";
 ERROR HY000: Unknown error
-select @@prepared_stmt_count;
-@@prepared_stmt_count
-1
+show status like 'prepared_stmt_count';
+Variable_name	Value
+Prepared_stmt_count	1
 deallocate prepare stmt;
-select @@prepared_stmt_count;
-@@prepared_stmt_count
-0
+show status like 'prepared_stmt_count';
+Variable_name	Value
+Prepared_stmt_count	0
 prepare stmt from "select 1";
-select @@prepared_stmt_count;
-@@prepared_stmt_count
-1
+show status like 'prepared_stmt_count';
+Variable_name	Value
+Prepared_stmt_count	1
 prepare stmt from "select 2";
-select @@prepared_stmt_count;
-@@prepared_stmt_count
+show status like 'prepared_stmt_count';
+Variable_name	Value
+Prepared_stmt_count	1
+show status like 'prepared_stmt_count';
+Variable_name	Value
+Prepared_stmt_count	1
+select @@max_prepared_stmt_count;
+@@max_prepared_stmt_count
 1
-select @@prepared_stmt_count, @@max_prepared_stmt_count;
-@@prepared_stmt_count	@@max_prepared_stmt_count
-1	1
 set global max_prepared_stmt_count=0;
 prepare stmt from "select 1";
 ERROR HY000: Unknown error
 execute stmt;
 ERROR HY000: Unknown prepared statement handler (stmt) given to EXECUTE
-select @@prepared_stmt_count;
-@@prepared_stmt_count
-0
+show status like 'prepared_stmt_count';
+Variable_name	Value
+Prepared_stmt_count	0
 prepare stmt from "select 1";
 ERROR HY000: Unknown error
-select @@prepared_stmt_count;
-@@prepared_stmt_count
-0
+show status like 'prepared_stmt_count';
+Variable_name	Value
+Prepared_stmt_count	0
 set global max_prepared_stmt_count=3;
-select @@max_prepared_stmt_count, @@prepared_stmt_count;
-@@max_prepared_stmt_count	@@prepared_stmt_count
-3	0
+select @@max_prepared_stmt_count;
+@@max_prepared_stmt_count
+3
+show status like 'prepared_stmt_count';
+Variable_name	Value
+Prepared_stmt_count	0
 prepare stmt from "select 1";
 prepare stmt from "select 2";
 prepare stmt1 from "select 3";
@@ -867,13 +870,13 @@ prepare stmt2 from "select 4";
 ERROR HY000: Unknown error
 prepare stmt2 from "select 4";
 ERROR HY000: Unknown error
-select @@max_prepared_stmt_count, @@prepared_stmt_count;
-@@max_prepared_stmt_count	@@prepared_stmt_count
-3	3
+select @@max_prepared_stmt_count;
+@@max_prepared_stmt_count
+3
+show status like 'prepared_stmt_count';
+Variable_name	Value
+Prepared_stmt_count	3
 deallocate prepare stmt;
-select @@max_prepared_stmt_count, @@prepared_stmt_count;
-@@max_prepared_stmt_count	@@prepared_stmt_count
-3	0
 set global max_prepared_stmt_count= @old_max_prepared_stmt_count;
 drop table if exists t1;
 create temporary table if not exists t1 (a1 int);
diff --git a/mysql-test/t/func_in.test b/mysql-test/t/func_in.test
index 2ffe5a2d5f7e9f1f54237ee045d6afc169f64e4c..ffed2aac2a0c595aa19750bf0c7290475b4ec9bd 100644
--- a/mysql-test/t/func_in.test
+++ b/mysql-test/t/func_in.test
@@ -109,4 +109,24 @@ select count(*) from t1 where id not in (1);
 select count(*) from t1 where id not in (1,2);
 drop table t1;
 
-# End of 4.1 tests
+
+#
+# BUG#17047: CHAR() and IN() can return NULL without signaling NULL
+# result
+#
+# The problem was in the IN() function that ignored maybe_null flags
+# of all arguments except the first (the one _before_ the IN
+# keyword, '1' in the test case below).
+#
+--disable_warnings
+DROP TABLE IF EXISTS t1;
+--enable_warnings
+
+CREATE TABLE t1 SELECT 1 IN (2, NULL);
+--echo SELECT should return NULL.
+SELECT * FROM t1;
+
+DROP TABLE t1;
+
+
+--echo End of 4.1 tests
diff --git a/mysql-test/t/ps.test b/mysql-test/t/ps.test
index 5b488ae439346fa3d6b3a33c02003d3f8f5fd6c5..fbeaaa494e09999520b57476d2342dfcfa4e3300 100644
--- a/mysql-test/t/ps.test
+++ b/mysql-test/t/ps.test
@@ -811,6 +811,9 @@ drop table t1;
 # Bug#16365 Prepared Statements: DoS with too many open statements
 # Check that the limit @@max_prpeared_stmt_count works.
 #
+# This is also the test for bug#23159 prepared_stmt_count should be
+# status variable.
+#
 # Save the old value
 set @old_max_prepared_stmt_count= @@max_prepared_stmt_count;
 #
@@ -820,17 +823,17 @@ set @old_max_prepared_stmt_count= @@max_prepared_stmt_count;
 #
 --disable_ps_protocol
 #
-# A. Check that the new variables are present in SHOW VARIABLES list.
+# A. Check that the new variables are present in SHOW VARIABLES and
+# SHOW STATUS lists.
 #
 show variables like 'max_prepared_stmt_count';
-show variables like 'prepared_stmt_count';
+show status like 'prepared_stmt_count';
 #
-# B. Check that the new variables are selectable.
+# B. Check that the new system variable is selectable.
 #
-select @@max_prepared_stmt_count, @@prepared_stmt_count;
+select @@max_prepared_stmt_count;
 #
-# C. Check that max_prepared_stmt_count is settable (global only),
-#    whereas prepared_stmt_count is readonly.
+# C. Check that max_prepared_stmt_count is settable (global only).
 #
 set global max_prepared_stmt_count=-1;
 select @@max_prepared_stmt_count;
@@ -844,12 +847,6 @@ set @@max_prepared_stmt_count=1;
 set max_prepared_stmt_count=1;
 --error 1229 # ER_GLOBAL_VARIABLE
 set local max_prepared_stmt_count=1;
---error 1229 # ER_GLOBAL_VARIABLE
-set local prepared_stmt_count=0;
---error 1229 # ER_GLOBAL_VARIABLE
-set @@prepared_stmt_count=0;
---error 1232 # ER_WRONG_TYPE_FOR_VAR
-set global prepared_stmt_count=1;
 # set to a reasonable limit works
 set global max_prepared_stmt_count=1;
 select @@max_prepared_stmt_count;
@@ -857,47 +854,50 @@ select @@max_prepared_stmt_count;
 # D. Check that the variables actually work.
 #
 set global max_prepared_stmt_count=0;
-select @@max_prepared_stmt_count, @@prepared_stmt_count;
+select @@max_prepared_stmt_count;
+show status like 'prepared_stmt_count';
 --error 1105 # ER_UNKNOWN_ERROR
 prepare stmt from "select 1";
-select @@prepared_stmt_count;
+show status like 'prepared_stmt_count';
 set global max_prepared_stmt_count=1;
 prepare stmt from "select 1";
-select @@prepared_stmt_count;
+show status like 'prepared_stmt_count';
 --error 1105 # ER_UNKNOWN_ERROR
 prepare stmt1 from "select 1";
-select @@prepared_stmt_count;
+show status like 'prepared_stmt_count';
 deallocate prepare stmt;
-select @@prepared_stmt_count;
+show status like 'prepared_stmt_count';
 #
 # E. Check that we can prepare a statement with the same name 
 # successfully, without hitting the limit.
 #
 prepare stmt from "select 1";
-select @@prepared_stmt_count;
+show status like 'prepared_stmt_count';
 prepare stmt from "select 2";
-select @@prepared_stmt_count;
+show status like 'prepared_stmt_count';
 #
 # F. We can set the max below the current count. In this case no new 
 # statements should be allowed to prepare.
 #
-select @@prepared_stmt_count, @@max_prepared_stmt_count;
+show status like 'prepared_stmt_count';
+select @@max_prepared_stmt_count;
 set global max_prepared_stmt_count=0;
 --error 1105 # ER_UNKNOWN_ERROR
 prepare stmt from "select 1";
 # Result: the old statement is deallocated, the new is not created.
 --error 1243 # ER_UNKNOWN_STMT_HANDLER
 execute stmt;
-select @@prepared_stmt_count;
+show status like 'prepared_stmt_count';
 --error 1105 # ER_UNKNOWN_ERROR
 prepare stmt from "select 1";
-select @@prepared_stmt_count;
+show status like 'prepared_stmt_count';
 #
 # G. Show that the variables are up to date even after a connection with all
 # statements in it was terminated.
 #
 set global max_prepared_stmt_count=3;
-select @@max_prepared_stmt_count, @@prepared_stmt_count;
+select @@max_prepared_stmt_count;
+show status like 'prepared_stmt_count';
 prepare stmt from "select 1";
 connect (con1,localhost,root,,);
 connection con1;
@@ -908,18 +908,11 @@ prepare stmt2 from "select 4";
 connection default;
 --error 1105 # ER_UNKNOWN_ERROR 
 prepare stmt2 from "select 4";
-select @@max_prepared_stmt_count, @@prepared_stmt_count;
+select @@max_prepared_stmt_count;
+show status like 'prepared_stmt_count';
 disconnect con1;
 connection default;
-# Wait for the connection to die: deal with a possible race
 deallocate prepare stmt;
-let $count= `select @@prepared_stmt_count`;
-if ($count)
-{
---sleep 2
-  let $count= `select @@prepared_stmt_count`;
-}
-select @@max_prepared_stmt_count, @@prepared_stmt_count;
 #
 # Restore the old value.
 #
diff --git a/sql/item_cmpfunc.cc b/sql/item_cmpfunc.cc
index 6b6996160a13f6d0d1c373d350ee8fae6684c08a..859b4e0ecc1679f05a3568a2ea3fa70daae1675b 100644
--- a/sql/item_cmpfunc.cc
+++ b/sql/item_cmpfunc.cc
@@ -1998,7 +1998,6 @@ void Item_func_in::fix_length_and_dec()
     if (cmp_type  == STRING_RESULT)
       in_item->cmp_charset= cmp_collation.collation;
   }
-  maybe_null= args[0]->maybe_null;
   max_length= 1;
 }
 
diff --git a/sql/item_sum.cc b/sql/item_sum.cc
index 2c8158b35fda9b58d978ed3ff669b6deb245b638..419efd07615a41576d1bd918a1e56b0376c64b92 100644
--- a/sql/item_sum.cc
+++ b/sql/item_sum.cc
@@ -71,9 +71,13 @@ void Item_sum::make_field(Send_field *tmp_field)
   if (args[0]->type() == Item::FIELD_ITEM && keep_field_type())
   {
     ((Item_field*) args[0])->field->make_field(tmp_field);
-    tmp_field->db_name=(char*)"";
-    tmp_field->org_table_name=tmp_field->table_name=(char*)"";
-    tmp_field->org_col_name=tmp_field->col_name=name;
+    /* For expressions only col_name should be non-empty string. */
+    char *empty_string= (char*)"";
+    tmp_field->db_name= empty_string;
+    tmp_field->org_table_name= empty_string;
+    tmp_field->table_name= empty_string;
+    tmp_field->org_col_name= empty_string;
+    tmp_field->col_name= name;
     if (maybe_null)
       tmp_field->flags&= ~NOT_NULL_FLAG;
   }
diff --git a/sql/mysqld.cc b/sql/mysqld.cc
index 6571717b61df046f6a0e15e1e24268c59ec2636f..cd0ddc00624a969b2343dc66a30971c0a3c4ef79 100644
--- a/sql/mysqld.cc
+++ b/sql/mysqld.cc
@@ -5733,6 +5733,7 @@ struct show_var_st status_vars[]= {
   {"Open_streams",             (char*) &my_stream_opened,       SHOW_LONG_CONST},
   {"Open_tables",              (char*) 0,                       SHOW_OPENTABLES},
   {"Opened_tables",            (char*) &opened_tables,          SHOW_LONG},
+  {"Prepared_stmt_count",      (char*) &prepared_stmt_count,    SHOW_LONG_CONST},
 #ifdef HAVE_QUERY_CACHE
   {"Qcache_free_blocks",       (char*) &query_cache.free_memory_blocks,
    SHOW_LONG_CONST},
@@ -5903,6 +5904,7 @@ static void mysql_init_variables(void)
   binlog_cache_use=  binlog_cache_disk_use= 0;
   max_used_connections= slow_launch_threads = 0;
   mysqld_user= mysqld_chroot= opt_init_file= opt_bin_logname = 0;
+  prepared_stmt_count= 0;
   errmesg= 0;
   mysqld_unix_port= opt_mysql_tmpdir= my_bind_addr_str= NullS;
   bzero((gptr) &mysql_tmpdir_list, sizeof(mysql_tmpdir_list));
diff --git a/sql/set_var.cc b/sql/set_var.cc
index 4433b6bf7d809a1872d219079387e2e156be0f4a..71ca382f9d95085cffb525e98dbf863cf080b21c 100644
--- a/sql/set_var.cc
+++ b/sql/set_var.cc
@@ -119,7 +119,6 @@ static KEY_CACHE *create_key_cache(const char *name, uint length);
 void fix_sql_mode_var(THD *thd, enum_var_type type);
 static byte *get_error_count(THD *thd);
 static byte *get_warning_count(THD *thd);
-static byte *get_prepared_stmt_count(THD *thd);
 static byte *get_have_innodb(THD *thd);
 
 /*
@@ -482,9 +481,6 @@ static sys_var_readonly		sys_warning_count("warning_count",
 						  OPT_SESSION,
 						  SHOW_LONG,
 						  get_warning_count);
-static sys_var_readonly	sys_prepared_stmt_count("prepared_stmt_count",
-                                                OPT_GLOBAL, SHOW_LONG,
-                                                get_prepared_stmt_count);
 
 /* alias for last_insert_id() to be compatible with Sybase */
 #ifdef HAVE_REPLICATION
@@ -604,7 +600,6 @@ sys_var *sys_variables[]=
   &sys_new_mode,
   &sys_old_passwords,
   &sys_preload_buff_size,
-  &sys_prepared_stmt_count,
   &sys_pseudo_thread_id,
   &sys_query_alloc_block_size,
   &sys_query_cache_size,
@@ -860,7 +855,6 @@ struct show_var_st init_vars[]= {
   {"pid_file",                (char*) pidfile_name,                 SHOW_CHAR},
   {"port",                    (char*) &mysqld_port,                  SHOW_INT},
   {sys_preload_buff_size.name, (char*) &sys_preload_buff_size,      SHOW_SYS},
-  {sys_prepared_stmt_count.name, (char*) &sys_prepared_stmt_count, SHOW_SYS},
   {"protocol_version",        (char*) &protocol_version,            SHOW_INT},
   {sys_query_alloc_block_size.name, (char*) &sys_query_alloc_block_size,
    SHOW_SYS},
@@ -2715,14 +2709,6 @@ static byte *get_have_innodb(THD *thd)
 }
 
 
-static byte *get_prepared_stmt_count(THD *thd)
-{
-  pthread_mutex_lock(&LOCK_prepared_stmt_count);
-  thd->sys_var_tmp.ulong_value= prepared_stmt_count;
-  pthread_mutex_unlock(&LOCK_prepared_stmt_count);
-  return (byte*) &thd->sys_var_tmp.ulong_value;
-}
-
 /****************************************************************************
   Main handling of variables:
   - Initialisation
diff --git a/tests/mysql_client_test.c b/tests/mysql_client_test.c
index b1ee144e5173f68789634dbff64be55ac312cc9b..98d7182d46f96d7f7ed9cb7c6c86496decb3e665 100644
--- a/tests/mysql_client_test.c
+++ b/tests/mysql_client_test.c
@@ -11949,6 +11949,150 @@ static void test_bug21726()
 }
 
 
+/*
+  BUG#23383: mysql_affected_rows() returns different values than
+  mysql_stmt_affected_rows()
+
+  Test that both mysql_affected_rows() and mysql_stmt_affected_rows()
+  return -1 on error, 0 when no rows were affected, and (positive) row
+  count when some rows were affected.
+*/
+static void test_bug23383()
+{
+  const char *insert_query= "INSERT INTO t1 VALUES (1), (2)";
+  const char *update_query= "UPDATE t1 SET i= 4 WHERE i = 3";
+  MYSQL_STMT *stmt;
+  my_ulonglong row_count;
+  int rc;
+
+  DBUG_ENTER("test_bug23383");
+  myheader("test_bug23383");
+
+  rc= mysql_query(mysql, "DROP TABLE IF EXISTS t1");
+  myquery(rc);
+
+  rc= mysql_query(mysql, "CREATE TABLE t1 (i INT UNIQUE)");
+  myquery(rc);
+
+  rc= mysql_query(mysql, insert_query);
+  myquery(rc);
+  row_count= mysql_affected_rows(mysql);
+  DIE_UNLESS(row_count == 2);
+
+  rc= mysql_query(mysql, insert_query);
+  DIE_UNLESS(rc != 0);
+  row_count= mysql_affected_rows(mysql);
+  DIE_UNLESS(row_count == (my_ulonglong)-1);
+
+  rc= mysql_query(mysql, update_query);
+  myquery(rc);
+  row_count= mysql_affected_rows(mysql);
+  DIE_UNLESS(row_count == 0);
+
+  rc= mysql_query(mysql, "DELETE FROM t1");
+  myquery(rc);
+
+  stmt= mysql_stmt_init(mysql);
+  DIE_UNLESS(stmt != 0);
+
+  rc= mysql_stmt_prepare(stmt, insert_query, strlen(insert_query));
+  check_execute(stmt, rc);
+
+  rc= mysql_stmt_execute(stmt);
+  check_execute(stmt, rc);
+  row_count= mysql_stmt_affected_rows(stmt);
+  DIE_UNLESS(row_count == 2);
+
+  rc= mysql_stmt_execute(stmt);
+  DIE_UNLESS(rc != 0);
+  row_count= mysql_stmt_affected_rows(stmt);
+  DIE_UNLESS(row_count == (my_ulonglong)-1);
+
+  rc= mysql_stmt_prepare(stmt, update_query, strlen(update_query));
+  check_execute(stmt, rc);
+
+  rc= mysql_stmt_execute(stmt);
+  check_execute(stmt, rc);
+  row_count= mysql_stmt_affected_rows(stmt);
+  DIE_UNLESS(row_count == 0);
+
+  rc= mysql_stmt_close(stmt);
+  check_execute(stmt, rc);
+
+  rc= mysql_query(mysql, "DROP TABLE t1");
+  myquery(rc);
+
+  DBUG_VOID_RETURN;
+}
+
+
+/*
+  BUG#21635: MYSQL_FIELD struct's member strings seem to misbehave for
+  expression cols
+
+  Check that for MIN(), MAX(), COUNT() only MYSQL_FIELD::name is set
+  to either expression or its alias, and db, org_table, table,
+  org_name fields are empty strings.
+*/
+static void test_bug21635()
+{
+  const char *expr[]=
+  {
+    "MIN(i)", "MIN(i)",
+    "MIN(i) AS A1", "A1",
+    "MAX(i)", "MAX(i)",
+    "MAX(i) AS A2", "A2",
+    "COUNT(i)", "COUNT(i)",
+    "COUNT(i) AS A3", "A3",
+  };
+  char *query_end;
+  MYSQL_RES *result;
+  MYSQL_FIELD *field;
+  unsigned int field_count, i;
+  int rc;
+
+  DBUG_ENTER("test_bug21635");
+  myheader("test_bug21635");
+
+  query_end= strxmov(query, "SELECT ", NullS);
+  for (i= 0; i < sizeof(expr) / sizeof(*expr) / 2; ++i)
+    query_end= strxmov(query_end, expr[i * 2], ", ", NullS);
+  query_end= strxmov(query_end - 2, " FROM t1 GROUP BY i", NullS);
+  DIE_UNLESS(query_end - query < MAX_TEST_QUERY_LENGTH);
+
+  rc= mysql_query(mysql, "DROP TABLE IF EXISTS t1");
+  myquery(rc);
+  rc= mysql_query(mysql, "CREATE TABLE t1 (i INT)");
+  myquery(rc);
+  rc= mysql_query(mysql, "INSERT INTO t1 VALUES (1)");
+  myquery(rc);
+
+  rc= mysql_real_query(mysql, query, query_end - query);
+  myquery(rc);
+
+  result= mysql_use_result(mysql);
+  DIE_UNLESS(result);
+
+  field_count= mysql_field_count(mysql);
+  for (i= 0; i < field_count; ++i)
+  {
+    field= mysql_fetch_field_direct(result, i);
+    printf("%s -> %s ... ", expr[i * 2], field->name);
+    fflush(stdout);
+    DIE_UNLESS(field->db[0] == 0 && field->org_table[0] == 0 &&
+               field->table[0] == 0 && field->org_name[0] == 0);
+    DIE_UNLESS(strcmp(field->name, expr[i * 2 + 1]) == 0);
+    puts("OK");
+  }
+
+  mysql_free_result(result);
+  rc= mysql_query(mysql, "DROP TABLE t1");
+  myquery(rc);
+
+  DBUG_VOID_RETURN;
+}
+
+
 /*
   Read and parse arguments and MySQL options from my.cnf
 */
@@ -12176,6 +12320,8 @@ static struct my_tests_st my_tests[]= {
   { "test_bug15613", test_bug15613 },
   { "test_bug20152", test_bug20152 },
   { "test_bug21726", test_bug21726 },
+  { "test_bug23383", test_bug23383 },
+  { "test_bug21635", test_bug21635 },
   { 0, 0 }
 };