Commit 01526671 authored by unknown's avatar unknown

Merge poseidon.ndb.mysql.com:/home/tomas/mysql-5.0-ndb

into  poseidon.ndb.mysql.com:/home/tomas/mysql-5.0-ndb-merge
parents dfca266e 2fcf1040
...@@ -421,10 +421,10 @@ select * from t1 order by a; ...@@ -421,10 +421,10 @@ select * from t1 order by a;
a a
1 1
20 20
21
33 33
34 34
35 35
65
insert into t1 values (100); insert into t1 values (100);
insert into t1 values (NULL); insert into t1 values (NULL);
insert into t1 values (NULL); insert into t1 values (NULL);
...@@ -432,11 +432,11 @@ select * from t1 order by a; ...@@ -432,11 +432,11 @@ select * from t1 order by a;
a a
1 1
20 20
21
22
33 33
34 34
35 35
65
66
100 100
101 101
set auto_increment_offset = @old_auto_increment_offset; set auto_increment_offset = @old_auto_increment_offset;
......
drop table if exists t1;
create table t1(a int primary key, b int, c int, unique(b)) engine = ndb;
insert into t1 values (2,2,2);
insert into t1 values (3,3,3);
insert into t1 values (4,4,4);
begin;
insert into t1 values (1,1,1);
begin;
update t1 set c = 2 where b = 1;
ERROR HY000: Lock wait timeout exceeded; try restarting transaction
rollback;
rollback;
drop table t1;
create table t1(a int primary key, b int, c int, key(b)) engine = ndb;
insert into t1 values (2,2,2);
insert into t1 values (3,3,3);
insert into t1 values (4,4,4);
begin;
insert into t1 values (1,1,1);
begin;
update t1 set c = 2 where b = 1;
ERROR HY000: Lock wait timeout exceeded; try restarting transaction
rollback;
rollback;
drop table t1;
--con1
create table t1(a int primary key, b int, c int, key(b)) engine = ndb;
insert into t1 values (1,1,1);
insert into t1 values (2,2,2);
insert into t1 values (3,3,3);
insert into t1 values (4,4,4);
begin;
update t1 set c = 10 where a = 1;
update t1 set c = 20 where a = 1;
update t1 set c = 30 where a = 1;
--con1 c=30
select * from t1 where b >= 1 order by b;
a b c
1 1 30
2 2 2
3 3 3
4 4 4
--con2 c=1
select * from t1 where b >= 1 order by b;
a b c
1 1 1
2 2 2
3 3 3
4 4 4
--con1
delete from t1 where a = 1;
--con1 c=none
select * from t1 where b >= 1 order by b;
a b c
2 2 2
3 3 3
4 4 4
--con2 c=1
select * from t1 where b >= 1 order by b;
a b c
1 1 1
2 2 2
3 3 3
4 4 4
--con1
commit;
--con1 c=none
select * from t1 where b >= 1 order by b;
a b c
2 2 2
3 3 3
4 4 4
--con2 c=none
select * from t1 where b >= 1 order by b;
a b c
2 2 2
3 3 3
4 4 4
--con1
begin;
insert into t1 values (1,1,1);
update t1 set c = 10 where a = 1;
update t1 set c = 20 where a = 1;
update t1 set c = 30 where a = 1;
--con1 c=30
select * from t1 where b >= 1 order by b;
a b c
1 1 30
2 2 2
3 3 3
4 4 4
--con2 c=none
select * from t1 where b >= 1 order by b;
a b c
2 2 2
3 3 3
4 4 4
drop table t1;
...@@ -1904,6 +1904,12 @@ a b d ...@@ -1904,6 +1904,12 @@ a b d
10 1 4369 10 1 4369
20 2 8738 20 2 8738
50 5 21845 50 5 21845
-- big filter just below limit
a b d
10 1 4369
20 2 8738
50 5 21845
-- big filter just above limit
a b d a b d
10 1 4369 10 1 4369
20 2 8738 20 2 8738
......
...@@ -266,21 +266,41 @@ a ...@@ -266,21 +266,41 @@ a
2000 2000
3000 3000
10000 10000
show table status like 't1_c'; select max(capgoaledatta) from t1_c;
Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment max(capgoaledatta)
X X X X X X X X X X 3001 X X X X X X X 3000
show table status like 't2_c'; select auto_increment from information_schema.tables
Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment where table_name = 't1_c';
X X X X X X X X X X 501 X X X X X X X auto_increment
show table status like 't4_c'; 3001
Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment select max(capgotod) from t2_c;
X X X X X X X X X X 290000001 X X X X X X X max(capgotod)
show table status like 't7_c'; 500
Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment select auto_increment from information_schema.tables
X X X X X X X X X X 29 X X X X X X X where table_name = 't2_c';
show table status like 't10_c'; auto_increment
Name Engine Version Row_format Rows Avg_row_length Data_length Max_data_length Index_length Data_free Auto_increment Create_time Update_time Check_time Collation Checksum Create_options Comment 501
X X X X X X X X X X 10001 X X X X X X X select max(capfa) from t4_c;
max(capfa)
290000000
select auto_increment from information_schema.tables
where table_name = 't4_c';
auto_increment
290000001
select max(dardtestard) from t7_c;
max(dardtestard)
28
select auto_increment from information_schema.tables
where table_name = 't7_c';
auto_increment
29
select max(a) from t10_c;
max(a)
10000
select auto_increment from information_schema.tables
where table_name = 't10_c';
auto_increment
10001
drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9, t10; drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9, t10;
drop table if exists t1_c,t2_c,t3_c,t4_c,t5_c,t6_c,t7_c,t8_c,t9_c, t10_c; drop table if exists t1_c,t2_c,t3_c,t4_c,t5_c,t6_c,t7_c,t8_c,t9_c, t10_c;
520093696,<the_backup_id> 520093696,<the_backup_id>
--source include/have_ndb.inc
--disable_warnings
drop table if exists t1;
--enable_warnings
# setup
connect (con1,localhost,root,,test);
connect (con2,localhost,root,,test);
# unique index
connection con1;
create table t1(a int primary key, b int, c int, unique(b)) engine = ndb;
insert into t1 values (2,2,2);
insert into t1 values (3,3,3);
insert into t1 values (4,4,4);
begin;
insert into t1 values (1,1,1);
connection con2;
begin;
--error 1205
update t1 set c = 2 where b = 1;
rollback;
connection con1;
rollback;
drop table t1;
# ordered index
connection con1;
create table t1(a int primary key, b int, c int, key(b)) engine = ndb;
insert into t1 values (2,2,2);
insert into t1 values (3,3,3);
insert into t1 values (4,4,4);
begin;
insert into t1 values (1,1,1);
connection con2;
begin;
--error 1205
update t1 set c = 2 where b = 1;
rollback;
connection con1;
rollback;
drop table t1;
# multiple versions
--echo --con1
connection con1;
create table t1(a int primary key, b int, c int, key(b)) engine = ndb;
insert into t1 values (1,1,1);
insert into t1 values (2,2,2);
insert into t1 values (3,3,3);
insert into t1 values (4,4,4);
begin;
update t1 set c = 10 where a = 1;
update t1 set c = 20 where a = 1;
update t1 set c = 30 where a = 1;
--echo --con1 c=30
select * from t1 where b >= 1 order by b;
--echo --con2 c=1
connection con2;
select * from t1 where b >= 1 order by b;
--echo --con1
connection con1;
delete from t1 where a = 1;
--echo --con1 c=none
select * from t1 where b >= 1 order by b;
--echo --con2 c=1
connection con2;
select * from t1 where b >= 1 order by b;
--echo --con1
connection con1;
commit;
--echo --con1 c=none
select * from t1 where b >= 1 order by b;
--echo --con2 c=none
connection con2;
select * from t1 where b >= 1 order by b;
--echo --con1
connection con1;
begin;
insert into t1 values (1,1,1);
update t1 set c = 10 where a = 1;
update t1 set c = 20 where a = 1;
update t1 set c = 30 where a = 1;
--echo --con1 c=30
select * from t1 where b >= 1 order by b;
--echo --con2 c=none
connection con2;
select * from t1 where b >= 1 order by b;
# this fails with "no such table" via con2 ???
connection con1;
drop table t1;
This diff is collapsed.
...@@ -231,16 +231,21 @@ select count(*) ...@@ -231,16 +231,21 @@ select count(*)
select * from t10_c order by a; select * from t10_c order by a;
# Bug #27775 cont'd # Bug #27775 cont'd
# - auto inc info should be correct # - auto inc info should be correct
--replace_column 1 X 2 X 3 X 4 X 5 X 6 X 7 X 8 X 9 X 10 X 12 X 13 X 14 X 15 X 16 X 17 X 18 X select max(capgoaledatta) from t1_c;
show table status like 't1_c'; select auto_increment from information_schema.tables
--replace_column 1 X 2 X 3 X 4 X 5 X 6 X 7 X 8 X 9 X 10 X 12 X 13 X 14 X 15 X 16 X 17 X 18 X where table_name = 't1_c';
show table status like 't2_c'; select max(capgotod) from t2_c;
--replace_column 1 X 2 X 3 X 4 X 5 X 6 X 7 X 8 X 9 X 10 X 12 X 13 X 14 X 15 X 16 X 17 X 18 X select auto_increment from information_schema.tables
show table status like 't4_c'; where table_name = 't2_c';
--replace_column 1 X 2 X 3 X 4 X 5 X 6 X 7 X 8 X 9 X 10 X 12 X 13 X 14 X 15 X 16 X 17 X 18 X select max(capfa) from t4_c;
show table status like 't7_c'; select auto_increment from information_schema.tables
--replace_column 1 X 2 X 3 X 4 X 5 X 6 X 7 X 8 X 9 X 10 X 12 X 13 X 14 X 15 X 16 X 17 X 18 X where table_name = 't4_c';
show table status like 't10_c'; select max(dardtestard) from t7_c;
select auto_increment from information_schema.tables
where table_name = 't7_c';
select max(a) from t10_c;
select auto_increment from information_schema.tables
where table_name = 't10_c';
--disable_warnings --disable_warnings
drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9, t10; drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9, t10;
......
...@@ -1386,22 +1386,22 @@ public: ...@@ -1386,22 +1386,22 @@ public:
* *
* @param cacheSize number of values to cache in this Ndb object * @param cacheSize number of values to cache in this Ndb object
* *
* @return 0 or -1 on error, and tupleId in out parameter * @return 0 or -1 on error, and autoValue in out parameter
*/ */
int getAutoIncrementValue(const char* aTableName, int getAutoIncrementValue(const char* aTableName,
Uint64 & tupleId, Uint32 cacheSize, Uint64 & autoValue, Uint32 cacheSize,
Uint64 step = 1, Uint64 start = 1); Uint64 step = 1, Uint64 start = 1);
int getAutoIncrementValue(const NdbDictionary::Table * aTable, int getAutoIncrementValue(const NdbDictionary::Table * aTable,
Uint64 & tupleId, Uint32 cacheSize, Uint64 & autoValue, Uint32 cacheSize,
Uint64 step = 1, Uint64 start = 1); Uint64 step = 1, Uint64 start = 1);
int readAutoIncrementValue(const char* aTableName, int readAutoIncrementValue(const char* aTableName,
Uint64 & tupleId); Uint64 & autoValue);
int readAutoIncrementValue(const NdbDictionary::Table * aTable, int readAutoIncrementValue(const NdbDictionary::Table * aTable,
Uint64 & tupleId); Uint64 & autoValue);
int setAutoIncrementValue(const char* aTableName, int setAutoIncrementValue(const char* aTableName,
Uint64 tupleId, bool increase); Uint64 autoValue, bool modify);
int setAutoIncrementValue(const NdbDictionary::Table * aTable, int setAutoIncrementValue(const NdbDictionary::Table * aTable,
Uint64 tupleId, bool increase); Uint64 autoValue, bool modify);
private: private:
int getTupleIdFromNdb(Ndb_local_table_info* info, int getTupleIdFromNdb(Ndb_local_table_info* info,
Uint64 & tupleId, Uint32 cacheSize, Uint64 & tupleId, Uint32 cacheSize,
...@@ -1409,7 +1409,9 @@ private: ...@@ -1409,7 +1409,9 @@ private:
int readTupleIdFromNdb(Ndb_local_table_info* info, int readTupleIdFromNdb(Ndb_local_table_info* info,
Uint64 & tupleId); Uint64 & tupleId);
int setTupleIdInNdb(Ndb_local_table_info* info, int setTupleIdInNdb(Ndb_local_table_info* info,
Uint64 tupleId, bool increase); Uint64 tupleId, bool modify);
int checkTupleIdInNdb(Ndb_local_table_info* info,
Uint64 tupleId);
int opTupleIdOnNdb(Ndb_local_table_info* info, Uint64 & opValue, Uint32 op); int opTupleIdOnNdb(Ndb_local_table_info* info, Uint64 & opValue, Uint32 op);
public: public:
......
...@@ -26,6 +26,7 @@ ...@@ -26,6 +26,7 @@
#define NDB_MAX_TUPLE_SIZE (NDB_MAX_TUPLE_SIZE_IN_WORDS*4) #define NDB_MAX_TUPLE_SIZE (NDB_MAX_TUPLE_SIZE_IN_WORDS*4)
#define NDB_MAX_ACTIVE_EVENTS 100 #define NDB_MAX_ACTIVE_EVENTS 100
#define NDB_MAX_SCANFILTER_SIZE_IN_WORDS 50000 /* TUP ZATTR_BUFFER_SIZE 16384 (minus 1) minus place for getValue()s */
#define NDB_MAX_SCANFILTER_SIZE_IN_WORDS (16384 - 1 - 1024)
#endif #endif
...@@ -129,7 +129,7 @@ SignalLoggerManager::log(LogMode logMode, const char * params) ...@@ -129,7 +129,7 @@ SignalLoggerManager::log(LogMode logMode, const char * params)
const int count = getParameter(blocks, "BLOCK=", params); const int count = getParameter(blocks, "BLOCK=", params);
int cnt = 0; int cnt = 0;
if((count == 1 && blocks[0] == "ALL") || if((count == 1 && !strcmp(blocks[0], "ALL")) ||
count == 0){ count == 0){
for (int number = 0; number < NO_OF_BLOCKS; ++number){ for (int number = 0; number < NO_OF_BLOCKS; ++number){
......
...@@ -69,7 +69,7 @@ printSCANTABCONF(FILE * output, const Uint32 * theData, Uint32 len, Uint16 recei ...@@ -69,7 +69,7 @@ printSCANTABCONF(FILE * output, const Uint32 * theData, Uint32 len, Uint16 recei
sig->transId1, sig->transId2); sig->transId1, sig->transId2);
fprintf(output, " requestInfo: Eod: %d OpCount: %d\n", fprintf(output, " requestInfo: Eod: %d OpCount: %d\n",
(requestInfo & ScanTabConf::EndOfData == ScanTabConf::EndOfData), (requestInfo & ScanTabConf::EndOfData) == ScanTabConf::EndOfData,
(requestInfo & (~ScanTabConf::EndOfData))); (requestInfo & (~ScanTabConf::EndOfData)));
size_t op_count= requestInfo & (~ScanTabConf::EndOfData); size_t op_count= requestInfo & (~ScanTabConf::EndOfData);
if(op_count){ if(op_count){
......
...@@ -29,7 +29,7 @@ static const char * fms[] = { ...@@ -29,7 +29,7 @@ static const char * fms[] = {
"%d", "0x%08x", // Int32 "%d", "0x%08x", // Int32
"%u", "0x%08x", // Uint32 "%u", "0x%08x", // Uint32
"%lld", "0x%016llx", // Int64 "%lld", "0x%016llx", // Int64
"%llu", "0x%016llx" // Uint64 "%llu", "0x%016llx", // Uint64
"%llu", "0x%016llx" // UintPtr "%llu", "0x%016llx" // UintPtr
}; };
......
...@@ -374,16 +374,18 @@ Backup::execCONTINUEB(Signal* signal) ...@@ -374,16 +374,18 @@ Backup::execCONTINUEB(Signal* signal)
ptr.p->files.getPtr(filePtr, ptr.p->ctlFilePtr); ptr.p->files.getPtr(filePtr, ptr.p->ctlFilePtr);
FsBuffer & buf = filePtr.p->operation.dataBuffer; FsBuffer & buf = filePtr.p->operation.dataBuffer;
if(buf.getFreeSize() + buf.getMinRead() < buf.getUsableSize()) { if(buf.getFreeSize() < buf.getMaxWrite()) {
jam(); jam();
TablePtr tabPtr LINT_SET_PTR; TablePtr tabPtr LINT_SET_PTR;
c_tablePool.getPtr(tabPtr, Tdata2); c_tablePool.getPtr(tabPtr, Tdata2);
DEBUG_OUT("Backup - Buffer full - " << buf.getFreeSize() DEBUG_OUT("Backup - Buffer full - "
<< " + " << buf.getMinRead() << buf.getFreeSize()
<< " < " << buf.getUsableSize() << " < " << buf.getMaxWrite()
<< " - tableId = " << tabPtr.p->tableId); << " (sz: " << buf.getUsableSize()
<< " getMinRead: " << buf.getMinRead()
<< ") - tableId = " << tabPtr.p->tableId);
signal->theData[0] = BackupContinueB::BUFFER_FULL_META; signal->theData[0] = BackupContinueB::BUFFER_FULL_META;
signal->theData[1] = Tdata1; signal->theData[1] = Tdata1;
signal->theData[2] = Tdata2; signal->theData[2] = Tdata2;
......
...@@ -518,7 +518,7 @@ public: ...@@ -518,7 +518,7 @@ public:
Uint32 m_diskless; Uint32 m_diskless;
STATIC_CONST(NO_OF_PAGES_META_FILE = STATIC_CONST(NO_OF_PAGES_META_FILE =
(MAX_WORDS_META_FILE + BACKUP_WORDS_PER_PAGE - 1) / (2*MAX_WORDS_META_FILE + BACKUP_WORDS_PER_PAGE - 1) /
BACKUP_WORDS_PER_PAGE); BACKUP_WORDS_PER_PAGE);
/** /**
......
...@@ -198,6 +198,7 @@ ...@@ -198,6 +198,7 @@
#define ZUNSUPPORTED_BRANCH 892 #define ZUNSUPPORTED_BRANCH 892
#define ZSTORED_SEIZE_ATTRINBUFREC_ERROR 873 // Part of Scan #define ZSTORED_SEIZE_ATTRINBUFREC_ERROR 873 // Part of Scan
#define ZSTORED_TOO_MUCH_ATTRINFO_ERROR 874
#define ZREAD_ONLY_CONSTRAINT_VIOLATION 893 #define ZREAD_ONLY_CONSTRAINT_VIOLATION 893
#define ZVAR_SIZED_NOT_SUPPORTED 894 #define ZVAR_SIZED_NOT_SUPPORTED 894
...@@ -1085,7 +1086,7 @@ public: ...@@ -1085,7 +1086,7 @@ public:
/* /*
* TUX checks if tuple is visible to scan. * TUX checks if tuple is visible to scan.
*/ */
bool tuxQueryTh(Uint32 fragPtrI, Uint32 tupAddr, Uint32 tupVersion, Uint32 transId1, Uint32 transId2, Uint32 savePointId); bool tuxQueryTh(Uint32 fragPtrI, Uint32 pageId, Uint32 pageOffset, Uint32 tupVersion, Uint32 transId1, Uint32 transId2, bool dirty, Uint32 savePointId);
private: private:
BLOCK_DEFINES(Dbtup); BLOCK_DEFINES(Dbtup);
...@@ -1942,6 +1943,8 @@ private: ...@@ -1942,6 +1943,8 @@ private:
bool getPageThroughSavePoint(Operationrec* const regOperPtr, bool getPageThroughSavePoint(Operationrec* const regOperPtr,
Operationrec* const leaderOpPtr); Operationrec* const leaderOpPtr);
bool find_savepoint(OperationrecPtr& loopOpPtr, Uint32 savepointId);
Uint32 calculateChecksum(Page* const pagePtr, Uint32 tupHeadOffset, Uint32 tupHeadSize); Uint32 calculateChecksum(Page* const pagePtr, Uint32 tupHeadOffset, Uint32 tupHeadSize);
void setChecksum(Page* const pagePtr, Uint32 tupHeadOffset, Uint32 tupHeadSize); void setChecksum(Page* const pagePtr, Uint32 tupHeadOffset, Uint32 tupHeadSize);
...@@ -2171,7 +2174,8 @@ private: ...@@ -2171,7 +2174,8 @@ private:
Operationrec* regOperPtr, Operationrec* regOperPtr,
Uint32 lenAttrInfo); Uint32 lenAttrInfo);
void storedSeizeAttrinbufrecErrorLab(Signal* signal, void storedSeizeAttrinbufrecErrorLab(Signal* signal,
Operationrec* regOperPtr); Operationrec* regOperPtr,
Uint32 errorCode);
bool storedProcedureAttrInfo(Signal* signal, bool storedProcedureAttrInfo(Signal* signal,
Operationrec* regOperPtr, Operationrec* regOperPtr,
Uint32 length, Uint32 length,
...@@ -2467,4 +2471,22 @@ bool Dbtup::isPageUndoLogged(Fragrecord* const regFragPtr, ...@@ -2467,4 +2471,22 @@ bool Dbtup::isPageUndoLogged(Fragrecord* const regFragPtr,
return false; return false;
}//Dbtup::isUndoLoggingNeeded() }//Dbtup::isUndoLoggingNeeded()
inline
bool Dbtup::find_savepoint(OperationrecPtr& loopOpPtr, Uint32 savepointId)
{
while (true) {
if (savepointId > loopOpPtr.p->savePointId) {
jam();
return true;
}
// note 5.0 has reversed next/prev pointers
loopOpPtr.i = loopOpPtr.p->nextActiveOp;
if (loopOpPtr.i == RNIL) {
break;
}
ptrCheckGuard(loopOpPtr, cnoOfOprec, operationrec);
}
return false;
}
#endif #endif
...@@ -77,6 +77,14 @@ void Dbtup::copyAttrinfo(Signal* signal, ...@@ -77,6 +77,14 @@ void Dbtup::copyAttrinfo(Signal* signal,
RbufLen = copyAttrBufPtr.p->attrbuf[ZBUF_DATA_LEN]; RbufLen = copyAttrBufPtr.p->attrbuf[ZBUF_DATA_LEN];
Rnext = copyAttrBufPtr.p->attrbuf[ZBUF_NEXT]; Rnext = copyAttrBufPtr.p->attrbuf[ZBUF_NEXT];
Rfirst = cfirstfreeAttrbufrec; Rfirst = cfirstfreeAttrbufrec;
/*
* ATTRINFO comes from 2 mutually exclusive places:
* 1) TUPKEYREQ (also interpreted part)
* 2) STORED_PROCREQ before scan start
* Assert here that both have a check for overflow.
* The "<" instead of "<=" is intentional.
*/
ndbrequire(RinBufIndex + RbufLen < ZATTR_BUFFER_SIZE);
MEMCOPY_NO_WORDS(&inBuffer[RinBufIndex], MEMCOPY_NO_WORDS(&inBuffer[RinBufIndex],
&copyAttrBufPtr.p->attrbuf[0], &copyAttrBufPtr.p->attrbuf[0],
RbufLen); RbufLen);
......
...@@ -246,8 +246,18 @@ Dbtup::accReadPk(Uint32 tableId, Uint32 fragId, Uint32 fragPageId, Uint32 pageIn ...@@ -246,8 +246,18 @@ Dbtup::accReadPk(Uint32 tableId, Uint32 fragId, Uint32 fragPageId, Uint32 pageIn
return ret; return ret;
} }
/*
* TUX index contains all tuple versions. A scan in TUX has scanned
* one of them and asks if it can be returned as scan result. This
* depends on trans id, dirty read flag, and savepoint within trans.
*
* Previously this faked a ZREAD operation and used getPage().
* In TUP getPage() is run after ACC locking, but TUX comes here
* before ACC access. Instead of modifying getPage() it is more
* clear to do the full check here.
*/
bool bool
Dbtup::tuxQueryTh(Uint32 fragPtrI, Uint32 tupAddr, Uint32 tupVersion, Uint32 transId1, Uint32 transId2, Uint32 savePointId) Dbtup::tuxQueryTh(Uint32 fragPtrI, Uint32 pageId, Uint32 pageOffset, Uint32 tupVersion, Uint32 transId1, Uint32 transId2, bool dirty, Uint32 savePointId)
{ {
ljamEntry(); ljamEntry();
FragrecordPtr fragPtr; FragrecordPtr fragPtr;
...@@ -256,33 +266,73 @@ Dbtup::tuxQueryTh(Uint32 fragPtrI, Uint32 tupAddr, Uint32 tupVersion, Uint32 tra ...@@ -256,33 +266,73 @@ Dbtup::tuxQueryTh(Uint32 fragPtrI, Uint32 tupAddr, Uint32 tupVersion, Uint32 tra
TablerecPtr tablePtr; TablerecPtr tablePtr;
tablePtr.i = fragPtr.p->fragTableId; tablePtr.i = fragPtr.p->fragTableId;
ptrCheckGuard(tablePtr, cnoOfTablerec, tablerec); ptrCheckGuard(tablePtr, cnoOfTablerec, tablerec);
// get page
PagePtr pagePtr; PagePtr pagePtr;
Uint32 fragPageId = tupAddr >> MAX_TUPLES_BITS; pagePtr.i = pageId;
Uint32 pageIndex = tupAddr & ((1 << MAX_TUPLES_BITS ) - 1); ptrCheckGuard(pagePtr, cnoOfPage, page);
// use temp op rec
Operationrec tempOp; OperationrecPtr currOpPtr;
tempOp.fragPageId = fragPageId; currOpPtr.i = pagePtr.p->pageWord[pageOffset];
tempOp.pageIndex = pageIndex; if (currOpPtr.i == RNIL) {
tempOp.transid1 = transId1; ljam();
tempOp.transid2 = transId2; // tuple has no operation, any scan can see it
tempOp.savePointId = savePointId; return true;
tempOp.optype = ZREAD; }
tempOp.dirtyOp = 1; ptrCheckGuard(currOpPtr, cnoOfOprec, operationrec);
if (getPage(pagePtr, &tempOp, fragPtr.p, tablePtr.p)) {
/* const bool sameTrans =
* We use the normal getPage which will return the tuple to be used transId1 == currOpPtr.p->transid1 &&
* for this transaction and savepoint id. If its tuple version transId2 == currOpPtr.p->transid2;
* equals the requested then we have a visible tuple otherwise not.
*/ bool res = false;
OperationrecPtr loopOpPtr = currOpPtr;
if (!sameTrans) {
ljam(); ljam();
Uint32 read_tupVersion = pagePtr.p->pageWord[tempOp.pageOffset + 1]; if (!dirty) {
if (read_tupVersion == tupVersion) {
ljam(); ljam();
return true; if (currOpPtr.p->prevActiveOp == RNIL) {
ljam();
// last op - TUX makes ACC lock request in same timeslice
res = true;
}
}
else {
// loop to first op (returns false)
find_savepoint(loopOpPtr, 0);
const Uint32 op_type = loopOpPtr.p->optype;
if (op_type != ZINSERT) {
ljam();
// read committed version from the page
const Uint32 origVersion = pagePtr.p->pageWord[pageOffset + 1];
if (origVersion == tupVersion) {
ljam();
res = true;
}
}
} }
} }
return false; else {
ljam();
// for own trans, ignore dirty flag
if (find_savepoint(loopOpPtr, savePointId)) {
ljam();
const Uint32 op_type = loopOpPtr.p->optype;
if (op_type != ZDELETE) {
ljam();
// check if this op has produced the scanned version
Uint32 loopVersion = loopOpPtr.p->tupVersion;
if (loopVersion == tupVersion) {
ljam();
res = true;
}
}
}
}
return res;
} }
// ordered index build // ordered index build
......
...@@ -108,6 +108,11 @@ void Dbtup::scanProcedure(Signal* signal, ...@@ -108,6 +108,11 @@ void Dbtup::scanProcedure(Signal* signal,
regOperPtr->attrinbufLen = lenAttrInfo; regOperPtr->attrinbufLen = lenAttrInfo;
regOperPtr->currentAttrinbufLen = 0; regOperPtr->currentAttrinbufLen = 0;
regOperPtr->pageOffset = storedPtr.i; regOperPtr->pageOffset = storedPtr.i;
if (lenAttrInfo >= ZATTR_BUFFER_SIZE) { // yes ">="
jam();
// send REF and change state to ignore the ATTRINFO to come
storedSeizeAttrinbufrecErrorLab(signal, regOperPtr, ZSTORED_TOO_MUCH_ATTRINFO_ERROR);
}
}//Dbtup::scanProcedure() }//Dbtup::scanProcedure()
void Dbtup::copyProcedure(Signal* signal, void Dbtup::copyProcedure(Signal* signal,
...@@ -146,7 +151,7 @@ bool Dbtup::storedProcedureAttrInfo(Signal* signal, ...@@ -146,7 +151,7 @@ bool Dbtup::storedProcedureAttrInfo(Signal* signal,
Uint32 RnoFree = cnoFreeAttrbufrec; Uint32 RnoFree = cnoFreeAttrbufrec;
if (ERROR_INSERTED(4004) && !copyProcedure) { if (ERROR_INSERTED(4004) && !copyProcedure) {
CLEAR_ERROR_INSERT_VALUE; CLEAR_ERROR_INSERT_VALUE;
storedSeizeAttrinbufrecErrorLab(signal, regOperPtr); storedSeizeAttrinbufrecErrorLab(signal, regOperPtr, ZSTORED_SEIZE_ATTRINBUFREC_ERROR);
return false; return false;
}//if }//if
regOperPtr->currentAttrinbufLen += length; regOperPtr->currentAttrinbufLen += length;
...@@ -162,7 +167,7 @@ bool Dbtup::storedProcedureAttrInfo(Signal* signal, ...@@ -162,7 +167,7 @@ bool Dbtup::storedProcedureAttrInfo(Signal* signal,
regAttrPtr.p->attrbuf[ZBUF_NEXT] = RNIL; regAttrPtr.p->attrbuf[ZBUF_NEXT] = RNIL;
} else { } else {
ljam(); ljam();
storedSeizeAttrinbufrecErrorLab(signal, regOperPtr); storedSeizeAttrinbufrecErrorLab(signal, regOperPtr, ZSTORED_SEIZE_ATTRINBUFREC_ERROR);
return false; return false;
}//if }//if
if (regOperPtr->firstAttrinbufrec == RNIL) { if (regOperPtr->firstAttrinbufrec == RNIL) {
...@@ -190,7 +195,7 @@ bool Dbtup::storedProcedureAttrInfo(Signal* signal, ...@@ -190,7 +195,7 @@ bool Dbtup::storedProcedureAttrInfo(Signal* signal,
}//if }//if
if (ERROR_INSERTED(4005) && !copyProcedure) { if (ERROR_INSERTED(4005) && !copyProcedure) {
CLEAR_ERROR_INSERT_VALUE; CLEAR_ERROR_INSERT_VALUE;
storedSeizeAttrinbufrecErrorLab(signal, regOperPtr); storedSeizeAttrinbufrecErrorLab(signal, regOperPtr, ZSTORED_SEIZE_ATTRINBUFREC_ERROR);
return false; return false;
}//if }//if
...@@ -211,7 +216,8 @@ bool Dbtup::storedProcedureAttrInfo(Signal* signal, ...@@ -211,7 +216,8 @@ bool Dbtup::storedProcedureAttrInfo(Signal* signal,
}//Dbtup::storedProcedureAttrInfo() }//Dbtup::storedProcedureAttrInfo()
void Dbtup::storedSeizeAttrinbufrecErrorLab(Signal* signal, void Dbtup::storedSeizeAttrinbufrecErrorLab(Signal* signal,
Operationrec* regOperPtr) Operationrec* regOperPtr,
Uint32 errorCode)
{ {
StoredProcPtr storedPtr; StoredProcPtr storedPtr;
c_storedProcPool.getPtr(storedPtr, (Uint32)regOperPtr->pageOffset); c_storedProcPool.getPtr(storedPtr, (Uint32)regOperPtr->pageOffset);
...@@ -222,7 +228,7 @@ void Dbtup::storedSeizeAttrinbufrecErrorLab(Signal* signal, ...@@ -222,7 +228,7 @@ void Dbtup::storedSeizeAttrinbufrecErrorLab(Signal* signal,
regOperPtr->lastAttrinbufrec = RNIL; regOperPtr->lastAttrinbufrec = RNIL;
regOperPtr->transstate = ERROR_WAIT_STORED_PROCREQ; regOperPtr->transstate = ERROR_WAIT_STORED_PROCREQ;
signal->theData[0] = regOperPtr->userpointer; signal->theData[0] = regOperPtr->userpointer;
signal->theData[1] = ZSTORED_SEIZE_ATTRINBUFREC_ERROR; signal->theData[1] = errorCode;
signal->theData[2] = regOperPtr->pageOffset; signal->theData[2] = regOperPtr->pageOffset;
sendSignal(regOperPtr->userblockref, GSN_STORED_PROCREF, signal, 3, JBB); sendSignal(regOperPtr->userblockref, GSN_STORED_PROCREF, signal, 3, JBB);
}//Dbtup::storedSeizeAttrinbufrecErrorLab() }//Dbtup::storedSeizeAttrinbufrecErrorLab()
......
...@@ -984,7 +984,8 @@ Dbtux::scanVisible(ScanOpPtr scanPtr, TreeEnt ent) ...@@ -984,7 +984,8 @@ Dbtux::scanVisible(ScanOpPtr scanPtr, TreeEnt ent)
const Frag& frag = *c_fragPool.getPtr(scan.m_fragPtrI); const Frag& frag = *c_fragPool.getPtr(scan.m_fragPtrI);
Uint32 fragBit = ent.m_fragBit; Uint32 fragBit = ent.m_fragBit;
Uint32 tableFragPtrI = frag.m_tupTableFragPtrI[fragBit]; Uint32 tableFragPtrI = frag.m_tupTableFragPtrI[fragBit];
Uint32 tupAddr = getTupAddr(frag, ent); Uint32 pageId = ent.m_tupLoc.getPageId();
Uint32 pageOffset = ent.m_tupLoc.getPageOffset();
Uint32 tupVersion = ent.m_tupVersion; Uint32 tupVersion = ent.m_tupVersion;
// check for same tuple twice in row // check for same tuple twice in row
if (scan.m_scanEnt.m_tupLoc == ent.m_tupLoc && if (scan.m_scanEnt.m_tupLoc == ent.m_tupLoc &&
...@@ -994,8 +995,9 @@ Dbtux::scanVisible(ScanOpPtr scanPtr, TreeEnt ent) ...@@ -994,8 +995,9 @@ Dbtux::scanVisible(ScanOpPtr scanPtr, TreeEnt ent)
} }
Uint32 transId1 = scan.m_transId1; Uint32 transId1 = scan.m_transId1;
Uint32 transId2 = scan.m_transId2; Uint32 transId2 = scan.m_transId2;
bool dirty = scan.m_readCommitted;
Uint32 savePointId = scan.m_savePointId; Uint32 savePointId = scan.m_savePointId;
bool ret = c_tup->tuxQueryTh(tableFragPtrI, tupAddr, tupVersion, transId1, transId2, savePointId); bool ret = c_tup->tuxQueryTh(tableFragPtrI, pageId, pageOffset, tupVersion, transId1, transId2, dirty, savePointId);
jamEntry(); jamEntry();
return ret; return ret;
} }
......
...@@ -45,8 +45,8 @@ public: ...@@ -45,8 +45,8 @@ public:
/** /**
* Seize element from pool - return i * Seize element from pool - return i
* *
* Note must be either added using <b>add</b> or released * Note *must* be added using <b>add</b> (even before hash.release)
* using <b>release</b> * or be released using pool
*/ */
bool seize(Ptr<T> &); bool seize(Ptr<T> &);
...@@ -374,7 +374,14 @@ DLHashTable<T>::remove(Ptr<T> & ptr){ ...@@ -374,7 +374,14 @@ DLHashTable<T>::remove(Ptr<T> & ptr){
prevP->nextHash = next; prevP->nextHash = next;
} else { } else {
const Uint32 hv = ptr.p->hashValue() & mask; const Uint32 hv = ptr.p->hashValue() & mask;
hashValues[hv] = next; if (hashValues[hv] == ptr.i)
{
hashValues[hv] = next;
}
else
{
// Will add assert in 5.1
}
} }
if(next != RNIL){ if(next != RNIL){
...@@ -395,7 +402,14 @@ DLHashTable<T>::release(Ptr<T> & ptr){ ...@@ -395,7 +402,14 @@ DLHashTable<T>::release(Ptr<T> & ptr){
prevP->nextHash = next; prevP->nextHash = next;
} else { } else {
const Uint32 hv = ptr.p->hashValue() & mask; const Uint32 hv = ptr.p->hashValue() & mask;
hashValues[hv] = next; if (hashValues[hv] == ptr.i)
{
hashValues[hv] = next;
}
else
{
// Will add assert in 5.1
}
} }
if(next != RNIL){ if(next != RNIL){
......
...@@ -43,8 +43,8 @@ public: ...@@ -43,8 +43,8 @@ public:
/** /**
* Seize element from pool - return i * Seize element from pool - return i
* *
* Note must be either added using <b>add</b> or released * Note *must* be added using <b>add</b> (even before hash.release)
* using <b>release</b> * or be released using pool
*/ */
bool seize(Ptr<T> &); bool seize(Ptr<T> &);
...@@ -375,7 +375,14 @@ DLHashTable2<T, U>::remove(Ptr<T> & ptr){ ...@@ -375,7 +375,14 @@ DLHashTable2<T, U>::remove(Ptr<T> & ptr){
prevP->nextHash = next; prevP->nextHash = next;
} else { } else {
const Uint32 hv = ptr.p->hashValue() & mask; const Uint32 hv = ptr.p->hashValue() & mask;
hashValues[hv] = next; if (hashValues[hv] == ptr.i)
{
hashValues[hv] = next;
}
else
{
// Will add assert in 5.1
}
} }
if(next != RNIL){ if(next != RNIL){
...@@ -396,7 +403,14 @@ DLHashTable2<T, U>::release(Ptr<T> & ptr){ ...@@ -396,7 +403,14 @@ DLHashTable2<T, U>::release(Ptr<T> & ptr){
prevP->nextHash = next; prevP->nextHash = next;
} else { } else {
const Uint32 hv = ptr.p->hashValue() & mask; const Uint32 hv = ptr.p->hashValue() & mask;
hashValues[hv] = next; if (hashValues[hv] == ptr.i)
{
hashValues[hv] = next;
}
else
{
// Will add assert in 5.1
}
} }
if(next != RNIL){ if(next != RNIL){
......
...@@ -49,7 +49,7 @@ ...@@ -49,7 +49,7 @@
theEmulatedJamBlockNumber = number(); \ theEmulatedJamBlockNumber = number(); \
Uint32 tEmulatedJamIndex = theEmulatedJamIndex; \ Uint32 tEmulatedJamIndex = theEmulatedJamIndex; \
*(Uint32*)(theEmulatedJam + tEmulatedJamIndex) = \ *(Uint32*)(theEmulatedJam + tEmulatedJamIndex) = \
((theEmulatedJamBlockNumber << 20) | line); \ ((theEmulatedJamBlockNumber << 20) | (line)); \
theEmulatedJamIndex = (tEmulatedJamIndex + 4) & JAM_MASK; } theEmulatedJamIndex = (tEmulatedJamIndex + 4) & JAM_MASK; }
#else #else
...@@ -72,7 +72,7 @@ ...@@ -72,7 +72,7 @@
theEmulatedJamBlockNumber = number(); \ theEmulatedJamBlockNumber = number(); \
Uint32 tEmulatedJamIndex = theEmulatedJamIndex; \ Uint32 tEmulatedJamIndex = theEmulatedJamIndex; \
*(Uint32*)((UintPtr)theEmulatedJam + (Uint32)tEmulatedJamIndex) = \ *(Uint32*)((UintPtr)theEmulatedJam + (Uint32)tEmulatedJamIndex) = \
((theEmulatedJamBlockNumber << 20) | line); \ ((theEmulatedJamBlockNumber << 20) | (line)); \
theEmulatedJamIndex = (tEmulatedJamIndex + 4) & JAM_MASK; } theEmulatedJamIndex = (tEmulatedJamIndex + 4) & JAM_MASK; }
#endif #endif
...@@ -232,7 +232,7 @@ ...@@ -232,7 +232,7 @@
#define MEMCOPY_PAGE(to, from, page_size_in_bytes) \ #define MEMCOPY_PAGE(to, from, page_size_in_bytes) \
memcpy((void*)(to), (void*)(from), (size_t)(page_size_in_bytes)); memcpy((void*)(to), (void*)(from), (size_t)(page_size_in_bytes));
#define MEMCOPY_NO_WORDS(to, from, no_of_words) \ #define MEMCOPY_NO_WORDS(to, from, no_of_words) \
memcpy((to), (void*)(from), (size_t)(no_of_words << 2)); memcpy((to), (void*)(from), (size_t)((no_of_words) << 2));
template <class T> template <class T>
struct Ptr { struct Ptr {
......
...@@ -46,6 +46,7 @@ Ndb_local_table_info::Ndb_local_table_info(NdbTableImpl *table_impl) ...@@ -46,6 +46,7 @@ Ndb_local_table_info::Ndb_local_table_info(NdbTableImpl *table_impl)
m_table_impl= table_impl; m_table_impl= table_impl;
m_first_tuple_id = ~(Uint64)0; m_first_tuple_id = ~(Uint64)0;
m_last_tuple_id = ~(Uint64)0; m_last_tuple_id = ~(Uint64)0;
m_highest_seen = 0;
} }
Ndb_local_table_info::~Ndb_local_table_info() Ndb_local_table_info::~Ndb_local_table_info()
......
...@@ -36,6 +36,7 @@ public: ...@@ -36,6 +36,7 @@ public:
// range of cached tuple ids per thread // range of cached tuple ids per thread
Uint64 m_first_tuple_id; Uint64 m_first_tuple_id;
Uint64 m_last_tuple_id; Uint64 m_last_tuple_id;
Uint64 m_highest_seen;
Uint64 m_local_data[1]; // Must be last member. Used to access extra space. Uint64 m_local_data[1]; // Must be last member. Used to access extra space.
private: private:
......
...@@ -767,8 +767,8 @@ Ndb::getNodeId() ...@@ -767,8 +767,8 @@ Ndb::getNodeId()
} }
/**************************************************************************** /****************************************************************************
Uint64 getAutoIncrementValue( const char* aTableName, int getAutoIncrementValue( const char* aTableName,
Uint64 & tupleId, Uint64 & autoValue,
Uint32 cacheSize, Uint32 cacheSize,
Uint64 step, Uint64 step,
Uint64 start); Uint64 start);
...@@ -779,6 +779,7 @@ Parameters: aTableName (IN) : The table name. ...@@ -779,6 +779,7 @@ Parameters: aTableName (IN) : The table name.
step (IN) : Specifies the step between the step (IN) : Specifies the step between the
autoincrement values. autoincrement values.
start (IN) : Start value for first value start (IN) : Start value for first value
Returns: 0 if succesful, -1 if error encountered
Remark: Returns a new autoincrement value to the application. Remark: Returns a new autoincrement value to the application.
The autoincrement values can be increased by steps The autoincrement values can be increased by steps
(default 1) and a number of values can be prefetched (default 1) and a number of values can be prefetched
...@@ -892,9 +893,18 @@ Ndb::getTupleIdFromNdb(Ndb_local_table_info* info, ...@@ -892,9 +893,18 @@ Ndb::getTupleIdFromNdb(Ndb_local_table_info* info,
DBUG_RETURN(0); DBUG_RETURN(0);
} }
/****************************************************************************
int readAutoIncrementValue( const char* aTableName,
Uint64 & autoValue);
Parameters: aTableName (IN) : The table name.
autoValue (OUT) : The current autoincrement value
Returns: 0 if succesful, -1 if error encountered
Remark: Returns the current autoincrement value to the application.
****************************************************************************/
int int
Ndb::readAutoIncrementValue(const char* aTableName, Ndb::readAutoIncrementValue(const char* aTableName,
Uint64 & tupleId) Uint64 & autoValue)
{ {
DBUG_ENTER("Ndb::readAutoIncrementValue"); DBUG_ENTER("Ndb::readAutoIncrementValue");
BaseString internal_tabname(internalize_table_name(aTableName)); BaseString internal_tabname(internalize_table_name(aTableName));
...@@ -905,15 +915,15 @@ Ndb::readAutoIncrementValue(const char* aTableName, ...@@ -905,15 +915,15 @@ Ndb::readAutoIncrementValue(const char* aTableName,
theError.code = theDictionary->getNdbError().code; theError.code = theDictionary->getNdbError().code;
DBUG_RETURN(-1); DBUG_RETURN(-1);
} }
if (readTupleIdFromNdb(info, tupleId) == -1) if (readTupleIdFromNdb(info, autoValue) == -1)
DBUG_RETURN(-1); DBUG_RETURN(-1);
DBUG_PRINT("info", ("value %lu", (ulong)tupleId)); DBUG_PRINT("info", ("value %lu", (ulong)autoValue));
DBUG_RETURN(0); DBUG_RETURN(0);
} }
int int
Ndb::readAutoIncrementValue(const NdbDictionary::Table * aTable, Ndb::readAutoIncrementValue(const NdbDictionary::Table * aTable,
Uint64 & tupleId) Uint64 & autoValue)
{ {
DBUG_ENTER("Ndb::readAutoIncrementValue"); DBUG_ENTER("Ndb::readAutoIncrementValue");
assert(aTable != 0); assert(aTable != 0);
...@@ -926,9 +936,9 @@ Ndb::readAutoIncrementValue(const NdbDictionary::Table * aTable, ...@@ -926,9 +936,9 @@ Ndb::readAutoIncrementValue(const NdbDictionary::Table * aTable,
theError.code = theDictionary->getNdbError().code; theError.code = theDictionary->getNdbError().code;
DBUG_RETURN(-1); DBUG_RETURN(-1);
} }
if (readTupleIdFromNdb(info, tupleId) == -1) if (readTupleIdFromNdb(info, autoValue) == -1)
DBUG_RETURN(-1); DBUG_RETURN(-1);
DBUG_PRINT("info", ("value %lu", (ulong)tupleId)); DBUG_PRINT("info", ("value %lu", (ulong)autoValue));
DBUG_RETURN(0); DBUG_RETURN(0);
} }
...@@ -956,9 +966,20 @@ Ndb::readTupleIdFromNdb(Ndb_local_table_info* info, ...@@ -956,9 +966,20 @@ Ndb::readTupleIdFromNdb(Ndb_local_table_info* info,
DBUG_RETURN(0); DBUG_RETURN(0);
} }
/****************************************************************************
int setAutoIncrementValue( const char* aTableName,
Uint64 autoValue,
bool modify);
Parameters: aTableName (IN) : The table name.
autoValue (IN) : The new autoincrement value
modify (IN) : Modify existing value (not initialization)
Returns: 0 if succesful, -1 if error encountered
Remark: Sets a new autoincrement value for the application.
****************************************************************************/
int int
Ndb::setAutoIncrementValue(const char* aTableName, Ndb::setAutoIncrementValue(const char* aTableName,
Uint64 tupleId, bool increase) Uint64 autoValue, bool modify)
{ {
DBUG_ENTER("Ndb::setAutoIncrementValue"); DBUG_ENTER("Ndb::setAutoIncrementValue");
BaseString internal_tabname(internalize_table_name(aTableName)); BaseString internal_tabname(internalize_table_name(aTableName));
...@@ -969,14 +990,14 @@ Ndb::setAutoIncrementValue(const char* aTableName, ...@@ -969,14 +990,14 @@ Ndb::setAutoIncrementValue(const char* aTableName,
theError.code = theDictionary->getNdbError().code; theError.code = theDictionary->getNdbError().code;
DBUG_RETURN(-1); DBUG_RETURN(-1);
} }
if (setTupleIdInNdb(info, tupleId, increase) == -1) if (setTupleIdInNdb(info, autoValue, modify) == -1)
DBUG_RETURN(-1); DBUG_RETURN(-1);
DBUG_RETURN(0); DBUG_RETURN(0);
} }
int int
Ndb::setAutoIncrementValue(const NdbDictionary::Table * aTable, Ndb::setAutoIncrementValue(const NdbDictionary::Table * aTable,
Uint64 tupleId, bool increase) Uint64 autoValue, bool modify)
{ {
DBUG_ENTER("Ndb::setAutoIncrementValue"); DBUG_ENTER("Ndb::setAutoIncrementValue");
assert(aTable != 0); assert(aTable != 0);
...@@ -989,38 +1010,42 @@ Ndb::setAutoIncrementValue(const NdbDictionary::Table * aTable, ...@@ -989,38 +1010,42 @@ Ndb::setAutoIncrementValue(const NdbDictionary::Table * aTable,
theError.code = theDictionary->getNdbError().code; theError.code = theDictionary->getNdbError().code;
DBUG_RETURN(-1); DBUG_RETURN(-1);
} }
if (setTupleIdInNdb(info, tupleId, increase) == -1) if (setTupleIdInNdb(info, autoValue, modify) == -1)
DBUG_RETURN(-1); DBUG_RETURN(-1);
DBUG_RETURN(0); DBUG_RETURN(0);
} }
int int
Ndb::setTupleIdInNdb(Ndb_local_table_info* info, Ndb::setTupleIdInNdb(Ndb_local_table_info* info,
Uint64 tupleId, bool increase) Uint64 tupleId, bool modify)
{ {
DBUG_ENTER("Ndb::setTupleIdInNdb"); DBUG_ENTER("Ndb::setTupleIdInNdb");
if (increase) if (modify)
{ {
if (info->m_first_tuple_id != info->m_last_tuple_id) if (checkTupleIdInNdb(info, tupleId))
{ {
assert(info->m_first_tuple_id < info->m_last_tuple_id); if (info->m_first_tuple_id != info->m_last_tuple_id)
if (tupleId <= info->m_first_tuple_id + 1)
DBUG_RETURN(0);
if (tupleId <= info->m_last_tuple_id)
{ {
info->m_first_tuple_id = tupleId - 1; assert(info->m_first_tuple_id < info->m_last_tuple_id);
DBUG_PRINT("info", if (tupleId <= info->m_first_tuple_id + 1)
("Setting next auto increment cached value to %lu", DBUG_RETURN(0);
(ulong)tupleId)); if (tupleId <= info->m_last_tuple_id)
DBUG_RETURN(0); {
info->m_first_tuple_id = tupleId - 1;
DBUG_PRINT("info",
("Setting next auto increment cached value to %lu",
(ulong)tupleId));
DBUG_RETURN(0);
}
} }
/*
* if tupleId <= NEXTID, do nothing. otherwise update NEXTID to
* tupleId and set cached range to first = last = tupleId - 1.
*/
Uint64 opValue = tupleId;
if (opTupleIdOnNdb(info, opValue, 2) == -1)
DBUG_RETURN(-1);
} }
/*
* if tupleId <= NEXTID, do nothing. otherwise update NEXTID to
* tupleId and set cached range to first = last = tupleId - 1.
*/
if (opTupleIdOnNdb(info, tupleId, 2) == -1)
DBUG_RETURN(-1);
} }
else else
{ {
...@@ -1033,6 +1058,32 @@ Ndb::setTupleIdInNdb(Ndb_local_table_info* info, ...@@ -1033,6 +1058,32 @@ Ndb::setTupleIdInNdb(Ndb_local_table_info* info,
DBUG_RETURN(0); DBUG_RETURN(0);
} }
int
Ndb::checkTupleIdInNdb(Ndb_local_table_info* info, Uint64 tupleId)
{
DBUG_ENTER("Ndb::checkTupleIdIndNdb");
if ((info->m_first_tuple_id != ~(Uint64)0) &&
(info->m_first_tuple_id > tupleId))
{
/*
* If we have ever cached a value in this object and this cached
* value is larger than the value we're trying to set then we
* need not check with the real value in the SYSTAB_0 table.
*/
DBUG_RETURN(0);
}
if (info->m_highest_seen > tupleId)
{
/*
* Although we've never cached any higher value we have read
* a higher value and again it isn't necessary to change the
* auto increment value.
*/
DBUG_RETURN(0);
}
DBUG_RETURN(1);
}
int int
Ndb::opTupleIdOnNdb(Ndb_local_table_info* info, Uint64 & opValue, Uint32 op) Ndb::opTupleIdOnNdb(Ndb_local_table_info* info, Uint64 & opValue, Uint32 op)
{ {
...@@ -1094,6 +1145,7 @@ Ndb::opTupleIdOnNdb(Ndb_local_table_info* info, Uint64 & opValue, Uint32 op) ...@@ -1094,6 +1145,7 @@ Ndb::opTupleIdOnNdb(Ndb_local_table_info* info, Uint64 & opValue, Uint32 op)
info->m_first_tuple_id = ~(Uint64)0; info->m_first_tuple_id = ~(Uint64)0;
info->m_last_tuple_id = ~(Uint64)0; info->m_last_tuple_id = ~(Uint64)0;
info->m_highest_seen = 0;
break; break;
case 2: case 2:
tOperation->interpretedUpdateTuple(); tOperation->interpretedUpdateTuple();
...@@ -1103,19 +1155,18 @@ Ndb::opTupleIdOnNdb(Ndb_local_table_info* info, Uint64 & opValue, Uint32 op) ...@@ -1103,19 +1155,18 @@ Ndb::opTupleIdOnNdb(Ndb_local_table_info* info, Uint64 & opValue, Uint32 op)
// compare NEXTID >= opValue // compare NEXTID >= opValue
tOperation->branch_le(2, 1, 0); tOperation->branch_le(2, 1, 0);
tOperation->write_attr("NEXTID", 1); tOperation->write_attr("NEXTID", 1);
tOperation->interpret_exit_ok();
tOperation->def_label(0); tOperation->def_label(0);
tOperation->interpret_exit_nok(9999); tOperation->interpret_exit_ok();
tRecAttrResult = tOperation->getValue("NEXTID");
if (tConnection->execute( Commit ) == -1) if (tConnection->execute( Commit ) == -1)
{ {
if (tConnection->theError.code != 9999) goto error_handler;
goto error_handler;
} }
else else
{ {
info->m_highest_seen = tRecAttrResult->u_64_value();
DBUG_PRINT("info", DBUG_PRINT("info",
("Setting next auto increment value (db) to %lu", ("Setting auto increment value (db) to %lu",
(ulong)opValue)); (ulong)opValue));
info->m_first_tuple_id = info->m_last_tuple_id = opValue - 1; info->m_first_tuple_id = info->m_last_tuple_id = opValue - 1;
} }
...@@ -1126,7 +1177,7 @@ Ndb::opTupleIdOnNdb(Ndb_local_table_info* info, Uint64 & opValue, Uint32 op) ...@@ -1126,7 +1177,7 @@ Ndb::opTupleIdOnNdb(Ndb_local_table_info* info, Uint64 & opValue, Uint32 op)
tRecAttrResult = tOperation->getValue("NEXTID"); tRecAttrResult = tOperation->getValue("NEXTID");
if (tConnection->execute( Commit ) == -1 ) if (tConnection->execute( Commit ) == -1 )
goto error_handler; goto error_handler;
opValue = tRecAttrResult->u_64_value(); // out info->m_highest_seen = opValue = tRecAttrResult->u_64_value(); // out
break; break;
default: default:
goto error_handler; goto error_handler;
...@@ -1415,11 +1466,7 @@ Ndb::printState(const char* fmt, ...) ...@@ -1415,11 +1466,7 @@ Ndb::printState(const char* fmt, ...)
NdbMutex_Lock(ndb_print_state_mutex); NdbMutex_Lock(ndb_print_state_mutex);
bool dups = false; bool dups = false;
unsigned i; unsigned i;
ndbout << buf << " ndb=" << hex << this << dec; ndbout << buf << " ndb=" << hex << (void*)this << endl;
#ifndef NDB_WIN32
ndbout << " thread=" << (int)pthread_self();
#endif
ndbout << endl;
for (unsigned n = 0; n < MAX_NDB_NODES; n++) { for (unsigned n = 0; n < MAX_NDB_NODES; n++) {
NdbTransaction* con = theConnectionArray[n]; NdbTransaction* con = theConnectionArray[n];
if (con != 0) { if (con != 0) {
......
...@@ -35,6 +35,7 @@ ...@@ -35,6 +35,7 @@
#include "NdbBlobImpl.hpp" #include "NdbBlobImpl.hpp"
#include <AttributeHeader.hpp> #include <AttributeHeader.hpp>
#include <my_sys.h> #include <my_sys.h>
#include <NdbSleep.h>
#define DEBUG_PRINT 0 #define DEBUG_PRINT 0
#define INCOMPATIBLE_VERSION -2 #define INCOMPATIBLE_VERSION -2
...@@ -886,7 +887,23 @@ NdbDictInterface::dictSignal(NdbApiSignal* signal, ...@@ -886,7 +887,23 @@ NdbDictInterface::dictSignal(NdbApiSignal* signal,
{ {
DBUG_ENTER("NdbDictInterface::dictSignal"); DBUG_ENTER("NdbDictInterface::dictSignal");
DBUG_PRINT("enter", ("useMasterNodeId: %d", useMasterNodeId)); DBUG_PRINT("enter", ("useMasterNodeId: %d", useMasterNodeId));
for(Uint32 i = 0; i<RETRIES; i++){
int sleep = 50;
int mod = 5;
for(Uint32 i = 0; i<RETRIES; i++)
{
if (i > 0)
NdbSleep_MilliSleep(sleep + 10 * (rand() % mod));
if (i == RETRIES / 2)
{
mod = 10;
}
if (i == 3*RETRIES/4)
{
sleep = 100;
}
//if (useMasterNodeId == 0) //if (useMasterNodeId == 0)
m_buffer.clear(); m_buffer.clear();
......
...@@ -291,6 +291,7 @@ ErrorBundle ErrorCodes[] = { ...@@ -291,6 +291,7 @@ ErrorBundle ErrorCodes[] = {
{ 242, AE, "Zero concurrency in scan"}, { 242, AE, "Zero concurrency in scan"},
{ 244, AE, "Too high concurrency in scan"}, { 244, AE, "Too high concurrency in scan"},
{ 269, AE, "No condition and attributes to read in scan"}, { 269, AE, "No condition and attributes to read in scan"},
{ 874, AE, "Too much attrinfo (e.g. scan filter) for scan in tuple manager" },
{ 4600, AE, "Transaction is already started"}, { 4600, AE, "Transaction is already started"},
{ 4601, AE, "Transaction is not started"}, { 4601, AE, "Transaction is not started"},
{ 4602, AE, "You must call getNdbOperation before executeScan" }, { 4602, AE, "You must call getNdbOperation before executeScan" },
......
...@@ -77,6 +77,11 @@ int runTestIncValue32(NDBT_Context* ctx, NDBT_Step* step){ ...@@ -77,6 +77,11 @@ int runTestIncValue32(NDBT_Context* ctx, NDBT_Step* step){
const NdbDictionary::Table * pTab = ctx->getTab(); const NdbDictionary::Table * pTab = ctx->getTab();
Ndb* pNdb = GETNDB(step); Ndb* pNdb = GETNDB(step);
if (strcmp(pTab->getName(), "T1") != 0) {
g_err << "runTestBug19537: skip, table != T1" << endl;
return NDBT_OK;
}
NdbConnection* pTrans = pNdb->startTransaction(); NdbConnection* pTrans = pNdb->startTransaction();
if (pTrans == NULL){ if (pTrans == NULL){
...@@ -258,6 +263,84 @@ int runTestBug19537(NDBT_Context* ctx, NDBT_Step* step){ ...@@ -258,6 +263,84 @@ int runTestBug19537(NDBT_Context* ctx, NDBT_Step* step){
} }
int runTestBug34107(NDBT_Context* ctx, NDBT_Step* step){
int result = NDBT_OK;
const NdbDictionary::Table * pTab = ctx->getTab();
Ndb* pNdb = GETNDB(step);
int i;
for (i = 0; i <= 1; i++) {
g_info << "bug34107:" << (i == 0 ? " small" : " too big") << endl;
NdbConnection* pTrans = pNdb->startTransaction();
if (pTrans == NULL){
ERR(pNdb->getNdbError());
return NDBT_FAILED;
}
NdbScanOperation* pOp = pTrans->getNdbScanOperation(pTab->getName());
if (pOp == NULL) {
ERR(pTrans->getNdbError());
pNdb->closeTransaction(pTrans);
return NDBT_FAILED;
}
if (pOp->readTuples() == -1) {
ERR(pOp->getNdbError());
pNdb->closeTransaction(pTrans);
return NDBT_FAILED;
}
int n = i == 0 ? 10000 : 30000;
int k;
for (k = 0; k < n; k++) {
// inserts 1 word ATTRINFO
if (pOp->interpret_exit_ok() == -1) {
ERR(pOp->getNdbError());
pNdb->closeTransaction(pTrans);
return NDBT_FAILED;
}
}
if (pTrans->execute(NoCommit) == -1) {
ERR(pTrans->getNdbError());
pNdb->closeTransaction(pTrans);
return NDBT_FAILED;
}
int ret;
while ((ret = pOp->nextResult()) == 0)
;
g_info << "ret=" << ret << " err=" << pOp->getNdbError().code << endl;
if (i == 0 && ret != 1) {
ERR(pTrans->getNdbError());
pNdb->closeTransaction(pTrans);
return NDBT_FAILED;
}
if (i == 1 && ret != -1) {
g_err << "unexpected big filter success" << endl;
pNdb->closeTransaction(pTrans);
return NDBT_FAILED;
}
if (i == 1 && pOp->getNdbError().code != 874) {
g_err << "unexpected big filter error code, wanted 874" << endl;
ERR(pTrans->getNdbError());
pNdb->closeTransaction(pTrans);
return NDBT_FAILED;
}
pNdb->closeTransaction(pTrans);
}
return NDBT_OK;
}
NDBT_TESTSUITE(testInterpreter); NDBT_TESTSUITE(testInterpreter);
TESTCASE("IncValue32", TESTCASE("IncValue32",
"Test incValue for 32 bit integer\n"){ "Test incValue for 32 bit integer\n"){
...@@ -277,6 +360,12 @@ TESTCASE("Bug19537", ...@@ -277,6 +360,12 @@ TESTCASE("Bug19537",
INITIALIZER(runTestBug19537); INITIALIZER(runTestBug19537);
FINALIZER(runClearTable); FINALIZER(runClearTable);
} }
TESTCASE("Bug34107",
"Test too big scan filter (error 874)\n"){
INITIALIZER(runLoadTable);
INITIALIZER(runTestBug34107);
FINALIZER(runClearTable);
}
#if 0 #if 0
TESTCASE("MaxTransactions", TESTCASE("MaxTransactions",
"Start transactions until no more can be created\n"){ "Start transactions until no more can be created\n"){
......
This diff is collapsed.
...@@ -649,10 +649,10 @@ max-time: 1000 ...@@ -649,10 +649,10 @@ max-time: 1000
cmd: testNdbApi cmd: testNdbApi
args: -n Bug28443 args: -n Bug28443
#max-time: 500 max-time: 500
#cmd: testInterpreter cmd: testInterpreter
#args: T1 args: T1
#
max-time: 150000 max-time: 150000
cmd: testOperations cmd: testOperations
args: args:
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment