List:Commits« Previous MessageNext Message »
From:Frazer Clement Date:November 6 2008 10:02pm
Subject:bzr commit into mysql-5.1 branch (frazer:2721) Bug#40241
View as plain text  
#At file:///home/frazer/bzr/mysql-5.1-telco-6.2/

 2721 Frazer Clement	2008-11-06
      Bug#40241 : NDBAPI : NdbScanOperation::getBlobHandle() fails with incorrect col
names/nums
      
      Scan operation getBlobHandle() methods have insufficient checks for bad
      column names + numbers
      
      New testcase to verify behaviour.
modified:
  storage/ndb/src/ndbapi/NdbOperationDefine.cpp
  storage/ndb/src/ndbapi/NdbOperationSearch.cpp
  storage/ndb/src/ndbapi/NdbScanOperation.cpp
  storage/ndb/test/ndbapi/testNdbApi.cpp
  storage/ndb/test/run-test/daily-basic-tests.txt

=== modified file 'storage/ndb/src/ndbapi/NdbOperationDefine.cpp'
--- a/storage/ndb/src/ndbapi/NdbOperationDefine.cpp	2008-06-03 10:00:31 +0000
+++ b/storage/ndb/src/ndbapi/NdbOperationDefine.cpp	2008-11-06 21:02:33 +0000
@@ -475,7 +475,9 @@ NdbOperation::setValue( const NdbColumnI
 {
   DBUG_ENTER("NdbOperation::setValue");
   DBUG_PRINT("enter", ("col: %s  op:%d  val: 0x%lx",
-                       tAttrInfo->m_name.c_str(), theOperationType,
+                       (tAttrInfo == NULL) ? "NULL":
+                       tAttrInfo->m_name.c_str(),
+                       theOperationType,
                        (long) aValuePassed));
 
   int tReturnCode;

=== modified file 'storage/ndb/src/ndbapi/NdbOperationSearch.cpp'
--- a/storage/ndb/src/ndbapi/NdbOperationSearch.cpp	2008-06-03 10:00:31 +0000
+++ b/storage/ndb/src/ndbapi/NdbOperationSearch.cpp	2008-11-06 21:02:33 +0000
@@ -58,7 +58,9 @@ NdbOperation::equal_impl(const NdbColumn
 {
   DBUG_ENTER("NdbOperation::equal_impl");
   DBUG_PRINT("enter", ("col: %s  op: %d  val: 0x%lx",
-                       tAttrInfo->m_name.c_str(), theOperationType,
+                       (tAttrInfo == NULL) ? "NULL" :
+                       tAttrInfo->m_name.c_str(), 
+                       theOperationType,
                        (long) aValuePassed));
   
   const char* aValue = aValuePassed;

=== modified file 'storage/ndb/src/ndbapi/NdbScanOperation.cpp'
--- a/storage/ndb/src/ndbapi/NdbScanOperation.cpp	2008-08-13 20:04:01 +0000
+++ b/storage/ndb/src/ndbapi/NdbScanOperation.cpp	2008-11-06 21:02:33 +0000
@@ -2365,31 +2365,49 @@ NdbScanOperation::takeOverScanOpNdbRecor
 NdbBlob*
 NdbScanOperation::getBlobHandle(const char* anAttrName)
 {
-  /* We need the row KeyInfo for Blobs
-   * Old Api scans have saved flags at this point
-   */
-  if (m_scanUsingOldApi)
-    m_savedScanFlagsOldApi|= SF_KeyInfo;
+  const NdbColumnImpl* col= m_currentTable->getColumn(anAttrName);
+  
+  if (col != NULL)
+  {
+    /* We need the row KeyInfo for Blobs
+     * Old Api scans have saved flags at this point
+     */
+    if (m_scanUsingOldApi)
+      m_savedScanFlagsOldApi|= SF_KeyInfo;
+    else
+      m_keyInfo= 1;
+    
+    return NdbOperation::getBlobHandle(m_transConnection, col);
+  }
   else
-    m_keyInfo= 1;
-
-  return NdbOperation::getBlobHandle(m_transConnection, 
-                                     m_currentTable->getColumn(anAttrName));
+  {
+    setErrorCode(4004);
+    return NULL;
+  }
 }
 
 NdbBlob*
 NdbScanOperation::getBlobHandle(Uint32 anAttrId)
 {
-  /* We need the row KeyInfo for Blobs 
-   * Old Api scans have saved flags at this point
-   */
-  if (m_scanUsingOldApi)
-    m_savedScanFlagsOldApi|= SF_KeyInfo;
+  const NdbColumnImpl* col= m_currentTable->getColumn(anAttrId);
+  
+  if (col != NULL)
+  {
+    /* We need the row KeyInfo for Blobs 
+     * Old Api scans have saved flags at this point
+     */
+    if (m_scanUsingOldApi)
+      m_savedScanFlagsOldApi|= SF_KeyInfo;
+    else
+      m_keyInfo= 1;
+    
+    return NdbOperation::getBlobHandle(m_transConnection, col);
+  }
   else
-    m_keyInfo= 1;
-
-  return NdbOperation::getBlobHandle(m_transConnection, 
-                                     m_currentTable->getColumn(anAttrId));
+  {
+    setErrorCode(4004);
+    return NULL;
+  }
 }
 
 NdbRecAttr*

=== modified file 'storage/ndb/test/ndbapi/testNdbApi.cpp'
--- a/storage/ndb/test/ndbapi/testNdbApi.cpp	2008-11-06 17:37:00 +0000
+++ b/storage/ndb/test/ndbapi/testNdbApi.cpp	2008-11-06 21:02:33 +0000
@@ -626,6 +626,175 @@ int runGetNdbOperationNoTab(NDBT_Context
   return NDBT_OK;
 }
 
+int runBadColNameHandling(NDBT_Context* ctx, NDBT_Step* step){
+  int result = NDBT_OK;
+  const NdbDictionary::Table* pTab = ctx->getTab();
+
+
+  Ndb* pNdb = new Ndb(&ctx->m_cluster_connection, "TEST_DB");
+  if (pNdb == NULL){
+    ndbout << "pNdb == NULL" << endl;      
+    return NDBT_FAILED;  
+  }
+  if (pNdb->init()){
+    ERR(pNdb->getNdbError());
+    delete pNdb;
+    return NDBT_FAILED;
+  }
+  
+  const int CASES= 5;
+  int i;
+
+  for (i= 0; i < CASES; i++)
+  {
+    ndbout << "Case " << i << endl;
+    NdbConnection* pCon = pNdb->startTransaction();
+    if (pCon == NULL){
+      pNdb->closeTransaction(pCon);  
+      delete pNdb;
+      return NDBT_FAILED;
+    }
+    
+    /* Cases 0-3 use PK ops, 4 + use scans */ 
+    NdbOperation* pOp = (i < 4 ? pCon->getNdbOperation(pTab->getName()):
+                         pCon->getNdbScanOperation(pTab->getName()));
+    if (pOp == NULL){
+      ERR(pCon->getNdbError());
+      pNdb->closeTransaction(pCon);  
+      delete pNdb;
+      return NDBT_FAILED;
+    }
+
+    bool failed= false;
+    int expectedError= 0;
+    HugoOperations hugoOps(*pTab);
+
+    switch(i) {
+    case 0:
+      if (pOp->readTuple() != 0){
+        ERR(pCon->getNdbError());
+        pNdb->closeTransaction(pCon);
+        delete pNdb;
+        return NDBT_FAILED;
+      }
+      
+      // getValue should fail, we check that we get correct errors
+      // in expected places.
+      expectedError= 4004;
+      failed= (pOp->getValue("MOST_IMPROBABLE^2") == NULL);
+      break;
+
+    case 1:
+      if (pOp->readTuple() != 0){
+        ERR(pCon->getNdbError());
+        pNdb->closeTransaction(pCon);
+        delete pNdb;
+        return NDBT_FAILED;
+      }
+      
+      // equal should fail, we check that we get correct errors
+      // in expected places.
+      expectedError= 4004;
+      failed= (pOp->equal("MOST_IMPROBABLE^2", 0) != 0);
+      break;
+
+    case 2:
+      if (pOp->writeTuple() != 0){
+        ERR(pCon->getNdbError());
+        pNdb->closeTransaction(pCon);
+        delete pNdb;
+        return NDBT_FAILED;
+      }
+
+      // set equality on pk columns
+      for(int a = 0; a<pTab->getNoOfColumns(); a++){
+        if (pTab->getColumn(a)->getPrimaryKey() == true){
+          if(hugoOps.equalForAttr(pOp, a, 1) != 0){
+            const NdbError err = pCon->getNdbError();
+            ERR(err);
+            pNdb->closeTransaction(pCon);
+            delete pNdb;
+            return NDBT_FAILED;
+          }
+        }
+      }
+      
+      // setValue should fail, we check that we get correct errors
+      // in expected places.
+      expectedError= 4004;
+      failed= (pOp->setValue("MOST_IMPROBABLE^2", 0) != 0);
+      break;
+
+    case 3:
+      if (pOp->readTuple() != 0){
+        ERR(pCon->getNdbError());
+        pNdb->closeTransaction(pCon);
+        delete pNdb;
+        return NDBT_FAILED;
+      }
+      
+      // getBlobHandle should fail, we check that we get correct errors
+      // in expected places.
+      expectedError= 4004;
+      failed= (pOp->getBlobHandle("MOST_IMPROBABLE^2") == NULL);
+      break;
+
+    case 4:
+    {
+      NdbScanOperation* sop= (NdbScanOperation*) pOp;
+      if (sop->readTuples() != 0){
+        ERR(pCon->getNdbError());
+        pNdb->closeTransaction(pCon);
+        delete pNdb;
+        return NDBT_FAILED;
+      }
+      
+      // getBlobHandle should fail, we check that we get correct errors
+      // in expected places.
+      expectedError= 4004;
+      ndbout << "About to call getBlobHandle" << endl;
+      failed= (sop->getBlobHandle("MOST_IMPROBABLE^2") == NULL);
+
+      sop->close();
+      break;
+    } 
+    
+    default:
+      break;
+    }
+
+    if (failed)
+    {
+      const NdbError opErr= pOp->getNdbError();
+      const NdbError transErr = pCon->getNdbError();
+      ERR(opErr);
+      ERR(transErr);
+      if (opErr.code != transErr.code) {
+        ndbout << "Error reporting mismatch, expected " 
+               << expectedError << endl;
+        result = NDBT_FAILED;
+      }
+      if (opErr.code != expectedError){
+        ndbout << "No or bad error detected, expected " 
+               << expectedError << endl;
+        result = NDBT_FAILED;	
+      }
+    } else {
+      ndbout << "Case " << i << " did not fail" << endl;
+      result = NDBT_FAILED;
+    }
+
+    pNdb->closeTransaction(pCon);
+
+    if (result == NDBT_FAILED)
+      break;
+  } // for
+  
+  delete pNdb;
+
+  return result;
+}
+
 int runMissingOperation(NDBT_Context* ctx, NDBT_Step* step){
   int result = NDBT_OK;
   const NdbDictionary::Table* pTab = ctx->getTab();
@@ -1854,6 +2023,10 @@ TESTCASE("GetOperationNoTab", 
 	"Call getNdbOperation on a table that does not exist\n"){ 
   INITIALIZER(runGetNdbOperationNoTab);
 }
+TESTCASE("BadColNameHandling",
+         "Call methods with an invalid column name and check error handling\n"){
+  INITIALIZER(runBadColNameHandling);
+}
 TESTCASE("MissingOperation", 
 	"Missing operation request(insertTuple) should give an error code\n"){ 
   INITIALIZER(runMissingOperation);

=== modified file 'storage/ndb/test/run-test/daily-basic-tests.txt'
--- a/storage/ndb/test/run-test/daily-basic-tests.txt	2008-08-11 10:41:11 +0000
+++ b/storage/ndb/test/run-test/daily-basic-tests.txt	2008-11-06 21:02:33 +0000
@@ -765,6 +765,10 @@ cmd: testNdbApi
 args: -n Bug28443
 
 max-time: 500
+cmd: testNdbApi
+args: -n BadColNameHandling T6
+
+max-time: 500
 cmd: testInterpreter
 args: T1 
 
@@ -1167,3 +1171,4 @@ cmd: test_event
 args -r 5000 -n Bug30780 T1
 
 #EOF 2008-08-11
+

Thread
bzr commit into mysql-5.1 branch (frazer:2721) Bug#40241Frazer Clement6 Nov