Index: mysql-5.1-telco-6.2/storage/ndb/src/ndbapi/NdbBlob.cpp =================================================================== --- mysql-5.1-telco-6.2.orig/storage/ndb/src/ndbapi/NdbBlob.cpp 2009-10-16 12:52:32.000000000 +0100 +++ mysql-5.1-telco-6.2/storage/ndb/src/ndbapi/NdbBlob.cpp 2009-10-16 14:47:32.000000000 +0100 @@ -2896,6 +2896,14 @@ NdbBlob::preCommit() DBUG_PRINT("info", ("this=%p op=%p con=%p", this, theNdbOp, theNdbCon)); if (theState == Invalid) DBUG_RETURN(-1); + if (unlikely((theState == Prepared) && + (theNdbCon->commitStatus() == NdbTransaction::Aborted))) + { + /* execute(Commit) called after transaction aborted from kernel + * Do nothing here - the call will fail later. + */ + DBUG_RETURN(0); + } assert(theState == Active); assert(isKeyOp()); if (isInsertOp() || isUpdateOp() || isWriteOp()) { Index: mysql-5.1-telco-6.2/storage/ndb/test/ndbapi/testBlobs.cpp =================================================================== --- mysql-5.1-telco-6.2.orig/storage/ndb/test/ndbapi/testBlobs.cpp 2009-10-16 12:52:32.000000000 +0100 +++ mysql-5.1-telco-6.2/storage/ndb/test/ndbapi/testBlobs.cpp 2009-10-16 15:07:01.000000000 +0100 @@ -173,6 +173,7 @@ printusage() << " -bug 27018 middle partial part write clobbers rest of part" << endl << " -bug 27370 Potential inconsistent blob reads for ReadCommitted reads" << endl << " -bug 36756 Handling execute(.., abortOption) and Blobs " << endl + << " -bug 45768 execute(Commit) after failing blob batch " << endl ; } @@ -3013,6 +3014,129 @@ bugtest_36756() return 0; } + +static int +bugtest_45768() +{ + /* Transaction inserting using blobs has an early error + resulting in kernel-originated rollback. + Api then calls execute(Commit) which chokes on Blob + objects + + */ + DBG("bugtest_45768 : Batched blob transaction with abort followed by commit"); + + const int numIterations = 5; + + for (int iteration=0; iteration < numIterations; iteration++) + { + /* Recalculate and insert different tuple every time to + * get different keys(and therefore nodes), and + * different length Blobs, including zero length + * and NULL + */ + calcTups(true); + + const Uint32 totalRows = 100; + const Uint32 preExistingTupNum = totalRows / 2; + + Tup& tupExists = g_tups[ preExistingTupNum ]; + + /* Setup table with just 1 row present */ + CHK((g_con= g_ndb->startTransaction()) != 0); + CHK((g_opr= g_con->getNdbOperation(g_opt.m_tname)) != 0); + CHK(g_opr->insertTuple() == 0); + CHK(g_opr->equal("PK1", tupExists.m_pk1) == 0); + if (g_opt.m_pk2chr.m_len != 0) + { + CHK(g_opr->equal("PK2", tupExists.m_pk2) == 0); + CHK(g_opr->equal("PK3", tupExists.m_pk3) == 0); + } + CHK(getBlobHandles(g_opr) == 0); + + CHK(setBlobValue(tupExists) == 0); + + CHK(g_con->execute(Commit) == 0); + g_con->close(); + + DBG("Iteration : " << iteration); + + /* Now do batched insert, including a TUP which already + * exists + */ + int rc = 0; + int retries = 10; + + do + { + CHK((g_con = g_ndb->startTransaction()) != 0); + + for (Uint32 tupNum = 0; tupNum < totalRows ; tupNum++) + { + Tup& tup = g_tups[ tupNum ]; + CHK((g_opr = g_con->getNdbOperation(g_opt.m_tname)) != 0); + CHK(g_opr->insertTuple() == 0); + CHK(g_opr->equal("PK1", tup.m_pk1) == 0); + if (g_opt.m_pk2chr.m_len != 0) + { + CHK(g_opr->equal("PK2", tup.m_pk2) == 0); + CHK(g_opr->equal("PK3", tup.m_pk3) == 0); + } + + CHK(getBlobHandles(g_opr) == 0); + CHK(setBlobValue(tup) == 0); + } + + /* Now execute NoCommit */ + int rc = g_con->execute(NdbTransaction::NoCommit); + + CHK(rc == -1); + + if (g_con->getNdbError().code == 630) + break; /* Expected */ + + CHK(g_con->getNdbError().code == 1218); // Send buffers overloaded + + DBG("Send Buffers overloaded, retrying"); + sleep(1); + g_con->close(); + } while (retries--); + + CHK(g_con->getNdbError().code == 630); + + /* Now execute Commit */ + rc = g_con->execute(NdbTransaction::Commit); + + CHK(rc == -1); + /* Transaction aborted already */ + CHK(g_con->getNdbError().code == 4350); + + g_con->close(); + + /* Now delete the 'existing'row */ + CHK((g_con= g_ndb->startTransaction()) != 0); + CHK((g_opr= g_con->getNdbOperation(g_opt.m_tname)) != 0); + CHK(g_opr->deleteTuple() == 0); + CHK(g_opr->equal("PK1", tupExists.m_pk1) == 0); + if (g_opt.m_pk2chr.m_len != 0) + { + CHK(g_opr->equal("PK2", tupExists.m_pk2) == 0); + CHK(g_opr->equal("PK3", tupExists.m_pk3) == 0); + } + + CHK(g_con->execute(Commit) == 0); + g_con->close(); + } + + g_opr= 0; + g_con= 0; + g_bh1= 0; + + return 0; +} + + + // main // from here on print always @@ -3842,7 +3966,8 @@ static struct { { 4088, bugtest_4088 }, { 27018, bugtest_27018 }, { 27370, bugtest_27370 }, - { 36756, bugtest_36756 } + { 36756, bugtest_36756 }, + { 45768, bugtest_45768 } }; NDB_COMMAND(testOdbcDriver, "testBlobs", "testBlobs", "testBlobs", 65535) Index: mysql-5.1-telco-6.2/storage/ndb/test/run-test/daily-basic-tests.txt =================================================================== --- mysql-5.1-telco-6.2.orig/storage/ndb/test/run-test/daily-basic-tests.txt 2009-10-16 13:04:05.000000000 +0100 +++ mysql-5.1-telco-6.2/storage/ndb/test/run-test/daily-basic-tests.txt 2009-10-16 14:48:01.000000000 +0100 @@ -840,6 +840,10 @@ max-time: 600 cmd: testBlobs args: -bug 36756 -skip p +max-time: 300 +cmd: testBlobs +args: -bug 45768 -skip p + max-time: 5000 cmd: testOIBasic args: -case abcdefz Index: mysql-5.1-telco-6.2/mysql-test/suite/ndb/r/ndb_dd_alter.result =================================================================== --- mysql-5.1-telco-6.2.orig/mysql-test/suite/ndb/r/ndb_dd_alter.result 2009-06-10 10:16:08.000000000 +0100 +++ mysql-5.1-telco-6.2/mysql-test/suite/ndb/r/ndb_dd_alter.result 2009-10-16 16:16:16.000000000 +0100 @@ -420,6 +420,18 @@ a1 a2 a3 hex(a4) a5 a6 a7 a8 a9 a10 a11 18 19.2345 20000018 0 1 23474 2006-01-01 07:04:00 1971-05-28 16:55:03 abc abcdefg LLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLL Text Field 19 20.2345 20000019 0 1 23475 2006-01-01 07:04:00 1971-05-28 16:55:03 abc abcdefg LLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLL Text Field 20 21.2345 20000020 0 1 23476 2006-01-01 07:04:00 1971-05-28 16:55:03 abc abcdefg LLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLLL Text Field +CREATE TABLESPACE ts2 +ADD DATAFILE './table_space/datafile2.dat' + USE LOGFILE GROUP lg +INITIAL_SIZE 1M +ENGINE NDB; +Expecting tablespace is full error +ALTER TABLE test.t1 TABLESPACE ts2 STORAGE DISK ENGINE NDB; +Got one of the listed errors +ALTER TABLESPACE ts2 +DROP DATAFILE './table_space/datafile2.dat' + ENGINE NDB; +DROP TABLESPACE ts2 ENGINE NDB; ALTER TABLE test.t1 ADD INDEX a2_i (a2), ADD INDEX a3_i (a3); SHOW CREATE TABLE test.t1; Table Create Table Index: mysql-5.1-telco-6.2/mysql-test/suite/ndb/t/ndb_dd_alter.test =================================================================== --- mysql-5.1-telco-6.2.orig/mysql-test/suite/ndb/t/ndb_dd_alter.test 2009-10-16 12:52:32.000000000 +0100 +++ mysql-5.1-telco-6.2/mysql-test/suite/ndb/t/ndb_dd_alter.test 2009-10-16 16:12:30.000000000 +0100 @@ -219,6 +219,27 @@ enable_query_log; SELECT a1, a2,a3,hex(a4),a5,a6,a7,a8,a9,a10,a11,a12,a13 FROM test.t1 ORDER BY a1; +#### Try to move t1 into too-small tablespace #### +# Bug #45768 + + CREATE TABLESPACE ts2 + ADD DATAFILE './table_space/datafile2.dat' + USE LOGFILE GROUP lg + INITIAL_SIZE 1M + ENGINE NDB; + +--echo Expecting tablespace is full error +# We mention the same error twice here to suppress printing of the error +# This is required as the error contains the temp table name which +# varies per-run +--error 1114,1114 +ALTER TABLE test.t1 TABLESPACE ts2 STORAGE DISK ENGINE NDB; + + ALTER TABLESPACE ts2 + DROP DATAFILE './table_space/datafile2.dat' + ENGINE NDB; + DROP TABLESPACE ts2 ENGINE NDB; + #### Try to ALTER DD Tables and add Indexes ALTER TABLE test.t1 ADD INDEX a2_i (a2), ADD INDEX a3_i (a3);