diff options
-rw-r--r-- | include/my_time.h | 2 | ||||
-rw-r--r-- | innobase/srv/srv0start.c | 7 | ||||
-rw-r--r-- | libmysql/libmysql.c | 7 | ||||
-rw-r--r-- | ndb/src/kernel/blocks/dbdict/Dbdict.cpp | 2 | ||||
-rw-r--r-- | ndb/src/kernel/blocks/dbdih/Dbdih.hpp | 1 | ||||
-rw-r--r-- | ndb/src/kernel/blocks/dbdih/DbdihMain.cpp | 29 | ||||
-rw-r--r-- | sql-common/my_time.c | 10 | ||||
-rw-r--r-- | sql/sql_prepare.cc | 50 | ||||
-rw-r--r-- | tests/client_test.c | 74 |
9 files changed, 135 insertions, 47 deletions
diff --git a/include/my_time.h b/include/my_time.h index 6c53e39d1d8..d4dbe459c3b 100644 --- a/include/my_time.h +++ b/include/my_time.h @@ -58,6 +58,8 @@ void init_time(void); my_time_t my_system_gmt_sec(const MYSQL_TIME *t, long *my_timezone, bool *in_dst_time_gap); +void set_zero_time(MYSQL_TIME *tm); + C_MODE_END #endif /* _my_time_h_ */ diff --git a/innobase/srv/srv0start.c b/innobase/srv/srv0start.c index 3d49a594924..4a0335086f0 100644 --- a/innobase/srv/srv0start.c +++ b/innobase/srv/srv0start.c @@ -1587,9 +1587,10 @@ NetWare. */ fprintf(stderr, "InnoDB: You have now successfully upgraded to the multiple tablespaces\n" -"InnoDB: format. You should NOT DOWNGRADE again to an earlier version of\n" -"InnoDB: InnoDB! But if you absolutely need to downgrade, see section 4.6 of\n" -"InnoDB: http://www.innodb.com/ibman.php for instructions.\n"); +"InnoDB: format. You should NOT DOWNGRADE to an earlier version of\n" +"InnoDB: InnoDB! But if you absolutely need to downgrade, see\n" +"InnoDB: http://dev.mysql.com/doc/mysql/en/Multiple_tablespaces.html\n" +"InnoDB: for instructions.\n"); } if (srv_force_recovery == 0) { diff --git a/libmysql/libmysql.c b/libmysql/libmysql.c index 380e53d7d47..7d71998f37d 100644 --- a/libmysql/libmysql.c +++ b/libmysql/libmysql.c @@ -3167,13 +3167,6 @@ mysql_stmt_send_long_data(MYSQL_STMT *stmt, uint param_number, Fetch and conversion of result set rows (binary protocol). *********************************************************************/ -static void set_zero_time(MYSQL_TIME *tm) -{ - bzero((void *)tm, sizeof(*tm)); - tm->time_type= MYSQL_TIMESTAMP_NONE; -} - - /* Read date, (time, datetime) value from network buffer and store it in MYSQL_TIME structure. diff --git a/ndb/src/kernel/blocks/dbdict/Dbdict.cpp b/ndb/src/kernel/blocks/dbdict/Dbdict.cpp index d7c4b8a2222..7126842459e 100644 --- a/ndb/src/kernel/blocks/dbdict/Dbdict.cpp +++ b/ndb/src/kernel/blocks/dbdict/Dbdict.cpp @@ -5660,7 +5660,7 @@ void Dbdict::execGET_TABINFOREQ(Signal* signal) signal->getSection(ssPtr,GetTabInfoReq::TABLE_NAME); SimplePropertiesSectionReader r0(ssPtr, getSectionSegmentPool()); r0.reset(); // undo implicit first() - if(r0.getWords((Uint32*)tableName, len)) + if(r0.getWords((Uint32*)tableName, ((len + 3)/4))) memcpy(keyRecord.tableName, tableName, len); else { jam(); diff --git a/ndb/src/kernel/blocks/dbdih/Dbdih.hpp b/ndb/src/kernel/blocks/dbdih/Dbdih.hpp index a96bcf74db1..14fa262f871 100644 --- a/ndb/src/kernel/blocks/dbdih/Dbdih.hpp +++ b/ndb/src/kernel/blocks/dbdih/Dbdih.hpp @@ -943,6 +943,7 @@ private: void ndbStartReqLab(Signal *, BlockReference ref); void nodeRestartStartRecConfLab(Signal *); void dihCopyCompletedLab(Signal *); + void release_connect(ConnectRecordPtr ptr); void copyTableNode(Signal *, CopyTableNode* ctn, NodeRecordPtr regNodePtr); diff --git a/ndb/src/kernel/blocks/dbdih/DbdihMain.cpp b/ndb/src/kernel/blocks/dbdih/DbdihMain.cpp index caa548e5f07..0a8abe59aed 100644 --- a/ndb/src/kernel/blocks/dbdih/DbdihMain.cpp +++ b/ndb/src/kernel/blocks/dbdih/DbdihMain.cpp @@ -6130,13 +6130,9 @@ void Dbdih::execDIRELEASEREQ(Signal* signal) ptrCheckGuard(connectPtr, cconnectFileSize, connectRecord); ndbrequire(connectPtr.p->connectState != ConnectRecord::FREE); ndbrequire(connectPtr.p->userblockref == userRef); - connectPtr.p->connectState = ConnectRecord::FREE; signal->theData[0] = connectPtr.p->userpointer; sendSignal(connectPtr.p->userblockref, GSN_DIRELEASECONF, signal, 1, JBB); - connectPtr.p->nfConnect = cfirstconnect; - cfirstconnect = connectPtr.i; - connectPtr.p->userblockref = ZNIL; - connectPtr.p->userpointer = RNIL; + release_connect(connectPtr); }//Dbdih::execDIRELEASEREQ() /* @@ -6573,11 +6569,16 @@ Dbdih::sendAddFragreq(Signal* signal, ConnectRecordPtr connectPtr, DiAddTabConf::SignalLength, JBB); // Release - connectPtr.p->userblockref = ZNIL; - connectPtr.p->userpointer = RNIL; - connectPtr.p->connectState = ConnectRecord::FREE; - connectPtr.p->nfConnect = cfirstconnect; - cfirstconnect = connectPtr.i; + release_connect(connectPtr); +} +void +Dbdih::release_connect(ConnectRecordPtr ptr) +{ + ptr.p->userblockref = ZNIL; + ptr.p->userpointer = RNIL; + ptr.p->connectState = ConnectRecord::FREE; + ptr.p->nfConnect = cfirstconnect; + cfirstconnect = ptr.i; } void @@ -6614,11 +6615,7 @@ Dbdih::execADD_FRAGREF(Signal* signal){ } // Release - connectPtr.p->userblockref = ZNIL; - connectPtr.p->userpointer = RNIL; - connectPtr.p->connectState = ConnectRecord::FREE; - connectPtr.p->nfConnect = cfirstconnect; - cfirstconnect = connectPtr.i; + release_connect(connectPtr); } /* @@ -6627,10 +6624,10 @@ Dbdih::execADD_FRAGREF(Signal* signal){ */ void Dbdih::addtabrefuseLab(Signal* signal, ConnectRecordPtr connectPtr, Uint32 errorCode) { - connectPtr.p->connectState = ConnectRecord::INUSE; signal->theData[0] = connectPtr.p->userpointer; signal->theData[1] = errorCode; sendSignal(connectPtr.p->userblockref, GSN_DIADDTABREF, signal, 2, JBB); + release_connect(connectPtr); return; }//Dbdih::addtabrefuseLab() diff --git a/sql-common/my_time.c b/sql-common/my_time.c index fcfa2efef61..4b5daf53bea 100644 --- a/sql-common/my_time.c +++ b/sql-common/my_time.c @@ -716,3 +716,13 @@ my_system_gmt_sec(const MYSQL_TIME *t, long *my_timezone, bool *in_dst_time_gap) return (my_time_t) tmp; } /* my_system_gmt_sec */ + + +/* Set MYSQL_TIME structure to 0000-00-00 00:00:00.000000 */ + +void set_zero_time(MYSQL_TIME *tm) +{ + bzero((void*) tm, sizeof(*tm)); + tm->time_type= MYSQL_TIMESTAMP_NONE; +} + diff --git a/sql/sql_prepare.cc b/sql/sql_prepare.cc index 50255e6d00c..1b6c7dbc9bc 100644 --- a/sql/sql_prepare.cc +++ b/sql/sql_prepare.cc @@ -329,15 +329,22 @@ static void set_param_double(Item_param *param, uchar **pos, ulong len) } #ifndef EMBEDDED_LIBRARY + +/* + Read date/time/datetime parameter values from network (binary + protocol). See writing counterparts of these functions in + libmysql.c (store_param_{time,date,datetime}). +*/ + static void set_param_time(Item_param *param, uchar **pos, ulong len) { - ulong length; - uint day; + MYSQL_TIME tm; + ulong length= get_param_length(pos, len); - if ((length= get_param_length(pos, len)) >= 8) + if (length >= 8) { uchar *to= *pos; - TIME tm; + uint day; tm.neg= (bool) to[0]; day= (uint) sint4korr(to+1); @@ -359,21 +366,22 @@ static void set_param_time(Item_param *param, uchar **pos, ulong len) tm.second= 59; } tm.day= tm.year= tm.month= 0; - - param->set_time(&tm, MYSQL_TIMESTAMP_TIME, - MAX_TIME_WIDTH * MY_CHARSET_BIN_MB_MAXLEN); } + else + set_zero_time(&tm); + param->set_time(&tm, MYSQL_TIMESTAMP_TIME, + MAX_TIME_WIDTH * MY_CHARSET_BIN_MB_MAXLEN); *pos+= length; } static void set_param_datetime(Item_param *param, uchar **pos, ulong len) { - uint length; + MYSQL_TIME tm; + ulong length= get_param_length(pos, len); - if ((length= get_param_length(pos, len)) >= 4) + if (length >= 4) { uchar *to= *pos; - TIME tm; tm.neg= 0; tm.year= (uint) sint2korr(to); @@ -394,21 +402,22 @@ static void set_param_datetime(Item_param *param, uchar **pos, ulong len) tm.hour= tm.minute= tm.second= 0; tm.second_part= (length > 7) ? (ulong) sint4korr(to+7) : 0; - - param->set_time(&tm, MYSQL_TIMESTAMP_DATETIME, - MAX_DATETIME_WIDTH * MY_CHARSET_BIN_MB_MAXLEN); } + else + set_zero_time(&tm); + param->set_time(&tm, MYSQL_TIMESTAMP_DATETIME, + MAX_DATETIME_WIDTH * MY_CHARSET_BIN_MB_MAXLEN); *pos+= length; } static void set_param_date(Item_param *param, uchar **pos, ulong len) { - ulong length; - - if ((length= get_param_length(pos, len)) >= 4) + MYSQL_TIME tm; + ulong length= get_param_length(pos, len); + + if (length >= 4) { uchar *to= *pos; - TIME tm; /* Note, that though ranges of hour, minute and second are not checked here we rely on them being < 256: otherwise @@ -421,10 +430,11 @@ static void set_param_date(Item_param *param, uchar **pos, ulong len) tm.hour= tm.minute= tm.second= 0; tm.second_part= 0; tm.neg= 0; - - param->set_time(&tm, MYSQL_TIMESTAMP_DATE, - MAX_DATE_WIDTH * MY_CHARSET_BIN_MB_MAXLEN); } + else + set_zero_time(&tm); + param->set_time(&tm, MYSQL_TIMESTAMP_DATE, + MAX_DATE_WIDTH * MY_CHARSET_BIN_MB_MAXLEN); *pos+= length; } diff --git a/tests/client_test.c b/tests/client_test.c index e71c4244cbb..b124fba3f59 100644 --- a/tests/client_test.c +++ b/tests/client_test.c @@ -10091,6 +10091,78 @@ static void test_bug5126() } +static void test_bug4231() +{ + MYSQL_STMT *stmt; + MYSQL_BIND bind[2]; + MYSQL_TIME tm[2]; + const char *stmt_text; + int rc; + + myheader("test_bug4231"); + + stmt_text= "DROP TABLE IF EXISTS t1"; + rc= mysql_real_query(mysql, stmt_text, strlen(stmt_text)); + myquery(rc); + + stmt_text= "CREATE TABLE t1 (a int)"; + rc= mysql_real_query(mysql, stmt_text, strlen(stmt_text)); + myquery(rc); + + stmt_text= "INSERT INTO t1 VALUES (1)"; + rc= mysql_real_query(mysql, stmt_text, strlen(stmt_text)); + myquery(rc); + + stmt= mysql_stmt_init(mysql); + stmt_text= "SELECT a FROM t1 WHERE ? = ?"; + rc= mysql_stmt_prepare(stmt, stmt_text, strlen(stmt_text)); + check_execute(stmt, rc); + + /* Bind input buffers */ + bzero(bind, sizeof(bind)); + bzero(tm, sizeof(tm)); + + bind[0].buffer_type= MYSQL_TYPE_TIME; + bind[0].buffer= (void*) tm; + bind[1].buffer_type= MYSQL_TYPE_TIME; + bind[1].buffer= (void*) tm+1; + + mysql_stmt_bind_param(stmt, bind); + check_execute(stmt, rc); + + /* + First set server-side params to some non-zero non-equal values: + then we will check that they are not used when client sends + new (zero) times. + */ + tm[0].time_type = MYSQL_TIMESTAMP_DATE; + tm[0].year = 2000; + tm[0].month = 1; + tm[0].day = 1; + tm[1]= tm[0]; + --tm[1].year; /* tm[0] != tm[1] */ + + rc= mysql_stmt_execute(stmt); + check_execute(stmt, rc); + + rc= mysql_stmt_fetch(stmt); + + /* binds are unequal, no rows should be returned */ + DBUG_ASSERT(rc == MYSQL_NO_DATA); + + /* Set one of the dates to zero */ + tm[0].year= tm[0].month= tm[0].day= 0; + tm[1]= tm[1]; + mysql_stmt_execute(stmt); + rc= mysql_stmt_fetch(stmt); + DBUG_ASSERT(rc == 0); + + mysql_stmt_close(stmt); + stmt_text= "DROP TABLE t1"; + rc= mysql_real_query(mysql, stmt_text, strlen(stmt_text)); + myquery(rc); +} + /* Read and parse arguments and MySQL options from my.cnf */ @@ -10389,6 +10461,8 @@ int main(int argc, char **argv) test_bug4030(); /* test conversion string -> time types in libmysql */ test_bug5126(); /* support for mediumint type in libmysql */ + test_bug4231(); /* proper handling of all-zero times and + dates in the server */ /* XXX: PLEASE RUN THIS PROGRAM UNDER VALGRIND AND VERIFY THAT YOUR TEST DOESN'T CONTAIN WARNINGS/ERRORS BEFORE YOU PUSH. |