mirror of
https://github.com/MariaDB/server.git
synced 2026-05-09 08:34:28 +02:00
Moved NdbSchemaCon and NdbSchemaOp out of the public NdbApi, it can however still be used by old test programs. Added print oof indexes to desc. ndb/BinDist.sh: Removed AttrType.hpp from BinDist.sh ndb/include/ndbapi/Ndb.hpp: Removed NdbSchemaCon and NdbSchemaOp includes from public NdbApi Removed AttrType.hpp ndb/include/ndbapi/NdbApi.hpp: Removed NdbSchemaCon and NdbSchemaOp includes from public NdbApi Removed AttrType.hpp ndb/include/ndbapi/NdbConnection.hpp: Removed NdbSchemaCon and NdbSchemaOp includes from public NdbApi Removed AttrType.hpp Moved internal types to the class where they are used ndb/include/ndbapi/NdbIndexOperation.hpp: Use limit from ndbapi_limit.h ndb/include/ndbapi/NdbOperation.hpp: Removed NdbSchemaCon and NdbSchemaOp includes from public NdbApi Removed AttrType.hpp Remove faulty comment about how many attributes a key is allowed to consist of Removed unused member variables ndb/include/ndbapi/NdbRecAttr.hpp: Removed NdbSchemaCon and NdbSchemaOp includes from public NdbApi Removed AttrType.hpp ndb/include/ndbapi/NdbSchemaCon.hpp: Removed NdbSchemaCon and NdbSchemaOp includes from public NdbApi Removed AttrType.hpp ndb/include/ndbapi/NdbSchemaOp.hpp: Removed NdbSchemaCon and NdbSchemaOp includes from public NdbApi Removed AttrType.hpp Moved all "old" datatypes here, so if a test program is still using old type, include NdbSchemaCon.hpp ndb/include/ndbapi/ndbapi_limits.h: Corrected limitations, added some from AttrTyp.hpp ndb/src/Makefile: Remove newtonapi from Makefile ndb/src/kernel/blocks/backup/restore/Restore.hpp: Removed AttrType Include NdbSchemaCon since restore uses old types ndb/src/kernel/blocks/backup/restore/main.cpp: Include NdbOut ndb/src/mgmsrv/MgmtSrvr.cpp: Remov AttrType.hpp ndb/src/ndbapi/ClusterMgr.cpp: Remov AttrType.hpp ndb/src/ndbapi/Ndb.cpp: Removed NdbSchemaCon and NdbSchemaOp includes from public NdbApi Removed AttrType.hpp Moved internal types to the class where they are used ndb/src/ndbapi/NdbApiSignal.cpp: Removed AttrType.hpp ndb/src/ndbapi/NdbApiSignal.hpp: Removed AttrType.hpp ndb/src/ndbapi/NdbConnection.cpp: Moved internal type s to the class where they belong ndb/src/ndbapi/NdbDictionaryImpl.cpp: RemovedAttrType.hpp Use limits from ndbapi_limits.h ndb/src/ndbapi/NdbEventOperationImpl.cpp: Removed AttrType.hpp Moved printRecAttr to end since it depends on old types and need to include "NdbSchemaCon", function will be rewritten and moved to NdbRecAttr. It's also useful from other places where an attribute has been read into an NdbRecAttr. ndb/src/ndbapi/NdbIndexOperation.cpp: Use limitations from ndbapi_limits.h Moved internal tyeps to the class where they belongs ndb/src/ndbapi/NdbOperation.cpp: Use limits from ndbapi_limits.h ndb/src/ndbapi/NdbOperationDefine.cpp: Remove AttrType.hpp ndb/src/ndbapi/NdbOperationExec.cpp: Moved internal tyeps to the class where they belongs ndb/src/ndbapi/NdbOperationInt.cpp: RemovedAttrType.hpp Use limits from ndbapi_limits.h ndb/src/ndbapi/NdbOperationScan.cpp: RemovedAttrType.hpp Use limits from ndbapi_limits.h ndb/src/ndbapi/NdbOperationSearch.cpp: Removed AttrType.hpp Use limits from ndbapi_limits.h ndb/src/ndbapi/NdbResultSet.cpp: Moved the "internal" types to corresponding class ndb/src/ndbapi/NdbSchemaCon.cpp: Updated not to be included in public NdbApi ndb/src/ndbapi/NdbSchemaOp.cpp: Updated not to be included in public NdbApi ndb/src/ndbapi/NdbUtil.hpp: Removed AttrType.hpp ndb/src/ndbapi/Ndbif.cpp: Removed AttrType.hpp Removed NdbSchemaCon and NdbSchemaOp from public NdbApi Moved "interal" types to their corresponding class ndb/src/ndbapi/Ndbinit.cpp: Removed NdbSchemaCon and NdbSchemaOp from public NdbApi ndb/src/ndbapi/Ndblist.cpp: Removed NdbSchemaCon and NdbSchemaOp from public NdbApi Moved "internal" types to their corresponding class ndb/src/ndbapi/TransporterFacade.cpp: Removed AttrType.hpp ndb/src/ndbapi/TransporterFacade.hpp: Removed AttrType.hpp Moved internal definition of how many Ndb objects to create to here ndb/test/include/NDBT_Table.hpp: Removed old NdbSchema* Added function to print information about an index ndb/test/ndbapi/acid/acid.cpp: This test program uses old NdbScheaCon.hpp ndb/test/ndbapi/flexAsynch/flexAsynch.cpp: This test program uses old NdbScheaCon.hpp ndb/test/ndbapi/flexScan/flexScan.cpp: This test program uses old NdbScheaCon.hpp ndb/test/ndbapi/interpreterInTup/interpreterInTup.cpp: This test program uses old NdbScheaCon.hpp ndb/test/ndbapi/lmc-bench/src/user/userInterface.cpp: This test program uses old NdbScheaCon.hpp ndb/test/ndbapi/ronja/initronja/initronja.cpp: This test program uses old NdbScheaCon.hpp ndb/test/ndbapi/telco/msa.cpp: This test program uses old NdbScheaCon.hpp ndb/test/ndbapi/testDataBuffers/testDataBuffers.cpp: This test program uses old NdbScheaCon.hpp ndb/test/ndbapi/testNdbApi/testNdbApi.cpp: Remove AttrType.hpp Define max number of Ndb objects test should "try" to create. ndb/test/ndbapi/testRestartGci/testRestartGci.cpp: Moved "internal" datatypes to corresponding class, in this case Ndb class ndb/test/src/NDBT_ResultRow.cpp: This test program uses old NdbScheaCon.hpp But should soon use "printer" from NdbRecAttr ndb/test/src/NDBT_Table.cpp: Print table info more SQL like ndb/test/src/UtilTransactions.cpp: When AttrType.hpp, this hidden bug was discovered. Using wrong enum types in switch. ndb/tools/desc/desc.cpp: Alos print info about indexes for a table
616 lines
16 KiB
C++
616 lines
16 KiB
C++
/* Copyright (C) 2003 MySQL AB
|
|
|
|
This program is free software; you can redistribute it and/or modify
|
|
it under the terms of the GNU General Public License as published by
|
|
the Free Software Foundation; either version 2 of the License, or
|
|
(at your option) any later version.
|
|
|
|
This program is distributed in the hope that it will be useful,
|
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
GNU General Public License for more details.
|
|
|
|
You should have received a copy of the GNU General Public License
|
|
along with this program; if not, write to the Free Software
|
|
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
|
|
|
|
/*
|
|
* testDataBuffers
|
|
*
|
|
* Test getValue() of byte arrays:
|
|
* - using application buffers of different alignments and sizes
|
|
* - using NdbApi allocated small (<32) and big (>=32) buffers
|
|
*
|
|
* Verifies fixes to tickets 189 and 206.
|
|
*
|
|
* Options: see printusage() below.
|
|
*
|
|
* Creates tables TB00 to TB15
|
|
*/
|
|
|
|
#include <ndb_global.h>
|
|
|
|
#include <NdbMain.h>
|
|
#include <NdbOut.hpp>
|
|
#include <NdbApi.hpp>
|
|
#include <NdbTest.hpp>
|
|
#include <NdbSchemaCon.hpp>
|
|
// limits
|
|
static int const MaxAttr = 64;
|
|
static int const MaxOper = 1000;
|
|
static int const MaxSize = 10000;
|
|
static int const MaxOff = 64; // max offset to add to data buffer
|
|
static int const MaxData = MaxSize + MaxOff + 100;
|
|
|
|
// options
|
|
static int attrcnt = 25;
|
|
static int existok = 0;
|
|
static bool kontinue = false;
|
|
static int loopcnt = 1;
|
|
static int opercnt = 100; // also does this many scans
|
|
static int randomizer = 171317;
|
|
static int sizelim = 500;
|
|
static int xverbose = 0;
|
|
|
|
static void printusage() {
|
|
ndbout
|
|
<< "usage: testDataBuffers options [default/max]"
|
|
<< endl
|
|
<< "NOTE: too large combinations result in NDB error"
|
|
<< endl
|
|
<< "-a N number of attributes (including the key) [25/64]"
|
|
<< endl
|
|
<< "-e no error if table exists (assumed to have same structure)"
|
|
<< endl
|
|
<< "-k on error continue with next test case"
|
|
<< endl
|
|
<< "-l N number of loops to run, 0 means infinite [1]"
|
|
<< endl
|
|
<< "-o N number of operations (rows in each table) [100/1000]"
|
|
<< endl
|
|
<< "-r N source of randomness (big number (prime)) [171317]"
|
|
<< endl
|
|
<< "-s N array size limit (rounded up in some tests) [500/10000]"
|
|
<< endl
|
|
<< "-x extremely verbose"
|
|
<< endl
|
|
<< "Tables: TB00 .. TB15"
|
|
<< endl
|
|
;
|
|
}
|
|
|
|
static Ndb* ndb = 0;
|
|
static NdbSchemaCon* tcon = 0;
|
|
static NdbSchemaOp* top = 0;
|
|
static NdbConnection* con = 0;
|
|
static NdbOperation* op = 0;
|
|
|
|
static int
|
|
ndberror(char const* fmt, ...)
|
|
{
|
|
va_list ap;
|
|
char buf[200];
|
|
va_start(ap, fmt);
|
|
vsnprintf(buf, sizeof(buf), fmt, ap);
|
|
va_end(ap);
|
|
ndbout << buf << " --" << endl;
|
|
if (ndb)
|
|
ndbout << "ndb : " << ndb->getNdbError() << endl;
|
|
if (tcon)
|
|
ndbout << "tcon: " << tcon->getNdbError() << endl;
|
|
if (top)
|
|
ndbout << "top: " << top->getNdbError() << endl;
|
|
if (con)
|
|
ndbout << "con : " << con->getNdbError() << endl;
|
|
if (op)
|
|
ndbout << "op : " << op->getNdbError() << endl;
|
|
return -1;
|
|
}
|
|
|
|
static int
|
|
chkerror(char const* fmt, ...)
|
|
{
|
|
va_list ap;
|
|
char buf[200];
|
|
va_start(ap, fmt);
|
|
vsnprintf(buf, sizeof(buf), fmt, ap);
|
|
va_end(ap);
|
|
ndbout << "*** check failed: " << buf << " ***" << endl;
|
|
return -1;
|
|
}
|
|
|
|
// alignment of addresses and data sizes
|
|
|
|
static bool isAligned(unsigned x)
|
|
{
|
|
return ((x & 3) == 0);
|
|
}
|
|
static bool isAligned(char* p)
|
|
{
|
|
return isAligned(unsigned(p));
|
|
}
|
|
static unsigned toAligned(unsigned x)
|
|
{
|
|
while (! isAligned(x))
|
|
x++;
|
|
return x;
|
|
}
|
|
static char* toAligned(char* p)
|
|
{
|
|
while (! isAligned(p))
|
|
p++;
|
|
return p;
|
|
}
|
|
|
|
// byte value for key k column i byte j
|
|
static int byteVal(int k, int i, int j)
|
|
{
|
|
return '0' + (k + i + j) % 10;
|
|
}
|
|
|
|
// tables
|
|
|
|
static char tab[20] = "";
|
|
|
|
static struct col {
|
|
char aAttrName[20];
|
|
AttrType aAttrType;
|
|
int aAttrSize;
|
|
int aArraySize;
|
|
KeyType aTupleKey;
|
|
bool nullable;
|
|
NdbRecAttr* aRa;
|
|
char* buf;
|
|
int bufsiz;
|
|
char data[MaxData];
|
|
} ccol[MaxAttr];
|
|
|
|
static int key = 0;
|
|
|
|
// independent test bits
|
|
static bool alignAddr; // align our buffer addresses to 4x
|
|
static bool alignSize; // align data sizes to 4x
|
|
static bool useBuf; // use our buffers for output
|
|
static bool noRandom; // do not randomize sizes and offsets
|
|
static int testbits = 4;
|
|
|
|
static int
|
|
makeSize(int i)
|
|
{
|
|
int n;
|
|
if (noRandom)
|
|
n = i;
|
|
else
|
|
n = i * randomizer;
|
|
n %= sizelim;
|
|
if (n <= 0)
|
|
n = 1;
|
|
if (alignSize)
|
|
n = toAligned(n);
|
|
return n;
|
|
}
|
|
|
|
static int
|
|
makeOff(int k)
|
|
{
|
|
int n;
|
|
if (alignAddr)
|
|
n = 0;
|
|
else if (noRandom)
|
|
n = k;
|
|
else
|
|
n = k * randomizer;
|
|
n %= MaxOff;
|
|
if (n < 0)
|
|
n = -n;
|
|
return n;
|
|
}
|
|
|
|
static int
|
|
testcase(int flag)
|
|
{
|
|
ndbout << "--- case " << flag << " ---" << endl;
|
|
sprintf(tab, "TB%02d", flag);
|
|
|
|
alignAddr = ! (flag & 1);
|
|
ndbout << (alignAddr ? "align addresses" : "mis-align addresses") << endl;
|
|
alignSize = ! (flag & 2);
|
|
ndbout << (alignSize ? "align data sizes" : "mis-align data sizes") << endl;
|
|
useBuf = ! (flag & 4);
|
|
ndbout << (useBuf ? "use our buffers" : "use ndbapi buffers") << endl;
|
|
noRandom = ! (flag & 8);
|
|
ndbout << (noRandom ? "simple sizes" : "randomize sizes") << endl;
|
|
|
|
int smax = 0, stot = 0;
|
|
if (xverbose)
|
|
ndbout << "- define table " << tab << endl;
|
|
for (int i = 0; i < attrcnt; i++) {
|
|
col& c = ccol[i];
|
|
memset(&c, 0, sizeof(c));
|
|
sprintf(c.aAttrName, "C%d", i);
|
|
if (i == 0) {
|
|
c.aAttrType = UnSigned;
|
|
c.aAttrSize = 32;
|
|
c.aArraySize = 1;
|
|
c.aTupleKey = TupleKey;
|
|
c.nullable = false;
|
|
} else {
|
|
c.aAttrType = String;
|
|
c.aAttrSize = 8;
|
|
c.aArraySize = makeSize(i);
|
|
if (smax < c.aArraySize)
|
|
smax = c.aArraySize;
|
|
stot += c.aArraySize;
|
|
c.aTupleKey = NoKey;
|
|
c.nullable = true;
|
|
if (xverbose)
|
|
ndbout << "-- column " << i << " size=" << c.aArraySize << endl;
|
|
}
|
|
c.buf = toAligned(c.data);
|
|
c.bufsiz = sizeof(c.data) - (c.buf - c.data);
|
|
}
|
|
ndbout << "tab=" << tab << " cols=" << attrcnt
|
|
<< " size max=" << smax << " tot=" << stot << endl;
|
|
|
|
ndb = new Ndb("TEST_DB");
|
|
if (ndb->init() != 0)
|
|
return ndberror("init");
|
|
if (ndb->waitUntilReady(30) < 0)
|
|
return ndberror("waitUntilReady");
|
|
|
|
if ((tcon = NdbSchemaCon::startSchemaTrans(ndb)) == 0)
|
|
return ndberror("startSchemaTransaction");
|
|
if ((top = tcon->getNdbSchemaOp()) == 0)
|
|
return ndberror("getNdbSchemaOp");
|
|
if (top->createTable(tab) < 0)
|
|
return ndberror("createTable");
|
|
for (int i = 0; i < attrcnt; i++) {
|
|
col& c = ccol[i];
|
|
if (top->createAttribute(
|
|
c.aAttrName,
|
|
c.aTupleKey,
|
|
c.aAttrSize,
|
|
c.aArraySize,
|
|
c.aAttrType,
|
|
MMBased,
|
|
c.nullable
|
|
) < 0)
|
|
return ndberror("createAttribute col=%d", i);
|
|
}
|
|
if (tcon->execute() < 0) {
|
|
if (! (tcon->getNdbError().code == 721 && existok))
|
|
return ndberror("execute");
|
|
ndbout << "using " << tab << endl;
|
|
} else {
|
|
ndbout << "created " << tab << endl;
|
|
}
|
|
top = 0;
|
|
tcon = 0;
|
|
|
|
if (xverbose)
|
|
ndbout << "- delete" << endl;
|
|
int delcnt = 0;
|
|
for (key = 0; key < opercnt; key++) {
|
|
if ((con = ndb->startTransaction()) == 0)
|
|
return ndberror("startTransaction key=%d", key);
|
|
if ((op = con->getNdbOperation(tab)) == 0)
|
|
return ndberror("getNdbOperation key=%d", key);
|
|
if (op->deleteTuple() < 0)
|
|
return ndberror("deleteTuple key=%d", key);
|
|
for (int i = 0; i < attrcnt; i++) {
|
|
col& c = ccol[i];
|
|
if (i == 0) {
|
|
if (op->equal(c.aAttrName, (char*)&key, sizeof(key)) < 0)
|
|
return ndberror("equal key=%d", key);
|
|
} else {
|
|
}
|
|
}
|
|
if (con->execute(Commit) < 0) {
|
|
if (con->getNdbError().code != 626)
|
|
return ndberror("execute key=%d", key);
|
|
} else {
|
|
delcnt++;
|
|
}
|
|
ndb->closeTransaction(con);
|
|
}
|
|
con = 0;
|
|
op = 0;
|
|
ndbout << "deleted " << delcnt << endl;
|
|
|
|
if (xverbose)
|
|
ndbout << "- insert" << endl;
|
|
for (key = 0; key < opercnt; key++) {
|
|
int off = makeOff(key);
|
|
if ((con = ndb->startTransaction()) == 0)
|
|
return ndberror("startTransaction key=%d", key);
|
|
if ((op = con->getNdbOperation(tab)) == 0)
|
|
return ndberror("getNdbOperation key=%d", key);
|
|
if (op->insertTuple() < 0)
|
|
return ndberror("insertTuple key=%d", key);
|
|
for (int i = 0; i < attrcnt; i++) {
|
|
col& c = ccol[i];
|
|
if (i == 0) {
|
|
if (op->equal(c.aAttrName, (char*)&key, sizeof(key)) < 0)
|
|
return ndberror("equal key=%d", key);
|
|
} else {
|
|
memset(c.buf, 'A', c.bufsiz);
|
|
for (int j = 0; j < c.aArraySize; j++)
|
|
c.buf[j + off] = byteVal(key, i, j);
|
|
if (op->setValue(c.aAttrName, c.buf + off, c.aArraySize) < 0)
|
|
return ndberror("setValue key=%d col=%d", key, i);
|
|
}
|
|
}
|
|
if (con->execute(Commit) < 0)
|
|
return ndberror("execute key=%d", key);
|
|
ndb->closeTransaction(con);
|
|
}
|
|
con = 0;
|
|
op = 0;
|
|
ndbout << "inserted " << key << endl;
|
|
|
|
if (xverbose)
|
|
ndbout << "- select" << endl;
|
|
for (key = 0; key < opercnt; key++) {
|
|
int off = makeOff(key);
|
|
if (xverbose)
|
|
ndbout << "-- key " << key << " off=" << off << endl;
|
|
if ((con = ndb->startTransaction()) == 0)
|
|
return ndberror("startTransaction key=%d", key);
|
|
if ((op = con->getNdbOperation(tab)) == 0)
|
|
return ndberror("getNdbOperation key=%d", key);
|
|
if (op->readTuple() < 0)
|
|
return ndberror("readTuple key=%d", key);
|
|
for (int i = 0; i < attrcnt; i++) {
|
|
col& c = ccol[i];
|
|
if (i == 0) {
|
|
if (op->equal(c.aAttrName, (char*)&key, sizeof(key)) < 0)
|
|
return ndberror("equal key=%d", key);
|
|
} else {
|
|
if (xverbose) {
|
|
char tmp[20];
|
|
if (useBuf)
|
|
sprintf(tmp, "0x%x", int(c.buf + off));
|
|
else
|
|
strcpy(tmp, "ndbapi");
|
|
ndbout << "--- column " << i << " addr=" << tmp << endl;
|
|
}
|
|
memset(c.buf, 'B', c.bufsiz);
|
|
if (useBuf) {
|
|
if (op->getValue(c.aAttrName, c.buf + off) < 0)
|
|
return ndberror("getValue key=%d col=%d", key, i);
|
|
} else {
|
|
if ((c.aRa = op->getValue(c.aAttrName)) == 0)
|
|
return ndberror("getValue key=%d col=%d", key, i);
|
|
}
|
|
}
|
|
}
|
|
if (con->execute(Commit) != 0)
|
|
return ndberror("execute key=%d", key);
|
|
for (int i = 0; i < attrcnt; i++) {
|
|
col& c = ccol[i];
|
|
if (i == 0) {
|
|
} else if (useBuf) {
|
|
for (int j = 0; j < off; j++) {
|
|
if (c.buf[j] != 'B') {
|
|
return chkerror("mismatch before key=%d col=%d pos=%d ok=%02x bad=%02x",
|
|
key, i, j, 'B', c.buf[j]);
|
|
}
|
|
}
|
|
for (int j = 0; j < c.aArraySize; j++) {
|
|
if (c.buf[j + off] != byteVal(key, i, j)) {
|
|
return chkerror("mismatch key=%d col=%d pos=%d ok=%02x bad=%02x",
|
|
key, i, j, byteVal(key, i, j), c.buf[j]);
|
|
}
|
|
}
|
|
for (int j = c.aArraySize + off; j < c.bufsiz; j++) {
|
|
if (c.buf[j] != 'B') {
|
|
return chkerror("mismatch after key=%d col=%d pos=%d ok=%02x bad=%02x",
|
|
key, i, j, 'B', c.buf[j]);
|
|
}
|
|
}
|
|
} else {
|
|
char* buf = c.aRa->aRef();
|
|
if (buf == 0)
|
|
return ndberror("null aRef key=%d col%d", key, i);
|
|
for (int j = 0; j < c.aArraySize; j++) {
|
|
if (buf[j] != byteVal(key, i, j)) {
|
|
return chkerror("mismatch key=%d col=%d pos=%d ok=%02x bad=%02x",
|
|
key, i, j, byteVal(key, i, j), buf[j]);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
ndb->closeTransaction(con);
|
|
}
|
|
con = 0;
|
|
op = 0;
|
|
ndbout << "selected " << key << endl;
|
|
|
|
if (xverbose)
|
|
ndbout << "- scan" << endl;
|
|
char found[MaxOper];
|
|
for (int k = 0; k < opercnt; k++)
|
|
found[k] = 0;
|
|
for (key = 0; key < opercnt; key++) {
|
|
int off = makeOff(key);
|
|
if (xverbose)
|
|
ndbout << "-- key " << key << " off=" << off << endl;
|
|
int newkey = 0;
|
|
if ((con = ndb->startTransaction()) == 0)
|
|
return ndberror("startTransaction key=%d", key);
|
|
if ((op = con->getNdbOperation(tab)) == 0)
|
|
return ndberror("getNdbOperation key=%d", key);
|
|
if (op->openScanRead(1) < 0)
|
|
return ndberror("openScanRead key=%d", key);
|
|
{
|
|
col& c = ccol[0];
|
|
if (op->load_const_u32(1, key) < 0)
|
|
return ndberror("load_const_u32");
|
|
if (op->read_attr(c.aAttrName, 2) < 0)
|
|
return ndberror("read_attr");
|
|
if (op->branch_eq(1, 2, 0) < 0)
|
|
return ndberror("branch_eq");
|
|
if (op->interpret_exit_nok() < 0)
|
|
return ndberror("interpret_exit_nok");
|
|
if (op->def_label(0) < 0)
|
|
return ndberror("def_label");
|
|
if (op->interpret_exit_ok() < 0)
|
|
return ndberror("interpret_exit_ok");
|
|
}
|
|
for (int i = 0; i < attrcnt; i++) {
|
|
col& c = ccol[i];
|
|
if (i == 0) {
|
|
if (op->getValue(c.aAttrName, (char*)&newkey) < 0)
|
|
return ndberror("getValue key=%d col=%d", key, i);
|
|
} else {
|
|
if (xverbose) {
|
|
char tmp[20];
|
|
if (useBuf)
|
|
sprintf(tmp, "0x%x", int(c.buf + off));
|
|
else
|
|
strcpy(tmp, "ndbapi");
|
|
ndbout << "--- column " << i << " addr=" << tmp << endl;
|
|
}
|
|
memset(c.buf, 'C', c.bufsiz);
|
|
if (useBuf) {
|
|
if (op->getValue(c.aAttrName, c.buf + off) < 0)
|
|
return ndberror("getValue key=%d col=%d", key, i);
|
|
} else {
|
|
if ((c.aRa = op->getValue(c.aAttrName)) == 0)
|
|
return ndberror("getValue key=%d col=%d", key, i);
|
|
}
|
|
}
|
|
}
|
|
if (con->executeScan() < 0)
|
|
return ndberror("executeScan key=%d", key);
|
|
int ret, cnt = 0;
|
|
while ((ret = con->nextScanResult()) == 0) {
|
|
if (key != newkey)
|
|
return ndberror("unexpected key=%d newkey=%d", key, newkey);
|
|
for (int i = 1; i < attrcnt; i++) {
|
|
col& c = ccol[i];
|
|
if (useBuf) {
|
|
for (int j = 0; j < off; j++) {
|
|
if (c.buf[j] != 'C') {
|
|
return chkerror("mismatch before key=%d col=%d pos=%d ok=%02x bad=%02x",
|
|
key, i, j, 'C', c.buf[j]);
|
|
}
|
|
}
|
|
for (int j = 0; j < c.aArraySize; j++) {
|
|
if (c.buf[j + off] != byteVal(key, i, j)) {
|
|
return chkerror("mismatch key=%d col=%d pos=%d ok=%02x bad=%02x",
|
|
key, i, j, byteVal(key, i, j), c.buf[j]);
|
|
}
|
|
}
|
|
for (int j = c.aArraySize + off; j < c.bufsiz; j++) {
|
|
if (c.buf[j] != 'C') {
|
|
return chkerror("mismatch after key=%d col=%d pos=%d ok=%02x bad=%02x",
|
|
key, i, j, 'C', c.buf[j]);
|
|
}
|
|
}
|
|
} else {
|
|
char* buf = c.aRa->aRef();
|
|
if (buf == 0)
|
|
return ndberror("null aRef key=%d col%d", key, i);
|
|
for (int j = 0; j < c.aArraySize; j++) {
|
|
if (buf[j] != byteVal(key, i, j)) {
|
|
return chkerror("mismatch key=%d col=%d pos=%d ok=%02x bad=%02x",
|
|
key, i, j, byteVal(key, i, j), buf[j]);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
cnt++;
|
|
}
|
|
if (ret < 0)
|
|
return ndberror("nextScanResult key=%d", key);
|
|
if (cnt != 1)
|
|
return ndberror("scan key=%d found %d", key, cnt);
|
|
found[key] = 1;
|
|
ndb->closeTransaction(con);
|
|
}
|
|
con = 0;
|
|
op = 0;
|
|
for (int k = 0; k < opercnt; k++)
|
|
if (! found[k])
|
|
return ndberror("key %d not found", k);
|
|
ndbout << "scanned " << key << endl;
|
|
|
|
ndb = 0;
|
|
ndbout << "done" << endl;
|
|
return 0;
|
|
}
|
|
|
|
NDB_COMMAND(testDataBuffers, "testDataBuffers", "testDataBuffers", "testDataBuffers", 65535)
|
|
{
|
|
while (++argv, --argc > 0) {
|
|
char const* p = argv[0];
|
|
if (*p++ != '-' || strlen(p) != 1)
|
|
goto wrongargs;
|
|
switch (*p) {
|
|
case 'a':
|
|
if (++argv, --argc > 0) {
|
|
attrcnt = atoi(argv[0]);
|
|
if (1 <= attrcnt && attrcnt <= MaxAttr)
|
|
break;
|
|
}
|
|
goto wrongargs;
|
|
case 'e':
|
|
existok = 1;
|
|
break;
|
|
case 'k':
|
|
kontinue = true;
|
|
break;
|
|
case 'l':
|
|
if (++argv, --argc > 0) {
|
|
loopcnt = atoi(argv[0]);
|
|
if (0 <= loopcnt)
|
|
break;
|
|
}
|
|
goto wrongargs;
|
|
case 'o':
|
|
if (++argv, --argc > 0) {
|
|
opercnt = atoi(argv[0]);
|
|
if (0 <= opercnt && opercnt <= MaxOper)
|
|
break;
|
|
}
|
|
goto wrongargs;
|
|
case 'r':
|
|
if (++argv, --argc > 0) {
|
|
randomizer = atoi(argv[0]);
|
|
if (1 <= randomizer)
|
|
break;
|
|
}
|
|
goto wrongargs;
|
|
case 's':
|
|
if (++argv, --argc > 0) {
|
|
sizelim = atoi(argv[0]);
|
|
if (1 <= sizelim && sizelim <= MaxSize)
|
|
break;
|
|
}
|
|
goto wrongargs;
|
|
case 'x':
|
|
xverbose = 1;
|
|
break;
|
|
default:
|
|
wrongargs:
|
|
printusage();
|
|
return NDBT_ProgramExit(NDBT_WRONGARGS);
|
|
}
|
|
}
|
|
unsigned ok = true;
|
|
for (int i = 1; 0 == loopcnt || i <= loopcnt; i++) {
|
|
ndbout << "=== loop " << i << " ===" << endl;
|
|
for (int flag = 0; flag < (1<<testbits); flag++) {
|
|
if (testcase(flag) < 0) {
|
|
ok = false;
|
|
if (! kontinue)
|
|
goto out;
|
|
}
|
|
}
|
|
}
|
|
out:
|
|
return NDBT_ProgramExit(ok ? NDBT_OK : NDBT_FAILED);
|
|
}
|
|
|
|
// vim: set sw=4:
|