diff options
Diffstat (limited to 'ndb/include')
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 |