mirror of
https://github.com/MariaDB/server.git
synced 2025-08-07 00:04:31 +03:00
ndb - bitfields - more tests, now passes all api tests!!
ndb/include/kernel/ndb_limits.h: #define for max null bits ndb/include/kernel/signaldata/TupFrag.hpp: Error code for too many nullbits ndb/include/util/Bitmask.hpp: Cosmetic fix ndb/src/common/util/Bitmask.cpp: handle (pos % 32) == 0 more unit tests ndb/src/kernel/blocks/dbtup/DbtupMeta.cpp: Check bitmask overflow ndb/src/ndbapi/ndberror.c: New error code ndb/test/ndbapi/testBitfield.cpp: Update test program ndb/test/run-test/daily-basic-tests.txt: Add testBitfield to autotest
This commit is contained in:
@@ -61,6 +61,7 @@
|
|||||||
#define MAX_FIXED_KEY_LENGTH_IN_WORDS 8
|
#define MAX_FIXED_KEY_LENGTH_IN_WORDS 8
|
||||||
#define MAX_KEY_SIZE_IN_WORDS 1023
|
#define MAX_KEY_SIZE_IN_WORDS 1023
|
||||||
#define MAX_FRM_DATA_SIZE 6000
|
#define MAX_FRM_DATA_SIZE 6000
|
||||||
|
#define MAX_NULL_BITS 4096
|
||||||
|
|
||||||
#define MIN_ATTRBUF ((MAX_ATTRIBUTES_IN_TABLE/24) + 1)
|
#define MIN_ATTRBUF ((MAX_ATTRIBUTES_IN_TABLE/24) + 1)
|
||||||
/*
|
/*
|
||||||
|
@@ -145,7 +145,8 @@ public:
|
|||||||
STATIC_CONST( SignalLength = 2 );
|
STATIC_CONST( SignalLength = 2 );
|
||||||
enum ErrorCode {
|
enum ErrorCode {
|
||||||
NoError = 0,
|
NoError = 0,
|
||||||
InvalidCharset = 743
|
InvalidCharset = 743,
|
||||||
|
TooManyBitsUsed = 831
|
||||||
};
|
};
|
||||||
private:
|
private:
|
||||||
Uint32 userPtr;
|
Uint32 userPtr;
|
||||||
|
@@ -818,7 +818,7 @@ BitmaskImpl::getField(unsigned size, const Uint32 src[],
|
|||||||
|
|
||||||
src += (pos >> 5);
|
src += (pos >> 5);
|
||||||
Uint32 offset = pos & 31;
|
Uint32 offset = pos & 31;
|
||||||
dst[0] = (* src >> offset) & (len >= 32 ? ~0 : (1 << len) - 1);
|
* dst = (* src >> offset) & (len >= 32 ? ~0 : (1 << len) - 1);
|
||||||
|
|
||||||
if(offset + len <= 32)
|
if(offset + len <= 32)
|
||||||
{
|
{
|
||||||
|
@@ -26,6 +26,9 @@ BitmaskImpl::getFieldImpl(const Uint32 src[],
|
|||||||
|
|
||||||
unsigned shiftR = 32 - shiftL;
|
unsigned shiftR = 32 - shiftL;
|
||||||
unsigned undefined = shiftL ? ~0 : 0;
|
unsigned undefined = shiftL ? ~0 : 0;
|
||||||
|
|
||||||
|
* dst = shiftL ? * dst : 0;
|
||||||
|
|
||||||
while(len >= 32)
|
while(len >= 32)
|
||||||
{
|
{
|
||||||
* dst++ |= (* src) << shiftL;
|
* dst++ |= (* src) << shiftL;
|
||||||
@@ -169,6 +172,69 @@ void simple(int pos, int size)
|
|||||||
require(cmp(src, dst, size+31));
|
require(cmp(src, dst, size+31));
|
||||||
};
|
};
|
||||||
|
|
||||||
|
static
|
||||||
|
void simple2(int size, int loops)
|
||||||
|
{
|
||||||
|
ndbout_c("simple2 %d - ", size);
|
||||||
|
Vector<Uint32> _mask;
|
||||||
|
Vector<Uint32> _src;
|
||||||
|
Vector<Uint32> _dst;
|
||||||
|
|
||||||
|
Uint32 sz32 = (size + 32) >> 5;
|
||||||
|
Uint32 sz = sz32 << 2;
|
||||||
|
|
||||||
|
Uint32 zero = 0;
|
||||||
|
_mask.fill(sz32+1, zero);
|
||||||
|
_src.fill(sz32+1, zero);
|
||||||
|
_dst.fill(sz32+1, zero);
|
||||||
|
|
||||||
|
Uint32 * src = _src.getBase();
|
||||||
|
Uint32 * dst = _dst.getBase();
|
||||||
|
Uint32 * mask = _mask.getBase();
|
||||||
|
|
||||||
|
Vector<Uint32> save;
|
||||||
|
for(int i = 0; i<loops; i++)
|
||||||
|
{
|
||||||
|
memset(mask, 0xFF, sz);
|
||||||
|
memset(dst, 0xFF, sz);
|
||||||
|
int len;
|
||||||
|
int pos = 0;
|
||||||
|
while(pos+1 < size)
|
||||||
|
{
|
||||||
|
memset(src, 0xFF, sz);
|
||||||
|
while(!(len = rand() % (size - pos)));
|
||||||
|
BitmaskImpl::setField(sz32, mask, pos, len, src);
|
||||||
|
if(memcmp(dst, mask, sz))
|
||||||
|
{
|
||||||
|
ndbout_c("pos: %d len: %d", pos, len);
|
||||||
|
print(mask, size);
|
||||||
|
abort();
|
||||||
|
}
|
||||||
|
printf("[ %d %d ]", pos, len);
|
||||||
|
save.push_back(pos);
|
||||||
|
save.push_back(len);
|
||||||
|
pos += len;
|
||||||
|
}
|
||||||
|
|
||||||
|
for(int j = 0; j<save.size(); )
|
||||||
|
{
|
||||||
|
pos = save[j++];
|
||||||
|
len = save[j++];
|
||||||
|
memset(src, 0xFF, sz);
|
||||||
|
BitmaskImpl::getField(sz32, mask, pos, len, src);
|
||||||
|
if(memcmp(dst, src, sz))
|
||||||
|
{
|
||||||
|
ndbout_c("pos: %d len: %d", pos, len);
|
||||||
|
printf("src: "); print(src, size); printf("\n");
|
||||||
|
printf("dst: "); print(dst, size); printf("\n");
|
||||||
|
printf("msk: "); print(mask, size); printf("\n");
|
||||||
|
abort();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
ndbout_c("");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
do_test(int bitmask_size)
|
do_test(int bitmask_size)
|
||||||
{
|
{
|
||||||
|
@@ -311,6 +311,7 @@ void Dbtup::execTUP_ADD_ATTRREQ(Signal* signal)
|
|||||||
setTabDescrWord(firstTabDesIndex, attrDescriptor);
|
setTabDescrWord(firstTabDesIndex, attrDescriptor);
|
||||||
Uint32 attrLen = AttributeDescriptor::getSize(attrDescriptor);
|
Uint32 attrLen = AttributeDescriptor::getSize(attrDescriptor);
|
||||||
Uint32 nullBitPos = fragOperPtr.p->currNullBit;
|
Uint32 nullBitPos = fragOperPtr.p->currNullBit;
|
||||||
|
Uint32 bitCount = 0;
|
||||||
|
|
||||||
if (AttributeDescriptor::getNullable(attrDescriptor)) {
|
if (AttributeDescriptor::getNullable(attrDescriptor)) {
|
||||||
if (!AttributeDescriptor::getDynamic(attrDescriptor)) {
|
if (!AttributeDescriptor::getDynamic(attrDescriptor)) {
|
||||||
@@ -342,7 +343,7 @@ void Dbtup::execTUP_ADD_ATTRREQ(Signal* signal)
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
ljam();
|
ljam();
|
||||||
Uint32 bitCount = AttributeDescriptor::getArraySize(attrDescriptor);
|
bitCount = AttributeDescriptor::getArraySize(attrDescriptor);
|
||||||
fragOperPtr.p->currNullBit += bitCount;
|
fragOperPtr.p->currNullBit += bitCount;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -351,6 +352,12 @@ void Dbtup::execTUP_ADD_ATTRREQ(Signal* signal)
|
|||||||
ndbrequire(false);
|
ndbrequire(false);
|
||||||
break;
|
break;
|
||||||
}//switch
|
}//switch
|
||||||
|
if(nullBitPos + bitCount + 1 >= MAX_NULL_BITS)
|
||||||
|
{
|
||||||
|
terrorCode = TupAddAttrRef::TooManyBitsUsed;
|
||||||
|
addattrrefuseLab(signal, regFragPtr, fragOperPtr, regTabPtr.p, fragId);
|
||||||
|
return;
|
||||||
|
}
|
||||||
AttributeOffset::setOffset(attrDes2, attributePos);
|
AttributeOffset::setOffset(attrDes2, attributePos);
|
||||||
AttributeOffset::setNullFlagPos(attrDes2, nullBitPos);
|
AttributeOffset::setNullFlagPos(attrDes2, nullBitPos);
|
||||||
} else {
|
} else {
|
||||||
|
@@ -259,6 +259,7 @@ ErrorBundle ErrorCodes[] = {
|
|||||||
* Application error
|
* Application error
|
||||||
*/
|
*/
|
||||||
{ 823, AE, "Too much attrinfo from application in tuple manager" },
|
{ 823, AE, "Too much attrinfo from application in tuple manager" },
|
||||||
|
{ 831, AE, "Too many nullable/bitfields in table definition" },
|
||||||
{ 876, AE, "876" },
|
{ 876, AE, "876" },
|
||||||
{ 877, AE, "877" },
|
{ 877, AE, "877" },
|
||||||
{ 878, AE, "878" },
|
{ 878, AE, "878" },
|
||||||
|
@@ -7,7 +7,7 @@
|
|||||||
|
|
||||||
static const char* opt_connect_str= 0;
|
static const char* opt_connect_str= 0;
|
||||||
static const char* _dbname = "TEST_DB";
|
static const char* _dbname = "TEST_DB";
|
||||||
static int g_loops = 5;
|
static int g_loops = 7;
|
||||||
static struct my_option my_long_options[] =
|
static struct my_option my_long_options[] =
|
||||||
{
|
{
|
||||||
NDB_STD_OPTS("ndb_desc"),
|
NDB_STD_OPTS("ndb_desc"),
|
||||||
@@ -130,16 +130,17 @@ static
|
|||||||
const NdbDictionary::Table*
|
const NdbDictionary::Table*
|
||||||
create_random_table(Ndb* pNdb)
|
create_random_table(Ndb* pNdb)
|
||||||
{
|
{
|
||||||
|
do {
|
||||||
NdbDictionary::Table tab;
|
NdbDictionary::Table tab;
|
||||||
Uint32 cols = 1 + (rand() % (NDB_MAX_ATTRIBUTES_IN_TABLE - 1));
|
Uint32 cols = 1 + (rand() % (NDB_MAX_ATTRIBUTES_IN_TABLE - 1));
|
||||||
Uint32 keys = NDB_MAX_NO_OF_ATTRIBUTES_IN_KEY;
|
Uint32 keys = NDB_MAX_NO_OF_ATTRIBUTES_IN_KEY;
|
||||||
Uint32 length = 4096;
|
Uint32 length = 4090;
|
||||||
Uint32 key_size = NDB_MAX_KEYSIZE_IN_WORDS;
|
Uint32 key_size = NDB_MAX_KEYSIZE_IN_WORDS;
|
||||||
|
|
||||||
BaseString name;
|
BaseString name;
|
||||||
name.assfmt("TAB_%d", rand() & 65535);
|
name.assfmt("TAB_%d", rand() & 65535);
|
||||||
tab.setName(name.c_str());
|
tab.setName(name.c_str());
|
||||||
for(int i = 0; i<cols && length > 0; i++)
|
for(int i = 0; i<cols && length > 2; i++)
|
||||||
{
|
{
|
||||||
NdbDictionary::Column col;
|
NdbDictionary::Column col;
|
||||||
name.assfmt("COL_%d", i);
|
name.assfmt("COL_%d", i);
|
||||||
@@ -156,18 +157,21 @@ create_random_table(Ndb* pNdb)
|
|||||||
|
|
||||||
col.setType(NdbDictionary::Column::Bit);
|
col.setType(NdbDictionary::Column::Bit);
|
||||||
|
|
||||||
Uint32 len = 1 + (rand() % 128); //(length - 1));
|
Uint32 len = 1 + (rand() % (length - 1));
|
||||||
col.setLength(len); length -= len;
|
col.setLength(len); length -= len;
|
||||||
col.setNullable((rand() >> 16) & 1);
|
int nullable = (rand() >> 16) & 1;
|
||||||
|
col.setNullable(nullable); length -= nullable;
|
||||||
col.setPrimaryKey(false);
|
col.setPrimaryKey(false);
|
||||||
tab.addColumn(col);
|
tab.addColumn(col);
|
||||||
}
|
}
|
||||||
|
|
||||||
ndbout << (NDBT_Table&)tab << endl;
|
pNdb->getDictionary()->dropTable(tab.getName());
|
||||||
if(pNdb->getDictionary()->createTable(tab) == 0)
|
if(pNdb->getDictionary()->createTable(tab) == 0)
|
||||||
{
|
{
|
||||||
|
ndbout << (NDBT_Table&)tab << endl;
|
||||||
return pNdb->getDictionary()->getTable(tab.getName());
|
return pNdb->getDictionary()->getTable(tab.getName());
|
||||||
}
|
}
|
||||||
|
} while(0);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -506,6 +506,10 @@ max-time: 2500
|
|||||||
cmd: testOIBasic
|
cmd: testOIBasic
|
||||||
args:
|
args:
|
||||||
|
|
||||||
|
max-time: 2500
|
||||||
|
cmd: testBitfield
|
||||||
|
args:
|
||||||
|
|
||||||
#
|
#
|
||||||
#
|
#
|
||||||
# SYSTEM RESTARTS
|
# SYSTEM RESTARTS
|
||||||
|
Reference in New Issue
Block a user