1
0
mirror of https://github.com/MariaDB/server.git synced 2025-08-07 00:04:31 +03:00

Merged new ndb_insert.test and .result

sql/ha_ndbcluster.cc:
  Auto merged
sql/ha_ndbcluster.h:
  Auto merged
mysql-test/r/ndb_insert.result:
  Merge new test cases
mysql-test/t/ndb_insert.test:
  Merge new test cases
This commit is contained in:
unknown
2004-09-20 11:14:31 +02:00
6 changed files with 312 additions and 59 deletions

View File

@@ -420,6 +420,9 @@ INSERT INTO t1 VALUES
(1,1,1),(2,2,2),(3,3,3),(4,4,4),(5,5,5), (1,1,1),(2,2,2),(3,3,3),(4,4,4),(5,5,5),
(6,6,6),(7,7,7),(8,8,8),(9,9,9),(10,10,10); (6,6,6),(7,7,7),(8,8,8),(9,9,9),(10,10,10);
ERROR 23000: Duplicate entry '10' for key 1 ERROR 23000: Duplicate entry '10' for key 1
select count(*) from t1;
count(*)
2000
begin; begin;
SELECT COUNT(*) FROM t1; SELECT COUNT(*) FROM t1;
COUNT(*) COUNT(*)
@@ -437,9 +440,121 @@ SELECT COUNT(*) FROM t1;
COUNT(*) COUNT(*)
2000 2000
commit; commit;
SELECT COUNT(*) FROM t1; ERROR HY000: Got error 4350 'Transaction already aborted' from ndbcluster
COUNT(*) select * from t1 where pk1=1;
pk1 b c
1 1 1
select * from t1 where pk1=10;
pk1 b c
10 10 10
select count(*) from t1 where pk1 <= 10 order by pk1;
count(*)
11
select count(*) from t1;
count(*)
2000
begin;
INSERT INTO t1 VALUES
(1,1,1),(2,2,2),(3,3,3),(4,4,4),(5,5,5),
(6,6,6),(7,7,7),(8,8,8),(9,9,9),(10,10,10);
ERROR 23000: Duplicate entry '10' for key 1
rollback;
select * from t1 where pk1=1;
pk1 b c
1 1 1
select * from t1 where pk1=10;
pk1 b c
10 10 10
select count(*) from t1 where pk1 <= 10 order by pk1;
count(*)
11
select count(*) from t1;
count(*)
2000
begin;
INSERT INTO t1 VALUES
(1,1,1),(2,2,2),(3,3,3),(4,4,4),(5,5,5),
(6,6,6),(7,7,7),(8,8,8),(9,9,9),(10,10,10);
ERROR 23000: Duplicate entry '10' for key 1
SELECT * FROM t1 WHERE pk1=10;
ERROR HY000: Got error 4350 'Transaction already aborted' from ndbcluster
rollback;
select * from t1 where pk1=1;
pk1 b c
1 1 1
select * from t1 where pk1=10;
pk1 b c
10 10 10
select count(*) from t1 where pk1 <= 10 order by pk1;
count(*)
11
select count(*) from t1;
count(*)
2000
begin;
INSERT INTO t1 VALUES
(1,1,1),(2,2,2),(3,3,3),(4,4,4),(5,5,5),
(6,6,6),(7,7,7),(8,8,8),(9,9,9),(10,10,10);
ERROR 23000: Duplicate entry '10' for key 1
SELECT * FROM t1 WHERE pk1=10;
ERROR HY000: Got error 4350 'Transaction already aborted' from ndbcluster
SELECT * FROM t1 WHERE pk1=10;
ERROR HY000: Got error 4350 'Transaction already aborted' from ndbcluster
commit;
ERROR HY000: Got error 4350 'Transaction already aborted' from ndbcluster
select * from t1 where pk1=1;
pk1 b c
1 1 1
select * from t1 where pk1=10;
pk1 b c
10 10 10
select count(*) from t1 where pk1 <= 10 order by pk1;
count(*)
11
select count(*) from t1;
count(*)
2000
begin;
INSERT INTO t1 VALUES
(1,1,1),(2,2,2),(3,3,3),(4,4,4),(5,5,5),
(6,6,6),(7,7,7),(8,8,8),(9,9,9),(10,10,10);
ERROR 23000: Duplicate entry '10' for key 1
INSERT INTO t1 values (4000, 40, 44);
ERROR HY000: Got error 4350 'Transaction already aborted' from ndbcluster
rollback;
select * from t1 where pk1=1;
pk1 b c
1 1 1
select * from t1 where pk1=10;
pk1 b c
10 10 10
select count(*) from t1 where pk1 <= 10 order by pk1;
count(*)
11
select count(*) from t1;
count(*)
2000 2000
insert into t1 select * from t1 where b < 10 order by pk1; insert into t1 select * from t1 where b < 10 order by pk1;
ERROR 23000: Duplicate entry '9' for key 1 ERROR 23000: Duplicate entry '9' for key 1
begin;
INSERT IGNORE INTO t1 VALUES(1,2,3);
ERROR HY000: Table storage engine for 't1' doesn't have this option
commit;
select * from t1 where pk1=1;
pk1 b c
1 1 1
INSERT IGNORE INTO t1 VALUES(1,2,3);
ERROR HY000: Table storage engine for 't1' doesn't have this option
select * from t1 where pk1=1;
pk1 b c
1 1 1
REPLACE INTO t1 values(1, 2, 3);
select * from t1 where pk1=1;
pk1 b c
1 2 3
INSERT INTO t1 VALUES(1,1,1) ON DUPLICATE KEY UPDATE b=79;
ERROR HY000: Table storage engine for 't1' doesn't have this option
select * from t1 where pk1=1;
pk1 b c
1 2 3
DROP TABLE t1; DROP TABLE t1;

View File

@@ -437,27 +437,117 @@ INSERT INTO t1 VALUES
(1,1,1),(2,2,2),(3,3,3),(4,4,4),(5,5,5), (1,1,1),(2,2,2),(3,3,3),(4,4,4),(5,5,5),
(6,6,6),(7,7,7),(8,8,8),(9,9,9),(10,10,10); (6,6,6),(7,7,7),(8,8,8),(9,9,9),(10,10,10);
select count(*) from t1;
begin;
# #
# Insert duplicate rows, inside transaction # Insert duplicate rows, inside transaction
# since failing inserts rollbacks whole transaction # try to commit
# all select count (except second) return same value
# #
SELECT COUNT(*) FROM t1; begin;
INSERT INTO t1 VALUES
(2001,2001,2001),(2002,2002,2002),(2003,2003,2003),(2004,2004,2004),(2005,2005,2005);
SELECT COUNT(*) FROM t1;
--error 1062 --error 1062
INSERT INTO t1 VALUES INSERT INTO t1 VALUES
(1,1,1),(2,2,2),(3,3,3),(4,4,4),(5,5,5), (1,1,1),(2,2,2),(3,3,3),(4,4,4),(5,5,5),
(6,6,6),(7,7,7),(8,8,8),(9,9,9),(10,10,10); (6,6,6),(7,7,7),(8,8,8),(9,9,9),(10,10,10);
SELECT COUNT(*) FROM t1;
--error 1296
commit;
select * from t1 where pk1=1;
select * from t1 where pk1=10;
select count(*) from t1 where pk1 <= 10 order by pk1;
select count(*) from t1;
#
# Insert duplicate rows, inside transaction
# rollback
#
begin;
--error 1062
INSERT INTO t1 VALUES
(1,1,1),(2,2,2),(3,3,3),(4,4,4),(5,5,5),
(6,6,6),(7,7,7),(8,8,8),(9,9,9),(10,10,10);
rollback;
select * from t1 where pk1=1;
select * from t1 where pk1=10;
select count(*) from t1 where pk1 <= 10 order by pk1;
select count(*) from t1;
#
# Insert duplicate rows, inside transaction
# then try to select, finally rollback
#
begin;
--error 1062
INSERT INTO t1 VALUES
(1,1,1),(2,2,2),(3,3,3),(4,4,4),(5,5,5),
(6,6,6),(7,7,7),(8,8,8),(9,9,9),(10,10,10);
--error 1296
SELECT * FROM t1 WHERE pk1=10;
rollback;
select * from t1 where pk1=1;
select * from t1 where pk1=10;
select count(*) from t1 where pk1 <= 10 order by pk1;
select count(*) from t1;
#
# Insert duplicate rows, inside transaction
# then try to select, finally commit
#
begin;
--error 1062
INSERT INTO t1 VALUES
(1,1,1),(2,2,2),(3,3,3),(4,4,4),(5,5,5),
(6,6,6),(7,7,7),(8,8,8),(9,9,9),(10,10,10);
--error 1296
SELECT * FROM t1 WHERE pk1=10;
--error 1296
SELECT * FROM t1 WHERE pk1=10;
--error 1296
commit; commit;
SELECT COUNT(*) FROM t1; SELECT COUNT(*) FROM t1;
select * from t1 where pk1=1;
select * from t1 where pk1=10;
select count(*) from t1 where pk1 <= 10 order by pk1;
select count(*) from t1;
#
# Insert duplicate rows, inside transaction
# then try to do another insert
#
begin;
--error 1062
INSERT INTO t1 VALUES
(1,1,1),(2,2,2),(3,3,3),(4,4,4),(5,5,5),
(6,6,6),(7,7,7),(8,8,8),(9,9,9),(10,10,10);
--error 1296
INSERT INTO t1 values (4000, 40, 44);
rollback;
select * from t1 where pk1=1;
select * from t1 where pk1=10;
select count(*) from t1 where pk1 <= 10 order by pk1;
select count(*) from t1;
# #
# Insert duplicate rows using "insert .. select" # Insert duplicate rows using "insert .. select"
@@ -466,4 +556,21 @@ SELECT COUNT(*) FROM t1;
insert into t1 select * from t1 where b < 10 order by pk1; insert into t1 select * from t1 where b < 10 order by pk1;
begin;
--error 1031
INSERT IGNORE INTO t1 VALUES(1,2,3);
commit;
select * from t1 where pk1=1;
--error 1031
INSERT IGNORE INTO t1 VALUES(1,2,3);
select * from t1 where pk1=1;
REPLACE INTO t1 values(1, 2, 3);
select * from t1 where pk1=1;
--error 1031
INSERT INTO t1 VALUES(1,1,1) ON DUPLICATE KEY UPDATE b=79;
select * from t1 where pk1=1;
DROP TABLE t1; DROP TABLE t1;

View File

@@ -145,27 +145,29 @@ NdbConnection::init()
}//NdbConnection::init() }//NdbConnection::init()
/***************************************************************************** /*****************************************************************************
setOperationErrorCode(int anErrorCode); setOperationErrorCode(int error);
Remark: Sets an error code on the connection object from an Remark: Sets an error code on the connection object from an
operation object. operation object.
*****************************************************************************/ *****************************************************************************/
void void
NdbConnection::setOperationErrorCode(int anErrorCode) NdbConnection::setOperationErrorCode(int error)
{ {
if (theError.code == 0) DBUG_ENTER("NdbConnection::setOperationErrorCode");
theError.code = anErrorCode; setErrorCode(error);
}//NdbConnection::setOperationErrorCode() DBUG_VOID_RETURN;
}
/***************************************************************************** /*****************************************************************************
setOperationErrorCodeAbort(int anErrorCode); setOperationErrorCodeAbort(int error);
Remark: Sets an error code on the connection object from an Remark: Sets an error code on the connection object from an
operation object. operation object.
*****************************************************************************/ *****************************************************************************/
void void
NdbConnection::setOperationErrorCodeAbort(int anErrorCode) NdbConnection::setOperationErrorCodeAbort(int error)
{ {
DBUG_ENTER("NdbConnection::setOperationErrorCodeAbort");
if (theTransactionIsStarted == false) { if (theTransactionIsStarted == false) {
theCommitStatus = Aborted; theCommitStatus = Aborted;
} else if ((m_abortOption == AbortOnError) && } else if ((m_abortOption == AbortOnError) &&
@@ -173,9 +175,9 @@ NdbConnection::setOperationErrorCodeAbort(int anErrorCode)
(theCommitStatus != Aborted)) { (theCommitStatus != Aborted)) {
theCommitStatus = NeedAbort; theCommitStatus = NeedAbort;
}//if }//if
if (theError.code == 0) setErrorCode(error);
theError.code = anErrorCode; DBUG_VOID_RETURN;
}//NdbConnection::setOperationErrorCodeAbort() }
/***************************************************************************** /*****************************************************************************
setErrorCode(int anErrorCode); setErrorCode(int anErrorCode);
@@ -183,10 +185,15 @@ setErrorCode(int anErrorCode);
Remark: Sets an error indication on the connection object. Remark: Sets an error indication on the connection object.
*****************************************************************************/ *****************************************************************************/
void void
NdbConnection::setErrorCode(int anErrorCode) NdbConnection::setErrorCode(int error)
{ {
DBUG_ENTER("NdbConnection::setErrorCode");
DBUG_PRINT("enter", ("error: %d, theError.code: %d", error, theError.code));
if (theError.code == 0) if (theError.code == 0)
theError.code = anErrorCode; theError.code = error;
DBUG_VOID_RETURN;
}//NdbConnection::setErrorCode() }//NdbConnection::setErrorCode()
int int
@@ -262,8 +269,12 @@ NdbConnection::execute(ExecType aTypeOfExec,
AbortOption abortOption, AbortOption abortOption,
int forceSend) int forceSend)
{ {
DBUG_ENTER("NdbConnection::execute");
DBUG_PRINT("enter", ("aTypeOfExec: %d, abortOption: %d",
aTypeOfExec, abortOption));
if (! theBlobFlag) if (! theBlobFlag)
return executeNoBlobs(aTypeOfExec, abortOption, forceSend); DBUG_RETURN(executeNoBlobs(aTypeOfExec, abortOption, forceSend));
/* /*
* execute prepared ops in batches, as requested by blobs * execute prepared ops in batches, as requested by blobs
@@ -346,7 +357,7 @@ NdbConnection::execute(ExecType aTypeOfExec,
} }
} while (theFirstOpInList != NULL || tExecType != aTypeOfExec); } while (theFirstOpInList != NULL || tExecType != aTypeOfExec);
return ret; DBUG_RETURN(ret);
} }
int int
@@ -354,6 +365,10 @@ NdbConnection::executeNoBlobs(ExecType aTypeOfExec,
AbortOption abortOption, AbortOption abortOption,
int forceSend) int forceSend)
{ {
DBUG_ENTER("NdbConnection::executeNoBlobs");
DBUG_PRINT("enter", ("aTypeOfExec: %d, abortOption: %d",
aTypeOfExec, abortOption));
//------------------------------------------------------------------------ //------------------------------------------------------------------------
// We will start by preparing all operations in the transaction defined // We will start by preparing all operations in the transaction defined
// since last execute or since beginning. If this works ok we will continue // since last execute or since beginning. If this works ok we will continue
@@ -376,7 +391,7 @@ NdbConnection::executeNoBlobs(ExecType aTypeOfExec,
*/ */
ndbout << "This timeout should never occur, execute(..)" << endl; ndbout << "This timeout should never occur, execute(..)" << endl;
setOperationErrorCodeAbort(4012); // Error code for "Cluster Failure" setOperationErrorCodeAbort(4012); // Error code for "Cluster Failure"
return -1; DBUG_RETURN(-1);
}//if }//if
/* /*
@@ -400,13 +415,13 @@ NdbConnection::executeNoBlobs(ExecType aTypeOfExec,
} }
#endif #endif
if (theReturnStatus == ReturnFailure) { if (theReturnStatus == ReturnFailure) {
return -1; DBUG_RETURN(-1);
}//if }//if
break; break;
} }
} }
thePendingBlobOps = 0; thePendingBlobOps = 0;
return 0; DBUG_RETURN(0);
}//NdbConnection::execute() }//NdbConnection::execute()
/***************************************************************************** /*****************************************************************************
@@ -430,9 +445,15 @@ NdbConnection::executeAsynchPrepare( ExecType aTypeOfExec,
void* anyObject, void* anyObject,
AbortOption abortOption) AbortOption abortOption)
{ {
DBUG_ENTER("NdbConnection::executeAsynchPrepare");
DBUG_PRINT("enter", ("aTypeOfExec: %d, aCallback: %x, anyObject: %x",
aTypeOfExec, aCallback, anyObject));
/** /**
* Reset error.code on execute * Reset error.code on execute
*/ */
if (theError.code != 0)
DBUG_PRINT("enter", ("Resetting error %d on execute", theError.code));
theError.code = 0; theError.code = 0;
NdbScanOperation* tcOp = m_theFirstScanOperation; NdbScanOperation* tcOp = m_theFirstScanOperation;
if (tcOp != 0){ if (tcOp != 0){
@@ -441,7 +462,7 @@ NdbConnection::executeAsynchPrepare( ExecType aTypeOfExec,
int tReturnCode; int tReturnCode;
tReturnCode = tcOp->executeCursor(theDBnode); tReturnCode = tcOp->executeCursor(theDBnode);
if (tReturnCode == -1) { if (tReturnCode == -1) {
return; DBUG_VOID_RETURN;
}//if }//if
tcOp = (NdbScanOperation*)tcOp->next(); tcOp = (NdbScanOperation*)tcOp->next();
} // while } // while
@@ -463,17 +484,6 @@ NdbConnection::executeAsynchPrepare( ExecType aTypeOfExec,
theCallbackFunction = aCallback; theCallbackFunction = aCallback;
theCallbackObject = anyObject; theCallbackObject = anyObject;
m_abortOption = abortOption; m_abortOption = abortOption;
// SendStatusType tSendStatus = theSendStatus;
// if (tSendStatus != InitState) {
/****************************************************************************
* The application is obviously doing strange things. We should probably
* report to the application the problem in some manner. Since we don't have
* a good way of handling the problem we avoid discovering the problem.
* Should be handled at some point in time.
****************************************************************************/
// return;
// }
m_waitForReply = true; m_waitForReply = true;
tNdb->thePreparedTransactionsArray[tnoOfPreparedTransactions] = this; tNdb->thePreparedTransactionsArray[tnoOfPreparedTransactions] = this;
theTransArrayIndex = tnoOfPreparedTransactions; theTransArrayIndex = tnoOfPreparedTransactions;
@@ -502,7 +512,11 @@ NdbConnection::executeAsynchPrepare( ExecType aTypeOfExec,
} else { } else {
theSendStatus = sendABORTfail; theSendStatus = sendABORTfail;
}//if }//if
return; if (theCommitStatus == Aborted){
DBUG_PRINT("exit", ("theCommitStatus: Aborted"));
setErrorCode(4350);
}
DBUG_VOID_RETURN;
}//if }//if
if (tTransactionIsStarted == true) { if (tTransactionIsStarted == true) {
if (tLastOp != NULL) { if (tLastOp != NULL) {
@@ -520,7 +534,7 @@ NdbConnection::executeAsynchPrepare( ExecType aTypeOfExec,
* We will use the commit method. * We will use the commit method.
*********************************************************************/ *********************************************************************/
theSendStatus = sendCOMMITstate; theSendStatus = sendCOMMITstate;
return; DBUG_VOID_RETURN;
} else { } else {
/********************************************************************** /**********************************************************************
* We need to put it into the array of completed transactions to * We need to put it into the array of completed transactions to
@@ -532,7 +546,7 @@ NdbConnection::executeAsynchPrepare( ExecType aTypeOfExec,
* put it into the completed array. * put it into the completed array.
**********************************************************************/ **********************************************************************/
theSendStatus = sendCompleted; theSendStatus = sendCompleted;
return; // No Commit with no operations is OK DBUG_VOID_RETURN; // No Commit with no operations is OK
}//if }//if
}//if }//if
} else if (tTransactionIsStarted == false) { } else if (tTransactionIsStarted == false) {
@@ -560,7 +574,7 @@ NdbConnection::executeAsynchPrepare( ExecType aTypeOfExec,
* will put it into the completed array. * will put it into the completed array.
***********************************************************************/ ***********************************************************************/
theSendStatus = sendCompleted; theSendStatus = sendCompleted;
return; DBUG_VOID_RETURN;
}//if }//if
} }
@@ -573,7 +587,7 @@ NdbConnection::executeAsynchPrepare( ExecType aTypeOfExec,
tReturnCode = tOp->prepareSend(theTCConPtr, theTransactionId); tReturnCode = tOp->prepareSend(theTCConPtr, theTransactionId);
if (tReturnCode == -1) { if (tReturnCode == -1) {
theSendStatus = sendABORTfail; theSendStatus = sendABORTfail;
return; DBUG_VOID_RETURN;
}//if }//if
/************************************************************************* /*************************************************************************
@@ -596,7 +610,7 @@ NdbConnection::executeAsynchPrepare( ExecType aTypeOfExec,
theNoOfOpSent = 0; theNoOfOpSent = 0;
theNoOfOpCompleted = 0; theNoOfOpCompleted = 0;
theSendStatus = sendOperations; theSendStatus = sendOperations;
return; DBUG_VOID_RETURN;
}//NdbConnection::executeAsynchPrepare() }//NdbConnection::executeAsynchPrepare()
void NdbConnection::close() void NdbConnection::close()
@@ -665,6 +679,8 @@ Remark: Send all operations belonging to this connection.
int int
NdbConnection::doSend() NdbConnection::doSend()
{ {
DBUG_ENTER("NdbConnection::doSend");
/* /*
This method assumes that at least one operation have been defined. This This method assumes that at least one operation have been defined. This
is ensured by the caller of this routine (=execute). is ensured by the caller of this routine (=execute).
@@ -687,7 +703,7 @@ NdbConnection::doSend()
theSendStatus = sendTC_OP; theSendStatus = sendTC_OP;
theTransactionIsStarted = true; theTransactionIsStarted = true;
tNdb->insert_sent_list(this); tNdb->insert_sent_list(this);
return 0; DBUG_RETURN(0);
}//case }//case
case sendABORT: case sendABORT:
case sendABORTfail:{ case sendABORTfail:{
@@ -699,18 +715,18 @@ NdbConnection::doSend()
theReturnStatus = ReturnFailure; theReturnStatus = ReturnFailure;
}//if }//if
if (sendROLLBACK() == 0) { if (sendROLLBACK() == 0) {
return 0; DBUG_RETURN(0);
}//if }//if
break; break;
}//case }//case
case sendCOMMITstate: case sendCOMMITstate:
if (sendCOMMIT() == 0) { if (sendCOMMIT() == 0) {
return 0; DBUG_RETURN(0);
}//if }//if
break; break;
case sendCompleted: case sendCompleted:
theNdb->insert_completed_list(this); theNdb->insert_completed_list(this);
return 0; DBUG_RETURN(0);
default: default:
ndbout << "Inconsistent theSendStatus = " << theSendStatus << endl; ndbout << "Inconsistent theSendStatus = " << theSendStatus << endl;
abort(); abort();
@@ -720,7 +736,7 @@ NdbConnection::doSend()
theReleaseOnClose = true; theReleaseOnClose = true;
theTransactionIsStarted = false; theTransactionIsStarted = false;
theCommitStatus = Aborted; theCommitStatus = Aborted;
return -1; DBUG_RETURN(-1);
}//NdbConnection::doSend() }//NdbConnection::doSend()
/************************************************************************** /**************************************************************************

View File

@@ -228,6 +228,7 @@ ErrorBundle ErrorCodes[] = {
{ 4347, IE, "Bad state at alter index" }, { 4347, IE, "Bad state at alter index" },
{ 4348, IE, "Inconsistency detected at alter index" }, { 4348, IE, "Inconsistency detected at alter index" },
{ 4349, IE, "Inconsistency detected at index usage" }, { 4349, IE, "Inconsistency detected at index usage" },
{ 4350, IE, "Transaction already aborted" },
/** /**
* Application error * Application error

View File

@@ -122,6 +122,8 @@ static const err_code_mapping err_map[]=
{ 827, HA_ERR_RECORD_FILE_FULL }, { 827, HA_ERR_RECORD_FILE_FULL },
{ 832, HA_ERR_RECORD_FILE_FULL }, { 832, HA_ERR_RECORD_FILE_FULL },
{ 0, 1 },
{ -1, -1 } { -1, -1 }
}; };
@@ -246,8 +248,6 @@ int ha_ndbcluster::ndb_err(NdbConnection *trans)
{ {
int res; int res;
const NdbError err= trans->getNdbError(); const NdbError err= trans->getNdbError();
if (!err.code)
return 0; // Don't log things to DBUG log if no error
DBUG_ENTER("ndb_err"); DBUG_ENTER("ndb_err");
ERR_PRINT(err); ERR_PRINT(err);
@@ -283,10 +283,11 @@ bool ha_ndbcluster::get_error_message(int error,
DBUG_ENTER("ha_ndbcluster::get_error_message"); DBUG_ENTER("ha_ndbcluster::get_error_message");
DBUG_PRINT("enter", ("error: %d", error)); DBUG_PRINT("enter", ("error: %d", error));
if (!m_ndb) Ndb* ndb = (Ndb*)current_thd->transaction.ndb;
if (!ndb)
DBUG_RETURN(false); DBUG_RETURN(false);
const NdbError err= m_ndb->getNdbError(error); const NdbError err= ndb->getNdbError(error);
bool temporary= err.status==NdbError::TemporaryError; bool temporary= err.status==NdbError::TemporaryError;
buf->set(err.message, strlen(err.message), &my_charset_bin); buf->set(err.message, strlen(err.message), &my_charset_bin);
DBUG_PRINT("exit", ("message: %s, temporary: %d", buf->ptr(), temporary)); DBUG_PRINT("exit", ("message: %s, temporary: %d", buf->ptr(), temporary));
@@ -1522,6 +1523,11 @@ int ha_ndbcluster::write_row(byte *record)
int res; int res;
DBUG_ENTER("write_row"); DBUG_ENTER("write_row");
if(m_ignore_dup_key_not_supported)
{
DBUG_RETURN(HA_ERR_WRONG_COMMAND);
}
statistic_increment(ha_write_count,&LOCK_status); statistic_increment(ha_write_count,&LOCK_status);
if (table->timestamp_default_now) if (table->timestamp_default_now)
update_timestamp(record+table->timestamp_default_now-1); update_timestamp(record+table->timestamp_default_now-1);
@@ -2479,14 +2485,20 @@ int ha_ndbcluster::extra(enum ha_extra_function operation)
break; break;
case HA_EXTRA_IGNORE_DUP_KEY: /* Dup keys don't rollback everything*/ case HA_EXTRA_IGNORE_DUP_KEY: /* Dup keys don't rollback everything*/
DBUG_PRINT("info", ("HA_EXTRA_IGNORE_DUP_KEY")); DBUG_PRINT("info", ("HA_EXTRA_IGNORE_DUP_KEY"));
if (current_thd->lex->sql_command == SQLCOM_REPLACE)
{
DBUG_PRINT("info", ("Turning ON use of write instead of insert")); DBUG_PRINT("info", ("Turning ON use of write instead of insert"));
m_use_write= TRUE; m_use_write= TRUE;
} else
{
m_ignore_dup_key_not_supported= TRUE;
}
break; break;
case HA_EXTRA_NO_IGNORE_DUP_KEY: case HA_EXTRA_NO_IGNORE_DUP_KEY:
DBUG_PRINT("info", ("HA_EXTRA_NO_IGNORE_DUP_KEY")); DBUG_PRINT("info", ("HA_EXTRA_NO_IGNORE_DUP_KEY"));
DBUG_PRINT("info", ("Turning OFF use of write instead of insert")); DBUG_PRINT("info", ("Turning OFF use of write instead of insert"));
m_use_write= false; m_use_write= false;
m_ignore_dup_key_not_supported= false;
break; break;
case HA_EXTRA_RETRIEVE_ALL_COLS: /* Retrieve all columns, not just those case HA_EXTRA_RETRIEVE_ALL_COLS: /* Retrieve all columns, not just those
where field->query_id is the same as where field->query_id is the same as
@@ -3364,6 +3376,7 @@ ha_ndbcluster::ha_ndbcluster(TABLE *table_arg):
HA_NO_PREFIX_CHAR_KEYS), HA_NO_PREFIX_CHAR_KEYS),
m_share(0), m_share(0),
m_use_write(false), m_use_write(false),
m_ignore_dup_key_not_supported(false),
retrieve_all_fields(FALSE), retrieve_all_fields(FALSE),
rows_to_insert(1), rows_to_insert(1),
rows_inserted(0), rows_inserted(0),

View File

@@ -245,6 +245,7 @@ class ha_ndbcluster: public handler
typedef union { NdbRecAttr *rec; NdbBlob *blob; void *ptr; } NdbValue; typedef union { NdbRecAttr *rec; NdbBlob *blob; void *ptr; } NdbValue;
NdbValue m_value[NDB_MAX_ATTRIBUTES_IN_TABLE]; NdbValue m_value[NDB_MAX_ATTRIBUTES_IN_TABLE];
bool m_use_write; bool m_use_write;
bool m_ignore_dup_key_not_supported;
bool retrieve_all_fields; bool retrieve_all_fields;
ha_rows rows_to_insert; ha_rows rows_to_insert;
ha_rows rows_inserted; ha_rows rows_inserted;