~mdcallag/+junk/5.1-map

« back to all changes in this revision

Viewing changes to storage/ndb/test/ndbapi/testDict.cpp

  • Committer: msvensson at pilot
  • Date: 2007-04-24 09:11:45 UTC
  • mfrom: (2469.1.106)
  • Revision ID: sp1r-msvensson@pilot.blaudden-20070424091145-10463
Merge pilot.blaudden:/home/msvensson/mysql/my51-m-mysql_upgrade
into  pilot.blaudden:/home/msvensson/mysql/mysql-5.1-maint

Show diffs side-by-side

added added

removed removed

Lines of Context:
23
23
#include <../../include/kernel/ndb_limits.h>
24
24
#include <random.h>
25
25
#include <NdbAutoPtr.hpp>
 
26
#include <NdbMixRestarter.hpp>
26
27
 
27
28
#define CHECK(b) if (!(b)) { \
28
29
  g_err << "ERR: "<< step->getName() \
2110
2111
  return result;
2111
2112
}
2112
2113
 
 
2114
int
 
2115
runBug21755(NDBT_Context* ctx, NDBT_Step* step)
 
2116
{
 
2117
  char buf[256];
 
2118
  NdbRestarter res;
 
2119
  NdbDictionary::Table pTab0 = * ctx->getTab();
 
2120
  NdbDictionary::Table pTab1 = pTab0;
 
2121
 
 
2122
  if (res.getNumDbNodes() < 2)
 
2123
    return NDBT_OK;
 
2124
 
 
2125
  Ndb* pNdb = GETNDB(step);
 
2126
  NdbDictionary::Dictionary* pDic = pNdb->getDictionary();
 
2127
  
 
2128
  if (pDic->createTable(pTab0))
 
2129
  {
 
2130
    ndbout << pDic->getNdbError() << endl;
 
2131
    return NDBT_FAILED;
 
2132
  }
 
2133
 
 
2134
  NdbDictionary::Index idx0;
 
2135
  BaseString::snprintf(buf, sizeof(buf), "%s-idx", pTab0.getName());  
 
2136
  idx0.setName(buf);
 
2137
  idx0.setType(NdbDictionary::Index::OrderedIndex);
 
2138
  idx0.setTable(pTab0.getName());
 
2139
  idx0.setStoredIndex(false);
 
2140
  for (Uint32 i = 0; i<pTab0.getNoOfColumns(); i++)
 
2141
  {
 
2142
    const NdbDictionary::Column * col = pTab0.getColumn(i);
 
2143
    if(col->getPrimaryKey()){
 
2144
      idx0.addIndexColumn(col->getName());
 
2145
    }
 
2146
  }
 
2147
  
 
2148
  if (pDic->createIndex(idx0))
 
2149
  {
 
2150
    ndbout << pDic->getNdbError() << endl;
 
2151
    return NDBT_FAILED;
 
2152
  }
 
2153
  
 
2154
  BaseString::snprintf(buf, sizeof(buf), "%s-2", pTab1.getName());
 
2155
  pTab1.setName(buf);
 
2156
 
 
2157
  if (pDic->createTable(pTab1))
 
2158
  {
 
2159
    ndbout << pDic->getNdbError() << endl;
 
2160
    return NDBT_FAILED;
 
2161
  }
 
2162
 
 
2163
  {
 
2164
    HugoTransactions t0 (*pDic->getTable(pTab0.getName()));
 
2165
    t0.loadTable(pNdb, 1000);
 
2166
  }
 
2167
 
 
2168
  {
 
2169
    HugoTransactions t1 (*pDic->getTable(pTab1.getName()));
 
2170
    t1.loadTable(pNdb, 1000);
 
2171
  }
 
2172
  
 
2173
  int node = res.getRandomNotMasterNodeId(rand());
 
2174
  res.restartOneDbNode(node, false, true, true);
 
2175
  
 
2176
  if (pDic->dropTable(pTab1.getName()))
 
2177
  {
 
2178
    ndbout << pDic->getNdbError() << endl;
 
2179
    return NDBT_FAILED;
 
2180
  }
 
2181
 
 
2182
  BaseString::snprintf(buf, sizeof(buf), "%s-idx2", pTab0.getName());    
 
2183
  idx0.setName(buf);
 
2184
  if (pDic->createIndex(idx0))
 
2185
  {
 
2186
    ndbout << pDic->getNdbError() << endl;
 
2187
    return NDBT_FAILED;
 
2188
  }
 
2189
  
 
2190
  res.waitNodesNoStart(&node, 1);
 
2191
  res.startNodes(&node, 1);
 
2192
  
 
2193
  if (res.waitClusterStarted())
 
2194
  {
 
2195
    return NDBT_FAILED;
 
2196
  }
 
2197
  
 
2198
  if (pDic->dropTable(pTab0.getName()))
 
2199
  {
 
2200
    ndbout << pDic->getNdbError() << endl;
 
2201
    return NDBT_FAILED;
 
2202
  }
 
2203
  
 
2204
  return NDBT_OK;
 
2205
}
 
2206
 
 
2207
struct RandSchemaOp
 
2208
{
 
2209
  struct Obj 
 
2210
  { 
 
2211
    BaseString m_name;
 
2212
    Uint32 m_type;
 
2213
    struct Obj* m_parent;
 
2214
    Vector<Obj*> m_dependant;
 
2215
  };
 
2216
 
 
2217
  Vector<Obj*> m_objects;
 
2218
 
 
2219
  int schema_op(Ndb*);
 
2220
  int validate(Ndb*);
 
2221
  int cleanup(Ndb*);
 
2222
 
 
2223
  Obj* get_obj(Uint32 mask);
 
2224
  int create_table(Ndb*);
 
2225
  int create_index(Ndb*, Obj*);
 
2226
  int drop_obj(Ndb*, Obj*);
 
2227
 
 
2228
  void remove_obj(Obj*);
 
2229
};
 
2230
 
 
2231
template class Vector<RandSchemaOp::Obj*>;
 
2232
 
 
2233
int
 
2234
RandSchemaOp::schema_op(Ndb* ndb)
 
2235
{
 
2236
  struct Obj* obj = 0;
 
2237
  Uint32 type = 0;
 
2238
loop:
 
2239
  switch((rand() >> 16) & 3){
 
2240
  case 0:
 
2241
    return create_table(ndb);
 
2242
  case 1:
 
2243
    if ((obj = get_obj(1 << NdbDictionary::Object::UserTable)) == 0)
 
2244
      goto loop;
 
2245
    return create_index(ndb, obj);
 
2246
  case 2:
 
2247
    type = (1 << NdbDictionary::Object::UserTable);
 
2248
    goto drop_object;
 
2249
  case 3:
 
2250
    type = 
 
2251
      (1 << NdbDictionary::Object::UniqueHashIndex) |
 
2252
      (1 << NdbDictionary::Object::OrderedIndex);    
 
2253
    goto drop_object;
 
2254
  default:
 
2255
    goto loop;
 
2256
  }
 
2257
 
 
2258
drop_object:
 
2259
  if ((obj = get_obj(type)) == 0)
 
2260
    goto loop;
 
2261
  return drop_obj(ndb, obj);
 
2262
}
 
2263
 
 
2264
RandSchemaOp::Obj*
 
2265
RandSchemaOp::get_obj(Uint32 mask)
 
2266
{
 
2267
  Vector<Obj*> tmp;
 
2268
  for (Uint32 i = 0; i<m_objects.size(); i++)
 
2269
  {
 
2270
    if ((1 << m_objects[i]->m_type) & mask)
 
2271
      tmp.push_back(m_objects[i]);
 
2272
  }
 
2273
 
 
2274
  if (tmp.size())
 
2275
  {
 
2276
    return tmp[rand()%tmp.size()];
 
2277
  }
 
2278
  return 0;
 
2279
}
 
2280
 
 
2281
int
 
2282
RandSchemaOp::create_table(Ndb* ndb)
 
2283
{
 
2284
  int numTables = NDBT_Tables::getNumTables();
 
2285
  int num = myRandom48(numTables);
 
2286
  NdbDictionary::Table pTab = * NDBT_Tables::getTable(num);
 
2287
  
 
2288
  NdbDictionary::Dictionary* pDict = ndb->getDictionary();
 
2289
 
 
2290
  if (pDict->getTable(pTab.getName()))
 
2291
  {
 
2292
    char buf[100];
 
2293
    BaseString::snprintf(buf, sizeof(buf), "%s-%d", 
 
2294
                         pTab.getName(), rand());
 
2295
    pTab.setName(buf);
 
2296
    if (pDict->createTable(pTab))
 
2297
      return NDBT_FAILED;
 
2298
  }
 
2299
  else
 
2300
  {
 
2301
    if (NDBT_Tables::createTable(ndb, pTab.getName()))
 
2302
    {
 
2303
      return NDBT_FAILED;
 
2304
    }
 
2305
  }
 
2306
 
 
2307
  ndbout_c("create table %s",  pTab.getName());
 
2308
  const NdbDictionary::Table* tab2 = pDict->getTable(pTab.getName());
 
2309
  HugoTransactions trans(*tab2);
 
2310
  trans.loadTable(ndb, 1000);
 
2311
 
 
2312
  Obj *obj = new Obj;
 
2313
  obj->m_name.assign(pTab.getName());
 
2314
  obj->m_type = NdbDictionary::Object::UserTable;
 
2315
  obj->m_parent = 0;
 
2316
  m_objects.push_back(obj);
 
2317
  
 
2318
  return NDBT_OK;
 
2319
}
 
2320
 
 
2321
int
 
2322
RandSchemaOp::create_index(Ndb* ndb, Obj* tab)
 
2323
{
 
2324
  NdbDictionary::Dictionary* pDict = ndb->getDictionary();
 
2325
  const NdbDictionary::Table * pTab = pDict->getTable(tab->m_name.c_str());
 
2326
 
 
2327
  if (pTab == 0)
 
2328
  {
 
2329
    return NDBT_FAILED;
 
2330
  }
 
2331
 
 
2332
  bool ordered = (rand() >> 16) & 1;
 
2333
  bool stored = (rand() >> 16) & 1;
 
2334
 
 
2335
  Uint32 type = ordered ? 
 
2336
    NdbDictionary::Index::OrderedIndex :
 
2337
    NdbDictionary::Index::UniqueHashIndex;
 
2338
  
 
2339
  char buf[255];
 
2340
  BaseString::snprintf(buf, sizeof(buf), "%s-%s", 
 
2341
                       pTab->getName(),
 
2342
                       ordered ? "OI" : "UI");
 
2343
  
 
2344
  if (pDict->getIndex(buf, pTab->getName()))
 
2345
  {
 
2346
    // Index exists...let it be ok
 
2347
    return NDBT_OK;
 
2348
  }
 
2349
  
 
2350
  ndbout_c("create index %s", buf);
 
2351
  NdbDictionary::Index idx0;
 
2352
  idx0.setName(buf);
 
2353
  idx0.setType((NdbDictionary::Index::Type)type);
 
2354
  idx0.setTable(pTab->getName());
 
2355
  idx0.setStoredIndex(ordered ? false : stored);
 
2356
 
 
2357
  for (Uint32 i = 0; i<pTab->getNoOfColumns(); i++)
 
2358
  {
 
2359
    if (pTab->getColumn(i)->getPrimaryKey())
 
2360
      idx0.addColumn(pTab->getColumn(i)->getName());
 
2361
  }
 
2362
  if (pDict->createIndex(idx0))
 
2363
  {
 
2364
    ndbout << pDict->getNdbError() << endl;
 
2365
    return NDBT_FAILED;
 
2366
  }
 
2367
  Obj *obj = new Obj;
 
2368
  obj->m_name.assign(buf);
 
2369
  obj->m_type = type;
 
2370
  obj->m_parent = tab;
 
2371
  m_objects.push_back(obj);
 
2372
  
 
2373
  tab->m_dependant.push_back(obj);
 
2374
  return NDBT_OK;
 
2375
}
 
2376
 
 
2377
int
 
2378
RandSchemaOp::drop_obj(Ndb* ndb, Obj* obj)
 
2379
{
 
2380
  NdbDictionary::Dictionary* pDict = ndb->getDictionary();
 
2381
  
 
2382
  if (obj->m_type == NdbDictionary::Object::UserTable)
 
2383
  {
 
2384
    ndbout_c("drop table %s", obj->m_name.c_str());
 
2385
    /**
 
2386
     * Drop of table automatically drops all indexes
 
2387
     */
 
2388
    if (pDict->dropTable(obj->m_name.c_str()))
 
2389
    {
 
2390
      return NDBT_FAILED;
 
2391
    }
 
2392
    while(obj->m_dependant.size())
 
2393
    {
 
2394
      remove_obj(obj->m_dependant[0]);
 
2395
    }
 
2396
    remove_obj(obj);
 
2397
  }
 
2398
  else if (obj->m_type == NdbDictionary::Object::UniqueHashIndex ||
 
2399
           obj->m_type == NdbDictionary::Object::OrderedIndex)
 
2400
  {
 
2401
    ndbout_c("drop index %s", obj->m_name.c_str());
 
2402
    if (pDict->dropIndex(obj->m_name.c_str(),
 
2403
                         obj->m_parent->m_name.c_str()))
 
2404
    {
 
2405
      return NDBT_FAILED;
 
2406
    }
 
2407
    remove_obj(obj);
 
2408
  }
 
2409
  return NDBT_OK;
 
2410
}
 
2411
 
 
2412
void
 
2413
RandSchemaOp::remove_obj(Obj* obj)
 
2414
{
 
2415
  Uint32 i;
 
2416
  if (obj->m_parent)
 
2417
  {
 
2418
    bool found = false;
 
2419
    for (i = 0; i<obj->m_parent->m_dependant.size(); i++)
 
2420
    {
 
2421
      if (obj->m_parent->m_dependant[i] == obj)
 
2422
      {
 
2423
        found = true;
 
2424
        obj->m_parent->m_dependant.erase(i);
 
2425
        break;
 
2426
      }
 
2427
    }
 
2428
    assert(found);
 
2429
  }
 
2430
 
 
2431
  {
 
2432
    bool found = false;
 
2433
    for (i = 0; i<m_objects.size(); i++)
 
2434
    {
 
2435
      if (m_objects[i] == obj)
 
2436
      {
 
2437
        found = true;
 
2438
        m_objects.erase(i);
 
2439
        break;
 
2440
      }
 
2441
    }
 
2442
    assert(found);
 
2443
  }
 
2444
  delete obj;
 
2445
}
 
2446
 
 
2447
int
 
2448
RandSchemaOp::validate(Ndb* ndb)
 
2449
{
 
2450
  NdbDictionary::Dictionary* pDict = ndb->getDictionary();
 
2451
  for (Uint32 i = 0; i<m_objects.size(); i++)
 
2452
  {
 
2453
    if (m_objects[i]->m_type == NdbDictionary::Object::UserTable)
 
2454
    {
 
2455
      const NdbDictionary::Table* tab2 = 
 
2456
        pDict->getTable(m_objects[i]->m_name.c_str());
 
2457
      HugoTransactions trans(*tab2);
 
2458
      trans.scanUpdateRecords(ndb, 1000);
 
2459
      trans.clearTable(ndb);
 
2460
      trans.loadTable(ndb, 1000);
 
2461
    }
 
2462
  }
 
2463
  
 
2464
  return NDBT_OK;
 
2465
}
 
2466
 
 
2467
/*
 
2468
      SystemTable = 1,        ///< System table
 
2469
      UserTable = 2,          ///< User table (may be temporary)
 
2470
      UniqueHashIndex = 3,    ///< Unique un-ordered hash index
 
2471
      OrderedIndex = 6,       ///< Non-unique ordered index
 
2472
      HashIndexTrigger = 7,   ///< Index maintenance, internal
 
2473
      IndexTrigger = 8,       ///< Index maintenance, internal
 
2474
      SubscriptionTrigger = 9,///< Backup or replication, internal
 
2475
      ReadOnlyConstraint = 10,///< Trigger, internal
 
2476
      Tablespace = 20,        ///< Tablespace
 
2477
      LogfileGroup = 21,      ///< Logfile group
 
2478
      Datafile = 22,          ///< Datafile
 
2479
      Undofile = 23           ///< Undofile
 
2480
*/
 
2481
 
 
2482
int
 
2483
RandSchemaOp::cleanup(Ndb* ndb)
 
2484
{
 
2485
  Int32 i;
 
2486
  for (i = m_objects.size() - 1; i >= 0; i--)
 
2487
  {
 
2488
    switch(m_objects[i]->m_type){
 
2489
    case NdbDictionary::Object::UniqueHashIndex:
 
2490
    case NdbDictionary::Object::OrderedIndex:        
 
2491
      if (drop_obj(ndb, m_objects[i]))
 
2492
        return NDBT_FAILED;
 
2493
      
 
2494
      break;
 
2495
    default:
 
2496
      break;
 
2497
    }
 
2498
  }
 
2499
 
 
2500
  for (i = m_objects.size() - 1; i >= 0; i--)
 
2501
  {
 
2502
    switch(m_objects[i]->m_type){
 
2503
    case NdbDictionary::Object::UserTable:
 
2504
      if (drop_obj(ndb, m_objects[i]))
 
2505
        return NDBT_FAILED;
 
2506
      break;
 
2507
    default:
 
2508
      break;
 
2509
    }
 
2510
  }
 
2511
  
 
2512
  assert(m_objects.size() == 0);
 
2513
  return NDBT_OK;
 
2514
}
 
2515
 
 
2516
int
 
2517
runDictRestart(NDBT_Context* ctx, NDBT_Step* step)
 
2518
{
 
2519
  Ndb* pNdb = GETNDB(step);
 
2520
  int loops = ctx->getNumLoops();
 
2521
 
 
2522
  NdbMixRestarter res;
 
2523
  
 
2524
  RandSchemaOp dict;
 
2525
  if (res.getNumDbNodes() < 2)
 
2526
    return NDBT_OK;
 
2527
 
 
2528
  if (res.init(ctx, step))
 
2529
    return NDBT_FAILED;
 
2530
  
 
2531
  for (Uint32 i = 0; i<loops; i++)
 
2532
  {
 
2533
    for (Uint32 j = 0; j<10; j++)
 
2534
      if (dict.schema_op(pNdb))
 
2535
        return NDBT_FAILED;
 
2536
    
 
2537
    if (res.dostep(ctx, step))
 
2538
      return NDBT_FAILED;
 
2539
 
 
2540
    if (dict.validate(pNdb))
 
2541
      return NDBT_FAILED;
 
2542
  }
 
2543
 
 
2544
  if (res.finish(ctx, step))
 
2545
    return NDBT_FAILED;
 
2546
 
 
2547
  if (dict.validate(pNdb))
 
2548
    return NDBT_FAILED;
 
2549
  
 
2550
  if (dict.cleanup(pNdb))
 
2551
    return NDBT_FAILED;
 
2552
  
 
2553
  return NDBT_OK;
 
2554
}
 
2555
 
2113
2556
NDBT_TESTSUITE(testDict);
2114
2557
TESTCASE("CreateAndDrop", 
2115
2558
         "Try to create and drop the table loop number of times\n"){
2256
2699
  STEP(runRestarts);
2257
2700
  STEP(runDictOps);
2258
2701
}
2259
 
 
 
2702
TESTCASE("Bug21755",
 
2703
         ""){
 
2704
  INITIALIZER(runBug21755);
 
2705
}
 
2706
TESTCASE("DictRestart",
 
2707
         ""){
 
2708
  INITIALIZER(runDictRestart);
 
2709
}
2260
2710
NDBT_TESTSUITE_END(testDict);
2261
2711
 
2262
2712
int main(int argc, const char** argv){