MySQL 5.6.14 Source Code Document
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
testBasic.cpp
1 /*
2  Copyright (c) 2003, 2011, Oracle and/or its affiliates. All rights reserved.
3 
4  This program is free software; you can redistribute it and/or modify
5  it under the terms of the GNU General Public License as published by
6  the Free Software Foundation; version 2 of the License.
7 
8  This program is distributed in the hope that it will be useful,
9  but WITHOUT ANY WARRANTY; without even the implied warranty of
10  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11  GNU General Public License for more details.
12 
13  You should have received a copy of the GNU General Public License
14  along with this program; if not, write to the Free Software
15  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
16 */
17 
18 #include <NDBT_Test.hpp>
19 #include <NDBT_ReturnCodes.h>
20 #include <HugoTransactions.hpp>
21 #include <UtilTransactions.hpp>
22 #include <NdbRestarter.hpp>
23 #include <signaldata/DictTabInfo.hpp>
24 #include <Bitmask.hpp>
25 #include <random.h>
26 #include <signaldata/DumpStateOrd.hpp>
27 
34 int runLoadTable2(NDBT_Context* ctx, NDBT_Step* step)
35 {
36  int records = ctx->getNumRecords();
37  HugoTransactions hugoTrans(*ctx->getTab());
38  if (hugoTrans.loadTable(GETNDB(step), records, 512, false, 0, true) != 0){
39  return NDBT_FAILED;
40  }
41  return NDBT_OK;
42 }
43 
44 int runLoadTable(NDBT_Context* ctx, NDBT_Step* step)
45 {
46  int records = ctx->getNumRecords();
47  HugoTransactions hugoTrans(*ctx->getTab());
48  if (hugoTrans.loadTable(GETNDB(step), records) != 0){
49  return NDBT_FAILED;
50  }
51  return NDBT_OK;
52 }
53 
54 int runInsert(NDBT_Context* ctx, NDBT_Step* step){
55 
56  int records = ctx->getNumRecords();
57  HugoTransactions hugoTrans(*ctx->getTab());
58  // Insert records, dont allow any
59  // errors(except temporary) while inserting
60  if (hugoTrans.loadTable(GETNDB(step), records, 1, false) != 0){
61  return NDBT_FAILED;
62  }
63  return NDBT_OK;
64 }
65 
66 int runInsertTwice(NDBT_Context* ctx, NDBT_Step* step){
67 
68  int records = ctx->getNumRecords();
69  HugoTransactions hugoTrans(*ctx->getTab());
70  // Insert records, expect primary key violation 630
71  if (hugoTrans.loadTable(GETNDB(step), records, 1, false) != 630){
72  return NDBT_FAILED;
73  }
74  return NDBT_OK;
75 }
76 
77 int runVerifyInsert(NDBT_Context* ctx, NDBT_Step* step){
78  int records = ctx->getNumRecords();
79 
80  HugoTransactions hugoTrans(*ctx->getTab());
81  if (hugoTrans.pkDelRecords(GETNDB(step), records, 1, false) != 0){
82  return NDBT_FAILED;
83  }
84  return NDBT_OK;
85 }
86 
87 int runInsertUntilStopped(NDBT_Context* ctx, NDBT_Step* step){
88  int records = ctx->getNumRecords();
89  int i = 0;
90  HugoTransactions hugoTrans(*ctx->getTab());
91  while (ctx->isTestStopped() == false) {
92  g_info << i << ": ";
93  if (hugoTrans.loadTable(GETNDB(step), records) != 0){
94  g_info << endl;
95  return NDBT_FAILED;
96  }
97  i++;
98  }
99  g_info << endl;
100  return NDBT_OK;
101 }
102 
103 int runClearTable(NDBT_Context* ctx, NDBT_Step* step){
104  int records = ctx->getNumRecords();
105  int batchSize = ctx->getProperty("BatchSize", 1);
106 
107  HugoTransactions hugoTrans(*ctx->getTab());
108  if (hugoTrans.pkDelRecords(GETNDB(step), records, batchSize) != 0){
109  return NDBT_FAILED;
110  }
111  return NDBT_OK;
112 }
113 
114 int runPkDelete(NDBT_Context* ctx, NDBT_Step* step){
115  int loops = ctx->getNumLoops();
116  int records = ctx->getNumRecords();
117 
118  int i = 0;
119  HugoTransactions hugoTrans(*ctx->getTab());
120  while (i<loops) {
121  g_info << i << ": ";
122  if (hugoTrans.pkDelRecords(GETNDB(step), records) != 0){
123  g_info << endl;
124  return NDBT_FAILED;
125  }
126  // Load table, don't allow any primary key violations
127  if (hugoTrans.loadTable(GETNDB(step), records, 512, false) != 0){
128  g_info << endl;
129  return NDBT_FAILED;
130  }
131  i++;
132  }
133  g_info << endl;
134  return NDBT_OK;
135 }
136 
137 
138 int runPkRead(NDBT_Context* ctx, NDBT_Step* step){
139  int loops = ctx->getNumLoops();
140  int records = ctx->getNumRecords();
141  int batchSize = ctx->getProperty("BatchSize", 1);
142  int lm = ctx->getProperty("LockMode", NdbOperation::LM_Read);
143  int i = 0;
144  HugoTransactions hugoTrans(*ctx->getTab());
145  while (i<loops) {
146  g_info << i << ": ";
147  if (hugoTrans.pkReadRecords(GETNDB(step), records, batchSize,
148  (NdbOperation::LockMode)lm) != NDBT_OK){
149  g_info << endl;
150  return NDBT_FAILED;
151  }
152  i++;
153  }
154  g_info << endl;
155  return NDBT_OK;
156 }
157 
158 int runPkReadUntilStopped(NDBT_Context* ctx, NDBT_Step* step){
159  int records = ctx->getNumRecords();
160  int batchSize = ctx->getProperty("BatchSize", 1);
161  int i = 0;
162  HugoTransactions hugoTrans(*ctx->getTab());
163  while (ctx->isTestStopped() == false) {
164  g_info << i << ": ";
165  if (hugoTrans.pkReadRecords(GETNDB(step), records, batchSize) != 0){
166  g_info << endl;
167  return NDBT_FAILED;
168  }
169  i++;
170  }
171  g_info << endl;
172  return NDBT_OK;
173 }
174 
175 int runPkUpdate(NDBT_Context* ctx, NDBT_Step* step){
176  int loops = ctx->getNumLoops();
177  int records = ctx->getNumRecords();
178  int batchSize = ctx->getProperty("BatchSize", 1);
179  int i = 0;
180  HugoTransactions hugoTrans(*ctx->getTab());
181  while (i<loops) {
182  g_info << "|- " << i << ": ";
183  if (hugoTrans.pkUpdateRecords(GETNDB(step), records, batchSize) != 0){
184  g_info << endl;
185  return NDBT_FAILED;
186  }
187  i++;
188  }
189  g_info << endl;
190  return NDBT_OK;
191 }
192 
193 int runPkUpdateUntilStopped(NDBT_Context* ctx, NDBT_Step* step){
194  int records = ctx->getNumRecords();
195  int batchSize = ctx->getProperty("BatchSize", 1);
196  int i = 0;
197  HugoTransactions hugoTrans(*ctx->getTab());
198  while (ctx->isTestStopped()) {
199  g_info << i << ": ";
200  if (hugoTrans.pkUpdateRecords(GETNDB(step), records, batchSize) != 0){
201  g_info << endl;
202  return NDBT_FAILED;
203  }
204  i++;
205  }
206  g_info << endl;
207  return NDBT_OK;
208 }
209 
210 int runLocker(NDBT_Context* ctx, NDBT_Step* step){
211  int result = NDBT_OK;
212  int records = ctx->getNumRecords();
213  HugoTransactions hugoTrans(*ctx->getTab());
214 
215  if (hugoTrans.lockRecords(GETNDB(step), records, 10, 500) != 0){
216  result = NDBT_FAILED;
217  }
218  ctx->stopTest();
219 
220  return result;
221 }
222 
223 int
224 runInsertOne(NDBT_Context* ctx, NDBT_Step* step){
225 
226  if(ctx->getProperty("InsertCommitted", (Uint32)0) != 0){
227  abort();
228  }
229 
230  while(ctx->getProperty("Read1Performed", (Uint32)0) == 0){
231  NdbSleep_MilliSleep(20);
232  }
233 
234  HugoTransactions hugoTrans(*ctx->getTab());
235 
236  if (hugoTrans.loadTable(GETNDB(step), 1, 1) != 0){
237  return NDBT_FAILED;
238  }
239 
240  ctx->setProperty("InsertCommitted", 1);
241 
242  NdbSleep_SecSleep(2);
243 
244  return NDBT_OK;
245 }
246 
247 static
248 int
249 readOneNoCommit(Ndb* pNdb, NdbConnection* pTrans,
250  const NdbDictionary::Table* tab,NDBT_ResultRow * row){
251  int a;
252  NdbOperation * pOp = pTrans->getNdbOperation(tab->getName());
253  if (pOp == NULL){
254  ERR(pTrans->getNdbError());
255  return NDBT_FAILED;
256  }
257 
258  HugoTransactions tmp(*tab);
259 
260  int check = pOp->readTuple();
261  if( check == -1 ) {
262  ERR(pTrans->getNdbError());
263  return NDBT_FAILED;
264  }
265 
266  // Define primary keys
267  for(a = 0; a<tab->getNoOfColumns(); a++){
268  if (tab->getColumn(a)->getPrimaryKey() == true){
269  if(tmp.equalForAttr(pOp, a, 0) != 0){
270  ERR(pTrans->getNdbError());
271  return NDBT_FAILED;
272  }
273  }
274  }
275 
276  // Define attributes to read
277  for(a = 0; a<tab->getNoOfColumns(); a++){
278  if((row->attributeStore(a) =
279  pOp->getValue(tab->getColumn(a)->getName())) == 0) {
280  ERR(pTrans->getNdbError());
281  return NDBT_FAILED;
282  }
283  }
284 
285  check = pTrans->execute(NoCommit);
286  if( check == -1 ) {
287  const NdbError err = pTrans->getNdbError();
288  ERR(err);
289  return err.code;
290  }
291  return NDBT_OK;
292 }
293 
294 int
295 runReadOne(NDBT_Context* ctx, NDBT_Step* step){
296 
297  Ndb* pNdb = GETNDB(step);
298  const NdbDictionary::Table* tab = ctx->getTab();
299  NDBT_ResultRow row1(*tab);
300  NDBT_ResultRow row2(*tab);
301 
302  if(ctx->getProperty("Read1Performed", (Uint32)0) != 0){
303  abort();
304  }
305 
306  if(ctx->getProperty("InsertCommitted", (Uint32)0) != 0){
307  abort();
308  }
309 
310  NdbConnection * pTrans = pNdb->startTransaction();
311  if (pTrans == NULL) {
312  abort();
313  }
314 
315  // Read a record with NoCommit
316  // Since the record isn't inserted yet it wil return 626
317  const int res1 = readOneNoCommit(pNdb, pTrans, tab, &row1);
318  g_info << "|- res1 = " << res1 << endl;
319 
320  ctx->setProperty("Read1Performed", 1);
321 
322  while(ctx->getProperty("InsertCommitted", (Uint32)0) == 0 &&
323  !ctx->isTestStopped()){
324  g_info << "|- Waiting for insert" << endl;
325  NdbSleep_MilliSleep(20);
326  }
327 
328  if(ctx->isTestStopped()){
329  abort();
330  }
331 
332  // Now the record should have been inserted
333  // Read it once again in the same transaction
334  // Should also reutrn 626 if reads are consistent
335 
336  // NOTE! Currently it's not possible to start a new operation
337  // on a transaction that has returned an error code
338  // This is wat fail in this test
339  // MASV 20030624
340  const int res2 = readOneNoCommit(pNdb, pTrans, tab, &row2);
341 
342  pTrans->execute(Commit);
343  pNdb->closeTransaction(pTrans);
344  g_info << "|- res2 = " << res2 << endl;
345 
346  if (res2 == 626 && res1 == res2)
347  return NDBT_OK;
348  else
349  return NDBT_FAILED;
350 }
351 
352 int runFillTable(NDBT_Context* ctx, NDBT_Step* step){
353  int batch = 512; //4096;
354  HugoTransactions hugoTrans(*ctx->getTab());
355  if (hugoTrans.fillTable(GETNDB(step), batch ) != 0){
356  return NDBT_FAILED;
357  }
358  return NDBT_OK;
359 }
360 
361 int runClearTable2(NDBT_Context* ctx, NDBT_Step* step){
362  int records = ctx->getNumRecords();
363 
364  UtilTransactions utilTrans(*ctx->getTab());
365  if (utilTrans.clearTable2(GETNDB(step), records, 240) != 0){
366  return NDBT_FAILED;
367  }
368  return NDBT_OK;
369 }
370 
371 #define CHECK(b) if (!(b)) { \
372  ndbout << "ERR: "<< step->getName() \
373  << " failed on line " << __LINE__ << endl; \
374  result = NDBT_FAILED; \
375  break; }
376 
377 int runNoCommitSleep(NDBT_Context* ctx, NDBT_Step* step){
378  int result = NDBT_OK;
379  HugoOperations hugoOps(*ctx->getTab());
380  Ndb* pNdb = GETNDB(step);
381  int sleepTime = 100; // ms
382  for (int i = 2; i < 8; i++){
383 
384  CHECK(hugoOps.startTransaction(pNdb) == 0);
385  CHECK(hugoOps.pkReadRecord(pNdb, 1, 1, NdbOperation::LM_Exclusive) == 0);
386  CHECK(hugoOps.execute_NoCommit(pNdb) == 0);
387 
388  ndbout << i <<": Sleeping for " << sleepTime << " ms" << endl;
389  NdbSleep_MilliSleep(sleepTime);
390 
391  // Dont care about result of these ops
392  hugoOps.pkReadRecord(pNdb, 1, 1, NdbOperation::LM_Exclusive);
393  hugoOps.closeTransaction(pNdb);
394 
395  sleepTime = sleepTime *i;
396  }
397 
398  hugoOps.closeTransaction(pNdb);
399 
400  return result;
401 }
402 
403 int runCommit626(NDBT_Context* ctx, NDBT_Step* step){
404  int result = NDBT_OK;
405  HugoOperations hugoOps(*ctx->getTab());
406  Ndb* pNdb = GETNDB(step);
407 
408  do{
409  // Commit transaction
410  CHECK(hugoOps.startTransaction(pNdb) == 0);
411  CHECK(hugoOps.pkReadRecord(pNdb, 1, 1, NdbOperation::LM_Exclusive) == 0);
412  CHECK(hugoOps.execute_Commit(pNdb) == 626);
413  CHECK(hugoOps.closeTransaction(pNdb) == 0);
414 
415  // Commit transaction
416  // Multiple operations
417  CHECK(hugoOps.startTransaction(pNdb) == 0);
418  CHECK(hugoOps.pkReadRecord(pNdb, 1, 1, NdbOperation::LM_Exclusive) == 0);
419  CHECK(hugoOps.pkReadRecord(pNdb, 2, 1, NdbOperation::LM_Exclusive) == 0);
420  CHECK(hugoOps.pkReadRecord(pNdb, 3, 1, NdbOperation::LM_Exclusive) == 0);
421  CHECK(hugoOps.execute_Commit(pNdb) == 626);
422  }while(false);
423 
424  hugoOps.closeTransaction(pNdb);
425 
426  return result;
427 }
428 
429 int runCommit630(NDBT_Context* ctx, NDBT_Step* step){
430  int result = NDBT_OK;
431  HugoOperations hugoOps(*ctx->getTab());
432  Ndb* pNdb = GETNDB(step);
433 
434  do{
435  // Commit transaction
436  CHECK(hugoOps.startTransaction(pNdb) == 0);
437  CHECK(hugoOps.pkInsertRecord(pNdb, 1) == 0);
438  CHECK(hugoOps.execute_Commit(pNdb) == 630);
439  }while(false);
440 
441  hugoOps.closeTransaction(pNdb);
442 
443  return result;
444 }
445 
446 int runCommit_TryCommit626(NDBT_Context* ctx, NDBT_Step* step){
447  int result = NDBT_OK;
448  HugoOperations hugoOps(*ctx->getTab());
449  Ndb* pNdb = GETNDB(step);
450 
451  do{
452  // Commit transaction, TryCommit
453  CHECK(hugoOps.startTransaction(pNdb) == 0);
454  CHECK(hugoOps.pkReadRecord(pNdb, 1, 1, NdbOperation::LM_Exclusive) == 0);
455  CHECK(hugoOps.execute_Commit(pNdb, TryCommit) == 626);
456  CHECK(hugoOps.closeTransaction(pNdb) == 0);
457 
458  // Commit transaction, TryCommit
459  // Several operations in one transaction
460  // The insert is OK
461  CHECK(hugoOps.startTransaction(pNdb) == 0);
462  CHECK(hugoOps.pkReadRecord(pNdb, 1, 1, NdbOperation::LM_Exclusive) == 0);
463  CHECK(hugoOps.pkReadRecord(pNdb, 2, 1, NdbOperation::LM_Exclusive) == 0);
464  CHECK(hugoOps.pkReadRecord(pNdb, 3, 1, NdbOperation::LM_Exclusive) == 0);
465  CHECK(hugoOps.pkInsertRecord(pNdb, 1) == 0);
466  CHECK(hugoOps.pkReadRecord(pNdb, 4, 1, NdbOperation::LM_Exclusive) == 0);
467  CHECK(hugoOps.execute_Commit(pNdb, TryCommit) == 626);
468  }while(false);
469 
470  hugoOps.closeTransaction(pNdb);
471 
472  return result;
473 }
474 
475 int runCommit_TryCommit630(NDBT_Context* ctx, NDBT_Step* step){
476  int result = NDBT_OK;
477  HugoOperations hugoOps(*ctx->getTab());
478  Ndb* pNdb = GETNDB(step);
479 
480  do{
481  // Commit transaction, TryCommit
482  CHECK(hugoOps.startTransaction(pNdb) == 0);
483  CHECK(hugoOps.pkInsertRecord(pNdb, 1) == 0);
484  CHECK(hugoOps.execute_Commit(pNdb, TryCommit) == 630);
485  }while(false);
486 
487  hugoOps.closeTransaction(pNdb);
488 
489  return result;
490 }
491 
492 int runCommit_CommitAsMuchAsPossible626(NDBT_Context* ctx, NDBT_Step* step){
493  int result = NDBT_OK;
494  HugoOperations hugoOps(*ctx->getTab());
495  Ndb* pNdb = GETNDB(step);
496 
497  do{
498  // Commit transaction, CommitAsMuchAsPossible
499  CHECK(hugoOps.startTransaction(pNdb) == 0);
500  CHECK(hugoOps.pkReadRecord(pNdb, 1, 1, NdbOperation::LM_Exclusive) == 0);
501  CHECK(hugoOps.execute_Commit(pNdb, CommitAsMuchAsPossible) == 626);
502  CHECK(hugoOps.closeTransaction(pNdb) == 0);
503 
504  // Commit transaction, CommitAsMuchAsPossible
505  CHECK(hugoOps.startTransaction(pNdb) == 0);
506  CHECK(hugoOps.pkReadRecord(pNdb, 2, 1, NdbOperation::LM_Exclusive) == 0);
507  CHECK(hugoOps.pkReadRecord(pNdb, 3, 1, NdbOperation::LM_Exclusive) == 0);
508  CHECK(hugoOps.pkInsertRecord(pNdb, 1) == 0);
509  CHECK(hugoOps.execute_Commit(pNdb, CommitAsMuchAsPossible) == 626);
510  CHECK(hugoOps.closeTransaction(pNdb) == 0);
511 
512  CHECK(hugoOps.startTransaction(pNdb) == 0);
513  CHECK(hugoOps.pkReadRecord(pNdb, 1) == 0);
514  CHECK(hugoOps.execute_Commit(pNdb) == 0);
515  CHECK(hugoOps.closeTransaction(pNdb) == 0);
516  } while(false);
517 
518  hugoOps.closeTransaction(pNdb);
519 
520  return result;
521 }
522 
523 int runCommit_CommitAsMuchAsPossible630(NDBT_Context* ctx, NDBT_Step* step){
524  int result = NDBT_OK;
525  HugoOperations hugoOps(*ctx->getTab());
526  Ndb* pNdb = GETNDB(step);
527 
528  do{
529  // Commit transaction, CommitAsMuchAsPossible
530  CHECK(hugoOps.startTransaction(pNdb) == 0);
531  CHECK(hugoOps.pkInsertRecord(pNdb, 1) == 0);
532  CHECK(hugoOps.pkDeleteRecord(pNdb, 2) == 0);
533  CHECK(hugoOps.execute_Commit(pNdb, CommitAsMuchAsPossible) == 630);
534  CHECK(hugoOps.closeTransaction(pNdb) == 0);
535 
536  CHECK(hugoOps.startTransaction(pNdb) == 0);
537  CHECK(hugoOps.pkReadRecord(pNdb, 2) == 0);
538  CHECK(hugoOps.execute_Commit(pNdb) == 626);
539  } while(false);
540 
541  hugoOps.closeTransaction(pNdb);
542 
543  return result;
544 }
545 
546 int runNoCommit626(NDBT_Context* ctx, NDBT_Step* step){
547  int result = NDBT_OK;
548  HugoOperations hugoOps(*ctx->getTab());
549  Ndb* pNdb = GETNDB(step);
550 
551  do{
552  // No commit transaction, readTuple
553  CHECK(hugoOps.startTransaction(pNdb) == 0);
554  CHECK(hugoOps.pkReadRecord(pNdb, 1, 1, NdbOperation::LM_Read) == 0);
555  CHECK(hugoOps.execute_NoCommit(pNdb) == 626);
556  CHECK(hugoOps.closeTransaction(pNdb) == 0);
557 
558  // No commit transaction, readTupleExcluive
559  CHECK(hugoOps.startTransaction(pNdb) == 0);
560  CHECK(hugoOps.pkReadRecord(pNdb, 1, 1, NdbOperation::LM_Exclusive) == 0);
561  CHECK(hugoOps.execute_NoCommit(pNdb) == 626);
562  }while(false);
563 
564  hugoOps.closeTransaction(pNdb);
565 
566  return result;
567 }
568 
569 int runNoCommit630(NDBT_Context* ctx, NDBT_Step* step){
570  int result = NDBT_OK;
571  HugoOperations hugoOps(*ctx->getTab());
572  Ndb* pNdb = GETNDB(step);
573 
574  do{
575  // No commit transaction
576  CHECK(hugoOps.startTransaction(pNdb) == 0);
577  CHECK(hugoOps.pkInsertRecord(pNdb, 1) == 0);
578  CHECK(hugoOps.execute_NoCommit(pNdb) == 630);
579  }while(false);
580 
581  hugoOps.closeTransaction(pNdb);
582 
583  return result;
584 }
585 
586 int runNoCommitRollback626(NDBT_Context* ctx, NDBT_Step* step){
587  int result = NDBT_OK;
588  HugoOperations hugoOps(*ctx->getTab());
589  Ndb* pNdb = GETNDB(step);
590 
591  do{
592  // No commit transaction, rollback
593  CHECK(hugoOps.startTransaction(pNdb) == 0);
594  CHECK(hugoOps.pkReadRecord(pNdb, 1, 1, NdbOperation::LM_Exclusive) == 0);
595  CHECK(hugoOps.execute_NoCommit(pNdb) == 626);
596  CHECK(hugoOps.execute_Rollback(pNdb) == 0);
597  CHECK(hugoOps.closeTransaction(pNdb) == 0);
598 
599  // No commit transaction, rollback
600  // Multiple operations
601  CHECK(hugoOps.startTransaction(pNdb) == 0);
602  CHECK(hugoOps.pkReadRecord(pNdb, 1, 1, NdbOperation::LM_Exclusive) == 0);
603  CHECK(hugoOps.pkReadRecord(pNdb, 2, 1, NdbOperation::LM_Exclusive) == 0);
604  CHECK(hugoOps.pkReadRecord(pNdb, 3, 1, NdbOperation::LM_Exclusive) == 0);
605  CHECK(hugoOps.pkReadRecord(pNdb, 4, 1, NdbOperation::LM_Exclusive) == 0);
606  CHECK(hugoOps.execute_NoCommit(pNdb) == 626);
607  CHECK(hugoOps.execute_Rollback(pNdb) == 0);
608  }while(false);
609 
610  hugoOps.closeTransaction(pNdb);
611 
612  return result;
613 }
614 
615 int runNoCommitRollback630(NDBT_Context* ctx, NDBT_Step* step){
616  int result = NDBT_OK;
617  HugoOperations hugoOps(*ctx->getTab());
618  Ndb* pNdb = GETNDB(step);
619 
620  do{
621  // No commit transaction, rollback
622  CHECK(hugoOps.startTransaction(pNdb) == 0);
623  CHECK(hugoOps.pkInsertRecord(pNdb, 1) == 0);
624  CHECK(hugoOps.execute_NoCommit(pNdb) == 630);
625  CHECK(hugoOps.execute_Rollback(pNdb) == 0);
626  }while(false);
627 
628  hugoOps.closeTransaction(pNdb);
629 
630  return result;
631 }
632 
633 
634 int runNoCommitAndClose(NDBT_Context* ctx, NDBT_Step* step){
635  int i, result = NDBT_OK;
636  HugoOperations hugoOps(*ctx->getTab());
637  Ndb* pNdb = GETNDB(step);
638 
639  do{
640  // Read
641  CHECK(hugoOps.startTransaction(pNdb) == 0);
642  for (i = 0; i < 10; i++)
643  CHECK(hugoOps.pkReadRecord(pNdb, i, 1, NdbOperation::LM_Exclusive) == 0);
644  CHECK(hugoOps.execute_NoCommit(pNdb) == 0);
645  CHECK(hugoOps.closeTransaction(pNdb) == 0);
646 
647  // Update
648  CHECK(hugoOps.startTransaction(pNdb) == 0);
649  for (i = 0; i < 10; i++)
650  CHECK(hugoOps.pkUpdateRecord(pNdb, i) == 0);
651  CHECK(hugoOps.execute_NoCommit(pNdb) == 0);
652  CHECK(hugoOps.closeTransaction(pNdb) == 0);
653 
654  // Delete
655  CHECK(hugoOps.startTransaction(pNdb) == 0);
656  for (i = 0; i < 10; i++)
657  CHECK(hugoOps.pkDeleteRecord(pNdb, i) == 0);
658  CHECK(hugoOps.execute_NoCommit(pNdb) == 0);
659  CHECK(hugoOps.closeTransaction(pNdb) == 0);
660 
661  // Try to insert, record should already exist
662  CHECK(hugoOps.startTransaction(pNdb) == 0);
663  for (i = 0; i < 10; i++)
664  CHECK(hugoOps.pkInsertRecord(pNdb, i) == 0);
665  CHECK(hugoOps.execute_Commit(pNdb) == 630);
666  CHECK(hugoOps.closeTransaction(pNdb) == 0);
667 
668  }while(false);
669 
670  hugoOps.closeTransaction(pNdb);
671 
672  return result;
673 }
674 
675 
676 
677 int runCheckRollbackDelete(NDBT_Context* ctx, NDBT_Step* step){
678  int result = NDBT_OK;
679  HugoOperations hugoOps(*ctx->getTab());
680  Ndb* pNdb = GETNDB(step);
681 
682  do{
683 
684  // Read value and save it for later
685  CHECK(hugoOps.startTransaction(pNdb) == 0);
686  CHECK(hugoOps.pkReadRecord(pNdb, 5) == 0);
687  CHECK(hugoOps.execute_Commit(pNdb) == 0);
688  CHECK(hugoOps.saveCopyOfRecord() == NDBT_OK);
689  CHECK(hugoOps.closeTransaction(pNdb) == 0);
690 
691  // Delete record 5
692  CHECK(hugoOps.startTransaction(pNdb) == 0);
693  CHECK(hugoOps.pkDeleteRecord(pNdb, 5) == 0);
694  CHECK(hugoOps.execute_NoCommit(pNdb) == 0);
695 
696  // Check record is deleted
697  CHECK(hugoOps.pkReadRecord(pNdb, 5, 1, NdbOperation::LM_Exclusive) == 0);
698  CHECK(hugoOps.execute_NoCommit(pNdb) == 626);
699  CHECK(hugoOps.execute_Rollback(pNdb) == 0);
700 
701  CHECK(hugoOps.closeTransaction(pNdb) == 0);
702 
703  // Check record is not deleted
704  CHECK(hugoOps.startTransaction(pNdb) == 0);
705  CHECK(hugoOps.pkReadRecord(pNdb, 5, 1, NdbOperation::LM_Exclusive) == 0);
706  CHECK(hugoOps.execute_Commit(pNdb) == 0);
707  CHECK(hugoOps.closeTransaction(pNdb) == 0);
708 
709  // Check record is back to original value
710  CHECK(hugoOps.startTransaction(pNdb) == 0);
711  CHECK(hugoOps.pkReadRecord(pNdb, 5, 1, NdbOperation::LM_Exclusive) == 0);
712  CHECK(hugoOps.execute_Commit(pNdb) == 0);
713  CHECK(hugoOps.compareRecordToCopy() == NDBT_OK);
714 
715 
716  }while(false);
717 
718  hugoOps.closeTransaction(pNdb);
719 
720  return result;
721 }
722 
723 int runCheckRollbackUpdate(NDBT_Context* ctx, NDBT_Step* step){
724  int result = NDBT_OK;
725  HugoOperations hugoOps(*ctx->getTab());
726  Ndb* pNdb = GETNDB(step);
727  int numRecords = 5;
728  do{
729 
730  // Read value and save it for later
731  CHECK(hugoOps.startTransaction(pNdb) == 0);
732  CHECK(hugoOps.pkReadRecord(pNdb, 1, numRecords) == 0);
733  CHECK(hugoOps.execute_Commit(pNdb) == 0);
734  CHECK(hugoOps.verifyUpdatesValue(0) == NDBT_OK); // Update value 0
735  CHECK(hugoOps.closeTransaction(pNdb) == 0);
736 
737  // Update record 5
738  CHECK(hugoOps.startTransaction(pNdb) == 0);
739  CHECK(hugoOps.pkUpdateRecord(pNdb, 1, numRecords, 5) == 0);// Updates value 5
740  CHECK(hugoOps.execute_NoCommit(pNdb) == 0);
741 
742  // Check record is updated
743  CHECK(hugoOps.pkReadRecord(pNdb, 1, numRecords, NdbOperation::LM_Exclusive) == 0);
744  CHECK(hugoOps.execute_NoCommit(pNdb) == 0);
745  CHECK(hugoOps.verifyUpdatesValue(5) == NDBT_OK); // Updates value 5
746  CHECK(hugoOps.execute_Rollback(pNdb) == 0);
747 
748  CHECK(hugoOps.closeTransaction(pNdb) == 0);
749 
750  // Check record is back to original value
751  CHECK(hugoOps.startTransaction(pNdb) == 0);
752  CHECK(hugoOps.pkReadRecord(pNdb, 1, numRecords, NdbOperation::LM_Exclusive) == 0);
753  CHECK(hugoOps.execute_Commit(pNdb) == 0);
754  CHECK(hugoOps.verifyUpdatesValue(0) == NDBT_OK); // Updates value 0
755 
756  }while(false);
757 
758  hugoOps.closeTransaction(pNdb);
759 
760  return result;
761 }
762 
763 int runCheckRollbackDeleteMultiple(NDBT_Context* ctx, NDBT_Step* step){
764  int result = NDBT_OK;
765  HugoOperations hugoOps(*ctx->getTab());
766  Ndb* pNdb = GETNDB(step);
767 
768  do{
769  // Read value and save it for later
770  CHECK(hugoOps.startTransaction(pNdb) == 0);
771  CHECK(hugoOps.pkReadRecord(pNdb, 5, 10) == 0);
772  CHECK(hugoOps.execute_Commit(pNdb) == 0);
773  CHECK(hugoOps.verifyUpdatesValue(0) == NDBT_OK);
774  CHECK(hugoOps.closeTransaction(pNdb) == 0);
775 
776  Uint32 updatesValue = 0;
777  Uint32 j;
778  for(Uint32 i = 0; i<1; i++){
779  // Read record 5 - 10
780  CHECK(hugoOps.startTransaction(pNdb) == 0);
781  CHECK(hugoOps.pkReadRecord(pNdb, 5, 10, NdbOperation::LM_Exclusive) == 0);
782  CHECK(hugoOps.execute_NoCommit(pNdb) == 0);
783 
784  for(j = 0; j<10; j++){
785  // Update record 5 - 10
786  updatesValue++;
787  CHECK(hugoOps.pkUpdateRecord(pNdb, 5, 10, updatesValue) == 0);
788  CHECK(hugoOps.execute_NoCommit(pNdb) == 0);
789 
790  CHECK(hugoOps.pkReadRecord(pNdb, 5, 10, NdbOperation::LM_Exclusive) == 0);
791  CHECK(hugoOps.execute_NoCommit(pNdb) == 0);
792  CHECK(hugoOps.verifyUpdatesValue(updatesValue) == 0);
793  }
794 
795  for(j = 0; j<10; j++){
796  // Delete record 5 - 10 times
797  CHECK(hugoOps.pkDeleteRecord(pNdb, 5, 10) == 0);
798  CHECK(hugoOps.execute_NoCommit(pNdb) == 0);
799 
800 #if 0
801  // Check records are deleted
802  CHECK(hugoOps.pkReadRecord(pNdb, 5, 10, NdbOperation::LM_Exclusive) == 0);
803  CHECK(hugoOps.execute_NoCommit(pNdb) == 626);
804 #endif
805 
806  updatesValue++;
807  CHECK(hugoOps.pkInsertRecord(pNdb, 5, 10, updatesValue) == 0);
808  CHECK(hugoOps.execute_NoCommit(pNdb) == 0);
809 
810  CHECK(hugoOps.pkReadRecord(pNdb, 5, 10, NdbOperation::LM_Exclusive) == 0);
811  CHECK(hugoOps.execute_NoCommit(pNdb) == 0);
812  CHECK(hugoOps.verifyUpdatesValue(updatesValue) == 0);
813  }
814 
815  CHECK(hugoOps.pkDeleteRecord(pNdb, 5, 10) == 0);
816  CHECK(hugoOps.execute_NoCommit(pNdb) == 0);
817 
818  // Check records are deleted
819  CHECK(hugoOps.pkReadRecord(pNdb, 5, 10, NdbOperation::LM_Exclusive) == 0);
820  CHECK(hugoOps.execute_NoCommit(pNdb) == 626);
821  CHECK(hugoOps.execute_Rollback(pNdb) == 0);
822 
823  CHECK(hugoOps.closeTransaction(pNdb) == 0);
824  }
825 
826  // Check records are not deleted
827  // after rollback
828  CHECK(hugoOps.startTransaction(pNdb) == 0);
829  CHECK(hugoOps.pkReadRecord(pNdb, 5, 10, NdbOperation::LM_Exclusive) == 0);
830  CHECK(hugoOps.execute_Commit(pNdb) == 0);
831  CHECK(hugoOps.verifyUpdatesValue(0) == NDBT_OK);
832 
833  }while(false);
834 
835  hugoOps.closeTransaction(pNdb);
836 
837  return result;
838 }
839 
840 
841 int runCheckImplicitRollbackDelete(NDBT_Context* ctx, NDBT_Step* step){
842  int result = NDBT_OK;
843  HugoOperations hugoOps(*ctx->getTab());
844  Ndb* pNdb = GETNDB(step);
845 
846  do{
847  // Read record 5
848  CHECK(hugoOps.startTransaction(pNdb) == 0);
849  CHECK(hugoOps.pkReadRecord(pNdb, 5, 1, NdbOperation::LM_Exclusive) == 0);
850  CHECK(hugoOps.execute_NoCommit(pNdb) == 0);
851  CHECK(hugoOps.closeTransaction(pNdb) == 0);
852 
853  // Update record 5
854  CHECK(hugoOps.startTransaction(pNdb) == 0);
855  CHECK(hugoOps.pkUpdateRecord(pNdb, 5) == 0);
856  CHECK(hugoOps.execute_NoCommit(pNdb) == 0);
857  CHECK(hugoOps.closeTransaction(pNdb) == 0);
858 
859  // Delete record 5
860  CHECK(hugoOps.startTransaction(pNdb) == 0);
861  CHECK(hugoOps.pkDeleteRecord(pNdb, 5) == 0);
862  CHECK(hugoOps.execute_NoCommit(pNdb) == 0);
863  CHECK(hugoOps.closeTransaction(pNdb) == 0);
864 
865  // Check record is not deleted
866  // Close transaction should have rollbacked
867  CHECK(hugoOps.startTransaction(pNdb) == 0);
868  CHECK(hugoOps.pkReadRecord(pNdb, 5, 1, NdbOperation::LM_Exclusive) == 0);
869  CHECK(hugoOps.execute_Commit(pNdb) == 0);
870  }while(false);
871 
872  hugoOps.closeTransaction(pNdb);
873 
874  return result;
875 }
876 
877 int runCheckCommitDelete(NDBT_Context* ctx, NDBT_Step* step){
878  int result = NDBT_OK;
879  HugoOperations hugoOps(*ctx->getTab());
880  Ndb* pNdb = GETNDB(step);
881 
882  do{
883  // Read 10 records
884  CHECK(hugoOps.startTransaction(pNdb) == 0);
885  CHECK(hugoOps.pkReadRecord(pNdb, 5, 10, NdbOperation::LM_Exclusive) == 0);
886  CHECK(hugoOps.execute_NoCommit(pNdb) == 0);
887 
888  // Update 10 records
889  CHECK(hugoOps.pkUpdateRecord(pNdb, 5, 10) == 0);
890  CHECK(hugoOps.execute_NoCommit(pNdb) == 0);
891 
892  // Delete 10 records
893  CHECK(hugoOps.pkDeleteRecord(pNdb, 5, 10) == 0);
894  CHECK(hugoOps.execute_NoCommit(pNdb) == 0);
895 
896  CHECK(hugoOps.execute_Commit(pNdb) == 0);
897  CHECK(hugoOps.closeTransaction(pNdb) == 0);
898 
899  // Check record's are deleted
900  CHECK(hugoOps.startTransaction(pNdb) == 0);
901  CHECK(hugoOps.pkReadRecord(pNdb, 5, 10, NdbOperation::LM_Exclusive) == 0);
902  CHECK(hugoOps.execute_Commit(pNdb) == 626);
903 
904  }while(false);
905 
906  hugoOps.closeTransaction(pNdb);
907 
908  return result;
909 }
910 
911 int runRollbackNothing(NDBT_Context* ctx, NDBT_Step* step){
912  int result = NDBT_OK;
913  HugoOperations hugoOps(*ctx->getTab());
914  Ndb* pNdb = GETNDB(step);
915 
916  do{
917  // Delete record 5 - 15
918  CHECK(hugoOps.startTransaction(pNdb) == 0);
919  CHECK(hugoOps.pkDeleteRecord(pNdb, 5, 10) == 0);
920  // Rollback
921  CHECK(hugoOps.execute_Rollback(pNdb) == 0);
922  CHECK(hugoOps.closeTransaction(pNdb) == 0);
923 
924  // Check records are not deleted
925  CHECK(hugoOps.startTransaction(pNdb) == 0);
926  CHECK(hugoOps.pkReadRecord(pNdb, 5, 10, NdbOperation::LM_Exclusive) == 0);
927  CHECK(hugoOps.execute_Commit(pNdb) == 0);
928  CHECK(hugoOps.closeTransaction(pNdb) == 0);
929 
930  CHECK(hugoOps.startTransaction(pNdb) == 0);
931  CHECK(hugoOps.execute_Rollback(pNdb) == 0);
932 
933  }while(false);
934 
935  hugoOps.closeTransaction(pNdb);
936 
937  return result;
938 }
939 
940 int runMassiveRollback(NDBT_Context* ctx, NDBT_Step* step){
941 
942  NdbRestarter restarter;
943  const int records = 4 * restarter.getNumDbNodes();
944 
945  HugoTransactions hugoTrans(*ctx->getTab());
946  if (hugoTrans.loadTable(GETNDB(step), records) != 0){
947  return NDBT_FAILED;
948  }
949 
950  int result = NDBT_OK;
951  HugoOperations hugoOps(*ctx->getTab());
952  Ndb* pNdb = GETNDB(step);
953 
954  const Uint32 OPS_PER_TRANS = 256;
955  const Uint32 OPS_TOTAL = 4096;
956 
957  for(int row = 0; row < records; row++){
958  int res;
959  CHECK(hugoOps.startTransaction(pNdb) == 0);
960  for(Uint32 i = 0; i<OPS_TOTAL; i += OPS_PER_TRANS){
961  for(Uint32 j = 0; j<OPS_PER_TRANS; j++){
962  CHECK(hugoOps.pkUpdateRecord(pNdb, row, 1, i) == 0);
963  }
964  g_info << "Performed " << (i+OPS_PER_TRANS) << " updates on row: " << row
965  << endl;
966  if(result != NDBT_OK){
967  break;
968  }
969  res = hugoOps.execute_NoCommit(pNdb);
970  if(res != 0){
971  NdbError err = pNdb->getNdbError(res);
973  break;
974  }
975  }
976  if(result != NDBT_OK){
977  break;
978  }
979  g_info << "executeRollback" << endl;
980  CHECK(hugoOps.execute_Rollback(pNdb) == 0);
981  CHECK(hugoOps.closeTransaction(pNdb) == 0);
982  }
983 
984  hugoOps.closeTransaction(pNdb);
985  return result;
986 }
987 
988 int
989 runMassiveRollback2(NDBT_Context* ctx, NDBT_Step* step){
990 
991  HugoTransactions hugoTrans(*ctx->getTab());
992  if (hugoTrans.loadTable(GETNDB(step), 1) != 0){
993  return NDBT_FAILED;
994  }
995 
996  int result = NDBT_OK;
997  HugoOperations hugoOps(*ctx->getTab());
998  Ndb* pNdb = GETNDB(step);
999 
1000  const Uint32 OPS_TOTAL = 4096;
1001  const Uint32 LOOPS = 10;
1002 
1003  for(Uint32 loop = 0; loop<LOOPS; loop++){
1004  CHECK(hugoOps.startTransaction(pNdb) == 0);
1005  for(Uint32 i = 0; i<OPS_TOTAL-1; i ++){
1006  if((i & 1) == 0){
1007  CHECK(hugoOps.pkUpdateRecord(pNdb, 0, 1, loop) == 0);
1008  } else {
1009  CHECK(hugoOps.pkUpdateRecord(pNdb, 1, 1, loop) == 0);
1010  }
1011  }
1012  CHECK(hugoOps.execute_Commit(pNdb) == 626);
1013  CHECK(hugoOps.execute_Rollback(pNdb) == 0);
1014  CHECK(hugoOps.closeTransaction(pNdb) == 0);
1015  }
1016 
1017  hugoOps.closeTransaction(pNdb);
1018  return result;
1019 }
1020 
1021 int
1022 runMassiveRollback3(NDBT_Context* ctx, NDBT_Step* step){
1023 
1024  int result = NDBT_OK;
1025  HugoOperations hugoOps(*ctx->getTab());
1026  Ndb* pNdb = GETNDB(step);
1027 
1028  const Uint32 BATCH = 10;
1029  const Uint32 OPS_TOTAL = 50;
1030  const Uint32 LOOPS = 100;
1031 
1032  for(Uint32 loop = 0; loop<LOOPS; loop++)
1033  {
1034  CHECK(hugoOps.startTransaction(pNdb) == 0);
1035  bool ok = true;
1036  for (Uint32 i = 0; i<OPS_TOTAL; i+= BATCH)
1037  {
1038  CHECK(hugoOps.pkInsertRecord(pNdb, i, BATCH, 0) == 0);
1039  if (hugoOps.execute_NoCommit(pNdb) != 0)
1040  {
1041  ok = false;
1042  break;
1043  }
1044  }
1045  hugoOps.execute_Rollback(pNdb);
1046  CHECK(hugoOps.closeTransaction(pNdb) == 0);
1047  }
1048 
1049  hugoOps.closeTransaction(pNdb);
1050  return result;
1051 }
1052 
1053 int
1054 runMassiveRollback4(NDBT_Context* ctx, NDBT_Step* step){
1055 
1056  int result = NDBT_OK;
1057  HugoOperations hugoOps(*ctx->getTab());
1058  Ndb* pNdb = GETNDB(step);
1059 
1060  const Uint32 BATCH = 10;
1061  const Uint32 OPS_TOTAL = 20;
1062  const Uint32 LOOPS = 100;
1063 
1064  for(Uint32 loop = 0; loop<LOOPS; loop++)
1065  {
1066  CHECK(hugoOps.startTransaction(pNdb) == 0);
1067  bool ok = true;
1068  for (Uint32 i = 0; i<OPS_TOTAL; i+= BATCH)
1069  {
1070  CHECK(hugoOps.pkInsertRecord(pNdb, i, BATCH, 0) == 0);
1071  CHECK(hugoOps.pkDeleteRecord(pNdb, i, BATCH) == 0);
1072  if (hugoOps.execute_NoCommit(pNdb) != 0)
1073  {
1074  ok = false;
1075  break;
1076  }
1077  }
1078  hugoOps.execute_Rollback(pNdb);
1079  CHECK(hugoOps.closeTransaction(pNdb) == 0);
1080  }
1081 
1082  hugoOps.closeTransaction(pNdb);
1083  return result;
1084 }
1085 
1089 struct TupError
1090 {
1091  enum Bits {
1092  TE_VARSIZE = 0x1,
1093  TE_MULTI_OP = 0x2,
1094  TE_DISK = 0x4,
1095  TE_REPLICA = 0x8,
1096  TE_OI = 0x10, // Ordered index
1097  TE_UI = 0x20 // Unique hash index
1098  };
1099  int op;
1100  int error;
1101  int bits;
1102 };
1103 
1104 static
1105 TupError
1106 f_tup_errors[] =
1107 {
1108  { NdbOperation::InsertRequest, 4014, 0 }, // Out of undo buffer
1109  { NdbOperation::InsertRequest, 4015, TupError::TE_DISK }, // Out of log space
1110  { NdbOperation::InsertRequest, 4016, 0 }, // AI Inconsistency
1111  { NdbOperation::InsertRequest, 4017, 0 }, // Out of memory
1112  { NdbOperation::InsertRequest, 4018, 0 }, // Null check error
1113  { NdbOperation::InsertRequest, 4019, TupError::TE_REPLICA }, //Alloc rowid error
1114  { NdbOperation::InsertRequest, 4020, TupError::TE_MULTI_OP }, // Size change error
1115  { NdbOperation::InsertRequest, 4021, TupError::TE_DISK }, // Out of disk space
1116  { NdbOperation::InsertRequest, 4022, TupError::TE_OI },
1117  { NdbOperation::InsertRequest, 4023, TupError::TE_OI },
1118  { NdbOperation::UpdateRequest, 4030, TupError::TE_UI },
1119  { -1, 0, 0 }
1120 };
1121 
1122 int
1123 runTupErrors(NDBT_Context* ctx, NDBT_Step* step){
1124 
1125  NdbRestarter restarter;
1126  HugoTransactions hugoTrans(*ctx->getTab());
1127  HugoOperations hugoOps(*ctx->getTab());
1128  Ndb* pNdb = GETNDB(step);
1129 
1130  const NdbDictionary::Table * tab = ctx->getTab();
1131  int i;
1132  int bits = TupError::TE_MULTI_OP;
1133  for(i = 0; i<tab->getNoOfColumns(); i++)
1134  {
1135  if (tab->getColumn(i)->getArrayType() != NdbDictionary::Column::ArrayTypeFixed)
1136  bits |= TupError::TE_VARSIZE;
1137  if (tab->getColumn(i)->getStorageType()!= NdbDictionary::Column::StorageTypeMemory)
1138  bits |= TupError::TE_DISK;
1139  }
1140 
1141  if (restarter.getNumDbNodes() >= 2)
1142  {
1143  bits |= TupError::TE_REPLICA;
1144  }
1145 
1147  pNdb->getDictionary()->listIndexes(l, tab->getName());
1148  for (i = 0; i<(int)l.count; i++)
1149  {
1150  if (DictTabInfo::isOrderedIndex(l.elements[i].type))
1151  bits |= TupError::TE_OI;
1152  if (DictTabInfo::isUniqueIndex(l.elements[i].type))
1153  bits |= TupError::TE_UI;
1154  }
1155 
1159  for(i = 0; f_tup_errors[i].op != -1; i++)
1160  {
1161  if (f_tup_errors[i].op != NdbOperation::InsertRequest)
1162  {
1163  continue;
1164  }
1165 
1166  if ((f_tup_errors[i].bits & bits) != f_tup_errors[i].bits)
1167  {
1168  g_err << "Skipping " << f_tup_errors[i].error
1169  << " - req bits: " << hex << f_tup_errors[i].bits
1170  << " bits: " << hex << bits << endl;
1171  continue;
1172  }
1173 
1174  g_err << "Testing error insert: " << f_tup_errors[i].error << endl;
1175  restarter.insertErrorInAllNodes(f_tup_errors[i].error);
1176  if (f_tup_errors[i].bits & TupError::TE_MULTI_OP)
1177  {
1178 
1179  }
1180  else
1181  {
1182  hugoTrans.loadTable(pNdb, 5);
1183  }
1184  restarter.insertErrorInAllNodes(0);
1185  if (hugoTrans.clearTable(pNdb, 5) != 0)
1186  {
1187  return NDBT_FAILED;
1188  }
1189  }
1190 
1194  hugoTrans.loadTable(pNdb, 5);
1195  for(i = 0; f_tup_errors[i].op != -1; i++)
1196  {
1197  if (f_tup_errors[i].op != NdbOperation::UpdateRequest)
1198  {
1199  continue;
1200  }
1201 
1202  if ((f_tup_errors[i].bits & bits) != f_tup_errors[i].bits)
1203  {
1204  g_err << "Skipping " << f_tup_errors[i].error
1205  << " - req bits: " << hex << f_tup_errors[i].bits
1206  << " bits: " << hex << bits << endl;
1207  continue;
1208  }
1209 
1210  g_err << "Testing error insert: " << f_tup_errors[i].error << endl;
1211  restarter.insertErrorInAllNodes(f_tup_errors[i].error);
1212  if (f_tup_errors[i].bits & TupError::TE_MULTI_OP)
1213  {
1214 
1215  }
1216  else
1217  {
1218  hugoTrans.scanUpdateRecords(pNdb, 5);
1219  }
1220  restarter.insertErrorInAllNodes(0);
1221  if (hugoTrans.scanUpdateRecords(pNdb, 5) != 0)
1222  {
1223  return NDBT_FAILED;
1224  }
1225  }
1226 
1227  return NDBT_OK;
1228 }
1229 
1230 int
1231 runInsertError(NDBT_Context* ctx, NDBT_Step* step){
1232 
1233  int result = NDBT_OK;
1234  HugoOperations hugoOp1(*ctx->getTab());
1235  HugoOperations hugoOp2(*ctx->getTab());
1236  Ndb* pNdb = GETNDB(step);
1237 
1238  NdbRestarter restarter;
1239  restarter.insertErrorInAllNodes(4017);
1240  const Uint32 LOOPS = 10;
1241  for (Uint32 i = 0; i<LOOPS; i++)
1242  {
1243  CHECK(hugoOp1.startTransaction(pNdb) == 0);
1244  CHECK(hugoOp1.pkInsertRecord(pNdb, 1) == 0);
1245 
1246  CHECK(hugoOp2.startTransaction(pNdb) == 0);
1247  CHECK(hugoOp2.pkReadRecord(pNdb, 1, 1) == 0);
1248 
1249  CHECK(hugoOp1.execute_async_prepare(pNdb, NdbTransaction::Commit) == 0);
1250  CHECK(hugoOp2.execute_async_prepare(pNdb, NdbTransaction::Commit) == 0);
1251  hugoOp1.wait_async(pNdb);
1252  hugoOp2.wait_async(pNdb);
1253  CHECK(hugoOp1.closeTransaction(pNdb) == 0);
1254  CHECK(hugoOp2.closeTransaction(pNdb) == 0);
1255  }
1256 
1257  restarter.insertErrorInAllNodes(0);
1258 
1259  return result;
1260 }
1261 
1262 int
1263 runInsertError2(NDBT_Context* ctx, NDBT_Step* step){
1264  int result = NDBT_OK;
1265  HugoOperations hugoOp1(*ctx->getTab());
1266  Ndb* pNdb = GETNDB(step);
1267 
1268  NdbRestarter restarter;
1269  restarter.insertErrorInAllNodes(4017);
1270 
1271  const Uint32 LOOPS = 1;
1272  for (Uint32 i = 0; i<LOOPS; i++)
1273  {
1274  CHECK(hugoOp1.startTransaction(pNdb) == 0);
1275  CHECK(hugoOp1.pkInsertRecord(pNdb, 1) == 0);
1276  CHECK(hugoOp1.pkDeleteRecord(pNdb, 1) == 0);
1277 
1278  hugoOp1.execute_NoCommit(pNdb);
1279  CHECK(hugoOp1.closeTransaction(pNdb) == 0);
1280  }
1281 
1282  restarter.insertErrorInAllNodes(0);
1283  return NDBT_OK;
1284 }
1285 
1286 int
1287 runBug25090(NDBT_Context* ctx, NDBT_Step* step){
1288 
1289  Ndb* pNdb = GETNDB(step);
1290  //NdbDictionary::Dictionary * dict = pNdb->getDictionary();
1291 
1292  HugoOperations ops(*ctx->getTab());
1293 
1294  int loops = ctx->getNumLoops();
1295  //const int rows = ctx->getNumRecords();
1296 
1297  while (loops--)
1298  {
1299  ops.startTransaction(pNdb);
1300  ops.pkReadRecord(pNdb, 1, 1);
1301  ops.execute_Commit(pNdb, AO_IgnoreError);
1302  sleep(10);
1303  ops.closeTransaction(pNdb);
1304  }
1305 
1306  return NDBT_OK;
1307 }
1308 
1309 int
1310 runDeleteRead(NDBT_Context* ctx, NDBT_Step* step){
1311 
1312  Ndb* pNdb = GETNDB(step);
1313 
1314  const NdbDictionary::Table* tab = ctx->getTab();
1315  NDBT_ResultRow row(*ctx->getTab());
1316  HugoTransactions tmp(*ctx->getTab());
1317 
1318  int a;
1319  int loops = ctx->getNumLoops();
1320  //const int rows = ctx->getNumRecords();
1321 
1322  while (loops--)
1323  {
1324  NdbTransaction* pTrans = pNdb->startTransaction();
1325  NdbOperation* pOp = pTrans->getNdbOperation(tab->getName());
1326  pOp->deleteTuple();
1327  tmp.equalForRow(pOp, loops);
1328 
1329  // Define attributes to read
1330  for(a = 0; a<tab->getNoOfColumns(); a++)
1331  {
1332  if((row.attributeStore(a) = pOp->getValue(tab->getColumn(a)->getName())) == 0) {
1333  ERR(pTrans->getNdbError());
1334  return NDBT_FAILED;
1335  }
1336  }
1337 
1338  pTrans->execute(Commit);
1339  pTrans->close();
1340 
1341  pTrans = pNdb->startTransaction();
1342  pOp = pTrans->getNdbOperation(tab->getName());
1343  pOp->insertTuple();
1344  tmp.setValues(pOp, loops, 0);
1345 
1346  pOp = pTrans->getNdbOperation(tab->getName());
1347  pOp->deleteTuple();
1348  tmp.equalForRow(pOp, loops);
1349  for(a = 0; a<tab->getNoOfColumns(); a++)
1350  {
1351  if((row.attributeStore(a) = pOp->getValue(tab->getColumn(a)->getName())) == 0)
1352  {
1353  ERR(pTrans->getNdbError());
1354  return NDBT_FAILED;
1355  }
1356  }
1357  if (pTrans->execute(Commit) != 0)
1358  {
1359  ERR(pTrans->getNdbError());
1360  return NDBT_FAILED;
1361  }
1362 
1363  pTrans->close();
1364  }
1365 
1366  return NDBT_OK;
1367 }
1368 
1369 int
1370 runBug27756(NDBT_Context* ctx, NDBT_Step* step)
1371 {
1372 
1373  Ndb* pNdb = GETNDB(step);
1374  //NdbDictionary::Dictionary * dict = pNdb->getDictionary();
1375 
1376  HugoOperations ops(*ctx->getTab());
1377 
1378  int loops = ctx->getNumLoops();
1379  //const int rows = ctx->getNumRecords();
1380 
1381  Vector<Uint64> copies;
1382  while (loops--)
1383  {
1384  ops.startTransaction(pNdb);
1385  ops.pkInsertRecord(pNdb, 1, 1);
1386  ops.execute_NoCommit(pNdb);
1387 
1388  NdbTransaction* pTrans = ops.getTransaction();
1389  NdbOperation* op = pTrans->getNdbOperation(ctx->getTab()->getName());
1390  op->interpretedUpdateTuple();
1391  ops.equalForRow(op, 1);
1392  NdbRecAttr* attr = op->getValue(NdbDictionary::Column::COPY_ROWID);
1393  ops.execute_NoCommit(pNdb);
1394 
1395  copies.push_back(attr->u_64_value());
1396  ndbout_c("copy at: %llx", copies.back());
1397  ops.execute_NoCommit(pNdb);
1398 
1399  ops.pkDeleteRecord(pNdb, 1, 1);
1400  ops.execute_NoCommit(pNdb);
1401 
1402  if (loops & 1)
1403  {
1404  ops.execute_Rollback(pNdb);
1405  ops.closeTransaction(pNdb);
1406  }
1407  else
1408  {
1409  ops.execute_Commit(pNdb);
1410  ops.closeTransaction(pNdb);
1411  ops.clearTable(pNdb, 100);
1412  }
1413  }
1414 
1415  for (Uint32 i = 0; i<copies.size(); i++)
1416  if (copies[i] != copies.back())
1417  {
1418  ndbout_c("Memleak detected");
1419  return NDBT_FAILED;
1420  }
1421 
1422  return NDBT_OK;
1423 }
1424 
1425 int
1426 runBug28073(NDBT_Context *ctx, NDBT_Step* step)
1427 {
1428  int result = NDBT_OK;
1429  const NdbDictionary::Table *table= ctx->getTab();
1430  HugoOperations hugoOp1(*table);
1431  HugoOperations hugoOp2(*table);
1432  Ndb* pNdb = GETNDB(step);
1433  int loops = ctx->getNumLoops();
1434  bool inserted= false;
1435 
1436  while (loops--)
1437  {
1438  if (!inserted)
1439  {
1440  CHECK(hugoOp1.startTransaction(pNdb) == 0);
1441  CHECK(hugoOp1.pkInsertRecord(pNdb, 1, 1) == 0);
1442  CHECK(hugoOp1.execute_Commit(pNdb) == 0);
1443  CHECK(hugoOp1.closeTransaction(pNdb) == 0);
1444  inserted= 1;
1445  }
1446 
1447  // Use TC hint to hit the same node in both transactions.
1448  Uint32 key_val= 0;
1449  const char *key= (const char *)(&key_val);
1450  CHECK(hugoOp1.startTransaction(pNdb, table, key, 4) == 0);
1451  CHECK(hugoOp2.startTransaction(pNdb, table, key, 4) == 0);
1452 
1453  // First take 2*read lock on the tuple in transaction 1.
1454  for (Uint32 i= 0; i < 2; i++)
1455  {
1456  CHECK(hugoOp1.pkReadRecord(pNdb, 1, 1, NdbOperation::LM_Read) == 0);
1457  CHECK(hugoOp1.pkReadRecord(pNdb, 1, 1, NdbOperation::LM_Read) == 0);
1458  }
1459  CHECK(hugoOp1.execute_NoCommit(pNdb) == 0);
1460 
1461  // Now send ops in two transactions, one batch.
1462  // First 2*read in transaction 2.
1463  for (Uint32 i= 0; i < 2; i++)
1464  {
1465  CHECK(hugoOp2.pkReadRecord(pNdb, 1, 1, NdbOperation::LM_Read) == 0);
1466  CHECK(hugoOp2.pkReadRecord(pNdb, 1, 1, NdbOperation::LM_Read) == 0);
1467  }
1468  CHECK(hugoOp2.execute_async_prepare(pNdb, NdbTransaction::NoCommit) == 0);
1469 
1470  // Second op an update in transaction 1.
1471  CHECK(hugoOp1.pkUpdateRecord(pNdb, 1, 1) == 0);
1472  CHECK(hugoOp1.execute_async_prepare(pNdb, NdbTransaction::Commit) == 0);
1473 
1474  // Transaction 1 will now hang waiting on transaction 2 to commit before it
1475  // can upgrade its read lock to a write lock.
1476  // With the bug, we get a node failure due to watchdog timeout here.
1477  CHECK(hugoOp2.wait_async(pNdb) == 0);
1478 
1479  // Now commit transaction 2, we should see transaction 1 finish with the
1480  // update.
1481  CHECK(hugoOp2.execute_async_prepare(pNdb, NdbTransaction::Commit) == 0);
1482  CHECK(hugoOp2.wait_async(pNdb) == 0);
1483  // No error check, as transaction 1 may have terminated already.
1484  hugoOp1.wait_async(pNdb);
1485 
1486  CHECK(hugoOp1.closeTransaction(pNdb) == 0);
1487  CHECK(hugoOp2.closeTransaction(pNdb) == 0);
1488  }
1489 
1490  return result;
1491 }
1492 
1493 int
1494 runBug20535(NDBT_Context* ctx, NDBT_Step* step)
1495 {
1496  Ndb* pNdb = GETNDB(step);
1497  const NdbDictionary::Table * tab = ctx->getTab();
1498 
1499  bool hasDefault = false;
1500  for (Uint32 i = 0; i<(Uint32)tab->getNoOfColumns(); i++)
1501  {
1502  if (tab->getColumn(i)->getNullable() ||
1503  tab->getColumn(i)->getDefaultValue())
1504  {
1505  hasDefault = true;
1506  break;
1507  }
1508  }
1509 
1510  if (!hasDefault)
1511  return NDBT_OK;
1512 
1513  HugoTransactions hugoTrans(* tab);
1514  hugoTrans.loadTable(pNdb, 1);
1515 
1516  NdbTransaction* pTrans = pNdb->startTransaction();
1517  NdbOperation* pOp = pTrans->getNdbOperation(tab->getName());
1518  pOp->deleteTuple();
1519  hugoTrans.equalForRow(pOp, 0);
1520  if (pTrans->execute(NoCommit) != 0)
1521  return NDBT_FAILED;
1522 
1523  pOp = pTrans->getNdbOperation(tab->getName());
1524  pOp->insertTuple();
1525  hugoTrans.equalForRow(pOp, 0);
1526  for (Uint32 i = 0; i<(Uint32)tab->getNoOfColumns(); i++)
1527  {
1528  if (!tab->getColumn(i)->getPrimaryKey() &&
1529  !tab->getColumn(i)->getNullable() &&
1530  !tab->getColumn(i)->getDefaultValue())
1531  {
1532  hugoTrans.setValueForAttr(pOp, i, 0, 1);
1533  }
1534  }
1535 
1536  if (pTrans->execute(Commit) != 0)
1537  return NDBT_FAILED;
1538 
1539  pTrans->close();
1540 
1541  pTrans = pNdb->startTransaction();
1542  pOp = pTrans->getNdbOperation(tab->getName());
1543  pOp->readTuple();
1544  hugoTrans.equalForRow(pOp, 0);
1545  Vector<NdbRecAttr*> values;
1546  for (Uint32 i = 0; i<(Uint32)tab->getNoOfColumns(); i++)
1547  {
1548  if (!tab->getColumn(i)->getPrimaryKey() &&
1549  (tab->getColumn(i)->getNullable() ||
1550  tab->getColumn(i)->getDefaultValue()))
1551  {
1552  values.push_back(pOp->getValue(i));
1553  }
1554  }
1555 
1556  if (pTrans->execute(Commit) != 0)
1557  return NDBT_FAILED;
1558 
1559  bool defaultOk = true;
1560  for (unsigned int i = 0; i<values.size(); i++)
1561  {
1562  const NdbRecAttr* recAttr = values[i];
1563  const NdbDictionary::Column* col = recAttr->getColumn();
1564  unsigned int defaultLen = 0;
1565  const char* def = (const char*) col->getDefaultValue(&defaultLen);
1566 
1567  if (def)
1568  {
1569  /* Column has a native default, check that it was set */
1570 
1571  if (!recAttr->isNULL())
1572  {
1573  if (memcmp(def, recAttr->aRef(), defaultLen) != 0)
1574  {
1575  defaultOk = false;
1576  ndbout_c("column %s does not have correct default value",
1577  recAttr->getColumn()->getName());
1578  }
1579  }
1580  else
1581  {
1582  defaultOk = false;
1583  ndbout_c("column %s is null, should have default value",
1584  recAttr->getColumn()->getName());
1585  }
1586  }
1587  else
1588  {
1589  /* Column has Null as its default */
1590  if (!recAttr->isNULL())
1591  {
1592  defaultOk = false;
1593  ndbout_c("column %s is not NULL", recAttr->getColumn()->getName());
1594  }
1595  }
1596  }
1597 
1598  pTrans->close();
1599 
1600  if (defaultOk)
1601  return NDBT_OK;
1602  else
1603  return NDBT_FAILED;
1604 }
1605 
1606 
1607 int
1608 runDDInsertFailUpdateBatch(NDBT_Context* ctx, NDBT_Step* step)
1609 {
1610  Ndb* pNdb = GETNDB(step);
1611  NdbRestarter restarter;
1612 
1613  const NdbDictionary::Table * tab = ctx->getTab();
1614 
1615  int errCode = 0;
1616  int expectedError = 0;
1617  {
1618  bool tabHasDD = false;
1619  for(int i = 0; i<tab->getNoOfColumns(); i++)
1620  {
1621  tabHasDD |= (tab->getColumn(i)->getStorageType() ==
1622  NdbDictionary::Column::StorageTypeDisk);
1623  }
1624 
1625  if (tabHasDD)
1626  {
1627  errCode = 4021;
1628  expectedError = 1601;
1629  }
1630  else
1631  {
1633  pNdb->getDictionary()->listIndexes(l, tab->getName());
1634  for (Uint32 i = 0; i<l.count; i++)
1635  {
1636  if (DictTabInfo::isOrderedIndex(l.elements[i].type))
1637  {
1638  errCode = 4023;
1639  expectedError = 9999;
1640  break;
1641  }
1642  }
1643  }
1644 
1645  if (errCode == 0)
1646  {
1647  ndbout_c("Table %s has no disk attributes or ordered indexes, skipping",
1648  tab->getName());
1649  return NDBT_OK;
1650  }
1651  }
1652 
1653  HugoOperations hugoOps(*ctx->getTab());
1654 
1655  int result = NDBT_OK;
1656 
1657  for (Uint32 loop = 0; loop < 100; loop ++)
1658  {
1659  restarter.insertErrorInAllNodes(errCode);
1660  CHECK(hugoOps.startTransaction(pNdb) == 0);
1661 
1662  /* Create batch with insert op (which will fail due to disk allocation issue)
1663  * followed by update op on same pk
1664  * Transaction will abort due to insert failure, and reason should be
1665  * disk space exhaustion, not any issue with the update.
1666  */
1667  CHECK(hugoOps.pkInsertRecord(pNdb, loop, 1, 0) == 0);
1668 
1669  /* Add up to 16 updates after the insert */
1670  Uint32 numUpdates = 1 + (loop % 15);
1671  for (Uint32 updateCnt = 0; updateCnt < numUpdates; updateCnt++)
1672  CHECK(hugoOps.pkUpdateRecord(pNdb, loop, 1, 1+updateCnt) == 0);
1673 
1674  CHECK(hugoOps.execute_Commit(pNdb) != 0); /* Expect failure */
1675 
1676  NdbError err= hugoOps.getTransaction()->getNdbError();
1677 
1678  CHECK(err.code == expectedError);
1679 
1680  hugoOps.closeTransaction(pNdb);
1681  }
1682 
1683  restarter.insertErrorInAllNodes(0);
1684 
1685  return result;
1686 }
1687 
1688 // Bug34348
1689 
1690 #define chk1(b) \
1691  if (!(b)) { g_err << "ERR: " << step->getName() << " failed on line " << __LINE__ << endl; result = NDBT_FAILED; continue; }
1692 #define chk2(b, e) \
1693  if (!(b)) { g_err << "ERR: " << step->getName() << " failed on line " << __LINE__ << ": " << e << endl; result = NDBT_FAILED; continue; }
1694 
1695 const char* tabname_bug34348 = "TBug34348";
1696 
1697 int
1698 runBug34348insert(NDBT_Context* ctx, NDBT_Step* step,
1699  HugoOperations& ops, int i, bool* rangeFull)
1700 {
1701  const int rangeFullError = 633;
1702  Ndb* pNdb = GETNDB(step);
1703  int result = NDBT_OK;
1704  while (result == NDBT_OK)
1705  {
1706  int code = 0;
1707  chk2(ops.startTransaction(pNdb) == 0, ops.getNdbError());
1708  chk2(ops.pkInsertRecord(pNdb, i, 1) == 0, ops.getNdbError());
1709  chk2(ops.execute_Commit(pNdb) == 0 || (code = ops.getNdbError().code) == rangeFullError, ops.getNdbError());
1710  ops.closeTransaction(pNdb);
1711  *rangeFull = (code == rangeFullError);
1712  break;
1713  }
1714  return result;
1715 }
1716 
1717 int
1718 runBug34348delete(NDBT_Context* ctx, NDBT_Step* step,
1719  HugoOperations& ops, int i)
1720 {
1721  Ndb* pNdb = GETNDB(step);
1722  int result = NDBT_OK;
1723  while (result == NDBT_OK)
1724  {
1725  chk2(ops.startTransaction(pNdb) == 0, ops.getNdbError());
1726  chk2(ops.pkDeleteRecord(pNdb, i, 1) == 0, ops.getNdbError());
1727  chk2(ops.execute_Commit(pNdb) == 0, ops.getNdbError());
1728  ops.closeTransaction(pNdb);
1729  break;
1730  }
1731  return result;
1732 }
1733 
1734 int
1735 runBug34348(NDBT_Context* ctx, NDBT_Step* step)
1736 {
1737  myRandom48Init((long)NdbTick_CurrentMillisecond());
1738  Ndb* pNdb = GETNDB(step);
1739  NdbDictionary::Dictionary* pDict = pNdb->getDictionary();
1740  NdbRestarter restarter;
1741  int result = NDBT_OK;
1742  const int loops = ctx->getNumLoops();
1743  const int errInsDBACC = 3002;
1744  const int errInsCLEAR = 0;
1745  Uint32* rowmask = 0;
1746 
1747  while (result == NDBT_OK)
1748  {
1749  chk1(restarter.insertErrorInAllNodes(errInsDBACC) == 0);
1750  ndbout << "error insert " << errInsDBACC << " done" << endl;
1751 
1752  const NdbDictionary::Table* pTab = 0;
1753  while (result == NDBT_OK)
1754  {
1755  (void)pDict->dropTable(tabname_bug34348);
1756  NdbDictionary::Table tab(tabname_bug34348);
1757  {
1758  NdbDictionary::Column col("a");
1760  col.setPrimaryKey(true);
1761  tab.addColumn(col);
1762  }
1763  {
1764  NdbDictionary::Column col("b");
1766  col.setNullable(false);
1767  tab.addColumn(col);
1768  }
1769  chk2(pDict->createTable(tab) == 0, pDict->getNdbError());
1770  chk2((pTab = pDict->getTable(tabname_bug34348)) != 0, pDict->getNdbError());
1771  break;
1772  }
1773 
1774  HugoOperations ops(*pTab);
1775  ops.setQuiet();
1776 
1777  int rowmaxprev = 0;
1778  int loop = 0;
1779  while (result == NDBT_OK && loop < loops)
1780  {
1781  ndbout << "loop:" << loop << endl;
1782  int rowcnt = 0;
1783 
1784  // fill up
1785  while (result == NDBT_OK)
1786  {
1787  bool rangeFull;
1788  chk1(runBug34348insert(ctx, step, ops, rowcnt, &rangeFull) == NDBT_OK);
1789  if (rangeFull)
1790  {
1791  // 360449 (1 fragment)
1792  ndbout << "dir range full at " << rowcnt << endl;
1793  break;
1794  }
1795  rowcnt++;
1796  }
1797  chk1(result == NDBT_OK);
1798  const int rowmax = rowcnt;
1799 
1800  if (loop == 0)
1801  rowmaxprev = rowmax;
1802  else
1803  chk2(rowmaxprev == rowmax, "rowmaxprev:" << rowmaxprev << " rowmax:" << rowmax);
1804 
1805  const int sz = (rowmax + 31) / 32;
1806  delete [] rowmask;
1807  rowmask = new Uint32 [sz];
1808  BitmaskImpl::clear(sz, rowmask);
1809  {
1810  int i;
1811  for (i = 0; i < rowmax; i++)
1812  BitmaskImpl::set(sz, rowmask, i);
1813  }
1814 
1815  // random delete until insert succeeds
1816  while (result == NDBT_OK)
1817  {
1818  int i = myRandom48(rowmax);
1819  if (!BitmaskImpl::get(sz, rowmask, i))
1820  continue;
1821  chk1(runBug34348delete(ctx, step, ops, i) == NDBT_OK);
1822  BitmaskImpl::clear(sz, rowmask, i);
1823  rowcnt--;
1824  bool rangeFull;
1825  chk1(runBug34348insert(ctx, step, ops, rowmax, &rangeFull) == NDBT_OK);
1826  if (!rangeFull)
1827  {
1828  chk1(runBug34348delete(ctx, step, ops, rowmax) == NDBT_OK);
1829  // 344063 (1 fragment)
1830  ndbout << "dir range released at " << rowcnt << endl;
1831  break;
1832  }
1833  }
1834  chk1(result == NDBT_OK);
1835  assert(BitmaskImpl::count(sz, rowmask)== (Uint32)rowcnt);
1836 
1837  // delete about 1/2 remaining
1838  while (result == NDBT_OK)
1839  {
1840  int i;
1841  for (i = 0; result == NDBT_OK && i < rowmax; i++)
1842  {
1843  if (!BitmaskImpl::get(sz, rowmask, i))
1844  continue;
1845  if (myRandom48(100) < 50)
1846  continue;
1847  chk1(runBug34348delete(ctx, step, ops, i) == NDBT_OK);
1848  BitmaskImpl::clear(sz, rowmask, i);
1849  rowcnt--;
1850  }
1851  ndbout << "deleted down to " << rowcnt << endl;
1852  break;
1853  }
1854  chk1(result == NDBT_OK);
1855  assert(BitmaskImpl::count(sz, rowmask)== (Uint32)rowcnt);
1856 
1857  // insert until full again
1858  while (result == NDBT_OK)
1859  {
1860  int i;
1861  for (i = 0; result == NDBT_OK && i < rowmax; i++)
1862  {
1863  if (BitmaskImpl::get(sz, rowmask, i))
1864  continue;
1865  bool rangeFull;
1866  chk1(runBug34348insert(ctx, step, ops, i, &rangeFull) == NDBT_OK);
1867  // assume all can be inserted back
1868  chk2(!rangeFull, "dir range full too early at " << rowcnt);
1869  BitmaskImpl::set(sz, rowmask, i);
1870  rowcnt++;
1871  }
1872  chk1(result == NDBT_OK);
1873  ndbout << "inserted all back to " << rowcnt << endl;
1874  break;
1875  }
1876  chk1(result == NDBT_OK);
1877  assert(BitmaskImpl::count(sz, rowmask)== (Uint32)rowcnt);
1878 
1879  // delete all
1880  while (result == NDBT_OK)
1881  {
1882  int i;
1883  for (i = 0; result == NDBT_OK && i < rowmax; i++)
1884  {
1885  if (!BitmaskImpl::get(sz, rowmask, i))
1886  continue;
1887  chk1(runBug34348delete(ctx, step, ops, i) == NDBT_OK);
1888  BitmaskImpl::clear(sz, rowmask, i);
1889  rowcnt--;
1890  }
1891  ndbout << "deleted all" << endl;
1892  break;
1893  }
1894  chk1(result == NDBT_OK);
1895  assert(BitmaskImpl::count(sz, rowmask)== (Uint32)rowcnt);
1896  assert(rowcnt == 0);
1897 
1898  loop++;
1899  }
1900 
1901  chk2(pDict->dropTable(tabname_bug34348) == 0, pDict->getNdbError());
1902 
1903  chk1(restarter.insertErrorInAllNodes(errInsCLEAR) == 0);
1904  ndbout << "error insert clear done" << endl;
1905  break;
1906  }
1907 
1908  if (result != NDBT_OK && restarter.insertErrorInAllNodes(errInsCLEAR) != 0)
1909  g_err << "error insert clear failed" << endl;
1910 
1911  delete [] rowmask;
1912  rowmask = 0;
1913  return result;
1914 }
1915 
1916 #define check(b, e) \
1917  if (!(b)) { g_err << "ERR: " << step->getName() << " failed on line " << __LINE__ << ": " << e.getNdbError() << endl; return NDBT_FAILED; }
1918 
1919 int runUnlocker(NDBT_Context* ctx, NDBT_Step* step){
1920  int loops = ctx->getNumLoops();
1921  int records = ctx->getNumRecords();
1922  int batchSize = ctx->getProperty("Batchsize", 1);
1923  int doubleUnlock = ctx->getProperty("DoubleUnlock", (Uint32)0);
1924  int lm = ctx->getProperty("LockMode", NdbOperation::LM_Read);
1925  int i = 0;
1926  HugoOperations hugoOps(*ctx->getTab());
1927  Ndb* ndb = GETNDB(step);
1928 
1929  g_err << "Unlocker : ";
1930  g_err << "Loops = " << loops << " Records = " << records << " Batchsize = "
1931  << batchSize << endl;
1932 
1933  while(i++ < loops)
1934  {
1935  g_err << i << " ";
1936 
1937  check(hugoOps.startTransaction(ndb) == 0, (*ndb));
1938 
1939  const int maxRetries = 10;
1940  int retryAttempt = 0;
1941  int r = records;
1942  Vector<const NdbLockHandle*> lockHandles;
1943 
1944  while(r > 0)
1945  {
1946  int batchContents = MIN(r, batchSize);
1947 
1948  check(hugoOps.pkReadRecordLockHandle(ndb,
1949  lockHandles,
1950  records - r,
1951  batchContents,
1952  (NdbOperation::LockMode)lm) == 0,
1953  hugoOps);
1954 
1955  r-= batchContents;
1956 
1957  if (hugoOps.execute_NoCommit(ndb) != 0)
1958  {
1959  NdbError err = hugoOps.getNdbError();
1960  if ((err.status == NdbError::TemporaryError) &&
1961  retryAttempt < maxRetries){
1962  ERR(err);
1963  NdbSleep_MilliSleep(50);
1964  retryAttempt++;
1965  lockHandles.clear();
1966  check(hugoOps.closeTransaction(ndb) == 0,
1967  hugoOps);
1968  check(hugoOps.startTransaction(ndb) == 0, (*ndb));
1969  continue;
1970  }
1971  ERR(err);
1972  return NDBT_FAILED;
1973  }
1974 
1975  check(hugoOps.pkUnlockRecord(ndb,
1976  lockHandles) == 0,
1977  hugoOps);
1978 
1979  check(hugoOps.execute_NoCommit(ndb) == 0,
1980  hugoOps);
1981 
1982  if (doubleUnlock)
1983  {
1985  switch(rand() % 2)
1986  {
1987  case 0:
1989  break;
1990  case 1:
1991  default:
1993  break;
1994  }
1995 
1996  g_err << "Double unlock, abort option is "
1997  << ao << endl;
1998 
1999  /* Failure scenario */
2000  check(hugoOps.pkUnlockRecord(ndb,
2001  lockHandles,
2002  0, // offset
2003  ~(0), // NumRecords
2004  ao) == 0,
2005  hugoOps);
2006 
2007  check(hugoOps.execute_NoCommit(ndb,
2008  DefaultAbortOption) != 0,
2009  hugoOps);
2010 
2011  /* 417 = Bad operation reference */
2012  check(hugoOps.getNdbError().code == 417,
2013  hugoOps);
2014 
2015 
2016  if (ao == NdbOperation::AbortOnError)
2017  {
2018  /* Restart transaction and continue with next loop iteration */
2019  r = 0;
2020  lockHandles.clear();
2021  check(hugoOps.closeTransaction(ndb) == 0,
2022  hugoOps);
2023  check(hugoOps.startTransaction(ndb) == 0, (*ndb));
2024 
2025  continue;
2026  }
2027  /* Otherwise, IgnoreError, so let's attempt to
2028  * continue
2029  */
2030  }
2031 
2032  check(hugoOps.releaseLockHandles(ndb,
2033  lockHandles) == 0,
2034  hugoOps);
2035 
2036  lockHandles.clear();
2037  }
2038 
2039  switch(rand() % 3)
2040  {
2041  case 0:
2042  check(hugoOps.execute_Commit(ndb) == 0,
2043  hugoOps);
2044  break;
2045  case 1:
2046  check(hugoOps.execute_Rollback(ndb) == 0,
2047  hugoOps);
2048  break;
2049  default:
2050  /* Do nothing, just close */
2051  break;
2052  }
2053 
2054  check(hugoOps.closeTransaction(ndb) == 0,
2055  hugoOps);
2056 
2057  }
2058 
2059  g_err << endl;
2060 
2061  return NDBT_OK;
2062 }
2063 
2064 template class Vector<NdbRecAttr*>;
2065 
2066 int
2067 runBug54986(NDBT_Context* ctx, NDBT_Step* step)
2068 {
2069  NdbRestarter restarter;
2070  Ndb* pNdb = GETNDB(step);
2071  NdbDictionary::Dictionary* pDict = pNdb->getDictionary();
2072  const NdbDictionary::Table * pTab = ctx->getTab();
2073  NdbDictionary::Table copy = *pTab;
2074 
2075  BaseString name;
2076  name.assfmt("%s_COPY", copy.getName());
2077  copy.setName(name.c_str());
2078  pDict->createTable(copy);
2079  const NdbDictionary::Table * copyTab = pDict->getTable(copy.getName());
2080 
2081  HugoTransactions hugoTrans(*pTab);
2082  hugoTrans.loadTable(pNdb, 20);
2083  hugoTrans.clearTable(pNdb);
2084 
2085  const Uint32 rows = 5000;
2086 
2087  HugoTransactions hugoTransCopy(*copyTab);
2088  hugoTransCopy.loadTable(pNdb, rows);
2089 
2090  {
2091  restarter.getNumDbNodes(); // connect
2092  int filter[] = { 15, NDB_MGM_EVENT_CATEGORY_CHECKPOINT, 0 };
2093  NdbLogEventHandle handle =
2094  ndb_mgm_create_logevent_handle(restarter.handle, filter);
2095  for (Uint32 i = 0; i<3; i++)
2096  {
2097  int dump[] = { DumpStateOrd::DihStartLcpImmediately };
2098 
2099  struct ndb_logevent event;
2100 
2101  restarter.dumpStateAllNodes(dump, 1);
2102  while(ndb_logevent_get_next(handle, &event, 0) >= 0 &&
2104  while(ndb_logevent_get_next(handle, &event, 0) >= 0 &&
2106  }
2107  ndb_mgm_destroy_logevent_handle(&handle);
2108  }
2109 
2110  for (int i = 0; i<5; i++)
2111  {
2112  int val1 = DumpStateOrd::DihMaxTimeBetweenLCP;
2113  int val2 = 7099; // Force start
2114 
2115  restarter.dumpStateAllNodes(&val1, 1);
2116  int val[] = { DumpStateOrd::CmvmiSetRestartOnErrorInsert, 1 };
2117  restarter.dumpStateAllNodes(val, 2);
2118 
2119  restarter.insertErrorInAllNodes(932); // prevent arbit shutdown
2120 
2121  HugoTransactions hugoTrans(*pTab);
2122  hugoTrans.loadTable(pNdb, 20);
2123 
2124  restarter.dumpStateAllNodes(&val2, 1);
2125 
2126  NdbSleep_SecSleep(15);
2127  hugoTrans.clearTable(pNdb);
2128 
2129  hugoTransCopy.pkReadRecords(pNdb, rows);
2130 
2131  HugoOperations hugoOps(*pTab);
2132  hugoOps.startTransaction(pNdb);
2133  hugoOps.pkInsertRecord(pNdb, 1);
2134  hugoOps.execute_NoCommit(pNdb);
2135 
2136  restarter.insertErrorInAllNodes(5056);
2137  restarter.dumpStateAllNodes(&val2, 1);
2138  restarter.waitClusterNoStart();
2139  int vall = 11009;
2140  restarter.dumpStateAllNodes(&vall, 1);
2141  restarter.startAll();
2142  restarter.waitClusterStarted();
2143  }
2144 
2145  pDict->dropTable(copy.getName());
2146 
2147  // remove 25-page pgman
2148  restarter.restartAll(false, true, true);
2149  restarter.waitClusterNoStart();
2150  restarter.startAll();
2151  restarter.waitClusterStarted();
2152  return NDBT_OK;
2153 }
2154 
2155 int
2156 runBug54944(NDBT_Context* ctx, NDBT_Step* step)
2157 {
2158  Ndb* pNdb = GETNDB(step);
2159  const NdbDictionary::Table * pTab = ctx->getTab();
2160  NdbRestarter res;
2161 
2162  for (Uint32 i = 0; i<5; i++)
2163  {
2164  Uint32 rows = 5000 + i * 2000;
2165  HugoOperations hugoOps(*pTab);
2166  hugoOps.startTransaction(pNdb);
2167 
2168  for (Uint32 r = 0; r < rows; r++)
2169  {
2170  for (Uint32 b = 0; b<100; b++, r++)
2171  {
2172  hugoOps.pkInsertRecord(pNdb, r);
2173  }
2174  hugoOps.execute_NoCommit(pNdb);
2175  }
2176 
2177  res.insertErrorInAllNodes(8087);
2178 
2179  HugoTransactions hugoTrans(*pTab);
2180  hugoTrans.loadTableStartFrom(pNdb, 50000, 100);
2181 
2182  hugoOps.execute_Rollback(pNdb);
2183  hugoTrans.clearTable(pNdb);
2184 
2185  res.insertErrorInAllNodes(0);
2186  }
2187  return NDBT_OK;
2188 }
2189 
2190 int
2191 runBug59496_scan(NDBT_Context* ctx, NDBT_Step* step)
2192 {
2193  Ndb* pNdb = GETNDB(step);
2194  const NdbDictionary::Table * pTab = ctx->getTab();
2195  NdbRestarter res;
2196  int rowcount = ctx->getProperty("CHECK_ROWCOUNT", Uint32(0));
2197  int records = ctx->getNumRecords();
2198  if (rowcount == 0)
2199  records = 0;
2200 
2201  HugoTransactions hugoTrans(*pTab);
2202  while (!ctx->isTestStopped())
2203  {
2204  if (hugoTrans.scanReadRecords(pNdb,
2205  records, 0, 0,
2207  (int)NdbScanOperation::SF_TupScan) != NDBT_OK)
2208  return NDBT_FAILED;
2209  }
2210  return NDBT_OK;
2211 }
2212 
2213 int
2214 runBug59496_case1(NDBT_Context* ctx, NDBT_Step* step)
2215 {
2216  Ndb* pNdb = GETNDB(step);
2217  NdbRestarter res;
2218 
2219  int loops = ctx->getNumLoops();
2220  int records = ctx->getNumRecords();
2221 
2222  HugoOperations hugoOps(*ctx->getTab());
2223  for (int i = 0; i < loops; i++)
2224  {
2225  hugoOps.startTransaction(pNdb);
2226  hugoOps.pkInsertRecord(pNdb, 0, records, 0);
2227  hugoOps.execute_NoCommit(pNdb);
2228  hugoOps.pkUpdateRecord(pNdb, 0, records, rand());
2229  hugoOps.execute_NoCommit(pNdb);
2230  hugoOps.pkUpdateRecord(pNdb, 0, records, rand());
2231  hugoOps.execute_NoCommit(pNdb);
2232  res.insertErrorInAllNodes(8089);
2233  hugoOps.execute_Commit(pNdb);
2234  res.insertErrorInAllNodes(0);
2235  hugoOps.closeTransaction(pNdb);
2236  hugoOps.clearTable(pNdb);
2237  }
2238  ctx->stopTest();
2239  return NDBT_OK;
2240 }
2241 
2242 int
2243 runBug59496_case2(NDBT_Context* ctx, NDBT_Step* step)
2244 {
2245  Ndb* pNdb = GETNDB(step);
2246  NdbRestarter res;
2247 
2248  int loops = ctx->getNumLoops();
2249  int records = ctx->getNumRecords();
2250 
2251  HugoOperations hugoOps(*ctx->getTab());
2252  for (int i = 0; i < loops; i++)
2253  {
2254  hugoOps.startTransaction(pNdb);
2255  hugoOps.pkDeleteRecord(pNdb, 0, records);
2256  hugoOps.execute_NoCommit(pNdb);
2257  hugoOps.pkInsertRecord(pNdb, 0, records, 0);
2258  hugoOps.execute_NoCommit(pNdb);
2259 
2260  res.insertErrorInAllNodes(8089);
2261  hugoOps.execute_Rollback(pNdb);
2262  res.insertErrorInAllNodes(0);
2263 
2264  hugoOps.closeTransaction(pNdb);
2265  }
2266  ctx->stopTest();
2267  return NDBT_OK;
2268 }
2269 
2270 #define CHK_RET_FAILED(x) if (!(x)) { ndbout_c("Failed on line: %u", __LINE__); return NDBT_FAILED; }
2271 
2272 int
2273 runTest899(NDBT_Context* ctx, NDBT_Step* step)
2274 {
2275  Ndb* pNdb = GETNDB(step);
2276  const NdbDictionary::Table* pTab = ctx->getTab();
2277 
2278  const int rows = ctx->getNumRecords();
2279  const int loops = ctx->getNumLoops();
2280  const int batch = ctx->getProperty("Batch", Uint32(50));
2281  const int until_stopped = ctx->getProperty("UntilStopped");
2282 
2283  const NdbRecord * pRowRecord = pTab->getDefaultRecord();
2284  CHK_RET_FAILED(pRowRecord != 0);
2285 
2286  const Uint32 len = NdbDictionary::getRecordRowLength(pRowRecord);
2287  Uint8 * pRow = new Uint8[len];
2288 
2289  int count_ok = 0;
2290  int count_failed = 0;
2291  int count_899 = 0;
2292  for (int i = 0; i < loops || (until_stopped && !ctx->isTestStopped()); i++)
2293  {
2294  ndbout_c("loop: %d",i);
2295  int result = 0;
2296  for (int rowNo = 0; rowNo < rows;)
2297  {
2298  NdbTransaction* pTrans = pNdb->startTransaction();
2299  CHK_RET_FAILED(pTrans != 0);
2300 
2301  for (int b = 0; rowNo < rows && b < batch; rowNo++, b++)
2302  {
2303  bzero(pRow, len);
2304 
2305  HugoCalculator calc(* pTab);
2306 
2308  bzero(&opts, sizeof(opts));
2309 
2310  const NdbOperation* pOp = 0;
2311  switch(i % 2){
2312  case 0:
2313  calc.setValues(pRow, pRowRecord, rowNo, rand());
2314  pOp = pTrans->writeTuple(pRowRecord, (char*)pRow,
2315  pRowRecord, (char*)pRow,
2316  0,
2317  &opts,
2318  sizeof(opts));
2319  result = pTrans->execute(NoCommit);
2320  break;
2321  case 1:
2322  calc.setValues(pRow, pRowRecord, rowNo, rand());
2323  pOp = pTrans->deleteTuple(pRowRecord, (char*)pRow,
2324  pRowRecord, (char*)pRow,
2325  0,
2326  &opts,
2327  sizeof(opts));
2328  result = pTrans->execute(NoCommit, AO_IgnoreError);
2329  break;
2330  }
2331 
2332  CHK_RET_FAILED(pOp != 0);
2333 
2334  if (result != 0)
2335  {
2336  goto found_error;
2337  }
2338  }
2339  result = pTrans->execute(Commit);
2340 
2341  if (result != 0)
2342  {
2343  found_error:
2344  count_failed++;
2345  NdbError err = pTrans->getNdbError();
2346  if (! (err.status == NdbError::TemporaryError ||
2349  {
2350  ndbout << err << endl;
2351  }
2352  CHK_RET_FAILED(err.status == NdbError::TemporaryError ||
2355  if (err.code == 899)
2356  {
2357  count_899++;
2358  ndbout << err << endl;
2359  }
2360  }
2361  else
2362  {
2363  count_ok++;
2364  }
2365  pTrans->close();
2366  }
2367  }
2368 
2369  ndbout_c("count_ok: %d count_failed: %d (899: %d)",
2370  count_ok, count_failed, count_899);
2371  delete [] pRow;
2372 
2373  return count_899 == 0 ? NDBT_OK : NDBT_FAILED;
2374 }
2375 
2376 int
2377 runInit899(NDBT_Context* ctx, NDBT_Step* step)
2378 {
2379  NdbRestarter restarter;
2380  int val = DumpStateOrd::DihMinTimeBetweenLCP;
2381  restarter.dumpStateAllNodes(&val, 1);
2382 
2383  Ndb* pNdb = GETNDB(step);
2384  const NdbDictionary::Table* pTab = ctx->getTab();
2385  const NdbDictionary::Table * pTab2 = pNdb->getDictionary()->
2386  getTable(pTab->getName());
2387 
2388  int tableId = pTab2->getObjectId();
2389  int val2[] = { DumpStateOrd::BackupErrorInsert, 10042, tableId };
2390 
2391  for (int i = 0; i < restarter.getNumDbNodes(); i++)
2392  {
2393  if (i & 1)
2394  {
2395  int nodeId = restarter.getDbNodeId(i);
2396  ndbout_c("Setting slow LCP of table %d on node %d",
2397  tableId, nodeId);
2398  restarter.dumpStateOneNode(nodeId, val2, 3);
2399  }
2400  }
2401 
2402  return NDBT_OK;
2403 }
2404 
2405 int
2406 runEnd899(NDBT_Context* ctx, NDBT_Step* step)
2407 {
2408  // reset LCP speed
2409  NdbRestarter restarter;
2410  int val[] = { DumpStateOrd::DihMinTimeBetweenLCP, 0 };
2411  restarter.dumpStateAllNodes(val, 2);
2412 
2413  restarter.insertErrorInAllNodes(0);
2414  return NDBT_OK;
2415 }
2416 
2417 
2418 int initSubscription(NDBT_Context* ctx, NDBT_Step* step){
2419  /* Subscribe to events on the table, and put access
2420  * to the subscription somewhere handy
2421  */
2422  Ndb* pNdb = GETNDB(step);
2423  const NdbDictionary::Table& tab = *ctx->getTab();
2424  bool merge_events = false;
2425  bool report = false;
2426 
2427  char eventName[1024];
2428  sprintf(eventName,"%s_EVENT",tab.getName());
2429 
2430  NdbDictionary::Dictionary *myDict = pNdb->getDictionary();
2431 
2432  if (!myDict) {
2433  g_err << "Dictionary not found "
2434  << pNdb->getNdbError().code << " "
2435  << pNdb->getNdbError().message << endl;
2436  return NDBT_FAILED;
2437  }
2438 
2439  myDict->dropEvent(eventName);
2440 
2441  NdbDictionary::Event myEvent(eventName);
2442  myEvent.setTable(tab.getName());
2443  myEvent.addTableEvent(NdbDictionary::Event::TE_ALL);
2444  for(int a = 0; a < tab.getNoOfColumns(); a++){
2445  myEvent.addEventColumn(a);
2446  }
2447  myEvent.mergeEvents(merge_events);
2448 
2449  if (report)
2450  myEvent.setReport(NdbDictionary::Event::ER_SUBSCRIBE);
2451 
2452  int res = myDict->createEvent(myEvent); // Add event to database
2453 
2454  if (res == 0)
2455  myEvent.print();
2456  else if (myDict->getNdbError().classification ==
2458  {
2459  g_info << "Event creation failed event exists\n";
2460  res = myDict->dropEvent(eventName);
2461  if (res) {
2462  g_err << "Failed to drop event: "
2463  << myDict->getNdbError().code << " : "
2464  << myDict->getNdbError().message << endl;
2465  return NDBT_FAILED;
2466  }
2467  // try again
2468  res = myDict->createEvent(myEvent); // Add event to database
2469  if (res) {
2470  g_err << "Failed to create event (1): "
2471  << myDict->getNdbError().code << " : "
2472  << myDict->getNdbError().message << endl;
2473  return NDBT_FAILED;
2474  }
2475  }
2476  else
2477  {
2478  g_err << "Failed to create event (2): "
2479  << myDict->getNdbError().code << " : "
2480  << myDict->getNdbError().message << endl;
2481  return NDBT_FAILED;
2482  }
2483 
2484  return NDBT_OK;
2485 }
2486 
2487 int removeSubscription(NDBT_Context* ctx, NDBT_Step* step){
2488  /* Remove subscription created above */
2489  Ndb* pNdb = GETNDB(step);
2490  const NdbDictionary::Table& tab = *ctx->getTab();
2491 
2492  char eventName[1024];
2493  sprintf(eventName,"%s_EVENT",tab.getName());
2494 
2495  NdbDictionary::Dictionary *myDict = pNdb->getDictionary();
2496 
2497  if (!myDict) {
2498  g_err << "Dictionary not found "
2499  << pNdb->getNdbError().code << " "
2500  << pNdb->getNdbError().message << endl;
2501  return NDBT_FAILED;
2502  }
2503 
2504  myDict->dropEvent(eventName);
2505 
2506  return NDBT_OK;
2507 }
2508 
2509 int runVerifyRowCount(NDBT_Context* ctx, NDBT_Step* step)
2510 {
2511  Ndb* ndb = GETNDB(step);
2512 
2513  /* Check that number of results returned by a normal scan
2514  * and per-fragment rowcount sum are equal
2515  */
2516  Uint32 rowCountSum = 0;
2517  Uint32 rowScanCount = 0;
2518 
2519  int result = NDBT_OK;
2520  do
2521  {
2522  NdbTransaction* trans = ndb->startTransaction();
2523  CHECK(trans != NULL);
2524 
2525  NdbScanOperation* scan = trans->getNdbScanOperation(ctx->getTab());
2526  CHECK(scan != NULL);
2527 
2529 
2530  NdbInterpretedCode code;
2531 
2532  CHECK(code.interpret_exit_last_row() == 0);
2533  CHECK(code.finalise() == 0);
2534 
2535  NdbRecAttr* rowCountRA = scan->getValue(NdbDictionary::Column::ROW_COUNT);
2536  CHECK(rowCountRA != NULL);
2537  CHECK(scan->setInterpretedCode(&code) == 0);
2538 
2539  CHECK(trans->execute(NoCommit) == 0);
2540 
2541  while (scan->nextResult() == 0)
2542  rowCountSum+= rowCountRA->u_32_value();
2543 
2544  trans->close();
2545 
2546  trans = ndb->startTransaction();
2547  CHECK(trans != NULL);
2548 
2549  scan = trans->getNdbScanOperation(ctx->getTab());
2550  CHECK(scan != NULL);
2551 
2553 
2554  rowCountRA = scan->getValue(NdbDictionary::Column::ROW_COUNT);
2555  CHECK(rowCountRA != NULL);
2556 
2557  CHECK(trans->execute(NoCommit) == 0);
2558 
2559  while (scan->nextResult() == 0)
2560  rowScanCount++;
2561 
2562  trans->close();
2563  }
2564  while(0);
2565 
2566  if (result == NDBT_OK)
2567  {
2568  ndbout_c("Sum of fragment row counts : %u Number rows scanned : %u",
2569  rowCountSum,
2570  rowScanCount);
2571 
2572  if (rowCountSum != rowScanCount)
2573  {
2574  ndbout_c("MISMATCH");
2575  result = NDBT_FAILED;
2576  }
2577  }
2578 
2579  return result;
2580 }
2581 
2582 enum ApiEventType { Insert, Update, Delete };
2583 
2584 template class Vector<ApiEventType>;
2585 
2587 {
2588  ApiEventType type;
2589  int id;
2590  Uint64 gci;
2591 };
2592 template class Vector<EventInfo>;
2593 
2594 int collectEvents(Ndb* ndb,
2595  HugoCalculator& calc,
2596  const NdbDictionary::Table& tab,
2597  Vector<EventInfo>& receivedEvents,
2598  int idCol,
2599  int updateCol,
2600  Vector<NdbRecAttr*>* beforeAttrs,
2601  Vector<NdbRecAttr*>* afterAttrs)
2602 {
2603  int MaxTimeouts = 5;
2604  while (true)
2605  {
2606  int res = ndb->pollEvents(1000);
2607 
2608  if (res > 0)
2609  {
2610  NdbEventOperation* pOp;
2611  while ((pOp = ndb->nextEvent()))
2612  {
2613  bool isDelete = (pOp->getEventType() == NdbDictionary::Event::TE_DELETE);
2614  Vector<NdbRecAttr*>* whichVersion =
2615  isDelete?
2616  beforeAttrs :
2617  afterAttrs;
2618  int id = (*whichVersion)[idCol]->u_32_value();
2619  Uint64 gci = pOp->getGCI();
2620  Uint32 anyValue = pOp->getAnyValue();
2621  Uint32 scenario = ((anyValue >> 24) & 0xff) -1;
2622  Uint32 optype = ((anyValue >> 16) & 0xff);
2623  Uint32 recNum = (anyValue & 0xffff);
2624 
2625  g_err << "# " << receivedEvents.size()
2626  << " GCI : " << (gci >> 32)
2627  << "/"
2628  << (gci & 0xffffffff)
2629  << " id : "
2630  << id
2631  << " scenario : " << scenario
2632  << " optype : " << optype
2633  << " record : " << recNum
2634  << " ";
2635 
2636  /* Check event has self-consistent data */
2637  int updatesValue = (*whichVersion)[updateCol]->u_32_value();
2638 
2639  if ((*whichVersion)[updateCol]->isNULL() ||
2640  (*whichVersion)[idCol]->isNULL())
2641  {
2642  g_err << "Null update/id cols : REFRESH of !EXISTS ";
2643  }
2644 
2645  g_err << "(Updates val = " << updatesValue << ")";
2646 
2647  for (int i=0; i < (int) whichVersion->size(); i++)
2648  {
2649  /* Check PK columns and also other columns for non-delete */
2650  if (!isDelete ||
2651  tab.getColumn(i)->getPrimaryKey())
2652  {
2653  NdbRecAttr* ra = (*whichVersion)[i];
2654  if (calc.verifyRecAttr(recNum, updatesValue, ra) != 0)
2655  {
2656  g_err << "Verify failed on recNum : " << recNum << " with updates value "
2657  << updatesValue << " for column " << ra->getColumn()->getAttrId()
2658  << endl;
2659  return NDBT_FAILED;
2660  }
2661  }
2662  }
2663 
2664  EventInfo ei;
2665 
2666  switch (pOp->getEventType())
2667  {
2669  g_err << " Insert event" << endl;
2670  ei.type = Insert;
2671  break;
2673  ei.type = Delete;
2674  g_err << " Delete event" << endl;
2675  break;
2677  ei.type = Update;
2678  g_err << " Update event" << endl;
2679  break;
2680  default:
2681  g_err << " Event type : " << pOp->getEventType() << endl;
2682  abort();
2683  break;
2684  }
2685 
2686  ei.id = recNum;
2687  ei.gci = gci;
2688 
2689  receivedEvents.push_back(ei);
2690  }
2691  }
2692  else
2693  {
2694  if (--MaxTimeouts == 0)
2695  {
2696  break;
2697  }
2698  }
2699  }
2700 
2701  return NDBT_OK;
2702 }
2703 
2704 int verifyEvents(const Vector<EventInfo>& receivedEvents,
2705  const Vector<ApiEventType>& expectedEvents,
2706  int records)
2707 {
2708  /* Now verify received events against expected
2709  * This is messy as events occurring in the same epoch are unordered
2710  * except via id, so we use id-duplicates to determine which event
2711  * sequence we're looking at.
2712  */
2713  g_err << "Received total of " << receivedEvents.size() << " events" << endl;
2714  Vector<Uint32> keys;
2715  Vector<Uint64> gcis;
2716  Uint32 z = 0;
2717  Uint64 z2 = 0;
2718  keys.fill(records, z);
2719  gcis.fill(records, z2);
2720  Uint64 currGci = 0;
2721 
2722  for (Uint32 e=0; e < receivedEvents.size(); e++)
2723  {
2724  EventInfo ei = receivedEvents[e];
2725 
2726  if (ei.gci != currGci)
2727  {
2728  if (ei.gci < currGci)
2729  abort();
2730 
2731  /* Epoch boundary */
2732  /* At this point, all id counts must be equal */
2733  for (int i=0; i < records; i++)
2734  {
2735  if (keys[i] != keys[0])
2736  {
2737  g_err << "Count for id " << i
2738  << " is " << keys[i]
2739  << " but should be " << keys[0] << endl;
2740  return NDBT_OK;
2741  }
2742  }
2743 
2744  currGci = ei.gci;
2745  }
2746 
2747  Uint32 eventIndex = keys[ei.id];
2748  keys[ei.id]++;
2749 
2750  ApiEventType et = expectedEvents[eventIndex];
2751 
2752  if (ei.type != et)
2753  {
2754  g_err << "Expected event of type " << et
2755  << " but found " << ei.type
2756  << " at expectedEvent " << eventIndex
2757  << " and event num " << e << endl;
2758  return NDBT_FAILED;
2759  }
2760  }
2761 
2762  return NDBT_OK;
2763 }
2764 
2765 int runRefreshTuple(NDBT_Context* ctx, NDBT_Step* step){
2766  int records = ctx->getNumRecords();
2767  Ndb* ndb = GETNDB(step);
2768 
2769  /* Now attempt to create EventOperation */
2770  NdbEventOperation* pOp;
2771  const NdbDictionary::Table& tab = *ctx->getTab();
2772 
2773  char eventName[1024];
2774  sprintf(eventName,"%s_EVENT",tab.getName());
2775 
2776  pOp = ndb->createEventOperation(eventName);
2777  if (pOp == NULL)
2778  {
2779  g_err << "Failed to create event operation\n";
2780  return NDBT_FAILED;
2781  }
2782 
2783  HugoCalculator calc(tab);
2784  Vector<NdbRecAttr*> eventAfterRecAttr;
2785  Vector<NdbRecAttr*> eventBeforeRecAttr;
2786  int updateCol = -1;
2787  int idCol = -1;
2788 
2789  /* Now request all attributes */
2790  for (int a = 0; a < tab.getNoOfColumns(); a++)
2791  {
2792  eventAfterRecAttr.push_back(pOp->getValue(tab.getColumn(a)->getName()));
2793  eventBeforeRecAttr.push_back(pOp->getPreValue(tab.getColumn(a)->getName()));
2794  if (calc.isIdCol(a))
2795  idCol = a;
2796  if (calc.isUpdateCol(a))
2797  updateCol = a;
2798  }
2799 
2800  /* Now execute the event */
2801  if (pOp->execute())
2802  {
2803  g_err << "Event operation execution failed : " << pOp->getNdbError() << endl;
2804  return NDBT_FAILED;
2805  }
2806 
2807  HugoOperations hugoOps(*ctx->getTab());
2808  int scenario = 0;
2809 
2810  Vector<ApiEventType> expectedEvents;
2811 
2812  for (scenario = 0; scenario < 2; scenario++)
2813  {
2814  g_err << "Scenario = " << scenario
2815  << " ( Refresh "
2816  << ((scenario == 0)? "before":"after")
2817  << " operations )" << endl;
2818  int optype = 0;
2819  bool done = false;
2820  int expectedError = 0;
2821  do
2822  {
2823  check(hugoOps.startTransaction(ndb) == 0, hugoOps);
2824 
2825  if (scenario == 0)
2826  {
2827  g_err << "Refresh before operations" << endl;
2828  int anyValue =
2829  ((1) << 8) |
2830  optype;
2831  check(hugoOps.pkRefreshRecord(ndb, 0, records, anyValue) == 0, hugoOps);
2832  }
2833 
2834  switch(optype)
2835  {
2836  case 0:
2837  {
2838  /* Refresh with no data present */
2839  g_err << " Do nothing" << endl;
2840  expectedError = 0; /* Single refresh should always be fine */
2841  expectedEvents.push_back(Delete);
2842  break;
2843  }
2844  case 1:
2845  {
2846  /* [Refresh] Insert [Refresh] */
2847  g_err << " Insert" << endl;
2848  check(hugoOps.pkInsertRecord(ndb, 0, records, 1) == 0, hugoOps);
2849  if (scenario == 0)
2850  {
2851  /* Tuple already existed error when we insert after refresh */
2852  expectedError = 630;
2853  expectedEvents.push_back(Delete);
2854  }
2855  else
2856  {
2857  expectedError = 0;
2858  expectedEvents.push_back(Insert);
2859  }
2860  /* Tuple already existed error when we insert after refresh */
2861  break;
2862  }
2863  case 2:
2864  {
2865  /* Refresh */
2866  g_err << " Refresh" << endl;
2867  if (scenario == 0)
2868  {
2869  expectedEvents.push_back(Delete);
2870  }
2871  else
2872  {
2873  expectedEvents.push_back(Insert);
2874  }
2875  expectedError = 0;
2876  break;
2877  }
2878  case 3:
2879  {
2880  /* [Refresh] Update [Refresh] */
2881  g_err << " Update" << endl;
2882  check(hugoOps.pkUpdateRecord(ndb, 0, records, 3) == 0, hugoOps);
2883  if (scenario == 0)
2884  {
2885  expectedError = 920;
2886  expectedEvents.push_back(Delete);
2887  }
2888  else
2889  {
2890  expectedError = 0;
2891  expectedEvents.push_back(Insert);
2892  }
2893  break;
2894  }
2895  case 4:
2896  {
2897  /* [Refresh] Delete [Refresh] */
2898  g_err << " [Refresh] Delete [Refresh]" << endl;
2899  if (scenario == 0)
2900  {
2901  expectedError = 920;
2902  expectedEvents.push_back(Delete);
2903  }
2904  else
2905  {
2906  expectedError = 0;
2907  expectedEvents.push_back(Delete);
2908  }
2909  check(hugoOps.pkDeleteRecord(ndb, 0, records) == 0, hugoOps);
2910  break;
2911  }
2912  case 5:
2913  {
2914  g_err << " Refresh" << endl;
2915  expectedError = 0;
2916  expectedEvents.push_back(Delete);
2917  /* Refresh with no data present */
2918  break;
2919  }
2920  case 6:
2921  {
2922  g_err << " Double refresh" << endl;
2923  int anyValue =
2924  ((2) << 8) |
2925  optype;
2926  check(hugoOps.pkRefreshRecord(ndb, 0, records, anyValue) == 0, hugoOps);
2927  expectedError = 920; /* Row operation defined after refreshTuple() */
2928  expectedEvents.push_back(Delete);
2929  }
2930  default:
2931  done = true;
2932  break;
2933  }
2934 
2935  if (scenario == 1)
2936  {
2937  g_err << "Refresh after operations" << endl;
2938  int anyValue =
2939  ((4) << 8) |
2940  optype;
2941  check(hugoOps.pkRefreshRecord(ndb, 0, records, anyValue) == 0, hugoOps);
2942  }
2943 
2944  int rc = hugoOps.execute_Commit(ndb, AO_IgnoreError);
2945  check(rc == expectedError, hugoOps);
2946 
2947  check(hugoOps.closeTransaction(ndb) == 0, hugoOps);
2948 
2949  optype++;
2950 
2951 
2952  /* Now check fragment counts vs findable row counts */
2953  if (runVerifyRowCount(ctx, step) != NDBT_OK)
2954  return NDBT_FAILED;
2955 
2956  } while (!done);
2957  } // for scenario...
2958 
2959  /* Now check fragment counts vs findable row counts */
2960  if (runVerifyRowCount(ctx, step) != NDBT_OK)
2961  return NDBT_FAILED;
2962 
2963  /* Now let's dump and check the events */
2964  g_err << "Expecting the following sequence..." << endl;
2965  for (Uint32 i=0; i < expectedEvents.size(); i++)
2966  {
2967  g_err << i << ". ";
2968  switch(expectedEvents[i])
2969  {
2970  case Insert:
2971  g_err << "Insert" << endl;
2972  break;
2973  case Update:
2974  g_err << "Update" << endl;
2975  break;
2976  case Delete:
2977  g_err << "Delete" << endl;
2978  break;
2979  default:
2980  abort();
2981  }
2982  }
2983 
2984  Vector<EventInfo> receivedEvents;
2985 
2986  int rc = collectEvents(ndb, calc, tab, receivedEvents, idCol, updateCol,
2987  &eventBeforeRecAttr,
2988  &eventAfterRecAttr);
2989  if (rc == NDBT_OK)
2990  {
2991  rc = verifyEvents(receivedEvents,
2992  expectedEvents,
2993  records);
2994  }
2995 
2996  if (ndb->dropEventOperation(pOp) != 0)
2997  {
2998  g_err << "Drop Event Operation failed : " << ndb->getNdbError() << endl;
2999  return NDBT_FAILED;
3000  }
3001 
3002  return rc;
3003 };
3004 
3005 enum PreRefreshOps
3006 {
3007  PR_NONE,
3008  PR_INSERT,
3009  PR_INSERTDELETE,
3010  PR_DELETE
3011 };
3012 
3014 {
3015  const char* name;
3016  bool preExist;
3017  PreRefreshOps preRefreshOps;
3018 };
3019 
3020 static RefreshScenario refreshTests[] = {
3021  { "No row, No pre-ops", false, PR_NONE },
3022  { "No row, Insert pre-op", false, PR_INSERT },
3023  { "No row, Insert-Del pre-op", false, PR_INSERTDELETE },
3024  { "Row exists, No pre-ops", true, PR_NONE },
3025  { "Row exists, Delete pre-op", true, PR_DELETE }
3026 };
3027 
3028 enum OpTypes
3029 {
3030  OP_READ_C,
3031  OP_READ_S,
3032  OP_READ_E,
3033  OP_INSERT,
3034  OP_UPDATE,
3035  OP_WRITE,
3036  OP_DELETE,
3037  OP_LAST
3038 };
3039 
3040 const char* opTypeNames[] =
3041 {
3042  "READ_C",
3043  "READ_S",
3044  "READ_E",
3045  "INSERT",
3046  "UPDATE",
3047  "WRITE",
3048  "DELETE"
3049 };
3050 
3051 
3052 int
3053 runRefreshLocking(NDBT_Context* ctx, NDBT_Step* step)
3054 {
3055  /* Check that refresh in various situations has the
3056  * locks we expect it to
3057  * Scenario combinations :
3058  * Now row pre-existing | Row pre-existing
3059  * Trans1 : Refresh | Insert-Refresh | Insert-Delete-Refresh
3060  * Delete-Refresh
3061  * Trans2 : Read [Committed|Shared|Exclusive] | Insert | Update
3062  * Write | Delete
3063  *
3064  * Expectations : Read committed always non-blocking
3065  * Read committed sees pre-existing row
3066  * All other trans2 operations deadlock
3067  */
3068 
3069  Ndb* ndb = GETNDB(step);
3070  Uint32 numScenarios = sizeof(refreshTests) / sizeof(refreshTests[0]);
3071  HugoTransactions hugoTrans(*ctx->getTab());
3072 
3073  for (Uint32 s = 0; s < numScenarios; s++)
3074  {
3075  RefreshScenario& scenario = refreshTests[s];
3076 
3077  if (scenario.preExist)
3078  {
3079  /* Create pre-existing tuple */
3080  if (hugoTrans.loadTable(ndb, 1) != 0)
3081  {
3082  g_err << "Pre-exist failed : " << hugoTrans.getNdbError() << endl;
3083  return NDBT_FAILED;
3084  }
3085  }
3086 
3087  if (hugoTrans.startTransaction(ndb) != 0)
3088  {
3089  g_err << "Start trans failed : " << hugoTrans.getNdbError() << endl;
3090  return NDBT_FAILED;
3091  }
3092 
3093  g_err << "Scenario : " << scenario.name << endl;
3094 
3095  /* Do pre-refresh ops */
3096  switch (scenario.preRefreshOps)
3097  {
3098  case PR_NONE:
3099  break;
3100  case PR_INSERT:
3101  case PR_INSERTDELETE:
3102  if (hugoTrans.pkInsertRecord(ndb, 0) != 0)
3103  {
3104  g_err << "Pre insert failed : " << hugoTrans.getNdbError() << endl;
3105  return NDBT_FAILED;
3106  }
3107 
3108  if (scenario.preRefreshOps == PR_INSERT)
3109  break;
3110  case PR_DELETE:
3111  if (hugoTrans.pkDeleteRecord(ndb, 0) != 0)
3112  {
3113  g_err << "Pre delete failed : " << hugoTrans.getNdbError() << endl;
3114  return NDBT_FAILED;
3115  }
3116  break;
3117  }
3118 
3119  /* Then refresh */
3120  if (hugoTrans.pkRefreshRecord(ndb, 0) != 0)
3121  {
3122  g_err << "Refresh failed : " << hugoTrans.getNdbError() << endl;
3123  return NDBT_FAILED;
3124  }
3125 
3126  /* Now execute */
3127  if (hugoTrans.execute_NoCommit(ndb) != 0)
3128  {
3129  g_err << "Execute failed : " << hugoTrans.getNdbError() << endl;
3130  return NDBT_FAILED;
3131  }
3132 
3133  {
3134  /* Now try ops from another transaction */
3135  HugoOperations hugoOps(*ctx->getTab());
3136  Uint32 ot = OP_READ_C;
3137 
3138  while (ot < OP_LAST)
3139  {
3140  if (hugoOps.startTransaction(ndb) != 0)
3141  {
3142  g_err << "Start trans2 failed : " << hugoOps.getNdbError() << endl;
3143  return NDBT_FAILED;
3144  }
3145 
3146  g_err << "Operation type : " << opTypeNames[ot] << endl;
3147  int res = 0;
3148  switch (ot)
3149  {
3150  case OP_READ_C:
3151  res = hugoOps.pkReadRecord(ndb,0,1,NdbOperation::LM_CommittedRead);
3152  break;
3153  case OP_READ_S:
3154  res = hugoOps.pkReadRecord(ndb,0,1,NdbOperation::LM_Read);
3155  break;
3156  case OP_READ_E:
3157  res = hugoOps.pkReadRecord(ndb,0,1,NdbOperation::LM_Exclusive);
3158  break;
3159  case OP_INSERT:
3160  res = hugoOps.pkInsertRecord(ndb, 0);
3161  break;
3162  case OP_UPDATE:
3163  res = hugoOps.pkUpdateRecord(ndb, 0);
3164  break;
3165  case OP_WRITE:
3166  res = hugoOps.pkWriteRecord(ndb, 0);
3167  break;
3168  case OP_DELETE:
3169  res = hugoOps.pkDeleteRecord(ndb, 0);
3170  break;
3171  case OP_LAST:
3172  abort();
3173  }
3174 
3175  hugoOps.execute_Commit(ndb);
3176 
3177  if ((ot == OP_READ_C) && (scenario.preExist))
3178  {
3179  if (hugoOps.getNdbError().code == 0)
3180  {
3181  g_err << "Read committed succeeded" << endl;
3182  }
3183  else
3184  {
3185  g_err << "UNEXPECTED : Read committed failed. " << hugoOps.getNdbError() << endl;
3186  return NDBT_FAILED;
3187  }
3188  }
3189  else
3190  {
3191  if (hugoOps.getNdbError().code == 0)
3192  {
3193  g_err << opTypeNames[ot] << " succeeded, should not have" << endl;
3194  return NDBT_FAILED;
3195  }
3196  }
3197 
3198  hugoOps.closeTransaction(ndb);
3199 
3200  ot = ot + 1;
3201  }
3202 
3203  }
3204 
3205  /* Close refresh transaction */
3206  hugoTrans.closeTransaction(ndb);
3207 
3208  if (scenario.preExist)
3209  {
3210  /* Cleanup pre-existing before next iteration */
3211  if (hugoTrans.pkDelRecords(ndb, 0) != 0)
3212  {
3213  g_err << "Delete pre existing failed : " << hugoTrans.getNdbError() << endl;
3214  return NDBT_FAILED;
3215  }
3216  }
3217  }
3218 
3219  return NDBT_OK;
3220 }
3221 
3222 
3223 NDBT_TESTSUITE(testBasic);
3224 TESTCASE("PkInsert",
3225  "Verify that we can insert and delete from this table using PK"
3226  "NOTE! No errors are allowed!" ){
3227  INITIALIZER(runInsert);
3228  VERIFIER(runVerifyInsert);
3229 }
3230 TESTCASE("PkRead",
3231  "Verify that we can insert, read and delete from this table using PK"){
3232  TC_PROPERTY("LockMode", NdbOperation::LM_Read);
3233  INITIALIZER(runLoadTable);
3234  STEP(runPkRead);
3235  FINALIZER(runClearTable);
3236 }
3237 TESTCASE("PkDirtyRead",
3238  "Verify that we can insert, dirty read and delete from this table using PK"){
3239  TC_PROPERTY("LockMode", NdbOperation::LM_Dirty);
3240  INITIALIZER(runLoadTable);
3241  STEP(runPkRead);
3242  FINALIZER(runClearTable);
3243 }
3244 TESTCASE("PkSimpleRead",
3245  "Verify that we can insert, simple read and delete from this table using PK"){
3246  TC_PROPERTY("LockMode", NdbOperation::LM_SimpleRead);
3247  INITIALIZER(runLoadTable);
3248  STEP(runPkRead);
3249  FINALIZER(runClearTable);
3250 }
3251 TESTCASE("PkUpdate",
3252  "Verify that we can insert, update and delete from this table using PK"){
3253  INITIALIZER(runLoadTable);
3254  STEP(runPkUpdate);
3255  FINALIZER(runClearTable);
3256 }
3257 TESTCASE("PkDelete",
3258  "Verify that we can delete from this table using PK"){
3259  INITIALIZER(runLoadTable);
3260  STEP(runPkDelete);
3261  FINALIZER(runClearTable);
3262 }
3263 TESTCASE("UpdateAndRead",
3264  "Verify that we can read and update at the same time"){
3265  INITIALIZER(runLoadTable);
3266  STEP(runPkRead);
3267  STEP(runPkRead);
3268  STEP(runPkRead);
3269  STEP(runPkUpdate);
3270  STEP(runPkUpdate);
3271  STEP(runPkUpdate);
3272  FINALIZER(runClearTable);
3273 }
3274 TESTCASE("PkReadAndLocker",
3275  "Verify that we can read although there are "\
3276  " a number of 1 second locks in the table"){
3277  INITIALIZER(runLoadTable);
3278  STEP(runPkReadUntilStopped);
3279  STEP(runLocker);
3280  FINALIZER(runClearTable);
3281 }
3282 TESTCASE("PkReadAndLocker2",
3283  "Verify that we can read and update although there are "\
3284  " a number of 1 second locks in the table"){
3285  INITIALIZER(runLoadTable);
3286  STEP(runPkReadUntilStopped);
3287  STEP(runPkReadUntilStopped);
3288  STEP(runPkReadUntilStopped);
3289  STEP(runPkReadUntilStopped);
3290  STEP(runPkReadUntilStopped);
3291  STEP(runPkReadUntilStopped);
3292  STEP(runLocker);
3293  FINALIZER(runClearTable);
3294 }
3295 TESTCASE("PkReadUpdateAndLocker",
3296  "Verify that we can read and update although there are "\
3297  " a number of 1 second locks in the table"){
3298  INITIALIZER(runLoadTable);
3299  STEP(runPkReadUntilStopped);
3300  STEP(runPkReadUntilStopped);
3301  STEP(runPkUpdateUntilStopped);
3302  STEP(runPkUpdateUntilStopped);
3303  STEP(runLocker);
3304  FINALIZER(runClearTable);
3305 }
3306 TESTCASE("ReadWithLocksAndInserts",
3307  "TR457: This test is added to verify that an insert of a records "\
3308  "that is already in the database does not delete the record"){
3309  INITIALIZER(runLoadTable);
3310  STEP(runPkReadUntilStopped);
3311  STEP(runPkReadUntilStopped);
3312  STEP(runLocker);
3313  STEP(runInsertUntilStopped);
3314  FINALIZER(runClearTable);
3315 }
3316 TESTCASE("PkInsertTwice",
3317  "Verify that we can't insert an already inserted record."
3318  "Error should be returned" ){
3319  INITIALIZER(runLoadTable);
3320  STEP(runInsertTwice);
3321  FINALIZER(runClearTable);
3322 }
3323 TESTCASE("NoCommitSleep",
3324  "Verify what happens when a NoCommit transaction is aborted by "
3325  "NDB because the application is sleeping" ){
3326  INITIALIZER(runLoadTable);
3327  INITIALIZER(runNoCommitSleep);
3328  FINALIZER(runClearTable2);
3329 }
3330 TESTCASE("Commit626",
3331  "Verify what happens when a Commit transaction is aborted by "
3332  "NDB because the record does no exist" ){
3333  INITIALIZER(runClearTable2);
3334  INITIALIZER(runCommit626);
3335  FINALIZER(runClearTable2);
3336 }
3337 TESTCASE("CommitTry626",
3338  "Verify what happens when a Commit(TryCommit) \n"
3339  "transaction is aborted by "
3340  "NDB because the record does no exist" ){
3341  INITIALIZER(runClearTable2);
3342  INITIALIZER(runCommit_TryCommit626);
3343  FINALIZER(runClearTable2);
3344 }
3345 TESTCASE("CommitAsMuch626",
3346  "Verify what happens when a Commit(CommitAsMuchAsPossible) \n"
3347  "transaction is aborted by\n"
3348  "NDB because the record does no exist" ){
3349  INITIALIZER(runClearTable2);
3350  INITIALIZER(runCommit_CommitAsMuchAsPossible626);
3351  FINALIZER(runClearTable2);
3352 }
3353 TESTCASE("NoCommit626",
3354  "Verify what happens when a NoCommit transaction is aborted by "
3355  "NDB because the record does no exist" ){
3356  INITIALIZER(runClearTable2);
3357  INITIALIZER(runNoCommit626);
3358  FINALIZER(runClearTable2);
3359 }
3360 TESTCASE("NoCommitRollback626",
3361  "Verify what happens when a NoCommit transaction is aborted by "
3362  "NDB because the record does no exist and then we try to rollback\n"
3363  "the transaction" ){
3364  INITIALIZER(runClearTable2);
3365  INITIALIZER(runNoCommitRollback626);
3366  FINALIZER(runClearTable2);
3367 }
3368 TESTCASE("Commit630",
3369  "Verify what happens when a Commit transaction is aborted by "
3370  "NDB because the record already exist" ){
3371  INITIALIZER(runLoadTable);
3372  INITIALIZER(runCommit630);
3373  FINALIZER(runClearTable2);
3374 }
3375 TESTCASE("CommitTry630",
3376  "Verify what happens when a Commit(TryCommit) \n"
3377  "transaction is aborted by "
3378  "NDB because the record already exist" ){
3379  INITIALIZER(runLoadTable);
3380  INITIALIZER(runCommit_TryCommit630);
3381  FINALIZER(runClearTable2);
3382 }
3383 TESTCASE("CommitAsMuch630",
3384  "Verify what happens when a Commit(CommitAsMuchAsPossible) \n"
3385  "transaction is aborted by\n"
3386  "NDB because the record already exist" ){
3387  INITIALIZER(runLoadTable);
3388  INITIALIZER(runCommit_CommitAsMuchAsPossible630);
3389  FINALIZER(runClearTable2);
3390 }
3391 TESTCASE("NoCommit630",
3392  "Verify what happens when a NoCommit transaction is aborted by "
3393  "NDB because the record already exist" ){
3394  INITIALIZER(runLoadTable);
3395  INITIALIZER(runNoCommit630);
3396  FINALIZER(runClearTable2);
3397 }
3398 TESTCASE("NoCommitRollback630",
3399  "Verify what happens when a NoCommit transaction is aborted by "
3400  "NDB because the record already exist and then we try to rollback\n"
3401  "the transaction" ){
3402  INITIALIZER(runLoadTable);
3403  INITIALIZER(runNoCommitRollback630);
3404  FINALIZER(runClearTable2);
3405 }
3406 TESTCASE("NoCommitAndClose",
3407  "Verify what happens when a NoCommit transaction is closed "
3408  "without rolling back the transaction " ){
3409  INITIALIZER(runLoadTable);
3410  INITIALIZER(runNoCommitAndClose);
3411  FINALIZER(runClearTable2);
3412 }
3413 TESTCASE("RollbackDelete",
3414  "Test rollback of a no committed delete"){
3415  INITIALIZER(runLoadTable);
3416  INITIALIZER(runCheckRollbackDelete);
3417  FINALIZER(runClearTable2);
3418 }
3419 TESTCASE("RollbackUpdate",
3420  "Test rollback of a no committed update"){
3421  INITIALIZER(runLoadTable);
3422  INITIALIZER(runCheckRollbackUpdate);
3423  FINALIZER(runClearTable2);
3424 }
3425 TESTCASE("RollbackDeleteMultiple",
3426  "Test rollback of 10 non committed delete"){
3427  INITIALIZER(runLoadTable);
3428  INITIALIZER(runCheckRollbackDeleteMultiple);
3429  FINALIZER(runClearTable2);
3430 }
3431 TESTCASE("ImplicitRollbackDelete",
3432  "Test close transaction after a no commited delete\n"
3433  "this would give an implicit rollback of the delete\n"){
3434  INITIALIZER(runLoadTable);
3435  INITIALIZER(runCheckImplicitRollbackDelete);
3436  FINALIZER(runClearTable2);
3437 }
3438 TESTCASE("CommitDelete",
3439  "Test close transaction after a no commited delete\n"
3440  "this would give an implicit rollback of the delete\n"){
3441  INITIALIZER(runLoadTable);
3442  INITIALIZER(runCheckCommitDelete);
3443  FINALIZER(runClearTable2);
3444 }
3445 TESTCASE("RollbackNothing",
3446  "Test rollback of nothing"){
3447  INITIALIZER(runLoadTable);
3448  INITIALIZER(runRollbackNothing);
3449  FINALIZER(runClearTable2);
3450 }
3451 TESTCASE("MassiveRollback",
3452  "Test rollback of 4096 operations"){
3453  INITIALIZER(runClearTable2);
3454  INITIALIZER(runMassiveRollback);
3455  FINALIZER(runClearTable2);
3456 }
3457 TESTCASE("MassiveRollback2",
3458  "Test rollback of 4096 operations"){
3459  INITIALIZER(runClearTable2);
3460  INITIALIZER(runMassiveRollback2);
3461  FINALIZER(runClearTable2);
3462 }
3463 TESTCASE("MassiveRollback3",
3464  "Test rollback of 4096 operations"){
3465  INITIALIZER(runClearTable2);
3466  STEP(runMassiveRollback3);
3467  STEP(runMassiveRollback3);
3468  FINALIZER(runClearTable2);
3469 }
3470 TESTCASE("MassiveRollback4",
3471  "Test rollback of 4096 operations"){
3472  INITIALIZER(runClearTable2);
3473  STEP(runMassiveRollback4);
3474  STEP(runMassiveRollback4);
3475  FINALIZER(runClearTable2);
3476 }
3477 TESTCASE("MassiveTransaction",
3478  "Test very large insert transaction"){
3479  INITIALIZER(runLoadTable2);
3480  FINALIZER(runClearTable2);
3481 }
3482 TESTCASE("TupError",
3483  "Verify what happens when we fill the db" ){
3484  INITIALIZER(runTupErrors);
3485 }
3486 TESTCASE("InsertError", "" ){
3487  INITIALIZER(runInsertError);
3488 }
3489 TESTCASE("InsertError2", "" ){
3490  INITIALIZER(runInsertError2);
3491 }
3492 TESTCASE("Fill",
3493  "Verify what happens when we fill the db" ){
3494  STEP(runFillTable);
3495 }
3496 TESTCASE("Bug25090",
3497  "Verify what happens when we fill the db" ){
3498  STEP(runBug25090);
3499 }
3500 TESTCASE("DeleteRead",
3501  "Verify Delete+Read" ){
3502  INITIALIZER(runLoadTable);
3503  INITIALIZER(runDeleteRead);
3504  FINALIZER(runClearTable2);
3505 }
3506 TESTCASE("Bug27756",
3507  "Verify what happens when we fill the db" ){
3508  STEP(runBug27756);
3509 }
3510 TESTCASE("Bug28073",
3511  "Infinite loop in lock queue" ){
3512  STEP(runBug28073);
3513 }
3514 TESTCASE("Bug20535",
3515  "Verify what happens when we fill the db" ){
3516  STEP(runBug20535);
3517 }
3518 TESTCASE("DDInsertFailUpdateBatch",
3519  "Verify DD insert failure effect on other ops in batch on same PK"){
3520  STEP(runDDInsertFailUpdateBatch);
3521 }
3522 
3523 TESTCASE("Bug34348",
3524  "Test fragment directory range full in ACC.\n"
3525  "NOTE: If interrupted, must clear error insert 3002 manually"){
3526  STEP(runBug34348);
3527 }
3528 TESTCASE("UnlockBatch",
3529  "Test that batched unlock operations work ok"){
3530  TC_PROPERTY("Batchsize", 33);
3531  INITIALIZER(runLoadTable);
3532  STEP(runUnlocker);
3533  FINALIZER(runClearTable);
3534 }
3535 TESTCASE("DoubleUnlock",
3536  "Test that batched unlock operations work ok"){
3537  TC_PROPERTY("DoubleUnlock", 1);
3538  INITIALIZER(runLoadTable);
3539  STEP(runUnlocker);
3540  FINALIZER(runClearTable);
3541 }
3542 TESTCASE("UnlockUpdateBatch",
3543  "Test Unlock mixed with Update"){
3544  TC_PROPERTY("Batchsize", 32);
3545  INITIALIZER(runLoadTable);
3546  STEP(runUnlocker);
3547  STEP(runUnlocker);
3548  STEP(runLocker);
3549  STEP(runPkUpdate);
3550  STEP(runPkUpdate);
3551  STEP(runPkRead);
3552  FINALIZER(runClearTable);
3553 }
3554 TESTCASE("RefreshTuple",
3555  "Test refreshTuple() operation properties"){
3556  INITIALIZER(initSubscription);
3557  INITIALIZER(runRefreshTuple);
3558  FINALIZER(removeSubscription);
3559 }
3560 TESTCASE("Bug54986", "")
3561 {
3562  INITIALIZER(runBug54986);
3563 }
3564 TESTCASE("Bug54944", "")
3565 {
3566  INITIALIZER(runBug54944);
3567 }
3568 TESTCASE("Bug59496_case1", "")
3569 {
3570  STEP(runBug59496_case1);
3571  STEPS(runBug59496_scan, 10);
3572 }
3573 TESTCASE("Bug59496_case2", "")
3574 {
3575  TC_PROPERTY("CHECK_ROWCOUNT", 1);
3576  INITIALIZER(runLoadTable);
3577  STEP(runBug59496_case2);
3578  STEPS(runBug59496_scan, 10);
3579 }
3580 TESTCASE("899", "")
3581 {
3582  INITIALIZER(runLoadTable);
3583  INITIALIZER(runInit899);
3584  STEP(runTest899);
3585  FINALIZER(runEnd899);
3586 }
3587 TESTCASE("RefreshLocking",
3588  "Test Refresh locking properties")
3589 {
3590  INITIALIZER(runRefreshLocking);
3591 }
3592 NDBT_TESTSUITE_END(testBasic);
3593 
3594 #if 0
3595 TESTCASE("ReadConsistency",
3596  "Check that a read within a transaction returns the " \
3597  "same result no matter"){
3598  STEP(runInsertOne);
3599  STEP(runReadOne);
3600  FINALIZER(runClearTable2);
3601 }
3602 TESTCASE("Fill",
3603  "Verify what happens when we fill the db" ){
3604  INITIALIZER(runFillTable);
3605  INITIALIZER(runPkRead);
3606  FINALIZER(runClearTable2);
3607 }
3608 #endif
3609 
3610 int main(int argc, const char** argv){
3611  ndb_init();
3612  NDBT_TESTSUITE_INSTANCE(testBasic);
3613  return testBasic.execute(argc, argv);
3614 }
3615 
3616 
3617