Exemple #1
0
int 
UtilTransactions::selectCount(Ndb* pNdb, 
			      int parallelism,
			      int* count_rows,
			      NdbOperation::LockMode lm,
			      NdbConnection* pTrans){
  
  int                  retryAttempt = 0;
  const int            retryMax = 100;
  int                  check;
  NdbScanOperation     *pOp;

  if(!pTrans)
    pTrans = pNdb->startTransaction();
    
  while (true){

    if (retryAttempt >= retryMax){
      g_info << "ERROR: has retried this operation " << retryAttempt 
	     << " times, failing!" << endl;
      return NDBT_FAILED;
    }
    pOp = getScanOperation(pTrans);
    if (pOp == NULL) {
      ERR(pTrans->getNdbError());
      closeTransaction(pNdb);
      return NDBT_FAILED;
    }

    if( pOp->readTuples(lm) ) {
      ERR(pTrans->getNdbError());
      closeTransaction(pNdb);
      return NDBT_FAILED;
    }

    if(0){
      NdbScanFilter sf(pOp);
      sf.begin(NdbScanFilter::OR);
      sf.eq(2, (Uint32)30);
      sf.end();
    } else {
      check = pOp->interpret_exit_ok();
      if( check == -1 ) {
	ERR(pTrans->getNdbError());
	closeTransaction(pNdb);
	return NDBT_FAILED;
      }
    }
    
    
    check = pTrans->execute(NoCommit, AbortOnError);
    if( check == -1 ) {
      ERR(pTrans->getNdbError());
      closeTransaction(pNdb);
      return NDBT_FAILED;
    }

    int eof;
    int rows = 0;
    

    while((eof = pOp->nextResult()) == 0){
      rows++;
    }
    if (eof == -1) {
      const NdbError err = pTrans->getNdbError();
      
      if (err.status == NdbError::TemporaryError){
	closeTransaction(pNdb);
	NdbSleep_MilliSleep(50);
	retryAttempt++;
	continue;
      }
      ERR(err);
      closeTransaction(pNdb);
      return NDBT_FAILED;
    }
    
    closeTransaction(pNdb);
    
    if (count_rows != NULL){
      *count_rows = rows;
    }
    
    return NDBT_OK;
  }
  return NDBT_FAILED;
}
Exemple #2
0
int 
UtilTransactions::scanAndCompareUniqueIndex(Ndb* pNdb,
					    const NdbDictionary::Index* pIndex,
					    int parallelism,
					    bool transactional){
  
  int                  retryAttempt = 0;
  const int            retryMax = 100;
  int                  check;
  NdbScanOperation       *pOp;
  NDBT_ResultRow       row(tab);

  parallelism = 1;

  while (true){
restart:
    if (retryAttempt >= retryMax){
      g_info << "ERROR: has retried this operation " << retryAttempt 
	     << " times, failing!" << endl;
      return NDBT_FAILED;
    }

    pTrans = pNdb->startTransaction();
    if (pTrans == NULL) {
      const NdbError err = pNdb->getNdbError();

      if (err.status == NdbError::TemporaryError){
	ERR(err);
	NdbSleep_MilliSleep(50);
	retryAttempt++;
	continue;
      }
      ERR(err);
      return NDBT_FAILED;
    }

    pOp = pTrans->getNdbScanOperation(tab.getName());	
    if (pOp == NULL) {
      const NdbError err = pNdb->getNdbError();
      closeTransaction(pNdb);
      ERR(err);
      
      if (err.status == NdbError::TemporaryError){
	NdbSleep_MilliSleep(50);
	retryAttempt++;
	continue;
      }
      return NDBT_FAILED;
    }

    int rs;
    if(transactional){
      rs = pOp->readTuples(NdbScanOperation::LM_Read, 0, parallelism);
    } else {
      rs = pOp->readTuples(NdbScanOperation::LM_CommittedRead, 0, parallelism);
    }
    
    if( rs != 0 ) {
      ERR(pTrans->getNdbError());
      closeTransaction(pNdb);
      return NDBT_FAILED;
    }

    check = pOp->interpret_exit_ok();
    if( check == -1 ) {
      ERR(pTrans->getNdbError());
      closeTransaction(pNdb);
      return NDBT_FAILED;
    }

    // Read all attributes
    for (int a = 0; a < tab.getNoOfColumns(); a++){
      if ((row.attributeStore(a) =  
	   pOp->getValue(tab.getColumn(a)->getName())) == 0) {
	ERR(pTrans->getNdbError());
	closeTransaction(pNdb);
	return NDBT_FAILED;
      }
    }

    check = pTrans->execute(NoCommit, AbortOnError);
    if( check == -1 ) {
      const NdbError err = pTrans->getNdbError();
      
      if (err.status == NdbError::TemporaryError){
	ERR(err);
	closeTransaction(pNdb);
	NdbSleep_MilliSleep(50);
	retryAttempt++;
	continue;
      }
      ERR(err);
      closeTransaction(pNdb);
      return NDBT_FAILED;
    }
    
    int eof;
    int rows = 0;
    
    
    while((eof = pOp->nextResult()) == 0){
      rows++;
      
      // ndbout << row.c_str().c_str() << endl;
      
      if (readRowFromTableAndIndex(pNdb,
				   pTrans,
				   pIndex,
				   row) != NDBT_OK){	
	
	while((eof= pOp->nextResult(false)) == 0);
	if(eof == 2)
	  eof = pOp->nextResult(true); // this should give -1
	if(eof == -1)
	{
	  const NdbError err = pTrans->getNdbError();
	  
	  if (err.status == NdbError::TemporaryError){
	    ERR(err);
	    closeTransaction(pNdb);
	    NdbSleep_MilliSleep(50);
	    retryAttempt++;
	    goto restart;
	  }
	}
	closeTransaction(pNdb);
	return NDBT_FAILED;
      }
    }
    if (eof == -1) {
      const NdbError err = pTrans->getNdbError();
      
      if (err.status == NdbError::TemporaryError){
	ERR(err);
	closeTransaction(pNdb);
	NdbSleep_MilliSleep(50);
	retryAttempt++;
	continue;
      }
      ERR(err);
      closeTransaction(pNdb);
      return NDBT_FAILED;
    }
    
    closeTransaction(pNdb);
    
    return NDBT_OK;
  }
  return NDBT_FAILED;
}
Exemple #3
0
int 
UtilTransactions::copyTableData(Ndb* pNdb,
			    const char* destName){
  // Scan all records and copy 
  // them to destName table
  int                  retryAttempt = 0;
  const int            retryMax = 10;
  int insertedRows = 0;
  int parallelism = 240;
  int check;
  NdbScanOperation		*pOp;
  NDBT_ResultRow       row(tab);
  
  while (true){
    
    if (retryAttempt >= retryMax){
      g_info << "ERROR: has retried this operation " << retryAttempt 
	     << " times, failing!" << endl;
      return NDBT_FAILED;
    }


    pTrans = pNdb->startTransaction();
    if (pTrans == NULL) {
      const NdbError err = pNdb->getNdbError();

      if (err.status == NdbError::TemporaryError){
	ERR(err);
	NdbSleep_MilliSleep(50);
	retryAttempt++;
	continue;
      }
      ERR(err);
      return NDBT_FAILED;
    }

    pOp = pTrans->getNdbScanOperation(tab.getName());	
    if (pOp == NULL) {
      ERR(pTrans->getNdbError());
      closeTransaction(pNdb);
      return NDBT_FAILED;
    }

    if( pOp->readTuples(NdbScanOperation::LM_Read, parallelism) ) {
      ERR(pTrans->getNdbError());
      closeTransaction(pNdb);
      return NDBT_FAILED;
    }

    check = pOp->interpret_exit_ok();
    if( check == -1 ) {
      ERR(pTrans->getNdbError());
      closeTransaction(pNdb);
      return NDBT_FAILED;
    }  

    // Read all attributes
    for (int a = 0; a < tab.getNoOfColumns(); a++){
      if ((row.attributeStore(a) =  
	   pOp->getValue(tab.getColumn(a)->getName())) == 0) {
	ERR(pTrans->getNdbError());
	closeTransaction(pNdb);
	return NDBT_FAILED;
      }
    }
    
    check = pTrans->execute(NoCommit, AbortOnError);
    if( check == -1 ) {
      ERR(pTrans->getNdbError());
      closeTransaction(pNdb);
      return NDBT_FAILED;
    }
  
    int eof;
    while((eof = pOp->nextResult(true)) == 0){
      do {
	insertedRows++;
	if (addRowToInsert(pNdb, pTrans, row, destName) != 0){
	  closeTransaction(pNdb);
	  return NDBT_FAILED;
	}
      } while((eof = pOp->nextResult(false)) == 0);
      
      check = pTrans->execute(Commit, AbortOnError);   
      pTrans->restart();
      if( check == -1 ) {
	const NdbError err = pTrans->getNdbError();    
	ERR(err);
	closeTransaction(pNdb);
	return NDBT_FAILED;
      }
    }  
    if (eof == -1) {
      const NdbError err = pTrans->getNdbError();
      
      if (err.status == NdbError::TemporaryError){
	ERR(err);
	closeTransaction(pNdb);
	NdbSleep_MilliSleep(50);
	// If error = 488 there should be no limit on number of retry attempts
	if (err.code != 488) 
	  retryAttempt++;
	continue;
      }
      ERR(err);
      closeTransaction(pNdb);
      return NDBT_FAILED;
    }
    
    closeTransaction(pNdb);
    
    g_info << insertedRows << " rows copied" << endl;
    
    return NDBT_OK;
  }
  return NDBT_FAILED;
}
Exemple #4
0
int 
UtilTransactions::scanReadRecords(Ndb* pNdb,
				  int parallelism,
				  NdbOperation::LockMode lm,
				  int records,
				  int noAttribs,
				  int *attrib_list,
				  ReadCallBackFn* fn){
  
  int                  retryAttempt = 0;
  const int            retryMax = 100;
  int                  check;
  NdbScanOperation	       *pOp;
  NDBT_ResultRow       row(tab);

  while (true){

    if (retryAttempt >= retryMax){
      g_info << "ERROR: has retried this operation " << retryAttempt 
	     << " times, failing!" << endl;
      return NDBT_FAILED;
    }

    pTrans = pNdb->startTransaction();
    if (pTrans == NULL) {
      const NdbError err = pNdb->getNdbError();

      if (err.status == NdbError::TemporaryError){
	ERR(err);
	NdbSleep_MilliSleep(50);
	retryAttempt++;
	continue;
      }
      ERR(err);
      return NDBT_FAILED;
    }

    pOp = getScanOperation(pTrans);
    if (pOp == NULL) {
      const NdbError err = pNdb->getNdbError();
      closeTransaction(pNdb);

      if (err.status == NdbError::TemporaryError){
	ERR(err);
	NdbSleep_MilliSleep(50);
	retryAttempt++;
	continue;
      }
      ERR(err);
      return NDBT_FAILED;
    }

    if( pOp->readTuples(lm, 0, parallelism) ) {
      ERR(pTrans->getNdbError());
      closeTransaction(pNdb);
      return NDBT_FAILED;
    }

    check = pOp->interpret_exit_ok();
    if( check == -1 ) {
      ERR(pTrans->getNdbError());
      closeTransaction(pNdb);
      return NDBT_FAILED;
    }
    
    // Call getValue for all the attributes supplied in attrib_list
    // ************************************************
    for (int a = 0; a < noAttribs; a++){
      if (attrib_list[a] < tab.getNoOfColumns()){ 
	g_info << "getValue(" << attrib_list[a] << ")" << endl;
	if ((row.attributeStore(attrib_list[a]) =  
	     pOp->getValue(tab.getColumn(attrib_list[a])->getName())) == 0) {
	  ERR(pTrans->getNdbError());
	  closeTransaction(pNdb);
	  return NDBT_FAILED;
	}
      }
    }
    // *************************************************
    
    check = pTrans->execute(NoCommit, AbortOnError);
    if( check == -1 ) {
      const NdbError err = pTrans->getNdbError();

      if (err.status == NdbError::TemporaryError){
	ERR(err);
	closeTransaction(pNdb);
	NdbSleep_MilliSleep(50);
	retryAttempt++;
	continue;
      }
      ERR(err);
      closeTransaction(pNdb);
      return NDBT_FAILED;
    }
    
    int eof;
    int rows = 0;
    
    
    while((eof = pOp->nextResult()) == 0){
      rows++;
      
      // Call callback for each record returned
      if(fn != NULL)
	fn(&row);
    }
    if (eof == -1) {
      const NdbError err = pTrans->getNdbError();
      
      if (err.status == NdbError::TemporaryError){
	ERR(err);
	closeTransaction(pNdb);
	NdbSleep_MilliSleep(50);
	retryAttempt++;
	continue;
      }
      ERR(err);
      closeTransaction(pNdb);
      return NDBT_FAILED;
    }
    
    closeTransaction(pNdb);
    g_info << rows << " rows have been read" << endl;
    if (records != 0 && rows != records){
      g_info << "Check expected number of records failed" << endl 
	     << "  expected=" << records <<", " << endl
	     << "  read=" << rows << endl;
      return NDBT_FAILED;
    }
    
    return NDBT_OK;
  }
  return NDBT_FAILED;
}
Exemple #5
0
inline
int 
ScanInterpretTest::scanReadVerify(Ndb* pNdb,
				  int records,
				  int parallelism,
				  ScanFilter& filter){
  int                  retryAttempt = 0;
  const int            retryMax = 100;
  int                  check;
  NdbConnection	       *pTrans;
  NdbScanOperation	       *pOp;
  
  while (true){
    
    if (retryAttempt >= retryMax){
      ndbout << "ERROR: has retried this operation " << retryAttempt 
	     << " times, failing!" << endl;
      return NDBT_FAILED;
    }
    
    pTrans = pNdb->startTransaction();
    if (pTrans == NULL) {
      const NdbError err = pNdb->getNdbError();
      if (err.status == NdbError::TemporaryError){
	ERR(err);
	NdbSleep_MilliSleep(50);
	retryAttempt++;
	continue;
      }
      ERR(err);
      return NDBT_FAILED;
    }
    
    
    pOp = pTrans->getNdbScanOperation(tab.getName());	
    if (pOp == NULL) {  if (pOp->getValue("KOL2") == 0){
    ERR(pNdb->getNdbError());
    return NDBT_FAILED;
  }
  

      ERR(pTrans->getNdbError());
      pNdb->closeTransaction(pTrans);
      return NDBT_FAILED;
    }
   
    if( pOp->readTuples(NdbScanOperation::LM_Read, 0, parallelism) ) {
      ERR(pTrans->getNdbError());
      pNdb->closeTransaction(pTrans);
      return NDBT_FAILED;
    }

    check = pOp->interpret_exit_ok();
    if (check == -1) {
      ERR(pTrans->getNdbError());
      pNdb->closeTransaction(pTrans);
      return NDBT_FAILED;
    }

    
    // Read all attributes  
    for(int a = 0; a<tab.getNoOfColumns(); a++){
      if((row.attributeStore(a) = 
	  pOp->getValue(tab.getColumn(a)->getName())) == 0) {
	ERR(pTrans->getNdbError());
	pNdb->closeTransaction(pTrans);
	return NDBT_FAILED;
      }
    }      
    check = pTrans->execute(NoCommit);   
    if( check == -1 ) {
      ERR(pTrans->getNdbError());
      pNdb->closeTransaction(pTrans);
      return NDBT_FAILED;
    }

    int eof;
    int rows = 0;
    int rowsNoExist = 0;
    int rowsExist = 0;    
    int existingRecordsNotFound = 0;
    int nonExistingRecordsFound = 0;


    NdbConnection* pExistTrans;
    NdbConnection* pNoExistTrans;
    
    while((eof = pOp->nextResult(true)) == 0){
      pExistTrans = pNdb->startTransaction();
      if (pExistTrans == NULL) {
	const NdbError err = pNdb->getNdbError();
	ERR(err);
	return NDBT_FAILED;
      }
      pNoExistTrans = pNdb->startTransaction();
      if (pNoExistTrans == NULL) {
	const NdbError err = pNdb->getNdbError();
	ERR(err);
	return NDBT_FAILED;
      }
      do {
	rows++;
	if (filter.verifyRecord(row) == NDBT_OK){
	  rowsExist++;
	  if (addRowToCheckTrans(pNdb, pExistTrans) != 0){
	    pNdb->closeTransaction(pTrans);
	    pNdb->closeTransaction(pExistTrans);
	    pNdb->closeTransaction(pNoExistTrans);
	    return NDBT_FAILED;
	  }
	}else{
	  rowsNoExist++;
	  if (addRowToCheckTrans(pNdb, pNoExistTrans) != 0){
	    pNdb->closeTransaction(pTrans);
	    pNdb->closeTransaction(pExistTrans);
	    pNdb->closeTransaction(pNoExistTrans);
	    return NDBT_FAILED;
	  }
	}
      } while((eof = pOp->nextResult(false)) == 0);


      // Execute the transaction containing reads of 
      // all the records that should be in the result table
      check = pExistTrans->execute(Commit);   
      if( check == -1 ) {
	const NdbError err = pExistTrans->getNdbError();    
	ERR(err);
	if (err.code != 626){
	  pNdb->closeTransaction(pExistTrans);
	  pNdb->closeTransaction(pNoExistTrans);
	  pNdb->closeTransaction(pTrans);
	  return NDBT_FAILED;
	}else{
	  // Some of the records expected to be found wasn't 
	  // there
	  existingRecordsNotFound = 1;
	}
      }
      pNdb->closeTransaction(pExistTrans);

      // Execute the transaction containing reads of 
      // all the records that should NOT be in the result table
      check = pNoExistTrans->execute(Commit, CommitAsMuchAsPossible);   
      if( check == -1 ) {
	const NdbError err = pNoExistTrans->getNdbError();    
	// The transactions error code should be zero
	if (err.code != 626){
	  ERR(err);
	  pNdb->closeTransaction(pNoExistTrans);
	  pNdb->closeTransaction(pTrans);
	  return NDBT_FAILED;
	}
	// Loop through the no existing transaction and check that no 
	// operations where successful
	const NdbOperation* pOp2 = NULL;
	while ((pOp2 = pNoExistTrans->getNextCompletedOperation(pOp2)) != NULL){
	  const NdbError err = pOp2->getNdbError();
	  if (err.code != 626){
	    ndbout << "err.code = " << err.code<< endl;
	    nonExistingRecordsFound = 1;
	  }
	}
      } 
      
      pNdb->closeTransaction(pNoExistTrans);
      

    }
    if (eof == -1) {
      const NdbError err = pTrans->getNdbError();
      
      if (err.status == NdbError::TemporaryError){
	ERR(err);
	pNdb->closeTransaction(pTrans);
	NdbSleep_MilliSleep(50);
	retryAttempt++;
	continue;
      }
      ERR(err);
      pNdb->closeTransaction(pTrans);
      return NDBT_FAILED;
    }
    
    int testResult = NDBT_OK;
    int rowsResult = 0;
    UtilTransactions utilTrans(restab);  
    if (utilTrans.selectCount(pNdb, 
			      240,
			      &rowsResult) != 0){
      return NDBT_FAILED;
    }
    if (existingRecordsNotFound == 1){
      ndbout << "!!! Expected records not found" << endl;
      testResult = NDBT_FAILED;
    }
    if (nonExistingRecordsFound == 1){
      ndbout << "!!! Unxpected records found" << endl;
      testResult = NDBT_FAILED;
    }
    ndbout << rows << " rows scanned("
	   << rowsExist << " found, " << rowsResult<<" expected)" << endl;
    if (rowsResult != rowsExist){
      ndbout << "!!! Number of rows in result table different from expected" << endl;
      testResult = NDBT_FAILED;
    }

    return testResult;
  }
  return NDBT_FAILED;
}
Exemple #6
0
int 
UtilTransactions::verifyOrderedIndex(Ndb* pNdb,
				     const NdbDictionary::Index* pIndex,
				     int parallelism,
				     bool transactional){
  
  int                  retryAttempt = 0;
  const int            retryMax = 100;
  int                  check;
  NdbScanOperation     *pOp;
  NdbIndexScanOperation * iop = 0;

  NDBT_ResultRow       scanRow(tab);
  NDBT_ResultRow       pkRow(tab);
  NDBT_ResultRow       indexRow(tab);
  const char * indexName = pIndex->getName();

  int res;
  parallelism = 1;
  
  while (true){

    if (retryAttempt >= retryMax){
      g_info << "ERROR: has retried this operation " << retryAttempt 
	     << " times, failing!" << endl;
      return NDBT_FAILED;
    }

    pTrans = pNdb->startTransaction();
    if (pTrans == NULL) {
      const NdbError err = pNdb->getNdbError();

      if (err.status == NdbError::TemporaryError){
	ERR(err);
	NdbSleep_MilliSleep(50);
	retryAttempt++;
	continue;
      }
      ERR(err);
      return NDBT_FAILED;
    }

    pOp = pTrans->getNdbScanOperation(tab.getName());	
    if (pOp == NULL) {
      ERR(pTrans->getNdbError());
      closeTransaction(pNdb);
      return NDBT_FAILED;
    }

    if( pOp->readTuples(NdbScanOperation::LM_Read, 0, parallelism) ) {
      ERR(pTrans->getNdbError());
      closeTransaction(pNdb);
      return NDBT_FAILED;
    }

    check = pOp->interpret_exit_ok();
    if( check == -1 ) {
      ERR(pTrans->getNdbError());
      closeTransaction(pNdb);
      return NDBT_FAILED;
    }

    if(get_values(pOp, scanRow))
    {
      abort();
    }

    check = pTrans->execute(NoCommit, AbortOnError);
    if( check == -1 ) {
      const NdbError err = pTrans->getNdbError();
      
      if (err.status == NdbError::TemporaryError){
	ERR(err);
	closeTransaction(pNdb);
	NdbSleep_MilliSleep(50);
	retryAttempt++;
	continue;
      }
      ERR(err);
      closeTransaction(pNdb);
      return NDBT_FAILED;
    }
        
    int eof;
    int rows = 0;
    while(check == 0 && (eof = pOp->nextResult()) == 0){
      rows++;

      bool null_found= false;
      for(int a = 0; a<(int)pIndex->getNoOfColumns(); a++){
	const NdbDictionary::Column *  col = pIndex->getColumn(a);
	if (scanRow.attributeStore(col->getName())->isNULL())
	{
	  null_found= true;
	  break;
	}
      }
      
      // Do pk lookup
      NdbOperation * pk = pTrans->getNdbOperation(tab.getName());
      if(!pk || pk->readTuple())
	goto error;
      if(equal(&tab, pk, scanRow) || get_values(pk, pkRow))
	goto error;

      if(!null_found)
      {
	if(!iop && (iop= pTrans->getNdbIndexScanOperation(indexName, 
							  tab.getName())))
	{
	  if(iop->readTuples(NdbScanOperation::LM_CommittedRead, 
			     parallelism))
	    goto error;
	  iop->interpret_exit_ok();
	  if(get_values(iop, indexRow))
	    goto error;
	}
	else if(!iop || iop->reset_bounds())
	{
	  goto error;
	}
	
	if(equal(pIndex, iop, scanRow))
	  goto error;
      }     

      check = pTrans->execute(NoCommit, AbortOnError);
      if(check)
	goto error;

      if(scanRow.c_str() != pkRow.c_str()){
	g_err << "Error when comapring records" << endl;
	g_err << " scanRow: \n" << scanRow.c_str().c_str() << endl;
	g_err << " pkRow: \n" << pkRow.c_str().c_str() << endl;
	closeTransaction(pNdb);
	return NDBT_FAILED;
      }

      if(!null_found)
      {
	
	if((res= iop->nextResult()) != 0){
	  g_err << "Failed to find row using index: " << res << endl;
	  ERR(pTrans->getNdbError());
	  closeTransaction(pNdb);
	  return NDBT_FAILED;
	}
	
	if(scanRow.c_str() != indexRow.c_str()){
	  g_err << "Error when comapring records" << endl;
	  g_err << " scanRow: \n" << scanRow.c_str().c_str() << endl;
	  g_err << " indexRow: \n" << indexRow.c_str().c_str() << endl;
	  closeTransaction(pNdb);
	  return NDBT_FAILED;
	}
	
	if(iop->nextResult() == 0){
	  g_err << "Found extra row!!" << endl;
	  g_err << " indexRow: \n" << indexRow.c_str().c_str() << endl;
	  closeTransaction(pNdb);
	  return NDBT_FAILED;
	}
      }
    }
    
    if (eof == -1 || check == -1) {
  error:
      const NdbError err = pTrans->getNdbError();
      
      if (err.status == NdbError::TemporaryError){
	ERR(err);
	iop = 0;
	closeTransaction(pNdb);
	NdbSleep_MilliSleep(50);
	retryAttempt++;
	rows--;
	continue;
      }
      ERR(err);
      closeTransaction(pNdb);
      return NDBT_FAILED;
    }
      
    closeTransaction(pNdb);
    
    return NDBT_OK;
  }
  return NDBT_FAILED;
}
Exemple #7
0
inline 
int 
ScanFunctions::scanReadFunctions(Ndb* pNdb,
				 int records,
				 int parallelism,
				 ActionType action,
				 bool exclusive){
  int                  retryAttempt = 0;
  const int            retryMax = 100;
  int sleepTime = 10;
  int                  check;
  NdbConnection	       *pTrans = 0;
  NdbScanOperation     *pOp = 0;

  while (true){
    if (retryAttempt >= retryMax){
      g_err << "ERROR: has retried this operation " << retryAttempt 
	     << " times, failing!" << endl;
      return NDBT_FAILED;
    }

    pTrans = pNdb->startTransaction();
    if (pTrans == NULL) {
      const NdbError err = pNdb->getNdbError();
      if (err.status == NdbError::TemporaryError){
	ERR(err);
	NdbSleep_MilliSleep(50);
	retryAttempt++;
	continue;
      }
      ERR(err);
      return NDBT_FAILED;
    }
    
    // Execute the scan without defining a scan operation
    pOp = pTrans->getNdbScanOperation(tab.getName());	
    if (pOp == NULL) {
      ERR(pTrans->getNdbError());
      pNdb->closeTransaction(pTrans);
      return NDBT_FAILED;
    }
    
    if( pOp->readTuples(exclusive ? 
			NdbScanOperation::LM_Exclusive : 
			NdbScanOperation::LM_Read) ) {
      ERR(pTrans->getNdbError());
      pNdb->closeTransaction(pTrans);
      return NDBT_FAILED;
    }
    
    
    if (action == OnlyOpenScanOnce){
      // Call openScan one more time when it's already defined
      if( pOp->readTuples(NdbScanOperation::LM_Read) ) {
	ERR(pTrans->getNdbError());
	pNdb->closeTransaction(pTrans);
	return NDBT_FAILED;
      }
    }
    
    if (action==EqualAfterOpenScan){
      check = pOp->equal(tab.getColumn(0)->getName(), 10);
      if( check == -1 ) {
	ERR(pTrans->getNdbError());
	pNdb->closeTransaction(pTrans);
	return NDBT_FAILED;
      }	
    }
    
    check = pOp->interpret_exit_ok();
    if( check == -1 ) {
      ERR(pTrans->getNdbError());
      pNdb->closeTransaction(pTrans);
      return NDBT_FAILED;
    }
    
    for(int a = 0; a<tab.getNoOfColumns(); a++){
      if(pOp->getValue(tab.getColumn(a)->getName()) == NULL) {
	ERR(pTrans->getNdbError());
	pNdb->closeTransaction(pTrans);
	return NDBT_FAILED;
      }
    }      
    
    check = pTrans->execute(NoCommit);
    if( check == -1 ) {
      ERR(pTrans->getNdbError());
      pNdb->closeTransaction(pTrans);
      return NDBT_FAILED;
    }
    
    int abortCount = records / 10;
    bool abortTrans = (action==CloseWithoutStop);
    int eof;
    int rows = 0;
    eof = pOp->nextResult();
    
    while(eof == 0){
      rows++;
      
      if (abortCount == rows && abortTrans == true){
	g_info << "Scan is aborted after "<<abortCount<<" rows" << endl;
	
	if (action != CloseWithoutStop){
	  // Test that we can closeTrans without stopScan
	  pOp->close();
	  if( check == -1 ) {
	    ERR(pTrans->getNdbError());
	    pNdb->closeTransaction(pTrans);
	    return NDBT_FAILED;
	  }
	}

	
	pNdb->closeTransaction(pTrans);
	return NDBT_OK;
      }
      
      if(action == CheckInactivityTimeOut){
	if ((rows % (records / 10)) == 0){
	  // Sleep for a long time before calling nextScanResult
	  if (sleepTime > 1)
	    sleepTime--;
	  g_info << "Sleeping "<<sleepTime<<" secs " << endl;
	  NdbSleep_SecSleep(sleepTime); 
	}
      }

      eof = pOp->nextResult();
    }
    if (eof == -1) {
      const NdbError err = pTrans->getNdbError();

      if (err.status == NdbError::TemporaryError){
	ERR(err);
	
	// Be cruel, call nextScanResult after error
	for(int i=0; i<10; i++){
	  eof = pOp->nextResult();
	  if(eof == 0){
	    g_err << "nextScanResult returned eof = " << eof << endl
		   << " That is an error when there are no more records" << endl;
	    return NDBT_FAILED;
	  }
	}
	// Be cruel end

	pNdb->closeTransaction(pTrans);
	NdbSleep_MilliSleep(50);
	retryAttempt++;
	g_info << "Starting over" << endl;

	// If test is CheckInactivityTimeOut
	// error 296 is expected
	if ((action == CheckInactivityTimeOut) &&
	    (err.code == 296))
	  return NDBT_OK;

	continue;
      }
      ERR(err);
      pNdb->closeTransaction(pTrans);
      return NDBT_FAILED;
    }

    if (action == NextScanWhenNoMore){
      g_info << "Calling nextScanresult when there are no more records" << endl;
      for(int i=0; i<10; i++){
	eof = pOp->nextResult();
	if(eof == 0){
	  g_err << "nextScanResult returned eof = " << eof << endl
		 << " That is an error when there are no more records" << endl;
	  return NDBT_FAILED;
	}
      }

    }
    if(action == CheckInactivityBeforeClose){
      // Sleep for a long time before calling close
      g_info << "NdbSleep_SecSleep(5) before close transaction" << endl;
      NdbSleep_SecSleep(5); 
    }
    if(action == NoCloseTransaction)
      g_info << "Forgetting to close transaction" << endl;
    else
      pNdb->closeTransaction(pTrans);

    g_info << rows << " rows have been read" << endl;
    if (records != 0 && rows != records){
      g_err << "Check expected number of records failed" << endl 
	     << "  expected=" << records <<", " << endl
	     << "  read=" << rows <<  endl;
      return NDBT_FAILED;
    }
    
    return NDBT_OK;
  }
  return NDBT_FAILED;


}
int
HugoTransactions::scanReadRecords(Ndb* pNdb, 
				  int records,
				  int abortPercent,
				  int parallelism, 
				  NdbOperation::LockMode lm,
                                  int scan_flags)
{
  
  int                  retryAttempt = 0;
  int                  check, a;
  NdbScanOperation	       *pOp;

  while (true){

    if (retryAttempt >= m_retryMax){
      g_err << "ERROR: has retried this operation " << retryAttempt 
	    << " times, failing!" << endl;
      return NDBT_FAILED;
    }

    pTrans = pNdb->startTransaction();
    if (pTrans == NULL) {
      const NdbError err = pNdb->getNdbError();

      if (err.status == NdbError::TemporaryError){
	ERR(err);
	NdbSleep_MilliSleep(50);
	retryAttempt++;
	continue;
      }
      ERR(err);
      return NDBT_FAILED;
    }

    pOp = getScanOperation(pTrans);
    if (pOp == NULL) {
      ERR(pTrans->getNdbError());
      closeTransaction(pNdb);
      return NDBT_FAILED;
    }

    if( pOp ->readTuples(lm, scan_flags, parallelism) ) {
      ERR(pTrans->getNdbError());
      closeTransaction(pNdb);
      return NDBT_FAILED;
    }
    
    check = pOp->interpret_exit_ok();
    if( check == -1 ) {
      ERR(pTrans->getNdbError());
      closeTransaction(pNdb);
      return NDBT_FAILED;
    }
  
    for(a = 0; a<tab.getNoOfColumns(); a++){
      if((row.attributeStore(a) = 
	  pOp->getValue(tab.getColumn(a)->getName())) == 0) {
	ERR(pTrans->getNdbError());
	closeTransaction(pNdb);
	return NDBT_FAILED;
      }
    }

    check = pTrans->execute(NoCommit, AbortOnError);
    if( check == -1 ) {
      const NdbError err = pTrans->getNdbError();
      if (err.status == NdbError::TemporaryError){
	ERR(err);
	closeTransaction(pNdb);
	NdbSleep_MilliSleep(50);
	retryAttempt++;
	continue;
      }
      ERR(err);
      closeTransaction(pNdb);
      return NDBT_FAILED;
    }

    // Abort after 1-100 or 1-records rows
    int ranVal = rand();
    int abortCount = ranVal % (records == 0 ? 100 : records); 
    bool abortTrans = false;
    if (abort > 0){
      // Abort if abortCount is less then abortPercent 
      if (abortCount < abortPercent) 
	abortTrans = true;
    }
    
    int eof;
    int rows = 0;
    while((eof = pOp->nextResult(true)) == 0){
      rows++;
      if (calc.verifyRowValues(&row) != 0){
	closeTransaction(pNdb);
	return NDBT_FAILED;
      }

      if (abortCount == rows && abortTrans == true){
	ndbout << "Scan is aborted" << endl;
	g_info << "Scan is aborted" << endl;
	pOp->close();
	if( check == -1 ) {
	  ERR(pTrans->getNdbError());
	  closeTransaction(pNdb);
	  return NDBT_FAILED;
	}
	
	closeTransaction(pNdb);
	return NDBT_OK;
      }
    }
    if (eof == -1) {
      const NdbError err = pTrans->getNdbError();
      
      if (err.status == NdbError::TemporaryError){
	ERR_INFO(err);
	closeTransaction(pNdb);
	NdbSleep_MilliSleep(50);
	switch (err.code){
	case 488:
	case 245:
	case 490:
	  // Too many active scans, no limit on number of retry attempts
	  break;
	default:
	  retryAttempt++;
	}
	continue;
      }
      ERR(err);
      closeTransaction(pNdb);
      return NDBT_FAILED;
    }

    closeTransaction(pNdb);

    g_info << rows << " rows have been read" << endl;
    if (records != 0 && rows != records){
      g_err << "Check expected number of records failed" << endl 
	    << "  expected=" << records <<", " << endl
	    << "  read=" << rows << endl;
      return NDBT_FAILED;
    }
    
    return NDBT_OK;
  }
  return NDBT_FAILED;
}
Exemple #9
0
int
run_scan(){
  int iter = g_paramters[P_LOOPS].value;
  NDB_TICKS start1, stop;
  int sum_time= 0;

  int sample_rows = 0;
  int tot_rows = 0;
  NDB_TICKS sample_start = NdbTick_CurrentMillisecond();

  Uint32 tot = g_paramters[P_ROWS].value;

  if(g_paramters[P_BOUND].value >= 2 || g_paramters[P_FILT].value == 2)
    iter *= g_paramters[P_ROWS].value;

  NdbScanOperation * pOp = 0;
  NdbIndexScanOperation * pIOp = 0;
  NdbConnection * pTrans = 0;
  int check = 0;

  for(int i = 0; i<iter; i++){
    start1 = NdbTick_CurrentMillisecond();
    pTrans = pTrans ? pTrans : g_ndb->startTransaction();
    if(!pTrans){
      g_err << "Failed to start transaction" << endl;
      err(g_ndb->getNdbError());
      return -1;
    }
    
    int par = g_paramters[P_PARRA].value;
    int bat = 0; // g_paramters[P_BATCH].value;
    NdbScanOperation::LockMode lm;
    switch(g_paramters[P_LOCK].value){
    case 0:
      lm = NdbScanOperation::LM_CommittedRead;
      break;
    case 1:
      lm = NdbScanOperation::LM_Read;
      break;
    case 2:
      lm = NdbScanOperation::LM_Exclusive;
      break;
    default:
      abort();
    }

    if(g_paramters[P_ACCESS].value == 0){
      pOp = pTrans->getNdbScanOperation(g_tablename);
      assert(pOp);
      pOp->readTuples(lm, bat, par);
    } else {
      if(g_paramters[P_RESET].value == 0 || pIOp == 0)
      {
	pOp= pIOp= pTrans->getNdbIndexScanOperation(g_indexname, g_tablename);
	bool ord = g_paramters[P_ACCESS].value == 2;
	pIOp->readTuples(lm, bat, par, ord);
      }
      else
      {
	pIOp->reset_bounds();
      }

      switch(g_paramters[P_BOUND].value){
      case 0: // All
	break;
      case 1: // None
	pIOp->setBound((Uint32)0, NdbIndexScanOperation::BoundEQ, 0);
	break;
      case 2: { // 1 row
      default:  
	assert(g_table->getNoOfPrimaryKeys() == 1); // only impl. so far
	int tot = g_paramters[P_ROWS].value;
	int row = rand() % tot;
#if 0
	fix_eq_bound(pIOp, row);
#else
	pIOp->setBound((Uint32)0, NdbIndexScanOperation::BoundEQ, &row);
#endif
	if(g_paramters[P_RESET].value == 2)
	  goto execute;
	break;
      }
      case 3: { // read multi
	int multi = g_paramters[P_MULTI].value;
	int tot = g_paramters[P_ROWS].value;
	for(; multi > 0 && i < iter; --multi, i++)
	{
	  int row = rand() % tot;
	  pIOp->setBound((Uint32)0, NdbIndexScanOperation::BoundEQ, &row);
	  pIOp->end_of_bound(i);
	}
	if(g_paramters[P_RESET].value == 2)
	  goto execute;
	break;
      }
      }
    }
    assert(pOp);
    
    switch(g_paramters[P_FILT].value){
    case 0: // All
      check = pOp->interpret_exit_ok();
      break;
    case 1: // None
      check = pOp->interpret_exit_nok();
      break;
    case 2: { // 1 row
    default:  
      assert(g_table->getNoOfPrimaryKeys() == 1); // only impl. so far
      abort();
#if 0
      int tot = g_paramters[P_ROWS].value;
      int row = rand() % tot;
      NdbScanFilter filter(pOp) ;   
      filter.begin(NdbScanFilter::AND);
      fix_eq(filter, pOp, row);
      filter.end();
      break;
#endif
    }
    }
    if(check != 0){
      err(pOp->getNdbError());
      return -1;
    }
    assert(check == 0);

    if(g_paramters[P_RESET].value == 1)
      g_paramters[P_RESET].value = 2;
    
    for(int i = 0; i<g_table->getNoOfColumns(); i++){
      pOp->getValue(i);
    }

    if(g_paramters[P_RESET].value == 1)
      g_paramters[P_RESET].value = 2;
execute:
    int rows = 0;
    check = pTrans->execute(NoCommit);
    assert(check == 0);
    int fetch = g_paramters[P_FETCH].value;
    while((check = pOp->nextResult(true)) == 0){
      do {
	rows++;
      } while(!fetch && ((check = pOp->nextResult(false)) == 0));
      if(check == -1){
        err(pTrans->getNdbError());
        return -1;
      }
      assert(check == 2);
    }

    if(check == -1){
      err(pTrans->getNdbError());
      return -1;
    }
    assert(check == 1);
    if(g_paramters[P_RESET].value == 0)
    {
      pTrans->close();
      pTrans = 0;
    }
    stop = NdbTick_CurrentMillisecond();
    
    int time_passed= (int)(stop - start1);
    sample_rows += rows;
    sum_time+= time_passed;
    tot_rows+= rows;
    
    if(sample_rows >= tot)
    {
      int sample_time = (int)(stop - sample_start);
      g_info << "Found " << sample_rows << " rows" << endl;
      g_err.println("Time: %d ms = %u rows/sec", sample_time,
		    (1000*sample_rows)/sample_time);
      sample_rows = 0;
      sample_start = stop;
    }
  }
  
  g_err.println("Avg time: %d ms = %u rows/sec", sum_time/tot_rows,
                (1000*tot_rows)/sum_time);
  return 0;
}
Exemple #10
0
int scanReadRecords(Ndb* pNdb,
                    const NdbDictionary::Table* pTab,
                    const NdbDictionary::Index* pIdx,
                    int parallel,
                    int _lock,
                    bool headers,
                    bool useHexFormat,
                    char delimiter, bool order, bool descending) {

    int                  retryAttempt = 0;
    const int            retryMax = 100;
    int                  check;
    NdbTransaction       *pTrans;
    NdbScanOperation	       *pOp;
    NdbIndexScanOperation * pIOp= 0;

    NDBT_ResultRow * row = new NDBT_ResultRow(*pTab, delimiter);

    while (true) {

        if (retryAttempt >= retryMax) {
            ndbout << "ERROR: has retried this operation " << retryAttempt
                   << " times, failing!" << endl;
            return -1;
        }

        pTrans = pNdb->startTransaction();
        if (pTrans == NULL) {
            const NdbError err = pNdb->getNdbError();

            if (err.status == NdbError::TemporaryError) {
                NdbSleep_MilliSleep(50);
                retryAttempt++;
                continue;
            }
            ERR(err);
            return -1;
        }


        pOp = (!pIdx) ? pTrans->getNdbScanOperation(pTab->getName()) :
              pIOp=pTrans->getNdbIndexScanOperation(pIdx->getName(), pTab->getName());

        if (pOp == NULL) {
            ERR(pTrans->getNdbError());
            pNdb->closeTransaction(pTrans);
            return -1;
        }

        int rs;
        unsigned scan_flags = 0;
        if (_tup) scan_flags |= NdbScanOperation::SF_TupScan;
        switch(_lock + (3 * order)) {
        case 1:
            rs = pOp->readTuples(NdbScanOperation::LM_Read, scan_flags, parallel);
            break;
        case 2:
            rs = pOp->readTuples(NdbScanOperation::LM_Exclusive, scan_flags, parallel);
            break;
        case 3:
            rs = pIOp->readTuples(NdbScanOperation::LM_CommittedRead, 0, parallel,
                                  true, descending);
            break;
        case 4:
            rs = pIOp->readTuples(NdbScanOperation::LM_Read, 0, parallel, true, descending);
            break;
        case 5:
            rs = pIOp->readTuples(NdbScanOperation::LM_Exclusive, 0, parallel, true, descending);
            break;
        case 0:
        default:
            rs = pOp->readTuples(NdbScanOperation::LM_CommittedRead, scan_flags, parallel);
            break;
        }
        if( rs != 0 ) {
            ERR(pTrans->getNdbError());
            pNdb->closeTransaction(pTrans);
            return -1;
        }

        if(0) {
            NdbScanFilter sf(pOp);
#if 0
            sf.begin(NdbScanFilter::AND);
            sf.le(0, (Uint32)10);

            sf.end();
#elif 0
            sf.begin(NdbScanFilter::OR);
            sf.begin(NdbScanFilter::AND);
            sf.ge(0, (Uint32)10);
            sf.lt(0, (Uint32)20);
            sf.end();
            sf.begin(NdbScanFilter::AND);
            sf.ge(0, (Uint32)30);
            sf.lt(0, (Uint32)40);
            sf.end();
            sf.end();
#elif 1
            sf.begin(NdbScanFilter::AND);
            sf.begin(NdbScanFilter::OR);
            sf.begin(NdbScanFilter::AND);
            sf.ge(0, (Uint32)10);
            sf.lt(0, (Uint32)20);
            sf.end();
            sf.begin(NdbScanFilter::AND);
            sf.ge(0, (Uint32)30);
            sf.lt(0, (Uint32)40);
            sf.end();
            sf.end();
            sf.begin(NdbScanFilter::OR);
            sf.begin(NdbScanFilter::AND);
            sf.ge(0, (Uint32)0);
            sf.lt(0, (Uint32)50);
            sf.end();
            sf.begin(NdbScanFilter::AND);
            sf.ge(0, (Uint32)100);
            sf.lt(0, (Uint32)200);
            sf.end();
            sf.end();
            sf.end();
#endif
        } else {
            check = pOp->interpret_exit_ok();
            if( check == -1 ) {
                ERR(pTrans->getNdbError());
                pNdb->closeTransaction(pTrans);
                return -1;
            }
        }

        bool disk= false;
        for(int a = 0; a<pTab->getNoOfColumns(); a++)
        {
            const NdbDictionary::Column* col = pTab->getColumn(a);
            if(col->getStorageType() == NdbDictionary::Column::StorageTypeDisk)
                disk= true;

            if (!nodata)
                if((row->attributeStore(a) = pOp->getValue(col)) == 0)
                {
                    ERR(pTrans->getNdbError());
                    pNdb->closeTransaction(pTrans);
                    return -1;
                }
        }

        NdbRecAttr * disk_ref= 0;
        if(_dumpDisk && disk)
            disk_ref = pOp->getValue(NdbDictionary::Column::DISK_REF);

        NdbRecAttr * rowid= 0, *frag = 0, *gci = 0;
        if (use_rowid)
        {
            frag = pOp->getValue(NdbDictionary::Column::FRAGMENT);
            rowid = pOp->getValue(NdbDictionary::Column::ROWID);
        }

        if (use_gci)
        {
            gci = pOp->getValue(NdbDictionary::Column::ROW_GCI);
        }

        check = pTrans->execute(NdbTransaction::NoCommit);
        if( check == -1 ) {
            const NdbError err = pTrans->getNdbError();

            if (err.status == NdbError::TemporaryError) {
                pNdb->closeTransaction(pTrans);
                NdbSleep_MilliSleep(50);
                retryAttempt++;
                continue;
            }
            ERR(err);
            pNdb->closeTransaction(pTrans);
            return -1;
        }

        if (rowid)
            ndbout << "ROWID\t";

        if (gci)
            ndbout << "\tGCI";

        if (headers && !nodata)
            row->header(ndbout);

        if (disk_ref)
            ndbout << "\tDISK_REF";

        ndbout << endl;

        int eof;
        int rows = 0;
        eof = pOp->nextResult();

        while(eof == 0) {
            rows++;

            if (useHexFormat)
                ndbout.setHexFormat(1);

            if (rowid)
            {
                ndbout << "[ fragment: " << frag->u_32_value()
                       << " m_page: " << rowid->u_32_value()
                       << " m_page_idx: " << *(Uint32*)(rowid->aRef() + 4) << " ]";
                ndbout << "\t";
            }

            if (gci)
            {
                if (gci->isNULL())
                    ndbout << "NULL\t";
                else
                    ndbout << gci->u_64_value() << "\t";
            }

            if (!nodata)
                ndbout << (*row);

            if(disk_ref)
            {
                ndbout << "\t";
                ndbout << "[ m_file_no: " << *(Uint16*)(disk_ref->aRef()+6)
                       << " m_page: " << disk_ref->u_32_value()
                       << " m_page_idx: " << *(Uint16*)(disk_ref->aRef() + 4) << " ]";
            }

            if (rowid || disk_ref || gci || !nodata)
                ndbout << endl;
            eof = pOp->nextResult();
        }
        if (eof == -1) {
            const NdbError err = pTrans->getNdbError();

            if (err.status == NdbError::TemporaryError) {
                pNdb->closeTransaction(pTrans);
                NdbSleep_MilliSleep(50);
                retryAttempt++;
                continue;
            }
            ERR(err);
            pNdb->closeTransaction(pTrans);
            return -1;
        }

        pNdb->closeTransaction(pTrans);

        ndbout << rows << " rows returned" << endl;

        return 0;
    }
    return -1;
}
int runTestBug34107(NDBT_Context* ctx, NDBT_Step* step){
  int result = NDBT_OK;
  const NdbDictionary::Table * pTab = ctx->getTab();
  Ndb* pNdb = GETNDB(step);

  int i;
  for (i = 0; i <= 1; i++) {
    g_info << "bug34107:" << (i == 0 ? " small" : " too big") << endl;

    NdbConnection* pTrans = pNdb->startTransaction();
    if (pTrans == NULL){
      ERR(pNdb->getNdbError());
      return NDBT_FAILED;
    }
    
    NdbScanOperation* pOp = pTrans->getNdbScanOperation(pTab->getName());
    if (pOp == NULL) {
      ERR(pTrans->getNdbError());
      pNdb->closeTransaction(pTrans);
      return NDBT_FAILED;
    }
    
    if (pOp->readTuples() == -1) {
      ERR(pOp->getNdbError());
      pNdb->closeTransaction(pTrans);
      return NDBT_FAILED;
    }

    int n = i == 0 ? 10000 : 30000;
    int k;

    for (k = 0; k < n; k++) {

      // inserts 1 word ATTRINFO

      if (pOp->interpret_exit_ok() == -1) {
        ERR(pOp->getNdbError());
        pNdb->closeTransaction(pTrans);
        return NDBT_FAILED;
      }
    }
      
    if (pTrans->execute(NoCommit) == -1) {
      ERR(pTrans->getNdbError());
      pNdb->closeTransaction(pTrans);
      return NDBT_FAILED;
    }

    int ret;
    while ((ret = pOp->nextResult()) == 0)
      ;
    g_info << "ret=" << ret << " err=" << pOp->getNdbError().code << endl;

    if (i == 0 && ret != 1) {
      ERR(pTrans->getNdbError());
      pNdb->closeTransaction(pTrans);
      return NDBT_FAILED;
    }

    if (i == 1 && ret != -1) {
      g_err << "unexpected big filter success" << endl;
      pNdb->closeTransaction(pTrans);
      return NDBT_FAILED;
    }
    if (i == 1 && pOp->getNdbError().code != 874) {
      g_err << "unexpected big filter error code, wanted 874" << endl;
      ERR(pTrans->getNdbError());
      pNdb->closeTransaction(pTrans);
      return NDBT_FAILED;
    }

    pNdb->closeTransaction(pTrans);
  }

  return NDBT_OK;
}