1 /* Copyright (c) 2003-2005 MySQL AB
3 This program is free software; you can redistribute it and/or modify
4 it under the terms of the GNU General Public License as published by
5 the Free Software Foundation; version 2 of the License.
7 This program is distributed in the hope that it will be useful,
8 but WITHOUT ANY WARRANTY; without even the implied warranty of
9 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10 GNU General Public License for more details.
12 You should have received a copy of the GNU General Public License
13 along with this program; if not, write to the Free Software
14 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */
16 #include <NDBT_Test.hpp>
17 #include <NDBT_ReturnCodes.h>
18 #include <HugoTransactions.hpp>
19 #include <UtilTransactions.hpp>
20 #include <NdbRestarter.hpp>
22 #define GETNDB(ps) ((NDBT_NdbApiStep*)ps)->getNdb()
24 static Uint32 max_dks
= 0;
28 run_drop_table(NDBT_Context
* ctx
, NDBT_Step
* step
)
30 NdbDictionary::Dictionary
* dict
= GETNDB(step
)->getDictionary();
31 dict
->dropTable(ctx
->getTab()->getName());
37 add_distribution_key(Ndb
*, NdbDictionary::Table
& tab
, int when
, void* arg
)
48 int keys
= tab
.getNoOfPrimaryKeys();
49 int dks
= (2 * keys
+ 2) / 3; dks
= (dks
> max_dks
? max_dks
: dks
);
52 for(unsigned i
= 0; i
<tab
.getNoOfColumns(); i
++)
53 if(tab
.getColumn(i
)->getPrimaryKey() &&
54 tab
.getColumn(i
)->getCharset() != 0)
57 Uint32 max
= NDB_MAX_NO_OF_ATTRIBUTES_IN_KEY
- tab
.getNoOfPrimaryKeys();
62 if(keys
<= 1 && max
> 0)
64 dks
= 1 + (rand() % max
);
65 ndbout_c("%s pks: %d dks: %d", tab
.getName(), keys
, dks
);
68 NdbDictionary::Column col
;
70 name
.assfmt("PK_DK_%d", dks
);
71 col
.setName(name
.c_str());
72 if((rand() % 100) > 50)
74 col
.setType(NdbDictionary::Column::Unsigned
);
79 col
.setType(NdbDictionary::Column::Varbinary
);
80 col
.setLength(1+(rand() % 25));
82 col
.setNullable(false);
83 col
.setPrimaryKey(true);
84 col
.setDistributionKey(true);
90 for(unsigned i
= 0; i
<tab
.getNoOfColumns(); i
++)
92 NdbDictionary::Column
* col
= tab
.getColumn(i
);
93 if(col
->getPrimaryKey() && col
->getCharset() == 0)
95 if(dks
>= keys
|| (rand() % 100) > 50)
97 col
->setDistributionKey(true);
105 Uint32 linear_hash_ind
= rand() & 1;
106 NdbDictionary::Table::FragmentType ftype
;
108 ftype
= NdbDictionary::Table::DistrKeyLin
;
110 ftype
= NdbDictionary::Table::DistrKeyHash
;
111 tab
.setFragmentType(ftype
);
113 ndbout
<< (NDBT_Table
&)tab
<< endl
;
119 run_create_table(NDBT_Context
* ctx
, NDBT_Step
* step
)
121 max_dks
= ctx
->getProperty("distributionkey", (unsigned)0);
123 if(NDBT_Tables::createTable(GETNDB(step
),
124 ctx
->getTab()->getName(),
126 max_dks
?add_distribution_key
:0) == NDBT_OK
)
131 if(GETNDB(step
)->getDictionary()->getNdbError().code
== 745)
138 run_create_pk_index(NDBT_Context
* ctx
, NDBT_Step
* step
){
139 bool orderedIndex
= ctx
->getProperty("OrderedIndex", (unsigned)0);
141 Ndb
* pNdb
= GETNDB(step
);
142 const NdbDictionary::Table
*pTab
=
143 pNdb
->getDictionary()->getTable(ctx
->getTab()->getName());
148 bool logged
= ctx
->getProperty("LoggedIndexes", orderedIndex
? 0 : 1);
151 name
.assfmt("IND_%s_PK_%c", pTab
->getName(), orderedIndex
? 'O' : 'U');
155 ndbout
<< "Creating " << ((logged
)?"logged ": "temporary ") << "ordered index "
156 << name
.c_str() << " (";
158 ndbout
<< "Creating " << ((logged
)?"logged ": "temporary ") << "unique index "
159 << name
.c_str() << " (";
161 NdbDictionary::Index
pIdx(name
.c_str());
162 pIdx
.setTable(pTab
->getName());
164 pIdx
.setType(NdbDictionary::Index::OrderedIndex
);
166 pIdx
.setType(NdbDictionary::Index::UniqueHashIndex
);
167 for (int c
= 0; c
< pTab
->getNoOfColumns(); c
++){
168 const NdbDictionary::Column
* col
= pTab
->getColumn(c
);
169 if(col
->getPrimaryKey()){
170 pIdx
.addIndexColumn(col
->getName());
171 ndbout
<< col
->getName() <<" ";
175 pIdx
.setStoredIndex(logged
);
177 if (pNdb
->getDictionary()->createIndex(pIdx
) != 0){
178 ndbout
<< "FAILED!" << endl
;
179 const NdbError err
= pNdb
->getDictionary()->getNdbError();
184 ndbout
<< "OK!" << endl
;
188 static int run_create_pk_index_drop(NDBT_Context
* ctx
, NDBT_Step
* step
){
189 bool orderedIndex
= ctx
->getProperty("OrderedIndex", (unsigned)0);
191 Ndb
* pNdb
= GETNDB(step
);
192 const NdbDictionary::Table
*pTab
=
193 pNdb
->getDictionary()->getTable(ctx
->getTab()->getName());
199 name
.assfmt("IND_%s_PK_%c", pTab
->getName(), orderedIndex
? 'O' : 'U');
201 ndbout
<< "Dropping index " << name
.c_str() << " ";
202 if (pNdb
->getDictionary()->dropIndex(name
.c_str(), pTab
->getName()) != 0){
203 ndbout
<< "FAILED!" << endl
;
204 ERR(pNdb
->getDictionary()->getNdbError());
207 ndbout
<< "OK!" << endl
;
214 run_tests(Ndb
* p_ndb
, HugoTransactions
& hugoTrans
, int records
)
216 if (hugoTrans
.loadTable(p_ndb
, records
) != 0)
221 if(hugoTrans
.pkReadRecords(p_ndb
, records
) != 0)
226 if(hugoTrans
.pkUpdateRecords(p_ndb
, records
) != 0)
231 if(hugoTrans
.pkDelRecords(p_ndb
, records
) != 0)
236 if (hugoTrans
.loadTable(p_ndb
, records
) != 0)
241 if(hugoTrans
.scanUpdateRecords(p_ndb
, records
) != 0)
247 for(Uint32 j
= 0; j
<5; j
++){
248 Uint32 parallelism
= (j
== 1 ? 1 : j
* 3);
249 ndbout_c("parallelism: %d", parallelism
);
250 if (hugoTrans
.scanReadRecords(p_ndb
, records
, abort
, parallelism
,
251 NdbOperation::LM_Read
) != 0)
255 if (hugoTrans
.scanReadRecords(p_ndb
, records
, abort
, parallelism
,
256 NdbOperation::LM_Exclusive
) != 0)
260 if (hugoTrans
.scanReadRecords(p_ndb
, records
, abort
, parallelism
,
261 NdbOperation::LM_CommittedRead
) != 0)
267 if(hugoTrans
.clearTable(p_ndb
, records
) != 0)
276 run_pk_dk(NDBT_Context
* ctx
, NDBT_Step
* step
)
278 Ndb
* p_ndb
= GETNDB(step
);
279 int records
= ctx
->getNumRecords();
280 const NdbDictionary::Table
*tab
=
281 p_ndb
->getDictionary()->getTable(ctx
->getTab()->getName());
286 HugoTransactions
hugoTrans(*tab
);
288 return run_tests(p_ndb
, hugoTrans
, records
);
292 run_index_dk(NDBT_Context
* ctx
, NDBT_Step
* step
)
294 Ndb
* p_ndb
= GETNDB(step
);
295 int records
= ctx
->getNumRecords();
296 const NdbDictionary::Table
*pTab
=
297 p_ndb
->getDictionary()->getTable(ctx
->getTab()->getName());
302 bool orderedIndex
= ctx
->getProperty("OrderedIndex", (unsigned)0);
305 name
.assfmt("IND_%s_PK_%c", pTab
->getName(), orderedIndex
? 'O' : 'U');
307 const NdbDictionary::Index
* idx
=
308 p_ndb
->getDictionary()->getIndex(name
.c_str(), pTab
->getName());
312 ndbout
<< "Failed to retreive index: " << name
.c_str() << endl
;
316 HugoTransactions
hugoTrans(*pTab
, idx
);
318 return run_tests(p_ndb
, hugoTrans
, records
);
322 run_startHint(NDBT_Context
* ctx
, NDBT_Step
* step
)
324 Ndb
* p_ndb
= GETNDB(step
);
325 int records
= ctx
->getNumRecords();
326 const NdbDictionary::Table
*tab
=
327 p_ndb
->getDictionary()->getTable(ctx
->getTab()->getName());
332 HugoTransactions
hugoTrans(*tab
);
333 if (hugoTrans
.loadTable(p_ndb
, records
) != 0)
338 NdbRestarter restarter
;
339 if(restarter
.insertErrorInAllNodes(8050) != 0)
342 HugoCalculator
dummy(*tab
);
343 int result
= NDBT_OK
;
344 for(int i
= 0; i
<records
&& result
== NDBT_OK
; i
++)
347 char* start
= buffer
+ (rand() & 7);
350 for(int j
= 0; j
<tab
->getNoOfColumns(); j
++)
352 if(tab
->getColumn(j
)->getPartitionKey())
354 ndbout_c(tab
->getColumn(j
)->getName());
355 int sz
= tab
->getColumn(j
)->getSizeInBytes();
356 int aligned_size
= 4 * ((sz
+ 3) >> 2);
357 memset(pos
, 0, aligned_size
);
359 dummy
.calcValue(i
, j
, 0, pos
, sz
, &real_size
);
360 pos
+= (real_size
+ 3) & ~3;
363 // Now we have the pk
364 NdbTransaction
* pTrans
= p_ndb
->startTransaction(tab
, start
,(pos
- start
));
365 HugoOperations
ops(*tab
);
366 ops
.setTransaction(pTrans
);
367 if(ops
.pkReadRecord(p_ndb
, i
, 1) != NDBT_OK
)
369 result
= NDBT_FAILED
;
373 if(ops
.execute_Commit(p_ndb
) != 0)
375 result
= NDBT_FAILED
;
379 ops
.closeTransaction(p_ndb
);
381 restarter
.insertErrorInAllNodes(0);
386 NDBT_TESTSUITE(testPartitioning
);
388 "Primary key operations with distribution key")
390 TC_PROPERTY("distributionkey", ~0);
391 INITIALIZER(run_drop_table
);
392 INITIALIZER(run_create_table
);
393 INITIALIZER(run_pk_dk
);
394 INITIALIZER(run_drop_table
);
396 TESTCASE("hash_index_dk",
397 "Unique index operatations with distribution key")
399 TC_PROPERTY("distributionkey", ~0);
400 TC_PROPERTY("OrderedIndex", (unsigned)0);
401 INITIALIZER(run_drop_table
);
402 INITIALIZER(run_create_table
);
403 INITIALIZER(run_create_pk_index
);
404 INITIALIZER(run_index_dk
);
405 INITIALIZER(run_create_pk_index_drop
);
406 INITIALIZER(run_drop_table
);
408 TESTCASE("ordered_index_dk",
409 "Ordered index operatations with distribution key")
411 TC_PROPERTY("distributionkey", (unsigned)1);
412 TC_PROPERTY("OrderedIndex", (unsigned)1);
413 INITIALIZER(run_drop_table
);
414 INITIALIZER(run_create_table
);
415 INITIALIZER(run_create_pk_index
);
416 INITIALIZER(run_index_dk
);
417 INITIALIZER(run_create_pk_index_drop
);
418 INITIALIZER(run_drop_table
);
420 TESTCASE("startTransactionHint",
421 "Test startTransactionHint wo/ distribution key")
423 TC_PROPERTY("distributionkey", (unsigned)0);
424 INITIALIZER(run_drop_table
);
425 INITIALIZER(run_create_table
);
426 INITIALIZER(run_startHint
);
427 INITIALIZER(run_drop_table
);
429 TESTCASE("startTransactionHint_dk",
430 "Test startTransactionHint with distribution key")
432 TC_PROPERTY("distributionkey", (unsigned)~0);
433 INITIALIZER(run_drop_table
);
434 INITIALIZER(run_create_table
);
435 INITIALIZER(run_startHint
);
436 INITIALIZER(run_drop_table
);
438 NDBT_TESTSUITE_END(testPartitioning
);
440 int main(int argc
, const char** argv
){
442 testPartitioning
.setCreateTable(false);
443 return testPartitioning
.execute(argc
, argv
);