diff --git a/ndb/include/ndbapi/NdbDictionary.hpp b/ndb/include/ndbapi/NdbDictionary.hpp index b4e670dfb89..5bf71adb0d3 100644 --- a/ndb/include/ndbapi/NdbDictionary.hpp +++ b/ndb/include/ndbapi/NdbDictionary.hpp @@ -442,6 +442,8 @@ public: static const Column * COMMIT_COUNT; static const Column * ROW_SIZE; static const Column * RANGE_NO; + + int getSizeInBytes() const; #endif private: diff --git a/ndb/include/ndbapi/NdbOperation.hpp b/ndb/include/ndbapi/NdbOperation.hpp index 24af18bb507..fca610772cc 100644 --- a/ndb/include/ndbapi/NdbOperation.hpp +++ b/ndb/include/ndbapi/NdbOperation.hpp @@ -709,6 +709,11 @@ public: */ const char* getTableName() const; + /** + * Get table object for this operation + */ + const NdbDictionary::Table * getTable() const; + /** @} *********************************************************************/ #ifndef DOXYGEN_SHOULD_SKIP_INTERNAL diff --git a/ndb/include/ndbapi/NdbTransaction.hpp b/ndb/include/ndbapi/NdbTransaction.hpp index 148f4911ed9..e0b78511ca3 100644 --- a/ndb/include/ndbapi/NdbTransaction.hpp +++ b/ndb/include/ndbapi/NdbTransaction.hpp @@ -560,6 +560,11 @@ public: * ops are used (read, insert, update, delete). */ int executePendingBlobOps(Uint8 flags = 0xFF); + + /** + * Get nodeId of TC for this transaction + */ + Uint32 getConnectedNodeId(); // Get Connected node id #endif private: @@ -593,7 +598,6 @@ private: */ void setConnectedNodeId( Uint32 nodeId, Uint32 sequence); - Uint32 getConnectedNodeId(); // Get Connected node id void setMyBlockReference( int ); // Set my block refrerence void setTC_ConnectPtr( Uint32 ); // Sets TC Connect pointer int getTC_ConnectPtr(); // Gets TC Connect pointer diff --git a/ndb/include/util/Base64.hpp b/ndb/include/util/Base64.hpp index 1156636eec8..f4b11ad9214 100644 --- a/ndb/include/util/Base64.hpp +++ b/ndb/include/util/Base64.hpp @@ -21,6 +21,7 @@ #include int base64_encode(const UtilBuffer &src, BaseString &dst); +int base64_encode(const void * s, size_t src_len, BaseString &dst); int base64_decode(const BaseString &src, UtilBuffer &dst); int base64_decode(const char * s, size_t len, UtilBuffer &dst); diff --git a/ndb/src/common/util/Base64.cpp b/ndb/src/common/util/Base64.cpp index f7a490d427d..3db911f481f 100644 --- a/ndb/src/common/util/Base64.cpp +++ b/ndb/src/common/util/Base64.cpp @@ -22,17 +22,22 @@ static char base64_table[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZ" "0123456789+/"; int -base64_encode(const UtilBuffer &src, BaseString &dst) { - const unsigned char *s = (const unsigned char *)src.get_data(); +base64_encode(const UtilBuffer &src, BaseString &dst) +{ + return base64_encode(src.get_data(), src.length(), dst); +} + +int +base64_encode(const void * _s, size_t src_len, BaseString &dst) { + const unsigned char * s = (const unsigned char*)_s; size_t i = 0; size_t len = 0; - size_t src_len = src.length(); while(i < src_len) { if(len == 76){ len = 0; dst.append('\n'); } - + unsigned c; c = s[i++]; c <<= 8; diff --git a/ndb/src/kernel/blocks/ERROR_codes.txt b/ndb/src/kernel/blocks/ERROR_codes.txt index 5193d3eae9d..a30021607cc 100644 --- a/ndb/src/kernel/blocks/ERROR_codes.txt +++ b/ndb/src/kernel/blocks/ERROR_codes.txt @@ -196,6 +196,8 @@ Delay execution of ABORTREQ signal 2 seconds to generate time-out. 8048: Make TC not choose own node for simple/dirty read 5041: Crash is receiving simple read from other TC on different node +8050: Send TCKEYREF is operation is non local + ERROR CODES FOR TESTING TIME-OUT HANDLING IN DBTC ------------------------------------------------- 8040: @@ -409,6 +411,8 @@ Drop Table/Index: 8033: Fail next trigger create in TC 8034: Fail next index create in TC + + System Restart: --------------- diff --git a/ndb/src/kernel/blocks/dbdih/DbdihMain.cpp b/ndb/src/kernel/blocks/dbdih/DbdihMain.cpp index adae429e65d..b579c37c842 100644 --- a/ndb/src/kernel/blocks/dbdih/DbdihMain.cpp +++ b/ndb/src/kernel/blocks/dbdih/DbdihMain.cpp @@ -7475,6 +7475,22 @@ void Dbdih::execDIHNDBTAMPER(Signal* signal) #ifdef ERROR_INSERT case 5: jam(); + if(tuserpointer == 0) + { + jam(); + signal->theData[0] = 0; + sendSignal(QMGR_REF, GSN_NDB_TAMPER, signal, 1, JBB); + sendSignal(NDBCNTR_REF, GSN_NDB_TAMPER, signal, 1, JBB); + sendSignal(NDBFS_REF, GSN_NDB_TAMPER, signal, 1, JBB); + sendSignal(DBACC_REF, GSN_NDB_TAMPER, signal, 1, JBB); + sendSignal(DBTUP_REF, GSN_NDB_TAMPER, signal, 1, JBB); + sendSignal(DBLQH_REF, GSN_NDB_TAMPER, signal, 1, JBB); + sendSignal(DBDICT_REF, GSN_NDB_TAMPER, signal, 1, JBB); + sendSignal(DBDIH_REF, GSN_NDB_TAMPER, signal, 1, JBB); + sendSignal(DBTC_REF, GSN_NDB_TAMPER, signal, 1, JBB); + sendSignal(CMVMI_REF, GSN_NDB_TAMPER, signal, 1, JBB); + return; + } /*----------------------------------------------------------------------*/ // Insert errors. /*----------------------------------------------------------------------*/ diff --git a/ndb/src/kernel/blocks/dbtc/DbtcMain.cpp b/ndb/src/kernel/blocks/dbtc/DbtcMain.cpp index cf4bdaeebbc..ce38c355c91 100644 --- a/ndb/src/kernel/blocks/dbtc/DbtcMain.cpp +++ b/ndb/src/kernel/blocks/dbtc/DbtcMain.cpp @@ -3081,6 +3081,15 @@ void Dbtc::tckeyreq050Lab(Signal* signal) execDIGETNODESREF(signal); return; } + + if(ERROR_INSERTED(8050) && signal->theData[3] != getOwnNodeId()) + { + ndbassert(false); + signal->theData[1] = 626; + execDIGETNODESREF(signal); + return; + } + /****************>>*/ /* DIGETNODESCONF >*/ /* ***************>*/ diff --git a/ndb/src/ndbapi/NdbDictionary.cpp b/ndb/src/ndbapi/NdbDictionary.cpp index 4221c22121d..3299abdb2b4 100644 --- a/ndb/src/ndbapi/NdbDictionary.cpp +++ b/ndb/src/ndbapi/NdbDictionary.cpp @@ -231,6 +231,12 @@ NdbDictionary::Column::equal(const NdbDictionary::Column & col) const { return m_impl.equal(col.m_impl); } +int +NdbDictionary::Column::getSizeInBytes() const +{ + return m_impl.m_attrSize * m_impl.m_arraySize; +} + /***************************************************************** * Table facade */ @@ -426,8 +432,7 @@ NdbDictionary::Table::getRowSizeInBytes() const { int sz = 0; for(int i = 0; igetSizeInBytes()+ 3) / 4; } return sz * 4; } diff --git a/ndb/src/ndbapi/NdbDictionaryImpl.cpp b/ndb/src/ndbapi/NdbDictionaryImpl.cpp index 7107f109e94..06248bceee1 100644 --- a/ndb/src/ndbapi/NdbDictionaryImpl.cpp +++ b/ndb/src/ndbapi/NdbDictionaryImpl.cpp @@ -1264,7 +1264,8 @@ NdbDictInterface::parseTableInfo(NdbTableImpl ** ret, Uint32 blobCount = 0; Uint32 distKeys = 0; - for(Uint32 i = 0; i < tableDesc.NoOfAttributes; i++) { + Uint32 i; + for(i = 0; i < tableDesc.NoOfAttributes; i++) { DictTabInfo::Attribute attrDesc; attrDesc.init(); s = SimpleProperties::unpack(it, &attrDesc, @@ -1348,7 +1349,6 @@ NdbDictInterface::parseTableInfo(NdbTableImpl ** ret, if(tableDesc.FragmentDataLen > 0) { - unsigned i; Uint32 replicaCount = tableDesc.FragmentData[0]; Uint32 fragCount = tableDesc.FragmentData[1]; @@ -1377,6 +1377,15 @@ NdbDictInterface::parseTableInfo(NdbTableImpl ** ret, impl->m_hashpointerValue = 0; } + if(distKeys == 0) + { + for(i = 0; i < tableDesc.NoOfAttributes; i++) + { + if(impl->m_columns[i]->getPrimaryKey()) + impl->m_columns[i]->m_distributionKey = true; + } + } + * ret = impl; DBUG_RETURN(0); @@ -1468,7 +1477,6 @@ int NdbDictionaryImpl::alterTable(NdbTableImpl &impl) BaseString internalName = impl.m_internalName; const char * originalInternalName = internalName.c_str(); BaseString externalName = impl.m_externalName; - const char * originalExternalName = externalName.c_str(); DBUG_ENTER("NdbDictionaryImpl::alterTable"); if(!get_local_table_info(originalInternalName, false)){ @@ -1705,11 +1713,12 @@ void NdbDictInterface::execCREATE_TABLE_CONF(NdbApiSignal * signal, LinearSectionPtr ptr[3]) { +#if 0 const CreateTableConf* const conf= CAST_CONSTPTR(CreateTableConf, signal->getDataPtr()); Uint32 tableId= conf->tableId; Uint32 tableVersion= conf->tableVersion; - +#endif m_waiter.signal(NO_WAIT); } diff --git a/ndb/src/ndbapi/NdbOperation.cpp b/ndb/src/ndbapi/NdbOperation.cpp index 58147f2654e..c9143444908 100644 --- a/ndb/src/ndbapi/NdbOperation.cpp +++ b/ndb/src/ndbapi/NdbOperation.cpp @@ -392,3 +392,9 @@ NdbOperation::getTableName() const { return m_currentTable->m_externalName.c_str(); } + +const NdbDictionary::Table* +NdbOperation::getTable() const +{ + return m_currentTable; +} diff --git a/ndb/src/ndbapi/NdbOperationSearch.cpp b/ndb/src/ndbapi/NdbOperationSearch.cpp index 6e76287eef0..06d8ddd412b 100644 --- a/ndb/src/ndbapi/NdbOperationSearch.cpp +++ b/ndb/src/ndbapi/NdbOperationSearch.cpp @@ -229,9 +229,6 @@ NdbOperation::equal_impl(const NdbColumnImpl* tAttrInfo, theNoOfTupKeyLeft = tNoKeysDef; tErrorLine++; theErrorLine = tErrorLine; - - if(tDistrKey) - handle_distribution_key((Uint64*)aValue, totalSizeInWords); if (tNoKeysDef == 0) { if (tOpType == UpdateRequest) { diff --git a/ndb/test/include/HugoCalculator.hpp b/ndb/test/include/HugoCalculator.hpp index 108af0d1358..03de46cd7ea 100644 --- a/ndb/test/include/HugoCalculator.hpp +++ b/ndb/test/include/HugoCalculator.hpp @@ -31,13 +31,6 @@ class HugoCalculator { public: HugoCalculator(const NdbDictionary::Table& tab); Int32 calcValue(int record, int attrib, int updates) const; -#if 0 - U_Int32 calcValue(int record, int attrib, int updates) const; - U_Int64 calcValue(int record, int attrib, int updates) const; - Int64 calcValue(int record, int attrib, int updates) const; - float calcValue(int record, int attrib, int updates) const; - double calcValue(int record, int attrib, int updates) const; -#endif const char* calcValue(int record, int attrib, int updates, char* buf, int len) const; int verifyRowValues(NDBT_ResultRow* const pRow) const; diff --git a/ndb/test/include/HugoOperations.hpp b/ndb/test/include/HugoOperations.hpp index d7f336a117d..38e53d765ec 100644 --- a/ndb/test/include/HugoOperations.hpp +++ b/ndb/test/include/HugoOperations.hpp @@ -29,8 +29,9 @@ public: ~HugoOperations(); int startTransaction(Ndb*); + int setTransaction(NdbTransaction*); int closeTransaction(Ndb*); - NdbConnection* getTransaction(); + NdbTransaction* getTransaction(); void refresh(); int pkInsertRecord(Ndb*, @@ -68,10 +69,13 @@ public: int attrId, int rowId, int updateId); + int equalForAttr(NdbOperation*, int attrId, int rowId); - + + int setValues(NdbOperation*, int rowId, int updateId); + int verifyUpdatesValue(int updatesValue, int _numRows = 0); int indexReadRecords(Ndb*, const char * idxName, int recordNo, diff --git a/ndb/test/ndbapi/testPartitioning.cpp b/ndb/test/ndbapi/testPartitioning.cpp index c50921b85fc..9d67c27354b 100644 --- a/ndb/test/ndbapi/testPartitioning.cpp +++ b/ndb/test/ndbapi/testPartitioning.cpp @@ -318,8 +318,51 @@ run_startHint(NDBT_Context* ctx, NDBT_Step* step) { return NDBT_FAILED; } + + NdbRestarter restarter; + if(restarter.insertErrorInAllNodes(8050) != 0) + return NDBT_FAILED; - return NDBT_OK; + HugoCalculator dummy(*tab); + int result = NDBT_OK; + for(int i = 0; igetNoOfColumns(); j++) + { + if(tab->getColumn(j)->getPartitionKey()) + { + ndbout_c(tab->getColumn(j)->getName()); + int sz = tab->getColumn(j)->getSizeInBytes(); + int aligned_size = 4 * ((sz + 3) >> 2); + memset(pos, 0, aligned_size); + dummy.calcValue(i, j, 0, pos, sz); + pos += aligned_size; + } + } + // Now we have the pk + NdbTransaction* pTrans= p_ndb->startTransaction(tab, start,(pos - start)); + HugoOperations ops(*tab); + ops.setTransaction(pTrans); + if(ops.pkReadRecord(p_ndb, i, 1) != NDBT_OK) + { + result = NDBT_FAILED; + break; + } + + if(ops.execute_Commit(p_ndb) != 0) + { + result = NDBT_FAILED; + break; + } + + ops.closeTransaction(p_ndb); + } + restarter.insertErrorInAllNodes(0); + return result; } @@ -358,9 +401,18 @@ TESTCASE("ordered_index_dk", INITIALIZER(run_drop_table); } TESTCASE("startTransactionHint", - "Test startTransactionHint") + "Test startTransactionHint wo/ distribution key") { - TC_PROPERTY("distributionkey", ~0); + TC_PROPERTY("distributionkey", (unsigned)0); + INITIALIZER(run_drop_table); + INITIALIZER(run_create_table); + INITIALIZER(run_startHint); + INITIALIZER(run_drop_table); +} +TESTCASE("startTransactionHint_dk", + "Test startTransactionHint with distribution key") +{ + TC_PROPERTY("distributionkey", (unsigned)~0); INITIALIZER(run_drop_table); INITIALIZER(run_create_table); INITIALIZER(run_startHint); diff --git a/ndb/test/run-test/atrt-mysql-test-run b/ndb/test/run-test/atrt-mysql-test-run index dd7b709bd06..c30a4defc7f 100755 --- a/ndb/test/run-test/atrt-mysql-test-run +++ b/ndb/test/run-test/atrt-mysql-test-run @@ -5,8 +5,8 @@ p=`pwd` cd $MYSQL_BASE_DIR/mysql-test ./mysql-test-run --with-ndbcluster --ndb-connectstring=$NDB_CONNECTSTRING $* | tee $p/output.txt -f=`grep -c fail $p/output.txt` -o=`grep -c pass $p/output.txt` +f=`grep -c '[ fail ]' $p/output.txt` +o=`grep -c '[ pass ]' $p/output.txt` if [ $o -gt 0 -a $f -eq 0 ] then diff --git a/ndb/test/src/HugoCalculator.cpp b/ndb/test/src/HugoCalculator.cpp index 675d0ac786a..77821870754 100644 --- a/ndb/test/src/HugoCalculator.cpp +++ b/ndb/test/src/HugoCalculator.cpp @@ -16,6 +16,7 @@ #include "HugoCalculator.hpp" #include +#include /* ************************************************************* * HugoCalculator @@ -58,22 +59,11 @@ Int32 HugoCalculator::calcValue(int record, int attrib, int updates) const { - const NdbDictionary::Column* attr = m_tab.getColumn(attrib); - // If this is the "id" column - if (attrib == m_idCol) - return record; - - // If this is the update column - if (attrib == m_updatesCol) - return updates; + + Int32 i; + calcValue(record, attrib, updates, (char*)&i, sizeof(i)); - - Int32 val; - if (attr->getPrimaryKey()) - val = record + attrib; - else - val = record + attrib + updates; - return val; + return i; } #if 0 HugoCalculator::U_Int32 calcValue(int record, int attrib, int updates) const; @@ -88,52 +78,100 @@ HugoCalculator::calcValue(int record, int updates, char* buf, int len) const { - const char a[26] = {"UAWBORCTDPEFQGNYHISJMKXLZ"}; + const NdbDictionary::Column* attr = m_tab.getColumn(attrib); - int val = calcValue(record, attrib, updates); - - if (attr->getPrimaryKey()){ - // Create a string where val is printed as chars in the beginning - // of the string, then fill with other chars - // The string length is set to the same size as the attribute - BaseString::snprintf(buf, len, "%d", val); - for(int i=strlen(buf); i < len; i++) - buf[i] = a[((val^i)%25)]; - } else{ - - // Fill buf with some pattern so that we can detect - // anomalies in the area that we don't fill with chars - int i; - for (i = 0; igetType() == NdbDictionary::Column::Varchar) - len = val % (len + 1); - else - if((val % (len + 1)) == 0) - len = 0; - - // If len == 0 return NULL if this is a nullable attribute - if (len == 0){ - if(attr->getNullable() == true) - return NULL; - else - len++; - } - for(i=0; i < len; i++) - buf[i] = a[((val^i)%25)]; - buf[len] = 0; - - if(attr->getType() == NdbDictionary::Column::Bit) + Uint32 val; + do + { + if (attrib == m_idCol) { - Uint32 bits= attr->getLength(); - Uint32 pos = bits >> 5; - Uint32 size = bits & 31; - ((Uint32*)buf)[pos] &= ((1 << size) - 1); + *((Uint32*)buf)= record; + return buf; } + + // If this is the update column + if (attrib == m_updatesCol) + { + *((Uint32*)buf)= updates; + return buf; + } + + if (attr->getPrimaryKey()) + { + srand(record + attrib + updates); + val = (record + attrib); + } + else + { + srand(record + attrib + updates); + val = rand(); + } + } while (0); + + if(attr->getNullable() && (((val >> 16) & 255) > 220)) + return NULL; + + memcpy(buf, &val, (len > 4 ? 4 : len)); + int pos= 4; + while(pos + 4 < len) + { + val= rand(); + memcpy(buf+pos, &val, 4); + pos++; } + + if(pos < len) + { + val= rand(); + memcpy(buf+pos, &val, (len - pos)); + } + + switch(attr->getType()){ + case NdbDictionary::Column::Tinyint: + case NdbDictionary::Column::Tinyunsigned: + case NdbDictionary::Column::Smallint: + case NdbDictionary::Column::Smallunsigned: + case NdbDictionary::Column::Mediumint: + case NdbDictionary::Column::Mediumunsigned: + case NdbDictionary::Column::Int: + case NdbDictionary::Column::Unsigned: + case NdbDictionary::Column::Bigint: + case NdbDictionary::Column::Bigunsigned: + case NdbDictionary::Column::Float: + case NdbDictionary::Column::Double: + case NdbDictionary::Column::Decimal: + case NdbDictionary::Column::Binary: + case NdbDictionary::Column::Datetime: + case NdbDictionary::Column::Time: + case NdbDictionary::Column::Date: + break; + case NdbDictionary::Column::Bit: + { + Uint32 bits= attr->getLength(); + Uint32 tmp = bits >> 5; + Uint32 size = bits & 31; + ((Uint32*)buf)[tmp] &= ((1 << size) - 1); + break; + } + case NdbDictionary::Column::Varbinary: + case NdbDictionary::Column::Varchar: + case NdbDictionary::Column::Text: + case NdbDictionary::Column::Char: + case NdbDictionary::Column::Longvarchar: + case NdbDictionary::Column::Longvarbinary: + { + BaseString tmp; + base64_encode(buf, len, tmp); + memcpy(buf, tmp.c_str(), len); + break; + } + case NdbDictionary::Column::Blob: + case NdbDictionary::Column::Undefined: + abort(); + break; + } + + return buf; } @@ -148,93 +186,40 @@ HugoCalculator::verifyRowValues(NDBT_ResultRow* const pRow) const{ // Check the values of each column for (int i = 0; igetLength(); - switch (attr->getType()){ - case NdbDictionary::Column::Bit: - len = 4 * ((len + 31) >> 5); - case NdbDictionary::Column::Char: - case NdbDictionary::Column::Varchar: - case NdbDictionary::Column::Binary: - case NdbDictionary::Column::Varbinary:{ - char* buf = new char[len+1]; - const char* res = calcValue(id, i, updates, buf, len); - if (res == NULL){ - if (!pRow->attributeStore(i)->isNULL()){ - g_err << "|- NULL ERROR: expected a NULL but the column was not null" << endl; - g_err << "|- The row: \"" << (*pRow) << "\"" << endl; - result = -1; - } - } else{ - if (memcmp(res, pRow->attributeStore(i)->aRef(), len) != 0){ - // if (memcmp(res, pRow->attributeStore(i)->aRef(), pRow->attributeStore(i)->getLength()) != 0){ - g_err << "Column: " << attr->getName() << endl; - const char* buf2 = pRow->attributeStore(i)->aRef(); - for (Uint32 j = 0; j < len; j++) + Uint32 len = attr->getSizeInBytes(); + char buf[8000]; + const char* res = calcValue(id, i, updates, buf, len); + if (res == NULL){ + if (!pRow->attributeStore(i)->isNULL()){ + g_err << "|- NULL ERROR: expected a NULL but the column was not null" << endl; + g_err << "|- The row: \"" << (*pRow) << "\"" << endl; + result = -1; + } + } else{ + if (memcmp(res, pRow->attributeStore(i)->aRef(), len) != 0){ + // if (memcmp(res, pRow->attributeStore(i)->aRef(), pRow->attributeStore(i)->getLength()) != 0){ + g_err << "Column: " << attr->getName() << endl; + const char* buf2 = pRow->attributeStore(i)->aRef(); + for (Uint32 j = 0; j < len; j++) + { + g_err << j << ":" << hex << (int)buf[j] << "[" << hex << (int)buf2[j] << "]"; + if (buf[j] != buf2[j]) { - g_err << j << ":" << hex << (int)buf[j] << "[" << hex << (int)buf2[j] << "]"; - if (buf[j] != buf2[j]) - { - g_err << "==>Match failed!"; - } - g_err << endl; + g_err << "==>Match failed!"; } g_err << endl; - g_err << "|- Invalid data found in attribute " << i << ": \"" - << pRow->attributeStore(i)->aRef() - << "\" != \"" << res << "\"" << endl - << "Length of expected=" << (unsigned)strlen(res) << endl - << "Lenght of read=" - << (unsigned)strlen(pRow->attributeStore(i)->aRef()) << endl; - g_err << "|- The row: \"" << (* pRow) << "\"" << endl; - result = -1; } - } - delete []buf; - } - break; - case NdbDictionary::Column::Int: - case NdbDictionary::Column::Unsigned:{ - Int32 cval = calcValue(id, i, updates); - Int32 val = pRow->attributeStore(i)->int32_value(); - if (val != cval){ - g_err << "|- Invalid data found: \"" << val << "\" != \"" - << cval << "\"" << endl; + g_err << endl; + g_err << "|- Invalid data found in attribute " << i << ": \"" + << pRow->attributeStore(i)->aRef() + << "\" != \"" << res << "\"" << endl + << "Length of expected=" << (unsigned)strlen(res) << endl + << "Lenght of read=" + << (unsigned)strlen(pRow->attributeStore(i)->aRef()) << endl; g_err << "|- The row: \"" << (* pRow) << "\"" << endl; result = -1; } - break; - } - case NdbDictionary::Column::Bigint: - case NdbDictionary::Column::Bigunsigned:{ - Uint64 cval = calcValue(id, i, updates); - Uint64 val = pRow->attributeStore(i)->u_64_value(); - if (val != cval){ - g_err << "|- Invalid data found: \"" << val << "\" != \"" - << cval << "\"" - << endl; - g_err << "|- The row: \"" << (* pRow) << "\"" << endl; - result = -1; - } - } - break; - case NdbDictionary::Column::Float:{ - float cval = calcValue(id, i, updates); - float val = pRow->attributeStore(i)->float_value(); - if (val != cval){ - g_err << "|- Invalid data found: \"" << val << "\" != \"" - << cval << "\"" << endl; - g_err << "|- The row: \"" << (* pRow) << "\"" << endl; - result = -1; - } - } - break; - case NdbDictionary::Column::Undefined: - default: - assert(0); - result = -1; - break; } } } diff --git a/ndb/test/src/HugoOperations.cpp b/ndb/test/src/HugoOperations.cpp index f670591fe9c..959db70ec2e 100644 --- a/ndb/test/src/HugoOperations.cpp +++ b/ndb/test/src/HugoOperations.cpp @@ -32,6 +32,19 @@ int HugoOperations::startTransaction(Ndb* pNdb){ return NDBT_OK; } +int HugoOperations::setTransaction(NdbTransaction* new_trans){ + + if (pTrans != NULL){ + ndbout << "HugoOperations::startTransaction, pTrans != NULL" << endl; + return NDBT_FAILED; + } + pTrans = new_trans; + if (pTrans == NULL) { + return NDBT_FAILED; + } + return NDBT_OK; +} + int HugoOperations::closeTransaction(Ndb* pNdb){ if (pTrans != NULL){ @@ -145,26 +158,33 @@ int HugoOperations::pkUpdateRecord(Ndb* pNdb, return NDBT_FAILED; } - // Define primary keys - for(a = 0; agetPrimaryKey() == true){ - if(equalForAttr(pOp, a, r+recordNo) != 0){ - ERR(pTrans->getNdbError()); - return NDBT_FAILED; - } + if(setValues(pOp, r+recordNo, updatesValue) != NDBT_OK) + { + return NDBT_FAILED; + } + } + return NDBT_OK; +} + +int +HugoOperations::setValues(NdbOperation* pOp, int rowId, int updateId) +{ + // Define primary keys + int a; + for(a = 0; agetPrimaryKey() == true){ + if(equalForAttr(pOp, a, rowId) != 0){ + ERR(pTrans->getNdbError()); + return NDBT_FAILED; + } + } else { + if(setValueForAttr(pOp, a, rowId, updateId ) != 0){ + ERR(pTrans->getNdbError()); + return NDBT_FAILED; } } - - // Define attributes to update - for(a = 0; agetPrimaryKey() == false){ - if(setValueForAttr(pOp, a, recordNo+r, updatesValue ) != 0){ - ERR(pTrans->getNdbError()); - return NDBT_FAILED; - } - } - } } + return NDBT_OK; } @@ -187,25 +207,10 @@ int HugoOperations::pkInsertRecord(Ndb* pNdb, return NDBT_FAILED; } - // Define primary keys - for(a = 0; agetPrimaryKey() == true){ - if(equalForAttr(pOp, a, r+recordNo) != 0){ - ERR(pTrans->getNdbError()); - return NDBT_FAILED; - } - } + if(setValues(pOp, r+recordNo, updatesValue) != NDBT_OK) + { + return NDBT_FAILED; } - - // Define attributes to update - for(a = 0; agetPrimaryKey() == false){ - if(setValueForAttr(pOp, a, recordNo+r, updatesValue ) != 0){ - ERR(pTrans->getNdbError()); - return NDBT_FAILED; - } - } - } } return NDBT_OK; } @@ -373,38 +378,11 @@ int HugoOperations::equalForAttr(NdbOperation* pOp, return NDBT_FAILED; } - int len = attr->getLength(); - switch (attr->getType()){ - case NdbDictionary::Column::Bit: - len = 4 * ((len + 31) >> 5); - case NdbDictionary::Column::Char: - case NdbDictionary::Column::Varchar: - case NdbDictionary::Column::Binary: - case NdbDictionary::Column::Varbinary:{ - char buf[8000]; - memset(buf, 0, sizeof(buf)); - check = pOp->equal( attr->getName(), - calc.calcValue(rowId, attrId, 0, buf, len)); - break; - } - case NdbDictionary::Column::Int: - check = pOp->equal( attr->getName(), (Int32)calc.calcValue(rowId, attrId, 0)); - break; - case NdbDictionary::Column::Unsigned: - check = pOp->equal( attr->getName(), (Uint32)calc.calcValue(rowId, attrId, 0)); - break; - case NdbDictionary::Column::Bigint: - check = pOp->equal( attr->getName(), (Int64)calc.calcValue(rowId, attrId, 0)); - break; - case NdbDictionary::Column::Bigunsigned: - check = pOp->equal( attr->getName(), (Uint64)calc.calcValue(rowId, attrId, 0)); - break; - case NdbDictionary::Column::Float: - g_info << "Float not allowed as PK value" << endl; - check = -1; - break; - } - return check; + int len = attr->getSizeInBytes(); + char buf[8000]; + memset(buf, 0, sizeof(buf)); + return pOp->equal( attr->getName(), + calc.calcValue(rowId, attrId, 0, buf, len)); } int HugoOperations::setValueForAttr(NdbOperation* pOp, @@ -414,47 +392,11 @@ int HugoOperations::setValueForAttr(NdbOperation* pOp, int check = -1; const NdbDictionary::Column* attr = tab.getColumn(attrId); - int len = attr->getLength(); - switch (attr->getType()){ - case NdbDictionary::Column::Bit: - len = 4 * ((len + 31) >> 5); - case NdbDictionary::Column::Char: - case NdbDictionary::Column::Varchar: - case NdbDictionary::Column::Binary: - case NdbDictionary::Column::Varbinary:{ - char buf[8000]; - check = pOp->setValue( attr->getName(), - calc.calcValue(rowId, attrId, updateId, buf, len)); - break; - } - case NdbDictionary::Column::Int:{ - Int32 val = calc.calcValue(rowId, attrId, updateId); - check = pOp->setValue( attr->getName(), val); - } - break; - case NdbDictionary::Column::Bigint:{ - Int64 val = calc.calcValue(rowId, attrId, updateId); - check = pOp->setValue( attr->getName(), - val); - } - break; - case NdbDictionary::Column::Unsigned:{ - Uint32 val = calc.calcValue(rowId, attrId, updateId); - check = pOp->setValue( attr->getName(), val); - } - break; - case NdbDictionary::Column::Bigunsigned:{ - Uint64 val = calc.calcValue(rowId, attrId, updateId); - check = pOp->setValue( attr->getName(), - val); - } - break; - case NdbDictionary::Column::Float: - check = pOp->setValue( attr->getName(), - (float)calc.calcValue(rowId, attrId, updateId)); - break; - } - return check; + int len = attr->getSizeInBytes(); + char buf[8000]; + memset(buf, 0, sizeof(buf)); + return pOp->setValue( attr->getName(), + calc.calcValue(rowId, attrId, updateId, buf, len)); } int @@ -470,7 +412,7 @@ HugoOperations::verifyUpdatesValue(int updatesValue, int _numRows){ result = NDBT_FAILED; continue; } - + if(calc.getUpdatesValue(rows[i]) != updatesValue){ result = NDBT_FAILED; g_err << "Invalid updates value for row " << i << endl @@ -480,7 +422,7 @@ HugoOperations::verifyUpdatesValue(int updatesValue, int _numRows){ continue; } } - + if(_numRows == 0){ g_err << "No rows -> Invalid updates value" << endl; return NDBT_FAILED;