Below is the list of changes that have just been committed into a local
5.1 repository of pekka. When pekka does a push these changes will
be propagated to the main repository and, within 24 hours after the
push, to the public repository.
For information on how to access the public repository
see http://dev.mysql.com/doc/mysql/en/installing-source-tree.html
ChangeSet@stripped, 2007-03-31 18:26:33+02:00, pekka@stripped +8 -0
ndb - wl#3717 blobs V2 default partitioning + test program improvements
storage/ndb/include/ndbapi/NdbBlob.hpp@stripped, 2007-03-31 18:25:51+02:00, pekka@stripped +3 -2
wl#3717 blobs V2 default partitioning + test program improvements
storage/ndb/include/ndbapi/NdbDictionary.hpp@stripped, 2007-03-31 18:25:51+02:00, pekka@stripped +22 -7
wl#3717 blobs V2 default partitioning + test program improvements
storage/ndb/src/ndbapi/NdbBlob.cpp@stripped, 2007-03-31 18:25:51+02:00, pekka@stripped +59 -27
wl#3717 blobs V2 default partitioning + test program improvements
storage/ndb/src/ndbapi/NdbDictionaryImpl.cpp@stripped, 2007-03-31 18:25:51+02:00, pekka@stripped +7 -3
wl#3717 blobs V2 default partitioning + test program improvements
storage/ndb/src/ndbapi/NdbEventOperationImpl.cpp@stripped, 2007-03-31 18:25:52+02:00, pekka@stripped +7 -4
wl#3717 blobs V2 default partitioning + test program improvements
storage/ndb/src/ndbapi/NdbEventOperationImpl.hpp@stripped, 2007-03-31 18:25:52+02:00, pekka@stripped +1 -1
wl#3717 blobs V2 default partitioning + test program improvements
storage/ndb/test/ndbapi/testBlobs.cpp@stripped, 2007-03-31 18:25:52+02:00, pekka@stripped +256 -125
wl#3717 blobs V2 default partitioning + test program improvements
storage/ndb/test/ndbapi/test_event_merge.cpp@stripped, 2007-03-31 18:25:52+02:00, pekka@stripped +57 -23
wl#3717 blobs V2 default partitioning + test program improvements
# This is a BitKeeper patch. What follows are the unified diffs for the
# set of deltas contained in the patch. The rest of the patch, the part
# that BitKeeper cares about, is below these diffs.
# User: pekka
# Host: clam.(none)
# Root: /export/space/pekka/ndb/version/my51-wl3717-a
--- 1.90/storage/ndb/include/ndbapi/NdbDictionary.hpp 2007-03-22 09:15:04 +01:00
+++ 1.91/storage/ndb/include/ndbapi/NdbDictionary.hpp 2007-03-31 18:25:51 +02:00
@@ -353,8 +353,7 @@
/**
* For blob, get "inline size" i.e. number of initial bytes
- * to store in table's blob attribute. This part is normally in
- * main memory and can be indexed and interpreted.
+ * to store in table's blob attribute.
*/
int getInlineSize() const;
@@ -478,22 +477,38 @@
void setCharset(CHARSET_INFO* cs);
/**
- * For blob, get "inline size" i.e. number of initial bytes
+ * For blob, set "inline size" i.e. number of initial bytes
* to store in table's blob attribute. This part is normally in
- * main memory and can be indexed and interpreted.
+ * main memory. It can not currently be indexed.
*/
void setInlineSize(int size);
/**
- * For blob, get "part size" i.e. number of bytes to store in
+ * For blob, set "part size" i.e. number of bytes to store in
* each tuple of the "blob table". Can be set to zero to omit parts
* and to allow only inline bytes ("tinyblob").
*/
void setPartSize(int size);
/**
- * For blob, get "stripe size" i.e. number of consecutive
- * <em>parts</em> to store in each node group.
+ * For blob, set "stripe size" i.e. number of consecutive
+ * <em>parts</em> to store in a fragment, before moving to
+ * another (random) fragment.
+ *
+ * Striping may improve performance for large blobs
+ * since blob part operations are done in parallel.
+ * Optimal stripe size depends on the transport e.g. tcp/ip.
+ *
+ * Example: Given part size 2048 bytes, set stripe size 8.
+ * This assigns i/o in 16k chunks to each fragment.
+ *
+ * Blobs V1 required non-zero stripe size. Blobs V2
+ * (created in version >= 5.1.x) have following behaviour:
+ *
+ * Default stripe size is zero, which means no striping and
+ * also that blob part data is stored in the same node group
+ * as the primary table row. This is done by giving blob parts
+ * table same partition key as the primary table.
*/
void setStripeSize(int size);
--- 1.165/storage/ndb/src/ndbapi/NdbDictionaryImpl.cpp 2007-03-22 09:15:04 +01:00
+++ 1.166/storage/ndb/src/ndbapi/NdbDictionaryImpl.cpp 2007-03-31 18:25:51 +02:00
@@ -205,7 +205,7 @@
case Blob:
m_precision = 256;
m_scale = 8000;
- m_length = 4;
+ m_length = 0; // default no striping
m_cs = NULL;
m_arrayType = NDB_ARRAYTYPE_MEDIUM_VAR;
m_blobVersion = NDB_BLOB_V2;
@@ -213,7 +213,7 @@
case Text:
m_precision = 256;
m_scale = 8000;
- m_length = 4;
+ m_length = 0;
m_cs = default_cs;
m_arrayType = NDB_ARRAYTYPE_MEDIUM_VAR;
m_blobVersion = NDB_BLOB_V2;
@@ -2344,7 +2344,11 @@
if (! c.getBlobType() || c.getPartSize() == 0)
continue;
NdbTableImpl bt;
- NdbBlob::getBlobTable(bt, &t, &c);
+ NdbError error;
+ if (NdbBlob::getBlobTable(bt, &t, &c, error) == -1) {
+ m_error.code = error.code;
+ DBUG_RETURN(-1);
+ }
NdbDictionary::Column::StorageType
d = NdbDictionary::Column::StorageTypeDisk;
if (orig.m_columns[i]->getStorageType() == d)
--- 1.85/storage/ndb/src/ndbapi/NdbEventOperationImpl.cpp 2007-03-28 18:37:06 +02:00
+++ 1.86/storage/ndb/src/ndbapi/NdbEventOperationImpl.cpp 2007-03-31 18:25:52 +02:00
@@ -458,7 +458,7 @@
}
Uint32
-NdbEventOperationImpl::get_blob_part_no()
+NdbEventOperationImpl::get_blob_part_no(bool hasDist)
{
assert(theBlobVersion == 1 || theBlobVersion == 2);
assert(theMainOp != NULL);
@@ -466,10 +466,11 @@
assert(m_data_item != NULL);
LinearSectionPtr (&ptr)[3] = m_data_item->ptr;
- uint pos = 0; // PK and DIST to skip
+ uint pos = 0; // PK and possibly DIST to skip
if (unlikely(theBlobVersion == 1)) {
pos += AttributeHeader(ptr[0].p[0]).getDataSize();
+ assert(hasDist);
pos += AttributeHeader(ptr[0].p[1]).getDataSize();
} else {
uint n = mainTable->m_noOfKeys;
@@ -477,7 +478,8 @@
for (i = 0; i < n; i++) {
pos += AttributeHeader(ptr[0].p[i]).getDataSize();
}
- pos += AttributeHeader(ptr[0].p[n]).getDataSize();
+ if (hasDist)
+ pos += AttributeHeader(ptr[0].p[n]).getDataSize();
}
assert(pos < ptr[1].sz);
@@ -494,6 +496,7 @@
part, count, blob->theEventBlobVersion));
NdbEventOperationImpl* blob_op = blob->theBlobEventOp;
+ const bool hasDist = (blob->theStripeSize != 0);
EventBufData* main_data = m_data_item;
DBUG_PRINT_EVENT("info", ("main_data=%p", main_data));
@@ -527,7 +530,7 @@
int r = blob_op->receive_event();
assert(r > 0);
// XXX should be: no = blob->theBlobEventPartValue
- Uint32 no = blob_op->get_blob_part_no();
+ Uint32 no = blob_op->get_blob_part_no(hasDist);
DBUG_PRINT_EVENT("info", ("part_data=%p part no=%u part sz=%u", data, no, sz));
--- 1.36/storage/ndb/src/ndbapi/NdbEventOperationImpl.hpp 2007-03-28 18:37:06 +02:00
+++ 1.37/storage/ndb/src/ndbapi/NdbEventOperationImpl.hpp 2007-03-31 18:25:52 +02:00
@@ -356,7 +356,7 @@
NdbRecAttr *getValue(const NdbColumnImpl *, char *aValue, int n);
NdbBlob *getBlobHandle(const char *colName, int n);
NdbBlob *getBlobHandle(const NdbColumnImpl *, int n);
- Uint32 get_blob_part_no();
+ Uint32 get_blob_part_no(bool hasDist);
int readBlobParts(char* buf, NdbBlob* blob,
Uint32 part, Uint32 count, Uint16* lenLoc);
int receive_event();
--- 1.40/storage/ndb/test/ndbapi/testBlobs.cpp 2007-03-28 18:37:06 +02:00
+++ 1.41/storage/ndb/test/ndbapi/testBlobs.cpp 2007-03-31 18:25:52 +02:00
@@ -24,25 +24,6 @@
#include <NdbTest.hpp>
#include <NdbTick.h>
-struct Bcol {
- bool m_nullable;
- unsigned m_inline;
- unsigned m_partsize;
- unsigned m_stripe;
- char m_btname[200];
- Bcol(bool a, unsigned b, unsigned c, unsigned d) :
- m_nullable(a),
- m_inline(b),
- m_partsize(c),
- m_stripe(d)
- {}
-};
-
-#define TEST_BLOBS_SIZE1 false, 240, 2000, 4
-#define TEST_BLOBS_SIZE2 true, 99, 55, 1
-#define TEST_BLOBS_MIN_SIZE1 false, 8, 8, 4
-#define TEST_BLOBS_MIN_SIZE2 true, 9, 5, 1
-
struct Opt {
unsigned m_batch;
bool m_core;
@@ -64,9 +45,12 @@
const char* m_x2name; // ordered index
unsigned m_pk1off;
unsigned m_pk2len;
+ unsigned m_pk2totlen;
+ bool m_pk2fixed;
+ bool m_pk2binary;
+ bool m_pk2part;
+ uint m_pk2type;
bool m_oneblob;
- Bcol m_blob1;
- Bcol m_blob2;
// perf
const char* m_tnameperf;
unsigned m_rowsperf;
@@ -94,9 +78,11 @@
m_x2name("TB1X2"),
m_pk1off(0x12340000),
m_pk2len(55),
+ m_pk2totlen(0),
+ m_pk2fixed(false),
+ m_pk2binary(false),
+ m_pk2part(false),
m_oneblob(false),
- m_blob1(TEST_BLOBS_SIZE1), // head+inline=256 bytes
- m_blob2(TEST_BLOBS_SIZE2),
// perf
m_tnameperf("TB2"),
m_rowsperf(10000),
@@ -106,7 +92,7 @@
}
};
-static const unsigned g_max_pk2len = 256;
+static const unsigned g_max_pk2len = 255;
static void
printusage()
@@ -130,7 +116,10 @@
<< " -test xxx only given tests (see list) [all tests]" << endl
<< " -version N blob version 1 or 2 [" << d.m_blob_version << "]" << endl
<< "metadata" << endl
- << " -pk2len N length of PK2 [" << d.m_pk2len << "/" << g_max_pk2len <<"]" << endl
+ << " -pk2len N length of PK2, zero omits PK2,PK3 [" << d.m_pk2len << "/" << g_max_pk2len <<"]" << endl
+ << " -pk2fixed PK2 is Char [default Varchar]" << endl
+ << " -pk2binary PK2 is Binary or Varbinary" << endl
+ << " -pk2part partition primary table by PK2" << endl
<< " -oneblob only 1 blob attribute [default 2]" << endl
<< "testcases for test/skip" << endl
<< " k primary key ops" << endl
@@ -230,6 +219,44 @@
ndbout << "line " << __LINE__ << " " << x << endl; \
} while (0)
+
+struct Bcol {
+ int m_type;
+ int m_version;
+ bool m_nullable;
+ uint m_inline;
+ uint m_partsize;
+ uint m_stripe;
+ char m_btname[200];
+ Bcol() { memset(this, 0, sizeof(*this)); }
+};
+
+static Bcol g_blob1;
+static Bcol g_blob2;
+
+static void
+initblobs()
+{
+ {
+ Bcol& b = g_blob1;
+ b.m_type = NdbDictionary::Column::Text;
+ b.m_version = g_opt.m_blob_version;
+ b.m_nullable = false;
+ b.m_inline = g_opt.m_min ? 8 : 240;
+ b.m_partsize = g_opt.m_min ? 8 : 2000;
+ b.m_stripe = b.m_version == 1 ? 4 : 0;
+ }
+ {
+ Bcol& b = g_blob2;
+ b.m_type = NdbDictionary::Column::Blob;
+ b.m_version = g_opt.m_blob_version;
+ b.m_nullable = true;
+ b.m_inline = g_opt.m_min ? 9 : 99;
+ b.m_partsize = g_opt.m_min ? 5 : 55;
+ b.m_stripe = 3;
+ }
+}
+
static int
dropTable()
{
@@ -244,6 +271,7 @@
{
NdbDictionary::Table tab(g_opt.m_tname);
tab.setLogging(false);
+ tab.setFragmentType(NdbDictionary::Object::FragAllLarge);
// col PK1 - Uint32
{ NdbDictionary::Column col("PK1");
col.setType(NdbDictionary::Column::Unsigned);
@@ -252,43 +280,54 @@
}
// col BL1 - Text not-nullable
{ NdbDictionary::Column col("BL1");
- const Bcol& b = g_opt.m_blob1;
- col.setType(NdbDictionary::Column::Text);
- col.setBlobVersion(g_opt.m_blob_version);
+ const Bcol& b = g_blob1;
+ col.setType((NdbDictionary::Column::Type)b.m_type);
+ col.setBlobVersion(b.m_version);
+ col.setNullable(b.m_nullable);
col.setInlineSize(b.m_inline);
col.setPartSize(b.m_partsize);
col.setStripeSize(b.m_stripe);
tab.addColumn(col);
}
- // col PK2 - Char[55]
+ // col PK2 - Char or Varchar, charset binary
if (g_opt.m_pk2len != 0)
{ NdbDictionary::Column col("PK2");
- col.setType(NdbDictionary::Column::Char);
+ col.setType((NdbDictionary::Column::Type)g_opt.m_pk2type);
col.setLength(g_opt.m_pk2len);
col.setPrimaryKey(true);
+ if (g_opt.m_pk2part)
+ col.setPartitionKey(true);
tab.addColumn(col);
}
// col BL2 - Blob nullable
if (! g_opt.m_oneblob)
{ NdbDictionary::Column col("BL2");
- const Bcol& b = g_opt.m_blob2;
- col.setType(NdbDictionary::Column::Blob);
- col.setBlobVersion(g_opt.m_blob_version);
- col.setNullable(true);
+ const Bcol& b = g_blob2;
+ col.setType((NdbDictionary::Column::Type)b.m_type);
+ col.setBlobVersion(b.m_version);
+ col.setNullable(b.m_nullable);
col.setInlineSize(b.m_inline);
col.setPartSize(b.m_partsize);
col.setStripeSize(b.m_stripe);
tab.addColumn(col);
}
+ // col PK3 - puts the Var* key PK2 between PK1 and PK3
+ if (g_opt.m_pk2len != 0)
+ { NdbDictionary::Column col("PK3");
+ col.setType(NdbDictionary::Column::Smallunsigned);
+ col.setPrimaryKey(true);
+ tab.addColumn(col);
+ }
// create table
CHK(g_dic->createTable(tab) == 0);
- // unique hash index on PK2
+ // unique hash index on PK2,PK3
if (g_opt.m_pk2len != 0)
{ NdbDictionary::Index idx(g_opt.m_x1name);
idx.setType(NdbDictionary::Index::UniqueHashIndex);
idx.setLogging(false);
idx.setTable(g_opt.m_tname);
idx.addColumnName("PK2");
+ idx.addColumnName("PK3");
CHK(g_dic->createIndex(idx) == 0);
}
// ordered index on PK2
@@ -321,6 +360,9 @@
m_error_code(0)
{}
~Bval() { delete [] m_val; delete [] m_buf; }
+ void alloc() {
+ alloc(m_bcol.m_inline + m_bcol.m_partsize * g_opt.m_parts);
+ }
void alloc(unsigned buflen) {
m_buflen = buflen;
delete [] m_buf;
@@ -362,25 +404,32 @@
struct Tup {
bool m_exists; // exists in table
- Uint32 m_pk1; // primary keys concatenated like keyinfo
- char m_pk2[g_max_pk2len + 1];
- Bval m_blob1;
- Bval m_blob2;
+ Uint32 m_pk1; // in V1 primary keys concatenated like keyinfo
+ char *m_pk2;
+ Uint16 m_pk3;
+ Bval m_bval1;
+ Bval m_bval2;
+ Uint32 m_frag;
Tup() :
m_exists(false),
- m_blob1(g_opt.m_blob1),
- m_blob2(g_opt.m_blob2)
+ m_pk2(new char [g_opt.m_pk2totlen]),
+ m_bval1(g_blob1),
+ m_bval2(g_blob2),
+ m_frag(~(Uint32)0)
{}
- ~Tup() { }
+ ~Tup() {
+ delete [] m_pk2;
+ m_pk2 = 0;
+ }
// alloc buffers of max size
void alloc() {
- m_blob1.alloc(g_opt.m_blob1.m_inline + g_opt.m_blob1.m_partsize * g_opt.m_parts);
- m_blob2.alloc(g_opt.m_blob2.m_inline + g_opt.m_blob2.m_partsize * g_opt.m_parts);
+ m_bval1.alloc();
+ m_bval2.alloc();
}
void copyfrom(const Tup& tup) {
assert(m_pk1 == tup.m_pk1);
- m_blob1.copyfrom(tup.m_blob1);
- m_blob2.copyfrom(tup.m_blob2);
+ m_bval1.copyfrom(tup.m_bval1);
+ m_bval2.copyfrom(tup.m_bval2);
}
private:
Tup(const Tup&);
@@ -424,24 +473,39 @@
static void
calcBval(Tup& tup, bool keepsize)
{
- calcBval(g_opt.m_blob1, tup.m_blob1, keepsize);
+ calcBval(g_blob1, tup.m_bval1, keepsize);
if (! g_opt.m_oneblob)
- calcBval(g_opt.m_blob2, tup.m_blob2, keepsize);
+ calcBval(g_blob2, tup.m_bval2, keepsize);
}
static void
-calcTups(bool keepsize)
+calcTups(bool keys, bool keepsize)
{
for (unsigned k = 0; k < g_opt.m_rows; k++) {
Tup& tup = g_tups[k];
- tup.m_pk1 = g_opt.m_pk1off + k;
- for (unsigned i = 0, n = k; i < g_opt.m_pk2len; i++) {
- if (n != 0) {
- tup.m_pk2[i] = '0' + n % 10;
- n = n / 10;
- } else {
- tup.m_pk2[i] = 'a' + i % 26;
+ if (keys) {
+ tup.m_pk1 = g_opt.m_pk1off + k;
+ {
+ char* p = tup.m_pk2;
+ uint sz = urandom(g_opt.m_pk2len + 1);
+ if (! g_opt.m_pk2fixed) {
+ *(uchar*)p = sz;
+ p++;
+ }
+ uint i = 0;
+ while (i < sz) {
+ p[i] = 'a' + urandom(26);
+ i++;
+ }
+ while (i < g_opt.m_pk2len) {
+ if (g_opt.m_pk2fixed)
+ p[i] = 0x40;
+ else
+ p[i] = 'A' + urandom(26); //garbage
+ i++;
+ }
}
+ tup.m_pk3 = (Uint16)k;
}
calcBval(tup, keepsize);
}
@@ -518,9 +582,9 @@
static int
setBlobValue(const Tup& tup, int error_code = 0)
{
- CHK(setBlobValue(g_bh1, tup.m_blob1, error_code) == 0);
+ CHK(setBlobValue(g_bh1, tup.m_bval1, error_code) == 0);
if (! g_opt.m_oneblob)
- CHK(setBlobValue(g_bh2, tup.m_blob2, error_code) == 0);
+ CHK(setBlobValue(g_bh2, tup.m_bval2, error_code) == 0);
return 0;
}
@@ -536,9 +600,9 @@
static int
getBlobValue(const Tup& tup)
{
- CHK(getBlobValue(g_bh1, tup.m_blob1) == 0);
+ CHK(getBlobValue(g_bh1, tup.m_bval1) == 0);
if (! g_opt.m_oneblob)
- CHK(getBlobValue(g_bh2, tup.m_blob2) == 0);
+ CHK(getBlobValue(g_bh2, tup.m_bval2) == 0);
return 0;
}
@@ -565,9 +629,9 @@
static int
verifyBlobValue(const Tup& tup)
{
- CHK(verifyBlobValue(g_bh1, tup.m_blob1) == 0);
+ CHK(verifyBlobValue(g_bh1, tup.m_bval1) == 0);
if (! g_opt.m_oneblob)
- CHK(verifyBlobValue(g_bh2, tup.m_blob2) == 0);
+ CHK(verifyBlobValue(g_bh2, tup.m_bval2) == 0);
return 0;
}
@@ -612,11 +676,11 @@
static int
writeBlobData(Tup& tup, int error_code = 0)
{
- tup.m_blob1.m_error_code = error_code;
- CHK(writeBlobData(g_bh1, tup.m_blob1) == 0);
+ tup.m_bval1.m_error_code = error_code;
+ CHK(writeBlobData(g_bh1, tup.m_bval1) == 0);
if (! g_opt.m_oneblob) {
- tup.m_blob2.m_error_code = error_code;
- CHK(writeBlobData(g_bh2, tup.m_blob2) == 0);
+ tup.m_bval2.m_error_code = error_code;
+ CHK(writeBlobData(g_bh2, tup.m_bval2) == 0);
}
return 0;
}
@@ -660,9 +724,9 @@
static int
readBlobData(const Tup& tup)
{
- CHK(readBlobData(g_bh1, tup.m_blob1) == 0);
+ CHK(readBlobData(g_bh1, tup.m_bval1) == 0);
if (! g_opt.m_oneblob)
- CHK(readBlobData(g_bh2, tup.m_blob2) == 0);
+ CHK(readBlobData(g_bh2, tup.m_bval2) == 0);
return 0;
}
@@ -691,9 +755,9 @@
static int
setBlobWriteHook(Tup& tup, int error_code = 0)
{
- CHK(setBlobWriteHook(g_bh1, tup.m_blob1, error_code) == 0);
+ CHK(setBlobWriteHook(g_bh1, tup.m_bval1, error_code) == 0);
if (! g_opt.m_oneblob)
- CHK(setBlobWriteHook(g_bh2, tup.m_blob2, error_code) == 0);
+ CHK(setBlobWriteHook(g_bh2, tup.m_bval2, error_code) == 0);
return 0;
}
@@ -726,53 +790,59 @@
static int
setBlobReadHook(Tup& tup)
{
- CHK(setBlobReadHook(g_bh1, tup.m_blob1) == 0);
+ CHK(setBlobReadHook(g_bh1, tup.m_bval1) == 0);
if (! g_opt.m_oneblob)
- CHK(setBlobReadHook(g_bh2, tup.m_blob2) == 0);
+ CHK(setBlobReadHook(g_bh2, tup.m_bval2) == 0);
return 0;
}
// verify blob data
static int
-verifyHeadInline(const Bcol& c, const Bval& v, NdbRecAttr* ra)
+verifyHeadInline(const Bcol& b, const Bval& v, NdbRecAttr* ra)
{
if (v.m_val == 0) {
CHK(ra->isNULL() == 1);
} else {
CHK(ra->isNULL() == 0);
NdbBlob::Head head;
- NdbBlob::unpackBlobHead(head, ra->aRef(), g_opt.m_blob_version);
+ NdbBlob::unpackBlobHead(head, ra->aRef(), b.m_version);
CHK(head.length == v.m_len);
const char* data = ra->aRef() + head.headsize;
- for (unsigned i = 0; i < head.length && i < c.m_inline; i++)
+ for (unsigned i = 0; i < head.length && i < b.m_inline; i++)
CHK(data[i] == v.m_val[i]);
}
return 0;
}
static int
-verifyHeadInline(const Tup& tup)
+verifyHeadInline(Tup& tup)
{
DBG("verifyHeadInline pk1=" << hex << tup.m_pk1);
CHK((g_con = g_ndb->startTransaction()) != 0);
CHK((g_opr = g_con->getNdbOperation(g_opt.m_tname)) != 0);
CHK(g_opr->readTuple() == 0);
CHK(g_opr->equal("PK1", tup.m_pk1) == 0);
- if (g_opt.m_pk2len != 0)
+ if (g_opt.m_pk2len != 0) {
CHK(g_opr->equal("PK2", tup.m_pk2) == 0);
+ CHK(g_opr->equal("PK3", (char*)&tup.m_pk3) == 0);
+ }
NdbRecAttr* ra1;
NdbRecAttr* ra2;
+ NdbRecAttr* ra_frag;
CHK((ra1 = g_opr->getValue("BL1")) != 0);
if (! g_opt.m_oneblob)
CHK((ra2 = g_opr->getValue("BL2")) != 0);
+ CHK((ra_frag = g_opr->getValue(NdbDictionary::Column::FRAGMENT)) != 0);
if (tup.m_exists) {
CHK(g_con->execute(Commit, AbortOnError) == 0);
+ tup.m_frag = ra_frag->u_32_value();
+ DBG("fragment id: " << tup.m_frag);
DBG("verifyHeadInline BL1");
- CHK(verifyHeadInline(g_opt.m_blob1, tup.m_blob1, ra1) == 0);
+ CHK(verifyHeadInline(g_blob1, tup.m_bval1, ra1) == 0);
if (! g_opt.m_oneblob) {
DBG("verifyHeadInline BL2");
- CHK(verifyHeadInline(g_opt.m_blob2, tup.m_blob2, ra2) == 0);
+ CHK(verifyHeadInline(g_blob2, tup.m_bval2, ra2) == 0);
}
} else {
CHK(g_con->execute(Commit, AbortOnError) == -1 &&
@@ -792,28 +862,34 @@
}
static int
-verifyBlobTable(const Bcol& b, const Bval& v, Uint32 pk1, bool exists)
+verifyBlobTable(const Bval& v, Uint32 pk1, Uint32 m_frag, bool exists)
{
+ const Bcol& b = v.m_bcol;
DBG("verify " << b.m_btname << " pk1=" << hex << pk1);
NdbRecAttr* ra_pk = 0; // V1
NdbRecAttr* ra_pk1 = 0; // V2
NdbRecAttr* ra_pk2 = 0; // V2
+ NdbRecAttr* ra_pk3 = 0; // V2
NdbRecAttr* ra_part = 0;
NdbRecAttr* ra_data = 0;
+ NdbRecAttr* ra_frag = 0;
CHK((g_con = g_ndb->startTransaction()) != 0);
CHK((g_ops = g_con->getNdbScanOperation(b.m_btname)) != 0);
CHK(g_ops->readTuples() == 0);
- if (g_opt.m_blob_version == 1) {
+ if (b.m_version == 1) {
CHK((ra_pk = g_ops->getValue("PK")) != 0);
CHK((ra_part = g_ops->getValue("PART")) != 0);
CHK((ra_data = g_ops->getValue("DATA")) != 0);
} else {
CHK((ra_pk1 = g_ops->getValue("PK1")) != 0);
- if (g_opt.m_pk2len != 0)
+ if (g_opt.m_pk2len != 0) {
CHK((ra_pk2 = g_ops->getValue("PK2")) != 0);
+ CHK((ra_pk3 = g_ops->getValue("PK3")) != 0);
+ }
CHK((ra_part = g_ops->getValue("NDB$PART")) != 0);
CHK((ra_data = g_ops->getValue("NDB$DATA")) != 0);
}
+ CHK((ra_frag = g_ops->getValue(NdbDictionary::Column::FRAGMENT)) != 0);
CHK(g_con->execute(NoCommit) == 0);
unsigned partcount;
if (! exists || v.m_len <= b.m_inline)
@@ -827,7 +903,7 @@
CHK((ret = g_ops->nextResult()) == 0 || ret == 1);
if (ret == 1)
break;
- if (g_opt.m_blob_version == 1) {
+ if (b.m_version == 1) {
if (pk1 != ra_pk->u_32_value())
continue;
} else {
@@ -844,7 +920,7 @@
if (m > b.m_partsize)
m = b.m_partsize;
const char* data = ra_data->aRef();
- if (g_opt.m_blob_version == 1)
+ if (b.m_version == 1)
;
else {
unsigned sz = getvarsize(data);
@@ -857,6 +933,11 @@
CHK(sz == m);
}
CHK(memcmp(data, v.m_val + n, m) == 0);
+ if (b.m_stripe == 0) {
+ Uint32 frag = ra_frag->u_32_value();
+ CHK(frag == frag);
+ DBG("verified frag id " << frag);
+ }
}
for (unsigned i = 0; i < partcount; i++)
CHK(seen[i] == 1);
@@ -870,9 +951,9 @@
static int
verifyBlobTable(const Tup& tup)
{
- CHK(verifyBlobTable(g_opt.m_blob1, tup.m_blob1, tup.m_pk1, tup.m_exists) == 0);
+ CHK(verifyBlobTable(tup.m_bval1, tup.m_pk1, tup.m_frag, tup.m_exists) == 0);
if (! g_opt.m_oneblob)
- CHK(verifyBlobTable(g_opt.m_blob2, tup.m_blob2, tup.m_pk1, tup.m_exists) == 0);
+ CHK(verifyBlobTable(tup.m_bval2, tup.m_pk1, tup.m_frag, tup.m_exists) == 0);
return 0;
}
@@ -880,7 +961,7 @@
verifyBlob()
{
for (unsigned k = 0; k < g_opt.m_rows; k++) {
- const Tup& tup = g_tups[k];
+ Tup& tup = g_tups[k];
DBG("verifyBlob pk1=" << hex << tup.m_pk1);
CHK(verifyHeadInline(tup) == 0);
CHK(verifyBlobTable(tup) == 0);
@@ -910,8 +991,10 @@
CHK((g_opr = g_con->getNdbOperation(g_opt.m_tname)) != 0);
CHK(g_opr->insertTuple() == 0);
CHK(g_opr->equal("PK1", tup.m_pk1) == 0);
- if (g_opt.m_pk2len != 0)
+ if (g_opt.m_pk2len != 0) {
CHK(g_opr->equal("PK2", tup.m_pk2) == 0);
+ CHK(g_opr->equal("PK3", (char*)&tup.m_pk3) == 0);
+ }
CHK(getBlobHandles(g_opr) == 0);
if (style == 0) {
CHK(setBlobValue(tup) == 0);
@@ -957,8 +1040,10 @@
else
CHK(g_opr->readTuple(NdbOperation::LM_CommittedRead) == 0);
CHK(g_opr->equal("PK1", tup.m_pk1) == 0);
- if (g_opt.m_pk2len != 0)
+ if (g_opt.m_pk2len != 0) {
CHK(g_opr->equal("PK2", tup.m_pk2) == 0);
+ CHK(g_opr->equal("PK3", (char*)&tup.m_pk3) == 0);
+ }
CHK(getBlobHandles(g_opr) == 0);
if (style == 0) {
CHK(getBlobValue(tup) == 0);
@@ -1004,8 +1089,10 @@
CHK(g_opr->readTuple() == 0);
}
CHK(g_opr->equal("PK1", tup.m_pk1) == 0);
- if (g_opt.m_pk2len != 0)
+ if (g_opt.m_pk2len != 0) {
CHK(g_opr->equal("PK2", tup.m_pk2) == 0);
+ CHK(g_opr->equal("PK3", (char*)&tup.m_pk3) == 0);
+ }
CHK(getBlobHandles(g_opr) == 0);
if (style == 0) {
CHK(setBlobValue(tup, error_code) == 0);
@@ -1040,8 +1127,10 @@
CHK((g_opr = g_con->getNdbOperation(g_opt.m_tname)) != 0);
CHK(g_opr->writeTuple() == 0);
CHK(g_opr->equal("PK1", tup.m_pk1) == 0);
- if (g_opt.m_pk2len != 0)
+ if (g_opt.m_pk2len != 0) {
CHK(g_opr->equal("PK2", tup.m_pk2) == 0);
+ CHK(g_opr->equal("PK3", (char*)&tup.m_pk3) == 0);
+ }
CHK(getBlobHandles(g_opr) == 0);
if (style == 0) {
CHK(setBlobValue(tup) == 0);
@@ -1076,8 +1165,10 @@
CHK((g_opr = g_con->getNdbOperation(g_opt.m_tname)) != 0);
CHK(g_opr->deleteTuple() == 0);
CHK(g_opr->equal("PK1", tup.m_pk1) == 0);
- if (g_opt.m_pk2len != 0)
+ if (g_opt.m_pk2len != 0) {
CHK(g_opr->equal("PK2", tup.m_pk2) == 0);
+ CHK(g_opr->equal("PK3", (char*)&tup.m_pk3) == 0);
+ }
if (++n == g_opt.m_batch) {
CHK(g_con->execute(Commit) == 0);
g_ndb->closeTransaction(g_con);
@@ -1112,6 +1203,7 @@
else
CHK(g_opx->readTuple(NdbOperation::LM_CommittedRead) == 0);
CHK(g_opx->equal("PK2", tup.m_pk2) == 0);
+ CHK(g_opx->equal("PK3", (char*)&tup.m_pk3) == 0);
CHK(getBlobHandles(g_opx) == 0);
if (style == 0) {
CHK(getBlobValue(tup) == 0);
@@ -1146,6 +1238,7 @@
CHK((g_opx = g_con->getNdbIndexOperation(g_opt.m_x1name, g_opt.m_tname)) != 0);
CHK(g_opx->updateTuple() == 0);
CHK(g_opx->equal("PK2", tup.m_pk2) == 0);
+ CHK(g_opx->equal("PK3", (char*)&tup.m_pk3) == 0);
CHK(getBlobHandles(g_opx) == 0);
if (style == 0) {
CHK(setBlobValue(tup) == 0);
@@ -1175,6 +1268,7 @@
CHK((g_opx = g_con->getNdbIndexOperation(g_opt.m_x1name, g_opt.m_tname)) != 0);
CHK(g_opx->writeTuple() == 0);
CHK(g_opx->equal("PK2", tup.m_pk2) == 0);
+ CHK(g_opx->equal("PK3", (char*)&tup.m_pk3) == 0);
CHK(getBlobHandles(g_opx) == 0);
if (style == 0) {
CHK(setBlobValue(tup) == 0);
@@ -1209,6 +1303,7 @@
CHK((g_opx = g_con->getNdbIndexOperation(g_opt.m_x1name, g_opt.m_tname)) != 0);
CHK(g_opx->deleteTuple() == 0);
CHK(g_opx->equal("PK2", tup.m_pk2) == 0);
+ CHK(g_opx->equal("PK3", (char*)&tup.m_pk3) == 0);
if (++n == g_opt.m_batch) {
CHK(g_con->execute(Commit) == 0);
g_ndb->closeTransaction(g_con);
@@ -1244,8 +1339,10 @@
else
CHK(g_ops->readTuples(NdbOperation::LM_CommittedRead) == 0);
CHK(g_ops->getValue("PK1", (char*)&tup.m_pk1) != 0);
- if (g_opt.m_pk2len != 0)
+ if (g_opt.m_pk2len != 0) {
CHK(g_ops->getValue("PK2", tup.m_pk2) != 0);
+ CHK(g_ops->getValue("PK3", (char*)&tup.m_pk3) != 0);
+ }
CHK(getBlobHandles(g_ops) == 0);
if (style == 0) {
CHK(getBlobValue(tup) == 0);
@@ -1298,8 +1395,10 @@
}
CHK(g_ops->readTuples(NdbOperation::LM_Exclusive) == 0);
CHK(g_ops->getValue("PK1", (char*)&tup.m_pk1) != 0);
- if (g_opt.m_pk2len != 0)
+ if (g_opt.m_pk2len != 0) {
CHK(g_ops->getValue("PK2", tup.m_pk2) != 0);
+ CHK(g_ops->getValue("PK3", (char*)&tup.m_pk3) != 0);
+ }
CHK(g_con->execute(NoCommit) == 0);
unsigned rows = 0;
while (1) {
@@ -1351,8 +1450,10 @@
}
CHK(g_ops->readTuples(NdbOperation::LM_Exclusive) == 0);
CHK(g_ops->getValue("PK1", (char*)&tup.m_pk1) != 0);
- if (g_opt.m_pk2len != 0)
+ if (g_opt.m_pk2len != 0) {
CHK(g_ops->getValue("PK2", tup.m_pk2) != 0);
+ CHK(g_ops->getValue("PK3", (char*)&tup.m_pk3) != 0);
+ }
CHK(g_con->execute(NoCommit) == 0);
unsigned rows = 0;
unsigned n = 0;
@@ -1411,14 +1512,15 @@
CHK(g_ndb->init(20) == 0);
CHK(g_ndb->waitUntilReady() == 0);
g_dic = g_ndb->getDictionary();
+ initblobs();
g_tups = new Tup [g_opt.m_rows];
CHK(dropTable() == 0);
CHK(createTable() == 0);
- Bcol& b1 = g_opt.m_blob1;
+ Bcol& b1 = g_blob1;
CHK(NdbBlob::getBlobTableName(b1.m_btname, g_ndb, g_opt.m_tname, "BL1") == 0);
DBG("BL1: inline=" << b1.m_inline << " part=" << b1.m_partsize << " table=" << b1.m_btname);
if (! g_opt.m_oneblob) {
- Bcol& b2 = g_opt.m_blob2;
+ Bcol& b2 = g_blob2;
CHK(NdbBlob::getBlobTableName(b2.m_btname, g_ndb, g_opt.m_tname, "BL2") == 0);
DBG("BL2: inline=" << b2.m_inline << " part=" << b2.m_partsize << " table=" << b2.m_btname);
}
@@ -1444,12 +1546,12 @@
continue;
DBG("--- pk ops " << stylename[style] << " ---");
if (testcase('n')) {
- calcTups(false);
+ calcTups(true, false);
CHK(insertPk(style) == 0);
CHK(verifyBlob() == 0);
CHK(readPk(style) == 0);
if (testcase('u')) {
- calcTups(style);
+ calcTups(false, style);
CHK(updatePk(style) == 0);
CHK(verifyBlob() == 0);
CHK(readPk(style) == 0);
@@ -1458,12 +1560,12 @@
CHK(verifyBlob() == 0);
}
if (testcase('w')) {
- calcTups(false);
+ calcTups(false, false);
CHK(writePk(style) == 0);
CHK(verifyBlob() == 0);
CHK(readPk(style) == 0);
if (testcase('u')) {
- calcTups(style);
+ calcTups(false, style);
CHK(writePk(style) == 0);
CHK(verifyBlob() == 0);
CHK(readPk(style) == 0);
@@ -1478,12 +1580,12 @@
continue;
DBG("--- idx ops " << stylename[style] << " ---");
if (testcase('n')) {
- calcTups(false);
+ calcTups(true, false);
CHK(insertPk(style) == 0);
CHK(verifyBlob() == 0);
CHK(readIdx(style) == 0);
if (testcase('u')) {
- calcTups(style);
+ calcTups(false, style);
CHK(updateIdx(style) == 0);
CHK(verifyBlob() == 0);
CHK(readIdx(style) == 0);
@@ -1492,12 +1594,12 @@
CHK(verifyBlob() == 0);
}
if (testcase('w')) {
- calcTups(false);
+ calcTups(false, false);
CHK(writePk(style) == 0);
CHK(verifyBlob() == 0);
CHK(readIdx(style) == 0);
if (testcase('u')) {
- calcTups(style);
+ calcTups(false, style);
CHK(writeIdx(style) == 0);
CHK(verifyBlob() == 0);
CHK(readIdx(style) == 0);
@@ -1511,7 +1613,7 @@
if (! testcase('s') || ! testcase(style))
continue;
DBG("--- table scan " << stylename[style] << " ---");
- calcTups(false);
+ calcTups(true, false);
CHK(insertPk(style) == 0);
CHK(verifyBlob() == 0);
CHK(readScan(style, false) == 0);
@@ -1527,7 +1629,7 @@
if (! testcase('r') || ! testcase(style))
continue;
DBG("--- index scan " << stylename[style] << " ---");
- calcTups(false);
+ calcTups(true, false);
CHK(insertPk(style) == 0);
CHK(verifyBlob() == 0);
CHK(readScan(style, true) == 0);
@@ -1843,7 +1945,7 @@
unsigned i;
DBG("bug test 4088 - ndb api hang with mixed ops on index table");
// insert rows
- calcTups(false);
+ calcTups(true, false);
CHK(insertPk(false) == 0);
// new trans
CHK((g_con = g_ndb->startTransaction()) != 0);
@@ -1865,8 +1967,8 @@
CHK((g_opx = g_con->getNdbIndexOperation(g_opt.m_x1name, g_opt.m_tname)) != 0);
CHK(g_opx->readTuple() == 0);
CHK(g_opx->equal("PK2", tup.m_pk2) == 0);
- assert(tup.m_blob1.m_buf != 0);
- CHK(g_opx->getValue("BL1", (char*)tup.m_blob1.m_buf) != 0);
+ assert(tup.m_bval1.m_buf != 0);
+ CHK(g_opx->getValue("BL1", (char*)tup.m_bval1.m_buf) != 0);
// execute
// BUG 4088: gets 1 tckeyconf, 1 tcindxconf, then hangs
CHK(g_con->execute(Commit) == 0);
@@ -1875,7 +1977,7 @@
CHK(pktup[i].m_pk1 == tup.m_pk1);
CHK(memcmp(pktup[i].m_pk2, tup.m_pk2, g_opt.m_pk2len) == 0);
}
- CHK(memcmp(tup.m_blob1.m_val, tup.m_blob1.m_buf, 8 + g_opt.m_blob1.m_inline) == 0);
+ CHK(memcmp(tup.m_bval1.m_val, tup.m_bval1.m_buf, 8 + g_blob1.m_inline) == 0);
}
return 0;
}
@@ -1886,7 +1988,7 @@
DBG("bug test 27018 - middle partial part write clobbers rest of part");
// insert rows
- calcTups(false);
+ calcTups(true, false);
CHK(insertPk(false) == 0);
// new trans
for (unsigned k= 0; k < g_opt.m_rows; k++)
@@ -1894,25 +1996,27 @@
Tup& tup= g_tups[k];
/* Update one byte in random position. */
- Uint32 offset= urandom(tup.m_blob1.m_len + 1);
- if (offset == tup.m_blob1.m_len) {
+ Uint32 offset= urandom(tup.m_bval1.m_len + 1);
+ if (offset == tup.m_bval1.m_len) {
// testing write at end is another problem..
continue;
}
- //DBG("len=" << tup.m_blob1.m_len << " offset=" << offset);
+ //DBG("len=" << tup.m_bval1.m_len << " offset=" << offset);
CHK((g_con= g_ndb->startTransaction()) != 0);
CHK((g_opr= g_con->getNdbOperation(g_opt.m_tname)) != 0);
CHK(g_opr->updateTuple() == 0);
CHK(g_opr->equal("PK1", tup.m_pk1) == 0);
- if (g_opt.m_pk2len != 0)
+ if (g_opt.m_pk2len != 0) {
CHK(g_opr->equal("PK2", tup.m_pk2) == 0);
+ CHK(g_opr->equal("PK3", (char*)&tup.m_pk3) == 0);
+ }
CHK(getBlobHandles(g_opr) == 0);
CHK(g_con->execute(NoCommit) == 0);
- tup.m_blob1.m_buf[0]= 0xff ^ tup.m_blob1.m_val[offset];
+ tup.m_bval1.m_buf[0]= 0xff ^ tup.m_bval1.m_val[offset];
CHK(g_bh1->setPos(offset) == 0);
- CHK(g_bh1->writeData(&(tup.m_blob1.m_buf[0]), 1) == 0);
+ CHK(g_bh1->writeData(&(tup.m_bval1.m_buf[0]), 1) == 0);
CHK(g_con->execute(Commit) == 0);
g_ndb->closeTransaction(g_con);
@@ -1920,17 +2024,19 @@
CHK((g_opr= g_con->getNdbOperation(g_opt.m_tname)) != 0);
CHK(g_opr->readTuple() == 0);
CHK(g_opr->equal("PK1", tup.m_pk1) == 0);
- if (g_opt.m_pk2len != 0)
+ if (g_opt.m_pk2len != 0) {
CHK(g_opr->equal("PK2", tup.m_pk2) == 0);
+ CHK(g_opr->equal("PK3", (char*)&tup.m_pk3) == 0);
+ }
CHK(getBlobHandles(g_opr) == 0);
- CHK(g_bh1->getValue(tup.m_blob1.m_buf, tup.m_blob1.m_len) == 0);
+ CHK(g_bh1->getValue(tup.m_bval1.m_buf, tup.m_bval1.m_len) == 0);
CHK(g_con->execute(Commit) == 0);
Uint64 len= ~0;
- CHK(g_bh1->getLength(len) == 0 && len == tup.m_blob1.m_len);
- tup.m_blob1.m_buf[offset]^= 0xff;
- CHK(memcmp(tup.m_blob1.m_buf, tup.m_blob1.m_val, tup.m_blob1.m_len) == 0);
+ CHK(g_bh1->getLength(len) == 0 && len == tup.m_bval1.m_len);
+ tup.m_bval1.m_buf[offset]^= 0xff;
+ CHK(memcmp(tup.m_bval1.m_buf, tup.m_bval1.m_val, tup.m_bval1.m_len) == 0);
g_ndb->closeTransaction(g_con);
}
@@ -2012,8 +2118,6 @@
}
if (strcmp(arg, "-min") == 0) {
g_opt.m_min = true;
- new (&g_opt.m_blob1) Bcol(TEST_BLOBS_MIN_SIZE1);
- new (&g_opt.m_blob2) Bcol(TEST_BLOBS_MIN_SIZE2);
continue;
}
if (strcmp(arg, "-parts") == 0) {
@@ -2067,6 +2171,18 @@
continue;
}
}
+ if (strcmp(arg, "-pk2fixed") == 0) {
+ g_opt.m_pk2fixed = true;
+ continue;
+ }
+ if (strcmp(arg, "-pk2binary") == 0) {
+ g_opt.m_pk2binary = true;
+ continue;
+ }
+ if (strcmp(arg, "-pk2part") == 0) {
+ g_opt.m_pk2part = true;
+ continue;
+ }
if (strcmp(arg, "-oneblob") == 0) {
g_opt.m_oneblob = true;
continue;
@@ -2108,6 +2224,21 @@
strcat(b, "i");
strcat(b, "r");
g_opt.m_skip = strdup(b);
+ }
+ if (g_opt.m_pk2len != 0) {
+ if (g_opt.m_pk2fixed) {
+ if (g_opt.m_pk2binary)
+ g_opt.m_pk2type = NdbDictionary::Column::Binary;
+ else
+ g_opt.m_pk2type = NdbDictionary::Column::Char;
+ g_opt.m_pk2totlen = g_opt.m_pk2len;
+ } else {
+ if (g_opt.m_pk2binary)
+ g_opt.m_pk2type = NdbDictionary::Column::Varbinary;
+ else
+ g_opt.m_pk2type = NdbDictionary::Column::Varchar;
+ g_opt.m_pk2totlen = 1 + g_opt.m_pk2len;
+ }
}
ndbout << cmdline << endl;
g_ncc = new Ndb_cluster_connection();
--- 1.27/storage/ndb/include/ndbapi/NdbBlob.hpp 2007-03-28 18:37:05 +02:00
+++ 1.28/storage/ndb/include/ndbapi/NdbBlob.hpp 2007-03-31 18:25:51 +02:00
@@ -295,13 +295,13 @@
int theEventBlobVersion; // -1=normal blob 0=post event 1=pre event
// define blob table
static void getBlobTableName(char* btname, const NdbTableImpl* t, const NdbColumnImpl* c);
- static void getBlobTable(NdbTableImpl& bt, const NdbTableImpl* t, const NdbColumnImpl* c);
+ static int getBlobTable(NdbTableImpl& bt, const NdbTableImpl* t, const NdbColumnImpl* c, struct NdbError& error);
static void getBlobEventName(char* bename, const NdbEventImpl* e, const NdbColumnImpl* c);
static void getBlobEvent(NdbEventImpl& be, const NdbEventImpl* e, const NdbColumnImpl* c);
// compute blob table column number for faster access
enum {
BtColumnPk = 0, /* V1 only */
- BtColumnDist = 1,
+ BtColumnDist = 1, /* if stripe size != 0 */
BtColumnPart = 2,
BtColumnPkid = 3, /* V2 only */
BtColumnData = 4
@@ -403,6 +403,7 @@
int getTableKeyValue(NdbOperation* anOp);
int setTableKeyValue(NdbOperation* anOp);
int setAccessKeyValue(NdbOperation* anOp);
+ int setDistKeyValue(NdbOperation* anOp, Uint32 part);
int setPartKeyValue(NdbOperation* anOp, Uint32 part);
int setPartPkidValue(NdbOperation* anOp, Uint32 pkid);
int getPartDataValue(NdbOperation* anOp, char* buf, Uint16* aLenLoc);
--- 1.57/storage/ndb/src/ndbapi/NdbBlob.cpp 2007-03-28 18:37:06 +02:00
+++ 1.58/storage/ndb/src/ndbapi/NdbBlob.cpp 2007-03-31 18:25:51 +02:00
@@ -83,8 +83,8 @@
DBUG_VOID_RETURN;
}
-void
-NdbBlob::getBlobTable(NdbTableImpl& bt, const NdbTableImpl* t, const NdbColumnImpl* c)
+int
+NdbBlob::getBlobTable(NdbTableImpl& bt, const NdbTableImpl* t, const NdbColumnImpl* c, NdbError& error)
{
DBUG_ENTER("NdbBlob::getBlobTable");
const int blobVersion = c->m_blobVersion;
@@ -131,6 +131,14 @@
blobVersion,
bt.m_primaryTableId, (uint)bt.getFragmentType()));
if (unlikely(blobVersion == NDB_BLOB_V1)) {
+ /*
+ * Stripe size 0 in V1 does not work as intended.
+ * No point to add support for it now.
+ */
+ if (c->getStripeSize() == 0) {
+ error.code = NdbBlobImpl::ErrTable;
+ DBUG_RETURN(-1);
+ }
{ NdbDictionary::Column bc("PK");
bc.setType(NdbDictionary::Column::Unsigned);
assert(t->m_keyLenInWords != 0);
@@ -176,15 +184,22 @@
uint i;
for (i = 0; n < noOfKeys; i++) {
assert(i < columns);
- NdbColumnImpl* c = t->m_columns[i];
+ const NdbColumnImpl* c = t->getColumn(i);
assert(c != NULL);
if (c->m_pk) {
bt.addColumn(*c);
+ if (c->getDistributionKey()) {
+ // addColumn might usefully return the column added..
+ NdbColumnImpl* bc = bt.getColumn(n);
+ assert(bc != NULL);
+ bc->setDistributionKey(true);
+ }
n++;
}
}
}
// in V2 add NDB$ to avoid conflict with table PK
+ if (c->getStripeSize() != 0)
{ NdbDictionary::Column bc("NDB$DIST");
bc.setType(NdbDictionary::Column::Unsigned);
bc.setPrimaryKey(true);
@@ -194,12 +209,8 @@
{ NdbDictionary::Column bc("NDB$PART");
bc.setType(NdbDictionary::Column::Unsigned);
bc.setPrimaryKey(true);
- /*
- * Cannot allow partial distribution key now because
- * primary table PK may contain unsupported types.
- * Must be fixed. All PK types must be supported.
- */
- bc.setDistributionKey(true);
+ // wl3717_todo all PK types must be allowed as DK
+ bc.setDistributionKey(false);
bt.addColumn(bc);
}
// in V2 add id sequence for use in blob event code
@@ -228,7 +239,7 @@
bt.addColumn(bc);
}
}
- DBUG_VOID_RETURN;
+ DBUG_RETURN(0);
}
int
@@ -756,10 +767,23 @@
}
int
+NdbBlob::setDistKeyValue(NdbOperation* anOp, Uint32 part)
+{
+ DBUG_ENTER("NdbBlob::setDistKeyValue");
+ if (theStripeSize != 0) {
+ Uint32 dist = getDistKey(part);
+ DBUG_PRINT("info", ("dist=%u", dist));
+ if (anOp->equal(theBtColumnNo[BtColumnDist], dist) == -1)
+ DBUG_RETURN(-1);
+ }
+ DBUG_RETURN(0);
+}
+
+int
NdbBlob::setPartKeyValue(NdbOperation* anOp, Uint32 part)
{
DBUG_ENTER("NdbBlob::setPartKeyValue");
- DBUG_PRINT("info", ("dist=%u part=%u packkey=", getDistKey(part), part));
+ DBUG_PRINT("info", ("part=%u packkey=", part));
DBUG_DUMP("info", thePackKeyBuf.data, 4 * thePackKeyBuf.size);
// TODO use attr ids after compatibility with 4.1.7 not needed
if (unlikely(theBlobVersion == NDB_BLOB_V1)) {
@@ -772,7 +796,7 @@
}
} else {
if (setTableKeyValue(anOp) == -1 ||
- anOp->equal(theBtColumnNo[BtColumnDist], getDistKey(part)) == -1 ||
+ setDistKeyValue(anOp, part) == -1 ||
anOp->equal(theBtColumnNo[BtColumnPart], part) == -1) {
setErrorCode(anOp);
DBUG_RETURN(-1);
@@ -1820,6 +1844,7 @@
buf = thePackKeyBuf.data;
theBlobEventPkRecAttr = theBlobEventOp->getValue(bc, buf, version);
//
+ assert(theStripeSize != 0);
bc = theBlobTable->getColumn(theBtColumnNo[BtColumnDist]);
buf = (char*)&theBlobEventDistValue;
theBlobEventDistRecAttr = theBlobEventOp->getValue(bc, buf, version);
@@ -1861,9 +1886,11 @@
n++;
}
}
- bc = theBlobTable->getColumn(theBtColumnNo[BtColumnDist]);
- buf = (char*)&theBlobEventDistValue;
- theBlobEventDistRecAttr = theBlobEventOp->getValue(bc, buf, version);
+ if (theStripeSize != 0) {
+ bc = theBlobTable->getColumn(theBtColumnNo[BtColumnDist]);
+ buf = (char*)&theBlobEventDistValue;
+ theBlobEventDistRecAttr = theBlobEventOp->getValue(bc, buf, version);
+ }
//
bc = theBlobTable->getColumn(theBtColumnNo[BtColumnPart]);
buf = (char*)&theBlobEventPartValue;
@@ -1877,7 +1904,7 @@
buf = theBlobEventDataBuf.data;
theBlobEventDataRecAttr = theBlobEventOp->getValue(bc, buf, version);
if (unlikely(
- theBlobEventDistRecAttr == NULL ||
+ (theStripeSize != 0 && theBlobEventDistRecAttr == NULL) ||
theBlobEventPartRecAttr == NULL ||
theBlobEventPkidRecAttr == NULL ||
theBlobEventDataRecAttr == NULL
@@ -1896,7 +1923,12 @@
{
DBUG_ENTER("prepareColumn");
NdbDictionary::Column::Type partType = NdbDictionary::Column::Undefined;
+ //
theBlobVersion = theColumn->m_blobVersion;
+ theInlineSize = theColumn->getInlineSize();
+ thePartSize = theColumn->getPartSize();
+ theStripeSize = theColumn->getStripeSize();
+ //
if (unlikely(theBlobVersion == NDB_BLOB_V1)) {
theHeadSize = (NDB_BLOB_V1_HEAD_SIZE << 2);
theVarsizeBytes = 0;
@@ -1913,6 +1945,8 @@
setErrorCode(NdbBlobImpl::ErrUsage);
DBUG_RETURN(-1);
}
+ // in V1 stripe size is != 0 (except tinyblob)
+ assert(!(thePartSize != 0 && theStripeSize == 0));
theBtColumnNo[BtColumnPk] = 0;
theBtColumnNo[BtColumnDist] = 1;
theBtColumnNo[BtColumnPart] = 2;
@@ -1931,26 +1965,24 @@
setErrorCode(NdbBlobImpl::ErrUsage);
DBUG_RETURN(-1);
}
- uint noOfKeys = theTable->m_noOfKeys;
- theBtColumnNo[BtColumnDist] = noOfKeys + 0;
- theBtColumnNo[BtColumnPart] = noOfKeys + 1;
- theBtColumnNo[BtColumnPkid] = noOfKeys + 2;
- theBtColumnNo[BtColumnData] = noOfKeys + 3;
+ uint off = theTable->m_noOfKeys;
+ if (theStripeSize != 0) {
+ theBtColumnNo[BtColumnDist] = off;
+ off += 1;
+ }
+ theBtColumnNo[BtColumnPart] = off + 0;
+ theBtColumnNo[BtColumnPkid] = off + 1;
+ theBtColumnNo[BtColumnData] = off + 2;
} else {
setErrorCode(NdbBlobImpl::ErrUsage);
DBUG_RETURN(-1);
}
- // sizes
- theInlineSize = theColumn->getInlineSize();
- thePartSize = theColumn->getPartSize();
- theStripeSize = theColumn->getStripeSize();
// sanity check
assert(theColumn->m_attrSize * theColumn->m_arraySize == theHeadSize + theInlineSize);
if (thePartSize > 0) {
const NdbTableImpl* bt = NULL;
const NdbColumnImpl* bc = NULL;
- if (theStripeSize == 0 ||
- (bt = theColumn->m_blobTable) == NULL ||
+ if ((bt = theColumn->m_blobTable) == NULL ||
(bc = bt->getColumn(theBtColumnNo[BtColumnData])) == NULL ||
bc->getType() != partType ||
bc->getLength() != (int)thePartSize) {
--- 1.16/storage/ndb/test/ndbapi/test_event_merge.cpp 2007-03-24 17:38:52 +01:00
+++ 1.17/storage/ndb/test/ndbapi/test_event_merge.cpp 2007-03-31 18:25:52 +02:00
@@ -79,6 +79,7 @@
const char* opstring;
uint seed;
int maxtab;
+ my_bool pk2binary;
my_bool separate_events;
uint tweak; // whatever's useful
my_bool use_table;
@@ -105,7 +106,6 @@
static uint g_blobinlinesize = 256;
static uint g_blobpartsize = 2000;
-static uint g_blobstripesize = 2;
static const uint g_maxblobsize = 100000;
static NdbEventOperation* g_evt_op = 0;
@@ -209,6 +209,9 @@
bool nullable;
uint length;
uint size;
+ uint inlinesize;
+ uint partsize;
+ uint stripesize;
bool isblob() const {
return
type == NdbDictionary::Column::Text ||
@@ -216,14 +219,29 @@
}
};
-static const Col g_col[] = {
- { 0, "pk1", NdbDictionary::Column::Unsigned, true, false, 1, 4 },
- { 1, "pk2", NdbDictionary::Column::Char, true, false, g_charlen, g_charlen },
- { 2, "seq", NdbDictionary::Column::Unsigned, false, false, 1, 4 },
- { 3, "cc1", NdbDictionary::Column::Char, false, true, g_charlen, g_charlen },
- { 4, "tx1", NdbDictionary::Column::Text, false, true, 0, 0 },
- { 5, "tx2", NdbDictionary::Column::Text, false, true, 0, 0 },
- { 6, "bl1", NdbDictionary::Column::Blob, false, true, 0, 0 } // tinyblob
+// not const, options may modify
+static Col g_col[] = {
+ { 0, "pk1", NdbDictionary::Column::Unsigned,
+ true, false,
+ 1, 4, 0, 0, 0 },
+ { 1, "pk2", NdbDictionary::Column::Char,
+ true, false,
+ g_charlen, g_charlen, 0, 0, 0 },
+ { 2, "seq", NdbDictionary::Column::Unsigned,
+ false, true,
+ 1, 4, 0, 0, 0 },
+ { 3, "cc1", NdbDictionary::Column::Char,
+ false, true,
+ g_charlen, g_charlen, 0, 0, 0 },
+ { 4, "tx1", NdbDictionary::Column::Text,
+ false, true,
+ 0, 0, g_blobinlinesize, g_blobpartsize, 0 }, // V2 distribution
+ { 5, "tx2", NdbDictionary::Column::Text,
+ false, true,
+ 0, 0, g_blobinlinesize, g_blobpartsize, 4 },
+ { 6, "bl1", NdbDictionary::Column::Blob, // tinyblob
+ false, true,
+ 0, 0, g_blobinlinesize, 0, 0 }
};
static const uint g_maxcol = sizeof(g_col)/sizeof(g_col[0]);
@@ -240,7 +258,7 @@
return n;
}
-static const Col&
+static Col&
getcol(uint i)
{
if (i < ncol())
@@ -249,7 +267,7 @@
return g_col[0];
}
-static const Col&
+static Col&
getcol(const char* name)
{
uint i;
@@ -305,9 +323,7 @@
NdbDictionary::Column col(c.name);
col.setType(c.type);
col.setPrimaryKey(c.pk);
- if (! c.pk)
- col.setNullable(true);
- col.setLength(c.length);
+ col.setNullable(c.nullable);
switch (c.type) {
case NdbDictionary::Column::Unsigned:
break;
@@ -315,18 +331,21 @@
col.setLength(c.length);
col.setCharset(cs);
break;
+ case NdbDictionary::Column::Binary:
+ col.setLength(c.length);
+ break;
case NdbDictionary::Column::Text:
col.setBlobVersion(g_opts.blob_version);
- col.setInlineSize(g_blobinlinesize);
- col.setPartSize(g_blobpartsize);
- col.setStripeSize(g_blobstripesize);
+ col.setInlineSize(c.inlinesize);
+ col.setPartSize(c.partsize);
+ col.setStripeSize(c.stripesize);
col.setCharset(cs);
break;
case NdbDictionary::Column::Blob:
col.setBlobVersion(g_opts.blob_version);
- col.setInlineSize(g_blobinlinesize);
- col.setPartSize(0);
- col.setStripeSize(0);
+ col.setInlineSize(c.inlinesize);
+ col.setPartSize(c.partsize);
+ col.setStripeSize(c.stripesize);
break;
default:
assert(false);
@@ -509,6 +528,7 @@
return 1;
break;
case NdbDictionary::Column::Char:
+ case NdbDictionary::Column::Binary:
if (memcmp(d1.ptr[i].ch, d2.ptr[i].ch, c.size) != 0)
return 1;
break;
@@ -550,6 +570,7 @@
out << *d.ptr[i].u32;
break;
case NdbDictionary::Column::Char:
+ case NdbDictionary::Column::Binary:
{
char buf[g_charlen + 1];
memcpy(buf, d.ptr[i].ch, g_charlen);
@@ -1314,6 +1335,7 @@
}
break;
case NdbDictionary::Column::Char:
+ case NdbDictionary::Column::Binary:
{
char* p = d.ptr[i].ch;
sprintf(p, "%-*u", g_charlen, pk1);
@@ -1347,6 +1369,7 @@
}
break;
case NdbDictionary::Column::Char:
+ case NdbDictionary::Column::Binary:
{
char* p = d.ptr[i].ch;
uint u = urandom(g_charlen);
@@ -2242,6 +2265,9 @@
{ "blob-version", 1018, "Blob version 1 or 2 (default 2)",
(gptr*)&g_opts.blob_version, (gptr*)&g_opts.blob_version, 0,
GET_INT, REQUIRED_ARG, 2, 0, 0, 0, 0, 0 },
+ { "pk2binary", 1019, "Make pk2 binary",
+ (gptr*)&g_opts.pk2binary, (gptr*)&g_opts.pk2binary, 0,
+ GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0 },
{ 0, 0, 0,
0, 0, 0,
GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0 }
@@ -2256,9 +2282,6 @@
static int
checkopts()
{
- if (g_opts.blob_version < 1 || g_opts.blob_version > 2) {
- return -1;
- }
if (g_opts.separate_events) {
g_opts.no_blobs = true;
}
@@ -2298,6 +2321,17 @@
if (g_opts.maxpk > g_maxpk ||
g_opts.maxtab > g_maxtab) {
return -1;
+ }
+ if (g_opts.blob_version < 1 || g_opts.blob_version > 2) {
+ return -1;
+ }
+ if (g_opts.blob_version == 1 && ! g_opts.no_blobs) {
+ Col& c = getcol("tx1");
+ c.stripesize = 4;
+ }
+ if (g_opts.pk2binary) {
+ Col& c = getcol("pk2");
+ c.type = NdbDictionary::Column::Binary;
}
return 0;
}
| Thread |
|---|
| • bk commit into 5.1 tree (pekka:1.2504) | pekka | 31 Mar |