ndb - bug#19537: arithmetic conversion Uint64 reg to Uint32 attr
This commit is contained in:
parent
9326f67dda
commit
da44e731cc
@ -1494,6 +1494,7 @@ int Dbtup::interpreterNextLab(Signal* signal,
|
||||
// word read. Thus we set the register to be a 32 bit register.
|
||||
/* ------------------------------------------------------------- */
|
||||
TregMemBuffer[theRegister] = 0x50;
|
||||
// arithmetic conversion if big-endian
|
||||
* (Int64*)(TregMemBuffer+theRegister+2) = TregMemBuffer[theRegister+1];
|
||||
} else if (TnoDataRW == 3) {
|
||||
/* ------------------------------------------------------------- */
|
||||
@ -1557,6 +1558,11 @@ int Dbtup::interpreterNextLab(Signal* signal,
|
||||
Tlen = TattrNoOfWords + 1;
|
||||
if (Toptype == ZUPDATE) {
|
||||
if (TattrNoOfWords <= 2) {
|
||||
if (TattrNoOfWords == 1) {
|
||||
// arithmetic conversion if big-endian
|
||||
TdataForUpdate[1] = *(Int64*)&TregMemBuffer[theRegister + 2];
|
||||
TdataForUpdate[2] = 0;
|
||||
}
|
||||
if (TregType == 0) {
|
||||
/* --------------------------------------------------------- */
|
||||
// Write a NULL value into the attribute
|
||||
|
@ -24,6 +24,7 @@ testOIBasic \
|
||||
testOperations \
|
||||
testRestartGci \
|
||||
testScan \
|
||||
testInterpreter \
|
||||
testScanInterpreter \
|
||||
testScanPerf \
|
||||
testSystemRestart \
|
||||
@ -61,6 +62,7 @@ testOIBasic_SOURCES = testOIBasic.cpp
|
||||
testOperations_SOURCES = testOperations.cpp
|
||||
testRestartGci_SOURCES = testRestartGci.cpp
|
||||
testScan_SOURCES = testScan.cpp ScanFunctions.hpp
|
||||
testInterpreter_SOURCES = testInterpreter.cpp
|
||||
testScanInterpreter_SOURCES = testScanInterpreter.cpp ScanFilter.hpp ScanInterpretTest.hpp
|
||||
testScanPerf_SOURCES = testScanPerf.cpp
|
||||
testSystemRestart_SOURCES = testSystemRestart.cpp
|
||||
@ -152,3 +154,4 @@ testScan.dsp: Makefile \
|
||||
@$(top_srcdir)/ndb/config/win-includes $@ $(INCLUDES)
|
||||
@$(top_srcdir)/ndb/config/win-sources $@ $(testScan_SOURCES)
|
||||
@$(top_srcdir)/ndb/config/win-libraries $@ LINK $(LDADD)
|
||||
|
||||
|
@ -79,46 +79,46 @@ int runTestIncValue32(NDBT_Context* ctx, NDBT_Step* step){
|
||||
Ndb* pNdb = GETNDB(step);
|
||||
|
||||
|
||||
NdbConnection* pTrans = pNdb->startTransaction();
|
||||
if (pTrans == NULL){
|
||||
ERR(pNdb->getNdbError());
|
||||
return NDBT_FAILED;
|
||||
}
|
||||
|
||||
NdbOperation* pOp = pTrans->getNdbOperation(pTab->getName());
|
||||
if (pOp == NULL) {
|
||||
ERR(pTrans->getNdbError());
|
||||
pNdb->closeTransaction(pTrans);
|
||||
return NDBT_FAILED;
|
||||
}
|
||||
|
||||
int check = pOp->interpretedUpdateTuple();
|
||||
if( check == -1 ) {
|
||||
ERR(pTrans->getNdbError());
|
||||
pNdb->closeTransaction(pTrans);
|
||||
return NDBT_FAILED;
|
||||
}
|
||||
|
||||
|
||||
// Primary keys
|
||||
Uint32 pkVal = 1;
|
||||
check = pOp->equal("KOL1", pkVal );
|
||||
if( check == -1 ) {
|
||||
ERR(pTrans->getNdbError());
|
||||
pNdb->closeTransaction(pTrans);
|
||||
return NDBT_FAILED;
|
||||
}
|
||||
|
||||
// Attributes
|
||||
|
||||
// Update column
|
||||
Uint32 valToIncWith = 1;
|
||||
check = pOp->incValue("KOL2", valToIncWith);
|
||||
if( check == -1 ) {
|
||||
ERR(pTrans->getNdbError());
|
||||
pNdb->closeTransaction(pTrans);
|
||||
return NDBT_FAILED;
|
||||
}
|
||||
NdbConnection* pTrans = pNdb->startTransaction();
|
||||
if (pTrans == NULL){
|
||||
ERR(pNdb->getNdbError());
|
||||
return NDBT_FAILED;
|
||||
}
|
||||
|
||||
NdbOperation* pOp = pTrans->getNdbOperation(pTab->getName());
|
||||
if (pOp == NULL) {
|
||||
ERR(pTrans->getNdbError());
|
||||
pNdb->closeTransaction(pTrans);
|
||||
return NDBT_FAILED;
|
||||
}
|
||||
|
||||
int check = pOp->interpretedUpdateTuple();
|
||||
if( check == -1 ) {
|
||||
ERR(pTrans->getNdbError());
|
||||
pNdb->closeTransaction(pTrans);
|
||||
return NDBT_FAILED;
|
||||
}
|
||||
|
||||
|
||||
// Primary keys
|
||||
Uint32 pkVal = 1;
|
||||
check = pOp->equal("KOL1", pkVal );
|
||||
if( check == -1 ) {
|
||||
ERR(pTrans->getNdbError());
|
||||
pNdb->closeTransaction(pTrans);
|
||||
return NDBT_FAILED;
|
||||
}
|
||||
|
||||
// Attributes
|
||||
|
||||
// Update column
|
||||
Uint32 valToIncWith = 1;
|
||||
check = pOp->incValue("KOL2", valToIncWith);
|
||||
if( check == -1 ) {
|
||||
ERR(pTrans->getNdbError());
|
||||
pNdb->closeTransaction(pTrans);
|
||||
return NDBT_FAILED;
|
||||
}
|
||||
|
||||
NdbRecAttr* valueRec = pOp->getValue("KOL2");
|
||||
if( valueRec == NULL ) {
|
||||
@ -142,6 +142,122 @@ int runTestIncValue32(NDBT_Context* ctx, NDBT_Step* step){
|
||||
return NDBT_OK;
|
||||
}
|
||||
|
||||
int runTestBug19537(NDBT_Context* ctx, NDBT_Step* step){
|
||||
int result = NDBT_OK;
|
||||
const NdbDictionary::Table * pTab = ctx->getTab();
|
||||
Ndb* pNdb = GETNDB(step);
|
||||
|
||||
if (strcmp(pTab->getName(), "T1") != 0) {
|
||||
g_err << "runTestBug19537: skip, table != T1" << endl;
|
||||
return NDBT_OK;
|
||||
}
|
||||
|
||||
|
||||
NdbConnection* pTrans = pNdb->startTransaction();
|
||||
if (pTrans == NULL){
|
||||
ERR(pNdb->getNdbError());
|
||||
return NDBT_FAILED;
|
||||
}
|
||||
|
||||
NdbOperation* pOp = pTrans->getNdbOperation(pTab->getName());
|
||||
if (pOp == NULL) {
|
||||
ERR(pTrans->getNdbError());
|
||||
pNdb->closeTransaction(pTrans);
|
||||
return NDBT_FAILED;
|
||||
}
|
||||
|
||||
if (pOp->interpretedUpdateTuple() == -1) {
|
||||
ERR(pOp->getNdbError());
|
||||
pNdb->closeTransaction(pTrans);
|
||||
return NDBT_FAILED;
|
||||
}
|
||||
|
||||
|
||||
// Primary keys
|
||||
const Uint32 pkVal = 1;
|
||||
if (pOp->equal("KOL1", pkVal) == -1) {
|
||||
ERR(pTrans->getNdbError());
|
||||
pNdb->closeTransaction(pTrans);
|
||||
return NDBT_FAILED;
|
||||
}
|
||||
|
||||
// Load 64-bit constant into register 1 and
|
||||
// write from register 1 to 32-bit column KOL2
|
||||
const Uint64 reg_val = 0x0102030405060708ULL;
|
||||
|
||||
const Uint32* reg_ptr32 = (const Uint32*)®_val;
|
||||
if (reg_ptr32[0] == 0x05060708 && reg_ptr32[1] == 0x01020304) {
|
||||
g_err << "runTestBug19537: platform is LITTLE endian" << endl;
|
||||
} else if (reg_ptr32[0] == 0x01020304 && reg_ptr32[1] == 0x05060708) {
|
||||
g_err << "runTestBug19537: platform is BIG endian" << endl;
|
||||
} else {
|
||||
g_err << "runTestBug19537: impossible platform"
|
||||
<< hex << " [0]=" << reg_ptr32[0] << " [1]=" <<reg_ptr32[1] << endl;
|
||||
pNdb->closeTransaction(pTrans);
|
||||
return NDBT_FAILED;
|
||||
}
|
||||
|
||||
if (pOp->load_const_u64(1, reg_val) == -1 ||
|
||||
pOp->write_attr("KOL2", 1) == -1) {
|
||||
ERR(pOp->getNdbError());
|
||||
pNdb->closeTransaction(pTrans);
|
||||
return NDBT_FAILED;
|
||||
}
|
||||
|
||||
if (pTrans->execute(Commit) == -1) {
|
||||
ERR(pTrans->getNdbError());
|
||||
pNdb->closeTransaction(pTrans);
|
||||
return NDBT_FAILED;
|
||||
}
|
||||
|
||||
// Read value via a new transaction
|
||||
|
||||
pTrans = pNdb->startTransaction();
|
||||
if (pTrans == NULL){
|
||||
ERR(pNdb->getNdbError());
|
||||
return NDBT_FAILED;
|
||||
}
|
||||
|
||||
pOp = pTrans->getNdbOperation(pTab->getName());
|
||||
if (pOp == NULL) {
|
||||
ERR(pTrans->getNdbError());
|
||||
pNdb->closeTransaction(pTrans);
|
||||
return NDBT_FAILED;
|
||||
}
|
||||
|
||||
Uint32 kol2 = 0x09090909;
|
||||
if (pOp->readTuple() == -1 ||
|
||||
pOp->equal("KOL1", pkVal) == -1 ||
|
||||
pOp->getValue("KOL2", (char*)&kol2) == 0) {
|
||||
ERR(pOp->getNdbError());
|
||||
pNdb->closeTransaction(pTrans);
|
||||
return NDBT_FAILED;
|
||||
}
|
||||
|
||||
if (pTrans->execute(Commit) == -1) {
|
||||
ERR(pTrans->getNdbError());
|
||||
pNdb->closeTransaction(pTrans);
|
||||
return NDBT_FAILED;
|
||||
}
|
||||
|
||||
// Expected conversion as in C - truncate to lower (logical) word
|
||||
|
||||
if (kol2 == 0x01020304) {
|
||||
g_err << "runTestBug19537: the bug manifests itself !" << endl;
|
||||
pNdb->closeTransaction(pTrans);
|
||||
return NDBT_FAILED;
|
||||
}
|
||||
|
||||
if (kol2 != 0x05060708) {
|
||||
g_err << "runTestBug19537: impossible KOL2 " << hex << kol2 << endl;
|
||||
pNdb->closeTransaction(pTrans);
|
||||
return NDBT_FAILED;
|
||||
}
|
||||
|
||||
pNdb->closeTransaction(pTrans);
|
||||
return NDBT_OK;
|
||||
}
|
||||
|
||||
|
||||
NDBT_TESTSUITE(testInterpreter);
|
||||
TESTCASE("IncValue32",
|
||||
@ -156,6 +272,12 @@ TESTCASE("IncValue64",
|
||||
INITIALIZER(runTestIncValue64);
|
||||
FINALIZER(runClearTable);
|
||||
}
|
||||
TESTCASE("Bug19537",
|
||||
"Test big-endian write_attr of 32 bit integer\n"){
|
||||
INITIALIZER(runLoadTable);
|
||||
INITIALIZER(runTestBug19537);
|
||||
FINALIZER(runClearTable);
|
||||
}
|
||||
#if 0
|
||||
TESTCASE("MaxTransactions",
|
||||
"Start transactions until no more can be created\n"){
|
||||
|
Loading…
x
Reference in New Issue
Block a user