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