diff --git a/client/mysqltest.cc b/client/mysqltest.cc index 5d173ccd8c0cf6a85cf644519b1f4a20b07b6cfd..ca9217bf4285f917da9e4400a605a1b232155330 100644 --- a/client/mysqltest.cc +++ b/client/mysqltest.cc @@ -248,10 +248,14 @@ struct st_connection my_bool pending; #ifdef EMBEDDED_LIBRARY + pthread_t tid; const char *cur_query; int cur_query_len; - pthread_mutex_t mutex; - pthread_cond_t cond; + int command, result; + pthread_mutex_t query_mutex; + pthread_cond_t query_cond; + pthread_mutex_t result_mutex; + pthread_cond_t result_cond; int query_done; #endif /*EMBEDDED_LIBRARY*/ }; @@ -703,67 +707,148 @@ void handle_no_error(struct st_command*); #ifdef EMBEDDED_LIBRARY +#define EMB_SEND_QUERY 1 +#define EMB_READ_QUERY_RESULT 2 +#define EMB_END_CONNECTION 3 + /* attributes of the query thread */ pthread_attr_t cn_thd_attrib; + /* - send_one_query executes query in separate thread, which is - necessary in embedded library to run 'send' in proper way. - This implementation doesn't handle errors returned - by mysql_send_query. It's technically possible, though - I don't see where it is needed. + This procedure represents the connection and actually + runs queries when in the EMBEDDED-SERVER mode. + The run_query_normal() just sends request for running + mysql_send_query and mysql_read_query_result() here. */ -pthread_handler_t send_one_query(void *arg) + +pthread_handler_t connection_thread(void *arg) { struct st_connection *cn= (struct st_connection*)arg; mysql_thread_init(); - (void) mysql_send_query(&cn->mysql, cn->cur_query, cn->cur_query_len); + while (cn->command != EMB_END_CONNECTION) + { + if (!cn->command) + { + pthread_mutex_lock(&cn->query_mutex); + while (!cn->command) + pthread_cond_wait(&cn->query_cond, &cn->query_mutex); + pthread_mutex_unlock(&cn->query_mutex); + } + switch (cn->command) + { + case EMB_END_CONNECTION: + goto end_thread; + case EMB_SEND_QUERY: + cn->result= mysql_send_query(&cn->mysql, cn->cur_query, cn->cur_query_len); + break; + case EMB_READ_QUERY_RESULT: + cn->result= mysql_read_query_result(&cn->mysql); + break; + default: + DBUG_ASSERT(0); + } + cn->command= 0; + pthread_mutex_lock(&cn->result_mutex); + cn->query_done= 1; + pthread_cond_signal(&cn->result_cond); + pthread_mutex_unlock(&cn->result_mutex); + } - mysql_thread_end(); - pthread_mutex_lock(&cn->mutex); +end_thread: cn->query_done= 1; - pthread_cond_signal(&cn->cond); - pthread_mutex_unlock(&cn->mutex); + mysql_thread_end(); pthread_exit(0); return 0; } -static int do_send_query(struct st_connection *cn, const char *q, int q_len, - int flags) + +static void wait_query_thread_done(struct st_connection *con) +{ + DBUG_ASSERT(con->tid); + if (!con->query_done) + { + pthread_mutex_lock(&con->result_mutex); + while (!con->query_done) + pthread_cond_wait(&con->result_cond, &con->result_mutex); + pthread_mutex_unlock(&con->result_mutex); + } +} + + +static void signal_connection_thd(struct st_connection *cn, int command) { - pthread_t tid; + DBUG_ASSERT(cn->tid); + cn->query_done= 0; + cn->command= command; + pthread_mutex_lock(&cn->query_mutex); + pthread_cond_signal(&cn->query_cond); + pthread_mutex_unlock(&cn->query_mutex); +} - if (flags & QUERY_REAP_FLAG) - return mysql_send_query(&cn->mysql, q, q_len); - if (pthread_mutex_init(&cn->mutex, NULL) || - pthread_cond_init(&cn->cond, NULL)) - die("Error in the thread library"); +/* + Sometimes we try to execute queries when the connection is closed. + It's done to make sure it was closed completely. + So that if our connection is closed (cn->tid == 0), we just return + the mysql_send_query() result which is an error in this case. +*/ +static int do_send_query(struct st_connection *cn, const char *q, int q_len) +{ + if (!cn->tid) + return mysql_send_query(&cn->mysql, q, q_len); cn->cur_query= q; cn->cur_query_len= q_len; - cn->query_done= 0; - if (pthread_create(&tid, &cn_thd_attrib, send_one_query, (void*)cn)) - die("Cannot start new thread for query"); - + signal_connection_thd(cn, EMB_SEND_QUERY); return 0; } -static void wait_query_thread_end(struct st_connection *con) + +static int do_read_query_result(struct st_connection *cn) { - if (!con->query_done) - { - pthread_mutex_lock(&con->mutex); - while (!con->query_done) - pthread_cond_wait(&con->cond, &con->mutex); - pthread_mutex_unlock(&con->mutex); - } + DBUG_ASSERT(cn->tid); + wait_query_thread_done(cn); + signal_connection_thd(cn, EMB_READ_QUERY_RESULT); + wait_query_thread_done(cn); + + return cn->result; +} + + +static void emb_close_connection(struct st_connection *cn) +{ + if (!cn->tid) + return; + wait_query_thread_done(cn); + signal_connection_thd(cn, EMB_END_CONNECTION); + pthread_join(cn->tid, NULL); + cn->tid= 0; + pthread_mutex_destroy(&cn->query_mutex); + pthread_cond_destroy(&cn->query_cond); + pthread_mutex_destroy(&cn->result_mutex); + pthread_cond_destroy(&cn->result_cond); } + +static void init_connection_thd(struct st_connection *cn) +{ + cn->query_done= 1; + cn->command= 0; + if (pthread_mutex_init(&cn->query_mutex, NULL) || + pthread_cond_init(&cn->query_cond, NULL) || + pthread_mutex_init(&cn->result_mutex, NULL) || + pthread_cond_init(&cn->result_cond, NULL) || + pthread_create(&cn->tid, &cn_thd_attrib, connection_thread, (void*)cn)) + die("Error in the thread library"); +} + + #else /*EMBEDDED_LIBRARY*/ -#define do_send_query(cn,q,q_len,flags) mysql_send_query(&cn->mysql, q, q_len) +#define do_send_query(cn,q,q_len) mysql_send_query(&cn->mysql, q, q_len) +#define do_read_query_result(cn) mysql_read_query_result(&cn->mysql) #endif /*EMBEDDED_LIBRARY*/ @@ -1106,6 +1191,9 @@ void close_connections() DBUG_ENTER("close_connections"); for (--next_con; next_con >= connections; --next_con) { +#ifdef EMBEDDED_LIBRARY + emb_close_connection(next_con); +#endif if (next_con->stmt) mysql_stmt_close(next_con->stmt); next_con->stmt= 0; @@ -4866,7 +4954,7 @@ void do_close_connection(struct st_command *command) we need to check if the query's thread was finished and probably wait (embedded-server specific) */ - wait_query_thread_end(con); + emb_close_connection(con); #endif /*EMBEDDED_LIBRARY*/ if (con->stmt) mysql_stmt_close(con->stmt); @@ -5216,8 +5304,9 @@ void do_connect(struct st_command *command) } #ifdef EMBEDDED_LIBRARY - con_slot->query_done= 1; -#endif + init_connection_thd(con_slot); +#endif /*EMBEDDED_LIBRARY*/ + if (!mysql_init(&con_slot->mysql)) die("Failed on mysql_init()"); @@ -6768,21 +6857,13 @@ void run_query_normal(struct st_connection *cn, struct st_command *command, /* Send the query */ - if (do_send_query(cn, query, query_len, flags)) + if (do_send_query(cn, query, query_len)) { handle_error(command, mysql_errno(mysql), mysql_error(mysql), mysql_sqlstate(mysql), ds); goto end; } } -#ifdef EMBEDDED_LIBRARY - /* - Here we handle 'reap' command, so we need to check if the - query's thread was finished and probably wait - */ - else if (flags & QUERY_REAP_FLAG) - wait_query_thread_end(cn); -#endif /*EMBEDDED_LIBRARY*/ if (!(flags & QUERY_REAP_FLAG)) { cn->pending= TRUE; @@ -6795,7 +6876,7 @@ void run_query_normal(struct st_connection *cn, struct st_command *command, When on first result set, call mysql_read_query_result to retrieve answer to the query sent earlier */ - if ((counter==0) && mysql_read_query_result(mysql)) + if ((counter==0) && do_read_query_result(cn)) { handle_error(command, mysql_errno(mysql), mysql_error(mysql), mysql_sqlstate(mysql), ds); @@ -7970,6 +8051,9 @@ int main(int argc, char **argv) ps_protocol_enabled= 1; st_connection *con= connections; +#ifdef EMBEDDED_LIBRARY + init_connection_thd(con); +#endif /*EMBEDDED_LIBRARY*/ if (!( mysql_init(&con->mysql))) die("Failed in mysql_init()"); if (opt_connect_timeout) diff --git a/cmake/dtrace.cmake b/cmake/dtrace.cmake index d5566d039133ad3e90ddb04b679a101fde0deaf6..c12a74cba31e265a3a6cf1d6f306008770fc2eeb 100644 --- a/cmake/dtrace.cmake +++ b/cmake/dtrace.cmake @@ -13,13 +13,30 @@ # along with this program; if not, write to the Free Software # Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +IF(CMAKE_SYSTEM_NAME MATCHES "SunOS" AND CMAKE_COMPILER_IS_GNUCXX + AND CMAKE_SIZEOF_VOID_P EQUAL 4) + IF(NOT DEFINED BUGGY_GCC_NO_DTRACE_MODULES) + EXECUTE_PROCESS( + COMMAND ${CMAKE_C_COMPILER} ${CMAKE_C_COMPILER_ARG1} --version + OUTPUT_VARIABLE out) + IF(out MATCHES "3.4.6") + # This gcc causes crashes in dlopen() for dtraced shared libs, + # while standard shipped with Solaris10 3.4.3 is ok + SET(BUGGY_GCC_NO_DTRACE_MODULES 1 CACHE INTERNAL "") + ELSE() + SET(BUGGY_GCC_NO_DTRACE_MODULES 0 CACHE INTERNAL "") + ENDIF() + ENDIF() +ENDIF() + # Check if OS supports DTrace MACRO(CHECK_DTRACE) FIND_PROGRAM(DTRACE dtrace) MARK_AS_ADVANCED(DTRACE) # On FreeBSD, dtrace does not handle userland tracing yet - IF(DTRACE AND NOT CMAKE_SYSTEM_NAME MATCHES "FreeBSD") + IF(DTRACE AND NOT CMAKE_SYSTEM_NAME MATCHES "FreeBSD" + AND NOT BUGGY_GCC_NO_DTRACE_MODULES) SET(ENABLE_DTRACE ON CACHE BOOL "Enable dtrace") ENDIF() SET(HAVE_DTRACE ${ENABLE_DTRACE}) @@ -72,22 +89,6 @@ IF(ENABLE_DTRACE) ) ENDIF() -IF(CMAKE_SYSTEM_NAME MATCHES "SunOS" AND CMAKE_COMPILER_IS_GNUCXX - AND CMAKE_SIZEOF_VOID_P EQUAL 4) - IF(NOT DEFINED BUGGY_GCC_NO_DTRACE_MODULES) - EXECUTE_PROCESS( - COMMAND ${CMAKE_C_COMPILER} ${CMAKE_C_COMPILER_ARG1} --version - OUTPUT_VARIABLE out) - IF(out MATCHES "3.4.6") - # This gcc causes crashes in dlopen() for dtraced shared libs, - # while standard shipped with Solaris10 3.4.3 is ok - SET(BUGGY_GCC_NO_DTRACE_MODULES 1 CACHE INTERNAL "") - ELSE() - SET(BUGGY_GCC_NO_DTRACE_MODULES 0 CACHE INTERNAL "") - ENDIF() - ENDIF() -ENDIF() - FUNCTION(DTRACE_INSTRUMENT target) IF(BUGGY_GCC_NO_DTRACE_MODULES) GET_TARGET_PROPERTY(target_type ${target} TYPE) diff --git a/libmysqld/lib_sql.cc b/libmysqld/lib_sql.cc index 94927c590cf8861980bb03babf493ac2a6101174..7d61dbc55f4561b113f18f8f6d635304d2467459 100644 --- a/libmysqld/lib_sql.cc +++ b/libmysqld/lib_sql.cc @@ -481,6 +481,10 @@ int init_embedded_server(int argc, char **argv, char **groups) char *fake_argv[] = { (char *)"", 0 }; const char *fake_groups[] = { "server", "embedded", 0 }; my_bool acl_error; + + if (my_thread_init()) + return 1; + if (argc) { argcp= &argc; diff --git a/mysql-test/r/func_time.result b/mysql-test/r/func_time.result index 9ba1ae489caeab4e7c947a250c2999e261bc0ed1..f2c26110d8a4ff4774f56a65bc17b99a7b42398e 100644 --- a/mysql-test/r/func_time.result +++ b/mysql-test/r/func_time.result @@ -1200,6 +1200,8 @@ set time_zone= @@global.time_zone; select str_to_date('10:00 PM', '%h:%i %p') + INTERVAL 10 MINUTE; str_to_date('10:00 PM', '%h:%i %p') + INTERVAL 10 MINUTE NULL +Warnings: +Warning 1411 Incorrect datetime value: '10:00 PM' for function str_to_date create table t1 (field DATE); insert into t1 values ('2006-11-06'); select * from t1 where field < '2006-11-06 04:08:36.0'; diff --git a/mysql-test/r/parser.result b/mysql-test/r/parser.result index 467bb7c5cb83469f89affcd71f4751d4f0890bf1..1ea9e91df8a7da021bc9416988c91dab33d8e410 100644 --- a/mysql-test/r/parser.result +++ b/mysql-test/r/parser.result @@ -556,9 +556,13 @@ DROP TABLE IF EXISTS t1; SELECT STR_TO_DATE('10:00 PM', '%h:%i %p') + INTERVAL 10 MINUTE; STR_TO_DATE('10:00 PM', '%h:%i %p') + INTERVAL 10 MINUTE NULL +Warnings: +Warning 1411 Incorrect datetime value: '10:00 PM' for function str_to_date SELECT STR_TO_DATE('10:00 PM', '%h:%i %p') + INTERVAL (INTERVAL(1,2,3) + 1) MINUTE; STR_TO_DATE('10:00 PM', '%h:%i %p') + INTERVAL (INTERVAL(1,2,3) + 1) MINUTE NULL +Warnings: +Warning 1411 Incorrect datetime value: '10:00 PM' for function str_to_date SELECT "1997-12-31 23:59:59" + INTERVAL 1 SECOND; "1997-12-31 23:59:59" + INTERVAL 1 SECOND 1998-01-01 00:00:00 diff --git a/mysql-test/r/select.result b/mysql-test/r/select.result index e8628d72a46b0f0433124833549c7e17bb216736..b1e0f30668dc767063465f58ca42574cf3f84a91 100644 --- a/mysql-test/r/select.result +++ b/mysql-test/r/select.result @@ -4171,9 +4171,10 @@ str_to_date('2007-10-00','%Y-%m-%d') between '2007/09/01 00:00:00' set SQL_MODE=TRADITIONAL; select str_to_date('2007-10-00 12:34','%Y-%m-%d %H:%i') = '2007-10-00 12:34'; str_to_date('2007-10-00 12:34','%Y-%m-%d %H:%i') = '2007-10-00 12:34' -0 +NULL Warnings: Warning 1292 Truncated incorrect datetime value: '2007-10-00 12:34' +Warning 1411 Incorrect datetime value: '2007-10-00 12:34' for function str_to_date select str_to_date('2007-10-01 12:34','%Y-%m-%d %H:%i') = '2007-10-00 12:34'; str_to_date('2007-10-01 12:34','%Y-%m-%d %H:%i') = '2007-10-00 12:34' 0 @@ -4181,17 +4182,16 @@ Warnings: Warning 1292 Truncated incorrect datetime value: '2007-10-00 12:34' select str_to_date('2007-10-00 12:34','%Y-%m-%d %H:%i') = '2007-10-01 12:34'; str_to_date('2007-10-00 12:34','%Y-%m-%d %H:%i') = '2007-10-01 12:34' -0 +NULL Warnings: -Warning 1292 Truncated incorrect datetime value: '2007-10-00 12:34:00' +Warning 1411 Incorrect datetime value: '2007-10-00 12:34' for function str_to_date select str_to_date('2007-10-00','%Y-%m-%d') between '2007/09/01' and '2007/10/20'; str_to_date('2007-10-00','%Y-%m-%d') between '2007/09/01' and '2007/10/20' -0 +NULL Warnings: -Warning 1292 Incorrect datetime value: '2007-10-00' for column '2007/09/01' at row 1 -Warning 1292 Incorrect datetime value: '2007-10-00' for column '2007/10/20' at row 1 +Warning 1411 Incorrect datetime value: '2007-10-00' for function str_to_date set SQL_MODE=DEFAULT; select str_to_date('2007-10-00','%Y-%m-%d') between '' and '2007/10/20'; str_to_date('2007-10-00','%Y-%m-%d') between '' and '2007/10/20' diff --git a/mysql-test/r/strict.result b/mysql-test/r/strict.result index 79f8c20a150021c47a804f0f46ce6e50b01a1460..872bfdc48730a748e4a303c2cdd431648ed38caf 100644 --- a/mysql-test/r/strict.result +++ b/mysql-test/r/strict.result @@ -206,12 +206,11 @@ INSERT INTO t1 (col1) VALUES (STR_TO_DATE('15.10.2004','%d.%m.%Y')); INSERT INTO t1 (col2) VALUES (STR_TO_DATE('15.10.2004 10.15','%d.%m.%Y %H.%i')); INSERT INTO t1 (col3) VALUES (STR_TO_DATE('15.10.2004 10.15','%d.%m.%Y %H.%i')); INSERT INTO t1 (col1) VALUES(STR_TO_DATE('31.10.0000 15.30','%d.%m.%Y %H.%i')); -Warnings: -Note 1265 Data truncated for column 'col1' at row 1 +ERROR HY000: Incorrect datetime value: '31.10.0000 15.30' for function str_to_date INSERT INTO t1 (col1) VALUES(STR_TO_DATE('31.0.2004 15.30','%d.%m.%Y %H.%i')); -ERROR 22007: Incorrect date value: '2004-00-31 15:30:00' for column 'col1' at row 1 +ERROR HY000: Incorrect datetime value: '31.0.2004 15.30' for function str_to_date INSERT INTO t1 (col1) VALUES(STR_TO_DATE('0.10.2004 15.30','%d.%m.%Y %H.%i')); -ERROR 22007: Incorrect date value: '2004-10-00 15:30:00' for column 'col1' at row 1 +ERROR HY000: Incorrect datetime value: '0.10.2004 15.30' for function str_to_date INSERT INTO t1 (col1) VALUES(STR_TO_DATE('31.9.2004 15.30','%d.%m.%Y %H.%i')); ERROR 22007: Incorrect date value: '2004-09-31 15:30:00' for column 'col1' at row 1 INSERT INTO t1 (col1) VALUES(STR_TO_DATE('32.10.2004 15.30','%d.%m.%Y %H.%i')); @@ -221,12 +220,13 @@ ERROR 22007: Incorrect date value: '2003-02-29 15:30:00' for column 'col1' at ro INSERT INTO t1 (col1) VALUES(STR_TO_DATE('15.13.2004 15.30','%d.%m.%Y %H.%i')); ERROR HY000: Incorrect datetime value: '15.13.2004 15.30' for function str_to_date INSERT INTO t1 (col1) VALUES(STR_TO_DATE('00.00.0000','%d.%m.%Y')); -ERROR 22007: Incorrect date value: '0000-00-00' for column 'col1' at row 1 +ERROR HY000: Incorrect datetime value: '00.00.0000' for function str_to_date INSERT INTO t1 (col2) VALUES(STR_TO_DATE('31.10.0000 15.30','%d.%m.%Y %H.%i')); +ERROR HY000: Incorrect datetime value: '31.10.0000 15.30' for function str_to_date INSERT INTO t1 (col2) VALUES(STR_TO_DATE('31.0.2004 15.30','%d.%m.%Y %H.%i')); -ERROR 22007: Incorrect datetime value: '2004-00-31 15:30:00' for column 'col2' at row 1 +ERROR HY000: Incorrect datetime value: '31.0.2004 15.30' for function str_to_date INSERT INTO t1 (col2) VALUES(STR_TO_DATE('0.10.2004 15.30','%d.%m.%Y %H.%i')); -ERROR 22007: Incorrect datetime value: '2004-10-00 15:30:00' for column 'col2' at row 1 +ERROR HY000: Incorrect datetime value: '0.10.2004 15.30' for function str_to_date INSERT INTO t1 (col2) VALUES(STR_TO_DATE('31.9.2004 15.30','%d.%m.%Y %H.%i')); ERROR 22007: Incorrect datetime value: '2004-09-31 15:30:00' for column 'col2' at row 1 INSERT INTO t1 (col2) VALUES(STR_TO_DATE('32.10.2004 15.30','%d.%m.%Y %H.%i')); @@ -236,13 +236,13 @@ ERROR 22007: Incorrect datetime value: '2003-02-29 15:30:00' for column 'col2' a INSERT INTO t1 (col2) VALUES(STR_TO_DATE('15.13.2004 15.30','%d.%m.%Y %H.%i')); ERROR HY000: Incorrect datetime value: '15.13.2004 15.30' for function str_to_date INSERT INTO t1 (col2) VALUES(STR_TO_DATE('00.00.0000','%d.%m.%Y')); -ERROR 22007: Incorrect datetime value: '0000-00-00' for column 'col2' at row 1 +ERROR HY000: Incorrect datetime value: '00.00.0000' for function str_to_date INSERT INTO t1 (col3) VALUES(STR_TO_DATE('31.10.0000 15.30','%d.%m.%Y %H.%i')); -ERROR 22007: Incorrect datetime value: '0000-10-31 15:30:00' for column 'col3' at row 1 +ERROR HY000: Incorrect datetime value: '31.10.0000 15.30' for function str_to_date INSERT INTO t1 (col3) VALUES(STR_TO_DATE('31.0.2004 15.30','%d.%m.%Y %H.%i')); -ERROR 22007: Incorrect datetime value: '2004-00-31 15:30:00' for column 'col3' at row 1 +ERROR HY000: Incorrect datetime value: '31.0.2004 15.30' for function str_to_date INSERT INTO t1 (col3) VALUES(STR_TO_DATE('0.10.2004 15.30','%d.%m.%Y %H.%i')); -ERROR 22007: Incorrect datetime value: '2004-10-00 15:30:00' for column 'col3' at row 1 +ERROR HY000: Incorrect datetime value: '0.10.2004 15.30' for function str_to_date INSERT INTO t1 (col3) VALUES(STR_TO_DATE('31.9.2004 15.30','%d.%m.%Y %H.%i')); ERROR 22007: Incorrect datetime value: '2004-09-31 15:30:00' for column 'col3' at row 1 INSERT INTO t1 (col3) VALUES(STR_TO_DATE('32.10.2004 15.30','%d.%m.%Y %H.%i')); @@ -252,7 +252,7 @@ ERROR 22007: Incorrect datetime value: '2003-02-29 15:30:00' for column 'col3' a INSERT INTO t1 (col3) VALUES(STR_TO_DATE('15.13.2004 15.30','%d.%m.%Y %H.%i')); ERROR HY000: Incorrect datetime value: '15.13.2004 15.30' for function str_to_date INSERT INTO t1 (col3) VALUES(STR_TO_DATE('00.00.0000','%d.%m.%Y')); -ERROR 22007: Incorrect datetime value: '0000-00-00' for column 'col3' at row 1 +ERROR HY000: Incorrect datetime value: '00.00.0000' for function str_to_date drop table t1; CREATE TABLE t1 (col1 date, col2 datetime, col3 timestamp); INSERT INTO t1 (col1) VALUES (CAST('2004-10-15' AS DATE)); @@ -1108,6 +1108,9 @@ Warnings: Warning 1411 Incorrect datetime value: '2004.12.12 10:22:61' for function str_to_date Warning 1411 Incorrect datetime value: '2004.12.12 10:22:61' for function str_to_date Warning 1411 Incorrect datetime value: '2004.12.12 10:22:61' for function str_to_date +Warning 1411 Incorrect datetime value: '2004.12.12 10:22:61' for function str_to_date +Warning 1411 Incorrect datetime value: '2004.12.12 10:22:61' for function str_to_date +Warning 1411 Incorrect datetime value: '2004.12.12 10:22:61' for function str_to_date drop table t1; create table t1 (col1 char(3), col2 integer); insert into t1 (col1) values (cast(1000 as char(3))); diff --git a/mysql-test/r/type_datetime.result b/mysql-test/r/type_datetime.result index a054659abe94975a86277a5819563babd1a85bbe..f7bfba0accd5adb6098a2c2ce188d1f9ae387d88 100644 --- a/mysql-test/r/type_datetime.result +++ b/mysql-test/r/type_datetime.result @@ -655,5 +655,30 @@ Note 1003 select `test`.`t1`.`Id` AS `Id`,`test`.`t1`.`AtTime` AS `AtTime` from DROP TABLE t1; SET NAMES latin1; # +# Bug#56271: Wrong comparison result with STR_TO_DATE function +# +CREATE TABLE t1 ( +`year` int(4) NOT NULL, +`month` int(2) NOT NULL +); +INSERT INTO t1 VALUES (2010,3),(2010,4),(2009,8),(2008,9); +SELECT * +FROM t1 +WHERE STR_TO_DATE(CONCAT_WS('/01/',`month`,`year`), '%m/%d/%Y') >= +STR_TO_DATE('1/1/2010', '%m/%d/%Y'); +year month +2010 3 +2010 4 +create table t2(f1 datetime primary key); +insert into t2 select STR_TO_DATE(CONCAT_WS('/01/',`month`,`year`), '%m/%d/%Y') from t1; +select * from t2 where f1=STR_TO_DATE('4/1/2010', '%m/%d/%Y'); +f1 +2010-04-01 00:00:00 +t2 should be const +explain select * from t2 where f1=STR_TO_DATE('4/1/2010', '%m/%d/%Y'); +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t2 const PRIMARY PRIMARY 8 const 1 Using index +DROP TABLE t1,t2; +# # End of 5.5 tests # diff --git a/mysql-test/suite/rpl/t/disabled.def b/mysql-test/suite/rpl/t/disabled.def index f864139495ab66e33bf73ebdd3a08ff7a6873c90..2ed7e087667cdb348edb94c0f7735afe71b15274 100644 --- a/mysql-test/suite/rpl/t/disabled.def +++ b/mysql-test/suite/rpl/t/disabled.def @@ -11,7 +11,6 @@ ############################################################################## rpl_failed_optimize : WL#4284: Can't optimize table used by a pending transaction (there is metadata lock on the table). -rpl_plugin_load : Bug#55966 2010-08-13 alik "plugin" tests fail in 5.5 rpl_read_only : WL#4284: Setting Read only won't succeed until all metadata locks are released. rpl_row_create_table : Bug#51574 2010-02-27 andrei failed different way than earlier with bug#45576 rpl_spec_variables : BUG#47661 2009-10-27 jasonh rpl_spec_variables fails on PB2 hpux diff --git a/mysql-test/t/disabled.def b/mysql-test/t/disabled.def index 1684201603721c720c0767b229f155acd8203c21..d35d612f93c09e046fef3799bc8a7135c711ef96 100644 --- a/mysql-test/t/disabled.def +++ b/mysql-test/t/disabled.def @@ -14,9 +14,6 @@ lowercase_table3 : Bug#54845 2010-06-30 alik main.lowercase_table3 on Ma mysqlhotcopy_myisam : Bug#54129 2010-08-31 alik mysqlhotcopy* fails mysqlhotcopy_archive : Bug#54129 2010-08-31 alik mysqlhotcopy* fails partition_innodb_plugin : Bug#53307 2010-04-30 VasilDimov valgrind warnings -plugin : Bug#55966 2010-08-13 alik "plugin" tests fail in 5.5 -plugin_load : Bug#55966 2010-08-13 alik "plugin" tests fail in 5.5 -plugin_not_embedded : Bug#55966 2010-08-13 alik "plugin" tests fail in 5.5 query_cache_28249 : Bug#43861 2009-03-25 main.query_cache_28249 fails sporadically sp_sync : Bug#48157 2010-02-06 5.5-m3 demands a differnt solution ctype_utf8mb4_ndb : Bug#55799, Bug#51907, disabled by Konstantin 2010-08-06 diff --git a/mysql-test/t/strict.test b/mysql-test/t/strict.test index 0dd324d5df2a8ec94867336515f80a8642733018..fc522a69a3c9512e5343d23001b0c7574378a266 100644 --- a/mysql-test/t/strict.test +++ b/mysql-test/t/strict.test @@ -192,11 +192,11 @@ INSERT INTO t1 (col3) VALUES (STR_TO_DATE('15.10.2004 10.15','%d.%m.%Y %H.%i')); # All test cases expected to fail should return # SQLSTATE 22007 <invalid date value> +--error 1411 INSERT INTO t1 (col1) VALUES(STR_TO_DATE('31.10.0000 15.30','%d.%m.%Y %H.%i')); - ---error 1292 +--error 1411 INSERT INTO t1 (col1) VALUES(STR_TO_DATE('31.0.2004 15.30','%d.%m.%Y %H.%i')); ---error 1292 +--error 1411 INSERT INTO t1 (col1) VALUES(STR_TO_DATE('0.10.2004 15.30','%d.%m.%Y %H.%i')); --error 1292 INSERT INTO t1 (col1) VALUES(STR_TO_DATE('31.9.2004 15.30','%d.%m.%Y %H.%i')); @@ -206,18 +206,18 @@ INSERT INTO t1 (col1) VALUES(STR_TO_DATE('32.10.2004 15.30','%d.%m.%Y %H.%i')); INSERT INTO t1 (col1) VALUES(STR_TO_DATE('29.02.2003 15.30','%d.%m.%Y %H.%i')); --error 1411 INSERT INTO t1 (col1) VALUES(STR_TO_DATE('15.13.2004 15.30','%d.%m.%Y %H.%i')); ---error 1292 +--error 1411 INSERT INTO t1 (col1) VALUES(STR_TO_DATE('00.00.0000','%d.%m.%Y')); ## Test INSERT with STR_TO_DATE into DATETIME # All test cases expected to fail should return # SQLSTATE 22007 <invalid datetime value> +--error 1411 INSERT INTO t1 (col2) VALUES(STR_TO_DATE('31.10.0000 15.30','%d.%m.%Y %H.%i')); - ---error 1292 +--error 1411 INSERT INTO t1 (col2) VALUES(STR_TO_DATE('31.0.2004 15.30','%d.%m.%Y %H.%i')); ---error 1292 +--error 1411 INSERT INTO t1 (col2) VALUES(STR_TO_DATE('0.10.2004 15.30','%d.%m.%Y %H.%i')); --error 1292 INSERT INTO t1 (col2) VALUES(STR_TO_DATE('31.9.2004 15.30','%d.%m.%Y %H.%i')); @@ -227,18 +227,18 @@ INSERT INTO t1 (col2) VALUES(STR_TO_DATE('32.10.2004 15.30','%d.%m.%Y %H.%i')); INSERT INTO t1 (col2) VALUES(STR_TO_DATE('29.02.2003 15.30','%d.%m.%Y %H.%i')); --error 1411 INSERT INTO t1 (col2) VALUES(STR_TO_DATE('15.13.2004 15.30','%d.%m.%Y %H.%i')); ---error 1292 +--error 1411 INSERT INTO t1 (col2) VALUES(STR_TO_DATE('00.00.0000','%d.%m.%Y')); ## Test INSERT with STR_TO_DATE into TIMESTAMP # All test cases expected to fail should return # SQLSTATE 22007 <invalid datetime value> ---error 1292 +--error 1411 INSERT INTO t1 (col3) VALUES(STR_TO_DATE('31.10.0000 15.30','%d.%m.%Y %H.%i')); ---error 1292 +--error 1411 INSERT INTO t1 (col3) VALUES(STR_TO_DATE('31.0.2004 15.30','%d.%m.%Y %H.%i')); ---error 1292 +--error 1411 INSERT INTO t1 (col3) VALUES(STR_TO_DATE('0.10.2004 15.30','%d.%m.%Y %H.%i')); --error 1292 INSERT INTO t1 (col3) VALUES(STR_TO_DATE('31.9.2004 15.30','%d.%m.%Y %H.%i')); @@ -248,7 +248,7 @@ INSERT INTO t1 (col3) VALUES(STR_TO_DATE('32.10.2004 15.30','%d.%m.%Y %H.%i')); INSERT INTO t1 (col3) VALUES(STR_TO_DATE('29.02.2003 15.30','%d.%m.%Y %H.%i')); --error 1411 INSERT INTO t1 (col3) VALUES(STR_TO_DATE('15.13.2004 15.30','%d.%m.%Y %H.%i')); ---error 1292 +--error 1411 INSERT INTO t1 (col3) VALUES(STR_TO_DATE('00.00.0000','%d.%m.%Y')); drop table t1; diff --git a/mysql-test/t/type_datetime.test b/mysql-test/t/type_datetime.test index e607823764bb14ef7dfd75ff3ade32b260e84602..6e40c9ccfa0aea9e4cfb722953644f04dd647e59 100644 --- a/mysql-test/t/type_datetime.test +++ b/mysql-test/t/type_datetime.test @@ -461,6 +461,29 @@ EXPLAIN EXTENDED SELECT * FROM t1 FORCE INDEX(attime) WHERE AtTime = '2010-02-22 DROP TABLE t1; SET NAMES latin1; +--echo # +--echo # Bug#56271: Wrong comparison result with STR_TO_DATE function +--echo # +CREATE TABLE t1 ( + `year` int(4) NOT NULL, + `month` int(2) NOT NULL +); + +INSERT INTO t1 VALUES (2010,3),(2010,4),(2009,8),(2008,9); + +SELECT * +FROM t1 +WHERE STR_TO_DATE(CONCAT_WS('/01/',`month`,`year`), '%m/%d/%Y') >= +STR_TO_DATE('1/1/2010', '%m/%d/%Y'); + +create table t2(f1 datetime primary key); +insert into t2 select STR_TO_DATE(CONCAT_WS('/01/',`month`,`year`), '%m/%d/%Y') from t1; +select * from t2 where f1=STR_TO_DATE('4/1/2010', '%m/%d/%Y'); +--echo t2 should be const +explain select * from t2 where f1=STR_TO_DATE('4/1/2010', '%m/%d/%Y'); + +DROP TABLE t1,t2; + --echo # --echo # End of 5.5 tests --echo # diff --git a/mysys/my_gethwaddr.c b/mysys/my_gethwaddr.c index 9ca22f2201e78d8d0e1482c0c08dd0b382e4c32d..d14087d061ecb9b9be8b6c67ab0f3b0e284e8c59 100644 --- a/mysys/my_gethwaddr.c +++ b/mysys/my_gethwaddr.c @@ -64,7 +64,7 @@ my_bool my_gethwaddr(uchar *to) if (ifm->ifm_type == RTM_IFINFO) { sdl = (struct sockaddr_dl *)(ifm + 1); - addr=LLADDR(sdl); + addr=(uchar *)LLADDR(sdl); res=memcpy_and_test(to, addr, ETHER_ADDR_LEN); } } diff --git a/mysys/my_sync.c b/mysys/my_sync.c index 6497ae59159e4ff5b6ae094ef8ce5110cb119a60..bc050922ffcfb42c29f4367bfd54c3302573cb31 100644 --- a/mysys/my_sync.c +++ b/mysys/my_sync.c @@ -100,9 +100,9 @@ static const char cur_dir_name[]= {FN_CURLIB, 0}; RETURN 0 if ok, !=0 if error */ +#ifdef NEED_EXPLICIT_SYNC_DIR int my_sync_dir(const char *dir_name, myf my_flags) { -#ifdef NEED_EXPLICIT_SYNC_DIR File dir_fd; int res= 0; const char *correct_dir_name; @@ -124,10 +124,14 @@ int my_sync_dir(const char *dir_name, myf my_flags) else res= 1; DBUG_RETURN(res); -#else +} +#else /* NEED_EXPLICIT_SYNC_DIR */ +int my_sync_dir(const char *dir_name __attribute__((unused)), + myf my_flags __attribute__((unused))) +{ return 0; -#endif } +#endif /* NEED_EXPLICIT_SYNC_DIR */ /* @@ -141,15 +145,18 @@ int my_sync_dir(const char *dir_name, myf my_flags) RETURN 0 if ok, !=0 if error */ +#ifdef NEED_EXPLICIT_SYNC_DIR int my_sync_dir_by_file(const char *file_name, myf my_flags) { -#ifdef NEED_EXPLICIT_SYNC_DIR char dir_name[FN_REFLEN]; size_t dir_name_length; dirname_part(dir_name, file_name, &dir_name_length); return my_sync_dir(dir_name, my_flags); -#else +} +#else /* NEED_EXPLICIT_SYNC_DIR */ +int my_sync_dir_by_file(const char *file_name __attribute__((unused)), + myf my_flags __attribute__((unused))) +{ return 0; -#endif } - +#endif /* NEED_EXPLICIT_SYNC_DIR */ diff --git a/sql/derror.cc b/sql/derror.cc index bf8c589a65faa587bde796403dcd0dbbdeb7a994..db9cd3c0c58b6f0c056b25b421e1b696e0fd46df 100644 --- a/sql/derror.cc +++ b/sql/derror.cc @@ -35,6 +35,8 @@ static void init_myfunc_errs(void); C_MODE_START static const char **get_server_errmsgs() { + if (!current_thd) + return DEFAULT_ERRMSGS; return CURRENT_THD_ERRMSGS; } C_MODE_END diff --git a/sql/item_timefunc.cc b/sql/item_timefunc.cc index 1c2c1cfe5120b537774172f3c4dc794e50aef7b0..cc363398fdde7697f4e9ce48dc1cff7db6716e8e 100644 --- a/sql/item_timefunc.cc +++ b/sql/item_timefunc.cc @@ -3368,6 +3368,8 @@ void Item_func_str_to_date::fix_length_and_dec() cached_field_type= MYSQL_TYPE_DATETIME; max_length= MAX_DATETIME_FULL_WIDTH*MY_CHARSET_BIN_MB_MAXLEN; cached_timestamp_type= MYSQL_TIMESTAMP_NONE; + sql_mode= (current_thd->variables.sql_mode & + (MODE_NO_ZERO_IN_DATE | MODE_NO_ZERO_DATE)); if ((const_item= args[1]->const_item())) { char format_buff[64]; @@ -3433,6 +3435,14 @@ bool Item_func_str_to_date::get_date(MYSQL_TIME *ltime, uint fuzzy_date) return 0; null_date: + if (fuzzy_date & TIME_NO_ZERO_DATE) + { + char buff[128]; + strmake(buff, val->ptr(), min(val->length(), sizeof(buff)-1)); + push_warning_printf(current_thd, MYSQL_ERROR::WARN_LEVEL_WARN, + ER_WRONG_VALUE_FOR_TYPE, ER(ER_WRONG_VALUE_FOR_TYPE), + "datetime", buff, "str_to_date"); + } return (null_value=1); } @@ -3442,7 +3452,7 @@ String *Item_func_str_to_date::val_str(String *str) DBUG_ASSERT(fixed == 1); MYSQL_TIME ltime; - if (Item_func_str_to_date::get_date(<ime, TIME_FUZZY_DATE)) + if (Item_func_str_to_date::get_date(<ime, TIME_FUZZY_DATE | sql_mode)) return 0; if (!make_datetime((const_item ? cached_format_type : @@ -3453,6 +3463,29 @@ String *Item_func_str_to_date::val_str(String *str) } +longlong Item_func_str_to_date::val_int() +{ + DBUG_ASSERT(fixed == 1); + MYSQL_TIME ltime; + + if (Item_func_str_to_date::get_date(<ime, TIME_FUZZY_DATE | sql_mode)) + return 0; + + if (const_item) + { + switch (cached_field_type) { + case MYSQL_TYPE_DATE: + return TIME_to_ulonglong_date(<ime); + case MYSQL_TYPE_TIME: + return TIME_to_ulonglong_time(<ime); + default: + return TIME_to_ulonglong_datetime(<ime); + } + } + return TIME_to_ulonglong_datetime(<ime); +} + + bool Item_func_last_day::get_date(MYSQL_TIME *ltime, uint fuzzy_date) { if (get_arg0_date(ltime, fuzzy_date & ~TIME_FUZZY_DATE) || diff --git a/sql/item_timefunc.h b/sql/item_timefunc.h index 2c08853fda4dd36c8d77468d24f22af2291ff53e..6e31b5c6705449bbb2fdd53ecb86d91ee3b481a2 100644 --- a/sql/item_timefunc.h +++ b/sql/item_timefunc.h @@ -1039,6 +1039,7 @@ class Item_func_str_to_date :public Item_str_func date_time_format_types cached_format_type; timestamp_type cached_timestamp_type; bool const_item; + ulonglong sql_mode; public: Item_func_str_to_date(Item *a, Item *b) :Item_str_func(a, b), const_item(false) @@ -1052,6 +1053,8 @@ public: { return tmp_table_field_from_field_type(table, 1); } + longlong val_int(); + bool result_as_longlong() { return TRUE; } }; diff --git a/sql/mysqld.cc b/sql/mysqld.cc index 6dd74eb299ae2f1f7c219cdcece479c241e034bd..840616e0e7c8dec871980ac435bfa4d24e5cba02 100644 --- a/sql/mysqld.cc +++ b/sql/mysqld.cc @@ -1486,6 +1486,7 @@ void clean_up(bool print_message) cleanup_errmsgs(); MYSQL_CALLBACK(thread_scheduler, end, ()); finish_client_errs(); + (void) my_error_unregister(ER_ERROR_FIRST, ER_ERROR_LAST); // finish server errs DBUG_PRINT("quit", ("Error messages freed")); /* Tell main we are ready */ logger.cleanup_end(); diff --git a/sql/set_var.cc b/sql/set_var.cc index 501c638205601afb2cc73c92c0a0986ba08b7fbe..34b66dea31908afabfa9ba6f339f93f9dd5373db 100644 --- a/sql/set_var.cc +++ b/sql/set_var.cc @@ -108,7 +108,7 @@ void sys_var_end() my_hash_free(&system_variable_hash); for (sys_var *var=all_sys_vars.first; var; var= var->next) - var->~sys_var(); + var->cleanup(); DBUG_VOID_RETURN; } diff --git a/sql/set_var.h b/sql/set_var.h index 5f1f889c4ce17870e89536fe1ba7a029063ea631..2972b430e484c98a4492e0729605051d9a27100e 100644 --- a/sql/set_var.h +++ b/sql/set_var.h @@ -91,11 +91,13 @@ public: longlong def_val, PolyLock *lock, enum binlog_status_enum binlog_status_arg, on_check_function on_check_func, on_update_function on_update_func, uint deprecated_version, const char *substitute, int parse_flag); + + virtual ~sys_var() {} + /** - The instance should only be destroyed on shutdown, as it doesn't unlink - itself from the chain. + All the cleanup procedures should be performed here */ - virtual ~sys_var() {} + virtual void cleanup() {} /** downcast for sys_var_pluginvar. Returns this if it's an instance of sys_var_pluginvar, and 0 otherwise. diff --git a/sql/sys_vars.h b/sql/sys_vars.h index ee6b429b04a608df80cbcb0eb18e4cd859093517..740c4f03e3e15f8c3650da8c2fe2d72187c27556 100644 --- a/sql/sys_vars.h +++ b/sql/sys_vars.h @@ -385,7 +385,7 @@ public: DBUG_ASSERT(scope() == GLOBAL); DBUG_ASSERT(size == sizeof(char *)); } - ~Sys_var_charptr() + void cleanup() { if (flags & ALLOCATED) my_free(global_var(char*));