List:Commits« Previous MessageNext Message »
From:Jan Wedvik Date:June 26 2012 10:58am
Subject:bzr push into mysql-5.1-telco-7.1 branch (jan.wedvik:4578 to 4579)
View as plain text  
 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 Wedvik26 Jun