18 #include <NDBT_Test.hpp>
19 #include <NDBT_ReturnCodes.h>
20 #include <HugoTransactions.hpp>
21 #include <UtilTransactions.hpp>
22 #include <NdbRestarter.hpp>
24 static Uint32 max_dks = 0;
25 static const Uint32 MAX_FRAGS=48 * 8 * 4;
26 static Uint32 frag_ng_mappings[MAX_FRAGS];
27 static const char* DistTabName=
"DistTest";
28 static const char* DistTabDKeyCol=
"DKey";
29 static const char* DistTabPKey2Col=
"PKey2";
30 static const char* DistTabResultCol=
"Result";
31 static const char* DistIdxName=
"ResultIndex";
56 const Uint32 rType= rand() % 3;
61 fragType = NdbDictionary::Object::DistrKeyHash;
64 fragType = NdbDictionary::Object::DistrKeyLin;
67 fragType = NdbDictionary::Object::HashMapPartition;
71 ndbout <<
"Setting fragment type to " << fragType << endl;
91 setNativePartitioning(ndb, tab, when, arg);
94 Uint32 dks = (2 * keys + 2) / 3; dks = (dks > max_dks ? max_dks : dks);
106 if(keys <= 1 && max > 0)
108 dks = 1 + (rand() % max);
109 ndbout_c(
"%s pks: %d dks: %d", tab.
getName(), keys, dks);
114 name.
assfmt(
"PK_DK_%d", dks);
116 if((rand() % 100) > 50)
128 col.setDistributionKey(
true);
139 if((
int)dks >= keys || (rand() % 100) > 50)
141 col->setDistributionKey(
true);
161 const Uint32 numReplicas= 2;
162 const Uint32 guessNumNgs= numNodes/2;
163 const Uint32 numNgs= guessNumNgs?guessNumNgs : 1;
164 const Uint32 numFragsPerNode= 2 + (rand() % 3);
165 const Uint32 numPartitions= numReplicas * numNgs * numFragsPerNode;
169 for (Uint32
i=0;
i<numPartitions;
i++)
171 frag_ng_mappings[
i]=
i % numNgs;
191 setupUDPartitioning(ndb, tab);
211 setNativePartitioning(ndb, tab, when, arg);
214 int dist_key_no = rand()% keys;
220 if (dist_key_no-- == 0)
237 create_dist_table(
Ndb* pNdb,
248 setupUDPartitioning(pNdb, tab);
252 setNativePartitioning(pNdb, tab, 0, 0);
274 result.
setName(DistTabResultCol);
301 ndbout <<
"Primary Index created successfully" << endl;
304 ndbout <<
"Primary Index create failed with " <<
306 " retrying " << endl;
323 ndbout <<
"Index on Result created successfully" << endl;
326 ndbout <<
"Index create failed with " <<
340 max_dks = ctx->getProperty(
"distributionkey", (
unsigned)0);
341 bool userDefined = ctx->getProperty(
"UserDefined", (
unsigned) 0);
343 if(NDBT_Tables::createTable(GETNDB(step),
347 add_distribution_key:
349 setUserDefPartitioning :
350 setNativePartitioning) == NDBT_OK)
355 if(GETNDB(step)->getDictionary()->getNdbError().code == 745)
364 if(NDBT_Tables::createTable(GETNDB(step),
367 one_distribution_key) == NDBT_OK)
372 if(GETNDB(step)->getDictionary()->getNdbError().code == 745)
380 bool orderedIndex = ctx->getProperty(
"OrderedIndex", (
unsigned)0);
382 Ndb* pNdb = GETNDB(step);
389 bool logged = ctx->getProperty(
"LoggedIndexes", orderedIndex ? 0 : 1);
392 name.
assfmt(
"IND_%s_PK_%c", pTab->
getName(), orderedIndex ?
'O' :
'U');
396 ndbout <<
"Creating " << ((logged)?
"logged ":
"temporary ") <<
"ordered index "
397 << name.
c_str() <<
" (";
399 ndbout <<
"Creating " << ((logged)?
"logged ":
"temporary ") <<
"unique index "
400 << name.
c_str() <<
" (";
411 pIdx.addIndexColumn(col->
getName());
412 ndbout << col->
getName() <<
" ";
416 pIdx.setStoredIndex(logged);
419 ndbout <<
"FAILED!" << endl;
425 ndbout <<
"OK!" << endl;
430 bool orderedIndex = ctx->getProperty(
"OrderedIndex", (
unsigned)0);
432 Ndb* pNdb = GETNDB(step);
440 name.
assfmt(
"IND_%s_PK_%c", pTab->
getName(), orderedIndex ?
'O' :
'U');
442 ndbout <<
"Dropping index " << name.
c_str() <<
" ";
444 ndbout <<
"FAILED!" << endl;
448 ndbout <<
"OK!" << endl;
457 bool userDefined = ctx->getProperty(
"UserDefined", (
unsigned)0);
458 if(create_dist_table(GETNDB(step),
468 GETNDB(step)->getDictionary()->dropTable(DistTabName);
475 if (hugoTrans.loadTable(p_ndb, records, batchSize) != 0)
485 if(hugoTrans.pkUpdateRecords(p_ndb, records, batchSize) != 0)
490 if(hugoTrans.pkDelRecords(p_ndb, records, batchSize) != 0)
495 if (hugoTrans.loadTable(p_ndb, records, batchSize) != 0)
500 if(hugoTrans.scanUpdateRecords(p_ndb, records) != 0)
506 for(Uint32 j = 0; j<5; j++){
507 Uint32 parallelism = (j == 1 ? 1 : j * 3);
508 ndbout_c(
"parallelism: %d", parallelism);
526 if(hugoTrans.clearTable(p_ndb, records) != 0)
537 Ndb* p_ndb = GETNDB(step);
538 int records = ctx->getNumRecords();
547 Uint32 batchSize= ctx->getProperty(
"BatchSize", (
unsigned) 1);
549 return run_tests(p_ndb, hugoTrans, records, batchSize);
555 Ndb* p_ndb = GETNDB(step);
556 int records = ctx->getNumRecords();
563 bool orderedIndex = ctx->getProperty(
"OrderedIndex", (
unsigned)0);
566 name.
assfmt(
"IND_%s_PK_%c", pTab->
getName(), orderedIndex ?
'O' :
'U');
573 ndbout <<
"Failed to retreive index: " << name.
c_str() << endl;
576 Uint32 batchSize= ctx->getProperty(
"BatchSize", (
unsigned) 1);
580 return run_tests(p_ndb, hugoTrans, records, batchSize);
586 Ndb* p_ndb = GETNDB(step);
587 int records = ctx->getNumRecords();
595 if (hugoTrans.loadTable(p_ndb, records) != 0)
601 if(restarter.insertErrorInAllNodes(8050) != 0)
605 int result = NDBT_OK;
606 for(
int i = 0;
i<records && result == NDBT_OK;
i++)
608 char buffer[NDB_MAX_TUPLE_SIZE];
609 char* start= buffer + (rand() & 7);
619 int sz = tab->
getColumn(j)->getSizeInBytes();
621 dummy.calcValue(
i, j, 0, pos, sz, &real_size);
623 ptrs[k++].len = real_size;
624 pos += (real_size + 3) & ~3;
632 ops.setTransaction(pTrans);
633 if(ops.pkReadRecord(p_ndb,
i, 1) != NDBT_OK)
635 result = NDBT_FAILED;
639 if(ops.execute_Commit(p_ndb) != 0)
641 result = NDBT_FAILED;
645 ops.closeTransaction(p_ndb);
647 restarter.insertErrorInAllNodes(0);
654 Ndb* p_ndb = GETNDB(step);
655 int records = ctx->getNumRecords();
670 ndbout <<
"Failed to retreive index: " << name.
c_str() << endl;
675 if (hugoTrans.loadTable(p_ndb, records) != 0)
681 if(restarter.insertErrorInAllNodes(8050) != 0)
685 int result = NDBT_OK;
686 for(
int i = 0;
i<records && result == NDBT_OK;
i++)
688 char buffer[NDB_MAX_TUPLE_SIZE];
691 char* start= buffer + (rand() & 7);
701 int sz = tab->
getColumn(j)->getSizeInBytes();
703 dummy.calcValue(
i, j, 0, pos, sz, &real_size);
705 ptrs[k++].len = real_size;
706 pos += (real_size + 3) & ~3;
717 ops.setTransaction(pTrans);
729 if(ops.pkReadRecord(p_ndb,
i, 1) != NDBT_OK)
731 result = NDBT_FAILED;
735 if(ops.execute_Commit(p_ndb) != 0)
737 result = NDBT_FAILED;
741 ops.closeTransaction(p_ndb);
743 restarter.insertErrorInAllNodes(0);
747 #define CHECK(x, y) {int res= (x); \
748 if (res != 0) { ndbout << "Assert failed at " \
749 << __LINE__ << endl \
752 << (y)->getNdbError().code \
754 return NDBT_FAILED; } }
756 #define CHECKNOTNULL(x, y) { \
757 if ((x) == NULL) { ndbout << "Assert failed at line " \
758 << __LINE__ << endl \
760 << (y)->getNdbError().code \
762 return NDBT_FAILED; } }
766 load_dist_table(
Ndb* pNdb,
int records,
int parts)
770 NdbDictionary::Object::UserDefined);
773 CHECKNOTNULL(distRecord, pNdb);
775 char*
buf= (
char*) malloc(NdbDictionary::getRecordRowLength(distRecord));
777 CHECKNOTNULL(buf, pNdb);
782 for (
int r=0; r < records; r++)
785 CHECKNOTNULL(trans, pNdb);
788 const int dKeyVal= r % parts;
789 const Uint32 dKeyAttrid= tab->
getColumn(DistTabDKeyCol)->getAttrId();
790 memcpy(NdbDictionary::getValuePtr(distRecord, buf,
792 &dKeyVal,
sizeof(dKeyVal));
796 const int pKey2Val= r;
797 const Uint32 pKey2Attrid= tab->
getColumn(DistTabPKey2Col)->getAttrId();
798 memcpy(NdbDictionary::getValuePtr(distRecord, buf,
800 &pKey2Val,
sizeof(pKey2Val));
804 const int resultVal= r*r;
805 const Uint32 resultValAttrid=
806 tab->
getColumn(DistTabResultCol)->getAttrId();
807 memcpy(NdbDictionary::getValuePtr(distRecord, buf,
809 &resultVal,
sizeof(resultVal));
812 NdbDictionary::setNull(distRecord, buf, resultValAttrid,
false);
817 opts.optionsPresent= 0;
825 opts.optionsPresent= NdbOperation::OperationOptions::OO_PARTITION_ID;
829 CHECKNOTNULL(trans->insertTuple(distRecord, buf,
830 NULL, &opts,
sizeof(opts)), trans);
837 ndbout << err << endl;
838 NdbSleep_MilliSleep(50);
867 Ap(
void* _ptr) : ptr(_ptr)
880 dist_scan_body(
Ndb* pNdb,
int records,
int parts,
PartInfo* partInfo,
bool usePrimary)
884 const char* indexName= usePrimary ?
"PRIMARY" : DistIdxName;
891 NdbDictionary::Object::UserDefined);
893 char* boundBuf= (
char*) malloc(NdbDictionary::getRecordRowLength(idx->
getDefaultRecord()));
896 ndbout <<
"Checking MRR indexscan distribution awareness when distribution key part of bounds" << endl;
898 ndbout <<
"Checking MRR indexscan distribution awareness when distribution key provided explicitly" << endl;
901 ndbout <<
"User Defined Partitioning scheme" << endl;
903 ndbout <<
"Native Partitioning scheme" << endl;
905 Ap boundAp(boundBuf);
907 for (
int r=0; r < records; r++)
909 int partValue= r % parts;
910 PartInfo& pInfo= partInfo[partValue];
912 if (pInfo.trans == NULL)
918 keyParts[0].ptr= &partValue;
919 keyParts[0].len=
sizeof(partValue);
920 keyParts[1].ptr= NULL;
939 pInfo.dKeyVal= partValue;
942 opts.optionsPresent= NdbScanOperation::ScanOptions::SO_SCANFLAGS;
943 opts.scan_flags= NdbScanOperation::SF_MultiRange;
961 int dKeyVal= partValue;
964 memcpy(NdbDictionary::getValuePtr(idxRecord,
966 tab->
getColumn(DistTabDKeyCol)->getAttrId()),
969 memcpy(NdbDictionary::getValuePtr(idxRecord,
971 tab->
getColumn(DistTabPKey2Col)->getAttrId()),
978 ib.low_key= boundBuf;
980 ib.low_inclusive=
true;
981 ib.high_key= ib.low_key;
982 ib.high_key_count= ib.low_key_count;
983 ib.high_inclusive=
true;
984 ib.range_no= pInfo.valCount++;
989 pSpec.type= Ndb::PartitionSpec::PS_NONE;
994 pSpec.type= Ndb::PartitionSpec::PS_USER_DEFINED;
1006 Uint32 resultValAttrId= tab->
getColumn(DistTabResultCol)->getAttrId();
1010 memcpy(NdbDictionary::getValuePtr(idxRecord,
1017 NdbDictionary::setNull(idxRecord,
1023 ib.low_key= boundBuf;
1024 ib.low_key_count= 1;
1025 ib.low_inclusive=
true;
1026 ib.high_key= ib.low_key;
1027 ib.high_key_count= ib.low_key_count;
1028 ib.high_inclusive=
true;
1029 ib.range_no= pInfo.valCount++;
1032 keyParts[0].ptr= &partValue;
1033 keyParts[0].len=
sizeof(partValue);
1034 keyParts[1].ptr= NULL;
1047 pSpec.type= Ndb::PartitionSpec::PS_USER_DEFINED;
1058 pSpec.type= Ndb::PartitionSpec::PS_DISTR_KEY_PART_PTR;
1059 pSpec.KeyPartPtr.tableKeyParts= keyParts;
1060 pSpec.KeyPartPtr.xfrmbuf= NULL;
1061 pSpec.KeyPartPtr.xfrmbuflen= 0;
1068 tabRow= (
char*)malloc(NdbDictionary::getRecordRowLength(tabRecord));
1069 int& dKeyVal= *((
int*) NdbDictionary::getValuePtr(tabRecord,
1071 tab->
getColumn(DistTabDKeyCol)->getAttrId()));
1075 pSpec.type= Ndb::PartitionSpec::PS_DISTR_KEY_RECORD;
1076 pSpec.KeyRecord.keyRecord= tabRecord;
1077 pSpec.KeyRecord.keyRow= tabRow;
1078 pSpec.KeyRecord.xfrmbuf= 0;
1079 pSpec.KeyRecord.xfrmbuflen= 0;
1096 for (
int p=0; p < parts; p++)
1104 ndbout <<
"MRR Scan Operation should have been pruned, but was not." << endl;
1112 const char* resultPtr;
1115 while ((rc= pInfo.op->
nextResult(&resultPtr,
true,
true)) == 0)
1118 memcpy(&dKeyVal, NdbDictionary::getValuePtr(tabRecord,
1120 tab->
getColumn(DistTabDKeyCol)->getAttrId()),
1124 memcpy(&pKey2Val, NdbDictionary::getValuePtr(tabRecord,
1126 tab->
getColumn(DistTabPKey2Col)->getAttrId()),
1130 memcpy(&resultVal, NdbDictionary::getValuePtr(tabRecord,
1132 tab->
getColumn(DistTabResultCol)->getAttrId()),
1135 if ((dKeyVal != pInfo.dKeyVal) ||
1136 (resultVal != (pKey2Val * pKey2Val)))
1138 ndbout <<
"Got bad values. Dkey : " << dKeyVal
1139 <<
" Pkey2 : " << pKey2Val
1140 <<
" Result : " << resultVal
1149 ndbout <<
"Got bad scan rc " << rc << endl;
1151 ndbout <<
"Trans Error : " << pInfo.trans->
getNdbError().
code << endl;
1155 if (resultCount != pInfo.valCount)
1157 ndbout <<
"Error resultCount was " << resultCount << endl;
1161 pInfo.trans->
close();
1164 ndbout <<
"Success" << endl;
1170 dist_scan(
Ndb* pNdb,
int records,
int parts,
bool usePk)
1175 if(restarter.insertErrorInAllNodes(8050) != 0)
1181 for (
int p=0; p<parts; p++)
1183 partInfo[p].trans= NULL;
1184 partInfo[p].op= NULL;
1185 partInfo[p].dKeyVal= 0;
1186 partInfo[p].valCount= 0;
1189 int result= dist_scan_body(pNdb,
1195 restarter.insertErrorInAllNodes(0);
1204 int records= ctx->getNumRecords();
1209 int numTabPartitions= GETNDB(step)
1211 ->getTable(DistTabName)
1212 ->getFragmentCount();
1213 int numDkeyValues= 2*numTabPartitions + (rand() % 6);
1214 if (numDkeyValues > records)
1217 numDkeyValues = records;
1220 ndbout <<
"Table has " << numTabPartitions
1221 <<
" physical partitions" << endl;
1222 ndbout <<
"Testing with " << numDkeyValues
1223 <<
" discrete distribution key values " << endl;
1225 if (load_dist_table(GETNDB(step), records, numDkeyValues) != NDBT_OK)
1229 if (dist_scan(GETNDB(step), records, numDkeyValues,
true) != NDBT_OK)
1233 if (dist_scan(GETNDB(step), records, numDkeyValues,
false) != NDBT_OK)
1241 NDBT_TESTSUITE(testPartitioning);
1243 "Primary key operations with distribution key")
1245 TC_PROPERTY(
"distributionkey", ~0);
1246 INITIALIZER(run_drop_table);
1247 INITIALIZER(run_create_table);
1248 INITIALIZER(run_pk_dk);
1249 INITIALIZER(run_drop_table);
1251 TESTCASE(
"hash_index_dk",
1252 "Unique index operations with distribution key")
1254 TC_PROPERTY(
"distributionkey", ~0);
1255 TC_PROPERTY(
"OrderedIndex", (
unsigned)0);
1256 INITIALIZER(run_drop_table);
1257 INITIALIZER(run_create_table);
1258 INITIALIZER(run_create_pk_index);
1259 INITIALIZER(run_index_dk);
1260 INITIALIZER(run_create_pk_index_drop);
1261 INITIALIZER(run_drop_table);
1263 TESTCASE(
"ordered_index_dk",
1264 "Ordered index operations with distribution key")
1266 TC_PROPERTY(
"distributionkey", (
unsigned)1);
1267 TC_PROPERTY(
"OrderedIndex", (
unsigned)1);
1268 INITIALIZER(run_drop_table);
1269 INITIALIZER(run_create_table);
1270 INITIALIZER(run_create_pk_index);
1271 INITIALIZER(run_index_dk);
1272 INITIALIZER(run_create_pk_index_drop);
1273 INITIALIZER(run_drop_table);
1275 TESTCASE(
"smart_scan",
1276 "Ordered index operations with distribution key")
1278 TC_PROPERTY(
"OrderedIndex", (
unsigned)1);
1279 INITIALIZER(run_drop_table);
1280 INITIALIZER(run_create_table_smart_scan);
1281 INITIALIZER(run_create_pk_index);
1282 INITIALIZER(run_index_dk);
1283 INITIALIZER(run_create_pk_index_drop);
1284 INITIALIZER(run_drop_table);
1286 TESTCASE(
"startTransactionHint",
1287 "Test startTransactionHint wo/ distribution key")
1290 TC_PROPERTY(
"distributionkey", (
unsigned)0);
1291 INITIALIZER(run_drop_table);
1292 INITIALIZER(run_create_table);
1293 INITIALIZER(run_startHint);
1294 INITIALIZER(run_drop_table);
1296 TESTCASE(
"startTransactionHint_dk",
1297 "Test startTransactionHint with distribution key")
1300 TC_PROPERTY(
"distributionkey", (
unsigned)~0);
1301 INITIALIZER(run_drop_table);
1302 INITIALIZER(run_create_table);
1303 INITIALIZER(run_startHint);
1304 INITIALIZER(run_drop_table);
1306 TESTCASE(
"startTransactionHint_orderedIndex",
1307 "Test startTransactionHint and ordered index reads")
1310 TC_PROPERTY(
"distributionkey", (
unsigned)0);
1311 TC_PROPERTY(
"OrderedIndex", (
unsigned)1);
1312 INITIALIZER(run_drop_table);
1313 INITIALIZER(run_create_table);
1314 INITIALIZER(run_create_pk_index);
1315 INITIALIZER(run_startHint_ordered_index);
1316 INITIALIZER(run_create_pk_index_drop);
1317 INITIALIZER(run_drop_table);
1319 TESTCASE(
"startTransactionHint_orderedIndex_dk",
1320 "Test startTransactionHint and ordered index reads with distribution key")
1323 TC_PROPERTY(
"distributionkey", (
unsigned)~0);
1324 TC_PROPERTY(
"OrderedIndex", (
unsigned)1);
1325 INITIALIZER(run_drop_table);
1326 INITIALIZER(run_create_table);
1327 INITIALIZER(run_create_pk_index);
1328 INITIALIZER(run_startHint_ordered_index);
1329 INITIALIZER(run_create_pk_index_drop);
1330 INITIALIZER(run_drop_table);
1332 TESTCASE(
"startTransactionHint_orderedIndex_mrr_native",
1333 "Test hinting and MRR Ordered Index Scans for native partitioned table")
1335 TC_PROPERTY(
"UserDefined", (
unsigned)0);
1336 INITIALIZER(run_create_dist_table);
1337 INITIALIZER(run_dist_test);
1338 INITIALIZER(run_drop_dist_table);
1340 TESTCASE(
"pk_userDefined",
1341 "Test primary key operations on table with user-defined partitioning")
1344 TC_PROPERTY(
"UserDefined", (
unsigned) 1);
1345 INITIALIZER(run_drop_table);
1346 INITIALIZER(run_create_table);
1347 INITIALIZER(run_create_pk_index);
1348 INITIALIZER(run_pk_dk);
1349 INITIALIZER(run_create_pk_index_drop);
1350 INITIALIZER(run_drop_table);
1352 TESTCASE(
"hash_index_userDefined",
1353 "Unique index operations on table with user-defined partitioning")
1356 TC_PROPERTY(
"OrderedIndex", (
unsigned)0);
1357 TC_PROPERTY(
"UserDefined", (
unsigned)1);
1358 INITIALIZER(run_drop_table);
1359 INITIALIZER(run_create_table);
1360 INITIALIZER(run_create_pk_index);
1361 INITIALIZER(run_index_dk);
1362 INITIALIZER(run_create_pk_index_drop);
1363 INITIALIZER(run_drop_table);
1365 TESTCASE(
"ordered_index_userDefined",
1366 "Ordered index operations on table with user-defined partitioning")
1369 TC_PROPERTY(
"OrderedIndex", (
unsigned)1);
1370 TC_PROPERTY(
"UserDefined", (
unsigned)1);
1371 INITIALIZER(run_drop_table);
1372 INITIALIZER(run_create_table);
1373 INITIALIZER(run_create_pk_index);
1374 INITIALIZER(run_index_dk);
1375 INITIALIZER(run_create_pk_index_drop);
1376 INITIALIZER(run_drop_table);
1378 TESTCASE(
"startTransactionHint_orderedIndex_mrr_userDefined",
1379 "Test hinting and MRR Ordered Index Scans for user defined partitioned table")
1381 TC_PROPERTY(
"UserDefined", (
unsigned)1);
1382 INITIALIZER(run_create_dist_table);
1383 INITIALIZER(run_dist_test);
1384 INITIALIZER(run_drop_dist_table);
1387 NDBT_TESTSUITE_END(testPartitioning);
1389 int main(
int argc,
const char** argv){
1391 NDBT_TESTSUITE_INSTANCE(testPartitioning);
1392 testPartitioning.setCreateTable(
false);
1393 return testPartitioning.execute(argc, argv);