mirror of
https://github.com/MariaDB/server.git
synced 2025-01-21 22:34:18 +01:00
Merge mysql.com:/home/jonas/src/mysql-5.0
into mysql.com:/home/jonas/src/mysql-5.0-ndb
This commit is contained in:
commit
2a44929c16
49 changed files with 977 additions and 1495 deletions
|
@ -65,7 +65,12 @@ private:
|
|||
UintR buddyConPtr; // DATA 8
|
||||
UintR batch_byte_size; // DATA 9
|
||||
UintR first_batch_size; // DATA 10
|
||||
|
||||
|
||||
/**
|
||||
* Optional
|
||||
*/
|
||||
Uint32 distributionKey;
|
||||
|
||||
/**
|
||||
* Get:ers for requestInfo
|
||||
*/
|
||||
|
@ -76,6 +81,7 @@ private:
|
|||
static Uint8 getRangeScanFlag(const UintR & requestInfo);
|
||||
static Uint8 getKeyinfoFlag(const UintR & requestInfo);
|
||||
static Uint16 getScanBatch(const UintR & requestInfo);
|
||||
static Uint8 getDistributionKeyFlag(const UintR & requestInfo);
|
||||
|
||||
/**
|
||||
* Set:ers for requestInfo
|
||||
|
@ -88,6 +94,7 @@ private:
|
|||
static void setRangeScanFlag(UintR & requestInfo, Uint32 flag);
|
||||
static void setKeyinfoFlag(UintR & requestInfo, Uint32 flag);
|
||||
static void setScanBatch(Uint32& requestInfo, Uint32 sz);
|
||||
static void setDistributionKeyFlag(Uint32& requestInfo, Uint32 flag);
|
||||
};
|
||||
|
||||
/**
|
||||
|
@ -100,6 +107,7 @@ private:
|
|||
k = Keyinfo - 1 Bit 12
|
||||
x = Range Scan (TUX) - 1 Bit 15
|
||||
b = Scan batch - 10 Bit 16-25 (max 1023)
|
||||
d = Distribution key flag
|
||||
|
||||
1111111111222222222233
|
||||
01234567890123456789012345678901
|
||||
|
@ -127,6 +135,8 @@ private:
|
|||
#define SCAN_BATCH_SHIFT (16)
|
||||
#define SCAN_BATCH_MASK (1023)
|
||||
|
||||
#define SCAN_DISTR_KEY_SHIFT (26)
|
||||
|
||||
inline
|
||||
Uint8
|
||||
ScanTabReq::getParallelism(const UintR & requestInfo){
|
||||
|
@ -225,6 +235,18 @@ ScanTabReq::setKeyinfoFlag(UintR & requestInfo, Uint32 flag){
|
|||
requestInfo |= (flag << KEYINFO_SHIFT);
|
||||
}
|
||||
|
||||
inline
|
||||
Uint8
|
||||
ScanTabReq::getDistributionKeyFlag(const UintR & requestInfo){
|
||||
return (Uint8)((requestInfo >> SCAN_DISTR_KEY_SHIFT) & 1);
|
||||
}
|
||||
|
||||
inline
|
||||
void
|
||||
ScanTabReq::setDistributionKeyFlag(UintR & requestInfo, Uint32 flag){
|
||||
ASSERT_BOOL(flag, "ScanTabReq::setKeyinfoFlag");
|
||||
requestInfo |= (flag << SCAN_DISTR_KEY_SHIFT);
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
|
|
|
@ -18,379 +18,7 @@
|
|||
#define TC_INDX_H
|
||||
|
||||
#include "SignalData.hpp"
|
||||
|
||||
class TcIndxReq {
|
||||
/**
|
||||
* Reciver(s)
|
||||
*/
|
||||
friend class Dbtc; // Reciver
|
||||
|
||||
/**
|
||||
* Sender(s)
|
||||
*/
|
||||
friend class NdbIndexOperation;
|
||||
|
||||
/**
|
||||
* For printing
|
||||
*/
|
||||
friend bool printTCINDXREQ(FILE *, const Uint32 *, Uint32, Uint16);
|
||||
|
||||
public:
|
||||
/**
|
||||
* Length of signal
|
||||
*/
|
||||
STATIC_CONST( StaticLength = 8 );
|
||||
STATIC_CONST( SignalLength = 25 );
|
||||
STATIC_CONST( MaxKeyInfo = 8 );
|
||||
STATIC_CONST( MaxAttrInfo = 5 );
|
||||
|
||||
private:
|
||||
|
||||
enum CommitType {
|
||||
CommitIfFailFree = 0,
|
||||
TryCommit = 1,
|
||||
CommitAsMuchAsPossible = 2
|
||||
};
|
||||
|
||||
/**
|
||||
* DATA VARIABLES
|
||||
*/
|
||||
//-------------------------------------------------------------
|
||||
// Unconditional part. First 8 words
|
||||
//-------------------------------------------------------------
|
||||
UintR apiConnectPtr; // DATA 0
|
||||
UintR senderData; // DATA 1
|
||||
UintR attrLen; // DATA 2 (including API Version)
|
||||
UintR indexId; // DATA 3
|
||||
UintR requestInfo; // DATA 4
|
||||
UintR indexSchemaVersion; // DATA 5
|
||||
UintR transId1; // DATA 6
|
||||
UintR transId2; // DATA 7
|
||||
//-------------------------------------------------------------
|
||||
// Conditional part. Those four words will be sent only if their
|
||||
// indicator is set.
|
||||
//-------------------------------------------------------------
|
||||
UintR scanInfo; // DATA 8
|
||||
UintR distrGroupHashValue; // DATA 9
|
||||
UintR distributionKeySize; // DATA 10
|
||||
UintR storedProcId; // DATA 11
|
||||
|
||||
//-------------------------------------------------------------
|
||||
// Variable sized key and attrinfo part. Those will be placed to
|
||||
// pack the signal in an appropriate manner.
|
||||
//-------------------------------------------------------------
|
||||
UintR keyInfo[MaxKeyInfo]; // DATA 12 - 19
|
||||
UintR attrInfo[MaxAttrInfo]; // DATA 20 - 24
|
||||
|
||||
static Uint8 getAPIVersion(const UintR & attrLen);
|
||||
|
||||
/**
|
||||
* Get:ers for requestInfo
|
||||
*/
|
||||
static Uint8 getCommitFlag(const UintR & requestInfo);
|
||||
static Uint8 getCommitType(const UintR & requestInfo);
|
||||
static Uint8 getStartFlag(const UintR & requestInfo);
|
||||
static Uint8 getSimpleFlag(const UintR & requestInfo);
|
||||
static Uint8 getDirtyFlag(const UintR & requestInfo);
|
||||
static Uint8 getInterpretedFlag(const UintR & requestInfo);
|
||||
static Uint8 getDistributionGroupFlag(const UintR & requestInfo);
|
||||
static Uint8 getDistributionGroupTypeFlag(const UintR & requestInfo);
|
||||
static Uint8 getDistributionKeyFlag(const UintR & requestInfo);
|
||||
static Uint8 getScanIndFlag(const UintR & requestInfo);
|
||||
|
||||
static Uint8 getOperationType(const UintR & requestInfo);
|
||||
|
||||
static Uint16 getIndexLength(const UintR & requestInfo);
|
||||
static Uint8 getAIInTcIndxReq(const UintR & requestInfo);
|
||||
|
||||
/**
|
||||
* Get:ers for scanInfo
|
||||
*/
|
||||
|
||||
static void setAPIVersion(UintR & attrLen, Uint16 apiVersion);
|
||||
|
||||
/**
|
||||
* Set:ers for requestInfo
|
||||
*/
|
||||
static void clearRequestInfo(UintR & requestInfo);
|
||||
static void setCommitType(UintR & requestInfo, Uint32 type);
|
||||
static void setCommitFlag(UintR & requestInfo, Uint32 flag);
|
||||
static void setStartFlag(UintR & requestInfo, Uint32 flag);
|
||||
static void setSimpleFlag(UintR & requestInfo, Uint32 flag);
|
||||
static void setDirtyFlag(UintR & requestInfo, Uint32 flag);
|
||||
static void setInterpretedFlag(UintR & requestInfo, Uint32 flag);
|
||||
static void setDistributionGroupFlag(UintR & requestInfo, Uint32 flag);
|
||||
static void setDistributionGroupTypeFlag(UintR & requestInfo, Uint32 flag);
|
||||
static void setDistributionKeyFlag(UintR & requestInfo, Uint32 flag);
|
||||
static void setScanIndFlag(UintR & requestInfo, Uint32 flag);
|
||||
|
||||
static void setOperationType(UintR & requestInfo, Uint32 type);
|
||||
|
||||
static void setIndexLength(UintR & requestInfo, Uint32 len);
|
||||
static void setAIInTcIndxReq(UintR & requestInfo, Uint32 len);
|
||||
|
||||
/**
|
||||
* Set:ers for scanInfo
|
||||
*/
|
||||
|
||||
};
|
||||
|
||||
#define API_VER_NO_SHIFT (16)
|
||||
#define API_VER_NO_MASK (65535)
|
||||
|
||||
/**
|
||||
* Request Info
|
||||
*
|
||||
a = Attr Info in TCINDXREQ - 3 Bits -> Max 7 (Bit 16-18)
|
||||
b = Distribution Key Ind - 1 Bit 2
|
||||
c = Commit Indicator - 1 Bit 4
|
||||
d = Dirty Indicator - 1 Bit 0
|
||||
e = Scan Indicator - 1 Bit 14
|
||||
g = Distribution Group Ind - 1 Bit 1
|
||||
i = Interpreted Indicator - 1 Bit 15
|
||||
k = Index lengt - 12 Bits -> Max 4095 (Bit 20 - 31)
|
||||
o = Operation Type - 3 Bits -> Max 7 (Bit 5-7)
|
||||
p = Simple Indicator - 1 Bit 8
|
||||
s = Start Indicator - 1 Bit 11
|
||||
t = Distribution GroupType - 1 Bit 3
|
||||
y = Commit Type - 2 Bit 12-13
|
||||
x = Last Op in execute - 1 Bit 19
|
||||
|
||||
1111111111222222222233
|
||||
01234567890123456789012345678901
|
||||
dgbtcooop syyeiaaa-kkkkkkkkkkkk
|
||||
*/
|
||||
|
||||
#define COMMIT_SHIFT (4)
|
||||
#define START_SHIFT (11)
|
||||
#define SIMPLE_SHIFT (8)
|
||||
#define DIRTY_SHIFT (0)
|
||||
#define INTERPRETED_SHIFT (15)
|
||||
#define DISTR_GROUP_SHIFT (1)
|
||||
#define DISTR_GROUP_TYPE_SHIFT (3)
|
||||
#define DISTR_KEY_SHIFT (2)
|
||||
#define SCAN_SHIFT (14)
|
||||
|
||||
#define OPERATION_SHIFT (5)
|
||||
#define OPERATION_MASK (7)
|
||||
|
||||
#define AINFO_SHIFT (16)
|
||||
#define AINFO_MASK (7)
|
||||
|
||||
#define INDEX_LEN_SHIFT (20)
|
||||
#define INDEX_LEN_MASK (4095)
|
||||
|
||||
#define COMMIT_TYPE_SHIFT (12)
|
||||
#define COMMIT_TYPE_MASK (3)
|
||||
|
||||
#define LAST_OP_IN_EXEC_SHIFT (19)
|
||||
|
||||
/**
|
||||
* Scan Info
|
||||
*
|
||||
|
||||
|
||||
1111111111222222222233
|
||||
01234567890123456789012345678901
|
||||
|
||||
*/
|
||||
|
||||
inline
|
||||
Uint8
|
||||
TcIndxReq::getCommitFlag(const UintR & requestInfo){
|
||||
return (Uint8)((requestInfo >> COMMIT_SHIFT) & 1);
|
||||
}
|
||||
|
||||
inline
|
||||
Uint8
|
||||
TcIndxReq::getCommitType(const UintR & requestInfo){
|
||||
return (Uint8)((requestInfo >> COMMIT_TYPE_SHIFT) & COMMIT_TYPE_MASK);
|
||||
}
|
||||
|
||||
inline
|
||||
Uint8
|
||||
TcIndxReq::getStartFlag(const UintR & requestInfo){
|
||||
return (Uint8)((requestInfo >> START_SHIFT) & 1);
|
||||
}
|
||||
|
||||
inline
|
||||
Uint8
|
||||
TcIndxReq::getSimpleFlag(const UintR & requestInfo){
|
||||
return (Uint8)((requestInfo >> SIMPLE_SHIFT) & 1);
|
||||
}
|
||||
|
||||
inline
|
||||
Uint8
|
||||
TcIndxReq::getDirtyFlag(const UintR & requestInfo){
|
||||
return (Uint8)((requestInfo >> DIRTY_SHIFT) & 1);
|
||||
}
|
||||
|
||||
inline
|
||||
Uint8
|
||||
TcIndxReq::getInterpretedFlag(const UintR & requestInfo){
|
||||
return (Uint8)((requestInfo >> INTERPRETED_SHIFT) & 1);
|
||||
}
|
||||
|
||||
inline
|
||||
Uint8
|
||||
TcIndxReq::getDistributionGroupFlag(const UintR & requestInfo){
|
||||
return (Uint8)((requestInfo >> DISTR_GROUP_SHIFT) & 1);
|
||||
}
|
||||
|
||||
inline
|
||||
Uint8
|
||||
TcIndxReq::getDistributionGroupTypeFlag(const UintR & requestInfo){
|
||||
return (Uint8)((requestInfo >> DISTR_GROUP_TYPE_SHIFT) & 1);
|
||||
}
|
||||
|
||||
inline
|
||||
Uint8
|
||||
TcIndxReq::getDistributionKeyFlag(const UintR & requestInfo){
|
||||
return (Uint8)((requestInfo >> DISTR_KEY_SHIFT) & 1);
|
||||
}
|
||||
|
||||
inline
|
||||
Uint8
|
||||
TcIndxReq::getScanIndFlag(const UintR & requestInfo){
|
||||
return (Uint8)((requestInfo >> SCAN_SHIFT) & 1);
|
||||
}
|
||||
|
||||
inline
|
||||
Uint8
|
||||
TcIndxReq::getOperationType(const UintR & requestInfo){
|
||||
return (Uint8)((requestInfo >> OPERATION_SHIFT) & OPERATION_MASK);
|
||||
}
|
||||
|
||||
inline
|
||||
Uint16
|
||||
TcIndxReq::getIndexLength(const UintR & requestInfo){
|
||||
return (Uint16)((requestInfo >> INDEX_LEN_SHIFT) & INDEX_LEN_MASK);
|
||||
}
|
||||
|
||||
inline
|
||||
Uint8
|
||||
TcIndxReq::getAIInTcIndxReq(const UintR & requestInfo){
|
||||
return (Uint8)((requestInfo >> AINFO_SHIFT) & AINFO_MASK);
|
||||
}
|
||||
|
||||
inline
|
||||
void
|
||||
TcIndxReq::clearRequestInfo(UintR & requestInfo){
|
||||
requestInfo = 0;
|
||||
}
|
||||
|
||||
inline
|
||||
void
|
||||
TcIndxReq::setCommitType(UintR & requestInfo, Uint32 type){
|
||||
ASSERT_MAX(type, COMMIT_TYPE_MASK, "TcIndxReq::setCommitType");
|
||||
requestInfo |= (type << COMMIT_TYPE_SHIFT);
|
||||
}
|
||||
|
||||
inline
|
||||
void
|
||||
TcIndxReq::setCommitFlag(UintR & requestInfo, Uint32 flag){
|
||||
ASSERT_BOOL(flag, "TcIndxReq::setCommitFlag");
|
||||
requestInfo &= ~(1 << COMMIT_SHIFT);
|
||||
requestInfo |= (flag << COMMIT_SHIFT);
|
||||
}
|
||||
|
||||
inline
|
||||
void
|
||||
TcIndxReq::setStartFlag(UintR & requestInfo, Uint32 flag){
|
||||
ASSERT_BOOL(flag, "TcIndxReq::setStartFlag");
|
||||
requestInfo &= ~(1 << START_SHIFT);
|
||||
requestInfo |= (flag << START_SHIFT);
|
||||
}
|
||||
|
||||
inline
|
||||
void
|
||||
TcIndxReq::setSimpleFlag(UintR & requestInfo, Uint32 flag){
|
||||
ASSERT_BOOL(flag, "TcIndxReq::setSimpleFlag");
|
||||
requestInfo &= ~(1 << SIMPLE_SHIFT);
|
||||
requestInfo |= (flag << SIMPLE_SHIFT);
|
||||
}
|
||||
|
||||
inline
|
||||
void
|
||||
TcIndxReq::setDirtyFlag(UintR & requestInfo, Uint32 flag){
|
||||
ASSERT_BOOL(flag, "TcIndxReq::setDirtyFlag");
|
||||
requestInfo &= ~(1 << DIRTY_SHIFT);
|
||||
requestInfo |= (flag << DIRTY_SHIFT);
|
||||
}
|
||||
|
||||
inline
|
||||
void
|
||||
TcIndxReq::setInterpretedFlag(UintR & requestInfo, Uint32 flag){
|
||||
ASSERT_BOOL(flag, "TcIndxReq::setInterpretedFlag");
|
||||
requestInfo &= ~(1 << INTERPRETED_SHIFT);
|
||||
requestInfo |= (flag << INTERPRETED_SHIFT);
|
||||
}
|
||||
|
||||
inline
|
||||
void
|
||||
TcIndxReq::setDistributionGroupTypeFlag(UintR & requestInfo, Uint32 flag){
|
||||
ASSERT_BOOL(flag, "TcIndxReq::setDistributionGroupTypeFlag");
|
||||
requestInfo &= ~(1 << DISTR_GROUP_TYPE_SHIFT);
|
||||
requestInfo |= (flag << DISTR_GROUP_TYPE_SHIFT);
|
||||
}
|
||||
|
||||
inline
|
||||
void
|
||||
TcIndxReq::setDistributionGroupFlag(UintR & requestInfo, Uint32 flag){
|
||||
ASSERT_BOOL(flag, "TcIndxReq::setDistributionGroupFlag");
|
||||
requestInfo &= ~(1 << DISTR_GROUP_SHIFT);
|
||||
requestInfo |= (flag << DISTR_GROUP_SHIFT);
|
||||
}
|
||||
|
||||
inline
|
||||
void
|
||||
TcIndxReq::setDistributionKeyFlag(UintR & requestInfo, Uint32 flag){
|
||||
ASSERT_BOOL(flag, "TcIndxReq::setDistributionKeyFlag");
|
||||
requestInfo &= ~(1 << DISTR_KEY_SHIFT);
|
||||
requestInfo |= (flag << DISTR_KEY_SHIFT);
|
||||
}
|
||||
|
||||
inline
|
||||
void
|
||||
TcIndxReq::setScanIndFlag(UintR & requestInfo, Uint32 flag){
|
||||
ASSERT_BOOL(flag, "TcIndxReq::setScanIndFlag");
|
||||
requestInfo &= ~(1 << SCAN_SHIFT);
|
||||
requestInfo |= (flag << SCAN_SHIFT);
|
||||
}
|
||||
|
||||
inline
|
||||
void
|
||||
TcIndxReq::setOperationType(UintR & requestInfo, Uint32 type){
|
||||
ASSERT_MAX(type, OPERATION_MASK, "TcIndxReq::setOperationType");
|
||||
requestInfo |= (type << OPERATION_SHIFT);
|
||||
}
|
||||
|
||||
inline
|
||||
void
|
||||
TcIndxReq::setIndexLength(UintR & requestInfo, Uint32 len){
|
||||
ASSERT_MAX(len, INDEX_LEN_MASK, "TcIndxReq::setKeyLength");
|
||||
requestInfo |= (len << INDEX_LEN_SHIFT);
|
||||
}
|
||||
|
||||
inline
|
||||
void
|
||||
TcIndxReq::setAIInTcIndxReq(UintR & requestInfo, Uint32 len){
|
||||
ASSERT_MAX(len, AINFO_MASK, "TcIndxReq::setAIInTcIndxReq");
|
||||
requestInfo |= (len << AINFO_SHIFT);
|
||||
}
|
||||
|
||||
inline
|
||||
Uint8
|
||||
TcIndxReq::getAPIVersion(const UintR & anAttrLen){
|
||||
return (Uint16)((anAttrLen >> API_VER_NO_SHIFT) & API_VER_NO_MASK);
|
||||
}
|
||||
|
||||
inline
|
||||
void
|
||||
TcIndxReq::setAPIVersion(UintR & anAttrLen, Uint16 apiVersion){
|
||||
// ASSERT_MAX(apiVersion, API_VER_NO_MASK, "TcIndxReq::setAPIVersion");
|
||||
anAttrLen |= (apiVersion << API_VER_NO_SHIFT);
|
||||
}
|
||||
#include "TcKeyReq.hpp"
|
||||
|
||||
class TcIndxConf {
|
||||
|
||||
|
|
|
@ -142,7 +142,7 @@ private:
|
|||
* Get:ers for scanInfo
|
||||
*/
|
||||
static Uint8 getTakeOverScanFlag(const UintR & scanInfo);
|
||||
static Uint16 getTakeOverScanNode(const UintR & scanInfo);
|
||||
static Uint16 getTakeOverScanFragment(const UintR & scanInfo);
|
||||
static Uint32 getTakeOverScanInfo(const UintR & scanInfo);
|
||||
|
||||
|
||||
|
@ -171,7 +171,7 @@ private:
|
|||
* Set:ers for scanInfo
|
||||
*/
|
||||
static void setTakeOverScanFlag(UintR & scanInfo, Uint8 flag);
|
||||
static void setTakeOverScanNode(UintR & scanInfo, Uint16 node);
|
||||
static void setTakeOverScanFragment(UintR & scanInfo, Uint16 fragment);
|
||||
static void setTakeOverScanInfo(UintR & scanInfo, Uint32 aScanInfo);
|
||||
};
|
||||
|
||||
|
@ -238,8 +238,8 @@ private:
|
|||
|
||||
#define TAKE_OVER_SHIFT (0)
|
||||
|
||||
#define TAKE_OVER_NODE_SHIFT (20)
|
||||
#define TAKE_OVER_NODE_MASK (4095)
|
||||
#define TAKE_OVER_FRAG_SHIFT (20)
|
||||
#define TAKE_OVER_FRAG_MASK (4095)
|
||||
|
||||
#define SCAN_INFO_SHIFT (1)
|
||||
#define SCAN_INFO_MASK (262143)
|
||||
|
@ -485,8 +485,8 @@ TcKeyReq::getTakeOverScanFlag(const UintR & scanInfo){
|
|||
|
||||
inline
|
||||
Uint16
|
||||
TcKeyReq::getTakeOverScanNode(const UintR & scanInfo){
|
||||
return (Uint16)((scanInfo >> TAKE_OVER_NODE_SHIFT) & TAKE_OVER_NODE_MASK);
|
||||
TcKeyReq::getTakeOverScanFragment(const UintR & scanInfo){
|
||||
return (Uint16)((scanInfo >> TAKE_OVER_FRAG_SHIFT) & TAKE_OVER_FRAG_MASK);
|
||||
}
|
||||
|
||||
inline
|
||||
|
@ -505,9 +505,9 @@ TcKeyReq::setTakeOverScanFlag(UintR & scanInfo, Uint8 flag){
|
|||
|
||||
inline
|
||||
void
|
||||
TcKeyReq::setTakeOverScanNode(UintR & scanInfo, Uint16 node){
|
||||
TcKeyReq::setTakeOverScanFragment(UintR & scanInfo, Uint16 node){
|
||||
// ASSERT_MAX(node, TAKE_OVER_NODE_MASK, "TcKeyReq::setTakeOverScanNode");
|
||||
scanInfo |= (node << TAKE_OVER_NODE_SHIFT);
|
||||
scanInfo |= (node << TAKE_OVER_FRAG_SHIFT);
|
||||
}
|
||||
|
||||
inline
|
||||
|
|
|
@ -371,16 +371,6 @@ public:
|
|||
/** @} *******************************************************************/
|
||||
|
||||
#ifndef DOXYGEN_SHOULD_SKIP_INTERNAL
|
||||
void setTupleKey(bool);
|
||||
bool getTupleKey() const;
|
||||
|
||||
void setDistributionGroup(bool, int bits = 16);
|
||||
bool getDistributionGroup() const;
|
||||
int getDistributionGroupBits() const;
|
||||
|
||||
void setIndexOnlyStorage(bool);
|
||||
bool getIndexOnlyStorage() const;
|
||||
|
||||
const Table * getBlobTable() const;
|
||||
|
||||
/**
|
||||
|
|
|
@ -176,30 +176,17 @@ private:
|
|||
NdbIndexOperation(Ndb* aNdb);
|
||||
~NdbIndexOperation();
|
||||
|
||||
void closeScan();
|
||||
|
||||
int receiveTCINDXREF(NdbApiSignal* aSignal);
|
||||
|
||||
// Overloaded method from NdbOperation
|
||||
void setLastFlag(NdbApiSignal* signal, Uint32 lastFlag);
|
||||
|
||||
// Overloaded methods from NdbCursorOperation
|
||||
int executeCursor(int ProcessorId);
|
||||
|
||||
// Overloaded methods from NdbCursorOperation
|
||||
int indxInit(const class NdbIndexImpl* anIndex,
|
||||
const class NdbTableImpl* aTable,
|
||||
NdbConnection* myConnection);
|
||||
|
||||
int equal_impl(const class NdbColumnImpl*, const char* aValue, Uint32 len);
|
||||
int prepareSend(Uint32 TC_ConnectPtr, Uint64 TransactionId);
|
||||
|
||||
// Private attributes
|
||||
const NdbIndexImpl* m_theIndex;
|
||||
const NdbTableImpl* m_thePrimaryTable;
|
||||
Uint32 m_theIndexDefined[NDB_MAX_ATTRIBUTES_IN_INDEX][3];
|
||||
Uint32 m_theIndexLen; // Length of the index in words
|
||||
Uint32 m_theNoOfIndexDefined; // The number of index attributes
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
|
@ -719,6 +719,15 @@ public:
|
|||
|
||||
LockMode getLockMode() const { return theLockMode; }
|
||||
|
||||
/**
|
||||
* Set/get distribution/partition key
|
||||
*/
|
||||
void setPartitionId(Uint32 id);
|
||||
void setPartitionHash(Uint32 key);
|
||||
void setPartitionHash(const Uint64 *, Uint32 len);
|
||||
Uint32 getPartitionId() const;
|
||||
protected:
|
||||
int handle_distribution_key(const Uint64 *, Uint32 len);
|
||||
protected:
|
||||
/******************************************************************************
|
||||
* These are the methods used to create and delete the NdbOperation objects.
|
||||
|
@ -810,13 +819,12 @@ protected:
|
|||
int branch_col_null(Uint32 type, Uint32 col, Uint32 Label);
|
||||
|
||||
// Handle ATTRINFO signals
|
||||
int insertATTRINFO(Uint32 aData);
|
||||
int insertATTRINFOloop(const Uint32* aDataPtr, Uint32 aLength);
|
||||
|
||||
int insertKEYINFO(const char* aValue,
|
||||
Uint32 aStartPosition,
|
||||
Uint32 aKeyLenInByte,
|
||||
Uint32 anAttrBitsInLastWord);
|
||||
int insertATTRINFO(Uint32 aData);
|
||||
int insertATTRINFOloop(const Uint32* aDataPtr, Uint32 aLength);
|
||||
|
||||
int insertKEYINFO(const char* aValue,
|
||||
Uint32 aStartPosition,
|
||||
Uint32 aKeyLenInByte);
|
||||
|
||||
virtual void setErrorCode(int aErrorCode);
|
||||
virtual void setErrorCodeAbort(int aErrorCode);
|
||||
|
@ -850,14 +858,18 @@ protected:
|
|||
Ndb* theNdb; // Point back to the Ndb object.
|
||||
NdbConnection* theNdbCon; // Point back to the connection object.
|
||||
NdbOperation* theNext; // Next pointer to operation.
|
||||
NdbApiSignal* theTCREQ; // The TC[KEY/INDX]REQ signal object
|
||||
|
||||
union {
|
||||
NdbApiSignal* theTCREQ; // The TC[KEY/INDX]REQ signal object
|
||||
NdbApiSignal* theSCAN_TABREQ;
|
||||
};
|
||||
|
||||
NdbApiSignal* theFirstATTRINFO; // The first ATTRINFO signal object
|
||||
NdbApiSignal* theCurrentATTRINFO; // The current ATTRINFO signal object
|
||||
Uint32 theTotalCurrAI_Len; // The total number of attribute info
|
||||
// words currently defined
|
||||
Uint32 theAI_LenInCurrAI; // The number of words defined in the
|
||||
// current ATTRINFO signal
|
||||
NdbApiSignal* theFirstKEYINFO; // The first KEYINFO signal object
|
||||
NdbApiSignal* theLastKEYINFO; // The first KEYINFO signal object
|
||||
|
||||
class NdbLabel* theFirstLabel;
|
||||
|
@ -874,8 +886,8 @@ protected:
|
|||
Uint32* theKEYINFOptr; // Pointer to where to write KEYINFO
|
||||
Uint32* theATTRINFOptr; // Pointer to where to write ATTRINFO
|
||||
|
||||
const class NdbTableImpl* m_currentTable; // The current table
|
||||
const class NdbTableImpl* m_accessTable;
|
||||
const class NdbTableImpl* m_currentTable; // The current table
|
||||
const class NdbTableImpl* m_accessTable; // Index table (== current for pk)
|
||||
|
||||
// Set to TRUE when a tuple key attribute has been defined.
|
||||
Uint32 theTupleKeyDefined[NDB_MAX_NO_OF_ATTRIBUTES_IN_KEY][3];
|
||||
|
@ -883,18 +895,18 @@ protected:
|
|||
Uint32 theTotalNrOfKeyWordInSignal; // The total number of
|
||||
// keyword in signal.
|
||||
|
||||
Uint32 theTupKeyLen; // Length of the tuple key in words
|
||||
Uint32 theNoOfTupKeyDefined; // The number of tuple key attributes
|
||||
// currently defined
|
||||
OperationType theOperationType; // Read Request, Update Req......
|
||||
|
||||
Uint32 theTupKeyLen; // Length of the tuple key in words
|
||||
// left until done
|
||||
Uint8 theNoOfTupKeyLeft; // The number of tuple key attributes
|
||||
OperationType theOperationType; // Read Request, Update Req......
|
||||
|
||||
LockMode theLockMode; // Can be set to WRITE if read operation
|
||||
OperationStatus theStatus; // The status of the operation.
|
||||
|
||||
Uint32 theMagicNumber; // Magic number to verify that object
|
||||
// is correct
|
||||
Uint32 theScanInfo; // Scan info bits (take over flag etc)
|
||||
Uint32 theDistrKeySize; // Distribution Key size if used
|
||||
Uint32 theDistributionGroup; // Distribution Group if used
|
||||
Uint32 theDistributionKey; // Distribution Key size if used
|
||||
|
||||
Uint32 theSubroutineSize; // Size of subroutines for interpretation
|
||||
Uint32 theInitialReadSize; // Size of initial reads for interpretation
|
||||
|
@ -902,14 +914,12 @@ protected:
|
|||
Uint32 theFinalUpdateSize; // Size of final updates for interpretation
|
||||
Uint32 theFinalReadSize; // Size of final reads for interpretation
|
||||
|
||||
Uint8 theStartIndicator; // Indicator of whether start operation
|
||||
Uint8 theCommitIndicator; // Indicator of whether commit operation
|
||||
Uint8 theSimpleIndicator; // Indicator of whether simple operation
|
||||
Uint8 theDirtyIndicator; // Indicator of whether dirty operation
|
||||
Uint8 theInterpretIndicator; // Indicator of whether interpreted operation
|
||||
Uint8 theDistrGroupIndicator; // Indicates whether distribution grp is used
|
||||
Uint8 theDistrGroupType; // Type of distribution group used
|
||||
Uint8 theDistrKeyIndicator; // Indicates whether distr. key is used
|
||||
Uint8 theStartIndicator; // Indicator of whether start operation
|
||||
Uint8 theCommitIndicator; // Indicator of whether commit operation
|
||||
Uint8 theSimpleIndicator; // Indicator of whether simple operation
|
||||
Uint8 theDirtyIndicator; // Indicator of whether dirty operation
|
||||
Uint8 theInterpretIndicator; // Indicator of whether interpreted operation
|
||||
Int8 theDistrKeyIndicator_; // Indicates whether distr. key is used
|
||||
|
||||
Uint16 m_tcReqGSN;
|
||||
Uint16 m_keyInfoGSN;
|
||||
|
|
|
@ -114,7 +114,6 @@ protected:
|
|||
// Scan related variables
|
||||
Uint32 theParallelism;
|
||||
Uint32 m_keyInfo;
|
||||
NdbApiSignal* theSCAN_TABREQ;
|
||||
|
||||
int getFirstATTRINFOScan();
|
||||
int doSendScan(int ProcessorId);
|
||||
|
|
|
@ -20,6 +20,15 @@
|
|||
#include <ndb_types.h>
|
||||
|
||||
// External declaration of hash function
|
||||
Uint32 md5_hash(const Uint64* keybuf, Uint32 no_of_32_words);
|
||||
void md5_hash(Uint32 result[4], const Uint64* keybuf, Uint32 no_of_32_words);
|
||||
|
||||
inline
|
||||
Uint32
|
||||
md5_hash(const Uint64* keybuf, Uint32 no_of_32_words)
|
||||
{
|
||||
Uint32 result[4];
|
||||
md5_hash(result, keybuf, no_of_32_words);
|
||||
return result[0];
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
|
@ -82,14 +82,10 @@ SignalDataPrintFunctions[] = {
|
|||
{ GSN_ALTER_INDX_REQ, printALTER_INDX_REQ },
|
||||
{ GSN_ALTER_INDX_CONF, printALTER_INDX_CONF },
|
||||
{ GSN_ALTER_INDX_REF, printALTER_INDX_REF },
|
||||
{ GSN_TCINDXREQ, printTCINDXREQ },
|
||||
{ GSN_TCINDXCONF, printTCINDXCONF },
|
||||
{ GSN_TCINDXREF, printTCINDXREF },
|
||||
{ GSN_INDXKEYINFO, printINDXKEYINFO },
|
||||
{ GSN_INDXATTRINFO, printINDXATTRINFO },
|
||||
//{ GSN_TCINDXNEXTREQ, printTCINDXNEXTREQ },
|
||||
//{ GSN_TCINDEXNEXTCONF, printTCINDEXNEXTCONF },
|
||||
//{ GSN_TCINDEXNEXREF, printTCINDEXNEXREF },
|
||||
{ GSN_FSAPPENDREQ, printFSAPPENDREQ },
|
||||
{ GSN_BACKUP_REQ, printBACKUP_REQ },
|
||||
{ GSN_BACKUP_DATA, printBACKUP_DATA },
|
||||
|
|
|
@ -18,91 +18,6 @@
|
|||
#include <signaldata/TcKeyReq.hpp>
|
||||
#include <BlockNumbers.h>
|
||||
|
||||
bool
|
||||
printTCINDXREQ(FILE * output, const Uint32 * theData, Uint32 len, Uint16 receiverBlockNo){
|
||||
|
||||
const TcIndxReq * const sig = (TcIndxReq *) theData;
|
||||
|
||||
UintR requestInfo = sig->requestInfo;
|
||||
UintR scanInfo = sig->scanInfo;
|
||||
|
||||
fprintf(output, " apiConnectPtr: H\'%.8x, senderData: H\'%.8x\n",
|
||||
sig->apiConnectPtr, sig->senderData);
|
||||
|
||||
fprintf(output, " Operation: %s, Flags: ",
|
||||
sig->getOperationType(requestInfo) == ZREAD ? "Read" :
|
||||
sig->getOperationType(requestInfo) == ZREAD_EX ? "Read-Ex" :
|
||||
sig->getOperationType(requestInfo) == ZUPDATE ? "Update" :
|
||||
sig->getOperationType(requestInfo) == ZINSERT ? "Insert" :
|
||||
sig->getOperationType(requestInfo) == ZDELETE ? "Delete" :
|
||||
sig->getOperationType(requestInfo) == ZWRITE ? "Write" :
|
||||
"Unknown");
|
||||
|
||||
{
|
||||
if(sig->getDirtyFlag(requestInfo)){
|
||||
fprintf(output, "Dirty ");
|
||||
}
|
||||
if(sig->getStartFlag(requestInfo)){
|
||||
fprintf(output, "Start ");
|
||||
}
|
||||
if (TcKeyReq::getExecuteFlag(sig->requestInfo)) {
|
||||
fprintf(output, "Execute ");
|
||||
}
|
||||
if(sig->getCommitFlag(requestInfo)){
|
||||
fprintf(output, "Commit, Type = ");
|
||||
UintR TcommitType = sig->getCommitType(requestInfo);
|
||||
if (TcommitType == TcIndxReq::CommitIfFailFree) {
|
||||
fprintf(output, "FailFree ");
|
||||
} else if (TcommitType == TcIndxReq::TryCommit) {
|
||||
fprintf(output, "TryCommit ");
|
||||
} else if (TcommitType == TcIndxReq::CommitAsMuchAsPossible) {
|
||||
fprintf(output, "Always ");
|
||||
}//if
|
||||
}
|
||||
if(sig->getSimpleFlag(requestInfo)){
|
||||
fprintf(output, "Simple ");
|
||||
}
|
||||
if(sig->getInterpretedFlag(requestInfo)){
|
||||
fprintf(output, "Interpreted ");
|
||||
}
|
||||
if(sig->getDistributionGroupFlag(requestInfo)){
|
||||
fprintf(output, "DGroup = %d ", sig->distrGroupHashValue);
|
||||
}
|
||||
if(sig->getDistributionKeyFlag(sig->requestInfo)){
|
||||
fprintf(output, "DKey = %d ", sig->distributionKeySize);
|
||||
}
|
||||
fprintf(output, "\n");
|
||||
}
|
||||
|
||||
const int indexLen = sig->getIndexLength(requestInfo);
|
||||
const int attrInThis = sig->getAIInTcIndxReq(requestInfo);
|
||||
fprintf(output,
|
||||
" indexLen: %d, attrLen: %d, AI in this: %d, indexId: %d, "
|
||||
"indexSchemaVer: %d, API Ver: %d\n",
|
||||
indexLen, sig->attrLen, attrInThis,
|
||||
sig->indexId, sig->indexSchemaVersion, sig->getAPIVersion(scanInfo));
|
||||
|
||||
fprintf(output, " transId(1, 2): (H\'%.8x, H\'%.8x)\n -- Variable Data --\n",
|
||||
sig->transId1, sig->transId2);
|
||||
|
||||
Uint32 restLen = (len - 8);
|
||||
const Uint32 * rest = &sig->scanInfo;
|
||||
while(restLen >= 7){
|
||||
fprintf(output,
|
||||
" H\'%.8x H\'%.8x H\'%.8x H\'%.8x H\'%.8x H\'%.8x H\'%.8x\n",
|
||||
rest[0], rest[1], rest[2], rest[3],
|
||||
rest[4], rest[5], rest[6]);
|
||||
restLen -= 7;
|
||||
rest += 7;
|
||||
}
|
||||
if(restLen > 0){
|
||||
for(Uint32 i = 0; i<restLen; i++)
|
||||
fprintf(output, " H\'%.8x", rest[i]);
|
||||
fprintf(output, "\n");
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
printTCINDXCONF(FILE * output, const Uint32 * theData, Uint32 len, Uint16 receiverBlockNo){
|
||||
|
|
|
@ -68,11 +68,8 @@ printTCKEYREQ(FILE * output, const Uint32 * theData, Uint32 len, Uint16 receiver
|
|||
if(sig->getInterpretedFlag(requestInfo)){
|
||||
fprintf(output, "Interpreted ");
|
||||
}
|
||||
if(sig->getDistributionGroupFlag(requestInfo)){
|
||||
fprintf(output, "DGroup = %d ", sig->distrGroupHashValue);
|
||||
}
|
||||
if(sig->getDistributionKeyFlag(sig->requestInfo)){
|
||||
fprintf(output, "DKey = %d ", sig->distributionKeySize);
|
||||
fprintf(output, " d-key");
|
||||
}
|
||||
fprintf(output, "\n");
|
||||
}
|
||||
|
|
|
@ -75,7 +75,7 @@ void byteReverse(unsigned char *buf, unsigned longs)
|
|||
* reflect the addition of 16 longwords of new data. MD5Update blocks
|
||||
* the data and converts bytes into longwords for this routine.
|
||||
*/
|
||||
void MD5Transform(Uint32 buf[4], Uint32 const in[16])
|
||||
static void MD5Transform(Uint32 buf[4], Uint32 const in[16])
|
||||
{
|
||||
register Uint32 a, b, c, d;
|
||||
|
||||
|
@ -162,13 +162,13 @@ void MD5Transform(Uint32 buf[4], Uint32 const in[16])
|
|||
* Start MD5 accumulation. Set bit count to 0 and buffer to mysterious
|
||||
* initialization constants.
|
||||
*/
|
||||
Uint32 md5_hash(const Uint64* keybuf, Uint32 no_of_32_words)
|
||||
void md5_hash(Uint32 result[4], const Uint64* keybuf, Uint32 no_of_32_words)
|
||||
{
|
||||
/*
|
||||
* This is the external interface of the module
|
||||
* It is assumed that keybuf is placed on 8 byte
|
||||
* alignment.
|
||||
*/
|
||||
/**
|
||||
* This is the external interface of the module
|
||||
* It is assumed that keybuf is placed on 8 byte
|
||||
* alignment.
|
||||
*/
|
||||
Uint32 i;
|
||||
Uint32 buf[4];
|
||||
Uint64 transform64_buf[8];
|
||||
|
@ -230,6 +230,10 @@ Uint32 md5_hash(const Uint64* keybuf, Uint32 no_of_32_words)
|
|||
byteReverse((unsigned char *)transform32_buf, 16);
|
||||
MD5Transform(buf, transform32_buf);
|
||||
}
|
||||
return buf[0];
|
||||
|
||||
result[0] = buf[0];
|
||||
result[1] = buf[1];
|
||||
result[2] = buf[2];
|
||||
result[3] = buf[3];
|
||||
}
|
||||
|
||||
|
|
|
@ -22,6 +22,9 @@
|
|||
#include <pc.hpp>
|
||||
#include <SimulatedBlock.hpp>
|
||||
|
||||
// primary key is stored in TUP
|
||||
#include <Dbtup.hpp>
|
||||
|
||||
#ifdef DBACC_C
|
||||
// Debug Macros
|
||||
#define dbgWord32(ptr, ind, val)
|
||||
|
@ -661,9 +664,10 @@ struct Fragmentrec {
|
|||
//-----------------------------------------------------------------------------
|
||||
// elementLength: Length of element in bucket and overflow pages
|
||||
// keyLength: Length of key (== 0 if long key or variable key length)
|
||||
// wl-2066 always Length of key
|
||||
//-----------------------------------------------------------------------------
|
||||
Uint8 elementLength;
|
||||
Uint8 keyLength;
|
||||
Uint16 keyLength;
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// This flag is used to avoid sending a big number of expand or shrink signals
|
||||
|
@ -783,7 +787,7 @@ struct Operationrec {
|
|||
Uint8 dirtyRead;
|
||||
Uint8 commitDeleteCheckFlag;
|
||||
Uint8 isAccLockReq;
|
||||
Uint32 nextOpList;
|
||||
Uint8 isUndoLogReq;
|
||||
}; /* p2c: size = 168 bytes */
|
||||
|
||||
typedef Ptr<Operationrec> OperationrecPtr;
|
||||
|
@ -914,6 +918,9 @@ public:
|
|||
Dbacc(const class Configuration &);
|
||||
virtual ~Dbacc();
|
||||
|
||||
// pointer to TUP instance in this thread
|
||||
Dbtup* c_tup;
|
||||
|
||||
private:
|
||||
BLOCK_DEFINES(Dbacc);
|
||||
|
||||
|
@ -977,10 +984,8 @@ private:
|
|||
void initFragGeneral(FragmentrecPtr);
|
||||
void verifyFragCorrect(FragmentrecPtr regFragPtr);
|
||||
void sendFSREMOVEREQ(Signal* signal, Uint32 tableId);
|
||||
void sendDROP_TABFILECONF(Signal* signal, TabrecPtr tabPtr);
|
||||
void releaseFragResources(Signal* signal, Uint32 fragIndex);
|
||||
void releaseRootFragRecord(Signal* signal, RootfragmentrecPtr rootPtr);
|
||||
void sendREL_TABMEMCONF(Signal* signal, TabrecPtr tabPtr);
|
||||
void releaseRootFragResources(Signal* signal, Uint32 tableId);
|
||||
void releaseDirResources(Signal* signal,
|
||||
Uint32 fragIndex,
|
||||
|
@ -1075,6 +1080,7 @@ private:
|
|||
void storeLongKeys(Signal* signal);
|
||||
void storeLongKeysAtPos(Signal* signal);
|
||||
void reorgLongPage(Signal* signal);
|
||||
void readTablePk(Uint32 localkey1);
|
||||
void getElement(Signal* signal);
|
||||
void searchLongKey(Signal* signal);
|
||||
void getdirindex(Signal* signal);
|
||||
|
@ -1108,7 +1114,6 @@ private:
|
|||
void initLcpConnRec(Signal* signal);
|
||||
void initOverpage(Signal* signal);
|
||||
void initPage(Signal* signal);
|
||||
void initPageZero(Signal* signal);
|
||||
void initRootfragrec(Signal* signal);
|
||||
void putOpInFragWaitQue(Signal* signal);
|
||||
void putOverflowRecInFrag(Signal* signal);
|
||||
|
@ -1162,8 +1167,6 @@ private:
|
|||
void refaccConnectLab(Signal* signal);
|
||||
void srReadOverPagesLab(Signal* signal);
|
||||
void releaseScanLab(Signal* signal);
|
||||
void exeoperationLab(Signal* signal);
|
||||
void saveKeyDataLab(Signal* signal);
|
||||
void lcpOpenUndofileConfLab(Signal* signal);
|
||||
void srFsOpenConfLab(Signal* signal);
|
||||
void checkSyncUndoPagesLab(Signal* signal);
|
||||
|
@ -1175,13 +1178,12 @@ private:
|
|||
void srReadPagesLab(Signal* signal);
|
||||
void srDoUndoLab(Signal* signal);
|
||||
void ndbrestart1Lab(Signal* signal);
|
||||
void initialiseRecordsLab(Signal* signal, Uint32 returnRef, Uint32 retData);
|
||||
void initialiseRecordsLab(Signal* signal, Uint32 ref, Uint32 data);
|
||||
void srReadPagesAllocLab(Signal* signal);
|
||||
void checkNextBucketLab(Signal* signal);
|
||||
void endsavepageLab(Signal* signal);
|
||||
void saveZeroPageLab(Signal* signal);
|
||||
void srAllocPage0011Lab(Signal* signal);
|
||||
void allocscanrecLab(Signal* signal);
|
||||
void sendLcpFragidconfLab(Signal* signal);
|
||||
void savepagesLab(Signal* signal);
|
||||
void saveOverPagesLab(Signal* signal);
|
||||
|
@ -1303,7 +1305,6 @@ private:
|
|||
Page8Ptr iloPageptr;
|
||||
Page8Ptr inpPageptr;
|
||||
Page8Ptr iopPageptr;
|
||||
Page8Ptr ipzPageptr;
|
||||
Page8Ptr lastPageptr;
|
||||
Page8Ptr lastPrevpageptr;
|
||||
Page8Ptr lcnPageptr;
|
||||
|
@ -1333,7 +1334,6 @@ private:
|
|||
Page8Ptr ropPageptr;
|
||||
Page8Ptr rpPageptr;
|
||||
Page8Ptr slPageptr;
|
||||
Page8Ptr slpPageptr;
|
||||
Page8Ptr spPageptr;
|
||||
Uint32 cfirstfreepage;
|
||||
Uint32 cfreepage;
|
||||
|
@ -1351,7 +1351,6 @@ private:
|
|||
/* --------------------------------------------------------------------------------- */
|
||||
Rootfragmentrec *rootfragmentrec;
|
||||
RootfragmentrecPtr rootfragrecptr;
|
||||
RootfragmentrecPtr tmprootfrgptr;
|
||||
Uint32 crootfragmentsize;
|
||||
Uint32 cfirstfreerootfrag;
|
||||
/* --------------------------------------------------------------------------------- */
|
||||
|
@ -1424,7 +1423,6 @@ private:
|
|||
Uint32 tdelForward;
|
||||
Uint32 tiopPageId;
|
||||
Uint32 tipPageId;
|
||||
Uint32 ttupKeyLength;
|
||||
Uint32 tgeLocked;
|
||||
Uint32 tgeResult;
|
||||
Uint32 tgeContainerptr;
|
||||
|
@ -1457,7 +1455,6 @@ private:
|
|||
Uint32 tscanFlag;
|
||||
Uint32 theadundoindex;
|
||||
Uint32 tgflBufType;
|
||||
Uint32 thashvalue;
|
||||
Uint32 tgseIsforward;
|
||||
Uint32 tsscIsforward;
|
||||
Uint32 trscIsforward;
|
||||
|
@ -1466,17 +1463,7 @@ private:
|
|||
Uint32 tisoIsforward;
|
||||
Uint32 tgseIsLocked;
|
||||
Uint32 tsscIsLocked;
|
||||
Uint32 tkey1;
|
||||
Uint32 tkey2;
|
||||
Uint32 tkey3;
|
||||
Uint32 tkey4;
|
||||
Uint32 tkeylen;
|
||||
Uint32 tkSize;
|
||||
Uint32 tlhfragbits;
|
||||
Uint32 tlhdirbits;
|
||||
Uint32 tlocalkeylen;
|
||||
Uint32 tmaxloadfactor;
|
||||
Uint32 tminloadfactor;
|
||||
Uint32 tmp;
|
||||
Uint32 tmpP;
|
||||
Uint32 tmpP2;
|
||||
|
@ -1494,9 +1481,6 @@ private:
|
|||
Uint32 trsbPageindex;
|
||||
Uint32 tnciPageindex;
|
||||
Uint32 tlastPrevconptr;
|
||||
Uint32 treqinfo;
|
||||
Uint32 transactionid1;
|
||||
Uint32 transactionid2;
|
||||
Uint32 tresult;
|
||||
Uint32 tslUpdateHeader;
|
||||
Uint32 tuserptr;
|
||||
|
@ -1509,16 +1493,13 @@ private:
|
|||
Uint32 tgdiPageindex;
|
||||
Uint32 tiopIndex;
|
||||
Uint32 tnciTmp;
|
||||
Uint32 tlenKeyinfo;
|
||||
Uint32 tullIndex;
|
||||
Uint32 turlIndex;
|
||||
Uint32 tlfrTmp1;
|
||||
Uint32 tlfrTmp2;
|
||||
Uint32 tgnptNrTransaction;
|
||||
Uint32 tudqeIndex;
|
||||
Uint32 tscanTrid1;
|
||||
Uint32 tscanTrid2;
|
||||
Uint32 taccscanTmp;
|
||||
|
||||
Uint16 clastUndoPageIdWritten;
|
||||
Uint32 cactiveCheckpId;
|
||||
|
@ -1562,7 +1543,10 @@ private:
|
|||
Uint32 cexcPrevpageindex;
|
||||
Uint32 cexcPrevforward;
|
||||
Uint32 clocalkey[32];
|
||||
union {
|
||||
Uint32 ckeys[2048];
|
||||
Uint64 ckeys_align;
|
||||
};
|
||||
|
||||
Uint32 c_errorInsert3000_TableId;
|
||||
Uint32 cSrUndoRecords[5];
|
||||
|
|
|
@ -133,7 +133,8 @@ void Dbacc::initRecords()
|
|||
}//Dbacc::initRecords()
|
||||
|
||||
Dbacc::Dbacc(const class Configuration & conf):
|
||||
SimulatedBlock(DBACC, conf)
|
||||
SimulatedBlock(DBACC, conf),
|
||||
c_tup(0)
|
||||
{
|
||||
Uint32 log_page_size= 0;
|
||||
BLOCK_CONSTRUCTOR(Dbacc);
|
||||
|
|
|
@ -570,7 +570,14 @@ void Dbacc::execNDB_STTOR(Signal* signal)
|
|||
void Dbacc::execSTTOR(Signal* signal)
|
||||
{
|
||||
jamEntry();
|
||||
// tstartphase = signal->theData[1];
|
||||
Uint32 tstartphase = signal->theData[1];
|
||||
switch (tstartphase) {
|
||||
case 1:
|
||||
jam();
|
||||
c_tup = (Dbtup*)globalData.getBlock(DBTUP);
|
||||
ndbrequire(c_tup != 0);
|
||||
break;
|
||||
}
|
||||
tuserblockref = signal->theData[3];
|
||||
csignalkey = signal->theData[6];
|
||||
sttorrysignalLab(signal);
|
||||
|
@ -1567,6 +1574,9 @@ void Dbacc::initOpRec(Signal* signal)
|
|||
|
||||
// bit to mark lock operation
|
||||
operationRecPtr.p->isAccLockReq = (Treqinfo >> 31) & 0x1;
|
||||
|
||||
// undo log is not run via ACCKEYREQ
|
||||
operationRecPtr.p->isUndoLogReq = 0;
|
||||
}//Dbacc::initOpRec()
|
||||
|
||||
/* --------------------------------------------------------------------------------- */
|
||||
|
@ -1807,7 +1817,7 @@ void Dbacc::insertExistElemLab(Signal* signal)
|
|||
/* --------------------------------------------------------------------------------- */
|
||||
void Dbacc::insertelementLab(Signal* signal)
|
||||
{
|
||||
Uint32 tinsKeyLen;
|
||||
Uint32 tinsKeyLen; // wl-2066 remove
|
||||
|
||||
if (fragrecptr.p->createLcp == ZTRUE) {
|
||||
if (remainingUndoPages() < ZMIN_UNDO_PAGES_AT_OPERATION) {
|
||||
|
@ -1828,14 +1838,17 @@ void Dbacc::insertelementLab(Signal* signal)
|
|||
if (fragrecptr.p->keyLength != operationRecPtr.p->tupkeylen) {
|
||||
ndbrequire(fragrecptr.p->keyLength == 0);
|
||||
}//if
|
||||
if (fragrecptr.p->keyLength != 0) {
|
||||
if (true)
|
||||
tinsKeyLen = 0;
|
||||
else if (fragrecptr.p->keyLength != 0) { // wl-2066 remove
|
||||
ndbrequire(operationRecPtr.p->tupkeylen <= 8);
|
||||
for (Uint32 i = 0; i < operationRecPtr.p->tupkeylen; i++) {
|
||||
jam();
|
||||
ckeys[i] = signal->theData[i + 7];
|
||||
}//for
|
||||
tinsKeyLen = operationRecPtr.p->tupkeylen;
|
||||
} else {
|
||||
tinsKeyLen = 0;
|
||||
} else { // wl-2066 remove
|
||||
jam();
|
||||
seizePage(signal);
|
||||
if (tresult > ZLIMIT_OF_ERROR) {
|
||||
|
@ -2484,6 +2497,7 @@ void Dbacc::execACC_LOCKREQ(Signal* signal)
|
|||
signal->theData[4] = 1; // fake primKeyLen
|
||||
signal->theData[5] = req->transId1;
|
||||
signal->theData[6] = req->transId2;
|
||||
// enter local key in place of PK
|
||||
signal->theData[7] = req->tupAddr;
|
||||
EXECUTE_DIRECT(DBACC, GSN_ACCKEYREQ, signal, 8);
|
||||
// translate the result
|
||||
|
@ -2861,6 +2875,8 @@ void Dbacc::insertContainer(Signal* signal)
|
|||
idrPageptr.p->word32[tidrIndex] = clocalkey[tidrInputIndex]; /* INSERTS LOCALKEY */
|
||||
tidrIndex += tidrForward;
|
||||
}//for
|
||||
ndbrequire(tidrKeyLen == 0);
|
||||
#if 0 // wl-2066 remove
|
||||
guard26 = tidrKeyLen - 1;
|
||||
arrGuard(guard26, 8);
|
||||
for (tidrInputIndex = 0; tidrInputIndex <= guard26; tidrInputIndex++) {
|
||||
|
@ -2869,6 +2885,7 @@ void Dbacc::insertContainer(Signal* signal)
|
|||
idrPageptr.p->word32[tidrIndex] = ckeys[tidrInputIndex]; /* INSERTS TUPLE KEY */
|
||||
tidrIndex += tidrForward;
|
||||
}//for
|
||||
#endif
|
||||
tidrContLen = idrPageptr.p->word32[tidrContainerptr] << 6;
|
||||
tidrContLen = tidrContLen >> 6;
|
||||
dbgWord32(idrPageptr, tidrContainerptr, (tidrContainerlen << 26) | tidrContLen);
|
||||
|
@ -4423,7 +4440,7 @@ void Dbacc::printoutInfoAndShutdown(LongKeyPage *page) {
|
|||
/* --------------------------------------------------------------------------------- */
|
||||
/* --------------------------------------------------------------------------------- */
|
||||
/* */
|
||||
/* MODULE: READ */
|
||||
/* MODULE: GET_ELEMENT */
|
||||
/* THE FOLLOWING SUBROUTINES ARE ONLY USED BY GET_ELEMENT AND */
|
||||
/* GETDIRINDEX. THIS ROUTINE IS THE SOLE INTERFACE TO GET ELEMENTS */
|
||||
/* FROM THE INDEX. CURRENT USERS ARE ALL REQUESTS AND EXECUTE UNDO LOG */
|
||||
|
@ -4484,6 +4501,20 @@ void Dbacc::getdirindex(Signal* signal)
|
|||
ptrCheckGuard(gdiPageptr, cpagesize, page8);
|
||||
}//Dbacc::getdirindex()
|
||||
|
||||
void
|
||||
Dbacc::readTablePk(Uint32 localkey1)
|
||||
{
|
||||
Uint32 tableId = fragrecptr.p->myTableId;
|
||||
Uint32 fragId = fragrecptr.p->myfid;
|
||||
Uint32 fragPageId = localkey1 >> MAX_TUPLES_BITS;
|
||||
Uint32 pageIndex = localkey1 & ((1 << MAX_TUPLES_BITS ) - 1);
|
||||
#ifdef VM_TRACE
|
||||
memset(ckeys, 0x1f, fragrecptr.p->keyLength << 2);
|
||||
#endif
|
||||
int ret = c_tup->accReadPk(tableId, fragId, fragPageId, pageIndex, ckeys);
|
||||
ndbrequire(ret == fragrecptr.p->keyLength);
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------------------- */
|
||||
/* GET_ELEMENT */
|
||||
/* INPUT: */
|
||||
|
@ -4534,19 +4565,16 @@ void Dbacc::getElement(Signal* signal)
|
|||
gePageptr = gdiPageptr;
|
||||
tgeResult = ZFALSE;
|
||||
tgeCompareLen = fragrecptr.p->keyLength;
|
||||
const Uint32 isAccLockReq = operationRecPtr.p->isAccLockReq;
|
||||
if (isAccLockReq) {
|
||||
jam();
|
||||
tgeCompareLen = 0;
|
||||
}
|
||||
const Uint32 isAccLockReq = operationRecPtr.p->isAccLockReq; // wl-2066 remove
|
||||
/*
|
||||
* The value seached is
|
||||
* - table key for ACCKEYREQ, stored in TUP
|
||||
* - local key (1 word) for ACC_LOCKREQ and UNDO, stored in ACC
|
||||
*/
|
||||
const bool compareLocalKey =
|
||||
operationRecPtr.p->isAccLockReq || operationRecPtr.p->isUndoLogReq;
|
||||
|
||||
// We can handle keylength up to 8, but not more (0 means dynamic)
|
||||
if (tgeCompareLen >= 9) {
|
||||
ACCKEY_error(2); return;
|
||||
}//if
|
||||
if (TelemLen < 3) {
|
||||
ACCKEY_error(3); return;
|
||||
}//if
|
||||
ndbrequire(TelemLen == ZELEM_HEAD_SIZE + fragrecptr.p->localkeylen);
|
||||
tgeNextptrtype = ZLEFT;
|
||||
tgeLocked = 0;
|
||||
|
||||
|
@ -4577,7 +4605,7 @@ void Dbacc::getElement(Signal* signal)
|
|||
} else {
|
||||
ACCKEY_error(6); return;
|
||||
}//if
|
||||
if (tgeRemLen >= TelemLen) {
|
||||
if (tgeRemLen >= ZCON_HEAD_SIZE + TelemLen) {
|
||||
if (tgeRemLen > ZBUF_SIZE) {
|
||||
ACCKEY_error(7); return;
|
||||
}//if
|
||||
|
@ -4585,7 +4613,45 @@ void Dbacc::getElement(Signal* signal)
|
|||
// There is at least one element in this container. Check if it is the element
|
||||
// searched for.
|
||||
/* --------------------------------------------------------------------------------- */
|
||||
if (tgeCompareLen != 0) {
|
||||
if (true) {
|
||||
do {
|
||||
tgeElementHeader = gePageptr.p->word32[tgeElementptr];
|
||||
tgeRemLen = tgeRemLen - TelemLen;
|
||||
Uint32 hashValuePart;
|
||||
if (ElementHeader::getLocked(tgeElementHeader)) {
|
||||
jam();
|
||||
geTmpOperationRecPtr.i = ElementHeader::getOpPtrI(tgeElementHeader);
|
||||
ptrCheckGuard(geTmpOperationRecPtr, coprecsize, operationrec);
|
||||
hashValuePart = geTmpOperationRecPtr.p->hashvaluePart;
|
||||
} else {
|
||||
jam();
|
||||
hashValuePart = ElementHeader::getHashValuePart(tgeElementHeader);
|
||||
}
|
||||
if (hashValuePart == opHashValuePart) {
|
||||
jam();
|
||||
Uint32 localkey1 = gePageptr.p->word32[tgeElementptr + tgeForward];
|
||||
Uint32 localkey2 = 0;
|
||||
bool found;
|
||||
if (! compareLocalKey) {
|
||||
readTablePk(localkey1);
|
||||
found = (memcmp(Tkeydata, ckeys, fragrecptr.p->keyLength << 2) == 0);
|
||||
} else {
|
||||
found = (localkey1 == Tkeydata[0]);
|
||||
}
|
||||
if (found) {
|
||||
tgeLocked = ElementHeader::getLocked(tgeElementHeader);
|
||||
tgeResult = ZTRUE;
|
||||
operationRecPtr.p->localdata[0] = localkey1;
|
||||
operationRecPtr.p->localdata[1] = localkey2;
|
||||
return;
|
||||
}
|
||||
}
|
||||
if (tgeRemLen <= ZCON_HEAD_SIZE) {
|
||||
break;
|
||||
}
|
||||
tgeElementptr = tgeElementptr + tgeElemStep;
|
||||
} while (true);
|
||||
} else if (tgeCompareLen != 0) { // wl-2066 remove
|
||||
/* --------------------------------------------------------------------------------- */
|
||||
/* THIS PART IS USED TO SEARCH FOR KEYS WITH FIXED SIZE. THE LOOP TAKES CARE */
|
||||
/* OF SEARCHING THROUGH ALL ELEMENTS IN ONE CONTAINER. */
|
||||
|
@ -4629,7 +4695,7 @@ void Dbacc::getElement(Signal* signal)
|
|||
tgeKeyptr = tgeKeyptr + tgeElemStep;
|
||||
tgeElementptr = tgeElementptr + tgeElemStep;
|
||||
} while (1);
|
||||
} else if (! isAccLockReq) {
|
||||
} else if (! isAccLockReq) { // wl-2066 remove
|
||||
jam();
|
||||
/* --------------------------------------------------------------------------------- */
|
||||
/* THIS PART IS USED TO SEARCH FOR KEYS WITH VARIABLE LENGTH OR FIXED LENGTH */
|
||||
|
@ -4696,7 +4762,7 @@ void Dbacc::getElement(Signal* signal)
|
|||
tgeKeyptr = tgeKeyptr + tgeElemStep;
|
||||
tgeElementptr = tgeElementptr + tgeElemStep;
|
||||
} while (1);
|
||||
} else {
|
||||
} else { // wl-2066 remove
|
||||
jam();
|
||||
/* --------------------------------------------------------------------------------- */
|
||||
/* Search for local key in a lock request */
|
||||
|
@ -4855,7 +4921,7 @@ void Dbacc::commitdelete(Signal* signal, bool systemRestart)
|
|||
EXECUTE_DIRECT(DBTUP, GSN_TUP_DEALLOCREQ, signal, 4);
|
||||
jamEntry();
|
||||
}//if
|
||||
if (fragrecptr.p->keyLength == 0) {
|
||||
if (fragrecptr.p->keyLength == 0) { // wl-2066 remove
|
||||
jam();
|
||||
tdlkLogicalPageIndex = operationRecPtr.p->longKeyPageIndex;
|
||||
dlkPageptr.i = operationRecPtr.p->longPagePtr;
|
||||
|
@ -6607,14 +6673,17 @@ void Dbacc::expandcontainer(Signal* signal)
|
|||
Uint32 texcHashvalue;
|
||||
Uint32 texcTmp;
|
||||
Uint32 texcIndex;
|
||||
Uint32 texpKeyLen;
|
||||
Uint32 texpKeyLen; // wl-2066 remove
|
||||
Uint32 guard20;
|
||||
|
||||
texpKeyLen = 0;
|
||||
#if 0 // wl-2066 remove
|
||||
texpKeyLen = fragrecptr.p->keyLength;
|
||||
if (texpKeyLen == 0) {
|
||||
jam();
|
||||
texpKeyLen = ZACTIVE_LONG_KEY_LEN;
|
||||
}//if
|
||||
#endif
|
||||
cexcPrevpageptr = RNIL;
|
||||
cexcPrevconptr = 0;
|
||||
cexcForward = ZTRUE;
|
||||
|
@ -6701,6 +6770,7 @@ void Dbacc::expandcontainer(Signal* signal)
|
|||
clocalkey[texcIndex] = excPageptr.p->word32[texcTmp];
|
||||
texcTmp = texcTmp + cexcForward;
|
||||
}//for
|
||||
#if 0 // wl-2066 remove
|
||||
guard20 = texpKeyLen - 1;
|
||||
for (texcIndex = 0; texcIndex <= guard20; texcIndex++) {
|
||||
arrGuard(texcIndex, 2048);
|
||||
|
@ -6708,6 +6778,7 @@ void Dbacc::expandcontainer(Signal* signal)
|
|||
ckeys[texcIndex] = excPageptr.p->word32[texcTmp];
|
||||
texcTmp = texcTmp + cexcForward;
|
||||
}//for
|
||||
#endif
|
||||
tidrPageindex = fragrecptr.p->expReceiveIndex;
|
||||
idrPageptr.i = fragrecptr.p->expReceivePageptr;
|
||||
ptrCheckGuard(idrPageptr, cpagesize, page8);
|
||||
|
@ -6794,12 +6865,14 @@ void Dbacc::expandcontainer(Signal* signal)
|
|||
clocalkey[texcIndex] = lastPageptr.p->word32[texcTmp];
|
||||
texcTmp = texcTmp + tlastForward;
|
||||
}//for
|
||||
#if 0 // wl-2066 remove
|
||||
for (texcIndex = 0; texcIndex < texpKeyLen; texcIndex++) {
|
||||
arrGuard(texcIndex, 2048);
|
||||
arrGuard(texcTmp, 2048);
|
||||
ckeys[texcIndex] = lastPageptr.p->word32[texcTmp];
|
||||
texcTmp = texcTmp + tlastForward;
|
||||
}//for
|
||||
#endif
|
||||
tidrPageindex = fragrecptr.p->expReceiveIndex;
|
||||
idrPageptr.i = fragrecptr.p->expReceivePageptr;
|
||||
ptrCheckGuard(idrPageptr, cpagesize, page8);
|
||||
|
@ -7285,17 +7358,19 @@ void Dbacc::shrinkcontainer(Signal* signal)
|
|||
Uint32 tshrElementptr;
|
||||
Uint32 tshrRemLen;
|
||||
Uint32 tshrInc;
|
||||
Uint32 tshrKeyLen;
|
||||
Uint32 tshrKeyLen = 0; // wl-2066 remove
|
||||
Uint32 tshrTmp;
|
||||
Uint32 tshrIndex;
|
||||
Uint32 guard21;
|
||||
|
||||
tshrRemLen = cexcContainerlen - ZCON_HEAD_SIZE;
|
||||
#if 0 // wl-2066 remove
|
||||
tshrKeyLen = fragrecptr.p->keyLength;
|
||||
if (tshrKeyLen == 0) {
|
||||
jam();
|
||||
tshrKeyLen = ZACTIVE_LONG_KEY_LEN;
|
||||
}//if
|
||||
#endif
|
||||
tshrInc = (ZELEM_HEAD_SIZE + tshrKeyLen) + fragrecptr.p->localkeylen;
|
||||
if (cexcForward == ZTRUE) {
|
||||
jam();
|
||||
|
@ -7345,6 +7420,7 @@ void Dbacc::shrinkcontainer(Signal* signal)
|
|||
clocalkey[tshrIndex] = excPageptr.p->word32[tshrTmp];
|
||||
tshrTmp = tshrTmp + cexcForward;
|
||||
}//for
|
||||
#if 0 // wl-2066 remove
|
||||
guard21 = tshrKeyLen - 1;
|
||||
for (tshrIndex = 0; tshrIndex <= guard21; tshrIndex++) {
|
||||
arrGuard(tshrIndex, 2048);
|
||||
|
@ -7352,6 +7428,7 @@ void Dbacc::shrinkcontainer(Signal* signal)
|
|||
ckeys[tshrIndex] = excPageptr.p->word32[tshrTmp];
|
||||
tshrTmp = tshrTmp + cexcForward;
|
||||
}//for
|
||||
#endif
|
||||
tidrPageindex = fragrecptr.p->expReceiveIndex;
|
||||
idrPageptr.i = fragrecptr.p->expReceivePageptr;
|
||||
ptrCheckGuard(idrPageptr, cpagesize, page8);
|
||||
|
@ -9012,8 +9089,9 @@ void Dbacc::writeUndoHeader(Signal* signal,
|
|||
(UndoHeader *) &undopageptr.p->undoword[theadundoindex];
|
||||
|
||||
undoHeaderPtr->tableId = rootfragrecptr.p->mytabptr;
|
||||
undoHeaderPtr->rootFragId = rootfragrecptr.p->fragmentid[0];
|
||||
undoHeaderPtr->rootFragId = rootfragrecptr.p->fragmentid[0] >> 1;
|
||||
undoHeaderPtr->localFragId = fragrecptr.p->myfid;
|
||||
ndbrequire((undoHeaderPtr->localFragId >> 1) == undoHeaderPtr->rootFragId);
|
||||
Uint32 Ttmp = cundoinfolength;
|
||||
Ttmp = (Ttmp << 4) + pageType;
|
||||
Ttmp = Ttmp << 14;
|
||||
|
@ -9043,15 +9121,27 @@ void Dbacc::writeUndoOpInfo(Signal* signal)
|
|||
undopageptr.p->undoword[tundoindex + 1] = operationRecPtr.p->hashValue;
|
||||
undopageptr.p->undoword[tundoindex + 2] = operationRecPtr.p->tupkeylen;
|
||||
tundoindex = tundoindex + 3;
|
||||
if (fragrecptr.p->keyLength != 0) {
|
||||
if (true) {
|
||||
// log localkey1
|
||||
jam();
|
||||
locPageptr.i = operationRecPtr.p->elementPage;
|
||||
ptrCheckGuard(locPageptr, cpagesize, page8);
|
||||
Uint32 Tforward = operationRecPtr.p->elementIsforward;
|
||||
Uint32 TelemPtr = operationRecPtr.p->elementPointer;
|
||||
TelemPtr += Tforward; // ZELEM_HEAD_SIZE
|
||||
arrGuard(tundoindex+1, 8192);
|
||||
undopageptr.p->undoword[tundoindex] = locPageptr.p->word32[TelemPtr];
|
||||
tundoindex++;
|
||||
cundoinfolength = ZOP_HEAD_INFO_LN + 1;
|
||||
} else if (fragrecptr.p->keyLength != 0) { // wl-2066 remove
|
||||
// Fixed size keys
|
||||
jam();
|
||||
locPageptr.i = operationRecPtr.p->elementPage;
|
||||
ptrCheckGuard(locPageptr, cpagesize, page8);
|
||||
Uint32 Tforward = operationRecPtr.p->elementIsforward;
|
||||
Uint32 TelemPtr = operationRecPtr.p->elementPointer;
|
||||
TelemPtr += Tforward;
|
||||
TelemPtr += Tforward;
|
||||
TelemPtr += Tforward; // ZELEM_HEAD_SIZE
|
||||
TelemPtr += Tforward; // localkey1
|
||||
//---------------------------------------------------------------------------------
|
||||
// Now the pointer is at the start of the key part of the element. Now copy from there
|
||||
// to the UNDO log.
|
||||
|
@ -9067,7 +9157,7 @@ void Dbacc::writeUndoOpInfo(Signal* signal)
|
|||
TelemPtr += Tforward;
|
||||
}//for
|
||||
cundoinfolength = ZOP_HEAD_INFO_LN + operationRecPtr.p->tupkeylen;
|
||||
} else {
|
||||
} else { // wl-2066 remove
|
||||
// Long keys
|
||||
jam();
|
||||
|
||||
|
@ -9272,7 +9362,7 @@ void Dbacc::initFragAdd(Signal* signal,
|
|||
}//if
|
||||
regFragPtr.p->fragState = ACTIVEFRAG;
|
||||
// NOTE: next line must match calculation in Dblqh::execLQHFRAGREQ
|
||||
regFragPtr.p->myfid = (rootFragIndex << (lhFragBits - 1)) | req->fragId;
|
||||
regFragPtr.p->myfid = (req->fragId << 1) | rootFragIndex;
|
||||
regFragPtr.p->myroot = rootIndex;
|
||||
regFragPtr.p->myTableId = req->tableId;
|
||||
ndbrequire(req->kValue == 6);
|
||||
|
@ -9300,10 +9390,13 @@ void Dbacc::initFragAdd(Signal* signal,
|
|||
regFragPtr.p->dirsize = 1;
|
||||
regFragPtr.p->loadingFlag = ZFALSE;
|
||||
regFragPtr.p->keyLength = req->keyLength;
|
||||
if (req->keyLength == 0) {
|
||||
ndbrequire(req->keyLength != 0);
|
||||
if (true) {
|
||||
regFragPtr.p->elementLength = ZELEM_HEAD_SIZE + regFragPtr.p->localkeylen;
|
||||
} else if (req->keyLength == 0) { // wl-2066 remove
|
||||
jam();
|
||||
regFragPtr.p->elementLength = (1 + ZELEM_HEAD_SIZE) + regFragPtr.p->localkeylen;
|
||||
} else {
|
||||
} else { // wl-2066 remove
|
||||
jam();
|
||||
regFragPtr.p->elementLength = (ZELEM_HEAD_SIZE + regFragPtr.p->localkeylen) + regFragPtr.p->keyLength;
|
||||
}//if
|
||||
|
@ -10108,6 +10201,7 @@ void Dbacc::srDoUndoLab(Signal* signal)
|
|||
|
||||
// ROOT FRAGMENT ID
|
||||
tfid = undoHeaderPtr->rootFragId;
|
||||
ndbrequire((undoHeaderPtr->localFragId >> 1) == undoHeaderPtr->rootFragId);
|
||||
if (!getrootfragmentrec(signal, rootfragrecptr, tfid)) {
|
||||
jam();
|
||||
/*---------------------------------------------------------------------*/
|
||||
|
@ -10117,7 +10211,10 @@ void Dbacc::srDoUndoLab(Signal* signal)
|
|||
creadyUndoaddress = cprevUndoaddress;
|
||||
// PREVIOUS UNDO LOG RECORD FOR ALL FRAGMENTS
|
||||
cprevUndoaddress = undoHeaderPtr->prevUndoAddress;
|
||||
undoNext2Lab(signal);
|
||||
undoNext2Lab(signal);
|
||||
#ifdef VM_TRACE
|
||||
ndbout_c("ignoring root fid %d", (int)tfid);
|
||||
#endif
|
||||
return;
|
||||
}//if
|
||||
/*-----------------------------------------------------------------------*/
|
||||
|
@ -10362,6 +10459,7 @@ void Dbacc::srDoUndoLab(Signal* signal)
|
|||
operationRecPtr.p->longKeyPageIndex = RNIL;
|
||||
operationRecPtr.p->scanRecPtr = RNIL;
|
||||
operationRecPtr.p->isAccLockReq = ZFALSE;
|
||||
operationRecPtr.p->isUndoLogReq = ZTRUE;
|
||||
|
||||
// Read operation values from undo page
|
||||
operationRecPtr.p->operation = undopageptr.p->undoword[tmpindex];
|
||||
|
@ -10373,15 +10471,19 @@ void Dbacc::srDoUndoLab(Signal* signal)
|
|||
operationRecPtr.p->tupkeylen = tkeylen;
|
||||
operationRecPtr.p->fragptr = fragrecptr.i;
|
||||
|
||||
ndbrequire((fragrecptr.p->keyLength == 0) ||
|
||||
ndbrequire((fragrecptr.p->keyLength == 0) || // wl-2066 change
|
||||
((fragrecptr.p->keyLength != 0) &&
|
||||
(fragrecptr.p->keyLength == tkeylen)));
|
||||
|
||||
// Read keydata from undo page
|
||||
// Read localkey1 from undo page
|
||||
signal->theData[7 + 0] = undopageptr.p->undoword[tmpindex];
|
||||
tmpindex = tmpindex + 1;
|
||||
#if 0 // wl-2066 remove
|
||||
for (Uint32 tmp = 0; tmp < tkeylen; tmp++) {
|
||||
signal->theData[7+tmp] = undopageptr.p->undoword[tmpindex];
|
||||
tmpindex = tmpindex + 1;
|
||||
}//for
|
||||
#endif
|
||||
arrGuard((tmpindex - 1), 8192);
|
||||
getElement(signal);
|
||||
if (tgeResult != ZTRUE) {
|
||||
|
@ -11456,6 +11558,7 @@ void Dbacc::initScanOpRec(Signal* signal)
|
|||
operationRecPtr.p->elementPointer = tisoElementptr;
|
||||
operationRecPtr.p->elementPage = isoPageptr.i;
|
||||
operationRecPtr.p->isAccLockReq = ZFALSE;
|
||||
operationRecPtr.p->isUndoLogReq = ZFALSE;
|
||||
tisoLocalPtr = tisoElementptr + tisoIsforward;
|
||||
guard24 = fragrecptr.p->localkeylen - 1;
|
||||
for (tisoTmp = 0; tisoTmp <= guard24; tisoTmp++) {
|
||||
|
@ -11466,7 +11569,10 @@ void Dbacc::initScanOpRec(Signal* signal)
|
|||
}//for
|
||||
arrGuard(tisoLocalPtr, 2048);
|
||||
operationRecPtr.p->keydata[0] = isoPageptr.p->word32[tisoLocalPtr];
|
||||
if (fragrecptr.p->keyLength != 0) {
|
||||
if (true) {
|
||||
jam();
|
||||
operationRecPtr.p->tupkeylen = fragrecptr.p->keyLength;
|
||||
} else if (fragrecptr.p->keyLength != 0) { // wl-2066 remove
|
||||
jam();
|
||||
operationRecPtr.p->tupkeylen = fragrecptr.p->keyLength;
|
||||
guard24 = fragrecptr.p->keyLength - 1;
|
||||
|
@ -11476,7 +11582,7 @@ void Dbacc::initScanOpRec(Signal* signal)
|
|||
operationRecPtr.p->keydata[tisoTmp] = isoPageptr.p->word32[tisoLocalPtr];
|
||||
tisoLocalPtr = tisoLocalPtr + tisoIsforward;
|
||||
}//for
|
||||
} else {
|
||||
} else { // wl-2066 remove
|
||||
// Long key handling. Put the long key reference in the operation records.
|
||||
tisoPageIndex = operationRecPtr.p->keydata[0] & 0x3ff;
|
||||
arrGuard(ZWORDS_IN_PAGE - tisoPageIndex, 2048);
|
||||
|
@ -11694,18 +11800,20 @@ void Dbacc::releaseScanContainer(Signal* signal)
|
|||
Uint32 trscElemlens;
|
||||
Uint32 trscElemlen;
|
||||
|
||||
if (trscContainerlen < 5) {
|
||||
if (trscContainerlen < 4) { // wl-2066 do it like in getElement
|
||||
if (trscContainerlen != ZCON_HEAD_SIZE) {
|
||||
jam();
|
||||
sendSystemerror(signal);
|
||||
}//if
|
||||
return; /* 3 IS THE MINIMUM SIZE OF THE ELEMENT */
|
||||
return; /* 2 IS THE MINIMUM SIZE OF THE ELEMENT */
|
||||
}//if
|
||||
trscElemlens = trscContainerlen - 2;
|
||||
if (fragrecptr.p->keyLength != 0) {
|
||||
trscElemlens = trscContainerlen - 2; // wl-2066 use ZCON_HEAD_SIZE
|
||||
if (true) { // wl-2066 use fragrecptr.p->elementLength
|
||||
trscElemlen = (1 + 0) + fragrecptr.p->localkeylen;
|
||||
} else if (fragrecptr.p->keyLength != 0) { // wl-2066 remove
|
||||
jam();
|
||||
trscElemlen = (1 + fragrecptr.p->keyLength) + fragrecptr.p->localkeylen; /* LENGTH OF THE ELEMENT */
|
||||
} else {
|
||||
} else { // wl-2066 remove
|
||||
jam();
|
||||
trscElemlen = (1 + ZACTIVE_LONG_KEY_LEN) + fragrecptr.p->localkeylen; /* LENGTH OF THE ELEMENT */
|
||||
}//if
|
||||
|
@ -11735,7 +11843,7 @@ void Dbacc::releaseScanContainer(Signal* signal)
|
|||
}//if
|
||||
trscElemlens = trscElemlens - trscElemlen;
|
||||
trscElementptr = trscElementptr + trscElemStep;
|
||||
} while (trscElemlens > 2);
|
||||
} while (trscElemlens > 1);
|
||||
if (trscElemlens != 0) {
|
||||
jam();
|
||||
sendSystemerror(signal);
|
||||
|
@ -11794,15 +11902,17 @@ bool Dbacc::searchScanContainer(Signal* signal)
|
|||
Uint32 tsscElemlen;
|
||||
Uint32 tsscElemStep;
|
||||
|
||||
if (tsscContainerlen < 5) {
|
||||
if (tsscContainerlen < 4) { // wl-2066 check exact size
|
||||
jam();
|
||||
return false; /* 3 IS THE MINIMUM SIZE OF THE ELEMENT */
|
||||
return false; /* 2 IS THE MINIMUM SIZE OF THE ELEMENT */
|
||||
}//if
|
||||
tsscElemlens = tsscContainerlen - ZCON_HEAD_SIZE;
|
||||
if (fragrecptr.p->keyLength == 0) {
|
||||
if (true) { // wl-2066 use fragrecptr.p->elementLength
|
||||
tsscElemlen = (ZELEM_HEAD_SIZE + 0) + fragrecptr.p->localkeylen;
|
||||
} else if (fragrecptr.p->keyLength == 0) { // wl-2066 remove
|
||||
jam();
|
||||
tsscElemlen = (ZELEM_HEAD_SIZE + ZACTIVE_LONG_KEY_LEN) + fragrecptr.p->localkeylen;
|
||||
} else {
|
||||
} else { // wl-2066 remove
|
||||
jam();
|
||||
/* LENGTH OF THE ELEMENT */
|
||||
tsscElemlen = (ZELEM_HEAD_SIZE + fragrecptr.p->keyLength) + fragrecptr.p->localkeylen;
|
||||
|
@ -11844,7 +11954,7 @@ bool Dbacc::searchScanContainer(Signal* signal)
|
|||
/* THE ELEMENT IS ALREADY SENT. */
|
||||
/* SEARCH FOR NEXT ONE */
|
||||
tsscElemlens = tsscElemlens - tsscElemlen;
|
||||
if (tsscElemlens > 2) {
|
||||
if (tsscElemlens > 1) { // wl-2066 loop as in getElement
|
||||
jam();
|
||||
tsscElementptr = tsscElementptr + tsscElemStep;
|
||||
goto SCANELEMENTLOOP001;
|
||||
|
@ -11877,7 +11987,8 @@ void Dbacc::sendNextScanConf(Signal* signal)
|
|||
|
||||
fragrecptr.i = operationRecPtr.p->fragptr;
|
||||
ptrCheckGuard(fragrecptr, cfragmentsize, fragmentrec);
|
||||
if (fragrecptr.p->keyLength != 0) {
|
||||
readTablePk(operationRecPtr.p->localdata[0]);
|
||||
if (fragrecptr.p->keyLength != 0) { // wl-2066 remove if
|
||||
jam();
|
||||
signal->theData[0] = scanPtr.p->scanUserptr;
|
||||
signal->theData[1] = operationRecPtr.i;
|
||||
|
@ -11886,26 +11997,28 @@ void Dbacc::sendNextScanConf(Signal* signal)
|
|||
signal->theData[4] = operationRecPtr.p->localdata[1];
|
||||
signal->theData[5] = fragrecptr.p->localkeylen;
|
||||
signal->theData[6] = fragrecptr.p->keyLength;
|
||||
signal->theData[7] = operationRecPtr.p->keydata[0];
|
||||
signal->theData[8] = operationRecPtr.p->keydata[1];
|
||||
signal->theData[9] = operationRecPtr.p->keydata[2];
|
||||
signal->theData[10] = operationRecPtr.p->keydata[3];
|
||||
signal->theData[7] = ckeys[0];
|
||||
signal->theData[8] = ckeys[1];
|
||||
signal->theData[9] = ckeys[2];
|
||||
signal->theData[10] = ckeys[3];
|
||||
EXECUTE_DIRECT(blockNo, GSN_NEXT_SCANCONF, signal, 11);
|
||||
if (fragrecptr.p->keyLength > ZKEYINKEYREQ) {
|
||||
const Uint32 keyLength = fragrecptr.p->keyLength;
|
||||
Uint32 total = 4;
|
||||
while (total < keyLength) {
|
||||
jam();
|
||||
/* = 4 */
|
||||
Uint32 length = keyLength - total;
|
||||
if (length > 20)
|
||||
length = 20;
|
||||
signal->theData[0] = scanPtr.p->scanUserptr;
|
||||
signal->theData[1] = operationRecPtr.i;
|
||||
signal->theData[2] = operationRecPtr.p->fid;
|
||||
signal->theData[3] = fragrecptr.p->keyLength - ZKEYINKEYREQ;
|
||||
signal->theData[4] = operationRecPtr.p->keydata[4];
|
||||
signal->theData[5] = operationRecPtr.p->keydata[5];
|
||||
signal->theData[6] = operationRecPtr.p->keydata[6];
|
||||
signal->theData[7] = operationRecPtr.p->keydata[7];
|
||||
EXECUTE_DIRECT(blockNo, GSN_ACC_SCAN_INFO, signal, 8);
|
||||
return;
|
||||
signal->theData[1] = operationRecPtr.i; // not used by LQH
|
||||
signal->theData[2] = operationRecPtr.p->fid; // not used by LQH
|
||||
signal->theData[3] = length;
|
||||
memcpy(&signal->theData[4], &ckeys[total], length << 2);
|
||||
EXECUTE_DIRECT(blockNo, GSN_ACC_SCAN_INFO24, signal, 4 + length);
|
||||
// wl-2066 remove GSN_ACC_SCAN_INFO
|
||||
total += length;
|
||||
}//if
|
||||
} else {
|
||||
} else { // wl-2066 remove
|
||||
jam();
|
||||
sendScaninfo(signal);
|
||||
return;
|
||||
|
|
|
@ -3,6 +3,8 @@ noinst_LIBRARIES = libdbacc.a
|
|||
|
||||
libdbacc_a_SOURCES = DbaccInit.cpp DbaccMain.cpp
|
||||
|
||||
INCLUDES_LOC = -I$(top_srcdir)/ndb/src/kernel/blocks/dbtup
|
||||
|
||||
include $(top_srcdir)/ndb/config/common.mk.am
|
||||
include $(top_srcdir)/ndb/config/type_kernel.mk.am
|
||||
|
||||
|
|
|
@ -4096,14 +4096,14 @@ Dbdict::execADD_FRAGREQ(Signal* signal) {
|
|||
req->maxLoadFactor = tabPtr.p->maxLoadFactor;
|
||||
req->minLoadFactor = tabPtr.p->minLoadFactor;
|
||||
req->kValue = tabPtr.p->kValue;
|
||||
req->lh3DistrBits = lhDistrBits;
|
||||
req->lh3PageBits = lhPageBits;
|
||||
req->lh3DistrBits = 0; //lhDistrBits;
|
||||
req->lh3PageBits = 0; //lhPageBits;
|
||||
req->noOfAttributes = tabPtr.p->noOfAttributes;
|
||||
req->noOfNullAttributes = tabPtr.p->noOfNullAttr;
|
||||
req->noOfPagesToPreAllocate = 0;
|
||||
req->schemaVersion = tabPtr.p->tableVersion;
|
||||
Uint32 keyLen = tabPtr.p->tupKeyLength;
|
||||
req->keyLength = keyLen > 8 ? 0 : keyLen; // Put this into ACC instead
|
||||
req->keyLength = keyLen; // wl-2066 no more "long keys"
|
||||
req->nextLCP = lcpNo;
|
||||
|
||||
req->noOfKeyAttr = tabPtr.p->noOfPrimkey;
|
||||
|
|
|
@ -6852,8 +6852,7 @@ void Dbdih::execDIGETNODESREQ(Signal* signal)
|
|||
TabRecord* regTabDesc = tabRecord;
|
||||
jamEntry();
|
||||
ptrCheckGuard(tabPtr, ttabFileSize, regTabDesc);
|
||||
hashValue = hashValue >> tabPtr.p->kvalue;
|
||||
Uint32 fragId = tabPtr.p->mask & hashValue;
|
||||
Uint32 fragId = hashValue & tabPtr.p->mask;
|
||||
ndbrequire(tabPtr.p->tabStatus == TabRecord::TS_ACTIVE);
|
||||
if (fragId < tabPtr.p->hashpointer) {
|
||||
jam();
|
||||
|
|
|
@ -861,10 +861,6 @@ public:
|
|||
* heard of.
|
||||
*/
|
||||
Uint8 fragDistributionKey;
|
||||
/**
|
||||
* Used to calculate which local fragment to use.
|
||||
*/
|
||||
Uint8 hashCheckBit;
|
||||
/**
|
||||
* The identity of the next local checkpoint this fragment
|
||||
* should perform.
|
||||
|
|
|
@ -1078,8 +1078,8 @@ void Dblqh::execLQHFRAGREQ(Signal* signal)
|
|||
if (DictTabInfo::isOrderedIndex(tableType)) {
|
||||
jam();
|
||||
// NOTE: next 2 lines stolen from ACC
|
||||
addfragptr.p->fragid1 = (0 << tlhstar) | fragId;
|
||||
addfragptr.p->fragid2 = (1 << tlhstar) | fragId;
|
||||
addfragptr.p->fragid1 = (fragId << 1) | 0;
|
||||
addfragptr.p->fragid2 = (fragId << 1) | 1;
|
||||
addfragptr.p->addfragStatus = AddFragRecord::WAIT_TWO_TUP;
|
||||
sendAddFragReq(signal);
|
||||
return;
|
||||
|
@ -1099,7 +1099,6 @@ void Dblqh::execACCFRAGCONF(Signal* signal)
|
|||
Uint32 fragId2 = signal->theData[3];
|
||||
Uint32 accFragPtr1 = signal->theData[4];
|
||||
Uint32 accFragPtr2 = signal->theData[5];
|
||||
Uint32 hashCheckBit = signal->theData[6];
|
||||
ptrCheckGuard(addfragptr, caddfragrecFileSize, addFragRecord);
|
||||
ndbrequire(addfragptr.p->addfragStatus == AddFragRecord::ACC_ADDFRAG);
|
||||
|
||||
|
@ -1110,7 +1109,6 @@ void Dblqh::execACCFRAGCONF(Signal* signal)
|
|||
ptrCheckGuard(fragptr, cfragrecFileSize, fragrecord);
|
||||
fragptr.p->accFragptr[0] = accFragPtr1;
|
||||
fragptr.p->accFragptr[1] = accFragPtr2;
|
||||
fragptr.p->hashCheckBit = hashCheckBit;
|
||||
|
||||
addfragptr.p->addfragStatus = AddFragRecord::WAIT_TWO_TUP;
|
||||
sendAddFragReq(signal);
|
||||
|
@ -1268,7 +1266,7 @@ Dblqh::sendAddFragReq(Signal* signal)
|
|||
tuxreq->noOfAttr = addfragptr.p->noOfAttr - 1; /* skip NDB$TNODE */
|
||||
tuxreq->fragId =
|
||||
addfragptr.p->addfragStatus == AddFragRecord::WAIT_TWO_TUX
|
||||
? addfragptr.p->fragid1 : addfragptr.p->fragid2;
|
||||
? addfragptr.p->fragid1: addfragptr.p->fragid2;
|
||||
tuxreq->fragOff = addfragptr.p->lh3DistrBits;
|
||||
tuxreq->tableType = addfragptr.p->tableType;
|
||||
tuxreq->primaryTableId = addfragptr.p->primaryTableId;
|
||||
|
@ -3420,7 +3418,7 @@ void Dblqh::execLQHKEYREQ(Signal* signal)
|
|||
LQHKEY_error(signal, 6);
|
||||
return;
|
||||
}//if
|
||||
regTcPtr->localFragptr = (regTcPtr->hashValue >> fragptr.p->hashCheckBit) & 1;
|
||||
regTcPtr->localFragptr = regTcPtr->hashValue & 1;
|
||||
Uint8 TcopyType = fragptr.p->fragCopy;
|
||||
tfragDistKey = fragptr.p->fragDistributionKey;
|
||||
if (fragptr.p->fragStatus == Fragrecord::ACTIVE_CREATION) {
|
||||
|
@ -8023,13 +8021,7 @@ void Dblqh::nextScanConfLoopLab(Signal* signal)
|
|||
ptrCheckGuard(fragptr, cfragrecFileSize, fragrecord);
|
||||
if (! scanptr.p->rangeScan) {
|
||||
tableRef = tcConnectptr.p->tableref;
|
||||
if (fragptr.p->fragId == scanptr.p->scanLocalFragid) {
|
||||
jam();
|
||||
tupFragPtr = fragptr.p->tupFragptr[0];
|
||||
} else {
|
||||
jam();
|
||||
tupFragPtr = fragptr.p->tupFragptr[1];
|
||||
}//if
|
||||
tupFragPtr = fragptr.p->tupFragptr[scanptr.p->scanLocalFragid & 1];
|
||||
} else {
|
||||
jam();
|
||||
// for ordered index use primary table
|
||||
|
@ -8037,13 +8029,7 @@ void Dblqh::nextScanConfLoopLab(Signal* signal)
|
|||
tFragPtr.i = fragptr.p->tableFragptr;
|
||||
ptrCheckGuard(tFragPtr, cfragrecFileSize, fragrecord);
|
||||
tableRef = tFragPtr.p->tabRef;
|
||||
if (tFragPtr.p->fragId == scanptr.p->scanLocalFragid) {
|
||||
jam();
|
||||
tupFragPtr = tFragPtr.p->tupFragptr[0];
|
||||
} else {
|
||||
jam();
|
||||
tupFragPtr = tFragPtr.p->tupFragptr[1];
|
||||
}//if
|
||||
tupFragPtr = tFragPtr.p->tupFragptr[scanptr.p->scanLocalFragid & 1];
|
||||
}
|
||||
{
|
||||
jam();
|
||||
|
@ -8520,7 +8506,8 @@ Uint32 Dblqh::initScanrec(const ScanFragReq* scanFragReq)
|
|||
#ifdef TRACE_SCAN_TAKEOVER
|
||||
ndbout_c("adding (%d %d) table: %d fragId: %d frag.i: %d tableFragptr: %d",
|
||||
scanptr.p->scanNumber, scanptr.p->fragPtrI,
|
||||
tabptr.i, scanFragReq->fragmentNo, fragptr.i, fragptr.p->tableFragptr);
|
||||
tabptr.i, scanFragReq->fragmentNoKeyLen & 0xFFFF,
|
||||
fragptr.i, fragptr.p->tableFragptr);
|
||||
#endif
|
||||
c_scanTakeOverHash.add(scanptr);
|
||||
}
|
||||
|
@ -8703,11 +8690,11 @@ void Dblqh::sendKeyinfo20(Signal* signal,
|
|||
TdataBuf.i = TdataBuf.p->nextDatabuf;
|
||||
}
|
||||
|
||||
Uint32 fragId = tcConP->fragmentid;
|
||||
keyInfo->clientOpPtr = scanP->scanApiOpPtr;
|
||||
keyInfo->keyLen = keyLen;
|
||||
keyInfo->scanInfo_Node = KeyInfo20::setScanInfo(scanOp,
|
||||
scanP->scanNumber)+
|
||||
(getOwnNodeId() << 20);
|
||||
keyInfo->scanInfo_Node =
|
||||
KeyInfo20::setScanInfo(scanOp, scanP->scanNumber) + (fragId << 20);
|
||||
keyInfo->transId1 = tcConP->transid[0];
|
||||
keyInfo->transId2 = tcConP->transid[1];
|
||||
|
||||
|
@ -9122,13 +9109,7 @@ void Dblqh::copySendTupkeyReqLab(Signal* signal)
|
|||
scanptr.p->scanState = ScanRecord::WAIT_TUPKEY_COPY;
|
||||
fragptr.i = tcConnectptr.p->fragmentptr;
|
||||
ptrCheckGuard(fragptr, cfragrecFileSize, fragrecord);
|
||||
if (fragptr.p->fragId == scanptr.p->scanLocalFragid) {
|
||||
jam();
|
||||
tupFragPtr = fragptr.p->tupFragptr[0];
|
||||
} else {
|
||||
jam();
|
||||
tupFragPtr = fragptr.p->tupFragptr[1];
|
||||
}//if
|
||||
tupFragPtr = fragptr.p->tupFragptr[scanptr.p->scanLocalFragid & 1];
|
||||
{
|
||||
TupKeyReq * const tupKeyReq = (TupKeyReq *)signal->getDataPtrSend();
|
||||
|
||||
|
@ -13390,7 +13371,6 @@ void Dblqh::execSR_FRAGIDCONF(Signal* signal)
|
|||
ptrCheckGuard(fragptr, cfragrecFileSize, fragrecord);
|
||||
fragptr.p->accFragptr[0] = srFragidConf->fragPtr[0];
|
||||
fragptr.p->accFragptr[1] = srFragidConf->fragPtr[1];
|
||||
fragptr.p->hashCheckBit = srFragidConf->hashCheckBit;
|
||||
Uint32 noLocFrag = srFragidConf->noLocFrag;
|
||||
ndbrequire(noLocFrag == 2);
|
||||
Uint32 fragid[2];
|
||||
|
|
|
@ -561,7 +561,7 @@ public:
|
|||
Uint32 expectedTransIdAI;
|
||||
AttributeBuffer transIdAI; // For accumulating TransId_AI
|
||||
|
||||
TcIndxReq tcIndxReq;
|
||||
TcKeyReq tcIndxReq;
|
||||
UintR connectionIndex;
|
||||
UintR indexReadTcConnect; //
|
||||
|
||||
|
@ -897,11 +897,11 @@ public:
|
|||
UintR hashValue; /* THE HASH VALUE USED TO LOCATE FRAGMENT */
|
||||
|
||||
Uint8 distributionKeyIndicator;
|
||||
Uint8 distributionGroupIndicator;
|
||||
Uint8 distributionGroupType;
|
||||
Uint8 unused1;
|
||||
Uint8 unused2;
|
||||
Uint8 lenAiInTckeyreq; /* LENGTH OF ATTRIBUTE INFORMATION IN TCKEYREQ */
|
||||
|
||||
Uint8 distributionKey;
|
||||
Uint8 fragmentDistributionKey; /* DIH generation no */
|
||||
|
||||
/**
|
||||
* EXECUTION MODE OF OPERATION
|
||||
|
@ -925,16 +925,16 @@ public:
|
|||
// Second 16 byte cache line in second 64 byte cache
|
||||
// line. Diverse use.
|
||||
//---------------------------------------------------
|
||||
UintR distributionGroup;
|
||||
UintR distributionKey;
|
||||
UintR nextCacheRec;
|
||||
UintR distributionKeySize;
|
||||
UintR unused3;
|
||||
Uint32 scanInfo;
|
||||
|
||||
//---------------------------------------------------
|
||||
// Third 16 byte cache line in second 64
|
||||
// byte cache line. Diverse use.
|
||||
//---------------------------------------------------
|
||||
Uint32 scanNode;
|
||||
Uint32 unused4;
|
||||
Uint32 scanTakeOverInd;
|
||||
UintR firstKeybuf; /* POINTER THE LINKED LIST OF KEY BUFFERS */
|
||||
UintR lastKeybuf; /* VARIABLE POINTING TO THE LAST KEY BUFFER */
|
||||
|
|
|
@ -2250,29 +2250,17 @@ void Dbtc::hash(Signal* signal)
|
|||
ti += 4;
|
||||
}//while
|
||||
}//if
|
||||
UintR ThashValue;
|
||||
UintR TdistrHashValue;
|
||||
ThashValue = md5_hash((Uint64*)&Tdata32[0], (UintR)regCachePtr->keylen);
|
||||
Uint32 tmp[4];
|
||||
md5_hash(tmp, (Uint64*)&Tdata32[0], (UintR)regCachePtr->keylen);
|
||||
|
||||
if (regCachePtr->distributionGroupIndicator == 1) {
|
||||
if (regCachePtr->distributionGroupType == 1) {
|
||||
jam();
|
||||
TdistrHashValue = (regCachePtr->distributionGroup << 6);
|
||||
} else {
|
||||
jam();
|
||||
Tdata32[0] = regCachePtr->distributionGroup;
|
||||
TdistrHashValue = md5_hash((Uint64*)&Tdata32[0], (UintR)1);
|
||||
}//if
|
||||
} else if (regCachePtr->distributionKeyIndicator == 1) {
|
||||
thashValue = tmp[0];
|
||||
if (regCachePtr->distributionKeyIndicator == 1) {
|
||||
jam();
|
||||
TdistrHashValue = md5_hash((Uint64*)&Tdata32[0],
|
||||
(UintR)regCachePtr->distributionKeySize);
|
||||
tdistrHashValue = regCachePtr->distributionKey;
|
||||
} else {
|
||||
jam();
|
||||
TdistrHashValue = ThashValue;
|
||||
tdistrHashValue = tmp[1];
|
||||
}//if
|
||||
thashValue = ThashValue;
|
||||
tdistrHashValue = TdistrHashValue;
|
||||
}//Dbtc::hash()
|
||||
|
||||
/*
|
||||
|
@ -2666,18 +2654,13 @@ void Dbtc::execTCKEYREQ(Signal* signal)
|
|||
Uint8 TSimpleFlag = tcKeyReq->getSimpleFlag(Treqinfo);
|
||||
Uint8 TDirtyFlag = tcKeyReq->getDirtyFlag(Treqinfo);
|
||||
Uint8 TInterpretedFlag = tcKeyReq->getInterpretedFlag(Treqinfo);
|
||||
Uint8 TDistrGroupFlag = tcKeyReq->getDistributionGroupFlag(Treqinfo);
|
||||
Uint8 TDistrGroupTypeFlag = tcKeyReq->getDistributionGroupTypeFlag(Treqinfo);
|
||||
Uint8 TDistrKeyFlag = tcKeyReq->getDistributionKeyFlag(Treqinfo);
|
||||
Uint8 TexecuteFlag = TexecFlag;
|
||||
|
||||
regCachePtr->opSimple = TSimpleFlag;
|
||||
regCachePtr->opExec = TInterpretedFlag;
|
||||
regTcPtr->dirtyOp = TDirtyFlag;
|
||||
|
||||
regCachePtr->distributionGroupIndicator = TDistrGroupFlag;
|
||||
regCachePtr->distributionGroupType = TDistrGroupTypeFlag;
|
||||
regCachePtr->distributionKeyIndicator = TDistrKeyFlag;
|
||||
regCachePtr->distributionKeyIndicator = TDistrKeyFlag;
|
||||
|
||||
//-------------------------------------------------------------
|
||||
// The next step is to read the upto three conditional words.
|
||||
|
@ -2686,17 +2669,14 @@ void Dbtc::execTCKEYREQ(Signal* signal)
|
|||
Uint32* TOptionalDataPtr = (Uint32*)&tcKeyReq->scanInfo;
|
||||
{
|
||||
Uint32 TDistrGHIndex = tcKeyReq->getScanIndFlag(Treqinfo);
|
||||
Uint32 TDistrKeyIndex = TDistrGHIndex + TDistrGroupFlag;
|
||||
Uint32 TDistrKeyIndex = TDistrGHIndex;
|
||||
|
||||
Uint32 TscanNode = tcKeyReq->getTakeOverScanNode(TOptionalDataPtr[0]);
|
||||
Uint32 TscanInfo = tcKeyReq->getTakeOverScanInfo(TOptionalDataPtr[0]);
|
||||
|
||||
regCachePtr->scanTakeOverInd = TDistrGHIndex;
|
||||
regCachePtr->scanNode = TscanNode;
|
||||
regCachePtr->scanInfo = TscanInfo;
|
||||
|
||||
regCachePtr->distributionGroup = TOptionalDataPtr[TDistrGHIndex];
|
||||
regCachePtr->distributionKeySize = TOptionalDataPtr[TDistrKeyIndex];
|
||||
regCachePtr->distributionKey = TOptionalDataPtr[TDistrKeyIndex];
|
||||
|
||||
TkeyIndex = TDistrKeyIndex + TDistrKeyFlag;
|
||||
}
|
||||
|
@ -2957,7 +2937,7 @@ void Dbtc::tckeyreq050Lab(Signal* signal)
|
|||
tnoOfBackup = tnodeinfo & 3;
|
||||
tnoOfStandby = (tnodeinfo >> 8) & 3;
|
||||
|
||||
regCachePtr->distributionKey = (tnodeinfo >> 16) & 255;
|
||||
regCachePtr->fragmentDistributionKey = (tnodeinfo >> 16) & 255;
|
||||
if (Toperation == ZREAD) {
|
||||
if (Tdirty == 1) {
|
||||
jam();
|
||||
|
@ -3048,7 +3028,6 @@ void Dbtc::attrinfoDihReceivedLab(Signal* signal)
|
|||
TcConnectRecord * const regTcPtr = tcConnectptr.p;
|
||||
Uint16 Tnode = regTcPtr->tcNodedata[0];
|
||||
Uint16 TscanTakeOverInd = regCachePtr->scanTakeOverInd;
|
||||
Uint16 TscanNode = regCachePtr->scanNode;
|
||||
|
||||
TableRecordPtr localTabptr;
|
||||
localTabptr.i = regCachePtr->tableref;
|
||||
|
@ -3061,11 +3040,6 @@ void Dbtc::attrinfoDihReceivedLab(Signal* signal)
|
|||
TCKEY_abort(signal, 58);
|
||||
return;
|
||||
}
|
||||
if ((TscanTakeOverInd == 1) &&
|
||||
(Tnode != TscanNode)) {
|
||||
TCKEY_abort(signal, 15);
|
||||
return;
|
||||
}//if
|
||||
arrGuard(Tnode, MAX_NDB_NODES);
|
||||
packLqhkeyreq(signal, calcLqhBlockRef(Tnode));
|
||||
}//Dbtc::attrinfoDihReceivedLab()
|
||||
|
@ -3127,7 +3101,7 @@ void Dbtc::sendlqhkeyreq(Signal* signal,
|
|||
/* ---------------------------------------------------------------------- */
|
||||
// Bit16 == 0 since StoredProcedures are not yet supported.
|
||||
/* ---------------------------------------------------------------------- */
|
||||
LqhKeyReq::setDistributionKey(tslrAttrLen, regCachePtr->distributionKey);
|
||||
LqhKeyReq::setDistributionKey(tslrAttrLen, regCachePtr->fragmentDistributionKey);
|
||||
LqhKeyReq::setScanTakeOverFlag(tslrAttrLen, regCachePtr->scanTakeOverInd);
|
||||
|
||||
Tdata10 = 0;
|
||||
|
@ -8477,7 +8451,7 @@ void Dbtc::systemErrorLab(Signal* signal)
|
|||
void Dbtc::execSCAN_TABREQ(Signal* signal)
|
||||
{
|
||||
const ScanTabReq * const scanTabReq = (ScanTabReq *)&signal->theData[0];
|
||||
const Uint32 reqinfo = scanTabReq->requestInfo;
|
||||
const Uint32 ri = scanTabReq->requestInfo;
|
||||
const Uint32 aiLength = (scanTabReq->attrLenKeyLen & 0xFFFF);
|
||||
const Uint32 keyLen = scanTabReq->attrLenKeyLen >> 16;
|
||||
const Uint32 schemaVersion = scanTabReq->tableSchemaVersion;
|
||||
|
@ -8487,8 +8461,8 @@ void Dbtc::execSCAN_TABREQ(Signal* signal)
|
|||
const Uint32 buddyPtr = (tmpXX == 0xFFFFFFFF ? RNIL : tmpXX);
|
||||
Uint32 currSavePointId = 0;
|
||||
|
||||
Uint32 scanConcurrency = scanTabReq->getParallelism(reqinfo);
|
||||
Uint32 noOprecPerFrag = ScanTabReq::getScanBatch(reqinfo);
|
||||
Uint32 scanConcurrency = scanTabReq->getParallelism(ri);
|
||||
Uint32 noOprecPerFrag = ScanTabReq::getScanBatch(ri);
|
||||
Uint32 scanParallel = scanConcurrency;
|
||||
Uint32 errCode;
|
||||
ScanRecordPtr scanptr;
|
||||
|
@ -8563,6 +8537,8 @@ void Dbtc::execSCAN_TABREQ(Signal* signal)
|
|||
seizeCacheRecord(signal);
|
||||
cachePtr.p->keylen = keyLen;
|
||||
cachePtr.p->save1 = 0;
|
||||
cachePtr.p->distributionKey = scanTabReq->distributionKey;
|
||||
cachePtr.p->distributionKeyIndicator= ScanTabReq::getDistributionKeyFlag(ri);
|
||||
scanptr = seizeScanrec(signal);
|
||||
|
||||
ndbrequire(transP->apiScanRec == RNIL);
|
||||
|
@ -8639,6 +8615,7 @@ void Dbtc::initScanrec(ScanRecordPtr scanptr,
|
|||
UintR scanParallel,
|
||||
UintR noOprecPerFrag)
|
||||
{
|
||||
const UintR ri = scanTabReq->requestInfo;
|
||||
scanptr.p->scanTcrec = tcConnectptr.i;
|
||||
scanptr.p->scanApiRec = apiConnectptr.i;
|
||||
scanptr.p->scanAiLength = scanTabReq->attrLenKeyLen & 0xFFFF;
|
||||
|
@ -8651,7 +8628,6 @@ void Dbtc::initScanrec(ScanRecordPtr scanptr,
|
|||
scanptr.p->batch_byte_size= scanTabReq->batch_byte_size;
|
||||
|
||||
Uint32 tmp = 0;
|
||||
const UintR ri = scanTabReq->requestInfo;
|
||||
ScanFragReq::setLockMode(tmp, ScanTabReq::getLockMode(ri));
|
||||
ScanFragReq::setHoldLockFlag(tmp, ScanTabReq::getHoldLockFlag(ri));
|
||||
ScanFragReq::setKeyinfoFlag(tmp, ScanTabReq::getKeyinfoFlag(ri));
|
||||
|
@ -8767,14 +8743,42 @@ void Dbtc::diFcountReqLab(Signal* signal, ScanRecordPtr scanptr)
|
|||
return;
|
||||
}
|
||||
|
||||
scanptr.p->scanNextFragId = 0;
|
||||
scanptr.p->scanState = ScanRecord::WAIT_FRAGMENT_COUNT;
|
||||
/*************************************************
|
||||
* THE FIRST STEP TO RECEIVE IS SUCCESSFULLY COMPLETED.
|
||||
* WE MUST FIRST GET THE NUMBER OF FRAGMENTS IN THE TABLE.
|
||||
***************************************************/
|
||||
signal->theData[0] = tcConnectptr.p->dihConnectptr;
|
||||
signal->theData[1] = scanptr.p->scanTableref;
|
||||
sendSignal(cdihblockref, GSN_DI_FCOUNTREQ, signal, 2, JBB);
|
||||
|
||||
if(!cachePtr.p->distributionKeyIndicator)
|
||||
{
|
||||
jam();
|
||||
/*************************************************
|
||||
* THE FIRST STEP TO RECEIVE IS SUCCESSFULLY COMPLETED.
|
||||
* WE MUST FIRST GET THE NUMBER OF FRAGMENTS IN THE TABLE.
|
||||
***************************************************/
|
||||
signal->theData[0] = tcConnectptr.p->dihConnectptr;
|
||||
signal->theData[1] = scanptr.p->scanTableref;
|
||||
sendSignal(cdihblockref, GSN_DI_FCOUNTREQ, signal, 2, JBB);
|
||||
}
|
||||
else
|
||||
{
|
||||
signal->theData[0] = tcConnectptr.p->dihConnectptr;
|
||||
signal->theData[1] = tabPtr.i;
|
||||
signal->theData[2] = cachePtr.p->distributionKey;
|
||||
EXECUTE_DIRECT(DBDIH, GSN_DIGETNODESREQ, signal, 3);
|
||||
UintR TerrorIndicator = signal->theData[0];
|
||||
jamEntry();
|
||||
if (TerrorIndicator != 0) {
|
||||
signal->theData[0] = tcConnectptr.i;
|
||||
//signal->theData[1] Contains error
|
||||
execDI_FCOUNTREF(signal);
|
||||
return;
|
||||
}
|
||||
|
||||
UintR Tdata1 = signal->theData[1];
|
||||
scanptr.p->scanNextFragId = Tdata1;
|
||||
|
||||
signal->theData[0] = tcConnectptr.i;
|
||||
signal->theData[1] = 1; // Frag count
|
||||
execDI_FCOUNTCONF(signal);
|
||||
}
|
||||
return;
|
||||
}//Dbtc::diFcountReqLab()
|
||||
|
||||
|
@ -8791,7 +8795,7 @@ void Dbtc::execDI_FCOUNTCONF(Signal* signal)
|
|||
{
|
||||
jamEntry();
|
||||
tcConnectptr.i = signal->theData[0];
|
||||
const UintR tfragCount = signal->theData[1];
|
||||
Uint32 tfragCount = signal->theData[1];
|
||||
ptrCheckGuard(tcConnectptr, ctcConnectFilesize, tcConnectRecord);
|
||||
apiConnectptr.i = tcConnectptr.p->apiConnect;
|
||||
ptrCheckGuard(apiConnectptr, capiConnectFilesize, apiConnectRecord);
|
||||
|
@ -8825,24 +8829,17 @@ void Dbtc::execDI_FCOUNTCONF(Signal* signal)
|
|||
return;
|
||||
}
|
||||
|
||||
if(scanptr.p->scanParallel > tfragCount){
|
||||
jam();
|
||||
abortScanLab(signal, scanptr, ZTOO_HIGH_CONCURRENCY_ERROR);
|
||||
return;
|
||||
}
|
||||
|
||||
scanptr.p->scanParallel = tfragCount;
|
||||
scanptr.p->scanNoFrag = tfragCount;
|
||||
scanptr.p->scanNextFragId = 0;
|
||||
scanptr.p->scanState = ScanRecord::RUNNING;
|
||||
|
||||
setApiConTimer(apiConnectptr.i, 0, __LINE__);
|
||||
updateBuddyTimer(apiConnectptr);
|
||||
|
||||
ScanFragRecPtr ptr;
|
||||
ScanFragList list(c_scan_frag_pool,
|
||||
scanptr.p->m_running_scan_frags);
|
||||
for (list.first(ptr); !ptr.isNull(); list.next(ptr)){
|
||||
ScanFragList list(c_scan_frag_pool, scanptr.p->m_running_scan_frags);
|
||||
for (list.first(ptr); !ptr.isNull() && tfragCount;
|
||||
list.next(ptr), tfragCount--){
|
||||
jam();
|
||||
|
||||
ptr.p->lqhBlockref = 0;
|
||||
|
@ -8857,6 +8854,20 @@ void Dbtc::execDI_FCOUNTCONF(Signal* signal)
|
|||
signal->theData[3] = ptr.p->scanFragId;
|
||||
sendSignal(cdihblockref, GSN_DIGETPRIMREQ, signal, 4, JBB);
|
||||
}//for
|
||||
|
||||
ScanFragList queued(c_scan_frag_pool, scanptr.p->m_queued_scan_frags);
|
||||
for (; !ptr.isNull();)
|
||||
{
|
||||
ptr.p->m_ops = 0;
|
||||
ptr.p->m_totalLen = 0;
|
||||
ptr.p->scanFragState = ScanFragRec::QUEUED_FOR_DELIVERY;
|
||||
ptr.p->stopFragTimer();
|
||||
|
||||
ScanFragRecPtr tmp = ptr;
|
||||
list.next(ptr);
|
||||
list.remove(tmp);
|
||||
queued.add(tmp);
|
||||
}
|
||||
}//Dbtc::execDI_FCOUNTCONF()
|
||||
|
||||
/******************************************************
|
||||
|
@ -11060,7 +11071,7 @@ void Dbtc::execTCINDXREQ(Signal* signal)
|
|||
{
|
||||
jamEntry();
|
||||
|
||||
TcIndxReq * const tcIndxReq = (TcIndxReq *)signal->getDataPtr();
|
||||
TcKeyReq * const tcIndxReq = (TcKeyReq *)signal->getDataPtr();
|
||||
const UintR TapiIndex = tcIndxReq->apiConnectPtr;
|
||||
Uint32 tcIndxRequestInfo = tcIndxReq->requestInfo;
|
||||
Uint32 startFlag = tcIndxReq->getStartFlag(tcIndxRequestInfo);
|
||||
|
@ -11111,7 +11122,7 @@ void Dbtc::execTCINDXREQ(Signal* signal)
|
|||
|
||||
// If operation is readTupleExclusive or updateTuple then read index
|
||||
// table with exclusive lock
|
||||
Uint32 indexLength = TcIndxReq::getIndexLength(tcIndxRequestInfo);
|
||||
Uint32 indexLength = TcKeyReq::getKeyLength(tcIndxRequestInfo);
|
||||
Uint32 attrLength = tcIndxReq->attrLen;
|
||||
indexOp->expectedKeyInfo = indexLength;
|
||||
Uint32 includedIndexLength = MIN(indexLength, indexBufSize);
|
||||
|
@ -11524,7 +11535,7 @@ void Dbtc::execTCKEYREF(Signal* signal)
|
|||
// Send TCINDXREF
|
||||
|
||||
jam();
|
||||
TcIndxReq * const tcIndxReq = &indexOp->tcIndxReq;
|
||||
TcKeyReq * const tcIndxReq = &indexOp->tcIndxReq;
|
||||
TcIndxRef * const tcIndxRef = (TcIndxRef *)signal->getDataPtrSend();
|
||||
|
||||
ndbassert(regApiPtr->noIndexOp);
|
||||
|
@ -11719,7 +11730,7 @@ void Dbtc::readIndexTable(Signal* signal,
|
|||
(Operation_t)TcKeyReq::getOperationType(tcKeyRequestInfo);
|
||||
|
||||
// Find index table
|
||||
if ((indexData = c_theIndexes.getPtr(indexOp->tcIndxReq.indexId)) == NULL) {
|
||||
if ((indexData = c_theIndexes.getPtr(indexOp->tcIndxReq.tableId)) == NULL) {
|
||||
jam();
|
||||
// Failed to find index record
|
||||
TcIndxRef * const tcIndxRef = (TcIndxRef *)signal->getDataPtrSend();
|
||||
|
@ -11736,7 +11747,7 @@ void Dbtc::readIndexTable(Signal* signal,
|
|||
tcKeyReq->transId2 = transId2;
|
||||
tcKeyReq->tableId = indexData->indexId;
|
||||
tcKeyLength += MIN(keyLength, keyBufSize);
|
||||
tcKeyReq->tableSchemaVersion = indexOp->tcIndxReq.indexSchemaVersion;
|
||||
tcKeyReq->tableSchemaVersion = indexOp->tcIndxReq.tableSchemaVersion;
|
||||
TcKeyReq::setOperationType(tcKeyRequestInfo,
|
||||
opType == ZREAD ? ZREAD : ZREAD_EX);
|
||||
TcKeyReq::setAIInTcKeyReq(tcKeyRequestInfo, 1); // Allways send one AttrInfo
|
||||
|
@ -11828,7 +11839,7 @@ void Dbtc::executeIndexOperation(Signal* signal,
|
|||
Uint32 keyBufSize = 8; // Maximum for key in TCKEYREQ
|
||||
Uint32 attrBufSize = 5;
|
||||
Uint32 dataPos = 0;
|
||||
TcIndxReq * const tcIndxReq = &indexOp->tcIndxReq;
|
||||
TcKeyReq * const tcIndxReq = &indexOp->tcIndxReq;
|
||||
TcKeyReq * const tcKeyReq = (TcKeyReq *)signal->getDataPtrSend();
|
||||
Uint32 * dataPtr = &tcKeyReq->scanInfo;
|
||||
Uint32 tcKeyLength = TcKeyReq::StaticLength;
|
||||
|
@ -11839,7 +11850,7 @@ void Dbtc::executeIndexOperation(Signal* signal,
|
|||
bool moreKeyData = indexOp->transIdAI.first(aiIter);
|
||||
|
||||
// Find index table
|
||||
if ((indexData = c_theIndexes.getPtr(tcIndxReq->indexId)) == NULL) {
|
||||
if ((indexData = c_theIndexes.getPtr(tcIndxReq->tableId)) == NULL) {
|
||||
jam();
|
||||
// Failed to find index record
|
||||
TcIndxRef * const tcIndxRef = (TcIndxRef *)signal->getDataPtrSend();
|
||||
|
|
|
@ -1020,6 +1020,13 @@ public:
|
|||
*/
|
||||
int tuxReadPk(Uint32 fragPtrI, Uint32 pageId, Uint32 pageOffset, Uint32* dataOut);
|
||||
|
||||
/*
|
||||
* ACC reads primary key without headers into an array of words. At
|
||||
* this point in ACC deconstruction, ACC still uses logical references
|
||||
* to fragment and tuple.
|
||||
*/
|
||||
int accReadPk(Uint32 tableId, Uint32 fragId, Uint32 fragPageId, Uint32 pageIndex, Uint32* dataOut);
|
||||
|
||||
/*
|
||||
* TUX checks if tuple is visible to scan.
|
||||
*/
|
||||
|
|
|
@ -200,8 +200,7 @@ Dbtup::tuxReadPk(Uint32 fragPtrI, Uint32 pageId, Uint32 pageOffset, Uint32* data
|
|||
operPtr.i = RNIL;
|
||||
operPtr.p = NULL;
|
||||
// do it
|
||||
int ret = readAttributes(pagePtr.p, pageOffset, attrIds,
|
||||
numAttrs, dataOut, ZNIL, true);
|
||||
int ret = readAttributes(pagePtr.p, pageOffset, attrIds, numAttrs, dataOut, ZNIL, true);
|
||||
// restore globals
|
||||
tabptr = tabptr_old;
|
||||
fragptr = fragptr_old;
|
||||
|
@ -229,6 +228,27 @@ Dbtup::tuxReadPk(Uint32 fragPtrI, Uint32 pageId, Uint32 pageOffset, Uint32* data
|
|||
return ret;
|
||||
}
|
||||
|
||||
int
|
||||
Dbtup::accReadPk(Uint32 tableId, Uint32 fragId, Uint32 fragPageId, Uint32 pageIndex, Uint32* dataOut)
|
||||
{
|
||||
ljamEntry();
|
||||
// get table
|
||||
TablerecPtr tablePtr;
|
||||
tablePtr.i = tableId;
|
||||
ptrCheckGuard(tablePtr, cnoOfTablerec, tablerec);
|
||||
// get fragment
|
||||
FragrecordPtr fragPtr;
|
||||
getFragmentrec(fragPtr, fragId, tablePtr.p);
|
||||
// get real page id and tuple offset
|
||||
PagePtr pagePtr;
|
||||
Uint32 pageId = getRealpid(fragPtr.p, fragPageId);
|
||||
ndbrequire((pageIndex & 0x1) == 0);
|
||||
Uint32 pageOffset = ZPAGE_HEADER_SIZE + (pageIndex >> 1) * tablePtr.p->tupheadsize;
|
||||
// use TUX routine - optimize later
|
||||
int ret = tuxReadPk(fragPtr.i, pageId, pageOffset, dataOut);
|
||||
return ret;
|
||||
}
|
||||
|
||||
bool
|
||||
Dbtup::tuxQueryTh(Uint32 fragPtrI, Uint32 tupAddr, Uint32 tupVersion, Uint32 transId1, Uint32 transId2, Uint32 savePointId)
|
||||
{
|
||||
|
|
|
@ -987,7 +987,7 @@ Dbtup::read_psuedo(Uint32 attrId, Uint32* outBuffer){
|
|||
Signal * signal = (Signal*)&tmp;
|
||||
switch(attrId){
|
||||
case AttributeHeader::FRAGMENT:
|
||||
* outBuffer = operPtr.p->fragId;
|
||||
* outBuffer = operPtr.p->fragId >> 1; // remove "hash" bit
|
||||
return 1;
|
||||
case AttributeHeader::ROW_COUNT:
|
||||
case AttributeHeader::COMMIT_COUNT:
|
||||
|
|
|
@ -449,7 +449,7 @@ private:
|
|||
State m_state;
|
||||
DictTabInfo::TableType m_tableType;
|
||||
Uint32 m_tableId;
|
||||
Uint16 m_fragOff; // offset for duplicate fragId bits
|
||||
Uint16 unused;
|
||||
Uint16 m_numFrags;
|
||||
Uint32 m_fragId[MaxIndexFragments];
|
||||
Uint32 m_fragPtrI[MaxIndexFragments];
|
||||
|
@ -475,7 +475,7 @@ private:
|
|||
struct Frag {
|
||||
Uint32 m_tableId; // copy from index level
|
||||
Uint32 m_indexId;
|
||||
Uint16 m_fragOff;
|
||||
Uint16 unused;
|
||||
Uint16 m_fragId;
|
||||
Uint32 m_descPage; // copy from index level
|
||||
Uint16 m_descOff;
|
||||
|
@ -1072,7 +1072,6 @@ inline
|
|||
Dbtux::Frag::Frag(ArrayPool<ScanOp>& scanOpPool) :
|
||||
m_tableId(RNIL),
|
||||
m_indexId(RNIL),
|
||||
m_fragOff(ZNIL),
|
||||
m_fragId(ZNIL),
|
||||
m_descPage(RNIL),
|
||||
m_descOff(0),
|
||||
|
|
|
@ -370,7 +370,6 @@ operator<<(NdbOut& out, const Dbtux::Index& index)
|
|||
{
|
||||
out << "[Index " << hex << &index;
|
||||
out << " [tableId " << dec << index.m_tableId << "]";
|
||||
out << " [fragOff " << dec << index.m_fragOff << "]";
|
||||
out << " [numFrags " << dec << index.m_numFrags << "]";
|
||||
for (unsigned i = 0; i < index.m_numFrags; i++) {
|
||||
out << " [frag " << dec << i << " ";
|
||||
|
@ -393,7 +392,6 @@ operator<<(NdbOut& out, const Dbtux::Frag& frag)
|
|||
out << "[Frag " << hex << &frag;
|
||||
out << " [tableId " << dec << frag.m_tableId << "]";
|
||||
out << " [indexId " << dec << frag.m_indexId << "]";
|
||||
out << " [fragOff " << dec << frag.m_fragOff << "]";
|
||||
out << " [fragId " << dec << frag.m_fragId << "]";
|
||||
out << " [descPage " << hex << frag.m_descPage << "]";
|
||||
out << " [descOff " << dec << frag.m_descOff << "]";
|
||||
|
|
|
@ -57,9 +57,9 @@ Dbtux::execTUX_MAINT_REQ(Signal* signal)
|
|||
c_indexPool.getPtr(indexPtr, req->indexId);
|
||||
ndbrequire(indexPtr.p->m_tableId == req->tableId);
|
||||
// get base fragment id and extra bits
|
||||
const Uint32 fragOff = indexPtr.p->m_fragOff;
|
||||
const Uint32 fragId = req->fragId & ((1 << fragOff) - 1);
|
||||
const Uint32 fragBit = req->fragId >> fragOff;
|
||||
const Uint32 fragId = req->fragId & ~1;
|
||||
const Uint32 fragBit = req->fragId & 1;
|
||||
|
||||
// get the fragment
|
||||
FragPtr fragPtr;
|
||||
fragPtr.i = RNIL;
|
||||
|
@ -71,6 +71,7 @@ Dbtux::execTUX_MAINT_REQ(Signal* signal)
|
|||
break;
|
||||
}
|
||||
}
|
||||
|
||||
ndbrequire(fragPtr.i != RNIL);
|
||||
Frag& frag = *fragPtr.p;
|
||||
// set up index keys for this operation
|
||||
|
|
|
@ -74,7 +74,6 @@ Dbtux::execTUXFRAGREQ(Signal* signal)
|
|||
new (fragPtr.p) Frag(c_scanOpPool);
|
||||
fragPtr.p->m_tableId = req->primaryTableId;
|
||||
fragPtr.p->m_indexId = req->tableId;
|
||||
fragPtr.p->m_fragOff = req->fragOff;
|
||||
fragPtr.p->m_fragId = req->fragId;
|
||||
fragPtr.p->m_numAttrs = req->noOfAttr;
|
||||
fragPtr.p->m_storeNullKey = true; // not yet configurable
|
||||
|
@ -102,7 +101,6 @@ Dbtux::execTUXFRAGREQ(Signal* signal)
|
|||
indexPtr.p->m_state = Index::Defining;
|
||||
indexPtr.p->m_tableType = (DictTabInfo::TableType)req->tableType;
|
||||
indexPtr.p->m_tableId = req->primaryTableId;
|
||||
indexPtr.p->m_fragOff = req->fragOff;
|
||||
indexPtr.p->m_numAttrs = req->noOfAttr;
|
||||
indexPtr.p->m_storeNullKey = true; // not yet configurable
|
||||
// allocate attribute descriptors
|
||||
|
@ -118,7 +116,6 @@ Dbtux::execTUXFRAGREQ(Signal* signal)
|
|||
indexPtr.p->m_state == Index::Defining &&
|
||||
indexPtr.p->m_tableType == (DictTabInfo::TableType)req->tableType &&
|
||||
indexPtr.p->m_tableId == req->primaryTableId &&
|
||||
indexPtr.p->m_fragOff == req->fragOff &&
|
||||
indexPtr.p->m_numAttrs == req->noOfAttr);
|
||||
}
|
||||
// copy metadata address to each fragment
|
||||
|
|
|
@ -34,7 +34,7 @@ Dbtux::execACC_SCANREQ(Signal* signal)
|
|||
fragPtr.i = RNIL;
|
||||
for (unsigned i = 0; i < indexPtr.p->m_numFrags; i++) {
|
||||
jam();
|
||||
if (indexPtr.p->m_fragId[i] == req->fragmentNo) {
|
||||
if (indexPtr.p->m_fragId[i] == req->fragmentNo << 1) {
|
||||
jam();
|
||||
c_fragPool.getPtr(fragPtr, indexPtr.p->m_fragPtrI[i]);
|
||||
break;
|
||||
|
@ -43,7 +43,6 @@ Dbtux::execACC_SCANREQ(Signal* signal)
|
|||
ndbrequire(fragPtr.i != RNIL);
|
||||
Frag& frag = *fragPtr.p;
|
||||
// must be normal DIH/TC fragment
|
||||
ndbrequire(frag.m_fragId < (1 << frag.m_fragOff));
|
||||
TreeHead& tree = frag.m_tree;
|
||||
// check for empty fragment
|
||||
if (tree.m_root == NullTupLoc) {
|
||||
|
@ -354,7 +353,7 @@ Dbtux::execACC_CHECK_SCAN(Signal* signal)
|
|||
NextScanConf* const conf = (NextScanConf*)signal->getDataPtrSend();
|
||||
conf->scanPtr = scan.m_userPtr;
|
||||
conf->accOperationPtr = RNIL; // no tuple returned
|
||||
conf->fragId = frag.m_fragId | (ent.m_fragBit << frag.m_fragOff);
|
||||
conf->fragId = frag.m_fragId | ent.m_fragBit;
|
||||
unsigned signalLength = 3;
|
||||
// if TC has ordered scan close, it will be detected here
|
||||
sendSignal(scan.m_userRef, GSN_NEXT_SCANCONF,
|
||||
|
@ -397,7 +396,7 @@ Dbtux::execACC_CHECK_SCAN(Signal* signal)
|
|||
lockReq->userPtr = scanPtr.i;
|
||||
lockReq->userRef = reference();
|
||||
lockReq->tableId = scan.m_tableId;
|
||||
lockReq->fragId = frag.m_fragId | (ent.m_fragBit << frag.m_fragOff);
|
||||
lockReq->fragId = frag.m_fragId | ent.m_fragBit;
|
||||
lockReq->fragPtrI = frag.m_accTableFragPtrI[ent.m_fragBit];
|
||||
const Uint32* const buf32 = static_cast<Uint32*>(pkData);
|
||||
const Uint64* const buf64 = reinterpret_cast<const Uint64*>(buf32);
|
||||
|
@ -496,7 +495,7 @@ Dbtux::execACC_CHECK_SCAN(Signal* signal)
|
|||
accLockOp = (Uint32)-1;
|
||||
}
|
||||
conf->accOperationPtr = accLockOp;
|
||||
conf->fragId = frag.m_fragId | (ent.m_fragBit << frag.m_fragOff);
|
||||
conf->fragId = frag.m_fragId | ent.m_fragBit;
|
||||
conf->localKey[0] = getTupAddr(frag, ent);
|
||||
conf->localKey[1] = 0;
|
||||
conf->localKeyLength = 1;
|
||||
|
@ -890,7 +889,7 @@ Dbtux::scanVisible(ScanOpPtr scanPtr, TreeEnt ent)
|
|||
const Frag& frag = *c_fragPool.getPtr(scan.m_fragPtrI);
|
||||
Uint32 fragBit = ent.m_fragBit;
|
||||
Uint32 tableFragPtrI = frag.m_tupTableFragPtrI[fragBit];
|
||||
Uint32 fragId = frag.m_fragId | (fragBit << frag.m_fragOff);
|
||||
Uint32 fragId = frag.m_fragId | fragBit;
|
||||
Uint32 tupAddr = getTupAddr(frag, ent);
|
||||
Uint32 tupVersion = ent.m_tupVersion;
|
||||
// check for same tuple twice in row
|
||||
|
|
|
@ -138,6 +138,14 @@ before mc02/c 5 ms 13 ms 126 pct
|
|||
after mc02/c 5 ms 10 ms 70 pct
|
||||
mc02/d 178 ms 242 ms 69 pct
|
||||
|
||||
[ prelim preformance fix for max batch size 16 -> 992 ]
|
||||
[ prelim performance fix for max batch size 16 -> 992 ]
|
||||
|
||||
wl-2066 mc02/c 5 ms 10 ms 87 pct
|
||||
before mc02/d 140 ms 237 ms 69 pct
|
||||
|
||||
wl-2066 mc02/c 5 ms 10 ms 69 pct
|
||||
after mc02/d 150 ms 229 ms 52 pct
|
||||
|
||||
[ wl-2066 = remove ACC storage, use TUX test to see effect ]
|
||||
|
||||
vim: set et:
|
||||
|
|
|
@ -213,7 +213,7 @@ NdbApiSignal::setSignal(int aNdbSignalType)
|
|||
theTrace = TestOrd::TraceAPI;
|
||||
theReceiversBlockNumber = DBTC;
|
||||
theVerId_signalNumber = GSN_TCINDXREQ;
|
||||
theLength = TcIndxReq::SignalLength;
|
||||
theLength = TcKeyReq::SignalLength;
|
||||
}
|
||||
break;
|
||||
|
||||
|
|
|
@ -99,8 +99,8 @@ NdbBlob::getBlobTable(NdbTableImpl& bt, const NdbTableImpl* t, const NdbColumnIm
|
|||
bt.setFragmentType(t->getFragmentType());
|
||||
{ NdbDictionary::Column bc("PK");
|
||||
bc.setType(NdbDictionary::Column::Unsigned);
|
||||
assert(t->m_sizeOfKeysInWords != 0);
|
||||
bc.setLength(t->m_sizeOfKeysInWords);
|
||||
assert(t->m_keyLenInWords != 0);
|
||||
bc.setLength(t->m_keyLenInWords);
|
||||
bc.setPrimaryKey(true);
|
||||
bc.setDistributionKey(true);
|
||||
bt.addColumn(bc);
|
||||
|
@ -346,7 +346,7 @@ int
|
|||
NdbBlob::setTableKeyValue(NdbOperation* anOp)
|
||||
{
|
||||
const Uint32* data = (const Uint32*)theKeyBuf.data;
|
||||
DBG("setTableKeyValue key=" << ndb_blob_debug(data, theTable->m_sizeOfKeysInWords));
|
||||
DBG("setTableKeyValue key=" << ndb_blob_debug(data, theTable->m_keyLenInWords));
|
||||
const unsigned columns = theTable->m_columns.size();
|
||||
unsigned pos = 0;
|
||||
for (unsigned i = 0; i < columns; i++) {
|
||||
|
@ -369,7 +369,7 @@ int
|
|||
NdbBlob::setAccessKeyValue(NdbOperation* anOp)
|
||||
{
|
||||
const Uint32* data = (const Uint32*)theAccessKeyBuf.data;
|
||||
DBG("setAccessKeyValue key=" << ndb_blob_debug(data, theAccessTable->m_sizeOfKeysInWords));
|
||||
DBG("setAccessKeyValue key=" << ndb_blob_debug(data, theAccessTable->m_keyLenInWords));
|
||||
const unsigned columns = theAccessTable->m_columns.size();
|
||||
unsigned pos = 0;
|
||||
for (unsigned i = 0; i < columns; i++) {
|
||||
|
@ -392,7 +392,7 @@ int
|
|||
NdbBlob::setPartKeyValue(NdbOperation* anOp, Uint32 part)
|
||||
{
|
||||
Uint32* data = (Uint32*)theKeyBuf.data;
|
||||
unsigned size = theTable->m_sizeOfKeysInWords;
|
||||
unsigned size = theTable->m_keyLenInWords;
|
||||
DBG("setPartKeyValue dist=" << getDistKey(part) << " part=" << part << " key=" << ndb_blob_debug(data, size));
|
||||
// TODO use attr ids after compatibility with 4.1.7 not needed
|
||||
if (anOp->equal("PK", theKeyBuf.data) == -1 ||
|
||||
|
@ -1105,8 +1105,8 @@ NdbBlob::atPrepare(NdbConnection* aCon, NdbOperation* anOp, const NdbColumnImpl*
|
|||
theBlobTable = &NdbTableImpl::getImpl(*bt);
|
||||
}
|
||||
// buffers
|
||||
theKeyBuf.alloc(theTable->m_sizeOfKeysInWords << 2);
|
||||
theAccessKeyBuf.alloc(theAccessTable->m_sizeOfKeysInWords << 2);
|
||||
theKeyBuf.alloc(theTable->m_keyLenInWords << 2);
|
||||
theAccessKeyBuf.alloc(theAccessTable->m_keyLenInWords << 2);
|
||||
theHeadInlineBuf.alloc(sizeof(Head) + theInlineSize);
|
||||
theHeadInlineCopyBuf.alloc(sizeof(Head) + theInlineSize);
|
||||
thePartBuf.alloc(thePartSize);
|
||||
|
@ -1118,7 +1118,7 @@ NdbBlob::atPrepare(NdbConnection* aCon, NdbOperation* anOp, const NdbColumnImpl*
|
|||
if (isTableOp()) {
|
||||
// get table key
|
||||
Uint32* data = (Uint32*)theKeyBuf.data;
|
||||
unsigned size = theTable->m_sizeOfKeysInWords;
|
||||
unsigned size = theTable->m_keyLenInWords;
|
||||
if (theNdbOp->getKeyFromTCREQ(data, size) == -1) {
|
||||
setErrorCode(ErrUsage);
|
||||
return -1;
|
||||
|
@ -1127,7 +1127,7 @@ NdbBlob::atPrepare(NdbConnection* aCon, NdbOperation* anOp, const NdbColumnImpl*
|
|||
if (isIndexOp()) {
|
||||
// get index key
|
||||
Uint32* data = (Uint32*)theAccessKeyBuf.data;
|
||||
unsigned size = theAccessTable->m_sizeOfKeysInWords;
|
||||
unsigned size = theAccessTable->m_keyLenInWords;
|
||||
if (theNdbOp->getKeyFromTCREQ(data, size) == -1) {
|
||||
setErrorCode(ErrUsage);
|
||||
return -1;
|
||||
|
@ -1487,7 +1487,7 @@ NdbBlob::atNextResult()
|
|||
assert(isScanOp());
|
||||
// get primary key
|
||||
{ Uint32* data = (Uint32*)theKeyBuf.data;
|
||||
unsigned size = theTable->m_sizeOfKeysInWords;
|
||||
unsigned size = theTable->m_keyLenInWords;
|
||||
if (((NdbScanOperation*)theNdbOp)->getKeyFromKEYINFO20(data, size) == -1) {
|
||||
setErrorCode(ErrUsage);
|
||||
return -1;
|
||||
|
|
|
@ -1084,8 +1084,7 @@ NdbConnection::getNdbIndexScanOperation(const NdbIndexImpl* index,
|
|||
if (theCommitStatus == Started){
|
||||
const NdbTableImpl * indexTable = index->getIndexTable();
|
||||
if (indexTable != 0){
|
||||
NdbIndexScanOperation* tOp =
|
||||
getNdbScanOperation((NdbTableImpl *) indexTable);
|
||||
NdbIndexScanOperation* tOp = getNdbScanOperation(indexTable);
|
||||
tOp->m_currentTable = table;
|
||||
if(tOp) tOp->m_cursor_type = NdbScanOperation::IndexCursor;
|
||||
return tOp;
|
||||
|
|
|
@ -176,16 +176,6 @@ NdbDictionary::Column::getPrimaryKey() const {
|
|||
return m_impl.m_pk;
|
||||
}
|
||||
|
||||
void
|
||||
NdbDictionary::Column::setTupleKey(bool val){
|
||||
m_impl.m_tupleKey = val;
|
||||
}
|
||||
|
||||
bool
|
||||
NdbDictionary::Column::getTupleKey() const {
|
||||
return m_impl.m_tupleKey;
|
||||
}
|
||||
|
||||
void
|
||||
NdbDictionary::Column::setDistributionKey(bool val){
|
||||
m_impl.m_distributionKey = val;
|
||||
|
@ -196,32 +186,6 @@ NdbDictionary::Column::getDistributionKey() const{
|
|||
return m_impl.m_distributionKey;
|
||||
}
|
||||
|
||||
void
|
||||
NdbDictionary::Column::setDistributionGroup(bool val, int bits){
|
||||
m_impl.m_distributionGroup = val;
|
||||
m_impl.m_distributionGroupBits = bits;
|
||||
}
|
||||
|
||||
bool
|
||||
NdbDictionary::Column::getDistributionGroup() const {
|
||||
return m_impl.m_distributionGroup;
|
||||
}
|
||||
|
||||
int
|
||||
NdbDictionary::Column::getDistributionGroupBits() const{
|
||||
return m_impl.m_distributionGroupBits;
|
||||
}
|
||||
|
||||
void
|
||||
NdbDictionary::Column::setIndexOnlyStorage(bool val){
|
||||
m_impl.m_indexOnly = val;
|
||||
}
|
||||
|
||||
bool
|
||||
NdbDictionary::Column::getIndexOnlyStorage() const {
|
||||
return m_impl.m_indexOnly;
|
||||
}
|
||||
|
||||
const NdbDictionary::Table *
|
||||
NdbDictionary::Column::getBlobTable() const {
|
||||
NdbTableImpl * t = m_impl.m_blobTable;
|
||||
|
@ -969,9 +933,9 @@ operator<<(NdbOut& out, const NdbDictionary::Column& col)
|
|||
else
|
||||
out << " NULL";
|
||||
|
||||
if (col.getDistributionKey())
|
||||
if(col.getDistributionKey())
|
||||
out << " DISTRIBUTION KEY";
|
||||
|
||||
|
||||
return out;
|
||||
}
|
||||
|
||||
|
|
|
@ -69,12 +69,8 @@ NdbColumnImpl::operator=(const NdbColumnImpl& col)
|
|||
m_scale = col.m_scale;
|
||||
m_length = col.m_length;
|
||||
m_pk = col.m_pk;
|
||||
m_tupleKey = col.m_tupleKey;
|
||||
m_distributionKey = col.m_distributionKey;
|
||||
m_distributionGroup = col.m_distributionGroup;
|
||||
m_distributionGroupBits = col.m_distributionGroupBits;
|
||||
m_nullable = col.m_nullable;
|
||||
m_indexOnly = col.m_indexOnly;
|
||||
m_autoIncrement = col.m_autoIncrement;
|
||||
m_autoIncrementInitialValue = col.m_autoIncrementInitialValue;
|
||||
m_defaultValue = col.m_defaultValue;
|
||||
|
@ -153,11 +149,7 @@ NdbColumnImpl::init(Type t)
|
|||
}
|
||||
m_pk = false;
|
||||
m_nullable = false;
|
||||
m_tupleKey = false;
|
||||
m_indexOnly = false;
|
||||
m_distributionKey = false;
|
||||
m_distributionGroup = false;
|
||||
m_distributionGroupBits = 8;
|
||||
m_keyInfoPos = 0;
|
||||
// next 2 are set at run time
|
||||
m_attrSize = 0;
|
||||
|
@ -187,22 +179,9 @@ NdbColumnImpl::equal(const NdbColumnImpl& col) const
|
|||
return false;
|
||||
}
|
||||
if(m_pk){
|
||||
if(m_tupleKey != col.m_tupleKey){
|
||||
return false;
|
||||
}
|
||||
if(m_indexOnly != col.m_indexOnly){
|
||||
return false;
|
||||
}
|
||||
if(m_distributionKey != col.m_distributionKey){
|
||||
return false;
|
||||
}
|
||||
if(m_distributionGroup != col.m_distributionGroup){
|
||||
return false;
|
||||
}
|
||||
if(m_distributionGroup &&
|
||||
(m_distributionGroupBits != col.m_distributionGroupBits)){
|
||||
return false;
|
||||
}
|
||||
}
|
||||
if (m_precision != col.m_precision ||
|
||||
m_scale != col.m_scale ||
|
||||
|
@ -285,8 +264,9 @@ NdbTableImpl::init(){
|
|||
m_indexType = NdbDictionary::Index::Undefined;
|
||||
|
||||
m_noOfKeys = 0;
|
||||
m_noOfDistributionKeys = 0;
|
||||
m_fragmentCount = 0;
|
||||
m_sizeOfKeysInWords = 0;
|
||||
m_keyLenInWords = 0;
|
||||
m_noOfBlobs = 0;
|
||||
}
|
||||
|
||||
|
@ -365,8 +345,9 @@ NdbTableImpl::assign(const NdbTableImpl& org)
|
|||
delete m_index;
|
||||
m_index = org.m_index;
|
||||
|
||||
m_noOfDistributionKeys = org.m_noOfDistributionKeys;
|
||||
m_noOfKeys = org.m_noOfKeys;
|
||||
m_sizeOfKeysInWords = org.m_sizeOfKeysInWords;
|
||||
m_keyLenInWords = org.m_keyLenInWords;
|
||||
m_noOfBlobs = org.m_noOfBlobs;
|
||||
|
||||
m_version = org.m_version;
|
||||
|
@ -1233,6 +1214,7 @@ NdbDictInterface::parseTableInfo(NdbTableImpl ** ret,
|
|||
Uint32 keyInfoPos = 0;
|
||||
Uint32 keyCount = 0;
|
||||
Uint32 blobCount = 0;
|
||||
Uint32 distKeys = 0;
|
||||
|
||||
for(Uint32 i = 0; i < tableDesc.NoOfAttributes; i++) {
|
||||
DictTabInfo::Attribute attrDesc; attrDesc.init();
|
||||
|
@ -1286,12 +1268,8 @@ NdbDictInterface::parseTableInfo(NdbTableImpl ** ret,
|
|||
col->m_arraySize = attrDesc.AttributeArraySize;
|
||||
|
||||
col->m_pk = attrDesc.AttributeKeyFlag;
|
||||
col->m_tupleKey = 0;
|
||||
col->m_distributionKey = attrDesc.AttributeDKey;
|
||||
col->m_distributionGroup = attrDesc.AttributeDGroup;
|
||||
col->m_distributionGroupBits = 16;
|
||||
col->m_nullable = attrDesc.AttributeNullableFlag;
|
||||
col->m_indexOnly = (attrDesc.AttributeStoredInd ? false : true);
|
||||
col->m_autoIncrement = (attrDesc.AttributeAutoIncrement ? true : false);
|
||||
col->m_autoIncrementInitialValue = ~0;
|
||||
col->m_defaultValue.assign(attrDesc.AttributeDefaultValue);
|
||||
|
@ -1300,6 +1278,9 @@ NdbDictInterface::parseTableInfo(NdbTableImpl ** ret,
|
|||
col->m_keyInfoPos = keyInfoPos + 1;
|
||||
keyInfoPos += ((col->m_attrSize * col->m_arraySize + 3) / 4);
|
||||
keyCount++;
|
||||
|
||||
if(attrDesc.AttributeDKey)
|
||||
distKeys++;
|
||||
} else {
|
||||
col->m_keyInfoPos = 0;
|
||||
}
|
||||
|
@ -1318,8 +1299,8 @@ NdbDictInterface::parseTableInfo(NdbTableImpl ** ret,
|
|||
|
||||
impl->m_noOfKeys = keyCount;
|
||||
impl->m_keyLenInWords = keyInfoPos;
|
||||
impl->m_sizeOfKeysInWords = keyInfoPos;
|
||||
impl->m_noOfBlobs = blobCount;
|
||||
impl->m_noOfDistributionKeys = distKeys;
|
||||
* ret = impl;
|
||||
return 0;
|
||||
}
|
||||
|
@ -1527,11 +1508,11 @@ NdbDictInterface::createOrAlterTable(Ndb & ndb,
|
|||
BaseString::snprintf(tmpAttr.AttributeName, sizeof(tmpAttr.AttributeName),
|
||||
col->m_name.c_str());
|
||||
tmpAttr.AttributeId = i;
|
||||
tmpAttr.AttributeKeyFlag = col->m_pk || col->m_tupleKey;
|
||||
tmpAttr.AttributeKeyFlag = col->m_pk;
|
||||
tmpAttr.AttributeNullableFlag = col->m_nullable;
|
||||
tmpAttr.AttributeStoredInd = (col->m_indexOnly ? 0 : 1);
|
||||
tmpAttr.AttributeStoredInd = 1;
|
||||
tmpAttr.AttributeDKey = col->m_distributionKey;
|
||||
tmpAttr.AttributeDGroup = col->m_distributionGroup;
|
||||
tmpAttr.AttributeDGroup = 0;
|
||||
|
||||
tmpAttr.AttributeExtType =
|
||||
getKernelConstant(col->m_type,
|
||||
|
@ -2029,10 +2010,6 @@ NdbDictInterface::createIndex(Ndb & ndb,
|
|||
// Copy column definition
|
||||
*impl.m_columns[i] = *col;
|
||||
|
||||
if(col->m_pk && col->m_indexOnly){
|
||||
m_error.code = 4245;
|
||||
return -1;
|
||||
}
|
||||
// index key type check
|
||||
if (it == DictTabInfo::UniqueHashIndex &&
|
||||
! NdbSqlUtil::usable_in_hash_index(col->m_type, col->m_cs) ||
|
||||
|
|
|
@ -63,12 +63,8 @@ public:
|
|||
CHARSET_INFO * m_cs; // not const in MySQL
|
||||
|
||||
bool m_pk;
|
||||
bool m_tupleKey;
|
||||
bool m_distributionKey;
|
||||
bool m_distributionGroup;
|
||||
int m_distributionGroupBits;
|
||||
bool m_nullable;
|
||||
bool m_indexOnly;
|
||||
bool m_autoIncrement;
|
||||
Uint64 m_autoIncrementInitialValue;
|
||||
BaseString m_defaultValue;
|
||||
|
@ -128,8 +124,8 @@ public:
|
|||
int m_kvalue;
|
||||
int m_minLoadFactor;
|
||||
int m_maxLoadFactor;
|
||||
int m_keyLenInWords;
|
||||
int m_fragmentCount;
|
||||
Uint16 m_keyLenInWords;
|
||||
Uint16 m_fragmentCount;
|
||||
|
||||
NdbDictionaryImpl * m_dictionary;
|
||||
NdbIndexImpl * m_index;
|
||||
|
@ -147,9 +143,9 @@ public:
|
|||
/**
|
||||
* Aggregates
|
||||
*/
|
||||
Uint32 m_noOfKeys;
|
||||
unsigned short m_sizeOfKeysInWords;
|
||||
unsigned short m_noOfBlobs;
|
||||
Uint8 m_noOfKeys;
|
||||
Uint8 m_noOfDistributionKeys;
|
||||
Uint8 m_noOfBlobs;
|
||||
|
||||
/**
|
||||
* Equality/assign
|
||||
|
|
|
@ -28,9 +28,7 @@
|
|||
|
||||
NdbIndexOperation::NdbIndexOperation(Ndb* aNdb) :
|
||||
NdbOperation(aNdb),
|
||||
m_theIndex(NULL),
|
||||
m_theIndexLen(0),
|
||||
m_theNoOfIndexDefined(0)
|
||||
m_theIndex(NULL)
|
||||
{
|
||||
m_tcReqGSN = GSN_TCINDXREQ;
|
||||
m_attrInfoGSN = GSN_INDXATTRINFO;
|
||||
|
@ -71,18 +69,8 @@ NdbIndexOperation::indxInit(const NdbIndexImpl * anIndex,
|
|||
return -1;
|
||||
}
|
||||
m_theIndex = anIndex;
|
||||
m_thePrimaryTable = aTable;
|
||||
m_accessTable = anIndex->m_table;
|
||||
m_theIndexLen = 0;
|
||||
m_theNoOfIndexDefined = 0;
|
||||
for (Uint32 i=0; i<NDB_MAX_ATTRIBUTES_IN_INDEX; i++)
|
||||
for (int j=0; j<3; j++)
|
||||
m_theIndexDefined[i][j] = false;
|
||||
|
||||
TcIndxReq * const tcIndxReq = CAST_PTR(TcIndxReq, theTCREQ->getDataPtrSend());
|
||||
tcIndxReq->scanInfo = 0;
|
||||
theKEYINFOptr = &tcIndxReq->keyInfo[0];
|
||||
theATTRINFOptr = &tcIndxReq->attrInfo[0];
|
||||
theNoOfTupKeyLeft = m_accessTable->getNoOfPrimaryKeys();
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -179,310 +167,6 @@ int NdbIndexOperation::interpretedDeleteTuple()
|
|||
return NdbOperation::interpretedDeleteTuple();
|
||||
}
|
||||
|
||||
int NdbIndexOperation::equal_impl(const NdbColumnImpl* tAttrInfo,
|
||||
const char* aValuePassed,
|
||||
Uint32 aVariableKeyLen)
|
||||
{
|
||||
register Uint32 tAttrId;
|
||||
|
||||
Uint32 tData;
|
||||
Uint32 tKeyInfoPosition;
|
||||
const char* aValue = aValuePassed;
|
||||
Uint32 xfrmData[1024];
|
||||
Uint32 tempData[1024];
|
||||
|
||||
if ((theStatus == OperationDefined) &&
|
||||
(aValue != NULL) &&
|
||||
(tAttrInfo != NULL )) {
|
||||
/************************************************************************
|
||||
* Start by checking that the attribute is an index key.
|
||||
* This value is also the word order in the tuple key of this
|
||||
* tuple key attribute.
|
||||
* Then check that this tuple key has not already been defined.
|
||||
* Finally check if all tuple key attributes have been defined. If
|
||||
* this is true then set Operation state to tuple key defined.
|
||||
************************************************************************/
|
||||
tAttrId = tAttrInfo->m_attrId;
|
||||
tKeyInfoPosition = tAttrInfo->m_keyInfoPos;
|
||||
Uint32 i = 0;
|
||||
|
||||
// Check that the attribute is part if the index attributes
|
||||
// by checking if it is a primary key attribute of index table
|
||||
if (tAttrInfo->m_pk) {
|
||||
Uint32 tKeyDefined = theTupleKeyDefined[0][2];
|
||||
Uint32 tKeyAttrId = theTupleKeyDefined[0][0];
|
||||
do {
|
||||
if (tKeyDefined == false) {
|
||||
goto keyEntryFound;
|
||||
} else {
|
||||
if (tKeyAttrId != tAttrId) {
|
||||
/******************************************************************
|
||||
* We read the key defined variable in advance.
|
||||
* It could potentially read outside its area when
|
||||
* i = MAXNROFTUPLEKEY - 1,
|
||||
* it is not a problem as long as the variable
|
||||
* theTupleKeyDefined is defined
|
||||
* in the middle of the object.
|
||||
* Reading wrong data and not using it causes no problems.
|
||||
*****************************************************************/
|
||||
i++;
|
||||
tKeyAttrId = theTupleKeyDefined[i][0];
|
||||
tKeyDefined = theTupleKeyDefined[i][2];
|
||||
continue;
|
||||
} else {
|
||||
goto equal_error2;
|
||||
}//if
|
||||
}//if
|
||||
} while (i < NDB_MAX_ATTRIBUTES_IN_INDEX);
|
||||
goto equal_error2;
|
||||
} else {
|
||||
goto equal_error1;
|
||||
}
|
||||
/**************************************************************************
|
||||
* Now it is time to retrieve the tuple key data from the pointer supplied
|
||||
* by the application.
|
||||
* We have to retrieve the size of the attribute in words and bits.
|
||||
*************************************************************************/
|
||||
keyEntryFound:
|
||||
m_theIndexDefined[i][0] = tAttrId;
|
||||
m_theIndexDefined[i][1] = tKeyInfoPosition;
|
||||
m_theIndexDefined[i][2] = true;
|
||||
|
||||
Uint32 sizeInBytes = tAttrInfo->m_attrSize * tAttrInfo->m_arraySize;
|
||||
{
|
||||
/*************************************************************************
|
||||
* Check if the pointer of the value passed is aligned on a 4 byte
|
||||
* boundary. If so only assign the pointer to the internal variable
|
||||
* aValue. If it is not aligned then we start by copying the value to
|
||||
* tempData and use this as aValue instead.
|
||||
*************************************************************************/
|
||||
const int attributeSize = sizeInBytes;
|
||||
const int slack = sizeInBytes & 3;
|
||||
if ((((UintPtr)aValue & 3) != 0) || (slack != 0)){
|
||||
memcpy(&tempData[0], aValue, attributeSize);
|
||||
aValue = (char*)&tempData[0];
|
||||
if(slack != 0) {
|
||||
char * tmp = (char*)&tempData[0];
|
||||
memset(&tmp[attributeSize], 0, (4 - slack));
|
||||
}//if
|
||||
}//if
|
||||
}
|
||||
const char* aValueToWrite = aValue;
|
||||
|
||||
CHARSET_INFO* cs = tAttrInfo->m_cs;
|
||||
if (cs != 0) {
|
||||
// current limitation: strxfrm does not increase length
|
||||
assert(cs->strxfrm_multiply == 1);
|
||||
unsigned n =
|
||||
(*cs->coll->strnxfrm)(cs,
|
||||
(uchar*)xfrmData, sizeof(xfrmData),
|
||||
(const uchar*)aValue, sizeInBytes);
|
||||
while (n < sizeInBytes)
|
||||
((uchar*)xfrmData)[n++] = 0x20;
|
||||
aValue = (char*)xfrmData;
|
||||
}
|
||||
|
||||
Uint32 bitsInLastWord = 8 * (sizeInBytes & 3) ;
|
||||
Uint32 totalSizeInWords = (sizeInBytes + 3)/4;// Inc. bits in last word
|
||||
Uint32 sizeInWords = sizeInBytes / 4; // Exc. bits in last word
|
||||
|
||||
if (true){ //tArraySize != 0) {
|
||||
Uint32 tIndexLen = m_theIndexLen;
|
||||
|
||||
m_theIndexLen = tIndexLen + totalSizeInWords;
|
||||
if ((aVariableKeyLen == sizeInBytes) ||
|
||||
(aVariableKeyLen == 0)) {
|
||||
;
|
||||
} else {
|
||||
goto equal_error3;
|
||||
}
|
||||
}
|
||||
#if 0
|
||||
else {
|
||||
/************************************************************************
|
||||
* The attribute is a variable array. We need to use the length parameter
|
||||
* to know the size of this attribute in the key information and
|
||||
* variable area. A key is however not allowed to be larger than 4
|
||||
* kBytes and this is checked for variable array attributes
|
||||
* used as keys.
|
||||
***********************************************************************/
|
||||
Uint32 tMaxVariableKeyLenInWord = (MAXTUPLEKEYLENOFATTERIBUTEINWORD -
|
||||
tKeyInfoPosition);
|
||||
tAttrSizeInBits = aVariableKeyLen << 3;
|
||||
tAttrSizeInWords = tAttrSizeInBits >> 5;
|
||||
tAttrBitsInLastWord = tAttrSizeInBits - (tAttrSizeInWords << 5);
|
||||
tAttrLenInWords = ((tAttrSizeInBits + 31) >> 5);
|
||||
if (tAttrLenInWords > tMaxVariableKeyLenInWord) {
|
||||
setErrorCodeAbort(4207);
|
||||
return -1;
|
||||
}//if
|
||||
m_theIndexLen = m_theIndexLen + tAttrLenInWords;
|
||||
}//if
|
||||
#endif
|
||||
int tDistrKey = tAttrInfo->m_distributionKey;
|
||||
int tDistrGroup = tAttrInfo->m_distributionGroup;
|
||||
OperationType tOpType = theOperationType;
|
||||
if ((tDistrKey != 1) && (tDistrGroup != 1)) {
|
||||
;
|
||||
} else if (tDistrKey == 1) {
|
||||
theDistrKeySize += totalSizeInWords;
|
||||
theDistrKeyIndicator = 1;
|
||||
} else {
|
||||
Uint32 TsizeInBytes = sizeInBytes;
|
||||
Uint32 TbyteOrderFix = 0;
|
||||
char* TcharByteOrderFix = (char*)&TbyteOrderFix;
|
||||
if (tAttrInfo->m_distributionGroupBits == 8) {
|
||||
char tFirstChar = aValue[TsizeInBytes - 2];
|
||||
char tSecondChar = aValue[TsizeInBytes - 2];
|
||||
TcharByteOrderFix[0] = tFirstChar;
|
||||
TcharByteOrderFix[1] = tSecondChar;
|
||||
TcharByteOrderFix[2] = 0x30;
|
||||
TcharByteOrderFix[3] = 0x30;
|
||||
theDistrGroupType = 0;
|
||||
} else {
|
||||
TbyteOrderFix = ((aValue[TsizeInBytes - 2] - 0x30) * 10)
|
||||
+ (aValue[TsizeInBytes - 1] - 0x30);
|
||||
theDistrGroupType = 1;
|
||||
}//if
|
||||
theDistributionGroup = TbyteOrderFix;
|
||||
theDistrGroupIndicator = 1;
|
||||
}//if
|
||||
/**************************************************************************
|
||||
* If the operation is a write request and the attribute is stored then
|
||||
* we also set the value in the stored part through putting the
|
||||
* information in the INDXATTRINFO signals.
|
||||
*************************************************************************/
|
||||
if ((tOpType == WriteRequest)) {
|
||||
if (!tAttrInfo->m_indexOnly){
|
||||
// invalid data can crash kernel
|
||||
if (cs != NULL &&
|
||||
(*cs->cset->well_formed_len)(cs,
|
||||
aValueToWrite,
|
||||
aValueToWrite + sizeInBytes,
|
||||
sizeInBytes) != sizeInBytes)
|
||||
goto equal_error4;
|
||||
Uint32 ahValue;
|
||||
Uint32 sz = totalSizeInWords;
|
||||
/*
|
||||
* XXX should be linked in metadata but cannot now because
|
||||
* things can be defined in arbitrary order
|
||||
*/
|
||||
const NdbColumnImpl* primaryCol = m_thePrimaryTable->getColumn(tAttrInfo->m_name.c_str());
|
||||
assert(primaryCol != NULL);
|
||||
AttributeHeader::init(&ahValue, primaryCol->m_attrId, sz);
|
||||
insertATTRINFO( ahValue );
|
||||
insertATTRINFOloop((Uint32*)aValueToWrite, sizeInWords);
|
||||
if (bitsInLastWord != 0) {
|
||||
tData = *(Uint32*)(aValueToWrite + (sizeInWords << 2));
|
||||
tData = convertEndian(tData);
|
||||
tData = tData & ((1 << bitsInLastWord) - 1);
|
||||
tData = convertEndian(tData);
|
||||
insertATTRINFO( tData );
|
||||
}//if
|
||||
}//if
|
||||
}//if
|
||||
/**************************************************************************
|
||||
* Store the Key information in the TCINDXREQ and INDXKEYINFO signals.
|
||||
*************************************************************************/
|
||||
if (insertKEYINFO(aValue, tKeyInfoPosition,
|
||||
totalSizeInWords, bitsInLastWord) != -1) {
|
||||
/************************************************************************
|
||||
* Add one to number of tuple key attributes defined.
|
||||
* If all have been defined then set the operation state to indicate
|
||||
* that tuple key is defined.
|
||||
* Thereby no more search conditions are allowed in this version.
|
||||
***********************************************************************/
|
||||
Uint32 tNoIndexDef = m_theNoOfIndexDefined;
|
||||
Uint32 tErrorLine = theErrorLine;
|
||||
int tNoIndexAttrs = m_theIndex->m_columns.size();
|
||||
unsigned char tInterpretInd = theInterpretIndicator;
|
||||
tNoIndexDef++;
|
||||
m_theNoOfIndexDefined = tNoIndexDef;
|
||||
tErrorLine++;
|
||||
theErrorLine = tErrorLine;
|
||||
if (int(tNoIndexDef) == tNoIndexAttrs) {
|
||||
if (tOpType == UpdateRequest) {
|
||||
if (tInterpretInd == 1) {
|
||||
theStatus = GetValue;
|
||||
} else {
|
||||
theStatus = SetValue;
|
||||
}//if
|
||||
return 0;
|
||||
} else if ((tOpType == ReadRequest) || (tOpType == DeleteRequest) ||
|
||||
(tOpType == ReadExclusive)) {
|
||||
theStatus = GetValue;
|
||||
// create blob handles automatically
|
||||
if (tOpType == DeleteRequest && m_currentTable->m_noOfBlobs != 0) {
|
||||
for (unsigned i = 0; i < m_currentTable->m_columns.size(); i++) {
|
||||
NdbColumnImpl* c = m_currentTable->m_columns[i];
|
||||
assert(c != 0);
|
||||
if (c->getBlobType()) {
|
||||
if (getBlobHandle(theNdbCon, c) == NULL)
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
} else if ((tOpType == InsertRequest) || (tOpType == WriteRequest)) {
|
||||
theStatus = SetValue;
|
||||
return 0;
|
||||
} else {
|
||||
setErrorCodeAbort(4005);
|
||||
return -1;
|
||||
}//if
|
||||
}//if
|
||||
return 0;
|
||||
} else {
|
||||
|
||||
return -1;
|
||||
}//if
|
||||
} else {
|
||||
if (theStatus != OperationDefined) {
|
||||
return -1;
|
||||
}//if
|
||||
|
||||
if (aValue == NULL) {
|
||||
setErrorCodeAbort(4505);
|
||||
return -1;
|
||||
}//if
|
||||
|
||||
if ( tAttrInfo == NULL ) {
|
||||
setErrorCodeAbort(4004);
|
||||
return -1;
|
||||
}//if
|
||||
}//if
|
||||
return -1;
|
||||
|
||||
equal_error1:
|
||||
setErrorCodeAbort(4205);
|
||||
return -1;
|
||||
|
||||
equal_error2:
|
||||
setErrorCodeAbort(4206);
|
||||
return -1;
|
||||
|
||||
equal_error3:
|
||||
setErrorCodeAbort(4209);
|
||||
return -1;
|
||||
|
||||
equal_error4:
|
||||
setErrorCodeAbort(744);
|
||||
return -1;
|
||||
}
|
||||
|
||||
int NdbIndexOperation::executeCursor(int aProcessorId)
|
||||
{
|
||||
printf("NdbIndexOperation::executeCursor NYI\n");
|
||||
// NYI
|
||||
return -1;
|
||||
}
|
||||
void
|
||||
NdbIndexOperation::setLastFlag(NdbApiSignal* signal, Uint32 lastFlag)
|
||||
{
|
||||
TcIndxReq * const req = CAST_PTR(TcIndxReq, signal->getDataPtrSend());
|
||||
TcKeyReq::setExecuteFlag(req->requestInfo, lastFlag);
|
||||
}
|
||||
|
||||
int
|
||||
NdbIndexOperation::prepareSend(Uint32 aTC_ConnectPtr, Uint64 aTransactionId)
|
||||
{
|
||||
|
@ -523,18 +207,18 @@ NdbIndexOperation::prepareSend(Uint32 aTC_ConnectPtr, Uint64 aTransactionId)
|
|||
// We start by filling in the first 8 unconditional words of the
|
||||
// TCINDXREQ signal.
|
||||
//-------------------------------------------------------------
|
||||
TcIndxReq * const tcIndxReq =
|
||||
CAST_PTR(TcIndxReq, theTCREQ->getDataPtrSend());
|
||||
TcKeyReq * tcKeyReq =
|
||||
CAST_PTR(TcKeyReq, theTCREQ->getDataPtrSend());
|
||||
|
||||
Uint32 tTotalCurrAI_Len = theTotalCurrAI_Len;
|
||||
Uint32 tIndexId = m_theIndex->m_indexId;
|
||||
Uint32 tSchemaVersion = m_theIndex->m_version;
|
||||
|
||||
tcIndxReq->apiConnectPtr = aTC_ConnectPtr;
|
||||
tcIndxReq->senderData = ptr2int();
|
||||
tcIndxReq->attrLen = tTotalCurrAI_Len;
|
||||
tcIndxReq->indexId = tIndexId;
|
||||
tcIndxReq->indexSchemaVersion = tSchemaVersion;
|
||||
tcKeyReq->apiConnectPtr = aTC_ConnectPtr;
|
||||
tcKeyReq->senderData = ptr2int();
|
||||
tcKeyReq->attrLen = tTotalCurrAI_Len;
|
||||
tcKeyReq->tableId = tIndexId;
|
||||
tcKeyReq->tableSchemaVersion = tSchemaVersion;
|
||||
|
||||
tTransId1 = (Uint32) aTransactionId;
|
||||
tTransId2 = (Uint32) (aTransactionId >> 32);
|
||||
|
@ -562,59 +246,53 @@ NdbIndexOperation::prepareSend(Uint32 aTC_ConnectPtr, Uint64 aTransactionId)
|
|||
Uint8 tSimpleState = tReadInd & tSimpleAlt;
|
||||
//theNdbCon->theSimpleState = tSimpleState;
|
||||
|
||||
tcIndxReq->transId1 = tTransId1;
|
||||
tcIndxReq->transId2 = tTransId2;
|
||||
tcKeyReq->transId1 = tTransId1;
|
||||
tcKeyReq->transId2 = tTransId2;
|
||||
|
||||
tReqInfo = 0;
|
||||
|
||||
if (tTotalCurrAI_Len <= TcIndxReq::MaxAttrInfo) {
|
||||
tcIndxReq->setAIInTcIndxReq(tReqInfo, tTotalCurrAI_Len);
|
||||
if (tTotalCurrAI_Len <= TcKeyReq::MaxAttrInfo) {
|
||||
tcKeyReq->setAIInTcKeyReq(tReqInfo, tTotalCurrAI_Len);
|
||||
} else {
|
||||
tcIndxReq->setAIInTcIndxReq(tReqInfo, TcIndxReq::MaxAttrInfo);
|
||||
tcKeyReq->setAIInTcKeyReq(tReqInfo, TcKeyReq::MaxAttrInfo);
|
||||
}//if
|
||||
|
||||
tcIndxReq->setSimpleFlag(tReqInfo, tSimpleIndicator);
|
||||
tcIndxReq->setCommitFlag(tReqInfo, tCommitIndicator);
|
||||
tcIndxReq->setStartFlag(tReqInfo, tStartIndicator);
|
||||
tcKeyReq->setSimpleFlag(tReqInfo, tSimpleIndicator);
|
||||
tcKeyReq->setCommitFlag(tReqInfo, tCommitIndicator);
|
||||
tcKeyReq->setStartFlag(tReqInfo, tStartIndicator);
|
||||
const Uint8 tInterpretIndicator = theInterpretIndicator;
|
||||
tcIndxReq->setInterpretedFlag(tReqInfo, tInterpretIndicator);
|
||||
tcKeyReq->setInterpretedFlag(tReqInfo, tInterpretIndicator);
|
||||
|
||||
Uint8 tDirtyIndicator = theDirtyIndicator;
|
||||
OperationType tOperationType = theOperationType;
|
||||
Uint32 tIndexLen = m_theIndexLen;
|
||||
Uint32 tIndexLen = theTupKeyLen;
|
||||
Uint8 abortOption = theNdbCon->m_abortOption;
|
||||
|
||||
tcIndxReq->setDirtyFlag(tReqInfo, tDirtyIndicator);
|
||||
tcIndxReq->setOperationType(tReqInfo, tOperationType);
|
||||
tcIndxReq->setIndexLength(tReqInfo, tIndexLen);
|
||||
tcIndxReq->setCommitType(tReqInfo, abortOption);
|
||||
tcKeyReq->setDirtyFlag(tReqInfo, tDirtyIndicator);
|
||||
tcKeyReq->setOperationType(tReqInfo, tOperationType);
|
||||
tcKeyReq->setKeyLength(tReqInfo, tIndexLen);
|
||||
tcKeyReq->setAbortOption(tReqInfo, abortOption);
|
||||
|
||||
Uint8 tDistrKeyIndicator = theDistrKeyIndicator;
|
||||
Uint8 tDistrGroupIndicator = theDistrGroupIndicator;
|
||||
Uint8 tDistrGroupType = theDistrGroupType;
|
||||
Uint8 tDistrKeyIndicator = theDistrKeyIndicator_;
|
||||
Uint8 tScanIndicator = theScanInfo & 1;
|
||||
|
||||
tcIndxReq->setDistributionGroupFlag(tReqInfo, tDistrGroupIndicator);
|
||||
tcIndxReq->setDistributionGroupTypeFlag(tReqInfo, tDistrGroupType);
|
||||
tcIndxReq->setDistributionKeyFlag(tReqInfo, tDistrKeyIndicator);
|
||||
tcIndxReq->setScanIndFlag(tReqInfo, tScanIndicator);
|
||||
tcKeyReq->setDistributionKeyFlag(tReqInfo, tDistrKeyIndicator);
|
||||
tcKeyReq->setScanIndFlag(tReqInfo, tScanIndicator);
|
||||
|
||||
tcIndxReq->requestInfo = tReqInfo;
|
||||
tcKeyReq->requestInfo = tReqInfo;
|
||||
|
||||
//-------------------------------------------------------------
|
||||
// The next step is to fill in the upto three conditional words.
|
||||
//-------------------------------------------------------------
|
||||
Uint32* tOptionalDataPtr = &tcIndxReq->scanInfo;
|
||||
Uint32* tOptionalDataPtr = &tcKeyReq->scanInfo;
|
||||
Uint32 tDistrGHIndex = tScanIndicator;
|
||||
Uint32 tDistrKeyIndex = tDistrGHIndex + tDistrGroupIndicator;
|
||||
Uint32 tDistrKeyIndex = tDistrGHIndex;
|
||||
|
||||
Uint32 tScanInfo = theScanInfo;
|
||||
Uint32 tDistributionGroup = theDistributionGroup;
|
||||
Uint32 tDistrKeySize = theDistrKeySize;
|
||||
Uint32 tDistrKey = theDistributionKey;
|
||||
|
||||
tOptionalDataPtr[0] = tScanInfo;
|
||||
tOptionalDataPtr[tDistrGHIndex] = tDistributionGroup;
|
||||
tOptionalDataPtr[tDistrKeyIndex] = tDistrKeySize;
|
||||
tOptionalDataPtr[tDistrKeyIndex] = tDistrKey;
|
||||
|
||||
//-------------------------------------------------------------
|
||||
// The next is step is to compress the key data part of the
|
||||
|
@ -622,10 +300,10 @@ NdbIndexOperation::prepareSend(Uint32 aTC_ConnectPtr, Uint64 aTransactionId)
|
|||
//-------------------------------------------------------------
|
||||
Uint32 tKeyIndex = tDistrKeyIndex + tDistrKeyIndicator;
|
||||
Uint32* tKeyDataPtr = &tOptionalDataPtr[tKeyIndex];
|
||||
Uint32 Tdata1 = tcIndxReq->keyInfo[0];
|
||||
Uint32 Tdata2 = tcIndxReq->keyInfo[1];
|
||||
Uint32 Tdata3 = tcIndxReq->keyInfo[2];
|
||||
Uint32 Tdata4 = tcIndxReq->keyInfo[3];
|
||||
Uint32 Tdata1 = tcKeyReq->keyInfo[0];
|
||||
Uint32 Tdata2 = tcKeyReq->keyInfo[1];
|
||||
Uint32 Tdata3 = tcKeyReq->keyInfo[2];
|
||||
Uint32 Tdata4 = tcKeyReq->keyInfo[3];
|
||||
Uint32 Tdata5;
|
||||
|
||||
tKeyDataPtr[0] = Tdata1;
|
||||
|
@ -633,10 +311,10 @@ NdbIndexOperation::prepareSend(Uint32 aTC_ConnectPtr, Uint64 aTransactionId)
|
|||
tKeyDataPtr[2] = Tdata3;
|
||||
tKeyDataPtr[3] = Tdata4;
|
||||
if (tIndexLen > 4) {
|
||||
Tdata1 = tcIndxReq->keyInfo[4];
|
||||
Tdata2 = tcIndxReq->keyInfo[5];
|
||||
Tdata3 = tcIndxReq->keyInfo[6];
|
||||
Tdata4 = tcIndxReq->keyInfo[7];
|
||||
Tdata1 = tcKeyReq->keyInfo[4];
|
||||
Tdata2 = tcKeyReq->keyInfo[5];
|
||||
Tdata3 = tcKeyReq->keyInfo[6];
|
||||
Tdata4 = tcKeyReq->keyInfo[7];
|
||||
|
||||
tKeyDataPtr[4] = Tdata1;
|
||||
tKeyDataPtr[5] = Tdata2;
|
||||
|
@ -650,12 +328,12 @@ NdbIndexOperation::prepareSend(Uint32 aTC_ConnectPtr, Uint64 aTransactionId)
|
|||
//-------------------------------------------------------------
|
||||
Uint32 tAttrInfoIndex;
|
||||
|
||||
if (tIndexLen > TcIndxReq::MaxKeyInfo) {
|
||||
if (tIndexLen > TcKeyReq::MaxKeyInfo) {
|
||||
/**
|
||||
* Set transid and TC connect ptr in the INDXKEYINFO signals
|
||||
*/
|
||||
NdbApiSignal* tSignal = theFirstKEYINFO;
|
||||
Uint32 remainingKey = tIndexLen - TcIndxReq::MaxKeyInfo;
|
||||
NdbApiSignal* tSignal = theTCREQ->next();
|
||||
Uint32 remainingKey = tIndexLen - TcKeyReq::MaxKeyInfo;
|
||||
|
||||
do {
|
||||
Uint32* tSigDataPtr = tSignal->getDataPtrSend();
|
||||
|
@ -676,7 +354,7 @@ NdbIndexOperation::prepareSend(Uint32 aTC_ConnectPtr, Uint64 aTransactionId)
|
|||
}
|
||||
tSignal = tnextSignal;
|
||||
} while (tSignal != NULL);
|
||||
tAttrInfoIndex = tKeyIndex + TcIndxReq::MaxKeyInfo;
|
||||
tAttrInfoIndex = tKeyIndex + TcKeyReq::MaxKeyInfo;
|
||||
} else {
|
||||
tAttrInfoIndex = tKeyIndex + tIndexLen;
|
||||
}//if
|
||||
|
@ -686,14 +364,14 @@ NdbIndexOperation::prepareSend(Uint32 aTC_ConnectPtr, Uint64 aTransactionId)
|
|||
// above.
|
||||
//-------------------------------------------------------------
|
||||
Uint32* tAIDataPtr = &tOptionalDataPtr[tAttrInfoIndex];
|
||||
Tdata1 = tcIndxReq->attrInfo[0];
|
||||
Tdata2 = tcIndxReq->attrInfo[1];
|
||||
Tdata3 = tcIndxReq->attrInfo[2];
|
||||
Tdata4 = tcIndxReq->attrInfo[3];
|
||||
Tdata5 = tcIndxReq->attrInfo[4];
|
||||
Tdata1 = tcKeyReq->attrInfo[0];
|
||||
Tdata2 = tcKeyReq->attrInfo[1];
|
||||
Tdata3 = tcKeyReq->attrInfo[2];
|
||||
Tdata4 = tcKeyReq->attrInfo[3];
|
||||
Tdata5 = tcKeyReq->attrInfo[4];
|
||||
|
||||
theTCREQ->setLength(tcIndxReq->getAIInTcIndxReq(tReqInfo) +
|
||||
tAttrInfoIndex + TcIndxReq::StaticLength);
|
||||
theTCREQ->setLength(tcKeyReq->getAIInTcKeyReq(tReqInfo) +
|
||||
tAttrInfoIndex + TcKeyReq::StaticLength);
|
||||
tAIDataPtr[0] = Tdata1;
|
||||
tAIDataPtr[1] = Tdata2;
|
||||
tAIDataPtr[2] = Tdata3;
|
||||
|
@ -722,11 +400,6 @@ NdbIndexOperation::prepareSend(Uint32 aTC_ConnectPtr, Uint64 aTransactionId)
|
|||
return 0;
|
||||
}
|
||||
|
||||
void NdbIndexOperation::closeScan()
|
||||
{
|
||||
printf("NdbIndexOperation::closeScan NYI\n");
|
||||
}
|
||||
|
||||
/***************************************************************************
|
||||
int receiveTCINDXREF( NdbApiSignal* aSignal)
|
||||
|
||||
|
|
|
@ -49,7 +49,6 @@ NdbOperation::NdbOperation(Ndb* aNdb) :
|
|||
theCurrentATTRINFO(NULL),
|
||||
theTotalCurrAI_Len(0),
|
||||
theAI_LenInCurrAI(0),
|
||||
theFirstKEYINFO(NULL),
|
||||
theLastKEYINFO(NULL),
|
||||
|
||||
theFirstLabel(NULL),
|
||||
|
@ -68,13 +67,11 @@ NdbOperation::NdbOperation(Ndb* aNdb) :
|
|||
//theSchemaVersion(0),
|
||||
theTotalNrOfKeyWordInSignal(8),
|
||||
theTupKeyLen(0),
|
||||
theNoOfTupKeyDefined(0),
|
||||
theNoOfTupKeyLeft(0),
|
||||
theOperationType(NotDefined),
|
||||
theStatus(Init),
|
||||
theMagicNumber(0xFE11D0),
|
||||
theScanInfo(0),
|
||||
theDistrKeySize(0),
|
||||
theDistributionGroup(0),
|
||||
m_tcReqGSN(GSN_TCKEYREQ),
|
||||
m_keyInfoGSN(GSN_KEYINFO),
|
||||
m_attrInfoGSN(GSN_ATTRINFO),
|
||||
|
@ -145,14 +142,11 @@ NdbOperation::init(const NdbTableImpl* tab, NdbConnection* myConnection){
|
|||
|
||||
theFirstATTRINFO = NULL;
|
||||
theCurrentATTRINFO = NULL;
|
||||
theFirstKEYINFO = NULL;
|
||||
theLastKEYINFO = NULL;
|
||||
|
||||
|
||||
theTupKeyLen = 0;
|
||||
theNoOfTupKeyDefined = 0;
|
||||
theDistrKeySize = 0;
|
||||
theDistributionGroup = 0;
|
||||
theTupKeyLen = 0;
|
||||
theNoOfTupKeyLeft = tab->getNoOfPrimaryKeys();
|
||||
|
||||
theTotalCurrAI_Len = 0;
|
||||
theAI_LenInCurrAI = 0;
|
||||
|
@ -161,9 +155,7 @@ NdbOperation::init(const NdbTableImpl* tab, NdbConnection* myConnection){
|
|||
theSimpleIndicator = 0;
|
||||
theDirtyIndicator = 0;
|
||||
theInterpretIndicator = 0;
|
||||
theDistrGroupIndicator= 0;
|
||||
theDistrGroupType = 0;
|
||||
theDistrKeyIndicator = 0;
|
||||
theDistrKeyIndicator_ = 0;
|
||||
theScanInfo = 0;
|
||||
theTotalNrOfKeyWordInSignal = 8;
|
||||
theMagicNumber = 0xABCDEF01;
|
||||
|
@ -210,11 +202,16 @@ NdbOperation::release()
|
|||
NdbBlob* tBlob;
|
||||
NdbBlob* tSaveBlob;
|
||||
|
||||
if (theTCREQ != NULL)
|
||||
tSignal = theTCREQ;
|
||||
while (tSignal != NULL)
|
||||
{
|
||||
theNdb->releaseSignal(theTCREQ);
|
||||
}
|
||||
tSaveSignal = tSignal;
|
||||
tSignal = tSignal->next();
|
||||
theNdb->releaseSignal(tSaveSignal);
|
||||
}
|
||||
theTCREQ = NULL;
|
||||
theLastKEYINFO = NULL;
|
||||
|
||||
tSignal = theFirstATTRINFO;
|
||||
while (tSignal != NULL)
|
||||
{
|
||||
|
@ -224,15 +221,7 @@ NdbOperation::release()
|
|||
}
|
||||
theFirstATTRINFO = NULL;
|
||||
theCurrentATTRINFO = NULL;
|
||||
tSignal = theFirstKEYINFO;
|
||||
while (tSignal != NULL)
|
||||
{
|
||||
tSaveSignal = tSignal;
|
||||
tSignal = tSignal->next();
|
||||
theNdb->releaseSignal(tSaveSignal);
|
||||
}
|
||||
theFirstKEYINFO = NULL;
|
||||
theLastKEYINFO = NULL;
|
||||
|
||||
if (theInterpretIndicator == 1)
|
||||
{
|
||||
tBranch = theFirstBranch;
|
||||
|
|
|
@ -350,7 +350,6 @@ NdbOperation::getValue_impl(const NdbColumnImpl* tAttrInfo, char* aValue)
|
|||
{
|
||||
NdbRecAttr* tRecAttr;
|
||||
if ((tAttrInfo != NULL) &&
|
||||
(!tAttrInfo->m_indexOnly) &&
|
||||
(theStatus != Init)){
|
||||
if (theStatus != GetValue) {
|
||||
if (theInterpretIndicator == 1) {
|
||||
|
@ -398,10 +397,6 @@ NdbOperation::getValue_impl(const NdbColumnImpl* tAttrInfo, char* aValue)
|
|||
setErrorCodeAbort(4004);
|
||||
return NULL;
|
||||
}//if
|
||||
if (tAttrInfo->m_indexOnly){
|
||||
setErrorCodeAbort(4208);
|
||||
return NULL;
|
||||
}//if
|
||||
}//if
|
||||
setErrorCodeAbort(4200);
|
||||
return NULL;
|
||||
|
|
|
@ -65,7 +65,7 @@ NdbOperation::doSend(int aNodeId, Uint32 lastFlag)
|
|||
if (tReturnCode == -1) {
|
||||
return -1;
|
||||
}
|
||||
NdbApiSignal *tSignal = theFirstKEYINFO;
|
||||
NdbApiSignal *tSignal = theTCREQ->next();
|
||||
while (tSignal != NULL) {
|
||||
NdbApiSignal* tnextSignal = tSignal->next();
|
||||
tReturnCode = tp->sendSignal(tSignal, aNodeId);
|
||||
|
@ -202,13 +202,9 @@ NdbOperation::prepareSend(Uint32 aTC_ConnectPtr, Uint64 aTransId)
|
|||
abortOption = tSimpleIndicator ? IgnoreError : abortOption;
|
||||
tcKeyReq->setAbortOption(tReqInfo, abortOption);
|
||||
|
||||
Uint8 tDistrKeyIndicator = theDistrKeyIndicator;
|
||||
Uint8 tDistrGroupIndicator = theDistrGroupIndicator;
|
||||
Uint8 tDistrGroupType = theDistrGroupType;
|
||||
Uint8 tDistrKeyIndicator = theDistrKeyIndicator_;
|
||||
Uint8 tScanIndicator = theScanInfo & 1;
|
||||
|
||||
tcKeyReq->setDistributionGroupFlag(tReqInfo, tDistrGroupIndicator);
|
||||
tcKeyReq->setDistributionGroupTypeFlag(tReqInfo, tDistrGroupType);
|
||||
tcKeyReq->setDistributionKeyFlag(tReqInfo, tDistrKeyIndicator);
|
||||
tcKeyReq->setScanIndFlag(tReqInfo, tScanIndicator);
|
||||
|
||||
|
@ -219,15 +215,13 @@ NdbOperation::prepareSend(Uint32 aTC_ConnectPtr, Uint64 aTransId)
|
|||
//-------------------------------------------------------------
|
||||
Uint32* tOptionalDataPtr = &tcKeyReq->scanInfo;
|
||||
Uint32 tDistrGHIndex = tScanIndicator;
|
||||
Uint32 tDistrKeyIndex = tDistrGHIndex + tDistrGroupIndicator;
|
||||
Uint32 tDistrKeyIndex = tDistrGHIndex;
|
||||
|
||||
Uint32 tScanInfo = theScanInfo;
|
||||
Uint32 tDistributionGroup = theDistributionGroup;
|
||||
Uint32 tDistrKeySize = theDistrKeySize;
|
||||
Uint32 tDistrKey = theDistributionKey;
|
||||
|
||||
tOptionalDataPtr[0] = tScanInfo;
|
||||
tOptionalDataPtr[tDistrGHIndex] = tDistributionGroup;
|
||||
tOptionalDataPtr[tDistrKeyIndex] = tDistrKeySize;
|
||||
tOptionalDataPtr[tDistrKeyIndex] = tDistrKey;
|
||||
|
||||
//-------------------------------------------------------------
|
||||
// The next is step is to compress the key data part of the
|
||||
|
@ -267,7 +261,7 @@ NdbOperation::prepareSend(Uint32 aTC_ConnectPtr, Uint64 aTransId)
|
|||
/**
|
||||
* Set transid, TC connect ptr and length in the KEYINFO signals
|
||||
*/
|
||||
NdbApiSignal* tSignal = theFirstKEYINFO;
|
||||
NdbApiSignal* tSignal = theTCREQ->next();
|
||||
Uint32 remainingKey = tTupKeyLen - TcKeyReq::MaxKeyInfo;
|
||||
do {
|
||||
Uint32* tSigDataPtr = tSignal->getDataPtrSend();
|
||||
|
|
|
@ -38,7 +38,9 @@ Adjust: 971022 UABMNST First version.
|
|||
|
||||
#include <AttributeHeader.hpp>
|
||||
#include <signaldata/TcKeyReq.hpp>
|
||||
#include <signaldata/KeyInfo.hpp>
|
||||
#include "NdbDictionaryImpl.hpp"
|
||||
#include <md5_hash.hpp>
|
||||
|
||||
/******************************************************************************
|
||||
CondIdType equal(const char* anAttrName, char* aValue, Uint32 aVarKeylen);
|
||||
|
@ -60,8 +62,8 @@ NdbOperation::equal_impl(const NdbColumnImpl* tAttrInfo,
|
|||
Uint32 tData;
|
||||
Uint32 tKeyInfoPosition;
|
||||
const char* aValue = aValuePassed;
|
||||
Uint32 xfrmData[1024];
|
||||
Uint32 tempData[1024];
|
||||
Uint64 xfrmData[512];
|
||||
Uint64 tempData[512];
|
||||
|
||||
if ((theStatus == OperationDefined) &&
|
||||
(aValue != NULL) &&
|
||||
|
@ -76,6 +78,8 @@ NdbOperation::equal_impl(const NdbColumnImpl* tAttrInfo,
|
|||
*****************************************************************************/
|
||||
tAttrId = tAttrInfo->m_attrId;
|
||||
tKeyInfoPosition = tAttrInfo->m_keyInfoPos;
|
||||
bool tDistrKey = tAttrInfo->m_distributionKey;
|
||||
|
||||
Uint32 i = 0;
|
||||
if (tAttrInfo->m_pk) {
|
||||
Uint32 tKeyDefined = theTupleKeyDefined[0][2];
|
||||
|
@ -119,30 +123,30 @@ NdbOperation::equal_impl(const NdbColumnImpl* tAttrInfo,
|
|||
|
||||
Uint32 sizeInBytes = tAttrInfo->m_attrSize * tAttrInfo->m_arraySize;
|
||||
{
|
||||
/***************************************************************************
|
||||
* Check if the pointer of the value passed is aligned on a 4 byte
|
||||
* boundary. If so only assign the pointer to the internal variable
|
||||
* aValue. If it is not aligned then we start by copying the value to
|
||||
* tempData and use this as aValue instead.
|
||||
*****************************************************************************/
|
||||
/************************************************************************
|
||||
* Check if the pointer of the value passed is aligned on a 4 byte
|
||||
* boundary. If so only assign the pointer to the internal variable
|
||||
* aValue. If it is not aligned then we start by copying the value to
|
||||
* tempData and use this as aValue instead.
|
||||
***********************************************************************/
|
||||
const int attributeSize = sizeInBytes;
|
||||
const int slack = sizeInBytes & 3;
|
||||
|
||||
if ((((UintPtr)aValue & 3) != 0) || (slack != 0)){
|
||||
const int align = UintPtr(aValue) & 7;
|
||||
|
||||
if (((align & 3) != 0) || (slack != 0) || (tDistrKey && (align != 0)))
|
||||
{
|
||||
((Uint32*)tempData)[attributeSize >> 2] = 0;
|
||||
memcpy(&tempData[0], aValue, attributeSize);
|
||||
aValue = (char*)&tempData[0];
|
||||
if(slack != 0) {
|
||||
char * tmp = (char*)&tempData[0];
|
||||
memset(&tmp[attributeSize], 0, (4 - slack));
|
||||
}//if
|
||||
}//if
|
||||
}
|
||||
const char* aValueToWrite = aValue;
|
||||
|
||||
|
||||
CHARSET_INFO* cs = tAttrInfo->m_cs;
|
||||
if (cs != 0) {
|
||||
// current limitation: strxfrm does not increase length
|
||||
assert(cs->strxfrm_multiply == 1);
|
||||
((Uint32*)xfrmData)[sizeInBytes >> 2] = 0;
|
||||
unsigned n =
|
||||
(*cs->coll->strnxfrm)(cs,
|
||||
(uchar*)xfrmData, sizeof(xfrmData),
|
||||
|
@ -152,9 +156,7 @@ NdbOperation::equal_impl(const NdbColumnImpl* tAttrInfo,
|
|||
aValue = (char*)xfrmData;
|
||||
}
|
||||
|
||||
Uint32 bitsInLastWord = 8 * (sizeInBytes & 3) ;
|
||||
Uint32 totalSizeInWords = (sizeInBytes + 3)/4; // Inc. bits in last word
|
||||
Uint32 sizeInWords = sizeInBytes / 4; // Exc. bits in last word
|
||||
|
||||
if (true){ //tArraySize != 0) {
|
||||
Uint32 tTupKeyLen = theTupKeyLen;
|
||||
|
@ -190,84 +192,49 @@ NdbOperation::equal_impl(const NdbColumnImpl* tAttrInfo,
|
|||
}//if
|
||||
#endif
|
||||
|
||||
int tDistrKey = tAttrInfo->m_distributionKey;
|
||||
int tDistrGroup = tAttrInfo->m_distributionGroup;
|
||||
OperationType tOpType = theOperationType;
|
||||
if ((tDistrKey != 1) && (tDistrGroup != 1)) {
|
||||
;
|
||||
} else if (tDistrKey == 1) {
|
||||
theDistrKeySize += totalSizeInWords;
|
||||
theDistrKeyIndicator = 1;
|
||||
} else {
|
||||
Uint32 TsizeInBytes = sizeInBytes;
|
||||
Uint32 TbyteOrderFix = 0;
|
||||
char* TcharByteOrderFix = (char*)&TbyteOrderFix;
|
||||
if (tAttrInfo->m_distributionGroupBits == 8) {
|
||||
char tFirstChar = aValue[TsizeInBytes - 2];
|
||||
char tSecondChar = aValue[TsizeInBytes - 2];
|
||||
TcharByteOrderFix[0] = tFirstChar;
|
||||
TcharByteOrderFix[1] = tSecondChar;
|
||||
TcharByteOrderFix[2] = 0x30;
|
||||
TcharByteOrderFix[3] = 0x30;
|
||||
theDistrGroupType = 0;
|
||||
} else {
|
||||
TbyteOrderFix = ((aValue[TsizeInBytes - 2] - 0x30) * 10)
|
||||
+ (aValue[TsizeInBytes - 1] - 0x30);
|
||||
theDistrGroupType = 1;
|
||||
}//if
|
||||
theDistributionGroup = TbyteOrderFix;
|
||||
theDistrGroupIndicator = 1;
|
||||
}//if
|
||||
/******************************************************************************
|
||||
/**************************************************************************
|
||||
* If the operation is an insert request and the attribute is stored then
|
||||
* we also set the value in the stored part through putting the
|
||||
* information in the ATTRINFO signals.
|
||||
*****************************************************************************/
|
||||
*************************************************************************/
|
||||
if ((tOpType == InsertRequest) ||
|
||||
(tOpType == WriteRequest)) {
|
||||
if (!tAttrInfo->m_indexOnly){
|
||||
// invalid data can crash kernel
|
||||
if (cs != NULL &&
|
||||
(*cs->cset->well_formed_len)(cs,
|
||||
aValueToWrite,
|
||||
aValueToWrite + sizeInBytes,
|
||||
sizeInBytes) != sizeInBytes)
|
||||
goto equal_error4;
|
||||
Uint32 ahValue;
|
||||
const Uint32 sz = totalSizeInWords;
|
||||
AttributeHeader::init(&ahValue, tAttrId, sz);
|
||||
insertATTRINFO( ahValue );
|
||||
insertATTRINFOloop((Uint32*)aValueToWrite, sizeInWords);
|
||||
if (bitsInLastWord != 0) {
|
||||
tData = *(Uint32*)(aValueToWrite + (sizeInWords << 2));
|
||||
tData = convertEndian(tData);
|
||||
tData = tData & ((1 << bitsInLastWord) - 1);
|
||||
tData = convertEndian(tData);
|
||||
insertATTRINFO( tData );
|
||||
}//if
|
||||
}//if
|
||||
// invalid data can crash kernel
|
||||
if (cs != NULL &&
|
||||
(*cs->cset->well_formed_len)(cs,
|
||||
aValueToWrite,
|
||||
aValueToWrite + sizeInBytes,
|
||||
sizeInBytes) != sizeInBytes)
|
||||
goto equal_error4;
|
||||
Uint32 ahValue;
|
||||
const Uint32 sz = totalSizeInWords;
|
||||
AttributeHeader::init(&ahValue, tAttrId, sz);
|
||||
insertATTRINFO( ahValue );
|
||||
insertATTRINFOloop((Uint32*)aValueToWrite, sz);
|
||||
}//if
|
||||
|
||||
/***************************************************************************
|
||||
/**************************************************************************
|
||||
* Store the Key information in the TCKEYREQ and KEYINFO signals.
|
||||
**************************************************************************/
|
||||
if (insertKEYINFO(aValue, tKeyInfoPosition,
|
||||
totalSizeInWords, bitsInLastWord) != -1) {
|
||||
/*************************************************************************
|
||||
*************************************************************************/
|
||||
if (insertKEYINFO(aValue, tKeyInfoPosition, totalSizeInWords) != -1) {
|
||||
/************************************************************************
|
||||
* Add one to number of tuple key attributes defined.
|
||||
* If all have been defined then set the operation state to indicate
|
||||
* that tuple key is defined.
|
||||
* Thereby no more search conditions are allowed in this version.
|
||||
************************************************************************/
|
||||
Uint32 tNoKeysDef = theNoOfTupKeyDefined;
|
||||
***********************************************************************/
|
||||
Uint32 tNoKeysDef = theNoOfTupKeyLeft - 1;
|
||||
Uint32 tErrorLine = theErrorLine;
|
||||
int tNoTableKeys = m_currentTable->m_noOfKeys;
|
||||
unsigned char tInterpretInd = theInterpretIndicator;
|
||||
tNoKeysDef++;
|
||||
theNoOfTupKeyDefined = tNoKeysDef;
|
||||
theNoOfTupKeyLeft = tNoKeysDef;
|
||||
tErrorLine++;
|
||||
theErrorLine = tErrorLine;
|
||||
if (int(tNoKeysDef) == tNoTableKeys) {
|
||||
|
||||
if(tDistrKey)
|
||||
handle_distribution_key((Uint64*)aValue, totalSizeInWords);
|
||||
|
||||
if (tNoKeysDef == 0) {
|
||||
if (tOpType == UpdateRequest) {
|
||||
if (tInterpretInd == 1) {
|
||||
theStatus = GetValue;
|
||||
|
@ -297,13 +264,14 @@ NdbOperation::equal_impl(const NdbColumnImpl* tAttrInfo,
|
|||
setErrorCodeAbort(4005);
|
||||
return -1;
|
||||
}//if
|
||||
return 0;
|
||||
}//if
|
||||
return 0;
|
||||
} else {
|
||||
return -1;
|
||||
}//if
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
if (aValue == NULL) {
|
||||
// NULL value in primary key
|
||||
setErrorCodeAbort(4505);
|
||||
|
@ -321,6 +289,8 @@ NdbOperation::equal_impl(const NdbColumnImpl* tAttrInfo,
|
|||
setErrorCodeAbort(4225);
|
||||
return -1;
|
||||
}//if
|
||||
|
||||
ndbout_c("theStatus: %d", theStatus);
|
||||
|
||||
// If we come here, set a general errorcode
|
||||
// and exit
|
||||
|
@ -387,8 +357,7 @@ NdbOperation::setTupleId()
|
|||
int
|
||||
NdbOperation::insertKEYINFO(const char* aValue,
|
||||
register Uint32 aStartPosition,
|
||||
register Uint32 anAttrSizeInWords,
|
||||
register Uint32 anAttrBitsInLastWord)
|
||||
register Uint32 anAttrSizeInWords)
|
||||
{
|
||||
NdbApiSignal* tSignal;
|
||||
NdbApiSignal* tCurrentKEYINFO;
|
||||
|
@ -408,7 +377,7 @@ NdbOperation::insertKEYINFO(const char* aValue,
|
|||
*****************************************************************************/
|
||||
tEndPos = aStartPosition + anAttrSizeInWords - 1;
|
||||
|
||||
if ((tEndPos < 9) && (anAttrBitsInLastWord == 0)) {
|
||||
if ((tEndPos < 9)) {
|
||||
register Uint32 tkeyData = *(Uint32*)aValue;
|
||||
//TcKeyReq* tcKeyReq = CAST_PTR(TcKeyReq, tTCREQ->getDataPtrSend());
|
||||
register Uint32* tDataPtr = (Uint32*)aValue;
|
||||
|
@ -449,10 +418,11 @@ NdbOperation::insertKEYINFO(const char* aValue,
|
|||
setErrorCodeAbort(4001);
|
||||
return -1;
|
||||
}
|
||||
if (theFirstKEYINFO != NULL)
|
||||
if (theTCREQ->next() != NULL)
|
||||
theLastKEYINFO->next(tSignal);
|
||||
else
|
||||
theFirstKEYINFO = tSignal;
|
||||
theTCREQ->next(tSignal);
|
||||
|
||||
theLastKEYINFO = tSignal;
|
||||
theLastKEYINFO->next(NULL);
|
||||
theTotalNrOfKeyWordInSignal += 20;
|
||||
|
@ -465,7 +435,7 @@ NdbOperation::insertKEYINFO(const char* aValue,
|
|||
* this is the first word in a KEYINFO signal. *
|
||||
*****************************************************************************/
|
||||
tPosition = aStartPosition;
|
||||
tCurrentKEYINFO = theFirstKEYINFO;
|
||||
tCurrentKEYINFO = theTCREQ->next();
|
||||
|
||||
/*****************************************************************************
|
||||
* Start by filling up Key information in the 8 words allocated in the *
|
||||
|
@ -518,39 +488,20 @@ NdbOperation::insertKEYINFO(const char* aValue,
|
|||
} while (1);
|
||||
|
||||
LastWordLabel:
|
||||
|
||||
/*****************************************************************************
|
||||
* There could be a last word that only contains partial data. This word*
|
||||
* will contain zeroes in the rest of the bits since the index expects *
|
||||
* a certain number of words and do not care for parts of words. *
|
||||
*****************************************************************************/
|
||||
if (anAttrBitsInLastWord != 0) {
|
||||
tData = *(Uint32*)(aValue + (anAttrSizeInWords - 1) * 4);
|
||||
tData = convertEndian(tData);
|
||||
tData = tData & ((1 << anAttrBitsInLastWord) - 1);
|
||||
tData = convertEndian(tData);
|
||||
if (tPosition > 8) {
|
||||
tCurrentKEYINFO->setData(tData, signalCounter);
|
||||
signalCounter++;
|
||||
} else {
|
||||
theTCREQ->setData(tData, (12 + tPosition));
|
||||
}//if
|
||||
}//if
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
NdbOperation::getKeyFromTCREQ(Uint32* data, unsigned size)
|
||||
{
|
||||
assert(m_accessTable != 0 && m_accessTable->m_sizeOfKeysInWords != 0);
|
||||
assert(m_accessTable->m_sizeOfKeysInWords == size);
|
||||
assert(m_accessTable != 0 && m_accessTable->m_keyLenInWords != 0);
|
||||
assert(m_accessTable->m_keyLenInWords == size);
|
||||
unsigned pos = 0;
|
||||
while (pos < 8 && pos < size) {
|
||||
data[pos] = theKEYINFOptr[pos];
|
||||
pos++;
|
||||
}
|
||||
NdbApiSignal* tSignal = theFirstKEYINFO;
|
||||
NdbApiSignal* tSignal = theTCREQ->next();
|
||||
unsigned n = 0;
|
||||
while (pos < size) {
|
||||
if (n == 20) {
|
||||
|
@ -561,3 +512,113 @@ NdbOperation::getKeyFromTCREQ(Uint32* data, unsigned size)
|
|||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
NdbOperation::handle_distribution_key(const Uint64* value, Uint32 len)
|
||||
{
|
||||
if(theDistrKeyIndicator_ == 1 ||
|
||||
(theNoOfTupKeyLeft > 0 && m_accessTable->m_noOfDistributionKeys > 1))
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
if(m_accessTable->m_noOfDistributionKeys == 1)
|
||||
{
|
||||
setPartitionHash(value, len);
|
||||
}
|
||||
else
|
||||
{
|
||||
/**
|
||||
* Copy distribution key to linear memory
|
||||
*/
|
||||
NdbColumnImpl* const * cols = m_accessTable->m_columns.getBase();
|
||||
Uint32 len = 0;
|
||||
Uint64 tmp[1000];
|
||||
|
||||
Uint32 chunk = 8;
|
||||
Uint32* dst = (Uint32*)tmp;
|
||||
NdbApiSignal* tSignal = theTCREQ;
|
||||
Uint32* src = ((TcKeyReq*)tSignal->getDataPtrSend())->keyInfo;
|
||||
if(tSignal->readSignalNumber() == GSN_SCAN_TABREQ)
|
||||
{
|
||||
tSignal = tSignal->next();
|
||||
src = ((KeyInfo*)tSignal->getDataPtrSend())->keyData;
|
||||
chunk = KeyInfo::DataLength;
|
||||
}
|
||||
|
||||
for(unsigned i = m_accessTable->m_columns.size(); i>0; cols++, i--)
|
||||
{
|
||||
if (!(* cols)->getPrimaryKey())
|
||||
continue;
|
||||
|
||||
NdbColumnImpl* tAttrInfo = * cols;
|
||||
Uint32 sizeInBytes = tAttrInfo->m_attrSize * tAttrInfo->m_arraySize;
|
||||
Uint32 currLen = (sizeInBytes + 3) >> 2;
|
||||
if (tAttrInfo->getDistributionKey())
|
||||
{
|
||||
while (currLen >= chunk)
|
||||
{
|
||||
memcpy(dst, src, 4*chunk);
|
||||
dst += chunk;
|
||||
tSignal = tSignal->next();
|
||||
src = ((KeyInfo*)tSignal->getDataPtrSend())->keyData;
|
||||
currLen -= chunk;
|
||||
chunk = KeyInfo::DataLength;
|
||||
}
|
||||
|
||||
memcpy(dst, src, 4*currLen);
|
||||
dst += currLen;
|
||||
src += currLen;
|
||||
chunk -= currLen;
|
||||
}
|
||||
else
|
||||
{
|
||||
while (currLen >= chunk)
|
||||
{
|
||||
tSignal = tSignal->next();
|
||||
src = ((KeyInfo*)tSignal->getDataPtrSend())->keyData;
|
||||
currLen -= chunk;
|
||||
chunk = KeyInfo::DataLength;
|
||||
}
|
||||
|
||||
src += currLen;
|
||||
chunk -= currLen;
|
||||
}
|
||||
}
|
||||
setPartitionHash(tmp, dst - (Uint32*)tmp);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
void
|
||||
NdbOperation::setPartitionHash(Uint32 value)
|
||||
{
|
||||
union {
|
||||
Uint32 tmp32;
|
||||
Uint64 tmp64;
|
||||
};
|
||||
|
||||
tmp32 = value;
|
||||
setPartitionHash(&tmp64, 1);
|
||||
}
|
||||
|
||||
void
|
||||
NdbOperation::setPartitionHash(const Uint64* value, Uint32 len)
|
||||
{
|
||||
Uint32 buf[4];
|
||||
md5_hash(buf, value, len);
|
||||
setPartitionId(buf[1]);
|
||||
}
|
||||
|
||||
void
|
||||
NdbOperation::setPartitionId(Uint32 value)
|
||||
{
|
||||
theDistributionKey = value;
|
||||
theDistrKeyIndicator_ = 1;
|
||||
}
|
||||
|
||||
Uint32
|
||||
NdbOperation::getPartitionId() const
|
||||
{
|
||||
return theDistributionKey;
|
||||
}
|
||||
|
|
|
@ -118,7 +118,7 @@ NdbScanOperation::init(const NdbTableImpl* tab, NdbConnection* myConnection)
|
|||
theStatus = GetValue;
|
||||
theOperationType = OpenScanRequest;
|
||||
theNdbCon->theMagicNumber = 0xFE11DF;
|
||||
|
||||
theNoOfTupKeyLeft = tab->m_noOfDistributionKeys;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -199,6 +199,7 @@ NdbResultSet* NdbScanOperation::readTuples(NdbScanOperation::LockMode lm,
|
|||
return 0;
|
||||
}//if
|
||||
|
||||
theSCAN_TABREQ->setSignal(GSN_SCAN_TABREQ);
|
||||
ScanTabReq * req = CAST_PTR(ScanTabReq, theSCAN_TABREQ->getDataPtrSend());
|
||||
req->apiConnectPtr = theNdbCon->theTCConPtr;
|
||||
req->tableId = m_accessTable->m_tableId;
|
||||
|
@ -219,16 +220,17 @@ NdbResultSet* NdbScanOperation::readTuples(NdbScanOperation::LockMode lm,
|
|||
req->transId1 = (Uint32) transId;
|
||||
req->transId2 = (Uint32) (transId >> 32);
|
||||
|
||||
NdbApiSignal* tSignal =
|
||||
theFirstKEYINFO;
|
||||
|
||||
theFirstKEYINFO = (tSignal ? tSignal : tSignal = theNdb->getSignal());
|
||||
NdbApiSignal* tSignal = theSCAN_TABREQ->next();
|
||||
if(!tSignal)
|
||||
{
|
||||
theSCAN_TABREQ->next(tSignal = theNdb->getSignal());
|
||||
}
|
||||
theLastKEYINFO = tSignal;
|
||||
|
||||
tSignal->setSignal(GSN_KEYINFO);
|
||||
theKEYINFOptr = ((KeyInfo*)tSignal->getDataPtrSend())->keyData;
|
||||
theTotalNrOfKeyWordInSignal= 0;
|
||||
|
||||
|
||||
getFirstATTRINFOScan();
|
||||
return getResultSet();
|
||||
}
|
||||
|
@ -348,60 +350,6 @@ NdbScanOperation::getFirstATTRINFOScan()
|
|||
#define FAKE_PTR 2
|
||||
#define API_PTR 3
|
||||
|
||||
|
||||
/*
|
||||
* After setBound() are done, move the accumulated ATTRINFO signals to
|
||||
* a separate list. Then continue with normal scan.
|
||||
*/
|
||||
#if 0
|
||||
int
|
||||
NdbIndexScanOperation::saveBoundATTRINFO()
|
||||
{
|
||||
theCurrentATTRINFO->setLength(theAI_LenInCurrAI);
|
||||
theBoundATTRINFO = theFirstATTRINFO;
|
||||
theTotalBoundAI_Len = theTotalCurrAI_Len;
|
||||
theTotalCurrAI_Len = 5;
|
||||
theBoundATTRINFO->setData(theTotalBoundAI_Len, 4);
|
||||
theBoundATTRINFO->setData(0, 5);
|
||||
theBoundATTRINFO->setData(0, 6);
|
||||
theBoundATTRINFO->setData(0, 7);
|
||||
theBoundATTRINFO->setData(0, 8);
|
||||
theStatus = GetValue;
|
||||
|
||||
int res = getFirstATTRINFOScan();
|
||||
|
||||
/**
|
||||
* Define each key with getValue (if ordered)
|
||||
* unless the one's with EqBound
|
||||
*/
|
||||
if(!res && m_ordered){
|
||||
|
||||
/**
|
||||
* If setBound EQ
|
||||
*/
|
||||
Uint32 i = 0;
|
||||
while(theTupleKeyDefined[i][0] == SETBOUND_EQ)
|
||||
i++;
|
||||
|
||||
|
||||
Uint32 cnt = m_accessTable->getNoOfColumns() - 1;
|
||||
m_sort_columns = cnt - i;
|
||||
for(; i<cnt; i++){
|
||||
const NdbColumnImpl* key = m_accessTable->m_index->m_columns[i];
|
||||
const NdbColumnImpl* col = m_currentTable->getColumn(key->m_keyInfoPos);
|
||||
NdbRecAttr* tmp = NdbScanOperation::getValue_impl(col, (char*)-1);
|
||||
UintPtr newVal = UintPtr(tmp);
|
||||
theTupleKeyDefined[i][0] = FAKE_PTR;
|
||||
theTupleKeyDefined[i][1] = (newVal & 0xFFFFFFFF);
|
||||
#if (SIZEOF_CHARP == 8)
|
||||
theTupleKeyDefined[i][2] = (newVal >> 32);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
return res;
|
||||
}
|
||||
#endif
|
||||
|
||||
#define WAITFOR_SCAN_TIMEOUT 120000
|
||||
|
||||
int
|
||||
|
@ -683,12 +631,14 @@ void NdbScanOperation::release()
|
|||
for(Uint32 i = 0; i<m_allocated_receivers; i++){
|
||||
m_receivers[i]->release();
|
||||
}
|
||||
|
||||
NdbOperation::release();
|
||||
|
||||
if(theSCAN_TABREQ)
|
||||
{
|
||||
theNdb->releaseSignal(theSCAN_TABREQ);
|
||||
theSCAN_TABREQ = 0;
|
||||
}
|
||||
NdbOperation::release();
|
||||
}
|
||||
|
||||
/***************************************************************************
|
||||
|
@ -783,10 +733,6 @@ NdbScanOperation::doSendScan(int aProcessorId)
|
|||
|
||||
assert(theSCAN_TABREQ != NULL);
|
||||
tSignal = theSCAN_TABREQ;
|
||||
if (tSignal->setSignal(GSN_SCAN_TABREQ) == -1) {
|
||||
setErrorCode(4001);
|
||||
return -1;
|
||||
}
|
||||
|
||||
Uint32 tupKeyLen = theTupKeyLen;
|
||||
Uint32 len = theTotalNrOfKeyWordInSignal;
|
||||
|
@ -798,6 +744,10 @@ NdbScanOperation::doSendScan(int aProcessorId)
|
|||
// we created the ATTRINFO signals after the SCAN_TABREQ signal.
|
||||
ScanTabReq * const req = CAST_PTR(ScanTabReq, tSignal->getDataPtrSend());
|
||||
req->attrLenKeyLen = (tupKeyLen << 16) | theTotalCurrAI_Len;
|
||||
Uint32 tmp = req->requestInfo;
|
||||
ScanTabReq::setDistributionKeyFlag(tmp, theDistrKeyIndicator_);
|
||||
req->distributionKey = theDistributionKey;
|
||||
tSignal->setLength(ScanTabReq::StaticLength + theDistrKeyIndicator_);
|
||||
|
||||
TransporterFacade *tp = TransporterFacade::instance();
|
||||
LinearSectionPtr ptr[3];
|
||||
|
@ -814,8 +764,8 @@ NdbScanOperation::doSendScan(int aProcessorId)
|
|||
tSignal = theLastKEYINFO;
|
||||
tSignal->setLength(KeyInfo::HeaderLength + theTotalNrOfKeyWordInSignal);
|
||||
|
||||
assert(theFirstKEYINFO != NULL);
|
||||
tSignal = theFirstKEYINFO;
|
||||
assert(theSCAN_TABREQ->next() != NULL);
|
||||
tSignal = theSCAN_TABREQ->next();
|
||||
|
||||
NdbApiSignal* last;
|
||||
do {
|
||||
|
@ -932,11 +882,11 @@ NdbScanOperation::takeOverScanOp(OperationType opType, NdbConnection* pTrans){
|
|||
|
||||
const Uint32 * src = (Uint32*)tRecAttr->aRef();
|
||||
const Uint32 tScanInfo = src[len] & 0x3FFFF;
|
||||
const Uint32 tTakeOverNode = src[len] >> 20;
|
||||
const Uint32 tTakeOverFragment = src[len] >> 20;
|
||||
{
|
||||
UintR scanInfo = 0;
|
||||
TcKeyReq::setTakeOverScanFlag(scanInfo, 1);
|
||||
TcKeyReq::setTakeOverScanNode(scanInfo, tTakeOverNode);
|
||||
TcKeyReq::setTakeOverScanFragment(scanInfo, tTakeOverFragment);
|
||||
TcKeyReq::setTakeOverScanInfo(scanInfo, tScanInfo);
|
||||
newOp->theScanInfo = scanInfo;
|
||||
}
|
||||
|
@ -950,7 +900,7 @@ NdbScanOperation::takeOverScanOp(OperationType opType, NdbConnection* pTrans){
|
|||
|
||||
if(i < len){
|
||||
NdbApiSignal* tSignal = theNdb->getSignal();
|
||||
newOp->theFirstKEYINFO = tSignal;
|
||||
newOp->theTCREQ->next(tSignal);
|
||||
|
||||
Uint32 left = len - i;
|
||||
while(tSignal && left > KeyInfo::DataLength){
|
||||
|
@ -1085,37 +1035,51 @@ NdbIndexScanOperation::setBound(const NdbColumnImpl* tAttrInfo,
|
|||
Uint32 currLen = theTotalNrOfKeyWordInSignal;
|
||||
Uint32 remaining = KeyInfo::DataLength - currLen;
|
||||
Uint32 sizeInBytes = tAttrInfo->m_attrSize * tAttrInfo->m_arraySize;
|
||||
bool tDistrKey = tAttrInfo->m_distributionKey;
|
||||
|
||||
// normalize char bound
|
||||
CHARSET_INFO* cs = tAttrInfo->m_cs;
|
||||
Uint32 xfrmData[2000];
|
||||
if (cs != NULL && aValue != NULL) {
|
||||
// current limitation: strxfrm does not increase length
|
||||
assert(cs->strxfrm_multiply == 1);
|
||||
unsigned n =
|
||||
(*cs->coll->strnxfrm)(cs,
|
||||
(uchar*)xfrmData, sizeof(xfrmData),
|
||||
(const uchar*)aValue, sizeInBytes);
|
||||
while (n < sizeInBytes)
|
||||
((uchar*)xfrmData)[n++] = 0x20;
|
||||
aValue = (char*)xfrmData;
|
||||
}
|
||||
len = aValue != NULL ? sizeInBytes : 0;
|
||||
if (len != sizeInBytes && (len != 0)) {
|
||||
setErrorCodeAbort(4209);
|
||||
return -1;
|
||||
}
|
||||
|
||||
// normalize char bound
|
||||
CHARSET_INFO* cs = tAttrInfo->m_cs;
|
||||
Uint64 xfrmData[1001];
|
||||
if (cs != NULL && aValue != NULL) {
|
||||
// current limitation: strxfrm does not increase length
|
||||
assert(cs->strxfrm_multiply == 1);
|
||||
((Uint32*)xfrmData)[len >> 2] = 0;
|
||||
unsigned n =
|
||||
(*cs->coll->strnxfrm)(cs,
|
||||
(uchar*)xfrmData, sizeof(xfrmData),
|
||||
(const uchar*)aValue, len);
|
||||
|
||||
while (n < len)
|
||||
((uchar*)xfrmData)[n++] = 0x20;
|
||||
|
||||
if(len & 3)
|
||||
{
|
||||
len += (4 - (len & 3));
|
||||
}
|
||||
|
||||
aValue = (char*)xfrmData;
|
||||
}
|
||||
|
||||
// insert attribute header
|
||||
len = aValue != NULL ? sizeInBytes : 0;
|
||||
Uint32 tIndexAttrId = tAttrInfo->m_attrId;
|
||||
Uint32 sizeInWords = (len + 3) / 4;
|
||||
AttributeHeader ah(tIndexAttrId, sizeInWords);
|
||||
const Uint32 ahValue = ah.m_value;
|
||||
|
||||
const bool aligned = (UintPtr(aValue) & 3) == 0;
|
||||
const Uint32 align = (UintPtr(aValue) & 7);
|
||||
const bool aligned = (tDistrKey && type == BoundEQ) ?
|
||||
(align == 0) : (align & 3) == 0;
|
||||
|
||||
const bool nobytes = (len & 0x3) == 0;
|
||||
const Uint32 totalLen = 2 + sizeInWords;
|
||||
Uint32 tupKeyLen = theTupKeyLen;
|
||||
if(remaining > totalLen && aligned && nobytes){
|
||||
if(remaining > totalLen && aligned && nobytes){
|
||||
Uint32 * dst = theKEYINFOptr + currLen;
|
||||
* dst ++ = type;
|
||||
* dst ++ = ahValue;
|
||||
|
@ -1123,12 +1087,12 @@ NdbIndexScanOperation::setBound(const NdbColumnImpl* tAttrInfo,
|
|||
theTotalNrOfKeyWordInSignal = currLen + totalLen;
|
||||
} else {
|
||||
if(!aligned || !nobytes){
|
||||
Uint32 tempData[2002];
|
||||
Uint32 *tempData = (Uint32*)xfrmData;
|
||||
tempData[0] = type;
|
||||
tempData[1] = ahValue;
|
||||
tempData[2 + (len >> 2)] = 0;
|
||||
memcpy(tempData+2, aValue, len);
|
||||
while ((len & 0x3) != 0)
|
||||
((char*)&tempData[2])[len++] = 0;
|
||||
|
||||
insertBOUNDS(tempData, 2+sizeInWords);
|
||||
} else {
|
||||
Uint32 buf[2] = { type, ahValue };
|
||||
|
@ -1147,11 +1111,11 @@ NdbIndexScanOperation::setBound(const NdbColumnImpl* tAttrInfo,
|
|||
* so it's safe to use [tIndexAttrId]
|
||||
* (instead of looping as is NdbOperation::equal_impl)
|
||||
*/
|
||||
if(type == BoundEQ && !theTupleKeyDefined[tIndexAttrId][0]){
|
||||
theNoOfTupKeyDefined++;
|
||||
theTupleKeyDefined[tIndexAttrId][0] = SETBOUND_EQ;
|
||||
if(type == BoundEQ && tDistrKey)
|
||||
{
|
||||
theNoOfTupKeyLeft--;
|
||||
return handle_distribution_key((Uint64*)aValue, sizeInWords);
|
||||
}
|
||||
|
||||
return 0;
|
||||
} else {
|
||||
setErrorCodeAbort(4228); // XXX wrong code
|
||||
|
@ -1562,10 +1526,12 @@ NdbIndexScanOperation::reset_bounds(){
|
|||
theError.code = 0;
|
||||
reset_receivers(theParallelism, m_ordered);
|
||||
|
||||
theLastKEYINFO = theFirstKEYINFO;
|
||||
theKEYINFOptr = ((KeyInfo*)theFirstKEYINFO->getDataPtrSend())->keyData;
|
||||
theLastKEYINFO = theSCAN_TABREQ->next();
|
||||
theKEYINFOptr = ((KeyInfo*)theLastKEYINFO->getDataPtrSend())->keyData;
|
||||
theTupKeyLen = 0;
|
||||
theTotalNrOfKeyWordInSignal = 0;
|
||||
theNoOfTupKeyLeft = m_accessTable->m_noOfDistributionKeys;
|
||||
theDistrKeyIndicator_ = 0;
|
||||
m_transConnection
|
||||
->remove_list((NdbOperation*&)m_transConnection->m_firstExecutedScanOp,
|
||||
this);
|
||||
|
|
|
@ -23,11 +23,13 @@
|
|||
#include <NdbDictionary.hpp>
|
||||
#include <NDBT_Table.hpp>
|
||||
|
||||
typedef int (* NDBT_CreateTableHook)(Ndb*, NdbDictionary::Table&, int when);
|
||||
|
||||
class NDBT_Tables {
|
||||
public:
|
||||
|
||||
|
||||
static int createTable(Ndb* pNdb, const char* _name, bool _temp = false,
|
||||
bool existsOK = false);
|
||||
bool existsOK = false, NDBT_CreateTableHook = 0);
|
||||
static int createAllTables(Ndb* pNdb, bool _temp, bool existsOK = false);
|
||||
static int createAllTables(Ndb* pNdb);
|
||||
|
||||
|
|
|
@ -30,7 +30,8 @@ testSystemRestart \
|
|||
testTimeout \
|
||||
testTransactions \
|
||||
testDeadlock \
|
||||
test_event ndbapi_slow_select testReadPerf testLcp
|
||||
test_event ndbapi_slow_select testReadPerf testLcp \
|
||||
testPartitioning
|
||||
|
||||
#flexTimedAsynch
|
||||
#testBlobs
|
||||
|
@ -69,6 +70,7 @@ test_event_SOURCES = test_event.cpp
|
|||
ndbapi_slow_select_SOURCES = slow_select.cpp
|
||||
testReadPerf_SOURCES = testReadPerf.cpp
|
||||
testLcp_SOURCES = testLcp.cpp
|
||||
testPartitioning_SOURCES = testPartitioning.cpp
|
||||
|
||||
INCLUDES_LOC = -I$(top_srcdir)/ndb/include/kernel
|
||||
|
||||
|
|
189
ndb/test/ndbapi/testPartitioning.cpp
Normal file
189
ndb/test/ndbapi/testPartitioning.cpp
Normal file
|
@ -0,0 +1,189 @@
|
|||
/* Copyright (C) 2003 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 <NDBT_Test.hpp>
|
||||
#include <NDBT_ReturnCodes.h>
|
||||
#include <HugoTransactions.hpp>
|
||||
#include <UtilTransactions.hpp>
|
||||
#include <NdbRestarter.hpp>
|
||||
|
||||
#define GETNDB(ps) ((NDBT_NdbApiStep*)ps)->getNdb()
|
||||
|
||||
static
|
||||
int runLoadTable(NDBT_Context* ctx, NDBT_Step* step)
|
||||
{
|
||||
int records = ctx->getNumRecords();
|
||||
HugoTransactions hugoTrans(*ctx->getTab());
|
||||
if (hugoTrans.loadTable(GETNDB(step), records) != 0){
|
||||
return NDBT_FAILED;
|
||||
}
|
||||
return NDBT_OK;
|
||||
}
|
||||
|
||||
static
|
||||
int
|
||||
run_drop_table(NDBT_Context* ctx, NDBT_Step* step)
|
||||
{
|
||||
NdbDictionary::Dictionary* dict = GETNDB(step)->getDictionary();
|
||||
dict->dropTable(ctx->getTab()->getName());
|
||||
return 0;
|
||||
}
|
||||
|
||||
static
|
||||
int
|
||||
add_distribution_key(Ndb*, NdbDictionary::Table& tab, int when)
|
||||
{
|
||||
switch(when){
|
||||
case 0: // Before
|
||||
break;
|
||||
case 1: // After
|
||||
return 0;
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
|
||||
int keys = tab.getNoOfPrimaryKeys();
|
||||
int dks = (2 * keys + 2) / 3;
|
||||
int cnt = 0;
|
||||
ndbout_c("%s pks: %d dks: %d", tab.getName(), keys, dks);
|
||||
for(unsigned i = 0; i<tab.getNoOfColumns(); i++)
|
||||
{
|
||||
NdbDictionary::Column* col = tab.getColumn(i);
|
||||
if(col->getPrimaryKey())
|
||||
{
|
||||
if(dks >= keys || (rand() % 100) > 50)
|
||||
{
|
||||
col->setDistributionKey(true);
|
||||
dks--;
|
||||
}
|
||||
keys--;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
run_create_table(NDBT_Context* ctx, NDBT_Step* step)
|
||||
{
|
||||
bool dk = ctx->getProperty("distributionkey", (unsigned)0);
|
||||
return NDBT_Tables::createTable(GETNDB(step),
|
||||
ctx->getTab()->getName(),
|
||||
false, false, dk?add_distribution_key:0);
|
||||
}
|
||||
|
||||
int
|
||||
run_pk_dk(NDBT_Context* ctx, NDBT_Step* step)
|
||||
{
|
||||
Ndb* p_ndb = GETNDB(step);
|
||||
int records = ctx->getNumRecords();
|
||||
const NdbDictionary::Table *tab =
|
||||
p_ndb->getDictionary()->getTable(ctx->getTab()->getName());
|
||||
HugoTransactions hugoTrans(*tab);
|
||||
|
||||
if (hugoTrans.loadTable(p_ndb, records) != 0)
|
||||
{
|
||||
return NDBT_FAILED;
|
||||
}
|
||||
|
||||
if(hugoTrans.pkReadRecords(p_ndb, records) != 0)
|
||||
{
|
||||
return NDBT_FAILED;
|
||||
}
|
||||
|
||||
if(hugoTrans.pkUpdateRecords(p_ndb, records) != 0)
|
||||
{
|
||||
return NDBT_FAILED;
|
||||
}
|
||||
|
||||
if(hugoTrans.pkDelRecords(p_ndb, records) != 0)
|
||||
{
|
||||
return NDBT_FAILED;
|
||||
}
|
||||
|
||||
if (hugoTrans.loadTable(p_ndb, records) != 0)
|
||||
{
|
||||
return NDBT_FAILED;
|
||||
}
|
||||
|
||||
if(hugoTrans.scanUpdateRecords(p_ndb, records) != 0)
|
||||
{
|
||||
return NDBT_FAILED;
|
||||
}
|
||||
|
||||
if(hugoTrans.scanReadRecords(p_ndb, records) != 0)
|
||||
{
|
||||
return NDBT_FAILED;
|
||||
}
|
||||
|
||||
if(hugoTrans.clearTable(p_ndb, records) != 0)
|
||||
{
|
||||
return NDBT_FAILED;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
run_hash_dk(NDBT_Context* ctx, NDBT_Step* step)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
run_index_dk(NDBT_Context* ctx, NDBT_Step* step)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
NDBT_TESTSUITE(testPartitioning);
|
||||
TESTCASE("pk_dk",
|
||||
"Primary key operations with distribution key")
|
||||
{
|
||||
TC_PROPERTY("distributionkey", 1);
|
||||
INITIALIZER(run_drop_table);
|
||||
INITIALIZER(run_create_table);
|
||||
INITIALIZER(run_pk_dk);
|
||||
INITIALIZER(run_drop_table);
|
||||
}
|
||||
TESTCASE("hash_index_dk",
|
||||
"Unique index operatations with distribution key")
|
||||
{
|
||||
TC_PROPERTY("distributionkey", 1);
|
||||
INITIALIZER(run_drop_table);
|
||||
INITIALIZER(run_create_table);
|
||||
INITIALIZER(run_hash_dk);
|
||||
INITIALIZER(run_drop_table);
|
||||
}
|
||||
TESTCASE("ordered_index_dk",
|
||||
"Ordered index operatations with distribution key")
|
||||
{
|
||||
TC_PROPERTY("distributionkey", 1);
|
||||
INITIALIZER(run_drop_table);
|
||||
INITIALIZER(run_create_table);
|
||||
INITIALIZER(run_index_dk);
|
||||
INITIALIZER(run_drop_table);
|
||||
}
|
||||
NDBT_TESTSUITE_END(testPartitioning);
|
||||
|
||||
int main(int argc, const char** argv){
|
||||
ndb_init();
|
||||
testPartitioning.setCreateTable(false);
|
||||
return testPartitioning.execute(argc, argv);
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -456,11 +456,6 @@ int HugoOperations::setValueForAttr(NdbOperation* pOp,
|
|||
int check = 0;
|
||||
const NdbDictionary::Column* attr = tab.getColumn(attrId);
|
||||
|
||||
if (attr->getTupleKey()){
|
||||
// Don't set values for TupleId PKs
|
||||
return check;
|
||||
}
|
||||
|
||||
switch (attr->getType()){
|
||||
case NdbDictionary::Column::Char:
|
||||
case NdbDictionary::Column::Varchar:
|
||||
|
|
|
@ -820,21 +820,25 @@ NDBT_Tables::createAllTables(Ndb* pNdb){
|
|||
|
||||
int
|
||||
NDBT_Tables::createTable(Ndb* pNdb, const char* _name, bool _temp,
|
||||
bool existsOk){
|
||||
bool existsOk, NDBT_CreateTableHook f){
|
||||
|
||||
const NdbDictionary::Table* tab = NDBT_Tables::getTable(_name);
|
||||
if (tab == NULL){
|
||||
ndbout << "Could not create table " << _name
|
||||
<< ", it doesn't exist in list of tables "\
|
||||
"that NDBT_Tables can create!" << endl;
|
||||
"that NDBT_Tables can create!" << endl;
|
||||
return NDBT_WRONGARGS;
|
||||
}
|
||||
|
||||
|
||||
int r = 0;
|
||||
do {
|
||||
NdbDictionary::Table tmpTab(* tab);
|
||||
tmpTab.setStoredTable(_temp ? 0 : 1);
|
||||
|
||||
if(f != 0 && f(pNdb, tmpTab, 0))
|
||||
{
|
||||
ndbout << "Failed to create table" << endl;
|
||||
return NDBT_FAILED;
|
||||
}
|
||||
r = pNdb->getDictionary()->createTable(tmpTab);
|
||||
if(r == -1){
|
||||
if(!existsOk){
|
||||
|
@ -883,6 +887,11 @@ NDBT_Tables::createTable(Ndb* pNdb, const char* _name, bool _temp,
|
|||
}
|
||||
}
|
||||
}
|
||||
if(f != 0 && f(pNdb, tmpTab, 1))
|
||||
{
|
||||
ndbout << "Failed to create table" << endl;
|
||||
return NDBT_FAILED;
|
||||
}
|
||||
} while(false);
|
||||
|
||||
return r;
|
||||
|
|
|
@ -158,7 +158,6 @@ NdbSchemaOp::createAttribute( const char* anAttrName,
|
|||
col.setPrimaryKey(false);
|
||||
|
||||
col.setDistributionKey(aDistributionKeyFlag);
|
||||
col.setDistributionGroup(aDistributionGroupFlag,aDistributionGroupNoOfBits);
|
||||
col.setAutoIncrement(aAutoIncrement);
|
||||
col.setDefaultValue(aDefaultValue != 0 ? aDefaultValue : "");
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue