Commit 3705bf9d authored by unknown's avatar unknown

wl2240 - ndb - new testcase for validating startTransation with hint


ndb/include/ndbapi/NdbDictionary.hpp:
  NdbDictionaryColumn::getSizeInBytes
ndb/include/ndbapi/NdbOperation.hpp:
  NdbOperation::getTable
ndb/include/ndbapi/NdbTransaction.hpp:
  Make getConnectionNodeId public (for test programs)
ndb/include/util/Base64.hpp:
  base64(void*)
ndb/src/common/util/Base64.cpp:
  base64(void*)
ndb/src/kernel/blocks/ERROR_codes.txt:
  New error code for REF'ing non-local TCKEYREQ
ndb/src/kernel/blocks/dbdih/DbdihMain.cpp:
  Easy clearing of ERROR_INSERT
ndb/src/kernel/blocks/dbtc/DbtcMain.cpp:
  New error code for REF'ing non-local TCKEYREQ
ndb/src/ndbapi/NdbDictionary.cpp:
  NdbDictionaryColumn::getSizeInBytes
ndb/src/ndbapi/NdbDictionaryImpl.cpp:
  If m_noIfDistKyes == 0, then each PK is dist key
ndb/src/ndbapi/NdbOperation.cpp:
  NdbOperation::getTable
ndb/src/ndbapi/NdbOperationSearch.cpp:
  remove d-key handling for pk ops
ndb/test/include/HugoCalculator.hpp:
  remove unimpletemented methods
ndb/test/include/HugoOperations.hpp:
  1) HugoOperation::setTransaction 
  2) Type independant value handling
  3) Some more util methods
ndb/test/ndbapi/testPartitioning.cpp:
  new testcase for validating startTransation with hint
ndb/test/run-test/atrt-mysql-test-run:
  fix checks of return values
ndb/test/src/HugoCalculator.cpp:
  Better generation of values
   -- depends on fact that srand(K), rand() == srand(K), rand()
  Generate string with base64
ndb/test/src/HugoOperations.cpp:
  1) HugoOperation::setTransaction 
  2) Type independant value handling
  3) Some more util methods
parent ae9b0794
...@@ -442,6 +442,8 @@ public: ...@@ -442,6 +442,8 @@ public:
static const Column * COMMIT_COUNT; static const Column * COMMIT_COUNT;
static const Column * ROW_SIZE; static const Column * ROW_SIZE;
static const Column * RANGE_NO; static const Column * RANGE_NO;
int getSizeInBytes() const;
#endif #endif
private: private:
......
...@@ -709,6 +709,11 @@ public: ...@@ -709,6 +709,11 @@ public:
*/ */
const char* getTableName() const; const char* getTableName() const;
/**
* Get table object for this operation
*/
const NdbDictionary::Table * getTable() const;
/** @} *********************************************************************/ /** @} *********************************************************************/
#ifndef DOXYGEN_SHOULD_SKIP_INTERNAL #ifndef DOXYGEN_SHOULD_SKIP_INTERNAL
......
...@@ -560,6 +560,11 @@ public: ...@@ -560,6 +560,11 @@ public:
* ops are used (read, insert, update, delete). * ops are used (read, insert, update, delete).
*/ */
int executePendingBlobOps(Uint8 flags = 0xFF); int executePendingBlobOps(Uint8 flags = 0xFF);
/**
* Get nodeId of TC for this transaction
*/
Uint32 getConnectedNodeId(); // Get Connected node id
#endif #endif
private: private:
...@@ -593,7 +598,6 @@ private: ...@@ -593,7 +598,6 @@ private:
*/ */
void setConnectedNodeId( Uint32 nodeId, Uint32 sequence); void setConnectedNodeId( Uint32 nodeId, Uint32 sequence);
Uint32 getConnectedNodeId(); // Get Connected node id
void setMyBlockReference( int ); // Set my block refrerence void setMyBlockReference( int ); // Set my block refrerence
void setTC_ConnectPtr( Uint32 ); // Sets TC Connect pointer void setTC_ConnectPtr( Uint32 ); // Sets TC Connect pointer
int getTC_ConnectPtr(); // Gets TC Connect pointer int getTC_ConnectPtr(); // Gets TC Connect pointer
......
...@@ -21,6 +21,7 @@ ...@@ -21,6 +21,7 @@
#include <BaseString.hpp> #include <BaseString.hpp>
int base64_encode(const UtilBuffer &src, BaseString &dst); 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 BaseString &src, UtilBuffer &dst);
int base64_decode(const char * s, size_t len, UtilBuffer &dst); int base64_decode(const char * s, size_t len, UtilBuffer &dst);
......
...@@ -22,11 +22,16 @@ static char base64_table[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZ" ...@@ -22,11 +22,16 @@ static char base64_table[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
"0123456789+/"; "0123456789+/";
int int
base64_encode(const UtilBuffer &src, BaseString &dst) { base64_encode(const UtilBuffer &src, BaseString &dst)
const unsigned char *s = (const unsigned char *)src.get_data(); {
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 i = 0;
size_t len = 0; size_t len = 0;
size_t src_len = src.length();
while(i < src_len) { while(i < src_len) {
if(len == 76){ if(len == 76){
len = 0; len = 0;
......
...@@ -196,6 +196,8 @@ Delay execution of ABORTREQ signal 2 seconds to generate time-out. ...@@ -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 8048: Make TC not choose own node for simple/dirty read
5041: Crash is receiving simple read from other TC on different node 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 ERROR CODES FOR TESTING TIME-OUT HANDLING IN DBTC
------------------------------------------------- -------------------------------------------------
8040: 8040:
...@@ -409,6 +411,8 @@ Drop Table/Index: ...@@ -409,6 +411,8 @@ Drop Table/Index:
8033: Fail next trigger create in TC 8033: Fail next trigger create in TC
8034: Fail next index create in TC 8034: Fail next index create in TC
System Restart: System Restart:
--------------- ---------------
......
...@@ -7475,6 +7475,22 @@ void Dbdih::execDIHNDBTAMPER(Signal* signal) ...@@ -7475,6 +7475,22 @@ void Dbdih::execDIHNDBTAMPER(Signal* signal)
#ifdef ERROR_INSERT #ifdef ERROR_INSERT
case 5: case 5:
jam(); 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. // Insert errors.
/*----------------------------------------------------------------------*/ /*----------------------------------------------------------------------*/
......
...@@ -3081,6 +3081,15 @@ void Dbtc::tckeyreq050Lab(Signal* signal) ...@@ -3081,6 +3081,15 @@ void Dbtc::tckeyreq050Lab(Signal* signal)
execDIGETNODESREF(signal); execDIGETNODESREF(signal);
return; return;
} }
if(ERROR_INSERTED(8050) && signal->theData[3] != getOwnNodeId())
{
ndbassert(false);
signal->theData[1] = 626;
execDIGETNODESREF(signal);
return;
}
/****************>>*/ /****************>>*/
/* DIGETNODESCONF >*/ /* DIGETNODESCONF >*/
/* ***************>*/ /* ***************>*/
......
...@@ -231,6 +231,12 @@ NdbDictionary::Column::equal(const NdbDictionary::Column & col) const { ...@@ -231,6 +231,12 @@ NdbDictionary::Column::equal(const NdbDictionary::Column & col) const {
return m_impl.equal(col.m_impl); return m_impl.equal(col.m_impl);
} }
int
NdbDictionary::Column::getSizeInBytes() const
{
return m_impl.m_attrSize * m_impl.m_arraySize;
}
/***************************************************************** /*****************************************************************
* Table facade * Table facade
*/ */
...@@ -426,8 +432,7 @@ NdbDictionary::Table::getRowSizeInBytes() const { ...@@ -426,8 +432,7 @@ NdbDictionary::Table::getRowSizeInBytes() const {
int sz = 0; int sz = 0;
for(int i = 0; i<getNoOfColumns(); i++){ for(int i = 0; i<getNoOfColumns(); i++){
const NdbDictionary::Column * c = getColumn(i); const NdbDictionary::Column * c = getColumn(i);
const NdbColumnImpl & col = NdbColumnImpl::getImpl(* c); sz += (c->getSizeInBytes()+ 3) / 4;
sz += (((col.m_attrSize * col.m_arraySize) + 3) / 4);
} }
return sz * 4; return sz * 4;
} }
......
...@@ -1264,7 +1264,8 @@ NdbDictInterface::parseTableInfo(NdbTableImpl ** ret, ...@@ -1264,7 +1264,8 @@ NdbDictInterface::parseTableInfo(NdbTableImpl ** ret,
Uint32 blobCount = 0; Uint32 blobCount = 0;
Uint32 distKeys = 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(); DictTabInfo::Attribute attrDesc; attrDesc.init();
s = SimpleProperties::unpack(it, s = SimpleProperties::unpack(it,
&attrDesc, &attrDesc,
...@@ -1348,7 +1349,6 @@ NdbDictInterface::parseTableInfo(NdbTableImpl ** ret, ...@@ -1348,7 +1349,6 @@ NdbDictInterface::parseTableInfo(NdbTableImpl ** ret,
if(tableDesc.FragmentDataLen > 0) if(tableDesc.FragmentDataLen > 0)
{ {
unsigned i;
Uint32 replicaCount = tableDesc.FragmentData[0]; Uint32 replicaCount = tableDesc.FragmentData[0];
Uint32 fragCount = tableDesc.FragmentData[1]; Uint32 fragCount = tableDesc.FragmentData[1];
...@@ -1377,6 +1377,15 @@ NdbDictInterface::parseTableInfo(NdbTableImpl ** ret, ...@@ -1377,6 +1377,15 @@ NdbDictInterface::parseTableInfo(NdbTableImpl ** ret,
impl->m_hashpointerValue = 0; 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; * ret = impl;
DBUG_RETURN(0); DBUG_RETURN(0);
...@@ -1468,7 +1477,6 @@ int NdbDictionaryImpl::alterTable(NdbTableImpl &impl) ...@@ -1468,7 +1477,6 @@ int NdbDictionaryImpl::alterTable(NdbTableImpl &impl)
BaseString internalName = impl.m_internalName; BaseString internalName = impl.m_internalName;
const char * originalInternalName = internalName.c_str(); const char * originalInternalName = internalName.c_str();
BaseString externalName = impl.m_externalName; BaseString externalName = impl.m_externalName;
const char * originalExternalName = externalName.c_str();
DBUG_ENTER("NdbDictionaryImpl::alterTable"); DBUG_ENTER("NdbDictionaryImpl::alterTable");
if(!get_local_table_info(originalInternalName, false)){ if(!get_local_table_info(originalInternalName, false)){
...@@ -1705,11 +1713,12 @@ void ...@@ -1705,11 +1713,12 @@ void
NdbDictInterface::execCREATE_TABLE_CONF(NdbApiSignal * signal, NdbDictInterface::execCREATE_TABLE_CONF(NdbApiSignal * signal,
LinearSectionPtr ptr[3]) LinearSectionPtr ptr[3])
{ {
#if 0
const CreateTableConf* const conf= const CreateTableConf* const conf=
CAST_CONSTPTR(CreateTableConf, signal->getDataPtr()); CAST_CONSTPTR(CreateTableConf, signal->getDataPtr());
Uint32 tableId= conf->tableId; Uint32 tableId= conf->tableId;
Uint32 tableVersion= conf->tableVersion; Uint32 tableVersion= conf->tableVersion;
#endif
m_waiter.signal(NO_WAIT); m_waiter.signal(NO_WAIT);
} }
......
...@@ -392,3 +392,9 @@ NdbOperation::getTableName() const ...@@ -392,3 +392,9 @@ NdbOperation::getTableName() const
{ {
return m_currentTable->m_externalName.c_str(); return m_currentTable->m_externalName.c_str();
} }
const NdbDictionary::Table*
NdbOperation::getTable() const
{
return m_currentTable;
}
...@@ -230,9 +230,6 @@ NdbOperation::equal_impl(const NdbColumnImpl* tAttrInfo, ...@@ -230,9 +230,6 @@ NdbOperation::equal_impl(const NdbColumnImpl* tAttrInfo,
tErrorLine++; tErrorLine++;
theErrorLine = tErrorLine; theErrorLine = tErrorLine;
if(tDistrKey)
handle_distribution_key((Uint64*)aValue, totalSizeInWords);
if (tNoKeysDef == 0) { if (tNoKeysDef == 0) {
if (tOpType == UpdateRequest) { if (tOpType == UpdateRequest) {
if (tInterpretInd == 1) { if (tInterpretInd == 1) {
......
...@@ -31,13 +31,6 @@ class HugoCalculator { ...@@ -31,13 +31,6 @@ class HugoCalculator {
public: public:
HugoCalculator(const NdbDictionary::Table& tab); HugoCalculator(const NdbDictionary::Table& tab);
Int32 calcValue(int record, int attrib, int updates) const; 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; const char* calcValue(int record, int attrib, int updates, char* buf, int len) const;
int verifyRowValues(NDBT_ResultRow* const pRow) const; int verifyRowValues(NDBT_ResultRow* const pRow) const;
......
...@@ -29,8 +29,9 @@ public: ...@@ -29,8 +29,9 @@ public:
~HugoOperations(); ~HugoOperations();
int startTransaction(Ndb*); int startTransaction(Ndb*);
int setTransaction(NdbTransaction*);
int closeTransaction(Ndb*); int closeTransaction(Ndb*);
NdbConnection* getTransaction(); NdbTransaction* getTransaction();
void refresh(); void refresh();
int pkInsertRecord(Ndb*, int pkInsertRecord(Ndb*,
...@@ -68,10 +69,13 @@ public: ...@@ -68,10 +69,13 @@ public:
int attrId, int attrId,
int rowId, int rowId,
int updateId); int updateId);
int equalForAttr(NdbOperation*, int equalForAttr(NdbOperation*,
int attrId, int attrId,
int rowId); int rowId);
int setValues(NdbOperation*, int rowId, int updateId);
int verifyUpdatesValue(int updatesValue, int _numRows = 0); int verifyUpdatesValue(int updatesValue, int _numRows = 0);
int indexReadRecords(Ndb*, const char * idxName, int recordNo, int indexReadRecords(Ndb*, const char * idxName, int recordNo,
......
...@@ -319,7 +319,50 @@ run_startHint(NDBT_Context* ctx, NDBT_Step* step) ...@@ -319,7 +319,50 @@ run_startHint(NDBT_Context* ctx, NDBT_Step* step)
return NDBT_FAILED; return NDBT_FAILED;
} }
return NDBT_OK; NdbRestarter restarter;
if(restarter.insertErrorInAllNodes(8050) != 0)
return NDBT_FAILED;
HugoCalculator dummy(*tab);
int result = NDBT_OK;
for(int i = 0; i<records && result == NDBT_OK; i++)
{
char buffer[8000];
char* start= buffer + (rand() & 7);
char* pos= start;
for(int j = 0; j<tab->getNoOfColumns(); 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", ...@@ -358,9 +401,18 @@ TESTCASE("ordered_index_dk",
INITIALIZER(run_drop_table); INITIALIZER(run_drop_table);
} }
TESTCASE("startTransactionHint", 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_drop_table);
INITIALIZER(run_create_table); INITIALIZER(run_create_table);
INITIALIZER(run_startHint); INITIALIZER(run_startHint);
......
...@@ -5,8 +5,8 @@ p=`pwd` ...@@ -5,8 +5,8 @@ p=`pwd`
cd $MYSQL_BASE_DIR/mysql-test cd $MYSQL_BASE_DIR/mysql-test
./mysql-test-run --with-ndbcluster --ndb-connectstring=$NDB_CONNECTSTRING $* | tee $p/output.txt ./mysql-test-run --with-ndbcluster --ndb-connectstring=$NDB_CONNECTSTRING $* | tee $p/output.txt
f=`grep -c fail $p/output.txt` f=`grep -c '[ fail ]' $p/output.txt`
o=`grep -c pass $p/output.txt` o=`grep -c '[ pass ]' $p/output.txt`
if [ $o -gt 0 -a $f -eq 0 ] if [ $o -gt 0 -a $f -eq 0 ]
then then
......
...@@ -16,6 +16,7 @@ ...@@ -16,6 +16,7 @@
#include "HugoCalculator.hpp" #include "HugoCalculator.hpp"
#include <NDBT.hpp> #include <NDBT.hpp>
#include <Base64.hpp>
/* ************************************************************* /* *************************************************************
* HugoCalculator * HugoCalculator
...@@ -58,22 +59,11 @@ Int32 ...@@ -58,22 +59,11 @@ Int32
HugoCalculator::calcValue(int record, HugoCalculator::calcValue(int record,
int attrib, int attrib,
int updates) const { 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; return i;
if (attr->getPrimaryKey())
val = record + attrib;
else
val = record + attrib + updates;
return val;
} }
#if 0 #if 0
HugoCalculator::U_Int32 calcValue(int record, int attrib, int updates) const; HugoCalculator::U_Int32 calcValue(int record, int attrib, int updates) const;
...@@ -88,52 +78,100 @@ HugoCalculator::calcValue(int record, ...@@ -88,52 +78,100 @@ HugoCalculator::calcValue(int record,
int updates, int updates,
char* buf, char* buf,
int len) const { int len) const {
const char a[26] = {"UAWBORCTDPEFQGNYHISJMKXLZ"};
const NdbDictionary::Column* attr = m_tab.getColumn(attrib); const NdbDictionary::Column* attr = m_tab.getColumn(attrib);
int val = calcValue(record, attrib, updates); Uint32 val;
do
if (attr->getPrimaryKey()){ {
// Create a string where val is printed as chars in the beginning if (attrib == m_idCol)
// of the string, then fill with other chars {
// The string length is set to the same size as the attribute *((Uint32*)buf)= record;
BaseString::snprintf(buf, len, "%d", val); return buf;
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 // If this is the update column
// anomalies in the area that we don't fill with chars if (attrib == m_updatesCol)
int i; {
for (i = 0; i<len; i++) *((Uint32*)buf)= updates;
buf[i] = ((i+2) % 255); return buf;
}
// Calculate length of the string to create. We want the string if (attr->getPrimaryKey())
// length to be varied between max and min of this attribute. {
if(attr->getType() == NdbDictionary::Column::Varchar) srand(record + attrib + updates);
len = val % (len + 1); val = (record + attrib);
}
else else
if((val % (len + 1)) == 0) {
len = 0; srand(record + attrib + updates);
val = rand();
}
} while (0);
// If len == 0 return NULL if this is a nullable attribute if(attr->getNullable() && (((val >> 16) & 255) > 220))
if (len == 0){
if(attr->getNullable() == true)
return NULL; return NULL;
else
len++; memcpy(buf, &val, (len > 4 ? 4 : len));
int pos= 4;
while(pos + 4 < len)
{
val= rand();
memcpy(buf+pos, &val, 4);
pos++;
} }
for(i=0; i < len; i++)
buf[i] = a[((val^i)%25)];
buf[len] = 0;
if(attr->getType() == NdbDictionary::Column::Bit) 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 bits= attr->getLength();
Uint32 pos = bits >> 5; Uint32 tmp = bits >> 5;
Uint32 size = bits & 31; Uint32 size = bits & 31;
((Uint32*)buf)[pos] &= ((1 << size) - 1); ((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; return buf;
} }
...@@ -148,17 +186,9 @@ HugoCalculator::verifyRowValues(NDBT_ResultRow* const pRow) const{ ...@@ -148,17 +186,9 @@ HugoCalculator::verifyRowValues(NDBT_ResultRow* const pRow) const{
// Check the values of each column // Check the values of each column
for (int i = 0; i<m_tab.getNoOfColumns(); i++){ for (int i = 0; i<m_tab.getNoOfColumns(); i++){
if (i != m_updatesCol && id != m_idCol) { if (i != m_updatesCol && id != m_idCol) {
const NdbDictionary::Column* attr = m_tab.getColumn(i); const NdbDictionary::Column* attr = m_tab.getColumn(i);
Uint32 len = attr->getLength(); Uint32 len = attr->getSizeInBytes();
switch (attr->getType()){ char buf[8000];
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); const char* res = calcValue(id, i, updates, buf, len);
if (res == NULL){ if (res == NULL){
if (!pRow->attributeStore(i)->isNULL()){ if (!pRow->attributeStore(i)->isNULL()){
...@@ -191,51 +221,6 @@ HugoCalculator::verifyRowValues(NDBT_ResultRow* const pRow) const{ ...@@ -191,51 +221,6 @@ HugoCalculator::verifyRowValues(NDBT_ResultRow* const pRow) const{
result = -1; 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 << "|- 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;
}
} }
} }
return result; return result;
......
...@@ -32,6 +32,19 @@ int HugoOperations::startTransaction(Ndb* pNdb){ ...@@ -32,6 +32,19 @@ int HugoOperations::startTransaction(Ndb* pNdb){
return NDBT_OK; 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){ int HugoOperations::closeTransaction(Ndb* pNdb){
if (pTrans != NULL){ if (pTrans != NULL){
...@@ -145,26 +158,33 @@ int HugoOperations::pkUpdateRecord(Ndb* pNdb, ...@@ -145,26 +158,33 @@ int HugoOperations::pkUpdateRecord(Ndb* pNdb,
return NDBT_FAILED; return NDBT_FAILED;
} }
// Define primary keys if(setValues(pOp, r+recordNo, updatesValue) != NDBT_OK)
for(a = 0; a<tab.getNoOfColumns(); a++){ {
if (tab.getColumn(a)->getPrimaryKey() == true){
if(equalForAttr(pOp, a, r+recordNo) != 0){
ERR(pTrans->getNdbError());
return NDBT_FAILED; return NDBT_FAILED;
} }
} }
} return NDBT_OK;
}
// Define attributes to update int
HugoOperations::setValues(NdbOperation* pOp, int rowId, int updateId)
{
// Define primary keys
int a;
for(a = 0; a<tab.getNoOfColumns(); a++){ for(a = 0; a<tab.getNoOfColumns(); a++){
if (tab.getColumn(a)->getPrimaryKey() == false){ if (tab.getColumn(a)->getPrimaryKey() == true){
if(setValueForAttr(pOp, a, recordNo+r, updatesValue ) != 0){ if(equalForAttr(pOp, a, rowId) != 0){
ERR(pTrans->getNdbError()); ERR(pTrans->getNdbError());
return NDBT_FAILED; return NDBT_FAILED;
} }
} else {
if(setValueForAttr(pOp, a, rowId, updateId ) != 0){
ERR(pTrans->getNdbError());
return NDBT_FAILED;
} }
} }
} }
return NDBT_OK; return NDBT_OK;
} }
...@@ -187,26 +207,11 @@ int HugoOperations::pkInsertRecord(Ndb* pNdb, ...@@ -187,26 +207,11 @@ int HugoOperations::pkInsertRecord(Ndb* pNdb,
return NDBT_FAILED; return NDBT_FAILED;
} }
// Define primary keys if(setValues(pOp, r+recordNo, updatesValue) != NDBT_OK)
for(a = 0; a<tab.getNoOfColumns(); a++){ {
if (tab.getColumn(a)->getPrimaryKey() == true){
if(equalForAttr(pOp, a, r+recordNo) != 0){
ERR(pTrans->getNdbError());
return NDBT_FAILED;
}
}
}
// Define attributes to update
for(a = 0; a<tab.getNoOfColumns(); a++){
if (tab.getColumn(a)->getPrimaryKey() == false){
if(setValueForAttr(pOp, a, recordNo+r, updatesValue ) != 0){
ERR(pTrans->getNdbError());
return NDBT_FAILED; return NDBT_FAILED;
} }
} }
}
}
return NDBT_OK; return NDBT_OK;
} }
...@@ -373,38 +378,11 @@ int HugoOperations::equalForAttr(NdbOperation* pOp, ...@@ -373,38 +378,11 @@ int HugoOperations::equalForAttr(NdbOperation* pOp,
return NDBT_FAILED; return NDBT_FAILED;
} }
int len = attr->getLength(); int len = attr->getSizeInBytes();
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]; char buf[8000];
memset(buf, 0, sizeof(buf)); memset(buf, 0, sizeof(buf));
check = pOp->equal( attr->getName(), return pOp->equal( attr->getName(),
calc.calcValue(rowId, attrId, 0, buf, len)); 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 HugoOperations::setValueForAttr(NdbOperation* pOp, int HugoOperations::setValueForAttr(NdbOperation* pOp,
...@@ -414,47 +392,11 @@ int HugoOperations::setValueForAttr(NdbOperation* pOp, ...@@ -414,47 +392,11 @@ int HugoOperations::setValueForAttr(NdbOperation* pOp,
int check = -1; int check = -1;
const NdbDictionary::Column* attr = tab.getColumn(attrId); const NdbDictionary::Column* attr = tab.getColumn(attrId);
int len = attr->getLength(); int len = attr->getSizeInBytes();
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]; char buf[8000];
check = pOp->setValue( attr->getName(), memset(buf, 0, sizeof(buf));
return pOp->setValue( attr->getName(),
calc.calcValue(rowId, attrId, updateId, buf, len)); 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 int
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment