summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorunknown <joreland@mysql.com>2004-11-11 10:45:45 +0100
committerunknown <joreland@mysql.com>2004-11-11 10:45:45 +0100
commit7d78fe866a458e21f7df17c3b014fab64a7953f9 (patch)
tree9e0c7a25254a4da9687e3a841d9570529f583760
parent971660bec5ff29fc54956d3e7f42e951e0549bac (diff)
parented78385899fcc1e6f4f66b50d17a8869144b2d01 (diff)
downloadmariadb-git-7d78fe866a458e21f7df17c3b014fab64a7953f9.tar.gz
merge
ndb/include/ndbapi/NdbOperation.hpp: Auto merged ndb/src/kernel/blocks/dbacc/DbaccMain.cpp: Auto merged ndb/src/kernel/blocks/dbdict/Dbdict.cpp: Auto merged ndb/src/kernel/blocks/dblqh/DblqhMain.cpp: Auto merged ndb/src/ndbapi/NdbConnection.cpp: Auto merged ndb/src/ndbapi/NdbDictionaryImpl.cpp: Auto merged ndb/src/ndbapi/NdbOperation.cpp: Auto merged ndb/src/ndbapi/NdbOperationExec.cpp: Auto merged ndb/src/ndbapi/NdbScanOperation.cpp: Auto merged ndb/include/ndbapi/NdbIndexOperation.hpp: merge (again) ndb/src/ndbapi/NdbBlob.cpp: merge (again) ndb/src/ndbapi/NdbIndexOperation.cpp: merge (again)
-rw-r--r--ndb/include/kernel/signaldata/ScanTab.hpp24
-rw-r--r--ndb/include/kernel/signaldata/TcIndx.hpp374
-rw-r--r--ndb/include/ndbapi/NdbDictionary.hpp10
-rw-r--r--ndb/include/ndbapi/NdbIndexOperation.hpp13
-rw-r--r--ndb/include/ndbapi/NdbOperation.hpp62
-rw-r--r--ndb/include/ndbapi/NdbScanOperation.hpp1
-rw-r--r--ndb/include/util/md5_hash.hpp11
-rw-r--r--ndb/src/common/debugger/signaldata/SignalDataPrint.cpp4
-rw-r--r--ndb/src/common/debugger/signaldata/TcIndx.cpp85
-rw-r--r--ndb/src/common/debugger/signaldata/TcKeyReq.cpp5
-rw-r--r--ndb/src/common/util/md5_hash.cpp20
-rw-r--r--ndb/src/kernel/blocks/dbacc/DbaccMain.cpp2
-rw-r--r--ndb/src/kernel/blocks/dbdict/Dbdict.cpp4
-rw-r--r--ndb/src/kernel/blocks/dbdih/DbdihMain.cpp3
-rw-r--r--ndb/src/kernel/blocks/dblqh/Dblqh.hpp4
-rw-r--r--ndb/src/kernel/blocks/dblqh/DblqhMain.cpp35
-rw-r--r--ndb/src/kernel/blocks/dbtc/Dbtc.hpp12
-rw-r--r--ndb/src/kernel/blocks/dbtc/DbtcMain.cpp135
-rw-r--r--ndb/src/kernel/blocks/dbtux/Dbtux.hpp5
-rw-r--r--ndb/src/kernel/blocks/dbtux/DbtuxDebug.cpp2
-rw-r--r--ndb/src/kernel/blocks/dbtux/DbtuxMaint.cpp7
-rw-r--r--ndb/src/kernel/blocks/dbtux/DbtuxMeta.cpp3
-rw-r--r--ndb/src/kernel/blocks/dbtux/DbtuxScan.cpp11
-rw-r--r--ndb/src/ndbapi/NdbApiSignal.cpp2
-rw-r--r--ndb/src/ndbapi/NdbBlob.cpp18
-rw-r--r--ndb/src/ndbapi/NdbConnection.cpp3
-rw-r--r--ndb/src/ndbapi/NdbDictionary.cpp39
-rw-r--r--ndb/src/ndbapi/NdbDictionaryImpl.cpp47
-rw-r--r--ndb/src/ndbapi/NdbDictionaryImpl.hpp14
-rw-r--r--ndb/src/ndbapi/NdbIndexOperation.cpp428
-rw-r--r--ndb/src/ndbapi/NdbOperation.cpp37
-rw-r--r--ndb/src/ndbapi/NdbOperationDefine.cpp5
-rw-r--r--ndb/src/ndbapi/NdbOperationExec.cpp18
-rw-r--r--ndb/src/ndbapi/NdbOperationSearch.cpp277
-rw-r--r--ndb/src/ndbapi/NdbScanOperation.cpp142
-rw-r--r--ndb/test/include/NDBT_Tables.hpp6
-rw-r--r--ndb/test/src/HugoOperations.cpp5
-rw-r--r--ndb/test/src/NDBT_Tables.cpp17
-rw-r--r--ndb/test/src/NdbSchemaOp.cpp1
39 files changed, 530 insertions, 1361 deletions
diff --git a/ndb/include/kernel/signaldata/ScanTab.hpp b/ndb/include/kernel/signaldata/ScanTab.hpp
index 2029b16197e..ca70b8c62a9 100644
--- a/ndb/include/kernel/signaldata/ScanTab.hpp
+++ b/ndb/include/kernel/signaldata/ScanTab.hpp
@@ -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);
+}
/**
*
diff --git a/ndb/include/kernel/signaldata/TcIndx.hpp b/ndb/include/kernel/signaldata/TcIndx.hpp
index 764d4e9fcd7..f82cd95878e 100644
--- a/ndb/include/kernel/signaldata/TcIndx.hpp
+++ b/ndb/include/kernel/signaldata/TcIndx.hpp
@@ -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 {
diff --git a/ndb/include/ndbapi/NdbDictionary.hpp b/ndb/include/ndbapi/NdbDictionary.hpp
index 51a6895648f..0444b565a16 100644
--- a/ndb/include/ndbapi/NdbDictionary.hpp
+++ b/ndb/include/ndbapi/NdbDictionary.hpp
@@ -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;
/**
diff --git a/ndb/include/ndbapi/NdbIndexOperation.hpp b/ndb/include/ndbapi/NdbIndexOperation.hpp
index 1472f1b249e..4c81282caa9 100644
--- a/ndb/include/ndbapi/NdbIndexOperation.hpp
+++ b/ndb/include/ndbapi/NdbIndexOperation.hpp
@@ -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
diff --git a/ndb/include/ndbapi/NdbOperation.hpp b/ndb/include/ndbapi/NdbOperation.hpp
index 46d4ddab0f5..f32a418f6d2 100644
--- a/ndb/include/ndbapi/NdbOperation.hpp
+++ b/ndb/include/ndbapi/NdbOperation.hpp
@@ -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;
diff --git a/ndb/include/ndbapi/NdbScanOperation.hpp b/ndb/include/ndbapi/NdbScanOperation.hpp
index 2e4d173ac75..81d0839ad8a 100644
--- a/ndb/include/ndbapi/NdbScanOperation.hpp
+++ b/ndb/include/ndbapi/NdbScanOperation.hpp
@@ -114,7 +114,6 @@ protected:
// Scan related variables
Uint32 theParallelism;
Uint32 m_keyInfo;
- NdbApiSignal* theSCAN_TABREQ;
int getFirstATTRINFOScan();
int doSendScan(int ProcessorId);
diff --git a/ndb/include/util/md5_hash.hpp b/ndb/include/util/md5_hash.hpp
index 4c3cf239881..b79dce3b5a9 100644
--- a/ndb/include/util/md5_hash.hpp
+++ b/ndb/include/util/md5_hash.hpp
@@ -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
diff --git a/ndb/src/common/debugger/signaldata/SignalDataPrint.cpp b/ndb/src/common/debugger/signaldata/SignalDataPrint.cpp
index 3314f0bd097..8be576aa735 100644
--- a/ndb/src/common/debugger/signaldata/SignalDataPrint.cpp
+++ b/ndb/src/common/debugger/signaldata/SignalDataPrint.cpp
@@ -138,14 +138,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 },
diff --git a/ndb/src/common/debugger/signaldata/TcIndx.cpp b/ndb/src/common/debugger/signaldata/TcIndx.cpp
index 6bfa29eff15..b0578f5b646 100644
--- a/ndb/src/common/debugger/signaldata/TcIndx.cpp
+++ b/ndb/src/common/debugger/signaldata/TcIndx.cpp
@@ -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){
diff --git a/ndb/src/common/debugger/signaldata/TcKeyReq.cpp b/ndb/src/common/debugger/signaldata/TcKeyReq.cpp
index 7304872ff9c..3918bd5db26 100644
--- a/ndb/src/common/debugger/signaldata/TcKeyReq.cpp
+++ b/ndb/src/common/debugger/signaldata/TcKeyReq.cpp
@@ -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");
}
diff --git a/ndb/src/common/util/md5_hash.cpp b/ndb/src/common/util/md5_hash.cpp
index 068843183ac..d4eedbc40fb 100644
--- a/ndb/src/common/util/md5_hash.cpp
+++ b/ndb/src/common/util/md5_hash.cpp
@@ -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];
}
diff --git a/ndb/src/kernel/blocks/dbacc/DbaccMain.cpp b/ndb/src/kernel/blocks/dbacc/DbaccMain.cpp
index c275e5382f7..d431333282a 100644
--- a/ndb/src/kernel/blocks/dbacc/DbaccMain.cpp
+++ b/ndb/src/kernel/blocks/dbacc/DbaccMain.cpp
@@ -9272,7 +9272,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);
diff --git a/ndb/src/kernel/blocks/dbdict/Dbdict.cpp b/ndb/src/kernel/blocks/dbdict/Dbdict.cpp
index 882557daae1..ffcd964a4c1 100644
--- a/ndb/src/kernel/blocks/dbdict/Dbdict.cpp
+++ b/ndb/src/kernel/blocks/dbdict/Dbdict.cpp
@@ -4096,8 +4096,8 @@ 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;
diff --git a/ndb/src/kernel/blocks/dbdih/DbdihMain.cpp b/ndb/src/kernel/blocks/dbdih/DbdihMain.cpp
index 76aa745c3e0..83ab897d0c3 100644
--- a/ndb/src/kernel/blocks/dbdih/DbdihMain.cpp
+++ b/ndb/src/kernel/blocks/dbdih/DbdihMain.cpp
@@ -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();
diff --git a/ndb/src/kernel/blocks/dblqh/Dblqh.hpp b/ndb/src/kernel/blocks/dblqh/Dblqh.hpp
index d6987f3e478..ef35cecb2b1 100644
--- a/ndb/src/kernel/blocks/dblqh/Dblqh.hpp
+++ b/ndb/src/kernel/blocks/dblqh/Dblqh.hpp
@@ -862,10 +862,6 @@ public:
*/
Uint8 fragDistributionKey;
/**
- * Used to calculate which local fragment to use.
- */
- Uint8 hashCheckBit;
- /**
* The identity of the next local checkpoint this fragment
* should perform.
*/
diff --git a/ndb/src/kernel/blocks/dblqh/DblqhMain.cpp b/ndb/src/kernel/blocks/dblqh/DblqhMain.cpp
index af1131e5e55..534b818f315 100644
--- a/ndb/src/kernel/blocks/dblqh/DblqhMain.cpp
+++ b/ndb/src/kernel/blocks/dblqh/DblqhMain.cpp
@@ -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();
@@ -9122,13 +9108,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 +13370,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];
diff --git a/ndb/src/kernel/blocks/dbtc/Dbtc.hpp b/ndb/src/kernel/blocks/dbtc/Dbtc.hpp
index a209df24c44..41f35152127 100644
--- a/ndb/src/kernel/blocks/dbtc/Dbtc.hpp
+++ b/ndb/src/kernel/blocks/dbtc/Dbtc.hpp
@@ -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,9 +925,9 @@ 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;
//---------------------------------------------------
diff --git a/ndb/src/kernel/blocks/dbtc/DbtcMain.cpp b/ndb/src/kernel/blocks/dbtc/DbtcMain.cpp
index d8b3ee10532..b9c553bb805 100644
--- a/ndb/src/kernel/blocks/dbtc/DbtcMain.cpp
+++ b/ndb/src/kernel/blocks/dbtc/DbtcMain.cpp
@@ -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,7 +2669,7 @@ 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]);
@@ -2695,8 +2678,7 @@ void Dbtc::execTCKEYREQ(Signal* signal)
regCachePtr->scanNode = TscanNode;
regCachePtr->scanInfo = TscanInfo;
- regCachePtr->distributionGroup = TOptionalDataPtr[TDistrGHIndex];
- regCachePtr->distributionKeySize = TOptionalDataPtr[TDistrKeyIndex];
+ regCachePtr->distributionKey = TOptionalDataPtr[TDistrKeyIndex];
TkeyIndex = TDistrKeyIndex + TDistrKeyFlag;
}
@@ -2957,7 +2939,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();
@@ -3127,7 +3109,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 +8459,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 +8469,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 +8545,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 +8623,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 +8636,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 +8751,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 +8803,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 +8837,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 +8862,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 +11079,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 +11130,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 +11543,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 +11738,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 +11755,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 +11847,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 +11858,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();
diff --git a/ndb/src/kernel/blocks/dbtux/Dbtux.hpp b/ndb/src/kernel/blocks/dbtux/Dbtux.hpp
index 8896324f793..0059f558995 100644
--- a/ndb/src/kernel/blocks/dbtux/Dbtux.hpp
+++ b/ndb/src/kernel/blocks/dbtux/Dbtux.hpp
@@ -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),
diff --git a/ndb/src/kernel/blocks/dbtux/DbtuxDebug.cpp b/ndb/src/kernel/blocks/dbtux/DbtuxDebug.cpp
index c5c22264460..01193b5e41f 100644
--- a/ndb/src/kernel/blocks/dbtux/DbtuxDebug.cpp
+++ b/ndb/src/kernel/blocks/dbtux/DbtuxDebug.cpp
@@ -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 << "]";
diff --git a/ndb/src/kernel/blocks/dbtux/DbtuxMaint.cpp b/ndb/src/kernel/blocks/dbtux/DbtuxMaint.cpp
index 30afb51e7d7..2d256487dcc 100644
--- a/ndb/src/kernel/blocks/dbtux/DbtuxMaint.cpp
+++ b/ndb/src/kernel/blocks/dbtux/DbtuxMaint.cpp
@@ -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
diff --git a/ndb/src/kernel/blocks/dbtux/DbtuxMeta.cpp b/ndb/src/kernel/blocks/dbtux/DbtuxMeta.cpp
index 1577c5045e0..54882d99800 100644
--- a/ndb/src/kernel/blocks/dbtux/DbtuxMeta.cpp
+++ b/ndb/src/kernel/blocks/dbtux/DbtuxMeta.cpp
@@ -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
diff --git a/ndb/src/kernel/blocks/dbtux/DbtuxScan.cpp b/ndb/src/kernel/blocks/dbtux/DbtuxScan.cpp
index 8677ae741b3..c56919865bd 100644
--- a/ndb/src/kernel/blocks/dbtux/DbtuxScan.cpp
+++ b/ndb/src/kernel/blocks/dbtux/DbtuxScan.cpp
@@ -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
diff --git a/ndb/src/ndbapi/NdbApiSignal.cpp b/ndb/src/ndbapi/NdbApiSignal.cpp
index a1d34896968..b1671e593e1 100644
--- a/ndb/src/ndbapi/NdbApiSignal.cpp
+++ b/ndb/src/ndbapi/NdbApiSignal.cpp
@@ -213,7 +213,7 @@ NdbApiSignal::setSignal(int aNdbSignalType)
theTrace = TestOrd::TraceAPI;
theReceiversBlockNumber = DBTC;
theVerId_signalNumber = GSN_TCINDXREQ;
- theLength = TcIndxReq::SignalLength;
+ theLength = TcKeyReq::SignalLength;
}
break;
diff --git a/ndb/src/ndbapi/NdbBlob.cpp b/ndb/src/ndbapi/NdbBlob.cpp
index 53c0a0e07f9..0ba14185adb 100644
--- a/ndb/src/ndbapi/NdbBlob.cpp
+++ b/ndb/src/ndbapi/NdbBlob.cpp
@@ -113,6 +113,8 @@ NdbBlob::getBlobTable(NdbTableImpl& bt, const NdbTableImpl* t, const NdbColumnIm
}
{ NdbDictionary::Column bc("PART");
bc.setType(NdbDictionary::Column::Unsigned);
+ assert(t->m_keyLenInWords != 0);
+ bc.setLength(t->m_keyLenInWords);
bc.setPrimaryKey(true);
bc.setDistributionKey(false);
bt.addColumn(bc);
@@ -346,7 +348,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 +371,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 +394,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 +1107,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 +1120,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 +1129,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 +1489,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;
diff --git a/ndb/src/ndbapi/NdbConnection.cpp b/ndb/src/ndbapi/NdbConnection.cpp
index 4f6468eb4ae..8cf7c46deee 100644
--- a/ndb/src/ndbapi/NdbConnection.cpp
+++ b/ndb/src/ndbapi/NdbConnection.cpp
@@ -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;
diff --git a/ndb/src/ndbapi/NdbDictionary.cpp b/ndb/src/ndbapi/NdbDictionary.cpp
index c8414ec16a3..4bc1fa8eb59 100644
--- a/ndb/src/ndbapi/NdbDictionary.cpp
+++ b/ndb/src/ndbapi/NdbDictionary.cpp
@@ -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;
@@ -956,6 +920,9 @@ operator<<(NdbOut& out, const NdbDictionary::Column& col)
out << " NOT NULL";
else
out << " NULL";
+
+ if(col.getDistributionKey())
+ out << " DISTRIBUTION KEY";
return out;
}
diff --git a/ndb/src/ndbapi/NdbDictionaryImpl.cpp b/ndb/src/ndbapi/NdbDictionaryImpl.cpp
index 304d1b904d4..446e9c3b1c0 100644
--- a/ndb/src/ndbapi/NdbDictionaryImpl.cpp
+++ b/ndb/src/ndbapi/NdbDictionaryImpl.cpp
@@ -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) ||
diff --git a/ndb/src/ndbapi/NdbDictionaryImpl.hpp b/ndb/src/ndbapi/NdbDictionaryImpl.hpp
index 12f0946ab67..955ac3ed3c7 100644
--- a/ndb/src/ndbapi/NdbDictionaryImpl.hpp
+++ b/ndb/src/ndbapi/NdbDictionaryImpl.hpp
@@ -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
diff --git a/ndb/src/ndbapi/NdbIndexOperation.cpp b/ndb/src/ndbapi/NdbIndexOperation.cpp
index 3f174a61b64..7bcb7e8b2b5 100644
--- a/ndb/src/ndbapi/NdbIndexOperation.cpp
+++ b/ndb/src/ndbapi/NdbIndexOperation.cpp
@@ -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;
@@ -73,16 +71,7 @@ NdbIndexOperation::indxInit(const NdbIndexImpl * anIndex,
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 +168,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 +208,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 +247,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 +301,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 +312,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 +329,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 +355,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 +365,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];
-
- theTCREQ->setLength(tcIndxReq->getAIInTcIndxReq(tReqInfo) +
- tAttrInfoIndex + TcIndxReq::StaticLength);
+ Tdata1 = tcKeyReq->attrInfo[0];
+ Tdata2 = tcKeyReq->attrInfo[1];
+ Tdata3 = tcKeyReq->attrInfo[2];
+ Tdata4 = tcKeyReq->attrInfo[3];
+ Tdata5 = tcKeyReq->attrInfo[4];
+
+ theTCREQ->setLength(tcKeyReq->getAIInTcKeyReq(tReqInfo) +
+ tAttrInfoIndex + TcKeyReq::StaticLength);
tAIDataPtr[0] = Tdata1;
tAIDataPtr[1] = Tdata2;
tAIDataPtr[2] = Tdata3;
@@ -722,11 +401,6 @@ NdbIndexOperation::prepareSend(Uint32 aTC_ConnectPtr, Uint64 aTransactionId)
return 0;
}
-void NdbIndexOperation::closeScan()
-{
- printf("NdbIndexOperation::closeScan NYI\n");
-}
-
/***************************************************************************
int receiveTCINDXREF( NdbApiSignal* aSignal)
diff --git a/ndb/src/ndbapi/NdbOperation.cpp b/ndb/src/ndbapi/NdbOperation.cpp
index 88d8a000d50..f0de2242d2a 100644
--- a/ndb/src/ndbapi/NdbOperation.cpp
+++ b/ndb/src/ndbapi/NdbOperation.cpp
@@ -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;
diff --git a/ndb/src/ndbapi/NdbOperationDefine.cpp b/ndb/src/ndbapi/NdbOperationDefine.cpp
index 35abb15b00d..d9aa860f71f 100644
--- a/ndb/src/ndbapi/NdbOperationDefine.cpp
+++ b/ndb/src/ndbapi/NdbOperationDefine.cpp
@@ -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;
diff --git a/ndb/src/ndbapi/NdbOperationExec.cpp b/ndb/src/ndbapi/NdbOperationExec.cpp
index 13664794dcd..bde0f4a0988 100644
--- a/ndb/src/ndbapi/NdbOperationExec.cpp
+++ b/ndb/src/ndbapi/NdbOperationExec.cpp
@@ -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();
diff --git a/ndb/src/ndbapi/NdbOperationSearch.cpp b/ndb/src/ndbapi/NdbOperationSearch.cpp
index 69b4e803acd..4f2d26f4501 100644
--- a/ndb/src/ndbapi/NdbOperationSearch.cpp
+++ b/ndb/src/ndbapi/NdbOperationSearch.cpp
@@ -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, (Uint32*)tmp - dst);
+ }
+ 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;
+}
diff --git a/ndb/src/ndbapi/NdbScanOperation.cpp b/ndb/src/ndbapi/NdbScanOperation.cpp
index 86bac7deb16..020d509360c 100644
--- a/ndb/src/ndbapi/NdbScanOperation.cpp
+++ b/ndb/src/ndbapi/NdbScanOperation.cpp
@@ -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 {
@@ -942,7 +892,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){
@@ -1077,37 +1027,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;
+ len = aValue != NULL ? sizeInBytes : 0;
+ if (len != sizeInBytes && (len != 0)) {
+ setErrorCodeAbort(4209);
+ return -1;
+ }
+
// normalize char bound
CHARSET_INFO* cs = tAttrInfo->m_cs;
- Uint32 xfrmData[2000];
+ 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,
+ (*cs->coll->strnxfrm)(cs,
(uchar*)xfrmData, sizeof(xfrmData),
- (const uchar*)aValue, sizeInBytes);
- while (n < sizeInBytes)
+ (const uchar*)aValue, len);
+
+ while (n < len)
((uchar*)xfrmData)[n++] = 0x20;
+
+ if(len & 3)
+ {
+ len += (4 - (len & 3));
+ }
+
aValue = (char*)xfrmData;
}
- if (len != sizeInBytes && (len != 0)) {
- setErrorCodeAbort(4209);
- return -1;
- }
+
// 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;
@@ -1115,12 +1079,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 };
@@ -1139,11 +1103,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
@@ -1559,10 +1523,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);
diff --git a/ndb/test/include/NDBT_Tables.hpp b/ndb/test/include/NDBT_Tables.hpp
index aa78f7d4e2c..fb0df8aa35b 100644
--- a/ndb/test/include/NDBT_Tables.hpp
+++ b/ndb/test/include/NDBT_Tables.hpp
@@ -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);
diff --git a/ndb/test/src/HugoOperations.cpp b/ndb/test/src/HugoOperations.cpp
index e8e2d992345..d3da8ae4ba2 100644
--- a/ndb/test/src/HugoOperations.cpp
+++ b/ndb/test/src/HugoOperations.cpp
@@ -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:
diff --git a/ndb/test/src/NDBT_Tables.cpp b/ndb/test/src/NDBT_Tables.cpp
index ff6db3e892c..b61d48b216c 100644
--- a/ndb/test/src/NDBT_Tables.cpp
+++ b/ndb/test/src/NDBT_Tables.cpp
@@ -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;
diff --git a/ndb/test/src/NdbSchemaOp.cpp b/ndb/test/src/NdbSchemaOp.cpp
index a296094ea9d..9bce0b10fc3 100644
--- a/ndb/test/src/NdbSchemaOp.cpp
+++ b/ndb/test/src/NdbSchemaOp.cpp
@@ -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 : "");