List:Commits« Previous MessageNext Message »
From:lzhou Date:February 9 2007 11:02am
Subject:bk commit into 5.1 tree (lzhou:1.2344)
View as plain text  
Below is the list of changes that have just been committed into a local
5.1 repository of zhl. When zhl does a push these changes will
be propagated to the main repository and, within 24 hours after the
push, to the public repository.
For information on how to access the public repository
see http://dev.mysql.com/doc/mysql/en/installing-source-tree.html

ChangeSet@stripped, 2007-02-09 11:02:10+00:00, lzhou@dev3-63.(none) +34 -0
  WorkLog3615 enable cluster when cluster runs in machines with different endian types. 
  This is *NOT DONE* patch for review by jonas.
  Because this patch is generated from 5.1-14, so can't use directly in lastest ndb-tree. I try it, but there have some error when do patch
  

  storage/ndb/config/type_util.mk.am@stripped, 2007-02-09 11:01:59+00:00, lzhou@dev3-63.(none) +2 -1
    add kernel include file

  storage/ndb/include/kernel/NodeInfo.hpp@stripped, 2007-02-09 11:01:59+00:00, lzhou@dev3-63.(none) +6 -2
    add endian type

  storage/ndb/include/kernel/signaldata/ApiRegSignalData.hpp@stripped, 2007-02-09 11:01:59+00:00, lzhou@dev3-63.(none) +4 -2
    add endian type and modify signal length

  storage/ndb/include/kernel/signaldata/CmRegSignalData.hpp@stripped, 2007-02-09 11:01:59+00:00, lzhou@dev3-63.(none) +4 -2
    add endian type and change signal length

  storage/ndb/include/kernel/signaldata/TupCommit.hpp@stripped, 2007-02-09 11:01:59+00:00, lzhou@dev3-63.(none) +2 -1
    add applRef and change signal length

  storage/ndb/include/util/SimpleProperties.hpp@stripped, 2007-02-09 11:02:00+00:00, lzhou@dev3-63.(none) +42 -5
    add several functions

  storage/ndb/include/util/ndb_endian.h@stripped, 2007-02-09 10:32:07+00:00, lzhou@dev3-63.(none) +42 -0
    BitKeeper file /home/zhl/mysql/mysql-5.1/work/storage/ndb/include/util/ndb_endian.h

  storage/ndb/include/util/ndb_endian.h@stripped, 2007-02-09 10:32:07+00:00, lzhou@dev3-63.(none) +0 -0

  storage/ndb/src/common/transporter/Packer.cpp@stripped, 2007-02-09 11:02:00+00:00, lzhou@dev3-63.(none) +57 -18
    change signal variable endian if the sender and receiver are not endian 

  storage/ndb/src/common/util/Makefile.am@stripped, 2007-02-09 11:02:00+00:00, lzhou@dev3-63.(none) +1 -1
    add one file

  storage/ndb/src/common/util/SimpleProperties.cpp@stripped, 2007-02-09 11:02:00+00:00, lzhou@dev3-63.(none) +112 -15
    covert if sender and receiver are not the same endian type

  storage/ndb/src/common/util/md5_hash.cpp@stripped, 2007-02-09 11:02:00+00:00, lzhou@dev3-63.(none) +11 -0
    md5 is sometimes not correct

  storage/ndb/src/common/util/ndb_endian.c@stripped, 2007-02-09 10:32:24+00:00, lzhou@dev3-63.(none) +145 -0
    BitKeeper file /home/zhl/mysql/mysql-5.1/work/storage/ndb/src/common/util/ndb_endian.c

  storage/ndb/src/common/util/ndb_endian.c@stripped, 2007-02-09 10:32:24+00:00, lzhou@dev3-63.(none) +0 -0

  storage/ndb/src/kernel/blocks/cmvmi/Cmvmi.cpp@stripped, 2007-02-09 11:02:00+00:00, lzhou@dev3-63.(none) +51 -0
    if endian type is not the same, then convert

  storage/ndb/src/kernel/blocks/dbdict/Dbdict.cpp@stripped, 2007-02-09 11:02:00+00:00, lzhou@dev3-63.(none) +407 -23
    do convert in all conditions needed to convert

  storage/ndb/src/kernel/blocks/dbdict/Dbdict.hpp@stripped, 2007-02-09 11:02:00+00:00, lzhou@dev3-63.(none) +3 -1
    add two functions

  storage/ndb/src/kernel/blocks/dbdih/DbdihMain.cpp@stripped, 2007-02-09 11:02:00+00:00, lzhou@dev3-63.(none) +4 -0
    just comment

  storage/ndb/src/kernel/blocks/dblqh/Dblqh.hpp@stripped, 2007-02-09 11:02:01+00:00, lzhou@dev3-63.(none) +1 -0
    add one function

  storage/ndb/src/kernel/blocks/dblqh/DblqhMain.cpp@stripped, 2007-02-09 11:02:01+00:00, lzhou@dev3-63.(none) +61 -2
    convert data 

  storage/ndb/src/kernel/blocks/dbtc/Dbtc.hpp@stripped, 2007-02-09 11:02:01+00:00, lzhou@dev3-63.(none) +1 -0
    add one function

  storage/ndb/src/kernel/blocks/dbtc/DbtcMain.cpp@stripped, 2007-02-09 11:02:01+00:00, lzhou@dev3-63.(none) +46 -0
    handle key data

  storage/ndb/src/kernel/blocks/dbtup/Dbtup.hpp@stripped, 2007-02-09 11:02:01+00:00, lzhou@dev3-63.(none) +1 -0
    add one function

  storage/ndb/src/kernel/blocks/dbtup/DbtupCommit.cpp@stripped, 2007-02-09 11:02:01+00:00, lzhou@dev3-63.(none) +3 -0
    initialize variables

  storage/ndb/src/kernel/blocks/dbtup/DbtupExecQuery.cpp@stripped, 2007-02-09 11:02:02+00:00, lzhou@dev3-63.(none) +2 -0
    initialize

  storage/ndb/src/kernel/blocks/dbtup/DbtupIndex.cpp@stripped, 2007-02-09 11:02:02+00:00, lzhou@dev3-63.(none) +6 -0
    initialize

  storage/ndb/src/kernel/blocks/dbtup/DbtupRoutines.cpp@stripped, 2007-02-09 11:02:02+00:00, lzhou@dev3-63.(none) +775 -10
    convert data

  storage/ndb/src/kernel/blocks/dbtup/DbtupTrigger.cpp@stripped, 2007-02-09 11:02:02+00:00, lzhou@dev3-63.(none) +9 -0
    convert attr info

  storage/ndb/src/kernel/blocks/dbutil/DbUtil.cpp@stripped, 2007-02-09 11:02:02+00:00, lzhou@dev3-63.(none) +4 -0
    just comment

  storage/ndb/src/kernel/blocks/qmgr/QmgrMain.cpp@stripped, 2007-02-09 11:02:02+00:00, lzhou@dev3-63.(none) +48 -0
    set value of endian and do convert

  storage/ndb/src/kernel/vm/SimplePropertiesSection.cpp@stripped, 2007-02-09 11:02:02+00:00, lzhou@dev3-63.(none) +22 -2
    initialize endian 

  storage/ndb/src/kernel/vm/SimulatedBlock.cpp@stripped, 2007-02-09 11:02:02+00:00, lzhou@dev3-63.(none) +204 -0
    convert several data type  

  storage/ndb/src/kernel/vm/SimulatedBlock.hpp@stripped, 2007-02-09 11:02:02+00:00, lzhou@dev3-63.(none) +10 -0
    add some function

  storage/ndb/src/mgmsrv/Services.cpp@stripped, 2007-02-09 11:02:02+00:00, lzhou@dev3-63.(none) +7 -0
    remove limited for different endian type in one cluster

  storage/ndb/src/ndbapi/ClusterMgr.cpp@stripped, 2007-02-09 11:02:02+00:00, lzhou@dev3-63.(none) +22 -0
    set endian type when api initialize

  storage/ndb/src/ndbapi/NdbDictionaryImpl.cpp@stripped, 2007-02-09 11:02:03+00:00, lzhou@dev3-63.(none) +10 -0
    remove original convert ?

# This is a BitKeeper patch.  What follows are the unified diffs for the
# set of deltas contained in the patch.  The rest of the patch, the part
# that BitKeeper cares about, is below these diffs.
# User:	lzhou
# Host:	dev3-63.(none)
# Root:	/home/zhl/mysql/mysql-5.1/work
--- New file ---
+++ storage/ndb/include/util/ndb_endian.h	07/02/09 10:32:07
/* Copyright (C) 2007 MySQL AB

   This program is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
   the Free Software Foundation; either version 2 of the License, or
   (at your option) any later version.

   This program is distributed in the hope that it will be useful,
   but WITHOUT ANY WARRANTY; without even the implied warranty of
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   GNU General Public License for more details.

   You should have received a copy of the GNU General Public License
   along with this program; if not, write to the Free Software
   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA */


#ifndef NDB_ENDIAN_H
#define NDB_ENDIAN_H

#include <ndb_types.h>

#define NDB_LITTLE_ENDIAN	0
#define NDB_BIG_ENDIAN		1

#ifdef __cplusplus
extern "C" {
#endif

Uint32 checkEndian();

Uint32 swapOneWord32(Uint32 data);
void swapManyWords32(Uint32 *data, Uint32 length);

void swapManyWords16(Uint32 *data, Uint32 length);
void swapManyWords64(Uint32 *data, Uint32 length);
  
#ifdef __cplusplus
}
#endif

#endif

--- New file ---
+++ storage/ndb/src/common/util/ndb_endian.c	07/02/09 10:32:24
/* Copyright (C) 2007 MySQL AB

   This program is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
   the Free Software Foundation; either version 2 of the License, or
   (at your option) any later version.

   This program is distributed in the hope that it will be useful,
   but WITHOUT ANY WARRANTY; without even the implied warranty of
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   GNU General Public License for more details.

   You should have received a copy of the GNU General Public License
   along with this program; if not, write to the Free Software
   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA */

#include <ndb_global.h>
#include <ndb_endian.h>
#include <NdbOut.hpp>

/**
 * Check the endian of own node.
 */
Uint32 checkEndian()
{
  union
  {
    long l;
    char c[sizeof(long)];
  } endian_check;

  endian_check.l = 1;

  return ((endian_check.c[sizeof(long)-1]) ? NDB_BIG_ENDIAN : NDB_LITTLE_ENDIAN);
}

/**
 * Swap the byte order of one 32-bit word.
 *
 * Parameters:
 *   data: the data to be swapped
 *
 * Returned value:
 *   the data after swapped.
 */
Uint32 swapOneWord32(Uint32 data)
{ 
  Uint32 data2;

  ((unsigned char*)&data2)[0] = ((unsigned char*)&data)[3];
  ((unsigned char*)&data2)[1] = ((unsigned char*)&data)[2];
  ((unsigned char*)&data2)[2] = ((unsigned char*)&data)[1];
  ((unsigned char*)&data2)[3] = ((unsigned char*)&data)[0];

  return data2;
}

/**
 * Swap the byte order of many 32-bit words.
 *
 * Parameters:
 *   data: the data to be swapped
 *   length: the number of 32-bit words
 *
 * Returned value:
 *   the value after swapped is stored in data.
 */
void swapManyWords32(Uint32 *data, Uint32 length)
{
  Uint32 data2;

  if (!data || length == 0)
    return;

  do {
    data2 = swapOneWord32(*data);
    *data = data2;
    data++;
  } while (--length);
}

/**
 * Swap the byte order for 16-bit words.
 * If the endian of the sender and receiver are different,
 * the byte order of all the data in signal will be swapped
 * for each 32-bit word.
 * So for 16-bit word, we can just exchange the high and 
 * low 16-bit of the 32-bit word.
 *
 * Parameters:
 *   data: the data to be swapped
 *   length: the number of 32-bit words
 *
 * Returned value:
 *   the value after swapped is stored in data.
 */
void swapManyWords16(Uint32 *data, Uint32 length)
{
  Uint32 data2;

  if (!data || length == 0)
    return;

  do {
    data2 = (((*data) & 0xFFFF0000) >> 16) + (((*data) & 0x0000FFFF) << 16);
    *data = data2;
    data++;
  } while (--length);
}

/**
 * Swap the byte order for 64-bit words.
 * If the endian of the sender and receiver are different,
 * the byte order of all the data in signal will be swapped
 * for each 32-bit word.
 * So for 64-bit word, we can just exchange its high and 
 * low 32-bit words.
 *
 * Note:
 * On Solaris Sparc, if transfer a Uint32 type address to
 * a Uint64 type address, may cause Bus Error. 
 *
 * Parameters:
 *   data: the data to be swapped
 *   length: the number of 32-bit words
 *
 * Returned value:
 *   the value after swapped is stored in data.
 */
void swapManyWords64(Uint32 *data, Uint32 length)
{
  Uint32 data2;

  if (!data || length == 0)
    return;

  do {
    data2 = *data;
    *data = *(data + 1);
    *(data + 1) = data2;
    data += 2;
    length -= 2;
  } while (length);
}



--- 1.5/storage/ndb/include/kernel/NodeInfo.hpp	2007-02-09 11:02:31 +00:00
+++ 1.6/storage/ndb/include/kernel/NodeInfo.hpp	2007-02-09 11:02:31 +00:00
@@ -19,6 +19,7 @@
 
 #include <NdbOut.hpp>
 #include <mgmapi_config_parameters.h>
+#include <ndb_endian.h>
 
 class NodeInfo {
 public:
@@ -34,10 +35,11 @@ public:
     INVALID = 255 ///< Invalid type
   };
   NodeType getType() const;
-  
+
   Uint32 m_version;       ///< Node version
   Uint32 m_signalVersion; ///< Signal version
   Uint32 m_type;          ///< Node type
+  Uint32 m_endian;        ///< Node endian type
   Uint32 m_connectCount;  ///< No of times connected
   bool   m_connected;     ///< Node is connected
   Uint32 m_heartbeat_cnt; ///< Missed heartbeats
@@ -51,6 +53,7 @@ NodeInfo::NodeInfo(){
   m_version = 0;
   m_signalVersion = 0;
   m_type = INVALID;
+  m_endian = NDB_LITTLE_ENDIAN; //default is little-endian
   m_connectCount = 0;
   m_heartbeat_cnt= 0;
 }
@@ -84,7 +87,8 @@ operator<<(NdbOut& ndbout, const NodeInf
   }
 
   ndbout << " version: " << info.m_version
-	 << " sig. version; " << info.m_signalVersion
+	 << " sig. version: " << info.m_signalVersion
+	 << " endian: " << info.m_endian
 	 << " connect count: " << info.m_connectCount
 	 << "]";
   return ndbout;

--- 1.4/storage/ndb/include/kernel/signaldata/ApiRegSignalData.hpp	2007-02-09 11:02:31 +00:00
+++ 1.5/storage/ndb/include/kernel/signaldata/ApiRegSignalData.hpp	2007-02-09 11:02:31 +00:00
@@ -31,11 +31,12 @@ class ApiRegReq {
   friend class Qmgr;
 
 public:
-  STATIC_CONST( SignalLength = 2 );
+  STATIC_CONST( SignalLength = 3 );
 
 private:
   Uint32 ref;
   Uint32 version; // Version of API node
+  Uint32 endian; // Endian of API node
 };
 
 /**
@@ -80,11 +81,12 @@ class ApiRegConf {
   friend class ClusterMgr;
 
 public:
-  STATIC_CONST( SignalLength = 3 + NodeState::DataLength );
+  STATIC_CONST( SignalLength = 4 + NodeState::DataLength );
 private:
   
   Uint32 qmgrRef;
   Uint32 version; // Version of NDB node
+  Uint32 endian; // Endian of NDB node
   Uint32 apiHeartbeatFrequency;
   NodeState nodeState;
 };

--- 1.4/storage/ndb/include/kernel/signaldata/CmRegSignalData.hpp	2007-02-09 11:02:31 +00:00
+++ 1.5/storage/ndb/include/kernel/signaldata/CmRegSignalData.hpp	2007-02-09 11:02:31 +00:00
@@ -159,7 +159,7 @@ class CmNodeInfoReq {
   friend class Qmgr;
   
 public:
-  STATIC_CONST( SignalLength = 3 );
+  STATIC_CONST( SignalLength = 4 );
   
 private:
   /**
@@ -168,6 +168,7 @@ private:
   Uint32 nodeId;
   Uint32 dynamicId;
   Uint32 version;
+  Uint32 endian; //Endian of NDB node
 };
 
 class CmNodeInfoRef {
@@ -195,12 +196,13 @@ class CmNodeInfoConf {
   friend class Qmgr;
   
 public:
-  STATIC_CONST( SignalLength = 3 );
+  STATIC_CONST( SignalLength = 4 );
   
 private:
   Uint32 nodeId;
   Uint32 dynamicId;
   Uint32 version;
+  Uint32 endian; //Endian of NDB node
 };
 
 #endif

--- 1.2/storage/ndb/include/kernel/signaldata/TupCommit.hpp	2007-02-09 11:02:31 +00:00
+++ 1.3/storage/ndb/include/kernel/signaldata/TupCommit.hpp	2007-02-09 11:02:31 +00:00
@@ -36,7 +36,7 @@ class TupCommitReq {
   friend bool printTUPCOMMITREQ(FILE * output, const Uint32 * theData, Uint32 len, Uint16 receiverBlockNo);
 
 public:
-  STATIC_CONST( SignalLength = 3 );
+  STATIC_CONST( SignalLength = 4 );
 
 private:
 
@@ -46,6 +46,7 @@ private:
   Uint32 opPtr;
   Uint32 gci;
   Uint32 hashValue;
+  Uint32 applRef;
 };
 
 #endif

--- 1.11/storage/ndb/include/util/SimpleProperties.hpp	2007-02-09 11:02:31 +00:00
+++ 1.12/storage/ndb/include/util/SimpleProperties.hpp	2007-02-09 11:02:31 +00:00
@@ -141,6 +141,11 @@ public:
      */
     void printAll(NdbOut& ndbout);
 
+    /**
+     * Get the need convert endian flag.
+     */
+    virtual bool needConvertEndian() const { return false; };
+
   private:
     bool readValue();
     
@@ -172,6 +177,11 @@ public:
     bool add(Uint16 key, Uint32 value);
     bool add(Uint16 key, const char * value);
     bool add(Uint16 key, const void* value, int len);
+    /**
+     * Get the need convert endian flag.
+     */
+    virtual bool needConvertEndian() const { return false; };
+
   protected:
     virtual ~Writer() {}
     virtual bool reset() = 0;
@@ -179,6 +189,7 @@ public:
     virtual bool putWords(const Uint32 * src, Uint32 len) = 0;
   private:
     bool add(const char* value, int len);
+    bool add16(const char* value, int len);
   };
 };
 
@@ -187,7 +198,7 @@ public:
  */
 class SimplePropertiesLinearReader : public SimpleProperties::Reader {
 public:
-  SimplePropertiesLinearReader(const Uint32 * src, Uint32 len);
+  SimplePropertiesLinearReader(const Uint32 * src, Uint32 len, bool needConvertEndian = false);
   virtual ~SimplePropertiesLinearReader() {}
   
   virtual void reset();
@@ -195,10 +206,15 @@ public:
   virtual bool getWord(Uint32 * dst);
   virtual bool peekWord(Uint32 * dst) const ;
   virtual bool peekWords(Uint32 * dst, Uint32 len) const;
+  /**
+   * Get the need convert endian flag.
+   */
+  virtual bool needConvertEndian() const;
 private:
   Uint32 m_len;
   Uint32 m_pos;
   const Uint32 * m_src;
+  bool m_convertEndian;
 };
 
 /**
@@ -206,17 +222,22 @@ private:
  */
 class LinearWriter : public SimpleProperties::Writer {
 public:
-  LinearWriter(Uint32 * src, Uint32 len);
+  LinearWriter(Uint32 * src, Uint32 len, bool needConvertEndian = false);
   virtual ~LinearWriter() {}
 
   virtual bool reset();
   virtual bool putWord(Uint32 val);
   virtual bool putWords(const Uint32 * src, Uint32 len);
   Uint32 getWordsUsed() const;
+  /**
+   * Get the need convert endian flag.
+   */
+  virtual bool needConvertEndian() const;
 private:
   Uint32 m_len;
   Uint32 m_pos;
   Uint32 * m_src;
+  bool m_convertEndian;
 };
 
 /**
@@ -224,15 +245,20 @@ private:
  */
 class UtilBufferWriter : public SimpleProperties::Writer {
 public:
-  UtilBufferWriter(class UtilBuffer & buf);
+  UtilBufferWriter(class UtilBuffer & buf, bool needConvertEndian = false);
   virtual ~UtilBufferWriter() {}
   
   virtual bool reset();
   virtual bool putWord(Uint32 val);
   virtual bool putWords(const Uint32 * src, Uint32 len);
   Uint32 getWordsUsed() const;
+  /**
+   * Get the need convert endian flag.
+   */
+  virtual bool needConvertEndian() const;
 private:
   class UtilBuffer & m_buf;
+  bool m_convertEndian;
 };
 
 /**
@@ -244,7 +270,8 @@ private:
 class SimplePropertiesSectionReader : public SimpleProperties::Reader {
 public:
   SimplePropertiesSectionReader(struct SegmentedSectionPtr &,
-				class SectionSegmentPool &);
+				class SectionSegmentPool &,
+				bool needConvertEndian = false);
   virtual ~SimplePropertiesSectionReader() {}
   
   virtual void reset();
@@ -254,6 +281,10 @@ public:
   virtual bool peekWords(Uint32 * dst, Uint32 len) const;
   Uint32 getSize() const;
   bool getWords(Uint32 * dst, Uint32 len);
+  /**
+   * Get the need convert endian flag.
+   */
+  virtual bool needConvertEndian() const;
 
 private:
   Uint32 m_pos;
@@ -261,6 +292,7 @@ private:
   class SectionSegmentPool & m_pool;
   struct SectionSegment * m_head;
   struct SectionSegment * m_currentSegment;
+  bool m_convertEndian;
 };
 
 inline
@@ -277,7 +309,7 @@ Uint32 SimplePropertiesSectionReader::ge
  */
 class SimplePropertiesSectionWriter : public SimpleProperties::Writer {
 public:
-  SimplePropertiesSectionWriter(class SectionSegmentPool &);
+  SimplePropertiesSectionWriter(class SectionSegmentPool &, bool needConvertEndian = false);
   virtual ~SimplePropertiesSectionWriter() {}
 
   virtual bool reset();
@@ -288,6 +320,10 @@ public:
    * This "unlinks" the writer from the memory
    */
   void getPtr(struct SegmentedSectionPtr & dst);
+  /**
+   * Get the need convert endian flag.
+   */
+  virtual bool needConvertEndian() const;
   
 private:
   Int32 m_pos;
@@ -296,6 +332,7 @@ private:
   struct SectionSegment * m_head;
   Uint32 m_prevPtrI; // Prev to m_currentSegment
   struct SectionSegment * m_currentSegment;
+  bool m_convertEndian;
 };
 
 #endif

--- 1.8/storage/ndb/src/common/transporter/Packer.cpp	2007-02-09 11:02:31 +00:00
+++ 1.9/storage/ndb/src/common/transporter/Packer.cpp	2007-02-09 11:02:31 +00:00
@@ -15,6 +15,7 @@
    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA */
 
 #include <ndb_global.h>
+#include <ndb_endian.h>
 
 #include "Packer.hpp"
 #include <TransporterRegistry.hpp>
@@ -41,11 +42,13 @@ TransporterRegistry::unpack(Uint32 * rea
       Uint32 word3 = readPtr[2];
       loop_count++;
       
-#if 0
-      if(Protocol6::getByteOrder(word1) != MY_OWN_BYTE_ORDER){
-	//Do funky stuff
+      // Handle byte order of first 3 words
+      Uint32 myOwnByteOrder = checkEndian();
+      if (Protocol6::getByteOrder(word1) != myOwnByteOrder){
+        word1 = swapOneWord32(word1);
+        word2 = swapOneWord32(word2);
+        word3 = swapOneWord32(word3);
       }
-#endif
 
       const Uint16 messageLen32    = Protocol6::getMessageLength(word1);
       const Uint32 messageLenBytes = ((Uint32)messageLen32) << 2;
@@ -60,6 +63,12 @@ TransporterRegistry::unpack(Uint32 * rea
 	break;
       }//if
       
+      // Handle byte order of signal data
+      if (Protocol6::getByteOrder(word1) != myOwnByteOrder){
+        // swap the left data
+        swapManyWords32(&readPtr[3], messageLen32 - 3);
+      }
+
       if(Protocol6::getCheckSumIncluded(word1)){
 	const Uint32 tmpLen = messageLen32 - 1;
 	const Uint32 checkSumSent     = readPtr[tmpLen];
@@ -124,11 +133,13 @@ TransporterRegistry::unpack(Uint32 * rea
       Uint32 word3 = readPtr[2];
       loop_count++;
       
-#if 0
-      if(Protocol6::getByteOrder(word1) != MY_OWN_BYTE_ORDER){
-	//Do funky stuff
-      }//if
-#endif
+      // Handle byte order of first 3 words
+      Uint32 myOwnByteOrder = checkEndian();
+      if (Protocol6::getByteOrder(word1) != myOwnByteOrder){
+        word1 = swapOneWord32(word1);
+        word2 = swapOneWord32(word2);
+        word3 = swapOneWord32(word3);
+      }
       
       const Uint16 messageLen32    = Protocol6::getMessageLength(word1);
       const Uint32 messageLenBytes = ((Uint32)messageLen32) << 2;
@@ -142,6 +153,12 @@ TransporterRegistry::unpack(Uint32 * rea
 	break;
       }//if
       
+      // Handle byte order of signal data
+      if (Protocol6::getByteOrder(word1) != myOwnByteOrder){
+        // swap the left data
+        swapManyWords32(&readPtr[3], messageLen32 - 3);
+      }
+
       if(Protocol6::getCheckSumIncluded(word1)){
 	const Uint32 tmpLen = messageLen32 - 1;
 	const Uint32 checkSumSent     = readPtr[tmpLen];
@@ -222,11 +239,14 @@ TransporterRegistry::unpack(Uint32 * rea
       Uint32 word2 = readPtr[1];
       Uint32 word3 = readPtr[2];
       loop_count++; 
-#if 0
-      if(Protocol6::getByteOrder(word1) != MY_OWN_BYTE_ORDER){
-	//Do funky stuff
+
+      // Handle byte order of first 3 words
+      Uint32 myOwnByteOrder = checkEndian();
+      if (Protocol6::getByteOrder(word1) != myOwnByteOrder){
+        word1 = swapOneWord32(word1);
+        word2 = swapOneWord32(word2);
+        word3 = swapOneWord32(word3);
       }
-#endif
       
       const Uint16 messageLen32    = Protocol6::getMessageLength(word1);
       
@@ -236,6 +256,12 @@ TransporterRegistry::unpack(Uint32 * rea
         return readPtr;
       }//if
       
+      // Handle byte order of signal data
+      if (Protocol6::getByteOrder(word1) != myOwnByteOrder){
+        // swap the left data
+        swapManyWords32(&readPtr[3], messageLen32 - 3);
+      }
+
       if(Protocol6::getCheckSumIncluded(word1)){
 	const Uint32 tmpLen = messageLen32 - 1;
 	const Uint32 checkSumSent     = readPtr[tmpLen];
@@ -293,11 +319,14 @@ TransporterRegistry::unpack(Uint32 * rea
       Uint32 word2 = readPtr[1];
       Uint32 word3 = readPtr[2];
       loop_count++; 
-#if 0
-      if(Protocol6::getByteOrder(word1) != MY_OWN_BYTE_ORDER){
-	//Do funky stuff
-      }//if
-#endif
+
+      // Handle byte order of first 3 words
+      Uint32 myOwnByteOrder = checkEndian();
+      if (Protocol6::getByteOrder(word1) != myOwnByteOrder){
+        word1 = swapOneWord32(word1);
+        word2 = swapOneWord32(word2);
+        word3 = swapOneWord32(word3);
+      }
       
       const Uint16 messageLen32    = Protocol6::getMessageLength(word1);
       if(messageLen32 == 0 || messageLen32 > MAX_MESSAGE_SIZE){
@@ -306,6 +335,12 @@ TransporterRegistry::unpack(Uint32 * rea
         return readPtr;
       }//if
       
+      // Handle byte order of signal data
+      if (Protocol6::getByteOrder(word1) != myOwnByteOrder){
+        // swap the left data
+        swapManyWords32(&readPtr[3], messageLen32 - 3);
+      }
+
       if(Protocol6::getCheckSumIncluded(word1)){
 	const Uint32 tmpLen = messageLen32 - 1;
 	const Uint32 checkSumSent     = readPtr[tmpLen];
@@ -420,6 +455,8 @@ Packer::pack(Uint32 * insertPtr, 
   Uint32 word2 = 0;
   Uint32 word3 = 0;
   
+  Uint32 ownByteOrder = checkEndian();
+  Protocol6::setByteOrder(word1, ownByteOrder);
   Protocol6::setPrio(word1, prio);
   Protocol6::setMessageLength(word1, len32);
   Protocol6::createProtocol6Header(word1, word2, word3, header);
@@ -479,6 +516,8 @@ Packer::pack(Uint32 * insertPtr, 
   Uint32 word2 = 0;
   Uint32 word3 = 0;
   
+  Uint32 ownByteOrder = checkEndian();
+  Protocol6::setByteOrder(word1, ownByteOrder);
   Protocol6::setPrio(word1, prio);
   Protocol6::setMessageLength(word1, len32);
   Protocol6::createProtocol6Header(word1, word2, word3, header);

--- 1.11/storage/ndb/src/common/util/SimpleProperties.cpp	2007-02-09 11:02:31 +00:00
+++ 1.12/storage/ndb/src/common/util/SimpleProperties.cpp	2007-02-09 11:02:31 +00:00
@@ -19,6 +19,8 @@
 #include <NdbOut.hpp>
 #include <NdbTCP.h>
 #include <UtilBuffer.hpp>
+#include <signaldata/DictTabInfo.hpp>
+#include <ndb_endian.h>
 
 bool
 SimpleProperties::Writer::first(){
@@ -30,20 +32,67 @@ SimpleProperties::Writer::add(Uint16 key
   Uint32 head = Uint32Value;  
   head <<= 16;
   head += key;
-  if(!putWord(htonl(head)))
+  if(!putWord(head))
     return false;
   
-  return putWord(htonl(value));
+  return putWord(value);
 }
 
 bool
 SimpleProperties::Writer::add(const char * value, int len){
+  bool need_convert_endian = needConvertEndian();
   const Uint32 valLen = (len + 3) / 4;
 
-  if ((len % 4) == 0)
+  if ((len % 4) == 0) {
+    if (need_convert_endian && valLen > 0) {
+      // swap byte order for character strings
+      swapManyWords32((Uint32*)value, valLen);
+    }
+    return putWords((Uint32*)value, valLen);
+  }
+
+  const Uint32 putLen= valLen - 1;
+  if (need_convert_endian && putLen > 0) {
+    // swap byte order for character strings
+    swapManyWords32((Uint32*)value, putLen);
+  }
+  if (!putWords((Uint32*)value, putLen))
+    return false;
+
+  // Special handling of last bytes
+  union {
+    Uint32 lastWord;
+    char lastBytes[4];
+  } tmp;
+  tmp.lastWord =0 ;
+  memcpy(tmp.lastBytes,
+         value + putLen*4,
+         len - putLen*4);
+  if (need_convert_endian && len > 0) {
+    // swap byte order for character strings
+    swapManyWords32(&(tmp.lastWord), 1);
+  }
+  return putWord(tmp.lastWord);
+}
+
+bool
+SimpleProperties::Writer::add16(const char * value, int len){
+  bool need_convert_endian = needConvertEndian();
+  const Uint32 valLen = (len + 3) / 4;
+
+  if ((len % 4) == 0) {
+    if (need_convert_endian && valLen > 0) {
+      // swap byte order for 16-bit words.
+      swapManyWords16((Uint32*)value, valLen);
+    }
     return putWords((Uint32*)value, valLen);
+  }
 
   const Uint32 putLen= valLen - 1;
+  if (need_convert_endian && putLen > 0) {
+    // swap byte order for 16-bit words.
+    swapManyWords16((Uint32*)value, putLen);
+  }
   if (!putWords((Uint32*)value, putLen))
     return false;
 
@@ -56,6 +105,10 @@ SimpleProperties::Writer::add(const char
   memcpy(tmp.lastBytes,
          value + putLen*4,
          len - putLen*4);
+  if (need_convert_endian && len > 0) {
+    // swap byte order for 16-bit word.
+    swapManyWords16(&(tmp.lastWord), 1);
+  }
   return putWord(tmp.lastWord);
 }
 
@@ -64,10 +117,11 @@ SimpleProperties::Writer::add(Uint16 key
   Uint32 head = StringValue;
   head <<= 16;
   head += key;
-  if(!putWord(htonl(head)))
+
+  if(!putWord(head))
     return false;
   Uint32 strLen = strlen(value) + 1; // Including NULL-byte
-  if(!putWord(htonl(strLen)))
+  if(!putWord(strLen))
     return false;
 
   return add(value, (int)strLen);
@@ -79,12 +133,21 @@ SimpleProperties::Writer::add(Uint16 key
   Uint32 head = BinaryValue;
   head <<= 16;
   head += key;
-  if(!putWord(htonl(head)))
+  if(!putWord(head))
     return false;
-  if(!putWord(htonl(len)))
+  if(!putWord(len))
     return false;
 
-  return add((const char*)value, len);
+  switch (key) {
+  case DictTabInfo::ReplicaData:
+  case DictTabInfo::FragmentData:
+    return add16((const char*)value, len);
+  default:
+    /**
+     * Treat all the other Binary attributes as char string.
+     */
+    return add((const char*)value, len);
+  }
 }
 
 SimpleProperties::Reader::Reader(){
@@ -139,8 +202,29 @@ SimpleProperties::Reader::getUint32() co
 
 char * 
 SimpleProperties::Reader::getString(char * dst) const {
-  if(peekWords((Uint32*)dst, m_itemLen))
+//  bool need_convert_endian = ((SimpleProperties::Reader*)this)->needConvertEndian();
+  bool need_convert_endian = needConvertEndian();
+
+  if(peekWords((Uint32*)dst, m_itemLen)) {
+    if (need_convert_endian) {
+      Uint16 key = getKey();
+      switch (key) {
+      case DictTabInfo::ReplicaData:
+      case DictTabInfo::FragmentData:
+        // swap byte order for 16-bit words.
+        swapManyWords16((Uint32*)dst, m_itemLen);
+        break;
+      default:
+        /**
+         * swap byte order for 32-bit words.
+         * Treat all the other Binary attributes as char string.
+         */
+        swapManyWords32((Uint32*)dst, m_itemLen);
+        break;
+      }
+    }
     return dst;
+  }
   return 0;
 }
 
@@ -157,7 +241,6 @@ SimpleProperties::Reader::readValue(){
     return false;
   }
 
-  tmp = ntohl(tmp);
   m_key = tmp & 0xFFFF;
   m_type = (SimpleProperties::ValueType)(tmp >> 16);
   switch(m_type){
@@ -165,13 +248,12 @@ SimpleProperties::Reader::readValue(){
     m_itemLen = 1;
     if(!peekWord(&m_ui32_value))
       return false;
-    m_ui32_value = ntohl(m_ui32_value);
     return true;
   case StringValue:
   case BinaryValue:
     if(!getWord(&tmp))
       return false;
-    m_strLen = ntohl(tmp);
+    m_strLen = tmp;
     m_itemLen = (m_strLen + 3)/4;
     return true;
   default:
@@ -321,10 +403,12 @@ SimpleProperties::Reader::printAll(NdbOu
 }
 
 SimplePropertiesLinearReader::SimplePropertiesLinearReader
-(const Uint32 * src, Uint32 len){
+(const Uint32 * src, Uint32 len, bool needConvertEndian)
+{
   m_src = src;
   m_len = len;
   m_pos = 0;
+  m_convertEndian = needConvertEndian;
   first();
 }
 
@@ -366,9 +450,15 @@ SimplePropertiesLinearReader::peekWords(
   return false;
 }
 
-LinearWriter::LinearWriter(Uint32 * src, Uint32 len){
+bool 
+SimplePropertiesLinearReader::needConvertEndian() const {
+  return m_convertEndian;
+}
+
+LinearWriter::LinearWriter(Uint32 * src, Uint32 len, bool needConvertEndian){
   m_src = src;
   m_len = len;
+  m_convertEndian = needConvertEndian;
   reset();
 }
 
@@ -396,9 +486,13 @@ LinearWriter::putWords(const Uint32 * sr
 Uint32
 LinearWriter::getWordsUsed() const { return m_pos;}
 
-UtilBufferWriter::UtilBufferWriter(UtilBuffer & b)
+bool
+LinearWriter::needConvertEndian() const { return m_convertEndian; }
+
+UtilBufferWriter::UtilBufferWriter(UtilBuffer & b, bool needConvertEndian)
   : m_buf(b)
 {
+  m_convertEndian = needConvertEndian;
   reset();
 }
 
@@ -417,6 +511,9 @@ UtilBufferWriter::putWords(const Uint32 
 
 Uint32
 UtilBufferWriter::getWordsUsed() const { return m_buf.length() / 4;}
+
+bool
+UtilBufferWriter::needConvertEndian() const { return m_convertEndian;}
 
 #if 0
 LinearPagesReader::LinearPagesReader(const Uint32 * base, 

--- 1.4/storage/ndb/src/common/util/md5_hash.cpp	2007-02-09 11:02:31 +00:00
+++ 1.5/storage/ndb/src/common/util/md5_hash.cpp	2007-02-09 11:02:31 +00:00
@@ -214,6 +214,17 @@ void md5_hash(Uint32 result[4], const Ui
 
   if (no_of_32_words < 14) {
     byteReverse((unsigned char *)transform32_buf, 16);
+    /**
+     * FIXME: david.li
+     * It seems should fix as follows, otherwise the hash value
+     * will be different on big-enidan and little-endian machines.
+     * Also should consider same in the 'else' case.
+     */
+#if 0
+    transform32_buf[no_of_32_words] = 0x80000000;
+    transform32_buf[14] = len;
+    transform32_buf[15] = 0;
+#endif
     MD5Transform(buf, transform32_buf);
   } else {
     if (no_of_32_words == 14)

--- 1.34/storage/ndb/src/kernel/blocks/cmvmi/Cmvmi.cpp	2007-02-09 11:02:31 +00:00
+++ 1.35/storage/ndb/src/kernel/blocks/cmvmi/Cmvmi.cpp	2007-02-09 11:02:31 +00:00
@@ -218,8 +218,59 @@ void Cmvmi::execEVENT_REP(Signal* signal
     if(ptr.p->logLevel.getLogLevel(eventCategory) < threshold){
       continue;
     }
+    // judge whether need endian conversion
+    const Uint32 senderRef = ptr.p->blockRef;
+    const Uint32 senderNodeId = refToNode(senderRef);
+    const Uint32 ownNodeId = getOwnNodeId();
+    Uint32 senderEndian;
+    Uint32 ownEndian;
+    if (senderNodeId != 0 && senderNodeId != ownNodeId) {
+      senderEndian = getNodeInfo(senderNodeId).m_endian;
+      ownEndian = getNodeInfo(ownNodeId).m_endian;
+    } else {
+      senderEndian = ownEndian = getNodeInfo(ownNodeId).m_endian;
+    }
+
+    bool needConvertEndian = false;
+    if (senderEndian != ownEndian) {
+      needConvertEndian = true;
+    }
+
+    /**
+     * If the event type is InfoEvent or WarningEvent, it will send the char
+     * string event info to the MGM node.
+     * So if the endianness of MGM node and own node are different, should
+     * swap the char string event info here, so that no need to swap it on
+     * the MGM node.
+     */
+    if (needConvertEndian) {
+      switch(eventType) {
+      case NDB_LE_InfoEvent:
+      case NDB_LE_WarningEvent:
+        Uint32 noOfWords = signal->header.theLength - 1; //subtract theData[0]
+        swapManyWords32(&(signal->theData[1]), noOfWords);
+        break;
+      default:
+        break;
+      }
+    }
     
     sendSignal(ptr.p->blockRef, GSN_EVENT_REP, signal, signal->length(), JBB);
+
+    /**
+     * Turn it back again, so that it can be reused.
+     */
+    if (needConvertEndian) {
+      switch(eventType) {
+      case NDB_LE_InfoEvent:
+      case NDB_LE_WarningEvent:
+        Uint32 noOfWords = signal->header.theLength - 1; //subtract theData[0]
+        swapManyWords32(&(signal->theData[1]), noOfWords);
+        break;
+      default:
+        break;
+      }
+    }
   }
   
   if(clogLevel.getLogLevel(eventCategory) < threshold){

--- 1.107/storage/ndb/src/kernel/blocks/dbdict/Dbdict.cpp	2007-02-09 11:02:31 +00:00
+++ 1.108/storage/ndb/src/kernel/blocks/dbdict/Dbdict.cpp	2007-02-09 11:02:31 +00:00
@@ -346,12 +346,31 @@ void Dbdict::packTableIntoPages(Signal* 
   const Uint32 type= signal->theData[2];
   const Uint32 pageId= signal->theData[3];
 
+  // judge whether need endian conversion
+  const Uint32 senderRef = c_retrieveRecord.blockRef;
+  const Uint32 senderNodeId = refToNode(senderRef);
+  const Uint32 ownNodeId = getOwnNodeId();
+  Uint32 senderEndian;
+  Uint32 ownEndian;
+  if (senderNodeId != 0 && senderNodeId != ownNodeId) {
+    senderEndian = getNodeInfo(senderNodeId).m_endian;
+    ownEndian = getNodeInfo(ownNodeId).m_endian;
+  } else {
+    senderEndian = ownEndian = getNodeInfo(ownNodeId).m_endian;
+  }
+
+  bool needConvertEndian = false;
+  if (senderEndian != ownEndian) {
+    needConvertEndian = true;
+  }
+
   PageRecordPtr pagePtr;
   c_pageRecordArray.getPtr(pagePtr, pageId);
 
   memset(&pagePtr.p->word[0], 0, 4 * ZPAGE_HEADER_SIZE);
   LinearWriter w(&pagePtr.p->word[ZPAGE_HEADER_SIZE], 
-		 ZMAX_PAGES_OF_TABLE_DEFINITION * ZSIZE_OF_PAGES_IN_WORDS);
+		 ZMAX_PAGES_OF_TABLE_DEFINITION * ZSIZE_OF_PAGES_IN_WORDS,
+		 needConvertEndian);
   w.first();
   switch((DictTabInfo::TableType)type) {
   case DictTabInfo::SystemTable:
@@ -481,8 +500,6 @@ Dbdict::packTableIntoPages(SimplePropert
     Uint16 *data = (Uint16*)&signal->theData[25];
     Uint32 count = 2 + data[0] * data[1];
     w.add(DictTabInfo::ReplicaDataLen, 2*count);
-    for (Uint32 i = 0; i < count; i++)
-      data[i] = htons(data[i]);
     w.add(DictTabInfo::ReplicaData, data, 2*count);
   }
   else
@@ -3073,10 +3090,32 @@ Dbdict::restartCreateTab_readTableConf(S
   ParseDictTabInfoRecord parseRecord;
   parseRecord.requestType = DictTabInfo::GetTabInfoConf;
   parseRecord.errorCode = 0;
-  
+
+  /*
+   * FIXME: david.li
+   * Is this signal only sent around own node ??
+   */
+  // judge whether need endian conversion
+  const Uint32 senderRef = signal->senderBlockRef();
+  const Uint32 senderNodeId = refToNode(senderRef);
+  const Uint32 ownNodeId = getOwnNodeId();
+  Uint32 senderEndian;
+  Uint32 ownEndian;
+  if (senderNodeId != 0 && senderNodeId != ownNodeId) {
+    senderEndian = getNodeInfo(senderNodeId).m_endian;
+    ownEndian = getNodeInfo(ownNodeId).m_endian;
+  } else {
+    senderEndian = ownEndian = getNodeInfo(ownNodeId).m_endian;
+  }
+
+  bool needConvertEndian = false;
+  if (senderEndian != ownEndian) {
+    needConvertEndian = true;
+  }
+
   Uint32 sz = c_readTableRecord.no_of_words;
-  SimplePropertiesLinearReader r(pageRecPtr.p->word+ZPAGE_HEADER_SIZE, sz);
-  handleTabInfoInit(r, &parseRecord);
+  SimplePropertiesLinearReader r(pageRecPtr.p->word+ZPAGE_HEADER_SIZE, sz, needConvertEndian);
+  handleTabInfoInit(r, &parseRecord, true);
   if (parseRecord.errorCode != 0)
   {
     char buf[255];
@@ -3198,8 +3237,12 @@ Dbdict::execGET_TABINFO_CONF(Signal* sig
   parseRecord.requestType = DictTabInfo::GetTabInfoConf;
   parseRecord.errorCode = 0;
   
+  /**
+   * Because we convert endian in the reply of GET_TABINFOREQ,
+   * no need to convert endian here.
+   */
   SimplePropertiesSectionReader r(tabInfoPtr, getSectionSegmentPool());
-  handleTabInfoInit(r, &parseRecord);
+  handleTabInfoInit(r, &parseRecord, true);
   ndbrequire(parseRecord.errorCode == 0);
 
   // save to disk
@@ -3735,6 +3778,23 @@ Dbdict::execCREATE_TABLE_REQ(Signal* sig
   CreateTableReq* const req = (CreateTableReq*)signal->getDataPtr();
   const Uint32 senderRef = req->senderRef;
   const Uint32 senderData = req->senderData;
+
+  // judge whether need endian conversion
+  const Uint32 senderNodeId = refToNode(senderRef);
+  const Uint32 ownNodeId = getOwnNodeId();
+  Uint32 senderEndian;
+  Uint32 ownEndian;
+  if (senderNodeId != 0 && senderNodeId != ownNodeId) {
+    senderEndian = getNodeInfo(senderNodeId).m_endian;
+    ownEndian = getNodeInfo(ownNodeId).m_endian;
+  } else {
+    senderEndian = ownEndian = getNodeInfo(ownNodeId).m_endian;
+  }
+
+  bool needConvertEndian = false;
+  if (senderEndian != ownEndian) {
+    needConvertEndian = true;
+  }
   
   ParseDictTabInfoRecord parseRecord;
   do {
@@ -3770,9 +3830,9 @@ Dbdict::execCREATE_TABLE_REQ(Signal* sig
     
     SegmentedSectionPtr ptr;
     signal->getSection(ptr, CreateTableReq::DICT_TAB_INFO);
-    SimplePropertiesSectionReader r(ptr, getSectionSegmentPool());
+    SimplePropertiesSectionReader r(ptr, getSectionSegmentPool(), needConvertEndian);
     
-    handleTabInfoInit(r, &parseRecord);
+    handleTabInfoInit(r, &parseRecord, true);
     releaseSections(signal);
     
     if(parseRecord.errorCode != 0){
@@ -3791,6 +3851,10 @@ Dbdict::execCREATE_TABLE_REQ(Signal* sig
 
     Uint32 key = c_opRecordSequence + 1;
     Uint32 *theData = signal->getDataPtrSend(), i;
+    /*
+     * FIXME: david.li
+     * The fragment data is sent to the same node, no need to handle endian.
+     */
     Uint16 *frag_data= (Uint16*)&signal->theData[25];
     CreateFragmentationReq * const req = (CreateFragmentationReq*)theData;
     req->senderRef = reference();
@@ -3913,6 +3977,23 @@ Dbdict::execALTER_TABLE_REQ(Signal* sign
   const Uint32 tableId = req->tableId;
   const Uint32 tableVersion = req->tableVersion;
   ParseDictTabInfoRecord* aParseRecord;
+
+  // judge whether need endian conversion
+  const Uint32 senderNodeId = refToNode(senderRef);
+  const Uint32 ownNodeId = getOwnNodeId();
+  Uint32 senderEndian;
+  Uint32 ownEndian;
+  if (senderNodeId != 0 && senderNodeId != ownNodeId) {
+    senderEndian = getNodeInfo(senderNodeId).m_endian;
+    ownEndian = getNodeInfo(ownNodeId).m_endian;
+  } else {
+    senderEndian = ownEndian = getNodeInfo(ownNodeId).m_endian;
+  }
+
+  bool needConvertEndian = false;
+  if (senderEndian != ownEndian) {
+    needConvertEndian = true;
+  }
   
   // Get table definition
   TableRecordPtr tablePtr;
@@ -3998,7 +4079,7 @@ Dbdict::execALTER_TABLE_REQ(Signal* sign
   
   SegmentedSectionPtr ptr;
   signal->getSection(ptr, AlterTableReq::DICT_TAB_INFO);
-  SimplePropertiesSectionReader r(ptr, getSectionSegmentPool());
+  SimplePropertiesSectionReader r(ptr, getSectionSegmentPool(), needConvertEndian);
 
   handleTabInfoInit(r, &parseRecord, false); // Will not save info
   
@@ -4025,6 +4106,11 @@ Dbdict::execALTER_TABLE_REQ(Signal* sign
   alterTabPtr.p->m_dihAddFragPtr = RNIL;
   alterTabPtr.p->m_alterTableId = tablePtr.p->tableId;
 
+  /**
+   * FIXME: david.li
+   * No need handle endian problem here, it will be handled in
+   * execALTER_TAB_REQ().
+   */ 
   // Send prepare request to all alive nodes
   SimplePropertiesSectionWriter w(getSectionSegmentPool());
   packTableIntoPages(w, parseRecord.tablePtr);
@@ -4152,6 +4238,23 @@ Dbdict::execALTER_TAB_REQ(Signal * signa
   AlterTabReq::RequestType requestType = 
     (AlterTabReq::RequestType) req->requestType;
 
+  // judge whether need endian conversion
+  const Uint32 senderNodeId = refToNode(senderRef);
+  const Uint32 ownNodeId = getOwnNodeId();
+  Uint32 senderEndian;
+  Uint32 ownEndian;
+  if (senderNodeId != 0 && senderNodeId != ownNodeId) {
+    senderEndian = getNodeInfo(senderNodeId).m_endian;
+    ownEndian = getNodeInfo(ownNodeId).m_endian;
+  } else {
+    senderEndian = ownEndian = getNodeInfo(ownNodeId).m_endian;
+  }
+
+  bool needConvertEndian = false;
+  if (senderEndian != ownEndian) {
+    needConvertEndian = true;
+  }
+
   SegmentedSectionPtr tabInfoPtr;
   signal->getSection(tabInfoPtr, AlterTabReq::DICT_TAB_INFO);
 
@@ -4242,7 +4345,7 @@ Dbdict::execALTER_TAB_REQ(Signal * signa
       parseRecord.requestType = DictTabInfo::AlterTableFromAPI;
       parseRecord.errorCode = 0;
       
-      SimplePropertiesSectionReader r(tabInfoPtr, getSectionSegmentPool());
+      SimplePropertiesSectionReader r(tabInfoPtr, getSectionSegmentPool(), needConvertEndian);
       
       handleTabInfoInit(r, &parseRecord, false); // Will not save info
       
@@ -4404,6 +4507,11 @@ void Dbdict::execALTER_TAB_REF(Signal * 
       Uint32 tableId = tablePtr.p->tableId;
       Uint32 tableVersion = tablePtr.p->tableVersion;
       Uint32 gci = tablePtr.p->gciTableCreated;
+      /**
+       * FIXME: david.li
+       * No need handle endian problem here, it will be handled in
+       * execALTER_TAB_REQ().
+       */
       SimplePropertiesSectionWriter w(getSectionSegmentPool());
       packTableIntoPages(w, tablePtr);
       SegmentedSectionPtr spDataPtr;
@@ -4540,6 +4648,11 @@ Dbdict::execALTER_TAB_CONF(Signal * sign
 	Uint32 tableId = tablePtr.p->tableId;
 	Uint32 tableVersion = tablePtr.p->tableVersion;
 	Uint32 gci = tablePtr.p->gciTableCreated;
+        /**
+         * FIXME: david.li
+         * No need to handle endian problem here, it will be handled in
+         * execALTER_TAB_REQ().
+         */
 	SimplePropertiesSectionWriter w(getSectionSegmentPool());
 	packTableIntoPages(w, tablePtr);
 	SegmentedSectionPtr spDataPtr;
@@ -4569,6 +4682,11 @@ Dbdict::execALTER_TAB_CONF(Signal * sign
 	// Send commit request to all alive nodes
 	TableRecordPtr tablePtr;
 	c_tableRecordPool.getPtr(tablePtr, tableId);
+        /**
+         * FIXME: david.li
+         * No need to handle endian problem here, it will be handled in
+         * execALTER_TAB_REQ().
+         */
 	SimplePropertiesSectionWriter w(getSectionSegmentPool());
 	packTableIntoPages(w, tablePtr);
 	SegmentedSectionPtr spDataPtr;
@@ -4931,6 +5049,11 @@ Dbdict::execCREATE_FRAGMENTATION_CONF(Si
     create_obj_inc_schema_version(tabEntry->m_tableVersion);
 
   /**
+   * FIXME: david.li
+   * No need to handle endian problem here, it will be handled in
+   * execCREATE_TAB_REQ().
+   */
+  /**
    * Pack
    */
   SimplePropertiesSectionWriter w(getSectionSegmentPool());
@@ -5175,6 +5298,23 @@ Dbdict::createTab_prepare(Signal* signal
   const Uint32 gci = req->gci;
   const Uint32 tableId = req->tableId;
   const Uint32 tableVersion = req->tableVersion;
+  // judge whether need endian conversion
+  const Uint32 senderRef = req->senderRef;
+  const Uint32 senderNodeId = refToNode(senderRef);
+  const Uint32 ownNodeId = getOwnNodeId();
+  Uint32 senderEndian;
+  Uint32 ownEndian;
+  if (senderNodeId != 0 && senderNodeId != ownNodeId) {
+    senderEndian = getNodeInfo(senderNodeId).m_endian;
+    ownEndian = getNodeInfo(ownNodeId).m_endian;
+  } else {
+    senderEndian = ownEndian = getNodeInfo(ownNodeId).m_endian;
+  }
+
+  bool needConvertEndian = false;
+  if (senderEndian != ownEndian) {
+    needConvertEndian = true;
+  }
 
   SegmentedSectionPtr tabInfoPtr;
   signal->getSection(tabInfoPtr, CreateTabReq::DICT_TAB_INFO);
@@ -5205,9 +5345,9 @@ Dbdict::createTab_prepare(Signal* signal
     parseRecord.requestType = DictTabInfo::AddTableFromDict;
     parseRecord.errorCode = 0;
     
-    SimplePropertiesSectionReader r(tabInfoPtr, getSectionSegmentPool());
+    SimplePropertiesSectionReader r(tabInfoPtr, getSectionSegmentPool(), needConvertEndian);
     
-    handleTabInfoInit(r, &parseRecord);
+    handleTabInfoInit(r, &parseRecord, true);
 
     ndbrequire(parseRecord.errorCode == 0);
   }
@@ -7323,6 +7463,23 @@ void Dbdict::execGET_TABINFOREQ(Signal* 
   }  
 
   GetTabInfoReq * const req = (GetTabInfoReq *)&signal->theData[0];
+  // judge whether need endian conversion for table name
+  const Uint32 senderRef = req->senderRef;
+  const Uint32 senderNodeId = refToNode(senderRef);
+  const Uint32 ownNodeId = getOwnNodeId();
+  Uint32 senderEndian;
+  Uint32 ownEndian;
+  if (senderNodeId != 0 && senderNodeId != ownNodeId) {
+    senderEndian = getNodeInfo(senderNodeId).m_endian;
+    ownEndian = getNodeInfo(ownNodeId).m_endian;
+  } else {
+    senderEndian = ownEndian = getNodeInfo(ownNodeId).m_endian;
+  }
+
+  bool needConvertEndian = false;
+  if (senderEndian != ownEndian) {
+    needConvertEndian = true;
+  }
 
   /**
    * If I get a GET_TABINFO_REQ from myself
@@ -7379,7 +7536,7 @@ void Dbdict::execGET_TABINFOREQ(Signal* 
     char tableName[MAX_TAB_NAME_SIZE];
     SegmentedSectionPtr ssPtr;
     signal->getSection(ssPtr,GetTabInfoReq::TABLE_NAME);
-    SimplePropertiesSectionReader r0(ssPtr, getSectionSegmentPool());
+    SimplePropertiesSectionReader r0(ssPtr, getSectionSegmentPool(), needConvertEndian);
     r0.reset(); // undo implicit first()
     if(!r0.getWords((Uint32*)tableName, (len+3)/4)){
       jam();
@@ -7455,6 +7612,10 @@ void Dbdict::execGET_TABINFOREQ(Signal* 
     req->requestType= GetTabInfoReq::RequestById;
     req->tableId= obj_id;
 
+    /**
+     * FIXME: david.li
+     * Send to own node, no need handle byte order.
+     */
     sendSignal(TSMAN_REF, GSN_GET_TABINFOREQ, signal,
 	       GetTabInfoReq::SignalLength, JBB);
   }
@@ -7467,6 +7628,10 @@ void Dbdict::execGET_TABINFOREQ(Signal* 
     req->requestType= GetTabInfoReq::RequestById;
     req->tableId= obj_id;
 
+    /**
+     * FIXME: david.li
+     * Send to own node, no need handle byte order.
+     */
     sendSignal(LGMAN_REF, GSN_GET_TABINFOREQ, signal,
 	       GetTabInfoReq::SignalLength, JBB);
   }
@@ -7554,6 +7719,22 @@ Dbdict::execLIST_TABLES_REQ(Signal* sign
   conf->senderData = senderData;
   conf->counter = 0;
   Uint32 pos = 0;
+  // judge whether need endian conversion for table name
+  const Uint32 senderNodeId = refToNode(senderRef);
+  const Uint32 ownNodeId = getOwnNodeId();
+  Uint32 senderEndian;
+  Uint32 ownEndian;
+  if (senderNodeId != 0 && senderNodeId != ownNodeId) {
+    senderEndian = getNodeInfo(senderNodeId).m_endian;
+    ownEndian = getNodeInfo(ownNodeId).m_endian;
+  } else {
+    senderEndian = ownEndian = getNodeInfo(ownNodeId).m_endian;
+  }
+
+  bool needConvertEndian = false;
+  if (senderEndian != ownEndian) {
+    needConvertEndian = true;
+  }
 
   DLHashTable<DictObject>::Iterator iter;
   bool ok = c_obj_hash.first(iter);
@@ -7700,6 +7881,13 @@ Dbdict::execLIST_TABLES_REQ(Signal* sign
 	else
 	  *p++ = 0;
       }
+      // handle endian conversion for table name.
+      Uint32* tmpData = &conf->tableData[pos];
+      if (needConvertEndian) {
+        jam();
+        // need swap byte order for each 4-byte word of table name
+        swapManyWords32(tmpData, 1);
+      }
       pos++;
       if (pos >= ListTablesConf::DataLength) {
 	sendSignal(senderRef, GSN_LIST_TABLES_CONF, signal,
@@ -7799,6 +7987,10 @@ Dbdict::execCREATE_INDX_REQ(Signal* sign
     // save attribute list
     SegmentedSectionPtr ssPtr;
     signal->getSection(ssPtr, CreateIndxReq::ATTRIBUTE_LIST_SECTION);
+    /**
+     * FIXME: david.li
+     * Because type is Uint32, no need handle byte order here.
+     */
     SimplePropertiesSectionReader r0(ssPtr, getSectionSegmentPool());
     r0.reset(); // undo implicit first()
     if (! r0.getWord(&opPtr.p->m_attrList.sz) ||
@@ -7810,9 +8002,27 @@ Dbdict::execCREATE_INDX_REQ(Signal* sign
       createIndex_sendReply(signal, opPtr, opPtr.p->m_isMaster);
       return;
     }
+    // judge whether need endian conversion
+    const Uint32 clientRef = req->getUserRef();
+    const Uint32 clientNodeId = refToNode(clientRef);
+    const Uint32 ownNodeId = getOwnNodeId();
+    Uint32 clientEndian;
+    Uint32 ownEndian;
+    if (clientNodeId != 0 && clientNodeId != ownNodeId) {
+      clientEndian = getNodeInfo(clientNodeId).m_endian;
+      ownEndian = getNodeInfo(ownNodeId).m_endian;
+    } else {
+      clientEndian = ownEndian = getNodeInfo(ownNodeId).m_endian;
+    }
+
+    bool needConvertEndian = false;
+    if (clientEndian != ownEndian) {
+      needConvertEndian = true;
+    }
+
     // save name and index table properties
     signal->getSection(ssPtr, CreateIndxReq::INDEX_NAME_SECTION);
-    SimplePropertiesSectionReader r1(ssPtr, getSectionSegmentPool());
+    SimplePropertiesSectionReader r1(ssPtr, getSectionSegmentPool(), needConvertEndian);
     c_tableDesc.init();
     SimpleProperties::UnpackStatus status = SimpleProperties::unpack(
         r1, &c_tableDesc,
@@ -7954,6 +8164,10 @@ Dbdict::createIndex_slavePrepare(Signal*
 void
 Dbdict::createIndex_toCreateTable(Signal* signal, OpCreateIndexPtr opPtr)
 {
+  /**
+   * FIXME: david.li
+   * Send CREATE_TABLE_REQ to own node, no need to handle byte order here.
+   */
   union {
     char tableName[MAX_TAB_NAME_SIZE];
     char attributeName[MAX_ATTR_NAME_SIZE];
@@ -8913,6 +9127,10 @@ Dbdict::prepareUtilTransaction(Callback 
 			       Uint32 attrIds[],
 			       const char *attrNames[])
 {
+  /**
+   * FIXME: david.li
+   * Send to own node, no need consider endian problem
+   */
   jam();
   EVENT_TRACE;
 
@@ -9164,13 +9382,31 @@ Dbdict::createEvent_RT_USER_CREATE(Signa
   ndbout_c("mask = %s", buf);
 #endif
 
+  // judge whether need endian conversion
+  const Uint32 clientRef = evntRecPtr.p->m_request.getUserRef();
+  const Uint32 clientNodeId = refToNode(clientRef);
+  const Uint32 ownNodeId = getOwnNodeId();
+  Uint32 clientEndian;
+  Uint32 ownEndian;
+  if (clientNodeId != 0 && clientNodeId != ownNodeId) {
+    clientEndian = getNodeInfo(clientNodeId).m_endian;
+    ownEndian = getNodeInfo(ownNodeId).m_endian;
+  } else {
+    clientEndian = ownEndian = getNodeInfo(ownNodeId).m_endian;
+  }
+
+  bool needConvertEndian = false;
+  if (clientEndian != ownEndian) {
+    needConvertEndian = true;
+  }
+
   // Interpret the long signal
 
   SegmentedSectionPtr ssPtr;
   // save name and event properties
   signal->getSection(ssPtr, CreateEvntReq::EVENT_NAME_SECTION);
 
-  SimplePropertiesSectionReader r0(ssPtr, getSectionSegmentPool());
+  SimplePropertiesSectionReader r0(ssPtr, getSectionSegmentPool(), needConvertEndian);
 #ifdef EVENT_DEBUG
   r0.printAll(ndbout);
 #endif
@@ -9690,11 +9926,29 @@ Dbdict::createEvent_RT_USER_GET(Signal* 
   ndbout_c("DBDICT(Coordinator) got GSN_CREATE_EVNT_REQ::RT_USER_GET evntRecPtr.i = (%d), ref = %u", evntRecPtr.i, evntRecPtr.p->m_request.getUserRef());
 #endif
 
+  // judge whether need endian conversion
+  const Uint32 clientRef = evntRecPtr.p->m_request.getUserRef();
+  const Uint32 clientNodeId = refToNode(clientRef);
+  const Uint32 ownNodeId = getOwnNodeId();
+  Uint32 clientEndian;
+  Uint32 ownEndian;
+  if (clientNodeId != 0 && clientNodeId != ownNodeId) {
+    clientEndian = getNodeInfo(clientNodeId).m_endian;
+    ownEndian = getNodeInfo(ownNodeId).m_endian;
+  } else {
+    clientEndian = ownEndian = getNodeInfo(ownNodeId).m_endian;
+  }
+
+  bool needConvertEndian = false;
+  if (clientEndian != ownEndian) {
+    needConvertEndian = true;
+  }
+
   SegmentedSectionPtr ssPtr;
 
   signal->getSection(ssPtr, 0);
 
-  SimplePropertiesSectionReader r0(ssPtr, getSectionSegmentPool());
+  SimplePropertiesSectionReader r0(ssPtr, getSectionSegmentPool(), needConvertEndian);
 #ifdef EVENT_DEBUG
   r0.printAll(ndbout);
 #endif
@@ -9818,7 +10072,12 @@ void Dbdict::execCREATE_EVNT_CONF(Signal
   ptr[0].p = (Uint32 *)evntRecPtr.p->m_eventRec.TABLE_NAME;
   ptr[0].sz =
     (strlen(evntRecPtr.p->m_eventRec.TABLE_NAME)+4)/4; // to make sure we have a null
-
+  /**
+   * If the user node and own node have different endian,
+   * should swap the byte order of table name.
+   * But because this method will be call many times, will
+   * swap in createEvent_sendReply() instead of this method.
+   */
   createEvent_sendReply(signal, evntRecPtr, ptr, 1);
     
   return;
@@ -10005,6 +10264,33 @@ void Dbdict::createEvent_sendReply(Signa
 
   if (ptr) {
     jam();
+
+    // judge whether need endian conversion
+    const Uint32 senderNodeId = refToNode(senderRef);
+    const Uint32 ownNodeId = getOwnNodeId();
+    Uint32 senderEndian;
+    Uint32 ownEndian;
+    if (senderNodeId != 0 && senderNodeId != ownNodeId) {
+      senderEndian = getNodeInfo(senderNodeId).m_endian;
+      ownEndian = getNodeInfo(ownNodeId).m_endian;
+    } else {
+      senderEndian = ownEndian = getNodeInfo(ownNodeId).m_endian;
+    }
+
+    bool needConvertEndian = false;
+    if (senderEndian != ownEndian) {
+      needConvertEndian = true;
+    }
+
+    if (needConvertEndian) {
+      /**
+       * If the user node and own node have different endian,
+       * should swap the byte order of table name here, so that
+       * no need to handle it on user node.
+       */
+      swapManyWords32(ptr[0].p, ptr[0].sz);
+    }
+
     sendSignal(senderRef, gsn, signal, signalLength, JBB, ptr, noLSP);
   } else {
     jam();
@@ -10516,11 +10802,29 @@ Dbdict::execDROP_EVNT_REQ(Signal* signal
   OpDropEvent* evntRec = evntRecPtr.p;
   evntRec->init(req);
 
+  // judge whether need endian conversion
+  const Uint32 clientRef = evntRecPtr.p->m_request.getUserRef();
+  const Uint32 clientNodeId = refToNode(clientRef);
+  const Uint32 ownNodeId = getOwnNodeId();
+  Uint32 clientEndian;
+  Uint32 ownEndian;
+  if (clientNodeId != 0 && clientNodeId != ownNodeId) {
+    clientEndian = getNodeInfo(clientNodeId).m_endian;
+    ownEndian = getNodeInfo(ownNodeId).m_endian;
+  } else {
+    clientEndian = ownEndian = getNodeInfo(ownNodeId).m_endian;
+  }
+
+  bool needConvertEndian = false;
+  if (clientEndian != ownEndian) {
+    needConvertEndian = true;
+  }
+
   SegmentedSectionPtr ssPtr;
 
   signal->getSection(ssPtr, 0);
 
-  SimplePropertiesSectionReader r0(ssPtr, getSectionSegmentPool());
+  SimplePropertiesSectionReader r0(ssPtr, getSectionSegmentPool(), needConvertEndian);
 #ifdef EVENT_DEBUG
   r0.printAll(ndbout);
 #endif
@@ -12178,6 +12482,24 @@ Dbdict::execCREATE_TRIG_REQ(Signal* sign
           signal, CreateTrigReq::SignalLength + 1, JBB);
       return;
     }
+    // judge whether need endian conversion
+    const Uint32 clientRef = req->getUserRef();
+    const Uint32 clientNodeId = refToNode(clientRef);
+    const Uint32 ownNodeId = getOwnNodeId();
+    Uint32 clientEndian;
+    Uint32 ownEndian;
+    if (clientNodeId != 0 && clientNodeId != ownNodeId) {
+      clientEndian = getNodeInfo(clientNodeId).m_endian;
+      ownEndian = getNodeInfo(ownNodeId).m_endian;
+    } else {
+      clientEndian = ownEndian = getNodeInfo(ownNodeId).m_endian;
+    }
+
+    bool needConvertEndian = false;
+    if (clientEndian != ownEndian) {
+      needConvertEndian = true;
+    }
+
     // seize operation record
     ndbrequire(signal->getLength() == CreateTrigReq::SignalLength + 1);
     const Uint32 opKey = req->getOpKey();
@@ -12202,7 +12524,7 @@ Dbdict::execCREATE_TRIG_REQ(Signal* sign
       // save name
       SegmentedSectionPtr ssPtr;
       signal->getSection(ssPtr, CreateTrigReq::TRIGGER_NAME_SECTION);
-      SimplePropertiesSectionReader ssReader(ssPtr, getSectionSegmentPool());
+      SimplePropertiesSectionReader ssReader(ssPtr, getSectionSegmentPool(), needConvertEndian);
       if (ssReader.getKey() != CreateTrigReq::TriggerNameKey ||
 	  ! ssReader.getString(opPtr.p->m_triggerName)) {
 	jam();
@@ -12648,9 +12970,27 @@ Dbdict::execDROP_TRIG_REQ(Signal* signal
     OpDropTrigger opTmp;
     opPtr.p=&opTmp;
 
+    // judge whether need endian conversion
+    const Uint32 clientRef = req->getUserRef();
+    const Uint32 clientNodeId = refToNode(clientRef);
+    const Uint32 ownNodeId = getOwnNodeId();
+    Uint32 clientEndian;
+    Uint32 ownEndian;
+    if (clientNodeId != 0 && clientNodeId != ownNodeId) {
+      clientEndian = getNodeInfo(clientNodeId).m_endian;
+      ownEndian = getNodeInfo(ownNodeId).m_endian;
+    } else {
+      clientEndian = ownEndian = getNodeInfo(ownNodeId).m_endian;
+    }
+
+    bool needConvertEndian = false;
+    if (clientEndian != ownEndian) {
+      needConvertEndian = true;
+    }
+
     SegmentedSectionPtr ssPtr;
     signal->getSection(ssPtr, DropTrigReq::TRIGGER_NAME_SECTION);
-    SimplePropertiesSectionReader ssReader(ssPtr, getSectionSegmentPool());
+    SimplePropertiesSectionReader ssReader(ssPtr, getSectionSegmentPool(), needConvertEndian);
     if (ssReader.getKey() != DropTrigReq::TriggerNameKey ||
 	! ssReader.getString(triggerName)) {
       jam();
@@ -15447,12 +15787,30 @@ Dbdict::dropObj_abort_complete_done(Sign
 
 void 
 Dbdict::create_fg_prepare_start(Signal* signal, SchemaOp* op){
+  // judge whether need endian conversion
+  const Uint32 clientRef = op->m_clientRef;
+  const Uint32 clientNodeId = refToNode(clientRef);
+  const Uint32 ownNodeId = getOwnNodeId();
+  Uint32 clientEndian;
+  Uint32 ownEndian;
+  if (clientNodeId != 0 && clientNodeId != ownNodeId) {
+    clientEndian = getNodeInfo(clientNodeId).m_endian;
+    ownEndian = getNodeInfo(ownNodeId).m_endian;
+  } else {
+    clientEndian = ownEndian = getNodeInfo(ownNodeId).m_endian;
+  }
+
+  bool needConvertEndian = false;
+  if (clientEndian != ownEndian) {
+    needConvertEndian = true;
+  }
+
   /**
    * Put data into table record
    */
   SegmentedSectionPtr objInfoPtr;
   getSection(objInfoPtr, ((OpCreateObj*)op)->m_obj_info_ptr_i);
-  SimplePropertiesSectionReader it(objInfoPtr, getSectionSegmentPool());
+  SimplePropertiesSectionReader it(objInfoPtr, getSectionSegmentPool(), needConvertEndian);
 
   Ptr<DictObject> obj_ptr; obj_ptr.setNull();
   FilegroupPtr fg_ptr; fg_ptr.setNull();
@@ -15615,6 +15973,10 @@ Dbdict::create_fg_prepare_complete(Signa
     ndbrequire(false);
   }
   
+  /**
+   * FIXME: david.li
+   * Send to own node, no need handle byte order.
+   */
   sendSignal(ref, GSN_CREATE_FILEGROUP_REQ, signal, len, JBB);
 }
 
@@ -15677,12 +16039,30 @@ Dbdict::create_fg_abort_complete(Signal*
 
 void 
 Dbdict::create_file_prepare_start(Signal* signal, SchemaOp* op){
+  // judge whether need endian conversion
+  const Uint32 clientRef = op->m_clientRef;
+  const Uint32 clientNodeId = refToNode(clientRef);
+  const Uint32 ownNodeId = getOwnNodeId();
+  Uint32 clientEndian;
+  Uint32 ownEndian;
+  if (clientNodeId != 0 && clientNodeId != ownNodeId) {
+    clientEndian = getNodeInfo(clientNodeId).m_endian;
+    ownEndian = getNodeInfo(ownNodeId).m_endian;
+  } else {
+    clientEndian = ownEndian = getNodeInfo(ownNodeId).m_endian;
+  }
+
+  bool needConvertEndian = false;
+  if (clientEndian != ownEndian) {
+    needConvertEndian = true;
+  }
+
   /**
    * Put data into table record
    */
   SegmentedSectionPtr objInfoPtr;
   getSection(objInfoPtr, ((OpCreateObj*)op)->m_obj_info_ptr_i);
-  SimplePropertiesSectionReader it(objInfoPtr, getSectionSegmentPool());
+  SimplePropertiesSectionReader it(objInfoPtr, getSectionSegmentPool(), needConvertEndian);
   
   Ptr<DictObject> obj_ptr; obj_ptr.setNull();
   FilePtr filePtr; filePtr.setNull();
@@ -15870,6 +16250,10 @@ Dbdict::create_file_prepare_complete(Sig
     ndbrequire(false);
   }
   
+  /**
+   * FIXME: david.li
+   * Send to own node, no need to handle byte order.
+   */
   char name[MAX_TAB_NAME_SIZE];
   ConstRope tmp(c_rope_pool, f_ptr.p->m_path);
   tmp.copy(name);

--- 1.43/storage/ndb/src/kernel/blocks/dbdict/Dbdict.hpp	2007-02-09 11:02:31 +00:00
+++ 1.44/storage/ndb/src/kernel/blocks/dbdict/Dbdict.hpp	2007-02-09 11:02:31 +00:00
@@ -2146,7 +2146,9 @@ private:
   bool getNewAttributeRecord(TableRecordPtr tablePtr,
 			     AttributeRecordPtr & attrPtr);
   void packTableIntoPages(Signal* signal);
-  void packTableIntoPages(SimpleProperties::Writer &, TableRecordPtr, Signal* =0);
+  void packTableIntoPages(SimpleProperties::Writer &, 
+                          TableRecordPtr, 
+                          Signal* = 0);
   void packFilegroupIntoPages(SimpleProperties::Writer &,
 			      FilegroupPtr,
 			      const Uint32 undo_free_hi,

--- 1.91/storage/ndb/src/kernel/blocks/dbdih/DbdihMain.cpp	2007-02-09 11:02:32 +00:00
+++ 1.92/storage/ndb/src/kernel/blocks/dbdih/DbdihMain.cpp	2007-02-09 11:02:32 +00:00
@@ -6605,6 +6605,10 @@ void Dbdih::execCREATE_FRAGMENTATION_REQ
     TabRecordPtr primTabPtr;
     Uint32 count = 2;
     Uint16 noOfReplicas = cnoReplicas;
+    /*
+     * FIXME: david.li
+     * No need to handle endian for fragments.
+     */
     Uint16 *fragments = (Uint16*)(signal->theData+25);
     if (primaryTableId == RNIL) {
       jam();

--- 1.55/storage/ndb/src/kernel/blocks/dblqh/Dblqh.hpp	2007-02-09 11:02:32 +00:00
+++ 1.56/storage/ndb/src/kernel/blocks/dblqh/Dblqh.hpp	2007-02-09 11:02:32 +00:00
@@ -2574,6 +2574,7 @@ private:
   void acckeyconf_tupkeyreq(Signal*, TcConnectionrec*, Fragrecord*, Uint32, Uint32);
   void acckeyconf_load_diskpage(Signal*,TcConnectionrecPtr,Fragrecord*,Uint32);
   
+  bool handle_keydata_endian_conversion(Uint32 tabPtrI, Uint32* src, TcConnectionrecPtr regTcPtr);
   void handle_nr_copy(Signal*, Ptr<TcConnectionrec>);
   void exec_acckeyreq(Signal*, Ptr<TcConnectionrec>);
   int compare_key(const TcConnectionrec*, const Uint32 * ptr, Uint32 len);

--- 1.127/storage/ndb/src/kernel/blocks/dblqh/DblqhMain.cpp	2007-02-09 11:02:32 +00:00
+++ 1.128/storage/ndb/src/kernel/blocks/dblqh/DblqhMain.cpp	2007-02-09 11:02:32 +00:00
@@ -3390,6 +3390,17 @@ void Dblqh::execLQHKEYREQ(Signal* signal
   regTcPtr->transid[1] = sig2;
   regTcPtr->applRef = sig3;
   regTcPtr->applOprec = sig4;
+  /**
+   * Fixed for WL#3615.
+   */
+  if ((LqhKeyReq::getApplicationAddressFlag(Treqinfo) == 0) &&
+      (LqhKeyReq::getSameClientAndTcFlag(Treqinfo) == 0)) {
+    /**
+     * lqhKeyReq->variableData[0] is replaced by other data
+     * set applRef to regTcPtr->clientBlockref, ie. the sender.
+     */
+    regTcPtr->applRef = regTcPtr->clientBlockref;
+  }
 
   regTcPtr->commitAckMarker = RNIL;
   if(LqhKeyReq::getMarkerFlag(Treqinfo)){
@@ -3841,7 +3852,7 @@ void Dblqh::prepareContinueAfterBlockedL
       TRACENR(" rowid: " << regTcPtr->m_row_id);
     TRACENR(" key: " << regTcPtr->tupkeyData[0]);
   }
-  
+
   if (likely(activeCreat == Fragrecord::AC_NORMAL))
   {
     if (TRACENR_FLAG)
@@ -3915,6 +3926,17 @@ Dblqh::exec_acckeyreq(Signal* signal, Tc
   if (regTcPtr.p->primKeyLen > 4) {
     sendKeyinfoAcc(signal, 11);
   }//if
+
+  // handle key data endian conversion before sending to DBACC
+  Uint32 tabPtr = fragptr.p->tabRef;
+  Uint32 *src = &signal->theData[7];
+  jam();
+  bool ok = handle_keydata_endian_conversion(tabPtr, src, regTcPtr);
+  if (unlikely(!ok))
+  {
+    goto error;
+  }
+
   EXECUTE_DIRECT(refToBlock(regTcPtr.p->tcAccBlockref), GSN_ACCKEYREQ, 
 		 signal, 7 + regTcPtr.p->primKeyLen);
   if (signal->theData[0] < RNIL) {
@@ -3925,11 +3947,47 @@ Dblqh::exec_acckeyreq(Signal* signal, Tc
     ;
   } else {
     ndbrequire(signal->theData[0] == (UintR)-1);
+error:
     signal->theData[0] = regTcPtr.i;
     execACCKEYREF(signal);
   }//if
   return;
-}//Dblqh::prepareContinueAfterBlockedLab()
+}//Dblqh::exec_acckeyreq()
+
+bool
+Dblqh::handle_keydata_endian_conversion(Uint32 tabPtrI, Uint32* src, TcConnectionrecPtr regTcPtr)
+{
+  const BlockReference applBlockref= regTcPtr.p->applRef;
+  const Uint32 applNodeId = refToNode(applBlockref);
+  const BlockReference tcAccBlockref= regTcPtr.p->tcAccBlockref;
+  const Uint32 tcAccNodeId = refToNode(tcAccBlockref);
+  Uint32 applEndian;
+  Uint32 accEndian;
+  if (applNodeId != 0 && applNodeId != tcAccNodeId) {
+    applEndian = getNodeInfo(applNodeId).m_endian;
+    accEndian = getNodeInfo(tcAccNodeId).m_endian;
+  } else {
+    applEndian = accEndian = getNodeInfo(tcAccNodeId).m_endian;
+  }
+
+  bool needConvertEndian = false;
+  if (applEndian != accEndian) {
+    needConvertEndian = true;
+  }
+
+  if (needConvertEndian)
+  {
+    jam();
+
+    bool ok = convert_endian_key(tabPtrI, src);
+    if (unlikely(!ok))
+    {
+      return false;
+    }
+  }
+
+  return true;  // success
+}
 
 void
 Dblqh::handle_nr_copy(Signal* signal, Ptr<TcConnectionrec> regTcPtr)
@@ -6347,6 +6405,7 @@ void Dblqh::commitContinueAfterBlockedLa
       tupCommitReq->opPtr = sig0;
       tupCommitReq->gci = regTcPtr.p->gci;
       tupCommitReq->hashValue = regTcPtr.p->hashValue;
+      tupCommitReq->applRef = regTcPtr.p->applRef;
       EXECUTE_DIRECT(tup, GSN_TUP_COMMITREQ, signal, 
 		     TupCommitReq::SignalLength);
 

--- 1.42/storage/ndb/src/kernel/blocks/dbtc/Dbtc.hpp	2007-02-09 11:02:32 +00:00
+++ 1.43/storage/ndb/src/kernel/blocks/dbtc/Dbtc.hpp	2007-02-09 11:02:32 +00:00
@@ -1425,6 +1425,7 @@ private:
   void gcpTcfinished(Signal* signal);
   void handleGcp(Signal* signal);
   void hash(Signal* signal);
+  bool handle_keydata_endian_conversion(Uint32 tabPtrI, Uint32* src);
   bool handle_special_hash(Uint32 dstHash[4], 
 			     Uint32* src, Uint32 srcLen, 
 			     Uint32 tabPtrI, bool distr);

--- 1.125/storage/ndb/src/kernel/blocks/dbtc/DbtcMain.cpp	2007-02-09 11:02:32 +00:00
+++ 1.126/storage/ndb/src/kernel/blocks/dbtc/DbtcMain.cpp	2007-02-09 11:02:32 +00:00
@@ -2268,6 +2268,15 @@ void Dbtc::hash(Signal* signal) 
     }//while
   }//if
 
+  // handle key attribute endian conversion for the hash
+  Uint32 *src = &Tdata32[0];
+  jam();
+  bool ok = handle_keydata_endian_conversion(regCachePtr->tableref, src);
+  if (unlikely(!ok))
+  {
+    goto end;
+  }
+
   UintR keylen = (UintR)regCachePtr->keylen;
   Uint32 distKey = regCachePtr->distributionKeyIndicator;
   
@@ -2281,6 +2290,7 @@ void Dbtc::hash(Signal* signal) 
     handle_special_hash(tmp, Tdata32, keylen, regCachePtr->tableref, !distKey);
   }
   
+end:
   thashValue = tmp[0];
   if (distKey){
     jam();
@@ -2290,6 +2300,42 @@ void Dbtc::hash(Signal* signal) 
     tdistrHashValue = tmp[1];
   }//if
 }//Dbtc::hash()
+
+bool
+Dbtc::handle_keydata_endian_conversion(Uint32 tabPtrI, Uint32* src)
+{
+  const BlockReference apiBlockref= apiConnectptr.p->ndbapiBlockref;
+  const Uint32 apiNodeId = refToNode(apiBlockref);
+  const Uint32 ownNodeId = getOwnNodeId();
+  Uint32 apiEndian;
+  Uint32 ownEndian;
+  if (apiNodeId != 0 && apiNodeId != ownNodeId) {
+    apiEndian = getNodeInfo(apiNodeId).m_endian;
+    ownEndian = getNodeInfo(ownNodeId).m_endian;
+  } else {
+    apiEndian = ownEndian = getNodeInfo(ownNodeId).m_endian;
+  }
+
+  bool needConvertEndian = false;
+  if (apiEndian != ownEndian)
+  {
+    needConvertEndian = true;
+  }
+
+  if (needConvertEndian)
+  {
+    jam();
+
+    bool ok = convert_endian_key(tabPtrI, src);
+    if (unlikely(!ok))
+    {
+      terrorCode = ZINVALID_KEY;
+      return false;
+    }
+  }
+
+  return true;  // success
+}
 
 bool
 Dbtc::handle_special_hash(Uint32 dstHash[4], Uint32* src, Uint32 srcLen, 

--- 1.50/storage/ndb/src/kernel/blocks/dbtup/Dbtup.hpp	2007-02-09 11:02:32 +00:00
+++ 1.51/storage/ndb/src/kernel/blocks/dbtup/Dbtup.hpp	2007-02-09 11:02:32 +00:00
@@ -1961,6 +1961,7 @@ private:
   bool readDiskBitsNotNULL(Uint32*, KeyReqStruct*, AttributeHeader*, Uint32);
   bool updateDiskBitsNULLable(Uint32*, KeyReqStruct*, Uint32);
   bool updateDiskBitsNotNULL(Uint32*, KeyReqStruct*, Uint32);
+  void swapFixedSizeAttr(Uint32* attrBuffer, Uint32 attrDescriptor, Uint32 attrNoOfWords);
 
 
 //------------------------------------------------------------------

--- 1.17/storage/ndb/src/kernel/blocks/dbtup/DbtupCommit.cpp	2007-02-09 11:02:32 +00:00
+++ 1.18/storage/ndb/src/kernel/blocks/dbtup/DbtupCommit.cpp	2007-02-09 11:02:32 +00:00
@@ -435,6 +435,8 @@ void Dbtup::execTUP_COMMITREQ(Signal* si
   OperationrecPtr regOperPtr;
   TablerecPtr regTabPtr;
   KeyReqStruct req_struct;
+  // initialize rec_blockref in case use it later
+  req_struct.rec_blockref= 0;
   TransState trans_state;
   Uint32 no_of_fragrec, no_of_tablerec, hash_value, gci;
 
@@ -469,6 +471,7 @@ void Dbtup::execTUP_COMMITREQ(Signal* si
   req_struct.signal= signal;
   req_struct.hash_value= hash_value;
   req_struct.gci= gci;
+  req_struct.rec_blockref= tupCommitReq->applRef;
 
   ptrCheckGuard(regTabPtr, no_of_tablerec, tablerec);
 

--- 1.47/storage/ndb/src/kernel/blocks/dbtup/DbtupExecQuery.cpp	2007-02-09 11:02:32 +00:00
+++ 1.48/storage/ndb/src/kernel/blocks/dbtup/DbtupExecQuery.cpp	2007-02-09 11:02:32 +00:00
@@ -2926,6 +2926,8 @@ Dbtup::nr_read_pk(Uint32 fragPtrI, 
     return -1;
   
   KeyReqStruct req_struct;
+  // initialize rec_blockref in case use it later
+  req_struct.rec_blockref = 0;
   Uint32* ptr= ((Fix_page*)page_ptr.p)->get_ptr(key->m_page_idx, 0);
   
   req_struct.m_page_ptr = page_ptr;

--- 1.20/storage/ndb/src/kernel/blocks/dbtup/DbtupIndex.cpp	2007-02-09 11:02:32 +00:00
+++ 1.21/storage/ndb/src/kernel/blocks/dbtup/DbtupIndex.cpp	2007-02-09 11:02:32 +00:00
@@ -144,6 +144,8 @@ Dbtup::tuxReadAttrs(Uint32 fragPtrI,
 
   Operationrec tmpOp;
   KeyReqStruct req_struct;
+  // initialize rec_blockref in case use it later
+  req_struct.rec_blockref= 0;
   tmpOp.m_tuple_location.m_page_no= pageId;
   tmpOp.m_tuple_location.m_page_idx= pageIndex;
 
@@ -217,6 +219,8 @@ Dbtup::tuxReadPk(Uint32 fragPtrI, Uint32
   tmpOp.m_tuple_location.m_page_idx= pageIndex;
   
   KeyReqStruct req_struct;
+  // initialize rec_blockref in case use it later
+  req_struct.rec_blockref= 0;
  
   PagePtr page_ptr;
   Uint32* ptr= get_ptr(&page_ptr, &tmpOp.m_tuple_location, tablePtr.p);
@@ -343,6 +347,8 @@ Dbtup::tuxQueryTh(Uint32 fragPtrI,
   // use temp op rec
   Operationrec tempOp;
   KeyReqStruct req_struct;
+  // initialize rec_blockref in case use it later
+  req_struct.rec_blockref= 0;
   tempOp.m_tuple_location.m_page_no= getRealpid(fragPtr.p, fragPageId);
   tempOp.m_tuple_location.m_page_idx= pageIndex;
   tempOp.savepointId= savePointId;

--- 1.29/storage/ndb/src/kernel/blocks/dbtup/DbtupRoutines.cpp	2007-02-09 11:02:32 +00:00
+++ 1.30/storage/ndb/src/kernel/blocks/dbtup/DbtupRoutines.cpp	2007-02-09 11:02:32 +00:00
@@ -23,6 +23,7 @@
 #include <AttributeDescriptor.hpp>
 #include "AttributeOffset.hpp"
 #include <AttributeHeader.hpp>
+#include <ndb_endian.h>
 
 #define ljam() { jamLine(3000 + __LINE__); }
 #define ljamEntry() { jamEntryLine(3000 + __LINE__); }
@@ -224,6 +225,10 @@ int Dbtup::readAttributes(KeyReqStruct *
         return -1;
       }
     } else if(attributeId & AttributeHeader::PSEUDO) {
+      /*
+       * FIXME: david.li
+       * No need handle endian ??
+       */
       ljam();
       Uint32 sz= read_pseudo(attributeId,
                              req_struct,
@@ -250,11 +255,36 @@ Dbtup::readFixedSizeTHOneWordNotNULL(Uin
   Uint32 const wordRead= tuple_header[readOffset];
   Uint32 newIndexBuf= indexBuf + 1;
   Uint32 maxRead= req_struct->max_read;
+  const BlockReference apiBlockRef= req_struct->rec_blockref;
+  const Uint32 apiNodeId = refToNode(apiBlockRef);
+  const Uint32 ownNodeId = getOwnNodeId();
+  Uint32 apiEndian;
+  Uint32 ownEndian;
+  if (apiNodeId != 0 && apiNodeId != ownNodeId) {
+    /**
+     * execute remotely
+     */
+    apiEndian = getNodeInfo(apiNodeId).m_endian;
+    ownEndian = getNodeInfo(ownNodeId).m_endian;
+  } else {
+    /**
+     * execute directly
+     */
+    apiEndian = ownEndian = getNodeInfo(ownNodeId).m_endian;
+  }
+
+  bool needConvertEndian = false;
+  if (apiEndian != ownEndian) {
+    needConvertEndian = true;
+  }
 
   ndbrequire(readOffset < req_struct->check_offset[MM]);
   if (newIndexBuf <= maxRead) {
     ljam();
     outBuffer[indexBuf]= wordRead;
+    if (needConvertEndian) {
+      swapFixedSizeAttr(&outBuffer[indexBuf], req_struct->attr_descriptor, 1);
+    }
     ahOut->setDataSize(1);
     req_struct->out_buf_index= newIndexBuf;
     return true;
@@ -278,6 +308,28 @@ Dbtup::readFixedSizeTHTwoWordNotNULL(Uin
   Uint32 const wordReadSecond= tuple_header[readOffset + 1];
   Uint32 newIndexBuf= indexBuf + 2;
   Uint32 maxRead= req_struct->max_read;
+  const BlockReference apiBlockRef= req_struct->rec_blockref;
+  const Uint32 apiNodeId = refToNode(apiBlockRef);
+  const Uint32 ownNodeId = getOwnNodeId();
+  Uint32 apiEndian;
+  Uint32 ownEndian;
+  if (apiNodeId != 0 && apiNodeId != ownNodeId) {
+    /**
+     * execute remotely
+     */
+    apiEndian = getNodeInfo(apiNodeId).m_endian;
+    ownEndian = getNodeInfo(ownNodeId).m_endian;
+  } else {
+    /**
+     * execute directly
+     */
+    apiEndian = ownEndian = getNodeInfo(ownNodeId).m_endian;
+  }
+
+  bool needConvertEndian = false;
+  if (apiEndian != ownEndian) {
+    needConvertEndian = true;
+  }
 
   ndbrequire(readOffset + 1 < req_struct->check_offset[MM]);
   if (newIndexBuf <= maxRead) {
@@ -285,6 +337,9 @@ Dbtup::readFixedSizeTHTwoWordNotNULL(Uin
     ahOut->setDataSize(2);
     outBuffer[indexBuf]= wordReadFirst;
     outBuffer[indexBuf + 1]= wordReadSecond;
+    if (needConvertEndian) {
+      swapFixedSizeAttr(&outBuffer[indexBuf], req_struct->attr_descriptor, 2);
+    }
     req_struct->out_buf_index= newIndexBuf;
     return true;
   } else {
@@ -307,6 +362,28 @@ Dbtup::readFixedSizeTHManyWordNotNULL(Ui
   Uint32 attrNoOfWords= AttributeDescriptor::getSizeInWords(attrDescriptor);
   Uint32 maxRead= req_struct->max_read;
   Uint32 charsetFlag = AttributeOffset::getCharsetFlag(attrDes2);
+  const BlockReference apiBlockRef= req_struct->rec_blockref;
+  const Uint32 apiNodeId = refToNode(apiBlockRef);
+  const Uint32 ownNodeId = getOwnNodeId();
+  Uint32 apiEndian;
+  Uint32 ownEndian;
+  if (apiNodeId != 0 && apiNodeId != ownNodeId) {
+    /**
+     * execute remotely
+     */
+    apiEndian = getNodeInfo(apiNodeId).m_endian;
+    ownEndian = getNodeInfo(ownNodeId).m_endian;
+  } else {
+    /**
+     * execute directly
+     */
+    apiEndian = ownEndian = getNodeInfo(ownNodeId).m_endian;
+  }
+
+  bool needConvertEndian = false;
+  if (apiEndian != ownEndian) {
+    needConvertEndian = true;
+  }
 
   ndbrequire((readOffset + attrNoOfWords - 1) < req_struct->check_offset[MM]);
   if (! charsetFlag || ! req_struct->xfrm_flag) {
@@ -318,6 +395,10 @@ Dbtup::readFixedSizeTHManyWordNotNULL(Ui
                        &tuple_header[readOffset],
                        attrNoOfWords);
       req_struct->out_buf_index = newIndexBuf;
+
+      if (needConvertEndian) {
+        swapFixedSizeAttr(&outBuffer[indexBuf], attrDescriptor, attrNoOfWords);
+      }
       return true;
     } else {
       ljam();
@@ -353,6 +434,10 @@ Dbtup::readFixedSizeTHManyWordNotNULL(Ui
       Uint32 newIndexBuf = indexBuf + (m >> 2);
       ndbrequire(newIndexBuf <= maxRead);
       req_struct->out_buf_index = newIndexBuf;
+
+      if (needConvertEndian) {
+        swapFixedSizeAttr(&outBuffer[indexBuf], attrDescriptor, (m >> 2));
+      }
       return true;
     } else {
       ljam();
@@ -462,6 +547,28 @@ Dbtup::readVarSizeNotNULL(Uint32* out_bu
   Uint32 attr_descriptor, index_buf, var_index;
   Uint32 vsize_in_bytes, vsize_in_words, new_index, max_var_size;
   Uint32 var_attr_pos, max_read;
+  const BlockReference apiBlockRef= req_struct->rec_blockref;
+  const Uint32 apiNodeId = refToNode(apiBlockRef);
+  const Uint32 ownNodeId = getOwnNodeId();
+  Uint32 apiEndian;
+  Uint32 ownEndian;
+  if (apiNodeId != 0 && apiNodeId != ownNodeId) {
+    /**
+     * execute remotely
+     */
+    apiEndian = getNodeInfo(apiNodeId).m_endian;
+    ownEndian = getNodeInfo(ownNodeId).m_endian;
+  } else {
+    /**
+     * execute directly
+     */
+    apiEndian = ownEndian = getNodeInfo(ownNodeId).m_endian;
+  }
+
+  bool needConvertEndian = false;
+  if (apiEndian != ownEndian) {
+    needConvertEndian = true;
+  }
 
   Uint32 idx= req_struct->m_var_data[MM].m_var_len_offset;
   var_index= AttributeOffset::getOffset(attr_des2);
@@ -486,6 +593,14 @@ Dbtup::readVarSizeNotNULL(Uint32* out_bu
 	     req_struct->m_var_data[MM].m_data_ptr+var_attr_pos,
 	     vsize_in_bytes);
       req_struct->out_buf_index= new_index;
+
+      if (needConvertEndian) {
+        /*
+         * swap the byte order for each byte of each 4-byte word.
+         */
+        swapManyWords32(out_buffer+index_buf, vsize_in_words);
+      }
+
       return true;
     }
   }
@@ -522,6 +637,13 @@ Dbtup::readVarSizeNotNULL(Uint32* out_bu
       Uint32 newIndexBuf = index_buf + (m >> 2);
       ndbrequire(newIndexBuf <= max_read);
       req_struct->out_buf_index = newIndexBuf;
+
+      if (needConvertEndian) {
+        /*
+         * swap the byte order for each byte of each 4-byte word.
+         */
+        swapManyWords32(out_buffer+index_buf, m >> 2);
+      }
       return true;
     }
   }
@@ -584,6 +706,28 @@ Dbtup::readDiskFixedSizeNotNULL(Uint32* 
   Uint32 attrNoOfWords= AttributeDescriptor::getSizeInWords(attrDescriptor);
   Uint32 maxRead= req_struct->max_read;
   Uint32 charsetFlag = AttributeOffset::getCharsetFlag(attrDes2);
+  const BlockReference apiBlockRef= req_struct->rec_blockref;
+  const Uint32 apiNodeId = refToNode(apiBlockRef);
+  const Uint32 ownNodeId = getOwnNodeId();
+  Uint32 apiEndian;
+  Uint32 ownEndian;
+  if (apiNodeId != 0 && apiNodeId != ownNodeId) {
+    /**
+     * execute remotely
+     */
+    apiEndian = getNodeInfo(apiNodeId).m_endian;
+    ownEndian = getNodeInfo(ownNodeId).m_endian;
+  } else {
+    /**
+     * execute directly
+     */
+    apiEndian = ownEndian = getNodeInfo(ownNodeId).m_endian;
+  }
+
+  bool needConvertEndian = false;
+  if (apiEndian != ownEndian) {
+    needConvertEndian = true;
+  }
 
   ndbrequire((readOffset + attrNoOfWords - 1) < req_struct->check_offset[DD]);
   if (! charsetFlag || ! req_struct->xfrm_flag) {
@@ -595,6 +739,11 @@ Dbtup::readDiskFixedSizeNotNULL(Uint32* 
                        &tuple_header[readOffset],
                        attrNoOfWords);
       req_struct->out_buf_index = newIndexBuf;
+
+      if (needConvertEndian) {
+        swapFixedSizeAttr(&outBuffer[indexBuf], attrDescriptor, attrNoOfWords);
+      }
+
       return true;
     } else {
       ljam();
@@ -630,6 +779,11 @@ Dbtup::readDiskFixedSizeNotNULL(Uint32* 
       Uint32 newIndexBuf = indexBuf + (m >> 2);
       ndbrequire(newIndexBuf <= maxRead);
       req_struct->out_buf_index = newIndexBuf;
+
+      if (needConvertEndian) {
+        swapFixedSizeAttr(&outBuffer[indexBuf], attrDescriptor, (m >> 2));
+      }
+
       return true;
     } else {
       ljam();
@@ -667,6 +821,28 @@ Dbtup::readDiskVarSizeNotNULL(Uint32* ou
   Uint32 attr_descriptor, index_buf, var_index;
   Uint32 vsize_in_bytes, vsize_in_words, new_index, max_var_size;
   Uint32 var_attr_pos, max_read;
+  const BlockReference apiBlockRef= req_struct->rec_blockref;
+  const Uint32 apiNodeId = refToNode(apiBlockRef);
+  const Uint32 ownNodeId = getOwnNodeId();
+  Uint32 apiEndian;
+  Uint32 ownEndian;
+  if (apiNodeId != 0 && apiNodeId != ownNodeId) {
+    /**
+     * execute remotely
+     */
+    apiEndian = getNodeInfo(apiNodeId).m_endian;
+    ownEndian = getNodeInfo(ownNodeId).m_endian;
+  } else {
+    /**
+     * execute directly
+     */
+    apiEndian = ownEndian = getNodeInfo(ownNodeId).m_endian;
+  }
+
+  bool needConvertEndian = false;
+  if (apiEndian != ownEndian) {
+    needConvertEndian = true;
+  }
 
   Uint32 idx= req_struct->m_var_data[DD].m_var_len_offset;
   var_index= AttributeOffset::getOffset(attr_des2);
@@ -687,6 +863,14 @@ Dbtup::readDiskVarSizeNotNULL(Uint32* ou
 	   req_struct->m_var_data[DD].m_data_ptr+var_attr_pos,
 	   vsize_in_bytes);
     req_struct->out_buf_index= new_index;
+
+    if (needConvertEndian) {
+      /*
+       * swap the byte order for each byte of each 4-byte word.
+       */
+      swapManyWords32(out_buffer+index_buf, vsize_in_words);
+    }
+
     return true;
   } else {
     ljam();
@@ -778,6 +962,10 @@ int Dbtup::updateAttributes(KeyReqStruct
     } 
     else if(attributeId == AttributeHeader::DISK_REF)
     {
+      /*
+       * FIXME: david.li
+       * No need handle endian here ??
+       */
       ljam();
       Uint32 sz= ahIn.getDataSize();
       ndbrequire(sz == 2);
@@ -814,14 +1002,67 @@ Dbtup::checkUpdateOfPrimaryKey(KeyReqStr
   Uint32 xfrmBuffer[1 + MAX_KEY_SIZE_IN_WORDS * MAX_XFRM_MULTIPLY];
   Uint32 charsetFlag = AttributeOffset::getCharsetFlag(attributeOffset);
   if (charsetFlag) {
+    const BlockReference apiBlockRef= req_struct->rec_blockref;
+    const Uint32 apiNodeId = refToNode(apiBlockRef);
+    const Uint32 ownNodeId = getOwnNodeId();
+    Uint32 apiEndian;
+    Uint32 ownEndian;
+    if (apiNodeId != 0 && apiNodeId != ownNodeId) {
+      /**
+       * execute remotely
+       */
+      apiEndian = getNodeInfo(apiNodeId).m_endian;
+      ownEndian = getNodeInfo(ownNodeId).m_endian;
+    } else {
+      /**
+       * execute directly
+       */
+      apiEndian = ownEndian = getNodeInfo(ownNodeId).m_endian;
+    }
+
+    bool needConvertEndian = false;
+    if (apiEndian != ownEndian) {
+      needConvertEndian = true;
+    }
+
+    Uint32 tmpKeyBuffer[MAX_KEY_SIZE_IN_WORDS];
     Uint32 csIndex = AttributeOffset::getCharsetPos(attributeOffset);
     CHARSET_INFO* cs = regTabPtr->charsetArray[csIndex];
     Uint32 srcPos = 0;
     Uint32 dstPos = 0;
-    xfrm_attr(attrDescriptor, cs, &updateBuffer[1], srcPos,
+
+    Uint32 attrWords = ahIn.getDataSize();
+    Uint32 attrBytes = attrWords << 2;
+    memcpy(tmpKeyBuffer, updateBuffer, attrBytes);
+
+    if (needConvertEndian) {
+      // should swap byte order of attribute before calling xfrm_attr().
+      bool ok = convert_endian_attr(attrDescriptor, cs, tmpKeyBuffer, srcPos, true);
+      if (unlikely(!ok))
+        return false;
+    }
+
+    srcPos = 0;
+    dstPos = 0;
+
+    xfrm_attr(attrDescriptor, cs, &tmpKeyBuffer[1], srcPos,
               &xfrmBuffer[1], dstPos, MAX_KEY_SIZE_IN_WORDS * MAX_XFRM_MULTIPLY);
     ahIn.setDataSize(dstPos);
     xfrmBuffer[0] = ahIn.m_value;
+
+    srcPos = 0;
+
+    if (needConvertEndian) {
+      /*
+       * Then should turn back byte order of attribute, so that can compare with
+       * the data read, because the data read also is swapped byte order while
+       * reading if the sender and receiver have different endian.
+       */
+      bool ok = convert_endian_attr(attrDescriptor, cs, xfrmBuffer, srcPos, false);
+      if (unlikely(!ok))
+        return false;
+    }
+
     updateBuffer = xfrmBuffer;
   }
 
@@ -867,8 +1108,34 @@ Dbtup::updateFixedSizeTHOneWordNotNULL(U
   Uint32 newIndex= indexBuf + 2;
   Uint32 *tuple_header= req_struct->m_tuple_ptr->m_data;
   ndbrequire(updateOffset < req_struct->check_offset[MM]);
+  const BlockReference apiBlockRef= req_struct->rec_blockref;
+  const Uint32 apiNodeId = refToNode(apiBlockRef);
+  const Uint32 ownNodeId = getOwnNodeId();
+  Uint32 apiEndian;
+  Uint32 ownEndian;
+  if (apiNodeId != 0 && apiNodeId != ownNodeId) {
+    /**
+     * execute remotely
+     */
+    apiEndian = getNodeInfo(apiNodeId).m_endian;
+    ownEndian = getNodeInfo(ownNodeId).m_endian;
+  } else {
+    /**
+     * execute directly
+     */
+    apiEndian = ownEndian = getNodeInfo(ownNodeId).m_endian;
+  }
+
+  bool needConvertEndian = false;
+  if (apiEndian != ownEndian) {
+    needConvertEndian = true;
+  }
 
   if (newIndex <= inBufLen) {
+    if (needConvertEndian) {
+      swapFixedSizeAttr(&inBuffer[indexBuf + 1], req_struct->attr_descriptor, 1);
+    }
+
     Uint32 updateWord= inBuffer[indexBuf + 1];
     if (!nullIndicator) {
       ljam();
@@ -901,8 +1168,34 @@ Dbtup::updateFixedSizeTHTwoWordNotNULL(U
   Uint32 newIndex= indexBuf + 3;
   Uint32 *tuple_header= req_struct->m_tuple_ptr->m_data;
   ndbrequire((updateOffset + 1) < req_struct->check_offset[MM]);
+  const BlockReference apiBlockRef= req_struct->rec_blockref;
+  const Uint32 apiNodeId = refToNode(apiBlockRef);
+  const Uint32 ownNodeId = getOwnNodeId();
+  Uint32 apiEndian;
+  Uint32 ownEndian;
+  if (apiNodeId != 0 && apiNodeId != ownNodeId) {
+    /**
+     * execute remotely
+     */
+    apiEndian = getNodeInfo(apiNodeId).m_endian;
+    ownEndian = getNodeInfo(ownNodeId).m_endian;
+  } else {
+    /**
+     * execute directly
+     */
+    apiEndian = ownEndian = getNodeInfo(ownNodeId).m_endian;
+  }
+
+  bool needConvertEndian = false;
+  if (apiEndian != ownEndian) {
+    needConvertEndian = true;
+  }
 
   if (newIndex <= inBufLen) {
+    if (needConvertEndian) {
+      swapFixedSizeAttr(&inBuffer[indexBuf + 1], req_struct->attr_descriptor, 2);
+    }
+
     Uint32 updateWord1= inBuffer[indexBuf + 1];
     Uint32 updateWord2= inBuffer[indexBuf + 2];
     if (!nullIndicator) {
@@ -933,6 +1226,28 @@ Dbtup::updateFixedSizeTHManyWordNotNULL(
   Uint32 inBufLen= req_struct->in_buf_len;
   Uint32 updateOffset= AttributeOffset::getOffset(attrDes2);
   Uint32 charsetFlag = AttributeOffset::getCharsetFlag(attrDes2);
+  const BlockReference apiBlockRef= req_struct->rec_blockref;
+  const Uint32 apiNodeId = refToNode(apiBlockRef);
+  const Uint32 ownNodeId = getOwnNodeId();
+  Uint32 apiEndian;
+  Uint32 ownEndian;
+  if (apiNodeId != 0 && apiNodeId != ownNodeId) {
+    /**
+     * execute remotely
+     */
+    apiEndian = getNodeInfo(apiNodeId).m_endian;
+    ownEndian = getNodeInfo(ownNodeId).m_endian;
+  } else {
+    /**
+     * execute directly
+     */
+    apiEndian = ownEndian = getNodeInfo(ownNodeId).m_endian;
+  }
+
+  bool needConvertEndian = false;
+  if (apiEndian != ownEndian) {
+    needConvertEndian = true;
+  }
   
   AttributeHeader ahIn(inBuffer[indexBuf]);
   Uint32 noOfWords= AttributeDescriptor::getSizeInWords(attrDescriptor);
@@ -944,6 +1259,10 @@ Dbtup::updateFixedSizeTHManyWordNotNULL(
   if (newIndex <= inBufLen) {
     if (!nullIndicator) {
       ljam();
+      if (needConvertEndian) {
+        swapFixedSizeAttr(&inBuffer[indexBuf + 1], attrDescriptor, noOfWords);
+      }
+
       if (charsetFlag) {
         ljam();
         Tablerec* regTabPtr = tabptr.p;
@@ -973,7 +1292,7 @@ Dbtup::updateFixedSizeTHManyWordNotNULL(
       MEMCOPY_NO_WORDS(&tuple_header[updateOffset],
                        &inBuffer[indexBuf + 1],
                        noOfWords);
-      
+
       return true;
     } else {
       ljam();
@@ -1029,6 +1348,28 @@ Dbtup::updateVarSizeNotNULL(Uint32* in_b
   Uint32 var_attr_pos;
   char *var_data_start;
   Uint16 *vpos_array;
+  const BlockReference apiBlockRef= req_struct->rec_blockref;
+  const Uint32 apiNodeId = refToNode(apiBlockRef);
+  const Uint32 ownNodeId = getOwnNodeId();
+  Uint32 apiEndian;
+  Uint32 ownEndian;
+  if (apiNodeId != 0 && apiNodeId != ownNodeId) {
+    /**
+     * execute remotely
+     */
+    apiEndian = getNodeInfo(apiNodeId).m_endian;
+    ownEndian = getNodeInfo(ownNodeId).m_endian;
+  } else {
+    /**
+     * execute directly
+     */
+    apiEndian = ownEndian = getNodeInfo(ownNodeId).m_endian;
+  }
+
+  bool needConvertEndian = false;
+  if (apiEndian != ownEndian) {
+    needConvertEndian = true;
+  }
 
   attr_descriptor= req_struct->attr_descriptor;
   index_buf= req_struct->in_buf_index;
@@ -1052,9 +1393,17 @@ Dbtup::updateVarSizeNotNULL(Uint32* in_b
       vpos_array[var_index+idx]= var_attr_pos+size_in_bytes;
       req_struct->in_buf_index= new_index;
       
+      if (needConvertEndian) {
+        /*
+         * swap the byte order for each byte of each 4-byte word.
+         */
+        swapManyWords32(&in_buffer[index_buf + 1], vsize_in_words);
+      }
+
       ndbrequire(var_attr_pos+size_in_bytes <= check_offset);
       memcpy(var_data_start+var_attr_pos, &in_buffer[index_buf + 1],
 	     size_in_bytes);
+
       return true;
     } else {
       ljam();
@@ -1130,6 +1479,10 @@ Dbtup::read_pseudo(Uint32 attrId,
                    KeyReqStruct *req_struct,
                    Uint32* outBuffer)
 {
+/*
+ * FIXME: david.li
+ * whether need convert endian for Uint64 data here ??
+ */
   Uint32 tmp[sizeof(SignalHeader)+25];
   Signal * signal = (Signal*)&tmp;
   switch(attrId){
@@ -1217,6 +1570,29 @@ Dbtup::readBitsNotNULL(Uint32* outBuffer
   Uint32 newIndexBuf = indexBuf + ((bitCount + 31) >> 5);
   Uint32 maxRead = req_struct->max_read;
   Uint32 *bits= req_struct->m_tuple_ptr->get_null_bits(regTabPtr);
+  const BlockReference apiBlockRef= req_struct->rec_blockref;
+  const Uint32 apiNodeId = refToNode(apiBlockRef);
+  const Uint32 ownNodeId = getOwnNodeId();
+  Uint32 apiEndian;
+  Uint32 ownEndian;
+  if (apiNodeId != 0 && apiNodeId != ownNodeId) {
+    /**
+     * execute remotely
+     */
+    apiEndian = getNodeInfo(apiNodeId).m_endian;
+    ownEndian = getNodeInfo(ownNodeId).m_endian;
+  } else {
+    /**
+     * execute directly
+     */
+    apiEndian = ownEndian = getNodeInfo(ownNodeId).m_endian;
+  }
+
+  bool needConvertEndian = false;
+  if (apiEndian != ownEndian) {
+    needConvertEndian = true;
+  }
+
   if (newIndexBuf <= maxRead) {
     ljam();
     ahOut->setDataSize((bitCount + 31) >> 5);
@@ -1224,7 +1600,17 @@ Dbtup::readBitsNotNULL(Uint32* outBuffer
     
     BitmaskImpl::getField(regTabPtr->m_offsets[MM].m_null_words, bits, pos, 
 			  bitCount, outBuffer+indexBuf);
-    
+    Uint32 attrNoOfWords = (bitCount + 31) >> 5;
+    /**
+     * If the bit count is more than 32, the bits is stored in a Uint64 data,
+     * should swap it's byte order as Uint64.
+     * Else, the bits is stored in a Uint32 data, need not to swap byte order.
+     * The bit count is 64 at most.
+     */
+    if (needConvertEndian && attrNoOfWords == 2) {
+      swapManyWords64(&outBuffer[indexBuf], attrNoOfWords);
+    }
+
     return true;
   } else {
     ljam();
@@ -1248,7 +1634,29 @@ Dbtup::readBitsNULLable(Uint32* outBuffe
   Uint32 newIndexBuf = indexBuf + ((bitCount + 31) >> 5);
   Uint32 maxRead = req_struct->max_read;
   Uint32 *bits= req_struct->m_tuple_ptr->get_null_bits(regTabPtr);
-  
+  const BlockReference apiBlockRef= req_struct->rec_blockref;
+  const Uint32 apiNodeId = refToNode(apiBlockRef);
+  const Uint32 ownNodeId = getOwnNodeId();
+  Uint32 apiEndian;
+  Uint32 ownEndian;
+  if (apiNodeId != 0 && apiNodeId != ownNodeId) {
+    /**
+     * execute remotely
+     */
+    apiEndian = getNodeInfo(apiNodeId).m_endian;
+    ownEndian = getNodeInfo(ownNodeId).m_endian;
+  } else {
+    /**
+     * execute directly
+     */
+    apiEndian = ownEndian = getNodeInfo(ownNodeId).m_endian;
+  }
+
+  bool needConvertEndian = false;
+  if (apiEndian != ownEndian) {
+    needConvertEndian = true;
+  }
+ 
   if(BitmaskImpl::get(regTabPtr->m_offsets[MM].m_null_words, bits, pos))
   {
     ljam();
@@ -1262,6 +1670,17 @@ Dbtup::readBitsNULLable(Uint32* outBuffe
     req_struct->out_buf_index = newIndexBuf;
     BitmaskImpl::getField(regTabPtr->m_offsets[MM].m_null_words, bits, pos+1, 
 			  bitCount, outBuffer+indexBuf);
+    Uint32 attrNoOfWords = (bitCount + 31) >> 5;
+    /**
+     * If the bit count is more than 32, the bits is stored in a Uint64 data,
+     * should swap it's byte order as Uint64.
+     * Else, the bits is stored in a Uint32 data, need not to swap byte order.
+     * The bit count is 64 at most.
+     */
+    if (needConvertEndian && attrNoOfWords == 2) {
+      swapManyWords64(&outBuffer[indexBuf], attrNoOfWords);
+    }
+
     return true;
   } else {
     ljam();
@@ -1285,9 +1704,42 @@ Dbtup::updateBitsNotNULL(Uint32* inBuffe
     AttributeDescriptor::getArraySize(req_struct->attr_descriptor);
   Uint32 newIndex = indexBuf + 1 + ((bitCount + 31) >> 5);
   Uint32 *bits= req_struct->m_tuple_ptr->get_null_bits(regTabPtr);
-  
+  const BlockReference apiBlockRef= req_struct->rec_blockref;
+  const Uint32 apiNodeId = refToNode(apiBlockRef);
+  const Uint32 ownNodeId = getOwnNodeId();
+  Uint32 apiEndian;
+  Uint32 ownEndian;
+  if (apiNodeId != 0 && apiNodeId != ownNodeId) {
+    /**
+     * execute remotely
+     */
+    apiEndian = getNodeInfo(apiNodeId).m_endian;
+    ownEndian = getNodeInfo(ownNodeId).m_endian;
+  } else {
+    /**
+     * execute directly
+     */
+    apiEndian = ownEndian = getNodeInfo(ownNodeId).m_endian;
+  }
+
+  bool needConvertEndian = false;
+  if (apiEndian != ownEndian) {
+    needConvertEndian = true;
+  }
+ 
   if (newIndex <= inBufLen) {
     if (!nullIndicator) {
+      Uint32 attrNoOfWords = (bitCount + 31) >> 5;
+      /**
+       * If the bit count is more than 32, the bits is stored in a Uint64 data,
+       * should swap it's byte order as Uint64.
+       * Else, the bits is stored in a Uint32 data, need not to swap byte order.
+       * The bit count is 64 at most.
+       */
+      if (needConvertEndian && attrNoOfWords == 2) {
+        swapManyWords64(inBuffer+indexBuf+1, attrNoOfWords);
+      }
+
       BitmaskImpl::setField(regTabPtr->m_offsets[MM].m_null_words, bits, pos, 
 			    bitCount, inBuffer+indexBuf+1);
       req_struct->in_buf_index = newIndex;
@@ -1318,9 +1770,42 @@ Dbtup::updateBitsNULLable(Uint32* inBuff
   Uint32 bitCount = 
     AttributeDescriptor::getArraySize(req_struct->attr_descriptor);
   Uint32 *bits= req_struct->m_tuple_ptr->get_null_bits(regTabPtr);
-  
+  const BlockReference apiBlockRef= req_struct->rec_blockref;
+  const Uint32 apiNodeId = refToNode(apiBlockRef);
+  const Uint32 ownNodeId = getOwnNodeId();
+  Uint32 apiEndian;
+  Uint32 ownEndian;
+  if (apiNodeId != 0 && apiNodeId != ownNodeId) {
+    /**
+     * execute remotely
+     */
+    apiEndian = getNodeInfo(apiNodeId).m_endian;
+    ownEndian = getNodeInfo(ownNodeId).m_endian;
+  } else {
+    /**
+     * execute directly
+     */
+    apiEndian = ownEndian = getNodeInfo(ownNodeId).m_endian;
+  }
+
+  bool needConvertEndian = false;
+  if (apiEndian != ownEndian) {
+    needConvertEndian = true;
+  }
+ 
   if (!nullIndicator) {
     BitmaskImpl::clear(regTabPtr->m_offsets[MM].m_null_words, bits, pos);
+    Uint32 attrNoOfWords = (bitCount + 31) >> 5;
+    /**
+     * If the bit count is more than 32, the bits is stored in a Uint64 data,
+     * should swap it's byte order as Uint64.
+     * Else, the bits is stored in a Uint32 data, need not to swap byte order.
+     * The bit count is 64 at most.
+     */
+    if (needConvertEndian && attrNoOfWords == 2) {
+      swapManyWords64(inBuffer+indexBuf+1, attrNoOfWords);
+    }
+
     BitmaskImpl::setField(regTabPtr->m_offsets[MM].m_null_words, bits, pos+1, 
 			  bitCount, inBuffer+indexBuf+1);
     
@@ -1354,6 +1839,28 @@ Dbtup::updateDiskFixedSizeNotNULL(Uint32
   Uint32 inBufLen= req_struct->in_buf_len;
   Uint32 updateOffset= AttributeOffset::getOffset(attrDes2);
   Uint32 charsetFlag = AttributeOffset::getCharsetFlag(attrDes2);
+  const BlockReference apiBlockRef= req_struct->rec_blockref;
+  const Uint32 apiNodeId = refToNode(apiBlockRef);
+  const Uint32 ownNodeId = getOwnNodeId();
+  Uint32 apiEndian;
+  Uint32 ownEndian;
+  if (apiNodeId != 0 && apiNodeId != ownNodeId) {
+    /**
+     * execute remotely
+     */
+    apiEndian = getNodeInfo(apiNodeId).m_endian;
+    ownEndian = getNodeInfo(ownNodeId).m_endian;
+  } else {
+    /**
+     * execute directly
+     */
+    apiEndian = ownEndian = getNodeInfo(ownNodeId).m_endian;
+  }
+
+  bool needConvertEndian = false;
+  if (apiEndian != ownEndian) {
+    needConvertEndian = true;
+  }
   
   AttributeHeader ahIn(inBuffer[indexBuf]);
   Uint32 noOfWords= AttributeDescriptor::getSizeInWords(attrDescriptor);
@@ -1365,6 +1872,11 @@ Dbtup::updateDiskFixedSizeNotNULL(Uint32
   if (newIndex <= inBufLen) {
     if (!nullIndicator) {
       ljam();
+
+      if (needConvertEndian) {
+        swapFixedSizeAttr(&inBuffer[indexBuf + 1], attrDescriptor, noOfWords);
+      }
+
       if (charsetFlag) {
         ljam();
         Tablerec* regTabPtr = tabptr.p;
@@ -1449,6 +1961,28 @@ Dbtup::updateDiskVarSizeNotNULL(Uint32* 
   Uint32 var_attr_pos;
   char *var_data_start;
   Uint16 *vpos_array;
+  const BlockReference apiBlockRef= req_struct->rec_blockref;
+  const Uint32 apiNodeId = refToNode(apiBlockRef);
+  const Uint32 ownNodeId = getOwnNodeId();
+  Uint32 apiEndian;
+  Uint32 ownEndian;
+  if (apiNodeId != 0 && apiNodeId != ownNodeId) {
+    /**
+     * execute remotely
+     */
+    apiEndian = getNodeInfo(apiNodeId).m_endian;
+    ownEndian = getNodeInfo(ownNodeId).m_endian;
+  } else {
+    /**
+     * execute directly
+     */
+    apiEndian = ownEndian = getNodeInfo(ownNodeId).m_endian;
+  }
+
+  bool needConvertEndian = false;
+  if (apiEndian != ownEndian) {
+    needConvertEndian = true;
+  }
 
   attr_descriptor= req_struct->attr_descriptor;
   index_buf= req_struct->in_buf_index;
@@ -1471,7 +2005,14 @@ Dbtup::updateDiskVarSizeNotNULL(Uint32* 
       var_data_start= req_struct->m_var_data[DD].m_data_ptr;
       vpos_array[var_index+idx]= var_attr_pos+size_in_bytes;
       req_struct->in_buf_index= new_index;
-      
+
+      if (needConvertEndian) {
+        /*
+         * swap the byte order for each byte of each 4-byte word.
+         */
+        swapManyWords32(&in_buffer[index_buf + 1], vsize_in_words);
+      }
+
       ndbrequire(var_attr_pos+size_in_bytes <= check_offset);
       memcpy(var_data_start+var_attr_pos, &in_buffer[index_buf + 1],
 	     size_in_bytes);
@@ -1539,6 +2080,29 @@ Dbtup::readDiskBitsNotNULL(Uint32* outBu
   Uint32 newIndexBuf = indexBuf + ((bitCount + 31) >> 5);
   Uint32 maxRead = req_struct->max_read;
   Uint32 *bits= req_struct->m_disk_ptr->get_null_bits(regTabPtr, DD);
+  const BlockReference apiBlockRef= req_struct->rec_blockref;
+  const Uint32 apiNodeId = refToNode(apiBlockRef);
+  const Uint32 ownNodeId = getOwnNodeId();
+  Uint32 apiEndian;
+  Uint32 ownEndian;
+  if (apiNodeId != 0 && apiNodeId != ownNodeId) {
+    /**
+     * execute remotely
+     */
+    apiEndian = getNodeInfo(apiNodeId).m_endian;
+    ownEndian = getNodeInfo(ownNodeId).m_endian;
+  } else {
+    /**
+     * execute directly
+     */
+    apiEndian = ownEndian = getNodeInfo(ownNodeId).m_endian;
+  }
+
+  bool needConvertEndian = false;
+  if (apiEndian != ownEndian) {
+    needConvertEndian = true;
+  }
+
   if (newIndexBuf <= maxRead) {
     ljam();
     ahOut->setDataSize((bitCount + 31) >> 5);
@@ -1546,6 +2110,16 @@ Dbtup::readDiskBitsNotNULL(Uint32* outBu
     
     BitmaskImpl::getField(regTabPtr->m_offsets[DD].m_null_words, bits, pos, 
 			  bitCount, outBuffer+indexBuf);
+    Uint32 attrNoOfWords = (bitCount + 31) >> 5;
+    /**
+     * If the bit count is more than 32, the bits is stored in a Uint64 data,
+     * should swap it's byte order as Uint64.
+     * Else, the bits is stored in a Uint32 data, need not to swap byte order.
+     * The bit count is 64 at most.
+     */
+    if (needConvertEndian && attrNoOfWords == 2) {
+      swapManyWords64(&outBuffer[indexBuf], attrNoOfWords);
+    }
     
     return true;
   } else {
@@ -1570,7 +2144,29 @@ Dbtup::readDiskBitsNULLable(Uint32* outB
   Uint32 newIndexBuf = indexBuf + ((bitCount + 31) >> 5);
   Uint32 maxRead = req_struct->max_read;
   Uint32 *bits= req_struct->m_disk_ptr->get_null_bits(regTabPtr, DD);
-  
+  const BlockReference apiBlockRef= req_struct->rec_blockref;
+  const Uint32 apiNodeId = refToNode(apiBlockRef);
+  const Uint32 ownNodeId = getOwnNodeId();
+  Uint32 apiEndian;
+  Uint32 ownEndian;
+  if (apiNodeId != 0 && apiNodeId != ownNodeId) {
+    /**
+     * execute remotely
+     */
+    apiEndian = getNodeInfo(apiNodeId).m_endian;
+    ownEndian = getNodeInfo(ownNodeId).m_endian;
+  } else {
+    /**
+     * execute directly
+     */
+    apiEndian = ownEndian = getNodeInfo(ownNodeId).m_endian;
+  }
+
+  bool needConvertEndian = false;
+  if (apiEndian != ownEndian) {
+    needConvertEndian = true;
+  }
+ 
   if(BitmaskImpl::get(regTabPtr->m_offsets[DD].m_null_words, bits, pos))
   {
     ljam();
@@ -1584,6 +2180,17 @@ Dbtup::readDiskBitsNULLable(Uint32* outB
     req_struct->out_buf_index = newIndexBuf;
     BitmaskImpl::getField(regTabPtr->m_offsets[DD].m_null_words, bits, pos+1, 
 			  bitCount, outBuffer+indexBuf);
+    Uint32 attrNoOfWords = (bitCount + 31) >> 5;
+    /**
+     * If the bit count is more than 32, the bits is stored in a Uint64 data,
+     * should swap it's byte order as Uint64.
+     * Else, the bits is stored in a Uint32 data, need not to swap byte order.
+     * The bit count is 64 at most.
+     */
+    if (needConvertEndian && attrNoOfWords == 2) {
+      swapManyWords64(&outBuffer[indexBuf], attrNoOfWords);
+    }
+
     return true;
   } else {
     ljam();
@@ -1607,9 +2214,42 @@ Dbtup::updateDiskBitsNotNULL(Uint32* inB
     AttributeDescriptor::getArraySize(req_struct->attr_descriptor);
   Uint32 newIndex = indexBuf + 1 + ((bitCount + 31) >> 5);
   Uint32 *bits= req_struct->m_disk_ptr->get_null_bits(regTabPtr, DD);
-  
+  const BlockReference apiBlockRef= req_struct->rec_blockref;
+  const Uint32 apiNodeId = refToNode(apiBlockRef);
+  const Uint32 ownNodeId = getOwnNodeId();
+  Uint32 apiEndian;
+  Uint32 ownEndian;
+  if (apiNodeId != 0 && apiNodeId != ownNodeId) {
+    /**
+     * execute remotely
+     */
+    apiEndian = getNodeInfo(apiNodeId).m_endian;
+    ownEndian = getNodeInfo(ownNodeId).m_endian;
+  } else {
+    /**
+     * execute directly
+     */
+    apiEndian = ownEndian = getNodeInfo(ownNodeId).m_endian;
+  }
+
+  bool needConvertEndian = false;
+  if (apiEndian != ownEndian) {
+    needConvertEndian = true;
+  }
+ 
   if (newIndex <= inBufLen) {
     if (!nullIndicator) {
+      Uint32 attrNoOfWords = (bitCount + 31) >> 5;
+      /**
+       * If the bit count is more than 32, the bits is stored in a Uint64 data,
+       * should swap it's byte order as Uint64.
+       * Else, the bits is stored in a Uint32 data, need not to swap byte order.
+       * The bit count is 64 at most.
+       */
+      if (needConvertEndian && attrNoOfWords == 2) {
+        swapManyWords64(inBuffer+indexBuf+1, attrNoOfWords);
+      }
+
       BitmaskImpl::setField(regTabPtr->m_offsets[DD].m_null_words, bits, pos, 
 			    bitCount, inBuffer+indexBuf+1);
       req_struct->in_buf_index = newIndex;
@@ -1640,9 +2280,42 @@ Dbtup::updateDiskBitsNULLable(Uint32* in
   Uint32 bitCount = 
     AttributeDescriptor::getArraySize(req_struct->attr_descriptor);
   Uint32 *bits= req_struct->m_disk_ptr->get_null_bits(regTabPtr, DD);
-  
+  const BlockReference apiBlockRef= req_struct->rec_blockref;
+  const Uint32 apiNodeId = refToNode(apiBlockRef);
+  const Uint32 ownNodeId = getOwnNodeId();
+  Uint32 apiEndian;
+  Uint32 ownEndian;
+  if (apiNodeId != 0 && apiNodeId != ownNodeId) {
+    /**
+     * execute remotely
+     */
+    apiEndian = getNodeInfo(apiNodeId).m_endian;
+    ownEndian = getNodeInfo(ownNodeId).m_endian;
+  } else {
+    /**
+     * execute directly
+     */
+    apiEndian = ownEndian = getNodeInfo(ownNodeId).m_endian;
+  }
+
+  bool needConvertEndian = false;
+  if (apiEndian != ownEndian) {
+    needConvertEndian = true;
+  }
+ 
   if (!nullIndicator) {
     BitmaskImpl::clear(regTabPtr->m_offsets[DD].m_null_words, bits, pos);
+    Uint32 attrNoOfWords = (bitCount + 31) >> 5;
+    /**
+     * If the bit count is more than 32, the bits is stored in a Uint64 data,
+     * should swap it's byte order as Uint64.
+     * Else, the bits is stored in a Uint32 data, need not to swap byte order.
+     * The bit count is 64 at most.
+     */
+    if (needConvertEndian && attrNoOfWords == 2) {
+      swapManyWords64(inBuffer+indexBuf+1, attrNoOfWords);
+    }
+
     BitmaskImpl::setField(regTabPtr->m_offsets[DD].m_null_words, bits, pos+1, 
 			  bitCount, inBuffer+indexBuf+1);
     
@@ -1664,5 +2337,97 @@ Dbtup::updateDiskBitsNULLable(Uint32* in
       return false;
     }//if
   }//if
+}
+
+void
+Dbtup::swapFixedSizeAttr(Uint32* attrBuffer,
+                         Uint32 attrDescriptor,
+                         Uint32 attrNoOfWords)
+{
+  Uint32 typeId = AttributeDescriptor::getType(attrDescriptor);
+  Uint32 attrNoOfWords64 = (attrNoOfWords + 1) / 2;
+
+  switch (typeId) {
+  case NdbSqlUtil::Type::Tinyint:
+  case NdbSqlUtil::Type::Tinyunsigned:
+    /**
+     * 8 bits
+     * data is stored in the lowest 1 byte of a 4-byte word.
+     * should swap byte order for each byte of the word.
+     */
+    swapManyWords32(attrBuffer, attrNoOfWords);
+    break;
+  case NdbSqlUtil::Type::Smallint:
+  case NdbSqlUtil::Type::Smallunsigned:
+    /**
+     * 16 bits
+     * data is stored as Uint16.
+     * should swap byte order as Uint16.
+     */
+    swapManyWords16(attrBuffer, attrNoOfWords);
+    break;
+  case NdbSqlUtil::Type::Mediumint:
+  case NdbSqlUtil::Type::Mediumunsigned:
+    /**
+     * 24 bits
+     * data is stored in the lowest 3 bytes of a 4-byte word.
+     * should swap byte order for each byte of the word.
+     */
+    swapManyWords32(attrBuffer, attrNoOfWords);
+    break;
+  case NdbSqlUtil::Type::Bigint:
+  case NdbSqlUtil::Type::Bigunsigned:
+  case NdbSqlUtil::Type::Double:
+  case NdbSqlUtil::Type::Datetime:
+    /**
+     * 64 bits
+     * data is stored as Uint64.
+     * should swap byte order as Uint64.
+     */
+    swapManyWords64(attrBuffer, attrNoOfWords64 << 1);
+    break;
+  case NdbSqlUtil::Type::Olddecimal:
+  case NdbSqlUtil::Type::Olddecimalunsigned:
+  case NdbSqlUtil::Type::Decimal :
+  case NdbSqlUtil::Type::Decimalunsigned :
+  case NdbSqlUtil::Type::Char:
+  case NdbSqlUtil::Type::Binary:
+    /**
+     * data is stored in the byte order of character string.
+     * should swap byte order for each byte.
+     */
+    swapManyWords32(attrBuffer, attrNoOfWords);
+    break;
+  case NdbSqlUtil::Type::Date:
+  case NdbSqlUtil::Type::Time:
+    /**
+     * 24 bits
+     * data is stored in the lowest 3 bytes of a 4-byte word.
+     * should swap byte order for each byte of the word.
+     */
+    swapManyWords32(attrBuffer, attrNoOfWords);
+    break;
+  case NdbSqlUtil::Type::Blob:
+  case NdbSqlUtil::Type::Text:
+    /**
+     * The first 8 bytes of the Blob/Text data is a Uint64 data,
+     * should swap the byte order of it as Uint64.
+     * The left data of Blob/Text is stored as character string, 
+     * should swap the byte order for each byte of it.
+     */
+    swapManyWords64(attrBuffer, 2);
+    swapManyWords32(attrBuffer + 2, attrNoOfWords - 2);
+    break;
+  case NdbSqlUtil::Type::Year:
+    /**
+     * 8 bits
+     * data is stored in the lowest 1 byte of a 4-byte word.
+     * should swap byte order for each byte of the word.
+     */
+    swapManyWords32(attrBuffer, attrNoOfWords);
+    break;
+  default:
+    break;
+  }
 }
 

--- 1.25/storage/ndb/src/kernel/blocks/dbtup/DbtupTrigger.cpp	2007-02-09 11:02:32 +00:00
+++ 1.26/storage/ndb/src/kernel/blocks/dbtup/DbtupTrigger.cpp	2007-02-09 11:02:32 +00:00
@@ -695,6 +695,15 @@ void Dbtup::executeTrigger(KeyReqStruct 
       return;
     }
   }
+  /**
+   * If the attr info receiver is TC block, should change
+   * req_struct->rec_blockref to TC_ref to let readAttributes()
+   * to convert endian correctly.
+   */
+  if (trigPtr->triggerType == TriggerType::SECONDARY_INDEX) {
+    ljam();
+    req_struct->rec_blockref = req_struct->TC_ref;
+  }
   if (!readTriggerInfo(trigPtr,
                        regOperPtr,
                        req_struct,

--- 1.17/storage/ndb/src/kernel/blocks/dbutil/DbUtil.cpp	2007-02-09 11:02:32 +00:00
+++ 1.18/storage/ndb/src/kernel/blocks/dbutil/DbUtil.cpp	2007-02-09 11:02:32 +00:00
@@ -881,6 +881,10 @@ void DbUtil::readPrepareProps(Signal* si
       LinearSectionPtr ptr[1];
       ptr[0].p = (Uint32*)tableName; 
       ptr[0].sz = req->tableNameLen; 
+      /**
+       * FIXME: david.li
+       * Send to own node, no need consider endian problem.
+       */
       sendSignal(DBDICT_REF, GSN_GET_TABINFOREQ, signal, 
 		 GetTabInfoReq::SignalLength, JBB, ptr,1);
 

--- 1.41/storage/ndb/src/kernel/blocks/qmgr/QmgrMain.cpp	2007-02-09 11:02:32 +00:00
+++ 1.42/storage/ndb/src/kernel/blocks/qmgr/QmgrMain.cpp	2007-02-09 11:02:32 +00:00
@@ -37,6 +37,7 @@
 #include <signaldata/ApiBroadcast.hpp>
 
 #include <ndb_version.h>
+#include <ndb_endian.h>
 
 #ifdef DEBUG_ARBIT
 #include <NdbOut.hpp>
@@ -989,6 +990,7 @@ Qmgr::sendCmNodeInfoReq(Signal* signal, 
   req->nodeId = getOwnNodeId();
   req->dynamicId = self->ndynamicId;
   req->version = getNodeInfo(getOwnNodeId()).m_version;
+  req->endian = getNodeInfo(getOwnNodeId()).m_endian;
   const Uint32 ref = calcQmgrBlockRef(nodeId);
   sendSignal(ref,GSN_CM_NODEINFOREQ, signal, CmNodeInfoReq::SignalLength, JBB);
   DEBUG_START(GSN_CM_NODEINFOREQ, nodeId, "");
@@ -1503,6 +1505,7 @@ void Qmgr::execCM_NODEINFOCONF(Signal* s
   replyNodePtr.p->ndynamicId = dynamicId;
   replyNodePtr.p->blockRef = signal->getSendersBlockRef();
   setNodeInfo(replyNodePtr.i).m_version = version;
+  setNodeInfo(replyNodePtr.i).m_endian = conf->endian;
 
   if(!c_start.m_nodes.done()){
     jam();
@@ -1554,6 +1557,7 @@ void Qmgr::execCM_NODEINFOREQ(Signal* si
   addNodePtr.p->ndynamicId = req->dynamicId;
   addNodePtr.p->blockRef = signal->getSendersBlockRef();
   setNodeInfo(addNodePtr.i).m_version = req->version;
+  setNodeInfo(addNodePtr.i).m_endian = req->endian;
   c_maxDynamicId = req->dynamicId;
 
   cmAddPrepare(signal, addNodePtr, nodePtr.p);
@@ -1608,6 +1612,7 @@ Qmgr::cmAddPrepare(Signal* signal, NodeR
   conf->nodeId = getOwnNodeId();
   conf->dynamicId = self->ndynamicId;
   conf->version = getNodeInfo(getOwnNodeId()).m_version;
+  conf->endian = getNodeInfo(getOwnNodeId()).m_endian;
   sendSignal(nodePtr.p->blockRef, GSN_CM_NODEINFOCONF, signal,
 	     CmNodeInfoConf::SignalLength, JBB);
   DEBUG_START(GSN_CM_NODEINFOCONF, refToNode(nodePtr.p->blockRef), "");
@@ -2118,6 +2123,10 @@ void Qmgr::initData(Signal* signal) 
     execARBIT_CFG(signal);
   }
   setNodeInfo(getOwnNodeId()).m_version = NDB_VERSION;
+  /**
+   * Set the endian info of own node.
+   */
+  setNodeInfo(getOwnNodeId()).m_endian = checkEndian();
 }//Qmgr::initData()
 
 
@@ -2665,6 +2674,7 @@ void Qmgr::execAPI_REGREQ(Signal* signal
   
   ApiRegReq* req = (ApiRegReq*)signal->getDataPtr();
   const Uint32 version = req->version;
+  const Uint32 endian = req->endian;
   const BlockReference ref = req->ref;
   
   NodeRecPtr apiNodePtr;
@@ -2707,6 +2717,10 @@ void Qmgr::execAPI_REGREQ(Signal* signal
   }
 
   setNodeInfo(apiNodePtr.i).m_version = version;
+  // store the endian of API node
+  if(getNodeInfo(apiNodePtr.i).m_endian != endian){
+    setNodeInfo(apiNodePtr.i).m_endian = endian;
+  }
 
   setNodeInfo(apiNodePtr.i).m_heartbeat_cnt= 0;
 
@@ -2714,6 +2728,12 @@ void Qmgr::execAPI_REGREQ(Signal* signal
   apiRegConf->qmgrRef = reference();
   apiRegConf->apiHeartbeatFrequency = (chbApiDelay / 10);
   apiRegConf->version = NDB_VERSION;
+  /**
+   * Because some API_REGREQ will come ealier than execution of Qmgr::initData(),
+   * here call checkEndian() instead of getNodeInfo().
+   */
+  //apiRegConf->endian = getNodeInfo(getOwnNodeId()).m_endian;
+  apiRegConf->endian = checkEndian();
   NodeState state= apiRegConf->nodeState = getNodeState();
   {
     NodeRecPtr nodePtr;
@@ -2763,12 +2783,40 @@ Qmgr::execAPI_VERSION_REQ(Signal * signa
   Uint32 senderRef = req->senderRef;
   Uint32 nodeId = req->nodeId;
 
+  // judge whether need endian conversion
+  const Uint32 senderNodeId = refToNode(senderRef);
+  const Uint32 ownNodeId = getOwnNodeId();
+  Uint32 senderEndian;
+  Uint32 ownEndian;
+  if (senderNodeId != 0 && senderNodeId != ownNodeId) {
+    senderEndian = getNodeInfo(senderNodeId).m_endian;
+    ownEndian = getNodeInfo(ownNodeId).m_endian;
+  } else {
+    senderEndian = ownEndian = getNodeInfo(ownNodeId).m_endian;
+  }
+
+  bool needConvertEndian = false;
+  if (senderEndian != ownEndian) {
+    needConvertEndian = true;
+  }
+
   ApiVersionConf * conf = (ApiVersionConf *)req;
   if(getNodeInfo(nodeId).m_connected)
   {
     conf->version =  getNodeInfo(nodeId).m_version;
     struct in_addr in= globalTransporterRegistry.get_connect_address(nodeId);
     conf->inet_addr= in.s_addr;
+    /**
+     * If the endian of the sender and receiver are different, the byte 
+     * order of conf->inet_addr will be swapped, but conf->inet_addr
+     * already is network byte order before sending, so it is needed to
+     * turn back its byte order again.
+     * Swap the byte order before sending instead of turning it back on
+     * API node.
+     */
+    if (needConvertEndian) {
+      swapManyWords32(&(conf->inet_addr), sizeof(conf->inet_addr)>>2);
+    }
   }
   else
   {

--- 1.3/storage/ndb/src/kernel/vm/SimplePropertiesSection.cpp	2007-02-09 11:02:32 +00:00
+++ 1.4/storage/ndb/src/kernel/vm/SimplePropertiesSection.cpp	2007-02-09 11:02:32 +00:00
@@ -17,9 +17,10 @@
 #include <SimpleProperties.hpp>
 #include <TransporterDefinitions.hpp>
 #include "LongSignal.hpp"
+#include <ndb_endian.h>
 
 SimplePropertiesSectionReader::SimplePropertiesSectionReader
-(struct SegmentedSectionPtr & ptr, class SectionSegmentPool & pool)
+(struct SegmentedSectionPtr & ptr, class SectionSegmentPool & pool, bool needConvertEndian)
   : m_pool(pool)
 {
   if(ptr.p == 0){
@@ -27,11 +28,13 @@ SimplePropertiesSectionReader::SimplePro
     m_len = 0;
     m_head = 0;
     m_currentSegment = 0;
+    m_convertEndian = needConvertEndian;
   } else {
     m_pos = 0;
     m_len = ptr.p->m_sz;
     m_head = ptr.p;
     m_currentSegment = ptr.p;
+    m_convertEndian = needConvertEndian;
   }
   first();
 }
@@ -112,14 +115,24 @@ SimplePropertiesSectionReader::peekWords
 
 bool
 SimplePropertiesSectionReader::getWords(Uint32 * dst, Uint32 len){
+  bool need_convert_endian = needConvertEndian();
   if(peekWords(dst, len)){
+    if (need_convert_endian && len > 0) {
+      swapManyWords32(dst, len);
+    }
     step(len);
     return true;
   }
   return false;
 }
 
-SimplePropertiesSectionWriter::SimplePropertiesSectionWriter(class SectionSegmentPool & pool)
+bool
+SimplePropertiesSectionReader::needConvertEndian() const {
+  return m_convertEndian;
+}
+
+SimplePropertiesSectionWriter::SimplePropertiesSectionWriter(class SectionSegmentPool & pool,
+							     bool needConvertEndian)
   : m_pool(pool)
 {
   Ptr<SectionSegment> first;
@@ -130,6 +143,7 @@ SimplePropertiesSectionWriter::SimplePro
     m_head = 0;
     m_currentSegment = 0;
     m_prevPtrI = RNIL;
+    m_convertEndian = needConvertEndian;
     return;
   }
   m_sz = 0;
@@ -138,6 +152,7 @@ SimplePropertiesSectionWriter::SimplePro
   m_head->m_lastSegment = first.i;
   m_currentSegment = first.p;
   m_prevPtrI = RNIL;
+  m_convertEndian = needConvertEndian;
 }
   
 bool
@@ -220,4 +235,9 @@ SimplePropertiesSectionWriter::getPtr(st
   m_pos = -1;
   m_head = m_currentSegment = 0;
   m_prevPtrI = RNIL;
+}
+
+bool
+SimplePropertiesSectionWriter::needConvertEndian() const {
+  return m_convertEndian;
 }

--- 1.35/storage/ndb/src/kernel/vm/SimulatedBlock.cpp	2007-02-09 11:02:32 +00:00
+++ 1.36/storage/ndb/src/kernel/vm/SimulatedBlock.cpp	2007-02-09 11:02:32 +00:00
@@ -2053,5 +2053,209 @@ SimulatedBlock::create_distr_key(Uint32 
   return dstPos;
 }
 
+bool
+SimulatedBlock::convert_endian_key(Uint32 tab, Uint32* src) const
+{
+  const KeyDescriptor * desc = g_key_descriptor_pool.getPtr(tab);
+  const Uint32 noOfKeyAttr = desc->noOfKeyAttr;
+
+  Uint32 i = 0;
+  Uint32 srcPos = 0;
+  while (i < noOfKeyAttr) 
+  {
+    const KeyDescriptor::KeyAttr& keyAttr = desc->keyAttr[i];
+    bool ok =
+      convert_endian_attr(keyAttr.attributeDescriptor, keyAttr.charsetInfo,
+                src, srcPos, true);
+    if (unlikely(!ok))
+      return false;
+
+    i++;
+  }
+
+  return true;
+}
+
+bool
+SimulatedBlock::convert_endian_attr(Uint32 attrDesc, CHARSET_INFO* cs,
+                          Uint32* src, Uint32& srcPos, bool swapFirstWord) const
+{
+  Uint32 attrBytes = AttributeDescriptor::getSizeInBytes(attrDesc);
+  Uint32 attrNoOfWords= AttributeDescriptor::getSizeInWords(attrDesc);
+  Uint32 attrNoOfWords64 = (attrNoOfWords + 1) / 2;
+  Uint32 typeId = AttributeDescriptor::getType(attrDesc);
+  bool ok = false;
+
+
+  switch (typeId) {
+  case NdbSqlUtil::Type::Tinyint:
+  case NdbSqlUtil::Type::Tinyunsigned:
+    /**
+     * 8 bits
+     * data is stored in the lowest 1 byte of a 4-byte word.
+     * should swap byte order for each byte of the word.
+     */
+    swapManyWords32((Uint32*)((char*)src + srcPos), attrNoOfWords);
+    break;
+  case NdbSqlUtil::Type::Smallint:
+  case NdbSqlUtil::Type::Smallunsigned:
+    /**
+     * 16 bits
+     * data is stored as Uint16.
+     * should swap byte order as Uint16.
+     */
+    swapManyWords16((Uint32*)((char*)src + srcPos), attrNoOfWords);
+    break;
+  case NdbSqlUtil::Type::Mediumint:
+  case NdbSqlUtil::Type::Mediumunsigned:
+    /**
+     * 24 bits
+     * data is stored in the lowest 3 bytes of a 4-byte word.
+     * should swap byte order for each byte of the word.
+     */
+    swapManyWords32((Uint32*)((char*)src + srcPos), attrNoOfWords);
+    break;
+  case NdbSqlUtil::Type::Bigint:
+  case NdbSqlUtil::Type::Bigunsigned:
+  case NdbSqlUtil::Type::Double:
+  case NdbSqlUtil::Type::Datetime:
+    /**
+     * 64 bits
+     * data is stored as Uint64.
+     * should swap byte order as Uint64.
+     */
+    swapManyWords64((Uint32*)((char*)src + srcPos), attrNoOfWords64 << 1);
+    break;
+  case NdbSqlUtil::Type::Olddecimal:
+  case NdbSqlUtil::Type::Olddecimalunsigned:
+  case NdbSqlUtil::Type::Decimal :
+  case NdbSqlUtil::Type::Decimalunsigned :
+  case NdbSqlUtil::Type::Char:
+  case NdbSqlUtil::Type::Binary:
+    /**
+     * data is stored in the byte order of character string.
+     * should swap byte order for each byte.
+     */
+    swapManyWords32((Uint32*)((char*)src + srcPos), attrNoOfWords);
+    break;
+  case NdbSqlUtil::Type::Varchar:
+  case NdbSqlUtil::Type::Varbinary:
+  case NdbSqlUtil::Type::Longvarchar:
+  case NdbSqlUtil::Type::Longvarbinary:
+    ok = convert_endian_var_attr(attrDesc, cs, src, srcPos, attrBytes, swapFirstWord);
+    if (unlikely(!ok))
+      return false;
+    break;
+  case NdbSqlUtil::Type::Date:
+  case NdbSqlUtil::Type::Time:
+    /**
+     * 24 bits
+     * data is stored in the lowest 3 bytes of a 4-byte word.
+     * should swap byte order for each byte of the word.
+     */
+    swapManyWords32((Uint32*)((char*)src + srcPos), attrNoOfWords);
+    break;
+  case NdbSqlUtil::Type::Blob:
+  case NdbSqlUtil::Type::Text:
+    /**
+     * The first 8 bytes of the Blob/Text data is a Uint64 data,
+     * should swap the byte order of it as Uint64.
+     * The left data of Blob/Text is stored as character string,
+     * should swap the byte order for each byte of it.
+     */
+    swapManyWords64((Uint32*)((char*)src + srcPos), 2);
+    swapManyWords32((Uint32*)((char*)src + srcPos + 8), attrNoOfWords - 2);
+    break;
+  case NdbSqlUtil::Type::Bit:
+    Uint32 bitCount = AttributeDescriptor::getArraySize(attrDesc);
+    attrNoOfWords = (bitCount + 31) >> 5;
+    /**
+     * If the bit count is more than 32, the bits is stored in a Uint64 data,
+     * should swap it's byte order as Uint64.
+     * Else, the bits is stored in a Uint32 data, need not to swap byte order.
+     * The bit count is 64 at most.
+     */
+    if (attrNoOfWords == 2) {
+      swapManyWords64((Uint32*)((char*)src + srcPos), attrNoOfWords);
+    }
+    break;
+  case NdbSqlUtil::Type::Year:
+    /**
+     * 8 bits
+     * data is stored in the lowest 1 byte of a 4-byte word.
+     * should swap byte order for each byte of the word.
+     */
+    swapManyWords32((Uint32*)((char*)src + srcPos), attrNoOfWords);
+    break;
+  default:
+    break;
+  }
+
+  srcPos += attrBytes;
+
+  return true;
+}
+
+bool
+SimulatedBlock::convert_endian_var_attr(Uint32 attrDesc, CHARSET_INFO* cs,
+                          Uint32* src, Uint32& srcPos, Uint32& attrBytes,
+                          bool swapFirstWord) const
+{
+  Uint32 typeId = AttributeDescriptor::getType(attrDesc);
+  Uint32 array = AttributeDescriptor::getArrayType(attrDesc);
+  Uint32 noOfWords;
+
+  Uint32 srcTmp;
+  // get the first 4 bytes
+  memcpy(&srcTmp, ((char *)src + srcPos), 4);
+  if (swapFirstWord) {
+    swapManyWords32(&srcTmp, 1);
+  }
+
+  const uchar* srcPtr = (const uchar*)&srcTmp;
+  Uint32 varLen, varWords;
+
+  if (cs == NULL)
+  {
+    jam();
+    Uint32 len;
+    LINT_INIT(len);
+    switch(array){
+    case NDB_ARRAYTYPE_SHORT_VAR:
+      len = 1 + srcPtr[0];
+      break;
+    case NDB_ARRAYTYPE_MEDIUM_VAR:
+      len = 2 + srcPtr[0] + (srcPtr[1] << 8);
+      break;
+    default:
+      len = attrBytes;
+      break;
+    }
+    varLen = len;
+    varWords = (varLen + 3) >> 2;
+  }
+  else
+  {
+    jam();
+    Uint32 lb, len;
+    bool ok = NdbSqlUtil::get_var_length(typeId, srcPtr, attrBytes, lb, len);
+    if (unlikely(!ok))
+      return false;
+    varLen = lb + len;
+    varWords = (varLen + 3) >> 2;
+  }
+
+  attrBytes = varLen;
+  noOfWords = varWords;
+
+  // swap the var attribute
+  swapManyWords32((Uint32*)((char*)src + srcPos), noOfWords);
+
+  // the offset to the next key should be (noOfWords << 2)
+  attrBytes = noOfWords << 2;
+
+  return true;
+}
+
 CArray<KeyDescriptor> g_key_descriptor_pool;
 

--- 1.26/storage/ndb/src/kernel/vm/SimulatedBlock.hpp	2007-02-09 11:02:32 +00:00
+++ 1.27/storage/ndb/src/kernel/vm/SimulatedBlock.hpp	2007-02-09 11:02:32 +00:00
@@ -424,6 +424,16 @@ protected:
   Uint32 create_distr_key(Uint32 tableId,
 			  Uint32 *data, 
 			  const Uint32 keyPaLen[MAX_ATTRIBUTES_IN_INDEX])const;
+
+  /**
+   * convert endian for keyinfo
+   */
+  bool convert_endian_key(Uint32 tab, Uint32* src) const;
+  bool convert_endian_attr(Uint32 attrDesc, CHARSET_INFO* cs,
+                          Uint32* src, Uint32& srcPos, bool swapFirstWord) const;
+  bool convert_endian_var_attr(Uint32 attrDesc, CHARSET_INFO* cs,
+                          Uint32* src, Uint32& srcPos, Uint32& attrBytes,
+                          bool swapFirstWord) const;
   
 private:
   NewVARIABLE* NewVarRef;      /* New Base Address Table for block  */

--- 1.80/storage/ndb/src/mgmsrv/Services.cpp	2007-02-09 11:02:32 +00:00
+++ 1.81/storage/ndb/src/mgmsrv/Services.cpp	2007-02-09 11:02:32 +00:00
@@ -486,6 +486,12 @@ MgmApiSession::get_nodeid(Parser_t::Cont
   log_event_version= args.get("log_event", &log_event);
 
   endian_check.l = 1;
+  /**
+   * Commented by david.li for wl#3615.
+   * Now it can work well even if the requesting node does not have
+   * the same endianness as the management server.
+   */
+#if 0
   if(endian 
      && strcmp(endian,(endian_check.c[sizeof(long)-1])?"big":"little")!=0) {
     m_output->println(cmd);
@@ -493,6 +499,7 @@ MgmApiSession::get_nodeid(Parser_t::Cont
     m_output->println("");
     return;
   }
+#endif
 
   bool compatible;
   switch (nodetype) {

--- 1.32/storage/ndb/src/ndbapi/ClusterMgr.cpp	2007-02-09 11:02:32 +00:00
+++ 1.33/storage/ndb/src/ndbapi/ClusterMgr.cpp	2007-02-09 11:02:32 +00:00
@@ -18,6 +18,7 @@
 #include <my_pthread.h>
 #include <ndb_limits.h>
 #include <ndb_version.h>
+#include <ndb_endian.h>
 
 #include "TransporterFacade.hpp"
 #include "ClusterMgr.hpp"
@@ -192,6 +193,12 @@ ClusterMgr::forceHB()
     ApiRegReq * req = CAST_PTR(ApiRegReq, signal.getDataPtrSend());
     req->ref = numberToRef(API_CLUSTERMGR, theFacade.ownId());
     req->version = NDB_VERSION;
+    /**
+     * Set the endian info of own node
+     */
+    const NodeId ownNodeId = theFacade.ownId();
+    Node & ownNode = theNodes[ownNodeId];
+    req->endian = ownNode.m_info.m_endian;
 
     int nodeId= 0;
     for(int i=0;
@@ -225,6 +232,17 @@ ClusterMgr::threadMain( ){
   req->ref = numberToRef(API_CLUSTERMGR, theFacade.ownId());
   req->version = NDB_VERSION;
 
+  /**
+   * Set the endian info of own node
+   */
+  const NodeId ownNodeId = theFacade.ownId();
+  Node & ownNode = theNodes[ownNodeId];
+  ownNode.m_info.m_endian = checkEndian();
+#ifdef DEBUG_REG
+  ndbout_c("ClusterMgr: own node ID: %d, own endian: %d", 
+	    ownNodeId, ownNode.m_info.m_endian);
+#endif
+  req->endian = ownNode.m_info.m_endian;
   
   Uint32 timeSlept = 100;
   Uint64 now = NdbTick_CurrentMillisecond();
@@ -384,6 +402,10 @@ ClusterMgr::execAPI_REGCONF(const Uint32
     else
       node.compatible = ndbCompatible_api_ndb(NDB_VERSION,
 					      node.m_info.m_version);
+  }
+  // store the endian of remote node
+  if(node.m_info.m_endian != apiRegConf->endian){
+    node.m_info.m_endian = apiRegConf->endian;
   }
 
   node.m_state = apiRegConf->nodeState;

--- 1.154/storage/ndb/src/ndbapi/NdbDictionaryImpl.cpp	2007-02-09 11:02:33 +00:00
+++ 1.155/storage/ndb/src/ndbapi/NdbDictionaryImpl.cpp	2007-02-09 11:02:33 +00:00
@@ -2185,15 +2185,24 @@ NdbDictInterface::parseTableInfo(NdbTabl
 
   if(tableDesc->ReplicaDataLen > 0)
   {
+#if 0
     Uint16 replicaCount = ntohs(tableDesc->ReplicaData[0]);
     Uint16 fragCount = ntohs(tableDesc->ReplicaData[1]);
+#else
+    Uint16 replicaCount = tableDesc->ReplicaData[0];
+    Uint16 fragCount = tableDesc->ReplicaData[1];
+#endif
 
     impl->m_replicaCount = replicaCount;
     impl->m_fragmentCount = fragCount;
     DBUG_PRINT("info", ("replicaCount=%x , fragCount=%x",replicaCount,fragCount));
     for(i = 0; i < (Uint32) (fragCount*replicaCount); i++)
     {
+#if 0
       impl->m_fragments.push_back(ntohs(tableDesc->ReplicaData[i+2]));
+#else
+      impl->m_fragments.push_back(tableDesc->ReplicaData[i+2]);
+#endif
     }
 
     Uint32 topBit = (1 << 31);
@@ -3811,6 +3820,7 @@ NdbDictInterface::execCREATE_EVNT_CONF(N
   if (signal->m_noOfSections > 0) {
     m_buffer.append((char *)ptr[0].p, strlen((char *)ptr[0].p)+1);
   }
+ndbout_c("event table name: %s", (char *)m_buffer.get_data() + sizeof(len) + len);
 
   const CreateEvntConf * const createEvntConf=
     CAST_CONSTPTR(CreateEvntConf, signal->getDataPtr());

--- 1.8/storage/ndb/config/type_util.mk.am	2007-02-09 11:02:33 +00:00
+++ 1.9/storage/ndb/config/type_util.mk.am	2007-02-09 11:02:33 +00:00
@@ -7,4 +7,5 @@ INCLUDES += -I$(srcdir) \
 	-I$(top_srcdir)/storage/ndb/include \
         -I$(top_srcdir)/storage/ndb/include/util \
         -I$(top_srcdir)/storage/ndb/include/portlib \
-        -I$(top_srcdir)/storage/ndb/include/logger
+        -I$(top_srcdir)/storage/ndb/include/logger \
+        -I$(top_srcdir)/storage/ndb/include/kernel

--- 1.13/storage/ndb/src/common/util/Makefile.am	2007-02-09 11:02:33 +00:00
+++ 1.14/storage/ndb/src/common/util/Makefile.am	2007-02-09 11:02:33 +00:00
@@ -7,7 +7,7 @@ libgeneral_la_SOURCES = \
             SocketServer.cpp SocketClient.cpp SocketAuthenticator.cpp\
 	    OutputStream.cpp NdbOut.cpp BaseString.cpp \
 	    NdbSqlUtil.cpp new.cpp \
-            uucode.c random.c version.c \
+            uucode.c random.c version.c ndb_endian.c \
             strdup.c \
             ConfigValues.cpp ndb_init.c basestring_vsnprintf.c \
             Bitmask.cpp
Thread
bk commit into 5.1 tree (lzhou:1.2344)lzhou9 Feb