MySQL 5.6.14 Source Code Document
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
index2.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 char* errorText)
61 {
62  // Test failed
63  ndbout << endl << "ErrorMessage: " << errorText << endl;
64  testPassed = false;
65 }
66 
67 static void
68 error_handler4(int line, int status, int classif, int errNo, const char* errorText)
69 {
70  ndbout << endl << "Line " << line << endl;
71  // Test failed
72  ndbout << "Status " << status << ", Classification " << classif<< ", Error code " << errNo << "\n" << errorText << endl;
73  testPassed = false;
74 }
75 
76 static char *longName, *sixtysix, *ninetynine, *hundred;
77 
78 static void createTable(Ndb &myNdb, bool storeInACC, bool twoKey, bool longKey)
79 {
81  NdbDictionary::Table table("THE_TABLE");
82  NdbDictionary::Column column;
83  int res;
84 
85  column.setName("X");
87  column.setLength(1);
88  column.setPrimaryKey(true);
89  column.setNullable(false);
90  table.addColumn(column);
91 
92  column.setName("Y");
94  column.setLength(1);
95  column.setPrimaryKey(false);
96  column.setNullable(false);
97  table.addColumn(column);
98 
99  if ((res = dict->createTable(table)) == -1) {
100  error_handler(dict->getNdbError().message);
101  }
102  else
103  ndbout << "Created table" << ((longKey)?" with long key":"") <<endl;
104 }
105 
106 static void createIndex(Ndb &myNdb, bool includePrimary, unsigned int noOfIndexes)
107 {
108  Uint64 before, after;
110  char indexName[] = "INDEX0000";
111  int res;
112 
113  for(unsigned int indexNum = 0; indexNum < noOfIndexes; indexNum++) {
114  sprintf(indexName, "INDEX%.4u", indexNum);
115  NdbDictionary::Index index(indexName);
116  index.setTable("THE_TABLE");
118  if (includePrimary) {
119  const char* attr_arr[] = {"X", "Y"};
120  index.addIndexColumns(2, attr_arr);
121  }
122  else {
123  const char* attr_arr[] = {"Y"};
124  index.addIndexColumns(2, attr_arr);
125  }
126  before = NdbTick_CurrentMillisecond();
127  if ((res = dict->createIndex(index)) == -1) {
128  error_handler(dict->getNdbError().message);
129  }
130  after = NdbTick_CurrentMillisecond();
131  ndbout << "Created index " << indexName << ", " << after - before << " msec"<< endl;
132  }
133 }
134 
135 static void insertTable(Ndb &myNdb, unsigned int noOfTuples, unsigned int noOfOperations, bool oneTrans, bool twoKey, bool longKey)
136 {
137  Uint64 tbefore, tafter, before, after;
138  NdbConnection *myTrans;
139  NdbOperation *myOp;
140 
141  tbefore = NdbTick_CurrentMillisecond();
142  if (oneTrans) myTrans = myNdb.startTransaction();
143  for (unsigned int i = 0; i<noOfTuples; i++) {
144  if (!oneTrans) myTrans = myNdb.startTransaction();
145  for(unsigned int j = 1;
146  ((j<=noOfOperations)&&(i<noOfTuples));
147  (++j<=noOfOperations)?i++:i) {
148  if (myTrans == NULL)
149  error_handler4(__LINE__, myNdb.getNdbError().status, myNdb.getNdbError().classification,
150  myNdb.getNdbError().code, myNdb.getNdbError().message);
151 
152  myOp = myTrans->getNdbOperation("THE_TABLE");
153  if (myOp == NULL)
154  error_handler4(__LINE__, myTrans->getNdbError().status, myTrans->getNdbError().classification,
155  myTrans->getNdbError().code, myTrans->getNdbError().message);
156 
157  myOp->insertTuple();
158  if (myOp->equal("X", i) == -1) {
159  error_handler4(__LINE__, myTrans->getNdbError().status, myTrans->getNdbError().classification,
160  myTrans->getNdbError().code, myTrans->getNdbError().message);
161  myNdb.closeTransaction(myTrans);
162  break;
163  }
164  if (myOp->setValue("Y", i+1) == -1) {
165  error_handler4(__LINE__, myTrans->getNdbError().status, myTrans->getNdbError().classification,
166  myTrans->getNdbError().code, myTrans->getNdbError().message);
167  myNdb.closeTransaction(myTrans);
168  break;
169  }
170  }
171  before = NdbTick_CurrentMillisecond();
172  if (myTrans->execute( (oneTrans) ? NoCommit : Commit ) == -1)
173  {
174  error_handler4(__LINE__, myTrans->getNdbError().status, myTrans->getNdbError().classification,
175  myTrans->getNdbError().code, myTrans->getNdbError().message);
176  myNdb.closeTransaction(myTrans);
177  break;
178  }
179  after = NdbTick_CurrentMillisecond();
180  if (noOfOperations == 1)
181  printf("Inserted 1 tuple, %u msec\n", (Uint32) after - before);
182  else
183  printf("Inserted %u tuples, %u msec\n", noOfOperations, (Uint32) after - before);
184 
185  if (!oneTrans) myNdb.closeTransaction(myTrans);
186  }
187  if (oneTrans) {
188  if (myTrans->execute( Commit ) == -1) {
189  error_handler4(__LINE__, myTrans->getNdbError().status, myTrans->getNdbError().classification,
190  myTrans->getNdbError().code, myTrans->getNdbError().message);
191  }
192  myNdb.closeTransaction(myTrans);
193  }
194  tafter = NdbTick_CurrentMillisecond();
195 
196  ndbout << "Inserted "<< noOfTuples << " tuples in " << ((oneTrans) ? 1 : noOfTuples) << " transaction(s), " << tafter - tbefore << " msec" << endl;
197 }
198 
199 static void updateTable(Ndb &myNdb, unsigned int noOfTuples, unsigned int noOfOperations, bool oneTrans, bool twoKey, bool longKey)
200 {
201  Uint64 tbefore, tafter, before, after;
202  NdbConnection *myTrans;
203  NdbOperation *myOp;
204 
205  tbefore = NdbTick_CurrentMillisecond();
206  if (oneTrans) myTrans = myNdb.startTransaction();
207  for (unsigned int i = 0; i<noOfTuples; i++) {
208  if (!oneTrans) myTrans = myNdb.startTransaction();
209  for(unsigned int j = 1;
210  ((j<=noOfOperations)&&(i<noOfTuples));
211  (++j<=noOfOperations)?i++:i) {
212  if (myTrans == NULL)
213  error_handler4(__LINE__, myNdb.getNdbError().status, myNdb.getNdbError().classification,
214  myNdb.getNdbError().code, myNdb.getNdbError().message);
215 
216  myOp = myTrans->getNdbOperation("THE_TABLE");
217  if (myOp == NULL)
218  error_handler4(__LINE__, myTrans->getNdbError().status, myTrans->getNdbError().classification,
219  myTrans->getNdbError().code, myTrans->getNdbError().message);
220 
221  myOp->updateTuple();
222  if (myOp->equal("X", i) == -1) {
223  error_handler4(__LINE__, myTrans->getNdbError().status, myTrans->getNdbError().classification,
224  myTrans->getNdbError().code, myTrans->getNdbError().message);
225  myNdb.closeTransaction(myTrans);
226  break;
227  }
228  if (myOp->setValue("Y", i+2) == -1) {
229  error_handler4(__LINE__, myTrans->getNdbError().status, myTrans->getNdbError().classification,
230  myTrans->getNdbError().code, myTrans->getNdbError().message);
231  myNdb.closeTransaction(myTrans);
232  break;
233  }
234  }
235  before = NdbTick_CurrentMillisecond();
236  if (myTrans->execute( (oneTrans) ? NoCommit : Commit ) == -1)
237  {
238  error_handler4(__LINE__, myTrans->getNdbError().status, myTrans->getNdbError().classification,
239  myTrans->getNdbError().code, myTrans->getNdbError().message);
240  myNdb.closeTransaction(myTrans);
241  break;
242  }
243  after = NdbTick_CurrentMillisecond();
244  if (noOfOperations == 1)
245  printf("Updated 1 tuple, %u msec\n", (Uint32) after - before);
246  else
247  printf("Update %u tuples, %u msec\n", noOfOperations, (Uint32) after - before);
248 
249  if (!oneTrans) myNdb.closeTransaction(myTrans);
250  }
251  if (oneTrans) {
252  if (myTrans->execute( Commit ) == -1) {
253  error_handler4(__LINE__, myTrans->getNdbError().status, myTrans->getNdbError().classification,
254  myTrans->getNdbError().code, myTrans->getNdbError().message);
255  }
256  myNdb.closeTransaction(myTrans);
257  }
258  tafter = NdbTick_CurrentMillisecond();
259 
260  ndbout << "Updated "<< noOfTuples << " tuples in " << ((oneTrans) ? 1 : noOfTuples) << " transaction(s), " << tafter - tbefore << " msec" << endl;
261 }
262 
263 static void deleteTable(Ndb &myNdb, unsigned int noOfTuples, unsigned int noOfOperations, bool oneTrans, bool twoKey, bool longKey)
264 {
265  Uint64 tbefore, tafter, before, after;
266  NdbConnection *myTrans;
267  NdbOperation *myOp;
268 
269  tbefore = NdbTick_CurrentMillisecond();
270  if (oneTrans) myTrans = myNdb.startTransaction();
271  for (unsigned int i = 0; i<noOfTuples; i++) {
272  if (!oneTrans) myTrans = myNdb.startTransaction();
273  for(unsigned int j = 1;
274  ((j<=noOfOperations)&&(i<noOfTuples));
275  (++j<=noOfOperations)?i++:i) {
276  if (myTrans == NULL)
277  error_handler4(__LINE__, myNdb.getNdbError().status, myNdb.getNdbError().classification,
278  myNdb.getNdbError().code, myNdb.getNdbError().message);
279 
280  myOp = myTrans->getNdbOperation("THE_TABLE");
281  if (myOp == NULL)
282  error_handler4(__LINE__, myTrans->getNdbError().status, myTrans->getNdbError().classification,
283  myTrans->getNdbError().code, myTrans->getNdbError().message);
284 
285  myOp->deleteTuple();
286  if (myOp->equal("X", i) == -1) {
287  error_handler4(__LINE__, myTrans->getNdbError().status, myTrans->getNdbError().classification,
288  myTrans->getNdbError().code, myTrans->getNdbError().message);
289  myNdb.closeTransaction(myTrans);
290  break;
291  }
292  before = NdbTick_CurrentMillisecond();
293  if (myTrans->execute( (oneTrans) ? NoCommit : Commit ) == -1)
294  {
295  error_handler4(__LINE__, myTrans->getNdbError().status, myTrans->getNdbError().classification,
296  myTrans->getNdbError().code, myTrans->getNdbError().message);
297  myNdb.closeTransaction(myTrans);
298  break;
299  }
300  }
301  after = NdbTick_CurrentMillisecond();
302  if (noOfOperations == 1)
303  printf("Deleted 1 tuple, %u msec\n", (Uint32) after - before);
304  else
305  printf("Deleted %u tuples, %u msec\n", noOfOperations, (Uint32) after - before);
306 
307  if (!oneTrans) myNdb.closeTransaction(myTrans);
308  }
309  if (oneTrans) {
310  if (myTrans->execute( Commit ) == -1) {
311  error_handler4(__LINE__, myTrans->getNdbError().status, myTrans->getNdbError().classification,
312  myTrans->getNdbError().code, myTrans->getNdbError().message);
313  }
314  myNdb.closeTransaction(myTrans);
315  }
316  tafter = NdbTick_CurrentMillisecond();
317 
318  ndbout << "Deleted "<< noOfTuples << " tuples in " << ((oneTrans) ? 1 : noOfTuples) << " transaction(s), " << tafter - tbefore << " msec" << endl;
319 }
320 
321 static void readTable(Ndb &myNdb, unsigned int noOfTuples, unsigned int noOfOperations, bool oneTrans, bool twoKey, bool longKey)
322 {
323  Uint64 tbefore, tafter, before, after;
324  NdbConnection *myTrans;
325  NdbOperation *myOp;
326  NdbRecAttr* myRecAttrArr[MAX_NO_PARALLEL_OPERATIONS];
327 
328  tbefore = NdbTick_CurrentMillisecond();
329  if (oneTrans) myTrans = myNdb.startTransaction();
330  for (unsigned int i = 0; i<noOfTuples; i++) {
331  if (!oneTrans) myTrans = myNdb.startTransaction();
332  for(unsigned int j = 1;
333  ((j<=noOfOperations)&&(i<noOfTuples));
334  (++j<=noOfOperations)?i++:i) {
335  if (myTrans == NULL)
336  error_handler4(__LINE__, myNdb.getNdbError().status, myNdb.getNdbError().classification,
337  myNdb.getNdbError().code, myNdb.getNdbError().message);
338 
339  myOp = myTrans->getNdbOperation("THE_TABLE");
340  if (myOp == NULL)
341  error_handler4(__LINE__, myTrans->getNdbError().status, myTrans->getNdbError().classification,
342  myTrans->getNdbError().code, myTrans->getNdbError().message);
343 
344  myOp->readTuple();
345  if (myOp->equal("X", i) == -1) {
346  error_handler4(__LINE__, myTrans->getNdbError().status, myTrans->getNdbError().classification,
347  myTrans->getNdbError().code, myTrans->getNdbError().message);
348  myNdb.closeTransaction(myTrans);
349  break;
350  }
351  myRecAttrArr[j-1] = myOp->getValue("Y", NULL);
352  }
353  before = NdbTick_CurrentMillisecond();
354  if (myTrans->execute( (oneTrans) ? NoCommit : Commit ) == -1)
355  {
356  error_handler4(__LINE__, myTrans->getNdbError().status, myTrans->getNdbError().classification,
357  myTrans->getNdbError().code, myTrans->getNdbError().message);
358  myNdb.closeTransaction(myTrans);
359  break;
360  }
361  after = NdbTick_CurrentMillisecond();
362  if (noOfOperations == 1)
363  printf("Read 1 tuple, %u msec\n", (Uint32) after - before);
364  else
365  printf("Read %u tuples, %u msec\n", noOfOperations, (Uint32) after - before);
366  for(unsigned int j = 0; j<noOfOperations; j++)
367  printf("Y = %u\n", myRecAttrArr[j]->u_32_value());
368  if (!oneTrans) myNdb.closeTransaction(myTrans);
369  }
370  if (oneTrans) {
371  if (myTrans->execute( Commit ) == -1) {
372  error_handler4(__LINE__, myTrans->getNdbError().status, myTrans->getNdbError().classification,
373  myTrans->getNdbError().code, myTrans->getNdbError().message);
374  }
375  myNdb.closeTransaction(myTrans);
376  }
377  tafter = NdbTick_CurrentMillisecond();
378 
379  ndbout << "Read "<< noOfTuples << " tuples in " << ((oneTrans) ? 1 : noOfTuples) << " transaction(s), " << tafter - tbefore << " msec" << endl;
380 }
381 
382 static void readIndex(Ndb &myNdb, unsigned int noOfTuples, unsigned int noOfOperations, bool includePrimary, bool oneTrans, bool longKey)
383 {
384  Uint64 tbefore, tafter, before, after;
385  NdbConnection *myTrans;
386  NdbIndexOperation *myOp;
387  char indexName[] = "INDEX0000";
388  NdbRecAttr* myRecAttrArr[MAX_NO_PARALLEL_OPERATIONS];
389 
390  tbefore = NdbTick_CurrentMillisecond();
391  if (oneTrans) myTrans = myNdb.startTransaction();
392  for (unsigned int i = 0; i<noOfTuples; i++) {
393  if (!oneTrans) myTrans = myNdb.startTransaction();
394  for(unsigned int j = 1;
395  ((j<=noOfOperations)&&(i<noOfTuples));
396  (++j<=noOfOperations)?i++:i) {
397  if (myTrans == NULL)
398  error_handler4(__LINE__, myNdb.getNdbError().status, myNdb.getNdbError().classification,
399  myNdb.getNdbError().code, myNdb.getNdbError().message);
400 
401  myOp = myTrans->getNdbIndexOperation(indexName, "THE_TABLE");
402  if (myOp == NULL)
403  error_handler4(__LINE__, myTrans->getNdbError().status, myTrans->getNdbError().classification,
404  myTrans->getNdbError().code, myTrans->getNdbError().message);
405 
406  myOp->readTuple();
407  if (includePrimary) {
408  if (myOp->equal("X", i) == -1) {
409  error_handler4(__LINE__, myTrans->getNdbError().status, myTrans->getNdbError().classification,
410  myTrans->getNdbError().code, myTrans->getNdbError().message);
411  myNdb.closeTransaction(myTrans);
412  break;
413  }
414  }
415  if (myOp->equal("Y", i+1) == -1) {
416  error_handler4(__LINE__, myTrans->getNdbError().status, myTrans->getNdbError().classification,
417  myTrans->getNdbError().code, myTrans->getNdbError().message);
418  myNdb.closeTransaction(myTrans);
419  break;
420  }
421  myRecAttrArr[j-1] = myOp->getValue("Y", NULL);
422  }
423  before = NdbTick_CurrentMillisecond();
424  if (myTrans->execute( (oneTrans) ? NoCommit : Commit ) == -1)
425  {
426  error_handler4(__LINE__, myTrans->getNdbError().status, myTrans->getNdbError().classification,
427  myTrans->getNdbError().code, myTrans->getNdbError().message);
428  myNdb.closeTransaction(myTrans);
429  break;
430  }
431  after = NdbTick_CurrentMillisecond();
432  if (noOfOperations == 1)
433  printf("Read 1 tuple, %u msec\n", (Uint32) after - before);
434  else
435  printf("Read %u tuples, %u msec\n", noOfOperations, (Uint32) after - before);
436  for(unsigned int j = 0; j<noOfOperations; j++)
437  printf("Y = %u\n", myRecAttrArr[j]->u_32_value());
438  if (!oneTrans) myNdb.closeTransaction(myTrans);
439  }
440  if (oneTrans) {
441  if (myTrans->execute( Commit ) == -1) {
442  error_handler4(__LINE__, myTrans->getNdbError().status, myTrans->getNdbError().classification,
443  myTrans->getNdbError().code, myTrans->getNdbError().message);
444  }
445  myNdb.closeTransaction(myTrans);
446  }
447  tafter = NdbTick_CurrentMillisecond();
448 
449  ndbout << "Read "<< noOfTuples << " tuples in " << ((oneTrans) ? 1 : noOfTuples) << " transaction(s), " << tafter - tbefore << " msec" << endl;
450 }
451 
452 static void updateIndex(Ndb &myNdb, unsigned int noOfTuples, unsigned int noOfOperations, bool includePrimary, bool oneTrans, bool longKey)
453 {
454  Uint64 tbefore, tafter, before, after;
455  NdbConnection *myTrans;
456  NdbIndexOperation *myOp;
457  char indexName[] = "INDEX0000";
458 
459  tbefore = NdbTick_CurrentMillisecond();
460  if (oneTrans) myTrans = myNdb.startTransaction();
461  for (unsigned int i = 0; i<noOfTuples; i++) {
462  if (!oneTrans) myTrans = myNdb.startTransaction();
463  for(unsigned int j = 1;
464  ((j<=noOfOperations)&&(i<noOfTuples));
465  (++j<=noOfOperations)?i++:i) {
466  if (myTrans == NULL)
467  error_handler4(__LINE__, myNdb.getNdbError().status, myNdb.getNdbError().classification,
468  myNdb.getNdbError().code, myNdb.getNdbError().message);
469 
470  myOp = myTrans->getNdbIndexOperation(indexName, "THE_TABLE");
471  if (myOp == NULL)
472  error_handler4(__LINE__, myTrans->getNdbError().status, myTrans->getNdbError().classification,
473  myTrans->getNdbError().code, myTrans->getNdbError().message);
474 
475  myOp->updateTuple();
476  if (includePrimary) {
477  if (myOp->equal("X", i) == -1) {
478  error_handler4(__LINE__, myTrans->getNdbError().status, myTrans->getNdbError().classification,
479  myTrans->getNdbError().code, myTrans->getNdbError().message);
480  myNdb.closeTransaction(myTrans);
481  break;
482  }
483  }
484  if (myOp->equal("Y", i+1) == -1) {
485  error_handler4(__LINE__, myTrans->getNdbError().status, myTrans->getNdbError().classification,
486  myTrans->getNdbError().code, myTrans->getNdbError().message);
487  myNdb.closeTransaction(myTrans);
488  break;
489  }
490  // Update index itself, should be possible
491  if (myOp->setValue("Y", i+2) == -1) {
492  error_handler4(__LINE__, myTrans->getNdbError().status, myTrans->getNdbError().classification,
493  myTrans->getNdbError().code, myTrans->getNdbError().message);
494  myNdb.closeTransaction(myTrans);
495  break;
496  }
497  }
498  before = NdbTick_CurrentMillisecond();
499  if (myTrans->execute( (oneTrans) ? NoCommit : Commit ) == -1)
500  {
501  error_handler4(__LINE__, myTrans->getNdbError().status, myTrans->getNdbError().classification,
502  myTrans->getNdbError().code, myTrans->getNdbError().message);
503  myNdb.closeTransaction(myTrans);
504  break;
505  }
506 
507  after = NdbTick_CurrentMillisecond();
508  if (noOfOperations == 1)
509  printf("Updated 1 tuple, %u msec\n", (Uint32) after - before);
510  else
511  printf("Updated %u tuples, %u msec\n", noOfOperations, (Uint32) after - before);
512  if (!oneTrans) myNdb.closeTransaction(myTrans);
513  }
514  if (oneTrans) {
515  if (myTrans->execute( Commit ) == -1) {
516  error_handler4(__LINE__, myTrans->getNdbError().status, myTrans->getNdbError().classification,
517  myTrans->getNdbError().code, myTrans->getNdbError().message);
518  }
519  myNdb.closeTransaction(myTrans);
520  }
521  tafter = NdbTick_CurrentMillisecond();
522 
523  ndbout << "Updated "<< noOfTuples << " tuples in " << ((oneTrans) ? 1 : noOfTuples) << " transaction(s), " << tafter - tbefore << " msec" << endl;
524 }
525 
526 static void deleteIndex(Ndb &myNdb, unsigned int noOfTuples, unsigned int noOfOperations, bool includePrimary, bool oneTrans, bool longKey)
527 {
528  Uint64 tbefore, tafter, before, after;
529  NdbConnection *myTrans;
530  NdbIndexOperation *myOp;
531  char indexName[] = "INDEX0000";
532 
533  tbefore = NdbTick_CurrentMillisecond();
534  if (oneTrans) myTrans = myNdb.startTransaction();
535  for (unsigned int i = 0; i<noOfTuples; i++) {
536  for(unsigned int j = 1;
537  ((j<=noOfOperations)&&(i<noOfTuples));
538  (++j<=noOfOperations)?i++:i) {
539  if (!oneTrans) myTrans = myNdb.startTransaction();
540  if (myTrans == NULL)
541  error_handler4(__LINE__, myNdb.getNdbError().status, myNdb.getNdbError().classification,
542  myNdb.getNdbError().code, myNdb.getNdbError().message);
543 
544  myOp = myTrans->getNdbIndexOperation(indexName, "THE_TABLE");
545  if (myOp == NULL)
546  error_handler4(__LINE__, myTrans->getNdbError().status, myTrans->getNdbError().classification,
547  myTrans->getNdbError().code, myTrans->getNdbError().message);
548 
549  myOp->deleteTuple();
550  if (includePrimary) {
551  if (myOp->equal("X", i) == -1) {
552  error_handler4(__LINE__, myTrans->getNdbError().status, myTrans->getNdbError().classification,
553  myTrans->getNdbError().code, myTrans->getNdbError().message);
554  myNdb.closeTransaction(myTrans);
555  break;
556  }
557  }
558  if (myOp->equal("Y", i+1) == -1) {
559  error_handler4(__LINE__, myTrans->getNdbError().status, myTrans->getNdbError().classification,
560  myTrans->getNdbError().code, myTrans->getNdbError().message);
561  myNdb.closeTransaction(myTrans);
562  break;
563  }
564  }
565  before = NdbTick_CurrentMillisecond();
566  if (myTrans->execute( (oneTrans) ? NoCommit : Commit ) == -1)
567  {
568  error_handler4(__LINE__, myTrans->getNdbError().status, myTrans->getNdbError().classification,
569  myTrans->getNdbError().code, myTrans->getNdbError().message);
570  myNdb.closeTransaction(myTrans);
571  break;
572  }
573  after = NdbTick_CurrentMillisecond();
574  if (noOfOperations == 1)
575  printf("Deleted 1 tuple, %u msec\n", (Uint32) after - before);
576  else
577  printf("Deleted %u tuples, %u msec\n", noOfOperations, (Uint32) after - before);
578  if (!oneTrans) myNdb.closeTransaction(myTrans);
579  }
580  if (oneTrans) {
581  if (myTrans->execute( Commit ) == -1) {
582  error_handler4(__LINE__, myTrans->getNdbError().status, myTrans->getNdbError().classification,
583  myTrans->getNdbError().code, myTrans->getNdbError().message);
584  }
585  myNdb.closeTransaction(myTrans);
586  }
587  tafter = NdbTick_CurrentMillisecond();
588 
589  ndbout << "Deleted "<< noOfTuples << " tuples in " << ((oneTrans) ? 1 : noOfTuples) << " transaction(s), " << tafter - tbefore << " msec" << endl;
590 }
591 
592 static void dropIndex(Ndb &myNdb, unsigned int noOfIndexes)
593 {
594  for(unsigned int indexNum = 0; indexNum < noOfIndexes; indexNum++) {
595  char indexName[255];
596  sprintf(indexName, "INDEX%.4u", indexNum);
597  const Uint64 before = NdbTick_CurrentMillisecond();
598  const int retVal = myNdb.getDictionary()->dropIndex(indexName,"THE_TABLE");
599  const Uint64 after = NdbTick_CurrentMillisecond();
600 
601  if(retVal == 0){
602  ndbout << "Dropped index " << indexName << ", "
603  << after - before << " msec" << endl;
604  } else {
605  ndbout << "Failed to drop index " << indexName << endl;
606  ndbout << myNdb.getDictionary()->getNdbError() << endl;
607  }
608  }
609 }
610 
611 NDB_COMMAND(indexTest, "indexTest", "indexTest", "indexTest", 65535)
612 {
613  ndb_init();
614  bool createTableOp, createIndexOp, dropIndexOp, insertOp, updateOp, deleteOp, readOp, readIndexOp, updateIndexOp, deleteIndexOp, twoKey, longKey;
615  unsigned int noOfTuples = 1;
616  unsigned int noOfOperations = 1;
617  unsigned int noOfIndexes = 1;
618  int i = 1;
619  Ndb myNdb( "TEST_DB" );
620  int check;
621  bool storeInACC = false;
622  bool includePrimary = false;
623  bool oneTransaction = false;
624 
625  createTableOp = createIndexOp = dropIndexOp = insertOp = updateOp = deleteOp = readOp = readIndexOp = updateIndexOp = deleteIndexOp = twoKey = longKey = false;
626  // Read arguments
627  if (argc > 1)
628  while (argc > 1)
629  {
630  if (strcmp(argv[i], "-T") == 0)
631  {
632  createTableOp = true;
633  argc -= 1;
634  i++;
635  }
636  else if (strcmp(argv[i], "-c") == 0)
637  {
638  createIndexOp = true;
639  argc -= 1;
640  i++;
641  }
642  else if (strcmp(argv[i], "-X") == 0)
643  {
644  dropIndexOp = true;
645  argc -= 1;
646  i++;
647  }
648  else if (strcmp(argv[i], "-I") == 0)
649  {
650  insertOp = true;
651  argc -= 1;
652  i++;
653  }
654  else if (strcmp(argv[i], "-D") == 0)
655  {
656  deleteOp = true;
657  argc -= 1;
658  i++;
659  }
660  else if (strcmp(argv[i], "-U") == 0)
661  {
662  updateOp = true;
663  argc -= 1;
664  i++;
665  }
666  else if (strcmp(argv[i], "-R") == 0)
667  {
668  readOp = true;
669  argc -= 1;
670  i++;
671  }
672  else if (strcmp(argv[i], "-r") == 0)
673  {
674  readIndexOp = true;
675  argc -= 1;
676  i++;
677  }
678  else if (strcmp(argv[i], "-u") == 0)
679  {
680  updateIndexOp = true;
681  argc -= 1;
682  i++;
683  }
684  else if (strcmp(argv[i], "-d") == 0)
685  {
686  deleteIndexOp = true;
687  argc -= 1;
688  i++;
689  }
690  else if (strcmp(argv[i], "-s") == 0)
691  {
692  storeInACC = true;
693  argc -= 1;
694  i++;
695  }
696  else if (strcmp(argv[i], "-p") == 0)
697  {
698  includePrimary = true;
699  argc -= 1;
700  i++;
701  }
702  else if (strcmp(argv[i], "-L") == 0)
703  {
704  longKey = true;
705  argc -= 1;
706  i++;
707  }
708  else if (strcmp(argv[i], "-1") == 0)
709  {
710  oneTransaction = true;
711  argc -= 1;
712  i++;
713  }
714  else if (strcmp(argv[i], "-2") == 0)
715  {
716  twoKey = true;
717  argc -= 1;
718  i++;
719  }
720  else if (strstr(argv[i], "-n") != 0)
721  {
722  noOfTuples = atoi(argv[i]+2);
723  argc -= 1;
724  i++;
725  }
726  else if (strstr(argv[i], "-o") != 0)
727  {
728  noOfOperations = MIN(MAX_NO_PARALLEL_OPERATIONS, atoi(argv[i]+2));
729  argc -= 1;
730  i++;
731  }
732  else if (strstr(argv[i], "-m") != 0)
733  {
734  noOfIndexes = atoi(argv[i]+2);
735  argc -= 1;
736  i++;
737  }
738  else if (strstr(argv[i], "-h") != 0)
739  {
740  printf("Synopsis: \
741  index\
742  -T create table\
743  -L include a long attribute in key or index\
744  -2 define primary key with two attributes\
745  -c create index\
746  -p make index unique (include primary key attribute)\
747  -r read using index\
748  -u update using index\
749  -d delete using index\
750  -n<no operations> do n operations (for -I -r -u -d -R -U -D)\
751  -o<no parallel operations> (for -I -r -u -d -R -U -D)\
752  -m<no indexes>\n");
753  argc -= 1;
754  i++;
755  }
756  else {
757  char errStr[256];
758 
759  sprintf(errStr, "Illegal argument: %s", argv[i]);
760  error_handler(errStr);
761  exit(-1);
762  }
763  }
764  else
765  {
766  createTableOp = createIndexOp = dropIndexOp = insertOp = updateOp = deleteOp = true;
767  }
768  if (longKey) {
769  longName = (char *) malloc(1024);
770  for (int i = 0; i < 1023; i++)
771  longName[i] = 'x';
772  longName[1023] = '\0';
773  }
774  sixtysix = (char *) malloc(256);
775  for (int i = 0; i < 255; i++)
776  sixtysix[i] = ' ';
777  sixtysix[255] = '\0';
778  strncpy(sixtysix, "sixtysix", strlen("sixtysix"));
779  ninetynine = (char *) malloc(256);
780  for (int i = 0; i < 255; i++)
781  ninetynine[i] = ' ';
782  ninetynine[255] = '\0';
783  strncpy(ninetynine, "ninetynine", strlen("ninetynine"));
784  hundred = (char *) malloc(256);
785  for (int i = 0; i < 255; i++)
786  hundred[i] = ' ';
787  hundred[255] = '\0';
788  strncpy(hundred, "hundred", strlen("hundred"));
789  myNdb.init();
790  // Wait for Ndb to become ready
791  if (myNdb.waitUntilReady(30) == 0)
792  {
793  if (createTableOp)
794  createTable(myNdb, storeInACC, twoKey, longKey);
795 
796  if (createIndexOp)
797  createIndex(myNdb, includePrimary, noOfIndexes);
798 
799  if (insertOp)
800  insertTable(myNdb, noOfTuples, noOfOperations, oneTransaction, twoKey, longKey);
801 
802  if (updateOp)
803  updateTable(myNdb, noOfTuples, noOfOperations, oneTransaction, twoKey, longKey);
804 
805  if (deleteOp)
806  deleteTable(myNdb, noOfTuples, noOfOperations, oneTransaction, twoKey, longKey);
807 
808  if (readOp)
809  readTable(myNdb, noOfTuples, noOfOperations, oneTransaction, twoKey, longKey);
810 
811  if (readIndexOp)
812  readIndex(myNdb, noOfTuples, noOfOperations, includePrimary, oneTransaction, longKey);
813 
814  if (updateIndexOp)
815  updateIndex(myNdb, noOfTuples, noOfOperations, includePrimary, oneTransaction, longKey);
816 
817  if (deleteIndexOp)
818  deleteIndex(myNdb, noOfTuples, noOfOperations, includePrimary, oneTransaction, longKey);
819 
820  if (dropIndexOp)
821  dropIndex(myNdb, noOfIndexes);
822  }
823 
824  if (testPassed)
825  {
826  // Test passed
827  ndbout << "OK - Test passed" << endl;
828  }
829  else
830  {
831  // Test failed
832  ndbout << "FAIL - Test failed" << endl;
833  exit(-1);
834  }
835  return NULL;
836 }
837 
838