summaryrefslogtreecommitdiff
path: root/ndb
diff options
context:
space:
mode:
authorunknown <joreland@mysql.com>2005-02-01 17:16:05 +0100
committerunknown <joreland@mysql.com>2005-02-01 17:16:05 +0100
commit6b7f067e8b3285ea63160512d1c0dcf1ce553865 (patch)
tree7ca4c58c6b2cf379c9ff17aab9497e05047dee15 /ndb
parent514b2364b4156e23fb15f4506a50877011b9c7ef (diff)
parent9d548d7f2253ea5dd1f78960f61ba2f0822db177 (diff)
downloadmariadb-git-6b7f067e8b3285ea63160512d1c0dcf1ce553865.tar.gz
merge
Diffstat (limited to 'ndb')
-rw-r--r--ndb/include/ndbapi/NdbConnection.hpp2
-rw-r--r--ndb/src/kernel/blocks/dbacc/DbaccMain.cpp3
-rw-r--r--ndb/test/include/NDBT_Test.hpp4
-rw-r--r--ndb/test/ndbapi/testOperations.cpp283
-rw-r--r--ndb/test/src/HugoOperations.cpp4
-rw-r--r--ndb/test/src/NDBT_Test.cpp12
6 files changed, 302 insertions, 6 deletions
diff --git a/ndb/include/ndbapi/NdbConnection.hpp b/ndb/include/ndbapi/NdbConnection.hpp
index 166355cae17..f173cd8ac6e 100644
--- a/ndb/include/ndbapi/NdbConnection.hpp
+++ b/ndb/include/ndbapi/NdbConnection.hpp
@@ -687,6 +687,8 @@ private:
void remove_list(NdbOperation*& head, NdbOperation*);
void define_scan_op(NdbIndexScanOperation*);
+
+ friend int runOperations(class NDBT_Context*, class NDBT_Step*);
};
inline
diff --git a/ndb/src/kernel/blocks/dbacc/DbaccMain.cpp b/ndb/src/kernel/blocks/dbacc/DbaccMain.cpp
index 5c7cc597672..a82c96beebd 100644
--- a/ndb/src/kernel/blocks/dbacc/DbaccMain.cpp
+++ b/ndb/src/kernel/blocks/dbacc/DbaccMain.cpp
@@ -5704,7 +5704,8 @@ void Dbacc::commitOperation(Signal* signal)
Uint32 tmp2Olq;
if ((operationRecPtr.p->commitDeleteCheckFlag == ZFALSE) &&
- (operationRecPtr.p->operation != ZSCAN_OP)) {
+ (operationRecPtr.p->operation != ZSCAN_OP) &&
+ (operationRecPtr.p->operation != ZREAD)) {
jam();
/* This method is used to check whether the end result of the transaction
will be to delete the tuple. In this case all operation will be marked
diff --git a/ndb/test/include/NDBT_Test.hpp b/ndb/test/include/NDBT_Test.hpp
index 8b69faebde8..a60228c1a5d 100644
--- a/ndb/test/include/NDBT_Test.hpp
+++ b/ndb/test/include/NDBT_Test.hpp
@@ -188,7 +188,7 @@ public:
NDBT_TestCase(NDBT_TestSuite* psuite,
const char* name,
const char* comment);
- virtual ~NDBT_TestCase(){}
+ virtual ~NDBT_TestCase() {}
// This is the default executor of a test case
// When a test case is executed it will need to be suplied with a number of
@@ -225,6 +225,8 @@ protected:
void stopTimer(NDBT_Context*);
void printTimer(NDBT_Context*);
+ BaseString _name;
+ BaseString _comment;
const char* name;
const char* comment;
NDBT_TestSuite* suite;
diff --git a/ndb/test/ndbapi/testOperations.cpp b/ndb/test/ndbapi/testOperations.cpp
index 949f08281a5..92cc3e81b1a 100644
--- a/ndb/test/ndbapi/testOperations.cpp
+++ b/ndb/test/ndbapi/testOperations.cpp
@@ -98,6 +98,11 @@ OperationTestCase matrix[] = {
result = NDBT_FAILED; \
break; }
+#define C3(b) if (!(b)) { \
+ g_err << "ERR: "<< step->getName() \
+ << " failed on line " << __LINE__ << endl; \
+ abort(); return NDBT_FAILED; }
+
int
runOp(HugoOperations & hugoOps,
Ndb * pNdb,
@@ -228,11 +233,287 @@ runClearTable(NDBT_Context* ctx, NDBT_Step* step){
return NDBT_OK;
}
+enum OPS { o_DONE= 0, o_INS= 1, o_UPD= 2, o_DEL= 3 };
+typedef Vector<OPS> Sequence;
+
+static
+bool
+valid(const Sequence& s)
+{
+ if(s.size() == 0)
+ return false;
+
+ for(size_t i = 1; i<s.size(); i++)
+ {
+ switch(s[i]){
+ case o_INS:
+ if(s[i-1] != o_DEL)
+ return false;
+ break;
+ case o_UPD:
+ case o_DEL:
+ if(s[i-1] == o_DEL)
+ return false;
+ break;
+ case o_DONE:
+ return true;
+ }
+ }
+ return true;
+}
+
+static
+NdbOut& operator<<(NdbOut& out, const Sequence& s)
+{
+ out << "[ ";
+ for(size_t i = 0; i<s.size(); i++)
+ {
+ switch(s[i]){
+ case o_INS:
+ out << "INS ";
+ break;
+ case o_DEL:
+ out << "DEL ";
+ break;
+ case o_UPD:
+ out << "UPD ";
+ break;
+ case o_DONE:
+ abort();
+ }
+ }
+ out << "]";
+ return out;
+}
+
+static
+void
+generate(Sequence& out, int no)
+{
+ while(no & 3)
+ {
+ out.push_back((OPS)(no & 3));
+ no >>= 2;
+ }
+}
+
+static
+void
+generate(Vector<int>& out, size_t len)
+{
+ int max= 1;
+ while(len)
+ {
+ max <<= 2;
+ len--;
+ }
+
+ len= 1;
+ for(int i = 0; i<max; i++)
+ {
+ Sequence tmp;
+ generate(tmp, i);
+
+ if(tmp.size() >= len && valid(tmp))
+ {
+ out.push_back(i);
+ len= tmp.size();
+ }
+ else
+ {
+ //ndbout << "DISCARD: " << tmp << endl;
+ }
+ }
+}
+
+int
+runOperations(NDBT_Context* ctx, NDBT_Step* step)
+{
+ const Uint32 DUMMY = 0;
+ const Uint32 ROW = 1;
+
+ int tmp;
+ Ndb* pNdb = GETNDB(step);
+
+ Uint32 seqNo = ctx->getProperty("Sequence", (Uint32)0);
+ Uint32 no_wait = NdbOperation::LM_CommittedRead*
+ ctx->getProperty("NoWait", (Uint32)1);
+
+ if(seqNo == 0)
+ {
+ return NDBT_FAILED;
+ }
+
+ Sequence seq;
+ generate(seq, seqNo);
+
+ {
+ // Dummy row
+ HugoOperations hugoOps(*ctx->getTab());
+ C3(hugoOps.startTransaction(pNdb) == 0);
+ C3(hugoOps.pkInsertRecord(pNdb, DUMMY, 1, 0) == 0);
+ C3(hugoOps.execute_Commit(pNdb) == 0);
+ }
+
+ const bool inital_row= (seq[0] != o_INS);
+ if(inital_row)
+ {
+ HugoOperations hugoOps(*ctx->getTab());
+ C3(hugoOps.startTransaction(pNdb) == 0);
+ C3(hugoOps.pkInsertRecord(pNdb, ROW, 1, 0) == 0);
+ C3(hugoOps.execute_Commit(pNdb) == 0);
+ }
+
+ HugoOperations trans1(*ctx->getTab());
+ C3(trans1.startTransaction(pNdb) == 0);
+ for(size_t i = 0; i<seq.size(); i++)
+ {
+ /**
+ * Perform operation
+ */
+ switch(seq[i]){
+ case o_INS:
+ C3(trans1.pkInsertRecord(pNdb, ROW, 1, i+1) == 0);
+ break;
+ case o_UPD:
+ C3(trans1.pkUpdateRecord(pNdb, ROW, 1, i+1) == 0);
+ break;
+ case o_DEL:
+ C3(trans1.pkDeleteRecord(pNdb, ROW, 1) == 0);
+ break;
+ case o_DONE:
+ abort();
+ }
+ C3(trans1.execute_NoCommit(pNdb) == 0);
+
+ /**
+ * Verify other transaction
+ */
+ for(size_t j = no_wait; j<3; j++)
+ {
+ HugoOperations other(*ctx->getTab());
+ C3(other.startTransaction(pNdb) == 0);
+ C3(other.pkReadRecord(pNdb, ROW, 1, (NdbOperation::LockMode)j) == 0);
+ tmp= other.execute_Commit(pNdb);
+ if(j == NdbOperation::LM_CommittedRead)
+ {
+ C3(inital_row? tmp==0 && other.verifyUpdatesValue(0) == 0 : tmp==626);
+ }
+ else
+ {
+ C3(tmp == 266);
+ }
+ }
+
+ /**
+ * Verify savepoint read
+ */
+ Uint64 transactionId= trans1.getTransaction()->getTransactionId();
+ for(size_t k=0; k<=i+1; k++)
+ {
+ for(size_t j = 0; j<3; j++)
+ {
+ const NdbOperation::LockMode lm= (NdbOperation::LockMode)j;
+
+ HugoOperations same(*ctx->getTab());
+ C3(same.startTransaction(pNdb) == 0);
+ same.getTransaction()->setTransactionId(transactionId); // Cheat
+
+ /**
+ * Increase savepoint to <em>k</em>
+ */
+ for(size_t l = 1; l<=k; l++)
+ {
+ C3(same.pkReadRecord(pNdb, DUMMY, 1, lm) == 0); // Read dummy row
+ C3(same.execute_NoCommit(pNdb) == 0);
+ g_info << "savepoint: " << l << endl;
+ }
+
+ g_info << "op(" << k << ", " << i << "): "
+ << " lock mode " << lm << endl;
+
+ C3(same.pkReadRecord(pNdb, ROW, 1, lm) == 0); // Read real row
+ tmp= same.execute_Commit(pNdb);
+ if(k == 0)
+ {
+ if(inital_row)
+ {
+ C3(tmp == 0 && same.verifyUpdatesValue(0) == 0);
+ } else
+ {
+ C3(tmp == 626);
+ }
+ }
+ else
+ {
+ switch(seq[k-1]){
+ case o_INS:
+ case o_UPD:
+ C3(tmp == 0 && same.verifyUpdatesValue(k) == 0);
+ break;
+ case o_DEL:
+ C3(tmp == 626);
+ break;
+ case o_DONE:
+ abort();
+ }
+ }
+ }
+ }
+ }
+ C3(trans1.execute_Commit(pNdb) == 0);
+
+ return NDBT_OK;
+}
+
int
main(int argc, const char** argv){
ndb_init();
+ Vector<int> tmp;
+ generate(tmp, 5);
+
NDBT_TestSuite ts("testOperations");
+ for(size_t i = 0; i<tmp.size(); i++)
+ {
+ BaseString name;
+ Sequence s;
+ generate(s, tmp[i]);
+ for(size_t j = 0; j<s.size(); j++){
+ switch(s[j]){
+ case o_INS:
+ name.append("_INS");
+ break;
+ case o_DEL:
+ name.append("_DEL");
+ break;
+ case o_UPD:
+ name.append("_UPD");
+ break;
+ case o_DONE:
+ abort();
+ }
+ }
+
+ NDBT_TestCaseImpl1 *pt = new NDBT_TestCaseImpl1(&ts,
+ name.c_str()+1, "");
+
+ pt->setProperty("Sequence", tmp[i]);
+ pt->addInitializer(new NDBT_Initializer(pt,
+ "runClearTable",
+ runClearTable));
+
+ pt->addStep(new NDBT_ParallelStep(pt,
+ name.c_str()+1,
+ runOperations));
+
+ pt->addFinalizer(new NDBT_Finalizer(pt,
+ "runClearTable",
+ runClearTable));
+
+ ts.addTest(pt);
+ }
+
for(Uint32 i = 0; i<sizeof(matrix)/sizeof(matrix[0]); i++){
NDBT_TestCaseImpl1 *pt = new NDBT_TestCaseImpl1(&ts, matrix[i].name, "");
@@ -270,3 +551,5 @@ main(int argc, const char** argv){
return ts.execute(argc, argv);
}
+template class Vector<OPS>;
+template class Vector<Sequence>;
diff --git a/ndb/test/src/HugoOperations.cpp b/ndb/test/src/HugoOperations.cpp
index e8e2d992345..caaa3a3a0ee 100644
--- a/ndb/test/src/HugoOperations.cpp
+++ b/ndb/test/src/HugoOperations.cpp
@@ -401,6 +401,10 @@ HugoOperations::HugoOperations(const NdbDictionary::Table& _tab):
HugoOperations::~HugoOperations(){
deallocRows();
+ if (pTrans != NULL){
+ pTrans->close();
+ pTrans = NULL;
+ }
}
diff --git a/ndb/test/src/NDBT_Test.cpp b/ndb/test/src/NDBT_Test.cpp
index bbbde008938..0e5f744d5ea 100644
--- a/ndb/test/src/NDBT_Test.cpp
+++ b/ndb/test/src/NDBT_Test.cpp
@@ -327,13 +327,17 @@ NDBT_Finalizer::NDBT_Finalizer(NDBT_TestCase* ptest,
NDBT_TestCase::NDBT_TestCase(NDBT_TestSuite* psuite,
const char* pname,
const char* pcomment) :
- name(pname) ,
- comment(pcomment),
- suite(psuite){
+ name(strdup(pname)) ,
+ comment(strdup(pcomment)),
+ suite(psuite)
+{
+ _name.assign(pname);
+ _comment.assign(pcomment);
+ name= _name.c_str();
+ comment= _comment.c_str();
assert(suite != NULL);
}
-
NDBT_TestCaseImpl1::NDBT_TestCaseImpl1(NDBT_TestSuite* psuite,
const char* pname,
const char* pcomment) :