diff --git a/BitKeeper/etc/logging_ok b/BitKeeper/etc/logging_ok index 3d4c3d60ca8..e9cc35b4c7e 100644 --- a/BitKeeper/etc/logging_ok +++ b/BitKeeper/etc/logging_ok @@ -197,6 +197,7 @@ mysqldev@melody.local mysqldev@mysql.com mysqldev@o2k.irixworld.net ndbdev@dl145b.mysql.com +ndbdev@dl145c.mysql.com ndbdev@eel.hemma.oreland.se ndbdev@ndbmaster.mysql.com ndbdev@shark. diff --git a/mysql-test/r/func_if.result b/mysql-test/r/func_if.result index 3e72fb45a14..aee23b38ca5 100644 --- a/mysql-test/r/func_if.result +++ b/mysql-test/r/func_if.result @@ -108,3 +108,16 @@ id date_ord text 2 16-03-2005 Day 2 1 05-03-2005 Day 1 DROP TABLE t1; +CREATE TABLE t1 (a CHAR(10)); +INSERT INTO t1 VALUES ('aaa'), (NULL), (''), ('bbb'); +SELECT a, NULLIF(a,'') FROM t1; +a NULLIF(a,'') +aaa aaa +NULL NULL + NULL +bbb bbb +SELECT a, NULLIF(a,'') FROM t1 WHERE NULLIF(a,'') IS NULL; +a NULLIF(a,'') +NULL NULL + NULL +DROP TABLE t1; diff --git a/mysql-test/t/func_if.test b/mysql-test/t/func_if.test index 37556984f68..03590dea8d1 100644 --- a/mysql-test/t/func_if.test +++ b/mysql-test/t/func_if.test @@ -75,3 +75,15 @@ SELECT id, IF(date IS NULL, '-', FROM_UNIXTIME(date, '%d-%m-%Y')) AS date_ord, t SELECT id, IF(date IS NULL, '-', FROM_UNIXTIME(date, '%d-%m-%Y')) AS date_ord, text FROM t1 ORDER BY date_ord DESC; DROP TABLE t1; + +# +# Test for bug #11142: evaluation of NULLIF when the first argument is NULL +# + +CREATE TABLE t1 (a CHAR(10)); +INSERT INTO t1 VALUES ('aaa'), (NULL), (''), ('bbb'); + +SELECT a, NULLIF(a,'') FROM t1; +SELECT a, NULLIF(a,'') FROM t1 WHERE NULLIF(a,'') IS NULL; + +DROP TABLE t1; diff --git a/ndb/src/kernel/blocks/dbtc/DbtcMain.cpp b/ndb/src/kernel/blocks/dbtc/DbtcMain.cpp index 16554955646..e4cce29ba30 100644 --- a/ndb/src/kernel/blocks/dbtc/DbtcMain.cpp +++ b/ndb/src/kernel/blocks/dbtc/DbtcMain.cpp @@ -763,11 +763,14 @@ Dbtc::set_timeout_value(Uint32 timeOut) void Dbtc::set_appl_timeout_value(Uint32 timeOut) { - timeOut /= 10; - if (timeOut < ctimeOutValue) { - jam(); - c_appl_timeout_value = ctimeOutValue; - }//if + if (timeOut) + { + timeOut /= 10; + if (timeOut < ctimeOutValue) { + jam(); + c_appl_timeout_value = ctimeOutValue; + }//if + } c_appl_timeout_value = timeOut; } @@ -6286,7 +6289,8 @@ void Dbtc::timeOutFoundLab(Signal* signal, Uint32 TapiConPtr) particular state we will use the application timeout parameter rather than the shorter Deadlock detection timeout. */ - if ((ctcTimer - getApiConTimer(apiConnectptr.i)) <= c_appl_timeout_value) { + if (c_appl_timeout_value == 0 || + (ctcTimer - getApiConTimer(apiConnectptr.i)) <= c_appl_timeout_value) { jam(); return; }//if diff --git a/ndb/test/ndbapi/testTimeout.cpp b/ndb/test/ndbapi/testTimeout.cpp index ac4f257f12c..b02751ec819 100644 --- a/ndb/test/ndbapi/testTimeout.cpp +++ b/ndb/test/ndbapi/testTimeout.cpp @@ -22,14 +22,14 @@ #include <NdbConfig.hpp> #include <signaldata/DumpStateOrd.hpp> -#define TIMEOUT 3000 - +#define TIMEOUT (Uint32)3000 Uint32 g_org_timeout = 3000; int setTransactionTimeout(NDBT_Context* ctx, NDBT_Step* step){ NdbRestarter restarter; - + int timeout = ctx->getProperty("TransactionInactiveTimeout",TIMEOUT); + NdbConfig conf(GETNDB(step)->getNodeId()+1); unsigned int nodeId = conf.getMasterNodeId(); if (!conf.getProperty(nodeId, @@ -39,7 +39,7 @@ setTransactionTimeout(NDBT_Context* ctx, NDBT_Step* step){ return NDBT_FAILED; } - int val[] = { DumpStateOrd::TcSetApplTransactionTimeout, TIMEOUT }; + int val[] = { DumpStateOrd::TcSetApplTransactionTimeout, timeout }; if(restarter.dumpStateAllNodes(val, 2) != 0){ return NDBT_FAILED; } @@ -95,8 +95,10 @@ int runTimeoutTrans2(NDBT_Context* ctx, NDBT_Step* step){ int mul2 = ctx->getProperty("Op2", (Uint32)0); int records = ctx->getNumRecords(); - int minSleep = (int)(TIMEOUT * 1.5); - int maxSleep = TIMEOUT * 2; + int timeout = ctx->getProperty("TransactionInactiveTimeout",TIMEOUT); + + int minSleep = (int)(timeout * 1.5); + int maxSleep = timeout * 2; HugoOperations hugoOps(*ctx->getTab()); Ndb* pNdb = GETNDB(step); @@ -109,7 +111,7 @@ int runTimeoutTrans2(NDBT_Context* ctx, NDBT_Step* step){ op1 = (op1 % 5); op2 = (op2 % 5); - ndbout << stepNo << ": TransactionInactiveTimeout="<< TIMEOUT + ndbout << stepNo << ": TransactionInactiveTimeout="<< timeout << ", minSleep="<<minSleep << ", maxSleep="<<maxSleep << ", op1=" << op1 @@ -211,8 +213,10 @@ int runDontTimeoutTrans(NDBT_Context* ctx, NDBT_Step* step){ int loops = ctx->getNumLoops(); int stepNo = step->getStepNo(); - int maxSleep = (int)(TIMEOUT * 0.5); - ndbout << "TransactionInactiveTimeout="<< TIMEOUT + int timeout = ctx->getProperty("TransactionInactiveTimeout",TIMEOUT); + + int maxSleep = (int)(timeout * 0.5); + ndbout << "TransactionInactiveTimeout="<< timeout << ", maxSleep="<<maxSleep<<endl; @@ -242,6 +246,51 @@ int runDontTimeoutTrans(NDBT_Context* ctx, NDBT_Step* step){ return result; } +int runDeadlockTimeoutTrans(NDBT_Context* ctx, NDBT_Step* step){ + int result = NDBT_OK; + int loops = ctx->getNumLoops(); + int stepNo = step->getStepNo(); + + Uint32 deadlock_timeout; + NdbConfig conf(GETNDB(step)->getNodeId()+1); + unsigned int nodeId = conf.getMasterNodeId(); + if (!conf.getProperty(nodeId, + NODE_TYPE_DB, + CFG_DB_TRANSACTION_DEADLOCK_TIMEOUT, + &deadlock_timeout)){ + return NDBT_FAILED; + } + + + int do_sleep = (int)(deadlock_timeout * 0.5); + + + HugoOperations hugoOps(*ctx->getTab()); + Ndb* pNdb = GETNDB(step); + + for (int l = 0; l < loops && result == NDBT_OK; l++){ + + do{ + // Commit transaction + CHECK(hugoOps.startTransaction(pNdb) == 0); + CHECK(hugoOps.pkReadRecord(pNdb, stepNo) == 0); + CHECK(hugoOps.execute_NoCommit(pNdb) == 0); + + int sleep = deadlock_timeout * 1.5 + myRandom48(do_sleep); + ndbout << "Sleeping for " << sleep << " milliseconds" << endl; + NdbSleep_MilliSleep(sleep); + + // Expect that transaction has NOT timed-out + CHECK(hugoOps.execute_Commit(pNdb) == 0); + + } while(false); + + hugoOps.closeTransaction(pNdb); + } + + return result; +} + int runBuddyTransNoTimeout(NDBT_Context* ctx, NDBT_Step* step){ int result = NDBT_OK; int loops = ctx->getNumLoops(); @@ -295,6 +344,17 @@ TESTCASE("DontTimeoutTransaction", FINALIZER(resetTransactionTimeout); FINALIZER(runClearTable); } +TESTCASE("Bug11290", + "Setting TransactionInactiveTimeout to 0(zero) "\ + "should result in infinite timeout, and not as "\ + "was the bug, a timeout that is equal to the deadlock timeout"){ + TC_PROPERTY("TransactionInactiveTimeout",(Uint32)0); + INITIALIZER(runLoadTable); + INITIALIZER(setTransactionTimeout); + STEPS(runDeadlockTimeoutTrans, 1); + FINALIZER(resetTransactionTimeout); + FINALIZER(runClearTable); +} TESTCASE("DontTimeoutTransaction5", "Test that the transaction does not timeout "\ "if we sleep during the transaction. Use a sleep "\ diff --git a/sql/item_cmpfunc.cc b/sql/item_cmpfunc.cc index b5b37efaf07..e79a356c4d3 100644 --- a/sql/item_cmpfunc.cc +++ b/sql/item_cmpfunc.cc @@ -1406,9 +1406,7 @@ Item_func_nullif::val_decimal(my_decimal * decimal_value) bool Item_func_nullif::is_null() { - if (!cmp.compare()) - return (null_value=1); - return 0; + return (null_value= (!cmp.compare() ? 1 : args[0]->null_value)); } /*