mirror of
https://github.com/MariaDB/server.git
synced 2025-07-30 16:24:05 +03:00
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
This commit is contained in:
@ -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:
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
@ -21,6 +21,7 @@
|
||||
#include <BaseString.hpp>
|
||||
|
||||
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);
|
||||
|
||||
|
@ -22,11 +22,16 @@ 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;
|
||||
|
@ -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:
|
||||
---------------
|
||||
|
||||
|
@ -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.
|
||||
/*----------------------------------------------------------------------*/
|
||||
|
@ -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 >*/
|
||||
/* ***************>*/
|
||||
|
@ -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; i<getNoOfColumns(); i++){
|
||||
const NdbDictionary::Column * c = getColumn(i);
|
||||
const NdbColumnImpl & col = NdbColumnImpl::getImpl(* c);
|
||||
sz += (((col.m_attrSize * col.m_arraySize) + 3) / 4);
|
||||
sz += (c->getSizeInBytes()+ 3) / 4;
|
||||
}
|
||||
return sz * 4;
|
||||
}
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
|
@ -392,3 +392,9 @@ NdbOperation::getTableName() const
|
||||
{
|
||||
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,
|
||||
tErrorLine++;
|
||||
theErrorLine = tErrorLine;
|
||||
|
||||
if(tDistrKey)
|
||||
handle_distribution_key((Uint64*)aValue, totalSizeInWords);
|
||||
|
||||
if (tNoKeysDef == 0) {
|
||||
if (tOpType == UpdateRequest) {
|
||||
if (tInterpretInd == 1) {
|
||||
|
@ -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;
|
||||
|
@ -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,
|
||||
|
@ -319,7 +319,50 @@ run_startHint(NDBT_Context* ctx, NDBT_Step* step)
|
||||
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",
|
||||
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);
|
||||
|
@ -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
|
||||
|
@ -16,6 +16,7 @@
|
||||
|
||||
#include "HugoCalculator.hpp"
|
||||
#include <NDBT.hpp>
|
||||
#include <Base64.hpp>
|
||||
|
||||
/* *************************************************************
|
||||
* 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; i<len; i++)
|
||||
buf[i] = ((i+2) % 255);
|
||||
|
||||
// Calculate length of the string to create. We want the string
|
||||
// length to be varied between max and min of this attribute.
|
||||
if(attr->getType() == 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++;
|
||||
Uint32 val;
|
||||
do
|
||||
{
|
||||
if (attrib == m_idCol)
|
||||
{
|
||||
*((Uint32*)buf)= record;
|
||||
return buf;
|
||||
}
|
||||
for(i=0; i < len; i++)
|
||||
buf[i] = a[((val^i)%25)];
|
||||
buf[len] = 0;
|
||||
|
||||
if(attr->getType() == NdbDictionary::Column::Bit)
|
||||
// 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 pos = bits >> 5;
|
||||
Uint32 tmp = bits >> 5;
|
||||
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;
|
||||
}
|
||||
|
||||
@ -148,17 +186,9 @@ HugoCalculator::verifyRowValues(NDBT_ResultRow* const pRow) const{
|
||||
// Check the values of each column
|
||||
for (int i = 0; i<m_tab.getNoOfColumns(); i++){
|
||||
if (i != m_updatesCol && id != m_idCol) {
|
||||
|
||||
const NdbDictionary::Column* attr = m_tab.getColumn(i);
|
||||
Uint32 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 = new char[len+1];
|
||||
Uint32 len = attr->getSizeInBytes();
|
||||
char buf[8000];
|
||||
const char* res = calcValue(id, i, updates, buf, len);
|
||||
if (res == NULL){
|
||||
if (!pRow->attributeStore(i)->isNULL()){
|
||||
@ -191,51 +221,6 @@ HugoCalculator::verifyRowValues(NDBT_ResultRow* const pRow) const{
|
||||
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;
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
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; a<tab.getNoOfColumns(); a++){
|
||||
if (tab.getColumn(a)->getPrimaryKey() == true){
|
||||
if(equalForAttr(pOp, a, r+recordNo) != 0){
|
||||
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; 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_OK;
|
||||
}
|
||||
|
||||
@ -187,26 +207,11 @@ int HugoOperations::pkInsertRecord(Ndb* pNdb,
|
||||
return NDBT_FAILED;
|
||||
}
|
||||
|
||||
// Define primary keys
|
||||
for(a = 0; a<tab.getNoOfColumns(); a++){
|
||||
if (tab.getColumn(a)->getPrimaryKey() == true){
|
||||
if(equalForAttr(pOp, a, r+recordNo) != 0){
|
||||
ERR(pTrans->getNdbError());
|
||||
if(setValues(pOp, r+recordNo, updatesValue) != NDBT_OK)
|
||||
{
|
||||
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_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:{
|
||||
int len = attr->getSizeInBytes();
|
||||
char buf[8000];
|
||||
memset(buf, 0, sizeof(buf));
|
||||
check = pOp->equal( attr->getName(),
|
||||
return 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 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:{
|
||||
int len = attr->getSizeInBytes();
|
||||
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));
|
||||
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
|
||||
|
Reference in New Issue
Block a user