Below is the list of changes that have just been committed into a local
5.1 repository of dli. When dli 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-05-10 17:46:40+08:00, dli@stripped +13 -0
WL#3615 NDB: Endian Incompatability Support.
fixed after merged from 5.1.14 into 5.1-telco tree.
storage/ndb/src/common/util/ndb_endian.c@stripped, 2007-05-10 17:46:37+08:00,
dli@stripped +0 -1
WL#3615 NDB: Endian Incompatability Support.
fixed after merged from 5.1.14 into 5.1-telco tree.
removed NdbOut.hpp from ndb_endian.cpp
storage/ndb/src/kernel/blocks/cmvmi/Cmvmi.cpp@stripped, 2007-05-10 17:46:37+08:00,
dli@stripped +6 -3
WL#3615 NDB: Endian Incompatability Support.
fixed after merged from 5.1.14 into 5.1-telco tree.
storage/ndb/src/kernel/blocks/dblqh/Dblqh.hpp@stripped, 2007-05-10 17:46:37+08:00,
dli@stripped +4 -2
WL#3615 NDB: Endian Incompatability Support.
fixed after merged from 5.1.14 into 5.1-telco tree.
added caiLen to store the current length of ATTRINFO in caiBuffer, so that can send
the ATTRINFO to the next replica.
storage/ndb/src/kernel/blocks/dblqh/DblqhMain.cpp@stripped, 2007-05-10 17:46:37+08:00,
dli@stripped +9 -5
WL#3615 NDB: Endian Incompatability Support.
fixed after merged from 5.1.14 into 5.1-telco tree.
use caiLen to store the current length of ATTRINFO in caiBuffer instead of
regTcPtr->currReclenAi.
storage/ndb/src/kernel/blocks/dbtup/Dbtup.hpp@stripped, 2007-05-10 17:46:37+08:00,
dli@stripped +43 -4
WL#3615 NDB: Endian Incompatability Support.
fixed after merged from 5.1.14 into 5.1-telco tree.
rewrote all the endian conversion functions in DBTUP.
storage/ndb/src/kernel/blocks/dbtup/DbtupGen.cpp@stripped, 2007-05-10 17:46:37+08:00,
dli@stripped +3 -0
WL#3615 NDB: Endian Incompatability Support.
fixed after merged from 5.1.14 into 5.1-telco tree.
added initialization for newly added members.
storage/ndb/src/kernel/blocks/dbtup/DbtupMeta.cpp@stripped, 2007-05-10 17:46:37+08:00,
dli@stripped +26 -10
WL#3615 NDB: Endian Incompatability Support.
fixed after merged from 5.1.14 into 5.1-telco tree.
setup descriptor references for readEndianFunctonArray and updateEndianFunctionArray.
storage/ndb/src/kernel/blocks/dbtup/DbtupRoutines.cpp@stripped, 2007-05-10 17:46:37+08:00,
dli@stripped +397 -3
WL#3615 NDB: Endian Incompatability Support.
Fixed after merged from 5.1.14 into 5.1-telco tree.
Rewrote all the endian conversion functions in DBTUP.
Removed the endian conversion code from each read/update routine and rather make it a
post/pre processing step.
Like the implementation of read/update routines, add a property to the table
descriptor
in tup, this is a function pointer to the conversion function, we set a conversion
function
for each data type.
These function pointers are setup at table/attribute creation time, if the data type
of the
attribute is needed to convert endian, then its function pointer is set to the
corresponding
endian conversion function; else its function pointer is set to NULL.
For reading operations, we add endian conversion code in readAttributes() function,
and after
calling read function, we firstly compare the endian of API node with own node to
judge whether
it is needed to convert endian, if need convert endian and the endian conversion
function pointer
of this attribute is not NULL, then we call the endian conversion funtion to convert
endian for
the out buffer.
For updating operations, we add endian conversion code in updateAttributes() function,
and before
checkUpdateOfPrimaryKey() function, we firstly compare the endian of API node with own
node to
judge whether it is needed to convert endian, if need convert endian and the endian
conversion
function pointer of this attribute is not NULL, then we call the endian conversion
function to
convert endian for the in buffer.
Added 2 properties for table descriptor in tup:
- readEndianFunctionArray[], for reading operations
- updateEndianFunctionArray[], for updating operations
Set function pointers according to the data type of the attribute, if the data types
whose
endian handling method is the same, then they will share the same endian conversion
function.
(1) Tinyint, Tinyunsigned
readEndianFunctionArray[i] = &Dbtup::readEndianConversionWord32
updateEndianFunctionArray[i] = &Dbtup::updateEndianConversionWord32
(2) Smallint, Smallunsigned
readEndianFunctionArray[i] = &Dbtup::readEndianConversionWord16
updateEndianFunctionArray[i] = &Dbtup::updateEndianConversionWord16
(3) Mediumint, Mediumunsigned
readEndianFunctionArray[i] = &Dbtup::readEndianConversionWord32
updateEndianFunctionArray[i] = &Dbtup::updateEndianConversionWord32
(4) Bigint, Bigunsigned, Double, Datetime
readEndianFunctionArray[i] = &Dbtup::readEndianConversionWord64
updateEndianFunctionArray[i] = &Dbtup::updateEndianConversionWord64
(5) Olddecimal, Olddecimalunsigned, Decimal, Decimalunsigned, Char, Binary
readEndianFunctionArray[i] = &Dbtup::readEndianConversionWord32
updateEndianFunctionArray[i] = &Dbtup::updateEndianConversionWord32
(6) Varchar, VarBinary, Longvarchar, Longvarbinary
readEndianFunctionArray[i] = &Dbtup::readEndianConversionWord32
if not disk based attribute:
updateEndianFunctionArray[i] = &Dbtup::updateEndianConversionVar
if disk based attribute:
updateEndianFunctionArray[i] = &Dbtup::updateEndianConversionWord32
(7) Date, Time
readEndianFunctionArray[i] = &Dbtup::readEndianConversionWord32
updateEndianFunctionArray[i] = &Dbtup::updateEndianConversionWord32
(8) Blob, Text
readEndianFunctionArray[i] = &Dbtup::readEndianConversionBlob
updateEndianFunctionArray[i] = &Dbtup::updateEndianConversionBlob
(9) Year
readEndianFunctionArray[i] = &Dbtup::readEndianConversionWord32
updateEndianFunctionArray[i] = &Dbtup::updateEndianConversionWord32
(10) Int, Unsigned, Float, Timestamp, Bit
readEndianFunctionArray[i] = NULL
updateEndianFunctionArray[i] = NULL
storage/ndb/src/kernel/blocks/dbtup/DbtupTabDesMan.cpp@stripped, 2007-05-10 17:46:37+08:00,
dli@stripped +7 -5
WL#3615 NDB: Endian Incompatability Support.
fixed after merged from 5.1.14 into 5.1-telco tree.
Adjust table descriptor offset for readEndianFunctonArray[] and
updateEndianFunctionArray[].
storage/ndb/src/kernel/blocks/dbtup/DbtupTrigger.cpp@stripped, 2007-05-10 17:46:37+08:00,
dli@stripped +1 -1
WL#3615 NDB: Endian Incompatability Support.
fixed after merged from 5.1.14 into 5.1-telco tree.
Changed ljam() to jam().
storage/ndb/src/kernel/vm/SimplePropertiesSection.cpp@stripped, 2007-05-10 17:46:37+08:00,
dli@stripped +1 -1
WL#3615 NDB: Endian Incompatability Support.
fixed after merged from 5.1.14 into 5.1-telco tree.
judge whether len > 0 before calling endian conversion function.
storage/ndb/src/kernel/vm/SimulatedBlock.cpp@stripped, 2007-05-10 17:46:37+08:00,
dli@stripped +2 -185
WL#3615 NDB: Endian Incompatability Support.
fixed after merged from 5.1.14 into 5.1-telco tree.
Remove Blob/Text, Bit from convert_endian_attr() function.
Remove convert_endian_xfrm_key() and convert_endian_xfrm_attr() funtions, they were
used
in Dbtup::checkUpdateOfPrimaryKey() function before, now it is no need to convert
endian
in Dbtup::checkUpdateOfPrimarykey() function.
storage/ndb/src/kernel/vm/SimulatedBlock.hpp@stripped, 2007-05-10 17:46:37+08:00,
dli@stripped +0 -4
WL#3615 NDB: Endian Incompatability Support.
fixed after merged from 5.1.14 into 5.1-telco tree.
Removed declaration for convert_endian_xfrm_key() and convert_endian_xfrm_attr()
functions.
# 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: dli
# Host: dev3-164.dev.cn.tlan
# Root: /home/dli/mysql/mysql-5.1/mysql-5.1-telco-wl3615
--- 1.1/storage/ndb/src/common/util/ndb_endian.c 2007-05-10 17:46:49 +08:00
+++ 1.2/storage/ndb/src/common/util/ndb_endian.c 2007-05-10 17:46:49 +08:00
@@ -16,7 +16,6 @@
#include <ndb_global.h>
#include <ndb_endian.h>
-#include <NdbOut.hpp>
/**
* Check the endian of own node.
--- 1.48/storage/ndb/src/kernel/blocks/cmvmi/Cmvmi.cpp 2007-05-10 17:46:49 +08:00
+++ 1.49/storage/ndb/src/kernel/blocks/cmvmi/Cmvmi.cpp 2007-05-10 17:46:49 +08:00
@@ -225,15 +225,16 @@ void Cmvmi::execEVENT_REP(Signal* signal
*/
const Uint32 senderRef = ptr.p->blockRef;
bool needConvertEndian = compareEndianWithOwn(senderRef);
- Uint32 noOfWords;
if (needConvertEndian) {
switch(eventType) {
case NDB_LE_InfoEvent:
case NDB_LE_WarningEvent:
- noOfWords = signal->header.theLength - 1; //subtract theData[0]
+ {
+ Uint32 noOfWords = signal->header.theLength - 1; //subtract theData[0]
ndbSwapManyWords32(&(signal->theData[1]), noOfWords);
break;
+ }
default:
break;
}
@@ -248,9 +249,11 @@ void Cmvmi::execEVENT_REP(Signal* signal
switch(eventType) {
case NDB_LE_InfoEvent:
case NDB_LE_WarningEvent:
- noOfWords = signal->header.theLength - 1; //subtract theData[0]
+ {
+ Uint32 noOfWords = signal->header.theLength - 1; //subtract theData[0]
ndbSwapManyWords32(&(signal->theData[1]), noOfWords);
break;
+ }
default:
break;
}
--- 1.66/storage/ndb/src/kernel/blocks/dblqh/Dblqh.hpp 2007-05-10 17:46:49 +08:00
+++ 1.67/storage/ndb/src/kernel/blocks/dblqh/Dblqh.hpp 2007-05-10 17:46:49 +08:00
@@ -2582,8 +2582,8 @@ private:
void acckeyconf_tupkeyreq(Signal*, TcConnectionrec*, Fragrecord*, Uint32, Uint32);
void acckeyconf_load_diskpage(Signal*,TcConnectionrecPtr,Fragrecord*,Uint32);
- void Dblqh::copy_keydata_cache_to_linear(Signal* signal);
- void Dblqh::copy_keydata_linear_to_cache(Signal* signal);
+ void copy_keydata_cache_to_linear(Signal* signal);
+ void copy_keydata_linear_to_cache(Signal* signal);
bool handle_keydata_endian_conversion(Signal* signal);
void handle_nr_copy(Signal*, Ptr<TcConnectionrec>);
void exec_acckeyreq(Signal*, Ptr<TcConnectionrec>);
@@ -2911,6 +2911,8 @@ private:
// A little bit bigger to cover overwrites in copy algorithms (16384 real size).
#define ZATTR_BUFFER_SIZE 16384
Uint32 caiBuffer[ZATTR_BUFFER_SIZE + 16];
+ // Store the current length of ATTRINFO in caiBuffer.
+ Uint32 caiLen;
public:
bool is_same_trans(Uint32 opId, Uint32 trid1, Uint32 trid2);
--- 1.158/storage/ndb/src/kernel/blocks/dblqh/DblqhMain.cpp 2007-05-10 17:46:49 +08:00
+++ 1.159/storage/ndb/src/kernel/blocks/dblqh/DblqhMain.cpp 2007-05-10 17:46:49 +08:00
@@ -3184,9 +3184,8 @@ void Dblqh::execTUP_ORIG_ATTRINFO(Signal
ptrCheckGuard(tcConnectptr, ttcConnectrecFileSize, regTcConnectionrec);
ndbrequire(tcConnectptr.p->transactionState == TcConnectionrec::WAIT_TUP);
Uint32 *dataPtr = &signal->theData[3];
- Uint32 currReclenAi = tcConnectptr.p->currReclenAi;
- MEMCOPY_NO_WORDS(&caiBuffer[currReclenAi], dataPtr, length);
- tcConnectptr.p->currReclenAi = currReclenAi + length;
+ MEMCOPY_NO_WORDS(&caiBuffer[caiLen], dataPtr, length);
+ caiLen = caiLen + length;
}//Dblqh::execTUP_ORIG_ATTRINFO()
/* ------------------------------------------------------------------------- */
@@ -3226,8 +3225,8 @@ void Dblqh::lqhAttrinfoLab(Signal* signa
}//if
} else {
// need convert endian
- Uint32 currReclenAi = regTcPtr->currReclenAi - length;
- MEMCOPY_NO_WORDS(&caiBuffer[currReclenAi], dataPtr, length);
+ MEMCOPY_NO_WORDS(&caiBuffer[caiLen], dataPtr, length);
+ caiLen = caiLen + length;
}//if
}//if
}//if
@@ -3734,6 +3733,8 @@ void Dblqh::execLQHKEYREQ(Signal* signal
}//if
LQHKEY_error(signal, 1);
}//if
+ // initialize caiLen
+ caiLen = 0;
if (TreclenAiLqhkey != 0) {
if (regTcPtr->operation != ZREAD) {
if (regTcPtr->operation != ZDELETE) {
@@ -3783,6 +3784,7 @@ void Dblqh::execLQHKEYREQ(Signal* signal
regTcPtr->currTupAiLen = TreclenAiLqhkey;
} else {
MEMCOPY_NO_WORDS(&caiBuffer[0], lqhKeyReq->variableData+nextPos,
TreclenAiLqhkey);
+ caiLen = TreclenAiLqhkey;
}//if
} else {
jam();
@@ -5671,6 +5673,7 @@ void Dblqh::copyAttrInfo(Signal* signal)
/* ---- COPY FIRSTATTRINFO ------------------- */
Uint32 lqhLen = regTcPtr->reclenAiLqhkey;
+ ndbrequire(caiLen >= lqhLen);
if (lqhLen > 0) {
MEMCOPY_NO_WORDS(®TcPtr->firstAttrinfo[0], &caiBuffer[0], lqhLen);
regTcPtr->currTupAiLen = lqhLen;
@@ -5678,6 +5681,7 @@ void Dblqh::copyAttrInfo(Signal* signal)
/* ---- COPY ATTRBUF ------------------- */
UintR TotReclenAi = regTcPtr->totSendlenAi;
+ ndbrequire(caiLen >= TotReclenAi);
Uint32 length = TotReclenAi - lqhLen;
if (saveTupattrbuf(signal, &caiBuffer[lqhLen], length) == ZOK) {
return;
--- 1.72/storage/ndb/src/kernel/blocks/dbtup/Dbtup.hpp 2007-05-10 17:46:49 +08:00
+++ 1.73/storage/ndb/src/kernel/blocks/dbtup/Dbtup.hpp 2007-05-10 17:46:49 +08:00
@@ -351,6 +351,11 @@ typedef bool (Dbtup::* ReadFunction)(Uin
typedef bool (Dbtup::* UpdateFunction)(Uint32*,
KeyReqStruct*,
Uint32);
+typedef void (Dbtup::* ReadEndianFunction)(Uint8*,
+ KeyReqStruct*,
+ Uint32);
+typedef void (Dbtup::* UpdateEndianFunction)(Uint32*,
+ KeyReqStruct*);
private:
typedef Tup_fixsize_page Fix_page;
@@ -436,7 +441,7 @@ typedef Ptr<Fragoperrec> FragoperrecPtr;
Uint32 noOfDynVar;
Uint32 noOfDynFix;
Uint32 noOfDynamic;
- Uint32 tabDesOffset[7];
+ Uint32 tabDesOffset[9];
Uint32 desAllocSize;
Uint32 tableDescriptor;
Uint32 dynTabDesOffset[3];
@@ -1009,6 +1014,8 @@ ArrayPool<TupTriggerData> c_triggerPool;
ReadFunction* readFunctionArray;
UpdateFunction* updateFunctionArray;
+ ReadEndianFunction* readEndianFunctionArray;
+ UpdateEndianFunction* updateEndianFunctionArray;
CHARSET_INFO** charsetArray;
Uint32 readKeyArray;
@@ -2393,8 +2400,6 @@ private:
bool readDiskBitsNotNULL(Uint8*, KeyReqStruct*, AttributeHeader*, Uint32);
bool updateDiskBitsNULLable(Uint32*, KeyReqStruct*, Uint32);
bool updateDiskBitsNotNULL(Uint32*, KeyReqStruct*, Uint32);
- void swapFixedSizeAttr(Uint32* attrBuffer, Uint32 attrDescriptor, Uint32
attrNoOfWords);
-
/* Alter table methods. */
void handleAlterTabPrepare(Signal *signal, const Tablerec *regTabPtr);
@@ -2416,7 +2421,11 @@ private:
bool nullFlagCheck(KeyReqStruct *req_struct, Uint32 attrDes2);
bool disk_nullFlagCheck(KeyReqStruct *req_struct, Uint32 attrDes2);
Uint32 read_pseudo(const Uint32 *, Uint32, KeyReqStruct*, Uint32*);
- Uint32 read_packed(const Uint32 *, Uint32, KeyReqStruct*, Uint32*);
+ Uint32 read_packed(const Uint32* inBuf,
+ Uint32 inPos,
+ KeyReqStruct *req_struct,
+ Uint32* outBuffer,
+ bool needConvertEndian = false);
/* Fast bit counting (16 instructions on x86_64, gcc -O3). */
static inline uint32_t count_bits(uint32_t x)
@@ -2433,6 +2442,35 @@ private:
void setUpQueryRoutines(Tablerec* regTabPtr);
// *****************************************************************
+// Endian handling methods.
+// *****************************************************************
+ void setUpEndianRoutines(Tablerec *regTabPtr);
+
+ void readEndianConversionWord32(Uint8* outBuffer,
+ KeyReqStruct *req_struct,
+ Uint32 attrBufIndex);
+ void readEndianConversionWord16(Uint8* outBuffer,
+ KeyReqStruct *req_struct,
+ Uint32 attrBufIndex);
+ void readEndianConversionWord64(Uint8* outBuffer,
+ KeyReqStruct *req_struct,
+ Uint32 attrBufIndex);
+ void readEndianConversionBlob(Uint8* outBuffer,
+ KeyReqStruct *req_struct,
+ Uint32 attrBufIndex);
+
+ void updateEndianConversionWord32(Uint32* inBuffer,
+ KeyReqStruct *req_struct);
+ void updateEndianConversionWord16(Uint32* inBuffer,
+ KeyReqStruct *req_struct);
+ void updateEndianConversionWord64(Uint32* inBuffer,
+ KeyReqStruct *req_struct);
+ void updateEndianConversionVar(Uint32* inBuffer,
+ KeyReqStruct *req_struct);
+ void updateEndianConversionBlob(Uint32* inBuffer,
+ KeyReqStruct *req_struct);
+
+// *****************************************************************
// Service methods.
// *****************************************************************
TransState get_trans_state(Operationrec * const);
@@ -2845,6 +2883,7 @@ private:
// Private methods
Uint32 sizeOfReadFunction();
+ Uint32 sizeOfReadEndianFunction();
void removeTdArea(Uint32 tabDesRef, Uint32 list);
void insertTdArea(Uint32 tabDesRef, Uint32 list);
void itdaMergeTabDescr(Uint32& retRef, Uint32& retNo, bool normal);
--- 1.48/storage/ndb/src/kernel/blocks/dbtup/DbtupGen.cpp 2007-05-10 17:46:49 +08:00
+++ 1.49/storage/ndb/src/kernel/blocks/dbtup/DbtupGen.cpp 2007-05-10 17:46:49 +08:00
@@ -112,6 +112,7 @@ Dbtup::Dbtup(Block_context& ctx, Pgman*
totNoOfPagesAllocated = 0;
cnoOfAllocatedPages = 0;
c_no_of_pages = 0;
+ capiBlockref = 0;
initData();
CLEAR_ERROR_INSERT_VALUE;
@@ -643,6 +644,8 @@ Dbtup::initTab(Tablerec* const regTabPtr
}//for
regTabPtr->readFunctionArray = NULL;
regTabPtr->updateFunctionArray = NULL;
+ regTabPtr->readEndianFunctionArray = NULL;
+ regTabPtr->updateEndianFunctionArray = NULL;
regTabPtr->charsetArray = NULL;
regTabPtr->tabDescriptor = RNIL;
--- 1.42/storage/ndb/src/kernel/blocks/dbtup/DbtupMeta.cpp 2007-05-10 17:46:49 +08:00
+++ 1.43/storage/ndb/src/kernel/blocks/dbtup/DbtupMeta.cpp 2007-05-10 17:46:49 +08:00
@@ -707,10 +707,10 @@ Dbtup::handleAlterTabPrepare(Signal *sig
*/
Uint32* desc= &tableDescriptor[tableDescriptorRef].tabDescr;
CHARSET_INFO** CharsetArray=
- (CHARSET_INFO**)(desc + regAlterTabOpPtr.p->tabDesOffset[2]);
+ (CHARSET_INFO**)(desc + regAlterTabOpPtr.p->tabDesOffset[4]);
memcpy(CharsetArray, regTabPtr->charsetArray,
sizeof(*CharsetArray)*regTabPtr->noOfCharsets);
- Uint32 *attrDesPtr= desc + regAlterTabOpPtr.p->tabDesOffset[4];
+ Uint32 *attrDesPtr= desc + regAlterTabOpPtr.p->tabDesOffset[6];
memcpy(attrDesPtr,
&tableDescriptor[regTabPtr->tabDescriptor].tabDescr,
(ZAD_SIZE<<2)*oldNoOfAttr);
@@ -1141,6 +1141,7 @@ Dbtup::computeTableMetaData(Tablerec *re
regTabPtr->total_rec_size= total_rec_size;
setUpQueryRoutines(regTabPtr);
+ setUpEndianRoutines(regTabPtr);
setUpKeyArray(regTabPtr);
}
@@ -1208,9 +1209,11 @@ Dbtup::undo_createtable_logsync_callback
*
* 0 readFunctionArray ( one for each attribute )
* 1 updateFunctionArray ( ditto )
- * 2 charsetArray ( pointers to distinct CHARSET_INFO )
- * 3 readKeyArray ( attribute ids of keys )
- * 5 tabDescriptor ( attribute descriptors, each ZAD_SIZE )
+ * 2 readEndianFunctionArray ( one for each attribute )
+ * 3 updateEndianFunctionArray ( one for each attribute )
+ * 4 charsetArray ( pointers to distinct CHARSET_INFO )
+ * 5 readKeyArray ( attribute ids of keys )
+ * 6 tabDescriptor ( attribute descriptors, each ZAD_SIZE )
*/
void Dbtup::setUpDescriptorReferences(Uint32 descriptorReference,
Tablerec* const regTabPtr,
@@ -1219,10 +1222,12 @@ void Dbtup::setUpDescriptorReferences(Ui
Uint32* desc= &tableDescriptor[descriptorReference].tabDescr;
regTabPtr->readFunctionArray= (ReadFunction*)(desc + offset[0]);
regTabPtr->updateFunctionArray= (UpdateFunction*)(desc + offset[1]);
- regTabPtr->charsetArray= (CHARSET_INFO**)(desc + offset[2]);
- regTabPtr->readKeyArray= descriptorReference + offset[3];
- regTabPtr->tabDescriptor= descriptorReference + offset[4];
- regTabPtr->m_real_order_descriptor = descriptorReference + offset[5];
+ regTabPtr->readEndianFunctionArray= (ReadEndianFunction*)(desc + offset[2]);
+ regTabPtr->updateEndianFunctionArray= (UpdateEndianFunction*)(desc + offset[3]);
+ regTabPtr->charsetArray= (CHARSET_INFO**)(desc + offset[4]);
+ regTabPtr->readKeyArray= descriptorReference + offset[5];
+ regTabPtr->tabDescriptor= descriptorReference + offset[6];
+ regTabPtr->m_real_order_descriptor = descriptorReference + offset[7];
}
void Dbtup::setupDynDescriptorReferences(Uint32 dynDescr,
@@ -1244,6 +1249,15 @@ Dbtup::sizeOfReadFunction()
return (Uint32)(end - start);
}
+Uint32
+Dbtup::sizeOfReadEndianFunction()
+{
+ ReadEndianFunction* tmp= (ReadEndianFunction*)&tableDescriptor[0];
+ TableDescriptor* start= &tableDescriptor[0];
+ TableDescriptor * end= (TableDescriptor*)(tmp + 1);
+ return (Uint32)(end - start);
+}
+
void Dbtup::setUpKeyArray(Tablerec* const regTabPtr)
{
ndbrequire((regTabPtr->readKeyArray + regTabPtr->noOfKeyAttr) <
@@ -1465,10 +1479,12 @@ void Dbtup::releaseTabDescr(Tablerec* co
regTabPtr->readKeyArray= RNIL;
regTabPtr->readFunctionArray= NULL;
regTabPtr->updateFunctionArray= NULL;
+ regTabPtr->readEndianFunctionArray= NULL;
+ regTabPtr->updateEndianFunctionArray= NULL;
regTabPtr->charsetArray= NULL;
// move to start of descriptor
- descriptor -= offset[3];
+ descriptor -= offset[5];
Uint32 retNo= getTabDescrWord(descriptor + ZTD_DATASIZE);
ndbrequire(getTabDescrWord(descriptor + ZTD_HEADER) == ZTD_TYPE_NORMAL);
ndbrequire(retNo == getTabDescrWord((descriptor + retNo) - ZTD_TR_SIZE));
--- 1.42/storage/ndb/src/kernel/blocks/dbtup/DbtupRoutines.cpp 2007-05-10 17:46:49 +08:00
+++ 1.43/storage/ndb/src/kernel/blocks/dbtup/DbtupRoutines.cpp 2007-05-10 17:46:49 +08:00
@@ -23,6 +23,7 @@
#include <AttributeDescriptor.hpp>
#include "AttributeOffset.hpp"
#include <AttributeHeader.hpp>
+#include <ndb_endian.h>
void
Dbtup::setUpQueryRoutines(Tablerec *regTabPtr)
@@ -279,6 +280,335 @@ Dbtup::setUpQueryRoutines(Tablerec *regT
}
}
+void
+Dbtup::setUpEndianRoutines(Tablerec *regTabPtr)
+{
+ Uint32 startDescriptor = regTabPtr->tabDescriptor;
+ ndbrequire((startDescriptor + (regTabPtr->m_no_of_attributes << ZAD_LOG_SIZE))
+ <= cnoOfTabDescrRec);
+ for (Uint32 i = 0; i < regTabPtr->m_no_of_attributes; i++) {
+ Uint32 attrDescrStart = startDescriptor + (i << ZAD_LOG_SIZE);
+ Uint32 attrDescr = tableDescriptor[attrDescrStart].tabDescr;
+
+ Uint32 type = AttributeDescriptor::getType(attrDescr);
+
+ switch (type) {
+ 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.
+ */
+ jam();
+ regTabPtr->readEndianFunctionArray[i] = &Dbtup::readEndianConversionWord32;
+ regTabPtr->updateEndianFunctionArray[i] =
&Dbtup::updateEndianConversionWord32;
+ break;
+ case NdbSqlUtil::Type::Smallint:
+ case NdbSqlUtil::Type::Smallunsigned:
+ /**
+ * 16 bits
+ * data is stored as Uint16.
+ * should swap byte order as Uint16.
+ */
+ jam();
+ regTabPtr->readEndianFunctionArray[i] = &Dbtup::readEndianConversionWord16;
+ regTabPtr->updateEndianFunctionArray[i] =
&Dbtup::updateEndianConversionWord16;
+ 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.
+ */
+ jam();
+ regTabPtr->readEndianFunctionArray[i] = &Dbtup::readEndianConversionWord32;
+ regTabPtr->updateEndianFunctionArray[i] =
&Dbtup::updateEndianConversionWord32;
+ 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.
+ */
+ jam();
+ regTabPtr->readEndianFunctionArray[i] = &Dbtup::readEndianConversionWord64;
+ regTabPtr->updateEndianFunctionArray[i] =
&Dbtup::updateEndianConversionWord64;
+ 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.
+ */
+ jam();
+ regTabPtr->readEndianFunctionArray[i] = &Dbtup::readEndianConversionWord32;
+ regTabPtr->updateEndianFunctionArray[i] =
&Dbtup::updateEndianConversionWord32;
+ break;
+ case NdbSqlUtil::Type::Varchar:
+ case NdbSqlUtil::Type::Varbinary:
+ case NdbSqlUtil::Type::Longvarchar:
+ case NdbSqlUtil::Type::Longvarbinary:
+ {
+ jam();
+ regTabPtr->readEndianFunctionArray[i] = &Dbtup::readEndianConversionWord32;
+ /**
+ * For variable disk attribute, should handle as fixed size attribute.
+ */
+ Uint32 disk = AttributeDescriptor::getDiskBased(attrDescr);
+ Uint32 array = AttributeDescriptor::getArrayType(attrDescr);
+ if (disk && array == NDB_ARRAYTYPE_FIXED) {
+ regTabPtr->updateEndianFunctionArray[i] =
&Dbtup::updateEndianConversionWord32;
+ } else {
+ regTabPtr->updateEndianFunctionArray[i] =
&Dbtup::updateEndianConversionVar;
+ }
+ 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.
+ */
+ jam();
+ regTabPtr->readEndianFunctionArray[i] = &Dbtup::readEndianConversionWord32;
+ regTabPtr->updateEndianFunctionArray[i] =
&Dbtup::updateEndianConversionWord32;
+ break;
+ case NdbSqlUtil::Type::Blob:
+ case NdbSqlUtil::Type::Text:
+ jam();
+ regTabPtr->readEndianFunctionArray[i] = &Dbtup::readEndianConversionBlob;
+ regTabPtr->updateEndianFunctionArray[i] =
&Dbtup::updateEndianConversionBlob;
+ 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.
+ */
+ jam();
+ regTabPtr->readEndianFunctionArray[i] = &Dbtup::readEndianConversionWord32;
+ regTabPtr->updateEndianFunctionArray[i] =
&Dbtup::updateEndianConversionWord32;
+ break;
+ case NdbSqlUtil::Type::Int:
+ case NdbSqlUtil::Type::Unsigned:
+ case NdbSqlUtil::Type::Float:
+ case NdbSqlUtil::Type::Timestamp:
+ case NdbSqlUtil::Type::Bit:
+ default:
+ /**
+ * the types that no need to handle endian:
+ * Int, Unsigned, Float, Timestamp, Bit.
+ */
+ jam();
+ regTabPtr->readEndianFunctionArray[i] = NULL;
+ regTabPtr->updateEndianFunctionArray[i] = NULL;
+ break;
+ }
+ }
+}
+
+void
+Dbtup::readEndianConversionWord32(Uint8* outBuffer,
+ KeyReqStruct *req_struct,
+ Uint32 attrBufIndex)
+{
+ jam();
+ Uint32 newAttrBufIndex = req_struct->out_buf_index;
+ ndbrequire(attrBufIndex < newAttrBufIndex);
+
+ Uint32 attrNoOfBytes = newAttrBufIndex - attrBufIndex;
+ Uint32 attrNoOfWords = (attrNoOfBytes + 3) >> 2;
+ Uint32* attrBuffer = (Uint32*)(outBuffer + attrBufIndex);
+
+ ndbSwapManyWords32(attrBuffer, attrNoOfWords);
+}//Dbtup::readEndianConversionWord32()
+
+void
+Dbtup::readEndianConversionWord16(Uint8* outBuffer,
+ KeyReqStruct *req_struct,
+ Uint32 attrBufIndex)
+{
+ jam();
+ Uint32 newAttrBufIndex = req_struct->out_buf_index;
+ ndbrequire(attrBufIndex < newAttrBufIndex);
+
+ Uint32 attrNoOfBytes = newAttrBufIndex - attrBufIndex;
+ Uint32 attrNoOfWords = (attrNoOfBytes + 3) >> 2;
+ Uint32* attrBuffer = (Uint32*)(outBuffer + attrBufIndex);
+
+ ndbSwapManyWords16(attrBuffer, attrNoOfWords);
+}//Dbtup::readEndianConversionWord16()
+
+void
+Dbtup::readEndianConversionWord64(Uint8* outBuffer,
+ KeyReqStruct *req_struct,
+ Uint32 attrBufIndex)
+{
+ jam();
+ Uint32 newAttrBufIndex = req_struct->out_buf_index;
+ ndbrequire(attrBufIndex < newAttrBufIndex);
+
+ Uint32 attrNoOfBytes = newAttrBufIndex - attrBufIndex;
+ Uint32 attrNoOfWords = (attrNoOfBytes + 3) >> 2;
+ Uint32 attrNoOfWords64 = (attrNoOfWords + 1) >> 1;
+ Uint32* attrBuffer = (Uint32*)(outBuffer + attrBufIndex);
+
+ ndbSwapManyWords64(attrBuffer, attrNoOfWords64 << 1);
+}//Dbtup::readEndianConversionWord64()
+
+void
+Dbtup::readEndianConversionBlob(Uint8* outBuffer,
+ KeyReqStruct *req_struct,
+ Uint32 attrBufIndex)
+{
+ jam();
+ Uint32 newAttrBufIndex = req_struct->out_buf_index;
+ ndbrequire(attrBufIndex < newAttrBufIndex);
+
+ Uint32 attrNoOfBytes = newAttrBufIndex - attrBufIndex;
+ Uint32 attrNoOfWords = (attrNoOfBytes + 3) >> 2;
+ Uint32 attrDescriptor = req_struct->attr_descriptor;
+ Uint32 array = AttributeDescriptor::getArrayType(attrDescriptor);
+
+ Uint32* attrBuffer = (Uint32*)(outBuffer + attrBufIndex);
+
+ if (array == NDB_ARRAYTYPE_FIXED) {
+ /**
+ * Blob V1:
+ * Blob head V1 is 8 bytes:
+ * 8 bytes blob length - native endian
+ * Thus we should swap the byte-order of blob head as Uint64.
+ * The inline bytes of blob is stored as character string,
+ * should swap the byte-order for each byte of it.
+ */
+ ndbSwapManyWords64(attrBuffer, 2);
+ ndbSwapManyWords32(attrBuffer + 2, attrNoOfWords - 2);
+ } else if (array == NDB_ARRAYTYPE_MEDIUM_VAR) {
+ /**
+ * Blob V2:
+ * Blob head V2 is 16 bytes:
+ * 2 bytes head+inline length - little-endian
+ * 2 bytes reserved (zero)
+ * 4 bytes NDB$PKID - little-endian
+ * 8 bytes blob length - little-endian
+ * Thus we should swap the byte-order for each byte of blob head.
+ * The inline bytes of blob is stored as character string,
+ * should also swap the byte-order for each byte of it.
+ */
+ ndbSwapManyWords32(attrBuffer, attrNoOfWords);
+ }//if
+}//Dbtup::readEndianConversionBlob()
+
+void
+Dbtup::updateEndianConversionWord32(Uint32* inBuffer,
+ KeyReqStruct *req_struct)
+{
+ jam();
+ Uint32 attrDescriptor = req_struct->attr_descriptor;
+ Uint32 attrBufIndex = req_struct->in_buf_index;
+ Uint32 attrNoOfWords = AttributeDescriptor::getSizeInWords(attrDescriptor);
+
+ Uint32* attrBuffer = inBuffer + attrBufIndex + 1;
+
+ ndbSwapManyWords32(attrBuffer, attrNoOfWords);
+}//Dbtup::updateEndianConversionWord32()
+
+void
+Dbtup::updateEndianConversionWord16(Uint32* inBuffer,
+ KeyReqStruct *req_struct)
+{
+ jam();
+ Uint32 attrDescriptor = req_struct->attr_descriptor;
+ Uint32 attrBufIndex = req_struct->in_buf_index;
+ Uint32 attrNoOfWords = AttributeDescriptor::getSizeInWords(attrDescriptor);
+
+ Uint32* attrBuffer = inBuffer + attrBufIndex + 1;
+
+ ndbSwapManyWords16(attrBuffer, attrNoOfWords);
+}//Dbtup::updateEndianConversionWord16()
+
+void
+Dbtup::updateEndianConversionWord64(Uint32* inBuffer,
+ KeyReqStruct *req_struct)
+{
+ jam();
+ Uint32 attrDescriptor = req_struct->attr_descriptor;
+ Uint32 attrBufIndex = req_struct->in_buf_index;
+ Uint32 attrNoOfWords = AttributeDescriptor::getSizeInWords(attrDescriptor);
+ Uint32 attrNoOfWords64 = (attrNoOfWords + 1) >> 1;
+
+ Uint32* attrBuffer = inBuffer + attrBufIndex + 1;
+
+ ndbSwapManyWords64(attrBuffer, attrNoOfWords64 << 1);
+}//Dbtup::updateEndianConversionWord64()
+
+void
+Dbtup::updateEndianConversionVar(Uint32* inBuffer,
+ KeyReqStruct *req_struct)
+{
+ jam();
+ Uint32 attrDescriptor = req_struct->attr_descriptor;
+ Uint32 attrBufIndex = req_struct->in_buf_index;
+ AttributeHeader ahIn(inBuffer[attrBufIndex]);
+ Uint32 attrNoOfBytes = ahIn.getByteSize();
+ Uint32 attrNoOfWords = (attrNoOfBytes + 3) >> 2;
+
+ Uint32* attrBuffer = inBuffer + attrBufIndex + 1;
+
+ ndbSwapManyWords32(attrBuffer, attrNoOfWords);
+}//Dbtup::updateEndianConversionVar()
+
+void
+Dbtup::updateEndianConversionBlob(Uint32* inBuffer,
+ KeyReqStruct *req_struct)
+{
+ jam();
+ Uint32 attrDescriptor = req_struct->attr_descriptor;
+ Uint32 attrBufIndex = req_struct->in_buf_index;
+ Uint32 array = AttributeDescriptor::getArrayType(attrDescriptor);
+ Uint32 attrNoOfWords;
+
+ Uint32* attrBuffer = inBuffer + attrBufIndex + 1;
+
+ if (array == NDB_ARRAYTYPE_FIXED) {
+ /**
+ * Blob V1:
+ * Blob head V1 is 8 bytes:
+ * 8 bytes blob length - native endian
+ * Thus we should swap the byte-order of blob head as Uint64.
+ * The inline bytes of blob is stored as character string,
+ * should swap the byte-order for each byte of it.
+ */
+ attrNoOfWords = AttributeDescriptor::getSizeInWords(attrDescriptor);
+ ndbSwapManyWords64(attrBuffer, 2);
+ ndbSwapManyWords32(attrBuffer + 2, attrNoOfWords - 2);
+ } else if (array == NDB_ARRAYTYPE_MEDIUM_VAR) {
+ /**
+ * Blob V2:
+ * Blob head V2 is 16 bytes:
+ * 2 bytes head+inline length - little-endian
+ * 2 bytes reserved (zero)
+ * 4 bytes NDB$PKID - little-endian
+ * 8 bytes blob length - little-endian
+ * We treat it as a varchar.
+ */
+ AttributeHeader ahIn(inBuffer[attrBufIndex]);
+ Uint32 attrNoOfBytes = ahIn.getByteSize();
+ attrNoOfWords = (attrNoOfBytes + 3) >> 2;
+ ndbSwapManyWords32(attrBuffer, attrNoOfWords);
+ }//if
+}//Dbtup::updateEndianConversionBlob()
+
/* Dump a byte buffer, for debugging. */
static void dump_buf_hex(unsigned char *p, Uint32 bytes)
{
@@ -376,10 +706,25 @@ int Dbtup::readAttributes(KeyReqStruct *
attributeOffset= attr_descr[descr_index + 1].tabDescr;
ReadFunction f= regTabPtr->readFunctionArray[attributeId];
req_struct->attr_descriptor= attr_descr[descr_index].tabDescr;
+ Uint32 attrBufIndex= req_struct->out_buf_index;
+ ReadEndianFunction f_read_endian=
regTabPtr->readEndianFunctionArray[attributeId];
if ((this->*f)(outBuffer,
req_struct,
ahOut,
attributeOffset)) {
+ /**
+ * If the endian of API node and own node are different,
+ * the byte-order of each 4-byte word of the attributes read will be
+ * swapped while sending to the API node.
+ * Thus we should swap the byte-order for the attributes read in
+ * advance, so that it is no need to swap it on the API node again.
+ * We handle the outBuffer after reading function.
+ */
+ const Uint32 apiBlockRef= req_struct->rec_blockref;
+ bool needConvertEndian= compareEndianWithOwn(apiBlockRef);
+ if (needConvertEndian && f_read_endian != NULL) {
+ (this->*f_read_endian)(outBuffer, req_struct, attrBufIndex);
+ }
continue;
} else {
return -1;
@@ -1494,6 +1839,20 @@ int Dbtup::updateAttributes(KeyReqStruct
if (likely(attributeId < numAttributes)) {
Uint32 attrDescriptor= attr_descr[attrDescriptorIndex].tabDescr;
Uint32 attributeOffset= attr_descr[attrDescriptorIndex + 1].tabDescr;
+ req_struct->attr_descriptor= attrDescriptor;
+ /**
+ * If the endian of API node and own node are different,
+ * the byte-order of each 4-byte word of the attributes will be
+ * swapped while receiving from the API node.
+ * Thus we should swap back the byte-order for the attributes.
+ * We handle the inBuffer before updating function.
+ */
+ const Uint32 apiBlockRef= req_struct->rec_blockref;
+ bool needConvertEndian= compareEndianWithOwn(apiBlockRef);
+ UpdateEndianFunction f_update_endian=
regTabPtr->updateEndianFunctionArray[attributeId];
+ if (needConvertEndian && f_update_endian != NULL) {
+ (this->*f_update_endian)(inBuffer, req_struct);
+ }
if ((AttributeDescriptor::getPrimaryKey(attrDescriptor)) &&
(regOperPtr->op_struct.op_type != ZINSERT)) {
if (checkUpdateOfPrimaryKey(req_struct,
@@ -1506,7 +1865,6 @@ int Dbtup::updateAttributes(KeyReqStruct
}
UpdateFunction f= regTabPtr->updateFunctionArray[attributeId];
jam();
- req_struct->attr_descriptor= attrDescriptor;
req_struct->changeMask.set(attributeId);
if (attributeId >= 64) {
if (req_struct->max_attr_id_updated < attributeId) {
@@ -1527,6 +1885,9 @@ int Dbtup::updateAttributes(KeyReqStruct
}
else if(attributeId == AttributeHeader::DISK_REF)
{
+ /**
+ * No need consider endian here, the data is Uint32.
+ */
jam();
Uint32 sz= ahIn.getDataSize();
ndbrequire(sz == 2);
@@ -1538,6 +1899,9 @@ int Dbtup::updateAttributes(KeyReqStruct
}
else if(attributeId == AttributeHeader::ANY_VALUE)
{
+ /**
+ * No need consider endian here.
+ */
jam();
Uint32 sz= ahIn.getDataSize();
ndbrequire(sz == 1);
@@ -2166,6 +2530,10 @@ Dbtup::read_pseudo(const Uint32 * inBuff
ndbassert(req_struct->out_buf_bits == 0);
ndbassert((req_struct->out_buf_index & 3) == 0);
+ // compare the endian of API node and own node.
+ const Uint32 apiBlockRef = req_struct->rec_blockref;
+ bool needConvertEndian = compareEndianWithOwn(apiBlockRef);
+
Uint32 attrId = (* (inBuffer + inPos - 1)) >> 16;
Uint32 outPos = req_struct->out_buf_index;
Uint32* outBuffer = outBuf + ((outPos - 1) >> 2);
@@ -2176,7 +2544,7 @@ Dbtup::read_pseudo(const Uint32 * inBuff
switch(attrId){
case AttributeHeader::READ_PACKED:
case AttributeHeader::READ_ALL:
- return read_packed(inBuffer, inPos, req_struct, outBuf);
+ return read_packed(inBuffer, inPos, req_struct, outBuf, needConvertEndian);
case AttributeHeader::FRAGMENT:
outBuffer[1] = fragptr.p->fragmentId;
sz = 1;
@@ -2187,6 +2555,9 @@ Dbtup::read_pseudo(const Uint32 * inBuff
tmp*= 32768;
memcpy(outBuffer + 1, &tmp, 8);
sz = 2;
+ if (needConvertEndian) {
+ ndbSwapManyWords64(outBuffer + 1, 2);
+ }
break;
}
case AttributeHeader::FRAGMENT_VARSIZED_MEMORY:
@@ -2195,6 +2566,9 @@ Dbtup::read_pseudo(const Uint32 * inBuff
tmp*= 32768;
memcpy(outBuffer + 1, &tmp, 8);
sz = 2;
+ if (needConvertEndian) {
+ ndbSwapManyWords64(outBuffer + 1, 2);
+ }
break;
}
case AttributeHeader::ROW_SIZE:
@@ -2210,6 +2584,9 @@ Dbtup::read_pseudo(const Uint32 * inBuff
outBuffer[1] = signal->theData[0];
outBuffer[2] = signal->theData[1];
sz = 2;
+ if (needConvertEndian) {
+ ndbSwapManyWords64(outBuffer + 1, 2);
+ }
break;
case AttributeHeader::RANGE_NO:
signal->theData[0] = operPtr.p->userpointer;
@@ -2250,6 +2627,9 @@ Dbtup::read_pseudo(const Uint32 * inBuff
Uint64 tmp = * req_struct->m_tuple_ptr->get_mm_gci(tabptr.p);
memcpy(outBuffer + 1, &tmp, sizeof(tmp));
sz = 2;
+ if (needConvertEndian) {
+ ndbSwapManyWords64(outBuffer + 1, 2);
+ }
}
break;
case AttributeHeader::ANY_VALUE:
@@ -2288,7 +2668,8 @@ Dbtup::read_pseudo(const Uint32 * inBuff
Uint32
Dbtup::read_packed(const Uint32* inBuf, Uint32 inPos,
KeyReqStruct *req_struct,
- Uint32* outBuffer)
+ Uint32* outBuffer,
+ bool needConvertEndian)
{
ndbassert(req_struct->out_buf_index >= 4);
ndbassert((req_struct->out_buf_index & 3) == 0);
@@ -2378,6 +2759,8 @@ Dbtup::read_packed(const Uint32* inBuf,
req_struct->out_buf_index = outPos;
req_struct->out_buf_bits = outBits;
req_struct->attr_descriptor = attrDesc1;
+ Uint32 attrBufIndex = req_struct->out_buf_index;
+ ReadEndianFunction f_read_endian = regTabPtr->readEndianFunctionArray[attrId];
if ((this->*f)(outBuf, req_struct, &ahOut, attrDesc2))
{
jam();
@@ -2397,6 +2780,17 @@ Dbtup::read_packed(const Uint32* inBuf,
outPos = save[0];
outBits = save[1];
}
+ }
+ /**
+ * If the endian of API node and own node are different,
+ * the byte-order of each 4-byte word of the attributes read will be
+ * swapped while sending to the API node.
+ * Thus we should swap the byte-order for the attributes read in
+ * advance, so that it is no need to swap it on the API node again.
+ * We handle the outBuf after reading function.
+ */
+ if (needConvertEndian && f_read_endian != NULL) {
+ (this->*f_read_endian)(outBuf, req_struct, attrBufIndex);
}
continue;
} else {
--- 1.8/storage/ndb/src/kernel/blocks/dbtup/DbtupTabDesMan.cpp 2007-05-10 17:46:49 +08:00
+++ 1.9/storage/ndb/src/kernel/blocks/dbtup/DbtupTabDesMan.cpp 2007-05-10 17:46:49 +08:00
@@ -45,10 +45,12 @@ Dbtup::getTabDescrOffsets(Uint32 noOfAtt
offset[0] = allocSize += ZTD_SIZE;
offset[1] = allocSize += noOfAttrs * sizeOfReadFunction();
offset[2] = allocSize += noOfAttrs * sizeOfReadFunction();
- offset[3] = allocSize += noOfCharsets * sizeOfPointer;
- offset[4] = allocSize += noOfKeyAttr;
- offset[5] = allocSize += noOfAttrs * ZAD_SIZE;
- offset[6] = allocSize += (noOfAttrs+1) >> 1; // real order
+ offset[3] = allocSize += noOfAttrs * sizeOfReadEndianFunction();
+ offset[4] = allocSize += noOfAttrs * sizeOfReadEndianFunction();
+ offset[5] = allocSize += noOfCharsets * sizeOfPointer;
+ offset[6] = allocSize += noOfKeyAttr;
+ offset[7] = allocSize += noOfAttrs * ZAD_SIZE;
+ offset[8] = allocSize += (noOfAttrs+1) >> 1; // real order
allocSize += ZTD_TRAILER_SIZE;
// return number of words
return allocSize;
@@ -294,7 +296,7 @@ Dbtup::verifytabdes()
ptr.p->noOfCharsets,
ptr.p->noOfKeyAttr,
offset);
- const Uint32 desc = ptr.p->readKeyArray - offset[3];
+ const Uint32 desc = ptr.p->readKeyArray - offset[5];
Uint32 size = alloc;
if (size % ZTD_FREE_SIZE != 0)
size += ZTD_FREE_SIZE - size % ZTD_FREE_SIZE;
--- 1.30/storage/ndb/src/kernel/blocks/dbtup/DbtupTrigger.cpp 2007-05-10 17:46:49 +08:00
+++ 1.31/storage/ndb/src/kernel/blocks/dbtup/DbtupTrigger.cpp 2007-05-10 17:46:49 +08:00
@@ -699,7 +699,7 @@ void Dbtup::executeTrigger(KeyReqStruct
* to convert endian correctly.
*/
if (trigPtr->triggerType == TriggerType::SECONDARY_INDEX) {
- ljam();
+ jam();
req_struct->rec_blockref = req_struct->TC_ref;
}
if (!readTriggerInfo(trigPtr,
--- 1.5/storage/ndb/src/kernel/vm/SimplePropertiesSection.cpp 2007-05-10 17:46:49 +08:00
+++ 1.6/storage/ndb/src/kernel/vm/SimplePropertiesSection.cpp 2007-05-10 17:46:49 +08:00
@@ -180,7 +180,7 @@ SimplePropertiesSectionReader::peekWords
p = m_pool.getPtr(p->m_nextSegment);
}
- if (m_convertEndian && !m_hasConvertedEndian) {
+ if (m_convertEndian && !m_hasConvertedEndian && len > 0) {
Uint16 key = getKey();
switch (key) {
case DictTabInfo::ReplicaData:
--- 1.40/storage/ndb/src/kernel/vm/SimulatedBlock.cpp 2007-05-10 17:46:49 +08:00
+++ 1.41/storage/ndb/src/kernel/vm/SimulatedBlock.cpp 2007-05-10 17:46:49 +08:00
@@ -2107,7 +2107,6 @@ SimulatedBlock::convert_endian_attr(Uint
Uint32 attrNoOfWords= AttributeDescriptor::getSizeInWords(attrDesc);
Uint32 attrNoOfWords64 = (attrNoOfWords + 1) / 2;
Uint32 typeId = AttributeDescriptor::getType(attrDesc);
- Uint32 bitCount;
bool ok = false;
#if 0
@@ -2192,30 +2191,6 @@ SimulatedBlock::convert_endian_attr(Uint
*/
ndbSwapManyWords32((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.
- */
- ndbSwapManyWords64((Uint32*)((char*)src + srcPos), 2);
- ndbSwapManyWords32((Uint32*)((char*)src + srcPos + 8), attrNoOfWords - 2);
- break;
- case NdbSqlUtil::Type::Bit:
- 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) {
- ndbSwapManyWords64((Uint32*)((char*)src + srcPos), attrNoOfWords);
- }
- break;
case NdbSqlUtil::Type::Year:
/**
* 8 bits
@@ -2227,7 +2202,8 @@ SimulatedBlock::convert_endian_attr(Uint
default:
/**
* the types that no need to handle endian:
- * Int, Unsigned, Float, Timestamp.
+ * Int, Unsigned, Float, Timestamp, Bit.
+ * Blob, Text cannot be primary key.
*/
break;
}
@@ -2319,165 +2295,6 @@ SimulatedBlock::convert_endian_var_attr(
// the offset to the next key should be (noOfWords << 2)
attrBytes = noOfWords << 2;
-
- return true;
-}
-
-/**
- * This method is called to swap back the byte order of key attributes
- * after called xfrm_key().
- */
-bool
-SimulatedBlock::convert_endian_xfrm_key(Uint32 tab, Uint32* src,
- Uint32 keyPartLen[MAX_ATTRIBUTES_IN_INDEX]) 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];
- Uint32 keyLen = keyPartLen[i++];
- bool ok =
- convert_endian_xfrm_attr(keyAttr.attributeDescriptor, keyAttr.charsetInfo,
- src, srcPos, keyLen);
- if (unlikely(!ok))
- return false;
- }
-
- return true;
-}
-
-bool
-SimulatedBlock::convert_endian_xfrm_attr(Uint32 attrDesc, CHARSET_INFO* cs,
- Uint32* src, Uint32& srcPos, Uint32 keyLen) const
-{
- Uint32 attrBytes = AttributeDescriptor::getSizeInBytes(attrDesc);
- Uint32 attrNoOfWords= AttributeDescriptor::getSizeInWords(attrDesc);
- Uint32 attrNoOfWords64 = (attrNoOfWords + 1) / 2;
- Uint32 typeId = AttributeDescriptor::getType(attrDesc);
- Uint32 bitCount;
- 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.
- */
- ndbSwapManyWords32((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.
- */
- ndbSwapManyWords16((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.
- */
- ndbSwapManyWords32((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.
- */
- ndbSwapManyWords64((Uint32*)((char*)src + srcPos), attrNoOfWords64 << 1);
- // reset attrNoOfWords
- attrNoOfWords = 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.
- */
- ndbSwapManyWords32((Uint32*)((char*)src + srcPos), attrNoOfWords);
- break;
- case NdbSqlUtil::Type::Varchar:
- case NdbSqlUtil::Type::Varbinary:
- case NdbSqlUtil::Type::Longvarchar:
- case NdbSqlUtil::Type::Longvarbinary:
- /**
- * after xfrm_key(), var data is stored in the byte order of character string.
- * should swap byte order for each byte.
- */
- ndbSwapManyWords32((Uint32*)((char*)src + srcPos), keyLen);
- // reset attrNoOfWords
- attrNoOfWords = keyLen;
- 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.
- */
- ndbSwapManyWords32((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.
- */
- ndbSwapManyWords64((Uint32*)((char*)src + srcPos), 2);
- ndbSwapManyWords32((Uint32*)((char*)src + srcPos + 8), attrNoOfWords - 2);
- break;
- case NdbSqlUtil::Type::Bit:
- 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) {
- ndbSwapManyWords64((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.
- */
- ndbSwapManyWords32((Uint32*)((char*)src + srcPos), attrNoOfWords);
- break;
- default:
- /**
- * the types that no need to handle endian:
- * Int, Unsigned, Float, Timestamp.
- */
- break;
- }
-
- // use attrNoOfWords to calculate the real attrBytes
- attrBytes = attrNoOfWords << 2;
- srcPos += attrBytes;
return true;
}
--- 1.31/storage/ndb/src/kernel/vm/SimulatedBlock.hpp 2007-05-10 17:46:49 +08:00
+++ 1.32/storage/ndb/src/kernel/vm/SimulatedBlock.hpp 2007-05-10 17:46:49 +08:00
@@ -437,10 +437,6 @@ protected:
Uint32* src, Uint32& srcPos) const;
bool convert_endian_var_attr(Uint32 attrDesc, CHARSET_INFO* cs,
Uint32* src, Uint32& srcPos, Uint32& attrBytes) const;
- bool convert_endian_xfrm_key(Uint32 tab, Uint32* src,
- Uint32 keyPartLen[MAX_ATTRIBUTES_IN_INDEX]) const;
- bool convert_endian_xfrm_attr(Uint32 attrDesc, CHARSET_INFO* cs,
- Uint32* src, Uint32& srcPos, Uint32 keyLen) const;
private:
NewVARIABLE* NewVarRef; /* New Base Address Table for block */
| Thread |
|---|
| • bk commit into 5.1 tree (dli:1.2507) | David Li | 10 May |