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) | lzhou | 9 Feb |