4579 Jan Wedvik 2012-06-26 [merge]
Merge 7.0 -> 7.1
modified:
storage/ndb/src/ndbapi/NdbScanOperation.cpp
storage/ndb/src/ndbapi/ndberror.c
storage/ndb/test/ndbapi/testScan.cpp
storage/ndb/test/run-test/daily-basic-tests.txt
4578 magnus.blaudd@stripped 2012-06-25 [merge]
Merge 7.0 -> 7.1
modified:
storage/ndb/test/include/NdbBackup.hpp
storage/ndb/test/include/NdbConfig.hpp
storage/ndb/test/ndbapi/testBackup.cpp
storage/ndb/test/ndbapi/testBasic.cpp
storage/ndb/test/ndbapi/testSystemRestart.cpp
storage/ndb/test/ndbapi/testTimeout.cpp
storage/ndb/test/ndbapi/testUpgrade.cpp
=== modified file 'storage/ndb/src/ndbapi/NdbScanOperation.cpp'
--- a/storage/ndb/src/ndbapi/NdbScanOperation.cpp 2012-06-21 12:33:15 +0000
+++ b/storage/ndb/src/ndbapi/NdbScanOperation.cpp 2012-06-26 09:18:05 +0000
@@ -27,6 +27,8 @@
#define DEBUG_NEXT_RESULT 0
+static const int Err_scanAlreadyComplete = 4120;
+
NdbScanOperation::NdbScanOperation(Ndb* aNdb, NdbOperation::Type aType) :
NdbOperation(aNdb, aType),
m_transConnection(NULL)
@@ -1883,6 +1885,15 @@ NdbScanOperation::nextResultNdbRecord(co
if(theError.code)
{
+ if (theError.code == Err_scanAlreadyComplete)
+ {
+ /**
+ * The scan is already complete. There must be a bug in the api
+ * application such that is calls nextResult()/nextResultNdbRecord()
+ * again after getting return value 1 (meaning end of scan).
+ */
+ return -1;
+ }
goto err4;
}
@@ -1928,8 +1939,9 @@ NdbScanOperation::nextResultNdbRecord(co
{
/**
* No completed & no sent -> EndOfData
+ * Make sure user gets error if he tries again.
*/
- theError.code= -1; // make sure user gets error if he tries again
+ theError.code= Err_scanAlreadyComplete;
return 1;
}
@@ -3677,7 +3689,7 @@ NdbIndexScanOperation::next_result_order
}
else
{
- theError.code= -1;
+ theError.code= Err_scanAlreadyComplete;
return 1; // End-of-file
}
}
=== modified file 'storage/ndb/src/ndbapi/ndberror.c'
--- a/storage/ndb/src/ndbapi/ndberror.c 2012-01-28 09:59:44 +0000
+++ b/storage/ndb/src/ndbapi/ndberror.c 2012-06-26 10:57:31 +0000
@@ -603,6 +603,7 @@ ErrorBundle ErrorCodes[] = {
{ 4116, DMEC, AE, "Operation was not defined correctly, probably missing a key" },
{ 4117, DMEC, AE, "Could not start transporter, configuration error"},
{ 4118, DMEC, AE, "Parameter error in API call" },
+ { 4120, DMEC, AE, "Scan already complete" },
{ 4300, DMEC, AE, "Tuple Key Type not correct" },
{ 4301, DMEC, AE, "Fragment Type not correct" },
{ 4302, DMEC, AE, "Minimum Load Factor not correct" },
=== modified file 'storage/ndb/test/ndbapi/testScan.cpp'
--- a/storage/ndb/test/ndbapi/testScan.cpp 2012-04-24 14:22:40 +0000
+++ b/storage/ndb/test/ndbapi/testScan.cpp 2012-06-26 10:57:31 +0000
@@ -24,6 +24,7 @@
#include "ScanFunctions.hpp"
#include <random.h>
#include <signaldata/DumpStateOrd.hpp>
+#include <NdbConfig.hpp>
const NdbDictionary::Table *
getTable(Ndb* pNdb, int i){
@@ -1682,6 +1683,98 @@ runBug13394788(NDBT_Context* ctx, NDBT_S
return NDBT_OK;
}
+/**
+ * This is a regression test for bug #11748194 "TRANSACTION OBJECT CREATED
+ * AND UNRELEASED BY EXTRA CALL TO NEXTRESULT()".
+ * If a transaction made an extra call to nextResult() after getting
+ * end-of-scan from nextResult(), the API would leak transaction objects.
+ */
+static int
+runExtraNextResult(NDBT_Context* ctx, NDBT_Step* step)
+{
+ const NdbDictionary::Table * pTab = ctx->getTab();
+ // Fill table with 10 rows.
+ HugoTransactions hugoTrans(*pTab);
+ Ndb* const ndb = GETNDB(step);
+ hugoTrans.loadTable(ndb, 10);
+ // Read MaxNoOfConcurrentTransactions configuration value.
+ Uint32 maxTrans = 0;
+ NdbConfig conf;
+ require(conf.getProperty(conf.getMasterNodeId(),
+ NODE_TYPE_DB,
+ CFG_DB_NO_TRANSACTIONS,
+ &maxTrans));
+ require(maxTrans > 0);
+
+ /**
+ * The bug causes each scan to leak one object.
+ */
+ int result = NDBT_OK;
+ Uint32 i = 0;
+ while (i < maxTrans+1)
+ {
+ NdbTransaction* const trans = ndb->startTransaction();
+ if (trans == NULL)
+ {
+ g_err << "ndb->startTransaction() gave unexpected error : "
+ << ndb->getNdbError() << " in the " << i << "th iteration." <<endl;
+ }
+
+ // Do a random numer of scans in this transaction.
+ for (Uint32 j=0; j < random()%4; j++)
+ {
+ NdbScanOperation* const scan = trans->getNdbScanOperation(pTab);
+ if (scan == NULL)
+ {
+ g_err << "trans->getNdbScanOperation() gave unexpected error : "
+ << trans->getNdbError() << " in the " << i
+ << "th iteration." <<endl;
+ return NDBT_FAILED;
+ }
+
+ require(scan->readTuples(NdbOperation::LM_CommittedRead) == 0);
+ require(scan->getValue(0u) != 0);
+ require(trans->execute(NoCommit) == 0);
+
+ // Scan table until end.
+ int scanResult;
+ do
+ {
+ // Fetch new batch.
+ scanResult = scan->nextResult(true);
+ while (scanResult == 0)
+ {
+ // Iterate over batch.
+ scanResult = scan->nextResult(false);
+ }
+ } while (scanResult == 0 || scanResult == 2);
+
+ /**
+ * Do extra nextResult. This is the application error that triggers the
+ * bug.
+ */
+ scanResult = scan->nextResult(true);
+ require(scanResult < 0);
+ // Here we got the undefined error code -1. So check for that too.
+ // if (trans->getNdbError().code != 4120
+ if (scan->getNdbError().code != 4120
+ && result == NDBT_OK)
+ {
+ g_err << "scan->nextResult() gave unexpected error : "
+ << scan->getNdbError() << " in the " << i << "th iteration."
+ << endl;
+ result = NDBT_FAILED;
+ }
+ i++;
+ }
+ ndb->closeTransaction(trans);
+ } // while (i < maxTrans+1)
+
+ // Delete table rows.
+ require(UtilTransactions(*ctx->getTab()).clearTable(ndb) == 0);
+ return result;
+}
+
NDBT_TESTSUITE(testScan);
TESTCASE("ScanRead",
"Verify scan requirement: It should be possible "\
@@ -2247,6 +2340,11 @@ TESTCASE("Bug13394788", "")
FINALIZER(createOrderedPkIndex_Drop);
FINALIZER(runClearTable);
}
+TESTCASE("extraNextResultBug11748194",
+ "Regression test for bug #11748194")
+{
+ INITIALIZER(runExtraNextResult);
+}
NDBT_TESTSUITE_END(testScan);
int main(int argc, const char** argv){
=== modified file 'storage/ndb/test/run-test/daily-basic-tests.txt'
--- a/storage/ndb/test/run-test/daily-basic-tests.txt 2012-06-25 11:18:06 +0000
+++ b/storage/ndb/test/run-test/daily-basic-tests.txt 2012-06-26 09:18:05 +0000
@@ -1871,3 +1871,7 @@ max-time: 300
cmd: testBasic
args: -n LeakApiConnectObjects T1
+max-time: 300
+cmd: testScan
+args: -n extraNextResultBug11748194 T1
+
No bundle (reason: useless for push emails).
| Thread |
|---|
| • bzr push into mysql-5.1-telco-7.1 branch (jan.wedvik:4578 to 4579) | Jan Wedvik | 26 Jun |