diff options
author | unknown <monty@mysql.com> | 2004-09-06 15:14:10 +0300 |
---|---|---|
committer | unknown <monty@mysql.com> | 2004-09-06 15:14:10 +0300 |
commit | 4ad51359c1b7b5ed854f1af8df06fd6912068d28 (patch) | |
tree | d9ef905036723648a1d354d0523ef8124e4dee76 /ndb/test | |
parent | fa3bfbe45796edd85cce30e62ff1fcfb81df745c (diff) | |
parent | 9a63c8e0e468d7a64dcb7e23f4e5c344eebf635b (diff) | |
download | mariadb-git-4ad51359c1b7b5ed854f1af8df06fd6912068d28.tar.gz |
Merge with 4.1
(Includes merge of arena code in 4.1 and 5.0)
BitKeeper/etc/ignore:
auto-union
BitKeeper/etc/logging_ok:
auto-union
VC++Files/sql/mysqld.dsp:
Auto merged
client/mysql.cc:
Auto merged
client/mysqltest.c:
Auto merged
include/my_global.h:
Auto merged
include/my_sys.h:
Auto merged
include/mysql.h:
Auto merged
include/mysql_com.h:
Auto merged
innobase/row/row0sel.c:
Auto merged
libmysql/client_settings.h:
Auto merged
libmysql/libmysql.c:
Auto merged
libmysqld/Makefile.am:
Auto merged
libmysqld/examples/Makefile.am:
Auto merged
libmysqld/lib_sql.cc:
Auto merged
myisam/mi_check.c:
Auto merged
myisam/myisamchk.c:
Auto merged
myisam/sort.c:
Auto merged
mysql-test/r/connect.result:
Auto merged
mysql-test/r/ctype_recoding.result:
Auto merged
mysql-test/r/ctype_ucs.result:
Auto merged
mysql-test/r/func_in.result:
Auto merged
mysql-test/r/func_like.result:
Auto merged
mysql-test/r/gis.result:
Auto merged
mysql-test/r/having.result:
Auto merged
mysql-test/r/heap.result:
Auto merged
mysql-test/r/join.result:
Auto merged
mysql-test/r/key.result:
Auto merged
mysql-test/r/lowercase_table.result:
Auto merged
mysql-test/r/ndb_autodiscover.result:
Auto merged
mysql-test/r/null.result:
Auto merged
mysql-test/r/olap.result:
Auto merged
mysql-test/r/order_by.result:
Auto merged
mysql-test/r/ps_1general.result:
Auto merged
mysql-test/r/ps_2myisam.result:
Auto merged
mysql-test/r/ps_3innodb.result:
Auto merged
mysql-test/r/ps_4heap.result:
Auto merged
mysql-test/r/ps_5merge.result:
Auto merged
mysql-test/r/ps_6bdb.result:
Auto merged
mysql-test/r/range.result:
Auto merged
mysql-test/r/rename.result:
Auto merged
mysql-test/r/show_check.result:
Auto merged
mysql-test/r/subselect.result:
Auto merged
mysql-test/r/union.result:
Auto merged
mysql-test/r/variables.result:
Auto merged
mysql-test/t/alter_table.test:
Auto merged
mysql-test/t/null.test:
Auto merged
mysql-test/t/ps_1general.test:
Auto merged
mysql-test/t/rpl_charset.test:
Auto merged
mysql-test/t/rpl_heap.test:
Auto merged
mysql-test/t/rpl_relayrotate.test:
Auto merged
mysql-test/t/subselect.test:
Auto merged
mysql-test/t/variables.test:
Auto merged
netware/mysql_test_run.c:
Auto merged
scripts/make_binary_distribution.sh:
Auto merged
scripts/mysql_create_system_tables.sh:
Auto merged
scripts/mysql_fix_privilege_tables.sql:
Auto merged
scripts/mysql_install_db.sh:
Auto merged
sql/ha_berkeley.cc:
Auto merged
sql/ha_innodb.cc:
Auto merged
sql/ha_innodb.h:
Auto merged
sql/ha_myisam.cc:
Auto merged
sql/handler.cc:
Auto merged
sql/handler.h:
Auto merged
sql/item.h:
Auto merged
sql/item_cmpfunc.h:
Auto merged
sql/item_create.cc:
Auto merged
sql/item_create.h:
Auto merged
sql/item_func.cc:
Auto merged
sql/item_func.h:
Auto merged
sql/item_timefunc.cc:
Auto merged
sql/item_timefunc.h:
Auto merged
sql/lex.h:
Auto merged
sql/lock.cc:
Auto merged
sql/log_event.cc:
Auto merged
sql/mysql_priv.h:
Auto merged
sql/opt_sum.cc:
Auto merged
sql/protocol.cc:
Auto merged
sql/records.cc:
Auto merged
sql/repl_failsafe.cc:
Auto merged
sql/set_var.cc:
Auto merged
sql/set_var.h:
Auto merged
sql/slave.cc:
Auto merged
sql/sql_acl.cc:
Auto merged
sql/sql_acl.h:
Auto merged
sql/sql_db.cc:
Auto merged
sql/sql_delete.cc:
Auto merged
sql/sql_insert.cc:
Auto merged
sql/sql_list.h:
Auto merged
sql/sql_load.cc:
Auto merged
sql/sql_rename.cc:
Auto merged
sql/sql_select.h:
Auto merged
sql/sql_show.cc:
Auto merged
sql/sql_string.h:
Auto merged
sql/table.cc:
Auto merged
sql-common/client.c:
Auto merged
client/mysqlbinlog.cc:
Merge with 4.1
configure.in:
Merge with 4.1
include/mysqld_error.h:
Add new error message (1) from 4.1
mysql-test/mysql-test-run.sh:
Merge with 4.1
mysql-test/r/func_gconcat.result:
Merge with 4.1
mysql-test/r/func_if.result:
Merge with 4.1
mysql-test/r/grant.result:
Merge with 4.1
mysql-test/r/join_outer.result:
Merge with 4.1
mysql-test/r/rpl_charset.result:
Merge with 4.1 (This has to be fixed before pushing)
mysql-test/r/system_mysql_db.result:
Merge with 4.1.
Added collation to new privileges
mysql-test/t/grant.test:
Merge with 4.1
mysql-test/t/grant_cache.test:
Merge with 4.1
mysql-test/t/show_check.test:
Merge with 4.1
sql/Makefile.am:
Merge with 4.1
sql/item.cc:
Merge with 4.1
sql/item_cmpfunc.cc:
Merge with 4.1 (arena code)
sql/item_subselect.cc:
Merge with 4.1
sql/item_subselect.h:
Merge with 4.1
sql/item_sum.cc:
Merge with 4.1
sql/item_sum.h:
Merge with 4.1
sql/log.cc:
Merge with 4.1 (Remove code that is not relevant for 5.0)
sql/mysqld.cc:
Merge with 4.1
sql/opt_range.cc:
Merge with 4.1
sql/share/czech/errmsg.txt:
Merge with 4.1
sql/share/danish/errmsg.txt:
Merge with 4.1
sql/share/dutch/errmsg.txt:
Merge with 4.1
sql/share/english/errmsg.txt:
Merge with 4.1
sql/share/estonian/errmsg.txt:
Merge with 4.1
sql/share/french/errmsg.txt:
Merge with 4.1
sql/share/german/errmsg.txt:
Merge with 4.1
sql/share/greek/errmsg.txt:
Merge with 4.1
sql/share/hungarian/errmsg.txt:
Merge with 4.1
sql/share/italian/errmsg.txt:
Merge with 4.1
sql/share/japanese/errmsg.txt:
Merge with 4.1
sql/share/korean/errmsg.txt:
Merge with 4.1
sql/share/norwegian-ny/errmsg.txt:
Merge with 4.1
sql/share/norwegian/errmsg.txt:
Merge with 4.1
sql/share/polish/errmsg.txt:
Merge with 4.1
sql/share/portuguese/errmsg.txt:
Merge with 4.1
sql/share/romanian/errmsg.txt:
Merge with 4.1
sql/share/russian/errmsg.txt:
Merge with 4.1
sql/share/serbian/errmsg.txt:
Merge with 4.1
sql/share/slovak/errmsg.txt:
Merge with 4.1
sql/share/spanish/errmsg.txt:
Merge with 4.1
sql/share/swedish/errmsg.txt:
Merge with 4.1
sql/share/ukrainian/errmsg.txt:
Merge with 4.1
sql/sql_base.cc:
Merge with 4.1
sql/sql_class.cc:
Merge with 4.1
Use arena code from 4.1
sql/sql_class.h:
Merge with 4.1
Use arena code from 4.1
sql/sql_derived.cc:
Merge with 4.1
sql/sql_lex.cc:
Merge with 4.1
sql/sql_lex.h:
Merge with 4.1
sql/sql_parse.cc:
Merge with 4.1
sql/sql_prepare.cc:
Merge with 4.1
sql/sql_select.cc:
Merge with 4.1
sql/sql_table.cc:
Merge with 4.1
sql/sql_union.cc:
Merge with 4.1
sql/sql_yacc.yy:
Merge with 4.1
sql/tztime.cc:
Merge with 4.1
tests/client_test.c:
Merge with 4.1
Diffstat (limited to 'ndb/test')
55 files changed, 4195 insertions, 1695 deletions
diff --git a/ndb/test/include/HugoOperations.hpp b/ndb/test/include/HugoOperations.hpp index 7295b72b18f..6bd8f7204b2 100644 --- a/ndb/test/include/HugoOperations.hpp +++ b/ndb/test/include/HugoOperations.hpp @@ -57,10 +57,6 @@ public: int pkDeleteRecord(Ndb*, int recordNo, int numRecords = 1); - - int scanReadRecords(Ndb* pNdb, - Uint32 parallelism = 240, ScanLock lock = SL_Read); - int executeScanRead(Ndb*); int execute_Commit(Ndb*, AbortOption ao = AbortOnError); @@ -93,7 +89,11 @@ public: int recordNo, int numRecords = 1, int updatesValue = 0); - + + int scanReadRecords(Ndb*, NdbScanOperation::LockMode = + NdbScanOperation::LM_CommittedRead, + int numRecords = 1); + protected: void allocRows(int rows); void deallocRows(); @@ -102,48 +102,12 @@ protected: HugoCalculator calc; Vector<BaseString> savedRecords; + + struct RsPair { NdbResultSet* m_result_set; int records; }; + Vector<RsPair> m_result_sets; + Vector<RsPair> m_executed_result_sets; private: NdbConnection* pTrans; - - struct ScanTmp { - ScanTmp() { - pTrans = 0; - m_tmpRow = 0; - m_delete = true; - m_op = DONE; - } - ScanTmp(NdbConnection* a, NDBT_ResultRow* b){ - pTrans = a; - m_tmpRow = b; - m_delete = true; - m_op = DONE; - } - ScanTmp(const ScanTmp& org){ - * this = org; - } - ScanTmp& operator=(const ScanTmp& org){ - pTrans = org.pTrans; - m_tmpRow = org.m_tmpRow; - m_delete = org.m_delete; - m_op = org.m_op; - return * this; - } - - ~ScanTmp() { - if(m_delete && pTrans) - pTrans->close(); - if(m_delete && m_tmpRow) - delete m_tmpRow; - } - - NdbConnection * pTrans; - NDBT_ResultRow * m_tmpRow; - bool m_delete; - enum { DONE, READ, UPDATE, DELETE } m_op; - }; - Vector<ScanTmp> m_scans; - int run(ScanTmp & tmp); - }; #endif diff --git a/ndb/test/include/HugoTransactions.hpp b/ndb/test/include/HugoTransactions.hpp index 5ff1fef16bc..280d9490f15 100644 --- a/ndb/test/include/HugoTransactions.hpp +++ b/ndb/test/include/HugoTransactions.hpp @@ -34,16 +34,17 @@ public: int records, int batch = 512, bool allowConstraintViolation = true, - int doSleep = 0); + int doSleep = 0, + bool oneTrans = false); int scanReadRecords(Ndb*, int records, int abort = 0, - int parallelism = 1, + int parallelism = 0, bool committed = false); int scanReadCommittedRecords(Ndb*, int records, int abort = 0, - int parallelism = 1); + int parallelism = 0); int pkReadRecords(Ndb*, int records, int batchsize = 1, @@ -52,20 +53,20 @@ public: int scanUpdateRecords(Ndb*, int records, int abort = 0, - int parallelism = 1); + int parallelism = 0); int scanUpdateRecords1(Ndb*, int records, int abort = 0, - int parallelism = 1); + int parallelism = 0); int scanUpdateRecords2(Ndb*, int records, int abort = 0, - int parallelism = 1); + int parallelism = 0); int scanUpdateRecords3(Ndb*, int records, int abort = 0, - int parallelism = 1); + int parallelism = 0); int pkUpdateRecords(Ndb*, int records, @@ -100,24 +101,6 @@ public: int batchsize = 1); protected: - int takeOverAndUpdateRecord(Ndb*, - NdbOperation*); -#if 0 - int setValueForAttr(NdbOperation*, - int attrId, - int rowId, - int updateId); -public: - int equalForAttr(NdbOperation*, - int attrId, - int rowId); -#endif - - int addRowToUpdate(Ndb* pNdb, - NdbConnection* pUpdTrans, - NdbOperation* pOrgOp); - - NDBT_ResultRow row; int m_defaultScanUpdateMethod; }; diff --git a/ndb/test/include/NDBT_Table.hpp b/ndb/test/include/NDBT_Table.hpp index eee76773106..59db3ed1092 100644 --- a/ndb/test/include/NDBT_Table.hpp +++ b/ndb/test/include/NDBT_Table.hpp @@ -23,10 +23,9 @@ #include <NdbOut.hpp> class NDBT_Attribute : public NdbDictionary::Column { - friend class NdbOut& operator <<(class NdbOut&, const NDBT_Attribute &); public: NDBT_Attribute(const char* _name, - Column::Type _type, + NdbDictionary::Column::Type _type, int _length = 1, bool _pk = false, bool _nullable = false): @@ -51,13 +50,12 @@ public: NDBT_Table(const char* name, int noOfAttributes, - const NdbDictionary::Column attributes[], - bool stored = true) + const NdbDictionary::Column attributes[]) : NdbDictionary::Table(name) { assert(name != 0); - setStoredTable(stored); + //setStoredTable(stored); for(int i = 0; i<noOfAttributes; i++) addColumn(attributes[i]); } diff --git a/ndb/test/include/NDBT_Tables.hpp b/ndb/test/include/NDBT_Tables.hpp index 1da9818ee70..aa78f7d4e2c 100644 --- a/ndb/test/include/NDBT_Tables.hpp +++ b/ndb/test/include/NDBT_Tables.hpp @@ -26,7 +26,8 @@ class NDBT_Tables { public: - static int createTable(Ndb* pNdb, const char* _name, bool _temp = false); + static int createTable(Ndb* pNdb, const char* _name, bool _temp = false, + bool existsOK = false); static int createAllTables(Ndb* pNdb, bool _temp, bool existsOK = false); static int createAllTables(Ndb* pNdb); diff --git a/ndb/test/include/NDBT_Test.hpp b/ndb/test/include/NDBT_Test.hpp index 7a5d14689bc..6a968c491ae 100644 --- a/ndb/test/include/NDBT_Test.hpp +++ b/ndb/test/include/NDBT_Test.hpp @@ -63,6 +63,8 @@ public: bool getPropertyWait(const char*, Uint32); const char* getPropertyWait(const char*, const char* ); + void decProperty(const char *); + // Communicate with other tests void stopTest(); bool isTestStopped(); @@ -110,6 +112,7 @@ public: NDBT_Step(NDBT_TestCase* ptest, const char* pname, NDBT_TESTFUNC* pfunc); + virtual ~NDBT_Step() {} int execute(NDBT_Context*); virtual int setUp() = 0; virtual void tearDown() = 0; @@ -132,8 +135,9 @@ public: NDBT_NdbApiStep(NDBT_TestCase* ptest, const char* pname, NDBT_TESTFUNC* pfunc); - int setUp(); - void tearDown(); + virtual ~NDBT_NdbApiStep() {} + virtual int setUp(); + virtual void tearDown(); Ndb* getNdb(); protected: @@ -145,6 +149,7 @@ public: NDBT_ParallelStep(NDBT_TestCase* ptest, const char* pname, NDBT_TESTFUNC* pfunc); + virtual ~NDBT_ParallelStep() {} }; class NDBT_Verifier : public NDBT_NdbApiStep { @@ -152,6 +157,7 @@ public: NDBT_Verifier(NDBT_TestCase* ptest, const char* name, NDBT_TESTFUNC* func); + virtual ~NDBT_Verifier() {} }; class NDBT_Initializer : public NDBT_NdbApiStep { @@ -159,6 +165,7 @@ public: NDBT_Initializer(NDBT_TestCase* ptest, const char* name, NDBT_TESTFUNC* func); + virtual ~NDBT_Initializer() {} }; class NDBT_Finalizer : public NDBT_NdbApiStep { @@ -166,6 +173,7 @@ public: NDBT_Finalizer(NDBT_TestCase* ptest, const char* name, NDBT_TESTFUNC* func); + virtual ~NDBT_Finalizer() {} }; @@ -174,7 +182,8 @@ public: NDBT_TestCase(NDBT_TestSuite* psuite, const char* name, const char* comment); - virtual ~NDBT_TestCase(){}; + virtual ~NDBT_TestCase(){} + // This is the default executor of a test case // When a test case is executed it will need to be suplied with a number of // different parameters and settings, these are passed to the test in the diff --git a/ndb/test/include/NdbRestarter.hpp b/ndb/test/include/NdbRestarter.hpp index b4c29a87eff..114726f6a2b 100644 --- a/ndb/test/include/NdbRestarter.hpp +++ b/ndb/test/include/NdbRestarter.hpp @@ -19,6 +19,7 @@ #include <mgmapi.h> #include <Vector.hpp> +#include <BaseString.hpp> class NdbRestarter { public: @@ -85,8 +86,8 @@ protected: Vector<ndb_mgm_node_state> apiNodes; bool connected; - const char* addr; - const char* host; + BaseString addr; + BaseString host; int port; NdbMgmHandle handle; ndb_mgm_configuration * m_config; diff --git a/ndb/test/include/UtilTransactions.hpp b/ndb/test/include/UtilTransactions.hpp index b16ab74455e..1298028d591 100644 --- a/ndb/test/include/UtilTransactions.hpp +++ b/ndb/test/include/UtilTransactions.hpp @@ -34,24 +34,24 @@ public: int clearTable(Ndb*, int records = 0, - int parallelism = 240); + int parallelism = 0); // Delete all records from the table using a scan int clearTable1(Ndb*, int records = 0, - int parallelism = 16); + int parallelism = 0); // Delete all records from the table using a scan // Using batching int clearTable2(Ndb*, int records = 0, - int parallelism = 240); + int parallelism = 0); int clearTable3(Ndb*, int records = 0, - int parallelism = 240); + int parallelism = 0); int selectCount(Ndb*, - int parallelism = 16, + int parallelism = 0, int* count_rows = NULL, ScanLock lock = SL_Read, NdbConnection* pTrans = NULL); @@ -64,7 +64,7 @@ public: ReadCallBackFn* fn = NULL); int verifyIndex(Ndb*, const char* indexName, - int parallelism = 240, + int parallelism = 0, bool transactional = false); int copyTableData(Ndb*, @@ -88,7 +88,7 @@ private: int verifyUniqueIndex(Ndb*, const char* indexName, - int parallelism = 240, + int parallelism = 0, bool transactional = false); int scanAndCompareUniqueIndex(Ndb* pNdb, diff --git a/ndb/test/ndbapi/Makefile.am b/ndb/test/ndbapi/Makefile.am index 7b3648bdc45..51bc11f8a25 100644 --- a/ndb/test/ndbapi/Makefile.am +++ b/ndb/test/ndbapi/Makefile.am @@ -9,7 +9,6 @@ create_tab \ flexAsynch \ flexBench \ flexHammer \ -flexScan \ flexTT \ testBackup \ testBasic \ @@ -26,9 +25,11 @@ testOperations \ testRestartGci \ testScan \ testScanInterpreter \ +testScanPerf \ testSystemRestart \ testTimeout \ testTransactions \ +testDeadlock \ test_event #flexTimedAsynch @@ -41,7 +42,6 @@ drop_all_tabs_SOURCES = drop_all_tabs.cpp flexAsynch_SOURCES = flexAsynch.cpp flexBench_SOURCES = flexBench.cpp flexHammer_SOURCES = flexHammer.cpp -flexScan_SOURCES = flexScan.cpp flexTT_SOURCES = flexTT.cpp #flexTimedAsynch_SOURCES = flexTimedAsynch.cpp #flex_bench_mysql_SOURCES = flex_bench_mysql.cpp @@ -60,9 +60,11 @@ testOperations_SOURCES = testOperations.cpp testRestartGci_SOURCES = testRestartGci.cpp testScan_SOURCES = testScan.cpp ScanFunctions.hpp testScanInterpreter_SOURCES = testScanInterpreter.cpp ScanFilter.hpp ScanInterpretTest.hpp +testScanPerf_SOURCES = testScanPerf.cpp testSystemRestart_SOURCES = testSystemRestart.cpp testTimeout_SOURCES = testTimeout.cpp testTransactions_SOURCES = testTransactions.cpp +testDeadlock_SOURCES = testDeadlock.cpp test_event_SOURCES = test_event.cpp INCLUDES_LOC = -I$(top_srcdir)/ndb/include/kernel @@ -79,3 +81,4 @@ testBackup_LDADD = $(LDADD) bank/libbank.a # Don't update the files from bitkeeper %::SCCS/s.% + diff --git a/ndb/test/ndbapi/Makefile_old b/ndb/test/ndbapi/Makefile_old index 34761e1eb9c..c3198096ec0 100644 --- a/ndb/test/ndbapi/Makefile_old +++ b/ndb/test/ndbapi/Makefile_old @@ -4,12 +4,11 @@ include .defs.mk ifeq ($(NDB_OS), OSE) DIRS = basic flexBench flexAsynch else -DIRS = lmc-bench bank ronja +DIRS = lmc-bench ronja BIN_DIRS = \ flexAsynch \ flexBench \ flexHammer \ - flexScan \ flexTT \ create_tab \ create_all_tabs \ @@ -32,7 +31,6 @@ BIN_DIRS = \ testDataBuffers \ testDict \ acid \ - interpreterInTup \ telco \ indexTest \ test_event \ diff --git a/ndb/test/ndbapi/ScanFunctions.hpp b/ndb/test/ndbapi/ScanFunctions.hpp index 36d01909861..2ff4b751c33 100644 --- a/ndb/test/ndbapi/ScanFunctions.hpp +++ b/ndb/test/ndbapi/ScanFunctions.hpp @@ -79,8 +79,9 @@ ScanFunctions::scanReadFunctions(Ndb* pNdb, const int retryMax = 100; int sleepTime = 10; int check; - NdbConnection *pTrans; - NdbOperation *pOp; + NdbConnection *pTrans = 0; + NdbScanOperation *pOp = 0; + NdbResultSet *rs = 0; while (true){ if (retryAttempt >= retryMax){ @@ -103,117 +104,81 @@ ScanFunctions::scanReadFunctions(Ndb* pNdb, } // Execute the scan without defining a scan operation - if(action != ExecuteScanWithOutOpenScan){ - - if (action == OnlyOneOpBeforeOpenScan){ - // There can only be one operation defined when calling openScan - NdbOperation* pOp3; - pOp3 = pTrans->getNdbOperation(tab.getName()); - if (pOp3 == NULL) { - ERR(pTrans->getNdbError()); - pNdb->closeTransaction(pTrans); - return NDBT_FAILED; - } - } - - pOp = pTrans->getNdbOperation(tab.getName()); - if (pOp == NULL) { + pOp = pTrans->getNdbScanOperation(tab.getName()); + if (pOp == NULL) { + ERR(pTrans->getNdbError()); + pNdb->closeTransaction(pTrans); + return NDBT_FAILED; + } + + + rs = pOp->readTuples(exclusive ? + NdbScanOperation::LM_Exclusive : + NdbScanOperation::LM_Read); + + if( rs == 0 ) { + ERR(pTrans->getNdbError()); + pNdb->closeTransaction(pTrans); + return NDBT_FAILED; + } + + + if (action == OnlyOpenScanOnce){ + // Call openScan one more time when it's already defined + NdbResultSet* rs2 = pOp->readTuples(NdbScanOperation::LM_Read); + if( rs2 == 0 ) { ERR(pTrans->getNdbError()); pNdb->closeTransaction(pTrans); return NDBT_FAILED; } - - if (exclusive == true) - check = pOp->openScanExclusive(parallelism); - else - check = pOp->openScanRead(parallelism); + } + + if (action==EqualAfterOpenScan){ + check = pOp->equal(tab.getColumn(0)->getName(), 10); if( check == -1 ) { ERR(pTrans->getNdbError()); pNdb->closeTransaction(pTrans); return NDBT_FAILED; - } - - - if (action == OnlyOneScanPerTrans){ - // There can only be one operation in a scan transaction - NdbOperation* pOp4; - pOp4 = pTrans->getNdbOperation(tab.getName()); - if (pOp4 == NULL) { - ERR(pTrans->getNdbError()); - pNdb->closeTransaction(pTrans); - return NDBT_FAILED; - } - } - - if (action == OnlyOpenScanOnce){ - // Call openScan one more time when it's already defined - check = pOp->openScanRead(parallelism); - if( check == -1 ) { - ERR(pTrans->getNdbError()); - pNdb->closeTransaction(pTrans); - return NDBT_FAILED; - } - } - - if (action == OnlyOneOpInScanTrans){ - // Try to add another op to this scanTransaction - NdbOperation* pOp2; - pOp2 = pTrans->getNdbOperation(tab.getName()); - if (pOp2 == NULL) { - ERR(pTrans->getNdbError()); - pNdb->closeTransaction(pTrans); - return NDBT_FAILED; - } - } - - - if (action==EqualAfterOpenScan){ - check = pOp->equal(tab.getColumn(0)->getName(), 10); - if( check == -1 ) { - ERR(pTrans->getNdbError()); - pNdb->closeTransaction(pTrans); - return NDBT_FAILED; - } - } - - check = pOp->interpret_exit_ok(); - if( check == -1 ) { + } + } + + check = pOp->interpret_exit_ok(); + if( check == -1 ) { + ERR(pTrans->getNdbError()); + pNdb->closeTransaction(pTrans); + return NDBT_FAILED; + } + + for(int a = 0; a<tab.getNoOfColumns(); a++){ + if(pOp->getValue(tab.getColumn(a)->getName()) == NULL) { ERR(pTrans->getNdbError()); pNdb->closeTransaction(pTrans); return NDBT_FAILED; } - - for(int a = 0; a<tab.getNoOfColumns(); a++){ - if(pOp->getValue(tab.getColumn(a)->getName()) == NULL) { - ERR(pTrans->getNdbError()); - pNdb->closeTransaction(pTrans); - return NDBT_FAILED; - } - } - } - check = pTrans->executeScan(); + } + + check = pTrans->execute(NoCommit); if( check == -1 ) { ERR(pTrans->getNdbError()); pNdb->closeTransaction(pTrans); return NDBT_FAILED; } - - + int abortCount = records / 10; bool abortTrans = (action==CloseWithoutStop); int eof; int rows = 0; - eof = pTrans->nextScanResult(); - + eof = rs->nextResult(); + while(eof == 0){ rows++; - + if (abortCount == rows && abortTrans == true){ g_info << "Scan is aborted after "<<abortCount<<" rows" << endl; if (action != CloseWithoutStop){ // Test that we can closeTrans without stopScan - check = pTrans->stopScan(); + rs->close(); if( check == -1 ) { ERR(pTrans->getNdbError()); pNdb->closeTransaction(pTrans); @@ -236,7 +201,7 @@ ScanFunctions::scanReadFunctions(Ndb* pNdb, } } - eof = pTrans->nextScanResult(); + eof = rs->nextResult(); } if (eof == -1) { const NdbError err = pTrans->getNdbError(); @@ -246,7 +211,7 @@ ScanFunctions::scanReadFunctions(Ndb* pNdb, // Be cruel, call nextScanResult after error for(int i=0; i<10; i++){ - eof =pTrans->nextScanResult(); + eof = rs->nextResult(); if(eof == 0){ g_err << "nextScanResult returned eof = " << eof << endl << " That is an error when there are no more records" << endl; @@ -276,7 +241,7 @@ ScanFunctions::scanReadFunctions(Ndb* pNdb, if (action == NextScanWhenNoMore){ g_info << "Calling nextScanresult when there are no more records" << endl; for(int i=0; i<10; i++){ - eof =pTrans->nextScanResult(); + eof = rs->nextResult(); if(eof == 0){ g_err << "nextScanResult returned eof = " << eof << endl << " That is an error when there are no more records" << endl; @@ -285,7 +250,7 @@ ScanFunctions::scanReadFunctions(Ndb* pNdb, } } - if(action ==CheckInactivityBeforeClose){ + if(action == CheckInactivityBeforeClose){ // Sleep for a long time before calling close g_info << "NdbSleep_SecSleep(5) before close transaction" << endl; NdbSleep_SecSleep(5); diff --git a/ndb/test/ndbapi/ScanInterpretTest.hpp b/ndb/test/ndbapi/ScanInterpretTest.hpp index 3862de34111..e8a0d4b6dca 100644 --- a/ndb/test/ndbapi/ScanInterpretTest.hpp +++ b/ndb/test/ndbapi/ScanInterpretTest.hpp @@ -197,7 +197,7 @@ ScanInterpretTest::scanRead(Ndb* pNdb, int retryMax = 100; int check; NdbConnection *pTrans; - NdbOperation *pOp; + NdbScanOperation *pOp; while (true){ @@ -220,16 +220,17 @@ ScanInterpretTest::scanRead(Ndb* pNdb, return NDBT_FAILED; } - pOp = pTrans->getNdbOperation(tab.getName()); + pOp = pTrans->getNdbScanOperation(tab.getName()); if (pOp == NULL) { ERR(pTrans->getNdbError()); pNdb->closeTransaction(pTrans); return NDBT_FAILED; } - - check = pOp->openScanRead(parallelism); - //check = pOp->openScanExclusive(parallelism); - if( check == -1 ) { + + NdbResultSet * rs = pOp->readTuples(NdbScanOperation::LM_Read, + 0, parallelism); + + if( rs == 0 ) { ERR(pTrans->getNdbError()); pNdb->closeTransaction(pTrans); return NDBT_FAILED; @@ -250,7 +251,7 @@ ScanInterpretTest::scanRead(Ndb* pNdb, return NDBT_FAILED; } } - check = pTrans->executeScan(); + check = pTrans->execute(NoCommit); if( check == -1 ) { ERR(pTrans->getNdbError()); pNdb->closeTransaction(pTrans); @@ -261,32 +262,22 @@ ScanInterpretTest::scanRead(Ndb* pNdb, int rows = 0; NdbConnection* pInsTrans; - while((eof = pTrans->nextScanResult(true)) == 0){ - pInsTrans = pNdb->startTransaction(); - if (pInsTrans == NULL) { - const NdbError err = pNdb->getNdbError(); - ERR(err); - return NDBT_FAILED; - } + while((eof = rs->nextResult(true)) == 0){ do { rows++; - if (addRowToInsert(pNdb, pInsTrans) != 0){ + if (addRowToInsert(pNdb, pTrans) != 0){ pNdb->closeTransaction(pTrans); - pNdb->closeTransaction(pInsTrans); return NDBT_FAILED; } - } while((eof = pTrans->nextScanResult(false)) == 0); + } while((eof = rs->nextResult(false)) == 0); - check = pInsTrans->execute(Commit); + check = pTrans->execute(Commit); if( check == -1 ) { - const NdbError err = pInsTrans->getNdbError(); + const NdbError err = pTrans->getNdbError(); ERR(err); - pNdb->closeTransaction(pInsTrans); pNdb->closeTransaction(pTrans); return NDBT_FAILED; } - pNdb->closeTransaction(pInsTrans); - } if (eof == -1) { const NdbError err = pTrans->getNdbError(); @@ -322,7 +313,7 @@ ScanInterpretTest::scanReadVerify(Ndb* pNdb, const int retryMax = 100; int check; NdbConnection *pTrans; - NdbOperation *pOp; + NdbScanOperation *pOp; while (true){ @@ -346,7 +337,7 @@ ScanInterpretTest::scanReadVerify(Ndb* pNdb, } - pOp = pTrans->getNdbOperation(tab.getName()); + pOp = pTrans->getNdbScanOperation(tab.getName()); if (pOp == NULL) { if (pOp->getValue("KOL2") == 0){ ERR(pNdb->getNdbError()); return NDBT_FAILED; @@ -357,9 +348,10 @@ ScanInterpretTest::scanReadVerify(Ndb* pNdb, pNdb->closeTransaction(pTrans); return NDBT_FAILED; } - - check = pOp->openScanRead(parallelism); - if( check == -1 ) { + + NdbResultSet * rs = pOp->readTuples(NdbScanOperation::LM_Read, + 0, parallelism); + if( rs == 0 ) { ERR(pTrans->getNdbError()); pNdb->closeTransaction(pTrans); return NDBT_FAILED; @@ -382,7 +374,7 @@ ScanInterpretTest::scanReadVerify(Ndb* pNdb, return NDBT_FAILED; } } - check = pTrans->executeScan(); + check = pTrans->execute(NoCommit); if( check == -1 ) { ERR(pTrans->getNdbError()); pNdb->closeTransaction(pTrans); @@ -400,7 +392,7 @@ ScanInterpretTest::scanReadVerify(Ndb* pNdb, NdbConnection* pExistTrans; NdbConnection* pNoExistTrans; - while((eof = pTrans->nextScanResult(true)) == 0){ + while((eof = rs->nextResult(true)) == 0){ pExistTrans = pNdb->startTransaction(); if (pExistTrans == NULL) { const NdbError err = pNdb->getNdbError(); @@ -432,7 +424,7 @@ ScanInterpretTest::scanReadVerify(Ndb* pNdb, return NDBT_FAILED; } } - } while((eof = pTrans->nextScanResult(false)) == 0); + } while((eof = rs->nextResult(false)) == 0); // Execute the transaction containing reads of diff --git a/ndb/test/ndbapi/bank/Bank.cpp b/ndb/test/ndbapi/bank/Bank.cpp index 14883205693..7a2c5b057a1 100644 --- a/ndb/test/ndbapi/bank/Bank.cpp +++ b/ndb/test/ndbapi/bank/Bank.cpp @@ -670,15 +670,15 @@ int Bank::findLastGL(Uint64 &lastTime){ return NDBT_FAILED; } - NdbOperation* pOp = pScanTrans->getNdbOperation("GL"); + NdbScanOperation* pOp = pScanTrans->getNdbScanOperation("GL"); if (pOp == NULL) { ERR(pScanTrans->getNdbError()); m_ndb.closeTransaction(pScanTrans); return NDBT_FAILED; } - check = pOp->openScanRead(64); - if( check == -1 ) { + NdbResultSet * rs = pOp->readTuples(); + if( rs == 0 ) { ERR(pScanTrans->getNdbError()); m_ndb.closeTransaction(pScanTrans); return NDBT_FAILED; @@ -698,7 +698,7 @@ int Bank::findLastGL(Uint64 &lastTime){ return NDBT_FAILED; } - check = pScanTrans->executeScan(); + check = pScanTrans->execute(NoCommit); if( check == -1 ) { ERR(pScanTrans->getNdbError()); m_ndb.closeTransaction(pScanTrans); @@ -707,7 +707,7 @@ int Bank::findLastGL(Uint64 &lastTime){ int eof; int rows = 0; - eof = pScanTrans->nextScanResult(); + eof = rs->nextResult(); lastTime = 0; while(eof == 0){ @@ -717,7 +717,7 @@ int Bank::findLastGL(Uint64 &lastTime){ if (t > lastTime) lastTime = t; - eof = pScanTrans->nextScanResult(); + eof = rs->nextResult(); } if (eof == -1) { ERR(pScanTrans->getNdbError()); @@ -1002,15 +1002,15 @@ int Bank::sumTransactionsForGL(const Uint64 glTime, return NDBT_FAILED; } - NdbOperation* pOp = pScanTrans->getNdbOperation("TRANSACTION"); + NdbScanOperation* pOp = pScanTrans->getNdbScanOperation("TRANSACTION"); if (pOp == NULL) { ERR(pScanTrans->getNdbError()); m_ndb.closeTransaction(pScanTrans); return NDBT_FAILED; } - check = pOp->openScanExclusive(64); - if( check == -1 ) { + NdbResultSet * rs = pOp->readTuplesExclusive(); + if( rs == 0 ) { ERR(pScanTrans->getNdbError()); m_ndb.closeTransaction(pScanTrans); return NDBT_FAILED; @@ -1051,7 +1051,7 @@ int Bank::sumTransactionsForGL(const Uint64 glTime, return NDBT_FAILED; } - check = pScanTrans->executeScan(); + check = pScanTrans->execute(NoCommit); if( check == -1 ) { ERR(pScanTrans->getNdbError()); m_ndb.closeTransaction(pScanTrans); @@ -1061,7 +1061,7 @@ int Bank::sumTransactionsForGL(const Uint64 glTime, int eof; int rows = 0; int rowsFound = 0; - eof = pScanTrans->nextScanResult(); + eof = rs->nextResult(); while(eof == 0){ rows++; @@ -1085,7 +1085,7 @@ int Bank::sumTransactionsForGL(const Uint64 glTime, } } - eof = pScanTrans->nextScanResult(); + eof = rs->nextResult(); if ((rows % 100) == 0){ // "refresh" ownner transaction every 100th row @@ -1162,15 +1162,15 @@ int Bank::performValidateGL(Uint64 glTime){ return NDBT_FAILED; } - NdbOperation* pOp = pScanTrans->getNdbOperation("GL"); + NdbScanOperation* pOp = pScanTrans->getNdbScanOperation("GL"); if (pOp == NULL) { ERR(pScanTrans->getNdbError()); m_ndb.closeTransaction(pScanTrans); return NDBT_FAILED; } - check = pOp->openScanRead(64); - if( check == -1 ) { + NdbResultSet * rs = pOp->readTuples(); + if( rs == 0 ) { ERR(pScanTrans->getNdbError()); m_ndb.closeTransaction(pScanTrans); return NDBT_FAILED; @@ -1238,7 +1238,7 @@ int Bank::performValidateGL(Uint64 glTime){ return NDBT_FAILED; } - check = pScanTrans->executeScan(); + check = pScanTrans->execute(NoCommit); if( check == -1 ) { ERR(pScanTrans->getNdbError()); m_ndb.closeTransaction(pScanTrans); @@ -1249,7 +1249,7 @@ int Bank::performValidateGL(Uint64 glTime){ int rows = 0; int countGlRecords = 0; int result = NDBT_OK; - eof = pScanTrans->nextScanResult(); + eof = rs->nextResult(); while(eof == 0){ rows++; @@ -1336,7 +1336,7 @@ int Bank::performValidateGL(Uint64 glTime){ } } - eof = pScanTrans->nextScanResult(); + eof = rs->nextResult(); } if (eof == -1) { ERR(pScanTrans->getNdbError()); @@ -1426,15 +1426,15 @@ int Bank::getOldestPurgedGL(const Uint32 accountType, return NDBT_FAILED; } - NdbOperation* pOp = pScanTrans->getNdbOperation("GL"); + NdbScanOperation* pOp = pScanTrans->getNdbScanOperation("GL"); if (pOp == NULL) { ERR(pScanTrans->getNdbError()); m_ndb.closeTransaction(pScanTrans); return NDBT_FAILED; } - check = pOp->openScanRead(64); - if( check == -1 ) { + NdbResultSet * rs = pOp->readTuples(); + if( rs == 0 ) { ERR(pScanTrans->getNdbError()); m_ndb.closeTransaction(pScanTrans); return NDBT_FAILED; @@ -1468,7 +1468,7 @@ int Bank::getOldestPurgedGL(const Uint32 accountType, return NDBT_FAILED; } - check = pScanTrans->executeScan(); + check = pScanTrans->execute(NoCommit); if( check == -1 ) { ERR(pScanTrans->getNdbError()); m_ndb.closeTransaction(pScanTrans); @@ -1477,7 +1477,7 @@ int Bank::getOldestPurgedGL(const Uint32 accountType, int eof; int rows = 0; - eof = pScanTrans->nextScanResult(); + eof = rs->nextResult(); oldest = 0; while(eof == 0){ @@ -1491,7 +1491,7 @@ int Bank::getOldestPurgedGL(const Uint32 accountType, if (t > oldest) oldest = t; } - eof = pScanTrans->nextScanResult(); + eof = rs->nextResult(); } if (eof == -1) { ERR(pScanTrans->getNdbError()); @@ -1518,15 +1518,15 @@ int Bank::getOldestNotPurgedGL(Uint64 &oldest, return NDBT_FAILED; } - NdbOperation* pOp = pScanTrans->getNdbOperation("GL"); + NdbScanOperation* pOp = pScanTrans->getNdbScanOperation("GL"); if (pOp == NULL) { ERR(pScanTrans->getNdbError()); m_ndb.closeTransaction(pScanTrans); return NDBT_FAILED; } - check = pOp->openScanRead(64); - if( check == -1 ) { + NdbResultSet * rs = pOp->readTuples(); + if( rs == 0 ) { ERR(pScanTrans->getNdbError()); m_ndb.closeTransaction(pScanTrans); return NDBT_FAILED; @@ -1560,7 +1560,7 @@ int Bank::getOldestNotPurgedGL(Uint64 &oldest, return NDBT_FAILED; } - check = pScanTrans->executeScan(); + check = pScanTrans->execute(NoCommit); if( check == -1 ) { ERR(pScanTrans->getNdbError()); m_ndb.closeTransaction(pScanTrans); @@ -1569,7 +1569,7 @@ int Bank::getOldestNotPurgedGL(Uint64 &oldest, int eof; int rows = 0; - eof = pScanTrans->nextScanResult(); + eof = rs->nextResult(); oldest = (Uint64)-1; found = false; @@ -1586,7 +1586,7 @@ int Bank::getOldestNotPurgedGL(Uint64 &oldest, accountTypeId = a; } } - eof = pScanTrans->nextScanResult(); + eof = rs->nextResult(); } if (eof == -1) { ERR(pScanTrans->getNdbError()); @@ -1615,15 +1615,15 @@ int Bank::checkNoTransactionsOlderThan(const Uint32 accountType, return NDBT_FAILED; } - NdbOperation* pOp = pScanTrans->getNdbOperation("TRANSACTION"); + NdbScanOperation* pOp = pScanTrans->getNdbScanOperation("TRANSACTION"); if (pOp == NULL) { ERR(pScanTrans->getNdbError()); m_ndb.closeTransaction(pScanTrans); return NDBT_FAILED; } - check = pOp->openScanRead(64); - if( check == -1 ) { + NdbResultSet * rs = pOp->readTuples(); + if( rs == 0 ) { ERR(pScanTrans->getNdbError()); m_ndb.closeTransaction(pScanTrans); return NDBT_FAILED; @@ -1657,7 +1657,7 @@ int Bank::checkNoTransactionsOlderThan(const Uint32 accountType, return NDBT_FAILED; } - check = pScanTrans->executeScan(); + check = pScanTrans->execute(NoCommit); if( check == -1 ) { ERR(pScanTrans->getNdbError()); m_ndb.closeTransaction(pScanTrans); @@ -1667,7 +1667,7 @@ int Bank::checkNoTransactionsOlderThan(const Uint32 accountType, int eof; int rows = 0; int found = 0; - eof = pScanTrans->nextScanResult(); + eof = rs->nextResult(); while(eof == 0){ rows++; @@ -1683,7 +1683,7 @@ int Bank::checkNoTransactionsOlderThan(const Uint32 accountType, << " ti = " << ti << endl; found++; } - eof = pScanTrans->nextScanResult(); + eof = rs->nextResult(); } if (eof == -1) { ERR(pScanTrans->getNdbError()); @@ -1859,15 +1859,15 @@ int Bank::findTransactionsToPurge(const Uint64 glTime, return NDBT_FAILED; } - NdbOperation* pOp = pScanTrans->getNdbOperation("TRANSACTION"); + NdbScanOperation* pOp = pScanTrans->getNdbScanOperation("TRANSACTION"); if (pOp == NULL) { ERR(pScanTrans->getNdbError()); m_ndb.closeTransaction(pScanTrans); return NDBT_FAILED; } - check = pOp->openScanExclusive(64); - if( check == -1 ) { + NdbResultSet * rs = pOp->readTuplesExclusive(); + if( rs == 0 ) { ERR(pScanTrans->getNdbError()); m_ndb.closeTransaction(pScanTrans); return NDBT_FAILED; @@ -1894,7 +1894,7 @@ int Bank::findTransactionsToPurge(const Uint64 glTime, return NDBT_FAILED; } - check = pScanTrans->executeScan(); + check = pScanTrans->execute(NoCommit); if( check == -1 ) { ERR(pScanTrans->getNdbError()); m_ndb.closeTransaction(pScanTrans); @@ -1904,7 +1904,7 @@ int Bank::findTransactionsToPurge(const Uint64 glTime, int eof; int rows = 0; int rowsFound = 0; - eof = pScanTrans->nextScanResult(); + eof = rs->nextResult(); while(eof == 0){ rows++; @@ -1914,8 +1914,8 @@ int Bank::findTransactionsToPurge(const Uint64 glTime, if (a == accountType && t == glTime){ rowsFound++; // One record found - NdbOperation* pDelOp = pOp->takeOverForDelete(pTrans); - if (pDelOp == NULL){ + check = rs->deleteTuple(pTrans); + if (check == -1){ ERR(m_ndb.getNdbError()); m_ndb.closeTransaction(pScanTrans); return NDBT_FAILED; @@ -1929,7 +1929,7 @@ int Bank::findTransactionsToPurge(const Uint64 glTime, return NDBT_FAILED; } } - eof = pScanTrans->nextScanResult(); + eof = rs->nextResult(); } if (eof == -1) { ERR(pScanTrans->getNdbError()); @@ -2348,15 +2348,15 @@ int Bank::getSumAccounts(Uint32 &sumAccounts, return NDBT_FAILED; } - NdbOperation* pOp = pScanTrans->getNdbOperation("ACCOUNT"); + NdbScanOperation* pOp = pScanTrans->getNdbScanOperation("ACCOUNT"); if (pOp == NULL) { ERR(pScanTrans->getNdbError()); m_ndb.closeTransaction(pScanTrans); return NDBT_FAILED; } - check = pOp->openScanExclusive(64); - if( check == -1 ) { + NdbResultSet * rs = pOp->readTuplesExclusive(); + if( rs == 0 ) { ERR(pScanTrans->getNdbError()); m_ndb.closeTransaction(pScanTrans); return NDBT_FAILED; @@ -2376,7 +2376,7 @@ int Bank::getSumAccounts(Uint32 &sumAccounts, return NDBT_FAILED; } - check = pScanTrans->executeScan(); + check = pScanTrans->execute(NoCommit); if( check == -1 ) { ERR(pScanTrans->getNdbError()); m_ndb.closeTransaction(pScanTrans); @@ -2391,7 +2391,7 @@ int Bank::getSumAccounts(Uint32 &sumAccounts, } int eof; - eof = pScanTrans->nextScanResult(); + eof = rs->nextResult(); while(eof == 0){ Uint32 b = balanceRec->u_32_value(); @@ -2403,7 +2403,7 @@ int Bank::getSumAccounts(Uint32 &sumAccounts, // << ", sum="<< sumAccounts << endl; // Take over the operation so that the lock is kept in db - NdbOperation* pLockOp = pOp->takeOverForUpdate(pTrans); + NdbOperation* pLockOp = rs->updateTuple(pTrans); if (pLockOp == NULL){ ERR(m_ndb.getNdbError()); m_ndb.closeTransaction(pScanTrans); @@ -2429,7 +2429,7 @@ int Bank::getSumAccounts(Uint32 &sumAccounts, return NDBT_FAILED; } - eof = pScanTrans->nextScanResult(); + eof = rs->nextResult(); } if (eof == -1) { ERR(pScanTrans->getNdbError()); diff --git a/ndb/test/ndbapi/bank/BankLoad.cpp b/ndb/test/ndbapi/bank/BankLoad.cpp index 76261b664a6..bbaac27735b 100644 --- a/ndb/test/ndbapi/bank/BankLoad.cpp +++ b/ndb/test/ndbapi/bank/BankLoad.cpp @@ -335,15 +335,15 @@ int Bank::getBalanceForAccountType(const Uint32 accountType, return NDBT_FAILED; } - NdbOperation* pOp = pScanTrans->getNdbOperation("ACCOUNT"); + NdbScanOperation* pOp = pScanTrans->getNdbScanOperation("ACCOUNT"); if (pOp == NULL) { ERR(pScanTrans->getNdbError()); m_ndb.closeTransaction(pScanTrans); return NDBT_FAILED; } - check = pOp->openScanRead(64); - if( check == -1 ) { + NdbResultSet* rs = pOp->readTuples(); + if( rs == 0 ) { ERR(pScanTrans->getNdbError()); m_ndb.closeTransaction(pScanTrans); return NDBT_FAILED; @@ -370,7 +370,7 @@ int Bank::getBalanceForAccountType(const Uint32 accountType, return NDBT_FAILED; } - check = pScanTrans->executeScan(); + check = pScanTrans->execute(NoCommit); if( check == -1 ) { ERR(pScanTrans->getNdbError()); m_ndb.closeTransaction(pScanTrans); @@ -379,7 +379,7 @@ int Bank::getBalanceForAccountType(const Uint32 accountType, int eof; int rows = 0; - eof = pScanTrans->nextScanResult(); + eof = rs->nextResult(); while(eof == 0){ rows++; @@ -391,7 +391,7 @@ int Bank::getBalanceForAccountType(const Uint32 accountType, balance += b; } - eof = pScanTrans->nextScanResult(); + eof = rs->nextResult(); } if (eof == -1) { ERR(pScanTrans->getNdbError()); diff --git a/ndb/test/ndbapi/create_tab.cpp b/ndb/test/ndbapi/create_tab.cpp index 8bb1e7a9572..c2e3b7f64ea 100644 --- a/ndb/test/ndbapi/create_tab.cpp +++ b/ndb/test/ndbapi/create_tab.cpp @@ -63,9 +63,10 @@ int main(int argc, const char** argv){ /** * Print instead of creating */ - if(argv[optind] != NULL){ - for(int i = optind; i<argc; i++) + if(optind < argc){ + for(int i = optind; i<argc; i++){ NDBT_Tables::print(argv[i]); + } } else { NDBT_Tables::printAll(); } diff --git a/ndb/test/ndbapi/flexAsynch.cpp b/ndb/test/ndbapi/flexAsynch.cpp index 396ac06c87a..9192ec21b93 100644 --- a/ndb/test/ndbapi/flexAsynch.cpp +++ b/ndb/test/ndbapi/flexAsynch.cpp @@ -146,7 +146,7 @@ tellThreads(StartType what) NDB_COMMAND(flexAsynch, "flexAsynch", "flexAsynch", "flexAsynch", 65535) { ThreadNdb* pThreadData; - int tLoops=0; + int tLoops=0, i; int returnValue = NDBT_OK; flexAsynchErrorData = new ErrorData; @@ -256,7 +256,7 @@ NDB_COMMAND(flexAsynch, "flexAsynch", "flexAsynch", "flexAsynch", 65535) PRINT_TIMER("insert", noOfTransacts, tNoOfOpsPerTrans); if (0 < failed) { - int i = retry_opt ; + i = retry_opt ; int ci = 1 ; while (0 < failed && 0 < i){ ndbout << failed << " of the transactions returned errors!" @@ -293,7 +293,7 @@ NDB_COMMAND(flexAsynch, "flexAsynch", "flexAsynch", "flexAsynch", 65535) PRINT_TIMER("read", noOfTransacts, tNoOfOpsPerTrans); if (0 < failed) { - int i = retry_opt ; + i = retry_opt ; int cr = 1; while (0 < failed && 0 < i){ ndbout << failed << " of the transactions returned errors!"<<endl ; @@ -330,7 +330,7 @@ NDB_COMMAND(flexAsynch, "flexAsynch", "flexAsynch", "flexAsynch", 65535) PRINT_TIMER("update", noOfTransacts, tNoOfOpsPerTrans) ; if (0 < failed) { - int i = retry_opt ; + i = retry_opt ; int cu = 1 ; while (0 < failed && 0 < i){ ndbout << failed << " of the transactions returned errors!"<<endl ; @@ -366,7 +366,7 @@ NDB_COMMAND(flexAsynch, "flexAsynch", "flexAsynch", "flexAsynch", 65535) PRINT_TIMER("read", noOfTransacts, tNoOfOpsPerTrans); if (0 < failed) { - int i = retry_opt ; + i = retry_opt ; int cr2 = 1 ; while (0 < failed && 0 < i){ ndbout << failed << " of the transactions returned errors!"<<endl ; @@ -403,7 +403,7 @@ NDB_COMMAND(flexAsynch, "flexAsynch", "flexAsynch", "flexAsynch", 65535) PRINT_TIMER("delete", noOfTransacts, tNoOfOpsPerTrans); if (0 < failed) { - int i = retry_opt ; + i = retry_opt ; int cd = 1 ; while (0 < failed && 0 < i){ ndbout << failed << " of the transactions returned errors!"<< endl ; @@ -438,7 +438,7 @@ NDB_COMMAND(flexAsynch, "flexAsynch", "flexAsynch", "flexAsynch", 65535) execute(stStop); void * tmp; - for(int i = 0; i<tNoOfThreads; i++){ + for(i = 0; i<tNoOfThreads; i++){ NdbThread_WaitFor(threadLife[i], &tmp); NdbThread_Destroy(&threadLife[i]); } diff --git a/ndb/test/ndbapi/flexBench.cpp b/ndb/test/ndbapi/flexBench.cpp index 809d11086bf..38c8f6e280f 100644 --- a/ndb/test/ndbapi/flexBench.cpp +++ b/ndb/test/ndbapi/flexBench.cpp @@ -282,7 +282,7 @@ tellThreads(ThreadData* pt, StartType what) NDB_COMMAND(flexBench, "flexBench", "flexBench", "flexbench", 65535) { ThreadData* pThreadsData; - int tLoops = 0; + int tLoops = 0, i; int returnValue = NDBT_OK; if (readArguments(argc, argv) != 0){ @@ -355,7 +355,7 @@ NDB_COMMAND(flexBench, "flexBench", "flexBench", "flexbench", 65535) ****************************************************************/ resetThreads(pThreadsData); - for (unsigned int i = 0; i < tNoOfThreads; i++){ + for (i = 0; i < tNoOfThreads; i++){ pThreadsData[i].threadNo = i; pThreadsData[i].threadLife = NdbThread_Create(flexBenchThread, (void**)&pThreadsData[i], @@ -531,7 +531,7 @@ NDB_COMMAND(flexBench, "flexBench", "flexBench", "flexbench", 65535) waitForThreads(pThreadsData); void * tmp; - for(Uint32 i = 0; i<tNoOfThreads; i++){ + for(i = 0; i<tNoOfThreads; i++){ NdbThread_WaitFor(pThreadsData[i].threadLife, &tmp); NdbThread_Destroy(&pThreadsData[i].threadLife); } @@ -540,7 +540,7 @@ NDB_COMMAND(flexBench, "flexBench", "flexBench", "flexbench", 65535) if (useLongKeys == true) { // Only free these areas if they have been allocated // Otherwise cores will happen - for (Uint32 i = 0; i < tNoOfLongPK; i++) + for (i = 0; i < tNoOfLongPK; i++) free(longKeyAttrName[i]); free(longKeyAttrName); } // if @@ -629,9 +629,10 @@ static void* flexBenchThread(void* pArg) if(useLongKeys){ // Allocate and populate the longkey array. longKeyAttrValue = (unsigned ***) malloc(sizeof(unsigned**) * tNoOfOperations ); - for (Uint32 n = 0; n < tNoOfOperations; n++) + Uint32 n; + for (n = 0; n < tNoOfOperations; n++) longKeyAttrValue[n] = (unsigned **) malloc(sizeof(unsigned*) * tNoOfLongPK ); - for (Uint32 n = 0; n < tNoOfOperations; n++){ + for (n = 0; n < tNoOfOperations; n++){ for (Uint32 i = 0; i < tNoOfLongPK ; i++) { longKeyAttrValue[n][i] = (unsigned *) malloc(sizeof(unsigned) * tSizeOfLongPK); memset(longKeyAttrValue[n][i], 0, sizeof(unsigned) * tSizeOfLongPK); @@ -1064,13 +1065,14 @@ static void sleepBeforeStartingTest(int seconds){ static int createTables(Ndb* pMyNdb){ - for (Uint32 i = 0; i < tNoOfAttributes; i++){ + int i; + for (i = 0; i < tNoOfAttributes; i++){ snprintf(attrName[i], MAXSTRLEN, "COL%d", i); } // Note! Uses only uppercase letters in table name's // so that we can look at the tables with SQL - for (Uint32 i = 0; i < tNoOfTables; i++){ + for (i = 0; i < tNoOfTables; i++){ if (theStdTableNameFlag == 0){ snprintf(tableName[i], MAXSTRLEN, "TAB%d_%d", i, (int)(NdbTick_CurrentMillisecond() / 1000)); @@ -1079,7 +1081,7 @@ createTables(Ndb* pMyNdb){ } } - for(unsigned i = 0; i < tNoOfTables; i++){ + for(i = 0; i < tNoOfTables; i++){ ndbout << "Creating " << tableName[i] << "... "; NdbDictionary::Table tmpTable(tableName[i]); diff --git a/ndb/test/ndbapi/flexTT.cpp b/ndb/test/ndbapi/flexTT.cpp index a82875de5c2..c0ff31d1677 100644 --- a/ndb/test/ndbapi/flexTT.cpp +++ b/ndb/test/ndbapi/flexTT.cpp @@ -173,7 +173,7 @@ NDB_COMMAND(flexTT, "flexTT", "flexTT", "flexTT", 65535) { ThreadNdb* pThreadData; int returnValue = NDBT_OK; - + int i; flexTTErrorData = new ErrorData; flexTTErrorData->resetErrorCounters(); @@ -250,7 +250,7 @@ NDB_COMMAND(flexTT, "flexTT", "flexTT", "flexTT", 65535) * Create NDB objects. * ****************************************************************/ resetThreads(); - for (int i = 0; i < tNoOfThreads ; i++) { + for (i = 0; i < tNoOfThreads ; i++) { pThreadData[i].threadNo = i; threadLife[i] = NdbThread_Create(threadLoop, (void**)&pThreadData[i], @@ -301,7 +301,7 @@ NDB_COMMAND(flexTT, "flexTT", "flexTT", "flexTT", 65535) execute(stStop); void * tmp; - for(int i = 0; i<tNoOfThreads; i++){ + for(i = 0; i<tNoOfThreads; i++){ NdbThread_WaitFor(threadLife[i], &tmp); NdbThread_Destroy(&threadLife[i]); } diff --git a/ndb/test/ndbapi/old_dirs/testBackup/Makefile b/ndb/test/ndbapi/old_dirs/testBackup/Makefile index ce0e404803c..abf47dcfb2d 100644 --- a/ndb/test/ndbapi/old_dirs/testBackup/Makefile +++ b/ndb/test/ndbapi/old_dirs/testBackup/Makefile @@ -3,7 +3,6 @@ include .defs.mk TYPE = ndbapitest BIN_TARGET = testBackup -BIN_TARGET_LIBS += bank SOURCES = testBackup.cpp include $(NDB_TOP)/Epilogue.mk diff --git a/ndb/test/ndbapi/old_dirs/testGrep/Makefile b/ndb/test/ndbapi/old_dirs/testGrep/Makefile index 34fdd7113d0..6bad3d56a00 100644 --- a/ndb/test/ndbapi/old_dirs/testGrep/Makefile +++ b/ndb/test/ndbapi/old_dirs/testGrep/Makefile @@ -3,7 +3,6 @@ include .defs.mk TYPE = ndbapitest DIRS = verify BIN_TARGET = testGrep -BIN_TARGET_LIBS += bank SOURCES = testGrep.cpp include $(NDB_TOP)/Epilogue.mk diff --git a/ndb/test/ndbapi/old_dirs/testGrep/verify/Makefile b/ndb/test/ndbapi/old_dirs/testGrep/verify/Makefile index 4e6182de6b2..256e3c98f36 100644 --- a/ndb/test/ndbapi/old_dirs/testGrep/verify/Makefile +++ b/ndb/test/ndbapi/old_dirs/testGrep/verify/Makefile @@ -3,7 +3,6 @@ include .defs.mk TYPE = ndbapitest BIN_TARGET = testGrepVerify -BIN_TARGET_LIBS += bank SOURCES = testGrepVerify.cpp CFLAGS_testGrepVerify.cpp += -I$(call fixpath,$(NDB_TOP)/include/kernel) -I$(call fixpath,$(NDB_TOP)/include/mgmcommon) diff --git a/ndb/test/ndbapi/testBackup.cpp b/ndb/test/ndbapi/testBackup.cpp index 129eced54b0..d328a7db292 100644 --- a/ndb/test/ndbapi/testBackup.cpp +++ b/ndb/test/ndbapi/testBackup.cpp @@ -205,6 +205,11 @@ int runClearTable(NDBT_Context* ctx, NDBT_Step* step){ return NDBT_OK; } +int runDropTable(NDBT_Context* ctx, NDBT_Step* step){ + GETNDB(step)->getDictionary()->dropTable(ctx->getTab()->getName()); + return NDBT_OK; +} + #include "bank/Bank.hpp" int runCreateBank(NDBT_Context* ctx, NDBT_Step* step){ @@ -408,7 +413,7 @@ TESTCASE("BackupOne", INITIALIZER(runRestoreOne); VERIFIER(runVerifyOne); FINALIZER(runClearTable); - + FINALIZER(runDropTable); } TESTCASE("BackupBank", "Test that backup and restore works during transaction load\n" @@ -428,7 +433,6 @@ TESTCASE("BackupBank", STEP(runBackupBank); VERIFIER(runRestoreBankAndVerify); // FINALIZER(runDropBank); - } TESTCASE("NFMaster", "Test that backup behaves during node failiure\n"){ diff --git a/ndb/test/ndbapi/testBasic.cpp b/ndb/test/ndbapi/testBasic.cpp index 64dfe492c2c..26622f9b066 100644 --- a/ndb/test/ndbapi/testBasic.cpp +++ b/ndb/test/ndbapi/testBasic.cpp @@ -29,9 +29,18 @@ * delete should be visible to same transaction * */ +int runLoadTable2(NDBT_Context* ctx, NDBT_Step* step) +{ + int records = ctx->getNumRecords(); + HugoTransactions hugoTrans(*ctx->getTab()); + if (hugoTrans.loadTable(GETNDB(step), records, 512, false, 0, true) != 0){ + return NDBT_FAILED; + } + return NDBT_OK; +} -int runLoadTable(NDBT_Context* ctx, NDBT_Step* step){ - +int runLoadTable(NDBT_Context* ctx, NDBT_Step* step) +{ int records = ctx->getNumRecords(); HugoTransactions hugoTrans(*ctx->getTab()); if (hugoTrans.loadTable(GETNDB(step), records) != 0){ @@ -255,7 +264,7 @@ static int readOneNoCommit(Ndb* pNdb, NdbConnection* pTrans, const NdbDictionary::Table* tab,NDBT_ResultRow * row){ - + int a; NdbOperation * pOp = pTrans->getNdbOperation(tab->getName()); if (pOp == NULL){ ERR(pTrans->getNdbError()); @@ -271,7 +280,7 @@ readOneNoCommit(Ndb* pNdb, NdbConnection* pTrans, } // Define primary keys - for(int a = 0; a<tab->getNoOfColumns(); a++){ + for(a = 0; a<tab->getNoOfColumns(); a++){ if (tab->getColumn(a)->getPrimaryKey() == true){ if(tmp.equalForAttr(pOp, a, 0) != 0){ ERR(pTrans->getNdbError()); @@ -281,7 +290,7 @@ readOneNoCommit(Ndb* pNdb, NdbConnection* pTrans, } // Define attributes to read - for(int a = 0; a<tab->getNoOfColumns(); a++){ + for(a = 0; a<tab->getNoOfColumns(); a++){ if((row->attributeStore(a) = pOp->getValue(tab->getColumn(a)->getName())) == 0) { ERR(pTrans->getNdbError()); @@ -630,35 +639,35 @@ int runNoCommitRollback630(NDBT_Context* ctx, NDBT_Step* step){ int runNoCommitAndClose(NDBT_Context* ctx, NDBT_Step* step){ - int result = NDBT_OK; + int i, result = NDBT_OK; HugoOperations hugoOps(*ctx->getTab()); Ndb* pNdb = GETNDB(step); do{ // Read CHECK(hugoOps.startTransaction(pNdb) == 0); - for (int i = 0; i < 10; i++) + for (i = 0; i < 10; i++) CHECK(hugoOps.pkReadRecord(pNdb, i, true) == 0); CHECK(hugoOps.execute_NoCommit(pNdb) == 0); CHECK(hugoOps.closeTransaction(pNdb) == 0); // Update CHECK(hugoOps.startTransaction(pNdb) == 0); - for (int i = 0; i < 10; i++) + for (i = 0; i < 10; i++) CHECK(hugoOps.pkUpdateRecord(pNdb, i) == 0); CHECK(hugoOps.execute_NoCommit(pNdb) == 0); CHECK(hugoOps.closeTransaction(pNdb) == 0); // Delete CHECK(hugoOps.startTransaction(pNdb) == 0); - for (int i = 0; i < 10; i++) + for (i = 0; i < 10; i++) CHECK(hugoOps.pkDeleteRecord(pNdb, i) == 0); CHECK(hugoOps.execute_NoCommit(pNdb) == 0); CHECK(hugoOps.closeTransaction(pNdb) == 0); // Try to insert, record should already exist CHECK(hugoOps.startTransaction(pNdb) == 0); - for (int i = 0; i < 10; i++) + for (i = 0; i < 10; i++) CHECK(hugoOps.pkInsertRecord(pNdb, i) == 0); CHECK(hugoOps.execute_Commit(pNdb) == 630); CHECK(hugoOps.closeTransaction(pNdb) == 0); @@ -772,14 +781,14 @@ int runCheckRollbackDeleteMultiple(NDBT_Context* ctx, NDBT_Step* step){ CHECK(hugoOps.closeTransaction(pNdb) == 0); Uint32 updatesValue = 0; - + Uint32 j; for(Uint32 i = 0; i<1; i++){ // Read record 5 - 10 CHECK(hugoOps.startTransaction(pNdb) == 0); CHECK(hugoOps.pkReadRecord(pNdb, 5, true, 10) == 0); CHECK(hugoOps.execute_NoCommit(pNdb) == 0); - for(Uint32 j = 0; j<10; j++){ + for(j = 0; j<10; j++){ // Update record 5 - 10 updatesValue++; CHECK(hugoOps.pkUpdateRecord(pNdb, 5, 10, updatesValue) == 0); @@ -790,7 +799,7 @@ int runCheckRollbackDeleteMultiple(NDBT_Context* ctx, NDBT_Step* step){ CHECK(hugoOps.verifyUpdatesValue(updatesValue) == 0); } - for(Uint32 j = 0; j<10; j++){ + for(j = 0; j<10; j++){ // Delete record 5 - 10 times CHECK(hugoOps.pkDeleteRecord(pNdb, 5, 10) == 0); CHECK(hugoOps.execute_NoCommit(pNdb) == 0); @@ -953,6 +962,7 @@ int runMassiveRollback(NDBT_Context* ctx, NDBT_Step* step){ const Uint32 OPS_TOTAL = 4096; for(int row = 0; row < records; row++){ + int res; CHECK(hugoOps.startTransaction(pNdb) == 0); for(int i = 0; i<OPS_TOTAL; i += OPS_PER_TRANS){ for(int j = 0; j<OPS_PER_TRANS; j++){ @@ -963,7 +973,12 @@ int runMassiveRollback(NDBT_Context* ctx, NDBT_Step* step){ if(result != NDBT_OK){ break; } - CHECK(hugoOps.execute_NoCommit(pNdb) == 0); + res = hugoOps.execute_NoCommit(pNdb); + if(res != 0){ + NdbError err = pNdb->getNdbError(res); + CHECK(err.classification == NdbError::TimeoutExpired); + break; + } } if(result != NDBT_OK){ break; @@ -1255,6 +1270,11 @@ TESTCASE("MassiveRollback2", INITIALIZER(runMassiveRollback2); FINALIZER(runClearTable2); } +TESTCASE("MassiveTransaction", + "Test very large insert transaction"){ + INITIALIZER(runLoadTable2); + FINALIZER(runClearTable2); +} NDBT_TESTSUITE_END(testBasic); int main(int argc, const char** argv){ diff --git a/ndb/test/ndbapi/testBlobs.cpp b/ndb/test/ndbapi/testBlobs.cpp index 001ec83630a..64881ca39ab 100644 --- a/ndb/test/ndbapi/testBlobs.cpp +++ b/ndb/test/ndbapi/testBlobs.cpp @@ -38,6 +38,7 @@ struct Bcol { }; struct Opt { + unsigned m_batch; bool m_core; bool m_dbg; bool m_dbgall; @@ -46,7 +47,8 @@ struct Opt { unsigned m_parts; unsigned m_rows; unsigned m_seed; - char m_skip[255]; + const char* m_skip; + const char* m_style; // metadata const char* m_tname; const char* m_x1name; // hash index @@ -60,6 +62,7 @@ struct Opt { int m_bug; int (*m_bugtest)(); Opt() : + m_batch(7), m_core(false), m_dbg(false), m_dbgall(false), @@ -68,6 +71,8 @@ struct Opt { m_parts(10), m_rows(100), m_seed(0), + m_skip(""), + m_style("012"), // metadata m_tname("TBLOB1"), m_x1name("TBLOB1X1"), @@ -80,7 +85,6 @@ struct Opt { // bugs m_bug(0), m_bugtest(0) { - memset(m_skip, false, sizeof(m_skip)); } }; @@ -92,6 +96,7 @@ printusage() Opt d; ndbout << "usage: testBlobs options [default/max]" << endl + << " -batch N number of pk ops in batch [" << d.m_batch << "]" << endl << " -core dump core on error" << endl << " -dbg print debug" << endl << " -dbgall print also NDB API debug (if compiled in)" << endl @@ -101,7 +106,8 @@ printusage() << " -parts N max parts in blob value [" << d.m_parts << "]" << endl << " -rows N number of rows [" << d.m_rows << "]" << endl << " -seed N random seed 0=loop number [" << d.m_seed << "]" << endl - << " -skip xxx skip these tests (see list)" << endl + << " -skip xxx skip these tests (see list) [" << d.m_skip << endl + << " -style xxx access styles to test (see list) [" << d.m_style << "]" << endl << "metadata" << endl << " -pk2len N length of PK2 [" << d.m_pk2len << "/" << g_max_pk2len <<"]" << endl << " -oneblob only 1 blob attribute [default 2]" << endl @@ -111,8 +117,10 @@ printusage() << " s table scans" << endl << " r ordered index scans" << endl << " u update blob value" << endl - << " v getValue / setValue" << endl - << " w readData / writeData" << endl + << "access styles for -style" << endl + << " 0 getValue / setValue" << endl + << " 1 setActiveHook" << endl + << " 2 readData / writeData" << endl << "bug tests (no blob test)" << endl << " -bug 4088 ndb api hang with mixed ops on index table" << endl << " -bug 2222 delete + write gives 626" << endl @@ -122,11 +130,16 @@ printusage() static Opt g_opt; -static char& -skip(unsigned x) +static bool +skipcase(int x) { - assert(x < sizeof(g_opt.m_skip)); - return g_opt.m_skip[x]; + return strchr(g_opt.m_skip, x) != 0; +} + +static bool +skipstyle(int x) +{ + return strchr(g_opt.m_style, '0' + x) == 0; } static Ndb* g_ndb = 0; @@ -138,11 +151,12 @@ static NdbScanOperation* g_ops = 0; static NdbBlob* g_bh1 = 0; static NdbBlob* g_bh2 = 0; static bool g_printerror = true; +static unsigned g_loop = 0; static void printerror(int line, const char* msg) { - ndbout << "line " << line << ": " << msg << " failed" << endl; + ndbout << "line " << line << " FAIL " << msg << endl; if (! g_printerror) { return; } @@ -205,6 +219,7 @@ static int createTable() { NdbDictionary::Table tab(g_opt.m_tname); + tab.setLogging(false); // col PK1 - Uint32 { NdbDictionary::Column col("PK1"); col.setType(NdbDictionary::Column::Unsigned); @@ -228,11 +243,11 @@ createTable() col.setPrimaryKey(true); tab.addColumn(col); } - // col BL2 - Clob nullable + // col BL2 - Text nullable if (! g_opt.m_oneblob) { NdbDictionary::Column col("BL2"); const Bcol& b = g_opt.m_blob2; - col.setType(NdbDictionary::Column::Clob); + col.setType(NdbDictionary::Column::Text); col.setNullable(true); col.setInlineSize(b.m_inline); col.setPartSize(b.m_partsize); @@ -245,6 +260,7 @@ createTable() if (g_opt.m_pk2len != 0) { NdbDictionary::Index idx(g_opt.m_x1name); idx.setType(NdbDictionary::Index::UniqueHashIndex); + idx.setLogging(false); idx.setTable(g_opt.m_tname); idx.addColumnName("PK2"); CHK(g_dic->createIndex(idx) == 0); @@ -281,7 +297,7 @@ struct Bval { m_buf = new char [m_buflen]; trash(); } - void copy(const Bval& v) { + void copyfrom(const Bval& v) { m_len = v.m_len; delete [] m_val; if (v.m_val == 0) @@ -313,10 +329,10 @@ struct Tup { m_blob1.alloc(g_opt.m_blob1.m_inline + g_opt.m_blob1.m_partsize * g_opt.m_parts); m_blob2.alloc(g_opt.m_blob2.m_inline + g_opt.m_blob2.m_partsize * g_opt.m_parts); } - void copy(const Tup& tup) { + void copyfrom(const Tup& tup) { assert(m_pk1 == tup.m_pk1); - m_blob1.copy(tup.m_blob1); - m_blob2.copy(tup.m_blob2); + m_blob1.copyfrom(tup.m_blob1); + m_blob2.copyfrom(tup.m_blob2); } private: Tup(const Tup&); @@ -358,6 +374,14 @@ calcBval(const Bcol& b, Bval& v, bool keepsize) } static void +calcBval(Tup& tup, bool keepsize) +{ + calcBval(g_opt.m_blob1, tup.m_blob1, keepsize); + if (! g_opt.m_oneblob) + calcBval(g_opt.m_blob2, tup.m_blob2, keepsize); +} + +static void calcTups(bool keepsize) { for (unsigned k = 0; k < g_opt.m_rows; k++) { @@ -371,31 +395,59 @@ calcTups(bool keepsize) tup.m_pk2[i] = 'a' + i % 26; } } - calcBval(g_opt.m_blob1, tup.m_blob1, keepsize); - if (! g_opt.m_oneblob) - calcBval(g_opt.m_blob2, tup.m_blob2, keepsize); + calcBval(tup, keepsize); } } // blob handle ops static int +getBlobHandles(NdbOperation* opr) +{ + CHK((g_bh1 = opr->getBlobHandle("BL1")) != 0); + if (! g_opt.m_oneblob) + CHK((g_bh2 = opr->getBlobHandle("BL2")) != 0); + return 0; +} + +static int +getBlobHandles(NdbIndexOperation* opx) +{ + CHK((g_bh1 = opx->getBlobHandle("BL1")) != 0); + if (! g_opt.m_oneblob) + CHK((g_bh2 = opx->getBlobHandle("BL2")) != 0); + return 0; +} + +static int +getBlobHandles(NdbScanOperation* ops) +{ + CHK((g_bh1 = ops->getBlobHandle("BL1")) != 0); + if (! g_opt.m_oneblob) + CHK((g_bh2 = ops->getBlobHandle("BL2")) != 0); + return 0; +} + +static int getBlobLength(NdbBlob* h, unsigned& len) { Uint64 len2 = (unsigned)-1; CHK(h->getLength(len2) == 0); len = (unsigned)len2; assert(len == len2); + DBG("getBlobLength " << h->getColumn()->getName() << " len=" << len); return 0; } +// setValue / getValue + static int setBlobValue(NdbBlob* h, const Bval& v) { bool null = (v.m_val == 0); bool isNull; unsigned len; - DBG("set " << h->getColumn()->getName() << " len=" << v.m_len << " null=" << null); + DBG("setValue " << h->getColumn()->getName() << " len=" << v.m_len << " null=" << null); if (null) { CHK(h->setNull() == 0); isNull = false; @@ -410,10 +462,19 @@ setBlobValue(NdbBlob* h, const Bval& v) } static int +setBlobValue(const Tup& tup) +{ + CHK(setBlobValue(g_bh1, tup.m_blob1) == 0); + if (! g_opt.m_oneblob) + CHK(setBlobValue(g_bh2, tup.m_blob2) == 0); + return 0; +} + +static int getBlobValue(NdbBlob* h, const Bval& v) { bool null = (v.m_val == 0); - DBG("get " << h->getColumn()->getName() << " len=" << v.m_len << " null=" << null); + DBG("getValue " << h->getColumn()->getName() << " buflen=" << v.m_buflen); CHK(h->getValue(v.m_buf, v.m_buflen) == 0); return 0; } @@ -456,6 +517,8 @@ verifyBlobValue(const Tup& tup) return 0; } +// readData / writeData + static int writeBlobData(NdbBlob* h, const Bval& v) { @@ -469,6 +532,7 @@ writeBlobData(NdbBlob* h, const Bval& v) CHK(h->getNull(isNull) == 0 && isNull == true); CHK(getBlobLength(h, len) == 0 && len == 0); } else { + CHK(h->truncate(v.m_len) == 0); unsigned n = 0; do { unsigned m = g_opt.m_full ? v.m_len : urandom(v.m_len + 1); @@ -487,6 +551,15 @@ writeBlobData(NdbBlob* h, const Bval& v) } static int +writeBlobData(const Tup& tup) +{ + CHK(writeBlobData(g_bh1, tup.m_blob1) == 0); + if (! g_opt.m_oneblob) + CHK(writeBlobData(g_bh2, tup.m_blob2) == 0); + return 0; +} + +static int readBlobData(NdbBlob* h, const Bval& v) { bool null = (v.m_val == 0); @@ -531,6 +604,71 @@ readBlobData(const Tup& tup) return 0; } +// hooks + +static NdbBlob::ActiveHook blobWriteHook; + +static int +blobWriteHook(NdbBlob* h, void* arg) +{ + DBG("blobWriteHook"); + Bval& v = *(Bval*)arg; + CHK(writeBlobData(h, v) == 0); + return 0; +} + +static int +setBlobWriteHook(NdbBlob* h, Bval& v) +{ + DBG("setBlobWriteHook"); + CHK(h->setActiveHook(blobWriteHook, &v) == 0); + return 0; +} + +static int +setBlobWriteHook(Tup& tup) +{ + CHK(setBlobWriteHook(g_bh1, tup.m_blob1) == 0); + if (! g_opt.m_oneblob) + CHK(setBlobWriteHook(g_bh2, tup.m_blob2) == 0); + return 0; +} + +static NdbBlob::ActiveHook blobReadHook; + +// no PK yet to identify tuple so just read the value +static int +blobReadHook(NdbBlob* h, void* arg) +{ + DBG("blobReadHook"); + Bval& v = *(Bval*)arg; + unsigned len; + CHK(getBlobLength(h, len) == 0); + v.alloc(len); + Uint32 maxlen = 0xffffffff; + CHK(h->readData(v.m_buf, maxlen) == 0); + DBG("read " << maxlen << " bytes"); + CHK(len == maxlen); + return 0; +} + +static int +setBlobReadHook(NdbBlob* h, Bval& v) +{ + DBG("setBlobReadHook"); + CHK(h->setActiveHook(blobReadHook, &v) == 0); + return 0; +} + +static int +setBlobReadHook(Tup& tup) +{ + CHK(setBlobReadHook(g_bh1, tup.m_blob1) == 0); + if (! g_opt.m_oneblob) + CHK(setBlobReadHook(g_bh2, tup.m_blob2) == 0); + return 0; +} + // verify blob data static int @@ -540,7 +678,11 @@ verifyHeadInline(const Bcol& c, const Bval& v, NdbRecAttr* ra) CHK(ra->isNULL() == 1); } else { CHK(ra->isNULL() == 0); - CHK(ra->u_64_value() == v.m_len); + const NdbBlob::Head* head = (const NdbBlob::Head*)ra->aRef(); + CHK(head->length == v.m_len); + const char* data = (const char*)(head + 1); + for (unsigned i = 0; i < head->length && i < c.m_inline; i++) + CHK(data[i] == v.m_val[i]); } return 0; } @@ -548,7 +690,7 @@ verifyHeadInline(const Bcol& c, const Bval& v, NdbRecAttr* ra) static int verifyHeadInline(const Tup& tup) { - DBG("verifyHeadInline pk1=" << tup.m_pk1); + DBG("verifyHeadInline pk1=" << hex << tup.m_pk1); CHK((g_con = g_ndb->startTransaction()) != 0); CHK((g_opr = g_con->getNdbOperation(g_opt.m_tname)) != 0); CHK(g_opr->readTuple() == 0); @@ -580,17 +722,18 @@ verifyHeadInline(const Tup& tup) static int verifyBlobTable(const Bcol& b, const Bval& v, Uint32 pk1, bool exists) { - DBG("verify " << b.m_btname << " pk1=" << pk1); + DBG("verify " << b.m_btname << " pk1=" << hex << pk1); NdbRecAttr* ra_pk; NdbRecAttr* ra_part; NdbRecAttr* ra_data; + NdbResultSet* rs; CHK((g_con = g_ndb->startTransaction()) != 0); - CHK((g_opr = g_con->getNdbOperation(b.m_btname)) != 0); - CHK(g_opr->openScanRead() == 0); - CHK((ra_pk = g_opr->getValue("PK")) != 0); - CHK((ra_part = g_opr->getValue("PART")) != 0); - CHK((ra_data = g_opr->getValue("DATA")) != 0); - CHK(g_con->executeScan() == 0); + CHK((g_ops = g_con->getNdbScanOperation(b.m_btname)) != 0); + CHK((rs = g_ops->readTuples()) != 0); + CHK((ra_pk = g_ops->getValue("PK")) != 0); + CHK((ra_part = g_ops->getValue("PART")) != 0); + CHK((ra_data = g_ops->getValue("DATA")) != 0); + CHK(g_con->execute(NoCommit) == 0); unsigned partcount; if (! exists || v.m_len <= b.m_inline) partcount = 0; @@ -600,7 +743,7 @@ verifyBlobTable(const Bcol& b, const Bval& v, Uint32 pk1, bool exists) memset(seen, 0, partcount); while (1) { int ret; - CHK((ret = g_con->nextScanResult()) == 0 || ret == 1); + CHK((ret = rs->nextResult()) == 0 || ret == 1); if (ret == 1) break; if (pk1 != ra_pk->u_32_value()) @@ -620,7 +763,7 @@ verifyBlobTable(const Bcol& b, const Bval& v, Uint32 pk1, bool exists) for (unsigned i = 0; i < partcount; i++) CHK(seen[i] == 1); g_ndb->closeTransaction(g_con); - g_opr = 0; + g_ops = 0; g_con = 0; return 0; } @@ -639,7 +782,7 @@ verifyBlob() { for (unsigned k = 0; k < g_opt.m_rows; k++) { const Tup& tup = g_tups[k]; - DBG("verifyBlob pk1=" << tup.m_pk1); + DBG("verifyBlob pk1=" << hex << tup.m_pk1); CHK(verifyHeadInline(tup) == 0); CHK(verifyBlobTable(tup) == 0); } @@ -648,105 +791,120 @@ verifyBlob() // operations +static const char* stylename[3] = { + "style=getValue/setValue", + "style=setActiveHook", + "style=readData/writeData" +}; + +// pk ops + static int -insertPk(bool rw) +insertPk(int style) { - DBG("--- insertPk ---"); + DBG("--- insertPk " << stylename[style] << " ---"); + unsigned n = 0; + CHK((g_con = g_ndb->startTransaction()) != 0); for (unsigned k = 0; k < g_opt.m_rows; k++) { Tup& tup = g_tups[k]; - DBG("insertPk pk1=" << tup.m_pk1); - CHK((g_con = g_ndb->startTransaction()) != 0); + DBG("insertPk pk1=" << hex << tup.m_pk1); CHK((g_opr = g_con->getNdbOperation(g_opt.m_tname)) != 0); CHK(g_opr->insertTuple() == 0); CHK(g_opr->equal("PK1", tup.m_pk1) == 0); if (g_opt.m_pk2len != 0) CHK(g_opr->equal("PK2", tup.m_pk2) == 0); - CHK((g_bh1 = g_opr->getBlobHandle("BL1")) != 0); - if (! g_opt.m_oneblob) - CHK((g_bh2 = g_opr->getBlobHandle("BL2")) != 0); - if (! rw) { - CHK(setBlobValue(g_bh1, tup.m_blob1) == 0); - if (! g_opt.m_oneblob) - CHK(setBlobValue(g_bh2, tup.m_blob2) == 0); + CHK(getBlobHandles(g_opr) == 0); + if (style == 0) { + CHK(setBlobValue(tup) == 0); + } else if (style == 1) { + // non-nullable must be set + CHK(g_bh1->setValue("", 0) == 0); + CHK(setBlobWriteHook(tup) == 0); } else { // non-nullable must be set CHK(g_bh1->setValue("", 0) == 0); CHK(g_con->execute(NoCommit) == 0); - CHK(writeBlobData(g_bh1, tup.m_blob1) == 0); - if (! g_opt.m_oneblob) - CHK(writeBlobData(g_bh2, tup.m_blob2) == 0); + CHK(writeBlobData(tup) == 0); + } + // just another trap + if (urandom(10) == 0) + CHK(g_con->execute(NoCommit) == 0); + if (++n == g_opt.m_batch) { + CHK(g_con->execute(Commit) == 0); + g_ndb->closeTransaction(g_con); + CHK((g_con = g_ndb->startTransaction()) != 0); + n = 0; } - CHK(g_con->execute(Commit) == 0); - g_ndb->closeTransaction(g_con); g_opr = 0; - g_con = 0; tup.m_exists = true; } + if (n != 0) { + CHK(g_con->execute(Commit) == 0); + n = 0; + } + g_ndb->closeTransaction(g_con); + g_con = 0; return 0; } static int -updatePk(bool rw) +readPk(int style) { - DBG("--- updatePk ---"); + DBG("--- readPk " << stylename[style] << " ---"); for (unsigned k = 0; k < g_opt.m_rows; k++) { Tup& tup = g_tups[k]; - DBG("updatePk pk1=" << tup.m_pk1); + DBG("readPk pk1=" << hex << tup.m_pk1); CHK((g_con = g_ndb->startTransaction()) != 0); CHK((g_opr = g_con->getNdbOperation(g_opt.m_tname)) != 0); - CHK(g_opr->updateTuple() == 0); + CHK(g_opr->readTuple() == 0); CHK(g_opr->equal("PK1", tup.m_pk1) == 0); if (g_opt.m_pk2len != 0) CHK(g_opr->equal("PK2", tup.m_pk2) == 0); - CHK((g_bh1 = g_opr->getBlobHandle("BL1")) != 0); - if (! g_opt.m_oneblob) - CHK((g_bh2 = g_opr->getBlobHandle("BL2")) != 0); - if (! rw) { - CHK(setBlobValue(g_bh1, tup.m_blob1) == 0); - if (! g_opt.m_oneblob) - CHK(setBlobValue(g_bh2, tup.m_blob2) == 0); + CHK(getBlobHandles(g_opr) == 0); + if (style == 0) { + CHK(getBlobValue(tup) == 0); + } else if (style == 1) { + CHK(setBlobReadHook(tup) == 0); } else { CHK(g_con->execute(NoCommit) == 0); - CHK(writeBlobData(g_bh1, tup.m_blob1) == 0); - if (! g_opt.m_oneblob) - CHK(writeBlobData(g_bh2, tup.m_blob2) == 0); + CHK(readBlobData(tup) == 0); } CHK(g_con->execute(Commit) == 0); + if (style == 0 || style == 1) { + CHK(verifyBlobValue(tup) == 0); + } g_ndb->closeTransaction(g_con); g_opr = 0; g_con = 0; - tup.m_exists = true; } return 0; } static int -updateIdx(bool rw) +updatePk(int style) { - DBG("--- updateIdx ---"); + DBG("--- updatePk " << stylename[style] << " ---"); for (unsigned k = 0; k < g_opt.m_rows; k++) { Tup& tup = g_tups[k]; - DBG("updateIdx pk1=" << tup.m_pk1); + DBG("updatePk pk1=" << hex << tup.m_pk1); CHK((g_con = g_ndb->startTransaction()) != 0); - CHK((g_opx = g_con->getNdbIndexOperation(g_opt.m_x1name, g_opt.m_tname)) != 0); - CHK(g_opx->updateTuple() == 0); - CHK(g_opx->equal("PK2", tup.m_pk2) == 0); - CHK((g_bh1 = g_opx->getBlobHandle("BL1")) != 0); - if (! g_opt.m_oneblob) - CHK((g_bh2 = g_opx->getBlobHandle("BL2")) != 0); - if (! rw) { - CHK(setBlobValue(g_bh1, tup.m_blob1) == 0); - if (! g_opt.m_oneblob) - CHK(setBlobValue(g_bh2, tup.m_blob2) == 0); + CHK((g_opr = g_con->getNdbOperation(g_opt.m_tname)) != 0); + CHK(g_opr->updateTuple() == 0); + CHK(g_opr->equal("PK1", tup.m_pk1) == 0); + if (g_opt.m_pk2len != 0) + CHK(g_opr->equal("PK2", tup.m_pk2) == 0); + CHK(getBlobHandles(g_opr) == 0); + if (style == 0) { + CHK(setBlobValue(tup) == 0); + } else if (style == 1) { + CHK(setBlobWriteHook(tup) == 0); } else { CHK(g_con->execute(NoCommit) == 0); - CHK(writeBlobData(g_bh1, tup.m_blob1) == 0); - if (! g_opt.m_oneblob) - CHK(writeBlobData(g_bh2, tup.m_blob2) == 0); + CHK(writeBlobData(tup) == 0); } CHK(g_con->execute(Commit) == 0); g_ndb->closeTransaction(g_con); - g_opx = 0; + g_opr = 0; g_con = 0; tup.m_exists = true; } @@ -754,74 +912,115 @@ updateIdx(bool rw) } static int -readPk(bool rw) +deletePk() { - DBG("--- readPk ---"); + DBG("--- deletePk ---"); for (unsigned k = 0; k < g_opt.m_rows; k++) { Tup& tup = g_tups[k]; - DBG("readPk pk1=" << tup.m_pk1); + DBG("deletePk pk1=" << hex << tup.m_pk1); CHK((g_con = g_ndb->startTransaction()) != 0); CHK((g_opr = g_con->getNdbOperation(g_opt.m_tname)) != 0); - CHK(g_opr->readTuple() == 0); + CHK(g_opr->deleteTuple() == 0); CHK(g_opr->equal("PK1", tup.m_pk1) == 0); if (g_opt.m_pk2len != 0) CHK(g_opr->equal("PK2", tup.m_pk2) == 0); - CHK((g_bh1 = g_opr->getBlobHandle("BL1")) != 0); - if (! g_opt.m_oneblob) - CHK((g_bh2 = g_opr->getBlobHandle("BL2")) != 0); - if (! rw) { + CHK(g_con->execute(Commit) == 0); + g_ndb->closeTransaction(g_con); + g_opr = 0; + g_con = 0; + tup.m_exists = false; + } + return 0; +} + +// hash index ops + +static int +readIdx(int style) +{ + DBG("--- readIdx " << stylename[style] << " ---"); + for (unsigned k = 0; k < g_opt.m_rows; k++) { + Tup& tup = g_tups[k]; + DBG("readIdx pk1=" << hex << tup.m_pk1); + CHK((g_con = g_ndb->startTransaction()) != 0); + CHK((g_opx = g_con->getNdbIndexOperation(g_opt.m_x1name, g_opt.m_tname)) != 0); + CHK(g_opx->readTuple() == 0); + CHK(g_opx->equal("PK2", tup.m_pk2) == 0); + CHK(getBlobHandles(g_opx) == 0); + if (style == 0) { CHK(getBlobValue(tup) == 0); + } else if (style == 1) { + CHK(setBlobReadHook(tup) == 0); } else { CHK(g_con->execute(NoCommit) == 0); CHK(readBlobData(tup) == 0); } CHK(g_con->execute(Commit) == 0); - if (! rw) { + if (style == 0 || style == 1) { CHK(verifyBlobValue(tup) == 0); } g_ndb->closeTransaction(g_con); - g_opr = 0; + g_opx = 0; g_con = 0; } return 0; } static int -readIdx(bool rw) +updateIdx(int style) { - DBG("--- readIdx ---"); + DBG("--- updateIdx " << stylename[style] << " ---"); for (unsigned k = 0; k < g_opt.m_rows; k++) { Tup& tup = g_tups[k]; - DBG("readIdx pk1=" << tup.m_pk1); + DBG("updateIdx pk1=" << hex << tup.m_pk1); CHK((g_con = g_ndb->startTransaction()) != 0); CHK((g_opx = g_con->getNdbIndexOperation(g_opt.m_x1name, g_opt.m_tname)) != 0); - CHK(g_opx->readTuple() == 0); + CHK(g_opx->updateTuple() == 0); CHK(g_opx->equal("PK2", tup.m_pk2) == 0); - CHK((g_bh1 = g_opx->getBlobHandle("BL1")) != 0); - if (! g_opt.m_oneblob) - CHK((g_bh2 = g_opx->getBlobHandle("BL2")) != 0); - if (! rw) { - CHK(getBlobValue(tup) == 0); + CHK(getBlobHandles(g_opx) == 0); + if (style == 0) { + CHK(setBlobValue(tup) == 0); + } else if (style == 1) { + CHK(setBlobWriteHook(tup) == 0); } else { CHK(g_con->execute(NoCommit) == 0); - CHK(readBlobData(tup) == 0); + CHK(writeBlobData(tup) == 0); } CHK(g_con->execute(Commit) == 0); - if (! rw) { - CHK(verifyBlobValue(tup) == 0); - } g_ndb->closeTransaction(g_con); g_opx = 0; g_con = 0; + tup.m_exists = true; + } + return 0; +} + +static int +deleteIdx() +{ + DBG("--- deleteIdx ---"); + for (unsigned k = 0; k < g_opt.m_rows; k++) { + Tup& tup = g_tups[k]; + DBG("deleteIdx pk1=" << hex << tup.m_pk1); + CHK((g_con = g_ndb->startTransaction()) != 0); + CHK((g_opx = g_con->getNdbIndexOperation(g_opt.m_x1name, g_opt.m_tname)) != 0); + CHK(g_opx->deleteTuple() == 0); + CHK(g_opx->equal("PK2", tup.m_pk2) == 0); + CHK(g_con->execute(Commit) == 0); + g_ndb->closeTransaction(g_con); + g_opx = 0; + g_con = 0; + tup.m_exists = false; } return 0; } +// scan ops table and index + static int -readScan(bool rw, bool idx) +readScan(int style, bool idx) { - const char* func = ! idx ? "scan read table" : "scan read index"; - DBG("--- " << func << " ---"); + DBG("--- " << "readScan" << (idx ? "Idx" : "") << " " << stylename[style] << " ---"); Tup tup; tup.alloc(); // allocate buffers NdbResultSet* rs; @@ -829,17 +1028,17 @@ readScan(bool rw, bool idx) if (! idx) { CHK((g_ops = g_con->getNdbScanOperation(g_opt.m_tname)) != 0); } else { - CHK((g_ops = g_con->getNdbScanOperation(g_opt.m_x2name, g_opt.m_tname)) != 0); + CHK((g_ops = g_con->getNdbIndexScanOperation(g_opt.m_x2name, g_opt.m_tname)) != 0); } - CHK((rs = g_ops->readTuples(240, NdbScanOperation::LM_Exclusive)) != 0); + CHK((rs = g_ops->readTuples(NdbScanOperation::LM_Exclusive)) != 0); CHK(g_ops->getValue("PK1", (char*)&tup.m_pk1) != 0); if (g_opt.m_pk2len != 0) CHK(g_ops->getValue("PK2", tup.m_pk2) != 0); - CHK((g_bh1 = g_ops->getBlobHandle("BL1")) != 0); - if (! g_opt.m_oneblob) - CHK((g_bh2 = g_ops->getBlobHandle("BL2")) != 0); - if (! rw) { + CHK(getBlobHandles(g_ops) == 0); + if (style == 0) { CHK(getBlobValue(tup) == 0); + } else if (style == 1) { + CHK(setBlobReadHook(tup) == 0); } CHK(g_con->execute(NoCommit) == 0); unsigned rows = 0; @@ -850,11 +1049,14 @@ readScan(bool rw, bool idx) CHK((ret = rs->nextResult(true)) == 0 || ret == 1); if (ret == 1) break; - DBG(func << " pk1=" << tup.m_pk1); + DBG("readScan" << (idx ? "Idx" : "") << " pk1=" << hex << tup.m_pk1); Uint32 k = tup.m_pk1 - g_opt.m_pk1off; CHK(k < g_opt.m_rows && g_tups[k].m_exists); - tup.copy(g_tups[k]); - if (! rw) { + tup.copyfrom(g_tups[k]); + if (style == 0) { + CHK(verifyBlobValue(tup) == 0); + } else if (style == 1) { + // execute ops generated by callbacks, if any CHK(verifyBlobValue(tup) == 0); } else { CHK(readBlobData(tup) == 0); @@ -869,61 +1071,72 @@ readScan(bool rw, bool idx) } static int -deletePk() +updateScan(int style, bool idx) { - DBG("--- deletePk ---"); - for (unsigned k = 0; k < g_opt.m_rows; k++) { - Tup& tup = g_tups[k]; - DBG("deletePk pk1=" << tup.m_pk1); - CHK((g_con = g_ndb->startTransaction()) != 0); - CHK((g_opr = g_con->getNdbOperation(g_opt.m_tname)) != 0); - CHK(g_opr->deleteTuple() == 0); - CHK(g_opr->equal("PK1", tup.m_pk1) == 0); - if (g_opt.m_pk2len != 0) - CHK(g_opr->equal("PK2", tup.m_pk2) == 0); - CHK(g_con->execute(Commit) == 0); - g_ndb->closeTransaction(g_con); - g_opr = 0; - g_con = 0; - tup.m_exists = false; + DBG("--- " << "updateScan" << (idx ? "Idx" : "") << " " << stylename[style] << " ---"); + Tup tup; + tup.alloc(); // allocate buffers + NdbResultSet* rs; + CHK((g_con = g_ndb->startTransaction()) != 0); + if (! idx) { + CHK((g_ops = g_con->getNdbScanOperation(g_opt.m_tname)) != 0); + } else { + CHK((g_ops = g_con->getNdbIndexScanOperation(g_opt.m_x2name, g_opt.m_tname)) != 0); } - return 0; -} - -static int -deleteIdx() -{ - DBG("--- deleteIdx ---"); - for (unsigned k = 0; k < g_opt.m_rows; k++) { - Tup& tup = g_tups[k]; - DBG("deleteIdx pk1=" << tup.m_pk1); - CHK((g_con = g_ndb->startTransaction()) != 0); - CHK((g_opx = g_con->getNdbIndexOperation(g_opt.m_x1name, g_opt.m_tname)) != 0); - CHK(g_opx->deleteTuple() == 0); - CHK(g_opx->equal("PK2", tup.m_pk2) == 0); - CHK(g_con->execute(Commit) == 0); - g_ndb->closeTransaction(g_con); - g_opx = 0; - g_con = 0; - tup.m_exists = false; + CHK((rs = g_ops->readTuples(NdbScanOperation::LM_Exclusive)) != 0); + CHK(g_ops->getValue("PK1", (char*)&tup.m_pk1) != 0); + if (g_opt.m_pk2len != 0) + CHK(g_ops->getValue("PK2", tup.m_pk2) != 0); + CHK(g_con->execute(NoCommit) == 0); + unsigned rows = 0; + while (1) { + int ret; + tup.m_pk1 = (Uint32)-1; + memset(tup.m_pk2, 'x', g_opt.m_pk2len); + CHK((ret = rs->nextResult(true)) == 0 || ret == 1); + if (ret == 1) + break; + DBG("updateScan" << (idx ? "Idx" : "") << " pk1=" << hex << tup.m_pk1); + Uint32 k = tup.m_pk1 - g_opt.m_pk1off; + CHK(k < g_opt.m_rows && g_tups[k].m_exists); + // calculate new blob values + calcBval(g_tups[k], false); + tup.copyfrom(g_tups[k]); + CHK((g_opr = rs->updateTuple()) != 0); + CHK(getBlobHandles(g_opr) == 0); + if (style == 0) { + CHK(setBlobValue(tup) == 0); + } else if (style == 1) { + CHK(setBlobWriteHook(tup) == 0); + } else { + CHK(g_con->execute(NoCommit) == 0); + CHK(writeBlobData(tup) == 0); + } + CHK(g_con->execute(NoCommit) == 0); + g_opr = 0; + rows++; } + CHK(g_con->execute(Commit) == 0); + g_ndb->closeTransaction(g_con); + g_con = 0; + g_ops = 0; + CHK(g_opt.m_rows == rows); return 0; } static int deleteScan(bool idx) { - const char* func = ! idx ? "scan delete table" : "scan delete index"; - DBG("--- " << func << " ---"); + DBG("--- " << "deleteScan" << (idx ? "Idx" : "") << " ---"); Tup tup; NdbResultSet* rs; CHK((g_con = g_ndb->startTransaction()) != 0); if (! idx) { CHK((g_ops = g_con->getNdbScanOperation(g_opt.m_tname)) != 0); } else { - CHK((g_ops = g_con->getNdbScanOperation(g_opt.m_x2name, g_opt.m_tname)) != 0); + CHK((g_ops = g_con->getNdbIndexScanOperation(g_opt.m_x2name, g_opt.m_tname)) != 0); } - CHK((rs = g_ops->readTuples(240, NdbScanOperation::LM_Exclusive)) != 0); + CHK((rs = g_ops->readTuples(NdbScanOperation::LM_Exclusive)) != 0); CHK(g_ops->getValue("PK1", (char*)&tup.m_pk1) != 0); if (g_opt.m_pk2len != 0) CHK(g_ops->getValue("PK2", tup.m_pk2) != 0); @@ -936,7 +1149,7 @@ deleteScan(bool idx) CHK((ret = rs->nextResult()) == 0 || ret == 1); if (ret == 1) break; - DBG(func << " pk1=" << tup.m_pk1); + DBG("deleteScan" << (idx ? "Idx" : "") << " pk1=" << hex << tup.m_pk1); CHK(rs->deleteTuple() == 0); CHK(g_con->execute(NoCommit) == 0); Uint32 k = tup.m_pk1 - g_opt.m_pk1off; @@ -947,7 +1160,6 @@ deleteScan(bool idx) CHK(g_con->execute(Commit) == 0); g_ndb->closeTransaction(g_con); g_con = 0; - g_opr = 0; g_ops = 0; CHK(g_opt.m_rows == rows); return 0; @@ -958,6 +1170,7 @@ deleteScan(bool idx) static int testmain() { + int style; g_ndb = new Ndb("TEST_DB"); CHK(g_ndb->init() == 0); CHK(g_ndb->waitUntilReady() == 0); @@ -980,69 +1193,75 @@ testmain() } if (g_opt.m_seed != 0) srandom(g_opt.m_seed); - for (unsigned loop = 0; g_opt.m_loop == 0 || loop < g_opt.m_loop; loop++) { - DBG("=== loop " << loop << " ==="); + for (g_loop = 0; g_opt.m_loop == 0 || g_loop < g_opt.m_loop; g_loop++) { + DBG("=== loop " << g_loop << " ==="); if (g_opt.m_seed == 0) - srandom(loop); - bool llim = skip('v') ? true : false; - bool ulim = skip('w') ? false : true; + srandom(g_loop); // pk - for (int rw = llim; rw <= ulim; rw++) { - if (skip('k')) + for (style = 0; style <= 2; style++) { + if (skipcase('k') || skipstyle(style)) continue; - DBG("--- pk ops " << (! rw ? "get/set" : "read/write") << " ---"); + DBG("--- pk ops " << stylename[style] << " ---"); calcTups(false); - CHK(insertPk(rw) == 0); + CHK(insertPk(style) == 0); CHK(verifyBlob() == 0); - CHK(readPk(rw) == 0); - if (! skip('u')) { - calcTups(rw); - CHK(updatePk(rw) == 0); + CHK(readPk(style) == 0); + if (! skipcase('u')) { + calcTups(style); + CHK(updatePk(style) == 0); CHK(verifyBlob() == 0); } - CHK(readPk(rw) == 0); + CHK(readPk(style) == 0); CHK(deletePk() == 0); CHK(verifyBlob() == 0); } // hash index - for (int rw = llim; rw <= ulim; rw++) { - if (skip('i')) + for (style = 0; style <= 2; style++) { + if (skipcase('i') || skipstyle(style)) continue; - DBG("--- idx ops " << (! rw ? "get/set" : "read/write") << " ---"); + DBG("--- idx ops " << stylename[style] << " ---"); calcTups(false); - CHK(insertPk(rw) == 0); + CHK(insertPk(style) == 0); CHK(verifyBlob() == 0); - CHK(readIdx(rw) == 0); - calcTups(rw); - if (! skip('u')) { - CHK(updateIdx(rw) == 0); + CHK(readIdx(style) == 0); + calcTups(style); + if (! skipcase('u')) { + CHK(updateIdx(style) == 0); CHK(verifyBlob() == 0); - CHK(readIdx(rw) == 0); + CHK(readIdx(style) == 0); } CHK(deleteIdx() == 0); CHK(verifyBlob() == 0); } // scan table - for (int rw = llim; rw <= ulim; rw++) { - if (skip('s')) + for (style = 0; style <= 2; style++) { + if (skipcase('s') || skipstyle(style)) continue; - DBG("--- table scan " << (! rw ? "get/set" : "read/write") << " ---"); + DBG("--- table scan " << stylename[style] << " ---"); calcTups(false); - CHK(insertPk(rw) == 0); + CHK(insertPk(style) == 0); CHK(verifyBlob() == 0); - CHK(readScan(rw, false) == 0); + CHK(readScan(style, false) == 0); + if (! skipcase('u')) { + CHK(updateScan(style, false) == 0); + CHK(verifyBlob() == 0); + } CHK(deleteScan(false) == 0); CHK(verifyBlob() == 0); } // scan index - for (int rw = llim; rw <= ulim; rw++) { - if (skip('r')) + for (style = 0; style <= 2; style++) { + if (skipcase('r') || skipstyle(style)) continue; - DBG("--- index scan " << (! rw ? "get/set" : "read/write") << " ---"); + DBG("--- index scan " << stylename[style] << " ---"); calcTups(false); - CHK(insertPk(rw) == 0); + CHK(insertPk(style) == 0); CHK(verifyBlob() == 0); - CHK(readScan(rw, true) == 0); + CHK(readScan(style, true) == 0); + if (! skipcase('u')) { + CHK(updateScan(style, true) == 0); + CHK(verifyBlob() == 0); + } CHK(deleteScan(true) == 0); CHK(verifyBlob() == 0); } @@ -1056,6 +1275,7 @@ testmain() static int bugtest_4088() { + unsigned i; DBG("bug test 4088 - ndb api hang with mixed ops on index table"); // insert rows calcTups(false); @@ -1067,7 +1287,7 @@ bugtest_4088() // read table pk via index as a table const unsigned pkcnt = 2; Tup pktup[pkcnt]; - for (unsigned i = 0; i < pkcnt; i++) { + for (i = 0; i < pkcnt; i++) { char name[20]; // XXX guess table id sprintf(name, "%d/%s", 4, g_opt.m_x1name); @@ -1086,7 +1306,7 @@ bugtest_4088() // BUG 4088: gets 1 tckeyconf, 1 tcindxconf, then hangs CHK(g_con->execute(Commit) == 0); // verify - for (unsigned i = 0; i < pkcnt; i++) { + for (i = 0; i < pkcnt; i++) { CHK(pktup[i].m_pk1 == tup.m_pk1); CHK(memcmp(pktup[i].m_pk2, tup.m_pk2, g_opt.m_pk2len) == 0); } @@ -1120,6 +1340,12 @@ NDB_COMMAND(testOdbcDriver, "testBlobs", "testBlobs", "testBlobs", 65535) { while (++argv, --argc > 0) { const char* arg = argv[0]; + if (strcmp(arg, "-batch") == 0) { + if (++argv, --argc > 0) { + g_opt.m_batch = atoi(argv[0]); + continue; + } + } if (strcmp(arg, "-core") == 0) { g_opt.m_core = true; continue; @@ -1131,7 +1357,7 @@ NDB_COMMAND(testOdbcDriver, "testBlobs", "testBlobs", "testBlobs", 65535) if (strcmp(arg, "-dbgall") == 0) { g_opt.m_dbg = true; g_opt.m_dbgall = true; - putenv("NDB_BLOB_DEBUG=1"); + putenv(strdup("NDB_BLOB_DEBUG=1")); continue; } if (strcmp(arg, "-full") == 0) { @@ -1164,9 +1390,13 @@ NDB_COMMAND(testOdbcDriver, "testBlobs", "testBlobs", "testBlobs", 65535) } if (strcmp(arg, "-skip") == 0) { if (++argv, --argc > 0) { - for (const char* p = argv[0]; *p != 0; p++) { - skip(*p) = true; - } + g_opt.m_skip = strdup(argv[0]); + continue; + } + } + if (strcmp(arg, "-style") == 0) { + if (++argv, --argc > 0) { + g_opt.m_style = strdup(argv[0]); continue; } } @@ -1174,10 +1404,6 @@ NDB_COMMAND(testOdbcDriver, "testBlobs", "testBlobs", "testBlobs", 65535) if (strcmp(arg, "-pk2len") == 0) { if (++argv, --argc > 0) { g_opt.m_pk2len = atoi(argv[0]); - if (g_opt.m_pk2len == 0) { - skip('i') = true; - skip('r') = true; - } if (g_opt.m_pk2len <= g_max_pk2len) continue; } @@ -1204,7 +1430,15 @@ NDB_COMMAND(testOdbcDriver, "testBlobs", "testBlobs", "testBlobs", 65535) printusage(); return NDBT_ProgramExit(NDBT_WRONGARGS); } + if (g_opt.m_pk2len == 0) { + char b[100]; + strcpy(b, g_opt.m_skip); + strcat(b, "i"); + strcat(b, "r"); + g_opt.m_skip = strdup(b); + } if (testmain() == -1) { + ndbout << "line " << __LINE__ << " FAIL loop=" << g_loop << endl; return NDBT_ProgramExit(NDBT_FAILED); } return NDBT_ProgramExit(NDBT_OK); diff --git a/ndb/test/ndbapi/testDataBuffers.cpp b/ndb/test/ndbapi/testDataBuffers.cpp index 75773040113..2e29dbb0d7b 100644 --- a/ndb/test/ndbapi/testDataBuffers.cpp +++ b/ndb/test/ndbapi/testDataBuffers.cpp @@ -84,6 +84,8 @@ static NdbSchemaCon* tcon = 0; static NdbSchemaOp* top = 0; static NdbConnection* con = 0; static NdbOperation* op = 0; +static NdbScanOperation* sop = 0; +static NdbResultSet* rs = 0; static int ndberror(char const* fmt, ...) @@ -438,9 +440,9 @@ testcase(int flag) int newkey = 0; if ((con = ndb->startTransaction()) == 0) return ndberror("startTransaction key=%d", key); - if ((op = con->getNdbOperation(tab)) == 0) + if ((op = sop = con->getNdbScanOperation(tab)) == 0) return ndberror("getNdbOperation key=%d", key); - if (op->openScanRead(1) < 0) + if ((rs = sop->readTuples(1)) == 0) return ndberror("openScanRead key=%d", key); { col& c = ccol[0]; @@ -481,10 +483,10 @@ testcase(int flag) } } } - if (con->executeScan() < 0) + if (con->execute(NoCommit) < 0) return ndberror("executeScan key=%d", key); int ret, cnt = 0; - while ((ret = con->nextScanResult()) == 0) { + while ((ret = rs->nextResult()) == 0) { if (key != newkey) return ndberror("unexpected key=%d newkey=%d", key, newkey); for (int i = 1; i < attrcnt; i++) { diff --git a/ndb/test/ndbapi/testDeadlock.cpp b/ndb/test/ndbapi/testDeadlock.cpp new file mode 100644 index 00000000000..f51b3cea1e5 --- /dev/null +++ b/ndb/test/ndbapi/testDeadlock.cpp @@ -0,0 +1,514 @@ +/* Copyright (C) 2003 MySQL AB + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ + +#include <ndb_global.h> +#include <NdbMain.h> +#include <NdbApi.hpp> +#include <NdbOut.hpp> +#include <NdbMutex.h> +#include <NdbCondition.h> +#include <NdbThread.h> +#include <NdbTest.hpp> + +struct Opt { + bool m_dbg; + const char* m_scan; + const char* m_tname; + const char* m_xname; + Opt() : + m_dbg(true), + m_scan("tx"), + m_tname("T"), + m_xname("X") + {} +}; + +static void +printusage() +{ + Opt d; + ndbout + << "usage: testDeadlock" << endl + << "-scan tx scan table, index [" << d.m_scan << "]" << endl + ; +} + +static Opt g_opt; + +static NdbMutex ndbout_mutex = NDB_MUTEX_INITIALIZER; + +#define DBG(x) \ + do { \ + if (! g_opt.m_dbg) break; \ + NdbMutex_Lock(&ndbout_mutex); \ + ndbout << "line " << __LINE__ << " " << x << endl; \ + NdbMutex_Unlock(&ndbout_mutex); \ + } while (0) + +#define CHK(x) \ + do { \ + if (x) break; \ + ndbout << "line " << __LINE__ << ": " << #x << " failed" << endl; \ + return -1; \ + } while (0) + +#define CHN(p, x) \ + do { \ + if (x) break; \ + ndbout << "line " << __LINE__ << ": " << #x << " failed" << endl; \ + ndbout << (p)->getNdbError() << endl; \ + return -1; \ + } while (0) + +// threads + +typedef int (*Runstep)(struct Thr& thr); + +struct Thr { + enum State { Wait, Start, Stop, Stopped, Exit }; + State m_state; + int m_no; + Runstep m_runstep; + int m_ret; + NdbMutex* m_mutex; + NdbCondition* m_cond; + NdbThread* m_thread; + void* m_status; + Ndb* m_ndb; + NdbConnection* m_con; + NdbScanOperation* m_scanop; + NdbIndexScanOperation* m_indexscanop; + NdbResultSet* m_rs; + // + Thr(int no); + ~Thr(); + int run(); + void start(Runstep runstep); + void stop(); + void stopped(); + void lock() { NdbMutex_Lock(m_mutex); } + void unlock() { NdbMutex_Unlock(m_mutex); } + void wait() { NdbCondition_Wait(m_cond, m_mutex); } + void signal() { NdbCondition_Signal(m_cond); } + void exit(); + void join() { NdbThread_WaitFor(m_thread, &m_status); } +}; + +static NdbOut& +operator<<(NdbOut& out, const Thr& thr) { + out << "thr " << thr.m_no; + return out; +} + +extern "C" { static void* runthread(void* arg); } + +Thr::Thr(int no) +{ + m_state = Wait; + m_no = no; + m_runstep = 0; + m_ret = 0; + m_mutex = NdbMutex_Create(); + m_cond = NdbCondition_Create(); + assert(m_mutex != 0 && m_cond != 0); + const unsigned stacksize = 256 * 1024; + const NDB_THREAD_PRIO prio = NDB_THREAD_PRIO_LOW; + m_thread = NdbThread_Create(runthread, (void**)this, stacksize, "me", prio); + if (m_thread == 0) { + DBG("create thread failed: errno=" << errno); + m_ret = -1; + } + m_status = 0; + m_ndb = 0; + m_con = 0; + m_scanop = 0; + m_indexscanop = 0; + m_rs = 0; +} + +Thr::~Thr() +{ + if (m_thread != 0) + NdbThread_Destroy(&m_thread); + if (m_cond != 0) + NdbCondition_Destroy(m_cond); + if (m_mutex != 0) + NdbMutex_Destroy(m_mutex); +} + +static void* +runthread(void* arg) { + Thr& thr = *(Thr*)arg; + thr.run(); + return 0; +} + +int +Thr::run() +{ + DBG(*this << " run"); + while (true) { + lock(); + while (m_state != Start && m_state != Exit) { + wait(); + } + if (m_state == Exit) { + DBG(*this << " exit"); + unlock(); + break; + } + m_ret = (*m_runstep)(*this); + m_state = Stopped; + signal(); + unlock(); + if (m_ret != 0) { + DBG(*this << " error exit"); + break; + } + } + delete m_ndb; + m_ndb = 0; + return 0; +} + +void +Thr::start(Runstep runstep) +{ + lock(); + m_state = Start; + m_runstep = runstep; + signal(); + unlock(); +} + +void +Thr::stopped() +{ + lock(); + while (m_state != Stopped) { + wait(); + } + m_state = Wait; + unlock(); +} + +void +Thr::exit() +{ + lock(); + m_state = Exit; + signal(); + unlock(); +} + +// general + +static int +runstep_connect(Thr& thr) +{ + Ndb* ndb = thr.m_ndb = new Ndb("TEST_DB"); + CHN(ndb, ndb->init() == 0); + CHN(ndb, ndb->waitUntilReady() == 0); + DBG(thr << " connected"); + return 0; +} + +static int +runstep_starttx(Thr& thr) +{ + Ndb* ndb = thr.m_ndb; + assert(ndb != 0); + CHN(ndb, (thr.m_con = ndb->startTransaction()) != 0); + DBG("thr " << thr.m_no << " tx started"); + return 0; +} + +/* + * WL1822 flush locks + * + * Table T with 3 tuples X, Y, Z. + * Two transactions (* = lock wait). + * + * - tx1 reads and locks Z + * - tx2 scans X, Y, *Z + * - tx2 returns X, Y before lock wait on Z + * - tx1 reads and locks *X + * - api asks for next tx2 result + * - LQH unlocks X via ACC or TUX [*] + * - tx1 gets lock on X + * - tx1 returns X to api + * - api commits tx1 + * - tx2 gets lock on Z + * - tx2 returs Z to api + * + * The point is deadlock is avoided due to [*]. + * The test is for 1 db node and 1 fragment table. + */ + +static char wl1822_scantx = 0; + +static const Uint32 wl1822_valA[3] = { 0, 1, 2 }; +static const Uint32 wl1822_valB[3] = { 3, 4, 5 }; + +static Uint32 wl1822_bufA = ~0; +static Uint32 wl1822_bufB = ~0; + +// map scan row to key (A) and reverse +static unsigned wl1822_r2k[3] = { 0, 0, 0 }; +static unsigned wl1822_k2r[3] = { 0, 0, 0 }; + +static int +wl1822_createtable(Thr& thr) +{ + Ndb* ndb = thr.m_ndb; + assert(ndb != 0); + NdbDictionary::Dictionary* dic = ndb->getDictionary(); + // drop T + if (dic->getTable(g_opt.m_tname) != 0) + CHN(dic, dic->dropTable(g_opt.m_tname) == 0); + // create T + NdbDictionary::Table tab(g_opt.m_tname); + tab.setFragmentType(NdbDictionary::Object::FragAllSmall); + { NdbDictionary::Column col("A"); + col.setType(NdbDictionary::Column::Unsigned); + col.setPrimaryKey(true); + tab.addColumn(col); + } + { NdbDictionary::Column col("B"); + col.setType(NdbDictionary::Column::Unsigned); + col.setPrimaryKey(false); + tab.addColumn(col); + } + CHN(dic, dic->createTable(tab) == 0); + // create X + NdbDictionary::Index ind(g_opt.m_xname); + ind.setTable(g_opt.m_tname); + ind.setType(NdbDictionary::Index::OrderedIndex); + ind.setLogging(false); + ind.addColumn("B"); + CHN(dic, dic->createIndex(ind) == 0); + DBG("created " << g_opt.m_tname << ", " << g_opt.m_xname); + return 0; +} + +static int +wl1822_insertrows(Thr& thr) +{ + // insert X, Y, Z + Ndb* ndb = thr.m_ndb; + assert(ndb != 0); + NdbConnection* con; + NdbOperation* op; + for (unsigned k = 0; k < 3; k++) { + CHN(ndb, (con = ndb->startTransaction()) != 0); + CHN(con, (op = con->getNdbOperation(g_opt.m_tname)) != 0); + CHN(op, op->insertTuple() == 0); + CHN(op, op->equal("A", (char*)&wl1822_valA[k]) == 0); + CHN(op, op->setValue("B", (char*)&wl1822_valB[k]) == 0); + CHN(con, con->execute(Commit) == 0); + ndb->closeTransaction(con); + } + DBG("inserted X, Y, Z"); + return 0; +} + +static int +wl1822_getscanorder(Thr& thr) +{ + // cheat, table order happens to be key order in my test + wl1822_r2k[0] = 0; + wl1822_r2k[1] = 1; + wl1822_r2k[2] = 2; + wl1822_k2r[0] = 0; + wl1822_k2r[1] = 1; + wl1822_k2r[2] = 2; + DBG("scan order determined"); + return 0; +} + +static int +wl1822_tx1_readZ(Thr& thr) +{ + // tx1 read Z with exclusive lock + NdbConnection* con = thr.m_con; + assert(con != 0); + NdbOperation* op; + CHN(con, (op = con->getNdbOperation(g_opt.m_tname)) != 0); + CHN(op, op->readTupleExclusive() == 0); + CHN(op, op->equal("A", wl1822_valA[wl1822_r2k[2]]) == 0); + wl1822_bufB = ~0; + CHN(op, op->getValue("B", (char*)&wl1822_bufB) != 0); + CHN(con, con->execute(NoCommit) == 0); + CHK(wl1822_bufB == wl1822_valB[wl1822_r2k[2]]); + DBG("tx1 locked Z"); + return 0; +} + +static int +wl1822_tx2_scanXY(Thr& thr) +{ + // tx2 scan X, Y with exclusive lock + NdbConnection* con = thr.m_con; + assert(con != 0); + NdbScanOperation* scanop; + NdbIndexScanOperation* indexscanop; + NdbResultSet* rs; + if (wl1822_scantx == 't') { + CHN(con, (scanop = thr.m_scanop = con->getNdbScanOperation(g_opt.m_tname)) != 0); + DBG("tx2 scan exclusive " << g_opt.m_tname); + } + if (wl1822_scantx == 'x') { + CHN(con, (scanop = thr.m_scanop = indexscanop = thr.m_indexscanop = con->getNdbIndexScanOperation(g_opt.m_xname, g_opt.m_tname)) != 0); + DBG("tx2 scan exclusive " << g_opt.m_xname); + } + CHN(scanop, (rs = thr.m_rs = scanop->readTuplesExclusive(16)) != 0); + CHN(scanop, scanop->getValue("A", (char*)&wl1822_bufA) != 0); + CHN(scanop, scanop->getValue("B", (char*)&wl1822_bufB) != 0); + CHN(con, con->execute(NoCommit) == 0); + unsigned row = 0; + while (row < 2) { + DBG("before row " << row); + int ret; + wl1822_bufA = wl1822_bufB = ~0; + CHN(con, (ret = rs->nextResult(true)) == 0); + DBG("got row " << row << " a=" << wl1822_bufA << " b=" << wl1822_bufB); + CHK(wl1822_bufA == wl1822_valA[wl1822_r2k[row]]); + CHK(wl1822_bufB == wl1822_valB[wl1822_r2k[row]]); + row++; + } + return 0; +} + +static int +wl1822_tx1_readX_commit(Thr& thr) +{ + // tx1 read X with exclusive lock and commit + NdbConnection* con = thr.m_con; + assert(con != 0); + NdbOperation* op; + CHN(con, (op = con->getNdbOperation(g_opt.m_tname)) != 0); + CHN(op, op->readTupleExclusive() == 0); + CHN(op, op->equal("A", wl1822_valA[wl1822_r2k[2]]) == 0); + wl1822_bufB = ~0; + CHN(op, op->getValue("B", (char*)&wl1822_bufB) != 0); + CHN(con, con->execute(NoCommit) == 0); + CHK(wl1822_bufB == wl1822_valB[wl1822_r2k[2]]); + DBG("tx1 locked X"); + CHN(con, con->execute(Commit) == 0); + DBG("tx1 commit"); + return 0; +} + +static int +wl1822_tx2_scanZ_close(Thr& thr) +{ + // tx2 scan Z with exclusive lock and close scan + Ndb* ndb = thr.m_ndb; + NdbConnection* con = thr.m_con; + NdbScanOperation* scanop = thr.m_scanop; + NdbResultSet* rs = thr.m_rs; + assert(ndb != 0 && con != 0 && scanop != 0 && rs != 0); + unsigned row = 2; + while (true) { + DBG("before row " << row); + int ret; + wl1822_bufA = wl1822_bufB = ~0; + CHN(con, (ret = rs->nextResult(true)) == 0 || ret == 1); + if (ret == 1) + break; + DBG("got row " << row << " a=" << wl1822_bufA << " b=" << wl1822_bufB); + CHK(wl1822_bufA == wl1822_valA[wl1822_r2k[row]]); + CHK(wl1822_bufB == wl1822_valB[wl1822_r2k[row]]); + row++; + } + ndb->closeTransaction(con); + CHK(row == 3); + return 0; +} + +// threads are synced between each step +static Runstep wl1822_step[][2] = { + { runstep_connect, runstep_connect }, + { wl1822_createtable, 0 }, + { wl1822_insertrows, 0 }, + { wl1822_getscanorder, 0 }, + { runstep_starttx, runstep_starttx }, + { wl1822_tx1_readZ, 0 }, + { 0, wl1822_tx2_scanXY }, + { wl1822_tx1_readX_commit, wl1822_tx2_scanZ_close } +}; +const unsigned wl1822_stepcount = sizeof(wl1822_step)/sizeof(wl1822_step[0]); + +static int +wl1822_main(char scantx) +{ + wl1822_scantx = scantx; + static const unsigned thrcount = 2; + // create threads for tx1 and tx2 + Thr* thrlist[2]; + for (int n = 0; n < thrcount; n++) { + Thr& thr = *(thrlist[n] = new Thr(1 + n)); + CHK(thr.m_ret == 0); + } + // run the steps + for (unsigned i = 0; i < wl1822_stepcount; i++) { + DBG("step " << i << " start"); + for (int n = 0; n < thrcount; n++) { + Thr& thr = *thrlist[n]; + Runstep runstep = wl1822_step[i][n]; + if (runstep != 0) + thr.start(runstep); + } + for (int n = 0; n < thrcount; n++) { + Thr& thr = *thrlist[n]; + Runstep runstep = wl1822_step[i][n]; + if (runstep != 0) + thr.stopped(); + } + } + // delete threads + for (int n = 0; n < thrcount; n++) { + Thr& thr = *thrlist[n]; + thr.exit(); + thr.join(); + delete &thr; + } + return 0; +} + +NDB_COMMAND(testOdbcDriver, "testDeadlock", "testDeadlock", "testDeadlock", 65535) +{ + while (++argv, --argc > 0) { + const char* arg = argv[0]; + if (strcmp(arg, "-scan") == 0) { + if (++argv, --argc > 0) { + g_opt.m_scan = strdup(argv[0]); + continue; + } + } + printusage(); + return NDBT_ProgramExit(NDBT_WRONGARGS); + } + if ( + strchr(g_opt.m_scan, 't') != 0 && wl1822_main('t') == -1 || + strchr(g_opt.m_scan, 'x') != 0 && wl1822_main('x') == -1 + ) { + return NDBT_ProgramExit(NDBT_FAILED); + } + return NDBT_ProgramExit(NDBT_OK); +} + +// vim: set sw=2 et: diff --git a/ndb/test/ndbapi/testDict.cpp b/ndb/test/ndbapi/testDict.cpp index 1451c942362..e7597c26960 100644 --- a/ndb/test/ndbapi/testDict.cpp +++ b/ndb/test/ndbapi/testDict.cpp @@ -537,6 +537,7 @@ int runTestFragmentTypes(NDBT_Context* ctx, NDBT_Step* step){ } const NdbDictionary::Table* pTab = ctx->getTab(); + pNdb->getDictionary()->dropTable(pTab->getName()); NdbDictionary::Table newTab(* pTab); // Set fragment type for table diff --git a/ndb/test/ndbapi/testGrep.cpp b/ndb/test/ndbapi/testGrep.cpp index 4b870f6f9a9..0bf84cb4ec8 100644 --- a/ndb/test/ndbapi/testGrep.cpp +++ b/ndb/test/ndbapi/testGrep.cpp @@ -254,8 +254,7 @@ int runClearTable(NDBT_Context* ctx, NDBT_Step* step){ return NDBT_OK; } - -#include "../bank/Bank.hpp" +#include "bank/Bank.hpp" int runCreateBank(NDBT_Context* ctx, NDBT_Step* step){ Bank bank; @@ -444,6 +443,7 @@ int runRestoreBankAndVerify(NDBT_Context* ctx, NDBT_Step* step){ return result; } */ + NDBT_TESTSUITE(testGrep); TESTCASE("GrepBasic", "Test that Global Replication works on one table \n" @@ -473,8 +473,6 @@ TESTCASE("GrepNodeRestart", } - - TESTCASE("GrepBank", "Test that grep and restore works during transaction load\n" " by backing up the bank" @@ -495,6 +493,7 @@ TESTCASE("GrepBank", // FINALIZER(runDropBank); } + TESTCASE("NFMaster", "Test that grep behaves during node failiure\n"){ INITIALIZER(setMaster); diff --git a/ndb/test/ndbapi/testIndex.cpp b/ndb/test/ndbapi/testIndex.cpp index 47db0b3cff7..6ebbfd8b680 100644 --- a/ndb/test/ndbapi/testIndex.cpp +++ b/ndb/test/ndbapi/testIndex.cpp @@ -26,7 +26,7 @@ #define CHECK(b) if (!(b)) { \ g_err << "ERR: "<< step->getName() \ << " failed on line " << __LINE__ << endl; \ - result = NDBT_FAILED; \ + result = NDBT_FAILED; break;\ } @@ -381,6 +381,27 @@ runVerifyIndex(NDBT_Context* ctx, NDBT_Step* step){ } int +sync_down(NDBT_Context* ctx){ + Uint32 threads = ctx->getProperty("PauseThreads", (unsigned)0); + if(threads){ + ctx->decProperty("PauseThreads"); + } + return 0; +} + +int +sync_up_and_wait(NDBT_Context* ctx){ + Uint32 threads = ctx->getProperty("Threads", (unsigned)0); + ndbout_c("Setting PauseThreads to %d", threads); + ctx->setProperty("PauseThreads", threads); + ctx->getPropertyWait("PauseThreads", (unsigned)0); + if(threads){ + ndbout_c("wait completed"); + } + return 0; +} + +int runTransactions1(NDBT_Context* ctx, NDBT_Step* step){ // Verify that data in index match // table data @@ -394,10 +415,17 @@ runTransactions1(NDBT_Context* ctx, NDBT_Step* step){ g_err << "Updated table failed" << endl; return NDBT_FAILED; } + + sync_down(ctx); + if(ctx->isTestStopped()) + break; + if (hugoTrans.scanUpdateRecords(pNdb, rows, batchSize) != 0){ g_err << "Updated table failed" << endl; return NDBT_FAILED; } + + sync_down(ctx); } return NDBT_OK; } @@ -418,7 +446,7 @@ runTransactions2(NDBT_Context* ctx, NDBT_Step* step){ return NDBT_FAILED; } #endif - + sync_down(ctx); if(ctx->isTestStopped()) break; #if 1 @@ -427,6 +455,7 @@ runTransactions2(NDBT_Context* ctx, NDBT_Step* step){ return NDBT_FAILED; } #endif + sync_down(ctx); } return NDBT_OK; } @@ -447,6 +476,7 @@ runTransactions3(NDBT_Context* ctx, NDBT_Step* step){ g_err << "Load table failed" << endl; return NDBT_FAILED; } + sync_down(ctx); if(ctx->isTestStopped()) break; @@ -454,7 +484,8 @@ runTransactions3(NDBT_Context* ctx, NDBT_Step* step){ g_err << "Updated table failed" << endl; return NDBT_FAILED; } - + + sync_down(ctx); if(ctx->isTestStopped()) break; @@ -463,6 +494,7 @@ runTransactions3(NDBT_Context* ctx, NDBT_Step* step){ return NDBT_FAILED; } + sync_down(ctx); if(ctx->isTestStopped()) break; @@ -471,6 +503,7 @@ runTransactions3(NDBT_Context* ctx, NDBT_Step* step){ return NDBT_FAILED; } + sync_down(ctx); if(ctx->isTestStopped()) break; @@ -479,6 +512,7 @@ runTransactions3(NDBT_Context* ctx, NDBT_Step* step){ return NDBT_FAILED; } + sync_down(ctx); if(ctx->isTestStopped()) break; @@ -486,12 +520,15 @@ runTransactions3(NDBT_Context* ctx, NDBT_Step* step){ g_err << "Clear table failed" << endl; return NDBT_FAILED; } + + sync_down(ctx); if(ctx->isTestStopped()) break; - + int count = -1; if(utilTrans.selectCount(pNdb, 64, &count) != 0 || count != 0) return NDBT_FAILED; + sync_down(ctx); } return NDBT_OK; } @@ -510,6 +547,7 @@ int runRestarts(NDBT_Context* ctx, NDBT_Step* step){ result = NDBT_FAILED; break; } + sync_up_and_wait(ctx); i++; } ctx->stopTest(); @@ -1130,7 +1168,7 @@ runUniqueNullTransactions(NDBT_Context* ctx, NDBT_Step* step){ if(!pTrans) goto done; sOp = pTrans->getNdbScanOperation(pTab->getName()); if(!sOp) goto done; - rs = sOp->readTuples(240, NdbScanOperation::LM_Exclusive); + rs = sOp->readTuples(NdbScanOperation::LM_Exclusive); if(!rs) goto done; if(pTrans->execute(NoCommit) == -1) goto done; while((eof = rs->nextResult(true)) == 0){ @@ -1259,6 +1297,7 @@ TESTCASE("CreateLoadDrop_O", TESTCASE("NFNR1", "Test that indexes are correctly maintained during node fail and node restart"){ TC_PROPERTY("LoggedIndexes", (unsigned)0); + //TC_PROPERTY("Threads", 2); INITIALIZER(runClearTable); INITIALIZER(createRandomIndex); INITIALIZER(runLoadTable); @@ -1492,4 +1531,4 @@ int main(int argc, const char** argv){ return testIndex.execute(argc, argv); } - +template class Vector<Attrib*>; diff --git a/ndb/test/ndbapi/testNdbApi.cpp b/ndb/test/ndbapi/testNdbApi.cpp index 2e08ebbed4e..5b171d42578 100644 --- a/ndb/test/ndbapi/testNdbApi.cpp +++ b/ndb/test/ndbapi/testNdbApi.cpp @@ -1010,4 +1010,5 @@ int main(int argc, const char** argv){ return testNdbApi.execute(argc, argv); } - +template class Vector<Ndb*>; +template class Vector<NdbConnection*>; diff --git a/ndb/test/ndbapi/testNodeRestart.cpp b/ndb/test/ndbapi/testNodeRestart.cpp index fd591f04c69..89b38c78e71 100644 --- a/ndb/test/ndbapi/testNodeRestart.cpp +++ b/ndb/test/ndbapi/testNodeRestart.cpp @@ -287,8 +287,6 @@ TESTCASE("Terror", STEP(runPkUpdateUntilStopped); STEP(runScanReadUntilStopped); STEP(runScanUpdateUntilStopped); - STEP(runInsertUntilStopped); - STEP(runClearTableUntilStopped); FINALIZER(runClearTable); } TESTCASE("FullDb", diff --git a/ndb/test/ndbapi/testOIBasic.cpp b/ndb/test/ndbapi/testOIBasic.cpp index 0ca8ce79e2e..c58dd8538e9 100644 --- a/ndb/test/ndbapi/testOIBasic.cpp +++ b/ndb/test/ndbapi/testOIBasic.cpp @@ -33,14 +33,18 @@ struct Opt { // common options + unsigned m_batch; const char* m_case; bool m_core; bool m_dups; NdbDictionary::Object::FragmentType m_fragtype; + unsigned m_idxloop; const char* m_index; unsigned m_loop; bool m_nologging; + bool m_msglock; unsigned m_rows; + unsigned m_samples; unsigned m_scanrd; unsigned m_scanex; unsigned m_seed; @@ -49,17 +53,21 @@ struct Opt { unsigned m_threads; unsigned m_v; Opt() : + m_batch(32), m_case(0), m_core(false), m_dups(false), m_fragtype(NdbDictionary::Object::FragUndefined), + m_idxloop(4), m_index(0), m_loop(1), m_nologging(false), + m_msglock(true), m_rows(1000), + m_samples(0), m_scanrd(240), m_scanex(240), - m_seed(1), + m_seed(0), m_subloop(4), m_table(0), m_threads(4), @@ -78,17 +86,19 @@ printhelp() Opt d; ndbout << "usage: testOIbasic [options]" << endl + << " -batch N pk operations in batch [" << d.m_batch << "]" << endl << " -case abc only given test cases (letters a-z)" << endl << " -core core dump on error [" << d.m_core << "]" << endl << " -dups allow duplicate tuples from index scan [" << d.m_dups << "]" << endl << " -fragtype T fragment type single/small/medium/large" << endl << " -index xyz only given index numbers (digits 1-9)" << endl - << " -loop N loop count full suite forever=0 [" << d.m_loop << "]" << endl + << " -loop N loop count full suite 0=forever [" << d.m_loop << "]" << endl << " -nologging create tables in no-logging mode" << endl << " -rows N rows per thread [" << d.m_rows << "]" << endl + << " -samples N samples for some timings (0=all) [" << d.m_samples << "]" << endl << " -scanrd N scan read parallelism [" << d.m_scanrd << "]" << endl << " -scanex N scan exclusive parallelism [" << d.m_scanex << "]" << endl - << " -seed N srandom seed [" << d.m_seed << "]" << endl + << " -seed N srandom seed 0=loop number[" << d.m_seed << "]" << endl << " -subloop N subtest loop count [" << d.m_subloop << "]" << endl << " -table xyz only given table numbers (digits 1-9)" << endl << " -threads N number of threads [" << d.m_threads << "]" << endl @@ -99,6 +109,12 @@ printhelp() printtables(); } +// not yet configurable +static const bool g_store_null_key = true; + +// compare NULL like normal value (NULL < not NULL, NULL == NULL) +static const bool g_compare_null = true; + // log and error macros static NdbMutex ndbout_mutex = NDB_MUTEX_INITIALIZER; @@ -124,9 +140,9 @@ getthrstr() #define LLN(n, s) \ do { \ if ((n) > g_opt.m_v) break; \ - NdbMutex_Lock(&ndbout_mutex); \ + if (g_opt.m_msglock) NdbMutex_Lock(&ndbout_mutex); \ ndbout << getthrstr() << s << endl; \ - NdbMutex_Unlock(&ndbout_mutex); \ + if (g_opt.m_msglock) NdbMutex_Unlock(&ndbout_mutex); \ } while(0) #define LL0(s) LLN(0, s) @@ -139,11 +155,10 @@ getthrstr() // following check a condition and return -1 on failure #undef CHK // simple check -#undef CHKTRY // execute action (try-catch) on failure -#undef CHKMSG // print extra message on failure +#undef CHKTRY // check with action on fail #undef CHKCON // print NDB API errors on failure -#define CHK(x) CHKTRY(x, ;) +#define CHK(x) CHKTRY(x, ;) #define CHKTRY(x, act) \ do { \ @@ -154,14 +169,6 @@ getthrstr() return -1; \ } while (0) -#define CHKMSG(x, msg) \ - do { \ - if (x) break; \ - LL0("line " << __LINE__ << ": " << #x << " failed: " << msg); \ - if (g_opt.m_core) abort(); \ - return -1; \ - } while (0) - #define CHKCON(x, con) \ do { \ if (x) break; \ @@ -177,6 +184,7 @@ class Thr; class Con; class Tab; class Set; +class Tmr; struct Par : public Opt { unsigned m_no; @@ -186,14 +194,17 @@ struct Par : public Opt { const Tab& tab() const { assert(m_tab != 0); return *m_tab; } Set* m_set; Set& set() const { assert(m_set != 0); return *m_set; } + Tmr* m_tmr; + Tmr& tmr() const { assert(m_tmr != 0); return *m_tmr; } unsigned m_totrows; - unsigned m_batch; // value calculation unsigned m_pctnull; unsigned m_range; unsigned m_pctrange; // do verify after read bool m_verify; + // deadlock possible + bool m_deadlock; // timer location Par(const Opt& opt) : Opt(opt), @@ -201,12 +212,13 @@ struct Par : public Opt { m_con(0), m_tab(0), m_set(0), + m_tmr(0), m_totrows(m_threads * m_rows), - m_batch(32), m_pctnull(10), m_range(m_rows), m_pctrange(0), - m_verify(false) { + m_verify(false), + m_deadlock(false) { } }; @@ -241,19 +253,20 @@ struct Tmr { void on(); void off(unsigned cnt = 0); const char* time(); + const char* pct(const Tmr& t1); const char* over(const Tmr& t1); NDB_TICKS m_on; unsigned m_ms; unsigned m_cnt; char m_time[100]; - char m_over[100]; + char m_text[100]; Tmr() { clr(); } }; void Tmr::clr() { - m_on = m_ms = m_cnt = m_time[0] = m_over[0] = 0; + m_on = m_ms = m_cnt = m_time[0] = m_text[0] = 0; } void @@ -285,14 +298,63 @@ Tmr::time() } const char* +Tmr::pct(const Tmr& t1) +{ + if (0 < t1.m_ms) { + sprintf(m_text, "%u pct", (100 * m_ms) / t1.m_ms); + } else { + sprintf(m_text, "[cannot measure]"); + } + return m_text; +} + +const char* Tmr::over(const Tmr& t1) { - if (0 < t1.m_ms && t1.m_ms < m_ms) { - sprintf(m_over, "%u pct", (100 * (m_ms - t1.m_ms)) / t1.m_ms); + if (0 < t1.m_ms) { + if (t1.m_ms <= m_ms) + sprintf(m_text, "%u pct", (100 * (m_ms - t1.m_ms)) / t1.m_ms); + else + sprintf(m_text, "-%u pct", (100 * (t1.m_ms - m_ms)) / t1.m_ms); } else { - sprintf(m_over, "[cannot measure]"); + sprintf(m_text, "[cannot measure]"); } - return m_over; + return m_text; +} + +// list of ints + +struct Lst { + Lst(); + unsigned m_arr[1000]; + unsigned m_cnt; + void push(unsigned i); + unsigned cnt() const; + void reset(); +}; + +Lst::Lst() : + m_cnt(0) +{ +} + +void +Lst::push(unsigned i) +{ + assert(m_cnt < sizeof(m_arr)/sizeof(m_arr[0])); + m_arr[m_cnt++] = i; +} + +unsigned +Lst::cnt() const +{ + return m_cnt; +} + +void +Lst::reset() +{ + m_cnt = 0; } // tables and indexes @@ -409,7 +471,7 @@ operator<<(NdbOut& out, const Tab& tab) return out; } -// tt1 + tt1x1 tt1x2 tt1x3 tt1x4 +// tt1 + tt1x1 tt1x2 tt1x3 tt1x4 tt1x5 static const Col tt1col[] = { @@ -422,24 +484,29 @@ tt1col[] = { static const ICol tt1x1col[] = { - { 0, tt1col[1] } + { 0, tt1col[0] } }; static const ICol tt1x2col[] = { + { 0, tt1col[1] } +}; + +static const ICol +tt1x3col[] = { { 0, tt1col[1] }, { 1, tt1col[2] } }; static const ICol -tt1x3col[] = { +tt1x4col[] = { { 0, tt1col[3] }, { 1, tt1col[2] }, { 2, tt1col[1] } }; static const ICol -tt1x4col[] = { +tt1x5col[] = { { 0, tt1col[1] }, { 1, tt1col[4] }, { 2, tt1col[2] }, @@ -453,17 +520,22 @@ tt1x1 = { static const ITab tt1x2 = { - "TT1X2", 2, tt1x2col + "TT1X2", 1, tt1x2col }; static const ITab tt1x3 = { - "TT1X3", 3, tt1x3col + "TT1X3", 2, tt1x3col }; static const ITab tt1x4 = { - "TT1X4", 4, tt1x4col + "TT1X4", 3, tt1x4col +}; + +static const ITab +tt1x5 = { + "TT1X5", 4, tt1x5col }; static const ITab @@ -471,15 +543,16 @@ tt1itab[] = { tt1x1, tt1x2, tt1x3, - tt1x4 + tt1x4, + tt1x5 }; static const Tab tt1 = { - "TT1", 5, tt1col, 4, tt1itab + "TT1", 5, tt1col, 5, tt1itab }; -// tt2 + tt2x1 tt2x2 tt2x3 tt2x4 +// tt2 + tt2x1 tt2x2 tt2x3 tt2x4 tt2x5 static const Col tt2col[] = { @@ -492,24 +565,29 @@ tt2col[] = { static const ICol tt2x1col[] = { + { 0, tt2col[0] } +}; + +static const ICol +tt2x2col[] = { { 0, tt2col[1] }, { 1, tt2col[2] } }; static const ICol -tt2x2col[] = { +tt2x3col[] = { { 0, tt2col[2] }, { 1, tt2col[1] } }; static const ICol -tt2x3col[] = { +tt2x4col[] = { { 0, tt2col[3] }, { 1, tt2col[4] } }; static const ICol -tt2x4col[] = { +tt2x5col[] = { { 0, tt2col[4] }, { 1, tt2col[3] }, { 2, tt2col[2] }, @@ -518,7 +596,7 @@ tt2x4col[] = { static const ITab tt2x1 = { - "TT2X1", 2, tt2x1col + "TT2X1", 1, tt2x1col }; static const ITab @@ -533,7 +611,12 @@ tt2x3 = { static const ITab tt2x4 = { - "TT2X4", 4, tt2x4col + "TT2X4", 2, tt2x4col +}; + +static const ITab +tt2x5 = { + "TT2X5", 4, tt2x5col }; static const ITab @@ -541,12 +624,13 @@ tt2itab[] = { tt2x1, tt2x2, tt2x3, - tt2x4 + tt2x4, + tt2x5 }; static const Tab tt2 = { - "TT2", 5, tt2col, 4, tt2itab + "TT2", 5, tt2col, 5, tt2itab }; // all tables @@ -567,40 +651,42 @@ struct Con { NdbDictionary::Dictionary* m_dic; NdbConnection* m_tx; NdbOperation* m_op; - NdbConnection* m_scantx; - NdbOperation* m_scanop; + NdbScanOperation* m_scanop; + NdbIndexScanOperation* m_indexscanop; + NdbResultSet* m_resultset; enum ScanMode { ScanNo = 0, Committed, Latest, Exclusive }; ScanMode m_scanmode; enum ErrType { ErrNone = 0, ErrDeadlock, ErrOther }; ErrType m_errtype; Con() : m_ndb(0), m_dic(0), m_tx(0), m_op(0), - m_scantx(0), m_scanop(0), m_scanmode(ScanNo), m_errtype(ErrNone) {} + m_scanop(0), m_indexscanop(0), m_resultset(0), m_scanmode(ScanNo), m_errtype(ErrNone) {} + ~Con() { + if (m_tx != 0) + closeTransaction(); + } int connect(); + void connect(const Con& con); void disconnect(); int startTransaction(); - int startBuddyTransaction(const Con& con); int getNdbOperation(const Tab& tab); - int getNdbOperation(const ITab& itab, const Tab& tab); + int getNdbScanOperation(const Tab& tab); + int getNdbScanOperation(const ITab& itab, const Tab& tab); int equal(int num, const char* addr); int getValue(int num, NdbRecAttr*& rec); int setValue(int num, const char* addr); int setBound(int num, int type, const void* value); int execute(ExecType t); + int execute(ExecType t, bool& deadlock); int openScanRead(unsigned parallelism); int openScanExclusive(unsigned parallelism); int executeScan(); - int nextScanResult(); - int takeOverForUpdate(Con& scan); - int takeOverForDelete(Con& scan); + int nextScanResult(bool fetchAllowed); + int nextScanResult(bool fetchAllowed, bool& deadlock); + int updateScanTuple(Con& con2); + int deleteScanTuple(Con& con2); void closeTransaction(); void printerror(NdbOut& out); - // flush dict cache - int bugger() { - //disconnect(); - //CHK(connect() == 0); - return 0; - } }; int @@ -610,12 +696,18 @@ Con::connect() m_ndb = new Ndb("TEST_DB"); CHKCON(m_ndb->init() == 0, *this); CHKCON(m_ndb->waitUntilReady(30) == 0, *this); - m_dic = m_ndb->getDictionary(); m_tx = 0, m_op = 0; return 0; } void +Con::connect(const Con& con) +{ + assert(m_ndb == 0); + m_ndb = con.m_ndb; +} + +void Con::disconnect() { delete m_ndb; @@ -625,31 +717,34 @@ Con::disconnect() int Con::startTransaction() { - assert(m_ndb != 0 && m_tx == 0); + assert(m_ndb != 0); + if (m_tx != 0) + closeTransaction(); CHKCON((m_tx = m_ndb->startTransaction()) != 0, *this); return 0; } int -Con::startBuddyTransaction(const Con& con) +Con::getNdbOperation(const Tab& tab) { - assert(m_ndb != 0 && m_tx == 0 && con.m_ndb == m_ndb && con.m_tx != 0); - CHKCON((m_tx = m_ndb->hupp(con.m_tx)) != 0, *this); + assert(m_tx != 0); + CHKCON((m_op = m_tx->getNdbOperation(tab.m_name)) != 0, *this); return 0; } int -Con::getNdbOperation(const Tab& tab) +Con::getNdbScanOperation(const Tab& tab) { assert(m_tx != 0); - CHKCON((m_op = m_tx->getNdbOperation(tab.m_name)) != 0, *this); + CHKCON((m_op = m_scanop = m_tx->getNdbScanOperation(tab.m_name)) != 0, *this); return 0; } int -Con::getNdbOperation(const ITab& itab, const Tab& tab) +Con::getNdbScanOperation(const ITab& itab, const Tab& tab) { - CHKCON((m_op = m_tx->getNdbOperation(itab.m_name, tab.m_name)) != 0, *this); + assert(m_tx != 0); + CHKCON((m_op = m_scanop = m_indexscanop = m_tx->getNdbIndexScanOperation(itab.m_name, tab.m_name)) != 0, *this); return 0; } @@ -681,7 +776,7 @@ int Con::setBound(int num, int type, const void* value) { assert(m_tx != 0 && m_op != 0); - CHKCON(m_op->setBound(num, type, value) == 0, *this); + CHKCON(m_indexscanop->setBound(num, type, value) == 0, *this); return 0; } @@ -694,10 +789,26 @@ Con::execute(ExecType t) } int +Con::execute(ExecType t, bool& deadlock) +{ + int ret = execute(t); + if (ret != 0) { + if (deadlock && m_errtype == ErrDeadlock) { + LL3("caught deadlock"); + ret = 0; + } + } else { + deadlock = false; + } + CHK(ret == 0); + return 0; +} + +int Con::openScanRead(unsigned parallelism) { assert(m_tx != 0 && m_op != 0); - CHKCON(m_op->openScanRead(parallelism) == 0, *this); + CHKCON((m_resultset = m_scanop->readTuples(parallelism)) != 0, *this); return 0; } @@ -705,39 +816,56 @@ int Con::openScanExclusive(unsigned parallelism) { assert(m_tx != 0 && m_op != 0); - CHKCON(m_op->openScanExclusive(parallelism) == 0, *this); + CHKCON((m_resultset = m_scanop->readTuplesExclusive(parallelism)) != 0, *this); return 0; } int Con::executeScan() { - CHKCON(m_tx->executeScan() == 0, *this); + CHKCON(m_tx->execute(NoCommit) == 0, *this); return 0; } int -Con::nextScanResult() +Con::nextScanResult(bool fetchAllowed) { int ret; - CHKCON((ret = m_tx->nextScanResult()) != -1, *this); - assert(ret == 0 || ret == 1); + assert(m_resultset != 0); + CHKCON((ret = m_resultset->nextResult(fetchAllowed)) != -1, *this); + assert(ret == 0 || ret == 1 || (! fetchAllowed && ret == 2)); + return ret; +} + +int +Con::nextScanResult(bool fetchAllowed, bool& deadlock) +{ + int ret = nextScanResult(fetchAllowed); + if (ret == -1) { + if (deadlock && m_errtype == ErrDeadlock) { + LL3("caught deadlock"); + ret = 0; + } + } else { + deadlock = false; + } + CHK(ret == 0 || ret == 1 || (! fetchAllowed && ret == 2)); return ret; } int -Con::takeOverForUpdate(Con& scan) +Con::updateScanTuple(Con& con2) { - assert(m_tx != 0 && scan.m_op != 0); - CHKCON((m_op = scan.m_op->takeOverForUpdate(m_tx)) != 0, scan); + assert(con2.m_tx != 0); + CHKCON((con2.m_op = m_resultset->updateTuple(con2.m_tx)) != 0, *this); return 0; } int -Con::takeOverForDelete(Con& scan) +Con::deleteScanTuple(Con& con2) { - assert(m_tx != 0 && scan.m_op != 0); - CHKCON((m_op = scan.m_op->takeOverForUpdate(m_tx)) != 0, scan); + assert(con2.m_tx != 0); + CHKCON(m_resultset->deleteTuple(con2.m_tx) == 0, *this); return 0; } @@ -765,7 +893,7 @@ Con::printerror(NdbOut& out) if (m_tx) { if ((code = m_tx->getNdbError().code) != 0) { LL0(++any << " con: error " << m_tx->getNdbError()); - if (code == 266 || code == 274 || code == 296 || code == 297) + if (code == 266 || code == 274 || code == 296 || code == 297 || code == 499) m_errtype = ErrDeadlock; } if (m_op && m_op->getNdbError().code != 0) { @@ -785,7 +913,7 @@ invalidateindex(Par par, const ITab& itab) { Con& con = par.con(); const Tab& tab = par.tab(); - con.m_dic->invalidateIndex(itab.m_name, tab.m_name); + con.m_ndb->getDictionary()->invalidateIndex(itab.m_name, tab.m_name); return 0; } @@ -809,7 +937,7 @@ invalidatetable(Par par) Con& con = par.con(); const Tab& tab = par.tab(); invalidateindex(par); - con.m_dic->invalidateTable(tab.m_name); + con.m_ndb->getDictionary()->invalidateTable(tab.m_name); return 0; } @@ -818,6 +946,7 @@ droptable(Par par) { Con& con = par.con(); const Tab& tab = par.tab(); + con.m_dic = con.m_ndb->getDictionary(); if (con.m_dic->getTable(tab.m_name) == 0) { // how to check for error LL4("no table " << tab.m_name); @@ -825,6 +954,7 @@ droptable(Par par) LL3("drop table " << tab.m_name); CHKCON(con.m_dic->dropTable(tab.m_name) == 0, con); } + con.m_dic = 0; return 0; } @@ -832,7 +962,6 @@ static int createtable(Par par) { Con& con = par.con(); - CHK(con.bugger() == 0); const Tab& tab = par.tab(); LL3("create table " << tab.m_name); LL4(tab); @@ -852,7 +981,9 @@ createtable(Par par) c.setNullable(col.m_nullable); t.addColumn(c); } + con.m_dic = con.m_ndb->getDictionary(); CHKCON(con.m_dic->createTable(t) == 0, con); + con.m_dic = 0; return 0; } @@ -861,6 +992,7 @@ dropindex(Par par, const ITab& itab) { Con& con = par.con(); const Tab& tab = par.tab(); + con.m_dic = con.m_ndb->getDictionary(); if (con.m_dic->getIndex(itab.m_name, tab.m_name) == 0) { // how to check for error LL4("no index " << itab.m_name); @@ -868,6 +1000,7 @@ dropindex(Par par, const ITab& itab) LL3("drop index " << itab.m_name); CHKCON(con.m_dic->dropIndex(itab.m_name, tab.m_name) == 0, con); } + con.m_dic = 0; return 0; } @@ -888,7 +1021,6 @@ static int createindex(Par par, const ITab& itab) { Con& con = par.con(); - CHK(con.bugger() == 0); const Tab& tab = par.tab(); LL3("create index " << itab.m_name); LL4(itab); @@ -900,7 +1032,9 @@ createindex(Par par, const ITab& itab) const Col& col = itab.m_icol[k].m_col; x.addColumnName(col.m_name); } + con.m_dic = con.m_ndb->getDictionary(); CHKCON(con.m_dic->createIndex(x) == 0, con); + con.m_dic = 0; return 0; } @@ -1115,9 +1249,9 @@ Val::cmp(const Val& val2) const assert(col.m_type == col2.m_type && col.m_length == col2.m_length); if (m_null || val2.m_null) { if (! m_null) - return -1; - if (! val2.m_null) return +1; + if (! val2.m_null) + return -1; return 0; } // verify data formats @@ -1175,6 +1309,8 @@ struct Row { const Tab& m_tab; Val** m_val; bool m_exist; + enum Op { NoOp = 0, ReadOp, InsOp, UpdOp, DelOp }; + Op m_pending; Row(const Tab& tab); ~Row(); void copy(const Row& row2); @@ -1199,6 +1335,7 @@ Row::Row(const Tab& tab) : m_val[k] = new Val(col); } m_exist = false; + m_pending = NoOp; } Row::~Row() @@ -1236,7 +1373,7 @@ int Row::verify(const Row& row2) const { const Tab& tab = m_tab; - assert(&tab == &row2.m_tab); + assert(&tab == &row2.m_tab && m_exist && row2.m_exist); for (unsigned k = 0; k < tab.m_cols; k++) { const Val& val = *m_val[k]; const Val& val2 = *row2.m_val[k]; @@ -1257,7 +1394,7 @@ Row::insrow(Par par) const Val& val = *m_val[k]; CHK(val.setval(par) == 0); } - m_exist = true; + m_pending = InsOp; return 0; } @@ -1273,6 +1410,7 @@ Row::updrow(Par par) const Val& val = *m_val[k]; CHK(val.setval(par) == 0); } + m_pending = UpdOp; return 0; } @@ -1290,7 +1428,7 @@ Row::delrow(Par par) if (col.m_pk) CHK(val.setval(par) == 0); } - m_exist = false; + m_pending = DelOp; return 0; } @@ -1307,7 +1445,6 @@ Row::selrow(Par par) if (col.m_pk) CHK(val.setval(par) == 0); } - m_exist = false; return 0; } @@ -1322,6 +1459,7 @@ Row::setrow(Par par) if (! col.m_pk) CHK(val.setval(par) == 0); } + m_pending = UpdOp; return 0; } @@ -1349,6 +1487,10 @@ operator<<(NdbOut& out, const Row& row) out << " "; out << *row.m_val[i]; } + out << " [exist=" << row.m_exist; + if (row.m_pending) + out << " pending=" << row.m_pending; + out << "]"; return out; } @@ -1357,15 +1499,19 @@ operator<<(NdbOut& out, const Row& row) struct Set { const Tab& m_tab; unsigned m_rows; - unsigned m_count; Row** m_row; Row** m_saverow; Row* m_keyrow; NdbRecAttr** m_rec; Set(const Tab& tab, unsigned rows); ~Set(); + void reset(); + unsigned count() const; // row methods bool exist(unsigned i) const; + Row::Op pending(unsigned i) const; + void notpending(unsigned i); + void notpending(const Lst& lst); void calc(Par par, unsigned i); int insrow(Par par, unsigned i); int updrow(Par par, unsigned i); @@ -1380,7 +1526,7 @@ struct Set { void savepoint(); void commit(); void rollback(); - // locking (not perfect since ops may complete in different order) + // protect structure NdbMutex* m_mutex; void lock() { NdbMutex_Lock(m_mutex); @@ -1396,9 +1542,9 @@ Set::Set(const Tab& tab, unsigned rows) : m_tab(tab) { m_rows = rows; - m_count = 0; m_row = new Row* [m_rows]; for (unsigned i = 0; i < m_rows; i++) { + // allocate on need to save space m_row[i] = 0; } m_saverow = 0; @@ -1425,11 +1571,47 @@ Set::~Set() NdbMutex_Destroy(m_mutex); } +void +Set::reset() +{ + for (unsigned i = 0; i < m_rows; i++) { + if (m_row[i] != 0) { + Row& row = *m_row[i]; + row.m_exist = false; + } + } +} + +unsigned +Set::count() const +{ + unsigned count = 0; + for (unsigned i = 0; i < m_rows; i++) { + if (m_row[i] != 0) { + Row& row = *m_row[i]; + if (row.m_exist) + count++; + } + } + return count; +} + bool Set::exist(unsigned i) const { assert(i < m_rows); - return m_row[i] != 0 && m_row[i]->m_exist; + if (m_row[i] == 0) // not allocated => not exist + return false; + return m_row[i]->m_exist; +} + +Row::Op +Set::pending(unsigned i) const +{ + assert(i < m_rows); + if (m_row[i] == 0) // not allocated => not pending + return Row::NoOp; + return m_row[i]->m_pending; } void @@ -1448,9 +1630,9 @@ Set::calc(Par par, unsigned i) int Set::insrow(Par par, unsigned i) { - assert(m_row[i] != 0 && m_count < m_rows); - CHK(m_row[i]->insrow(par) == 0); - m_count++; + assert(m_row[i] != 0); + Row& row = *m_row[i]; + CHK(row.insrow(par) == 0); return 0; } @@ -1458,16 +1640,17 @@ int Set::updrow(Par par, unsigned i) { assert(m_row[i] != 0); - CHK(m_row[i]->updrow(par) == 0); + Row& row = *m_row[i]; + CHK(row.updrow(par) == 0); return 0; } int Set::delrow(Par par, unsigned i) { - assert(m_row[i] != 0 && m_count != 0); - CHK(m_row[i]->delrow(par) == 0); - m_count--; + assert(m_row[i] != 0); + Row& row = *m_row[i]; + CHK(row.delrow(par) == 0); return 0; } @@ -1507,7 +1690,7 @@ Set::getkey(Par par, unsigned* i) assert(m_rec[0] != 0); const char* aRef0 = m_rec[0]->aRef(); Uint32 key = *(const Uint32*)aRef0; - CHKMSG(key < m_rows, "key=" << key << " rows=" << m_rows); + CHK(key < m_rows); *i = key; return 0; } @@ -1532,19 +1715,37 @@ Set::putval(unsigned i, bool force) val.copy(aRef); val.m_null = false; } - if (! row.m_exist) { + if (! row.m_exist) row.m_exist = true; - m_count++; - } return 0; } +void +Set::notpending(unsigned i) +{ + assert(m_row[i] != 0); + Row& row = *m_row[i]; + if (row.m_pending == Row::InsOp) + row.m_exist = true; + if (row.m_pending == Row::DelOp) + row.m_exist = false; + row.m_pending = Row::NoOp; +} + +void +Set::notpending(const Lst& lst) +{ + for (unsigned j = 0; j < lst.m_cnt; j++) { + unsigned i = lst.m_arr[j]; + notpending(i); + } +} + int Set::verify(const Set& set2) const { const Tab& tab = m_tab; assert(&tab == &set2.m_tab && m_rows == set2.m_rows); - CHKMSG(m_count == set2.m_count, "set=" << m_count << " set2=" << set2.m_count); for (unsigned i = 0; i < m_rows; i++) { CHK(exist(i) == set2.exist(i)); if (! exist(i)) @@ -1618,8 +1819,8 @@ int BVal::setbnd(Par par) const { Con& con = par.con(); - const char* addr = (const char*)dataaddr(); - assert(! m_null); + assert(g_compare_null || ! m_null); + const char* addr = ! m_null ? (const char*)dataaddr() : 0; const ICol& icol = m_icol; CHK(con.setBound(icol.m_num, m_type, addr) == 0); return 0; @@ -1647,7 +1848,10 @@ struct BSet { unsigned m_bvals; BVal** m_bval; BSet(const Tab& tab, const ITab& itab, unsigned rows); + ~BSet(); + void reset(); void calc(Par par); + void calcpk(Par par, unsigned i); int setbnd(Par par) const; void filter(const Set& set, Set& set2) const; }; @@ -1659,12 +1863,31 @@ BSet::BSet(const Tab& tab, const ITab& itab, unsigned rows) : m_bvals(0) { m_bval = new BVal* [m_alloc]; + for (unsigned i = 0; i < m_alloc; i++) { + m_bval[i] = 0; + } +} + +BSet::~BSet() +{ + delete [] m_bval; +} + +void +BSet::reset() +{ + while (m_bvals > 0) { + unsigned i = --m_bvals; + delete m_bval[i]; + m_bval[i] = 0; + } } void BSet::calc(Par par) { const ITab& itab = m_itab; + reset(); for (unsigned k = 0; k < itab.m_icols; k++) { const ICol& icol = itab.m_icol[k]; const Col& col = icol.m_col; @@ -1686,7 +1909,8 @@ BSet::calc(Par par) if (k + 1 < itab.m_icols) bval.m_type = 4; // value generation parammeters - par.m_pctnull = 0; + if (! g_compare_null) + par.m_pctnull = 0; par.m_pctrange = 50; // bit higher do { bval.calc(par, 0); @@ -1705,6 +1929,23 @@ BSet::calc(Par par) } } +void +BSet::calcpk(Par par, unsigned i) +{ + const ITab& itab = m_itab; + reset(); + for (unsigned k = 0; k < itab.m_icols; k++) { + const ICol& icol = itab.m_icol[k]; + const Col& col = icol.m_col; + assert(col.m_pk); + assert(m_bvals < m_alloc); + BVal& bval = *new BVal(icol); + m_bval[m_bvals++] = &bval; + bval.m_type = 4; + bval.calc(par, i); + } +} + int BSet::setbnd(Par par) const { @@ -1721,23 +1962,25 @@ BSet::filter(const Set& set, Set& set2) const const Tab& tab = m_tab; const ITab& itab = m_itab; assert(&tab == &set2.m_tab && set.m_rows == set2.m_rows); - assert(set2.m_count == 0); + assert(set2.count() == 0); for (unsigned i = 0; i < set.m_rows; i++) { if (! set.exist(i)) continue; const Row& row = *set.m_row[i]; - bool ok1 = false; - for (unsigned k = 0; k < itab.m_icols; k++) { - const ICol& icol = itab.m_icol[k]; - const Col& col = icol.m_col; - const Val& val = *row.m_val[col.m_num]; - if (! val.m_null) { - ok1 = true; - break; + if (! g_store_null_key) { + bool ok1 = false; + for (unsigned k = 0; k < itab.m_icols; k++) { + const ICol& icol = itab.m_icol[k]; + const Col& col = icol.m_col; + const Val& val = *row.m_val[col.m_num]; + if (! val.m_null) { + ok1 = true; + break; + } } + if (! ok1) + continue; } - if (! ok1) - continue; bool ok2 = true; for (unsigned j = 0; j < m_bvals; j++) { const BVal& bval = *m_bval[j]; @@ -1769,7 +2012,6 @@ BSet::filter(const Set& set, Set& set2) const assert(! row2.m_exist); row2.copy(row); row2.m_exist = true; - set2.m_count++; } } @@ -1794,28 +2036,46 @@ pkinsert(Par par) Set& set = par.set(); LL3("pkinsert"); CHK(con.startTransaction() == 0); - unsigned n = 0; + Lst lst; for (unsigned j = 0; j < par.m_rows; j++) { unsigned i = thrrow(par, j); set.lock(); - if (set.exist(i)) { + if (set.exist(i) || set.pending(i)) { set.unlock(); continue; } set.calc(par, i); - LL4("pkinsert " << i << ": " << *set.m_row[i]); - CHKTRY(set.insrow(par, i) == 0, set.unlock()); + CHK(set.insrow(par, i) == 0); set.unlock(); - if (++n == par.m_batch) { - CHK(con.execute(Commit) == 0); + LL4("pkinsert " << i << ": " << *set.m_row[i]); + lst.push(i); + if (lst.cnt() == par.m_batch) { + bool deadlock = par.m_deadlock; + CHK(con.execute(Commit, deadlock) == 0); con.closeTransaction(); + if (deadlock) { + LL1("pkinsert: stop on deadlock"); + return 0; + } + set.lock(); + set.notpending(lst); + set.unlock(); + lst.reset(); CHK(con.startTransaction() == 0); - n = 0; } } - if (n != 0) { - CHK(con.execute(Commit) == 0); - n = 0; + if (lst.cnt() != 0) { + bool deadlock = par.m_deadlock; + CHK(con.execute(Commit, deadlock) == 0); + con.closeTransaction(); + if (deadlock) { + LL1("pkinsert: stop on deadlock"); + return 0; + } + set.lock(); + set.notpending(lst); + set.unlock(); + return 0; } con.closeTransaction(); return 0; @@ -1828,28 +2088,45 @@ pkupdate(Par par) Set& set = par.set(); LL3("pkupdate"); CHK(con.startTransaction() == 0); - unsigned n = 0; + Lst lst; + bool deadlock = false; for (unsigned j = 0; j < par.m_rows; j++) { unsigned i = thrrow(par, j); set.lock(); - if (! set.exist(i)) { + if (! set.exist(i) || set.pending(i)) { set.unlock(); continue; } set.calc(par, i); - LL4("pkupdate " << i << ": " << *set.m_row[i]); - CHKTRY(set.updrow(par, i) == 0, set.unlock()); + CHK(set.updrow(par, i) == 0); set.unlock(); - if (++n == par.m_batch) { - CHK(con.execute(Commit) == 0); + LL4("pkupdate " << i << ": " << *set.m_row[i]); + lst.push(i); + if (lst.cnt() == par.m_batch) { + deadlock = par.m_deadlock; + CHK(con.execute(Commit, deadlock) == 0); + if (deadlock) { + LL1("pkupdate: stop on deadlock"); + break; + } con.closeTransaction(); + set.lock(); + set.notpending(lst); + set.unlock(); + lst.reset(); CHK(con.startTransaction() == 0); - n = 0; } } - if (n != 0) { - CHK(con.execute(Commit) == 0); - n = 0; + if (! deadlock && lst.cnt() != 0) { + deadlock = par.m_deadlock; + CHK(con.execute(Commit, deadlock) == 0); + if (deadlock) { + LL1("pkupdate: stop on deadlock"); + } else { + set.lock(); + set.notpending(lst); + set.unlock(); + } } con.closeTransaction(); return 0; @@ -1862,27 +2139,44 @@ pkdelete(Par par) Set& set = par.set(); LL3("pkdelete"); CHK(con.startTransaction() == 0); - unsigned n = 0; + Lst lst; + bool deadlock = false; for (unsigned j = 0; j < par.m_rows; j++) { unsigned i = thrrow(par, j); set.lock(); - if (! set.exist(i)) { + if (! set.exist(i) || set.pending(i)) { set.unlock(); continue; } - LL4("pkdelete " << i << ": " << *set.m_row[i]); - CHKTRY(set.delrow(par, i) == 0, set.unlock()); + CHK(set.delrow(par, i) == 0); set.unlock(); - if (++n == par.m_batch) { - CHK(con.execute(Commit) == 0); + LL4("pkdelete " << i << ": " << *set.m_row[i]); + lst.push(i); + if (lst.cnt() == par.m_batch) { + deadlock = par.m_deadlock; + CHK(con.execute(Commit, deadlock) == 0); + if (deadlock) { + LL1("pkdelete: stop on deadlock"); + break; + } con.closeTransaction(); + set.lock(); + set.notpending(lst); + set.unlock(); + lst.reset(); CHK(con.startTransaction() == 0); - n = 0; } } - if (n != 0) { - CHK(con.execute(Commit) == 0); - n = 0; + if (! deadlock && lst.cnt() != 0) { + deadlock = par.m_deadlock; + CHK(con.execute(Commit, deadlock) == 0); + if (deadlock) { + LL1("pkdelete: stop on deadlock"); + } else { + set.lock(); + set.notpending(lst); + set.unlock(); + } } con.closeTransaction(); return 0; @@ -1893,21 +2187,25 @@ pkread(Par par) { Con& con = par.con(); const Tab& tab = par.tab(); - const Set& set = par.set(); + Set& set = par.set(); LL3((par.m_verify ? "pkverify " : "pkread ") << tab.m_name); // expected const Set& set1 = set; Set set2(tab, set.m_rows); for (unsigned i = 0; i < set.m_rows; i++) { - if (! set.exist(i)) + set.lock(); + if (! set.exist(i) || set.pending(i)) { + set.unlock(); continue; + } + set.unlock(); CHK(con.startTransaction() == 0); CHK(set2.selrow(par, i) == 0); CHK(con.execute(Commit) == 0); unsigned i2 = (unsigned)-1; CHK(set2.getkey(par, &i2) == 0 && i == i2); CHK(set2.putval(i, false) == 0); - LL4("row " << set2.m_count << ": " << *set2.m_row[i]); + LL4("row " << set2.count() << ": " << *set2.m_row[i]); con.closeTransaction(); } if (par.m_verify) @@ -1915,6 +2213,32 @@ pkread(Par par) return 0; } +static int +pkreadfast(Par par, unsigned count) +{ + Con& con = par.con(); + const Tab& tab = par.tab(); + const Set& set = par.set(); + LL3("pkfast " << tab.m_name); + Row keyrow(tab); + // not batched on purpose + for (unsigned j = 0; j < count; j++) { + unsigned i = urandom(set.m_rows); + assert(set.exist(i)); + CHK(con.startTransaction() == 0); + // define key + keyrow.calc(par, i); + CHK(keyrow.selrow(par) == 0); + NdbRecAttr* rec; + CHK(con.getValue((Uint32)0, rec) == 0); + CHK(con.executeScan() == 0); + // get 1st column + CHK(con.execute(Commit) == 0); + con.closeTransaction(); + } + return 0; +} + // scan read static int @@ -1928,19 +2252,19 @@ scanreadtable(Par par) LL3((par.m_verify ? "scanverify " : "scanread ") << tab.m_name); Set set2(tab, set.m_rows); CHK(con.startTransaction() == 0); - CHK(con.getNdbOperation(tab) == 0); + CHK(con.getNdbScanOperation(tab) == 0); CHK(con.openScanRead(par.m_scanrd) == 0); set2.getval(par); CHK(con.executeScan() == 0); while (1) { int ret; - CHK((ret = con.nextScanResult()) == 0 || ret == 1); + CHK((ret = con.nextScanResult(true)) == 0 || ret == 1); if (ret == 1) break; unsigned i = (unsigned)-1; CHK(set2.getkey(par, &i) == 0); CHK(set2.putval(i, false) == 0); - LL4("row " << set2.m_count << ": " << *set2.m_row[i]); + LL4("row " << set2.count() << ": " << *set2.m_row[i]); } con.closeTransaction(); if (par.m_verify) @@ -1949,6 +2273,33 @@ scanreadtable(Par par) } static int +scanreadtablefast(Par par, unsigned countcheck) +{ + Con& con = par.con(); + const Tab& tab = par.tab(); + const Set& set = par.set(); + LL3("scanfast " << tab.m_name); + CHK(con.startTransaction() == 0); + CHK(con.getNdbScanOperation(tab) == 0); + CHK(con.openScanRead(par.m_scanrd) == 0); + // get 1st column + NdbRecAttr* rec; + CHK(con.getValue((Uint32)0, rec) == 0); + CHK(con.executeScan() == 0); + unsigned count = 0; + while (1) { + int ret; + CHK((ret = con.nextScanResult(true)) == 0 || ret == 1); + if (ret == 1) + break; + count++; + } + con.closeTransaction(); + CHK(count == countcheck); + return 0; +} + +static int scanreadindex(Par par, const ITab& itab, const BSet& bset) { Con& con = par.con(); @@ -1961,21 +2312,21 @@ scanreadindex(Par par, const ITab& itab, const BSet& bset) LL4(bset); Set set2(tab, set.m_rows); CHK(con.startTransaction() == 0); - CHK(con.getNdbOperation(itab, tab) == 0); + CHK(con.getNdbScanOperation(itab, tab) == 0); CHK(con.openScanRead(par.m_scanrd) == 0); CHK(bset.setbnd(par) == 0); set2.getval(par); CHK(con.executeScan() == 0); while (1) { int ret; - CHK((ret = con.nextScanResult()) == 0 || ret == 1); + CHK((ret = con.nextScanResult(true)) == 0 || ret == 1); if (ret == 1) break; unsigned i = (unsigned)-1; CHK(set2.getkey(par, &i) == 0); LL4("key " << i); CHK(set2.putval(i, par.m_dups) == 0); - LL4("row " << set2.m_count << ": " << *set2.m_row[i]); + LL4("row " << set2.count() << ": " << *set2.m_row[i]); } con.closeTransaction(); if (par.m_verify) @@ -1984,10 +2335,39 @@ scanreadindex(Par par, const ITab& itab, const BSet& bset) } static int +scanreadindexfast(Par par, const ITab& itab, const BSet& bset, unsigned countcheck) +{ + Con& con = par.con(); + const Tab& tab = par.tab(); + const Set& set = par.set(); + LL3("scanfast " << itab.m_name << " bounds=" << bset.m_bvals); + LL4(bset); + CHK(con.startTransaction() == 0); + CHK(con.getNdbScanOperation(itab, tab) == 0); + CHK(con.openScanRead(par.m_scanrd) == 0); + CHK(bset.setbnd(par) == 0); + // get 1st column + NdbRecAttr* rec; + CHK(con.getValue((Uint32)0, rec) == 0); + CHK(con.executeScan() == 0); + unsigned count = 0; + while (1) { + int ret; + CHK((ret = con.nextScanResult(true)) == 0 || ret == 1); + if (ret == 1) + break; + count++; + } + con.closeTransaction(); + CHK(count == countcheck); + return 0; +} + +static int scanreadindex(Par par, const ITab& itab) { const Tab& tab = par.tab(); - for (unsigned i = 0; i < par.m_subloop; i++) { + for (unsigned i = 0; i < par.m_idxloop; i++) { BSet bset(tab, itab, par.m_rows); bset.calc(par); CHK(scanreadindex(par, itab, bset) == 0); @@ -2017,6 +2397,60 @@ scanreadall(Par par) return 0; } +// timing scans + +static int +timescantable(Par par) +{ + par.tmr().on(); + CHK(scanreadtablefast(par, par.m_totrows) == 0); + par.tmr().off(par.set().m_rows); + return 0; +} + +static int +timescanpkindex(Par par) +{ + const Tab& tab = par.tab(); + const ITab& itab = tab.m_itab[0]; // 1st index is on PK + BSet bset(tab, itab, par.m_rows); + par.tmr().on(); + CHK(scanreadindexfast(par, itab, bset, par.m_totrows) == 0); + par.tmr().off(par.set().m_rows); + return 0; +} + +static int +timepkreadtable(Par par) +{ + par.tmr().on(); + unsigned count = par.m_samples; + if (count == 0) + count = par.m_totrows; + CHK(pkreadfast(par, count) == 0); + par.tmr().off(count); + return 0; +} + +static int +timepkreadindex(Par par) +{ + const Tab& tab = par.tab(); + const ITab& itab = tab.m_itab[0]; // 1st index is on PK + BSet bset(tab, itab, par.m_rows); + unsigned count = par.m_samples; + if (count == 0) + count = par.m_totrows; + par.tmr().on(); + for (unsigned j = 0; j < count; j++) { + unsigned i = urandom(par.m_totrows); + bset.calcpk(par, i); + CHK(scanreadindexfast(par, itab, bset, 1) == 0); + } + par.tmr().off(count); + return 0; +} + // scan update static int @@ -2028,36 +2462,70 @@ scanupdatetable(Par par) LL3("scan update " << tab.m_name); Set set2(tab, set.m_rows); CHK(con.startTransaction() == 0); - CHK(con.getNdbOperation(tab) == 0); + CHK(con.getNdbScanOperation(tab) == 0); CHK(con.openScanExclusive(par.m_scanex) == 0); set2.getval(par); CHK(con.executeScan() == 0); unsigned count = 0; // updating trans Con con2; - con2.m_ndb = con.m_ndb; - CHK(con2.startBuddyTransaction(con) == 0); + con2.connect(con); + CHK(con2.startTransaction() == 0); + Lst lst; + bool deadlock = false; while (1) { int ret; - CHK((ret = con.nextScanResult()) == 0 || ret == 1); + deadlock = par.m_deadlock; + CHK((ret = con.nextScanResult(true, deadlock)) == 0 || ret == 1); + if (ret == 1) + break; + if (deadlock) { + LL1("scanupdatetable: stop on deadlock"); + break; + } + do { + unsigned i = (unsigned)-1; + CHK(set2.getkey(par, &i) == 0); + const Row& row = *set.m_row[i]; + set.lock(); + if (! set.exist(i) || set.pending(i)) { + LL4("scan update " << tab.m_name << ": skip: " << row); + } else { + CHKTRY(set2.putval(i, false) == 0, set.unlock()); + CHKTRY(con.updateScanTuple(con2) == 0, set.unlock()); + Par par2 = par; + par2.m_con = &con2; + set.calc(par, i); + CHKTRY(set.setrow(par2, i) == 0, set.unlock()); + LL4("scan update " << tab.m_name << ": " << row); + lst.push(i); + } + set.unlock(); + if (lst.cnt() == par.m_batch) { + CHK(con2.execute(Commit) == 0); + con2.closeTransaction(); + set.lock(); + set.notpending(lst); + set.unlock(); + count += lst.cnt(); + lst.reset(); + CHK(con2.startTransaction() == 0); + } + CHK((ret = con.nextScanResult(false)) == 0 || ret == 1 || ret == 2); + if (ret == 2 && lst.cnt() != 0) { + CHK(con2.execute(Commit) == 0); + con2.closeTransaction(); + set.lock(); + set.notpending(lst); + set.unlock(); + count += lst.cnt(); + lst.reset(); + CHK(con2.startTransaction() == 0); + } + } while (ret == 0); if (ret == 1) break; - unsigned i = (unsigned)-1; - CHK(set2.getkey(par, &i) == 0); - LL4("key " << i); - CHK(set2.putval(i, false) == 0); - CHK(con2.takeOverForUpdate(con) == 0); - Par par2 = par; - par2.m_con = &con2; - set.lock(); - set.calc(par, i); - LL4("scan update " << tab.m_name << ": " << *set.m_row[i]); - CHKTRY(set.setrow(par2, i) == 0, set.unlock()); - set.unlock(); - CHK(con2.execute(NoCommit) == 0); - count++; } - CHK(con2.execute(Commit) == 0); con2.closeTransaction(); LL3("scan update " << tab.m_name << " rows updated=" << count); con.closeTransaction(); @@ -2073,7 +2541,7 @@ scanupdateindex(Par par, const ITab& itab, const BSet& bset) LL3("scan update " << itab.m_name); Set set2(tab, set.m_rows); CHK(con.startTransaction() == 0); - CHK(con.getNdbOperation(itab, tab) == 0); + CHK(con.getNdbScanOperation(itab, tab) == 0); CHK(con.openScanExclusive(par.m_scanex) == 0); CHK(bset.setbnd(par) == 0); set2.getval(par); @@ -2081,32 +2549,61 @@ scanupdateindex(Par par, const ITab& itab, const BSet& bset) unsigned count = 0; // updating trans Con con2; - con2.m_ndb = con.m_ndb; - CHK(con2.startBuddyTransaction(con) == 0); + con2.connect(con); + CHK(con2.startTransaction() == 0); + Lst lst; + bool deadlock = false; while (1) { int ret; - CHK((ret = con.nextScanResult()) == 0 || ret == 1); + deadlock = par.m_deadlock; + CHK((ret = con.nextScanResult(true, deadlock)) == 0 || ret == 1); if (ret == 1) break; - unsigned i = (unsigned)-1; - CHK(set2.getkey(par, &i) == 0); - LL4("key " << i); - CHK(set2.putval(i, par.m_dups) == 0); - // avoid deadlock for now - //if (! isthrrow(par, i)) - //continue; - CHK(con2.takeOverForUpdate(con) == 0); - Par par2 = par; - par2.m_con = &con2; - set.lock(); - set.calc(par, i); - LL4("scan update " << itab.m_name << ": " << *set.m_row[i]); - CHKTRY(set.setrow(par2, i) == 0, set.unlock()); - set.unlock(); - CHK(con2.execute(NoCommit) == 0); - count++; + if (deadlock) { + LL1("scanupdateindex: stop on deadlock"); + break; + } + do { + unsigned i = (unsigned)-1; + CHK(set2.getkey(par, &i) == 0); + const Row& row = *set.m_row[i]; + set.lock(); + if (! set.exist(i) || set.pending(i)) { + LL4("scan update " << itab.m_name << ": skip: " << row); + } else { + CHKTRY(set2.putval(i, par.m_dups) == 0, set.unlock()); + CHKTRY(con.updateScanTuple(con2) == 0, set.unlock()); + Par par2 = par; + par2.m_con = &con2; + set.calc(par, i); + CHKTRY(set.setrow(par2, i) == 0, set.unlock()); + LL4("scan update " << itab.m_name << ": " << row); + lst.push(i); + } + set.unlock(); + if (lst.cnt() == par.m_batch) { + CHK(con2.execute(Commit) == 0); + con2.closeTransaction(); + set.lock(); + set.notpending(lst); + set.unlock(); + count += lst.cnt(); + lst.reset(); + CHK(con2.startTransaction() == 0); + } + CHK((ret = con.nextScanResult(false)) == 0 || ret == 1 || ret == 2); + if (ret == 2 && lst.cnt() != 0) { + CHK(con2.execute(Commit) == 0); + con2.closeTransaction(); + set.lock(); + set.notpending(lst); + set.unlock(); + count += lst.cnt(); + lst.reset(); + CHK(con2.startTransaction() == 0); + } + } while (ret == 0); } - CHK(con2.execute(Commit) == 0); con2.closeTransaction(); LL3("scan update " << itab.m_name << " rows updated=" << count); con.closeTransaction(); @@ -2117,7 +2614,7 @@ static int scanupdateindex(Par par, const ITab& itab) { const Tab& tab = par.tab(); - for (unsigned i = 0; i < par.m_subloop; i++) { + for (unsigned i = 0; i < par.m_idxloop; i++) { BSet bset(tab, itab, par.m_rows); bset.calc(par); CHK(scanupdateindex(par, itab, bset) == 0); @@ -2148,41 +2645,15 @@ scanupdateall(Par par) // medium level routines -static bool -ignoreverifyerror(Par par) -{ - Con& con = par.con(); - bool b = par.m_threads > 1; - if (b) { - LL1("ignore verify error"); - if (con.m_tx != 0) - con.closeTransaction(); - return true; - } - return b; -} - static int readverify(Par par) { par.m_verify = true; - CHK(pkread(par) == 0 || ignoreverifyerror(par)); - CHK(scanreadall(par) == 0 || ignoreverifyerror(par)); + CHK(pkread(par) == 0); + CHK(scanreadall(par) == 0); return 0; } -static bool -ignoredeadlock(Par par) -{ - Con& con = par.con(); - if (con.m_errtype == Con::ErrDeadlock) { - LL1("ignore deadlock"); - con.closeTransaction(); - return true; - } - return false; -} - static int pkupdatescanread(Par par) { @@ -2204,15 +2675,16 @@ static int mixedoperations(Par par) { par.m_dups = true; + par.m_deadlock = true; unsigned sel = urandom(10); if (sel < 2) { - CHK(pkdelete(par) == 0 || ignoredeadlock(par)); + CHK(pkdelete(par) == 0); } else if (sel < 4) { - CHK(pkupdate(par) == 0 || ignoredeadlock(par)); + CHK(pkupdate(par) == 0); } else if (sel < 6) { - CHK(scanupdatetable(par) == 0 || ignoredeadlock(par)); + CHK(scanupdatetable(par) == 0); } else { - CHK(scanupdateindex(par) == 0 || ignoredeadlock(par)); + CHK(scanupdateindex(par) == 0); } return 0; } @@ -2346,7 +2818,6 @@ Thr::run() break; } LL4("start"); - CHK(con.bugger() == 0); assert(m_state == Start); m_ret = (*m_func)(m_par); m_state = Stopped; @@ -2426,6 +2897,7 @@ runstep(Par par, const char* fname, TFunc func, unsigned mode) Thr& thr = *g_thrlist[n]; thr.m_par.m_tab = par.m_tab; thr.m_par.m_set = par.m_set; + thr.m_par.m_tmr = par.m_tmr; thr.m_func = func; thr.start(); } @@ -2476,13 +2948,13 @@ tpkops(Par par) RUNSTEP(par, pkinsert, MT); RUNSTEP(par, createindex, ST); RUNSTEP(par, invalidateindex, MT); - RUNSTEP(par, readverify, MT); + RUNSTEP(par, readverify, ST); for (unsigned i = 0; i < par.m_subloop; i++) { RUNSTEP(par, pkupdatescanread, MT); - RUNSTEP(par, readverify, MT); + RUNSTEP(par, readverify, ST); } RUNSTEP(par, pkdelete, MT); - RUNSTEP(par, readverify, MT); + RUNSTEP(par, readverify, ST); return 0; } @@ -2495,10 +2967,10 @@ tmixedops(Par par) RUNSTEP(par, pkinsert, MT); RUNSTEP(par, createindex, ST); RUNSTEP(par, invalidateindex, MT); - RUNSTEP(par, readverify, MT); + RUNSTEP(par, readverify, ST); for (unsigned i = 0; i < par.m_subloop; i++) { RUNSTEP(par, mixedoperations, MT); - RUNSTEP(par, readverify, MT); + RUNSTEP(par, readverify, ST); } return 0; } @@ -2513,7 +2985,7 @@ tbusybuild(Par par) for (unsigned i = 0; i < par.m_subloop; i++) { RUNSTEP(par, pkupdateindexbuild, MT); RUNSTEP(par, invalidateindex, MT); - RUNSTEP(par, readverify, MT); + RUNSTEP(par, readverify, ST); RUNSTEP(par, dropindex, ST); } return 0; @@ -2564,6 +3036,50 @@ ttimemaint(Par par) } static int +ttimescan(Par par) +{ + Tmr t1, t2; + RUNSTEP(par, droptable, ST); + RUNSTEP(par, createtable, ST); + RUNSTEP(par, invalidatetable, MT); + for (unsigned i = 0; i < par.m_subloop; i++) { + RUNSTEP(par, pkinsert, MT); + RUNSTEP(par, createindex, ST); + par.m_tmr = &t1; + RUNSTEP(par, timescantable, ST); + par.m_tmr = &t2; + RUNSTEP(par, timescanpkindex, ST); + RUNSTEP(par, dropindex, ST); + } + LL1("full scan table - " << t1.time()); + LL1("full scan PK index - " << t2.time()); + LL1("overhead - " << t2.over(t1)); + return 0; +} + +static int +ttimepkread(Par par) +{ + Tmr t1, t2; + RUNSTEP(par, droptable, ST); + RUNSTEP(par, createtable, ST); + RUNSTEP(par, invalidatetable, MT); + for (unsigned i = 0; i < par.m_subloop; i++) { + RUNSTEP(par, pkinsert, MT); + RUNSTEP(par, createindex, ST); + par.m_tmr = &t1; + RUNSTEP(par, timepkreadtable, ST); + par.m_tmr = &t2; + RUNSTEP(par, timepkreadindex, ST); + RUNSTEP(par, dropindex, ST); + } + LL1("pk read table - " << t1.time()); + LL1("pk read PK index - " << t2.time()); + LL1("overhead - " << t2.over(t1)); + return 0; +} + +static int tdrop(Par par) { RUNSTEP(par, droptable, ST); @@ -2589,6 +3105,8 @@ tcaselist[] = { TCase("d", tbusybuild, "pk operations and index build"), TCase("t", ttimebuild, "time index build"), TCase("u", ttimemaint, "time index maintenance"), + TCase("v", ttimescan, "time full scan table vs index on pk"), + TCase("w", ttimepkread, "time pk read table vs index on pk"), TCase("z", tdrop, "drop test tables") }; @@ -2608,7 +3126,7 @@ printcases() static void printtables() { - ndbout << "tables and indexes:" << endl; + ndbout << "tables and indexes (X1 is on table PK):" << endl; for (unsigned j = 0; j < tabcount; j++) { const Tab& tab = tablist[j]; ndbout << " " << tab.m_name; @@ -2624,7 +3142,8 @@ static int runtest(Par par) { LL1("start"); - srandom(par.m_seed); + if (par.m_seed != 0) + srandom(par.m_seed); Con con; CHK(con.connect() == 0); par.m_con = &con; @@ -2639,6 +3158,8 @@ runtest(Par par) } for (unsigned l = 0; par.m_loop == 0 || l < par.m_loop; l++) { LL1("loop " << l); + if (par.m_seed == 0) + srandom(l); for (unsigned i = 0; i < tcasecount; i++) { const TCase& tcase = tcaselist[i]; if (par.m_case != 0 && strchr(par.m_case, tcase.m_name[0]) == 0) @@ -2649,8 +3170,8 @@ runtest(Par par) continue; const Tab& tab = tablist[j]; par.m_tab = &tab; - Set set(tab, par.m_totrows); - par.m_set = &set; + delete par.m_set; + par.m_set = new Set(tab, par.m_totrows); LL1("table " << tab.m_name); CHK(tcase.m_func(par) == 0); } @@ -2680,6 +3201,12 @@ NDB_COMMAND(testOIBasic, "testOIBasic", "testOIBasic", "testOIBasic", 65535) ndbout << "testOIBasic: unknown argument " << arg; goto usage; } + if (strcmp(arg, "-batch") == 0) { + if (++argv, --argc > 0) { + g_opt.m_batch = atoi(argv[0]); + continue; + } + } if (strcmp(arg, "-case") == 0) { if (++argv, --argc > 0) { g_opt.m_case = strdup(argv[0]); @@ -2736,6 +3263,12 @@ NDB_COMMAND(testOIBasic, "testOIBasic", "testOIBasic", "testOIBasic", 65535) continue; } } + if (strcmp(arg, "-samples") == 0) { + if (++argv, --argc > 0) { + g_opt.m_samples = atoi(argv[0]); + continue; + } + } if (strcmp(arg, "-scanrd") == 0) { if (++argv, --argc > 0) { g_opt.m_scanrd = atoi(argv[0]); diff --git a/ndb/test/ndbapi/testRestartGci.cpp b/ndb/test/ndbapi/testRestartGci.cpp index e3dd1f8e2ce..54d38654ff2 100644 --- a/ndb/test/ndbapi/testRestartGci.cpp +++ b/ndb/test/ndbapi/testRestartGci.cpp @@ -216,3 +216,5 @@ NDBT_TESTSUITE_END(testRestartGci); int main(int argc, const char** argv){ return testRestartGci.execute(argc, argv); } + +template class Vector<SavedRecord>; diff --git a/ndb/test/ndbapi/testScan.cpp b/ndb/test/ndbapi/testScan.cpp index bc3be0b7dc9..3d8b37df0ca 100644 --- a/ndb/test/ndbapi/testScan.cpp +++ b/ndb/test/ndbapi/testScan.cpp @@ -65,7 +65,7 @@ int runDropAllTablesExceptTestTable(NDBT_Context* ctx, NDBT_Step* step){ } int res = GETNDB(step)->getDictionary()->dropTable(tab->getName()); - if(res != -1){ + if(res == -1){ return NDBT_FAILED; } } @@ -776,108 +776,19 @@ int runOnlyOpenScanOnce(NDBT_Context* ctx, NDBT_Step* step){ } int runOnlyOneOpInScanTrans(NDBT_Context* ctx, NDBT_Step* step){ - const NdbDictionary::Table* pTab = ctx->getTab(); - int records = ctx->getNumRecords(); - int numFailed = 0; - - ScanFunctions scanF(*pTab); - if (scanF.scanReadFunctions(GETNDB(step), - records, - 6, - ScanFunctions::OnlyOneOpInScanTrans, - false) == 0){ - numFailed++; - } - if (scanF.scanReadFunctions(GETNDB(step), - records, - 6, - ScanFunctions::OnlyOneOpInScanTrans, - true) == 0){ - numFailed++; - } - - - if(numFailed > 0) - return NDBT_FAILED; - else - return NDBT_OK; - + return NDBT_OK; } int runExecuteScanWithoutOpenScan(NDBT_Context* ctx, NDBT_Step* step){ - const NdbDictionary::Table* pTab = ctx->getTab(); - int records = ctx->getNumRecords(); - int numFailed = 0; - ScanFunctions scanF(*pTab); - if (scanF.scanReadFunctions(GETNDB(step), - records, - 1, - ScanFunctions::ExecuteScanWithOutOpenScan, - false) == 0){ - numFailed++; - } - - if(numFailed > 0) - return NDBT_FAILED; - else - return NDBT_OK; + return NDBT_OK; } - - int runOnlyOneOpBeforeOpenScan(NDBT_Context* ctx, NDBT_Step* step){ - const NdbDictionary::Table* pTab = ctx->getTab(); - int records = ctx->getNumRecords(); - int numFailed = 0; - - ScanFunctions scanF(*pTab); - if (scanF.scanReadFunctions(GETNDB(step), - records, - 6, - ScanFunctions::OnlyOneOpBeforeOpenScan, - false) == 0){ - numFailed++; - } - if (scanF.scanReadFunctions(GETNDB(step), - records, - 6, - ScanFunctions::OnlyOneOpBeforeOpenScan, - true) == 0){ - numFailed++; - } - - if(numFailed > 0) - return NDBT_FAILED; - else return NDBT_OK; - } -int runOnlyOneScanPerTrans(NDBT_Context* ctx, NDBT_Step* step){ - const NdbDictionary::Table* pTab = ctx->getTab(); - int records = ctx->getNumRecords(); - int numFailed = 0; - - ScanFunctions scanF(*pTab); - if (scanF.scanReadFunctions(GETNDB(step), - records, - 6, - ScanFunctions::OnlyOneScanPerTrans, - false) == 0){ - numFailed++; - } - if (scanF.scanReadFunctions(GETNDB(step), - records, - 6, - ScanFunctions::OnlyOneScanPerTrans, - true) == 0){ - numFailed++; - } - - if(numFailed > 0) - return NDBT_FAILED; - else - return NDBT_OK; +int runOnlyOneScanPerTrans(NDBT_Context* ctx, NDBT_Step* step){ + return NDBT_OK; } int runNoCloseTransaction(NDBT_Context* ctx, NDBT_Step* step){ @@ -970,6 +881,93 @@ int runCheckInactivityBeforeClose(NDBT_Context* ctx, NDBT_Step* step){ } +int runScanRestart(NDBT_Context* ctx, NDBT_Step* step){ + int loops = ctx->getNumLoops(); + int records = ctx->getNumRecords(); + Ndb * pNdb = GETNDB(step); + const NdbDictionary::Table* pTab = ctx->getTab(); + + HugoCalculator calc(* pTab); + NDBT_ResultRow tmpRow(* pTab); + + int i = 0; + while (i<loops && !ctx->isTestStopped()) { + g_info << i++ << ": "; + const int record = (rand() % records); + g_info << " row=" << record; + + NdbConnection* pCon = pNdb->startTransaction(); + NdbScanOperation* pOp = pCon->getNdbScanOperation(pTab->getName()); + if (pOp == NULL) { + ERR(pCon->getNdbError()); + return NDBT_FAILED; + } + + NdbResultSet* rs = pOp->readTuples(); + if( rs == 0 ) { + ERR(pCon->getNdbError()); + return NDBT_FAILED; + } + + int check = pOp->interpret_exit_ok(); + if( check == -1 ) { + ERR(pCon->getNdbError()); + return NDBT_FAILED; + } + + // Define attributes to read + for(int a = 0; a<pTab->getNoOfColumns(); a++){ + if((tmpRow.attributeStore(a) = + pOp->getValue(pTab->getColumn(a)->getName())) == 0) { + ERR(pCon->getNdbError()); + return NDBT_FAILED; + } + } + + check = pCon->execute(NoCommit); + if( check == -1 ) { + ERR(pCon->getNdbError()); + return NDBT_FAILED; + } + + int res; + int row = 0; + while(row < record && (res = rs->nextResult()) == 0) { + if(calc.verifyRowValues(&tmpRow) != 0){ + abort(); + return NDBT_FAILED; + } + row++; + } + if(row != record){ + ERR(pCon->getNdbError()); + abort(); + return NDBT_FAILED; + } + g_info << " restarting" << endl; + if((res = rs->restart()) != 0){ + ERR(pCon->getNdbError()); + abort(); + return NDBT_FAILED; + } + + row = 0; + while((res = rs->nextResult()) == 0) { + if(calc.verifyRowValues(&tmpRow) != 0){ + abort(); + return NDBT_FAILED; + } + row++; + } + if(res != 1 || row != records){ + ERR(pCon->getNdbError()); + abort(); + return NDBT_FAILED; + } + pCon->close(); + } + return NDBT_OK; +} NDBT_TESTSUITE(testScan); @@ -1393,6 +1391,12 @@ TESTCASE("ScanReadWhileNodeIsDown", STEP(runStopAndStartNode); FINALIZER(runClearTable); } +TESTCASE("ScanRestart", + "Verify restart functionallity"){ + INITIALIZER(runLoadTable); + STEP(runScanRestart); + FINALIZER(runClearTable); +} NDBT_TESTSUITE_END(testScan); int main(int argc, const char** argv){ @@ -1400,3 +1404,4 @@ int main(int argc, const char** argv){ return testScan.execute(argc, argv); } +template class Vector<Attrib*>; diff --git a/ndb/test/ndbapi/testScanPerf/testScanPerf.cpp b/ndb/test/ndbapi/testScanPerf.cpp index 61af1ffb989..61af1ffb989 100644 --- a/ndb/test/ndbapi/testScanPerf/testScanPerf.cpp +++ b/ndb/test/ndbapi/testScanPerf.cpp diff --git a/ndb/test/ndbapi/testScanPerf/Makefile b/ndb/test/ndbapi/testScanPerf/Makefile deleted file mode 100644 index fdf5980b385..00000000000 --- a/ndb/test/ndbapi/testScanPerf/Makefile +++ /dev/null @@ -1,9 +0,0 @@ -include .defs.mk - -TYPE = ndbapitest - -BIN_TARGET = testScanPerf - -SOURCES = testScanPerf.cpp - -include $(NDB_TOP)/Epilogue.mk diff --git a/ndb/test/ndbapi/testTimeout.cpp b/ndb/test/ndbapi/testTimeout.cpp index 8a7866880b3..62e69125073 100644 --- a/ndb/test/ndbapi/testTimeout.cpp +++ b/ndb/test/ndbapi/testTimeout.cpp @@ -20,6 +20,44 @@ #include <UtilTransactions.hpp> #include <random.h> #include <NdbConfig.hpp> +#include <signaldata/DumpStateOrd.hpp> + +#define TIMEOUT 3000 + +Uint32 g_org_timeout = 3000; + +int +setTransactionTimeout(NDBT_Context* ctx, NDBT_Step* step){ + NdbRestarter restarter; + + NdbConfig conf(GETNDB(step)->getNodeId()+1); + unsigned int nodeId = conf.getMasterNodeId(); + if (!conf.getProperty(nodeId, + NODE_TYPE_DB, + CFG_DB_TRANSACTION_INACTIVE_TIMEOUT, + &g_org_timeout)){ + return NDBT_FAILED; + } + + int val[] = { DumpStateOrd::TcSetApplTransactionTimeout, TIMEOUT }; + if(restarter.dumpStateAllNodes(val, 2) != 0){ + return NDBT_FAILED; + } + + return NDBT_OK; +} + +int +resetTransactionTimeout(NDBT_Context* ctx, NDBT_Step* step){ + NdbRestarter restarter; + + int val[] = { DumpStateOrd::TcSetApplTransactionTimeout, g_org_timeout }; + if(restarter.dumpStateAllNodes(val, 2) != 0){ + return NDBT_FAILED; + } + + return NDBT_OK; +} int runLoadTable(NDBT_Context* ctx, NDBT_Step* step){ @@ -55,16 +93,10 @@ int runTimeoutTrans(NDBT_Context* ctx, NDBT_Step* step){ NdbConfig conf(GETNDB(step)->getNodeId()+1); unsigned int nodeId = conf.getMasterNodeId(); int stepNo = step->getStepNo(); - Uint32 timeoutVal; - if (!conf.getProperty(nodeId, - NODE_TYPE_DB, - CFG_DB_TRANSACTION_INACTIVE_TIMEOUT, - &timeoutVal)){ - return NDBT_FAILED; - } - int minSleep = (int)(timeoutVal * 1.5); - int maxSleep = timeoutVal * 2; - ndbout << "TransactionInactiveTimeout="<<timeoutVal + + int minSleep = (int)(TIMEOUT * 1.5); + int maxSleep = TIMEOUT * 2; + ndbout << "TransactionInactiveTimeout="<< TIMEOUT << ", minSleep="<<minSleep << ", maxSleep="<<maxSleep<<endl; @@ -89,7 +121,125 @@ int runTimeoutTrans(NDBT_Context* ctx, NDBT_Step* step){ } while(false); hugoOps.closeTransaction(pNdb); + } + + return result; +} + +int runTimeoutTrans2(NDBT_Context* ctx, NDBT_Step* step){ + int result = NDBT_OK; + int loops = ctx->getNumLoops(); + int stepNo = step->getStepNo(); + int mul1 = ctx->getProperty("Op1", (Uint32)0); + int mul2 = ctx->getProperty("Op2", (Uint32)0); + int records = ctx->getNumRecords(); + + int minSleep = (int)(TIMEOUT * 1.5); + int maxSleep = TIMEOUT * 2; + HugoOperations hugoOps(*ctx->getTab()); + Ndb* pNdb = GETNDB(step); + + for (int l = 0; l<loops && !ctx->isTestStopped() && result == NDBT_OK; l++){ + + int op1 = 0 + (l + stepNo) * mul1; + int op2 = 0 + (l + stepNo) * mul2; + + op1 = (op1 % 5); + op2 = (op2 % 5); + + ndbout << stepNo << ": TransactionInactiveTimeout="<< TIMEOUT + << ", minSleep="<<minSleep + << ", maxSleep="<<maxSleep + << ", op1=" << op1 + << ", op2=" << op2 << endl;; + + do{ + // Commit transaction + CHECK(hugoOps.startTransaction(pNdb) == 0); + + switch(op1){ + case 0: + break; + case 1: + if(hugoOps.pkReadRecord(pNdb, stepNo, true) != 0){ + g_err << stepNo << ": Fail" << __LINE__ << endl; + result = NDBT_FAILED; break; + } + break; + case 2: + if(hugoOps.pkUpdateRecord(pNdb, stepNo, true) != 0){ + g_err << stepNo << ": Fail" << __LINE__ << endl; + result = NDBT_FAILED; break; + } + break; + case 3: + if(hugoOps.pkDeleteRecord(pNdb, stepNo, true) != 0){ + g_err << stepNo << ": Fail" << __LINE__ << endl; + result = NDBT_FAILED; break; + } + break; + case 4: + if(hugoOps.pkInsertRecord(pNdb, stepNo+records+l, true) != 0){ + g_err << stepNo << ": Fail" << __LINE__ << endl; + result = NDBT_FAILED; break; + } + break; + } + + if(result != NDBT_OK) + break; + + int res = hugoOps.execute_NoCommit(pNdb); + if(res != 0){ + g_err << stepNo << ": Fail" << __LINE__ << endl; + result = NDBT_FAILED; break; + } + + int sleep = minSleep + myRandom48(maxSleep-minSleep); + ndbout << stepNo << ": Sleeping for "<< sleep << " milliseconds" << endl; + NdbSleep_MilliSleep(sleep); + + switch(op2){ + case 0: + break; + case 1: + if(hugoOps.pkReadRecord(pNdb, stepNo, true) != 0){ + g_err << stepNo << ": Fail" << __LINE__ << endl; + result = NDBT_FAILED; break; + } + break; + case 2: + if(hugoOps.pkUpdateRecord(pNdb, stepNo, true) != 0){ + g_err << stepNo << ": Fail" << __LINE__ << endl; + result = NDBT_FAILED; break; + } + break; + case 3: + if(hugoOps.pkDeleteRecord(pNdb, stepNo, true) != 0){ + g_err << stepNo << ": Fail" << __LINE__ << endl; + result = NDBT_FAILED; break; + } + break; + case 4: + if(hugoOps.pkInsertRecord(pNdb, stepNo+2*records+l, true) != 0){ + g_err << stepNo << ": Fail" << __LINE__ << endl; + result = NDBT_FAILED; break; + } + break; + } + + // Expect that transaction has timed-out + res = hugoOps.execute_Commit(pNdb); + if(op1 != 0 && res != 266){ + g_err << stepNo << ": Fail: " << res << "!= 237, op1=" + << op1 << ", op2=" << op2 << endl; + result = NDBT_FAILED; break; + } + + } while(false); + + hugoOps.closeTransaction(pNdb); } return result; @@ -98,18 +248,10 @@ int runTimeoutTrans(NDBT_Context* ctx, NDBT_Step* step){ int runDontTimeoutTrans(NDBT_Context* ctx, NDBT_Step* step){ int result = NDBT_OK; int loops = ctx->getNumLoops(); - NdbConfig conf(GETNDB(step)->getNodeId()+1); - unsigned int nodeId = conf.getMasterNodeId(); int stepNo = step->getStepNo(); - Uint32 timeoutVal; - if (!conf.getProperty(nodeId, - NODE_TYPE_DB, - CFG_DB_TRANSACTION_INACTIVE_TIMEOUT, - &timeoutVal)){ - return NDBT_FAILED; - } - int maxSleep = (int)(timeoutVal * 0.5); - ndbout << "TransactionInactiveTimeout="<<timeoutVal + + int maxSleep = (int)(TIMEOUT * 0.5); + ndbout << "TransactionInactiveTimeout="<< TIMEOUT << ", maxSleep="<<maxSleep<<endl; @@ -134,11 +276,8 @@ int runDontTimeoutTrans(NDBT_Context* ctx, NDBT_Step* step){ } while(false); hugoOps.closeTransaction(pNdb); - - } - return result; } @@ -146,18 +285,9 @@ int runBuddyTransNoTimeout(NDBT_Context* ctx, NDBT_Step* step){ int result = NDBT_OK; int loops = ctx->getNumLoops(); int records = ctx->getNumRecords(); - NdbConfig conf(GETNDB(step)->getNodeId()+1); - unsigned int nodeId = conf.getMasterNodeId(); int stepNo = step->getStepNo(); - Uint32 timeoutVal; - if (!conf.getProperty(nodeId, - NODE_TYPE_DB, - CFG_DB_TRANSACTION_INACTIVE_TIMEOUT, - &timeoutVal)){ - return NDBT_FAILED; - } - int maxSleep = (int)(timeoutVal * 0.3); - ndbout << "TransactionInactiveTimeout="<<timeoutVal + int maxSleep = (int)(TIMEOUT * 0.3); + ndbout << "TransactionInactiveTimeout="<< TIMEOUT << ", maxSleep="<<maxSleep<<endl; HugoOperations hugoOps(*ctx->getTab()); @@ -172,11 +302,11 @@ int runBuddyTransNoTimeout(NDBT_Context* ctx, NDBT_Step* step){ CHECK(hugoOps.pkInsertRecord(pNdb, recordNo, true) == 0); CHECK(hugoOps.execute_NoCommit(pNdb) == 0); - for (int i = 0; i < 10; i++){ + for (int i = 0; i < 3; i++){ // Perform buddy scan reads - CHECK(hugoOps.scanReadRecords(pNdb) == 0); - CHECK(hugoOps.executeScanRead(pNdb) == 0); - + CHECK((hugoOps.scanReadRecords(pNdb)) == 0); + CHECK(hugoOps.execute_NoCommit(pNdb) == 0); + int sleep = myRandom48(maxSleep); ndbout << "Sleeping for " << sleep << " milliseconds" << endl; NdbSleep_MilliSleep(sleep); @@ -188,10 +318,7 @@ int runBuddyTransNoTimeout(NDBT_Context* ctx, NDBT_Step* step){ } while(false); hugoOps.closeTransaction(pNdb); - - } - return result; } @@ -202,7 +329,9 @@ TESTCASE("DontTimeoutTransaction", "if we sleep during the transaction. Use a sleep "\ "value which is smaller than TransactionInactiveTimeout"){ INITIALIZER(runLoadTable); + INITIALIZER(setTransactionTimeout); STEPS(runDontTimeoutTrans, 1); + FINALIZER(resetTransactionTimeout); FINALIZER(runClearTable); } TESTCASE("DontTimeoutTransaction5", @@ -211,7 +340,9 @@ TESTCASE("DontTimeoutTransaction5", "value which is smaller than TransactionInactiveTimeout" \ "Five simultaneous threads"){ INITIALIZER(runLoadTable); + INITIALIZER(setTransactionTimeout); STEPS(runDontTimeoutTrans, 5); + FINALIZER(resetTransactionTimeout); FINALIZER(runClearTable); } TESTCASE("TimeoutTransaction", @@ -219,7 +350,9 @@ TESTCASE("TimeoutTransaction", "if we sleep during the transaction. Use a sleep "\ "value which is larger than TransactionInactiveTimeout"){ INITIALIZER(runLoadTable); + INITIALIZER(setTransactionTimeout); STEPS(runTimeoutTrans, 1); + FINALIZER(resetTransactionTimeout); FINALIZER(runClearTable); } TESTCASE("TimeoutTransaction5", @@ -228,7 +361,21 @@ TESTCASE("TimeoutTransaction5", "value which is larger than TransactionInactiveTimeout" \ "Five simultaneous threads"){ INITIALIZER(runLoadTable); + INITIALIZER(setTransactionTimeout); STEPS(runTimeoutTrans, 5); + FINALIZER(resetTransactionTimeout); + FINALIZER(runClearTable); +} +TESTCASE("TimeoutRandTransaction", + "Test that the transaction does timeout "\ + "if we sleep during the transaction. Use a sleep "\ + "value which is larger than TransactionInactiveTimeout"){ + INITIALIZER(runLoadTable); + INITIALIZER(setTransactionTimeout); + TC_PROPERTY("Op1", 7); + TC_PROPERTY("Op2", 11); + STEPS(runTimeoutTrans2, 5); + FINALIZER(resetTransactionTimeout); FINALIZER(runClearTable); } TESTCASE("BuddyTransNoTimeout", @@ -238,7 +385,9 @@ TESTCASE("BuddyTransNoTimeout", "The total sleep time is longer than TransactionInactiveTimeout" \ "Commit the first transaction, it should not have timed out."){ INITIALIZER(runLoadTable); + INITIALIZER(setTransactionTimeout); STEPS(runBuddyTransNoTimeout, 1); + FINALIZER(resetTransactionTimeout); FINALIZER(runClearTable); } TESTCASE("BuddyTransNoTimeout5", @@ -249,7 +398,9 @@ TESTCASE("BuddyTransNoTimeout5", "Commit the first transaction, it should not have timed out." \ "Five simultaneous threads"){ INITIALIZER(runLoadTable); + INITIALIZER(setTransactionTimeout); STEPS(runBuddyTransNoTimeout, 5); + FINALIZER(resetTransactionTimeout); FINALIZER(runClearTable); } NDBT_TESTSUITE_END(testTimeout); diff --git a/ndb/test/ndbapi/testTransactions.cpp b/ndb/test/ndbapi/testTransactions.cpp index 9ce928f8736..67a2df24390 100644 --- a/ndb/test/ndbapi/testTransactions.cpp +++ b/ndb/test/ndbapi/testTransactions.cpp @@ -102,7 +102,7 @@ OperationTestCase matrix[] = { { "ScanExInsert", true, "SCAN-EX",1, "INSERT", 266, X, 0, 1 }, { "ScanExUpdate", true, "SCAN-EX",1, "UPDATE", 266, 2, 0, 1 }, { "ScanExDelete", true, "SCAN-EX",1, "DELETE", 266, X, 0, 1 }, - { "ScanExScan", true, "SCAN-EX",1, "SCAN", 274, X, 0, 1 }, + { "ScanExScan", true, "SCAN-EX",1, "SCAN", 0, 1, 0, 1 }, { "ScanExScanHl", true, "SCAN-EX",1, "SCAN-HL", 274, X, 0, 1 }, { "ScanExScanEx", true, "SCAN-EX",1, "SCAN-EX", 274, X, 0, 1 }, #if 0 @@ -117,8 +117,8 @@ OperationTestCase matrix[] = { { "ReadExInsert", true, "READ-EX",1, "INSERT", 266, X, 0, 1 }, { "ReadExUpdate", true, "READ-EX",1, "UPDATE", 266, X, 0, 1 }, { "ReadExDelete", true, "READ-EX",1, "DELETE", 266, X, 0, 1 }, - { "ReadExScan", true, "READ-EX",1, "SCAN", 274, 1, 0, 1 }, - { "ReadExScanHl", true, "READ-EX",1, "SCAN-HL", 274, 1, 0, 1 }, + { "ReadExScan", true, "READ-EX",1, "SCAN", 0, 1, 0, 1 }, + { "ReadExScanHl", true, "READ-EX",1, "SCAN-HL", 274, X, 0, 1 }, { "ReadExScanEx", true, "READ-EX",1, "SCAN-EX", 274, X, 0, 1 }, #if 0 { "ReadExScanUp", true, "READ-EX",1, "SCAN-UP", 266, X, 0, 1 }, @@ -132,7 +132,7 @@ OperationTestCase matrix[] = { { "InsertInsert", false, "INSERT", 1, "INSERT", 266, X, 0, 1 }, { "InsertUpdate", false, "INSERT", 1, "UPDATE", 266, X, 0, 1 }, { "InsertDelete", false, "INSERT", 1, "DELETE", 266, X, 0, 1 }, - { "InsertScan", false, "INSERT", 1, "SCAN", 274, X, 0, 1 }, + { "InsertScan", false, "INSERT", 1, "SCAN", 626, X, 0, 1 }, { "InsertScanHl", false, "INSERT", 1, "SCAN-HL", 274, X, 0, 1 }, { "InsertScanEx", false, "INSERT", 1, "SCAN-EX", 274, X, 0, 1 }, #if 0 @@ -147,7 +147,7 @@ OperationTestCase matrix[] = { { "UpdateInsert", true, "UPDATE", 2, "INSERT", 266, X, 0, 2 }, { "UpdateUpdate", true, "UPDATE", 2, "UPDATE", 266, X, 0, 2 }, { "UpdateDelete", true, "UPDATE", 2, "DELETE", 266, X, 0, 2 }, - { "UpdateScan", true, "UPDATE", 2, "SCAN", 274, X, 0, 2 }, + { "UpdateScan", true, "UPDATE", 2, "SCAN", 0, 1, 0, 2 }, { "UpdateScanHl", true, "UPDATE", 2, "SCAN-HL", 274, X, 0, 2 }, { "UpdateScanEx", true, "UPDATE", 2, "SCAN-EX", 274, X, 0, 2 }, #if 0 @@ -162,7 +162,7 @@ OperationTestCase matrix[] = { { "DeleteInsert", true, "DELETE", X, "INSERT", 266, X, 626, X }, { "DeleteUpdate", true, "DELETE", X, "UPDATE", 266, X, 626, X }, { "DeleteDelete", true, "DELETE", X, "DELETE", 266, X, 626, X }, - { "DeleteScan", true, "DELETE", X, "SCAN", 274, X, 626, X }, + { "DeleteScan", true, "DELETE", X, "SCAN", 0, 1, 626, X }, { "DeleteScanHl", true, "DELETE", X, "SCAN-HL", 274, X, 626, X }, { "DeleteScanEx", true, "DELETE", X, "SCAN-EX", 274, X, 626, X }, #if 0 @@ -206,9 +206,9 @@ runOp(HugoOperations & hugoOps, } else if(strcmp(op, "SCAN") == 0){ C2(hugoOps.scanReadRecords(pNdb) == 0); } else if(strcmp(op, "SCAN-HL") == 0){ - C2(hugoOps.scanReadRecords(pNdb, 240, HugoOperations::SL_ReadHold) == 0); + C2(hugoOps.scanReadRecords(pNdb, NdbScanOperation::LM_Read)== 0); } else if(strcmp(op, "SCAN-EX") == 0){ - C2(hugoOps.scanReadRecords(pNdb, 240, HugoOperations::SL_Exclusive) == 0); + C2(hugoOps.scanReadRecords(pNdb, NdbScanOperation::LM_Exclusive)== 0); } else { g_err << __FILE__ << " - " << __LINE__ << ": Unknown operation" << op << endl; diff --git a/ndb/test/run-test/Makefile.am b/ndb/test/run-test/Makefile.am index 3dd9632ce4b..04be35325db 100644 --- a/ndb/test/run-test/Makefile.am +++ b/ndb/test/run-test/Makefile.am @@ -1,18 +1,18 @@ -ndbtest_PROGRAMS = atrt +testdir=$(prefix)/mysql-test/ndb -atrt_SOURCES = main.cpp +include $(top_srcdir)/ndb/config/common.mk.am +include $(top_srcdir)/ndb/config/type_util.mk.am +include $(top_srcdir)/ndb/config/type_mgmapiclient.mk.am -ndbtest_SCRIPTS = atrt-analyze-result.sh atrt-gather-result.sh atrt-setup.sh \ +test_PROGRAMS = atrt +test_DATA=daily-basic-tests.txt daily-devel-tests.txt +test_SCRIPTS=atrt-analyze-result.sh atrt-gather-result.sh atrt-setup.sh \ atrt-clear-result.sh make-config.sh make-index.sh make-html-reports.sh -EXTRA_DIST = $(ndbtest_SCRIPTS) +atrt_SOURCES = main.cpp INCLUDES_LOC = -I$(top_srcdir)/ndb/src/mgmclient LDADD_LOC = $(top_builddir)/ndb/src/mgmclient/CpcClient.o $(top_builddir)/ndb/src/libndbclient.la -include $(top_srcdir)/ndb/config/common.mk.am -include $(top_srcdir)/ndb/config/type_util.mk.am -include $(top_srcdir)/ndb/config/type_mgmapiclient.mk.am - # Don't update the files from bitkeeper %::SCCS/s.% diff --git a/ndb/test/run-test/daily-basic-tests.txt b/ndb/test/run-test/daily-basic-tests.txt new file mode 100644 index 00000000000..631378cb636 --- /dev/null +++ b/ndb/test/run-test/daily-basic-tests.txt @@ -0,0 +1,1008 @@ +# BASIC FUNCTIONALITY +max-time: 500 +cmd: testBasic +args: -n PkRead + +max-time: 500 +cmd: testBasic +args: -n PkUpdate + +max-time: 500 +cmd: testBasic +args: -n PkDelete + +max-time: 500 +cmd: testBasic +args: -n PkInsert + +max-time: 600 +cmd: testBasic +args: -n UpdateAndRead + +max-time: 500 +cmd: testBasic +args: -n PkReadAndLocker T6 + +max-time: 500 +cmd: testBasic +args: -n PkReadAndLocker2 T6 + +max-time: 500 +cmd: testBasic +args: -n PkReadUpdateAndLocker T6 + +max-time: 500 +cmd: testBasic +args: -n ReadWithLocksAndInserts T6 + +max-time: 500 +cmd: testBasic +args: -n PkInsertTwice T1 T6 T10 + +max-time: 1500 +cmd: testBasic +args: -n Fill T13 + +max-time: 1500 +cmd: testBasic +args: -n Fill T6 + +max-time: 500 +cmd: testBasic +args: -n NoCommitSleep T6 + +max-time: 500 +cmd: testBasic +args: -n NoCommit626 T6 + +max-time: 500 +cmd: testBasic +args: -n NoCommitAndClose T6 + +max-time: 500 +cmd: testBasic +args: -n Commit626 T6 + +max-time: 500 +cmd: testBasic +args: -n CommitTry626 T6 + +max-time: 500 +cmd: testBasic +args: -n CommitAsMuch626 T6 + +max-time: 500 +cmd: testBasic +args: -n NoCommit626 T6 + +max-time: 500 +cmd: testBasic +args: -n NoCommitRollback626 T1 T6 + +max-time: 500 +cmd: testBasic +args: -n Commit630 T1 T6 + +max-time: 500 +cmd: testBasic +args: -n CommitTry630 T1 T6 + +max-time: 500 +cmd: testBasic +args: -n CommitAsMuch630 T1 T6 + +max-time: 500 +cmd: testBasic +args: -n NoCommit630 T1 T6 + +max-time: 500 +cmd: testBasic +args: -n NoCommitRollback630 T1 T6 + +max-time: 500 +cmd: testBasic +args: -n NoCommitAndClose T1 T6 + +max-time: 500 +cmd: testBasic +args: -n RollbackUpdate T1 T6 + +max-time: 500 +cmd: testBasic +args: -n RollbackDeleteMultiple T1 T6 + +max-time: 500 +cmd: testBasic +args: -n ImplicitRollbackDelete T1 T6 + +max-time: 500 +cmd: testBasic +args: -n CommitDelete T1 T6 + +max-time: 500 +cmd: testBasic +args: -n RollbackNothing T1 T6 + +max-time: 500 +cmd: testBasicAsynch +args: -n PkInsertAsynch + +max-time: 500 +cmd: testBasicAsynch +args: -n PkReadAsynch + +max-time: 500 +cmd: testBasicAsynch +args: -n PkUpdateAsynch + +max-time: 500 +cmd: testBasicAsynch +args: -n PkDeleteAsynch + +max-time: 500 +cmd: testBasic +args: -n MassiveRollback T1 T6 T13 + +max-time: 500 +cmd: testBasic +args: -n MassiveRollback2 T1 T6 T13 + +#-m 500 1: testBasic -n ReadConsistency T6 +max-time: 500 +cmd: testTimeout +args: -n DontTimeoutTransaction T1 + +max-time: 500 +cmd: testTimeout +args: -n DontTimeoutTransaction5 T1 + +max-time: 500 +cmd: testTimeout +args: -n TimeoutTransaction T1 + +max-time: 500 +cmd: testTimeout +args: -n TimeoutTransaction5 T1 + +max-time: 500 +cmd: testTimeout +args: -n BuddyTransNoTimeout T1 + +max-time: 500 +cmd: testTimeout +args: -n BuddyTransNoTimeout5 T1 + +max-time: 500 +cmd: testTimeout +args: -n TimeoutRandTransaction T1 + +# SCAN TESTS +# +max-time: 500 +cmd: testScan +args: -n ScanRead16 + +max-time: 500 +cmd: testScan +args: -n ScanRead240 + +max-time: 500 +cmd: testScan +args: -n ScanReadCommitted240 + +max-time: 500 +cmd: testScan +args: -n ScanUpdate + +max-time: 500 +cmd: testScan +args: -n ScanUpdate2 T6 + +max-time: 500 +cmd: testScan +args: -n ScanDelete + +max-time: 500 +cmd: testScan +args: -n ScanDelete2 T10 + +max-time: 500 +cmd: testScan +args: -n ScanUpdateAndScanRead T6 + +max-time: 500 +cmd: testScan +args: -n ScanReadAndLocker T6 + +max-time: 500 +cmd: testScan +args: -n ScanReadAndPkRead T6 + +max-time: 500 +cmd: testScan +args: -n ScanRead488 -l 10 T6 + +max-time: 600 +cmd: testScan +args: -n ScanRead40 -l 100 T2 + +max-time: 1800 +cmd: testScan +args: -n ScanRead100 -l 100 T1 + +max-time: 600 +cmd: testScan +args: -n ScanRead40 -l 100 T1 + +max-time: 1800 +cmd: testScan +args: -n ScanRead40RandomTable -l 100 T1 + +max-time: 3600 +cmd: testScan +args: -n ScanRead40RandomTable -l 1000 T2 + +max-time: 500 +cmd: testScan +args: -n ScanWithLocksAndInserts T6 + +max-time: 500 +cmd: testScan +args: -n ScanReadAbort T6 + +max-time: 500 +cmd: testScan +args: -n ScanReadAbort15 T6 + +max-time: 500 +cmd: testScan +args: -n ScanReadAbort240 T6 + +max-time: 500 +cmd: testScan +args: -n ScanUpdateAbort16 T6 + +max-time: 3600 +cmd: testScan +args: -n ScanReadRestart T1 T6 T13 + +max-time: 500 +cmd: testScan +args: -n ScanUpdateRestart T6 + +max-time: 500 +cmd: testScan +args: -n CheckGetValue T6 + +max-time: 500 +cmd: testScan +args: -n CloseWithoutStop T6 + +max-time: 500 +cmd: testScan +args: -n NextScanWhenNoMore T6 + +max-time: 500 +cmd: testScan +args: -n ExecuteScanWithoutOpenScan T6 + +max-time: 500 +cmd: testScan +args: -n OnlyOpenScanOnce T6 + +max-time: 500 +cmd: testScan +args: -n OnlyOneOpInScanTrans T6 + +max-time: 500 +cmd: testScan +args: -n OnlyOneOpBeforeOpenScan T6 + +max-time: 500 +cmd: testScan +args: -n OnlyOneScanPerTrans T6 + +max-time: 500 +cmd: testScan +args: -n NoCloseTransaction T6 + +max-time: 500 +cmd: testScan +args: -n CheckInactivityTimeOut T6 + +max-time: 500 +cmd: testScan +args: -n CheckInactivityBeforeClose T6 + +max-time: 500 +cmd: testScan +args: -n CheckAfterTerror T6 + +max-time: 500 +cmd: testScan +args: -n ScanReadError5021 T1 + +max-time: 500 +cmd: testScan +args: -n ScanReaderror5022 T1 + +max-time: 500 +cmd: testScan +args: -n ScanReadError5023 T1 + +max-time: 500 +cmd: testScan +args: -n ScanReadError5024 T1 + +max-time: 500 +cmd: testScan +args: -n ScanReadError5025 T1 + +max-time: 500 +cmd: testScan +args: -n ScanReadError5030 T1 + +max-time: 500 +cmd: testScan +args: -n InsertDelete T1 T6 + +max-time: 500 +cmd: testScan +args: -n CheckAfterTerror T1 + +max-time: 500 +cmd: testScan +args: -n ScanReadWhileNodeIsDown T1 + +max-time: 500 +cmd: testScan +args: -n ScanRestart T1 + +# OLD FLEX +max-time: 500 +cmd: flexBench +args: -c 25 -t 10 + +max-time: 500 +cmd: flexHammer +args: -r 5 -t 32 + +# +# DICT TESTS +max-time: 1500 +cmd: testDict +args: -n CreateAndDrop + +max-time: 1500 +cmd: testDict +args: -n CreateAndDropWithData + +max-time: 1500 +cmd: testDict +args: -n CreateAndDropDuring T6 T10 + +max-time: 1500 +cmd: testDict +args: -n CreateInvalidTables + +max-time: 1500 +cmd: testDict +args: -n CreateTableWhenDbIsFull T6 + +max-time: 1500 +cmd: testDict +args: -n CreateMaxTables T6 + +max-time: 500 +cmd: testDict +args: -n FragmentTypeSingle T1 + +max-time: 1500 +cmd: testDict +args: -n FragmentTypeAll T1 T6 T7 T8 + +max-time: 1500 +cmd: testDict +args: -n FragmentTypeAllLarge T1 T6 T7 T8 + +max-time: 1500 +cmd: testDict +args: -n TemporaryTables T1 T6 T7 T8 + +# +# TEST NDBAPI +# +max-time: 500 +cmd: testDataBuffers +args: + +# Testsuite: testNdbApi +# Number of tests: 5 +max-time: 500 +cmd: testNdbApi +args: -n MaxNdb T6 + +max-time: 500 +cmd: testNdbApi +args: -n MaxTransactions T1 T6 T7 T8 T13 + +max-time: 500 +cmd: testNdbApi +args: -n MaxOperations T1 T6 T7 T8 T13 + +max-time: 500 +cmd: testNdbApi +args: -n MaxGetValue T1 T6 T7 T8 T13 + +max-time: 500 +cmd: testNdbApi +args: -n MaxEqual + +max-time: 500 +cmd: testNdbApi +args: -n DeleteNdb T1 T6 + +max-time: 500 +cmd: testNdbApi +args: -n WaitUntilReady T1 T6 T7 T8 T13 + +max-time: 500 +cmd: testNdbApi +args: -n GetOperationNoTab T6 + +max-time: 500 +cmd: testNdbApi +args: -n NdbErrorOperation T6 + +max-time: 500 +cmd: testNdbApi +args: -n MissingOperation T6 + +max-time: 500 +cmd: testNdbApi +args: -n GetValueInUpdate T6 + +max-time: 500 +cmd: testNdbApi +args: -n UpdateWithoutKeys T6 + +max-time: 500 +cmd: testNdbApi +args: -n UpdateWithoutValues T6 + +#max-time: 500 +#cmd: testInterpreter +#args: T1 +# +max-time: 1500 +cmd: testOperations +args: -n ReadRead + +max-time: 1500 +cmd: testOperations +args: -n ReadReadEx + +max-time: 1500 +cmd: testOperations +args: -n ReadInsert + +max-time: 1500 +cmd: testOperations +args: -n ReadUpdate + +max-time: 1500 +cmd: testOperations +args: -n ReadDelete + +max-time: 1500 +cmd: testOperations +args: -n FReadRead + +max-time: 1500 +cmd: testOperations +args: -n FReadReadEx + +max-time: 1500 +cmd: testOperations +args: -n FReadInsert + +max-time: 1500 +cmd: testOperations +args: -n FReadUpdate + +max-time: 1500 +cmd: testOperations +args: -n FReadDelete + +max-time: 1500 +cmd: testOperations +args: -n ReadExRead + +max-time: 1500 +cmd: testOperations +args: -n ReadExReadEx + +max-time: 1500 +cmd: testOperations +args: -n ReadExInsert + +max-time: 1500 +cmd: testOperations +args: -n ReadExUpdate + +max-time: 1500 +cmd: testOperations +args: -n ReadExDelete + +max-time: 1500 +cmd: testOperations +args: -n InsertRead + +max-time: 1500 +cmd: testOperations +args: -n InsertReadEx + +max-time: 1500 +cmd: testOperations +args: -n InsertInsert + +max-time: 1500 +cmd: testOperations +args: -n InsertUpdate + +max-time: 1500 +cmd: testOperations +args: -n InsertDelete + +max-time: 1500 +cmd: testOperations +args: -n UpdateRead + +max-time: 1500 +cmd: testOperations +args: -n UpdateReadEx + +max-time: 1500 +cmd: testOperations +args: -n UpdateInsert + +max-time: 1500 +cmd: testOperations +args: -n UpdateUpdate + +max-time: 1500 +cmd: testOperations +args: -n UpdateDelete + +max-time: 1500 +cmd: testOperations +args: -n DeleteRead + +max-time: 1500 +cmd: testOperations +args: -n DeleteReadEx + +max-time: 1500 +cmd: testOperations +args: -n DeleteInsert + +max-time: 1500 +cmd: testOperations +args: -n DeleteUpdate + +max-time: 1500 +cmd: testOperations +args: -n DeleteDelete + +max-time: 1500 +cmd: testOperations +args: -n ReadSimpleRead + +max-time: 1500 +cmd: testOperations +args: -n ReadDirtyRead + +max-time: 1500 +cmd: testOperations +args: -n FReadSimpleRead + +max-time: 1500 +cmd: testOperations +args: -n FReadDirtyRead + +max-time: 1500 +cmd: testOperations +args: -n ReadExSimpleRead + +max-time: 1500 +cmd: testOperations +args: -n ReadExDirtyRead + +max-time: 1500 +cmd: testOperations +args: -n InsertSimpleRead + +max-time: 1500 +cmd: testOperations +args: -n InsertDirtyRead + +max-time: 1500 +cmd: testOperations +args: -n UpdateSimpleRead + +max-time: 1500 +cmd: testOperations +args: -n UpdateDirtyRead + +max-time: 1500 +cmd: testOperations +args: -n DeleteSimpleRead + +max-time: 1500 +cmd: testOperations +args: -n DeleteDirtyRead + +max-time: 1500 +cmd: testTransactions +args: -n ReadRead + +max-time: 1500 +cmd: testTransactions +args: -n ReadReadEx + +max-time: 1500 +cmd: testTransactions +args: -n ReadInsert + +max-time: 1500 +cmd: testTransactions +args: -n ReadUpdate + +max-time: 1500 +cmd: testTransactions +args: -n ReadDelete + +max-time: 1500 +cmd: testTransactions +args: -n ReadExRead + +max-time: 1500 +cmd: testTransactions +args: -n ReadExReadEx + +max-time: 1500 +cmd: testTransactions +args: -n ReadExInsert + +max-time: 1500 +cmd: testTransactions +args: -n ReadExUpdate + +max-time: 1500 +cmd: testTransactions +args: -n ReadExDelete + +max-time: 1500 +cmd: testTransactions +args: -n InsertRead + +max-time: 1500 +cmd: testTransactions +args: -n InsertReadEx + +max-time: 1500 +cmd: testTransactions +args: -n InsertInsert + +max-time: 1500 +cmd: testTransactions +args: -n InsertUpdate + +max-time: 1500 +cmd: testTransactions +args: -n InsertDelete + +max-time: 1500 +cmd: testTransactions +args: -n UpdateRead + +max-time: 1500 +cmd: testTransactions +args: -n UpdateReadEx + +max-time: 1500 +cmd: testTransactions +args: -n UpdateInsert + +max-time: 1500 +cmd: testTransactions +args: -n UpdateUpdate + +max-time: 1500 +cmd: testTransactions +args: -n UpdateDelete + +max-time: 1500 +cmd: testTransactions +args: -n DeleteRead + +max-time: 1500 +cmd: testTransactions +args: -n DeleteReadEx + +max-time: 1500 +cmd: testTransactions +args: -n DeleteInsert + +max-time: 1500 +cmd: testTransactions +args: -n DeleteUpdate + +max-time: 1500 +cmd: testTransactions +args: -n DeleteDelete + +max-time: 1500 +cmd: testTransactions +args: -n ReadSimpleRead + +max-time: 1500 +cmd: testTransactions +args: -n ReadDirtyRead + +max-time: 1500 +cmd: testTransactions +args: -n ReadExSimpleRead + +max-time: 1500 +cmd: testTransactions +args: -n ReadExDirtyRead + +max-time: 1500 +cmd: testTransactions +args: -n InsertSimpleRead + +max-time: 1500 +cmd: testTransactions +args: -n InsertDirtyRead + +max-time: 1500 +cmd: testTransactions +args: -n UpdateSimpleRead + +max-time: 1500 +cmd: testTransactions +args: -n UpdateDirtyRead + +max-time: 1500 +cmd: testTransactions +args: -n DeleteSimpleRead + +max-time: 1500 +cmd: testTransactions +args: -n DeleteDirtyRead + +max-time: 1500 +cmd: testTransactions +args: -n ReadScan + +max-time: 1500 +cmd: testTransactions +args: -n ReadScanHl + +max-time: 1500 +cmd: testTransactions +args: -n ReadScanEx + +max-time: 1500 +cmd: testTransactions +args: -n ScanRead + +max-time: 1500 +cmd: testTransactions +args: -n ScanReadEx + +max-time: 1500 +cmd: testTransactions +args: -n ScanSimpleRead + +max-time: 1500 +cmd: testTransactions +args: -n ScanDirtyRead + +max-time: 1500 +cmd: testTransactions +args: -n ScanInsert + +max-time: 1500 +cmd: testTransactions +args: -n ScanUpdate + +max-time: 1500 +cmd: testTransactions +args: -n ScanDelete + +max-time: 1500 +cmd: testTransactions +args: -n ScanScan + +max-time: 1500 +cmd: testTransactions +args: -n ScanScanHl + +max-time: 1500 +cmd: testTransactions +args: -n ScanScanEx + +max-time: 1500 +cmd: testTransactions +args: -n ScanHlRead + +max-time: 1500 +cmd: testTransactions +args: -n ScanHlReadEx + +max-time: 1500 +cmd: testTransactions +args: -n ScanHlSimpleRead + +max-time: 1500 +cmd: testTransactions +args: -n ScanHlDirtyRead + +max-time: 1500 +cmd: testTransactions +args: -n ScanHlInsert + +max-time: 1500 +cmd: testTransactions +args: -n ScanHlUpdate + +max-time: 1500 +cmd: testTransactions +args: -n ScanHlDelete + +max-time: 1500 +cmd: testTransactions +args: -n ScanHlScan + +max-time: 1500 +cmd: testTransactions +args: -n ScanHlScanHl + +max-time: 1500 +cmd: testTransactions +args: -n ScanHlScanEx + +max-time: 1500 +cmd: testTransactions +args: -n ScanExRead + +max-time: 1500 +cmd: testTransactions +args: -n ScanExReadEx + +max-time: 1500 +cmd: testTransactions +args: -n ScanExSimpleRead + +max-time: 1500 +cmd: testTransactions +args: -n ScanExDirtyRead + +max-time: 1500 +cmd: testTransactions +args: -n ScanExInsert + +max-time: 1500 +cmd: testTransactions +args: -n ScanExUpdate + +max-time: 1500 +cmd: testTransactions +args: -n ScanExDelete + +max-time: 1500 +cmd: testTransactions +args: -n ScanExScan + +max-time: 1500 +cmd: testTransactions +args: -n ScanExScanHl + +max-time: 1500 +cmd: testTransactions +args: -n ScanExScanEx + +max-time: 1500 +cmd: testTransactions +args: -n ReadExScan + +max-time: 1500 +cmd: testTransactions +args: -n ReadExScanHl + +max-time: 1500 +cmd: testTransactions +args: -n ReadExScanEx + +max-time: 1500 +cmd: testTransactions +args: -n InsertScan + +max-time: 1500 +cmd: testTransactions +args: -n InsertScanHl + +max-time: 1500 +cmd: testTransactions +args: -n InsertScanEx + +max-time: 1500 +cmd: testTransactions +args: -n UpdateScan + +max-time: 1500 +cmd: testTransactions +args: -n UpdateScanHl + +max-time: 1500 +cmd: testTransactions +args: -n UpdateScanEx + +max-time: 1500 +cmd: testTransactions +args: -n DeleteScan + +max-time: 1500 +cmd: testTransactions +args: -n DeleteScanHl + +max-time: 1500 +cmd: testTransactions +args: -n DeleteScanEx + +max-time: 1500 +cmd: testRestartGci +args: T6 + +max-time: 600 +cmd: testBlobs +args: + +max-time: 2500 +cmd: testOIBasic +args: + +# +# +# SYSTEM RESTARTS +# +max-time: 1500 +cmd: testSystemRestart +args: -n SR1 T1 + +max-time: 1500 +cmd: testSystemRestart +args: -n SR1 T6 + +max-time: 1500 +cmd: testSystemRestart +args: -n SR1 T7 + +max-time: 1500 +cmd: testSystemRestart +args: -n SR1 T8 + +max-time: 1500 +cmd: testSystemRestart +args: -n SR2 T1 + +max-time: 1500 +cmd: testSystemRestart +args: -n SR2 T6 + +max-time: 1500 +cmd: testSystemRestart +args: -n SR2 T7 + diff --git a/ndb/test/run-test/daily-devel-tests.txt b/ndb/test/run-test/daily-devel-tests.txt new file mode 100644 index 00000000000..15fa4db4abc --- /dev/null +++ b/ndb/test/run-test/daily-devel-tests.txt @@ -0,0 +1,204 @@ +# +# INDEX +# +max-time: 1500 +cmd: testIndex +args: -n CreateAll T1 T6 T13 + +#-m 7200 1: testIndex -n InsertDeleteGentle T7 +max-time: 3600 +cmd: testIndex +args: -n InsertDelete T1 T10 + +#-m 3600 1: testIndex -n CreateLoadDropGentle T7 +max-time: 3600 +cmd: testIndex +args: -n CreateLoadDrop T1 T10 + +# +# BACKUP +# +max-time: 600 +cmd: testBackup +args: -n BackupOne T1 T6 T3 I3 + +#max-time: 600 +#cmd: testBackup +#args: -n BackupBank T6 +# +# +# MGMAPI AND MGSRV +# +max-time: 1800 +cmd: testMgm +args: -n SingleUserMode T1 + +# +# +# SYSTEM RESTARTS +# +max-time: 1500 +cmd: testSystemRestart +args: -n SR_UNDO T1 + +max-time: 1500 +cmd: testSystemRestart +args: -n SR_UNDO T6 + +max-time: 1500 +cmd: testSystemRestart +args: -n SR_UNDO T7 + +max-time: 1500 +cmd: testSystemRestart +args: -n SR_UNDO T8 + +max-time: 1500 +cmd: testSystemRestart +args: -n SR3 T6 + +max-time: 1500 +cmd: testSystemRestart +args: -n SR4 T6 + +# +max-time: 1500 +cmd: testSystemRestart +args: -n SR_FULLDB T1 + +# +# NODE RESTARTS +# +max-time: 2500 +cmd: testNodeRestart +args: -n NoLoad T6 T8 T13 + +max-time: 2500 +cmd: testNodeRestart +args: -n PkRead T6 T8 T13 + +max-time: 2500 +cmd: testNodeRestart +args: -l 1 -n PkReadPkUpdate + +max-time: 2500 +cmd: testNodeRestart +args: -l 1 -n ReadUpdateScan + +max-time: 2500 +cmd: testNodeRestart +args: -n Terror T6 T13 + +max-time: 2500 +cmd: testNodeRestart +args: -n FullDb T6 T13 + +max-time: 2500 +cmd: testNodeRestart +args: -n RestartRandomNode T6 T13 + +max-time: 2500 +cmd: testNodeRestart +args: -n RestartRandomNodeError T6 T13 + +max-time: 2500 +cmd: testNodeRestart +args: -n RestartRandomNodeInitial T6 T13 + +max-time: 3600 +cmd: testNodeRestart +args: -l 1 -n RestartNFDuringNR T6 T13 + +max-time: 2500 +cmd: testNodeRestart +args: -n RestartMasterNodeError T6 T8 T13 + +max-time: 3600 +cmd: testNodeRestart +args: -n RestartNodeDuringLCP T6 + +max-time: 2500 +cmd: testNodeRestart +args: -n TwoNodeFailure T6 T8 T13 + +max-time: 2500 +cmd: testNodeRestart +args: -n TwoMasterNodeFailure T6 T8 T13 + +max-time: 2500 +cmd: testNodeRestart +args: -n FiftyPercentFail T6 T8 T13 + +max-time: 2500 +cmd: testNodeRestart +args: -n RestartAllNodes T6 T8 T13 + +max-time: 2500 +cmd: testNodeRestart +args: -n RestartAllNodesAbort T6 T8 T13 + +max-time: 2500 +cmd: testNodeRestart +args: -n RestartAllNodesError9999 T6 T8 T13 + +max-time: 2500 +cmd: testNodeRestart +args: -n FiftyPercentStopAndWait T6 T8 T13 + +#max-time: 500 +#cmd: testNodeRestart +#args: -n StopOnError T1 +# +# +max-time: 2500 +cmd: testIndex +args: -n NFNR1 T6 T13 + +max-time: 2500 +cmd: testIndex +args: -n NFNR2 T6 T13 + +max-time: 2500 +cmd: testIndex +args: -n NFNR3 T6 T13 + +max-time: 2500 +cmd: testIndex +args: -n BuildDuring T6 + +max-time: 2500 +cmd: testIndex +args: -l 2 -n SR1 T6 T13 + +max-time: 2500 +cmd: testIndex +args: -n NFNR1_O T6 T13 + +max-time: 2500 +cmd: testIndex +args: -n NFNR2_O T6 T13 + +max-time: 2500 +cmd: testIndex +args: -n NFNR3_O T6 T13 + +max-time: 2500 +cmd: testIndex +args: -n BuildDuring_O T6 + +max-time: 2500 +cmd: testIndex +args: -l 2 -n SR1_O T6 T13 + +max-time: 500 +cmd: testIndex +args: -n MixedTransaction T1 + +max-time: 2500 +cmd: testDict +args: -n NF1 T1 T6 T13 + +max-time: 2500 +cmd: test_event +args: -n BasicEventOperation T1 T6 + diff --git a/ndb/test/run-test/main.cpp b/ndb/test/run-test/main.cpp index 9e318b0219e..6f1899fdbe2 100644 --- a/ndb/test/run-test/main.cpp +++ b/ndb/test/run-test/main.cpp @@ -106,13 +106,6 @@ main(int argc, const char ** argv){ if(!setup_hosts(g_config)) goto end; - if(!start_processes(g_config, atrt_process::NDB_MGM)) - goto end; - - if(!connect_ndb_mgm(g_config)){ - goto end; - } - /** * Main loop */ @@ -122,25 +115,32 @@ main(int argc, const char ** argv){ */ if(restart){ g_logger.info("(Re)starting ndb processes"); + if(!stop_processes(g_config, atrt_process::NDB_MGM)) + goto end; + if(!stop_processes(g_config, atrt_process::NDB_DB)) goto end; - if(!wait_ndb(g_config, NDB_MGM_NODE_STATUS_NO_CONTACT)) + if(!start_processes(g_config, atrt_process::NDB_MGM)) goto end; + if(!connect_ndb_mgm(g_config)){ + goto end; + } + if(!start_processes(g_config, atrt_process::NDB_DB)) goto end; - + if(!wait_ndb(g_config, NDB_MGM_NODE_STATUS_NOT_STARTED)) goto end; - + for(Uint32 i = 0; i<3; i++) if(wait_ndb(g_config, NDB_MGM_NODE_STATUS_STARTED)) goto started; - + goto end; - -started: + + started: g_logger.info("Ndb start completed"); } @@ -211,7 +211,7 @@ started: (result == 0 ? "OK" : "FAILED"), result); if(g_report_file != 0){ - fprintf(g_report_file, "%s %s ; %d ; %d ; %d\n", + fprintf(g_report_file, "%s %s ; %d ; %d ; %ld\n", test_case.m_command.c_str(), test_case.m_args.c_str(), test_no, result, elapsed); @@ -447,7 +447,6 @@ setup_config(atrt_config& config){ proc.m_proc.m_owner = "atrt"; proc.m_proc.m_group = "group"; proc.m_proc.m_cwd.assign(dir).append("/run/"); - proc.m_proc.m_env.assfmt("LD_LIBRARY_PATH=%s/lib/mysql", dir.c_str()); proc.m_proc.m_stdout = "log.out"; proc.m_proc.m_stderr = "2>&1"; proc.m_proc.m_runas = proc.m_host->m_user; @@ -460,7 +459,7 @@ setup_config(atrt_config& config){ proc.m_proc.m_path.assign(dir).append("/libexec/ndb_mgmd"); proc.m_proc.m_args = "-n -c initconfig.txt"; proc.m_proc.m_cwd.appfmt("%d.ndb_mgmd", index); - connect_string.appfmt(";host=%s:%d", + connect_string.appfmt("host=%s:%d;", proc.m_hostname.c_str(), proc.m_ndb_mgm_port); } else if(split1[0] == "ndb"){ proc.m_type = atrt_process::NDB_DB; @@ -502,10 +501,10 @@ setup_config(atrt_config& config){ // Setup connect string for(size_t i = 0; i<config.m_processes.size(); i++){ - config.m_processes[i].m_proc.m_env.appfmt(" NDB_CONNECTSTRING=nodeid=%d%s", - i+1, connect_string.c_str()); + config.m_processes[i].m_proc.m_env.assfmt("NDB_CONNECTSTRING=%s", + connect_string.c_str()); } - + end: fclose(f); return result; @@ -615,11 +614,22 @@ wait_ndb(atrt_config& config, int goal){ /** * 1) retreive current state */ - state = ndb_mgm_get_status(handle); - if(state == 0){ - g_logger.critical("Unable to poll db state"); - return false; - } + state = 0; + do { + state = ndb_mgm_get_status(handle); + if(state == 0){ + const int err = ndb_mgm_get_latest_error(handle); + g_logger.error("Unable to poll db state: %d %s %s", + ndb_mgm_get_latest_error(handle), + ndb_mgm_get_latest_error_msg(handle), + ndb_mgm_get_latest_error_desc(handle)); + if(err == NDB_MGM_SERVER_NOT_CONNECTED && connect_ndb_mgm(config)){ + g_logger.error("Reconnected..."); + continue; + } + return false; + } + } while(state == 0); NdbAutoPtr<void> tmp(state); min2 = goal; @@ -791,6 +801,10 @@ update_status(atrt_config& config, int){ proc.m_proc.m_id, proc.m_hostname.c_str(), proc.m_proc.m_path.c_str()); + for(size_t j = 0; j<h_procs.size(); j++){ + g_logger.error("found: %d %s", h_procs[j].m_id, + h_procs[j].m_path.c_str()); + } return false; } } @@ -924,9 +938,11 @@ gather_result(atrt_config& config, int * result){ BaseString tmp = g_gather_progname; for(size_t i = 0; i<config.m_processes.size(); i++){ atrt_process & proc = config.m_processes[i]; - tmp.appfmt(" %s:%s", - proc.m_hostname.c_str(), - proc.m_proc.m_cwd.c_str()); + if(proc.m_proc.m_path != ""){ + tmp.appfmt(" %s:%s", + proc.m_hostname.c_str(), + proc.m_proc.m_cwd.c_str()); + } } const int r1 = system(tmp.c_str()); @@ -970,3 +986,7 @@ setup_hosts(atrt_config& config){ } return true; } + +template class Vector<Vector<SimpleCpcClient::Process> >; +template class Vector<atrt_host>; +template class Vector<atrt_process>; diff --git a/ndb/test/src/HugoAsynchTransactions.cpp b/ndb/test/src/HugoAsynchTransactions.cpp index 2af22b5f48d..f75293f5a14 100644 --- a/ndb/test/src/HugoAsynchTransactions.cpp +++ b/ndb/test/src/HugoAsynchTransactions.cpp @@ -165,12 +165,13 @@ HugoAsynchTransactions::pkUpdateRecordsAsynch(Ndb* pNdb, allocRows(trans*operations); allocTransactions(trans); + int a, t, r; for (int i = 0; i < batch; i++) { // For each batch while (cRecords < records*batch) { cTrans = 0; cReadIndex = 0; - for (int t = 0; t < trans; t++) { // For each transaction + for (t = 0; t < trans; t++) { // For each transaction transactions[t] = pNdb->startTransaction(); if (transactions[t] == NULL) { ERR(pNdb->getNdbError()); @@ -187,7 +188,7 @@ HugoAsynchTransactions::pkUpdateRecordsAsynch(Ndb* pNdb, // Read // Define primary keys check = pOp->readTupleExclusive(); - for (int a = 0; a < tab.getNoOfColumns(); a++) { + for (a = 0; a < tab.getNoOfColumns(); a++) { if (tab.getColumn(a)->getPrimaryKey() == true) { if (equalForAttr(pOp, a, cReadRecords) != 0){ ERR(transactions[t]->getNdbError()); @@ -197,7 +198,7 @@ HugoAsynchTransactions::pkUpdateRecordsAsynch(Ndb* pNdb, } } // Define attributes to read - for (int a = 0; a < tab.getNoOfColumns(); a++) { + for (a = 0; a < tab.getNoOfColumns(); a++) { if ((rows[cReadIndex]->attributeStore(a) = pOp->getValue(tab.getColumn(a)->getName())) == 0) { ERR(transactions[t]->getNdbError()); @@ -225,7 +226,7 @@ HugoAsynchTransactions::pkUpdateRecordsAsynch(Ndb* pNdb, pNdb->sendPollNdb(3000, 0, 0); // Verify the data! - for (int r = 0; r < trans*operations; r++) { + for (r = 0; r < trans*operations; r++) { if (calc.verifyRowValues(rows[r]) != 0) { g_info << "|- Verify failed..." << endl; // Close all transactions @@ -239,7 +240,7 @@ HugoAsynchTransactions::pkUpdateRecordsAsynch(Ndb* pNdb, // Update cTrans = 0; cIndex = 0; - for (int t = 0; t < trans; t++) { // For each transaction + for (t = 0; t < trans; t++) { // For each transaction for (int k = 0; k < operations; k++) { // For each operation NdbOperation* pOp = transactions[t]->getNdbOperation(tab.getName()); if (pOp == NULL) { @@ -258,7 +259,7 @@ HugoAsynchTransactions::pkUpdateRecordsAsynch(Ndb* pNdb, } // Set search condition for the record - for (int a = 0; a < tab.getNoOfColumns(); a++) { + for (a = 0; a < tab.getNoOfColumns(); a++) { if (tab.getColumn(a)->getPrimaryKey() == true) { if (equalForAttr(pOp, a, cRecords) != 0) { ERR(transactions[t]->getNdbError()); @@ -269,7 +270,7 @@ HugoAsynchTransactions::pkUpdateRecordsAsynch(Ndb* pNdb, } // Update the record - for (int a = 0; a < tab.getNoOfColumns(); a++) { + for (a = 0; a < tab.getNoOfColumns(); a++) { if (tab.getColumn(a)->getPrimaryKey() == false) { if (setValueForAttr(pOp, a, cRecords, updates) != 0) { ERR(transactions[t]->getNdbError()); @@ -298,7 +299,7 @@ HugoAsynchTransactions::pkUpdateRecordsAsynch(Ndb* pNdb, pNdb->sendPollNdb(3000, 0, 0); // Close all transactions - for (int t = 0; t < cTrans; t++) { + for (t = 0; t < cTrans; t++) { pNdb->closeTransaction(transactions[t]); } @@ -346,6 +347,7 @@ HugoAsynchTransactions::executeAsynchOperation(Ndb* pNdb, int cTrans = 0; int cRecords = 0; int cIndex = 0; + int a,t,r; transactionsCompleted = 0; allocTransactions(trans); @@ -354,7 +356,7 @@ HugoAsynchTransactions::executeAsynchOperation(Ndb* pNdb, while (cRecords < records*batch) { cTrans = 0; cIndex = 0; - for (int t = 0; t < trans; t++) { // For each transaction + for (t = 0; t < trans; t++) { // For each transaction transactions[t] = pNdb->startTransaction(); if (transactions[t] == NULL) { ERR(pNdb->getNdbError()); @@ -379,7 +381,7 @@ HugoAsynchTransactions::executeAsynchOperation(Ndb* pNdb, } // Set a calculated value for each attribute in this table - for (int a = 0; a < tab.getNoOfColumns(); a++) { + for (a = 0; a < tab.getNoOfColumns(); a++) { if (setValueForAttr(pOp, a, cRecords, 0 ) != 0) { ERR(transactions[t]->getNdbError()); pNdb->closeTransaction(transactions[t]); @@ -394,7 +396,7 @@ HugoAsynchTransactions::executeAsynchOperation(Ndb* pNdb, case NO_READ: // Define primary keys check = pOp->readTuple(); - for (int a = 0; a < tab.getNoOfColumns(); a++) { + for (a = 0; a < tab.getNoOfColumns(); a++) { if (tab.getColumn(a)->getPrimaryKey() == true) { if (equalForAttr(pOp, a, cRecords) != 0){ ERR(transactions[t]->getNdbError()); @@ -404,7 +406,7 @@ HugoAsynchTransactions::executeAsynchOperation(Ndb* pNdb, } } // Define attributes to read - for (int a = 0; a < tab.getNoOfColumns(); a++) { + for (a = 0; a < tab.getNoOfColumns(); a++) { if ((rows[cIndex]->attributeStore(a) = pOp->getValue(tab.getColumn(a)->getName())) == 0) { ERR(transactions[t]->getNdbError()); @@ -423,7 +425,7 @@ HugoAsynchTransactions::executeAsynchOperation(Ndb* pNdb, } // Define primary keys - for (int a = 0; a < tab.getNoOfColumns(); a++) { + for (a = 0; a < tab.getNoOfColumns(); a++) { if (tab.getColumn(a)->getPrimaryKey() == true){ if (equalForAttr(pOp, a, cRecords) != 0) { ERR(transactions[t]->getNdbError()); @@ -462,7 +464,7 @@ HugoAsynchTransactions::executeAsynchOperation(Ndb* pNdb, switch (theOperation) { case NO_READ: // Verify the data! - for (int r = 0; r < trans*operations; r++) { + for (r = 0; r < trans*operations; r++) { if (calc.verifyRowValues(rows[r]) != 0) { g_info << "|- Verify failed..." << endl; // Close all transactions @@ -476,11 +478,11 @@ HugoAsynchTransactions::executeAsynchOperation(Ndb* pNdb, case NO_INSERT: case NO_UPDATE: case NO_DELETE: - abort(); + break; } // Close all transactions - for (int t = 0; t < cTrans; t++) { + for (t = 0; t < cTrans; t++) { pNdb->closeTransaction(transactions[t]); } diff --git a/ndb/test/src/HugoCalculator.cpp b/ndb/test/src/HugoCalculator.cpp index 55aa96a4909..147c8b104d8 100644 --- a/ndb/test/src/HugoCalculator.cpp +++ b/ndb/test/src/HugoCalculator.cpp @@ -28,7 +28,8 @@ HugoCalculator::HugoCalculator(const NdbDictionary::Table& tab) : m_tab(tab) { // The "id" column of this table is found in the first integer column - for (int i=0; i<m_tab.getNoOfColumns(); i++){ + int i; + for (i=0; i<m_tab.getNoOfColumns(); i++){ const NdbDictionary::Column* attr = m_tab.getColumn(i); if (attr->getType() == NdbDictionary::Column::Unsigned){ m_idCol = i; @@ -37,7 +38,7 @@ HugoCalculator::HugoCalculator(const NdbDictionary::Table& tab) : m_tab(tab) { } // The "number of updates" column for this table is found in the last column - for (int i=m_tab.getNoOfColumns()-1; i>=0; i--){ + for (i=m_tab.getNoOfColumns()-1; i>=0; i--){ const NdbDictionary::Column* attr = m_tab.getColumn(i); if (attr->getType() == NdbDictionary::Column::Unsigned){ m_updatesCol = i; @@ -102,7 +103,8 @@ HugoCalculator::calcValue(int record, // Fill buf with some pattern so that we can detect // anomalies in the area that we don't fill with chars - for (int i = 0; i<attr->getLength(); i++) + int i; + for (i = 0; i<attr->getLength(); i++) buf[i] = ((i+2) % 255); // Calculate length of the string to create. We want the string @@ -116,7 +118,7 @@ HugoCalculator::calcValue(int record, else len++; } - for(int i=0; i < len; i++) + for(i=0; i < len; i++) buf[i] = a[((val^i)%25)]; buf[len] = 0; } diff --git a/ndb/test/src/HugoOperations.cpp b/ndb/test/src/HugoOperations.cpp index 91263aa29b4..7c05cb86a93 100644 --- a/ndb/test/src/HugoOperations.cpp +++ b/ndb/test/src/HugoOperations.cpp @@ -40,6 +40,9 @@ int HugoOperations::closeTransaction(Ndb* pNdb){ } pTrans = NULL; + m_result_sets.clear(); + m_executed_result_sets.clear(); + return NDBT_OK; } @@ -51,7 +54,7 @@ int HugoOperations::pkReadRecord(Ndb* pNdb, int recordNo, bool exclusive, int numRecords){ - + int a; allocRows(numRecords); int check; for(int r=0; r < numRecords; r++){ @@ -71,7 +74,7 @@ int HugoOperations::pkReadRecord(Ndb* pNdb, } // Define primary keys - for(int a = 0; a<tab.getNoOfColumns(); a++){ + for(a = 0; a<tab.getNoOfColumns(); a++){ if (tab.getColumn(a)->getPrimaryKey() == true){ if(equalForAttr(pOp, a, r+recordNo) != 0){ ERR(pTrans->getNdbError()); @@ -81,7 +84,7 @@ int HugoOperations::pkReadRecord(Ndb* pNdb, } // Define attributes to read - for(int a = 0; a<tab.getNoOfColumns(); a++){ + for(a = 0; a<tab.getNoOfColumns(); a++){ if((rows[r]->attributeStore(a) = pOp->getValue(tab.getColumn(a)->getName())) == 0) { ERR(pTrans->getNdbError()); @@ -95,7 +98,7 @@ int HugoOperations::pkReadRecord(Ndb* pNdb, int HugoOperations::pkDirtyReadRecord(Ndb* pNdb, int recordNo, int numRecords){ - + int a; allocRows(numRecords); int check; for(int r=0; r < numRecords; r++){ @@ -113,7 +116,7 @@ int HugoOperations::pkDirtyReadRecord(Ndb* pNdb, } // Define primary keys - for(int a = 0; a<tab.getNoOfColumns(); a++){ + for(a = 0; a<tab.getNoOfColumns(); a++){ if (tab.getColumn(a)->getPrimaryKey() == true){ if(equalForAttr(pOp, a, r+recordNo) != 0){ ERR(pTrans->getNdbError()); @@ -123,7 +126,7 @@ int HugoOperations::pkDirtyReadRecord(Ndb* pNdb, } // Define attributes to read - for(int a = 0; a<tab.getNoOfColumns(); a++){ + for(a = 0; a<tab.getNoOfColumns(); a++){ if((rows[r]->attributeStore(a) = pOp->getValue(tab.getColumn(a)->getName())) == 0) { ERR(pTrans->getNdbError()); @@ -137,7 +140,7 @@ int HugoOperations::pkDirtyReadRecord(Ndb* pNdb, int HugoOperations::pkSimpleReadRecord(Ndb* pNdb, int recordNo, int numRecords){ - + int a; allocRows(numRecords); int check; for(int r=0; r < numRecords; r++){ @@ -155,7 +158,7 @@ int HugoOperations::pkSimpleReadRecord(Ndb* pNdb, } // Define primary keys - for(int a = 0; a<tab.getNoOfColumns(); a++){ + for(a = 0; a<tab.getNoOfColumns(); a++){ if (tab.getColumn(a)->getPrimaryKey() == true){ if(equalForAttr(pOp, a, r+recordNo) != 0){ ERR(pTrans->getNdbError()); @@ -165,7 +168,7 @@ int HugoOperations::pkSimpleReadRecord(Ndb* pNdb, } // Define attributes to read - for(int a = 0; a<tab.getNoOfColumns(); a++){ + for(a = 0; a<tab.getNoOfColumns(); a++){ if((rows[r]->attributeStore(a) = pOp->getValue(tab.getColumn(a)->getName())) == 0) { ERR(pTrans->getNdbError()); @@ -180,7 +183,7 @@ int HugoOperations::pkUpdateRecord(Ndb* pNdb, int recordNo, int numRecords, int updatesValue){ - + int a; allocRows(numRecords); int check; for(int r=0; r < numRecords; r++){ @@ -197,7 +200,7 @@ int HugoOperations::pkUpdateRecord(Ndb* pNdb, } // Define primary keys - for(int a = 0; a<tab.getNoOfColumns(); a++){ + for(a = 0; a<tab.getNoOfColumns(); a++){ if (tab.getColumn(a)->getPrimaryKey() == true){ if(equalForAttr(pOp, a, r+recordNo) != 0){ ERR(pTrans->getNdbError()); @@ -207,7 +210,7 @@ int HugoOperations::pkUpdateRecord(Ndb* pNdb, } // Define attributes to update - for(int a = 0; a<tab.getNoOfColumns(); a++){ + for(a = 0; a<tab.getNoOfColumns(); a++){ if (tab.getColumn(a)->getPrimaryKey() == false){ if(setValueForAttr(pOp, a, recordNo+r, updatesValue ) != 0){ ERR(pTrans->getNdbError()); @@ -224,7 +227,7 @@ int HugoOperations::pkInsertRecord(Ndb* pNdb, int numRecords, int updatesValue){ - int check; + int a, check; for(int r=0; r < numRecords; r++){ NdbOperation* pOp = pTrans->getNdbOperation(tab.getName()); if (pOp == NULL) { @@ -239,7 +242,7 @@ int HugoOperations::pkInsertRecord(Ndb* pNdb, } // Define primary keys - for(int a = 0; a<tab.getNoOfColumns(); a++){ + for(a = 0; a<tab.getNoOfColumns(); a++){ if (tab.getColumn(a)->getPrimaryKey() == true){ if(equalForAttr(pOp, a, r+recordNo) != 0){ ERR(pTrans->getNdbError()); @@ -249,7 +252,7 @@ int HugoOperations::pkInsertRecord(Ndb* pNdb, } // Define attributes to update - for(int a = 0; a<tab.getNoOfColumns(); a++){ + for(a = 0; a<tab.getNoOfColumns(); a++){ if (tab.getColumn(a)->getPrimaryKey() == false){ if(setValueForAttr(pOp, a, recordNo+r, updatesValue ) != 0){ ERR(pTrans->getNdbError()); @@ -265,7 +268,7 @@ int HugoOperations::pkDeleteRecord(Ndb* pNdb, int recordNo, int numRecords){ - int check; + int a, check; for(int r=0; r < numRecords; r++){ NdbOperation* pOp = pTrans->getNdbOperation(tab.getName()); if (pOp == NULL) { @@ -280,7 +283,7 @@ int HugoOperations::pkDeleteRecord(Ndb* pNdb, } // Define primary keys - for(int a = 0; a<tab.getNoOfColumns(); a++){ + for(a = 0; a<tab.getNoOfColumns(); a++){ if (tab.getColumn(a)->getPrimaryKey() == true){ if(equalForAttr(pOp, a, r+recordNo) != 0){ ERR(pTrans->getNdbError()); @@ -291,110 +294,70 @@ int HugoOperations::pkDeleteRecord(Ndb* pNdb, } return NDBT_OK; } - -int HugoOperations::scanReadRecords(Ndb* pNdb, - Uint32 parallelism, ScanLock lock){ - - NdbConnection * pCon = pNdb->hupp(pTrans); +#if 0 +NdbResultSet* +HugoOperations::scanReadRecords(Ndb* pNdb, ScanLock lock){ + NDBT_ResultRow * m_tmpRow = new NDBT_ResultRow(tab); - ScanTmp tmp(pCon, m_tmpRow); - tmp.m_op = ScanTmp::READ; - NdbOperation* pOp = pCon->getNdbOperation(tab.getName()); + NdbScanOperation* pOp = pTrans->getNdbScanOperation(tab.getName()); if (pOp == NULL) { - ERR(pCon->getNdbError()); - return NDBT_FAILED; + ERR(pTrans->getNdbError()); + return 0; } + int check = 0; + NdbResultSet * rs = 0; switch(lock){ case SL_ReadHold: - check = pOp->openScanReadHoldLock(parallelism); + rs = pOp->readTuples(NdbScanOperation::LM_Read, 1, 1); break; case SL_Exclusive: - check = pOp->openScanExclusive(parallelism); + rs = pOp->readTuples(NdbScanOperation::LM_Exclusive, 1, 1); break; case SL_Read: default: - check = pOp->openScanRead(parallelism); + rs = pOp->readTuples(NdbScanOperation::LM_Dirty, 1, 1); } - if( check == -1 ) { - ERR(pCon->getNdbError()); - return NDBT_FAILED; + if( rs == 0) { + ERR(pTrans->getNdbError()); + return 0; } check = pOp->interpret_exit_ok(); if( check == -1 ) { - ERR(pCon->getNdbError()); - return NDBT_FAILED; + ERR(pTrans->getNdbError()); + return 0; } // Define attributes to read for(int a = 0; a<tab.getNoOfColumns(); a++){ if((m_tmpRow->attributeStore(a) = pOp->getValue(tab.getColumn(a)->getName())) == 0) { - ERR(pCon->getNdbError()); - return NDBT_FAILED; + ERR(pTrans->getNdbError()); + return 0; } } - - check = tmp.pTrans->executeScan(); - if( check == -1 ) { - NdbError err = tmp.pTrans->getNdbError(); - ERR(err); - return err.code; - } - - tmp.m_delete = false; - m_scans.push_back(tmp); - - return 0; + return rs; } -int HugoOperations::executeScanRead(Ndb* pNdb){ - - int check = 0; - for(Uint32 i = 0; i<m_scans.size(); i++){ - ScanTmp & tmp = m_scans[i]; - check = run(tmp); - if(check != 0){ - return check; - } - } - while(m_scans.size() > 0){ - ScanTmp & tmp = m_scans[m_scans.size() - 1]; - if(tmp.m_op != ScanTmp::DONE) - abort(); - - tmp.pTrans->close(); - delete tmp.m_tmpRow; - m_scans.erase(m_scans.size() - 1); - } - if(check != 0){ - return check; +int +HugoOperations::readTuples(NdbResultSet* rs){ + int res = 0; + while((res = rs->nextResult()) == 0){ } - + if(res != 1) + return NDBT_FAILED; return NDBT_OK; } +#endif int HugoOperations::execute_Commit(Ndb* pNdb, AbortOption eao){ int check = 0; - while(m_scans.size() > 0){ - ScanTmp & tmp = m_scans[m_scans.size() - 1]; - if(tmp.m_op != ScanTmp::DONE) - abort(); - - tmp.pTrans->close(); - delete tmp.m_tmpRow; - m_scans.erase(m_scans.size() - 1); - } - if(check != 0){ - return check; - } - check = pTrans->execute(Commit, eao); if( check == -1 ) { @@ -409,55 +372,41 @@ int HugoOperations::execute_Commit(Ndb* pNdb, return NDBT_FAILED; return err.code; } - return NDBT_OK; -} -int -HugoOperations::run(ScanTmp & tmp){ - int count = 0; - if(tmp.m_op == ScanTmp::DONE) - abort(); + for(int i = 0; i<m_result_sets.size(); i++){ + m_executed_result_sets.push_back(m_result_sets[i]); - int eof = tmp.pTrans->nextScanResult(true) ; - while(eof == 0){ - count++; - switch(tmp.m_op){ - case ScanTmp::READ: - case ScanTmp::UPDATE: - case ScanTmp::DELETE: - break; - case ScanTmp::DONE: - abort(); + int rows = m_result_sets[i].records; + NdbResultSet* rs = m_result_sets[i].m_result_set; + int res = rs->nextResult(); + switch(res){ + case 1: + return 626; + case -1: + const NdbError err = pTrans->getNdbError(); + ERR(err); + return (err.code > 0 ? err.code : NDBT_FAILED); } - rows.push_back(tmp.m_tmpRow->clone()); - eof = tmp.pTrans->nextScanResult(false); - } - tmp.m_op = ScanTmp::DONE; - if (eof == -1) { - deallocRows(); - NdbError err = tmp.pTrans->getNdbError(); - ERR(err); - return err.code; - } + // A row found - if(count == 0) - return 626; + switch(rows){ + case 0: + return 4000; + default: + m_result_sets[i].records--; + break; + } + } - return 0; + m_result_sets.clear(); + + return NDBT_OK; } int HugoOperations::execute_NoCommit(Ndb* pNdb, AbortOption eao){ int check; - for(Uint32 i = 0; i<m_scans.size(); i++){ - ScanTmp & tmp = m_scans[i]; - check = run(tmp); - if(check != 0){ - return check; - } - } - check = pTrans->execute(NoCommit, eao); if( check == -1 ) { @@ -472,6 +421,35 @@ int HugoOperations::execute_NoCommit(Ndb* pNdb, AbortOption eao){ return NDBT_FAILED; return err.code; } + + for(int i = 0; i<m_result_sets.size(); i++){ + m_executed_result_sets.push_back(m_result_sets[i]); + + int rows = m_result_sets[i].records; + NdbResultSet* rs = m_result_sets[i].m_result_set; + int res = rs->nextResult(); + switch(res){ + case 1: + return 626; + case -1: + const NdbError err = pTrans->getNdbError(); + ERR(err); + return (err.code > 0 ? err.code : NDBT_FAILED); + } + + // A row found + + switch(rows){ + case 0: + return 4000; + default: + case 1: + break; + } + } + + m_result_sets.clear(); + return NDBT_OK; } @@ -697,16 +675,13 @@ HugoOperations::refresh() { NdbConnection* t = getTransaction(); if(t) t->refresh(); - for(Uint32 i = 0; i<m_scans.size(); i++){ - if(m_scans[i].pTrans) - m_scans[i].pTrans->refresh(); - } } int HugoOperations::indexReadRecords(Ndb*, const char * idxName, int recordNo, bool exclusive, int numRecords){ + int a; allocRows(numRecords); int check; for(int r=0; r < numRecords; r++){ @@ -726,7 +701,7 @@ int HugoOperations::indexReadRecords(Ndb*, const char * idxName, int recordNo, } // Define primary keys - for(int a = 0; a<tab.getNoOfColumns(); a++){ + for(a = 0; a<tab.getNoOfColumns(); a++){ if (tab.getColumn(a)->getPrimaryKey() == true){ if(equalForAttr(pOp, a, r+recordNo) != 0){ ERR(pTrans->getNdbError()); @@ -736,7 +711,7 @@ int HugoOperations::indexReadRecords(Ndb*, const char * idxName, int recordNo, } // Define attributes to read - for(int a = 0; a<tab.getNoOfColumns(); a++){ + for(a = 0; a<tab.getNoOfColumns(); a++){ if((rows[r]->attributeStore(a) = pOp->getValue(tab.getColumn(a)->getName())) == 0) { ERR(pTrans->getNdbError()); @@ -753,7 +728,7 @@ HugoOperations::indexUpdateRecord(Ndb*, int recordNo, int numRecords, int updatesValue){ - + int a; allocRows(numRecords); int check; for(int r=0; r < numRecords; r++){ @@ -770,7 +745,7 @@ HugoOperations::indexUpdateRecord(Ndb*, } // Define primary keys - for(int a = 0; a<tab.getNoOfColumns(); a++){ + for(a = 0; a<tab.getNoOfColumns(); a++){ if (tab.getColumn(a)->getPrimaryKey() == true){ if(equalForAttr(pOp, a, r+recordNo) != 0){ ERR(pTrans->getNdbError()); @@ -780,7 +755,7 @@ HugoOperations::indexUpdateRecord(Ndb*, } // Define attributes to update - for(int a = 0; a<tab.getNoOfColumns(); a++){ + for(a = 0; a<tab.getNoOfColumns(); a++){ if (tab.getColumn(a)->getPrimaryKey() == false){ if(setValueForAttr(pOp, a, recordNo+r, updatesValue ) != 0){ ERR(pTrans->getNdbError()); @@ -791,3 +766,35 @@ HugoOperations::indexUpdateRecord(Ndb*, } return NDBT_OK; } + +int +HugoOperations::scanReadRecords(Ndb* pNdb, NdbScanOperation::LockMode lm, + int records){ + + allocRows(records); + NdbScanOperation * pOp = pTrans->getNdbScanOperation(tab.getName()); + + if(!pOp) + return -1; + + NdbResultSet * rs = pOp->readTuples(lm, 1, 1); + + if(!rs){ + return -1; + } + + for(int a = 0; a<tab.getNoOfColumns(); a++){ + if((rows[0]->attributeStore(a) = + pOp->getValue(tab.getColumn(a)->getName())) == 0) { + ERR(pTrans->getNdbError()); + return NDBT_FAILED; + } + } + + RsPair p = {rs, records}; + m_result_sets.push_back(p); + + return 0; +} + +template class Vector<HugoOperations::RsPair>; diff --git a/ndb/test/src/HugoTransactions.cpp b/ndb/test/src/HugoTransactions.cpp index 7f12484ddc8..05039562c76 100644 --- a/ndb/test/src/HugoTransactions.cpp +++ b/ndb/test/src/HugoTransactions.cpp @@ -46,9 +46,9 @@ HugoTransactions::scanReadRecords(Ndb* pNdb, int retryAttempt = 0; const int retryMax = 100; - int check; + int check, a; NdbConnection *pTrans; - NdbOperation *pOp; + NdbScanOperation *pOp; while (true){ @@ -72,19 +72,18 @@ HugoTransactions::scanReadRecords(Ndb* pNdb, return NDBT_FAILED; } - pOp = pTrans->getNdbOperation(tab.getName()); + pOp = pTrans->getNdbScanOperation(tab.getName()); if (pOp == NULL) { ERR(pTrans->getNdbError()); pNdb->closeTransaction(pTrans); return NDBT_FAILED; } - if (committed == true) - check = pOp->openScanReadCommitted(parallelism); - else - check = pOp->openScanRead(parallelism); + NdbResultSet * rs; + rs = pOp ->readTuples(committed ? NdbScanOperation::LM_CommittedRead : + NdbScanOperation::LM_Read); - if( check == -1 ) { + if( rs == 0 ) { ERR(pTrans->getNdbError()); pNdb->closeTransaction(pTrans); return NDBT_FAILED; @@ -97,7 +96,7 @@ HugoTransactions::scanReadRecords(Ndb* pNdb, return NDBT_FAILED; } - for(int a = 0; a<tab.getNoOfColumns(); a++){ + for(a = 0; a<tab.getNoOfColumns(); a++){ if((row.attributeStore(a) = pOp->getValue(tab.getColumn(a)->getName())) == 0) { ERR(pTrans->getNdbError()); @@ -106,7 +105,7 @@ HugoTransactions::scanReadRecords(Ndb* pNdb, } } - check = pTrans->executeScan(); + check = pTrans->execute(NoCommit); if( check == -1 ) { const NdbError err = pTrans->getNdbError(); if (err.status == NdbError::TemporaryError){ @@ -130,12 +129,10 @@ HugoTransactions::scanReadRecords(Ndb* pNdb, if (abortCount < abortPercent) abortTrans = true; } - + int eof; int rows = 0; - eof = pTrans->nextScanResult(); - - while(eof == 0){ + while((eof = rs->nextResult(true)) == 0){ rows++; if (calc.verifyRowValues(&row) != 0){ pNdb->closeTransaction(pTrans); @@ -145,22 +142,20 @@ HugoTransactions::scanReadRecords(Ndb* pNdb, if (abortCount == rows && abortTrans == true){ ndbout << "Scan is aborted" << endl; g_info << "Scan is aborted" << endl; - check = pTrans->stopScan(); + rs->close(); if( check == -1 ) { ERR(pTrans->getNdbError()); pNdb->closeTransaction(pTrans); return NDBT_FAILED; } - + pNdb->closeTransaction(pTrans); return NDBT_OK; } - - eof = pTrans->nextScanResult(); } if (eof == -1) { const NdbError err = pTrans->getNdbError(); - + if (err.status == NdbError::TemporaryError){ ERR_INFO(err); pNdb->closeTransaction(pTrans); @@ -199,106 +194,6 @@ HugoTransactions::scanReadRecords(Ndb* pNdb, #define RESTART_SCAN 99 -// Take over one record from pOrgOp and update it -int -HugoTransactions::takeOverAndUpdateRecord(Ndb* pNdb, - NdbOperation* pOrgOp){ - int retryAttempt = 0; - const int retryMax = 10; - int check; - NdbConnection *pUpdTrans; - NdbOperation *pUpdOp; - - while (true){ - - if (retryAttempt >= retryMax){ - g_info << "ERROR: has retried this operation " << retryAttempt - << " times, failing!" << endl; - return NDBT_FAILED; - } - - pUpdTrans = pNdb->startTransaction(); - if (pUpdTrans == NULL) { - const NdbError err = pNdb->getNdbError(); - - if (err.status == NdbError::TemporaryError){ - ERR(err); - NdbSleep_MilliSleep(50); - retryAttempt++; - continue; - } - ERR(err); - return NDBT_FAILED; - } - - if ((pUpdOp = pOrgOp->takeOverForUpdate(pUpdTrans)) == NULL){ - ERR(pNdb->getNdbError()); - return NDBT_FAILED; - } - - int updates = calc.getUpdatesValue(&row) + 1; - int id = calc.getIdValue(&row); - - // Set a calculated value for each non-PK attribute in this table - for (int a = 0; a<tab.getNoOfColumns(); a++){ - if (tab.getColumn(a)->getPrimaryKey() == false){ - if(setValueForAttr(pUpdOp, a, id, updates ) != 0){ - ERR(pUpdTrans->getNdbError()); - pNdb->closeTransaction(pUpdTrans); - return NDBT_FAILED; - } - } - } - check = pUpdTrans->execute( Commit ); - if(check == -1 ) { - const NdbError err = pUpdTrans->getNdbError(); - pNdb->closeTransaction(pUpdTrans); - - ERR(err); - if(err.code == 499 || err.code == 250){ - return RESTART_SCAN; - } - - switch(err.status){ - case NdbError::Success: - g_info << "ERROR: NdbError reports success when transcaction failed" - << endl; - return NDBT_FAILED; - break; - - case NdbError::TemporaryError: - NdbSleep_MilliSleep(50+50*retryAttempt); - retryAttempt++; - continue; - break; - - case NdbError::UnknownResult: - return NDBT_FAILED; - break; - - default: - case NdbError::PermanentError: - switch (err.code){ - case 499: - case 250: - return NDBT_TEMPORARY; - - default: - return NDBT_FAILED; - break; - } - break; - } - } - else{ - pNdb->closeTransaction(pUpdTrans); - } - - return NDBT_OK; - } - return NDBT_FAILED; -} - int HugoTransactions::scanUpdateRecords(Ndb* pNdb, int records, @@ -320,9 +215,12 @@ HugoTransactions::scanUpdateRecords1(Ndb* pNdb, int records, int abortPercent, int parallelism){ +#if 1 + return scanUpdateRecords3(pNdb, records, abortPercent, 1); +#else int retryAttempt = 0; const int retryMax = 100; - int check; + int check, a; NdbConnection *pTrans; NdbOperation *pOp; @@ -371,7 +269,7 @@ HugoTransactions::scanUpdateRecords1(Ndb* pNdb, } // Read all attributes from this table - for(int a=0; a<tab.getNoOfColumns(); a++){ + for(a=0; a<tab.getNoOfColumns(); a++){ if((row.attributeStore(a) = pOp->getValue(tab.getColumn(a)->getName())) == NULL){ ERR(pTrans->getNdbError()); pNdb->closeTransaction(pTrans); @@ -472,9 +370,9 @@ HugoTransactions::scanUpdateRecords1(Ndb* pNdb, return NDBT_OK; } return NDBT_FAILED; +#endif } - // Scan all records exclusive and update // them batched by asking nextScanResult to // give us all cached records before fetching new @@ -484,9 +382,12 @@ HugoTransactions::scanUpdateRecords2(Ndb* pNdb, int records, int abortPercent, int parallelism){ +#if 1 + return scanUpdateRecords3(pNdb, records, abortPercent, parallelism); +#else int retryAttempt = 0; const int retryMax = 100; - int check; + int check, a; NdbConnection *pTrans; NdbOperation *pOp; @@ -535,7 +436,7 @@ HugoTransactions::scanUpdateRecords2(Ndb* pNdb, } // Read all attributes from this table - for(int a=0; a<tab.getNoOfColumns(); a++){ + for(a=0; a<tab.getNoOfColumns(); a++){ if((row.attributeStore(a) = pOp->getValue(tab.getColumn(a)->getName())) == NULL){ ERR(pTrans->getNdbError()); pNdb->closeTransaction(pTrans); @@ -642,35 +543,9 @@ HugoTransactions::scanUpdateRecords2(Ndb* pNdb, return NDBT_OK; } return NDBT_FAILED; +#endif } -int -HugoTransactions::addRowToUpdate(Ndb* pNdb, - NdbConnection* pUpdTrans, - NdbOperation* pOrgOp){ - - int updates = calc.getUpdatesValue(&row) + 1; - int r = calc.getIdValue(&row); - - NdbOperation* pUpdOp = pOrgOp->takeOverForUpdate(pUpdTrans); - if (pUpdOp == NULL){ - ERR(pNdb->getNdbError()); - return NDBT_FAILED; - } - - for(int a = 0; a<tab.getNoOfColumns(); a++){ - if (tab.getColumn(a)->getPrimaryKey() == false){ - if(setValueForAttr(pUpdOp, a, r, updates ) != 0){ - ERR(pUpdTrans->getNdbError()); - pNdb->closeTransaction(pUpdTrans); - return NDBT_FAILED; - } - } - } - return NDBT_OK; -} - - int HugoTransactions::scanUpdateRecords3(Ndb* pNdb, int records, @@ -678,7 +553,7 @@ HugoTransactions::scanUpdateRecords3(Ndb* pNdb, int parallelism){ int retryAttempt = 0; const int retryMax = 100; - int check; + int check, a; NdbConnection *pTrans; NdbScanOperation *pOp; @@ -717,7 +592,7 @@ HugoTransactions::scanUpdateRecords3(Ndb* pNdb, } // Read all attributes from this table - for(int a=0; a<tab.getNoOfColumns(); a++){ + for(a=0; a<tab.getNoOfColumns(); a++){ if((row.attributeStore(a) = pOp->getValue(tab.getColumn(a)->getName())) == NULL){ ERR(pTrans->getNdbError()); pNdb->closeTransaction(pTrans); @@ -759,8 +634,7 @@ HugoTransactions::scanUpdateRecords3(Ndb* pNdb, } const int updates = calc.getUpdatesValue(&row) + 1; const int r = calc.getIdValue(&row); - - for(int a = 0; a<tab.getNoOfColumns(); a++){ + for(a = 0; a<tab.getNoOfColumns(); a++){ if (tab.getColumn(a)->getPrimaryKey() == false){ if(setValueForAttr(pUp, a, r, updates ) != 0){ ERR(pTrans->getNdbError()); @@ -780,7 +654,7 @@ HugoTransactions::scanUpdateRecords3(Ndb* pNdb, if(check != -1){ check = pTrans->execute(Commit); - pTrans->releaseCompletedOperations(); + pTrans->restart(); } const NdbError err = pTrans->getNdbError(); @@ -794,7 +668,7 @@ HugoTransactions::scanUpdateRecords3(Ndb* pNdb, return NDBT_FAILED; } } - + const NdbError err = pTrans->getNdbError(); if( check == -1 ) { pNdb->closeTransaction(pTrans); @@ -819,12 +693,14 @@ HugoTransactions::loadTable(Ndb* pNdb, int records, int batch, bool allowConstraintViolation, - int doSleep){ - int check; + int doSleep, + bool oneTrans){ + int check, a; int retryAttempt = 0; int retryMax = 5; NdbConnection *pTrans; NdbOperation *pOp; + bool first_batch = true; const int org = batch; const int cols = tab.getNoOfColumns(); @@ -833,7 +709,7 @@ HugoTransactions::loadTable(Ndb* pNdb, batch = (batch * 256); // -> 512 -> 65536k per commit batch = batch/bytes; // batch = batch == 0 ? 1 : batch; - + if(batch != org){ g_info << "batch = " << org << " rowsize = " << bytes << " -> rows/commit = " << batch << endl; @@ -841,7 +717,7 @@ HugoTransactions::loadTable(Ndb* pNdb, g_info << "|- Inserting records..." << endl; for (int c=0 ; c<records ; ){ - + bool closeTrans; if (retryAttempt >= retryMax){ g_info << "Record " << c << " could not be inserted, has retried " << retryAttempt << " times " << endl; @@ -852,19 +728,22 @@ HugoTransactions::loadTable(Ndb* pNdb, if (doSleep > 0) NdbSleep_MilliSleep(doSleep); - pTrans = pNdb->startTransaction(); - - if (pTrans == NULL) { - const NdbError err = pNdb->getNdbError(); + if (first_batch || !oneTrans) { + first_batch = false; + pTrans = pNdb->startTransaction(); + + if (pTrans == NULL) { + const NdbError err = pNdb->getNdbError(); - if (err.status == NdbError::TemporaryError){ - ERR(err); - NdbSleep_MilliSleep(50); - retryAttempt++; - continue; + if (err.status == NdbError::TemporaryError){ + ERR(err); + NdbSleep_MilliSleep(50); + retryAttempt++; + continue; + } + ERR(err); + return NDBT_FAILED; } - ERR(err); - return NDBT_FAILED; } for(int b = 0; b < batch && c+b<records; b++){ @@ -884,7 +763,7 @@ HugoTransactions::loadTable(Ndb* pNdb, } // Set a calculated value for each attribute in this table - for (int a = 0; a<tab.getNoOfColumns(); a++){ + for (a = 0; a<tab.getNoOfColumns(); a++){ if(setValueForAttr(pOp, a, c+b, 0 ) != 0){ ERR(pTrans->getNdbError()); pNdb->closeTransaction(pTrans); @@ -894,7 +773,13 @@ HugoTransactions::loadTable(Ndb* pNdb, } // Execute the transaction and insert the record - check = pTrans->execute( Commit ); + if (!oneTrans || (c + batch) >= records) { + closeTrans = true; + check = pTrans->execute( Commit ); + } else { + closeTrans = false; + check = pTrans->execute( NoCommit ); + } if(check == -1 ) { const NdbError err = pTrans->getNdbError(); pNdb->closeTransaction(pTrans); @@ -937,8 +822,10 @@ HugoTransactions::loadTable(Ndb* pNdb, break; } } - else{ - pNdb->closeTransaction(pTrans); + else{ + if (closeTrans) { + pNdb->closeTransaction(pTrans); + } } // Step to next record @@ -951,7 +838,7 @@ HugoTransactions::loadTable(Ndb* pNdb, int HugoTransactions::fillTable(Ndb* pNdb, int batch){ - int check; + int check, a, b; int retryAttempt = 0; int retryMax = 5; NdbConnection *pTrans; @@ -982,7 +869,7 @@ HugoTransactions::fillTable(Ndb* pNdb, return NDBT_FAILED; } - for(int b = 0; b < batch; b++){ + for(b = 0; b < batch; b++){ pOp = pTrans->getNdbOperation(tab.getName()); if (pOp == NULL) { @@ -999,7 +886,7 @@ HugoTransactions::fillTable(Ndb* pNdb, } // Set a calculated value for each attribute in this table - for (int a = 0; a<tab.getNoOfColumns(); a++){ + for (a = 0; a<tab.getNoOfColumns(); a++){ if(setValueForAttr(pOp, a, c+b, 0 ) != 0){ ERR(pTrans->getNdbError()); pNdb->closeTransaction(pTrans); @@ -1138,7 +1025,7 @@ int HugoTransactions::eventOperation(Ndb* pNdb, void* pstats, int records) { int myXXXXX = XXXXX++; - + Uint32 i; const char function[] = "HugoTransactions::eventOperation: "; struct receivedEvent* recInsertEvent; NdbAutoObjArrayPtr<struct receivedEvent> @@ -1155,7 +1042,7 @@ HugoTransactions::eventOperation(Ndb* pNdb, void* pstats, stats.n_duplicates = 0; stats.n_inconsistent_gcis = 0; - for (int i = 0; i < records; i++) { + for (i = 0; i < records; i++) { recInsertEvent[i].pk = 0xFFFFFFFF; recInsertEvent[i].count = 0; recInsertEvent[i].event = 0xFFFFFFFF; @@ -1263,7 +1150,7 @@ HugoTransactions::eventOperation(Ndb* pNdb, void* pstats, } g_info << "overrun " << overrun << " pk " << pk; - for (int i = 1; i < noEventColumnName; i++) { + for (i = 1; i < noEventColumnName; i++) { if (recAttr[i]->isNULL() >= 0) { // we have a value g_info << " post[" << i << "]="; if (recAttr[i]->isNULL() == 0) // we have a non-null value @@ -1306,7 +1193,7 @@ HugoTransactions::eventOperation(Ndb* pNdb, void* pstats, if (stats.n_updates > 0) { stats.n_consecutive++; } - for (Uint32 i = 0; i < (Uint32)records/3; i++) { + for (i = 0; i < (Uint32)records/3; i++) { if (recInsertEvent[i].pk != i) { stats.n_consecutive ++; ndbout << "missing insert pk " << i << endl; @@ -1345,7 +1232,7 @@ HugoTransactions::pkReadRecords(Ndb* pNdb, int r = 0; int retryAttempt = 0; const int retryMax = 100; - int check; + int check, a; NdbConnection *pTrans; NdbOperation *pOp; @@ -1397,7 +1284,7 @@ HugoTransactions::pkReadRecords(Ndb* pNdb, } // Define primary keys - for(int a = 0; a<tab.getNoOfColumns(); a++){ + for(a = 0; a<tab.getNoOfColumns(); a++){ if (tab.getColumn(a)->getPrimaryKey() == true){ if(equalForAttr(pOp, a, r+b) != 0){ ERR(pTrans->getNdbError()); @@ -1408,7 +1295,7 @@ HugoTransactions::pkReadRecords(Ndb* pNdb, } // Define attributes to read - for(int a = 0; a<tab.getNoOfColumns(); a++){ + for(a = 0; a<tab.getNoOfColumns(); a++){ if((rows[b]->attributeStore(a) = pOp->getValue(tab.getColumn(a)->getName())) == 0) { ERR(pTrans->getNdbError()); @@ -1471,13 +1358,13 @@ HugoTransactions::pkUpdateRecords(Ndb* pNdb, int r = 0; int retryAttempt = 0; const int retryMax = 100; - int check; + int check, a, b; NdbConnection *pTrans; NdbOperation *pOp; allocRows(batch); - g_info << "|- Updating records..." << endl; + g_info << "|- Updating records (batch=" << batch << ")..." << endl; while (r < records){ if (retryAttempt >= retryMax){ @@ -1503,7 +1390,7 @@ HugoTransactions::pkUpdateRecords(Ndb* pNdb, return NDBT_FAILED; } - for(int b = 0; b<batch && (r+b) < records; b++){ + for(b = 0; b<batch && (r+b) < records; b++){ pOp = pTrans->getNdbOperation(tab.getName()); if (pOp == NULL) { ERR(pTrans->getNdbError()); @@ -1519,7 +1406,7 @@ HugoTransactions::pkUpdateRecords(Ndb* pNdb, } // Define primary keys - for(int a = 0; a<tab.getNoOfColumns(); a++){ + for(a = 0; a<tab.getNoOfColumns(); a++){ if (tab.getColumn(a)->getPrimaryKey() == true){ if(equalForAttr(pOp, a, r+b) != 0){ ERR(pTrans->getNdbError()); @@ -1530,7 +1417,7 @@ HugoTransactions::pkUpdateRecords(Ndb* pNdb, } // Define attributes to read - for(int a = 0; a<tab.getNoOfColumns(); a++){ + for(a = 0; a<tab.getNoOfColumns(); a++){ if((rows[b]->attributeStore(a) = pOp->getValue(tab.getColumn(a)->getName())) == 0) { ERR(pTrans->getNdbError()); @@ -1556,7 +1443,7 @@ HugoTransactions::pkUpdateRecords(Ndb* pNdb, return NDBT_FAILED; } - for(int b = 0; b<batch && (b+r)<records; b++){ + for(b = 0; b<batch && (b+r)<records; b++){ if (calc.verifyRowValues(rows[b]) != 0){ pNdb->closeTransaction(pTrans); return NDBT_FAILED; @@ -1579,7 +1466,7 @@ HugoTransactions::pkUpdateRecords(Ndb* pNdb, return NDBT_FAILED; } - for(int a = 0; a<tab.getNoOfColumns(); a++){ + for(a = 0; a<tab.getNoOfColumns(); a++){ if (tab.getColumn(a)->getPrimaryKey() == true){ if(equalForAttr(pUpdOp, a, r+b) != 0){ ERR(pTrans->getNdbError()); @@ -1589,7 +1476,7 @@ HugoTransactions::pkUpdateRecords(Ndb* pNdb, } } - for(int a = 0; a<tab.getNoOfColumns(); a++){ + for(a = 0; a<tab.getNoOfColumns(); a++){ if (tab.getColumn(a)->getPrimaryKey() == false){ if(setValueForAttr(pUpdOp, a, r+b, updates ) != 0){ ERR(pTrans->getNdbError()); @@ -1639,7 +1526,7 @@ HugoTransactions::pkInterpretedUpdateRecords(Ndb* pNdb, int r = 0; int retryAttempt = 0; const int retryMax = 100; - int check; + int check, a; NdbConnection *pTrans; while (r < records){ @@ -1679,7 +1566,7 @@ HugoTransactions::pkInterpretedUpdateRecords(Ndb* pNdb, } // Define primary keys - for(int a = 0; a<tab.getNoOfColumns(); a++){ + for(a = 0; a<tab.getNoOfColumns(); a++){ if (tab.getColumn(a)->getPrimaryKey() == true){ if(equalForAttr(pOp, a, r) != 0){ ERR(pTrans->getNdbError()); @@ -1690,7 +1577,7 @@ HugoTransactions::pkInterpretedUpdateRecords(Ndb* pNdb, } // Read update value - for(int a = 0; a<tab.getNoOfColumns(); a++){ + for(a = 0; a<tab.getNoOfColumns(); a++){ if (calc.isUpdateCol(a) == true){ if((row.attributeStore(a) = pOp->getValue(tab.getColumn(a)->getName())) == 0) { @@ -1735,7 +1622,7 @@ HugoTransactions::pkInterpretedUpdateRecords(Ndb* pNdb, } // PKs - for(int a = 0; a<tab.getNoOfColumns(); a++){ + for(a = 0; a<tab.getNoOfColumns(); a++){ if (tab.getColumn(a)->getPrimaryKey() == true){ if(equalForAttr(pUpdOp, a, r) != 0){ ERR(pTrans->getNdbError()); @@ -1746,7 +1633,7 @@ HugoTransactions::pkInterpretedUpdateRecords(Ndb* pNdb, } // Update col - for(int a = 0; a<tab.getNoOfColumns(); a++){ + for(a = 0; a<tab.getNoOfColumns(); a++){ if ((tab.getColumn(a)->getPrimaryKey() == false) && (calc.isUpdateCol(a) == true)){ @@ -1763,7 +1650,7 @@ HugoTransactions::pkInterpretedUpdateRecords(Ndb* pNdb, } // Remaining attributes - for(int a = 0; a<tab.getNoOfColumns(); a++){ + for(a = 0; a<tab.getNoOfColumns(); a++){ if ((tab.getColumn(a)->getPrimaryKey() == false) && (calc.isUpdateCol(a) == false)){ if(setValueForAttr(pUpdOp, a, r, updates ) != 0){ @@ -1818,7 +1705,7 @@ HugoTransactions::pkDelRecords(Ndb* pNdb, int r = 0; int retryAttempt = 0; const int retryMax = 100; - int check; + int check, a; NdbConnection *pTrans; NdbOperation *pOp; @@ -1863,7 +1750,7 @@ HugoTransactions::pkDelRecords(Ndb* pNdb, } // Define primary keys - for(int a = 0; a<tab.getNoOfColumns(); a++){ + for(a = 0; a<tab.getNoOfColumns(); a++){ if (tab.getColumn(a)->getPrimaryKey() == true){ if(equalForAttr(pOp, a, r) != 0){ ERR(pTrans->getNdbError()); @@ -1933,7 +1820,7 @@ HugoTransactions::lockRecords(Ndb* pNdb, int r = 0; int retryAttempt = 0; const int retryMax = 100; - int check; + int check, a, b; NdbConnection *pTrans; NdbOperation *pOp; @@ -1970,7 +1857,7 @@ HugoTransactions::lockRecords(Ndb* pNdb, return NDBT_FAILED; } - for(int b = 0; (b<lockBatch) && (r+b < records); b++){ + for(b = 0; (b<lockBatch) && (r+b < records); b++){ pOp = pTrans->getNdbOperation(tab.getName()); if (pOp == NULL) { ERR(pTrans->getNdbError()); @@ -1986,7 +1873,7 @@ HugoTransactions::lockRecords(Ndb* pNdb, } // Define primary keys - for(int a = 0; a<tab.getNoOfColumns(); a++){ + for(a = 0; a<tab.getNoOfColumns(); a++){ if (tab.getColumn(a)->getPrimaryKey() == true){ if(equalForAttr(pOp, a, r+b) != 0){ ERR(pTrans->getNdbError()); @@ -1997,7 +1884,7 @@ HugoTransactions::lockRecords(Ndb* pNdb, } // Define attributes to read - for(int a = 0; a<tab.getNoOfColumns(); a++){ + for(a = 0; a<tab.getNoOfColumns(); a++){ if((rows[b]->attributeStore(a) = pOp->getValue(tab.getColumn(a)->getName())) == 0) { ERR(pTrans->getNdbError()); @@ -2080,10 +1967,10 @@ HugoTransactions::indexReadRecords(Ndb* pNdb, int r = 0; int retryAttempt = 0; const int retryMax = 100; - int check; + int check, a; NdbConnection *pTrans; NdbOperation *pOp; - NdbScanOperation *sOp; + NdbIndexScanOperation *sOp; NdbResultSet * rs; const NdbDictionary::Index* pIndex @@ -2134,7 +2021,7 @@ HugoTransactions::indexReadRecords(Ndb* pNdb, } check = pOp->readTuple(); } else { - pOp = sOp = pTrans->getNdbScanOperation(idxName, tab.getName()); + pOp = sOp = pTrans->getNdbIndexScanOperation(idxName, tab.getName()); if (sOp == NULL) { ERR(pTrans->getNdbError()); pNdb->closeTransaction(pTrans); @@ -2152,7 +2039,7 @@ HugoTransactions::indexReadRecords(Ndb* pNdb, } // Define primary keys - for(int a = 0; a<tab.getNoOfColumns(); a++){ + for(a = 0; a<tab.getNoOfColumns(); a++){ if (tab.getColumn(a)->getPrimaryKey() == true){ if(equalForAttr(pOp, a, r+b) != 0){ ERR(pTrans->getNdbError()); @@ -2163,7 +2050,7 @@ HugoTransactions::indexReadRecords(Ndb* pNdb, } // Define attributes to read - for(int a = 0; a<tab.getNoOfColumns(); a++){ + for(a = 0; a<tab.getNoOfColumns(); a++){ if((rows[b]->attributeStore(a) = pOp->getValue(tab.getColumn(a)->getName())) == 0) { ERR(pTrans->getNdbError()); @@ -2231,7 +2118,7 @@ HugoTransactions::indexUpdateRecords(Ndb* pNdb, int r = 0; int retryAttempt = 0; const int retryMax = 100; - int check; + int check, a, b; NdbConnection *pTrans; NdbOperation *pOp; NdbScanOperation * sOp; @@ -2268,7 +2155,7 @@ HugoTransactions::indexUpdateRecords(Ndb* pNdb, return NDBT_FAILED; } - for(int b = 0; b<batchsize && (b+r)<records; b++){ + for(b = 0; b<batchsize && (b+r)<records; b++){ if(!ordered){ pOp = pTrans->getNdbIndexOperation(idxName, tab.getName()); if (pOp == NULL) { @@ -2284,7 +2171,7 @@ HugoTransactions::indexUpdateRecords(Ndb* pNdb, return NDBT_FAILED; } } else { - pOp = sOp = pTrans->getNdbScanOperation(idxName, tab.getName()); + pOp = sOp = pTrans->getNdbIndexScanOperation(idxName, tab.getName()); if (pOp == NULL) { ERR(pTrans->getNdbError()); pNdb->closeTransaction(pTrans); @@ -2296,7 +2183,7 @@ HugoTransactions::indexUpdateRecords(Ndb* pNdb, } // Define primary keys - for(int a = 0; a<tab.getNoOfColumns(); a++){ + for(a = 0; a<tab.getNoOfColumns(); a++){ if (tab.getColumn(a)->getPrimaryKey() == true){ if(equalForAttr(pOp, a, r+b) != 0){ ERR(pTrans->getNdbError()); @@ -2307,7 +2194,7 @@ HugoTransactions::indexUpdateRecords(Ndb* pNdb, } // Define attributes to read - for(int a = 0; a<tab.getNoOfColumns(); a++){ + for(a = 0; a<tab.getNoOfColumns(); a++){ if((rows[b]->attributeStore(a) = pOp->getValue(tab.getColumn(a)->getName())) == 0) { ERR(pTrans->getNdbError()); @@ -2338,7 +2225,7 @@ HugoTransactions::indexUpdateRecords(Ndb* pNdb, return NDBT_FAILED; } - for(int b = 0; b<batchsize && (b+r)<records; b++){ + for(b = 0; b<batchsize && (b+r)<records; b++){ if (calc.verifyRowValues(rows[b]) != 0){ pNdb->closeTransaction(pTrans); return NDBT_FAILED; @@ -2367,7 +2254,7 @@ HugoTransactions::indexUpdateRecords(Ndb* pNdb, } if(!ordered){ - for(int a = 0; a<tab.getNoOfColumns(); a++){ + for(a = 0; a<tab.getNoOfColumns(); a++){ if (tab.getColumn(a)->getPrimaryKey() == true){ if(equalForAttr(pUpdOp, a, r+b) != 0){ ERR(pTrans->getNdbError()); @@ -2378,7 +2265,7 @@ HugoTransactions::indexUpdateRecords(Ndb* pNdb, } } - for(int a = 0; a<tab.getNoOfColumns(); a++){ + for(a = 0; a<tab.getNoOfColumns(); a++){ if (tab.getColumn(a)->getPrimaryKey() == false){ if(setValueForAttr(pUpdOp, a, r+b, updates ) != 0){ ERR(pTrans->getNdbError()); @@ -2415,4 +2302,4 @@ HugoTransactions::indexUpdateRecords(Ndb* pNdb, return NDBT_OK; } - +template class Vector<NDBT_ResultRow*>; diff --git a/ndb/test/src/NDBT_Table.cpp b/ndb/test/src/NDBT_Table.cpp index 485377e690a..d283cdf5912 100644 --- a/ndb/test/src/NDBT_Table.cpp +++ b/ndb/test/src/NDBT_Table.cpp @@ -19,35 +19,6 @@ #include <NDBT.hpp> class NdbOut& -operator <<(class NdbOut& ndbout, const NDBT_Attribute & attr){ - - NdbDictionary::Column::Type type = attr.getType(); - - ndbout << attr.getName() << " " << type; - - switch(type){ - case NdbDictionary::Column::Decimal: - ndbout << "(" << attr.getScale() << ", " << attr.getPrecision() << ")"; - break; - default: - break; - } - - if(attr.getLength() != 1) - ndbout << "[" << attr.getLength() << "]"; - - if(attr.getNullable()) - ndbout << " NULL"; - else - ndbout << " NOT NULL"; - - if(attr.getPrimaryKey()) - ndbout << " PRIMARY KEY"; - - return ndbout; -} - -class NdbOut& operator <<(class NdbOut& ndbout, const NDBT_Table & tab) { ndbout << "-- " << tab.getName() << " --" << endl; diff --git a/ndb/test/src/NDBT_Tables.cpp b/ndb/test/src/NDBT_Tables.cpp index 548e755a3fb..ff6db3e892c 100644 --- a/ndb/test/src/NDBT_Tables.cpp +++ b/ndb/test/src/NDBT_Tables.cpp @@ -297,7 +297,7 @@ NDBT_Table T14("T14", sizeof(T14Attribs)/sizeof(NDBT_Attribute), T14Attribs); */ static const -NDBT_Attribute C2_PORTS_Attribs[] = { +NDBT_Attribute I1_Cols[] = { NDBT_Attribute("ID", NdbDictionary::Column::Unsigned, true), NDBT_Attribute("PORT", NdbDictionary::Column::Char, 16, true), NDBT_Attribute("ACCESSNODE", NdbDictionary::Column::Char, 16, true), @@ -310,11 +310,19 @@ NDBT_Attribute C2_PORTS_Attribs[] = { }; static -NDBT_Table C2_PORTS("C2_PORTS", sizeof(C2_PORTS_Attribs)/sizeof(NDBT_Attribute), C2_PORTS_Attribs); +const +char* I1_Indexes[] = { + "UNIQUE", "ID", "PORT", "ACCESSNODE", "POP", "PORTSTATE", 0, + 0 +}; + +static +NDBT_Table I1("I1", sizeof(I1_Cols)/sizeof(NDBT_Attribute), I1_Cols + );// ,I1_Indexes); static const -NDBT_Attribute C2_SERVICES_Attribs[] = { +NDBT_Attribute I2_Cols[] = { NDBT_Attribute("ID", NdbDictionary::Column::Unsigned, true), NDBT_Attribute("PORT", NdbDictionary::Column::Char, 16, true), NDBT_Attribute("ACCESSNODE", NdbDictionary::Column::Char, 16, true), @@ -331,12 +339,20 @@ NDBT_Attribute C2_SERVICES_Attribs[] = { NDBT_Attribute("UPDATES", NdbDictionary::Column::Unsigned) }; +const +char* I2_Indexes[] = { + "ORDERED", "CUSTOMER_ID", 0, + "ORDERED", "NUM_IP", 0, + 0 +}; + static -NDBT_Table C2_SERVICES("C2_SERVICES", sizeof(C2_SERVICES_Attribs)/sizeof(NDBT_Attribute), C2_SERVICES_Attribs); +NDBT_Table I2("I2", sizeof(I2_Cols)/sizeof(NDBT_Attribute), I2_Cols + );//, I2_Indexes); static const -NDBT_Attribute C2_CLIENTS_Attribs[] = { +NDBT_Attribute I3_Cols[] = { NDBT_Attribute("ID", NdbDictionary::Column::Unsigned, true), NDBT_Attribute("PORT", NdbDictionary::Column::Char, 16), // SI2 NDBT_Attribute("ACCESSNODE", NdbDictionary::Column::Char, 16), // SI2 @@ -355,8 +371,17 @@ NDBT_Attribute C2_CLIENTS_Attribs[] = { NDBT_Attribute("UPDATES", NdbDictionary::Column::Unsigned) }; +const +char* I3_Indexes[] = { + "UNIQUE", "ID", 0, + "ORDERED", "MAC", 0, + "ORDERED", "GW", 0, + 0 +}; + static -NDBT_Table C2_CLIENTS("C2_CLIENTS", sizeof(C2_CLIENTS_Attribs)/sizeof(NDBT_Attribute), C2_CLIENTS_Attribs); +NDBT_Table I3("I3", sizeof(I3_Cols)/sizeof(NDBT_Attribute), I3_Cols + ); // ,I3_Indexes); // Define array with pointer to all tables static @@ -377,10 +402,23 @@ NDBT_Table *test_tables[]= &T12, &T13, &T14, - &C2_PORTS, - &C2_SERVICES, - &C2_CLIENTS + &I1, + &I2, + &I3 +}; + +struct NDBT_IndexList { + const char * m_table; + const char ** m_indexes; +}; +static +const +NDBT_IndexList indexes[] = { + "I1", I1_Indexes, + "I2", I2_Indexes, + "I3", I3_Indexes, + 0, 0 }; static @@ -430,7 +468,7 @@ NDBT_Table F2("F2", sizeof(F2Attribs)/sizeof(NDBT_Attribute), F2Attribs); /* F3 * - * Error: Too many primary keys defined, 16 is max? + * Error: Too many primary keys defined, 32 is max */ static const @@ -452,10 +490,26 @@ NDBT_Attribute F3Attribs[] = { NDBT_Attribute("KOL15", NdbDictionary::Column::Unsigned, 1, true), NDBT_Attribute("KOL16", NdbDictionary::Column::Unsigned, 1, true), NDBT_Attribute("KOL17", NdbDictionary::Column::Unsigned, 1, true), - NDBT_Attribute("KOL20", NdbDictionary::Column::Unsigned), - NDBT_Attribute("KOL30", NdbDictionary::Column::Unsigned), + NDBT_Attribute("KOL18", NdbDictionary::Column::Unsigned, 1, true), + NDBT_Attribute("KOL19", NdbDictionary::Column::Unsigned, 1, true), + NDBT_Attribute("KOL20", NdbDictionary::Column::Unsigned, 1, true), + NDBT_Attribute("KOL21", NdbDictionary::Column::Unsigned, 1, true), + NDBT_Attribute("KOL22", NdbDictionary::Column::Unsigned, 1, true), + NDBT_Attribute("KOL23", NdbDictionary::Column::Unsigned, 1, true), + NDBT_Attribute("KOL24", NdbDictionary::Column::Unsigned, 1, true), + NDBT_Attribute("KOL25", NdbDictionary::Column::Unsigned, 1, true), + NDBT_Attribute("KOL26", NdbDictionary::Column::Unsigned, 1, true), + NDBT_Attribute("KOL27", NdbDictionary::Column::Unsigned, 1, true), + NDBT_Attribute("KOL28", NdbDictionary::Column::Unsigned, 1, true), + NDBT_Attribute("KOL29", NdbDictionary::Column::Unsigned, 1, true), + NDBT_Attribute("KOL30", NdbDictionary::Column::Unsigned, 1, true), + NDBT_Attribute("KOL31", NdbDictionary::Column::Unsigned, 1, true), + NDBT_Attribute("KOL32", NdbDictionary::Column::Unsigned, 1, true), + NDBT_Attribute("KOL33", NdbDictionary::Column::Unsigned, 1, true), NDBT_Attribute("KOL40", NdbDictionary::Column::Unsigned), - NDBT_Attribute("KOL50", NdbDictionary::Column::Unsigned) + NDBT_Attribute("KOL50", NdbDictionary::Column::Unsigned), + NDBT_Attribute("KOL60", NdbDictionary::Column::Unsigned), + NDBT_Attribute("KOL70", NdbDictionary::Column::Unsigned) }; static @@ -678,17 +732,18 @@ NdbDictionary::Table* NDBT_Tables::getTable(const char* _nam){ // Search tables list to find a table NDBT_Table* tab = NULL; - for (int i=0; i<numTestTables; i++){ + int i; + for (i=0; i<numTestTables; i++){ if (strcmp(test_tables[i]->getName(), _nam) == 0){ return test_tables[i]; } } - for (int i=0; i<numFailTables; i++){ + for (i=0; i<numFailTables; i++){ if (strcmp(fail_tables[i]->getName(), _nam) == 0){ return fail_tables[i]; } } - for (int i=0; i<numUtilTables; i++){ + for (i=0; i<numUtilTables; i++){ if (strcmp(util_tables[i]->getName(), _nam) == 0){ return util_tables[i]; } @@ -746,26 +801,13 @@ NDBT_Tables::getNumTables(){ int NDBT_Tables::createAllTables(Ndb* pNdb, bool _temp, bool existsOk){ - + for (int i=0; i < NDBT_Tables::getNumTables(); i++){ - - const NdbDictionary::Table* tab = NDBT_Tables::getTable(i); - if (tab == NULL){ - return NDBT_ProgramExit(NDBT_FAILED); - } - - // Set temporary table - NdbDictionary::Table tmpTab(* tab); - tmpTab.setStoredTable(_temp? 0 : 1); - - int r = pNdb->getDictionary()->createTable(tmpTab); - int err = pNdb->getDictionary()->getNdbError().code; - if(r == -1){ - if (existsOk && err == 721) - ; - else { - return NDBT_FAILED; - } + pNdb->getDictionary()->dropTable(NDBT_Tables::getTable(i)->getName()); + int ret= createTable(pNdb, + NDBT_Tables::getTable(i)->getName(), _temp, existsOk); + if(ret){ + return ret; } } return NDBT_OK; @@ -777,7 +819,8 @@ NDBT_Tables::createAllTables(Ndb* pNdb){ } int -NDBT_Tables::createTable(Ndb* pNdb, const char* _name, bool _temp){ +NDBT_Tables::createTable(Ndb* pNdb, const char* _name, bool _temp, + bool existsOk){ const NdbDictionary::Table* tab = NDBT_Tables::getTable(_name); if (tab == NULL){ @@ -787,10 +830,61 @@ NDBT_Tables::createTable(Ndb* pNdb, const char* _name, bool _temp){ return NDBT_WRONGARGS; } - NdbDictionary::Table tmpTab(* tab); - tmpTab.setStoredTable(_temp ? 0 : 1); + int r = 0; + do { + NdbDictionary::Table tmpTab(* tab); + tmpTab.setStoredTable(_temp ? 0 : 1); + + r = pNdb->getDictionary()->createTable(tmpTab); + if(r == -1){ + if(!existsOk){ + ndbout << "Error: " << pNdb->getDictionary()->getNdbError() << endl; + break; + } + if(pNdb->getDictionary()->getNdbError().code != 721){ + ndbout << "Error: " << pNdb->getDictionary()->getNdbError() << endl; + break; + } + r = 0; + } + + Uint32 i = 0; + for(i = 0; indexes[i].m_table != 0; i++){ + if(strcmp(indexes[i].m_table, _name) != 0) + continue; + Uint32 j = 0; + while(indexes[i].m_indexes[j] != 0){ + NdbDictionary::Index tmpIndx; + BaseString name; + name.assfmt("%s$NDBT_IDX%d", _name, j); + tmpIndx.setName(name.c_str()); + tmpIndx.setTable(_name); + bool logging = !_temp; + if(strcmp(indexes[i].m_indexes[j], "ORDERED") == 0){ + logging = false; + tmpIndx.setType(NdbDictionary::Index::OrderedIndex); + } else if(strcmp(indexes[i].m_indexes[j], "UNIQUE") == 0){ + tmpIndx.setType(NdbDictionary::Index::UniqueHashIndex); + } else { + ndbout << "Unknown index type"; + abort(); + } + tmpIndx.setLogging(logging); + + j++; + while(indexes[i].m_indexes[j] != 0){ + tmpIndx.addIndexColumn(indexes[i].m_indexes[j]); + j++; + } + j++; + if(pNdb->getDictionary()->createIndex(tmpIndx) != 0){ + ndbout << pNdb->getDictionary()->getNdbError() << endl; + return NDBT_FAILED; + } + } + } + } while(false); - int r = pNdb->getDictionary()->createTable(tmpTab); return r; } @@ -815,7 +909,7 @@ NDBT_Tables::dropAllTables(Ndb* pNdb){ int NDBT_Tables::print(const char * _name){ - const NdbDictionary::Table* tab = NDBT_Tables::getTable(_name); + const NDBT_Table * tab = (const NDBT_Table*)NDBT_Tables::getTable(_name); if (tab == NULL){ ndbout << "Could not print table " << _name << ", it doesn't exist in list of tables " @@ -835,7 +929,7 @@ NDBT_Tables::printAll(){ if (tab == NULL){ abort(); } - ndbout << (* tab) << endl; + ndbout << (* (NDBT_Table*)tab) << endl; } return NDBT_OK; diff --git a/ndb/test/src/NDBT_Test.cpp b/ndb/test/src/NDBT_Test.cpp index 4cd2c96486b..b1691c379a9 100644 --- a/ndb/test/src/NDBT_Test.cpp +++ b/ndb/test/src/NDBT_Test.cpp @@ -132,6 +132,17 @@ void NDBT_Context::setProperty(const char* _name, Uint32 _val){ assert(b == true); NdbMutex_Unlock(propertyMutexPtr); } +void +NDBT_Context::decProperty(const char * name){ + NdbMutex_Lock(propertyMutexPtr); + Uint32 val = 0; + if(props.get(name, &val)){ + assert(val > 0); + props.put(name, (val - 1), true); + } + NdbCondition_Broadcast(propertyCondPtr); + NdbMutex_Unlock(propertyMutexPtr); +} void NDBT_Context::setProperty(const char* _name, const char* _val){ NdbMutex_Lock(propertyMutexPtr); @@ -336,24 +347,24 @@ NDBT_TestCaseImpl1::NDBT_TestCaseImpl1(NDBT_TestSuite* psuite, NDBT_TestCaseImpl1::~NDBT_TestCaseImpl1(){ NdbCondition_Destroy(waitThreadsCondPtr); NdbMutex_Destroy(waitThreadsMutexPtr); - - for(size_t i = 0; i < initializers.size(); i++) + size_t i; + for(i = 0; i < initializers.size(); i++) delete initializers[i]; initializers.clear(); - for(size_t i = 0; i < verifiers.size(); i++) + for(i = 0; i < verifiers.size(); i++) delete verifiers[i]; verifiers.clear(); - for(size_t i = 0; i < finalizers.size(); i++) + for(i = 0; i < finalizers.size(); i++) delete finalizers[i]; finalizers.clear(); - for(size_t i = 0; i < steps.size(); i++) + for(i = 0; i < steps.size(); i++) delete steps[i]; steps.clear(); results.clear(); - for(size_t i = 0; i < testTables.size(); i++) + for(i = 0; i < testTables.size(); i++) delete testTables[i]; testTables.clear(); - for(size_t i = 0; i < testResults.size(); i++) + for(i = 0; i < testResults.size(); i++) delete testResults[i]; testResults.clear(); @@ -487,7 +498,8 @@ void NDBT_TestCaseImpl1::waitSteps(){ waitThreadsMutexPtr); unsigned completedSteps = 0; - for(unsigned i=0; i<steps.size(); i++){ + unsigned i; + for(i=0; i<steps.size(); i++){ if (results[i] != NORESULT){ completedSteps++; if (results[i] == NDBT_OK) @@ -501,7 +513,7 @@ void NDBT_TestCaseImpl1::waitSteps(){ NdbMutex_Unlock(waitThreadsMutexPtr); void *status; - for(unsigned i=0; i<steps.size();i++){ + for(i=0; i<steps.size();i++){ NdbThread_WaitFor(threads[i], &status); NdbThread_Destroy(&threads[i]); } @@ -633,12 +645,12 @@ int NDBT_TestCaseImpl1::runSteps(NDBT_Context* ctx){ numStepsOk = 0; numStepsFail = 0; numStepsCompleted = 0; - - for (unsigned i = 0; i < steps.size(); i++) + unsigned i; + for (i = 0; i < steps.size(); i++) startStepInThread(i, ctx); waitSteps(); - for(unsigned i = 0; i < steps.size(); i++) + for(i = 0; i < steps.size(); i++) if (results[i] != NDBT_OK) res = NDBT_FAILED; return res; @@ -808,18 +820,19 @@ void NDBT_TestSuite::execute(Ndb* ndb, const NdbDictionary::Table* pTab, const NdbDictionary::Table* pTab2 = pDict->getTable(pTab->getName()); if (createTable == true){ - if (pTab2 != 0 && !pTab->equal(* pTab2)){ + if(pTab2 != 0 && pDict->dropTable(pTab->getName()) != 0){ numTestsFail++; numTestsExecuted++; - g_err << "ERROR0: Failed to create table " << pTab->getName() << endl; + g_err << "ERROR0: Failed to drop table " << pTab->getName() << endl; tests[t]->saveTestResult(pTab, FAILED_TO_CREATE); continue; } - - if(pTab2 == 0 && pDict->createTable(* pTab) != 0){ + + if(NDBT_Tables::createTable(ndb, pTab->getName()) != 0){ numTestsFail++; numTestsExecuted++; - g_err << "ERROR1: Failed to create table " << pTab->getName() << endl; + g_err << "ERROR1: Failed to create table " << pTab->getName() + << pDict->getNdbError() << endl; tests[t]->saveTestResult(pTab, FAILED_TO_CREATE); continue; } @@ -994,6 +1007,7 @@ int NDBT_TestSuite::execute(int argc, const char** argv){ res = executeAll(_testname); } else { testSuiteTimer.doStart(); + Ndb ndb("TEST_DB"); ndb.init(); for(int i = optind; i<argc; i++){ executeOne(argv[i], _testname); } @@ -1091,20 +1105,20 @@ void NDBT_TestCaseImpl1::print(){ abort(); } } - - for(unsigned i=0; i<initializers.size(); i++){ + unsigned i; + for(i=0; i<initializers.size(); i++){ ndbout << "Initializers[" << i << "]: " << endl; initializers[i]->print(); } - for(unsigned i=0; i<steps.size(); i++){ + for(i=0; i<steps.size(); i++){ ndbout << "Step[" << i << "]: " << endl; steps[i]->print(); } - for(unsigned i=0; i<verifiers.size(); i++){ + for(i=0; i<verifiers.size(); i++){ ndbout << "Verifier[" << i << "]: " << endl; verifiers[i]->print(); } - for(unsigned i=0; i<finalizers.size(); i++){ + for(i=0; i<finalizers.size(); i++){ ndbout << "Finalizer[" << i << "]: " << endl; finalizers[i]->print(); } @@ -1116,6 +1130,11 @@ void NDBT_Step::print(){ } - - - +template class Vector<NDBT_TestCase*>; +template class Vector<NDBT_TestCaseResult*>; +template class Vector<NDBT_Step*>; +template class Vector<NdbThread*>; +template class Vector<NDBT_Verifier*>; +template class Vector<NDBT_Initializer*>; +template class Vector<NDBT_Finalizer*>; +template class Vector<const NdbDictionary::Table*>; diff --git a/ndb/test/src/NdbBackup.cpp b/ndb/test/src/NdbBackup.cpp index 169034e0c07..a40c6ba7d7c 100644 --- a/ndb/test/src/NdbBackup.cpp +++ b/ndb/test/src/NdbBackup.cpp @@ -69,17 +69,24 @@ NdbBackup::getFileSystemPathForNode(int _node_id){ /** * Fetch configuration from management server */ - ConfigRetriever cr; + ConfigRetriever cr(0, NODE_TYPE_API); + ndb_mgm_configuration * p = 0; - ndb_mgm_configuration * p = cr.getConfig(host, port, 0); - if(p == 0){ - const char * s = cr.getErrorString(); - if(s == 0) - s = "No error given!"; + BaseString tmp; tmp.assfmt("%s:%d", host.c_str(), port); + NdbMgmHandle handle = ndb_mgm_create_handle(); + if(handle == 0 || ndb_mgm_connect(handle, tmp.c_str()) != 0 || + (p = ndb_mgm_get_configuration(handle, 0)) == 0){ - ndbout << "Could not fetch configuration" << endl; - ndbout << s << endl; - return NULL; + const char * s = 0; + if(p == 0 && handle != 0){ + s = ndb_mgm_get_latest_error_msg(handle); + if(s == 0) + s = "No error given!"; + + ndbout << "Could not fetch configuration" << endl; + ndbout << s << endl; + return NULL; + } } /** @@ -90,7 +97,8 @@ NdbBackup::getFileSystemPathForNode(int _node_id){ ndbout << "Invalid configuration fetched, DB missing" << endl; return NULL; } - unsigned int type = 123456; + + unsigned int type = NODE_TYPE_DB + 1; if(iter.get(CFG_TYPE_OF_SECTION, &type) || type != NODE_TYPE_DB){ ndbout <<"type = " << type << endl; ndbout <<"Invalid configuration fetched, I'm wrong type of node" << endl; @@ -141,31 +149,18 @@ NdbBackup::execRestore(bool _restore_data, ndbout << "res: " << res << endl; -#if 0 - snprintf(buf, 255, "ndb_restore -c \"nodeid=%d;host=%s\" -n %d -b %d %s %s %s/BACKUP/BACKUP-%d", - ownNodeId, - addr, - _node_id, - _backup_id, - _restore_data?"-r":"", - _restore_meta?"-m":"", - path, - _backup_id); - + snprintf(buf, 255, "%sndb_restore -c \"host=%s\" -n %d -b %d %s %s .", +#if 1 + "", +#else + "valgrind --leak-check=yes -v " #endif - - snprintf(buf, 255, "ndb_restore -c \"nodeid=%d;host=%s\" -n %d -b %d %s %s .", - ownNodeId, - addr, + addr.c_str(), _node_id, _backup_id, _restore_data?"-r":"", _restore_meta?"-m":""); - // path, - // _backup_id); - - ndbout << "buf: "<< buf <<endl; res = system(buf); diff --git a/ndb/test/src/NdbRestarter.cpp b/ndb/test/src/NdbRestarter.cpp index b731cccb259..4d6d3ddc001 100644 --- a/ndb/test/src/NdbRestarter.cpp +++ b/ndb/test/src/NdbRestarter.cpp @@ -33,13 +33,11 @@ NdbRestarter::NdbRestarter(const char* _addr): connected(false), - addr(_addr), - host(NULL), port(-1), handle(NULL), m_config(0) { - if (addr == NULL){ + if (_addr == NULL){ LocalConfig lcfg; if(!lcfg.init()){ lcfg.printError(); @@ -48,32 +46,32 @@ NdbRestarter::NdbRestarter(const char* _addr): return; } - if (lcfg.items == 0){ + if (lcfg.ids.size() == 0){ g_err << "NdbRestarter - No management servers configured in local config file" << endl; return; } - for (int i = 0; i<lcfg.items; i++){ - MgmtSrvrId * m = lcfg.ids[i]; + for (int i = 0; i<lcfg.ids.size(); i++){ + MgmtSrvrId * m = &lcfg.ids[i]; switch(m->type){ case MgmId_TCP: char buf[255]; - snprintf(buf, 255, "%s:%d", m->data.tcp.remoteHost, m->data.tcp.port); - addr = strdup(buf); - host = strdup(m->data.tcp.remoteHost); - port = m->data.tcp.port; + snprintf(buf, 255, "%s:%d", m->name.c_str(), m->port); + addr.assign(buf); + host.assign(m->name.c_str()); + port = m->port; + return; break; case MgmId_File: break; default: break; } - if (addr != NULL) - break; } + } else { + addr.assign(_addr); } - } NdbRestarter::~NdbRestarter(){ @@ -398,10 +396,10 @@ NdbRestarter::connect(){ g_err << "handle == NULL" << endl; return -1; } - g_info << "Connecting to mgmsrv at " << addr << endl; - if (ndb_mgm_connect(handle, addr) == -1) { + g_info << "Connecting to mgmsrv at " << addr.c_str() << endl; + if (ndb_mgm_connect(handle, addr.c_str()) == -1) { MGMERR(handle); - g_err << "Connection to " << addr << " failed" << endl; + g_err << "Connection to " << addr.c_str() << " failed" << endl; return -1; } @@ -672,3 +670,5 @@ NdbRestarter::getConfig(){ m_config = ndb_mgm_get_configuration(handle, 0); return m_config; } + +template class Vector<ndb_mgm_node_state>; diff --git a/ndb/test/src/NdbRestarts.cpp b/ndb/test/src/NdbRestarts.cpp index f6a85d69fc2..b649a60d98b 100644 --- a/ndb/test/src/NdbRestarts.cpp +++ b/ndb/test/src/NdbRestarts.cpp @@ -625,9 +625,9 @@ int restartNFDuringNR(NdbRestarter& _restarter, const NdbRestarts::NdbRestart* _restart){ myRandom48Init(NdbTick_CurrentMillisecond()); - + int i; const int sz = sizeof(NFDuringNR_codes)/sizeof(NFDuringNR_codes[0]); - for(int i = 0; i<sz; i++){ + for(i = 0; i<sz; i++){ int randomId = myRandom48(_restarter.getNumDbNodes()); int nodeId = _restarter.getDbNodeId(randomId); int error = NFDuringNR_codes[i]; @@ -673,7 +673,7 @@ int restartNFDuringNR(NdbRestarter& _restarter, if(NdbEnv_GetEnv("USER", buf, 256) == 0 || strcmp(buf, "ejonore") != 0) return NDBT_OK; - for(int i = 0; i<sz; i++){ + for(i = 0; i<sz; i++){ const int randomId = myRandom48(_restarter.getNumDbNodes()); int nodeId = _restarter.getDbNodeId(randomId); const int error = NFDuringNR_codes[i]; @@ -753,14 +753,14 @@ NRDuringLCP_NonMaster_codes[] = { int restartNodeDuringLCP(NdbRestarter& _restarter, const NdbRestarts::NdbRestart* _restart) { - + int i; // Master int val = DumpStateOrd::DihMinTimeBetweenLCP; CHECK(_restarter.dumpStateAllNodes(&val, 1) == 0, "Failed to set LCP to min value"); // Set LCP to min val int sz = sizeof(NRDuringLCP_Master_codes)/ sizeof(NRDuringLCP_Master_codes[0]); - for(int i = 0; i<sz; i++) { + for(i = 0; i<sz; i++) { int error = NRDuringLCP_Master_codes[i]; int masterNodeId = _restarter.getMasterNodeId(); @@ -798,7 +798,7 @@ int restartNodeDuringLCP(NdbRestarter& _restarter, // NON-Master sz = sizeof(NRDuringLCP_NonMaster_codes)/ sizeof(NRDuringLCP_NonMaster_codes[0]); - for(int i = 0; i<sz; i++) { + for(i = 0; i<sz; i++) { int error = NRDuringLCP_NonMaster_codes[i]; int nodeId = getRandomNodeId(_restarter); diff --git a/ndb/test/src/UtilTransactions.cpp b/ndb/test/src/UtilTransactions.cpp index 3ef31a2f535..9f3f1d33587 100644 --- a/ndb/test/src/UtilTransactions.cpp +++ b/ndb/test/src/UtilTransactions.cpp @@ -47,10 +47,14 @@ UtilTransactions::clearTable(Ndb* pNdb, } } + int UtilTransactions::clearTable1(Ndb* pNdb, int records, int parallelism){ +#if 1 + return clearTable3(pNdb, records, 1); +#else // Scan all records exclusive and delete // them one by one int retryAttempt = 0; @@ -191,12 +195,16 @@ UtilTransactions::clearTable1(Ndb* pNdb, return NDBT_OK; } return NDBT_FAILED; +#endif } int UtilTransactions::clearTable2(Ndb* pNdb, int records, int parallelism){ +#if 1 + return clearTable3(pNdb, records, parallelism); +#else // Scan all records exclusive and delete // them one by one int retryAttempt = 0; @@ -336,6 +344,7 @@ UtilTransactions::clearTable2(Ndb* pNdb, return NDBT_OK; } return NDBT_FAILED; +#endif } int @@ -403,7 +412,7 @@ UtilTransactions::clearTable3(Ndb* pNdb, if(check != -1){ check = pTrans->execute(Commit); - pTrans->releaseCompletedOperations(); + pTrans->restart(); } err = pTrans->getNdbError(); @@ -451,7 +460,7 @@ UtilTransactions::copyTableData(Ndb* pNdb, int parallelism = 240; int check; NdbConnection *pTrans; - NdbOperation *pOp; + NdbScanOperation *pOp; NDBT_ResultRow row(tab); while (true){ @@ -477,14 +486,15 @@ UtilTransactions::copyTableData(Ndb* pNdb, return NDBT_FAILED; } - pOp = pTrans->getNdbOperation(tab.getName()); + pOp = pTrans->getNdbScanOperation(tab.getName()); if (pOp == NULL) { ERR(pTrans->getNdbError()); pNdb->closeTransaction(pTrans); return NDBT_FAILED; } - check = pOp->openScanRead(parallelism); + NdbResultSet* rs = pOp->readTuples(NdbScanOperation::LM_Read, + parallelism); if( check == -1 ) { ERR(pTrans->getNdbError()); pNdb->closeTransaction(pTrans); @@ -508,7 +518,7 @@ UtilTransactions::copyTableData(Ndb* pNdb, } } - check = pTrans->executeScan(); + check = pTrans->execute(NoCommit); if( check == -1 ) { ERR(pTrans->getNdbError()); pNdb->closeTransaction(pTrans); @@ -516,39 +526,27 @@ UtilTransactions::copyTableData(Ndb* pNdb, } int eof; - NdbConnection* pInsTrans; - - while((eof = pTrans->nextScanResult(true)) == 0){ - pInsTrans = pNdb->startTransaction(); - if (pInsTrans == NULL) { - const NdbError err = pNdb->getNdbError(); - ERR(err); - pNdb->closeTransaction(pInsTrans); - return NDBT_FAILED; - } + while((eof = rs->nextResult(true)) == 0){ do { insertedRows++; - if (addRowToInsert(pNdb, pInsTrans, row, destName) != 0){ - pNdb->closeTransaction(pInsTrans); + if (addRowToInsert(pNdb, pTrans, row, destName) != 0){ pNdb->closeTransaction(pTrans); return NDBT_FAILED; } - } while((eof = pTrans->nextScanResult(false)) == 0); - - check = pInsTrans->execute(Commit); + } while((eof = rs->nextResult(false)) == 0); + + check = pTrans->execute(Commit); + pTrans->restart(); if( check == -1 ) { - const NdbError err = pInsTrans->getNdbError(); + const NdbError err = pTrans->getNdbError(); ERR(err); - pNdb->closeTransaction(pInsTrans); pNdb->closeTransaction(pTrans); return NDBT_FAILED; } - pNdb->closeTransaction(pInsTrans); - } if (eof == -1) { const NdbError err = pTrans->getNdbError(); - + if (err.status == NdbError::TemporaryError){ ERR(err); pNdb->closeTransaction(pTrans); @@ -562,30 +560,17 @@ UtilTransactions::copyTableData(Ndb* pNdb, pNdb->closeTransaction(pTrans); return NDBT_FAILED; } - + pNdb->closeTransaction(pTrans); - + g_info << insertedRows << " rows copied" << endl; - + return NDBT_OK; } return NDBT_FAILED; } int -UtilTransactions::addRowToDelete(Ndb* pNdb, - NdbConnection* pDelTrans, - NdbOperation* pOrgOp){ - - NdbOperation* pDelOp = pOrgOp->takeOverForDelete(pDelTrans); - if (pDelOp == NULL){ - ERR(pNdb->getNdbError()); - return NDBT_FAILED; - } - return NDBT_OK; -} - -int UtilTransactions::addRowToInsert(Ndb* pNdb, NdbConnection* pInsTrans, NDBT_ResultRow & row, @@ -621,101 +606,6 @@ UtilTransactions::addRowToInsert(Ndb* pNdb, return NDBT_OK; } -// Take over one record from pOrgOp and delete it -int -UtilTransactions::takeOverAndDeleteRecord(Ndb* pNdb, - NdbOperation* pOrgOp){ - - int retryAttempt = 0; - const int retryMax = 10; - int check; - NdbConnection *pDelTrans; - NdbOperation *pDelOp; - - while (true){ - - if (retryAttempt >= retryMax){ - g_info << "ERROR: has retried this operation " << retryAttempt - << " times, failing!" << endl; - return NDBT_FAILED; - } - - pDelTrans = pNdb->startTransaction(); - if (pDelTrans == NULL) { - const NdbError err = pNdb->getNdbError(); - - if (err.status == NdbError::TemporaryError){ - ERR(err); - NdbSleep_MilliSleep(50); - retryAttempt++; - continue; - } - ERR(err); - return NDBT_FAILED; - } - - if ((pDelOp = pOrgOp->takeOverForDelete(pDelTrans)) == NULL){ - ERR(pNdb->getNdbError()); - return NDBT_FAILED; - } - -#if 0 - // It should not be necessary to call deleteTuple HERE!!! - check = pDelOp->deleteTuple(); - if( check == -1 ) { - ERR(pDelTrans->getNdbError()); - pNdb->closeTransaction(pDelTrans); - return NDBT_FAILED; - } -#endif - - check = pDelTrans->execute( Commit ); - if(check == -1 ) { - const NdbError err = pDelTrans->getNdbError(); - pNdb->closeTransaction(pDelTrans); - - ERR(err); - if(err.code == 250 || err.code == 499) - return RESTART_SCAN; - - switch(err.status){ - case NdbError::Success: - g_info << "ERROR: NdbError reports success when transcaction failed" - << endl; - RETURN_FAIL(err); - break; - - case NdbError::TemporaryError: - NdbSleep_MilliSleep(50+50*retryAttempt); - retryAttempt++; - continue; - break; - - case NdbError::UnknownResult: - RETURN_FAIL(err); - break; - - default: - case NdbError::PermanentError: - switch (err.classification){ - default: - RETURN_FAIL(err); - break; - } - break; - } - } - else{ - pNdb->closeTransaction(pDelTrans); - } - - return NDBT_OK; - } - return NDBT_FAILED; -} - - - int UtilTransactions::scanReadRecords(Ndb* pNdb, @@ -730,7 +620,7 @@ UtilTransactions::scanReadRecords(Ndb* pNdb, const int retryMax = 100; int check; NdbConnection *pTrans; - NdbOperation *pOp; + NdbScanOperation *pOp; NDBT_ResultRow row(tab); while (true){ @@ -755,18 +645,18 @@ UtilTransactions::scanReadRecords(Ndb* pNdb, return NDBT_FAILED; } - pOp = pTrans->getNdbOperation(tab.getName()); + pOp = pTrans->getNdbScanOperation(tab.getName()); if (pOp == NULL) { ERR(pTrans->getNdbError()); pNdb->closeTransaction(pTrans); return NDBT_FAILED; } - if (exclusive == true) - check = pOp->openScanExclusive(parallelism); - else - check = pOp->openScanRead(parallelism); - if( check == -1 ) { + NdbResultSet * rs = pOp->readTuples(exclusive ? + NdbScanOperation::LM_Exclusive : + NdbScanOperation::LM_Read, + 0, parallelism); + if( rs == 0 ) { ERR(pTrans->getNdbError()); pNdb->closeTransaction(pTrans); return NDBT_FAILED; @@ -778,7 +668,7 @@ UtilTransactions::scanReadRecords(Ndb* pNdb, pNdb->closeTransaction(pTrans); return NDBT_FAILED; } - + // Call getValue for all the attributes supplied in attrib_list // ************************************************ for (int a = 0; a < noAttribs; a++){ @@ -793,8 +683,8 @@ UtilTransactions::scanReadRecords(Ndb* pNdb, } } // ************************************************* - - check = pTrans->executeScan(); + + check = pTrans->execute(NoCommit); if( check == -1 ) { const NdbError err = pTrans->getNdbError(); @@ -812,15 +702,14 @@ UtilTransactions::scanReadRecords(Ndb* pNdb, int eof; int rows = 0; - eof = pTrans->nextScanResult(); - while(eof == 0){ + + while((eof = rs->nextResult()) == 0){ rows++; // Call callback for each record returned if(fn != NULL) fn(&row); - eof = pTrans->nextScanResult(); } if (eof == -1) { const NdbError err = pTrans->getNdbError(); @@ -856,14 +745,15 @@ UtilTransactions::selectCount(Ndb* pNdb, int parallelism, int* count_rows, ScanLock lock, - NdbConnection* pBuddyTrans){ + NdbConnection* pTrans){ int retryAttempt = 0; const int retryMax = 100; int check; - NdbConnection *pTrans; - NdbOperation *pOp; + NdbScanOperation *pOp; + if(!pTrans) + pTrans = pNdb->startTransaction(); while (true){ if (retryAttempt >= retryMax){ @@ -871,39 +761,27 @@ UtilTransactions::selectCount(Ndb* pNdb, << " times, failing!" << endl; return NDBT_FAILED; } - - pTrans = pNdb->hupp(pBuddyTrans); - if (pTrans == NULL) { - const NdbError err = pNdb->getNdbError(); - - if (err.status == NdbError::TemporaryError){ - NdbSleep_MilliSleep(50); - retryAttempt++; - continue; - } - ERR(err); - return NDBT_FAILED; - } - pOp = pTrans->getNdbOperation(tab.getName()); + pOp = pTrans->getNdbScanOperation(tab.getName()); if (pOp == NULL) { ERR(pTrans->getNdbError()); pNdb->closeTransaction(pTrans); return NDBT_FAILED; } + NdbResultSet * rs; switch(lock){ case SL_ReadHold: - check = pOp->openScanReadHoldLock(parallelism); + rs = pOp->readTuples(NdbScanOperation::LM_Read); break; case SL_Exclusive: - check = pOp->openScanExclusive(parallelism); + rs = pOp->readTuples(NdbScanOperation::LM_Exclusive); break; case SL_Read: default: - check = pOp->openScanRead(parallelism); + rs = pOp->readTuples(NdbScanOperation::LM_CommittedRead); } - if( check == -1 ) { + if( rs == 0) { ERR(pTrans->getNdbError()); pNdb->closeTransaction(pTrans); return NDBT_FAILED; @@ -922,9 +800,9 @@ UtilTransactions::selectCount(Ndb* pNdb, return NDBT_FAILED; } } - - - check = pTrans->executeScan(); + + + check = pTrans->execute(NoCommit); if( check == -1 ) { ERR(pTrans->getNdbError()); pNdb->closeTransaction(pTrans); @@ -933,15 +811,14 @@ UtilTransactions::selectCount(Ndb* pNdb, int eof; int rows = 0; - eof = pTrans->nextScanResult(); + - while(eof == 0){ + while((eof = rs->nextResult()) == 0){ rows++; - eof = pTrans->nextScanResult(); } if (eof == -1) { const NdbError err = pTrans->getNdbError(); - + if (err.status == NdbError::TemporaryError){ pNdb->closeTransaction(pTrans); NdbSleep_MilliSleep(50); @@ -952,7 +829,7 @@ UtilTransactions::selectCount(Ndb* pNdb, pNdb->closeTransaction(pTrans); return NDBT_FAILED; } - + pNdb->closeTransaction(pTrans); if (count_rows != NULL){ @@ -963,7 +840,6 @@ UtilTransactions::selectCount(Ndb* pNdb, } return NDBT_FAILED; } - int UtilTransactions::verifyIndex(Ndb* pNdb, @@ -1028,7 +904,7 @@ UtilTransactions::scanAndCompareUniqueIndex(Ndb* pNdb, const int retryMax = 100; int check; NdbConnection *pTrans; - NdbOperation *pOp; + NdbScanOperation *pOp; NDBT_ResultRow row(tab); parallelism = 1; @@ -1055,20 +931,21 @@ UtilTransactions::scanAndCompareUniqueIndex(Ndb* pNdb, return NDBT_FAILED; } - pOp = pTrans->getNdbOperation(tab.getName()); + pOp = pTrans->getNdbScanOperation(tab.getName()); if (pOp == NULL) { ERR(pTrans->getNdbError()); pNdb->closeTransaction(pTrans); return NDBT_FAILED; } + NdbResultSet* rs; if(transactional){ - check = pOp->openScanReadHoldLock(parallelism); + rs = pOp->readTuples(NdbScanOperation::LM_Read, 0, parallelism); } else { - check = pOp->openScanRead(parallelism); + rs = pOp->readTuples(NdbScanOperation::LM_CommittedRead, 0, parallelism); } - - if( check == -1 ) { + + if( rs == 0 ) { ERR(pTrans->getNdbError()); pNdb->closeTransaction(pTrans); return NDBT_FAILED; @@ -1091,10 +968,10 @@ UtilTransactions::scanAndCompareUniqueIndex(Ndb* pNdb, } } - check = pTrans->executeScan(); + check = pTrans->execute(NoCommit); if( check == -1 ) { const NdbError err = pTrans->getNdbError(); - + if (err.status == NdbError::TemporaryError){ ERR(err); pNdb->closeTransaction(pTrans); @@ -1109,14 +986,14 @@ UtilTransactions::scanAndCompareUniqueIndex(Ndb* pNdb, int eof; int rows = 0; - eof = pTrans->nextScanResult(); - while(eof == 0){ + + while((eof = rs->nextResult()) == 0){ rows++; - + // ndbout << row.c_str().c_str() << endl; - - + + if (readRowFromTableAndIndex(pNdb, pTrans, indexName, @@ -1124,11 +1001,6 @@ UtilTransactions::scanAndCompareUniqueIndex(Ndb* pNdb, pNdb->closeTransaction(pTrans); return NDBT_FAILED; } - - - - - eof = pTrans->nextScanResult(); } if (eof == -1) { const NdbError err = pTrans->getNdbError(); @@ -1168,7 +1040,7 @@ UtilTransactions::readRowFromTableAndIndex(Ndb* pNdb, NdbDictionary::Index::Type indexType= pIndex->getType(); int retryAttempt = 0; const int retryMax = 100; - int check; + int check, a; NdbConnection *pTrans1=NULL; NdbResultSet *cursor= NULL; NdbOperation *pOp; @@ -1228,7 +1100,7 @@ UtilTransactions::readRowFromTableAndIndex(Ndb* pNdb, #if VERBOSE printf("PK: "); #endif - for(int a = 0; a<tab.getNoOfColumns(); a++){ + for(a = 0; a<tab.getNoOfColumns(); a++){ const NdbDictionary::Column* attr = tab.getColumn(a); if (attr->getPrimaryKey() == true){ if (pOp->equal(attr->getName(), row.attributeStore(a)->aRef()) != 0){ @@ -1247,7 +1119,7 @@ UtilTransactions::readRowFromTableAndIndex(Ndb* pNdb, #if VERBOSE printf("Reading %u attributes: ", tab.getNoOfColumns()); #endif - for(int a = 0; a<tab.getNoOfColumns(); a++){ + for(a = 0; a<tab.getNoOfColumns(); a++){ if((tabRow.attributeStore(a) = pOp->getValue(tab.getColumn(a)->getName())) == 0) { ERR(pTrans1->getNdbError()); @@ -1265,13 +1137,13 @@ UtilTransactions::readRowFromTableAndIndex(Ndb* pNdb, * Read the record from INDEX_TABLE */ NdbIndexOperation* pIndexOp= NULL; - NdbScanOperation *pScanOp= NULL; + NdbIndexScanOperation *pScanOp= NULL; { void* pOpCheck= NULL; if (indexType == NdbDictionary::Index::UniqueHashIndex) { pOpCheck= pIndexOp= pTrans1->getNdbIndexOperation(indexName, tab.getName()); } else { - pOpCheck= pScanOp= pTrans1->getNdbScanOperation(indexName, tab.getName()); + pOpCheck= pScanOp= pTrans1->getNdbIndexScanOperation(indexName, tab.getName()); } if (pOpCheck == NULL) { @@ -1298,7 +1170,7 @@ UtilTransactions::readRowFromTableAndIndex(Ndb* pNdb, #if VERBOSE printf("SI: "); #endif - for(int a = 0; a<(int)pIndex->getNoOfColumns(); a++){ + for(a = 0; a<(int)pIndex->getNoOfColumns(); a++){ const NdbDictionary::Column * col = pIndex->getColumn(a); int r; @@ -1308,7 +1180,7 @@ UtilTransactions::readRowFromTableAndIndex(Ndb* pNdb, // setBound not possible for null attributes if ( !row.attributeStore(col->getName())->isNULL() ) { r = pScanOp->setBound(col->getName(), - NdbOperation::BoundEQ, + NdbIndexScanOperation::BoundEQ, row.attributeStore(col->getName())->aRef()); } } @@ -1328,7 +1200,7 @@ UtilTransactions::readRowFromTableAndIndex(Ndb* pNdb, #if VERBOSE printf("Reading %u attributes: ", tab.getNoOfColumns()); #endif - for(int a = 0; a<tab.getNoOfColumns(); a++){ + for(a = 0; a<tab.getNoOfColumns(); a++){ void* pCheck; if (pIndexOp) diff --git a/ndb/test/tools/cpcc.cpp b/ndb/test/tools/cpcc.cpp index e768d707bbc..e30d458ffee 100644 --- a/ndb/test/tools/cpcc.cpp +++ b/ndb/test/tools/cpcc.cpp @@ -192,7 +192,7 @@ main(int argc, const char** argv){ ,{ "rm", 0, arg_flag, &rm, "-c rm", "undefine process(es)" } }; const int num_args = 10; - + int i; int optind = 0; char desc[] = "[host:[port]]\n"; @@ -215,13 +215,13 @@ main(int argc, const char** argv){ Expression * m_expr = 0; - for(int i = optind; i<argc; i++){ + for(i = optind; i<argc; i++){ add_host(g_hosts, argv[i]); } OrExpr * orE = new OrExpr(new Operate(cmd, g_settings), true); m_expr = orE; - for(int i = optind; i<argc; i++){ + for(i = optind; i<argc; i++){ BaseString tmp(argv[i]); Vector<BaseString> split; tmp.split(split, ":"); @@ -347,3 +347,5 @@ Operate::evaluate(SimpleCpcClient* c, const SimpleCpcClient::Process & pp){ return true; } +template class Vector<Expression*>; +template class Vector<SimpleCpcClient*>; diff --git a/ndb/test/tools/create_index.cpp b/ndb/test/tools/create_index.cpp index dc9e6c606d6..f883755ea24 100644 --- a/ndb/test/tools/create_index.cpp +++ b/ndb/test/tools/create_index.cpp @@ -29,10 +29,13 @@ main(int argc, const char** argv){ const char* _dbname = "TEST_DB"; int _help = 0; + int _ordered, _pk; 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", "" }, { "usage", '?', arg_flag, &_help, "Print help", "" } }; @@ -73,14 +76,21 @@ main(int argc, const char** argv){ } NdbDictionary::Index ind; + if(_ordered){ + ind.setType(NdbDictionary::Index::OrderedIndex); + ind.setLogging(false); + } else { + ind.setType(NdbDictionary::Index::UniqueHashIndex); + } char buf[512]; - sprintf(buf, "IND_%s", argv[i]); + sprintf(buf, "IND_%s_%s_%c", + argv[i], (_pk ? "PK" : "FULL"), (_ordered ? 'O' : 'U')); ind.setName(buf); ind.setTable(argv[i]); - ind.setType(NdbDictionary::Index::UniqueHashIndex); - for(int c = 0; c<tab->getNoOfColumns(); c++) - ind.addIndexColumn(tab->getColumn(c)->getName()); - + for(int c = 0; c<tab->getNoOfColumns(); c++){ + if(!_pk || tab->getColumn(c)->getPrimaryKey()) + ind.addIndexColumn(tab->getColumn(c)->getName()); + } ndbout << "creating index " << buf << " on table " << argv[i] << "..."; const int res = dict->createIndex(ind); if(res != 0) diff --git a/ndb/test/tools/hugoPkReadRecord.cpp b/ndb/test/tools/hugoPkReadRecord.cpp index ac17ffffee8..85f20bd2060 100644 --- a/ndb/test/tools/hugoPkReadRecord.cpp +++ b/ndb/test/tools/hugoPkReadRecord.cpp @@ -43,7 +43,7 @@ int main(int argc, const char** argv) }; int num_args = sizeof(args) / sizeof(args[0]); - int optind = 0; + int optind = 0, i; if(getarg(args, num_args, argc, argv, &optind) || argv[optind] == NULL) { arg_printusage(args, num_args, argv[0], "table name\n"); @@ -80,7 +80,7 @@ int main(int argc, const char** argv) } op->readTuple(); NdbRecAttr** data = new NdbRecAttr*[table->getNoOfColumns()]; - for (int i = 0; i < table->getNoOfColumns(); i++) + for (i = 0; i < table->getNoOfColumns(); i++) { const NdbDictionary::Column* c = table->getColumn(i); if (c->getPrimaryKey()) @@ -93,11 +93,10 @@ int main(int argc, const char** argv) data[i] = op->getValue(c->getName(), NULL); } } - if (conn->execute(Commit) == 0) { // Print column names - for (int i = 0; i < table->getNoOfColumns(); i++) + for (i = 0; i < table->getNoOfColumns(); i++) { const NdbDictionary::Column* c = table->getColumn(i); @@ -111,7 +110,7 @@ int main(int argc, const char** argv) { g_info << hex; } - for (int i = 0; i < table->getNoOfColumns(); i++) + for (i = 0; i < table->getNoOfColumns(); i++) { NdbRecAttr* a = data[i]; switch(a->getType()) |