1 /*
2    Copyright (c) 2003, 2021, Oracle and/or its affiliates.
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, version 2.0,
6    as published by the Free Software Foundation.
7 
8    This program is also distributed with certain software (including
9    but not limited to OpenSSL) that is licensed under separate terms,
10    as designated in a particular file or component or in included license
11    documentation.  The authors of MySQL hereby grant you an additional
12    permission to link the program and your derivative works with the
13    separately licensed software that they have included with MySQL.
14 
15    This program is distributed in the hope that it will be useful,
16    but WITHOUT ANY WARRANTY; without even the implied warranty of
17    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18    GNU General Public License, version 2.0, for more details.
19 
20    You should have received a copy of the GNU General Public License
21    along with this program; if not, write to the Free Software
22    Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301  USA
23 */
24 
25 #include <NDBT.hpp>
26 #include <NDBT_Test.hpp>
27 #include <HugoTransactions.hpp>
28 #include <UtilTransactions.hpp>
29 #include <NdbRestarter.hpp>
30 #include <NdbRestarts.hpp>
31 #include <Vector.hpp>
32 #include <signaldata/DumpStateOrd.hpp>
33 #include <NodeBitmask.hpp>
34 #include <NdbSqlUtil.hpp>
35 #include <BlockNumbers.h>
36 
37 #define CHECK(b) if (!(b)) { \
38   g_err << "ERR: "<< step->getName() \
39          << " failed on line " << __LINE__ << endl; \
40   result = NDBT_FAILED; break;\
41 }
42 
43 #define CHECKRET(b) if (!(b)) { \
44   g_err << "ERR: "<< step->getName() \
45          << " failed on line " << __LINE__ << endl; \
46   return NDBT_FAILED;                             \
47 }
48 
49 
50 struct Attrib {
51   bool indexCreated;
52   int numAttribs;
53   int attribs[1024];
AttribAttrib54   Attrib(){
55     numAttribs = 0;
56     indexCreated = false;
57   }
58 };
59 
60 class AttribList {
61 public:
AttribList()62   AttribList(){}
~AttribList()63   ~AttribList(){
64     for(unsigned i = 0; i < attriblist.size(); i++){
65       delete attriblist[i];
66     }
67   }
68   void buildAttribList(const NdbDictionary::Table* pTab);
69   Vector<Attrib*> attriblist;
70 };
71 
72 /**
73  * TODO expose in ndbapi
74  */
75 static
76 bool
isIndexable(const NdbDictionary::Column * col)77 isIndexable(const NdbDictionary::Column* col)
78 {
79   if (col == 0)
80     return false;
81 
82   switch(col->getType())
83   {
84   case NDB_TYPE_BIT:
85   case NDB_TYPE_BLOB:
86   case NDB_TYPE_TEXT:
87     return false;
88   default:
89     return true;
90   }
91 }
92 
buildAttribList(const NdbDictionary::Table * pTab)93 void AttribList::buildAttribList(const NdbDictionary::Table* pTab){
94   attriblist.clear();
95 
96   Attrib* attr;
97   // Build attrib definitions that describes which attributes to build index
98   // Try to build strange combinations, not just "all" or all PK's
99 
100   int i;
101 
102   for(i = 1; i <= pTab->getNoOfColumns(); i++){
103     attr = new Attrib;
104     attr->numAttribs = i;
105     for(int a = 0; a<i; a++)
106       attr->attribs[a] = a;
107     attriblist.push_back(attr);
108   }
109   int b = 0;
110   for(i = pTab->getNoOfColumns()-1; i > 0; i--){
111     attr = new Attrib;
112     attr->numAttribs = i;
113     b++;
114     for(int a = 0; a<i; a++)
115       attr->attribs[a] = a+b;
116     attriblist.push_back(attr);
117   }
118   for(i = pTab->getNoOfColumns(); i > 0;  i--){
119     attr = new Attrib;
120     attr->numAttribs = pTab->getNoOfColumns() - i;
121     for(int a = 0; a<pTab->getNoOfColumns() - i; a++)
122       attr->attribs[a] = pTab->getNoOfColumns()-a-1;
123     attriblist.push_back(attr);
124   }
125   for(i = 1; i < pTab->getNoOfColumns(); i++){
126     attr = new Attrib;
127     attr->numAttribs = pTab->getNoOfColumns() - i;
128     for(int a = 0; a<pTab->getNoOfColumns() - i; a++)
129       attr->attribs[a] = pTab->getNoOfColumns()-a-1;
130     attriblist.push_back(attr);
131   }
132   for(i = 1; i < pTab->getNoOfColumns(); i++){
133     attr = new Attrib;
134     attr->numAttribs = 2;
135     for(int a = 0; a<2; a++){
136       attr->attribs[a] = i%pTab->getNoOfColumns();
137     }
138     attriblist.push_back(attr);
139   }
140 
141   // Last
142   attr = new Attrib;
143   attr->numAttribs = 1;
144   attr->attribs[0] = pTab->getNoOfColumns()-1;
145   attriblist.push_back(attr);
146 
147   // Last and first
148   attr = new Attrib;
149   attr->numAttribs = 2;
150   attr->attribs[0] = pTab->getNoOfColumns()-1;
151   attr->attribs[1] = 0;
152   attriblist.push_back(attr);
153 
154   // First and last
155   attr = new Attrib;
156   attr->numAttribs = 2;
157   attr->attribs[0] = 0;
158   attr->attribs[1] = pTab->getNoOfColumns()-1;
159   attriblist.push_back(attr);
160 
161 #if 0
162   for(size_t i = 0; i < attriblist.size(); i++){
163 
164     ndbout << attriblist[i]->numAttribs << ": " ;
165     for(int a = 0; a < attriblist[i]->numAttribs; a++)
166       ndbout << attriblist[i]->attribs[a] << ", ";
167     ndbout << endl;
168   }
169 #endif
170 
171   /**
172    * Trim away combinations that contain non indexable columns
173    */
174   Vector<Attrib*> tmp;
175   for (Uint32 ii = 0; ii < attriblist.size(); ii++)
176   {
177     Attrib* attr = attriblist[ii];
178     for (int j = 0; j < attr->numAttribs; j++)
179     {
180       if (!isIndexable(pTab->getColumn(attr->attribs[j])))
181       {
182         delete attr;
183         goto skip;
184       }
185     }
186 
187     if (attr->numAttribs + pTab->getNoOfPrimaryKeys() >
188         NDB_MAX_ATTRIBUTES_IN_INDEX)
189     {
190       delete attr;
191       goto skip;
192     }
193 
194     tmp.push_back(attr);
195 skip:
196     (void)1;
197   }
198 
199   attriblist.clear();
200   attriblist = tmp;
201 }
202 
203 char idxName[255];
204 char pkIdxName[255];
205 
206 static const int SKIP_INDEX = 99;
207 
create_index(NDBT_Context * ctx,int indxNum,const NdbDictionary::Table * pTab,Ndb * pNdb,Attrib * attr,bool logged)208 int create_index(NDBT_Context* ctx, int indxNum,
209 		 const NdbDictionary::Table* pTab,
210 		 Ndb* pNdb, Attrib* attr, bool logged){
211   bool orderedIndex = ctx->getProperty("OrderedIndex", (unsigned)0);
212   bool notOnlyPkId = ctx->getProperty("NotOnlyPkId", (unsigned)0);
213   int result  = NDBT_OK;
214 
215   HugoCalculator calc(*pTab);
216 
217   if (attr->numAttribs == 1 &&
218       calc.isUpdateCol(attr->attribs[0]) == true){
219     // Don't create index for the Hugo update column
220     // since it's not unique
221     return SKIP_INDEX;
222   }
223 
224   // Create index
225   BaseString::snprintf(idxName, 255, "IDC%d", indxNum);
226   if (orderedIndex)
227     ndbout << "Creating " << ((logged)?"logged ": "temporary ") << "ordered index "<<idxName << " (";
228   else
229     ndbout << "Creating " << ((logged)?"logged ": "temporary ") << "unique index "<<idxName << " (";
230   ndbout << flush;
231   NdbDictionary::Index pIdx(idxName);
232   pIdx.setTable(pTab->getName());
233   if (orderedIndex)
234     pIdx.setType(NdbDictionary::Index::OrderedIndex);
235   else
236     pIdx.setType(NdbDictionary::Index::UniqueHashIndex);
237 
238   bool includesOnlyPkIdCols = true;
239   for (int c = 0; c< attr->numAttribs; c++){
240     int attrNo = attr->attribs[c];
241     const NdbDictionary::Column* col = pTab->getColumn(attrNo);
242     switch(col->getType())
243     {
244     case NDB_TYPE_BIT:
245     case NDB_TYPE_BLOB:
246     case NDB_TYPE_TEXT:
247       /* Not supported */
248       ndbout << col->getName() << " - bad type )" << endl;
249       return SKIP_INDEX;
250     default:
251       break;
252     }
253     if (col->getStorageType() == NDB_STORAGETYPE_DISK)
254     {
255       ndbout << col->getName() << " - disk based )" << endl;
256       return SKIP_INDEX;
257     }
258 
259     pIdx.addIndexColumn(col->getName());
260     ndbout << col->getName()<<" ";
261 
262     if (! (col->getPrimaryKey() ||
263            calc.isIdCol(attrNo)))
264       includesOnlyPkIdCols = false;
265   }
266 
267   if (notOnlyPkId && includesOnlyPkIdCols)
268   {
269     ndbout << " Only PK/id cols included - skipping" << endl;
270     return SKIP_INDEX;
271   }
272 
273   if (!orderedIndex)
274   {
275     /**
276      * For unique indexes we must add PK, otherwise it's not guaranteed
277      *  to be unique
278      */
279     for (int i = 0; i<pTab->getNoOfColumns(); i++)
280     {
281       if (pTab->getColumn(i)->getPrimaryKey())
282       {
283         for (int j = 0; j<attr->numAttribs; j++)
284         {
285           if (attr->attribs[j] == i)
286             goto next;
287         }
288         pIdx.addIndexColumn(pTab->getColumn(i)->getName());
289         ndbout << pTab->getColumn(i)->getName() << " ";
290       }
291   next:
292       (void)i;
293     }
294   }
295 
296   pIdx.setStoredIndex(logged);
297   ndbout << ") ";
298   bool noddl= ctx->getProperty("NoDDL");
299 
300   if (noddl)
301   {
302     const NdbDictionary::Index* idx= pNdb->
303       getDictionary()->getIndex(pIdx.getName(), pTab->getName());
304 
305     if (!idx)
306     {
307       ndbout << "Failed - Index does not exist and DDL not allowed" << endl;
308       return NDBT_FAILED;
309     }
310     else
311     {
312       attr->indexCreated = false;
313       // TODO : Check index definition is ok
314     }
315   }
316   else
317   {
318     if (pNdb->getDictionary()->createIndex(pIdx) != 0){
319       attr->indexCreated = false;
320       ndbout << "FAILED!" << endl;
321       const NdbError err = pNdb->getDictionary()->getNdbError();
322       NDB_ERR(err);
323       if (err.classification == NdbError::ApplicationError)
324         return SKIP_INDEX;
325 
326       if (err.status == NdbError::TemporaryError)
327         return SKIP_INDEX;
328 
329       return NDBT_FAILED;
330     } else {
331       ndbout << "OK!" << endl;
332       attr->indexCreated = true;
333     }
334   }
335   return result;
336 }
337 
338 
drop_index(int indxNum,Ndb * pNdb,const NdbDictionary::Table * pTab,Attrib * attr)339 int drop_index(int indxNum, Ndb* pNdb,
340 	       const NdbDictionary::Table* pTab, Attrib* attr){
341   int result = NDBT_OK;
342 
343   if (attr->indexCreated == false)
344     return NDBT_OK;
345 
346   BaseString::snprintf(idxName, 255, "IDC%d", indxNum);
347 
348   // Drop index
349   ndbout << "Dropping index "<<idxName<<"(" << pTab->getName() << ") ";
350   if (pNdb->getDictionary()->dropIndex(idxName, pTab->getName()) != 0){
351     ndbout << "FAILED!" << endl;
352     NDB_ERR(pNdb->getDictionary()->getNdbError());
353     result = NDBT_FAILED;
354   } else {
355     ndbout << "OK!" << endl;
356   }
357   return result;
358 }
359 
runCreateIndexes(NDBT_Context * ctx,NDBT_Step * step)360 int runCreateIndexes(NDBT_Context* ctx, NDBT_Step* step){
361   int loops = ctx->getNumLoops();
362   int l = 0;
363   const NdbDictionary::Table* pTab = ctx->getTab();
364   Ndb* pNdb = GETNDB(step);
365   int result = NDBT_OK;
366   // NOTE If we need to test creating both logged and non logged indexes
367   // this should be divided into two testcases
368   // The paramater logged should then be specified
369   // as a TC_PROPERTY. ex TC_PROPERTY("LoggedIndexes", 1);
370   // and read into the test step like
371   bool logged = ctx->getProperty("LoggedIndexes", 1);
372 
373   AttribList attrList;
374   attrList.buildAttribList(pTab);
375 
376 
377   while (l < loops && result == NDBT_OK){
378     unsigned int i;
379     for (i = 0; i < attrList.attriblist.size(); i++){
380 
381       // Try to create index
382       if (create_index(ctx, i, pTab, pNdb, attrList.attriblist[i], logged) == NDBT_FAILED)
383 	result = NDBT_FAILED;
384     }
385 
386     // Now drop all indexes that where created
387     for (i = 0; i < attrList.attriblist.size(); i++){
388 
389       // Try to drop index
390       if (drop_index(i, pNdb, pTab, attrList.attriblist[i]) != NDBT_OK)
391 	result = NDBT_FAILED;
392     }
393 
394     l++;
395   }
396 
397   return result;
398 }
399 
createRandomIndex(NDBT_Context * ctx,NDBT_Step * step)400 int createRandomIndex(NDBT_Context* ctx, NDBT_Step* step){
401   const NdbDictionary::Table* pTab = ctx->getTab();
402   Ndb* pNdb = GETNDB(step);
403   bool logged = ctx->getProperty("LoggedIndexes", 1);
404 
405   AttribList attrList;
406   attrList.buildAttribList(pTab);
407 
408   int retries = 100;
409   while(retries > 0){
410     const Uint32 i = rand() % attrList.attriblist.size();
411     int res = create_index(ctx, i, pTab, pNdb, attrList.attriblist[i],
412 			   logged);
413     if (res == SKIP_INDEX){
414       retries--;
415       continue;
416     }
417 
418     if (res == NDBT_FAILED){
419       return NDBT_FAILED;
420     }
421 
422     ctx->setProperty("createRandomIndex", i);
423     // Now drop all indexes that where created
424 
425     return NDBT_OK;
426   }
427 
428   return NDBT_FAILED;
429 }
430 
createRandomIndex_Drop(NDBT_Context * ctx,NDBT_Step * step)431 int createRandomIndex_Drop(NDBT_Context* ctx, NDBT_Step* step){
432   Ndb* pNdb = GETNDB(step);
433 
434   Uint32 i = ctx->getProperty("createRandomIndex");
435 
436   BaseString::snprintf(idxName, 255, "IDC%d", i);
437 
438   // Drop index
439   ndbout << "Dropping index " << idxName << " ";
440   if (pNdb->getDictionary()->dropIndex(idxName,
441 				       ctx->getTab()->getName()) != 0){
442     ndbout << "FAILED!" << endl;
443     NDB_ERR(pNdb->getDictionary()->getNdbError());
444     return NDBT_FAILED;
445   } else {
446     ndbout << "OK!" << endl;
447   }
448 
449   return NDBT_OK;
450 }
451 
createPkIndex(NDBT_Context * ctx,NDBT_Step * step)452 int createPkIndex(NDBT_Context* ctx, NDBT_Step* step){
453   bool orderedIndex = ctx->getProperty("OrderedIndex", (unsigned)0);
454 
455   const NdbDictionary::Table* pTab = ctx->getTab();
456   Ndb* pNdb = GETNDB(step);
457 
458   bool logged = ctx->getProperty("LoggedIndexes", 1);
459   bool noddl= ctx->getProperty("NoDDL");
460 
461   // Create index
462   BaseString::snprintf(pkIdxName, 255, "IDC_PK_%s", pTab->getName());
463   if (orderedIndex)
464     ndbout << "Creating " << ((logged)?"logged ": "temporary ") << "ordered index "
465 	   << pkIdxName << " (";
466   else
467     ndbout << "Creating " << ((logged)?"logged ": "temporary ") << "unique index "
468 	   << pkIdxName << " (";
469 
470   NdbDictionary::Index pIdx(pkIdxName);
471   pIdx.setTable(pTab->getName());
472   if (orderedIndex)
473     pIdx.setType(NdbDictionary::Index::OrderedIndex);
474   else
475     pIdx.setType(NdbDictionary::Index::UniqueHashIndex);
476   for (int c = 0; c< pTab->getNoOfColumns(); c++){
477     const NdbDictionary::Column * col = pTab->getColumn(c);
478     if(col->getPrimaryKey()){
479       pIdx.addIndexColumn(col->getName());
480       ndbout << col->getName() <<" ";
481     }
482   }
483 
484   pIdx.setStoredIndex(logged);
485   ndbout << ") ";
486   if (noddl)
487   {
488     const NdbDictionary::Index* idx= pNdb->
489       getDictionary()->getIndex(pkIdxName, pTab->getName());
490 
491     if (!idx)
492     {
493       ndbout << "Failed - Index does not exist and DDL not allowed" << endl;
494       NDB_ERR(pNdb->getDictionary()->getNdbError());
495       return NDBT_FAILED;
496     }
497     else
498     {
499       // TODO : Check index definition is ok
500     }
501   }
502   else
503   {
504     if (pNdb->getDictionary()->createIndex(pIdx) != 0){
505       ndbout << "FAILED!" << endl;
506       const NdbError err = pNdb->getDictionary()->getNdbError();
507       NDB_ERR(err);
508       return NDBT_FAILED;
509     }
510   }
511 
512   ndbout << "OK!" << endl;
513   return NDBT_OK;
514 }
515 
createPkIndex_Drop(NDBT_Context * ctx,NDBT_Step * step)516 int createPkIndex_Drop(NDBT_Context* ctx, NDBT_Step* step){
517   const NdbDictionary::Table* pTab = ctx->getTab();
518   Ndb* pNdb = GETNDB(step);
519 
520   bool noddl= ctx->getProperty("NoDDL");
521 
522   // Drop index
523   if (!noddl)
524   {
525     ndbout << "Dropping index " << pkIdxName << " ";
526     if (pNdb->getDictionary()->dropIndex(pkIdxName,
527                                          pTab->getName()) != 0){
528       ndbout << "FAILED!" << endl;
529       NDB_ERR(pNdb->getDictionary()->getNdbError());
530       return NDBT_FAILED;
531     } else {
532       ndbout << "OK!" << endl;
533     }
534   }
535 
536   return NDBT_OK;
537 }
538 
539 int
runVerifyIndex(NDBT_Context * ctx,NDBT_Step * step)540 runVerifyIndex(NDBT_Context* ctx, NDBT_Step* step){
541   // Verify that data in index match
542   // table data
543   Ndb* pNdb = GETNDB(step);
544   UtilTransactions utilTrans(*ctx->getTab());
545   const int batchSize = ctx->getProperty("BatchSize", 16);
546   const int parallelism = batchSize > 240 ? 240 : batchSize;
547 
548   do {
549     if (utilTrans.verifyIndex(pNdb, idxName, parallelism, true) != 0){
550       g_err << "Inconsistent index" << endl;
551       return NDBT_FAILED;
552     }
553   } while(ctx->isTestStopped() == false);
554   return NDBT_OK;
555 }
556 
557 int
runTransactions1(NDBT_Context * ctx,NDBT_Step * step)558 runTransactions1(NDBT_Context* ctx, NDBT_Step* step){
559   // Verify that data in index match
560   // table data
561   Ndb* pNdb = GETNDB(step);
562   HugoTransactions hugoTrans(*ctx->getTab());
563   const int batchSize = ctx->getProperty("BatchSize", 50);
564 
565   int rows = ctx->getNumRecords();
566   while (ctx->isTestStopped() == false) {
567     if (hugoTrans.pkUpdateRecords(pNdb, rows, batchSize) != 0){
568       g_err << "Updated table failed" << endl;
569       return NDBT_FAILED;
570     }
571 
572     ctx->sync_down("PauseThreads");
573     if(ctx->isTestStopped())
574       break;
575 
576     if (hugoTrans.scanUpdateRecords(pNdb, rows, batchSize) != 0){
577       g_err << "Updated table failed" << endl;
578       return NDBT_FAILED;
579     }
580 
581     ctx->sync_down("PauseThreads");
582   }
583   return NDBT_OK;
584 }
585 
586 int
runTransactions2(NDBT_Context * ctx,NDBT_Step * step)587 runTransactions2(NDBT_Context* ctx, NDBT_Step* step){
588   // Verify that data in index match
589   // table data
590   Ndb* pNdb = GETNDB(step);
591   HugoTransactions hugoTrans(*ctx->getTab());
592   const int batchSize = ctx->getProperty("BatchSize", 50);
593 
594   int rows = ctx->getNumRecords();
595   while (ctx->isTestStopped() == false) {
596 #if 1
597     if (hugoTrans.indexReadRecords(pNdb, pkIdxName, rows, batchSize) != 0){
598       g_err << "Index read failed" << endl;
599       return NDBT_FAILED;
600     }
601 #endif
602     ctx->sync_down("PauseThreads");
603     if(ctx->isTestStopped())
604       break;
605 #if 1
606     if (hugoTrans.indexUpdateRecords(pNdb, pkIdxName, rows, batchSize) != 0){
607       g_err << "Index update failed" << endl;
608       return NDBT_FAILED;
609     }
610 #endif
611     ctx->sync_down("PauseThreads");
612   }
613   return NDBT_OK;
614 }
615 
616 int
runTransactions3(NDBT_Context * ctx,NDBT_Step * step)617 runTransactions3(NDBT_Context* ctx, NDBT_Step* step){
618   // Verify that data in index match
619   // table data
620   Ndb* pNdb = GETNDB(step);
621   HugoTransactions hugoTrans(*ctx->getTab());
622   UtilTransactions utilTrans(*ctx->getTab());
623   const int batchSize = ctx->getProperty("BatchSize", 32);
624   const int parallel = batchSize > 240 ? 240 : batchSize;
625 
626   int rows = ctx->getNumRecords();
627   while (ctx->isTestStopped() == false) {
628     if(hugoTrans.loadTable(pNdb, rows, batchSize, false) != 0){
629       g_err << "Load table failed" << endl;
630       return NDBT_FAILED;
631     }
632     ctx->sync_down("PauseThreads");
633     if(ctx->isTestStopped())
634       break;
635 
636     if (hugoTrans.pkUpdateRecords(pNdb, rows, batchSize) != 0){
637       g_err << "Updated table failed" << endl;
638       return NDBT_FAILED;
639     }
640 
641     ctx->sync_down("PauseThreads");
642     if(ctx->isTestStopped())
643       break;
644 
645     if (hugoTrans.indexReadRecords(pNdb, pkIdxName, rows, batchSize) != 0){
646       g_err << "Index read failed" << endl;
647       return NDBT_FAILED;
648     }
649 
650     ctx->sync_down("PauseThreads");
651     if(ctx->isTestStopped())
652       break;
653 
654     if (hugoTrans.indexUpdateRecords(pNdb, pkIdxName, rows, batchSize) != 0){
655       g_err << "Index update failed" << endl;
656       return NDBT_FAILED;
657     }
658 
659     ctx->sync_down("PauseThreads");
660     if(ctx->isTestStopped())
661       break;
662 
663     if (hugoTrans.scanUpdateRecords(pNdb, rows, 5, parallel) != 0){
664       g_err << "Scan updated table failed" << endl;
665       return NDBT_FAILED;
666     }
667 
668     ctx->sync_down("PauseThreads");
669     if(ctx->isTestStopped())
670       break;
671 
672     if (utilTrans.verifyIndex(pNdb, idxName, parallel) != 0){
673       g_err << "Inconsistent index" << endl;
674       return NDBT_FAILED;
675     }
676     if(utilTrans.clearTable(pNdb, rows, parallel) != 0){
677       g_err << "Clear table failed" << endl;
678       return NDBT_FAILED;
679     }
680     if (utilTrans.verifyIndex(pNdb, idxName, parallel) != 0){
681       g_err << "Inconsistent index" << endl;
682       return NDBT_FAILED;
683     }
684 
685     ctx->sync_down("PauseThreads");
686     if(ctx->isTestStopped())
687       break;
688 
689     int count = -1;
690     if(utilTrans.selectCount(pNdb, 64, &count) != 0 || count != 0)
691       return NDBT_FAILED;
692     ctx->sync_down("PauseThreads");
693   }
694   return NDBT_OK;
695 }
696 
runRestarts(NDBT_Context * ctx,NDBT_Step * step)697 int runRestarts(NDBT_Context* ctx, NDBT_Step* step){
698   int result = NDBT_OK;
699   int loops = ctx->getNumLoops();
700   NDBT_TestCase* pCase = ctx->getCase();
701   NdbRestarts restarts;
702   int i = 0;
703   int timeout = 240;
704   int sync_threads = ctx->getProperty("Threads", (unsigned)0);
705 
706   while(i<loops && result != NDBT_FAILED && !ctx->isTestStopped()){
707     if(restarts.executeRestart(ctx, "RestartRandomNodeAbort", timeout) != 0){
708       g_err << "Failed to executeRestart(" <<pCase->getName() <<")" << endl;
709       result = NDBT_FAILED;
710       break;
711     }
712     ctx->sync_up_and_wait("PauseThreads", sync_threads);
713     i++;
714   }
715   ctx->stopTest();
716   return result;
717 }
718 
runCreateLoadDropIndex(NDBT_Context * ctx,NDBT_Step * step)719 int runCreateLoadDropIndex(NDBT_Context* ctx, NDBT_Step* step){
720   int loops = ctx->getNumLoops();
721   int records = ctx->getNumRecords();
722   int l = 0;
723   const NdbDictionary::Table* pTab = ctx->getTab();
724   Ndb* pNdb = GETNDB(step);
725   int result = NDBT_OK;
726   int batchSize = ctx->getProperty("BatchSize", 1);
727   int parallelism = batchSize > 240? 240: batchSize;
728   ndbout << "batchSize="<<batchSize<<endl;
729   bool logged = ctx->getProperty("LoggedIndexes", 1);
730 
731   HugoTransactions hugoTrans(*pTab);
732   UtilTransactions utilTrans(*pTab);
733   AttribList attrList;
734   attrList.buildAttribList(pTab);
735 
736   for (unsigned int i = 0; i < attrList.attriblist.size(); i++){
737 
738     while (l < loops && result == NDBT_OK){
739 
740       if ((l % 2) == 0){
741 	// Create index first and then load
742 
743 	// Try to create index
744 	if (create_index(ctx, i, pTab, pNdb, attrList.attriblist[i], logged) == NDBT_FAILED){
745 	  result = NDBT_FAILED;
746 	}
747 
748 	// Load the table with data
749 	ndbout << "Loading data after" << endl;
750 	CHECK(hugoTrans.loadTable(pNdb, records, batchSize) == 0);
751 
752 
753       } else {
754 	// Load table then create index
755 
756 	// Load the table with data
757 	ndbout << "Loading data before" << endl;
758 	CHECK(hugoTrans.loadTable(pNdb, records, batchSize) == 0);
759 
760 	// Try to create index
761 	if (create_index(ctx, i, pTab, pNdb, attrList.attriblist[i], logged) == NDBT_FAILED)
762 	  result = NDBT_FAILED;
763 
764       }
765 
766       // Verify that data in index match
767       // table data
768       CHECK(utilTrans.verifyIndex(pNdb, idxName, parallelism) == 0);
769 
770       // Do it all...
771       ndbout <<"Doing it all"<<endl;
772       int count;
773       ndbout << "  pkUpdateRecords" << endl;
774       CHECK(hugoTrans.pkUpdateRecords(pNdb, records, batchSize) == 0);
775       CHECK(utilTrans.verifyIndex(pNdb, idxName, parallelism) == 0);
776       CHECK(hugoTrans.pkUpdateRecords(pNdb, records, batchSize) == 0);
777       CHECK(utilTrans.verifyIndex(pNdb, idxName, parallelism) == 0);
778       ndbout << "  pkDelRecords half" << endl;
779       CHECK(hugoTrans.pkDelRecords(pNdb, records/2, batchSize) == 0);
780       CHECK(utilTrans.verifyIndex(pNdb, idxName, parallelism) == 0);
781       ndbout << "  scanUpdateRecords" << endl;
782       CHECK(hugoTrans.scanUpdateRecords(pNdb, records/2, parallelism) == 0);
783       CHECK(utilTrans.verifyIndex(pNdb, idxName, parallelism) == 0);
784       ndbout << "  clearTable" << endl;
785       CHECK(utilTrans.clearTable(pNdb, records/2, parallelism) == 0);
786       CHECK(utilTrans.verifyIndex(pNdb, idxName, parallelism) == 0);
787       CHECK(utilTrans.selectCount(pNdb, 64, &count) == 0);
788       CHECK(count == 0);
789       ndbout << "  loadTable" << endl;
790       CHECK(hugoTrans.loadTable(pNdb, records, batchSize) == 0);
791       CHECK(utilTrans.verifyIndex(pNdb, idxName, parallelism) == 0);
792       ndbout << "  loadTable again" << endl;
793       CHECK(hugoTrans.loadTable(pNdb, records, batchSize) == 0);
794       CHECK(utilTrans.verifyIndex(pNdb, idxName, parallelism) == 0);
795       CHECK(utilTrans.selectCount(pNdb, 64, &count) == 0);
796       CHECK(count == records);
797 
798 
799       if ((l % 2) == 0){
800 	// Drop index first and then clear
801 
802 	// Try to create index
803 	if (drop_index(i, pNdb, pTab, attrList.attriblist[i]) != NDBT_OK){
804 	  result = NDBT_FAILED;
805 	}
806 
807 	// Clear table
808 	ndbout << "Clearing table after" << endl;
809 	CHECK(hugoTrans.clearTable(pNdb, records, parallelism) == 0);
810 
811 
812       } else {
813 	// Clear table then drop index
814 
815 	//Clear table
816 	ndbout << "Clearing table before" << endl;
817 	CHECK(hugoTrans.clearTable(pNdb, records, parallelism) == 0);
818 
819 	// Try to drop index
820 	if (drop_index(i, pNdb, pTab, attrList.attriblist[i]) != NDBT_OK)
821 	  result = NDBT_FAILED;
822       }
823 
824       ndbout << "  Done!" << endl;
825       l++;
826     }
827 
828     // Make sure index is dropped
829     drop_index(i, pNdb, pTab, attrList.attriblist[i]);
830 
831   }
832 
833   return result;
834 }
835 
runInsertDelete(NDBT_Context * ctx,NDBT_Step * step)836 int runInsertDelete(NDBT_Context* ctx, NDBT_Step* step){
837   int loops = ctx->getNumLoops();
838   int records = ctx->getNumRecords();
839   const NdbDictionary::Table* pTab = ctx->getTab();
840   Ndb* pNdb = GETNDB(step);
841   int result = NDBT_OK;
842   int batchSize = ctx->getProperty("BatchSize", 1);
843   int parallelism = batchSize > 240? 240: batchSize;
844   ndbout << "batchSize="<<batchSize<<endl;
845   bool logged = ctx->getProperty("LoggedIndexes", 1);
846 
847   HugoTransactions hugoTrans(*pTab);
848   UtilTransactions utilTrans(*pTab);
849 
850   AttribList attrList;
851   attrList.buildAttribList(pTab);
852 
853   for (unsigned int i = 0; i < attrList.attriblist.size(); i++){
854 
855     Attrib* attr = attrList.attriblist[i];
856     // Create index
857     if (create_index(ctx, i, pTab, pNdb, attr, logged) == NDBT_OK){
858       int l = 1;
859       while (l <= loops && result == NDBT_OK){
860 
861 	CHECK(hugoTrans.loadTable(pNdb, records, batchSize) == 0);
862 	CHECK(utilTrans.verifyIndex(pNdb, idxName, parallelism) == 0);
863 	CHECK(utilTrans.clearTable(pNdb, records, parallelism) == 0);
864 	CHECK(utilTrans.verifyIndex(pNdb, idxName, parallelism) == 0);
865 	l++;
866       }
867 
868       // Drop index
869       if (drop_index(i, pNdb, pTab, attr) != NDBT_OK)
870 	result = NDBT_FAILED;
871     }
872   }
873 
874   return result;
875 }
876 
tryAddUniqueIndex(Ndb * pNdb,const NdbDictionary::Table * pTab,const char * idxName,HugoCalculator & calc,int & chosenCol)877 int tryAddUniqueIndex(Ndb* pNdb,
878                       const NdbDictionary::Table* pTab,
879                       const char* idxName,
880                       HugoCalculator& calc,
881                       int& chosenCol)
882 {
883   for(int c = 0; c < pTab->getNoOfColumns(); c++)
884   {
885     const NdbDictionary::Column* col = pTab->getColumn(c);
886 
887     if (!col->getPrimaryKey() &&
888         !calc.isUpdateCol(c) &&
889         !col->getNullable() &&
890         col->getStorageType() != NDB_STORAGETYPE_DISK)
891     {
892       chosenCol = c;
893       break;
894     }
895   }
896 
897   if (chosenCol == -1)
898   {
899     return 1;
900   }
901 
902 
903   /* Create unique index on chosen column */
904 
905   const char* colName = pTab->getColumn(chosenCol)->getName();
906   ndbout << "Creating unique index :" << idxName << " on ("
907          << colName << ")" << endl;
908 
909   NdbDictionary::Index idxDef(idxName);
910   idxDef.setTable(pTab->getName());
911   idxDef.setType(NdbDictionary::Index::UniqueHashIndex);
912 
913   idxDef.addIndexColumn(colName);
914   idxDef.setStoredIndex(false);
915 
916   if (pNdb->getDictionary()->createIndex(idxDef) != 0)
917   {
918     ndbout << "FAILED!" << endl;
919     const NdbError err = pNdb->getDictionary()->getNdbError();
920     NDB_ERR(err);
921     return -1;
922   }
923 
924   return 0;
925 }
926 
tryInsertUniqueRecord(NDBT_Step * step,HugoOperations & hugoOps,int & recordNum)927 int tryInsertUniqueRecord(NDBT_Step* step,
928                           HugoOperations& hugoOps,
929                           int& recordNum)
930 {
931   Ndb* pNdb = GETNDB(step);
932   do
933   {
934     CHECKRET(hugoOps.startTransaction(pNdb) == 0);
935     CHECKRET(hugoOps.pkInsertRecord(pNdb,
936                                     recordNum,
937                                     1,  // NumRecords
938                                     0)  // UpdatesValue
939              == 0);
940     if (hugoOps.execute_Commit(pNdb) != 0)
941     {
942       NdbError err = hugoOps.getTransaction()->getNdbError();
943       hugoOps.closeTransaction(pNdb);
944       if (err.code == 839)
945       {
946         /* Unique constraint violation, try again with
947          * different record
948          */
949         recordNum++;
950         continue;
951       }
952       else
953       {
954         NDB_ERR(err);
955         return NDBT_FAILED;
956       }
957     }
958 
959     hugoOps.closeTransaction(pNdb);
960     break;
961   } while (true);
962 
963   return NDBT_OK;
964 }
965 
966 
runConstraintDetails(NDBT_Context * ctx,NDBT_Step * step)967 int runConstraintDetails(NDBT_Context* ctx, NDBT_Step* step)
968 {
969   const NdbDictionary::Table* pTab = ctx->getTab();
970   Ndb* pNdb = GETNDB(step);
971 
972   /* Steps in testcase
973    * 1) Choose a column to index - not pk or updates column
974    * 2) Insert a couple of unique rows
975    * 3) For a number of different batch sizes :
976    *    i)  Insert a row with a conflicting values
977    *    ii) Update an existing row with a conflicting value
978    *    Verify :
979    *    - The correct error is received
980    *    - The failing constraint is detected
981    *    - The error details string is as expected.
982    */
983   HugoCalculator calc(*pTab);
984 
985   /* Choose column to add unique index to */
986 
987   int chosenCol = -1;
988   const char* idxName = "constraintCheck";
989 
990   int rc = tryAddUniqueIndex(pNdb, pTab, idxName, calc, chosenCol);
991 
992   if (rc)
993   {
994     if (rc == 1)
995     {
996       ndbout << "No suitable column in this table, skipping" << endl;
997       return NDBT_OK;
998     }
999     return NDBT_FAILED;
1000   }
1001 
1002   const NdbDictionary::Index* pIdx =
1003     pNdb->getDictionary()->getIndex(idxName, pTab->getName());
1004   CHECKRET(pIdx != 0);
1005 
1006 
1007   /* Now insert a couple of rows */
1008 
1009   HugoOperations hugoOps(*pTab);
1010   int firstRecordNum = 0;
1011   CHECKRET(tryInsertUniqueRecord(step, hugoOps, firstRecordNum) == NDBT_OK);
1012   int secondRecordNum = firstRecordNum + 1;
1013   CHECKRET(tryInsertUniqueRecord(step, hugoOps, secondRecordNum) == NDBT_OK);
1014 
1015 
1016   /* Now we'll attempt to insert/update records
1017    * in various sized batches and check the errors which
1018    * are returned
1019    */
1020 
1021   int maxBatchSize = 10;
1022   int recordOffset = secondRecordNum + 1;
1023   char buff[NDB_MAX_TUPLE_SIZE];
1024   Uint32 real_len;
1025   CHECKRET(calc.calcValue(firstRecordNum, chosenCol, 0, &buff[0],
1026                           pTab->getColumn(chosenCol)->getSizeInBytes(),
1027                           &real_len) != 0);
1028 
1029   for (int optype = 0; optype < 2; optype ++)
1030   {
1031     bool useInsert = (optype == 0);
1032     ndbout << "Verifying constraint violation for "
1033            << (useInsert?"Insert":"Update")
1034            << " operations" << endl;
1035 
1036     for (int batchSize = 1; batchSize <= maxBatchSize; batchSize++)
1037     {
1038       NdbTransaction* trans = pNdb->startTransaction();
1039       CHECKRET(trans != 0);
1040 
1041       for (int rows = 0; rows < batchSize; rows ++)
1042       {
1043         int rowId = recordOffset + rows;
1044         NdbOperation* op = trans->getNdbOperation(pTab);
1045         CHECKRET(op != 0);
1046         if (useInsert)
1047         {
1048           CHECKRET(op->insertTuple() == 0);
1049 
1050           CHECKRET(hugoOps.setValues(op, rowId, 0) == 0);
1051 
1052           /* Now override setValue for the indexed column to cause
1053            * constraint violation
1054            */
1055           CHECKRET(op->setValue(chosenCol, &buff[0], real_len) == 0);
1056         }
1057         else
1058         {
1059           /* Update value of 'second' row to conflict with
1060            * first
1061            */
1062           CHECKRET(op->updateTuple() == 0);
1063           CHECKRET(hugoOps.equalForRow(op, secondRecordNum) == 0);
1064 
1065           CHECKRET(op->setValue(chosenCol, &buff[0], real_len) == 0);
1066         }
1067       }
1068 
1069       CHECKRET(trans->execute(Commit) == -1);
1070 
1071       NdbError err = trans->getNdbError();
1072 
1073       NDB_ERR(err);
1074 
1075       CHECKRET(err.code == 893);
1076 
1077       /* Ugliness - current NdbApi puts index schema object id
1078        * as abs. value of char* in NdbError struct
1079        */
1080 
1081       int idxObjId = (int) ((UintPtr) err.details - UintPtr(0));
1082       char detailsBuff[100];
1083       const char* errIdxName = NULL;
1084 
1085       ndbout_c("Got details column val of %p and string of %s\n",
1086                err.details, pNdb->getNdbErrorDetail(err,
1087                                                     &detailsBuff[0],
1088                                                     100));
1089       if (idxObjId == pIdx->getObjectId())
1090       {
1091         /* Insert / update failed on the constraint we added */
1092         errIdxName = pIdx->getName();
1093       }
1094       else
1095       {
1096         /* We failed on a different constraint.
1097          * Some NDBT tables already have constraints (e.g. I3)
1098          * Check that the failing constraint contains our column
1099          */
1100         NdbDictionary::Dictionary::List tableIndices;
1101 
1102         CHECKRET(pNdb->getDictionary()->listIndexes(tableIndices,
1103                                                     pTab->getName()) == 0);
1104 
1105         bool ok = false;
1106         for (unsigned ind = 0; ind < tableIndices.count; ind ++)
1107         {
1108           if (tableIndices.elements[ind].id == (unsigned) idxObjId)
1109           {
1110             const char* otherIdxName = tableIndices.elements[ind].name;
1111             ndbout << "Found other violated constraint : " << otherIdxName << endl;
1112             const NdbDictionary::Index* otherIndex =
1113               pNdb->getDictionary()->getIndex(otherIdxName,
1114                                               pTab->getName());
1115             CHECKRET(otherIndex != NULL);
1116 
1117             for (unsigned col = 0; col < otherIndex->getNoOfColumns(); col++)
1118             {
1119               if (strcmp(otherIndex->getColumn(col)->getName(),
1120                          pTab->getColumn(chosenCol)->getName()) == 0)
1121               {
1122                 /* Found our column in the index */
1123                 ok = true;
1124                 errIdxName = otherIndex->getName();
1125                 break;
1126               }
1127             }
1128 
1129             if (ok)
1130             {
1131               ndbout << "  Constraint contains unique column " << endl;
1132               break;
1133             }
1134             ndbout << "  Constraint does not contain unique col - fail" << endl;
1135             CHECKRET(false);
1136           }
1137         }
1138 
1139         if (!ok)
1140         {
1141           ndbout << "Did not find violated constraint" << endl;
1142           CHECKRET(false);
1143         }
1144       }
1145 
1146       /* Finally verify the name returned is :
1147        * <db>/<schema>/<table>/<index>
1148        */
1149       BaseString expected;
1150 
1151       expected.assfmt("%s/%s/%s/%s",
1152                       pNdb->getDatabaseName(),
1153                       pNdb->getSchemaName(),
1154                       pTab->getName(),
1155                       errIdxName);
1156 
1157       CHECKRET(strcmp(expected.c_str(), &detailsBuff[0]) == 0);
1158 
1159       ndbout << " OK " << endl;
1160 
1161       trans->close();
1162     }
1163   }
1164 
1165   return NDBT_OK;
1166 }
1167 
runLoadTable(NDBT_Context * ctx,NDBT_Step * step)1168 int runLoadTable(NDBT_Context* ctx, NDBT_Step* step){
1169   int records = ctx->getNumRecords();
1170 
1171   HugoTransactions hugoTrans(*ctx->getTab());
1172   int batchSize = ctx->getProperty("BatchSize", 1);
1173   if(hugoTrans.loadTable(GETNDB(step), records, batchSize) != 0){
1174     return NDBT_FAILED;
1175   }
1176   return NDBT_OK;
1177 }
1178 
1179 
runClearTable(NDBT_Context * ctx,NDBT_Step * step)1180 int runClearTable(NDBT_Context* ctx, NDBT_Step* step){
1181   int records = ctx->getNumRecords();
1182 
1183   UtilTransactions utilTrans(*ctx->getTab());
1184   if (utilTrans.clearTable(GETNDB(step),  records) != 0){
1185     return NDBT_FAILED;
1186   }
1187   return NDBT_OK;
1188 }
1189 
runSystemRestart1(NDBT_Context * ctx,NDBT_Step * step)1190 int runSystemRestart1(NDBT_Context* ctx, NDBT_Step* step){
1191   Ndb* pNdb = GETNDB(step);
1192   int result = NDBT_OK;
1193   int timeout = 300;
1194   Uint32 loops = ctx->getNumLoops();
1195   int records = ctx->getNumRecords();
1196   int count;
1197   NdbRestarter restarter;
1198   Uint32 i = 1;
1199 
1200   UtilTransactions utilTrans(*ctx->getTab());
1201   HugoTransactions hugoTrans(*ctx->getTab());
1202   while(i<=loops && result != NDBT_FAILED){
1203 
1204     ndbout << "Loop " << i << "/"<< loops <<" started" << endl;
1205     /*
1206       1. Load data
1207       2. Restart cluster and verify records
1208       3. Update records
1209       4. Restart cluster and verify records
1210       5. Delete half of the records
1211       6. Restart cluster and verify records
1212       7. Delete all records
1213       8. Restart cluster and verify records
1214       9. Insert, update, delete records
1215       10. Restart cluster and verify records
1216       11. Insert, update, delete records
1217       12. Restart cluster with error insert 5020 and verify records
1218     */
1219     ndbout << "Loading records..." << endl;
1220     CHECK(hugoTrans.loadTable(pNdb, records, 1) == 0);
1221     CHECK(utilTrans.verifyIndex(pNdb, idxName, 16, false) == 0);
1222 
1223     ndbout << "Restarting cluster" << endl;
1224     CHECK(restarter.restartAll() == 0);
1225     CHECK(restarter.waitClusterStarted(timeout) == 0);
1226     CHECK(pNdb->waitUntilReady(timeout) == 0);
1227 
1228     ndbout << "Verifying records..." << endl;
1229     CHECK(hugoTrans.pkReadRecords(pNdb, records) == 0);
1230     CHECK(utilTrans.selectCount(pNdb, 64, &count) == 0);
1231     CHECK(count == records);
1232     CHECK(utilTrans.verifyIndex(pNdb, idxName, 16, false) == 0);
1233 
1234     ndbout << "Updating records..." << endl;
1235     CHECK(hugoTrans.pkUpdateRecords(pNdb, records) == 0);
1236     CHECK(utilTrans.verifyIndex(pNdb, idxName, 16, false) == 0);
1237 
1238     ndbout << "Restarting cluster..." << endl;
1239     CHECK(restarter.restartAll() == 0);
1240     CHECK(restarter.waitClusterStarted(timeout) == 0);
1241     CHECK(pNdb->waitUntilReady(timeout) == 0);
1242 
1243     ndbout << "Verifying records..." << endl;
1244     CHECK(hugoTrans.pkReadRecords(pNdb, records) == 0);
1245     CHECK(utilTrans.selectCount(pNdb, 64, &count) == 0);
1246     CHECK(count == records);
1247     CHECK(utilTrans.verifyIndex(pNdb, idxName, 16, false) == 0);
1248 
1249     ndbout << "Deleting 50% of records..." << endl;
1250     CHECK(hugoTrans.pkDelRecords(pNdb, records/2) == 0);
1251     CHECK(utilTrans.verifyIndex(pNdb, idxName, 16, false) == 0);
1252 
1253     ndbout << "Restarting cluster..." << endl;
1254     CHECK(restarter.restartAll() == 0);
1255     CHECK(restarter.waitClusterStarted(timeout) == 0);
1256     CHECK(pNdb->waitUntilReady(timeout) == 0);
1257 
1258     ndbout << "Verifying records..." << endl;
1259     CHECK(hugoTrans.scanReadRecords(pNdb, records/2, 0, 64) == 0);
1260     CHECK(utilTrans.selectCount(pNdb, 64, &count) == 0);
1261     CHECK(count == (records/2));
1262     CHECK(utilTrans.verifyIndex(pNdb, idxName, 16, false) == 0);
1263 
1264     ndbout << "Deleting all records..." << endl;
1265     CHECK(utilTrans.clearTable(pNdb, records/2) == 0);
1266     CHECK(utilTrans.verifyIndex(pNdb, idxName, 16, false) == 0);
1267 
1268     ndbout << "Restarting cluster..." << endl;
1269     CHECK(restarter.restartAll() == 0);
1270     CHECK(restarter.waitClusterStarted(timeout) == 0);
1271     CHECK(pNdb->waitUntilReady(timeout) == 0);
1272 
1273     ndbout << "Verifying records..." << endl;
1274     CHECK(utilTrans.selectCount(pNdb, 64, &count) == 0);
1275     CHECK(count == 0);
1276     CHECK(utilTrans.verifyIndex(pNdb, idxName, 16, false) == 0);
1277 
1278     ndbout << "Doing it all..." << endl;
1279     CHECK(hugoTrans.loadTable(pNdb, records, 1) == 0);
1280     CHECK(utilTrans.verifyIndex(pNdb, idxName, 16, false) == 0);
1281     CHECK(hugoTrans.pkUpdateRecords(pNdb, records) == 0);
1282     CHECK(utilTrans.verifyIndex(pNdb, idxName, 16, false) == 0);
1283     CHECK(hugoTrans.pkDelRecords(pNdb, records/2) == 0);
1284     CHECK(hugoTrans.scanUpdateRecords(pNdb, records/2) == 0);
1285     CHECK(utilTrans.verifyIndex(pNdb, idxName, 16, false) == 0);
1286     CHECK(utilTrans.clearTable(pNdb, records) == 0);
1287     CHECK(hugoTrans.loadTable(pNdb, records, 1) == 0);
1288     CHECK(utilTrans.clearTable(pNdb, records) == 0);
1289     CHECK(hugoTrans.loadTable(pNdb, records, 1) == 0);
1290     CHECK(hugoTrans.pkUpdateRecords(pNdb, records) == 0);
1291     CHECK(utilTrans.clearTable(pNdb, records) == 0);
1292 
1293     ndbout << "Restarting cluster..." << endl;
1294     CHECK(restarter.restartAll() == 0);
1295     CHECK(restarter.waitClusterStarted(timeout) == 0);
1296     CHECK(pNdb->waitUntilReady(timeout) == 0);
1297 
1298     ndbout << "Verifying records..." << endl;
1299     CHECK(utilTrans.selectCount(pNdb, 64, &count) == 0);
1300     CHECK(count == 0);
1301 
1302     ndbout << "Doing it all..." << endl;
1303     CHECK(hugoTrans.loadTable(pNdb, records, 1) == 0);
1304     CHECK(utilTrans.verifyIndex(pNdb, idxName,  16, false) == 0);
1305     CHECK(hugoTrans.pkUpdateRecords(pNdb, records) == 0);
1306     CHECK(utilTrans.verifyIndex(pNdb, idxName,  16, false) == 0);
1307     CHECK(hugoTrans.pkDelRecords(pNdb, records/2) == 0);
1308     CHECK(utilTrans.verifyIndex(pNdb, idxName,  16, false) == 0);
1309     CHECK(hugoTrans.scanUpdateRecords(pNdb, records/2) == 0);
1310     CHECK(utilTrans.verifyIndex(pNdb, idxName,  16, false) == 0);
1311     CHECK(utilTrans.clearTable(pNdb, records) == 0);
1312     CHECK(hugoTrans.loadTable(pNdb, records, 1) == 0);
1313     CHECK(utilTrans.clearTable(pNdb, records) == 0);
1314 
1315     ndbout << "Restarting cluster with error insert 5020..." << endl;
1316     CHECK(restarter.restartAll(false, true) == 0);
1317     CHECK(restarter.waitClusterNoStart(timeout) == 0);
1318     CHECK(restarter.insertErrorInAllNodes(5020) == 0);
1319     CHECK(restarter.startAll() == 0);
1320     CHECK(restarter.waitClusterStarted(timeout) == 0);
1321     CHECK(pNdb->waitUntilReady(timeout) == 0);
1322 
1323     i++;
1324   }
1325 
1326   ctx->stopTest();
1327   ndbout << "runSystemRestart1 finished" << endl;
1328 
1329   return result;
1330 }
1331 
1332 #define CHECK2(b, t) if(!(b)){ g_err << __LINE__ << ": " << t << endl; break;}
1333 #define CHECKOKORTIMEOUT(e, t) { int rc= (e);        \
1334     if (rc != 0) {                                      \
1335       if (rc == 266) {                                  \
1336         g_err << "Timeout : retries left : "            \
1337               << timeoutRetries                         \
1338               << endl;                                  \
1339         continue;                                       \
1340       }                                                 \
1341       g_err << __LINE__ << ": " << (t) << endl; break;  \
1342     } }
1343 
1344 
1345 int
runMixed1(NDBT_Context * ctx,NDBT_Step * step)1346 runMixed1(NDBT_Context* ctx, NDBT_Step* step){
1347   // Verify that data in index match
1348   // table data
1349   Ndb* pNdb = GETNDB(step);
1350   HugoOperations hugoOps(*ctx->getTab());
1351 
1352   /* Old, rather ineffective testcase which nonetheless passes on 6.3 */
1353 
1354   do {
1355     // TC1
1356     g_err << "pkRead, indexRead, Commit" << endl;
1357     CHECK2(hugoOps.startTransaction(pNdb) == 0, "startTransaction");
1358     CHECK2(hugoOps.indexReadRecords(pNdb, pkIdxName, 0) == 0, "indexReadRecords");
1359     CHECK2(hugoOps.pkReadRecord(pNdb, 0) == 0, "pkReadRecord");
1360     CHECK2(hugoOps.execute_Commit(pNdb) == 0, "executeCommit");
1361     CHECK2(hugoOps.closeTransaction(pNdb) == 0, "closeTransaction");
1362 
1363     // TC1
1364     g_err << "pkRead, indexRead, Commit" << endl;
1365     CHECK2(hugoOps.startTransaction(pNdb) == 0, "startTransaction");
1366     CHECK2(hugoOps.pkReadRecord(pNdb, 0) == 0, "pkReadRecord");
1367     CHECK2(hugoOps.indexReadRecords(pNdb, pkIdxName, 0) == 0, "indexReadRecords");
1368     CHECK2(hugoOps.execute_Commit(pNdb) == 0, "executeCommit");
1369     CHECK2(hugoOps.closeTransaction(pNdb) == 0, "closeTransaction");
1370 
1371 
1372     // TC2
1373     g_err << "pkRead, indexRead, NoCommit, Commit" << endl;
1374     CHECK2(hugoOps.startTransaction(pNdb) == 0, "startTransaction");
1375     CHECK2(hugoOps.pkReadRecord(pNdb, 0) == 0, "pkReadRecord");
1376     CHECK2(hugoOps.indexReadRecords(pNdb, pkIdxName, 0) == 0,
1377 	   "indexReadRecords");
1378     CHECK2(hugoOps.execute_NoCommit(pNdb) == 0, "executeNoCommit");
1379     CHECK2(hugoOps.execute_Commit(pNdb) == 0, "executeCommit");
1380     CHECK2(hugoOps.closeTransaction(pNdb) == 0, "closeTransaction");
1381 
1382     // TC3
1383     g_err << "pkRead, pkRead, Commit" << endl;
1384     CHECK2(hugoOps.startTransaction(pNdb) == 0, "startTransaction ");
1385     CHECK2(hugoOps.pkReadRecord(pNdb, 0) == 0, "pkReadRecords ");
1386     CHECK2(hugoOps.pkReadRecord(pNdb, 0) == 0, "pkReadRecords ");
1387     CHECK2(hugoOps.execute_Commit(pNdb) == 0, "executeCommit");
1388     CHECK2(hugoOps.closeTransaction(pNdb) == 0, "closeTransaction ");
1389 
1390     // TC4
1391     g_err << "indexRead, indexRead, Commit" << endl;
1392 
1393     CHECK2(hugoOps.startTransaction(pNdb) == 0, "startTransaction ");
1394     CHECK2(hugoOps.indexReadRecords(pNdb, pkIdxName, 0) == 0, "indexReadRecords");
1395     CHECK2(hugoOps.indexReadRecords(pNdb, pkIdxName, 0) == 0, "indexReadRecords");
1396     CHECK2(hugoOps.execute_Commit(pNdb) == 0, "executeCommit");
1397 
1398     CHECK2(hugoOps.closeTransaction(pNdb) == 0, "closeTransaction ");
1399 
1400     return NDBT_OK;
1401   } while(false);
1402 
1403 
1404   hugoOps.closeTransaction(pNdb);
1405   return NDBT_FAILED;
1406 }
1407 
1408 
1409 
1410 int
runMixedUpdateInterleaved(Ndb * pNdb,HugoOperations & hugoOps,int outOfRangeRec,int testSize,bool commit,bool abort,int pkFailRec,int ixFailRec,bool invertFail,AbortOption ao,int whatToUpdate,int updatesValue,bool ixFirst)1411 runMixedUpdateInterleaved(Ndb* pNdb,
1412                           HugoOperations& hugoOps,
1413                           int outOfRangeRec,
1414                           int testSize,
1415                           bool commit,
1416                           bool abort,
1417                           int pkFailRec,
1418                           int ixFailRec,
1419                           bool invertFail,
1420                           AbortOption ao,
1421                           int whatToUpdate,
1422                           int updatesValue,
1423                           bool ixFirst)
1424 {
1425   int execRc= 0;
1426   if ((pkFailRec != -1) || (ixFailRec != -1))
1427   {
1428     execRc= 626;
1429   }
1430 
1431   bool updateViaPk= whatToUpdate & 1;
1432   bool updateViaIx= whatToUpdate & 2;
1433 
1434   int ixOpNum= (ixFirst?0:1);
1435   int pkOpNum= (ixFirst?1:0);
1436 
1437   int timeoutRetries= 3;
1438 
1439   while (timeoutRetries--)
1440   {
1441     CHECK2(hugoOps.startTransaction(pNdb) == 0, "startTransaction");
1442     for (int i=0; i < testSize; i++)
1443     {
1444       /* invertFail causes all issued reads *except* the fail record number
1445        * to fail
1446        */
1447       int indxKey= ((i == ixFailRec)^invertFail)? outOfRangeRec : i;
1448       int pkKey= ((i == pkFailRec)^invertFail)? outOfRangeRec : i;
1449 
1450       for (int opNum=0; opNum < 2; opNum++)
1451       {
1452         if (opNum == ixOpNum)
1453         {
1454           if (updateViaIx)
1455           {
1456             CHECK2(hugoOps.indexUpdateRecord(pNdb, pkIdxName, indxKey, 1, updatesValue) == 0,
1457                    "indexUpdateRecord");
1458           }
1459           else
1460           {
1461             CHECK2(hugoOps.indexReadRecords(pNdb, pkIdxName, indxKey) == 0, "indexReadRecords");
1462           }
1463         }
1464 
1465         if (opNum == pkOpNum)
1466         {
1467           if (updateViaPk)
1468           {
1469             CHECK2(hugoOps.pkUpdateRecord(pNdb, pkKey, 1, updatesValue) == 0,
1470                    "pkUpdateRecord");
1471           }
1472           else
1473           {
1474             CHECK2(hugoOps.pkReadRecord(pNdb, pkKey) == 0, "pkReadRecord");
1475           }
1476         }
1477       }
1478     }
1479     if (commit)
1480     {
1481       int rc= hugoOps.execute_Commit(pNdb, ao);
1482       if (rc == 266)
1483       {
1484         /* Timeout */
1485         g_err << "Timeout : retries left=" << timeoutRetries << endl;
1486         hugoOps.closeTransaction(pNdb);
1487         continue;
1488       }
1489       CHECK2(rc == execRc, "execute_Commit");
1490       NdbError err= hugoOps.getTransaction()->getNdbError();
1491       CHECK2(err.code == execRc, "getNdbError");
1492     }
1493     else
1494     {
1495       int rc= hugoOps.execute_NoCommit(pNdb, ao);
1496       if (rc == 266)
1497       {
1498         /* Timeout */
1499         g_err << "Timeout : retries left=" << timeoutRetries << endl;
1500         hugoOps.closeTransaction(pNdb);
1501         continue;
1502       }
1503       CHECK2(rc == execRc, "execute_NoCommit");
1504       NdbError err= hugoOps.getTransaction()->getNdbError();
1505       CHECK2(err.code == execRc, "getNdbError");
1506       if (execRc && (ao == AO_IgnoreError))
1507       {
1508         /* Transaction should still be open, let's commit it */
1509         CHECK2(hugoOps.execute_Commit(pNdb, ao) == 0, "executeCommit");
1510       }
1511       else if (abort)
1512       {
1513         CHECK2(hugoOps.execute_Rollback(pNdb) == 0, "executeRollback");
1514       }
1515     }
1516     CHECK2(hugoOps.closeTransaction(pNdb) == 0, "closeTransaction");
1517 
1518     return 1;
1519   }
1520 
1521   hugoOps.closeTransaction(pNdb);
1522   return 0;
1523 }
1524 
1525 
1526 
1527 int
runMixed2(NDBT_Context * ctx,NDBT_Step * step)1528 runMixed2(NDBT_Context* ctx, NDBT_Step* step){
1529   Ndb* pNdb = GETNDB(step);
1530   HugoOperations hugoOps(*ctx->getTab());
1531 
1532   int numRecordsInTable= ctx->getNumRecords();
1533   const int maxTestSize= 10000;
1534   int testSize= MIN(numRecordsInTable, maxTestSize);
1535 
1536   /* Avoid overloading Send Buffers */
1537   Uint32 rowSize=  NdbDictionary::getRecordRowLength(ctx->getTab()->getDefaultRecord());
1538   Uint32 dataXfer= 2 * rowSize * testSize;
1539   const Uint32 MaxDataXfer= 500000; // 0.5M
1540 
1541   if (dataXfer > MaxDataXfer)
1542   {
1543     testSize= MIN((int)(MaxDataXfer/rowSize), testSize);
1544   }
1545 
1546   g_err << "testSize= " << testSize << endl;
1547   g_err << "rowSize= " << rowSize << endl;
1548 
1549   int updatesValue= 1;
1550   const int maxTimeoutRetries= 3;
1551 
1552   do {
1553     // TC0
1554     {
1555       bool ok= false;
1556       int timeoutRetries= maxTimeoutRetries;
1557       while (timeoutRetries--)
1558       {
1559         g_err << "TC0 : indexRead, pkread, Commit" << endl;
1560         CHECK2(hugoOps.startTransaction(pNdb) == 0, "startTransaction");
1561         CHECK2(hugoOps.indexReadRecords(pNdb, pkIdxName, 0, false, testSize) == 0, "indexReadRecords");
1562         CHECK2(hugoOps.pkReadRecord(pNdb, 0, testSize) == 0, "pkReadRecord");
1563         CHECKOKORTIMEOUT(hugoOps.execute_Commit(pNdb), "executeCommit");
1564         CHECK2(hugoOps.closeTransaction(pNdb) == 0, "closeTransaction");
1565 
1566         ok= true;
1567         break;
1568       }
1569       if (!ok) { break; };
1570     }
1571 
1572 
1573     // TC1
1574     {
1575       bool ok= false;
1576       int timeoutRetries= maxTimeoutRetries;
1577       while (timeoutRetries--)
1578       {
1579         g_err << "TC1 : pkRead, indexRead, Commit" << endl;
1580         CHECK2(hugoOps.startTransaction(pNdb) == 0, "startTransaction");
1581         CHECK2(hugoOps.pkReadRecord(pNdb, 0, testSize) == 0, "pkReadRecord");
1582         CHECK2(hugoOps.indexReadRecords(pNdb, pkIdxName, 0, false, testSize) == 0, "indexReadRecords");
1583         CHECKOKORTIMEOUT(hugoOps.execute_Commit(pNdb), "executeCommit");
1584         CHECK2(hugoOps.closeTransaction(pNdb) == 0, "closeTransaction");
1585 
1586         ok= true;
1587         break;
1588       }
1589       if (!ok) { break; };
1590     }
1591 
1592     // TC2
1593     {
1594       bool ok= false;
1595       int timeoutRetries= maxTimeoutRetries;
1596       while (timeoutRetries--)
1597       {
1598         g_err << "TC2 : pkRead, indexRead, NoCommit, Commit" << endl;
1599         CHECK2(hugoOps.startTransaction(pNdb) == 0, "startTransaction");
1600         CHECK2(hugoOps.pkReadRecord(pNdb, 0, testSize) == 0, "pkReadRecord");
1601         CHECK2(hugoOps.indexReadRecords(pNdb, pkIdxName, 0, false, testSize) == 0,
1602                "indexReadRecords");
1603         CHECKOKORTIMEOUT(hugoOps.execute_NoCommit(pNdb), "executeNoCommit");
1604         CHECK2(hugoOps.execute_Commit(pNdb) == 0, "executeCommit");
1605         CHECK2(hugoOps.closeTransaction(pNdb) == 0, "closeTransaction");
1606         ok= true;
1607         break;
1608       }
1609       if (!ok) { break; };
1610     }
1611 
1612     // TC3
1613     {
1614       bool ok= false;
1615       int timeoutRetries= maxTimeoutRetries;
1616       while (timeoutRetries--)
1617       {
1618         g_err << "TC3 : pkRead, pkRead, Commit" << endl;
1619         CHECK2(hugoOps.startTransaction(pNdb) == 0, "startTransaction ");
1620         CHECK2(hugoOps.pkReadRecord(pNdb, 0, testSize) == 0, "pkReadRecords ");
1621         CHECK2(hugoOps.pkReadRecord(pNdb, 0, testSize) == 0, "pkReadRecords ");
1622         CHECKOKORTIMEOUT(hugoOps.execute_Commit(pNdb), "executeCommit");
1623         CHECK2(hugoOps.closeTransaction(pNdb) == 0, "closeTransaction ");
1624         ok= true;
1625         break;
1626       }
1627       if (!ok) { break; };
1628     }
1629 
1630     // TC4
1631     {
1632       bool ok= false;
1633       int timeoutRetries= maxTimeoutRetries;
1634       while (timeoutRetries--)
1635       {
1636         g_err << "TC4 : indexRead, indexRead, Commit" << endl;
1637         CHECK2(hugoOps.startTransaction(pNdb) == 0, "startTransaction ");
1638         CHECK2(hugoOps.indexReadRecords(pNdb, pkIdxName, 0, false, testSize) == 0, "indexReadRecords");
1639         CHECK2(hugoOps.indexReadRecords(pNdb, pkIdxName, 0, false, testSize) == 0, "indexReadRecords");
1640         CHECKOKORTIMEOUT(hugoOps.execute_Commit(pNdb), "executeCommit");
1641         CHECK2(hugoOps.closeTransaction(pNdb) == 0, "closeTransaction ");
1642         ok= true;
1643         break;
1644       }
1645       if (!ok) { break; };
1646     }
1647 
1648     // TC5
1649     {
1650       bool ok= false;
1651       int timeoutRetries= maxTimeoutRetries;
1652       while (timeoutRetries--)
1653       {
1654         g_err << "TC5 : indexRead, pkUpdate, Commit" << endl;
1655         CHECK2(hugoOps.startTransaction(pNdb) == 0, "startTransaction");
1656         CHECK2(hugoOps.indexReadRecords(pNdb, pkIdxName, 0, false, testSize) == 0, "indexReadRecords");
1657         CHECK2(hugoOps.pkUpdateRecord(pNdb, 0, testSize, updatesValue++) == 0, "pkUpdateRecord");
1658         CHECKOKORTIMEOUT(hugoOps.execute_Commit(pNdb), "executeCommit");
1659         CHECK2(hugoOps.closeTransaction(pNdb) == 0, "closeTransaction");
1660         ok= true;
1661         break;
1662       }
1663       if (!ok) { break; };
1664     }
1665 
1666     // TC6
1667     {
1668       bool ok= false;
1669       int timeoutRetries= maxTimeoutRetries;
1670       while (timeoutRetries--)
1671       {
1672         g_err << "TC6 : pkUpdate, indexRead, Commit" << endl;
1673         CHECK2(hugoOps.startTransaction(pNdb) == 0, "startTransaction");
1674         CHECK2(hugoOps.pkUpdateRecord(pNdb, 0, testSize, updatesValue++) == 0, "pkUpdateRecord");
1675         CHECK2(hugoOps.indexReadRecords(pNdb, pkIdxName, 0, false, testSize) == 0, "indexReadRecords");
1676         CHECKOKORTIMEOUT(hugoOps.execute_Commit(pNdb), "executeCommit");
1677         CHECK2(hugoOps.closeTransaction(pNdb) == 0, "closeTransaction");
1678         ok= true;
1679         break;
1680       }
1681       if (!ok) { break; };
1682     }
1683 
1684     // TC7
1685     {
1686       bool ok= false;
1687       int timeoutRetries= maxTimeoutRetries;
1688       while (timeoutRetries--)
1689       {
1690         g_err << "TC7 : pkRead, indexUpdate, Commit" << endl;
1691         CHECK2(hugoOps.startTransaction(pNdb) == 0, "startTransaction");
1692         CHECK2(hugoOps.pkReadRecord(pNdb, 0, testSize) == 0, "pkReadRecord");
1693         CHECK2(hugoOps.indexUpdateRecord(pNdb, pkIdxName, 0, testSize, updatesValue++) == 0,
1694                "indexReadRecords");
1695         CHECKOKORTIMEOUT(hugoOps.execute_Commit(pNdb), "executeCommit");
1696         CHECK2(hugoOps.closeTransaction(pNdb) == 0, "closeTransaction");
1697         ok= true;
1698         break;
1699       }
1700       if (!ok) { break; };
1701     }
1702 
1703     // TC8
1704     {
1705       bool ok= false;
1706       int timeoutRetries= maxTimeoutRetries;
1707       while (timeoutRetries--)
1708       {
1709         g_err << "TC8 : indexUpdate, pkRead, Commit" << endl;
1710         CHECK2(hugoOps.startTransaction(pNdb) == 0, "startTransaction ");
1711         CHECK2(hugoOps.indexUpdateRecord(pNdb, pkIdxName, 0, testSize, updatesValue++) == 0,
1712                "indexReadRecords ");
1713         CHECK2(hugoOps.pkReadRecord(pNdb, 0, testSize) == 0, "pkReadRecords ");
1714         CHECKOKORTIMEOUT(hugoOps.execute_Commit(pNdb), "executeCommit");
1715         CHECK2(hugoOps.closeTransaction(pNdb) == 0, "closeTransaction ");
1716         ok= true;
1717         break;
1718       }
1719       if (!ok) { break; };
1720     }
1721 
1722     for (int ao=0; ao < 2; ao++)
1723     {
1724       AbortOption abortOption= ao?AO_IgnoreError:AbortOnError;
1725 
1726       for (int exType=0; exType < 3; exType++)
1727       {
1728         bool commit= (exType == 1);
1729         bool abort= (exType == 2);
1730 
1731         const char* exTypeStr= ((exType == 0) ? "NoCommit" :
1732                                 (exType == 1) ? "Commit" :
1733                                 "Abort");
1734 
1735         for (int failType= 0; failType < 4; failType++)
1736         {
1737           for (int failPos= 0; failPos < 2; failPos++)
1738           {
1739             int failRec= (failPos == 0)? 0 : testSize -1;
1740             int pkFailRec= -1;
1741             int ixFailRec= -1;
1742             if (failType)
1743             {
1744               if (failType & 1)
1745                 pkFailRec= failRec;
1746               if (failType & 2)
1747                 ixFailRec= failRec;
1748             }
1749 
1750             for (int invFail= 0;
1751                  invFail < ((failType==0)?1:2);
1752                  invFail++)
1753             {
1754               bool invertFail= (invFail)?true:false;
1755               const char* failTypeStr= ((failType==0)? "None" :
1756                                         ((failType==1)? "Pk":
1757                                          ((failType==2)?"Ix": "Both")));
1758               for (int updateVia= 0; updateVia < 3; updateVia++)
1759               {
1760                 const char* updateViaStr= ((updateVia == 0)? "None" :
1761                                            (updateVia == 1)? "Pk" :
1762                                            (updateVia == 2)? "Ix" :
1763                                            "Both");
1764                 for (int updateOrder= 0; updateOrder < 2; updateOrder++)
1765                 {
1766                   bool updateIxFirst= (updateOrder == 0);
1767                   g_err << endl
1768                         << "AbortOption : " << (ao?"IgnoreError":"AbortOnError") << endl
1769                         << "ExecType : " << exTypeStr << endl
1770                         << "Failtype : " << failTypeStr << endl
1771                         << "Failpos : " << ((failPos == 0)? "Early" : "Late") << endl
1772                         << "Failure scenarios : " << (invFail?"All but one":"one") << endl
1773                         << "UpdateVia : " << updateViaStr << endl
1774                         << "Order : " << (updateIxFirst? "Index First" : "Pk first") << endl;
1775                   bool ok= false;
1776                   do
1777                   {
1778                     g_err << "Mixed read/update interleaved" << endl;
1779                     CHECK2(runMixedUpdateInterleaved(pNdb, hugoOps, numRecordsInTable, testSize,
1780                                                      commit,  // Commit
1781                                                      abort, // Abort
1782                                                      pkFailRec,    // PkFail
1783                                                      ixFailRec,   // IxFail
1784                                                      invertFail, // Invertfail
1785                                                      abortOption,
1786                                                      updateVia,
1787                                                      updatesValue++,
1788                                                      updateIxFirst),
1789                          "TC4");
1790 
1791                     ok= true;
1792                   } while (false);
1793 
1794                   if (!ok)
1795                   {
1796                     hugoOps.closeTransaction(pNdb);
1797                     return NDBT_FAILED;
1798                   }
1799                 }
1800               }
1801             }
1802           }
1803         }
1804       }
1805     }
1806 
1807     return NDBT_OK;
1808   } while (false);
1809 
1810   hugoOps.closeTransaction(pNdb);
1811   return NDBT_FAILED;
1812 }
1813 
1814 #define check(b, e)                                                     \
1815   if (!(b)) { g_err << "ERR: " << step->getName() << " failed on line " << __LINE__ << ": " << e.getNdbError() << endl; return NDBT_FAILED; }
1816 
runRefreshTupleAbort(NDBT_Context * ctx,NDBT_Step * step)1817 int runRefreshTupleAbort(NDBT_Context* ctx, NDBT_Step* step){
1818   int records = ctx->getNumRecords();
1819   int loops = ctx->getNumLoops();
1820 
1821   Ndb* ndb = GETNDB(step);
1822 
1823   const NdbDictionary::Table& tab = *ctx->getTab();
1824 
1825   for (int i=0; i < tab.getNoOfColumns(); i++)
1826   {
1827     if (tab.getColumn(i)->getStorageType() == NDB_STORAGETYPE_DISK)
1828     {
1829       g_err << "Table has disk column(s) skipping." << endl;
1830       return NDBT_OK;
1831     }
1832   }
1833 
1834 
1835   g_err << "Loading table." << endl;
1836   HugoTransactions hugoTrans(*ctx->getTab());
1837   check(hugoTrans.loadTable(ndb, records) == 0, hugoTrans);
1838 
1839   HugoOperations hugoOps(*ctx->getTab());
1840 
1841   /* Check refresh, abort sequence with an ordered index
1842    * Previously this gave bugs due to corruption of the
1843    * tuple version
1844    */
1845   while (loops--)
1846   {
1847     Uint32 numRefresh = 2 + rand() % 10;
1848 
1849     g_err << "Refresh, rollback * " << numRefresh << endl;
1850 
1851     while (--numRefresh)
1852     {
1853       /* Refresh, rollback */
1854       check(hugoOps.startTransaction(ndb) == 0, hugoOps);
1855       check(hugoOps.pkRefreshRecord(ndb, 0, records, 0) == 0, hugoOps);
1856       check(hugoOps.execute_NoCommit(ndb) == 0, hugoOps);
1857       check(hugoOps.execute_Rollback(ndb) == 0, hugoOps);
1858       check(hugoOps.closeTransaction(ndb) == 0, hugoOps);
1859     }
1860 
1861     g_err << "Refresh, commit" << endl;
1862     /* Refresh, commit */
1863     check(hugoOps.startTransaction(ndb) == 0, hugoOps);
1864     check(hugoOps.pkRefreshRecord(ndb, 0, records, 0) == 0, hugoOps);
1865     check(hugoOps.execute_NoCommit(ndb) == 0, hugoOps);
1866     check(hugoOps.execute_Commit(ndb) == 0, hugoOps);
1867     check(hugoOps.closeTransaction(ndb) == 0, hugoOps);
1868 
1869     g_err << "Update, commit" << endl;
1870     /* Update */
1871     check(hugoOps.startTransaction(ndb) == 0, hugoOps);
1872     check(hugoOps.pkUpdateRecord(ndb, 0, records, 2 + loops) == 0, hugoOps);
1873     check(hugoOps.execute_NoCommit(ndb) == 0, hugoOps);
1874     check(hugoOps.execute_Commit(ndb) == 0, hugoOps);
1875     check(hugoOps.closeTransaction(ndb) == 0, hugoOps);
1876   }
1877 
1878   return NDBT_OK;
1879 }
1880 
1881 
1882 int
runBuildDuring(NDBT_Context * ctx,NDBT_Step * step)1883 runBuildDuring(NDBT_Context* ctx, NDBT_Step* step){
1884   // Verify that data in index match
1885   // table data
1886   const int Threads = ctx->getProperty("Threads", (Uint32)0);
1887   const int loops = ctx->getNumLoops();
1888 
1889   for(int i = 0; i<loops; i++){
1890 #if 1
1891     if(createPkIndex(ctx, step) != NDBT_OK){
1892       g_err << "Failed to create index" << endl;
1893       return NDBT_FAILED;
1894     }
1895 #endif
1896 
1897     if(ctx->isTestStopped())
1898       break;
1899 
1900 #if 1
1901     if(createRandomIndex(ctx, step) != NDBT_OK){
1902       g_err << "Failed to create index" << endl;
1903       return NDBT_FAILED;
1904     }
1905 #endif
1906 
1907     if(ctx->isTestStopped())
1908       break;
1909 
1910     if (Threads)
1911     {
1912       ctx->setProperty("pause", 1);
1913       int count = 0;
1914       for(int j = 0; count < Threads && !ctx->isTestStopped();
1915           j = (j+1) % Threads){
1916         char buf[255];
1917         sprintf(buf, "Thread%d_paused", j);
1918         int tmp = ctx->getProperty(buf, (Uint32)0);
1919         count += tmp;
1920       }
1921     }
1922 
1923     if(ctx->isTestStopped())
1924       break;
1925 
1926 #if 1
1927     if(createPkIndex_Drop(ctx, step) != NDBT_OK){
1928       g_err << "Failed to drop index" << endl;
1929       return NDBT_FAILED;
1930     }
1931 #endif
1932 
1933     if(ctx->isTestStopped())
1934       break;
1935 
1936 #if 1
1937     if(createRandomIndex_Drop(ctx, step) != NDBT_OK){
1938       g_err << "Failed to drop index" << endl;
1939       return NDBT_FAILED;
1940     }
1941 #endif
1942 
1943     if (Threads)
1944     {
1945       ctx->setProperty("pause", (Uint32)0);
1946       NdbSleep_SecSleep(2);
1947     }
1948   }
1949 
1950   ctx->stopTest();
1951   return NDBT_OK;
1952 }
1953 
1954 static NdbLockable g_lock;
1955 static int threadCounter = 0;
1956 
1957 void
wait_paused(NDBT_Context * ctx,int id)1958 wait_paused(NDBT_Context* ctx, int id){
1959   if(ctx->getProperty("pause", (Uint32)0) == 1){
1960     char buf[255];
1961     sprintf(buf, "Thread%d_paused", id);
1962     ctx->setProperty(buf, 1);
1963     while(!ctx->isTestStopped() && ctx->getProperty("pause", (Uint32)0) == 1){
1964       NdbSleep_MilliSleep(250);
1965     }
1966     ctx->setProperty(buf, (Uint32)0);
1967   }
1968 }
1969 
1970 int
runTransactions4(NDBT_Context * ctx,NDBT_Step * step)1971 runTransactions4(NDBT_Context* ctx, NDBT_Step* step){
1972 
1973   g_lock.lock();
1974   const int ThreadId = threadCounter++;
1975   g_lock.unlock();
1976 
1977   // Verify that data in index match
1978   // table data
1979   Ndb* pNdb = GETNDB(step);
1980   HugoTransactions hugoTrans(*ctx->getTab());
1981   UtilTransactions utilTrans(*ctx->getTab());
1982   const int batchSize = ctx->getProperty("BatchSize", 32);
1983   const int parallel = batchSize > 240 ? 240 : batchSize;
1984 
1985   int rows = ctx->getNumRecords();
1986   while (ctx->isTestStopped() == false) {
1987     if(hugoTrans.loadTable(pNdb, rows, batchSize, false) != 0){
1988       g_err << "Load table failed" << endl;
1989       return NDBT_FAILED;
1990     }
1991 
1992     wait_paused(ctx, ThreadId);
1993 
1994     if(ctx->isTestStopped())
1995       break;
1996 
1997     if (hugoTrans.pkUpdateRecords(pNdb, rows, batchSize) != 0){
1998       g_err << "Updated table failed" << endl;
1999       return NDBT_FAILED;
2000     }
2001 
2002     wait_paused(ctx, ThreadId);
2003 
2004     if(ctx->isTestStopped())
2005       break;
2006 
2007     if (hugoTrans.scanUpdateRecords(pNdb, rows, 5, parallel) != 0){
2008       g_err << "Scan updated table failed" << endl;
2009       return NDBT_FAILED;
2010     }
2011 
2012     wait_paused(ctx, ThreadId);
2013 
2014     if(ctx->isTestStopped())
2015       break;
2016 
2017     if(utilTrans.clearTable(pNdb, rows, parallel) != 0){
2018       g_err << "Clear table failed" << endl;
2019       return NDBT_FAILED;
2020     }
2021   }
2022   return NDBT_OK;
2023 }
2024 
2025 int
runUniqueNullTransactions(NDBT_Context * ctx,NDBT_Step * step)2026 runUniqueNullTransactions(NDBT_Context* ctx, NDBT_Step* step){
2027   Ndb* pNdb = GETNDB(step);
2028 
2029   bool logged = ctx->getProperty("LoggedIndexes", 1);
2030   bool orderedIndex = ctx->getProperty("OrderedIndex", (unsigned)0);
2031   NdbConnection * pTrans = 0;
2032 
2033   const NdbDictionary::Table* pTab = ctx->getTab();
2034   // Create index
2035   char nullIndex[255];
2036   BaseString::snprintf(nullIndex, 255, "IDC_PK_%s_NULL", pTab->getName());
2037   if (orderedIndex)
2038     ndbout << "Creating " << ((logged)?"logged ": "temporary ") << "ordered index "
2039 	   << pkIdxName << " (";
2040   else
2041     ndbout << "Creating " << ((logged)?"logged ": "temporary ") << "unique index "
2042 	   << pkIdxName << " (";
2043 
2044   NdbDictionary::Index pIdx(pkIdxName);
2045   pIdx.setTable(pTab->getName());
2046   if (orderedIndex)
2047     pIdx.setType(NdbDictionary::Index::OrderedIndex);
2048   else
2049     pIdx.setType(NdbDictionary::Index::UniqueHashIndex);
2050   pIdx.setStoredIndex(logged);
2051   int c;
2052   for (c = 0; c< pTab->getNoOfColumns(); c++){
2053     const NdbDictionary::Column * col = pTab->getColumn(c);
2054     if(col->getPrimaryKey()){
2055       pIdx.addIndexColumn(col->getName());
2056       ndbout << col->getName() <<" ";
2057     }
2058   }
2059 
2060   int colId = -1;
2061   for (c = 0; c< pTab->getNoOfColumns(); c++){
2062     const NdbDictionary::Column * col = pTab->getColumn(c);
2063     if(col->getNullable()){
2064       pIdx.addIndexColumn(col->getName());
2065       ndbout << col->getName() <<" ";
2066       colId = c;
2067       break;
2068     }
2069   }
2070   ndbout << ") ";
2071 
2072   if(colId == -1){
2073     ndbout << endl << "No nullable column found -> NDBT_FAILED" << endl;
2074     return NDBT_FAILED;
2075   }
2076 
2077   bool noddl= ctx->getProperty("NoDDL");
2078   if (noddl)
2079   {
2080     const NdbDictionary::Index* idx= pNdb->
2081       getDictionary()->getIndex(pIdx.getName(), pTab->getName());
2082 
2083     if (!idx)
2084     {
2085       ndbout << "Failed - Index does not exist and DDL not allowed" << endl;
2086       NDB_ERR(pNdb->getDictionary()->getNdbError());
2087       return NDBT_FAILED;
2088     }
2089     else
2090     {
2091       // TODO : Check index definition is ok
2092     }
2093   }
2094   else
2095   {
2096     if (pNdb->getDictionary()->createIndex(pIdx) != 0){
2097       ndbout << "FAILED!" << endl;
2098       const NdbError err = pNdb->getDictionary()->getNdbError();
2099       NDB_ERR(err);
2100       return NDBT_FAILED;
2101     }
2102   }
2103 
2104   int result = NDBT_OK;
2105 
2106   HugoTransactions hugoTrans(*ctx->getTab());
2107   const int batchSize = ctx->getProperty("BatchSize", 50);
2108   int loops = ctx->getNumLoops();
2109   int rows = ctx->getNumRecords();
2110   while (loops-- > 0 && ctx->isTestStopped() == false) {
2111     if (hugoTrans.pkUpdateRecords(pNdb, rows, batchSize) != 0){
2112       g_err << "Updated table failed" << endl;
2113       result = NDBT_FAILED;
2114       goto done;
2115     }
2116   }
2117 
2118   if(ctx->isTestStopped()){
2119     goto done;
2120   }
2121 
2122   ctx->stopTest();
2123   while(ctx->getNoOfRunningSteps() > 1){
2124     NdbSleep_MilliSleep(100);
2125   }
2126 
2127   result = NDBT_FAILED;
2128   pTrans = pNdb->startTransaction();
2129   NdbScanOperation * sOp;
2130 
2131   int eof;
2132   if(!pTrans) goto done;
2133   sOp = pTrans->getNdbScanOperation(pTab->getName());
2134   if(!sOp) goto done;
2135   if(sOp->readTuples(NdbScanOperation::LM_Exclusive)) goto done;
2136   if(pTrans->execute(NoCommit) == -1) goto done;
2137   while((eof = sOp->nextResult(true)) == 0){
2138     do {
2139       NdbOperation * uOp = sOp->updateCurrentTuple();
2140       if(uOp == 0) goto done;
2141       uOp->setValue(colId, 0);
2142     } while((eof = sOp->nextResult(false)) == 0);
2143     eof = pTrans->execute(Commit);
2144     if(eof == -1) goto done;
2145   }
2146 
2147  done:
2148   if(pTrans) pNdb->closeTransaction(pTrans);
2149   pNdb->getDictionary()->dropIndex(nullIndex, pTab->getName());
2150   return result;
2151 }
2152 
runLQHKEYREF(NDBT_Context * ctx,NDBT_Step * step)2153 int runLQHKEYREF(NDBT_Context* ctx, NDBT_Step* step){
2154   int loops = ctx->getNumLoops() * 100;
2155   NdbRestarter restarter;
2156 
2157   myRandom48Init((long)NdbTick_CurrentMillisecond());
2158 
2159 #if 0
2160   int val = DumpStateOrd::DihMinTimeBetweenLCP;
2161   if(restarter.dumpStateAllNodes(&val, 1) != 0){
2162     g_err << "Failed to dump DihMinTimeBetweenLCP" << endl;
2163     return NDBT_FAILED;
2164   }
2165 #endif
2166 
2167   for(int i = 0; i<loops && !ctx->isTestStopped(); i++){
2168     int randomId = myRandom48(restarter.getNumDbNodes());
2169     int nodeId = restarter.getDbNodeId(randomId);
2170 
2171     const Uint32 error = 5031 + (i % 3);
2172 
2173     if(restarter.insertErrorInNode(nodeId, error) != 0){
2174       g_err << "Failed to error insert( " << error << ") in node "
2175 	    << nodeId << endl;
2176       return NDBT_FAILED;
2177     }
2178   }
2179 
2180   ctx->stopTest();
2181   return NDBT_OK;
2182 }
2183 
2184 int
runBug21384(NDBT_Context * ctx,NDBT_Step * step)2185 runBug21384(NDBT_Context* ctx, NDBT_Step* step)
2186 {
2187   Ndb* pNdb = GETNDB(step);
2188   HugoTransactions hugoTrans(*ctx->getTab());
2189   NdbRestarter restarter;
2190 
2191   int loops = ctx->getNumLoops();
2192   const int rows = ctx->getNumRecords();
2193   const int batchsize = ctx->getProperty("BatchSize", 50);
2194 
2195   while (loops--)
2196   {
2197     if(restarter.insertErrorInAllNodes(8037) != 0)
2198     {
2199       g_err << "Failed to error insert(8037)" << endl;
2200       return NDBT_FAILED;
2201     }
2202 
2203     if (hugoTrans.indexReadRecords(pNdb, pkIdxName, rows, batchsize) == 0)
2204     {
2205       g_err << "Index succeded (it should have failed" << endl;
2206       return NDBT_FAILED;
2207     }
2208 
2209     if(restarter.insertErrorInAllNodes(0) != 0)
2210     {
2211       g_err << "Failed to error insert(0)" << endl;
2212       return NDBT_FAILED;
2213     }
2214 
2215     if (hugoTrans.indexReadRecords(pNdb, pkIdxName, rows, batchsize) != 0){
2216       g_err << "Index read failed" << endl;
2217       return NDBT_FAILED;
2218     }
2219   }
2220 
2221   return NDBT_OK;
2222 }
2223 
2224 int
runReadIndexUntilStopped(NDBT_Context * ctx,NDBT_Step * step)2225 runReadIndexUntilStopped(NDBT_Context* ctx, NDBT_Step* step)
2226 {
2227   Ndb* pNdb = GETNDB(step);
2228   HugoTransactions hugoTrans(*ctx->getTab());
2229   int rows = ctx->getNumRecords();
2230   while (!ctx->isTestStopped())
2231   {
2232     hugoTrans.indexReadRecords(pNdb, pkIdxName, rows, 1);
2233   }
2234   return NDBT_OK;
2235 }
2236 
2237 int
runBug25059(NDBT_Context * ctx,NDBT_Step * step)2238 runBug25059(NDBT_Context* ctx, NDBT_Step* step)
2239 {
2240   Ndb* pNdb = GETNDB(step);
2241   NdbDictionary::Dictionary * dict = pNdb->getDictionary();
2242   const NdbDictionary::Index * idx = dict->getIndex(pkIdxName,
2243 						    ctx->getTab()->getName());
2244 
2245   HugoOperations ops(*ctx->getTab(), idx);
2246 
2247   int res = NDBT_OK;
2248   int loops = ctx->getNumLoops();
2249   const int rows = ctx->getNumRecords();
2250 
2251   while (res == NDBT_OK && loops--)
2252   {
2253     ops.startTransaction(pNdb);
2254     ops.pkReadRecord(pNdb, 10 + rand() % rows, rows);
2255     int tmp;
2256     if ((tmp = ops.execute_Commit(pNdb, AO_IgnoreError)))
2257     {
2258       if (tmp == 4012)
2259 	res = NDBT_FAILED;
2260       else
2261 	if (ops.getTransaction()->getNdbError().code == 4012)
2262 	  res = NDBT_FAILED;
2263     }
2264     ops.closeTransaction(pNdb);
2265   }
2266 
2267   loops = ctx->getNumLoops();
2268   while (res == NDBT_OK && loops--)
2269   {
2270     ops.startTransaction(pNdb);
2271     ops.pkUpdateRecord(pNdb, 10 + rand() % rows, rows);
2272     int tmp;
2273     int arg;
2274     switch(rand() % 2){
2275     case 0:
2276       arg = AbortOnError;
2277       break;
2278     case 1:
2279       arg = AO_IgnoreError;
2280       ndbout_c("ignore error");
2281       break;
2282     }
2283     if ((tmp = ops.execute_Commit(pNdb, (AbortOption)arg)))
2284     {
2285       if (tmp == 4012)
2286 	res = NDBT_FAILED;
2287       else
2288 	if (ops.getTransaction()->getNdbError().code == 4012)
2289 	  res = NDBT_FAILED;
2290     }
2291     ops.closeTransaction(pNdb);
2292   }
2293 
2294   return res;
2295 }
2296 
2297 // From 6.3.X, Unique index operations do not use
2298 // TransactionBufferMemory.
2299 // Long signal KeyInfo and AttrInfo storage exhaustion
2300 // is already tested by testLimits
2301 // Testing of segment exhaustion when accumulating from
2302 // signal trains cannot be tested from 7.0 as we cannot
2303 // generate short signal trains.
2304 // TODO : Execute testcase as part of upgrade testing -
2305 // 6.3 to 7.0?
tcSaveINDX_test(NDBT_Context * ctx,NDBT_Step * step,int inject_err)2306 int tcSaveINDX_test(NDBT_Context* ctx, NDBT_Step* step, int inject_err)
2307 {
2308   int result= NDBT_OK;
2309   Ndb* pNdb = GETNDB(step);
2310   NdbDictionary::Dictionary * dict = pNdb->getDictionary();
2311   const NdbDictionary::Index * idx = dict->getIndex(pkIdxName,
2312                                                     ctx->getTab()->getName());
2313 
2314   HugoOperations ops(*ctx->getTab(), idx);
2315 
2316   g_err << "Using INDEX: " << pkIdxName << endl;
2317 
2318   NdbRestarter restarter;
2319 
2320   int loops = ctx->getNumLoops();
2321   const int rows = ctx->getNumRecords();
2322 
2323   for(int bs=1; bs < loops; bs++)
2324   {
2325     int c= 0;
2326     while (c++ < loops)
2327     {
2328       g_err << "BS " << bs << " LOOP #" << c << endl;
2329 
2330       g_err << "inserting error on op#" << c << endl;
2331 
2332       CHECK(ops.startTransaction(pNdb) == 0);
2333       for(int i=1;i<=c;i++)
2334       {
2335         if(i==c)
2336         {
2337           if(restarter.insertErrorInAllNodes(inject_err)!=0)
2338           {
2339             g_err << "**** FAILED to insert error" << endl;
2340             result= NDBT_FAILED;
2341             break;
2342           }
2343         }
2344         CHECK(ops.indexReadRecords(pNdb, pkIdxName, i,false,1) == 0);
2345         if(i%bs==0 || i==c)
2346         {
2347           if(i<c)
2348           {
2349             if(ops.execute_NoCommit(pNdb, AO_IgnoreError)!=NDBT_OK)
2350             {
2351               g_err << "**** executeNoCommit should have succeeded" << endl;
2352               result= NDBT_FAILED;
2353             }
2354           }
2355           else
2356           {
2357             if(ops.execute_NoCommit(pNdb, AO_IgnoreError)!=289)
2358             {
2359               g_err << "**** executeNoCommit should have failed with 289"
2360                     << endl;
2361               result= NDBT_FAILED;
2362             }
2363             g_err << "NdbError.code= " <<
2364               ops.getTransaction()->getNdbError().code << endl;
2365             break;
2366           }
2367         }
2368       }
2369 
2370       CHECK(ops.closeTransaction(pNdb) == 0);
2371 
2372       if(restarter.insertErrorInAllNodes(0) != 0)
2373       {
2374         g_err << "**** Failed to error insert(0)" << endl;
2375         return NDBT_FAILED;
2376       }
2377 
2378       CHECK(ops.startTransaction(pNdb) == 0);
2379       if (ops.indexReadRecords(pNdb, pkIdxName,0,0,rows) != 0){
2380         g_err << "**** Index read failed" << endl;
2381         return NDBT_FAILED;
2382       }
2383       CHECK(ops.closeTransaction(pNdb) == 0);
2384     }
2385   }
2386 
2387   return result;
2388 }
2389 
2390 int
runBug28804(NDBT_Context * ctx,NDBT_Step * step)2391 runBug28804(NDBT_Context* ctx, NDBT_Step* step)
2392 {
2393   return tcSaveINDX_test(ctx, step, 8052);
2394 }
2395 
2396 int
runBug28804_ATTRINFO(NDBT_Context * ctx,NDBT_Step * step)2397 runBug28804_ATTRINFO(NDBT_Context* ctx, NDBT_Step* step)
2398 {
2399   return tcSaveINDX_test(ctx, step, 8051);
2400 }
2401 
2402 int
runBug46069(NDBT_Context * ctx,NDBT_Step * step)2403 runBug46069(NDBT_Context* ctx, NDBT_Step* step)
2404 {
2405   HugoTransactions hugoTrans(*ctx->getTab());
2406   Ndb* pNdb = GETNDB(step);
2407   const int rows = ctx->getNumRecords();
2408   Uint32 threads = ctx->getProperty("THREADS", 12);
2409   int loops = ctx->getNumLoops();
2410 
2411   ctx->getPropertyWait("STARTED", threads);
2412 
2413   for (int i = 0; i<loops; i++)
2414   {
2415     ndbout << "Loop: " << i << endl;
2416     if (hugoTrans.loadTable(pNdb, rows) != 0)
2417       return NDBT_FAILED;
2418 
2419     ctx->setProperty("STARTED", Uint32(0));
2420     ctx->getPropertyWait("STARTED", threads);
2421   }
2422 
2423   ctx->stopTest();
2424   return NDBT_OK;
2425 }
2426 
2427 int
runBug46069_pkdel(NDBT_Context * ctx,NDBT_Step * step)2428 runBug46069_pkdel(NDBT_Context* ctx, NDBT_Step* step)
2429 {
2430   HugoOperations hugoOps(*ctx->getTab());
2431   Ndb* pNdb = GETNDB(step);
2432   const int rows = ctx->getNumRecords();
2433 
2434   while(!ctx->isTestStopped())
2435   {
2436     ctx->incProperty("STARTED");
2437     ctx->getPropertyWait("STARTED", Uint32(0));
2438     if (ctx->isTestStopped())
2439       break;
2440 
2441     for (int i = 0; i<rows && !ctx->isTestStopped(); )
2442     {
2443       int cnt = (rows - i);
2444       if (cnt > 100)
2445         cnt = 100;
2446       cnt = 1 + (rand() % cnt);
2447       if (hugoOps.startTransaction(pNdb) != 0)
2448       {
2449         break;
2450       }
2451       hugoOps.pkDeleteRecord(pNdb, i, cnt);
2452       int res = hugoOps.execute_Commit(pNdb, AO_IgnoreError);
2453       if (res != -1)
2454       {
2455         i += cnt;
2456       }
2457       hugoOps.closeTransaction(pNdb);
2458     }
2459   }
2460 
2461   return NDBT_OK;
2462 }
2463 
2464 int
runBug46069_scandel(NDBT_Context * ctx,NDBT_Step * step)2465 runBug46069_scandel(NDBT_Context* ctx, NDBT_Step* step)
2466 {
2467   Ndb* pNdb = GETNDB(step);
2468   NdbDictionary::Dictionary * dict = pNdb->getDictionary();
2469   const NdbDictionary::Index * idx = dict->getIndex(pkIdxName,
2470 						    ctx->getTab()->getName());
2471   if (idx == 0)
2472   {
2473     return NDBT_FAILED;
2474   }
2475   UtilTransactions hugoTrans(*ctx->getTab(), idx);
2476 
2477   while(!ctx->isTestStopped())
2478   {
2479     ctx->incProperty("STARTED");
2480     ctx->getPropertyWait("STARTED", Uint32(0));
2481     if (ctx->isTestStopped())
2482       break;
2483 
2484     hugoTrans.clearTable(pNdb);
2485   }
2486 
2487   return NDBT_OK;
2488 }
2489 
2490 int
runBug50118(NDBT_Context * ctx,NDBT_Step * step)2491 runBug50118(NDBT_Context* ctx, NDBT_Step* step)
2492 {
2493   NdbSleep_MilliSleep(500);
2494   int loops = ctx->getNumLoops();
2495   while (loops--)
2496   {
2497     createPkIndex_Drop(ctx, step);
2498     createPkIndex(ctx, step);
2499   }
2500   ctx->stopTest();
2501   return NDBT_OK;
2502 }
2503 
2504 int
runTrigOverload(NDBT_Context * ctx,NDBT_Step * step)2505 runTrigOverload(NDBT_Context* ctx, NDBT_Step* step)
2506 {
2507   /* Test inserts, deletes and updates via
2508    * PK with error inserts
2509    */
2510   Ndb* pNdb = GETNDB(step);
2511   HugoOperations hugoOps(*ctx->getTab());
2512   NdbRestarter restarter;
2513 
2514   unsigned numScenarios = 3;
2515   unsigned errorInserts[3] = {8085, 8086, 0};
2516   int results[3] = {
2517     293, // Inconsistent trigger state in TC block
2518     218, // Out of LongMessageBuffer
2519     0
2520   };
2521 
2522   unsigned iterations = 50;
2523 
2524   /* Insert some records */
2525   if (hugoOps.startTransaction(pNdb) ||
2526       hugoOps.pkInsertRecord(pNdb, 0, iterations) ||
2527       hugoOps.execute_Commit(pNdb))
2528   {
2529     g_err << "Failed on initial insert "
2530           << pNdb->getNdbError()
2531           << endl;
2532     return NDBT_FAILED;
2533   }
2534 
2535   hugoOps.closeTransaction(pNdb);
2536 
2537   for(unsigned i = 0 ; i < iterations; i++)
2538   {
2539     unsigned scenario = i % numScenarios;
2540     unsigned errorVal = errorInserts[ scenario ];
2541     g_err << "Iteration :" << i
2542           << " inserting error " << errorVal
2543           << " expecting result : " << results[scenario]
2544           << endl;
2545     restarter.insertErrorInAllNodes(errorVal);
2546     //    NdbSleep_MilliSleep(500); // Error insert latency?
2547 
2548     CHECKRET(hugoOps.startTransaction(pNdb) == 0);
2549 
2550     CHECKRET(hugoOps.pkInsertRecord(pNdb, iterations + i, 1) == 0);
2551 
2552     hugoOps.execute_Commit(pNdb);
2553 
2554     int errorCode = hugoOps.getTransaction()->getNdbError().code;
2555 
2556     if (errorCode != results[scenario])
2557     {
2558       g_err << "For Insert in scenario " << scenario
2559             << " expected code " << results[scenario]
2560             << " but got " << hugoOps.getTransaction()->getNdbError()
2561             << endl;
2562       return NDBT_FAILED;
2563     }
2564 
2565     hugoOps.closeTransaction(pNdb);
2566 
2567     CHECKRET(hugoOps.startTransaction(pNdb) == 0);
2568 
2569     CHECKRET(hugoOps.pkUpdateRecord(pNdb, i, 1, iterations) == 0);
2570 
2571     hugoOps.execute_Commit(pNdb);
2572 
2573     errorCode = hugoOps.getTransaction()->getNdbError().code;
2574 
2575     if (errorCode != results[scenario])
2576     {
2577       g_err << "For Update in scenario " << scenario
2578             << " expected code " << results[scenario]
2579             << " but got " << hugoOps.getTransaction()->getNdbError()
2580             << endl;
2581       return NDBT_FAILED;
2582     }
2583 
2584     hugoOps.closeTransaction(pNdb);
2585 
2586     CHECKRET(hugoOps.startTransaction(pNdb) == 0);
2587 
2588     CHECKRET(hugoOps.pkDeleteRecord(pNdb, i, 1) == 0);
2589 
2590     hugoOps.execute_Commit(pNdb);
2591 
2592     errorCode = hugoOps.getTransaction()->getNdbError().code;
2593 
2594     if (errorCode != results[scenario])
2595     {
2596       g_err << "For Delete in scenario " << scenario
2597             << " expected code " << results[scenario]
2598             << " but got " << hugoOps.getTransaction()->getNdbError()
2599             << endl;
2600       return NDBT_FAILED;
2601     }
2602 
2603     hugoOps.closeTransaction(pNdb);
2604 
2605   }
2606 
2607   restarter.insertErrorInAllNodes(0);
2608 
2609   return NDBT_OK;
2610 }
2611 
2612 int
runClearError(NDBT_Context * ctx,NDBT_Step * step)2613 runClearError(NDBT_Context* ctx, NDBT_Step* step)
2614 {
2615   NdbRestarter restarter;
2616 
2617   restarter.insertErrorInAllNodes(0);
2618 
2619   return NDBT_OK;
2620 }
2621 
2622 // bug#56829
2623 
2624 #undef CHECK2 // previous no good
2625 #define CHECK2(b, e) \
2626   if (!(b)) { \
2627     g_err << "ERR: " << #b << " failed at line " << __LINE__ \
2628           << ": " << e << endl; \
2629     result = NDBT_FAILED; \
2630     break; \
2631   }
2632 
2633 static int
get_data_memory_pages(NdbMgmHandle h,NdbNodeBitmask dbmask,int * pages_out)2634 get_data_memory_pages(NdbMgmHandle h, NdbNodeBitmask dbmask, int* pages_out)
2635 {
2636   int result = NDBT_OK;
2637   int pages = 0;
2638 
2639   while (1)
2640   {
2641     // sends dump 1000 and retrieves all replies
2642     ndb_mgm_events* e = 0;
2643     CHECK2((e = ndb_mgm_dump_events(h, NDB_LE_MemoryUsage, 0, 0)) != 0, ndb_mgm_get_latest_error_msg(h));
2644 
2645     // sum up pages (also verify sanity)
2646     for (int i = 0; i < e->no_of_events; i++)
2647     {
2648       ndb_logevent* le = &e->events[i];
2649       CHECK2(le->type == NDB_LE_MemoryUsage, "bad event type " << le->type);
2650       const ndb_logevent_MemoryUsage* lem = &le->MemoryUsage;
2651       if (lem->block != DBTUP)
2652         continue;
2653       int nodeId = le->source_nodeid;
2654       CHECK2(dbmask.get(nodeId), "duplicate event from node " << nodeId);
2655       dbmask.clear(nodeId);
2656       pages += lem->pages_used;
2657       g_info << "i:" << i << " node:" << le->source_nodeid << " pages:" << lem->pages_used << endl;
2658     }
2659     free(e);
2660     CHECK2(result == NDBT_OK, "failed");
2661 
2662     char buf[NdbNodeBitmask::TextLength + 1];
2663     CHECK2(dbmask.isclear(), "no response from nodes " << dbmask.getText(buf));
2664     break;
2665   }
2666 
2667   *pages_out = pages;
2668   return result;
2669 }
2670 
2671 int
runBug56829(NDBT_Context * ctx,NDBT_Step * step)2672 runBug56829(NDBT_Context* ctx, NDBT_Step* step)
2673 {
2674   Ndb* pNdb = GETNDB(step);
2675   NdbDictionary::Dictionary* pDic = pNdb->getDictionary();
2676   const int loops = ctx->getNumLoops();
2677   int result = NDBT_OK;
2678   const NdbDictionary::Table tab(*ctx->getTab());
2679   const int rows = ctx->getNumRecords();
2680   const char* mgm = 0;//XXX ctx->getRemoteMgm();
2681 
2682   char tabname[100];
2683   strcpy(tabname, tab.getName());
2684   char indname[100];
2685   strcpy(indname, tabname);
2686   strcat(indname, "X1");
2687 
2688   (void)pDic->dropTable(tabname);
2689 
2690   NdbMgmHandle h = 0;
2691   NdbNodeBitmask dbmask;
2692   // entry n marks if row with PK n exists
2693   char* rowmask = new char [rows];
2694   memset(rowmask, 0, rows);
2695   int loop = 0;
2696   while (loop < loops)
2697   {
2698     CHECK2(rows > 0, "rows must be != 0");
2699     g_info << "loop " << loop << "<" << loops << endl;
2700 
2701     // at first loop connect to mgm
2702     if (loop == 0)
2703     {
2704       CHECK2((h = ndb_mgm_create_handle()) != 0, "mgm: failed to create handle");
2705       CHECK2(ndb_mgm_set_connectstring(h, mgm) == 0, ndb_mgm_get_latest_error_msg(h));
2706       CHECK2(ndb_mgm_connect(h, 0, 0, 0) == 0, ndb_mgm_get_latest_error_msg(h));
2707       g_info << "mgm: connected to " << (mgm ? mgm : "default") << endl;
2708 
2709       // make bitmask of DB nodes
2710       dbmask.clear();
2711       ndb_mgm_cluster_state* cs = 0;
2712       CHECK2((cs = ndb_mgm_get_status(h)) != 0, ndb_mgm_get_latest_error_msg(h));
2713       for (int j = 0; j < cs->no_of_nodes; j++)
2714       {
2715         ndb_mgm_node_state* ns = &cs->node_states[j];
2716         if (ns->node_type == NDB_MGM_NODE_TYPE_NDB)
2717         {
2718           CHECK2(ns->node_status == NDB_MGM_NODE_STATUS_STARTED, "node " << ns->node_id << " not started status " << ns->node_status);
2719           CHECK2(!dbmask.get(ns->node_id), "duplicate node id " << ns->node_id);
2720           dbmask.set(ns->node_id);
2721           g_info << "added DB node " << ns->node_id << endl;
2722         }
2723       }
2724       free(cs);
2725       CHECK2(result == NDBT_OK, "some DB nodes are not started");
2726       CHECK2(!dbmask.isclear(), "found no DB nodes");
2727     }
2728 
2729     // data memory pages after following events
2730     // 0-initial 1,2-create table,index 3-load 4-delete 5,6-drop index,table
2731     int pages[7];
2732 
2733     // initial
2734     CHECK2(get_data_memory_pages(h, dbmask, &pages[0]) == NDBT_OK, "failed");
2735     g_info << "initial pages " << pages[0] << endl;
2736 
2737     // create table
2738     g_info << "create table " << tabname << endl;
2739     const NdbDictionary::Table* pTab = 0;
2740     CHECK2(pDic->createTable(tab) == 0, pDic->getNdbError());
2741     CHECK2((pTab = pDic->getTable(tabname)) != 0, pDic->getNdbError());
2742     CHECK2(get_data_memory_pages(h, dbmask, &pages[1]) == NDBT_OK, "failed");
2743     g_info << "create table pages " << pages[1] << endl;
2744 
2745     // choice of index attributes is not relevant to this bug
2746     // choose one non-PK updateable column
2747     NdbDictionary::Index ind;
2748     ind.setName(indname);
2749     ind.setTable(tabname);
2750     ind.setType(NdbDictionary::Index::OrderedIndex);
2751     ind.setLogging(false);
2752     {
2753       HugoCalculator calc(*pTab);
2754       for (int j = 0; j < pTab->getNoOfColumns(); j++)
2755       {
2756         const NdbDictionary::Column* col = pTab->getColumn(j);
2757         if (col->getPrimaryKey() || calc.isUpdateCol(j))
2758           continue;
2759         //CHARSET_INFO* cs = col->getCharset();
2760         if (NdbSqlUtil::check_column_for_ordered_index(col->getType(), col->getCharset()) == 0)
2761         {
2762           ind.addColumn(*col);
2763           break;
2764         }
2765       }
2766     }
2767     CHECK2(ind.getNoOfColumns() == 1, "cannot use table " << tabname);
2768 
2769     // create index
2770     g_info << "create index " << indname << " on " << ind.getColumn(0)->getName() << endl;
2771     const NdbDictionary::Index* pInd = 0;
2772     CHECK2(pDic->createIndex(ind, *pTab) == 0, pDic->getNdbError());
2773     CHECK2((pInd = pDic->getIndex(indname, tabname)) != 0, pDic->getNdbError());
2774     CHECK2(get_data_memory_pages(h, dbmask, &pages[2]) == NDBT_OK, "failed");
2775     g_info << "create index pages " << pages[2] << endl;
2776 
2777     HugoTransactions trans(*pTab);
2778 
2779     // load all records
2780     g_info << "load records" << endl;
2781     CHECK2(trans.loadTable(pNdb, rows) == 0, trans.getNdbError());
2782     memset(rowmask, 1, rows);
2783     CHECK2(get_data_memory_pages(h, dbmask, &pages[3]) == NDBT_OK, "failed");
2784     g_info << "load records pages " << pages[3] << endl;
2785 
2786     // test index with random ops
2787     g_info << "test index ops" << endl;
2788     {
2789       HugoOperations ops(*pTab);
2790       for (int i = 0; i < rows; i++)
2791       {
2792         CHECK2(ops.startTransaction(pNdb) == 0, ops.getNdbError());
2793         for (int j = 0; j < 32; j++)
2794         {
2795           int n = rand() % rows;
2796           if (!rowmask[n])
2797           {
2798             CHECK2(ops.pkInsertRecord(pNdb, n) == 0, ops.getNdbError());
2799             rowmask[n] = 1;
2800           }
2801           else if (rand() % 2 == 0)
2802           {
2803             CHECK2(ops.pkDeleteRecord(pNdb, n) == 0, ops.getNdbError());
2804             rowmask[n] = 0;
2805           }
2806           else
2807           {
2808             CHECK2(ops.pkUpdateRecord(pNdb, n) == 0, ops.getNdbError());
2809           }
2810         }
2811         CHECK2(result == NDBT_OK, "index ops batch failed");
2812         CHECK2(ops.execute_Commit(pNdb) == 0, ops.getNdbError());
2813         ops.closeTransaction(pNdb);
2814       }
2815       CHECK2(result == NDBT_OK, "index ops failed");
2816     }
2817 
2818     // delete all records
2819     g_info << "delete records" << endl;
2820     CHECK2(trans.clearTable(pNdb) == 0, trans.getNdbError());
2821     memset(rowmask, 0, rows);
2822     CHECK2(get_data_memory_pages(h, dbmask, &pages[4]) == NDBT_OK, "failed");
2823     g_info << "delete records pages " << pages[4] << endl;
2824 
2825     // drop index
2826     g_info << "drop index" <<  endl;
2827     CHECK2(pDic->dropIndex(indname, tabname) == 0, pDic->getNdbError());
2828     CHECK2(get_data_memory_pages(h, dbmask, &pages[5]) == NDBT_OK, "failed");
2829     g_info << "drop index pages " << pages[5] << endl;
2830 
2831     // drop table
2832     g_info << "drop table" << endl;
2833     CHECK2(pDic->dropTable(tabname) == 0, pDic->getNdbError());
2834     CHECK2(get_data_memory_pages(h, dbmask, &pages[6]) == NDBT_OK, "failed");
2835     g_info << "drop table pages " << pages[6] << endl;
2836 
2837     // verify
2838     CHECK2(pages[1] == pages[0], "pages after create table " << pages[1]
2839                                   << " not == initial pages " << pages[0]);
2840     CHECK2(pages[2] == pages[0], "pages after create index " << pages[2]
2841                                   << " not == initial pages " << pages[0]);
2842     CHECK2(pages[3] >  pages[0], "pages after load " << pages[3]
2843                                   << " not >  initial pages " << pages[0]);
2844     CHECK2(pages[4] == pages[0], "pages after delete " << pages[4]
2845                                   << " not == initial pages " << pages[0]);
2846     CHECK2(pages[5] == pages[0], "pages after drop index " << pages[5]
2847                                   << " not == initial pages " << pages[0]);
2848     CHECK2(pages[6] == pages[0], "pages after drop table " << pages[6]
2849                                   << " not == initial pages " << pages[0]);
2850 
2851     loop++;
2852 
2853     // at last loop disconnect from mgm
2854     if (loop == loops)
2855     {
2856       CHECK2(ndb_mgm_disconnect(h) == 0, ndb_mgm_get_latest_error_msg(h));
2857       ndb_mgm_destroy_handle(&h);
2858       g_info << "mgm: disconnected" << endl;
2859     }
2860   }
2861   delete [] rowmask;
2862 
2863   return result;
2864 }
2865 
2866 #define CHK_RET_FAILED(x) if (!(x)) { ndbout_c("Failed on line: %u", __LINE__); return NDBT_FAILED; }
2867 
2868 int
runBug12315582(NDBT_Context * ctx,NDBT_Step * step)2869 runBug12315582(NDBT_Context* ctx, NDBT_Step* step)
2870 {
2871   const NdbDictionary::Table * pTab = ctx->getTab();
2872   Ndb* pNdb = GETNDB(step);
2873   NdbDictionary::Dictionary * dict = pNdb->getDictionary();
2874 
2875   const NdbDictionary::Index* pIdx= dict->getIndex(pkIdxName, pTab->getName());
2876   CHK_RET_FAILED(pIdx != 0);
2877 
2878   const NdbRecord * pRowRecord = pTab->getDefaultRecord();
2879   CHK_RET_FAILED(pRowRecord != 0);
2880   const NdbRecord * pIdxRecord = pIdx->getDefaultRecord();
2881   CHK_RET_FAILED(pIdxRecord != 0);
2882 
2883   const Uint32 len = NdbDictionary::getRecordRowLength(pRowRecord);
2884   Uint8 * pRow = new Uint8[len];
2885   bzero(pRow, len);
2886 
2887   HugoCalculator calc(* pTab);
2888   calc.equalForRow(pRow, pRowRecord, 0);
2889 
2890   NdbTransaction* pTrans = pNdb->startTransaction();
2891   CHK_RET_FAILED(pTrans != 0);
2892 
2893   const NdbOperation * pOp[2] = { 0, 0 };
2894   for (Uint32 i = 0; i<2; i++)
2895   {
2896     NdbInterpretedCode code;
2897     if (i == 0)
2898       code.interpret_exit_ok();
2899     else
2900       code.interpret_exit_nok();
2901 
2902     code.finalise();
2903 
2904     NdbOperation::OperationOptions opts;
2905     bzero(&opts, sizeof(opts));
2906     opts.optionsPresent = NdbOperation::OperationOptions::OO_INTERPRETED;
2907     opts.interpretedCode = &code;
2908 
2909     pOp[i] = pTrans->readTuple(pIdxRecord, (char*)pRow,
2910                                pRowRecord, (char*)pRow,
2911                                NdbOperation::LM_Read,
2912                                0,
2913                                &opts,
2914                                sizeof(opts));
2915     CHK_RET_FAILED(pOp[i]);
2916   }
2917 
2918   int res = pTrans->execute(Commit, AO_IgnoreError);
2919 
2920   CHK_RET_FAILED(res == 0);
2921   CHK_RET_FAILED(pOp[0]->getNdbError().code == 0);
2922   CHK_RET_FAILED(pOp[1]->getNdbError().code != 0);
2923 
2924   delete [] pRow;
2925 
2926   return NDBT_OK;
2927 }
2928 
2929 int
runBug60851(NDBT_Context * ctx,NDBT_Step * step)2930 runBug60851(NDBT_Context* ctx, NDBT_Step* step)
2931 {
2932   const NdbDictionary::Table * pTab = ctx->getTab();
2933   Ndb* pNdb = GETNDB(step);
2934   NdbDictionary::Dictionary * dict = pNdb->getDictionary();
2935 
2936   const NdbDictionary::Index* pIdx= dict->getIndex(pkIdxName, pTab->getName());
2937   CHK_RET_FAILED(pIdx != 0);
2938 
2939   const NdbRecord * pRowRecord = pTab->getDefaultRecord();
2940   CHK_RET_FAILED(pRowRecord != 0);
2941   const NdbRecord * pIdxRecord = pIdx->getDefaultRecord();
2942   CHK_RET_FAILED(pIdxRecord != 0);
2943 
2944   const Uint32 len = NdbDictionary::getRecordRowLength(pRowRecord);
2945   Uint8 * pRow = new Uint8[len];
2946 
2947   NdbTransaction* pTrans = pNdb->startTransaction();
2948   CHK_RET_FAILED(pTrans != 0);
2949 
2950   const NdbOperation * pOp[3] = { 0, 0, 0};
2951   for (Uint32 i = 0; i<3; i++)
2952   {
2953     NdbInterpretedCode code;
2954     if (i == 1)
2955       code.interpret_exit_nok();
2956     else
2957       code.interpret_exit_ok();
2958 
2959     code.finalise();
2960 
2961     bzero(pRow, len);
2962     HugoCalculator calc(* pTab);
2963     calc.equalForRow(pRow, pRowRecord, i);
2964 
2965     NdbOperation::OperationOptions opts;
2966     bzero(&opts, sizeof(opts));
2967     opts.optionsPresent = NdbOperation::OperationOptions::OO_INTERPRETED;
2968     opts.interpretedCode = &code;
2969 
2970     pOp[i] = pTrans->deleteTuple(pIdxRecord, (char*)pRow,
2971                                  pRowRecord, (char*)pRow,
2972                                  0,
2973                                  &opts,
2974                                  sizeof(opts));
2975     CHK_RET_FAILED(pOp[i]);
2976   }
2977 
2978   int res = pTrans->execute(Commit, AO_IgnoreError);
2979 
2980   CHK_RET_FAILED(res == 0);
2981   CHK_RET_FAILED(pOp[0]->getNdbError().code == 0);
2982   CHK_RET_FAILED(pOp[1]->getNdbError().code != 0);
2983   CHK_RET_FAILED(pOp[2]->getNdbError().code == 0);
2984 
2985   delete [] pRow;
2986 
2987   return NDBT_OK;
2988 }
2989 
2990 static
2991 const int
2992 deferred_errors[] = {
2993   5064, 0,
2994   5065, 0,
2995   5066, 0,
2996   5067, 0,
2997   5068, 0,
2998   5069, 0,
2999   5070, 0,
3000   5071, 0,
3001   5072, 1,
3002   8090, 0,
3003   8091, 0,
3004   8092, 2, // connected tc
3005   0, 0 // trailer
3006 };
3007 
3008 int
runTestDeferredError(NDBT_Context * ctx,NDBT_Step * step)3009 runTestDeferredError(NDBT_Context* ctx, NDBT_Step* step)
3010 {
3011   NdbRestarter res;
3012   Ndb* pNdb = GETNDB(step);
3013   const NdbDictionary::Table* pTab = ctx->getTab();
3014 
3015   const int rows = ctx->getNumRecords();
3016 
3017   const NdbRecord * pRowRecord = pTab->getDefaultRecord();
3018   CHK_RET_FAILED(pRowRecord != 0);
3019 
3020   const Uint32 len = NdbDictionary::getRecordRowLength(pRowRecord);
3021   Uint8 * pRow = new Uint8[len];
3022 
3023   for (int i = 0; deferred_errors[i] != 0; i += 2)
3024   {
3025     const int errorno = deferred_errors[i];
3026     const int nodefail = deferred_errors[i+1];
3027 
3028     for (int j = 0; j<3; j++)
3029     {
3030       NdbTransaction* pTrans = pNdb->startTransaction();
3031       CHK_RET_FAILED(pTrans != 0);
3032 
3033       int nodeId =
3034         nodefail == 0 ? 0 :
3035         nodefail == 1 ? res.getNode(NdbRestarter::NS_RANDOM) :
3036         nodefail == 2 ? pTrans->getConnectedNodeId() :
3037         0;
3038 
3039       ndbout_c("errorno: %u(nf: %u - %u) j: %u : %s", errorno,
3040                nodefail, nodeId, j,
3041                j == 0 ? "test before error insert" :
3042                j == 1 ? "test with error insert" :
3043                j == 2 ? "test after error insert" :
3044                "");
3045       if (j == 0 || j == 2)
3046       {
3047         // First time succeed
3048         // Last time succeed
3049       }
3050       else if (nodefail == 0)
3051       {
3052         CHK_RET_FAILED(res.insertErrorInAllNodes(errorno) == 0);
3053       }
3054       else
3055       {
3056         int val2[] = { DumpStateOrd::CmvmiSetRestartOnErrorInsert, 1 };
3057         CHK_RET_FAILED(res.dumpStateOneNode(nodeId, val2, 2) == 0);
3058         CHK_RET_FAILED(res.insertErrorInNode(nodeId, errorno) == 0);
3059       }
3060 
3061       for (int rowNo = 0; rowNo < 100; rowNo++)
3062       {
3063         int rowId = rand() % rows;
3064         bzero(pRow, len);
3065 
3066         HugoCalculator calc(* pTab);
3067         calc.setValues(pRow, pRowRecord, rowId, rand());
3068 
3069         NdbOperation::OperationOptions opts;
3070         bzero(&opts, sizeof(opts));
3071         opts.optionsPresent =
3072           NdbOperation::OperationOptions::OO_DEFERRED_CONSTAINTS;
3073 
3074         const NdbOperation * pOp = pTrans->updateTuple(pRowRecord, (char*)pRow,
3075                                                        pRowRecord, (char*)pRow,
3076                                                        0,
3077                                                        &opts,
3078                                                        sizeof(opts));
3079         CHK_RET_FAILED(pOp != 0);
3080       }
3081 
3082       int result = pTrans->execute(Commit, AO_IgnoreError);
3083       if (j == 0 || j == 2)
3084       {
3085         CHK_RET_FAILED(result == 0);
3086       }
3087       else
3088       {
3089         CHK_RET_FAILED(result != 0);
3090       }
3091       pTrans->close();
3092 
3093 
3094       if (j == 0 || j == 2)
3095       {
3096       }
3097       else
3098       {
3099         if (nodefail)
3100         {
3101           ndbout_c("  waiting for %u to enter not-started", nodeId);
3102           // Wait for a node to enter not-started
3103           CHK_RET_FAILED(res.waitNodesNoStart(&nodeId, 1) == 0);
3104 
3105           ndbout_c("  starting all");
3106           CHK_RET_FAILED(res.startAll() == 0);
3107           ndbout_c("  wait cluster started");
3108           CHK_RET_FAILED(res.waitClusterStarted() == 0);
3109           ndbout_c("  cluster started");
3110         }
3111         CHK_RET_FAILED(res.insertErrorInAllNodes(0) == 0);
3112       }
3113     }
3114   }
3115 
3116   delete [] pRow;
3117 
3118   return NDBT_OK;
3119 }
3120 
3121 int
runMixedDML(NDBT_Context * ctx,NDBT_Step * step)3122 runMixedDML(NDBT_Context* ctx, NDBT_Step* step)
3123 {
3124   Ndb* pNdb = GETNDB(step);
3125   const NdbDictionary::Table* pTab = ctx->getTab();
3126 
3127   unsigned seed = (unsigned)NdbTick_CurrentMillisecond();
3128 
3129   const int rows = ctx->getNumRecords();
3130   const int loops = 10 * ctx->getNumLoops();
3131   const int until_stopped = ctx->getProperty("UntilStopped");
3132   const int deferred = ctx->getProperty("Deferred");
3133   const int batch = ctx->getProperty("Batch", Uint32(50));
3134 
3135   const NdbRecord * pRowRecord = pTab->getDefaultRecord();
3136   CHK_RET_FAILED(pRowRecord != 0);
3137 
3138   const Uint32 len = NdbDictionary::getRecordRowLength(pRowRecord);
3139   Uint8 * pRow = new Uint8[len];
3140 
3141   int count_ok = 0;
3142   int count_failed = 0;
3143   for (int i = 0; i < loops || (until_stopped && !ctx->isTestStopped()); i++)
3144   {
3145     NdbTransaction* pTrans = pNdb->startTransaction();
3146     CHK_RET_FAILED(pTrans != 0);
3147 
3148     int lastrow = 0;
3149     int result = 0;
3150     for (int rowNo = 0; rowNo < batch; rowNo++)
3151     {
3152       int left = rows - lastrow;
3153       int rowId = lastrow;
3154       if (left)
3155       {
3156         rowId += ndb_rand_r(&seed) % (left / 10 + 1);
3157       }
3158       else
3159       {
3160         break;
3161       }
3162       lastrow = rowId;
3163 
3164       bzero(pRow, len);
3165 
3166       HugoCalculator calc(* pTab);
3167       calc.setValues(pRow, pRowRecord, rowId, rand());
3168 
3169       NdbOperation::OperationOptions opts;
3170       bzero(&opts, sizeof(opts));
3171       if (deferred)
3172       {
3173         opts.optionsPresent =
3174           NdbOperation::OperationOptions::OO_DEFERRED_CONSTAINTS;
3175       }
3176 
3177       const NdbOperation* pOp = 0;
3178       switch(ndb_rand_r(&seed) % 3){
3179       case 0:
3180         pOp = pTrans->writeTuple(pRowRecord, (char*)pRow,
3181                                  pRowRecord, (char*)pRow,
3182                                  0,
3183                                  &opts,
3184                                  sizeof(opts));
3185         break;
3186       case 1:
3187         pOp = pTrans->deleteTuple(pRowRecord, (char*)pRow,
3188                                   pRowRecord, (char*)pRow,
3189                                   0,
3190                                   &opts,
3191                                   sizeof(opts));
3192         break;
3193       case 2:
3194         pOp = pTrans->updateTuple(pRowRecord, (char*)pRow,
3195                                   pRowRecord, (char*)pRow,
3196                                   0,
3197                                   &opts,
3198                                   sizeof(opts));
3199         break;
3200       }
3201       CHK_RET_FAILED(pOp != 0);
3202       result = pTrans->execute(NoCommit, AO_IgnoreError);
3203       if (result != 0)
3204       {
3205         goto found_error;
3206       }
3207     }
3208 
3209     result = pTrans->execute(Commit, AO_IgnoreError);
3210     if (result != 0)
3211     {
3212   found_error:
3213       count_failed++;
3214       NdbError err = pTrans->getNdbError();
3215       ndbout << err << endl;
3216       CHK_RET_FAILED(err.code == 1235 ||
3217                      err.code == 1236 ||
3218                      err.code == 5066 ||
3219                      err.status == NdbError::TemporaryError ||
3220                      err.classification == NdbError::NoDataFound ||
3221                      err.classification == NdbError::ConstraintViolation);
3222     }
3223     else
3224     {
3225       count_ok++;
3226     }
3227     pTrans->close();
3228   }
3229 
3230   ndbout_c("count_ok: %d count_failed: %d",
3231            count_ok, count_failed);
3232   delete [] pRow;
3233 
3234   return NDBT_OK;
3235 }
3236 
3237 int
runDeferredError(NDBT_Context * ctx,NDBT_Step * step)3238 runDeferredError(NDBT_Context* ctx, NDBT_Step* step)
3239 {
3240   NdbRestarter res;
3241 
3242   for (int l = 0; l<ctx->getNumLoops() && !ctx->isTestStopped(); l++)
3243   {
3244     for (int i = 0; deferred_errors[i] != 0 && !ctx->isTestStopped(); i += 2)
3245     {
3246       const int errorno = deferred_errors[i];
3247       const int nodefail = deferred_errors[i+1];
3248 
3249       int nodeId = res.getNode(NdbRestarter::NS_RANDOM);
3250 
3251       ndbout_c("errorno: %u (nf: %u - %u)",
3252                errorno,
3253                nodefail, nodeId);
3254 
3255       if (nodefail == 0)
3256       {
3257         CHK_RET_FAILED(res.insertErrorInNode(nodeId, errorno) == 0);
3258         NdbSleep_MilliSleep(300);
3259         CHK_RET_FAILED(res.insertErrorInNode(nodeId, errorno) == 0);
3260       }
3261       else
3262       {
3263         int val2[] = { DumpStateOrd::CmvmiSetRestartOnErrorInsert, 1 };
3264         CHK_RET_FAILED(res.dumpStateOneNode(nodeId, val2, 2) == 0);
3265         CHK_RET_FAILED(res.insertErrorInNode(nodeId, errorno) == 0);
3266         ndbout_c("  waiting for %u to enter not-started", nodeId);
3267         // Wait for a node to enter not-started
3268         CHK_RET_FAILED(res.waitNodesNoStart(&nodeId, 1) == 0);
3269 
3270         ndbout_c("  starting all");
3271         CHK_RET_FAILED(res.startAll() == 0);
3272         ndbout_c("  wait cluster started");
3273         CHK_RET_FAILED(res.waitClusterStarted() == 0);
3274         ndbout_c("  cluster started");
3275       }
3276     }
3277   }
3278 
3279   ctx->stopTest();
3280   return NDBT_OK;
3281 }
3282 
3283 NDBT_TESTSUITE(testIndex);
3284 TESTCASE("CreateAll",
3285 	 "Test that we can create all various indexes on each table\n"
3286 	 "Then drop the indexes\n"){
3287   INITIALIZER(runCreateIndexes);
3288 }
3289 TESTCASE("CreateAll_O",
3290 	 "Test that we can create all various indexes on each table\n"
3291 	 "Then drop the indexes\n"){
3292   TC_PROPERTY("OrderedIndex", 1);
3293   TC_PROPERTY("LoggedIndexes", (unsigned)0);
3294   INITIALIZER(runCreateIndexes);
3295 }
3296 TESTCASE("InsertDeleteGentle",
3297 	 "Create one index, then perform insert and delete in the table\n"
3298 	 "loop number of times. Use batch size 1."){
3299   TC_PROPERTY("BatchSize", 1);
3300   INITIALIZER(runInsertDelete);
3301   FINALIZER(runClearTable);
3302 }
3303 TESTCASE("InsertDeleteGentle_O",
3304 	 "Create one index, then perform insert and delete in the table\n"
3305 	 "loop number of times. Use batch size 1."){
3306   TC_PROPERTY("OrderedIndex", 1);
3307   TC_PROPERTY("LoggedIndexes", (unsigned)0);
3308   TC_PROPERTY("BatchSize", 1);
3309   INITIALIZER(runInsertDelete);
3310   FINALIZER(runClearTable);
3311 }
3312 TESTCASE("InsertDelete",
3313 	 "Create one index, then perform insert and delete in the table\n"
3314 	 "loop number of times. Use batchsize 512 to stress db more"){
3315   TC_PROPERTY("BatchSize", 512);
3316   INITIALIZER(runInsertDelete);
3317   FINALIZER(runClearTable);
3318 
3319 }
3320 TESTCASE("InsertDelete_O",
3321 	 "Create one index, then perform insert and delete in the table\n"
3322 	 "loop number of times. Use batchsize 512 to stress db more"){
3323   TC_PROPERTY("OrderedIndex", 1);
3324   TC_PROPERTY("LoggedIndexes", (unsigned)0);
3325   TC_PROPERTY("BatchSize", 512);
3326   INITIALIZER(runInsertDelete);
3327   FINALIZER(runClearTable);
3328 
3329 }
3330 TESTCASE("CreateLoadDropGentle",
3331 	 "Try to create, drop and load various indexes \n"
3332 	 "on table loop number of times.Usa batch size 1.\n"){
3333   TC_PROPERTY("BatchSize", 1);
3334   INITIALIZER(runCreateLoadDropIndex);
3335 }
3336 TESTCASE("CreateLoadDropGentle_O",
3337 	 "Try to create, drop and load various indexes \n"
3338 	 "on table loop number of times.Usa batch size 1.\n"){
3339   TC_PROPERTY("OrderedIndex", 1);
3340   TC_PROPERTY("LoggedIndexes", (unsigned)0);
3341   TC_PROPERTY("BatchSize", 1);
3342   INITIALIZER(runCreateLoadDropIndex);
3343 }
3344 TESTCASE("CreateLoadDrop",
3345 	 "Try to create, drop and load various indexes \n"
3346 	 "on table loop number of times. Use batchsize 512 to stress db more\n"){
3347   TC_PROPERTY("BatchSize", 512);
3348   INITIALIZER(runCreateLoadDropIndex);
3349 }
3350 TESTCASE("CreateLoadDrop_O",
3351 	 "Try to create, drop and load various indexes \n"
3352 	 "on table loop number of times. Use batchsize 512 to stress db more\n"){
3353   TC_PROPERTY("OrderedIndex", 1);
3354   TC_PROPERTY("LoggedIndexes", (unsigned)0);
3355   TC_PROPERTY("BatchSize", 512);
3356   INITIALIZER(runCreateLoadDropIndex);
3357 }
3358 TESTCASE("NFNR1",
3359 	 "Test that indexes are correctly maintained during node fail and node restart"){
3360   TC_PROPERTY("LoggedIndexes", (unsigned)0);
3361   TC_PROPERTY("PauseThreads", 2);
3362   INITIALIZER(runClearTable);
3363   INITIALIZER(createRandomIndex);
3364   INITIALIZER(runLoadTable);
3365   STEP(runRestarts);
3366   STEP(runTransactions1);
3367   STEP(runTransactions1);
3368   FINALIZER(runVerifyIndex);
3369   FINALIZER(createRandomIndex_Drop);
3370   FINALIZER(runClearTable);
3371 }
3372 TESTCASE("NFNR1_O",
3373 	 "Test that indexes are correctly maintained during node fail and node restart"){
3374   TC_PROPERTY("OrderedIndex", 1);
3375   TC_PROPERTY("LoggedIndexes", (unsigned)0);
3376   TC_PROPERTY("PauseThreads", 2);
3377   INITIALIZER(runClearTable);
3378   INITIALIZER(createRandomIndex);
3379   INITIALIZER(runLoadTable);
3380   STEP(runRestarts);
3381   STEP(runTransactions1);
3382   STEP(runTransactions1);
3383   FINALIZER(runVerifyIndex);
3384   FINALIZER(createRandomIndex_Drop);
3385   FINALIZER(runClearTable);
3386 }
3387 TESTCASE("NFNR2",
3388 	 "Test that indexes are correctly maintained during node fail and node restart"){
3389   TC_PROPERTY("LoggedIndexes", (unsigned)0);
3390   TC_PROPERTY("PauseThreads", 2);
3391   INITIALIZER(runClearTable);
3392   INITIALIZER(createRandomIndex);
3393   INITIALIZER(createPkIndex);
3394   INITIALIZER(runLoadTable);
3395   STEP(runRestarts);
3396   STEP(runTransactions2);
3397   STEP(runTransactions2);
3398   FINALIZER(runVerifyIndex);
3399   FINALIZER(createRandomIndex_Drop);
3400   FINALIZER(createPkIndex_Drop);
3401   FINALIZER(runClearTable);
3402 }
3403 TESTCASE("NFNR2_O",
3404 	 "Test that indexes are correctly maintained during node fail and node restart"){
3405   TC_PROPERTY("OrderedIndex", 1);
3406   TC_PROPERTY("LoggedIndexes", (unsigned)0);
3407   TC_PROPERTY("PauseThreads", 1);
3408   INITIALIZER(runClearTable);
3409   INITIALIZER(createRandomIndex);
3410   INITIALIZER(createPkIndex);
3411   INITIALIZER(runLoadTable);
3412   STEP(runRestarts);
3413   STEP(runTransactions2);
3414   //STEP(runTransactions2);
3415   FINALIZER(runVerifyIndex);
3416   FINALIZER(createRandomIndex_Drop);
3417   FINALIZER(createPkIndex_Drop);
3418   FINALIZER(runClearTable);
3419 }
3420 TESTCASE("NFNR3",
3421 	 "Test that indexes are correctly maintained during node fail and node restart"){
3422   TC_PROPERTY("LoggedIndexes", (unsigned)0);
3423   TC_PROPERTY("PauseThreads", 2);
3424   INITIALIZER(runClearTable);
3425   INITIALIZER(createRandomIndex);
3426   INITIALIZER(createPkIndex);
3427   STEP(runRestarts);
3428   STEP(runTransactions3);
3429   FINALIZER(runVerifyIndex);
3430   FINALIZER(createPkIndex_Drop);
3431   FINALIZER(createRandomIndex_Drop);
3432   FINALIZER(runClearTable);
3433 }
3434 TESTCASE("NFNR3_O",
3435 	 "Test that indexes are correctly maintained during node fail and node restart"){
3436   TC_PROPERTY("OrderedIndex", 1);
3437   TC_PROPERTY("LoggedIndexes", (unsigned)0);
3438   TC_PROPERTY("PauseThreads", 2);
3439   INITIALIZER(runClearTable);
3440   INITIALIZER(createRandomIndex);
3441   INITIALIZER(createPkIndex);
3442   STEP(runRestarts);
3443   STEP(runTransactions3);
3444   FINALIZER(runVerifyIndex);
3445   FINALIZER(createPkIndex_Drop);
3446   FINALIZER(createRandomIndex_Drop);
3447   FINALIZER(runClearTable);
3448 }
3449 TESTCASE("NFNR4",
3450 	 "Test that indexes are correctly maintained during node fail and node restart"){
3451   TC_PROPERTY("LoggedIndexes", (unsigned)0);
3452   TC_PROPERTY("PauseThreads", 4);
3453   INITIALIZER(runClearTable);
3454   INITIALIZER(createRandomIndex);
3455   INITIALIZER(createPkIndex);
3456   INITIALIZER(runLoadTable);
3457   STEP(runRestarts);
3458   STEP(runTransactions1);
3459   STEP(runTransactions1);
3460   STEP(runTransactions2);
3461   STEP(runTransactions2);
3462   FINALIZER(runVerifyIndex);
3463   FINALIZER(createRandomIndex_Drop);
3464   FINALIZER(createPkIndex_Drop);
3465   FINALIZER(runClearTable);
3466 }
3467 TESTCASE("NFNR4_O",
3468 	 "Test that indexes are correctly maintained during node fail and node restart"){
3469   TC_PROPERTY("OrderedIndex", 1);
3470   TC_PROPERTY("LoggedIndexes", (unsigned)0);
3471   TC_PROPERTY("PauseThreads", 4);
3472   INITIALIZER(runClearTable);
3473   INITIALIZER(createRandomIndex);
3474   INITIALIZER(createPkIndex);
3475   INITIALIZER(runLoadTable);
3476   STEP(runRestarts);
3477   STEP(runTransactions1);
3478   STEP(runTransactions1);
3479   STEP(runTransactions2);
3480   STEP(runTransactions2);
3481   FINALIZER(runVerifyIndex);
3482   FINALIZER(createRandomIndex_Drop);
3483   FINALIZER(createPkIndex_Drop);
3484   FINALIZER(runClearTable);
3485 }
3486 TESTCASE("NFNR5",
3487 	 "Test that indexes are correctly maintained during node fail and node restart"){
3488   TC_PROPERTY("LoggedIndexes", (unsigned)0);
3489   TC_PROPERTY("BatchSize", (unsigned)1);
3490   INITIALIZER(runClearTable);
3491   INITIALIZER(createRandomIndex);
3492   INITIALIZER(createPkIndex);
3493   INITIALIZER(runLoadTable);
3494   STEP(runLQHKEYREF);
3495   STEP(runTransactions1);
3496   STEP(runTransactions1);
3497   STEP(runTransactions2);
3498   STEP(runTransactions2);
3499   FINALIZER(runVerifyIndex);
3500   FINALIZER(createRandomIndex_Drop);
3501   FINALIZER(createPkIndex_Drop);
3502   FINALIZER(runClearTable);
3503 }
3504 TESTCASE("NFNR5_O",
3505 	 "Test that indexes are correctly maintained during node fail and node restart"){
3506   TC_PROPERTY("OrderedIndex", 1);
3507   TC_PROPERTY("LoggedIndexes", (unsigned)0);
3508   TC_PROPERTY("BatchSize", (unsigned)1);
3509   INITIALIZER(runClearTable);
3510   INITIALIZER(createRandomIndex);
3511   INITIALIZER(createPkIndex);
3512   INITIALIZER(runLoadTable);
3513   STEP(runLQHKEYREF);
3514   STEP(runTransactions1);
3515   STEP(runTransactions1);
3516   STEP(runTransactions2);
3517   STEP(runTransactions2);
3518   FINALIZER(runVerifyIndex);
3519   FINALIZER(createRandomIndex_Drop);
3520   FINALIZER(createPkIndex_Drop);
3521   FINALIZER(runClearTable);
3522 }
3523 TESTCASE("SR1",
3524 	 "Test that indexes are correctly maintained during SR"){
3525   INITIALIZER(runClearTable);
3526   INITIALIZER(createRandomIndex);
3527   INITIALIZER(createPkIndex);
3528   STEP(runSystemRestart1);
3529   FINALIZER(runVerifyIndex);
3530   FINALIZER(createPkIndex_Drop);
3531   FINALIZER(createRandomIndex_Drop);
3532   FINALIZER(runClearTable);
3533 }
3534 TESTCASE("MixedTransaction",
3535 	 "Test mixing of index and normal operations"){
3536   TC_PROPERTY("LoggedIndexes", (unsigned)0);
3537   INITIALIZER(runClearTable);
3538   INITIALIZER(createPkIndex);
3539   INITIALIZER(runLoadTable);
3540   STEP(runMixed1);
3541   FINALIZER(createPkIndex_Drop);
3542   FINALIZER(runClearTable);
3543 }
3544 TESTCASE("MixedTransaction2",
3545 	 "Test mixing of index and normal operations with batching"){
3546   TC_PROPERTY("LoggedIndexes", (unsigned)0);
3547   INITIALIZER(runClearTable);
3548   INITIALIZER(createPkIndex);
3549   INITIALIZER(runLoadTable);
3550   STEP(runMixed2);
3551   FINALIZER(createPkIndex_Drop);
3552   FINALIZER(runClearTable);
3553 }
3554 TESTCASE("SR1_O",
3555 	 "Test that indexes are correctly maintained during SR"){
3556   TC_PROPERTY("OrderedIndex", 1);
3557   TC_PROPERTY("LoggedIndexes", (unsigned)0);
3558   INITIALIZER(runClearTable);
3559   INITIALIZER(createRandomIndex);
3560   INITIALIZER(createPkIndex);
3561   STEP(runSystemRestart1);
3562   FINALIZER(runVerifyIndex);
3563   FINALIZER(createPkIndex_Drop);
3564   FINALIZER(createRandomIndex_Drop);
3565   FINALIZER(runClearTable);
3566 }
3567 TESTCASE("BuildDuring",
3568 	 "Test that index build when running transactions work"){
3569   TC_PROPERTY("OrderedIndex", (unsigned)0);
3570   TC_PROPERTY("LoggedIndexes", (unsigned)0);
3571   TC_PROPERTY("Threads", 1); // # runTransactions4
3572   TC_PROPERTY("BatchSize", 1);
3573   INITIALIZER(runClearTable);
3574   STEP(runBuildDuring);
3575   STEP(runTransactions4);
3576   //STEP(runTransactions4);
3577   FINALIZER(runClearTable);
3578 }
3579 TESTCASE("BuildDuring2",
3580 	 "Test that index build when running transactions work"){
3581   TC_PROPERTY("OrderedIndex", (unsigned)0);
3582   TC_PROPERTY("LoggedIndexes", (unsigned)0);
3583   TC_PROPERTY("BatchSize", 1);
3584   TC_PROPERTY("UntilStopped", Uint32(1));
3585   INITIALIZER(runClearTable);
3586   STEP(runBuildDuring);
3587   STEPS(runMixedDML, 3);
3588   FINALIZER(runClearTable);
3589 }
3590 TESTCASE("BuildDuring_O",
3591 	 "Test that index build when running transactions work"){
3592   TC_PROPERTY("OrderedIndex", (unsigned)1);
3593   TC_PROPERTY("LoggedIndexes", (unsigned)0);
3594   TC_PROPERTY("Threads", 1); // # runTransactions4
3595   INITIALIZER(runClearTable);
3596   STEP(runBuildDuring);
3597   STEP(runTransactions4);
3598   //STEP(runTransactions4);
3599   FINALIZER(runClearTable);
3600 }
3601 TESTCASE("UniqueNull",
3602 	 "Test that unique indexes and nulls"){
3603   TC_PROPERTY("LoggedIndexes", (unsigned)0);
3604   INITIALIZER(runClearTable);
3605   INITIALIZER(createRandomIndex);
3606   INITIALIZER(createPkIndex);
3607   INITIALIZER(runLoadTable);
3608   STEP(runTransactions1);
3609   STEP(runTransactions2);
3610   STEP(runUniqueNullTransactions);
3611   FINALIZER(runVerifyIndex);
3612   FINALIZER(createRandomIndex_Drop);
3613   FINALIZER(createPkIndex_Drop);
3614   FINALIZER(runClearTable);
3615 }
3616 TESTCASE("Bug21384",
3617 	 "Test that unique indexes and nulls"){
3618   TC_PROPERTY("LoggedIndexes", (unsigned)0);
3619   INITIALIZER(runClearTable);
3620   INITIALIZER(createPkIndex);
3621   INITIALIZER(runLoadTable);
3622   STEP(runBug21384);
3623   FINALIZER(createPkIndex_Drop);
3624   FINALIZER(runClearTable);
3625 }
3626 TESTCASE("Bug25059",
3627 	 "Test that unique indexes and nulls"){
3628   TC_PROPERTY("LoggedIndexes", (unsigned)0);
3629   INITIALIZER(createPkIndex);
3630   INITIALIZER(runLoadTable);
3631   STEP(runBug25059);
3632   FINALIZER(createPkIndex_Drop);
3633 }
3634 TESTCASE("Bug28804",
3635 	 "Test behaviour on out of TransactionBufferMemory for index lookup"){
3636   TC_PROPERTY("LoggedIndexes", (unsigned)0);
3637   INITIALIZER(runClearTable);
3638   INITIALIZER(createPkIndex);
3639   INITIALIZER(runLoadTable);
3640   STEP(runBug28804);
3641   FINALIZER(createPkIndex_Drop);
3642   FINALIZER(runClearTable);
3643 }
3644 TESTCASE("Bug28804_ATTRINFO",
3645 	 "Test behaviour on out of TransactionBufferMemory for index lookup"
3646          " in saveINDXATTRINFO"){
3647   TC_PROPERTY("LoggedIndexes", (unsigned)0);
3648   INITIALIZER(runClearTable);
3649   INITIALIZER(createPkIndex);
3650   INITIALIZER(runLoadTable);
3651   STEP(runBug28804_ATTRINFO);
3652   FINALIZER(createPkIndex_Drop);
3653   FINALIZER(runClearTable);
3654 }
3655 TESTCASE("Bug46069", ""){
3656   TC_PROPERTY("OrderedIndex", 1);
3657   TC_PROPERTY("THREADS", 12);
3658   TC_PROPERTY("LoggedIndexes", Uint32(0));
3659   INITIALIZER(createPkIndex);
3660   STEP(runBug46069);
3661   STEPS(runBug46069_pkdel, 10);
3662   STEPS(runBug46069_scandel, 2);
3663   FINALIZER(createPkIndex_Drop);
3664 }
3665 TESTCASE("ConstraintDetails",
3666          "Test that the details part of the returned NdbError is as "
3667          "expected"){
3668   INITIALIZER(runConstraintDetails);
3669 }
3670 TESTCASE("Bug50118", ""){
3671   TC_PROPERTY("LoggedIndexes", (unsigned)0);
3672   INITIALIZER(runClearTable);
3673   INITIALIZER(runLoadTable);
3674   INITIALIZER(createPkIndex);
3675   STEP(runReadIndexUntilStopped);
3676   STEP(runReadIndexUntilStopped);
3677   STEP(runReadIndexUntilStopped);
3678   STEP(runBug50118);
3679   FINALIZER(createPkIndex_Drop);
3680   FINALIZER(runClearTable);
3681 }
3682 TESTCASE("FireTrigOverload", ""){
3683   TC_PROPERTY("LoggedIndexes", (unsigned)0);
3684   TC_PROPERTY("NotOnlyPkId", (unsigned)1); // Index must be non PK to fire triggers
3685   TC_PROPERTY(NDBT_TestCase::getStepThreadStackSizePropName(), 128*1024);
3686   INITIALIZER(createRandomIndex);
3687   INITIALIZER(runClearTable);
3688   STEP(runTrigOverload);
3689   FINALIZER(runClearError);
3690   FINALIZER(createRandomIndex_Drop);
3691 }
3692 TESTCASE("DeferredError",
3693          "Test with deferred unique index handling and error inserts")
3694 {
3695   TC_PROPERTY("LoggedIndexes", Uint32(0));
3696   TC_PROPERTY("OrderedIndex", Uint32(0));
3697   INITIALIZER(createPkIndex);
3698   INITIALIZER(runLoadTable);
3699   STEP(runTestDeferredError);
3700   FINALIZER(createPkIndex_Drop);
3701 }
3702 TESTCASE("DeferredMixedLoad",
3703          "Test mixed load of DML with deferred indexes")
3704 {
3705   TC_PROPERTY("LoggedIndexes", Uint32(0));
3706   TC_PROPERTY("OrderedIndex", Uint32(0));
3707   TC_PROPERTY("UntilStopped", Uint32(0));
3708   TC_PROPERTY("Deferred", Uint32(1));
3709   INITIALIZER(createPkIndex);
3710   INITIALIZER(runLoadTable);
3711   STEPS(runMixedDML, 10);
3712   FINALIZER(createPkIndex_Drop);
3713 }
3714 TESTCASE("DeferredMixedLoadError",
3715          "Test mixed load of DML with deferred indexes")
3716 {
3717   TC_PROPERTY("LoggedIndexes", Uint32(0));
3718   TC_PROPERTY("OrderedIndex", Uint32(0));
3719   TC_PROPERTY("UntilStopped", Uint32(1));
3720   TC_PROPERTY("Deferred", Uint32(1));
3721   INITIALIZER(createPkIndex);
3722   INITIALIZER(runLoadTable);
3723   STEPS(runMixedDML, 4);
3724   STEP(runDeferredError);
3725   FINALIZER(createPkIndex_Drop);
3726 }
3727 TESTCASE("NF_DeferredMixed",
3728          "Test mixed load of DML with deferred indexes")
3729 {
3730   TC_PROPERTY("LoggedIndexes", Uint32(0));
3731   TC_PROPERTY("OrderedIndex", Uint32(0));
3732   TC_PROPERTY("UntilStopped", Uint32(1));
3733   TC_PROPERTY("Deferred", Uint32(1));
3734   INITIALIZER(createPkIndex);
3735   INITIALIZER(runLoadTable);
3736   STEPS(runMixedDML, 4);
3737   STEP(runRestarts);
3738   FINALIZER(createPkIndex_Drop);
3739 }
3740 TESTCASE("NF_Mixed",
3741          "Test mixed load of DML")
3742 {
3743   TC_PROPERTY("LoggedIndexes", Uint32(0));
3744   TC_PROPERTY("OrderedIndex", Uint32(0));
3745   TC_PROPERTY("UntilStopped", Uint32(1));
3746   INITIALIZER(createPkIndex);
3747   INITIALIZER(runLoadTable);
3748   STEPS(runMixedDML, 4);
3749   STEP(runRestarts);
3750   FINALIZER(createPkIndex_Drop);
3751 }
3752 TESTCASE("Bug56829",
3753          "Return empty ordered index nodes to index fragment "
3754          "so that empty fragment pages can be freed"){
3755   STEP(runBug56829);
3756 }
3757 TESTCASE("Bug12315582", "")
3758 {
3759   TC_PROPERTY("LoggedIndexes", Uint32(0));
3760   TC_PROPERTY("OrderedIndex", Uint32(0));
3761   INITIALIZER(createPkIndex);
3762   INITIALIZER(runLoadTable);
3763   INITIALIZER(runBug12315582);
3764   FINALIZER(createPkIndex_Drop);
3765 }
3766 TESTCASE("Bug60851", "")
3767 {
3768   TC_PROPERTY("LoggedIndexes", Uint32(0));
3769   TC_PROPERTY("OrderedIndex", Uint32(0));
3770   INITIALIZER(createPkIndex);
3771   INITIALIZER(runLoadTable);
3772   INITIALIZER(runBug60851);
3773   FINALIZER(createPkIndex_Drop);
3774 }
3775 TESTCASE("RefreshWithOrderedIndex",
3776          "Refresh tuples with ordered index(es)")
3777 {
3778   TC_PROPERTY("OrderedIndex", 1);
3779   TC_PROPERTY("LoggedIndexes", Uint32(0));
3780   INITIALIZER(createPkIndex);
3781   INITIALIZER(runRefreshTupleAbort);
3782   FINALIZER(createPkIndex_Drop);
3783   FINALIZER(runClearTable);
3784 }
3785 NDBT_TESTSUITE_END(testIndex);
3786 
main(int argc,const char ** argv)3787 int main(int argc, const char** argv){
3788   ndb_init();
3789   NDBT_TESTSUITE_INSTANCE(testIndex);
3790   return testIndex.execute(argc, argv);
3791 }
3792 
3793 template class Vector<Attrib*>;
3794