diff --git a/myisam/mi_test3.c b/myisam/mi_test3.c
index dca04a9a64baf2d1d8bed4e1eb55867bd8f5923a..27d23317b5c7e60708752bef75bbdc1462a7787b 100644
--- a/myisam/mi_test3.c
+++ b/myisam/mi_test3.c
@@ -40,7 +40,7 @@
 #endif
 
 
-const char *filename= "test3.MSI";
+const char *filename= "test3";
 uint tests=10,forks=10,key_cacheing=0,use_log=0;
 
 static void get_options(int argc, char *argv[]);
@@ -363,7 +363,7 @@ int test_write(MI_INFO *file,int id,int lock_type)
   }
 
   sprintf(record.id,"%7d",getpid());
-  strmov(record.text,"Testing...");
+  strnmov(record.text,"Testing...", sizeof(record.text));
 
   tries=(uint) rnd(100)+10;
   for (i=count=0 ; i < tries ; i++)
diff --git a/myisam/mi_write.c b/myisam/mi_write.c
index e059bbb569f2ca7517f04ae2f2f505c557ac322e..303e924118fed07c502f9f339013892c94b17b02 100644
--- a/myisam/mi_write.c
+++ b/myisam/mi_write.c
@@ -165,12 +165,7 @@ err:
     {
       uint j;
       for (j=0 ; j < share->base.keys ; j++)
-      {
-        if (is_tree_inited(&info->bulk_insert[j]))
-        {
-          reset_tree(&info->bulk_insert[j]);
-        }
-      }
+        mi_flush_bulk_insert(info, j);
     }
     info->errkey= (int) i;
     while ( i-- > 0)
@@ -329,7 +324,7 @@ static int w_search(register MI_INFO *info, register MI_KEYDEF *keyinfo,
   uchar *temp_buff,*keypos;
   uchar keybuff[MI_MAX_KEY_BUFF];
   my_bool was_last_key;
-  my_off_t next_page;
+  my_off_t next_page, dupp_key_pos;
   DBUG_ENTER("w_search");
   DBUG_PRINT("enter",("page: %ld",page));
 
@@ -349,9 +344,9 @@ static int w_search(register MI_INFO *info, register MI_KEYDEF *keyinfo,
 	/* get position to record with duplicated key */
     tmp_key_length=(*keyinfo->get_key)(keyinfo,nod_flag,&keypos,keybuff);
     if (tmp_key_length)
-      info->dupp_key_pos=_mi_dpos(info,0,keybuff+tmp_key_length);
+      dupp_key_pos=_mi_dpos(info,0,keybuff+tmp_key_length);
     else
-      info->dupp_key_pos= HA_OFFSET_ERROR;
+      dupp_key_pos= HA_OFFSET_ERROR;
     if (keyinfo->flag & HA_FULLTEXT)
     {
       uint off;
@@ -370,7 +365,7 @@ static int w_search(register MI_INFO *info, register MI_KEYDEF *keyinfo,
       else
       {
         /* popular word. two-level tree. going down */
-        my_off_t root=info->dupp_key_pos;
+        my_off_t root=dupp_key_pos;
         keyinfo=&info->s->ft2_keyinfo;
         get_key_full_length_rdonly(off, key);
         key+=off;
@@ -389,6 +384,7 @@ static int w_search(register MI_INFO *info, register MI_KEYDEF *keyinfo,
     }
     else /* not HA_FULLTEXT, normal HA_NOSAME key */
     {
+      info->dupp_key_pos= dupp_key_pos;
       my_afree((byte*) temp_buff);
       my_errno=HA_ERR_FOUND_DUPP_KEY;
       DBUG_RETURN(-1);
diff --git a/mysql-test/r/fulltext.result b/mysql-test/r/fulltext.result
index 1951f68e82299952c9d0f19b1ac2ddbf8a14e0f0..a85cfd4181ce656afbbbcb442b655338936704f9 100644
--- a/mysql-test/r/fulltext.result
+++ b/mysql-test/r/fulltext.result
@@ -399,3 +399,9 @@ select count(*) from t1;
 count(*)
 1
 drop table t1;
+create table t1 (a int primary key, b text, fulltext(b));
+create table t2 (a int, b text);
+insert t1 values (1, "aaaa"), (2, "bbbb");
+insert t2 values (10, "aaaa"), (2, "cccc");
+replace t1 select * from t2;
+drop table t1, t2;
diff --git a/mysql-test/t/fulltext.test b/mysql-test/t/fulltext.test
index 41fbf3f27ac092d868a181f0d0fac7272213e094..008e965297f83b5ecbc2eb658354107594e1986b 100644
--- a/mysql-test/t/fulltext.test
+++ b/mysql-test/t/fulltext.test
@@ -308,3 +308,16 @@ REPAIR TABLE t1;
 select count(*) from t1;
 drop table t1;
 
+#
+# bug#6784
+# mi_flush_bulk_insert (on dup key error in mi_write)
+# was mangling info->dupp_key_pos
+#
+
+create table t1 (a int primary key, b text, fulltext(b));
+create table t2 (a int, b text);
+insert t1 values (1, "aaaa"), (2, "bbbb");
+insert t2 values (10, "aaaa"), (2, "cccc");
+replace t1 select * from t2;
+drop table t1, t2;
+
diff --git a/ndb/src/common/logger/LogHandler.cpp b/ndb/src/common/logger/LogHandler.cpp
index 4fab957fc504ecd693153e8676efc49c488f5b3e..a76cb622878452b55bbdc7762fd8d31f483a81f7 100644
--- a/ndb/src/common/logger/LogHandler.cpp
+++ b/ndb/src/common/logger/LogHandler.cpp
@@ -117,10 +117,9 @@ LogHandler::parseParams(const BaseString &_params) {
   _params.split(v_args, ",");
   for(size_t i=0; i < v_args.size(); i++) {
     Vector<BaseString> v_param_value;
-
-    v_args[i].split(v_param_value, "=", 2);
-    if(v_param_value.size() == 2 &&
-       !setParam(v_param_value[0], v_param_value[1]))
+    if(v_args[i].split(v_param_value, "=", 2) != 2)
+      ret = false;
+    else if (!setParam(v_param_value[0], v_param_value[1]))
       ret = false;
   }
 
diff --git a/ndb/src/common/logger/Logger.cpp b/ndb/src/common/logger/Logger.cpp
index 00a2fae67bcc2f87d305ab3b91fe6b039b9bd5b0..1dc3bd43716db5f94296cf458aba330ae18ee668 100644
--- a/ndb/src/common/logger/Logger.cpp
+++ b/ndb/src/common/logger/Logger.cpp
@@ -169,10 +169,13 @@ Logger::addHandler(const BaseString &logstring) {
   size_t i;
   Vector<BaseString> logdest;
   Vector<LogHandler *>loghandlers;
+  DBUG_ENTER("Logger::addHandler");
 
   logstring.split(logdest, ";");
 
   for(i = 0; i < logdest.size(); i++) {
+    DBUG_PRINT("info",("adding: %s",logdest[i]));
+
     Vector<BaseString> v_type_args;
     logdest[i].split(v_type_args, ":", 2);
 
@@ -191,16 +194,16 @@ Logger::addHandler(const BaseString &logstring) {
       handler = new ConsoleLogHandler();
 
     if(handler == NULL)
-      return false;
+      DBUG_RETURN(false);
     if(!handler->parseParams(params))
-      return false;
+      DBUG_RETURN(false);
     loghandlers.push_back(handler);
   }
   
   for(i = 0; i < loghandlers.size(); i++)
     addHandler(loghandlers[i]);
   
-  return true; /* @todo handle errors */
+  DBUG_RETURN(true); /* @todo handle errors */
 }
 
 bool
diff --git a/ndb/src/kernel/blocks/dblqh/DblqhMain.cpp b/ndb/src/kernel/blocks/dblqh/DblqhMain.cpp
index 88e8f25b004681b222c0e1cff9ac4079625f8e3d..c106a6ddfac9a42a734622bad5c933a2f0e7d5ac 100644
--- a/ndb/src/kernel/blocks/dblqh/DblqhMain.cpp
+++ b/ndb/src/kernel/blocks/dblqh/DblqhMain.cpp
@@ -8573,13 +8573,11 @@ Uint32 Dblqh::initScanrec(const ScanFragReq* scanFragReq)
   /**
    * Used for scan take over
    */
-  {
-    FragrecordPtr tFragPtr;
-    tFragPtr.i = fragptr.p->tableFragptr;
-    ptrCheckGuard(tFragPtr, cfragrecFileSize, fragrecord);
-    scanptr.p->fragPtrI = fragptr.p->tableFragptr;
-  }
-
+  FragrecordPtr tFragPtr;
+  tFragPtr.i = fragptr.p->tableFragptr;
+  ptrCheckGuard(tFragPtr, cfragrecFileSize, fragrecord);
+  scanptr.p->fragPtrI = fragptr.p->tableFragptr;
+  
   /**
    * !idx uses 1 - (MAX_PARALLEL_SCANS_PER_FRAG - 1)  =  1-11
    *  idx uses from MAX_PARALLEL_SCANS_PER_FRAG - MAX = 12-42)
@@ -8587,11 +8585,11 @@ Uint32 Dblqh::initScanrec(const ScanFragReq* scanFragReq)
   Uint32 start = (idx ? MAX_PARALLEL_SCANS_PER_FRAG : 1 );
   Uint32 stop = (idx ? MAX_PARALLEL_INDEX_SCANS_PER_FRAG : MAX_PARALLEL_SCANS_PER_FRAG - 1);
   stop += start;
-  Uint32 free = fragptr.p->m_scanNumberMask.find(start);
-  
+  Uint32 free = tFragPtr.p->m_scanNumberMask.find(start);
+    
   if(free == Fragrecord::ScanNumberMask::NotFound || free >= stop){
     jam();
-
+    
     if(scanPrio == 0){
       jam();
       return ScanFragRef::ZTOO_MANY_ACTIVE_SCAN_ERROR;
@@ -8607,10 +8605,9 @@ Uint32 Dblqh::initScanrec(const ScanFragReq* scanFragReq)
     return ZOK;
   }
   
-  
   scanptr.p->scanNumber = free;
-  fragptr.p->m_scanNumberMask.clear(free);// Update mask  
-
+  tFragPtr.p->m_scanNumberMask.clear(free);// Update mask  
+  
   LocalDLList<ScanRecord> active(c_scanRecordPool, fragptr.p->m_activeScans);
   active.add(scanptr);
   if(scanptr.p->scanKeyinfoFlag){
@@ -8693,8 +8690,12 @@ void Dblqh::finishScanrec(Signal* signal)
   LocalDLList<ScanRecord> scans(c_scanRecordPool, fragptr.p->m_activeScans);
   scans.release(scanptr);
   
+  FragrecordPtr tFragPtr;
+  tFragPtr.i = scanptr.p->fragPtrI;
+  ptrCheckGuard(tFragPtr, cfragrecFileSize, fragrecord);
+
   const Uint32 scanNumber = scanptr.p->scanNumber;
-  ndbrequire(!fragptr.p->m_scanNumberMask.get(scanNumber));
+  ndbrequire(!tFragPtr.p->m_scanNumberMask.get(scanNumber));
   ScanRecordPtr restart;
 
   /**
@@ -8702,13 +8703,13 @@ void Dblqh::finishScanrec(Signal* signal)
    */
   if(scanNumber == NR_ScanNo || !queue.first(restart)){
     jam();
-    fragptr.p->m_scanNumberMask.set(scanNumber);
+    tFragPtr.p->m_scanNumberMask.set(scanNumber);
     return;
   }
 
   if(ERROR_INSERTED(5034)){
     jam();
-    fragptr.p->m_scanNumberMask.set(scanNumber);
+    tFragPtr.p->m_scanNumberMask.set(scanNumber);
     return;
   }
 
diff --git a/ndb/src/mgmsrv/InitConfigFileParser.cpp b/ndb/src/mgmsrv/InitConfigFileParser.cpp
index fdfe7823fc21782fc58bbd76b34caae457e18b6a..05102255eaa411cbbeb03af0578bd093c03b58a5 100644
--- a/ndb/src/mgmsrv/InitConfigFileParser.cpp
+++ b/ndb/src/mgmsrv/InitConfigFileParser.cpp
@@ -213,48 +213,41 @@ InitConfigFileParser::parseConfig(FILE * file) {
 //  Parse Name-Value Pair
 //****************************************************************************
 
-bool InitConfigFileParser::parseNameValuePair(Context& ctx, const char* line) {
-
-  char tmpLine[MAX_LINE_LENGTH];
-  char fname[MAX_LINE_LENGTH], rest[MAX_LINE_LENGTH];
-  char* t;
-  const char *separator_list[]= {":", "=", 0};
-  const char *separator= 0;
-
+bool InitConfigFileParser::parseNameValuePair(Context& ctx, const char* line)
+{
   if (ctx.m_currentSection == NULL){
     ctx.reportError("Value specified outside section");
     return false;
   }
 
-  strncpy(tmpLine, line, MAX_LINE_LENGTH);
-
   // *************************************
-  //  Check if a separator exists in line 
+  //  Split string at first occurrence of 
+  //  '=' or ':'
   // *************************************
-  for(int i= 0; separator_list[i] != 0; i++) {
-    if(strchr(tmpLine, separator_list[i][0])) {
-      separator= separator_list[i];
-      break;
-    }
-  }
 
-  if (separator == 0) {
+  Vector<BaseString> tmp_string_split;
+  if (BaseString(line).split(tmp_string_split,
+			     BaseString("=:"),
+			     2) != 2)
+  {
     ctx.reportError("Parse error");
     return false;
   }
 
-  // *******************************************
-  //  Get pointer to substring before separator
-  // *******************************************
-  t = strtok(tmpLine, separator);
-
-  // *****************************************
-  //  Count number of tokens before separator
-  // *****************************************
-  if (sscanf(t, "%120s%120s", fname, rest) != 1) {
-    ctx.reportError("Multiple names before \'%c\'", separator[0]);
-    return false;
+  // *************************************
+  // Remove leading and trailing chars
+  // *************************************
+  {
+    for (int i = 0; i < 2; i++)
+      tmp_string_split[i].trim("\r\n \t"); 
   }
+
+  // *************************************
+  // First in split is fname
+  // *************************************
+
+  const char *fname= tmp_string_split[0].c_str();
+
   if (!ctx.m_currentInfo->contains(fname)) {
     ctx.reportError("[%s] Unknown parameter: %s", ctx.fname, fname);
     return false;
@@ -273,24 +266,11 @@ bool InitConfigFileParser::parseNameValuePair(Context& ctx, const char* line) {
     } 
   }
 
-  // ******************************************
-  //  Get pointer to substring after separator 
-  // ******************************************
-  t = strtok(NULL, "\0");
-  if (t == NULL) {
-    ctx.reportError("No value for parameter");
-    return false;
-  }
-
-  // ******************************************
-  //  Remove prefix and postfix spaces and tabs
-  // *******************************************
-  trim(t);
-
   // ***********************
   //  Store name-value pair
   // ***********************
-  return storeNameValuePair(ctx, fname, t);
+
+  return storeNameValuePair(ctx, fname, tmp_string_split[1].c_str());
 }
 
 
diff --git a/sql/item_func.cc b/sql/item_func.cc
index 269bd38ffa6033038416472605bff4c4132e4860..01866a786a6c5861e707b443f88f1a9e5a5f78b8 100644
--- a/sql/item_func.cc
+++ b/sql/item_func.cc
@@ -1684,18 +1684,21 @@ longlong Item_func_bit_count::val_int()
 
 udf_handler::~udf_handler()
 {
-  if (initialized)
+  if (!not_original)
   {
-    if (u_d->func_deinit != NULL)
+    if (initialized)
     {
-      void (*deinit)(UDF_INIT *) = (void (*)(UDF_INIT*))
-	u_d->func_deinit;
-      (*deinit)(&initid);
+      if (u_d->func_deinit != NULL)
+      {
+        void (*deinit)(UDF_INIT *) = (void (*)(UDF_INIT*))
+        u_d->func_deinit;
+        (*deinit)(&initid);
+      }
+      free_udf(u_d);
     }
-    free_udf(u_d);
+    if (buffers)				// Because of bug in ecc
+      delete [] buffers;
   }
-  if (buffers)					// Because of bug in ecc
-    delete [] buffers;
 }
 
 
diff --git a/sql/item_sum.h b/sql/item_sum.h
index 278695b57bbe403fffa52f37d60ddec90b5b347c..c1352f7ae7ddd6689fee54c75bd3cefce990227c 100644
--- a/sql/item_sum.h
+++ b/sql/item_sum.h
@@ -571,7 +571,7 @@ public:
     :Item_sum( list ), udf(udf_arg)
   { quick_group=0;}
   Item_udf_sum(THD *thd, Item_udf_sum *item)
-    :Item_sum(thd, item), udf(item->udf) {}
+    :Item_sum(thd, item), udf(item->udf) { udf.not_original= TRUE; }
   const char *func_name() const { return udf.name(); }
   bool fix_fields(THD *thd, TABLE_LIST *tables, Item **ref)
   {
diff --git a/sql/sql_udf.h b/sql/sql_udf.h
index 7b10b80f148b26d2305bf4c923cc2156b628fe41..d1f99a6d2329f45c6688f2dcc69c089bbf34d43f 100644
--- a/sql/sql_udf.h
+++ b/sql/sql_udf.h
@@ -56,8 +56,9 @@ class udf_handler :public Sql_alloc
  public:
   table_map used_tables_cache;
   bool const_item_cache;
+  bool not_original;
   udf_handler(udf_func *udf_arg) :u_d(udf_arg), buffers(0), error(0),
-    is_null(0), initialized(0)
+    is_null(0), initialized(0), not_original(0)
   {}
   ~udf_handler();
   const char *name() const { return u_d ? u_d->name.str : "?"; }
diff --git a/sql/table.cc b/sql/table.cc
index 625f04846a8098fe675627ab255559606a7b43c8..63575f3032645031f01166ce3c78be20c6f8846f 100644
--- a/sql/table.cc
+++ b/sql/table.cc
@@ -486,7 +486,26 @@ int openfrm(THD *thd, const char *name, const char *alias, uint db_stat,
 
       /* old frm file */
       field_type= (enum_field_types) f_packtype(pack_flag);
-      charset=f_is_binary(pack_flag) ? &my_charset_bin : outparam->table_charset;
+      if (f_is_binary(pack_flag))
+      {
+        /*
+          Try to choose the best 4.1 type:
+          - for 4.0 "CHAR(N) BINARY" or "VARCHAR(N) BINARY" 
+            try to find a binary collation for character set.
+          - for other types (e.g. BLOB) just use my_charset_bin. 
+        */
+        if (!f_is_blob(pack_flag))
+        {
+          // 3.23 or 4.0 string
+          if (!(charset= get_charset_by_csname(outparam->table_charset->csname,
+                                               MY_CS_BINSORT, MYF(0))))
+            charset= &my_charset_bin;
+        }
+        else
+          charset= &my_charset_bin;
+      }
+      else
+        charset= outparam->table_charset;
       bzero((char*) &comment, sizeof(comment));
     }
     *field_ptr=reg_field=