Commit c06c0078 authored by unknown's avatar unknown
Browse files

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
parents 8b79d2b5 38238355
Loading
Loading
Loading
Loading
+117 −2
Original line number Diff line number Diff line
@@ -420,6 +420,9 @@ 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 count(*) from t1;
count(*)
2000
begin;
SELECT COUNT(*) FROM t1;
COUNT(*)
@@ -437,9 +440,121 @@ SELECT COUNT(*) FROM t1;
COUNT(*)
2000
commit;
SELECT COUNT(*) FROM t1;
COUNT(*)
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
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
insert into t1 select * from t1 where b < 10 order by pk1;
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;
+113 −6
Original line number Diff line number Diff line
@@ -437,27 +437,117 @@ 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);

select count(*) from t1;


#
# Insert duplicate rows, inside transaction
# try to 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
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
# since failing inserts rollbacks whole transaction
# all select count (except second) return same value
# rollback 
#
SELECT COUNT(*) FROM t1;
begin;

--error 1062
INSERT INTO t1 VALUES 
(2001,2001,2001),(2002,2002,2002),(2003,2003,2003),(2004,2004,2004),(2005,2005,2005);
SELECT COUNT(*) FROM t1;
(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);
SELECT COUNT(*) FROM t1;
--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;
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" 

@@ -466,4 +556,21 @@ SELECT COUNT(*) FROM t1;
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;
+56 −40
Original line number Diff line number Diff line
@@ -145,27 +145,29 @@ NdbConnection::init()
}//NdbConnection::init()

/*****************************************************************************
setOperationErrorCode(int anErrorCode);
setOperationErrorCode(int error);

Remark:        Sets an error code on the connection object from an 
               operation object. 
*****************************************************************************/
void
NdbConnection::setOperationErrorCode(int anErrorCode)
NdbConnection::setOperationErrorCode(int error)
{
  if (theError.code == 0)
    theError.code = anErrorCode;
}//NdbConnection::setOperationErrorCode()
  DBUG_ENTER("NdbConnection::setOperationErrorCode");
  setErrorCode(error);
  DBUG_VOID_RETURN;
}

/*****************************************************************************
setOperationErrorCodeAbort(int anErrorCode);
setOperationErrorCodeAbort(int error);

Remark:        Sets an error code on the connection object from an 
               operation object. 
*****************************************************************************/
void
NdbConnection::setOperationErrorCodeAbort(int anErrorCode)
NdbConnection::setOperationErrorCodeAbort(int error)
{
  DBUG_ENTER("NdbConnection::setOperationErrorCodeAbort");
  if (theTransactionIsStarted == false) {
    theCommitStatus = Aborted;
  } else if ((m_abortOption == AbortOnError) && 
@@ -173,9 +175,9 @@ NdbConnection::setOperationErrorCodeAbort(int anErrorCode)
             (theCommitStatus != Aborted)) {
    theCommitStatus = NeedAbort;
  }//if
  if (theError.code == 0)
    theError.code = anErrorCode;
}//NdbConnection::setOperationErrorCodeAbort()
  setErrorCode(error);
  DBUG_VOID_RETURN;
}

/*****************************************************************************
setErrorCode(int anErrorCode);
@@ -183,10 +185,15 @@ setErrorCode(int anErrorCode);
Remark:        Sets an error indication on the connection object. 
*****************************************************************************/
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)
    theError.code = anErrorCode;
    theError.code = error;

  DBUG_VOID_RETURN;
}//NdbConnection::setErrorCode()

int
@@ -262,8 +269,12 @@ NdbConnection::execute(ExecType aTypeOfExec,
		       AbortOption abortOption,
		       int forceSend)
{
  DBUG_ENTER("NdbConnection::execute");
  DBUG_PRINT("enter", ("aTypeOfExec: %d, abortOption: %d", 
		       aTypeOfExec, abortOption));

  if (! theBlobFlag)
    return executeNoBlobs(aTypeOfExec, abortOption, forceSend);
    DBUG_RETURN(executeNoBlobs(aTypeOfExec, abortOption, forceSend));

  /*
   * execute prepared ops in batches, as requested by blobs
@@ -346,7 +357,7 @@ NdbConnection::execute(ExecType aTypeOfExec,
    }
  } while (theFirstOpInList != NULL || tExecType != aTypeOfExec);

  return ret;
  DBUG_RETURN(ret);
}

int 
@@ -354,6 +365,10 @@ NdbConnection::executeNoBlobs(ExecType aTypeOfExec,
                              AbortOption abortOption,
                              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
// 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;
        setOperationErrorCodeAbort(4012);  // Error code for "Cluster Failure"
        return -1;
        DBUG_RETURN(-1);
      }//if

      /*
@@ -400,13 +415,13 @@ NdbConnection::executeNoBlobs(ExecType aTypeOfExec,
      }
#endif
      if (theReturnStatus == ReturnFailure) {
        return -1;
        DBUG_RETURN(-1);
      }//if
      break;
    }
  }
  thePendingBlobOps = 0;
  return 0;
  DBUG_RETURN(0);
}//NdbConnection::execute()

/*****************************************************************************
@@ -430,9 +445,15 @@ NdbConnection::executeAsynchPrepare( ExecType aTypeOfExec,
                                     void*              anyObject,
                                     AbortOption abortOption)
{
  DBUG_ENTER("NdbConnection::executeAsynchPrepare");
  DBUG_PRINT("enter", ("aTypeOfExec: %d, aCallback: %x, anyObject: %x", 
		       aTypeOfExec, aCallback, anyObject));

  /**
   * Reset error.code on execute
   */
  if (theError.code != 0)
    DBUG_PRINT("enter", ("Resetting error %d on execute", theError.code));
  theError.code = 0;
  NdbScanOperation* tcOp = m_theFirstScanOperation;
  if (tcOp != 0){
@@ -441,7 +462,7 @@ NdbConnection::executeAsynchPrepare( ExecType aTypeOfExec,
      int tReturnCode;
      tReturnCode = tcOp->executeCursor(theDBnode);
      if (tReturnCode == -1) {
        return;
        DBUG_VOID_RETURN;
      }//if
      tcOp = (NdbScanOperation*)tcOp->next();
    } // while
@@ -463,17 +484,6 @@ NdbConnection::executeAsynchPrepare( ExecType aTypeOfExec,
  theCallbackFunction = aCallback;
  theCallbackObject   = anyObject;
  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;
  tNdb->thePreparedTransactionsArray[tnoOfPreparedTransactions] = this;
  theTransArrayIndex = tnoOfPreparedTransactions;
@@ -502,7 +512,11 @@ NdbConnection::executeAsynchPrepare( ExecType aTypeOfExec,
    } else {
      theSendStatus = sendABORTfail;
    }//if
    return;
    if (theCommitStatus == Aborted){
      DBUG_PRINT("exit", ("theCommitStatus: Aborted"));
      setErrorCode(4350);
    }
    DBUG_VOID_RETURN;
  }//if
  if (tTransactionIsStarted == true) {
    if (tLastOp != NULL) {
@@ -520,7 +534,7 @@ NdbConnection::executeAsynchPrepare( ExecType aTypeOfExec,
	 *   We will use the commit method.
	 *********************************************************************/
        theSendStatus = sendCOMMITstate;
        return;
	DBUG_VOID_RETURN;
      } else {
	/**********************************************************************
	 * 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.
	 **********************************************************************/
        theSendStatus = sendCompleted;
	return;		// No Commit with no operations is OK
	DBUG_VOID_RETURN; // No Commit with no operations is OK
      }//if
    }//if
  } else if (tTransactionIsStarted == false) {
@@ -560,7 +574,7 @@ NdbConnection::executeAsynchPrepare( ExecType aTypeOfExec,
       * will put it into the completed array.
       ***********************************************************************/
      theSendStatus = sendCompleted;
      return;
      DBUG_VOID_RETURN;
    }//if
  }

@@ -573,7 +587,7 @@ NdbConnection::executeAsynchPrepare( ExecType aTypeOfExec,
    tReturnCode = tOp->prepareSend(theTCConPtr, theTransactionId);
    if (tReturnCode == -1) {
      theSendStatus = sendABORTfail;
      return;
      DBUG_VOID_RETURN;
    }//if

    /*************************************************************************
@@ -596,7 +610,7 @@ NdbConnection::executeAsynchPrepare( ExecType aTypeOfExec,
  theNoOfOpSent		= 0;
  theNoOfOpCompleted	= 0;
  theSendStatus = sendOperations;
  return;
  DBUG_VOID_RETURN;
}//NdbConnection::executeAsynchPrepare()

void NdbConnection::close()
@@ -665,6 +679,8 @@ Remark: Send all operations belonging to this connection.
int
NdbConnection::doSend()
{
  DBUG_ENTER("NdbConnection::doSend");

  /*
  This method assumes that at least one operation have been defined. This
  is ensured by the caller of this routine (=execute).
@@ -687,7 +703,7 @@ NdbConnection::doSend()
    theSendStatus = sendTC_OP;
    theTransactionIsStarted = true;
    tNdb->insert_sent_list(this);
    return 0;
    DBUG_RETURN(0);
  }//case
  case sendABORT:
  case sendABORTfail:{
@@ -699,18 +715,18 @@ NdbConnection::doSend()
      theReturnStatus = ReturnFailure;
    }//if
    if (sendROLLBACK() == 0) {
      return 0;
      DBUG_RETURN(0);
    }//if
    break;
  }//case
  case sendCOMMITstate:
    if (sendCOMMIT() == 0) {
      return 0;
      DBUG_RETURN(0);
    }//if
    break;
  case sendCompleted:
    theNdb->insert_completed_list(this); 
    return 0;
    DBUG_RETURN(0);
  default:
    ndbout << "Inconsistent theSendStatus = " << theSendStatus << endl;
    abort();
@@ -720,7 +736,7 @@ NdbConnection::doSend()
  theReleaseOnClose = true;
  theTransactionIsStarted = false;
  theCommitStatus = Aborted;
  return -1;
  DBUG_RETURN(-1);
}//NdbConnection::doSend()

/**************************************************************************
+1 −0
Original line number Diff line number Diff line
@@ -228,6 +228,7 @@ ErrorBundle ErrorCodes[] = {
  { 4347, IE, "Bad state at alter index" },
  { 4348, IE, "Inconsistency detected at alter index" },
  { 4349, IE, "Inconsistency detected at index usage" },
  { 4350, IE, "Transaction already aborted" },

  /**
   * Application error
+21 −8
Original line number Diff line number Diff line
@@ -122,6 +122,8 @@ static const err_code_mapping err_map[]=
  { 827, HA_ERR_RECORD_FILE_FULL },
  { 832, HA_ERR_RECORD_FILE_FULL },

  { 0, 1 },

  { -1, -1 }
};

@@ -246,8 +248,6 @@ int ha_ndbcluster::ndb_err(NdbConnection *trans)
{
  int res;
  const NdbError err= trans->getNdbError();
  if (!err.code)
    return 0;			// Don't log things to DBUG log if no error
  DBUG_ENTER("ndb_err");
  
  ERR_PRINT(err);
@@ -283,10 +283,11 @@ bool ha_ndbcluster::get_error_message(int error,
  DBUG_ENTER("ha_ndbcluster::get_error_message");
  DBUG_PRINT("enter", ("error: %d", error));
  
  if (!m_ndb)
  Ndb* ndb = (Ndb*)current_thd->transaction.ndb;
  if (!ndb)
    DBUG_RETURN(false);

  const NdbError err= m_ndb->getNdbError(error);
  const NdbError err= ndb->getNdbError(error);
  bool temporary= err.status==NdbError::TemporaryError;
  buf->set(err.message, strlen(err.message), &my_charset_bin);
  DBUG_PRINT("exit", ("message: %s, temporary: %d", buf->ptr(), temporary));
@@ -1522,6 +1523,11 @@ int ha_ndbcluster::write_row(byte *record)
  int res;
  DBUG_ENTER("write_row");

  if(m_ignore_dup_key_not_supported)
  {
    DBUG_RETURN(HA_ERR_WRONG_COMMAND);
  }
  
  statistic_increment(ha_write_count,&LOCK_status);
  if (table->timestamp_default_now)
    update_timestamp(record+table->timestamp_default_now-1);
@@ -2479,14 +2485,20 @@ int ha_ndbcluster::extra(enum ha_extra_function operation)
    break;
  case HA_EXTRA_IGNORE_DUP_KEY:       /* Dup keys don't rollback everything*/
    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"));
      m_use_write= TRUE;
    } else 
    {
      m_ignore_dup_key_not_supported= TRUE;
    }
    break;
  case 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"));
    m_use_write= false;
    m_ignore_dup_key_not_supported= false;
    break;
  case HA_EXTRA_RETRIEVE_ALL_COLS:    /* Retrieve all columns, not just those
					 where field->query_id is the same as
@@ -3364,6 +3376,7 @@ ha_ndbcluster::ha_ndbcluster(TABLE *table_arg):
		HA_NO_PREFIX_CHAR_KEYS),
  m_share(0),
  m_use_write(false),
  m_ignore_dup_key_not_supported(false),
  retrieve_all_fields(FALSE),
  rows_to_insert(1),
  rows_inserted(0),
Loading