Commit ce7a7b20 authored by unknown's avatar unknown
Browse files

ndb - bug#19537: arithmetic conversion Uint64 reg to Uint32 attr


ndb/test/ndbapi/Makefile.am:
  enable testInterpreter
ndb/test/ndbapi/testInterpreter.cpp:
  add test case Bug19537
  the bug fix also fixed IncValue64 for whatever reason..
ndb/src/kernel/blocks/dbtup/DbtupExecQuery.cpp:
  bug#19537: write_attr: perform arithmetic conversion Uint64 to Uint32
parent 774fae9c
Loading
Loading
Loading
Loading
+6 −0
Original line number Diff line number Diff line
@@ -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
+3 −0
Original line number Diff line number Diff line
@@ -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)
+162 −40
Original line number Diff line number Diff line
@@ -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*)&reg_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"){