diff options
Diffstat (limited to 'ndb/src')
72 files changed, 2117 insertions, 1849 deletions
diff --git a/ndb/src/common/debugger/signaldata/DictTabInfo.cpp b/ndb/src/common/debugger/signaldata/DictTabInfo.cpp index c6165532ddb..4d95e9b03b5 100644 --- a/ndb/src/common/debugger/signaldata/DictTabInfo.cpp +++ b/ndb/src/common/debugger/signaldata/DictTabInfo.cpp @@ -23,7 +23,6 @@ SimpleProperties::SP2StructMapping DictTabInfo::TableMapping[] = { DTIMAPS(Table, TableName, TableName, 0, MAX_TAB_NAME_SIZE), DTIMAP(Table, TableId, TableId), - DTIMAP(Table, SecondTableId, SecondTableId), DTIMAPS(Table, PrimaryTable, PrimaryTable, 0, MAX_TAB_NAME_SIZE), DTIMAP(Table, PrimaryTableId, PrimaryTableId), DTIMAP2(Table, TableLoggedFlag, TableLoggedFlag, 0, 1), @@ -32,8 +31,6 @@ DictTabInfo::TableMapping[] = { DTIMAP2(Table, MaxLoadFactor, MaxLoadFactor, 25, 110), DTIMAP2(Table, FragmentTypeVal, FragmentType, 0, 3), DTIMAP2(Table, TableStorageVal, TableStorage, 0, 0), - DTIMAP2(Table, ScanOptimised, ScanOptimised, 0, 0), - DTIMAP2(Table, FragmentKeyTypeVal, FragmentKeyType, 0, 2), DTIMAP2(Table, TableTypeVal, TableType, 1, 3), DTIMAP(Table, NoOfKeyAttr, NoOfKeyAttr), DTIMAP2(Table, NoOfAttributes, NoOfAttributes, 1, MAX_ATTRIBUTES_IN_TABLE), @@ -62,16 +59,12 @@ SimpleProperties::SP2StructMapping DictTabInfo::AttributeMapping[] = { DTIMAPS(Attribute, AttributeName, AttributeName, 0, MAX_ATTR_NAME_SIZE), DTIMAP(Attribute, AttributeId, AttributeId), - DTIMAP2(Attribute, AttributeType, AttributeType, 0, 3), + DTIMAP(Attribute, AttributeType, AttributeType), DTIMAP2(Attribute, AttributeSize, AttributeSize, 3, 7), DTIMAP2(Attribute, AttributeArraySize, AttributeArraySize, 0, 65535), DTIMAP2(Attribute, AttributeKeyFlag, AttributeKeyFlag, 0, 1), - DTIMAP2(Attribute, AttributeStorage, AttributeStorage, 0, 0), DTIMAP2(Attribute, AttributeNullableFlag, AttributeNullableFlag, 0, 1), - DTIMAP2(Attribute, AttributeDGroup, AttributeDGroup, 0, 1), DTIMAP2(Attribute, AttributeDKey, AttributeDKey, 0, 1), - DTIMAP2(Attribute, AttributeStoredInd, AttributeStoredInd, 0, 1), - DTIMAP2(Attribute, AttributeGroup, AttributeGroup, 0, 0), DTIMAP(Attribute, AttributeExtType, AttributeExtType), DTIMAP(Attribute, AttributeExtPrecision, AttributeExtPrecision), DTIMAP(Attribute, AttributeExtScale, AttributeExtScale), @@ -104,7 +97,6 @@ void DictTabInfo::Table::init(){ memset(TableName, 0, sizeof(TableName));//TableName[0] = 0; TableId = ~0; - SecondTableId = ~0; memset(PrimaryTable, 0, sizeof(PrimaryTable));//PrimaryTable[0] = 0; // Only used when "index" PrimaryTableId = RNIL; TableLoggedFlag = 1; @@ -118,8 +110,6 @@ DictTabInfo::Table::init(){ KeyLength = 0; FragmentType = DictTabInfo::AllNodesSmallTable; TableStorage = 0; - ScanOptimised = 0; - FragmentKeyType = DictTabInfo::PrimaryKey; TableType = DictTabInfo::UndefTableType; TableVersion = 0; IndexState = ~0; @@ -136,17 +126,13 @@ void DictTabInfo::Attribute::init(){ memset(AttributeName, 0, sizeof(AttributeName));//AttributeName[0] = 0; AttributeId = 0; - AttributeType = DictTabInfo::UnSignedType; + AttributeType = ~0, // deprecated AttributeSize = DictTabInfo::a32Bit; AttributeArraySize = 1; AttributeKeyFlag = 0; - AttributeStorage = 1; AttributeNullableFlag = 0; - AttributeDGroup = 0; AttributeDKey = 0; - AttributeStoredInd = 1; - AttributeGroup = 0; - AttributeExtType = 0, + AttributeExtType = DictTabInfo::ExtUnsigned, AttributeExtPrecision = 0, AttributeExtScale = 0, AttributeExtLength = 0, diff --git a/ndb/src/common/debugger/signaldata/ScanTab.cpp b/ndb/src/common/debugger/signaldata/ScanTab.cpp index 0755ee0a856..e9c5ba6cc52 100644 --- a/ndb/src/common/debugger/signaldata/ScanTab.cpp +++ b/ndb/src/common/debugger/signaldata/ScanTab.cpp @@ -30,20 +30,25 @@ printSCANTABREQ(FILE * output, const Uint32 * theData, Uint32 len, Uint16 receiv fprintf(output, " apiConnectPtr: H\'%.8x", sig->apiConnectPtr); fprintf(output, " requestInfo: H\'%.8x:\n", requestInfo); - fprintf(output, " Parallellism: %u, Batch: %u LockMode: %u, Keyinfo: %u Holdlock: %u, RangeScan: %u ReadCommitted: %u\n", + fprintf(output, " Parallellism: %u, Batch: %u LockMode: %u Keyinfo: %u Holdlock: %u RangeScan: %u Descending: %u ReadCommitted: %u\n DistributionKeyFlag: %u", sig->getParallelism(requestInfo), sig->getScanBatch(requestInfo), sig->getLockMode(requestInfo), sig->getKeyinfoFlag(requestInfo), sig->getHoldLockFlag(requestInfo), sig->getRangeScanFlag(requestInfo), - sig->getReadCommittedFlag(requestInfo)); + sig->getDescendingFlag(requestInfo), + sig->getReadCommittedFlag(requestInfo), + sig->getDistributionKeyFlag(requestInfo)); + + if(sig->getDistributionKeyFlag(requestInfo)) + fprintf(output, " DKey: %x", sig->distributionKey); Uint32 keyLen = (sig->attrLenKeyLen >> 16); Uint32 attrLen = (sig->attrLenKeyLen & 0xFFFF); fprintf(output, " attrLen: %d, keyLen: %d tableId: %d, tableSchemaVer: %d\n", attrLen, keyLen, sig->tableId, sig->tableSchemaVersion); - + fprintf(output, " transId(1, 2): (H\'%.8x, H\'%.8x) storedProcId: H\'%.8x\n", sig->transId1, sig->transId2, sig->storedProcId); fprintf(output, " batch_byte_size: %d, first_batch_size: %d\n", diff --git a/ndb/src/common/mgmcommon/IPCConfig.cpp b/ndb/src/common/mgmcommon/IPCConfig.cpp index 780504d2c62..d451e05cda4 100644 --- a/ndb/src/common/mgmcommon/IPCConfig.cpp +++ b/ndb/src/common/mgmcommon/IPCConfig.cpp @@ -367,7 +367,7 @@ IPCConfig::configureTransporters(Uint32 nodeId, Uint32 server_port= 0; if(iter.get(CFG_CONNECTION_SERVER_PORT, &server_port)) break; if (nodeId <= nodeId1 && nodeId <= nodeId2) { - tr.add_transporter_interface(localHostName, server_port); + tr.add_transporter_interface(remoteNodeId, localHostName, server_port); } DBUG_PRINT("info", ("Transporter between this node %d and node %d using port %d, signalId %d, checksum %d", nodeId, remoteNodeId, server_port, sendSignalId, checksum)); diff --git a/ndb/src/common/transporter/Transporter.hpp b/ndb/src/common/transporter/Transporter.hpp index 9a39f8788bc..8804cde8a3a 100644 --- a/ndb/src/common/transporter/Transporter.hpp +++ b/ndb/src/common/transporter/Transporter.hpp @@ -69,6 +69,16 @@ public: */ NodeId getLocalNodeId() const; + /** + * Get r_port we're connecting to + */ + unsigned int get_r_port() { return m_r_port; }; + + /** + * Set r_port to connect to + */ + void set_r_port(unsigned int port) { m_r_port = port; }; + protected: Transporter(TransporterRegistry &, const char *lHostName, @@ -101,7 +111,7 @@ protected: struct in_addr remoteHostAddress; struct in_addr localHostAddress; - const unsigned int m_r_port; + unsigned int m_r_port; const NodeId remoteNodeId; const NodeId localNodeId; @@ -149,7 +159,7 @@ Transporter::getRemoteNodeId() const { inline NodeId Transporter::getLocalNodeId() const { - return remoteNodeId; + return localNodeId; } inline diff --git a/ndb/src/common/transporter/TransporterRegistry.cpp b/ndb/src/common/transporter/TransporterRegistry.cpp index be51e9223ba..bcc809409dd 100644 --- a/ndb/src/common/transporter/TransporterRegistry.cpp +++ b/ndb/src/common/transporter/TransporterRegistry.cpp @@ -47,6 +47,8 @@ #include <InputStream.hpp> #include <OutputStream.hpp> +#include <mgmapi/mgmapi_debug.h> + int g_shm_pid = 0; SocketServer::Session * TransporterService::newSession(NDB_SOCKET_TYPE sockfd) @@ -105,13 +107,15 @@ SocketServer::Session * TransporterService::newSession(NDB_SOCKET_TYPE sockfd) DBUG_RETURN(0); } -TransporterRegistry::TransporterRegistry(void * callback, +TransporterRegistry::TransporterRegistry(NdbMgmHandle mgm_handle, + void * callback, unsigned _maxTransporters, unsigned sizeOfLongSignalMemory) { nodeIdSpecified = false; maxTransporters = _maxTransporters; sendCounter = 1; + m_mgm_handle = mgm_handle; callbackObj=callback; @@ -1136,8 +1140,27 @@ TransporterRegistry::start_clients_thread() const NodeId nodeId = t->getRemoteNodeId(); switch(performStates[nodeId]){ case CONNECTING: - if(!t->isConnected() && !t->isServer) - t->connect_client(); + if(!t->isConnected() && !t->isServer) { + if(t->get_r_port() <= 0) { // Port is dynamic + Uint32 server_port=0; + struct ndb_mgm_reply mgm_reply; + int res; + res=ndb_mgm_get_connection_int_parameter(m_mgm_handle, + t->getRemoteNodeId(), + t->getLocalNodeId(), + CFG_CONNECTION_SERVER_PORT, + &server_port, + &mgm_reply); + DBUG_PRINT("info",("Got dynamic port %u for %d -> %d (ret: %d)", + server_port,t->getRemoteNodeId(), + t->getLocalNodeId())); + if(res>=0) + t->set_r_port(server_port); + else + ndbout_c("Failed to get dynamic port to connect to."); + } + t->connect_client(); + } break; case DISCONNECTING: if(t->isConnected()) @@ -1180,7 +1203,9 @@ TransporterRegistry::stop_clients() } void -TransporterRegistry::add_transporter_interface(const char *interf, unsigned short port) +TransporterRegistry::add_transporter_interface(NodeId remoteNodeId, + const char *interf, + unsigned short port) { DBUG_ENTER("TransporterRegistry::add_transporter_interface"); DBUG_PRINT("enter",("interface=%s, port= %d", interf, port)); @@ -1203,6 +1228,7 @@ TransporterRegistry::add_transporter_interface(const char *interf, unsigned shor } } Transporter_interface t; + t.m_remote_nodeId= remoteNodeId; t.m_service_port= port; t.m_interface= interf; m_transporter_interface.push_back(t); @@ -1328,4 +1354,9 @@ NdbOut & operator <<(NdbOut & out, SignalHeader & sh){ return out; } +Transporter* +TransporterRegistry::get_transporter(NodeId nodeId) { + return theTransporters[nodeId]; +}; + template class Vector<TransporterRegistry::Transporter_interface>; diff --git a/ndb/src/common/util/NdbSqlUtil.cpp b/ndb/src/common/util/NdbSqlUtil.cpp index 6798655a71a..9ed791d2803 100644 --- a/ndb/src/common/util/NdbSqlUtil.cpp +++ b/ndb/src/common/util/NdbSqlUtil.cpp @@ -70,7 +70,7 @@ NdbSqlUtil::char_like(const char* s1, unsigned n1, return i1 == n2 && i2 == n2; } -/** +/* * Data types. */ @@ -138,7 +138,7 @@ NdbSqlUtil::m_typeList[] = { }, { Type::Varchar, - cmpVarchar + NULL // cmpVarchar }, { Type::Binary, @@ -146,7 +146,7 @@ NdbSqlUtil::m_typeList[] = { }, { Type::Varbinary, - cmpVarbinary + NULL // cmpVarbinary }, { Type::Datetime, @@ -154,15 +154,15 @@ NdbSqlUtil::m_typeList[] = { }, { Type::Timespec, - cmpTimespec + NULL // cmpTimespec }, { Type::Blob, - cmpBlob + NULL // cmpBlob }, { Type::Text, - cmpText + NULL // cmpText } }; @@ -195,374 +195,298 @@ NdbSqlUtil::getTypeBinary(Uint32 typeId) return getType(typeId); } -// compare +/* + * Comparison functions. + */ int -NdbSqlUtil::cmpTinyint(const void* info, const Uint32* p1, const Uint32* p2, Uint32 full, Uint32 size) +NdbSqlUtil::cmpTinyint(const void* info, const void* p1, unsigned n1, const void* p2, unsigned n2, bool full) { - assert(full >= size && size > 0); - union { Uint32 p[1]; Int8 v; } u1, u2; - u1.p[0] = p1[0]; - u2.p[0] = p2[0]; - if (u1.v < u2.v) - return -1; - if (u1.v > u2.v) - return +1; - return 0; + if (n2 >= sizeof(Int8)) { + Int8 v1, v2; + memcpy(&v1, p1, sizeof(Int8)); + memcpy(&v2, p2, sizeof(Int8)); + if (v1 < v2) + return -1; + if (v1 > v2) + return +1; + return 0; + } + assert(! full); + return CmpUnknown; } int -NdbSqlUtil::cmpTinyunsigned(const void* info, const Uint32* p1, const Uint32* p2, Uint32 full, Uint32 size) +NdbSqlUtil::cmpTinyunsigned(const void* info, const void* p1, unsigned n1, const void* p2, unsigned n2, bool full) { - assert(full >= size && size > 0); - union { Uint32 p[1]; Uint8 v; } u1, u2; - u1.p[0] = p1[0]; - u2.p[0] = p2[0]; - if (u1.v < u2.v) - return -1; - if (u1.v > u2.v) - return +1; - return 0; + if (n2 >= sizeof(Uint8)) { + Uint8 v1, v2; + memcpy(&v1, p1, sizeof(Uint8)); + memcpy(&v2, p2, sizeof(Uint8)); + if (v1 < v2) + return -1; + if (v1 > v2) + return +1; + return 0; + } + assert(! full); + return CmpUnknown; } int -NdbSqlUtil::cmpSmallint(const void* info, const Uint32* p1, const Uint32* p2, Uint32 full, Uint32 size) +NdbSqlUtil::cmpSmallint(const void* info, const void* p1, unsigned n1, const void* p2, unsigned n2, bool full) { - assert(full >= size && size > 0); - union { Uint32 p[1]; Int16 v; } u1, u2; - u1.p[0] = p1[0]; - u2.p[0] = p2[0]; - if (u1.v < u2.v) - return -1; - if (u1.v > u2.v) - return +1; - return 0; + if (n2 >= sizeof(Int16)) { + Int16 v1, v2; + memcpy(&v1, p1, sizeof(Int16)); + memcpy(&v2, p2, sizeof(Int16)); + if (v1 < v2) + return -1; + if (v1 > v2) + return +1; + return 0; + } + assert(! full); + return CmpUnknown; } int -NdbSqlUtil::cmpSmallunsigned(const void* info, const Uint32* p1, const Uint32* p2, Uint32 full, Uint32 size) +NdbSqlUtil::cmpSmallunsigned(const void* info, const void* p1, unsigned n1, const void* p2, unsigned n2, bool full) { - assert(full >= size && size > 0); - union { Uint32 p[1]; Uint16 v; } u1, u2; - u1.p[0] = p1[0]; - u2.p[0] = p2[0]; - if (u1.v < u2.v) - return -1; - if (u1.v > u2.v) - return +1; - return 0; + if (n2 >= sizeof(Uint16)) { + Uint16 v1, v2; + memcpy(&v1, p1, sizeof(Uint16)); + memcpy(&v2, p2, sizeof(Uint16)); + if (v1 < v2) + return -1; + if (v1 > v2) + return +1; + return 0; + } + assert(! full); + return CmpUnknown; } int -NdbSqlUtil::cmpMediumint(const void* info, const Uint32* p1, const Uint32* p2, Uint32 full, Uint32 size) +NdbSqlUtil::cmpMediumint(const void* info, const void* p1, unsigned n1, const void* p2, unsigned n2, bool full) { - assert(full >= size && size > 0); - 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; + if (n2 >= 3) { + Int32 v1, v2; + v1 = sint3korr((const uchar*)p1); + v2 = sint3korr((const uchar*)p2); + if (v1 < v2) + return -1; + if (v1 > v2) + return +1; + return 0; + } + assert(! full); + return CmpUnknown; } int -NdbSqlUtil::cmpMediumunsigned(const void* info, const Uint32* p1, const Uint32* p2, Uint32 full, Uint32 size) +NdbSqlUtil::cmpMediumunsigned(const void* info, const void* p1, unsigned n1, const void* p2, unsigned n2, bool full) { - assert(full >= size && size > 0); - 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; + if (n2 >= 3) { + Uint32 v1, v2; + v1 = uint3korr((const uchar*)p1); + v2 = uint3korr((const uchar*)p2); + if (v1 < v2) + return -1; + if (v1 > v2) + return +1; + return 0; + } + assert(! full); + return CmpUnknown; } int -NdbSqlUtil::cmpInt(const void* info, const Uint32* p1, const Uint32* p2, Uint32 full, Uint32 size) +NdbSqlUtil::cmpInt(const void* info, const void* p1, unsigned n1, const void* p2, unsigned n2, bool full) { - assert(full >= size && size > 0); - union { Uint32 p[1]; Int32 v; } u1, u2; - u1.p[0] = p1[0]; - u2.p[0] = p2[0]; - if (u1.v < u2.v) - return -1; - if (u1.v > u2.v) - return +1; - return 0; + if (n2 >= sizeof(Int32)) { + Int32 v1, v2; + memcpy(&v1, p1, sizeof(Int32)); + memcpy(&v2, p2, sizeof(Int32)); + if (v1 < v2) + return -1; + if (v1 > v2) + return +1; + return 0; + } + assert(! full); + return CmpUnknown; } int -NdbSqlUtil::cmpUnsigned(const void* info, const Uint32* p1, const Uint32* p2, Uint32 full, Uint32 size) +NdbSqlUtil::cmpUnsigned(const void* info, const void* p1, unsigned n1, const void* p2, unsigned n2, bool full) { - assert(full >= size && size > 0); - union { Uint32 p[1]; Uint32 v; } u1, u2; - u1.v = p1[0]; - u2.v = p2[0]; - if (u1.v < u2.v) - return -1; - if (u1.v > u2.v) - return +1; - return 0; + if (n2 >= sizeof(Uint32)) { + Uint32 v1, v2; + memcpy(&v1, p1, sizeof(Uint32)); + memcpy(&v2, p2, sizeof(Uint32)); + if (v1 < v2) + return -1; + if (v1 > v2) + return +1; + return 0; + } + assert(! full); + return CmpUnknown; } int -NdbSqlUtil::cmpBigint(const void* info, const Uint32* p1, const Uint32* p2, Uint32 full, Uint32 size) +NdbSqlUtil::cmpBigint(const void* info, const void* p1, unsigned n1, const void* p2, unsigned n2, bool full) { - assert(full >= size && size > 0); - if (size >= 2) { - union { Uint32 p[2]; Int64 v; } u1, u2; - u1.p[0] = p1[0]; - u1.p[1] = p1[1]; - u2.p[0] = p2[0]; - u2.p[1] = p2[1]; - if (u1.v < u2.v) + if (n2 >= sizeof(Int64)) { + Int64 v1, v2; + memcpy(&v1, p1, sizeof(Int64)); + memcpy(&v2, p2, sizeof(Int64)); + if (v1 < v2) return -1; - if (u1.v > u2.v) + if (v1 > v2) return +1; return 0; } + assert(! full); return CmpUnknown; } int -NdbSqlUtil::cmpBigunsigned(const void* info, const Uint32* p1, const Uint32* p2, Uint32 full, Uint32 size) +NdbSqlUtil::cmpBigunsigned(const void* info, const void* p1, unsigned n1, const void* p2, unsigned n2, bool full) { - assert(full >= size && size > 0); - if (size >= 2) { - union { Uint32 p[2]; Uint64 v; } u1, u2; - u1.p[0] = p1[0]; - u1.p[1] = p1[1]; - u2.p[0] = p2[0]; - u2.p[1] = p2[1]; - if (u1.v < u2.v) + if (n2 >= sizeof(Uint64)) { + Uint64 v1, v2; + memcpy(&v1, p1, sizeof(Uint64)); + memcpy(&v2, p2, sizeof(Uint64)); + if (v1 < v2) return -1; - if (u1.v > u2.v) + if (v1 > v2) return +1; return 0; } + assert(! full); return CmpUnknown; } int -NdbSqlUtil::cmpFloat(const void* info, const Uint32* p1, const Uint32* p2, Uint32 full, Uint32 size) +NdbSqlUtil::cmpFloat(const void* info, const void* p1, unsigned n1, const void* p2, unsigned n2, bool full) { - assert(full >= size && size > 0); - union { Uint32 p[1]; float v; } u1, u2; - u1.p[0] = p1[0]; - u2.p[0] = p2[0]; - // no format check - if (u1.v < u2.v) - return -1; - if (u1.v > u2.v) - return +1; - return 0; + if (n2 >= sizeof(float)) { + float v1, v2; + memcpy(&v1, p1, sizeof(float)); + memcpy(&v2, p2, sizeof(float)); + if (v1 < v2) + return -1; + if (v1 > v2) + return +1; + return 0; + } + assert(! full); + return CmpUnknown; } int -NdbSqlUtil::cmpDouble(const void* info, const Uint32* p1, const Uint32* p2, Uint32 full, Uint32 size) +NdbSqlUtil::cmpDouble(const void* info, const void* p1, unsigned n1, const void* p2, unsigned n2, bool full) { - assert(full >= size && size > 0); - if (size >= 2) { - union { Uint32 p[2]; double v; } u1, u2; - u1.p[0] = p1[0]; - u1.p[1] = p1[1]; - u2.p[0] = p2[0]; - u2.p[1] = p2[1]; - // no format check - if (u1.v < u2.v) + if (n2 >= sizeof(double)) { + double v1, v2; + memcpy(&v1, p1, sizeof(double)); + memcpy(&v2, p2, sizeof(double)); + if (v1 < v2) return -1; - if (u1.v > u2.v) + if (v1 > v2) return +1; return 0; } + assert(! full); return CmpUnknown; } +// not used by MySQL or NDB int -NdbSqlUtil::cmpDecimal(const void* info, const Uint32* p1, const Uint32* p2, Uint32 full, Uint32 size) +NdbSqlUtil::cmpDecimal(const void* info, const void* p1, unsigned n1, const void* p2, unsigned n2, bool full) { - assert(full >= size && size > 0); - // not used by MySQL or NDB assert(false); return 0; } int -NdbSqlUtil::cmpChar(const void* info, const Uint32* p1, const Uint32* p2, Uint32 full, Uint32 size) +NdbSqlUtil::cmpChar(const void* info, const void* p1, unsigned n1, const void* p2, unsigned n2, bool full) { // collation does not work on prefix for some charsets - assert(full == size && size > 0); - /* - * Char is blank-padded to length and null-padded to word size. - */ - union { const Uint32* p; const uchar* v; } u1, u2; - u1.p = p1; - u2.p = p2; + assert(full); + const uchar* v1 = (const uchar*)p1; + const uchar* v2 = (const uchar*)p2; // not const in MySQL CHARSET_INFO* cs = (CHARSET_INFO*)(info); - // length in bytes including null padding to Uint32 - uint l1 = (full << 2); - int k = (*cs->coll->strnncollsp)(cs, u1.v, l1, u2.v, l1, 0); + // compare with space padding + int k = (*cs->coll->strnncollsp)(cs, v1, n1, v2, n2, false); return k < 0 ? -1 : k > 0 ? +1 : 0; } +// waiting for MySQL and new NDB implementation int -NdbSqlUtil::cmpVarchar(const void* info, const Uint32* p1, const Uint32* p2, Uint32 full, Uint32 size) +NdbSqlUtil::cmpVarchar(const void* info, const void* p1, unsigned n1, const void* p2, unsigned n2, bool full) { - assert(full >= size && size > 0); - /* - * Varchar is not allowed to contain a null byte and the value is - * null-padded. Therefore comparison does not need to use the length. - * - * Not used before MySQL 5.0. Format is likely to change. Handle - * only binary collation for now. - */ - union { const Uint32* p; const char* v; } u1, u2; - u1.p = p1; - u2.p = p2; - // skip length in first 2 bytes - int k = strncmp(u1.v + 2, u2.v + 2, (size << 2) - 2); - return k < 0 ? -1 : k > 0 ? +1 : full == size ? 0 : CmpUnknown; + assert(false); + return 0; } int -NdbSqlUtil::cmpBinary(const void* info, const Uint32* p1, const Uint32* p2, Uint32 full, Uint32 size) +NdbSqlUtil::cmpBinary(const void* info, const void* p1, unsigned n1, const void* p2, unsigned n2, bool full) { - assert(full >= size && size > 0); - /* - * Binary data of full length. Compare bytewise. - */ - union { const Uint32* p; const unsigned 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; + const uchar* v1 = (const uchar*)p1; + const uchar* v2 = (const uchar*)p2; + // compare as binary strings + unsigned n = (n1 <= n2 ? n1 : n2); + int k = memcmp(v1, v2, n); + if (k == 0) { + if (full) + k = (int)n1 - (int)n2; + else + k = (int)n - (int)n2; + } + return k < 0 ? -1 : k > 0 ? +1 : full ? 0 : CmpUnknown; } +// waiting for MySQL and new NDB implementation int -NdbSqlUtil::cmpVarbinary(const void* info, const Uint32* p1, const Uint32* p2, Uint32 full, Uint32 size) +NdbSqlUtil::cmpVarbinary(const void* info, const void* p1, unsigned n1, const void* p2, unsigned n2, bool full) { - assert(full >= size && size > 0); - /* - * Binary data of variable length padded with nulls. The comparison - * does not need to use the length. - * - * Not used before MySQL 5.0. Format is likely to change. - */ - union { const Uint32* p; const unsigned char* v; } u1, u2; - u1.p = p1; - u2.p = p2; - // skip 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; + assert(false); + return 0; } +// allowed but ordering is wrong before wl-1442 done int -NdbSqlUtil::cmpDatetime(const void* info, const Uint32* p1, const Uint32* p2, Uint32 full, Uint32 size) +NdbSqlUtil::cmpDatetime(const void* info, const void* p1, unsigned n1, const void* p2, unsigned n2, bool full) { - assert(full >= size && size > 0); - /* - * Datetime is CC YY MM DD hh mm ss \0 - * - * Not used via MySQL. - */ - union { const Uint32* p; const unsigned char* v; } u1, u2; - u1.p = p1; - u2.p = p2; - // no 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); - return k < 0 ? -1 : k > 0 ? +1 : 0; - } - return CmpUnknown; + return cmpBinary(info, p1, n1, p2, n2, full); } +// not used by MySQL or NDB int -NdbSqlUtil::cmpTimespec(const void* info, const Uint32* p1, const Uint32* p2, Uint32 full, Uint32 size) +NdbSqlUtil::cmpTimespec(const void* info, const void* p1, unsigned n1, const void* p2, unsigned n2, bool full) { - assert(full >= size && size > 0); - /* - * Timespec is CC YY MM DD hh mm ss \0 NN NN NN NN - * - * Not used via MySQL. - */ - union { const Uint32* p; const unsigned char* v; } u1, u2; - u1.p = p1; - u2.p = p2; - // no 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; - if (size >= 3) { - 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; + assert(false); + return 0; } +// not supported int -NdbSqlUtil::cmpBlob(const void* info, const Uint32* p1, const Uint32* p2, Uint32 full, Uint32 size) +NdbSqlUtil::cmpBlob(const void* info, const void* p1, unsigned n1, const void* p2, unsigned n2, bool full) { - assert(full >= size && size > 0); - /* - * Blob comparison is on the inline bytes (null padded). - */ - const unsigned head = NDB_BLOB_HEAD_SIZE; - // skip blob head - if (size >= head + 1) { - union { const Uint32* p; const unsigned char* v; } u1, u2; - u1.p = p1 + head; - u2.p = p2 + head; - int k = memcmp(u1.v, u2.v, (size - head) << 2); - return k < 0 ? -1 : k > 0 ? +1 : full == size ? 0 : CmpUnknown; - } - return CmpUnknown; + assert(false); + return 0; } +// not supported int -NdbSqlUtil::cmpText(const void* info, const Uint32* p1, const Uint32* p2, Uint32 full, Uint32 size) +NdbSqlUtil::cmpText(const void* info, const void* p1, unsigned n1, const void* p2, unsigned n2, bool full) { - // collation does not work on prefix for some charsets - assert(full == size && size > 0); - /* - * Text comparison is on the inline bytes (blank padded). Currently - * not supported for multi-byte charsets. - */ - const unsigned head = NDB_BLOB_HEAD_SIZE; - // skip blob head - if (size >= head + 1) { - union { const Uint32* p; const uchar* v; } u1, u2; - u1.p = p1 + head; - u2.p = p2 + head; - // not const in MySQL - CHARSET_INFO* cs = (CHARSET_INFO*)(info); - // length in bytes including null padding to Uint32 - uint l1 = (full << 2); - int k = (*cs->coll->strnncollsp)(cs, u1.v, l1, u2.v, l1,0); - return k < 0 ? -1 : k > 0 ? +1 : 0; - } - return CmpUnknown; + assert(false); + return 0; } // check charset @@ -572,8 +496,6 @@ NdbSqlUtil::usable_in_pk(Uint32 typeId, const void* info) { const Type& type = getType(typeId); switch (type.m_typeId) { - case Type::Undefined: - break; case Type::Char: { const CHARSET_INFO *cs = (const CHARSET_INFO*)info; @@ -582,11 +504,12 @@ NdbSqlUtil::usable_in_pk(Uint32 typeId, const void* info) cs->cset != 0 && cs->coll != 0 && cs->coll->strnxfrm != 0 && - cs->strxfrm_multiply <= 1; // current limitation + cs->strxfrm_multiply <= MAX_XFRM_MULTIPLY; } break; + case Type::Undefined: case Type::Varchar: - return true; // Varchar not used via MySQL + case Type::Varbinary: case Type::Blob: case Type::Text: break; @@ -606,9 +529,9 @@ bool NdbSqlUtil::usable_in_ordered_index(Uint32 typeId, const void* info) { const Type& type = getType(typeId); + if (type.m_cmp == NULL) + return false; switch (type.m_typeId) { - case Type::Undefined: - break; case Type::Char: { const CHARSET_INFO *cs = (const CHARSET_INFO*)info; @@ -618,92 +541,17 @@ NdbSqlUtil::usable_in_ordered_index(Uint32 typeId, const void* info) cs->coll != 0 && cs->coll->strnxfrm != 0 && cs->coll->strnncollsp != 0 && - cs->strxfrm_multiply <= 1; // current limitation + cs->strxfrm_multiply <= MAX_XFRM_MULTIPLY; } break; + case Type::Undefined: case Type::Varchar: - return true; // Varchar not used via MySQL + case Type::Varbinary: + case Type::Blob: case Type::Text: - { - const CHARSET_INFO *cs = (const CHARSET_INFO*)info; - return - cs != 0 && - cs->mbmaxlen == 1 && // extra limitation - cs->cset != 0 && - cs->coll != 0 && - cs->coll->strnxfrm != 0 && - cs->coll->strnncollsp != 0 && - cs->strxfrm_multiply <= 1; // current limitation - } break; default: return true; } return false; } - -#ifdef NDB_SQL_UTIL_TEST - -#include <NdbTick.h> -#include <NdbOut.hpp> - -struct Testcase { - int op; // 1=compare 2=like - int res; - const char* s1; - const char* s2; - int pad; -}; -const Testcase testcase[] = { - { 2, 1, "abc", "abc", 0 }, - { 2, 1, "abc", "abc%", 0 }, - { 2, 1, "abcdef", "abc%", 0 }, - { 2, 1, "abcdefabcdefabcdef", "abc%", 0 }, - { 2, 1, "abcdefabcdefabcdef", "abc%f", 0 }, - { 2, 0, "abcdefabcdefabcdef", "abc%z", 0 }, - { 2, 1, "abcdefabcdefabcdef", "%f", 0 }, - { 2, 1, "abcdef", "a%b%c%d%e%f", 0 }, - { 0, 0, 0, 0 } -}; - -int -main(int argc, char** argv) -{ - ndb_init(); // for charsets - unsigned count = argc > 1 ? atoi(argv[1]) : 1000000; - ndbout_c("count = %u", count); - assert(count != 0); - for (const Testcase* t = testcase; t->s1 != 0; t++) { - ndbout_c("%d = '%s' %s '%s' pad=%d", - t->res, t->s1, t->op == 1 ? "comp" : "like", t->s2); - NDB_TICKS x1 = NdbTick_CurrentMillisecond(); - unsigned n1 = strlen(t->s1); - unsigned n2 = strlen(t->s2); - for (unsigned i = 0; i < count; i++) { - if (t->op == 1) { - int res = NdbSqlUtil::char_compare(t->s1, n1, t->s2, n2, t->pad); - assert(res == t->res); - continue; - } - if (t->op == 2) { - int res = NdbSqlUtil::char_like(t->s1, n1, t->s2, n2, t->pad); - assert(res == t->res); - continue; - } - assert(false); - } - NDB_TICKS x2 = NdbTick_CurrentMillisecond(); - if (x2 < x1) - x2 = x1; - double usec = 1000000.0 * double(x2 - x1) / double(count); - ndbout_c("time %.0f usec per call", usec); - } - // quick check - for (unsigned i = 0; i < sizeof(m_typeList) / sizeof(m_typeList[0]); i++) { - const NdbSqlUtil::Type& t = m_typeList[i]; - assert(t.m_typeId == i); - } - return 0; -} - -#endif diff --git a/ndb/src/common/util/version.c b/ndb/src/common/util/version.c index 0d254533708..dfbb1e4a2e6 100644 --- a/ndb/src/common/util/version.c +++ b/ndb/src/common/util/version.c @@ -90,6 +90,7 @@ void ndbSetOwnVersion() {} #ifndef TEST_VERSION struct NdbUpGradeCompatible ndbCompatibleTable_full[] = { + { MAKE_VERSION(5,0,3), MAKE_VERSION(5,0,2), UG_Exact }, { MAKE_VERSION(4,1,9), MAKE_VERSION(4,1,8), UG_Exact }, { MAKE_VERSION(3,5,2), MAKE_VERSION(3,5,1), UG_Exact }, { 0, 0, UG_Null } diff --git a/ndb/src/kernel/blocks/dbacc/Dbacc.hpp b/ndb/src/kernel/blocks/dbacc/Dbacc.hpp index af8ee136934..6a65da5bb6a 100644 --- a/ndb/src/kernel/blocks/dbacc/Dbacc.hpp +++ b/ndb/src/kernel/blocks/dbacc/Dbacc.hpp @@ -607,8 +607,7 @@ struct Fragmentrec { //----------------------------------------------------------------------------- // elementLength: Length of element in bucket and overflow pages -// keyLength: Length of key (== 0 if long key or variable key length) -// wl-2066 always Length of key +// keyLength: Length of key //----------------------------------------------------------------------------- Uint8 elementLength; Uint16 keyLength; @@ -637,6 +636,11 @@ struct Fragmentrec { //----------------------------------------------------------------------------- Uint8 nodetype; Uint8 stopQueOp; + +//----------------------------------------------------------------------------- +// flag to avoid accessing table record if no char attributes +//----------------------------------------------------------------------------- + Uint8 hasCharAttr; }; typedef Ptr<Fragmentrec> FragmentrecPtr; @@ -719,6 +723,7 @@ struct Operationrec { State transactionstate; Uint16 elementContainer; Uint16 tupkeylen; + Uint32 xfrmtupkeylen; Uint32 userblockref; Uint32 scanBits; Uint8 elementIsDisappeared; @@ -846,6 +851,13 @@ struct Tabrec { Uint32 fragptrholder[MAX_FRAG_PER_NODE]; Uint32 tabUserPtr; BlockReference tabUserRef; + + Uint8 noOfKeyAttr; + Uint8 hasCharAttr; + struct KeyAttr { + Uint32 attributeDescriptor; + CHARSET_INFO* charsetInfo; + } keyAttr[MAX_ATTRIBUTES_IN_INDEX]; }; typedef Ptr<Tabrec> TabrecPtr; @@ -891,6 +903,7 @@ private: void execACCKEYREQ(Signal* signal); void execACCSEIZEREQ(Signal* signal); void execACCFRAGREQ(Signal* signal); + void execTC_SCHVERREQ(Signal* signal); void execACC_SRREQ(Signal* signal); void execNEXT_SCANREQ(Signal* signal); void execACC_ABORTREQ(Signal* signal); @@ -1016,7 +1029,7 @@ private: void increaselistcont(Signal* signal); void seizeLeftlist(Signal* signal); void seizeRightlist(Signal* signal); - void readTablePk(Uint32 localkey1); + Uint32 readTablePk(Uint32 localkey1); void getElement(Signal* signal); void getdirindex(Signal* signal); void commitdelete(Signal* signal, bool systemRestart); @@ -1123,6 +1136,8 @@ private: void lcp_write_op_to_undolog(Signal* signal); void reenable_expand_after_redo_log_exection_complete(Signal*); + // charsets + void xfrmKeyData(Signal* signal); // Initialisation void initData(); diff --git a/ndb/src/kernel/blocks/dbacc/DbaccInit.cpp b/ndb/src/kernel/blocks/dbacc/DbaccInit.cpp index 64647f2e41f..94782e13e00 100644 --- a/ndb/src/kernel/blocks/dbacc/DbaccInit.cpp +++ b/ndb/src/kernel/blocks/dbacc/DbaccInit.cpp @@ -179,6 +179,7 @@ Dbacc::Dbacc(const class Configuration & conf): addRecSignal(GSN_ACCKEYREQ, &Dbacc::execACCKEYREQ); addRecSignal(GSN_ACCSEIZEREQ, &Dbacc::execACCSEIZEREQ); addRecSignal(GSN_ACCFRAGREQ, &Dbacc::execACCFRAGREQ); + addRecSignal(GSN_TC_SCHVERREQ, &Dbacc::execTC_SCHVERREQ); addRecSignal(GSN_ACC_SRREQ, &Dbacc::execACC_SRREQ); addRecSignal(GSN_NEXT_SCANREQ, &Dbacc::execNEXT_SCANREQ); addRecSignal(GSN_ACC_ABORTREQ, &Dbacc::execACC_ABORTREQ); diff --git a/ndb/src/kernel/blocks/dbacc/DbaccMain.cpp b/ndb/src/kernel/blocks/dbacc/DbaccMain.cpp index 1a5e22ac70a..0db74a0b709 100644 --- a/ndb/src/kernel/blocks/dbacc/DbaccMain.cpp +++ b/ndb/src/kernel/blocks/dbacc/DbaccMain.cpp @@ -16,6 +16,7 @@ #define DBACC_C #include "Dbacc.hpp" +#include <my_sys.h> #include <AttributeHeader.hpp> #include <signaldata/AccFrag.hpp> @@ -27,6 +28,7 @@ #include <signaldata/FsRemoveReq.hpp> #include <signaldata/DropTab.hpp> #include <signaldata/DumpStateOrd.hpp> +#include <SectionReader.hpp> // TO_DO_RONM is a label for comments on what needs to be improved in future versions // when more time is given. @@ -1033,6 +1035,12 @@ void Dbacc::initialiseTableRec(Signal* signal) tabptr.p->fragholder[i] = RNIL; tabptr.p->fragptrholder[i] = RNIL; }//for + tabptr.p->noOfKeyAttr = 0; + tabptr.p->hasCharAttr = 0; + for (Uint32 k = 0; k < MAX_ATTRIBUTES_IN_INDEX; k++) { + tabptr.p->keyAttr[k].attributeDescriptor = 0; + tabptr.p->keyAttr[k].charsetInfo = 0; + } }//for }//Dbacc::initialiseTableRec() @@ -1080,7 +1088,7 @@ void Dbacc::execACCFRAGREQ(Signal* signal) // config mismatch - do not crash if release compiled if (tabptr.i >= ctablesize) { jam(); - addFragRefuse(signal, 800); + addFragRefuse(signal, 640); return; } #endif @@ -1188,6 +1196,66 @@ void Dbacc::addFragRefuse(Signal* signal, Uint32 errorCode) }//Dbacc::addFragRefuseEarly() void +Dbacc::execTC_SCHVERREQ(Signal* signal) +{ + jamEntry(); + if (! assembleFragments(signal)) { + jam(); + return; + } + tabptr.i = signal->theData[0]; + ptrCheckGuard(tabptr, ctablesize, tabrec); + Uint32 noOfKeyAttr = signal->theData[6]; + ndbrequire(noOfKeyAttr <= MAX_ATTRIBUTES_IN_INDEX); + Uint32 hasCharAttr = 0; + + SegmentedSectionPtr s0Ptr; + signal->getSection(s0Ptr, 0); + SectionReader r0(s0Ptr, getSectionSegmentPool()); + Uint32 i = 0; + while (i < noOfKeyAttr) { + jam(); + Uint32 attributeDescriptor = ~0; + Uint32 csNumber = ~0; + if (! r0.getWord(&attributeDescriptor) || + ! r0.getWord(&csNumber)) { + jam(); + break; + } + CHARSET_INFO* cs = 0; + if (csNumber != 0) { + cs = all_charsets[csNumber]; + ndbrequire(cs != 0); + hasCharAttr = 1; + } + tabptr.p->keyAttr[i].attributeDescriptor = attributeDescriptor; + tabptr.p->keyAttr[i].charsetInfo = cs; + i++; + } + ndbrequire(i == noOfKeyAttr); + releaseSections(signal); + + tabptr.p->noOfKeyAttr = noOfKeyAttr; + tabptr.p->hasCharAttr = hasCharAttr; + + // copy char attr flag to each fragment + for (Uint32 i1 = 0; i1 < MAX_FRAG_PER_NODE; i1++) { + jam(); + if (tabptr.p->fragptrholder[i1] != RNIL) { + rootfragrecptr.i = tabptr.p->fragptrholder[i1]; + ptrCheckGuard(rootfragrecptr, crootfragmentsize, rootfragmentrec); + for (Uint32 i2 = 0; i2 < 2; i2++) { + fragrecptr.i = rootfragrecptr.p->fragmentptr[i2]; + ptrCheckGuard(fragrecptr, cfragmentsize, fragmentrec); + fragrecptr.p->hasCharAttr = hasCharAttr; + } + } + } + + // no reply to DICT +} + +void Dbacc::execDROP_TAB_REQ(Signal* signal){ jamEntry(); DropTabReq* req = (DropTabReq*)signal->getDataPtr(); @@ -1550,6 +1618,7 @@ void Dbacc::initOpRec(Signal* signal) operationRecPtr.p->hashValue = signal->theData[3]; operationRecPtr.p->tupkeylen = signal->theData[4]; + operationRecPtr.p->xfrmtupkeylen = signal->theData[4]; operationRecPtr.p->transId1 = signal->theData[5]; operationRecPtr.p->transId2 = signal->theData[6]; operationRecPtr.p->transactionstate = ACTIVE; @@ -1664,6 +1733,10 @@ void Dbacc::execACCKEYREQ(Signal* signal) ndbrequire(operationRecPtr.p->transactionstate == IDLE); initOpRec(signal); + // normalize key if any char attr + if (! operationRecPtr.p->isAccLockReq && fragrecptr.p->hasCharAttr) + xfrmKeyData(signal); + /*---------------------------------------------------------------*/ /* */ /* WE WILL USE THE HASH VALUE TO LOOK UP THE PROPER MEMORY */ @@ -1758,6 +1831,54 @@ void Dbacc::execACCKEYREQ(Signal* signal) return; }//Dbacc::execACCKEYREQ() +void +Dbacc::xfrmKeyData(Signal* signal) +{ + tabptr.i = fragrecptr.p->myTableId; + ptrCheckGuard(tabptr, ctablesize, tabrec); + + Uint32 dst[1024 * MAX_XFRM_MULTIPLY]; + Uint32 dstSize = (sizeof(dst) >> 2); + Uint32* src = &signal->theData[7]; + const Uint32 noOfKeyAttr = tabptr.p->noOfKeyAttr; + Uint32 dstPos = 0; + Uint32 srcPos = 0; + Uint32 i = 0; + + while (i < noOfKeyAttr) { + const Tabrec::KeyAttr& keyAttr = tabptr.p->keyAttr[i]; + + Uint32 srcBytes = AttributeDescriptor::getSizeInBytes(keyAttr.attributeDescriptor); + Uint32 srcWords = (srcBytes + 3) / 4; + Uint32 dstWords = ~0; + uchar* dstPtr = (uchar*)&dst[dstPos]; + const uchar* srcPtr = (const uchar*)&src[srcPos]; + CHARSET_INFO* cs = keyAttr.charsetInfo; + + if (cs == 0) { + jam(); + memcpy(dstPtr, srcPtr, srcWords << 2); + dstWords = srcWords; + } else { + jam(); + Uint32 xmul = cs->strxfrm_multiply; + if (xmul == 0) + xmul = 1; + Uint32 dstLen = xmul * srcBytes; + ndbrequire(dstLen <= ((dstSize - dstPos) << 2)); + uint n = (*cs->coll->strnxfrm)(cs, dstPtr, dstLen, srcPtr, srcBytes); + while ((n & 3) != 0) + dstPtr[n++] = 0; + dstWords = (n >> 2); + } + dstPos += dstWords; + srcPos += srcWords; + i++; + } + memcpy(src, dst, dstPos << 2); + operationRecPtr.p->xfrmtupkeylen = dstPos; +} + void Dbacc::accIsLockedLab(Signal* signal) { ndbrequire(csystemRestart == ZFALSE); @@ -1848,6 +1969,7 @@ void Dbacc::insertelementLab(Signal* signal) }//if }//if if (fragrecptr.p->keyLength != operationRecPtr.p->tupkeylen) { + // historical ndbrequire(fragrecptr.p->keyLength == 0); }//if @@ -3251,7 +3373,7 @@ void Dbacc::getdirindex(Signal* signal) ptrCheckGuard(gdiPageptr, cpagesize, page8); }//Dbacc::getdirindex() -void +Uint32 Dbacc::readTablePk(Uint32 localkey1) { Uint32 tableId = fragrecptr.p->myTableId; @@ -3259,10 +3381,11 @@ Dbacc::readTablePk(Uint32 localkey1) Uint32 fragPageId = localkey1 >> MAX_TUPLES_BITS; Uint32 pageIndex = localkey1 & ((1 << MAX_TUPLES_BITS ) - 1); #ifdef VM_TRACE - memset(ckeys, 0x1f, fragrecptr.p->keyLength << 2); + memset(ckeys, 0x1f, (fragrecptr.p->keyLength * MAX_XFRM_MULTIPLY) << 2); #endif - int ret = c_tup->accReadPk(tableId, fragId, fragPageId, pageIndex, ckeys); - ndbrequire(ret == fragrecptr.p->keyLength); + int ret = c_tup->accReadPk(tableId, fragId, fragPageId, pageIndex, ckeys, true); + ndbrequire(ret > 0); + return ret; } /* --------------------------------------------------------------------------------- */ @@ -3306,7 +3429,6 @@ void Dbacc::getElement(Signal* signal) Uint32 tgeNextptrtype; register Uint32 tgeKeyptr; register Uint32 tgeRemLen; - register Uint32 tgeCompareLen; register Uint32 TelemLen = fragrecptr.p->elementLength; register Uint32* Tkeydata = (Uint32*)&signal->theData[7]; @@ -3314,7 +3436,6 @@ void Dbacc::getElement(Signal* signal) tgePageindex = tgdiPageindex; gePageptr = gdiPageptr; tgeResult = ZFALSE; - tgeCompareLen = fragrecptr.p->keyLength; /* * The value seached is * - table key for ACCKEYREQ, stored in TUP @@ -3381,12 +3502,15 @@ void Dbacc::getElement(Signal* signal) Uint32 localkey2 = 0; bool found; if (! searchLocalKey) { - readTablePk(localkey1); - found = (memcmp(Tkeydata, ckeys, fragrecptr.p->keyLength << 2) == 0); + Uint32 len = readTablePk(localkey1); + found = (len == operationRecPtr.p->xfrmtupkeylen) && + (memcmp(Tkeydata, ckeys, len << 2) == 0); } else { + jam(); found = (localkey1 == Tkeydata[0]); } if (found) { + jam(); tgeLocked = ElementHeader::getLocked(tgeElementHeader); tgeResult = ZTRUE; operationRecPtr.p->localdata[0] = localkey1; @@ -7731,6 +7855,7 @@ void Dbacc::initFragGeneral(FragmentrecPtr regFragPtr) regFragPtr.p->activeDataPage = 0; regFragPtr.p->createLcp = ZFALSE; regFragPtr.p->stopQueOp = ZFALSE; + regFragPtr.p->hasCharAttr = ZFALSE; regFragPtr.p->nextAllocPage = 0; regFragPtr.p->nrWaitWriteUndoExit = 0; regFragPtr.p->lastUndoIsStored = ZFALSE; @@ -8680,6 +8805,7 @@ void Dbacc::srDoUndoLab(Signal* signal) const Uint32 tkeylen = undopageptr.p->undoword[tmpindex]; tmpindex++; operationRecPtr.p->tupkeylen = tkeylen; + operationRecPtr.p->xfrmtupkeylen = 0; // not used operationRecPtr.p->fragptr = fragrecptr.i; ndbrequire(fragrecptr.p->keyLength != 0 && @@ -9750,6 +9876,7 @@ void Dbacc::initScanOpRec(Signal* signal) arrGuard(tisoLocalPtr, 2048); operationRecPtr.p->keydata[0] = isoPageptr.p->word32[tisoLocalPtr]; operationRecPtr.p->tupkeylen = fragrecptr.p->keyLength; + operationRecPtr.p->xfrmtupkeylen = 0; // not used }//Dbacc::initScanOpRec() /* --------------------------------------------------------------------------------- */ diff --git a/ndb/src/kernel/blocks/dbdict/Dbdict.cpp b/ndb/src/kernel/blocks/dbdict/Dbdict.cpp index 48d71b12ddf..96995df44d5 100644 --- a/ndb/src/kernel/blocks/dbdict/Dbdict.cpp +++ b/ndb/src/kernel/blocks/dbdict/Dbdict.cpp @@ -256,7 +256,6 @@ Dbdict::packTableIntoPagesImpl(SimpleProperties::Writer & w, w.add(DictTabInfo::MaxLoadFactor, tablePtr.p->maxLoadFactor); w.add(DictTabInfo::TableKValue, tablePtr.p->kValue); w.add(DictTabInfo::FragmentTypeVal, tablePtr.p->fragmentType); - w.add(DictTabInfo::FragmentKeyTypeVal, tablePtr.p->fragmentKeyType); w.add(DictTabInfo::TableTypeVal, tablePtr.p->tableType); w.add(DictTabInfo::FragmentCount, tablePtr.p->fragmentCount); @@ -289,18 +288,14 @@ Dbdict::packTableIntoPagesImpl(SimpleProperties::Writer & w, const Uint32 attrSize = AttributeDescriptor::getSize(desc); const Uint32 arraySize = AttributeDescriptor::getArraySize(desc); const Uint32 nullable = AttributeDescriptor::getNullable(desc); - const Uint32 DGroup = AttributeDescriptor::getDGroup(desc); const Uint32 DKey = AttributeDescriptor::getDKey(desc); - const Uint32 attrStoredInd = AttributeDescriptor::getStoredInTup(desc); - w.add(DictTabInfo::AttributeType, attrType); + // AttributeType deprecated w.add(DictTabInfo::AttributeSize, attrSize); w.add(DictTabInfo::AttributeArraySize, arraySize); w.add(DictTabInfo::AttributeNullableFlag, nullable); - w.add(DictTabInfo::AttributeDGroup, DGroup); w.add(DictTabInfo::AttributeDKey, DKey); - w.add(DictTabInfo::AttributeStoredInd, attrStoredInd); - w.add(DictTabInfo::AttributeExtType, attrPtr.p->extType); + w.add(DictTabInfo::AttributeExtType, attrType); w.add(DictTabInfo::AttributeExtPrecision, attrPtr.p->extPrecision); w.add(DictTabInfo::AttributeExtScale, attrPtr.p->extScale); w.add(DictTabInfo::AttributeExtLength, attrPtr.p->extLength); @@ -1340,10 +1335,8 @@ void Dbdict::initialiseTableRecord(TableRecordPtr tablePtr) tablePtr.p->tableVersion = (Uint32)-1; tablePtr.p->tabState = TableRecord::NOT_DEFINED; tablePtr.p->tabReturnState = TableRecord::TRS_IDLE; - tablePtr.p->storageType = DictTabInfo::MainMemory; tablePtr.p->myConnect = RNIL; tablePtr.p->fragmentType = DictTabInfo::AllNodesSmallTable; - tablePtr.p->fragmentKeyType = DictTabInfo::PrimaryKey; memset(tablePtr.p->tableName, 0, sizeof(tablePtr.p->tableName)); tablePtr.p->gciTableCreated = 0; tablePtr.p->noOfAttributes = ZNIL; @@ -4105,7 +4098,7 @@ Dbdict::execADD_FRAGREQ(Signal* signal) { req->lh3DistrBits = 0; //lhDistrBits; req->lh3PageBits = 0; //lhPageBits; req->noOfAttributes = tabPtr.p->noOfAttributes; - req->noOfNullAttributes = tabPtr.p->noOfNullAttr; + req->noOfNullAttributes = tabPtr.p->noOfNullBits; req->noOfPagesToPreAllocate = 0; req->schemaVersion = tabPtr.p->tableVersion; Uint32 keyLen = tabPtr.p->tupKeyLength; @@ -4176,7 +4169,7 @@ Dbdict::sendLQHADDATTRREQ(Signal* signal, LqhAddAttrReq::Entry& entry = req->attributes[i]; entry.attrId = attrPtr.p->attributeId; entry.attrDescriptor = attrPtr.p->attributeDescriptor; - entry.extTypeInfo = attrPtr.p->extType; + entry.extTypeInfo = 0; // charset number passed to TUP, TUX in upper half entry.extTypeInfo |= (attrPtr.p->extPrecision & ~0xFFFF); if (tabPtr.p->isIndex()) { @@ -4318,7 +4311,28 @@ Dbdict::execTAB_COMMITCONF(Signal* signal){ signal->theData[3] = reference(); signal->theData[4] = (Uint32)tabPtr.p->tableType; signal->theData[5] = createTabPtr.p->key; - sendSignal(DBTC_REF, GSN_TC_SCHVERREQ, signal, 6, JBB); + signal->theData[6] = (Uint32)tabPtr.p->noOfPrimkey; + + Uint32 buf[2 * MAX_ATTRIBUTES_IN_INDEX]; + Uint32 sz = 0; + Uint32 tAttr = tabPtr.p->firstAttribute; + while (tAttr != RNIL) { + jam(); + AttributeRecord* aRec = c_attributeRecordPool.getPtr(tAttr); + if (aRec->tupleKey) { + buf[sz++] = aRec->attributeDescriptor; + buf[sz++] = (aRec->extPrecision >> 16); // charset number + } + tAttr = aRec->nextAttrInTable; + } + ndbrequire(sz == 2 * tabPtr.p->noOfPrimkey); + + LinearSectionPtr lsPtr[3]; + lsPtr[0].p = buf; + lsPtr[0].sz = sz; + // note: ACC does not reply + sendSignal(DBACC_REF, GSN_TC_SCHVERREQ, signal, 7, JBB, lsPtr, 1); + sendSignal(DBTC_REF, GSN_TC_SCHVERREQ, signal, 7, JBB, lsPtr, 1); return; } @@ -4677,7 +4691,6 @@ void Dbdict::handleTabInfoInit(SimpleProperties::Reader & it, tablePtr.p->minLoadFactor = tableDesc.MinLoadFactor; tablePtr.p->maxLoadFactor = tableDesc.MaxLoadFactor; tablePtr.p->fragmentType = (DictTabInfo::FragmentType)tableDesc.FragmentType; - tablePtr.p->fragmentKeyType = (DictTabInfo::FragmentKeyType)tableDesc.FragmentKeyType; tablePtr.p->tableType = (DictTabInfo::TableType)tableDesc.TableType; tablePtr.p->kValue = tableDesc.TableKValue; tablePtr.p->fragmentCount = tableDesc.FragmentCount; @@ -4726,6 +4739,7 @@ void Dbdict::handleTabInfo(SimpleProperties::Reader & it, Uint32 keyLength = 0; Uint32 attrCount = tablePtr.p->noOfAttributes; Uint32 nullCount = 0; + Uint32 nullBits = 0; Uint32 noOfCharsets = 0; Uint16 charsets[128]; Uint32 recordLength = 0; @@ -4778,19 +4792,24 @@ void Dbdict::handleTabInfo(SimpleProperties::Reader & it, attrPtr.p->attributeId = attrDesc.AttributeId; attrPtr.p->tupleKey = (keyCount + 1) * attrDesc.AttributeKeyFlag; - attrPtr.p->extType = attrDesc.AttributeExtType; attrPtr.p->extPrecision = attrDesc.AttributeExtPrecision; attrPtr.p->extScale = attrDesc.AttributeExtScale; attrPtr.p->extLength = attrDesc.AttributeExtLength; // charset in upper half of precision unsigned csNumber = (attrPtr.p->extPrecision >> 16); if (csNumber != 0) { + /* + * A new charset is first accessed here on this node. + * TODO use separate thread (e.g. via NDBFS) if need to load from file + */ CHARSET_INFO* cs = get_charset(csNumber, MYF(0)); if (cs == NULL) { parseP->errorCode = CreateTableRef::InvalidCharset; parseP->errorLine = __LINE__; return; } + // XXX should be done somewhere in mysql + all_charsets[cs->number] = cs; unsigned i = 0; while (i < noOfCharsets) { if (charsets[i] == csNumber) @@ -4823,15 +4842,12 @@ void Dbdict::handleTabInfo(SimpleProperties::Reader & it, } Uint32 desc = 0; - AttributeDescriptor::setType(desc, attrDesc.AttributeType); + AttributeDescriptor::setType(desc, attrDesc.AttributeExtType); AttributeDescriptor::setSize(desc, attrDesc.AttributeSize); AttributeDescriptor::setArray(desc, attrDesc.AttributeArraySize); AttributeDescriptor::setNullable(desc, attrDesc.AttributeNullableFlag); - AttributeDescriptor::setDGroup(desc, attrDesc.AttributeDGroup); AttributeDescriptor::setDKey(desc, attrDesc.AttributeDKey); AttributeDescriptor::setPrimaryKey(desc, attrDesc.AttributeKeyFlag); - - AttributeDescriptor::setStoredInTup(desc, attrDesc.AttributeStoredInd); attrPtr.p->attributeDescriptor = desc; attrPtr.p->autoIncrement = attrDesc.AttributeAutoIncrement; strcpy(attrPtr.p->defaultValue, attrDesc.AttributeDefaultValue); @@ -4851,9 +4867,18 @@ void Dbdict::handleTabInfo(SimpleProperties::Reader & it, else { sz = 0; - nullCount += attrDesc.AttributeArraySize; + nullBits += attrDesc.AttributeArraySize; } - + + if(attrDesc.AttributeArraySize == 0) + { + parseP->errorCode = CreateTableRef::InvalidArraySize; + parseP->status = status; + parseP->errorKey = it.getKey(); + parseP->errorLine = __LINE__; + return; + } + recordLength += sz; if(attrDesc.AttributeKeyFlag){ keyLength += sz; @@ -4881,6 +4906,7 @@ void Dbdict::handleTabInfo(SimpleProperties::Reader & it, tablePtr.p->noOfNullAttr = nullCount; tablePtr.p->noOfCharsets = noOfCharsets; tablePtr.p->tupKeyLength = keyLength; + tablePtr.p->noOfNullBits = nullCount + nullBits; tabRequire(recordLength<= MAX_TUPLE_SIZE_IN_WORDS, CreateTableRef::RecordTooBig); @@ -6379,6 +6405,7 @@ Dbdict::createIndex_toCreateTable(Signal* signal, OpCreateIndexPtr opPtr) jam(); const Uint32 a = aRec->attributeDescriptor; bool isNullable = AttributeDescriptor::getNullable(a); + Uint32 attrType = AttributeDescriptor::getType(a); w.add(DictTabInfo::AttributeName, aRec->attributeName); w.add(DictTabInfo::AttributeId, k); if (indexPtr.p->isHashIndex()) { @@ -6389,9 +6416,7 @@ Dbdict::createIndex_toCreateTable(Signal* signal, OpCreateIndexPtr opPtr) w.add(DictTabInfo::AttributeKeyFlag, (Uint32)false); w.add(DictTabInfo::AttributeNullableFlag, (Uint32)isNullable); } - w.add(DictTabInfo::AttributeStoredInd, (Uint32)DictTabInfo::Stored); - // ext type overrides - w.add(DictTabInfo::AttributeExtType, aRec->extType); + w.add(DictTabInfo::AttributeExtType, attrType); w.add(DictTabInfo::AttributeExtPrecision, aRec->extPrecision); w.add(DictTabInfo::AttributeExtScale, aRec->extScale); w.add(DictTabInfo::AttributeExtLength, aRec->extLength); @@ -6404,9 +6429,7 @@ Dbdict::createIndex_toCreateTable(Signal* signal, OpCreateIndexPtr opPtr) w.add(DictTabInfo::AttributeName, "NDB$PK"); w.add(DictTabInfo::AttributeId, opPtr.p->m_attrList.sz); w.add(DictTabInfo::AttributeKeyFlag, (Uint32)false); - w.add(DictTabInfo::AttributeStoredInd, (Uint32)DictTabInfo::Stored); w.add(DictTabInfo::AttributeNullableFlag, (Uint32)false); - // ext type overrides w.add(DictTabInfo::AttributeExtType, (Uint32)DictTabInfo::ExtUnsigned); w.add(DictTabInfo::AttributeExtLength, tablePtr.p->tupKeyLength); w.add(DictTabInfo::AttributeEnd, (Uint32)true); @@ -6417,9 +6440,7 @@ Dbdict::createIndex_toCreateTable(Signal* signal, OpCreateIndexPtr opPtr) w.add(DictTabInfo::AttributeName, "NDB$TNODE"); w.add(DictTabInfo::AttributeId, opPtr.p->m_attrList.sz); w.add(DictTabInfo::AttributeKeyFlag, (Uint32)true); - w.add(DictTabInfo::AttributeStoredInd, (Uint32)DictTabInfo::Stored); w.add(DictTabInfo::AttributeNullableFlag, (Uint32)false); - // ext type overrides w.add(DictTabInfo::AttributeExtType, (Uint32)DictTabInfo::ExtUnsigned); w.add(DictTabInfo::AttributeExtLength, indexPtr.p->tupKeyLength); w.add(DictTabInfo::AttributeEnd, (Uint32)true); diff --git a/ndb/src/kernel/blocks/dbdict/Dbdict.hpp b/ndb/src/kernel/blocks/dbdict/Dbdict.hpp index 5fc4742e829..622da5d45fd 100644 --- a/ndb/src/kernel/blocks/dbdict/Dbdict.hpp +++ b/ndb/src/kernel/blocks/dbdict/Dbdict.hpp @@ -213,7 +213,9 @@ public: IL_CREATED_TC = 1 << 0 // created in TC }; Uint32 indexLocal; - + + Uint32 noOfNullBits; + inline bool equal(TableRecord & rec) const { return strcmp(tableName, rec.tableName) == 0; } diff --git a/ndb/src/kernel/blocks/dblqh/Dblqh.hpp b/ndb/src/kernel/blocks/dblqh/Dblqh.hpp index ad19fc917e0..e7debe1f978 100644 --- a/ndb/src/kernel/blocks/dblqh/Dblqh.hpp +++ b/ndb/src/kernel/blocks/dblqh/Dblqh.hpp @@ -572,6 +572,7 @@ public: Uint8 scanLockMode; Uint8 readCommitted; Uint8 rangeScan; + Uint8 descending; Uint8 scanTcWaiting; Uint8 scanKeyinfoFlag; Uint8 m_last_row; @@ -2008,8 +2009,10 @@ public: BlockReference tcTuxBlockref; BlockReference tcTupBlockref; Uint32 commitAckMarker; - UintR noFiredTriggers; - + union { + Uint32 m_scan_curr_range_no; + UintR noFiredTriggers; + }; Uint16 errorCode; Uint16 logStartPageIndex; Uint16 logStartPageNo; diff --git a/ndb/src/kernel/blocks/dblqh/DblqhMain.cpp b/ndb/src/kernel/blocks/dblqh/DblqhMain.cpp index 2b531ede3d1..11075438fb1 100644 --- a/ndb/src/kernel/blocks/dblqh/DblqhMain.cpp +++ b/ndb/src/kernel/blocks/dblqh/DblqhMain.cpp @@ -2619,12 +2619,20 @@ Dblqh::execREAD_PSUEDO_REQ(Signal* signal){ regTcPtr.i = signal->theData[0]; ptrCheckGuard(regTcPtr, ctcConnectrecFileSize, tcConnectionrec); - FragrecordPtr regFragptr; - regFragptr.i = regTcPtr.p->fragmentptr; - ptrCheckGuard(regFragptr, cfragrecFileSize, fragrecord); - - signal->theData[0] = regFragptr.p->accFragptr[regTcPtr.p->localFragptr]; - EXECUTE_DIRECT(DBACC, GSN_READ_PSUEDO_REQ, signal, 2); + if(signal->theData[1] != AttributeHeader::RANGE_NO) + { + jam(); + FragrecordPtr regFragptr; + regFragptr.i = regTcPtr.p->fragmentptr; + ptrCheckGuard(regFragptr, cfragrecFileSize, fragrecord); + + signal->theData[0] = regFragptr.p->accFragptr[regTcPtr.p->localFragptr]; + EXECUTE_DIRECT(DBACC, GSN_READ_PSUEDO_REQ, signal, 2); + } + else + { + signal->theData[0] = regTcPtr.p->m_scan_curr_range_no; + } } /* ************>> */ @@ -2639,11 +2647,11 @@ void Dblqh::execTUPKEYCONF(Signal* signal) jamEntry(); tcConnectptr.i = tcIndex; ptrCheckGuard(tcConnectptr, ttcConnectrecFileSize, regTcConnectionrec); - if (tcConnectptr.p->seqNoReplica == 0) // Primary replica - tcConnectptr.p->noFiredTriggers = tupKeyConf->noFiredTriggers; switch (tcConnectptr.p->transactionState) { case TcConnectionrec::WAIT_TUP: jam(); + if (tcConnectptr.p->seqNoReplica == 0) // Primary replica + tcConnectptr.p->noFiredTriggers = tupKeyConf->noFiredTriggers; tupkeyConfLab(signal); break; case TcConnectionrec::COPY_TUPKEY: @@ -7629,6 +7637,7 @@ void Dblqh::continueAfterReceivingAllAiLab(Signal* signal) req->requestInfo = 0; AccScanReq::setLockMode(req->requestInfo, scanptr.p->scanLockMode); AccScanReq::setReadCommittedFlag(req->requestInfo, scanptr.p->readCommitted); + AccScanReq::setDescendingFlag(req->requestInfo, scanptr.p->descending); req->transId1 = tcConnectptr.p->transid[0]; req->transId2 = tcConnectptr.p->transid[1]; req->savePointId = tcConnectptr.p->savePointId; @@ -7866,11 +7875,12 @@ Dblqh::copy_bounds(Uint32 * dst, TcConnectionrec* tcPtrP) } Uint32 first = (* (dst - left)); // First word in range - (* (dst - left)) = (first & 0xFFFF); // Remove length (16 upper bits) // Length of this range Uint8 offset; const Uint32 len = (first >> 16) ? (first >> 16) : totalLen; + tcPtrP->m_scan_curr_range_no = (first & 0xFFF0) >> 4; + (* (dst - left)) = (first & 0xF); // Remove length & range no if(len < left) { @@ -8280,7 +8290,7 @@ Dblqh::readPrimaryKeys(ScanRecord *scanP, TcConnectionrec *tcConP, Uint32 *dst) tableId = tFragPtr.p->tabRef; } - int ret = c_tup->accReadPk(tableId, fragId, fragPageId, pageIndex, dst); + int ret = c_tup->accReadPk(tableId, fragId, fragPageId, pageIndex, dst, false); if(0) ndbout_c("readPrimaryKeys(table: %d fragment: %d [ %d %d ] -> %d", tableId, fragId, fragPageId, pageIndex, ret); @@ -8619,6 +8629,7 @@ Uint32 Dblqh::initScanrec(const ScanFragReq* scanFragReq) const Uint32 keyinfo = ScanFragReq::getKeyinfoFlag(reqinfo); const Uint32 readCommitted = ScanFragReq::getReadCommittedFlag(reqinfo); const Uint32 idx = ScanFragReq::getRangeScanFlag(reqinfo); + const Uint32 descending = ScanFragReq::getDescendingFlag(reqinfo); const Uint32 attrLen = ScanFragReq::getAttrLen(reqinfo); const Uint32 scanPrio = ScanFragReq::getScanPrio(reqinfo); @@ -8640,6 +8651,7 @@ Uint32 Dblqh::initScanrec(const ScanFragReq* scanFragReq) scanptr.p->scanLockMode = scanLockMode; scanptr.p->readCommitted = readCommitted; scanptr.p->rangeScan = idx; + scanptr.p->descending = descending; scanptr.p->scanState = ScanRecord::SCAN_FREE; scanptr.p->scanFlag = ZFALSE; scanptr.p->scanLocalref[0] = 0; @@ -8746,6 +8758,7 @@ void Dblqh::initScanTc(Signal* signal, tcConnectptr.p->listState = TcConnectionrec::NOT_IN_LIST; tcConnectptr.p->commitAckMarker = RNIL; tcConnectptr.p->m_offset_current_keybuf = 0; + tcConnectptr.p->m_scan_curr_range_no = 0; tabptr.p->usageCount++; }//Dblqh::initScanTc() diff --git a/ndb/src/kernel/blocks/dbtc/Dbtc.hpp b/ndb/src/kernel/blocks/dbtc/Dbtc.hpp index ccb7d55396d..60f57c60f1f 100644 --- a/ndb/src/kernel/blocks/dbtc/Dbtc.hpp +++ b/ndb/src/kernel/blocks/dbtc/Dbtc.hpp @@ -897,7 +897,7 @@ public: UintR hashValue; /* THE HASH VALUE USED TO LOCATE FRAGMENT */ Uint8 distributionKeyIndicator; - Uint8 unused1; + Uint8 m_special_hash; // collation or distribution key Uint8 unused2; Uint8 lenAiInTckeyreq; /* LENGTH OF ATTRIBUTE INFORMATION IN TCKEYREQ */ @@ -972,6 +972,7 @@ public: typedef Ptr<HostRecord> HostRecordPtr; /* *********** TABLE RECORD ********************************************* */ + /********************************************************/ /* THIS RECORD CONTAINS THE CURRENT SCHEMA VERSION OF */ /* ALL TABLES IN THE SYSTEM. */ @@ -982,13 +983,22 @@ public: Uint8 dropping; Uint8 tableType; Uint8 storedTable; + + Uint8 noOfKeyAttr; + Uint8 hasCharAttr; + Uint8 noOfDistrKeys; + struct KeyAttr { + Uint32 attributeDescriptor; + CHARSET_INFO* charsetInfo; + } keyAttr[MAX_ATTRIBUTES_IN_INDEX]; + bool checkTable(Uint32 schemaVersion) const { return enabled && !dropping && (schemaVersion == currentSchemaVersion); } - + Uint32 getErrorCode(Uint32 schemaVersion) const; - + struct DropTable { Uint32 senderRef; Uint32 senderData; @@ -1436,6 +1446,10 @@ private: void gcpTcfinished(Signal* signal); void handleGcp(Signal* signal); void hash(Signal* signal); + Uint32 handle_special_hash(Uint32 dstHash[4], + Uint32* src, Uint32 srcLen, + Uint32 tabPtrI, bool distr); + void initApiConnect(Signal* signal); void initApiConnectRec(Signal* signal, ApiConnectRecord * const regApiPtr, diff --git a/ndb/src/kernel/blocks/dbtc/DbtcMain.cpp b/ndb/src/kernel/blocks/dbtc/DbtcMain.cpp index f964cc2fd9c..2f371458b73 100644 --- a/ndb/src/kernel/blocks/dbtc/DbtcMain.cpp +++ b/ndb/src/kernel/blocks/dbtc/DbtcMain.cpp @@ -20,6 +20,7 @@ #include "md5_hash.hpp" #include <RefConvert.hpp> #include <ndb_limits.h> +#include <my_sys.h> #include <signaldata/EventReport.hpp> #include <signaldata/TcKeyReq.hpp> @@ -63,6 +64,8 @@ #include <signaldata/PackedSignal.hpp> #include <AttributeHeader.hpp> #include <signaldata/DictTabInfo.hpp> +#include <AttributeDescriptor.hpp> +#include <SectionReader.hpp> #include <NdbOut.hpp> #include <DebuggerNames.hpp> @@ -313,6 +316,10 @@ void Dbtc::execREAD_NODESREF(Signal* signal) void Dbtc::execTC_SCHVERREQ(Signal* signal) { jamEntry(); + if (! assembleFragments(signal)) { + jam(); + return; + } tabptr.i = signal->theData[0]; ptrCheckGuard(tabptr, ctabrecFilesize, tableRecord); tabptr.p->currentSchemaVersion = signal->theData[1]; @@ -320,10 +327,44 @@ void Dbtc::execTC_SCHVERREQ(Signal* signal) BlockReference retRef = signal->theData[3]; tabptr.p->tableType = (Uint8)signal->theData[4]; BlockReference retPtr = signal->theData[5]; + Uint32 noOfKeyAttr = signal->theData[6]; + ndbrequire(noOfKeyAttr <= MAX_ATTRIBUTES_IN_INDEX); + Uint32 hasCharAttr = 0; + Uint32 noOfDistrKeys = 0; + SegmentedSectionPtr s0Ptr; + signal->getSection(s0Ptr, 0); + SectionReader r0(s0Ptr, getSectionSegmentPool()); + Uint32 i = 0; + while (i < noOfKeyAttr) { + jam(); + Uint32 attributeDescriptor = ~0; + Uint32 csNumber = ~0; + if (! r0.getWord(&attributeDescriptor) || + ! r0.getWord(&csNumber)) { + jam(); + break; + } + CHARSET_INFO* cs = 0; + if (csNumber != 0) { + cs = all_charsets[csNumber]; + ndbrequire(cs != 0); + hasCharAttr = 1; + } + + noOfDistrKeys += AttributeDescriptor::getDKey(attributeDescriptor); + tabptr.p->keyAttr[i].attributeDescriptor = attributeDescriptor; + tabptr.p->keyAttr[i].charsetInfo = cs; + i++; + } + ndbrequire(i == noOfKeyAttr); + releaseSections(signal); ndbrequire(tabptr.p->enabled == false); tabptr.p->enabled = true; tabptr.p->dropping = false; + tabptr.p->noOfKeyAttr = noOfKeyAttr; + tabptr.p->hasCharAttr = hasCharAttr; + tabptr.p->noOfDistrKeys = noOfDistrKeys; signal->theData[0] = tabptr.i; signal->theData[1] = retPtr; @@ -2220,11 +2261,10 @@ void Dbtc::hash(Signal* signal) UintR Tdata2; UintR Tdata3; UintR* Tdata32; - Uint64 Tdata[512]; - + CacheRecord * const regCachePtr = cachePtr.p; - Tdata32 = (UintR*)&Tdata[0]; - + Tdata32 = signal->theData; + Tdata0 = regCachePtr->keydata[0]; Tdata1 = regCachePtr->keydata[1]; Tdata2 = regCachePtr->keydata[2]; @@ -2250,11 +2290,22 @@ void Dbtc::hash(Signal* signal) ti += 4; }//while }//if - Uint32 tmp[4]; - md5_hash(tmp, (Uint64*)&Tdata32[0], (UintR)regCachePtr->keylen); + UintR keylen = (UintR)regCachePtr->keylen; + Uint32 distKey = regCachePtr->distributionKeyIndicator; + + Uint32 tmp[4]; + if(!regCachePtr->m_special_hash) + { + md5_hash(tmp, (Uint64*)&Tdata32[0], keylen); + } + else + { + handle_special_hash(tmp, Tdata32, keylen, regCachePtr->tableref, !distKey); + } + thashValue = tmp[0]; - if (regCachePtr->distributionKeyIndicator == 1) { + if (distKey){ jam(); tdistrHashValue = regCachePtr->distributionKey; } else { @@ -2263,6 +2314,112 @@ void Dbtc::hash(Signal* signal) }//if }//Dbtc::hash() +Uint32 +Dbtc::handle_special_hash(Uint32 dstHash[4], Uint32* src, Uint32 srcLen, + Uint32 tabPtrI, + bool distr) +{ + Uint64 Tmp[MAX_KEY_SIZE_IN_WORDS * 4 * MAX_XFRM_MULTIPLY]; + const Uint32 dstSize = sizeof(Tmp) / 4; + const TableRecord* tabPtrP = &tableRecord[tabPtrI]; + const Uint32 noOfKeyAttr = tabPtrP->noOfKeyAttr; + Uint32 noOfDistrKeys = tabPtrP->noOfDistrKeys; + const bool hasCharAttr = tabPtrP->hasCharAttr; + + Uint32 *dst = (Uint32*)Tmp; + Uint32 dstPos = 0; + Uint32 srcPos = 0; + Uint32 keyPartLen[MAX_ATTRIBUTES_IN_INDEX]; + if(hasCharAttr){ + Uint32 i = 0; + while (i < noOfKeyAttr) { + const TableRecord::KeyAttr& keyAttr = tabPtrP->keyAttr[i]; + + Uint32 srcBytes = + AttributeDescriptor::getSizeInBytes(keyAttr.attributeDescriptor); + Uint32 srcWords = (srcBytes + 3) / 4; + Uint32 dstWords = ~0; + uchar* dstPtr = (uchar*)&dst[dstPos]; + const uchar* srcPtr = (const uchar*)&src[srcPos]; + CHARSET_INFO* cs = keyAttr.charsetInfo; + + if (cs == NULL) { + jam(); + memcpy(dstPtr, srcPtr, srcWords << 2); + dstWords = srcWords; + } else { + jam(); + Uint32 xmul = cs->strxfrm_multiply; + if (xmul == 0) + xmul = 1; + Uint32 dstLen = xmul * srcBytes; + ndbrequire(dstLen <= ((dstSize - dstPos) << 2)); + uint n = (*cs->coll->strnxfrm)(cs, dstPtr, dstLen, srcPtr, srcBytes); + while ((n & 3) != 0) { + dstPtr[n++] = 0; + } + dstWords = (n >> 2); + + } + dstPos += dstWords; + srcPos += srcWords; + keyPartLen[i++] = dstWords; + } + } + else + { + dst = src; + dstPos = srcLen; + } + + md5_hash(dstHash, (Uint64*)dst, dstPos); + + if(distr && noOfDistrKeys) + { + jam(); + src = dst; + dstPos = 0; + Uint32 i = 0; + if(hasCharAttr) + { + while (i < noOfKeyAttr && noOfDistrKeys) + { + const TableRecord::KeyAttr& keyAttr = tabPtrP->keyAttr[i]; + Uint32 len = keyPartLen[i]; + if(AttributeDescriptor::getDKey(keyAttr.attributeDescriptor)) + { + noOfDistrKeys--; + memmove(dst+dstPos, src, len << 2); + dstPos += len; + } + src += len; + i++; + } + } + else + { + while (i < noOfKeyAttr && noOfDistrKeys) + { + const TableRecord::KeyAttr& keyAttr = tabPtrP->keyAttr[i]; + Uint32 len = + AttributeDescriptor::getSizeInBytes(keyAttr.attributeDescriptor); + len = (len + 3) / 4; + if(AttributeDescriptor::getDKey(keyAttr.attributeDescriptor)) + { + noOfDistrKeys--; + memmove(dst+dstPos, src, len << 2); + dstPos += len; + } + src += len; + i++; + } + } + Uint32 tmp[4]; + md5_hash(tmp, (Uint64*)dst, dstPos); + dstHash[1] = tmp[1]; + } +} + /* INIT_API_CONNECT_REC --------------------------- @@ -2710,7 +2867,8 @@ void Dbtc::execTCKEYREQ(Signal* signal) regCachePtr->keylen = TkeyLength; regCachePtr->lenAiInTckeyreq = titcLenAiInTckeyreq; regCachePtr->currReclenAi = titcLenAiInTckeyreq; - + regCachePtr->m_special_hash = + localTabptr.p->hasCharAttr | (localTabptr.p->noOfDistrKeys > 0); Tdata1 = TAIDataPtr[0]; Tdata2 = TAIDataPtr[1]; Tdata3 = TAIDataPtr[2]; @@ -8633,6 +8791,7 @@ void Dbtc::initScanrec(ScanRecordPtr scanptr, ScanFragReq::setKeyinfoFlag(tmp, ScanTabReq::getKeyinfoFlag(ri)); ScanFragReq::setReadCommittedFlag(tmp,ScanTabReq::getReadCommittedFlag(ri)); ScanFragReq::setRangeScanFlag(tmp, ScanTabReq::getRangeScanFlag(ri)); + ScanFragReq::setDescendingFlag(tmp, ScanTabReq::getDescendingFlag(ri)); ScanFragReq::setAttrLen(tmp, scanTabReq->attrLenKeyLen & 0xFFFF); scanptr.p->scanRequestInfo = tmp; @@ -8859,6 +9018,7 @@ void Dbtc::execDI_FCOUNTCONF(Signal* signal) { ptr.p->m_ops = 0; ptr.p->m_totalLen = 0; + ptr.p->m_scan_frag_conf_status = 1; ptr.p->scanFragState = ScanFragRec::QUEUED_FOR_DELIVERY; ptr.p->stopFragTimer(); @@ -8866,6 +9026,7 @@ void Dbtc::execDI_FCOUNTCONF(Signal* signal) list.next(ptr); list.remove(tmp); queued.add(tmp); + scanptr.p->m_queued_count++; } }//Dbtc::execDI_FCOUNTCONF() @@ -9973,6 +10134,13 @@ void Dbtc::initTable(Signal* signal) tabptr.p->tableType = 0; tabptr.p->enabled = false; tabptr.p->dropping = false; + tabptr.p->noOfKeyAttr = 0; + tabptr.p->hasCharAttr = 0; + tabptr.p->noOfDistrKeys = 0; + for (unsigned k = 0; k < MAX_ATTRIBUTES_IN_INDEX; k++) { + tabptr.p->keyAttr[k].attributeDescriptor = 0; + tabptr.p->keyAttr[k].charsetInfo = 0; + } }//for }//Dbtc::initTable() @@ -11144,14 +11312,14 @@ void Dbtc::execTCINDXREQ(Signal* signal) if (!seizeIndexOperation(regApiPtr, indexOpPtr)) { jam(); // Failed to allocate index operation - TcIndxRef * const tcIndxRef = (TcIndxRef *)signal->getDataPtrSend(); + TcKeyRef * const tcIndxRef = (TcKeyRef *)signal->getDataPtrSend(); tcIndxRef->connectPtr = tcIndxReq->senderData; tcIndxRef->transId[0] = regApiPtr->transid[0]; tcIndxRef->transId[1] = regApiPtr->transid[1]; tcIndxRef->errorCode = 4000; sendSignal(regApiPtr->ndbapiBlockref, GSN_TCINDXREF, signal, - TcIndxRef::SignalLength, JBB); + TcKeyRef::SignalLength, JBB); return; } TcIndexOperation* indexOp = indexOpPtr.p; @@ -11465,14 +11633,14 @@ void Dbtc::execTCKEYCONF(Signal* signal) case(IOS_NOOP): { jam(); // Should never happen, abort - TcIndxRef * const tcIndxRef = (TcIndxRef *)signal->getDataPtrSend(); + TcKeyRef * const tcIndxRef = (TcKeyRef *)signal->getDataPtrSend(); tcIndxRef->connectPtr = indexOp->tcIndxReq.senderData; tcIndxRef->transId[0] = regApiPtr->transid[0]; tcIndxRef->transId[1] = regApiPtr->transid[1]; tcIndxRef->errorCode = 4349; sendSignal(regApiPtr->ndbapiBlockref, GSN_TCINDXREF, signal, - TcIndxRef::SignalLength, JBB); + TcKeyRef::SignalLength, JBB); return; } case(IOS_INDEX_ACCESS): { @@ -11484,14 +11652,14 @@ void Dbtc::execTCKEYCONF(Signal* signal) case(IOS_INDEX_ACCESS_WAIT_FOR_TRANSID_AI): { jam(); // Double TCKEYCONF, should never happen, abort - TcIndxRef * const tcIndxRef = (TcIndxRef *)signal->getDataPtrSend(); + TcKeyRef * const tcIndxRef = (TcKeyRef *)signal->getDataPtrSend(); tcIndxRef->connectPtr = indexOp->tcIndxReq.senderData; tcIndxRef->transId[0] = regApiPtr->transid[0]; tcIndxRef->transId[1] = regApiPtr->transid[1]; tcIndxRef->errorCode = 4349; sendSignal(regApiPtr->ndbapiBlockref, GSN_TCINDXREF, signal, - TcIndxRef::SignalLength, JBB); + TcKeyRef::SignalLength, JBB); return; } case(IOS_INDEX_ACCESS_WAIT_FOR_TCKEYCONF): { @@ -11578,7 +11746,7 @@ void Dbtc::execTCKEYREF(Signal* signal) jam(); TcKeyReq * const tcIndxReq = &indexOp->tcIndxReq; - TcIndxRef * const tcIndxRef = (TcIndxRef *)signal->getDataPtrSend(); + TcKeyRef * const tcIndxRef = (TcKeyRef *)signal->getDataPtrSend(); ndbassert(regApiPtr->noIndexOp); regApiPtr->noIndexOp--; // Decrease count @@ -11587,7 +11755,7 @@ void Dbtc::execTCKEYREF(Signal* signal) tcIndxRef->transId[1] = tcKeyRef->transId[1]; tcIndxRef->errorCode = tcKeyRef->errorCode; sendSignal(regApiPtr->ndbapiBlockref, - GSN_TCINDXREF, signal, TcIndxRef::SignalLength, JBB); + GSN_TCINDXREF, signal, TcKeyRef::SignalLength, JBB); return; } } @@ -11654,14 +11822,14 @@ void Dbtc::execTRANSID_AI(Signal* signal) signal->getLength() - TransIdAI::HeaderLength)) { jam(); // Failed to allocate space for TransIdAI - TcIndxRef * const tcIndxRef = (TcIndxRef *)signal->getDataPtrSend(); + TcKeyRef * const tcIndxRef = (TcKeyRef *)signal->getDataPtrSend(); tcIndxRef->connectPtr = indexOp->tcIndxReq.senderData; tcIndxRef->transId[0] = regApiPtr->transid[0]; tcIndxRef->transId[1] = regApiPtr->transid[1]; tcIndxRef->errorCode = 4000; sendSignal(regApiPtr->ndbapiBlockref, GSN_TCINDXREF, signal, - TcIndxRef::SignalLength, JBB); + TcKeyRef::SignalLength, JBB); return; } @@ -11669,14 +11837,14 @@ void Dbtc::execTRANSID_AI(Signal* signal) case(IOS_NOOP): { jam(); // Should never happen, abort - TcIndxRef * const tcIndxRef = (TcIndxRef *)signal->getDataPtrSend(); + TcKeyRef * const tcIndxRef = (TcKeyRef *)signal->getDataPtrSend(); tcIndxRef->connectPtr = indexOp->tcIndxReq.senderData; tcIndxRef->transId[0] = regApiPtr->transid[0]; tcIndxRef->transId[1] = regApiPtr->transid[1]; tcIndxRef->errorCode = 4349; sendSignal(regApiPtr->ndbapiBlockref, GSN_TCINDXREF, signal, - TcIndxRef::SignalLength, JBB); + TcKeyRef::SignalLength, JBB); return; break; } @@ -11697,14 +11865,14 @@ void Dbtc::execTRANSID_AI(Signal* signal) #endif /* // Too many TRANSID_AI - TcIndxRef * const tcIndxRef = (TcIndxRef *)signal->getDataPtrSend(); + TcKeyRef * const tcIndxRef = (TcKeyRef *)signal->getDataPtrSend(); tcIndexRef->connectPtr = indexOp->tcIndxReq.senderData; tcIndxRef->transId[0] = regApiPtr->transid[0]; tcIndxRef->transId[1] = regApiPtr->transid[1]; tcIndxRef->errorCode = 4349; sendSignal(regApiPtr->ndbapiBlockref, GSN_TCINDXREF, signal, - TcIndxRef::SignalLength, JBB); + TcKeyRef::SignalLength, JBB); */ break; } @@ -11722,14 +11890,14 @@ void Dbtc::execTRANSID_AI(Signal* signal) case(IOS_INDEX_OPERATION): { // Should never receive TRANSID_AI in this state!! jam(); - TcIndxRef * const tcIndxRef = (TcIndxRef *)signal->getDataPtrSend(); + TcKeyRef * const tcIndxRef = (TcKeyRef *)signal->getDataPtrSend(); tcIndxRef->connectPtr = indexOp->tcIndxReq.senderData; tcIndxRef->transId[0] = regApiPtr->transid[0]; tcIndxRef->transId[1] = regApiPtr->transid[1]; tcIndxRef->errorCode = 4349; sendSignal(regApiPtr->ndbapiBlockref, GSN_TCINDXREF, signal, - TcIndxRef::SignalLength, JBB); + TcKeyRef::SignalLength, JBB); return; } } @@ -11775,14 +11943,14 @@ void Dbtc::readIndexTable(Signal* signal, if ((indexData = c_theIndexes.getPtr(indexOp->tcIndxReq.tableId)) == NULL) { jam(); // Failed to find index record - TcIndxRef * const tcIndxRef = (TcIndxRef *)signal->getDataPtrSend(); + TcKeyRef * const tcIndxRef = (TcKeyRef *)signal->getDataPtrSend(); tcIndxRef->connectPtr = indexOp->tcIndxReq.senderData; tcIndxRef->transId[0] = regApiPtr->transid[0]; tcIndxRef->transId[1] = regApiPtr->transid[1]; tcIndxRef->errorCode = 4000; sendSignal(regApiPtr->ndbapiBlockref, GSN_TCINDXREF, signal, - TcIndxRef::SignalLength, JBB); + TcKeyRef::SignalLength, JBB); return; } tcKeyReq->transId1 = transId1; @@ -11895,14 +12063,14 @@ void Dbtc::executeIndexOperation(Signal* signal, if ((indexData = c_theIndexes.getPtr(tcIndxReq->tableId)) == NULL) { jam(); // Failed to find index record - TcIndxRef * const tcIndxRef = (TcIndxRef *)signal->getDataPtrSend(); + TcKeyRef * const tcIndxRef = (TcKeyRef *)signal->getDataPtrSend(); tcIndxRef->connectPtr = indexOp->tcIndxReq.senderData; tcIndxRef->transId[0] = regApiPtr->transid[0]; tcIndxRef->transId[1] = regApiPtr->transid[1]; tcIndxRef->errorCode = 4349; sendSignal(regApiPtr->ndbapiBlockref, GSN_TCINDXREF, signal, - TcIndxRef::SignalLength, JBB); + TcKeyRef::SignalLength, JBB); return; } // Find schema version of primary table diff --git a/ndb/src/kernel/blocks/dbtup/Dbtup.hpp b/ndb/src/kernel/blocks/dbtup/Dbtup.hpp index 1c7662c5d55..6d169d20d16 100644 --- a/ndb/src/kernel/blocks/dbtup/Dbtup.hpp +++ b/ndb/src/kernel/blocks/dbtup/Dbtup.hpp @@ -207,6 +207,8 @@ #define ZTUPLE_DELETED_ERROR 626 #define ZINSERT_ERROR 630 +#define ZINVALID_CHAR_FORMAT 744 + /* SOME WORD POSITIONS OF FIELDS IN SOME HEADERS */ #define ZPAGE_STATE_POS 0 /* POSITION OF PAGE STATE */ @@ -1020,14 +1022,14 @@ public: * for md5 summing and when returning keyinfo. Returns number of * words or negative (-terrorCode) on error. */ - int tuxReadPk(Uint32 fragPtrI, Uint32 pageId, Uint32 pageOffset, Uint32* dataOut); + int tuxReadPk(Uint32 fragPtrI, Uint32 pageId, Uint32 pageOffset, Uint32* dataOut, bool xfrmFlag); /* * ACC reads primary key without headers into an array of words. At * this point in ACC deconstruction, ACC still uses logical references * to fragment and tuple. */ - int accReadPk(Uint32 tableId, Uint32 fragId, Uint32 fragPageId, Uint32 pageIndex, Uint32* dataOut); + int accReadPk(Uint32 tableId, Uint32 fragId, Uint32 fragPageId, Uint32 pageIndex, Uint32* dataOut, bool xfrmFlag); /* * TUX checks if tuple is visible to scan. @@ -1637,20 +1639,6 @@ private: bool readBitsNotNULL(Uint32* outBuffer, AttributeHeader*, Uint32, Uint32); bool updateBitsNotNULL(Uint32* inBuffer, Uint32, Uint32); -// ***************************************************************** -// Read char routines optionally (tXfrmFlag) apply strxfrm -// ***************************************************************** - - bool readCharNotNULL(Uint32* outBuffer, - AttributeHeader* ahOut, - Uint32 attrDescriptor, - Uint32 attrDes2); - - bool readCharNULLable(Uint32* outBuffer, - AttributeHeader* ahOut, - Uint32 attrDescriptor, - Uint32 attrDes2); - //------------------------------------------------------------------ //------------------------------------------------------------------ bool nullFlagCheck(Uint32 attrDes2); diff --git a/ndb/src/kernel/blocks/dbtup/DbtupExecQuery.cpp b/ndb/src/kernel/blocks/dbtup/DbtupExecQuery.cpp index 8e3ca6528c2..9778c938e0f 100644 --- a/ndb/src/kernel/blocks/dbtup/DbtupExecQuery.cpp +++ b/ndb/src/kernel/blocks/dbtup/DbtupExecQuery.cpp @@ -858,6 +858,8 @@ void Dbtup::sendTUPKEYCONF(Signal* signal, return; }//Dbtup::sendTUPKEYCONF() +#define MAX_READ (sizeof(signal->theData) > MAX_MESSAGE_SIZE ? MAX_MESSAGE_SIZE : sizeof(signal->theData)) + /* ---------------------------------------------------------------- */ /* ----------------------------- READ ---------------------------- */ /* ---------------------------------------------------------------- */ @@ -878,7 +880,7 @@ int Dbtup::handleReadReq(Signal* signal, }//if Uint32 * dst = &signal->theData[25]; - Uint32 dstLen = (sizeof(signal->theData) / 4) - 25; + Uint32 dstLen = (MAX_READ / 4) - 25; const Uint32 node = refToNode(sendBref); if(node != 0 && node != getOwnNodeId()) { ; @@ -888,7 +890,7 @@ int Dbtup::handleReadReq(Signal* signal, * execute direct */ dst = &signal->theData[3]; - dstLen = (sizeof(signal->theData) / 4) - 3; + dstLen = (MAX_READ / 4) - 3; } if (regOperPtr->interpretedExec != 1) { @@ -1228,7 +1230,7 @@ int Dbtup::interpreterStartLab(Signal* signal, const BlockReference sendBref = regOperPtr->recBlockref; Uint32 * dst = &signal->theData[25]; - Uint32 dstLen = (sizeof(signal->theData) / 4) - 25; + Uint32 dstLen = (MAX_READ / 4) - 25; const Uint32 node = refToNode(sendBref); if(node != 0 && node != getOwnNodeId()) { ; @@ -1238,7 +1240,7 @@ int Dbtup::interpreterStartLab(Signal* signal, * execute direct */ dst = &signal->theData[3]; - dstLen = (sizeof(signal->theData) / 4) - 3; + dstLen = (MAX_READ / 4) - 3; } RtotalLen = RinitReadLen; @@ -1538,13 +1540,8 @@ int Dbtup::interpreterNextLab(Signal* signal, // Calculate the number of words of this attribute. // We allow writes into arrays as long as they fit into the 64 bit // register size. - //TEST_MR See to that TattrNoOfWords can be - // read faster from attribute description. /* --------------------------------------------------------------- */ - Uint32 TarraySize = (TattrDesc1 >> 16); - Uint32 TattrLogLen = (TattrDesc1 >> 4) & 0xf; - Uint32 TattrNoOfBits = TarraySize << TattrLogLen; - Uint32 TattrNoOfWords = (TattrNoOfBits + 31) >> 5; + Uint32 TattrNoOfWords = AttributeDescriptor::getSizeInWords(TattrDesc1); Uint32 Toptype = operPtr.p->optype; Uint32 TdataForUpdate[3]; @@ -1821,9 +1818,6 @@ int Dbtup::interpreterNextLab(Signal* signal, case Interpreter::BRANCH_ATTR_OP_ARG:{ jam(); Uint32 cond = Interpreter::getBinaryCondition(theInstruction); - Uint32 diff = Interpreter::getArrayLengthDiff(theInstruction); - Uint32 vchr = Interpreter::isVarchar(theInstruction); - Uint32 nopad =Interpreter::isNopad(theInstruction); Uint32 ins2 = TcurrentProgram[TprogramCounter]; Uint32 attrId = Interpreter::getBranchCol_AttrId(ins2) << 16; Uint32 argLen = Interpreter::getBranchCol_Len(ins2); @@ -1842,84 +1836,81 @@ int Dbtup::interpreterNextLab(Signal* signal, } tmpHabitant = attrId; } - - AttributeHeader ah(tmpArea[0]); + attrId >>= 16; + AttributeHeader ah(tmpArea[0]); + const char* s1 = (char*)&tmpArea[1]; const char* s2 = (char*)&TcurrentProgram[TprogramCounter+1]; - Uint32 attrLen = (4 * ah.getDataSize()) - diff; - if (vchr) { -#if NDB_VERSION_MAJOR >= 3 - bool vok = false; - if (attrLen >= 2) { - Uint32 vlen = (s1[0] << 8) | s1[1]; // big-endian - s1 += 2; - attrLen -= 2; - if (attrLen >= vlen) { - attrLen = vlen; - vok = true; - } - } - if (!vok) { - terrorCode = ZREGISTER_INIT_ERROR; - tupkeyErrorLab(signal); - return -1; - } -#else - Uint32 tmp; - if (attrLen >= 2) { - unsigned char* ss = (unsigned char*)&s1[attrLen - 2]; - tmp = (ss[0] << 8) | ss[1]; - if (tmp <= attrLen - 2) - attrLen = tmp; - } - // XXX handle bad data -#endif - } - bool res = false; - + Uint32 attrLen = (4 * ah.getDataSize()); + Uint32 TattrDescrIndex = tabptr.p->tabDescriptor + + (attrId << ZAD_LOG_SIZE); + Uint32 TattrDesc1 = tableDescriptor[TattrDescrIndex].tabDescr; + Uint32 TattrDesc2 = tableDescriptor[TattrDescrIndex+1].tabDescr; + Uint32 typeId = AttributeDescriptor::getType(TattrDesc1); + void * cs = 0; + if(AttributeOffset::getCharsetFlag(TattrDesc2)) + { + Uint32 pos = AttributeOffset::getCharsetPos(TattrDesc2); + cs = tabptr.p->charsetArray[pos]; + } + const NdbSqlUtil::Type& sqlType = NdbSqlUtil::getType(typeId); + + bool r1_null = ah.isNULL(); + bool r2_null = argLen == 0; + int res; + if(r1_null || r2_null) + { + res = r1_null && r2_null ? 0 : r1_null ? -1 : 1; + } + else + { + res = (*sqlType.m_cmp)(cs, s1, attrLen, s2, argLen, true); + } + switch ((Interpreter::BinaryCondition)cond) { case Interpreter::EQ: - res = NdbSqlUtil::char_compare(s1, attrLen, s2, argLen, !nopad) == 0; + res = (res == 0); break; case Interpreter::NE: - res = NdbSqlUtil::char_compare(s1, attrLen, s2, argLen, !nopad) != 0; + res = (res != 0); break; // note the condition is backwards case Interpreter::LT: - res = NdbSqlUtil::char_compare(s1, attrLen, s2, argLen, !nopad) > 0; + res = (res > 0); break; case Interpreter::LE: - res = NdbSqlUtil::char_compare(s1, attrLen, s2, argLen, !nopad) >= 0; + res = (res >= 0); break; case Interpreter::GT: - res = NdbSqlUtil::char_compare(s1, attrLen, s2, argLen, !nopad) < 0; + res = (res < 0); break; case Interpreter::GE: - res = NdbSqlUtil::char_compare(s1, attrLen, s2, argLen, !nopad) <= 0; + res = (res <= 0); break; case Interpreter::LIKE: - res = NdbSqlUtil::char_like(s1, attrLen, s2, argLen, !nopad); + res = NdbSqlUtil::char_like(s1, attrLen, s2, argLen, false); break; case Interpreter::NOT_LIKE: - res = ! NdbSqlUtil::char_like(s1, attrLen, s2, argLen, !nopad); + res = ! NdbSqlUtil::char_like(s1, attrLen, s2, argLen, false); break; - // XXX handle invalid value + // XXX handle invalid value } #ifdef TRACE_INTERPRETER - ndbout_c("cond=%u diff=%d vc=%d nopad=%d attr(%d) = >%.*s<(%d) str=>%.*s<(%d) -> res = %d", - cond, diff, vchr, nopad, - attrId >> 16, attrLen, s1, attrLen, argLen, s2, argLen, res); + ndbout_c("cond=%u diff=%d vc=%d nopad=%d attr(%d) = >%.*s<(%d) str=>%.*s<(%d) -> res = %d", + cond, diff, vchr, nopad, + attrId >> 16, attrLen, s1, attrLen, argLen, s2, argLen, res); #endif if (res) TprogramCounter = brancher(theInstruction, TprogramCounter); - else { - Uint32 tmp = (Interpreter::mod4(argLen) >> 2) + 1; + else + { + Uint32 tmp = ((argLen + 3) >> 2) + 1; TprogramCounter += tmp; } break; } - + case Interpreter::BRANCH_ATTR_EQ_NULL:{ jam(); Uint32 ins2 = TcurrentProgram[TprogramCounter]; diff --git a/ndb/src/kernel/blocks/dbtup/DbtupIndex.cpp b/ndb/src/kernel/blocks/dbtup/DbtupIndex.cpp index 3b0ba1c196f..ab6e0642e11 100644 --- a/ndb/src/kernel/blocks/dbtup/DbtupIndex.cpp +++ b/ndb/src/kernel/blocks/dbtup/DbtupIndex.cpp @@ -173,7 +173,7 @@ Dbtup::tuxReadAttrs(Uint32 fragPtrI, Uint32 pageId, Uint32 pageOffset, Uint32 tu } int -Dbtup::tuxReadPk(Uint32 fragPtrI, Uint32 pageId, Uint32 pageOffset, Uint32* dataOut) +Dbtup::tuxReadPk(Uint32 fragPtrI, Uint32 pageId, Uint32 pageOffset, Uint32* dataOut, bool xfrmFlag) { ljamEntry(); // use own variables instead of globals @@ -200,7 +200,7 @@ Dbtup::tuxReadPk(Uint32 fragPtrI, Uint32 pageId, Uint32 pageOffset, Uint32* data operPtr.i = RNIL; operPtr.p = NULL; // do it - int ret = readAttributes(pagePtr.p, pageOffset, attrIds, numAttrs, dataOut, ZNIL, true); + int ret = readAttributes(pagePtr.p, pageOffset, attrIds, numAttrs, dataOut, ZNIL, xfrmFlag); // restore globals tabptr = tabptr_old; fragptr = fragptr_old; @@ -229,7 +229,7 @@ Dbtup::tuxReadPk(Uint32 fragPtrI, Uint32 pageId, Uint32 pageOffset, Uint32* data } int -Dbtup::accReadPk(Uint32 tableId, Uint32 fragId, Uint32 fragPageId, Uint32 pageIndex, Uint32* dataOut) +Dbtup::accReadPk(Uint32 tableId, Uint32 fragId, Uint32 fragPageId, Uint32 pageIndex, Uint32* dataOut, bool xfrmFlag) { ljamEntry(); // get table @@ -245,7 +245,7 @@ Dbtup::accReadPk(Uint32 tableId, Uint32 fragId, Uint32 fragPageId, Uint32 pageIn ndbrequire((pageIndex & 0x1) == 0); Uint32 pageOffset = ZPAGE_HEADER_SIZE + (pageIndex >> 1) * tablePtr.p->tupheadsize; // use TUX routine - optimize later - int ret = tuxReadPk(fragPtr.i, pageId, pageOffset, dataOut); + int ret = tuxReadPk(fragPtr.i, pageId, pageOffset, dataOut, xfrmFlag); return ret; } diff --git a/ndb/src/kernel/blocks/dbtup/DbtupMeta.cpp b/ndb/src/kernel/blocks/dbtup/DbtupMeta.cpp index 56ae861270c..4ce807528c4 100644 --- a/ndb/src/kernel/blocks/dbtup/DbtupMeta.cpp +++ b/ndb/src/kernel/blocks/dbtup/DbtupMeta.cpp @@ -288,8 +288,7 @@ void Dbtup::execTUP_ADD_ATTRREQ(Signal* signal) ptrCheckGuard(fragOperPtr, cnoOfFragoprec, fragoperrec); Uint32 attrId = signal->theData[2]; Uint32 attrDescriptor = signal->theData[3]; - // DICT sends extended type (ignored) and charset number - Uint32 extType = (signal->theData[4] & 0xFF); + // DICT sends charset number in upper half Uint32 csNumber = (signal->theData[4] >> 16); regTabPtr.i = fragOperPtr.p->tableidFrag; @@ -364,13 +363,8 @@ void Dbtup::execTUP_ADD_ATTRREQ(Signal* signal) ndbrequire(false); }//if if (csNumber != 0) { - CHARSET_INFO* cs = get_charset(csNumber, MYF(0)); - if (cs == NULL) { - ljam(); - terrorCode = TupAddAttrRef::InvalidCharset; - addattrrefuseLab(signal, regFragPtr, fragOperPtr, regTabPtr.p, fragId); - return; - } + CHARSET_INFO* cs = all_charsets[csNumber]; + ndbrequire(cs != NULL); Uint32 i = 0; while (i < fragOperPtr.p->charsetIndex) { ljam(); diff --git a/ndb/src/kernel/blocks/dbtup/DbtupRoutines.cpp b/ndb/src/kernel/blocks/dbtup/DbtupRoutines.cpp index 5bcbb482a8c..3c25e675a5e 100644 --- a/ndb/src/kernel/blocks/dbtup/DbtupRoutines.cpp +++ b/ndb/src/kernel/blocks/dbtup/DbtupRoutines.cpp @@ -59,10 +59,11 @@ Dbtup::setUpQueryRoutines(Tablerec* const regTabPtr) } else { ndbrequire(false); }//if - // replace read function of char attribute + // replace functions for char attribute if (AttributeOffset::getCharsetFlag(attrOffset)) { ljam(); - regTabPtr->readFunctionArray[i] = &Dbtup::readCharNotNULL; + regTabPtr->readFunctionArray[i] = &Dbtup::readFixedSizeTHManyWordNotNULL; + regTabPtr->updateFunctionArray[i] = &Dbtup::updateFixedSizeTHManyWordNotNULL; } } else { if (AttributeDescriptor::getSize(attrDescriptor) == 0){ @@ -86,10 +87,11 @@ Dbtup::setUpQueryRoutines(Tablerec* const regTabPtr) regTabPtr->readFunctionArray[i] = &Dbtup::readFixedSizeTHZeroWordNULLable; regTabPtr->updateFunctionArray[i] = &Dbtup::updateFixedSizeTHManyWordNULLable; }//if - // replace read function of char attribute + // replace functions for char attribute if (AttributeOffset::getCharsetFlag(attrOffset)) { ljam(); - regTabPtr->readFunctionArray[i] = &Dbtup::readCharNULLable; + regTabPtr->readFunctionArray[i] = &Dbtup::readFixedSizeTHManyWordNULLable; + regTabPtr->updateFunctionArray[i] = &Dbtup::updateFixedSizeTHManyWordNULLable; } }//if } else if (AttributeDescriptor::getArrayType(attrDescriptor) == ZVAR_ARRAY) { @@ -337,25 +339,68 @@ Dbtup::readFixedSizeTHManyWordNotNULL(Uint32* outBuffer, Uint32 attrDes2) { Uint32 indexBuf = tOutBufIndex; + Uint32 charsetFlag = AttributeOffset::getCharsetFlag(attrDes2); Uint32 readOffset = AttributeOffset::getOffset(attrDes2); Uint32 attrNoOfWords = AttributeDescriptor::getSizeInWords(attrDescriptor); - Uint32 newIndexBuf = indexBuf + attrNoOfWords; Uint32 maxRead = tMaxRead; ndbrequire((readOffset + attrNoOfWords - 1) < tCheckOffset); - if (newIndexBuf <= maxRead) { - ljam(); - ahOut->setDataSize(attrNoOfWords); - MEMCOPY_NO_WORDS(&outBuffer[indexBuf], - &tTupleHeader[readOffset], - attrNoOfWords); - tOutBufIndex = newIndexBuf; - return true; + if (! charsetFlag || ! tXfrmFlag) { + Uint32 newIndexBuf = indexBuf + attrNoOfWords; + if (newIndexBuf <= maxRead) { + ljam(); + ahOut->setDataSize(attrNoOfWords); + MEMCOPY_NO_WORDS(&outBuffer[indexBuf], + &tTupleHeader[readOffset], + attrNoOfWords); + tOutBufIndex = newIndexBuf; + return true; + } else { + ljam(); + terrorCode = ZTRY_TO_READ_TOO_MUCH_ERROR; + }//if } else { ljam(); - terrorCode = ZTRY_TO_READ_TOO_MUCH_ERROR; - return false; - }//if + Tablerec* regTabPtr = tabptr.p; + Uint32 srcBytes = AttributeDescriptor::getSizeInBytes(attrDescriptor); + Uint32 i = AttributeOffset::getCharsetPos(attrDes2); + ndbrequire(i < regTabPtr->noOfCharsets); + CHARSET_INFO* cs = regTabPtr->charsetArray[i]; + Uint32 xmul = cs->strxfrm_multiply; + if (xmul == 0) + xmul = 1; + Uint32 dstLen = xmul * srcBytes; + Uint32 maxIndexBuf = indexBuf + (dstLen >> 2); + if (maxIndexBuf <= maxRead) { + ljam(); + uchar* dstPtr = (uchar*)&outBuffer[indexBuf]; + const uchar* srcPtr = (uchar*)&tTupleHeader[readOffset]; + const char* ssrcPtr = (const char*)srcPtr; + // could verify data format optionally + if (true || + (*cs->cset->well_formed_len)(cs, ssrcPtr, ssrcPtr + srcBytes, ZNIL) == srcBytes) { + ljam(); + // normalize + Uint32 n = (*cs->coll->strnxfrm)(cs, dstPtr, dstLen, srcPtr, srcBytes); + while ((n & 3) != 0) { + dstPtr[n++] = 0; + } + Uint32 dstWords = (n >> 2); + ahOut->setDataSize(dstWords); + Uint32 newIndexBuf = indexBuf + dstWords; + ndbrequire(newIndexBuf <= maxRead); + tOutBufIndex = newIndexBuf; + return true; + } else { + ljam(); + terrorCode = ZTUPLE_CORRUPTED_ERROR; + } + } else { + ljam(); + terrorCode = ZTRY_TO_READ_TOO_MUCH_ERROR; + } + } + return false; }//Dbtup::readFixedSizeTHManyWordNotNULL() bool @@ -402,7 +447,6 @@ Dbtup::readFixedSizeTHManyWordNULLable(Uint32* outBuffer, Uint32 attrDescriptor, Uint32 attrDes2) { -ljam(); if (!nullFlagCheck(attrDes2)) { ljam(); return readFixedSizeTHManyWordNotNULL(outBuffer, @@ -563,74 +607,6 @@ Dbtup::readDynSmallVarSize(Uint32* outBuffer, return false; }//Dbtup::readDynSmallVarSize() - -bool -Dbtup::readCharNotNULL(Uint32* outBuffer, - AttributeHeader* ahOut, - Uint32 attrDescriptor, - Uint32 attrDes2) -{ - Uint32 indexBuf = tOutBufIndex; - Uint32 readOffset = AttributeOffset::getOffset(attrDes2); - Uint32 attrNoOfWords = AttributeDescriptor::getSizeInWords(attrDescriptor); - Uint32 newIndexBuf = indexBuf + attrNoOfWords; - Uint32 maxRead = tMaxRead; - - ndbrequire((readOffset + attrNoOfWords - 1) < tCheckOffset); - if (newIndexBuf <= maxRead) { - ljam(); - ahOut->setDataSize(attrNoOfWords); - if (! tXfrmFlag) { - MEMCOPY_NO_WORDS(&outBuffer[indexBuf], - &tTupleHeader[readOffset], - attrNoOfWords); - } else { - ljam(); - Tablerec* regTabPtr = tabptr.p; - Uint32 i = AttributeOffset::getCharsetPos(attrDes2); - ndbrequire(i < tabptr.p->noOfCharsets); - // not const in MySQL - CHARSET_INFO* cs = tabptr.p->charsetArray[i]; - // XXX should strip Uint32 null padding - const unsigned nBytes = attrNoOfWords << 2; - unsigned n = - (*cs->coll->strnxfrm)(cs, - (uchar*)&outBuffer[indexBuf], - nBytes, - (const uchar*)&tTupleHeader[readOffset], - nBytes); - // pad with ascii spaces - while (n < nBytes) - ((uchar*)&outBuffer[indexBuf])[n++] = 0x20; - } - tOutBufIndex = newIndexBuf; - return true; - } else { - ljam(); - terrorCode = ZTRY_TO_READ_TOO_MUCH_ERROR; - return false; - } -} - -bool -Dbtup::readCharNULLable(Uint32* outBuffer, - AttributeHeader* ahOut, - Uint32 attrDescriptor, - Uint32 attrDes2) -{ - if (!nullFlagCheck(attrDes2)) { - ljam(); - return readCharNotNULL(outBuffer, - ahOut, - attrDescriptor, - attrDes2); - } else { - ljam(); - ahOut->setNULL(); - return true; - } -} - /* ---------------------------------------------------------------------- */ /* THIS ROUTINE IS USED TO UPDATE A NUMBER OF ATTRIBUTES. IT IS */ /* USED BY THE INSERT ROUTINE, THE UPDATE ROUTINE AND IT CAN BE */ @@ -818,6 +794,7 @@ Dbtup::updateFixedSizeTHManyWordNotNULL(Uint32* inBuffer, Uint32 indexBuf = tInBufIndex; Uint32 inBufLen = tInBufLen; Uint32 updateOffset = AttributeOffset::getOffset(attrDes2); + Uint32 charsetFlag = AttributeOffset::getCharsetFlag(attrDes2); AttributeHeader ahIn(inBuffer[indexBuf]); Uint32 nullIndicator = ahIn.isNULL(); Uint32 noOfWords = AttributeDescriptor::getSizeInWords(attrDescriptor); @@ -827,6 +804,21 @@ Dbtup::updateFixedSizeTHManyWordNotNULL(Uint32* inBuffer, if (newIndex <= inBufLen) { if (!nullIndicator) { ljam(); + if (charsetFlag) { + ljam(); + Tablerec* regTabPtr = tabptr.p; + Uint32 bytes = AttributeDescriptor::getSizeInBytes(attrDescriptor); + Uint32 i = AttributeOffset::getCharsetPos(attrDes2); + ndbrequire(i < regTabPtr->noOfCharsets); + // not const in MySQL + CHARSET_INFO* cs = regTabPtr->charsetArray[i]; + const char* ssrc = (const char*)&inBuffer[tInBufIndex + 1]; + if ((*cs->cset->well_formed_len)(cs, ssrc, ssrc + bytes, ZNIL) != bytes) { + ljam(); + terrorCode = ZINVALID_CHAR_FORMAT; + return false; + } + } tInBufIndex = newIndex; MEMCOPY_NO_WORDS(&tTupleHeader[updateOffset], &inBuffer[indexBuf + 1], @@ -1012,6 +1004,13 @@ Dbtup::read_psuedo(Uint32 attrId, Uint32* outBuffer){ outBuffer[0] = signal->theData[0]; outBuffer[1] = signal->theData[1]; return 2; + case AttributeHeader::RANGE_NO: + signal->theData[0] = operPtr.p->userpointer; + signal->theData[1] = attrId; + + EXECUTE_DIRECT(DBLQH, GSN_READ_PSUEDO_REQ, signal, 2); + outBuffer[0] = signal->theData[0]; + return 1; default: return 0; } diff --git a/ndb/src/kernel/blocks/dbtup/DbtupTrigger.cpp b/ndb/src/kernel/blocks/dbtup/DbtupTrigger.cpp index aac5c326cad..476a4b5724b 100644 --- a/ndb/src/kernel/blocks/dbtup/DbtupTrigger.cpp +++ b/ndb/src/kernel/blocks/dbtup/DbtupTrigger.cpp @@ -753,7 +753,7 @@ bool Dbtup::readTriggerInfo(TupTriggerData* const trigPtr, regTabPtr->noOfKeyAttr, keyBuffer, ZATTR_BUFFER_SIZE, - true); + false); ndbrequire(ret != -1); noPrimKey= ret; @@ -796,7 +796,7 @@ bool Dbtup::readTriggerInfo(TupTriggerData* const trigPtr, numAttrsToRead, mainBuffer, ZATTR_BUFFER_SIZE, - true); + false); ndbrequire(ret != -1); noMainWords= ret; } else { @@ -822,7 +822,7 @@ bool Dbtup::readTriggerInfo(TupTriggerData* const trigPtr, numAttrsToRead, copyBuffer, ZATTR_BUFFER_SIZE, - true); + false); ndbrequire(ret != -1); noCopyWords = ret; diff --git a/ndb/src/kernel/blocks/dbtux/Dbtux.hpp b/ndb/src/kernel/blocks/dbtux/Dbtux.hpp index b9cb179c6b2..79da3af5de4 100644 --- a/ndb/src/kernel/blocks/dbtux/Dbtux.hpp +++ b/ndb/src/kernel/blocks/dbtux/Dbtux.hpp @@ -406,6 +406,7 @@ private: Uint32 m_accLockOp; Uint8 m_readCommitted; // no locking Uint8 m_lockMode; + Uint8 m_descending; ScanBound m_boundMin; ScanBound m_boundMax; ScanBound* m_bound[2]; // pointers to above 2 @@ -638,7 +639,7 @@ private: void execACCKEYREF(Signal* signal); void execACC_ABORTCONF(Signal* signal); void scanFirst(ScanOpPtr scanPtr); - void scanNext(ScanOpPtr scanPtr); + void scanNext(ScanOpPtr scanPtr, bool fromMaintReq); bool scanVisible(ScanOpPtr scanPtr, TreeEnt ent); void scanClose(Signal* signal, ScanOpPtr scanPtr); void addAccLockOp(ScanOp& scan, Uint32 accLockOp); @@ -650,7 +651,9 @@ private: */ void searchToAdd(Frag& frag, ConstData searchKey, TreeEnt searchEnt, TreePos& treePos); void searchToRemove(Frag& frag, ConstData searchKey, TreeEnt searchEnt, TreePos& treePos); - void searchToScan(Frag& frag, ConstData boundInfo, unsigned boundCount, TreePos& treePos); + void searchToScan(Frag& frag, ConstData boundInfo, unsigned boundCount, bool descending, TreePos& treePos); + void searchToScanAscending(Frag& frag, ConstData boundInfo, unsigned boundCount, TreePos& treePos); + void searchToScanDescending(Frag& frag, ConstData boundInfo, unsigned boundCount, TreePos& treePos); /* * DbtuxCmp.cpp @@ -1029,6 +1032,7 @@ Dbtux::ScanOp::ScanOp(ScanBoundPool& scanBoundPool) : m_accLockOp(RNIL), m_readCommitted(0), m_lockMode(0), + m_descending(0), m_boundMin(scanBoundPool), m_boundMax(scanBoundPool), m_scanPos(), diff --git a/ndb/src/kernel/blocks/dbtux/DbtuxCmp.cpp b/ndb/src/kernel/blocks/dbtux/DbtuxCmp.cpp index ddab77b97b5..cf815b14c1a 100644 --- a/ndb/src/kernel/blocks/dbtux/DbtuxCmp.cpp +++ b/ndb/src/kernel/blocks/dbtux/DbtuxCmp.cpp @@ -18,24 +18,26 @@ #include "Dbtux.hpp" /* - * Search key vs node prefix or entry + * Search key vs node prefix or entry. * * The comparison starts at given attribute position. The position is * updated by number of equal initial attributes found. The entry data * may be partial in which case CmpUnknown may be returned. + * + * The attributes are normalized and have variable size given in words. */ int Dbtux::cmpSearchKey(const Frag& frag, unsigned& start, ConstData searchKey, ConstData entryData, unsigned maxlen) { const unsigned numAttrs = frag.m_numAttrs; const DescEnt& descEnt = getDescEnt(frag.m_descPage, frag.m_descOff); - // number of words of attribute data left - unsigned len2 = maxlen; // skip to right position in search key only for (unsigned i = 0; i < start; i++) { jam(); searchKey += AttributeHeaderSize + searchKey.ah().getDataSize(); } + // number of words of entry data left + unsigned len2 = maxlen; int ret = 0; while (start < numAttrs) { if (len2 <= AttributeHeaderSize) { @@ -47,18 +49,20 @@ Dbtux::cmpSearchKey(const Frag& frag, unsigned& start, ConstData searchKey, Cons if (! searchKey.ah().isNULL()) { if (! entryData.ah().isNULL()) { jam(); - // current attribute + // verify attribute id const DescAttr& descAttr = descEnt.m_descAttr[start]; - // full data size - const unsigned size1 = AttributeDescriptor::getSizeInWords(descAttr.m_attrDesc); - ndbrequire(size1 != 0 && size1 == entryData.ah().getDataSize()); - const unsigned size2 = min(size1, len2); + ndbrequire(searchKey.ah().getAttributeId() == descAttr.m_primaryAttrId); + ndbrequire(entryData.ah().getAttributeId() == descAttr.m_primaryAttrId); + // sizes + const unsigned size1 = searchKey.ah().getDataSize(); + const unsigned size2 = min(entryData.ah().getDataSize(), len2); len2 -= size2; // compare NdbSqlUtil::Cmp* const cmp = c_sqlCmp[start]; const Uint32* const p1 = &searchKey[AttributeHeaderSize]; const Uint32* const p2 = &entryData[AttributeHeaderSize]; - ret = (*cmp)(0, p1, p2, size1, size2); + const bool full = (maxlen == MaxAttrDataSize); + ret = (*cmp)(0, p1, size1 << 2, p2, size2 << 2, full); if (ret != 0) { jam(); break; @@ -99,18 +103,20 @@ Dbtux::cmpSearchKey(const Frag& frag, unsigned& start, ConstData searchKey, Cons * * Following example illustrates this. We are at (a=2, b=3). * - * dir bounds strict return + * idir bounds strict return * 0 a >= 2 and b >= 3 no -1 * 0 a >= 2 and b > 3 yes +1 * 1 a <= 2 and b <= 3 no +1 * 1 a <= 2 and b < 3 yes -1 + * + * The attributes are normalized and have variable size given in words. */ int -Dbtux::cmpScanBound(const Frag& frag, unsigned dir, ConstData boundInfo, unsigned boundCount, ConstData entryData, unsigned maxlen) +Dbtux::cmpScanBound(const Frag& frag, unsigned idir, ConstData boundInfo, unsigned boundCount, ConstData entryData, unsigned maxlen) { const DescEnt& descEnt = getDescEnt(frag.m_descPage, frag.m_descOff); // direction 0-lower 1-upper - ndbrequire(dir <= 1); + ndbrequire(idir <= 1); // number of words of data left unsigned len2 = maxlen; // in case of no bounds, init last type to something non-strict @@ -127,21 +133,21 @@ Dbtux::cmpScanBound(const Frag& frag, unsigned dir, ConstData boundInfo, unsigne if (! boundInfo.ah().isNULL()) { if (! entryData.ah().isNULL()) { jam(); - // current attribute - const unsigned index = boundInfo.ah().getAttributeId(); + // verify attribute id + const Uint32 index = boundInfo.ah().getAttributeId(); ndbrequire(index < frag.m_numAttrs); const DescAttr& descAttr = descEnt.m_descAttr[index]; ndbrequire(entryData.ah().getAttributeId() == descAttr.m_primaryAttrId); - // full data size + // sizes const unsigned size1 = boundInfo.ah().getDataSize(); - ndbrequire(size1 != 0 && size1 == entryData.ah().getDataSize()); - const unsigned size2 = min(size1, len2); + const unsigned size2 = min(entryData.ah().getDataSize(), len2); len2 -= size2; // compare NdbSqlUtil::Cmp* const cmp = c_sqlCmp[index]; const Uint32* const p1 = &boundInfo[AttributeHeaderSize]; const Uint32* const p2 = &entryData[AttributeHeaderSize]; - int ret = (*cmp)(0, p1, p2, size1, size2); + const bool full = (maxlen == MaxAttrDataSize); + int ret = (*cmp)(0, p1, size1 << 2, p2, size2 << 2, full); if (ret != 0) { jam(); return ret; @@ -165,5 +171,5 @@ Dbtux::cmpScanBound(const Frag& frag, unsigned dir, ConstData boundInfo, unsigne } // all attributes were equal const int strict = (type & 0x1); - return (dir == 0 ? (strict == 0 ? -1 : +1) : (strict == 0 ? +1 : -1)); + return (idir == 0 ? (strict == 0 ? -1 : +1) : (strict == 0 ? +1 : -1)); } diff --git a/ndb/src/kernel/blocks/dbtux/DbtuxDebug.cpp b/ndb/src/kernel/blocks/dbtux/DbtuxDebug.cpp index 3c2613c6cd1..ed29dc57915 100644 --- a/ndb/src/kernel/blocks/dbtux/DbtuxDebug.cpp +++ b/ndb/src/kernel/blocks/dbtux/DbtuxDebug.cpp @@ -340,13 +340,14 @@ operator<<(NdbOut& out, const Dbtux::ScanOp& scan) out << " [savePointId " << dec << scan.m_savePointId << "]"; out << " [accLockOp " << hex << scan.m_accLockOp << "]"; out << " [accLockOps"; - for (unsigned i = 0; i < Dbtux::MaxAccLockOps; i++) { + for (unsigned i = 0; i < scan.m_maxAccLockOps; i++) { if (scan.m_accLockOps[i] != RNIL) out << " " << hex << scan.m_accLockOps[i]; } out << "]"; out << " [readCommitted " << dec << scan.m_readCommitted << "]"; out << " [lockMode " << dec << scan.m_lockMode << "]"; + out << " [descending " << dec << scan.m_descending << "]"; out << " [pos " << scan.m_scanPos << "]"; out << " [ent " << scan.m_scanEnt << "]"; for (unsigned i = 0; i <= 1; i++) { diff --git a/ndb/src/kernel/blocks/dbtux/DbtuxGen.cpp b/ndb/src/kernel/blocks/dbtux/DbtuxGen.cpp index 8990d6c86b6..e9c3027dfc0 100644 --- a/ndb/src/kernel/blocks/dbtux/DbtuxGen.cpp +++ b/ndb/src/kernel/blocks/dbtux/DbtuxGen.cpp @@ -217,6 +217,7 @@ Dbtux::setKeyAttrs(const Frag& frag) const unsigned numAttrs = frag.m_numAttrs; const DescEnt& descEnt = getDescEnt(frag.m_descPage, frag.m_descOff); for (unsigned i = 0; i < numAttrs; i++) { + jam(); const DescAttr& descAttr = descEnt.m_descAttr[i]; Uint32 size = AttributeDescriptor::getSizeInWords(descAttr.m_attrDesc); // set attr id and fixed size @@ -244,6 +245,26 @@ Dbtux::readKeyAttrs(const Frag& frag, TreeEnt ent, unsigned start, Data keyData) jamEntry(); // TODO handle error ndbrequire(ret > 0); +#ifdef VM_TRACE + if (debugFlags & (DebugMaint | DebugScan)) { + debugOut << "readKeyAttrs:" << endl; + ConstData data = keyData; + Uint32 totalSize = 0; + for (Uint32 i = start; i < numAttrs; i++) { + Uint32 attrId = data.ah().getAttributeId(); + Uint32 dataSize = data.ah().getDataSize(); + debugOut << i << " attrId=" << attrId << " size=" << dataSize; + data += 1; + for (Uint32 j = 0; j < dataSize; j++) { + debugOut << " " << hex << data[0]; + data += 1; + } + debugOut << endl; + totalSize += 1 + dataSize; + } + ndbassert(totalSize == ret); + } +#endif } void @@ -251,7 +272,7 @@ Dbtux::readTablePk(const Frag& frag, TreeEnt ent, Data pkData, unsigned& pkSize) { const Uint32 tableFragPtrI = frag.m_tupTableFragPtrI[ent.m_fragBit]; const TupLoc tupLoc = ent.m_tupLoc; - int ret = c_tup->tuxReadPk(tableFragPtrI, tupLoc.getPageId(), tupLoc.getPageOffset(), pkData); + int ret = c_tup->tuxReadPk(tableFragPtrI, tupLoc.getPageId(), tupLoc.getPageOffset(), pkData, true); jamEntry(); // TODO handle error ndbrequire(ret > 0); diff --git a/ndb/src/kernel/blocks/dbtux/DbtuxMaint.cpp b/ndb/src/kernel/blocks/dbtux/DbtuxMaint.cpp index 2d256487dcc..4b568badc67 100644 --- a/ndb/src/kernel/blocks/dbtux/DbtuxMaint.cpp +++ b/ndb/src/kernel/blocks/dbtux/DbtuxMaint.cpp @@ -59,7 +59,6 @@ Dbtux::execTUX_MAINT_REQ(Signal* signal) // get base fragment id and extra bits const Uint32 fragId = req->fragId & ~1; const Uint32 fragBit = req->fragId & 1; - // get the fragment FragPtr fragPtr; fragPtr.i = RNIL; @@ -71,7 +70,6 @@ Dbtux::execTUX_MAINT_REQ(Signal* signal) break; } } - ndbrequire(fragPtr.i != RNIL); Frag& frag = *fragPtr.p; // set up index keys for this operation diff --git a/ndb/src/kernel/blocks/dbtux/DbtuxMeta.cpp b/ndb/src/kernel/blocks/dbtux/DbtuxMeta.cpp index cee4aaa8625..93c4a583624 100644 --- a/ndb/src/kernel/blocks/dbtux/DbtuxMeta.cpp +++ b/ndb/src/kernel/blocks/dbtux/DbtuxMeta.cpp @@ -16,6 +16,7 @@ #define DBTUX_META_CPP #include "Dbtux.hpp" +#include <my_sys.h> /* * Create index. @@ -200,7 +201,7 @@ Dbtux::execTUX_ADD_ATTRREQ(Signal* signal) DescAttr& descAttr = descEnt.m_descAttr[attrId]; descAttr.m_attrDesc = req->attrDescriptor; descAttr.m_primaryAttrId = req->primaryAttrId; - descAttr.m_typeId = req->extTypeInfo & 0xFF; + descAttr.m_typeId = AttributeDescriptor::getType(req->attrDescriptor); descAttr.m_charset = (req->extTypeInfo >> 16); #ifdef VM_TRACE if (debugFlags & DebugMeta) { @@ -215,17 +216,15 @@ Dbtux::execTUX_ADD_ATTRREQ(Signal* signal) errorCode = TuxAddAttrRef::InvalidAttributeType; break; } -#ifdef dbtux_uses_charset if (descAttr.m_charset != 0) { - CHARSET_INFO *cs = get_charset(descAttr.m_charset, MYF(0)); - // here use the non-binary type + CHARSET_INFO *cs = all_charsets[descAttr.m_charset]; + ndbrequire(cs != 0); if (! NdbSqlUtil::usable_in_ordered_index(descAttr.m_typeId, cs)) { jam(); errorCode = TuxAddAttrRef::InvalidCharset; break; } } -#endif const bool lastAttr = (indexPtr.p->m_numAttrs == fragOpPtr.p->m_numAttrsRecvd); if (ERROR_INSERTED(12003) && fragOpPtr.p->m_fragNo == 0 && attrId == 0 || ERROR_INSERTED(12004) && fragOpPtr.p->m_fragNo == 0 && lastAttr || diff --git a/ndb/src/kernel/blocks/dbtux/DbtuxNode.cpp b/ndb/src/kernel/blocks/dbtux/DbtuxNode.cpp index 389192fd0cf..855a8ed1c29 100644 --- a/ndb/src/kernel/blocks/dbtux/DbtuxNode.cpp +++ b/ndb/src/kernel/blocks/dbtux/DbtuxNode.cpp @@ -491,7 +491,7 @@ Dbtux::moveScanList(NodeHandle& node, unsigned pos) debugOut << "At pos=" << pos << " " << node << endl; } #endif - scanNext(scanPtr); + scanNext(scanPtr, true); ndbrequire(! (scanPos.m_loc == node.m_loc && scanPos.m_pos == pos)); } scanPtr.i = nextPtrI; diff --git a/ndb/src/kernel/blocks/dbtux/DbtuxScan.cpp b/ndb/src/kernel/blocks/dbtux/DbtuxScan.cpp index 31a11a5c16b..84081e76a8c 100644 --- a/ndb/src/kernel/blocks/dbtux/DbtuxScan.cpp +++ b/ndb/src/kernel/blocks/dbtux/DbtuxScan.cpp @@ -16,6 +16,7 @@ #define DBTUX_SCAN_CPP #include "Dbtux.hpp" +#include <my_sys.h> void Dbtux::execACC_SCANREQ(Signal* signal) @@ -73,17 +74,18 @@ Dbtux::execACC_SCANREQ(Signal* signal) scanPtr.p->m_savePointId = req->savePointId; scanPtr.p->m_readCommitted = AccScanReq::getReadCommittedFlag(req->requestInfo); scanPtr.p->m_lockMode = AccScanReq::getLockMode(req->requestInfo); -#ifdef VM_TRACE - if (debugFlags & DebugScan) { - debugOut << "Seize scan " << scanPtr.i << " " << *scanPtr.p << endl; - } -#endif + scanPtr.p->m_descending = AccScanReq::getDescendingFlag(req->requestInfo); /* * readCommitted lockMode keyInfo * 1 0 0 - read committed (no lock) * 0 0 0 - read latest (read lock) * 0 1 1 - read exclusive (write lock) */ +#ifdef VM_TRACE + if (debugFlags & DebugScan) { + debugOut << "Seize scan " << scanPtr.i << " " << *scanPtr.p << endl; + } +#endif // conf AccScanConf* const conf = (AccScanConf*)signal->getDataPtrSend(); conf->scanPtr = req->senderData; @@ -112,50 +114,89 @@ Dbtux::execACC_SCANREQ(Signal* signal) * keys and that all but possibly last bound is non-strict. * * Finally save the sets of lower and upper bounds (i.e. start key and - * end key). Full bound type (< 4) is included but only the strict bit - * is used since lower and upper have now been separated. + * end key). Full bound type is included but only the strict bit is + * used since lower and upper have now been separated. */ void Dbtux::execTUX_BOUND_INFO(Signal* signal) { jamEntry(); - struct BoundInfo { - int type; - unsigned offset; - unsigned size; - }; - TuxBoundInfo* const sig = (TuxBoundInfo*)signal->getDataPtrSend(); - const TuxBoundInfo reqCopy = *(const TuxBoundInfo*)sig; - const TuxBoundInfo* const req = &reqCopy; // get records + TuxBoundInfo* const sig = (TuxBoundInfo*)signal->getDataPtrSend(); + const TuxBoundInfo* const req = (const TuxBoundInfo*)sig; ScanOp& scan = *c_scanOpPool.getPtr(req->tuxScanPtrI); - Index& index = *c_indexPool.getPtr(scan.m_indexId); - // collect lower and upper bounds + const Index& index = *c_indexPool.getPtr(scan.m_indexId); + const DescEnt& descEnt = getDescEnt(index.m_descPage, index.m_descOff); + // collect normalized lower and upper bounds + struct BoundInfo { + int type2; // with EQ -> LE/GE + Uint32 offset; // offset in xfrmData + Uint32 size; + }; BoundInfo boundInfo[2][MaxIndexAttributes]; + const unsigned dstSize = 1024 * MAX_XFRM_MULTIPLY; + Uint32 xfrmData[dstSize]; + Uint32 dstPos = 0; // largest attrId seen plus one Uint32 maxAttrId[2] = { 0, 0 }; - unsigned offset = 0; - const Uint32* const data = (Uint32*)sig + TuxBoundInfo::SignalLength; // walk through entries + const Uint32* const data = (Uint32*)sig + TuxBoundInfo::SignalLength; + Uint32 offset = 0; while (offset + 2 <= req->boundAiLength) { jam(); const unsigned type = data[offset]; - if (type > 4) { - jam(); - scan.m_state = ScanOp::Invalid; - sig->errorCode = TuxBoundInfo::InvalidAttrInfo; - return; - } const AttributeHeader* ah = (const AttributeHeader*)&data[offset + 1]; const Uint32 attrId = ah->getAttributeId(); const Uint32 dataSize = ah->getDataSize(); - if (attrId >= index.m_numAttrs) { + if (type > 4 || attrId >= index.m_numAttrs || dstPos + 2 + dataSize > dstSize) { jam(); scan.m_state = ScanOp::Invalid; sig->errorCode = TuxBoundInfo::InvalidAttrInfo; return; } + // copy header + xfrmData[dstPos + 0] = data[offset + 0]; + xfrmData[dstPos + 1] = data[offset + 1]; + // copy bound value + Uint32 dstWords = 0; + if (! ah->isNULL()) { + jam(); + const DescAttr& descAttr = descEnt.m_descAttr[attrId]; + Uint32 srcBytes = AttributeDescriptor::getSizeInBytes(descAttr.m_attrDesc); + Uint32 srcWords = (srcBytes + 3) / 4; + if (srcWords != dataSize) { + jam(); + scan.m_state = ScanOp::Invalid; + sig->errorCode = TuxBoundInfo::InvalidAttrInfo; + return; + } + uchar* dstPtr = (uchar*)&xfrmData[dstPos + 2]; + const uchar* srcPtr = (const uchar*)&data[offset + 2]; + if (descAttr.m_charset == 0) { + memcpy(dstPtr, srcPtr, srcWords << 2); + dstWords = srcWords; + } else { + jam(); + CHARSET_INFO* cs = all_charsets[descAttr.m_charset]; + Uint32 xmul = cs->strxfrm_multiply; + if (xmul == 0) + xmul = 1; + Uint32 dstLen = xmul * srcBytes; + if (dstLen > ((dstSize - dstPos) << 2)) { + jam(); + scan.m_state = ScanOp::Invalid; + sig->errorCode = TuxBoundInfo::TooMuchAttrInfo; + return; + } + Uint32 n = (*cs->coll->strnxfrm)(cs, dstPtr, dstLen, srcPtr, srcBytes); + while ((n & 3) != 0) { + dstPtr[n++] = 0; + } + dstWords = n / 4; + } + } for (unsigned j = 0; j <= 1; j++) { + jam(); // check if lower/upper bit matches const unsigned luBit = (j << 1); if ((type & 0x2) != luBit && type != 4) @@ -164,29 +205,35 @@ Dbtux::execTUX_BOUND_INFO(Signal* signal) const unsigned type2 = (type & 0x1) | luBit; // fill in any gap while (maxAttrId[j] <= attrId) { + jam(); BoundInfo& b = boundInfo[j][maxAttrId[j]++]; - b.type = -1; + b.type2 = -1; } BoundInfo& b = boundInfo[j][attrId]; - if (b.type != -1) { - // compare with previous bound - if (b.type != (int)type2 || - b.size != 2 + dataSize || - memcmp(&data[b.offset + 2], &data[offset + 2], dataSize << 2) != 0) { + if (b.type2 != -1) { + // compare with previously defined bound + if (b.type2 != (int)type2 || + b.size != 2 + dstWords || + memcmp(&xfrmData[b.offset + 2], &xfrmData[dstPos + 2], dstWords << 2) != 0) { jam(); scan.m_state = ScanOp::Invalid; sig->errorCode = TuxBoundInfo::InvalidBounds; return; } } else { + // fix length + AttributeHeader* ah = (AttributeHeader*)&xfrmData[dstPos + 1]; + ah->setDataSize(dstWords); // enter new bound - b.type = type2; - b.offset = offset; - b.size = 2 + dataSize; + jam(); + b.type2 = type2; + b.offset = dstPos; + b.size = 2 + dstWords; } } // jump to next offset += 2 + dataSize; + dstPos += 2 + dstWords; } if (offset != req->boundAiLength) { jam(); @@ -200,13 +247,13 @@ Dbtux::execTUX_BOUND_INFO(Signal* signal) jam(); const BoundInfo& b = boundInfo[j][i]; // check for gap or strict bound before last - if (b.type == -1 || (i + 1 < maxAttrId[j] && (b.type & 0x1))) { + if (b.type2 == -1 || (i + 1 < maxAttrId[j] && (b.type2 & 0x1))) { jam(); scan.m_state = ScanOp::Invalid; sig->errorCode = TuxBoundInfo::InvalidBounds; return; } - bool ok = scan.m_bound[j]->append(&data[b.offset], b.size); + bool ok = scan.m_bound[j]->append(&xfrmData[b.offset], b.size); if (! ok) { jam(); scan.m_state = ScanOp::Invalid; @@ -372,7 +419,7 @@ Dbtux::execACC_CHECK_SCAN(Signal* signal) if (scan.m_state == ScanOp::Next) { jam(); // look for next - scanNext(scanPtr); + scanNext(scanPtr, false); } // for reading tuple key in Current or Locked state Data pkData = c_dataBuffer; @@ -651,8 +698,10 @@ Dbtux::scanFirst(ScanOpPtr scanPtr) TreeHead& tree = frag.m_tree; // set up index keys for this operation setKeyAttrs(frag); - // unpack lower bound into c_dataBuffer - const ScanBound& bound = *scan.m_bound[0]; + // scan direction 0, 1 + const unsigned idir = scan.m_descending; + // unpack start key into c_dataBuffer + const ScanBound& bound = *scan.m_bound[idir]; ScanBoundIterator iter; bound.first(iter); for (unsigned j = 0; j < bound.getSize(); j++) { @@ -660,11 +709,10 @@ Dbtux::scanFirst(ScanOpPtr scanPtr) c_dataBuffer[j] = *iter.data; bound.next(iter); } - // search for scan start position TreePos treePos; - searchToScan(frag, c_dataBuffer, scan.m_boundCnt[0], treePos); + searchToScan(frag, c_dataBuffer, scan.m_boundCnt[idir], scan.m_descending, treePos); if (treePos.m_loc == NullTupLoc) { - // empty tree + // empty result set jam(); scan.m_state = ScanOp::Last; return; @@ -682,7 +730,8 @@ Dbtux::scanFirst(ScanOpPtr scanPtr) * Move to next entry. The scan is already linked to some node. When * we leave, if an entry was found, it will be linked to a possibly * different node. The scan has a position, and a direction which tells - * from where we came to this position. This is one of: + * from where we came to this position. This is one of (all comments + * are in terms of ascending scan): * * 0 - up from left child (scan this node next) * 1 - up from right child (proceed to parent) @@ -694,7 +743,7 @@ Dbtux::scanFirst(ScanOpPtr scanPtr) * re-organizations need not worry about scan direction. */ void -Dbtux::scanNext(ScanOpPtr scanPtr) +Dbtux::scanNext(ScanOpPtr scanPtr, bool fromMaintReq) { ScanOp& scan = *scanPtr.p; Frag& frag = *c_fragPool.getPtr(scan.m_fragPtrI); @@ -707,8 +756,11 @@ Dbtux::scanNext(ScanOpPtr scanPtr) ndbrequire(scan.m_state != ScanOp::Locked); // set up index keys for this operation setKeyAttrs(frag); - // unpack upper bound into c_dataBuffer - const ScanBound& bound = *scan.m_bound[1]; + // scan direction + const unsigned idir = scan.m_descending; // 0, 1 + const int jdir = 1 - 2 * (int)idir; // 1, -1 + // unpack end key into c_dataBuffer + const ScanBound& bound = *scan.m_bound[1 - idir]; ScanBoundIterator iter; bound.first(iter); for (unsigned j = 0; j < bound.getSize(); j++) { @@ -728,6 +780,11 @@ Dbtux::scanNext(ScanOpPtr scanPtr) TreeEnt ent; while (true) { jam(); +#ifdef VM_TRACE + if (debugFlags & DebugScan) { + debugOut << "Scan next pos " << pos << " " << node << endl; + } +#endif if (pos.m_dir == 2) { // coming up from root ends the scan jam(); @@ -742,7 +799,7 @@ Dbtux::scanNext(ScanOpPtr scanPtr) if (pos.m_dir == 4) { // coming down from parent proceed to left child jam(); - TupLoc loc = node.getLink(0); + TupLoc loc = node.getLink(idir); if (loc != NullTupLoc) { jam(); pos.m_loc = loc; @@ -750,34 +807,42 @@ Dbtux::scanNext(ScanOpPtr scanPtr) continue; } // pretend we came from left child - pos.m_dir = 0; + pos.m_dir = idir; + } + const unsigned occup = node.getOccup(); + if (occup == 0) { + jam(); + ndbrequire(fromMaintReq); + // move back to parent - see comment in treeRemoveInner + pos.m_loc = node.getLink(2); + pos.m_dir = node.getSide(); + continue; } - if (pos.m_dir == 0) { + if (pos.m_dir == idir) { // coming up from left child scan current node jam(); - pos.m_pos = 0; + pos.m_pos = idir == 0 ? 0 : occup - 1; pos.m_match = false; pos.m_dir = 3; } if (pos.m_dir == 3) { // within node jam(); - unsigned occup = node.getOccup(); - ndbrequire(occup >= 1); // advance position if (! pos.m_match) pos.m_match = true; else - pos.m_pos++; + // becomes ZNIL (which is > occup) if 0 and scan descending + pos.m_pos += jdir; if (pos.m_pos < occup) { jam(); ent = node.getEnt(pos.m_pos); pos.m_dir = 3; // unchanged // read and compare all attributes readKeyAttrs(frag, ent, 0, c_entryKey); - int ret = cmpScanBound(frag, 1, c_dataBuffer, scan.m_boundCnt[1], c_entryKey); + int ret = cmpScanBound(frag, 1 - idir, c_dataBuffer, scan.m_boundCnt[1 - idir], c_entryKey); ndbrequire(ret != NdbSqlUtil::CmpUnknown); - if (ret < 0) { + if (jdir * ret < 0) { jam(); // hit upper bound of single range scan pos.m_loc = NullTupLoc; @@ -794,7 +859,7 @@ Dbtux::scanNext(ScanOpPtr scanPtr) break; } // after node proceed to right child - TupLoc loc = node.getLink(1); + TupLoc loc = node.getLink(1 - idir); if (loc != NullTupLoc) { jam(); pos.m_loc = loc; @@ -802,9 +867,9 @@ Dbtux::scanNext(ScanOpPtr scanPtr) continue; } // pretend we came from right child - pos.m_dir = 1; + pos.m_dir = 1 - idir; } - if (pos.m_dir == 1) { + if (pos.m_dir == 1 - idir) { // coming up from right child proceed to parent jam(); pos.m_loc = node.getLink(2); diff --git a/ndb/src/kernel/blocks/dbtux/DbtuxSearch.cpp b/ndb/src/kernel/blocks/dbtux/DbtuxSearch.cpp index 7057d74c3ad..b0e2a664bfd 100644 --- a/ndb/src/kernel/blocks/dbtux/DbtuxSearch.cpp +++ b/ndb/src/kernel/blocks/dbtux/DbtuxSearch.cpp @@ -253,22 +253,33 @@ Dbtux::searchToRemove(Frag& frag, ConstData searchKey, TreeEnt searchEnt, TreePo /* * Search for scan start position. * - * Similar to searchToAdd. + * Similar to searchToAdd. The routines differ somewhat depending on + * scan direction and are done by separate methods. */ void -Dbtux::searchToScan(Frag& frag, ConstData boundInfo, unsigned boundCount, TreePos& treePos) +Dbtux::searchToScan(Frag& frag, ConstData boundInfo, unsigned boundCount, bool descending, TreePos& treePos) { const TreeHead& tree = frag.m_tree; - NodeHandle currNode(frag); - currNode.m_loc = tree.m_root; - if (currNode.m_loc == NullTupLoc) { - // empty tree - jam(); - treePos.m_match = false; + if (tree.m_root != NullTupLoc) { + if (! descending) + searchToScanAscending(frag, boundInfo, boundCount, treePos); + else + searchToScanDescending(frag, boundInfo, boundCount, treePos); return; } + // empty tree +} + +void +Dbtux::searchToScanAscending(Frag& frag, ConstData boundInfo, unsigned boundCount, TreePos& treePos) +{ + const TreeHead& tree = frag.m_tree; + NodeHandle currNode(frag); + currNode.m_loc = tree.m_root; NodeHandle glbNode(frag); // potential g.l.b of final node NodeHandle bottomNode(frag); + // always before entry + treePos.m_match = false; while (true) { jam(); selectNode(currNode, currNode.m_loc); @@ -283,6 +294,7 @@ Dbtux::searchToScan(Frag& frag, ConstData boundInfo, unsigned boundCount, TreePo ndbrequire(ret != NdbSqlUtil::CmpUnknown); } if (ret < 0) { + // bound is left of this node jam(); const TupLoc loc = currNode.getLink(0); if (loc != NullTupLoc) { @@ -300,11 +312,11 @@ Dbtux::searchToScan(Frag& frag, ConstData boundInfo, unsigned boundCount, TreePo // start scanning this node treePos.m_loc = currNode.m_loc; treePos.m_pos = 0; - treePos.m_match = false; treePos.m_dir = 3; return; } } else if (ret > 0) { + // bound is at or right of this node jam(); const TupLoc loc = currNode.getLink(1); if (loc != NullTupLoc) { @@ -316,7 +328,7 @@ Dbtux::searchToScan(Frag& frag, ConstData boundInfo, unsigned boundCount, TreePo continue; } } else { - ndbassert(false); + ndbrequire(false); } break; } @@ -328,20 +340,19 @@ Dbtux::searchToScan(Frag& frag, ConstData boundInfo, unsigned boundCount, TreePo ret = cmpScanBound(frag, 0, boundInfo, boundCount, c_entryKey); ndbrequire(ret != NdbSqlUtil::CmpUnknown); if (ret < 0) { - // start scanning from current entry + // found first entry satisfying the bound treePos.m_loc = currNode.m_loc; treePos.m_pos = j; - treePos.m_match = false; treePos.m_dir = 3; return; } } + // bound is to right of this node if (! bottomNode.isNull()) { jam(); // start scanning the l.u.b treePos.m_loc = bottomNode.m_loc; treePos.m_pos = 0; - treePos.m_match = false; treePos.m_dir = 3; return; } @@ -349,3 +360,90 @@ Dbtux::searchToScan(Frag& frag, ConstData boundInfo, unsigned boundCount, TreePo treePos.m_loc = currNode.m_loc; treePos.m_dir = 1; } + +void +Dbtux::searchToScanDescending(Frag& frag, ConstData boundInfo, unsigned boundCount, TreePos& treePos) +{ + const TreeHead& tree = frag.m_tree; + NodeHandle currNode(frag); + currNode.m_loc = tree.m_root; + NodeHandle glbNode(frag); // potential g.l.b of final node + NodeHandle bottomNode(frag); + // always before entry + treePos.m_match = false; + while (true) { + jam(); + selectNode(currNode, currNode.m_loc); + int ret; + // compare prefix + ret = cmpScanBound(frag, 1, boundInfo, boundCount, currNode.getPref(), tree.m_prefSize); + if (ret == NdbSqlUtil::CmpUnknown) { + jam(); + // read and compare all attributes + readKeyAttrs(frag, currNode.getMinMax(0), 0, c_entryKey); + ret = cmpScanBound(frag, 1, boundInfo, boundCount, c_entryKey); + ndbrequire(ret != NdbSqlUtil::CmpUnknown); + } + if (ret < 0) { + // bound is left of this node + jam(); + const TupLoc loc = currNode.getLink(0); + if (loc != NullTupLoc) { + jam(); + // continue to left subtree + currNode.m_loc = loc; + continue; + } + if (! glbNode.isNull()) { + jam(); + // move up to the g.l.b but remember the bottom node + bottomNode = currNode; + currNode = glbNode; + } else { + // empty result set + return; + } + } else if (ret > 0) { + // bound is at or right of this node + jam(); + const TupLoc loc = currNode.getLink(1); + if (loc != NullTupLoc) { + jam(); + // save potential g.l.b + glbNode = currNode; + // continue to right subtree + currNode.m_loc = loc; + continue; + } + } else { + ndbrequire(false); + } + break; + } + for (unsigned j = 0, occup = currNode.getOccup(); j < occup; j++) { + jam(); + int ret; + // read and compare attributes + readKeyAttrs(frag, currNode.getEnt(j), 0, c_entryKey); + ret = cmpScanBound(frag, 1, boundInfo, boundCount, c_entryKey); + ndbrequire(ret != NdbSqlUtil::CmpUnknown); + if (ret < 0) { + if (j > 0) { + // start scanning from previous entry + treePos.m_loc = currNode.m_loc; + treePos.m_pos = j - 1; + treePos.m_dir = 3; + return; + } + // start scanning upwards (pretend we came from left child) + treePos.m_loc = currNode.m_loc; + treePos.m_pos = 0; + treePos.m_dir = 0; + return; + } + } + // start scanning this node + treePos.m_loc = currNode.m_loc; + treePos.m_pos = currNode.getOccup() - 1; + treePos.m_dir = 3; +} diff --git a/ndb/src/kernel/blocks/dbtux/DbtuxTree.cpp b/ndb/src/kernel/blocks/dbtux/DbtuxTree.cpp index b9e3b593a00..5107a8d8e31 100644 --- a/ndb/src/kernel/blocks/dbtux/DbtuxTree.cpp +++ b/ndb/src/kernel/blocks/dbtux/DbtuxTree.cpp @@ -226,6 +226,9 @@ Dbtux::treeRemoveInner(Frag& frag, NodeHandle lubNode, unsigned pos) // borrow max entry from semi/leaf Uint32 scanList = RNIL; nodePopDown(glbNode, glbNode.getOccup() - 1, ent, &scanList); + // g.l.b may be empty now + // a descending scan may try to enter the empty g.l.b + // we prevent this in scanNext nodePopUp(lubNode, pos, ent, scanList); if (glbNode.getLink(0) != NullTupLoc) { jam(); diff --git a/ndb/src/kernel/blocks/ndbcntr/NdbcntrMain.cpp b/ndb/src/kernel/blocks/ndbcntr/NdbcntrMain.cpp index 089cf613b03..e155a51be08 100644 --- a/ndb/src/kernel/blocks/ndbcntr/NdbcntrMain.cpp +++ b/ndb/src/kernel/blocks/ndbcntr/NdbcntrMain.cpp @@ -1562,13 +1562,9 @@ void Ndbcntr::createSystableLab(Signal* signal, unsigned index) ndbassert(column.pos == i); w.add(DictTabInfo::AttributeName, column.name); w.add(DictTabInfo::AttributeId, (Uint32)column.pos); - //w.add(DictTabInfo::AttributeType, DictTabInfo::UnSignedType); - //w.add(DictTabInfo::AttributeSize, DictTabInfo::a32Bit); - //w.add(DictTabInfo::AttributeArraySize, 1); w.add(DictTabInfo::AttributeKeyFlag, (Uint32)column.keyFlag); //w.add(DictTabInfo::AttributeStorage, (Uint32)DictTabInfo::MainMemory); w.add(DictTabInfo::AttributeNullableFlag, (Uint32)column.nullable); - // ext type overrides w.add(DictTabInfo::AttributeExtType, (Uint32)column.type); w.add(DictTabInfo::AttributeExtLength, (Uint32)column.length); w.add(DictTabInfo::AttributeEnd, (Uint32)true); diff --git a/ndb/src/kernel/main.cpp b/ndb/src/kernel/main.cpp index 44fe1725c9e..da0c5df7a33 100644 --- a/ndb/src/kernel/main.cpp +++ b/ndb/src/kernel/main.cpp @@ -19,6 +19,7 @@ #include <ndb_version.h> #include "Configuration.hpp" +#include <ConfigRetriever.hpp> #include <TransporterRegistry.hpp> #include "vm/SimBlockList.hpp" @@ -36,6 +37,8 @@ #include <NdbAutoPtr.hpp> +#include <mgmapi_debug.h> + #if defined NDB_SOLARIS // ok #include <sys/processor.h> // For system informatio #endif @@ -88,6 +91,10 @@ int main(int argc, char** argv) return 1; } } + + globalTransporterRegistry.set_mgm_handle(theConfig + ->get_config_retriever() + ->get_mgmHandle()); #ifndef NDB_WIN32 for(pid_t child = fork(); child != 0; child = fork()){ @@ -198,6 +205,17 @@ int main(int argc, char** argv) socket_server.startServer(); + struct ndb_mgm_reply mgm_reply; + for(unsigned int i=0;i<globalTransporterRegistry.m_transporter_interface.size();i++) + ndb_mgm_set_connection_int_parameter(theConfig->get_config_retriever()->get_mgmHandle(), + globalTransporterRegistry.get_localNodeId(), + globalTransporterRegistry.m_transporter_interface[i].m_remote_nodeId, + CFG_CONNECTION_SERVER_PORT, + globalTransporterRegistry.m_transporter_interface[i].m_service_port, + &mgm_reply); + + + // theConfig->closeConfiguration(); globalEmulatorData.theThreadConfig->ipControlLoop(); diff --git a/ndb/src/kernel/vm/Configuration.hpp b/ndb/src/kernel/vm/Configuration.hpp index acf0e163a84..a257881e353 100644 --- a/ndb/src/kernel/vm/Configuration.hpp +++ b/ndb/src/kernel/vm/Configuration.hpp @@ -68,6 +68,7 @@ public: Uint32 get_mgmd_port() const {return m_mgmd_port;}; const char *get_mgmd_host() const {return m_mgmd_host;}; + ConfigRetriever* get_config_retriever() { return m_config_retriever; }; class LogLevel * m_logLevel; private: diff --git a/ndb/src/kernel/vm/MetaData.hpp b/ndb/src/kernel/vm/MetaData.hpp index 11e262664c1..1000114a421 100644 --- a/ndb/src/kernel/vm/MetaData.hpp +++ b/ndb/src/kernel/vm/MetaData.hpp @@ -86,15 +86,9 @@ public: /* Primary table of index otherwise RNIL */ Uint32 primaryTableId; - /* Type of storage (memory/disk, not used) */ - DictTabInfo::StorageType storageType; - /* Type of fragmentation (small/medium/large) */ DictTabInfo::FragmentType fragmentType; - /* Key type of fragmentation (pk/dist key/dist group) */ - DictTabInfo::FragmentKeyType fragmentKeyType; - /* Global checkpoint identity when table created */ Uint32 gciTableCreated; @@ -166,7 +160,6 @@ public: Uint32 attributeDescriptor; /* Extended attributes */ - Uint32 extType; Uint32 extPrecision; Uint32 extScale; Uint32 extLength; diff --git a/ndb/src/kernel/vm/VMSignal.hpp b/ndb/src/kernel/vm/VMSignal.hpp index 9111ee7949c..45543c5d174 100644 --- a/ndb/src/kernel/vm/VMSignal.hpp +++ b/ndb/src/kernel/vm/VMSignal.hpp @@ -78,10 +78,16 @@ public: #define VMS_DATA_SIZE \ (MAX_ATTRIBUTES_IN_TABLE + MAX_TUPLE_SIZE_IN_WORDS + MAX_KEY_SIZE_IN_WORDS) +#if VMS_DATA_SIZE > 8192 +#error "VMSignal buffer is too small" +#endif + SignalHeader header; // 28 bytes SegmentedSectionPtr m_sectionPtr[3]; - Uint32 theData[25+VMS_DATA_SIZE]; // 2048 32-bit words -> 8K Bytes - + union { + Uint32 theData[8192]; // 8192 32-bit words -> 32K Bytes + Uint64 dummyAlign; + }; void garbage_register(); }; diff --git a/ndb/src/mgmapi/mgmapi.cpp b/ndb/src/mgmapi/mgmapi.cpp index 5a95c6e9ac1..166bd45d48b 100644 --- a/ndb/src/mgmapi/mgmapi.cpp +++ b/ndb/src/mgmapi/mgmapi.cpp @@ -287,8 +287,11 @@ ndb_mgm_call(NdbMgmHandle handle, const ParserRow<ParserDummy> *command_reply, out.println("%s: %s", name, val_s.c_str()); break; case PropertiesType_Properties: + DBUG_PRINT("info",("Ignoring PropertiesType_Properties.")); /* Ignore */ break; + default: + DBUG_PRINT("info",("Ignoring PropertiesType: %d.",t)); } } #ifdef MGMAPI_LOG @@ -304,14 +307,17 @@ ndb_mgm_call(NdbMgmHandle handle, const ParserRow<ParserDummy> *command_reply, ParserDummy session(handle->socket); Parser_t parser(command_reply, in, true, true, true); -#if 1 const Properties* p = parser.parse(ctx, session); if (p == NULL){ /** * Print some info about why the parser returns NULL */ - //ndbout << " status=" << ctx.m_status << ", curr=" - //<< ctx.m_currentToken << endl; + ndbout << "Error in mgm protocol parser. " + << "cmd: '" << cmd + << "' status=" << ctx.m_status + << ", curr=" << ctx.m_currentToken + << endl; + DBUG_PRINT("info",("parser.parse returned NULL")); } #ifdef MGMAPI_LOG else { @@ -322,9 +328,6 @@ ndb_mgm_call(NdbMgmHandle handle, const ParserRow<ParserDummy> *command_reply, } #endif return p; -#else - return parser.parse(ctx, session); -#endif } /** @@ -1851,9 +1854,9 @@ ndb_mgm_set_int_parameter(NdbMgmHandle handle, CHECK_CONNECTED(handle, 0); Properties args; - args.put("node: ", node); - args.put("param: ", param); - args.put("value: ", value); + args.put("node", node); + args.put("param", param); + args.put("value", value); const ParserRow<ParserDummy> reply[]= { MGM_CMD("set parameter reply", NULL, ""), @@ -1890,9 +1893,9 @@ ndb_mgm_set_int64_parameter(NdbMgmHandle handle, CHECK_CONNECTED(handle, 0); Properties args; - args.put("node: ", node); - args.put("param: ", param); - args.put("value: ", value); + args.put("node", node); + args.put("param", param); + args.put("value", value); const ParserRow<ParserDummy> reply[]= { MGM_CMD("set parameter reply", NULL, ""), @@ -1933,9 +1936,9 @@ ndb_mgm_set_string_parameter(NdbMgmHandle handle, CHECK_CONNECTED(handle, 0); Properties args; - args.put("node: ", node); - args.put("parameter: ", param); - args.put("value: ", value); + args.put("node", node); + args.put("parameter", param); + args.put("value", value); const ParserRow<ParserDummy> reply[]= { MGM_CMD("set parameter reply", NULL, ""), @@ -2041,4 +2044,95 @@ ndb_mgm_check_connection_error: return -1; } +extern "C" +int +ndb_mgm_set_connection_int_parameter(NdbMgmHandle handle, + int node1, + int node2, + int param, + unsigned value, + struct ndb_mgm_reply* mgmreply){ + DBUG_ENTER("ndb_mgm_set_connection_int_parameter"); + CHECK_HANDLE(handle, 0); + CHECK_CONNECTED(handle, 0); + + Properties args; + args.put("node1", node1); + args.put("node2", node2); + args.put("param", param); + args.put("value", value); + + const ParserRow<ParserDummy> reply[]= { + MGM_CMD("set connection parameter reply", NULL, ""), + MGM_ARG("message", String, Mandatory, "Error Message"), + MGM_ARG("result", String, Mandatory, "Status Result"), + MGM_END() + }; + + const Properties *prop; + prop= ndb_mgm_call(handle, reply, "set connection parameter", &args); + CHECK_REPLY(prop, -1); + + int res= -1; + do { + const char * buf; + if(!prop->get("result", &buf) || strcmp(buf, "Ok") != 0){ + ndbout_c("ERROR Message: %s\n", buf); + break; + } + res= 0; + } while(0); + + delete prop; + return res; +} + +extern "C" +int +ndb_mgm_get_connection_int_parameter(NdbMgmHandle handle, + int node1, + int node2, + int param, + Uint32 *value, + struct ndb_mgm_reply* mgmreply){ + DBUG_ENTER("ndb_mgm_get_connection_int_parameter"); + CHECK_HANDLE(handle, -1); + CHECK_CONNECTED(handle, -1); + + Properties args; + args.put("node1", node1); + args.put("node2", node2); + args.put("param", param); + + const ParserRow<ParserDummy> reply[]= { + MGM_CMD("get connection parameter reply", NULL, ""), + MGM_ARG("value", Int, Mandatory, "Current Value"), + MGM_ARG("result", String, Mandatory, "Result"), + MGM_END() + }; + + const Properties *prop; + prop = ndb_mgm_call(handle, reply, "get connection parameter", &args); + CHECK_REPLY(prop, -2); + + int res= -1; + do { + const char * buf; + if(!prop->get("result", &buf) || strcmp(buf, "Ok") != 0){ + ndbout_c("ERROR Message: %s\n", buf); + break; + } + res= 0; + } while(0); + + if(!prop->get("value",value)){ + ndbout_c("Unable to get value"); + res = -3; + } + + delete prop; + DBUG_RETURN(res); +} + + template class Vector<const ParserRow<ParserDummy>*>; diff --git a/ndb/src/mgmsrv/MgmtSrvr.cpp b/ndb/src/mgmsrv/MgmtSrvr.cpp index 3fcde997cb0..2b0e1871fd9 100644 --- a/ndb/src/mgmsrv/MgmtSrvr.cpp +++ b/ndb/src/mgmsrv/MgmtSrvr.cpp @@ -588,7 +588,8 @@ MgmtSrvr::start(BaseString &error_string) return false; } } - theFacade= TransporterFacade::theFacadeInstance= new TransporterFacade(); + theFacade= TransporterFacade::theFacadeInstance + = new TransporterFacade(m_config_retriever->get_mgmHandle()); if(theFacade == 0) { DEBUG("MgmtSrvr.cpp: theFacade is NULL."); @@ -2771,6 +2772,97 @@ MgmtSrvr::setDbParameter(int node, int param, const char * value, return 0; } +int +MgmtSrvr::setConnectionDbParameter(int node1, + int node2, + int param, + int value, + BaseString& msg){ + Uint32 current_value,new_value; + + DBUG_ENTER("MgmtSrvr::setConnectionDbParameter"); + + ndb_mgm_configuration_iterator iter(* _config->m_configValues, + CFG_SECTION_CONNECTION); + + if(iter.first() != 0){ + msg.assign("Unable to find connection section (iter.first())"); + return -1; + } + + for(;iter.valid();iter.next()) { + Uint32 n1,n2; + iter.get(CFG_CONNECTION_NODE_1, &n1); + iter.get(CFG_CONNECTION_NODE_2, &n2); + if(n1 == (unsigned)node1 && n2 == (unsigned)node2) + break; + } + if(!iter.valid()) { + msg.assign("Unable to find connection between nodes"); + return -1; + } + + if(iter.get(param, ¤t_value) < 0) { + msg.assign("Unable to get current value of parameter"); + return -1; + } + + ConfigValues::Iterator i2(_config->m_configValues->m_config, + iter.m_config); + + if(i2.set(param, (unsigned)value) < 0) { + msg.assign("Unable to set new value of parameter"); + return -1; + } + + if(iter.get(param, &new_value) < 0) { + msg.assign("Unable to get parameter after setting it."); + return -1; + } + + msg.assfmt("%u -> %u",current_value,new_value); + return 1; +} + + +int +MgmtSrvr::getConnectionDbParameter(int node1, + int node2, + int param, + unsigned *value, + BaseString& msg){ + DBUG_ENTER("MgmtSrvr::getConnectionDbParameter"); + + ndb_mgm_configuration_iterator iter(* _config->m_configValues, + CFG_SECTION_CONNECTION); + + if(iter.first() != 0){ + msg.assign("Unable to find connection section (iter.first())"); + return -1; + } + + for(;iter.valid();iter.next()) { + Uint32 n1,n2; + iter.get(CFG_CONNECTION_NODE_1, &n1); + iter.get(CFG_CONNECTION_NODE_2, &n2); + if((n1 == (unsigned)node1 && n2 == (unsigned)node2) + || (n1 == (unsigned)node2 && n2 == (unsigned)node1)) + break; + } + if(!iter.valid()) { + msg.assign("Unable to find connection between nodes"); + return -1; + } + + if(iter.get(param, value) < 0) { + msg.assign("Unable to get current value of parameter"); + return -1; + } + + msg.assfmt("%u",*value); + DBUG_RETURN(1); +} + template class Vector<SigMatch>; #if __SUNPRO_CC != 0x560 template bool SignalQueue::waitFor<SigMatch>(Vector<SigMatch>&, SigMatch**, NdbApiSignal**, unsigned); diff --git a/ndb/src/mgmsrv/MgmtSrvr.hpp b/ndb/src/mgmsrv/MgmtSrvr.hpp index 6378e763363..4742d5f6426 100644 --- a/ndb/src/mgmsrv/MgmtSrvr.hpp +++ b/ndb/src/mgmsrv/MgmtSrvr.hpp @@ -507,6 +507,12 @@ public: int getPort() const; int setDbParameter(int node, int parameter, const char * value, BaseString&); + int setConnectionDbParameter(int node1, int node2, int param, int value, + BaseString& msg); + int getConnectionDbParameter(int node1, int node2, int param, + unsigned *value, BaseString& msg); + + const char *get_connect_address(Uint32 node_id) { return inet_ntoa(m_connect_address[node_id]); } void get_connected_nodes(NodeBitmask &connected_nodes) const; diff --git a/ndb/src/mgmsrv/Services.cpp b/ndb/src/mgmsrv/Services.cpp index 8ba8c2fe87e..6295d82b3be 100644 --- a/ndb/src/mgmsrv/Services.cpp +++ b/ndb/src/mgmsrv/Services.cpp @@ -241,6 +241,19 @@ ParserRow<MgmApiSession> commands[] = { MGM_ARG("parameter", String, Mandatory, "Parameter"), MGM_ARG("value", String, Mandatory, "Value"), + MGM_CMD("set connection parameter", + &MgmApiSession::setConnectionParameter, ""), + MGM_ARG("node1", String, Mandatory, "Node1 ID"), + MGM_ARG("node2", String, Mandatory, "Node2 ID"), + MGM_ARG("param", String, Mandatory, "Parameter"), + MGM_ARG("value", String, Mandatory, "Value"), + + MGM_CMD("get connection parameter", + &MgmApiSession::getConnectionParameter, ""), + MGM_ARG("node1", String, Mandatory, "Node1 ID"), + MGM_ARG("node2", String, Mandatory, "Node2 ID"), + MGM_ARG("param", String, Mandatory, "Parameter"), + MGM_CMD("listen event", &MgmApiSession::listen_event, ""), MGM_ARG("node", Int, Optional, "Node"), MGM_ARG("filter", String, Mandatory, "Event category"), @@ -1335,6 +1348,51 @@ MgmApiSession::setParameter(Parser_t::Context &, } void +MgmApiSession::setConnectionParameter(Parser_t::Context &ctx, + Properties const &args) { + BaseString node1, node2, param, value; + args.get("node1", node1); + args.get("node2", node2); + args.get("param", param); + args.get("value", value); + + BaseString result; + int ret = m_mgmsrv.setConnectionDbParameter(atoi(node1.c_str()), + atoi(node2.c_str()), + atoi(param.c_str()), + atoi(value.c_str()), + result); + + m_output->println("set connection parameter reply"); + m_output->println("message: %s", result.c_str()); + m_output->println("result: %s", (ret>0)?"Ok":"Failed"); + m_output->println(""); +} + +void +MgmApiSession::getConnectionParameter(Parser_t::Context &ctx, + Properties const &args) { + BaseString node1, node2, param; + unsigned value = 0; + + args.get("node1", node1); + args.get("node2", node2); + args.get("param", param); + + BaseString result; + int ret = m_mgmsrv.getConnectionDbParameter(atoi(node1.c_str()), + atoi(node2.c_str()), + atoi(param.c_str()), + &value, + result); + + m_output->println("get connection parameter reply"); + m_output->println("value: %u", value); + m_output->println("result: %s", (ret>0)?"Ok":result.c_str()); + m_output->println(""); +} + +void MgmApiSession::listen_event(Parser<MgmApiSession>::Context & ctx, Properties const & args) { diff --git a/ndb/src/mgmsrv/Services.hpp b/ndb/src/mgmsrv/Services.hpp index 8627343b1cf..d7334ee1c5f 100644 --- a/ndb/src/mgmsrv/Services.hpp +++ b/ndb/src/mgmsrv/Services.hpp @@ -88,6 +88,11 @@ public: void configChange(Parser_t::Context &ctx, const class Properties &args); void setParameter(Parser_t::Context &ctx, const class Properties &args); + void setConnectionParameter(Parser_t::Context &ctx, + const class Properties &args); + void getConnectionParameter(Parser_t::Context &ctx, + Properties const &args); + void listen_event(Parser_t::Context &ctx, const class Properties &args); void purge_stale_sessions(Parser_t::Context &ctx, const class Properties &args); diff --git a/ndb/src/ndbapi/ClusterMgr.cpp b/ndb/src/ndbapi/ClusterMgr.cpp index e10b2e1d82c..ef6e35e0702 100644 --- a/ndb/src/ndbapi/ClusterMgr.cpp +++ b/ndb/src/ndbapi/ClusterMgr.cpp @@ -429,7 +429,6 @@ ClusterMgr::reportDisconnected(NodeId nodeId){ noOfConnectedNodes--; theNodes[nodeId].connected = false; - theNodes[nodeId].m_info.m_connectCount ++; reportNodeFailed(nodeId); } @@ -439,18 +438,22 @@ ClusterMgr::reportNodeFailed(NodeId nodeId){ Node & theNode = theNodes[nodeId]; theNode.m_alive = false; + theNode.m_info.m_connectCount ++; + if(theNode.connected) + { theFacade.doDisconnect(nodeId); - + } const bool report = (theNode.m_state.startLevel != NodeState::SL_NOTHING); theNode.m_state.startLevel = NodeState::SL_NOTHING; - if(report){ + if(report) + { theFacade.ReportNodeDead(nodeId); - } - + } + theNode.nfCompleteRep = false; - + if(noOfConnectedNodes == 0){ NFCompleteRep rep; for(Uint32 i = 1; i<MAX_NODES; i++){ diff --git a/ndb/src/ndbapi/Makefile.am b/ndb/src/ndbapi/Makefile.am index 9f8a851b995..b734e058b87 100644 --- a/ndb/src/ndbapi/Makefile.am +++ b/ndb/src/ndbapi/Makefile.am @@ -14,15 +14,14 @@ libndbapi_la_SOURCES = \ Ndberr.cpp \ ndberror.c \ NdbErrorOut.cpp \ - NdbConnection.cpp \ - NdbConnectionScan.cpp \ + NdbTransaction.cpp \ + NdbTransactionScan.cpp \ NdbOperation.cpp \ NdbOperationSearch.cpp \ NdbOperationScan.cpp \ NdbOperationInt.cpp \ NdbOperationDefine.cpp \ NdbOperationExec.cpp \ - NdbResultSet.cpp \ NdbScanOperation.cpp NdbScanFilter.cpp \ NdbIndexOperation.cpp \ NdbEventOperation.cpp \ diff --git a/ndb/src/ndbapi/Ndb.cpp b/ndb/src/ndbapi/Ndb.cpp index e9a125922c6..9c9138372cd 100644 --- a/ndb/src/ndbapi/Ndb.cpp +++ b/ndb/src/ndbapi/Ndb.cpp @@ -27,7 +27,7 @@ Name: Ndb.cpp #include "NdbApiSignal.hpp" #include "NdbImpl.hpp" #include <NdbOperation.hpp> -#include <NdbConnection.hpp> +#include <NdbTransaction.hpp> #include <NdbEventOperation.hpp> #include <NdbRecAttr.hpp> #include <md5_hash.hpp> @@ -43,7 +43,7 @@ void connect(); Connect to any node which has no connection at the moment. ****************************************************************************/ -NdbConnection* Ndb::doConnect(Uint32 tConNode) +NdbTransaction* Ndb::doConnect(Uint32 tConNode) { Uint32 tNode; Uint32 tAnyAlive = 0; @@ -55,7 +55,7 @@ NdbConnection* Ndb::doConnect(Uint32 tConNode) //**************************************************************************** // We have connections now to the desired node. Return //**************************************************************************** - return getConnectedNdbConnection(tConNode); + return getConnectedNdbTransaction(tConNode); } else if (TretCode != 0) { tAnyAlive = 1; }//if @@ -78,7 +78,7 @@ NdbConnection* Ndb::doConnect(Uint32 tConNode) //**************************************************************************** // We have connections now to the desired node. Return //**************************************************************************** - return getConnectedNdbConnection(tNode); + return getConnectedNdbTransaction(tNode); } else if (TretCode != 0) { tAnyAlive= 1; }//if @@ -103,7 +103,7 @@ NdbConnection* Ndb::doConnect(Uint32 tConNode) //**************************************************************************** // We have connections now to the desired node. Return //**************************************************************************** - return getConnectedNdbConnection(tNode); + return getConnectedNdbTransaction(tNode); } else if (TretCode != 0) { tAnyAlive= 1; }//if @@ -139,12 +139,12 @@ Ndb::NDB_connect(Uint32 tNode) return 0; } - NdbConnection * tConArray = theConnectionArray[tNode]; + NdbTransaction * tConArray = theConnectionArray[tNode]; if (tConArray != NULL) { return 2; } - NdbConnection * tNdbCon = getNdbCon(); // Get free connection object. + NdbTransaction * tNdbCon = getNdbCon(); // Get free connection object. if (tNdbCon == NULL) { return 4; }//if @@ -160,10 +160,10 @@ Ndb::NDB_connect(Uint32 tNode) }//if tSignal->setData(tNdbCon->ptr2int(), 1); //************************************************ -// Set connection pointer as NdbConnection object +// Set connection pointer as NdbTransaction object //************************************************ tSignal->setData(theMyRef, 2); // Set my block reference - tNdbCon->Status(NdbConnection::Connecting); // Set status to connecting + tNdbCon->Status(NdbTransaction::Connecting); // Set status to connecting Uint32 nodeSequence; { // send and receive signal Guard guard(tp->theMutexPtr); @@ -182,11 +182,11 @@ Ndb::NDB_connect(Uint32 tNode) tReturnCode = -1; }//if } - if ((tReturnCode == 0) && (tNdbCon->Status() == NdbConnection::Connected)) { + if ((tReturnCode == 0) && (tNdbCon->Status() == NdbTransaction::Connected)) { //************************************************ // Send and receive was successful //************************************************ - NdbConnection* tPrevFirst = theConnectionArray[tNode]; + NdbTransaction* tPrevFirst = theConnectionArray[tNode]; tNdbCon->setConnectedNodeId(tNode, nodeSequence); tNdbCon->setMyBlockReference(theMyRef); @@ -202,14 +202,14 @@ Ndb::NDB_connect(Uint32 tNode) }//if }//Ndb::NDB_connect() -NdbConnection * -Ndb::getConnectedNdbConnection(Uint32 nodeId){ - NdbConnection* next = theConnectionArray[nodeId]; +NdbTransaction * +Ndb::getConnectedNdbTransaction(Uint32 nodeId){ + NdbTransaction* next = theConnectionArray[nodeId]; theConnectionArray[nodeId] = next->theNext; next->theNext = NULL; return next; -}//Ndb::getConnectedNdbConnection() +}//Ndb::getConnectedNdbTransaction() /***************************************************************************** disconnect(); @@ -220,7 +220,7 @@ void Ndb::doDisconnect() { DBUG_ENTER("Ndb::doDisconnect"); - NdbConnection* tNdbCon; + NdbTransaction* tNdbCon; CHECK_STATUS_MACRO_VOID; Uint32 tNoOfDbNodes = theImpl->theNoOfDBnodes; @@ -231,14 +231,14 @@ Ndb::doDisconnect() Uint32 tNode = theDBnodes[i]; tNdbCon = theConnectionArray[tNode]; while (tNdbCon != NULL) { - NdbConnection* tmpNdbCon = tNdbCon; + NdbTransaction* tmpNdbCon = tNdbCon; tNdbCon = tNdbCon->theNext; releaseConnectToNdb(tmpNdbCon); }//while }//for tNdbCon = theTransactionList; while (tNdbCon != NULL) { - NdbConnection* tmpNdbCon = tNdbCon; + NdbTransaction* tmpNdbCon = tNdbCon; tNdbCon = tNdbCon->theNext; releaseConnectToNdb(tmpNdbCon); }//while @@ -292,13 +292,13 @@ Ndb::waitUntilReady(int timeout) } /***************************************************************************** -NdbConnection* startTransaction(); +NdbTransaction* startTransaction(); Return Value: Returns a pointer to a connection object. Return NULL otherwise. Remark: Start transaction. Synchronous. *****************************************************************************/ -NdbConnection* +NdbTransaction* Ndb::startTransaction(Uint32 aPriority, const char * keyData, Uint32 keyLen) { DBUG_ENTER("Ndb::startTransaction"); @@ -319,7 +319,7 @@ Ndb::startTransaction(Uint32 aPriority, const char * keyData, Uint32 keyLen) nodeId = 0; }//if { - NdbConnection *trans= startTransactionLocal(aPriority, nodeId); + NdbTransaction *trans= startTransactionLocal(aPriority, nodeId); DBUG_PRINT("exit",("start trans: 0x%x transid: 0x%llx", trans, trans ? trans->getTransactionId() : 0)); DBUG_RETURN(trans); @@ -330,15 +330,15 @@ Ndb::startTransaction(Uint32 aPriority, const char * keyData, Uint32 keyLen) }//Ndb::startTransaction() /***************************************************************************** -NdbConnection* hupp(NdbConnection* pBuddyTrans); +NdbTransaction* hupp(NdbTransaction* pBuddyTrans); Return Value: Returns a pointer to a connection object. Connected to the same node as pBuddyTrans and also using the same transction id Remark: Start transaction. Synchronous. *****************************************************************************/ -NdbConnection* -Ndb::hupp(NdbConnection* pBuddyTrans) +NdbTransaction* +Ndb::hupp(NdbTransaction* pBuddyTrans) { DBUG_ENTER("Ndb::hupp"); @@ -354,7 +354,7 @@ Ndb::hupp(NdbConnection* pBuddyTrans) checkFailedNode(); Uint32 nodeId = pBuddyTrans->getConnectedNodeId(); - NdbConnection* pCon = startTransactionLocal(aPriority, nodeId); + NdbTransaction* pCon = startTransactionLocal(aPriority, nodeId); if(pCon == NULL) DBUG_RETURN(NULL); @@ -375,8 +375,7 @@ Ndb::hupp(NdbConnection* pBuddyTrans) }//if }//Ndb::hupp() - -NdbConnection* +NdbTransaction* Ndb::startTransactionLocal(Uint32 aPriority, Uint32 nodeId) { #ifdef VM_TRACE @@ -390,13 +389,13 @@ Ndb::startTransactionLocal(Uint32 aPriority, Uint32 nodeId) DBUG_ENTER("Ndb::startTransactionLocal"); DBUG_PRINT("enter", ("nodeid: %d", nodeId)); - NdbConnection* tConnection; + NdbTransaction* tConnection; Uint64 tFirstTransId = theFirstTransId; tConnection = doConnect(nodeId); if (tConnection == NULL) { DBUG_RETURN(NULL); }//if - NdbConnection* tConNext = theTransactionList; + NdbTransaction* tConNext = theTransactionList; tConnection->init(); theTransactionList = tConnection; // into a transaction list. tConnection->next(tConNext); // Add the active connection object @@ -412,7 +411,7 @@ Ndb::startTransactionLocal(Uint32 aPriority, Uint32 nodeId) theFirstTransId = tFirstTransId + 1; }//if #ifdef VM_TRACE - if (tConnection->theListState != NdbConnection::NotInList) { + if (tConnection->theListState != NdbTransaction::NotInList) { printState("startTransactionLocal %x", tConnection); abort(); } @@ -421,17 +420,17 @@ Ndb::startTransactionLocal(Uint32 aPriority, Uint32 nodeId) }//Ndb::startTransactionLocal() /***************************************************************************** -void closeTransaction(NdbConnection* aConnection); +void closeTransaction(NdbTransaction* aConnection); Parameters: aConnection: the connection used in the transaction. Remark: Close transaction by releasing the connection and all operations. *****************************************************************************/ void -Ndb::closeTransaction(NdbConnection* aConnection) +Ndb::closeTransaction(NdbTransaction* aConnection) { DBUG_ENTER("Ndb::closeTransaction"); - NdbConnection* tCon; - NdbConnection* tPreviousCon; + NdbTransaction* tCon; + NdbTransaction* tPreviousCon; if (aConnection == NULL) { //----------------------------------------------------- @@ -464,12 +463,12 @@ Ndb::closeTransaction(NdbConnection* aConnection) if(aConnection->theError.code == 4008){ /** - * When a SCAN timed-out, returning the NdbConnection leads + * When a SCAN timed-out, returning the NdbTransaction leads * to reuse. And TC crashes when the API tries to reuse it to * something else... */ #ifdef VM_TRACE - printf("Scan timeout:ed NdbConnection-> " + printf("Scan timeout:ed NdbTransaction-> " "not returning it-> memory leak\n"); #endif DBUG_VOID_RETURN; @@ -491,12 +490,12 @@ Ndb::closeTransaction(NdbConnection* aConnection) if(aConnection->theError.code == 4008){ /** - * Something timed-out, returning the NdbConnection leads + * Something timed-out, returning the NdbTransaction leads * to reuse. And TC crashes when the API tries to reuse it to * something else... */ #ifdef VM_TRACE - printf("Con timeout:ed NdbConnection-> not returning it-> memory leak\n"); + printf("Con timeout:ed NdbTransaction-> not returning it-> memory leak\n"); #endif DBUG_VOID_RETURN; } @@ -535,7 +534,7 @@ Remark: Sends a signal to DIH. int Ndb::NdbTamper(TamperType aAction, int aNode) { - NdbConnection* tNdbConn; + NdbTransaction* tNdbConn; NdbApiSignal tSignal(theMyRef); int tNode; int tAction; @@ -577,7 +576,7 @@ Ndb::NdbTamper(TamperType aAction, int aNode) tSignal.setData (tAction, 1); tSignal.setData(tNdbConn->ptr2int(),2); tSignal.setData(theMyRef,3); // Set return block reference - tNdbConn->Status(NdbConnection::Connecting); // Set status to connecting + tNdbConn->Status(NdbTransaction::Connecting); // Set status to connecting TransporterFacade *tp = TransporterFacade::instance(); if (tAction == 3) { tp->lock_mutex(); @@ -610,7 +609,7 @@ Ndb::NdbTamper(TamperType aAction, int aNode) }//if ret_code = sendRecSignal(tNode, WAIT_NDB_TAMPER, &tSignal, 0); if (ret_code == 0) { - if (tNdbConn->Status() != NdbConnection::Connected) { + if (tNdbConn->Status() != NdbTransaction::Connected) { theRestartGCI = 0; }//if releaseNdbCon(tNdbConn); @@ -865,9 +864,10 @@ Ndb::setTupleIdInNdb(Uint32 aTableId, Uint64 val, bool increase ) Uint64 Ndb::opTupleIdOnNdb(Uint32 aTableId, Uint64 opValue, Uint32 op) { - DEBUG_TRACE("opTupleIdOnNdb"); + DBUG_ENTER("Ndb::opTupleIdOnNdb"); + DBUG_PRINT("enter", ("table=%u value=%llu op=%u", aTableId, opValue, op)); - NdbConnection* tConnection; + NdbTransaction* tConnection; NdbOperation* tOperation; Uint64 tValue; NdbRecAttr* tRecAttrResult; @@ -961,7 +961,7 @@ Ndb::opTupleIdOnNdb(Uint32 aTableId, Uint64 opValue, Uint32 op) setDatabaseName(currentDb.c_str()); setDatabaseSchemaName(currentSchema.c_str()); - return ret; + DBUG_RETURN(ret); error_handler: theError.code = tConnection->theError.code; @@ -971,7 +971,11 @@ Ndb::opTupleIdOnNdb(Uint32 aTableId, Uint64 opValue, Uint32 op) setDatabaseName(currentDb.c_str()); setDatabaseSchemaName(currentSchema.c_str()); - return ~0; + DBUG_PRINT("error", ("ndb=%d con=%d op=%d", + theError.code, + tConnection ? tConnection->theError.code : -1, + tOperation ? tOperation->theError.code : -1)); + DBUG_RETURN(~0); } Uint32 @@ -1209,7 +1213,7 @@ Ndb::pollEvents(int aMillisecondNumber) extern NdbMutex *ndb_print_state_mutex; static bool -checkdups(NdbConnection** list, unsigned no) +checkdups(NdbTransaction** list, unsigned no) { for (unsigned i = 0; i < no; i++) for (unsigned j = i + 1; j < no; j++) @@ -1234,7 +1238,7 @@ Ndb::printState(const char* fmt, ...) #endif ndbout << endl; for (unsigned n = 0; n < MAX_NDB_NODES; n++) { - NdbConnection* con = theConnectionArray[n]; + NdbTransaction* con = theConnectionArray[n]; if (con != 0) { ndbout << "conn " << n << ":" << endl; while (con != 0) { diff --git a/ndb/src/ndbapi/NdbApiSignal.hpp b/ndb/src/ndbapi/NdbApiSignal.hpp index 52c3be2256c..353c575d420 100644 --- a/ndb/src/ndbapi/NdbApiSignal.hpp +++ b/ndb/src/ndbapi/NdbApiSignal.hpp @@ -93,7 +93,7 @@ private: void setDataPtr(Uint32 *); - friend class NdbConnection; + friend class NdbTransaction; friend class NdbScanReceiver; friend class Table; void copyFrom(const NdbApiSignal * src); diff --git a/ndb/src/ndbapi/NdbBlob.cpp b/ndb/src/ndbapi/NdbBlob.cpp index 0a1433c71f3..8424440f91e 100644 --- a/ndb/src/ndbapi/NdbBlob.cpp +++ b/ndb/src/ndbapi/NdbBlob.cpp @@ -16,7 +16,7 @@ #include <Ndb.hpp> #include <NdbDictionaryImpl.hpp> -#include <NdbConnection.hpp> +#include <NdbTransaction.hpp> #include <NdbOperation.hpp> #include <NdbIndexOperation.hpp> #include <NdbRecAttr.hpp> @@ -1059,7 +1059,7 @@ NdbBlob::invokeActiveHook() * data. For read operation adds read of head+inline. */ int -NdbBlob::atPrepare(NdbConnection* aCon, NdbOperation* anOp, const NdbColumnImpl* aColumn) +NdbBlob::atPrepare(NdbTransaction* aCon, NdbOperation* anOp, const NdbColumnImpl* aColumn) { assert(theState == Idle); // ndb api stuff @@ -1550,7 +1550,7 @@ NdbBlob::setErrorCode(NdbOperation* anOp, bool invalidFlag) } void -NdbBlob::setErrorCode(NdbConnection* aCon, bool invalidFlag) +NdbBlob::setErrorCode(NdbTransaction* aCon, bool invalidFlag) { int code = 0; if (theNdbCon != NULL && (code = theNdbCon->theError.code) != 0) diff --git a/ndb/src/ndbapi/NdbCursorOperation.cpp b/ndb/src/ndbapi/NdbCursorOperation.cpp deleted file mode 100644 index a9f84c4c110..00000000000 --- a/ndb/src/ndbapi/NdbCursorOperation.cpp +++ /dev/null @@ -1,51 +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 */ - -/***************************************************************************** - * Name: NdbCursorOperation.cpp - * Include: - * Link: - * Author: UABMASD Martin Sköld INN/V Alzato - * Date: 2002-04-01 - * Version: 0.1 - * Description: Cursor support - * Documentation: - * Adjust: 2002-04-01 UABMASD First version. - ****************************************************************************/ - -#include <NdbCursorOperation.hpp> -#include <NdbResultSet.hpp> - -NdbCursorOperation::NdbCursorOperation(Ndb* aNdb) : -{ -} - -NdbCursorOperation::~NdbCursorOperation() -{ - if (m_resultSet) - delete m_resultSet; -} - -void NdbCursorOperation::cursInit() -{ - // Initialize result set -} - -NdbResultSet* NdbCursorOperation::getResultSet() -{ -} - - diff --git a/ndb/src/ndbapi/NdbDictionary.cpp b/ndb/src/ndbapi/NdbDictionary.cpp index e06901eb853..745a0635a81 100644 --- a/ndb/src/ndbapi/NdbDictionary.cpp +++ b/ndb/src/ndbapi/NdbDictionary.cpp @@ -938,3 +938,4 @@ const NdbDictionary::Column * NdbDictionary::Column::FRAGMENT = 0; const NdbDictionary::Column * NdbDictionary::Column::ROW_COUNT = 0; const NdbDictionary::Column * NdbDictionary::Column::COMMIT_COUNT = 0; const NdbDictionary::Column * NdbDictionary::Column::ROW_SIZE = 0; +const NdbDictionary::Column * NdbDictionary::Column::RANGE_NO = 0; diff --git a/ndb/src/ndbapi/NdbDictionaryImpl.cpp b/ndb/src/ndbapi/NdbDictionaryImpl.cpp index d39b921072b..018dfb825b6 100644 --- a/ndb/src/ndbapi/NdbDictionaryImpl.cpp +++ b/ndb/src/ndbapi/NdbDictionaryImpl.cpp @@ -74,7 +74,6 @@ NdbColumnImpl::operator=(const NdbColumnImpl& col) m_autoIncrement = col.m_autoIncrement; m_autoIncrementInitialValue = col.m_autoIncrementInitialValue; m_defaultValue = col.m_defaultValue; - m_attrType = col.m_attrType; m_attrSize = col.m_attrSize; m_arraySize = col.m_arraySize; m_keyInfoPos = col.m_keyInfoPos; @@ -223,6 +222,11 @@ NdbColumnImpl::create_psuedo(const char * name){ col->m_impl.m_attrId = AttributeHeader::ROW_SIZE; col->m_impl.m_attrSize = 4; col->m_impl.m_arraySize = 1; + } else if(!strcmp(name, "NDB$RANGE_NO")){ + col->setType(NdbDictionary::Column::Unsigned); + col->m_impl.m_attrId = AttributeHeader::RANGE_NO; + col->m_impl.m_attrSize = 4; + col->m_impl.m_arraySize = 1; } else { abort(); } @@ -694,6 +698,8 @@ NdbDictionaryImpl::setTransporter(class Ndb* ndb, NdbColumnImpl::create_psuedo("NDB$COMMIT_COUNT"); NdbDictionary::Column::ROW_SIZE= NdbColumnImpl::create_psuedo("NDB$ROW_SIZE"); + NdbDictionary::Column::RANGE_NO= + NdbColumnImpl::create_psuedo("NDB$RANGE_NO"); } m_globalHash->unlock(); return true; @@ -1102,8 +1108,6 @@ objectTypeMapping[] = { { DictTabInfo::SystemTable, NdbDictionary::Object::SystemTable }, { DictTabInfo::UserTable, NdbDictionary::Object::UserTable }, { DictTabInfo::UniqueHashIndex, NdbDictionary::Object::UniqueHashIndex }, - { DictTabInfo::HashIndex, NdbDictionary::Object::HashIndex }, - { DictTabInfo::UniqueOrderedIndex, NdbDictionary::Object::UniqueOrderedIndex }, { DictTabInfo::OrderedIndex, NdbDictionary::Object::OrderedIndex }, { DictTabInfo::HashIndexTrigger, NdbDictionary::Object::HashIndexTrigger }, { DictTabInfo::IndexTrigger, NdbDictionary::Object::IndexTrigger }, @@ -1135,41 +1139,10 @@ static const ApiKernelMapping indexTypeMapping[] = { { DictTabInfo::UniqueHashIndex, NdbDictionary::Index::UniqueHashIndex }, - { DictTabInfo::HashIndex, NdbDictionary::Index::HashIndex }, - { DictTabInfo::UniqueOrderedIndex, NdbDictionary::Index::UniqueOrderedIndex}, { DictTabInfo::OrderedIndex, NdbDictionary::Index::OrderedIndex }, { -1, -1 } }; -// TODO: remove, api-kernel type codes must match now -static const -ApiKernelMapping -columnTypeMapping[] = { - { DictTabInfo::ExtTinyint, NdbDictionary::Column::Tinyint }, - { DictTabInfo::ExtTinyunsigned, NdbDictionary::Column::Tinyunsigned }, - { DictTabInfo::ExtSmallint, NdbDictionary::Column::Smallint }, - { DictTabInfo::ExtSmallunsigned, NdbDictionary::Column::Smallunsigned }, - { DictTabInfo::ExtMediumint, NdbDictionary::Column::Mediumint }, - { DictTabInfo::ExtMediumunsigned, NdbDictionary::Column::Mediumunsigned }, - { DictTabInfo::ExtInt, NdbDictionary::Column::Int }, - { DictTabInfo::ExtUnsigned, NdbDictionary::Column::Unsigned }, - { DictTabInfo::ExtBigint, NdbDictionary::Column::Bigint }, - { DictTabInfo::ExtBigunsigned, NdbDictionary::Column::Bigunsigned }, - { DictTabInfo::ExtFloat, NdbDictionary::Column::Float }, - { DictTabInfo::ExtDouble, NdbDictionary::Column::Double }, - { DictTabInfo::ExtDecimal, NdbDictionary::Column::Decimal }, - { DictTabInfo::ExtChar, NdbDictionary::Column::Char }, - { DictTabInfo::ExtVarchar, NdbDictionary::Column::Varchar }, - { DictTabInfo::ExtBinary, NdbDictionary::Column::Binary }, - { DictTabInfo::ExtVarbinary, NdbDictionary::Column::Varbinary }, - { DictTabInfo::ExtDatetime, NdbDictionary::Column::Datetime }, - { DictTabInfo::ExtTimespec, NdbDictionary::Column::Timespec }, - { DictTabInfo::ExtBlob, NdbDictionary::Column::Blob }, - { DictTabInfo::ExtText, NdbDictionary::Column::Text }, - { DictTabInfo::ExtBit, NdbDictionary::Column::Bit }, - { -1, -1 } -}; - int NdbDictInterface::parseTableInfo(NdbTableImpl ** ret, const Uint32 * data, Uint32 len, @@ -1241,15 +1214,11 @@ NdbDictInterface::parseTableInfo(NdbTableImpl ** ret, NdbColumnImpl * col = new NdbColumnImpl(); col->m_attrId = attrDesc.AttributeId; col->setName(attrDesc.AttributeName); - col->m_type = (NdbDictionary::Column::Type) - getApiConstant(attrDesc.AttributeExtType, - columnTypeMapping, - NdbDictionary::Column::Undefined); - if (col->m_type == NdbDictionary::Column::Undefined) { + if (attrDesc.AttributeExtType >= NDB_TYPE_MAX) { delete impl; return 703; } - col->m_extType = attrDesc.AttributeExtType; + col->m_type = (NdbDictionary::Column::Type)attrDesc.AttributeExtType; col->m_precision = (attrDesc.AttributeExtPrecision & 0xFFFF); col->m_scale = attrDesc.AttributeExtScale; col->m_length = attrDesc.AttributeExtLength; @@ -1273,7 +1242,6 @@ NdbDictInterface::parseTableInfo(NdbTableImpl ** ret, delete impl; return 703; } - col->m_attrType =attrDesc.AttributeType; col->m_attrSize = (1 << attrDesc.AttributeSize) / 8; col->m_arraySize = attrDesc.AttributeArraySize; if(attrDesc.AttributeSize == 0) @@ -1525,14 +1493,13 @@ NdbDictInterface::createOrAlterTable(Ndb & ndb, tmpAttr.AttributeId = i; tmpAttr.AttributeKeyFlag = col->m_pk; tmpAttr.AttributeNullableFlag = col->m_nullable; - tmpAttr.AttributeStoredInd = 1; tmpAttr.AttributeDKey = col->m_distributionKey; - tmpAttr.AttributeDGroup = 0; - tmpAttr.AttributeExtType = - getKernelConstant(col->m_type, - columnTypeMapping, - DictTabInfo::ExtUndefined); + if (col->m_type >= NDB_TYPE_MAX) { + m_error.code = 703; + return -1; + } + tmpAttr.AttributeExtType = (Uint32)col->m_type; tmpAttr.AttributeExtPrecision = ((unsigned)col->m_precision & 0xFFFF); tmpAttr.AttributeExtScale = col->m_scale; tmpAttr.AttributeExtLength = col->m_length; @@ -1546,6 +1513,11 @@ NdbDictInterface::createOrAlterTable(Ndb & ndb, m_error.code = 743; DBUG_RETURN(-1); } + // distribution key not supported for Char attribute + if (col->m_distributionKey && col->m_cs != NULL) { + m_error.code = 745; + return -1; + } // charset in upper half of precision if (col->getCharType()) { tmpAttr.AttributeExtPrecision |= (col->m_cs->number << 16); @@ -1713,7 +1685,7 @@ NdbDictionaryImpl::dropTable(const char * name) DBUG_PRINT("enter",("name: %s", name)); NdbTableImpl * tab = getTable(name); if(tab == 0){ - return -1; + DBUG_RETURN(-1); } int ret = dropTable(* tab); // If table stored in cache is incompatible with the one in the kernel @@ -1927,7 +1899,7 @@ NdbDictionaryImpl::getIndexImpl(const char * externalName, int NdbDictInterface::create_index_obj_from_table(NdbIndexImpl** dst, - const NdbTableImpl* tab, + NdbTableImpl* tab, const NdbTableImpl* prim){ NdbIndexImpl *idx = new NdbIndexImpl(); idx->m_version = tab->m_version; @@ -1935,22 +1907,49 @@ NdbDictInterface::create_index_obj_from_table(NdbIndexImpl** dst, idx->m_indexId = tab->m_tableId; idx->m_externalName.assign(tab->getName()); idx->m_tableName.assign(prim->m_externalName); - idx->m_type = tab->m_indexType; + NdbDictionary::Index::Type type = idx->m_type = tab->m_indexType; idx->m_logging = tab->m_logging; // skip last attribute (NDB$PK or NDB$TNODE) - for(unsigned i = 0; i+1<tab->m_columns.size(); i++){ + + const Uint32 distKeys = prim->m_noOfDistributionKeys; + Uint32 keyCount = (distKeys ? distKeys : prim->m_noOfKeys); + + unsigned i; + for(i = 0; i+1<tab->m_columns.size(); i++){ + NdbColumnImpl* org = tab->m_columns[i]; + NdbColumnImpl* col = new NdbColumnImpl; // Copy column definition - *col = *tab->m_columns[i]; + *col = * org; idx->m_columns.push_back(col); + /** * reverse map */ - int key_id = prim->getColumn(col->getName())->getColumnNo(); + const NdbColumnImpl* primCol = prim->getColumn(col->getName()); + int key_id = primCol->getColumnNo(); int fill = -1; idx->m_key_ids.fill(key_id, fill); idx->m_key_ids[key_id] = i; col->m_keyInfoPos = key_id; + + if(type == NdbDictionary::Index::OrderedIndex && + (primCol->m_distributionKey || + (distKeys == 0 && primCol->getPrimaryKey()))) + { + keyCount--; + org->m_distributionKey = 1; + } + } + + if(keyCount == 0) + { + tab->m_noOfDistributionKeys = (distKeys ? distKeys : prim->m_noOfKeys); + } + else + { + for(i = 0; i+1<tab->m_columns.size(); i++) + tab->m_columns[i]->m_distributionKey = 0; } * dst = idx; @@ -2915,8 +2914,6 @@ NdbDictInterface::listObjects(NdbDictionary::Dictionary::List& list, BaseString schemaName; BaseString objectName; if ((element.type == NdbDictionary::Object::UniqueHashIndex) || - (element.type == NdbDictionary::Object::HashIndex) || - (element.type == NdbDictionary::Object::UniqueOrderedIndex) || (element.type == NdbDictionary::Object::OrderedIndex)) { char * indexName = new char[n << 2]; memcpy(indexName, &data[pos], n << 2); diff --git a/ndb/src/ndbapi/NdbDictionaryImpl.hpp b/ndb/src/ndbapi/NdbDictionaryImpl.hpp index 7ee064c2583..df20915a0e0 100644 --- a/ndb/src/ndbapi/NdbDictionaryImpl.hpp +++ b/ndb/src/ndbapi/NdbDictionaryImpl.hpp @@ -73,11 +73,9 @@ public: /** * Internal types and sizes, and aggregates */ - Uint32 m_attrType; // type outsize API and DICT Uint32 m_attrSize; // element size (size when arraySize==1) Uint32 m_arraySize; // length or length+2 for Var* types Uint32 m_keyInfoPos; - Uint32 m_extType; // used by restore (kernel type in versin v2x) bool getInterpretableType() const ; bool getCharType() const; bool getBlobType() const; @@ -303,8 +301,8 @@ public: bool fullyQualifiedNames); static int create_index_obj_from_table(NdbIndexImpl ** dst, - const NdbTableImpl*, - const NdbTableImpl*); + NdbTableImpl* index_table, + const NdbTableImpl* primary_table); NdbError & m_error; private: diff --git a/ndb/src/ndbapi/NdbImpl.hpp b/ndb/src/ndbapi/NdbImpl.hpp index 00a8ef19f3a..d649b39c5eb 100644 --- a/ndb/src/ndbapi/NdbImpl.hpp +++ b/ndb/src/ndbapi/NdbImpl.hpp @@ -89,9 +89,9 @@ Ndb::void2rec(void* val){ } inline -NdbConnection * +NdbTransaction * Ndb::void2con(void* val){ - return (NdbConnection*)val; + return (NdbTransaction*)val; } inline @@ -107,7 +107,7 @@ Ndb::void2rec_iop(void* val){ } inline -NdbConnection * +NdbTransaction * NdbReceiver::getTransaction(){ return ((NdbOperation*)m_owner)->theNdbCon; } diff --git a/ndb/src/ndbapi/NdbIndexOperation.cpp b/ndb/src/ndbapi/NdbIndexOperation.cpp index 7b8e15f4d81..4cedffed4a2 100644 --- a/ndb/src/ndbapi/NdbIndexOperation.cpp +++ b/ndb/src/ndbapi/NdbIndexOperation.cpp @@ -16,9 +16,8 @@ #include <ndb_global.h> #include <NdbIndexOperation.hpp> -#include <NdbResultSet.hpp> #include <Ndb.hpp> -#include <NdbConnection.hpp> +#include <NdbTransaction.hpp> #include "NdbApiSignal.hpp" #include <AttributeHeader.hpp> #include <signaldata/TcIndx.hpp> @@ -54,7 +53,7 @@ NdbIndexOperation::~NdbIndexOperation() int NdbIndexOperation::indxInit(const NdbIndexImpl * anIndex, const NdbTableImpl * aTable, - NdbConnection* myConnection) + NdbTransaction* myConnection) { NdbOperation::init(aTable, myConnection); @@ -62,8 +61,6 @@ NdbIndexOperation::indxInit(const NdbIndexImpl * anIndex, case(NdbDictionary::Index::UniqueHashIndex): break; case(NdbDictionary::Index::Undefined): - case(NdbDictionary::Index::HashIndex): - case(NdbDictionary::Index::UniqueOrderedIndex): case(NdbDictionary::Index::OrderedIndex): setErrorCodeAbort(4003); return -1; @@ -411,17 +408,5 @@ Remark: Handles the reception of the TCKEYREF signal. int NdbIndexOperation::receiveTCINDXREF( NdbApiSignal* aSignal) { - const TcIndxRef * const tcIndxRef = CAST_CONSTPTR(TcIndxRef, aSignal->getDataPtr()); - - if (checkState_TransId(aSignal) == -1) { - return -1; - }//if - - theStatus = Finished; - - theNdbCon->theReturnStatus = NdbConnection::ReturnFailure; - Uint32 errorCode = tcIndxRef->errorCode; - theError.code = errorCode; - theNdbCon->setOperationErrorCodeAbort(errorCode); - return theNdbCon->OpCompleteFailure(theNdbCon->m_abortOption); + return receiveTCKEYREF(aSignal); }//NdbIndexOperation::receiveTCINDXREF() diff --git a/ndb/src/ndbapi/NdbOperation.cpp b/ndb/src/ndbapi/NdbOperation.cpp index f0de2242d2a..58147f2654e 100644 --- a/ndb/src/ndbapi/NdbOperation.cpp +++ b/ndb/src/ndbapi/NdbOperation.cpp @@ -15,7 +15,7 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include <ndb_global.h> -#include <NdbConnection.hpp> +#include <NdbTransaction.hpp> #include <NdbOperation.hpp> #include "NdbApiSignal.hpp" #include "NdbRecAttr.hpp" @@ -128,7 +128,7 @@ NdbOperation::setErrorCodeAbort(int anErrorCode) *****************************************************************************/ int -NdbOperation::init(const NdbTableImpl* tab, NdbConnection* myConnection){ +NdbOperation::init(const NdbTableImpl* tab, NdbTransaction* myConnection){ NdbApiSignal* tSignal; theStatus = Init; theError.code = 0; diff --git a/ndb/src/ndbapi/NdbOperationDefine.cpp b/ndb/src/ndbapi/NdbOperationDefine.cpp index d9aa860f71f..ce4a28c1273 100644 --- a/ndb/src/ndbapi/NdbOperationDefine.cpp +++ b/ndb/src/ndbapi/NdbOperationDefine.cpp @@ -14,28 +14,17 @@ along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ - -/***************************************************************************** - * Name: NdbOperationDefine.C - * Include: - * Link: - * Author: UABMNST Mona Natterkvist UAB/B/SD - * Date: 970829 - * Version: 0.1 - * Description: Interface between TIS and NDB - * Documentation: - * Adjust: 971022 UABMNST First version. - *****************************************************************************/ -#include "NdbOperation.hpp" +#include <ndb_global.h> +#include <NdbOperation.hpp> #include "NdbApiSignal.hpp" -#include "NdbConnection.hpp" -#include "Ndb.hpp" -#include "NdbRecAttr.hpp" +#include <NdbTransaction.hpp> +#include <Ndb.hpp> +#include <NdbRecAttr.hpp> #include "NdbUtil.hpp" #include "NdbOut.hpp" #include "NdbImpl.hpp" #include <NdbIndexScanOperation.hpp> -#include "NdbBlob.hpp" +#include <NdbBlob.hpp> #include <Interpreter.hpp> @@ -48,7 +37,7 @@ int NdbOperation::insertTuple() { - NdbConnection* tNdbCon = theNdbCon; + NdbTransaction* tNdbCon = theNdbCon; int tErrorLine = theErrorLine; if (theStatus == Init) { theStatus = OperationDefined; @@ -68,7 +57,7 @@ NdbOperation::insertTuple() int NdbOperation::updateTuple() { - NdbConnection* tNdbCon = theNdbCon; + NdbTransaction* tNdbCon = theNdbCon; int tErrorLine = theErrorLine; if (theStatus == Init) { theStatus = OperationDefined; @@ -88,7 +77,7 @@ NdbOperation::updateTuple() int NdbOperation::writeTuple() { - NdbConnection* tNdbCon = theNdbCon; + NdbTransaction* tNdbCon = theNdbCon; int tErrorLine = theErrorLine; if (theStatus == Init) { theStatus = OperationDefined; @@ -128,7 +117,7 @@ NdbOperation::readTuple(NdbOperation::LockMode lm) int NdbOperation::readTuple() { - NdbConnection* tNdbCon = theNdbCon; + NdbTransaction* tNdbCon = theNdbCon; int tErrorLine = theErrorLine; if (theStatus == Init) { theStatus = OperationDefined; @@ -149,7 +138,7 @@ NdbOperation::readTuple() int NdbOperation::deleteTuple() { - NdbConnection* tNdbCon = theNdbCon; + NdbTransaction* tNdbCon = theNdbCon; int tErrorLine = theErrorLine; if (theStatus == Init) { theStatus = OperationDefined; @@ -170,7 +159,7 @@ NdbOperation::deleteTuple() int NdbOperation::readTupleExclusive() { - NdbConnection* tNdbCon = theNdbCon; + NdbTransaction* tNdbCon = theNdbCon; int tErrorLine = theErrorLine; if (theStatus == Init) { theStatus = OperationDefined; @@ -247,7 +236,7 @@ NdbOperation::committedRead() int NdbOperation::dirtyUpdate() { - NdbConnection* tNdbCon = theNdbCon; + NdbTransaction* tNdbCon = theNdbCon; int tErrorLine = theErrorLine; if (theStatus == Init) { theStatus = OperationDefined; @@ -270,7 +259,7 @@ NdbOperation::dirtyUpdate() int NdbOperation::dirtyWrite() { - NdbConnection* tNdbCon = theNdbCon; + NdbTransaction* tNdbCon = theNdbCon; int tErrorLine = theErrorLine; if (theStatus == Init) { theStatus = OperationDefined; @@ -293,7 +282,7 @@ NdbOperation::dirtyWrite() int NdbOperation::interpretedUpdateTuple() { - NdbConnection* tNdbCon = theNdbCon; + NdbTransaction* tNdbCon = theNdbCon; int tErrorLine = theErrorLine; if (theStatus == Init) { theStatus = OperationDefined; @@ -316,7 +305,7 @@ NdbOperation::interpretedUpdateTuple() int NdbOperation::interpretedDeleteTuple() { - NdbConnection* tNdbCon = theNdbCon; + NdbTransaction* tNdbCon = theNdbCon; int tErrorLine = theErrorLine; if (theStatus == Init) { theStatus = OperationDefined; @@ -520,16 +509,6 @@ NdbOperation::setValue( const NdbColumnImpl* tAttrInfo, // Insert Attribute Id into ATTRINFO part. const Uint32 sizeInBytes = tAttrInfo->m_attrSize * tAttrInfo->m_arraySize; - CHARSET_INFO* cs = tAttrInfo->m_cs; - // invalid data can crash kernel - if (cs != NULL && - (*cs->cset->well_formed_len)(cs, - aValue, - aValue + sizeInBytes, - sizeInBytes) != sizeInBytes) { - setErrorCodeAbort(744); - return -1; - } #if 0 tAttrSize = tAttrInfo->theAttrSize; tArraySize = tAttrInfo->theArraySize; @@ -588,7 +567,7 @@ NdbOperation::setValue( const NdbColumnImpl* tAttrInfo, }//NdbOperation::setValue() NdbBlob* -NdbOperation::getBlobHandle(NdbConnection* aCon, const NdbColumnImpl* tAttrInfo) +NdbOperation::getBlobHandle(NdbTransaction* aCon, const NdbColumnImpl* tAttrInfo) { NdbBlob* tBlob = theBlobList; NdbBlob* tLastBlob = NULL; diff --git a/ndb/src/ndbapi/NdbOperationExec.cpp b/ndb/src/ndbapi/NdbOperationExec.cpp index 9a461e1deef..4200300615d 100644 --- a/ndb/src/ndbapi/NdbOperationExec.cpp +++ b/ndb/src/ndbapi/NdbOperationExec.cpp @@ -16,7 +16,7 @@ #include <ndb_global.h> #include <NdbOperation.hpp> -#include <NdbConnection.hpp> +#include <NdbTransaction.hpp> #include "NdbApiSignal.hpp" #include <Ndb.hpp> #include <NdbRecAttr.hpp> @@ -543,10 +543,11 @@ NdbOperation::receiveTCKEYREF( NdbApiSignal* aSignal) theStatus = Finished; // blobs want this if (m_abortOption != AO_IgnoreError) - theNdbCon->theReturnStatus = NdbConnection::ReturnFailure; - + { + theNdbCon->theReturnStatus = NdbTransaction::ReturnFailure; + } theError.code = aSignal->readData(4); - theNdbCon->setOperationErrorCodeAbort(aSignal->readData(4), m_abortOption); + theNdbCon->setOperationErrorCodeAbort(aSignal->readData(4), ao); if(theOperationType != ReadRequest || !theSimpleIndicator) // not simple read return theNdbCon->OpCompleteFailure(ao, m_abortOption != AO_IgnoreError); diff --git a/ndb/src/ndbapi/NdbOperationInt.cpp b/ndb/src/ndbapi/NdbOperationInt.cpp index ee7b8132cd1..8e704ca4263 100644 --- a/ndb/src/ndbapi/NdbOperationInt.cpp +++ b/ndb/src/ndbapi/NdbOperationInt.cpp @@ -14,23 +14,11 @@ along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ - -/************************************************************************************************ -Name: NdbOperationInt.C -Include: -Link: -Author: UABRONM Mikael Ronström UAB/M/MT -Date: 991029 -Version: 0.1 -Description: Interpreted operations in NDB API -Documentation: -Adjust: 991029 UABRONM First version. -************************************************************************************************/ -#include "NdbOperation.hpp" +#include <NdbOperation.hpp> #include "NdbApiSignal.hpp" -#include "NdbConnection.hpp" -#include "Ndb.hpp" -#include "NdbRecAttr.hpp" +#include <NdbTransaction.hpp> +#include <Ndb.hpp> +#include <NdbRecAttr.hpp> #include "NdbUtil.hpp" #include "Interpreter.hpp" #include <NdbIndexScanOperation.hpp> @@ -94,7 +82,7 @@ NdbOperation::incCheck(const NdbColumnImpl* tNdbColumnImpl) } return tNdbColumnImpl->m_attrId; } else { - if (theNdbCon->theCommitStatus == NdbConnection::Started) + if (theNdbCon->theCommitStatus == NdbTransaction::Started) setErrorCodeAbort(4200); } return -1; @@ -146,7 +134,7 @@ NdbOperation::write_attrCheck(const NdbColumnImpl* tNdbColumnImpl) } return tNdbColumnImpl->m_attrId; } else { - if (theNdbCon->theCommitStatus == NdbConnection::Started) + if (theNdbCon->theCommitStatus == NdbTransaction::Started) setErrorCodeAbort(4200); } return -1; @@ -194,7 +182,7 @@ NdbOperation::read_attrCheck(const NdbColumnImpl* tNdbColumnImpl) } return tNdbColumnImpl->m_attrId; } else { - if (theNdbCon->theCommitStatus == NdbConnection::Started) + if (theNdbCon->theCommitStatus == NdbTransaction::Started) setErrorCodeAbort(4200); } return -1; @@ -230,7 +218,7 @@ NdbOperation::initial_interpreterCheck() } return 0; } else { - if (theNdbCon->theCommitStatus == NdbConnection::Started) + if (theNdbCon->theCommitStatus == NdbTransaction::Started) setErrorCodeAbort(4200); } return -1; @@ -256,7 +244,7 @@ NdbOperation::labelCheck() } return 0; } else { - if (theNdbCon->theCommitStatus == NdbConnection::Started) + if (theNdbCon->theCommitStatus == NdbTransaction::Started) setErrorCodeAbort(4200); } return -1; @@ -276,7 +264,7 @@ NdbOperation::intermediate_interpreterCheck() } return 0; } else { - if (theNdbCon->theCommitStatus == NdbConnection::Started) + if (theNdbCon->theCommitStatus == NdbTransaction::Started) setErrorCodeAbort(4200); } return -1; @@ -1022,26 +1010,31 @@ NdbOperation::insertCall(Uint32 aCall) int NdbOperation::branch_col(Uint32 type, - Uint32 ColId, const char * val, Uint32 len, + Uint32 ColId, const void * val, Uint32 len, bool nopad, Uint32 Label){ if (initial_interpreterCheck() == -1) return -1; Interpreter::BinaryCondition c = (Interpreter::BinaryCondition)type; - - const NdbDictionary::Column * col = + + const NdbColumnImpl * col = m_currentTable->getColumn(ColId); if(col == 0){ abort(); } - Uint32 vc = col->getType() == NdbDictionary::Column::Varchar; - Uint32 colLen = col->getLength() + 2 * vc; - Uint32 al = (4 - (colLen & 3)) & 0x3; + Uint32 sizeInBytes = col->m_attrSize * col->m_arraySize; + if(len != 0 && len != sizeInBytes) + { + setErrorCodeAbort(4209); + return -1; + } - if (insertATTRINFO(Interpreter::BranchCol(c, al, vc, nopad)) == -1) + len = sizeInBytes; + + if (insertATTRINFO(Interpreter::BranchCol(c, 0, 0, false)) == -1) return -1; if (insertBranch(Label) == -1) @@ -1059,7 +1052,7 @@ NdbOperation::branch_col(Uint32 type, Uint32 tmp = 0; for (Uint32 i = 0; i < len-len2; i++) { char* p = (char*)&tmp; - p[i] = val[len2+i]; + p[i] = ((char*)val)[len2+i]; } insertATTRINFO(tmp); } @@ -1069,54 +1062,54 @@ NdbOperation::branch_col(Uint32 type, } int -NdbOperation::branch_col_eq(Uint32 ColId, const char * val, Uint32 len, +NdbOperation::branch_col_eq(Uint32 ColId, const void * val, Uint32 len, bool nopad, Uint32 Label){ INT_DEBUG(("branch_col_eq %u %.*s(%u,%d) -> %u", ColId, len, val, len, nopad, Label)); return branch_col(Interpreter::EQ, ColId, val, len, nopad, Label); } int -NdbOperation::branch_col_ne(Uint32 ColId, const char * val, Uint32 len, +NdbOperation::branch_col_ne(Uint32 ColId, const void * val, Uint32 len, bool nopad, Uint32 Label){ INT_DEBUG(("branch_col_ne %u %.*s(%u,%d) -> %u", ColId, len, val, len, nopad, Label)); return branch_col(Interpreter::NE, ColId, val, len, nopad, Label); } int -NdbOperation::branch_col_lt(Uint32 ColId, const char * val, Uint32 len, +NdbOperation::branch_col_lt(Uint32 ColId, const void * val, Uint32 len, bool nopad, Uint32 Label){ INT_DEBUG(("branch_col_lt %u %.*s(%u,%d) -> %u", ColId, len, val, len, nopad, Label)); return branch_col(Interpreter::LT, ColId, val, len, nopad, Label); } int -NdbOperation::branch_col_le(Uint32 ColId, const char * val, Uint32 len, +NdbOperation::branch_col_le(Uint32 ColId, const void * val, Uint32 len, bool nopad, Uint32 Label){ INT_DEBUG(("branch_col_le %u %.*s(%u,%d) -> %u", ColId, len, val, len, nopad, Label)); return branch_col(Interpreter::LE, ColId, val, len, nopad, Label); } int -NdbOperation::branch_col_gt(Uint32 ColId, const char * val, Uint32 len, +NdbOperation::branch_col_gt(Uint32 ColId, const void * val, Uint32 len, bool nopad, Uint32 Label){ INT_DEBUG(("branch_col_gt %u %.*s(%u,%d) -> %u", ColId, len, val, len, nopad, Label)); return branch_col(Interpreter::GT, ColId, val, len, nopad, Label); } int -NdbOperation::branch_col_ge(Uint32 ColId, const char * val, Uint32 len, +NdbOperation::branch_col_ge(Uint32 ColId, const void * val, Uint32 len, bool nopad, Uint32 Label){ INT_DEBUG(("branch_col_ge %u %.*s(%u,%d) -> %u", ColId, len, val, len, nopad, Label)); return branch_col(Interpreter::GE, ColId, val, len, nopad, Label); } int -NdbOperation::branch_col_like(Uint32 ColId, const char * val, Uint32 len, +NdbOperation::branch_col_like(Uint32 ColId, const void * val, Uint32 len, bool nopad, Uint32 Label){ INT_DEBUG(("branch_col_like %u %.*s(%u,%d) -> %u", ColId, len, val, len, nopad, Label)); return branch_col(Interpreter::LIKE, ColId, val, len, nopad, Label); } int -NdbOperation::branch_col_notlike(Uint32 ColId, const char * val, Uint32 len, - bool nopad, Uint32 Label){ +NdbOperation::branch_col_notlike(Uint32 ColId, const void * val, Uint32 len, + bool nopad, Uint32 Label){ INT_DEBUG(("branch_col_notlike %u %.*s(%u,%d) -> %u", ColId,len,val,len,nopad,Label)); return branch_col(Interpreter::NOT_LIKE, ColId, val, len, nopad, Label); } diff --git a/ndb/src/ndbapi/NdbOperationSearch.cpp b/ndb/src/ndbapi/NdbOperationSearch.cpp index 7ae5bd70a11..70850bcc66b 100644 --- a/ndb/src/ndbapi/NdbOperationSearch.cpp +++ b/ndb/src/ndbapi/NdbOperationSearch.cpp @@ -31,7 +31,7 @@ Adjust: 971022 UABMNST First version. #include <NdbOperation.hpp> #include "NdbApiSignal.hpp" -#include <NdbConnection.hpp> +#include <NdbTransaction.hpp> #include <Ndb.hpp> #include "NdbImpl.hpp" #include <NdbOut.hpp> @@ -62,7 +62,6 @@ NdbOperation::equal_impl(const NdbColumnImpl* tAttrInfo, Uint32 tData; Uint32 tKeyInfoPosition; const char* aValue = aValuePassed; - Uint64 xfrmData[512]; Uint64 tempData[512]; if ((theStatus == OperationDefined) && @@ -140,21 +139,6 @@ NdbOperation::equal_impl(const NdbColumnImpl* tAttrInfo, aValue = (char*)&tempData[0]; }//if } - const char* aValueToWrite = aValue; - - CHARSET_INFO* cs = tAttrInfo->m_cs; - if (cs != 0) { - // current limitation: strxfrm does not increase length - assert(cs->strxfrm_multiply <= 1); - ((Uint32*)xfrmData)[sizeInBytes >> 2] = 0; - unsigned n = - (*cs->coll->strnxfrm)(cs, - (uchar*)xfrmData, sizeof(xfrmData), - (const uchar*)aValue, sizeInBytes); - while (n < sizeInBytes) - ((uchar*)xfrmData)[n++] = 0x20; - aValue = (char*)xfrmData; - } Uint32 totalSizeInWords = (sizeInBytes + 3)/4; // Inc. bits in last word @@ -200,13 +184,6 @@ NdbOperation::equal_impl(const NdbColumnImpl* tAttrInfo, *************************************************************************/ if ((tOpType == InsertRequest) || (tOpType == WriteRequest)) { - // invalid data can crash kernel - if (cs != NULL && - (*cs->cset->well_formed_len)(cs, - aValueToWrite, - aValueToWrite + sizeInBytes, - sizeInBytes) != sizeInBytes) - goto equal_error4; Uint32 ahValue; const Uint32 sz = totalSizeInWords; @@ -224,7 +201,7 @@ NdbOperation::equal_impl(const NdbColumnImpl* tAttrInfo, } insertATTRINFO( ahValue ); - insertATTRINFOloop((Uint32*)aValueToWrite, sz); + insertATTRINFOloop((Uint32*)aValue, sz); }//if /************************************************************************** @@ -321,36 +298,6 @@ NdbOperation::equal_impl(const NdbColumnImpl* tAttrInfo, equal_error3: setErrorCodeAbort(4209); return -1; - - equal_error4: - setErrorCodeAbort(744); - return -1; -} - -/****************************************************************************** - * Uint64 setTupleId( void ) - * - * Return Value: Return > 0: OK - * Return 0 : setTupleId failed - * Parameters: - * Remark: - *****************************************************************************/ -Uint64 -NdbOperation::setTupleId() -{ - if (theStatus != OperationDefined) - { - return 0; - } - Uint64 tTupleId = theNdb->getTupleIdFromNdb(m_currentTable->m_tableId); - if (tTupleId == ~(Uint64)0){ - setErrorCodeAbort(theNdb->theError.code); - return 0; - } - if (equal((Uint32)0, tTupleId) == -1) - return 0; - - return tTupleId; } /****************************************************************************** @@ -539,8 +486,10 @@ NdbOperation::handle_distribution_key(const Uint64* value, Uint32 len) { setPartitionHash(value, len); } - else + else if(theTCREQ->readSignalNumber() == GSN_TCKEYREQ) { + // No support for combined distribution key and scan + /** * Copy distribution key to linear memory */ diff --git a/ndb/src/ndbapi/NdbReceiver.cpp b/ndb/src/ndbapi/NdbReceiver.cpp index cad247512b2..df16ae66915 100644 --- a/ndb/src/ndbapi/NdbReceiver.cpp +++ b/ndb/src/ndbapi/NdbReceiver.cpp @@ -20,7 +20,7 @@ #include "NdbDictionaryImpl.hpp" #include <NdbRecAttr.hpp> #include <AttributeHeader.hpp> -#include <NdbConnection.hpp> +#include <NdbTransaction.hpp> #include <TransporterFacade.hpp> #include <signaldata/TcKeyConf.hpp> @@ -140,7 +140,10 @@ NdbReceiver::calculate_batch_size(Uint32 key_size, } void -NdbReceiver::do_get_value(NdbReceiver * org, Uint32 rows, Uint32 key_size){ +NdbReceiver::do_get_value(NdbReceiver * org, + Uint32 rows, + Uint32 key_size, + Uint32 range_no){ if(rows > m_defined_rows){ delete[] m_rows; m_defined_rows = rows; @@ -155,7 +158,7 @@ NdbReceiver::do_get_value(NdbReceiver * org, Uint32 rows, Uint32 key_size){ key.m_attrSize = 4; key.m_nullable = true; // So that receive works w.r.t KEYINFO20 } - m_key_info = key_size; + m_hidden_count = (key_size ? 1 : 0) + range_no ; for(Uint32 i = 0; i<rows; i++){ NdbRecAttr * prev = theCurrentRecAttr; @@ -167,6 +170,12 @@ NdbReceiver::do_get_value(NdbReceiver * org, Uint32 rows, Uint32 key_size){ return ; // -1 } + if(range_no && + !getValue(&NdbColumnImpl::getImpl(* NdbDictionary::Column::RANGE_NO),0)) + { + abort(); + } + NdbRecAttr* tRecAttr = org->theFirstRecAttr; while(tRecAttr != 0){ if(getValue(&NdbColumnImpl::getImpl(*tRecAttr->m_column), (char*)0) != 0) @@ -192,14 +201,14 @@ NdbReceiver::do_get_value(NdbReceiver * org, Uint32 rows, Uint32 key_size){ return; } -void +NdbRecAttr* NdbReceiver::copyout(NdbReceiver & dstRec){ - NdbRecAttr* src = m_rows[m_current_row++]; - NdbRecAttr* dst = dstRec.theFirstRecAttr; - Uint32 tmp = m_key_info; - if(tmp > 0){ + NdbRecAttr *src = m_rows[m_current_row++]; + NdbRecAttr *dst = dstRec.theFirstRecAttr; + NdbRecAttr *start = src; + Uint32 tmp = m_hidden_count; + while(tmp--) src = src->next(); - } while(dst){ Uint32 len = ((src->theAttrSize * src->theArraySize)+3)/4; @@ -207,6 +216,8 @@ NdbReceiver::copyout(NdbReceiver & dstRec){ src = src->next(); dst = dst->next(); } + + return start; } int diff --git a/ndb/src/ndbapi/NdbResultSet.cpp b/ndb/src/ndbapi/NdbResultSet.cpp deleted file mode 100644 index d9d71464026..00000000000 --- a/ndb/src/ndbapi/NdbResultSet.cpp +++ /dev/null @@ -1,103 +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 */ - -/***************************************************************************** - * Name: NdbResultSet.cpp - * Include: - * Link: - * Author: UABMASD Martin Sköld INN/V Alzato - * Date: 2002-04-01 - * Version: 0.1 - * Description: Cursor class - * Documentation: - * Adjust: 2002-04-01 UABMASD First version. - ****************************************************************************/ - -#include <Ndb.hpp> -#include <NdbConnection.hpp> -#include <NdbResultSet.hpp> -#include <NdbBlob.hpp> - -NdbResultSet::NdbResultSet(NdbScanOperation *owner) -: m_operation(owner) -{ -} - -NdbResultSet::~NdbResultSet() -{ -} - -void NdbResultSet::init() -{ -} - -int NdbResultSet::nextResult(bool fetchAllowed, bool forceSend) -{ - int res; - if ((res = m_operation->nextResult(fetchAllowed, forceSend)) == 0) { - // handle blobs - NdbBlob* tBlob = m_operation->theBlobList; - while (tBlob != 0) { - if (tBlob->atNextResult() == -1) - return -1; - tBlob = tBlob->theNext; - } - /* - * Flush blob part ops on behalf of user because - * - nextResult is analogous to execute(NoCommit) - * - user is likely to want blob value before next execute - */ - if (m_operation->m_transConnection->executePendingBlobOps() == -1) - return -1; - return 0; - } - return res; -} - -void NdbResultSet::close(bool forceSend) -{ - m_operation->closeScan(forceSend); -} - -NdbOperation* -NdbResultSet::updateTuple(){ - return updateTuple(m_operation->m_transConnection); -} - -NdbOperation* -NdbResultSet::updateTuple(NdbConnection* takeOverTrans){ - return m_operation->takeOverScanOp(NdbOperation::UpdateRequest, - takeOverTrans); -} - -int -NdbResultSet::deleteTuple(){ - return deleteTuple(m_operation->m_transConnection); -} - -int -NdbResultSet::deleteTuple(NdbConnection * takeOverTrans){ - void * res = m_operation->takeOverScanOp(NdbOperation::DeleteRequest, - takeOverTrans); - if(res == 0) - return -1; - return 0; -} - -int -NdbResultSet::restart(bool forceSend){ - return m_operation->restart(forceSend); -} diff --git a/ndb/src/ndbapi/NdbScanFilter.cpp b/ndb/src/ndbapi/NdbScanFilter.cpp index 0c851427ba5..f3f73c75ac0 100644 --- a/ndb/src/ndbapi/NdbScanFilter.cpp +++ b/ndb/src/ndbapi/NdbScanFilter.cpp @@ -48,11 +48,8 @@ public: int cond_col(Interpreter::UnaryCondition, Uint32 attrId); - template<typename T> - int cond_col_const(Interpreter::BinaryCondition, Uint32 attrId, T value); - int cond_col_const(Interpreter::BinaryCondition, Uint32 attrId, - const char * value, Uint32 len, bool nopad); + const void * value, Uint32 len); }; const Uint32 LabelExit = ~0; @@ -247,68 +244,7 @@ NdbScanFilter::isfalse(){ typedef int (NdbOperation:: * Branch1)(Uint32, Uint32 label); -typedef int (NdbOperation:: * Branch2)(Uint32, Uint32, Uint32 label); -typedef int (NdbOperation:: * StrBranch2)(Uint32, const char*,Uint32,bool,Uint32); - -struct tab { - Branch2 m_branches[5]; -}; - -static const tab table[] = { - /** - * EQ (AND, OR, NAND, NOR) - */ - { { 0, - &NdbOperation::branch_ne, - &NdbOperation::branch_eq, - &NdbOperation::branch_eq, - &NdbOperation::branch_ne } } - - /** - * NEQ - */ - ,{ { 0, - &NdbOperation::branch_eq, - &NdbOperation::branch_ne, - &NdbOperation::branch_ne, - &NdbOperation::branch_eq } } - - /** - * LT - */ - ,{ { 0, - &NdbOperation::branch_le, - &NdbOperation::branch_gt, - &NdbOperation::branch_gt, - &NdbOperation::branch_le } } - - /** - * LE - */ - ,{ { 0, - &NdbOperation::branch_lt, - &NdbOperation::branch_ge, - &NdbOperation::branch_ge, - &NdbOperation::branch_lt } } - - /** - * GT - */ - ,{ { 0, - &NdbOperation::branch_ge, - &NdbOperation::branch_lt, - &NdbOperation::branch_lt, - &NdbOperation::branch_ge } } - - /** - * GE - */ - ,{ { 0, - &NdbOperation::branch_gt, - &NdbOperation::branch_le, - &NdbOperation::branch_le, - &NdbOperation::branch_gt } } -}; +typedef int (NdbOperation:: * StrBranch2)(Uint32, const void*, Uint32, bool, Uint32); struct tab2 { Branch1 m_branches[5]; @@ -334,134 +270,9 @@ static const tab2 table2[] = { &NdbOperation::branch_col_eq_null } } }; -const int tab_sz = sizeof(table)/sizeof(table[0]); const int tab2_sz = sizeof(table2)/sizeof(table2[0]); int -matchType(const NdbDictionary::Column * col){ - return 1; -} - -template<typename T> int load_const(NdbOperation* op, T value, Uint32 reg); - -template<> -int -load_const(NdbOperation* op, Uint32 value, Uint32 reg){ - return op->load_const_u32(reg, value); -} - -template<> -int -load_const(NdbOperation* op, Uint64 value, Uint32 reg){ - return op->load_const_u64(reg, value); -} - -template<typename T> -int -NdbScanFilterImpl::cond_col_const(Interpreter::BinaryCondition op, - Uint32 AttrId, T value){ - - if(op < 0 || op >= tab_sz){ - m_operation->setErrorCodeAbort(4262); - return -1; - } - - if(m_current.m_group < NdbScanFilter::AND || - m_current.m_group > NdbScanFilter::NOR){ - m_operation->setErrorCodeAbort(4260); - return -1; - } - - Branch2 branch = table[op].m_branches[m_current.m_group]; - const NdbDictionary::Column * col = - m_operation->m_currentTable->getColumn(AttrId); - - if(col == 0){ - m_operation->setErrorCodeAbort(4261); - return -1; - } - - if(!matchType(col)){ - /** - * Code not reached - */ - return -1; - } - - if(m_latestAttrib != AttrId){ - m_operation->read_attr(&NdbColumnImpl::getImpl(* col), 4); - m_latestAttrib = AttrId; - } - - load_const<T>(m_operation, value, 5); - (m_operation->* branch)(4, 5, m_current.m_ownLabel); - - return 0; -} - -int -NdbScanFilter::eq(int AttrId, Uint32 value){ - return m_impl.cond_col_const(Interpreter::EQ, AttrId, value); -} - -int -NdbScanFilter::ne(int AttrId, Uint32 value){ - return m_impl.cond_col_const(Interpreter::NE, AttrId, value); -} - -int -NdbScanFilter::lt(int AttrId, Uint32 value){ - return m_impl.cond_col_const(Interpreter::LT, AttrId, value); -} - -int -NdbScanFilter::le(int AttrId, Uint32 value){ - return m_impl.cond_col_const(Interpreter::LE, AttrId, value); -} - -int -NdbScanFilter::gt(int AttrId, Uint32 value){ - return m_impl.cond_col_const(Interpreter::GT, AttrId, value); -} - -int -NdbScanFilter::ge(int AttrId, Uint32 value){ - return m_impl.cond_col_const(Interpreter::GE, AttrId, value); -} - - -int -NdbScanFilter::eq(int AttrId, Uint64 value){ - return m_impl.cond_col_const(Interpreter::EQ, AttrId, value); -} - -int -NdbScanFilter::ne(int AttrId, Uint64 value){ - return m_impl.cond_col_const(Interpreter::NE, AttrId, value); -} - -int -NdbScanFilter::lt(int AttrId, Uint64 value){ - return m_impl.cond_col_const(Interpreter::LT, AttrId, value); -} - -int -NdbScanFilter::le(int AttrId, Uint64 value){ - return m_impl.cond_col_const(Interpreter::LE, AttrId, value); -} - -int -NdbScanFilter::gt(int AttrId, Uint64 value){ - return m_impl.cond_col_const(Interpreter::GT, AttrId, value); -} - -int -NdbScanFilter::ge(int AttrId, Uint64 value){ - return m_impl.cond_col_const(Interpreter::GE, AttrId, value); -} - - -int NdbScanFilterImpl::cond_col(Interpreter::UnaryCondition op, Uint32 AttrId){ if(op < 0 || op >= tab2_sz){ @@ -570,11 +381,10 @@ static const tab3 table3[] = { const int tab3_sz = sizeof(table3)/sizeof(table3[0]); - int NdbScanFilterImpl::cond_col_const(Interpreter::BinaryCondition op, Uint32 AttrId, - const char * value, Uint32 len, bool nopad){ + const void * value, Uint32 len){ if(op < 0 || op >= tab3_sz){ m_operation->setErrorCodeAbort(4260); return -1; @@ -595,49 +405,31 @@ NdbScanFilterImpl::cond_col_const(Interpreter::BinaryCondition op, return -1; } - (m_operation->* branch)(AttrId, value, len, nopad, m_current.m_ownLabel); + (m_operation->* branch)(AttrId, value, len, false, m_current.m_ownLabel); return 0; } int -NdbScanFilter::eq(int ColId, const char * val, Uint32 len, bool nopad){ - return m_impl.cond_col_const(Interpreter::EQ, ColId, val, len, nopad); -} - -int -NdbScanFilter::ne(int ColId, const char * val, Uint32 len, bool nopad){ - return m_impl.cond_col_const(Interpreter::NE, ColId, val, len, nopad); -} - -int -NdbScanFilter::lt(int ColId, const char * val, Uint32 len, bool nopad){ - return m_impl.cond_col_const(Interpreter::LT, ColId, val, len, nopad); -} - -int -NdbScanFilter::le(int ColId, const char * val, Uint32 len, bool nopad){ - return m_impl.cond_col_const(Interpreter::LE, ColId, val, len, nopad); -} - -int -NdbScanFilter::gt(int ColId, const char * val, Uint32 len, bool nopad){ - return m_impl.cond_col_const(Interpreter::GT, ColId, val, len, nopad); -} - -int -NdbScanFilter::ge(int ColId, const char * val, Uint32 len, bool nopad){ - return m_impl.cond_col_const(Interpreter::GE, ColId, val, len, nopad); -} - -int -NdbScanFilter::like(int ColId, const char * val, Uint32 len, bool nopad){ - return m_impl.cond_col_const(Interpreter::LIKE, ColId, val, len, nopad); -} +NdbScanFilter::cmp(BinaryCondition cond, int ColId, + const void *val, Uint32 len) +{ + switch(cond){ + case COND_LE: + return m_impl.cond_col_const(Interpreter::LE, ColId, val, len); + case COND_LT: + return m_impl.cond_col_const(Interpreter::LT, ColId, val, len); + case COND_GE: + return m_impl.cond_col_const(Interpreter::GE, ColId, val, len); + case COND_GT: + return m_impl.cond_col_const(Interpreter::GT, ColId, val, len); + case COND_EQ: + return m_impl.cond_col_const(Interpreter::EQ, ColId, val, len); + case COND_NE: + return m_impl.cond_col_const(Interpreter::NE, ColId, val, len); + } + return -1; +} -int -NdbScanFilter::notlike(int ColId, const char * val, Uint32 len, bool nopad){ - return m_impl.cond_col_const(Interpreter::NOT_LIKE, ColId, val, len, nopad); -} #if 0 int @@ -778,10 +570,4 @@ main(void){ #endif template class Vector<NdbScanFilterImpl::State>; -#if __SUNPRO_CC != 0x560 -#ifndef _FORTEC_ -template int NdbScanFilterImpl::cond_col_const(Interpreter::BinaryCondition, Uint32 attrId, Uint32); -template int NdbScanFilterImpl::cond_col_const(Interpreter::BinaryCondition, Uint32 attrId, Uint64); -#endif -#endif diff --git a/ndb/src/ndbapi/NdbScanOperation.cpp b/ndb/src/ndbapi/NdbScanOperation.cpp index 1b8dbdde3d5..68cdce17b0d 100644 --- a/ndb/src/ndbapi/NdbScanOperation.cpp +++ b/ndb/src/ndbapi/NdbScanOperation.cpp @@ -18,11 +18,11 @@ #include <Ndb.hpp> #include <NdbScanOperation.hpp> #include <NdbIndexScanOperation.hpp> -#include <NdbConnection.hpp> -#include <NdbResultSet.hpp> +#include <NdbTransaction.hpp> #include "NdbApiSignal.hpp" #include <NdbOut.hpp> #include "NdbDictionaryImpl.hpp" +#include <NdbBlob.hpp> #include <NdbRecAttr.hpp> #include <NdbReceiver.hpp> @@ -39,7 +39,6 @@ NdbScanOperation::NdbScanOperation(Ndb* aNdb) : NdbOperation(aNdb), - m_resultSet(0), m_transConnection(NULL) { theParallelism = 0; @@ -60,24 +59,11 @@ NdbScanOperation::~NdbScanOperation() theNdb->releaseNdbScanRec(m_receivers[i]); } delete[] m_array; - if (m_resultSet) - delete m_resultSet; } -NdbResultSet* -NdbScanOperation::getResultSet() -{ - if (!m_resultSet) - m_resultSet = new NdbResultSet(this); - - return m_resultSet; -} - - - void NdbScanOperation::setErrorCode(int aErrorCode){ - NdbConnection* tmp = theNdbCon; + NdbTransaction* tmp = theNdbCon; theNdbCon = m_transConnection; NdbOperation::setErrorCode(aErrorCode); theNdbCon = tmp; @@ -85,7 +71,7 @@ NdbScanOperation::setErrorCode(int aErrorCode){ void NdbScanOperation::setErrorCodeAbort(int aErrorCode){ - NdbConnection* tmp = theNdbCon; + NdbTransaction* tmp = theNdbCon; theNdbCon = m_transConnection; NdbOperation::setErrorCodeAbort(aErrorCode); theNdbCon = tmp; @@ -100,11 +86,11 @@ NdbScanOperation::setErrorCodeAbort(int aErrorCode){ * Remark: Initiates operation record after allocation. *****************************************************************************/ int -NdbScanOperation::init(const NdbTableImpl* tab, NdbConnection* myConnection) +NdbScanOperation::init(const NdbTableImpl* tab, NdbTransaction* myConnection) { m_transConnection = myConnection; - //NdbConnection* aScanConnection = theNdb->startTransaction(myConnection); - NdbConnection* aScanConnection = theNdb->hupp(myConnection); + //NdbTransaction* aScanConnection = theNdb->startTransaction(myConnection); + NdbTransaction* aScanConnection = theNdb->hupp(myConnection); if (!aScanConnection){ setErrorCodeAbort(theNdb->getNdbError().code); return -1; @@ -121,14 +107,16 @@ NdbScanOperation::init(const NdbTableImpl* tab, NdbConnection* myConnection) theOperationType = OpenScanRequest; theNdbCon->theMagicNumber = 0xFE11DF; theNoOfTupKeyLeft = tab->m_noOfDistributionKeys; + m_read_range_no = 0; return 0; } -NdbResultSet* NdbScanOperation::readTuples(NdbScanOperation::LockMode lm, - Uint32 batch, - Uint32 parallel) +int +NdbScanOperation::readTuples(NdbScanOperation::LockMode lm, + Uint32 batch, + Uint32 parallel) { - m_ordered = 0; + m_ordered = m_descending = false; Uint32 fragCount = m_currentTable->m_fragmentCount; if (parallel > fragCount || parallel == 0) { @@ -141,7 +129,7 @@ NdbResultSet* NdbScanOperation::readTuples(NdbScanOperation::LockMode lm, // 3. theScanOp contains a NdbScanOperation if (theNdbCon->theScanningOp != NULL){ setErrorCode(4605); - return 0; + return -1; } theNdbCon->theScanningOp = this; @@ -166,14 +154,14 @@ NdbResultSet* NdbScanOperation::readTuples(NdbScanOperation::LockMode lm, break; default: setErrorCode(4003); - return 0; + return -1; } m_keyInfo = lockExcl ? 1 : 0; bool range = false; - if (m_accessTable->m_indexType == NdbDictionary::Index::OrderedIndex || - m_accessTable->m_indexType == NdbDictionary::Index::UniqueOrderedIndex){ + if (m_accessTable->m_indexType == NdbDictionary::Index::OrderedIndex) + { if (m_currentTable == m_accessTable){ // Old way of scanning indexes, should not be allowed m_currentTable = theNdb->theDictionary-> @@ -191,13 +179,13 @@ NdbResultSet* NdbScanOperation::readTuples(NdbScanOperation::LockMode lm, if(fix_receivers(parallel) == -1){ setErrorCodeAbort(4000); - return 0; + return -1; } theSCAN_TABREQ = (!theSCAN_TABREQ ? theNdb->getSignal() : theSCAN_TABREQ); if (theSCAN_TABREQ == NULL) { setErrorCodeAbort(4000); - return 0; + return -1; }//if theSCAN_TABREQ->setSignal(GSN_SCAN_TABREQ); @@ -233,7 +221,7 @@ NdbResultSet* NdbScanOperation::readTuples(NdbScanOperation::LockMode lm, theTotalNrOfKeyWordInSignal= 0; getFirstATTRINFOScan(); - return getResultSet(); + return 0; } int @@ -361,7 +349,7 @@ NdbScanOperation::getFirstATTRINFOScan() int NdbScanOperation::executeCursor(int nodeId){ - NdbConnection * tCon = theNdbCon; + NdbTransaction * tCon = theNdbCon; TransporterFacade* tp = TransporterFacade::instance(); Guard guard(tp->theMutexPtr); @@ -395,7 +383,7 @@ NdbScanOperation::executeCursor(int nodeId){ TRACE_DEBUG("The node is stopping when attempting to start a scan"); setErrorCode(4030); }//if - tCon->theCommitStatus = NdbConnection::Aborted; + tCon->theCommitStatus = NdbTransaction::Aborted; }//if return -1; } @@ -403,6 +391,29 @@ NdbScanOperation::executeCursor(int nodeId){ int NdbScanOperation::nextResult(bool fetchAllowed, bool forceSend) { + int res; + if ((res = nextResultImpl(fetchAllowed, forceSend)) == 0) { + // handle blobs + NdbBlob* tBlob = theBlobList; + while (tBlob != 0) { + if (tBlob->atNextResult() == -1) + return -1; + tBlob = tBlob->theNext; + } + /* + * Flush blob part ops on behalf of user because + * - nextResult is analogous to execute(NoCommit) + * - user is likely to want blob value before next execute + */ + if (m_transConnection->executePendingBlobOps() == -1) + return -1; + return 0; + } + return res; +} + +int NdbScanOperation::nextResultImpl(bool fetchAllowed, bool forceSend) +{ if(m_ordered) return ((NdbIndexScanOperation*)this)->next_result_ordered(fetchAllowed, forceSend); @@ -413,6 +424,7 @@ int NdbScanOperation::nextResult(bool fetchAllowed, bool forceSend) int retVal = 2; Uint32 idx = m_current_api_receiver; Uint32 last = m_api_receivers_count; + m_curr_row = 0; if(DEBUG_NEXT_RESULT) ndbout_c("nextResult(%d) idx=%d last=%d", fetchAllowed, idx, last); @@ -423,7 +435,7 @@ int NdbScanOperation::nextResult(bool fetchAllowed, bool forceSend) for(; idx < last; idx++){ NdbReceiver* tRec = m_api_receivers[idx]; if(tRec->nextResult()){ - tRec->copyout(theReceiver); + m_curr_row = tRec->copyout(theReceiver); retVal = 0; break; } @@ -499,7 +511,7 @@ int NdbScanOperation::nextResult(bool fetchAllowed, bool forceSend) for(; idx < last; idx++){ NdbReceiver* tRec = m_api_receivers[idx]; if(tRec->nextResult()){ - tRec->copyout(theReceiver); + m_curr_row = tRec->copyout(theReceiver); retVal = 0; break; } @@ -621,11 +633,11 @@ NdbScanOperation::doSend(int ProcessorId) return 0; } -void NdbScanOperation::closeScan(bool forceSend) +void NdbScanOperation::close(bool forceSend) { if(m_transConnection){ if(DEBUG_NEXT_RESULT) - ndbout_c("closeScan() theError.code = %d " + ndbout_c("close() theError.code = %d " "m_api_receivers_count = %d " "m_conf_receivers_count = %d " "m_sent_receivers_count = %d", @@ -656,7 +668,7 @@ NdbScanOperation::execCLOSE_SCAN_REP(){ void NdbScanOperation::release() { if(theNdbCon != 0 || m_transConnection != 0){ - closeScan(); + close(); } for(Uint32 i = 0; i<m_allocated_receivers; i++){ m_receivers[i]->release(); @@ -735,7 +747,9 @@ int NdbScanOperation::prepareSendScan(Uint32 aTC_ConnectPtr, req->requestInfo = reqInfo; for(Uint32 i = 0; i<theParallelism; i++){ - m_receivers[i]->do_get_value(&theReceiver, batch_size, key_size); + m_receivers[i]->do_get_value(&theReceiver, batch_size, + key_size, + m_read_range_no); } return 0; } @@ -777,8 +791,9 @@ NdbScanOperation::doSendScan(int aProcessorId) Uint32 tmp = req->requestInfo; ScanTabReq::setDistributionKeyFlag(tmp, theDistrKeyIndicator_); req->distributionKey = theDistributionKey; + req->requestInfo = tmp; tSignal->setLength(ScanTabReq::StaticLength + theDistrKeyIndicator_); - + TransporterFacade *tp = TransporterFacade::instance(); LinearSectionPtr ptr[3]; ptr[0].p = m_prepared_receivers; @@ -831,6 +846,7 @@ NdbScanOperation::doSendScan(int aProcessorId) } theStatus = WaitResponse; + m_curr_row = 0; m_sent_receivers_count = theParallelism; if(m_ordered) { @@ -842,9 +858,9 @@ NdbScanOperation::doSendScan(int aProcessorId) }//NdbOperation::doSendScan() /***************************************************************************** - * NdbOperation* takeOverScanOp(NdbConnection* updateTrans); + * NdbOperation* takeOverScanOp(NdbTransaction* updateTrans); * - * Parameters: The update transactions NdbConnection pointer. + * Parameters: The update transactions NdbTransaction pointer. * Return Value: A reference to the transferred operation object * or NULL if no success. * Remark: Take over the scanning transactions NdbOperation @@ -854,8 +870,8 @@ NdbScanOperation::doSendScan(int aProcessorId) * * FUTURE IMPLEMENTATION: (This note was moved from header file.) * In the future, it will even be possible to transfer - * to a NdbConnection on another Ndb-object. - * In this case the receiving NdbConnection-object must call + * to a NdbTransaction on another Ndb-object. + * In this case the receiving NdbTransaction-object must call * a method receiveOpFromScan to actually receive the information. * This means that the updating transactions can be placed * in separate threads and thus increasing the parallelism during @@ -864,16 +880,9 @@ NdbScanOperation::doSendScan(int aProcessorId) int NdbScanOperation::getKeyFromKEYINFO20(Uint32* data, unsigned size) { - Uint32 idx = m_current_api_receiver; - Uint32 last = m_api_receivers_count; - - Uint32 row; - NdbReceiver * tRec; - NdbRecAttr * tRecAttr; - if(idx < last && (tRec = m_api_receivers[idx]) - && ((row = tRec->m_current_row) <= tRec->m_defined_rows) - && (tRecAttr = tRec->m_rows[row-1])){ - + NdbRecAttr * tRecAttr = m_curr_row; + if(tRecAttr) + { const Uint32 * src = (Uint32*)tRecAttr->aRef(); memcpy(data, src, 4*size); return 0; @@ -882,18 +891,12 @@ NdbScanOperation::getKeyFromKEYINFO20(Uint32* data, unsigned size) } NdbOperation* -NdbScanOperation::takeOverScanOp(OperationType opType, NdbConnection* pTrans){ +NdbScanOperation::takeOverScanOp(OperationType opType, NdbTransaction* pTrans) +{ - Uint32 idx = m_current_api_receiver; - Uint32 last = m_api_receivers_count; - - Uint32 row; - NdbReceiver * tRec; - NdbRecAttr * tRecAttr; - if(idx < last && (tRec = m_api_receivers[idx]) - && ((row = tRec->m_current_row) <= tRec->m_defined_rows) - && (tRecAttr = tRec->m_rows[row-1])){ - + NdbRecAttr * tRecAttr = m_curr_row; + if(tRecAttr) + { NdbOperation * newOp = pTrans->getNdbOperation(m_currentTable); if (newOp == NULL){ return NULL; @@ -919,6 +922,8 @@ NdbScanOperation::takeOverScanOp(OperationType opType, NdbConnection* pTrans){ TcKeyReq::setTakeOverScanFragment(scanInfo, tTakeOverFragment); TcKeyReq::setTakeOverScanInfo(scanInfo, tScanInfo); newOp->theScanInfo = scanInfo; + newOp->theDistrKeyIndicator_ = 1; + newOp->theDistributionKey = tTakeOverFragment; } // Copy the first 8 words of key info from KEYINF20 into TCKEYREQ @@ -1072,29 +1077,6 @@ NdbIndexScanOperation::setBound(const NdbColumnImpl* tAttrInfo, setErrorCodeAbort(4209); return -1; } - - // normalize char bound - CHARSET_INFO* cs = tAttrInfo->m_cs; - Uint64 xfrmData[1001]; - if (cs != NULL && aValue != NULL) { - // current limitation: strxfrm does not increase length - assert(cs->strxfrm_multiply <= 1); - ((Uint32*)xfrmData)[len >> 2] = 0; - unsigned n = - (*cs->coll->strnxfrm)(cs, - (uchar*)xfrmData, sizeof(xfrmData), - (const uchar*)aValue, len); - - while (n < len) - ((uchar*)xfrmData)[n++] = 0x20; - - if(len & 3) - { - len += (4 - (len & 3)); - } - - aValue = (char*)xfrmData; - } // insert attribute header Uint32 tIndexAttrId = tAttrInfo->m_attrId; @@ -1117,7 +1099,7 @@ NdbIndexScanOperation::setBound(const NdbColumnImpl* tAttrInfo, theTotalNrOfKeyWordInSignal = currLen + totalLen; } else { if(!aligned || !nobytes){ - Uint32 *tempData = (Uint32*)xfrmData; + Uint32 tempData[2000]; tempData[0] = type; tempData[1] = ahValue; tempData[2 + (len >> 2)] = 0; @@ -1193,14 +1175,29 @@ error: return -1; } -NdbResultSet* +int NdbIndexScanOperation::readTuples(LockMode lm, Uint32 batch, Uint32 parallel, - bool order_by){ - NdbResultSet * rs = NdbScanOperation::readTuples(lm, batch, 0); - if(rs && order_by){ - m_ordered = 1; + bool order_by, + bool order_desc, + bool read_range_no){ + int res = NdbScanOperation::readTuples(lm, batch, 0); + if(!res && read_range_no) + { + m_read_range_no = 1; + Uint32 word = 0; + AttributeHeader::init(&word, AttributeHeader::RANGE_NO, 0); + if(insertATTRINFO(word) == -1) + res = -1; + } + if(!res && order_by){ + m_ordered = true; + if (order_desc) { + m_descending = true; + ScanTabReq * req = CAST_PTR(ScanTabReq, theSCAN_TABREQ->getDataPtrSend()); + ScanTabReq::setDescendingFlag(req->requestInfo, true); + } Uint32 cnt = m_accessTable->getNoOfColumns() - 1; m_sort_columns = cnt; // -1 for NDB$NODE m_current_api_receiver = m_sent_receivers_count; @@ -1222,7 +1219,7 @@ NdbIndexScanOperation::readTuples(LockMode lm, m_this_bound_start = 0; m_first_bound_word = theKEYINFOptr; - return rs; + return res; } void @@ -1264,22 +1261,23 @@ NdbIndexScanOperation::compare(Uint32 skip, Uint32 cols, r1 = (skip ? r1->next() : r1); r2 = (skip ? r2->next() : r2); - + const int jdir = 1 - 2 * (int)m_descending; + assert(jdir == 1 || jdir == -1); while(cols > 0){ Uint32 * d1 = (Uint32*)r1->aRef(); Uint32 * d2 = (Uint32*)r2->aRef(); unsigned r1_null = r1->isNULL(); if((r1_null ^ (unsigned)r2->isNULL())){ - return (r1_null ? -1 : 1); + return (r1_null ? -1 : 1) * jdir; } const NdbColumnImpl & col = NdbColumnImpl::getImpl(* r1->m_column); - Uint32 size = (r1->theAttrSize * r1->theArraySize + 3) / 4; + Uint32 len = r1->theAttrSize * r1->theArraySize; if(!r1_null){ - const NdbSqlUtil::Type& sqlType = NdbSqlUtil::getType(col.m_extType); - int r = (*sqlType.m_cmp)(col.m_cs, d1, d2, size, size); + const NdbSqlUtil::Type& sqlType = NdbSqlUtil::getType(col.m_type); + int r = (*sqlType.m_cmp)(col.m_cs, d1, len, d2, len, true); if(r){ assert(r != NdbSqlUtil::CmpUnknown); - return r; + return r * jdir; } } cols--; @@ -1293,6 +1291,7 @@ int NdbIndexScanOperation::next_result_ordered(bool fetchAllowed, bool forceSend){ + m_curr_row = 0; Uint32 u_idx = 0, u_last = 0; Uint32 s_idx = m_current_api_receiver; // first sorted Uint32 s_last = theParallelism; // last sorted @@ -1366,7 +1365,7 @@ NdbIndexScanOperation::next_result_ordered(bool fetchAllowed, s_idx, s_last); - Uint32 cols = m_sort_columns; + Uint32 cols = m_sort_columns + m_read_range_no; Uint32 skip = m_keyInfo; while(u_idx < u_last){ u_last--; @@ -1403,7 +1402,7 @@ NdbIndexScanOperation::next_result_ordered(bool fetchAllowed, tRec = m_api_receivers[s_idx]; if(s_idx < s_last && tRec->nextResult()){ - tRec->copyout(theReceiver); + m_curr_row = tRec->copyout(theReceiver); if(DEBUG_NEXT_RESULT) ndbout_c("return 0"); return 0; } @@ -1640,13 +1639,31 @@ NdbIndexScanOperation::reset_bounds(bool forceSend){ } int -NdbIndexScanOperation::set_new_bound() +NdbIndexScanOperation::end_of_bound(Uint32 no) { - Uint32 bound_head = * m_first_bound_word; - bound_head |= (theTupKeyLen - m_this_bound_start) << 16; - * m_first_bound_word = bound_head; - - m_first_bound_word = theKEYINFOptr + theTotalNrOfKeyWordInSignal;; - m_this_bound_start = theTupKeyLen; - return 0; + if(no < (1 << 13)) // Only 12-bits no of ranges + { + Uint32 bound_head = * m_first_bound_word; + bound_head |= (theTupKeyLen - m_this_bound_start) << 16 | (no << 4); + * m_first_bound_word = bound_head; + + m_first_bound_word = theKEYINFOptr + theTotalNrOfKeyWordInSignal;; + m_this_bound_start = theTupKeyLen; + return 0; + } + return -1; +} + +int +NdbIndexScanOperation::get_range_no() +{ + NdbRecAttr* tRecAttr = m_curr_row; + if(m_read_range_no && tRecAttr) + { + if(m_keyInfo) + tRecAttr = tRecAttr->next(); + Uint32 ret = *(Uint32*)tRecAttr->aRef(); + return ret; + } + return -1; } diff --git a/ndb/src/ndbapi/NdbConnection.cpp b/ndb/src/ndbapi/NdbTransaction.cpp index 29959a4ed7e..717089b8916 100644 --- a/ndb/src/ndbapi/NdbConnection.cpp +++ b/ndb/src/ndbapi/NdbTransaction.cpp @@ -16,7 +16,7 @@ #include <ndb_global.h> #include <NdbOut.hpp> -#include <NdbConnection.hpp> +#include <NdbTransaction.hpp> #include <NdbOperation.hpp> #include <NdbScanOperation.hpp> #include <NdbIndexScanOperation.hpp> @@ -34,13 +34,13 @@ #include <signaldata/TcHbRep.hpp> /***************************************************************************** -NdbConnection( Ndb* aNdb ); +NdbTransaction( Ndb* aNdb ); Return Value: None Parameters: aNdb: Pointers to the Ndb object Remark: Creates a connection object. *****************************************************************************/ -NdbConnection::NdbConnection( Ndb* aNdb ) : +NdbTransaction::NdbTransaction( Ndb* aNdb ) : theSendStatus(NotInit), theCallbackFunction(NULL), theCallbackObject(NULL), @@ -89,19 +89,19 @@ NdbConnection::NdbConnection( Ndb* aNdb ) : CHECK_SZ(m_db_nodes, NdbNodeBitmask::Size); CHECK_SZ(m_failed_db_nodes, NdbNodeBitmask::Size); -}//NdbConnection::NdbConnection() +}//NdbTransaction::NdbTransaction() /***************************************************************************** -~NdbConnection(); +~NdbTransaction(); Remark: Deletes the connection object. *****************************************************************************/ -NdbConnection::~NdbConnection() +NdbTransaction::~NdbTransaction() { - DBUG_ENTER("NdbConnection::~NdbConnection"); + DBUG_ENTER("NdbTransaction::~NdbTransaction"); theNdb->theImpl->theNdbObjectIdMap.unmap(theId, this); DBUG_VOID_RETURN; -}//NdbConnection::~NdbConnection() +}//NdbTransaction::~NdbTransaction() /***************************************************************************** void init(); @@ -109,7 +109,7 @@ void init(); Remark: Initialise connection object for new transaction. *****************************************************************************/ void -NdbConnection::init() +NdbTransaction::init() { theListState = NotInList; theInUseState = true; @@ -149,7 +149,7 @@ NdbConnection::init() // theBlobFlag = false; thePendingBlobOps = 0; -}//NdbConnection::init() +}//NdbTransaction::init() /***************************************************************************** setOperationErrorCode(int error); @@ -158,9 +158,9 @@ Remark: Sets an error code on the connection object from an operation object. *****************************************************************************/ void -NdbConnection::setOperationErrorCode(int error) +NdbTransaction::setOperationErrorCode(int error) { - DBUG_ENTER("NdbConnection::setOperationErrorCode"); + DBUG_ENTER("NdbTransaction::setOperationErrorCode"); setErrorCode(error); DBUG_VOID_RETURN; } @@ -172,9 +172,9 @@ Remark: Sets an error code on the connection object from an operation object. *****************************************************************************/ void -NdbConnection::setOperationErrorCodeAbort(int error, int abortOption) +NdbTransaction::setOperationErrorCodeAbort(int error, int abortOption) { - DBUG_ENTER("NdbConnection::setOperationErrorCodeAbort"); + DBUG_ENTER("NdbTransaction::setOperationErrorCodeAbort"); if (abortOption == -1) abortOption = m_abortOption; if (theTransactionIsStarted == false) { @@ -194,20 +194,20 @@ setErrorCode(int anErrorCode); Remark: Sets an error indication on the connection object. *****************************************************************************/ void -NdbConnection::setErrorCode(int error) +NdbTransaction::setErrorCode(int error) { - DBUG_ENTER("NdbConnection::setErrorCode"); + DBUG_ENTER("NdbTransaction::setErrorCode"); DBUG_PRINT("enter", ("error: %d, theError.code: %d", error, theError.code)); if (theError.code == 0) theError.code = error; DBUG_VOID_RETURN; -}//NdbConnection::setErrorCode() +}//NdbTransaction::setErrorCode() int -NdbConnection::restart(){ - DBUG_ENTER("NdbConnection::restart"); +NdbTransaction::restart(){ + DBUG_ENTER("NdbTransaction::restart"); if(theCompletionStatus == CompletedSuccess){ releaseCompletedOperations(); Uint64 tTransid = theNdb->theFirstTransId; @@ -232,23 +232,8 @@ void handleExecuteCompletion(void); Remark: Handle time-out on a transaction object. *****************************************************************************/ void -NdbConnection::handleExecuteCompletion() +NdbTransaction::handleExecuteCompletion() { - - if (theCompletionStatus == CompletedFailure) { - NdbOperation* tOpTemp = theFirstExecOpInList; - while (tOpTemp != NULL) { -/***************************************************************************** - * Ensure that all executing operations report failed for each - * read attribute when failure occurs. - * We do not want any operations to report both failure and - * success on different read attributes. - ****************************************************************************/ - tOpTemp->handleFailedAI_ElemLen(); - tOpTemp = tOpTemp->next(); - }//while - theReturnStatus = ReturnFailure; - }//if /*************************************************************************** * Move the NdbOperation objects from the list of executing * operations to list of completed @@ -265,7 +250,7 @@ NdbConnection::handleExecuteCompletion() }//if theSendStatus = InitState; return; -}//NdbConnection::handleExecuteCompletion() +}//NdbTransaction::handleExecuteCompletion() /***************************************************************************** int execute(ExecType aTypeOfExec, CommitType aTypeOfCommit, int forceSend); @@ -276,11 +261,11 @@ Parameters : aTypeOfExec: Type of execute. Remark: Initialise connection object for new transaction. *****************************************************************************/ int -NdbConnection::execute(ExecType aTypeOfExec, +NdbTransaction::execute(ExecType aTypeOfExec, AbortOption abortOption, int forceSend) { - DBUG_ENTER("NdbConnection::execute"); + DBUG_ENTER("NdbTransaction::execute"); DBUG_PRINT("enter", ("aTypeOfExec: %d, abortOption: %d", aTypeOfExec, abortOption)); @@ -411,11 +396,11 @@ NdbConnection::execute(ExecType aTypeOfExec, } int -NdbConnection::executeNoBlobs(ExecType aTypeOfExec, +NdbTransaction::executeNoBlobs(ExecType aTypeOfExec, AbortOption abortOption, int forceSend) { - DBUG_ENTER("NdbConnection::executeNoBlobs"); + DBUG_ENTER("NdbTransaction::executeNoBlobs"); DBUG_PRINT("enter", ("aTypeOfExec: %d, abortOption: %d", aTypeOfExec, abortOption)); @@ -424,7 +409,7 @@ NdbConnection::executeNoBlobs(ExecType aTypeOfExec, // since last execute or since beginning. If this works ok we will continue // by calling the poll with wait method. This method will return when // the NDB kernel has completed its task or when 10 seconds have passed. -// The NdbConnectionCallBack-method will receive the return code of the +// The NdbTransactionCallBack-method will receive the return code of the // transaction. The normal methods of reading error codes still apply. //------------------------------------------------------------------------ Ndb* tNdb = theNdb; @@ -472,7 +457,7 @@ NdbConnection::executeNoBlobs(ExecType aTypeOfExec, } thePendingBlobOps = 0; DBUG_RETURN(0); -}//NdbConnection::execute() +}//NdbTransaction::execute() /***************************************************************************** void executeAsynchPrepare(ExecType aTypeOfExec, @@ -490,12 +475,12 @@ Parameters : aTypeOfExec: Type of execute. Remark: Prepare a part of a transaction in an asynchronous manner. *****************************************************************************/ void -NdbConnection::executeAsynchPrepare( ExecType aTypeOfExec, +NdbTransaction::executeAsynchPrepare( ExecType aTypeOfExec, NdbAsynchCallback aCallback, void* anyObject, AbortOption abortOption) { - DBUG_ENTER("NdbConnection::executeAsynchPrepare"); + DBUG_ENTER("NdbTransaction::executeAsynchPrepare"); DBUG_PRINT("enter", ("aTypeOfExec: %d, aCallback: %x, anyObject: %x", aTypeOfExec, aCallback, anyObject)); @@ -658,14 +643,14 @@ NdbConnection::executeAsynchPrepare( ExecType aTypeOfExec, NdbNodeBitmask::clear(m_db_nodes); NdbNodeBitmask::clear(m_failed_db_nodes); DBUG_VOID_RETURN; -}//NdbConnection::executeAsynchPrepare() +}//NdbTransaction::executeAsynchPrepare() -void NdbConnection::close() +void NdbTransaction::close() { theNdb->closeTransaction(this); } -int NdbConnection::refresh(){ +int NdbTransaction::refresh(){ return sendTC_HBREP(); } @@ -677,7 +662,7 @@ Parameters : None. Remark: Order NDB to refresh the timeout counter of the transaction. ******************************************************************************/ int -NdbConnection::sendTC_HBREP() // Send a TC_HBREP signal; +NdbTransaction::sendTC_HBREP() // Send a TC_HBREP signal; { NdbApiSignal* tSignal; Ndb* tNdb = theNdb; @@ -712,7 +697,7 @@ NdbConnection::sendTC_HBREP() // Send a TC_HBREP signal; } return 0; -}//NdbConnection::sendTC_HBREP() +}//NdbTransaction::sendTC_HBREP() /***************************************************************************** int doSend(); @@ -724,9 +709,9 @@ Remark: Send all operations belonging to this connection. object from the prepared transactions array on the Ndb-object. *****************************************************************************/ int -NdbConnection::doSend() +NdbTransaction::doSend() { - DBUG_ENTER("NdbConnection::doSend"); + DBUG_ENTER("NdbTransaction::doSend"); /* This method assumes that at least one operation have been defined. This @@ -785,7 +770,7 @@ NdbConnection::doSend() theTransactionIsStarted = false; theCommitStatus = Aborted; DBUG_RETURN(-1); -}//NdbConnection::doSend() +}//NdbTransaction::doSend() /************************************************************************** int sendROLLBACK(); @@ -795,7 +780,7 @@ Parameters : None. Remark: Order NDB to rollback the transaction. **************************************************************************/ int -NdbConnection::sendROLLBACK() // Send a TCROLLBACKREQ signal; +NdbTransaction::sendROLLBACK() // Send a TCROLLBACKREQ signal; { Ndb* tNdb = theNdb; if ((theTransactionIsStarted == true) && @@ -839,7 +824,7 @@ NdbConnection::sendROLLBACK() // Send a TCROLLBACKREQ signal; return 0; ; }//if -}//NdbConnection::sendROLLBACK() +}//NdbTransaction::sendROLLBACK() /*************************************************************************** int sendCOMMIT(); @@ -850,7 +835,7 @@ Parameters : None. Remark: Order NDB to commit the transaction. ***************************************************************************/ int -NdbConnection::sendCOMMIT() // Send a TC_COMMITREQ signal; +NdbTransaction::sendCOMMIT() // Send a TC_COMMITREQ signal; { NdbApiSignal tSignal(theNdb->theMyRef); Uint32 tTransId1, tTransId2; @@ -872,7 +857,7 @@ NdbConnection::sendCOMMIT() // Send a TC_COMMITREQ signal; } else { return -1; }//if -}//NdbConnection::sendCOMMIT() +}//NdbTransaction::sendCOMMIT() /****************************************************************************** void release(); @@ -880,7 +865,7 @@ void release(); Remark: Release all operations. ******************************************************************************/ void -NdbConnection::release(){ +NdbTransaction::release(){ releaseOperations(); if ( (theTransactionIsStarted == true) && ((theCommitStatus != Committed) && @@ -899,10 +884,10 @@ NdbConnection::release(){ abort(); } #endif -}//NdbConnection::release() +}//NdbTransaction::release() void -NdbConnection::releaseOps(NdbOperation* tOp){ +NdbTransaction::releaseOps(NdbOperation* tOp){ while (tOp != NULL) { NdbOperation* tmp = tOp; tOp->release(); @@ -917,7 +902,7 @@ void releaseOperations(); Remark: Release all operations. ******************************************************************************/ void -NdbConnection::releaseOperations() +NdbTransaction::releaseOperations() { // Release any open scans releaseScanOperations(m_theFirstScanOperation); @@ -937,15 +922,15 @@ NdbConnection::releaseOperations() m_theFirstScanOperation = NULL; m_theLastScanOperation = NULL; m_firstExecutedScanOp = NULL; -}//NdbConnection::releaseOperations() +}//NdbTransaction::releaseOperations() void -NdbConnection::releaseCompletedOperations() +NdbTransaction::releaseCompletedOperations() { releaseOps(theCompletedFirstOp); theCompletedFirstOp = NULL; theCompletedLastOp = NULL; -}//NdbConnection::releaseOperations() +}//NdbTransaction::releaseOperations() /****************************************************************************** void releaseScanOperations(); @@ -954,7 +939,7 @@ Remark: Release all cursor operations. (NdbScanOperation and NdbIndexOperation) ******************************************************************************/ void -NdbConnection::releaseScanOperations(NdbIndexScanOperation* cursorOp) +NdbTransaction::releaseScanOperations(NdbIndexScanOperation* cursorOp) { while(cursorOp != 0){ NdbIndexScanOperation* next = (NdbIndexScanOperation*)cursorOp->next(); @@ -962,7 +947,7 @@ NdbConnection::releaseScanOperations(NdbIndexScanOperation* cursorOp) theNdb->releaseScanOperation(cursorOp); cursorOp = next; } -}//NdbConnection::releaseScanOperations() +}//NdbTransaction::releaseScanOperations() /***************************************************************************** NdbOperation* getNdbOperation(const char* aTableName); @@ -972,13 +957,13 @@ Return Value Return a pointer to a NdbOperation object if getNdbOperation Return NULL : In all other case. Parameters: aTableName : Name of the database table. Remark: Get an operation from NdbOperation idlelist and get the - NdbConnection object + NdbTransaction object who was fetch by startTransaction pointing to this operation getOperation will set the theTableId in the NdbOperation object. synchronous ******************************************************************************/ NdbOperation* -NdbConnection::getNdbOperation(const char* aTableName) +NdbTransaction::getNdbOperation(const char* aTableName) { if (theCommitStatus == Started){ NdbTableImpl* table = theNdb->theDictionary->getTable(aTableName); @@ -993,7 +978,7 @@ NdbConnection::getNdbOperation(const char* aTableName) setOperationErrorCodeAbort(4114); return NULL; -}//NdbConnection::getNdbOperation() +}//NdbTransaction::getNdbOperation() /***************************************************************************** NdbOperation* getNdbOperation(int aTableId); @@ -1003,13 +988,13 @@ Return Value Return a pointer to a NdbOperation object if getNdbOperation Return NULL: In all other case. Parameters: tableId : Id of the database table beeing deleted. Remark: Get an operation from NdbOperation object idlelist and - get the NdbConnection object who was fetch by + get the NdbTransaction object who was fetch by startTransaction pointing to this operation getOperation will set the theTableId in the NdbOperation object, synchronous. *****************************************************************************/ NdbOperation* -NdbConnection::getNdbOperation(const NdbTableImpl * tab, NdbOperation* aNextOp) +NdbTransaction::getNdbOperation(const NdbTableImpl * tab, NdbOperation* aNextOp) { NdbOperation* tOp; @@ -1053,15 +1038,15 @@ NdbConnection::getNdbOperation(const NdbTableImpl * tab, NdbOperation* aNextOp) getNdbOp_error1: setOperationErrorCodeAbort(4000); return NULL; -}//NdbConnection::getNdbOperation() +}//NdbTransaction::getNdbOperation() -NdbOperation* NdbConnection::getNdbOperation(const NdbDictionary::Table * table) +NdbOperation* NdbTransaction::getNdbOperation(const NdbDictionary::Table * table) { if (table) return getNdbOperation(& NdbTableImpl::getImpl(*table)); else return NULL; -}//NdbConnection::getNdbOperation() +}//NdbTransaction::getNdbOperation() // NdbScanOperation /***************************************************************************** @@ -1070,12 +1055,12 @@ NdbScanOperation* getNdbScanOperation(const char* aTableName); Return Value Return a pointer to a NdbScanOperation object if getNdbScanOperation was succesful. Return NULL : In all other case. Parameters: aTableName : Name of the database table. -Remark: Get an operation from NdbScanOperation idlelist and get the NdbConnection object +Remark: Get an operation from NdbScanOperation idlelist and get the NdbTransaction object who was fetch by startTransaction pointing to this operation getOperation will set the theTableId in the NdbOperation object.synchronous ******************************************************************************/ NdbScanOperation* -NdbConnection::getNdbScanOperation(const char* aTableName) +NdbTransaction::getNdbScanOperation(const char* aTableName) { if (theCommitStatus == Started){ NdbTableImpl* tab = theNdb->theDictionary->getTable(aTableName); @@ -1089,7 +1074,7 @@ NdbConnection::getNdbScanOperation(const char* aTableName) setOperationErrorCodeAbort(4114); return NULL; -}//NdbConnection::getNdbScanOperation() +}//NdbTransaction::getNdbScanOperation() /***************************************************************************** NdbScanOperation* getNdbScanOperation(const char* anIndexName, const char* aTableName); @@ -1098,12 +1083,12 @@ Return Value Return a pointer to a NdbScanOperation object if getNdbScanOpera Return NULL : In all other case. Parameters: anIndexName : Name of the index to use. aTableName : Name of the database table. -Remark: Get an operation from NdbScanOperation idlelist and get the NdbConnection object +Remark: Get an operation from NdbScanOperation idlelist and get the NdbTransaction object who was fetch by startTransaction pointing to this operation getOperation will set the theTableId in the NdbOperation object.synchronous ******************************************************************************/ NdbIndexScanOperation* -NdbConnection::getNdbIndexScanOperation(const char* anIndexName, +NdbTransaction::getNdbIndexScanOperation(const char* anIndexName, const char* aTableName) { NdbIndexImpl* index = @@ -1114,7 +1099,7 @@ NdbConnection::getNdbIndexScanOperation(const char* anIndexName, } NdbIndexScanOperation* -NdbConnection::getNdbIndexScanOperation(const NdbIndexImpl* index, +NdbTransaction::getNdbIndexScanOperation(const NdbIndexImpl* index, const NdbTableImpl* table) { if (theCommitStatus == Started){ @@ -1124,7 +1109,6 @@ NdbConnection::getNdbIndexScanOperation(const NdbIndexImpl* index, if(tOp) { tOp->m_currentTable = table; - tOp->m_cursor_type = NdbScanOperation::IndexCursor; } return tOp; } else { @@ -1135,10 +1119,10 @@ NdbConnection::getNdbIndexScanOperation(const NdbIndexImpl* index, setOperationErrorCodeAbort(4114); return NULL; -}//NdbConnection::getNdbIndexScanOperation() +}//NdbTransaction::getNdbIndexScanOperation() NdbIndexScanOperation* -NdbConnection::getNdbIndexScanOperation(const NdbDictionary::Index * index, +NdbTransaction::getNdbIndexScanOperation(const NdbDictionary::Index * index, const NdbDictionary::Table * table) { if (index && table) @@ -1146,7 +1130,7 @@ NdbConnection::getNdbIndexScanOperation(const NdbDictionary::Index * index, & NdbTableImpl::getImpl(*table)); else return NULL; -}//NdbConnection::getNdbIndexScanOperation() +}//NdbTransaction::getNdbIndexScanOperation() /***************************************************************************** NdbScanOperation* getNdbScanOperation(int aTableId); @@ -1154,12 +1138,12 @@ NdbScanOperation* getNdbScanOperation(int aTableId); Return Value Return a pointer to a NdbOperation object if getNdbOperation was succesful. Return NULL: In all other case. Parameters: tableId : Id of the database table beeing deleted. -Remark: Get an operation from NdbScanOperation object idlelist and get the NdbConnection +Remark: Get an operation from NdbScanOperation object idlelist and get the NdbTransaction object who was fetch by startTransaction pointing to this operation getOperation will set the theTableId in the NdbOperation object, synchronous. *****************************************************************************/ NdbIndexScanOperation* -NdbConnection::getNdbScanOperation(const NdbTableImpl * tab) +NdbTransaction::getNdbScanOperation(const NdbTableImpl * tab) { NdbIndexScanOperation* tOp; @@ -1178,10 +1162,10 @@ NdbConnection::getNdbScanOperation(const NdbTableImpl * tab) getNdbOp_error1: setOperationErrorCodeAbort(4000); return NULL; -}//NdbConnection::getNdbScanOperation() +}//NdbTransaction::getNdbScanOperation() void -NdbConnection::remove_list(NdbOperation*& list, NdbOperation* op){ +NdbTransaction::remove_list(NdbOperation*& list, NdbOperation* op){ NdbOperation* tmp= list; if(tmp == op) list = op->next(); @@ -1194,7 +1178,7 @@ NdbConnection::remove_list(NdbOperation*& list, NdbOperation* op){ } void -NdbConnection::define_scan_op(NdbIndexScanOperation * tOp){ +NdbTransaction::define_scan_op(NdbIndexScanOperation * tOp){ // Link scan operation into list of cursor operations if (m_theLastScanOperation == NULL) m_theFirstScanOperation = m_theLastScanOperation = tOp; @@ -1206,13 +1190,13 @@ NdbConnection::define_scan_op(NdbIndexScanOperation * tOp){ } NdbScanOperation* -NdbConnection::getNdbScanOperation(const NdbDictionary::Table * table) +NdbTransaction::getNdbScanOperation(const NdbDictionary::Table * table) { if (table) return getNdbScanOperation(& NdbTableImpl::getImpl(*table)); else return NULL; -}//NdbConnection::getNdbScanOperation() +}//NdbTransaction::getNdbScanOperation() // IndexOperation @@ -1223,12 +1207,12 @@ NdbIndexOperation* getNdbIndexOperation(const char* anIndexName, Return Value Return a pointer to a NdbOperation object if getNdbScanOperation was succesful. Return NULL : In all other case. Parameters: aTableName : Name of the database table. -Remark: Get an operation from NdbScanOperation idlelist and get the NdbConnection object +Remark: Get an operation from NdbScanOperation idlelist and get the NdbTransaction object who was fetch by startTransaction pointing to this operation getOperation will set the theTableId in the NdbScanOperation object.synchronous ******************************************************************************/ NdbIndexOperation* -NdbConnection::getNdbIndexOperation(const char* anIndexName, +NdbTransaction::getNdbIndexOperation(const char* anIndexName, const char* aTableName) { if (theCommitStatus == Started) { @@ -1251,7 +1235,7 @@ NdbConnection::getNdbIndexOperation(const char* anIndexName, setOperationErrorCodeAbort(4114); return 0; -}//NdbConnection::getNdbIndexOperation() +}//NdbTransaction::getNdbIndexOperation() /***************************************************************************** NdbIndexOperation* getNdbIndexOperation(int anIndexId, int aTableId); @@ -1259,12 +1243,12 @@ NdbIndexOperation* getNdbIndexOperation(int anIndexId, int aTableId); Return Value Return a pointer to a NdbIndexOperation object if getNdbIndexOperation was succesful. Return NULL: In all other case. Parameters: tableId : Id of the database table beeing deleted. -Remark: Get an operation from NdbIndexOperation object idlelist and get the NdbConnection +Remark: Get an operation from NdbIndexOperation object idlelist and get the NdbTransaction object who was fetch by startTransaction pointing to this operation getOperation will set the theTableId in the NdbIndexOperation object, synchronous. *****************************************************************************/ NdbIndexOperation* -NdbConnection::getNdbIndexOperation(const NdbIndexImpl * anIndex, +NdbTransaction::getNdbIndexOperation(const NdbIndexImpl * anIndex, const NdbTableImpl * aTable, NdbOperation* aNextOp) { @@ -1305,10 +1289,10 @@ NdbConnection::getNdbIndexOperation(const NdbIndexImpl * anIndex, getNdbOp_error1: setOperationErrorCodeAbort(4000); return NULL; -}//NdbConnection::getNdbIndexOperation() +}//NdbTransaction::getNdbIndexOperation() NdbIndexOperation* -NdbConnection::getNdbIndexOperation(const NdbDictionary::Index * index, +NdbTransaction::getNdbIndexOperation(const NdbDictionary::Index * index, const NdbDictionary::Table * table) { if (index && table) @@ -1316,7 +1300,7 @@ NdbConnection::getNdbIndexOperation(const NdbDictionary::Index * index, & NdbTableImpl::getImpl(*table)); else return NULL; -}//NdbConnection::getNdbIndexOperation() +}//NdbTransaction::getNdbIndexOperation() /******************************************************************************* @@ -1328,7 +1312,7 @@ Parameters: aSignal: The signal object pointer. Remark: Sets theRestartGCI in the NDB object. *******************************************************************************/ int -NdbConnection::receiveDIHNDBTAMPER(NdbApiSignal* aSignal) +NdbTransaction::receiveDIHNDBTAMPER(NdbApiSignal* aSignal) { if (theStatus != Connecting) { return -1; @@ -1337,7 +1321,7 @@ NdbConnection::receiveDIHNDBTAMPER(NdbApiSignal* aSignal) theStatus = Connected; }//if return 0; -}//NdbConnection::receiveDIHNDBTAMPER() +}//NdbTransaction::receiveDIHNDBTAMPER() /******************************************************************************* int receiveTCSEIZECONF(NdbApiSignal* aSignal); @@ -1348,7 +1332,7 @@ Parameters: aSignal: The signal object pointer. Remark: Sets TC Connect pointer at reception of TCSEIZECONF. *******************************************************************************/ int -NdbConnection::receiveTCSEIZECONF(NdbApiSignal* aSignal) +NdbTransaction::receiveTCSEIZECONF(NdbApiSignal* aSignal) { if (theStatus != Connecting) { @@ -1359,7 +1343,7 @@ NdbConnection::receiveTCSEIZECONF(NdbApiSignal* aSignal) theStatus = Connected; } return 0; -}//NdbConnection::receiveTCSEIZECONF() +}//NdbTransaction::receiveTCSEIZECONF() /******************************************************************************* int receiveTCSEIZEREF(NdbApiSignal* aSignal); @@ -1370,7 +1354,7 @@ Parameters: aSignal: The signal object pointer. Remark: Sets TC Connect pointer. *******************************************************************************/ int -NdbConnection::receiveTCSEIZEREF(NdbApiSignal* aSignal) +NdbTransaction::receiveTCSEIZEREF(NdbApiSignal* aSignal) { if (theStatus != Connecting) { @@ -1381,7 +1365,7 @@ NdbConnection::receiveTCSEIZEREF(NdbApiSignal* aSignal) theNdb->theError.code = aSignal->readData(2); return 0; } -}//NdbConnection::receiveTCSEIZEREF() +}//NdbTransaction::receiveTCSEIZEREF() /******************************************************************************* int receiveTCRELEASECONF(NdbApiSignal* aSignal); @@ -1392,7 +1376,7 @@ Parameters: aSignal: The signal object pointer. Remark: DisConnect TC Connect pointer to NDBAPI. *******************************************************************************/ int -NdbConnection::receiveTCRELEASECONF(NdbApiSignal* aSignal) +NdbTransaction::receiveTCRELEASECONF(NdbApiSignal* aSignal) { if (theStatus != DisConnecting) { @@ -1402,7 +1386,7 @@ NdbConnection::receiveTCRELEASECONF(NdbApiSignal* aSignal) theStatus = NotConnected; } return 0; -}//NdbConnection::receiveTCRELEASECONF() +}//NdbTransaction::receiveTCRELEASECONF() /******************************************************************************* int receiveTCRELEASEREF(NdbApiSignal* aSignal); @@ -1413,7 +1397,7 @@ Parameters: aSignal: The signal object pointer. Remark: DisConnect TC Connect pointer to NDBAPI Failure. *******************************************************************************/ int -NdbConnection::receiveTCRELEASEREF(NdbApiSignal* aSignal) +NdbTransaction::receiveTCRELEASEREF(NdbApiSignal* aSignal) { if (theStatus != DisConnecting) { return -1; @@ -1422,7 +1406,7 @@ NdbConnection::receiveTCRELEASEREF(NdbApiSignal* aSignal) theNdb->theError.code = aSignal->readData(2); return 0; }//if -}//NdbConnection::receiveTCRELEASEREF() +}//NdbTransaction::receiveTCRELEASEREF() /****************************************************************************** int receiveTC_COMMITCONF(NdbApiSignal* aSignal); @@ -1433,7 +1417,7 @@ Parameters: aSignal: The signal object pointer. Remark: ******************************************************************************/ int -NdbConnection::receiveTC_COMMITCONF(const TcCommitConf * commitConf) +NdbTransaction::receiveTC_COMMITCONF(const TcCommitConf * commitConf) { if(checkState_TransId(&commitConf->transId1)){ theCommitStatus = Committed; @@ -1445,7 +1429,7 @@ NdbConnection::receiveTC_COMMITCONF(const TcCommitConf * commitConf) #endif } return -1; -}//NdbConnection::receiveTC_COMMITCONF() +}//NdbTransaction::receiveTC_COMMITCONF() /****************************************************************************** int receiveTC_COMMITREF(NdbApiSignal* aSignal); @@ -1456,13 +1440,14 @@ Parameters: aSignal: The signal object pointer. Remark: ******************************************************************************/ int -NdbConnection::receiveTC_COMMITREF(NdbApiSignal* aSignal) +NdbTransaction::receiveTC_COMMITREF(NdbApiSignal* aSignal) { const TcCommitRef * ref = CAST_CONSTPTR(TcCommitRef, aSignal->getDataPtr()); if(checkState_TransId(&ref->transId1)){ setOperationErrorCodeAbort(ref->errorCode); theCommitStatus = Aborted; theCompletionStatus = CompletedFailure; + theReturnStatus = ReturnFailure; return 0; } else { #ifdef NDB_NO_DROPPED_SIGNAL @@ -1471,7 +1456,7 @@ NdbConnection::receiveTC_COMMITREF(NdbApiSignal* aSignal) } return -1; -}//NdbConnection::receiveTC_COMMITREF() +}//NdbTransaction::receiveTC_COMMITREF() /****************************************************************************** int receiveTCROLLBACKCONF(NdbApiSignal* aSignal); @@ -1482,7 +1467,7 @@ Parameters: aSignal: The signal object pointer. Remark: ******************************************************************************/ int -NdbConnection::receiveTCROLLBACKCONF(NdbApiSignal* aSignal) +NdbTransaction::receiveTCROLLBACKCONF(NdbApiSignal* aSignal) { if(checkState_TransId(aSignal->getDataPtr() + 1)){ theCommitStatus = Aborted; @@ -1495,7 +1480,7 @@ NdbConnection::receiveTCROLLBACKCONF(NdbApiSignal* aSignal) } return -1; -}//NdbConnection::receiveTCROLLBACKCONF() +}//NdbTransaction::receiveTCROLLBACKCONF() /******************************************************************************* int receiveTCROLLBACKREF(NdbApiSignal* aSignal); @@ -1506,12 +1491,13 @@ Parameters: aSignal: The signal object pointer. Remark: *******************************************************************************/ int -NdbConnection::receiveTCROLLBACKREF(NdbApiSignal* aSignal) +NdbTransaction::receiveTCROLLBACKREF(NdbApiSignal* aSignal) { if(checkState_TransId(aSignal->getDataPtr() + 1)){ setOperationErrorCodeAbort(aSignal->readData(4)); theCommitStatus = Aborted; theCompletionStatus = CompletedFailure; + theReturnStatus = ReturnFailure; return 0; } else { #ifdef NDB_NO_DROPPED_SIGNAL @@ -1520,7 +1506,7 @@ NdbConnection::receiveTCROLLBACKREF(NdbApiSignal* aSignal) } return -1; -}//NdbConnection::receiveTCROLLBACKREF() +}//NdbTransaction::receiveTCROLLBACKREF() /***************************************************************************** int receiveTCROLLBACKREP( NdbApiSignal* aSignal) @@ -1532,7 +1518,7 @@ Parameters: aSignal: the signal object that contains the Remark: Handles the reception of the ROLLBACKREP signal. *****************************************************************************/ int -NdbConnection::receiveTCROLLBACKREP( NdbApiSignal* aSignal) +NdbTransaction::receiveTCROLLBACKREP( NdbApiSignal* aSignal) { /**************************************************************************** Check that we are expecting signals from this transaction and that it doesn't @@ -1551,6 +1537,7 @@ transactions. /**********************************************************************/ theCompletionStatus = CompletedFailure; theCommitStatus = Aborted; + theReturnStatus = ReturnFailure; return 0; } else { #ifdef NDB_NO_DROPPED_SIGNAL @@ -1559,7 +1546,7 @@ transactions. } return -1; -}//NdbConnection::receiveTCROLLBACKREP() +}//NdbTransaction::receiveTCROLLBACKREP() /******************************************************************************* int receiveTCKEYCONF(NdbApiSignal* aSignal, Uint32 long_short_ind); @@ -1570,7 +1557,7 @@ Parameters: aSignal: The signal object pointer. Remark: *******************************************************************************/ int -NdbConnection::receiveTCKEYCONF(const TcKeyConf * keyConf, Uint32 aDataLength) +NdbTransaction::receiveTCKEYCONF(const TcKeyConf * keyConf, Uint32 aDataLength) { NdbReceiver* tOp; const Uint32 tTemp = keyConf->confInfo; @@ -1599,6 +1586,7 @@ from other transactions. done = 1; tOp->setErrorCode(4119); theCompletionStatus = CompletedFailure; + theReturnStatus = NdbTransaction::ReturnFailure; } } tNoComp += done; @@ -1628,6 +1616,7 @@ from other transactions. /**********************************************************************/ theError.code = 4011; theCompletionStatus = CompletedFailure; + theReturnStatus = NdbTransaction::ReturnFailure; theCommitStatus = Aborted; return 0; }//if @@ -1642,7 +1631,7 @@ from other transactions. } return -1; -}//NdbConnection::receiveTCKEYCONF() +}//NdbTransaction::receiveTCKEYCONF() /***************************************************************************** int receiveTCKEY_FAILCONF( NdbApiSignal* aSignal) @@ -1654,7 +1643,7 @@ Parameters: aSignal: the signal object that contains the Remark: Handles the reception of the TCKEY_FAILCONF signal. *****************************************************************************/ int -NdbConnection::receiveTCKEY_FAILCONF(const TcKeyFailConf * failConf) +NdbTransaction::receiveTCKEY_FAILCONF(const TcKeyFailConf * failConf) { NdbOperation* tOp; /* @@ -1687,6 +1676,7 @@ NdbConnection::receiveTCKEY_FAILCONF(const TcKeyFailConf * failConf) case NdbOperation::OpenScanRequest: case NdbOperation::OpenRangeScanRequest: theCompletionStatus = CompletedFailure; + theReturnStatus = NdbTransaction::ReturnFailure; setOperationErrorCodeAbort(4115); tOp = NULL; break; @@ -1704,7 +1694,7 @@ NdbConnection::receiveTCKEY_FAILCONF(const TcKeyFailConf * failConf) #endif } return -1; -}//NdbConnection::receiveTCKEY_FAILCONF() +}//NdbTransaction::receiveTCKEY_FAILCONF() /************************************************************************* int receiveTCKEY_FAILREF( NdbApiSignal* aSignal) @@ -1716,7 +1706,7 @@ Parameters: aSignal: the signal object that contains the Remark: Handles the reception of the TCKEY_FAILREF signal. **************************************************************************/ int -NdbConnection::receiveTCKEY_FAILREF(NdbApiSignal* aSignal) +NdbTransaction::receiveTCKEY_FAILREF(NdbApiSignal* aSignal) { /* Check that we are expecting signals from this transaction and @@ -1728,18 +1718,19 @@ NdbConnection::receiveTCKEY_FAILREF(NdbApiSignal* aSignal) We received an indication of that this transaction was aborted due to a node failure. */ - if (theSendStatus == NdbConnection::sendTC_ROLLBACK) { + if (theSendStatus == NdbTransaction::sendTC_ROLLBACK) { /* We were in the process of sending a rollback anyways. We will report it as a success. */ - theCompletionStatus = NdbConnection::CompletedSuccess; + theCompletionStatus = NdbTransaction::CompletedSuccess; } else { - theCompletionStatus = NdbConnection::CompletedFailure; + theReturnStatus = NdbTransaction::ReturnFailure; + theCompletionStatus = NdbTransaction::CompletedFailure; theError.code = 4031; }//if theReleaseOnClose = true; - theCommitStatus = NdbConnection::Aborted; + theCommitStatus = NdbTransaction::Aborted; return 0; } else { #ifdef VM_TRACE @@ -1747,7 +1738,7 @@ NdbConnection::receiveTCKEY_FAILREF(NdbApiSignal* aSignal) #endif } return -1; -}//NdbConnection::receiveTCKEY_FAILREF() +}//NdbTransaction::receiveTCKEY_FAILREF() /****************************************************************************** int receiveTCINDXCONF(NdbApiSignal* aSignal, Uint32 long_short_ind); @@ -1758,7 +1749,7 @@ Parameters: aSignal: The signal object pointer. Remark: ******************************************************************************/ int -NdbConnection::receiveTCINDXCONF(const TcIndxConf * indxConf, +NdbTransaction::receiveTCINDXCONF(const TcIndxConf * indxConf, Uint32 aDataLength) { if(checkState_TransId(&indxConf->transId1)){ @@ -1792,8 +1783,9 @@ NdbConnection::receiveTCINDXCONF(const TcIndxConf * indxConf, // no Commit flag set. This is clearly an anomaly. /**********************************************************************/ theError.code = 4011; - theCompletionStatus = NdbConnection::CompletedFailure; - theCommitStatus = NdbConnection::Aborted; + theCompletionStatus = NdbTransaction::CompletedFailure; + theCommitStatus = NdbTransaction::Aborted; + theReturnStatus = NdbTransaction::ReturnFailure; return 0; }//if if (tNoComp >= tNoSent) { @@ -1807,7 +1799,7 @@ NdbConnection::receiveTCINDXCONF(const TcIndxConf * indxConf, } return -1; -}//NdbConnection::receiveTCINDXCONF() +}//NdbTransaction::receiveTCINDXCONF() /***************************************************************************** int receiveTCINDXREF( NdbApiSignal* aSignal) @@ -1819,7 +1811,7 @@ Parameters: aSignal: the signal object that contains the Remark: Handles the reception of the TCINDXREF signal. *****************************************************************************/ int -NdbConnection::receiveTCINDXREF( NdbApiSignal* aSignal) +NdbTransaction::receiveTCINDXREF( NdbApiSignal* aSignal) { if(checkState_TransId(aSignal->getDataPtr()+1)){ theError.code = aSignal->readData(4); // Override any previous errors @@ -1831,8 +1823,9 @@ NdbConnection::receiveTCINDXREF( NdbApiSignal* aSignal) /* and we only need to report completion and return with the */ /* error code to the application. */ /**********************************************************************/ - theCompletionStatus = NdbConnection::CompletedFailure; - theCommitStatus = NdbConnection::Aborted; + theCompletionStatus = NdbTransaction::CompletedFailure; + theCommitStatus = NdbTransaction::Aborted; + theReturnStatus = NdbTransaction::ReturnFailure; return 0; } else { #ifdef NDB_NO_DROPPED_SIGNAL @@ -1841,7 +1834,7 @@ NdbConnection::receiveTCINDXREF( NdbApiSignal* aSignal) } return -1; -}//NdbConnection::receiveTCINDXREF() +}//NdbTransaction::receiveTCINDXREF() /******************************************************************************* int OpCompletedFailure(); @@ -1852,12 +1845,12 @@ Parameters: aErrorCode: The error code. Remark: An operation was completed with failure. *******************************************************************************/ int -NdbConnection::OpCompleteFailure(Uint8 abortOption, bool setFailure) +NdbTransaction::OpCompleteFailure(Uint8 abortOption, bool setFailure) { Uint32 tNoComp = theNoOfOpCompleted; Uint32 tNoSent = theNoOfOpSent; if (setFailure) - theCompletionStatus = NdbConnection::CompletedFailure; + theCompletionStatus = NdbTransaction::CompletedFailure; tNoComp++; theNoOfOpCompleted = tNoComp; if (tNoComp == tNoSent) { @@ -1882,7 +1875,7 @@ NdbConnection::OpCompleteFailure(Uint8 abortOption, bool setFailure) } else { return -1; // Continue waiting for more signals }//if -}//NdbConnection::OpCompleteFailure() +}//NdbTransaction::OpCompleteFailure() /****************************************************************************** int OpCompleteSuccess(); @@ -1892,7 +1885,7 @@ Return Value: Return 0 : OpCompleteSuccess was successful. Remark: An operation was completed with success. *******************************************************************************/ int -NdbConnection::OpCompleteSuccess() +NdbTransaction::OpCompleteSuccess() { Uint32 tNoComp = theNoOfOpCompleted; Uint32 tNoSent = theNoOfOpSent; @@ -1905,10 +1898,11 @@ NdbConnection::OpCompleteSuccess() } else { setOperationErrorCodeAbort(4113); // Too many operations, // stop waiting for more - theCompletionStatus = NdbConnection::CompletedFailure; + theCompletionStatus = NdbTransaction::CompletedFailure; + theReturnStatus = NdbTransaction::ReturnFailure; return 0; }//if -}//NdbConnection::OpCompleteSuccess() +}//NdbTransaction::OpCompleteSuccess() /****************************************************************************** int getGCI(); @@ -1916,13 +1910,13 @@ NdbConnection::OpCompleteSuccess() Remark: Get global checkpoint identity of the transaction *******************************************************************************/ int -NdbConnection::getGCI() +NdbTransaction::getGCI() { - if (theCommitStatus == NdbConnection::Committed) { + if (theCommitStatus == NdbTransaction::Committed) { return theGlobalCheckpointId; }//if return 0; -}//NdbConnection::getGCI() +}//NdbTransaction::getGCI() /******************************************************************************* Uint64 getTransactionId(void); @@ -1930,31 +1924,31 @@ Uint64 getTransactionId(void); Remark: Get the transaction identity. *******************************************************************************/ Uint64 -NdbConnection::getTransactionId() +NdbTransaction::getTransactionId() { return theTransactionId; -}//NdbConnection::getTransactionId() +}//NdbTransaction::getTransactionId() -NdbConnection::CommitStatusType -NdbConnection::commitStatus() +NdbTransaction::CommitStatusType +NdbTransaction::commitStatus() { return theCommitStatus; -}//NdbConnection::commitStatus() +}//NdbTransaction::commitStatus() int -NdbConnection::getNdbErrorLine() +NdbTransaction::getNdbErrorLine() { return theErrorLine; } NdbOperation* -NdbConnection::getNdbErrorOperation() +NdbTransaction::getNdbErrorOperation() { return theErrorOperation; -}//NdbConnection::getNdbErrorOperation() +}//NdbTransaction::getNdbErrorOperation() const NdbOperation * -NdbConnection::getNextCompletedOperation(const NdbOperation * current) const { +NdbTransaction::getNextCompletedOperation(const NdbOperation * current) const { if(current == 0) return theCompletedFirstOp; return current->theNext; @@ -1963,7 +1957,7 @@ NdbConnection::getNextCompletedOperation(const NdbOperation * current) const { #ifdef VM_TRACE #define CASE(x) case x: ndbout << " " << #x; break void -NdbConnection::printState() +NdbTransaction::printState() { ndbout << "con=" << hex << this << dec; ndbout << " node=" << getConnectedNodeId(); @@ -2016,7 +2010,7 @@ NdbConnection::printState() #endif int -NdbConnection::report_node_failure(Uint32 id){ +NdbTransaction::report_node_failure(Uint32 id){ NdbNodeBitmask::set(m_failed_db_nodes, id); if(!NdbNodeBitmask::get(m_db_nodes, id)) { @@ -2035,22 +2029,28 @@ NdbConnection::report_node_failure(Uint32 id){ const Uint32 len = TcKeyConf::SimpleReadBit | id; Uint32 tNoComp = theNoOfOpCompleted; Uint32 tNoSent = theNoOfOpSent; + Uint32 count = 0; while(tmp != 0) { if(tmp->theReceiver.m_expected_result_length == len && tmp->theReceiver.m_received_result_length == 0) { - tNoComp++; + count++; tmp->theError.code = 4119; } tmp = tmp->next(); } + tNoComp += count; theNoOfOpCompleted = tNoComp; - if(tNoComp == tNoSent) + if(count) { - theError.code = 4119; - theCompletionStatus = NdbConnection::CompletedFailure; - return 1; + theReturnStatus = NdbTransaction::ReturnFailure; + if(tNoComp == tNoSent) + { + theError.code = 4119; + theCompletionStatus = NdbTransaction::CompletedFailure; + return 1; + } } return 0; } diff --git a/ndb/src/ndbapi/NdbConnectionScan.cpp b/ndb/src/ndbapi/NdbTransactionScan.cpp index b0c546c512a..4c507f6ab8c 100644 --- a/ndb/src/ndbapi/NdbConnectionScan.cpp +++ b/ndb/src/ndbapi/NdbTransactionScan.cpp @@ -15,22 +15,10 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ -/***************************************************************************** - * Name: NdbConnectionScan.cpp - * Include: - * Link: - * Author: UABRONM MikaelRonström UAB/M/MT - * QABJKAM Jonas Kamf UAB/M/MT - * Date: 2000-06-12 - * Version: 0.1 - * Description: Interface between Application and NDB - * Documentation: - * Adjust: 2000-06-12 UABRONM First version. - ****************************************************************************/ #include <ndb_global.h> #include <Ndb.hpp> -#include <NdbConnection.hpp> +#include <NdbTransaction.hpp> #include <NdbOperation.hpp> #include <NdbScanOperation.hpp> #include "NdbApiSignal.hpp" @@ -52,7 +40,7 @@ * ****************************************************************************/ int -NdbConnection::receiveSCAN_TABREF(NdbApiSignal* aSignal){ +NdbTransaction::receiveSCAN_TABREF(NdbApiSignal* aSignal){ const ScanTabRef * ref = CAST_CONSTPTR(ScanTabRef, aSignal->getDataPtr()); if(checkState_TransId(&ref->transId1)){ @@ -93,7 +81,7 @@ NdbConnection::receiveSCAN_TABREF(NdbApiSignal* aSignal){ * *****************************************************************************/ int -NdbConnection::receiveSCAN_TABCONF(NdbApiSignal* aSignal, +NdbTransaction::receiveSCAN_TABCONF(NdbApiSignal* aSignal, const Uint32 * ops, Uint32 len) { const ScanTabConf * conf = CAST_CONSTPTR(ScanTabConf, aSignal->getDataPtr()); diff --git a/ndb/src/ndbapi/Ndberr.cpp b/ndb/src/ndbapi/Ndberr.cpp index a8b968da03f..07f33d3e8b3 100644 --- a/ndb/src/ndbapi/Ndberr.cpp +++ b/ndb/src/ndbapi/Ndberr.cpp @@ -19,7 +19,7 @@ #include "NdbImpl.hpp" #include "NdbDictionaryImpl.hpp" #include <NdbOperation.hpp> -#include <NdbConnection.hpp> +#include <NdbTransaction.hpp> #include <NdbBlob.hpp> @@ -55,7 +55,7 @@ NdbDictionaryImpl::getNdbError() const { const NdbError & -NdbConnection::getNdbError() const { +NdbTransaction::getNdbError() const { update(theError); return theError; } diff --git a/ndb/src/ndbapi/Ndbif.cpp b/ndb/src/ndbapi/Ndbif.cpp index a4f233709c4..40eb46ea397 100644 --- a/ndb/src/ndbapi/Ndbif.cpp +++ b/ndb/src/ndbapi/Ndbif.cpp @@ -19,12 +19,12 @@ #include "NdbApiSignal.hpp" #include "NdbImpl.hpp" -#include "NdbOperation.hpp" -#include "NdbIndexOperation.hpp" -#include "NdbScanOperation.hpp" -#include "NdbConnection.hpp" -#include "NdbRecAttr.hpp" -#include "NdbReceiver.hpp" +#include <NdbTransaction.hpp> +#include <NdbOperation.hpp> +#include <NdbIndexOperation.hpp> +#include <NdbScanOperation.hpp> +#include <NdbRecAttr.hpp> +#include <NdbReceiver.hpp> #include "API.hpp" #include <signaldata/TcCommit.hpp> @@ -113,9 +113,9 @@ Ndb::init(int aMaxNoOfTransactions) }//if theMaxNoOfTransactions = tMaxNoOfTransactions; - thePreparedTransactionsArray = new NdbConnection* [tMaxNoOfTransactions]; - theSentTransactionsArray = new NdbConnection* [tMaxNoOfTransactions]; - theCompletedTransactionsArray = new NdbConnection* [tMaxNoOfTransactions]; + thePreparedTransactionsArray = new NdbTransaction* [tMaxNoOfTransactions]; + theSentTransactionsArray = new NdbTransaction* [tMaxNoOfTransactions]; + theCompletedTransactionsArray = new NdbTransaction* [tMaxNoOfTransactions]; if ((thePreparedTransactionsArray == NULL) || (theSentTransactionsArray == NULL) || @@ -272,11 +272,11 @@ Ndb::abortTransactionsAfterNodeFailure(Uint16 aNodeId) { Uint32 tNoSentTransactions = theNoOfSentTransactions; for (int i = tNoSentTransactions - 1; i >= 0; i--) { - NdbConnection* localCon = theSentTransactionsArray[i]; + NdbTransaction* localCon = theSentTransactionsArray[i]; if (localCon->getConnectedNodeId() == aNodeId) { - const NdbConnection::SendStatusType sendStatus = localCon->theSendStatus; - if (sendStatus == NdbConnection::sendTC_OP || - sendStatus == NdbConnection::sendTC_COMMIT) { + const NdbTransaction::SendStatusType sendStatus = localCon->theSendStatus; + if (sendStatus == NdbTransaction::sendTC_OP || + sendStatus == NdbTransaction::sendTC_COMMIT) { /* A transaction was interrupted in the prepare phase by a node failure. Since the transaction was not found in the phase @@ -284,13 +284,13 @@ Ndb::abortTransactionsAfterNodeFailure(Uint16 aNodeId) we report a normal node failure abort. */ localCon->setOperationErrorCodeAbort(4010); - localCon->theCompletionStatus = NdbConnection::CompletedFailure; - } else if (sendStatus == NdbConnection::sendTC_ROLLBACK) { + localCon->theCompletionStatus = NdbTransaction::CompletedFailure; + } else if (sendStatus == NdbTransaction::sendTC_ROLLBACK) { /* We aimed for abort and abort we got even if it was by a node failure. We will thus report it as a success. */ - localCon->theCompletionStatus = NdbConnection::CompletedSuccess; + localCon->theCompletionStatus = NdbTransaction::CompletedSuccess; } else { #ifdef VM_TRACE printState("abortTransactionsAfterNodeFailure %x", this); @@ -302,7 +302,8 @@ Ndb::abortTransactionsAfterNodeFailure(Uint16 aNodeId) intact since the node was failing and they were aborted. Thus we set commit state to Aborted and set state to release on close. */ - localCon->theCommitStatus = NdbConnection::Aborted; + localCon->theReturnStatus = NdbTransaction::ReturnFailure; + localCon->theCommitStatus = NdbTransaction::Aborted; localCon->theReleaseOnClose = true; completedTransaction(localCon); } @@ -325,7 +326,7 @@ Ndb::handleReceivedSignal(NdbApiSignal* aSignal, LinearSectionPtr ptr[3]) { NdbOperation* tOp; NdbIndexOperation* tIndexOp; - NdbConnection* tCon; + NdbTransaction* tCon; int tReturnCode = -1; const Uint32* tDataPtr = aSignal->getDataPtr(); const Uint32 tWaitState = theImpl->theWaiter.m_state; @@ -355,14 +356,14 @@ Ndb::handleReceivedSignal(NdbApiSignal* aSignal, LinearSectionPtr ptr[3]) tCon = void2con(tFirstDataPtr); if ((tCon->checkMagicNumber() == 0) && - (tCon->theSendStatus == NdbConnection::sendTC_OP)) { + (tCon->theSendStatus == NdbTransaction::sendTC_OP)) { tReturnCode = tCon->receiveTCKEYCONF(keyConf, tLen); if (tReturnCode != -1) { completedTransaction(tCon); }//if if(TcKeyConf::getMarkerFlag(keyConf->confInfo)){ - NdbConnection::sendTC_COMMIT_ACK(theCommitAckSignal, + NdbTransaction::sendTC_COMMIT_ACK(theCommitAckSignal, keyConf->transId1, keyConf->transId2, aTCRef); @@ -426,8 +427,8 @@ Ndb::handleReceivedSignal(NdbApiSignal* aSignal, LinearSectionPtr ptr[3]) if (tOp->checkMagicNumber(false) == 0) { tCon = tOp->theNdbCon; if (tCon != NULL) { - if ((tCon->theSendStatus == NdbConnection::sendTC_OP) || - (tCon->theSendStatus == NdbConnection::sendTC_COMMIT)) { + if ((tCon->theSendStatus == NdbTransaction::sendTC_OP) || + (tCon->theSendStatus == NdbTransaction::sendTC_COMMIT)) { tReturnCode = tCon->receiveTCKEY_FAILCONF(failConf); if (tReturnCode != -1) { completedTransaction(tCon); @@ -441,7 +442,7 @@ Ndb::handleReceivedSignal(NdbApiSignal* aSignal, LinearSectionPtr ptr[3]) #endif } if(tFirstData & 1){ - NdbConnection::sendTC_COMMIT_ACK(theCommitAckSignal, + NdbTransaction::sendTC_COMMIT_ACK(theCommitAckSignal, failConf->transId1, failConf->transId2, aTCRef); @@ -456,8 +457,8 @@ Ndb::handleReceivedSignal(NdbApiSignal* aSignal, LinearSectionPtr ptr[3]) if (tOp->checkMagicNumber() == 0) { tCon = tOp->theNdbCon; if (tCon != NULL) { - if ((tCon->theSendStatus == NdbConnection::sendTC_OP) || - (tCon->theSendStatus == NdbConnection::sendTC_ROLLBACK)) { + if ((tCon->theSendStatus == NdbTransaction::sendTC_OP) || + (tCon->theSendStatus == NdbTransaction::sendTC_ROLLBACK)) { tReturnCode = tCon->receiveTCKEY_FAILREF(aSignal); if (tReturnCode != -1) { completedTransaction(tCon); @@ -482,7 +483,7 @@ Ndb::handleReceivedSignal(NdbApiSignal* aSignal, LinearSectionPtr ptr[3]) if (tOp->checkMagicNumber() == 0) { tCon = tOp->theNdbCon; if (tCon != NULL) { - if (tCon->theSendStatus == NdbConnection::sendTC_OP) { + if (tCon->theSendStatus == NdbTransaction::sendTC_OP) { tReturnCode = tOp->receiveTCKEYREF(aSignal); if (tReturnCode != -1) { completedTransaction(tCon); @@ -505,14 +506,14 @@ Ndb::handleReceivedSignal(NdbApiSignal* aSignal, LinearSectionPtr ptr[3]) tCon = void2con(tFirstDataPtr); if ((tCon->checkMagicNumber() == 0) && - (tCon->theSendStatus == NdbConnection::sendTC_COMMIT)) { + (tCon->theSendStatus == NdbTransaction::sendTC_COMMIT)) { tReturnCode = tCon->receiveTC_COMMITCONF(commitConf); if (tReturnCode != -1) { completedTransaction(tCon); }//if if(tFirstData & 1){ - NdbConnection::sendTC_COMMIT_ACK(theCommitAckSignal, + NdbTransaction::sendTC_COMMIT_ACK(theCommitAckSignal, commitConf->transId1, commitConf->transId2, aTCRef); @@ -530,7 +531,7 @@ Ndb::handleReceivedSignal(NdbApiSignal* aSignal, LinearSectionPtr ptr[3]) tCon = void2con(tFirstDataPtr); if ((tCon->checkMagicNumber() == 0) && - (tCon->theSendStatus == NdbConnection::sendTC_COMMIT)) { + (tCon->theSendStatus == NdbTransaction::sendTC_COMMIT)) { tReturnCode = tCon->receiveTC_COMMITREF(aSignal); if (tReturnCode != -1) { completedTransaction(tCon); @@ -545,7 +546,7 @@ Ndb::handleReceivedSignal(NdbApiSignal* aSignal, LinearSectionPtr ptr[3]) tCon = void2con(tFirstDataPtr); if ((tCon->checkMagicNumber() == 0) && - (tCon->theSendStatus == NdbConnection::sendTC_ROLLBACK)) { + (tCon->theSendStatus == NdbTransaction::sendTC_ROLLBACK)) { tReturnCode = tCon->receiveTCROLLBACKCONF(aSignal); if (tReturnCode != -1) { completedTransaction(tCon); @@ -560,7 +561,7 @@ Ndb::handleReceivedSignal(NdbApiSignal* aSignal, LinearSectionPtr ptr[3]) tCon = void2con(tFirstDataPtr); if ((tCon->checkMagicNumber() == 0) && - (tCon->theSendStatus == NdbConnection::sendTC_ROLLBACK)) { + (tCon->theSendStatus == NdbTransaction::sendTC_ROLLBACK)) { tReturnCode = tCon->receiveTCROLLBACKREF(aSignal); if (tReturnCode != -1) { completedTransaction(tCon); @@ -797,7 +798,7 @@ Ndb::handleReceivedSignal(NdbApiSignal* aSignal, LinearSectionPtr ptr[3]) const BlockReference aTCRef = aSignal->theSendersBlockRef; tCon = void2con(tFirstDataPtr); if ((tCon->checkMagicNumber() == 0) && - (tCon->theSendStatus == NdbConnection::sendTC_OP)) { + (tCon->theSendStatus == NdbTransaction::sendTC_OP)) { tReturnCode = tCon->receiveTCINDXCONF(indxConf, tLen); if (tReturnCode != -1) { completedTransaction(tCon); @@ -805,7 +806,7 @@ Ndb::handleReceivedSignal(NdbApiSignal* aSignal, LinearSectionPtr ptr[3]) }//if if(TcIndxConf::getMarkerFlag(indxConf->confInfo)){ - NdbConnection::sendTC_COMMIT_ACK(theCommitAckSignal, + NdbTransaction::sendTC_COMMIT_ACK(theCommitAckSignal, indxConf->transId1, indxConf->transId2, aTCRef); @@ -820,7 +821,7 @@ Ndb::handleReceivedSignal(NdbApiSignal* aSignal, LinearSectionPtr ptr[3]) if (tIndexOp->checkMagicNumber() == 0) { tCon = tIndexOp->theNdbCon; if (tCon != NULL) { - if (tCon->theSendStatus == NdbConnection::sendTC_OP) { + if (tCon->theSendStatus == NdbTransaction::sendTC_OP) { tReturnCode = tIndexOp->receiveTCINDXREF(aSignal); if (tReturnCode != -1) { completedTransaction(tCon); @@ -861,7 +862,7 @@ Ndb::handleReceivedSignal(NdbApiSignal* aSignal, LinearSectionPtr ptr[3]) /***************************************************************************** -void completedTransaction(NdbConnection* aCon); +void completedTransaction(NdbTransaction* aCon); Remark: One transaction has been completed. Remove it from send array and put it into the completed @@ -869,14 +870,14 @@ Remark: One transaction has been completed. up a poller. ******************************************************************************/ void -Ndb::completedTransaction(NdbConnection* aCon) +Ndb::completedTransaction(NdbTransaction* aCon) { Uint32 tTransArrayIndex = aCon->theTransArrayIndex; Uint32 tNoSentTransactions = theNoOfSentTransactions; Uint32 tNoCompletedTransactions = theNoOfCompletedTransactions; - if ((tNoSentTransactions > 0) && (aCon->theListState == NdbConnection::InSendList) && + if ((tNoSentTransactions > 0) && (aCon->theListState == NdbTransaction::InSendList) && (tTransArrayIndex < tNoSentTransactions)) { - NdbConnection* tMoveCon = theSentTransactionsArray[tNoSentTransactions - 1]; + NdbTransaction* tMoveCon = theSentTransactionsArray[tNoSentTransactions - 1]; theCompletedTransactionsArray[tNoCompletedTransactions] = aCon; aCon->theTransArrayIndex = tNoCompletedTransactions; @@ -888,7 +889,7 @@ Ndb::completedTransaction(NdbConnection* aCon) theNoOfCompletedTransactions = tNoCompletedTransactions + 1; theNoOfSentTransactions = tNoSentTransactions - 1; - aCon->theListState = NdbConnection::InCompletedList; + aCon->theListState = NdbTransaction::InCompletedList; aCon->handleExecuteCompletion(); if ((theMinNoOfEventsToWakeUp != 0) && (theNoOfCompletedTransactions >= theMinNoOfEventsToWakeUp)) { @@ -909,12 +910,12 @@ Ndb::completedTransaction(NdbConnection* aCon) }//Ndb::completedTransaction() /***************************************************************************** -void reportCallback(NdbConnection** aCopyArray, Uint32 aNoOfCompletedTrans); +void reportCallback(NdbTransaction** aCopyArray, Uint32 aNoOfCompletedTrans); Remark: Call the callback methods of the completed transactions. ******************************************************************************/ void -Ndb::reportCallback(NdbConnection** aCopyArray, Uint32 aNoOfCompletedTrans) +Ndb::reportCallback(NdbTransaction** aCopyArray, Uint32 aNoOfCompletedTrans) { Uint32 i; if (aNoOfCompletedTrans > 0) { @@ -923,7 +924,7 @@ Ndb::reportCallback(NdbConnection** aCopyArray, Uint32 aNoOfCompletedTrans) NdbAsynchCallback aCallback = aCopyArray[i]->theCallbackFunction; int tResult = 0; if (aCallback != NULL) { - if (aCopyArray[i]->theReturnStatus == NdbConnection::ReturnFailure) { + if (aCopyArray[i]->theReturnStatus == NdbTransaction::ReturnFailure) { tResult = -1; }//if (*aCallback)(tResult, aCopyArray[i], anyObject); @@ -933,13 +934,13 @@ Ndb::reportCallback(NdbConnection** aCopyArray, Uint32 aNoOfCompletedTrans) }//Ndb::reportCallback() /***************************************************************************** -Uint32 pollCompleted(NdbConnection** aCopyArray); +Uint32 pollCompleted(NdbTransaction** aCopyArray); Remark: Transfer the data from the completed transaction to a local array. This support is used by a number of the poll-methods. ******************************************************************************/ Uint32 -Ndb::pollCompleted(NdbConnection** aCopyArray) +Ndb::pollCompleted(NdbTransaction** aCopyArray) { check_send_timeout(); Uint32 i; @@ -947,13 +948,13 @@ Ndb::pollCompleted(NdbConnection** aCopyArray) if (tNoCompletedTransactions > 0) { for (i = 0; i < tNoCompletedTransactions; i++) { aCopyArray[i] = theCompletedTransactionsArray[i]; - if (aCopyArray[i]->theListState != NdbConnection::InCompletedList) { + if (aCopyArray[i]->theListState != NdbTransaction::InCompletedList) { ndbout << "pollCompleted error "; ndbout << (int) aCopyArray[i]->theListState << endl; abort(); }//if theCompletedTransactionsArray[i] = NULL; - aCopyArray[i]->theListState = NdbConnection::NotInList; + aCopyArray[i]->theListState = NdbTransaction::NotInList; }//for }//if theNoOfCompletedTransactions = 0; @@ -968,7 +969,7 @@ Ndb::check_send_timeout() the_last_check_time = current_time; Uint32 no_of_sent = theNoOfSentTransactions; for (Uint32 i = 0; i < no_of_sent; i++) { - NdbConnection* a_con = theSentTransactionsArray[i]; + NdbTransaction* a_con = theSentTransactionsArray[i]; if ((current_time - a_con->theStartTransTime) > WAITFOR_RESPONSE_TIMEOUT) { #ifdef VM_TRACE @@ -979,8 +980,8 @@ Ndb::check_send_timeout() abort(); #endif a_con->setOperationErrorCodeAbort(4012); - a_con->theCommitStatus = NdbConnection::Aborted; - a_con->theCompletionStatus = NdbConnection::CompletedFailure; + a_con->theCommitStatus = NdbTransaction::Aborted; + a_con->theCompletionStatus = NdbTransaction::CompletedFailure; a_con->handleExecuteCompletion(); remove_sent_list(i); insert_completed_list(a_con); @@ -996,7 +997,7 @@ Ndb::remove_sent_list(Uint32 list_index) { Uint32 last_index = theNoOfSentTransactions - 1; if (list_index < last_index) { - NdbConnection* t_con = theSentTransactionsArray[last_index]; + NdbTransaction* t_con = theSentTransactionsArray[last_index]; theSentTransactionsArray[list_index] = t_con; }//if theNoOfSentTransactions = last_index; @@ -1004,23 +1005,23 @@ Ndb::remove_sent_list(Uint32 list_index) } Uint32 -Ndb::insert_completed_list(NdbConnection* a_con) +Ndb::insert_completed_list(NdbTransaction* a_con) { Uint32 no_of_comp = theNoOfCompletedTransactions; theCompletedTransactionsArray[no_of_comp] = a_con; theNoOfCompletedTransactions = no_of_comp + 1; - a_con->theListState = NdbConnection::InCompletedList; + a_con->theListState = NdbTransaction::InCompletedList; a_con->theTransArrayIndex = no_of_comp; return no_of_comp; } Uint32 -Ndb::insert_sent_list(NdbConnection* a_con) +Ndb::insert_sent_list(NdbTransaction* a_con) { Uint32 no_of_sent = theNoOfSentTransactions; theSentTransactionsArray[no_of_sent] = a_con; theNoOfSentTransactions = no_of_sent + 1; - a_con->theListState = NdbConnection::InSendList; + a_con->theListState = NdbTransaction::InSendList; a_con->theTransArrayIndex = no_of_sent; return no_of_sent; } @@ -1052,16 +1053,16 @@ Ndb::sendPrepTrans(int forceSend) TransporterFacade* tp = TransporterFacade::instance(); Uint32 no_of_prep_trans = theNoOfPreparedTransactions; for (i = 0; i < no_of_prep_trans; i++) { - NdbConnection * a_con = thePreparedTransactionsArray[i]; + NdbTransaction * a_con = thePreparedTransactionsArray[i]; thePreparedTransactionsArray[i] = NULL; Uint32 node_id = a_con->getConnectedNodeId(); if ((tp->getNodeSequence(node_id) == a_con->theNodeSequence) && tp->get_node_alive(node_id) || (tp->get_node_stopping(node_id) && - ((a_con->theSendStatus == NdbConnection::sendABORT) || - (a_con->theSendStatus == NdbConnection::sendABORTfail) || - (a_con->theSendStatus == NdbConnection::sendCOMMITstate) || - (a_con->theSendStatus == NdbConnection::sendCompleted)))) { + ((a_con->theSendStatus == NdbTransaction::sendABORT) || + (a_con->theSendStatus == NdbTransaction::sendABORTfail) || + (a_con->theSendStatus == NdbTransaction::sendCOMMITstate) || + (a_con->theSendStatus == NdbTransaction::sendCompleted)))) { /* We will send if 1) Node is alive and sequences are correct OR @@ -1093,13 +1094,13 @@ Ndb::sendPrepTrans(int forceSend) again and will thus set the state to Aborted to avoid a more or less eternal loop of tries. */ - if (a_con->theSendStatus == NdbConnection::sendOperations) { + if (a_con->theSendStatus == NdbTransaction::sendOperations) { a_con->setOperationErrorCodeAbort(4021); - a_con->theCommitStatus = NdbConnection::NeedAbort; + a_con->theCommitStatus = NdbTransaction::NeedAbort; TRACE_DEBUG("Send buffer full and sendOperations"); } else { a_con->setOperationErrorCodeAbort(4026); - a_con->theCommitStatus = NdbConnection::Aborted; + a_con->theCommitStatus = NdbTransaction::Aborted; TRACE_DEBUG("Send buffer full, set state to Aborted"); }//if }//if @@ -1116,7 +1117,7 @@ Ndb::sendPrepTrans(int forceSend) */ TRACE_DEBUG("Abort a transaction when stopping a node"); a_con->setOperationErrorCodeAbort(4023); - a_con->theCommitStatus = NdbConnection::NeedAbort; + a_con->theCommitStatus = NdbTransaction::NeedAbort; } else { /* The node is hard dead and we cannot continue. We will also release @@ -1126,10 +1127,11 @@ Ndb::sendPrepTrans(int forceSend) a_con->setOperationErrorCodeAbort(4025); a_con->theReleaseOnClose = true; a_con->theTransactionIsStarted = false; - a_con->theCommitStatus = NdbConnection::Aborted; + a_con->theCommitStatus = NdbTransaction::Aborted; }//if }//if - a_con->theCompletionStatus = NdbConnection::CompletedFailure; + a_con->theReturnStatus = NdbTransaction::ReturnFailure; + a_con->theCompletionStatus = NdbTransaction::CompletedFailure; a_con->handleExecuteCompletion(); insert_completed_list(a_con); }//for @@ -1203,7 +1205,7 @@ Remark: First send all prepared operations and then check if there are any int Ndb::sendPollNdb(int aMillisecondNumber, int minNoOfEventsToWakeup, int forceSend) { - NdbConnection* tConArray[1024]; + NdbTransaction* tConArray[1024]; Uint32 tNoCompletedTransactions; //theCurrentConnectCounter = 0; @@ -1236,7 +1238,7 @@ Remark: Check if there are any transactions already completed. Wait for not int Ndb::pollNdb(int aMillisecondNumber, int minNoOfEventsToWakeup) { - NdbConnection* tConArray[1024]; + NdbTransaction* tConArray[1024]; Uint32 tNoCompletedTransactions; //theCurrentConnectCounter = 0; @@ -1343,7 +1345,7 @@ Ndb::sendRecSignal(Uint16 node_id, }//Ndb::sendRecSignal() void -NdbConnection::sendTC_COMMIT_ACK(NdbApiSignal * aSignal, +NdbTransaction::sendTC_COMMIT_ACK(NdbApiSignal * aSignal, Uint32 transId1, Uint32 transId2, Uint32 aTCRef){ #ifdef MARKER_TRACE diff --git a/ndb/src/ndbapi/Ndbinit.cpp b/ndb/src/ndbapi/Ndbinit.cpp index e1af7bd4cc5..55a30a9742d 100644 --- a/ndb/src/ndbapi/Ndbinit.cpp +++ b/ndb/src/ndbapi/Ndbinit.cpp @@ -19,12 +19,12 @@ #include "NdbApiSignal.hpp" #include "NdbImpl.hpp" -#include "NdbOperation.hpp" -#include "NdbConnection.hpp" -#include "NdbRecAttr.hpp" -#include "IPCConfig.hpp" +#include <NdbOperation.hpp> +#include <NdbTransaction.hpp> +#include <NdbRecAttr.hpp> +#include <IPCConfig.hpp> #include "TransporterFacade.hpp" -#include "ConfigRetriever.hpp" +#include <ConfigRetriever.hpp> #include <ndb_limits.h> #include <NdbOut.hpp> #include <NdbSleep.h> diff --git a/ndb/src/ndbapi/Ndblist.cpp b/ndb/src/ndbapi/Ndblist.cpp index 5902aa413dc..df90f3378ab 100644 --- a/ndb/src/ndbapi/Ndblist.cpp +++ b/ndb/src/ndbapi/Ndblist.cpp @@ -19,7 +19,6 @@ #include <NdbOperation.hpp> #include <NdbIndexOperation.hpp> #include <NdbIndexScanOperation.hpp> -#include <NdbConnection.hpp> #include "NdbApiSignal.hpp" #include <NdbRecAttr.hpp> #include "NdbUtil.hpp" @@ -51,10 +50,10 @@ Ndb::checkFailedNode() /** * Release all connections in idle list (for node) */ - NdbConnection * tNdbCon = theConnectionArray[node_id]; + NdbTransaction * tNdbCon = theConnectionArray[node_id]; theConnectionArray[node_id] = NULL; while (tNdbCon != NULL) { - NdbConnection* tempNdbCon = tNdbCon; + NdbTransaction* tempNdbCon = tNdbCon; tNdbCon = tNdbCon->next(); releaseNdbCon(tempNdbCon); } @@ -71,14 +70,14 @@ Ndb::checkFailedNode() * if createConIdleList was succesful * Return -1: In all other case. * Parameters: aNrOfCon : Number of connections offered to the application. - * Remark: Create connection idlelist with NdbConnection objects. + * Remark: Create connection idlelist with NdbTransaction objects. ***************************************************************************/ int Ndb::createConIdleList(int aNrOfCon) { for (int i = 0; i < aNrOfCon; i++) { - NdbConnection* tNdbCon = new NdbConnection(this); + NdbTransaction* tNdbCon = new NdbTransaction(this); if (tNdbCon == NULL) { return -1; @@ -92,7 +91,7 @@ Ndb::createConIdleList(int aNrOfCon) tNdbCon->next(theConIdleList); theConIdleList = tNdbCon; } - tNdbCon->Status(NdbConnection::NotConnected); + tNdbCon->Status(NdbTransaction::NotConnected); } theNoOfAllocatedTransactions = aNrOfCon; return aNrOfCon; @@ -183,19 +182,19 @@ Ndb::getNdbCall() } /*************************************************************************** - * NdbConnection* getNdbCon(); + * NdbTransaction* getNdbCon(); * * Return Value: Return a connection if the getNdbCon was successful. * Return NULL : In all other case. * Remark: Get a connection from theConIdleList and return the object . ***************************************************************************/ -NdbConnection* +NdbTransaction* Ndb::getNdbCon() { - NdbConnection* tNdbCon; + NdbTransaction* tNdbCon; if ( theConIdleList == NULL ) { if (theNoOfAllocatedTransactions < theMaxNoOfTransactions) { - tNdbCon = new NdbConnection(this); + tNdbCon = new NdbTransaction(this); if (tNdbCon == NULL) { return NULL; }//if @@ -467,13 +466,13 @@ Ndb::releaseNdbCall(NdbCall* aNdbCall) } /*************************************************************************** -void releaseNdbCon(NdbConnection* aNdbCon); +void releaseNdbCon(NdbTransaction* aNdbCon); -Parameters: aNdbCon: The NdbConnection object. +Parameters: aNdbCon: The NdbTransaction object. Remark: Add a Connection object into the signal idlelist. ***************************************************************************/ void -Ndb::releaseNdbCon(NdbConnection* aNdbCon) +Ndb::releaseNdbCon(NdbTransaction* aNdbCon) { aNdbCon->next(theConIdleList); aNdbCon->theMagicNumber = 0xFE11DD; @@ -703,7 +702,7 @@ Remark: Always release the first item in the free list void Ndb::freeNdbCon() { - NdbConnection* tNdbCon = theConIdleList; + NdbTransaction* tNdbCon = theConIdleList; theConIdleList = theConIdleList->next(); delete tNdbCon; } @@ -772,14 +771,14 @@ Ndb::freeNdbBlob() } /**************************************************************************** -int releaseConnectToNdb(NdbConnection* aConnectConnection); +int releaseConnectToNdb(NdbTransaction* aConnectConnection); Return Value: -1 if error Parameters: aConnectConnection : Seized schema connection to DBTC Remark: Release and disconnect from DBTC a connection and seize it to theConIdleList. *****************************************************************************/ void -Ndb::releaseConnectToNdb(NdbConnection* a_con) +Ndb::releaseConnectToNdb(NdbTransaction* a_con) { DBUG_ENTER("Ndb::releaseConnectToNdb"); NdbApiSignal tSignal(theMyRef); @@ -797,7 +796,7 @@ Ndb::releaseConnectToNdb(NdbConnection* a_con) tSignal.setData((tConPtr = a_con->getTC_ConnectPtr()), 1); tSignal.setData(theMyRef, 2); tSignal.setData(a_con->ptr2int(), 3); - a_con->Status(NdbConnection::DisConnecting); + a_con->Status(NdbTransaction::DisConnecting); a_con->theMagicNumber = 0x37412619; int ret_code = sendRecSignal(node_id, WAIT_TC_RELEASE, diff --git a/ndb/src/ndbapi/TransporterFacade.cpp b/ndb/src/ndbapi/TransporterFacade.cpp index 821ed7288a8..b179c1fe6b9 100644 --- a/ndb/src/ndbapi/TransporterFacade.cpp +++ b/ndb/src/ndbapi/TransporterFacade.cpp @@ -472,12 +472,13 @@ void TransporterFacade::threadMainReceive(void) theTransporterRegistry->stopReceiving(); } -TransporterFacade::TransporterFacade() : +TransporterFacade::TransporterFacade(NdbMgmHandle mgm_handle) : theTransporterRegistry(0), theStopReceive(0), theSendThread(NULL), theReceiveThread(NULL), - m_fragmented_signal_id(0) + m_fragmented_signal_id(0), + m_mgm_handle(mgm_handle) { theOwnId = 0; @@ -501,7 +502,7 @@ bool TransporterFacade::init(Uint32 nodeId, const ndb_mgm_configuration* props) { theOwnId = nodeId; - theTransporterRegistry = new TransporterRegistry(this); + theTransporterRegistry = new TransporterRegistry(m_mgm_handle,this); const int res = IPCConfig::configureTransporters(nodeId, * props, diff --git a/ndb/src/ndbapi/TransporterFacade.hpp b/ndb/src/ndbapi/TransporterFacade.hpp index fb78cc6a92a..bd3fc67a8d6 100644 --- a/ndb/src/ndbapi/TransporterFacade.hpp +++ b/ndb/src/ndbapi/TransporterFacade.hpp @@ -24,6 +24,7 @@ #include <NdbMutex.h> #include "DictCache.hpp" #include <BlockNumbers.h> +#include <mgmapi.h> class ClusterMgr; class ArbitMgr; @@ -46,7 +47,7 @@ extern "C" { class TransporterFacade { public: - TransporterFacade(); + TransporterFacade(NdbMgmHandle mgm_handle); virtual ~TransporterFacade(); bool init(Uint32, const ndb_mgm_configuration *); @@ -111,6 +112,8 @@ public: Uint32 get_batch_byte_size(); Uint32 get_batch_size(); + TransporterRegistry* get_registry() { return theTransporterRegistry;}; + private: /** * Send a signal unconditional of node status (used by ClusterMgr) @@ -129,7 +132,8 @@ private: bool isConnected(NodeId aNodeId); void doStop(); - + + NdbMgmHandle m_mgm_handle; TransporterRegistry* theTransporterRegistry; SocketServer m_socket_server; int sendPerformedLastInterval; diff --git a/ndb/src/ndbapi/ndb_cluster_connection.cpp b/ndb/src/ndbapi/ndb_cluster_connection.cpp index 98a52786aab..1c03fc460cb 100644 --- a/ndb/src/ndbapi/ndb_cluster_connection.cpp +++ b/ndb/src/ndbapi/ndb_cluster_connection.cpp @@ -28,7 +28,7 @@ #include <ndb_limits.h> #include <ConfigRetriever.hpp> #include <ndb_version.h> -#include <Vector.hpp> +#include <mgmapi_debug.h> #include <md5_hash.hpp> static int g_run_connect_thread= 0; @@ -256,8 +256,6 @@ Ndb_cluster_connection_impl::Ndb_cluster_connection_impl(const char * { DBUG_ENTER("Ndb_cluster_connection"); DBUG_PRINT("enter",("Ndb_cluster_connection this=0x%x", this)); - m_transporter_facade= - TransporterFacade::theFacadeInstance= new TransporterFacade(); m_connect_thread= 0; m_connect_callback= 0; @@ -282,6 +280,10 @@ Ndb_cluster_connection_impl::Ndb_cluster_connection_impl(const char * m_config_retriever= 0; } + m_transporter_facade= + TransporterFacade::theFacadeInstance= + new TransporterFacade(m_config_retriever->get_mgmHandle()); + DBUG_VOID_RETURN; } @@ -467,6 +469,8 @@ Ndb_cluster_connection_impl::do_test() int Ndb_cluster_connection::connect(int no_retries, int retry_delay_in_seconds, int verbose) { + struct ndb_mgm_reply mgm_reply; + DBUG_ENTER("Ndb_cluster_connection::connect"); const char* error = 0; do { @@ -484,10 +488,22 @@ int Ndb_cluster_connection::connect(int no_retries, int retry_delay_in_seconds, ndb_mgm_configuration * props = m_impl.m_config_retriever->getConfig(); if(props == 0) break; - m_impl.m_transporter_facade->start_instance(nodeId, props); + m_impl.m_transporter_facade->start_instance(nodeId, props); m_impl.init_nodes_vector(nodeId, *props); + for(int i=0;i<m_impl.m_transporter_facade->get_registry()->m_transporter_interface.size();i++) + ndb_mgm_set_connection_int_parameter(m_impl.m_config_retriever->get_mgmHandle(), + nodeId, + m_impl.m_transporter_facade->get_registry() + ->m_transporter_interface[i] + .m_remote_nodeId, + CFG_CONNECTION_SERVER_PORT, + m_impl.m_transporter_facade->get_registry() + ->m_transporter_interface[i] + .m_service_port, + &mgm_reply); + ndb_mgm_destroy_configuration(props); m_impl.m_transporter_facade->connected(); DBUG_RETURN(0); diff --git a/ndb/src/ndbapi/ndberror.c b/ndb/src/ndbapi/ndberror.c index 562d8940f85..dd4a1cf0b9e 100644 --- a/ndb/src/ndbapi/ndberror.c +++ b/ndb/src/ndbapi/ndberror.c @@ -69,6 +69,7 @@ static const char* empty_string = ""; * 600 - ACC * 700 - DICT * 800 - TUP + * 900 - TUX * 1200 - LQH * 1300 - BACKUP * 4000 - API @@ -176,10 +177,13 @@ ErrorBundle ErrorCodes[] = { { 623, IS, "623" }, { 624, IS, "624" }, { 625, IS, "Out of memory in Ndb Kernel, index part (increase IndexMemory)" }, - { 800, IS, "Too many ordered indexes (increase MaxNoOfOrderedIndexes)" }, + { 640, IS, "Too many hash indexes (should not happen)" }, { 826, IS, "Too many tables and attributes (increase MaxNoOfAttributes or MaxNoOfTables)" }, { 827, IS, "Out of memory in Ndb Kernel, data part (increase DataMemory)" }, - { 832, IS, "832" }, + { 902, IS, "Out of memory in Ndb Kernel, data part (increase DataMemory)" }, + { 903, IS, "Too many ordered indexes (increase MaxNoOfOrderedIndexes)" }, + { 904, IS, "Out of fragment records (increase MaxNoOfOrderedIndexes)" }, + { 905, IS, "Out of attribute records (increase MaxNoOfAttributes)" }, /** * TimeoutExpired @@ -205,7 +209,8 @@ ErrorBundle ErrorCodes[] = { * Internal errors */ { 892, IE, "Inconsistent hash index. The index needs to be dropped and recreated" }, - { 895, IE, "Inconsistent ordered index. The index needs to be dropped and recreated" }, + { 896, IE, "Tuple corrupted - wrong checksum or column data in invalid format" }, + { 901, IE, "Inconsistent ordered index. The index needs to be dropped and recreated" }, { 202, IE, "202" }, { 203, IE, "203" }, { 207, IE, "207" }, @@ -303,20 +308,23 @@ ErrorBundle ErrorCodes[] = { { 709, SE, "No such table existed" }, { 721, SE, "Table or index with given name already exists" }, { 723, SE, "No such table existed" }, - { 736, SE, "Wrong attribute size" }, + { 736, SE, "Unsupported array size" }, { 737, SE, "Attribute array size too big" }, { 738, SE, "Record too big" }, { 739, SE, "Unsupported primary key length" }, { 740, SE, "Nullable primary key not supported" }, { 741, SE, "Unsupported alter table" }, - { 742, SE, "Unsupported attribute type in index" }, { 743, SE, "Unsupported character set in table or index" }, { 744, SE, "Character string is invalid for given character set" }, + { 745, SE, "Distribution key not supported for char attribute (use binary attribute)" }, { 241, SE, "Invalid schema object version" }, { 283, SE, "Table is being dropped" }, { 284, SE, "Table not defined in transaction coordinator" }, { 285, SE, "Unknown table error in transaction coordinator" }, { 881, SE, "Unable to create table, out of data pages (increase DataMemory) " }, + { 906, SE, "Unsupported attribute type in index" }, + { 907, SE, "Unsupported character set in table or index" }, + { 908, IS, "Invalid ordered index tree node size" }, { 1225, SE, "Table not defined in local query handler" }, { 1226, SE, "Table is being dropped" }, { 1228, SE, "Cannot use drop table for drop index" }, @@ -480,8 +488,8 @@ ErrorBundle ErrorCodes[] = { { 4266, AE, "Invalid blob seek position" }, { 4267, IE, "Corrupted blob value" }, { 4268, IE, "Error in blob head update forced rollback of transaction" }, - { 4268, IE, "Unknown blob error" }, { 4269, IE, "No connection to ndb management server" }, + { 4270, IE, "Unknown blob error" }, { 4335, AE, "Only one autoincrement column allowed per table. Having a table without primary key uses an autoincremented hidden key, i.e. a table without a primary key can not have an autoincremented column" } }; |