=== modified file 'storage/ndb/src/ndbapi/NdbOperationDefine.cpp' --- storage/ndb/src/ndbapi/NdbOperationDefine.cpp 2008-06-03 10:00:31 +0000 +++ storage/ndb/src/ndbapi/NdbOperationDefine.cpp 2008-10-22 12:11:49 +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' --- storage/ndb/src/ndbapi/NdbOperationSearch.cpp 2008-06-03 10:00:31 +0000 +++ storage/ndb/src/ndbapi/NdbOperationSearch.cpp 2008-10-22 12:11:52 +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' --- storage/ndb/src/ndbapi/NdbScanOperation.cpp 2008-08-13 20:04:01 +0000 +++ storage/ndb/src/ndbapi/NdbScanOperation.cpp 2008-10-22 12:14:37 +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' --- storage/ndb/test/ndbapi/testNdbApi.cpp 2008-06-03 12:37:17 +0000 +++ storage/ndb/test/ndbapi/testNdbApi.cpp 2008-10-22 12:16:27 +0000 @@ -628,6 +628,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; agetNoOfColumns(); 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(); @@ -1769,6 +1938,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' --- storage/ndb/test/run-test/daily-basic-tests.txt 2008-08-11 10:41:11 +0000 +++ storage/ndb/test/run-test/daily-basic-tests.txt 2008-10-22 12:17:39 +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 +