Пример #1
0
static int
doall()
{
  int ret = 0;
  do
  {
    CHK2(doconnect() == 0, "connect to NDB");

    int loop = 0;
    while (++loop <= _loops)
    {
      g_info << "loop " << loop << " of " << _loops << endl;
      if (!_sys_any)
      {
        if (loop == 1)
        {
          CHK1(checkobjs() == 0);
        }
        CHK2(dostats() == 0, "at loop " << loop);
      }
      else
      {
        CHK2(dosys() == 0, "at loop " << loop);
      }
    }
    CHK1(ret == 0);
  }
  while (0);

  dodisconnect();
  return ret;
}
int
Ndb_move_data::copy_array_to_array(const Attr& attr1, const Attr& attr2)
{
  int ret = 0;
  Op& op = m_op;
  const int i1 = attr1.id;
  do
  {
    const NdbRecAttr* ra1 = op.values[i1].ra;
    require(ra1 != 0 && ra1->isNULL() != -1);

    if (ra1->isNULL())
    {
      const char* data1 = 0;
      CHK1(copy_data_to_array(data1, attr2, 0, 0) == 0);
    }
    else
    {
      Uint32 size1 = ra1->get_size_in_bytes();
      require(size1 >= attr1.length_bytes);
      Uint32 length1 = size1 - attr1.length_bytes;

      const char* aref1 = ra1->aRef();
      const char* data1 = &aref1[attr1.length_bytes];
      if (attr1.length_bytes == 0)
        while (length1 != 0 && data1[length1-1] == attr1.pad_char)
          length1--;
      CHK1(copy_data_to_array(data1, attr2, length1, length1) == 0);
    }
  }
  while (0);
  return ret;
}
int
Ndb_move_data::move_batch()
{
  int ret = 0;
  Op& op = m_op;
  op.rows_in_batch = 0;
  op.truncated_in_batch = 0;
  do
  {
    int res;
    CHK2((res = op.scanop->nextResult(true)) != -1,
         (op.scanop->getNdbError()));
    require(res == 0 || res == 1);
    if (res == 1)
    {
      op.end_of_scan = true;
      op.ndb->closeTransaction(op.scantrans);
      op.scantrans = 0;
      break;
    }

    require(op.updatetrans == 0);
    op.updatetrans = op.ndb->startTransaction();
    CHK2(op.updatetrans != 0, (op.ndb->getNdbError()));

    do
    {
      CHK1(move_row() == 0);
      op.rows_in_batch++;
      CHK2((res = op.scanop->nextResult(false)) != -1,
           (op.scanop->getNdbError()));
      require(res == 0 || res == 2);
    }
    while (res == 0);
    CHK1(ret == 0);

    if (m_error_insert && ndb_rand() % 5 == 0)
    {
      invoke_error_insert();
      CHK1(false);
    }

    CHK2(op.updatetrans->execute(NdbTransaction::Commit) == 0,
         (op.updatetrans->getNdbError()));
    op.ndb->closeTransaction(op.updatetrans);
    op.updatetrans = 0;
  }
  while (0);
  release_data();
  return ret;
}
Пример #4
0
static int
dostats()
{
  int ret = 0;
  do
  {
    for (int i = 0; i < g_indcount; i++)
    {
      CHK1(dostats(i) == 0);
    }
    CHK1(ret == 0);
  }
  while (0);
  return ret;
}
Пример #5
0
static int
scanblobstart(const Blob& b)
{
  int ret = 0;

  do
  {
    assert(g_scantx == 0);
    g_scantx = g_ndb->startTransaction();
    CHK2(g_scantx != 0, g_ndb->getNdbError());

    g_scanop = g_scantx->getNdbScanOperation(b.blobtab);
    CHK2(g_scanop != 0, g_scantx->getNdbError());

    const NdbOperation::LockMode lm = NdbOperation::LM_Exclusive;
    CHK2(g_scanop->readTuples(lm) == 0, g_scanop->getNdbError());

    for (int i = 0; i < g_valcount; i++)
    {
      Val& v = g_vallist[i];
      v.ra = g_scanop->getValue(v.colname);
      CHK2(v.ra != 0, v.colname << ": " << g_scanop->getNdbError());
    }
    CHK1(ret == 0);

    CHK2(g_scantx->execute(NoCommit) == 0, g_scantx->getNdbError());
  }
  while (0);

  return ret;
}
Пример #6
0
static int
doall()
{
  int ret = 0;
  do
  {
    if (opt_dump_file)
    {
      g_dump_file = fopen(opt_dump_file, "w");
      CHK2(g_dump_file != 0, opt_dump_file << ": " << strerror(errno));
      g_dump_out = new FileOutputStream(g_dump_file);
      new (&g_dump) NdbOut(*g_dump_out);

      const char* action = 0;
      if (opt_check_orphans)
        action = "check";
      if (opt_delete_orphans)
        action = "delete";

      g_dump << "table: " << g_tabname << endl;
      g_dump << "action: " << action << endl;
    }
    CHK1(doconnect() == 0);
    CHK1(getobjs() == 0);
    if (g_blobcount == 0)
    {
      g_err << g_tabname << ": no blob columns" << endl;
      break;
    }
    CHK1(doorphans() == 0);
  }
  while (0);

  dodisconnect();
  if (g_dump_file != 0)
  {
    g_dump << "result: "<< (ret == 0 ? "ok" : "failed") << endl;
    flush(g_dump);
    if (fclose(g_dump_file) != 0)
    {
      g_err << opt_dump_file << ": write failed: " << strerror(errno) << endl;
    }
    g_dump_file = 0;
  }
  return ret;
}
int
Ndb_move_data::check_sizes(const Attr& attr1, const Attr& attr2)
{
  int ret = 0;
  do
  {
    if (attr1.data_size < attr2.data_size)
    {
      CHK1(check_promotion(attr1, attr2) == 0);
    }
    if (attr1.data_size > attr2.data_size)
    {
      CHK1(check_demotion(attr1, attr2) == 0);
    }
  }
  while (0);
  return ret;
}
int
Ndb_move_data::copy_attr(const Attr& attr1, const Attr& attr2)
{
  int ret = 0;
  require(attr1.map_id == attr2.id);
  do
  {
    if (attr1.equal && attr1.type != Attr::TypeBlob)
    {
      require(attr2.equal && attr2.type != Attr::TypeBlob);
      CHK1(copy_other_to_other(attr1, attr2) == 0);
      break;
    }
    if (attr1.type == Attr::TypeArray &&
        attr2.type == Attr::TypeArray)
    {
      CHK1(copy_array_to_array(attr1, attr2) == 0);
      break;
    }
    if (attr1.type == Attr::TypeArray &&
        attr2.type == Attr::TypeBlob)
    {
      CHK1(copy_array_to_blob(attr1, attr2) == 0);
      break;
    }
    if (attr1.type == Attr::TypeBlob &&
        attr2.type == Attr::TypeArray)
    {
      CHK1(copy_blob_to_array(attr1, attr2) == 0);
      break;
    }
    if (attr1.type == Attr::TypeBlob &&
        attr2.type == Attr::TypeBlob)
    {
      CHK1(copy_blob_to_blob(attr1, attr2) == 0);
      break;
    }
    require(false);
  }
  while (0);
  return ret;
}
Пример #9
0
static int
checkorphan(const Blob&b, int& res)
{
  int ret = 0;

  NdbTransaction* tx = 0;
  NdbOperation* op = 0;

  do
  {
    tx = g_ndb->startTransaction();
    CHK2(tx != 0, g_ndb->getNdbError());

    op = tx->getNdbOperation(g_tab);
    CHK2(op != 0, tx->getNdbError());

    const NdbOperation::LockMode lm = NdbOperation::LM_Read;
    CHK2(op->readTuple(lm) == 0, op->getNdbError());

    for (int i = 0; i < g_pkcount; i++)
    {
      Val& v = g_vallist[i];
      assert(v.ra != 0);
      assert(v.ra->isNULL() == 0);
      const char* data = v.ra->aRef();
      CHK2(op->equal(v.colname, data) == 0, op->getNdbError());
    }
    CHK1(ret == 0);

    // read something to be safe
    NdbRecAttr* ra0 = op->getValue(g_vallist[0].colname);
    assert(ra0 != 0);

    // not sure about the rules
    assert(tx->getNdbError().code == 0);
    tx->execute(Commit);
    if (tx->getNdbError().code == 626)
    {
      g_info << "parent not found" << endl;
      res = 1; // not found
    }
    else
    {
      CHK2(tx->getNdbError().code == 0, tx->getNdbError());
      res = 0; // found
    }
  }
  while (0);

  if (tx != 0)
    g_ndb->closeTransaction(tx);
  return ret;
}
Пример #10
0
static int
doorphans()
{
  int ret = 0;
  g_err << "processing " << g_blobcount << " blobs" << endl;
  for (int i = 0; i < g_blobcount; i++)
  {
    const Blob& b = g_bloblist[i];
    CHK1(doorphan(b) == 0);
  }
  return ret;
}
int
Ndb_move_data::move_row()
{
  int ret = 0;
  Op& op = m_op;
  const int attrcount1 = m_source->getNoOfColumns();
  do
  {
    op.updateop = op.updatetrans->getNdbOperation(m_target);
    CHK2(op.updateop != 0, (op.updatetrans->getNdbError()));
    CHK2(op.updateop->insertTuple() == 0, (op.updateop->getNdbError()));

    for (int j = 0; j <= 1; j++)
    {
      for (int i1 = 0; i1 < attrcount1; i1++)
      {
        const Attr& attr1 = m_sourceattr[i1];
        int i2 = attr1.map_id;
        if (unlikely(i2 == -1))
          continue;
        const Attr& attr2 = m_targetattr[i2];
        const NdbDictionary::Column* c = attr2.column;
        if (j == 0 && !c->getPrimaryKey())
          continue;
        if (j == 1 && c->getPrimaryKey())
          continue;
        CHK1(copy_attr(attr1, attr2) == 0);
      }
      CHK1(ret == 0);
    }
    CHK1(ret == 0);

    CHK2(op.scanop->deleteCurrentTuple(op.updatetrans) == 0,
         (op.scanop->getNdbError()));
  }
  while (0);
  return ret;
}
int
Ndb_move_data::move_data(Ndb* ndb)
{
  int ret = 0;
  Op& op = m_op;
  Stat& stat = m_stat;
  stat.rows_moved = 0; // keep rows_total
  do
  {
    const NDB_TICKS now = NdbTick_getCurrentTicks(); 
    ndb_srand((unsigned)now.getUint64());
    reset_error();

    CHK2(m_source != 0 && m_target != 0,
        (Error::InvalidState, "source / target not defined"));

    op.ndb = ndb;
    CHK1(m_error.code == 0);
    CHK1(check_tables() == 0);
    CHK1(start_scan() == 0);
    while (1)
    {
      CHK1(move_batch() == 0);
      stat.rows_moved += op.rows_in_batch;
      stat.rows_total += op.rows_in_batch;
      stat.truncated += op.truncated_in_batch;

      require(op.end_of_scan == (op.rows_in_batch == 0));
      if (op.end_of_scan)
        break;
    }
    CHK1(ret == 0);
  }
  while (0);
  close_op(ndb, ret);
  return ret;
}
Пример #13
0
static int
checkopts(int argc, char** argv)
{
  int ret = 0;
  do
  {
    _stats_any =
      (_dbname != 0) +
      (_delete != 0) +
      (_update != 0) +
      (_dump != 0) +
      (_query != 0);
    _sys_any =
      (_sys_create != 0) +
      (_sys_create_if_not_exist != 0) +
      (_sys_create_if_not_valid != 0) +
      (_sys_drop != 0) +
      ( _sys_check != 0) +
      (_sys_skip_tables != 0) +
      (_sys_skip_events != 0);
    if (!_sys_any)
    {
      if (_dbname == 0)
        _dbname = "TEST_DB";
      CHK2(argc >= 1, "stats options require table");
      g_tabname = strdup(argv[0]);
      CHK2(g_tabname != 0, "out of memory");
      g_indcount = argc - 1;
      if (g_indcount != 0)
      {
        g_indnames = (const char**)malloc(sizeof(char*) * g_indcount);
        CHK2(g_indnames != 0, "out of memory");
        for (int i = 0; i < g_indcount; i++)
        {
          g_indnames[i] = strdup(argv[1 + i]);
          CHK2(g_indnames[i] != 0, "out of memory");
        }
        CHK1(ret == 0);
      }
    }
    else
    {
      CHK2(_stats_any == 0, "cannot mix --sys options with stats options");
      CHK2(argc == 0, "--sys options take no args");
    }
  }
  while (0);
  return ret;
}
int
Ndb_move_data::copy_blob_to_array(const Attr& attr1, const Attr& attr2)
{
  int ret = 0;
  Op& op = m_op;
  const int i1 = attr1.id;
  do
  {
    NdbBlob* bh1 = op.values[i1].bh;
    require(bh1 != 0);

    int isNull = -1;
    CHK2(bh1->getNull(isNull) == 0, (bh1->getNdbError()));
    require(isNull == 0 || isNull == 1);
    Uint64 length64 = ~(Uint64)0;
    CHK2(bh1->getLength(length64) == 0, (bh1->getNdbError()));
    Uint32 data_length = (Uint32)length64;
    require((uint64)data_length == length64);

    if (isNull)
    {
      const char* data1 = 0;
      CHK1(copy_data_to_array(data1, attr2, 0, 0) == 0);
    }
    else
    {
      char* data1 = &op.buf1[0];
      Uint32 length1 = attr2.data_size;
      CHK2(bh1->readData(data1, length1) == 0, (bh1->getNdbError()));
      // pass also real length to detect truncation
      CHK1(copy_data_to_array(data1, attr2, length1, data_length) == 0);
    }
  }
  while (0);
  return ret;
}
int
Ndb_move_data::start_scan()
{
  int ret = 0;
  Op& op = m_op;
  const int attrcount1 = m_source->getNoOfColumns();
  do
  {
    require(op.scantrans == 0);
    op.scantrans = op.ndb->startTransaction(m_source);
    CHK2(op.scantrans != 0, (op.ndb->getNdbError()));

    op.scanop = op.scantrans->getNdbScanOperation(m_source);
    CHK2(op.scanop != 0, (op.scantrans->getNdbError()));

    NdbOperation::LockMode lm = NdbOperation::LM_Exclusive;
    Uint32 flags = 0;
    CHK2(op.scanop->readTuples(lm, flags) == 0, (op.scanop->getNdbError()));

    require(op.values == 0);
    op.values = new Op::Value [attrcount1];

    for (int i1 = 0; i1 < attrcount1; i1++)
    {
      const Attr& attr1 = m_sourceattr[i1];

      if (attr1.type != Attr::TypeBlob)
      {
        NdbRecAttr* ra = op.scanop->getValue(i1);
        CHK2(ra != 0, (op.scanop->getNdbError()));
        op.values[i1].ra = ra;
      }
      else
      {
        NdbBlob* bh = op.scanop->getBlobHandle(i1);
        CHK2(bh != 0, (op.scanop->getNdbError()));
        op.values[i1].bh = bh;
      }
    }
    CHK1(ret == 0);

    CHK2(op.scantrans->execute(NdbTransaction::NoCommit) == 0,
         (op.scantrans->getNdbError()));
  }
  while (0);
  return ret;
}
Пример #16
0
static int
checkobjs()
{
  int ret = 0;
  do
  {
    CHK2((g_tab = g_dic->getTable(g_tabname)) != 0,
          g_tabname << ": " << g_dic->getNdbError());

    if (g_indcount == 0)
    {
      NdbDictionary::Dictionary::List list;
      CHK2(g_dic->listIndexes(list, g_tabname) == 0, g_dic->getNdbError());
      const int count = list.count;
      g_indnames = (const char**)malloc(sizeof(char*) * count);
      CHK2(g_indnames != 0, "out of memory");
      for (int i = 0; i < count; i++)
      {
        const NdbDictionary::Dictionary::List::Element& e = list.elements[i];
        if (e.type == NdbDictionary::Object::OrderedIndex)
        {
          g_indnames[g_indcount] = strdup(e.name);
          CHK2(g_indnames[g_indcount] != 0, "out of memory");
          g_indcount++;
        }
      }
      CHK1(ret == 0);
    }
    g_indlist = (const NdbDictionary::Index**)malloc(sizeof(NdbDictionary::Index*) * g_indcount);
    CHK2(g_indlist != 0, "out of memory");
    for (int i = 0; i < g_indcount; i++)
    {
      CHK2((g_indlist[i] = g_dic->getIndex(g_indnames[i], g_tabname)) != 0,
            g_tabname << "." << g_indnames[i] << ": " << g_dic->getNdbError());
    }
  }
  while (0);
  return ret;
}
Пример #17
0
static int
doorphan(const Blob& b)
{
  int ret = 0;
  do
  {
    g_err << "processing blob #" << b.blobno << " " << b.colname
          << " " << b.blobname << endl;

    if (opt_dump_file)
    {
      g_dump << "column: " << b.colname << endl;
      g_dump << "blob: " << b.blobname << endl;
      g_dump << "orphans (table key; blob part number):" << endl;
    }

    int totcount = 0;
    int orphancount = 0;

    CHK1(scanblobstart(b) == 0);
    while (1)
    {
      int res;
      res = -1;
      CHK1(scanblobnext(b, res) == 0);
      if (res != 0)
        break;
      totcount++;
      res = -1;
      CHK1(checkorphan(b, res) == 0);
      if (res != 0)
      {
        orphancount++;
        if (opt_dump_file)
        {
          g_dump << "key: ";
          for (int i = 0; i < g_valcount; i++)
          {
            const Val& v = g_vallist[i];
            g_dump << *v.ra;
            if (i + 1 < g_valcount)
              g_dump << ";";
          }
          g_dump << endl;
        }
        if (opt_delete_orphans)
        {
          CHK1(deleteorphan(b) == 0);
        }
      }
    }
    CHK1(ret == 0);

    g_err << "total parts: " << totcount << endl;
    g_err << "orphan parts: " << orphancount << endl;
    if (opt_dump_file)
    {
      g_dump << "total parts: " << totcount << endl;
      g_dump << "orphan parts: " << orphancount << endl;
    }
  }
  while (0);

  scanblobclose(b);
  return ret;
}
Пример #18
0
static int
getobjs()
{
  int ret = 0;
  do
  {
    g_tab = g_dic->getTable(g_tabname);
    CHK2(g_tab != 0, g_tabname << ": " << g_dic->getNdbError());
    const int tabid = g_tab->getObjectId();
    const int ncol = g_tab->getNoOfColumns();

    g_pklist = new Pk [NDB_MAX_NO_OF_ATTRIBUTES_IN_KEY];
    for (int i = 0; i < ncol; i++)
    {
      const NdbDictionary::Column* c = g_tab->getColumn(i);
      if (c->getPrimaryKey())
      {
        Pk& p = g_pklist[g_pkcount++];
        const char* colname = c->getName();
        p.colname = newstr(colname);
      }
    }
    assert(g_pkcount != 0 && g_pkcount == g_tab->getNoOfPrimaryKeys());

    g_valcount = g_pkcount + 1;
    g_vallist = new Val [g_valcount];
    for (int i = 0; i < g_valcount; i++)
    {
      Val& v = g_vallist[i];
      if (i < g_pkcount)
      {
        const Pk& p = g_pklist[i];
        v.colname = newstr(p.colname);
      }
      if (i == g_pkcount + 0) // first blob attr to scan
      {
        v.colname = newstr("NDB$PART");
      }
    }

    if (g_blobcount == 0)
    {
      for (int i = 0; i < ncol; i++)
      {
        const NdbDictionary::Column* c = g_tab->getColumn(i);
        if (isblob(c))
        {
          Blob& b = g_bloblist[g_blobcount++];
          const char* colname = c->getName();
          b.colname = newstr(colname);
        }
      }
    }

    for (int i = 0; i < g_blobcount; i++)
    {
      Blob& b = g_bloblist[i];
      b.blobno = i;
      const NdbDictionary::Column* c = g_tab->getColumn(b.colname);
      CHK2(c != 0, g_tabname << ": " << b.colname << ": no such column");
      CHK2(isblob(c), g_tabname << ": " << b.colname << ": not a blob");
      b.colno = c->getColumnNo();
      {
        char blobname[100];
        sprintf(blobname, "NDB$BLOB_%d_%d", tabid, b.colno);
        b.blobname = newstr(blobname);
      }
      b.blobtab = g_dic->getTable(b.blobname);
      CHK2(b.blobtab != 0, g_tabname << ": " << b.colname << ": " << b.blobname << ": " << g_dic->getNdbError());
    }
    CHK1(ret == 0);
  }
  while (0);
  return ret;
}
Пример #19
0
/* Test various atomic.h macros.  */
static int
do_test (void)
{
  atomic_t mem, expected, retval;
  int ret = 0;

#ifdef atomic_compare_and_exchange_val_acq
  mem = 24;
  CHK2(atomic_compare_and_exchange_val_acq, 35, 24, 24, 35);
  mem = 12;
  CHK2(atomic_compare_and_exchange_val_acq, 10, 15, 12, 12);
  mem = -15;
  CHK2(atomic_compare_and_exchange_val_acq, -56, -15, -15, -56);
  mem = -1;
  CHK2(atomic_compare_and_exchange_val_acq, 17, 0, -1, -1);
#endif

  mem = 24;
  CHK2(atomic_compare_and_exchange_bool_acq, 35, 24, 0, 35);
  mem = 12;
  CHK2(atomic_compare_and_exchange_bool_acq, 10, 15, 1, 12);
  mem = -15;
  CHK2(atomic_compare_and_exchange_bool_acq, -56, -15, 0, -56);
  mem = -1;
  CHK2(atomic_compare_and_exchange_bool_acq, 17, 0, 1, -1);

  mem = 64;
  CHK1(atomic_exchange_acq, 31, 64, 31);
  mem = 2;
  CHK1(atomic_exchange_and_add, 11, 2, 13);
  mem = 2;
  CHK1(atomic_exchange_and_add_acq, 11, 2, 13);
  mem = 2;
  CHK1(atomic_exchange_and_add_rel, 11, 2, 13);

  mem = -21;
  atomic_add (&mem, 22);
  if (mem != 1)
    {
      printf ("atomic_add(mem, 22):    mem %lu != expected 1\n", mem);
      ret = 1;
    }

  mem = -1;
  atomic_increment (&mem);
  if (mem != 0)
    {
      printf ("atomic_increment(mem):    mem %lu != expected 0\n", mem);
      ret = 1;
    }

  mem = 2;
  if ((retval = atomic_increment_val (&mem)) != 3)
    {
      printf ("atomic_increment_val(mem): retval %lu != expected 3\n", retval);
      ret = 1;
    }

  mem = 0;
  CHK0(atomic_increment_and_test, 0, 1);
  mem = 35;
  CHK0(atomic_increment_and_test, 0, 36);
  mem = -1;
  CHK0(atomic_increment_and_test, 1, 0);
  mem = 17;
  atomic_decrement (&mem);
  if (mem != 16)
    {
      printf ("atomic_increment(mem):    mem %lu != expected 16\n", mem);
      ret = 1;
    }

  if ((retval = atomic_decrement_val (&mem)) != 15)
    {
      printf ("atomic_decrement_val(mem): retval %lu != expected 15\n", retval);
      ret = 1;
    }

  mem = 0;
  CHK0(atomic_decrement_and_test, 0, -1);

  mem = 15;
  CHK0(atomic_decrement_and_test, 0, 14);
  mem = 1;
  CHK0(atomic_decrement_and_test, 1, 0);
  mem = 1;
  if (atomic_decrement_if_positive (&mem) != 1
      || mem != 0)
    {
      puts ("atomic_decrement_if_positive test 1 failed");
      ret = 1;
    }

  mem = 0;
  if (atomic_decrement_if_positive (&mem) != 0
      || mem != 0)
    {
      puts ("atomic_decrement_if_positive test 2 failed");
      ret = 1;
    }

  mem = -1;
  if (atomic_decrement_if_positive (&mem) != -1
      || mem != -1)
    {
      puts ("atomic_decrement_if_positive test 3 failed");
      ret = 1;
    }

  mem = -12;
  if (! atomic_add_negative (&mem, 10)
      || mem != -2)
    {
      puts ("atomic_add_negative test 1 failed");
      ret = 1;
    }

  mem = 0;
  if (atomic_add_negative (&mem, 100)
      || mem != 100)
    {
      puts ("atomic_add_negative test 2 failed");
      ret = 1;
    }

  mem = 15;
  if (atomic_add_negative (&mem, -10)
      || mem != 5)
    {
      puts ("atomic_add_negative test 3 failed");
      ret = 1;
    }

  mem = -12;
  if (atomic_add_negative (&mem, 14)
      || mem != 2)
    {
      puts ("atomic_add_negative test 4 failed");
      ret = 1;
    }

  mem = 0;
  if (! atomic_add_negative (&mem, -1)
      || mem != -1)
    {
      puts ("atomic_add_negative test 5 failed");
      ret = 1;
    }

  mem = -31;
  if (atomic_add_negative (&mem, 31)
      || mem != 0)
    {
      puts ("atomic_add_negative test 6 failed");
      ret = 1;
    }

  mem = -34;
  if (atomic_add_zero (&mem, 31)
      || mem != -3)
    {
      puts ("atomic_add_zero test 1 failed");
      ret = 1;
    }

  mem = -36;
  if (! atomic_add_zero (&mem, 36)
      || mem != 0)
    {
      puts ("atomic_add_zero test 2 failed");
      ret = 1;
    }

  mem = 113;
  if (atomic_add_zero (&mem, -13)
      || mem != 100)
    {
      puts ("atomic_add_zero test 3 failed");
      ret = 1;
    }

  mem = -18;
  if (atomic_add_zero (&mem, 20)
      || mem != 2)
    {
      puts ("atomic_add_zero test 4 failed");
      ret = 1;
    }

  mem = 10;
  if (atomic_add_zero (&mem, -20)
      || mem != -10)
    {
      puts ("atomic_add_zero test 5 failed");
      ret = 1;
    }

  mem = 10;
  if (! atomic_add_zero (&mem, -10)
      || mem != 0)
    {
      puts ("atomic_add_zero test 6 failed");
      ret = 1;
    }

  mem = 0;
  atomic_bit_set (&mem, 1);
  if (mem != 2)
    {
      puts ("atomic_bit_set test 1 failed");
      ret = 1;
    }

  mem = 8;
  atomic_bit_set (&mem, 3);
  if (mem != 8)
    {
      puts ("atomic_bit_set test 2 failed");
      ret = 1;
    }

#ifdef TEST_ATOMIC64
  mem = 16;
  atomic_bit_set (&mem, 35);
  if (mem != 0x800000010LL)
    {
      puts ("atomic_bit_set test 3 failed");
      ret = 1;
    }
#endif

  mem = 0;
  if (atomic_bit_test_set (&mem, 1)
      || mem != 2)
    {
      puts ("atomic_bit_test_set test 1 failed");
      ret = 1;
    }

  mem = 8;
  if (! atomic_bit_test_set (&mem, 3)
      || mem != 8)
    {
      puts ("atomic_bit_test_set test 2 failed");
      ret = 1;
    }

#ifdef TEST_ATOMIC64
  mem = 16;
  if (atomic_bit_test_set (&mem, 35)
      || mem != 0x800000010LL)
    {
      puts ("atomic_bit_test_set test 3 failed");
      ret = 1;
    }

  mem = 0x100000000LL;
  if (! atomic_bit_test_set (&mem, 32)
      || mem != 0x100000000LL)
    {
      puts ("atomic_bit_test_set test 4 failed");
      ret = 1;
    }
#endif

#ifdef catomic_compare_and_exchange_val_acq
  mem = 24;
  if (catomic_compare_and_exchange_val_acq (&mem, 35, 24) != 24
      || mem != 35)
    {
      puts ("catomic_compare_and_exchange_val_acq test 1 failed");
      ret = 1;
    }

  mem = 12;
  if (catomic_compare_and_exchange_val_acq (&mem, 10, 15) != 12
      || mem != 12)
    {
      puts ("catomic_compare_and_exchange_val_acq test 2 failed");
      ret = 1;
    }

  mem = -15;
  if (catomic_compare_and_exchange_val_acq (&mem, -56, -15) != -15
      || mem != -56)
    {
      puts ("catomic_compare_and_exchange_val_acq test 3 failed");
      ret = 1;
    }

  mem = -1;
  if (catomic_compare_and_exchange_val_acq (&mem, 17, 0) != -1
      || mem != -1)
    {
      puts ("catomic_compare_and_exchange_val_acq test 4 failed");
      ret = 1;
    }
#endif

  mem = 24;
  if (catomic_compare_and_exchange_bool_acq (&mem, 35, 24)
      || mem != 35)
    {
      puts ("catomic_compare_and_exchange_bool_acq test 1 failed");
      ret = 1;
    }

  mem = 12;
  if (! catomic_compare_and_exchange_bool_acq (&mem, 10, 15)
      || mem != 12)
    {
      puts ("catomic_compare_and_exchange_bool_acq test 2 failed");
      ret = 1;
    }

  mem = -15;
  if (catomic_compare_and_exchange_bool_acq (&mem, -56, -15)
      || mem != -56)
    {
      puts ("catomic_compare_and_exchange_bool_acq test 3 failed");
      ret = 1;
    }

  mem = -1;
  if (! catomic_compare_and_exchange_bool_acq (&mem, 17, 0)
      || mem != -1)
    {
      puts ("catomic_compare_and_exchange_bool_acq test 4 failed");
      ret = 1;
    }

  mem = 2;
  if (catomic_exchange_and_add (&mem, 11) != 2
      || mem != 13)
    {
      puts ("catomic_exchange_and_add test failed");
      ret = 1;
    }

  mem = -21;
  catomic_add (&mem, 22);
  if (mem != 1)
    {
      puts ("catomic_add test failed");
      ret = 1;
    }

  mem = -1;
  catomic_increment (&mem);
  if (mem != 0)
    {
      puts ("catomic_increment test failed");
      ret = 1;
    }

  mem = 2;
  if (catomic_increment_val (&mem) != 3)
    {
      puts ("catomic_increment_val test failed");
      ret = 1;
    }

  mem = 17;
  catomic_decrement (&mem);
  if (mem != 16)
    {
      puts ("catomic_decrement test failed");
      ret = 1;
    }

  if (catomic_decrement_val (&mem) != 15)
    {
      puts ("catomic_decrement_val test failed");
      ret = 1;
    }

  /* Tests for C11-like atomics.  */
  mem = 11;
  if (atomic_load_relaxed (&mem) != 11 || atomic_load_acquire (&mem) != 11)
    {
      puts ("atomic_load_{relaxed,acquire} test failed");
      ret = 1;
    }

  atomic_store_relaxed (&mem, 12);
  if (mem != 12)
    {
      puts ("atomic_store_relaxed test failed");
      ret = 1;
    }
  atomic_store_release (&mem, 13);
  if (mem != 13)
    {
      puts ("atomic_store_release test failed");
      ret = 1;
    }

  mem = 14;
  expected = 14;
  if (!atomic_compare_exchange_weak_relaxed (&mem, &expected, 25)
      || mem != 25 || expected != 14)
    {
      puts ("atomic_compare_exchange_weak_relaxed test 1 failed");
      ret = 1;
    }
  if (atomic_compare_exchange_weak_relaxed (&mem, &expected, 14)
      || mem != 25 || expected != 25)
    {
      puts ("atomic_compare_exchange_weak_relaxed test 2 failed");
      ret = 1;
    }
  mem = 14;
  expected = 14;
  if (!atomic_compare_exchange_weak_acquire (&mem, &expected, 25)
      || mem != 25 || expected != 14)
    {
      puts ("atomic_compare_exchange_weak_acquire test 1 failed");
      ret = 1;
    }
  if (atomic_compare_exchange_weak_acquire (&mem, &expected, 14)
      || mem != 25 || expected != 25)
    {
      puts ("atomic_compare_exchange_weak_acquire test 2 failed");
      ret = 1;
    }
  mem = 14;
  expected = 14;
  if (!atomic_compare_exchange_weak_release (&mem, &expected, 25)
      || mem != 25 || expected != 14)
    {
      puts ("atomic_compare_exchange_weak_release test 1 failed");
      ret = 1;
    }
  if (atomic_compare_exchange_weak_release (&mem, &expected, 14)
      || mem != 25 || expected != 25)
    {
      puts ("atomic_compare_exchange_weak_release test 2 failed");
      ret = 1;
    }

  mem = 23;
  if (atomic_exchange_acquire (&mem, 42) != 23 || mem != 42)
    {
      puts ("atomic_exchange_acquire test failed");
      ret = 1;
    }
  mem = 23;
  if (atomic_exchange_release (&mem, 42) != 23 || mem != 42)
    {
      puts ("atomic_exchange_release test failed");
      ret = 1;
    }

  mem = 23;
  if (atomic_fetch_add_relaxed (&mem, 1) != 23 || mem != 24)
    {
      puts ("atomic_fetch_add_relaxed test failed");
      ret = 1;
    }
  mem = 23;
  if (atomic_fetch_add_acquire (&mem, 1) != 23 || mem != 24)
    {
      puts ("atomic_fetch_add_acquire test failed");
      ret = 1;
    }
  mem = 23;
  if (atomic_fetch_add_release (&mem, 1) != 23 || mem != 24)
    {
      puts ("atomic_fetch_add_release test failed");
      ret = 1;
    }
  mem = 23;
  if (atomic_fetch_add_acq_rel (&mem, 1) != 23 || mem != 24)
    {
      puts ("atomic_fetch_add_acq_rel test failed");
      ret = 1;
    }

  mem = 3;
  if (atomic_fetch_and_acquire (&mem, 2) != 3 || mem != 2)
    {
      puts ("atomic_fetch_and_acquire test failed");
      ret = 1;
    }

  mem = 4;
  if (atomic_fetch_or_relaxed (&mem, 2) != 4 || mem != 6)
    {
      puts ("atomic_fetch_or_relaxed test failed");
      ret = 1;
    }
  mem = 4;
  if (atomic_fetch_or_acquire (&mem, 2) != 4 || mem != 6)
    {
      puts ("atomic_fetch_or_acquire test failed");
      ret = 1;
    }

  /* This is a single-threaded test, so we can't test the effects of the
     fences.  */
  atomic_thread_fence_acquire ();
  atomic_thread_fence_release ();
  atomic_thread_fence_seq_cst ();

  return ret;
}
int
Ndb_move_data::check_tables()
{
  int ret = 0;
  const Opts& opts = m_opts;
  do
  {
    int attrcount1 = m_source->getNoOfColumns();
    int attrcount2 = m_target->getNoOfColumns();
    m_sourceattr = new Attr [attrcount1];
    m_targetattr = new Attr [attrcount2];

    // set type info, remap columns, check missing

    for (int i1 = 0; i1 < attrcount1; i1++)
    {
      Attr& attr1 = m_sourceattr[i1];
      attr1.id = i1;
      const NdbDictionary::Column* c1 = m_source->getColumn(i1);
      require(c1 != 0);
      set_type(attr1, c1);
      const NdbDictionary::Column* c2 = m_target->getColumn(attr1.name);
      if (c2 == 0)
      {
        CHK2(opts.flags & Opts::MD_EXCLUDE_MISSING_COLUMNS,
             (Error::NoExcludeMissingFlag,
              "cannot convert source to target"
              ": source column #%d '%s' not found in target"
              " and exclude-missing-columns has not been specified",
              1+i1, attr1.name));
      }
      else
      {
        int i2 = c2->getColumnNo();
        require(i2 >= 0 && i2 < attrcount2);
        Attr& attr2 = m_targetattr[i2];
        attr1.map_id = i2;
        require(attr2.map_id == -1);
        attr2.map_id = i1;
      }
    }
    CHK1(ret == 0);

    for (int i2 = 0; i2 < attrcount2; i2++)
    {
      Attr& attr2 = m_targetattr[i2];
      attr2.id = i2;
      const NdbDictionary::Column* c2 = m_target->getColumn(i2);
      require(c2 != 0);
      set_type(attr2, c2);
      const NdbDictionary::Column* c1 = m_source->getColumn(attr2.name);
      if (c1 == 0)
      {
        CHK2(opts.flags & Opts::MD_EXCLUDE_MISSING_COLUMNS,
             (Error::NoExcludeMissingFlag,
              "cannot convert source to target"
              ": target column #%d '%s' not found in source"
              " and exclude-missing-columns has not been specified",
              1+i2, attr2.name));
      }
      else
      {
        int i1 = c1->getColumnNo();
        require(i2 >= 0 && i2 < attrcount2);
        Attr& attr1 = m_sourceattr[i1];
        require(attr1.map_id == i2);
        require(attr2.map_id == i1);
      }
    }
    CHK1(ret == 0);

    // check conversion of non-excluded columns

    for (int i1 = 0; i1 < attrcount1; i1++)
    {
      Attr& attr1 = m_sourceattr[i1];
      int i2 = attr1.map_id;
      if (i2 == -1) // excluded
        continue;
      Attr& attr2 = m_targetattr[i2];

      {
        /* Exclude internal implementation details when comparing */
        NdbDictionary::Column a1ColCopy(*attr1.column);
        NdbDictionary::Column a2ColCopy(*attr2.column);
        
        /* [Non] Dynamic internal storage is irrelevant */ 
        a1ColCopy.setDynamic(false);
        a2ColCopy.setDynamic(false);
        
        if ((attr1.equal = attr2.equal = a1ColCopy.equal(a2ColCopy)))
        {
          continue;
        }
      }

      if (attr1.type == Attr::TypeArray &&
          attr2.type == Attr::TypeBlob)
      {
        CHK1(check_nopk(attr1, attr2) == 0);
        CHK1(check_promotion(attr1, attr2) == 0);
        continue;
      }

      if (attr1.type == Attr::TypeBlob &&
          attr2.type == Attr::TypeArray)
      {
        CHK1(check_nopk(attr1, attr2) == 0);
        CHK1(check_demotion(attr1, attr2) == 0);
        continue;
      }

      if (attr1.type == Attr::TypeArray &&
          attr2.type == Attr::TypeArray)
      {
        CHK1(check_sizes(attr1, attr2) == 0);
        continue;
      }

      CHK1(check_unsupported(attr1, attr2) == 0);
    }
    CHK1(ret == 0);
  }
  while (0);
  return ret;
}