MySQL 5.6.14 Source Code Document
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
index.cpp
1 /*
2  Copyright (C) 2003-2006 MySQL AB
3  All rights reserved. Use is subject to license terms.
4 
5  This program is free software; you can redistribute it and/or modify
6  it under the terms of the GNU General Public License as published by
7  the Free Software Foundation; version 2 of the License.
8 
9  This program is distributed in the hope that it will be useful,
10  but WITHOUT ANY WARRANTY; without even the implied warranty of
11  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12  GNU General Public License for more details.
13 
14  You should have received a copy of the GNU General Public License
15  along with this program; if not, write to the Free Software
16  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
17 */
18 
19 /* ***************************************************
20  INDEX TEST 1
21  Test index functionality of NDB
22 
23  Arguments:
24  -T create table
25  -L include a long attribute in key or index
26  -2 define primary key with two attributes
27  -c create index
28  -p make index unique (include primary key attribute)
29  -r read using index
30  -u update using index
31  -d delete using index
32  -n<no operations> do n operations (for -I -r -u -d -R -U -D)
33  -o<no parallel operations> (for -I -r -u -d -R -U -D)
34  -m<no indexes>
35 
36  Returns:
37  0 - Test passed
38  -1 - Test failed
39  1 - Invalid arguments
40  * *************************************************** */
41 
42 #include <ndb_global.h>
43 
44 #include <NdbApi.hpp>
45 #include <NdbOut.hpp>
46 #include <NdbTick.h>
47 #include <NdbMain.h>
48 #include <NdbTest.hpp>
49 #include <NDBT_Error.hpp>
50 
51 #ifndef MIN
52 #define MIN(x,y) (((x)<(y))?(x):(y))
53 #endif
54 
55 #define MAX_NO_PARALLEL_OPERATIONS 100
56 
57 bool testPassed = true;
58 
59 static void
60 error_handler(const NdbError & err)
61 {
62  // Test failed
63  ndbout << endl << err << endl;
64  testPassed = false;
65 }
66 
67 static void
68 error_handler4(int line, const NdbError & err){
69  ndbout << endl << "Line " << line << endl;
70  // Test failed
71  ndbout << err << endl;
72  testPassed = false;
73 }
74 
75 static char *longName, *sixtysix, *ninetynine, *hundred;
76 
77 static void createTable(Ndb &myNdb, bool storeInACC, bool twoKey, bool longKey)
78 {
80  NdbDictionary::Table table("PERSON");
81  //NdbDictionary::Column column(); // Bug
82  NdbDictionary::Column column;
83  int res;
84 
85  column.setName("NAME");
87  column.setLength((longKey)?
88  1024 // 1KB => long key
89  :12);
90  column.setPrimaryKey(true);
91  column.setNullable(false);
92  table.addColumn(column);
93 
94  if (twoKey) {
95  column.setName("KEY2");
97  column.setLength(1);
98  column.setPrimaryKey(true);
99  column.setNullable(false);
100  table.addColumn(column);
101  }
102 
103  column.setName("PNUM1");
105  column.setLength(1);
106  column.setPrimaryKey(false);
107  column.setNullable(false);
108  table.addColumn(column);
109 
110  column.setName("PNUM2");
112  column.setLength(1);
113  column.setPrimaryKey(false);
114  column.setNullable(false);
115  table.addColumn(column);
116 
117  column.setName("PNUM3");
119  column.setLength(1);
120  column.setPrimaryKey(false);
121  column.setNullable(false);
122  table.addColumn(column);
123 
124  column.setName("PNUM4");
126  column.setLength(1);
127  column.setPrimaryKey(false);
128  column.setNullable(false);
129  table.addColumn(column);
130 
131  column.setName("AGE");
133  column.setLength(1);
134  column.setPrimaryKey(false);
135  column.setNullable(false);
136  table.addColumn(column);
137 
138  column.setName("STRING_AGE");
140  column.setLength(1);
141  column.setLength(256);
142  column.setPrimaryKey(false);
143  column.setNullable(false);
144  table.addColumn(column);
145 
146  if ((res = dict->createTable(table)) == -1) {
147  error_handler(dict->getNdbError());
148  }
149  else
150  ndbout << "Created table" << ((longKey)?" with long key":"") <<endl;
151 }
152 
153 static void createIndex(Ndb &myNdb, bool includePrimary, unsigned int noOfIndexes)
154 {
155  Uint64 before, after;
157  char indexName[] = "PNUMINDEX0000";
158  int res;
159 
160  for(unsigned int indexNum = 0; indexNum < noOfIndexes; indexNum++) {
161  sprintf(indexName, "PNUMINDEX%.4u", indexNum);
162  NdbDictionary::Index index(indexName);
163  index.setTable("PERSON");
165  if (includePrimary) {
166  const char* attr_arr[] = {"NAME", "PNUM1", "PNUM3"};
167  index.addIndexColumns(3, attr_arr);
168  }
169  else {
170  const char* attr_arr[] = {"PNUM1", "PNUM3"};
171  index.addIndexColumns(2, attr_arr);
172  }
173  before = NdbTick_CurrentMillisecond();
174  if ((res = dict->createIndex(index)) == -1) {
175  error_handler(dict->getNdbError());
176  }
177  after = NdbTick_CurrentMillisecond();
178  ndbout << "Created index " << indexName << ", " << after - before << " msec" << endl;
179  }
180 }
181 
182 static void insertTable(Ndb &myNdb, unsigned int noOfTuples, unsigned int noOfOperations, bool oneTrans, bool twoKey, bool longKey)
183 {
184  Uint64 tbefore, tafter, before, after;
185  NdbConnection *myTrans;
186  NdbOperation *myOp;
187  char name[] = "Kalle0000000";
188 
189  tbefore = NdbTick_CurrentMillisecond();
190  if (oneTrans) myTrans = myNdb.startTransaction();
191  for (unsigned int i = 0; i<noOfTuples; i++) {
192  if (!oneTrans) myTrans = myNdb.startTransaction();
193  for(unsigned int j = 1;
194  ((j<=noOfOperations)&&(i<noOfTuples));
195  (++j<=noOfOperations)?i++:i) {
196  if (myTrans == NULL)
197  error_handler4(__LINE__, myNdb.getNdbError());
198 
199  myOp = myTrans->getNdbOperation("PERSON");
200  if (myOp == NULL)
201  error_handler4(__LINE__, myTrans->getNdbError());
202 
203  myOp->insertTuple();
204  sprintf(name, "Kalle%.7i", i);
205  if (longKey)
206  memcpy(longName, name, strlen(name));
207  if (myOp->equal("NAME", (longKey)?longName:name) == -1) {
208  error_handler4(__LINE__, myTrans->getNdbError());
209  myNdb.closeTransaction(myTrans);
210  break;
211  }
212  if (twoKey)
213  if (myOp->equal("KEY2", i) == -1) {
214  error_handler4(__LINE__, myTrans->getNdbError());
215  myNdb.closeTransaction(myTrans);
216  break;
217  }
218  if (myOp->setValue("PNUM1", 17) == -1) {
219  error_handler4(__LINE__, myTrans->getNdbError());
220  myNdb.closeTransaction(myTrans);
221  break;
222  }
223  if (myOp->setValue("PNUM2", 18)) {
224  error_handler4(__LINE__, myTrans->getNdbError());
225  myNdb.closeTransaction(myTrans);
226  break;
227  }
228  if (myOp->setValue("PNUM3", 19)) {
229  error_handler4(__LINE__, myTrans->getNdbError());
230  myNdb.closeTransaction(myTrans);
231  break;
232  }
233  if (myOp->setValue("PNUM4", 20)) {
234  error_handler4(__LINE__, myTrans->getNdbError());
235  myNdb.closeTransaction(myTrans);
236  break;
237  }
238  if (myOp->setValue("AGE", ((i % 2) == 0)?66:99) == -1) {
239  error_handler4(__LINE__, myTrans->getNdbError());
240  myNdb.closeTransaction(myTrans);
241  break;
242  }
243  if (myOp->setValue("STRING_AGE", ((i % 2) == 0)?sixtysix:ninetynine) == -1) {
244  error_handler4(__LINE__, myTrans->getNdbError());
245  myNdb.closeTransaction(myTrans);
246  break;
247  }
248  }
249  if (noOfOperations == 1)
250  printf("Trying to insert person %s\n", name);
251  else
252  printf("Trying to insert %u persons\n", noOfOperations);
253  before = NdbTick_CurrentMillisecond();
254  if (myTrans->execute( (oneTrans) ? NoCommit : Commit ) == -1)
255  {
256  error_handler4(__LINE__, myTrans->getNdbError());
257  myNdb.closeTransaction(myTrans);
258  break;
259  }
260  after = NdbTick_CurrentMillisecond();
261  if (noOfOperations == 1)
262  printf("Inserted person %s, %u msec\n", name, (Uint32) after - before);
263  else
264  printf("Inserted %u persons, %u msec\n", noOfOperations, (Uint32) after - before);
265  if (!oneTrans) myNdb.closeTransaction(myTrans);
266  }
267  if (oneTrans) {
268  if (myTrans->execute( Commit ) == -1) {
269  error_handler4(__LINE__, myTrans->getNdbError());
270  }
271  myNdb.closeTransaction(myTrans);
272  }
273  tafter = NdbTick_CurrentMillisecond();
274 
275  ndbout << "Inserted "<< noOfTuples << " tuples in " << ((oneTrans) ? 1 : noOfTuples) << " transaction(s), " << tafter - tbefore << " msec" << endl;
276 }
277 
278 static void updateTable(Ndb &myNdb, unsigned int noOfTuples, unsigned int noOfOperations, bool oneTrans, bool twoKey, bool longKey)
279 {
280  Uint64 tbefore, tafter, before, after;
281  NdbConnection *myTrans;
282  NdbOperation *myOp;
283  char name[] = "Kalle0000000";
284 
285  tbefore = NdbTick_CurrentMillisecond();
286  if (oneTrans) myTrans = myNdb.startTransaction();
287  for (unsigned int i = 0; i<noOfTuples; i++) {
288  if (!oneTrans) myTrans = myNdb.startTransaction();
289  for(unsigned int j = 1;
290  ((j<=noOfOperations)&&(i<noOfTuples));
291  (++j<=noOfOperations)?i++:i) {
292  if (myTrans == NULL)
293  error_handler4(__LINE__, myNdb.getNdbError());
294 
295  myOp = myTrans->getNdbOperation("PERSON");
296  if (myOp == NULL)
297  error_handler4(__LINE__, myTrans->getNdbError());
298 
299  myOp->updateTuple();
300  sprintf(name, "Kalle%.7i", i);
301  if (longKey)
302  memcpy(longName, name, strlen(name));
303  if (myOp->equal("NAME", (longKey)?longName:name) == -1) {
304  error_handler4(__LINE__, myTrans->getNdbError());
305  myNdb.closeTransaction(myTrans);
306  break;
307  }
308  if (twoKey)
309  if (myOp->equal("KEY2", i) == -1) {
310  error_handler4(__LINE__, myTrans->getNdbError());
311  myNdb.closeTransaction(myTrans);
312  break;
313  }
314  if (myOp->setValue("PNUM1", 77) == -1) {
315  error_handler4(__LINE__, myTrans->getNdbError());
316  myNdb.closeTransaction(myTrans);
317  break;
318  }
319  if (myOp->setValue("PNUM2", 88)) {
320  error_handler4(__LINE__, myTrans->getNdbError());
321  myNdb.closeTransaction(myTrans);
322  break;
323  }
324  if (myOp->setValue("PNUM4", 99)) {
325  error_handler4(__LINE__, myTrans->getNdbError());
326  myNdb.closeTransaction(myTrans);
327  break;
328  }
329  if (myOp->setValue("AGE", 100) == -1) {
330  error_handler4(__LINE__, myTrans->getNdbError());
331  myNdb.closeTransaction(myTrans);
332  break;
333  }
334  if (myOp->setValue("STRING_AGE", hundred) == -1) {
335  error_handler4(__LINE__, myTrans->getNdbError());
336  myNdb.closeTransaction(myTrans);
337  break;
338  }
339  }
340  if (noOfOperations == 1)
341  printf("Trying to update person %s\n", name);
342  else
343  printf("Trying to update %u persons\n", noOfOperations);
344  before = NdbTick_CurrentMillisecond();
345  if (myTrans->execute( (oneTrans) ? NoCommit : Commit ) == -1)
346  {
347  error_handler4(__LINE__, myTrans->getNdbError());
348  myNdb.closeTransaction(myTrans);
349  break;
350  }
351  after = NdbTick_CurrentMillisecond();
352  if (noOfOperations == 1)
353  printf("Updated person %s, %u msec\n", name, (Uint32) after - before);
354  else
355  printf("Update %u persons, %u msec\n", noOfOperations, (Uint32) after - before);
356  if (!oneTrans) myNdb.closeTransaction(myTrans);
357  }
358  if (oneTrans) {
359  if (myTrans->execute( Commit ) == -1) {
360  error_handler4(__LINE__, myTrans->getNdbError());
361  }
362  myNdb.closeTransaction(myTrans);
363  }
364  tafter = NdbTick_CurrentMillisecond();
365 
366  ndbout << "Updated "<< noOfTuples << " tuples in " << ((oneTrans) ? 1 : noOfTuples) << " transaction(s), " << tafter - tbefore << " msec" << endl;
367 }
368 
369 static void deleteTable(Ndb &myNdb, unsigned int noOfTuples, unsigned int noOfOperations, bool oneTrans, bool twoKey, bool longKey)
370 {
371  Uint64 tbefore, tafter, before, after;
372  NdbConnection *myTrans;
373  NdbOperation *myOp;
374  char name[] = "Kalle0000000";
375 
376  tbefore = NdbTick_CurrentMillisecond();
377  if (oneTrans) myTrans = myNdb.startTransaction();
378  for (unsigned int i = 0; i<noOfTuples; i++) {
379  if (!oneTrans) myTrans = myNdb.startTransaction();
380  for(unsigned int j = 1;
381  ((j<=noOfOperations)&&(i<noOfTuples));
382  (++j<=noOfOperations)?i++:i) {
383  if (myTrans == NULL)
384  error_handler4(__LINE__, myNdb.getNdbError());
385 
386  myOp = myTrans->getNdbOperation("PERSON");
387  if (myOp == NULL)
388  error_handler4(__LINE__, myTrans->getNdbError());
389 
390  myOp->deleteTuple();
391  sprintf(name, "Kalle%.7i", i);
392  if (longKey)
393  memcpy(longName, name, strlen(name));
394  if (myOp->equal("NAME", (longKey)?longName:name) == -1) {
395  error_handler4(__LINE__, myTrans->getNdbError());
396  myNdb.closeTransaction(myTrans);
397  break;
398  }
399  if (twoKey)
400  if (myOp->equal("KEY2", i) == -1) {
401  error_handler4(__LINE__, myTrans->getNdbError());
402  myNdb.closeTransaction(myTrans);
403  break;
404  }
405  }
406  if (noOfOperations == 1)
407  printf("Trying to delete person %s\n", name);
408  else
409  printf("Trying to delete %u persons\n", noOfOperations);
410  before = NdbTick_CurrentMillisecond();
411  if (myTrans->execute( (oneTrans) ? NoCommit : Commit ) == -1)
412  {
413  error_handler4(__LINE__, myTrans->getNdbError());
414  myNdb.closeTransaction(myTrans);
415  break;
416  }
417  after = NdbTick_CurrentMillisecond();
418  if (noOfOperations == 1)
419  printf("Deleted person %s, %u msec\n", name, (Uint32) after - before);
420  else
421  printf("Deleted %u persons, %u msec\n", noOfOperations, (Uint32) after - before);
422 
423  if (!oneTrans) myNdb.closeTransaction(myTrans);
424  }
425  if (oneTrans) {
426  if (myTrans->execute( Commit ) == -1) {
427  error_handler4(__LINE__, myTrans->getNdbError());
428  }
429  myNdb.closeTransaction(myTrans);
430  }
431  tafter = NdbTick_CurrentMillisecond();
432 
433  ndbout << "Deleted "<< noOfTuples << " tuples in " << ((oneTrans) ? 1 : noOfTuples) << " transaction(s), " << tafter - tbefore << " msec" << endl;
434 }
435 
436 static void readTable(Ndb &myNdb, unsigned int noOfTuples, unsigned int noOfOperations, bool oneTrans, bool twoKey, bool longKey)
437 {
438  Uint64 tbefore, tafter, before, after;
439  NdbConnection *myTrans;
440  NdbOperation *myOp;
441  char name[] = "Kalle0000000";
442  NdbRecAttr* myRecAttrArr[MAX_NO_PARALLEL_OPERATIONS];
443 
444  tbefore = NdbTick_CurrentMillisecond();
445  if (oneTrans) myTrans = myNdb.startTransaction();
446  for (unsigned int i = 0; i<noOfTuples; i++) {
447  if (!oneTrans) myTrans = myNdb.startTransaction();
448  for(unsigned int j = 1;
449  ((j<=noOfOperations)&&(i<noOfTuples));
450  (++j<=noOfOperations)?i++:i) {
451  if (myTrans == NULL)
452  error_handler4(__LINE__, myNdb.getNdbError());
453 
454  myOp = myTrans->getNdbOperation("PERSON");
455  if (myOp == NULL)
456  error_handler4(__LINE__, myTrans->getNdbError());
457 
458  myOp->readTuple();
459  sprintf(name, "Kalle%.7i", i);
460  if (longKey)
461  memcpy(longName, name, strlen(name));
462  if (myOp->equal("NAME", (longKey)?longName:name) == -1) {
463  error_handler4(__LINE__, myTrans->getNdbError());
464  myNdb.closeTransaction(myTrans);
465  break;
466  }
467  if (twoKey)
468  if (myOp->equal("KEY2", i) == -1) {
469  error_handler4(__LINE__, myTrans->getNdbError());
470  myNdb.closeTransaction(myTrans);
471  break;
472  }
473  myRecAttrArr[j-1] = myOp->getValue("PNUM2", NULL);
474  }
475  if (noOfOperations == 1)
476  printf("Trying to read person %s\n", name);
477  else
478  printf("Trying to read %u persons\n", noOfOperations);
479  before = NdbTick_CurrentMillisecond();
480  if (myTrans->execute( (oneTrans) ? NoCommit : Commit ) == -1)
481  {
482  error_handler4(__LINE__, myTrans->getNdbError());
483  myNdb.closeTransaction(myTrans);
484  break;
485  }
486  after = NdbTick_CurrentMillisecond();
487  if (noOfOperations == 1)
488  printf("Read person %s, %u msec\n", name, (Uint32) after - before);
489  else
490  printf("Read %u persons, %u msec\n", noOfOperations, (Uint32) after - before);
491  for(unsigned int j = 0; j<noOfOperations; j++)
492  printf("PNUM2 = %u\n", myRecAttrArr[j]->u_32_value());
493  if (!oneTrans) myNdb.closeTransaction(myTrans);
494  }
495  if (oneTrans) {
496  if (myTrans->execute( Commit ) == -1) {
497  error_handler4(__LINE__, myTrans->getNdbError());
498  }
499  myNdb.closeTransaction(myTrans);
500  }
501  tafter = NdbTick_CurrentMillisecond();
502 
503  ndbout << "Read "<< noOfTuples << " tuples in " << ((oneTrans) ? 1 : noOfTuples) << " transaction(s), " << tafter - tbefore << " msec" << endl;
504 }
505 
506 static void readIndex(Ndb &myNdb, unsigned int noOfTuples, unsigned int noOfOperations, bool includePrimary, bool oneTrans, bool longKey)
507 {
508  Uint64 tbefore, tafter, before, after;
509  NdbConnection *myTrans;
510  NdbIndexOperation *myOp;
511  char indexName[] = "PNUMINDEX0000";
512  char name[] = "Kalle0000000";
513  NdbRecAttr* myRecAttrArr[MAX_NO_PARALLEL_OPERATIONS];
514 
515  tbefore = NdbTick_CurrentMillisecond();
516  if (oneTrans) myTrans = myNdb.startTransaction();
517  for (unsigned int i = 0; i<noOfTuples; i++) {
518  if (!oneTrans) myTrans = myNdb.startTransaction();
519  for(unsigned int j = 1;
520  ((j<=noOfOperations)&&(i<noOfTuples));
521  (++j<=noOfOperations)?i++:i) {
522  if (myTrans == NULL)
523  error_handler4(__LINE__, myNdb.getNdbError());
524 
525  myOp = myTrans->getNdbIndexOperation(indexName, "PERSON");
526  if (myOp == NULL)
527  error_handler4(__LINE__, myTrans->getNdbError());
528 
529  myOp->readTuple();
530  if (includePrimary) {
531  sprintf(name, "Kalle%.7i", i);
532  if (longKey)
533  memcpy(longName, name, strlen(name));
534  if (myOp->equal("NAME", (longKey)?longName:name) == -1) {
535  error_handler4(__LINE__, myTrans->getNdbError());
536  myNdb.closeTransaction(myTrans);
537  break;
538  }
539  }
540  if (myOp->equal("PNUM1", 17) == -1) {
541  error_handler4(__LINE__, myTrans->getNdbError());
542  myNdb.closeTransaction(myTrans);
543  break;
544  }
545  if (myOp->equal("PNUM3", 19) == -1) {
546  error_handler4(__LINE__, myTrans->getNdbError());
547  myNdb.closeTransaction(myTrans);
548  break;
549  }
550  myRecAttrArr[j-1] = myOp->getValue("PNUM2", NULL);
551  }
552  if (noOfOperations == 1)
553  printf("Trying to read person %s\n", name);
554  else
555  printf("Trying to read %u persons\n", noOfOperations);
556  before = NdbTick_CurrentMillisecond();
557  if (myTrans->execute( (oneTrans) ? NoCommit : Commit ) == -1)
558  {
559  error_handler4(__LINE__, myTrans->getNdbError());
560  myNdb.closeTransaction(myTrans);
561  break;
562  }
563  after = NdbTick_CurrentMillisecond();
564  if (noOfOperations == 1)
565  printf("Read person %s, %u msec\n", name, (Uint32) after - before);
566  else
567  printf("Read %u persons, %u msec\n", noOfOperations, (Uint32) after - before);
568  for(unsigned int j = 0; j<noOfOperations; j++)
569  printf("PNUM2 = %u\n", myRecAttrArr[j]->u_32_value());
570  if (!oneTrans) myNdb.closeTransaction(myTrans);
571  }
572  if (oneTrans) {
573  if (myTrans->execute( Commit ) == -1) {
574  error_handler4(__LINE__, myTrans->getNdbError());
575  }
576  myNdb.closeTransaction(myTrans);
577  }
578  tafter = NdbTick_CurrentMillisecond();
579 
580  ndbout << "Read "<< noOfTuples << " tuples in " << ((oneTrans) ? 1 : noOfTuples) << " transaction(s), " << tafter - tbefore << " msec" << endl;
581 }
582 
583 static void updateIndex(Ndb &myNdb, unsigned int noOfTuples, unsigned int noOfOperations, bool includePrimary, bool oneTrans, bool longKey)
584 {
585  Uint64 tbefore, tafter, before, after;
586  NdbConnection *myTrans;
587  NdbIndexOperation *myOp;
588  char indexName[] = "PNUMINDEX0000";
589  char name[] = "Kalle0000000";
590 
591  tbefore = NdbTick_CurrentMillisecond();
592  if (oneTrans) myTrans = myNdb.startTransaction();
593  for (unsigned int i = 0; i<noOfTuples; i++) {
594  if (!oneTrans) myTrans = myNdb.startTransaction();
595  for(unsigned int j = 1;
596  ((j<=noOfOperations)&&(i<noOfTuples));
597  (++j<=noOfOperations)?i++:i) {
598  if (myTrans == NULL)
599  error_handler4(__LINE__, myNdb.getNdbError());
600 
601  myOp = myTrans->getNdbIndexOperation(indexName, "PERSON");
602  if (myOp == NULL)
603  error_handler4(__LINE__, myTrans->getNdbError());
604 
605  myOp->updateTuple();
606  if (includePrimary) {
607  sprintf(name, "Kalle%.7i", i);
608  if (longKey)
609  memcpy(longName, name, strlen(name));
610  if (myOp->equal("NAME", (longKey)?longName:name) == -1) {
611  error_handler4(__LINE__, myTrans->getNdbError());
612  myNdb.closeTransaction(myTrans);
613  break;
614  }
615  }
616  if (myOp->equal("PNUM1", 17) == -1) {
617  error_handler4(__LINE__, myTrans->getNdbError());
618  myNdb.closeTransaction(myTrans);
619  break;
620  }
621  if (myOp->equal("PNUM3", 19) == -1) {
622  error_handler4(__LINE__, myTrans->getNdbError());
623  myNdb.closeTransaction(myTrans);
624  break;
625  }
626  // Update index itself, should be possible
627  if (myOp->setValue("PNUM1", 77) == -1) {
628  error_handler4(__LINE__, myTrans->getNdbError());
629  myNdb.closeTransaction(myTrans);
630  break;
631  }
632  if (myOp->setValue("PNUM2", 88)) {
633  error_handler4(__LINE__, myTrans->getNdbError());
634  myNdb.closeTransaction(myTrans);
635  break;
636  }
637  if (myOp->setValue("PNUM4", 99)) {
638  error_handler4(__LINE__, myTrans->getNdbError());
639  myNdb.closeTransaction(myTrans);
640  break;
641  }
642  if (myOp->setValue("AGE", 100) == -1) {
643  error_handler4(__LINE__, myTrans->getNdbError());
644  myNdb.closeTransaction(myTrans);
645  break;
646  }
647  if (myOp->setValue("STRING_AGE", hundred) == -1) {
648  error_handler4(__LINE__, myTrans->getNdbError());
649  myNdb.closeTransaction(myTrans);
650  break;
651  }
652  }
653  if (noOfOperations == 1)
654  printf("Trying to update person %s\n", name);
655  else
656  printf("Trying to update %u persons\n", noOfOperations);
657  before = NdbTick_CurrentMillisecond();
658  if (myTrans->execute( (oneTrans) ? NoCommit : Commit ) == -1)
659  {
660  error_handler4(__LINE__, myTrans->getNdbError());
661  myNdb.closeTransaction(myTrans);
662  break;
663  }
664  after = NdbTick_CurrentMillisecond();
665  if (noOfOperations == 1)
666  printf("Updated person %s, %u msec\n", name, (Uint32) after - before);
667  else
668  printf("Updated %u persons, %u msec\n", noOfOperations, (Uint32) after - before);
669  if (!oneTrans) myNdb.closeTransaction(myTrans);
670  }
671  if (oneTrans) {
672  if (myTrans->execute( Commit ) == -1) {
673  error_handler4(__LINE__, myTrans->getNdbError());
674  }
675  myNdb.closeTransaction(myTrans);
676  }
677  tafter = NdbTick_CurrentMillisecond();
678 
679  ndbout << "Updated "<< noOfTuples << " tuples in " << ((oneTrans) ? 1 : noOfTuples) << " transaction(s), " << tafter - tbefore << " msec" << endl;
680 }
681 
682 static void deleteIndex(Ndb &myNdb, unsigned int noOfTuples, unsigned int noOfOperations, bool includePrimary, bool oneTrans, bool longKey)
683 {
684  Uint64 tbefore, tafter, before, after;
685  NdbConnection *myTrans;
686  NdbIndexOperation *myOp;
687  char indexName[] = "PNUMINDEX0000";
688  char name[] = "Kalle0000000";
689 
690  tbefore = NdbTick_CurrentMillisecond();
691  if (oneTrans) myTrans = myNdb.startTransaction();
692  for (unsigned int i = 0; i<noOfTuples; i++) {
693  for(unsigned int j = 1;
694  ((j<=noOfOperations)&&(i<noOfTuples));
695  (++j<=noOfOperations)?i++:i) {
696  if (!oneTrans) myTrans = myNdb.startTransaction();
697  if (myTrans == NULL)
698  error_handler4(__LINE__, myNdb.getNdbError());
699 
700  myOp = myTrans->getNdbIndexOperation(indexName, "PERSON");
701  if (myOp == NULL)
702  error_handler4(__LINE__, myTrans->getNdbError());
703 
704  myOp->deleteTuple();
705  if (includePrimary) {
706  sprintf(name, "Kalle%.7i", i);
707  if (longKey)
708  memcpy(longName, name, strlen(name));
709  if (myOp->equal("NAME", (longKey)?longName:name) == -1) {
710  error_handler4(__LINE__, myTrans->getNdbError());
711  myNdb.closeTransaction(myTrans);
712  break;
713  }
714  }
715  if (myOp->equal("PNUM1", 17) == -1) {
716  error_handler4(__LINE__, myTrans->getNdbError());
717  myNdb.closeTransaction(myTrans);
718  break;
719  }
720  if (myOp->equal("PNUM3", 19) == -1) {
721  error_handler4(__LINE__, myTrans->getNdbError());
722  myNdb.closeTransaction(myTrans);
723  break;
724  }
725  }
726  if (noOfOperations == 1)
727  printf("Trying to delete person %s\n", name);
728  else
729  printf("Trying to delete %u persons\n", noOfOperations);
730  before = NdbTick_CurrentMillisecond();
731  if (myTrans->execute( (oneTrans) ? NoCommit : Commit ) == -1)
732  {
733  error_handler4(__LINE__, myTrans->getNdbError());
734  myNdb.closeTransaction(myTrans);
735  break;
736  }
737  after = NdbTick_CurrentMillisecond();
738  if (noOfOperations == 1)
739  printf("Deleted person %s, %u msec\n", name, (Uint32) after - before);
740  else
741  printf("Deleted %u persons, %u msec\n", noOfOperations, (Uint32) after - before);
742  if (!oneTrans) myNdb.closeTransaction(myTrans);
743  }
744  if (oneTrans) {
745  if (myTrans->execute( Commit ) == -1) {
746  error_handler4(__LINE__, myTrans->getNdbError());
747  }
748  myNdb.closeTransaction(myTrans);
749  }
750  tafter = NdbTick_CurrentMillisecond();
751 
752  ndbout << "Deleted "<< noOfTuples << " tuples in " << ((oneTrans) ? 1 : noOfTuples) << " transaction(s), " << tafter - tbefore << " msec" << endl;
753 }
754 
755 static void dropIndex(Ndb &myNdb, unsigned int noOfIndexes)
756 {
757  for(unsigned int indexNum = 0; indexNum < noOfIndexes; indexNum++) {
758  char indexName[255];
759  sprintf(indexName, "PNUMINDEX%.4u", indexNum);
760  const Uint64 before = NdbTick_CurrentMillisecond();
761  const int retVal = myNdb.getDictionary()->dropIndex(indexName, "PERSON");
762  const Uint64 after = NdbTick_CurrentMillisecond();
763 
764  if(retVal == 0){
765  ndbout << "Dropped index " << indexName << ", "
766  << after - before << " msec" << endl;
767  } else {
768  ndbout << "Failed to drop index " << indexName << endl;
769  ndbout << myNdb.getDictionary()->getNdbError() << endl;
770  }
771  }
772 }
773 
774 NDB_COMMAND(indexTest, "indexTest", "indexTest", "indexTest", 65535)
775 {
776  ndb_init();
777  bool createTableOp, createIndexOp, dropIndexOp, insertOp, updateOp, deleteOp, readOp, readIndexOp, updateIndexOp, deleteIndexOp, twoKey, longKey;
778  unsigned int noOfTuples = 1;
779  unsigned int noOfOperations = 1;
780  unsigned int noOfIndexes = 1;
781  int i = 1;
782  Ndb myNdb( "TEST_DB" );
783  int check;
784  bool storeInACC = false;
785  bool includePrimary = false;
786  bool oneTransaction = false;
787 
788  createTableOp = createIndexOp = dropIndexOp = insertOp = updateOp = deleteOp = readOp = readIndexOp = updateIndexOp = deleteIndexOp = twoKey = longKey = false;
789  // Read arguments
790  if (argc > 1)
791  while (argc > 1)
792  {
793  if (strcmp(argv[i], "-T") == 0)
794  {
795  createTableOp = true;
796  argc -= 1;
797  i++;
798  }
799  else if (strcmp(argv[i], "-c") == 0)
800  {
801  createIndexOp = true;
802  argc -= 1;
803  i++;
804  }
805  else if (strcmp(argv[i], "-X") == 0)
806  {
807  dropIndexOp = true;
808  argc -= 1;
809  i++;
810  }
811  else if (strcmp(argv[i], "-I") == 0)
812  {
813  insertOp = true;
814  argc -= 1;
815  i++;
816  }
817  else if (strcmp(argv[i], "-D") == 0)
818  {
819  deleteOp = true;
820  argc -= 1;
821  i++;
822  }
823  else if (strcmp(argv[i], "-U") == 0)
824  {
825  updateOp = true;
826  argc -= 1;
827  i++;
828  }
829  else if (strcmp(argv[i], "-R") == 0)
830  {
831  readOp = true;
832  argc -= 1;
833  i++;
834  }
835  else if (strcmp(argv[i], "-r") == 0)
836  {
837  readIndexOp = true;
838  argc -= 1;
839  i++;
840  }
841  else if (strcmp(argv[i], "-u") == 0)
842  {
843  updateIndexOp = true;
844  argc -= 1;
845  i++;
846  }
847  else if (strcmp(argv[i], "-d") == 0)
848  {
849  deleteIndexOp = true;
850  argc -= 1;
851  i++;
852  }
853  else if (strcmp(argv[i], "-s") == 0)
854  {
855  storeInACC = true;
856  argc -= 1;
857  i++;
858  }
859  else if (strcmp(argv[i], "-p") == 0)
860  {
861  includePrimary = true;
862  argc -= 1;
863  i++;
864  }
865  else if (strcmp(argv[i], "-L") == 0)
866  {
867  longKey = true;
868  argc -= 1;
869  i++;
870  }
871  else if (strcmp(argv[i], "-1") == 0)
872  {
873  oneTransaction = true;
874  argc -= 1;
875  i++;
876  }
877  else if (strcmp(argv[i], "-2") == 0)
878  {
879  twoKey = true;
880  argc -= 1;
881  i++;
882  }
883  else if (strstr(argv[i], "-n") != 0)
884  {
885  noOfTuples = atoi(argv[i]+2);
886  argc -= 1;
887  i++;
888  }
889  else if (strstr(argv[i], "-o") != 0)
890  {
891  noOfOperations = MIN(MAX_NO_PARALLEL_OPERATIONS, atoi(argv[i]+2));
892  argc -= 1;
893  i++;
894  }
895  else if (strstr(argv[i], "-m") != 0)
896  {
897  noOfIndexes = atoi(argv[i]+2);
898  argc -= 1;
899  i++;
900  }
901  else if (strstr(argv[i], "-h") != 0)
902  {
903  printf("Synopsis:\n");
904  printf("index\n");
905  printf("\t-T create table\n");
906  printf("\t-L include a long attribute in key or index\n");
907  printf("\t-2 define primary key with two attributes\n");
908  printf("\t-c create index\n");
909  printf("\t-p make index unique (include primary key attribute)\n");
910  printf("\t-r read using index\n");
911  printf("\t-u update using index\n");
912  printf("\t-d delete using index\n");
913  printf("\t-n<no operations> do n operations (for -I -r -u -d -R -U -D)\n");
914  printf("\t-o<no parallel operations> (for -I -r -u -d -R -U -D)\n");
915  printf("\t-m<no indexes>\n");
916  argc -= 1;
917  i++;
918  }
919  else {
920  char errStr[256];
921 
922  printf(errStr, "Illegal argument: %s", argv[i]);
923  exit(-1);
924  }
925  }
926  else
927  {
928  createTableOp = createIndexOp = dropIndexOp = insertOp = updateOp = deleteOp = true;
929  }
930  if (longKey) {
931  longName = (char *) malloc(1024);
932  for (int i = 0; i < 1023; i++)
933  longName[i] = 'x';
934  longName[1023] = '\0';
935  }
936  sixtysix = (char *) malloc(256);
937  for (int i = 0; i < 255; i++)
938  sixtysix[i] = ' ';
939  sixtysix[255] = '\0';
940  strncpy(sixtysix, "sixtysix", strlen("sixtysix"));
941  ninetynine = (char *) malloc(256);
942  for (int i = 0; i < 255; i++)
943  ninetynine[i] = ' ';
944  ninetynine[255] = '\0';
945  strncpy(ninetynine, "ninetynine", strlen("ninetynine"));
946  hundred = (char *) malloc(256);
947  for (int i = 0; i < 255; i++)
948  hundred[i] = ' ';
949  hundred[255] = '\0';
950  strncpy(hundred, "hundred", strlen("hundred"));
951  myNdb.init();
952  // Wait for Ndb to become ready
953  if (myNdb.waitUntilReady(30) == 0)
954  {
955  if (createTableOp)
956  createTable(myNdb, storeInACC, twoKey, longKey);
957 
958  if (createIndexOp)
959  createIndex(myNdb, includePrimary, noOfIndexes);
960 
961  if (insertOp)
962  insertTable(myNdb, noOfTuples, noOfOperations, oneTransaction, twoKey, longKey);
963 
964  if (updateOp)
965  updateTable(myNdb, noOfTuples, noOfOperations, oneTransaction, twoKey, longKey);
966 
967  if (deleteOp)
968  deleteTable(myNdb, noOfTuples, noOfOperations, oneTransaction, twoKey, longKey);
969 
970  if (readOp)
971  readTable(myNdb, noOfTuples, noOfOperations, oneTransaction, twoKey, longKey);
972 
973  if (readIndexOp)
974  readIndex(myNdb, noOfTuples, noOfOperations, includePrimary, oneTransaction, longKey);
975 
976  if (updateIndexOp)
977  updateIndex(myNdb, noOfTuples, noOfOperations, includePrimary, oneTransaction, longKey);
978 
979  if (deleteIndexOp)
980  deleteIndex(myNdb, noOfTuples, noOfOperations, includePrimary, oneTransaction, longKey);
981 
982  if (dropIndexOp)
983  dropIndex(myNdb, noOfIndexes);
984  }
985 
986  if (testPassed)
987  {
988  // Test passed
989  ndbout << "OK - Test passed" << endl;
990  }
991  else
992  {
993  // Test failed
994  ndbout << "FAIL - Test failed" << endl;
995  exit(-1);
996  }
997  return 0;
998 }
999 
1000