diff --git a/BUILD/SETUP.sh b/BUILD/SETUP.sh index c7f434d1bb3..00bd4965f87 100755 --- a/BUILD/SETUP.sh +++ b/BUILD/SETUP.sh @@ -1,6 +1,6 @@ #!/bin/sh -# Copyright (C) 2000, 2007 MySQL AB +# Copyright (c) 2000, 2011, Oracle and/or its affiliates. All rights reserved. # # This program is free software; you can redistribute it and/or # modify it under the terms of the GNU Library General Public @@ -250,7 +250,7 @@ gcov_compile_flags="$gcov_compile_flags -DMYSQL_SERVER_SUFFIX=-gcov -DHAVE_gcov" gcov_link_flags="-fprofile-arcs -ftest-coverage" -gcov_configs="--disable-shared" +gcov_configs="--with-gcov" # gprof diff --git a/cmake/configure.pl b/cmake/configure.pl index b24afa034c7..bf872264953 100644 --- a/cmake/configure.pl +++ b/cmake/configure.pl @@ -190,6 +190,11 @@ foreach my $option (@ARGV) $cmakeargs = $cmakeargs." \"-DWITH_COMMENT=".substr($option,13)."\""; next; } + if ($option =~ /with-gcov/) + { + $cmakeargs = $cmakeargs." -DENABLE_GCOV=ON"; + next; + } $option = uc($option); $option =~ s/-/_/g; diff --git a/cmake/os/WindowsCache.cmake b/cmake/os/WindowsCache.cmake index 477fd1d2b88..68bbb337e15 100644 --- a/cmake/os/WindowsCache.cmake +++ b/cmake/os/WindowsCache.cmake @@ -341,6 +341,7 @@ SET(SIGNAL_RETURN_TYPE_IS_VOID 1 CACHE INTERNAL "") SET(C_HAS_inline CACHE INTERNAL "") SET(C_HAS___inline 1 CACHE INTERNAL "") SET(FIONREAD_IN_SYS_IOCTL CACHE INTERNAL "") +SET(FIONREAD_IN_SYS_FILIO CACHE INTERNAL "") SET(GWINSZ_IN_SYS_IOCTL CACHE INTERNAL "") SET(HAVE_CXXABI_H CACHE INTERNAL "") SET(HAVE_NDIR_H CACHE INTERNAL "") diff --git a/include/violite.h b/include/violite.h index 140f021ebb4..ba057028ed2 100644 --- a/include/violite.h +++ b/include/violite.h @@ -134,13 +134,13 @@ struct st_VioSSLFd SSL_CTX *ssl_context; }; -int sslaccept(struct st_VioSSLFd*, Vio *, long timeout); -int sslconnect(struct st_VioSSLFd*, Vio *, long timeout); +int sslaccept(struct st_VioSSLFd*, Vio *, long timeout, unsigned long *errptr); +int sslconnect(struct st_VioSSLFd*, Vio *, long timeout, unsigned long *errptr); struct st_VioSSLFd *new_VioSSLConnectorFd(const char *key_file, const char *cert_file, const char *ca_file, const char *ca_path, - const char *cipher); + const char *cipher, enum enum_ssl_init_error* error); struct st_VioSSLFd *new_VioSSLAcceptorFd(const char *key_file, const char *cert_file, const char *ca_file,const char *ca_path, diff --git a/libmysql/errmsg.c b/libmysql/errmsg.c index b99b3f2de30..a2d066b1eba 100644 --- a/libmysql/errmsg.c +++ b/libmysql/errmsg.c @@ -51,7 +51,7 @@ const char *client_errors[]= "Error on SHOW SLAVE HOSTS:", "Error connecting to slave:", "Error connecting to master:", - "SSL connection error", + "SSL connection error: %-.100s", "Malformed packet", "This client library is licensed only for use with MySQL servers having '%s' license", "Invalid use of null pointer", diff --git a/mysql-test/lib/mtr_cases.pm b/mysql-test/lib/mtr_cases.pm index c3dd43c12ca..d677645d9da 100644 --- a/mysql-test/lib/mtr_cases.pm +++ b/mysql-test/lib/mtr_cases.pm @@ -287,9 +287,11 @@ sub collect_one_suite($) "mysql-test/suite", "mysql-test", # Look in storage engine specific suite dirs - "storage/*/mysql-test-suites" + "storage/*/mtr", + # Look in plugin specific suite dir + "plugin/$suite/tests", ], - [$suite]); + [$suite, "mtr"]); } mtr_verbose("suitedir: $suitedir"); } diff --git a/mysql-test/lib/mtr_misc.pl b/mysql-test/lib/mtr_misc.pl index a7b5afd9fd7..e50e8cc77df 100644 --- a/mysql-test/lib/mtr_misc.pl +++ b/mysql-test/lib/mtr_misc.pl @@ -31,6 +31,7 @@ sub mtr_script_exists(@); sub mtr_file_exists(@); sub mtr_exe_exists(@); sub mtr_exe_maybe_exists(@); +sub mtr_compress_file($); sub mtr_milli_sleep($); sub start_timer($); sub has_expired($); @@ -199,6 +200,40 @@ sub mtr_exe_exists (@) { } } +# +# Try to compress file using tools that might be available. +# If zip/gzip is not available, just silently ignore. +# + +sub mtr_compress_file ($) { + my ($filename)= @_; + + mtr_error ("File to compress not found: $filename") unless -f $filename; + + my $did_compress= 0; + + if (IS_WINDOWS) + { + # Capture stderr + my $ziperr= `zip $filename.zip $filename 2>&1`; + if ($?) { + print "$ziperr\n" if $ziperr !~ /recognized as an internal or external/; + } else { + unlink($filename); + $did_compress=1; + } + } + else + { + my $gzres= system("gzip $filename"); + $did_compress= ! $gzres; + if ($gzres && $gzres != -1) { + mtr_error ("Error: have gzip but it fails to compress core file"); + } + } + mtr_print("Compressed file $filename") if $did_compress; +} + sub mtr_milli_sleep ($) { die "usage: mtr_milli_sleep(milliseconds)" unless @_ == 1; diff --git a/mysql-test/mysql-test-run.pl b/mysql-test/mysql-test-run.pl index 0e4b3cedbfd..42360aeb28f 100755 --- a/mysql-test/mysql-test-run.pl +++ b/mysql-test/mysql-test-run.pl @@ -263,7 +263,6 @@ my $opt_shutdown_timeout= $ENV{MTR_SHUTDOWN_TIMEOUT} || 10; # seconds my $opt_start_timeout = $ENV{MTR_START_TIMEOUT} || 180; # seconds sub suite_timeout { return $opt_suite_timeout * 60; }; -sub check_timeout { return $opt_testcase_timeout * 6; }; my $opt_wait_all; my $opt_user_args; @@ -299,6 +298,8 @@ sub testcase_timeout ($) { return $opt_testcase_timeout * 60; } +sub check_timeout ($) { return testcase_timeout($_[0]) / 10; } + our $opt_warnings= 1; our $opt_include_ndbcluster= 0; @@ -657,6 +658,8 @@ sub run_test_server ($$$) { mtr_report(" - deleting it, already saved", "$opt_max_save_core"); unlink("$core_file"); + } else { + mtr_compress_file($core_file) unless @opt_cases; } ++$num_saved_cores; } @@ -3413,7 +3416,7 @@ sub check_testcase($$) # Return immediately if no check proceess was started return 0 unless ( keys %started ); - my $timeout= start_timer(check_timeout()); + my $timeout= start_timer(check_timeout($tinfo)); while (1){ my $result; @@ -3485,7 +3488,7 @@ test case was executed:\n"; } elsif ( $proc->{timeout} ) { $tinfo->{comment}.= "Timeout for 'check-testcase' expired after " - .check_timeout()." seconds"; + .check_timeout($tinfo)." seconds"; $result= 4; } else { @@ -3575,7 +3578,7 @@ sub run_on_all($$) # Return immediately if no check proceess was started return 0 unless ( keys %started ); - my $timeout= start_timer(check_timeout()); + my $timeout= start_timer(check_timeout($tinfo)); while (1){ my $result; @@ -3606,7 +3609,7 @@ sub run_on_all($$) } elsif ($proc->{timeout}) { $tinfo->{comment}.= "Timeout for '$run' expired after " - .check_timeout()." seconds"; + .check_timeout($tinfo)." seconds"; } else { # Unknown process returned, most likley a crash, abort everything @@ -4331,7 +4334,7 @@ sub check_warnings ($) { # Return immediately if no check proceess was started return 0 unless ( keys %started ); - my $timeout= start_timer(check_timeout()); + my $timeout= start_timer(check_timeout($tinfo)); while (1){ my $result= 0; @@ -4383,7 +4386,7 @@ sub check_warnings ($) { } elsif ( $proc->{timeout} ) { $tinfo->{comment}.= "Timeout for 'check warnings' expired after " - .check_timeout()." seconds"; + .check_timeout($tinfo)." seconds"; $result= 4; } else { diff --git a/mysql-test/r/func_math.result b/mysql-test/r/func_math.result index ac24ef4dea9..c93e33f98b9 100644 --- a/mysql-test/r/func_math.result +++ b/mysql-test/r/func_math.result @@ -543,6 +543,12 @@ ROUND(LEAST(15, -4939092, 0.2704), STDDEV('a')) -4939092.0000 Warnings: Warning 1292 Truncated incorrect DOUBLE value: 'a' +# +# Bug#12392636 ASSERTION FAILED: SCALE >= 0 && PRECISION > 0 && SCALE <= PRECISION +# +SELECT SUM(DISTINCT (TRUNCATE((.1), NULL))); +SUM(DISTINCT (TRUNCATE((.1), NULL))) +NULL End of 5.1 tests # # Bug #8433: Overflow must be an error diff --git a/mysql-test/r/openssl_1.result b/mysql-test/r/openssl_1.result index 6389438c993..72bbaa71da5 100644 --- a/mysql-test/r/openssl_1.result +++ b/mysql-test/r/openssl_1.result @@ -44,13 +44,13 @@ ERROR 42000: DELETE command denied to user 'ssl_user4'@'localhost' for table 't1 drop user ssl_user1@localhost, ssl_user2@localhost, ssl_user3@localhost, ssl_user4@localhost, ssl_user5@localhost; drop table t1; -mysqltest: Could not open connection 'default': 2026 SSL connection error -mysqltest: Could not open connection 'default': 2026 SSL connection error -mysqltest: Could not open connection 'default': 2026 SSL connection error +mysqltest: Could not open connection 'default': 2026 SSL connection error: ASN: bad other signature confirmation +mysqltest: Could not open connection 'default': 2026 SSL connection error: ASN: bad other signature confirmation +mysqltest: Could not open connection 'default': 2026 SSL connection error: ASN: bad other signature confirmation SSL error: Unable to get private key from '' -mysqltest: Could not open connection 'default': 2026 SSL connection error +mysqltest: Could not open connection 'default': 2026 SSL connection error: Unable to get private key SSL error: Unable to get certificate from '' -mysqltest: Could not open connection 'default': 2026 SSL connection error +mysqltest: Could not open connection 'default': 2026 SSL connection error: Unable to get certificate SHOW STATUS LIKE 'Ssl_cipher'; Variable_name Value Ssl_cipher DHE-RSA-AES256-SHA @@ -83,7 +83,7 @@ Ssl_cipher AES128-SHA SHOW STATUS LIKE 'Ssl_cipher'; Variable_name Value Ssl_cipher AES128-SHA -mysqltest: Could not open connection 'default': 2026 SSL connection error +mysqltest: Could not open connection 'default': 2026 SSL connection error: SSL_CTX_new failed CREATE TABLE t1(a int); INSERT INTO t1 VALUES (1), (2); @@ -189,7 +189,7 @@ UNLOCK TABLES; /*!40111 SET SQL_NOTES=@OLD_SQL_NOTES */; SSL error: Unable to get private key from 'MYSQL_TEST_DIR/std_data/client-cert.pem' -mysqldump: Got error: 2026: SSL connection error when trying to connect +mysqldump: Got error: 2026: SSL connection error: Unable to get private key when trying to connect DROP TABLE t1; Variable_name Value Ssl_cipher DHE-RSA-AES256-SHA diff --git a/mysql-test/suite/binlog/r/binlog_reset_master.result b/mysql-test/suite/binlog/r/binlog_reset_master.result new file mode 100644 index 00000000000..b3d605560ff --- /dev/null +++ b/mysql-test/suite/binlog/r/binlog_reset_master.result @@ -0,0 +1 @@ +RESET MASTER; diff --git a/mysql-test/suite/binlog/t/binlog_reset_master.test b/mysql-test/suite/binlog/t/binlog_reset_master.test new file mode 100644 index 00000000000..b7ad69da3ea --- /dev/null +++ b/mysql-test/suite/binlog/t/binlog_reset_master.test @@ -0,0 +1,26 @@ +# ==== Purpose ==== +# +# Test bugs in RESET MASTER. + +--source include/have_debug.inc +--source include/have_log_bin.inc + +####################################################################### +# BUG#12574820: binlog.binlog_tmp_table timing out in daily and weekly trunk run +# Problem: MYSQL_BIN_LOG::reset_logs acquired LOCK_thread_count and +# LOCK_log in the wrong order. This could cause a deadlock when +# RESET MASTER was run concurrently with a disconnecting thread. +####################################################################### + +# We use sleep, not debug_sync, because the sync point needs to be in +# the thread shut down code after the debug sync facility has been +# shut down. +--let $write_var= SET DEBUG="+d,sleep_after_lock_thread_count_before_delete_thd"; CREATE TEMPORARY TABLE test.t1 (a INT); +--let $write_to_file= GENERATE +--disable_query_log +--source include/write_var_to_file.inc +--enable_query_log + +--exec $MYSQL < $write_to_file +RESET MASTER; +--remove_file $write_to_file diff --git a/mysql-test/suite/innodb/r/innodb_mysql.result b/mysql-test/suite/innodb/r/innodb_mysql.result index 7d96a4acf3f..b6976e43bcb 100644 --- a/mysql-test/suite/innodb/r/innodb_mysql.result +++ b/mysql-test/suite/innodb/r/innodb_mysql.result @@ -2663,7 +2663,6 @@ COUNT(*) 1537 SET SESSION sort_buffer_size = DEFAULT; DROP TABLE t1; -End of 5.1 tests # # Test for bug #39932 "create table fails if column for FK is in different # case than in corr index". @@ -2685,6 +2684,23 @@ t2 CREATE TABLE `t2` ( ) ENGINE=InnoDB DEFAULT CHARSET=latin1 drop table t2, t1; # +# Test for bug #11762012 - "54553: INNODB ASSERTS IN HA_INNOBASE:: +# UPDATE_ROW, TEMPORARY TABLE, TABLE LOCK". +# +DROP TABLE IF EXISTS t1; +CREATE TEMPORARY TABLE t1 (c int) ENGINE = InnoDB; +INSERT INTO t1 VALUES (1); +LOCK TABLES t1 READ; +# Even though temporary table was locked for READ we +# still allow writes to it to be compatible with MyISAM. +# This is possible since due to fact that temporary tables +# are specific to connection and therefore locking for them +# is irrelevant. +UPDATE t1 SET c = 5; +UNLOCK TABLES; +DROP TEMPORARY TABLE t1; +End of 5.1 tests +# # Bug#44613 SELECT statement inside FUNCTION takes a shared lock # DROP TABLE IF EXISTS t1; diff --git a/mysql-test/suite/innodb/t/innodb_mysql.test b/mysql-test/suite/innodb/t/innodb_mysql.test index acc843341eb..910b93b443b 100644 --- a/mysql-test/suite/innodb/t/innodb_mysql.test +++ b/mysql-test/suite/innodb/t/innodb_mysql.test @@ -830,8 +830,6 @@ SET SESSION sort_buffer_size = DEFAULT; DROP TABLE t1; ---echo End of 5.1 tests - --echo # --echo # Test for bug #39932 "create table fails if column for FK is in different @@ -851,6 +849,28 @@ show create table t2; drop table t2, t1; +--echo # +--echo # Test for bug #11762012 - "54553: INNODB ASSERTS IN HA_INNOBASE:: +--echo # UPDATE_ROW, TEMPORARY TABLE, TABLE LOCK". +--echo # +--disable_warnings +DROP TABLE IF EXISTS t1; +--enable_warnings +CREATE TEMPORARY TABLE t1 (c int) ENGINE = InnoDB; +INSERT INTO t1 VALUES (1); +LOCK TABLES t1 READ; +--echo # Even though temporary table was locked for READ we +--echo # still allow writes to it to be compatible with MyISAM. +--echo # This is possible since due to fact that temporary tables +--echo # are specific to connection and therefore locking for them +--echo # is irrelevant. +UPDATE t1 SET c = 5; +UNLOCK TABLES; +DROP TEMPORARY TABLE t1; + +--echo End of 5.1 tests + + --echo # --echo # Bug#44613 SELECT statement inside FUNCTION takes a shared lock --echo # diff --git a/mysql-test/suite/rpl/t/rpl_typeconv-master.opt b/mysql-test/suite/rpl/t/rpl_typeconv-master.opt new file mode 100644 index 00000000000..de048691031 --- /dev/null +++ b/mysql-test/suite/rpl/t/rpl_typeconv-master.opt @@ -0,0 +1 @@ +--testcase-timeout=40 diff --git a/mysql-test/t/func_math.test b/mysql-test/t/func_math.test index 0e704fecf57..0d59f98a313 100644 --- a/mysql-test/t/func_math.test +++ b/mysql-test/t/func_math.test @@ -370,6 +370,12 @@ DROP TABLE t1; SELECT ROUND(LEAST(15, -4939092, 0.2704), STDDEV('a')); +--echo # +--echo # Bug#12392636 ASSERTION FAILED: SCALE >= 0 && PRECISION > 0 && SCALE <= PRECISION +--echo # + +SELECT SUM(DISTINCT (TRUNCATE((.1), NULL))); + --echo End of 5.1 tests --echo # diff --git a/sql-common/client.c b/sql-common/client.c index abaea310aae..f38467ff731 100644 --- a/sql-common/client.c +++ b/sql-common/client.c @@ -1840,6 +1840,8 @@ mysql_get_ssl_cipher(MYSQL *mysql __attribute__((unused))) ssl_verify_server_cert() vio pointer to a SSL connected vio server_hostname name of the server that we connected to + errptr if we fail, we'll return (a pointer to a string + describing) the reason here RETURN VALUES 0 Success @@ -1849,7 +1851,7 @@ mysql_get_ssl_cipher(MYSQL *mysql __attribute__((unused))) #if defined(HAVE_OPENSSL) && !defined(EMBEDDED_LIBRARY) -static int ssl_verify_server_cert(Vio *vio, const char* server_hostname) +static int ssl_verify_server_cert(Vio *vio, const char* server_hostname, const char **errptr) { SSL *ssl; X509 *server_cert; @@ -1860,19 +1862,19 @@ static int ssl_verify_server_cert(Vio *vio, const char* server_hostname) if (!(ssl= (SSL*)vio->ssl_arg)) { - DBUG_PRINT("error", ("No SSL pointer found")); + *errptr= "No SSL pointer found"; DBUG_RETURN(1); } if (!server_hostname) { - DBUG_PRINT("error", ("No server hostname supplied")); + *errptr= "No server hostname supplied"; DBUG_RETURN(1); } if (!(server_cert= SSL_get_peer_certificate(ssl))) { - DBUG_PRINT("error", ("Could not get server certificate")); + *errptr= "Could not get server certificate"; DBUG_RETURN(1); } @@ -1901,7 +1903,7 @@ static int ssl_verify_server_cert(Vio *vio, const char* server_hostname) DBUG_RETURN(0); } } - DBUG_PRINT("error", ("SSL certificate validation failure")); + *errptr= "SSL certificate validation failure"; DBUG_RETURN(1); } @@ -2507,6 +2509,9 @@ static int send_client_reply_packet(MCPVIO_EXT *mpvio, /* Do the SSL layering. */ struct st_mysql_options *options= &mysql->options; struct st_VioSSLFd *ssl_fd; + enum enum_ssl_init_error ssl_init_error; + const char *cert_error; + unsigned long ssl_error; /* Send mysql->client_flag, max_packet_size - unencrypted otherwise @@ -2526,9 +2531,11 @@ static int send_client_reply_packet(MCPVIO_EXT *mpvio, options->ssl_cert, options->ssl_ca, options->ssl_capath, - options->ssl_cipher))) + options->ssl_cipher, + &ssl_init_error))) { - set_mysql_error(mysql, CR_SSL_CONNECTION_ERROR, unknown_sqlstate); + set_mysql_extended_error(mysql, CR_SSL_CONNECTION_ERROR, unknown_sqlstate, + ER(CR_SSL_CONNECTION_ERROR), sslGetErrString(ssl_init_error)); goto error; } mysql->connector_fd= (unsigned char *) ssl_fd; @@ -2536,18 +2543,24 @@ static int send_client_reply_packet(MCPVIO_EXT *mpvio, /* Connect to the server */ DBUG_PRINT("info", ("IO layer change in progress...")); if (sslconnect(ssl_fd, net->vio, - (long) (mysql->options.connect_timeout))) + (long) (mysql->options.connect_timeout), &ssl_error)) { - set_mysql_error(mysql, CR_SSL_CONNECTION_ERROR, unknown_sqlstate); + char buf[512]; + ERR_error_string_n(ssl_error, buf, 512); + buf[511]= 0; + set_mysql_extended_error(mysql, CR_SSL_CONNECTION_ERROR, unknown_sqlstate, + ER(CR_SSL_CONNECTION_ERROR), + buf); goto error; } DBUG_PRINT("info", ("IO layer change done!")); /* Verify server cert */ if ((mysql->client_flag & CLIENT_SSL_VERIFY_SERVER_CERT) && - ssl_verify_server_cert(net->vio, mysql->host)) + ssl_verify_server_cert(net->vio, mysql->host, &cert_error)) { - set_mysql_error(mysql, CR_SSL_CONNECTION_ERROR, unknown_sqlstate); + set_mysql_extended_error(mysql, CR_SSL_CONNECTION_ERROR, unknown_sqlstate, + ER(CR_SSL_CONNECTION_ERROR), cert_error); goto error; } } diff --git a/sql/item_func.cc b/sql/item_func.cc index d0def6abccb..754eae6d55b 100644 --- a/sql/item_func.cc +++ b/sql/item_func.cc @@ -2259,6 +2259,9 @@ void Item_func_round::fix_length_and_dec() } val1= args[1]->val_int(); + if ((null_value= args[1]->is_null())) + return; + val1_unsigned= args[1]->unsigned_flag; if (val1 < 0) decimals_to_set= val1_unsigned ? INT_MAX : 0; diff --git a/sql/log.cc b/sql/log.cc index ce6b0f0a5a2..9080dcd7fa2 100644 --- a/sql/log.cc +++ b/sql/log.cc @@ -3372,12 +3372,6 @@ bool MYSQL_BIN_LOG::reset_logs(THD* thd) DBUG_ENTER("reset_logs"); ha_reset_logs(thd); - /* - We need to get both locks to be sure that no one is trying to - write to the index log file. - */ - mysql_mutex_lock(&LOCK_log); - mysql_mutex_lock(&LOCK_index); /* The following mutex is needed to ensure that no threads call @@ -3387,6 +3381,13 @@ bool MYSQL_BIN_LOG::reset_logs(THD* thd) */ mysql_mutex_lock(&LOCK_thread_count); + /* + We need to get both locks to be sure that no one is trying to + write to the index log file. + */ + mysql_mutex_lock(&LOCK_log); + mysql_mutex_lock(&LOCK_index); + /* Save variables so that we can reopen the log */ save_name=name; name=0; // Protect against free diff --git a/sql/mysqld.cc b/sql/mysqld.cc index 8ea076e72ba..687ab09d379 100644 --- a/sql/mysqld.cc +++ b/sql/mysqld.cc @@ -2070,6 +2070,12 @@ void unlink_thd(THD *thd) thd_cleanup(thd); dec_connection_count(); mysql_mutex_lock(&LOCK_thread_count); + /* + Used by binlog_reset_master. It would be cleaner to use + DEBUG_SYNC here, but that's not possible because the THD's debug + sync feature has been shut down at this point. + */ + DBUG_EXECUTE_IF("sleep_after_lock_thread_count_before_delete_thd", sleep(5);); delete_thd(thd); DBUG_VOID_RETURN; } diff --git a/sql/sql_acl.cc b/sql/sql_acl.cc index 60658c040ab..44e42c86228 100644 --- a/sql/sql_acl.cc +++ b/sql/sql_acl.cc @@ -8527,14 +8527,14 @@ static ulong parse_client_handshake_packet(MPVIO_EXT *mpvio, DBUG_PRINT("info", ("client capabilities: %lu", mpvio->client_capabilities)); if (mpvio->client_capabilities & CLIENT_SSL) { - char error_string[1024] __attribute__((unused)); + unsigned long errptr; /* Do the SSL layering. */ if (!ssl_acceptor_fd) return packet_error; DBUG_PRINT("info", ("IO layer change in progress...")); - if (sslaccept(ssl_acceptor_fd, net->vio, net->read_timeout)) + if (sslaccept(ssl_acceptor_fd, net->vio, net->read_timeout, &errptr)) { DBUG_PRINT("error", ("Failed to accept new SSL connection")); return packet_error; diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc index 4f5bce3e8af..44a9243d8f5 100644 --- a/sql/sql_parse.cc +++ b/sql/sql_parse.cc @@ -1748,6 +1748,67 @@ bool sp_process_definer(THD *thd) } +/** + Auxiliary call that opens and locks tables for LOCK TABLES statement + and initializes the list of locked tables. + + @param thd Thread context. + @param tables List of tables to be locked. + + @return FALSE in case of success, TRUE in case of error. +*/ + +static bool lock_tables_open_and_lock_tables(THD *thd, TABLE_LIST *tables) +{ + Lock_tables_prelocking_strategy lock_tables_prelocking_strategy; + uint counter; + TABLE_LIST *table; + + thd->in_lock_tables= 1; + + if (open_tables(thd, &tables, &counter, 0, &lock_tables_prelocking_strategy)) + goto err; + + /* + We allow to change temporary tables even if they were locked for read + by LOCK TABLES. To avoid a discrepancy between lock acquired at LOCK + TABLES time and by the statement which is later executed under LOCK TABLES + we ensure that for temporary tables we always request a write lock (such + discrepancy can cause problems for the storage engine). + We don't set TABLE_LIST::lock_type in this case as this might result in + extra warnings from THD::decide_logging_format() even though binary logging + is totally irrelevant for LOCK TABLES. + */ + for (table= tables; table; table= table->next_global) + if (!table->placeholder() && table->table->s->tmp_table) + table->table->reginfo.lock_type= TL_WRITE; + + if (lock_tables(thd, tables, counter, 0) || + thd->locked_tables_list.init_locked_tables(thd)) + goto err; + + thd->in_lock_tables= 0; + + return FALSE; + +err: + thd->in_lock_tables= 0; + + trans_rollback_stmt(thd); + /* + Need to end the current transaction, so the storage engine (InnoDB) + can free its locks if LOCK TABLES locked some tables before finding + that it can't lock a table in its list + */ + trans_commit_implicit(thd); + /* Close tables and release metadata locks. */ + close_thread_tables(thd); + DBUG_ASSERT(!thd->locked_tables_mode); + thd->mdl_context.release_transactional_locks(); + return TRUE; +} + + /** Execute command saved in thd and lex->sql_command. @@ -3093,31 +3154,11 @@ end_with_restore_list: goto error; thd->variables.option_bits|= OPTION_TABLE_LOCK; - thd->in_lock_tables=1; - { - Lock_tables_prelocking_strategy lock_tables_prelocking_strategy; - - res= (open_and_lock_tables(thd, all_tables, FALSE, 0, - &lock_tables_prelocking_strategy) || - thd->locked_tables_list.init_locked_tables(thd)); - } - - thd->in_lock_tables= 0; + res= lock_tables_open_and_lock_tables(thd, all_tables); if (res) { - trans_rollback_stmt(thd); - /* - Need to end the current transaction, so the storage engine (InnoDB) - can free its locks if LOCK TABLES locked some tables before finding - that it can't lock a table in its list - */ - trans_commit_implicit(thd); - /* Close tables and release metadata locks. */ - close_thread_tables(thd); - DBUG_ASSERT(!thd->locked_tables_mode); - thd->mdl_context.release_transactional_locks(); thd->variables.option_bits&= ~(OPTION_TABLE_LOCK); } else diff --git a/vio/test-ssl.c b/vio/test-ssl.c index 1e846727d00..4d158ae83f7 100644 --- a/vio/test-ssl.c +++ b/vio/test-ssl.c @@ -59,6 +59,9 @@ main(int argc, char** argv) struct st_VioSSLFd* ssl_acceptor= 0; struct st_VioSSLFd* ssl_connector= 0; Vio* client_vio=0, *server_vio=0; + enum enum_ssl_init_error ssl_init_error; + unsigned long ssl_error; + MY_INIT(argv[0]); DBUG_PROCESS(argv[0]); DBUG_PUSH(default_dbug_option); @@ -91,16 +94,16 @@ main(int argc, char** argv) ssl_acceptor = new_VioSSLAcceptorFd(server_key, server_cert, ca_file, ca_path, cipher); ssl_connector = new_VioSSLConnectorFd(client_key, client_cert, ca_file, - ca_path, cipher); + ca_path, cipher, &ssl_init_error); client_vio = (struct st_vio*)my_malloc(sizeof(struct st_vio),MYF(0)); client_vio->sd = sv[0]; client_vio->vioblocking(client_vio, 0, &unused); - sslconnect(ssl_connector,client_vio,60L); + sslconnect(ssl_connector,client_vio,60L,&ssl_error); server_vio = (struct st_vio*)my_malloc(sizeof(struct st_vio),MYF(0)); server_vio->sd = sv[1]; server_vio->vioblocking(client_vio, 0, &unused); - sslaccept(ssl_acceptor,server_vio,60L); + sslaccept(ssl_acceptor,server_vio,60L, &ssl_error); printf("Socketpair: %d , %d\n", client_vio->sd, server_vio->sd); diff --git a/vio/test-sslclient.c b/vio/test-sslclient.c index 643dcbf2c8e..9d8a741e313 100644 --- a/vio/test-sslclient.c +++ b/vio/test-sslclient.c @@ -50,6 +50,9 @@ main( int argc __attribute__((unused)), Vio* client_vio=0; int err; char xbuf[100]="Ohohhhhoh1234"; + enum enum_ssl_init_error ssl_init_error; + unsigned long ssl_error; + MY_INIT(argv[0]); DBUG_PROCESS(argv[0]); DBUG_PUSH(default_dbug_option); @@ -60,7 +63,8 @@ main( int argc __attribute__((unused)), if (ca_path!=0) printf("CApath : %s\n", ca_path); - ssl_connector = new_VioSSLConnectorFd(client_key, client_cert, ca_file, ca_path, cipher); + ssl_connector = new_VioSSLConnectorFd(client_key, client_cert, ca_file, ca_path, cipher, + &ssl_init_error); if(!ssl_connector) { fatal_error("client:new_VioSSLConnectorFd failed"); } @@ -81,7 +85,7 @@ main( int argc __attribute__((unused)), /* ----------------------------------------------- */ /* Now we have TCP conncetion. Start SSL negotiation. */ read(client_vio->sd,xbuf, sizeof(xbuf)); - sslconnect(ssl_connector,client_vio,60L); + sslconnect(ssl_connector,client_vio,60L,&ssl_error); err = vio_read(client_vio,xbuf, sizeof(xbuf)); if (err<=0) { my_free(ssl_connector); diff --git a/vio/test-sslserver.c b/vio/test-sslserver.c index 3123a4def2c..35cfa26bd00 100644 --- a/vio/test-sslserver.c +++ b/vio/test-sslserver.c @@ -52,6 +52,7 @@ do_ssl_stuff( TH_ARGS* args) const char* s = "Huhuhuhuuu"; Vio* server_vio; int err; + unsigned long ssl_error; DBUG_ENTER("do_ssl_stuff"); server_vio = vio_new(args->sd, VIO_TYPE_TCPIP, TRUE); @@ -60,7 +61,7 @@ do_ssl_stuff( TH_ARGS* args) /* TCP connection is ready. Do server side SSL. */ err = write(server_vio->sd,(uchar*)s, strlen(s)); - sslaccept(args->ssl_acceptor,server_vio,60L); + sslaccept(args->ssl_acceptor,server_vio,60L,&ssl_error); err = server_vio->write(server_vio,(uchar*)s, strlen(s)); DBUG_VOID_RETURN; } diff --git a/vio/viossl.c b/vio/viossl.c index 5cb5f36f20d..290abf788c2 100644 --- a/vio/viossl.c +++ b/vio/viossl.c @@ -144,8 +144,9 @@ void vio_ssl_delete(Vio *vio) static int ssl_do(struct st_VioSSLFd *ptr, Vio *vio, long timeout, - int (*connect_accept_func)(SSL*)) + int (*connect_accept_func)(SSL*), unsigned long *errptr) { + int r; SSL *ssl; my_bool unused; my_bool was_blocking; @@ -160,7 +161,7 @@ static int ssl_do(struct st_VioSSLFd *ptr, Vio *vio, long timeout, if (!(ssl= SSL_new(ptr->ssl_context))) { DBUG_PRINT("error", ("SSL_new failure")); - report_errors(ssl); + *errptr= ERR_get_error(); vio_blocking(vio, was_blocking, &unused); DBUG_RETURN(1); } @@ -169,10 +170,10 @@ static int ssl_do(struct st_VioSSLFd *ptr, Vio *vio, long timeout, SSL_SESSION_set_timeout(SSL_get_session(ssl), timeout); SSL_set_fd(ssl, vio->sd); - if (connect_accept_func(ssl) < 1) + if ((r= connect_accept_func(ssl)) < 1) { DBUG_PRINT("error", ("SSL_connect/accept failure")); - report_errors(ssl); + *errptr= SSL_get_error(ssl, r); SSL_free(ssl); vio_blocking(vio, was_blocking, &unused); DBUG_RETURN(1); @@ -220,17 +221,17 @@ static int ssl_do(struct st_VioSSLFd *ptr, Vio *vio, long timeout, } -int sslaccept(struct st_VioSSLFd *ptr, Vio *vio, long timeout) +int sslaccept(struct st_VioSSLFd *ptr, Vio *vio, long timeout, unsigned long *errptr) { DBUG_ENTER("sslaccept"); - DBUG_RETURN(ssl_do(ptr, vio, timeout, SSL_accept)); + DBUG_RETURN(ssl_do(ptr, vio, timeout, SSL_accept, errptr)); } -int sslconnect(struct st_VioSSLFd *ptr, Vio *vio, long timeout) +int sslconnect(struct st_VioSSLFd *ptr, Vio *vio, long timeout, unsigned long *errptr) { DBUG_ENTER("sslconnect"); - DBUG_RETURN(ssl_do(ptr, vio, timeout, SSL_connect)); + DBUG_RETURN(ssl_do(ptr, vio, timeout, SSL_connect, errptr)); } diff --git a/vio/viosslfactories.c b/vio/viosslfactories.c index 4971dec37fb..4f4dd5758ba 100644 --- a/vio/viosslfactories.c +++ b/vio/viosslfactories.c @@ -165,7 +165,7 @@ static struct st_VioSSLFd * new_VioSSLFd(const char *key_file, const char *cert_file, const char *ca_file, const char *ca_path, const char *cipher, SSL_METHOD *method, - enum enum_ssl_init_error* error) + enum enum_ssl_init_error *error) { DH *dh; struct st_VioSSLFd *ssl_fd; @@ -249,11 +249,10 @@ new_VioSSLFd(const char *key_file, const char *cert_file, struct st_VioSSLFd * new_VioSSLConnectorFd(const char *key_file, const char *cert_file, const char *ca_file, const char *ca_path, - const char *cipher) + const char *cipher, enum enum_ssl_init_error* error) { struct st_VioSSLFd *ssl_fd; int verify= SSL_VERIFY_PEER; - enum enum_ssl_init_error dummy; /* Turn off verification of servers certificate if both @@ -263,7 +262,7 @@ new_VioSSLConnectorFd(const char *key_file, const char *cert_file, verify= SSL_VERIFY_NONE; if (!(ssl_fd= new_VioSSLFd(key_file, cert_file, ca_file, - ca_path, cipher, TLSv1_client_method(), &dummy))) + ca_path, cipher, TLSv1_client_method(), error))) { return 0; } diff --git a/vio/viotest-ssl.c b/vio/viotest-ssl.c index 5c68e861d2a..90489b46605 100644 --- a/vio/viotest-ssl.c +++ b/vio/viotest-ssl.c @@ -60,6 +60,9 @@ int main(int argc, char **argv) struct st_VioSSLConnectorFd* ssl_connector=0; Vio* client_vio=0; Vio* server_vio=0; + enum enum_ssl_init_error ssl_init_error; + unsigned long ssl_error; + MY_INIT(argv[0]); DBUG_PROCESS(argv[0]); DBUG_PUSH(default_dbug_option); @@ -92,14 +95,14 @@ int main(int argc, char **argv) ssl_acceptor = new_VioSSLAcceptorFd(server_key, server_cert, ca_file, ca_path); ssl_connector = new_VioSSLConnectorFd(client_key, client_cert, ca_file, - ca_path); + ca_path, &ssl_init_error); client_vio = (Vio*)my_malloc(sizeof(struct st_vio),MYF(0)); client_vio->sd = sv[0]; - sslconnect(ssl_connector,client_vio); + sslconnect(ssl_connector,client_vio,&ssl_error); server_vio = (Vio*)my_malloc(sizeof(struct st_vio),MYF(0)); server_vio->sd = sv[1]; - sslaccept(ssl_acceptor,server_vio); + sslaccept(ssl_acceptor,server_vio,&ssl_error); printf("Socketpair: %d , %d\n", client_vio->sd, server_vio->sd);