From: Date: July 3 2009 5:21pm Subject: bzr commit into mysql-5.1-telco-7.1 branch (frazer:2930) List-Archive: http://lists.mysql.com/commits/77923 Message-Id: <200907031521.n63FLLDP014393@localhost.localdomain> MIME-Version: 1.0 Content-Type: text/plain; CHARSET=US-ASCII Content-Transfer-Encoding: 7BIT #At file:///home/frazer/bzr/mysql-5.1-telco-7.1/ 2930 Frazer Clement 2009-07-03 [merge] Merge 7.0->7.1 modified: storage/ndb/test/include/NDBT_Test.hpp storage/ndb/test/ndbapi/testIndex.cpp storage/ndb/test/src/NDBT_Test.cpp storage/ndb/test/tools/create_index.cpp === modified file 'storage/ndb/test/include/NDBT_Test.hpp' --- a/storage/ndb/test/include/NDBT_Test.hpp 2009-05-27 15:21:45 +0000 +++ b/storage/ndb/test/include/NDBT_Test.hpp 2009-07-03 15:08:14 +0000 @@ -414,6 +414,7 @@ private: bool temporaryTables; bool m_logging; NDBT_DriverType m_driverType; + bool m_noddl; }; === modified file 'storage/ndb/test/ndbapi/testIndex.cpp' --- a/storage/ndb/test/ndbapi/testIndex.cpp 2009-05-27 15:21:45 +0000 +++ b/storage/ndb/test/ndbapi/testIndex.cpp 2009-07-03 15:08:14 +0000 @@ -197,21 +197,42 @@ int create_index(NDBT_Context* ctx, int pIdx.setStoredIndex(logged); ndbout << ") "; - if (pNdb->getDictionary()->createIndex(pIdx) != 0){ - attr->indexCreated = false; - ndbout << "FAILED!" << endl; - const NdbError err = pNdb->getDictionary()->getNdbError(); - ERR(err); - if (err.classification == NdbError::ApplicationError) - return SKIP_INDEX; + bool noddl= ctx->getProperty("NoDDL"); - if (err.status == NdbError::TemporaryError) - return SKIP_INDEX; - - return NDBT_FAILED; - } else { - ndbout << "OK!" << endl; - attr->indexCreated = true; + if (noddl) + { + const NdbDictionary::Index* idx= pNdb-> + getDictionary()->getIndex(pIdx.getName(), pTab->getName()); + + if (!idx) + { + ndbout << "Failed - Index does not exist and DDL not allowed" << endl; + return NDBT_FAILED; + } + else + { + attr->indexCreated = false; + // TODO : Check index definition is ok + } + } + else + { + if (pNdb->getDictionary()->createIndex(pIdx) != 0){ + attr->indexCreated = false; + ndbout << "FAILED!" << endl; + const NdbError err = pNdb->getDictionary()->getNdbError(); + ERR(err); + if (err.classification == NdbError::ApplicationError) + return SKIP_INDEX; + + if (err.status == NdbError::TemporaryError) + return SKIP_INDEX; + + return NDBT_FAILED; + } else { + ndbout << "OK!" << endl; + attr->indexCreated = true; + } } return result; } @@ -337,7 +358,8 @@ int createPkIndex(NDBT_Context* ctx, NDB Ndb* pNdb = GETNDB(step); bool logged = ctx->getProperty("LoggedIndexes", 1); - + bool noddl= ctx->getProperty("NoDDL"); + // Create index BaseString::snprintf(pkIdxName, 255, "IDC_PK_%s", pTab->getName()); if (orderedIndex) @@ -363,11 +385,30 @@ int createPkIndex(NDBT_Context* ctx, NDB pIdx.setStoredIndex(logged); ndbout << ") "; - if (pNdb->getDictionary()->createIndex(pIdx) != 0){ - ndbout << "FAILED!" << endl; - const NdbError err = pNdb->getDictionary()->getNdbError(); - ERR(err); - return NDBT_FAILED; + if (noddl) + { + const NdbDictionary::Index* idx= pNdb-> + getDictionary()->getIndex(pkIdxName, pTab->getName()); + + if (!idx) + { + ndbout << "Failed - Index does not exist and DDL not allowed" << endl; + ERR(pNdb->getDictionary()->getNdbError()); + return NDBT_FAILED; + } + else + { + // TODO : Check index definition is ok + } + } + else + { + if (pNdb->getDictionary()->createIndex(pIdx) != 0){ + ndbout << "FAILED!" << endl; + const NdbError err = pNdb->getDictionary()->getNdbError(); + ERR(err); + return NDBT_FAILED; + } } ndbout << "OK!" << endl; @@ -378,15 +419,20 @@ int createPkIndex_Drop(NDBT_Context* ctx const NdbDictionary::Table* pTab = ctx->getTab(); Ndb* pNdb = GETNDB(step); + bool noddl= ctx->getProperty("NoDDL"); + // Drop index - ndbout << "Dropping index " << pkIdxName << " "; - if (pNdb->getDictionary()->dropIndex(pkIdxName, - pTab->getName()) != 0){ - ndbout << "FAILED!" << endl; - ERR(pNdb->getDictionary()->getNdbError()); - return NDBT_FAILED; - } else { - ndbout << "OK!" << endl; + if (!noddl) + { + ndbout << "Dropping index " << pkIdxName << " "; + if (pNdb->getDictionary()->dropIndex(pkIdxName, + pTab->getName()) != 0){ + ndbout << "FAILED!" << endl; + ERR(pNdb->getDictionary()->getNdbError()); + return NDBT_FAILED; + } else { + ndbout << "OK!" << endl; + } } return NDBT_OK; @@ -886,6 +932,17 @@ int runSystemRestart1(NDBT_Context* ctx, } #define CHECK2(b, t) if(!b){ g_err << __LINE__ << ": " << t << endl; break;} +#define CHECKOKORTIMEOUT(e, t) { int rc= (e); \ + if (rc != 0) { \ + if (rc == 266) { \ + g_err << "Timeout : retries left : " \ + << timeoutRetries \ + << endl; \ + continue; \ + } \ + g_err << __LINE__ << ": " << (t) << endl; break; \ + } } + int runMixed1(NDBT_Context* ctx, NDBT_Step* step){ @@ -894,6 +951,7 @@ runMixed1(NDBT_Context* ctx, NDBT_Step* Ndb* pNdb = GETNDB(step); HugoOperations hugoOps(*ctx->getTab()); + /* Old, rather ineffective testcase which nonetheless passes on 6.3 */ do { // TC1 @@ -949,6 +1007,413 @@ runMixed1(NDBT_Context* ctx, NDBT_Step* return NDBT_FAILED; } + + +int +runMixedUpdateInterleaved(Ndb* pNdb, + HugoOperations& hugoOps, + int outOfRangeRec, + int testSize, + bool commit, + bool abort, + int pkFailRec, + int ixFailRec, + bool invertFail, + AbortOption ao, + int whatToUpdate, + int updatesValue, + bool ixFirst) +{ + Uint32 execRc= 0; + if ((pkFailRec != -1) || (ixFailRec != -1)) + { + execRc= 626; + } + + bool updateViaPk= whatToUpdate & 1; + bool updateViaIx= whatToUpdate & 2; + + int ixOpNum= (ixFirst?0:1); + int pkOpNum= (ixFirst?1:0); + + int timeoutRetries= 3; + + while (timeoutRetries--) + { + CHECK2(hugoOps.startTransaction(pNdb) == 0, "startTransaction"); + for (int i=0; i < testSize; i++) + { + /* invertFail causes all issued reads *except* the fail record number + * to fail + */ + int indxKey= ((i == ixFailRec)^invertFail)? outOfRangeRec : i; + int pkKey= ((i == pkFailRec)^invertFail)? outOfRangeRec : i; + + for (int opNum=0; opNum < 2; opNum++) + { + if (opNum == ixOpNum) + { + if (updateViaIx) + { + CHECK2(hugoOps.indexUpdateRecord(pNdb, pkIdxName, indxKey, 1, updatesValue) == 0, + "indexUpdateRecord"); + } + else + { + CHECK2(hugoOps.indexReadRecords(pNdb, pkIdxName, indxKey) == 0, "indexReadRecords"); + } + } + + if (opNum == pkOpNum) + { + if (updateViaPk) + { + CHECK2(hugoOps.pkUpdateRecord(pNdb, pkKey, 1, updatesValue) == 0, + "pkUpdateRecord"); + } + else + { + CHECK2(hugoOps.pkReadRecord(pNdb, pkKey) == 0, "pkReadRecord"); + } + } + } + } + if (commit) + { + int rc= hugoOps.execute_Commit(pNdb, ao); + if (rc == 266) + { + /* Timeout */ + g_err << "Timeout : retries left=" << timeoutRetries << endl; + hugoOps.closeTransaction(pNdb); + continue; + } + CHECK2(rc == execRc, "execute_Commit"); + NdbError err= hugoOps.getTransaction()->getNdbError(); + CHECK2(err.code == execRc, "getNdbError"); + } + else + { + int rc= hugoOps.execute_NoCommit(pNdb, ao); + if (rc == 266) + { + /* Timeout */ + g_err << "Timeout : retries left=" << timeoutRetries << endl; + hugoOps.closeTransaction(pNdb); + continue; + } + CHECK2(rc == execRc, "execute_NoCommit"); + NdbError err= hugoOps.getTransaction()->getNdbError(); + CHECK2(err.code == execRc, "getNdbError"); + if (execRc && (ao == AO_IgnoreError)) + { + /* Transaction should still be open, let's commit it */ + CHECK2(hugoOps.execute_Commit(pNdb, ao) == 0, "executeCommit"); + } + else if (abort) + { + CHECK2(hugoOps.execute_Rollback(pNdb) == 0, "executeRollback"); + } + } + CHECK2(hugoOps.closeTransaction(pNdb) == 0, "closeTransaction"); + + return 1; + } + + hugoOps.closeTransaction(pNdb); + return 0; +} + + + +int +runMixed2(NDBT_Context* ctx, NDBT_Step* step){ + Ndb* pNdb = GETNDB(step); + HugoOperations hugoOps(*ctx->getTab()); + + int numRecordsInTable= ctx->getNumRecords(); + const int maxTestSize= 10000; + int testSize= MIN(numRecordsInTable, maxTestSize); + + /* Avoid overloading Send Buffers */ + Uint32 rowSize= NdbDictionary::getRecordRowLength(ctx->getTab()->getDefaultRecord()); + Uint32 dataXfer= 2 * rowSize * testSize; + const Uint32 MaxDataXfer= 500000; // 0.5M + + if (dataXfer > MaxDataXfer) + { + testSize= MIN((int)(MaxDataXfer/rowSize), testSize); + } + + g_err << "testSize= " << testSize << endl; + g_err << "rowSize= " << rowSize << endl; + + int updatesValue= 1; + const int maxTimeoutRetries= 3; + + do { + // TC0 + { + bool ok= false; + int timeoutRetries= maxTimeoutRetries; + while (timeoutRetries--) + { + g_err << "TC0 : indexRead, pkread, Commit" << endl; + CHECK2(hugoOps.startTransaction(pNdb) == 0, "startTransaction"); + CHECK2(hugoOps.indexReadRecords(pNdb, pkIdxName, 0, false, testSize) == 0, "indexReadRecords"); + CHECK2(hugoOps.pkReadRecord(pNdb, 0, testSize) == 0, "pkReadRecord"); + CHECKOKORTIMEOUT(hugoOps.execute_Commit(pNdb), "executeCommit"); + CHECK2(hugoOps.closeTransaction(pNdb) == 0, "closeTransaction"); + + ok= true; + break; + } + if (!ok) { break; }; + } + + + // TC1 + { + bool ok= false; + int timeoutRetries= maxTimeoutRetries; + while (timeoutRetries--) + { + g_err << "TC1 : pkRead, indexRead, Commit" << endl; + CHECK2(hugoOps.startTransaction(pNdb) == 0, "startTransaction"); + CHECK2(hugoOps.pkReadRecord(pNdb, 0, testSize) == 0, "pkReadRecord"); + CHECK2(hugoOps.indexReadRecords(pNdb, pkIdxName, 0, false, testSize) == 0, "indexReadRecords"); + CHECKOKORTIMEOUT(hugoOps.execute_Commit(pNdb), "executeCommit"); + CHECK2(hugoOps.closeTransaction(pNdb) == 0, "closeTransaction"); + + ok= true; + break; + } + if (!ok) { break; }; + } + + // TC2 + { + bool ok= false; + int timeoutRetries= maxTimeoutRetries; + while (timeoutRetries--) + { + g_err << "TC2 : pkRead, indexRead, NoCommit, Commit" << endl; + CHECK2(hugoOps.startTransaction(pNdb) == 0, "startTransaction"); + CHECK2(hugoOps.pkReadRecord(pNdb, 0, testSize) == 0, "pkReadRecord"); + CHECK2(hugoOps.indexReadRecords(pNdb, pkIdxName, 0, false, testSize) == 0, + "indexReadRecords"); + CHECKOKORTIMEOUT(hugoOps.execute_NoCommit(pNdb), "executeNoCommit"); + CHECK2(hugoOps.execute_Commit(pNdb) == 0, "executeCommit"); + CHECK2(hugoOps.closeTransaction(pNdb) == 0, "closeTransaction"); + ok= true; + break; + } + if (!ok) { break; }; + } + + // TC3 + { + bool ok= false; + int timeoutRetries= maxTimeoutRetries; + while (timeoutRetries--) + { + g_err << "TC3 : pkRead, pkRead, Commit" << endl; + CHECK2(hugoOps.startTransaction(pNdb) == 0, "startTransaction "); + CHECK2(hugoOps.pkReadRecord(pNdb, 0, testSize) == 0, "pkReadRecords "); + CHECK2(hugoOps.pkReadRecord(pNdb, 0, testSize) == 0, "pkReadRecords "); + CHECKOKORTIMEOUT(hugoOps.execute_Commit(pNdb), "executeCommit"); + CHECK2(hugoOps.closeTransaction(pNdb) == 0, "closeTransaction "); + ok= true; + break; + } + if (!ok) { break; }; + } + + // TC4 + { + bool ok= false; + int timeoutRetries= maxTimeoutRetries; + while (timeoutRetries--) + { + g_err << "TC4 : indexRead, indexRead, Commit" << endl; + CHECK2(hugoOps.startTransaction(pNdb) == 0, "startTransaction "); + CHECK2(hugoOps.indexReadRecords(pNdb, pkIdxName, 0, false, testSize) == 0, "indexReadRecords"); + CHECK2(hugoOps.indexReadRecords(pNdb, pkIdxName, 0, false, testSize) == 0, "indexReadRecords"); + CHECKOKORTIMEOUT(hugoOps.execute_Commit(pNdb), "executeCommit"); + CHECK2(hugoOps.closeTransaction(pNdb) == 0, "closeTransaction "); + ok= true; + break; + } + if (!ok) { break; }; + } + + // TC5 + { + bool ok= false; + int timeoutRetries= maxTimeoutRetries; + while (timeoutRetries--) + { + g_err << "TC5 : indexRead, pkUpdate, Commit" << endl; + CHECK2(hugoOps.startTransaction(pNdb) == 0, "startTransaction"); + CHECK2(hugoOps.indexReadRecords(pNdb, pkIdxName, 0, false, testSize) == 0, "indexReadRecords"); + CHECK2(hugoOps.pkUpdateRecord(pNdb, 0, testSize, updatesValue++) == 0, "pkUpdateRecord"); + CHECKOKORTIMEOUT(hugoOps.execute_Commit(pNdb), "executeCommit"); + CHECK2(hugoOps.closeTransaction(pNdb) == 0, "closeTransaction"); + ok= true; + break; + } + if (!ok) { break; }; + } + + // TC6 + { + bool ok= false; + int timeoutRetries= maxTimeoutRetries; + while (timeoutRetries--) + { + g_err << "TC6 : pkUpdate, indexRead, Commit" << endl; + CHECK2(hugoOps.startTransaction(pNdb) == 0, "startTransaction"); + CHECK2(hugoOps.pkUpdateRecord(pNdb, 0, testSize, updatesValue++) == 0, "pkUpdateRecord"); + CHECK2(hugoOps.indexReadRecords(pNdb, pkIdxName, 0, false, testSize) == 0, "indexReadRecords"); + CHECKOKORTIMEOUT(hugoOps.execute_Commit(pNdb), "executeCommit"); + CHECK2(hugoOps.closeTransaction(pNdb) == 0, "closeTransaction"); + ok= true; + break; + } + if (!ok) { break; }; + } + + // TC7 + { + bool ok= false; + int timeoutRetries= maxTimeoutRetries; + while (timeoutRetries--) + { + g_err << "TC7 : pkRead, indexUpdate, Commit" << endl; + CHECK2(hugoOps.startTransaction(pNdb) == 0, "startTransaction"); + CHECK2(hugoOps.pkReadRecord(pNdb, 0, testSize) == 0, "pkReadRecord"); + CHECK2(hugoOps.indexUpdateRecord(pNdb, pkIdxName, 0, testSize, updatesValue++) == 0, + "indexReadRecords"); + CHECKOKORTIMEOUT(hugoOps.execute_Commit(pNdb), "executeCommit"); + CHECK2(hugoOps.closeTransaction(pNdb) == 0, "closeTransaction"); + ok= true; + break; + } + if (!ok) { break; }; + } + + // TC8 + { + bool ok= false; + int timeoutRetries= maxTimeoutRetries; + while (timeoutRetries--) + { + g_err << "TC8 : indexUpdate, pkRead, Commit" << endl; + CHECK2(hugoOps.startTransaction(pNdb) == 0, "startTransaction "); + CHECK2(hugoOps.indexUpdateRecord(pNdb, pkIdxName, 0, testSize, updatesValue++) == 0, + "indexReadRecords "); + CHECK2(hugoOps.pkReadRecord(pNdb, 0, testSize) == 0, "pkReadRecords "); + CHECKOKORTIMEOUT(hugoOps.execute_Commit(pNdb), "executeCommit"); + CHECK2(hugoOps.closeTransaction(pNdb) == 0, "closeTransaction "); + ok= true; + break; + } + if (!ok) { break; }; + } + + for (int ao=0; ao < 2; ao++) + { + AbortOption abortOption= ao?AO_IgnoreError:AbortOnError; + + for (int exType=0; exType < 3; exType++) + { + bool commit= (exType == 1); + bool abort= (exType == 2); + + const char* exTypeStr= ((exType == 0) ? "NoCommit" : + (exType == 1) ? "Commit" : + "Abort"); + + for (int failType= 0; failType < 4; failType++) + { + for (int failPos= 0; failPos < 2; failPos++) + { + int failRec= (failPos == 0)? 0 : testSize -1; + int pkFailRec= -1; + int ixFailRec= -1; + if (failType) + { + if (failType & 1) + pkFailRec= failRec; + if (failType & 2) + ixFailRec= failRec; + } + + for (int invFail= 0; + invFail < ((failType==0)?1:2); + invFail++) + { + bool invertFail= (invFail)?true:false; + const char* failTypeStr= ((failType==0)? "None" : + ((failType==1)? "Pk": + ((failType==2)?"Ix": "Both"))); + for (int updateVia= 0; updateVia < 3; updateVia++) + { + const char* updateViaStr= ((updateVia == 0)? "None" : + (updateVia == 1)? "Pk" : + (updateVia == 2)? "Ix" : + "Both"); + for (int updateOrder= 0; updateOrder < 2; updateOrder++) + { + bool updateIxFirst= (updateOrder == 0); + g_err << endl + << "AbortOption : " << (ao?"IgnoreError":"AbortOnError") << endl + << "ExecType : " << exTypeStr << endl + << "Failtype : " << failTypeStr << endl + << "Failpos : " << ((failPos == 0)? "Early" : "Late") << endl + << "Failure scenarios : " << (invFail?"All but one":"one") << endl + << "UpdateVia : " << updateViaStr << endl + << "Order : " << (updateIxFirst? "Index First" : "Pk first") << endl; + bool ok= false; + do + { + g_err << "Mixed read/update interleaved" << endl; + CHECK2(runMixedUpdateInterleaved(pNdb, hugoOps, numRecordsInTable, testSize, + commit, // Commit + abort, // Abort + pkFailRec, // PkFail + ixFailRec, // IxFail + invertFail, // Invertfail + abortOption, + updateVia, + updatesValue++, + updateIxFirst), + "TC4"); + + ok= true; + } while (false); + + if (!ok) + { + hugoOps.closeTransaction(pNdb); + return NDBT_FAILED; + } + } + } + } + } + } + } + } + + return NDBT_OK; + } while (false); + + hugoOps.closeTransaction(pNdb); + return NDBT_FAILED; +} + + int runBuildDuring(NDBT_Context* ctx, NDBT_Step* step){ // Verify that data in index match @@ -1138,13 +1603,33 @@ runUniqueNullTransactions(NDBT_Context* return NDBT_FAILED; } - if (pNdb->getDictionary()->createIndex(pIdx) != 0){ - ndbout << "FAILED!" << endl; - const NdbError err = pNdb->getDictionary()->getNdbError(); - ERR(err); - return NDBT_FAILED; + bool noddl= ctx->getProperty("NoDDL"); + if (noddl) + { + const NdbDictionary::Index* idx= pNdb-> + getDictionary()->getIndex(pIdx.getName(), pTab->getName()); + + if (!idx) + { + ndbout << "Failed - Index does not exist and DDL not allowed" << endl; + ERR(pNdb->getDictionary()->getNdbError()); + return NDBT_FAILED; + } + else + { + // TODO : Check index definition is ok + } } - + else + { + if (pNdb->getDictionary()->createIndex(pIdx) != 0){ + ndbout << "FAILED!" << endl; + const NdbError err = pNdb->getDictionary()->getNdbError(); + ERR(err); + return NDBT_FAILED; + } + } + int result = NDBT_OK; HugoTransactions hugoTrans(*ctx->getTab()); @@ -1693,6 +2178,16 @@ TESTCASE("MixedTransaction", FINALIZER(createPkIndex_Drop); FINALIZER(runClearTable); } +TESTCASE("MixedTransaction2", + "Test mixing of index and normal operations with batching"){ + TC_PROPERTY("LoggedIndexes", (unsigned)0); + INITIALIZER(runClearTable); + INITIALIZER(createPkIndex); + INITIALIZER(runLoadTable); + STEP(runMixed2); + FINALIZER(createPkIndex_Drop); + FINALIZER(runClearTable); +} TESTCASE("SR1_O", "Test that indexes are correctly maintained during SR"){ TC_PROPERTY("OrderedIndex", 1); === modified file 'storage/ndb/test/src/NDBT_Test.cpp' --- a/storage/ndb/test/src/NDBT_Test.cpp 2009-05-27 15:21:45 +0000 +++ b/storage/ndb/test/src/NDBT_Test.cpp 2009-07-03 15:08:14 +0000 @@ -790,6 +790,7 @@ NDBT_TestSuite::NDBT_TestSuite(const cha tsname = NULL; temporaryTables = false; runonce = false; + m_noddl = false; } @@ -876,6 +877,7 @@ int NDBT_TestSuite::executeAll(Ndb_clust ctx->setNumRecords(records); ctx->setNumLoops(loops); ctx->setSuite(this); + ctx->setProperty("NoDDL", (Uint32) m_noddl); int result = tests[i]->execute(ctx); @@ -951,6 +953,7 @@ NDBT_TestSuite::executeOneCtx(Ndb_cluste ctx->setNumRecords(records); ctx->setNumLoops(loops); ctx->setSuite(this); + ctx->setProperty("NoDDL", (Uint32) m_noddl); result = tests[t]->execute(ctx); if (result != NDBT_OK) @@ -1026,6 +1029,7 @@ void NDBT_TestSuite::execute(Ndb_cluster ctx->setNumLoops(loops); ctx->setSuite(this); ctx->setTab(pTab); + ctx->setProperty("NoDDL", (Uint32) m_noddl); result = tests[t]->execute(ctx); tests[t]->saveTestResult(pTab->getName(), result); @@ -1127,7 +1131,6 @@ NDBT_TestSuite::dropTables(Ndb_cluster_c Ndb ndb(&con, "TEST_DB"); ndb.init(1); - int res= NDBT_OK; NdbDictionary::Dictionary* pDict = ndb.getDictionary(); for(unsigned i = 0; im_cluster_connection, "TEST_DB"); ndb.init(1); - int res= NDBT_OK; NdbDictionary::Dictionary* pDict = ndb.getDictionary(); pDict->dropTable(tab_name); } return NDBT_OK; } + +static int +runCheckTableExists(NDBT_Context* ctx, NDBT_Step* step) +{ + Ndb ndb(&ctx->m_cluster_connection, "TEST_DB"); + ndb.init(1); + + NdbDictionary::Dictionary* pDict = ndb.getDictionary(); + const NdbDictionary::Table* pTab = ctx->getTab(); + const char *tab_name= pTab->getName(); + + const NdbDictionary::Table* pDictTab = pDict->getTable(tab_name); + + if (pDictTab == NULL) + { + g_err << "runCheckTableExists : Failed to find table " + << tab_name << endl; + g_err << "Required schema : " << *((NDBT_Table*)pTab) << endl; + return NDBT_FAILED; + } + + /* Todo : better check that table in DB is same as + * table we expect + */ + + // Update ctx with a pointer to dict table + ctx->setTab(pDictTab); + ctx->setProperty("$table", tab_name); + + return NDBT_OK; +} + +static int +runEmptyDropTable(NDBT_Context* ctx, NDBT_Step* step) +{ + return NDBT_OK; +} + int NDBT_TestSuite::report(const char* _tcname){ int result; @@ -1239,6 +1279,7 @@ static int opt_verbose; static int opt_seed = 0; static int opt_nologging = 0; static int opt_temporary = 0; +static int opt_noddl = 0; static struct my_option my_long_options[] = { @@ -1276,6 +1317,9 @@ static struct my_option my_long_options[ { "nologging", 0, "Create table(s) wo/ logging", (uchar **) &opt_nologging, (uchar **) &opt_nologging, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0 }, + { "noddl", 0, "Don't create/drop tables as part of running tests", + (uchar**) &opt_noddl, (uchar**) &opt_noddl, 0, + GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0 }, { 0, 0, 0, 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0} }; @@ -1345,6 +1389,7 @@ int NDBT_TestSuite::execute(int argc, co if (opt_nologging) setLogging(false); temporaryTables = opt_temporary; + m_noddl = opt_noddl; if (opt_seed == 0) { @@ -1375,16 +1420,39 @@ int NDBT_TestSuite::execute(int argc, co { for (unsigned t = 0; t < tests.size(); t++) { + const char* createFuncName= NULL; + NDBT_TESTFUNC* createFunc= NULL; + const char* dropFuncName= NULL; + NDBT_TESTFUNC* dropFunc= NULL; + + if (!m_noddl) + { + createFuncName= m_createAll ? "runCreateTable" : "runCreateTable"; + createFunc= m_createAll ? &runCreateTables : &runCreateTable; + dropFuncName= m_createAll ? "runDropTables" : "runDropTable"; + dropFunc= m_createAll ? &runDropTables : &runDropTable; + } + else + { + /* No DDL allowed, so we substitute 'do nothing' variants + * of the create + drop table test procs + */ + createFuncName= "runCheckTableExists"; + createFunc= &runCheckTableExists; + dropFuncName= "runEmptyDropTable"; + dropFunc= &runEmptyDropTable; + } + NDBT_TestCaseImpl1* pt= (NDBT_TestCaseImpl1*)tests[t]; NDBT_Initializer* pti = new NDBT_Initializer(pt, - m_createAll ? "runCreateTables" : "runCreateTable", - m_createAll ? runCreateTables : runCreateTable); + createFuncName, + *createFunc); pt->addInitializer(pti, true); NDBT_Finalizer* ptf = new NDBT_Finalizer(pt, - m_createAll ? "runDropTables" : "runDropTable", - m_createAll ? runDropTables : runDropTable); + dropFuncName, + *dropFunc); pt->addFinalizer(ptf); } } === modified file 'storage/ndb/test/tools/create_index.cpp' --- a/storage/ndb/test/tools/create_index.cpp 2009-05-26 18:53:34 +0000 +++ b/storage/ndb/test/tools/create_index.cpp 2009-07-03 14:15:09 +0000 @@ -33,12 +33,16 @@ main(int argc, const char** argv){ const char* _dbname = "TEST_DB"; int _help = 0; int _ordered = 0, _pk = 1; + char* _iname= NULL; + char* _tname= NULL; struct getargs args[] = { { "database", 'd', arg_string, &_dbname, "dbname", "Name of database table is in"}, { "ordered", 'o', arg_flag, &_ordered, "Create ordered index", "" }, { "pk", 'p', arg_flag, &_pk, "Create index on primary key", "" }, + { "idxname", 'i', arg_string, &_iname, "idxname", "Override default name for index" }, + { "tabname", 't', arg_string, &_tname, "tabname", "Specify single tabname and list of col names as args" }, { "usage", '?', arg_flag, &_help, "Print help", "" } }; @@ -73,16 +77,15 @@ main(int argc, const char** argv){ NdbDictionary::Dictionary * dict = MyNdb.getDictionary(); for(int i = optind; igetTable(argv[i]); + const char* tabName= (_tname)? _tname : argv[i]; + const NdbDictionary::Table * tab = dict->getTable(tabName); if(tab == 0){ - g_err << "Unknown table: " << argv[i] << endl; + g_err << "Unknown table: " << tabName << endl; + if (_tname) + return NDBT_ProgramExit(NDBT_FAILED); continue; } - if(tab->getNoOfColumns() > 16){ - g_err << "Table " << argv[i] << " has more than 16 columns" << endl; - } - NdbDictionary::Index ind; if(_ordered){ ind.setType(NdbDictionary::Index::OrderedIndex); @@ -91,20 +94,59 @@ main(int argc, const char** argv){ ind.setType(NdbDictionary::Index::UniqueHashIndex); } char buf[512]; - sprintf(buf, "IND_%s_%s_%c", - argv[i], (_pk ? "PK" : "FULL"), (_ordered ? 'O' : 'U')); - ind.setName(buf); - ind.setTable(argv[i]); - for(int c = 0; cgetNoOfColumns(); c++){ - if(!_pk || tab->getColumn(c)->getPrimaryKey()) - ind.addIndexColumn(tab->getColumn(c)->getName()); + if (!_iname) + { + sprintf(buf, "IND_%s_%s_%c", + argv[i], (_pk ? "PK" : "FULL"), (_ordered ? 'O' : 'U')); + ind.setName(buf); + } + else + { + ind.setName(_iname); + } + + ind.setTable(tabName); + + if (!_tname) + { + ndbout << "creating index " << ind.getName() << " on table " << tabName + << "("; + for(int c = 0; cgetNoOfColumns(); c++){ + if(!_pk || tab->getColumn(c)->getPrimaryKey()) + { + ndbout << tab->getColumn(c)->getName() << ", "; + ind.addIndexColumn(tab->getColumn(c)->getName()); + } + } + ndbout << ")" << endl; + } + else + { + /* Treat args as column names */ + ndbout << "creating index " << ind.getName() << " on table " << tabName + << "("; + for(int argNum=i; argNum < argc; argNum++) + { + const char* colName= argv[argNum]; + if (tab->getColumn(colName) == NULL) + { + g_err << "Column " << colName << " does not exist in table " << tabName + << endl; + return NDBT_ProgramExit(NDBT_FAILED); + } + ndbout << colName << ", "; + ind.addIndexColumn(colName); + } + ndbout << ")" << endl; } - ndbout << "creating index " << buf << " on table " << argv[i] << "..."; const int res = dict->createIndex(ind); if(res != 0) ndbout << endl << dict->getNdbError() << endl; else ndbout << "OK" << endl; + + if (_tname) // Just create a single index + return NDBT_ProgramExit(NDBT_OK); } return NDBT_ProgramExit(NDBT_OK);