Commit e4f0614c authored by unknown's avatar unknown

NDB bug-6018 support writeTuple with blobs


mysql-test/r/ndb_blob.result:
  bug-6018
mysql-test/t/ndb_blob.test:
  bug-6018
ndb/include/ndbapi/NdbBlob.hpp:
  bug-6018
ndb/include/ndbapi/NdbConnection.hpp:
  bug-6018
ndb/include/ndbapi/NdbIndexOperation.hpp:
  bug-6018
ndb/include/ndbapi/NdbOperation.hpp:
  bug-6018
ndb/src/ndbapi/NdbBlob.cpp:
  bug-6018
ndb/src/ndbapi/NdbConnection.cpp:
  bug-6018
ndb/src/ndbapi/NdbDictionaryImpl.cpp:
  bug-6018
ndb/src/ndbapi/NdbIndexOperation.cpp:
  bug-6018
ndb/src/ndbapi/NdbOperation.cpp:
  bug-6018
ndb/src/ndbapi/NdbOperationExec.cpp:
  bug-6018
ndb/test/ndbapi/testBlobs.cpp:
  bug-6018
parent 2e7b3801
drop table if exists t1;
drop database if exists mysqltest;
create table t1 (
a int not null primary key,
b tinytext
) engine=ndbcluster;
insert into t1 values(1, 'x');
update t1 set b = 'y';
select * from t1;
a b
1 y
delete from t1;
drop table t1;
create table t1 (
a int not null primary key,
b text not null
) engine=ndbcluster;
insert into t1 values(1, '');
select * from t1;
a b
1
drop table t1;
drop database if exists test2;
set autocommit=0;
create table t1 (
a int not null primary key,
......@@ -102,6 +82,53 @@ commit;
select count(*) from t1;
count(*)
0
replace t1 set a=1,b=@b1,c=111,d=@d1;
replace t1 set a=2,b=@b2,c=222,d=@d2;
commit;
explain select * from t1 where a = 1;
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE t1 const PRIMARY PRIMARY 4 const 1
select a,length(b),substr(b,1+2*900,2),length(d),substr(d,1+3*900,3)
from t1 where a=1;
a length(b) substr(b,1+2*900,2) length(d) substr(d,1+3*900,3)
1 2256 b1 3000 dd1
select a,length(b),substr(b,1+2*9000,2),length(d),substr(d,1+3*9000,3)
from t1 where a=2;
a length(b) substr(b,1+2*9000,2) length(d) substr(d,1+3*9000,3)
2 20000 b2 30000 dd2
replace t1 set a=1,b=@b2,c=111,d=@d2;
replace t1 set a=2,b=@b1,c=222,d=@d1;
commit;
select a,length(b),substr(b,1+2*9000,2),length(d),substr(d,1+3*9000,3)
from t1 where a=1;
a length(b) substr(b,1+2*9000,2) length(d) substr(d,1+3*9000,3)
1 20000 b2 30000 dd2
select a,length(b),substr(b,1+2*900,2),length(d),substr(d,1+3*900,3)
from t1 where a=2;
a length(b) substr(b,1+2*900,2) length(d) substr(d,1+3*900,3)
2 2256 b1 3000 dd1
replace t1 set a=1,b=concat(@b2,@b2),c=111,d=concat(@d2,@d2);
replace t1 set a=2,b=concat(@b1,@b1),c=222,d=concat(@d1,@d1);
commit;
select a,length(b),substr(b,1+4*9000,2),length(d),substr(d,1+6*9000,3)
from t1 where a=1;
a length(b) substr(b,1+4*9000,2) length(d) substr(d,1+6*9000,3)
1 40000 b2 60000 dd2
select a,length(b),substr(b,1+4*900,2),length(d),substr(d,1+6*900,3)
from t1 where a=2;
a length(b) substr(b,1+4*900,2) length(d) substr(d,1+6*900,3)
2 4512 b1 6000 dd1
replace t1 set a=1,b='xyz',c=111,d=null;
commit;
select a,b from t1 where d is null;
a b
1 xyz
delete from t1 where a=1;
delete from t1 where a=2;
commit;
select count(*) from t1;
count(*)
0
insert into t1 values(1,@b1,111,@d1);
insert into t1 values(2,@b2,222,@d2);
commit;
......@@ -241,90 +268,6 @@ a b c d
7 7xb7 777 7xdd7
8 8xb8 888 8xdd8
9 9xb9 999 9xdd9
select * from t1 order by a;
a b c d
1 1xb1 111 1xdd1
2 2xb2 222 2xdd2
3 3xb3 333 3xdd3
4 4xb4 444 4xdd4
5 5xb5 555 5xdd5
6 6xb6 666 6xdd6
7 7xb7 777 7xdd7
8 8xb8 888 8xdd8
9 9xb9 999 9xdd9
alter table t1 add x int;
select * from t1 order by a;
a b c d x
1 1xb1 111 1xdd1 NULL
2 2xb2 222 2xdd2 NULL
3 3xb3 333 3xdd3 NULL
4 4xb4 444 4xdd4 NULL
5 5xb5 555 5xdd5 NULL
6 6xb6 666 6xdd6 NULL
7 7xb7 777 7xdd7 NULL
8 8xb8 888 8xdd8 NULL
9 9xb9 999 9xdd9 NULL
alter table t1 drop x;
select * from t1 order by a;
a b c d
1 1xb1 111 1xdd1
2 2xb2 222 2xdd2
3 3xb3 333 3xdd3
4 4xb4 444 4xdd4
5 5xb5 555 5xdd5
6 6xb6 666 6xdd6
7 7xb7 777 7xdd7
8 8xb8 888 8xdd8
9 9xb9 999 9xdd9
create database mysqltest;
use mysqltest;
CREATE TABLE t2 (
a bigint unsigned NOT NULL PRIMARY KEY,
b int unsigned not null,
c int unsigned
) engine=ndbcluster;
insert into t2 values (1,1,1),(2,2,2);
select * from test.t1,t2 where test.t1.a = t2.a order by test.t1.a;
a b c d a b c
1 1xb1 111 1xdd1 1 1 1
2 2xb2 222 2xdd2 2 2 2
drop table t2;
use test;
select * from t1 order by a;
a b c d
1 1xb1 111 1xdd1
2 2xb2 222 2xdd2
3 3xb3 333 3xdd3
4 4xb4 444 4xdd4
5 5xb5 555 5xdd5
6 6xb6 666 6xdd6
7 7xb7 777 7xdd7
8 8xb8 888 8xdd8
9 9xb9 999 9xdd9
alter table t1 add x int;
select * from t1 order by a;
a b c d x
1 1xb1 111 1xdd1 NULL
2 2xb2 222 2xdd2 NULL
3 3xb3 333 3xdd3 NULL
4 4xb4 444 4xdd4 NULL
5 5xb5 555 5xdd5 NULL
6 6xb6 666 6xdd6 NULL
7 7xb7 777 7xdd7 NULL
8 8xb8 888 8xdd8 NULL
9 9xb9 999 9xdd9 NULL
alter table t1 drop x;
select * from t1 order by a;
a b c d
1 1xb1 111 1xdd1
2 2xb2 222 2xdd2
3 3xb3 333 3xdd3
4 4xb4 444 4xdd4
5 5xb5 555 5xdd5
6 6xb6 666 6xdd6
7 7xb7 777 7xdd7
8 8xb8 888 8xdd8
9 9xb9 999 9xdd9
delete from t1 where c >= 100;
commit;
select count(*) from t1;
......@@ -375,8 +318,122 @@ rollback;
select count(*) from t1;
count(*)
0
insert into t1 values(1,'b1',111,'dd1');
insert into t1 values(2,'b2',222,'dd2');
insert into t1 values(3,'b3',333,'dd3');
insert into t1 values(4,'b4',444,'dd4');
insert into t1 values(5,'b5',555,'dd5');
insert into t1 values(6,'b6',666,'dd6');
insert into t1 values(7,'b7',777,'dd7');
insert into t1 values(8,'b8',888,'dd8');
insert into t1 values(9,'b9',999,'dd9');
commit;
select * from t1 order by a;
a b c d
1 b1 111 dd1
2 b2 222 dd2
3 b3 333 dd3
4 b4 444 dd4
5 b5 555 dd5
6 b6 666 dd6
7 b7 777 dd7
8 b8 888 dd8
9 b9 999 dd9
alter table t1 add x int;
select * from t1 order by a;
a b c d x
1 b1 111 dd1 NULL
2 b2 222 dd2 NULL
3 b3 333 dd3 NULL
4 b4 444 dd4 NULL
5 b5 555 dd5 NULL
6 b6 666 dd6 NULL
7 b7 777 dd7 NULL
8 b8 888 dd8 NULL
9 b9 999 dd9 NULL
alter table t1 drop x;
select * from t1 order by a;
a b c d
1 b1 111 dd1
2 b2 222 dd2
3 b3 333 dd3
4 b4 444 dd4
5 b5 555 dd5
6 b6 666 dd6
7 b7 777 dd7
8 b8 888 dd8
9 b9 999 dd9
create database test2;
use test2;
CREATE TABLE t2 (
a bigint unsigned NOT NULL PRIMARY KEY,
b int unsigned not null,
c int unsigned
) engine=ndbcluster;
insert into t2 values (1,1,1),(2,2,2);
select * from test.t1,t2 where test.t1.a = t2.a order by test.t1.a;
a b c d a b c
1 b1 111 dd1 1 1 1
2 b2 222 dd2 2 2 2
drop table t2;
use test;
select * from t1 order by a;
a b c d
1 b1 111 dd1
2 b2 222 dd2
3 b3 333 dd3
4 b4 444 dd4
5 b5 555 dd5
6 b6 666 dd6
7 b7 777 dd7
8 b8 888 dd8
9 b9 999 dd9
alter table t1 add x int;
select * from t1 order by a;
a b c d x
1 b1 111 dd1 NULL
2 b2 222 dd2 NULL
3 b3 333 dd3 NULL
4 b4 444 dd4 NULL
5 b5 555 dd5 NULL
6 b6 666 dd6 NULL
7 b7 777 dd7 NULL
8 b8 888 dd8 NULL
9 b9 999 dd9 NULL
alter table t1 drop x;
select * from t1 order by a;
a b c d
1 b1 111 dd1
2 b2 222 dd2
3 b3 333 dd3
4 b4 444 dd4
5 b5 555 dd5
6 b6 666 dd6
7 b7 777 dd7
8 b8 888 dd8
9 b9 999 dd9
drop table t1;
drop database test2;
create table t1 (
a int not null primary key,
b tinytext
) engine=ndbcluster;
insert into t1 values(1, 'x');
update t1 set b = 'y';
select * from t1;
a b
1 x
delete from t1;
drop table t1;
create table t1 (
a int not null primary key,
b text not null
) engine=ndbcluster;
insert into t1 values(1, '');
select * from t1;
a b
1
drop table t1;
drop database mysqltest;
set autocommit=1;
use test;
CREATE TABLE t1 (
......
......@@ -2,7 +2,7 @@
--disable_warnings
drop table if exists t1;
drop database if exists mysqltest;
drop database if exists test2;
--enable_warnings
#
......@@ -12,31 +12,7 @@ drop database if exists mysqltest;
# A prerequisite for this handler test is that "testBlobs" succeeds.
#
# -- bug-5252 tinytext crashes --
create table t1 (
a int not null primary key,
b tinytext
) engine=ndbcluster;
insert into t1 values(1, 'x');
update t1 set b = 'y';
select * from t1;
delete from t1;
drop table t1;
# -- bug-5013 insert empty string to text --
create table t1 (
a int not null primary key,
b text not null
) engine=ndbcluster;
insert into t1 values(1, '');
select * from t1;
drop table t1;
-- general test starts --
# -- general test starts --
# make test harder with autocommit off
set autocommit=0;
......@@ -117,7 +93,6 @@ from t1 where a=2;
# pk update to null
update t1 set d=null where a=1;
commit;
# FIXME now fails at random due to weird mixup between the 2 rows
select a from t1 where d is null;
# pk delete
......@@ -126,6 +101,49 @@ delete from t1 where a=2;
commit;
select count(*) from t1;
# -- replace ( bug-6018 ) --
# insert
replace t1 set a=1,b=@b1,c=111,d=@d1;
replace t1 set a=2,b=@b2,c=222,d=@d2;
commit;
explain select * from t1 where a = 1;
# pk read
select a,length(b),substr(b,1+2*900,2),length(d),substr(d,1+3*900,3)
from t1 where a=1;
select a,length(b),substr(b,1+2*9000,2),length(d),substr(d,1+3*9000,3)
from t1 where a=2;
# update
replace t1 set a=1,b=@b2,c=111,d=@d2;
replace t1 set a=2,b=@b1,c=222,d=@d1;
commit;
select a,length(b),substr(b,1+2*9000,2),length(d),substr(d,1+3*9000,3)
from t1 where a=1;
select a,length(b),substr(b,1+2*900,2),length(d),substr(d,1+3*900,3)
from t1 where a=2;
# update
replace t1 set a=1,b=concat(@b2,@b2),c=111,d=concat(@d2,@d2);
replace t1 set a=2,b=concat(@b1,@b1),c=222,d=concat(@d1,@d1);
commit;
select a,length(b),substr(b,1+4*9000,2),length(d),substr(d,1+6*9000,3)
from t1 where a=1;
select a,length(b),substr(b,1+4*900,2),length(d),substr(d,1+6*900,3)
from t1 where a=2;
# update to null
replace t1 set a=1,b='xyz',c=111,d=null;
commit;
select a,b from t1 where d is null;
# pk delete
delete from t1 where a=1;
delete from t1 where a=2;
commit;
select count(*) from t1;
# -- hash index ops --
insert into t1 values(1,@b1,111,@d1);
......@@ -231,39 +249,6 @@ where c >= 100;
commit;
select * from t1 where c >= 100 order by a;
# alter table
select * from t1 order by a;
alter table t1 add x int;
select * from t1 order by a;
alter table t1 drop x;
select * from t1 order by a;
# multi db
create database mysqltest;
use mysqltest;
CREATE TABLE t2 (
a bigint unsigned NOT NULL PRIMARY KEY,
b int unsigned not null,
c int unsigned
) engine=ndbcluster;
insert into t2 values (1,1,1),(2,2,2);
select * from test.t1,t2 where test.t1.a = t2.a order by test.t1.a;
drop table t2;
use test;
# alter table
select * from t1 order by a;
alter table t1 add x int;
select * from t1 order by a;
alter table t1 drop x;
select * from t1 order by a;
# range scan delete
delete from t1 where c >= 100;
commit;
......@@ -306,10 +291,77 @@ select a,length(b),substr(b,1+2*900,2),length(d),substr(d,1+3*900,3)
from t1 order by a;
rollback;
select count(*) from t1;
# -- alter table and multi db --
insert into t1 values(1,'b1',111,'dd1');
insert into t1 values(2,'b2',222,'dd2');
insert into t1 values(3,'b3',333,'dd3');
insert into t1 values(4,'b4',444,'dd4');
insert into t1 values(5,'b5',555,'dd5');
insert into t1 values(6,'b6',666,'dd6');
insert into t1 values(7,'b7',777,'dd7');
insert into t1 values(8,'b8',888,'dd8');
insert into t1 values(9,'b9',999,'dd9');
commit;
select * from t1 order by a;
alter table t1 add x int;
select * from t1 order by a;
alter table t1 drop x;
select * from t1 order by a;
create database test2;
use test2;
CREATE TABLE t2 (
a bigint unsigned NOT NULL PRIMARY KEY,
b int unsigned not null,
c int unsigned
) engine=ndbcluster;
insert into t2 values (1,1,1),(2,2,2);
select * from test.t1,t2 where test.t1.a = t2.a order by test.t1.a;
drop table t2;
use test;
select * from t1 order by a;
alter table t1 add x int;
select * from t1 order by a;
alter table t1 drop x;
select * from t1 order by a;
# -- end general test --
drop table t1;
drop database test2;
# -- bug-5252 tinytext crashes --
create table t1 (
a int not null primary key,
b tinytext
) engine=ndbcluster;
insert into t1 values(1, 'x');
update t1 set b = 'y';
select * from t1;
delete from t1;
drop table t1;
# -- bug-5013 insert empty string to text --
create table t1 (
a int not null primary key,
b text not null
) engine=ndbcluster;
insert into t1 values(1, '');
select * from t1;
drop table t1;
drop database mysqltest;
# bug #5349
# -- bug #5349 --
set autocommit=1;
use test;
CREATE TABLE t1 (
......@@ -327,7 +379,7 @@ select * from t1 order by a;
alter table t1 engine=ndb;
select * from t1 order by a;
# bug #5872
# -- bug #5872 --
alter table t1 engine=myisam;
select * from t1 order by a;
drop table t1;
......@@ -36,7 +36,7 @@ class NdbColumnImpl;
* Blob data is stored in 2 places:
*
* - "header" and "inline bytes" stored in the blob attribute
* - "blob parts" stored in a separate table NDB$BLOB_<t>_<v>_<c>
* - "blob parts" stored in a separate table NDB$BLOB_<tid>_<cid>
*
* Inline and part sizes can be set via NdbDictionary::Column methods
* when the table is created.
......@@ -74,23 +74,21 @@ class NdbColumnImpl;
* NdbBlob methods return -1 on error and 0 on success, and use output
* parameters when necessary.
*
* Notes:
* - table and its blob part tables are not created atomically
* - scan must use the "new" interface NdbScanOperation
* - to update a blob in a read op requires exclusive tuple lock
* - update op in scan must do its own getBlobHandle
* - delete creates implicit, not-accessible blob handles
* - NdbOperation::writeTuple does not support blobs
* - there is no support for an asynchronous interface
* Operation types:
* - insertTuple must use setValue if blob column is non-nullable
* - readTuple with exclusive lock can also update existing value
* - updateTuple can overwrite with setValue or update existing value
* - writeTuple always overwrites and must use setValue if non-nullable
* - deleteTuple creates implicit non-accessible blob handles
* - scan with exclusive lock can also update existing value
* - scan "lock takeover" update op must do its own getBlobHandle
*
* Bugs / limitations:
* - scan must use exclusive locking for now
*
* Todo:
* - add scan method hold-read-lock + return-keyinfo
* - check keyinfo length when setting keys
* - check allowed blob ops vs locking mode
* - overload control (too many pending ops)
* - lock mode upgrade should be handled automatically
* - lock mode vs allowed operation is not checked
* - too many pending blob ops can blow up i/o buffers
* - table and its blob part tables are not created atomically
* - there is no support for an asynchronous interface
*/
class NdbBlob {
public:
......@@ -172,19 +170,11 @@ public:
* read in the in/out bytes parameter.
*/
int readData(void* data, Uint32& bytes);
/**
* Read at given position. Does not use or update current position.
*/
int readData(Uint64 pos, void* data, Uint32& bytes);
/**
* Write at current position and set new position to first byte after
* the data written. A write past blob end extends the blob value.
*/
int writeData(const void* data, Uint32 bytes);
/**
* Write at given position. Does not use or update current position.
*/
int writeData(Uint64 pos, const void* data, Uint32 bytes);
/**
* Return the blob column.
*/
......@@ -266,14 +256,17 @@ private:
Buf();
~Buf();
void alloc(unsigned n);
void copyfrom(const Buf& src);
};
Buf theKeyBuf;
Buf theAccessKeyBuf;
Buf theHeadInlineBuf;
Buf theHeadInlineCopyBuf; // for writeTuple
Buf thePartBuf;
Head* theHead;
char* theInlineData;
NdbRecAttr* theHeadInlineRecAttr;
NdbOperation* theHeadInlineReadOp;
bool theHeadInlineUpdateFlag;
// length and read/write position
int theNullFlag;
......@@ -294,6 +287,7 @@ private:
bool isReadOp();
bool isInsertOp();
bool isUpdateOp();
bool isWriteOp();
bool isDeleteOp();
bool isScanOp();
// computations
......@@ -309,12 +303,13 @@ private:
void getHeadFromRecAttr();
int setHeadInlineValue(NdbOperation* anOp);
// data operations
int readDataPrivate(Uint64 pos, char* buf, Uint32& bytes);
int writeDataPrivate(Uint64 pos, const char* buf, Uint32 bytes);
int readDataPrivate(char* buf, Uint32& bytes);
int writeDataPrivate(const char* buf, Uint32 bytes);
int readParts(char* buf, Uint32 part, Uint32 count);
int insertParts(const char* buf, Uint32 part, Uint32 count);
int updateParts(const char* buf, Uint32 part, Uint32 count);
int deleteParts(Uint32 part, Uint32 count);
int deletePartsUnknown(Uint32 part);
// pending ops
int executePendingBlobReads();
int executePendingBlobWrites();
......
......@@ -526,7 +526,7 @@ private:
int sendCOMMIT(); // Send a TC_COMMITREQ signal;
void setGCI(int GCI); // Set the global checkpoint identity
int OpCompleteFailure(Uint8 abortoption);
int OpCompleteFailure(Uint8 abortoption, bool setFailure = true);
int OpCompleteSuccess();
void CompletedOperations(); // Move active ops to list of completed
......@@ -552,7 +552,7 @@ private:
void setOperationErrorCode(int anErrorCode);
// Indicate something went wrong in the definition phase
void setOperationErrorCodeAbort(int anErrorCode);
void setOperationErrorCodeAbort(int anErrorCode, int abortOption = -1);
int checkMagicNumber(); // Verify correct object
NdbOperation* getNdbOperation(const class NdbTableImpl* aTable,
......
......@@ -49,6 +49,9 @@ public:
* @{
*/
/** insert is not allowed */
int insertTuple();
/**
* Define the NdbIndexOperation to be a standard operation of type readTuple.
* When calling NdbConnection::execute, this operation
......@@ -193,6 +196,7 @@ private:
// Private attributes
const NdbIndexImpl* m_theIndex;
const NdbTableImpl* m_thePrimaryTable;
Uint32 m_theIndexDefined[NDB_MAX_ATTRIBUTES_IN_INDEX][3];
Uint32 m_theIndexLen; // Length of the index in words
Uint32 m_theNoOfIndexDefined; // The number of index attributes
......
......@@ -918,6 +918,13 @@ protected:
// Blobs in this operation
NdbBlob* theBlobList;
/*
* Abort option per operation, used by blobs. Default -1. If set,
* overrides abort option on connection level. If set to IgnoreError,
* does not cause execute() to return failure. This is different from
* IgnoreError on connection level.
*/
Int8 m_abortOption;
};
#ifdef NDB_NO_DROPPED_SIGNAL
......@@ -1160,5 +1167,3 @@ NdbOperation::setValue(Uint32 anAttrId, double aPar)
}
#endif
This diff is collapsed.
......@@ -170,12 +170,14 @@ Remark: Sets an error code on the connection object from an
operation object.
*****************************************************************************/
void
NdbConnection::setOperationErrorCodeAbort(int error)
NdbConnection::setOperationErrorCodeAbort(int error, int abortOption)
{
DBUG_ENTER("NdbConnection::setOperationErrorCodeAbort");
if (abortOption == -1)
abortOption = m_abortOption;
if (theTransactionIsStarted == false) {
theCommitStatus = Aborted;
} else if ((m_abortOption == AbortOnError) &&
} else if ((abortOption == AbortOnError) &&
(theCommitStatus != Committed) &&
(theCommitStatus != Aborted)) {
theCommitStatus = NeedAbort;
......@@ -335,8 +337,11 @@ NdbConnection::execute(ExecType aTypeOfExec,
tOp = tOp->next();
}
}
if (executeNoBlobs(tExecType, abortOption, forceSend) == -1)
ret = -1;
assert(theFirstOpInList == NULL && theLastOpInList == NULL);
{
NdbOperation* tOp = theCompletedFirstOp;
while (tOp != NULL) {
......@@ -360,6 +365,7 @@ NdbConnection::execute(ExecType aTypeOfExec,
theLastOpInList->next(tRestOp);
theLastOpInList = tLastOp;
}
assert(theFirstOpInList == NULL || tExecType == NoCommit);
} while (theFirstOpInList != NULL || tExecType != aTypeOfExec);
DBUG_RETURN(ret);
......@@ -1806,11 +1812,12 @@ Parameters: aErrorCode: The error code.
Remark: An operation was completed with failure.
*******************************************************************************/
int
NdbConnection::OpCompleteFailure(Uint8 abortOption)
NdbConnection::OpCompleteFailure(Uint8 abortOption, bool setFailure)
{
Uint32 tNoComp = theNoOfOpCompleted;
Uint32 tNoSent = theNoOfOpSent;
theCompletionStatus = NdbConnection::CompletedFailure;
if (setFailure)
theCompletionStatus = NdbConnection::CompletedFailure;
tNoComp++;
theNoOfOpCompleted = tNoComp;
if (tNoComp == tNoSent) {
......
......@@ -47,13 +47,15 @@
* Column
*/
NdbColumnImpl::NdbColumnImpl()
: NdbDictionary::Column(* this), m_facade(this)
: NdbDictionary::Column(* this), m_facade(this),
m_attrId(-1)
{
init();
}
NdbColumnImpl::NdbColumnImpl(NdbDictionary::Column & f)
: NdbDictionary::Column(* this), m_facade(&f)
: NdbDictionary::Column(* this), m_facade(&f),
m_attrId(-1)
{
init();
}
......@@ -93,8 +95,7 @@ NdbColumnImpl::init(Type t)
{
// do not use default_charset_info as it may not be initialized yet
// use binary collation until NDB tests can handle charsets
CHARSET_INFO* default_cs = &my_charset_latin1_bin;
m_attrId = -1;
CHARSET_INFO* default_cs = &my_charset_bin;
m_type = t;
switch (m_type) {
case Tinyint:
......
......@@ -71,6 +71,7 @@ NdbIndexOperation::indxInit(const NdbIndexImpl * anIndex,
return -1;
}
m_theIndex = anIndex;
m_thePrimaryTable = aTable;
m_accessTable = anIndex->m_table;
m_theIndexLen = 0;
m_theNoOfIndexDefined = 0;
......@@ -102,6 +103,12 @@ int NdbIndexOperation::readTuple(NdbOperation::LockMode lm)
};
}
int NdbIndexOperation::insertTuple()
{
setErrorCode(4200);
return -1;
}
int NdbIndexOperation::readTuple()
{
// First check that index is unique
......@@ -341,12 +348,11 @@ int NdbIndexOperation::equal_impl(const NdbColumnImpl* tAttrInfo,
theDistrGroupIndicator = 1;
}//if
/**************************************************************************
* If the operation is an insert request and the attribute is stored then
* If the operation is a write request and the attribute is stored then
* we also set the value in the stored part through putting the
* information in the INDXATTRINFO signals.
*************************************************************************/
if ((tOpType == InsertRequest) ||
(tOpType == WriteRequest)) {
if ((tOpType == WriteRequest)) {
if (!tAttrInfo->m_indexOnly){
// invalid data can crash kernel
if (cs != NULL &&
......@@ -357,7 +363,13 @@ int NdbIndexOperation::equal_impl(const NdbColumnImpl* tAttrInfo,
goto equal_error4;
Uint32 ahValue;
Uint32 sz = totalSizeInWords;
AttributeHeader::init(&ahValue, tAttrId, sz);
/*
* XXX should be linked in metadata but cannot now because
* things can be defined in arbitrary order
*/
const NdbColumnImpl* primaryCol = m_thePrimaryTable->getColumn(tAttrInfo->m_name.c_str());
assert(primaryCol != NULL);
AttributeHeader::init(&ahValue, primaryCol->m_attrId, sz);
insertATTRINFO( ahValue );
insertATTRINFOloop((Uint32*)aValueToWrite, sizeInWords);
if (bitsInLastWord != 0) {
......@@ -369,7 +381,6 @@ int NdbIndexOperation::equal_impl(const NdbColumnImpl* tAttrInfo,
}//if
}//if
}//if
/**************************************************************************
* Store the Key information in the TCINDXREQ and INDXKEYINFO signals.
*************************************************************************/
......@@ -734,13 +745,10 @@ NdbIndexOperation::receiveTCINDXREF( NdbApiSignal* aSignal)
}//if
theStatus = Finished;
theNdbCon->theReturnStatus = NdbConnection::ReturnFailure;
Uint32 errorCode = tcIndxRef->errorCode;
theError.code = errorCode;
theNdbCon->setOperationErrorCodeAbort(errorCode);
return theNdbCon->OpCompleteFailure(theNdbCon->m_abortOption);
}//NdbIndexOperation::receiveTCINDXREF()
......@@ -78,7 +78,8 @@ NdbOperation::NdbOperation(Ndb* aNdb) :
m_tcReqGSN(GSN_TCKEYREQ),
m_keyInfoGSN(GSN_KEYINFO),
m_attrInfoGSN(GSN_ATTRINFO),
theBlobList(NULL)
theBlobList(NULL),
m_abortOption(-1)
{
theReceiver.init(NdbReceiver::NDB_OPERATION, this);
theError.code = 0;
......@@ -167,6 +168,7 @@ NdbOperation::init(const NdbTableImpl* tab, NdbConnection* myConnection){
theTotalNrOfKeyWordInSignal = 8;
theMagicNumber = 0xABCDEF01;
theBlobList = NULL;
m_abortOption = -1;
tSignal = theNdb->getSignal();
if (tSignal == NULL)
......
......@@ -191,7 +191,8 @@ NdbOperation::prepareSend(Uint32 aTC_ConnectPtr, Uint64 aTransId)
Uint8 tDirtyIndicator = theDirtyIndicator;
OperationType tOperationType = theOperationType;
Uint32 tTupKeyLen = theTupKeyLen;
Uint8 abortOption = theNdbCon->m_abortOption;
Uint8 abortOption =
m_abortOption != -1 ? m_abortOption : theNdbCon->m_abortOption;
tcKeyReq->setDirtyFlag(tReqInfo, tDirtyIndicator);
tcKeyReq->setOperationType(tReqInfo, tOperationType);
......@@ -541,17 +542,20 @@ NdbOperation::receiveTCKEYREF( NdbApiSignal* aSignal)
return -1;
}//if
AbortOption ao = (AbortOption)theNdbCon->m_abortOption;
AbortOption ao = (AbortOption)
(m_abortOption != -1 ? m_abortOption : theNdbCon->m_abortOption);
theReceiver.m_received_result_length = ~0;
theStatus = Finished;
theNdbCon->theReturnStatus = NdbConnection::ReturnFailure;
// blobs want this
if (m_abortOption != IgnoreError)
theNdbCon->theReturnStatus = NdbConnection::ReturnFailure;
theError.code = aSignal->readData(4);
theNdbCon->setOperationErrorCodeAbort(aSignal->readData(4));
theNdbCon->setOperationErrorCodeAbort(aSignal->readData(4), ao);
if(theOperationType != ReadRequest || !theSimpleIndicator) // not simple read
return theNdbCon->OpCompleteFailure(ao);
return theNdbCon->OpCompleteFailure(ao, m_abortOption != IgnoreError);
/**
* If TCKEYCONF has arrived
......
This diff is collapsed.
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