42 #include <ndb_global.h>
48 #include <NdbTest.hpp>
49 #include <NDBT_Error.hpp>
52 #define MIN(x,y) (((x)<(y))?(x):(y))
55 #define MAX_NO_PARALLEL_OPERATIONS 100
57 bool testPassed =
true;
63 ndbout << endl << err << endl;
68 error_handler4(
int line,
const NdbError & err){
69 ndbout << endl <<
"Line " << line << endl;
71 ndbout << err << endl;
75 static char *longName, *sixtysix, *ninetynine, *hundred;
77 static void createTable(
Ndb &myNdb,
bool storeInACC,
bool twoKey,
bool longKey)
92 table.addColumn(column);
100 table.addColumn(column);
108 table.addColumn(column);
115 table.addColumn(column);
122 table.addColumn(column);
129 table.addColumn(column);
136 table.addColumn(column);
144 table.addColumn(column);
150 ndbout <<
"Created table" << ((longKey)?
" with long key":
"") <<endl;
153 static void createIndex(
Ndb &myNdb,
bool includePrimary,
unsigned int noOfIndexes)
155 Uint64 before, after;
157 char indexName[] =
"PNUMINDEX0000";
160 for(
unsigned int indexNum = 0; indexNum < noOfIndexes; indexNum++) {
161 sprintf(indexName,
"PNUMINDEX%.4u", indexNum);
163 index.setTable(
"PERSON");
165 if (includePrimary) {
166 const char* attr_arr[] = {
"NAME",
"PNUM1",
"PNUM3"};
167 index.addIndexColumns(3, attr_arr);
170 const char* attr_arr[] = {
"PNUM1",
"PNUM3"};
171 index.addIndexColumns(2, attr_arr);
173 before = NdbTick_CurrentMillisecond();
177 after = NdbTick_CurrentMillisecond();
178 ndbout <<
"Created index " << indexName <<
", " << after - before <<
" msec" << endl;
182 static void insertTable(
Ndb &myNdb,
unsigned int noOfTuples,
unsigned int noOfOperations,
bool oneTrans,
bool twoKey,
bool longKey)
184 Uint64 tbefore, tafter, before, after;
187 char name[] =
"Kalle0000000";
189 tbefore = NdbTick_CurrentMillisecond();
191 for (
unsigned int i = 0;
i<noOfTuples;
i++) {
193 for(
unsigned int j = 1;
194 ((j<=noOfOperations)&&(
i<noOfTuples));
195 (++j<=noOfOperations)?
i++:
i) {
204 sprintf(name,
"Kalle%.7i",
i);
206 memcpy(longName, name, strlen(name));
207 if (myOp->equal(
"NAME", (longKey)?longName:name) == -1) {
213 if (myOp->equal(
"KEY2",
i) == -1) {
218 if (myOp->setValue(
"PNUM1", 17) == -1) {
223 if (myOp->setValue(
"PNUM2", 18)) {
228 if (myOp->setValue(
"PNUM3", 19)) {
233 if (myOp->setValue(
"PNUM4", 20)) {
238 if (myOp->setValue(
"AGE", ((
i % 2) == 0)?66:99) == -1) {
243 if (myOp->setValue(
"STRING_AGE", ((
i % 2) == 0)?sixtysix:ninetynine) == -1) {
249 if (noOfOperations == 1)
250 printf(
"Trying to insert person %s\n", name);
252 printf(
"Trying to insert %u persons\n", noOfOperations);
253 before = NdbTick_CurrentMillisecond();
254 if (myTrans->
execute( (oneTrans) ? NoCommit : Commit ) == -1)
260 after = NdbTick_CurrentMillisecond();
261 if (noOfOperations == 1)
262 printf(
"Inserted person %s, %u msec\n", name, (Uint32) after - before);
264 printf(
"Inserted %u persons, %u msec\n", noOfOperations, (Uint32) after - before);
268 if (myTrans->
execute( Commit ) == -1) {
273 tafter = NdbTick_CurrentMillisecond();
275 ndbout <<
"Inserted "<< noOfTuples <<
" tuples in " << ((oneTrans) ? 1 : noOfTuples) <<
" transaction(s), " << tafter - tbefore <<
" msec" << endl;
278 static void updateTable(
Ndb &myNdb,
unsigned int noOfTuples,
unsigned int noOfOperations,
bool oneTrans,
bool twoKey,
bool longKey)
280 Uint64 tbefore, tafter, before, after;
283 char name[] =
"Kalle0000000";
285 tbefore = NdbTick_CurrentMillisecond();
287 for (
unsigned int i = 0;
i<noOfTuples;
i++) {
289 for(
unsigned int j = 1;
290 ((j<=noOfOperations)&&(
i<noOfTuples));
291 (++j<=noOfOperations)?
i++:
i) {
300 sprintf(name,
"Kalle%.7i",
i);
302 memcpy(longName, name, strlen(name));
303 if (myOp->equal(
"NAME", (longKey)?longName:name) == -1) {
309 if (myOp->equal(
"KEY2",
i) == -1) {
314 if (myOp->setValue(
"PNUM1", 77) == -1) {
319 if (myOp->setValue(
"PNUM2", 88)) {
324 if (myOp->setValue(
"PNUM4", 99)) {
329 if (myOp->setValue(
"AGE", 100) == -1) {
334 if (myOp->setValue(
"STRING_AGE", hundred) == -1) {
340 if (noOfOperations == 1)
341 printf(
"Trying to update person %s\n", name);
343 printf(
"Trying to update %u persons\n", noOfOperations);
344 before = NdbTick_CurrentMillisecond();
345 if (myTrans->
execute( (oneTrans) ? NoCommit : Commit ) == -1)
351 after = NdbTick_CurrentMillisecond();
352 if (noOfOperations == 1)
353 printf(
"Updated person %s, %u msec\n", name, (Uint32) after - before);
355 printf(
"Update %u persons, %u msec\n", noOfOperations, (Uint32) after - before);
359 if (myTrans->
execute( Commit ) == -1) {
364 tafter = NdbTick_CurrentMillisecond();
366 ndbout <<
"Updated "<< noOfTuples <<
" tuples in " << ((oneTrans) ? 1 : noOfTuples) <<
" transaction(s), " << tafter - tbefore <<
" msec" << endl;
369 static void deleteTable(
Ndb &myNdb,
unsigned int noOfTuples,
unsigned int noOfOperations,
bool oneTrans,
bool twoKey,
bool longKey)
371 Uint64 tbefore, tafter, before, after;
374 char name[] =
"Kalle0000000";
376 tbefore = NdbTick_CurrentMillisecond();
378 for (
unsigned int i = 0;
i<noOfTuples;
i++) {
380 for(
unsigned int j = 1;
381 ((j<=noOfOperations)&&(
i<noOfTuples));
382 (++j<=noOfOperations)?
i++:
i) {
391 sprintf(name,
"Kalle%.7i",
i);
393 memcpy(longName, name, strlen(name));
394 if (myOp->equal(
"NAME", (longKey)?longName:name) == -1) {
400 if (myOp->equal(
"KEY2",
i) == -1) {
406 if (noOfOperations == 1)
407 printf(
"Trying to delete person %s\n", name);
409 printf(
"Trying to delete %u persons\n", noOfOperations);
410 before = NdbTick_CurrentMillisecond();
411 if (myTrans->
execute( (oneTrans) ? NoCommit : Commit ) == -1)
417 after = NdbTick_CurrentMillisecond();
418 if (noOfOperations == 1)
419 printf(
"Deleted person %s, %u msec\n", name, (Uint32) after - before);
421 printf(
"Deleted %u persons, %u msec\n", noOfOperations, (Uint32) after - before);
426 if (myTrans->
execute( Commit ) == -1) {
431 tafter = NdbTick_CurrentMillisecond();
433 ndbout <<
"Deleted "<< noOfTuples <<
" tuples in " << ((oneTrans) ? 1 : noOfTuples) <<
" transaction(s), " << tafter - tbefore <<
" msec" << endl;
436 static void readTable(
Ndb &myNdb,
unsigned int noOfTuples,
unsigned int noOfOperations,
bool oneTrans,
bool twoKey,
bool longKey)
438 Uint64 tbefore, tafter, before, after;
441 char name[] =
"Kalle0000000";
442 NdbRecAttr* myRecAttrArr[MAX_NO_PARALLEL_OPERATIONS];
444 tbefore = NdbTick_CurrentMillisecond();
446 for (
unsigned int i = 0;
i<noOfTuples;
i++) {
448 for(
unsigned int j = 1;
449 ((j<=noOfOperations)&&(
i<noOfTuples));
450 (++j<=noOfOperations)?
i++:
i) {
459 sprintf(name,
"Kalle%.7i",
i);
461 memcpy(longName, name, strlen(name));
462 if (myOp->equal(
"NAME", (longKey)?longName:name) == -1) {
468 if (myOp->equal(
"KEY2",
i) == -1) {
473 myRecAttrArr[j-1] = myOp->getValue(
"PNUM2", NULL);
475 if (noOfOperations == 1)
476 printf(
"Trying to read person %s\n", name);
478 printf(
"Trying to read %u persons\n", noOfOperations);
479 before = NdbTick_CurrentMillisecond();
480 if (myTrans->
execute( (oneTrans) ? NoCommit : Commit ) == -1)
486 after = NdbTick_CurrentMillisecond();
487 if (noOfOperations == 1)
488 printf(
"Read person %s, %u msec\n", name, (Uint32) after - before);
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());
496 if (myTrans->
execute( Commit ) == -1) {
501 tafter = NdbTick_CurrentMillisecond();
503 ndbout <<
"Read "<< noOfTuples <<
" tuples in " << ((oneTrans) ? 1 : noOfTuples) <<
" transaction(s), " << tafter - tbefore <<
" msec" << endl;
506 static void readIndex(
Ndb &myNdb,
unsigned int noOfTuples,
unsigned int noOfOperations,
bool includePrimary,
bool oneTrans,
bool longKey)
508 Uint64 tbefore, tafter, before, after;
511 char indexName[] =
"PNUMINDEX0000";
512 char name[] =
"Kalle0000000";
513 NdbRecAttr* myRecAttrArr[MAX_NO_PARALLEL_OPERATIONS];
515 tbefore = NdbTick_CurrentMillisecond();
517 for (
unsigned int i = 0;
i<noOfTuples;
i++) {
519 for(
unsigned int j = 1;
520 ((j<=noOfOperations)&&(
i<noOfTuples));
521 (++j<=noOfOperations)?
i++:
i) {
530 if (includePrimary) {
531 sprintf(name,
"Kalle%.7i",
i);
533 memcpy(longName, name, strlen(name));
534 if (myOp->equal(
"NAME", (longKey)?longName:name) == -1) {
540 if (myOp->equal(
"PNUM1", 17) == -1) {
545 if (myOp->equal(
"PNUM3", 19) == -1) {
550 myRecAttrArr[j-1] = myOp->getValue(
"PNUM2", NULL);
552 if (noOfOperations == 1)
553 printf(
"Trying to read person %s\n", name);
555 printf(
"Trying to read %u persons\n", noOfOperations);
556 before = NdbTick_CurrentMillisecond();
557 if (myTrans->
execute( (oneTrans) ? NoCommit : Commit ) == -1)
563 after = NdbTick_CurrentMillisecond();
564 if (noOfOperations == 1)
565 printf(
"Read person %s, %u msec\n", name, (Uint32) after - before);
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());
573 if (myTrans->
execute( Commit ) == -1) {
578 tafter = NdbTick_CurrentMillisecond();
580 ndbout <<
"Read "<< noOfTuples <<
" tuples in " << ((oneTrans) ? 1 : noOfTuples) <<
" transaction(s), " << tafter - tbefore <<
" msec" << endl;
583 static void updateIndex(
Ndb &myNdb,
unsigned int noOfTuples,
unsigned int noOfOperations,
bool includePrimary,
bool oneTrans,
bool longKey)
585 Uint64 tbefore, tafter, before, after;
588 char indexName[] =
"PNUMINDEX0000";
589 char name[] =
"Kalle0000000";
591 tbefore = NdbTick_CurrentMillisecond();
593 for (
unsigned int i = 0;
i<noOfTuples;
i++) {
595 for(
unsigned int j = 1;
596 ((j<=noOfOperations)&&(
i<noOfTuples));
597 (++j<=noOfOperations)?
i++:
i) {
606 if (includePrimary) {
607 sprintf(name,
"Kalle%.7i",
i);
609 memcpy(longName, name, strlen(name));
610 if (myOp->equal(
"NAME", (longKey)?longName:name) == -1) {
616 if (myOp->equal(
"PNUM1", 17) == -1) {
621 if (myOp->equal(
"PNUM3", 19) == -1) {
627 if (myOp->setValue(
"PNUM1", 77) == -1) {
632 if (myOp->setValue(
"PNUM2", 88)) {
637 if (myOp->setValue(
"PNUM4", 99)) {
642 if (myOp->setValue(
"AGE", 100) == -1) {
647 if (myOp->setValue(
"STRING_AGE", hundred) == -1) {
653 if (noOfOperations == 1)
654 printf(
"Trying to update person %s\n", name);
656 printf(
"Trying to update %u persons\n", noOfOperations);
657 before = NdbTick_CurrentMillisecond();
658 if (myTrans->
execute( (oneTrans) ? NoCommit : Commit ) == -1)
664 after = NdbTick_CurrentMillisecond();
665 if (noOfOperations == 1)
666 printf(
"Updated person %s, %u msec\n", name, (Uint32) after - before);
668 printf(
"Updated %u persons, %u msec\n", noOfOperations, (Uint32) after - before);
672 if (myTrans->
execute( Commit ) == -1) {
677 tafter = NdbTick_CurrentMillisecond();
679 ndbout <<
"Updated "<< noOfTuples <<
" tuples in " << ((oneTrans) ? 1 : noOfTuples) <<
" transaction(s), " << tafter - tbefore <<
" msec" << endl;
682 static void deleteIndex(
Ndb &myNdb,
unsigned int noOfTuples,
unsigned int noOfOperations,
bool includePrimary,
bool oneTrans,
bool longKey)
684 Uint64 tbefore, tafter, before, after;
687 char indexName[] =
"PNUMINDEX0000";
688 char name[] =
"Kalle0000000";
690 tbefore = NdbTick_CurrentMillisecond();
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) {
705 if (includePrimary) {
706 sprintf(name,
"Kalle%.7i",
i);
708 memcpy(longName, name, strlen(name));
709 if (myOp->equal(
"NAME", (longKey)?longName:name) == -1) {
715 if (myOp->equal(
"PNUM1", 17) == -1) {
720 if (myOp->equal(
"PNUM3", 19) == -1) {
726 if (noOfOperations == 1)
727 printf(
"Trying to delete person %s\n", name);
729 printf(
"Trying to delete %u persons\n", noOfOperations);
730 before = NdbTick_CurrentMillisecond();
731 if (myTrans->
execute( (oneTrans) ? NoCommit : Commit ) == -1)
737 after = NdbTick_CurrentMillisecond();
738 if (noOfOperations == 1)
739 printf(
"Deleted person %s, %u msec\n", name, (Uint32) after - before);
741 printf(
"Deleted %u persons, %u msec\n", noOfOperations, (Uint32) after - before);
745 if (myTrans->
execute( Commit ) == -1) {
750 tafter = NdbTick_CurrentMillisecond();
752 ndbout <<
"Deleted "<< noOfTuples <<
" tuples in " << ((oneTrans) ? 1 : noOfTuples) <<
" transaction(s), " << tafter - tbefore <<
" msec" << endl;
755 static void dropIndex(
Ndb &myNdb,
unsigned int noOfIndexes)
757 for(
unsigned int indexNum = 0; indexNum < noOfIndexes; indexNum++) {
759 sprintf(indexName,
"PNUMINDEX%.4u", indexNum);
760 const Uint64 before = NdbTick_CurrentMillisecond();
762 const Uint64 after = NdbTick_CurrentMillisecond();
765 ndbout <<
"Dropped index " << indexName <<
", "
766 << after - before <<
" msec" << endl;
768 ndbout <<
"Failed to drop index " << indexName << endl;
774 NDB_COMMAND(indexTest,
"indexTest",
"indexTest",
"indexTest", 65535)
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;
782 Ndb myNdb(
"TEST_DB" );
784 bool storeInACC =
false;
785 bool includePrimary =
false;
786 bool oneTransaction =
false;
788 createTableOp = createIndexOp = dropIndexOp = insertOp = updateOp = deleteOp = readOp = readIndexOp = updateIndexOp = deleteIndexOp = twoKey = longKey =
false;
793 if (strcmp(argv[i],
"-T") == 0)
795 createTableOp =
true;
799 else if (strcmp(argv[i],
"-c") == 0)
801 createIndexOp =
true;
805 else if (strcmp(argv[i],
"-X") == 0)
811 else if (strcmp(argv[i],
"-I") == 0)
817 else if (strcmp(argv[i],
"-D") == 0)
823 else if (strcmp(argv[i],
"-U") == 0)
829 else if (strcmp(argv[i],
"-R") == 0)
835 else if (strcmp(argv[i],
"-r") == 0)
841 else if (strcmp(argv[i],
"-u") == 0)
843 updateIndexOp =
true;
847 else if (strcmp(argv[i],
"-d") == 0)
849 deleteIndexOp =
true;
853 else if (strcmp(argv[i],
"-s") == 0)
859 else if (strcmp(argv[i],
"-p") == 0)
861 includePrimary =
true;
865 else if (strcmp(argv[i],
"-L") == 0)
871 else if (strcmp(argv[i],
"-1") == 0)
873 oneTransaction =
true;
877 else if (strcmp(argv[i],
"-2") == 0)
883 else if (strstr(argv[i],
"-n") != 0)
885 noOfTuples = atoi(argv[i]+2);
889 else if (strstr(argv[i],
"-o") != 0)
891 noOfOperations = MIN(MAX_NO_PARALLEL_OPERATIONS, atoi(argv[i]+2));
895 else if (strstr(argv[i],
"-m") != 0)
897 noOfIndexes = atoi(argv[i]+2);
901 else if (strstr(argv[i],
"-h") != 0)
903 printf(
"Synopsis:\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");
922 printf(errStr,
"Illegal argument: %s", argv[i]);
928 createTableOp = createIndexOp = dropIndexOp = insertOp = updateOp = deleteOp =
true;
931 longName = (
char *) malloc(1024);
932 for (
int i = 0; i < 1023; i++)
934 longName[1023] =
'\0';
936 sixtysix = (
char *) malloc(256);
937 for (
int i = 0; i < 255; i++)
939 sixtysix[255] =
'\0';
940 strncpy(sixtysix,
"sixtysix", strlen(
"sixtysix"));
941 ninetynine = (
char *) malloc(256);
942 for (
int i = 0; i < 255; i++)
944 ninetynine[255] =
'\0';
945 strncpy(ninetynine,
"ninetynine", strlen(
"ninetynine"));
946 hundred = (
char *) malloc(256);
947 for (
int i = 0; i < 255; i++)
950 strncpy(hundred,
"hundred", strlen(
"hundred"));
956 createTable(myNdb, storeInACC, twoKey, longKey);
959 createIndex(myNdb, includePrimary, noOfIndexes);
962 insertTable(myNdb, noOfTuples, noOfOperations, oneTransaction, twoKey, longKey);
965 updateTable(myNdb, noOfTuples, noOfOperations, oneTransaction, twoKey, longKey);
968 deleteTable(myNdb, noOfTuples, noOfOperations, oneTransaction, twoKey, longKey);
971 readTable(myNdb, noOfTuples, noOfOperations, oneTransaction, twoKey, longKey);
974 readIndex(myNdb, noOfTuples, noOfOperations, includePrimary, oneTransaction, longKey);
977 updateIndex(myNdb, noOfTuples, noOfOperations, includePrimary, oneTransaction, longKey);
980 deleteIndex(myNdb, noOfTuples, noOfOperations, includePrimary, oneTransaction, longKey);
983 dropIndex(myNdb, noOfIndexes);
989 ndbout <<
"OK - Test passed" << endl;
994 ndbout <<
"FAIL - Test failed" << endl;