summaryrefslogtreecommitdiff
path: root/ndb/include
diff options
context:
space:
mode:
Diffstat (limited to 'ndb/include')
-rw-r--r--ndb/include/Makefile.am1
-rw-r--r--ndb/include/debugger/EventLogger.hpp7
-rw-r--r--ndb/include/kernel/GlobalSignalNumbers.h11
-rw-r--r--ndb/include/kernel/Interpreter.hpp6
-rw-r--r--ndb/include/kernel/NodeInfo.hpp9
-rw-r--r--ndb/include/kernel/NodeState.hpp21
-rw-r--r--ndb/include/kernel/kernel_config_parameters.h5
-rw-r--r--ndb/include/kernel/ndb_limits.h2
-rw-r--r--ndb/include/kernel/signaldata/CreateFragmentation.hpp2
-rw-r--r--ndb/include/kernel/signaldata/DictTabInfo.hpp6
-rw-r--r--ndb/include/kernel/signaldata/DropTab.hpp3
-rw-r--r--ndb/include/kernel/signaldata/DumpStateOrd.hpp1
-rw-r--r--ndb/include/kernel/signaldata/KeyInfo.hpp1
-rw-r--r--ndb/include/kernel/signaldata/PrepDropTab.hpp6
-rw-r--r--ndb/include/kernel/signaldata/ScanTab.hpp155
-rw-r--r--ndb/include/kernel/signaldata/SignalData.hpp16
-rw-r--r--ndb/include/kernel/signaldata/StartInfo.hpp2
-rw-r--r--ndb/include/kernel/signaldata/TcCommit.hpp1
-rw-r--r--ndb/include/kernel/signaldata/TcKeyReq.hpp1
-rw-r--r--ndb/include/kernel/signaldata/TupAccess.hpp174
-rw-r--r--ndb/include/mgmapi/mgmapi.h15
-rw-r--r--ndb/include/mgmapi/mgmapi_config_parameters.h3
-rw-r--r--ndb/include/mgmapi/mgmapi_debug.h25
-rw-r--r--ndb/include/mgmcommon/ConfigRetriever.hpp45
-rw-r--r--ndb/include/mgmcommon/LocalConfig.hpp67
-rw-r--r--ndb/include/mgmcommon/MgmtErrorReporter.hpp6
-rw-r--r--ndb/include/mgmcommon/NdbConfig.h13
-rw-r--r--ndb/include/ndb_global.h12
-rw-r--r--ndb/include/ndbapi/Ndb.hpp42
-rw-r--r--ndb/include/ndbapi/NdbApi.hpp2
-rw-r--r--ndb/include/ndbapi/NdbBlob.hpp86
-rw-r--r--ndb/include/ndbapi/NdbConnection.hpp193
-rw-r--r--ndb/include/ndbapi/NdbCursorOperation.hpp73
-rw-r--r--ndb/include/ndbapi/NdbDictionary.hpp13
-rw-r--r--ndb/include/ndbapi/NdbIndexOperation.hpp2
-rw-r--r--ndb/include/ndbapi/NdbIndexScanOperation.hpp140
-rw-r--r--ndb/include/ndbapi/NdbOperation.hpp246
-rw-r--r--ndb/include/ndbapi/NdbRecAttr.hpp50
-rw-r--r--ndb/include/ndbapi/NdbReceiver.hpp67
-rw-r--r--ndb/include/ndbapi/NdbResultSet.hpp54
-rw-r--r--ndb/include/ndbapi/NdbScanOperation.hpp231
-rw-r--r--ndb/include/portlib/NdbTCP.h2
-rw-r--r--ndb/include/transporter/TransporterDefinitions.hpp1
-rw-r--r--ndb/include/transporter/TransporterRegistry.hpp83
-rw-r--r--ndb/include/util/BaseString.hpp2
-rw-r--r--ndb/include/util/Bitmask.hpp171
-rw-r--r--ndb/include/util/ConfigValues.hpp6
-rw-r--r--ndb/include/util/NdbSqlUtil.hpp126
-rw-r--r--ndb/include/util/Properties.hpp2
-rw-r--r--ndb/include/util/SocketAuthenticator.hpp39
-rw-r--r--ndb/include/util/SocketClient.hpp38
51 files changed, 1086 insertions, 1199 deletions
diff --git a/ndb/include/Makefile.am b/ndb/include/Makefile.am
index 2565a78238b..b1b7951f216 100644
--- a/ndb/include/Makefile.am
+++ b/ndb/include/Makefile.am
@@ -23,6 +23,7 @@ ndbapi/NdbReceiver.hpp \
ndbapi/NdbResultSet.hpp \
ndbapi/NdbScanFilter.hpp \
ndbapi/NdbScanOperation.hpp \
+ndbapi/NdbIndexScanOperation.hpp \
ndbapi/ndberror.h
mgmapiinclude_HEADERS = \
diff --git a/ndb/include/debugger/EventLogger.hpp b/ndb/include/debugger/EventLogger.hpp
index c49bd176ee8..6cd6a83e68d 100644
--- a/ndb/include/debugger/EventLogger.hpp
+++ b/ndb/include/debugger/EventLogger.hpp
@@ -73,13 +73,6 @@ public:
~EventLogger();
/**
- * Open/create the eventlog, the default name is 'cluster.log'.
- *
- * @return true if successful.
- */
- bool open();
-
- /**
* Opens/creates the eventlog with the specified filename.
*
* @param aFileName the eventlog filename.
diff --git a/ndb/include/kernel/GlobalSignalNumbers.h b/ndb/include/kernel/GlobalSignalNumbers.h
index 7b70f4c3ac0..8941fa6b381 100644
--- a/ndb/include/kernel/GlobalSignalNumbers.h
+++ b/ndb/include/kernel/GlobalSignalNumbers.h
@@ -84,7 +84,7 @@ extern const GlobalSignalNumber NO_OF_SIGNAL_NAMES;
#define GSN_SCAN_NEXTREQ 28
#define GSN_SCAN_TABCONF 29
-#define GSN_SCAN_TABINFO 30
+// 30 unused
#define GSN_SCAN_TABREF 31
#define GSN_SCAN_TABREQ 32
#define GSN_KEYINFO20 33
@@ -897,12 +897,9 @@ extern const GlobalSignalNumber NO_OF_SIGNAL_NAMES;
#define GSN_TUX_MAINT_CONF 678
#define GSN_TUX_MAINT_REF 679
-/*
- * TUP access
- */
-#define GSN_TUP_READ_ATTRS 680
-#define GSN_TUP_QUERY_TH 712
-#define GSN_TUP_STORE_TH 681
+// not used 680
+// not used 712
+// not used 681
/**
* from mgmtsrvr to NDBCNTR
diff --git a/ndb/include/kernel/Interpreter.hpp b/ndb/include/kernel/Interpreter.hpp
index 2c282be361c..74399f5732e 100644
--- a/ndb/include/kernel/Interpreter.hpp
+++ b/ndb/include/kernel/Interpreter.hpp
@@ -83,7 +83,7 @@ public:
static Uint32 LoadConst64(Uint32 Register); // Value in next 2 words
static Uint32 Add(Uint32 DstReg, Uint32 SrcReg1, Uint32 SrcReg2);
static Uint32 Sub(Uint32 DstReg, Uint32 SrcReg1, Uint32 SrcReg2);
- static Uint32 Branch(Uint32 Inst, Uint32 R1, Uint32 R2);
+ static Uint32 Branch(Uint32 Inst, Uint32 Reg1, Uint32 Reg2);
static Uint32 ExitOK();
/**
@@ -184,8 +184,8 @@ Interpreter::Sub(Uint32 Dcoleg, Uint32 SrcReg1, Uint32 SrcReg2){
inline
Uint32
-Interpreter::Branch(Uint32 Inst, Uint32 R1, Uint32 R2){
- return (R1 << 9) + (R2 << 6) + Inst;
+Interpreter::Branch(Uint32 Inst, Uint32 Reg1, Uint32 Reg2){
+ return (Reg1 << 9) + (Reg2 << 6) + Inst;
}
inline
diff --git a/ndb/include/kernel/NodeInfo.hpp b/ndb/include/kernel/NodeInfo.hpp
index 86aca7d6883..5377f001949 100644
--- a/ndb/include/kernel/NodeInfo.hpp
+++ b/ndb/include/kernel/NodeInfo.hpp
@@ -18,6 +18,7 @@
#define NODE_INFO_HPP
#include <NdbOut.hpp>
+#include <mgmapi_config_parameters.h>
class NodeInfo {
public:
@@ -27,10 +28,10 @@ public:
* NodeType
*/
enum NodeType {
- DB = 0, ///< Database node
- API = 1, ///< NDB API node
- MGM = 2, ///< Management node (incl. NDB API)
- REP = 3, ///< Replication node (incl. NDB API)
+ DB = NODE_TYPE_DB, ///< Database node
+ API = NODE_TYPE_API, ///< NDB API node
+ MGM = NODE_TYPE_MGM, ///< Management node (incl. NDB API)
+ REP = NODE_TYPE_REP, ///< Replication node (incl. NDB API)
INVALID = 255 ///< Invalid type
};
NodeType getType() const;
diff --git a/ndb/include/kernel/NodeState.hpp b/ndb/include/kernel/NodeState.hpp
index 1bc7806876d..185e3ea8ea4 100644
--- a/ndb/include/kernel/NodeState.hpp
+++ b/ndb/include/kernel/NodeState.hpp
@@ -18,6 +18,7 @@
#define NODE_STATE_HPP
#include <NdbOut.hpp>
+#include <NodeBitmask.hpp>
class NodeState {
public:
@@ -99,7 +100,7 @@ public:
/**
* Length in 32-bit words
*/
- static const Uint32 DataLength = 8;
+ static const Uint32 DataLength = 8 + NdbNodeBitmask::Size;
/**
* Constructor(s)
@@ -108,7 +109,8 @@ public:
NodeState(StartLevel);
NodeState(StartLevel, bool systemShutdown);
NodeState(StartLevel, Uint32 startPhase, StartType);
-
+ void init();
+
/**
* Current start level
*/
@@ -146,6 +148,8 @@ public:
Uint32 singleUserMode;
Uint32 singleUserApi; //the single user node
+ BitmaskPOD<NdbNodeBitmask::Size> m_connected_nodes;
+
void setDynamicId(Uint32 dynamic);
void setNodeGroup(Uint32 group);
void setSingleUser(Uint32 s);
@@ -177,16 +181,23 @@ public:
inline
NodeState::NodeState(){
+ init();
+}
+
+inline
+void
+NodeState::init(){
startLevel = SL_CMVMI;
nodeGroup = 0xFFFFFFFF;
dynamicId = 0xFFFFFFFF;
singleUserMode = 0;
singleUserApi = 0xFFFFFFFF;
+ m_connected_nodes.clear();
}
inline
NodeState::NodeState(StartLevel sl){
- NodeState::NodeState();
+ init();
startLevel = sl;
singleUserMode = 0;
singleUserApi = 0xFFFFFFFF;
@@ -194,7 +205,7 @@ NodeState::NodeState(StartLevel sl){
inline
NodeState::NodeState(StartLevel sl, Uint32 sp, StartType typeOfStart){
- NodeState::NodeState();
+ init();
startLevel = sl;
starting.startPhase = sp;
starting.restartType = typeOfStart;
@@ -204,7 +215,7 @@ NodeState::NodeState(StartLevel sl, Uint32 sp, StartType typeOfStart){
inline
NodeState::NodeState(StartLevel sl, bool sys){
- NodeState::NodeState();
+ init();
startLevel = sl;
stopping.systemShutdown = sys;
singleUserMode = 0;
diff --git a/ndb/include/kernel/kernel_config_parameters.h b/ndb/include/kernel/kernel_config_parameters.h
index 2f63efa4b6c..bb7c6ebd42c 100644
--- a/ndb/include/kernel/kernel_config_parameters.h
+++ b/ndb/include/kernel/kernel_config_parameters.h
@@ -14,10 +14,7 @@
#define CFG_ACC_SCAN (PRIVATE_BASE + 9)
#define CFG_DICT_ATTRIBUTE (PRIVATE_BASE + 10)
-#define CFG_DICT_CONNECT (PRIVATE_BASE + 11)
-#define CFG_DICT_FRAG_CONNECT (PRIVATE_BASE + 12)
#define CFG_DICT_TABLE (PRIVATE_BASE + 13)
-#define CFG_DICT_TC_CONNECT (PRIVATE_BASE + 14)
#define CFG_DIH_API_CONNECT (PRIVATE_BASE + 15)
#define CFG_DIH_CONNECT (PRIVATE_BASE + 16)
@@ -27,10 +24,8 @@
#define CFG_DIH_TABLE (PRIVATE_BASE + 20)
#define CFG_LQH_FRAG (PRIVATE_BASE + 21)
-#define CFG_LQH_CONNECT (PRIVATE_BASE + 22)
#define CFG_LQH_TABLE (PRIVATE_BASE + 23)
#define CFG_LQH_TC_CONNECT (PRIVATE_BASE + 24)
-#define CFG_LQH_REPLICAS (PRIVATE_BASE + 25)
#define CFG_LQH_LOG_FILES (PRIVATE_BASE + 26)
#define CFG_LQH_SCAN (PRIVATE_BASE + 27)
diff --git a/ndb/include/kernel/ndb_limits.h b/ndb/include/kernel/ndb_limits.h
index 68ffe310328..f35cc617e86 100644
--- a/ndb/include/kernel/ndb_limits.h
+++ b/ndb/include/kernel/ndb_limits.h
@@ -88,7 +88,7 @@
* Ordered index constants. Make configurable per index later.
*/
#define MAX_TTREE_NODE_SIZE 64 // total words in node
-#define MAX_TTREE_PREF_SIZE 4 // words in min/max prefix each
+#define MAX_TTREE_PREF_SIZE 4 // words in min prefix
#define MAX_TTREE_NODE_SLACK 3 // diff between max and min occupancy
/*
diff --git a/ndb/include/kernel/signaldata/CreateFragmentation.hpp b/ndb/include/kernel/signaldata/CreateFragmentation.hpp
index a2f45a9580d..7d53dd91154 100644
--- a/ndb/include/kernel/signaldata/CreateFragmentation.hpp
+++ b/ndb/include/kernel/signaldata/CreateFragmentation.hpp
@@ -88,7 +88,7 @@ class CreateFragmentationConf {
friend bool printCREATE_FRAGMENTATION_CONF(FILE *,
const Uint32 *, Uint32, Uint16);
public:
- STATIC_CONST( SignalLength = 3 );
+ STATIC_CONST( SignalLength = 4 );
SECTION( FRAGMENTS = 0 );
private:
diff --git a/ndb/include/kernel/signaldata/DictTabInfo.hpp b/ndb/include/kernel/signaldata/DictTabInfo.hpp
index 67610f9d2be..dec7145c897 100644
--- a/ndb/include/kernel/signaldata/DictTabInfo.hpp
+++ b/ndb/include/kernel/signaldata/DictTabInfo.hpp
@@ -100,6 +100,7 @@ public:
CustomTriggerId = 25,
FrmLen = 26,
FrmData = 27,
+ FragmentCount = 128, // No of fragments in table (!fragment replicas)
TableEnd = 999,
AttributeName = 1000, // String, Mandatory
@@ -277,6 +278,7 @@ public:
Uint32 CustomTriggerId;
Uint32 FrmLen;
char FrmData[MAX_FRM_DATA_SIZE];
+ Uint32 FragmentCount;
void init();
};
@@ -309,7 +311,7 @@ public:
ExtDatetime = NdbSqlUtil::Type::Datetime,
ExtTimespec = NdbSqlUtil::Type::Timespec,
ExtBlob = NdbSqlUtil::Type::Blob,
- ExtClob = NdbSqlUtil::Type::Clob
+ ExtText = NdbSqlUtil::Type::Text
};
// Attribute data interpretation
@@ -433,7 +435,7 @@ public:
AttributeArraySize = 12 * AttributeExtLength;
return true;
case DictTabInfo::ExtBlob:
- case DictTabInfo::ExtClob:
+ case DictTabInfo::ExtText:
AttributeType = DictTabInfo::StringType;
AttributeSize = DictTabInfo::an8Bit;
// head + inline part [ attr precision ]
diff --git a/ndb/include/kernel/signaldata/DropTab.hpp b/ndb/include/kernel/signaldata/DropTab.hpp
index 906f952d852..dd3946d8cc0 100644
--- a/ndb/include/kernel/signaldata/DropTab.hpp
+++ b/ndb/include/kernel/signaldata/DropTab.hpp
@@ -101,7 +101,8 @@ public:
NoSuchTable = 1,
DropWoPrep = 2, // Calling Drop with first calling PrepDrop
PrepDropInProgress = 3,
- DropInProgress = 4
+ DropInProgress = 4,
+ NF_FakeErrorREF = 5
};
private:
diff --git a/ndb/include/kernel/signaldata/DumpStateOrd.hpp b/ndb/include/kernel/signaldata/DumpStateOrd.hpp
index 6403a52926f..1e349fad55a 100644
--- a/ndb/include/kernel/signaldata/DumpStateOrd.hpp
+++ b/ndb/include/kernel/signaldata/DumpStateOrd.hpp
@@ -94,6 +94,7 @@ public:
TcDumpOneApiConnectRec = 2505,
TcDumpAllApiConnectRec = 2506,
TcSetTransactionTimeout = 2507,
+ TcSetApplTransactionTimeout = 2508,
CmvmiDumpConnections = 2600,
CmvmiDumpLongSignalMemory = 2601,
CmvmiSetRestartOnErrorInsert = 2602,
diff --git a/ndb/include/kernel/signaldata/KeyInfo.hpp b/ndb/include/kernel/signaldata/KeyInfo.hpp
index b839a2c2035..a4c698f89b2 100644
--- a/ndb/include/kernel/signaldata/KeyInfo.hpp
+++ b/ndb/include/kernel/signaldata/KeyInfo.hpp
@@ -25,6 +25,7 @@ class KeyInfo {
*/
friend class DbUtil;
friend class NdbOperation;
+ friend class NdbScanOperation;
/**
* Reciver(s)
diff --git a/ndb/include/kernel/signaldata/PrepDropTab.hpp b/ndb/include/kernel/signaldata/PrepDropTab.hpp
index e9cc28fed0c..c54b2474aa3 100644
--- a/ndb/include/kernel/signaldata/PrepDropTab.hpp
+++ b/ndb/include/kernel/signaldata/PrepDropTab.hpp
@@ -88,7 +88,8 @@ public:
NoSuchTable = 1,
PrepDropInProgress = 2,
DropInProgress = 3,
- InvalidTableState = 4
+ InvalidTableState = 4,
+ NF_FakeErrorREF = 5
};
private:
@@ -137,7 +138,8 @@ public:
enum ErrorCode {
NoSuchTable = 1,
IllegalTableState = 2,
- DropInProgress = 3
+ DropInProgress = 3,
+ NF_FakeErrorREF = 4
};
Uint32 tableId;
diff --git a/ndb/include/kernel/signaldata/ScanTab.hpp b/ndb/include/kernel/signaldata/ScanTab.hpp
index efd8a4918ab..ab2978e48da 100644
--- a/ndb/include/kernel/signaldata/ScanTab.hpp
+++ b/ndb/include/kernel/signaldata/ScanTab.hpp
@@ -33,8 +33,8 @@ class ScanTabReq {
/**
* Sender(s)
*/
- friend class NdbOperation;
friend class NdbConnection;
+ friend class NdbScanOperation;
/**
* For printing
@@ -73,6 +73,7 @@ private:
static Uint8 getHoldLockFlag(const UintR & requestInfo);
static Uint8 getReadCommittedFlag(const UintR & requestInfo);
static Uint8 getRangeScanFlag(const UintR & requestInfo);
+ static Uint8 getScanBatch(const UintR & requestInfo);
/**
* Set:ers for requestInfo
@@ -83,7 +84,7 @@ private:
static void setHoldLockFlag(UintR & requestInfo, Uint32 flag);
static void setReadCommittedFlag(UintR & requestInfo, Uint32 flag);
static void setRangeScanFlag(UintR & requestInfo, Uint32 flag);
-
+ static void setScanBatch(Uint32& requestInfo, Uint32 sz);
};
/**
@@ -94,10 +95,11 @@ private:
h = Hold lock mode - 1 Bit 10
c = Read Committed - 1 Bit 11
x = Range Scan (TUX) - 1 Bit 15
+ b = Scan batch - 5 Bit 16-19 (max 15)
1111111111222222222233
01234567890123456789012345678901
- ppppppppl hc x
+ ppppppppl hc xbbbbb
*/
#define PARALLELL_SHIFT (0)
@@ -115,6 +117,9 @@ private:
#define RANGE_SCAN_SHIFT (15)
#define RANGE_SCAN_MASK (1)
+#define SCAN_BATCH_SHIFT (16)
+#define SCAN_BATCH_MASK (31)
+
inline
Uint8
ScanTabReq::getParallelism(const UintR & requestInfo){
@@ -146,6 +151,12 @@ ScanTabReq::getRangeScanFlag(const UintR & requestInfo){
}
inline
+Uint8
+ScanTabReq::getScanBatch(const Uint32 & requestInfo){
+ return (Uint8)((requestInfo >> SCAN_BATCH_SHIFT) & SCAN_BATCH_MASK);
+}
+
+inline
void
ScanTabReq::clearRequestInfo(UintR & requestInfo){
requestInfo = 0;
@@ -186,6 +197,12 @@ ScanTabReq::setRangeScanFlag(UintR & requestInfo, Uint32 flag){
requestInfo |= (flag << RANGE_SCAN_SHIFT);
}
+inline
+void
+ScanTabReq::setScanBatch(Uint32 & requestInfo, Uint32 flag){
+ ASSERT_MAX(flag, SCAN_BATCH_MASK, "ScanTabReq::setScanBatch");
+ requestInfo |= (flag << SCAN_BATCH_SHIFT);
+}
/**
*
@@ -213,7 +230,8 @@ public:
* Length of signal
*/
STATIC_CONST( SignalLength = 4 );
-
+ static const Uint32 EndOfData = (1 << 31);
+
private:
// Type definitions
@@ -225,29 +243,15 @@ private:
UintR requestInfo; // DATA 1
UintR transId1; // DATA 2
UintR transId2; // DATA 3
-#if 0
- UintR operLenAndIdx[16]; // DATA 4-19
-
- /**
- * Get:ers for operLenAndIdx
- */
- static Uint32 getLen(const UintR & operLenAndIdx);
- static Uint8 getIdx(const UintR & operLenAndIdx);
-#endif
-
- /**
- * Get:ers for requestInfo
- */
- static Uint8 getOperations(const UintR & reqInfo);
- static Uint8 getScanStatus(const UintR & reqInfo);
-
- /**
- * Set:ers for requestInfo
- */
- static void setOperations(UintR & reqInfo, Uint32 ops);
- static void setScanStatus(UintR & reqInfo, Uint32 stat);
+ struct OpData {
+ Uint32 apiPtrI;
+ Uint32 tcPtrI;
+ Uint32 info;
+ };
+ static Uint32 getLength(Uint32 opDataInfo) { return opDataInfo >> 5; };
+ static Uint32 getRows(Uint32 opDataInfo) { return opDataInfo & 31;}
};
/**
@@ -267,103 +271,6 @@ private:
#define STATUS_SHIFT (8)
#define STATUS_MASK (0xFF)
-inline
-Uint8
-ScanTabConf::getOperations(const UintR & reqInfo){
- return (Uint8)((reqInfo >> OPERATIONS_SHIFT) & OPERATIONS_MASK);
-}
-
-inline
-void
-ScanTabConf::setOperations(UintR & requestInfo, Uint32 ops){
- ASSERT_MAX(ops, OPERATIONS_MASK, "ScanTabConf::setOperations");
- requestInfo |= (ops << OPERATIONS_SHIFT);
-}
-
-inline
-Uint8
-ScanTabConf::getScanStatus(const UintR & reqInfo){
- return (Uint8)((reqInfo >> STATUS_SHIFT) & STATUS_MASK);
-}
-
-inline
-void
-ScanTabConf::setScanStatus(UintR & requestInfo, Uint32 stat){
- ASSERT_MAX(stat, STATUS_MASK, "ScanTabConf::setScanStatus");
- requestInfo |= (stat << STATUS_SHIFT);
-}
-
-
-/**
- *
- * SENDER: Dbtc, API
- * RECIVER: API, Dbtc
- */
-class ScanTabInfo {
- /**
- * Reciver(s) and Sender(s)
- */
- friend class NdbConnection;
- friend class Dbtc;
-
- /**
- * For printing
- */
- friend bool printSCANTABINFO(FILE * output, const Uint32 * theData, Uint32 len, Uint16 receiverBlockNo);
-
-public:
- /**
- * Length of signal
- */
- STATIC_CONST( SignalLength = 17 );
-
-private:
-
- // Type definitions
-
- /**
- * DATA VARIABLES
- */
- UintR apiConnectPtr; // DATA 0
- UintR operLenAndIdx[16]; // DATA 1-16
-
- /**
- * Get:ers for operLenAndIdx
- */
- static Uint32 getLen(const UintR & operLenAndIdx);
- static Uint8 getIdx(const UintR & operLenAndIdx);
-
-};
-
-
-/**
- * Operation length and index
- *
- l = Length of operation - 24 Bits -> Max 16777215 (Bit 0-24)
- i = Index of operation - 7 Bits -> Max 255 (Bit 25-32)
-
- 1111111111222222222233
- 01234567890123456789012345678901
- llllllllllllllllllllllllliiiiiii
-*/
-
-#define LENGTH_SHIFT (0)
-#define LENGTH_MASK (0xFFFFFF)
-
-#define INDEX_SHIFT (24)
-#define INDEX_MASK (0xFF)
-
-inline
-Uint32
-ScanTabInfo::getLen(const UintR & operLenAndIdx){
- return (Uint32)((operLenAndIdx >> LENGTH_SHIFT) & LENGTH_MASK);
-}
-
-inline
-Uint8
-ScanTabInfo::getIdx(const UintR & operLenAndIdx){
- return (Uint8)((operLenAndIdx >> INDEX_SHIFT) & INDEX_MASK);
-}
/**
*
@@ -390,7 +297,7 @@ public:
/**
* Length of signal
*/
- STATIC_CONST( SignalLength = 4 );
+ STATIC_CONST( SignalLength = 5 );
private:
@@ -403,7 +310,7 @@ private:
UintR transId1; // DATA 1
UintR transId2; // DATA 2
UintR errorCode; // DATA 3
- // UintR sendScanNextReqWithClose; // DATA 4
+ UintR closeNeeded; // DATA 4
};
diff --git a/ndb/include/kernel/signaldata/SignalData.hpp b/ndb/include/kernel/signaldata/SignalData.hpp
index 511e7d30c21..6e5748217b2 100644
--- a/ndb/include/kernel/signaldata/SignalData.hpp
+++ b/ndb/include/kernel/signaldata/SignalData.hpp
@@ -21,20 +21,10 @@
#include <ndb_limits.h>
#include <kernel_types.h>
-#ifndef NDB_ASSERT
-#ifdef VM_TRACE
-#define NDB_ASSERT(test, message) { if(!(test)) { printf(message); exit(-1); }}
-#else
-#define NDB_ASSERT(test, message)
-#endif
-#endif
-
-// Useful ASSERT macros...
-#define ASSERT_BOOL(flag, message) NDB_ASSERT( (flag<=1), (message) )
+#define ASSERT_BOOL(flag, message) assert(flag<=1)
#define ASSERT_RANGE(value, min, max, message) \
- NDB_ASSERT((value) >= (min) && (value) <= (max), (message))
-#define ASSERT_MAX(value, max, message) \
- NDB_ASSERT((value) <= (max), (message))
+ assert((value) >= (min) && (value) <= (max))
+#define ASSERT_MAX(value, max, message) assert((value) <= (max))
#define SECTION(x) STATIC_CONST(x)
diff --git a/ndb/include/kernel/signaldata/StartInfo.hpp b/ndb/include/kernel/signaldata/StartInfo.hpp
index da032adba8a..d0850b13ef4 100644
--- a/ndb/include/kernel/signaldata/StartInfo.hpp
+++ b/ndb/include/kernel/signaldata/StartInfo.hpp
@@ -78,7 +78,7 @@ class StartInfoRef {
Uint32 errorCode;
public:
- STATIC_CONST( SignalLength = 2 );
+ STATIC_CONST( SignalLength = 3 );
};
#endif
diff --git a/ndb/include/kernel/signaldata/TcCommit.hpp b/ndb/include/kernel/signaldata/TcCommit.hpp
index 43eb7be1c39..b7f3fbbb361 100644
--- a/ndb/include/kernel/signaldata/TcCommit.hpp
+++ b/ndb/include/kernel/signaldata/TcCommit.hpp
@@ -33,6 +33,7 @@ class TcCommitConf {
* Reciver(s)
*/
friend class Ndb;
+ friend class NdbConnection;
public:
STATIC_CONST( SignalLength = 3 );
diff --git a/ndb/include/kernel/signaldata/TcKeyReq.hpp b/ndb/include/kernel/signaldata/TcKeyReq.hpp
index df0a00da3e0..f7d3c2e3282 100644
--- a/ndb/include/kernel/signaldata/TcKeyReq.hpp
+++ b/ndb/include/kernel/signaldata/TcKeyReq.hpp
@@ -38,6 +38,7 @@ class TcKeyReq {
friend class Ndbcntr;
friend class NdbOperation;
friend class NdbIndexOperation;
+ friend class NdbScanOperation;
friend class DbUtil;
/**
diff --git a/ndb/include/kernel/signaldata/TupAccess.hpp b/ndb/include/kernel/signaldata/TupAccess.hpp
deleted file mode 100644
index ab56a73322c..00000000000
--- a/ndb/include/kernel/signaldata/TupAccess.hpp
+++ /dev/null
@@ -1,174 +0,0 @@
-/* Copyright (C) 2003 MySQL AB
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
-
-#ifndef TUP_ACCESS_HPP
-#define TUP_ACCESS_HPP
-
-#include "SignalData.hpp"
-
-/*
- * Direct signals used by ACC and TUX to access the TUP block in the
- * same thread.
- *
- * NOTE: Caller must set errorCode to RNIL. Signal printer uses this to
- * distinguish between input and output (no better way exists).
- */
-
-/*
- * Read attributes from any table.
- */
-class TupReadAttrs {
- friend class Dbtup;
- friend class Dbacc;
- friend class Dbtux;
- friend bool printTUP_READ_ATTRS(FILE*, const Uint32*, Uint32, Uint16);
-public:
- enum Flag {
- /*
- * Read primary key attributes. No input attribute ids are
- * specified. Instead TUP fills in both input and output sections.
- * Tuple version is not used.
- */
- ReadKeys = (1 << 0)
- };
- STATIC_CONST( SignalLength = 10 );
-private:
- /*
- * Error code set by TUP. Zero means no error.
- */
- Uint32 errorCode;
- /*
- * Request info contains flags (see Flags above).
- */
- Uint32 requestInfo;
- /*
- * Table i-value.
- */
- Uint32 tableId;
- /*
- * Fragment is given by logical id within the table or by direct
- * i-value (faster). Unknown values are given as RNIL. On return TUP
- * fills in both values.
- */
- Uint32 fragId;
- Uint32 fragPtrI;
- /*
- * Logical address ("local key") of "original" tuple (the latest
- * version) consisting of logical fragment page id and tuple index
- * within the page (shifted left by 1).
- */
- Uint32 tupAddr;
- /*
- * Version of the tuple to read. Not used if ReadKeys.
- */
- Uint32 tupVersion;
- /*
- * Real page id and offset of the "original" tuple. Unknown page is
- * given as RNIL. On return TUP fills in these.
- */
- Uint32 pageId;
- Uint32 pageOffset;
- /*
- * Shared buffer id. Currently must be 0 which means to use rest of
- * signal data.
- */
- Uint32 bufferId;
- /*
- * Shared buffer 0 starts after signal class. Input is number of
- * attributes and list of attribute ids in AttributeHeader format.
- * Output is placed after the input and consists of a list of entries
- * where each entry has an AttributeHeader followed by words of data.
- */
-};
-
-/*
- * Query status of tuple version. Used by TUX to decide if a tuple
- * version found in index tree is visible to the transaction.
- */
-class TupQueryTh {
- friend class Dbtup;
- friend class Dbtux;
- friend bool printTUP_QUERY_TH(FILE*, const Uint32*, Uint32, Uint16);
-public:
- enum Flag {
- };
- STATIC_CONST( SignalLength = 7 );
-private:
- /*
- TUX wants to check if tuple is visible to the scan query.
- Input data is tuple address (tableId, fragId, tupAddr, tupVersion),
- and transaction data so that TUP knows how to deduct if tuple is
- visible (transId1, transId2, savePointId).
- returnCode is set in return signal to indicate whether tuple is visible.
- */
- union {
- Uint32 returnCode; // 1 if tuple visible
- Uint32 tableId;
- };
- Uint32 fragId;
- Uint32 tupAddr;
- Uint32 tupVersion;
- Uint32 transId1;
- Uint32 transId2;
- Uint32 savePointId;
-};
-
-/*
- * Operate on entire tuple. Used by TUX where the table has a single
- * Uint32 array attribute representing an index tree node.
- *
- * XXX this signal is no longer used by TUX and can be removed
- */
-class TupStoreTh {
- friend class Dbtup;
- friend class Dbtux;
- friend bool printTUP_STORE_TH(FILE*, const Uint32*, Uint32, Uint16);
-public:
- enum OpCode {
- OpUndefined = 0,
- OpRead = 1,
- OpInsert = 2,
- OpUpdate = 3,
- OpDelete = 4
- };
- STATIC_CONST( SignalLength = 12 );
-private:
- /*
- * These are as in TupReadAttrs (except opCode). Version must be
- * zero. Ordered index tuple (tree node) has only current version.
- */
- Uint32 errorCode;
- Uint32 opCode;
- Uint32 tableId;
- Uint32 fragId;
- Uint32 fragPtrI;
- Uint32 tupAddr;
- Uint32 tupVersion;
- Uint32 pageId;
- Uint32 pageOffset;
- Uint32 bufferId;
- /*
- * Data offset and size in words. Applies to both the buffer and the
- * tuple. Used e.g. to read only node header.
- */
- Uint32 dataOffset;
- Uint32 dataSize;
- /*
- * Shared buffer 0 starts after signal class.
- */
-};
-
-#endif
diff --git a/ndb/include/mgmapi/mgmapi.h b/ndb/include/mgmapi/mgmapi.h
index 7b2f728bda8..123297b0d71 100644
--- a/ndb/include/mgmapi/mgmapi.h
+++ b/ndb/include/mgmapi/mgmapi.h
@@ -49,6 +49,8 @@
* @{
*/
+#include "mgmapi_config_parameters.h"
+
#ifdef __cplusplus
extern "C" {
#endif
@@ -81,10 +83,10 @@ extern "C" {
*/
enum ndb_mgm_node_type {
NDB_MGM_NODE_TYPE_UNKNOWN = -1, /*/< Node type not known*/
- NDB_MGM_NODE_TYPE_API = 0, /*/< An application node (API)*/
- NDB_MGM_NODE_TYPE_NDB = 1, /*/< A database node (DB)*/
- NDB_MGM_NODE_TYPE_MGM = 2, /*/< A management server node (MGM)*/
- NDB_MGM_NODE_TYPE_REP = 3, ///< A replication node
+ NDB_MGM_NODE_TYPE_API = NODE_TYPE_API, /*/< An application node (API)*/
+ NDB_MGM_NODE_TYPE_NDB = NODE_TYPE_DB, /*/< A database node (DB)*/
+ NDB_MGM_NODE_TYPE_MGM = NODE_TYPE_MGM, /*/< A management server node (MGM)*/
+ NDB_MGM_NODE_TYPE_REP = NODE_TYPE_REP, ///< A replication node
NDB_MGM_NODE_TYPE_MIN = 0, /*/< Min valid value*/
NDB_MGM_NODE_TYPE_MAX = 3 /*/< Max valid value*/
@@ -666,6 +668,11 @@ extern "C" {
*/
struct ndb_mgm_configuration * ndb_mgm_get_configuration(NdbMgmHandle handle,
unsigned version);
+
+ int ndb_mgm_alloc_nodeid(NdbMgmHandle handle,
+ unsigned version,
+ unsigned *pnodeid,
+ int nodetype);
/**
* Config iterator
*/
diff --git a/ndb/include/mgmapi/mgmapi_config_parameters.h b/ndb/include/mgmapi/mgmapi_config_parameters.h
index d3bb44c1523..3eca49055fe 100644
--- a/ndb/include/mgmapi/mgmapi_config_parameters.h
+++ b/ndb/include/mgmapi/mgmapi_config_parameters.h
@@ -6,6 +6,7 @@
#define CFG_SYS_PRIMARY_MGM_NODE 1
#define CFG_SYS_CONFIG_GENERATION 2
#define CFG_SYS_REPLICATION_ROLE 7
+#define CFG_SYS_PORT_BASE 8
#define CFG_NODE_ID 3
#define CFG_NODE_BYTE_ORDER 4
@@ -87,11 +88,11 @@
#define CFG_CONNECTION_CHECKSUM 403
#define CFG_CONNECTION_NODE_1_SYSTEM 404
#define CFG_CONNECTION_NODE_2_SYSTEM 405
+#define CFG_CONNECTION_SERVER_PORT 406
#define CFG_TCP_HOSTNAME_1 450
#define CFG_TCP_HOSTNAME_2 451
#define CFG_TCP_SERVER 452
-#define CFG_TCP_SERVER_PORT 453
#define CFG_TCP_SEND_BUFFER_SIZE 454
#define CFG_TCP_RECEIVE_BUFFER_SIZE 455
#define CFG_TCP_PROXY 456
diff --git a/ndb/include/mgmapi/mgmapi_debug.h b/ndb/include/mgmapi/mgmapi_debug.h
index 2723263e7a7..1c562cd164f 100644
--- a/ndb/include/mgmapi/mgmapi_debug.h
+++ b/ndb/include/mgmapi/mgmapi_debug.h
@@ -106,6 +106,31 @@ extern "C" {
struct ndb_mgm_reply* reply);
+ /**
+ *
+ * @param handle the NDB management handle.
+ * @param nodeId the node id. 0 = all db nodes
+ * @param errrorCode the errorCode.
+ * @param reply the reply message.
+ * @return 0 if successful or an error code.
+ */
+ int ndb_mgm_set_int_parameter(NdbMgmHandle handle,
+ int node,
+ int param,
+ unsigned value,
+ struct ndb_mgm_reply* reply);
+
+ int ndb_mgm_set_int64_parameter(NdbMgmHandle handle,
+ int node,
+ int param,
+ unsigned long long value,
+ struct ndb_mgm_reply* reply);
+
+ int ndb_mgm_set_string_parameter(NdbMgmHandle handle,
+ int node,
+ int param,
+ const char * value,
+ struct ndb_mgm_reply* reply);
#ifdef __cplusplus
}
#endif
diff --git a/ndb/include/mgmcommon/ConfigRetriever.hpp b/ndb/include/mgmcommon/ConfigRetriever.hpp
index 50d333b54dd..396ce24308c 100644
--- a/ndb/include/mgmcommon/ConfigRetriever.hpp
+++ b/ndb/include/mgmcommon/ConfigRetriever.hpp
@@ -19,6 +19,8 @@
#include <ndb_types.h>
#include <mgmapi.h>
+#include <BaseString.hpp>
+#include <LocalConfig.hpp>
/**
* @class ConfigRetriever
@@ -26,15 +28,16 @@
*/
class ConfigRetriever {
public:
- ConfigRetriever();
- ConfigRetriever(const int id, const char* remoteHost, const int port);
+ ConfigRetriever(Uint32 version, Uint32 nodeType);
~ConfigRetriever();
/**
* Read local config
* @return Own node id, -1 means fail
*/
- int init(bool onlyNodeId = false);
+ int init();
+
+ int do_connect();
/**
* Get configuration for current (nodeId given in local config file) node.
@@ -47,7 +50,7 @@ public:
* @return ndb_mgm_configuration object if succeeded,
* NULL if erroneous local config file or configuration error.
*/
- struct ndb_mgm_configuration * getConfig(int versionId, int nodeType);
+ struct ndb_mgm_configuration * getConfig();
const char * getErrorString();
@@ -62,28 +65,21 @@ public:
void setLocalConfigFileName(const char * connectString);
/**
- * Sets connectstring which can be used instead of local config file
- * environment variables and Ndb.cfg has precidence over this
- */
- void setDefaultConnectString(const char * defaultConnectString);
-
- /**
* @return Node id of this node (as stated in local config or connectString)
*/
- inline Uint32 getOwnNodeId() { return _ownNodeId; }
-
+ Uint32 allocNodeId();
/**
* Get config using socket
*/
- struct ndb_mgm_configuration * getConfig(const char * mgmhost, short port,
- int versionId);
+ struct ndb_mgm_configuration * getConfig(NdbMgmHandle handle);
+
/**
* Get config from file
*/
- struct ndb_mgm_configuration * getConfig(const char * file, int versionId);
+ struct ndb_mgm_configuration * getConfig(const char * file);
private:
- char * errorString;
+ BaseString errorString;
enum ErrorType {
CR_ERROR = 0,
CR_RETRY = 1
@@ -91,18 +87,21 @@ private:
ErrorType latestErrorType;
void setError(ErrorType, const char * errorMsg);
-
- char * _localConfigFileName;
- struct LocalConfig * _localConfig;
+
+ BaseString _localConfigFileName;
+ struct LocalConfig _localConfig;
int _ownNodeId;
-
- char * m_connectString;
- char * m_defaultConnectString;
+ BaseString m_connectString;
+
+ Uint32 m_version;
+ Uint32 m_node_type;
+ NdbMgmHandle m_handle;
+
/**
* Verify config
*/
- bool verifyConfig(const struct ndb_mgm_configuration *, int type);
+ bool verifyConfig(const struct ndb_mgm_configuration *);
};
#endif
diff --git a/ndb/include/mgmcommon/LocalConfig.hpp b/ndb/include/mgmcommon/LocalConfig.hpp
new file mode 100644
index 00000000000..c741b35f482
--- /dev/null
+++ b/ndb/include/mgmcommon/LocalConfig.hpp
@@ -0,0 +1,67 @@
+/* Copyright (C) 2003 MySQL AB
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
+
+#ifndef LocalConfig_H
+#define LocalConfig_H
+
+#include <ndb_global.h>
+#include <NdbOut.hpp>
+
+//****************************************************************************
+// Description: The class LocalConfig corresponds to the information possible
+// to give in the local configuration file.
+//*****************************************************************************
+
+enum MgmtSrvrId_Type {
+ MgmId_TCP = 0,
+ MgmId_File = 1
+};
+
+struct MgmtSrvrId {
+ MgmtSrvrId_Type type;
+ BaseString name;
+ unsigned int port;
+};
+
+struct LocalConfig {
+
+ int _ownNodeId;
+ Vector<MgmtSrvrId> ids;
+
+ int error_line;
+ char error_msg[256];
+
+ LocalConfig();
+ ~LocalConfig();
+ bool init(const char *connectString = 0,
+ const char *fileName = 0);
+
+ void printError() const;
+ void printUsage() const;
+
+ void setError(int lineNumber, const char * _msg);
+ bool readConnectString(const char *);
+ bool readFile(const char * file, bool &fopenError);
+ bool parseLine(char * line, int lineNumber);
+
+ bool parseNodeId(const char *buf);
+ bool parseHostName(const char *buf);
+ bool parseFileName(const char *buf);
+ bool parseString(const char *buf, char *line);
+};
+
+#endif // LocalConfig_H
+
diff --git a/ndb/include/mgmcommon/MgmtErrorReporter.hpp b/ndb/include/mgmcommon/MgmtErrorReporter.hpp
index 925d9e6407a..0d980aa7245 100644
--- a/ndb/include/mgmcommon/MgmtErrorReporter.hpp
+++ b/ndb/include/mgmcommon/MgmtErrorReporter.hpp
@@ -63,12 +63,6 @@
// Returns: -
//****************************************************************************
-#ifndef NDB_ASSERT
-#define NDB_ASSERT(trueToContinue, message) \
- if ( !(trueToContinue) ) { \
-ndbout << "ASSERT FAILED. FILE: " << __FILE__ << ", LINE: " << __LINE__ << ", MSG: " << message << endl;exit(-1);}
-#endif
-
#define MGM_REQUIRE(x) \
if (!(x)) { ndbout << __FILE__ << " " << __LINE__ \
<< ": Warning! Requirement failed" << endl; }
diff --git a/ndb/include/mgmcommon/NdbConfig.h b/ndb/include/mgmcommon/NdbConfig.h
index d9b484edcc5..5c83a348df2 100644
--- a/ndb/include/mgmcommon/NdbConfig.h
+++ b/ndb/include/mgmcommon/NdbConfig.h
@@ -21,11 +21,14 @@
extern "C" {
#endif
-const char* NdbConfig_HomePath(char* buf, int buflen);
-
-const char* NdbConfig_NdbCfgName(char* buf, int buflen, int with_ndb_home);
-const char* NdbConfig_ErrorFileName(char* buf, int buflen);
-const char* NdbConfig_ClusterLogFileName(char* buf, int buflen);
+char* NdbConfig_NdbCfgName(int with_ndb_home);
+char* NdbConfig_ErrorFileName(int node_id);
+char* NdbConfig_ClusterLogFileName(int node_id);
+char* NdbConfig_SignalLogFileName(int node_id);
+char* NdbConfig_TraceFileName(int node_id, int file_no);
+char* NdbConfig_NextTraceFileName(int node_id);
+char* NdbConfig_PidFileName(int node_id);
+char* NdbConfig_StdoutFileName(int node_id);
#ifdef __cplusplus
}
diff --git a/ndb/include/ndb_global.h b/ndb/include/ndb_global.h
index f871acbc075..b8fcca6dbb1 100644
--- a/ndb/include/ndb_global.h
+++ b/ndb/include/ndb_global.h
@@ -3,6 +3,10 @@
#define NDBGLOBAL_H
#include <my_global.h>
+#define NDB_BASE_PORT 2200
+
+/** signal & SIG_PIPE */
+#include <my_alarm.h>
#if defined(_WIN32) || defined(_WIN64) || defined(__WIN32__) || defined(WIN32)
#define NDB_WIN32
@@ -90,6 +94,14 @@ extern int strcasecmp(const char *s1, const char *s2);
extern int strncasecmp(const char *s1, const char *s2, size_t n);
#endif
+#ifdef SCO
+
+#ifndef PATH_MAX
+#define PATH_MAX 1024
+#endif
+
+#endif /* SCO */
+
#ifdef __cplusplus
}
#endif
diff --git a/ndb/include/ndbapi/Ndb.hpp b/ndb/include/ndbapi/Ndb.hpp
index 27da5c3fa39..7904ecef305 100644
--- a/ndb/include/ndbapi/Ndb.hpp
+++ b/ndb/include/ndbapi/Ndb.hpp
@@ -867,6 +867,7 @@ class NdbObjectIdMap;
class NdbOperation;
class NdbEventOperationImpl;
class NdbScanOperation;
+class NdbIndexScanOperation;
class NdbIndexOperation;
class NdbConnection;
class NdbApiSignal;
@@ -875,7 +876,6 @@ class NdbLabel;
class NdbBranch;
class NdbSubroutine;
class NdbCall;
-class NdbScanReceiver;
class Table;
class BaseString;
class NdbEventOperation;
@@ -961,8 +961,9 @@ class Ndb
friend class NdbConnection;
friend class Table;
friend class NdbApiSignal;
- friend class NdbScanReceiver;
friend class NdbIndexOperation;
+ friend class NdbScanOperation;
+ friend class NdbIndexScanOperation;
friend class NdbDictionaryImpl;
friend class NdbDictInterface;
friend class NdbBlob;
@@ -1413,12 +1414,24 @@ public:
*
* @return tuple id or 0 on error
*/
- Uint64 getAutoIncrementValue(const char* aTableName, Uint32 cacheSize = 1);
- bool setAutoIncrementValue(const char* aTableName, Uint64 val);
- Uint64 getTupleIdFromNdb(const char* aTableName, Uint32 cacheSize = 1000 );
- Uint64 getTupleIdFromNdb(Uint32 aTableId, Uint32 cacheSize = 1000 );
- bool setTupleIdInNdb(const char* aTableName, Uint64 val);
- bool setTupleIdInNdb(Uint32 aTableId, Uint64 val);
+ Uint64 getAutoIncrementValue(const char* aTableName,
+ Uint32 cacheSize = 1);
+ Uint64 getAutoIncrementValue(NdbDictionary::Table * aTable,
+ Uint32 cacheSize = 1);
+ Uint64 readAutoIncrementValue(const char* aTableName);
+ Uint64 readAutoIncrementValue(NdbDictionary::Table * aTable);
+ bool setAutoIncrementValue(const char* aTableName, Uint64 val,
+ bool increase = false);
+ bool setAutoIncrementValue(NdbDictionary::Table * aTable, Uint64 val,
+ bool increase = false);
+ Uint64 getTupleIdFromNdb(const char* aTableName,
+ Uint32 cacheSize = 1000);
+ Uint64 getTupleIdFromNdb(Uint32 aTableId,
+ Uint32 cacheSize = 1000);
+ Uint64 readTupleIdFromNdb(Uint32 aTableId);
+ bool setTupleIdInNdb(const char* aTableName, Uint64 val,
+ bool increase);
+ bool setTupleIdInNdb(Uint32 aTableId, Uint64 val, bool increase);
Uint64 opTupleIdOnNdb(Uint32 aTableId, Uint64 opValue, Uint32 op);
#endif
@@ -1441,7 +1454,7 @@ private:
NdbConnection* doConnect(Uint32 nodeId);
void doDisconnect();
- NdbScanReceiver* getNdbScanRec();// Get a NdbScanReceiver from idle list
+ NdbReceiver* getNdbScanRec();// Get a NdbScanReceiver from idle list
NdbLabel* getNdbLabel(); // Get a NdbLabel from idle list
NdbBranch* getNdbBranch(); // Get a NdbBranch from idle list
NdbSubroutine* getNdbSubroutine();// Get a NdbSubroutine from idle
@@ -1450,7 +1463,7 @@ private:
NdbRecAttr* getRecAttr(); // Get a receeive attribute object from
// idle list of the Ndb object.
NdbOperation* getOperation(); // Get an operation from idle list
- NdbScanOperation* getScanOperation(); // Get a scan operation from idle
+ NdbIndexScanOperation* getScanOperation(); // Get a scan operation from idle
NdbIndexOperation* getIndexOperation();// Get an index operation from idle
class NdbGlobalEventBufferHandle* getGlobalEventBufferHandle();
@@ -1458,14 +1471,14 @@ private:
void releaseSignal(NdbApiSignal* anApiSignal);
void releaseSignalsInList(NdbApiSignal** pList);
- void releaseNdbScanRec(NdbScanReceiver* aNdbScanRec);
+ void releaseNdbScanRec(NdbReceiver* aNdbScanRec);
void releaseNdbLabel(NdbLabel* anNdbLabel);
void releaseNdbBranch(NdbBranch* anNdbBranch);
void releaseNdbSubroutine(NdbSubroutine* anNdbSubroutine);
void releaseNdbCall(NdbCall* anNdbCall);
void releaseRecAttr (NdbRecAttr* aRecAttr);
void releaseOperation(NdbOperation* anOperation);
- void releaseScanOperation(NdbScanOperation* aScanOperation);
+ void releaseScanOperation(NdbIndexScanOperation*);
void releaseNdbBlob(NdbBlob* aBlob);
void check_send_timeout();
@@ -1565,7 +1578,6 @@ private:
void* int2void (Uint32 val);
NdbReceiver* void2rec (void* val);
NdbConnection* void2con (void* val);
- NdbScanReceiver* void2rec_srec(void* val);
NdbOperation* void2rec_op (void* val);
NdbIndexOperation* void2rec_iop (void* val);
@@ -1607,7 +1619,7 @@ private:
NdbOperation* theOpIdleList; // First operation in the idle list.
- NdbScanOperation* theScanOpIdleList; // First scan operation in the idle list.
+ NdbIndexScanOperation* theScanOpIdleList; // First scan operation in the idle list.
NdbIndexOperation* theIndexOpIdleList; // First index operation in the idle list.
NdbConnection* theTransactionList;
NdbConnection** theConnectionArray;
@@ -1617,7 +1629,7 @@ private:
NdbBranch* theBranchList; // First branch descriptor in list
NdbSubroutine* theSubroutineList; // First subroutine descriptor in
NdbCall* theCallList; // First call descriptor in list
- NdbScanReceiver* theScanList;
+ NdbReceiver* theScanList;
NdbBlob* theNdbBlobIdleList;
Uint32 theMyRef; // My block reference
diff --git a/ndb/include/ndbapi/NdbApi.hpp b/ndb/include/ndbapi/NdbApi.hpp
index 515f39433e4..add733cccd7 100644
--- a/ndb/include/ndbapi/NdbApi.hpp
+++ b/ndb/include/ndbapi/NdbApi.hpp
@@ -23,6 +23,8 @@
#include "NdbOperation.hpp"
#include "NdbScanOperation.hpp"
#include "NdbIndexOperation.hpp"
+#include "NdbIndexScanOperation.hpp"
+#include "NdbScanFilter.hpp"
#include "NdbRecAttr.hpp"
#include "NdbResultSet.hpp"
#include "NdbDictionary.hpp"
diff --git a/ndb/include/ndbapi/NdbBlob.hpp b/ndb/include/ndbapi/NdbBlob.hpp
index 9398f77c474..dc47115d16f 100644
--- a/ndb/include/ndbapi/NdbBlob.hpp
+++ b/ndb/include/ndbapi/NdbBlob.hpp
@@ -50,24 +50,33 @@ class NdbColumnImpl;
* - closed: after transaction commit
* - invalid: after rollback or transaction close
*
- * NdbBlob supports 2 styles of data access:
+ * NdbBlob supports 3 styles of data access:
*
* - in prepare phase, NdbBlob methods getValue and setValue are used to
- * prepare a read or write of a single blob value of known size
+ * prepare a read or write of a blob value of known size
*
- * - in active phase, NdbBlob methods readData and writeData are used to
- * read or write blob data of undetermined size
+ * - in prepare phase, setActiveHook is used to define a routine which
+ * is invoked as soon as the handle becomes active
+ *
+ * - in active phase, readData and writeData are used to read or write
+ * blob data of arbitrary size
+ *
+ * The styles can be applied in combination (in above order).
+ *
+ * Blob operations take effect at next transaction execute. In some
+ * cases NdbBlob is forced to do implicit executes. To avoid this,
+ * operate on complete blob parts.
+ *
+ * Use NdbConnection::executePendingBlobOps to flush your reads and
+ * writes. It avoids execute penalty if nothing is pending. It is not
+ * needed after execute (obviously) or after next scan result.
*
* NdbBlob methods return -1 on error and 0 on success, and use output
* parameters when necessary.
*
* Notes:
* - table and its blob part tables are not created atomically
- * - blob data operations take effect at next transaction execute
- * - NdbBlob may need to do implicit executes on the transaction
- * - read and write of complete parts is much more efficient
* - scan must use the "new" interface NdbScanOperation
- * - scan with blobs applies hold-read-lock (at minimum)
* - to update a blob in a read op requires exclusive tuple lock
* - update op in scan must do its own getBlobHandle
* - delete creates implicit, not-accessible blob handles
@@ -78,12 +87,16 @@ class NdbColumnImpl;
* - scan must use exclusive locking for now
*
* Todo:
- * - add scan method hold-read-lock-until-next + return-keyinfo
- * - better check of keyinfo length when setting keys
- * - better check of allowed blob op vs locking mode
+ * - add scan method hold-read-lock + return-keyinfo
+ * - check keyinfo length when setting keys
+ * - check allowed blob ops vs locking mode
+ * - overload control (too many pending ops)
*/
class NdbBlob {
public:
+ /**
+ * State.
+ */
enum State {
Idle = 0,
Prepared = 1,
@@ -93,8 +106,14 @@ public:
};
State getState();
/**
+ * Inline blob header.
+ */
+ struct Head {
+ Uint64 length;
+ };
+ /**
* Prepare to read blob value. The value is available after execute.
- * Use isNull to check for NULL and getLength to get the real length
+ * Use getNull to check for NULL and getLength to get the real length
* and to check for truncation. Sets current read/write position to
* after the data read.
*/
@@ -107,6 +126,20 @@ public:
*/
int setValue(const void* data, Uint32 bytes);
/**
+ * Callback for setActiveHook. Invoked immediately when the prepared
+ * operation has been executed (but not committed). Any getValue or
+ * setValue is done first. The blob handle is active so readData or
+ * writeData etc can be used to manipulate blob value. A user-defined
+ * argument is passed along. Returns non-zero on error.
+ */
+ typedef int ActiveHook(NdbBlob* me, void* arg);
+ /**
+ * Define callback for blob handle activation. The queue of prepared
+ * operations will be executed in no commit mode up to this point and
+ * then the callback is invoked.
+ */
+ int setActiveHook(ActiveHook* activeHook, void* arg);
+ /**
* Check if blob is null.
*/
int getNull(bool& isNull);
@@ -115,7 +148,7 @@ public:
*/
int setNull();
/**
- * Get current length in bytes. Use isNull to distinguish between
+ * Get current length in bytes. Use getNull to distinguish between
* length 0 blob and NULL blob.
*/
int getLength(Uint64& length);
@@ -180,6 +213,13 @@ public:
static const int ErrAbort = 4268;
// "Unknown blob error"
static const int ErrUnknown = 4269;
+ /**
+ * Return info about all blobs in this operation.
+ */
+ // Get first blob in list
+ NdbBlob* blobsFirstBlob();
+ // Get next blob in list after this one
+ NdbBlob* blobsNextBlob();
private:
friend class Ndb;
@@ -187,20 +227,20 @@ private:
friend class NdbOperation;
friend class NdbScanOperation;
friend class NdbDictionaryImpl;
+ friend class NdbResultSet; // atNextResult
// state
State theState;
void setState(State newState);
// define blob table
static void getBlobTableName(char* btname, const NdbTableImpl* t, const NdbColumnImpl* c);
static void getBlobTable(NdbTableImpl& bt, const NdbTableImpl* t, const NdbColumnImpl* c);
- // table name
- char theBlobTableName[BlobTableNameSize];
// ndb api stuff
Ndb* theNdb;
NdbConnection* theNdbCon;
NdbOperation* theNdbOp;
NdbTableImpl* theTable;
NdbTableImpl* theAccessTable;
+ NdbTableImpl* theBlobTable;
const NdbColumnImpl* theColumn;
char theFillChar;
// sizes
@@ -213,10 +253,11 @@ private:
bool theSetFlag;
const char* theSetBuf;
Uint32 theGetSetBytes;
- // head
- struct Head {
- Uint64 length;
- };
+ // pending ops
+ Uint8 thePendingBlobOps;
+ // activation callback
+ ActiveHook* theActiveHook;
+ void* theActiveHookArg;
// buffers
struct Buf {
char* data;
@@ -234,7 +275,6 @@ private:
char* theInlineData;
NdbRecAttr* theHeadInlineRecAttr;
bool theHeadInlineUpdateFlag;
- bool theNewPartFlag;
// length and read/write position
int theNullFlag;
Uint64 theLength;
@@ -275,6 +315,11 @@ private:
int insertParts(const char* buf, Uint32 part, Uint32 count);
int updateParts(const char* buf, Uint32 part, Uint32 count);
int deleteParts(Uint32 part, Uint32 count);
+ // pending ops
+ int executePendingBlobReads();
+ int executePendingBlobWrites();
+ // callbacks
+ int invokeActiveHook();
// blob handle maintenance
int atPrepare(NdbConnection* aCon, NdbOperation* anOp, const NdbColumnImpl* aColumn);
int preExecute(ExecType anExecType, bool& batch);
@@ -286,6 +331,7 @@ private:
void setErrorCode(NdbOperation* anOp, bool invalidFlag = true);
void setErrorCode(NdbConnection* aCon, bool invalidFlag = true);
#ifdef VM_TRACE
+ int getOperationType() const;
friend class NdbOut& operator<<(NdbOut&, const NdbBlob&);
#endif
};
diff --git a/ndb/include/ndbapi/NdbConnection.hpp b/ndb/include/ndbapi/NdbConnection.hpp
index c620578cabd..c268f9aab04 100644
--- a/ndb/include/ndbapi/NdbConnection.hpp
+++ b/ndb/include/ndbapi/NdbConnection.hpp
@@ -19,15 +19,15 @@
#include <ndb_types.h>
#include <NdbError.hpp>
+#include <NdbDictionary.hpp>
class NdbConnection;
class NdbOperation;
-class NdbCursorOperation;
class NdbScanOperation;
+class NdbIndexScanOperation;
class NdbIndexOperation;
class NdbApiSignal;
class Ndb;
-class NdbScanReceiver;
class NdbBlob;
@@ -160,7 +160,7 @@ class NdbConnection
friend class NdbOperation;
friend class NdbScanOperation;
friend class NdbIndexOperation;
- friend class NdbScanReceiver;
+ friend class NdbIndexScanOperation;
friend class NdbBlob;
public:
@@ -178,56 +178,31 @@ public:
NdbOperation* getNdbOperation(const char* aTableName);
/**
- * Get an NdbOperation for index scan of a table.
- * Note that the operation has to be defined before it is executed.
- *
- * @note All operations within the same transaction need to
- * be initialized with this method.
- *
- * @param anIndexName The index name.
- * @param aTableName The table name.
- * @return Pointer to an NdbOperation object if successful, otherwise NULL.
- */
- NdbOperation* getNdbOperation(const char* anIndexName,
- const char* aTableName);
-
-#ifndef DOXYGEN_SHOULD_SKIP_INTERNAL
- /**
* Get an operation from NdbScanOperation idlelist and
* get the NdbConnection object which
* was fetched by startTransaction pointing to this operation.
- * This operation will set the theTableId
- * in the NdbOperation object.synchronous.
*
* @param aTableName a table name.
* @return pointer to an NdbOperation object if successful, otherwise NULL
*/
NdbScanOperation* getNdbScanOperation(const char* aTableName);
-#endif
-#ifndef DOXYGEN_SHOULD_SKIP_INTERNAL
/**
* Get an operation from NdbScanOperation idlelist and
* get the NdbConnection object which
* was fetched by startTransaction pointing to this operation.
- * This operation will set the theTableId
- * in the NdbOperation object.synchronous.
*
* @param anIndexName The index name.
* @param aTableName a table name.
* @return pointer to an NdbOperation object if successful, otherwise NULL
*/
- NdbScanOperation* getNdbScanOperation(const char* anIndexName,
- const char* aTableName);
-#endif
-
-
+ NdbIndexScanOperation* getNdbIndexScanOperation(const char* anIndexName,
+ const char* aTableName);
+
/**
* Get an operation from NdbIndexOperation idlelist and
* get the NdbConnection object that
* was fetched by startTransaction pointing to this operation.
- * This operation will set the theTableId
- * in the NdbOperation object. Synchronous.
*
* @param indexName An index name (as created by createIndex).
* @param tableName A table name.
@@ -337,76 +312,17 @@ public:
*/
void close();
- /** @} *********************************************************************/
-
- /**
- * @name Scan Transactions
- * @{
- */
-
/**
- * Execute a scan transaction. This will define
- * and start the scan transaction in the NDB kernel.
- *
- * @return 0 if successful otherwise -1.
- */
- int executeScan();
-
- /**
- * Get the next tuple in a scan transaction.
- *
- * After each call to NdbConnection::nextScanResult
- * the buffers and NdbRecAttr objects defined in
- * NdbOperation::getValue are updated with values
- * from the scanned tuple.
- *
- * @param fetchAllowed If set to false, then fetching is disabled
- *
- * The NDB API will contact the NDB Kernel for more tuples
- * when necessary to do so unless you set the fetchAllowed
- * to false.
- * This will force NDB to process any records it
- * already has in it's caches. When there are no more cached
- * records it will return 2. You must then call nextScanResult
- * with fetchAllowed = true in order to contact NDB for more
- * records.
- *
- * fetchAllowed = false is useful when you want to update or
- * delete all the records fetched in one transaction(This will save a
- * lot of round trip time and make updates or deletes of scanned
- * records a lot faster).
- * While nextScanResult(false)
- * returns 0 take over the record to another transaction. When
- * nextScanResult(false) returns 2 you must execute and commit the other
- * transaction. This will cause the locks to be transferred to the
- * other transaction, updates or deletes will be made and then the
- * locks will be released.
- * After that, call nextScanResult(true) which will fetch new records and
- * cache them in the NdbApi.
- *
- * @note If you don't take over the records to another transaction the
- * locks on those records will be released the next time NDB Kernel
- * is contacted for more records.
+ * Restart transaction
*
- * @note Please contact for examples of efficient scan
- * updates and deletes.
+ * Once a transaction has been completed successfully
+ * it can be started again wo/ calling closeTransaction/startTransaction
*
- * @return
- * - -1: if unsuccessful,<br>
- * - 0: if another tuple was received, and<br>
- * - 1: if there are no more tuples to scan.
- * - 2: if there are no more cached records in NdbApi
+ * Note this method also releases completed operations
*/
- int nextScanResult(bool fetchAllowed = true);
+ int restart();
- /**
- * Stops the scan. Used if no more tuples are wanted.
- * The transaction should still be closed with
- * Ndb::closeTransaction.
- *
- * @return 0 if successful otherwise -1.
- */
- int stopScan();
+ /** @} *********************************************************************/
/**
* @name Meta Information
@@ -514,15 +430,30 @@ public:
*/
const NdbOperation * getNextCompletedOperation(const NdbOperation * op)const;
+ /** @} *********************************************************************/
+
/**
- * Release completed operations
+ * Execute the transaction in NoCommit mode if there are any not-yet
+ * executed blob part operations of given types. Otherwise do
+ * nothing. The flags argument is bitwise OR of (1 << optype) where
+ * optype comes from NdbOperation::OperationType. Only the basic PK
+ * ops are used (read, insert, update, delete).
*/
- void releaseCompletedOperations();
+ int executePendingBlobOps(Uint8 flags = 0xFF);
-
- /** @} *********************************************************************/
+ // Fast path calls for MySQL ha_ndbcluster
+ NdbOperation* getNdbOperation(NdbDictionary::Table * table);
+ NdbIndexOperation* getNdbIndexOperation(NdbDictionary::Index * index,
+ NdbDictionary::Table * table);
+ NdbScanOperation* getNdbScanOperation(NdbDictionary::Table * table);
+ NdbIndexScanOperation* getNdbIndexScanOperation(NdbDictionary::Index * index,
+ NdbDictionary::Table * table);
private:
+ /**
+ * Release completed operations
+ */
+ void releaseCompletedOperations();
typedef Uint64 TimeMillis_t;
/**************************************************************************
@@ -587,13 +518,7 @@ private:
int receiveTCINDXCONF(const class TcIndxConf *, Uint32 aDataLength);
int receiveTCINDXREF(NdbApiSignal*);
int receiveSCAN_TABREF(NdbApiSignal*);
- int receiveSCAN_TABCONF(NdbApiSignal*);
- int receiveSCAN_TABINFO(NdbApiSignal*);
-
- int checkNextScanResultComplete();
- int sendScanStart();
- int sendScanNext(bool stopScanFlag);
- int fetchNextScanResult();
+ int receiveSCAN_TABCONF(NdbApiSignal*, const Uint32*, Uint32 len);
int doSend(); // Send all operations
int sendROLLBACK(); // Send of an ROLLBACK
@@ -616,7 +541,7 @@ private:
// Release all cursor operations in connection
void releaseOps(NdbOperation*);
- void releaseCursorOperations(NdbCursorOperation*);
+ void releaseScanOperations(NdbIndexScanOperation*);
// Set the transaction identity of the transaction
void setTransactionId(Uint64 aTransactionId);
@@ -633,10 +558,12 @@ private:
int checkMagicNumber(); // Verify correct object
NdbOperation* getNdbOperation(class NdbTableImpl* aTable,
NdbOperation* aNextOp = 0);
- NdbScanOperation* getNdbScanOperation(class NdbTableImpl* aTable);
+ NdbIndexScanOperation* getNdbScanOperation(class NdbTableImpl* aTable);
NdbIndexOperation* getNdbIndexOperation(class NdbIndexImpl* anIndex,
class NdbTableImpl* aTable,
NdbOperation* aNextOp = 0);
+ NdbIndexScanOperation* getNdbIndexScanOperation(NdbIndexImpl* index,
+ NdbTableImpl* table);
void handleExecuteCompletion();
@@ -687,7 +614,6 @@ private:
Uint32 theNoOfOpSent; // How many operations have been sent
Uint32 theNoOfOpCompleted; // How many operations have completed
Uint32 theNoOfOpFetched; // How many operations was actually fetched
- Uint32 theNoOfSCANTABCONFRecv; // How many SCAN_TABCONF have been received
Uint32 theMyRef; // Our block reference
Uint32 theTCConPtr; // Transaction Co-ordinator connection pointer.
Uint64 theTransactionId; // theTransactionId of the transaction
@@ -723,23 +649,20 @@ private:
Uint32 theNodeSequence; // The sequence no of the db node
bool theReleaseOnClose;
- // Cursor operations
+ // Scan operations
bool m_waitForReply;
- NdbCursorOperation* m_theFirstCursorOperation;
- NdbCursorOperation* m_theLastCursorOperation;
+ NdbIndexScanOperation* m_theFirstScanOperation;
+ NdbIndexScanOperation* m_theLastScanOperation;
- NdbCursorOperation* m_firstExecutedCursorOp;
- // Scan operations
- bool theScanFinished;
+ NdbIndexScanOperation* m_firstExecutedScanOp;
- NdbScanReceiver* theCurrentScanRec; // The current operation to
- // distribute to the app.
- NdbScanReceiver* thePreviousScanRec; // The previous operation read by
- // nextScanResult.
- NdbOperation* theScanningOp; // The operation actually performing the scan
+ // Scan operations
+ // The operation actually performing the scan
+ NdbScanOperation* theScanningOp;
Uint32 theBuddyConPtr;
// optim: any blobs
bool theBlobFlag;
+ Uint8 thePendingBlobOps;
static void sendTC_COMMIT_ACK(NdbApiSignal *,
Uint32 transId1, Uint32 transId2,
@@ -749,6 +672,7 @@ private:
#ifdef VM_TRACE
void printState();
#endif
+ bool checkState_TransId(const Uint32 * transId) const;
};
inline
@@ -783,6 +707,16 @@ NdbConnection::checkMagicNumber()
}
}
+inline
+bool
+NdbConnection::checkState_TransId(const Uint32 * transId) const {
+ const Uint32 tTmp1 = transId[0];
+ const Uint32 tTmp2 = transId[1];
+ Uint64 tRecTransId = (Uint64)tTmp1 + ((Uint64)tTmp2 << 32);
+ bool b = theStatus == Connected && theTransactionId == tRecTransId;
+ return b;
+}
+
/************************************************************************************************
void setTransactionId(Uint64 aTransactionId);
@@ -956,6 +890,21 @@ NdbConnection::OpSent()
theNoOfOpSent++;
}
+/******************************************************************************
+void executePendingBlobOps();
+******************************************************************************/
+#include <stdlib.h>
+inline
+int
+NdbConnection::executePendingBlobOps(Uint8 flags)
+{
+ if (thePendingBlobOps & flags) {
+ // not executeNoBlobs because there can be new ops with blobs
+ return execute(NoCommit);
+ }
+ return 0;
+}
+
inline
Uint32
NdbConnection::ptr2int(){
@@ -963,5 +912,3 @@ NdbConnection::ptr2int(){
}
#endif
-
-
diff --git a/ndb/include/ndbapi/NdbCursorOperation.hpp b/ndb/include/ndbapi/NdbCursorOperation.hpp
index cd76b045ea2..e7eeb54ba2d 100644
--- a/ndb/include/ndbapi/NdbCursorOperation.hpp
+++ b/ndb/include/ndbapi/NdbCursorOperation.hpp
@@ -17,77 +17,4 @@
#ifndef NdbCursorOperation_H
#define NdbCursorOperation_H
-#include <NdbOperation.hpp>
-
-class NdbResultSet;
-
-/**
- * @class NdbCursorOperation
- * @brief Operation using cursors
- */
-class NdbCursorOperation : public NdbOperation
-{
- friend class NdbResultSet;
- friend class NdbConnection;
-
-public:
- /**
- * Type of cursor
- */
- enum CursorType {
- NoCursor = 0,
- ScanCursor = 1,
- IndexCursor = 2
- };
-
- /**
- * Lock when performing scan
- */
- enum LockMode {
- LM_Read = 0,
- LM_Exclusive = 1,
- LM_CommittedRead = 2,
-#ifndef DOXYGEN_SHOULD_SKIP_INTERNAL
- LM_Dirty = 2
-#endif
- };
-
- virtual CursorType cursorType() = 0;
-
- /**
- * readTuples returns a NdbResultSet where tuples are stored.
- * Tuples are not stored in NdbResultSet until execute(NoCommit)
- * has been executed and nextResult has been called.
- *
- * @param parallel Scan parallelism
- * @param LockMode Scan lock handling
- * @returns NdbResultSet.
- */
- virtual NdbResultSet* readTuples(unsigned parallel = 0,
- LockMode = LM_Read ) = 0;
-
- inline NdbResultSet* readTuplesExclusive(int parallell = 0){
- return readTuples(parallell, LM_Exclusive);
- }
-
-protected:
- NdbCursorOperation(Ndb* aNdb);
-
- ~NdbCursorOperation();
-
- void cursInit();
-
- virtual int executeCursor(int ProcessorId) = 0;
-
- NdbResultSet* getResultSet();
- NdbResultSet* m_resultSet;
-
-private:
-
- virtual int nextResult(bool fetchAllowed) = 0;
-
- virtual void closeScan() = 0;
-};
-
-
#endif
diff --git a/ndb/include/ndbapi/NdbDictionary.hpp b/ndb/include/ndbapi/NdbDictionary.hpp
index 3b38e33ec91..b5c3985c6cb 100644
--- a/ndb/include/ndbapi/NdbDictionary.hpp
+++ b/ndb/include/ndbapi/NdbDictionary.hpp
@@ -144,6 +144,8 @@ public:
FragAllLarge = 4 ///< Eight fragments per node group.
};
};
+
+ class Table; // forward declaration
/**
* @class Column
@@ -183,7 +185,7 @@ public:
Datetime, ///< Precision down to 1 sec (sizeof(Datetime) == 8 bytes )
Timespec, ///< Precision down to 1 nsec(sizeof(Datetime) == 12 bytes )
Blob, ///< Binary large object (see NdbBlob)
- Clob ///< Text blob
+ Text ///< Text blob
};
/**
@@ -309,7 +311,8 @@ public:
/**
* For blob, set or get "part size" i.e. number of bytes to store in
- * each tuple of the "blob table". Must be less than 64k.
+ * each tuple of the "blob table". Can be set to zero to omit parts
+ * and to allow only inline bytes ("tinyblob").
*/
void setPartSize(int size) { setScale(size); }
int getPartSize() const { return getScale(); }
@@ -324,7 +327,7 @@ public:
/**
* Get size of element
*/
- int Column::getSize() const;
+ int getSize() const;
/**
* Set distribution key
@@ -364,6 +367,8 @@ public:
void setIndexOnlyStorage(bool);
bool getIndexOnlyStorage() const;
+ const Table * getBlobTable() const;
+
/**
* @name ODBC Specific methods
* @{
@@ -1060,6 +1065,6 @@ public:
};
};
-class NdbOut& operator <<(class NdbOut& ndbout, const NdbDictionary::Column::Type type);
+class NdbOut& operator <<(class NdbOut& out, const NdbDictionary::Column& col);
#endif
diff --git a/ndb/include/ndbapi/NdbIndexOperation.hpp b/ndb/include/ndbapi/NdbIndexOperation.hpp
index baf31dca0ee..2d873c52e56 100644
--- a/ndb/include/ndbapi/NdbIndexOperation.hpp
+++ b/ndb/include/ndbapi/NdbIndexOperation.hpp
@@ -29,7 +29,7 @@
#ifndef NdbIndexOperation_H
#define NdbIndexOperation_H
-#include <NdbCursorOperation.hpp>
+#include "NdbOperation.hpp"
class Index;
class NdbResultSet;
diff --git a/ndb/include/ndbapi/NdbIndexScanOperation.hpp b/ndb/include/ndbapi/NdbIndexScanOperation.hpp
new file mode 100644
index 00000000000..82aed04a9fc
--- /dev/null
+++ b/ndb/include/ndbapi/NdbIndexScanOperation.hpp
@@ -0,0 +1,140 @@
+/* Copyright (C) 2003 MySQL AB
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
+
+#ifndef NdbIndexScanOperation_H
+#define NdbIndexScanOperation_H
+
+#include <NdbScanOperation.hpp>
+
+/**
+ * @class NdbIndexScanOperation
+ * @brief Class of scan operations for use to scan ordered index
+ */
+class NdbIndexScanOperation : public NdbScanOperation {
+ friend class Ndb;
+ friend class NdbConnection;
+ friend class NdbResultSet;
+ friend class NdbOperation;
+ friend class NdbScanOperation;
+public:
+ /**
+ * readTuples returns a NdbResultSet where tuples are stored.
+ * Tuples are not stored in NdbResultSet until execute(NoCommit)
+ * has been executed and nextResult has been called.
+ *
+ * @param parallel Scan parallelism
+ * @param batch No of rows to fetch from each fragment at a time
+ * @param LockMode Scan lock handling
+ * @param order_by Order result set in index order
+ * @returns NdbResultSet.
+ * @see NdbScanOperation::readTuples
+ */
+ NdbResultSet* readTuples(LockMode = LM_Read,
+ Uint32 batch = 0,
+ Uint32 parallel = 0,
+ bool order_by = false);
+
+ inline NdbResultSet* readTuples(int parallell){
+ return readTuples(LM_Read, 0, parallell, false);
+ }
+
+ inline NdbResultSet* readTuplesExclusive(int parallell = 0){
+ return readTuples(LM_Exclusive, 0, parallell, false);
+ }
+
+ /**
+ * @name Define Range Scan
+ *
+ * A range scan is a scan on an ordered index. The operation is on
+ * the index table but tuples are returned from the primary table.
+ * The index contains all tuples where at least one index key has not
+ * null value.
+ *
+ * A range scan is currently opened via a normal open scan method.
+ * Bounds can be defined for each index key. After setting bounds,
+ * usual scan methods can be used (get value, interpreter, take over).
+ * These operate on the primary table.
+ *
+ * @{
+ */
+
+ /**
+ * Type of ordered index key bound. The values (0-4) will not change
+ * and can be used explicitly (e.g. they could be computed).
+ */
+ enum BoundType {
+ BoundLE = 0, ///< lower bound,
+ BoundLT = 1, ///< lower bound, strict
+ BoundGE = 2, ///< upper bound
+ BoundGT = 3, ///< upper bound, strict
+ BoundEQ = 4 ///< equality
+ };
+
+ /**
+ * Define bound on index key in range scan.
+ *
+ * Each index key can have lower and/or upper bound, or can be set
+ * equal to a value. The bounds can be defined in any order but
+ * a duplicate definition is an error.
+ *
+ * The bounds must specify a single range i.e. they are on an initial
+ * sequence of index keys and the condition is equality for all but
+ * (at most) the last key which has a lower and/or upper bound.
+ *
+ * NULL is treated like a normal value which is less than any not-NULL
+ * value and equal to another NULL value. To search for NULL use
+ * setBound with null pointer (0).
+ *
+ * An index stores also all-NULL keys (this may become optional).
+ * Doing index scan with empty bound set returns all table tuples.
+ *
+ * @param attrName Attribute name, alternatively:
+ * @param anAttrId Index column id (starting from 0)
+ * @param type Type of bound
+ * @param value Pointer to bound value, 0 for NULL
+ * @param len Value length in bytes.
+ * Fixed per datatype and can be omitted
+ * @return 0 if successful otherwise -1
+ */
+ int setBound(const char* attr, int type, const void* aValue, Uint32 len = 0);
+
+ /**
+ * Define bound on index key in range scan using index column id.
+ * See the other setBound() method for details.
+ */
+ int setBound(Uint32 anAttrId, int type, const void* aValue, Uint32 len = 0);
+
+ /** @} *********************************************************************/
+
+private:
+ NdbIndexScanOperation(Ndb* aNdb);
+ virtual ~NdbIndexScanOperation();
+
+ int setBound(const NdbColumnImpl*, int type, const void* aValue, Uint32 len);
+ int saveBoundATTRINFO();
+
+ virtual int equal_impl(const NdbColumnImpl*, const char*, Uint32);
+ virtual NdbRecAttr* getValue_impl(const NdbColumnImpl*, char*);
+
+ void fix_get_values();
+ int next_result_ordered(bool fetchAllowed);
+ int send_next_scan_ordered(Uint32 idx);
+ int compare(Uint32 key, Uint32 cols, const NdbReceiver*, const NdbReceiver*);
+
+ Uint32 m_sort_columns;
+};
+
+#endif
diff --git a/ndb/include/ndbapi/NdbOperation.hpp b/ndb/include/ndbapi/NdbOperation.hpp
index cfa656cb2d5..c48dccd4864 100644
--- a/ndb/include/ndbapi/NdbOperation.hpp
+++ b/ndb/include/ndbapi/NdbOperation.hpp
@@ -42,8 +42,8 @@ class NdbOperation
friend class NdbScanReceiver;
friend class NdbScanFilter;
friend class NdbScanFilterImpl;
+ friend class NdbReceiver;
friend class NdbBlob;
-
public:
/**
* @name Define Standard Operation Type
@@ -196,196 +196,7 @@ public:
*/
virtual int interpretedDeleteTuple();
- /**
- * Scan a table to read tuples.
- *
- * The operation only sets a temporary read lock while
- * reading the tuple.
- * The tuple lock is released when the result of the read reaches the
- * application.
- *
- * @param Parallelism Number of parallel tuple reads are performed
- * in the scan.
- * Currently a maximum of 256 parallel tuple
- * reads are allowed.
- * The parallelism can in reality be lower
- * than specified
- * depending on the number of nodes
- * in the cluster
- * @return 0 if successful otherwise -1.
- */
- int openScanRead(Uint32 Parallelism = 16 );
-
- /**
- * Scan a table to write or update tuples.
- *
- * The operation sets an exclusive lock on the tuple and sends the result
- * to the application.
- * Thus when the application reads the data, the tuple is
- * still locked with an exclusive lock.
- *
- * @param parallelism Number of parallel tuple reads are performed
- * in the scan.
- * Currently a maximum of 256 parallel tuple
- * reads are allowed.
- * The parallelism can in reality be lower
- * than specified depending on the number
- * of nodes in the cluster
- * @return 0 if successful otherwise -1.
- *
- */
- int openScanExclusive(Uint32 parallelism = 16);
-
- /**
- * Scan a table to read tuples.
- *
- * The operation only sets a read lock while
- * reading the tuple.
- * Thus when the application reads the data, the tuple is
- * still locked with a read lock.
- *
- * @param parallelism Number of parallel tuple reads are performed
- * in the scan.
- * Currently a maximum of 256 parallel tuple
- * reads are allowed.
- * The parallelism can in reality be lower
- * than specified
- * depending on the number of nodes
- * in the cluster
- * @return 0 if successful otherwise -1.
- */
- int openScanReadHoldLock(Uint32 parallelism = 16);
-
- /**
- * Scan a table to read tuples.
- *
- * The operation does not wait for locks held by other transactions
- * but returns the latest committed tuple instead.
- *
- * @param parallelism Number of parallel tuple reads are performed
- * in the scan.
- * Currently a maximum of 256 parallel tuple
- * reads are allowed.
- * The parallelism can in reality be lower
- * than specified
- * depending on the number of nodes
- * in the cluster
- * @return 0 if successful otherwise -1.
- */
- int openScanReadCommitted(Uint32 parallelism = 16);
-
- /** @} *********************************************************************/
-
- /**
- * @name Define Range Scan
- *
- * A range scan is a scan on an ordered index. The operation is on
- * the index table but tuples are returned from the primary table.
- * The index contains all tuples where at least one index key has not
- * null value.
- *
- * A range scan is currently opened via a normal open scan method.
- * Bounds can be defined for each index key. After setting bounds,
- * usual scan methods can be used (get value, interpreter, take over).
- * These operate on the primary table.
- *
- * @{
- */
-
- /**
- * Type of ordered index key bound. The values (0-4) will not change
- * and can be used explicitly (e.g. they could be computed).
- */
- enum BoundType {
- BoundLE = 0, ///< lower bound,
- BoundLT = 1, ///< lower bound, strict
- BoundGE = 2, ///< upper bound
- BoundGT = 3, ///< upper bound, strict
- BoundEQ = 4 ///< equality
- };
-
- /**
- * Define bound on index key in range scan.
- *
- * Each index key can have not null lower and/or upper bound, or can
- * be set equal to not null value. The bounds can be defined in any
- * order but a duplicate definition is an error.
- *
- * The scan is most effective when bounds are given for an initial
- * sequence of non-nullable index keys, and all but the last one is an
- * equality. In this case the scan returns a contiguous range from
- * each ordered index fragment.
- *
- * @note This release implements only the case described above,
- * except for the non-nullable limitation. Other sets of
- * bounds return error or empty result set.
- *
- * @note In this release a null key value satisfies any lower
- * bound and no upper bound. This may change.
- *
- * @param attrName Attribute name, alternatively:
- * @param anAttrId Index column id (starting from 0).
- * @param type Type of bound
- * @param value Pointer to bound value
- * @param len Value length in bytes.
- * Fixed per datatype and can be omitted
- * @return 0 if successful otherwise -1
- */
- int setBound(const char* anAttrName, int type, const void* aValue, Uint32 len = 0);
-
- /**
- * Define bound on index key in range scan using index column id.
- * See the other setBound() method for details.
- */
- int setBound(Uint32 anAttrId, int type, const void* aValue, Uint32 len = 0);
-
/** @} *********************************************************************/
-
- /**
- * Validate parallelism parameter by checking the number
- * against number of executing Ndb nodes.
- *
- * @param Parallelism
- * @return 0 if correct parallelism value, otherwise -1.
- *
- */
- int checkParallelism(Uint32 Parallelism);
-
- /**
- * Transfer scan operation to an updating transaction. Use this function
- * when a scan has found a record that you want to update.
- * 1. Start a new transaction.
- * 2. Call the function takeOverForUpdate using your new transaction
- * as parameter, all the properties of the found record will be copied
- * to the new transaction.
- * 3. When you execute the new transaction, the lock held by the scan will
- * be transferred to the new transaction(it's taken over).
- *
- * @note You must have started the scan with openScanExclusive
- * to be able to update the found tuple.
- *
- * @param updateTrans the update transaction connection.
- * @return an NdbOperation or NULL.
- */
- NdbOperation* takeOverForUpdate(NdbConnection* updateTrans);
-
- /**
- * Transfer scan operation to a deleting transaction. Use this function
- * when a scan has found a record that you want to delete.
- * 1. Start a new transaction.
- * 2. Call the function takeOverForDelete using your new transaction
- * as parameter, all the properties of the found record will be copied
- * to the new transaction.
- * 3. When you execute the new transaction, the lock held by the scan will
- * be transferred to the new transaction(its taken over).
- *
- * @note You must have started the scan with openScanExclusive
- * to be able to delete the found tuple.
- *
- * @param deleteTrans the delete transaction connection.
- * @return an NdbOperation or NULL.
- */
- NdbOperation* takeOverForDelete(NdbConnection* deleteTrans);
/**
* @name Specify Search Conditions
@@ -883,16 +694,7 @@ protected:
// Initialise after allocating operation to a transaction
//--------------------------------------------------------------
int init(class NdbTableImpl*, NdbConnection* aCon);
-
- void initScan(); // Initialise after allocating operation
- // to a scan transaction
- virtual void releaseScan(); // Release scan parts of transaction
- void releaseSignals();
- void releaseScanSignals();
- void prepareNextScanResult();
-
- // Common part for Read and Exclusive
- int openScan(Uint32 aParallelism, bool, bool, bool);
+ void initInterpreter();
void next(NdbOperation*); // Set next pointer
@@ -938,19 +740,12 @@ protected:
*****************************************************************************/
int doSend(int ProcessorId, Uint32 lastFlag);
- int doSendScan(int ProcessorId);
-
- int prepareSendScan(Uint32 TC_ConnectPtr,
- Uint64 TransactionId);
-
virtual int prepareSend(Uint32 TC_ConnectPtr,
Uint64 TransactionId);
virtual void setLastFlag(NdbApiSignal* signal, Uint32 lastFlag);
int prepareSendInterpreted(); // Help routine to prepare*
- void TCOPCONF(Uint32 anNdbColumnImplLen); // Handle TC[KEY/INDX]CONF signal
-
int receiveTCKEYREF(NdbApiSignal*);
@@ -958,7 +753,7 @@ protected:
int receiveREAD_CONF(const Uint32* aDataPtr, Uint32 aDataLength);
- int checkMagicNumber(); // Verify correct object
+ int checkMagicNumber(bool b = true); // Verify correct object
int checkState_TransId(NdbApiSignal* aSignal);
@@ -966,10 +761,8 @@ protected:
* These are support methods only used locally in this class.
******************************************************************************/
- virtual int equal_impl(const NdbColumnImpl* anAttrObject,
- const char* aValue,
- Uint32 len);
- NdbRecAttr* getValue(const NdbColumnImpl* anAttrObject, char* aValue = 0);
+ virtual int equal_impl(const NdbColumnImpl*,const char* aValue, Uint32 len);
+ virtual NdbRecAttr* getValue_impl(const NdbColumnImpl*, char* aValue = 0);
int setValue(const NdbColumnImpl* anAttrObject, const char* aValue, Uint32 len);
NdbBlob* getBlobHandle(NdbConnection* aCon, const NdbColumnImpl* anAttrObject);
int incValue(const NdbColumnImpl* anAttrObject, Uint32 aValue);
@@ -981,15 +774,12 @@ protected:
int branch_reg_reg(Uint32 type, Uint32, Uint32, Uint32);
int branch_col(Uint32 type, Uint32, const char *, Uint32, bool, Uint32 Label);
int branch_col_null(Uint32 type, Uint32 col, Uint32 Label);
- int setBound(const NdbColumnImpl* anAttrObject, int type, const void* aValue, Uint32 len);
// Handle ATTRINFO signals
int receiveREAD_AI(Uint32* aDataPtr, Uint32 aLength);
int insertATTRINFO(Uint32 aData);
int insertATTRINFOloop(const Uint32* aDataPtr, Uint32 aLength);
- int getFirstATTRINFOScan();
- int saveBoundATTRINFO();
int insertKEYINFO(const char* aValue,
Uint32 aStartPosition,
@@ -1013,12 +803,8 @@ protected:
Uint32 ptr2int() { return theReceiver.getId(); };
- NdbOperation*
- takeOverScanOp(OperationType opType, NdbConnection* updateTrans);
-
// get table or index key from prepared signals
int getKeyFromTCREQ(Uint32* data, unsigned size);
- int getKeyFromKEYINFO20(Uint32* data, unsigned size);
/******************************************************************************
* These are the private variables that are defined in the operation objects.
@@ -1032,7 +818,6 @@ protected:
Ndb* theNdb; // Point back to the Ndb object.
NdbConnection* theNdbCon; // Point back to the connection object.
NdbOperation* theNext; // Next pointer to operation.
- NdbOperation* theNextScanOp;
NdbApiSignal* theTCREQ; // The TC[KEY/INDX]REQ signal object
NdbApiSignal* theFirstATTRINFO; // The first ATTRINFO signal object
NdbApiSignal* theCurrentATTRINFO; // The current ATTRINFO signal object
@@ -1043,9 +828,6 @@ protected:
NdbApiSignal* theFirstKEYINFO; // The first KEYINFO signal object
NdbApiSignal* theLastKEYINFO; // The first KEYINFO signal object
- NdbRecAttr* theFirstRecAttr; // The first receive attribute object
- NdbRecAttr* theCurrentRecAttr; // The current receive attribute object
-
class NdbLabel* theFirstLabel;
class NdbLabel* theLastLabel;
class NdbBranch* theFirstBranch;
@@ -1060,11 +842,6 @@ protected:
Uint32* theKEYINFOptr; // Pointer to where to write KEYINFO
Uint32* theATTRINFOptr; // Pointer to where to write ATTRINFO
- Uint32 theTotalRecAI_Len; // The total length received according
- // to the TCKEYCONF signal
- Uint32 theCurrRecAI_Len; // The currently received length
- Uint32 theAI_ElementLen; // How many words long is this element
- Uint32* theCurrElemPtr; // The current pointer to the element
class NdbTableImpl* m_currentTable; // The current table
class NdbTableImpl* m_accessTable;
@@ -1106,15 +883,6 @@ protected:
Uint16 m_keyInfoGSN;
Uint16 m_attrInfoGSN;
- // Scan related variables
- Uint32 theParallelism;
- NdbScanReceiver** theScanReceiversArray;
- NdbApiSignal* theSCAN_TABREQ;
- NdbApiSignal* theFirstSCAN_TABINFO_Send;
- NdbApiSignal* theLastSCAN_TABINFO_Send;
- NdbApiSignal* theFirstSCAN_TABINFO_Recv;
- NdbApiSignal* theLastSCAN_TABINFO_Recv;
- NdbApiSignal* theSCAN_TABCONF_Recv;
// saveBoundATTRINFO() moves ATTRINFO here when setBound() is ready
NdbApiSignal* theBoundATTRINFO;
Uint32 theTotalBoundAI_Len;
@@ -1130,11 +898,11 @@ protected:
inline
int
-NdbOperation::checkMagicNumber()
+NdbOperation::checkMagicNumber(bool b)
{
if (theMagicNumber != 0xABCDEF01){
#ifdef NDB_NO_DROPPED_SIGNAL
- abort();
+ if(b) abort();
#endif
return -1;
}
diff --git a/ndb/include/ndbapi/NdbRecAttr.hpp b/ndb/include/ndbapi/NdbRecAttr.hpp
index 36b54035d96..da03df13027 100644
--- a/ndb/include/ndbapi/NdbRecAttr.hpp
+++ b/ndb/include/ndbapi/NdbRecAttr.hpp
@@ -73,8 +73,9 @@ class NdbOperation;
class NdbRecAttr
{
friend class NdbOperation;
+ friend class NdbIndexScanOperation;
friend class NdbEventOperationImpl;
- friend class NdbScanReceiver;
+ friend class NdbReceiver;
friend class Ndb;
friend class NdbOut& operator<<(class NdbOut&, const class AttributeS&);
@@ -244,9 +245,8 @@ private:
NdbRecAttr();
Uint32 attrId() const; /* Get attribute id */
- void setNULL(); /* Set NULL indicator */
- void setNotNULL(); /* Set Not NULL indicator */
- void setUNDEFINED(); /* Set UNDEFINED indicator */
+ bool setNULL(); /* Set NULL indicator */
+ bool receive_data(const Uint32*, Uint32);
void release(); /* Release memory if allocated */
void init(); /* Initialise object when allocated */
@@ -269,6 +269,7 @@ private:
Uint32 theAttrId; /* The attribute id */
int theNULLind;
+ bool m_nullable;
Uint32 theAttrSize;
Uint32 theArraySize;
const NdbDictionary::Column* m_column;
@@ -289,29 +290,7 @@ NdbRecAttr::getColumn() const {
inline
Uint32
NdbRecAttr::attrSize() const {
-
- switch(getType()){
- case NdbDictionary::Column::Int:
- case NdbDictionary::Column::Unsigned:
- case NdbDictionary::Column::Float:
- return 4;
- case NdbDictionary::Column::Decimal:
- case NdbDictionary::Column::Char:
- case NdbDictionary::Column::Varchar:
- case NdbDictionary::Column::Binary:
- case NdbDictionary::Column::Varbinary:
- return 1;
- case NdbDictionary::Column::Bigint:
- case NdbDictionary::Column::Bigunsigned:
- case NdbDictionary::Column::Double:
- case NdbDictionary::Column::Datetime:
- return 8;
- case NdbDictionary::Column::Timespec:
- return 12;
- case NdbDictionary::Column::Undefined:
- default:
- return 0;
- }
+ return theAttrSize;
}
inline
@@ -449,24 +428,11 @@ NdbRecAttr::attrId() const
}
inline
-void
+bool
NdbRecAttr::setNULL()
{
theNULLind = 1;
-}
-
-inline
-void
-NdbRecAttr::setNotNULL()
-{
- theNULLind = 0;
-}
-
-inline
-void
-NdbRecAttr::setUNDEFINED()
-{
- theNULLind = -1;
+ return m_nullable;
}
inline
diff --git a/ndb/include/ndbapi/NdbReceiver.hpp b/ndb/include/ndbapi/NdbReceiver.hpp
index a1a08a9735a..13898fc8e5f 100644
--- a/ndb/include/ndbapi/NdbReceiver.hpp
+++ b/ndb/include/ndbapi/NdbReceiver.hpp
@@ -23,6 +23,12 @@
class Ndb;
class NdbReceiver
{
+ friend class Ndb;
+ friend class NdbOperation;
+ friend class NdbScanOperation;
+ friend class NdbIndexOperation;
+ friend class NdbIndexScanOperation;
+ friend class NdbConnection;
public:
enum ReceiverType { NDB_UNINITIALIZED,
NDB_OPERATION = 1,
@@ -32,6 +38,7 @@ public:
NdbReceiver(Ndb *aNdb);
void init(ReceiverType type, void* owner);
+ void release();
~NdbReceiver();
Uint32 getId(){
@@ -42,18 +49,51 @@ public:
return m_type;
}
+ inline NdbConnection * getTransaction();
void* getOwner(){
return m_owner;
}
bool checkMagicNumber() const;
+ inline void next(NdbReceiver* next) { m_next = next;}
+ inline NdbReceiver* next() { return m_next; }
+
private:
Uint32 theMagicNumber;
Ndb* m_ndb;
Uint32 m_id;
+ Uint32 m_tcPtrI;
+ Uint32 m_key_info;
ReceiverType m_type;
void* m_owner;
+ NdbReceiver* m_next;
+
+ /**
+ * At setup
+ */
+ class NdbRecAttr * getValue(const class NdbColumnImpl*, char * user_dst_ptr);
+ void do_get_value(NdbReceiver*, Uint32 rows, Uint32 key_size);
+ void prepareSend();
+
+ int execKEYINFO20(Uint32 info, const Uint32* ptr, Uint32 len);
+ int execTRANSID_AI(const Uint32* ptr, Uint32 len);
+ int execTCOPCONF(Uint32 len);
+ int execSCANOPCONF(Uint32 tcPtrI, Uint32 len, Uint32 rows);
+ class NdbRecAttr* theFirstRecAttr;
+ class NdbRecAttr* theCurrentRecAttr;
+ class NdbRecAttr** m_rows;
+
+ Uint32 m_list_index; // When using multiple
+ Uint32 m_current_row;
+ Uint32 m_result_rows;
+ Uint32 m_defined_rows;
+
+ Uint32 m_expected_result_length;
+ Uint32 m_received_result_length;
+
+ bool nextResult() const { return m_current_row < m_result_rows; }
+ void copyout(NdbReceiver&);
};
#ifdef NDB_NO_DROPPED_SIGNAL
@@ -72,5 +112,32 @@ NdbReceiver::checkMagicNumber() const {
return retVal;
}
+inline
+void
+NdbReceiver::prepareSend(){
+ m_current_row = 0;
+ m_received_result_length = 0;
+ m_expected_result_length = 0;
+ theCurrentRecAttr = theFirstRecAttr;
+}
+
+inline
+int
+NdbReceiver::execTCOPCONF(Uint32 len){
+ Uint32 tmp = m_received_result_length;
+ m_expected_result_length = len;
+ return (tmp == len ? 1 : 0);
+}
+
+inline
+int
+NdbReceiver::execSCANOPCONF(Uint32 tcPtrI, Uint32 len, Uint32 rows){
+ m_tcPtrI = tcPtrI;
+ m_result_rows = rows;
+ Uint32 tmp = m_received_result_length;
+ m_expected_result_length = len;
+ return (tmp == len ? 1 : 0);
+}
+
#endif
#endif
diff --git a/ndb/include/ndbapi/NdbResultSet.hpp b/ndb/include/ndbapi/NdbResultSet.hpp
index d48df01214e..483e08179c0 100644
--- a/ndb/include/ndbapi/NdbResultSet.hpp
+++ b/ndb/include/ndbapi/NdbResultSet.hpp
@@ -30,17 +30,15 @@
#define NdbResultSet_H
-#include <NdbCursorOperation.hpp>
-#include <NdbIndexOperation.hpp>
#include <NdbScanOperation.hpp>
/**
* @class NdbResultSet
- * @brief NdbResultSet contains a NdbCursorOperation.
+ * @brief NdbResultSet contains a NdbScanOperation.
*/
class NdbResultSet
{
- friend class NdbCursorOperation;
+ friend class NdbScanOperation;
public:
@@ -93,22 +91,62 @@ public:
*/
int nextResult(bool fetchAllowed = true);
+ /**
+ * Close result set (scan)
+ */
void close();
- NdbOperation* updateTuple();
- NdbOperation* updateTuple(NdbConnection* takeOverTransaction);
+ /**
+ * Restart
+ */
+ int restart();
+ /**
+ * Transfer scan operation to an updating transaction. Use this function
+ * when a scan has found a record that you want to update.
+ * 1. Start a new transaction.
+ * 2. Call the function takeOverForUpdate using your new transaction
+ * as parameter, all the properties of the found record will be copied
+ * to the new transaction.
+ * 3. When you execute the new transaction, the lock held by the scan will
+ * be transferred to the new transaction(it's taken over).
+ *
+ * @note You must have started the scan with openScanExclusive
+ * to be able to update the found tuple.
+ *
+ * @param updateTrans the update transaction connection.
+ * @return an NdbOperation or NULL.
+ */
+ NdbOperation* updateTuple();
+ NdbOperation* updateTuple(NdbConnection* updateTrans);
+
+ /**
+ * Transfer scan operation to a deleting transaction. Use this function
+ * when a scan has found a record that you want to delete.
+ * 1. Start a new transaction.
+ * 2. Call the function takeOverForDelete using your new transaction
+ * as parameter, all the properties of the found record will be copied
+ * to the new transaction.
+ * 3. When you execute the new transaction, the lock held by the scan will
+ * be transferred to the new transaction(its taken over).
+ *
+ * @note You must have started the scan with openScanExclusive
+ * to be able to delete the found tuple.
+ *
+ * @param deleteTrans the delete transaction connection.
+ * @return an NdbOperation or NULL.
+ */
int deleteTuple();
int deleteTuple(NdbConnection* takeOverTransaction);
private:
- NdbResultSet(NdbCursorOperation*);
+ NdbResultSet(NdbScanOperation*);
~NdbResultSet();
void init();
- NdbCursorOperation* m_operation;
+ NdbScanOperation* m_operation;
};
#endif
diff --git a/ndb/include/ndbapi/NdbScanOperation.hpp b/ndb/include/ndbapi/NdbScanOperation.hpp
index 151dc5bb99f..c7ae029e742 100644
--- a/ndb/include/ndbapi/NdbScanOperation.hpp
+++ b/ndb/include/ndbapi/NdbScanOperation.hpp
@@ -29,9 +29,7 @@
#ifndef NdbScanOperation_H
#define NdbScanOperation_H
-
#include <NdbOperation.hpp>
-#include <NdbCursorOperation.hpp>
class NdbBlob;
@@ -39,63 +37,71 @@ class NdbBlob;
* @class NdbScanOperation
* @brief Class of scan operations for use in transactions.
*/
-class NdbScanOperation : public NdbCursorOperation
-{
+class NdbScanOperation : public NdbOperation {
friend class Ndb;
friend class NdbConnection;
friend class NdbResultSet;
friend class NdbOperation;
-
+ friend class NdbBlob;
public:
/**
+ * Type of cursor
+ */
+ enum CursorType {
+ NoCursor = 0,
+ ScanCursor = 1,
+ IndexCursor = 2
+ };
+
+ /**
+ * Lock when performing scan
+ */
+ enum LockMode {
+ LM_Read = 0,
+ LM_Exclusive = 1,
+ LM_CommittedRead = 2,
+#ifndef DOXYGEN_SHOULD_SKIP_INTERNAL
+ LM_Dirty = 2
+#endif
+ };
+
+ /**
+ * Type of cursor
+ */
+ CursorType get_cursor_type() const;
+
+ /**
* readTuples returns a NdbResultSet where tuples are stored.
* Tuples are not stored in NdbResultSet until execute(NoCommit)
* has been executed and nextResult has been called.
*
* @param parallel Scan parallelism
+ * @param batch No of rows to fetch from each fragment at a time
* @param LockMode Scan lock handling
* @returns NdbResultSet.
+ * @note specifying 0 for batch and parallall means max performance
*/
- virtual NdbResultSet* readTuples(unsigned parallel = 0,
- LockMode = LM_Read );
+ NdbResultSet* readTuples(LockMode = LM_Read,
+ Uint32 batch = 0, Uint32 parallel = 0);
+
+ inline NdbResultSet* readTuples(int parallell){
+ return readTuples(LM_Read, 0, parallell);
+ }
+
+ inline NdbResultSet* readTuplesExclusive(int parallell = 0){
+ return readTuples(LM_Exclusive, 0, parallell);
+ }
-#ifndef DOXYGEN_SHOULD_SKIP_INTERNAL
-
- int updateTuples();
- int updateTuples(Uint32 parallelism);
-
- int deleteTuples();
- int deleteTuples(Uint32 parallelism);
-
- // Overload setValue for updateTuples
- int setValue(const char* anAttrName, const char* aValue, Uint32 len = 0);
- int setValue(const char* anAttrName, Int32 aValue);
- int setValue(const char* anAttrName, Uint32 aValue);
- int setValue(const char* anAttrName, Int64 aValue);
- int setValue(const char* anAttrName, Uint64 aValue);
- int setValue(const char* anAttrName, float aValue);
- int setValue(const char* anAttrName, double aValue);
-
- int setValue(Uint32 anAttrId, const char* aValue, Uint32 len = 0);
- int setValue(Uint32 anAttrId, Int32 aValue);
- int setValue(Uint32 anAttrId, Uint32 aValue);
- int setValue(Uint32 anAttrId, Int64 aValue);
- int setValue(Uint32 anAttrId, Uint64 aValue);
- int setValue(Uint32 anAttrId, float aValue);
- int setValue(Uint32 anAttrId, double aValue);
-#endif
-
NdbBlob* getBlobHandle(const char* anAttrName);
NdbBlob* getBlobHandle(Uint32 anAttrId);
-private:
- NdbScanOperation(Ndb* aNdb);
+protected:
+ CursorType m_cursor_type;
+ NdbScanOperation(Ndb* aNdb);
~NdbScanOperation();
- NdbCursorOperation::CursorType cursorType();
-
- virtual int nextResult(bool fetchAllowed = true);
+ int nextResult(bool fetchAllowed = true);
virtual void release();
void closeScan();
@@ -111,125 +117,54 @@ private:
virtual void setErrorCode(int aErrorCode);
virtual void setErrorCodeAbort(int aErrorCode);
- virtual int equal_impl(const NdbColumnImpl* anAttrObject,
- const char* aValue,
- Uint32 len);
-private:
+ NdbResultSet * m_resultSet;
+ NdbResultSet* getResultSet();
NdbConnection *m_transConnection;
- bool m_autoExecute;
- bool m_updateOp;
- bool m_writeOp;
- bool m_deleteOp;
- class SetValueRecList* m_setValueList;
-};
-#ifndef DOXYGEN_SHOULD_SKIP_INTERNAL
-class AttrInfo;
-class SetValueRecList;
+ // Scan related variables
+ Uint32 theBatchSize;
+ Uint32 theParallelism;
+ Uint32 m_keyInfo;
+ NdbApiSignal* theSCAN_TABREQ;
-class SetValueRec {
- friend class SetValueRecList;
-public:
- SetValueRec();
- ~SetValueRec();
-
- enum SetValueType {
- SET_STRING_ATTR1 = 0,
- SET_INT32_ATTR1 = 1,
- SET_UINT32_ATTR1 = 2,
- SET_INT64_ATTR1 = 3,
- SET_UINT64_ATTR1 = 4,
- SET_FLOAT_ATTR1 = 5,
- SET_DOUBLE_ATTR1 = 6,
- SET_STRING_ATTR2 = 7,
- SET_INT32_ATTR2 = 8,
- SET_UINT32_ATTR2 = 9,
- SET_INT64_ATTR2 = 10,
- SET_UINT64_ATTR2 = 11,
- SET_FLOAT_ATTR2 = 12,
- SET_DOUBLE_ATTR2 = 13
- };
-
- SetValueType stype;
- union {
- char* anAttrName;
- Uint32 anAttrId;
- };
- struct String {
- char* aStringValue;
- Uint32 len;
- };
- union {
- String stringStruct;
- Int32 anInt32Value;
- Uint32 anUint32Value;
- Int64 anInt64Value;
- Uint64 anUint64Value;
- float aFloatValue;
- double aDoubleValue;
- };
-private:
- SetValueRec* next;
-};
-
-inline
-SetValueRec::SetValueRec() :
- next(0)
-{
-}
+ int getFirstATTRINFOScan();
+ int doSendScan(int ProcessorId);
+ int prepareSendScan(Uint32 TC_ConnectPtr, Uint64 TransactionId);
+
+ int fix_receivers(Uint32 parallel);
+ Uint32* m_array; // containing all arrays below
+ Uint32 m_allocated_receivers;
+ NdbReceiver** m_receivers; // All receivers
-class SetValueRecList {
-public:
- SetValueRecList();
- ~SetValueRecList();
-
- void add(const char* anAttrName, const char* aValue, Uint32 len = 0);
- void add(const char* anAttrName, Int32 aValue);
- void add(const char* anAttrName, Uint32 aValue);
- void add(const char* anAttrName, Int64 aValue);
- void add(const char* anAttrName, Uint64 aValue);
- void add(const char* anAttrName, float aValue);
- void add(const char* anAttrName, double aValue);
- void add(Uint32 anAttrId, const char* aValue, Uint32 len = 0);
- void add(Uint32 anAttrId, Int32 aValue);
- void add(Uint32 anAttrId, Uint32 aValue);
- void add(Uint32 anAttrId, Int64 aValue);
- void add(Uint32 anAttrId, Uint64 aValue);
- void add(Uint32 anAttrId, float aValue);
- void add(Uint32 anAttrId, double aValue);
-
- typedef void(* IterateFn)(SetValueRec&, NdbOperation&);
- static void callSetValueFn(SetValueRec&, NdbOperation&);
- void iterate(IterateFn nextfn, NdbOperation&);
-private:
- SetValueRec* first;
- SetValueRec* last;
-};
+ Uint32* m_prepared_receivers; // These are to be sent
+
+ Uint32 m_current_api_receiver;
+ Uint32 m_api_receivers_count;
+ NdbReceiver** m_api_receivers; // These are currently used by api
+
+ Uint32 m_conf_receivers_count; // NOTE needs mutex to access
+ NdbReceiver** m_conf_receivers; // receive thread puts them here
+
+ Uint32 m_sent_receivers_count; // NOTE needs mutex to access
+ NdbReceiver** m_sent_receivers; // receive thread puts them here
+
+ int send_next_scan(Uint32 cnt, bool close);
+ void receiver_delivered(NdbReceiver*);
+ void receiver_completed(NdbReceiver*);
+ void execCLOSE_SCAN_REP();
-inline
-SetValueRecList::SetValueRecList() :
- first(0),
- last(0)
-{
-}
+ int getKeyFromKEYINFO20(Uint32* data, unsigned size);
+ NdbOperation* takeOverScanOp(OperationType opType, NdbConnection*);
-inline
-SetValueRecList::~SetValueRecList() {
- if (first) delete first;
- first = last = 0;
-}
+ Uint32 m_ordered;
+ int restart();
+};
inline
-void SetValueRecList::iterate(SetValueRecList::IterateFn nextfn, NdbOperation& oper)
-{
- SetValueRec* recPtr = first;
- while(recPtr) {
- (*nextfn)(*recPtr, oper);
- recPtr = recPtr->next; // Move to next in list - MASV
- }
+NdbScanOperation::CursorType
+NdbScanOperation::get_cursor_type() const {
+ return m_cursor_type;
}
#endif
-
-#endif
diff --git a/ndb/include/portlib/NdbTCP.h b/ndb/include/portlib/NdbTCP.h
index 42c34855c39..4dc8435eef1 100644
--- a/ndb/include/portlib/NdbTCP.h
+++ b/ndb/include/portlib/NdbTCP.h
@@ -64,7 +64,7 @@ typedef int socklen_t;
#define NDB_NONBLOCK O_NONBLOCK
#define NDB_SOCKET_TYPE int
#define NDB_INVALID_SOCKET -1
-#define NDB_CLOSE_SOCKET(x) close(x)
+#define NDB_CLOSE_SOCKET(x) ::close(x)
#define InetErrno errno
diff --git a/ndb/include/transporter/TransporterDefinitions.hpp b/ndb/include/transporter/TransporterDefinitions.hpp
index cb859e310db..0301d12348f 100644
--- a/ndb/include/transporter/TransporterDefinitions.hpp
+++ b/ndb/include/transporter/TransporterDefinitions.hpp
@@ -69,6 +69,7 @@ struct TCP_TransporterConfiguration {
* SHM Transporter Configuration
*/
struct SHM_TransporterConfiguration {
+ Uint32 port;
NodeId remoteNodeId;
NodeId localNodeId;
bool compression;
diff --git a/ndb/include/transporter/TransporterRegistry.hpp b/ndb/include/transporter/TransporterRegistry.hpp
index 6c979777f18..3c6c307406c 100644
--- a/ndb/include/transporter/TransporterRegistry.hpp
+++ b/ndb/include/transporter/TransporterRegistry.hpp
@@ -29,20 +29,10 @@
#define TransporterRegistry_H
#include "TransporterDefinitions.hpp"
+#include <SocketServer.hpp>
#include <NdbTCP.h>
-// A transporter is always in a PerformState.
-// PerformIO is used initially and as long as any of the events
-// PerformConnect, ...
-enum PerformState {
- PerformNothing = 4, // Does nothing
- PerformIO = 0, // Is connected
- PerformConnect = 1, // Is trying to connect
- PerformDisconnect = 2, // Trying to disconnect
- RemoveTransporter = 3 // Will be removed
-};
-
// A transporter is always in an IOState.
// NoHalt is used initially and as long as it is no restrictions on
// sending or receiving.
@@ -60,18 +50,45 @@ enum TransporterType {
tt_OSE_TRANSPORTER = 4
};
+static const char *performStateString[] =
+ { "is connected",
+ "is trying to connect",
+ "does nothing",
+ "is trying to disconnect" };
+
class Transporter;
class TCP_Transporter;
class SCI_Transporter;
class SHM_Transporter;
class OSE_Transporter;
+class TransporterRegistry;
+class SocketAuthenticator;
+
+class TransporterService : public SocketServer::Service {
+ SocketAuthenticator * m_auth;
+ TransporterRegistry * m_transporter_registry;
+public:
+ TransporterService(SocketAuthenticator *auth= 0)
+ {
+ m_auth= auth;
+ m_transporter_registry= 0;
+ }
+ void setTransporterRegistry(TransporterRegistry *t)
+ {
+ m_transporter_registry= t;
+ }
+ SocketServer::Session * newSession(NDB_SOCKET_TYPE socket);
+};
+
/**
* @class TransporterRegistry
* @brief ...
*/
class TransporterRegistry {
friend class OSE_Receiver;
+ friend class Transporter;
+ friend class TransporterService;
public:
/**
* Constructor
@@ -98,6 +115,12 @@ public:
*/
~TransporterRegistry();
+ bool start_service(SocketServer& server);
+ bool start_clients();
+ bool stop_clients();
+ void start_clients_thread();
+ void update_connections();
+
/**
* Start/Stop receiving
*/
@@ -110,16 +133,26 @@ public:
void startSending();
void stopSending();
+ // A transporter is always in a PerformState.
+ // PerformIO is used initially and as long as any of the events
+ // PerformConnect, ...
+ enum PerformState {
+ CONNECTED = 0,
+ CONNECTING = 1,
+ DISCONNECTED = 2,
+ DISCONNECTING = 3
+ };
+ const char *getPerformStateString(NodeId nodeId) const
+ { return performStateString[(unsigned)performStates[nodeId]]; };
+
/**
* Get and set methods for PerformState
*/
- PerformState performState(NodeId nodeId);
- void setPerformState(NodeId nodeId, PerformState state);
-
- /**
- * Set perform state for all transporters
- */
- void setPerformState(PerformState state);
+ void do_connect(NodeId node_id);
+ void do_disconnect(NodeId node_id);
+ bool is_connected(NodeId node_id) { return performStates[node_id] == CONNECTED; };
+ void report_connect(NodeId node_id);
+ void report_disconnect(NodeId node_id, int errnum);
/**
* Get and set methods for IOState
@@ -174,8 +207,6 @@ public:
void performReceive();
void performSend();
- void checkConnections();
-
/**
* Force sending if more than or equal to sendLimit
* number have asked for send. Returns 0 if not sending
@@ -187,11 +218,18 @@ public:
void printState();
#endif
+ unsigned short m_service_port;
+
protected:
private:
void * callbackObj;
+ TransporterService *m_transporter_service;
+ char *m_interface_name;
+ struct NdbThread *m_start_clients_thread;
+ bool m_run_start_clients_thread;
+
int sendCounter;
NodeId localNodeId;
bool nodeIdSpecified;
@@ -202,11 +240,6 @@ private:
int nSHMTransporters;
int nOSETransporters;
- int m_ccCount;
- int m_ccIndex;
- int m_ccStep;
- int m_nTransportersPerformConnect;
- bool m_ccReady;
/**
* Arrays holding all transporters in the order they are created
*/
diff --git a/ndb/include/util/BaseString.hpp b/ndb/include/util/BaseString.hpp
index 8755c13e9bb..a1bb91ea9c5 100644
--- a/ndb/include/util/BaseString.hpp
+++ b/ndb/include/util/BaseString.hpp
@@ -176,7 +176,7 @@ public:
/**
* Trim string from <i>delim</i>
*/
- static char* trim(char * src, const char * delim = " \t");
+ static char* trim(char * src, const char * delim);
private:
char* m_chr;
unsigned m_len;
diff --git a/ndb/include/util/Bitmask.hpp b/ndb/include/util/Bitmask.hpp
index 7355742f845..bb217adab5f 100644
--- a/ndb/include/util/Bitmask.hpp
+++ b/ndb/include/util/Bitmask.hpp
@@ -19,11 +19,6 @@
#include <ndb_global.h>
-#ifndef NDB_ASSERT
-#define NDB_ASSERT(x, s) \
- do { if (!(x)) { printf("%s\n", s); abort(); } } while (0)
-#endif
-
/**
* Bitmask implementation. Size is given explicitly
* (as first argument). All methods are static.
@@ -140,7 +135,7 @@ public:
inline bool
BitmaskImpl::get(unsigned size, const Uint32 data[], unsigned n)
{
- NDB_ASSERT(n < (size << 5), "bit get out of range");
+ assert(n < (size << 5));
return (data[n >> 5] & (1 << (n & 31))) != 0;
}
@@ -153,7 +148,7 @@ BitmaskImpl::set(unsigned size, Uint32 data[], unsigned n, bool value)
inline void
BitmaskImpl::set(unsigned size, Uint32 data[], unsigned n)
{
- NDB_ASSERT(n < (size << 5), "bit set out of range");
+ assert(n < (size << 5));
data[n >> 5] |= (1 << (n & 31));
}
@@ -176,7 +171,7 @@ BitmaskImpl::assign(unsigned size, Uint32 dst[], const Uint32 src[])
inline void
BitmaskImpl::clear(unsigned size, Uint32 data[], unsigned n)
{
- NDB_ASSERT(n < (size << 5), "bit clear out of range");
+ assert(n < (size << 5));
data[n >> 5] &= ~(1 << (n & 31));
}
@@ -326,7 +321,7 @@ BitmaskImpl::getText(unsigned size, const Uint32 data[], char* buf)
* XXX replace size by length in bits
*/
template <unsigned size>
-class Bitmask {
+struct BitmaskPOD {
public:
/**
* POD data representation
@@ -334,7 +329,7 @@ public:
struct Data {
Uint32 data[size];
#if 0
- Data & operator=(const Bitmask<size> & src) {
+ Data & operator=(const BitmaskPOD<size> & src) {
src.copyto(size, data);
return *this;
}
@@ -348,19 +343,17 @@ public:
STATIC_CONST( NotFound = BitmaskImpl::NotFound );
STATIC_CONST( TextLength = size * 8 );
- Bitmask() { clear();}
-
/**
* assign - Set all bits in <em>dst</em> to corresponding in <em>src/<em>
*/
- void assign(const typename Bitmask<size>::Data & src);
+ void assign(const typename BitmaskPOD<size>::Data & src);
/**
* assign - Set all bits in <em>dst</em> to corresponding in <em>src/<em>
*/
static void assign(Uint32 dst[], const Uint32 src[]);
- static void assign(Uint32 dst[], const Bitmask<size> & src);
- void assign(const Bitmask<size> & src);
+ static void assign(Uint32 dst[], const BitmaskPOD<size> & src);
+ void assign(const BitmaskPOD<size> & src);
/**
* copy this to <em>dst</em>
@@ -432,43 +425,43 @@ public:
* equal - Bitwise equal.
*/
static bool equal(const Uint32 data[], const Uint32 data2[]);
- bool equal(const Bitmask<size>& mask2) const;
+ bool equal(const BitmaskPOD<size>& mask2) const;
/**
* bitOR - Bitwise (x | y) into first operand.
*/
static void bitOR(Uint32 data[], const Uint32 data2[]);
- Bitmask<size>& bitOR(const Bitmask<size>& mask2);
+ BitmaskPOD<size>& bitOR(const BitmaskPOD<size>& mask2);
/**
* bitAND - Bitwise (x & y) into first operand.
*/
static void bitAND(Uint32 data[], const Uint32 data2[]);
- Bitmask<size>& bitAND(const Bitmask<size>& mask2);
+ BitmaskPOD<size>& bitAND(const BitmaskPOD<size>& mask2);
/**
* bitANDC - Bitwise (x & ~y) into first operand.
*/
static void bitANDC(Uint32 data[], const Uint32 data2[]);
- Bitmask<size>& bitANDC(const Bitmask<size>& mask2);
+ BitmaskPOD<size>& bitANDC(const BitmaskPOD<size>& mask2);
/**
* bitXOR - Bitwise (x ^ y) into first operand.
*/
static void bitXOR(Uint32 data[], const Uint32 data2[]);
- Bitmask<size>& bitXOR(const Bitmask<size>& mask2);
+ BitmaskPOD<size>& bitXOR(const BitmaskPOD<size>& mask2);
/**
* contains - Check if all bits set in data2 (that) are also set in data (this)
*/
static bool contains(Uint32 data[], const Uint32 data2[]);
- bool contains(Bitmask<size> that);
+ bool contains(BitmaskPOD<size> that);
/**
- * overlaps - Check if any bit set in this Bitmask (data) is also set in that (data2)
+ * overlaps - Check if any bit set in this BitmaskPOD (data) is also set in that (data2)
*/
static bool overlaps(Uint32 data[], const Uint32 data2[]);
- bool overlaps(Bitmask<size> that);
+ bool overlaps(BitmaskPOD<size> that);
/**
* getText - Return as hex-digits (only for debug routines).
@@ -479,286 +472,292 @@ public:
template <unsigned size>
inline void
-Bitmask<size>::assign(Uint32 dst[], const Uint32 src[])
+BitmaskPOD<size>::assign(Uint32 dst[], const Uint32 src[])
{
BitmaskImpl::assign(size, dst, src);
}
template <unsigned size>
inline void
-Bitmask<size>::assign(Uint32 dst[], const Bitmask<size> & src)
+BitmaskPOD<size>::assign(Uint32 dst[], const BitmaskPOD<size> & src)
{
BitmaskImpl::assign(size, dst, src.rep.data);
}
template <unsigned size>
inline void
-Bitmask<size>::assign(const typename Bitmask<size>::Data & src)
+BitmaskPOD<size>::assign(const typename BitmaskPOD<size>::Data & src)
{
- assign(rep.data, src.data);
+ BitmaskPOD<size>::assign(rep.data, src.data);
}
template <unsigned size>
inline void
-Bitmask<size>::assign(const Bitmask<size> & src)
+BitmaskPOD<size>::assign(const BitmaskPOD<size> & src)
{
- assign(rep.data, src.rep.data);
+ BitmaskPOD<size>::assign(rep.data, src.rep.data);
}
template <unsigned size>
inline void
-Bitmask<size>::copyto(unsigned sz, Uint32 dst[]) const
+BitmaskPOD<size>::copyto(unsigned sz, Uint32 dst[]) const
{
BitmaskImpl::assign(sz, dst, rep.data);
}
template <unsigned size>
inline void
-Bitmask<size>::assign(unsigned sz, const Uint32 src[])
+BitmaskPOD<size>::assign(unsigned sz, const Uint32 src[])
{
BitmaskImpl::assign(sz, rep.data, src);
}
template <unsigned size>
inline bool
-Bitmask<size>::get(const Uint32 data[], unsigned n)
+BitmaskPOD<size>::get(const Uint32 data[], unsigned n)
{
return BitmaskImpl::get(size, data, n);
}
template <unsigned size>
inline bool
-Bitmask<size>::get(unsigned n) const
+BitmaskPOD<size>::get(unsigned n) const
{
- return get(rep.data, n);
+ return BitmaskPOD<size>::get(rep.data, n);
}
template <unsigned size>
inline void
-Bitmask<size>::set(Uint32 data[], unsigned n, bool value)
+BitmaskPOD<size>::set(Uint32 data[], unsigned n, bool value)
{
BitmaskImpl::set(size, data, n, value);
}
template <unsigned size>
inline void
-Bitmask<size>::set(unsigned n, bool value)
+BitmaskPOD<size>::set(unsigned n, bool value)
{
- set(rep.data, n, value);
+ BitmaskPOD<size>::set(rep.data, n, value);
}
template <unsigned size>
inline void
-Bitmask<size>::set(Uint32 data[], unsigned n)
+BitmaskPOD<size>::set(Uint32 data[], unsigned n)
{
BitmaskImpl::set(size, data, n);
}
template <unsigned size>
inline void
-Bitmask<size>::set(unsigned n)
+BitmaskPOD<size>::set(unsigned n)
{
- set(rep.data, n);
+ BitmaskPOD<size>::set(rep.data, n);
}
template <unsigned size>
inline void
-Bitmask<size>::set(Uint32 data[])
+BitmaskPOD<size>::set(Uint32 data[])
{
BitmaskImpl::set(size, data);
}
template <unsigned size>
inline void
-Bitmask<size>::set()
+BitmaskPOD<size>::set()
{
- set(rep.data);
+ BitmaskPOD<size>::set(rep.data);
}
template <unsigned size>
inline void
-Bitmask<size>::clear(Uint32 data[], unsigned n)
+BitmaskPOD<size>::clear(Uint32 data[], unsigned n)
{
BitmaskImpl::clear(size, data, n);
}
template <unsigned size>
inline void
-Bitmask<size>::clear(unsigned n)
+BitmaskPOD<size>::clear(unsigned n)
{
- clear(rep.data, n);
+ BitmaskPOD<size>::clear(rep.data, n);
}
template <unsigned size>
inline void
-Bitmask<size>::clear(Uint32 data[])
+BitmaskPOD<size>::clear(Uint32 data[])
{
BitmaskImpl::clear(size, data);
}
template <unsigned size>
inline void
-Bitmask<size>::clear()
+BitmaskPOD<size>::clear()
{
- clear(rep.data);
+ BitmaskPOD<size>::clear(rep.data);
}
template <unsigned size>
inline bool
-Bitmask<size>::isclear(const Uint32 data[])
+BitmaskPOD<size>::isclear(const Uint32 data[])
{
return BitmaskImpl::isclear(size, data);
}
template <unsigned size>
inline bool
-Bitmask<size>::isclear() const
+BitmaskPOD<size>::isclear() const
{
- return isclear(rep.data);
+ return BitmaskPOD<size>::isclear(rep.data);
}
template <unsigned size>
unsigned
-Bitmask<size>::count(const Uint32 data[])
+BitmaskPOD<size>::count(const Uint32 data[])
{
return BitmaskImpl::count(size, data);
}
template <unsigned size>
inline unsigned
-Bitmask<size>::count() const
+BitmaskPOD<size>::count() const
{
- return count(rep.data);
+ return BitmaskPOD<size>::count(rep.data);
}
template <unsigned size>
unsigned
-Bitmask<size>::find(const Uint32 data[], unsigned n)
+BitmaskPOD<size>::find(const Uint32 data[], unsigned n)
{
return BitmaskImpl::find(size, data, n);
}
template <unsigned size>
inline unsigned
-Bitmask<size>::find(unsigned n) const
+BitmaskPOD<size>::find(unsigned n) const
{
- return find(rep.data, n);
+ return BitmaskPOD<size>::find(rep.data, n);
}
template <unsigned size>
inline bool
-Bitmask<size>::equal(const Uint32 data[], const Uint32 data2[])
+BitmaskPOD<size>::equal(const Uint32 data[], const Uint32 data2[])
{
return BitmaskImpl::equal(size, data, data2);
}
template <unsigned size>
inline bool
-Bitmask<size>::equal(const Bitmask<size>& mask2) const
+BitmaskPOD<size>::equal(const BitmaskPOD<size>& mask2) const
{
- return equal(rep.data, mask2.rep.data);
+ return BitmaskPOD<size>::equal(rep.data, mask2.rep.data);
}
template <unsigned size>
inline void
-Bitmask<size>::bitOR(Uint32 data[], const Uint32 data2[])
+BitmaskPOD<size>::bitOR(Uint32 data[], const Uint32 data2[])
{
BitmaskImpl::bitOR(size,data, data2);
}
template <unsigned size>
-inline Bitmask<size>&
-Bitmask<size>::bitOR(const Bitmask<size>& mask2)
+inline BitmaskPOD<size>&
+BitmaskPOD<size>::bitOR(const BitmaskPOD<size>& mask2)
{
- bitOR(rep.data, mask2.rep.data);
+ BitmaskPOD<size>::bitOR(rep.data, mask2.rep.data);
return *this;
}
template <unsigned size>
inline void
-Bitmask<size>::bitAND(Uint32 data[], const Uint32 data2[])
+BitmaskPOD<size>::bitAND(Uint32 data[], const Uint32 data2[])
{
BitmaskImpl::bitAND(size,data, data2);
}
template <unsigned size>
-inline Bitmask<size>&
-Bitmask<size>::bitAND(const Bitmask<size>& mask2)
+inline BitmaskPOD<size>&
+BitmaskPOD<size>::bitAND(const BitmaskPOD<size>& mask2)
{
- bitAND(rep.data, mask2.rep.data);
+ BitmaskPOD<size>::bitAND(rep.data, mask2.rep.data);
return *this;
}
template <unsigned size>
inline void
-Bitmask<size>::bitANDC(Uint32 data[], const Uint32 data2[])
+BitmaskPOD<size>::bitANDC(Uint32 data[], const Uint32 data2[])
{
BitmaskImpl::bitANDC(size,data, data2);
}
template <unsigned size>
-inline Bitmask<size>&
-Bitmask<size>::bitANDC(const Bitmask<size>& mask2)
+inline BitmaskPOD<size>&
+BitmaskPOD<size>::bitANDC(const BitmaskPOD<size>& mask2)
{
- bitANDC(rep.data, mask2.rep.data);
+ BitmaskPOD<size>::bitANDC(rep.data, mask2.rep.data);
return *this;
}
template <unsigned size>
inline void
-Bitmask<size>::bitXOR(Uint32 data[], const Uint32 data2[])
+BitmaskPOD<size>::bitXOR(Uint32 data[], const Uint32 data2[])
{
BitmaskImpl::bitXOR(size,data, data2);
}
template <unsigned size>
-inline Bitmask<size>&
-Bitmask<size>::bitXOR(const Bitmask<size>& mask2)
+inline BitmaskPOD<size>&
+BitmaskPOD<size>::bitXOR(const BitmaskPOD<size>& mask2)
{
- bitXOR(rep.data, mask2.rep.data);
+ BitmaskPOD<size>::bitXOR(rep.data, mask2.rep.data);
return *this;
}
template <unsigned size>
char *
-Bitmask<size>::getText(const Uint32 data[], char* buf)
+BitmaskPOD<size>::getText(const Uint32 data[], char* buf)
{
return BitmaskImpl::getText(size, data, buf);
}
template <unsigned size>
inline char *
-Bitmask<size>::getText(char* buf) const
+BitmaskPOD<size>::getText(char* buf) const
{
- return getText(rep.data, buf);
+ return BitmaskPOD<size>::getText(rep.data, buf);
}
template <unsigned size>
inline bool
-Bitmask<size>::contains(Uint32 data[], const Uint32 data2[])
+BitmaskPOD<size>::contains(Uint32 data[], const Uint32 data2[])
{
return BitmaskImpl::contains(size, data, data2);
}
template <unsigned size>
inline bool
-Bitmask<size>::contains(Bitmask<size> that)
+BitmaskPOD<size>::contains(BitmaskPOD<size> that)
{
- return contains(this->rep.data, that.rep.data);
+ return BitmaskPOD<size>::contains(this->rep.data, that.rep.data);
}
template <unsigned size>
inline bool
-Bitmask<size>::overlaps(Uint32 data[], const Uint32 data2[])
+BitmaskPOD<size>::overlaps(Uint32 data[], const Uint32 data2[])
{
return BitmaskImpl::overlaps(size, data, data2);
}
template <unsigned size>
inline bool
-Bitmask<size>::overlaps(Bitmask<size> that)
+BitmaskPOD<size>::overlaps(BitmaskPOD<size> that)
{
- return overlaps(this->rep.data, that.rep.data);
+ return BitmaskPOD<size>::overlaps(this->rep.data, that.rep.data);
}
+template <unsigned size>
+class Bitmask : public BitmaskPOD<size> {
+public:
+ Bitmask() { this->clear();}
+};
+
#endif
diff --git a/ndb/include/util/ConfigValues.hpp b/ndb/include/util/ConfigValues.hpp
index 3fbeedb25a0..457488e3c42 100644
--- a/ndb/include/util/ConfigValues.hpp
+++ b/ndb/include/util/ConfigValues.hpp
@@ -32,9 +32,8 @@ public:
class ConstIterator {
friend class ConfigValuesFactory;
const ConfigValues & m_cfg;
- protected:
- Uint32 m_currentSection;
public:
+ Uint32 m_currentSection;
ConstIterator(const ConfigValues&c) : m_cfg(c) { m_currentSection = 0;}
bool openSection(Uint32 key, Uint32 no);
@@ -57,6 +56,9 @@ public:
ConfigValues & m_cfg;
public:
Iterator(ConfigValues&c) : ConstIterator(c), m_cfg(c) {}
+ Iterator(ConfigValues&c, const ConstIterator& i):ConstIterator(c),m_cfg(c){
+ m_currentSection = i.m_currentSection;
+ }
bool set(Uint32 key, Uint32 value);
bool set(Uint32 key, Uint64 value);
diff --git a/ndb/include/util/NdbSqlUtil.hpp b/ndb/include/util/NdbSqlUtil.hpp
index 841da513d4a..a79245868e0 100644
--- a/ndb/include/util/NdbSqlUtil.hpp
+++ b/ndb/include/util/NdbSqlUtil.hpp
@@ -17,8 +17,7 @@
#ifndef NDB_SQL_UTIL_HPP
#define NDB_SQL_UTIL_HPP
-#include <string.h>
-#include <ndb_types.h>
+#include <ndb_global.h>
#include <kernel/ndb_limits.h>
class NdbSqlUtil {
@@ -80,7 +79,7 @@ public:
Datetime, // Precision down to 1 sec (size 8 bytes)
Timespec, // Precision down to 1 nsec (size 12 bytes)
Blob, // Blob
- Clob // Text blob
+ Text // Text blob
};
Enum m_typeId;
Cmp* m_cmp; // set to NULL if cmp not implemented
@@ -125,12 +124,13 @@ private:
static Cmp cmpDatetime;
static Cmp cmpTimespec;
static Cmp cmpBlob;
- static Cmp cmpClob;
+ static Cmp cmpText;
};
inline int
NdbSqlUtil::cmp(Uint32 typeId, const Uint32* p1, const Uint32* p2, Uint32 full, Uint32 size)
{
+ // XXX require size >= 1
if (size > full)
return CmpError;
switch ((Type::Enum)typeId) {
@@ -192,10 +192,38 @@ NdbSqlUtil::cmp(Uint32 typeId, const Uint32* p1, const Uint32* p2, Uint32 full,
}
return CmpUnknown;
}
- case Type::Mediumint: // XXX fix these
- break;
+ case Type::Mediumint:
+ {
+ if (size >= 1) {
+ union { const Uint32* p; const unsigned char* v; } u1, u2;
+ u1.p = p1;
+ u2.p = p2;
+ Int32 v1 = sint3korr(u1.v);
+ Int32 v2 = sint3korr(u2.v);
+ if (v1 < v2)
+ return -1;
+ if (v1 > v2)
+ return +1;
+ return 0;
+ }
+ return CmpUnknown;
+ }
case Type::Mediumunsigned:
- break;
+ {
+ if (size >= 1) {
+ union { const Uint32* p; const unsigned char* v; } u1, u2;
+ u1.p = p1;
+ u2.p = p2;
+ Uint32 v1 = uint3korr(u1.v);
+ Uint32 v2 = uint3korr(u2.v);
+ if (v1 < v2)
+ return -1;
+ if (v1 > v2)
+ return +1;
+ return 0;
+ }
+ return CmpUnknown;
+ }
case Type::Int:
{
if (size >= 1) {
@@ -287,6 +315,7 @@ NdbSqlUtil::cmp(Uint32 typeId, const Uint32* p1, const Uint32* p2, Uint32 full,
return CmpUnknown;
}
case Type::Decimal:
+ // XXX not used by MySQL or NDB
break;
case Type::Char:
{
@@ -317,10 +346,28 @@ NdbSqlUtil::cmp(Uint32 typeId, const Uint32* p1, const Uint32* p2, Uint32 full,
}
return CmpUnknown;
}
- case Type::Binary: // XXX fix these
- break;
+ case Type::Binary:
+ {
+ // compare byte wise
+ union { const Uint32* p; const char* v; } u1, u2;
+ u1.p = p1;
+ u2.p = p2;
+ int k = memcmp(u1.v, u2.v, size << 2);
+ return k < 0 ? -1 : k > 0 ? +1 : full == size ? 0 : CmpUnknown;
+ }
case Type::Varbinary:
- break;
+ {
+ // assume correctly padded and compare byte wise
+ if (size >= 1) {
+ union { const Uint32* p; const char* v; } u1, u2;
+ u1.p = p1;
+ u2.p = p2;
+ // length in first 2 bytes
+ int k = memcmp(u1.v + 2, u2.v + 2, (size << 2) - 2);
+ return k < 0 ? -1 : k > 0 ? +1 : full == size ? 0 : CmpUnknown;
+ }
+ return CmpUnknown;
+ }
case Type::Datetime:
{
/*
@@ -331,29 +378,66 @@ NdbSqlUtil::cmp(Uint32 typeId, const Uint32* p1, const Uint32* p2, Uint32 full,
u1.p = p1;
u2.p = p2;
// skip format check
- int k = strncmp(u1.v, u2.v, 4);
+ int k = memcmp(u1.v, u2.v, 4);
if (k != 0)
- return k;
+ return k < 0 ? -1 : +1;
if (size >= 2) {
- return strncmp(u1.v + 4, u2.v + 4, 4);
+ k = memcmp(u1.v + 4, u2.v + 4, 4);
+ return k < 0 ? -1 : k > 0 ? +1 : 0;
}
}
return CmpUnknown;
}
- case Type::Timespec: // XXX fix this
- break;
- case Type::Blob: // XXX fix
- break;
- case Type::Clob:
+ case Type::Timespec:
+ {
+ /*
+ * Timespec is CC YY MM DD hh mm ss \0 NN NN NN NN
+ */
+ if (size >= 1) {
+ union { const Uint32* p; const char* v; } u1, u2;
+ u1.p = p1;
+ u2.p = p2;
+ // skip format check
+ int k = memcmp(u1.v, u2.v, 4);
+ if (k != 0)
+ return k < 0 ? -1 : +1;
+ if (size >= 2) {
+ k = memcmp(u1.v + 4, u2.v + 4, 4);
+ if (k != 0)
+ return k < 0 ? -1 : +1;
+ Uint32 n1 = *(const Uint32*)(u1.v + 8);
+ Uint32 n2 = *(const Uint32*)(u2.v + 8);
+ if (n1 < n2)
+ return -1;
+ if (n2 > n1)
+ return +1;
+ return 0;
+ }
+ }
+ return CmpUnknown;
+ }
+ case Type::Blob:
{
- // skip blob head, the rest is varchar
+ // skip blob head, the rest is binary
const unsigned skip = NDB_BLOB_HEAD_SIZE;
if (size >= skip + 1) {
union { const Uint32* p; const char* v; } u1, u2;
u1.p = p1 + skip;
u2.p = p2 + skip;
- // length in first 2 bytes
- int k = strncmp(u1.v + 2, u2.v + 2, ((size - skip) << 2) - 2);
+ int k = memcmp(u1.v, u2.v, (size - 1) << 2);
+ return k < 0 ? -1 : k > 0 ? +1 : full == size ? 0 : CmpUnknown;
+ }
+ return CmpUnknown;
+ }
+ case Type::Text:
+ {
+ // skip blob head, the rest is char
+ const unsigned skip = NDB_BLOB_HEAD_SIZE;
+ if (size >= skip + 1) {
+ union { const Uint32* p; const char* v; } u1, u2;
+ u1.p = p1 + skip;
+ u2.p = p2 + skip;
+ int k = memcmp(u1.v, u2.v, (size - 1) << 2);
return k < 0 ? -1 : k > 0 ? +1 : full == size ? 0 : CmpUnknown;
}
return CmpUnknown;
diff --git a/ndb/include/util/Properties.hpp b/ndb/include/util/Properties.hpp
index 2c30f7f7e3c..df8e2887001 100644
--- a/ndb/include/util/Properties.hpp
+++ b/ndb/include/util/Properties.hpp
@@ -55,7 +55,7 @@ public:
static const char delimiter = ':';
static const char version[];
- Properties();
+ Properties(bool case_insensitive= false);
Properties(const Properties &);
Properties(const Property *, int len);
virtual ~Properties();
diff --git a/ndb/include/util/SocketAuthenticator.hpp b/ndb/include/util/SocketAuthenticator.hpp
new file mode 100644
index 00000000000..1b82567feaa
--- /dev/null
+++ b/ndb/include/util/SocketAuthenticator.hpp
@@ -0,0 +1,39 @@
+/* Copyright (C) 2003 MySQL AB
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
+
+#ifndef SOCKET_AUTHENTICATOR_HPP
+#define SOCKET_AUTHENTICATOR_HPP
+
+class SocketAuthenticator
+{
+public:
+ virtual ~SocketAuthenticator() {};
+ virtual bool client_authenticate(int sockfd) = 0;
+ virtual bool server_authenticate(int sockfd) = 0;
+};
+
+class SocketAuthSimple : public SocketAuthenticator
+{
+ const char *m_passwd;
+ const char *m_username;
+public:
+ SocketAuthSimple(const char *username, const char *passwd);
+ virtual ~SocketAuthSimple();
+ virtual bool client_authenticate(int sockfd);
+ virtual bool server_authenticate(int sockfd);
+};
+
+#endif // SOCKET_AUTHENTICATOR_HPP
diff --git a/ndb/include/util/SocketClient.hpp b/ndb/include/util/SocketClient.hpp
new file mode 100644
index 00000000000..de9a081464a
--- /dev/null
+++ b/ndb/include/util/SocketClient.hpp
@@ -0,0 +1,38 @@
+/* Copyright (C) 2003 MySQL AB
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
+
+#ifndef SOCKET_CLIENT_HPP
+#define SOCKET_CLIENT_HPP
+
+#include <NdbTCP.h>
+class SocketAuthenticator;
+
+class SocketClient
+{
+ NDB_SOCKET_TYPE m_sockfd;
+ struct sockaddr_in m_servaddr;
+ unsigned short m_port;
+ char *m_server_name;
+ SocketAuthenticator *m_auth;
+public:
+ SocketClient(const char *server_name, unsigned short port, SocketAuthenticator *sa = 0);
+ ~SocketClient();
+ bool init();
+ NDB_SOCKET_TYPE connect();
+ bool close();
+};
+
+#endif // SOCKET_ClIENT_HPP