From 3d2e560562948f1c53fbc0bd0ab200863861dfed Mon Sep 17 00:00:00 2001 From: "joreland@mysql.com" <> Date: Fri, 10 Dec 2004 16:15:36 +0100 Subject: [PATCH] ndb - bitfields - more tests, now passes all api tests!! --- ndb/include/kernel/ndb_limits.h | 1 + ndb/include/kernel/signaldata/TupFrag.hpp | 3 +- ndb/include/util/Bitmask.hpp | 2 +- ndb/src/common/util/Bitmask.cpp | 68 ++++++++++++++++++- ndb/src/kernel/blocks/dbtup/DbtupMeta.cpp | 9 ++- ndb/src/ndbapi/ndberror.c | 3 +- ndb/test/ndbapi/testBitfield.cpp | 80 ++++++++++++----------- ndb/test/run-test/daily-basic-tests.txt | 4 ++ 8 files changed, 127 insertions(+), 43 deletions(-) diff --git a/ndb/include/kernel/ndb_limits.h b/ndb/include/kernel/ndb_limits.h index 48a56c019bb..4ed38a194e4 100644 --- a/ndb/include/kernel/ndb_limits.h +++ b/ndb/include/kernel/ndb_limits.h @@ -61,6 +61,7 @@ #define MAX_FIXED_KEY_LENGTH_IN_WORDS 8 #define MAX_KEY_SIZE_IN_WORDS 1023 #define MAX_FRM_DATA_SIZE 6000 +#define MAX_NULL_BITS 4096 #define MIN_ATTRBUF ((MAX_ATTRIBUTES_IN_TABLE/24) + 1) /* diff --git a/ndb/include/kernel/signaldata/TupFrag.hpp b/ndb/include/kernel/signaldata/TupFrag.hpp index c132b19c50a..fe543cd1004 100644 --- a/ndb/include/kernel/signaldata/TupFrag.hpp +++ b/ndb/include/kernel/signaldata/TupFrag.hpp @@ -145,7 +145,8 @@ public: STATIC_CONST( SignalLength = 2 ); enum ErrorCode { NoError = 0, - InvalidCharset = 743 + InvalidCharset = 743, + TooManyBitsUsed = 831 }; private: Uint32 userPtr; diff --git a/ndb/include/util/Bitmask.hpp b/ndb/include/util/Bitmask.hpp index a88c48b4cb3..ade57a5ee57 100644 --- a/ndb/include/util/Bitmask.hpp +++ b/ndb/include/util/Bitmask.hpp @@ -818,7 +818,7 @@ BitmaskImpl::getField(unsigned size, const Uint32 src[], src += (pos >> 5); 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) { diff --git a/ndb/src/common/util/Bitmask.cpp b/ndb/src/common/util/Bitmask.cpp index 2499e016a13..4169434483f 100644 --- a/ndb/src/common/util/Bitmask.cpp +++ b/ndb/src/common/util/Bitmask.cpp @@ -23,9 +23,12 @@ BitmaskImpl::getFieldImpl(const Uint32 src[], unsigned shiftL, unsigned len, Uint32 dst[]) { assert(shiftL < 32); - + unsigned shiftR = 32 - shiftL; unsigned undefined = shiftL ? ~0 : 0; + + * dst = shiftL ? * dst : 0; + while(len >= 32) { * dst++ |= (* src) << shiftL; @@ -169,6 +172,69 @@ void simple(int pos, int size) require(cmp(src, dst, size+31)); }; +static +void simple2(int size, int loops) +{ + ndbout_c("simple2 %d - ", size); + Vector _mask; + Vector _src; + Vector _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 save; + for(int i = 0; icurrNullBit; + Uint32 bitCount = 0; if (AttributeDescriptor::getNullable(attrDescriptor)) { if (!AttributeDescriptor::getDynamic(attrDescriptor)) { @@ -342,7 +343,7 @@ void Dbtup::execTUP_ADD_ATTRREQ(Signal* signal) else { ljam(); - Uint32 bitCount = AttributeDescriptor::getArraySize(attrDescriptor); + bitCount = AttributeDescriptor::getArraySize(attrDescriptor); fragOperPtr.p->currNullBit += bitCount; break; } @@ -351,6 +352,12 @@ void Dbtup::execTUP_ADD_ATTRREQ(Signal* signal) ndbrequire(false); break; }//switch + if(nullBitPos + bitCount + 1 >= MAX_NULL_BITS) + { + terrorCode = TupAddAttrRef::TooManyBitsUsed; + addattrrefuseLab(signal, regFragPtr, fragOperPtr, regTabPtr.p, fragId); + return; + } AttributeOffset::setOffset(attrDes2, attributePos); AttributeOffset::setNullFlagPos(attrDes2, nullBitPos); } else { diff --git a/ndb/src/ndbapi/ndberror.c b/ndb/src/ndbapi/ndberror.c index c0a6b6ba122..638996530e2 100644 --- a/ndb/src/ndbapi/ndberror.c +++ b/ndb/src/ndbapi/ndberror.c @@ -259,6 +259,7 @@ ErrorBundle ErrorCodes[] = { * Application error */ { 823, AE, "Too much attrinfo from application in tuple manager" }, + { 831, AE, "Too many nullable/bitfields in table definition" }, { 876, AE, "876" }, { 877, AE, "877" }, { 878, AE, "878" }, @@ -270,7 +271,7 @@ ErrorBundle ErrorCodes[] = { { 897, AE, "Update attempt of primary key via ndbcluster internal api (if this occurs via the MySQL server it is a bug, please report)" }, { 4256, AE, "Must call Ndb::init() before this function" }, { 4257, AE, "Tried to read too much - too many getValue calls" }, - + /** * Scan application errors */ diff --git a/ndb/test/ndbapi/testBitfield.cpp b/ndb/test/ndbapi/testBitfield.cpp index 1438f65418b..42439e20959 100644 --- a/ndb/test/ndbapi/testBitfield.cpp +++ b/ndb/test/ndbapi/testBitfield.cpp @@ -7,7 +7,7 @@ static const char* opt_connect_str= 0; static const char* _dbname = "TEST_DB"; -static int g_loops = 5; +static int g_loops = 7; static struct my_option my_long_options[] = { NDB_STD_OPTS("ndb_desc"), @@ -130,44 +130,48 @@ static const NdbDictionary::Table* create_random_table(Ndb* pNdb) { - NdbDictionary::Table tab; - Uint32 cols = 1 + (rand() % (NDB_MAX_ATTRIBUTES_IN_TABLE - 1)); - Uint32 keys = NDB_MAX_NO_OF_ATTRIBUTES_IN_KEY; - Uint32 length = 4096; - Uint32 key_size = NDB_MAX_KEYSIZE_IN_WORDS; - - BaseString name; - name.assfmt("TAB_%d", rand() & 65535); - tab.setName(name.c_str()); - for(int i = 0; i 0; i++) - { - NdbDictionary::Column col; - name.assfmt("COL_%d", i); - col.setName(name.c_str()); - if(i == 0 || i == 1) - { - col.setType(NdbDictionary::Column::Unsigned); - col.setLength(1); - col.setNullable(false); - col.setPrimaryKey(i == 0); - tab.addColumn(col); - continue; - } - - col.setType(NdbDictionary::Column::Bit); + do { + NdbDictionary::Table tab; + Uint32 cols = 1 + (rand() % (NDB_MAX_ATTRIBUTES_IN_TABLE - 1)); + Uint32 keys = NDB_MAX_NO_OF_ATTRIBUTES_IN_KEY; + Uint32 length = 4090; + Uint32 key_size = NDB_MAX_KEYSIZE_IN_WORDS; - Uint32 len = 1 + (rand() % 128); //(length - 1)); - col.setLength(len); length -= len; - col.setNullable((rand() >> 16) & 1); - col.setPrimaryKey(false); - tab.addColumn(col); - } - - ndbout << (NDBT_Table&)tab << endl; - if(pNdb->getDictionary()->createTable(tab) == 0) - { - return pNdb->getDictionary()->getTable(tab.getName()); - } + BaseString name; + name.assfmt("TAB_%d", rand() & 65535); + tab.setName(name.c_str()); + for(int i = 0; i 2; i++) + { + NdbDictionary::Column col; + name.assfmt("COL_%d", i); + col.setName(name.c_str()); + if(i == 0 || i == 1) + { + col.setType(NdbDictionary::Column::Unsigned); + col.setLength(1); + col.setNullable(false); + col.setPrimaryKey(i == 0); + tab.addColumn(col); + continue; + } + + col.setType(NdbDictionary::Column::Bit); + + Uint32 len = 1 + (rand() % (length - 1)); + col.setLength(len); length -= len; + int nullable = (rand() >> 16) & 1; + col.setNullable(nullable); length -= nullable; + col.setPrimaryKey(false); + tab.addColumn(col); + } + + pNdb->getDictionary()->dropTable(tab.getName()); + if(pNdb->getDictionary()->createTable(tab) == 0) + { + ndbout << (NDBT_Table&)tab << endl; + return pNdb->getDictionary()->getTable(tab.getName()); + } + } while(0); return 0; } diff --git a/ndb/test/run-test/daily-basic-tests.txt b/ndb/test/run-test/daily-basic-tests.txt index 8a927b88194..dce89766319 100644 --- a/ndb/test/run-test/daily-basic-tests.txt +++ b/ndb/test/run-test/daily-basic-tests.txt @@ -506,6 +506,10 @@ max-time: 2500 cmd: testOIBasic args: +max-time: 2500 +cmd: testBitfield +args: + # # # SYSTEM RESTARTS