diff --git a/libmysqld/lib_sql.cc b/libmysqld/lib_sql.cc
index 8992bea943b..9ee8d48eec4 100644
--- a/libmysqld/lib_sql.cc
+++ b/libmysqld/lib_sql.cc
@@ -69,10 +69,14 @@ void embedded_get_error(MYSQL *mysql)
 
 static void emb_free_rows(THD *thd)
 {
+  if (!thd->data)
+    return;
+
   if (thd->current_stmt)
     free_root(&thd->data->alloc,MYF(0));
   else
     free_rows(thd->data);
+  thd->data= NULL;
 }
 
 
@@ -86,11 +90,8 @@ emb_advanced_command(MYSQL *mysql, enum enum_server_command command,
   THD *thd=(THD *) mysql->thd;
   NET *net= &mysql->net;
 
-  if (thd->data)
-  {
-    emb_free_rows(thd);
-    thd->data= 0;
-  }
+  emb_free_rows(thd);
+
   /* Check that we are calling the client functions in right order */
   if (mysql->status != MYSQL_STATUS_READY)
   {
@@ -143,13 +144,7 @@ emb_advanced_command(MYSQL *mysql, enum enum_server_command command,
 
 static void emb_flush_use_result(MYSQL *mysql)
 {
-  MYSQL_DATA *data= ((THD*)(mysql->thd))->data;
-
-  if (data)
-  {
-    free_rows(data);
-    ((THD*)(mysql->thd))->data= NULL;
-  }
+  emb_free_rows((THD*) (mysql->thd));
 }
 
 static MYSQL_DATA *
@@ -304,8 +299,7 @@ int emb_unbuffered_fetch(MYSQL *mysql, char **row)
 static void emb_free_embedded_thd(MYSQL *mysql)
 {
   THD *thd= (THD*)mysql->thd;
-  if (thd->data)
-    emb_free_rows(thd);
+  emb_free_rows(thd);
   thread_count--;
   delete thd;
   mysql->thd=0;
diff --git a/mysql-test/r/type_datetime.result b/mysql-test/r/type_datetime.result
index f313a6b934b..64337bd2c2f 100644
--- a/mysql-test/r/type_datetime.result
+++ b/mysql-test/r/type_datetime.result
@@ -166,3 +166,6 @@ dt
 0000-00-00 00:00:00
 0000-00-00 00:00:00
 drop table t1;
+select cast('2006-12-05 22:10:10' as datetime) + 0;
+cast('2006-12-05 22:10:10' as datetime) + 0
+20061205221010.000000
diff --git a/mysql-test/t/type_datetime.test b/mysql-test/t/type_datetime.test
index 4b6741b4242..87b86b55fc9 100644
--- a/mysql-test/t/type_datetime.test
+++ b/mysql-test/t/type_datetime.test
@@ -113,4 +113,10 @@ insert into t1 values ("00-00-00"), ("00-00-00 00:00:00");
 select * from t1;
 drop table t1;
 
+#
+# Bug #16546 DATETIME+0 not always coerced the same way 
+#
+select cast('2006-12-05 22:10:10' as datetime) + 0;
+
+
 # End of 4.1 tests
diff --git a/sql/item_timefunc.h b/sql/item_timefunc.h
index 45cad627c05..2383b4f86ac 100644
--- a/sql/item_timefunc.h
+++ b/sql/item_timefunc.h
@@ -751,12 +751,19 @@ public:
   String *val_str(String *str);
   const char *cast_type() const { return "datetime"; }
   enum_field_types field_type() const { return MYSQL_TYPE_DATETIME; }
+  void fix_length_and_dec()
+  {
+    Item_typecast_maybe_null::fix_length_and_dec();
+    decimals= DATETIME_DEC;
+  }
+
   Field *tmp_table_field(TABLE *t_arg)
   {
     return (new Field_datetime(maybe_null, name, t_arg, &my_charset_bin));
   }
   bool result_as_longlong() { return TRUE; }
   longlong val_int();
+  double val() { return (double) val_int(); }
 };
 
 class Item_func_makedate :public Item_str_func
diff --git a/sql/sql_class.cc b/sql/sql_class.cc
index c8d90848f6e..b187d29021a 100644
--- a/sql/sql_class.cc
+++ b/sql/sql_class.cc
@@ -1048,7 +1048,6 @@ bool select_export::send_data(List<Item> &items)
   }
   row_count++;
   Item *item;
-  char *buff_ptr=buff;
   uint used_length=0,items_left=items.elements;
   List_iterator_fast<Item> li(items);
 
@@ -1148,19 +1147,18 @@ bool select_export::send_data(List<Item> &items)
 	  goto err;
       }
     }
-    buff_ptr=buff;				// Place separators here
     if (res && (!exchange->opt_enclosed || result_type == STRING_RESULT))
     {
-      memcpy(buff_ptr,exchange->enclosed->ptr(),exchange->enclosed->length());
-      buff_ptr+=exchange->enclosed->length();
+      if (my_b_write(&cache, (byte*) exchange->enclosed->ptr(),
+                     exchange->enclosed->length()))
+        goto err;
     }
     if (--items_left)
     {
-      memcpy(buff_ptr,exchange->field_term->ptr(),field_term_length);
-      buff_ptr+=field_term_length;
+      if (my_b_write(&cache, (byte*) exchange->field_term->ptr(),
+                     field_term_length))
+        goto err;
     }
-    if (my_b_write(&cache,(byte*) buff,(uint) (buff_ptr-buff)))
-      goto err;
   }
   if (my_b_write(&cache,(byte*) exchange->line_term->ptr(),
 		 exchange->line_term->length()))