summaryrefslogtreecommitdiff
path: root/ndb/test
diff options
context:
space:
mode:
Diffstat (limited to 'ndb/test')
-rw-r--r--ndb/test/include/HugoCalculator.hpp9
-rw-r--r--ndb/test/include/HugoOperations.hpp29
-rw-r--r--ndb/test/include/HugoTransactions.hpp8
-rw-r--r--ndb/test/include/NDBT_Error.hpp6
-rw-r--r--ndb/test/include/NDBT_ResultRow.hpp7
-rw-r--r--ndb/test/include/NDBT_Tables.hpp6
-rw-r--r--ndb/test/include/NDBT_Test.hpp22
-rw-r--r--ndb/test/include/NdbSchemaOp.hpp51
-rw-r--r--ndb/test/include/UtilTransactions.hpp30
-rw-r--r--ndb/test/ndbapi/Makefile.am12
-rw-r--r--ndb/test/ndbapi/ScanFunctions.hpp23
-rw-r--r--ndb/test/ndbapi/ScanInterpretTest.hpp17
-rw-r--r--ndb/test/ndbapi/bank/Bank.cpp64
-rw-r--r--ndb/test/ndbapi/bank/Bank.hpp2
-rw-r--r--ndb/test/ndbapi/bank/BankLoad.cpp11
-rw-r--r--ndb/test/ndbapi/bank/bankCreator.cpp8
-rw-r--r--ndb/test/ndbapi/bank/bankMakeGL.cpp8
-rw-r--r--ndb/test/ndbapi/bank/bankSumAccounts.cpp8
-rw-r--r--ndb/test/ndbapi/bank/bankTimer.cpp8
-rw-r--r--ndb/test/ndbapi/bank/bankTransactionMaker.cpp8
-rw-r--r--ndb/test/ndbapi/bank/bankValidateAllGLs.cpp8
-rw-r--r--ndb/test/ndbapi/bank/testBank.cpp12
-rw-r--r--ndb/test/ndbapi/bench/userInterface.cpp6
-rw-r--r--ndb/test/ndbapi/bench/userInterface.h2
-rw-r--r--ndb/test/ndbapi/create_all_tabs.cpp7
-rw-r--r--ndb/test/ndbapi/create_tab.cpp8
-rw-r--r--ndb/test/ndbapi/drop_all_tabs.cpp8
-rw-r--r--ndb/test/ndbapi/flexAsynch.cpp16
-rw-r--r--ndb/test/ndbapi/flexBench.cpp15
-rw-r--r--ndb/test/ndbapi/flexHammer.cpp13
-rw-r--r--ndb/test/ndbapi/flexTT.cpp13
-rw-r--r--ndb/test/ndbapi/flex_bench_mysql.cpp2
-rw-r--r--ndb/test/ndbapi/slow_select.cpp28
-rw-r--r--ndb/test/ndbapi/testBackup.cpp16
-rw-r--r--ndb/test/ndbapi/testBitfield.cpp198
-rw-r--r--ndb/test/ndbapi/testBlobs.cpp37
-rw-r--r--ndb/test/ndbapi/testDataBuffers.cpp21
-rw-r--r--ndb/test/ndbapi/testDeadlock.cpp27
-rw-r--r--ndb/test/ndbapi/testDict.cpp171
-rw-r--r--ndb/test/ndbapi/testIndex.cpp19
-rw-r--r--ndb/test/ndbapi/testLcp.cpp12
-rw-r--r--ndb/test/ndbapi/testNdbApi.cpp209
-rw-r--r--ndb/test/ndbapi/testNodeRestart.cpp2
-rw-r--r--ndb/test/ndbapi/testOIBasic.cpp2770
-rw-r--r--ndb/test/ndbapi/testPartitioning.cpp430
-rw-r--r--ndb/test/ndbapi/testReadPerf.cpp32
-rw-r--r--ndb/test/ndbapi/testScan.cpp77
-rw-r--r--ndb/test/ndbapi/testScanPerf.cpp105
-rw-r--r--ndb/test/ndbapi/testTimeout.cpp62
-rw-r--r--ndb/test/ndbapi/test_event.cpp390
-rw-r--r--ndb/test/ndbapi/test_event_multi_table.cpp487
-rw-r--r--ndb/test/run-test/16node-tests.txt733
-rw-r--r--ndb/test/run-test/Makefile.am2
-rw-r--r--ndb/test/run-test/basic.txt2
-rw-r--r--ndb/test/run-test/daily-basic-tests.txt95
-rw-r--r--ndb/test/run-test/daily-devel-tests.txt31
-rw-r--r--ndb/test/src/HugoAsynchTransactions.cpp11
-rw-r--r--ndb/test/src/HugoCalculator.cpp298
-rw-r--r--ndb/test/src/HugoOperations.cpp360
-rw-r--r--ndb/test/src/HugoTransactions.cpp843
-rw-r--r--ndb/test/src/NDBT_ResultRow.cpp9
-rw-r--r--ndb/test/src/NDBT_Tables.cpp19
-rw-r--r--ndb/test/src/NDBT_Test.cpp50
-rw-r--r--ndb/test/src/NdbBackup.cpp2
-rw-r--r--ndb/test/src/NdbRestarts.cpp30
-rw-r--r--ndb/test/src/NdbSchemaOp.cpp3
-rw-r--r--ndb/test/src/UtilTransactions.cpp755
-rw-r--r--ndb/test/tools/Makefile.am3
-rw-r--r--ndb/test/tools/copy_tab.cpp9
-rw-r--r--ndb/test/tools/create_index.cpp7
-rw-r--r--ndb/test/tools/hugoFill.cpp7
-rw-r--r--ndb/test/tools/hugoLoad.cpp7
-rw-r--r--ndb/test/tools/hugoLockRecords.cpp7
-rw-r--r--ndb/test/tools/hugoPkDelete.cpp7
-rw-r--r--ndb/test/tools/hugoPkRead.cpp7
-rw-r--r--ndb/test/tools/hugoPkReadRecord.cpp7
-rw-r--r--ndb/test/tools/hugoPkUpdate.cpp7
-rw-r--r--ndb/test/tools/hugoScanRead.cpp10
-rw-r--r--ndb/test/tools/hugoScanUpdate.cpp7
-rw-r--r--ndb/test/tools/verify_index.cpp7
80 files changed, 6187 insertions, 2688 deletions
diff --git a/ndb/test/include/HugoCalculator.hpp b/ndb/test/include/HugoCalculator.hpp
index b782eb003a3..03de46cd7ea 100644
--- a/ndb/test/include/HugoCalculator.hpp
+++ b/ndb/test/include/HugoCalculator.hpp
@@ -31,14 +31,7 @@ class HugoCalculator {
public:
HugoCalculator(const NdbDictionary::Table& tab);
Int32 calcValue(int record, int attrib, int updates) const;
-#if 0
- U_Int32 calcValue(int record, int attrib, int updates) const;
- U_Int64 calcValue(int record, int attrib, int updates) const;
- Int64 calcValue(int record, int attrib, int updates) const;
- float calcValue(int record, int attrib, int updates) const;
- double calcValue(int record, int attrib, int updates) const;
-#endif
- const char* calcValue(int record, int attrib, int updates, char* buf) const;
+ const char* calcValue(int record, int attrib, int updates, char* buf, int len) const;
int verifyRowValues(NDBT_ResultRow* const pRow) const;
int getIdValue(NDBT_ResultRow* const pRow) const;
diff --git a/ndb/test/include/HugoOperations.hpp b/ndb/test/include/HugoOperations.hpp
index 34b2edc2ae8..82fd5529fa2 100644
--- a/ndb/test/include/HugoOperations.hpp
+++ b/ndb/test/include/HugoOperations.hpp
@@ -24,11 +24,14 @@
class HugoOperations : public UtilTransactions {
public:
- HugoOperations(const NdbDictionary::Table&);
+ HugoOperations(const NdbDictionary::Table&,
+ const NdbDictionary::Index* idx = 0);
+
~HugoOperations();
int startTransaction(Ndb*);
+ int setTransaction(NdbTransaction*);
int closeTransaction(Ndb*);
- NdbConnection* getTransaction();
+ NdbTransaction* getTransaction();
void refresh();
void setTransactionId(Uint64);
@@ -42,6 +45,10 @@ public:
int recordNo,
int numRecords = 1,
int updatesValue = 0);
+
+ int pkWritePartialRecord(Ndb*,
+ int recordNo,
+ int numRecords = 1);
int pkReadRecord(Ndb*,
int recordNo,
@@ -73,10 +80,13 @@ public:
int attrId,
int rowId,
int updateId);
+
int equalForAttr(NdbOperation*,
int attrId,
int rowId);
-
+
+ int setValues(NdbOperation*, int rowId, int updateId);
+
int verifyUpdatesValue(int updatesValue, int _numRows = 0);
int indexReadRecords(Ndb*, const char * idxName, int recordNo,
@@ -93,8 +103,11 @@ public:
NdbScanOperation::LM_CommittedRead,
int numRecords = 1);
+ NdbIndexScanOperation* pIndexScanOp;
- int execute_async(Ndb*, ExecType, AbortOption = AbortOnError);
+ NDBT_ResultRow& get_row(Uint32 idx) { return *rows[idx];}
+
+ int execute_async(Ndb*, NdbTransaction::ExecType, NdbTransaction::AbortOption = NdbTransaction::AbortOnError);
int wait_async(Ndb*, int timeout = -1);
protected:
@@ -106,16 +119,14 @@ protected:
Vector<BaseString> savedRecords;
- struct RsPair { NdbResultSet* m_result_set; int records; };
+ struct RsPair { NdbScanOperation* m_result_set; int records; };
Vector<RsPair> m_result_sets;
Vector<RsPair> m_executed_result_sets;
- NdbConnection* pTrans;
-
int m_async_reply;
int m_async_return;
- friend void HugoOperations_async_callback(int, NdbConnection*, void*);
- void callback(int res, NdbConnection*);
+ friend void HugoOperations_async_callback(int, NdbTransaction*, void*);
+ void callback(int res, NdbTransaction*);
};
#endif
diff --git a/ndb/test/include/HugoTransactions.hpp b/ndb/test/include/HugoTransactions.hpp
index b833f2ac629..5795bbc94c9 100644
--- a/ndb/test/include/HugoTransactions.hpp
+++ b/ndb/test/include/HugoTransactions.hpp
@@ -25,7 +25,8 @@
class HugoTransactions : public HugoOperations {
public:
- HugoTransactions(const NdbDictionary::Table&);
+ HugoTransactions(const NdbDictionary::Table&,
+ const NdbDictionary::Index* idx = 0);
~HugoTransactions();
int createEvent(Ndb*);
int eventOperation(Ndb*, void* stats,
@@ -41,7 +42,8 @@ public:
int records,
int abort = 0,
int parallelism = 0,
- NdbOperation::LockMode = NdbOperation::LM_Read);
+ NdbOperation::LockMode = NdbOperation::LM_Read,
+ int scan_flags = 0);
int scanReadRecords(Ndb*,
const NdbDictionary::Index*,
@@ -49,7 +51,7 @@ public:
int abort = 0,
int parallelism = 0,
NdbOperation::LockMode = NdbOperation::LM_Read,
- bool sorted = false);
+ int scan_flags = 0);
int pkReadRecords(Ndb*,
int records,
diff --git a/ndb/test/include/NDBT_Error.hpp b/ndb/test/include/NDBT_Error.hpp
index ef107072465..6775a107196 100644
--- a/ndb/test/include/NDBT_Error.hpp
+++ b/ndb/test/include/NDBT_Error.hpp
@@ -91,7 +91,11 @@ private:
; \
}
-#define ERR(error) ERR_OUT(g_err, error)
+#define ERR(error) \
+{ \
+ const NdbError &_error= (error); \
+ ERR_OUT(g_err, _error); \
+}
#define ERR_INFO(error) ERR_OUT(g_info, error)
#endif
diff --git a/ndb/test/include/NDBT_ResultRow.hpp b/ndb/test/include/NDBT_ResultRow.hpp
index 6072d0ea510..cbb5d7f6c6a 100644
--- a/ndb/test/include/NDBT_ResultRow.hpp
+++ b/ndb/test/include/NDBT_ResultRow.hpp
@@ -27,7 +27,7 @@ public:
const NdbRecAttr * attributeStore(int i) const ;
const NdbRecAttr * attributeStore(const char* name) const ;
- BaseString c_str();
+ BaseString c_str() const ;
NdbOut & header (NdbOut &) const;
friend NdbOut & operator << (NdbOut&, const NDBT_ResultRow &);
@@ -36,6 +36,11 @@ public:
* Make copy of NDBT_ResultRow
*/
NDBT_ResultRow * clone() const;
+
+ bool operator==(const NDBT_ResultRow&) const ;
+ bool operator!=(const NDBT_ResultRow& other) const {
+ return ! (*this == other);
+ }
private:
int cols;
diff --git a/ndb/test/include/NDBT_Tables.hpp b/ndb/test/include/NDBT_Tables.hpp
index aa78f7d4e2c..fb0df8aa35b 100644
--- a/ndb/test/include/NDBT_Tables.hpp
+++ b/ndb/test/include/NDBT_Tables.hpp
@@ -23,11 +23,13 @@
#include <NdbDictionary.hpp>
#include <NDBT_Table.hpp>
+typedef int (* NDBT_CreateTableHook)(Ndb*, NdbDictionary::Table&, int when);
+
class NDBT_Tables {
public:
-
+
static int createTable(Ndb* pNdb, const char* _name, bool _temp = false,
- bool existsOK = false);
+ bool existsOK = false, NDBT_CreateTableHook = 0);
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 bcaa0bf4d40..027ac356e0c 100644
--- a/ndb/test/include/NDBT_Test.hpp
+++ b/ndb/test/include/NDBT_Test.hpp
@@ -25,6 +25,7 @@
#include <NdbCondition.h>
#include <NdbTimer.hpp>
#include <Vector.hpp>
+#include <NdbApi.hpp>
#include <NdbDictionary.hpp>
class NDBT_Step;
@@ -34,7 +35,9 @@ class NDBT_TestCaseImpl1;
class NDBT_Context {
public:
- NDBT_Context();
+ Ndb_cluster_connection& m_cluster_connection;
+
+ NDBT_Context(Ndb_cluster_connection&);
~NDBT_Context();
const NdbDictionary::Table* getTab();
NDBT_TestSuite* getSuite();
@@ -121,7 +124,7 @@ public:
NDBT_TESTFUNC* pfunc);
virtual ~NDBT_Step() {}
int execute(NDBT_Context*);
- virtual int setUp() = 0;
+ virtual int setUp(Ndb_cluster_connection&) = 0;
virtual void tearDown() = 0;
void setContext(NDBT_Context*);
NDBT_Context* getContext();
@@ -143,7 +146,7 @@ public:
const char* pname,
NDBT_TESTFUNC* pfunc);
virtual ~NDBT_NdbApiStep() {}
- virtual int setUp();
+ virtual int setUp(Ndb_cluster_connection&);
virtual void tearDown();
Ndb* getNdb();
@@ -350,10 +353,13 @@ public:
int addTest(NDBT_TestCase* pTest);
private:
- int executeOne(const char* _tabname, const char* testname = NULL);
- int executeAll(const char* testname = NULL);
-
- void execute(Ndb*, const NdbDictionary::Table*, const char* testname = NULL);
+ int executeOne(Ndb_cluster_connection&,
+ const char* _tabname, const char* testname = NULL);
+ int executeAll(Ndb_cluster_connection&,
+ const char* testname = NULL);
+ void execute(Ndb_cluster_connection&,
+ Ndb*, const NdbDictionary::Table*, const char* testname = NULL);
+
int report(const char* _tcname = NULL);
int reportAllTables(const char* );
const char* name;
@@ -426,7 +432,7 @@ C##suitname():NDBT_TestSuite(#suitname){ \
pt->addTable(tableName, false);
#define NDBT_TESTSUITE_END(suitname) \
- } } ; C##suitname suitname;
+ } } ; C##suitname suitname
// Helper functions for retrieving variables from NDBT_Step
#define GETNDB(ps) ((NDBT_NdbApiStep*)ps)->getNdb()
diff --git a/ndb/test/include/NdbSchemaOp.hpp b/ndb/test/include/NdbSchemaOp.hpp
index e8ab542b00a..1edbc155643 100644
--- a/ndb/test/include/NdbSchemaOp.hpp
+++ b/ndb/test/include/NdbSchemaOp.hpp
@@ -79,29 +79,6 @@
};
/**
- * Where attribute is stored.
- *
- * This is used to indicate whether a primary key
- * should only be stored in the index storage and not in the data storage
- * or if it should be stored in both places.
- * The first alternative makes the attribute take less space,
- * but makes it impossible to scan using attribute.
- *
- * @note Use NormalStorageAttribute for most cases.
- * (IndexStorageAttribute should only be used on primary key
- * attributes and only if you do not want to scan using the attribute.)
- */
- enum StorageAttributeType {
- NoStorageAttributeTypeDefined = -1, ///< <i>Missing explanation</i>
- IndexStorageAttribute, ///< Attribute is only stored in
- ///< index storage (ACC)
- NormalStorageAttribute ///< Attribute values are stored
- ///< both in the index (ACC) and
- ///< in the data storage (TUP)
- };
-
-
- /**
* Type of fragmentation used for a table
*/
enum FragmentType {
@@ -405,27 +382,7 @@ public:
* the attribute.
* <br>
* Legal values: true, false
- * @param aStType Stored in both index and data storage or
- * only store in index data storage.
- * <br>
- * This parameter is only of interest for tuple
- * key attributes.
- * All tuple key attributes values are always stored
- * in the index storage part.
- * If this parameter is set to
- * IndexStorageAttribute, then the attribute values
- * will <em>only</em> be stored in the index
- * storage part and <em>not</em> in the data
- * storage part.
- * <br>
- * If there will be no scans using the primary
- * key attribute and if the size of the attribute
- * is large, then this might be of interest.
- * A typical example is a table where
- * http-addresses are used as primary key.
- * <br>
- * Legal values: NormalStorageAttribute,
- * IndexStorageAttribute
+ * @param aStType Obsolete since wl-2066
* @param aDistributionKey Sometimes it is preferable to use a subset
* of the primary key as the distribution key.
* An example is TPC-C where it might be
@@ -474,7 +431,7 @@ public:
AttrType aAttrType = UnSigned,
StorageMode aStorageMode = MMBased,
bool nullable = false,
- StorageAttributeType aStType= NormalStorageAttribute,
+ int aStType= 0, // obsolete
int aDistributionKey = 0,
int aDistributionGroup = 0,
int aDistributionGroupNoOfBits = 16,
@@ -491,7 +448,7 @@ public:
AttrType aAttrType,
StorageMode aStorageMode,
NullAttributeType aNullAttr,
- StorageAttributeType aStType = NormalStorageAttribute,
+ int aStType, // obsolete
int aDistributionKey = 0,
int aDistributionGroup = 0,
int aDistributionGroupNoOfBits = 16){
@@ -569,6 +526,8 @@ convertColumnTypeToAttrType(NdbDictionary::Column::Type _type)
case NdbDictionary::Column::Float:
case NdbDictionary::Column::Olddecimal:
case NdbDictionary::Column::Olddecimalunsigned:
+ case NdbDictionary::Column::Decimal:
+ case NdbDictionary::Column::Decimalunsigned:
case NdbDictionary::Column::Double:
return Float;
case NdbDictionary::Column::Char:
diff --git a/ndb/test/include/UtilTransactions.hpp b/ndb/test/include/UtilTransactions.hpp
index 23902f3b317..333f5d98328 100644
--- a/ndb/test/include/UtilTransactions.hpp
+++ b/ndb/test/include/UtilTransactions.hpp
@@ -23,15 +23,13 @@ typedef int (ReadCallBackFn)(NDBT_ResultRow*);
class UtilTransactions {
public:
- enum ScanLock {
- SL_Read = 0,
- SL_ReadHold = 1,
- SL_Exclusive = 2
- };
-
- UtilTransactions(const NdbDictionary::Table&);
- UtilTransactions(Ndb* ndb, const char * tableName);
-
+ UtilTransactions(const NdbDictionary::Table&,
+ const NdbDictionary::Index* idx = 0);
+ UtilTransactions(Ndb* ndb,
+ const char * tableName, const char * indexName = 0);
+
+ int closeTransaction(Ndb*);
+
int clearTable(Ndb*,
int records = 0,
int parallelism = 0);
@@ -70,6 +68,14 @@ public:
int copyTableData(Ndb*,
const char* destName);
+ /**
+ * Compare this table with other_table
+ *
+ * return 0 - on equality
+ * -1 - on error
+ * >0 - otherwise
+ */
+ int compare(Ndb*, const char * other_table, int flags);
private:
static int takeOverAndDeleteRecord(Ndb*,
@@ -114,6 +120,12 @@ private:
protected:
int m_defaultClearMethod;
const NdbDictionary::Table& tab;
+ const NdbDictionary::Index* idx;
+ NdbConnection* pTrans;
+
+ NdbOperation* getOperation(NdbConnection*,
+ NdbOperation::OperationType);
+ NdbScanOperation* getScanOperation(NdbConnection*);
};
#endif
diff --git a/ndb/test/ndbapi/Makefile.am b/ndb/test/ndbapi/Makefile.am
index 7b4a96f5890..d83e9614eb5 100644
--- a/ndb/test/ndbapi/Makefile.am
+++ b/ndb/test/ndbapi/Makefile.am
@@ -31,7 +31,10 @@ testTimeout \
testTransactions \
testDeadlock \
test_event ndbapi_slow_select testReadPerf testLcp \
+testPartitioning \
+testBitfield \
DbCreate DbAsyncGenerator \
+test_event_multi_table \
testSRBank
#flexTimedAsynch
@@ -71,8 +74,11 @@ test_event_SOURCES = test_event.cpp
ndbapi_slow_select_SOURCES = slow_select.cpp
testReadPerf_SOURCES = testReadPerf.cpp
testLcp_SOURCES = testLcp.cpp
-DbCreate_SOURCES= bench/mainPopulate.cpp bench/dbPopulate.cpp bench/userInterface.cpp bench/dbPopulate.h bench/userInterface.h bench/testData.h bench/testDefinitions.h bench/ndb_schema.hpp bench/ndb_error.hpp
-DbAsyncGenerator_SOURCES= bench/mainAsyncGenerator.cpp bench/asyncGenerator.cpp bench/ndb_async2.cpp bench/dbGenerator.h bench/macros.h bench/userInterface.h bench/testData.h bench/testDefinitions.h bench/ndb_schema.hpp bench/ndb_error.hpp
+testPartitioning_SOURCES = testPartitioning.cpp
+testBitfield_SOURCES = testBitfield.cpp
+DbCreate_SOURCES = bench/mainPopulate.cpp bench/dbPopulate.cpp bench/userInterface.cpp bench/dbPopulate.h bench/userInterface.h bench/testData.h bench/testDefinitions.h bench/ndb_schema.hpp bench/ndb_error.hpp
+DbAsyncGenerator_SOURCES = bench/mainAsyncGenerator.cpp bench/asyncGenerator.cpp bench/ndb_async2.cpp bench/dbGenerator.h bench/macros.h bench/userInterface.h bench/testData.h bench/testDefinitions.h bench/ndb_schema.hpp bench/ndb_error.hpp
+test_event_multi_table_SOURCES = test_event_multi_table.cpp
testSRBank_SOURCES = testSRBank.cpp
INCLUDES_LOC = -I$(top_srcdir)/ndb/include/kernel
@@ -90,6 +96,8 @@ testSRBank_LDADD = bank/libbank.a $(LDADD)
# Don't update the files from bitkeeper
%::SCCS/s.%
+
+
windoze-dsp: flexBench.dsp testBasic.dsp testBlobs.dsp \
testScan.dsp
diff --git a/ndb/test/ndbapi/ScanFunctions.hpp b/ndb/test/ndbapi/ScanFunctions.hpp
index 6964f8c73a8..37389d9b7de 100644
--- a/ndb/test/ndbapi/ScanFunctions.hpp
+++ b/ndb/test/ndbapi/ScanFunctions.hpp
@@ -81,7 +81,6 @@ ScanFunctions::scanReadFunctions(Ndb* pNdb,
int check;
NdbConnection *pTrans = 0;
NdbScanOperation *pOp = 0;
- NdbResultSet *rs = 0;
while (true){
if (retryAttempt >= retryMax){
@@ -111,12 +110,9 @@ ScanFunctions::scanReadFunctions(Ndb* pNdb,
return NDBT_FAILED;
}
-
- rs = pOp->readTuples(exclusive ?
- NdbScanOperation::LM_Exclusive :
- NdbScanOperation::LM_Read);
-
- if( rs == 0 ) {
+ if( pOp->readTuples(exclusive ?
+ NdbScanOperation::LM_Exclusive :
+ NdbScanOperation::LM_Read) ) {
ERR(pTrans->getNdbError());
pNdb->closeTransaction(pTrans);
return NDBT_FAILED;
@@ -125,8 +121,7 @@ ScanFunctions::scanReadFunctions(Ndb* pNdb,
if (action == OnlyOpenScanOnce){
// Call openScan one more time when it's already defined
- NdbResultSet* rs2 = pOp->readTuples(NdbScanOperation::LM_Read);
- if( rs2 == 0 ) {
+ if( pOp->readTuples(NdbScanOperation::LM_Read) ) {
ERR(pTrans->getNdbError());
pNdb->closeTransaction(pTrans);
return NDBT_FAILED;
@@ -168,7 +163,7 @@ ScanFunctions::scanReadFunctions(Ndb* pNdb,
bool abortTrans = (action==CloseWithoutStop);
int eof;
int rows = 0;
- eof = rs->nextResult();
+ eof = pOp->nextResult();
while(eof == 0){
rows++;
@@ -178,7 +173,7 @@ ScanFunctions::scanReadFunctions(Ndb* pNdb,
if (action != CloseWithoutStop){
// Test that we can closeTrans without stopScan
- rs->close();
+ pOp->close();
if( check == -1 ) {
ERR(pTrans->getNdbError());
pNdb->closeTransaction(pTrans);
@@ -201,7 +196,7 @@ ScanFunctions::scanReadFunctions(Ndb* pNdb,
}
}
- eof = rs->nextResult();
+ eof = pOp->nextResult();
}
if (eof == -1) {
const NdbError err = pTrans->getNdbError();
@@ -211,7 +206,7 @@ ScanFunctions::scanReadFunctions(Ndb* pNdb,
// Be cruel, call nextScanResult after error
for(int i=0; i<10; i++){
- eof = rs->nextResult();
+ eof = pOp->nextResult();
if(eof == 0){
g_err << "nextScanResult returned eof = " << eof << endl
<< " That is an error when there are no more records" << endl;
@@ -241,7 +236,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 = rs->nextResult();
+ eof = pOp->nextResult();
if(eof == 0){
g_err << "nextScanResult returned eof = " << eof << endl
<< " That is an error when there are no more records" << endl;
diff --git a/ndb/test/ndbapi/ScanInterpretTest.hpp b/ndb/test/ndbapi/ScanInterpretTest.hpp
index e8a0d4b6dca..d4e9bbecc81 100644
--- a/ndb/test/ndbapi/ScanInterpretTest.hpp
+++ b/ndb/test/ndbapi/ScanInterpretTest.hpp
@@ -227,10 +227,7 @@ ScanInterpretTest::scanRead(Ndb* pNdb,
return NDBT_FAILED;
}
- NdbResultSet * rs = pOp->readTuples(NdbScanOperation::LM_Read,
- 0, parallelism);
-
- if( rs == 0 ) {
+ if( pOp->readTuples(NdbScanOperation::LM_Read, 0, parallelism) ) {
ERR(pTrans->getNdbError());
pNdb->closeTransaction(pTrans);
return NDBT_FAILED;
@@ -262,14 +259,14 @@ ScanInterpretTest::scanRead(Ndb* pNdb,
int rows = 0;
NdbConnection* pInsTrans;
- while((eof = rs->nextResult(true)) == 0){
+ while((eof = pOp->nextResult(true)) == 0){
do {
rows++;
if (addRowToInsert(pNdb, pTrans) != 0){
pNdb->closeTransaction(pTrans);
return NDBT_FAILED;
}
- } while((eof = rs->nextResult(false)) == 0);
+ } while((eof = pOp->nextResult(false)) == 0);
check = pTrans->execute(Commit);
if( check == -1 ) {
@@ -349,9 +346,7 @@ ScanInterpretTest::scanReadVerify(Ndb* pNdb,
return NDBT_FAILED;
}
- NdbResultSet * rs = pOp->readTuples(NdbScanOperation::LM_Read,
- 0, parallelism);
- if( rs == 0 ) {
+ if( pOp->readTuples(NdbScanOperation::LM_Read, 0, parallelism) ) {
ERR(pTrans->getNdbError());
pNdb->closeTransaction(pTrans);
return NDBT_FAILED;
@@ -392,7 +387,7 @@ ScanInterpretTest::scanReadVerify(Ndb* pNdb,
NdbConnection* pExistTrans;
NdbConnection* pNoExistTrans;
- while((eof = rs->nextResult(true)) == 0){
+ while((eof = pOp->nextResult(true)) == 0){
pExistTrans = pNdb->startTransaction();
if (pExistTrans == NULL) {
const NdbError err = pNdb->getNdbError();
@@ -424,7 +419,7 @@ ScanInterpretTest::scanReadVerify(Ndb* pNdb,
return NDBT_FAILED;
}
}
- } while((eof = rs->nextResult(false)) == 0);
+ } while((eof = pOp->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 346442367fc..37224fdd055 100644
--- a/ndb/test/ndbapi/bank/Bank.cpp
+++ b/ndb/test/ndbapi/bank/Bank.cpp
@@ -19,8 +19,8 @@
#include <NdbSleep.h>
#include <UtilTransactions.hpp>
-Bank::Bank(bool _init):
- m_ndb("BANK"),
+Bank::Bank(Ndb_cluster_connection& con, bool _init):
+ m_ndb(&con, "BANK"),
m_maxAccount(-1),
m_initialized(false)
{
@@ -661,8 +661,7 @@ int Bank::findLastGL(Uint64 &lastTime){
return NDBT_FAILED;
}
- NdbResultSet * rs = pOp->readTuples();
- if( rs == 0 ) {
+ if( pOp->readTuples() ) {
ERR(pScanTrans->getNdbError());
m_ndb.closeTransaction(pScanTrans);
return NDBT_FAILED;
@@ -691,7 +690,7 @@ int Bank::findLastGL(Uint64 &lastTime){
int eof;
int rows = 0;
- eof = rs->nextResult();
+ eof = pOp->nextResult();
lastTime = 0;
while(eof == 0){
@@ -701,7 +700,7 @@ int Bank::findLastGL(Uint64 &lastTime){
if (t > lastTime)
lastTime = t;
- eof = rs->nextResult();
+ eof = pOp->nextResult();
}
if (eof == -1) {
ERR(pScanTrans->getNdbError());
@@ -993,8 +992,7 @@ int Bank::sumTransactionsForGL(const Uint64 glTime,
return NDBT_FAILED;
}
- NdbResultSet * rs = pOp->readTuplesExclusive();
- if( rs == 0 ) {
+ if( pOp->readTuplesExclusive()) {
ERR(pScanTrans->getNdbError());
m_ndb.closeTransaction(pScanTrans);
return NDBT_FAILED;
@@ -1045,7 +1043,7 @@ int Bank::sumTransactionsForGL(const Uint64 glTime,
int eof;
int rows = 0;
int rowsFound = 0;
- eof = rs->nextResult();
+ eof = pOp->nextResult();
while(eof == 0){
rows++;
@@ -1069,7 +1067,7 @@ int Bank::sumTransactionsForGL(const Uint64 glTime,
}
}
- eof = rs->nextResult();
+ eof = pOp->nextResult();
if ((rows % 100) == 0){
// "refresh" ownner transaction every 100th row
@@ -1153,8 +1151,7 @@ int Bank::performValidateGL(Uint64 glTime){
return NDBT_FAILED;
}
- NdbResultSet * rs = pOp->readTuples();
- if( rs == 0 ) {
+ if( pOp->readTuples() ) {
ERR(pScanTrans->getNdbError());
m_ndb.closeTransaction(pScanTrans);
return NDBT_FAILED;
@@ -1233,7 +1230,7 @@ int Bank::performValidateGL(Uint64 glTime){
int rows = 0;
int countGlRecords = 0;
int result = NDBT_OK;
- eof = rs->nextResult();
+ eof = pOp->nextResult();
while(eof == 0){
rows++;
@@ -1320,7 +1317,7 @@ int Bank::performValidateGL(Uint64 glTime){
}
}
- eof = rs->nextResult();
+ eof = pOp->nextResult();
}
if (eof == -1) {
ERR(pScanTrans->getNdbError());
@@ -1417,8 +1414,7 @@ int Bank::getOldestPurgedGL(const Uint32 accountType,
return NDBT_FAILED;
}
- NdbResultSet * rs = pOp->readTuples();
- if( rs == 0 ) {
+ if( pOp->readTuples() ) {
ERR(pScanTrans->getNdbError());
m_ndb.closeTransaction(pScanTrans);
return NDBT_FAILED;
@@ -1461,7 +1457,7 @@ int Bank::getOldestPurgedGL(const Uint32 accountType,
int eof;
int rows = 0;
- eof = rs->nextResult();
+ eof = pOp->nextResult();
oldest = 0;
while(eof == 0){
@@ -1475,7 +1471,7 @@ int Bank::getOldestPurgedGL(const Uint32 accountType,
if (t > oldest)
oldest = t;
}
- eof = rs->nextResult();
+ eof = pOp->nextResult();
}
if (eof == -1) {
ERR(pScanTrans->getNdbError());
@@ -1509,8 +1505,7 @@ int Bank::getOldestNotPurgedGL(Uint64 &oldest,
return NDBT_FAILED;
}
- NdbResultSet * rs = pOp->readTuples();
- if( rs == 0 ) {
+ if( pOp->readTuples() ) {
ERR(pScanTrans->getNdbError());
m_ndb.closeTransaction(pScanTrans);
return NDBT_FAILED;
@@ -1553,7 +1548,7 @@ int Bank::getOldestNotPurgedGL(Uint64 &oldest,
int eof;
int rows = 0;
- eof = rs->nextResult();
+ eof = pOp->nextResult();
oldest = (Uint64)-1;
found = false;
@@ -1570,7 +1565,7 @@ int Bank::getOldestNotPurgedGL(Uint64 &oldest,
accountTypeId = a;
}
}
- eof = rs->nextResult();
+ eof = pOp->nextResult();
}
if (eof == -1) {
ERR(pScanTrans->getNdbError());
@@ -1606,8 +1601,7 @@ int Bank::checkNoTransactionsOlderThan(const Uint32 accountType,
return NDBT_FAILED;
}
- NdbResultSet * rs = pOp->readTuples();
- if( rs == 0 ) {
+ if( pOp->readTuples() ) {
ERR(pScanTrans->getNdbError());
m_ndb.closeTransaction(pScanTrans);
return NDBT_FAILED;
@@ -1651,7 +1645,7 @@ int Bank::checkNoTransactionsOlderThan(const Uint32 accountType,
int eof;
int rows = 0;
int found = 0;
- eof = rs->nextResult();
+ eof = pOp->nextResult();
while(eof == 0){
rows++;
@@ -1667,7 +1661,7 @@ int Bank::checkNoTransactionsOlderThan(const Uint32 accountType,
<< " ti = " << ti << endl;
found++;
}
- eof = rs->nextResult();
+ eof = pOp->nextResult();
}
if (eof == -1) {
ERR(pScanTrans->getNdbError());
@@ -1850,8 +1844,7 @@ int Bank::findTransactionsToPurge(const Uint64 glTime,
return NDBT_FAILED;
}
- NdbResultSet * rs = pOp->readTuplesExclusive();
- if( rs == 0 ) {
+ if( pOp->readTuplesExclusive() ) {
ERR(pScanTrans->getNdbError());
m_ndb.closeTransaction(pScanTrans);
return NDBT_FAILED;
@@ -1888,7 +1881,7 @@ int Bank::findTransactionsToPurge(const Uint64 glTime,
int eof;
int rows = 0;
int rowsFound = 0;
- eof = rs->nextResult();
+ eof = pOp->nextResult();
while(eof == 0){
rows++;
@@ -1898,7 +1891,7 @@ int Bank::findTransactionsToPurge(const Uint64 glTime,
if (a == accountType && t == glTime){
rowsFound++;
// One record found
- check = rs->deleteTuple(pTrans);
+ check = pOp->deleteCurrentTuple(pTrans);
if (check == -1){
ERR(m_ndb.getNdbError());
m_ndb.closeTransaction(pScanTrans);
@@ -1913,7 +1906,7 @@ int Bank::findTransactionsToPurge(const Uint64 glTime,
return NDBT_FAILED;
}
}
- eof = rs->nextResult();
+ eof = pOp->nextResult();
}
if (eof == -1) {
ERR(pScanTrans->getNdbError());
@@ -2371,8 +2364,7 @@ int Bank::getSumAccounts(Uint32 &sumAccounts,
return NDBT_FAILED;
}
- NdbResultSet * rs = pOp->readTuplesExclusive();
- if( rs == 0 ) {
+ if( pOp->readTuplesExclusive() ) {
ERR(pScanTrans->getNdbError());
m_ndb.closeTransaction(pScanTrans);
return NDBT_FAILED;
@@ -2407,7 +2399,7 @@ int Bank::getSumAccounts(Uint32 &sumAccounts,
}
int eof;
- eof = rs->nextResult();
+ eof = pOp->nextResult();
while(eof == 0){
Uint32 b = balanceRec->u_32_value();
@@ -2419,7 +2411,7 @@ int Bank::getSumAccounts(Uint32 &sumAccounts,
// << ", sum="<< sumAccounts << endl;
// Take over the operation so that the lock is kept in db
- NdbOperation* pLockOp = rs->updateTuple(pTrans);
+ NdbOperation* pLockOp = pOp->updateCurrentTuple(pTrans);
if (pLockOp == NULL){
ERR(m_ndb.getNdbError());
m_ndb.closeTransaction(pScanTrans);
@@ -2445,7 +2437,7 @@ int Bank::getSumAccounts(Uint32 &sumAccounts,
return NDBT_FAILED;
}
- eof = rs->nextResult();
+ eof = pOp->nextResult();
}
if (eof == -1) {
ERR(pScanTrans->getNdbError());
diff --git a/ndb/test/ndbapi/bank/Bank.hpp b/ndb/test/ndbapi/bank/Bank.hpp
index 14e01df29d5..b80f02dae97 100644
--- a/ndb/test/ndbapi/bank/Bank.hpp
+++ b/ndb/test/ndbapi/bank/Bank.hpp
@@ -27,7 +27,7 @@
class Bank {
public:
- Bank(bool init = true);
+ Bank(Ndb_cluster_connection&, bool init = true);
int createAndLoadBank(bool overWrite, int num_accounts=10);
int dropBank();
diff --git a/ndb/test/ndbapi/bank/BankLoad.cpp b/ndb/test/ndbapi/bank/BankLoad.cpp
index 39dc8097115..34947019a51 100644
--- a/ndb/test/ndbapi/bank/BankLoad.cpp
+++ b/ndb/test/ndbapi/bank/BankLoad.cpp
@@ -321,7 +321,7 @@ int Bank::loadGl(){
m_ndb.closeTransaction(pTrans);
return NDBT_OK;
-};
+}
int Bank::getBalanceForAccountType(const Uint32 accountType,
@@ -342,8 +342,7 @@ int Bank::getBalanceForAccountType(const Uint32 accountType,
return NDBT_FAILED;
}
- NdbResultSet* rs = pOp->readTuples();
- if( rs == 0 ) {
+ if( pOp->readTuples() ) {
ERR(pScanTrans->getNdbError());
m_ndb.closeTransaction(pScanTrans);
return NDBT_FAILED;
@@ -379,7 +378,7 @@ int Bank::getBalanceForAccountType(const Uint32 accountType,
int eof;
int rows = 0;
- eof = rs->nextResult();
+ eof = pOp->nextResult();
while(eof == 0){
rows++;
@@ -391,7 +390,7 @@ int Bank::getBalanceForAccountType(const Uint32 accountType,
balance += b;
}
- eof = rs->nextResult();
+ eof = pOp->nextResult();
}
if (eof == -1) {
ERR(pScanTrans->getNdbError());
@@ -460,7 +459,7 @@ int Bank::loadAccountType(){
m_ndb.closeTransaction(pTrans);
return NDBT_OK;
-};
+}
/**
* Load ACCOUNT table
diff --git a/ndb/test/ndbapi/bank/bankCreator.cpp b/ndb/test/ndbapi/bank/bankCreator.cpp
index 301d8bda6d2..257255babc8 100644
--- a/ndb/test/ndbapi/bank/bankCreator.cpp
+++ b/ndb/test/ndbapi/bank/bankCreator.cpp
@@ -43,7 +43,13 @@ int main(int argc, const char** argv){
return NDBT_ProgramExit(NDBT_WRONGARGS);
}
- Bank bank;
+ Ndb_cluster_connection con;
+ if(con.connect(12, 5, 1) != 0)
+ {
+ return NDBT_ProgramExit(NDBT_FAILED);
+ }
+
+ Bank bank(con);
int overWriteExisting = true;
if (bank.createAndLoadBank(overWriteExisting) != NDBT_OK)
return NDBT_ProgramExit(NDBT_FAILED);
diff --git a/ndb/test/ndbapi/bank/bankMakeGL.cpp b/ndb/test/ndbapi/bank/bankMakeGL.cpp
index 9e2762ed8ae..cf373481e3e 100644
--- a/ndb/test/ndbapi/bank/bankMakeGL.cpp
+++ b/ndb/test/ndbapi/bank/bankMakeGL.cpp
@@ -43,7 +43,13 @@ int main(int argc, const char** argv){
return NDBT_ProgramExit(NDBT_WRONGARGS);
}
- Bank bank;
+ Ndb_cluster_connection con;
+ if(con.connect(12, 5, 1) != 0)
+ {
+ return NDBT_ProgramExit(NDBT_FAILED);
+ }
+
+ Bank bank(con);
if (bank.performMakeGLs() != 0)
return NDBT_ProgramExit(NDBT_FAILED);
diff --git a/ndb/test/ndbapi/bank/bankSumAccounts.cpp b/ndb/test/ndbapi/bank/bankSumAccounts.cpp
index b576161b27b..034f70f8f95 100644
--- a/ndb/test/ndbapi/bank/bankSumAccounts.cpp
+++ b/ndb/test/ndbapi/bank/bankSumAccounts.cpp
@@ -43,7 +43,13 @@ int main(int argc, const char** argv){
return NDBT_ProgramExit(NDBT_WRONGARGS);
}
- Bank bank;
+ Ndb_cluster_connection con;
+ if(con.connect(12, 5, 1) != 0)
+ {
+ return NDBT_ProgramExit(NDBT_FAILED);
+ }
+
+ Bank bank(con);
if (bank.performSumAccounts() != 0)
return NDBT_ProgramExit(NDBT_FAILED);
diff --git a/ndb/test/ndbapi/bank/bankTimer.cpp b/ndb/test/ndbapi/bank/bankTimer.cpp
index 874afd9c21e..298f85e1e43 100644
--- a/ndb/test/ndbapi/bank/bankTimer.cpp
+++ b/ndb/test/ndbapi/bank/bankTimer.cpp
@@ -46,7 +46,13 @@ int main(int argc, const char** argv){
return NDBT_ProgramExit(NDBT_WRONGARGS);
}
- Bank bank;
+ Ndb_cluster_connection con;
+ if(con.connect(12, 5, 1) != 0)
+ {
+ return NDBT_ProgramExit(NDBT_FAILED);
+ }
+
+ Bank bank(con);
if (bank.performIncreaseTime(_wait) != 0)
return NDBT_ProgramExit(NDBT_FAILED);
diff --git a/ndb/test/ndbapi/bank/bankTransactionMaker.cpp b/ndb/test/ndbapi/bank/bankTransactionMaker.cpp
index e5ff9aeb918..f8e646b6553 100644
--- a/ndb/test/ndbapi/bank/bankTransactionMaker.cpp
+++ b/ndb/test/ndbapi/bank/bankTransactionMaker.cpp
@@ -46,7 +46,13 @@ int main(int argc, const char** argv){
return NDBT_ProgramExit(NDBT_WRONGARGS);
}
- Bank bank;
+ Ndb_cluster_connection con;
+ if(con.connect(12, 5, 1) != 0)
+ {
+ return NDBT_ProgramExit(NDBT_FAILED);
+ }
+
+ Bank bank(con);
if (bank.performTransactions(_wait) != 0)
return NDBT_ProgramExit(NDBT_FAILED);
diff --git a/ndb/test/ndbapi/bank/bankValidateAllGLs.cpp b/ndb/test/ndbapi/bank/bankValidateAllGLs.cpp
index cf298ecc8e3..0c268121d8a 100644
--- a/ndb/test/ndbapi/bank/bankValidateAllGLs.cpp
+++ b/ndb/test/ndbapi/bank/bankValidateAllGLs.cpp
@@ -44,7 +44,13 @@ int main(int argc, const char** argv){
return NDBT_ProgramExit(NDBT_WRONGARGS);
}
- Bank bank;
+ Ndb_cluster_connection con;
+ if(con.connect(12, 5, 1) != 0)
+ {
+ return NDBT_ProgramExit(NDBT_FAILED);
+ }
+
+ Bank bank(con);
if (bank.performValidateAllGLs() != 0)
return NDBT_ProgramExit(NDBT_FAILED);
diff --git a/ndb/test/ndbapi/bank/testBank.cpp b/ndb/test/ndbapi/bank/testBank.cpp
index 3ef2799cd3c..6be66d528b1 100644
--- a/ndb/test/ndbapi/bank/testBank.cpp
+++ b/ndb/test/ndbapi/bank/testBank.cpp
@@ -32,7 +32,7 @@
#include "Bank.hpp"
int runCreateBank(NDBT_Context* ctx, NDBT_Step* step){
- Bank bank;
+ Bank bank(ctx->m_cluster_connection);
int overWriteExisting = true;
if (bank.createAndLoadBank(overWriteExisting) != NDBT_OK)
return NDBT_FAILED;
@@ -40,7 +40,7 @@ int runCreateBank(NDBT_Context* ctx, NDBT_Step* step){
}
int runBankTimer(NDBT_Context* ctx, NDBT_Step* step){
- Bank bank;
+ Bank bank(ctx->m_cluster_connection);
int wait = 30; // Max seconds between each "day"
int yield = 1; // Loops before bank returns
@@ -51,7 +51,7 @@ int runBankTimer(NDBT_Context* ctx, NDBT_Step* step){
}
int runBankTransactions(NDBT_Context* ctx, NDBT_Step* step){
- Bank bank;
+ Bank bank(ctx->m_cluster_connection);
int wait = 10; // Max ms between each transaction
int yield = 100; // Loops before bank returns
@@ -62,7 +62,7 @@ int runBankTransactions(NDBT_Context* ctx, NDBT_Step* step){
}
int runBankGL(NDBT_Context* ctx, NDBT_Step* step){
- Bank bank;
+ Bank bank(ctx->m_cluster_connection);
int yield = 20; // Loops before bank returns
int result = NDBT_OK;
@@ -76,7 +76,7 @@ int runBankGL(NDBT_Context* ctx, NDBT_Step* step){
}
int runBankSum(NDBT_Context* ctx, NDBT_Step* step){
- Bank bank;
+ Bank bank(ctx->m_cluster_connection);
int wait = 2000; // Max ms between each sum of accounts
int yield = 1; // Loops before bank returns
int result = NDBT_OK;
@@ -91,7 +91,7 @@ int runBankSum(NDBT_Context* ctx, NDBT_Step* step){
}
int runDropBank(NDBT_Context* ctx, NDBT_Step* step){
- Bank bank;
+ Bank bank(ctx->m_cluster_connection);
if (bank.dropBank() != NDBT_OK)
return NDBT_FAILED;
return NDBT_OK;
diff --git a/ndb/test/ndbapi/bench/userInterface.cpp b/ndb/test/ndbapi/bench/userInterface.cpp
index 683552c3133..35e88183230 100644
--- a/ndb/test/ndbapi/bench/userInterface.cpp
+++ b/ndb/test/ndbapi/bench/userInterface.cpp
@@ -173,7 +173,7 @@ create_table_server(Ndb * pNdb){
String,
MMBased,
NotNullAttribute,
- NormalStorageAttribute,
+ 0,
0,
1,
16);
@@ -376,7 +376,7 @@ create_table_subscriber(Ndb * pNdb){
String,
MMBased,
NotNullAttribute,
- NormalStorageAttribute,
+ 0,
0,
1,
16);
@@ -494,7 +494,7 @@ create_table_session(Ndb * pNdb){
String,
MMBased,
NotNullAttribute,
- NormalStorageAttribute,
+ 0,
0,
1,
16);
diff --git a/ndb/test/ndbapi/bench/userInterface.h b/ndb/test/ndbapi/bench/userInterface.h
index 9e3b6f8f2a5..bad61fcf171 100644
--- a/ndb/test/ndbapi/bench/userInterface.h
+++ b/ndb/test/ndbapi/bench/userInterface.h
@@ -101,7 +101,7 @@ extern "C" {
typedef struct {
struct Ndb_cluster_connection* pNCC;
struct Ndb * pNDB;
- struct NdbConnection * pCurrTrans;
+ struct NdbTransaction * pCurrTrans;
} UserHandle;
/***************************************************************
diff --git a/ndb/test/ndbapi/create_all_tabs.cpp b/ndb/test/ndbapi/create_all_tabs.cpp
index 97236b98b36..f06078d67a2 100644
--- a/ndb/test/ndbapi/create_all_tabs.cpp
+++ b/ndb/test/ndbapi/create_all_tabs.cpp
@@ -47,7 +47,12 @@ int main(int argc, const char** argv){
}
// Connect to Ndb
- Ndb MyNdb( "TEST_DB" );
+ Ndb_cluster_connection con;
+ if(con.connect(12, 5, 1) != 0)
+ {
+ return NDBT_ProgramExit(NDBT_FAILED);
+ }
+ Ndb MyNdb(&con, "TEST_DB" );
if(MyNdb.init() != 0){
ERR(MyNdb.getNdbError());
diff --git a/ndb/test/ndbapi/create_tab.cpp b/ndb/test/ndbapi/create_tab.cpp
index 283c83d30e0..b35c8655236 100644
--- a/ndb/test/ndbapi/create_tab.cpp
+++ b/ndb/test/ndbapi/create_tab.cpp
@@ -77,8 +77,12 @@ int main(int argc, const char** argv){
*/
// Connect to Ndb
- Ndb::setConnectString(_connectstr);
- Ndb MyNdb( "TEST_DB" );
+ Ndb_cluster_connection con(_connectstr);
+ if(con.connect(12, 5, 1) != 0)
+ {
+ return NDBT_ProgramExit(NDBT_FAILED);
+ }
+ Ndb MyNdb(&con, "TEST_DB" );
if(MyNdb.init() != 0){
ERR(MyNdb.getNdbError());
diff --git a/ndb/test/ndbapi/drop_all_tabs.cpp b/ndb/test/ndbapi/drop_all_tabs.cpp
index c024a81a5e6..f12d750916e 100644
--- a/ndb/test/ndbapi/drop_all_tabs.cpp
+++ b/ndb/test/ndbapi/drop_all_tabs.cpp
@@ -40,7 +40,13 @@ int main(int argc, const char** argv){
}
// Connect to Ndb
- Ndb MyNdb( "TEST_DB" );
+ Ndb_cluster_connection con;
+ if(con.connect(12, 5, 1) != 0)
+ {
+ return NDBT_ProgramExit(NDBT_FAILED);
+ }
+
+ Ndb MyNdb(&con, "TEST_DB" );
if(MyNdb.init() != 0){
ERR(MyNdb.getNdbError());
diff --git a/ndb/test/ndbapi/flexAsynch.cpp b/ndb/test/ndbapi/flexAsynch.cpp
index 4b87b2c70ed..8a7dbec1561 100644
--- a/ndb/test/ndbapi/flexAsynch.cpp
+++ b/ndb/test/ndbapi/flexAsynch.cpp
@@ -16,6 +16,7 @@
+#include <ndb_global.h>
#include "NdbApi.hpp"
#include <NdbSchemaCon.hpp>
#include <NdbMain.h>
@@ -143,6 +144,8 @@ tellThreads(StartType what)
ThreadStart[i] = what;
}
+static Ndb_cluster_connection *g_cluster_connection= 0;
+
NDB_COMMAND(flexAsynch, "flexAsynch", "flexAsynch", "flexAsynch", 65535)
{
ndb_init();
@@ -200,7 +203,14 @@ NDB_COMMAND(flexAsynch, "flexAsynch", "flexAsynch", "flexAsynch", 65535)
setAttrNames();
setTableNames();
- Ndb * pNdb = new Ndb("TEST_DB");
+ Ndb_cluster_connection con;
+ if(con.connect(12, 5, 1) != 0)
+ {
+ return NDBT_ProgramExit(NDBT_FAILED);
+ }
+ g_cluster_connection= &con;
+
+ Ndb * pNdb = new Ndb(g_cluster_connection, "TEST_DB");
pNdb->init();
tNodeId = pNdb->getNodeId();
@@ -225,7 +235,7 @@ NDB_COMMAND(flexAsynch, "flexAsynch", "flexAsynch", "flexAsynch", 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,
@@ -468,7 +478,7 @@ threadLoop(void* ThreadData)
StartType tType;
ThreadNdb* tabThread = (ThreadNdb*)ThreadData;
int threadNo = tabThread->ThreadNo;
- localNdb = new Ndb("TEST_DB");
+ localNdb = new Ndb(g_cluster_connection, "TEST_DB");
localNdb->init(1024);
localNdb->waitUntilReady(10000);
unsigned int threadBase = (threadNo << 16) + tNodeId ;
diff --git a/ndb/test/ndbapi/flexBench.cpp b/ndb/test/ndbapi/flexBench.cpp
index cc2bfb391da..abddecfdc40 100644
--- a/ndb/test/ndbapi/flexBench.cpp
+++ b/ndb/test/ndbapi/flexBench.cpp
@@ -49,6 +49,7 @@ Arguments:
* *************************************************** */
+#include <ndb_global.h>
#include "NdbApi.hpp"
#include <NdbMain.h>
@@ -279,6 +280,8 @@ tellThreads(ThreadData* pt, StartType what)
pt[i].threadStart = what;
}
+static Ndb_cluster_connection *g_cluster_connection= 0;
+
NDB_COMMAND(flexBench, "flexBench", "flexBench", "flexbench", 65535)
{
ndb_init();
@@ -326,8 +329,16 @@ NDB_COMMAND(flexBench, "flexBench", "flexBench", "flexbench", 65535)
NdbThread_SetConcurrencyLevel(tNoOfThreads + 2);
+ Ndb_cluster_connection con;
+ if(con.connect(12, 5, 1) != 0)
+ {
+ return NDBT_ProgramExit(NDBT_FAILED);
+ }
+
+ g_cluster_connection= &con;
+
Ndb* pNdb;
- pNdb = new Ndb( "TEST_DB" );
+ pNdb = new Ndb(&con, "TEST_DB" );
pNdb->init();
tNodeId = pNdb->getNodeId();
@@ -605,7 +616,7 @@ static void* flexBenchThread(void* pArg)
attrValue = (int*)malloc(nReadBuffSize) ;
attrRefValue = (int*)malloc(nRefBuffSize) ;
pOps = (NdbOperation**)malloc(tNoOfTables*sizeof(NdbOperation*)) ;
- pNdb = new Ndb( "TEST_DB" );
+ pNdb = new Ndb(g_cluster_connection, "TEST_DB" );
if(!attrValue || !attrRefValue || !pOps || !pNdb){
// Check allocations to make sure we got all the memory we asked for
diff --git a/ndb/test/ndbapi/flexHammer.cpp b/ndb/test/ndbapi/flexHammer.cpp
index 13cd2d5e561..f254b1e5ccf 100644
--- a/ndb/test/ndbapi/flexHammer.cpp
+++ b/ndb/test/ndbapi/flexHammer.cpp
@@ -47,6 +47,7 @@ Revision history:
* *************************************************** */
+#include <ndb_global.h>
#include <NdbApi.hpp>
#include <NdbMain.h>
@@ -174,6 +175,8 @@ tellThreads(ThreadNdb* threadArrayP, const StartType what)
threadArrayP[i].threadStart = what;
} // for
} // tellThreads
+
+static Ndb_cluster_connection *g_cluster_connection= 0;
NDB_COMMAND(flexHammer, "flexHammer", "flexHammer", "flexHammer", 65535)
//main(int argc, const char** argv)
@@ -213,7 +216,13 @@ NDB_COMMAND(flexHammer, "flexHammer", "flexHammer", "flexHammer", 65535)
// NdbThread_SetConcurrencyLevel(tNoOfThreads + 2);
// Create and init Ndb object
- pMyNdb = new Ndb("TEST_DB");
+ Ndb_cluster_connection con;
+ if(con.connect(12, 5, 1) != 0)
+ {
+ return NDBT_ProgramExit(NDBT_FAILED);
+ }
+ g_cluster_connection= &con;
+ pMyNdb = new Ndb(g_cluster_connection, "TEST_DB");
pMyNdb->init();
// Wait for Ndb to become ready
@@ -345,7 +354,7 @@ flexHammerThread(void* pArg)
for (i = 0; i < MAXATTRSIZE; i++)
attrValue[i] = 0;
// Ndb object for each thread
- pMyNdb = new Ndb( "TEST_DB" );
+ pMyNdb = new Ndb(g_cluster_connection, "TEST_DB" );
pMyNdb->init();
if (pMyNdb->waitUntilReady(10000) != 0) {
// Error, NDB is not ready
diff --git a/ndb/test/ndbapi/flexTT.cpp b/ndb/test/ndbapi/flexTT.cpp
index 8d5be2bb399..7cd5ac8e3b4 100644
--- a/ndb/test/ndbapi/flexTT.cpp
+++ b/ndb/test/ndbapi/flexTT.cpp
@@ -169,6 +169,8 @@ tellThreads(StartType what)
ThreadStart[i] = what;
}
+static Ndb_cluster_connection *g_cluster_connection= 0;
+
NDB_COMMAND(flexTT, "flexTT", "flexTT", "flexTT", 65535)
{
ndb_init();
@@ -226,7 +228,14 @@ NDB_COMMAND(flexTT, "flexTT", "flexTT", "flexTT", 65535)
setAttrNames();
setTableNames();
- Ndb * pNdb = new Ndb("TEST_DB");
+ Ndb_cluster_connection con;
+ if(con.connect(12, 5, 1) != 0)
+ {
+ return NDBT_ProgramExit(NDBT_FAILED);
+ }
+ g_cluster_connection= &con;
+
+ Ndb * pNdb = new Ndb(g_cluster_connection, "TEST_DB");
pNdb->init();
tNodeId = pNdb->getNodeId();
@@ -334,7 +343,7 @@ threadLoop(void* ThreadData)
void * mem = malloc(sizeof(TransNdb)*tNoOfParallelTrans);
TransNdb* pTransData = (TransNdb*)mem;
- localNdb = new Ndb("TEST_DB");
+ localNdb = new Ndb(g_cluster_connection, "TEST_DB");
localNdb->init(1024);
localNdb->waitUntilReady();
diff --git a/ndb/test/ndbapi/flex_bench_mysql.cpp b/ndb/test/ndbapi/flex_bench_mysql.cpp
index c15175bfb00..3efb7ee2094 100644
--- a/ndb/test/ndbapi/flex_bench_mysql.cpp
+++ b/ndb/test/ndbapi/flex_bench_mysql.cpp
@@ -397,6 +397,7 @@ NDB_COMMAND(flexBench, "flexBench", "flexBench", "flexbench", 65535)
ndbout << "Connect failed" <<endl;
returnValue = NDBT_FAILED;
}
+ mysql.reconnect= 1;
}
if(returnValue == NDBT_OK){
mysql_set_server_option(&mysql, MYSQL_OPTION_MULTI_STATEMENTS_ON);
@@ -712,6 +713,7 @@ static void* flexBenchThread(void* pArg)
ndbout << "failed" << endl;
return 0;
}
+ mysql.reconnect= 1;
ndbout << "ok" << endl;
int r;
diff --git a/ndb/test/ndbapi/slow_select.cpp b/ndb/test/ndbapi/slow_select.cpp
index 625dbc34457..8d615fa5771 100644
--- a/ndb/test/ndbapi/slow_select.cpp
+++ b/ndb/test/ndbapi/slow_select.cpp
@@ -1,4 +1,5 @@
+#include <ndb_global.h>
#include <NdbApi.hpp>
#include <NdbOut.hpp>
#include <NdbTick.h>
@@ -8,18 +9,17 @@ S_Scan {
const char * m_table;
const char * m_index;
NdbIndexScanOperation * m_scan;
- NdbResultSet * m_result;
Uint32 metaid;
Uint32 match_count;
Uint32 row_count;
};
static S_Scan g_scans[] = {
- { "affiliatestometa", "ind_affiliatestometa", 0, 0, 0, 0, 0 },
- { "media", "metaid", 0, 0, 0, 0, 0 },
- { "meta", "PRIMARY", 0, 0, 0, 0, 0 },
- { "artiststometamap", "PRIMARY", 0, 0, 0, 0, 0 },
- { "subgenrestometamap", "metaid", 0, 0, 0, 0, 0 }
+ { "affiliatestometa", "ind_affiliatestometa", 0, 0, 0, 0 },
+ { "media", "metaid", 0, 0, 0, 0 },
+ { "meta", "PRIMARY", 0, 0, 0, 0 },
+ { "artiststometamap", "PRIMARY", 0, 0, 0, 0 },
+ { "subgenrestometamap", "metaid", 0, 0, 0, 0 }
};
#define require(x) if(!(x)) { ndbout << "LINE: " << __LINE__ << endl;abort(); }
@@ -37,7 +37,14 @@ static void lookup();
int
main(void){
ndb_init();
- Ndb g_ndb("test");
+
+ Ndb_cluster_connection con;
+ if(con.connect(12, 5, 1) != 0)
+ {
+ return 1;
+ }
+
+ Ndb g_ndb(&con, "test");
g_ndb.init(1024);
require(g_ndb.waitUntilReady() == 0);
@@ -58,9 +65,8 @@ main(void){
g_scans[i].m_table);
NdbIndexScanOperation* scan = g_scans[i].m_scan;
require(scan);
- g_scans[i].m_result = scan->readTuples(NdbScanOperation::LM_CommittedRead,
- 0, 0, true);
- require(g_scans[i].m_result);
+ require(scan->readTuples(NdbScanOperation::LM_CommittedRead,
+ 0, 0, true) == 0);
}
require(!g_scans[0].m_scan->setBound((Uint32)0,
@@ -125,7 +131,7 @@ main(void){
//ndbout_c("%s - %d", g_scans[i].m_table, g_scans[i].metaid);
for(i = 0; i<prev_F_sz; i++){
- int res = F[i]->m_result->nextResult();
+ int res = F[i]->m_scan->nextResult();
if(res == -1)
abort();
diff --git a/ndb/test/ndbapi/testBackup.cpp b/ndb/test/ndbapi/testBackup.cpp
index 14198c250c7..1ab348e735f 100644
--- a/ndb/test/ndbapi/testBackup.cpp
+++ b/ndb/test/ndbapi/testBackup.cpp
@@ -271,7 +271,7 @@ int runDropTable(NDBT_Context* ctx, NDBT_Step* step){
#include "bank/Bank.hpp"
int runCreateBank(NDBT_Context* ctx, NDBT_Step* step){
- Bank bank;
+ Bank bank(ctx->m_cluster_connection);
int overWriteExisting = true;
if (bank.createAndLoadBank(overWriteExisting, 10) != NDBT_OK)
return NDBT_FAILED;
@@ -279,7 +279,7 @@ int runCreateBank(NDBT_Context* ctx, NDBT_Step* step){
}
int runBankTimer(NDBT_Context* ctx, NDBT_Step* step){
- Bank bank;
+ Bank bank(ctx->m_cluster_connection);
int wait = 30; // Max seconds between each "day"
int yield = 1; // Loops before bank returns
@@ -290,7 +290,7 @@ int runBankTimer(NDBT_Context* ctx, NDBT_Step* step){
}
int runBankTransactions(NDBT_Context* ctx, NDBT_Step* step){
- Bank bank;
+ Bank bank(ctx->m_cluster_connection);
int wait = 10; // Max ms between each transaction
int yield = 100; // Loops before bank returns
@@ -301,7 +301,7 @@ int runBankTransactions(NDBT_Context* ctx, NDBT_Step* step){
}
int runBankGL(NDBT_Context* ctx, NDBT_Step* step){
- Bank bank;
+ Bank bank(ctx->m_cluster_connection);
int yield = 20; // Loops before bank returns
int result = NDBT_OK;
@@ -315,7 +315,7 @@ int runBankGL(NDBT_Context* ctx, NDBT_Step* step){
}
int runBankSum(NDBT_Context* ctx, NDBT_Step* step){
- Bank bank;
+ Bank bank(ctx->m_cluster_connection);
int wait = 2000; // Max ms between each sum of accounts
int yield = 1; // Loops before bank returns
int result = NDBT_OK;
@@ -330,7 +330,7 @@ int runBankSum(NDBT_Context* ctx, NDBT_Step* step){
}
int runDropBank(NDBT_Context* ctx, NDBT_Step* step){
- Bank bank;
+ Bank bank(ctx->m_cluster_connection);
if (bank.dropBank() != NDBT_OK)
return NDBT_FAILED;
return NDBT_OK;
@@ -404,7 +404,7 @@ int runRestoreBankAndVerify(NDBT_Context* ctx, NDBT_Step* step){
// To erase all tables from cache(s)
// To be removed, maybe replaced by ndb.invalidate();
{
- Bank bank;
+ Bank bank(ctx->m_cluster_connection);
if (bank.dropBank() != NDBT_OK){
result = NDBT_FAILED;
@@ -427,7 +427,7 @@ int runRestoreBankAndVerify(NDBT_Context* ctx, NDBT_Step* step){
ndbout << "Backup " << backupId << " restored" << endl;
// Let bank verify
- Bank bank;
+ Bank bank(ctx->m_cluster_connection);
int wait = 0;
int yield = 1;
diff --git a/ndb/test/ndbapi/testBitfield.cpp b/ndb/test/ndbapi/testBitfield.cpp
new file mode 100644
index 00000000000..e26f495f5a4
--- /dev/null
+++ b/ndb/test/ndbapi/testBitfield.cpp
@@ -0,0 +1,198 @@
+
+#include <ndb_global.h>
+#include <ndb_opts.h>
+#include <NDBT.hpp>
+#include <NdbApi.hpp>
+#include <HugoTransactions.hpp>
+
+static const char* _dbname = "TEST_DB";
+static int g_loops = 7;
+
+static void usage()
+{
+ ndb_std_print_version();
+}
+#if 0
+static my_bool
+get_one_option(int optid, const struct my_option *opt __attribute__((unused)),
+ const char *argument)
+{
+ return ndb_std_get_one_option(optid, opt, argument ? argument :
+ "d:t:O,/tmp/testBitfield.trace");
+}
+#endif
+
+static const NdbDictionary::Table* create_random_table(Ndb*);
+static int transactions(Ndb*, const NdbDictionary::Table* tab);
+static int unique_indexes(Ndb*, const NdbDictionary::Table* tab);
+static int ordered_indexes(Ndb*, const NdbDictionary::Table* tab);
+static int node_restart(Ndb*, const NdbDictionary::Table* tab);
+static int system_restart(Ndb*, const NdbDictionary::Table* tab);
+
+int
+main(int argc, char** argv){
+ NDB_INIT(argv[0]);
+ const char *load_default_groups[]= { "mysql_cluster",0 };
+ load_defaults("my",load_default_groups,&argc,&argv);
+ int ho_error;
+
+ argc--;
+ argv++;
+
+ Ndb_cluster_connection con(opt_connect_str);
+ if(con.connect(12, 5, 1))
+ {
+ return NDBT_ProgramExit(NDBT_FAILED);
+ }
+
+
+ Ndb* pNdb;
+ pNdb = new Ndb(&con, _dbname);
+ pNdb->init();
+ while (pNdb->waitUntilReady() != 0);
+ int res = NDBT_FAILED;
+
+ NdbDictionary::Dictionary * dict = pNdb->getDictionary();
+
+ const NdbDictionary::Table* pTab = 0;
+ for (int i = 0; i < (argc ? argc : g_loops) ; i++)
+ {
+ res = NDBT_FAILED;
+ if(argc == 0)
+ {
+ pTab = create_random_table(pNdb);
+ }
+ else
+ {
+ dict->dropTable(argv[i]);
+ NDBT_Tables::createTable(pNdb, argv[i]);
+ pTab = dict->getTable(argv[i]);
+ }
+
+ if (pTab == 0)
+ {
+ ndbout << "Failed to create table" << endl;
+ ndbout << dict->getNdbError() << endl;
+ break;
+ }
+
+ if(transactions(pNdb, pTab))
+ break;
+
+ if(unique_indexes(pNdb, pTab))
+ break;
+
+ if(ordered_indexes(pNdb, pTab))
+ break;
+
+ if(node_restart(pNdb, pTab))
+ break;
+
+ if(system_restart(pNdb, pTab))
+ break;
+
+ dict->dropTable(pTab->getName());
+ res = NDBT_OK;
+ }
+
+ if(res != NDBT_OK && pTab)
+ {
+ dict->dropTable(pTab->getName());
+ }
+
+ delete pNdb;
+ return NDBT_ProgramExit(res);
+}
+
+static
+const NdbDictionary::Table*
+create_random_table(Ndb* pNdb)
+{
+ do {
+ NdbDictionary::Table tab;
+ Uint32 cols = 1 + (rand() % (NDB_MAX_ATTRIBUTES_IN_TABLE - 1));
+ Uint32 keys = NDB_MAX_NO_OF_ATTRIBUTES_IN_KEY;
+ Uint32 length = 4090;
+ Uint32 key_size = NDB_MAX_KEYSIZE_IN_WORDS;
+
+ BaseString name;
+ name.assfmt("TAB_%d", rand() & 65535);
+ tab.setName(name.c_str());
+ for(int i = 0; i<cols && length > 2; i++)
+ {
+ NdbDictionary::Column col;
+ name.assfmt("COL_%d", i);
+ col.setName(name.c_str());
+ if(i == 0 || i == 1)
+ {
+ col.setType(NdbDictionary::Column::Unsigned);
+ col.setLength(1);
+ col.setNullable(false);
+ col.setPrimaryKey(i == 0);
+ tab.addColumn(col);
+ continue;
+ }
+
+ col.setType(NdbDictionary::Column::Bit);
+
+ Uint32 len = 1 + (rand() % (length - 1));
+ col.setLength(len); length -= len;
+ int nullable = (rand() >> 16) & 1;
+ col.setNullable(nullable); length -= nullable;
+ col.setPrimaryKey(false);
+ tab.addColumn(col);
+ }
+
+ pNdb->getDictionary()->dropTable(tab.getName());
+ if(pNdb->getDictionary()->createTable(tab) == 0)
+ {
+ ndbout << (NDBT_Table&)tab << endl;
+ return pNdb->getDictionary()->getTable(tab.getName());
+ }
+ } while(0);
+ return 0;
+}
+
+static
+int
+transactions(Ndb* pNdb, const NdbDictionary::Table* tab)
+{
+ int i = 0;
+ HugoTransactions trans(* tab);
+ i |= trans.loadTable(pNdb, 1000);
+ i |= trans.pkReadRecords(pNdb, 1000, 13);
+ i |= trans.scanReadRecords(pNdb, 1000, 25);
+ i |= trans.pkUpdateRecords(pNdb, 1000, 37);
+ i |= trans.scanUpdateRecords(pNdb, 1000, 25);
+ i |= trans.pkDelRecords(pNdb, 500, 23);
+ i |= trans.clearTable(pNdb);
+ return i;
+}
+
+static
+int
+unique_indexes(Ndb* pNdb, const NdbDictionary::Table* tab)
+{
+ return 0;
+}
+
+static
+int
+ordered_indexes(Ndb* pNdb, const NdbDictionary::Table* tab)
+{
+ return 0;
+}
+
+static
+int
+node_restart(Ndb* pNdb, const NdbDictionary::Table* tab)
+{
+ return 0;
+}
+
+static
+int
+system_restart(Ndb* pNdb, const NdbDictionary::Table* tab)
+{
+ return 0;
+}
diff --git a/ndb/test/ndbapi/testBlobs.cpp b/ndb/test/ndbapi/testBlobs.cpp
index efbdceac5a6..a88d7d21820 100644
--- a/ndb/test/ndbapi/testBlobs.cpp
+++ b/ndb/test/ndbapi/testBlobs.cpp
@@ -23,14 +23,13 @@
#include <NdbOut.hpp>
#include <NdbTest.hpp>
#include <NdbTick.h>
-#include <ndb/src/ndbapi/NdbBlobImpl.hpp>
struct Bcol {
bool m_nullable;
unsigned m_inline;
unsigned m_partsize;
unsigned m_stripe;
- char m_btname[NdbBlobImpl::BlobTableNameSize];
+ char m_btname[200];
Bcol(bool a, unsigned b, unsigned c, unsigned d) :
m_nullable(a),
m_inline(b),
@@ -741,10 +740,9 @@ verifyBlobTable(const Bcol& b, const Bval& v, Uint32 pk1, bool exists)
NdbRecAttr* ra_pk;
NdbRecAttr* ra_part;
NdbRecAttr* ra_data;
- NdbResultSet* rs;
CHK((g_con = g_ndb->startTransaction()) != 0);
CHK((g_ops = g_con->getNdbScanOperation(b.m_btname)) != 0);
- CHK((rs = g_ops->readTuples()) != 0);
+ CHK(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);
@@ -758,7 +756,7 @@ verifyBlobTable(const Bcol& b, const Bval& v, Uint32 pk1, bool exists)
memset(seen, 0, partcount);
while (1) {
int ret;
- CHK((ret = rs->nextResult()) == 0 || ret == 1);
+ CHK((ret = g_ops->nextResult()) == 0 || ret == 1);
if (ret == 1)
break;
if (pk1 != ra_pk->u_32_value())
@@ -1106,14 +1104,13 @@ readScan(int style, bool idx)
DBG("--- " << "readScan" << (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);
}
- CHK((rs = g_ops->readTuples(NdbScanOperation::LM_Read)) != 0);
+ CHK(g_ops->readTuples(NdbScanOperation::LM_Read) == 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);
@@ -1129,7 +1126,7 @@ readScan(int style, bool idx)
int ret;
tup.m_pk1 = (Uint32)-1;
memset(tup.m_pk2, 'x', g_opt.m_pk2len);
- CHK((ret = rs->nextResult(true)) == 0 || ret == 1);
+ CHK((ret = g_ops->nextResult(true)) == 0 || ret == 1);
if (ret == 1)
break;
DBG("readScan" << (idx ? "Idx" : "") << " pk1=" << hex << tup.m_pk1);
@@ -1159,14 +1156,13 @@ updateScan(int style, bool idx)
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);
}
- CHK((rs = g_ops->readTuples(NdbScanOperation::LM_Exclusive)) != 0);
+ CHK(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);
@@ -1176,7 +1172,7 @@ updateScan(int style, bool idx)
int ret;
tup.m_pk1 = (Uint32)-1;
memset(tup.m_pk2, 'x', g_opt.m_pk2len);
- CHK((ret = rs->nextResult(true)) == 0 || ret == 1);
+ CHK((ret = g_ops->nextResult(true)) == 0 || ret == 1);
if (ret == 1)
break;
DBG("updateScan" << (idx ? "Idx" : "") << " pk1=" << hex << tup.m_pk1);
@@ -1185,7 +1181,7 @@ updateScan(int style, bool idx)
// calculate new blob values
calcBval(g_tups[k], false);
tup.copyfrom(g_tups[k]);
- CHK((g_opr = rs->updateTuple()) != 0);
+ CHK((g_opr = g_ops->updateCurrentTuple()) != 0);
CHK(getBlobHandles(g_opr) == 0);
if (style == 0) {
CHK(setBlobValue(tup) == 0);
@@ -1212,14 +1208,13 @@ deleteScan(bool idx)
{
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->getNdbIndexScanOperation(g_opt.m_x2name, g_opt.m_tname)) != 0);
}
- CHK((rs = g_ops->readTuples(NdbScanOperation::LM_Exclusive)) != 0);
+ CHK(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);
@@ -1229,11 +1224,11 @@ deleteScan(bool idx)
int ret;
tup.m_pk1 = (Uint32)-1;
memset(tup.m_pk2, 'x', g_opt.m_pk2len);
- CHK((ret = rs->nextResult()) == 0 || ret == 1);
+ CHK((ret = g_ops->nextResult()) == 0 || ret == 1);
if (ret == 1)
break;
DBG("deleteScan" << (idx ? "Idx" : "") << " pk1=" << hex << tup.m_pk1);
- CHK(rs->deleteTuple() == 0);
+ CHK(g_ops->deleteCurrentTuple() == 0);
CHK(g_con->execute(NoCommit) == 0);
Uint32 k = tup.m_pk1 - g_opt.m_pk1off;
CHK(k < g_opt.m_rows && g_tups[k].m_exists);
@@ -1611,12 +1606,11 @@ testperf()
// scan read char
{
DBG("--- scan read char ---");
- NdbResultSet* rs;
Uint32 a;
char b[20];
CHK((g_con = g_ndb->startTransaction()) != 0);
CHK((g_ops = g_con->getNdbScanOperation(tab.getName())) != 0);
- CHK((rs = g_ops->readTuples(NdbScanOperation::LM_Read)) != 0);
+ CHK(g_ops->readTuples(NdbScanOperation::LM_Read) == 0);
CHK(g_ops->getValue(cA, (char*)&a) != 0);
CHK(g_ops->getValue(cB, b) != 0);
CHK(g_con->execute(NoCommit) == 0);
@@ -1626,7 +1620,7 @@ testperf()
a = (Uint32)-1;
b[0] = 0;
int ret;
- CHK((ret = rs->nextResult(true)) == 0 || ret == 1);
+ CHK((ret = g_ops->nextResult(true)) == 0 || ret == 1);
if (ret == 1)
break;
CHK(a < g_opt.m_rowsperf && strcmp(b, "b") == 0);
@@ -1641,12 +1635,11 @@ testperf()
// scan read text
{
DBG("--- read text ---");
- NdbResultSet* rs;
Uint32 a;
char c[20];
CHK((g_con = g_ndb->startTransaction()) != 0);
CHK((g_ops = g_con->getNdbScanOperation(tab.getName())) != 0);
- CHK((rs = g_ops->readTuples(NdbScanOperation::LM_Read)) != 0);
+ CHK(g_ops->readTuples(NdbScanOperation::LM_Read) == 0);
CHK(g_ops->getValue(cA, (char*)&a) != 0);
CHK((g_bh1 = g_ops->getBlobHandle(cC)) != 0);
CHK(g_con->execute(NoCommit) == 0);
@@ -1656,7 +1649,7 @@ testperf()
a = (Uint32)-1;
c[0] = 0;
int ret;
- CHK((ret = rs->nextResult(true)) == 0 || ret == 1);
+ CHK((ret = g_ops->nextResult(true)) == 0 || ret == 1);
if (ret == 1)
break;
Uint32 m = 20;
diff --git a/ndb/test/ndbapi/testDataBuffers.cpp b/ndb/test/ndbapi/testDataBuffers.cpp
index 03d52252334..aaecb6ee61e 100644
--- a/ndb/test/ndbapi/testDataBuffers.cpp
+++ b/ndb/test/ndbapi/testDataBuffers.cpp
@@ -209,7 +209,7 @@ makeOff(int k)
}
static int
-testcase(int flag)
+testcase(Ndb_cluster_connection&cc, int flag)
{
ndbout << "--- case " << flag << " ---" << endl;
sprintf(tab, "TB%02d", flag);
@@ -254,7 +254,7 @@ testcase(int flag)
ndbout << "tab=" << tab << " cols=" << attrcnt
<< " size max=" << smax << " tot=" << stot << endl;
- ndb = new Ndb("TEST_DB");
+ ndb = new Ndb(&cc, "TEST_DB");
if (ndb->init() != 0)
return ndberror("init");
if (ndb->waitUntilReady(30) < 0)
@@ -443,9 +443,9 @@ testcase(int flag)
if ((con = ndb->startTransaction()) == 0)
return ndberror("startTransaction key=%d", key);
if ((op = sop = con->getNdbScanOperation(tab)) == 0)
- return ndberror("getNdbOperation key=%d", key);
- if ((rs = sop->readTuples(1)) == 0)
- return ndberror("openScanRead key=%d", key);
+ return ndberror("getNdbOperation key=%d", key);
+ if (sop->readTuples(1))
+ return ndberror("openScanRead key=%d", key);
{
col& c = ccol[0];
if (op->load_const_u32(1, key) < 0)
@@ -488,7 +488,7 @@ testcase(int flag)
if (con->execute(NoCommit) < 0)
return ndberror("executeScan key=%d", key);
int ret, cnt = 0;
- while ((ret = rs->nextResult()) == 0) {
+ while ((ret = sop->nextResult()) == 0) {
if (key != newkey)
return ndberror("unexpected key=%d newkey=%d", key, newkey);
for (i = 1; i < attrcnt; i++) {
@@ -606,10 +606,17 @@ NDB_COMMAND(testDataBuffers, "testDataBuffers", "testDataBuffers", "testDataBuff
}
}
unsigned ok = true;
+
+ Ndb_cluster_connection con;
+ if(con.connect(12, 5, 1))
+ {
+ return NDBT_ProgramExit(NDBT_FAILED);
+ }
+
for (i = 1; 0 == loopcnt || i <= loopcnt; i++) {
ndbout << "=== loop " << i << " ===" << endl;
for (int flag = 0; flag < (1<<testbits); flag++) {
- if (testcase(flag) < 0) {
+ if (testcase(con, flag) < 0) {
ok = false;
if (! kontinue)
goto out;
diff --git a/ndb/test/ndbapi/testDeadlock.cpp b/ndb/test/ndbapi/testDeadlock.cpp
index eb985e815ac..0070a7ecc83 100644
--- a/ndb/test/ndbapi/testDeadlock.cpp
+++ b/ndb/test/ndbapi/testDeadlock.cpp
@@ -49,7 +49,7 @@ printusage()
static Opt g_opt;
static NdbMutex *ndbout_mutex= NULL;
-
+static Ndb_cluster_connection *g_cluster_connection= 0;
#define DBG(x) \
do { \
if (! g_opt.m_dbg) break; \
@@ -91,7 +91,6 @@ struct Thr {
NdbConnection* m_con;
NdbScanOperation* m_scanop;
NdbIndexScanOperation* m_indexscanop;
- NdbResultSet* m_rs;
//
Thr(int no);
~Thr();
@@ -136,7 +135,6 @@ Thr::Thr(int no)
m_con = 0;
m_scanop = 0;
m_indexscanop = 0;
- m_rs = 0;
}
Thr::~Thr()
@@ -219,7 +217,7 @@ Thr::exit()
static int
runstep_connect(Thr& thr)
{
- Ndb* ndb = thr.m_ndb = new Ndb("TEST_DB");
+ Ndb* ndb = thr.m_ndb = new Ndb(g_cluster_connection, "TEST_DB");
CHN(ndb, ndb->init() == 0);
CHN(ndb, ndb->waitUntilReady() == 0);
DBG(thr << " connected");
@@ -374,7 +372,7 @@ wl1822_tx2_scanXY(Thr& thr)
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->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);
@@ -383,7 +381,7 @@ wl1822_tx2_scanXY(Thr& thr)
DBG("before row " << row);
int ret;
wl1822_bufA = wl1822_bufB = ~0;
- CHN(con, (ret = rs->nextResult(true)) == 0);
+ CHN(con, (ret = scanop->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]]);
@@ -419,14 +417,13 @@ wl1822_tx2_scanZ_close(Thr& thr)
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);
+ assert(ndb != 0 && con != 0 && scanop != 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);
+ CHN(con, (ret = scanop->nextResult(true)) == 0 || ret == 1);
if (ret == 1)
break;
DBG("got row " << row << " a=" << wl1822_bufA << " b=" << wl1822_bufB);
@@ -467,7 +464,7 @@ wl1822_main(char scantx)
// run the steps
for (unsigned i = 0; i < wl1822_stepcount; i++) {
DBG("step " << i << " start");
- for (int n = 0; n < thrcount; n++) {
+ for (n = 0; n < thrcount; n++) {
Thr& thr = *thrlist[n];
Runstep runstep = wl1822_step[i][n];
if (runstep != 0)
@@ -506,10 +503,18 @@ NDB_COMMAND(testOdbcDriver, "testDeadlock", "testDeadlock", "testDeadlock", 6553
printusage();
return NDBT_ProgramExit(NDBT_WRONGARGS);
}
+
+ Ndb_cluster_connection con;
+ if(con.connect(12, 5, 1) != 0)
+ {
+ return NDBT_ProgramExit(NDBT_FAILED);
+ }
+ g_cluster_connection= &con;
+
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);
diff --git a/ndb/test/ndbapi/testDict.cpp b/ndb/test/ndbapi/testDict.cpp
index 5f88342705a..dd5846f0d62 100644
--- a/ndb/test/ndbapi/testDict.cpp
+++ b/ndb/test/ndbapi/testDict.cpp
@@ -125,6 +125,16 @@ int runCreateTheTable(NDBT_Context* ctx, NDBT_Step* step){
return NDBT_OK;
}
+int runDropTheTable(NDBT_Context* ctx, NDBT_Step* step){
+ Ndb* pNdb = GETNDB(step);
+ const NdbDictionary::Table* pTab = ctx->getTab();
+
+ // Try to create table in db
+ pNdb->getDictionary()->dropTable(pTab->getName());
+
+ return NDBT_OK;
+}
+
int runCreateTableWhenDbIsFull(NDBT_Context* ctx, NDBT_Step* step){
Ndb* pNdb = GETNDB(step);
int result = NDBT_OK;
@@ -418,103 +428,99 @@ int runUseTableUntilStopped(NDBT_Context* ctx, NDBT_Step* step){
}
-int runCreateMaxTables(NDBT_Context* ctx, NDBT_Step* step){
- int failures = 0;
+int
+runCreateMaxTables(NDBT_Context* ctx, NDBT_Step* step)
+{
char tabName[256];
int numTables = ctx->getProperty("tables", 1000);
Ndb* pNdb = GETNDB(step);
-
- for (int i = 0; i < numTables && failures < 5; i++){
+ NdbDictionary::Dictionary* pDic = pNdb->getDictionary();
+ int i = 0;
+ for (i = 0; i < numTables; i++) {
BaseString::snprintf(tabName, 256, "MAXTAB%d", i);
-
- if (pNdb->waitUntilReady(30) != 0){
+ if (pNdb->waitUntilReady(30) != 0) {
// Db is not ready, return with failure
return NDBT_FAILED;
}
-
const NdbDictionary::Table* pTab = ctx->getTab();
- ndbout << "|- " << tabName << endl;
-
+ //ndbout << "|- " << tabName << endl;
// Set new name for T1
NdbDictionary::Table newTab(* pTab);
newTab.setName(tabName);
-
+ // Drop any old (or try to)
+ (void)pDic->dropTable(newTab.getName());
// Try to create table in db
- if (newTab.createTableInDb(pNdb) != 0){
- ndbout << tabName << " coult not be created"<< endl;
- failures++;
- continue;
+ if (newTab.createTableInDb(pNdb) != 0) {
+ ndbout << tabName << " could not be created: "
+ << pDic->getNdbError() << endl;
+ if (pDic->getNdbError().code == 707 ||
+ pDic->getNdbError().code == 708 ||
+ pDic->getNdbError().code == 826 ||
+ pDic->getNdbError().code == 827)
+ break;
+ return NDBT_FAILED;
}
-
// Verify that table exists in db
const NdbDictionary::Table* pTab3 =
NDBT_Table::discoverTableFromDb(pNdb, tabName) ;
if (pTab3 == NULL){
- ndbout << tabName << " was not found in DB"<< endl;
- failures++;
- continue;
+ ndbout << tabName << " was not found in DB: "
+ << pDic->getNdbError() << endl;
+ return NDBT_FAILED;
}
-
- if (pTab->equal(*pTab3) == false){
- ndbout << "It was not equal" << endl;
- failures++;
+ if (! newTab.equal(*pTab3)) {
+ ndbout << "It was not equal" << endl; abort();
+ return NDBT_FAILED;
}
-
- int records = 1000;
+ int records = ctx->getNumRecords();
HugoTransactions hugoTrans(*pTab3);
- if (hugoTrans.loadTable(pNdb, records) != 0){
+ if (hugoTrans.loadTable(pNdb, records) != 0) {
ndbout << "It can NOT be loaded" << endl;
- } else{
- ndbout << "It can be loaded" << endl;
-
- UtilTransactions utilTrans(*pTab3);
- if (utilTrans.clearTable(pNdb, records, 64) != 0){
- ndbout << "It can NOT be cleared" << endl;
- } else{
- ndbout << "It can be cleared" << endl;
- }
+ return NDBT_FAILED;
+ }
+ UtilTransactions utilTrans(*pTab3);
+ if (utilTrans.clearTable(pNdb, records, 64) != 0) {
+ ndbout << "It can NOT be cleared" << endl;
+ return NDBT_FAILED;
}
-
}
- if (pNdb->waitUntilReady(30) != 0){
+ if (pNdb->waitUntilReady(30) != 0) {
// Db is not ready, return with failure
return NDBT_FAILED;
}
+ ctx->setProperty("maxtables", i);
// HURRAAA!
return NDBT_OK;
}
-int runDropMaxTables(NDBT_Context* ctx, NDBT_Step* step){
- int result = NDBT_OK;
+int runDropMaxTables(NDBT_Context* ctx, NDBT_Step* step)
+{
char tabName[256];
- int numTables = ctx->getProperty("tables", 1000);
+ int numTables = ctx->getProperty("maxtables", (Uint32)0);
Ndb* pNdb = GETNDB(step);
-
- for (int i = 0; i < numTables; i++){
+ NdbDictionary::Dictionary* pDic = pNdb->getDictionary();
+ for (int i = 0; i < numTables; i++) {
BaseString::snprintf(tabName, 256, "MAXTAB%d", i);
-
- if (pNdb->waitUntilReady(30) != 0){
+ if (pNdb->waitUntilReady(30) != 0) {
// Db is not ready, return with failure
return NDBT_FAILED;
}
-
// Verify that table exists in db
const NdbDictionary::Table* pTab3 =
NDBT_Table::discoverTableFromDb(pNdb, tabName) ;
- if (pTab3 == NULL){
- ndbout << tabName << " was not found in DB"<< endl;
- continue;
+ if (pTab3 == NULL) {
+ ndbout << tabName << " was not found in DB: "
+ << pDic->getNdbError() << endl;
+ return NDBT_FAILED;
}
-
-
// Try to drop table in db
- if (pNdb->getDictionary()->dropTable(pTab3->getName()) != 0){
- ndbout << tabName << " coult not be dropped"<< endl;
- result = NDBT_FAILED;
+ if (pDic->dropTable(pTab3->getName()) != 0) {
+ ndbout << tabName << " could not be dropped: "
+ << pDic->getNdbError() << endl;
+ return NDBT_FAILED;
}
-
}
- return result;
+ return NDBT_OK;
}
int runTestFragmentTypes(NDBT_Context* ctx, NDBT_Step* step){
@@ -524,13 +530,6 @@ int runTestFragmentTypes(NDBT_Context* ctx, NDBT_Step* step){
int result = NDBT_OK;
NdbRestarter restarter;
- // enum FragmentType {
- // Unknown = 0,
- // Single = 1, ///< Only one fragment
- // All = 2, ///< Default value. One fragment per node group
- // AllLarge = 3 ///< Sixten fragments per node group.
- // };
-
if (pNdb->waitUntilReady(30) != 0){
// Db is not ready, return with failure
return NDBT_FAILED;
@@ -547,6 +546,7 @@ int runTestFragmentTypes(NDBT_Context* ctx, NDBT_Step* step){
if (newTab.createTableInDb(pNdb) != 0){
ndbout << newTab.getName() << " could not be created"
<< ", fragmentType = "<<fragTtype <<endl;
+ ndbout << pNdb->getDictionary()->getNdbError() << endl;
return NDBT_FAILED;
}
@@ -564,13 +564,17 @@ int runTestFragmentTypes(NDBT_Context* ctx, NDBT_Step* step){
result = NDBT_FAILED;
goto drop_the_tab;
}
-
+/**
+ This test does not work since fragmentation is
+ decided by the kernel, hence the fragementation
+ attribute on the column will differ
+
if (newTab.equal(*pTab3) == false){
ndbout << "It was not equal" << endl;
result = NDBT_FAILED;
goto drop_the_tab;
}
-
+*/
do {
HugoTransactions hugoTrans(*pTab3);
@@ -1005,10 +1009,10 @@ int runGetPrimaryKey(NDBT_Context* ctx, NDBT_Step* step){
struct ErrorCodes { int error_id; bool crash;};
ErrorCodes
NF_codes[] = {
- {6003, true},
- {6004, true},
+ {6003, true}
+ ,{6004, true}
//,6005, true,
- {7173, false}
+ //{7173, false}
};
int
@@ -1027,17 +1031,6 @@ runNF1(NDBT_Context* ctx, NDBT_Step* step){
int result = NDBT_OK;
- /**
- * Need to run LCP at high rate otherwise
- * packed replicas become "to many"
- */
- int val = DumpStateOrd::DihMinTimeBetweenLCP;
- if(restarter.dumpStateAllNodes(&val, 1) != 0){
- do { CHECK(0); } while(0);
- g_err << "Failed to set LCP to min value" << endl;
- return NDBT_FAILED;
- }
-
const int loops = ctx->getNumLoops();
for (int l = 0; l < loops && result == NDBT_OK ; l++){
const int sz = sizeof(NF_codes)/sizeof(NF_codes[0]);
@@ -1060,7 +1053,7 @@ runNF1(NDBT_Context* ctx, NDBT_Step* step){
CHECK2(dict->createTable(* pTab) == 0,
"failed to create table");
-
+
if (crash) {
CHECK2(restarter.waitNodesNoStart(&nodeId, 1) == 0,
"waitNodesNoStart failed");
@@ -1084,9 +1077,6 @@ runNF1(NDBT_Context* ctx, NDBT_Step* step){
CHECK2(restarter.waitClusterStarted() == 0,
"waitClusterStarted failed");
}
-
- CHECK2(restarter.dumpStateOneNode(nodeId, &val, 1) == 0,
- "Failed to set LCP to min value");
}
}
}
@@ -1583,21 +1573,26 @@ TESTCASE("CreateTableWhenDbIsFull",
INITIALIZER(runFillTable);
INITIALIZER(runCreateTableWhenDbIsFull);
INITIALIZER(runDropTableWhenDbIsFull);
- FINALIZER(runClearTable);
+ FINALIZER(runDropTheTable);
}
TESTCASE("FragmentTypeSingle",
"Create the table with fragment type Single\n"){
- TC_PROPERTY("FragmentType", 1);
+ TC_PROPERTY("FragmentType", NdbDictionary::Table::FragSingle);
+ INITIALIZER(runTestFragmentTypes);
+}
+TESTCASE("FragmentTypeAllSmall",
+ "Create the table with fragment type AllSmall\n"){
+ TC_PROPERTY("FragmentType", NdbDictionary::Table::FragAllSmall);
INITIALIZER(runTestFragmentTypes);
}
-TESTCASE("FragmentTypeAll",
- "Create the table with fragment type All\n"){
- TC_PROPERTY("FragmentType", 2);
+TESTCASE("FragmentTypeAllMedium",
+ "Create the table with fragment type AllMedium\n"){
+ TC_PROPERTY("FragmentType", NdbDictionary::Table::FragAllMedium);
INITIALIZER(runTestFragmentTypes);
}
TESTCASE("FragmentTypeAllLarge",
"Create the table with fragment type AllLarge\n"){
- TC_PROPERTY("FragmentType", 3);
+ TC_PROPERTY("FragmentType", NdbDictionary::Table::FragAllLarge);
INITIALIZER(runTestFragmentTypes);
}
TESTCASE("TemporaryTables",
@@ -1609,7 +1604,7 @@ TESTCASE("CreateMaxTables",
"Create tables until db says that it can't create any more\n"){
TC_PROPERTY("tables", 1000);
INITIALIZER(runCreateMaxTables);
- FINALIZER(runDropMaxTables);
+ INITIALIZER(runDropMaxTables);
}
TESTCASE("PkSizes",
"Create tables with all different primary key sizes.\n"\
diff --git a/ndb/test/ndbapi/testIndex.cpp b/ndb/test/ndbapi/testIndex.cpp
index d359f83257f..5785db232c4 100644
--- a/ndb/test/ndbapi/testIndex.cpp
+++ b/ndb/test/ndbapi/testIndex.cpp
@@ -1145,20 +1145,18 @@ runUniqueNullTransactions(NDBT_Context* ctx, NDBT_Step* step){
pTrans = pNdb->startTransaction();
NdbScanOperation * sOp;
NdbOperation * uOp;
- NdbResultSet * rs;
int eof;
if(!pTrans) goto done;
sOp = pTrans->getNdbScanOperation(pTab->getName());
if(!sOp) goto done;
- rs = sOp->readTuples(NdbScanOperation::LM_Exclusive);
- if(!rs) goto done;
+ if(sOp->readTuples(NdbScanOperation::LM_Exclusive)) goto done;
if(pTrans->execute(NoCommit) == -1) goto done;
- while((eof = rs->nextResult(true)) == 0){
+ while((eof = sOp->nextResult(true)) == 0){
do {
- NdbOperation * uOp = rs->updateTuple();
+ NdbOperation * uOp = sOp->updateCurrentTuple();
if(uOp == 0) goto done;
uOp->setValue(colId, 0);
- } while((eof = rs->nextResult(false)) == 0);
+ } while((eof = sOp->nextResult(false)) == 0);
eof = pTrans->execute(Commit);
if(eof == -1) goto done;
}
@@ -1279,7 +1277,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);
+ TC_PROPERTY("PauseThreads", 2);
INITIALIZER(runClearTable);
INITIALIZER(createRandomIndex);
INITIALIZER(runLoadTable);
@@ -1294,6 +1292,7 @@ TESTCASE("NFNR1_O",
"Test that indexes are correctly maintained during node fail and node restart"){
TC_PROPERTY("OrderedIndex", 1);
TC_PROPERTY("LoggedIndexes", (unsigned)0);
+ TC_PROPERTY("PauseThreads", 2);
INITIALIZER(runClearTable);
INITIALIZER(createRandomIndex);
INITIALIZER(runLoadTable);
@@ -1307,6 +1306,7 @@ TESTCASE("NFNR1_O",
TESTCASE("NFNR2",
"Test that indexes are correctly maintained during node fail and node restart"){
TC_PROPERTY("LoggedIndexes", (unsigned)0);
+ TC_PROPERTY("PauseThreads", 2);
INITIALIZER(runClearTable);
INITIALIZER(createRandomIndex);
INITIALIZER(createPkIndex);
@@ -1323,6 +1323,7 @@ TESTCASE("NFNR2_O",
"Test that indexes are correctly maintained during node fail and node restart"){
TC_PROPERTY("OrderedIndex", 1);
TC_PROPERTY("LoggedIndexes", (unsigned)0);
+ TC_PROPERTY("PauseThreads", 1);
INITIALIZER(runClearTable);
INITIALIZER(createRandomIndex);
INITIALIZER(createPkIndex);
@@ -1338,6 +1339,7 @@ TESTCASE("NFNR2_O",
TESTCASE("NFNR3",
"Test that indexes are correctly maintained during node fail and node restart"){
TC_PROPERTY("LoggedIndexes", (unsigned)0);
+ TC_PROPERTY("PauseThreads", 2);
INITIALIZER(runClearTable);
INITIALIZER(createRandomIndex);
INITIALIZER(createPkIndex);
@@ -1353,6 +1355,7 @@ TESTCASE("NFNR3_O",
"Test that indexes are correctly maintained during node fail and node restart"){
TC_PROPERTY("OrderedIndex", 1);
TC_PROPERTY("LoggedIndexes", (unsigned)0);
+ TC_PROPERTY("PauseThreads", 2);
INITIALIZER(runClearTable);
INITIALIZER(createRandomIndex);
INITIALIZER(createPkIndex);
@@ -1367,6 +1370,7 @@ TESTCASE("NFNR3_O",
TESTCASE("NFNR4",
"Test that indexes are correctly maintained during node fail and node restart"){
TC_PROPERTY("LoggedIndexes", (unsigned)0);
+ TC_PROPERTY("PauseThreads", 4);
INITIALIZER(runClearTable);
INITIALIZER(createRandomIndex);
INITIALIZER(createPkIndex);
@@ -1385,6 +1389,7 @@ TESTCASE("NFNR4_O",
"Test that indexes are correctly maintained during node fail and node restart"){
TC_PROPERTY("OrderedIndex", 1);
TC_PROPERTY("LoggedIndexes", (unsigned)0);
+ TC_PROPERTY("PauseThreads", 4);
INITIALIZER(runClearTable);
INITIALIZER(createRandomIndex);
INITIALIZER(createPkIndex);
diff --git a/ndb/test/ndbapi/testLcp.cpp b/ndb/test/ndbapi/testLcp.cpp
index d11692db761..8bfc7ccf9b9 100644
--- a/ndb/test/ndbapi/testLcp.cpp
+++ b/ndb/test/ndbapi/testLcp.cpp
@@ -30,6 +30,7 @@ static CASE g_ops[] =
const size_t OP_COUNT = (sizeof(g_ops)/sizeof(g_ops[0]));
static Ndb* g_ndb = 0;
+static Ndb_cluster_connection *g_cluster_connection= 0;
static CASE* g_cases;
static HugoOperations* g_hugo_ops;
@@ -122,6 +123,7 @@ main(int argc, char ** argv){
static int init_ndb(int argc, char** argv)
{
+ ndb_init();
return 0;
}
@@ -132,7 +134,13 @@ static int parse_args(int argc, char** argv)
static int connect_ndb()
{
- g_ndb = new Ndb("TEST_DB");
+ g_cluster_connection = new Ndb_cluster_connection();
+ if(g_cluster_connection->connect(12, 5, 1) != 0)
+ {
+ return 1;
+ }
+
+ g_ndb = new Ndb(g_cluster_connection, "TEST_DB");
g_ndb->init();
if(g_ndb->waitUntilReady(30) == 0){
int args[] = { DumpStateOrd::DihMaxTimeBetweenLCP };
@@ -144,8 +152,10 @@ static int connect_ndb()
static int disconnect_ndb()
{
delete g_ndb;
+ delete g_cluster_connection;
g_ndb = 0;
g_table = 0;
+ g_cluster_connection= 0;
return 0;
}
diff --git a/ndb/test/ndbapi/testNdbApi.cpp b/ndb/test/ndbapi/testNdbApi.cpp
index 3a06269f8dc..f456d852898 100644
--- a/ndb/test/ndbapi/testNdbApi.cpp
+++ b/ndb/test/ndbapi/testNdbApi.cpp
@@ -56,7 +56,7 @@ int runTestMaxNdb(NDBT_Context* ctx, NDBT_Step* step){
int init = 0;
do {
- Ndb* pNdb = new Ndb("TEST_DB");
+ Ndb* pNdb = new Ndb(&ctx->m_cluster_connection, "TEST_DB");
if (pNdb == NULL){
ndbout << "pNdb == NULL" << endl;
errors++;
@@ -108,7 +108,7 @@ int runTestMaxTransaction(NDBT_Context* ctx, NDBT_Step* step){
int oldi = 0;
int result = NDBT_OK;
- Ndb* pNdb = new Ndb("TEST_DB");
+ Ndb* pNdb = new Ndb(&ctx->m_cluster_connection, "TEST_DB");
if (pNdb == NULL){
ndbout << "pNdb == NULL" << endl;
return NDBT_FAILED;
@@ -119,6 +119,9 @@ int runTestMaxTransaction(NDBT_Context* ctx, NDBT_Step* step){
return NDBT_FAILED;
}
+ const NdbDictionary::Table* pTab = ctx->getTab();
+ if (pTab == 0) abort();
+
while (l < loops && result == NDBT_OK){
int errors = 0;
int maxErrors = 5;
@@ -131,39 +134,25 @@ int runTestMaxTransaction(NDBT_Context* ctx, NDBT_Step* step){
NdbConnection* pCon;
- int type = i%4;
+ int type = i%2;
switch (type){
case 0:
pCon = pNdb->startTransaction();
break;
case 1:
- pCon = pNdb->startTransaction(2,
- "DATA",
- 4);
- break;
- case 2:
- ndbout_c("startTransactionDGroup not supported");
- abort();
- /*
- pCon = pNdb->startTransactionDGroup(1,
- "TEST",
- 0);
- */
- break;
- case 3:
- ndbout_c("startTransactionDGroup not supported");
- abort();
- /*
- pCon = pNdb->startTransactionDGroup(2,
- "TEST",
- 1);
- */
- break;
-
+ {
+ BaseString key;
+ key.appfmt("DATA-%d", i);
+ ndbout_c("%s", key.c_str());
+ pCon = pNdb->startTransaction(pTab,
+ key.c_str(),
+ key.length());
+ }
+ break;
default:
abort();
}
-
+
if (pCon == NULL){
ERR(pNdb->getNdbError());
errors++;
@@ -209,7 +198,7 @@ int runTestMaxOperations(NDBT_Context* ctx, NDBT_Step* step){
int maxOpsLimit = 1;
const NdbDictionary::Table* pTab = ctx->getTab();
- Ndb* pNdb = new Ndb("TEST_DB");
+ Ndb* pNdb = new Ndb(&ctx->m_cluster_connection, "TEST_DB");
if (pNdb == NULL){
ndbout << "pNdb == NULL" << endl;
return NDBT_FAILED;
@@ -281,7 +270,7 @@ int runTestGetValue(NDBT_Context* ctx, NDBT_Step* step){
int result = NDBT_OK;
const NdbDictionary::Table* pTab = ctx->getTab();
- Ndb* pNdb = new Ndb("TEST_DB");
+ Ndb* pNdb = new Ndb(&ctx->m_cluster_connection, "TEST_DB");
if (pNdb == NULL){
ndbout << "pNdb == NULL" << endl;
return NDBT_FAILED;
@@ -381,7 +370,7 @@ int runTestEqual(NDBT_Context* ctx, NDBT_Step* step){
int result = NDBT_OK;
const NdbDictionary::Table* pTab = ctx->getTab();
- Ndb* pNdb = new Ndb("TEST_DB");
+ Ndb* pNdb = new Ndb(&ctx->m_cluster_connection, "TEST_DB");
if (pNdb == NULL){
ndbout << "pNdb == NULL" << endl;
return NDBT_FAILED;
@@ -502,7 +491,7 @@ int runTestDeleteNdb(NDBT_Context* ctx, NDBT_Step* step){
// Create 5 ndb objects
for( int i = 0; i < 5; i++){
- Ndb* pNdb = new Ndb("TEST_DB");
+ Ndb* pNdb = new Ndb(&ctx->m_cluster_connection, "TEST_DB");
if (pNdb == NULL){
ndbout << "pNdb == NULL" << endl;
result = NDBT_FAILED;
@@ -583,7 +572,7 @@ int runLoadTable(NDBT_Context* ctx, NDBT_Step* step){
int runTestWaitUntilReady(NDBT_Context* ctx, NDBT_Step* step){
- Ndb* pNdb = new Ndb("TEST_DB");
+ Ndb* pNdb = new Ndb(&ctx->m_cluster_connection, "TEST_DB");
// Forget about calling pNdb->init();
@@ -604,7 +593,7 @@ int runTestWaitUntilReady(NDBT_Context* ctx, NDBT_Step* step){
int runGetNdbOperationNoTab(NDBT_Context* ctx, NDBT_Step* step){
- Ndb* pNdb = new Ndb("TEST_DB");
+ Ndb* pNdb = new Ndb(&ctx->m_cluster_connection, "TEST_DB");
if (pNdb == NULL){
ndbout << "pNdb == NULL" << endl;
return NDBT_FAILED;
@@ -645,7 +634,7 @@ int runMissingOperation(NDBT_Context* ctx, NDBT_Step* step){
const NdbDictionary::Table* pTab = ctx->getTab();
- Ndb* pNdb = new Ndb("TEST_DB");
+ Ndb* pNdb = new Ndb(&ctx->m_cluster_connection, "TEST_DB");
if (pNdb == NULL){
ndbout << "pNdb == NULL" << endl;
return NDBT_FAILED;
@@ -695,7 +684,7 @@ int runMissingOperation(NDBT_Context* ctx, NDBT_Step* step){
int runGetValueInUpdate(NDBT_Context* ctx, NDBT_Step* step){
const NdbDictionary::Table* pTab = ctx->getTab();
- Ndb* pNdb = new Ndb("TEST_DB");
+ Ndb* pNdb = new Ndb(&ctx->m_cluster_connection, "TEST_DB");
if (pNdb == NULL){
ndbout << "pNdb == NULL" << endl;
return NDBT_FAILED;
@@ -761,7 +750,7 @@ int runUpdateWithoutValues(NDBT_Context* ctx, NDBT_Step* step){
HugoOperations hugoOps(*pTab);
- Ndb* pNdb = new Ndb("TEST_DB");
+ Ndb* pNdb = new Ndb(&ctx->m_cluster_connection, "TEST_DB");
if (pNdb == NULL){
ndbout << "pNdb == NULL" << endl;
return NDBT_FAILED;
@@ -807,13 +796,13 @@ int runUpdateWithoutValues(NDBT_Context* ctx, NDBT_Step* step){
// Dont' call any setValues
- // Execute should not work
+ // Execute should work
int check = pCon->execute(Commit);
if (check == 0){
ndbout << "execute worked" << endl;
- result = NDBT_FAILED;
} else {
ERR(pCon->getNdbError());
+ result = NDBT_FAILED;
}
pNdb->closeTransaction(pCon);
@@ -827,7 +816,7 @@ int runUpdateWithoutKeys(NDBT_Context* ctx, NDBT_Step* step){
const NdbDictionary::Table* pTab = ctx->getTab();
- Ndb* pNdb = new Ndb("TEST_DB");
+ Ndb* pNdb = new Ndb(&ctx->m_cluster_connection, "TEST_DB");
if (pNdb == NULL){
ndbout << "pNdb == NULL" << endl;
return NDBT_FAILED;
@@ -953,8 +942,7 @@ int runReadWithoutGetValue(NDBT_Context* ctx, NDBT_Step* step){
return NDBT_FAILED;
}
- NdbResultSet *rs;
- if ((rs = pOp->readTuples((NdbOperation::LockMode)lm)) == 0){
+ if ((pOp->readTuples((NdbOperation::LockMode)lm)) != 0){
pNdb->closeTransaction(pCon);
ERR(pOp->getNdbError());
return NDBT_FAILED;
@@ -973,7 +961,7 @@ int runReadWithoutGetValue(NDBT_Context* ctx, NDBT_Step* step){
}
int res;
- while((res = rs->nextResult()) == 0);
+ while((res = pOp->nextResult()) == 0);
pNdb->closeTransaction(pCon);
if(res != 1)
@@ -988,7 +976,7 @@ int runCheckGetNdbErrorOperation(NDBT_Context* ctx, NDBT_Step* step){
int result = NDBT_OK;
const NdbDictionary::Table* pTab = ctx->getTab();
- Ndb* pNdb = new Ndb("TEST_DB");
+ Ndb* pNdb = new Ndb(&ctx->m_cluster_connection, "TEST_DB");
if (pNdb == NULL){
ndbout << "pNdb == NULL" << endl;
return NDBT_FAILED;
@@ -1049,7 +1037,7 @@ int runCheckGetNdbErrorOperation(NDBT_Context* ctx, NDBT_Step* step){
return result;
}
-#define C2(x) { int _x= (x); if(_x == 0) return NDBT_FAILED; }
+#define C2(x) { int _x= (x); if(_x == 0){ ndbout << "line: " << __LINE__ << endl; return NDBT_FAILED;} }
int runBug_11133(NDBT_Context* ctx, NDBT_Step* step){
int result = NDBT_OK;
@@ -1058,7 +1046,6 @@ int runBug_11133(NDBT_Context* ctx, NDBT_Step* step){
HugoOperations hugoOps(*pTab);
Ndb* pNdb = GETNDB(step);
-
C2(hugoOps.startTransaction(pNdb) == 0);
C2(hugoOps.pkInsertRecord(pNdb, 0, 1) == 0);
C2(hugoOps.execute_NoCommit(pNdb) == 0);
@@ -1101,7 +1088,7 @@ int runBug_11133(NDBT_Context* ctx, NDBT_Step* step){
C2(hugoOps.execute_Commit(pNdb) == 0);
C2(hugoOps.closeTransaction(pNdb) == 0);
- Ndb ndb2("TEST_DB");
+ Ndb ndb2(&ctx->m_cluster_connection, "TEST_DB");
C2(ndb2.init() == 0);
C2(ndb2.waitUntilReady() == 0);
HugoOperations hugoOps2(*pTab);
@@ -1110,8 +1097,8 @@ int runBug_11133(NDBT_Context* ctx, NDBT_Step* step){
C2(hugoOps.pkInsertRecord(pNdb, 0, 1) == 0);
C2(hugoOps.execute_NoCommit(pNdb) == 0);
C2(hugoOps2.startTransaction(&ndb2) == 0);
- C2(hugoOps2.pkWriteRecord(&ndb2, 0, 1) == 0);
- C2(hugoOps2.execute_async(&ndb2, NoCommit) == 0);
+ C2(hugoOps2.pkWritePartialRecord(&ndb2, 0) == 0);
+ C2(hugoOps2.execute_async(&ndb2, NdbTransaction::NoCommit) == 0);
C2(hugoOps.execute_Commit(pNdb) == 0);
C2(hugoOps2.wait_async(&ndb2) == 0);
C2(hugoOps.closeTransaction(pNdb) == 0);
@@ -1122,15 +1109,133 @@ int runBug_11133(NDBT_Context* ctx, NDBT_Step* step){
C2(hugoOps.execute_NoCommit(pNdb) == 0);
C2(hugoOps2.startTransaction(&ndb2) == 0);
C2(hugoOps2.pkWriteRecord(&ndb2, 0, 1) == 0);
- C2(hugoOps2.execute_async(&ndb2, NoCommit) == 0);
+ C2(hugoOps2.execute_async(&ndb2, NdbTransaction::NoCommit) == 0);
C2(hugoOps.execute_Commit(pNdb) == 0);
C2(hugoOps2.wait_async(&ndb2) == 0);
+ C2(hugoOps2.execute_Commit(pNdb) == 0);
C2(hugoOps.closeTransaction(pNdb) == 0);
C2(hugoOps2.closeTransaction(&ndb2) == 0);
+ C2(hugoOps.startTransaction(pNdb) == 0);
+ C2(hugoOps.pkUpdateRecord(pNdb, 0, 1) == 0);
+ C2(hugoOps.execute_NoCommit(pNdb) == 0);
+ C2(hugoOps2.startTransaction(&ndb2) == 0);
+ C2(hugoOps2.pkWritePartialRecord(&ndb2, 0) == 0);
+ C2(hugoOps2.execute_async(&ndb2, NdbTransaction::NoCommit) == 0);
+ C2(hugoOps.execute_Commit(pNdb) == 0);
+ C2(hugoOps2.wait_async(&ndb2) == 0);
+ C2(hugoOps.closeTransaction(pNdb) == 0);
+ C2(hugoOps2.closeTransaction(&ndb2) == 0);
+
+ C2(hugoOps.startTransaction(pNdb) == 0);
+ C2(hugoOps.pkDeleteRecord(pNdb, 0, 1) == 0);
+ C2(hugoOps.execute_NoCommit(pNdb) == 0);
+ C2(hugoOps2.startTransaction(&ndb2) == 0);
+ C2(hugoOps2.pkWritePartialRecord(&ndb2, 0) == 0);
+ C2(hugoOps2.execute_async(&ndb2, NdbTransaction::NoCommit) == 0);
+ C2(hugoOps.execute_Commit(pNdb) == 0);
+ C2(hugoOps2.wait_async(&ndb2) != 0);
+ C2(hugoOps.closeTransaction(pNdb) == 0);
+ C2(hugoOps2.closeTransaction(&ndb2) == 0);
+
+ return result;
+}
+
+int runScan_4006(NDBT_Context* ctx, NDBT_Step* step){
+ int result = NDBT_OK;
+ const Uint32 max= 5;
+ const NdbDictionary::Table* pTab = ctx->getTab();
+
+ Ndb* pNdb = new Ndb(&ctx->m_cluster_connection, "TEST_DB");
+ if (pNdb == NULL){
+ ndbout << "pNdb == NULL" << endl;
+ return NDBT_FAILED;
+ }
+ if (pNdb->init(max)){
+ ERR(pNdb->getNdbError());
+ delete pNdb;
+ return NDBT_FAILED;
+ }
+
+ NdbConnection* pCon = pNdb->startTransaction();
+ if (pCon == NULL){
+ pNdb->closeTransaction(pCon);
+ delete pNdb;
+ return NDBT_FAILED;
+ }
+
+ Uint32 i;
+ Vector<NdbScanOperation*> scans;
+ for(i = 0; i<10*max; i++)
+ {
+ NdbScanOperation* pOp = pCon->getNdbScanOperation(pTab->getName());
+ if (pOp == NULL){
+ ERR(pCon->getNdbError());
+ pNdb->closeTransaction(pCon);
+ delete pNdb;
+ return NDBT_FAILED;
+ }
+
+ if (pOp->readTuples() != 0){
+ pNdb->closeTransaction(pCon);
+ ERR(pOp->getNdbError());
+ delete pNdb;
+ return NDBT_FAILED;
+ }
+ scans.push_back(pOp);
+ }
+
+ // Dont' call any equal or setValues
+
+ // Execute should not work
+ int check = pCon->execute(NoCommit);
+ if (check == 0){
+ ndbout << "execute worked" << endl;
+ } else {
+ ERR(pCon->getNdbError());
+ }
+
+ for(i= 0; i<scans.size(); i++)
+ {
+ NdbScanOperation* pOp= scans[i];
+ while((check= pOp->nextResult()) == 0);
+ if(check != 1)
+ {
+ ERR(pOp->getNdbError());
+ pNdb->closeTransaction(pCon);
+ delete pNdb;
+ return NDBT_FAILED;
+ }
+ }
+
+ pNdb->closeTransaction(pCon);
+
+ Vector<NdbConnection*> cons;
+ for(i= 0; i<10*max; i++)
+ {
+ pCon= pNdb->startTransaction();
+ if(pCon)
+ cons.push_back(pCon);
+ else
+ break;
+ }
+
+ for(i= 0; i<cons.size(); i++)
+ {
+ cons[i]->close();
+ }
+
+ if(cons.size() != max)
+ {
+ result= NDBT_FAILED;
+ }
+
+ delete pNdb;
+
return result;
}
+template class Vector<NdbScanOperation*>;
NDBT_TESTSUITE(testNdbApi);
@@ -1212,6 +1317,12 @@ TESTCASE("Bug_11133",
INITIALIZER(runBug_11133);
FINALIZER(runClearTable);
}
+TESTCASE("Scan_4006",
+ "Check that getNdbScanOperation does not get 4006\n"){
+ INITIALIZER(runLoadTable);
+ INITIALIZER(runScan_4006);
+ FINALIZER(runClearTable);
+}
NDBT_TESTSUITE_END(testNdbApi);
int main(int argc, const char** argv){
diff --git a/ndb/test/ndbapi/testNodeRestart.cpp b/ndb/test/ndbapi/testNodeRestart.cpp
index 9c25d715d07..6ef3da2d760 100644
--- a/ndb/test/ndbapi/testNodeRestart.cpp
+++ b/ndb/test/ndbapi/testNodeRestart.cpp
@@ -311,7 +311,7 @@ int runDirtyRead(NDBT_Context* ctx, NDBT_Step* step){
int id = i % restarter.getNumDbNodes();
int nodeId = restarter.getDbNodeId(id);
ndbout << "Restart node " << nodeId << endl;
- restarter.insertErrorInAllNodes(5041);
+ restarter.insertErrorInNode(nodeId, 5041);
restarter.insertErrorInAllNodes(8048 + (i & 1));
for(int j = 0; j<records; j++){
diff --git a/ndb/test/ndbapi/testOIBasic.cpp b/ndb/test/ndbapi/testOIBasic.cpp
index 9f8da850ff4..942ee2ec966 100644
--- a/ndb/test/ndbapi/testOIBasic.cpp
+++ b/ndb/test/ndbapi/testOIBasic.cpp
@@ -28,7 +28,10 @@
#include <NdbCondition.h>
#include <NdbThread.h>
#include <NdbTick.h>
+#include <NdbSleep.h>
#include <my_sys.h>
+#include <NdbSqlUtil.hpp>
+#include <ndb_version.h>
// options
@@ -37,6 +40,7 @@ struct Opt {
unsigned m_batch;
const char* m_bound;
const char* m_case;
+ bool m_collsp;
bool m_core;
const char* m_csname;
CHARSET_INFO* m_cs;
@@ -52,20 +56,20 @@ struct Opt {
unsigned m_pctnull;
unsigned m_rows;
unsigned m_samples;
- unsigned m_scanbat;
unsigned m_scanpar;
unsigned m_scanstop;
- unsigned m_seed;
+ int m_seed;
unsigned m_subloop;
const char* m_table;
unsigned m_threads;
- int m_v;
+ int m_v; // int for lint
Opt() :
m_batch(32),
m_bound("01234"),
m_case(0),
+ m_collsp(false),
m_core(false),
- m_csname("latin1_bin"),
+ m_csname("random"),
m_cs(0),
m_die(0),
m_dups(false),
@@ -79,13 +83,12 @@ struct Opt {
m_pctnull(10),
m_rows(1000),
m_samples(0),
- m_scanbat(0),
m_scanpar(0),
m_scanstop(0),
- m_seed(0),
+ m_seed(-1),
m_subloop(4),
m_table(0),
- m_threads(10),
+ m_threads(4),
m_v(1) {
}
};
@@ -104,23 +107,23 @@ printhelp()
<< " -batch N pk operations in batch [" << d.m_batch << "]" << endl
<< " -bound xyz use only these bound types 0-4 [" << d.m_bound << "]" << endl
<< " -case abc only given test cases (letters a-z)" << endl
+ << " -collsp use strnncollsp instead of strnxfrm" << endl
<< " -core core dump on error [" << d.m_core << "]" << endl
- << " -csname S charset (collation) of non-pk char column [" << d.m_csname << "]" << endl
+ << " -csname S charset or collation [" << d.m_csname << "]" << endl
<< " -die nnn exit immediately on NDB error code nnn" << 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
+ << " -index xyz only given index numbers (digits 0-9)" << endl
<< " -loop N loop count full suite 0=forever [" << d.m_loop << "]" << endl
<< " -nologging create tables in no-logging mode" << endl
<< " -noverify skip index verifications" << endl
<< " -pctnull N pct NULL values in nullable column [" << d.m_pctnull << "]" << endl
<< " -rows N rows per thread [" << d.m_rows << "]" << endl
<< " -samples N samples for some timings (0=all) [" << d.m_samples << "]" << endl
- << " -scanbat N scan batch per fragment (ignored by ndb api) [" << d.m_scanbat << "]" << endl
<< " -scanpar N scan parallelism [" << d.m_scanpar << "]" << endl
- << " -seed N srandom seed 0=loop number[" << d.m_seed << "]" << endl
+ << " -seed N srandom seed 0=loop number -1=random [" << d.m_seed << "]" << endl
<< " -subloop N subtest loop count [" << d.m_subloop << "]" << endl
- << " -table xyz only given table numbers (digits 1-9)" << endl
+ << " -table xyz only given table numbers (digits 0-9)" << endl
<< " -threads N number of threads [" << d.m_threads << "]" << endl
<< " -vN verbosity [" << d.m_v << "]" << endl
<< " -h or -help print this help text" << endl
@@ -135,9 +138,84 @@ 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;
+static const char* hexstr = "0123456789abcdef";
+
+// random ints
+
+static unsigned
+urandom(unsigned n)
+{
+ if (n == 0)
+ return 0;
+ unsigned i = random() % n;
+ return i;
+}
+
+static int
+irandom(unsigned n)
+{
+ if (n == 0)
+ return 0;
+ int i = random() % n;
+ if (random() & 0x1)
+ i = -i;
+ return i;
+}
+
+static bool
+randompct(unsigned pct)
+{
+ if (pct == 0)
+ return false;
+ if (pct >= 100)
+ return true;
+ return urandom(100) < pct;
+}
+
+static unsigned
+random_coprime(unsigned n)
+{
+ unsigned prime[] = { 101, 211, 307, 401, 503, 601, 701, 809, 907 };
+ unsigned count = sizeof(prime) / sizeof(prime[0]);
+ if (n == 0)
+ return 0;
+ while (1) {
+ unsigned i = urandom(count);
+ if (n % prime[i] != 0)
+ return prime[i];
+ }
+}
+
+// random re-sequence of 0...(n-1)
+
+struct Rsq {
+ Rsq(unsigned n);
+ unsigned next();
+private:
+ unsigned m_n;
+ unsigned m_i;
+ unsigned m_start;
+ unsigned m_prime;
+};
+
+Rsq::Rsq(unsigned n)
+{
+ m_n = n;
+ m_i = 0;
+ m_start = urandom(n);
+ m_prime = random_coprime(n);
+}
+
+unsigned
+Rsq::next()
+{
+ assert(m_n != 0);
+ return (m_start + m_i++ * m_prime) % m_n;
+}
+
// log and error macros
-static NdbMutex *ndbout_mutex= NULL;
+static NdbMutex *ndbout_mutex = NULL;
static unsigned getthrno();
@@ -198,7 +276,7 @@ getthrstr()
return -1; \
} while (0)
-// method parameters base class
+// method parameters
class Thr;
class Con;
@@ -222,6 +300,8 @@ struct Par : public Opt {
// value calculation
unsigned m_range;
unsigned m_pctrange;
+ unsigned m_pctbrange;
+ int m_bdir;
// choice of key
bool m_randomkey;
// do verify after read
@@ -230,6 +310,11 @@ struct Par : public Opt {
bool m_deadlock;
// abort percentabge
unsigned m_abortpct;
+ NdbOperation::LockMode m_lockmode;
+ // scan options
+ bool m_tupscan;
+ bool m_ordered;
+ bool m_descending;
// timer location
Par(const Opt& opt) :
Opt(opt),
@@ -242,24 +327,30 @@ struct Par : public Opt {
m_slno(0),
m_totrows(m_threads * m_rows),
m_range(m_rows),
- m_pctrange(0),
+ m_pctrange(40),
+ m_pctbrange(80),
+ m_bdir(0),
m_randomkey(false),
m_verify(false),
m_deadlock(false),
- m_abortpct(0) {
+ m_abortpct(0),
+ m_lockmode(NdbOperation::LM_Read),
+ m_tupscan(false),
+ m_ordered(false),
+ m_descending(false) {
}
};
static bool
-usetable(unsigned i)
+usetable(Par par, unsigned i)
{
- return g_opt.m_table == 0 || strchr(g_opt.m_table, '1' + i) != 0;
+ return par.m_table == 0 || strchr(par.m_table, '0' + i) != 0;
}
static bool
-useindex(unsigned i)
+useindex(Par par, unsigned i)
{
- return g_opt.m_index == 0 || strchr(g_opt.m_index, '1' + i) != 0;
+ return par.m_index == 0 || strchr(par.m_index, '0' + i) != 0;
}
static unsigned
@@ -385,38 +476,285 @@ Lst::reset()
m_cnt = 0;
}
+// character sets
+
+static const unsigned maxcsnumber = 512;
+static const unsigned maxcharcount = 32;
+static const unsigned maxcharsize = 4;
+static const unsigned maxxmulsize = 8;
+
+// single mb char
+struct Chr {
+ unsigned char m_bytes[maxcharsize];
+ unsigned char m_xbytes[maxxmulsize * maxcharsize];
+ unsigned m_size;
+ Chr();
+};
+
+Chr::Chr()
+{
+ memset(m_bytes, 0, sizeof(m_bytes));
+ memset(m_xbytes, 0, sizeof(m_xbytes));
+ m_size = 0;
+}
+
+// charset and random valid chars to use
+struct Chs {
+ CHARSET_INFO* m_cs;
+ unsigned m_xmul;
+ Chr* m_chr;
+ Chs(CHARSET_INFO* cs);
+ ~Chs();
+};
+
+static NdbOut&
+operator<<(NdbOut& out, const Chs& chs);
+
+Chs::Chs(CHARSET_INFO* cs) :
+ m_cs(cs)
+{
+ m_xmul = m_cs->strxfrm_multiply;
+ if (m_xmul == 0)
+ m_xmul = 1;
+ assert(m_xmul <= maxxmulsize);
+ m_chr = new Chr [maxcharcount];
+ unsigned i = 0;
+ unsigned miss1 = 0;
+ unsigned miss2 = 0;
+ unsigned miss3 = 0;
+ unsigned miss4 = 0;
+ while (i < maxcharcount) {
+ unsigned char* bytes = m_chr[i].m_bytes;
+ unsigned char* xbytes = m_chr[i].m_xbytes;
+ unsigned& size = m_chr[i].m_size;
+ bool ok;
+ size = m_cs->mbminlen + urandom(m_cs->mbmaxlen - m_cs->mbminlen + 1);
+ assert(m_cs->mbminlen <= size && size <= m_cs->mbmaxlen);
+ // prefer longer chars
+ if (size == m_cs->mbminlen && m_cs->mbminlen < m_cs->mbmaxlen && urandom(5) != 0)
+ continue;
+ for (unsigned j = 0; j < size; j++) {
+ bytes[j] = urandom(256);
+ }
+ int not_used;
+ // check wellformed
+ const char* sbytes = (const char*)bytes;
+ if ((*cs->cset->well_formed_len)(cs, sbytes, sbytes + size, 1, &not_used) != size) {
+ miss1++;
+ continue;
+ }
+ // check no proper prefix wellformed
+ ok = true;
+ for (unsigned j = 1; j < size; j++) {
+ if ((*cs->cset->well_formed_len)(cs, sbytes, sbytes + j, 1, &not_used) == j) {
+ ok = false;
+ break;
+ }
+ }
+ if (! ok) {
+ miss2++;
+ continue;
+ }
+ // normalize
+ memset(xbytes, 0, sizeof(xbytes));
+ // currently returns buffer size always
+ int xlen = (*cs->coll->strnxfrm)(cs, xbytes, m_xmul * size, bytes, size);
+ // check we got something
+ ok = false;
+ for (unsigned j = 0; j < xlen; j++) {
+ if (xbytes[j] != 0) {
+ ok = true;
+ break;
+ }
+ }
+ if (! ok) {
+ miss3++;
+ continue;
+ }
+ // check for duplicate (before normalize)
+ ok = true;
+ for (unsigned j = 0; j < i; j++) {
+ const Chr& chr = m_chr[j];
+ if (chr.m_size == size && memcmp(chr.m_bytes, bytes, size) == 0) {
+ ok = false;
+ break;
+ }
+ }
+ if (! ok) {
+ miss4++;
+ continue;
+ }
+ i++;
+ }
+ bool disorder = true;
+ unsigned bubbles = 0;
+ while (disorder) {
+ disorder = false;
+ for (unsigned i = 1; i < maxcharcount; i++) {
+ unsigned len = sizeof(m_chr[i].m_xbytes);
+ if (memcmp(m_chr[i-1].m_xbytes, m_chr[i].m_xbytes, len) > 0) {
+ Chr chr = m_chr[i];
+ m_chr[i] = m_chr[i-1];
+ m_chr[i-1] = chr;
+ disorder = true;
+ bubbles++;
+ }
+ }
+ }
+ LL3("inited charset " << *this << " miss=" << miss1 << "," << miss2 << "," << miss3 << "," << miss4 << " bubbles=" << bubbles);
+}
+
+Chs::~Chs()
+{
+ delete [] m_chr;
+}
+
+static NdbOut&
+operator<<(NdbOut& out, const Chs& chs)
+{
+ CHARSET_INFO* cs = chs.m_cs;
+ out << cs->name << "[" << cs->mbminlen << "-" << cs->mbmaxlen << "," << chs.m_xmul << "]";
+ return out;
+}
+
+static Chs* cslist[maxcsnumber];
+
+static void
+resetcslist()
+{
+ for (unsigned i = 0; i < maxcsnumber; i++) {
+ delete cslist[i];
+ cslist[i] = 0;
+ }
+}
+
+static Chs*
+getcs(Par par)
+{
+ CHARSET_INFO* cs;
+ if (par.m_cs != 0) {
+ cs = par.m_cs;
+ } else {
+ while (1) {
+ unsigned n = urandom(maxcsnumber);
+ cs = get_charset(n, MYF(0));
+ if (cs != 0) {
+ // prefer complex charsets
+ if (cs->mbmaxlen != 1 || urandom(5) == 0)
+ break;
+ }
+ }
+ }
+ if (cslist[cs->number] == 0)
+ cslist[cs->number] = new Chs(cs);
+ return cslist[cs->number];
+}
+
// tables and indexes
// Col - table column
struct Col {
+ enum Type {
+ Unsigned = NdbDictionary::Column::Unsigned,
+ Char = NdbDictionary::Column::Char,
+ Varchar = NdbDictionary::Column::Varchar,
+ Longvarchar = NdbDictionary::Column::Longvarchar
+ };
+ const class Tab& m_tab;
unsigned m_num;
const char* m_name;
bool m_pk;
- NdbDictionary::Column::Type m_type;
+ Type m_type;
unsigned m_length;
+ unsigned m_bytelength; // multiplied by char width
+ unsigned m_attrsize; // base type size
+ unsigned m_headsize; // length bytes
+ unsigned m_bytesize; // full value size
bool m_nullable;
- void verify(const void* addr) const;
+ const Chs* m_chs;
+ Col(const class Tab& tab, unsigned num, const char* name, bool pk, Type type, unsigned length, bool nullable, const Chs* chs);
+ ~Col();
+ bool equal(const Col& col2) const;
+ void wellformed(const void* addr) const;
};
+Col::Col(const class Tab& tab, unsigned num, const char* name, bool pk, Type type, unsigned length, bool nullable, const Chs* chs) :
+ m_tab(tab),
+ m_num(num),
+ m_name(strcpy(new char [strlen(name) + 1], name)),
+ m_pk(pk),
+ m_type(type),
+ m_length(length),
+ m_bytelength(length * (chs == 0 ? 1 : chs->m_cs->mbmaxlen)),
+ m_attrsize(
+ type == Unsigned ? sizeof(Uint32) :
+ type == Char ? sizeof(char) :
+ type == Varchar ? sizeof(char) :
+ type == Longvarchar ? sizeof(char) : ~0),
+ m_headsize(
+ type == Unsigned ? 0 :
+ type == Char ? 0 :
+ type == Varchar ? 1 :
+ type == Longvarchar ? 2 : ~0),
+ m_bytesize(m_headsize + m_attrsize * m_bytelength),
+ m_nullable(nullable),
+ m_chs(chs)
+{
+ // fix long varchar
+ if (type == Varchar && m_bytelength > 255) {
+ m_type = Longvarchar;
+ m_headsize += 1;
+ m_bytesize += 1;
+ }
+}
+
+Col::~Col()
+{
+ delete [] m_name;
+}
+
+bool
+Col::equal(const Col& col2) const
+{
+ return m_type == col2.m_type && m_length == col2.m_length && m_chs == col2.m_chs;
+}
+
void
-Col::verify(const void* addr) const
+Col::wellformed(const void* addr) const
{
switch (m_type) {
- case NdbDictionary::Column::Unsigned:
+ case Col::Unsigned:
break;
- case NdbDictionary::Column::Varchar:
+ case Col::Char:
{
- const unsigned char* p = (const unsigned char*)addr;
- unsigned n = (p[0] << 8) | p[1];
- assert(n <= m_length);
- unsigned i;
- for (i = 0; i < n; i++) {
- assert(p[2 + i] != 0);
- }
- for (i = n; i < m_length; i++) {
- assert(p[2 + i] == 0);
- }
+ CHARSET_INFO* cs = m_chs->m_cs;
+ const char* src = (const char*)addr;
+ unsigned len = m_bytelength;
+ int not_used;
+ assert((*cs->cset->well_formed_len)(cs, src, src + len, 0xffff, &not_used) == len);
+ }
+ break;
+ case Col::Varchar:
+ {
+ CHARSET_INFO* cs = m_chs->m_cs;
+ const unsigned char* src = (const unsigned char*)addr;
+ const char* ssrc = (const char*)src;
+ unsigned len = src[0];
+ int not_used;
+ assert(len <= m_bytelength);
+ assert((*cs->cset->well_formed_len)(cs, ssrc + 1, ssrc + 1 + len, 0xffff, &not_used) == len);
+ }
+ break;
+ case Col::Longvarchar:
+ {
+ CHARSET_INFO* cs = m_chs->m_cs;
+ const unsigned char* src = (const unsigned char*)addr;
+ const char* ssrc = (const char*)src;
+ unsigned len = src[0] + (src[1] << 8);
+ int not_used;
+ assert(len <= m_bytelength);
+ assert((*cs->cset->well_formed_len)(cs, ssrc + 2, ssrc + 2 + len, 0xffff, &not_used) == len);
}
break;
default:
@@ -428,14 +766,28 @@ Col::verify(const void* addr) const
static NdbOut&
operator<<(NdbOut& out, const Col& col)
{
- out << "col " << col.m_num;
- out << " " << col.m_name;
+ out << "col[" << col.m_num << "] " << col.m_name;
switch (col.m_type) {
- case NdbDictionary::Column::Unsigned:
+ case Col::Unsigned:
out << " unsigned";
break;
- case NdbDictionary::Column::Varchar:
- out << " varchar(" << col.m_length << ")";
+ case Col::Char:
+ {
+ CHARSET_INFO* cs = col.m_chs->m_cs;
+ out << " char(" << col.m_length << "*" << cs->mbmaxlen << ";" << cs->name << ")";
+ }
+ break;
+ case Col::Varchar:
+ {
+ CHARSET_INFO* cs = col.m_chs->m_cs;
+ out << " varchar(" << col.m_length << "*" << cs->mbmaxlen << ";" << cs->name << ")";
+ }
+ break;
+ case Col::Longvarchar:
+ {
+ CHARSET_INFO* cs = col.m_chs->m_cs;
+ out << " longvarchar(" << col.m_length << "*" << cs->mbmaxlen << ";" << cs->name << ")";
+ }
break;
default:
out << "type" << (int)col.m_type;
@@ -450,25 +802,84 @@ operator<<(NdbOut& out, const Col& col)
// ICol - index column
struct ICol {
+ const class ITab& m_itab;
unsigned m_num;
- struct Col m_col;
+ const Col& m_col;
+ ICol(const class ITab& itab, unsigned num, const Col& col);
+ ~ICol();
};
+ICol::ICol(const class ITab& itab, unsigned num, const Col& col) :
+ m_itab(itab),
+ m_num(num),
+ m_col(col)
+{
+}
+
+ICol::~ICol()
+{
+}
+
+static NdbOut&
+operator<<(NdbOut& out, const ICol& icol)
+{
+ out << "icol[" << icol.m_num << "] " << icol.m_col;
+ return out;
+}
+
// ITab - index
struct ITab {
+ enum Type {
+ OrderedIndex = NdbDictionary::Index::OrderedIndex,
+ UniqueHashIndex = NdbDictionary::Index::UniqueHashIndex
+ };
+ const class Tab& m_tab;
const char* m_name;
+ Type m_type;
unsigned m_icols;
- const ICol* m_icol;
+ const ICol** m_icol;
+ unsigned m_colmask;
+ ITab(const class Tab& tab, const char* name, Type type, unsigned icols);
+ ~ITab();
+ void icoladd(unsigned k, const ICol* icolptr);
};
+ITab::ITab(const class Tab& tab, const char* name, Type type, unsigned icols) :
+ m_tab(tab),
+ m_name(strcpy(new char [strlen(name) + 1], name)),
+ m_type(type),
+ m_icols(icols),
+ m_icol(new const ICol* [icols + 1]),
+ m_colmask(0)
+{
+ for (unsigned k = 0; k <= m_icols; k++)
+ m_icol[k] = 0;
+}
+
+ITab::~ITab()
+{
+ delete [] m_name;
+ for (unsigned i = 0; i < m_icols; i++)
+ delete m_icol[i];
+ delete [] m_icol;
+}
+
+void
+ITab::icoladd(unsigned k, const ICol* icolptr)
+{
+ assert(k == icolptr->m_num && k < m_icols && m_icol[k] == 0);
+ m_icol[k] = icolptr;
+ m_colmask |= (1 << icolptr->m_col.m_num);
+}
+
static NdbOut&
operator<<(NdbOut& out, const ITab& itab)
{
- out << "itab " << itab.m_name << " " << itab.m_icols;
+ out << "itab " << itab.m_name << " icols=" << itab.m_icols;
for (unsigned k = 0; k < itab.m_icols; k++) {
- out << endl;
- out << "icol " << k << " " << itab.m_icol[k].m_col;
+ const ICol& icol = *itab.m_icol[k];
+ out << endl << icol;
}
return out;
}
@@ -478,200 +889,298 @@ operator<<(NdbOut& out, const ITab& itab)
struct Tab {
const char* m_name;
unsigned m_cols;
- const Col* m_col;
+ const Col** m_col;
unsigned m_itabs;
- const ITab* m_itab;
+ const ITab** m_itab;
+ // pk must contain an Unsigned column
+ unsigned m_keycol;
+ void coladd(unsigned k, Col* colptr);
+ void itabadd(unsigned j, ITab* itab);
+ Tab(const char* name, unsigned cols, unsigned itabs, unsigned keycol);
+ ~Tab();
};
+Tab::Tab(const char* name, unsigned cols, unsigned itabs, unsigned keycol) :
+ m_name(strcpy(new char [strlen(name) + 1], name)),
+ m_cols(cols),
+ m_col(new const Col* [cols + 1]),
+ m_itabs(itabs),
+ m_itab(new const ITab* [itabs + 1]),
+ m_keycol(keycol)
+{
+ for (unsigned k = 0; k <= cols; k++)
+ m_col[k] = 0;
+ for (unsigned j = 0; j <= itabs; j++)
+ m_itab[j] = 0;
+}
+
+Tab::~Tab()
+{
+ delete [] m_name;
+ for (unsigned i = 0; i < m_cols; i++)
+ delete m_col[i];
+ delete [] m_col;
+ for (unsigned i = 0; i < m_itabs; i++)
+ delete m_itab[i];
+ delete [] m_itab;
+}
+
+void
+Tab::coladd(unsigned k, Col* colptr)
+{
+ assert(k == colptr->m_num && k < m_cols && m_col[k] == 0);
+ m_col[k] = colptr;
+}
+
+void
+Tab::itabadd(unsigned j, ITab* itabptr)
+{
+ assert(j < m_itabs && m_itab[j] == 0);
+ m_itab[j] = itabptr;
+}
+
static NdbOut&
operator<<(NdbOut& out, const Tab& tab)
{
- out << "tab " << tab.m_name << " " << tab.m_cols;
+ out << "tab " << tab.m_name << " cols=" << tab.m_cols;
for (unsigned k = 0; k < tab.m_cols; k++) {
- out << endl;
- out << tab.m_col[k];
+ const Col& col = *tab.m_col[k];
+ out << endl << col;
}
for (unsigned i = 0; i < tab.m_itabs; i++) {
- if (! useindex(i))
+ if (tab.m_itab[i] == 0)
continue;
- out << endl;
- out << tab.m_itab[i];
+ const ITab& itab = *tab.m_itab[i];
+ out << endl << itab;
}
return out;
}
-// tt1 + tt1x1 tt1x2 tt1x3 tt1x4 tt1x5
-
-static const Col
-tt1col[] = {
- { 0, "A", 1, NdbDictionary::Column::Unsigned, 1, 0 },
- { 1, "B", 0, NdbDictionary::Column::Unsigned, 1, 1 },
- { 2, "C", 0, NdbDictionary::Column::Unsigned, 1, 1 },
- { 3, "D", 0, NdbDictionary::Column::Unsigned, 1, 1 },
- { 4, "E", 0, NdbDictionary::Column::Unsigned, 1, 1 }
-};
+// make table structs
-static const ICol
-tt1x1col[] = {
- { 0, tt1col[0] }
-};
-
-static const ICol
-tt1x2col[] = {
- { 0, tt1col[1] }
-};
-
-static const ICol
-tt1x3col[] = {
- { 0, tt1col[1] },
- { 1, tt1col[2] }
-};
-
-static const ICol
-tt1x4col[] = {
- { 0, tt1col[3] },
- { 1, tt1col[2] },
- { 2, tt1col[1] }
-};
-
-static const ICol
-tt1x5col[] = {
- { 0, tt1col[1] },
- { 1, tt1col[4] },
- { 2, tt1col[2] },
- { 3, tt1col[3] }
-};
-
-static const ITab
-tt1x1 = {
- "TT1X1", 1, tt1x1col
-};
-
-static const ITab
-tt1x2 = {
- "TT1X2", 1, tt1x2col
-};
-
-static const ITab
-tt1x3 = {
- "TT1X3", 2, tt1x3col
-};
+static const Tab** tablist = 0;
+static unsigned tabcount = 0;
-static const ITab
-tt1x4 = {
- "TT1X4", 3, tt1x4col
-};
-
-static const ITab
-tt1x5 = {
- "TT1X5", 4, tt1x5col
-};
-
-static const ITab
-tt1itab[] = {
- tt1x1,
- tt1x2,
- tt1x3,
- tt1x4,
- tt1x5
-};
-
-static const Tab
-tt1 = {
- "TT1", 5, tt1col, 5, tt1itab
-};
-
-// tt2 + tt2x1 tt2x2 tt2x3 tt2x4 tt2x5
-
-static const Col
-tt2col[] = {
- { 0, "A", 1, NdbDictionary::Column::Unsigned, 1, 0 },
- { 1, "B", 0, NdbDictionary::Column::Unsigned, 1, 1 },
- { 2, "C", 0, NdbDictionary::Column::Varchar, 20, 1 },
- { 3, "D", 0, NdbDictionary::Column::Varchar, 5, 1 },
- { 4, "E", 0, NdbDictionary::Column::Varchar, 5, 1 }
-};
-
-static const ICol
-tt2x1col[] = {
- { 0, tt2col[0] }
-};
-
-static const ICol
-tt2x2col[] = {
- { 0, tt2col[1] },
- { 1, tt2col[2] }
-};
-
-static const ICol
-tt2x3col[] = {
- { 0, tt2col[2] },
- { 1, tt2col[1] }
-};
-
-static const ICol
-tt2x4col[] = {
- { 0, tt2col[3] },
- { 1, tt2col[4] }
-};
-
-static const ICol
-tt2x5col[] = {
- { 0, tt2col[4] },
- { 1, tt2col[3] },
- { 2, tt2col[2] },
- { 3, tt2col[1] }
-};
-
-static const ITab
-tt2x1 = {
- "TT2X1", 1, tt2x1col
-};
-
-static const ITab
-tt2x2 = {
- "TT2X2", 2, tt2x2col
-};
-
-static const ITab
-tt2x3 = {
- "TT2X3", 2, tt2x3col
-};
-
-static const ITab
-tt2x4 = {
- "TT2X4", 2, tt2x4col
-};
-
-static const ITab
-tt2x5 = {
- "TT2X5", 4, tt2x5col
-};
-
-static const ITab
-tt2itab[] = {
- tt2x1,
- tt2x2,
- tt2x3,
- tt2x4,
- tt2x5
-};
-
-static const Tab
-tt2 = {
- "TT2", 5, tt2col, 5, tt2itab
-};
-
-// all tables
-
-static const Tab
-tablist[] = {
- tt1,
- tt2
-};
+static void
+verifytables()
+{
+ for (unsigned j = 0; j < tabcount; j++) {
+ const Tab* t = tablist[j];
+ if (t == 0)
+ continue;
+ assert(t->m_cols != 0 && t->m_col != 0);
+ for (unsigned k = 0; k < t->m_cols; k++) {
+ const Col* c = t->m_col[k];
+ assert(c != 0 && c->m_num == k);
+ assert(! (c->m_pk && c->m_nullable));
+ }
+ assert(t->m_col[t->m_cols] == 0);
+ {
+ assert(t->m_keycol < t->m_cols);
+ const Col* c = t->m_col[t->m_keycol];
+ assert(c->m_pk && c->m_type == Col::Unsigned);
+ }
+ assert(t->m_itabs != 0 && t->m_itab != 0);
+ for (unsigned i = 0; i < t->m_itabs; i++) {
+ const ITab* x = t->m_itab[i];
+ if (x == 0)
+ continue;
+ assert(x != 0 && x->m_icols != 0 && x->m_icol != 0);
+ for (unsigned k = 0; k < x->m_icols; k++) {
+ const ICol* c = x->m_icol[k];
+ assert(c != 0 && c->m_num == k && c->m_col.m_num < t->m_cols);
+ if (x->m_type == ITab::UniqueHashIndex) {
+ assert(! c->m_col.m_nullable);
+ }
+ }
+ }
+ assert(t->m_itab[t->m_itabs] == 0);
+ }
+}
-static const unsigned
-tabcount = sizeof(tablist) / sizeof(tablist[0]);
+static void
+makebuiltintables(Par par)
+{
+ LL2("makebuiltintables");
+ resetcslist();
+ tabcount = 3;
+ if (tablist == 0) {
+ tablist = new const Tab* [tabcount];
+ for (unsigned j = 0; j < tabcount; j++) {
+ tablist[j] = 0;
+ }
+ } else {
+ for (unsigned j = 0; j < tabcount; j++) {
+ delete tablist[j];
+ tablist[j] = 0;
+ }
+ }
+ // ti0 - basic
+ if (usetable(par, 0)) {
+ Tab* t = new Tab("ti0", 5, 7, 0);
+ // name - pk - type - length - nullable - cs
+ t->coladd(0, new Col(*t, 0, "a", 1, Col::Unsigned, 1, 0, 0));
+ t->coladd(1, new Col(*t, 1, "b", 0, Col::Unsigned, 1, 1, 0));
+ t->coladd(2, new Col(*t, 2, "c", 0, Col::Unsigned, 1, 0, 0));
+ t->coladd(3, new Col(*t, 3, "d", 0, Col::Unsigned, 1, 1, 0));
+ t->coladd(4, new Col(*t, 4, "e", 0, Col::Unsigned, 1, 0, 0));
+ if (useindex(par, 0)) {
+ // a
+ ITab* x = new ITab(*t, "ti0x0", ITab::OrderedIndex, 1);
+ x->icoladd(0, new ICol(*x, 0, *t->m_col[0]));
+ t->itabadd(0, x);
+ }
+ if (useindex(par, 1)) {
+ // b
+ ITab* x = new ITab(*t, "ti0x1", ITab::OrderedIndex, 1);
+ x->icoladd(0, new ICol(*x, 0, *t->m_col[1]));
+ t->itabadd(1, x);
+ }
+ if (useindex(par, 2)) {
+ // b, c
+ ITab* x = new ITab(*t, "ti0x2", ITab::OrderedIndex, 2);
+ x->icoladd(0, new ICol(*x, 0, *t->m_col[1]));
+ x->icoladd(1, new ICol(*x, 1, *t->m_col[2]));
+ t->itabadd(2, x);
+ }
+ if (useindex(par, 3)) {
+ // b, e, c, d
+ ITab* x = new ITab(*t, "ti0x3", ITab::OrderedIndex, 4);
+ x->icoladd(0, new ICol(*x, 0, *t->m_col[1]));
+ x->icoladd(1, new ICol(*x, 1, *t->m_col[4]));
+ x->icoladd(2, new ICol(*x, 2, *t->m_col[2]));
+ x->icoladd(3, new ICol(*x, 3, *t->m_col[3]));
+ t->itabadd(3, x);
+ }
+ if (useindex(par, 4)) {
+ // a, c
+ ITab* x = new ITab(*t, "ti0z4", ITab::UniqueHashIndex, 2);
+ x->icoladd(0, new ICol(*x, 0, *t->m_col[0]));
+ x->icoladd(1, new ICol(*x, 1, *t->m_col[2]));
+ t->itabadd(4, x);
+ }
+ if (useindex(par, 5)) {
+ // a, e
+ ITab* x = new ITab(*t, "ti0z5", ITab::UniqueHashIndex, 2);
+ x->icoladd(0, new ICol(*x, 0, *t->m_col[0]));
+ x->icoladd(1, new ICol(*x, 1, *t->m_col[4]));
+ t->itabadd(5, x);
+ }
+ tablist[0] = t;
+ }
+ // ti1 - simple char fields
+ if (usetable(par, 1)) {
+ Tab* t = new Tab("ti1", 5, 7, 1);
+ // name - pk - type - length - nullable - cs
+ t->coladd(0, new Col(*t, 0, "a", 0, Col::Unsigned, 1, 0, 0));
+ t->coladd(1, new Col(*t, 1, "b", 1, Col::Unsigned, 1, 0, 0));
+ t->coladd(2, new Col(*t, 2, "c", 0, Col::Varchar, 20, 0, getcs(par)));
+ t->coladd(3, new Col(*t, 3, "d", 0, Col::Char, 5, 0, getcs(par)));
+ t->coladd(4, new Col(*t, 4, "e", 0, Col::Longvarchar, 5, 1, getcs(par)));
+ if (useindex(par, 0)) {
+ // b
+ ITab* x = new ITab(*t, "ti1x0", ITab::OrderedIndex, 1);
+ x->icoladd(0, new ICol(*x, 0, *t->m_col[1]));
+ t->itabadd(0, x);
+ }
+ if (useindex(par, 1)) {
+ // c, a
+ ITab* x = new ITab(*t, "ti1x1", ITab::OrderedIndex, 2);
+ x->icoladd(0, new ICol(*x, 0, *t->m_col[2]));
+ x->icoladd(1, new ICol(*x, 1, *t->m_col[0]));
+ t->itabadd(1, x);
+ }
+ if (useindex(par, 2)) {
+ // d
+ ITab* x = new ITab(*t, "ti1x2", ITab::OrderedIndex, 1);
+ x->icoladd(0, new ICol(*x, 0, *t->m_col[3]));
+ t->itabadd(2, x);
+ }
+ if (useindex(par, 3)) {
+ // e, d, c, b
+ ITab* x = new ITab(*t, "ti1x3", ITab::OrderedIndex, 4);
+ x->icoladd(0, new ICol(*x, 0, *t->m_col[4]));
+ x->icoladd(1, new ICol(*x, 1, *t->m_col[3]));
+ x->icoladd(2, new ICol(*x, 2, *t->m_col[2]));
+ x->icoladd(3, new ICol(*x, 3, *t->m_col[1]));
+ t->itabadd(3, x);
+ }
+ if (useindex(par, 4)) {
+ // a, b
+ ITab* x = new ITab(*t, "ti1z4", ITab::UniqueHashIndex, 2);
+ x->icoladd(0, new ICol(*x, 0, *t->m_col[0]));
+ x->icoladd(1, new ICol(*x, 1, *t->m_col[1]));
+ t->itabadd(4, x);
+ }
+ if (useindex(par, 5)) {
+ // b, c, d
+ ITab* x = new ITab(*t, "ti1z5", ITab::UniqueHashIndex, 3);
+ x->icoladd(0, new ICol(*x, 0, *t->m_col[1]));
+ x->icoladd(1, new ICol(*x, 1, *t->m_col[2]));
+ x->icoladd(2, new ICol(*x, 2, *t->m_col[3]));
+ t->itabadd(5, x);
+ }
+ tablist[1] = t;
+ }
+ // ti2 - complex char fields
+ if (usetable(par, 2)) {
+ Tab* t = new Tab("ti2", 5, 7, 2);
+ // name - pk - type - length - nullable - cs
+ t->coladd(0, new Col(*t, 0, "a", 1, Col::Char, 31, 0, getcs(par)));
+ t->coladd(1, new Col(*t, 1, "b", 0, Col::Char, 4, 1, getcs(par)));
+ t->coladd(2, new Col(*t, 2, "c", 1, Col::Unsigned, 1, 0, 0));
+ t->coladd(3, new Col(*t, 3, "d", 1, Col::Varchar, 128, 0, getcs(par)));
+ t->coladd(4, new Col(*t, 4, "e", 0, Col::Varchar, 7, 0, getcs(par)));
+ if (useindex(par, 0)) {
+ // a, c, d
+ ITab* x = new ITab(*t, "ti2x0", ITab::OrderedIndex, 3);
+ x->icoladd(0, new ICol(*x, 0, *t->m_col[0]));
+ x->icoladd(1, new ICol(*x, 1, *t->m_col[2]));
+ x->icoladd(2, new ICol(*x, 2, *t->m_col[3]));
+ t->itabadd(0, x);
+ }
+ if (useindex(par, 1)) {
+ // e, d, c, b, a
+ ITab* x = new ITab(*t, "ti2x1", ITab::OrderedIndex, 5);
+ x->icoladd(0, new ICol(*x, 0, *t->m_col[4]));
+ x->icoladd(1, new ICol(*x, 1, *t->m_col[3]));
+ x->icoladd(2, new ICol(*x, 2, *t->m_col[2]));
+ x->icoladd(3, new ICol(*x, 3, *t->m_col[1]));
+ x->icoladd(4, new ICol(*x, 4, *t->m_col[0]));
+ t->itabadd(1, x);
+ }
+ if (useindex(par, 2)) {
+ // d
+ ITab* x = new ITab(*t, "ti2x2", ITab::OrderedIndex, 1);
+ x->icoladd(0, new ICol(*x, 0, *t->m_col[3]));
+ t->itabadd(2, x);
+ }
+ if (useindex(par, 3)) {
+ // b
+ ITab* x = new ITab(*t, "ti2x3", ITab::OrderedIndex, 1);
+ x->icoladd(0, new ICol(*x, 0, *t->m_col[1]));
+ t->itabadd(3, x);
+ }
+ if (useindex(par, 4)) {
+ // a, c
+ ITab* x = new ITab(*t, "ti2z4", ITab::UniqueHashIndex, 2);
+ x->icoladd(0, new ICol(*x, 0, *t->m_col[0]));
+ x->icoladd(1, new ICol(*x, 1, *t->m_col[2]));
+ t->itabadd(4, x);
+ }
+ if (useindex(par, 5)) {
+ // a, c, d, e
+ ITab* x = new ITab(*t, "ti2z5", ITab::UniqueHashIndex, 4);
+ x->icoladd(0, new ICol(*x, 0, *t->m_col[0]));
+ x->icoladd(1, new ICol(*x, 1, *t->m_col[2]));
+ x->icoladd(2, new ICol(*x, 2, *t->m_col[3]));
+ x->icoladd(3, new ICol(*x, 3, *t->m_col[4]));
+ t->itabadd(5, x);
+ }
+ tablist[2] = t;
+ }
+ verifytables();
+}
// connections
@@ -682,16 +1191,18 @@ struct Con {
NdbDictionary::Dictionary* m_dic;
NdbConnection* m_tx;
NdbOperation* m_op;
+ NdbIndexOperation* m_indexop;
NdbScanOperation* m_scanop;
NdbIndexScanOperation* m_indexscanop;
- NdbResultSet* m_resultset;
+ NdbScanFilter* m_scanfilter;
enum ScanMode { ScanNo = 0, Committed, Latest, Exclusive };
ScanMode m_scanmode;
enum ErrType { ErrNone = 0, ErrDeadlock, ErrNospace, ErrOther };
ErrType m_errtype;
Con() :
- m_ndb(0), m_dic(0), m_tx(0), m_op(0),
- m_scanop(0), m_indexscanop(0), m_resultset(0), m_scanmode(ScanNo), m_errtype(ErrNone) {}
+ m_ndb(0), m_dic(0), m_tx(0), m_op(0), m_indexop(0),
+ m_scanop(0), m_indexscanop(0), m_scanfilter(0),
+ m_scanmode(ScanNo), m_errtype(ErrNone) {}
~Con() {
if (m_tx != 0)
closeTransaction();
@@ -701,16 +1212,23 @@ struct Con {
void disconnect();
int startTransaction();
int getNdbOperation(const Tab& tab);
+ int getNdbIndexOperation1(const ITab& itab, const Tab& tab);
+ int getNdbIndexOperation(const ITab& itab, const Tab& tab);
int getNdbScanOperation(const Tab& tab);
- int getNdbScanOperation(const ITab& itab, const Tab& tab);
+ int getNdbIndexScanOperation1(const ITab& itab, const Tab& tab);
+ int getNdbIndexScanOperation(const ITab& itab, const Tab& tab);
+ int getNdbScanFilter();
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 beginFilter(int group);
+ int endFilter();
+ int setFilter(int num, int cond, const void* value, unsigned len);
int execute(ExecType t);
int execute(ExecType t, bool& deadlock, bool& nospace);
- int openScanRead(unsigned scanbat, unsigned scanpar);
- int openScanExclusive(unsigned scanbat, unsigned scanpar);
+ int readTuples(Par par);
+ int readIndexTuples(Par par);
int executeScan();
int nextScanResult(bool fetchAllowed);
int nextScanResult(bool fetchAllowed, bool& deadlock);
@@ -765,6 +1283,28 @@ Con::getNdbOperation(const Tab& tab)
}
int
+Con::getNdbIndexOperation1(const ITab& itab, const Tab& tab)
+{
+ assert(m_tx != 0);
+ CHKCON((m_op = m_indexop = m_tx->getNdbIndexOperation(itab.m_name, tab.m_name)) != 0, *this);
+ return 0;
+}
+
+int
+Con::getNdbIndexOperation(const ITab& itab, const Tab& tab)
+{
+ assert(m_tx != 0);
+ unsigned tries = 0;
+ while (1) {
+ if (getNdbIndexOperation1(itab, tab) == 0)
+ break;
+ CHK(++tries < 10);
+ NdbSleep_MilliSleep(100);
+ }
+ return 0;
+}
+
+int
Con::getNdbScanOperation(const Tab& tab)
{
assert(m_tx != 0);
@@ -773,7 +1313,7 @@ Con::getNdbScanOperation(const Tab& tab)
}
int
-Con::getNdbScanOperation(const ITab& itab, const Tab& tab)
+Con::getNdbIndexScanOperation1(const ITab& itab, const Tab& tab)
{
assert(m_tx != 0);
CHKCON((m_op = m_scanop = m_indexscanop = m_tx->getNdbIndexScanOperation(itab.m_name, tab.m_name)) != 0, *this);
@@ -781,6 +1321,29 @@ Con::getNdbScanOperation(const ITab& itab, const Tab& tab)
}
int
+Con::getNdbIndexScanOperation(const ITab& itab, const Tab& tab)
+{
+ assert(m_tx != 0);
+ unsigned tries = 0;
+ while (1) {
+ if (getNdbIndexScanOperation1(itab, tab) == 0)
+ break;
+ CHK(++tries < 10);
+ NdbSleep_MilliSleep(100);
+ }
+ return 0;
+}
+
+int
+Con::getNdbScanFilter()
+{
+ assert(m_tx != 0 && m_scanop != 0);
+ delete m_scanfilter;
+ m_scanfilter = new NdbScanFilter(m_scanop);
+ return 0;
+}
+
+int
Con::equal(int num, const char* addr)
{
assert(m_tx != 0 && m_op != 0);
@@ -807,12 +1370,36 @@ Con::setValue(int num, const char* addr)
int
Con::setBound(int num, int type, const void* value)
{
- assert(m_tx != 0 && m_op != 0);
+ assert(m_tx != 0 && m_indexscanop != 0);
CHKCON(m_indexscanop->setBound(num, type, value) == 0, *this);
return 0;
}
int
+Con::beginFilter(int group)
+{
+ assert(m_tx != 0 && m_scanfilter != 0);
+ CHKCON(m_scanfilter->begin((NdbScanFilter::Group)group) == 0, *this);
+ return 0;
+}
+
+int
+Con::endFilter()
+{
+ assert(m_tx != 0 && m_scanfilter != 0);
+ CHKCON(m_scanfilter->end() == 0, *this);
+ return 0;
+}
+
+int
+Con::setFilter(int num, int cond, const void* value, unsigned len)
+{
+ assert(m_tx != 0 && m_scanfilter != 0);
+ CHKCON(m_scanfilter->cmp((NdbScanFilter::BinaryCondition)cond, num, value, len) == 0, *this);
+ return 0;
+}
+
+int
Con::execute(ExecType t)
{
assert(m_tx != 0);
@@ -841,20 +1428,21 @@ Con::execute(ExecType t, bool& deadlock, bool& nospace)
}
int
-Con::openScanRead(unsigned scanbat, unsigned scanpar)
+Con::readTuples(Par par)
{
- assert(m_tx != 0 && m_op != 0);
- NdbOperation::LockMode lm = NdbOperation::LM_Read;
- CHKCON((m_resultset = m_scanop->readTuples(lm, scanbat, scanpar)) != 0, *this);
+ assert(m_tx != 0 && m_scanop != 0);
+ int scan_flags = 0;
+ if (par.m_tupscan)
+ scan_flags |= NdbScanOperation::SF_TupScan;
+ CHKCON(m_scanop->readTuples(par.m_lockmode, scan_flags, par.m_scanpar) == 0, *this);
return 0;
}
int
-Con::openScanExclusive(unsigned scanbat, unsigned scanpar)
+Con::readIndexTuples(Par par)
{
- assert(m_tx != 0 && m_op != 0);
- NdbOperation::LockMode lm = NdbOperation::LM_Exclusive;
- CHKCON((m_resultset = m_scanop->readTuples(lm, scanbat, scanpar)) != 0, *this);
+ assert(m_tx != 0 && m_indexscanop != 0);
+ CHKCON(m_indexscanop->readTuples(par.m_lockmode, 0, par.m_scanpar, par.m_ordered, par.m_descending) == 0, *this);
return 0;
}
@@ -869,8 +1457,8 @@ int
Con::nextScanResult(bool fetchAllowed)
{
int ret;
- assert(m_resultset != 0);
- CHKCON((ret = m_resultset->nextResult(fetchAllowed)) != -1, *this);
+ assert(m_scanop != 0);
+ CHKCON((ret = m_scanop->nextResult(fetchAllowed)) != -1, *this);
assert(ret == 0 || ret == 1 || (! fetchAllowed && ret == 2));
return ret;
}
@@ -895,7 +1483,7 @@ int
Con::updateScanTuple(Con& con2)
{
assert(con2.m_tx != 0);
- CHKCON((con2.m_op = m_resultset->updateTuple(con2.m_tx)) != 0, *this);
+ CHKCON((con2.m_op = m_scanop->updateCurrentTuple(con2.m_tx)) != 0, *this);
return 0;
}
@@ -903,16 +1491,16 @@ int
Con::deleteScanTuple(Con& con2)
{
assert(con2.m_tx != 0);
- CHKCON(m_resultset->deleteTuple(con2.m_tx) == 0, *this);
+ CHKCON(m_scanop->deleteCurrentTuple(con2.m_tx) == 0, *this);
return 0;
}
void
Con::closeScan()
{
- assert(m_resultset != 0);
- m_resultset->close();
- m_scanop = 0, m_indexscanop = 0, m_resultset = 0;
+ assert(m_scanop != 0);
+ m_scanop->close();
+ m_scanop = 0, m_indexscanop = 0;
}
@@ -922,7 +1510,7 @@ Con::closeTransaction()
assert(m_ndb != 0 && m_tx != 0);
m_ndb->closeTransaction(m_tx);
m_tx = 0, m_op = 0;
- m_scanop = 0, m_indexscanop = 0, m_resultset = 0;
+ m_scanop = 0, m_indexscanop = 0;
}
void
@@ -945,7 +1533,8 @@ Con::printerror(NdbOut& out)
if ((code = m_tx->getNdbError().code) != 0) {
LL0(++any << " con: error " << m_tx->getNdbError());
die += (code == g_opt.m_die);
- if (code == 266 || code == 274 || code == 296 || code == 297 || code == 499)
+ // 631 is new, occurs only on 4 db nodes, needs to be checked out
+ if (code == 266 || code == 274 || code == 296 || code == 297 || code == 499 || code == 631)
m_errtype = ErrDeadlock;
if (code == 826 || code == 827 || code == 902)
m_errtype = ErrNospace;
@@ -983,9 +1572,9 @@ invalidateindex(Par par)
Con& con = par.con();
const Tab& tab = par.tab();
for (unsigned i = 0; i < tab.m_itabs; i++) {
- if (! useindex(i))
+ if (tab.m_itab[i] == 0)
continue;
- const ITab& itab = tab.m_itab[i];
+ const ITab& itab = *tab.m_itab[i];
invalidateindex(par, itab);
}
return 0;
@@ -1033,16 +1622,14 @@ createtable(Par par)
t.setLogging(false);
}
for (unsigned k = 0; k < tab.m_cols; k++) {
- const Col& col = tab.m_col[k];
+ const Col& col = *tab.m_col[k];
NdbDictionary::Column c(col.m_name);
- c.setType(col.m_type);
- c.setLength(col.m_length);
+ c.setType((NdbDictionary::Column::Type)col.m_type);
+ c.setLength(col.m_bytelength); // for char NDB API uses length in bytes
c.setPrimaryKey(col.m_pk);
c.setNullable(col.m_nullable);
- if (c.getCharset()) { // test if char type
- if (! col.m_pk)
- c.setCharset(par.m_cs);
- }
+ if (col.m_chs != 0)
+ c.setCharset(col.m_chs->m_cs);
t.addColumn(c);
}
con.m_dic = con.m_ndb->getDictionary();
@@ -1073,9 +1660,9 @@ dropindex(Par par)
{
const Tab& tab = par.tab();
for (unsigned i = 0; i < tab.m_itabs; i++) {
- if (! useindex(i))
+ if (tab.m_itab[i] == 0)
continue;
- const ITab& itab = tab.m_itab[i];
+ const ITab& itab = *tab.m_itab[i];
CHK(dropindex(par, itab) == 0);
}
return 0;
@@ -1090,10 +1677,13 @@ createindex(Par par, const ITab& itab)
LL4(itab);
NdbDictionary::Index x(itab.m_name);
x.setTable(tab.m_name);
- x.setType(NdbDictionary::Index::OrderedIndex);
- x.setLogging(false);
+ x.setType((NdbDictionary::Index::Type)itab.m_type);
+ if (par.m_nologging || itab.m_type == ITab::OrderedIndex) {
+ x.setLogging(false);
+ }
for (unsigned k = 0; k < itab.m_icols; k++) {
- const Col& col = itab.m_icol[k].m_col;
+ const ICol& icol = *itab.m_icol[k];
+ const Col& col = icol.m_col;
x.addColumnName(col.m_name);
}
con.m_dic = con.m_ndb->getDictionary();
@@ -1107,9 +1697,9 @@ createindex(Par par)
{
const Tab& tab = par.tab();
for (unsigned i = 0; i < tab.m_itabs; i++) {
- if (! useindex(i))
+ if (tab.m_itab[i] == 0)
continue;
- const ITab& itab = tab.m_itab[i];
+ const ITab& itab = *tab.m_itab[i];
CHK(createindex(par, itab) == 0);
}
return 0;
@@ -1117,43 +1707,15 @@ createindex(Par par)
// data sets
-static unsigned
-urandom(unsigned n)
-{
- if (n == 0)
- return 0;
- unsigned i = random() % n;
- return i;
-}
-
-static int
-irandom(unsigned n)
-{
- if (n == 0)
- return 0;
- int i = random() % n;
- if (random() & 0x1)
- i = -i;
- return i;
-}
-
-static bool
-randompct(unsigned pct)
-{
- if (pct == 0)
- return false;
- if (pct >= 100)
- return true;
- return urandom(100) < pct;
-}
-
// Val - typed column value
struct Val {
const Col& m_col;
union {
Uint32 m_uint32;
- char* m_varchar;
+ unsigned char* m_char;
+ unsigned char* m_varchar;
+ unsigned char* m_longvarchar;
};
Val(const Col& col);
~Val();
@@ -1161,10 +1723,17 @@ struct Val {
void copy(const void* addr);
const void* dataaddr() const;
bool m_null;
+ int equal(Par par) const;
+ int equal(Par par, const ICol& icol) const;
int setval(Par par) const;
void calc(Par par, unsigned i);
- int verify(const Val& val2) const;
- int cmp(const Val& val2) const;
+ void calckey(Par par, unsigned i);
+ void calckeychars(Par par, unsigned i, unsigned& n, unsigned char* buf);
+ void calcnokey(Par par);
+ void calcnokeychars(Par par, unsigned& n, unsigned char* buf);
+ int verify(Par par, const Val& val2) const;
+ int cmp(Par par, const Val& val2) const;
+ int cmpchars(Par par, const unsigned char* buf1, unsigned len1, const unsigned char* buf2, unsigned len2) const;
private:
Val& operator=(const Val& val2);
};
@@ -1176,10 +1745,16 @@ Val::Val(const Col& col) :
m_col(col)
{
switch (col.m_type) {
- case NdbDictionary::Column::Unsigned:
+ case Col::Unsigned:
break;
- case NdbDictionary::Column::Varchar:
- m_varchar = new char [2 + col.m_length];
+ case Col::Char:
+ m_char = new unsigned char [col.m_bytelength];
+ break;
+ case Col::Varchar:
+ m_varchar = new unsigned char [1 + col.m_bytelength];
+ break;
+ case Col::Longvarchar:
+ m_longvarchar = new unsigned char [2 + col.m_bytelength];
break;
default:
assert(false);
@@ -1191,11 +1766,17 @@ Val::~Val()
{
const Col& col = m_col;
switch (col.m_type) {
- case NdbDictionary::Column::Unsigned:
+ case Col::Unsigned:
break;
- case NdbDictionary::Column::Varchar:
+ case Col::Char:
+ delete [] m_char;
+ break;
+ case Col::Varchar:
delete [] m_varchar;
break;
+ case Col::Longvarchar:
+ delete [] m_longvarchar;
+ break;
default:
assert(false);
break;
@@ -1220,11 +1801,17 @@ Val::copy(const void* addr)
{
const Col& col = m_col;
switch (col.m_type) {
- case NdbDictionary::Column::Unsigned:
+ case Col::Unsigned:
m_uint32 = *(const Uint32*)addr;
break;
- case NdbDictionary::Column::Varchar:
- memcpy(m_varchar, addr, 2 + col.m_length);
+ case Col::Char:
+ memcpy(m_char, addr, col.m_bytelength);
+ break;
+ case Col::Varchar:
+ memcpy(m_varchar, addr, 1 + col.m_bytelength);
+ break;
+ case Col::Longvarchar:
+ memcpy(m_longvarchar, addr, 2 + col.m_bytelength);
break;
default:
assert(false);
@@ -1238,10 +1825,14 @@ Val::dataaddr() const
{
const Col& col = m_col;
switch (col.m_type) {
- case NdbDictionary::Column::Unsigned:
+ case Col::Unsigned:
return &m_uint32;
- case NdbDictionary::Column::Varchar:
+ case Col::Char:
+ return m_char;
+ case Col::Varchar:
return m_varchar;
+ case Col::Longvarchar:
+ return m_longvarchar;
default:
break;
}
@@ -1250,18 +1841,37 @@ Val::dataaddr() const
}
int
-Val::setval(Par par) const
+Val::equal(Par par) const
{
Con& con = par.con();
const Col& col = m_col;
+ assert(col.m_pk && ! m_null);
const char* addr = (const char*)dataaddr();
- if (m_null)
- addr = 0;
- if (col.m_pk)
- CHK(con.equal(col.m_num, addr) == 0);
- else
- CHK(con.setValue(col.m_num, addr) == 0);
- LL5("setval [" << m_col << "] " << *this);
+ LL5("equal [" << col << "] " << *this);
+ CHK(con.equal(col.m_num, addr) == 0);
+ return 0;
+}
+
+int
+Val::equal(Par par, const ICol& icol) const
+{
+ Con& con = par.con();
+ assert(! m_null);
+ const char* addr = (const char*)dataaddr();
+ LL5("equal [" << icol << "] " << *this);
+ CHK(con.equal(icol.m_num, addr) == 0);
+ return 0;
+}
+
+int
+Val::setval(Par par) const
+{
+ Con& con = par.con();
+ const Col& col = m_col;
+ assert(! col.m_pk);
+ const char* addr = ! m_null ? (const char*)dataaddr() : 0;
+ LL5("setval [" << col << "] " << *this);
+ CHK(con.setValue(col.m_num, addr) == 0);
return 0;
}
@@ -1269,58 +1879,170 @@ void
Val::calc(Par par, unsigned i)
{
const Col& col = m_col;
+ col.m_pk ? calckey(par, i) : calcnokey(par);
+ if (! m_null)
+ col.wellformed(dataaddr());
+}
+
+void
+Val::calckey(Par par, unsigned i)
+{
+ const Col& col = m_col;
m_null = false;
- if (col.m_pk) {
+ switch (col.m_type) {
+ case Col::Unsigned:
m_uint32 = i;
- return;
+ break;
+ case Col::Char:
+ {
+ const Chs* chs = col.m_chs;
+ CHARSET_INFO* cs = chs->m_cs;
+ unsigned n = 0;
+ calckeychars(par, i, n, m_char);
+ // extend by appropriate space
+ (*cs->cset->fill)(cs, (char*)&m_char[n], col.m_bytelength - n, 0x20);
+ }
+ break;
+ case Col::Varchar:
+ {
+ unsigned n = 0;
+ calckeychars(par, i, n, m_varchar + 1);
+ // set length and pad with nulls
+ m_varchar[0] = n;
+ memset(&m_varchar[1 + n], 0, col.m_bytelength - n);
+ }
+ break;
+ case Col::Longvarchar:
+ {
+ unsigned n = 0;
+ calckeychars(par, i, n, m_longvarchar + 2);
+ // set length and pad with nulls
+ m_longvarchar[0] = (n & 0xff);
+ m_longvarchar[1] = (n >> 8);
+ memset(&m_longvarchar[2 + n], 0, col.m_bytelength - n);
+ }
+ break;
+ default:
+ assert(false);
+ break;
}
+}
+
+void
+Val::calckeychars(Par par, unsigned i, unsigned& n, unsigned char* buf)
+{
+ const Col& col = m_col;
+ const Chs* chs = col.m_chs;
+ CHARSET_INFO* cs = chs->m_cs;
+ n = 0;
+ unsigned len = 0;
+ while (len < col.m_length) {
+ if (i % (1 + n) == 0) {
+ break;
+ }
+ const Chr& chr = chs->m_chr[i % maxcharcount];
+ assert(n + chr.m_size <= col.m_bytelength);
+ memcpy(buf + n, chr.m_bytes, chr.m_size);
+ n += chr.m_size;
+ len++;
+ }
+}
+
+void
+Val::calcnokey(Par par)
+{
+ const Col& col = m_col;
+ m_null = false;
if (col.m_nullable && urandom(100) < par.m_pctnull) {
m_null = true;
return;
}
- unsigned v = par.m_range + irandom((par.m_pctrange * par.m_range) / 100);
+ int r = irandom((par.m_pctrange * par.m_range) / 100);
+ if (par.m_bdir != 0 && urandom(10) != 0) {
+ if (r < 0 && par.m_bdir > 0 || r > 0 && par.m_bdir < 0)
+ r = -r;
+ }
+ unsigned v = par.m_range + r;
switch (col.m_type) {
- case NdbDictionary::Column::Unsigned:
+ case Col::Unsigned:
m_uint32 = v;
break;
- case NdbDictionary::Column::Varchar:
+ case Col::Char:
{
+ const Chs* chs = col.m_chs;
+ CHARSET_INFO* cs = chs->m_cs;
unsigned n = 0;
- while (n < col.m_length) {
- if (urandom(1 + col.m_length) == 0) {
- // nice distribution on lengths
- break;
- }
- m_varchar[2 + n++] = 'a' + urandom((par.m_pctrange * 10) / 100);
- }
- m_varchar[0] = (n >> 8);
- m_varchar[1] = (n & 0xff);
- while (n < col.m_length) {
- m_varchar[2 + n++] = 0;
- }
+ calcnokeychars(par, n, m_char);
+ // extend by appropriate space
+ (*cs->cset->fill)(cs, (char*)&m_char[n], col.m_bytelength - n, 0x20);
+ }
+ break;
+ case Col::Varchar:
+ {
+ unsigned n = 0;
+ calcnokeychars(par, n, m_varchar + 1);
+ // set length and pad with nulls
+ m_varchar[0] = n;
+ memset(&m_varchar[1 + n], 0, col.m_bytelength - n);
+ }
+ break;
+ case Col::Longvarchar:
+ {
+ unsigned n = 0;
+ calcnokeychars(par, n, m_longvarchar + 2);
+ // set length and pad with nulls
+ m_longvarchar[0] = (n & 0xff);
+ m_longvarchar[1] = (n >> 8);
+ memset(&m_longvarchar[2 + n], 0, col.m_bytelength - n);
}
break;
default:
assert(false);
break;
}
- // verify format
- col.verify(dataaddr());
+}
+
+void
+Val::calcnokeychars(Par par, unsigned& n, unsigned char* buf)
+{
+ const Col& col = m_col;
+ const Chs* chs = col.m_chs;
+ CHARSET_INFO* cs = chs->m_cs;
+ n = 0;
+ unsigned len = 0;
+ while (len < col.m_length) {
+ if (urandom(1 + col.m_bytelength) == 0) {
+ break;
+ }
+ unsigned half = maxcharcount / 2;
+ int r = irandom((par.m_pctrange * half) / 100);
+ if (par.m_bdir != 0 && urandom(10) != 0) {
+ if (r < 0 && par.m_bdir > 0 || r > 0 && par.m_bdir < 0)
+ r = -r;
+ }
+ unsigned i = half + r;
+ assert(i < maxcharcount);
+ const Chr& chr = chs->m_chr[i];
+ assert(n + chr.m_size <= col.m_bytelength);
+ memcpy(buf + n, chr.m_bytes, chr.m_size);
+ n += chr.m_size;
+ len++;
+ }
}
int
-Val::verify(const Val& val2) const
+Val::verify(Par par, const Val& val2) const
{
- CHK(cmp(val2) == 0);
+ CHK(cmp(par, val2) == 0);
return 0;
}
int
-Val::cmp(const Val& val2) const
+Val::cmp(Par par, const Val& val2) const
{
const Col& col = m_col;
const Col& col2 = val2.m_col;
- assert(col.m_type == col2.m_type && col.m_length == col2.m_length);
+ assert(col.equal(col2));
if (m_null || val2.m_null) {
if (! m_null)
return +1;
@@ -1329,18 +2051,39 @@ Val::cmp(const Val& val2) const
return 0;
}
// verify data formats
- col.verify(dataaddr());
- col.verify(val2.dataaddr());
+ col.wellformed(dataaddr());
+ col.wellformed(val2.dataaddr());
// compare
switch (col.m_type) {
- case NdbDictionary::Column::Unsigned:
- if (m_uint32 < val2.m_uint32)
- return -1;
- if (m_uint32 > val2.m_uint32)
- return +1;
- return 0;
- case NdbDictionary::Column::Varchar:
- return memcmp(&m_varchar[2], &val2.m_varchar[2], col.m_length);
+ case Col::Unsigned:
+ {
+ if (m_uint32 < val2.m_uint32)
+ return -1;
+ if (m_uint32 > val2.m_uint32)
+ return +1;
+ return 0;
+ }
+ break;
+ case Col::Char:
+ {
+ unsigned len = col.m_bytelength;
+ return cmpchars(par, m_char, len, val2.m_char, len);
+ }
+ break;
+ case Col::Varchar:
+ {
+ unsigned len1 = m_varchar[0];
+ unsigned len2 = val2.m_varchar[0];
+ return cmpchars(par, m_varchar + 1, len1, val2.m_varchar + 1, len2);
+ }
+ break;
+ case Col::Longvarchar:
+ {
+ unsigned len1 = m_longvarchar[0] + (m_longvarchar[1] << 8);
+ unsigned len2 = val2.m_longvarchar[0] + (val2.m_longvarchar[1] << 8);
+ return cmpchars(par, m_longvarchar + 2, len1, val2.m_longvarchar + 2, len2);
+ }
+ break;
default:
break;
}
@@ -1348,6 +2091,56 @@ Val::cmp(const Val& val2) const
return 0;
}
+int
+Val::cmpchars(Par par, const unsigned char* buf1, unsigned len1, const unsigned char* buf2, unsigned len2) const
+{
+ const Col& col = m_col;
+ const Chs* chs = col.m_chs;
+ CHARSET_INFO* cs = chs->m_cs;
+ int k;
+ if (! par.m_collsp) {
+ unsigned char x1[maxxmulsize * 8000];
+ unsigned char x2[maxxmulsize * 8000];
+ // make strxfrm pad both to same length
+ unsigned len = maxxmulsize * col.m_bytelength;
+ int n1 = NdbSqlUtil::strnxfrm_bug7284(cs, x1, chs->m_xmul * len, buf1, len1);
+ int n2 = NdbSqlUtil::strnxfrm_bug7284(cs, x2, chs->m_xmul * len, buf2, len2);
+ assert(n1 != -1 && n1 == n2);
+ k = memcmp(x1, x2, n1);
+ } else {
+ k = (*cs->coll->strnncollsp)(cs, buf1, len1, buf2, len2, false);
+ }
+ return k < 0 ? -1 : k > 0 ? +1 : 0;
+}
+
+static void
+printstring(NdbOut& out, const unsigned char* str, unsigned len, bool showlen)
+{
+ char buf[4 * 8000];
+ char *p = buf;
+ *p++ = '[';
+ if (showlen) {
+ sprintf(p, "%u:", len);
+ p += strlen(p);
+ }
+ for (unsigned i = 0; i < len; i++) {
+ unsigned char c = str[i];
+ if (c == '\\') {
+ *p++ = '\\';
+ *p++ = c;
+ } else if (0x20 <= c && c < 0x7e) {
+ *p++ = c;
+ } else {
+ *p++ = '\\';
+ *p++ = hexstr[c >> 4];
+ *p++ = hexstr[c & 15];
+ }
+ }
+ *p++ = ']';
+ *p = 0;
+ out << buf;
+}
+
static NdbOut&
operator<<(NdbOut& out, const Val& val)
{
@@ -1357,16 +2150,25 @@ operator<<(NdbOut& out, const Val& val)
return out;
}
switch (col.m_type) {
- case NdbDictionary::Column::Unsigned:
+ case Col::Unsigned:
out << val.m_uint32;
break;
- case NdbDictionary::Column::Varchar:
+ case Col::Char:
+ {
+ unsigned len = col.m_bytelength;
+ printstring(out, val.m_char, len, false);
+ }
+ break;
+ case Col::Varchar:
{
- char buf[8000];
- unsigned n = (val.m_varchar[0] << 8) | val.m_varchar[1];
- assert(n <= col.m_length);
- sprintf(buf, "'%.*s'[%d]", n, &val.m_varchar[2], n);
- out << buf;
+ unsigned len = val.m_varchar[0];
+ printstring(out, val.m_varchar + 1, len, true);
+ }
+ break;
+ case Col::Longvarchar:
+ {
+ unsigned len = val.m_longvarchar[0] + (val.m_longvarchar[1] << 8);
+ printstring(out, val.m_longvarchar + 2, len, true);
}
break;
default:
@@ -1383,19 +2185,25 @@ struct Row {
const Tab& m_tab;
Val** m_val;
bool m_exist;
- enum Op { NoOp = 0, ReadOp, InsOp, UpdOp, DelOp };
+ enum Op { NoOp = 0, ReadOp = 1, InsOp = 2, UpdOp = 4, DelOp = 8, AnyOp = 15 };
Op m_pending;
+ Row* m_dbrow; // copy of db row before update
Row(const Tab& tab);
~Row();
void copy(const Row& row2);
- void calc(Par par, unsigned i);
- int verify(const Row& row2) const;
+ void calc(Par par, unsigned i, unsigned mask = 0);
+ const Row& dbrow() const;
+ int verify(Par par, const Row& row2) const;
int insrow(Par par);
int updrow(Par par);
+ int updrow(Par par, const ITab& itab);
int delrow(Par par);
+ int delrow(Par par, const ITab& itab);
int selrow(Par par);
+ int selrow(Par par, const ITab& itab);
int setrow(Par par);
- int cmp(const Row& row2) const;
+ int cmp(Par par, const Row& row2) const;
+ int cmp(Par par, const Row& row2, const ITab& itab) const;
private:
Row& operator=(const Row& row2);
};
@@ -1405,11 +2213,12 @@ Row::Row(const Tab& tab) :
{
m_val = new Val* [tab.m_cols];
for (unsigned k = 0; k < tab.m_cols; k++) {
- const Col& col = tab.m_col[k];
+ const Col& col = *tab.m_col[k];
m_val[k] = new Val(col);
}
m_exist = false;
m_pending = NoOp;
+ m_dbrow = 0;
}
Row::~Row()
@@ -1419,6 +2228,7 @@ Row::~Row()
delete m_val[k];
}
delete [] m_val;
+ delete m_dbrow;
}
void
@@ -1431,27 +2241,49 @@ Row::copy(const Row& row2)
const Val& val2 = *row2.m_val[k];
val.copy(val2);
}
+ m_exist = row2.m_exist;
+ m_pending = row2.m_pending;
+ if (row2.m_dbrow == 0) {
+ m_dbrow = 0;
+ } else {
+ assert(row2.m_dbrow->m_dbrow == 0);
+ if (m_dbrow == 0)
+ m_dbrow = new Row(tab);
+ m_dbrow->copy(*row2.m_dbrow);
+ }
}
void
-Row::calc(Par par, unsigned i)
+Row::calc(Par par, unsigned i, unsigned mask)
{
const Tab& tab = m_tab;
for (unsigned k = 0; k < tab.m_cols; k++) {
- Val& val = *m_val[k];
- val.calc(par, i);
+ if (! (mask & (1 << k))) {
+ Val& val = *m_val[k];
+ val.calc(par, i);
+ }
}
}
+const Row&
+Row::dbrow() const
+{
+ if (m_dbrow == 0)
+ return *this;
+ assert(m_pending == Row::UpdOp || m_pending == Row::DelOp);
+ return *m_dbrow;
+}
+
int
-Row::verify(const Row& row2) const
+Row::verify(Par par, const Row& row2) const
{
const Tab& tab = m_tab;
- assert(&tab == &row2.m_tab && m_exist && row2.m_exist);
+ const Row& row1 = *this;
+ assert(&row1.m_tab == &row2.m_tab && row1.m_exist && row2.m_exist);
for (unsigned k = 0; k < tab.m_cols; k++) {
- const Val& val = *m_val[k];
+ const Val& val1 = *row1.m_val[k];
const Val& val2 = *row2.m_val[k];
- CHK(val.verify(val2) == 0);
+ CHK(val1.verify(par, val2) == 0);
}
return 0;
}
@@ -1464,9 +2296,21 @@ Row::insrow(Par par)
assert(! m_exist);
CHK(con.getNdbOperation(tab) == 0);
CHKCON(con.m_op->insertTuple() == 0, con);
+ Rsq rsq1(tab.m_cols);
for (unsigned k = 0; k < tab.m_cols; k++) {
- const Val& val = *m_val[k];
- CHK(val.setval(par) == 0);
+ unsigned k2 = rsq1.next();
+ const Val& val = *m_val[k2];
+ const Col& col = val.m_col;
+ if (col.m_pk)
+ CHK(val.equal(par) == 0);
+ }
+ Rsq rsq2(tab.m_cols);
+ for (unsigned k = 0; k < tab.m_cols; k++) {
+ unsigned k2 = rsq2.next();
+ const Val& val = *m_val[k2];
+ const Col& col = val.m_col;
+ if (! col.m_pk)
+ CHK(val.setval(par) == 0);
}
m_pending = InsOp;
return 0;
@@ -1480,9 +2324,51 @@ Row::updrow(Par par)
assert(m_exist);
CHK(con.getNdbOperation(tab) == 0);
CHKCON(con.m_op->updateTuple() == 0, con);
+ Rsq rsq1(tab.m_cols);
for (unsigned k = 0; k < tab.m_cols; k++) {
- const Val& val = *m_val[k];
- CHK(val.setval(par) == 0);
+ unsigned k2 = rsq1.next();
+ const Val& val = *m_val[k2];
+ const Col& col = val.m_col;
+ if (col.m_pk)
+ CHK(val.equal(par) == 0);
+ }
+ Rsq rsq2(tab.m_cols);
+ for (unsigned k = 0; k < tab.m_cols; k++) {
+ unsigned k2 = rsq2.next();
+ const Val& val = *m_val[k2];
+ const Col& col = val.m_col;
+ if (! col.m_pk)
+ CHK(val.setval(par) == 0);
+ }
+ m_pending = UpdOp;
+ return 0;
+}
+
+int
+Row::updrow(Par par, const ITab& itab)
+{
+ Con& con = par.con();
+ const Tab& tab = m_tab;
+ assert(itab.m_type == ITab::UniqueHashIndex && &itab.m_tab == &tab);
+ assert(m_exist);
+ CHK(con.getNdbIndexOperation(itab, tab) == 0);
+ CHKCON(con.m_op->updateTuple() == 0, con);
+ Rsq rsq1(itab.m_icols);
+ for (unsigned k = 0; k < itab.m_icols; k++) {
+ unsigned k2 = rsq1.next();
+ const ICol& icol = *itab.m_icol[k2];
+ const Col& col = icol.m_col;
+ unsigned m = col.m_num;
+ const Val& val = *m_val[m];
+ CHK(val.equal(par, icol) == 0);
+ }
+ Rsq rsq2(tab.m_cols);
+ for (unsigned k = 0; k < tab.m_cols; k++) {
+ unsigned k2 = rsq2.next();
+ const Val& val = *m_val[k2];
+ const Col& col = val.m_col;
+ if (! col.m_pk)
+ CHK(val.setval(par) == 0);
}
m_pending = UpdOp;
return 0;
@@ -1496,11 +2382,35 @@ Row::delrow(Par par)
assert(m_exist);
CHK(con.getNdbOperation(m_tab) == 0);
CHKCON(con.m_op->deleteTuple() == 0, con);
+ Rsq rsq1(tab.m_cols);
for (unsigned k = 0; k < tab.m_cols; k++) {
- const Val& val = *m_val[k];
+ unsigned k2 = rsq1.next();
+ const Val& val = *m_val[k2];
const Col& col = val.m_col;
if (col.m_pk)
- CHK(val.setval(par) == 0);
+ CHK(val.equal(par) == 0);
+ }
+ m_pending = DelOp;
+ return 0;
+}
+
+int
+Row::delrow(Par par, const ITab& itab)
+{
+ Con& con = par.con();
+ const Tab& tab = m_tab;
+ assert(itab.m_type == ITab::UniqueHashIndex && &itab.m_tab == &tab);
+ assert(m_exist);
+ CHK(con.getNdbIndexOperation(itab, tab) == 0);
+ CHKCON(con.m_op->deleteTuple() == 0, con);
+ Rsq rsq1(itab.m_icols);
+ for (unsigned k = 0; k < itab.m_icols; k++) {
+ unsigned k2 = rsq1.next();
+ const ICol& icol = *itab.m_icol[k2];
+ const Col& col = icol.m_col;
+ unsigned m = col.m_num;
+ const Val& val = *m_val[m];
+ CHK(val.equal(par, icol) == 0);
}
m_pending = DelOp;
return 0;
@@ -1513,11 +2423,33 @@ Row::selrow(Par par)
const Tab& tab = m_tab;
CHK(con.getNdbOperation(m_tab) == 0);
CHKCON(con.m_op->readTuple() == 0, con);
+ Rsq rsq1(tab.m_cols);
for (unsigned k = 0; k < tab.m_cols; k++) {
- const Val& val = *m_val[k];
+ unsigned k2 = rsq1.next();
+ const Val& val = *m_val[k2];
const Col& col = val.m_col;
if (col.m_pk)
- CHK(val.setval(par) == 0);
+ CHK(val.equal(par) == 0);
+ }
+ return 0;
+}
+
+int
+Row::selrow(Par par, const ITab& itab)
+{
+ Con& con = par.con();
+ const Tab& tab = m_tab;
+ assert(itab.m_type == ITab::UniqueHashIndex && &itab.m_tab == &tab);
+ CHK(con.getNdbIndexOperation(itab, tab) == 0);
+ CHKCON(con.m_op->readTuple() == 0, con);
+ Rsq rsq1(itab.m_icols);
+ for (unsigned k = 0; k < itab.m_icols; k++) {
+ unsigned k2 = rsq1.next();
+ const ICol& icol = *itab.m_icol[k2];
+ const Col& col = icol.m_col;
+ unsigned m = col.m_num;
+ const Val& val = *m_val[m];
+ CHK(val.equal(par, icol) == 0);
}
return 0;
}
@@ -1527,8 +2459,10 @@ Row::setrow(Par par)
{
Con& con = par.con();
const Tab& tab = m_tab;
+ Rsq rsq1(tab.m_cols);
for (unsigned k = 0; k < tab.m_cols; k++) {
- const Val& val = *m_val[k];
+ unsigned k2 = rsq1.next();
+ const Val& val = *m_val[k2];
const Col& col = val.m_col;
if (! col.m_pk)
CHK(val.setval(par) == 0);
@@ -1538,7 +2472,7 @@ Row::setrow(Par par)
}
int
-Row::cmp(const Row& row2) const
+Row::cmp(Par par, const Row& row2) const
{
const Tab& tab = m_tab;
assert(&tab == &row2.m_tab);
@@ -1546,13 +2480,47 @@ Row::cmp(const Row& row2) const
for (unsigned k = 0; k < tab.m_cols; k++) {
const Val& val = *m_val[k];
const Val& val2 = *row2.m_val[k];
- if ((c = val.cmp(val2)) != 0)
+ if ((c = val.cmp(par, val2)) != 0)
+ break;
+ }
+ return c;
+}
+
+int
+Row::cmp(Par par, const Row& row2, const ITab& itab) const
+{
+ const Tab& tab = m_tab;
+ int c = 0;
+ for (unsigned i = 0; i < itab.m_icols; i++) {
+ const ICol& icol = *itab.m_icol[i];
+ const Col& col = icol.m_col;
+ unsigned k = col.m_num;
+ assert(k < tab.m_cols);
+ const Val& val = *m_val[k];
+ const Val& val2 = *row2.m_val[k];
+ if ((c = val.cmp(par, val2)) != 0)
break;
}
return c;
}
static NdbOut&
+operator<<(NdbOut& out, const Row::Op op)
+{
+ if (op == Row::NoOp)
+ out << "NoOp";
+ else if (op == Row::InsOp)
+ out << "InsOp";
+ else if (op == Row::UpdOp)
+ out << "UpdOp";
+ else if (op == Row::DelOp)
+ out << "DelOp";
+ else
+ out << op;
+ return out;
+}
+
+static NdbOut&
operator<<(NdbOut& out, const Row& row)
{
const Tab& tab = row.m_tab;
@@ -1561,10 +2529,21 @@ operator<<(NdbOut& out, const Row& row)
out << " ";
out << *row.m_val[i];
}
- out << " [exist=" << row.m_exist;
+ out << " exist=" << row.m_exist;
if (row.m_pending)
out << " pending=" << row.m_pending;
- out << "]";
+ if (row.m_dbrow != 0)
+ out << " [dbrow=" << *row.m_dbrow << "]";
+ return out;
+}
+
+static NdbOut&
+operator<<(NdbOut& out, const Row* rowptr)
+{
+ if (rowptr == 0)
+ out << "null";
+ else
+ out << *rowptr;
return out;
}
@@ -1574,38 +2553,47 @@ struct Set {
const Tab& m_tab;
unsigned m_rows;
Row** m_row;
- Row** m_saverow;
+ unsigned* m_rowkey; // maps row number (from 0) in scan to tuple key
Row* m_keyrow;
NdbRecAttr** m_rec;
Set(const Tab& tab, unsigned rows);
~Set();
void reset();
unsigned count() const;
- // row methods
+ // old and new values
bool exist(unsigned i) const;
- Row::Op pending(unsigned i) const;
+ void dbsave(unsigned i);
+ void calc(Par par, unsigned i, unsigned mask = 0);
+ bool pending(unsigned i, unsigned mask) const;
void notpending(unsigned i, ExecType et = Commit);
void notpending(const Lst& lst, ExecType et = Commit);
- void calc(Par par, unsigned i);
+ void dbdiscard(unsigned i);
+ void dbdiscard(const Lst& lst);
+ const Row& dbrow(unsigned i) const;
+ // operations
int insrow(Par par, unsigned i);
int updrow(Par par, unsigned i);
+ int updrow(Par par, const ITab& itab, unsigned i);
int delrow(Par par, unsigned i);
- int selrow(Par par, unsigned i);
+ int delrow(Par par, const ITab& itab, unsigned i);
+ int selrow(Par par, const Row& keyrow);
+ int selrow(Par par, const ITab& itab, const Row& keyrow);
+ // set and get
+ void setkey(Par par, const Row& keyrow);
+ void setkey(Par par, const ITab& itab, const Row& keyrow);
int setrow(Par par, unsigned i);
int getval(Par par);
int getkey(Par par, unsigned* i);
- int putval(unsigned i, bool force);
- // set methods
- int verify(const Set& set2) const;
- void savepoint();
- void commit();
- void rollback();
+ int putval(unsigned i, bool force, unsigned n = ~0);
+ // verify
+ int verify(Par par, const Set& set2) const;
+ int verifyorder(Par par, const ITab& itab, bool descending) const;
// protect structure
NdbMutex* m_mutex;
- void lock() {
+ void lock() const {
NdbMutex_Lock(m_mutex);
}
- void unlock() {
+ void unlock() const {
NdbMutex_Unlock(m_mutex);
}
private:
@@ -1621,7 +2609,11 @@ Set::Set(const Tab& tab, unsigned rows) :
// allocate on need to save space
m_row[i] = 0;
}
- m_saverow = 0;
+ m_rowkey = new unsigned [m_rows];
+ for (unsigned n = 0; n < m_rows; n++) {
+ // initialize to null
+ m_rowkey[n] = ~0;
+ }
m_keyrow = new Row(tab);
m_rec = new NdbRecAttr* [tab.m_cols];
for (unsigned k = 0; k < tab.m_cols; k++) {
@@ -1635,11 +2627,9 @@ Set::~Set()
{
for (unsigned i = 0; i < m_rows; i++) {
delete m_row[i];
- if (m_saverow != 0)
- delete m_saverow[i];
}
delete [] m_row;
- delete [] m_saverow;
+ delete [] m_rowkey;
delete m_keyrow;
delete [] m_rec;
NdbMutex_Destroy(m_mutex);
@@ -1670,6 +2660,8 @@ Set::count() const
return count;
}
+// old and new values
+
bool
Set::exist(unsigned i) const
{
@@ -1679,27 +2671,97 @@ Set::exist(unsigned i) const
return m_row[i]->m_exist;
}
-Row::Op
-Set::pending(unsigned i) const
+void
+Set::dbsave(unsigned i)
{
- assert(i < m_rows);
- if (m_row[i] == 0) // not allocated => not pending
- return Row::NoOp;
- return m_row[i]->m_pending;
+ const Tab& tab = m_tab;
+ assert(i < m_rows && m_row[i] != 0);
+ Row& row = *m_row[i];
+ LL5("dbsave " << i << ": " << row);
+ assert(row.m_exist && ! row.m_pending && row.m_dbrow == 0);
+ // could swap pointers but making copy is safer
+ Row* rowptr = new Row(tab);
+ rowptr->copy(row);
+ row.m_dbrow = rowptr;
}
void
-Set::calc(Par par, unsigned i)
+Set::calc(Par par, unsigned i, unsigned mask)
{
const Tab& tab = m_tab;
if (m_row[i] == 0)
m_row[i] = new Row(tab);
Row& row = *m_row[i];
- // value generation parameters
- par.m_pctrange = 40;
- row.calc(par, i);
+ row.calc(par, i, mask);
+}
+
+bool
+Set::pending(unsigned i, unsigned mask) const
+{
+ assert(i < m_rows);
+ if (m_row[i] == 0) // not allocated => not pending
+ return Row::NoOp;
+ return m_row[i]->m_pending & mask;
+}
+
+void
+Set::notpending(unsigned i, ExecType et)
+{
+ assert(m_row[i] != 0);
+ Row& row = *m_row[i];
+ if (et == Commit) {
+ if (row.m_pending == Row::InsOp)
+ row.m_exist = true;
+ if (row.m_pending == Row::DelOp)
+ row.m_exist = false;
+ } else {
+ if (row.m_pending == Row::InsOp)
+ row.m_exist = false;
+ if (row.m_pending == Row::DelOp)
+ row.m_exist = true;
+ }
+ row.m_pending = Row::NoOp;
+}
+
+void
+Set::notpending(const Lst& lst, ExecType et)
+{
+ for (unsigned j = 0; j < lst.m_cnt; j++) {
+ unsigned i = lst.m_arr[j];
+ notpending(i, et);
+ }
+}
+
+void
+Set::dbdiscard(unsigned i)
+{
+ assert(m_row[i] != 0);
+ Row& row = *m_row[i];
+ LL5("dbdiscard " << i << ": " << row);
+ assert(row.m_dbrow != 0);
+ delete row.m_dbrow;
+ row.m_dbrow = 0;
}
+const Row&
+Set::dbrow(unsigned i) const
+{
+ assert(m_row[i] != 0);
+ Row& row = *m_row[i];
+ return row.dbrow();
+}
+
+void
+Set::dbdiscard(const Lst& lst)
+{
+ for (unsigned j = 0; j < lst.m_cnt; j++) {
+ unsigned i = lst.m_arr[j];
+ dbdiscard(i);
+ }
+}
+
+// operations
+
int
Set::insrow(Par par, unsigned i)
{
@@ -1719,6 +2781,15 @@ Set::updrow(Par par, unsigned i)
}
int
+Set::updrow(Par par, const ITab& itab, unsigned i)
+{
+ assert(m_row[i] != 0);
+ Row& row = *m_row[i];
+ CHK(row.updrow(par, itab) == 0);
+ return 0;
+}
+
+int
Set::delrow(Par par, unsigned i)
{
assert(m_row[i] != 0);
@@ -1728,16 +2799,68 @@ Set::delrow(Par par, unsigned i)
}
int
-Set::selrow(Par par, unsigned i)
+Set::delrow(Par par, const ITab& itab, unsigned i)
+{
+ assert(m_row[i] != 0);
+ Row& row = *m_row[i];
+ CHK(row.delrow(par, itab) == 0);
+ return 0;
+}
+
+int
+Set::selrow(Par par, const Row& keyrow)
{
Con& con = par.con();
- m_keyrow->calc(par, i);
+ const Tab& tab = par.tab();
+ setkey(par, keyrow);
+ LL5("selrow " << tab.m_name << ": keyrow: " << keyrow);
CHK(m_keyrow->selrow(par) == 0);
CHK(getval(par) == 0);
return 0;
}
int
+Set::selrow(Par par, const ITab& itab, const Row& keyrow)
+{
+ Con& con = par.con();
+ setkey(par, itab, keyrow);
+ LL5("selrow " << itab.m_name << ": keyrow: " << keyrow);
+ CHK(m_keyrow->selrow(par, itab) == 0);
+ CHK(getval(par) == 0);
+ return 0;
+}
+
+// set and get
+
+void
+Set::setkey(Par par, const Row& keyrow)
+{
+ const Tab& tab = m_tab;
+ for (unsigned k = 0; k < tab.m_cols; k++) {
+ const Col& col = *tab.m_col[k];
+ if (col.m_pk) {
+ Val& val1 = *m_keyrow->m_val[k];
+ const Val& val2 = *keyrow.dbrow().m_val[k];
+ val1.copy(val2);
+ }
+ }
+}
+
+void
+Set::setkey(Par par, const ITab& itab, const Row& keyrow)
+{
+ const Tab& tab = m_tab;
+ for (unsigned k = 0; k < itab.m_icols; k++) {
+ const ICol& icol = *itab.m_icol[k];
+ const Col& col = icol.m_col;
+ unsigned m = col.m_num;
+ Val& val1 = *m_keyrow->m_val[m];
+ const Val& val2 = *keyrow.dbrow().m_val[m];
+ val1.copy(val2);
+ }
+}
+
+int
Set::setrow(Par par, unsigned i)
{
Con& con = par.con();
@@ -1751,8 +2874,10 @@ Set::getval(Par par)
{
Con& con = par.con();
const Tab& tab = m_tab;
+ Rsq rsq1(tab.m_cols);
for (unsigned k = 0; k < tab.m_cols; k++) {
- CHK(con.getValue(k, m_rec[k]) == 0);
+ unsigned k2 = rsq1.next();
+ CHK(con.getValue(k2, m_rec[k2]) == 0);
}
return 0;
}
@@ -1760,16 +2885,18 @@ Set::getval(Par par)
int
Set::getkey(Par par, unsigned* i)
{
- assert(m_rec[0] != 0);
- const char* aRef0 = m_rec[0]->aRef();
- Uint32 key = *(const Uint32*)aRef0;
+ const Tab& tab = m_tab;
+ unsigned k = tab.m_keycol;
+ assert(m_rec[k] != 0);
+ const char* aRef = m_rec[k]->aRef();
+ Uint32 key = *(const Uint32*)aRef;
CHK(key < m_rows);
*i = key;
return 0;
}
int
-Set::putval(unsigned i, bool force)
+Set::putval(unsigned i, bool force, unsigned n)
{
const Tab& tab = m_tab;
if (m_row[i] == 0)
@@ -1790,82 +2917,53 @@ Set::putval(unsigned i, bool force)
}
if (! row.m_exist)
row.m_exist = true;
+ if (n != ~0)
+ m_rowkey[n] = i;
return 0;
}
-void
-Set::notpending(unsigned i, ExecType et)
-{
- assert(m_row[i] != 0);
- Row& row = *m_row[i];
- if (et == Commit) {
- if (row.m_pending == Row::InsOp)
- row.m_exist = true;
- if (row.m_pending == Row::DelOp)
- row.m_exist = false;
- } else {
- if (row.m_pending == Row::InsOp)
- row.m_exist = false;
- if (row.m_pending == Row::DelOp)
- row.m_exist = true;
- }
- row.m_pending = Row::NoOp;
-}
-
-void
-Set::notpending(const Lst& lst, ExecType et)
-{
- for (unsigned j = 0; j < lst.m_cnt; j++) {
- unsigned i = lst.m_arr[j];
- notpending(i, et);
- }
-}
-
int
-Set::verify(const Set& set2) const
+Set::verify(Par par, const Set& set2) const
{
- const Tab& tab = m_tab;
- assert(&tab == &set2.m_tab && m_rows == set2.m_rows);
+ assert(&m_tab == &set2.m_tab && m_rows == set2.m_rows);
+ LL4("verify set1 count=" << count() << " vs set2 count=" << set2.count());
for (unsigned i = 0; i < m_rows; i++) {
- CHK(exist(i) == set2.exist(i));
- if (! exist(i))
- continue;
- Row& row = *m_row[i];
- Row& row2 = *set2.m_row[i];
- CHK(row.verify(row2) == 0);
+ bool ok = true;
+ if (exist(i) != set2.exist(i)) {
+ ok = false;
+ } else if (exist(i)) {
+ if (dbrow(i).verify(par, set2.dbrow(i)) != 0)
+ ok = false;
+ }
+ if (! ok) {
+ LL1("verify failed: key=" << i << " row1=" << m_row[i] << " row2=" << set2.m_row[i]);
+ CHK(0 == 1);
+ }
}
return 0;
}
-void
-Set::savepoint()
+int
+Set::verifyorder(Par par, const ITab& itab, bool descending) const
{
const Tab& tab = m_tab;
- assert(m_saverow == 0);
- m_saverow = new Row* [m_rows];
- for (unsigned i = 0; i < m_rows; i++) {
- if (m_row[i] == 0)
- m_saverow[i] = 0;
- else {
- m_saverow[i] = new Row(tab);
- m_saverow[i]->copy(*m_row[i]);
- }
+ for (unsigned n = 0; n < m_rows; n++) {
+ unsigned i2 = m_rowkey[n];
+ if (i2 == ~0)
+ break;
+ if (n == 0)
+ continue;
+ unsigned i1 = m_rowkey[n - 1];
+ assert(i1 < m_rows && i2 < m_rows);
+ const Row& row1 = *m_row[i1];
+ const Row& row2 = *m_row[i2];
+ assert(row1.m_exist && row2.m_exist);
+ if (! descending)
+ CHK(row1.cmp(par, row2, itab) <= 0);
+ else
+ CHK(row1.cmp(par, row2, itab) >= 0);
}
-}
-
-void
-Set::commit()
-{
- delete [] m_saverow;
- m_saverow = 0;
-}
-
-void
-Set::rollback()
-{
- assert(m_saverow != 0);
- m_row = m_saverow;
- m_saverow = 0;
+ return 0;
}
static NdbOut&
@@ -1887,6 +2985,7 @@ struct BVal : public Val {
int m_type;
BVal(const ICol& icol);
int setbnd(Par par) const;
+ int setflt(Par par) const;
};
BVal::BVal(const ICol& icol) :
@@ -1906,16 +3005,37 @@ BVal::setbnd(Par par) const
return 0;
}
+int
+BVal::setflt(Par par) const
+{
+ static unsigned index_bound_to_filter_bound[5] = {
+ NdbScanFilter::COND_GE,
+ NdbScanFilter::COND_GT,
+ NdbScanFilter::COND_LE,
+ NdbScanFilter::COND_LT,
+ NdbScanFilter::COND_EQ
+ };
+ Con& con = par.con();
+ assert(g_compare_null || ! m_null);
+ const char* addr = ! m_null ? (const char*)dataaddr() : 0;
+ const ICol& icol = m_icol;
+ const Col& col = icol.m_col;
+ unsigned length = col.m_bytesize;
+ unsigned cond = index_bound_to_filter_bound[m_type];
+ CHK(con.setFilter(col.m_num, cond, addr, length) == 0);
+ return 0;
+}
+
static NdbOut&
operator<<(NdbOut& out, const BVal& bval)
{
const ICol& icol = bval.m_icol;
const Col& col = icol.m_col;
const Val& val = bval;
- out << "type " << bval.m_type;
- out << " icol " << icol.m_num;
- out << " col " << col.m_name << "(" << col.m_num << ")";
- out << " value " << val;
+ out << "type=" << bval.m_type;
+ out << " icol=" << icol.m_num;
+ out << " col=" << col.m_num << "," << col.m_name;
+ out << " value=" << val;
return out;
}
@@ -1933,7 +3053,8 @@ struct BSet {
void calc(Par par);
void calcpk(Par par, unsigned i);
int setbnd(Par par) const;
- void filter(const Set& set, Set& set2) const;
+ int setflt(Par par) const;
+ void filter(Par par, const Set& set, Set& set2) const;
};
BSet::BSet(const Tab& tab, const ITab& itab, unsigned rows) :
@@ -1967,12 +3088,15 @@ void
BSet::calc(Par par)
{
const ITab& itab = m_itab;
+ par.m_pctrange = par.m_pctbrange;
reset();
for (unsigned k = 0; k < itab.m_icols; k++) {
- const ICol& icol = itab.m_icol[k];
+ const ICol& icol = *itab.m_icol[k];
const Col& col = icol.m_col;
for (unsigned i = 0; i <= 1; i++) {
- if (urandom(10) == 0)
+ if (m_bvals == 0 && urandom(100) == 0)
+ return;
+ if (m_bvals != 0 && urandom(3) == 0)
return;
assert(m_bvals < m_alloc);
BVal& bval = *new BVal(icol);
@@ -1991,17 +3115,19 @@ BSet::calc(Par par)
bval.m_type = 4;
if (k + 1 < itab.m_icols)
bval.m_type = 4;
- // value generation parammeters
if (! g_compare_null)
par.m_pctnull = 0;
- par.m_pctrange = 50; // bit higher
+ if (bval.m_type == 0 || bval.m_type == 1)
+ par.m_bdir = -1;
+ if (bval.m_type == 2 || bval.m_type == 3)
+ par.m_bdir = +1;
do {
- bval.calc(par, 0);
+ bval.calcnokey(par);
if (i == 1) {
assert(m_bvals >= 2);
const BVal& bv1 = *m_bval[m_bvals - 2];
const BVal& bv2 = *m_bval[m_bvals - 1];
- if (bv1.cmp(bv2) > 0 && urandom(100) != 0)
+ if (bv1.cmp(par, bv2) > 0 && urandom(100) != 0)
continue;
}
} while (0);
@@ -2018,7 +3144,7 @@ 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 ICol& icol = *itab.m_icol[k];
const Col& col = icol.m_col;
assert(col.m_pk);
assert(m_bvals < m_alloc);
@@ -2033,26 +3159,48 @@ int
BSet::setbnd(Par par) const
{
if (m_bvals != 0) {
- unsigned p1 = urandom(m_bvals);
- unsigned p2 = 10009; // prime
- // random order
+ Rsq rsq1(m_bvals);
for (unsigned j = 0; j < m_bvals; j++) {
- unsigned k = p1 + p2 * j;
- const BVal& bval = *m_bval[k % m_bvals];
+ unsigned j2 = rsq1.next();
+ const BVal& bval = *m_bval[j2];
CHK(bval.setbnd(par) == 0);
}
// duplicate
if (urandom(5) == 0) {
- unsigned k = urandom(m_bvals);
- const BVal& bval = *m_bval[k];
+ unsigned j3 = urandom(m_bvals);
+ const BVal& bval = *m_bval[j3];
CHK(bval.setbnd(par) == 0);
}
}
return 0;
}
+int
+BSet::setflt(Par par) const
+{
+ Con& con = par.con();
+ CHK(con.getNdbScanFilter() == 0);
+ CHK(con.beginFilter(NdbScanFilter::AND) == 0);
+ if (m_bvals != 0) {
+ Rsq rsq1(m_bvals);
+ for (unsigned j = 0; j < m_bvals; j++) {
+ unsigned j2 = rsq1.next();
+ const BVal& bval = *m_bval[j2];
+ CHK(bval.setflt(par) == 0);
+ }
+ // duplicate
+ if (urandom(5) == 0) {
+ unsigned j3 = urandom(m_bvals);
+ const BVal& bval = *m_bval[j3];
+ CHK(bval.setflt(par) == 0);
+ }
+ }
+ CHK(con.endFilter() == 0);
+ return 0;
+}
+
void
-BSet::filter(const Set& set, Set& set2) const
+BSet::filter(Par par, const Set& set, Set& set2) const
{
const Tab& tab = m_tab;
const ITab& itab = m_itab;
@@ -2061,11 +3209,13 @@ BSet::filter(const Set& set, Set& set2) const
for (unsigned i = 0; i < set.m_rows; i++) {
if (! set.exist(i))
continue;
- const Row& row = *set.m_row[i];
+ set.lock();
+ const Row& row = set.dbrow(i);
+ set.unlock();
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 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) {
@@ -2082,7 +3232,8 @@ BSet::filter(const Set& set, Set& set2) const
const ICol& icol = bval.m_icol;
const Col& col = icol.m_col;
const Val& val = *row.m_val[col.m_num];
- int ret = bval.cmp(val);
+ int ret = bval.cmp(par, val);
+ LL5("cmp: ret=" << ret << " " << bval << " vs " << val);
if (bval.m_type == 0)
ok2 = (ret <= 0);
else if (bval.m_type == 1)
@@ -2106,7 +3257,6 @@ BSet::filter(const Set& set, Set& set2) const
Row& row2 = *set2.m_row[i];
assert(! row2.m_exist);
row2.copy(row);
- row2.m_exist = true;
}
}
@@ -2115,9 +3265,8 @@ operator<<(NdbOut& out, const BSet& bset)
{
out << "bounds=" << bset.m_bvals;
for (unsigned j = 0; j < bset.m_bvals; j++) {
- out << endl;
const BVal& bval = *bset.m_bval[j];
- out << "bound " << j << ": " << bval;
+ out << " [bound " << j << ": " << bval << "]";
}
return out;
}
@@ -2128,15 +3277,16 @@ static int
pkinsert(Par par)
{
Con& con = par.con();
+ const Tab& tab = par.tab();
Set& set = par.set();
- LL3("pkinsert");
+ LL3("pkinsert " << tab.m_name);
CHK(con.startTransaction() == 0);
Lst lst;
for (unsigned j = 0; j < par.m_rows; j++) {
unsigned j2 = ! par.m_randomkey ? j : urandom(par.m_rows);
unsigned i = thrrow(par, j2);
set.lock();
- if (set.exist(i) || set.pending(i)) {
+ if (set.exist(i) || set.pending(i, Row::AnyOp)) {
set.unlock();
continue;
}
@@ -2152,7 +3302,7 @@ pkinsert(Par par)
CHK(con.execute(et, deadlock, nospace) == 0);
con.closeTransaction();
if (deadlock) {
- LL1("pkinsert: stop on deadlock");
+ LL1("pkinsert: stop on deadlock [at 1]");
return 0;
}
if (nospace) {
@@ -2173,7 +3323,7 @@ pkinsert(Par par)
CHK(con.execute(et, deadlock, nospace) == 0);
con.closeTransaction();
if (deadlock) {
- LL1("pkinsert: stop on deadlock");
+ LL1("pkinsert: stop on deadlock [at 2]");
return 0;
}
if (nospace) {
@@ -2187,14 +3337,15 @@ pkinsert(Par par)
}
con.closeTransaction();
return 0;
-};
+}
static int
pkupdate(Par par)
{
Con& con = par.con();
+ const Tab& tab = par.tab();
Set& set = par.set();
- LL3("pkupdate");
+ LL3("pkupdate " << tab.m_name);
CHK(con.startTransaction() == 0);
Lst lst;
bool deadlock = false;
@@ -2203,10 +3354,11 @@ pkupdate(Par par)
unsigned j2 = ! par.m_randomkey ? j : urandom(par.m_rows);
unsigned i = thrrow(par, j2);
set.lock();
- if (! set.exist(i) || set.pending(i)) {
+ if (! set.exist(i) || set.pending(i, Row::AnyOp)) {
set.unlock();
continue;
}
+ set.dbsave(i);
set.calc(par, i);
CHK(set.updrow(par, i) == 0);
set.unlock();
@@ -2218,16 +3370,17 @@ pkupdate(Par par)
ExecType et = randompct(par.m_abortpct) ? Rollback : Commit;
CHK(con.execute(et, deadlock, nospace) == 0);
if (deadlock) {
- LL1("pkupdate: stop on deadlock");
+ LL1("pkupdate: stop on deadlock [at 1]");
break;
}
if (nospace) {
- LL1("pkupdate: cnt=" << j << " stop on nospace");
+ LL1("pkupdate: cnt=" << j << " stop on nospace [at 1]");
break;
}
con.closeTransaction();
set.lock();
set.notpending(lst, et);
+ set.dbdiscard(lst);
set.unlock();
lst.reset();
CHK(con.startTransaction() == 0);
@@ -2239,25 +3392,27 @@ pkupdate(Par par)
ExecType et = randompct(par.m_abortpct) ? Rollback : Commit;
CHK(con.execute(et, deadlock, nospace) == 0);
if (deadlock) {
- LL1("pkupdate: stop on deadlock");
+ LL1("pkupdate: stop on deadlock [at 2]");
} else if (nospace) {
- LL1("pkupdate: end: stop on nospace");
+ LL1("pkupdate: end: stop on nospace [at 2]");
} else {
set.lock();
set.notpending(lst, et);
+ set.dbdiscard(lst);
set.unlock();
}
}
con.closeTransaction();
return 0;
-};
+}
static int
pkdelete(Par par)
{
Con& con = par.con();
+ const Tab& tab = par.tab();
Set& set = par.set();
- LL3("pkdelete");
+ LL3("pkdelete " << tab.m_name);
CHK(con.startTransaction() == 0);
Lst lst;
bool deadlock = false;
@@ -2266,7 +3421,7 @@ pkdelete(Par par)
unsigned j2 = ! par.m_randomkey ? j : urandom(par.m_rows);
unsigned i = thrrow(par, j2);
set.lock();
- if (! set.exist(i) || set.pending(i)) {
+ if (! set.exist(i) || set.pending(i, Row::AnyOp)) {
set.unlock();
continue;
}
@@ -2280,7 +3435,7 @@ pkdelete(Par par)
ExecType et = randompct(par.m_abortpct) ? Rollback : Commit;
CHK(con.execute(et, deadlock, nospace) == 0);
if (deadlock) {
- LL1("pkdelete: stop on deadlock");
+ LL1("pkdelete: stop on deadlock [at 1]");
break;
}
con.closeTransaction();
@@ -2297,7 +3452,7 @@ pkdelete(Par par)
ExecType et = randompct(par.m_abortpct) ? Rollback : Commit;
CHK(con.execute(et, deadlock, nospace) == 0);
if (deadlock) {
- LL1("pkdelete: stop on deadlock");
+ LL1("pkdelete: stop on deadlock [at 2]");
} else {
set.lock();
set.notpending(lst, et);
@@ -2306,7 +3461,7 @@ pkdelete(Par par)
}
con.closeTransaction();
return 0;
-};
+}
static int
pkread(Par par)
@@ -2314,19 +3469,19 @@ pkread(Par par)
Con& con = par.con();
const Tab& tab = par.tab();
Set& set = par.set();
- LL3((par.m_verify ? "pkverify " : "pkread ") << tab.m_name);
+ LL3("pkread " << tab.m_name << " verify=" << par.m_verify);
// expected
const Set& set1 = set;
Set set2(tab, set.m_rows);
for (unsigned i = 0; i < set.m_rows; i++) {
set.lock();
- if (! set.exist(i) || set.pending(i)) {
+ if (! set.exist(i)) {
set.unlock();
continue;
}
set.unlock();
CHK(con.startTransaction() == 0);
- CHK(set2.selrow(par, i) == 0);
+ CHK(set2.selrow(par, *set1.m_row[i]) == 0);
CHK(con.execute(Commit) == 0);
unsigned i2 = (unsigned)-1;
CHK(set2.getkey(par, &i2) == 0 && i == i2);
@@ -2335,7 +3490,7 @@ pkread(Par par)
con.closeTransaction();
}
if (par.m_verify)
- CHK(set1.verify(set2) == 0);
+ CHK(set1.verify(par, set2) == 0);
return 0;
}
@@ -2364,6 +3519,148 @@ pkreadfast(Par par, unsigned count)
return 0;
}
+// hash index operations
+
+static int
+hashindexupdate(Par par, const ITab& itab)
+{
+ Con& con = par.con();
+ Set& set = par.set();
+ LL3("hashindexupdate " << itab.m_name);
+ CHK(con.startTransaction() == 0);
+ Lst lst;
+ bool deadlock = false;
+ bool nospace = false;
+ for (unsigned j = 0; j < par.m_rows; j++) {
+ unsigned j2 = ! par.m_randomkey ? j : urandom(par.m_rows);
+ unsigned i = thrrow(par, j2);
+ set.lock();
+ if (! set.exist(i) || set.pending(i, Row::AnyOp)) {
+ set.unlock();
+ continue;
+ }
+ set.dbsave(i);
+ // index key columns are not re-calculated
+ set.calc(par, i, itab.m_colmask);
+ CHK(set.updrow(par, itab, i) == 0);
+ set.unlock();
+ LL4("hashindexupdate " << i << ": " << *set.m_row[i]);
+ lst.push(i);
+ if (lst.cnt() == par.m_batch) {
+ deadlock = par.m_deadlock;
+ CHK(con.execute(Commit, deadlock, nospace) == 0);
+ if (deadlock) {
+ LL1("hashindexupdate: stop on deadlock [at 1]");
+ break;
+ }
+ con.closeTransaction();
+ set.lock();
+ set.notpending(lst);
+ set.dbdiscard(lst);
+ set.unlock();
+ lst.reset();
+ CHK(con.startTransaction() == 0);
+ }
+ }
+ if (! deadlock && lst.cnt() != 0) {
+ deadlock = par.m_deadlock;
+ CHK(con.execute(Commit, deadlock, nospace) == 0);
+ if (deadlock) {
+ LL1("hashindexupdate: stop on deadlock [at 2]");
+ } else {
+ set.lock();
+ set.notpending(lst);
+ set.dbdiscard(lst);
+ set.unlock();
+ }
+ }
+ con.closeTransaction();
+ return 0;
+}
+
+static int
+hashindexdelete(Par par, const ITab& itab)
+{
+ Con& con = par.con();
+ Set& set = par.set();
+ LL3("hashindexdelete " << itab.m_name);
+ CHK(con.startTransaction() == 0);
+ Lst lst;
+ bool deadlock = false;
+ bool nospace = false;
+ for (unsigned j = 0; j < par.m_rows; j++) {
+ unsigned j2 = ! par.m_randomkey ? j : urandom(par.m_rows);
+ unsigned i = thrrow(par, j2);
+ set.lock();
+ if (! set.exist(i) || set.pending(i, Row::AnyOp)) {
+ set.unlock();
+ continue;
+ }
+ CHK(set.delrow(par, itab, i) == 0);
+ set.unlock();
+ LL4("hashindexdelete " << i << ": " << *set.m_row[i]);
+ lst.push(i);
+ if (lst.cnt() == par.m_batch) {
+ deadlock = par.m_deadlock;
+ CHK(con.execute(Commit, deadlock, nospace) == 0);
+ if (deadlock) {
+ LL1("hashindexdelete: stop on deadlock [at 1]");
+ break;
+ }
+ con.closeTransaction();
+ set.lock();
+ set.notpending(lst);
+ set.unlock();
+ lst.reset();
+ CHK(con.startTransaction() == 0);
+ }
+ }
+ if (! deadlock && lst.cnt() != 0) {
+ deadlock = par.m_deadlock;
+ CHK(con.execute(Commit, deadlock, nospace) == 0);
+ if (deadlock) {
+ LL1("hashindexdelete: stop on deadlock [at 2]");
+ } else {
+ set.lock();
+ set.notpending(lst);
+ set.unlock();
+ }
+ }
+ con.closeTransaction();
+ return 0;
+}
+
+static int
+hashindexread(Par par, const ITab& itab)
+{
+ Con& con = par.con();
+ const Tab& tab = par.tab();
+ Set& set = par.set();
+ LL3("hashindexread " << itab.m_name << " verify=" << par.m_verify);
+ // expected
+ const Set& set1 = set;
+ Set set2(tab, set.m_rows);
+ for (unsigned i = 0; i < set.m_rows; i++) {
+ set.lock();
+ if (! set.exist(i)) {
+ set.unlock();
+ continue;
+ }
+ set.unlock();
+ CHK(con.startTransaction() == 0);
+ CHK(set2.selrow(par, itab, *set1.m_row[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.count() << ": " << *set2.m_row[i]);
+ con.closeTransaction();
+ }
+ if (par.m_verify)
+ CHK(set1.verify(par, set2) == 0);
+ return 0;
+}
+
// scan read
static int
@@ -2374,26 +3671,35 @@ scanreadtable(Par par)
const Set& set = par.set();
// expected
const Set& set1 = set;
- LL3((par.m_verify ? "scanverify " : "scanread ") << tab.m_name);
+ LL3("scanread " << tab.m_name << " lockmode=" << par.m_lockmode << " tupscan=" << par.m_tupscan << " expect=" << set1.count() << " verify=" << par.m_verify);
Set set2(tab, set.m_rows);
CHK(con.startTransaction() == 0);
CHK(con.getNdbScanOperation(tab) == 0);
- CHK(con.openScanRead(par.m_scanbat, par.m_scanpar) == 0);
+ CHK(con.readTuples(par) == 0);
set2.getval(par);
CHK(con.executeScan() == 0);
+ unsigned n = 0;
+ bool deadlock = false;
while (1) {
int ret;
- CHK((ret = con.nextScanResult(true)) == 0 || ret == 1);
+ deadlock = par.m_deadlock;
+ CHK((ret = con.nextScanResult(true, deadlock)) == 0 || ret == 1);
if (ret == 1)
break;
+ if (deadlock) {
+ LL1("scanreadtable: stop on deadlock");
+ break;
+ }
unsigned i = (unsigned)-1;
CHK(set2.getkey(par, &i) == 0);
- CHK(set2.putval(i, false) == 0);
- LL4("row " << set2.count() << ": " << *set2.m_row[i]);
+ CHK(set2.putval(i, false, n) == 0);
+ LL4("row " << n << ": " << *set2.m_row[i]);
+ n++;
}
con.closeTransaction();
if (par.m_verify)
- CHK(set1.verify(set2) == 0);
+ CHK(set1.verify(par, set2) == 0);
+ LL3("scanread " << tab.m_name << " done rows=" << n);
return 0;
}
@@ -2406,7 +3712,7 @@ scanreadtablefast(Par par, unsigned countcheck)
LL3("scanfast " << tab.m_name);
CHK(con.startTransaction() == 0);
CHK(con.getNdbScanOperation(tab) == 0);
- CHK(con.openScanRead(par.m_scanbat, par.m_scanpar) == 0);
+ CHK(con.readTuples(par) == 0);
// get 1st column
NdbRecAttr* rec;
CHK(con.getValue((Uint32)0, rec) == 0);
@@ -2425,37 +3731,60 @@ scanreadtablefast(Par par, unsigned countcheck)
}
static int
-scanreadindex(Par par, const ITab& itab, const BSet& bset)
+scanreadindex(Par par, const ITab& itab, BSet& bset, bool calc)
{
Con& con = par.con();
const Tab& tab = par.tab();
const Set& set = par.set();
- // expected
Set set1(tab, set.m_rows);
- bset.filter(set, set1);
- LL3((par.m_verify ? "scanverify " : "scanread ") << itab.m_name << " bounds=" << bset.m_bvals);
- LL4(bset);
+ if (calc) {
+ while (true) {
+ bset.calc(par);
+ bset.filter(par, set, set1);
+ unsigned n = set1.count();
+ // prefer proper subset
+ if (0 < n && n < set.m_rows)
+ break;
+ if (urandom(3) == 0)
+ break;
+ set1.reset();
+ }
+ } else {
+ bset.filter(par, set, set1);
+ }
+ LL3("scanread " << itab.m_name << " " << bset << " lockmode=" << par.m_lockmode << " expect=" << set1.count() << " verify=" << par.m_verify << " ordered=" << par.m_ordered << " descending=" << par.m_descending);
Set set2(tab, set.m_rows);
CHK(con.startTransaction() == 0);
- CHK(con.getNdbScanOperation(itab, tab) == 0);
- CHK(con.openScanRead(par.m_scanbat, par.m_scanpar) == 0);
+ CHK(con.getNdbIndexScanOperation(itab, tab) == 0);
+ CHK(con.readIndexTuples(par) == 0);
CHK(bset.setbnd(par) == 0);
set2.getval(par);
CHK(con.executeScan() == 0);
+ unsigned n = 0;
+ bool deadlock = false;
while (1) {
int ret;
- CHK((ret = con.nextScanResult(true)) == 0 || ret == 1);
+ deadlock = par.m_deadlock;
+ CHK((ret = con.nextScanResult(true, deadlock)) == 0 || ret == 1);
if (ret == 1)
break;
+ if (deadlock) {
+ LL1("scanreadindex: stop on deadlock");
+ 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.count() << ": " << *set2.m_row[i]);
+ CHK(set2.putval(i, par.m_dups, n) == 0);
+ LL4("key " << i << " row " << n << ": " << *set2.m_row[i]);
+ n++;
}
con.closeTransaction();
- if (par.m_verify)
- CHK(set1.verify(set2) == 0);
+ if (par.m_verify) {
+ CHK(set1.verify(par, set2) == 0);
+ if (par.m_ordered)
+ CHK(set2.verifyorder(par, itab, par.m_descending) == 0);
+ }
+ LL3("scanread " << itab.m_name << " done rows=" << n);
return 0;
}
@@ -2465,11 +3794,11 @@ scanreadindexfast(Par par, const ITab& itab, const BSet& bset, unsigned countche
Con& con = par.con();
const Tab& tab = par.tab();
const Set& set = par.set();
- LL3("scanfast " << itab.m_name << " bounds=" << bset.m_bvals);
+ LL3("scanfast " << itab.m_name << " " << bset);
LL4(bset);
CHK(con.startTransaction() == 0);
- CHK(con.getNdbScanOperation(itab, tab) == 0);
- CHK(con.openScanRead(par.m_scanbat, par.m_scanpar) == 0);
+ CHK(con.getNdbIndexScanOperation(itab, tab) == 0);
+ CHK(con.readIndexTuples(par) == 0);
CHK(bset.setbnd(par) == 0);
// get 1st column
NdbRecAttr* rec;
@@ -2489,13 +3818,71 @@ scanreadindexfast(Par par, const ITab& itab, const BSet& bset, unsigned countche
}
static int
+scanreadfilter(Par par, const ITab& itab, BSet& bset, bool calc)
+{
+ Con& con = par.con();
+ const Tab& tab = par.tab();
+ const Set& set = par.set();
+ Set set1(tab, set.m_rows);
+ if (calc) {
+ while (true) {
+ bset.calc(par);
+ bset.filter(par, set, set1);
+ unsigned n = set1.count();
+ // prefer proper subset
+ if (0 < n && n < set.m_rows)
+ break;
+ if (urandom(3) == 0)
+ break;
+ set1.reset();
+ }
+ } else {
+ bset.filter(par, set, set1);
+ }
+ LL3("scanfilter " << itab.m_name << " " << bset << " lockmode=" << par.m_lockmode << " expect=" << set1.count() << " verify=" << par.m_verify);
+ Set set2(tab, set.m_rows);
+ CHK(con.startTransaction() == 0);
+ CHK(con.getNdbScanOperation(tab) == 0);
+ CHK(con.readTuples(par) == 0);
+ CHK(bset.setflt(par) == 0);
+ set2.getval(par);
+ CHK(con.executeScan() == 0);
+ unsigned n = 0;
+ bool deadlock = false;
+ while (1) {
+ int ret;
+ deadlock = par.m_deadlock;
+ CHK((ret = con.nextScanResult(true, deadlock)) == 0 || ret == 1);
+ if (ret == 1)
+ break;
+ if (deadlock) {
+ LL1("scanfilter: stop on deadlock");
+ break;
+ }
+ unsigned i = (unsigned)-1;
+ CHK(set2.getkey(par, &i) == 0);
+ CHK(set2.putval(i, par.m_dups, n) == 0);
+ LL4("key " << i << " row " << n << ": " << *set2.m_row[i]);
+ n++;
+ }
+ con.closeTransaction();
+ if (par.m_verify) {
+ CHK(set1.verify(par, set2) == 0);
+ }
+ LL3("scanfilter " << itab.m_name << " done rows=" << n);
+ return 0;
+}
+
+static int
scanreadindex(Par par, const ITab& itab)
{
const Tab& tab = par.tab();
for (unsigned i = 0; i < par.m_subsubloop; i++) {
- BSet bset(tab, itab, par.m_rows);
- bset.calc(par);
- CHK(scanreadindex(par, itab, bset) == 0);
+ if (itab.m_type == ITab::OrderedIndex) {
+ BSet bset(tab, itab, par.m_rows);
+ CHK(scanreadfilter(par, itab, bset, true) == 0);
+ CHK(scanreadindex(par, itab, bset, true) == 0);
+ }
}
return 0;
}
@@ -2505,10 +3892,14 @@ scanreadindex(Par par)
{
const Tab& tab = par.tab();
for (unsigned i = 0; i < tab.m_itabs; i++) {
- if (! useindex(i))
+ if (tab.m_itab[i] == 0)
continue;
- const ITab& itab = tab.m_itab[i];
- CHK(scanreadindex(par, itab) == 0);
+ const ITab& itab = *tab.m_itab[i];
+ if (itab.m_type == ITab::OrderedIndex) {
+ CHK(scanreadindex(par, itab) == 0);
+ } else {
+ CHK(hashindexread(par, itab) == 0);
+ }
}
return 0;
}
@@ -2516,8 +3907,7 @@ scanreadindex(Par par)
static int
scanreadall(Par par)
{
- if (par.m_no < 11)
- CHK(scanreadtable(par) == 0);
+ CHK(scanreadtable(par) == 0);
CHK(scanreadindex(par) == 0);
return 0;
}
@@ -2537,7 +3927,7 @@ static int
timescanpkindex(Par par)
{
const Tab& tab = par.tab();
- const ITab& itab = tab.m_itab[0]; // 1st index is on PK
+ 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);
@@ -2561,7 +3951,7 @@ static int
timepkreadindex(Par par)
{
const Tab& tab = par.tab();
- const ITab& itab = tab.m_itab[0]; // 1st index is on PK
+ 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)
@@ -2586,9 +3976,10 @@ scanupdatetable(Par par)
Set& set = par.set();
LL3("scan update " << tab.m_name);
Set set2(tab, set.m_rows);
+ par.m_lockmode = NdbOperation::LM_Exclusive;
CHK(con.startTransaction() == 0);
CHK(con.getNdbScanOperation(tab) == 0);
- CHK(con.openScanExclusive(par.m_scanbat, par.m_scanpar) == 0);
+ CHK(con.readTuples(par) == 0);
set2.getval(par);
CHK(con.executeScan() == 0);
unsigned count = 0;
@@ -2598,6 +3989,7 @@ scanupdatetable(Par par)
CHK(con2.startTransaction() == 0);
Lst lst;
bool deadlock = false;
+ bool nospace = false;
while (1) {
int ret;
deadlock = par.m_deadlock;
@@ -2605,7 +3997,7 @@ scanupdatetable(Par par)
if (ret == 1)
break;
if (deadlock) {
- LL1("scanupdatetable: stop on deadlock");
+ LL1("scanupdatetable: stop on deadlock [at 1]");
break;
}
if (par.m_scanstop != 0 && urandom(par.m_scanstop) == 0) {
@@ -2617,13 +4009,14 @@ scanupdatetable(Par par)
CHK(set2.getkey(par, &i) == 0);
const Row& row = *set.m_row[i];
set.lock();
- if (! set.exist(i) || set.pending(i)) {
+ if (! set.exist(i) || set.pending(i, Row::AnyOp)) {
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.dbsave(i);
set.calc(par, i);
CHKTRY(set.setrow(par2, i) == 0, set.unlock());
LL4("scan update " << tab.m_name << ": " << row);
@@ -2631,10 +4024,16 @@ scanupdatetable(Par par)
}
set.unlock();
if (lst.cnt() == par.m_batch) {
- CHK(con2.execute(Commit) == 0);
+ deadlock = par.m_deadlock;
+ CHK(con2.execute(Commit, deadlock, nospace) == 0);
+ if (deadlock) {
+ LL1("scanupdatetable: stop on deadlock [at 2]");
+ goto out;
+ }
con2.closeTransaction();
set.lock();
set.notpending(lst);
+ set.dbdiscard(lst);
set.unlock();
count += lst.cnt();
lst.reset();
@@ -2642,10 +4041,16 @@ scanupdatetable(Par par)
}
CHK((ret = con.nextScanResult(false)) == 0 || ret == 1 || ret == 2);
if (ret == 2 && lst.cnt() != 0) {
- CHK(con2.execute(Commit) == 0);
+ deadlock = par.m_deadlock;
+ CHK(con2.execute(Commit, deadlock, nospace) == 0);
+ if (deadlock) {
+ LL1("scanupdatetable: stop on deadlock [at 3]");
+ goto out;
+ }
con2.closeTransaction();
set.lock();
set.notpending(lst);
+ set.dbdiscard(lst);
set.unlock();
count += lst.cnt();
lst.reset();
@@ -2655,6 +4060,7 @@ scanupdatetable(Par par)
if (ret == 1)
break;
}
+out:
con2.closeTransaction();
LL3("scan update " << tab.m_name << " rows updated=" << count);
con.closeTransaction();
@@ -2669,9 +4075,10 @@ scanupdateindex(Par par, const ITab& itab, const BSet& bset)
Set& set = par.set();
LL3("scan update " << itab.m_name);
Set set2(tab, set.m_rows);
+ par.m_lockmode = NdbOperation::LM_Exclusive;
CHK(con.startTransaction() == 0);
- CHK(con.getNdbScanOperation(itab, tab) == 0);
- CHK(con.openScanExclusive(par.m_scanbat, par.m_scanpar) == 0);
+ CHK(con.getNdbIndexScanOperation(itab, tab) == 0);
+ CHK(con.readTuples(par) == 0);
CHK(bset.setbnd(par) == 0);
set2.getval(par);
CHK(con.executeScan() == 0);
@@ -2682,6 +4089,7 @@ scanupdateindex(Par par, const ITab& itab, const BSet& bset)
CHK(con2.startTransaction() == 0);
Lst lst;
bool deadlock = false;
+ bool nospace = false;
while (1) {
int ret;
deadlock = par.m_deadlock;
@@ -2689,7 +4097,7 @@ scanupdateindex(Par par, const ITab& itab, const BSet& bset)
if (ret == 1)
break;
if (deadlock) {
- LL1("scanupdateindex: stop on deadlock");
+ LL1("scanupdateindex: stop on deadlock [at 1]");
break;
}
if (par.m_scanstop != 0 && urandom(par.m_scanstop) == 0) {
@@ -2701,13 +4109,14 @@ scanupdateindex(Par par, const ITab& itab, const BSet& bset)
CHK(set2.getkey(par, &i) == 0);
const Row& row = *set.m_row[i];
set.lock();
- if (! set.exist(i) || set.pending(i)) {
+ if (! set.exist(i) || set.pending(i, Row::AnyOp)) {
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.dbsave(i);
set.calc(par, i);
CHKTRY(set.setrow(par2, i) == 0, set.unlock());
LL4("scan update " << itab.m_name << ": " << row);
@@ -2715,10 +4124,16 @@ scanupdateindex(Par par, const ITab& itab, const BSet& bset)
}
set.unlock();
if (lst.cnt() == par.m_batch) {
- CHK(con2.execute(Commit) == 0);
+ deadlock = par.m_deadlock;
+ CHK(con2.execute(Commit, deadlock, nospace) == 0);
+ if (deadlock) {
+ LL1("scanupdateindex: stop on deadlock [at 2]");
+ goto out;
+ }
con2.closeTransaction();
set.lock();
set.notpending(lst);
+ set.dbdiscard(lst);
set.unlock();
count += lst.cnt();
lst.reset();
@@ -2726,10 +4141,16 @@ scanupdateindex(Par par, const ITab& itab, const BSet& bset)
}
CHK((ret = con.nextScanResult(false)) == 0 || ret == 1 || ret == 2);
if (ret == 2 && lst.cnt() != 0) {
- CHK(con2.execute(Commit) == 0);
+ deadlock = par.m_deadlock;
+ CHK(con2.execute(Commit, deadlock, nospace) == 0);
+ if (deadlock) {
+ LL1("scanupdateindex: stop on deadlock [at 3]");
+ goto out;
+ }
con2.closeTransaction();
set.lock();
set.notpending(lst);
+ set.dbdiscard(lst);
set.unlock();
count += lst.cnt();
lst.reset();
@@ -2737,6 +4158,7 @@ scanupdateindex(Par par, const ITab& itab, const BSet& bset)
}
} while (ret == 0);
}
+out:
con2.closeTransaction();
LL3("scan update " << itab.m_name << " rows updated=" << count);
con.closeTransaction();
@@ -2748,9 +4170,13 @@ scanupdateindex(Par par, const ITab& itab)
{
const Tab& tab = par.tab();
for (unsigned i = 0; i < par.m_subsubloop; i++) {
- BSet bset(tab, itab, par.m_rows);
- bset.calc(par);
- CHK(scanupdateindex(par, itab, bset) == 0);
+ if (itab.m_type == ITab::OrderedIndex) {
+ BSet bset(tab, itab, par.m_rows);
+ bset.calc(par);
+ CHK(scanupdateindex(par, itab, bset) == 0);
+ } else {
+ CHK(hashindexupdate(par, itab) == 0);
+ }
}
return 0;
}
@@ -2760,9 +4186,9 @@ scanupdateindex(Par par)
{
const Tab& tab = par.tab();
for (unsigned i = 0; i < tab.m_itabs; i++) {
- if (! useindex(i))
+ if (tab.m_itab[i] == 0)
continue;
- const ITab& itab = tab.m_itab[i];
+ const ITab& itab = *tab.m_itab[i];
CHK(scanupdateindex(par, itab) == 0);
}
return 0;
@@ -2788,6 +4214,7 @@ readverify(Par par)
LL2("skip verify in this version"); // implement in 5.0 version
par.m_verify = false;
}
+ par.m_lockmode = NdbOperation::LM_CommittedRead;
CHK(pkread(par) == 0);
CHK(scanreadall(par) == 0);
return 0;
@@ -2799,43 +4226,106 @@ readverifyfull(Par par)
if (par.m_noverify)
return 0;
par.m_verify = true;
- if (par.m_no == 0)
+ if (par.m_abortpct != 0) {
+ LL2("skip verify in this version"); // implement in 5.0 version
+ par.m_verify = false;
+ }
+ par.m_lockmode = NdbOperation::LM_CommittedRead;
+ const Tab& tab = par.tab();
+ if (par.m_no == 0) {
+ // thread 0 scans table
CHK(scanreadtable(par) == 0);
- else {
- const Tab& tab = par.tab();
- unsigned i = par.m_no;
- if (i <= tab.m_itabs && useindex(i)) {
- const ITab& itab = tab.m_itab[i - 1];
+ // once more via tup scan
+ par.m_tupscan = true;
+ if (NDB_VERSION < MAKE_VERSION(5, 1, 0)) //TODO
+ CHK(scanreadtable(par) == 0);
+ }
+ // each thread scans different indexes
+ for (unsigned i = 0; i < tab.m_itabs; i++) {
+ if (i % par.m_threads != par.m_no)
+ continue;
+ if (tab.m_itab[i] == 0)
+ continue;
+ const ITab& itab = *tab.m_itab[i];
+ if (itab.m_type == ITab::OrderedIndex) {
BSet bset(tab, itab, par.m_rows);
- CHK(scanreadindex(par, itab, bset) == 0);
+ CHK(scanreadindex(par, itab, bset, false) == 0);
+ } else {
+ CHK(hashindexread(par, itab) == 0);
}
}
return 0;
}
static int
+readverifyindex(Par par)
+{
+ if (par.m_noverify)
+ return 0;
+ par.m_verify = true;
+ par.m_lockmode = NdbOperation::LM_CommittedRead;
+ unsigned sel = urandom(10);
+ if (sel < 9) {
+ par.m_ordered = true;
+ par.m_descending = (sel < 5);
+ }
+ CHK(scanreadindex(par) == 0);
+ return 0;
+}
+
+static int
pkops(Par par)
{
+ const Tab& tab = par.tab();
par.m_randomkey = true;
for (unsigned i = 0; i < par.m_subsubloop; i++) {
+ unsigned j = 0;
+ while (j < tab.m_itabs) {
+ if (tab.m_itab[j] != 0) {
+ const ITab& itab = *tab.m_itab[j];
+ if (itab.m_type == ITab::UniqueHashIndex && urandom(5) == 0)
+ break;
+ }
+ j++;
+ }
unsigned sel = urandom(10);
if (par.m_slno % 2 == 0) {
// favor insert
if (sel < 8) {
CHK(pkinsert(par) == 0);
} else if (sel < 9) {
- CHK(pkupdate(par) == 0);
+ if (j == tab.m_itabs)
+ CHK(pkupdate(par) == 0);
+ else {
+ const ITab& itab = *tab.m_itab[j];
+ CHK(hashindexupdate(par, itab) == 0);
+ }
} else {
- CHK(pkdelete(par) == 0);
+ if (j == tab.m_itabs)
+ CHK(pkdelete(par) == 0);
+ else {
+ const ITab& itab = *tab.m_itab[j];
+ CHK(hashindexdelete(par, itab) == 0);
+ }
}
} else {
// favor delete
if (sel < 1) {
CHK(pkinsert(par) == 0);
} else if (sel < 2) {
- CHK(pkupdate(par) == 0);
+ if (j == tab.m_itabs)
+ CHK(pkupdate(par) == 0);
+ else {
+ const ITab& itab = *tab.m_itab[j];
+ CHK(hashindexupdate(par, itab) == 0);
+ }
} else {
- CHK(pkdelete(par) == 0);
+ if (j == tab.m_itabs)
+ CHK(pkdelete(par) == 0);
+ else {
+ const ITab& itab = *tab.m_itab[j];
+ CHK(hashindexdelete(par, itab) == 0);
+ }
}
}
}
@@ -2846,6 +4336,7 @@ static int
pkupdatescanread(Par par)
{
par.m_dups = true;
+ par.m_deadlock = true;
unsigned sel = urandom(10);
if (sel < 5) {
CHK(pkupdate(par) == 0);
@@ -2854,6 +4345,10 @@ pkupdatescanread(Par par)
CHK(scanreadtable(par) == 0);
} else {
par.m_verify = false;
+ if (sel < 8) {
+ par.m_ordered = true;
+ par.m_descending = (sel < 7);
+ }
CHK(scanreadindex(par) == 0);
}
return 0;
@@ -2873,6 +4368,10 @@ mixedoperations(Par par)
} else if (sel < 6) {
CHK(scanupdatetable(par) == 0);
} else {
+ if (sel < 8) {
+ par.m_ordered = true;
+ par.m_descending = (sel < 7);
+ }
CHK(scanupdateindex(par) == 0);
}
return 0;
@@ -3134,6 +4633,24 @@ tbuild(Par par)
}
static int
+tindexscan(Par par)
+{
+ RUNSTEP(par, droptable, ST);
+ RUNSTEP(par, createtable, ST);
+ RUNSTEP(par, invalidatetable, MT);
+ RUNSTEP(par, createindex, ST);
+ RUNSTEP(par, invalidateindex, MT);
+ RUNSTEP(par, pkinsert, MT);
+ RUNSTEP(par, readverifyfull, MT);
+ for (par.m_slno = 0; par.m_slno < par.m_subloop; par.m_slno++) {
+ LL4("subloop " << par.m_slno);
+ RUNSTEP(par, readverifyindex, MT);
+ }
+ return 0;
+}
+
+
+static int
tpkops(Par par)
{
RUNSTEP(par, droptable, ST);
@@ -3266,6 +4783,10 @@ ttimemaint(Par par)
static int
ttimescan(Par par)
{
+ if (par.tab().m_itab[0] == 0) {
+ LL1("ttimescan - no index 0, skipped");
+ return 0;
+ }
Tmr t1, t2;
RUNSTEP(par, droptable, ST);
RUNSTEP(par, createtable, ST);
@@ -3288,6 +4809,10 @@ ttimescan(Par par)
static int
ttimepkread(Par par)
{
+ if (par.tab().m_itab[0] == 0) {
+ LL1("ttimescan - no index 0, skipped");
+ return 0;
+ }
Tmr t1, t2;
RUNSTEP(par, droptable, ST);
RUNSTEP(par, createtable, ST);
@@ -3328,7 +4853,7 @@ struct TCase {
static const TCase
tcaselist[] = {
TCase("a", tbuild, "index build"),
- // "b" in 5.0
+ TCase("b", tindexscan, "index scans"),
TCase("c", tpkops, "pk operations"),
TCase("d", tpkopsread, "pk operations and scan reads"),
TCase("e", tmixedops, "pk operations and scan operations"),
@@ -3357,13 +4882,32 @@ printcases()
static void
printtables()
{
- ndbout << "tables and indexes (X1 is on table PK):" << endl;
+ Par par(g_opt);
+ makebuiltintables(par);
+ ndbout << "tables and indexes (x=ordered z=hash x0=on pk):" << endl;
for (unsigned j = 0; j < tabcount; j++) {
- const Tab& tab = tablist[j];
- ndbout << " " << tab.m_name;
+ if (tablist[j] == 0)
+ continue;
+ const Tab& tab = *tablist[j];
+ const char* tname = tab.m_name;
+ ndbout << " " << tname;
for (unsigned i = 0; i < tab.m_itabs; i++) {
- const ITab& itab = tab.m_itab[i];
- ndbout << " " << itab.m_name;
+ if (tab.m_itab[i] == 0)
+ continue;
+ const ITab& itab = *tab.m_itab[i];
+ const char* iname = itab.m_name;
+ if (strncmp(tname, iname, strlen(tname)) == 0)
+ iname += strlen(tname);
+ ndbout << " " << iname;
+ ndbout << "(";
+ for (unsigned k = 0; k < itab.m_icols; k++) {
+ if (k != 0)
+ ndbout << ",";
+ const ICol& icol = *itab.m_icol[k];
+ const Col& col = icol.m_col;
+ ndbout << col.m_name;
+ }
+ ndbout << ")";
}
ndbout << endl;
}
@@ -3373,15 +4917,29 @@ static int
runtest(Par par)
{
LL1("start");
- if (par.m_seed != 0)
+ if (par.m_seed == -1) {
+ // good enough for daily run
+ unsigned short seed = (getpid() ^ time(0));
+ LL1("random seed: " << seed);
+ srandom((unsigned)seed);
+ } else if (par.m_seed != 0) {
+ LL1("random seed: " << par.m_seed);
srandom(par.m_seed);
+ } else {
+ LL1("random seed: loop number");
+ }
+ // cs
assert(par.m_csname != 0);
- CHARSET_INFO* cs;
- CHK((cs = get_charset_by_name(par.m_csname, MYF(0))) != 0 || (cs = get_charset_by_csname(par.m_csname, MY_CS_PRIMARY, MYF(0))) != 0);
- par.m_cs = cs;
+ if (strcmp(par.m_csname, "random") != 0) {
+ CHARSET_INFO* cs;
+ CHK((cs = get_charset_by_name(par.m_csname, MYF(0))) != 0 || (cs = get_charset_by_csname(par.m_csname, MY_CS_PRIMARY, MYF(0))) != 0);
+ par.m_cs = cs;
+ }
+ // con
Con con;
CHK(con.connect() == 0);
par.m_con = &con;
+ // threads
g_thrlist = new Thr* [par.m_threads];
unsigned n;
for (n = 0; n < par.m_threads; n++) {
@@ -3400,16 +4958,18 @@ runtest(Par par)
const TCase& tcase = tcaselist[i];
if (par.m_case != 0 && strchr(par.m_case, tcase.m_name[0]) == 0)
continue;
+ makebuiltintables(par);
LL1("case " << tcase.m_name << " - " << tcase.m_desc);
for (unsigned j = 0; j < tabcount; j++) {
- if (! usetable(j))
+ if (tablist[j] == 0)
continue;
- const Tab& tab = tablist[j];
+ const Tab& tab = *tablist[j];
par.m_tab = &tab;
- delete par.m_set;
par.m_set = new Set(tab, par.m_totrows);
LL1("table " << tab.m_name);
CHK(tcase.m_func(par) == 0);
+ delete par.m_set;
+ par.m_set = 0;
}
}
}
@@ -3433,7 +4993,7 @@ NDB_COMMAND(testOIBasic, "testOIBasic", "testOIBasic", "testOIBasic", 65535)
{
ndb_init();
if (ndbout_mutex == NULL)
- ndbout_mutex= NdbMutex_Create();
+ ndbout_mutex = NdbMutex_Create();
while (++argv, --argc > 0) {
const char* arg = argv[0];
if (*arg != '-') {
@@ -3461,6 +5021,10 @@ NDB_COMMAND(testOIBasic, "testOIBasic", "testOIBasic", "testOIBasic", 65535)
continue;
}
}
+ if (strcmp(arg, "-collsp") == 0) {
+ g_opt.m_collsp = true;
+ continue;
+ }
if (strcmp(arg, "-core") == 0) {
g_opt.m_core = true;
continue;
@@ -3539,12 +5103,6 @@ NDB_COMMAND(testOIBasic, "testOIBasic", "testOIBasic", "testOIBasic", 65535)
continue;
}
}
- if (strcmp(arg, "-scanbat") == 0) {
- if (++argv, --argc > 0) {
- g_opt.m_scanbat = atoi(argv[0]);
- continue;
- }
- }
if (strcmp(arg, "-scanpar") == 0) {
if (++argv, --argc > 0) {
g_opt.m_scanpar = atoi(argv[0]);
@@ -3572,7 +5130,8 @@ NDB_COMMAND(testOIBasic, "testOIBasic", "testOIBasic", "testOIBasic", 65535)
if (strcmp(arg, "-threads") == 0) {
if (++argv, --argc > 0) {
g_opt.m_threads = atoi(argv[0]);
- continue;
+ if (1 <= g_opt.m_threads)
+ continue;
}
}
if (strcmp(arg, "-v") == 0) {
@@ -3589,7 +5148,7 @@ NDB_COMMAND(testOIBasic, "testOIBasic", "testOIBasic", "testOIBasic", 65535)
printhelp();
goto wrongargs;
}
- ndbout << "testOIBasic: unknown option " << arg;
+ ndbout << "testOIBasic: bad or unknown option " << arg;
goto usage;
}
{
@@ -3600,7 +5159,6 @@ NDB_COMMAND(testOIBasic, "testOIBasic", "testOIBasic", "testOIBasic", 65535)
delete g_ncc;
g_ncc = 0;
}
- // always exit with NDBT code
ok:
return NDBT_ProgramExit(NDBT_OK);
failed:
diff --git a/ndb/test/ndbapi/testPartitioning.cpp b/ndb/test/ndbapi/testPartitioning.cpp
new file mode 100644
index 00000000000..9d67c27354b
--- /dev/null
+++ b/ndb/test/ndbapi/testPartitioning.cpp
@@ -0,0 +1,430 @@
+/* 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 <NDBT_Test.hpp>
+#include <NDBT_ReturnCodes.h>
+#include <HugoTransactions.hpp>
+#include <UtilTransactions.hpp>
+#include <NdbRestarter.hpp>
+
+#define GETNDB(ps) ((NDBT_NdbApiStep*)ps)->getNdb()
+
+static Uint32 max_dks = 0;
+
+static
+int
+run_drop_table(NDBT_Context* ctx, NDBT_Step* step)
+{
+ NdbDictionary::Dictionary* dict = GETNDB(step)->getDictionary();
+ dict->dropTable(ctx->getTab()->getName());
+ return 0;
+}
+
+static
+int
+add_distribution_key(Ndb*, NdbDictionary::Table& tab, int when)
+{
+ switch(when){
+ case 0: // Before
+ break;
+ case 1: // After
+ return 0;
+ default:
+ return 0;
+ }
+
+ int keys = tab.getNoOfPrimaryKeys();
+ int dks = (2 * keys + 2) / 3; dks = (dks > max_dks ? max_dks : dks);
+ int cnt = 0;
+
+ for(unsigned i = 0; i<tab.getNoOfColumns(); i++)
+ if(tab.getColumn(i)->getPrimaryKey() &&
+ tab.getColumn(i)->getCharset() != 0)
+ keys--;
+
+ Uint32 max = NDB_MAX_NO_OF_ATTRIBUTES_IN_KEY - tab.getNoOfPrimaryKeys();
+
+ if(max_dks < max)
+ max = max_dks;
+
+ if(keys <= 1 && max > 0)
+ {
+ dks = 1 + (rand() % max);
+ ndbout_c("%s pks: %d dks: %d", tab.getName(), keys, dks);
+ while(dks--)
+ {
+ NdbDictionary::Column col;
+ BaseString name;
+ name.assfmt("PK_DK_%d", dks);
+ col.setName(name.c_str());
+ col.setType(NdbDictionary::Column::Unsigned);
+ col.setLength(1);
+ col.setNullable(false);
+ col.setPrimaryKey(true);
+ col.setDistributionKey(true);
+ tab.addColumn(col);
+ }
+ }
+ else
+ {
+ for(unsigned i = 0; i<tab.getNoOfColumns(); i++)
+ {
+ NdbDictionary::Column* col = tab.getColumn(i);
+ if(col->getPrimaryKey() && col->getCharset() == 0)
+ {
+ if(dks >= keys || (rand() % 100) > 50)
+ {
+ col->setDistributionKey(true);
+ dks--;
+ }
+ keys--;
+ }
+ }
+ }
+ ndbout << (NDBT_Table&)tab << endl;
+
+ return 0;
+}
+
+static int
+run_create_table(NDBT_Context* ctx, NDBT_Step* step)
+{
+ max_dks = ctx->getProperty("distributionkey", (unsigned)0);
+
+ if(NDBT_Tables::createTable(GETNDB(step),
+ ctx->getTab()->getName(),
+ false, false,
+ max_dks?add_distribution_key:0) == NDBT_OK)
+ {
+ return NDBT_OK;
+ }
+
+ if(GETNDB(step)->getDictionary()->getNdbError().code == 745)
+ return NDBT_OK;
+
+ return NDBT_FAILED;
+}
+
+static int
+run_create_pk_index(NDBT_Context* ctx, NDBT_Step* step){
+ bool orderedIndex = ctx->getProperty("OrderedIndex", (unsigned)0);
+
+ Ndb* pNdb = GETNDB(step);
+ const NdbDictionary::Table *pTab =
+ pNdb->getDictionary()->getTable(ctx->getTab()->getName());
+
+ if(!pTab)
+ return NDBT_OK;
+
+ bool logged = ctx->getProperty("LoggedIndexes", orderedIndex ? 0 : 1);
+
+ BaseString name;
+ name.assfmt("IND_%s_PK_%c", pTab->getName(), orderedIndex ? 'O' : 'U');
+
+ // Create index
+ if (orderedIndex)
+ ndbout << "Creating " << ((logged)?"logged ": "temporary ") << "ordered index "
+ << name.c_str() << " (";
+ else
+ ndbout << "Creating " << ((logged)?"logged ": "temporary ") << "unique index "
+ << name.c_str() << " (";
+
+ NdbDictionary::Index pIdx(name.c_str());
+ pIdx.setTable(pTab->getName());
+ if (orderedIndex)
+ pIdx.setType(NdbDictionary::Index::OrderedIndex);
+ else
+ pIdx.setType(NdbDictionary::Index::UniqueHashIndex);
+ for (int c = 0; c< pTab->getNoOfColumns(); c++){
+ const NdbDictionary::Column * col = pTab->getColumn(c);
+ if(col->getPrimaryKey()){
+ pIdx.addIndexColumn(col->getName());
+ ndbout << col->getName() <<" ";
+ }
+ }
+
+ pIdx.setStoredIndex(logged);
+ ndbout << ") ";
+ if (pNdb->getDictionary()->createIndex(pIdx) != 0){
+ ndbout << "FAILED!" << endl;
+ const NdbError err = pNdb->getDictionary()->getNdbError();
+ ERR(err);
+ return NDBT_FAILED;
+ }
+
+ ndbout << "OK!" << endl;
+ return NDBT_OK;
+}
+
+static int run_create_pk_index_drop(NDBT_Context* ctx, NDBT_Step* step){
+ bool orderedIndex = ctx->getProperty("OrderedIndex", (unsigned)0);
+
+ Ndb* pNdb = GETNDB(step);
+ const NdbDictionary::Table *pTab =
+ pNdb->getDictionary()->getTable(ctx->getTab()->getName());
+
+ if(!pTab)
+ return NDBT_OK;
+
+ BaseString name;
+ name.assfmt("IND_%s_PK_%c", pTab->getName(), orderedIndex ? 'O' : 'U');
+
+ ndbout << "Dropping index " << name.c_str() << " ";
+ if (pNdb->getDictionary()->dropIndex(name.c_str(), pTab->getName()) != 0){
+ ndbout << "FAILED!" << endl;
+ ERR(pNdb->getDictionary()->getNdbError());
+ return NDBT_FAILED;
+ } else {
+ ndbout << "OK!" << endl;
+ }
+
+ return NDBT_OK;
+}
+
+static int
+run_tests(Ndb* p_ndb, HugoTransactions& hugoTrans, int records)
+{
+ if (hugoTrans.loadTable(p_ndb, records) != 0)
+ {
+ return NDBT_FAILED;
+ }
+
+ if(hugoTrans.pkReadRecords(p_ndb, records) != 0)
+ {
+ return NDBT_FAILED;
+ }
+
+ if(hugoTrans.pkUpdateRecords(p_ndb, records) != 0)
+ {
+ return NDBT_FAILED;
+ }
+
+ if(hugoTrans.pkDelRecords(p_ndb, records) != 0)
+ {
+ return NDBT_FAILED;
+ }
+
+ if (hugoTrans.loadTable(p_ndb, records) != 0)
+ {
+ return NDBT_FAILED;
+ }
+
+ if(hugoTrans.scanUpdateRecords(p_ndb, records) != 0)
+ {
+ return NDBT_FAILED;
+ }
+
+ Uint32 abort = 23;
+ for(Uint32 j = 0; j<5; j++){
+ Uint32 parallelism = (j == 1 ? 1 : j * 3);
+ ndbout_c("parallelism: %d", parallelism);
+ if (hugoTrans.scanReadRecords(p_ndb, records, abort, parallelism,
+ NdbOperation::LM_Read) != 0)
+ {
+ return NDBT_FAILED;
+ }
+ if (hugoTrans.scanReadRecords(p_ndb, records, abort, parallelism,
+ NdbOperation::LM_Exclusive) != 0)
+ {
+ return NDBT_FAILED;
+ }
+ if (hugoTrans.scanReadRecords(p_ndb, records, abort, parallelism,
+ NdbOperation::LM_CommittedRead) != 0)
+ {
+ return NDBT_FAILED;
+ }
+ }
+
+ if(hugoTrans.clearTable(p_ndb, records) != 0)
+ {
+ return NDBT_FAILED;
+ }
+
+ return 0;
+}
+
+static int
+run_pk_dk(NDBT_Context* ctx, NDBT_Step* step)
+{
+ Ndb* p_ndb = GETNDB(step);
+ int records = ctx->getNumRecords();
+ const NdbDictionary::Table *tab =
+ p_ndb->getDictionary()->getTable(ctx->getTab()->getName());
+
+ if(!tab)
+ return NDBT_OK;
+
+ HugoTransactions hugoTrans(*tab);
+
+ return run_tests(p_ndb, hugoTrans, records);
+}
+
+int
+run_index_dk(NDBT_Context* ctx, NDBT_Step* step)
+{
+ Ndb* p_ndb = GETNDB(step);
+ int records = ctx->getNumRecords();
+ const NdbDictionary::Table *pTab =
+ p_ndb->getDictionary()->getTable(ctx->getTab()->getName());
+
+ if(!pTab)
+ return NDBT_OK;
+
+ bool orderedIndex = ctx->getProperty("OrderedIndex", (unsigned)0);
+
+ BaseString name;
+ name.assfmt("IND_%s_PK_%c", pTab->getName(), orderedIndex ? 'O' : 'U');
+
+ const NdbDictionary::Index * idx =
+ p_ndb->getDictionary()->getIndex(name.c_str(), pTab->getName());
+
+ if(!idx)
+ {
+ ndbout << "Failed to retreive index: " << name.c_str() << endl;
+ return NDBT_FAILED;
+ }
+
+ HugoTransactions hugoTrans(*pTab, idx);
+
+ return run_tests(p_ndb, hugoTrans, records);
+}
+
+static int
+run_startHint(NDBT_Context* ctx, NDBT_Step* step)
+{
+ Ndb* p_ndb = GETNDB(step);
+ int records = ctx->getNumRecords();
+ const NdbDictionary::Table *tab =
+ p_ndb->getDictionary()->getTable(ctx->getTab()->getName());
+
+ if(!tab)
+ return NDBT_OK;
+
+ HugoTransactions hugoTrans(*tab);
+ if (hugoTrans.loadTable(p_ndb, records) != 0)
+ {
+ return NDBT_FAILED;
+ }
+
+ NdbRestarter restarter;
+ if(restarter.insertErrorInAllNodes(8050) != 0)
+ return NDBT_FAILED;
+
+ HugoCalculator dummy(*tab);
+ int result = NDBT_OK;
+ for(int i = 0; i<records && result == NDBT_OK; i++)
+ {
+ char buffer[8000];
+ char* start= buffer + (rand() & 7);
+ char* pos= start;
+
+ for(int j = 0; j<tab->getNoOfColumns(); j++)
+ {
+ if(tab->getColumn(j)->getPartitionKey())
+ {
+ ndbout_c(tab->getColumn(j)->getName());
+ int sz = tab->getColumn(j)->getSizeInBytes();
+ int aligned_size = 4 * ((sz + 3) >> 2);
+ memset(pos, 0, aligned_size);
+ dummy.calcValue(i, j, 0, pos, sz);
+ pos += aligned_size;
+ }
+ }
+ // Now we have the pk
+ NdbTransaction* pTrans= p_ndb->startTransaction(tab, start,(pos - start));
+ HugoOperations ops(*tab);
+ ops.setTransaction(pTrans);
+ if(ops.pkReadRecord(p_ndb, i, 1) != NDBT_OK)
+ {
+ result = NDBT_FAILED;
+ break;
+ }
+
+ if(ops.execute_Commit(p_ndb) != 0)
+ {
+ result = NDBT_FAILED;
+ break;
+ }
+
+ ops.closeTransaction(p_ndb);
+ }
+ restarter.insertErrorInAllNodes(0);
+ return result;
+}
+
+
+NDBT_TESTSUITE(testPartitioning);
+TESTCASE("pk_dk",
+ "Primary key operations with distribution key")
+{
+ TC_PROPERTY("distributionkey", ~0);
+ INITIALIZER(run_drop_table);
+ INITIALIZER(run_create_table);
+ INITIALIZER(run_pk_dk);
+ INITIALIZER(run_drop_table);
+}
+TESTCASE("hash_index_dk",
+ "Unique index operatations with distribution key")
+{
+ TC_PROPERTY("distributionkey", ~0);
+ TC_PROPERTY("OrderedIndex", (unsigned)0);
+ INITIALIZER(run_drop_table);
+ INITIALIZER(run_create_table);
+ INITIALIZER(run_create_pk_index);
+ INITIALIZER(run_index_dk);
+ INITIALIZER(run_create_pk_index_drop);
+ INITIALIZER(run_drop_table);
+}
+TESTCASE("ordered_index_dk",
+ "Ordered index operatations with distribution key")
+{
+ TC_PROPERTY("distributionkey", (unsigned)1);
+ TC_PROPERTY("OrderedIndex", (unsigned)1);
+ INITIALIZER(run_drop_table);
+ INITIALIZER(run_create_table);
+ INITIALIZER(run_create_pk_index);
+ INITIALIZER(run_index_dk);
+ INITIALIZER(run_create_pk_index_drop);
+ INITIALIZER(run_drop_table);
+}
+TESTCASE("startTransactionHint",
+ "Test startTransactionHint wo/ distribution key")
+{
+ TC_PROPERTY("distributionkey", (unsigned)0);
+ INITIALIZER(run_drop_table);
+ INITIALIZER(run_create_table);
+ INITIALIZER(run_startHint);
+ INITIALIZER(run_drop_table);
+}
+TESTCASE("startTransactionHint_dk",
+ "Test startTransactionHint with distribution key")
+{
+ TC_PROPERTY("distributionkey", (unsigned)~0);
+ INITIALIZER(run_drop_table);
+ INITIALIZER(run_create_table);
+ INITIALIZER(run_startHint);
+ INITIALIZER(run_drop_table);
+}
+NDBT_TESTSUITE_END(testPartitioning);
+
+int main(int argc, const char** argv){
+ ndb_init();
+ testPartitioning.setCreateTable(false);
+ return testPartitioning.execute(argc, argv);
+}
+
+
+
diff --git a/ndb/test/ndbapi/testReadPerf.cpp b/ndb/test/ndbapi/testReadPerf.cpp
index 3adcb5a2d9b..ba5f3c4232d 100644
--- a/ndb/test/ndbapi/testReadPerf.cpp
+++ b/ndb/test/ndbapi/testReadPerf.cpp
@@ -119,7 +119,13 @@ main(int argc, const char** argv){
myRandom48Init(NdbTick_CurrentMillisecond());
memset(g_times, 0, sizeof(g_times));
- g_ndb = new Ndb("TEST_DB");
+ Ndb_cluster_connection con;
+ if(con.connect(12, 5, 1))
+ {
+ return NDBT_ProgramExit(NDBT_FAILED);
+ }
+
+ g_ndb = new Ndb(&con, "TEST_DB");
if(g_ndb->init() != 0){
g_err << "init() failed" << endl;
goto error;
@@ -266,7 +272,6 @@ run_read(){
NdbScanOperation * pSp;
NdbIndexOperation * pUp;
NdbIndexScanOperation * pIp;
- NdbResultSet * rs = (NdbResultSet*)~0;
Uint32 start_row = rand() % (rows - range);
Uint32 stop_row = start_row + range;
@@ -319,27 +324,27 @@ run_read(){
}
break;
case 4:
- pOp = pIp = pTrans->getNdbIndexScanOperation(g_ordered,g_table);
- rs = pIp->readTuples(NdbScanOperation::LM_CommittedRead, 0, 0);
+ pOp = pSp = pIp = pTrans->getNdbIndexScanOperation(g_ordered,g_table);
+ pIp->readTuples(NdbScanOperation::LM_CommittedRead, 0, 0);
check = pIp->setBound(pk, NdbIndexScanOperation::BoundEQ, &start_row);
break;
case 5:
- pOp = pIp = pTrans->getNdbIndexScanOperation(g_ordered,g_table);
- rs = pIp->readTuples(NdbScanOperation::LM_CommittedRead, 0, 0);
+ pOp = pSp = pIp = pTrans->getNdbIndexScanOperation(g_ordered,g_table);
+ pIp->readTuples(NdbScanOperation::LM_CommittedRead, 0, 0);
check = pIp->setBound(pk, NdbIndexScanOperation::BoundLE, &start_row);
check = pIp->setBound(pk, NdbIndexScanOperation::BoundGT, &stop_row);
start_row = stop_row;
break;
case 6:
- pOp = pIp = pTrans->getNdbIndexScanOperation(g_ordered,g_table);
- rs = pIp->readTuples(NdbScanOperation::LM_CommittedRead, 0, 0, true);
+ pOp = pSp = pIp = pTrans->getNdbIndexScanOperation(g_ordered,g_table);
+ pIp->readTuples(NdbScanOperation::LM_CommittedRead, 0, 0, true);
check = pIp->setBound(pk, NdbIndexScanOperation::BoundLE, &start_row);
check = pIp->setBound(pk, NdbIndexScanOperation::BoundGT, &stop_row);
start_row = stop_row;
break;
case 7:
pOp = pSp = pTrans->getNdbScanOperation(g_table);
- rs = pSp->readTuples(NdbScanOperation::LM_CommittedRead, 0, 0);
+ pSp->readTuples(NdbScanOperation::LM_CommittedRead, 0, 0);
NdbScanFilter filter(pOp) ;
filter.begin(NdbScanFilter::AND);
filter.ge(pk, start_row);
@@ -355,7 +360,6 @@ run_read(){
ndbout << pTrans->getNdbError() << endl;
}
assert(check == 0);
- assert(rs);
for(int j = 0; j<g_tab->getNoOfColumns(); j++){
res = pOp->getValue(j);
@@ -368,7 +372,7 @@ run_read(){
}
assert(check == 0);
if(g_paramters[P_OPER].value >= 4){
- while((check = rs->nextResult(true)) == 0){
+ while((check = pSp->nextResult(true)) == 0){
cnt++;
}
@@ -377,13 +381,13 @@ run_read(){
return -1;
}
assert(check == 1);
- rs->close();
+ pSp->close();
}
}
assert(g_paramters[P_OPER].value < 4 || (cnt == range));
-
+
pTrans->close();
-
+
stop = NdbTick_CurrentMillisecond();
g_times[g_paramters[P_OPER].value] += (stop - start1);
return 0;
diff --git a/ndb/test/ndbapi/testScan.cpp b/ndb/test/ndbapi/testScan.cpp
index f1018d29846..2802f1c950e 100644
--- a/ndb/test/ndbapi/testScan.cpp
+++ b/ndb/test/ndbapi/testScan.cpp
@@ -316,11 +316,16 @@ int runScanReadIndex(NDBT_Context* ctx, NDBT_Step* step){
while (pIdx && i<loops && !ctx->isTestStopped()) {
g_info << i << ": ";
bool sort = (rand() % 100) > 50 ? true : false;
+ bool desc = (rand() % 100) > 50 ? true : false;
+ desc = false; // random causes too many deadlocks
+ int scan_flags =
+ (NdbScanOperation::SF_OrderBy & -(int)sort) |
+ (NdbScanOperation::SF_Descending & -(int)desc);
NdbOperation::LockMode lm = (NdbOperation::LockMode)(rand() % 3);
if (hugoTrans.scanReadRecords(GETNDB(step), pIdx,
records, abort, parallelism,
lm,
- sort) != 0){
+ scan_flags) != 0){
return NDBT_FAILED;
}
i++;
@@ -333,6 +338,8 @@ int runScanReadCommitted(NDBT_Context* ctx, NDBT_Step* step){
int records = ctx->getNumRecords();
int parallelism = ctx->getProperty("Parallelism", 240);
int abort = ctx->getProperty("AbortProb", 5);
+ bool tupScan = ctx->getProperty("TupScan");
+ int scan_flags = (NdbScanOperation::SF_TupScan & -(int)tupScan);
int i = 0;
HugoTransactions hugoTrans(*ctx->getTab());
@@ -340,7 +347,8 @@ int runScanReadCommitted(NDBT_Context* ctx, NDBT_Step* step){
g_info << i << ": ";
if (hugoTrans.scanReadRecords(GETNDB(step), records,
abort, parallelism,
- NdbOperation::LM_CommittedRead) != 0){
+ NdbOperation::LM_CommittedRead,
+ scan_flags) != 0){
return NDBT_FAILED;
}
i++;
@@ -1013,8 +1021,7 @@ int runScanRestart(NDBT_Context* ctx, NDBT_Step* step){
return NDBT_FAILED;
}
- NdbResultSet* rs = pOp->readTuples();
- if( rs == 0 ) {
+ if( pOp->readTuples() ) {
ERR(pCon->getNdbError());
return NDBT_FAILED;
}
@@ -1042,7 +1049,7 @@ int runScanRestart(NDBT_Context* ctx, NDBT_Step* step){
int res;
int row = 0;
- while(row < record && (res = rs->nextResult()) == 0) {
+ while(row < record && (res = pOp->nextResult()) == 0) {
if(calc.verifyRowValues(&tmpRow) != 0){
abort();
return NDBT_FAILED;
@@ -1055,14 +1062,14 @@ int runScanRestart(NDBT_Context* ctx, NDBT_Step* step){
return NDBT_FAILED;
}
g_info << " restarting" << endl;
- if((res = rs->restart()) != 0){
+ if((res = pOp->restart()) != 0){
ERR(pCon->getNdbError());
abort();
return NDBT_FAILED;
}
row = 0;
- while((res = rs->nextResult()) == 0) {
+ while((res = pOp->nextResult()) == 0) {
if(calc.verifyRowValues(&tmpRow) != 0){
abort();
return NDBT_FAILED;
@@ -1080,6 +1087,44 @@ int runScanRestart(NDBT_Context* ctx, NDBT_Step* step){
}
+int
+runScanParallelism(NDBT_Context* ctx, NDBT_Step* step){
+ int loops = ctx->getNumLoops() + 3;
+ int records = ctx->getNumRecords();
+ int abort = ctx->getProperty("AbortProb", 15);
+
+ Uint32 fib[] = { 1, 2 };
+ Uint32 parallelism = 0; // start with 0
+ int i = 0;
+ HugoTransactions hugoTrans(*ctx->getTab());
+ while (i<loops && !ctx->isTestStopped()) {
+ g_info << i << ": ";
+
+ if (hugoTrans.scanReadRecords(GETNDB(step), records, abort, parallelism,
+ NdbOperation::LM_Read) != 0){
+ return NDBT_FAILED;
+ }
+ if (hugoTrans.scanReadRecords(GETNDB(step), records, abort, parallelism,
+ NdbOperation::LM_Exclusive) != 0){
+ return NDBT_FAILED;
+ }
+ if (hugoTrans.scanReadRecords(GETNDB(step), records, abort, parallelism,
+ NdbOperation::LM_CommittedRead) != 0){
+ return NDBT_FAILED;
+ }
+ if (hugoTrans.scanUpdateRecords(GETNDB(step), records, abort, parallelism)
+ != 0){
+ return NDBT_FAILED;
+ }
+ i++;
+ parallelism = fib[0];
+ Uint32 next = fib[0] + fib[1];
+ fib[0] = fib[1];
+ fib[1] = next;
+ }
+ return NDBT_OK;
+}
+
NDBT_TESTSUITE(testScan);
TESTCASE("ScanRead",
"Verify scan requirement: It should be possible "\
@@ -1113,6 +1158,18 @@ TESTCASE("ScanReadCommitted240",
"downgraded to the maximum parallelism value for the current config)"){
INITIALIZER(runLoadTable);
TC_PROPERTY("Parallelism", 240);
+ TC_PROPERTY("TupScan", (Uint32)0);
+ STEP(runScanReadCommitted);
+ FINALIZER(runClearTable);
+}
+TESTCASE("ScanTupReadCommitted240",
+ "Verify scan requirement: It should be possible to scan read committed with "\
+ "parallelism, test with parallelism 240(240 would automatically be "\
+ "downgraded to the maximum parallelism value for the current config). "\
+ "Scans TUP pages directly without using ACC."){
+ INITIALIZER(runLoadTable);
+ TC_PROPERTY("Parallelism", 240);
+ TC_PROPERTY("TupScan", 1);
STEP(runScanReadCommitted);
FINALIZER(runClearTable);
}
@@ -1540,6 +1597,12 @@ TESTCASE("ScanRestart",
STEP(runScanRestart);
FINALIZER(runClearTable);
}
+TESTCASE("ScanParallelism",
+ "Test scan with different parallelism"){
+ INITIALIZER(runLoadTable);
+ STEP(runScanParallelism);
+ FINALIZER(runClearTable);
+}
NDBT_TESTSUITE_END(testScan);
int main(int argc, const char** argv){
diff --git a/ndb/test/ndbapi/testScanPerf.cpp b/ndb/test/ndbapi/testScanPerf.cpp
index 45f0468bc70..a730136c3af 100644
--- a/ndb/test/ndbapi/testScanPerf.cpp
+++ b/ndb/test/ndbapi/testScanPerf.cpp
@@ -38,10 +38,10 @@ struct Parameter {
#define P_ROWS 7
#define P_LOOPS 8
#define P_CREATE 9
-#define P_LOAD 10
#define P_RESET 11
+#define P_MULTI 12
-#define P_MAX 12
+#define P_MAX 13
static
Parameter
@@ -57,7 +57,8 @@ g_paramters[] = {
{ "iterations", 3, 1, ~0 },
{ "create_drop", 1, 0, 1 },
{ "data", 1, 0, 1 },
- { "q-reset bounds", 0, 1, 0 }
+ { "q-reset bounds", 0, 1, 0 },
+ { "multi read range", 1000, 1, ~0 }
};
static Ndb* g_ndb = 0;
@@ -67,10 +68,7 @@ static char g_tablename[256];
static char g_indexname[256];
int create_table();
-int load_table();
int run_scan();
-int clear_table();
-int drop_table();
int
main(int argc, const char** argv){
@@ -101,7 +99,13 @@ main(int argc, const char** argv){
myRandom48Init(NdbTick_CurrentMillisecond());
- g_ndb = new Ndb("TEST_DB");
+ Ndb_cluster_connection con;
+ if(con.connect(12, 5, 1))
+ {
+ return NDBT_ProgramExit(NDBT_FAILED);
+ }
+
+ g_ndb = new Ndb(&con, "TEST_DB");
if(g_ndb->init() != 0){
g_err << "init() failed" << endl;
goto error;
@@ -117,14 +121,8 @@ main(int argc, const char** argv){
BaseString::snprintf(g_indexname, sizeof(g_indexname), "IDX_%s", T);
if(create_table())
goto error;
- if(load_table())
- goto error;
if(run_scan())
goto error;
- if(clear_table())
- goto error;
- if(drop_table())
- goto error;
}
if(g_ndb) delete g_ndb;
@@ -139,6 +137,7 @@ create_table(){
NdbDictionary::Dictionary* dict = g_ndb->getDictionary();
assert(dict);
if(g_paramters[P_CREATE].value){
+ g_ndb->getDictionary()->dropTable(g_tablename);
const NdbDictionary::Table * pTab = NDBT_Tables::getTable(g_tablename);
assert(pTab);
NdbDictionary::Table copy = * pTab;
@@ -167,46 +166,18 @@ create_table(){
g_index = dict->getIndex(g_indexname, g_tablename);
assert(g_table);
assert(g_index);
- return 0;
-}
-int
-drop_table(){
- if(!g_paramters[P_CREATE].value)
- return 0;
- if(g_ndb->getDictionary()->dropTable(g_table->getName()) != 0){
- g_err << "Failed to drop table: " << g_table->getName() << endl;
- return -1;
- }
- g_table = 0;
- return 0;
-}
-
-int
-load_table(){
- if(!g_paramters[P_LOAD].value)
- return 0;
-
- int rows = g_paramters[P_ROWS].value;
- HugoTransactions hugoTrans(* g_table);
- if (hugoTrans.loadTable(g_ndb, rows)){
- g_err.println("Failed to load %s with %d rows", g_table->getName(), rows);
- return -1;
+ if(g_paramters[P_CREATE].value)
+ {
+ int rows = g_paramters[P_ROWS].value;
+ HugoTransactions hugoTrans(* g_table);
+ if (hugoTrans.loadTable(g_ndb, rows)){
+ g_err.println("Failed to load %s with %d rows",
+ g_table->getName(), rows);
+ return -1;
+ }
}
- return 0;
-}
-
-int
-clear_table(){
- if(!g_paramters[P_LOAD].value)
- return 0;
- int rows = g_paramters[P_ROWS].value;
- UtilTransactions utilTrans(* g_table);
- if (utilTrans.clearTable(g_ndb, rows) != 0){
- g_err.println("Failed to clear table %s", g_table->getName());
- return -1;
- }
return 0;
}
@@ -227,13 +198,12 @@ run_scan(){
Uint32 tot = g_paramters[P_ROWS].value;
- if(g_paramters[P_BOUND].value == 2 || g_paramters[P_FILT].value == 2)
+ if(g_paramters[P_BOUND].value >= 2 || g_paramters[P_FILT].value == 2)
iter *= g_paramters[P_ROWS].value;
NdbScanOperation * pOp = 0;
NdbIndexScanOperation * pIOp = 0;
NdbConnection * pTrans = 0;
- NdbResultSet * rs = 0;
int check = 0;
for(int i = 0; i<iter; i++){
@@ -246,7 +216,7 @@ run_scan(){
}
int par = g_paramters[P_PARRA].value;
- int bat = g_paramters[P_BATCH].value;
+ int bat = 0; // g_paramters[P_BATCH].value;
NdbScanOperation::LockMode lm;
switch(g_paramters[P_LOCK].value){
case 0:
@@ -265,13 +235,13 @@ run_scan(){
if(g_paramters[P_ACCESS].value == 0){
pOp = pTrans->getNdbScanOperation(g_tablename);
assert(pOp);
- rs = pOp->readTuples(lm, bat, par);
+ pOp->readTuples(lm, bat, par);
} else {
if(g_paramters[P_RESET].value == 0 || pIOp == 0)
{
pOp= pIOp= pTrans->getNdbIndexScanOperation(g_indexname, g_tablename);
bool ord = g_paramters[P_ACCESS].value == 2;
- rs = pIOp->readTuples(lm, bat, par, ord);
+ pIOp->readTuples(lm, bat, par, ord);
}
else
{
@@ -294,14 +264,26 @@ run_scan(){
#else
pIOp->setBound((Uint32)0, NdbIndexScanOperation::BoundEQ, &row);
#endif
+ if(g_paramters[P_RESET].value == 2)
+ goto execute;
+ break;
+ }
+ case 3: { // read multi
+ int multi = g_paramters[P_MULTI].value;
+ int tot = g_paramters[P_ROWS].value;
+ for(; multi > 0 && i < iter; --multi, i++)
+ {
+ int row = rand() % tot;
+ pIOp->setBound((Uint32)0, NdbIndexScanOperation::BoundEQ, &row);
+ pIOp->end_of_bound(i);
+ }
+ if(g_paramters[P_RESET].value == 2)
+ goto execute;
break;
}
}
- if(g_paramters[P_RESET].value == 2)
- goto execute;
}
assert(pOp);
- assert(rs);
switch(g_paramters[P_FILT].value){
case 0: // All
@@ -337,15 +319,18 @@ run_scan(){
for(int i = 0; i<g_table->getNoOfColumns(); i++){
pOp->getValue(i);
}
+
+ if(g_paramters[P_RESET].value == 1)
+ g_paramters[P_RESET].value = 2;
execute:
int rows = 0;
check = pTrans->execute(NoCommit);
assert(check == 0);
int fetch = g_paramters[P_FETCH].value;
- while((check = rs->nextResult(true)) == 0){
+ while((check = pOp->nextResult(true)) == 0){
do {
rows++;
- } while(!fetch && ((check = rs->nextResult(false)) == 0));
+ } while(!fetch && ((check = pOp->nextResult(false)) == 0));
if(check == -1){
err(pTrans->getNdbError());
return -1;
diff --git a/ndb/test/ndbapi/testTimeout.cpp b/ndb/test/ndbapi/testTimeout.cpp
index 71c11b25859..b02751ec819 100644
--- a/ndb/test/ndbapi/testTimeout.cpp
+++ b/ndb/test/ndbapi/testTimeout.cpp
@@ -87,47 +87,6 @@ int runClearTable(NDBT_Context* ctx, NDBT_Step* step){
result = NDBT_FAILED; \
break; }
-int runTimeoutTrans(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();
-
- int timeout = ctx->getProperty("TransactionInactiveTimeout",TIMEOUT);
-
- int minSleep = (int)(timeout * 1.5);
- int maxSleep = timeout * 2;
- ndbout << "TransactionInactiveTimeout="<< timeout
- << ", minSleep="<<minSleep
- << ", maxSleep="<<maxSleep<<endl;
-
- HugoOperations hugoOps(*ctx->getTab());
- Ndb* pNdb = GETNDB(step);
-
- for (int l = 0; l < loops && result == NDBT_OK; l++){
-
- do{
- // Commit transaction
- CHECK(hugoOps.startTransaction(pNdb) == 0);
- CHECK(hugoOps.pkReadRecord(pNdb, stepNo) == 0);
- CHECK(hugoOps.execute_NoCommit(pNdb) == 0);
-
- int sleep = minSleep + myRandom48(maxSleep-minSleep);
- ndbout << "Sleeping for " << sleep << " milliseconds" << endl;
- NdbSleep_MilliSleep(sleep);
-
- // Expect that transaction has timed-out
- CHECK(hugoOps.execute_Commit(pNdb) == 237);
-
- } while(false);
-
- hugoOps.closeTransaction(pNdb);
- }
-
- return result;
-}
-
int runTimeoutTrans2(NDBT_Context* ctx, NDBT_Step* step){
int result = NDBT_OK;
int loops = ctx->getNumLoops();
@@ -407,27 +366,6 @@ TESTCASE("DontTimeoutTransaction5",
FINALIZER(resetTransactionTimeout);
FINALIZER(runClearTable);
}
-TESTCASE("TimeoutTransaction",
- "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);
- STEPS(runTimeoutTrans, 1);
- FINALIZER(resetTransactionTimeout);
- FINALIZER(runClearTable);
-}
-TESTCASE("TimeoutTransaction5",
- "Test that the transaction does timeout " \
- "if we sleep during the transaction. Use a sleep " \
- "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 "\
diff --git a/ndb/test/ndbapi/test_event.cpp b/ndb/test/ndbapi/test_event.cpp
index cb2793e42b9..2df50f21e43 100644
--- a/ndb/test/ndbapi/test_event.cpp
+++ b/ndb/test/ndbapi/test_event.cpp
@@ -14,11 +14,11 @@
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
-#include "NDBT_Test.hpp"
-#include "NDBT_ReturnCodes.h"
-#include "HugoTransactions.hpp"
-#include "UtilTransactions.hpp"
-#include "TestNdbEventOperation.hpp"
+#include <NDBT_Test.hpp>
+#include <NDBT_ReturnCodes.h>
+#include <HugoTransactions.hpp>
+#include <UtilTransactions.hpp>
+#include <TestNdbEventOperation.hpp>
#define GETNDB(ps) ((NDBT_NdbApiStep*)ps)->getNdb()
@@ -32,6 +32,69 @@ int runCreateEvent(NDBT_Context* ctx, NDBT_Step* step)
return NDBT_OK;
}
+int runCreateShadowTable(NDBT_Context* ctx, NDBT_Step* step)
+{
+ const NdbDictionary::Table *table= ctx->getTab();
+ char buf[1024];
+ sprintf(buf, "%s_SHADOW", table->getName());
+
+ GETNDB(step)->getDictionary()->dropTable(buf);
+ if (GETNDB(step)->getDictionary()->getTable(buf))
+ {
+ g_err << "unsucessful drop of " << buf << endl;
+ return NDBT_FAILED;
+ }
+
+ NdbDictionary::Table table_shadow(*table);
+ table_shadow.setName(buf);
+ GETNDB(step)->getDictionary()->createTable(table_shadow);
+ if (GETNDB(step)->getDictionary()->getTable(buf))
+ return NDBT_OK;
+
+ g_err << "unsucessful create of " << buf << endl;
+ return NDBT_FAILED;
+}
+
+int runCreateDropEventOperation(NDBT_Context* ctx, NDBT_Step* step)
+{
+ int loops = ctx->getNumLoops();
+ int records = ctx->getNumRecords();
+ HugoTransactions hugoTrans(*ctx->getTab());
+ EventOperationStats stats;
+
+ Ndb *pNdb=GETNDB(step);
+ const NdbDictionary::Table& tab= *ctx->getTab();
+ NdbEventOperation *pOp;
+ char eventName[1024];
+ sprintf(eventName,"%s_EVENT",tab.getName());
+ int noEventColumnName = tab.getNoOfColumns();
+
+ for (int i= 0; i < loops; i++)
+ {
+#if 1
+ if (hugoTrans.eventOperation(GETNDB(step), (void*)&stats, 0) != 0){
+ return NDBT_FAILED;
+ }
+#else
+ g_info << "create EventOperation\n";
+ pOp = pNdb->createEventOperation(eventName, 100);
+ if ( pOp == NULL ) {
+ g_err << "Event operation creation failed\n";
+ return NDBT_FAILED;
+ }
+
+ g_info << "dropping event operation" << endl;
+ int res = pNdb->dropEventOperation(pOp);
+ if (res != 0) {
+ g_err << "operation execution failed\n";
+ return NDBT_FAILED;
+ }
+#endif
+ }
+
+ return NDBT_OK;
+}
+
int theThreadIdCounter = 0;
int runEventOperation(NDBT_Context* ctx, NDBT_Step* step)
@@ -43,7 +106,7 @@ int runEventOperation(NDBT_Context* ctx, NDBT_Step* step)
EventOperationStats stats;
- g_info << "***** Id " << tId << endl;
+ g_info << "***** start Id " << tId << endl;
// sleep(tId);
@@ -62,12 +125,13 @@ int runEventOperation(NDBT_Context* ctx, NDBT_Step* step)
ret = NDBT_FAILED;
if (ret == NDBT_FAILED) {
- ndbout << "n_inserts = " << stats.n_inserts << endl;
- ndbout << "n_deletes = " << stats.n_deletes << endl;
- ndbout << "n_updates = " << stats.n_updates << endl;
- ndbout << "n_consecutive = " << stats.n_consecutive << endl;
- ndbout << "n_duplicates = " << stats.n_duplicates << endl;
- ndbout << "n_inconsistent_gcis = " << stats.n_inconsistent_gcis << endl;
+ g_info << "***** end Id " << tId << endl;
+ ndbout_c("n_inserts = %d (%d)", stats.n_inserts, records);
+ ndbout_c("n_deletes = %d (%d)", stats.n_deletes, records);
+ ndbout_c("n_updates = %d (%d)", stats.n_updates, records);
+ ndbout_c("n_consecutive = %d (%d)", stats.n_consecutive, 3);
+ ndbout_c("n_duplicates = %d (%d)", stats.n_duplicates, 0);
+ ndbout_c("n_inconsistent_gcis = %d (%d)", stats.n_inconsistent_gcis, 0);
}
return ret;
@@ -94,6 +158,36 @@ int runEventLoad(NDBT_Context* ctx, NDBT_Step* step)
return NDBT_OK;
}
+int runEventMixedLoad(NDBT_Context* ctx, NDBT_Step* step)
+{
+ int loops = ctx->getNumLoops();
+ int records = ctx->getNumRecords();
+ HugoTransactions hugoTrans(*ctx->getTab());
+
+ sleep(5);
+
+ if (hugoTrans.loadTable(GETNDB(step), 3*records, 1, true, 1) != 0){
+ return NDBT_FAILED;
+ }
+ if (hugoTrans.pkDelRecords(GETNDB(step), 3*records, 1, true, 1) != 0){
+ return NDBT_FAILED;
+ }
+ if (hugoTrans.loadTable(GETNDB(step), records, 1, true, 1) != 0){
+ return NDBT_FAILED;
+ }
+ if (hugoTrans.pkUpdateRecords(GETNDB(step), records, 1, 1) != 0){
+ return NDBT_FAILED;
+ }
+ if (hugoTrans.pkUpdateRecords(GETNDB(step), records, 1, 1) != 0){
+ return NDBT_FAILED;
+ }
+ if (hugoTrans.pkUpdateRecords(GETNDB(step), records, 1, 1) != 0){
+ return NDBT_FAILED;
+ }
+
+ return NDBT_OK;
+}
+
int runDropEvent(NDBT_Context* ctx, NDBT_Step* step)
{
HugoTransactions hugoTrans(*ctx->getTab());
@@ -105,6 +199,246 @@ int runDropEvent(NDBT_Context* ctx, NDBT_Step* step)
return NDBT_OK;
}
+int runVerify(NDBT_Context* ctx, NDBT_Step* step)
+{
+ int records = ctx->getNumRecords();
+ const NdbDictionary::Table * table= ctx->getTab();
+ char buf[1024];
+
+ sprintf(buf, "%s_SHADOW", table->getName());
+
+ HugoTransactions hugoTrans(*table);
+ if (hugoTrans.compare(GETNDB(step), buf, 0))
+ {
+ return NDBT_FAILED;
+ }
+
+ return NDBT_OK;
+}
+
+int runEventApplier(NDBT_Context* ctx, NDBT_Step* step)
+{
+ DBUG_ENTER("runEventApplier");
+
+ int records = ctx->getNumRecords();
+ int loops = ctx->getNumLoops();
+ const NdbDictionary::Table * table= ctx->getTab();
+ char buf[1024];
+
+ sprintf(buf, "%s_SHADOW", table->getName());
+ const NdbDictionary::Table * table_shadow;
+ if ((table_shadow = GETNDB(step)->getDictionary()->getTable(buf)) == 0)
+ {
+ g_err << "Unable to get table " << buf << endl;
+ DBUG_RETURN(NDBT_FAILED);
+ }
+
+ sprintf(buf, "%s_EVENT", table->getName());
+ NdbEventOperation *pOp;
+ pOp = GETNDB(step)->createEventOperation(buf, 10*records);
+ if ( pOp == NULL ) {
+ g_err << "Event operation creation failed on %s" << buf << endl;
+ DBUG_RETURN(NDBT_FAILED);
+ }
+
+ int i;
+ int n_columns= table->getNoOfColumns();
+ NdbRecAttr* recAttr[1024];
+ NdbRecAttr* recAttrPre[1024];
+ for (i = 0; i < n_columns; i++) {
+ recAttr[i] = pOp->getValue(table->getColumn(i)->getName());
+ recAttrPre[i] = pOp->getPreValue(table->getColumn(i)->getName());
+ }
+
+ if (pOp->execute()) { // This starts changes to "start flowing"
+ g_err << "execute operation execution failed: \n";
+ g_err << pOp->getNdbError().code << " "
+ << pOp->getNdbError().message << endl;
+ DBUG_RETURN(NDBT_FAILED);
+ }
+
+ int r= 0;
+ int res;
+ while (r < 10*records){
+ //printf("now waiting for event...\n");
+ res= GETNDB(step)->pollEvents(1000); // wait for event or 1000 ms
+ if (res <= 0)
+ {
+ ndbout_c("********************");
+ continue;
+ }
+
+ //printf("got data! %d\n", r);
+ int overrun= 0;
+ while (pOp->next(&overrun) > 0)
+ {
+ if (overrun)
+ {
+ g_err << "buffer overrun\n";
+ DBUG_RETURN(NDBT_FAILED);
+ }
+ r++;
+
+ Uint32 gci= pOp->getGCI();
+
+ if (!pOp->isConsistent()) {
+ g_err << "A node failure has occured and events might be missing\n";
+ DBUG_RETURN(NDBT_FAILED);
+ }
+
+ int noRetries= 0;
+ do
+ {
+ NdbTransaction *trans= GETNDB(step)->startTransaction();
+ if (trans == 0)
+ {
+ g_err << "startTransaction failed "
+ << GETNDB(step)->getNdbError().code << " "
+ << GETNDB(step)->getNdbError().message << endl;
+ DBUG_RETURN(NDBT_FAILED);
+ }
+
+ NdbOperation *op= trans->getNdbOperation(table_shadow);
+ if (op == 0)
+ {
+ g_err << "getNdbOperation failed "
+ << trans->getNdbError().code << " "
+ << trans->getNdbError().message << endl;
+ DBUG_RETURN(NDBT_FAILED);
+ }
+
+ switch (pOp->getEventType()) {
+ case NdbDictionary::Event::TE_INSERT:
+ if (op->insertTuple())
+ {
+ g_err << "insertTuple "
+ << op->getNdbError().code << " "
+ << op->getNdbError().message << endl;
+ DBUG_RETURN(NDBT_FAILED);
+ }
+ break;
+ case NdbDictionary::Event::TE_DELETE:
+ if (op->deleteTuple())
+ {
+ g_err << "deleteTuple "
+ << op->getNdbError().code << " "
+ << op->getNdbError().message << endl;
+ DBUG_RETURN(NDBT_FAILED);
+ }
+ break;
+ case NdbDictionary::Event::TE_UPDATE:
+ if (op->updateTuple())
+ {
+ g_err << "updateTuple "
+ << op->getNdbError().code << " "
+ << op->getNdbError().message << endl;
+ DBUG_RETURN(NDBT_FAILED);
+ }
+ break;
+ default:
+ abort();
+ }
+
+ for (i= 0; i < n_columns; i++)
+ {
+ if (recAttr[i]->isNULL())
+ {
+ if (table->getColumn(i)->getPrimaryKey())
+ {
+ g_err << "internal error: primary key isNull()="
+ << recAttr[i]->isNULL() << endl;
+ DBUG_RETURN(NDBT_FAILED);
+ }
+ switch (pOp->getEventType()) {
+ case NdbDictionary::Event::TE_INSERT:
+ if (recAttr[i]->isNULL() < 0)
+ {
+ g_err << "internal error: missing value for insert\n";
+ DBUG_RETURN(NDBT_FAILED);
+ }
+ break;
+ case NdbDictionary::Event::TE_DELETE:
+ break;
+ case NdbDictionary::Event::TE_UPDATE:
+ break;
+ default:
+ abort();
+ }
+ }
+ if (table->getColumn(i)->getPrimaryKey() &&
+ op->equal(i,recAttr[i]->aRef()))
+ {
+ g_err << "equal " << i << " "
+ << op->getNdbError().code << " "
+ << op->getNdbError().message << endl;
+ DBUG_RETURN(NDBT_FAILED);
+ }
+ }
+
+ switch (pOp->getEventType()) {
+ case NdbDictionary::Event::TE_INSERT:
+ for (i= 0; i < n_columns; i++)
+ {
+ if (!table->getColumn(i)->getPrimaryKey() &&
+ op->setValue(i,recAttr[i]->isNULL() ? 0:recAttr[i]->aRef()))
+ {
+ g_err << "setValue(insert) " << i << " "
+ << op->getNdbError().code << " "
+ << op->getNdbError().message << endl;
+ DBUG_RETURN(NDBT_FAILED);
+ }
+ }
+ break;
+ case NdbDictionary::Event::TE_DELETE:
+ break;
+ case NdbDictionary::Event::TE_UPDATE:
+ for (i= 0; i < n_columns; i++)
+ {
+ if (!table->getColumn(i)->getPrimaryKey() &&
+ recAttr[i]->isNULL() >= 0 &&
+ op->setValue(i,recAttr[i]->isNULL() ? 0:recAttr[i]->aRef()))
+ {
+ g_err << "setValue(update) " << i << " "
+ << op->getNdbError().code << " "
+ << op->getNdbError().message << endl;
+ DBUG_RETURN(NDBT_FAILED);
+ }
+ }
+ break;
+ case NdbDictionary::Event::TE_ALL:
+ abort();
+ }
+ if (trans->execute(Commit) == 0)
+ {
+ trans->close();
+ // everything ok
+ break;
+ }
+ if (noRetries++ == 10 ||
+ trans->getNdbError().status != NdbError::TemporaryError)
+ {
+ g_err << "execute " << r << " failed "
+ << trans->getNdbError().code << " "
+ << trans->getNdbError().message << endl;
+ trans->close();
+ DBUG_RETURN(NDBT_FAILED);
+ }
+ trans->close();
+ NdbSleep_MilliSleep(100); // sleep before retying
+ } while(1);
+ }
+ }
+
+ if (GETNDB(step)->dropEventOperation(pOp)) {
+ g_err << "dropEventOperation execution failed "
+ << GETNDB(step)->getNdbError().code << " "
+ << GETNDB(step)->getNdbError().message << endl;
+ DBUG_RETURN(NDBT_FAILED);
+ }
+
+ DBUG_RETURN(NDBT_OK);
+}
+
// INITIALIZER(runInsert);
// STEP(runPkRead);
// VERIFIER(runVerifyInsert);
@@ -116,25 +450,37 @@ TESTCASE("BasicEventOperation",
"NOTE! No errors are allowed!" ){
INITIALIZER(runCreateEvent);
STEP(runEventOperation);
- STEP(runEventOperation);
- STEP(runEventOperation);
- STEP(runEventOperation);
STEP(runEventLoad);
FINALIZER(runDropEvent);
}
-NDBT_TESTSUITE_END(test_event);
-
-#if 0
-NDBT_TESTSUITE(test_event);
+TESTCASE("CreateDropEventOperation",
+ "Verify that we can Create and Drop many times"
+ "NOTE! No errors are allowed!" ){
+ INITIALIZER(runCreateEvent);
+ STEP(runCreateDropEventOperation);
+ FINALIZER(runDropEvent);
+}
TESTCASE("ParallellEventOperation",
- "Verify that we can listen to Events in Parallell"
+ "Verify that we can listen to Events in parallell"
"NOTE! No errors are allowed!" ){
- INITIALIZER(runCreateAllEvent);
+ INITIALIZER(runCreateEvent);
+ STEP(runEventOperation);
STEP(runEventOperation);
+ STEP(runEventLoad);
+ FINALIZER(runDropEvent);
+}
+TESTCASE("EventOperationApplier",
+ "Verify that if we apply the data we get from event "
+ "operation is the same as the original table"
+ "NOTE! No errors are allowed!" ){
+ INITIALIZER(runCreateEvent);
+ INITIALIZER(runCreateShadowTable);
+ STEP(runEventApplier);
+ STEP(runEventMixedLoad);
FINALIZER(runDropEvent);
+ FINALIZER(runVerify);
}
NDBT_TESTSUITE_END(test_event);
-#endif
int main(int argc, const char** argv){
ndb_init();
diff --git a/ndb/test/ndbapi/test_event_multi_table.cpp b/ndb/test/ndbapi/test_event_multi_table.cpp
new file mode 100644
index 00000000000..f16504029fa
--- /dev/null
+++ b/ndb/test/ndbapi/test_event_multi_table.cpp
@@ -0,0 +1,487 @@
+/* Copyright (C) 2005 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 <ndb_opts.h>
+#include <NDBT_Test.hpp>
+#include <NDBT_ReturnCodes.h>
+#include <HugoTransactions.hpp>
+#include <UtilTransactions.hpp>
+#include <TestNdbEventOperation.hpp>
+
+static void usage()
+{
+ ndb_std_print_version();
+}
+
+static int start_transaction(Ndb *ndb, Vector<HugoOperations*> &ops)
+{
+ if (ops[0]->startTransaction(ndb) != NDBT_OK)
+ return -1;
+ NdbTransaction * t= ops[0]->getTransaction();
+ for (int i= ops.size()-1; i > 0; i--)
+ {
+ ops[i]->setTransaction(t);
+ }
+ return 0;
+}
+
+static int close_transaction(Ndb *ndb, Vector<HugoOperations*> &ops)
+{
+ if (ops[0]->closeTransaction(ndb) != NDBT_OK)
+ return -1;
+ for (int i= ops.size()-1; i > 0; i--)
+ {
+ ops[i]->setTransaction(NULL);
+ }
+ return 0;
+}
+
+static int execute_commit(Ndb *ndb, Vector<HugoOperations*> &ops)
+{
+ if (ops[0]->execute_Commit(ndb) != NDBT_OK)
+ return -1;
+ return 0;
+}
+
+static int copy_events(Ndb *ndb,
+ Vector<NdbEventOperation *> &ops,
+ Vector<const NdbDictionary::Table *> &tabs,
+ Vector<Vector<NdbRecAttr *> > &values)
+{
+ DBUG_ENTER("copy_events");
+ int r= 0;
+ while (1)
+ {
+ int res= ndb->pollEvents(1000); // wait for event or 1000 ms
+ DBUG_PRINT("info", ("pollEvents res=%d", r));
+ if (res <= 0)
+ {
+ break;
+ }
+ for (unsigned i_ops= 0; i_ops < ops.size(); i_ops++)
+ {
+ NdbEventOperation *pOp= ops[i_ops];
+ const NdbDictionary::Table *table= tabs[i_ops];
+ Vector<NdbRecAttr *> &recAttr= values[i_ops];
+
+ int overrun= 0;
+ unsigned i;
+ unsigned n_columns= table->getNoOfColumns();
+ while (pOp->next(&overrun) > 0)
+ {
+ if (overrun)
+ {
+ g_err << "buffer overrun\n";
+ DBUG_RETURN(-1);
+ }
+ r++;
+
+ Uint32 gci= pOp->getGCI();
+
+ if (!pOp->isConsistent()) {
+ g_err << "A node failure has occured and events might be missing\n";
+ DBUG_RETURN(-1);
+ }
+
+ int noRetries= 0;
+ do
+ {
+ NdbTransaction *trans= ndb->startTransaction();
+ if (trans == 0)
+ {
+ g_err << "startTransaction failed "
+ << ndb->getNdbError().code << " "
+ << ndb->getNdbError().message << endl;
+ DBUG_RETURN(-1);
+ }
+
+ NdbOperation *op= trans->getNdbOperation(table);
+ if (op == 0)
+ {
+ g_err << "getNdbOperation failed "
+ << trans->getNdbError().code << " "
+ << trans->getNdbError().message << endl;
+ DBUG_RETURN(-1);
+ }
+
+ switch (pOp->getEventType()) {
+ case NdbDictionary::Event::TE_INSERT:
+ if (op->insertTuple())
+ {
+ g_err << "insertTuple "
+ << op->getNdbError().code << " "
+ << op->getNdbError().message << endl;
+ DBUG_RETURN(-1);
+ }
+ break;
+ case NdbDictionary::Event::TE_DELETE:
+ if (op->deleteTuple())
+ {
+ g_err << "deleteTuple "
+ << op->getNdbError().code << " "
+ << op->getNdbError().message << endl;
+ DBUG_RETURN(-1);
+ }
+ break;
+ case NdbDictionary::Event::TE_UPDATE:
+ if (op->updateTuple())
+ {
+ g_err << "updateTuple "
+ << op->getNdbError().code << " "
+ << op->getNdbError().message << endl;
+ DBUG_RETURN(-1);
+ }
+ break;
+ default:
+ abort();
+ }
+
+ for (i= 0; i < n_columns; i++)
+ {
+ if (recAttr[i]->isNULL())
+ {
+ if (table->getColumn(i)->getPrimaryKey())
+ {
+ g_err << "internal error: primary key isNull()="
+ << recAttr[i]->isNULL() << endl;
+ DBUG_RETURN(NDBT_FAILED);
+ }
+ switch (pOp->getEventType()) {
+ case NdbDictionary::Event::TE_INSERT:
+ if (recAttr[i]->isNULL() < 0)
+ {
+ g_err << "internal error: missing value for insert\n";
+ DBUG_RETURN(NDBT_FAILED);
+ }
+ break;
+ case NdbDictionary::Event::TE_DELETE:
+ break;
+ case NdbDictionary::Event::TE_UPDATE:
+ break;
+ default:
+ abort();
+ }
+ }
+ if (table->getColumn(i)->getPrimaryKey() &&
+ op->equal(i,recAttr[i]->aRef()))
+ {
+ g_err << "equal " << i << " "
+ << op->getNdbError().code << " "
+ << op->getNdbError().message << endl;
+ DBUG_RETURN(NDBT_FAILED);
+ }
+ }
+
+ switch (pOp->getEventType()) {
+ case NdbDictionary::Event::TE_INSERT:
+ for (i= 0; i < n_columns; i++)
+ {
+ if (!table->getColumn(i)->getPrimaryKey() &&
+ op->setValue(i,recAttr[i]->isNULL() ? 0:recAttr[i]->aRef()))
+ {
+ g_err << "setValue(insert) " << i << " "
+ << op->getNdbError().code << " "
+ << op->getNdbError().message << endl;
+ DBUG_RETURN(-1);
+ }
+ }
+ break;
+ case NdbDictionary::Event::TE_DELETE:
+ break;
+ case NdbDictionary::Event::TE_UPDATE:
+ for (i= 0; i < n_columns; i++)
+ {
+ if (!table->getColumn(i)->getPrimaryKey() &&
+ recAttr[i]->isNULL() >= 0 &&
+ op->setValue(i,recAttr[i]->isNULL() ? 0:recAttr[i]->aRef()))
+ {
+ g_err << "setValue(update) " << i << " "
+ << op->getNdbError().code << " "
+ << op->getNdbError().message << endl;
+ DBUG_RETURN(NDBT_FAILED);
+ }
+ }
+ break;
+ case NdbDictionary::Event::TE_ALL:
+ abort();
+ }
+ if (trans->execute(Commit) == 0)
+ {
+ trans->close();
+ // everything ok
+ break;
+ }
+ if (noRetries++ == 10 ||
+ trans->getNdbError().status != NdbError::TemporaryError)
+ {
+ g_err << "execute " << r << " failed "
+ << trans->getNdbError().code << " "
+ << trans->getNdbError().message << endl;
+ trans->close();
+ DBUG_RETURN(-1);
+ }
+ trans->close();
+ NdbSleep_MilliSleep(100); // sleep before retying
+ } while(1);
+ }
+ }
+ }
+ DBUG_RETURN(r);
+}
+
+static int verify_copy(Ndb *ndb,
+ Vector<const NdbDictionary::Table *> &tabs1,
+ Vector<const NdbDictionary::Table *> &tabs2)
+{
+ for (unsigned i= 0; i < tabs1.size(); i++)
+ if (tabs1[i])
+ {
+ HugoTransactions hugoTrans(*tabs1[i]);
+ if (hugoTrans.compare(ndb, tabs2[i]->getName(), 0))
+ return -1;
+ }
+ return 0;
+}
+
+NDB_STD_OPTS_VARS;
+
+static const char* _dbname = "TEST_DB";
+static struct my_option my_long_options[] =
+{
+ NDB_STD_OPTS(""),
+ { "database", 'd', "Name of database table is in",
+ (gptr*) &_dbname, (gptr*) &_dbname, 0,
+ GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0 },
+ { 0, 0, 0, 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0}
+};
+
+int
+main(int argc, char** argv)
+{
+ NDB_INIT(argv[0]);
+ const char *load_default_groups[]= { "mysql_cluster",0 };
+ load_defaults("my",load_default_groups,&argc,&argv);
+
+ int ho_error;
+#ifndef DBUG_OFF
+ opt_debug= "d:t:F:L";
+#endif
+ if ((ho_error=handle_options(&argc, &argv, my_long_options,
+ ndb_std_get_one_option)))
+ return NDBT_ProgramExit(NDBT_WRONGARGS);
+
+ DBUG_ENTER("main");
+ Ndb_cluster_connection con(opt_connect_str);
+ if(con.connect(12, 5, 1))
+ {
+ DBUG_RETURN(NDBT_ProgramExit(NDBT_FAILED));
+ }
+
+
+ Ndb ndb(&con,_dbname);
+ ndb.init();
+ while (ndb.waitUntilReady() != 0);
+
+ NdbDictionary::Dictionary * dict = ndb.getDictionary();
+ int no_error= 1;
+ int i;
+
+ // create all tables
+ Vector<const NdbDictionary::Table*> pTabs;
+ for (i= 0; no_error && argc; argc--, i++)
+ {
+ dict->dropTable(argv[i]);
+ NDBT_Tables::createTable(&ndb, argv[i]);
+ const NdbDictionary::Table *pTab= dict->getTable(argv[i]);
+ if (pTab == 0)
+ {
+ ndbout << "Failed to create table" << endl;
+ ndbout << dict->getNdbError() << endl;
+ no_error= 0;
+ break;
+ }
+ pTabs.push_back(pTab);
+ }
+ pTabs.push_back(NULL);
+
+ // create an event for each table
+ for (i= 0; no_error && pTabs[i]; i++)
+ {
+ HugoTransactions ht(*pTabs[i]);
+ if (ht.createEvent(&ndb)){
+ no_error= 0;
+ break;
+ }
+ }
+
+ // create an event operation for each event
+ Vector<NdbEventOperation *> pOps;
+ for (i= 0; no_error && pTabs[i]; i++)
+ {
+ char buf[1024];
+ sprintf(buf, "%s_EVENT", pTabs[i]->getName());
+ NdbEventOperation *pOp= ndb.createEventOperation(buf, 1000);
+ if ( pOp == NULL )
+ {
+ no_error= 0;
+ break;
+ }
+ pOps.push_back(pOp);
+ }
+
+ // get storage for each event operation
+ Vector<Vector<NdbRecAttr*> > values;
+ Vector<Vector<NdbRecAttr*> > pre_values;
+ for (i= 0; no_error && pTabs[i]; i++)
+ {
+ int n_columns= pTabs[i]->getNoOfColumns();
+ Vector<NdbRecAttr*> tmp_a;
+ Vector<NdbRecAttr*> tmp_b;
+ for (int j = 0; j < n_columns; j++) {
+ tmp_a.push_back(pOps[i]->getValue(pTabs[i]->getColumn(j)->getName()));
+ tmp_b.push_back(pOps[i]->getPreValue(pTabs[i]->getColumn(j)->getName()));
+ }
+ values.push_back(tmp_a);
+ pre_values.push_back(tmp_b);
+ }
+
+ // start receiving events
+ for (i= 0; no_error && pTabs[i]; i++)
+ {
+ if ( pOps[i]->execute() )
+ {
+ no_error= 0;
+ break;
+ }
+ }
+
+ // create a "shadow" table for each table
+ Vector<const NdbDictionary::Table*> pShadowTabs;
+ for (i= 0; no_error && pTabs[i]; i++)
+ {
+ char buf[1024];
+ sprintf(buf, "%s_SHADOW", pTabs[i]->getName());
+
+ dict->dropTable(buf);
+ if (dict->getTable(buf))
+ {
+ no_error= 0;
+ break;
+ }
+
+ NdbDictionary::Table table_shadow(*pTabs[i]);
+ table_shadow.setName(buf);
+ dict->createTable(table_shadow);
+ pShadowTabs.push_back(dict->getTable(buf));
+ if (!pShadowTabs[i])
+ {
+ no_error= 0;
+ break;
+ }
+ }
+
+ // create a hugo operation per table
+ Vector<HugoOperations *> hugo_ops;
+ for (i= 0; no_error && pTabs[i]; i++)
+ {
+ hugo_ops.push_back(new HugoOperations(*pTabs[i]));
+ }
+
+ sleep(5);
+
+ // insert 3 records per table
+ do {
+ if (start_transaction(&ndb, hugo_ops))
+ {
+ no_error= 0;
+ break;
+ }
+ for (i= 0; no_error && pTabs[i]; i++)
+ {
+ hugo_ops[i]->pkInsertRecord(&ndb, 0, 3);
+ }
+ if (execute_commit(&ndb, hugo_ops))
+ {
+ no_error= 0;
+ break;
+ }
+ if(close_transaction(&ndb, hugo_ops))
+ {
+ no_error= 0;
+ break;
+ }
+ } while(0);
+
+ // copy events and verify
+ do {
+ if (copy_events(&ndb, pOps, pShadowTabs, values) < 0)
+ {
+ no_error= 0;
+ break;
+ }
+ if (verify_copy(&ndb, pTabs, pShadowTabs))
+ {
+ no_error= 0;
+ break;
+ }
+ } while (0);
+
+ // update 2 records in first table
+ do {
+ if (start_transaction(&ndb, hugo_ops))
+ {
+ no_error= 0;
+ break;
+ }
+
+ hugo_ops[0]->pkUpdateRecord(&ndb, 2);
+
+ if (execute_commit(&ndb, hugo_ops))
+ {
+ no_error= 0;
+ break;
+ }
+ if(close_transaction(&ndb, hugo_ops))
+ {
+ no_error= 0;
+ break;
+ }
+ } while(0);
+
+ // copy events and verify
+ do {
+ if (copy_events(&ndb, pOps, pShadowTabs, values) < 0)
+ {
+ no_error= 0;
+ break;
+ }
+ if (verify_copy(&ndb, pTabs, pShadowTabs))
+ {
+ no_error= 0;
+ break;
+ }
+ } while (0);
+
+ if (no_error)
+ DBUG_RETURN(NDBT_ProgramExit(NDBT_OK));
+ DBUG_RETURN(NDBT_ProgramExit(NDBT_FAILED));
+}
+
+template class Vector<HugoOperations *>;
+template class Vector<NdbEventOperation *>;
+template class Vector<NdbRecAttr*>;
+template class Vector<Vector<NdbRecAttr*> >;
diff --git a/ndb/test/run-test/16node-tests.txt b/ndb/test/run-test/16node-tests.txt
new file mode 100644
index 00000000000..11ade56c28c
--- /dev/null
+++ b/ndb/test/run-test/16node-tests.txt
@@ -0,0 +1,733 @@
+# 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
+
+max-time: 500
+cmd: testTimeout
+args: 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: 500
+cmd: testScan
+args: -n ScanRead488O -l 10 T6
+
+max-time: 1000
+cmd: testScan
+args: -n ScanRead488_Mixed -l 10 T6
+
+max-time: 500
+cmd: testScan
+args: -n ScanRead488Timeout -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: 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
+
+max-time: 500
+cmd: testScan
+args: -n ScanParallelism
+
+#
+# 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 FragmentTypeAllSmall 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: 150000
+cmd: testOperations
+args:
+
+max-time: 15000
+cmd: testTransactions
+args:
+
+max-time: 1500
+cmd: testRestartGci
+args: T6
+
+max-time: 600
+cmd: testBlobs
+args:
+
+max-time: 5000
+cmd: testOIBasic
+args:
+
+max-time: 2500
+cmd: testBitfield
+args:
+
+max-time: 2500
+cmd: testPartitioning
+args:
+
+max-time: 25000
+cmd: atrt-mysql-test-run
+args: --force
+
+#
+# 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: atrt-testBackup
+args: -n BackupOne T1 T6 T3 I3
+
+#
+#
+# SYSTEM RESTARTS
+#
+max-time: 1500
+cmd: testSystemRestart
+args: -n SR3 T6
+
+max-time: 1500
+cmd: testSystemRestart
+args: -n SR4 T6
+
+#
+# NODE RESTARTS
+#
+max-time: 2500
+cmd: testNodeRestart
+args: -n NoLoad T6
+
+max-time: 2500
+cmd: testNodeRestart
+args: -n MixedPkRead T6 T8 T13
+
+max-time: 2500
+cmd: testNodeRestart
+args: -l 1 -n MixedPkReadPkUpdate
+
+max-time: 2500
+cmd: testNodeRestart
+args: -l 1 -n MixedReadUpdateScan
+
+max-time: 2500
+cmd: testNodeRestart
+args: -n CommittedRead T1
+
+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: 1500
+cmd: testSystemRestart
+args: -l 1 -n SR6 T1
+
+max-time: 1500
+cmd: testSystemRestart
+args: -l 1 -n SR7 T1
+
+max-time: 1500
+cmd: testSystemRestart
+args: -l 1 -n SR8 T1
+
+max-time: 1500
+cmd: testSystemRestart
+args: -l 1 -n SR9 T1
+
+#
+max-time: 2500
+cmd: test_event
+args: -n BasicEventOperation T1 T6
+
+#
+#
+# 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
+
+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
+
+# OLD FLEX
+max-time: 500
+cmd: flexBench
+args: -c 25 -t 10
+
+max-time: 500
+cmd: flexHammer
+args: -r 5 -t 32
+
diff --git a/ndb/test/run-test/Makefile.am b/ndb/test/run-test/Makefile.am
index cf08542ae97..60d64a7697f 100644
--- a/ndb/test/run-test/Makefile.am
+++ b/ndb/test/run-test/Makefile.am
@@ -6,7 +6,7 @@ include $(top_srcdir)/ndb/config/type_util.mk.am
include $(top_srcdir)/ndb/config/type_mgmapiclient.mk.am
test_PROGRAMS = atrt
-test_DATA=daily-basic-tests.txt daily-devel-tests.txt \
+test_DATA=daily-basic-tests.txt daily-devel-tests.txt 16node-tests.txt \
conf-daily-basic-ndbmaster.txt \
conf-daily-basic-shark.txt \
conf-daily-devel-ndbmaster.txt \
diff --git a/ndb/test/run-test/basic.txt b/ndb/test/run-test/basic.txt
index a952320db08..ec9e21359e5 100644
--- a/ndb/test/run-test/basic.txt
+++ b/ndb/test/run-test/basic.txt
@@ -374,7 +374,7 @@ args: -n FragmentTypeSingle T1
max-time: 1500
cmd: testDict
-args: -n FragmentTypeAll T1 T6 T7 T8
+args: -n FragmentTypeAllSmall T1 T6 T7 T8
max-time: 1500
cmd: testDict
diff --git a/ndb/test/run-test/daily-basic-tests.txt b/ndb/test/run-test/daily-basic-tests.txt
index fc04664564f..8b44594a9b5 100644
--- a/ndb/test/run-test/daily-basic-tests.txt
+++ b/ndb/test/run-test/daily-basic-tests.txt
@@ -75,7 +75,7 @@ max-time: 500
cmd: testBasic
args: -n PkInsert
-max-time: 600
+max-time: 660
cmd: testBasic
args: -n UpdateAndRead
@@ -207,34 +207,9 @@ 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
+args: T1
# SCAN TESTS
#
@@ -434,14 +409,9 @@ max-time: 500
cmd: testScan
args: -l 100 -n Scan-bug8262 T7
-# OLD FLEX
max-time: 500
-cmd: flexBench
-args: -c 25 -t 10
-
-max-time: 500
-cmd: flexHammer
-args: -r 5 -t 32
+cmd: testScan
+args: -n ScanParallelism
#
# DICT TESTS
@@ -475,7 +445,7 @@ args: -n FragmentTypeSingle T1
max-time: 1500
cmd: testDict
-args: -n FragmentTypeAll T1 T6 T7 T8
+args: -n FragmentTypeAllSmall T1 T6 T7 T8
max-time: 1500
cmd: testDict
@@ -554,6 +524,10 @@ max-time: 500
cmd: testNdbApi
args: -n Bug_11133 T1
+max-time: 500
+cmd: testNdbApi
+args: -n Scan_4006 T1
+
#max-time: 500
#cmd: testInterpreter
#args: T1
@@ -562,7 +536,7 @@ max-time: 150000
cmd: testOperations
args:
-max-time: 150000
+max-time: 15000
cmd: testTransactions
args:
@@ -574,10 +548,18 @@ max-time: 600
cmd: testBlobs
args:
-max-time: 2500
+max-time: 5000
cmd: testOIBasic
args:
+max-time: 2500
+cmd: testBitfield
+args:
+
+max-time: 2500
+cmd: testPartitioning
+args:
+
#
#
# SYSTEM RESTARTS
@@ -625,3 +607,42 @@ args: -n SR_UNDO T7
max-time: 1500
cmd: testSystemRestart
args: -n SR_UNDO T8
+
+# OLD FLEX
+max-time: 500
+cmd: flexBench
+args: -c 25 -t 10
+
+max-time: 500
+cmd: flexHammer
+args: -r 5 -t 32
+
+max-time: 300
+cmd: DbCreate
+args:
+
+max-time: 180
+cmd: DbAsyncGenerator
+args: -time 60 -p 1
+type: bench
+
+max-time: 180
+cmd: DbAsyncGenerator
+args: -time 60 -p 25
+type: bench
+
+max-time: 180
+cmd: DbAsyncGenerator
+args: -time 60 -p 100
+type: bench
+
+max-time: 180
+cmd: DbAsyncGenerator
+args: -time 60 -p 200
+type: bench
+
+max-time: 180
+cmd: DbAsyncGenerator
+args: -time 60 -p 1 -proc 25
+type: bench
+
diff --git a/ndb/test/run-test/daily-devel-tests.txt b/ndb/test/run-test/daily-devel-tests.txt
index 9812ec2ceaa..20f54e031e5 100644
--- a/ndb/test/run-test/daily-devel-tests.txt
+++ b/ndb/test/run-test/daily-devel-tests.txt
@@ -206,34 +206,5 @@ args: -l 1 -n SR9 T1
#
max-time: 2500
cmd: test_event
-args: -n BasicEventOperation T1 T6
-
-max-time: 300
-cmd: DbCreate
-args:
-
-max-time: 180
-cmd: DbAsyncGenerator
-args: -time 60 -p 1
-type: bench
-
-max-time: 180
-cmd: DbAsyncGenerator
-args: -time 60 -p 25
-type: bench
-
-max-time: 180
-cmd: DbAsyncGenerator
-args: -time 60 -p 100
-type: bench
-
-max-time: 180
-cmd: DbAsyncGenerator
-args: -time 60 -p 200
-type: bench
-
-max-time: 180
-cmd: DbAsyncGenerator
-args: -time 60 -p 1 -proc 25
-type: bench
+args: -n EventOperationApplier
diff --git a/ndb/test/src/HugoAsynchTransactions.cpp b/ndb/test/src/HugoAsynchTransactions.cpp
index f75293f5a14..5d2eb451c0b 100644
--- a/ndb/test/src/HugoAsynchTransactions.cpp
+++ b/ndb/test/src/HugoAsynchTransactions.cpp
@@ -17,11 +17,12 @@
#include <NdbSleep.h>
#include <HugoAsynchTransactions.hpp>
-HugoAsynchTransactions::HugoAsynchTransactions(const NdbDictionary::Table& _tab):
- HugoTransactions(_tab),
- transactionsCompleted(0),
- numTransactions(0),
- transactions(NULL){
+HugoAsynchTransactions::HugoAsynchTransactions(const NdbDictionary::Table& _t)
+ : HugoTransactions(_t),
+ transactionsCompleted(0),
+ numTransactions(0),
+ transactions(NULL)
+{
}
HugoAsynchTransactions::~HugoAsynchTransactions(){
diff --git a/ndb/test/src/HugoCalculator.cpp b/ndb/test/src/HugoCalculator.cpp
index 62c35c54a7a..8e01f6442bb 100644
--- a/ndb/test/src/HugoCalculator.cpp
+++ b/ndb/test/src/HugoCalculator.cpp
@@ -14,8 +14,26 @@
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 "HugoCalculator.hpp"
#include <NDBT.hpp>
+#include <Base64.hpp>
+
+static
+Uint32
+myRand(Uint64 * seed)
+{
+ const Uint64 mul= 0x5deece66dull;
+ const Uint64 add= 0xb;
+ Uint64 loc_result = *seed * mul + add;
+
+ * seed= loc_result;
+ return loc_result >> 1;
+}
+
+static char base64_table[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
+ "abcdefghijklmnopqrstuvwxyz"
+ "0123456789+/";
/* *************************************************************
* HugoCalculator
@@ -40,7 +58,8 @@ HugoCalculator::HugoCalculator(const NdbDictionary::Table& tab) : m_tab(tab) {
// The "number of updates" column for this table is found in the last column
for (i=m_tab.getNoOfColumns()-1; i>=0; i--){
const NdbDictionary::Column* attr = m_tab.getColumn(i);
- if (attr->getType() == NdbDictionary::Column::Unsigned){
+ if (attr->getType() == NdbDictionary::Column::Unsigned &&
+ !attr->getPrimaryKey()){
m_updatesCol = i;
break;
}
@@ -51,29 +70,18 @@ HugoCalculator::HugoCalculator(const NdbDictionary::Table& tab) : m_tab(tab) {
#endif
// Check that idCol is not conflicting with updatesCol
assert(m_idCol != m_updatesCol && m_idCol != -1 && m_updatesCol != -1);
-};
+}
Int32
HugoCalculator::calcValue(int record,
int attrib,
int updates) const {
- const NdbDictionary::Column* attr = m_tab.getColumn(attrib);
- // If this is the "id" column
- if (attrib == m_idCol)
- return record;
-
- // If this is the update column
- if (attrib == m_updatesCol)
- return updates;
-
-
- Int32 val;
- if (attr->getPrimaryKey())
- val = record + attrib;
- else
- val = record + attrib + updates;
- return val;
-};
+
+ Int32 i;
+ calcValue(record, attrib, updates, (char*)&i, sizeof(i));
+
+ return i;
+}
#if 0
HugoCalculator::U_Int32 calcValue(int record, int attrib, int updates) const;
HugoCalculator::U_Int64 calcValue(int record, int attrib, int updates) const;
@@ -81,49 +89,121 @@ HugoCalculator::Int64 calcValue(int record, int attrib, int updates) const;
HugoCalculator::float calcValue(int record, int attrib, int updates) const;
HugoCalculator::double calcValue(int record, int attrib, int updates) const;
#endif
+
const char*
HugoCalculator::calcValue(int record,
int attrib,
int updates,
- char* buf) const {
- const char a[26] = {"UAWBORCTDPEFQGNYHISJMKXLZ"};
+ char* buf,
+ int len) const {
+ Uint64 seed;
const NdbDictionary::Column* attr = m_tab.getColumn(attrib);
- int val = calcValue(record, attrib, updates);
-
- int len;
- if (attr->getPrimaryKey()){
- // Create a string where val is printed as chars in the beginning
- // of the string, then fill with other chars
- // The string length is set to the same size as the attribute
- len = attr->getLength();
- BaseString::snprintf(buf, len, "%d", val);
- for(int i=strlen(buf); i < len; i++)
- buf[i] = a[((val^i)%25)];
- } else{
+ Uint32 val;
+ do
+ {
+ if (attrib == m_idCol)
+ {
+ val= record;
+ memcpy(buf, &val, 4);
+ return buf;
+ }
- // Fill buf with some pattern so that we can detect
- // anomalies in the area that we don't fill with chars
- int i;
- for (i = 0; i<attr->getLength(); i++)
- buf[i] = ((i+2) % 255);
+ // If this is the update column
+ if (attrib == m_updatesCol)
+ {
+ val= updates;
+ memcpy(buf, &val, 4);
+ return buf;
+ }
+
+ if (attr->getPrimaryKey())
+ {
+ seed = record + attrib;
+ }
+ else
+ {
+ seed = record + attrib + updates;
+ }
+ } while (0);
+
+ val = myRand(&seed);
+
+ if(attr->getNullable() && (((val >> 16) & 255) > 220))
+ return NULL;
+
+ int pos= 0;
+ switch(attr->getType()){
+ case NdbDictionary::Column::Tinyint:
+ case NdbDictionary::Column::Tinyunsigned:
+ case NdbDictionary::Column::Smallint:
+ case NdbDictionary::Column::Smallunsigned:
+ case NdbDictionary::Column::Mediumint:
+ case NdbDictionary::Column::Mediumunsigned:
+ case NdbDictionary::Column::Int:
+ case NdbDictionary::Column::Unsigned:
+ case NdbDictionary::Column::Bigint:
+ case NdbDictionary::Column::Bigunsigned:
+ case NdbDictionary::Column::Float:
+ case NdbDictionary::Column::Double:
+ case NdbDictionary::Column::Olddecimal:
+ case NdbDictionary::Column::Olddecimalunsigned:
+ case NdbDictionary::Column::Decimal:
+ case NdbDictionary::Column::Decimalunsigned:
+ case NdbDictionary::Column::Binary:
+ case NdbDictionary::Column::Datetime:
+ case NdbDictionary::Column::Time:
+ case NdbDictionary::Column::Date:
+ case NdbDictionary::Column::Bit:
+ while (len > 4)
+ {
+ memcpy(buf+pos, &val, 4);
+ pos += 4;
+ len -= 4;
+ val= myRand(&seed);
+ }
- // Calculate length of the string to create. We want the string
- // length to be varied between max and min of this attribute.
-
- len = val % (attr->getLength() + 1);
- // If len == 0 return NULL if this is a nullable attribute
- if (len == 0){
- if(attr->getNullable() == true)
- return NULL;
- else
- len++;
+ memcpy(buf+pos, &val, len);
+ if(attr->getType() == NdbDictionary::Column::Bit)
+ {
+ Uint32 bits= attr->getLength();
+ Uint32 tmp = bits >> 5;
+ Uint32 size = bits & 31;
+ ((Uint32*)buf)[tmp] &= ((1 << size) - 1);
}
- for(i=0; i < len; i++)
- buf[i] = a[((val^i)%25)];
- buf[len] = 0;
+ break;
+ case NdbDictionary::Column::Varbinary:
+ case NdbDictionary::Column::Varchar:
+ case NdbDictionary::Column::Text:
+ case NdbDictionary::Column::Char:
+ case NdbDictionary::Column::Longvarchar:
+ case NdbDictionary::Column::Longvarbinary:
+ {
+ char* ptr= (char*)&val;
+ while(len >= 4)
+ {
+ len -= 4;
+ buf[pos++] = base64_table[ptr[0] & 0x3f];
+ buf[pos++] = base64_table[ptr[1] & 0x3f];
+ buf[pos++] = base64_table[ptr[2] & 0x3f];
+ buf[pos++] = base64_table[ptr[3] & 0x3f];
+ val= myRand(&seed);
+ }
+
+ for(; len; len--, pos++)
+ buf[pos] = base64_table[ptr[len] & 0x3f];
+
+ pos--;
+ break;
}
+ case NdbDictionary::Column::Blob:
+ case NdbDictionary::Column::Undefined:
+ abort();
+ break;
+ }
+
+
return buf;
-};
+}
int
HugoCalculator::verifyRowValues(NDBT_ResultRow* const pRow) const{
@@ -131,104 +211,48 @@ HugoCalculator::verifyRowValues(NDBT_ResultRow* const pRow) const{
id = pRow->attributeStore(m_idCol)->u_32_value();
updates = pRow->attributeStore(m_updatesCol)->u_32_value();
-
+ int result = 0;
+
// Check the values of each column
for (int i = 0; i<m_tab.getNoOfColumns(); i++){
if (i != m_updatesCol && id != m_idCol) {
-
const NdbDictionary::Column* attr = m_tab.getColumn(i);
- switch (attr->getType()){
- case NdbDictionary::Column::Char:
- case NdbDictionary::Column::Varchar:
- case NdbDictionary::Column::Binary:
- case NdbDictionary::Column::Varbinary:{
- int result = 0;
- char* buf = new char[attr->getLength()+1];
- const char* res = calcValue(id, i, updates, buf);
- if (res == NULL){
- if (!pRow->attributeStore(i)->isNULL()){
- g_err << "|- NULL ERROR: expected a NULL but the column was not null" << endl;
- g_err << "|- The row: \"" << (*pRow) << "\"" << endl;
- result = -1;
- }
- } else{
- if (memcmp(res, pRow->attributeStore(i)->aRef(), pRow->attributeStore(i)->arraySize()) != 0){
- // if (memcmp(res, pRow->attributeStore(i)->aRef(), pRow->attributeStore(i)->getLength()) != 0){
- g_err << "arraySize(): "
- << pRow->attributeStore(i)->arraySize()
- << ", NdbDict::Column::getLength(): " << attr->getLength()
- << endl;
- const char* buf2 = pRow->attributeStore(i)->aRef();
- for (Uint32 j = 0; j < pRow->attributeStore(i)->arraySize(); j++)
+ Uint32 len = attr->getSizeInBytes();
+ char buf[8000];
+ const char* res = calcValue(id, i, updates, buf, len);
+ if (res == NULL){
+ if (!pRow->attributeStore(i)->isNULL()){
+ g_err << "|- NULL ERROR: expected a NULL but the column was not null" << endl;
+ g_err << "|- The row: \"" << (*pRow) << "\"" << endl;
+ result = -1;
+ }
+ } else{
+ if (memcmp(res, pRow->attributeStore(i)->aRef(), len) != 0){
+ g_err << "Column: " << attr->getName() << endl;
+ const char* buf2 = pRow->attributeStore(i)->aRef();
+ for (Uint32 j = 0; j < len; j++)
+ {
+ g_err << j << ":" << hex << (Uint32)(Uint8)buf[j] << "[" << hex << (Uint32)(Uint8)buf2[j] << "]";
+ if (buf[j] != buf2[j])
{
- g_err << j << ":" << buf[j] << "[" << buf2[j] << "]";
- if (buf[j] != buf2[j])
- {
- g_err << "==>Match failed!";
- }
- g_err << endl;
+ g_err << "==>Match failed!";
}
g_err << endl;
- g_err << "|- Invalid data found in attribute " << i << ": \""
- << pRow->attributeStore(i)->aRef()
- << "\" != \"" << res << "\"" << endl
- << "Length of expected=" << (unsigned)strlen(res) << endl
- << "Lenght of read="
- << (unsigned)strlen(pRow->attributeStore(i)->aRef()) << endl;
- g_err << "|- The row: \"" << (* pRow) << "\"" << endl;
- result = -1;
}
- }
- delete []buf;
- if (result != 0)
- return result;
- }
- break;
- case NdbDictionary::Column::Int:
- case NdbDictionary::Column::Unsigned:{
- Int32 cval = calcValue(id, i, updates);
- Int32 val = pRow->attributeStore(i)->int32_value();
- if (val != cval){
- g_err << "|- Invalid data found: \"" << val << "\" != \""
- << cval << "\"" << endl;
- g_err << "|- The row: \"" << (* pRow) << "\"" << endl;
- return -1;
- }
- break;
- }
- case NdbDictionary::Column::Bigint:
- case NdbDictionary::Column::Bigunsigned:{
- Uint64 cval = calcValue(id, i, updates);
- Uint64 val = pRow->attributeStore(i)->u_64_value();
- if (val != cval){
- g_err << "|- Invalid data found: \"" << val << "\" != \""
- << cval << "\""
- << endl;
+ g_err << endl;
+ g_err << "|- Invalid data found in attribute " << i << ": \""
+ << pRow->attributeStore(i)->aRef()
+ << "\" != \"" << res << "\"" << endl
+ << "Length of expected=" << (unsigned)strlen(res) << endl
+ << "Lenght of read="
+ << (unsigned)strlen(pRow->attributeStore(i)->aRef()) << endl;
g_err << "|- The row: \"" << (* pRow) << "\"" << endl;
- return -1;
+ result = -1;
}
}
- break;
- case NdbDictionary::Column::Float:{
- float cval = calcValue(id, i, updates);
- float val = pRow->attributeStore(i)->float_value();
- if (val != cval){
- g_err << "|- Invalid data found: \"" << val << "\" != \""
- << cval << "\"" << endl;
- g_err << "|- The row: \"" << (* pRow) << "\"" << endl;
- return -1;
- }
- }
- break;
- case NdbDictionary::Column::Undefined:
- default:
- assert(false);
- break;
- }
-
}
}
- return 0;
+ return result;
}
int
diff --git a/ndb/test/src/HugoOperations.cpp b/ndb/test/src/HugoOperations.cpp
index 6b1a1ca395b..f2e54971766 100644
--- a/ndb/test/src/HugoOperations.cpp
+++ b/ndb/test/src/HugoOperations.cpp
@@ -31,6 +31,19 @@ int HugoOperations::startTransaction(Ndb* pNdb){
return NDBT_OK;
}
+int HugoOperations::setTransaction(NdbTransaction* new_trans){
+
+ if (pTrans != NULL){
+ ndbout << "HugoOperations::startTransaction, pTrans != NULL" << endl;
+ return NDBT_FAILED;
+ }
+ pTrans = new_trans;
+ if (pTrans == NULL) {
+ return NDBT_FAILED;
+ }
+ return NDBT_OK;
+}
+
void
HugoOperations::setTransactionId(Uint64 id){
if (pTrans != NULL){
@@ -40,11 +53,7 @@ HugoOperations::setTransactionId(Uint64 id){
int HugoOperations::closeTransaction(Ndb* pNdb){
- if (pTrans != NULL){
- pNdb->closeTransaction(pTrans);
- pTrans = NULL;
- }
- pTrans = NULL;
+ UtilTransactions::closeTransaction(pNdb);
m_result_sets.clear();
m_executed_result_sets.clear();
@@ -63,8 +72,16 @@ int HugoOperations::pkReadRecord(Ndb* pNdb,
int a;
allocRows(numRecords);
int check;
+
+ NdbOperation* pOp = 0;
+ pIndexScanOp = 0;
+
for(int r=0; r < numRecords; r++){
- NdbOperation* pOp = pTrans->getNdbOperation(tab.getName());
+
+ if(pOp == 0)
+ {
+ pOp = getOperation(pTrans, NdbOperation::ReadRequest);
+ }
if (pOp == NULL) {
ERR(pTrans->getNdbError());
return NDBT_FAILED;
@@ -73,13 +90,16 @@ int HugoOperations::pkReadRecord(Ndb* pNdb,
rand_lock_mode:
switch(lm){
case NdbOperation::LM_Read:
- check = pOp->readTuple();
- break;
case NdbOperation::LM_Exclusive:
- check = pOp->readTupleExclusive();
- break;
case NdbOperation::LM_CommittedRead:
- check = pOp->dirtyRead();
+ if(idx && idx->getType() == NdbDictionary::Index::OrderedIndex &&
+ pIndexScanOp == 0)
+ {
+ pIndexScanOp = ((NdbIndexScanOperation*)pOp);
+ check = pIndexScanOp->readTuples(lm);
+ }
+ else
+ check = pOp->readTuple(lm);
break;
default:
lm = (NdbOperation::LockMode)((rand() >> 16) & 3);
@@ -100,15 +120,22 @@ rand_lock_mode:
}
}
}
+
+ if(pIndexScanOp)
+ pIndexScanOp->end_of_bound(r);
- // Define attributes to read
- for(a = 0; a<tab.getNoOfColumns(); a++){
- if((rows[r]->attributeStore(a) =
- pOp->getValue(tab.getColumn(a)->getName())) == 0) {
- ERR(pTrans->getNdbError());
- return NDBT_FAILED;
- }
- }
+ if(r == 0 || pIndexScanOp == 0)
+ {
+ // Define attributes to read
+ for(a = 0; a<tab.getNoOfColumns(); a++){
+ if((rows[r]->attributeStore(a) =
+ pOp->getValue(tab.getColumn(a)->getName())) == 0) {
+ ERR(pTrans->getNdbError());
+ return NDBT_FAILED;
+ }
+ }
+ }
+ pOp = pIndexScanOp;
}
return NDBT_OK;
}
@@ -121,7 +148,7 @@ int HugoOperations::pkUpdateRecord(Ndb* pNdb,
allocRows(numRecords);
int check;
for(int r=0; r < numRecords; r++){
- NdbOperation* pOp = pTrans->getNdbOperation(tab.getName());
+ NdbOperation* pOp = getOperation(pTrans, NdbOperation::UpdateRequest);
if (pOp == NULL) {
ERR(pTrans->getNdbError());
return NDBT_FAILED;
@@ -133,26 +160,37 @@ int HugoOperations::pkUpdateRecord(Ndb* pNdb,
return NDBT_FAILED;
}
- // Define primary keys
- for(a = 0; a<tab.getNoOfColumns(); a++){
- if (tab.getColumn(a)->getPrimaryKey() == true){
- if(equalForAttr(pOp, a, r+recordNo) != 0){
- ERR(pTrans->getNdbError());
- return NDBT_FAILED;
- }
+ if(setValues(pOp, r+recordNo, updatesValue) != NDBT_OK)
+ {
+ return NDBT_FAILED;
+ }
+ }
+ return NDBT_OK;
+}
+
+int
+HugoOperations::setValues(NdbOperation* pOp, int rowId, int updateId)
+{
+ // Define primary keys
+ int a;
+ for(a = 0; a<tab.getNoOfColumns(); a++){
+ if (tab.getColumn(a)->getPrimaryKey() == true){
+ if(equalForAttr(pOp, a, rowId) != 0){
+ ERR(pTrans->getNdbError());
+ return NDBT_FAILED;
}
}
-
- // Define attributes to update
- for(a = 0; a<tab.getNoOfColumns(); a++){
- if (tab.getColumn(a)->getPrimaryKey() == false){
- if(setValueForAttr(pOp, a, recordNo+r, updatesValue ) != 0){
- ERR(pTrans->getNdbError());
- return NDBT_FAILED;
- }
+ }
+
+ for(a = 0; a<tab.getNoOfColumns(); a++){
+ if (tab.getColumn(a)->getPrimaryKey() == false){
+ if(setValueForAttr(pOp, a, rowId, updateId ) != 0){
+ ERR(pTrans->getNdbError());
+ return NDBT_FAILED;
}
- }
+ }
}
+
return NDBT_OK;
}
@@ -163,7 +201,7 @@ int HugoOperations::pkInsertRecord(Ndb* pNdb,
int a, check;
for(int r=0; r < numRecords; r++){
- NdbOperation* pOp = pTrans->getNdbOperation(tab.getName());
+ NdbOperation* pOp = getOperation(pTrans, NdbOperation::InsertRequest);
if (pOp == NULL) {
ERR(pTrans->getNdbError());
return NDBT_FAILED;
@@ -175,25 +213,10 @@ int HugoOperations::pkInsertRecord(Ndb* pNdb,
return NDBT_FAILED;
}
- // Define primary keys
- for(a = 0; a<tab.getNoOfColumns(); a++){
- if (tab.getColumn(a)->getPrimaryKey() == true){
- if(equalForAttr(pOp, a, r+recordNo) != 0){
- ERR(pTrans->getNdbError());
- return NDBT_FAILED;
- }
- }
+ if(setValues(pOp, r+recordNo, updatesValue) != NDBT_OK)
+ {
+ return NDBT_FAILED;
}
-
- // Define attributes to update
- for(a = 0; a<tab.getNoOfColumns(); a++){
- if (tab.getColumn(a)->getPrimaryKey() == false){
- if(setValueForAttr(pOp, a, recordNo+r, updatesValue ) != 0){
- ERR(pTrans->getNdbError());
- return NDBT_FAILED;
- }
- }
- }
}
return NDBT_OK;
}
@@ -240,9 +263,9 @@ int HugoOperations::pkWriteRecord(Ndb* pNdb,
return NDBT_OK;
}
-int HugoOperations::pkDeleteRecord(Ndb* pNdb,
- int recordNo,
- int numRecords){
+int HugoOperations::pkWritePartialRecord(Ndb* pNdb,
+ int recordNo,
+ int numRecords){
int a, check;
for(int r=0; r < numRecords; r++){
@@ -252,7 +275,7 @@ int HugoOperations::pkDeleteRecord(Ndb* pNdb,
return NDBT_FAILED;
}
- check = pOp->deleteTuple();
+ check = pOp->writeTuple();
if( check == -1 ) {
ERR(pTrans->getNdbError());
return NDBT_FAILED;
@@ -270,65 +293,37 @@ int HugoOperations::pkDeleteRecord(Ndb* pNdb,
}
return NDBT_OK;
}
-#if 0
-NdbResultSet*
-HugoOperations::scanReadRecords(Ndb* pNdb, ScanLock lock){
-
- NDBT_ResultRow * m_tmpRow = new NDBT_ResultRow(tab);
-
- NdbScanOperation* pOp = pTrans->getNdbScanOperation(tab.getName());
- if (pOp == NULL) {
- ERR(pTrans->getNdbError());
- return 0;
- }
-
- int check = 0;
- NdbResultSet * rs = 0;
- switch(lock){
- case SL_ReadHold:
- rs = pOp->readTuples(NdbScanOperation::LM_Read, 1, 1);
- break;
- case SL_Exclusive:
- rs = pOp->readTuples(NdbScanOperation::LM_Exclusive, 1, 1);
- break;
- case SL_Read:
- default:
- rs = pOp->readTuples(NdbScanOperation::LM_Dirty, 1, 1);
- }
-
- if( rs == 0) {
- ERR(pTrans->getNdbError());
- return 0;
- }
-
- check = pOp->interpret_exit_ok();
- if( check == -1 ) {
- ERR(pTrans->getNdbError());
- return 0;
- }
+int HugoOperations::pkDeleteRecord(Ndb* pNdb,
+ int recordNo,
+ int numRecords){
- // Define attributes to read
- for(int a = 0; a<tab.getNoOfColumns(); a++){
- if((m_tmpRow->attributeStore(a) =
- pOp->getValue(tab.getColumn(a)->getName())) == 0) {
+ int a, check;
+ for(int r=0; r < numRecords; r++){
+ NdbOperation* pOp = getOperation(pTrans, NdbOperation::DeleteRequest);
+ if (pOp == NULL) {
ERR(pTrans->getNdbError());
- return 0;
+ return NDBT_FAILED;
+ }
+
+ check = pOp->deleteTuple();
+ if( check == -1 ) {
+ ERR(pTrans->getNdbError());
+ return NDBT_FAILED;
+ }
+
+ // Define primary keys
+ for(a = 0; a<tab.getNoOfColumns(); a++){
+ if (tab.getColumn(a)->getPrimaryKey() == true){
+ if(equalForAttr(pOp, a, r+recordNo) != 0){
+ ERR(pTrans->getNdbError());
+ return NDBT_FAILED;
+ }
+ }
}
- }
- return rs;
-}
-
-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){
@@ -353,7 +348,7 @@ int HugoOperations::execute_Commit(Ndb* pNdb,
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;
+ NdbScanOperation* rs = m_result_sets[i].m_result_set;
int res = rs->nextResult();
switch(res){
case 1:
@@ -402,7 +397,7 @@ int HugoOperations::execute_NoCommit(Ndb* pNdb, AbortOption eao){
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;
+ NdbScanOperation* rs = m_result_sets[i].m_result_set;
int res = rs->nextResult();
switch(res){
case 1:
@@ -441,21 +436,29 @@ int HugoOperations::execute_Rollback(Ndb* pNdb){
}
void
-HugoOperations_async_callback(int res, NdbConnection* pCon, void* ho)
+HugoOperations_async_callback(int res, NdbTransaction* pCon, void* ho)
{
((HugoOperations*)ho)->callback(res, pCon);
}
void
-HugoOperations::callback(int res, NdbConnection* pCon)
+HugoOperations::callback(int res, NdbTransaction* pCon)
{
assert(pCon == pTrans);
m_async_reply= 1;
- m_async_return= res;
+ if(res)
+ {
+ m_async_return = pCon->getNdbError().code;
+ }
+ else
+ {
+ m_async_return = 0;
+ }
}
int
-HugoOperations::execute_async(Ndb* pNdb, ExecType et, AbortOption eao){
+HugoOperations::execute_async(Ndb* pNdb, NdbTransaction::ExecType et,
+ NdbTransaction::AbortOption eao){
m_async_reply= 0;
pTrans->executeAsynchPrepare(et,
@@ -475,16 +478,18 @@ HugoOperations::wait_async(Ndb* pNdb, int timeout)
if(m_async_reply)
{
+ if(m_async_return)
+ ndbout << "ERROR: " << pNdb->getNdbError(m_async_return) << endl;
return m_async_return;
}
ndbout_c("wait returned nothing...");
return -1;
}
-HugoOperations::HugoOperations(const NdbDictionary::Table& _tab):
- UtilTransactions(_tab),
- calc(_tab),
- pTrans(NULL)
+HugoOperations::HugoOperations(const NdbDictionary::Table& _tab,
+ const NdbDictionary::Index* idx):
+ UtilTransactions(_tab, idx),
+ calc(_tab)
{
}
@@ -501,101 +506,32 @@ HugoOperations::~HugoOperations(){
int HugoOperations::equalForAttr(NdbOperation* pOp,
int attrId,
int rowId){
- int check = 0;
+ int check = -1;
const NdbDictionary::Column* attr = tab.getColumn(attrId);
if (attr->getPrimaryKey() == false){
g_info << "Can't call equalForAttr on non PK attribute" << endl;
return NDBT_FAILED;
}
- switch (attr->getType()){
- case NdbDictionary::Column::Char:
- case NdbDictionary::Column::Varchar:
- case NdbDictionary::Column::Binary:
- case NdbDictionary::Column::Varbinary:{
- char buf[8000];
- memset(buf, 0, sizeof(buf));
- check = pOp->equal( attr->getName(), calc.calcValue(rowId, attrId, 0, buf));
- break;
- }
- case NdbDictionary::Column::Int:
- check = pOp->equal( attr->getName(), (Int32)calc.calcValue(rowId, attrId, 0));
- break;
- case NdbDictionary::Column::Unsigned:
- check = pOp->equal( attr->getName(), (Uint32)calc.calcValue(rowId, attrId, 0));
- break;
- case NdbDictionary::Column::Bigint:
- check = pOp->equal( attr->getName(), (Int64)calc.calcValue(rowId, attrId, 0));
- break;
- case NdbDictionary::Column::Bigunsigned:
- check = pOp->equal( attr->getName(), (Uint64)calc.calcValue(rowId, attrId, 0));
- break;
- case NdbDictionary::Column::Float:
- g_info << "Float not allowed as PK value" << endl;
- check = -1;
- break;
-
- default:
- g_info << "default" << endl;
- check = -1;
- break;
- }
- return check;
+ int len = attr->getSizeInBytes();
+ char buf[8000];
+ memset(buf, 0, sizeof(buf));
+ return pOp->equal( attr->getName(),
+ calc.calcValue(rowId, attrId, 0, buf, len));
}
int HugoOperations::setValueForAttr(NdbOperation* pOp,
int attrId,
int rowId,
int updateId){
- int check = 0;
+ int check = -1;
const NdbDictionary::Column* attr = tab.getColumn(attrId);
-
- if (attr->getTupleKey()){
- // Don't set values for TupleId PKs
- return check;
- }
- switch (attr->getType()){
- case NdbDictionary::Column::Char:
- case NdbDictionary::Column::Varchar:
- case NdbDictionary::Column::Binary:
- case NdbDictionary::Column::Varbinary:{
- char buf[8000];
- check = pOp->setValue( attr->getName(),
- calc.calcValue(rowId, attrId, updateId, buf));
- break;
- }
- case NdbDictionary::Column::Int:{
- Int32 val = calc.calcValue(rowId, attrId, updateId);
- check = pOp->setValue( attr->getName(), val);
- }
- break;
- case NdbDictionary::Column::Bigint:{
- Int64 val = calc.calcValue(rowId, attrId, updateId);
- check = pOp->setValue( attr->getName(),
- val);
- }
- break;
- case NdbDictionary::Column::Unsigned:{
- Uint32 val = calc.calcValue(rowId, attrId, updateId);
- check = pOp->setValue( attr->getName(), val);
- }
- break;
- case NdbDictionary::Column::Bigunsigned:{
- Uint64 val = calc.calcValue(rowId, attrId, updateId);
- check = pOp->setValue( attr->getName(),
- val);
- }
- break;
- case NdbDictionary::Column::Float:
- check = pOp->setValue( attr->getName(),
- (float)calc.calcValue(rowId, attrId, updateId));
- break;
- default:
- check = -1;
- break;
- }
- return check;
+ int len = attr->getSizeInBytes();
+ char buf[8000];
+ memset(buf, 0, sizeof(buf));
+ return pOp->setValue( attr->getName(),
+ calc.calcValue(rowId, attrId, updateId, buf, len));
}
int
@@ -611,7 +547,7 @@ HugoOperations::verifyUpdatesValue(int updatesValue, int _numRows){
result = NDBT_FAILED;
continue;
}
-
+
if(calc.getUpdatesValue(rows[i]) != updatesValue){
result = NDBT_FAILED;
g_err << "Invalid updates value for row " << i << endl
@@ -621,7 +557,7 @@ HugoOperations::verifyUpdatesValue(int updatesValue, int _numRows){
continue;
}
}
-
+
if(_numRows == 0){
g_err << "No rows -> Invalid updates value" << endl;
return NDBT_FAILED;
@@ -631,14 +567,12 @@ HugoOperations::verifyUpdatesValue(int updatesValue, int _numRows){
}
void HugoOperations::allocRows(int _numRows){
- deallocRows();
-
if(_numRows <= 0){
g_info << "Illegal value for num rows : " << _numRows << endl;
abort();
}
- for(int b=0; b<_numRows; b++){
+ for(int b=rows.size(); b<_numRows; b++){
rows.push_back(new NDBT_ResultRow(tab));
}
}
@@ -694,7 +628,7 @@ int HugoOperations::compareRecordToCopy(int numRecords ){
void
HugoOperations::refresh() {
- NdbConnection* t = getTransaction();
+ NdbTransaction * t = getTransaction();
if(t)
t->refresh();
}
@@ -799,12 +733,10 @@ HugoOperations::scanReadRecords(Ndb* pNdb, NdbScanOperation::LockMode lm,
if(!pOp)
return -1;
- NdbResultSet * rs = pOp->readTuples(lm, 1, 1);
-
- if(!rs){
+ if(pOp->readTuples(lm, 0, 1)){
return -1;
}
-
+
for(int a = 0; a<tab.getNoOfColumns(); a++){
if((rows[0]->attributeStore(a) =
pOp->getValue(tab.getColumn(a)->getName())) == 0) {
@@ -812,8 +744,8 @@ HugoOperations::scanReadRecords(Ndb* pNdb, NdbScanOperation::LockMode lm,
return NDBT_FAILED;
}
}
-
- RsPair p = {rs, records};
+
+ RsPair p = {pOp, records};
m_result_sets.push_back(p);
return 0;
diff --git a/ndb/test/src/HugoTransactions.cpp b/ndb/test/src/HugoTransactions.cpp
index 5d5b2fa99df..3260b921985 100644
--- a/ndb/test/src/HugoTransactions.cpp
+++ b/ndb/test/src/HugoTransactions.cpp
@@ -18,8 +18,9 @@
#include <NdbSleep.h>
-HugoTransactions::HugoTransactions(const NdbDictionary::Table& _tab):
- HugoOperations(_tab),
+HugoTransactions::HugoTransactions(const NdbDictionary::Table& _tab,
+ const NdbDictionary::Index* idx):
+ HugoOperations(_tab, idx),
row(_tab){
m_defaultScanUpdateMethod = 3;
@@ -34,7 +35,8 @@ HugoTransactions::scanReadRecords(Ndb* pNdb,
int records,
int abortPercent,
int parallelism,
- NdbOperation::LockMode lm)
+ NdbOperation::LockMode lm,
+ int scan_flags)
{
int retryAttempt = 0;
@@ -64,17 +66,14 @@ HugoTransactions::scanReadRecords(Ndb* pNdb,
return NDBT_FAILED;
}
- pOp = pTrans->getNdbScanOperation(tab.getName());
+ pOp = getScanOperation(pTrans);
if (pOp == NULL) {
ERR(pTrans->getNdbError());
closeTransaction(pNdb);
return NDBT_FAILED;
}
- NdbResultSet * rs;
- rs = pOp ->readTuples(lm);
-
- if( rs == 0 ) {
+ if( pOp ->readTuples(lm, scan_flags, parallelism) ) {
ERR(pTrans->getNdbError());
closeTransaction(pNdb);
return NDBT_FAILED;
@@ -123,7 +122,7 @@ HugoTransactions::scanReadRecords(Ndb* pNdb,
int eof;
int rows = 0;
- while((eof = rs->nextResult(true)) == 0){
+ while((eof = pOp->nextResult(true)) == 0){
rows++;
if (calc.verifyRowValues(&row) != 0){
closeTransaction(pNdb);
@@ -133,7 +132,7 @@ HugoTransactions::scanReadRecords(Ndb* pNdb,
if (abortCount == rows && abortTrans == true){
ndbout << "Scan is aborted" << endl;
g_info << "Scan is aborted" << endl;
- rs->close();
+ pOp->close();
if( check == -1 ) {
ERR(pTrans->getNdbError());
closeTransaction(pNdb);
@@ -189,7 +188,7 @@ HugoTransactions::scanReadRecords(Ndb* pNdb,
int abortPercent,
int parallelism,
NdbOperation::LockMode lm,
- bool sorted)
+ int scan_flags)
{
int retryAttempt = 0;
@@ -226,10 +225,7 @@ HugoTransactions::scanReadRecords(Ndb* pNdb,
return NDBT_FAILED;
}
- NdbResultSet * rs;
- rs = pOp ->readTuples(lm, 0, parallelism, sorted);
-
- if( rs == 0 ) {
+ if( pOp ->readTuples(lm, scan_flags, parallelism) ) {
ERR(pTrans->getNdbError());
closeTransaction(pNdb);
return NDBT_FAILED;
@@ -278,7 +274,7 @@ HugoTransactions::scanReadRecords(Ndb* pNdb,
int eof;
int rows = 0;
- while((eof = rs->nextResult(true)) == 0){
+ while((eof = pOp->nextResult(true)) == 0){
rows++;
if (calc.verifyRowValues(&row) != 0){
closeTransaction(pNdb);
@@ -288,7 +284,7 @@ HugoTransactions::scanReadRecords(Ndb* pNdb,
if (abortCount == rows && abortTrans == true){
ndbout << "Scan is aborted" << endl;
g_info << "Scan is aborted" << endl;
- rs->close();
+ pOp->close();
if( check == -1 ) {
ERR(pTrans->getNdbError());
closeTransaction(pNdb);
@@ -361,161 +357,7 @@ 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, a;
- NdbOperation *pOp;
-
-
- while (true){
-
- if (retryAttempt >= retryMax){
- g_info << "ERROR: has retried this operation " << retryAttempt
- << " times, failing!" << endl;
- return NDBT_FAILED;
- }
-
- pTrans = pNdb->startTransaction();
- if (pTrans == NULL) {
- const NdbError err = pNdb->getNdbError();
-
- if (err.status == NdbError::TemporaryError){
- ERR(err);
- NdbSleep_MilliSleep(50);
- retryAttempt++;
- continue;
- }
- ERR(err);
- return NDBT_FAILED;
- }
-
- pOp = pTrans->getNdbOperation(tab.getName());
- if (pOp == NULL) {
- ERR(pTrans->getNdbError());
- closeTransaction(pNdb);
- return NDBT_FAILED;
- }
-
- check = pOp->openScanExclusive(parallelism);
- if( check == -1 ) {
- ERR(pTrans->getNdbError());
- closeTransaction(pNdb);
- return NDBT_FAILED;
- }
-
- check = pOp->interpret_exit_ok();
- if( check == -1 ) {
- ERR(pTrans->getNdbError());
- closeTransaction(pNdb);
- return NDBT_FAILED;
- }
-
- // Read all attributes from this table
- for(a=0; a<tab.getNoOfColumns(); a++){
- if((row.attributeStore(a) = pOp->getValue(tab.getColumn(a)->getName())) == NULL){
- ERR(pTrans->getNdbError());
- closeTransaction(pNdb);
- return NDBT_FAILED;
- }
- }
-
- check = pTrans->executeScan();
- if( check == -1 ) {
- const NdbError err = pTrans->getNdbError();
- if (err.status == NdbError::TemporaryError){
- ERR(err);
- closeTransaction(pNdb);
- NdbSleep_MilliSleep(50);
- retryAttempt++;
- continue;
- }
- ERR(err);
- closeTransaction(pNdb);
- return NDBT_FAILED;
- }
-
- // Abort after 1-100 or 1-records rows
- int ranVal = rand();
- int abortCount = ranVal % (records == 0 ? 100 : records);
- bool abortTrans = false;
- if (abort > 0){
- // Abort if abortCount is less then abortPercent
- if (abortCount < abortPercent)
- abortTrans = true;
- }
-
-
- int eof;
- int rows = 0;
-
- eof = pTrans->nextScanResult();
- while(eof == 0){
- rows++;
-
- if (abortCount == rows && abortTrans == true){
- g_info << "Scan is aborted" << endl;
- // This scan should be aborted
- check = pTrans->stopScan();
- if( check == -1 ) {
- ERR(pTrans->getNdbError());
- closeTransaction(pNdb);
- return NDBT_FAILED;
- }
-
- closeTransaction(pNdb);
- return NDBT_OK;
- }
- int res = takeOverAndUpdateRecord(pNdb, pOp);
- if(res == RESTART_SCAN){
- eof = -2;
- continue;
- }
- if (res != 0){
- closeTransaction(pNdb);
- return res;
- }
-
- eof = pTrans->nextScanResult();
- }
- if (eof == -1) {
- const NdbError err = pTrans->getNdbError();
-
- if (err.status == NdbError::TemporaryError){
- ERR(err);
- NdbSleep_MilliSleep(50);
- switch (err.code){
- case 488:
- case 245:
- case 490:
- // Too many active scans, no limit on number of retry attempts
- break;
- default:
- retryAttempt++;
- }
- continue;
- }
- ERR(err);
- closeTransaction(pNdb);
- return NDBT_FAILED;
- }
-
- if(eof == -2){
- closeTransaction(pNdb);
- NdbSleep_MilliSleep(50);
- retryAttempt++;
- continue;
- }
-
- closeTransaction(pNdb);
-
- g_info << rows << " rows have been updated" << endl;
- return NDBT_OK;
- }
- return NDBT_FAILED;
-#endif
}
// Scan all records exclusive and update
@@ -527,166 +369,7 @@ 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, a;
- NdbOperation *pOp;
-
-
- while (true){
-
- if (retryAttempt >= retryMax){
- g_info << "ERROR: has retried this operation " << retryAttempt
- << " times, failing!" << endl;
- return NDBT_FAILED;
- }
-
- pTrans = pNdb->startTransaction();
- if (pTrans == NULL) {
- const NdbError err = pNdb->getNdbError();
-
- if (err.status == NdbError::TemporaryError){
- ERR(err);
- NdbSleep_MilliSleep(50);
- retryAttempt++;
- continue;
- }
- ERR(err);
- return NDBT_FAILED;
- }
-
- pOp = pTrans->getNdbOperation(tab.getName());
- if (pOp == NULL) {
- ERR(pTrans->getNdbError());
- closeTransaction(pNdb);
- return NDBT_FAILED;
- }
-
- check = pOp->openScanExclusive(parallelism);
- if( check == -1 ) {
- ERR(pTrans->getNdbError());
- closeTransaction(pNdb);
- return NDBT_FAILED;
- }
-
- check = pOp->interpret_exit_ok();
- if( check == -1 ) {
- ERR(pTrans->getNdbError());
- closeTransaction(pNdb);
- return NDBT_FAILED;
- }
-
- // Read all attributes from this table
- for(a=0; a<tab.getNoOfColumns(); a++){
- if((row.attributeStore(a) = pOp->getValue(tab.getColumn(a)->getName())) == NULL){
- ERR(pTrans->getNdbError());
- closeTransaction(pNdb);
- return NDBT_FAILED;
- }
- }
-
- check = pTrans->executeScan();
- if( check == -1 ) {
- const NdbError err = pTrans->getNdbError();
- if (err.status == NdbError::TemporaryError){
- ERR(err);
- closeTransaction(pNdb);
- NdbSleep_MilliSleep(50);
- retryAttempt++;
- continue;
- }
- ERR(err);
- closeTransaction(pNdb);
- return NDBT_FAILED;
- }
-
- // Abort after 1-100 or 1-records rows
- int ranVal = rand();
- int abortCount = ranVal % (records == 0 ? 100 : records);
- bool abortTrans = false;
- if (abort > 0){
- // Abort if abortCount is less then abortPercent
- if (abortCount < abortPercent)
- abortTrans = true;
- }
-
- int eof;
- int rows = 0;
-
- while((eof = pTrans->nextScanResult(true)) == 0){
- pUpTrans = pNdb->startTransaction();
- if (pUpTrans == NULL) {
- const NdbError err = pNdb->getNdbError();
-
- if (err.status == NdbError::TemporaryError){
- ERR(err);
- NdbSleep_MilliSleep(50);
- retryAttempt++;
- continue;
- }
- ERR(err);
- return NDBT_FAILED;
- }
- do {
- rows++;
- if (addRowToUpdate(pNdb, pUpTrans, pOp) != 0){
- pNdb->closeTransaction(pUpTrans);
- closeTransaction(pNdb);
- return NDBT_FAILED;
- }
- } while((eof = pTrans->nextScanResult(false)) == 0);
-
- if (abortCount == rows && abortTrans == true){
- g_info << "Scan is aborted" << endl;
- // This scan should be aborted
- check = pTrans->stopScan();
- if( check == -1 ) {
- ERR(pTrans->getNdbError());
- closeTransaction(pNdb);
- pNdb->closeTransaction(pUpTrans);
- return NDBT_FAILED;
- }
-
- closeTransaction(pNdb);
- pNdb->closeTransaction(pUpTrans);
- return NDBT_OK;
- }
-
- check = pUpTrans->execute(Commit);
- if( check == -1 ) {
- const NdbError err = pUpTrans->getNdbError();
- ERR(err);
- pNdb->closeTransaction(pUpTrans);
- closeTransaction(pNdb);
- return NDBT_FAILED;
- }
- pNdb->closeTransaction(pUpTrans);
- }
- if (eof == -1) {
- const NdbError err = pTrans->getNdbError();
-
- if (err.status == NdbError::TemporaryError){
- ERR(err);
- closeTransaction(pNdb);
- NdbSleep_MilliSleep(50);
- retryAttempt++;
- continue;
- }
- ERR(err);
- closeTransaction(pNdb);
- return NDBT_FAILED;
- }
-
- closeTransaction(pNdb);
-
- g_info << rows << " rows have been updated" << endl;
- return NDBT_OK;
- }
- return NDBT_FAILED;
-#endif
}
int
@@ -719,15 +402,14 @@ restart:
return NDBT_FAILED;
}
- pOp = pTrans->getNdbScanOperation(tab.getName());
+ pOp = getScanOperation(pTrans);
if (pOp == NULL) {
ERR(pTrans->getNdbError());
closeTransaction(pNdb);
return NDBT_FAILED;
}
- NdbResultSet *rs = pOp->readTuplesExclusive(parallelism);
- if( rs == 0 ) {
+ if( pOp->readTuplesExclusive(parallelism) ) {
ERR(pTrans->getNdbError());
closeTransaction(pNdb);
return NDBT_FAILED;
@@ -765,10 +447,10 @@ restart:
}
int rows = 0;
- while((check = rs->nextResult(true)) == 0){
+ while((check = pOp->nextResult(true)) == 0){
do {
rows++;
- NdbOperation* pUp = rs->updateTuple();
+ NdbOperation* pUp = pOp->updateCurrentTuple();
if(pUp == 0){
ERR(pTrans->getNdbError());
closeTransaction(pNdb);
@@ -792,7 +474,7 @@ restart:
closeTransaction(pNdb);
return NDBT_OK;
}
- } while((check = rs->nextResult(false)) == 0);
+ } while((check = pOp->nextResult(false)) == 0);
if(check != -1){
check = pTrans->execute(Commit);
@@ -858,7 +540,11 @@ HugoTransactions::loadTable(Ndb* pNdb,
g_info << "|- Inserting records..." << endl;
for (int c=0 ; c<records ; ){
- bool closeTrans;
+ bool closeTrans = true;
+
+ if(c + batch > records)
+ batch = records - c;
+
if (retryAttempt >= retryMax){
g_info << "Record " << c << " could not be inserted, has retried "
<< retryAttempt << " times " << endl;
@@ -887,30 +573,11 @@ HugoTransactions::loadTable(Ndb* pNdb,
}
}
- for(int b = 0; b < batch && c+b<records; b++){
-
- pOp = pTrans->getNdbOperation(tab.getName());
- if (pOp == NULL) {
- ERR(pTrans->getNdbError());
- closeTransaction(pNdb);
- return NDBT_FAILED;
- }
-
- check = pOp->insertTuple();
- if( check == -1 ) {
- ERR(pTrans->getNdbError());
- closeTransaction(pNdb);
- return NDBT_FAILED;
- }
-
- // Set a calculated value for each attribute in this table
- for (a = 0; a<tab.getNoOfColumns(); a++){
- if(setValueForAttr(pOp, a, c+b, 0 ) != 0){
- ERR(pTrans->getNdbError());
- closeTransaction(pNdb);
- return NDBT_FAILED;
- }
- }
+ if(pkInsertRecord(pNdb, c, batch) != NDBT_OK)
+ {
+ ERR(pTrans->getNdbError());
+ closeTransaction(pNdb);
+ return NDBT_FAILED;
}
// Execute the transaction and insert the record
@@ -976,6 +643,9 @@ HugoTransactions::loadTable(Ndb* pNdb,
c = c+batch;
retryAttempt = 0;
}
+
+ if(pTrans)
+ closeTransaction(pNdb);
return NDBT_OK;
}
@@ -986,8 +656,20 @@ HugoTransactions::fillTable(Ndb* pNdb,
int retryAttempt = 0;
int retryMax = 5;
NdbOperation *pOp;
+
+ const int org = batch;
+ const int cols = tab.getNoOfColumns();
+ const int brow = tab.getRowSizeInBytes();
+ const int bytes = 12 + brow + 4 * cols;
+ 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;
+ }
- g_info << "|- Inserting records..." << endl;
for (int c=0 ; ; ){
if (retryAttempt >= retryMax){
@@ -1012,30 +694,11 @@ HugoTransactions::fillTable(Ndb* pNdb,
return NDBT_FAILED;
}
- for(b = 0; b < batch; b++){
-
- pOp = pTrans->getNdbOperation(tab.getName());
- if (pOp == NULL) {
- ERR(pTrans->getNdbError());
- closeTransaction(pNdb);
- return NDBT_FAILED;
- }
-
- check = pOp->insertTuple();
- if( check == -1 ) {
- ERR(pTrans->getNdbError());
- closeTransaction(pNdb);
- return NDBT_FAILED;
- }
-
- // Set a calculated value for each attribute in this table
- for (a = 0; a<tab.getNoOfColumns(); a++){
- if(setValueForAttr(pOp, a, c+b, 0 ) != 0){
- ERR(pTrans->getNdbError());
- closeTransaction(pNdb);
- return NDBT_FAILED;
- }
- }
+ if(pkInsertRecord(pNdb, c, batch) != NDBT_OK)
+ {
+ ERR(pTrans->getNdbError());
+ closeTransaction(pNdb);
+ return NDBT_FAILED;
}
// Execute the transaction and insert the record
@@ -1113,7 +776,9 @@ HugoTransactions::createEvent(Ndb* pNdb){
NdbDictionary::Dictionary *myDict = pNdb->getDictionary();
if (!myDict) {
- printf("Event Creation failedDictionary not found");
+ g_err << "Dictionary not found "
+ << pNdb->getNdbError().code << " "
+ << pNdb->getNdbError().message << endl;
return NDBT_FAILED;
}
@@ -1134,21 +799,33 @@ HugoTransactions::createEvent(Ndb* pNdb){
if (res == 0)
myEvent.print();
- else {
- g_info << "Event creation failed\n";
- g_info << "trying drop Event, maybe event exists\n";
+ else if (myDict->getNdbError().classification ==
+ NdbError::SchemaObjectExists)
+ {
+ g_info << "Event creation failed event exists\n";
res = myDict->dropEvent(eventName);
if (res) {
- g_err << "failed to drop event\n";
+ g_err << "Failed to drop event: "
+ << myDict->getNdbError().code << " : "
+ << myDict->getNdbError().message << endl;
return NDBT_FAILED;
}
// try again
res = myDict->createEvent(myEvent); // Add event to database
if (res) {
- g_err << "failed to create event\n";
+ g_err << "Failed to create event (1): "
+ << myDict->getNdbError().code << " : "
+ << myDict->getNdbError().message << endl;
return NDBT_FAILED;
}
}
+ else
+ {
+ g_err << "Failed to create event (2): "
+ << myDict->getNdbError().code << " : "
+ << myDict->getNdbError().message << endl;
+ return NDBT_FAILED;
+ }
return NDBT_OK;
}
@@ -1164,6 +841,7 @@ struct receivedEvent {
};
int XXXXX = 0;
+
int
HugoTransactions::eventOperation(Ndb* pNdb, void* pstats,
int records) {
@@ -1234,7 +912,9 @@ HugoTransactions::eventOperation(Ndb* pNdb, void* pstats,
// set up the callbacks
g_info << function << "execute\n";
if (pOp->execute()) { // This starts changes to "start flowing"
- g_err << function << "operation execution failed\n";
+ g_err << function << "operation execution failed: \n";
+ g_err << pOp->getNdbError().code << " "
+ << pOp->getNdbError().message << endl;
return NDBT_FAILED;
}
@@ -1362,36 +1042,36 @@ HugoTransactions::eventOperation(Ndb* pNdb, void* pstats,
stats.n_duplicates += recDeleteEvent[i].count-1;
}
}
-
+
return NDBT_OK;
}
int
HugoTransactions::pkReadRecords(Ndb* pNdb,
int records,
- int batchsize,
+ int batch,
NdbOperation::LockMode lm){
int reads = 0;
int r = 0;
int retryAttempt = 0;
const int retryMax = 100;
int check, a;
- NdbOperation *pOp;
- if (batchsize == 0) {
- g_info << "ERROR: Argument batchsize == 0 in pkReadRecords(). Not allowed." << endl;
+ if (batch == 0) {
+ g_info << "ERROR: Argument batch == 0 in pkReadRecords(). Not allowed." << endl;
return NDBT_FAILED;
}
- allocRows(batchsize);
-
while (r < records){
+ if(r + batch > records)
+ batch = records - r;
+
if (retryAttempt >= retryMax){
g_info << "ERROR: has retried this operation " << retryAttempt
<< " times, failing!" << endl;
return NDBT_FAILED;
}
-
+
pTrans = pNdb->startTransaction();
if (pTrans == NULL) {
const NdbError err = pNdb->getNdbError();
@@ -1405,64 +1085,18 @@ HugoTransactions::pkReadRecords(Ndb* pNdb,
ERR(err);
return NDBT_FAILED;
}
-
- for(int b=0; (b<batchsize) && (r+b < records); b++){
- pOp = pTrans->getNdbOperation(tab.getName());
- if (pOp == NULL) {
- ERR(pTrans->getNdbError());
- closeTransaction(pNdb);
- return NDBT_FAILED;
- }
-
- rand_lock_mode:
- switch(lm){
- case NdbOperation::LM_Read:
- check = pOp->readTuple();
- break;
- case NdbOperation::LM_Exclusive:
- check = pOp->readTupleExclusive();
- break;
- case NdbOperation::LM_CommittedRead:
- check = pOp->dirtyRead();
- break;
- default:
- lm = (NdbOperation::LockMode)((rand() >> 16) & 3);
- goto rand_lock_mode;
- }
-
- if( check == -1 ) {
- ERR(pTrans->getNdbError());
- closeTransaction(pNdb);
- return NDBT_FAILED;
- }
- // Define primary keys
- for(a = 0; a<tab.getNoOfColumns(); a++){
- if (tab.getColumn(a)->getPrimaryKey() == true){
- if(equalForAttr(pOp, a, r+b) != 0){
- ERR(pTrans->getNdbError());
- closeTransaction(pNdb);
- return NDBT_FAILED;
- }
- }
- }
-
- // Define attributes to read
- for(a = 0; a<tab.getNoOfColumns(); a++){
- if((rows[b]->attributeStore(a) =
- pOp->getValue(tab.getColumn(a)->getName())) == 0) {
- ERR(pTrans->getNdbError());
- closeTransaction(pNdb);
- return NDBT_FAILED;
- }
- }
-
+ if(pkReadRecord(pNdb, r, batch, lm) != NDBT_OK)
+ {
+ ERR(pTrans->getNdbError());
+ closeTransaction(pNdb);
+ return NDBT_FAILED;
}
-
+
check = pTrans->execute(Commit);
if( check == -1 ) {
const NdbError err = pTrans->getNdbError();
-
+
if (err.status == NdbError::TemporaryError){
ERR(err);
closeTransaction(pNdb);
@@ -1481,19 +1115,48 @@ HugoTransactions::pkReadRecords(Ndb* pNdb,
closeTransaction(pNdb);
return NDBT_FAILED;
}
- } else{
- for (int b=0; (b<batchsize) && (r+b<records); b++){
- if (calc.verifyRowValues(rows[b]) != 0){
+ } else {
+ if(pIndexScanOp)
+ {
+ int rows_found = 0;
+ while((check = pIndexScanOp->nextResult()) == 0)
+ {
+ rows_found++;
+ if (calc.verifyRowValues(rows[0]) != 0){
+ closeTransaction(pNdb);
+ return NDBT_FAILED;
+ }
+ }
+ if(check != 1 || rows_found > batch)
+ {
closeTransaction(pNdb);
return NDBT_FAILED;
}
- reads++;
- r++;
+ else if(rows_found < batch)
+ {
+ if(batch == 1){
+ g_info << r << ": not found" << endl; abort(); }
+ else
+ g_info << "Found " << rows_found << " of "
+ << batch << " rows" << endl;
+ }
+ r += batch;
+ reads += rows_found;
+ }
+ else
+ {
+ for (int b=0; (b<batch) && (r+b<records); b++){
+ if (calc.verifyRowValues(rows[b]) != 0){
+ closeTransaction(pNdb);
+ return NDBT_FAILED;
+ }
+ reads++;
+ r++;
+ }
}
}
-
+
closeTransaction(pNdb);
-
}
deallocRows();
g_info << reads << " records read" << endl;
@@ -1518,6 +1181,8 @@ HugoTransactions::pkUpdateRecords(Ndb* pNdb,
g_info << "|- Updating records (batch=" << batch << ")..." << endl;
while (r < records){
+ if(r + batch > records)
+ batch = records - r;
if (retryAttempt >= retryMax){
g_info << "ERROR: has retried this operation " << retryAttempt
@@ -1542,43 +1207,13 @@ HugoTransactions::pkUpdateRecords(Ndb* pNdb,
return NDBT_FAILED;
}
- for(b = 0; b<batch && (r+b) < records; b++){
- pOp = pTrans->getNdbOperation(tab.getName());
- if (pOp == NULL) {
- ERR(pTrans->getNdbError());
- closeTransaction(pNdb);
- return NDBT_FAILED;
- }
-
- check = pOp->readTupleExclusive();
- if( check == -1 ) {
- ERR(pTrans->getNdbError());
- closeTransaction(pNdb);
- return NDBT_FAILED;
- }
-
- // Define primary keys
- for(a = 0; a<tab.getNoOfColumns(); a++){
- if (tab.getColumn(a)->getPrimaryKey() == true){
- if(equalForAttr(pOp, a, r+b) != 0){
- ERR(pTrans->getNdbError());
- closeTransaction(pNdb);
- return NDBT_FAILED;
- }
- }
- }
-
- // Define attributes to read
- for(a = 0; a<tab.getNoOfColumns(); a++){
- if((rows[b]->attributeStore(a) =
- pOp->getValue(tab.getColumn(a)->getName())) == 0) {
- ERR(pTrans->getNdbError());
- closeTransaction(pNdb);
- return NDBT_FAILED;
- }
- }
+ if(pkReadRecord(pNdb, r, batch, NdbOperation::LM_Exclusive) != NDBT_OK)
+ {
+ ERR(pTrans->getNdbError());
+ closeTransaction(pNdb);
+ return NDBT_FAILED;
}
-
+
check = pTrans->execute(NoCommit);
if( check == -1 ) {
const NdbError err = pTrans->getNdbError();
@@ -1594,52 +1229,62 @@ HugoTransactions::pkUpdateRecords(Ndb* pNdb,
closeTransaction(pNdb);
return NDBT_FAILED;
}
-
- for(b = 0; b<batch && (b+r)<records; b++){
- if (calc.verifyRowValues(rows[b]) != 0){
- closeTransaction(pNdb);
- return NDBT_FAILED;
- }
-
- int updates = calc.getUpdatesValue(rows[b]) + 1;
-
- NdbOperation* pUpdOp;
- pUpdOp = pTrans->getNdbOperation(tab.getName());
- if (pUpdOp == NULL) {
- ERR(pTrans->getNdbError());
- closeTransaction(pNdb);
- return NDBT_FAILED;
- }
-
- check = pUpdOp->updateTuple();
- if( check == -1 ) {
- ERR(pTrans->getNdbError());
- closeTransaction(pNdb);
- return NDBT_FAILED;
- }
-
- for(a = 0; a<tab.getNoOfColumns(); a++){
- if (tab.getColumn(a)->getPrimaryKey() == true){
- if(equalForAttr(pUpdOp, a, r+b) != 0){
- ERR(pTrans->getNdbError());
+
+ if(pIndexScanOp)
+ {
+ int rows_found = 0;
+ while((check = pIndexScanOp->nextResult(true)) == 0)
+ {
+ do {
+
+ if (calc.verifyRowValues(rows[0]) != 0){
closeTransaction(pNdb);
return NDBT_FAILED;
}
- }
- }
-
- for(a = 0; a<tab.getNoOfColumns(); a++){
- if (tab.getColumn(a)->getPrimaryKey() == false){
- if(setValueForAttr(pUpdOp, a, r+b, updates ) != 0){
+
+ int updates = calc.getUpdatesValue(rows[0]) + 1;
+
+ if(pkUpdateRecord(pNdb, r+rows_found, 1, updates) != NDBT_OK)
+ {
ERR(pTrans->getNdbError());
closeTransaction(pNdb);
return NDBT_FAILED;
}
+ rows_found++;
+ } while((check = pIndexScanOp->nextResult(false)) == 0);
+
+ if(check != 2)
+ break;
+ if((check = pTrans->execute(NoCommit)) != 0)
+ break;
+ }
+ if(check != 1 || rows_found != batch)
+ {
+ closeTransaction(pNdb);
+ return NDBT_FAILED;
+ }
+ }
+ else
+ {
+ for(b = 0; b<batch && (b+r)<records; b++)
+ {
+ if (calc.verifyRowValues(rows[b]) != 0)
+ {
+ closeTransaction(pNdb);
+ return NDBT_FAILED;
+ }
+
+ int updates = calc.getUpdatesValue(rows[b]) + 1;
+
+ if(pkUpdateRecord(pNdb, r+b, 1, updates) != NDBT_OK)
+ {
+ ERR(pTrans->getNdbError());
+ closeTransaction(pNdb);
+ return NDBT_FAILED;
}
}
+ check = pTrans->execute(Commit);
}
-
- check = pTrans->execute(Commit);
if( check == -1 ) {
const NdbError err = pTrans->getNdbError();
@@ -1658,13 +1303,12 @@ HugoTransactions::pkUpdateRecords(Ndb* pNdb,
else{
updated += batch;
}
-
-
+
closeTransaction(pNdb);
-
+
r += batch; // Read next record
}
-
+
deallocRows();
g_info << "|- " << updated << " records updated" << endl;
return NDBT_OK;
@@ -1713,7 +1357,7 @@ HugoTransactions::pkInterpretedUpdateRecords(Ndb* pNdb,
if( check == -1 ) {
ERR(pTrans->getNdbError());
closeTransaction(pNdb);
- return NDBT_FAILED;
+ return NDBT_FAILED;
}
// Define primary keys
@@ -1861,6 +1505,8 @@ HugoTransactions::pkDelRecords(Ndb* pNdb,
g_info << "|- Deleting records..." << endl;
while (r < records){
+ if(r + batch > records)
+ batch = records - r;
if (retryAttempt >= retryMax){
g_info << "ERROR: has retried this operation " << retryAttempt
@@ -1885,30 +1531,13 @@ HugoTransactions::pkDelRecords(Ndb* pNdb,
return NDBT_FAILED;
}
- pOp = pTrans->getNdbOperation(tab.getName());
- if (pOp == NULL) {
- ERR(pTrans->getNdbError());
- closeTransaction(pNdb);
- return NDBT_FAILED;
- }
-
- check = pOp->deleteTuple();
- if( check == -1 ) {
+ if(pkDeleteRecord(pNdb, r, batch) != NDBT_OK)
+ {
ERR(pTrans->getNdbError());
closeTransaction(pNdb);
return NDBT_FAILED;
}
- // Define primary keys
- for(a = 0; a<tab.getNoOfColumns(); a++){
- if (tab.getColumn(a)->getPrimaryKey() == true){
- if(equalForAttr(pOp, a, r) != 0){
- ERR(pTrans->getNdbError());
- closeTransaction(pNdb);
- return NDBT_FAILED;
- }
- }
- }
check = pTrans->execute(Commit);
if( check == -1) {
const NdbError err = pTrans->getNdbError();
@@ -1946,11 +1575,11 @@ HugoTransactions::pkDelRecords(Ndb* pNdb,
}
}
else {
- deleted++;
+ deleted += batch;
}
closeTransaction(pNdb);
-
- r++; // Read next record
+
+ r += batch; // Read next record
}
@@ -1972,6 +1601,7 @@ HugoTransactions::lockRecords(Ndb* pNdb,
const int retryMax = 100;
int check, a, b;
NdbOperation *pOp;
+ NdbOperation::LockMode lm = NdbOperation::LM_Exclusive;
// Calculate how many records to lock in each batch
if (percentToLock <= 0)
@@ -1984,6 +1614,9 @@ HugoTransactions::lockRecords(Ndb* pNdb,
allocRows(lockBatch);
while (r < records){
+ if(r + lockBatch > records)
+ lockBatch = records - r;
+
g_info << "|- Locking " << lockBatch << " records..." << endl;
if (retryAttempt >= retryMax){
@@ -2006,42 +1639,13 @@ HugoTransactions::lockRecords(Ndb* pNdb,
return NDBT_FAILED;
}
- for(b = 0; (b<lockBatch) && (r+b < records); b++){
- pOp = pTrans->getNdbOperation(tab.getName());
- if (pOp == NULL) {
- ERR(pTrans->getNdbError());
- closeTransaction(pNdb);
- return NDBT_FAILED;
- }
-
- check = pOp->readTupleExclusive();
- if( check == -1 ) {
- ERR(pTrans->getNdbError());
- closeTransaction(pNdb);
- return NDBT_FAILED;
- }
-
- // Define primary keys
- for(a = 0; a<tab.getNoOfColumns(); a++){
- if (tab.getColumn(a)->getPrimaryKey() == true){
- if(equalForAttr(pOp, a, r+b) != 0){
- ERR(pTrans->getNdbError());
- closeTransaction(pNdb);
- return NDBT_FAILED;
- }
- }
- }
-
- // Define attributes to read
- for(a = 0; a<tab.getNoOfColumns(); a++){
- if((rows[b]->attributeStore(a) =
- pOp->getValue(tab.getColumn(a)->getName())) == 0) {
- ERR(pTrans->getNdbError());
- closeTransaction(pNdb);
- return NDBT_FAILED;
- }
- }
+ if(pkReadRecord(pNdb, r, lockBatch, lm) != NDBT_OK)
+ {
+ ERR(pTrans->getNdbError());
+ closeTransaction(pNdb);
+ return NDBT_FAILED;
}
+
// NoCommit lockTime times with 100 millis interval
int sleepInterval = 50;
int lockCount = lockTime / sleepInterval;
@@ -2099,8 +1703,7 @@ HugoTransactions::lockRecords(Ndb* pNdb,
}
closeTransaction(pNdb);
-
-
+
}
deallocRows();
g_info << "|- Record locking completed" << endl;
@@ -2111,7 +1714,7 @@ int
HugoTransactions::indexReadRecords(Ndb* pNdb,
const char * idxName,
int records,
- int batchsize){
+ int batch){
int reads = 0;
int r = 0;
int retryAttempt = 0;
@@ -2119,24 +1722,23 @@ HugoTransactions::indexReadRecords(Ndb* pNdb,
int check, a;
NdbOperation *pOp;
NdbIndexScanOperation *sOp;
- NdbResultSet * rs;
const NdbDictionary::Index* pIndex
= pNdb->getDictionary()->getIndex(idxName, tab.getName());
const bool ordered = (pIndex->getType()==NdbDictionary::Index::OrderedIndex);
- if (batchsize == 0) {
- g_info << "ERROR: Argument batchsize == 0 in indexReadRecords(). "
+ if (batch == 0) {
+ g_info << "ERROR: Argument batch == 0 in indexReadRecords(). "
<< "Not allowed." << endl;
return NDBT_FAILED;
}
if (ordered) {
- batchsize = 1;
+ batch = 1;
}
- allocRows(batchsize);
+ allocRows(batch);
while (r < records){
if (retryAttempt >= retryMax){
@@ -2159,7 +1761,7 @@ HugoTransactions::indexReadRecords(Ndb* pNdb,
return NDBT_FAILED;
}
- for(int b=0; (b<batchsize) && (r+b < records); b++){
+ for(int b=0; (b<batch) && (r+b < records); b++){
if(!ordered){
pOp = pTrans->getNdbIndexOperation(idxName, tab.getName());
if (pOp == NULL) {
@@ -2175,9 +1777,7 @@ HugoTransactions::indexReadRecords(Ndb* pNdb,
closeTransaction(pNdb);
return NDBT_FAILED;
}
-
- check = 0;
- rs = sOp->readTuples();
+ check = sOp->readTuples();
}
if( check == -1 ) {
@@ -2209,7 +1809,7 @@ HugoTransactions::indexReadRecords(Ndb* pNdb,
}
check = pTrans->execute(Commit);
- check = (check == -1 ? -1 : !ordered ? check : rs->nextResult(true));
+ check = (check == -1 ? -1 : !ordered ? check : sOp->nextResult(true));
if( check == -1 ) {
const NdbError err = pTrans->getNdbError();
@@ -2232,7 +1832,7 @@ HugoTransactions::indexReadRecords(Ndb* pNdb,
return NDBT_FAILED;
}
} else{
- for (int b=0; (b<batchsize) && (r+b<records); b++){
+ for (int b=0; (b<batch) && (r+b<records); b++){
if (calc.verifyRowValues(rows[b]) != 0){
closeTransaction(pNdb);
return NDBT_FAILED;
@@ -2240,7 +1840,7 @@ HugoTransactions::indexReadRecords(Ndb* pNdb,
reads++;
r++;
}
- if(ordered && rs->nextResult(true) == 0){
+ if(ordered && sOp->nextResult(true) == 0){
ndbout << "Error when comparing records "
<< " - index op next_result to many" << endl;
closeTransaction(pNdb);
@@ -2260,7 +1860,7 @@ int
HugoTransactions::indexUpdateRecords(Ndb* pNdb,
const char * idxName,
int records,
- int batchsize){
+ int batch){
int updated = 0;
int r = 0;
@@ -2269,17 +1869,16 @@ HugoTransactions::indexUpdateRecords(Ndb* pNdb,
int check, a, b;
NdbOperation *pOp;
NdbScanOperation * sOp;
- NdbResultSet * rs;
const NdbDictionary::Index* pIndex
= pNdb->getDictionary()->getIndex(idxName, tab.getName());
const bool ordered = (pIndex->getType()==NdbDictionary::Index::OrderedIndex);
if (ordered){
- batchsize = 1;
+ batch = 1;
}
- allocRows(batchsize);
+ allocRows(batch);
while (r < records){
if (retryAttempt >= retryMax){
@@ -2302,7 +1901,7 @@ HugoTransactions::indexUpdateRecords(Ndb* pNdb,
return NDBT_FAILED;
}
- for(b = 0; b<batchsize && (b+r)<records; b++){
+ for(b = 0; b<batch && (b+r)<records; b++){
if(!ordered){
pOp = pTrans->getNdbIndexOperation(idxName, tab.getName());
if (pOp == NULL) {
@@ -2326,7 +1925,7 @@ HugoTransactions::indexUpdateRecords(Ndb* pNdb,
}
check = 0;
- rs = sOp->readTuplesExclusive();
+ sOp->readTuplesExclusive();
}
// Define primary keys
@@ -2352,7 +1951,7 @@ HugoTransactions::indexUpdateRecords(Ndb* pNdb,
}
check = pTrans->execute(NoCommit);
- check = (check == -1 ? -1 : !ordered ? check : rs->nextResult(true));
+ check = (check == -1 ? -1 : !ordered ? check : sOp->nextResult(true));
if( check == -1 ) {
const NdbError err = pTrans->getNdbError();
ERR(err);
@@ -2367,12 +1966,12 @@ HugoTransactions::indexUpdateRecords(Ndb* pNdb,
}
if(ordered && check != 0){
- g_err << "Row: " << r << " not found!!" << endl;
+ g_err << check << " - Row: " << r << " not found!!" << endl;
closeTransaction(pNdb);
return NDBT_FAILED;
}
- for(b = 0; b<batchsize && (b+r)<records; b++){
+ for(b = 0; b<batch && (b+r)<records; b++){
if (calc.verifyRowValues(rows[b]) != 0){
closeTransaction(pNdb);
return NDBT_FAILED;
@@ -2385,7 +1984,7 @@ HugoTransactions::indexUpdateRecords(Ndb* pNdb,
pUpdOp = pTrans->getNdbIndexOperation(idxName, tab.getName());
check = (pUpdOp == 0 ? -1 : pUpdOp->updateTuple());
} else {
- pUpdOp = rs->updateTuple();
+ pUpdOp = sOp->updateCurrentTuple();
}
if (pUpdOp == NULL) {
@@ -2437,12 +2036,12 @@ HugoTransactions::indexUpdateRecords(Ndb* pNdb,
ndbout << "r = " << r << endl;
return NDBT_FAILED;
} else {
- updated += batchsize;
+ updated += batch;
}
closeTransaction(pNdb);
- r+= batchsize; // Read next record
+ r+= batch; // Read next record
}
g_info << "|- " << updated << " records updated" << endl;
diff --git a/ndb/test/src/NDBT_ResultRow.cpp b/ndb/test/src/NDBT_ResultRow.cpp
index 11554b4a9b3..ab8d7b07ea1 100644
--- a/ndb/test/src/NDBT_ResultRow.cpp
+++ b/ndb/test/src/NDBT_ResultRow.cpp
@@ -84,7 +84,7 @@ NDBT_ResultRow::header (NdbOut & out) const {
return out;
}
-BaseString NDBT_ResultRow::c_str() {
+BaseString NDBT_ResultRow::c_str() const {
BaseString str;
@@ -137,3 +137,10 @@ NDBT_ResultRow::clone () const {
return row;
}
+
+bool
+NDBT_ResultRow::operator==(const NDBT_ResultRow& other) const
+{
+ // quick and dirty
+ return c_str() == other.c_str();
+}
diff --git a/ndb/test/src/NDBT_Tables.cpp b/ndb/test/src/NDBT_Tables.cpp
index ff6db3e892c..5a5fecd85c1 100644
--- a/ndb/test/src/NDBT_Tables.cpp
+++ b/ndb/test/src/NDBT_Tables.cpp
@@ -48,7 +48,7 @@ const
NDBT_Attribute T2Attribs[] = {
NDBT_Attribute("KOL1", NdbDictionary::Column::Bigunsigned, 1, true),
NDBT_Attribute("KOL2", NdbDictionary::Column::Unsigned),
- NDBT_Attribute("KOL3", NdbDictionary::Column::Unsigned),
+ NDBT_Attribute("KOL3", NdbDictionary::Column::Bit, 23),
NDBT_Attribute("KOL4", NdbDictionary::Column::Unsigned,
1, false, true), // Nullable
NDBT_Attribute("KOL5", NdbDictionary::Column::Unsigned)
@@ -820,21 +820,25 @@ NDBT_Tables::createAllTables(Ndb* pNdb){
int
NDBT_Tables::createTable(Ndb* pNdb, const char* _name, bool _temp,
- bool existsOk){
+ bool existsOk, NDBT_CreateTableHook f){
const NdbDictionary::Table* tab = NDBT_Tables::getTable(_name);
if (tab == NULL){
ndbout << "Could not create table " << _name
<< ", it doesn't exist in list of tables "\
- "that NDBT_Tables can create!" << endl;
+ "that NDBT_Tables can create!" << endl;
return NDBT_WRONGARGS;
}
-
+
int r = 0;
do {
NdbDictionary::Table tmpTab(* tab);
tmpTab.setStoredTable(_temp ? 0 : 1);
-
+ if(f != 0 && f(pNdb, tmpTab, 0))
+ {
+ ndbout << "Failed to create table" << endl;
+ return NDBT_FAILED;
+ }
r = pNdb->getDictionary()->createTable(tmpTab);
if(r == -1){
if(!existsOk){
@@ -883,6 +887,11 @@ NDBT_Tables::createTable(Ndb* pNdb, const char* _name, bool _temp,
}
}
}
+ if(f != 0 && f(pNdb, tmpTab, 1))
+ {
+ ndbout << "Failed to create table" << endl;
+ return NDBT_FAILED;
+ }
} while(false);
return r;
diff --git a/ndb/test/src/NDBT_Test.cpp b/ndb/test/src/NDBT_Test.cpp
index 6355c21c997..8fecf56531f 100644
--- a/ndb/test/src/NDBT_Test.cpp
+++ b/ndb/test/src/NDBT_Test.cpp
@@ -15,6 +15,7 @@
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
#include <ndb_global.h>
+#include <my_pthread.h>
#include "NDBT.hpp"
#include "NDBT_Test.hpp"
@@ -26,7 +27,9 @@
// No verbose outxput
-NDBT_Context::NDBT_Context(){
+NDBT_Context::NDBT_Context(Ndb_cluster_connection& con)
+ : m_cluster_connection(con)
+{
tab = NULL;
suite = NULL;
testcase = NULL;
@@ -248,7 +251,7 @@ int NDBT_Step::execute(NDBT_Context* ctx) {
g_info << " |- " << name << " started [" << ctx->suite->getDate() << "]"
<< endl;
- result = setUp();
+ result = setUp(ctx->m_cluster_connection);
if (result != NDBT_OK){
return result;
}
@@ -288,10 +291,10 @@ NDBT_NdbApiStep::NDBT_NdbApiStep(NDBT_TestCase* ptest,
int
-NDBT_NdbApiStep::setUp(){
- ndb = new Ndb( "TEST_DB" );
+NDBT_NdbApiStep::setUp(Ndb_cluster_connection& con){
+ ndb = new Ndb(&con, "TEST_DB" );
ndb->init(1024);
-
+
int result = ndb->waitUntilReady(300); // 5 minutes
if (result != 0){
g_err << name << ": Ndb was not ready" << endl;
@@ -624,8 +627,7 @@ int NDBT_TestCase::execute(NDBT_Context* ctx){
<< endl;
}
return res;
-};
-
+}
void NDBT_TestCase::startTimer(NDBT_Context* ctx){
timer.doStart();
@@ -757,14 +759,15 @@ int NDBT_TestSuite::addTest(NDBT_TestCase* pTest){
return 0;
}
-int NDBT_TestSuite::executeAll(const char* _testname){
+int NDBT_TestSuite::executeAll(Ndb_cluster_connection& con,
+ const char* _testname){
if(tests.size() == 0)
return NDBT_FAILED;
- Ndb ndb("TEST_DB");
+ Ndb ndb(&con, "TEST_DB");
ndb.init(1024);
- int result = ndb.waitUntilReady(300); // 5 minutes
+ int result = ndb.waitUntilReady(500); // 5 minutes
if (result != 0){
g_err << name <<": Ndb was not ready" << endl;
return NDBT_FAILED;
@@ -777,18 +780,19 @@ int NDBT_TestSuite::executeAll(const char* _testname){
for (int t=0; t < NDBT_Tables::getNumTables(); t++){
const NdbDictionary::Table* ptab = NDBT_Tables::getTable(t);
ndbout << "|- " << ptab->getName() << endl;
- execute(&ndb, ptab, _testname);
+ execute(con, &ndb, ptab, _testname);
}
testSuiteTimer.doStop();
return reportAllTables(_testname);
}
int
-NDBT_TestSuite::executeOne(const char* _tabname, const char* _testname){
+NDBT_TestSuite::executeOne(Ndb_cluster_connection& con,
+ const char* _tabname, const char* _testname){
if(tests.size() == 0)
return NDBT_FAILED;
- Ndb ndb("TEST_DB");
+ Ndb ndb(&con, "TEST_DB");
ndb.init(1024);
int result = ndb.waitUntilReady(300); // 5 minutes
@@ -805,7 +809,7 @@ NDBT_TestSuite::executeOne(const char* _tabname, const char* _testname){
ndbout << "|- " << ptab->getName() << endl;
- execute(&ndb, ptab, _testname);
+ execute(con, &ndb, ptab, _testname);
if (numTestsFail > 0){
return NDBT_FAILED;
@@ -814,7 +818,8 @@ NDBT_TestSuite::executeOne(const char* _tabname, const char* _testname){
}
}
-void NDBT_TestSuite::execute(Ndb* ndb, const NdbDictionary::Table* pTab,
+void NDBT_TestSuite::execute(Ndb_cluster_connection& con,
+ Ndb* ndb, const NdbDictionary::Table* pTab,
const char* _testname){
int result;
@@ -856,14 +861,14 @@ void NDBT_TestSuite::execute(Ndb* ndb, const NdbDictionary::Table* pTab,
pTab2 = pTab;
}
- ctx = new NDBT_Context();
+ ctx = new NDBT_Context(con);
ctx->setTab(pTab2);
ctx->setNumRecords(records);
ctx->setNumLoops(loops);
if(remote_mgm != NULL)
ctx->setRemoteMgm(remote_mgm);
ctx->setSuite(this);
-
+
result = tests[t]->execute(ctx);
tests[t]->saveTestResult(pTab, result);
if (result != NDBT_OK)
@@ -1035,14 +1040,19 @@ int NDBT_TestSuite::execute(int argc, const char** argv){
loops = _loops;
timer = _timer;
+ Ndb_cluster_connection con;
+ if(con.connect(12, 5, 1))
+ {
+ return NDBT_ProgramExit(NDBT_FAILED);
+ }
+
if(optind == argc){
// No table specified
- res = executeAll(_testname);
+ res = executeAll(con, _testname);
} else {
testSuiteTimer.doStart();
- Ndb ndb("TEST_DB"); ndb.init();
for(int i = optind; i<argc; i++){
- executeOne(argv[i], _testname);
+ executeOne(con, argv[i], _testname);
}
testSuiteTimer.doStop();
res = report(_testname);
diff --git a/ndb/test/src/NdbBackup.cpp b/ndb/test/src/NdbBackup.cpp
index 28724323bd7..fe101b9c80b 100644
--- a/ndb/test/src/NdbBackup.cpp
+++ b/ndb/test/src/NdbBackup.cpp
@@ -342,7 +342,7 @@ NdbBackup::NF(NdbRestarter& _restarter, int *NFDuringBackup_codes, const int sz,
}
return NDBT_OK;
-};
+}
int
FailS_codes[] = {
diff --git a/ndb/test/src/NdbRestarts.cpp b/ndb/test/src/NdbRestarts.cpp
index 607e48c4126..c0f31af84ce 100644
--- a/ndb/test/src/NdbRestarts.cpp
+++ b/ndb/test/src/NdbRestarts.cpp
@@ -213,7 +213,7 @@ NdbRestarts::NdbRestart::NdbRestart(const char* _name,
m_restartFunc = _func;
m_numRequiredNodes = _requiredNodes;
// m_arg1 = arg1;
-};
+}
int NdbRestarts::getNumRestarts(){
@@ -367,7 +367,7 @@ int restartRandomNodeGraceful(NdbRestarter& _restarter,
"Could not restart node "<<nodeId);
return NDBT_OK;
-};
+}
int restartRandomNodeAbort(NdbRestarter& _restarter,
const NdbRestarts::NdbRestart* _restart){
@@ -382,7 +382,7 @@ int restartRandomNodeAbort(NdbRestarter& _restarter,
"Could not restart node "<<nodeId);
return NDBT_OK;
-};
+}
int restartRandomNodeError(NdbRestarter& _restarter,
const NdbRestarts::NdbRestart* _restart){
@@ -397,7 +397,7 @@ int restartRandomNodeError(NdbRestarter& _restarter,
"Could not restart node "<<nodeId);
return NDBT_OK;
-};
+}
int restartMasterNodeError(NdbRestarter& _restarter,
const NdbRestarts::NdbRestart* _restart){
@@ -410,7 +410,7 @@ int restartMasterNodeError(NdbRestarter& _restarter,
"Could not restart node "<<nodeId);
return NDBT_OK;
-};
+}
int restartRandomNodeInitial(NdbRestarter& _restarter,
const NdbRestarts::NdbRestart* _restart){
@@ -425,7 +425,7 @@ int restartRandomNodeInitial(NdbRestarter& _restarter,
"Could not restart node "<<nodeId);
return NDBT_OK;
-};
+}
int twoNodeFailure(NdbRestarter& _restarter,
const NdbRestarts::NdbRestart* _restart){
@@ -453,7 +453,7 @@ int twoNodeFailure(NdbRestarter& _restarter,
"Could not restart node "<< nodeId);
return NDBT_OK;
-};
+}
int twoMasterNodeFailure(NdbRestarter& _restarter,
const NdbRestarts::NdbRestart* _restart){
@@ -478,7 +478,7 @@ int twoMasterNodeFailure(NdbRestarter& _restarter,
"Could not restart node "<< nodeId);
return NDBT_OK;
-};
+}
int get50PercentOfNodes(NdbRestarter& restarter,
int * _nodes){
@@ -519,7 +519,7 @@ int fiftyPercentFail(NdbRestarter& _restarter,
"Could not start all nodes");
return NDBT_OK;
-};
+}
int restartAllNodesGracfeul(NdbRestarter& _restarter,
@@ -533,7 +533,7 @@ int restartAllNodesGracfeul(NdbRestarter& _restarter,
return NDBT_OK;
-};
+}
int restartAllNodesAbort(NdbRestarter& _restarter,
const NdbRestarts::NdbRestart* _restart){
@@ -545,7 +545,7 @@ int restartAllNodesAbort(NdbRestarter& _restarter,
"Could not restart all nodes");
return NDBT_OK;
-};
+}
int restartAllNodesError9999(NdbRestarter& _restarter,
const NdbRestarts::NdbRestart* _restart){
@@ -557,7 +557,7 @@ int restartAllNodesError9999(NdbRestarter& _restarter,
"Could not restart all nodes ");
return NDBT_OK;
-};
+}
int fiftyPercentStopAndWait(NdbRestarter& _restarter,
const NdbRestarts::NdbRestart* _restart){
@@ -590,7 +590,7 @@ int fiftyPercentStopAndWait(NdbRestarter& _restarter,
g_info << _restart->m_name << endl;
return NDBT_OK;
-};
+}
int
NFDuringNR_codes[] = {
@@ -713,7 +713,7 @@ int restartNFDuringNR(NdbRestarter& _restarter,
}
return NDBT_OK;
-};
+}
int
NRDuringLCP_Master_codes[] = {
@@ -864,7 +864,7 @@ int stopOnError(NdbRestarter& _restarter,
} while (false);
return NDBT_OK;
-};
+}
int getRandomNodeId(NdbRestarter& _restarter) {
myRandom48Init(NdbTick_CurrentMillisecond());
diff --git a/ndb/test/src/NdbSchemaOp.cpp b/ndb/test/src/NdbSchemaOp.cpp
index a296094ea9d..4281ceb02c8 100644
--- a/ndb/test/src/NdbSchemaOp.cpp
+++ b/ndb/test/src/NdbSchemaOp.cpp
@@ -113,7 +113,7 @@ NdbSchemaOp::createAttribute( const char* anAttrName,
AttrType anAttrType,
StorageMode aStorageMode,
bool nullable,
- StorageAttributeType aStorageAttr,
+ int aStorageAttr,
int aDistributionKeyFlag,
int aDistributionGroupFlag,
int aDistributionGroupNoOfBits,
@@ -158,7 +158,6 @@ NdbSchemaOp::createAttribute( const char* anAttrName,
col.setPrimaryKey(false);
col.setDistributionKey(aDistributionKeyFlag);
- col.setDistributionGroup(aDistributionGroupFlag,aDistributionGroupNoOfBits);
col.setAutoIncrement(aAutoIncrement);
col.setDefaultValue(aDefaultValue != 0 ? aDefaultValue : "");
diff --git a/ndb/test/src/UtilTransactions.cpp b/ndb/test/src/UtilTransactions.cpp
index 92073143d34..31c323045ed 100644
--- a/ndb/test/src/UtilTransactions.cpp
+++ b/ndb/test/src/UtilTransactions.cpp
@@ -20,13 +20,20 @@
#define VERBOSE 0
-UtilTransactions::UtilTransactions(const NdbDictionary::Table& _tab):
- tab(_tab){
+UtilTransactions::UtilTransactions(const NdbDictionary::Table& _tab,
+ const NdbDictionary::Index* _idx):
+ tab(_tab), idx(_idx), pTrans(0)
+{
m_defaultClearMethod = 3;
}
-UtilTransactions::UtilTransactions(Ndb* ndb, const char * name) :
- tab(* ndb->getDictionary()->getTable(name)){
+UtilTransactions::UtilTransactions(Ndb* ndb,
+ const char * name,
+ const char * index) :
+ tab(* ndb->getDictionary()->getTable(name)),
+ idx(index ? ndb->getDictionary()->getIndex(index, name) : 0),
+ pTrans(0)
+{
m_defaultClearMethod = 3;
}
@@ -51,313 +58,29 @@ UtilTransactions::clearTable(Ndb* pNdb,
int
UtilTransactions::clearTable1(Ndb* pNdb,
int records,
- int parallelism){
-#if 1
+ int parallelism)
+{
return clearTable3(pNdb, records, 1);
-#else
- // Scan all records exclusive and delete
- // them one by one
- int retryAttempt = 0;
- const int retryMax = 100;
- int check;
- NdbConnection *pTrans;
- NdbOperation *pOp;
-
- while (true){
-
- if (retryAttempt >= retryMax){
- g_info << "ERROR: Has retried this operation " << retryAttempt
- << " times, failing!" << endl;
- return NDBT_FAILED;
- }
-
-
- pTrans = pNdb->startTransaction();
- if (pTrans == NULL) {
- NdbError err = pNdb->getNdbError();
-
- if (err.status == NdbError::TemporaryError){
- ERR(err);
- NdbSleep_MilliSleep(50);
- retryAttempt++;
- continue;
- }
- ERR(err);
- RETURN_FAIL(err);
- }
-
- pOp = pTrans->getNdbOperation(tab.getName());
- if (pOp == NULL) {
- NdbError err = pNdb->getNdbError();
- ERR(err);
- pNdb->closeTransaction(pTrans);
- RETURN_FAIL(err);
- }
-
- check = pOp->openScanExclusive(parallelism);
- if( check == -1 ) {
- NdbError err = pNdb->getNdbError();
- ERR(pTrans->getNdbError());
- pNdb->closeTransaction(pTrans);
- RETURN_FAIL(err);
- }
-
- check = pOp->interpret_exit_ok();
- if( check == -1 ) {
- NdbError err = pNdb->getNdbError();
- ERR(pTrans->getNdbError());
- pNdb->closeTransaction(pTrans);
- RETURN_FAIL(err);
- }
-#if 0
- // It's not necessary to read and PK's
- // Information about the PK's are sent in
- // KEYINFO20 signals anyway and used by takeOverScan
-
- // Read the primary keys from this table
- for(int a=0; a<tab.getNoOfColumns(); a++){
- if (tab.getColumn(a)->getPrimaryKey()){
- if(pOp->getValue(tab.getColumn(a)->getName()) == NULL){
- ERR(pTrans->getNdbError());
- pNdb->closeTransaction(pTrans);
- RETURN_FAIL(err);
- }
- }
- }
-#endif
-
- check = pTrans->executeScan();
- if( check == -1 ) {
- NdbError err = pTrans->getNdbError();
-
- if (err.status == NdbError::TemporaryError){
- ERR(err);
- pNdb->closeTransaction(pTrans);
- NdbSleep_MilliSleep(50);
- retryAttempt++;
- continue;
- }
- ERR(err);
- pNdb->closeTransaction(pTrans);
- RETURN_FAIL(err);
- }
-
- int eof;
- int rows = 0;
-
- eof = pTrans->nextScanResult();
- while(eof == 0){
- rows++;
-
- int res = takeOverAndDeleteRecord(pNdb, pOp);
- if(res == RESTART_SCAN){
- eof = -2;
- continue;
- }
-
- if (res != 0){
- NdbError err = pNdb->getNdbError(res);
- pNdb->closeTransaction(pTrans);
- RETURN_FAIL(err);
- }
-
- eof = pTrans->nextScanResult();
- }
-
- if (eof == -1) {
- const NdbError err = pTrans->getNdbError();
-
- if (err.status == NdbError::TemporaryError){
- ERR(err);
- pNdb->closeTransaction(pTrans);
- NdbSleep_MilliSleep(50);
- // If error = 488 there should be no limit on number of retry attempts
- if (err.code != 488)
- retryAttempt++;
- continue;
- }
- ERR(err);
- pNdb->closeTransaction(pTrans);
- RETURN_FAIL(err);
- }
-
- if(eof == -2){
- pNdb->closeTransaction(pTrans);
- NdbSleep_MilliSleep(50);
- retryAttempt++;
- continue;
- }
-
- pNdb->closeTransaction(pTrans);
-
- g_info << rows << " deleted" << endl;
-
- return NDBT_OK;
- }
- return NDBT_FAILED;
-#endif
}
int
UtilTransactions::clearTable2(Ndb* pNdb,
- int records,
- int parallelism){
-#if 1
+ int records,
+ int parallelism)
+{
return clearTable3(pNdb, records, parallelism);
-#else
- // Scan all records exclusive and delete
- // them one by one
- int retryAttempt = 0;
- const int retryMax = 10;
- int deletedRows = 0;
- int check;
- NdbConnection *pTrans;
- NdbOperation *pOp;
-
- while (true){
-
- if (retryAttempt >= retryMax){
- g_info << "ERROR: has retried this operation " << retryAttempt
- << " times, failing!" << endl;
- return NDBT_FAILED;
- }
-
-
- pTrans = pNdb->startTransaction();
- if (pTrans == NULL) {
- const NdbError err = pNdb->getNdbError();
-
- if (err.status == NdbError::TemporaryError){
- ERR(err);
- NdbSleep_MilliSleep(50);
- retryAttempt++;
- continue;
- }
- ERR(err);
- return NDBT_FAILED;
- }
-
- pOp = pTrans->getNdbOperation(tab.getName());
- if (pOp == NULL) {
- ERR(pTrans->getNdbError());
- pNdb->closeTransaction(pTrans);
- return NDBT_FAILED;
- }
-
- check = pOp->openScanExclusive(parallelism);
- if( check == -1 ) {
- ERR(pTrans->getNdbError());
- pNdb->closeTransaction(pTrans);
- return NDBT_FAILED;
- }
-
- check = pOp->interpret_exit_ok();
- if( check == -1 ) {
- ERR(pTrans->getNdbError());
- pNdb->closeTransaction(pTrans);
- return NDBT_FAILED;
- }
-#if 0
- // It's not necessary to read any PK's
- // Information about the PK's are sent in
- // KEYINFO20 signals anyway and used by takeOverScan
-
- // Read the primary keys from this table
- for(int a=0; a<tab.getNoOfColumns(); a++){
- if (tab.getColumn(a)->getPrimaryKey()){
- if(pOp->getValue(tab.getColumn(a)->getName()) == NULL){
- ERR(pTrans->getNdbError());
- pNdb->closeTransaction(pTrans);
- return -1;
- }
- }
- }
-#endif
-
- check = pTrans->executeScan();
- if( check == -1 ) {
- ERR(pTrans->getNdbError());
- pNdb->closeTransaction(pTrans);
- return NDBT_FAILED;
- }
-
- int eof;
- NdbConnection* pDelTrans;
-
- while((eof = pTrans->nextScanResult(true)) == 0){
- pDelTrans = pNdb->startTransaction();
- if (pDelTrans == NULL) {
- const NdbError err = pNdb->getNdbError();
-#if 0
- if (err.status == NdbError::TemporaryError){
- ERR(err);
- NdbSleep_MilliSleep(50);
- retryAttempt++;
- continue;
- }
-#endif
- ERR(err);
- pNdb->closeTransaction(pDelTrans);
- return NDBT_FAILED;
- }
- do {
- deletedRows++;
- if (addRowToDelete(pNdb, pDelTrans, pOp) != 0){
- pNdb->closeTransaction(pDelTrans);
- pNdb->closeTransaction(pTrans);
- return NDBT_FAILED;
- }
- } while((eof = pTrans->nextScanResult(false)) == 0);
-
- check = pDelTrans->execute(Commit);
- if( check == -1 ) {
- const NdbError err = pDelTrans->getNdbError();
- ERR(err);
- pNdb->closeTransaction(pDelTrans);
- pNdb->closeTransaction(pTrans);
- return NDBT_FAILED;
- }
- pNdb->closeTransaction(pDelTrans);
-
- }
- if (eof == -1) {
- const NdbError err = pTrans->getNdbError();
-
- if (err.status == NdbError::TemporaryError){
- ERR(err);
- pNdb->closeTransaction(pTrans);
- NdbSleep_MilliSleep(50);
- // If error = 488 there should be no limit on number of retry attempts
- if (err.code != 488)
- retryAttempt++;
- continue;
- }
- ERR(err);
- pNdb->closeTransaction(pTrans);
- return NDBT_FAILED;
- }
-
- pNdb->closeTransaction(pTrans);
-
- g_info << deletedRows << " rows deleted" << endl;
-
- return NDBT_OK;
- }
- return NDBT_FAILED;
-#endif
}
int
UtilTransactions::clearTable3(Ndb* pNdb,
- int records,
- int parallelism){
+ int records,
+ int parallelism){
// Scan all records exclusive and delete
// them one by one
int retryAttempt = 0;
const int retryMax = 10;
int deletedRows = 0;
int check;
- NdbConnection *pTrans;
NdbScanOperation *pOp;
NdbError err;
@@ -380,13 +103,13 @@ UtilTransactions::clearTable3(Ndb* pNdb,
}
goto failed;
}
-
- pOp = pTrans->getNdbScanOperation(tab.getName());
+
+ pOp = getScanOperation(pTrans);
if (pOp == NULL) {
err = pTrans->getNdbError();
if(err.status == NdbError::TemporaryError){
ERR(err);
- pNdb->closeTransaction(pTrans);
+ closeTransaction(pNdb);
NdbSleep_MilliSleep(50);
par = 1;
goto restart;
@@ -394,8 +117,7 @@ UtilTransactions::clearTable3(Ndb* pNdb,
goto failed;
}
- NdbResultSet * rs = pOp->readTuplesExclusive(par);
- if( rs == 0 ) {
+ if( pOp->readTuplesExclusive(par) ) {
err = pTrans->getNdbError();
goto failed;
}
@@ -404,20 +126,20 @@ UtilTransactions::clearTable3(Ndb* pNdb,
err = pTrans->getNdbError();
if(err.status == NdbError::TemporaryError){
ERR(err);
- pNdb->closeTransaction(pTrans);
+ closeTransaction(pNdb);
NdbSleep_MilliSleep(50);
continue;
}
goto failed;
}
- while((check = rs->nextResult(true)) == 0){
+ while((check = pOp->nextResult(true)) == 0){
do {
- if (rs->deleteTuple() != 0){
+ if (pOp->deleteCurrentTuple() != 0){
goto failed;
}
deletedRows++;
- } while((check = rs->nextResult(false)) == 0);
+ } while((check = pOp->nextResult(false)) == 0);
if(check != -1){
check = pTrans->execute(Commit);
@@ -428,7 +150,7 @@ UtilTransactions::clearTable3(Ndb* pNdb,
if(check == -1){
if(err.status == NdbError::TemporaryError){
ERR(err);
- pNdb->closeTransaction(pTrans);
+ closeTransaction(pNdb);
NdbSleep_MilliSleep(50);
par = 1;
goto restart;
@@ -440,20 +162,20 @@ UtilTransactions::clearTable3(Ndb* pNdb,
err = pTrans->getNdbError();
if(err.status == NdbError::TemporaryError){
ERR(err);
- pNdb->closeTransaction(pTrans);
+ closeTransaction(pNdb);
NdbSleep_MilliSleep(50);
par = 1;
goto restart;
}
goto failed;
}
- pNdb->closeTransaction(pTrans);
+ closeTransaction(pNdb);
return NDBT_OK;
}
return NDBT_FAILED;
failed:
- if(pTrans != 0) pNdb->closeTransaction(pTrans);
+ closeTransaction(pNdb);
ERR(err);
return (err.code != 0 ? err.code : NDBT_FAILED);
}
@@ -468,7 +190,6 @@ UtilTransactions::copyTableData(Ndb* pNdb,
int insertedRows = 0;
int parallelism = 240;
int check;
- NdbConnection *pTrans;
NdbScanOperation *pOp;
NDBT_ResultRow row(tab);
@@ -498,22 +219,20 @@ UtilTransactions::copyTableData(Ndb* pNdb,
pOp = pTrans->getNdbScanOperation(tab.getName());
if (pOp == NULL) {
ERR(pTrans->getNdbError());
- pNdb->closeTransaction(pTrans);
+ closeTransaction(pNdb);
return NDBT_FAILED;
}
- NdbResultSet* rs = pOp->readTuples(NdbScanOperation::LM_Read,
- parallelism);
- if( check == -1 ) {
+ if( pOp->readTuples(NdbScanOperation::LM_Read, parallelism) ) {
ERR(pTrans->getNdbError());
- pNdb->closeTransaction(pTrans);
+ closeTransaction(pNdb);
return NDBT_FAILED;
}
check = pOp->interpret_exit_ok();
if( check == -1 ) {
ERR(pTrans->getNdbError());
- pNdb->closeTransaction(pTrans);
+ closeTransaction(pNdb);
return NDBT_FAILED;
}
@@ -522,7 +241,7 @@ UtilTransactions::copyTableData(Ndb* pNdb,
if ((row.attributeStore(a) =
pOp->getValue(tab.getColumn(a)->getName())) == 0) {
ERR(pTrans->getNdbError());
- pNdb->closeTransaction(pTrans);
+ closeTransaction(pNdb);
return NDBT_FAILED;
}
}
@@ -530,26 +249,26 @@ UtilTransactions::copyTableData(Ndb* pNdb,
check = pTrans->execute(NoCommit);
if( check == -1 ) {
ERR(pTrans->getNdbError());
- pNdb->closeTransaction(pTrans);
+ closeTransaction(pNdb);
return NDBT_FAILED;
}
int eof;
- while((eof = rs->nextResult(true)) == 0){
+ while((eof = pOp->nextResult(true)) == 0){
do {
insertedRows++;
if (addRowToInsert(pNdb, pTrans, row, destName) != 0){
- pNdb->closeTransaction(pTrans);
+ closeTransaction(pNdb);
return NDBT_FAILED;
}
- } while((eof = rs->nextResult(false)) == 0);
+ } while((eof = pOp->nextResult(false)) == 0);
check = pTrans->execute(Commit);
pTrans->restart();
if( check == -1 ) {
const NdbError err = pTrans->getNdbError();
ERR(err);
- pNdb->closeTransaction(pTrans);
+ closeTransaction(pNdb);
return NDBT_FAILED;
}
}
@@ -558,7 +277,7 @@ UtilTransactions::copyTableData(Ndb* pNdb,
if (err.status == NdbError::TemporaryError){
ERR(err);
- pNdb->closeTransaction(pTrans);
+ closeTransaction(pNdb);
NdbSleep_MilliSleep(50);
// If error = 488 there should be no limit on number of retry attempts
if (err.code != 488)
@@ -566,11 +285,11 @@ UtilTransactions::copyTableData(Ndb* pNdb,
continue;
}
ERR(err);
- pNdb->closeTransaction(pTrans);
+ closeTransaction(pNdb);
return NDBT_FAILED;
}
- pNdb->closeTransaction(pTrans);
+ closeTransaction(pNdb);
g_info << insertedRows << " rows copied" << endl;
@@ -628,7 +347,6 @@ UtilTransactions::scanReadRecords(Ndb* pNdb,
int retryAttempt = 0;
const int retryMax = 100;
int check;
- NdbConnection *pTrans;
NdbScanOperation *pOp;
NDBT_ResultRow row(tab);
@@ -654,10 +372,10 @@ UtilTransactions::scanReadRecords(Ndb* pNdb,
return NDBT_FAILED;
}
- pOp = pTrans->getNdbScanOperation(tab.getName());
+ pOp = getScanOperation(pTrans);
if (pOp == NULL) {
const NdbError err = pNdb->getNdbError();
- pNdb->closeTransaction(pTrans);
+ closeTransaction(pNdb);
if (err.status == NdbError::TemporaryError){
ERR(err);
@@ -669,17 +387,16 @@ UtilTransactions::scanReadRecords(Ndb* pNdb,
return NDBT_FAILED;
}
- NdbResultSet * rs = pOp->readTuples(lm, 0, parallelism);
- if( rs == 0 ) {
+ if( pOp->readTuples(lm, 0, parallelism) ) {
ERR(pTrans->getNdbError());
- pNdb->closeTransaction(pTrans);
+ closeTransaction(pNdb);
return NDBT_FAILED;
}
check = pOp->interpret_exit_ok();
if( check == -1 ) {
ERR(pTrans->getNdbError());
- pNdb->closeTransaction(pTrans);
+ closeTransaction(pNdb);
return NDBT_FAILED;
}
@@ -691,7 +408,7 @@ UtilTransactions::scanReadRecords(Ndb* pNdb,
if ((row.attributeStore(attrib_list[a]) =
pOp->getValue(tab.getColumn(attrib_list[a])->getName())) == 0) {
ERR(pTrans->getNdbError());
- pNdb->closeTransaction(pTrans);
+ closeTransaction(pNdb);
return NDBT_FAILED;
}
}
@@ -704,13 +421,13 @@ UtilTransactions::scanReadRecords(Ndb* pNdb,
if (err.status == NdbError::TemporaryError){
ERR(err);
- pNdb->closeTransaction(pTrans);
+ closeTransaction(pNdb);
NdbSleep_MilliSleep(50);
retryAttempt++;
continue;
}
ERR(err);
- pNdb->closeTransaction(pTrans);
+ closeTransaction(pNdb);
return NDBT_FAILED;
}
@@ -718,7 +435,7 @@ UtilTransactions::scanReadRecords(Ndb* pNdb,
int rows = 0;
- while((eof = rs->nextResult()) == 0){
+ while((eof = pOp->nextResult()) == 0){
rows++;
// Call callback for each record returned
@@ -730,17 +447,17 @@ UtilTransactions::scanReadRecords(Ndb* pNdb,
if (err.status == NdbError::TemporaryError){
ERR(err);
- pNdb->closeTransaction(pTrans);
+ closeTransaction(pNdb);
NdbSleep_MilliSleep(50);
retryAttempt++;
continue;
}
ERR(err);
- pNdb->closeTransaction(pTrans);
+ closeTransaction(pNdb);
return NDBT_FAILED;
}
- pNdb->closeTransaction(pTrans);
+ closeTransaction(pNdb);
g_info << rows << " rows have been read" << endl;
if (records != 0 && rows != records){
g_info << "Check expected number of records failed" << endl
@@ -766,37 +483,26 @@ UtilTransactions::selectCount(Ndb* pNdb,
int check;
NdbScanOperation *pOp;
+ if(!pTrans)
+ pTrans = pNdb->startTransaction();
+
while (true){
+
if (retryAttempt >= retryMax){
g_info << "ERROR: has retried this operation " << retryAttempt
<< " times, failing!" << endl;
return NDBT_FAILED;
}
- if(!pTrans)
- pTrans = pNdb->startTransaction();
-
- if(!pTrans)
- {
- const NdbError err = pNdb->getNdbError();
-
- if (err.status == NdbError::TemporaryError)
- continue;
- return NDBT_FAILED;
- }
-
- pOp = pTrans->getNdbScanOperation(tab.getName());
+ pOp = getScanOperation(pTrans);
if (pOp == NULL) {
ERR(pTrans->getNdbError());
- pNdb->closeTransaction(pTrans);
- pTrans = 0;
+ closeTransaction(pNdb);
return NDBT_FAILED;
}
- NdbResultSet * rs = pOp->readTuples(lm);
- if( rs == 0) {
+ if( pOp->readTuples(lm) ) {
ERR(pTrans->getNdbError());
- pNdb->closeTransaction(pTrans);
- pTrans = 0;
+ closeTransaction(pNdb);
return NDBT_FAILED;
}
@@ -809,8 +515,7 @@ UtilTransactions::selectCount(Ndb* pNdb,
check = pOp->interpret_exit_ok();
if( check == -1 ) {
ERR(pTrans->getNdbError());
- pNdb->closeTransaction(pTrans);
- pTrans = 0;
+ closeTransaction(pNdb);
return NDBT_FAILED;
}
}
@@ -819,8 +524,7 @@ UtilTransactions::selectCount(Ndb* pNdb,
check = pTrans->execute(NoCommit);
if( check == -1 ) {
ERR(pTrans->getNdbError());
- pNdb->closeTransaction(pTrans);
- pTrans = 0;
+ closeTransaction(pNdb);
return NDBT_FAILED;
}
@@ -828,27 +532,24 @@ UtilTransactions::selectCount(Ndb* pNdb,
int rows = 0;
- while((eof = rs->nextResult()) == 0){
+ while((eof = pOp->nextResult()) == 0){
rows++;
}
if (eof == -1) {
const NdbError err = pTrans->getNdbError();
if (err.status == NdbError::TemporaryError){
- pNdb->closeTransaction(pTrans);
- pTrans = 0;
+ closeTransaction(pNdb);
NdbSleep_MilliSleep(50);
retryAttempt++;
continue;
}
ERR(err);
- pNdb->closeTransaction(pTrans);
- pTrans = 0;
+ closeTransaction(pNdb);
return NDBT_FAILED;
}
- pNdb->closeTransaction(pTrans);
- pTrans = 0;
+ closeTransaction(pNdb);
if (count_rows != NULL){
*count_rows = rows;
@@ -922,14 +623,13 @@ UtilTransactions::scanAndCompareUniqueIndex(Ndb* pNdb,
int retryAttempt = 0;
const int retryMax = 100;
int check;
- NdbConnection *pTrans;
NdbScanOperation *pOp;
NDBT_ResultRow row(tab);
parallelism = 1;
while (true){
-
+restart:
if (retryAttempt >= retryMax){
g_info << "ERROR: has retried this operation " << retryAttempt
<< " times, failing!" << endl;
@@ -953,7 +653,7 @@ UtilTransactions::scanAndCompareUniqueIndex(Ndb* pNdb,
pOp = pTrans->getNdbScanOperation(tab.getName());
if (pOp == NULL) {
const NdbError err = pNdb->getNdbError();
- pNdb->closeTransaction(pTrans);
+ closeTransaction(pNdb);
ERR(err);
if (err.status == NdbError::TemporaryError){
@@ -964,23 +664,23 @@ UtilTransactions::scanAndCompareUniqueIndex(Ndb* pNdb,
return NDBT_FAILED;
}
- NdbResultSet* rs;
+ int rs;
if(transactional){
rs = pOp->readTuples(NdbScanOperation::LM_Read, 0, parallelism);
} else {
rs = pOp->readTuples(NdbScanOperation::LM_CommittedRead, 0, parallelism);
}
- if( rs == 0 ) {
+ if( rs != 0 ) {
ERR(pTrans->getNdbError());
- pNdb->closeTransaction(pTrans);
+ closeTransaction(pNdb);
return NDBT_FAILED;
}
check = pOp->interpret_exit_ok();
if( check == -1 ) {
ERR(pTrans->getNdbError());
- pNdb->closeTransaction(pTrans);
+ closeTransaction(pNdb);
return NDBT_FAILED;
}
@@ -989,7 +689,7 @@ UtilTransactions::scanAndCompareUniqueIndex(Ndb* pNdb,
if ((row.attributeStore(a) =
pOp->getValue(tab.getColumn(a)->getName())) == 0) {
ERR(pTrans->getNdbError());
- pNdb->closeTransaction(pTrans);
+ closeTransaction(pNdb);
return NDBT_FAILED;
}
}
@@ -1000,13 +700,13 @@ UtilTransactions::scanAndCompareUniqueIndex(Ndb* pNdb,
if (err.status == NdbError::TemporaryError){
ERR(err);
- pNdb->closeTransaction(pTrans);
+ closeTransaction(pNdb);
NdbSleep_MilliSleep(50);
retryAttempt++;
continue;
}
ERR(err);
- pNdb->closeTransaction(pTrans);
+ closeTransaction(pNdb);
return NDBT_FAILED;
}
@@ -1014,17 +714,32 @@ UtilTransactions::scanAndCompareUniqueIndex(Ndb* pNdb,
int rows = 0;
- while((eof = rs->nextResult()) == 0){
+ while((eof = pOp->nextResult()) == 0){
rows++;
// ndbout << row.c_str().c_str() << endl;
-
if (readRowFromTableAndIndex(pNdb,
pTrans,
pIndex,
row) != NDBT_OK){
- pNdb->closeTransaction(pTrans);
+
+ while((eof= pOp->nextResult(false)) == 0);
+ if(eof == 2)
+ eof = pOp->nextResult(true); // this should give -1
+ if(eof == -1)
+ {
+ const NdbError err = pTrans->getNdbError();
+
+ if (err.status == NdbError::TemporaryError){
+ ERR(err);
+ closeTransaction(pNdb);
+ NdbSleep_MilliSleep(50);
+ retryAttempt++;
+ goto restart;
+ }
+ }
+ closeTransaction(pNdb);
return NDBT_FAILED;
}
}
@@ -1033,18 +748,17 @@ UtilTransactions::scanAndCompareUniqueIndex(Ndb* pNdb,
if (err.status == NdbError::TemporaryError){
ERR(err);
- pNdb->closeTransaction(pTrans);
+ closeTransaction(pNdb);
NdbSleep_MilliSleep(50);
retryAttempt++;
- rows--;
continue;
}
ERR(err);
- pNdb->closeTransaction(pTrans);
+ closeTransaction(pNdb);
return NDBT_FAILED;
}
- pNdb->closeTransaction(pTrans);
+ closeTransaction(pNdb);
return NDBT_OK;
}
@@ -1062,7 +776,6 @@ UtilTransactions::readRowFromTableAndIndex(Ndb* pNdb,
const int retryMax = 100;
int check, a;
NdbConnection *pTrans1=NULL;
- NdbResultSet *cursor= NULL;
NdbOperation *pOp;
int return_code= NDBT_FAILED;
@@ -1112,7 +825,6 @@ UtilTransactions::readRowFromTableAndIndex(Ndb* pNdb,
check = pOp->readTuple();
if( check == -1 ) {
ERR(pTrans1->getNdbError());
- pNdb->closeTransaction(pTrans1);
goto close_all;
}
@@ -1190,7 +902,7 @@ UtilTransactions::readRowFromTableAndIndex(Ndb* pNdb,
if (pIndexOp) {
not_ok = pIndexOp->readTuple() == -1;
} else {
- not_ok = (cursor= pScanOp->readTuples()) == 0;
+ not_ok = pScanOp->readTuples();
}
if( not_ok ) {
@@ -1244,7 +956,7 @@ UtilTransactions::readRowFromTableAndIndex(Ndb* pNdb,
#if VERBOSE
printf("\n");
#endif
-
+ scanTrans->refresh();
check = pTrans1->execute(Commit);
if( check == -1 ) {
const NdbError err = pTrans1->getNdbError();
@@ -1267,7 +979,7 @@ UtilTransactions::readRowFromTableAndIndex(Ndb* pNdb,
*/
if(!null_found){
if (pScanOp) {
- if (cursor->nextResult() != 0){
+ if (pScanOp->nextResult() != 0){
const NdbError err = pTrans1->getNdbError();
ERR(err);
ndbout << "Error when comparing records - index op next_result missing" << endl;
@@ -1282,7 +994,7 @@ UtilTransactions::readRowFromTableAndIndex(Ndb* pNdb,
goto close_all;
}
if (pScanOp) {
- if (cursor->nextResult() == 0){
+ if (pScanOp->nextResult() == 0){
ndbout << "Error when comparing records - index op next_result to many" << endl;
ndbout << "row: " << row.c_str().c_str() << endl;
goto close_all;
@@ -1294,8 +1006,6 @@ UtilTransactions::readRowFromTableAndIndex(Ndb* pNdb,
}
close_all:
- if (cursor)
- cursor->close();
if (pTrans1)
pNdb->closeTransaction(pTrans1);
@@ -1311,10 +1021,8 @@ UtilTransactions::verifyOrderedIndex(Ndb* pNdb,
int retryAttempt = 0;
const int retryMax = 100;
int check;
- NdbConnection *pTrans;
NdbScanOperation *pOp;
NdbIndexScanOperation * iop = 0;
- NdbResultSet* cursor= 0;
NDBT_ResultRow scanRow(tab);
NDBT_ResultRow pkRow(tab);
@@ -1349,23 +1057,20 @@ UtilTransactions::verifyOrderedIndex(Ndb* pNdb,
pOp = pTrans->getNdbScanOperation(tab.getName());
if (pOp == NULL) {
ERR(pTrans->getNdbError());
- pNdb->closeTransaction(pTrans);
+ closeTransaction(pNdb);
return NDBT_FAILED;
}
- NdbResultSet*
- rs = pOp->readTuples(NdbScanOperation::LM_Read, 0, parallelism);
-
- if( rs == 0 ) {
+ if( pOp->readTuples(NdbScanOperation::LM_Read, 0, parallelism) ) {
ERR(pTrans->getNdbError());
- pNdb->closeTransaction(pTrans);
+ closeTransaction(pNdb);
return NDBT_FAILED;
}
check = pOp->interpret_exit_ok();
if( check == -1 ) {
ERR(pTrans->getNdbError());
- pNdb->closeTransaction(pTrans);
+ closeTransaction(pNdb);
return NDBT_FAILED;
}
@@ -1380,19 +1085,19 @@ UtilTransactions::verifyOrderedIndex(Ndb* pNdb,
if (err.status == NdbError::TemporaryError){
ERR(err);
- pNdb->closeTransaction(pTrans);
+ closeTransaction(pNdb);
NdbSleep_MilliSleep(50);
retryAttempt++;
continue;
}
ERR(err);
- pNdb->closeTransaction(pTrans);
+ closeTransaction(pNdb);
return NDBT_FAILED;
}
int eof;
int rows = 0;
- while(check == 0 && (eof = rs->nextResult()) == 0){
+ while(check == 0 && (eof = pOp->nextResult()) == 0){
rows++;
bool null_found= false;
@@ -1417,10 +1122,11 @@ UtilTransactions::verifyOrderedIndex(Ndb* pNdb,
if(!iop && (iop= pTrans->getNdbIndexScanOperation(indexName,
tab.getName())))
{
- cursor= iop->readTuples(NdbScanOperation::LM_CommittedRead,
- parallelism);
+ if(iop->readTuples(NdbScanOperation::LM_CommittedRead,
+ parallelism))
+ goto error;
iop->interpret_exit_ok();
- if(!cursor || get_values(iop, indexRow))
+ if(get_values(iop, indexRow))
goto error;
}
else if(!iop || iop->reset_bounds())
@@ -1440,17 +1146,17 @@ UtilTransactions::verifyOrderedIndex(Ndb* pNdb,
g_err << "Error when comapring records" << endl;
g_err << " scanRow: \n" << scanRow.c_str().c_str() << endl;
g_err << " pkRow: \n" << pkRow.c_str().c_str() << endl;
- pNdb->closeTransaction(pTrans);
+ closeTransaction(pNdb);
return NDBT_FAILED;
}
if(!null_found)
{
- if((res= cursor->nextResult()) != 0){
+ if((res= iop->nextResult()) != 0){
g_err << "Failed to find row using index: " << res << endl;
ERR(pTrans->getNdbError());
- pNdb->closeTransaction(pTrans);
+ closeTransaction(pNdb);
return NDBT_FAILED;
}
@@ -1458,14 +1164,14 @@ UtilTransactions::verifyOrderedIndex(Ndb* pNdb,
g_err << "Error when comapring records" << endl;
g_err << " scanRow: \n" << scanRow.c_str().c_str() << endl;
g_err << " indexRow: \n" << indexRow.c_str().c_str() << endl;
- pNdb->closeTransaction(pTrans);
+ closeTransaction(pNdb);
return NDBT_FAILED;
}
- if(cursor->nextResult() == 0){
+ if(iop->nextResult() == 0){
g_err << "Found extra row!!" << endl;
g_err << " indexRow: \n" << indexRow.c_str().c_str() << endl;
- pNdb->closeTransaction(pTrans);
+ closeTransaction(pNdb);
return NDBT_FAILED;
}
}
@@ -1478,18 +1184,18 @@ UtilTransactions::verifyOrderedIndex(Ndb* pNdb,
if (err.status == NdbError::TemporaryError){
ERR(err);
iop = 0;
- pNdb->closeTransaction(pTrans);
+ closeTransaction(pNdb);
NdbSleep_MilliSleep(50);
retryAttempt++;
rows--;
continue;
}
ERR(err);
- pNdb->closeTransaction(pTrans);
+ closeTransaction(pNdb);
return NDBT_FAILED;
}
- pNdb->closeTransaction(pTrans);
+ closeTransaction(pNdb);
return NDBT_OK;
}
@@ -1537,3 +1243,218 @@ UtilTransactions::equal(const NdbDictionary::Table* pTable,
}
return 0;
}
+
+NdbScanOperation*
+UtilTransactions::getScanOperation(NdbConnection* pTrans)
+{
+ return (NdbScanOperation*)
+ getOperation(pTrans, NdbOperation::OpenScanRequest);
+}
+
+NdbOperation*
+UtilTransactions::getOperation(NdbConnection* pTrans,
+ NdbOperation::OperationType type)
+{
+ switch(type){
+ case NdbOperation::ReadRequest:
+ case NdbOperation::ReadExclusive:
+ if(idx)
+ {
+ switch(idx->getType()){
+ case NdbDictionary::Index::UniqueHashIndex:
+ return pTrans->getNdbIndexOperation(idx->getName(), tab.getName());
+ case NdbDictionary::Index::OrderedIndex:
+ return pTrans->getNdbIndexScanOperation(idx->getName(), tab.getName());
+ }
+ }
+ case NdbOperation::InsertRequest:
+ case NdbOperation::WriteRequest:
+ return pTrans->getNdbOperation(tab.getName());
+ case NdbOperation::UpdateRequest:
+ case NdbOperation::DeleteRequest:
+ if(idx)
+ {
+ switch(idx->getType()){
+ case NdbDictionary::Index::UniqueHashIndex:
+ return pTrans->getNdbIndexOperation(idx->getName(), tab.getName());
+ }
+ }
+ return pTrans->getNdbOperation(tab.getName());
+ case NdbOperation::OpenScanRequest:
+ if(idx)
+ {
+ switch(idx->getType()){
+ case NdbDictionary::Index::OrderedIndex:
+ return pTrans->getNdbIndexScanOperation(idx->getName(), tab.getName());
+ }
+ }
+ return pTrans->getNdbScanOperation(tab.getName());
+ case NdbOperation::OpenRangeScanRequest:
+ if(idx)
+ {
+ switch(idx->getType()){
+ case NdbDictionary::Index::OrderedIndex:
+ return pTrans->getNdbIndexScanOperation(idx->getName(), tab.getName());
+ }
+ }
+ return 0;
+ }
+}
+
+#include <HugoOperations.hpp>
+
+int
+UtilTransactions::closeTransaction(Ndb* pNdb)
+{
+ if (pTrans != NULL){
+ pNdb->closeTransaction(pTrans);
+ pTrans = NULL;
+ }
+ return 0;
+}
+
+int
+UtilTransactions::compare(Ndb* pNdb, const char* tab_name2, int flags){
+
+
+ NdbError err;
+ int return_code= -1, row_count= 0;
+ int retryAttempt = 0, retryMax = 10;
+
+ HugoCalculator calc(tab);
+ NDBT_ResultRow row(tab);
+ const NdbDictionary::Table* tmp= pNdb->getDictionary()->getTable(tab_name2);
+ if(tmp == 0)
+ {
+ g_err << "Unable to lookup table: " << tab_name2
+ << endl << pNdb->getDictionary()->getNdbError() << endl;
+ return -1;
+ }
+ const NdbDictionary::Table& tab2= *tmp;
+
+ HugoOperations cmp(tab2);
+ UtilTransactions count(tab2);
+
+ while (true){
+
+ if (retryAttempt++ >= retryMax){
+ g_info << "ERROR: has retried this operation " << retryAttempt
+ << " times, failing!" << endl;
+ return -1;
+ }
+
+ NdbScanOperation *pOp= 0;
+ pTrans = pNdb->startTransaction();
+ if (pTrans == NULL) {
+ err = pNdb->getNdbError();
+ goto error;
+ }
+
+ pOp= pTrans->getNdbScanOperation(tab.getName());
+ if (pOp == NULL) {
+ ERR(err= pTrans->getNdbError());
+ goto error;
+ }
+
+ if( pOp->readTuples(NdbScanOperation::LM_Read) ) {
+ ERR(err= pTrans->getNdbError());
+ goto error;
+ }
+
+ if( pOp->interpret_exit_ok() == -1 ) {
+ ERR(err= pTrans->getNdbError());
+ goto error;
+ }
+
+ // Read all attributes
+ {
+ for (int a = 0; a < tab.getNoOfColumns(); a++){
+ if ((row.attributeStore(a) =
+ pOp->getValue(tab.getColumn(a)->getName())) == 0) {
+ ERR(err= pTrans->getNdbError());
+ goto error;
+ }
+ }
+ }
+
+ if( pTrans->execute(NoCommit) == -1 ) {
+ ERR(err= pTrans->getNdbError());
+ goto error;
+ }
+
+ {
+ int eof;
+ while((eof = pOp->nextResult(true)) == 0)
+ {
+ do {
+ row_count++;
+ if(cmp.startTransaction(pNdb) != NDBT_OK)
+ {
+ ERR(err= pNdb->getNdbError());
+ goto error;
+ }
+ int rowNo= calc.getIdValue(&row);
+ if(cmp.pkReadRecord(pNdb, rowNo, 1) != NDBT_OK)
+ {
+ ERR(err= cmp.getTransaction()->getNdbError());
+ goto error;
+ }
+ if(cmp.execute_Commit(pNdb) != NDBT_OK)
+ {
+ ERR(err= cmp.getTransaction()->getNdbError());
+ goto error;
+ }
+ if(row != cmp.get_row(0))
+ {
+ g_err << "COMPARE FAILED" << endl;
+ g_err << row << endl;
+ g_err << cmp.get_row(0) << endl;
+ return_code= 1;
+ goto close;
+ }
+ retryAttempt= 0;
+ cmp.closeTransaction(pNdb);
+ } while((eof = pOp->nextResult(false)) == 0);
+ }
+ if (eof == -1)
+ {
+ err = pTrans->getNdbError();
+ goto error;
+ }
+ }
+
+ pTrans->close(); pTrans= 0;
+
+ g_info << row_count << " rows compared" << endl;
+ {
+ int row_count2;
+ if(count.selectCount(pNdb, 0, &row_count2) != NDBT_OK)
+ {
+ g_err << "Failed to count rows in tab_name2" << endl;
+ return -1;
+ }
+
+ g_info << row_count2 << " rows in tab_name2" << endl;
+ return (row_count == row_count2 ? 0 : 1);
+ }
+error:
+ if(err.status == NdbError::TemporaryError)
+ {
+ NdbSleep_MilliSleep(50);
+ if(pTrans != 0)
+ {
+ pTrans->close();
+ pTrans= 0;
+ }
+ if(cmp.getTransaction())
+ cmp.closeTransaction(pNdb);
+ continue;
+ }
+ break;
+ }
+
+close:
+ if(pTrans != 0) pTrans->close();
+
+ return return_code;
+}
diff --git a/ndb/test/tools/Makefile.am b/ndb/test/tools/Makefile.am
index a6a013bb263..873136e254d 100644
--- a/ndb/test/tools/Makefile.am
+++ b/ndb/test/tools/Makefile.am
@@ -1,9 +1,8 @@
-ndbtest_PROGRAMS = hugoCalculator hugoLoad hugoFill hugoLockRecords hugoPkDelete hugoPkRead hugoPkReadRecord hugoPkUpdate hugoScanRead hugoScanUpdate restart verify_index copy_tab create_index ndb_cpcc
+ndbtest_PROGRAMS = hugoLoad hugoFill hugoLockRecords hugoPkDelete hugoPkRead hugoPkReadRecord hugoPkUpdate hugoScanRead hugoScanUpdate restart verify_index copy_tab create_index ndb_cpcc
# transproxy
-hugoCalculator_SOURCES = hugoCalculator.cpp
hugoFill_SOURCES = hugoFill.cpp
hugoLoad_SOURCES = hugoLoad.cpp
hugoLockRecords_SOURCES = hugoLockRecords.cpp
diff --git a/ndb/test/tools/copy_tab.cpp b/ndb/test/tools/copy_tab.cpp
index 30141acaa78..97370b170ef 100644
--- a/ndb/test/tools/copy_tab.cpp
+++ b/ndb/test/tools/copy_tab.cpp
@@ -56,9 +56,12 @@ int main(int argc, const char** argv){
_tabname = argv[optind];
_to_tabname = argv[optind+1];
- if (_connectstr)
- Ndb::setConnectString(_connectstr);
- Ndb MyNdb(_dbname);
+ Ndb_cluster_connection con(_connectstr);
+ if(con.connect(12, 5, 1) != 0)
+ {
+ return NDBT_ProgramExit(NDBT_FAILED);
+ }
+ Ndb MyNdb(&con,_dbname);
if(MyNdb.init() != 0){
ERR(MyNdb.getNdbError());
return NDBT_ProgramExit(NDBT_FAILED);
diff --git a/ndb/test/tools/create_index.cpp b/ndb/test/tools/create_index.cpp
index 6e4c5377f4a..9f9c26aa0da 100644
--- a/ndb/test/tools/create_index.cpp
+++ b/ndb/test/tools/create_index.cpp
@@ -53,8 +53,13 @@ main(int argc, const char** argv){
return NDBT_ProgramExit(NDBT_WRONGARGS);
}
+ Ndb_cluster_connection con;
+ if(con.connect(12, 5, 1) != 0)
+ {
+ return NDBT_ProgramExit(NDBT_FAILED);
+ }
- Ndb MyNdb(_dbname);
+ Ndb MyNdb(&con, _dbname);
if(MyNdb.init() != 0){
ERR(MyNdb.getNdbError());
return NDBT_ProgramExit(NDBT_FAILED);
diff --git a/ndb/test/tools/hugoFill.cpp b/ndb/test/tools/hugoFill.cpp
index 6253bd1bb12..6408b2987f9 100644
--- a/ndb/test/tools/hugoFill.cpp
+++ b/ndb/test/tools/hugoFill.cpp
@@ -51,7 +51,12 @@ int main(int argc, const char** argv){
_tabname = argv[optind];
// Connect to Ndb
- Ndb MyNdb( "TEST_DB" );
+ Ndb_cluster_connection con;
+ if(con.connect(12, 5, 1) != 0)
+ {
+ return NDBT_ProgramExit(NDBT_FAILED);
+ }
+ Ndb MyNdb(&con, "TEST_DB" );
if(MyNdb.init() != 0){
ERR(MyNdb.getNdbError());
diff --git a/ndb/test/tools/hugoLoad.cpp b/ndb/test/tools/hugoLoad.cpp
index 3a0bba07df3..1a229169650 100644
--- a/ndb/test/tools/hugoLoad.cpp
+++ b/ndb/test/tools/hugoLoad.cpp
@@ -56,7 +56,12 @@ int main(int argc, const char** argv){
_tabname = argv[optind];
// Connect to Ndb
- Ndb MyNdb( db ? db : "TEST_DB" );
+ Ndb_cluster_connection con;
+ if(con.connect(12, 5, 1) != 0)
+ {
+ return NDBT_ProgramExit(NDBT_FAILED);
+ }
+ Ndb MyNdb( &con, db ? db : "TEST_DB" );
if(MyNdb.init() != 0){
ERR(MyNdb.getNdbError());
diff --git a/ndb/test/tools/hugoLockRecords.cpp b/ndb/test/tools/hugoLockRecords.cpp
index 629408d401d..c0d0b9f9c5a 100644
--- a/ndb/test/tools/hugoLockRecords.cpp
+++ b/ndb/test/tools/hugoLockRecords.cpp
@@ -59,7 +59,12 @@ int main(int argc, const char** argv){
_tabname = argv[optind];
// Connect to Ndb
- Ndb MyNdb( "TEST_DB" );
+ Ndb_cluster_connection con;
+ if(con.connect(12, 5, 1) != 0)
+ {
+ return NDBT_ProgramExit(NDBT_FAILED);
+ }
+ Ndb MyNdb(&con, "TEST_DB" );
if(MyNdb.init() != 0){
ERR(MyNdb.getNdbError());
diff --git a/ndb/test/tools/hugoPkDelete.cpp b/ndb/test/tools/hugoPkDelete.cpp
index 78a90ebcb46..84e7ded0add 100644
--- a/ndb/test/tools/hugoPkDelete.cpp
+++ b/ndb/test/tools/hugoPkDelete.cpp
@@ -55,7 +55,12 @@ int main(int argc, const char** argv){
_tabname = argv[optind];
// Connect to Ndb
- Ndb MyNdb( "TEST_DB" );
+ Ndb_cluster_connection con;
+ if(con.connect(12, 5, 1) != 0)
+ {
+ return NDBT_ProgramExit(NDBT_FAILED);
+ }
+ Ndb MyNdb(&con, "TEST_DB" );
if(MyNdb.init() != 0){
ERR(MyNdb.getNdbError());
diff --git a/ndb/test/tools/hugoPkRead.cpp b/ndb/test/tools/hugoPkRead.cpp
index cf08b137e8e..e3702dc5ca1 100644
--- a/ndb/test/tools/hugoPkRead.cpp
+++ b/ndb/test/tools/hugoPkRead.cpp
@@ -60,7 +60,12 @@ int main(int argc, const char** argv){
// Connect to Ndb
- Ndb MyNdb( "TEST_DB" );
+ Ndb_cluster_connection con;
+ if(con.connect(12, 5, 1) != 0)
+ {
+ return NDBT_ProgramExit(NDBT_FAILED);
+ }
+ Ndb MyNdb(&con, "TEST_DB" );
if(MyNdb.init() != 0){
ERR(MyNdb.getNdbError());
diff --git a/ndb/test/tools/hugoPkReadRecord.cpp b/ndb/test/tools/hugoPkReadRecord.cpp
index 38b7cae2bf4..c60a994c7d4 100644
--- a/ndb/test/tools/hugoPkReadRecord.cpp
+++ b/ndb/test/tools/hugoPkReadRecord.cpp
@@ -62,7 +62,12 @@ int main(int argc, const char** argv)
<< "Row: " << _row << ", PrimaryKey: " << _primaryKey
<< endl;
- Ndb* ndb = new Ndb("TEST_DB");
+ Ndb_cluster_connection con;
+ if(con.connect(12, 5, 1) != 0)
+ {
+ return NDBT_ProgramExit(NDBT_FAILED);
+ }
+ Ndb* ndb = new Ndb(&con, "TEST_DB");
if (ndb->init() == 0 && ndb->waitUntilReady(30) == 0)
{
NdbConnection* conn = ndb->startTransaction();
diff --git a/ndb/test/tools/hugoPkUpdate.cpp b/ndb/test/tools/hugoPkUpdate.cpp
index ccbbccfc523..7d46ae95c29 100644
--- a/ndb/test/tools/hugoPkUpdate.cpp
+++ b/ndb/test/tools/hugoPkUpdate.cpp
@@ -58,7 +58,12 @@ int main(int argc, const char** argv){
_tabname = argv[optind];
// Connect to Ndb
- Ndb MyNdb( db ? db : "TEST_DB" );
+ Ndb_cluster_connection con;
+ if(con.connect(12, 5, 1) != 0)
+ {
+ return NDBT_ProgramExit(NDBT_FAILED);
+ }
+ Ndb MyNdb( &con, db ? db : "TEST_DB" );
if(MyNdb.init() != 0){
ERR(MyNdb.getNdbError());
diff --git a/ndb/test/tools/hugoScanRead.cpp b/ndb/test/tools/hugoScanRead.cpp
index 4cd428f44c6..a345bb88d0e 100644
--- a/ndb/test/tools/hugoScanRead.cpp
+++ b/ndb/test/tools/hugoScanRead.cpp
@@ -62,7 +62,12 @@ int main(int argc, const char** argv){
_tabname = argv[optind];
// Connect to Ndb
- Ndb MyNdb( db ? db : "TEST_DB" );
+ Ndb_cluster_connection con;
+ if(con.connect(12, 5, 1) != 0)
+ {
+ return NDBT_ProgramExit(NDBT_FAILED);
+ }
+ Ndb MyNdb( &con, db ? db : "TEST_DB" );
if(MyNdb.init() != 0){
ERR(MyNdb.getNdbError());
@@ -86,8 +91,7 @@ int main(int argc, const char** argv){
if(!pIdx)
ndbout << " Index " << argv[optind+1] << " not found" << endl;
else
- if(pIdx->getType() != NdbDictionary::Index::UniqueOrderedIndex &&
- pIdx->getType() != NdbDictionary::Index::OrderedIndex)
+ if(pIdx->getType() != NdbDictionary::Index::OrderedIndex)
{
ndbout << " Index " << argv[optind+1] << " is not scannable" << endl;
pIdx = 0;
diff --git a/ndb/test/tools/hugoScanUpdate.cpp b/ndb/test/tools/hugoScanUpdate.cpp
index 8fe84779c6b..6960fa44b96 100644
--- a/ndb/test/tools/hugoScanUpdate.cpp
+++ b/ndb/test/tools/hugoScanUpdate.cpp
@@ -59,7 +59,12 @@ int main(int argc, const char** argv){
_tabname = argv[optind];
// Connect to Ndb
- Ndb MyNdb( db ? db : "TEST_DB" );
+ Ndb_cluster_connection con;
+ if(con.connect(12, 5, 1) != 0)
+ {
+ return NDBT_ProgramExit(NDBT_FAILED);
+ }
+ Ndb MyNdb( &con, db ? db : "TEST_DB" );
if(MyNdb.init() != 0){
ERR(MyNdb.getNdbError());
diff --git a/ndb/test/tools/verify_index.cpp b/ndb/test/tools/verify_index.cpp
index 6c8e304e1a1..acc97af883b 100644
--- a/ndb/test/tools/verify_index.cpp
+++ b/ndb/test/tools/verify_index.cpp
@@ -53,7 +53,12 @@ int main(int argc, const char** argv){
_indexname = argv[optind+1];
// Connect to Ndb
- Ndb MyNdb( "TEST_DB" );
+ Ndb_cluster_connection con;
+ if(con.connect(12, 5, 1) != 0)
+ {
+ return NDBT_ProgramExit(NDBT_FAILED);
+ }
+ Ndb MyNdb(&con, "TEST_DB" );
if(MyNdb.init() != 0){
ERR(MyNdb.getNdbError());