diff --git a/client/mysqltest.cc b/client/mysqltest.cc
index 5d173ccd8c0cf6a85cf644519b1f4a20b07b6cfd..ca9217bf4285f917da9e4400a605a1b232155330 100644
--- a/client/mysqltest.cc
+++ b/client/mysqltest.cc
@@ -248,10 +248,14 @@ struct st_connection
   my_bool pending;
 
 #ifdef EMBEDDED_LIBRARY
+  pthread_t tid;
   const char *cur_query;
   int cur_query_len;
-  pthread_mutex_t mutex;
-  pthread_cond_t cond;
+  int command, result;
+  pthread_mutex_t query_mutex;
+  pthread_cond_t query_cond;
+  pthread_mutex_t result_mutex;
+  pthread_cond_t result_cond;
   int query_done;
 #endif /*EMBEDDED_LIBRARY*/
 };
@@ -703,67 +707,148 @@ void handle_no_error(struct st_command*);
 
 #ifdef EMBEDDED_LIBRARY
 
+#define EMB_SEND_QUERY 1
+#define EMB_READ_QUERY_RESULT 2
+#define EMB_END_CONNECTION 3
+
 /* attributes of the query thread */
 pthread_attr_t cn_thd_attrib;
 
+
 /*
-  send_one_query executes query in separate thread, which is
-  necessary in embedded library to run 'send' in proper way.
-  This implementation doesn't handle errors returned
-  by mysql_send_query. It's technically possible, though
-  I don't see where it is needed.
+  This procedure represents the connection and actually
+  runs queries when in the EMBEDDED-SERVER mode.
+  The run_query_normal() just sends request for running
+  mysql_send_query and mysql_read_query_result() here.
 */
-pthread_handler_t send_one_query(void *arg)
+
+pthread_handler_t connection_thread(void *arg)
 {
   struct st_connection *cn= (struct st_connection*)arg;
 
   mysql_thread_init();
-  (void) mysql_send_query(&cn->mysql, cn->cur_query, cn->cur_query_len);
+  while (cn->command != EMB_END_CONNECTION)
+  {
+    if (!cn->command)
+    {
+      pthread_mutex_lock(&cn->query_mutex);
+      while (!cn->command)
+        pthread_cond_wait(&cn->query_cond, &cn->query_mutex);
+      pthread_mutex_unlock(&cn->query_mutex);
+    }
+    switch (cn->command)
+    {
+      case EMB_END_CONNECTION:
+        goto end_thread;
+      case EMB_SEND_QUERY:
+        cn->result= mysql_send_query(&cn->mysql, cn->cur_query, cn->cur_query_len);
+        break;
+      case EMB_READ_QUERY_RESULT:
+        cn->result= mysql_read_query_result(&cn->mysql);
+        break;
+      default:
+        DBUG_ASSERT(0);
+    }
+    cn->command= 0;
+    pthread_mutex_lock(&cn->result_mutex);
+    cn->query_done= 1;
+    pthread_cond_signal(&cn->result_cond);
+    pthread_mutex_unlock(&cn->result_mutex);
+  }
 
-  mysql_thread_end();
-  pthread_mutex_lock(&cn->mutex);
+end_thread:
   cn->query_done= 1;
-  pthread_cond_signal(&cn->cond);
-  pthread_mutex_unlock(&cn->mutex);
+  mysql_thread_end();
   pthread_exit(0);
   return 0;
 }
 
-static int do_send_query(struct st_connection *cn, const char *q, int q_len,
-                         int flags)
+
+static void wait_query_thread_done(struct st_connection *con)
+{
+  DBUG_ASSERT(con->tid);
+  if (!con->query_done)
+  {
+    pthread_mutex_lock(&con->result_mutex);
+    while (!con->query_done)
+      pthread_cond_wait(&con->result_cond, &con->result_mutex);
+    pthread_mutex_unlock(&con->result_mutex);
+  }
+}
+
+
+static void signal_connection_thd(struct st_connection *cn, int command)
 {
-  pthread_t tid;
+  DBUG_ASSERT(cn->tid);
+  cn->query_done= 0;
+  cn->command= command;
+  pthread_mutex_lock(&cn->query_mutex);
+  pthread_cond_signal(&cn->query_cond);
+  pthread_mutex_unlock(&cn->query_mutex);
+}
 
-  if (flags & QUERY_REAP_FLAG)
-    return mysql_send_query(&cn->mysql, q, q_len);
 
-  if (pthread_mutex_init(&cn->mutex, NULL) ||
-      pthread_cond_init(&cn->cond, NULL))
-    die("Error in the thread library");
+/*
+  Sometimes we try to execute queries when the connection is closed.
+  It's done to make sure it was closed completely.
+  So that if our connection is closed (cn->tid == 0), we just return
+  the mysql_send_query() result which is an error in this case.
+*/
 
+static int do_send_query(struct st_connection *cn, const char *q, int q_len)
+{
+  if (!cn->tid)
+    return mysql_send_query(&cn->mysql, q, q_len);
   cn->cur_query= q;
   cn->cur_query_len= q_len;
-  cn->query_done= 0;
-  if (pthread_create(&tid, &cn_thd_attrib, send_one_query, (void*)cn))
-    die("Cannot start new thread for query");
-
+  signal_connection_thd(cn, EMB_SEND_QUERY);
   return 0;
 }
 
-static void wait_query_thread_end(struct st_connection *con)
+
+static int do_read_query_result(struct st_connection *cn)
 {
-  if (!con->query_done)
-  {
-    pthread_mutex_lock(&con->mutex);
-    while (!con->query_done)
-      pthread_cond_wait(&con->cond, &con->mutex);
-    pthread_mutex_unlock(&con->mutex);
-  }
+  DBUG_ASSERT(cn->tid);
+  wait_query_thread_done(cn);
+  signal_connection_thd(cn, EMB_READ_QUERY_RESULT);
+  wait_query_thread_done(cn);
+
+  return cn->result;
+}
+
+
+static void emb_close_connection(struct st_connection *cn)
+{
+  if (!cn->tid)
+    return;
+  wait_query_thread_done(cn);
+  signal_connection_thd(cn, EMB_END_CONNECTION);
+  pthread_join(cn->tid, NULL);
+  cn->tid= 0;
+  pthread_mutex_destroy(&cn->query_mutex);
+  pthread_cond_destroy(&cn->query_cond);
+  pthread_mutex_destroy(&cn->result_mutex);
+  pthread_cond_destroy(&cn->result_cond);
 }
 
+
+static void init_connection_thd(struct st_connection *cn)
+{
+  cn->query_done= 1;
+  cn->command= 0;
+  if (pthread_mutex_init(&cn->query_mutex, NULL) ||
+      pthread_cond_init(&cn->query_cond, NULL) ||
+      pthread_mutex_init(&cn->result_mutex, NULL) ||
+      pthread_cond_init(&cn->result_cond, NULL) ||
+      pthread_create(&cn->tid, &cn_thd_attrib, connection_thread, (void*)cn))
+    die("Error in the thread library");
+}
+
+
 #else /*EMBEDDED_LIBRARY*/
 
-#define do_send_query(cn,q,q_len,flags) mysql_send_query(&cn->mysql, q, q_len)
+#define do_send_query(cn,q,q_len) mysql_send_query(&cn->mysql, q, q_len)
+#define do_read_query_result(cn) mysql_read_query_result(&cn->mysql)
 
 #endif /*EMBEDDED_LIBRARY*/
 
@@ -1106,6 +1191,9 @@ void close_connections()
   DBUG_ENTER("close_connections");
   for (--next_con; next_con >= connections; --next_con)
   {
+#ifdef EMBEDDED_LIBRARY
+    emb_close_connection(next_con);
+#endif
     if (next_con->stmt)
       mysql_stmt_close(next_con->stmt);
     next_con->stmt= 0;
@@ -4866,7 +4954,7 @@ void do_close_connection(struct st_command *command)
     we need to check if the query's thread was finished and probably wait
     (embedded-server specific)
   */
-  wait_query_thread_end(con);
+  emb_close_connection(con);
 #endif /*EMBEDDED_LIBRARY*/
   if (con->stmt)
     mysql_stmt_close(con->stmt);
@@ -5216,8 +5304,9 @@ void do_connect(struct st_command *command)
   }
 
 #ifdef EMBEDDED_LIBRARY
-  con_slot->query_done= 1;
-#endif
+  init_connection_thd(con_slot);
+#endif /*EMBEDDED_LIBRARY*/
+
   if (!mysql_init(&con_slot->mysql))
     die("Failed on mysql_init()");
 
@@ -6768,21 +6857,13 @@ void run_query_normal(struct st_connection *cn, struct st_command *command,
     /*
       Send the query
     */
-    if (do_send_query(cn, query, query_len, flags))
+    if (do_send_query(cn, query, query_len))
     {
       handle_error(command, mysql_errno(mysql), mysql_error(mysql),
 		   mysql_sqlstate(mysql), ds);
       goto end;
     }
   }
-#ifdef EMBEDDED_LIBRARY
-  /*
-    Here we handle 'reap' command, so we need to check if the
-    query's thread was finished and probably wait
-  */
-  else if (flags & QUERY_REAP_FLAG)
-    wait_query_thread_end(cn);
-#endif /*EMBEDDED_LIBRARY*/
   if (!(flags & QUERY_REAP_FLAG))
   {
     cn->pending= TRUE;
@@ -6795,7 +6876,7 @@ void run_query_normal(struct st_connection *cn, struct st_command *command,
       When  on first result set, call mysql_read_query_result to retrieve
       answer to the query sent earlier
     */
-    if ((counter==0) && mysql_read_query_result(mysql))
+    if ((counter==0) && do_read_query_result(cn))
     {
       handle_error(command, mysql_errno(mysql), mysql_error(mysql),
 		   mysql_sqlstate(mysql), ds);
@@ -7970,6 +8051,9 @@ int main(int argc, char **argv)
     ps_protocol_enabled= 1;
 
   st_connection *con= connections;
+#ifdef EMBEDDED_LIBRARY
+  init_connection_thd(con);
+#endif /*EMBEDDED_LIBRARY*/
   if (!( mysql_init(&con->mysql)))
     die("Failed in mysql_init()");
   if (opt_connect_timeout)
diff --git a/cmake/dtrace.cmake b/cmake/dtrace.cmake
index d5566d039133ad3e90ddb04b679a101fde0deaf6..c12a74cba31e265a3a6cf1d6f306008770fc2eeb 100644
--- a/cmake/dtrace.cmake
+++ b/cmake/dtrace.cmake
@@ -13,13 +13,30 @@
 # along with this program; if not, write to the Free Software
 # Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA 
 
+IF(CMAKE_SYSTEM_NAME MATCHES "SunOS" AND CMAKE_COMPILER_IS_GNUCXX
+  AND CMAKE_SIZEOF_VOID_P EQUAL 4)
+  IF(NOT DEFINED BUGGY_GCC_NO_DTRACE_MODULES)
+    EXECUTE_PROCESS(
+      COMMAND ${CMAKE_C_COMPILER} ${CMAKE_C_COMPILER_ARG1}  --version
+      OUTPUT_VARIABLE out)
+    IF(out MATCHES "3.4.6")
+     # This gcc causes crashes in dlopen() for dtraced shared libs,
+     # while standard shipped with Solaris10 3.4.3 is ok
+     SET(BUGGY_GCC_NO_DTRACE_MODULES 1 CACHE INTERNAL "")
+    ELSE()
+     SET(BUGGY_GCC_NO_DTRACE_MODULES 0 CACHE INTERNAL "")
+    ENDIF()
+  ENDIF()
+ENDIF()
+
 # Check if OS supports DTrace
 MACRO(CHECK_DTRACE)
  FIND_PROGRAM(DTRACE dtrace)
  MARK_AS_ADVANCED(DTRACE)
 
  # On FreeBSD, dtrace does not handle userland tracing yet
- IF(DTRACE AND NOT CMAKE_SYSTEM_NAME MATCHES "FreeBSD")
+ IF(DTRACE AND NOT CMAKE_SYSTEM_NAME MATCHES "FreeBSD"
+     AND NOT BUGGY_GCC_NO_DTRACE_MODULES)
    SET(ENABLE_DTRACE ON CACHE BOOL "Enable dtrace")
  ENDIF()
  SET(HAVE_DTRACE ${ENABLE_DTRACE})
@@ -72,22 +89,6 @@ IF(ENABLE_DTRACE)
   ) 
 ENDIF()
 
-IF(CMAKE_SYSTEM_NAME MATCHES "SunOS" AND CMAKE_COMPILER_IS_GNUCXX
-  AND CMAKE_SIZEOF_VOID_P EQUAL 4)
-  IF(NOT DEFINED BUGGY_GCC_NO_DTRACE_MODULES)
-    EXECUTE_PROCESS(
-      COMMAND ${CMAKE_C_COMPILER} ${CMAKE_C_COMPILER_ARG1}  --version
-      OUTPUT_VARIABLE out)
-    IF(out MATCHES "3.4.6")
-     # This gcc causes crashes in dlopen() for dtraced shared libs,
-     # while standard shipped with Solaris10 3.4.3 is ok
-     SET(BUGGY_GCC_NO_DTRACE_MODULES 1 CACHE INTERNAL "")
-    ELSE()
-     SET(BUGGY_GCC_NO_DTRACE_MODULES 0 CACHE INTERNAL "")
-    ENDIF()
-  ENDIF()
-ENDIF()
-
 FUNCTION(DTRACE_INSTRUMENT target)
   IF(BUGGY_GCC_NO_DTRACE_MODULES)
     GET_TARGET_PROPERTY(target_type ${target} TYPE)
diff --git a/libmysqld/lib_sql.cc b/libmysqld/lib_sql.cc
index 94927c590cf8861980bb03babf493ac2a6101174..7d61dbc55f4561b113f18f8f6d635304d2467459 100644
--- a/libmysqld/lib_sql.cc
+++ b/libmysqld/lib_sql.cc
@@ -481,6 +481,10 @@ int init_embedded_server(int argc, char **argv, char **groups)
   char *fake_argv[] = { (char *)"", 0 };
   const char *fake_groups[] = { "server", "embedded", 0 };
   my_bool acl_error;
+
+  if (my_thread_init())
+    return 1;
+
   if (argc)
   {
     argcp= &argc;
diff --git a/mysql-test/r/func_time.result b/mysql-test/r/func_time.result
index 9ba1ae489caeab4e7c947a250c2999e261bc0ed1..f2c26110d8a4ff4774f56a65bc17b99a7b42398e 100644
--- a/mysql-test/r/func_time.result
+++ b/mysql-test/r/func_time.result
@@ -1200,6 +1200,8 @@ set time_zone= @@global.time_zone;
 select str_to_date('10:00 PM', '%h:%i %p') + INTERVAL 10 MINUTE;
 str_to_date('10:00 PM', '%h:%i %p') + INTERVAL 10 MINUTE
 NULL
+Warnings:
+Warning	1411	Incorrect datetime value: '10:00 PM' for function str_to_date
 create table t1 (field DATE);
 insert into t1 values ('2006-11-06');
 select * from t1 where field < '2006-11-06 04:08:36.0';
diff --git a/mysql-test/r/parser.result b/mysql-test/r/parser.result
index 467bb7c5cb83469f89affcd71f4751d4f0890bf1..1ea9e91df8a7da021bc9416988c91dab33d8e410 100644
--- a/mysql-test/r/parser.result
+++ b/mysql-test/r/parser.result
@@ -556,9 +556,13 @@ DROP TABLE IF EXISTS t1;
 SELECT STR_TO_DATE('10:00 PM', '%h:%i %p') + INTERVAL 10 MINUTE;
 STR_TO_DATE('10:00 PM', '%h:%i %p') + INTERVAL 10 MINUTE
 NULL
+Warnings:
+Warning	1411	Incorrect datetime value: '10:00 PM' for function str_to_date
 SELECT STR_TO_DATE('10:00 PM', '%h:%i %p') + INTERVAL (INTERVAL(1,2,3) + 1) MINUTE;
 STR_TO_DATE('10:00 PM', '%h:%i %p') + INTERVAL (INTERVAL(1,2,3) + 1) MINUTE
 NULL
+Warnings:
+Warning	1411	Incorrect datetime value: '10:00 PM' for function str_to_date
 SELECT "1997-12-31 23:59:59" + INTERVAL 1 SECOND;
 "1997-12-31 23:59:59" + INTERVAL 1 SECOND
 1998-01-01 00:00:00
diff --git a/mysql-test/r/select.result b/mysql-test/r/select.result
index e8628d72a46b0f0433124833549c7e17bb216736..b1e0f30668dc767063465f58ca42574cf3f84a91 100644
--- a/mysql-test/r/select.result
+++ b/mysql-test/r/select.result
@@ -4171,9 +4171,10 @@ str_to_date('2007-10-00','%Y-%m-%d') between '2007/09/01 00:00:00'
 set SQL_MODE=TRADITIONAL;
 select str_to_date('2007-10-00 12:34','%Y-%m-%d %H:%i') = '2007-10-00 12:34';
 str_to_date('2007-10-00 12:34','%Y-%m-%d %H:%i') = '2007-10-00 12:34'
-0
+NULL
 Warnings:
 Warning	1292	Truncated incorrect datetime value: '2007-10-00 12:34'
+Warning	1411	Incorrect datetime value: '2007-10-00 12:34' for function str_to_date
 select str_to_date('2007-10-01 12:34','%Y-%m-%d %H:%i') = '2007-10-00 12:34';
 str_to_date('2007-10-01 12:34','%Y-%m-%d %H:%i') = '2007-10-00 12:34'
 0
@@ -4181,17 +4182,16 @@ Warnings:
 Warning	1292	Truncated incorrect datetime value: '2007-10-00 12:34'
 select str_to_date('2007-10-00 12:34','%Y-%m-%d %H:%i') = '2007-10-01 12:34';
 str_to_date('2007-10-00 12:34','%Y-%m-%d %H:%i') = '2007-10-01 12:34'
-0
+NULL
 Warnings:
-Warning	1292	Truncated incorrect datetime value: '2007-10-00 12:34:00'
+Warning	1411	Incorrect datetime value: '2007-10-00 12:34' for function str_to_date
 select str_to_date('2007-10-00','%Y-%m-%d') between '2007/09/01'
                                                 and '2007/10/20';
 str_to_date('2007-10-00','%Y-%m-%d') between '2007/09/01'
                                                 and '2007/10/20'
-0
+NULL
 Warnings:
-Warning	1292	Incorrect datetime value: '2007-10-00' for column '2007/09/01' at row 1
-Warning	1292	Incorrect datetime value: '2007-10-00' for column '2007/10/20' at row 1
+Warning	1411	Incorrect datetime value: '2007-10-00' for function str_to_date
 set SQL_MODE=DEFAULT;
 select str_to_date('2007-10-00','%Y-%m-%d') between '' and '2007/10/20';
 str_to_date('2007-10-00','%Y-%m-%d') between '' and '2007/10/20'
diff --git a/mysql-test/r/strict.result b/mysql-test/r/strict.result
index 79f8c20a150021c47a804f0f46ce6e50b01a1460..872bfdc48730a748e4a303c2cdd431648ed38caf 100644
--- a/mysql-test/r/strict.result
+++ b/mysql-test/r/strict.result
@@ -206,12 +206,11 @@ INSERT INTO t1 (col1) VALUES (STR_TO_DATE('15.10.2004','%d.%m.%Y'));
 INSERT INTO t1 (col2) VALUES (STR_TO_DATE('15.10.2004 10.15','%d.%m.%Y %H.%i'));
 INSERT INTO t1 (col3) VALUES (STR_TO_DATE('15.10.2004 10.15','%d.%m.%Y %H.%i'));
 INSERT INTO t1 (col1) VALUES(STR_TO_DATE('31.10.0000 15.30','%d.%m.%Y %H.%i'));
-Warnings:
-Note	1265	Data truncated for column 'col1' at row 1
+ERROR HY000: Incorrect datetime value: '31.10.0000 15.30' for function str_to_date
 INSERT INTO t1 (col1) VALUES(STR_TO_DATE('31.0.2004 15.30','%d.%m.%Y %H.%i'));
-ERROR 22007: Incorrect date value: '2004-00-31 15:30:00' for column 'col1' at row 1
+ERROR HY000: Incorrect datetime value: '31.0.2004 15.30' for function str_to_date
 INSERT INTO t1 (col1) VALUES(STR_TO_DATE('0.10.2004 15.30','%d.%m.%Y %H.%i'));
-ERROR 22007: Incorrect date value: '2004-10-00 15:30:00' for column 'col1' at row 1
+ERROR HY000: Incorrect datetime value: '0.10.2004 15.30' for function str_to_date
 INSERT INTO t1 (col1) VALUES(STR_TO_DATE('31.9.2004 15.30','%d.%m.%Y %H.%i'));
 ERROR 22007: Incorrect date value: '2004-09-31 15:30:00' for column 'col1' at row 1
 INSERT INTO t1 (col1) VALUES(STR_TO_DATE('32.10.2004 15.30','%d.%m.%Y %H.%i'));
@@ -221,12 +220,13 @@ ERROR 22007: Incorrect date value: '2003-02-29 15:30:00' for column 'col1' at ro
 INSERT INTO t1 (col1) VALUES(STR_TO_DATE('15.13.2004 15.30','%d.%m.%Y %H.%i'));
 ERROR HY000: Incorrect datetime value: '15.13.2004 15.30' for function str_to_date
 INSERT INTO t1 (col1) VALUES(STR_TO_DATE('00.00.0000','%d.%m.%Y'));
-ERROR 22007: Incorrect date value: '0000-00-00' for column 'col1' at row 1
+ERROR HY000: Incorrect datetime value: '00.00.0000' for function str_to_date
 INSERT INTO t1 (col2) VALUES(STR_TO_DATE('31.10.0000 15.30','%d.%m.%Y %H.%i'));
+ERROR HY000: Incorrect datetime value: '31.10.0000 15.30' for function str_to_date
 INSERT INTO t1 (col2) VALUES(STR_TO_DATE('31.0.2004 15.30','%d.%m.%Y %H.%i'));
-ERROR 22007: Incorrect datetime value: '2004-00-31 15:30:00' for column 'col2' at row 1
+ERROR HY000: Incorrect datetime value: '31.0.2004 15.30' for function str_to_date
 INSERT INTO t1 (col2) VALUES(STR_TO_DATE('0.10.2004 15.30','%d.%m.%Y %H.%i'));
-ERROR 22007: Incorrect datetime value: '2004-10-00 15:30:00' for column 'col2' at row 1
+ERROR HY000: Incorrect datetime value: '0.10.2004 15.30' for function str_to_date
 INSERT INTO t1 (col2) VALUES(STR_TO_DATE('31.9.2004 15.30','%d.%m.%Y %H.%i'));
 ERROR 22007: Incorrect datetime value: '2004-09-31 15:30:00' for column 'col2' at row 1
 INSERT INTO t1 (col2) VALUES(STR_TO_DATE('32.10.2004 15.30','%d.%m.%Y %H.%i'));
@@ -236,13 +236,13 @@ ERROR 22007: Incorrect datetime value: '2003-02-29 15:30:00' for column 'col2' a
 INSERT INTO t1 (col2) VALUES(STR_TO_DATE('15.13.2004 15.30','%d.%m.%Y %H.%i'));
 ERROR HY000: Incorrect datetime value: '15.13.2004 15.30' for function str_to_date
 INSERT INTO t1 (col2) VALUES(STR_TO_DATE('00.00.0000','%d.%m.%Y'));
-ERROR 22007: Incorrect datetime value: '0000-00-00' for column 'col2' at row 1
+ERROR HY000: Incorrect datetime value: '00.00.0000' for function str_to_date
 INSERT INTO t1 (col3) VALUES(STR_TO_DATE('31.10.0000 15.30','%d.%m.%Y %H.%i'));
-ERROR 22007: Incorrect datetime value: '0000-10-31 15:30:00' for column 'col3' at row 1
+ERROR HY000: Incorrect datetime value: '31.10.0000 15.30' for function str_to_date
 INSERT INTO t1 (col3) VALUES(STR_TO_DATE('31.0.2004 15.30','%d.%m.%Y %H.%i'));
-ERROR 22007: Incorrect datetime value: '2004-00-31 15:30:00' for column 'col3' at row 1
+ERROR HY000: Incorrect datetime value: '31.0.2004 15.30' for function str_to_date
 INSERT INTO t1 (col3) VALUES(STR_TO_DATE('0.10.2004 15.30','%d.%m.%Y %H.%i'));
-ERROR 22007: Incorrect datetime value: '2004-10-00 15:30:00' for column 'col3' at row 1
+ERROR HY000: Incorrect datetime value: '0.10.2004 15.30' for function str_to_date
 INSERT INTO t1 (col3) VALUES(STR_TO_DATE('31.9.2004 15.30','%d.%m.%Y %H.%i'));
 ERROR 22007: Incorrect datetime value: '2004-09-31 15:30:00' for column 'col3' at row 1
 INSERT INTO t1 (col3) VALUES(STR_TO_DATE('32.10.2004 15.30','%d.%m.%Y %H.%i'));
@@ -252,7 +252,7 @@ ERROR 22007: Incorrect datetime value: '2003-02-29 15:30:00' for column 'col3' a
 INSERT INTO t1 (col3) VALUES(STR_TO_DATE('15.13.2004 15.30','%d.%m.%Y %H.%i'));
 ERROR HY000: Incorrect datetime value: '15.13.2004 15.30' for function str_to_date
 INSERT INTO t1 (col3) VALUES(STR_TO_DATE('00.00.0000','%d.%m.%Y'));
-ERROR 22007: Incorrect datetime value: '0000-00-00' for column 'col3' at row 1
+ERROR HY000: Incorrect datetime value: '00.00.0000' for function str_to_date
 drop table t1;
 CREATE TABLE t1 (col1 date, col2 datetime, col3 timestamp);
 INSERT INTO t1 (col1) VALUES (CAST('2004-10-15' AS DATE));
@@ -1108,6 +1108,9 @@ Warnings:
 Warning	1411	Incorrect datetime value: '2004.12.12 10:22:61' for function str_to_date
 Warning	1411	Incorrect datetime value: '2004.12.12 10:22:61' for function str_to_date
 Warning	1411	Incorrect datetime value: '2004.12.12 10:22:61' for function str_to_date
+Warning	1411	Incorrect datetime value: '2004.12.12 10:22:61' for function str_to_date
+Warning	1411	Incorrect datetime value: '2004.12.12 10:22:61' for function str_to_date
+Warning	1411	Incorrect datetime value: '2004.12.12 10:22:61' for function str_to_date
 drop table t1;
 create table t1 (col1 char(3), col2 integer);
 insert into t1 (col1) values (cast(1000 as char(3)));
diff --git a/mysql-test/r/type_datetime.result b/mysql-test/r/type_datetime.result
index a054659abe94975a86277a5819563babd1a85bbe..f7bfba0accd5adb6098a2c2ce188d1f9ae387d88 100644
--- a/mysql-test/r/type_datetime.result
+++ b/mysql-test/r/type_datetime.result
@@ -655,5 +655,30 @@ Note	1003	select `test`.`t1`.`Id` AS `Id`,`test`.`t1`.`AtTime` AS `AtTime` from
 DROP TABLE t1;
 SET NAMES latin1;
 #
+# Bug#56271: Wrong comparison result with STR_TO_DATE function
+#
+CREATE TABLE t1 (
+`year` int(4) NOT NULL,
+`month` int(2) NOT NULL
+);
+INSERT INTO t1 VALUES (2010,3),(2010,4),(2009,8),(2008,9);
+SELECT *
+FROM t1
+WHERE STR_TO_DATE(CONCAT_WS('/01/',`month`,`year`), '%m/%d/%Y') >=
+STR_TO_DATE('1/1/2010', '%m/%d/%Y');
+year	month
+2010	3
+2010	4
+create table t2(f1 datetime primary key);
+insert into t2 select STR_TO_DATE(CONCAT_WS('/01/',`month`,`year`), '%m/%d/%Y') from t1;
+select * from t2 where f1=STR_TO_DATE('4/1/2010', '%m/%d/%Y');
+f1
+2010-04-01 00:00:00
+t2 should be const
+explain select * from t2 where f1=STR_TO_DATE('4/1/2010', '%m/%d/%Y');
+id	select_type	table	type	possible_keys	key	key_len	ref	rows	Extra
+1	SIMPLE	t2	const	PRIMARY	PRIMARY	8	const	1	Using index
+DROP TABLE t1,t2;
+#
 # End of 5.5 tests
 #
diff --git a/mysql-test/suite/rpl/t/disabled.def b/mysql-test/suite/rpl/t/disabled.def
index f864139495ab66e33bf73ebdd3a08ff7a6873c90..2ed7e087667cdb348edb94c0f7735afe71b15274 100644
--- a/mysql-test/suite/rpl/t/disabled.def
+++ b/mysql-test/suite/rpl/t/disabled.def
@@ -11,7 +11,6 @@
 ##############################################################################
 
 rpl_failed_optimize       : WL#4284: Can't optimize table used by a pending transaction (there is metadata lock on the table).
-rpl_plugin_load           : Bug#55966 2010-08-13 alik "plugin" tests fail in 5.5
 rpl_read_only             : WL#4284: Setting Read only won't succeed until all metadata locks are released.
 rpl_row_create_table      : Bug#51574 2010-02-27 andrei failed different way than earlier with bug#45576
 rpl_spec_variables        : BUG#47661 2009-10-27 jasonh rpl_spec_variables fails on PB2 hpux
diff --git a/mysql-test/t/disabled.def b/mysql-test/t/disabled.def
index 1684201603721c720c0767b229f155acd8203c21..d35d612f93c09e046fef3799bc8a7135c711ef96 100644
--- a/mysql-test/t/disabled.def
+++ b/mysql-test/t/disabled.def
@@ -14,9 +14,6 @@ lowercase_table3         : Bug#54845 2010-06-30 alik main.lowercase_table3 on Ma
 mysqlhotcopy_myisam      : Bug#54129 2010-08-31 alik mysqlhotcopy* fails
 mysqlhotcopy_archive     : Bug#54129 2010-08-31 alik mysqlhotcopy* fails
 partition_innodb_plugin  : Bug#53307 2010-04-30 VasilDimov valgrind warnings
-plugin                   : Bug#55966 2010-08-13 alik "plugin" tests fail in 5.5
-plugin_load              : Bug#55966 2010-08-13 alik "plugin" tests fail in 5.5
-plugin_not_embedded      : Bug#55966 2010-08-13 alik "plugin" tests fail in 5.5
 query_cache_28249        : Bug#43861 2009-03-25 main.query_cache_28249 fails sporadically
 sp_sync                  : Bug#48157 2010-02-06 5.5-m3 demands a differnt solution
 ctype_utf8mb4_ndb	: Bug#55799, Bug#51907, disabled by Konstantin 2010-08-06
diff --git a/mysql-test/t/strict.test b/mysql-test/t/strict.test
index 0dd324d5df2a8ec94867336515f80a8642733018..fc522a69a3c9512e5343d23001b0c7574378a266 100644
--- a/mysql-test/t/strict.test
+++ b/mysql-test/t/strict.test
@@ -192,11 +192,11 @@ INSERT INTO t1 (col3) VALUES (STR_TO_DATE('15.10.2004 10.15','%d.%m.%Y %H.%i'));
 #       All test cases expected to fail should return 
 #       SQLSTATE 22007 <invalid date value>
 
+--error 1411
 INSERT INTO t1 (col1) VALUES(STR_TO_DATE('31.10.0000 15.30','%d.%m.%Y %H.%i'));
-
---error 1292
+--error 1411
 INSERT INTO t1 (col1) VALUES(STR_TO_DATE('31.0.2004 15.30','%d.%m.%Y %H.%i'));
---error 1292
+--error 1411
 INSERT INTO t1 (col1) VALUES(STR_TO_DATE('0.10.2004 15.30','%d.%m.%Y %H.%i'));
 --error 1292
 INSERT INTO t1 (col1) VALUES(STR_TO_DATE('31.9.2004 15.30','%d.%m.%Y %H.%i'));
@@ -206,18 +206,18 @@ INSERT INTO t1 (col1) VALUES(STR_TO_DATE('32.10.2004 15.30','%d.%m.%Y %H.%i'));
 INSERT INTO t1 (col1) VALUES(STR_TO_DATE('29.02.2003 15.30','%d.%m.%Y %H.%i'));
 --error 1411
 INSERT INTO t1 (col1) VALUES(STR_TO_DATE('15.13.2004 15.30','%d.%m.%Y %H.%i'));
---error 1292
+--error 1411
 INSERT INTO t1 (col1) VALUES(STR_TO_DATE('00.00.0000','%d.%m.%Y'));
 
 ## Test INSERT with STR_TO_DATE into DATETIME
 #       All test cases expected to fail should return 
 #       SQLSTATE 22007 <invalid datetime value>
 
+--error 1411
 INSERT INTO t1 (col2) VALUES(STR_TO_DATE('31.10.0000 15.30','%d.%m.%Y %H.%i'));
-
---error 1292
+--error 1411
 INSERT INTO t1 (col2) VALUES(STR_TO_DATE('31.0.2004 15.30','%d.%m.%Y %H.%i'));
---error 1292
+--error 1411
 INSERT INTO t1 (col2) VALUES(STR_TO_DATE('0.10.2004 15.30','%d.%m.%Y %H.%i'));
 --error 1292
 INSERT INTO t1 (col2) VALUES(STR_TO_DATE('31.9.2004 15.30','%d.%m.%Y %H.%i'));
@@ -227,18 +227,18 @@ INSERT INTO t1 (col2) VALUES(STR_TO_DATE('32.10.2004 15.30','%d.%m.%Y %H.%i'));
 INSERT INTO t1 (col2) VALUES(STR_TO_DATE('29.02.2003 15.30','%d.%m.%Y %H.%i'));
 --error 1411
 INSERT INTO t1 (col2) VALUES(STR_TO_DATE('15.13.2004 15.30','%d.%m.%Y %H.%i'));
---error 1292
+--error 1411
 INSERT INTO t1 (col2) VALUES(STR_TO_DATE('00.00.0000','%d.%m.%Y'));
 
 ## Test INSERT with STR_TO_DATE into TIMESTAMP
 #       All test cases expected to fail should return 
 #       SQLSTATE 22007 <invalid datetime value>
 
---error 1292
+--error 1411
 INSERT INTO t1 (col3) VALUES(STR_TO_DATE('31.10.0000 15.30','%d.%m.%Y %H.%i'));
---error 1292
+--error 1411
 INSERT INTO t1 (col3) VALUES(STR_TO_DATE('31.0.2004 15.30','%d.%m.%Y %H.%i'));
---error 1292
+--error 1411
 INSERT INTO t1 (col3) VALUES(STR_TO_DATE('0.10.2004 15.30','%d.%m.%Y %H.%i'));
 --error 1292
 INSERT INTO t1 (col3) VALUES(STR_TO_DATE('31.9.2004 15.30','%d.%m.%Y %H.%i'));
@@ -248,7 +248,7 @@ INSERT INTO t1 (col3) VALUES(STR_TO_DATE('32.10.2004 15.30','%d.%m.%Y %H.%i'));
 INSERT INTO t1 (col3) VALUES(STR_TO_DATE('29.02.2003 15.30','%d.%m.%Y %H.%i'));
 --error 1411
 INSERT INTO t1 (col3) VALUES(STR_TO_DATE('15.13.2004 15.30','%d.%m.%Y %H.%i'));
---error 1292
+--error 1411
 INSERT INTO t1 (col3) VALUES(STR_TO_DATE('00.00.0000','%d.%m.%Y'));
 
 drop table t1;
diff --git a/mysql-test/t/type_datetime.test b/mysql-test/t/type_datetime.test
index e607823764bb14ef7dfd75ff3ade32b260e84602..6e40c9ccfa0aea9e4cfb722953644f04dd647e59 100644
--- a/mysql-test/t/type_datetime.test
+++ b/mysql-test/t/type_datetime.test
@@ -461,6 +461,29 @@ EXPLAIN EXTENDED SELECT * FROM t1 FORCE INDEX(attime) WHERE AtTime = '2010-02-22
 DROP TABLE t1;
 SET NAMES latin1;
 
+--echo #
+--echo # Bug#56271: Wrong comparison result with STR_TO_DATE function
+--echo #
+CREATE TABLE t1 (
+  `year` int(4) NOT NULL,
+  `month` int(2) NOT NULL
+);
+
+INSERT INTO t1 VALUES (2010,3),(2010,4),(2009,8),(2008,9);
+
+SELECT *
+FROM t1
+WHERE STR_TO_DATE(CONCAT_WS('/01/',`month`,`year`), '%m/%d/%Y') >=
+STR_TO_DATE('1/1/2010', '%m/%d/%Y');
+
+create table t2(f1 datetime primary key);
+insert into t2 select STR_TO_DATE(CONCAT_WS('/01/',`month`,`year`), '%m/%d/%Y') from t1;
+select * from t2 where f1=STR_TO_DATE('4/1/2010', '%m/%d/%Y');
+--echo t2 should be const
+explain select * from t2 where f1=STR_TO_DATE('4/1/2010', '%m/%d/%Y');
+
+DROP TABLE t1,t2;
+
 --echo #
 --echo # End of 5.5 tests
 --echo #
diff --git a/mysys/my_gethwaddr.c b/mysys/my_gethwaddr.c
index 9ca22f2201e78d8d0e1482c0c08dd0b382e4c32d..d14087d061ecb9b9be8b6c67ab0f3b0e284e8c59 100644
--- a/mysys/my_gethwaddr.c
+++ b/mysys/my_gethwaddr.c
@@ -64,7 +64,7 @@ my_bool my_gethwaddr(uchar *to)
     if (ifm->ifm_type == RTM_IFINFO)
     {
       sdl = (struct sockaddr_dl *)(ifm + 1);
-      addr=LLADDR(sdl);
+      addr=(uchar *)LLADDR(sdl);
       res=memcpy_and_test(to, addr, ETHER_ADDR_LEN);
     }
   }
diff --git a/mysys/my_sync.c b/mysys/my_sync.c
index 6497ae59159e4ff5b6ae094ef8ce5110cb119a60..bc050922ffcfb42c29f4367bfd54c3302573cb31 100644
--- a/mysys/my_sync.c
+++ b/mysys/my_sync.c
@@ -100,9 +100,9 @@ static const char cur_dir_name[]= {FN_CURLIB, 0};
   RETURN
     0 if ok, !=0 if error
 */
+#ifdef NEED_EXPLICIT_SYNC_DIR
 int my_sync_dir(const char *dir_name, myf my_flags)
 {
-#ifdef NEED_EXPLICIT_SYNC_DIR
   File dir_fd;
   int res= 0;
   const char *correct_dir_name;
@@ -124,10 +124,14 @@ int my_sync_dir(const char *dir_name, myf my_flags)
   else
     res= 1;
   DBUG_RETURN(res);
-#else
+}
+#else /* NEED_EXPLICIT_SYNC_DIR */
+int my_sync_dir(const char *dir_name __attribute__((unused)),
+		myf my_flags __attribute__((unused)))
+{
   return 0;
-#endif
 }
+#endif /* NEED_EXPLICIT_SYNC_DIR */
 
 
 /*
@@ -141,15 +145,18 @@ int my_sync_dir(const char *dir_name, myf my_flags)
   RETURN
     0 if ok, !=0 if error
 */
+#ifdef NEED_EXPLICIT_SYNC_DIR
 int my_sync_dir_by_file(const char *file_name, myf my_flags)
 {
-#ifdef NEED_EXPLICIT_SYNC_DIR
   char dir_name[FN_REFLEN];
   size_t dir_name_length;
   dirname_part(dir_name, file_name, &dir_name_length);
   return my_sync_dir(dir_name, my_flags);
-#else
+}
+#else /* NEED_EXPLICIT_SYNC_DIR */
+int my_sync_dir_by_file(const char *file_name __attribute__((unused)),
+			myf my_flags __attribute__((unused)))
+{
   return 0;
-#endif
 }
-
+#endif /* NEED_EXPLICIT_SYNC_DIR */
diff --git a/sql/derror.cc b/sql/derror.cc
index bf8c589a65faa587bde796403dcd0dbbdeb7a994..db9cd3c0c58b6f0c056b25b421e1b696e0fd46df 100644
--- a/sql/derror.cc
+++ b/sql/derror.cc
@@ -35,6 +35,8 @@ static void init_myfunc_errs(void);
 C_MODE_START
 static const char **get_server_errmsgs()
 {
+  if (!current_thd)
+    return DEFAULT_ERRMSGS;
   return CURRENT_THD_ERRMSGS;
 }
 C_MODE_END
diff --git a/sql/item_timefunc.cc b/sql/item_timefunc.cc
index 1c2c1cfe5120b537774172f3c4dc794e50aef7b0..cc363398fdde7697f4e9ce48dc1cff7db6716e8e 100644
--- a/sql/item_timefunc.cc
+++ b/sql/item_timefunc.cc
@@ -3368,6 +3368,8 @@ void Item_func_str_to_date::fix_length_and_dec()
   cached_field_type= MYSQL_TYPE_DATETIME;
   max_length= MAX_DATETIME_FULL_WIDTH*MY_CHARSET_BIN_MB_MAXLEN;
   cached_timestamp_type= MYSQL_TIMESTAMP_NONE;
+  sql_mode= (current_thd->variables.sql_mode &
+             (MODE_NO_ZERO_IN_DATE | MODE_NO_ZERO_DATE));
   if ((const_item= args[1]->const_item()))
   {
     char format_buff[64];
@@ -3433,6 +3435,14 @@ bool Item_func_str_to_date::get_date(MYSQL_TIME *ltime, uint fuzzy_date)
   return 0;
 
 null_date:
+  if (fuzzy_date & TIME_NO_ZERO_DATE)
+  {
+    char buff[128];
+    strmake(buff, val->ptr(), min(val->length(), sizeof(buff)-1));
+    push_warning_printf(current_thd, MYSQL_ERROR::WARN_LEVEL_WARN,
+                        ER_WRONG_VALUE_FOR_TYPE, ER(ER_WRONG_VALUE_FOR_TYPE),
+                        "datetime", buff, "str_to_date");
+  }
   return (null_value=1);
 }
 
@@ -3442,7 +3452,7 @@ String *Item_func_str_to_date::val_str(String *str)
   DBUG_ASSERT(fixed == 1);
   MYSQL_TIME ltime;
 
-  if (Item_func_str_to_date::get_date(&ltime, TIME_FUZZY_DATE))
+  if (Item_func_str_to_date::get_date(&ltime, TIME_FUZZY_DATE | sql_mode))
     return 0;
 
   if (!make_datetime((const_item ? cached_format_type :
@@ -3453,6 +3463,29 @@ String *Item_func_str_to_date::val_str(String *str)
 }
 
 
+longlong Item_func_str_to_date::val_int()
+{
+  DBUG_ASSERT(fixed == 1);
+  MYSQL_TIME ltime;
+
+  if (Item_func_str_to_date::get_date(&ltime, TIME_FUZZY_DATE | sql_mode))
+    return 0;
+
+  if (const_item)
+  {
+    switch (cached_field_type) {
+    case MYSQL_TYPE_DATE:
+      return TIME_to_ulonglong_date(&ltime);
+    case MYSQL_TYPE_TIME:
+      return TIME_to_ulonglong_time(&ltime);
+    default:
+      return TIME_to_ulonglong_datetime(&ltime);
+    }
+  }
+  return TIME_to_ulonglong_datetime(&ltime);
+}
+
+
 bool Item_func_last_day::get_date(MYSQL_TIME *ltime, uint fuzzy_date)
 {
   if (get_arg0_date(ltime, fuzzy_date & ~TIME_FUZZY_DATE) ||
diff --git a/sql/item_timefunc.h b/sql/item_timefunc.h
index 2c08853fda4dd36c8d77468d24f22af2291ff53e..6e31b5c6705449bbb2fdd53ecb86d91ee3b481a2 100644
--- a/sql/item_timefunc.h
+++ b/sql/item_timefunc.h
@@ -1039,6 +1039,7 @@ class Item_func_str_to_date :public Item_str_func
   date_time_format_types cached_format_type;
   timestamp_type cached_timestamp_type;
   bool const_item;
+  ulonglong sql_mode;
 public:
   Item_func_str_to_date(Item *a, Item *b)
     :Item_str_func(a, b), const_item(false)
@@ -1052,6 +1053,8 @@ public:
   {
     return tmp_table_field_from_field_type(table, 1);
   }
+  longlong val_int();
+  bool result_as_longlong() { return TRUE; }
 };
 
 
diff --git a/sql/mysqld.cc b/sql/mysqld.cc
index 6dd74eb299ae2f1f7c219cdcece479c241e034bd..840616e0e7c8dec871980ac435bfa4d24e5cba02 100644
--- a/sql/mysqld.cc
+++ b/sql/mysqld.cc
@@ -1486,6 +1486,7 @@ void clean_up(bool print_message)
   cleanup_errmsgs();
   MYSQL_CALLBACK(thread_scheduler, end, ());
   finish_client_errs();
+  (void) my_error_unregister(ER_ERROR_FIRST, ER_ERROR_LAST); // finish server errs
   DBUG_PRINT("quit", ("Error messages freed"));
   /* Tell main we are ready */
   logger.cleanup_end();
diff --git a/sql/set_var.cc b/sql/set_var.cc
index 501c638205601afb2cc73c92c0a0986ba08b7fbe..34b66dea31908afabfa9ba6f339f93f9dd5373db 100644
--- a/sql/set_var.cc
+++ b/sql/set_var.cc
@@ -108,7 +108,7 @@ void sys_var_end()
   my_hash_free(&system_variable_hash);
 
   for (sys_var *var=all_sys_vars.first; var; var= var->next)
-    var->~sys_var();
+    var->cleanup();
 
   DBUG_VOID_RETURN;
 }
diff --git a/sql/set_var.h b/sql/set_var.h
index 5f1f889c4ce17870e89536fe1ba7a029063ea631..2972b430e484c98a4492e0729605051d9a27100e 100644
--- a/sql/set_var.h
+++ b/sql/set_var.h
@@ -91,11 +91,13 @@ public:
           longlong def_val, PolyLock *lock, enum binlog_status_enum binlog_status_arg,
           on_check_function on_check_func, on_update_function on_update_func,
           uint deprecated_version, const char *substitute, int parse_flag);
+
+  virtual ~sys_var() {}
+
   /**
-    The instance should only be destroyed on shutdown, as it doesn't unlink
-    itself from the chain.
+    All the cleanup procedures should be performed here
   */
-  virtual ~sys_var() {}
+  virtual void cleanup() {}
   /**
     downcast for sys_var_pluginvar. Returns this if it's an instance
     of sys_var_pluginvar, and 0 otherwise.
diff --git a/sql/sys_vars.h b/sql/sys_vars.h
index ee6b429b04a608df80cbcb0eb18e4cd859093517..740c4f03e3e15f8c3650da8c2fe2d72187c27556 100644
--- a/sql/sys_vars.h
+++ b/sql/sys_vars.h
@@ -385,7 +385,7 @@ public:
     DBUG_ASSERT(scope() == GLOBAL);
     DBUG_ASSERT(size == sizeof(char *));
   }
-  ~Sys_var_charptr()
+  void cleanup()
   {
     if (flags & ALLOCATED)
       my_free(global_var(char*));