diff --git a/myisam/myisamchk.c b/myisam/myisamchk.c index c4b5acadc92..2c44953ccc9 100644 --- a/myisam/myisamchk.c +++ b/myisam/myisamchk.c @@ -328,11 +328,11 @@ static struct my_option my_long_options[] = { "ft_max_word_len", OPT_FT_MAX_WORD_LEN, "", (gptr*) &ft_max_word_len, (gptr*) &ft_max_word_len, 0, GET_ULONG, REQUIRED_ARG, HA_FT_MAXCHARLEN, 10, HA_FT_MAXCHARLEN, 0, 1, 0}, - { 0, 0, 0, 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0}, { "ft_stopword_file", OPT_FT_STOPWORD_FILE, "Use stopwords from this file instead of built-in list.", (gptr*) &ft_stopword_file, (gptr*) &ft_stopword_file, 0, GET_STR, - REQUIRED_ARG, 0, 0, 0, 0, 0, 0} + REQUIRED_ARG, 0, 0, 0, 0, 0, 0}, + { 0, 0, 0, 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0} }; diff --git a/mysql-test/r/timezone2.result b/mysql-test/r/timezone2.result index 5361ff4ffe6..02406b77a65 100644 --- a/mysql-test/r/timezone2.result +++ b/mysql-test/r/timezone2.result @@ -244,3 +244,10 @@ NULL select convert_tz( NULL, 'MET', 'UTC'); convert_tz( NULL, 'MET', 'UTC') NULL +create table t1 (ts timestamp); +set timestamp=1000000000; +insert into t1 (ts) values (now()); +select convert_tz(ts, @@time_zone, 'Japan') from t1; +convert_tz(ts, @@time_zone, 'Japan') +2001-09-09 10:46:40 +drop table t1; diff --git a/mysql-test/t/timezone2.test b/mysql-test/t/timezone2.test index 49579421570..15ac3416b29 100644 --- a/mysql-test/t/timezone2.test +++ b/mysql-test/t/timezone2.test @@ -187,3 +187,15 @@ select convert_tz('2003-12-31 04:00:00', 'SomeNotExistingTimeZone', 'UTC'); select convert_tz('2003-12-31 04:00:00', 'MET', 'SomeNotExistingTimeZone'); select convert_tz('2003-12-31 04:00:00', 'MET', NULL); select convert_tz( NULL, 'MET', 'UTC'); + +# +# Test for bug #4508 "CONVERT_TZ() function with new time zone as param +# crashes server." (Was caused by improperly worked mechanism of time zone +# dynamical loading). +# +create table t1 (ts timestamp); +set timestamp=1000000000; +insert into t1 (ts) values (now()); +select convert_tz(ts, @@time_zone, 'Japan') from t1; +drop table t1; + diff --git a/ndb/src/common/mgmcommon/ConfigInfo.cpp b/ndb/src/common/mgmcommon/ConfigInfo.cpp index 6076b56de04..1dffd6751b5 100644 --- a/ndb/src/common/mgmcommon/ConfigInfo.cpp +++ b/ndb/src/common/mgmcommon/ConfigInfo.cpp @@ -494,7 +494,7 @@ const ConfigInfo::ParamInfo ConfigInfo::m_ParamInfo[] = { ConfigInfo::USED, true, ConfigInfo::INT, - 4000, + 6000, 70, MAX_INT_RNIL }, @@ -2586,7 +2586,6 @@ fixPortNumber(InitConfigFileParser::Context & ctx, const char * data){ Uint32 id1= 0, id2= 0; require(ctx.m_currentSection->get("NodeId1", &id1)); require(ctx.m_currentSection->get("NodeId2", &id2)); - id1 = id1 < id2 ? id1 : id2; const Properties * node; @@ -2619,7 +2618,6 @@ fixPortNumber(InitConfigFileParser::Context & ctx, const char * data){ } ctx.m_userProperties.put("ServerPortBase", base); } - port= base + adder; ctx.m_userProperties.put("ServerPort_", id1, port); } diff --git a/ndb/src/common/mgmcommon/IPCConfig.cpp b/ndb/src/common/mgmcommon/IPCConfig.cpp index a8536bf4fa7..a76c541f3f6 100644 --- a/ndb/src/common/mgmcommon/IPCConfig.cpp +++ b/ndb/src/common/mgmcommon/IPCConfig.cpp @@ -445,7 +445,6 @@ IPCConfig::configureTransporters(Uint32 nodeId, if(iter.get(CFG_TCP_RECEIVE_BUFFER_SIZE, &conf.maxReceiveSize)) break; conf.port= tmp_server_port; - const char * proxy; if (!iter.get(CFG_TCP_PROXY, &proxy)) { if (strlen(proxy) > 0 && nodeId2 == nodeId) { diff --git a/ndb/src/common/transporter/Transporter.cpp b/ndb/src/common/transporter/Transporter.cpp index 41972cf20fd..7a469252c00 100644 --- a/ndb/src/common/transporter/Transporter.cpp +++ b/ndb/src/common/transporter/Transporter.cpp @@ -93,7 +93,6 @@ bool Transporter::connect_client() { if(m_connected) return true; - NDB_SOCKET_TYPE sockfd = m_socket_client->connect(); if (sockfd < 0) @@ -102,7 +101,6 @@ Transporter::connect_client() { // send info about own id SocketOutputStream s_output(sockfd); s_output.println("%d", localNodeId); - // get remote id int nodeId; SocketInputStream s_input(sockfd); @@ -115,7 +113,6 @@ Transporter::connect_client() { NDB_CLOSE_SOCKET(sockfd); return false; } - bool res = connect_client_impl(sockfd); if(res){ m_connected = true; diff --git a/ndb/src/common/transporter/TransporterRegistry.cpp b/ndb/src/common/transporter/TransporterRegistry.cpp index aa1913e3040..01f1f74f053 100644 --- a/ndb/src/common/transporter/TransporterRegistry.cpp +++ b/ndb/src/common/transporter/TransporterRegistry.cpp @@ -200,8 +200,7 @@ TransporterRegistry::createTransporter(TCP_TransporterConfiguration *config) { if(theTransporters[config->remoteNodeId] != NULL) return false; - - + TCP_Transporter * t = new TCP_Transporter(*this, config->sendBufferSize, config->maxReceiveSize, diff --git a/ndb/src/common/util/SocketClient.cpp b/ndb/src/common/util/SocketClient.cpp index b7769633875..ec837babc24 100644 --- a/ndb/src/common/util/SocketClient.cpp +++ b/ndb/src/common/util/SocketClient.cpp @@ -70,19 +70,21 @@ SocketClient::connect() return -1; } } - const int r = ::connect(m_sockfd, (struct sockaddr*) &m_servaddr, sizeof(m_servaddr)); - if (r == -1) + if (r == -1) { + NDB_CLOSE_SOCKET(m_sockfd); + m_sockfd= -1; return -1; + } - if (m_auth) + if (m_auth) { if (!m_auth->client_authenticate(m_sockfd)) { NDB_CLOSE_SOCKET(m_sockfd); m_sockfd= -1; return -1; } - + } NDB_SOCKET_TYPE sockfd= m_sockfd; m_sockfd= -1; diff --git a/ndb/src/common/util/SocketServer.cpp b/ndb/src/common/util/SocketServer.cpp index 44c57c766f8..0cc06a54496 100644 --- a/ndb/src/common/util/SocketServer.cpp +++ b/ndb/src/common/util/SocketServer.cpp @@ -147,7 +147,6 @@ SocketServer::doAccept(){ ServiceInstance & si = m_services[i]; if(FD_ISSET(si.m_socket, &readSet)){ - NDB_SOCKET_TYPE childSock = accept(si.m_socket, 0, 0); if(childSock == NDB_INVALID_SOCKET){ continue; diff --git a/ndb/src/kernel/blocks/cmvmi/Cmvmi.cpp b/ndb/src/kernel/blocks/cmvmi/Cmvmi.cpp index ef0f91841dc..0f25391fccb 100644 --- a/ndb/src/kernel/blocks/cmvmi/Cmvmi.cpp +++ b/ndb/src/kernel/blocks/cmvmi/Cmvmi.cpp @@ -480,7 +480,6 @@ void Cmvmi::execDISCONNECT_REP(Signal *signal) void Cmvmi::execCONNECT_REP(Signal *signal){ const Uint32 hostId = signal->theData[0]; - jamEntry(); const NodeInfo::NodeType type = (NodeInfo::NodeType)getNodeInfo(hostId).m_type; diff --git a/ndb/src/kernel/blocks/dbacc/DbaccMain.cpp b/ndb/src/kernel/blocks/dbacc/DbaccMain.cpp index 5ee00c4158c..9cfac0ad2a2 100644 --- a/ndb/src/kernel/blocks/dbacc/DbaccMain.cpp +++ b/ndb/src/kernel/blocks/dbacc/DbaccMain.cpp @@ -757,6 +757,7 @@ void Dbacc::initialiseDirRec(Signal* signal) DirectoryarrayPtr idrDirptr; ndbrequire(cdirarraysize > 0); for (idrDirptr.i = 0; idrDirptr.i < cdirarraysize; idrDirptr.i++) { + refresh_watch_dog(); ptrAss(idrDirptr, directoryarray); for (Uint32 i = 0; i <= 255; i++) { idrDirptr.p->pagep[i] = RNIL; @@ -776,6 +777,7 @@ void Dbacc::initialiseDirRangeRec(Signal* signal) ndbrequire(cdirrangesize > 0); for (idrDirRangePtr.i = 0; idrDirRangePtr.i < cdirrangesize; idrDirRangePtr.i++) { + refresh_watch_dog(); ptrAss(idrDirRangePtr, dirRange); idrDirRangePtr.p->dirArray[0] = idrDirRangePtr.i + 1; for (Uint32 i = 1; i < 256; i++) { @@ -798,6 +800,7 @@ void Dbacc::initialiseFragRec(Signal* signal) ndbrequire(cfragmentsize > 0); for (regFragPtr.i = 0; regFragPtr.i < cfragmentsize; regFragPtr.i++) { jam(); + refresh_watch_dog(); ptrAss(regFragPtr, fragmentrec); initFragGeneral(regFragPtr); regFragPtr.p->nextfreefrag = regFragPtr.i + 1; @@ -876,6 +879,7 @@ void Dbacc::initialiseOperationRec(Signal* signal) { ndbrequire(coprecsize > 0); for (operationRecPtr.i = 0; operationRecPtr.i < coprecsize; operationRecPtr.i++) { + refresh_watch_dog(); ptrAss(operationRecPtr, operationrec); operationRecPtr.p->transactionstate = IDLE; operationRecPtr.p->operation = ZUNDEFINED_OP; @@ -898,6 +902,7 @@ void Dbacc::initialiseOverflowRec(Signal* signal) ndbrequire(coverflowrecsize > 0); for (iorOverflowRecPtr.i = 0; iorOverflowRecPtr.i < coverflowrecsize; iorOverflowRecPtr.i++) { + refresh_watch_dog(); ptrAss(iorOverflowRecPtr, overflowRecord); iorOverflowRecPtr.p->nextfreeoverrec = iorOverflowRecPtr.i + 1; }//for @@ -958,6 +963,7 @@ void Dbacc::initialiseRootfragRec(Signal* signal) { ndbrequire(crootfragmentsize > 0); for (rootfragrecptr.i = 0; rootfragrecptr.i < crootfragmentsize; rootfragrecptr.i++) { + refresh_watch_dog(); ptrAss(rootfragrecptr, rootfragmentrec); rootfragrecptr.p->nextroot = rootfragrecptr.i + 1; rootfragrecptr.p->fragmentptr[0] = RNIL; @@ -1013,6 +1019,7 @@ void Dbacc::initialiseTableRec(Signal* signal) { ndbrequire(ctablesize > 0); for (tabptr.i = 0; tabptr.i < ctablesize; tabptr.i++) { + refresh_watch_dog(); ptrAss(tabptr, tabrec); for (Uint32 i = 0; i < NO_OF_FRAG_PER_NODE; i++) { tabptr.p->fragholder[i] = RNIL; diff --git a/ndb/src/kernel/blocks/dbdict/Dbdict.cpp b/ndb/src/kernel/blocks/dbdict/Dbdict.cpp index bd191d112f1..143a96e49d3 100644 --- a/ndb/src/kernel/blocks/dbdict/Dbdict.cpp +++ b/ndb/src/kernel/blocks/dbdict/Dbdict.cpp @@ -1313,6 +1313,7 @@ void Dbdict::initTableRecords() TableRecordPtr tablePtr; while (1) { jam(); + refresh_watch_dog(); c_tableRecordPool.seize(tablePtr); if (tablePtr.i == RNIL) { jam(); @@ -1373,6 +1374,7 @@ void Dbdict::initTriggerRecords() TriggerRecordPtr triggerPtr; while (1) { jam(); + refresh_watch_dog(); c_triggerRecordPool.seize(triggerPtr); if (triggerPtr.i == RNIL) { jam(); diff --git a/ndb/src/kernel/blocks/dbdih/DbdihMain.cpp b/ndb/src/kernel/blocks/dbdih/DbdihMain.cpp index 557fed03498..3884bbda960 100644 --- a/ndb/src/kernel/blocks/dbdih/DbdihMain.cpp +++ b/ndb/src/kernel/blocks/dbdih/DbdihMain.cpp @@ -6896,6 +6896,7 @@ void Dbdih::initialiseFragstore() cfirstfragstore = RNIL; cremainingfrags = 0; for (i = 0; i < noOfChunks; i++) { + refresh_watch_dog(); ptrCheckGuard(fragPtr, cfragstoreFileSize, fragmentstore); fragPtr.p->nextFragmentChunk = cfirstfragstore; cfirstfragstore = fragPtr.i; @@ -11107,6 +11108,7 @@ void Dbdih::initialiseRecordsLab(Signal* signal, jam(); /******** INTIALIZING API CONNECT RECORDS ********/ for (apiConnectptr.i = 0; apiConnectptr.i < capiConnectFileSize; apiConnectptr.i++) { + refresh_watch_dog(); ptrAss(apiConnectptr, apiConnectRecord); apiConnectptr.p->nextApi = RNIL; }//for @@ -11118,6 +11120,7 @@ void Dbdih::initialiseRecordsLab(Signal* signal, jam(); /****** CONNECT ******/ for (connectPtr.i = 0; connectPtr.i < cconnectFileSize; connectPtr.i++) { + refresh_watch_dog(); ptrAss(connectPtr, connectRecord); connectPtr.p->userpointer = RNIL; connectPtr.p->userblockref = ZNIL; @@ -11182,6 +11185,7 @@ void Dbdih::initialiseRecordsLab(Signal* signal, jam(); /******* PAGE RECORD ******/ for (pagePtr.i = 0; pagePtr.i < cpageFileSize; pagePtr.i++) { + refresh_watch_dog(); ptrAss(pagePtr, pageRecord); pagePtr.p->nextfreepage = pagePtr.i + 1; }//for @@ -11198,6 +11202,7 @@ void Dbdih::initialiseRecordsLab(Signal* signal, /******* REPLICA RECORD ******/ for (initReplicaPtr.i = 0; initReplicaPtr.i < creplicaFileSize; initReplicaPtr.i++) { + refresh_watch_dog(); ptrAss(initReplicaPtr, replicaRecord); initReplicaPtr.p->lcpIdStarted = 0; initReplicaPtr.p->lcpOngoingFlag = false; @@ -11217,6 +11222,7 @@ void Dbdih::initialiseRecordsLab(Signal* signal, /********* TAB-DESCRIPTOR ********/ for (loopTabptr.i = 0; loopTabptr.i < ctabFileSize; loopTabptr.i++) { ptrAss(loopTabptr, tabRecord); + refresh_watch_dog(); initTable(loopTabptr); }//for break; diff --git a/ndb/src/kernel/blocks/dblqh/DblqhMain.cpp b/ndb/src/kernel/blocks/dblqh/DblqhMain.cpp index 3d7f3258686..9b61c7566eb 100644 --- a/ndb/src/kernel/blocks/dblqh/DblqhMain.cpp +++ b/ndb/src/kernel/blocks/dblqh/DblqhMain.cpp @@ -15976,6 +15976,7 @@ void Dblqh::initialiseAttrbuf(Signal* signal) for (attrinbufptr.i = 0; attrinbufptr.i < cattrinbufFileSize; attrinbufptr.i++) { + refresh_watch_dog(); ptrAss(attrinbufptr, attrbuf); attrinbufptr.p->attrbuf[ZINBUF_NEXT] = attrinbufptr.i + 1; }//for @@ -15998,6 +15999,7 @@ void Dblqh::initialiseDatabuf(Signal* signal) { if (cdatabufFileSize != 0) { for (databufptr.i = 0; databufptr.i < cdatabufFileSize; databufptr.i++) { + refresh_watch_dog(); ptrAss(databufptr, databuf); databufptr.p->nextDatabuf = databufptr.i + 1; }//for @@ -16019,6 +16021,7 @@ void Dblqh::initialiseFragrec(Signal* signal) { if (cfragrecFileSize != 0) { for (fragptr.i = 0; fragptr.i < cfragrecFileSize; fragptr.i++) { + refresh_watch_dog(); ptrAss(fragptr, fragrecord); fragptr.p->fragStatus = Fragrecord::FREE; fragptr.p->fragActiveStatus = ZFALSE; @@ -16151,6 +16154,7 @@ void Dblqh::initialiseLogPage(Signal* signal) { if (clogPageFileSize != 0) { for (logPagePtr.i = 0; logPagePtr.i < clogPageFileSize; logPagePtr.i++) { + refresh_watch_dog(); ptrAss(logPagePtr, logPageRecord); logPagePtr.p->logPageWord[ZNEXT_PAGE] = logPagePtr.i + 1; }//for @@ -16329,6 +16333,7 @@ void Dblqh::initialiseScanrec(Signal* signal) DLList tmp(c_scanRecordPool); while (tmp.seize(scanptr)){ //new (scanptr.p) ScanRecord(); + refresh_watch_dog(); scanptr.p->scanType = ScanRecord::ST_IDLE; scanptr.p->scanState = ScanRecord::SCAN_FREE; scanptr.p->scanTcWaiting = ZFALSE; @@ -16346,6 +16351,7 @@ void Dblqh::initialiseTabrec(Signal* signal) { if (ctabrecFileSize != 0) { for (tabptr.i = 0; tabptr.i < ctabrecFileSize; tabptr.i++) { + refresh_watch_dog(); ptrAss(tabptr, tablerec); tabptr.p->tableStatus = Tablerec::NOT_DEFINED; tabptr.p->usageCount = 0; @@ -16367,6 +16373,7 @@ void Dblqh::initialiseTcrec(Signal* signal) for (tcConnectptr.i = 0; tcConnectptr.i < ctcConnectrecFileSize; tcConnectptr.i++) { + refresh_watch_dog(); ptrAss(tcConnectptr, tcConnectionrec); tcConnectptr.p->transactionState = TcConnectionrec::TC_NOT_CONNECTED; tcConnectptr.p->tcScanRec = RNIL; diff --git a/ndb/src/kernel/blocks/dbtc/DbtcMain.cpp b/ndb/src/kernel/blocks/dbtc/DbtcMain.cpp index b3e6eb0dc6a..3246fcc5e6f 100644 --- a/ndb/src/kernel/blocks/dbtc/DbtcMain.cpp +++ b/ndb/src/kernel/blocks/dbtc/DbtcMain.cpp @@ -9584,6 +9584,7 @@ void Dbtc::initApiConnect(Signal* signal) ndbrequire(tiacTmp > 0); guard4 = tiacTmp + 1; for (cachePtr.i = 0; cachePtr.i < guard4; cachePtr.i++) { + refresh_watch_dog(); ptrAss(cachePtr, cacheRecord); cachePtr.p->firstAttrbuf = RNIL; cachePtr.p->lastAttrbuf = RNIL; @@ -9598,6 +9599,7 @@ void Dbtc::initApiConnect(Signal* signal) guard4 = tiacTmp - 1; for (apiConnectptr.i = 0; apiConnectptr.i <= guard4; apiConnectptr.i++) { + refresh_watch_dog(); jam(); ptrAss(apiConnectptr, apiConnectRecord); apiConnectptr.p->apiConnectstate = CS_DISCONNECTED; @@ -9623,6 +9625,7 @@ void Dbtc::initApiConnect(Signal* signal) guard4 = (2 * tiacTmp) - 1; for (apiConnectptr.i = tiacTmp; apiConnectptr.i <= guard4; apiConnectptr.i++) { + refresh_watch_dog(); jam(); ptrCheckGuard(apiConnectptr, capiConnectFilesize, apiConnectRecord); apiConnectptr.p->apiConnectstate = CS_RESTART; @@ -9648,6 +9651,7 @@ void Dbtc::initApiConnect(Signal* signal) guard4 = (3 * tiacTmp) - 1; for (apiConnectptr.i = 2 * tiacTmp; apiConnectptr.i <= guard4; apiConnectptr.i++) { + refresh_watch_dog(); jam(); ptrCheckGuard(apiConnectptr, capiConnectFilesize, apiConnectRecord); setApiConTimer(apiConnectptr.i, 0, __LINE__); @@ -9676,6 +9680,7 @@ void Dbtc::initattrbuf(Signal* signal) { ndbrequire(cattrbufFilesize > 0); for (attrbufptr.i = 0; attrbufptr.i < cattrbufFilesize; attrbufptr.i++) { + refresh_watch_dog(); jam(); ptrAss(attrbufptr, attrbufRecord); attrbufptr.p->attrbuf[ZINBUF_NEXT] = attrbufptr.i + 1; /* NEXT ATTRBUF */ @@ -9690,6 +9695,7 @@ void Dbtc::initdatabuf(Signal* signal) { ndbrequire(cdatabufFilesize > 0); for (databufptr.i = 0; databufptr.i < cdatabufFilesize; databufptr.i++) { + refresh_watch_dog(); ptrAss(databufptr, databufRecord); databufptr.p->nextDatabuf = databufptr.i + 1; }//for @@ -9817,6 +9823,7 @@ void Dbtc::initialiseScanrec(Signal* signal) ScanRecordPtr scanptr; ndbrequire(cscanrecFileSize > 0); for (scanptr.i = 0; scanptr.i < cscanrecFileSize; scanptr.i++) { + refresh_watch_dog(); jam(); ptrAss(scanptr, scanRecord); new (scanptr.p) ScanRecord(); @@ -9843,6 +9850,7 @@ void Dbtc::initTable(Signal* signal) ndbrequire(ctabrecFilesize > 0); for (tabptr.i = 0; tabptr.i < ctabrecFilesize; tabptr.i++) { + refresh_watch_dog(); ptrAss(tabptr, tableRecord); tabptr.p->currentSchemaVersion = 0; tabptr.p->storedTable = true; @@ -9859,6 +9867,7 @@ void Dbtc::initialiseTcConnect(Signal* signal) // Place half of tcConnectptr's in cfirstfreeTcConnectFail list Uint32 titcTmp = ctcConnectFilesize / 2; for (tcConnectptr.i = 0; tcConnectptr.i < titcTmp; tcConnectptr.i++) { + refresh_watch_dog(); jam(); ptrAss(tcConnectptr, tcConnectRecord); tcConnectptr.p->tcConnectstate = OS_RESTART; @@ -9874,6 +9883,7 @@ void Dbtc::initialiseTcConnect(Signal* signal) // Place other half in cfirstfreeTcConnect list for (tcConnectptr.i = titcTmp; tcConnectptr.i < ctcConnectFilesize; tcConnectptr.i++) { + refresh_watch_dog(); jam(); ptrAss(tcConnectptr, tcConnectRecord); tcConnectptr.p->tcConnectstate = OS_RESTART; diff --git a/ndb/src/kernel/blocks/dbtup/DbtupGen.cpp b/ndb/src/kernel/blocks/dbtup/DbtupGen.cpp index 8133f70a803..cba3c62ec03 100644 --- a/ndb/src/kernel/blocks/dbtup/DbtupGen.cpp +++ b/ndb/src/kernel/blocks/dbtup/DbtupGen.cpp @@ -888,6 +888,7 @@ void Dbtup::initializeAttrbufrec() AttrbufrecPtr attrBufPtr; for (attrBufPtr.i = 0; attrBufPtr.i < cnoOfAttrbufrec; attrBufPtr.i++) { + refresh_watch_dog(); ptrAss(attrBufPtr, attrbufrec); attrBufPtr.p->attrbuf[ZBUF_NEXT] = attrBufPtr.i + 1; }//for @@ -944,6 +945,7 @@ void Dbtup::initializeFragrecord() { FragrecordPtr regFragPtr; for (regFragPtr.i = 0; regFragPtr.i < cnoOfFragrec; regFragPtr.i++) { + refresh_watch_dog(); ptrAss(regFragPtr, fragrecord); regFragPtr.p->nextfreefrag = regFragPtr.i + 1; regFragPtr.p->checkpointVersion = RNIL; @@ -982,6 +984,7 @@ void Dbtup::initializeOperationrec() { OperationrecPtr regOpPtr; for (regOpPtr.i = 0; regOpPtr.i < cnoOfOprec; regOpPtr.i++) { + refresh_watch_dog(); ptrAss(regOpPtr, operationrec); regOpPtr.p->firstAttrinbufrec = RNIL; regOpPtr.p->lastAttrinbufrec = RNIL; @@ -1036,6 +1039,7 @@ void Dbtup::initializeTablerec() TablerecPtr regTabPtr; for (regTabPtr.i = 0; regTabPtr.i < cnoOfTablerec; regTabPtr.i++) { ljam(); + refresh_watch_dog(); ptrAss(regTabPtr, tablerec); initTab(regTabPtr.p); }//for @@ -1099,6 +1103,7 @@ void Dbtup::initializeTabDescr() cfreeTdList[i] = RNIL; }//for for (regTabDesPtr.i = 0; regTabDesPtr.i < cnoOfTabDescrRec; regTabDesPtr.i++) { + refresh_watch_dog(); ptrAss(regTabDesPtr, tableDescriptor); regTabDesPtr.p->tabDescr = RNIL; }//for @@ -1111,6 +1116,7 @@ void Dbtup::initializeUndoPage() for (undoPagep.i = 0; undoPagep.i < cnoOfUndoPage; undoPagep.i = undoPagep.i + ZUB_SEGMENT_SIZE) { + refresh_watch_dog(); ptrAss(undoPagep, undoPage); undoPagep.p->undoPageWord[ZPAGE_NEXT_POS] = undoPagep.i + ZUB_SEGMENT_SIZE; diff --git a/ndb/src/kernel/blocks/dbtup/DbtupPagMan.cpp b/ndb/src/kernel/blocks/dbtup/DbtupPagMan.cpp index d168a6797bb..1830b4135e3 100644 --- a/ndb/src/kernel/blocks/dbtup/DbtupPagMan.cpp +++ b/ndb/src/kernel/blocks/dbtup/DbtupPagMan.cpp @@ -123,6 +123,7 @@ void Dbtup::initializePage() PagePtr pagePtr; for (pagePtr.i = 0; pagePtr.i < cnoOfPage; pagePtr.i++) { ljam(); + refresh_watch_dog(); ptrAss(pagePtr, page); pagePtr.p->pageWord[ZPAGE_PHYSICAL_INDEX] = pagePtr.i; pagePtr.p->pageWord[ZPAGE_NEXT_POS] = pagePtr.i + 1; diff --git a/ndb/src/kernel/blocks/dbtux/DbtuxGen.cpp b/ndb/src/kernel/blocks/dbtux/DbtuxGen.cpp index 22b2ce69838..f6f1610c8c1 100644 --- a/ndb/src/kernel/blocks/dbtux/DbtuxGen.cpp +++ b/ndb/src/kernel/blocks/dbtux/DbtuxGen.cpp @@ -192,6 +192,7 @@ Dbtux::execREAD_CONFIG_REQ(Signal* signal) IndexPtr indexPtr; while (1) { jam(); + refresh_watch_dog(); c_indexPool.seize(indexPtr); if (indexPtr.i == RNIL) { jam(); diff --git a/ndb/src/kernel/blocks/ndbcntr/NdbcntrMain.cpp b/ndb/src/kernel/blocks/ndbcntr/NdbcntrMain.cpp index 91776cd7c03..4b2fcfe0c8c 100644 --- a/ndb/src/kernel/blocks/ndbcntr/NdbcntrMain.cpp +++ b/ndb/src/kernel/blocks/ndbcntr/NdbcntrMain.cpp @@ -554,11 +554,13 @@ Ndbcntr::execCNTR_START_REP(Signal* signal){ } if(cmasterNodeId != getOwnNodeId()){ + jam(); c_start.reset(); return; } if(c_start.m_waiting.isclear()){ + jam(); c_start.reset(); return; } @@ -597,6 +599,7 @@ Ndbcntr::execCNTR_START_REQ(Signal * signal){ ndbrequire(false); case NodeState::SL_STARTING: case NodeState::SL_STARTED: + jam(); break; case NodeState::SL_STOPPING_1: @@ -616,9 +619,11 @@ Ndbcntr::execCNTR_START_REQ(Signal * signal){ c_start.m_waiting.set(nodeId); switch(st){ case NodeState::ST_INITIAL_START: + jam(); c_start.m_withoutLog.set(nodeId); break; case NodeState::ST_SYSTEM_RESTART: + jam(); c_start.m_withLog.set(nodeId); if(starting && lastGci > c_start.m_lastGci){ jam(); @@ -631,6 +636,7 @@ Ndbcntr::execCNTR_START_REQ(Signal * signal){ return; } if(starting){ + jam(); Uint32 i = c_start.m_logNodesCount++; c_start.m_logNodes[i].m_nodeId = nodeId; c_start.m_logNodes[i].m_lastGci = req->lastGci; @@ -652,11 +658,12 @@ Ndbcntr::execCNTR_START_REQ(Signal * signal){ } if(starting){ + jam(); trySystemRestart(signal); } else { + jam(); startWaitingNodes(signal); } - return; } @@ -670,6 +677,7 @@ Ndbcntr::startWaitingNodes(Signal * signal){ NodeState::StartType nrType = NodeState::ST_NODE_RESTART; if(c_start.m_withoutLog.get(nodeId)){ + jam(); nrType = NodeState::ST_INITIAL_NODE_RESTART; } @@ -706,6 +714,7 @@ Ndbcntr::startWaitingNodes(Signal * signal){ char buf[100]; if(!c_start.m_withLog.isclear()){ + jam(); ndbout_c("Starting nodes w/ log: %s", c_start.m_withLog.getText(buf)); NodeReceiverGroup rg(NDBCNTR, c_start.m_withLog); @@ -716,6 +725,7 @@ Ndbcntr::startWaitingNodes(Signal * signal){ } if(!c_start.m_withoutLog.isclear()){ + jam(); ndbout_c("Starting nodes wo/ log: %s", c_start.m_withoutLog.getText(buf)); NodeReceiverGroup rg(NDBCNTR, c_start.m_withoutLog); conf->startType = NodeState::ST_INITIAL_NODE_RESTART; @@ -777,6 +787,7 @@ Ndbcntr::trySystemRestart(Signal* signal){ jam(); return false; } + jam(); srType = NodeState::ST_INITIAL_START; c_start.m_starting = c_start.m_withoutLog; // Used for starting... c_start.m_withoutLog.clear(); @@ -793,13 +804,11 @@ Ndbcntr::trySystemRestart(Signal* signal){ // If we lose with all nodes, then we're in trouble ndbrequire(!allNodes); return false; - break; case CheckNodeGroups::Partitioning: jam(); bool allowPartition = (c_start.m_startPartitionedTimeout != (Uint64)~0); if(allNodes){ - jam(); if(allowPartition){ jam(); break; @@ -1043,8 +1052,10 @@ void Ndbcntr::ph5ALab(Signal* signal) return; case NodeState::ST_NODE_RESTART: case NodeState::ST_INITIAL_NODE_RESTART: + jam(); break; case NodeState::ST_ILLEGAL_TYPE: + jam(); break; } ndbrequire(false); diff --git a/ndb/src/kernel/blocks/qmgr/QmgrMain.cpp b/ndb/src/kernel/blocks/qmgr/QmgrMain.cpp index 30f4d783c81..6017365a463 100644 --- a/ndb/src/kernel/blocks/qmgr/QmgrMain.cpp +++ b/ndb/src/kernel/blocks/qmgr/QmgrMain.cpp @@ -258,7 +258,6 @@ void Qmgr::execCONNECT_REP(Signal* signal) { const Uint32 nodeId = signal->theData[0]; c_connectedNodes.set(nodeId); - NodeRecPtr nodePtr; nodePtr.i = getOwnNodeId(); ptrCheckGuard(nodePtr, MAX_NODES, nodeRec); @@ -679,7 +678,6 @@ void Qmgr::execCM_REGREF(Signal* signal) UintR TaddNodeno = signal->theData[1]; UintR TrefuseReason = signal->theData[2]; Uint32 candidate = signal->theData[3]; - DEBUG_START3(signal, TrefuseReason); if(candidate != cpresidentCandidate){ @@ -768,7 +766,6 @@ void Qmgr::execCM_REGREF(Signal* signal) Uint64 now = NdbTick_CurrentMillisecond(); if((c_regReqReqRecv == cnoOfNodes) || now > c_stopElectionTime){ jam(); - electionWon(); sendSttorryLab(signal); diff --git a/ndb/src/kernel/vm/SimulatedBlock.cpp b/ndb/src/kernel/vm/SimulatedBlock.cpp index cb3c5dc9d2c..40e18017993 100644 --- a/ndb/src/kernel/vm/SimulatedBlock.cpp +++ b/ndb/src/kernel/vm/SimulatedBlock.cpp @@ -636,12 +636,12 @@ SimulatedBlock::getBatSize(Uint16 blockNo){ } void* -SimulatedBlock::allocRecord(const char * type, size_t s, size_t n) const +SimulatedBlock::allocRecord(const char * type, size_t s, size_t n) { void* p = NULL; size_t size = n*s; - + refresh_watch_dog(); if (size > 0){ #ifdef VM_TRACE_MEM ndbout_c("%s::allocRecord(%s, %u, %u) = %u bytes", @@ -660,8 +660,7 @@ SimulatedBlock::allocRecord(const char * type, size_t s, size_t n) const snprintf(buf2, sizeof(buf2), "Requested: %ux%u = %u bytes", (Uint32)s, (Uint32)n, (Uint32)size); ERROR_SET(fatal, ERR_MEMALLOC, buf1, buf2); } - - +#ifdef NDB_DEBUG_FULL // Set the allocated memory to zero #ifndef NDB_PURIFY #if defined NDB_OSE @@ -685,6 +684,7 @@ SimulatedBlock::allocRecord(const char * type, size_t s, size_t n) const memset(p, 0xF1, size); #endif +#endif #endif } return p; @@ -703,6 +703,12 @@ SimulatedBlock::deallocRecord(void ** ptr, } } +void +SimulatedBlock::refresh_watch_dog() +{ + globalData.incrementWatchDogCounter(1); +} + void SimulatedBlock::progError(int line, int err_code, const char* extra) const { jamLine(line); diff --git a/ndb/src/kernel/vm/SimulatedBlock.hpp b/ndb/src/kernel/vm/SimulatedBlock.hpp index e3eac8c0e20..2d8f7e5aaba 100644 --- a/ndb/src/kernel/vm/SimulatedBlock.hpp +++ b/ndb/src/kernel/vm/SimulatedBlock.hpp @@ -304,7 +304,13 @@ protected: BlockNumber number() const; BlockReference reference() const; NodeId getOwnNodeId() const; - + + /** + * Refresh Watch Dog in initialising code + * + */ + void refresh_watch_dog(); + /** * Prog error * This function should be called when this node should be shutdown @@ -344,7 +350,7 @@ protected: * Allocates memory for the datastructures where ndb keeps the data * */ - void* allocRecord(const char * type, size_t s, size_t n) const ; + void* allocRecord(const char * type, size_t s, size_t n); /** * Deallocate record diff --git a/scripts/mysql_create_system_tables.sh b/scripts/mysql_create_system_tables.sh index e45c0ec5571..7a30bcdbeca 100644 --- a/scripts/mysql_create_system_tables.sh +++ b/scripts/mysql_create_system_tables.sh @@ -307,7 +307,8 @@ then then i_tzn="$i_tzn INSERT INTO time_zone_name (Name, Time_Zone_id) VALUES" i_tzn="$i_tzn ('MET', 1), ('UTC', 2), ('Universal', 2), " - i_tzn="$i_tzn ('Europe/Moscow',3), ('leap/Europe/Moscow',4);" + i_tzn="$i_tzn ('Europe/Moscow',3), ('leap/Europe/Moscow',4), " + i_tzn="$i_tzn ('Japan', 5);" fi fi @@ -327,7 +328,7 @@ then if test "$1" = "test" then i_tz="$i_tz INSERT INTO time_zone (Time_zone_id, Use_leap_seconds)" - i_tz="$i_tz VALUES (1,'N'), (2,'N'), (3,'N'), (4,'Y');" + i_tz="$i_tz VALUES (1,'N'), (2,'N'), (3,'N'), (4,'Y'), (5,'N');" fi fi @@ -546,7 +547,8 @@ then i_tzt="$i_tzt ,(4, 2045689222, 8) ,(4, 2058390022, 9)" i_tzt="$i_tzt ,(4, 2077138822, 8) ,(4, 2090444422, 9)" i_tzt="$i_tzt ,(4, 2108588422, 8) ,(4, 2121894022, 9)" - i_tzt="$i_tzt ,(4, 2140038022, 8);" + i_tzt="$i_tzt ,(4, 2140038022, 8)" + i_tzt="$i_tzt ,(5, -1009875600, 1);" fi fi @@ -584,7 +586,8 @@ then i_tztt="$i_tztt ,(4, 4, 10800, 0, 'MSK') ,(4, 5, 14400, 1, 'MSD')" i_tztt="$i_tztt ,(4, 6, 18000, 1, 'MSD') ,(4, 7, 7200, 0, 'EET')" i_tztt="$i_tztt ,(4, 8, 10800, 0, 'MSK') ,(4, 9, 14400, 1, 'MSD')" - i_tztt="$i_tztt ,(4, 10, 10800, 1, 'EEST') ,(4, 11, 7200, 0, 'EET');" + i_tztt="$i_tztt ,(4, 10, 10800, 1, 'EEST') ,(4, 11, 7200, 0, 'EET')" + i_tztt="$i_tztt ,(5, 0, 32400, 0, 'CJT') ,(5, 1, 32400, 0, 'JST');" fi fi diff --git a/sql/item_create.cc b/sql/item_create.cc index 4290a25e348..c98c7892c26 100644 --- a/sql/item_create.cc +++ b/sql/item_create.cc @@ -89,11 +89,6 @@ Item *create_func_conv(Item* a, Item *b, Item *c) return new Item_func_conv(a,b,c); } -Item *create_func_convert_tz(Item* a, Item *b, Item *c) -{ - return new Item_func_convert_tz(a,b,c); -} - Item *create_func_cos(Item* a) { return new Item_func_cos(a); diff --git a/sql/item_create.h b/sql/item_create.h index 19f0c9133f2..7577627ef04 100644 --- a/sql/item_create.h +++ b/sql/item_create.h @@ -31,7 +31,6 @@ Item *create_func_char_length(Item* a); Item *create_func_cast(Item *a, Cast_target cast_type, int len, CHARSET_INFO *cs); Item *create_func_connection_id(void); Item *create_func_conv(Item* a, Item *b, Item *c); -Item *create_func_convert_tz(Item* a, Item *b, Item *c); Item *create_func_cos(Item* a); Item *create_func_cot(Item* a); Item *create_func_crc32(Item* a); diff --git a/sql/item_timefunc.cc b/sql/item_timefunc.cc index cc320addd47..73aec7e8bdd 100644 --- a/sql/item_timefunc.cc +++ b/sql/item_timefunc.cc @@ -1648,19 +1648,29 @@ bool Item_func_from_unixtime::get_date(TIME *ltime, void Item_func_convert_tz::fix_length_and_dec() -{ - String str; - - thd= current_thd; +{ collation.set(&my_charset_bin); decimals= 0; max_length= MAX_DATETIME_WIDTH*MY_CHARSET_BIN_MB_MAXLEN; +} + + +bool +Item_func_convert_tz::fix_fields(THD *thd_arg, TABLE_LIST *tables_arg, Item **ref) +{ + String str; + if (Item_date_func::fix_fields(thd_arg, tables_arg, ref)) + return 1; + + tz_tables= thd_arg->lex->time_zone_tables_used; if (args[1]->const_item()) - from_tz= my_tz_find(thd, args[1]->val_str(&str)); - + from_tz= my_tz_find(args[1]->val_str(&str), tz_tables); + if (args[2]->const_item()) - to_tz= my_tz_find(thd, args[2]->val_str(&str)); + to_tz= my_tz_find(args[2]->val_str(&str), tz_tables); + + return 0; } @@ -1701,10 +1711,10 @@ bool Item_func_convert_tz::get_date(TIME *ltime, String str; if (!args[1]->const_item()) - from_tz= my_tz_find(thd, args[1]->val_str(&str)); + from_tz= my_tz_find(args[1]->val_str(&str), tz_tables); if (!args[2]->const_item()) - to_tz= my_tz_find(thd, args[2]->val_str(&str)); + to_tz= my_tz_find(args[2]->val_str(&str), tz_tables); if (from_tz==0 || to_tz==0 || get_arg0_date(ltime, 0)) { diff --git a/sql/item_timefunc.h b/sql/item_timefunc.h index a7ff2924786..2254fc830c9 100644 --- a/sql/item_timefunc.h +++ b/sql/item_timefunc.h @@ -531,9 +531,22 @@ class Item_func_from_unixtime :public Item_date_func */ class Time_zone; +/* + This class represents CONVERT_TZ() function. + The important fact about this function that it is handled in special way. + When such function is met in expression time_zone system tables are added + to global list of tables to open, so later those already opened and locked + tables can be used during this function calculation for loading time zone + descriptions. +*/ class Item_func_convert_tz :public Item_date_func { - THD *thd; + /* Cached pointer to list of pre-opened time zone tables. */ + TABLE_LIST *tz_tables; + /* + If time zone parameters are constants we are caching objects that + represent them. + */ Time_zone *from_tz, *to_tz; public: Item_func_convert_tz(Item *a, Item *b, Item *c): @@ -542,6 +555,7 @@ class Item_func_convert_tz :public Item_date_func double val() { return (double) val_int(); } String *val_str(String *str); const char *func_name() const { return "convert_tz"; } + bool fix_fields(THD *, struct st_table_list *, Item **); void fix_length_and_dec(); bool get_date(TIME *res, uint fuzzy_date); }; diff --git a/sql/lex.h b/sql/lex.h index 218a1762a5c..c64a7069c32 100644 --- a/sql/lex.h +++ b/sql/lex.h @@ -499,7 +499,7 @@ static SYMBOL sql_functions[] = { { "CONNECTION_ID", F_SYM(FUNC_ARG0),0,CREATE_FUNC(create_func_connection_id)}, { "CONTAINS", F_SYM(FUNC_ARG2),0,CREATE_FUNC_GEOM(create_func_contains)}, { "CONV", F_SYM(FUNC_ARG3),0,CREATE_FUNC(create_func_conv)}, - { "CONVERT_TZ", F_SYM(FUNC_ARG3),0,CREATE_FUNC(create_func_convert_tz)}, + { "CONVERT_TZ", SYM(CONVERT_TZ_SYM)}, { "COUNT", SYM(COUNT_SYM)}, { "COS", F_SYM(FUNC_ARG1),0,CREATE_FUNC(create_func_cos)}, { "COT", F_SYM(FUNC_ARG1),0,CREATE_FUNC(create_func_cot)}, diff --git a/sql/mysql_priv.h b/sql/mysql_priv.h index 2f0e2085430..b3b79c16787 100644 --- a/sql/mysql_priv.h +++ b/sql/mysql_priv.h @@ -500,7 +500,6 @@ int mysql_select(THD *thd, Item ***rref_pointer_array, select_result *result, SELECT_LEX_UNIT *unit, SELECT_LEX *select_lex); void free_underlaid_joins(THD *thd, SELECT_LEX *select); -void fix_tables_pointers(SELECT_LEX *select_lex); int mysql_explain_union(THD *thd, SELECT_LEX_UNIT *unit, select_result *result); int mysql_explain_select(THD *thd, SELECT_LEX *sl, char const *type, diff --git a/sql/set_var.cc b/sql/set_var.cc index bcebb62ae4d..fc1332695d6 100644 --- a/sql/set_var.cc +++ b/sql/set_var.cc @@ -2372,8 +2372,9 @@ bool sys_var_thd_time_zone::check(THD *thd, set_var *var) return 1; } #endif - - if (!(var->save_result.time_zone= my_tz_find(thd, res))) + + if (!(var->save_result.time_zone= + my_tz_find(res, thd->lex->time_zone_tables_used))) { my_error(ER_UNKNOWN_TIME_ZONE, MYF(0), res ? res->c_ptr() : "NULL"); return 1; @@ -2418,7 +2419,8 @@ void sys_var_thd_time_zone::set_default(THD *thd, enum_var_type type) if (default_tz_name) { String str(default_tz_name, &my_charset_latin1); - global_system_variables.time_zone= my_tz_find(thd, &str); + global_system_variables.time_zone= + my_tz_find(&str, thd->lex->time_zone_tables_used); } else global_system_variables.time_zone= my_tz_SYSTEM; diff --git a/sql/set_var.h b/sql/set_var.h index a51e44285d6..4a4e631d88c 100644 --- a/sql/set_var.h +++ b/sql/set_var.h @@ -908,6 +908,7 @@ ulong fix_sql_mode(ulong sql_mode); extern sys_var_str sys_charset_system; extern sys_var_str sys_init_connect; extern sys_var_str sys_init_slave; +extern sys_var_thd_time_zone sys_time_zone; CHARSET_INFO *get_old_charset_by_name(const char *old_name); gptr find_named(I_List *list, const char *name, uint length, NAMED_LIST **found); diff --git a/sql/sql_base.cc b/sql/sql_base.cc index dd8283e057a..4efdd3edbcd 100644 --- a/sql/sql_base.cc +++ b/sql/sql_base.cc @@ -1670,7 +1670,22 @@ int open_and_lock_tables(THD *thd, TABLE_LIST *tables) uint counter; if (open_tables(thd, tables, &counter) || lock_tables(thd, tables, counter)) DBUG_RETURN(-1); /* purecov: inspected */ - fix_tables_pointers(thd->lex->all_selects_list); + /* + Let us propagate pointers to open tables from global table list + to table lists in particular selects if needed. + */ + if (thd->lex->all_selects_list->next_select_in_list() || + thd->lex->time_zone_tables_used) + { + for (SELECT_LEX *sl= thd->lex->all_selects_list; + sl; + sl= sl->next_select_in_list()) + for (TABLE_LIST *cursor= (TABLE_LIST *) sl->table_list.first; + cursor; + cursor=cursor->next) + if (cursor->table_list) + cursor->table= cursor->table_list->table; + } DBUG_RETURN(mysql_handle_derived(thd->lex)); } diff --git a/sql/sql_lex.cc b/sql/sql_lex.cc index 949eaba7311..2b6a307092c 100644 --- a/sql/sql_lex.cc +++ b/sql/sql_lex.cc @@ -22,6 +22,16 @@ #include #include + +/* + Fake table list object, pointer to which is used as special value for + st_lex::time_zone_tables_used indicating that we implicitly use time + zone tables in this statement but real table list was not yet created. + Pointer to it is also returned by my_tz_get_tables_list() as indication + of transient error; +*/ +TABLE_LIST fake_time_zone_tables_list; + /* Macros to look like lex */ #define yyGet() *(lex->ptr++) @@ -1292,7 +1302,32 @@ bool st_select_lex_unit::create_total_list(THD *thd_arg, st_lex *lex, TABLE_LIST **result_arg) { *result_arg= 0; - res= create_total_list_n_last_return(thd_arg, lex, &result_arg); + if (!(res= create_total_list_n_last_return(thd_arg, lex, &result_arg))) + { + /* + If time zone tables were used implicitly in statement we should add + them to global table list. + */ + if (lex->time_zone_tables_used) + { + /* + Altough we are modifying lex data, it won't raise any problem in + case when this lex belongs to some prepared statement or stored + procedure: such modification does not change any invariants imposed + by requirement to reuse the same lex for multiple executions. + */ + if ((lex->time_zone_tables_used= my_tz_get_table_list(thd)) != + &fake_time_zone_tables_list) + { + *result_arg= lex->time_zone_tables_used; + } + else + { + send_error(thd, 0); + res= 1; + } + } + } return res; } diff --git a/sql/sql_lex.h b/sql/sql_lex.h index 5348d5e5646..053c85166f6 100644 --- a/sql/sql_lex.h +++ b/sql/sql_lex.h @@ -633,6 +633,12 @@ typedef struct st_lex bool prepared_stmt_code_is_varref; /* Names of user variables holding parameters (in EXECUTE) */ List prepared_stmt_params; + /* + If points to fake_time_zone_tables_list indicates that time zone + tables are implicitly used by statement, also is used for holding + list of those tables after they are opened. + */ + TABLE_LIST *time_zone_tables_used; st_lex() {} inline void uncacheable(uint8 cause) { @@ -661,6 +667,7 @@ typedef struct st_lex TABLE_LIST *local_first); } LEX; +extern TABLE_LIST fake_time_zone_tables_list; void lex_init(void); void lex_free(void); diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc index b69d582f30b..1182f018ea4 100644 --- a/sql/sql_parse.cc +++ b/sql/sql_parse.cc @@ -1897,7 +1897,8 @@ mysql_execute_command(THD *thd) #endif } #endif /* !HAVE_REPLICATION */ - if (&lex->select_lex != lex->all_selects_list && + if ((&lex->select_lex != lex->all_selects_list || + lex->time_zone_tables_used) && lex->unit.create_total_list(thd, lex, &tables)) DBUG_VOID_RETURN; @@ -3875,6 +3876,7 @@ mysql_init_query(THD *thd, uchar *buf, uint length) lex->lock_option= TL_READ; lex->found_colon= 0; lex->safe_to_cache_query= 1; + lex->time_zone_tables_used= 0; lex_start(thd, buf, length); thd->select_number= lex->select_lex.select_number= 1; thd->free_list= 0; diff --git a/sql/sql_prepare.cc b/sql/sql_prepare.cc index d8deba2c939..db904d24bf7 100644 --- a/sql/sql_prepare.cc +++ b/sql/sql_prepare.cc @@ -1407,7 +1407,8 @@ static int send_prepare_results(Prepared_statement *stmt, bool text_protocol) DBUG_PRINT("enter",("command: %d, param_count: %ld", sql_command, stmt->param_count)); - if (select_lex != lex->all_selects_list && + if ((&lex->select_lex != lex->all_selects_list || + lex->time_zone_tables_used) && lex->unit.create_total_list(thd, lex, &tables)) DBUG_RETURN(1); diff --git a/sql/sql_select.cc b/sql/sql_select.cc index 3b3d8303210..f8bc6210a2f 100644 --- a/sql/sql_select.cc +++ b/sql/sql_select.cc @@ -213,39 +213,6 @@ int handle_select(THD *thd, LEX *lex, select_result *result) } -void relink_tables(SELECT_LEX *select_lex) -{ - for (TABLE_LIST *cursor= (TABLE_LIST *) select_lex->table_list.first; - cursor; - cursor=cursor->next) - if (cursor->table_list) - cursor->table= cursor->table_list->table; -} - - -void fix_tables_pointers(SELECT_LEX *select_lex) -{ - if (select_lex->next_select_in_list()) - { - /* Fix tables 'to-be-unioned-from' list to point at opened tables */ - for (SELECT_LEX *sl= select_lex; - sl; - sl= sl->next_select_in_list()) - relink_tables(sl); - } -} - -void fix_tables_pointers(SELECT_LEX_UNIT *unit) -{ - for (SELECT_LEX *sl= unit->first_select(); sl; sl= sl->next_select()) - { - relink_tables(sl); - for (SELECT_LEX_UNIT *un= sl->first_inner_unit(); un; un= un->next_unit()) - fix_tables_pointers(un); - } -} - - /* Function to setup clauses without sum functions */ diff --git a/sql/sql_yacc.yy b/sql/sql_yacc.yy index ccbaf7c0112..5d6ca5d5de5 100644 --- a/sql/sql_yacc.yy +++ b/sql/sql_yacc.yy @@ -463,6 +463,7 @@ bool my_yyoverflow(short **a, YYSTYPE **b, ulong *yystacksize); %token CASE_SYM %token CONCAT %token CONCAT_WS +%token CONVERT_TZ_SYM %token CURDATE %token CURTIME %token DATABASE @@ -2825,6 +2826,11 @@ simple_expr: { $$= new Item_func_concat(* $3); } | CONCAT_WS '(' expr ',' expr_list ')' { $$= new Item_func_concat_ws($3, *$5); } + | CONVERT_TZ_SYM '(' expr ',' expr ',' expr ')' + { + Lex->time_zone_tables_used= &fake_time_zone_tables_list; + $$= new Item_func_convert_tz($3, $5, $7); + } | CURDATE optional_braces { $$= new Item_func_curdate_local(); Lex->safe_to_cache_query=0; } | CURTIME optional_braces @@ -5308,6 +5314,12 @@ internal_variable_name: $$.var= tmp; $$.base_name.str=0; $$.base_name.length=0; + /* + If this is time_zone variable we should open time zone + describing tables + */ + if (tmp == &sys_time_zone) + Lex->time_zone_tables_used= &fake_time_zone_tables_list; } | ident '.' ident { diff --git a/sql/tztime.cc b/sql/tztime.cc index 2ed55f2fa4e..757272d332f 100644 --- a/sql/tztime.cc +++ b/sql/tztime.cc @@ -1359,6 +1359,13 @@ static bool tz_inited= 0; static uint tz_leapcnt= 0; static LS_INFO *tz_lsis= 0; +/* + Shows whenever we have found time zone tables during start-up. + Used for avoiding of putting those tables to global table list + for queries that use time zone info. +*/ +static bool time_zone_tables_exist= 1; + typedef struct st_tz_names_entry: public Sql_alloc { @@ -1387,6 +1394,68 @@ extern "C" byte* my_offset_tzs_get_key(Time_zone_offset *entry, uint *length, } +/* + Prepare table list with time zone related tables from preallocated array. + + SYNOPSIS + tz_init_table_list() + tz_tabs - pointer to preallocated array of 4 TABLE_LIST objects. + + DESCRIPTION + This function prepares list of TABLE_LIST objects which can be used + for opening of time zone tables from preallocated array. +*/ + +void +tz_init_table_list(TABLE_LIST *tz_tabs) +{ + bzero(tz_tabs, sizeof(TABLE_LIST) * 4); + tz_tabs[0].alias= tz_tabs[0].real_name= (char*)"time_zone_name"; + tz_tabs[1].alias= tz_tabs[1].real_name= (char*)"time_zone"; + tz_tabs[2].alias= tz_tabs[2].real_name= (char*)"time_zone_transition_type"; + tz_tabs[3].alias= tz_tabs[3].real_name= (char*)"time_zone_transition"; + tz_tabs[0].next= tz_tabs+1; + tz_tabs[1].next= tz_tabs+2; + tz_tabs[2].next= tz_tabs+3; + tz_tabs[0].lock_type= tz_tabs[1].lock_type= tz_tabs[2].lock_type= + tz_tabs[3].lock_type= TL_READ; + tz_tabs[0].db= tz_tabs[1].db= tz_tabs[2].db= tz_tabs[3].db= (char *)"mysql"; +} + + +/* + Create table list with time zone related tables. + + SYNOPSIS + my_tz_get_table_list() + thd - current thread object + + DESCRIPTION + This function creates list of TABLE_LIST objects allocated in thd's + memroot, which can be used for opening of time zone tables. + + RETURN VALUES + Returns pointer to first TABLE_LIST object, (could be 0 if time zone + tables don't exist) and &fake_time_zone_tables_list in case of error. +*/ + +TABLE_LIST * +my_tz_get_table_list(THD *thd) +{ + TABLE_LIST *tz_tabs; + + if (!time_zone_tables_exist) + return 0; + + if (!(tz_tabs= (TABLE_LIST *)thd->alloc(sizeof(TABLE_LIST) * 4))) + return &fake_time_zone_tables_list; + + tz_init_table_list(tz_tabs); + + return tz_tabs; +} + + /* Initialize time zone support infrastructure. @@ -1399,13 +1468,13 @@ extern "C" byte* my_offset_tzs_get_key(Time_zone_offset *entry, uint *length, DESCRIPTION This function will init memory structures needed for time zone support, it will register mandatory SYSTEM time zone in them. It will try to open - mysql.time_zone_leap_seconds table and and load information which further - will be shared among all time zones loaded. It will also try to load - information about default time zone. If system tables with time zone - descriptions don't exist it won't fail (unless default_tzname is time zone - from tables). If bootstrap parameter is true then this routine assumes that - we are in bootstrap mode and won't load time zone descriptions unless someone - specifies default time zone which is supposedly stored in those tables. + mysql.time_zone* tables and load information about default time zone and + information which further will be shared among all time zones loaded. + If system tables with time zone descriptions don't exist it won't fail + (unless default_tzname is time zone from tables). If bootstrap parameter + is true then this routine assumes that we are in bootstrap mode and won't + load time zone descriptions unless someone specifies default time zone + which is supposedly stored in those tables. It'll also set default time zone if it is specified. RETURN VALUES @@ -1416,14 +1485,13 @@ my_bool my_tz_init(THD *org_thd, const char *default_tzname, my_bool bootstrap) { THD *thd; - TABLE_LIST tables; + TABLE_LIST *tables= 0; + TABLE_LIST tables_buff[5]; TABLE *table; - TABLE *lock_ptr; - MYSQL_LOCK *lock; TZ_NAMES_ENTRY *tmp_tzname; my_bool return_val= 1; int res; - uint not_used; + uint counter; DBUG_ENTER("my_tz_init"); /* @@ -1468,7 +1536,7 @@ my_tz_init(THD *org_thd, const char *default_tzname, my_bool bootstrap) if (bootstrap) { /* If we are in bootstrap mode we should not load time zone tables */ - return_val= 0; + return_val= time_zone_tables_exist= 0; goto end_with_setting_default_tz; } @@ -1480,28 +1548,25 @@ my_tz_init(THD *org_thd, const char *default_tzname, my_bool bootstrap) thd->db= my_strdup("mysql",MYF(0)); thd->db_length= 5; // Safety - bzero((char*) &tables,sizeof(tables)); - tables.alias= tables.real_name= (char*)"time_zone_leap_second"; - tables.lock_type= TL_READ; - tables.db= thd->db; + bzero((char*) &tables_buff, sizeof(TABLE_LIST)); + tables_buff[0].alias= tables_buff[0].real_name= + (char*)"time_zone_leap_second"; + tables_buff[0].lock_type= TL_READ; + tables_buff[0].db= thd->db; + tables_buff[0].next= tables_buff + 1; + /* Fill TABLE_LIST for rest of the time zone describing tables */ + tz_init_table_list(tables_buff + 1); - if (open_tables(thd, &tables, ¬_used)) + if (open_tables(thd, tables_buff, &counter) || + lock_tables(thd, tables_buff, counter)) { - sql_print_error("Warning: Can't open time zone table: %s " + sql_print_error("Warning: Can't open and lock time zone table: %s " "trying to live without them", thd->net.last_error); /* We will try emulate that everything is ok */ - return_val= 0; + return_val= time_zone_tables_exist= 0; goto end_with_setting_default_tz; } - - lock_ptr= tables.table; - if (!(lock= mysql_lock_tables(thd, &lock_ptr, 1))) - { - sql_print_error("Fatal error: Can't lock time zone table: %s", - thd->net.last_error); - goto end_with_close; - } - + tables= tables_buff + 1; /* Now we are going to load leap seconds descriptions that are shared @@ -1514,11 +1579,16 @@ my_tz_init(THD *org_thd, const char *default_tzname, my_bool bootstrap) { sql_print_error("Fatal error: Out of memory while loading " "mysql.time_zone_leap_second table"); - goto end_with_unlock; + goto end_with_close; } - table= tables.table; - table->file->ha_index_init(0); + table= tables_buff[0].table; + /* + It is OK to ignore ha_index_init()/ha_index_end() return values since + mysql.time_zone* tables are MyISAM and these operations always succeed + for MyISAM. + */ + (void)table->file->ha_index_init(0); tz_leapcnt= 0; res= table->file->index_first(table->record[0]); @@ -1530,7 +1600,7 @@ my_tz_init(THD *org_thd, const char *default_tzname, my_bool bootstrap) sql_print_error("Fatal error: While loading mysql.time_zone_leap_second" " table: too much leaps"); table->file->ha_index_end(); - goto end_with_unlock; + goto end_with_close; } tz_lsis[tz_leapcnt].ls_trans= (my_time_t)table->field[0]->val_int(); @@ -1546,13 +1616,13 @@ my_tz_init(THD *org_thd, const char *default_tzname, my_bool bootstrap) res= table->file->index_next(table->record[0]); } - table->file->ha_index_end(); + (void)table->file->ha_index_end(); if (res != HA_ERR_END_OF_FILE) { sql_print_error("Fatal error: Error while loading " "mysql.time_zone_leap_second table"); - goto end_with_unlock; + goto end_with_close; } /* @@ -1562,19 +1632,12 @@ my_tz_init(THD *org_thd, const char *default_tzname, my_bool bootstrap) return_val= 0; -end_with_unlock: - mysql_unlock_tables(thd, lock); - -end_with_close: - close_thread_tables(thd); - thd->version--; /* Force close to free memory */ - end_with_setting_default_tz: - /* If not an error and have default time zone try to load it */ - if (!return_val && default_tzname) + /* If we have default time zone try to load it */ + if (default_tzname) { String tzname(default_tzname, &my_charset_latin1); - if (!(global_system_variables.time_zone= my_tz_find(thd, &tzname))) + if (!(global_system_variables.time_zone= my_tz_find(&tzname, tables))) { sql_print_error("Fatal error: Illegal or unknown default time zone '%s'", default_tzname); @@ -1582,6 +1645,10 @@ end_with_setting_default_tz: } } +end_with_close: + thd->version--; /* Force close to free memory */ + close_thread_tables(thd); + end_with_cleanup: /* if there were error free time zone describing structs */ @@ -1625,29 +1692,27 @@ void my_tz_free() Load time zone description from system tables. SYNOPSIS - tz_load_from_db() - thd - current thread object - tz_name - name of time zone that should be loaded. + tz_load_from_open_tables() + tz_name - name of time zone that should be loaded. + tz_tables - list of tables from which time zone description + should be loaded DESCRIPTION - This function will try to open system tables describing time zones - and to load information about time zone specified. It will also update - information in hash used for time zones lookup. + This function will try to load information about time zone specified + from the list of the already opened and locked tables (first table in + tz_tables should be time_zone_name, next time_zone, then + time_zone_transition_type and time_zone_transition should be last). + It will also update information in hash used for time zones lookup. RETURN VALUES Returns pointer to newly created Time_zone object or 0 in case of error. */ + static Time_zone* -tz_load_from_db(THD *thd, const String *tz_name) +tz_load_from_open_tables(const String *tz_name, TABLE_LIST *tz_tables) { - TABLE_LIST tables[4]; TABLE *table= 0; - TABLE *lock_ptr[4]; - MYSQL_LOCK *lock; - char system_db_name[]= "mysql"; - char *db_save; - uint db_length_save; TIME_ZONE_INFO *tz_info; TZ_NAMES_ENTRY *tmp_tzname; Time_zone *return_val= 0; @@ -1667,9 +1732,8 @@ tz_load_from_db(THD *thd, const String *tz_name) #ifdef ABBR_ARE_USED char chars[max(TZ_MAX_CHARS + 1, (2 * (MY_TZNAME_MAX + 1)))]; #endif - uint not_used; - DBUG_ENTER("tz_load_from_db"); + DBUG_ENTER("tz_load_from_open_tables"); /* Prepare tz_info for loading also let us make copy of time zone name */ @@ -1689,77 +1753,46 @@ tz_load_from_db(THD *thd, const String *tz_name) */ strmake(tz_name_buff, tz_name->ptr(), tz_name->length()); - /* - Open and lock time zone description tables - */ - db_save= thd->db; - db_length_save= thd->db_length; - thd->db= system_db_name; - thd->db_length= 5; - - bzero((char*) &tables,sizeof(tables)); - tables[0].alias= tables[0].real_name= (char*)"time_zone_name"; - tables[1].alias= tables[1].real_name= (char*)"time_zone"; - tables[2].alias= tables[2].real_name= (char*)"time_zone_transition"; - tables[3].alias= tables[3].real_name= (char*)"time_zone_transition_type"; - tables[0].next= tables+1; - tables[1].next= tables+2; - tables[2].next= tables+3; - tables[0].lock_type= tables[1].lock_type= tables[2].lock_type= - tables[3].lock_type= TL_READ; - tables[0].db= tables[1].db= tables[2].db= tables[3].db= thd->db; - if (open_tables(thd, tables, ¬_used)) - { - sql_print_error("Error: Can't open time zone tables: %s", - thd->net.last_error); - goto end; - } - - lock_ptr[0]= tables[0].table; - lock_ptr[1]= tables[1].table; - lock_ptr[2]= tables[2].table; - lock_ptr[3]= tables[3].table; - if (!(lock= mysql_lock_tables(thd, lock_ptr, 4))) - { - sql_print_error("Error: Can't lock time zone tables: %s", - thd->net.last_error); - goto end_with_close; - } - /* Let us find out time zone id by its name (there is only one index and it is specifically for this purpose). */ - table= tables[0].table; - + table= tz_tables->table; + tz_tables= tz_tables->next; table->field[0]->store(tz_name->ptr(), tz_name->length(), &my_charset_latin1); - table->file->ha_index_init(0); + /* + It is OK to ignore ha_index_init()/ha_index_end() return values since + mysql.time_zone* tables are MyISAM and these operations always succeed + for MyISAM. + */ + (void)table->file->ha_index_init(0); if (table->file->index_read(table->record[0], (byte*)table->field[0]->ptr, 0, HA_READ_KEY_EXACT)) { sql_print_error("Error: Can't find description of time zone."); - goto end_with_unlock; + goto end; } tzid= (uint)table->field[1]->val_int(); - table->file->ha_index_end(); + (void)table->file->ha_index_end(); /* Now we need to lookup record in mysql.time_zone table in order to understand whenever this timezone uses leap seconds (again we are using the only index in this table). */ - table= tables[1].table; + table= tz_tables->table; + tz_tables= tz_tables->next; table->field[0]->store((longlong)tzid); - table->file->ha_index_init(0); + (void)table->file->ha_index_init(0); if (table->file->index_read(table->record[0], (byte*)table->field[0]->ptr, 0, HA_READ_KEY_EXACT)) { sql_print_error("Error: Can't find description of time zone."); - goto end_with_unlock; + goto end; } /* If Uses_leap_seconds == 'Y' */ @@ -1769,7 +1802,7 @@ tz_load_from_db(THD *thd, const String *tz_name) tz_info->lsis= tz_lsis; } - table->file->ha_index_end(); + (void)table->file->ha_index_end(); /* Now we will iterate through records for out time zone in @@ -1777,9 +1810,10 @@ tz_load_from_db(THD *thd, const String *tz_name) only for our time zone guess what are we doing? Right - using special index. */ - table= tables[3].table; + table= tz_tables->table; + tz_tables= tz_tables->next; table->field[0]->store((longlong)tzid); - table->file->ha_index_init(0); + (void)table->file->ha_index_init(0); // FIXME Is there any better approach than explicitly specifying 4 ??? res= table->file->index_read(table->record[0], (byte*)table->field[0]->ptr, @@ -1793,7 +1827,7 @@ tz_load_from_db(THD *thd, const String *tz_name) sql_print_error("Error while loading time zone description from " "mysql.time_zone_transition_type table: too big " "transition type id"); - goto end_with_unlock; + goto end; } ttis[ttid].tt_gmtoff= (long)table->field[2]->val_int(); @@ -1807,7 +1841,7 @@ tz_load_from_db(THD *thd, const String *tz_name) sql_print_error("Error while loading time zone description from " "mysql.time_zone_transition_type table: not enough " "room for abbreviations"); - goto end_with_unlock; + goto end; } ttis[ttid].tt_abbrind= tz_info->charcnt; memcpy(chars + tz_info->charcnt, abbr.ptr(), abbr.length()); @@ -1838,10 +1872,10 @@ tz_load_from_db(THD *thd, const String *tz_name) { sql_print_error("Error while loading time zone description from " "mysql.time_zone_transition_type table"); - goto end_with_unlock; + goto end; } - table->file->ha_index_end(); + (void)table->file->ha_index_end(); /* @@ -1849,9 +1883,9 @@ tz_load_from_db(THD *thd, const String *tz_name) mysql.time_zone_transition table. Here we additionaly need records in ascending order by index scan also satisfies us. */ - table= tables[2].table; + table= tz_tables->table; table->field[0]->store((longlong)tzid); - table->file->ha_index_init(0); + (void)table->file->ha_index_init(0); // FIXME Is there any better approach than explicitly specifying 4 ??? res= table->file->index_read(table->record[0], (byte*)table->field[0]->ptr, @@ -1866,14 +1900,14 @@ tz_load_from_db(THD *thd, const String *tz_name) sql_print_error("Error while loading time zone description from " "mysql.time_zone_transition table: " "too much transitions"); - goto end_with_unlock; + goto end; } if (ttid + 1 > tz_info->typecnt) { sql_print_error("Error while loading time zone description from " "mysql.time_zone_transition table: " "bad transition type id"); - goto end_with_unlock; + goto end; } ats[tz_info->timecnt]= ttime; @@ -1896,10 +1930,10 @@ tz_load_from_db(THD *thd, const String *tz_name) { sql_print_error("Error while loading time zone description from " "mysql.time_zone_transition table"); - goto end_with_unlock; + goto end; } - table->file->ha_index_end(); + (void)table->file->ha_index_end(); table= 0; /* @@ -1916,7 +1950,7 @@ tz_load_from_db(THD *thd, const String *tz_name) { sql_print_error("Error: Out of memory while loading time zone " "description"); - goto end_with_unlock; + goto end; } @@ -1941,12 +1975,12 @@ tz_load_from_db(THD *thd, const String *tz_name) if (tz_info->typecnt < 1) { sql_print_error("Error: loading time zone without transition types"); - goto end_with_unlock; + goto end; } if (prepare_tz_info(tz_info, &tz_storage)) { sql_print_error("Error: Unable to build mktime map for time zone"); - goto end_with_unlock; + goto end; } @@ -1958,7 +1992,7 @@ tz_load_from_db(THD *thd, const String *tz_name) my_hash_insert(&tz_names, (const byte *)tmp_tzname))) { sql_print_error("Error: Out of memory while loading time zone"); - goto end_with_unlock; + goto end; } /* @@ -1966,19 +2000,11 @@ tz_load_from_db(THD *thd, const String *tz_name) */ return_val= tmp_tzname->tz; -end_with_unlock: +end: if (table) - table->file->ha_index_end(); + (void)table->file->ha_index_end(); - mysql_unlock_tables(thd, lock); - -end_with_close: - close_thread_tables(thd); - -end: - thd->db= db_save; - thd->db_length= db_length_save; DBUG_RETURN(return_val); } @@ -2068,8 +2094,8 @@ str_to_offset(const char *str, uint length, long *offset) SYNOPSIS my_tz_find() - thd - current thread name - time zone specification + tz_tables - list of opened'n'locked time zone describing tables DESCRIPTION This function checks if name is one of time zones described in db, @@ -2091,7 +2117,11 @@ str_to_offset(const char *str, uint length, long *offset) values as parameter without additional external check and this property is used by @@time_zone variable handling code). - It will perform lookup in system tables (mysql.time_zone*) if needed. + It will perform lookup in system tables (mysql.time_zone*) if needed + using tz_tables as list of already opened tables (for info about this + list look at tz_load_from_open_tables() description). It won't perform + such lookup if no time zone describing tables were found during server + start up. RETURN VALUE Pointer to corresponding Time_zone object. 0 - in case of bad time zone @@ -2099,7 +2129,7 @@ str_to_offset(const char *str, uint length, long *offset) */ Time_zone * -my_tz_find(THD *thd, const String * name) +my_tz_find(const String * name, TABLE_LIST *tz_tables) { TZ_NAMES_ENTRY *tmp_tzname; Time_zone *result_tz= 0; @@ -2109,6 +2139,8 @@ my_tz_find(THD *thd, const String * name) DBUG_PRINT("enter", ("time zone name='%s'", name ? ((String *)name)->c_ptr() : "NULL")); + DBUG_ASSERT(!time_zone_tables_exist || tz_tables); + if (!name) DBUG_RETURN(0); @@ -2136,8 +2168,10 @@ my_tz_find(THD *thd, const String * name) (const byte *)name->ptr(), name->length()))) result_tz= tmp_tzname->tz; + else if(time_zone_tables_exist) + result_tz= tz_load_from_open_tables(name, tz_tables); else - result_tz= tz_load_from_db(thd, name); + result_tz= 0; } VOID(pthread_mutex_unlock(&tz_LOCK)); diff --git a/sql/tztime.h b/sql/tztime.h index 69ff176326e..aabec260ec7 100644 --- a/sql/tztime.h +++ b/sql/tztime.h @@ -59,7 +59,8 @@ public: extern Time_zone * my_tz_UTC; extern Time_zone * my_tz_SYSTEM; -extern Time_zone * my_tz_find(THD *thd, const String *name); +extern TABLE_LIST * my_tz_get_table_list(THD *thd); +extern Time_zone * my_tz_find(const String *name, TABLE_LIST *tz_tables); extern my_bool my_tz_init(THD *org_thd, const char *default_tzname, my_bool bootstrap); extern void my_tz_free();