1 /* Copyright (c) 2003-2007 MySQL AB
2    Use is subject to license terms
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 Street, Fifth Floor, Boston, MA  02110-1301, USA */
16 
17 #include <NDBT.hpp>
18 #include <NDBT_Test.hpp>
19 #include <HugoTransactions.hpp>
20 #include <UtilTransactions.hpp>
21 #include <NdbRestarter.hpp>
22 #include <NdbRestarts.hpp>
23 #include <Vector.hpp>
24 #include <random.h>
25 #include <NdbTick.h>
26 
27 #define MAX_NDB_OBJECTS 32678
28 
29 #define CHECK(b) if (!(b)) { \
30   ndbout << "ERR: "<< step->getName() \
31          << " failed on line " << __LINE__ << endl; \
32   result = NDBT_FAILED; \
33   continue; }
34 
35 #define CHECKE(b) if (!(b)) { \
36   errors++; \
37   ndbout << "ERR: "<< step->getName() \
38          << " failed on line " << __LINE__ << endl; \
39   result = NDBT_FAILED; \
40   continue; }
41 
42 
runTestMaxNdb(NDBT_Context * ctx,NDBT_Step * step)43 int runTestMaxNdb(NDBT_Context* ctx, NDBT_Step* step){
44   Uint32 loops = ctx->getNumLoops();
45   Uint32 l = 0;
46   int oldi = 0;
47   int result = NDBT_OK;
48 
49   while (l < loops && result == NDBT_OK){
50     ndbout_c("loop %d", l + 1);
51     int errors = 0;
52     int maxErrors = 5;
53 
54     Vector<Ndb*> ndbVector;
55     int i = 0;
56     int init = 0;
57     do {
58 
59       Ndb* pNdb = new Ndb(&ctx->m_cluster_connection, "TEST_DB");
60       if (pNdb == NULL){
61 	ndbout << "pNdb == NULL" << endl;
62 	errors++;
63 	continue;
64 
65       }
66       i++;
67 
68       ndbVector.push_back(pNdb);
69 
70       if (pNdb->init()){
71 	ERR(pNdb->getNdbError());
72 	errors++;
73 	continue;
74       }
75 
76       init++;
77 
78     } while (errors == 0);
79 
80     ndbout << i << " ndb objects created" << endl;
81 
82     if (l > 0 && i != oldi && init != MAX_NDB_OBJECTS){
83       ndbout << l << ": not as manyNdb objects created" << endl
84 	     << i << " != " << oldi << endl;
85       result =  NDBT_FAILED;
86     }
87 
88     oldi = i;
89 
90 
91     for(size_t j = 0;  j < ndbVector.size(); j++){
92       delete ndbVector[j];
93       if(((j+1) % 250) == 0){
94 	ndbout << "Deleted " << (Uint64) j << " ndb objects " << endl;
95       }
96     }
97     ndbVector.clear();
98 
99     l++;
100   }
101 
102   return result;
103 }
104 
runTestMaxTransaction(NDBT_Context * ctx,NDBT_Step * step)105 int runTestMaxTransaction(NDBT_Context* ctx, NDBT_Step* step){
106   Uint32 loops = ctx->getNumLoops();
107   Uint32 l = 0;
108   int oldi = 0;
109   int result = NDBT_OK;
110 
111   Ndb* pNdb = new Ndb(&ctx->m_cluster_connection, "TEST_DB");
112   if (pNdb == NULL){
113     ndbout << "pNdb == NULL" << endl;
114     return NDBT_FAILED;
115   }
116   if (pNdb->init(2048)){
117     ERR(pNdb->getNdbError());
118     delete pNdb;
119     return NDBT_FAILED;
120   }
121 
122   const NdbDictionary::Table* pTab = ctx->getTab();
123   if (pTab == 0) abort();
124 
125   while (l < loops && result == NDBT_OK){
126     int errors = 0;
127     int maxErrors = 5;
128 
129     Vector<NdbConnection*> conVector;
130 
131 
132     int i = 0;
133     do {
134 
135       NdbConnection* pCon;
136 
137       int type = i%2;
138       switch (type){
139       case 0:
140 	pCon = pNdb->startTransaction();
141 	break;
142       case 1:
143       {
144 	BaseString key;
145 	key.appfmt("DATA-%d", i);
146 	ndbout_c("%s", key.c_str());
147 	pCon = pNdb->startTransaction(pTab,
148 				      key.c_str(),
149 				      key.length());
150       }
151       break;
152       default:
153 	abort();
154       }
155 
156       if (pCon == NULL){
157 	ERR(pNdb->getNdbError());
158 	errors++;
159 	continue;
160       }
161 
162       conVector.push_back(pCon);
163 
164       i++;
165     } while (errors < maxErrors);
166 
167     ndbout << i << " connections created" << endl;
168 
169     if (l > 0 && i != oldi){
170       ndbout << l << ": not as many transactions created" << endl
171 	     << i << " != " << oldi << endl;
172       result =  NDBT_FAILED;
173     }
174 
175     oldi = i;
176 
177 
178     for(size_t j = 0; j < conVector.size(); j++){
179       pNdb->closeTransaction(conVector[j]);
180     }
181     conVector.clear();
182     l++;
183 
184   }
185 
186   // BONUS Test closeTransaction with null trans
187   pNdb->closeTransaction(NULL);
188 
189   delete pNdb;
190 
191 
192   return result;
193 }
194 
runTestMaxOperations(NDBT_Context * ctx,NDBT_Step * step)195 int runTestMaxOperations(NDBT_Context* ctx, NDBT_Step* step){
196   Uint32 l = 1;
197   int result = NDBT_OK;
198   int maxOpsLimit = 1;
199   const NdbDictionary::Table* pTab = ctx->getTab();
200 
201   Ndb* pNdb = new Ndb(&ctx->m_cluster_connection, "TEST_DB");
202   if (pNdb == NULL){
203     ndbout << "pNdb == NULL" << endl;
204     return NDBT_FAILED;
205   }
206   if (pNdb->init(2048)){
207     ERR(pNdb->getNdbError());
208     delete pNdb;
209     return NDBT_FAILED;
210   }
211 
212   HugoOperations hugoOps(*pTab);
213 
214   bool endTest = false;
215   while (!endTest && result == NDBT_OK){
216     int errors = 0;
217     int maxErrors = 5;
218 
219     maxOpsLimit = l*1000;
220 
221     if (hugoOps.startTransaction(pNdb) != NDBT_OK){
222       delete pNdb;
223       return NDBT_FAILED;
224     }
225 
226     int i = 0;
227     while (errors < maxErrors){
228 
229       if(hugoOps.pkReadRecord(pNdb,1, 1) != NDBT_OK){
230 	errors++;
231 	continue;
232       }
233 
234       i++;
235 
236       if (i >= maxOpsLimit){
237 	errors = maxErrors;
238       }
239 
240     }
241 
242     ndbout << i << " operations used" << endl;
243 
244     int execResult = hugoOps.execute_Commit(pNdb);
245     switch(execResult){
246     case NDBT_OK:
247       break;
248     case 233: // Out of operation records in transaction coordinator
249       // OK - end test
250       endTest = true;
251       break;
252     default:
253       result = NDBT_FAILED;
254       break;
255     }
256 
257     hugoOps.closeTransaction(pNdb);
258 
259     l++;
260 
261   }
262 
263   delete pNdb;
264 
265   return result;
266 }
267 
runTestGetValue(NDBT_Context * ctx,NDBT_Step * step)268 int runTestGetValue(NDBT_Context* ctx, NDBT_Step* step){
269 
270   int result = NDBT_OK;
271   const NdbDictionary::Table* pTab = ctx->getTab();
272 
273   Ndb* pNdb = new Ndb(&ctx->m_cluster_connection, "TEST_DB");
274   if (pNdb == NULL){
275     ndbout << "pNdb == NULL" << endl;
276     return NDBT_FAILED;
277   }
278   if (pNdb->init(2048)){
279     ERR(pNdb->getNdbError());
280     delete pNdb;
281     return NDBT_FAILED;
282   }
283 
284   HugoOperations hugoOps(*pTab);
285 
286   for (int m = 1; m < 100; m++){
287     int errors = 0;
288     int maxErrors = 5;
289 
290     NdbConnection* pCon = pNdb->startTransaction();
291     if (pCon == NULL){
292       delete pNdb;
293       return NDBT_FAILED;
294     }
295 
296     NdbOperation* pOp = pCon->getNdbOperation(pTab->getName());
297     if (pOp == NULL){
298       pNdb->closeTransaction(pCon);
299       delete pNdb;
300       return NDBT_FAILED;
301     }
302 
303     if (pOp->readTuple() != 0){
304       pNdb->closeTransaction(pCon);
305       delete pNdb;
306       return NDBT_FAILED;
307     }
308 
309     for(int a = 0; a<pTab->getNoOfColumns(); a++){
310       if (pTab->getColumn(a)->getPrimaryKey() == true){
311 	if(hugoOps.equalForAttr(pOp, a, 1) != 0){
312 	  ERR(pCon->getNdbError());
313 	  pNdb->closeTransaction(pCon);
314 	  delete pNdb;
315 	  return NDBT_FAILED;
316 	}
317       }
318     }
319 
320     int i = 0;
321     int maxLimit = 1000*m;
322     do {
323 
324       if (pOp->getValue(pTab->getColumn(1)->getName()) == NULL) {
325 	const NdbError err = pCon->getNdbError();
326 	ERR(err);
327 	if (err.code == 0)
328 	  result = NDBT_FAILED;
329 	errors++;
330 	continue;
331       }
332 
333       i++;
334 
335     } while (errors < maxErrors && i < maxLimit);
336 
337     ndbout << i << " getValues called" << endl;
338 
339 
340     if (pCon->execute(Commit) != 0){
341       const NdbError err = pCon->getNdbError();
342       switch(err.code){
343       case 880: // TUP - Read too much
344       case 823: // TUP - Too much AI
345       case 4257: // NDBAPI - Too much AI
346 	// OK errors
347 	ERR(pCon->getNdbError());
348 	break;
349       default:
350 	ERR(pCon->getNdbError());
351 	ndbout << "Illegal error" << endl;
352 	result= NDBT_FAILED;
353 	break;
354       }
355     }
356 
357     pNdb->closeTransaction(pCon);
358 
359   }// m
360 
361 
362   delete pNdb;
363 
364   return result;
365 }
366 
runTestEqual(NDBT_Context * ctx,NDBT_Step * step)367 int runTestEqual(NDBT_Context* ctx, NDBT_Step* step){
368   Uint32 loops = ctx->getNumLoops();
369   Uint32 l = 0;
370   int result = NDBT_OK;
371   const NdbDictionary::Table* pTab = ctx->getTab();
372 
373   Ndb* pNdb = new Ndb(&ctx->m_cluster_connection, "TEST_DB");
374   if (pNdb == NULL){
375     ndbout << "pNdb == NULL" << endl;
376     return NDBT_FAILED;
377   }
378   if (pNdb->init(2048)){
379     ERR(pNdb->getNdbError());
380     delete pNdb;
381     return NDBT_FAILED;
382   }
383 
384   HugoOperations hugoOps(*pTab);
385 
386   while (l < loops){
387     for(int m = 1; m < 10; m++){
388       int errors = 0;
389       int maxErrors = 5;
390 
391       NdbConnection* pCon = pNdb->startTransaction();
392       if (pCon == NULL){
393 	ndbout << "Could not start transaction" << endl;
394 	delete pNdb;
395 	return NDBT_FAILED;
396       }
397 
398       NdbOperation* pOp = pCon->getNdbOperation(pTab->getName());
399       if (pOp == NULL){
400 	ERR(pCon->getNdbError());
401 	pNdb->closeTransaction(pCon);
402 	delete pNdb;
403 	return NDBT_FAILED;
404       }
405 
406       if (pOp->readTuple() != 0){
407 	ERR(pCon->getNdbError());
408 	pNdb->closeTransaction(pCon);
409 	delete pNdb;
410 	return NDBT_FAILED;
411       }
412 
413       int i = 0;
414       int maxLimit = 1000*m;
415       do {
416 
417 	if ((l%2)!=0){
418 	  // Forward
419 	  for(int a = 0; a<pTab->getNoOfColumns(); a++){
420 	    if (pTab->getColumn(a)->getPrimaryKey() == true){
421 	      if(hugoOps.equalForAttr(pOp, a, 1) != 0){
422 		const NdbError err = pCon->getNdbError();
423 		ERR(err);
424 		if (err.code == 0)
425 		  result = NDBT_FAILED;
426 		errors++;
427 	      }
428 	    }
429 	  }
430 	} else {
431 	  // Backward
432 	  for(int a = pTab->getNoOfColumns()-1; a>=0; a--){
433 	    if (pTab->getColumn(a)->getPrimaryKey() == true){
434 	      if(hugoOps.equalForAttr(pOp, a, 1) != 0){
435 		const NdbError err = pCon->getNdbError();
436 		ERR(err);
437 		if (err.code == 0)
438 		  result = NDBT_FAILED;
439 		errors++;
440 	      }
441 	    }
442 	  }
443 	}
444 
445 	i++;
446 
447       } while (errors < maxErrors && i < maxLimit);
448 
449       if (pOp->getValue(pTab->getColumn(1)->getName()) == NULL) {
450         const NdbError err = pCon->getNdbError();
451 	ERR(pCon->getNdbError());
452 	pNdb->closeTransaction(pCon);
453 	delete pNdb;
454         if (err.code == 4225) {
455           return NDBT_OK;
456         } else {
457           return NDBT_FAILED;
458         }//if
459       }
460 
461       ndbout << i << " equal called" << endl;
462 
463 
464       int check = pCon->execute(Commit);
465       if (check != 0){
466 	ERR(pCon->getNdbError());
467       }
468 
469       pNdb->closeTransaction(pCon);
470 
471     }// m
472     l++;
473 
474   }// l
475 
476   delete pNdb;
477   return result;
478 }
479 
runTestDeleteNdb(NDBT_Context * ctx,NDBT_Step * step)480 int runTestDeleteNdb(NDBT_Context* ctx, NDBT_Step* step){
481   Uint32 loops = ctx->getNumLoops();
482   Uint32 l = 0;
483   int result = NDBT_OK;
484   NdbRestarts restarts;
485   Vector<Ndb*> ndbVector;
486   const NdbDictionary::Table* pTab = ctx->getTab();
487   HugoTransactions hugoTrans(*pTab);
488   int records = ctx->getNumRecords();
489 
490   while (l < loops && result == NDBT_OK){
491 
492     // Create 5 ndb objects
493     for( int i = 0; i < 5; i++){
494       Ndb* pNdb = new Ndb(&ctx->m_cluster_connection, "TEST_DB");
495       if (pNdb == NULL){
496 	ndbout << "pNdb == NULL" << endl;
497 	result = NDBT_FAILED;
498 	goto end_test;
499       }
500       ndbVector.push_back(pNdb);
501 
502       if (pNdb->init()){
503 	ERR(pNdb->getNdbError());
504 	result = NDBT_FAILED;
505 	goto end_test;
506       }
507       if (pNdb->waitUntilReady() != 0){
508 	ERR(pNdb->getNdbError());
509 	result = NDBT_FAILED;
510 	goto end_test;
511       }
512       if (hugoTrans.pkReadRecords(pNdb, records) != 0){
513 	result = NDBT_FAILED;
514 	goto end_test;
515       }
516     }
517 
518     if ((l % 2) == 0){
519       // Restart random node
520       ndbout << "Restart random node " << endl;
521       if(restarts.executeRestart("RestartRandomNodeAbort", 120) != 0){
522 	g_err << "Failed to executeRestart(RestartRandomNode)"<<endl;
523 	result = NDBT_FAILED;
524 	goto end_test;
525       }
526     } else {
527       // Restart all nodes
528       ndbout << "Restart all nodes " << endl;
529       if(restarts.executeRestart("RestartAllNodesAbort", 120) != 0){
530 	g_err << "Failed to executeRestart(RestartAllNodes)"<<endl;
531 	result = NDBT_FAILED;
532 	goto end_test;
533       }
534     }
535 
536     // Delete the ndb objects
537     for(size_t j = 0;  j < ndbVector.size(); j++)
538       delete ndbVector[j];
539     ndbVector.clear();
540     l++;
541   }
542 
543 
544  end_test:
545 
546   for(size_t i = 0;  i < ndbVector.size(); i++)
547     delete ndbVector[i];
548   ndbVector.clear();
549 
550   return result;
551 }
552 
553 
runClearTable(NDBT_Context * ctx,NDBT_Step * step)554 int runClearTable(NDBT_Context* ctx, NDBT_Step* step){
555   int records = ctx->getNumRecords();
556 
557   UtilTransactions utilTrans(*ctx->getTab());
558   if (utilTrans.clearTable2(GETNDB(step),  records) != 0){
559     return NDBT_FAILED;
560   }
561   return NDBT_OK;
562 }
runLoadTable(NDBT_Context * ctx,NDBT_Step * step)563 int runLoadTable(NDBT_Context* ctx, NDBT_Step* step){
564 
565   int records = ctx->getNumRecords();
566   HugoTransactions hugoTrans(*ctx->getTab());
567   if (hugoTrans.loadTable(GETNDB(step), records) != 0){
568     return NDBT_FAILED;
569   }
570   return NDBT_OK;
571 }
572 
runTestWaitUntilReady(NDBT_Context * ctx,NDBT_Step * step)573 int runTestWaitUntilReady(NDBT_Context* ctx, NDBT_Step* step){
574 
575   Ndb* pNdb = new Ndb(&ctx->m_cluster_connection, "TEST_DB");
576 
577   // Forget about calling pNdb->init();
578 
579   if (pNdb->waitUntilReady() == 0){
580     ndbout << "waitUntilReady returned OK" << endl;
581     delete pNdb;
582     return NDBT_FAILED;
583   }
584   const NdbError err = pNdb->getNdbError();
585   delete pNdb;
586 
587   ERR(err);
588   if (err.code != 4256)
589     return NDBT_FAILED;
590 
591   return NDBT_OK;
592 }
593 
runGetNdbOperationNoTab(NDBT_Context * ctx,NDBT_Step * step)594 int runGetNdbOperationNoTab(NDBT_Context* ctx, NDBT_Step* step){
595 
596   Ndb* pNdb = new Ndb(&ctx->m_cluster_connection, "TEST_DB");
597   if (pNdb == NULL){
598     ndbout << "pNdb == NULL" << endl;
599     return NDBT_FAILED;
600   }
601   if (pNdb->init()){
602     ERR(pNdb->getNdbError());
603     delete pNdb;
604     return NDBT_FAILED;
605   }
606 
607   NdbConnection* pCon = pNdb->startTransaction();
608   if (pCon == NULL){
609     delete pNdb;
610     return NDBT_FAILED;
611   }
612 
613   // Call getNdbOperation on an unknown table
614   NdbOperation* pOp = pCon->getNdbOperation("HUPP76");
615   if (pOp == NULL){
616     NdbError err = pCon->getNdbError();
617     ERR(err);
618     if (err.code == 0){
619       pNdb->closeTransaction(pCon);
620       delete pNdb;
621       return NDBT_FAILED;
622     }
623   }
624 
625   pNdb->closeTransaction(pCon);
626 
627   delete pNdb;
628 
629   return NDBT_OK;
630 }
631 
runMissingOperation(NDBT_Context * ctx,NDBT_Step * step)632 int runMissingOperation(NDBT_Context* ctx, NDBT_Step* step){
633   int result = NDBT_OK;
634   const NdbDictionary::Table* pTab = ctx->getTab();
635 
636 
637   Ndb* pNdb = new Ndb(&ctx->m_cluster_connection, "TEST_DB");
638   if (pNdb == NULL){
639     ndbout << "pNdb == NULL" << endl;
640     return NDBT_FAILED;
641   }
642   if (pNdb->init()){
643     ERR(pNdb->getNdbError());
644     delete pNdb;
645     return NDBT_FAILED;
646   }
647 
648   NdbConnection* pCon = pNdb->startTransaction();
649   if (pCon == NULL){
650     pNdb->closeTransaction(pCon);
651     delete pNdb;
652     return NDBT_FAILED;
653   }
654 
655   NdbOperation* pOp = pCon->getNdbOperation(pTab->getName());
656   if (pOp == NULL){
657     ERR(pCon->getNdbError());
658     pNdb->closeTransaction(pCon);
659     delete pNdb;
660     return NDBT_FAILED;
661   }
662 
663   // Forget about calling pOp->insertTuple();
664 
665   // Call getValue should not work
666   if (pOp->getValue(pTab->getColumn(1)->getName()) == NULL) {
667     const NdbError err = pCon->getNdbError();
668     ERR(err);
669     if (err.code == 0){
670       ndbout << "hupp" << endl;
671       result = NDBT_FAILED;
672     }
673   } else {
674       ndbout << "hupp2" << endl;
675     result = NDBT_FAILED;
676   }
677 
678   pNdb->closeTransaction(pCon);
679   delete pNdb;
680 
681   return result;
682 }
683 
runGetValueInUpdate(NDBT_Context * ctx,NDBT_Step * step)684 int runGetValueInUpdate(NDBT_Context* ctx, NDBT_Step* step){
685   const NdbDictionary::Table* pTab = ctx->getTab();
686 
687   Ndb* pNdb = new Ndb(&ctx->m_cluster_connection, "TEST_DB");
688   if (pNdb == NULL){
689     ndbout << "pNdb == NULL" << endl;
690     return NDBT_FAILED;
691   }
692   if (pNdb->init()){
693     ERR(pNdb->getNdbError());
694     delete pNdb;
695     return NDBT_FAILED;
696   }
697 
698   NdbConnection* pCon = pNdb->startTransaction();
699   if (pCon == NULL){
700     pNdb->closeTransaction(pCon);
701     delete pNdb;
702     return NDBT_FAILED;
703   }
704 
705   NdbOperation* pOp = pCon->getNdbOperation(pTab->getName());
706   if (pOp == NULL){
707     ERR(pCon->getNdbError());
708     pNdb->closeTransaction(pCon);
709     delete pNdb;
710     return NDBT_FAILED;
711   }
712 
713   if (pOp->updateTuple() != 0){
714     pNdb->closeTransaction(pCon);
715     delete pNdb;
716     return NDBT_FAILED;
717   }
718 
719   // Call getValue should not work
720   if (pOp->getValue(pTab->getColumn(1)->getName()) == NULL) {
721     // It didn't work
722     const NdbError err = pCon->getNdbError();
723     ERR(err);
724     if (err.code == 0){
725       pNdb->closeTransaction(pCon);
726       delete pNdb;
727       return NDBT_FAILED;
728     }
729   } else {
730     // It worked, not good!
731     pNdb->closeTransaction(pCon);
732     delete pNdb;
733     return NDBT_FAILED;
734   }
735 
736   int check = pCon->execute(Commit);
737   if (check != 0){
738     ERR(pCon->getNdbError());
739   }
740 
741   pNdb->closeTransaction(pCon);
742   delete pNdb;
743 
744   return NDBT_OK;
745 }
746 
runUpdateWithoutValues(NDBT_Context * ctx,NDBT_Step * step)747 int runUpdateWithoutValues(NDBT_Context* ctx, NDBT_Step* step){
748   int result = NDBT_OK;
749   const NdbDictionary::Table* pTab = ctx->getTab();
750 
751   HugoOperations hugoOps(*pTab);
752 
753   Ndb* pNdb = new Ndb(&ctx->m_cluster_connection, "TEST_DB");
754   if (pNdb == NULL){
755     ndbout << "pNdb == NULL" << endl;
756     return NDBT_FAILED;
757   }
758   if (pNdb->init()){
759     ERR(pNdb->getNdbError());
760     delete pNdb;
761     return NDBT_FAILED;
762   }
763 
764   NdbConnection* pCon = pNdb->startTransaction();
765   if (pCon == NULL){
766     pNdb->closeTransaction(pCon);
767     delete pNdb;
768     return NDBT_FAILED;
769   }
770 
771   NdbOperation* pOp = pCon->getNdbOperation(pTab->getName());
772   if (pOp == NULL){
773     ERR(pCon->getNdbError());
774     pNdb->closeTransaction(pCon);
775     delete pNdb;
776     return NDBT_FAILED;
777   }
778 
779   if (pOp->updateTuple() != 0){
780     pNdb->closeTransaction(pCon);
781     ERR(pOp->getNdbError());
782     delete pNdb;
783     return NDBT_FAILED;
784   }
785 
786   for(int a = 0; a<pTab->getNoOfColumns(); a++){
787     if (pTab->getColumn(a)->getPrimaryKey() == true){
788       if(hugoOps.equalForAttr(pOp, a, 1) != 0){
789 	ERR(pCon->getNdbError());
790 	pNdb->closeTransaction(pCon);
791 	delete pNdb;
792 	return NDBT_FAILED;
793       }
794     }
795   }
796 
797   // Dont' call any setValues
798 
799   // Execute should work
800   int check = pCon->execute(Commit);
801   if (check == 0){
802     ndbout << "execute worked" << endl;
803   } else {
804     ERR(pCon->getNdbError());
805     result = NDBT_FAILED;
806   }
807 
808   pNdb->closeTransaction(pCon);
809   delete pNdb;
810 
811   return result;
812 }
813 
runUpdateWithoutKeys(NDBT_Context * ctx,NDBT_Step * step)814 int runUpdateWithoutKeys(NDBT_Context* ctx, NDBT_Step* step){
815   int result = NDBT_OK;
816   const NdbDictionary::Table* pTab = ctx->getTab();
817 
818 
819   Ndb* pNdb = new Ndb(&ctx->m_cluster_connection, "TEST_DB");
820   if (pNdb == NULL){
821     ndbout << "pNdb == NULL" << endl;
822     return NDBT_FAILED;
823   }
824   if (pNdb->init()){
825     ERR(pNdb->getNdbError());
826     delete pNdb;
827     return NDBT_FAILED;
828   }
829 
830   NdbConnection* pCon = pNdb->startTransaction();
831   if (pCon == NULL){
832     pNdb->closeTransaction(pCon);
833     delete pNdb;
834     return NDBT_FAILED;
835   }
836 
837   NdbOperation* pOp = pCon->getNdbOperation(pTab->getName());
838   if (pOp == NULL){
839     ERR(pCon->getNdbError());
840     pNdb->closeTransaction(pCon);
841     delete pNdb;
842     return NDBT_FAILED;
843   }
844 
845   if (pOp->updateTuple() != 0){
846     pNdb->closeTransaction(pCon);
847     ERR(pOp->getNdbError());
848     delete pNdb;
849     return NDBT_FAILED;
850   }
851 
852   // Dont' call any equal or setValues
853 
854   // Execute should not work
855   int check = pCon->execute(Commit);
856   if (check == 0){
857     ndbout << "execute worked" << endl;
858     result = NDBT_FAILED;
859   } else {
860     ERR(pCon->getNdbError());
861   }
862 
863   pNdb->closeTransaction(pCon);
864   delete pNdb;
865 
866   return result;
867 }
868 
869 
runReadWithoutGetValue(NDBT_Context * ctx,NDBT_Step * step)870 int runReadWithoutGetValue(NDBT_Context* ctx, NDBT_Step* step){
871   int result = NDBT_OK;
872   const NdbDictionary::Table* pTab = ctx->getTab();
873 
874   HugoOperations hugoOps(*pTab);
875 
876   Ndb* pNdb = GETNDB(step);
877   Uint32 lm;
878 
879   for(Uint32 cm= 0; cm < 2; cm++)
880   {
881     for(lm= 0; lm <= NdbOperation::LM_CommittedRead; lm++)
882     {
883       NdbConnection* pCon = pNdb->startTransaction();
884       if (pCon == NULL){
885 	pNdb->closeTransaction(pCon);
886 	return NDBT_FAILED;
887       }
888 
889       NdbOperation* pOp = pCon->getNdbOperation(pTab->getName());
890       if (pOp == NULL){
891 	ERR(pCon->getNdbError());
892 	pNdb->closeTransaction(pCon);
893 	return NDBT_FAILED;
894       }
895 
896       if (pOp->readTuple((NdbOperation::LockMode)lm) != 0){
897 	pNdb->closeTransaction(pCon);
898 	ERR(pOp->getNdbError());
899 	return NDBT_FAILED;
900       }
901 
902       for(int a = 0; a<pTab->getNoOfColumns(); a++){
903 	if (pTab->getColumn(a)->getPrimaryKey() == true){
904 	  if(hugoOps.equalForAttr(pOp, a, 1) != 0){
905 	    ERR(pCon->getNdbError());
906 	    pNdb->closeTransaction(pCon);
907 	    return NDBT_FAILED;
908 	  }
909 	}
910       }
911 
912       // Dont' call any getValues
913 
914       // Execute should work
915       int check = pCon->execute(cm == 0 ? NoCommit : Commit);
916       if (check == 0){
917 	ndbout << "execute worked" << endl;
918       } else {
919 	ERR(pCon->getNdbError());
920 	result = NDBT_FAILED;
921       }
922 
923       pNdb->closeTransaction(pCon);
924     }
925   }
926 
927   /**
928    * Now test scans
929    */
930   for(lm= 0; lm <= NdbOperation::LM_CommittedRead; lm++)
931   {
932     NdbConnection* pCon = pNdb->startTransaction();
933     if (pCon == NULL){
934       pNdb->closeTransaction(pCon);
935       return NDBT_FAILED;
936     }
937 
938     NdbScanOperation* pOp = pCon->getNdbScanOperation(pTab->getName());
939     if (pOp == NULL){
940       ERR(pCon->getNdbError());
941       pNdb->closeTransaction(pCon);
942       return NDBT_FAILED;
943     }
944 
945     if ((pOp->readTuples((NdbOperation::LockMode)lm)) != 0){
946       pNdb->closeTransaction(pCon);
947       ERR(pOp->getNdbError());
948       return NDBT_FAILED;
949     }
950 
951 
952     // Dont' call any getValues
953 
954     // Execute should work
955     int check = pCon->execute(NoCommit);
956     if (check == 0){
957       ndbout << "execute worked" << endl;
958     } else {
959       ERR(pCon->getNdbError());
960       result = NDBT_FAILED;
961     }
962 
963     int res;
964     while((res = pOp->nextResult()) == 0);
965     pNdb->closeTransaction(pCon);
966 
967     if(res != 1)
968       result = NDBT_FAILED;
969   }
970 
971   return result;
972 }
973 
974 
runCheckGetNdbErrorOperation(NDBT_Context * ctx,NDBT_Step * step)975 int runCheckGetNdbErrorOperation(NDBT_Context* ctx, NDBT_Step* step){
976   int result = NDBT_OK;
977   const NdbDictionary::Table* pTab = ctx->getTab();
978 
979   Ndb* pNdb = new Ndb(&ctx->m_cluster_connection, "TEST_DB");
980   if (pNdb == NULL){
981     ndbout << "pNdb == NULL" << endl;
982     return NDBT_FAILED;
983   }
984   if (pNdb->init(2048)){
985     ERR(pNdb->getNdbError());
986     delete pNdb;
987     return NDBT_FAILED;
988   }
989 
990   HugoOperations hugoOps(*pTab);
991 
992 
993   NdbConnection* pCon = pNdb->startTransaction();
994   if (pCon == NULL){
995     ndbout << "Could not start transaction" << endl;
996     delete pNdb;
997     return NDBT_FAILED;
998   }
999 
1000   NdbOperation* pOp = pCon->getNdbOperation(pTab->getName());
1001   if (pOp == NULL){
1002     ERR(pCon->getNdbError());
1003     pNdb->closeTransaction(pCon);
1004     delete pNdb;
1005     return NDBT_FAILED;
1006   }
1007 
1008   // Dont call readTuple here
1009   // That's the error!
1010 
1011   for(int a = 0; a<pTab->getNoOfColumns(); a++){
1012     if (pTab->getColumn(a)->getPrimaryKey() == true){
1013       if(hugoOps.equalForAttr(pOp, a, 1) != 0){
1014 	// An error has occured, check that
1015 	// it's possible to get the NdbErrorOperation
1016 	const NdbError err = pCon->getNdbError();
1017 	ERR(err);
1018 	if (err.code == 0)
1019 	  result = NDBT_FAILED;
1020 
1021 	NdbOperation* pOp2 = pCon->getNdbErrorOperation();
1022 	if (pOp2 == NULL)
1023 	  result = NDBT_FAILED;
1024 	else {
1025 	  const NdbError err2 = pOp2->getNdbError();
1026 	  ERR(err2);
1027 	  if (err.code == 0)
1028 	    result = NDBT_FAILED;
1029 	}
1030       }
1031     }
1032   }
1033 
1034   pNdb->closeTransaction(pCon);
1035 
1036   delete pNdb;
1037   return result;
1038 }
1039 
1040 #define C2(x) { int _x= (x); if(_x == 0){ ndbout << "line: " << __LINE__ << endl;  return NDBT_FAILED;} }
1041 
runBug_11133(NDBT_Context * ctx,NDBT_Step * step)1042 int runBug_11133(NDBT_Context* ctx, NDBT_Step* step){
1043   int result = NDBT_OK;
1044   const NdbDictionary::Table* pTab = ctx->getTab();
1045 
1046   HugoOperations hugoOps(*pTab);
1047 
1048   Ndb* pNdb = GETNDB(step);
1049   C2(hugoOps.startTransaction(pNdb) == 0);
1050   C2(hugoOps.pkInsertRecord(pNdb, 0, 1) == 0);
1051   C2(hugoOps.execute_NoCommit(pNdb) == 0);
1052   C2(hugoOps.pkDeleteRecord(pNdb, 0, 1) == 0);
1053   C2(hugoOps.execute_NoCommit(pNdb) == 0);
1054   C2(hugoOps.pkWriteRecord(pNdb, 0, 1) == 0);
1055   C2(hugoOps.execute_NoCommit(pNdb) == 0);
1056   C2(hugoOps.pkWriteRecord(pNdb, 0, 1) == 0);
1057   C2(hugoOps.execute_NoCommit(pNdb) == 0);
1058   C2(hugoOps.pkDeleteRecord(pNdb, 0, 1) == 0);
1059   C2(hugoOps.execute_Commit(pNdb) == 0);
1060   C2(hugoOps.closeTransaction(pNdb) == 0);
1061 
1062   C2(hugoOps.startTransaction(pNdb) == 0);
1063   C2(hugoOps.pkInsertRecord(pNdb, 0, 1) == 0);
1064   C2(hugoOps.execute_NoCommit(pNdb) == 0);
1065   C2(hugoOps.pkWriteRecord(pNdb, 0, 1) == 0);
1066   C2(hugoOps.execute_NoCommit(pNdb) == 0);
1067   C2(hugoOps.pkWriteRecord(pNdb, 0, 1) == 0);
1068   C2(hugoOps.execute_NoCommit(pNdb) == 0);
1069   C2(hugoOps.pkDeleteRecord(pNdb, 0, 1) == 0);
1070   C2(hugoOps.execute_Commit(pNdb) == 0);
1071   C2(hugoOps.closeTransaction(pNdb) == 0);
1072 
1073   C2(hugoOps.startTransaction(pNdb) == 0);
1074   C2(hugoOps.pkInsertRecord(pNdb, 0, 1) == 0);
1075   C2(hugoOps.execute_Commit(pNdb) == 0);
1076   C2(hugoOps.closeTransaction(pNdb) == 0);
1077 
1078   C2(hugoOps.startTransaction(pNdb) == 0);
1079   C2(hugoOps.pkReadRecord(pNdb, 0, 1, NdbOperation::LM_Exclusive) == 0);
1080   C2(hugoOps.execute_NoCommit(pNdb) == 0);
1081   C2(hugoOps.pkDeleteRecord(pNdb, 0, 1) == 0);
1082   C2(hugoOps.execute_NoCommit(pNdb) == 0);
1083   C2(hugoOps.pkWriteRecord(pNdb, 0, 1) == 0);
1084   C2(hugoOps.execute_NoCommit(pNdb) == 0);
1085   C2(hugoOps.pkWriteRecord(pNdb, 0, 1) == 0);
1086   C2(hugoOps.execute_NoCommit(pNdb) == 0);
1087   C2(hugoOps.pkDeleteRecord(pNdb, 0, 1) == 0);
1088   C2(hugoOps.execute_Commit(pNdb) == 0);
1089   C2(hugoOps.closeTransaction(pNdb) == 0);
1090 
1091   Ndb ndb2(&ctx->m_cluster_connection, "TEST_DB");
1092   C2(ndb2.init() == 0);
1093   C2(ndb2.waitUntilReady() == 0);
1094   HugoOperations hugoOps2(*pTab);
1095 
1096   C2(hugoOps.startTransaction(pNdb) == 0);
1097   C2(hugoOps.pkInsertRecord(pNdb, 0, 1) == 0);
1098   C2(hugoOps.execute_NoCommit(pNdb) == 0);
1099   C2(hugoOps2.startTransaction(&ndb2) == 0);
1100   C2(hugoOps2.pkWritePartialRecord(&ndb2, 0) == 0);
1101   C2(hugoOps2.execute_async(&ndb2, NdbTransaction::NoCommit) == 0);
1102   C2(hugoOps.execute_Commit(pNdb) == 0);
1103   C2(hugoOps2.wait_async(&ndb2) == 0);
1104   C2(hugoOps.closeTransaction(pNdb) == 0);
1105   C2(hugoOps2.closeTransaction(&ndb2) == 0);
1106 
1107   C2(hugoOps.startTransaction(pNdb) == 0);
1108   C2(hugoOps.pkDeleteRecord(pNdb, 0, 1) == 0);
1109   C2(hugoOps.execute_NoCommit(pNdb) == 0);
1110   C2(hugoOps2.startTransaction(&ndb2) == 0);
1111   C2(hugoOps2.pkWriteRecord(&ndb2, 0, 1) == 0);
1112   C2(hugoOps2.execute_async(&ndb2, NdbTransaction::NoCommit) == 0);
1113   C2(hugoOps.execute_Commit(pNdb) == 0);
1114   C2(hugoOps2.wait_async(&ndb2) == 0);
1115   C2(hugoOps2.execute_Commit(pNdb) == 0);
1116   C2(hugoOps.closeTransaction(pNdb) == 0);
1117   C2(hugoOps2.closeTransaction(&ndb2) == 0);
1118 
1119   C2(hugoOps.startTransaction(pNdb) == 0);
1120   C2(hugoOps.pkUpdateRecord(pNdb, 0, 1) == 0);
1121   C2(hugoOps.execute_NoCommit(pNdb) == 0);
1122   C2(hugoOps2.startTransaction(&ndb2) == 0);
1123   C2(hugoOps2.pkWritePartialRecord(&ndb2, 0) == 0);
1124   C2(hugoOps2.execute_async(&ndb2, NdbTransaction::NoCommit) == 0);
1125   C2(hugoOps.execute_Commit(pNdb) == 0);
1126   C2(hugoOps2.wait_async(&ndb2) == 0);
1127   C2(hugoOps.closeTransaction(pNdb) == 0);
1128   C2(hugoOps2.closeTransaction(&ndb2) == 0);
1129 
1130   C2(hugoOps.startTransaction(pNdb) == 0);
1131   C2(hugoOps.pkDeleteRecord(pNdb, 0, 1) == 0);
1132   C2(hugoOps.execute_NoCommit(pNdb) == 0);
1133   C2(hugoOps2.startTransaction(&ndb2) == 0);
1134   C2(hugoOps2.pkWritePartialRecord(&ndb2, 0) == 0);
1135   C2(hugoOps2.execute_async(&ndb2, NdbTransaction::NoCommit) == 0);
1136   C2(hugoOps.execute_Commit(pNdb) == 0);
1137   C2(hugoOps2.wait_async(&ndb2) != 0);
1138   C2(hugoOps.closeTransaction(pNdb) == 0);
1139   C2(hugoOps2.closeTransaction(&ndb2) == 0);
1140 
1141   return result;
1142 }
1143 
runBug_WritePartialIgnoreError(NDBT_Context * ctx,NDBT_Step * step)1144 int runBug_WritePartialIgnoreError(NDBT_Context* ctx, NDBT_Step* step){
1145   int result = NDBT_OK;
1146   const NdbDictionary::Table* pTab = ctx->getTab();
1147 
1148   HugoOperations hugoOps(*pTab);
1149 
1150   Ndb* pNdb = GETNDB(step);
1151   C2(hugoOps.startTransaction(pNdb) == 0);
1152   C2(hugoOps.pkWritePartialRecord(pNdb, 0, 1) == 0);
1153   C2(hugoOps.execute_Commit(pNdb, AO_IgnoreError) == 839);
1154   C2(hugoOps.closeTransaction(pNdb) == 0);
1155 
1156   return result;
1157 }
1158 
runScan_4006(NDBT_Context * ctx,NDBT_Step * step)1159 int runScan_4006(NDBT_Context* ctx, NDBT_Step* step){
1160   int result = NDBT_OK;
1161   const Uint32 max= 5;
1162   const NdbDictionary::Table* pTab = ctx->getTab();
1163 
1164   Ndb* pNdb = new Ndb(&ctx->m_cluster_connection, "TEST_DB");
1165   if (pNdb == NULL){
1166     ndbout << "pNdb == NULL" << endl;
1167     return NDBT_FAILED;
1168   }
1169   if (pNdb->init(max)){
1170     ERR(pNdb->getNdbError());
1171     delete pNdb;
1172     return NDBT_FAILED;
1173   }
1174 
1175   NdbConnection* pCon = pNdb->startTransaction();
1176   if (pCon == NULL){
1177     pNdb->closeTransaction(pCon);
1178     delete pNdb;
1179     return NDBT_FAILED;
1180   }
1181 
1182   Uint32 i;
1183   Vector<NdbScanOperation*> scans;
1184   for(i = 0; i<10*max; i++)
1185   {
1186     NdbScanOperation* pOp = pCon->getNdbScanOperation(pTab->getName());
1187     if (pOp == NULL){
1188       ERR(pCon->getNdbError());
1189       pNdb->closeTransaction(pCon);
1190       delete pNdb;
1191       return NDBT_FAILED;
1192     }
1193 
1194     if (pOp->readTuples() != 0){
1195       pNdb->closeTransaction(pCon);
1196       ERR(pOp->getNdbError());
1197       delete pNdb;
1198       return NDBT_FAILED;
1199     }
1200     scans.push_back(pOp);
1201   }
1202 
1203   // Dont' call any equal or setValues
1204 
1205   // Execute should not work
1206   int check = pCon->execute(NoCommit);
1207   if (check == 0){
1208     ndbout << "execute worked" << endl;
1209   } else {
1210     ERR(pCon->getNdbError());
1211   }
1212 
1213   for(i= 0; i<scans.size(); i++)
1214   {
1215     NdbScanOperation* pOp= scans[i];
1216     while((check= pOp->nextResult()) == 0);
1217     if(check != 1)
1218     {
1219       ERR(pOp->getNdbError());
1220       pNdb->closeTransaction(pCon);
1221       delete pNdb;
1222       return NDBT_FAILED;
1223     }
1224   }
1225 
1226   pNdb->closeTransaction(pCon);
1227 
1228   Vector<NdbConnection*> cons;
1229   for(i= 0; i<10*max; i++)
1230   {
1231     pCon= pNdb->startTransaction();
1232     if(pCon)
1233       cons.push_back(pCon);
1234     else
1235       break;
1236   }
1237 
1238   for(i= 0; i<cons.size(); i++)
1239   {
1240     cons[i]->close();
1241   }
1242 
1243   if(cons.size() != max)
1244   {
1245     result= NDBT_FAILED;
1246   }
1247 
1248   delete pNdb;
1249 
1250   return result;
1251 }
1252 
1253 char pkIdxName[255];
1254 
createPkIndex(NDBT_Context * ctx,NDBT_Step * step)1255 int createPkIndex(NDBT_Context* ctx, NDBT_Step* step){
1256   bool orderedIndex = ctx->getProperty("OrderedIndex", (unsigned)0);
1257 
1258   const NdbDictionary::Table* pTab = ctx->getTab();
1259   Ndb* pNdb = GETNDB(step);
1260 
1261   bool logged = ctx->getProperty("LoggedIndexes", 1);
1262 
1263   // Create index
1264   BaseString::snprintf(pkIdxName, 255, "IDC_PK_%s", pTab->getName());
1265   if (orderedIndex)
1266     ndbout << "Creating " << ((logged)?"logged ": "temporary ") << "ordered index "
1267 	   << pkIdxName << " (";
1268   else
1269     ndbout << "Creating " << ((logged)?"logged ": "temporary ") << "unique index "
1270 	   << pkIdxName << " (";
1271 
1272   NdbDictionary::Index pIdx(pkIdxName);
1273   pIdx.setTable(pTab->getName());
1274   if (orderedIndex)
1275     pIdx.setType(NdbDictionary::Index::OrderedIndex);
1276   else
1277     pIdx.setType(NdbDictionary::Index::UniqueHashIndex);
1278   for (int c = 0; c< pTab->getNoOfColumns(); c++){
1279     const NdbDictionary::Column * col = pTab->getColumn(c);
1280     if(col->getPrimaryKey()){
1281       pIdx.addIndexColumn(col->getName());
1282       ndbout << col->getName() <<" ";
1283     }
1284   }
1285 
1286   pIdx.setStoredIndex(logged);
1287   ndbout << ") ";
1288   if (pNdb->getDictionary()->createIndex(pIdx) != 0){
1289     ndbout << "FAILED!" << endl;
1290     const NdbError err = pNdb->getDictionary()->getNdbError();
1291     ERR(err);
1292     return NDBT_FAILED;
1293   }
1294 
1295   ndbout << "OK!" << endl;
1296   return NDBT_OK;
1297 }
1298 
createPkIndex_Drop(NDBT_Context * ctx,NDBT_Step * step)1299 int createPkIndex_Drop(NDBT_Context* ctx, NDBT_Step* step){
1300   const NdbDictionary::Table* pTab = ctx->getTab();
1301   Ndb* pNdb = GETNDB(step);
1302 
1303   // Drop index
1304   ndbout << "Dropping index " << pkIdxName << " ";
1305   if (pNdb->getDictionary()->dropIndex(pkIdxName,
1306 				       pTab->getName()) != 0){
1307     ndbout << "FAILED!" << endl;
1308     ERR(pNdb->getDictionary()->getNdbError());
1309     return NDBT_FAILED;
1310   } else {
1311     ndbout << "OK!" << endl;
1312   }
1313 
1314   return NDBT_OK;
1315 }
1316 
1317 static
1318 int
op_row(NdbTransaction * pTrans,HugoOperations & hugoOps,const NdbDictionary::Table * pTab,int op,int row)1319 op_row(NdbTransaction* pTrans, HugoOperations& hugoOps,
1320        const NdbDictionary::Table* pTab, int op, int row)
1321 {
1322   NdbOperation * pOp = 0;
1323   switch(op){
1324   case 0:
1325   case 1:
1326   case 2:
1327   case 3:
1328   case 4:
1329   case 5:
1330     pOp = pTrans->getNdbOperation(pTab->getName());
1331     break;
1332   case 9:
1333     return 0;
1334   case 6:
1335   case 7:
1336   case 8:
1337   case 10:
1338   case 11:
1339     pOp = pTrans->getNdbIndexOperation(pkIdxName, pTab->getName());
1340   default:
1341     break;
1342   }
1343 
1344   switch(op){
1345   case 0:
1346   case 6:
1347     pOp->readTuple();
1348     break;
1349   case 1:
1350   case 7:
1351     pOp->committedRead();
1352     break;
1353   case 2:
1354   case 8:
1355     pOp->readTupleExclusive();
1356     break;
1357   case 3:
1358   case 9:
1359     pOp->insertTuple();
1360     break;
1361   case 4:
1362   case 10:
1363     pOp->updateTuple();
1364     break;
1365   case 5:
1366   case 11:
1367     pOp->deleteTuple();
1368     break;
1369   default:
1370     abort();
1371   }
1372 
1373   for(int a = 0; a<pTab->getNoOfColumns(); a++){
1374     if (pTab->getColumn(a)->getPrimaryKey() == true){
1375       if(hugoOps.equalForAttr(pOp, a, row) != 0){
1376 	return NDBT_FAILED;
1377       }
1378     }
1379   }
1380 
1381   switch(op){
1382   case 0:
1383   case 1:
1384   case 2:
1385   case 6:
1386   case 7:
1387   case 8:
1388     for(int a = 0; a<pTab->getNoOfColumns(); a++){
1389       pOp->getValue(a);
1390     }
1391     break;
1392   case 3:
1393   case 4:
1394   case 10:
1395     for(int a = 0; a<pTab->getNoOfColumns(); a++){
1396       if (pTab->getColumn(a)->getPrimaryKey() == false){
1397 	if(hugoOps.setValueForAttr(pOp, a, row, 2) != 0){
1398 	  return NDBT_FAILED;
1399 	}
1400       }
1401     }
1402     break;
1403   case 5:
1404   case 11:
1405     pOp->deleteTuple();
1406     break;
1407   case 9:
1408   default:
1409     abort();
1410   }
1411 
1412   return NDBT_OK;
1413 }
1414 
print(int op)1415 static void print(int op)
1416 {
1417   const char * str = 0;
1418   switch(op){
1419   case 0:  str = "pk read-sh"; break;
1420   case 1:  str = "pk read-nl"; break;
1421   case 2:  str = "pk read-ex"; break;
1422   case 3:  str = "pk insert "; break;
1423   case 4:  str = "pk update "; break;
1424   case 5:  str = "pk delete "; break;
1425   case 6:  str = "uk read-sh"; break;
1426   case 7:  str = "uk read-nl"; break;
1427   case 8:  str = "uk read-ex"; break;
1428   case 9:  str = "noop      "; break;
1429   case 10: str = "uk update "; break;
1430   case 11: str = "uk delete "; break;
1431   default:
1432     abort();
1433   }
1434   printf("%s ", str);
1435 }
1436 
1437 int
runTestIgnoreError(NDBT_Context * ctx,NDBT_Step * step)1438 runTestIgnoreError(NDBT_Context* ctx, NDBT_Step* step)
1439 {
1440   int result = NDBT_OK;
1441   Uint32 loops = ctx->getNumRecords();
1442   const NdbDictionary::Table* pTab = ctx->getTab();
1443 
1444   HugoOperations hugoOps(*pTab);
1445   HugoTransactions hugoTrans(*pTab);
1446 
1447   Ndb* pNdb = GETNDB(step);
1448 
1449   struct {
1450     ExecType et;
1451     AbortOption ao;
1452   } tests[] = {
1453     { Commit, AbortOnError },
1454     { Commit, AO_IgnoreError },
1455     { NoCommit, AbortOnError },
1456     { NoCommit, AO_IgnoreError },
1457   };
1458 
1459   printf("case: <op1>     <op2>       c/nc ao/ie\n");
1460   Uint32 tno = 0;
1461   for (Uint32 op1 = 0; op1 < 12; op1++)
1462   {
1463     for (Uint32 op2 = op1; op2 < 12; op2++)
1464     {
1465       int ret;
1466       NdbTransaction* pTrans = 0;
1467 
1468       for (Uint32 i = 0; i<4; i++, tno++)
1469       {
1470 	if (loops != 1000 && loops != tno)
1471 	  continue;
1472 	ExecType et = tests[i].et;
1473 	AbortOption ao = tests[i].ao;
1474 
1475 	printf("%.3d : ", tno);
1476 	print(op1);
1477 	print(op2);
1478 	switch(et){
1479 	case Commit: printf("c    "); break;
1480 	case NoCommit: printf("nc   "); break;
1481 	}
1482 	switch(ao){
1483 	case AbortOnError: printf("aoe  "); break;
1484 	case AO_IgnoreError: printf("ie   "); break;
1485 	}
1486 	printf(": ");
1487 
1488 
1489 	hugoTrans.loadTable(pNdb, 1);
1490 	pTrans = pNdb->startTransaction();
1491 	op_row(pTrans, hugoOps, pTab, op1, 0);
1492 	ret = pTrans->execute(et, ao);
1493 	pTrans->close();
1494 	printf("%d ", ret);
1495 	hugoTrans.clearTable(pNdb);
1496 
1497 	hugoTrans.loadTable(pNdb, 1);
1498 	pTrans = pNdb->startTransaction();
1499 	op_row(pTrans, hugoOps, pTab, op1, 1);
1500 	ret = pTrans->execute(et, ao);
1501 	pTrans->close();
1502 	printf("%d ", ret);
1503 	hugoTrans.clearTable(pNdb);
1504 
1505 	hugoTrans.loadTable(pNdb, 1);
1506 	pTrans = pNdb->startTransaction();
1507 	op_row(pTrans, hugoOps, pTab, op1, 0);
1508 	op_row(pTrans, hugoOps, pTab, op2, 1);
1509 	ret = pTrans->execute(et, ao);
1510 	pTrans->close();
1511 	printf("%d\n", ret);
1512 	hugoTrans.clearTable(pNdb);
1513 
1514 	hugoTrans.clearTable(pNdb);
1515       }
1516     }
1517   }
1518   return NDBT_OK;
1519 }
1520 
1521 static void
testExecuteAsynchCallback(int res,NdbTransaction * con,void * data_ptr)1522 testExecuteAsynchCallback(int res, NdbTransaction *con, void *data_ptr)
1523 {
1524   int *res_ptr= (int *)data_ptr;
1525 
1526   *res_ptr= res;
1527 }
1528 
runTestExecuteAsynch(NDBT_Context * ctx,NDBT_Step * step)1529 int runTestExecuteAsynch(NDBT_Context* ctx, NDBT_Step* step){
1530   /* Test that NdbTransaction::executeAsynch() works (BUG#27495). */
1531   int result = NDBT_OK;
1532   const NdbDictionary::Table* pTab = ctx->getTab();
1533 
1534   Ndb* pNdb = new Ndb(&ctx->m_cluster_connection, "TEST_DB");
1535   if (pNdb == NULL){
1536     ndbout << "pNdb == NULL" << endl;
1537     return NDBT_FAILED;
1538   }
1539   if (pNdb->init(2048)){
1540     ERR(pNdb->getNdbError());
1541     delete pNdb;
1542     return NDBT_FAILED;
1543   }
1544 
1545   NdbConnection* pCon = pNdb->startTransaction();
1546   if (pCon == NULL){
1547     ERR(pNdb->getNdbError());
1548     delete pNdb;
1549     return NDBT_FAILED;
1550   }
1551 
1552   NdbScanOperation* pOp = pCon->getNdbScanOperation(pTab->getName());
1553   if (pOp == NULL){
1554     ERR(pOp->getNdbError());
1555     pNdb->closeTransaction(pCon);
1556     delete pNdb;
1557     return NDBT_FAILED;
1558   }
1559 
1560   if (pOp->readTuples() != 0){
1561     ERR(pOp->getNdbError());
1562     pNdb->closeTransaction(pCon);
1563     delete pNdb;
1564     return NDBT_FAILED;
1565   }
1566 
1567   if (pOp->getValue(NdbDictionary::Column::FRAGMENT) == 0){
1568     ERR(pOp->getNdbError());
1569     pNdb->closeTransaction(pCon);
1570     delete pNdb;
1571     return NDBT_FAILED;
1572   }
1573   int res= 42;
1574   pCon->executeAsynch(NoCommit, testExecuteAsynchCallback, &res);
1575   while(pNdb->pollNdb(100000) == 0)
1576     ;
1577   if (res != 0){
1578     ERR(pCon->getNdbError());
1579     ndbout << "Error returned from execute: " << res << endl;
1580     result= NDBT_FAILED;
1581   }
1582 
1583   pNdb->closeTransaction(pCon);
1584 
1585   delete pNdb;
1586 
1587   return result;
1588 }
1589 
1590 template class Vector<NdbScanOperation*>;
1591 
1592 int
runBug28443(NDBT_Context * ctx,NDBT_Step * step)1593 runBug28443(NDBT_Context* ctx, NDBT_Step* step)
1594 {
1595   int result = NDBT_OK;
1596   int records = ctx->getNumRecords();
1597 
1598   NdbRestarter restarter;
1599 
1600   restarter.insertErrorInAllNodes(9003);
1601 
1602   for (Uint32 i = 0; i<ctx->getNumLoops(); i++)
1603   {
1604     HugoTransactions hugoTrans(*ctx->getTab());
1605     if (hugoTrans.loadTable(GETNDB(step), records, 2048) != 0)
1606     {
1607       result = NDBT_FAILED;
1608       goto done;
1609     }
1610     if (runClearTable(ctx, step) != 0)
1611     {
1612       result = NDBT_FAILED;
1613       goto done;
1614     }
1615   }
1616 
1617 done:
1618   restarter.insertErrorInAllNodes(9003);
1619 
1620   return result;
1621 }
1622 
1623 NDBT_TESTSUITE(testNdbApi);
1624 TESTCASE("MaxNdb",
1625 	 "Create Ndb objects until no more can be created\n"){
1626   INITIALIZER(runTestMaxNdb);
1627 }
1628 TESTCASE("MaxTransactions",
1629 	 "Start transactions until no more can be created\n"){
1630   INITIALIZER(runTestMaxTransaction);
1631 }
1632 TESTCASE("MaxOperations",
1633 	"Get operations until no more can be created\n"){
1634   INITIALIZER(runLoadTable);
1635   INITIALIZER(runTestMaxOperations);
1636   FINALIZER(runClearTable);
1637 }
1638 TESTCASE("MaxGetValue",
1639 	"Call getValue loads of time\n"){
1640   INITIALIZER(runLoadTable);
1641   INITIALIZER(runTestGetValue);
1642   FINALIZER(runClearTable);
1643 }
1644 TESTCASE("MaxEqual",
1645 	"Call equal loads of time\n"){
1646   INITIALIZER(runTestEqual);
1647 }
1648 TESTCASE("DeleteNdb",
1649 	"Make sure that a deleted Ndb object is properly deleted\n"
1650 	"and removed from transporter\n"){
1651   INITIALIZER(runLoadTable);
1652   INITIALIZER(runTestDeleteNdb);
1653   FINALIZER(runClearTable);
1654 }
1655 TESTCASE("WaitUntilReady",
1656 	"Make sure you get an error message when calling waitUntilReady\n"
1657 	"without an init'ed Ndb\n"){
1658   INITIALIZER(runTestWaitUntilReady);
1659 }
1660 TESTCASE("GetOperationNoTab",
1661 	"Call getNdbOperation on a table that does not exist\n"){
1662   INITIALIZER(runGetNdbOperationNoTab);
1663 }
1664 TESTCASE("MissingOperation",
1665 	"Missing operation request(insertTuple) should give an error code\n"){
1666   INITIALIZER(runMissingOperation);
1667 }
1668 TESTCASE("GetValueInUpdate",
1669 	"Test that it's not possible to perform getValue in an update\n"){
1670   INITIALIZER(runLoadTable);
1671   INITIALIZER(runGetValueInUpdate);
1672   FINALIZER(runClearTable);
1673 }
1674 TESTCASE("UpdateWithoutKeys",
1675 	"Test that it's not possible to perform update without setting\n"
1676 	 "PKs"){
1677   INITIALIZER(runLoadTable);
1678   INITIALIZER(runUpdateWithoutKeys);
1679   FINALIZER(runClearTable);
1680 }
1681 TESTCASE("UpdateWithoutValues",
1682 	"Test that it's not possible to perform update without setValues\n"){
1683   INITIALIZER(runLoadTable);
1684   INITIALIZER(runUpdateWithoutValues);
1685   FINALIZER(runClearTable);
1686 }
1687 TESTCASE("NdbErrorOperation",
1688 	 "Test that NdbErrorOperation is properly set"){
1689   INITIALIZER(runCheckGetNdbErrorOperation);
1690 }
1691 TESTCASE("ReadWithoutGetValue",
1692 	 "Test that it's possible to perform read wo/ getvalue's\n"){
1693   INITIALIZER(runLoadTable);
1694   INITIALIZER(runReadWithoutGetValue);
1695   FINALIZER(runClearTable);
1696 }
1697 TESTCASE("Bug_11133",
1698 	 "Test ReadEx-Delete-Write\n"){
1699   INITIALIZER(runBug_11133);
1700   FINALIZER(runClearTable);
1701 }
1702 TESTCASE("Bug_WritePartialIgnoreError",
1703 	 "Test WritePartialIgnoreError\n"){
1704   INITIALIZER(runBug_WritePartialIgnoreError);
1705   FINALIZER(runClearTable);
1706 }
1707 TESTCASE("Scan_4006",
1708 	 "Check that getNdbScanOperation does not get 4006\n"){
1709   INITIALIZER(runLoadTable);
1710   INITIALIZER(runScan_4006);
1711   FINALIZER(runClearTable);
1712 }
1713 TESTCASE("IgnoreError", ""){
1714   INITIALIZER(createPkIndex);
1715   STEP(runTestIgnoreError);
1716   FINALIZER(runClearTable);
1717   FINALIZER(createPkIndex_Drop);
1718 }
1719 TESTCASE("ExecuteAsynch",
1720 	 "Check that executeAsync() works (BUG#27495)\n"){
1721   INITIALIZER(runTestExecuteAsynch);
1722 }
1723 TESTCASE("Bug28443",
1724 	 ""){
1725   INITIALIZER(runBug28443);
1726 }
1727 NDBT_TESTSUITE_END(testNdbApi);
1728 
main(int argc,const char ** argv)1729 int main(int argc, const char** argv){
1730   ndb_init();
1731   //  TABLE("T1");
1732   return testNdbApi.execute(argc, argv);
1733 }
1734 
1735 template class Vector<Ndb*>;
1736 template class Vector<NdbConnection*>;
1737