diff options
122 files changed, 2869 insertions, 1727 deletions
diff --git a/.bzrignore b/.bzrignore index 409b6148125..74c81c48e05 100644 --- a/.bzrignore +++ b/.bzrignore @@ -1097,7 +1097,6 @@ CPackSourceConfig.cmake Docs/INFO_BIN Docs/INFO_SRC tags -sql/.empty Testing info_macros.cmake VERSION.dep @@ -1,4 +1,4 @@ MYSQL_VERSION_MAJOR=5 MYSQL_VERSION_MINOR=5 -MYSQL_VERSION_PATCH=25 +MYSQL_VERSION_PATCH=27 MYSQL_VERSION_EXTRA= diff --git a/client/mysqlbinlog.cc b/client/mysqlbinlog.cc index ccbd2fb4d22..6c6410c87f7 100644 --- a/client/mysqlbinlog.cc +++ b/client/mysqlbinlog.cc @@ -1,5 +1,6 @@ /* - Copyright (c) 2000, 2011, Oracle and/or its affiliates. + Copyright (c) 2000, 2012, Oracle and/or its affiliates. + Copyright (c) 2009, 2012, Monty Program Ab This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -843,6 +844,7 @@ Exit_status process_event(PRINT_EVENT_INFO *print_event_info, Log_event *ev, DBUG_ENTER("process_event"); print_event_info->short_form= short_form; Exit_status retval= OK_CONTINUE; + IO_CACHE *const head= &print_event_info->head_cache; /* Format events are not concerned by --offset and such, we always need to @@ -922,6 +924,8 @@ Exit_status process_event(PRINT_EVENT_INFO *print_event_info, Log_event *ev, print_skip_replication_statement(print_event_info, ev); ev->print(result_file, print_event_info); } + if (head->error == -1) + goto err; break; } @@ -954,8 +958,9 @@ Exit_status process_event(PRINT_EVENT_INFO *print_event_info, Log_event *ev, { print_skip_replication_statement(print_event_info, ev); ce->print(result_file, print_event_info, TRUE); + if (head->error == -1) + goto err; } - // If this binlog is not 3.23 ; why this test?? if (glob_description_event->binlog_version >= 3) { @@ -977,6 +982,8 @@ Exit_status process_event(PRINT_EVENT_INFO *print_event_info, Log_event *ev, output of Append_block_log_event::print is only a comment. */ ev->print(result_file, print_event_info); + if (head->error == -1) + goto err; if ((retval= load_processor.process((Append_block_log_event*) ev)) != OK_CONTINUE) goto end; @@ -985,6 +992,8 @@ Exit_status process_event(PRINT_EVENT_INFO *print_event_info, Log_event *ev, case EXEC_LOAD_EVENT: { ev->print(result_file, print_event_info); + if (head->error == -1) + goto err; Execute_load_log_event *exv= (Execute_load_log_event*)ev; Create_file_log_event *ce= load_processor.grab_event(exv->file_id); /* @@ -1002,6 +1011,8 @@ Exit_status process_event(PRINT_EVENT_INFO *print_event_info, Log_event *ev, ce->print(result_file, print_event_info, TRUE); my_free((void*)ce->fname); delete ce; + if (head->error == -1) + goto err; } else warning("Ignoring Execute_load_log_event as there is no " @@ -1014,6 +1025,8 @@ Exit_status process_event(PRINT_EVENT_INFO *print_event_info, Log_event *ev, print_event_info->common_header_len= glob_description_event->common_header_len; ev->print(result_file, print_event_info); + if (head->error == -1) + goto err; if (!remote_opt) { ev->free_temp_buf(); // free memory allocated in dump_local_log_entries @@ -1043,6 +1056,8 @@ Exit_status process_event(PRINT_EVENT_INFO *print_event_info, Log_event *ev, break; case BEGIN_LOAD_QUERY_EVENT: ev->print(result_file, print_event_info); + if (head->error == -1) + goto err; if ((retval= load_processor.process((Begin_load_query_log_event*) ev)) != OK_CONTINUE) goto end; @@ -1060,6 +1075,12 @@ Exit_status process_event(PRINT_EVENT_INFO *print_event_info, Log_event *ev, convert_path_to_forward_slashes(fname); print_skip_replication_statement(print_event_info, ev); exlq->print(result_file, print_event_info, fname); + if (head->error == -1) + { + if (fname) + my_free(fname); + goto err; + } } else warning("Ignoring Execute_load_query since there is no " @@ -1190,6 +1211,8 @@ Exit_status process_event(PRINT_EVENT_INFO *print_event_info, Log_event *ev, default: print_skip_replication_statement(print_event_info, ev); ev->print(result_file, print_event_info); + if (head->error == -1) + goto err; } } @@ -1353,7 +1376,7 @@ static struct my_option my_options[] = "Stop reading the binlog at position N. Applies to the last binlog " "passed on the command line.", &stop_position, &stop_position, 0, GET_ULL, - REQUIRED_ARG, (ulonglong)(~(my_off_t)0), BIN_LOG_HEADER_SIZE, + REQUIRED_ARG, (longlong)(~(my_off_t)0), BIN_LOG_HEADER_SIZE, (ulonglong)(~(my_off_t)0), 0, 0, 0}, {"to-last-log", 't', "Requires -R. Will not stop at the end of the \ requested binlog but rather continue printing until the end of the last \ @@ -2322,7 +2345,13 @@ err: end: if (fd >= 0) my_close(fd, MYF(MY_WME)); - end_io_cache(file); + /* + Since the end_io_cache() writes to the + file errors may happen. + */ + if (end_io_cache(file)) + retval= ERROR_STOP; + return retval; } diff --git a/client/mysqldump.c b/client/mysqldump.c index 3adbc897c50..739cc345ec2 100644 --- a/client/mysqldump.c +++ b/client/mysqldump.c @@ -2610,6 +2610,7 @@ static uint get_table_structure(char *table, char *db, char *table_type, if (strcmp(field->name, "View") == 0) { char *scv_buff= NULL; + my_ulonglong n_cols; verbose_msg("-- It's a view, create dummy table for view\n"); @@ -2624,8 +2625,8 @@ static uint get_table_structure(char *table, char *db, char *table_type, the same name in order to satisfy views that depend on this view. The table will be removed when the actual view is created. - The properties of each column, aside from the data type, are not - preserved in this temporary table, because they are not necessary. + The properties of each column, are not preserved in this temporary + table, because they are not necessary. This will not be necessary once we can determine dependencies between views and can simply dump them in the appropriate order. @@ -2652,8 +2653,23 @@ static uint get_table_structure(char *table, char *db, char *table_type, else my_free(scv_buff); - if (mysql_num_rows(result)) + n_cols= mysql_num_rows(result); + if (0 != n_cols) { + + /* + The actual formula is based on the column names and how the .FRM + files are stored and is too volatile to be repeated here. + Thus we simply warn the user if the columns exceed a limit we + know works most of the time. + */ + if (n_cols >= 1000) + fprintf(stderr, + "-- Warning: Creating a stand-in table for view %s may" + " fail when replaying the dump file produced because " + "of the number of columns exceeding 1000. Exercise " + "caution when replaying the produced dump file.\n", + table); if (opt_drop) { /* @@ -2680,14 +2696,19 @@ static uint get_table_structure(char *table, char *db, char *table_type, row= mysql_fetch_row(result); - fprintf(sql_file, " %s %s", quote_name(row[0], name_buff, 0), - row[1]); + /* + The actual column type doesn't matter anyway, since the table will + be dropped at run time. + We do tinyint to avoid hitting the row size limit. + */ + fprintf(sql_file, " %s tinyint NOT NULL", + quote_name(row[0], name_buff, 0)); while((row= mysql_fetch_row(result))) { /* col name, col type */ - fprintf(sql_file, ",\n %s %s", - quote_name(row[0], name_buff, 0), row[1]); + fprintf(sql_file, ",\n %s tinyint NOT NULL", + quote_name(row[0], name_buff, 0)); } /* diff --git a/client/mysqltest.cc b/client/mysqltest.cc index f204f359656..bb89db4b231 100644 --- a/client/mysqltest.cc +++ b/client/mysqltest.cc @@ -1,5 +1,5 @@ -/* Copyright (c) 2000, 2011, Oracle and/or its affiliates. - Copyright (c) 2009-2012 Monty Program Ab. +/* Copyright (c) 2000, 2012, Oracle and/or its affiliates. + Copyright (c) 2009, 2012, Monty Program Ab. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -5148,7 +5148,7 @@ typedef struct static st_error global_error_names[] = { - { "<No error>", -1, "" }, + { "<No error>", -1U, "" }, #include <mysqld_ername.h> { 0, 0, 0 } }; @@ -7710,6 +7710,8 @@ void run_query_normal(struct st_connection *cn, struct st_command *command, */ if ((counter==0) && do_read_query_result(cn)) { + /* we've failed to collect the result set */ + cn->pending= TRUE; handle_error(command, mysql_errno(mysql), mysql_error(mysql), mysql_sqlstate(mysql), ds); goto end; diff --git a/extra/yassl/taocrypt/src/asn.cpp b/extra/yassl/taocrypt/src/asn.cpp index a502666d15b..5ec4cac1c44 100644 --- a/extra/yassl/taocrypt/src/asn.cpp +++ b/extra/yassl/taocrypt/src/asn.cpp @@ -758,6 +758,10 @@ void CertDecoder::GetName(NameType nt) while (source_.get_index() < length) { GetSet(); + if (source_.GetError().What() == SET_E) { + source_.SetError(NO_ERROR_E); // extensions may only have sequence + source_.prev(); + } GetSequence(); byte b = source_.next(); diff --git a/include/my_getopt.h b/include/my_getopt.h index 61c4b054615..a56be90f455 100644 --- a/include/my_getopt.h +++ b/include/my_getopt.h @@ -1,5 +1,5 @@ /* - Copyright (c) 2002, 2011, Oracle and/or its affiliates. + Copyright (c) 2002, 2012, Oracle and/or its affiliates. This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -79,7 +79,7 @@ struct my_option enum get_opt_arg_type arg_type; /**< e.g. REQUIRED_ARG or OPT_ARG */ longlong def_value; /**< Default value */ longlong min_value; /**< Min allowed value (for numbers) */ - longlong max_value; /**< Max allowed value (for numbers) */ + ulonglong max_value; /**< Max allowed value (for numbers) */ longlong sub_size; /**< Unused */ long block_size; /**< Value should be a mult. of this (for numbers) */ void *app_type; /**< To be used by an application */ diff --git a/include/sql_common.h b/include/sql_common.h index cd32a77f86e..a1c9faac82d 100644 --- a/include/sql_common.h +++ b/include/sql_common.h @@ -1,7 +1,7 @@ #ifndef SQL_COMMON_INCLUDED #define SQL_COMMON_INCLUDED -/* Copyright (c) 2003, 2010, Oracle and/or its affiliates. - Copyright (c) 2010, 2011, Monty Program Ab +/* Copyright (c) 2003, 2012, Oracle and/or its affiliates. + Copyright (c) 2010, 2012, Monty Program Ab This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -80,8 +80,9 @@ typedef struct st_mysql_methods 0, arg, length, 1, stmt) extern CHARSET_INFO *default_client_charset_info; -MYSQL_FIELD *unpack_fields(MYSQL_DATA *data,MEM_ROOT *alloc,uint fields, - my_bool default_value, uint server_capabilities); +MYSQL_FIELD *unpack_fields(MYSQL *mysql, MYSQL_DATA *data,MEM_ROOT *alloc, + uint fields, my_bool default_value, + uint server_capabilities); void free_rows(MYSQL_DATA *cur); void free_old_query(MYSQL *mysql); void end_server(MYSQL *mysql); diff --git a/libmysql/libmysql.c b/libmysql/libmysql.c index 230376bc3b0..f90cc96a90f 100644 --- a/libmysql/libmysql.c +++ b/libmysql/libmysql.c @@ -1,4 +1,5 @@ -/* Copyright (c) 2000, 2011, Oracle and/or its affiliates +/* Copyright (c) 2000, 2012, Oracle and/or its affiliates + Copyright (c) 2009, 2012, Monty Program Ab This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -811,7 +812,7 @@ MYSQL_FIELD *cli_list_fields(MYSQL *mysql) return NULL; mysql->field_count= (uint) query->rows; - return unpack_fields(query,&mysql->field_alloc, + return unpack_fields(mysql, query,&mysql->field_alloc, mysql->field_count, 1, mysql->server_capabilities); } @@ -871,7 +872,7 @@ mysql_list_processes(MYSQL *mysql) if (!(fields = (*mysql->methods->read_rows)(mysql,(MYSQL_FIELD*) 0, protocol_41(mysql) ? 7 : 5))) DBUG_RETURN(NULL); - if (!(mysql->fields=unpack_fields(fields,&mysql->field_alloc,field_count,0, + if (!(mysql->fields=unpack_fields(mysql, fields,&mysql->field_alloc,field_count,0, mysql->server_capabilities))) DBUG_RETURN(0); mysql->status=MYSQL_STATUS_GET_RESULT; @@ -1456,7 +1457,7 @@ my_bool cli_read_prepare_result(MYSQL *mysql, MYSQL_STMT *stmt) if (!(fields_data= (*mysql->methods->read_rows)(mysql,(MYSQL_FIELD*)0,7))) DBUG_RETURN(1); - if (!(stmt->fields= unpack_fields(fields_data,&stmt->mem_root, + if (!(stmt->fields= unpack_fields(mysql, fields_data,&stmt->mem_root, field_count,0, mysql->server_capabilities))) DBUG_RETURN(1); diff --git a/libmysqld/examples/CMakeLists.txt b/libmysqld/examples/CMakeLists.txt index 146e51d79c7..559b1d9ae32 100644 --- a/libmysqld/examples/CMakeLists.txt +++ b/libmysqld/examples/CMakeLists.txt @@ -15,9 +15,9 @@ INCLUDE_DIRECTORIES(${CMAKE_SOURCE_DIR}/include ${CMAKE_SOURCE_DIR}/libmysqld/include - ${CMAKE_SOURCE_DIR}/regex + ${CMAKE_SOURCE_DIR}/regex ${CMAKE_SOURCE_DIR}/sql - ${MY_READLINE_INCLUDE_DIR} + ${MY_READLINE_INCLUDE_DIR} ) diff --git a/mysql-test/include/mysqlbinlog_have_debug.inc b/mysql-test/include/mysqlbinlog_have_debug.inc new file mode 100644 index 00000000000..14da1379ecd --- /dev/null +++ b/mysql-test/include/mysqlbinlog_have_debug.inc @@ -0,0 +1,34 @@ +############################################# +# checks if mysqlbinlog is debug compiled +# this "cannot" be done simply by using +# have_debug.inc +############################################# + +--disable_query_log +--let $temp_out_help_file=$MYSQL_TMP_DIR/mysqlbinlog_help.tmp +--exec $MYSQL_BINLOG --help>$temp_out_help_file +let log_tmp=$temp_out_help_file; +--let $temp_inc=$MYSQL_TMP_DIR/temp.inc +let inc_tmp=$temp_inc; + +--perl +use strict; +my $tmp_file= $ENV{'log_tmp'} or die "log_tmp not set"; +open(FILE, "$tmp_file") or die("Unable to open $tmp_file: $!\n"); +my $count = () = grep(/Output debug log/g,<FILE>); +close FILE; + +my $temp_inc= $ENV{'inc_tmp'} or die "temp_inc not set"; +open(FILE_INC,">", "$temp_inc") or die("can't open file \"$temp_inc\": $!"); +print FILE_INC '--let $is_debug= '.$count; +close FILE_INC; +EOF +--source $temp_inc + +if (!$is_debug) +{ + --skip mysqlbinlog needs to be debug compiled +} +--remove_file $temp_out_help_file +--remove_file $temp_inc +--enable_query_log diff --git a/mysql-test/r/create-big.result b/mysql-test/r/create-big.result index 34293d7e5cd..4cce5d8618c 100644 --- a/mysql-test/r/create-big.result +++ b/mysql-test/r/create-big.result @@ -53,8 +53,8 @@ set debug_sync='create_table_select_before_create SIGNAL parked WAIT_FOR go'; create table t1 select 1 as i;; set debug_sync='now WAIT_FOR parked'; alter table t3 rename to t1; -ERROR 42S01: Table 't1' already exists set debug_sync='now SIGNAL go'; +ERROR 42S01: Table 't1' already exists show create table t1; Table Create Table t1 CREATE TABLE `t1` ( @@ -65,8 +65,8 @@ set debug_sync='create_table_select_before_create SIGNAL parked WAIT_FOR go'; create table t1 select 1 as i;; set debug_sync='now WAIT_FOR parked'; alter table t3 rename to t1, add k int; -ERROR 42S01: Table 't1' already exists set debug_sync='now SIGNAL go'; +ERROR 42S01: Table 't1' already exists show create table t1; Table Create Table t1 CREATE TABLE `t1` ( diff --git a/mysql-test/r/ctype_binary.result b/mysql-test/r/ctype_binary.result index 1cb4b48ed69..c897108f793 100644 --- a/mysql-test/r/ctype_binary.result +++ b/mysql-test/r/ctype_binary.result @@ -2039,6 +2039,8 @@ hex(concat(a)) a 30303030303030303030303030303031303030302E31 00000000000000010000.1 drop table t1; create table t1 (a year(2)); +Warnings: +Note 1287 'YEAR(2)' is deprecated and will be removed in a future release. Please use YEAR(4) instead insert into t1 values (1); select hex(concat(a)) from t1; hex(concat(a)) @@ -2352,6 +2354,8 @@ hex(a) drop table t1; drop view v1; create table t1 (a year(2)); +Warnings: +Note 1287 'YEAR(2)' is deprecated and will be removed in a future release. Please use YEAR(4) instead insert into t1 values (1); create view v1(a) as select concat(a) from t1; show columns from v1; diff --git a/mysql-test/r/ctype_cp1251.result b/mysql-test/r/ctype_cp1251.result index 3d695a87701..5323469dff3 100644 --- a/mysql-test/r/ctype_cp1251.result +++ b/mysql-test/r/ctype_cp1251.result @@ -2431,6 +2431,8 @@ hex(concat(a)) a 30303030303030303030303030303031303030302E31 00000000000000010000.1 drop table t1; create table t1 (a year(2)); +Warnings: +Note 1287 'YEAR(2)' is deprecated and will be removed in a future release. Please use YEAR(4) instead insert into t1 values (1); select hex(concat(a)) from t1; hex(concat(a)) @@ -2744,6 +2746,8 @@ hex(a) drop table t1; drop view v1; create table t1 (a year(2)); +Warnings: +Note 1287 'YEAR(2)' is deprecated and will be removed in a future release. Please use YEAR(4) instead insert into t1 values (1); create view v1(a) as select concat(a) from t1; show columns from v1; diff --git a/mysql-test/r/ctype_latin1.result b/mysql-test/r/ctype_latin1.result index e2169e4e4e2..ae459fce8eb 100644 --- a/mysql-test/r/ctype_latin1.result +++ b/mysql-test/r/ctype_latin1.result @@ -2458,6 +2458,8 @@ hex(concat(a)) a 30303030303030303030303030303031303030302E31 00000000000000010000.1 drop table t1; create table t1 (a year(2)); +Warnings: +Note 1287 'YEAR(2)' is deprecated and will be removed in a future release. Please use YEAR(4) instead insert into t1 values (1); select hex(concat(a)) from t1; hex(concat(a)) @@ -2771,6 +2773,8 @@ hex(a) drop table t1; drop view v1; create table t1 (a year(2)); +Warnings: +Note 1287 'YEAR(2)' is deprecated and will be removed in a future release. Please use YEAR(4) instead insert into t1 values (1); create view v1(a) as select concat(a) from t1; show columns from v1; diff --git a/mysql-test/r/ctype_ucs.result b/mysql-test/r/ctype_ucs.result index 501b9cb611b..d463ce87c92 100644 --- a/mysql-test/r/ctype_ucs.result +++ b/mysql-test/r/ctype_ucs.result @@ -3341,6 +3341,8 @@ hex(concat(a)) a 00300030003000300030003000300030003000300030003000300030003000310030003000300030002E0031 00000000000000010000.1 drop table t1; create table t1 (a year(2)); +Warnings: +Note 1287 'YEAR(2)' is deprecated and will be removed in a future release. Please use YEAR(4) instead insert into t1 values (1); select hex(concat(a)) from t1; hex(concat(a)) @@ -3654,6 +3656,8 @@ hex(a) drop table t1; drop view v1; create table t1 (a year(2)); +Warnings: +Note 1287 'YEAR(2)' is deprecated and will be removed in a future release. Please use YEAR(4) instead insert into t1 values (1); create view v1(a) as select concat(a) from t1; show columns from v1; diff --git a/mysql-test/r/ctype_utf8.result b/mysql-test/r/ctype_utf8.result index 4dd9d787528..69e32977103 100644 --- a/mysql-test/r/ctype_utf8.result +++ b/mysql-test/r/ctype_utf8.result @@ -4197,6 +4197,8 @@ hex(concat(a)) a 30303030303030303030303030303031303030302E31 00000000000000010000.1 drop table t1; create table t1 (a year(2)); +Warnings: +Note 1287 'YEAR(2)' is deprecated and will be removed in a future release. Please use YEAR(4) instead insert into t1 values (1); select hex(concat(a)) from t1; hex(concat(a)) @@ -4510,6 +4512,8 @@ hex(a) drop table t1; drop view v1; create table t1 (a year(2)); +Warnings: +Note 1287 'YEAR(2)' is deprecated and will be removed in a future release. Please use YEAR(4) instead insert into t1 values (1); create view v1(a) as select concat(a) from t1; show columns from v1; diff --git a/mysql-test/r/func_group.result b/mysql-test/r/func_group.result index 3b47227a261..65323257300 100644 --- a/mysql-test/r/func_group.result +++ b/mysql-test/r/func_group.result @@ -1527,6 +1527,8 @@ DROP TABLE t1; # Bug#43668: Wrong comparison and MIN/MAX for YEAR(2) # create table t1 (f1 year(2), f2 year(4), f3 date, f4 datetime); +Warnings: +Note 1287 'YEAR(2)' is deprecated and will be removed in a future release. Please use YEAR(4) instead insert into t1 values (98,1998,19980101,"1998-01-01 00:00:00"), (00,2000,20000101,"2000-01-01 00:00:01"), diff --git a/mysql-test/r/mysqld--help.result b/mysql-test/r/mysqld--help.result index ad55bfa3003..63df79160cc 100644 --- a/mysql-test/r/mysqld--help.result +++ b/mysql-test/r/mysqld--help.result @@ -697,7 +697,7 @@ The following options may be given as the first argument: partial matching --rpl-recovery-rank=# Unused, will be removed - --safe-mode Skip some optimize stages (for testing). + --safe-mode Skip some optimize stages (for testing). Deprecated. --safe-user-create Don't allow new user creation by the user who has no write privileges to the mysql.user table. --secure-auth Disallow authentication for accounts that have old @@ -737,6 +737,9 @@ The following options may be given as the first argument: --slave-load-tmpdir=name The location where the slave should put its temporary files when replicating a LOAD DATA INFILE command + --slave-max-allowed-packet=# + The maximum packet length to sent successfully from the + master to slave. --slave-net-timeout=# Number of seconds to wait for more data from a master/slave connection before aborting the read @@ -1057,6 +1060,7 @@ skip-show-database FALSE skip-slave-start FALSE slave-compressed-protocol FALSE slave-exec-mode STRICT +slave-max-allowed-packet 1073741824 slave-net-timeout 3600 slave-skip-errors (No default value) slave-sql-verify-checksum TRUE diff --git a/mysql-test/r/mysqldump.result b/mysql-test/r/mysqldump.result index ff591c6cb69..7b650addd3d 100644 --- a/mysql-test/r/mysqldump.result +++ b/mysql-test/r/mysqldump.result @@ -2073,7 +2073,7 @@ DROP TABLE IF EXISTS `v2`; SET @saved_cs_client = @@character_set_client; SET character_set_client = utf8; /*!50001 CREATE TABLE `v2` ( - `a` varchar(30) + `a` tinyint NOT NULL ) ENGINE=MyISAM */; SET character_set_client = @saved_cs_client; /*!50001 DROP TABLE IF EXISTS `v2`*/; @@ -2167,7 +2167,7 @@ DROP TABLE IF EXISTS `v1`; SET @saved_cs_client = @@character_set_client; SET character_set_client = utf8; /*!50001 CREATE TABLE `v1` ( - `a` int(11) + `a` tinyint NOT NULL ) ENGINE=MyISAM */; SET character_set_client = @saved_cs_client; /*!50001 DROP TABLE IF EXISTS `v1`*/; @@ -2241,7 +2241,7 @@ DROP TABLE IF EXISTS `v2`; SET @saved_cs_client = @@character_set_client; SET character_set_client = utf8; /*!50001 CREATE TABLE `v2` ( - `a` varchar(30) + `a` tinyint NOT NULL ) ENGINE=MyISAM */; SET character_set_client = @saved_cs_client; /*!50001 DROP TABLE IF EXISTS `v2`*/; @@ -2355,9 +2355,9 @@ DROP TABLE IF EXISTS `v1`; SET @saved_cs_client = @@character_set_client; SET character_set_client = utf8; /*!50001 CREATE TABLE `v1` ( - `a` int(11), - `b` int(11), - `c` varchar(30) + `a` tinyint NOT NULL, + `b` tinyint NOT NULL, + `c` tinyint NOT NULL ) ENGINE=MyISAM */; SET character_set_client = @saved_cs_client; DROP TABLE IF EXISTS `v2`; @@ -2365,7 +2365,7 @@ DROP TABLE IF EXISTS `v2`; SET @saved_cs_client = @@character_set_client; SET character_set_client = utf8; /*!50001 CREATE TABLE `v2` ( - `a` int(11) + `a` tinyint NOT NULL ) ENGINE=MyISAM */; SET character_set_client = @saved_cs_client; DROP TABLE IF EXISTS `v3`; @@ -2373,9 +2373,9 @@ DROP TABLE IF EXISTS `v3`; SET @saved_cs_client = @@character_set_client; SET character_set_client = utf8; /*!50001 CREATE TABLE `v3` ( - `a` int(11), - `b` int(11), - `c` varchar(30) + `a` tinyint NOT NULL, + `b` tinyint NOT NULL, + `c` tinyint NOT NULL ) ENGINE=MyISAM */; SET character_set_client = @saved_cs_client; /*!50001 DROP TABLE IF EXISTS `v1`*/; @@ -3112,9 +3112,9 @@ DROP TABLE IF EXISTS `v0`; SET @saved_cs_client = @@character_set_client; SET character_set_client = utf8; /*!50001 CREATE TABLE `v0` ( - `a` int(11), - `b` varchar(32), - `c` varchar(32) + `a` tinyint NOT NULL, + `b` tinyint NOT NULL, + `c` tinyint NOT NULL ) ENGINE=MyISAM */; SET character_set_client = @saved_cs_client; DROP TABLE IF EXISTS `v1`; @@ -3122,9 +3122,9 @@ DROP TABLE IF EXISTS `v1`; SET @saved_cs_client = @@character_set_client; SET character_set_client = utf8; /*!50001 CREATE TABLE `v1` ( - `a` int(11), - `b` varchar(32), - `c` varchar(32) + `a` tinyint NOT NULL, + `b` tinyint NOT NULL, + `c` tinyint NOT NULL ) ENGINE=MyISAM */; SET character_set_client = @saved_cs_client; DROP TABLE IF EXISTS `v2`; @@ -3132,9 +3132,9 @@ DROP TABLE IF EXISTS `v2`; SET @saved_cs_client = @@character_set_client; SET character_set_client = utf8; /*!50001 CREATE TABLE `v2` ( - `a` int(11), - `b` varchar(32), - `c` varchar(32) + `a` tinyint NOT NULL, + `b` tinyint NOT NULL, + `c` tinyint NOT NULL ) ENGINE=MyISAM */; SET character_set_client = @saved_cs_client; @@ -3514,7 +3514,7 @@ DROP TABLE IF EXISTS `v1`; SET @saved_cs_client = @@character_set_client; SET character_set_client = utf8; /*!50001 CREATE TABLE `v1` ( - `id` int(11) + `id` tinyint NOT NULL ) ENGINE=MyISAM */; SET character_set_client = @saved_cs_client; @@ -3574,7 +3574,7 @@ USE `mysqldump_views`; SET @saved_cs_client = @@character_set_client; SET character_set_client = utf8; /*!50001 CREATE TABLE `nasishnasifu` ( - `id` bigint(20) unsigned + `id` tinyint NOT NULL ) ENGINE=MyISAM */; SET character_set_client = @saved_cs_client; @@ -3967,7 +3967,7 @@ DROP TABLE IF EXISTS `v2`; SET @saved_cs_client = @@character_set_client; SET character_set_client = utf8; /*!50001 CREATE TABLE `v2` ( - `c` int(11) + `c` tinyint NOT NULL ) ENGINE=MyISAM */; SET character_set_client = @saved_cs_client; /*!50001 DROP TABLE IF EXISTS `v2`*/; @@ -4384,7 +4384,7 @@ DROP TABLE IF EXISTS `v1`; SET @saved_cs_client = @@character_set_client; SET character_set_client = utf8; /*!50001 CREATE TABLE `v1` ( - `id` int(11) + `id` tinyint NOT NULL ) ENGINE=MyISAM */; SET character_set_client = @saved_cs_client; diff --git a/mysql-test/r/type_blob.result b/mysql-test/r/type_blob.result index fc2e0854620..723efbdcb23 100644 --- a/mysql-test/r/type_blob.result +++ b/mysql-test/r/type_blob.result @@ -878,6 +878,8 @@ ERROR 42000: Column length too big for column 'a' (max = 255); use BLOB or TEXT CREATE TABLE b15776 (a char(4294967296)); ERROR 42000: Display width out of range for 'a' (max = 4294967295) CREATE TABLE b15776 (a year(4294967295)); +Warnings: +Note 1287 'YEAR(4294967295)' is deprecated and will be removed in a future release. Please use YEAR(4) instead INSERT INTO b15776 VALUES (42); SELECT * FROM b15776; a @@ -886,6 +888,8 @@ DROP TABLE b15776; CREATE TABLE b15776 (a year(4294967296)); ERROR 42000: Display width out of range for 'a' (max = 4294967295) CREATE TABLE b15776 (a year(0)); +Warnings: +Note 1287 'YEAR(0)' is deprecated and will be removed in a future release. Please use YEAR(4) instead DROP TABLE b15776; CREATE TABLE b15776 (a year(-2)); ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near '-2))' at line 1 diff --git a/mysql-test/r/type_year.result b/mysql-test/r/type_year.result index 5d89a1ee407..4b9bf6f433f 100644 --- a/mysql-test/r/type_year.result +++ b/mysql-test/r/type_year.result @@ -1,5 +1,7 @@ drop table if exists t1; create table t1 (y year,y2 year(2)); +Warnings: +Note 1287 'YEAR(2)' is deprecated and will be removed in a future release. Please use YEAR(4) instead insert into t1 values (0,0),(1999,1999),(2000,2000),(2001,2001),(70,70),(69,69); select * from t1; y y2 @@ -50,6 +52,8 @@ End of 5.0 tests # Bug #49480: WHERE using YEAR columns returns unexpected results # CREATE TABLE t2(yy YEAR(2), c2 CHAR(4)); +Warnings: +Note 1287 'YEAR(2)' is deprecated and will be removed in a future release. Please use YEAR(4) instead CREATE TABLE t4(yyyy YEAR(4), c4 CHAR(4)); INSERT INTO t2 (c2) VALUES (NULL),(1970),(1999),(2000),(2001),(2069); INSERT INTO t4 (c4) SELECT c2 FROM t2; @@ -358,9 +362,22 @@ total_rows min_value MAX(c1+0) 3 0 2155 DROP TABLE t1; # +# WL#6219: Deprecate and remove YEAR(2) type +# +CREATE TABLE t1 (c1 YEAR(2), c2 YEAR(4)); +Warnings: +Note 1287 'YEAR(2)' is deprecated and will be removed in a future release. Please use YEAR(4) instead +ALTER TABLE t1 MODIFY COLUMN c2 YEAR(2); +Warnings: +Note 1287 'YEAR(2)' is deprecated and will be removed in a future release. Please use YEAR(4) instead +Note 1287 'YEAR(2)' is deprecated and will be removed in a future release. Please use YEAR(4) instead +DROP TABLE t1; +# End of 5.1 tests create function y2k() returns int deterministic return 2000; create table t1 (a year(2), b int); +Warnings: +Note 1287 'YEAR(2)' is deprecated and will be removed in a future release. Please use YEAR(4) instead insert t1 values (0,2000); select a from t1 where a=2000; a diff --git a/mysql-test/suite/engines/iuds/r/delete_year.result b/mysql-test/suite/engines/iuds/r/delete_year.result index 02cbe24ecc9..c82f0dae7d9 100644 --- a/mysql-test/suite/engines/iuds/r/delete_year.result +++ b/mysql-test/suite/engines/iuds/r/delete_year.result @@ -2,7 +2,13 @@ DROP TABLE IF EXISTS t1,t2,t3,t4; CREATE TABLE t1(c1 YEAR NOT NULL,c2 YEAR, PRIMARY KEY(c1)); CREATE TABLE t2(c1 YEAR NOT NULL, c2 YEAR, UNIQUE INDEX idx(c1,c2)); CREATE TABLE t3(c1 YEAR(2) NOT NULL,c2 YEAR(2), PRIMARY KEY(c1)); +Warnings: +Note 1287 'YEAR(2)' is deprecated and will be removed in a future release. Please use YEAR(4) instead +Note 1287 'YEAR(2)' is deprecated and will be removed in a future release. Please use YEAR(4) instead CREATE TABLE t4(c1 YEAR(2), c2 YEAR(2), UNIQUE INDEX idx(c1,c2)); +Warnings: +Note 1287 'YEAR(2)' is deprecated and will be removed in a future release. Please use YEAR(4) instead +Note 1287 'YEAR(2)' is deprecated and will be removed in a future release. Please use YEAR(4) instead INSERT INTO t1 VALUES (1901,1901),(1970,1970),(1999,1999),(2000,2000),(2155,2155); INSERT INTO t2 VALUES (1901,1901),(1970,1970),(1999,1999),(2000,2000),(2155,2155); INSERT INTO t3 VALUES (1901,1901),(1970,1970),(1999,1999),(2000,2000),(2155,2155); diff --git a/mysql-test/suite/engines/iuds/r/insert_year.result b/mysql-test/suite/engines/iuds/r/insert_year.result index 386c8090434..b9618ba4e2d 100644 --- a/mysql-test/suite/engines/iuds/r/insert_year.result +++ b/mysql-test/suite/engines/iuds/r/insert_year.result @@ -3235,9 +3235,21 @@ c1 c2 c3 c4 1999 1999 1998-12-30 1998-12-30 11:30:45 DROP TABLE t1,t2,t3,t4; CREATE TABLE t1(c1 YEAR(2) NOT NULL, c2 YEAR(2) NULL, c3 DATE, c4 DATETIME, PRIMARY KEY(c1), UNIQUE INDEX(c2)); +Warnings: +Note 1287 'YEAR(2)' is deprecated and will be removed in a future release. Please use YEAR(4) instead +Note 1287 'YEAR(2)' is deprecated and will be removed in a future release. Please use YEAR(4) instead CREATE TABLE t2(c1 YEAR(2) NOT NULL, c2 YEAR(2) NULL, c3 DATE, c4 DATETIME, PRIMARY KEY(c1,c2)); +Warnings: +Note 1287 'YEAR(2)' is deprecated and will be removed in a future release. Please use YEAR(4) instead +Note 1287 'YEAR(2)' is deprecated and will be removed in a future release. Please use YEAR(4) instead CREATE TABLE t3(c1 YEAR(2) NOT NULL, c2 YEAR(2) NULL, c3 DATE, c4 DATETIME, UNIQUE INDEX idx(c1,c2)); +Warnings: +Note 1287 'YEAR(2)' is deprecated and will be removed in a future release. Please use YEAR(4) instead +Note 1287 'YEAR(2)' is deprecated and will be removed in a future release. Please use YEAR(4) instead CREATE TABLE t4(c1 YEAR(2) NOT NULL, c2 YEAR(2) NULL, c3 DATE, c4 DATETIME); +Warnings: +Note 1287 'YEAR(2)' is deprecated and will be removed in a future release. Please use YEAR(4) instead +Note 1287 'YEAR(2)' is deprecated and will be removed in a future release. Please use YEAR(4) instead INSERT INTO t1 VALUES('1901','1901','98-12-31','98.12.31 11:30:45'),('1999','1999','98-12-30','98.12.30 11:30:45'),('2000','2000','98-12-29','98.12.29 11:30:45'),('2001','2001','98-12-28','98.12.28 11:30:45'),('2099','2099','98-12-27','98.12.27 11:30:45'),('2100','2100','98-12-26','98.12.26 11:30:45'),('2155','2155','98-12-26','98.12.26 11:30:45'); INSERT INTO t2 VALUES('1901','1901','98-12-31','98.12.31 11:30:45'),('1999','1999','98-12-30','98.12.30 11:30:45'),('2000','2000','98-12-29','98.12.29 11:30:45'),('2001','2001','98-12-28','98.12.28 11:30:45'),('2099','2099','98-12-27','98.12.27 11:30:45'),('2100','2100','98-12-26','98.12.26 11:30:45'),('2155','2155','98-12-26','98.12.26 11:30:45'); INSERT INTO t3 VALUES('1901','1901','98-12-31','98.12.31 11:30:45'),('1999','1999','98-12-30','98.12.30 11:30:45'),('2000','2000','98-12-29','98.12.29 11:30:45'),('2001','2001','98-12-28','98.12.28 11:30:45'),('2099','2099','98-12-27','98.12.27 11:30:45'),('2100','2100','98-12-26','98.12.26 11:30:45'),('2155','2155','98-12-26','98.12.26 11:30:45'); diff --git a/mysql-test/suite/engines/iuds/r/update_year.result b/mysql-test/suite/engines/iuds/r/update_year.result index 1b0ead45314..c762d70a276 100644 --- a/mysql-test/suite/engines/iuds/r/update_year.result +++ b/mysql-test/suite/engines/iuds/r/update_year.result @@ -2,7 +2,13 @@ DROP TABLE IF EXISTS t1,t2,t3,t4; CREATE TABLE t1(c1 YEAR NOT NULL,c2 YEAR, PRIMARY KEY(c1)); CREATE TABLE t2(c1 YEAR NOT NULL, c2 YEAR, UNIQUE INDEX idx(c1,c2)); CREATE TABLE t3(c1 YEAR(2) NOT NULL,c2 YEAR(2), PRIMARY KEY(c1)); +Warnings: +Note 1287 'YEAR(2)' is deprecated and will be removed in a future release. Please use YEAR(4) instead +Note 1287 'YEAR(2)' is deprecated and will be removed in a future release. Please use YEAR(4) instead CREATE TABLE t4(c1 YEAR(2), c2 YEAR(2), UNIQUE INDEX idx(c1,c2)); +Warnings: +Note 1287 'YEAR(2)' is deprecated and will be removed in a future release. Please use YEAR(4) instead +Note 1287 'YEAR(2)' is deprecated and will be removed in a future release. Please use YEAR(4) instead INSERT INTO t1 VALUES (1901,1901),(1970,1970),(1999,1999),(2000,2000),(2155,2155); INSERT INTO t2 VALUES (1901,1901),(1970,1970),(1999,1999),(2000,2000),(2155,2155); INSERT INTO t3 VALUES (1901,1901),(1970,1970),(1999,1999),(2000,2000),(2155,2155); diff --git a/mysql-test/suite/funcs_1/r/innodb_views.result b/mysql-test/suite/funcs_1/r/innodb_views.result index d9cd0f1e7f8..b50f5640520 100644 --- a/mysql-test/suite/funcs_1/r/innodb_views.result +++ b/mysql-test/suite/funcs_1/r/innodb_views.result @@ -53,6 +53,8 @@ f107 year(4) not null default 2000, f108 enum("1enum","2enum") not null default "1enum", f109 set("1set","2set") not null default "1set" ) engine = innodb; +Warnings: +Note 1287 'YEAR(3)' is deprecated and will be removed in a future release. Please use YEAR(4) instead load data infile '<MYSQLTEST_VARDIR>/std_data/funcs_1/innodb_tb2.txt' into table tb2; DROP DATABASE IF EXISTS test1; @@ -112,6 +114,8 @@ f107 year(4) not null default 2000, f108 enum("1enum","2enum") not null default "1enum", f109 set("1set","2set") not null default "1set" ) engine = innodb; +Warnings: +Note 1287 'YEAR(3)' is deprecated and will be removed in a future release. Please use YEAR(4) instead load data infile '<MYSQLTEST_VARDIR>/std_data/funcs_1/innodb_tb2.txt' into table tb2; USE test; diff --git a/mysql-test/suite/funcs_1/r/is_columns_innodb.result b/mysql-test/suite/funcs_1/r/is_columns_innodb.result index f3d3c6b7bad..085017fb529 100644 --- a/mysql-test/suite/funcs_1/r/is_columns_innodb.result +++ b/mysql-test/suite/funcs_1/r/is_columns_innodb.result @@ -132,6 +132,8 @@ f107 year(4) not null default 2000, f108 enum("1enum","2enum") not null default "1enum", f109 set("1set","2set") not null default "1set" ) engine = innodb; +Warnings: +Note 1287 'YEAR(3)' is deprecated and will be removed in a future release. Please use YEAR(4) instead load data infile '<MYSQLTEST_VARDIR>/std_data/funcs_1/innodb_tb2.txt' into table tb2; drop table if exists tb3 ; @@ -262,6 +264,8 @@ f239 varchar(20000) binary, f240 varchar(2000), f241 char(100) ) engine = innodb; +Warnings: +Note 1287 'YEAR(3)' is deprecated and will be removed in a future release. Please use YEAR(4) instead load data infile '<MYSQLTEST_VARDIR>/std_data/funcs_1/innodb_tb4.txt' into table tb4; USE test1; @@ -319,6 +323,8 @@ f107 year(4) not null default 2000, f108 enum("1enum","2enum") not null default "1enum", f109 set("1set","2set") not null default "1set" ) engine = innodb; +Warnings: +Note 1287 'YEAR(3)' is deprecated and will be removed in a future release. Please use YEAR(4) instead load data infile '<MYSQLTEST_VARDIR>/std_data/funcs_1/innodb_tb2.txt' into table tb2; USE test; diff --git a/mysql-test/suite/funcs_1/r/is_columns_memory.result b/mysql-test/suite/funcs_1/r/is_columns_memory.result index 39a5dcd0b0c..7521a9857a6 100644 --- a/mysql-test/suite/funcs_1/r/is_columns_memory.result +++ b/mysql-test/suite/funcs_1/r/is_columns_memory.result @@ -128,6 +128,8 @@ f107 year(4) not null default 2000, f108 enum("1enum","2enum") not null default "1enum", f109 set("1set","2set") not null default "1set" ) engine = memory; +Warnings: +Note 1287 'YEAR(3)' is deprecated and will be removed in a future release. Please use YEAR(4) instead load data infile '<MYSQLTEST_VARDIR>/std_data/funcs_1/memory_tb2.txt' into table tb2 ; drop table if exists tb3; @@ -251,6 +253,8 @@ f238 varchar(25000) binary, f239 varbinary(0), f240 varchar(1200) ) engine = memory; +Warnings: +Note 1287 'YEAR(3)' is deprecated and will be removed in a future release. Please use YEAR(4) instead load data infile '<MYSQLTEST_VARDIR>/std_data/funcs_1/memory_tb4.txt' into table tb4; USE test1; @@ -308,6 +312,8 @@ f107 year(4) not null default 2000, f108 enum("1enum","2enum") not null default "1enum", f109 set("1set","2set") not null default "1set" ) engine = memory; +Warnings: +Note 1287 'YEAR(3)' is deprecated and will be removed in a future release. Please use YEAR(4) instead load data infile '<MYSQLTEST_VARDIR>/std_data/funcs_1/memory_tb2.txt' into table tb2 ; USE test; diff --git a/mysql-test/suite/funcs_1/r/is_columns_myisam.result b/mysql-test/suite/funcs_1/r/is_columns_myisam.result index 03af4ebb89f..6c2586cc3c1 100644 --- a/mysql-test/suite/funcs_1/r/is_columns_myisam.result +++ b/mysql-test/suite/funcs_1/r/is_columns_myisam.result @@ -144,6 +144,8 @@ f115 VARBINARY(27) null , f116 VARBINARY(64) null, f117 VARBINARY(192) null ) engine = myisam; +Warnings: +Note 1287 'YEAR(3)' is deprecated and will be removed in a future release. Please use YEAR(4) instead load data infile '<MYSQLTEST_VARDIR>/std_data/funcs_1/myisam_tb2.txt' into table tb2; drop table if exists tb3 ; @@ -283,6 +285,8 @@ f240 varchar(120), f241 char(100), f242 bit(30) ) engine = myisam; +Warnings: +Note 1287 'YEAR(3)' is deprecated and will be removed in a future release. Please use YEAR(4) instead load data infile '<MYSQLTEST_VARDIR>/std_data/funcs_1/myisam_tb4.txt' into table tb4; USE test1; @@ -348,6 +352,8 @@ f115 VARBINARY(27) null , f116 VARBINARY(64) null, f117 VARBINARY(192) null ) engine = myisam; +Warnings: +Note 1287 'YEAR(3)' is deprecated and will be removed in a future release. Please use YEAR(4) instead load data infile '<MYSQLTEST_VARDIR>/std_data/funcs_1/myisam_tb2.txt' into table tb2; USE test; diff --git a/mysql-test/suite/funcs_1/r/is_columns_myisam_embedded.result b/mysql-test/suite/funcs_1/r/is_columns_myisam_embedded.result index dd8e508e821..150469a4a2f 100644 --- a/mysql-test/suite/funcs_1/r/is_columns_myisam_embedded.result +++ b/mysql-test/suite/funcs_1/r/is_columns_myisam_embedded.result @@ -144,6 +144,8 @@ f115 VARBINARY(27) null , f116 VARBINARY(64) null, f117 VARBINARY(192) null ) engine = myisam; +Warnings: +Note 1287 'YEAR(3)' is deprecated and will be removed in a future release. Please use YEAR(4) instead load data infile '<MYSQLTEST_VARDIR>/std_data/funcs_1/myisam_tb2.txt' into table tb2; drop table if exists tb3 ; @@ -283,6 +285,8 @@ f240 varchar(120), f241 char(100), f242 bit(30) ) engine = myisam; +Warnings: +Note 1287 'YEAR(3)' is deprecated and will be removed in a future release. Please use YEAR(4) instead load data infile '<MYSQLTEST_VARDIR>/std_data/funcs_1/myisam_tb4.txt' into table tb4; USE test1; @@ -348,6 +352,8 @@ f115 VARBINARY(27) null , f116 VARBINARY(64) null, f117 VARBINARY(192) null ) engine = myisam; +Warnings: +Note 1287 'YEAR(3)' is deprecated and will be removed in a future release. Please use YEAR(4) instead load data infile '<MYSQLTEST_VARDIR>/std_data/funcs_1/myisam_tb2.txt' into table tb2; USE test; diff --git a/mysql-test/suite/funcs_1/r/memory_views.result b/mysql-test/suite/funcs_1/r/memory_views.result index 864cbb93b29..a718f986648 100644 --- a/mysql-test/suite/funcs_1/r/memory_views.result +++ b/mysql-test/suite/funcs_1/r/memory_views.result @@ -54,6 +54,8 @@ f107 year(4) not null default 2000, f108 enum("1enum","2enum") not null default "1enum", f109 set("1set","2set") not null default "1set" ) engine = memory; +Warnings: +Note 1287 'YEAR(3)' is deprecated and will be removed in a future release. Please use YEAR(4) instead load data infile '<MYSQLTEST_VARDIR>/std_data/funcs_1/memory_tb2.txt' into table tb2 ; DROP DATABASE IF EXISTS test1; @@ -113,6 +115,8 @@ f107 year(4) not null default 2000, f108 enum("1enum","2enum") not null default "1enum", f109 set("1set","2set") not null default "1set" ) engine = memory; +Warnings: +Note 1287 'YEAR(3)' is deprecated and will be removed in a future release. Please use YEAR(4) instead load data infile '<MYSQLTEST_VARDIR>/std_data/funcs_1/memory_tb2.txt' into table tb2 ; USE test; diff --git a/mysql-test/suite/funcs_1/r/myisam_views-big.result b/mysql-test/suite/funcs_1/r/myisam_views-big.result index f4025dfef2a..1ee9c6e0cd6 100644 --- a/mysql-test/suite/funcs_1/r/myisam_views-big.result +++ b/mysql-test/suite/funcs_1/r/myisam_views-big.result @@ -62,6 +62,8 @@ f115 VARBINARY(27) null , f116 VARBINARY(64) null, f117 VARBINARY(192) null ) engine = myisam; +Warnings: +Note 1287 'YEAR(3)' is deprecated and will be removed in a future release. Please use YEAR(4) instead load data infile '<MYSQLTEST_VARDIR>/std_data/funcs_1/myisam_tb2.txt' into table tb2; DROP DATABASE IF EXISTS test1; @@ -129,6 +131,8 @@ f115 VARBINARY(27) null , f116 VARBINARY(64) null, f117 VARBINARY(192) null ) engine = myisam; +Warnings: +Note 1287 'YEAR(3)' is deprecated and will be removed in a future release. Please use YEAR(4) instead load data infile '<MYSQLTEST_VARDIR>/std_data/funcs_1/myisam_tb2.txt' into table tb2; USE test; diff --git a/mysql-test/suite/funcs_1/r/storedproc.result b/mysql-test/suite/funcs_1/r/storedproc.result index 7b45ec4c9e1..179d0cd814e 100644 --- a/mysql-test/suite/funcs_1/r/storedproc.result +++ b/mysql-test/suite/funcs_1/r/storedproc.result @@ -7499,9 +7499,13 @@ BEGIN declare x, y, z year(3) default 2005; SELECT x, y, z; END// +Warnings: +Note 1287 'YEAR(3)' is deprecated and will be removed in a future release. Please use YEAR(4) instead CALL sp1(); x y z 2005 2005 2005 +Warnings: +Note 1287 'YEAR(3)' is deprecated and will be removed in a future release. Please use YEAR(4) instead DROP PROCEDURE IF EXISTS sp1; CREATE PROCEDURE sp1( ) BEGIN diff --git a/mysql-test/suite/innodb/r/innodb_bug52745.result b/mysql-test/suite/innodb/r/innodb_bug52745.result index 74db8b0c20a..927ba0e0e53 100644 --- a/mysql-test/suite/innodb/r/innodb_bug52745.result +++ b/mysql-test/suite/innodb/r/innodb_bug52745.result @@ -58,6 +58,7 @@ col89 float unsigned zerofill DEFAULT NULL, col90 tinyblob ) ENGINE=InnoDB DEFAULT CHARSET=latin1 ROW_FORMAT=COMPRESSED KEY_BLOCK_SIZE=1; Warnings: +Note 1287 'YEAR(2)' is deprecated and will be removed in a future release. Please use YEAR(4) instead Note 1291 Column 'col82' has duplicated value '' in ENUM Note 1291 Column 'col82' has duplicated value '' in ENUM INSERT INTO bug52745 SET diff --git a/mysql-test/suite/perfschema/disabled.def b/mysql-test/suite/perfschema/disabled.def index 8cae44a3607..8a843692d2a 100644 --- a/mysql-test/suite/perfschema/disabled.def +++ b/mysql-test/suite/perfschema/disabled.def @@ -9,4 +9,4 @@ # Do not use any TAB characters for whitespace. # ############################################################################## - +misc : bug#14113704 24/04/2012 Mayank issue reported causing failure. diff --git a/mysql-test/suite/perfschema/r/func_file_io.result b/mysql-test/suite/perfschema/r/func_file_io.result index d99e77dcd8c..c95fae94803 100644 --- a/mysql-test/suite/perfschema/r/func_file_io.result +++ b/mysql-test/suite/perfschema/r/func_file_io.result @@ -15,6 +15,9 @@ SET @before_count = (SELECT SUM(TIMER_WAIT) FROM performance_schema.events_waits_history_long WHERE (EVENT_NAME = 'wait/io/file/myisam/dfile') AND (OBJECT_NAME LIKE '%t1.MYD')); +SELECT (@before_count >= 0) as have_before_count; +have_before_count +1 SELECT IF(@before_count > 0, 'Success', 'Failure') has_instrumentation; has_instrumentation Success @@ -27,6 +30,9 @@ SET @after_count = (SELECT SUM(TIMER_WAIT) FROM performance_schema.events_waits_history_long WHERE (EVENT_NAME = 'wait/io/file/myisam/dfile') AND (OBJECT_NAME LIKE '%t1.MYD') AND (1 = 1)); +SELECT (@after_count >= 0) as have_after_count; +have_after_count +1 SELECT IF((@after_count - @before_count) > 0, 'Success', 'Failure') test_ff1_timed; test_ff1_timed Success @@ -35,6 +41,9 @@ SET @before_count = (SELECT SUM(TIMER_WAIT) FROM performance_schema.events_waits_history_long WHERE (EVENT_NAME = 'wait/io/file/myisam/dfile') AND (OBJECT_NAME LIKE '%t1.MYD') AND (2 = 2)); +SELECT (@before_count >= 0) as have_before_count; +have_before_count +1 SELECT * FROM t1 WHERE id < 6; id b 1 initial value @@ -46,6 +55,9 @@ SET @after_count = (SELECT SUM(TIMER_WAIT) FROM performance_schema.events_waits_history_long WHERE (EVENT_NAME = 'wait/io/file/myisam/dfile') AND (OBJECT_NAME LIKE '%t1.MYD') AND (3 = 3)); +SELECT (@after_count >= 0) as have_after_count; +have_after_count +1 SELECT IF((COALESCE(@after_count, 0) - COALESCE(@before_count, 0)) = 0, 'Success', 'Failure') test_ff2_timed; test_ff2_timed Success diff --git a/mysql-test/suite/perfschema/r/query_cache.result b/mysql-test/suite/perfschema/r/query_cache.result index c49cb7b718e..8786cd055ca 100644 --- a/mysql-test/suite/perfschema/r/query_cache.result +++ b/mysql-test/suite/perfschema/r/query_cache.result @@ -36,9 +36,9 @@ Qcache_hits 1 select spins from performance_schema.events_waits_current order by event_name limit 1; spins NULL -select name from performance_schema.setup_instruments order by name limit 1; -name -wait/io/file/aria/control +select * from performance_schema.setup_timers where name='wait'; +NAME TIMER_NAME +wait CYCLE show status like "Qcache_queries_in_cache"; Variable_name Value Qcache_queries_in_cache 1 @@ -51,9 +51,9 @@ Qcache_hits 1 select spins from performance_schema.events_waits_current order by event_name limit 1; spins NULL -select name from performance_schema.setup_instruments order by name limit 1; -name -wait/io/file/aria/control +select * from performance_schema.setup_timers where name='wait'; +NAME TIMER_NAME +wait CYCLE show status like "Qcache_queries_in_cache"; Variable_name Value Qcache_queries_in_cache 1 diff --git a/mysql-test/suite/perfschema/t/func_file_io.test b/mysql-test/suite/perfschema/t/func_file_io.test index bcf29a7daa2..e8b01a10bd1 100644 --- a/mysql-test/suite/perfschema/t/func_file_io.test +++ b/mysql-test/suite/perfschema/t/func_file_io.test @@ -41,6 +41,7 @@ SET @before_count = (SELECT SUM(TIMER_WAIT) WHERE (EVENT_NAME = 'wait/io/file/myisam/dfile') AND (OBJECT_NAME LIKE '%t1.MYD')); +SELECT (@before_count >= 0) as have_before_count; SELECT IF(@before_count > 0, 'Success', 'Failure') has_instrumentation; SELECT * FROM t1 WHERE id < 4; @@ -50,6 +51,7 @@ SET @after_count = (SELECT SUM(TIMER_WAIT) WHERE (EVENT_NAME = 'wait/io/file/myisam/dfile') AND (OBJECT_NAME LIKE '%t1.MYD') AND (1 = 1)); +SELECT (@after_count >= 0) as have_after_count; SELECT IF((@after_count - @before_count) > 0, 'Success', 'Failure') test_ff1_timed; UPDATE performance_schema.setup_instruments SET enabled='NO'; @@ -59,6 +61,7 @@ SET @before_count = (SELECT SUM(TIMER_WAIT) WHERE (EVENT_NAME = 'wait/io/file/myisam/dfile') AND (OBJECT_NAME LIKE '%t1.MYD') AND (2 = 2)); +SELECT (@before_count >= 0) as have_before_count; SELECT * FROM t1 WHERE id < 6; SET @after_count = (SELECT SUM(TIMER_WAIT) @@ -66,6 +69,7 @@ SET @after_count = (SELECT SUM(TIMER_WAIT) WHERE (EVENT_NAME = 'wait/io/file/myisam/dfile') AND (OBJECT_NAME LIKE '%t1.MYD') AND (3 = 3)); +SELECT (@after_count >= 0) as have_after_count; SELECT IF((COALESCE(@after_count, 0) - COALESCE(@before_count, 0)) = 0, 'Success', 'Failure') test_ff2_timed; # diff --git a/mysql-test/suite/perfschema/t/query_cache.test b/mysql-test/suite/perfschema/t/query_cache.test index 8c9e5fcd0ed..60d4a648222 100644 --- a/mysql-test/suite/perfschema/t/query_cache.test +++ b/mysql-test/suite/perfschema/t/query_cache.test @@ -34,7 +34,7 @@ show status like "Qcache_hits"; select spins from performance_schema.events_waits_current order by event_name limit 1; -select name from performance_schema.setup_instruments order by name limit 1; +select * from performance_schema.setup_timers where name='wait'; show status like "Qcache_queries_in_cache"; show status like "Qcache_inserts"; @@ -42,7 +42,7 @@ show status like "Qcache_hits"; select spins from performance_schema.events_waits_current order by event_name limit 1; -select name from performance_schema.setup_instruments order by name limit 1; +select * from performance_schema.setup_timers where name='wait'; show status like "Qcache_queries_in_cache"; show status like "Qcache_inserts"; diff --git a/mysql-test/suite/rpl/r/rpl_filter_tables_not_exist.result b/mysql-test/suite/rpl/r/rpl_filter_tables_not_exist.result index fcd03ea74b8..baf0cf81cec 100644 --- a/mysql-test/suite/rpl/r/rpl_filter_tables_not_exist.result +++ b/mysql-test/suite/rpl/r/rpl_filter_tables_not_exist.result @@ -114,22 +114,23 @@ id c 3 3 [on master] drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9; -CREATE TABLE test.t5 (a INT AUTO_INCREMENT PRIMARY KEY, b INT, c INT); +CREATE TABLE test.t5 (a INT AUTO_INCREMENT PRIMARY KEY, b DECIMAL(20,20), c INT); CREATE TABLE test.t1 (a INT); INSERT INTO test.t1 VALUES(1); call mtr.add_suppression("Unsafe statement written to the binary log using statement format since BINLOG_FORMAT = STATEMENT"); -CREATE TABLE test.t_slave (a INT AUTO_INCREMENT PRIMARY KEY, b INT, c INT); +CREATE TABLE test.t_slave (a INT AUTO_INCREMENT PRIMARY KEY, b DECIMAL(20,20), c INT); CREATE TRIGGER t1_update AFTER UPDATE ON test.t1 FOR EACH ROW -INSERT INTO test.t_slave VALUES(NULL, ROUND(RAND() * 1000), @c); +INSERT INTO test.t_slave VALUES(NULL, RAND(), @c); SET INSERT_ID=2; SET @c=2; SET @@rand_seed1=10000000, @@rand_seed2=1000000; -INSERT INTO t5 VALUES (NULL, ROUND(RAND() * 1000), @c); +INSERT INTO t5 VALUES (NULL, RAND(), @c); SELECT b into @b FROM test.t5; UPDATE test.t1 SET a=2; SELECT a AS 'ONE' into @a FROM test.t_slave; SELECT c AS 'NULL' into @c FROM test.t_slave; SELECT b into @b FROM test.t_slave; +include/assert.inc [Random values from master and slave must be different] drop table test.t5; drop table test.t1; drop table test.t_slave; diff --git a/mysql-test/suite/rpl/r/rpl_log_pos.result b/mysql-test/suite/rpl/r/rpl_log_pos.result index 8910f7c8f74..610d18a88c6 100644 --- a/mysql-test/suite/rpl/r/rpl_log_pos.result +++ b/mysql-test/suite/rpl/r/rpl_log_pos.result @@ -11,7 +11,7 @@ include/stop_slave.inc change master to master_log_pos=MASTER_LOG_POS; start slave; include/wait_for_slave_io_error.inc [errno=1236] -Last_IO_Error = 'Got fatal error 1236 from master when reading data from binary log: 'log event entry exceeded max_allowed_packet; Increase max_allowed_packet on master; the first event 'master-bin.000001' at XXX, the last event read from 'master-bin.000001' at XXX, the last byte read from 'master-bin.000001' at XXX.'' +Last_IO_Error = 'Got fatal error 1236 from master when reading data from binary log: 'binlog truncated in the middle of event; consider out of disk space on master; the first event 'master-bin.000001' at XXX, the last event read from 'master-bin.000001' at XXX, the last byte read from 'master-bin.000001' at XXX.'' include/stop_slave_sql.inc show master status; File Position Binlog_Do_DB Binlog_Ignore_DB diff --git a/mysql-test/suite/rpl/r/rpl_packet.result b/mysql-test/suite/rpl/r/rpl_packet.result index 4d5ffae2d63..65fd2800e7d 100644 --- a/mysql-test/suite/rpl/r/rpl_packet.result +++ b/mysql-test/suite/rpl/r/rpl_packet.result @@ -1,7 +1,7 @@ include/master-slave.inc [connection master] -call mtr.add_suppression("Slave I/O: Got a packet bigger than 'max_allowed_packet' bytes, Error_code: 1153"); -call mtr.add_suppression("Slave I/O: Got fatal error 1236 from master when reading data from binary log:"); +call mtr.add_suppression("Slave I/O: Got a packet bigger than 'slave_max_allowed_packet' bytes, Error_code: 1153"); +call mtr.add_suppression("Log entry on master is longer than slave_max_allowed_packet"); drop database if exists DB_NAME_OF_MAX_LENGTH_AKA_NAME_LEN_64_BYTES_____________________; create database DB_NAME_OF_MAX_LENGTH_AKA_NAME_LEN_64_BYTES_____________________; SET @@global.max_allowed_packet=1024; @@ -30,14 +30,14 @@ include/start_slave.inc CREATE TABLE `t1` (`f1` LONGTEXT) ENGINE=MyISAM; INSERT INTO `t1`(`f1`) VALUES ('aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa2048'); include/wait_for_slave_io_error.inc [errno=1153] -Last_IO_Error = 'Got a packet bigger than 'max_allowed_packet' bytes' +Last_IO_Error = 'Got a packet bigger than 'slave_max_allowed_packet' bytes' include/stop_slave_sql.inc include/rpl_reset.inc DROP TABLE t1; CREATE TABLE t1 (f1 int PRIMARY KEY, f2 LONGTEXT, f3 LONGTEXT) ENGINE=MyISAM; INSERT INTO t1(f1, f2, f3) VALUES(1, REPEAT('a', @@global.max_allowed_packet), REPEAT('b', @@global.max_allowed_packet)); -include/wait_for_slave_io_error.inc [errno=1236] -Last_IO_Error = 'Got fatal error 1236 from master when reading data from binary log: 'log event entry exceeded max_allowed_packet; Increase max_allowed_packet on master; the first event '.' at XXX, the last event read from 'master-bin.000001' at XXX, the last byte read from 'master-bin.000001' at XXX.'' +include/wait_for_slave_io_error.inc [errno=1153] +Last_IO_Error = 'Got a packet bigger than 'slave_max_allowed_packet' bytes' STOP SLAVE; RESET SLAVE; RESET MASTER; @@ -52,6 +52,7 @@ SET @@global.max_allowed_packet= 1024; Warnings: Warning 1708 The value of 'max_allowed_packet' should be no less than the value of 'net_buffer_length' SET @@global.net_buffer_length= 1024; +SET @@global.slave_max_allowed_packet= 1073741824; DROP TABLE t1; RESET SLAVE; include/rpl_end.inc diff --git a/mysql-test/suite/rpl/r/rpl_trigger.result b/mysql-test/suite/rpl/r/rpl_trigger.result index 784cd1bcdff..ac6d9155f4b 100644 --- a/mysql-test/suite/rpl/r/rpl_trigger.result +++ b/mysql-test/suite/rpl/r/rpl_trigger.result @@ -4,7 +4,7 @@ DROP TABLE IF EXISTS t1; DROP TABLE IF EXISTS t2; DROP TABLE IF EXISTS t3; create table t1 (a int auto_increment, primary key (a), b int, rand_value double not null); -create table t2 (a int auto_increment, primary key (a), b int); +create table t2 (a int auto_increment, primary key (a), b int) engine=innodb; create table t3 (a int auto_increment, primary key (a), name varchar(64) not null, old_a int, old_b int, rand_value double not null); create trigger t1 before insert on t1 for each row begin @@ -29,7 +29,7 @@ a b 1 2 3 0 4 0 -5 0 +6 0 500 0 select a,name, old_a, old_b, truncate(rand_value,4) from t3; a name old_a old_b truncate(rand_value,4) @@ -39,7 +39,7 @@ a name old_a old_b truncate(rand_value,4) 103 t2 1 2 0.9164 104 t2 3 0 0.8826 105 t2 4 0 0.6635 -106 t2 5 0 0.6699 +106 t2 6 0 0.6699 107 t2 500 0 0.3593 --- On slave -- @@ -52,7 +52,7 @@ a b 1 2 3 0 4 0 -5 0 +6 0 500 0 select a,name, old_a, old_b, truncate(rand_value,4) from t3; a name old_a old_b truncate(rand_value,4) @@ -62,7 +62,7 @@ a name old_a old_b truncate(rand_value,4) 103 t2 1 2 0.9164 104 t2 3 0 0.8826 105 t2 4 0 0.6635 -106 t2 5 0 0.6699 +106 t2 6 0 0.6699 107 t2 500 0 0.3593 drop table t1,t2,t3; select get_lock("bug12480",2); diff --git a/mysql-test/suite/rpl/t/rpl_filter_tables_not_exist.test b/mysql-test/suite/rpl/t/rpl_filter_tables_not_exist.test index b62a6e96437..3572dd53ea7 100644 --- a/mysql-test/suite/rpl/t/rpl_filter_tables_not_exist.test +++ b/mysql-test/suite/rpl/t/rpl_filter_tables_not_exist.test @@ -215,21 +215,23 @@ drop table if exists t1,t2,t3,t4,t5,t6,t7,t8,t9; # be filtered as well. # connection master; -CREATE TABLE test.t5 (a INT AUTO_INCREMENT PRIMARY KEY, b INT, c INT); # ignored on slave +# Although RAND() is from 0 to 1.0, DECIMAL(M,D), requires that M must be >= D. +CREATE TABLE test.t5 (a INT AUTO_INCREMENT PRIMARY KEY, b DECIMAL(20,20), c INT); # ignored on slave CREATE TABLE test.t1 (a INT); # accepted on slave INSERT INTO test.t1 VALUES(1); --sync_slave_with_master call mtr.add_suppression("Unsafe statement written to the binary log using statement format since BINLOG_FORMAT = STATEMENT"); -CREATE TABLE test.t_slave (a INT AUTO_INCREMENT PRIMARY KEY, b INT, c INT); +# Although RAND() is from 0 to 1.0, DECIMAL(M,D), requires that M must be >= D. +CREATE TABLE test.t_slave (a INT AUTO_INCREMENT PRIMARY KEY, b DECIMAL(20,20), c INT); CREATE TRIGGER t1_update AFTER UPDATE ON test.t1 FOR EACH ROW - INSERT INTO test.t_slave VALUES(NULL, ROUND(RAND() * 1000), @c); + INSERT INTO test.t_slave VALUES(NULL, RAND(), @c); connection master; SET INSERT_ID=2; SET @c=2; SET @@rand_seed1=10000000, @@rand_seed2=1000000; -INSERT INTO t5 VALUES (NULL, ROUND(RAND() * 1000), @c); # to be ignored +INSERT INTO t5 VALUES (NULL, RAND(), @c); # to be ignored SELECT b into @b FROM test.t5; --let $b_master=`select @b` UPDATE test.t1 SET a=2; # to run trigger on slave @@ -253,10 +255,9 @@ if (`SELECT @a != 2 and @c != NULL`) SELECT b into @b FROM test.t_slave; --let $b_slave=`select @b` -if (`SELECT $b_slave = $b_master`) -{ - --echo Might be pure coincidence of two randoms from master and slave table. Don not panic yet. -} +--let $assert_text= Random values from master and slave must be different +--let $assert_cond= $b_master != $b_slave +--source include/assert.inc # cleanup BUG#11754117 connection master; diff --git a/mysql-test/suite/rpl/t/rpl_packet-slave.opt b/mysql-test/suite/rpl/t/rpl_packet-slave.opt index 412bc079caa..1aed7d07572 100644 --- a/mysql-test/suite/rpl/t/rpl_packet-slave.opt +++ b/mysql-test/suite/rpl/t/rpl_packet-slave.opt @@ -1 +1 @@ ---max_allowed_packet=1024 --net_buffer_length=1024 +--max_allowed_packet=1024 --net_buffer_length=1024 --slave_max_allowed_packet=1024 diff --git a/mysql-test/suite/rpl/t/rpl_packet.test b/mysql-test/suite/rpl/t/rpl_packet.test index 4f296fed68e..c49d9490bd9 100644 --- a/mysql-test/suite/rpl/t/rpl_packet.test +++ b/mysql-test/suite/rpl/t/rpl_packet.test @@ -11,9 +11,8 @@ # max-out size db name source include/master-slave.inc; source include/have_binlog_format_row.inc; -call mtr.add_suppression("Slave I/O: Got a packet bigger than 'max_allowed_packet' bytes, Error_code: 1153"); -call mtr.add_suppression("Slave I/O: Got fatal error 1236 from master when reading data from binary log:"); - +call mtr.add_suppression("Slave I/O: Got a packet bigger than 'slave_max_allowed_packet' bytes, Error_code: 1153"); +call mtr.add_suppression("Log entry on master is longer than slave_max_allowed_packet"); let $db= DB_NAME_OF_MAX_LENGTH_AKA_NAME_LEN_64_BYTES_____________________; disable_warnings; eval drop database if exists $db; @@ -23,6 +22,7 @@ eval create database $db; connection master; let $old_max_allowed_packet= `SELECT @@global.max_allowed_packet`; let $old_net_buffer_length= `SELECT @@global.net_buffer_length`; +let $old_slave_max_allowed_packet= `SELECT @@global.slave_max_allowed_packet`; SET @@global.max_allowed_packet=1024; SET @@global.net_buffer_length=1024; @@ -123,11 +123,9 @@ INSERT INTO t1(f1, f2, f3) VALUES(1, REPEAT('a', @@global.max_allowed_packet), R connection slave; # The slave I/O thread must stop after receiving -# 1236=ER_MASTER_FATAL_ERROR_READING_BINLOG error message from master. ---let $slave_io_errno= 1236 - -# Mask line numbers ---let $slave_io_error_replace= / at [0-9]*/ at XXX/ +# 1153 = ER_NET_PACKET_TOO_LARGE +--let $slave_io_errno= 1153 +--let $show_slave_io_error= 1 --source include/wait_for_slave_io_error.inc # Remove the bad binlog and clear error status on slave. @@ -167,6 +165,7 @@ connection master; DROP TABLE t1; eval SET @@global.max_allowed_packet= $old_max_allowed_packet; eval SET @@global.net_buffer_length= $old_net_buffer_length; +eval SET @@global.slave_max_allowed_packet= $old_slave_max_allowed_packet; # slave is stopped connection slave; DROP TABLE t1; diff --git a/mysql-test/suite/rpl/t/rpl_trigger.test b/mysql-test/suite/rpl/t/rpl_trigger.test index e2974a21bf7..723fa3e44e2 100644 --- a/mysql-test/suite/rpl/t/rpl_trigger.test +++ b/mysql-test/suite/rpl/t/rpl_trigger.test @@ -3,13 +3,10 @@ # Adding statement include due to Bug 12574 # TODO: Remove statement include once 12574 is patched --source include/have_binlog_format_mixed_or_statement.inc ---source include/master-slave.inc ---source include/have_innodb.inc -connection slave; --source include/have_innodb.inc +--source include/master-slave.inc connection master; - disable_query_log; call mtr.add_suppression("Unsafe statement written to the binary log using statement format since BINLOG_FORMAT = STATEMENT"); enable_query_log; @@ -26,7 +23,7 @@ DROP TABLE IF EXISTS t3; # create table t1 (a int auto_increment, primary key (a), b int, rand_value double not null); -create table t2 (a int auto_increment, primary key (a), b int); +create table t2 (a int auto_increment, primary key (a), b int) engine=innodb; create table t3 (a int auto_increment, primary key (a), name varchar(64) not null, old_a int, old_b int, rand_value double not null); delimiter |; diff --git a/mysql-test/suite/sys_vars/r/slave_max_allowed_packet_basic.result b/mysql-test/suite/sys_vars/r/slave_max_allowed_packet_basic.result new file mode 100644 index 00000000000..a5fe9b35ed5 --- /dev/null +++ b/mysql-test/suite/sys_vars/r/slave_max_allowed_packet_basic.result @@ -0,0 +1,147 @@ +SET @start_value = @@global.slave_max_allowed_packet; +SELECT @start_value; +@start_value +1073741824 +'#--------------------FN_DYNVARS_072_01------------------------#' +SET @@global.slave_max_allowed_packet = 5000; +Warnings: +Warning 1292 Truncated incorrect slave_max_allowed_packet value: '5000' +SET @@global.slave_max_allowed_packet = DEFAULT; +SELECT @@global.slave_max_allowed_packet; +@@global.slave_max_allowed_packet +1073741824 +'#---------------------FN_DYNVARS_072_02-------------------------#' +SET @@global.slave_max_allowed_packet = @start_value; +SELECT @@global.slave_max_allowed_packet = 1073741824; +@@global.slave_max_allowed_packet = 1073741824 +1 +'Bug# 34876: Incorrect Default Value is assigned to variable'; +'#--------------------FN_DYNVARS_072_03------------------------#' +SET @@global.slave_max_allowed_packet = 1024; +SELECT @@global.slave_max_allowed_packet; +@@global.slave_max_allowed_packet +1024 +SET @@global.slave_max_allowed_packet = 1073741824; +SELECT @@global.slave_max_allowed_packet; +@@global.slave_max_allowed_packet +1073741824 +SET @@global.slave_max_allowed_packet = 1073741824; +SELECT @@global.slave_max_allowed_packet; +@@global.slave_max_allowed_packet +1073741824 +SET @@global.slave_max_allowed_packet = 1025; +Warnings: +Warning 1292 Truncated incorrect slave_max_allowed_packet value: '1025' +SELECT @@global.slave_max_allowed_packet; +@@global.slave_max_allowed_packet +1024 +SET @@global.slave_max_allowed_packet = 65535; +Warnings: +Warning 1292 Truncated incorrect slave_max_allowed_packet value: '65535' +SELECT @@global.slave_max_allowed_packet; +@@global.slave_max_allowed_packet +64512 +'Bug# 34877: Invalid Values are coming in variable on assigning valid values'; +'#--------------------FN_DYNVARS_072_04-------------------------#' +SET @@global.slave_max_allowed_packet = -1; +Warnings: +Warning 1292 Truncated incorrect slave_max_allowed_packet value: '-1' +SELECT @@global.slave_max_allowed_packet; +@@global.slave_max_allowed_packet +1024 +SET @@global.slave_max_allowed_packet = 100000000000; +Warnings: +Warning 1292 Truncated incorrect slave_max_allowed_packet value: '100000000000' +SELECT @@global.slave_max_allowed_packet; +@@global.slave_max_allowed_packet +1073741824 +SET @@global.slave_max_allowed_packet = 10000.01; +ERROR 42000: Incorrect argument type to variable 'slave_max_allowed_packet' +SELECT @@global.slave_max_allowed_packet; +@@global.slave_max_allowed_packet +1073741824 +SET @@global.slave_max_allowed_packet = -1024; +Warnings: +Warning 1292 Truncated incorrect slave_max_allowed_packet value: '-1024' +SELECT @@global.slave_max_allowed_packet; +@@global.slave_max_allowed_packet +1024 +SET @@global.slave_max_allowed_packet = 4294967296; +Warnings: +Warning 1292 Truncated incorrect slave_max_allowed_packet value: '4294967296' +SELECT @@global.slave_max_allowed_packet; +@@global.slave_max_allowed_packet +1073741824 +SET @@global.slave_max_allowed_packet = 1023; +Warnings: +Warning 1292 Truncated incorrect slave_max_allowed_packet value: '1023' +SELECT @@global.slave_max_allowed_packet; +@@global.slave_max_allowed_packet +1024 +'Bug # 34837: Errors are not coming on assigning invalid values to variable'; +SET @@global.slave_max_allowed_packet = ON; +ERROR 42000: Incorrect argument type to variable 'slave_max_allowed_packet' +SELECT @@global.slave_max_allowed_packet; +@@global.slave_max_allowed_packet +1024 +SET @@global.slave_max_allowed_packet = 'test'; +ERROR 42000: Incorrect argument type to variable 'slave_max_allowed_packet' +SELECT @@global.slave_max_allowed_packet; +@@global.slave_max_allowed_packet +1024 +'#-------------------FN_DYNVARS_072_05----------------------------#' +SET @@session.slave_max_allowed_packet = 4096; +ERROR HY000: Variable 'slave_max_allowed_packet' is a GLOBAL variable and should be set with SET GLOBAL +SELECT @@session.slave_max_allowed_packet; +ERROR HY000: Variable 'slave_max_allowed_packet' is a GLOBAL variable +'#----------------------FN_DYNVARS_072_06------------------------#' +SELECT @@global.slave_max_allowed_packet = VARIABLE_VALUE +FROM INFORMATION_SCHEMA.GLOBAL_VARIABLES +WHERE VARIABLE_NAME='slave_max_allowed_packet'; +@@global.slave_max_allowed_packet = VARIABLE_VALUE +1 +SELECT @@slave_max_allowed_packet = VARIABLE_VALUE +FROM INFORMATION_SCHEMA.SESSION_VARIABLES +WHERE VARIABLE_NAME='slave_max_allowed_packet'; +@@slave_max_allowed_packet = VARIABLE_VALUE +1 +'#---------------------FN_DYNVARS_072_07----------------------#' +SET @@global.slave_max_allowed_packet = TRUE; +Warnings: +Warning 1292 Truncated incorrect slave_max_allowed_packet value: '1' +SELECT @@global.slave_max_allowed_packet; +@@global.slave_max_allowed_packet +1024 +SET @@global.slave_max_allowed_packet = FALSE; +Warnings: +Warning 1292 Truncated incorrect slave_max_allowed_packet value: '0' +SELECT @@global.slave_max_allowed_packet; +@@global.slave_max_allowed_packet +1024 +'#---------------------FN_DYNVARS_072_08----------------------#' +SET @@global.slave_max_allowed_packet = 5000; +Warnings: +Warning 1292 Truncated incorrect slave_max_allowed_packet value: '5000' +SELECT @@slave_max_allowed_packet = @@global.slave_max_allowed_packet; +@@slave_max_allowed_packet = @@global.slave_max_allowed_packet +1 +'#---------------------FN_DYNVARS_072_09----------------------#' +SET slave_max_allowed_packet = 6000; +ERROR HY000: Variable 'slave_max_allowed_packet' is a GLOBAL variable and should be set with SET GLOBAL +SELECT @@slave_max_allowed_packet; +@@slave_max_allowed_packet +4096 +SET local.slave_max_allowed_packet = 7000; +ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near 'slave_max_allowed_packet = 7000' at line 1 +SELECT local.slave_max_allowed_packet; +ERROR 42S02: Unknown table 'local' in field list +SET global.slave_max_allowed_packet = 8000; +ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near 'slave_max_allowed_packet = 8000' at line 1 +SELECT global.slave_max_allowed_packet; +ERROR 42S02: Unknown table 'global' in field list +SELECT slave_max_allowed_packet = @@session.slave_max_allowed_packet; +ERROR 42S22: Unknown column 'slave_max_allowed_packet' in 'field list' +SET @@global.slave_max_allowed_packet = @start_value; +SELECT @@global.slave_max_allowed_packet; +@@global.slave_max_allowed_packet +1073741824 diff --git a/mysql-test/suite/sys_vars/t/slave_max_allowed_packet_basic.test b/mysql-test/suite/sys_vars/t/slave_max_allowed_packet_basic.test new file mode 100644 index 00000000000..4caaae84906 --- /dev/null +++ b/mysql-test/suite/sys_vars/t/slave_max_allowed_packet_basic.test @@ -0,0 +1,177 @@ +############## mysql-test\t\slave_max_allowed_packet_basic.test ################## +# # +# Variable Name: slave_max_allowed_packet # +# Scope: GLOBAL # +# Access Type: Dynamic # +# Data Type: numeric # +# Default Value:1073741824 # +# Range: 1024 - 1073741824 # +# # +# # +# # +# Description: Test Cases of Dynamic System Variable slave_max_allowed_packet # +# that checks the behavior of this variable in the following ways# +# * Default Value # +# * Valid & Invalid values # +# * Scope & Access method # +# * Data Integrity # +# # +############################################################################### + +--source include/load_sysvars.inc + +######################################################################## +# START OF slave_max_allowed_packet TESTS # +######################################################################## + + +########################################################################### +# Saving initial value of slave_max_allowed_packet in a temporary variable# +########################################################################### + +SET @start_value = @@global.slave_max_allowed_packet; +SELECT @start_value; + + +--echo '#--------------------FN_DYNVARS_072_01------------------------#' +######################################################################## +# Display the DEFAULT value of slave_max_allowed_packet # +######################################################################## + +SET @@global.slave_max_allowed_packet = 5000; +SET @@global.slave_max_allowed_packet = DEFAULT; +SELECT @@global.slave_max_allowed_packet; + + +--echo '#---------------------FN_DYNVARS_072_02-------------------------#' +############################################### +# Verify default value of variable # +############################################### + +SET @@global.slave_max_allowed_packet = @start_value; +SELECT @@global.slave_max_allowed_packet = 1073741824; +--echo 'Bug# 34876: Incorrect Default Value is assigned to variable'; + +--echo '#--------------------FN_DYNVARS_072_03------------------------#' +######################################################################## +# Change the value of slave_max_allowed_packet to a valid value # +######################################################################## + +SET @@global.slave_max_allowed_packet = 1024; +SELECT @@global.slave_max_allowed_packet; +SET @@global.slave_max_allowed_packet = 1073741824; +SELECT @@global.slave_max_allowed_packet; +SET @@global.slave_max_allowed_packet = 1073741824; +SELECT @@global.slave_max_allowed_packet; +SET @@global.slave_max_allowed_packet = 1025; +SELECT @@global.slave_max_allowed_packet; +SET @@global.slave_max_allowed_packet = 65535; +SELECT @@global.slave_max_allowed_packet; +--echo 'Bug# 34877: Invalid Values are coming in variable on assigning valid values'; + + +--echo '#--------------------FN_DYNVARS_072_04-------------------------#' +########################################################################### +# Change the value of slave_max_allowed_packet to invalid value # +########################################################################### + +SET @@global.slave_max_allowed_packet = -1; +SELECT @@global.slave_max_allowed_packet; +SET @@global.slave_max_allowed_packet = 100000000000; +SELECT @@global.slave_max_allowed_packet; +--Error ER_WRONG_TYPE_FOR_VAR +SET @@global.slave_max_allowed_packet = 10000.01; +SELECT @@global.slave_max_allowed_packet; +SET @@global.slave_max_allowed_packet = -1024; +SELECT @@global.slave_max_allowed_packet; +SET @@global.slave_max_allowed_packet = 4294967296; +SELECT @@global.slave_max_allowed_packet; +SET @@global.slave_max_allowed_packet = 1023; +SELECT @@global.slave_max_allowed_packet; + +--echo 'Bug # 34837: Errors are not coming on assigning invalid values to variable'; + +--Error ER_WRONG_TYPE_FOR_VAR +SET @@global.slave_max_allowed_packet = ON; +SELECT @@global.slave_max_allowed_packet; +--Error ER_WRONG_TYPE_FOR_VAR +SET @@global.slave_max_allowed_packet = 'test'; +SELECT @@global.slave_max_allowed_packet; + + +--echo '#-------------------FN_DYNVARS_072_05----------------------------#' +########################################################################### +# Test if accessing session slave_max_allowed_packet gives error # +########################################################################### + +--Error ER_GLOBAL_VARIABLE +SET @@session.slave_max_allowed_packet = 4096; +--Error ER_INCORRECT_GLOBAL_LOCAL_VAR +SELECT @@session.slave_max_allowed_packet; + + +--echo '#----------------------FN_DYNVARS_072_06------------------------#' +############################################################################## +# Check if the value in GLOBAL & SESSION Tables matches values in variable # +############################################################################## + +SELECT @@global.slave_max_allowed_packet = VARIABLE_VALUE +FROM INFORMATION_SCHEMA.GLOBAL_VARIABLES +WHERE VARIABLE_NAME='slave_max_allowed_packet'; + +SELECT @@slave_max_allowed_packet = VARIABLE_VALUE +FROM INFORMATION_SCHEMA.SESSION_VARIABLES +WHERE VARIABLE_NAME='slave_max_allowed_packet'; + + +--echo '#---------------------FN_DYNVARS_072_07----------------------#' +################################################################### +# Check if TRUE and FALSE values can be used on variable # +################################################################### + +SET @@global.slave_max_allowed_packet = TRUE; +SELECT @@global.slave_max_allowed_packet; +SET @@global.slave_max_allowed_packet = FALSE; +SELECT @@global.slave_max_allowed_packet; + + +--echo '#---------------------FN_DYNVARS_072_08----------------------#' +######################################################################################################## +# Check if accessing variable with SESSION,LOCAL and without SCOPE points to same session variable # +######################################################################################################## + +SET @@global.slave_max_allowed_packet = 5000; +SELECT @@slave_max_allowed_packet = @@global.slave_max_allowed_packet; + + +--echo '#---------------------FN_DYNVARS_072_09----------------------#' +################################################################################ +# Check if slave_max_allowed_packet can be accessed with and without @@ sign # +################################################################################ + +--Error ER_GLOBAL_VARIABLE +SET slave_max_allowed_packet = 6000; +SELECT @@slave_max_allowed_packet; +--Error ER_PARSE_ERROR +SET local.slave_max_allowed_packet = 7000; +--Error ER_UNKNOWN_TABLE +SELECT local.slave_max_allowed_packet; +--Error ER_PARSE_ERROR +SET global.slave_max_allowed_packet = 8000; +--Error ER_UNKNOWN_TABLE +SELECT global.slave_max_allowed_packet; +--Error ER_BAD_FIELD_ERROR +SELECT slave_max_allowed_packet = @@session.slave_max_allowed_packet; + + +############################## +# Restore initial value # +############################## + +SET @@global.slave_max_allowed_packet = @start_value; +SELECT @@global.slave_max_allowed_packet; + + +######################################################################## +# END OF slave_max_allowed_packet TESTS # +######################################################################## diff --git a/mysql-test/t/create-big.test b/mysql-test/t/create-big.test index d487608f7e1..8d916f8da82 100644 --- a/mysql-test/t/create-big.test +++ b/mysql-test/t/create-big.test @@ -132,11 +132,20 @@ set debug_sync='create_table_select_before_create SIGNAL parked WAIT_FOR go'; --send create table t1 select 1 as i; connection addconroot1; set debug_sync='now WAIT_FOR parked'; ---error ER_TABLE_EXISTS_ERROR -alter table t3 rename to t1; +--send alter table t3 rename to t1 +connection addconroot2; +# Wait until the above ALTER TABLE RENAME is blocked due to CREATE +let $wait_condition= + select count(*) = 1 from information_schema.processlist + where state = "Waiting for table metadata lock" and + info = "alter table t3 rename to t1"; +--source include/wait_condition.inc set debug_sync='now SIGNAL go'; connection default; --reap +connection addconroot1; +--error ER_TABLE_EXISTS_ERROR +--reap connection default; show create table t1; drop table t1; @@ -146,11 +155,21 @@ set debug_sync='create_table_select_before_create SIGNAL parked WAIT_FOR go'; --send create table t1 select 1 as i; connection addconroot1; set debug_sync='now WAIT_FOR parked'; ---error ER_TABLE_EXISTS_ERROR -alter table t3 rename to t1, add k int; +--send alter table t3 rename to t1, add k int +connection addconroot2; +# Wait until the above ALTER TABLE RENAME is blocked due to CREATE +let $wait_condition= + select count(*) = 1 from information_schema.processlist + where state = "Waiting for table metadata lock" and + info = "alter table t3 rename to t1, add k int"; +--source include/wait_condition.inc set debug_sync='now SIGNAL go'; connection default; --reap +connection addconroot1; +--error ER_TABLE_EXISTS_ERROR +--reap +connection default; show create table t1; drop table t1,t3; diff --git a/mysql-test/t/mysql_plugin.test b/mysql-test/t/mysql_plugin.test index 71617b86330..a05b5a624d9 100644 --- a/mysql-test/t/mysql_plugin.test +++ b/mysql-test/t/mysql_plugin.test @@ -372,11 +372,11 @@ let $MYSQL_PLUGIN_CMD= $MYSQL_PLUGIN -n --datadir=$MYSQL_DATADIR --basedir=$MYSQ --echo # Show the help. --echo # replace_result $MYSQL_PLUGIN mysql_plugin; ---replace_regex /Ver [0-9.]+ Distrib [0-9.]+/Ver V.V.VV Distrib XX.XX.XX/ /XX-m[0-9]+/XX/ +--replace_regex /Ver [0-9.]+ Distrib [0-9.]+/Ver V.V.VV Distrib XX.XX.XX/ /XX-m[0-9]+/XX/ /XX[a-z]/XX/ --exec $MYSQL_PLUGIN --help replace_result $MYSQL_PLUGIN mysql_plugin; ---replace_regex /Ver [0-9.]+ Distrib [0-9.]+/Ver V.V.VV Distrib XX.XX.XX/ /XX-m[0-9]+/XX/ +--replace_regex /Ver [0-9.]+ Distrib [0-9.]+/Ver V.V.VV Distrib XX.XX.XX/ /XX-m[0-9]+/XX/ /XX[a-z]/XX/ --exec $MYSQL_PLUGIN --version # diff --git a/mysql-test/t/type_year.test b/mysql-test/t/type_year.test index 0a0c73da39b..685587fe3c5 100644 --- a/mysql-test/t/type_year.test +++ b/mysql-test/t/type_year.test @@ -161,6 +161,14 @@ SELECT COUNT(*) AS total_rows, MIN(c1+0) AS min_value, MAX(c1+0) FROM t1; DROP TABLE t1; --echo # +--echo # WL#6219: Deprecate and remove YEAR(2) type +--echo # + +CREATE TABLE t1 (c1 YEAR(2), c2 YEAR(4)); +ALTER TABLE t1 MODIFY COLUMN c2 YEAR(2); +DROP TABLE t1; + +--echo # --echo End of 5.1 tests # diff --git a/mysys/mf_iocache2.c b/mysys/mf_iocache2.c index 3c23d0737e7..6c7cd9a7e84 100644 --- a/mysys/mf_iocache2.c +++ b/mysys/mf_iocache2.c @@ -433,7 +433,11 @@ process_flags: memset(buffz, '0', minimum_width - length2); else memset(buffz, ' ', minimum_width - length2); - my_b_write(info, buffz, minimum_width - length2); + if (my_b_write(info, buffz, minimum_width - length2)) + { + my_afree(buffz); + goto err; + } my_afree(buffz); } diff --git a/mysys/my_write.c b/mysys/my_write.c index dc04b60f613..c4cba7a927d 100644 --- a/mysys/my_write.c +++ b/mysys/my_write.c @@ -47,6 +47,11 @@ size_t my_write(File Filedes, const uchar *Buffer, size_t Count, myf MyFlags) #else writtenbytes= write(Filedes, Buffer, Count); #endif + DBUG_EXECUTE_IF("simulate_file_write_error", + { + errno= ENOSPC; + writtenbytes= (size_t) -1; + }); if (writtenbytes == Count) break; if (writtenbytes != (size_t) -1) diff --git a/plugin/semisync/semisync.cc b/plugin/semisync/semisync.cc index 83c7791c14b..022773eed0a 100644 --- a/plugin/semisync/semisync.cc +++ b/plugin/semisync/semisync.cc @@ -26,5 +26,5 @@ const unsigned long Trace::kTraceDetail = 0x0010; const unsigned long Trace::kTraceNetWait = 0x0020; const unsigned long Trace::kTraceFunction = 0x0040; -const char ReplSemiSyncBase::kSyncHeader[2] = +const unsigned char ReplSemiSyncBase::kSyncHeader[2] = {ReplSemiSyncBase::kPacketMagicNum, 0}; diff --git a/plugin/semisync/semisync.h b/plugin/semisync/semisync.h index 57353f3c156..900ce5d8bf9 100644 --- a/plugin/semisync/semisync.h +++ b/plugin/semisync/semisync.h @@ -71,7 +71,7 @@ public: class ReplSemiSyncBase :public Trace { public: - static const char kSyncHeader[2]; /* three byte packet header */ + static const unsigned char kSyncHeader[2]; /* three byte packet header */ /* Constants in network packet header. */ static const unsigned char kPacketMagicNum; diff --git a/plugin/semisync/semisync_master_plugin.cc b/plugin/semisync/semisync_master_plugin.cc index 9a325018242..b6ff23cd1ad 100644 --- a/plugin/semisync/semisync_master_plugin.cc +++ b/plugin/semisync/semisync_master_plugin.cc @@ -180,7 +180,7 @@ static MYSQL_SYSVAR_ULONG(timeout, rpl_semi_sync_master_timeout, "The timeout value (in ms) for semi-synchronous replication in the master", NULL, // check fix_rpl_semi_sync_master_timeout, // update - 10000, 0, ~0L, 1); + 10000, 0, ~0UL, 1); static MYSQL_SYSVAR_BOOL(wait_no_slave, rpl_semi_sync_master_wait_no_slave, PLUGIN_VAR_OPCMDARG, @@ -194,7 +194,7 @@ static MYSQL_SYSVAR_ULONG(trace_level, rpl_semi_sync_master_trace_level, "The tracing level for semi-sync replication.", NULL, // check &fix_rpl_semi_sync_master_trace_level, // update - 32, 0, ~0L, 1); + 32, 0, ~0UL, 1); static SYS_VAR* semi_sync_master_system_vars[]= { MYSQL_SYSVAR(enabled), diff --git a/plugin/semisync/semisync_slave_plugin.cc b/plugin/semisync/semisync_slave_plugin.cc index d5472b9cc83..5d373fa0862 100644 --- a/plugin/semisync/semisync_slave_plugin.cc +++ b/plugin/semisync/semisync_slave_plugin.cc @@ -161,7 +161,7 @@ static MYSQL_SYSVAR_ULONG(trace_level, rpl_semi_sync_slave_trace_level, "The tracing level for semi-sync replication.", NULL, // check &fix_rpl_semi_sync_trace_level, // update - 32, 0, ~0L, 1); + 32, 0, ~0UL, 1); static SYS_VAR* semi_sync_slave_system_vars[]= { MYSQL_SYSVAR(enabled), diff --git a/sql-common/client.c b/sql-common/client.c index 349d844ebd3..9f58281ddbf 100644 --- a/sql-common/client.c +++ b/sql-common/client.c @@ -1,5 +1,5 @@ -/* - Copyright (c) 2003, 2011, Oracle and/or its affiliates. +/* Copyright (c) 2003, 2012, Oracle and/or its affiliates. + Copyright (c) 2009, 2012, Monty Program Ab This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -1439,7 +1439,7 @@ static void cli_fetch_lengths(ulong *to, MYSQL_ROW column, ***************************************************************************/ MYSQL_FIELD * -unpack_fields(MYSQL_DATA *data,MEM_ROOT *alloc,uint fields, +unpack_fields(MYSQL *mysql, MYSQL_DATA *data,MEM_ROOT *alloc,uint fields, my_bool default_value, uint server_capabilities) { MYSQL_ROWS *row; @@ -1452,6 +1452,7 @@ unpack_fields(MYSQL_DATA *data,MEM_ROOT *alloc,uint fields, if (!result) { free_rows(data); /* Free old data */ + set_mysql_error(mysql, CR_OUT_OF_MEMORY, unknown_sqlstate); DBUG_RETURN(0); } bzero((char*) field, (uint) sizeof(MYSQL_FIELD)*fields); @@ -1479,6 +1480,14 @@ unpack_fields(MYSQL_DATA *data,MEM_ROOT *alloc,uint fields, field->org_name_length= lengths[5]; /* Unpack fixed length parts */ + if (lengths[6] != 12) + { + /* malformed packet. signal an error. */ + free_rows(data); /* Free old data */ + set_mysql_error(mysql, CR_MALFORMED_PACKET, unknown_sqlstate); + DBUG_RETURN(0); + } + pos= (uchar*) row->data[6]; field->charsetnr= uint2korr(pos); field->length= (uint) uint4korr(pos+2); @@ -3361,6 +3370,12 @@ CLI_MYSQL_REAL_CONNECT(MYSQL *mysql,const char *host, const char *user, mysql->server_status=uint2korr(end+3); mysql->server_capabilities|= uint2korr(end+5) << 16; pkt_scramble_len= end[7]; + if (pkt_scramble_len < 0) + { + set_mysql_error(mysql, CR_MALFORMED_PACKET, + unknown_sqlstate); /* purecov: inspected */ + goto error; + } } end+= 18; @@ -3896,7 +3911,7 @@ get_info: if (!(fields=cli_read_rows(mysql,(MYSQL_FIELD*)0, protocol_41(mysql) ? 7:5))) DBUG_RETURN(1); - if (!(mysql->fields=unpack_fields(fields,&mysql->field_alloc, + if (!(mysql->fields=unpack_fields(mysql, fields,&mysql->field_alloc, (uint) field_count,0, mysql->server_capabilities))) DBUG_RETURN(1); diff --git a/sql/field.cc b/sql/field.cc index 2084c661602..f20d9ba87fc 100644 --- a/sql/field.cc +++ b/sql/field.cc @@ -9567,6 +9567,17 @@ Create_field::Create_field(Field *old_field,Field *orig_field) geom_type= ((Field_geom*)old_field)->geom_type; break; #endif + case MYSQL_TYPE_YEAR: + if (length != 4) + { + char buff[sizeof("YEAR()") + MY_INT64_NUM_DECIMAL_DIGITS + 1]; + my_snprintf(buff, sizeof(buff), "YEAR(%lu)", length); + push_warning_printf(current_thd, MYSQL_ERROR::WARN_LEVEL_NOTE, + ER_WARN_DEPRECATED_SYNTAX, + ER(ER_WARN_DEPRECATED_SYNTAX), + buff, "YEAR(4)"); + } + break; default: break; } diff --git a/sql/ha_partition.cc b/sql/ha_partition.cc index 78adbeff623..0d2b4387327 100644 --- a/sql/ha_partition.cc +++ b/sql/ha_partition.cc @@ -6490,7 +6490,17 @@ ha_rows ha_partition::min_rows_for_estimate() DBUG_ENTER("ha_partition::min_rows_for_estimate"); tot_used_partitions= bitmap_bits_set(&m_part_info->used_partitions); - DBUG_ASSERT(tot_used_partitions); + + /* + All partitions might have been left as unused during partition pruning + due to, for example, an impossible WHERE condition. Nonetheless, the + optimizer might still attempt to perform (e.g. range) analysis where an + estimate of the the number of rows is calculated using records_in_range. + Hence, to handle this and other possible cases, use zero as the minimum + number of rows to base the estimate on if no partition is being used. + */ + if (!tot_used_partitions) + DBUG_RETURN(0); /* Allow O(log2(tot_partitions)) increase in number of used partitions. diff --git a/sql/handler.cc b/sql/handler.cc index ecd02e2a1be..b5c9716bbbf 100644 --- a/sql/handler.cc +++ b/sql/handler.cc @@ -2554,8 +2554,19 @@ int handler::update_auto_increment() reservation means potentially losing unused values). Note that in prelocked mode no estimation is given. */ + if ((auto_inc_intervals_count == 0) && (estimation_rows_to_insert > 0)) nb_desired_values= estimation_rows_to_insert; + else if ((auto_inc_intervals_count == 0) && + (thd->lex->many_values.elements > 0)) + { + /* + For multi-row inserts, if the bulk inserts cannot be started, the + handler::estimation_rows_to_insert will not be set. But we still + want to reserve the autoinc values. + */ + nb_desired_values= thd->lex->many_values.elements; + } else /* go with the increasing defaults */ { /* avoid overflow in formula, with this if() */ @@ -5071,6 +5082,8 @@ int handler::ha_write_row(uchar *buf) rows_changed++; if (unlikely(error= binlog_log_row(table, 0, buf, log_func))) DBUG_RETURN(error); /* purecov: inspected */ + + DEBUG_SYNC_C("ha_write_row_end"); DBUG_RETURN(0); } diff --git a/sql/item.cc b/sql/item.cc index 3031e90c9b2..eac33041797 100644 --- a/sql/item.cc +++ b/sql/item.cc @@ -6823,7 +6823,7 @@ bool Item_ref::fix_fields(THD *thd, Item **reference) if (from_field != not_found_field) { Item_field* fld; - if (!(fld= new Item_field(from_field))) + if (!(fld= new Item_field(thd, last_checked_context, from_field))) goto error; thd->change_item_tree(reference, fld); mark_as_dependent(thd, last_checked_context->select_lex, diff --git a/sql/item_cmpfunc.cc b/sql/item_cmpfunc.cc index 2a0ca19a4e9..8cfbcb97144 100644 --- a/sql/item_cmpfunc.cc +++ b/sql/item_cmpfunc.cc @@ -4866,8 +4866,8 @@ bool Item_func_like::fix_fields(THD *thd, Item **ref) } if (canDoTurboBM) { - pattern = first + 1; pattern_len = (int) len - 2; + pattern = thd->strmake(first + 1, pattern_len); DBUG_PRINT("info", ("Initializing pattern: '%s'", first)); int *suff = (int*) thd->alloc((int) (sizeof(int)* ((pattern_len + 1)*2+ diff --git a/sql/log.cc b/sql/log.cc index 801d945f3f0..9cb85ab4b2b 100644 --- a/sql/log.cc +++ b/sql/log.cc @@ -2836,7 +2836,10 @@ bool MYSQL_QUERY_LOG::write(THD *thd, time_t current_time, { end= strxmov(buff, "# administrator command: ", NullS); buff_len= (ulong) (end - buff); - my_b_write(&log_file, (uchar*) buff, buff_len); + DBUG_EXECUTE_IF("simulate_slow_log_write_error", + {DBUG_SET("+d,simulate_file_write_error");}); + if(my_b_write(&log_file, (uchar*) buff, buff_len)) + tmp_errno= errno; } if (my_b_write(&log_file, (uchar*) sql_text, sql_text_len) || my_b_write(&log_file, (uchar*) ";\n",2) || @@ -2890,7 +2893,7 @@ MYSQL_BIN_LOG::MYSQL_BIN_LOG(uint *sync_period) need_start_event(TRUE), group_commit_queue(0), group_commit_queue_busy(FALSE), num_commits(0), num_group_commits(0), - sync_period_ptr(sync_period), + sync_period_ptr(sync_period), sync_counter(0), is_relay_log(0), signal_cnt(0), checksum_alg_reset(BINLOG_CHECKSUM_ALG_UNDEF), relay_log_checksum_alg(BINLOG_CHECKSUM_ALG_UNDEF), diff --git a/sql/log.h b/sql/log.h index 6c21a34fd08..88352de5418 100644 --- a/sql/log.h +++ b/sql/log.h @@ -1,5 +1,5 @@ -/* - Copyright (c) 2005, 2011, Oracle and/or its affiliates. +/* Copyright (c) 2005, 2012, Oracle and/or its affiliates. + Copyright (c) 2009, 2012, Monty Program Ab This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by diff --git a/sql/log_event.cc b/sql/log_event.cc index 60e074deaca..6ef5a68e768 100644 --- a/sql/log_event.cc +++ b/sql/log_event.cc @@ -1348,7 +1348,7 @@ failed my_b_read")); Log_event *res= 0; #ifndef max_allowed_packet THD *thd=current_thd; - uint max_allowed_packet= thd ? thd->variables.max_allowed_packet : ~(ulong)0; + uint max_allowed_packet= thd ? slave_max_allowed_packet:~(ulong)0; #endif if (data_len > max_allowed_packet) @@ -3218,24 +3218,41 @@ Query_log_event::Query_log_event(const char* buf, uint event_len, pos= (const uchar*) end; // Break loop } } - + + /** + Layout for the data buffer is as follows + +--------+-----------+------+------+---------+----+-------+ + | catlog | time_zone | user | host | db name | \0 | Query | + +--------+-----------+------+------+---------+----+-------+ + + To support the query cache we append the following buffer to the above + +-------+----------------------------------------+-------+ + |db len | uninitiatlized space of size of db len | FLAGS | + +-------+----------------------------------------+-------+ + + The area of buffer starting from Query field all the way to the end belongs + to the Query buffer and its structure is described in alloc_query() in + sql_parse.cc + */ + #if !defined(MYSQL_CLIENT) && defined(HAVE_QUERY_CACHE) - if (!(start= data_buf = (Log_event::Byte*) my_malloc(catalog_len + 1 + - time_zone_len + 1 + - data_len + 1 + - QUERY_CACHE_DB_LENGTH_SIZE + - QUERY_CACHE_FLAGS_SIZE + - user.length + 1 + - host.length + 1 + - db_len + 1, - MYF(MY_WME)))) + if (!(start= data_buf = (Log_event::Byte*) my_malloc(catalog_len + 1 + + time_zone_len + 1 + + user.length + 1 + + host.length + 1 + + data_len + 1 + + sizeof(size_t)//for db_len + + db_len + 1 + + QUERY_CACHE_DB_LENGTH_SIZE + + QUERY_CACHE_FLAGS_SIZE, + MYF(MY_WME)))) #else - if (!(start= data_buf = (Log_event::Byte*) my_malloc(catalog_len + 1 + - time_zone_len + 1 + - data_len + 1 + - user.length + 1 + - host.length + 1, - MYF(MY_WME)))) + if (!(start= data_buf = (Log_event::Byte*) my_malloc(catalog_len + 1 + + time_zone_len + 1 + + user.length + 1 + + host.length + 1 + + data_len + 1, + MYF(MY_WME)))) #endif DBUG_VOID_RETURN; if (catalog_len) // If catalog is given @@ -3275,6 +3292,14 @@ Query_log_event::Query_log_event(const char* buf, uint event_len, db= (char *)start; query= (char *)(start + db_len + 1); q_len= data_len - db_len -1; + /** + Append the db length at the end of the buffer. This will be used by + Query_cache::send_result_to_client() in case the query cache is On. + */ +#if !defined(MYSQL_CLIENT) && defined(HAVE_QUERY_CACHE) + size_t db_length= (size_t)db_len; + memcpy(start + data_len + 1, &db_length, sizeof(size_t)); +#endif DBUG_VOID_RETURN; } @@ -3461,6 +3486,12 @@ void Query_log_event::print(FILE* file, PRINT_EVENT_INFO* print_event_info) { Write_on_release_cache cache(&print_event_info->head_cache, file); + /** + reduce the size of io cache so that the write function is called + for every call to my_b_write(). + */ + DBUG_EXECUTE_IF ("simulate_file_write_error", + {(&cache)->write_pos= (&cache)->write_end- 500;}); print_query_header(&cache, print_event_info); my_b_write(&cache, (uchar*) query, q_len); my_b_printf(&cache, "\n%s\n", print_event_info->delimiter); @@ -6205,6 +6236,9 @@ User_var_log_event:: User_var_log_event(const char* buf, const Format_description_log_event* description_event) :Log_event(buf, description_event) +#ifndef MYSQL_CLIENT + , deferred(false) +#endif { /* The Post-Header is empty. The Variable Data part begins immediately. */ const char *start= buf; @@ -6454,7 +6488,10 @@ int User_var_log_event::do_apply_event(Relay_log_info const *rli) CHARSET_INFO *charset; if (rli->deferred_events_collecting) + { + set_deferred(); return rli->deferred_events->add(this); + } if (!(charset= get_charset(charset_number, MYF(MY_WME)))) return 1; @@ -6506,7 +6543,8 @@ int User_var_log_event::do_apply_event(Relay_log_info const *rli) return 0; } } - Item_func_set_user_var e(user_var_name, it); + + Item_func_set_user_var *e= new Item_func_set_user_var(user_var_name, it); /* Item_func_set_user_var can't substitute something else on its place => 0 can be passed as last argument (reference on item) @@ -6515,7 +6553,7 @@ int User_var_log_event::do_apply_event(Relay_log_info const *rli) crash the server, so if fix fields fails, we just return with an error. */ - if (e.fix_fields(thd, 0)) + if (e->fix_fields(thd, 0)) return 1; /* @@ -6523,9 +6561,10 @@ int User_var_log_event::do_apply_event(Relay_log_info const *rli) a single record and with a single column. Thus, like a column value, it could always have IMPLICIT derivation. */ - e.update_hash(val, val_len, type, charset, DERIVATION_IMPLICIT, - (flags & User_var_log_event::UNSIGNED_F)); - free_root(thd->mem_root,0); + e->update_hash(val, val_len, type, charset, DERIVATION_IMPLICIT, + (flags & User_var_log_event::UNSIGNED_F)); + if (!is_deferred()) + free_root(thd->mem_root, 0); return 0; } @@ -6922,11 +6961,18 @@ void Create_file_log_event::print(FILE* file, PRINT_EVENT_INFO* print_event_info { Load_log_event::print(file, print_event_info, !check_fname_outside_temp_buf()); - /* - That one is for "file_id: etc" below: in mysqlbinlog we want the #, in - SHOW BINLOG EVENTS we don't. - */ - my_b_printf(&cache, "#"); + /** + reduce the size of io cache so that the write function is called + for every call to my_b_printf(). + */ + DBUG_EXECUTE_IF ("simulate_create_event_write_error", + {(&cache)->write_pos= (&cache)->write_end; + DBUG_SET("+d,simulate_file_write_error");}); + /* + That one is for "file_id: etc" below: in mysqlbinlog we want the #, in + SHOW BINLOG EVENTS we don't. + */ + my_b_printf(&cache, "#"); } my_b_printf(&cache, " file_id: %d block_len: %d\n", file_id, block_len); @@ -7616,6 +7662,13 @@ void Execute_load_query_log_event::print(FILE* file, Write_on_release_cache cache(&print_event_info->head_cache, file); print_query_header(&cache, print_event_info); + /** + reduce the size of io cache so that the write function is called + for every call to my_b_printf(). + */ + DBUG_EXECUTE_IF ("simulate_execute_event_write_error", + {(&cache)->write_pos= (&cache)->write_end; + DBUG_SET("+d,simulate_file_write_error");}); if (local_fname) { diff --git a/sql/log_event.h b/sql/log_event.h index cccab93e0d5..19a77f03b84 100644 --- a/sql/log_event.h +++ b/sql/log_event.h @@ -284,6 +284,13 @@ struct sql_ex_info MAX_SIZE_LOG_EVENT_STATUS + /* status */ \ NAME_LEN + 1) +/* + The new option is added to handle large packets that are sent from the master + to the slave. It is used to increase the thd(max_allowed) for both the + DUMP thread on the master and the SQL/IO thread on the slave. +*/ +#define MAX_MAX_ALLOWED_PACKET 1024*1024*1024 + /* Event header offsets; these point to places inside the fixed header. @@ -2666,6 +2673,7 @@ public: bool is_null; uchar flags; #ifdef MYSQL_SERVER + bool deferred; User_var_log_event(THD* thd_arg, char *name_arg, uint name_len_arg, char *val_arg, ulong val_len_arg, Item_result type_arg, uint charset_number_arg, uchar flags_arg, @@ -2673,7 +2681,7 @@ public: :Log_event(thd_arg, 0, using_trans), name(name_arg), name_len(name_len_arg), val(val_arg), val_len(val_len_arg), type(type_arg), charset_number(charset_number_arg), - flags(flags_arg) + flags(flags_arg), deferred(false) { is_null= !val; if (direct) @@ -2690,6 +2698,13 @@ public: Log_event_type get_type_code() { return USER_VAR_EVENT;} #ifdef MYSQL_SERVER bool write(IO_CACHE* file); + /* + Getter and setter for deferred User-event. + Returns true if the event is not applied directly + and which case the applier adjusts execution path. + */ + bool is_deferred() { return deferred; } + void set_deferred() { deferred= val; } #endif bool is_valid() const { return 1; } diff --git a/sql/mysqld.cc b/sql/mysqld.cc index 063567388aa..aa5efe4fbe6 100644 --- a/sql/mysqld.cc +++ b/sql/mysqld.cc @@ -477,6 +477,7 @@ ulonglong slave_type_conversions_options; ulong thread_cache_size=0; ulonglong binlog_cache_size=0; ulonglong max_binlog_cache_size=0; +ulong slave_max_allowed_packet= 0; ulonglong binlog_stmt_cache_size=0; ulonglong max_binlog_stmt_cache_size=0; ulonglong query_cache_size=0; @@ -6371,7 +6372,7 @@ struct my_option my_long_options[]= "will not do updates to tables in databases that start with foo and whose " "table names start with bar.", 0, 0, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0}, - {"safe-mode", OPT_SAFE, "Skip some optimize stages (for testing).", + {"safe-mode", OPT_SAFE, "Skip some optimize stages (for testing). Deprecated.", 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0}, {"safe-user-create", 0, "Don't allow new user creation by the user who has no write privileges to the mysql.user table.", @@ -7612,6 +7613,8 @@ mysqld_get_one_option(int optid, #ifdef HAVE_QUERY_CACHE query_cache_size=0; #endif + sql_print_warning("The syntax '--safe-mode' is deprecated and will be " + "removed in a future release."); break; case (int) OPT_SKIP_PRIOR: opt_specialflag|= SPECIAL_NO_PRIOR; diff --git a/sql/mysqld.h b/sql/mysqld.h index f32b92633b7..56419acdcd4 100644 --- a/sql/mysqld.h +++ b/sql/mysqld.h @@ -170,6 +170,7 @@ extern ulong open_files_limit; extern ulonglong binlog_cache_size, binlog_stmt_cache_size; extern ulonglong max_binlog_cache_size, max_binlog_stmt_cache_size; extern ulong max_binlog_size, max_relay_log_size; +extern ulong slave_max_allowed_packet; extern ulong opt_binlog_rows_event_max_size; extern ulong rpl_recovery_rank, thread_cache_size; extern ulong stored_program_cache_size; diff --git a/sql/opt_range.cc b/sql/opt_range.cc index da328063e56..910bbf2d975 100644 --- a/sql/opt_range.cc +++ b/sql/opt_range.cc @@ -11804,9 +11804,10 @@ get_best_group_min_max(PARAM *param, SEL_TREE *tree, double read_time) have_min= TRUE; else if (min_max_item->sum_func() == Item_sum::MAX_FUNC) have_max= TRUE; - else if (min_max_item->sum_func() == Item_sum::COUNT_DISTINCT_FUNC || - min_max_item->sum_func() == Item_sum::SUM_DISTINCT_FUNC || - min_max_item->sum_func() == Item_sum::AVG_DISTINCT_FUNC) + else if (is_agg_distinct && + (min_max_item->sum_func() == Item_sum::COUNT_DISTINCT_FUNC || + min_max_item->sum_func() == Item_sum::SUM_DISTINCT_FUNC || + min_max_item->sum_func() == Item_sum::AVG_DISTINCT_FUNC)) continue; else DBUG_RETURN(NULL); diff --git a/sql/protocol.cc b/sql/protocol.cc index 10c85939986..3af7dc88b88 100644 --- a/sql/protocol.cc +++ b/sql/protocol.cc @@ -1,5 +1,5 @@ -/* Copyright (c) 2000, 2011, Oracle and/or its affiliates. - Copyright (c) 2008, 2011, Monty Program Ab +/* Copyright (c) 2000, 2012, Oracle and/or its affiliates. + Copyright (c) 2008, 2012, Monty Program Ab This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -775,6 +775,8 @@ bool Protocol::send_result_set_metadata(List<Item> *list, uint flags) /* Store fixed length fields */ pos= (char*) local_packet->ptr()+local_packet->length(); *pos++= 12; // Length of packed fields + /* inject a NULL to test the client */ + DBUG_EXECUTE_IF("poison_rs_fields", pos[-1]= 0xfb;); if (item->charset_for_protocol() == &my_charset_bin || thd_charset == NULL) { /* No conversion */ diff --git a/sql/rpl_utility.h b/sql/rpl_utility.h index 9046891e27f..79f4517c492 100644 --- a/sql/rpl_utility.h +++ b/sql/rpl_utility.h @@ -272,7 +272,7 @@ private: public: Deferred_log_events(Relay_log_info *rli); ~Deferred_log_events(); - /* queue for exection at Query-log-event time prior the Query */; + /* queue for exection at Query-log-event time prior the Query */ int add(Log_event *ev); bool is_empty(); bool execute(Relay_log_info *rli); diff --git a/sql/slave.cc b/sql/slave.cc index fb4c72c10bd..9149cd82d5e 100644 --- a/sql/slave.cc +++ b/sql/slave.cc @@ -2281,8 +2281,7 @@ static int init_slave_thread(THD* thd, SLAVE_THD_TYPE thd_type) slave threads, since a replication event can become this much larger than the corresponding packet (query) sent from client to master. */ - thd->variables.max_allowed_packet= global_system_variables.max_allowed_packet - + MAX_LOG_EVENT_HEADER; /* note, incr over the global not session var */ + thd->variables.max_allowed_packet= slave_max_allowed_packet; thd->slave_thread = 1; thd->enable_slow_log= opt_log_slow_slave_statements; thd->variables.log_slow_filter= global_system_variables.log_slow_filter; @@ -3070,6 +3069,7 @@ pthread_handler_t handle_slave_io(void *arg) thread, since a replication event can become this much larger than the corresponding packet (query) sent from client to master. */ + thd->net.max_packet_size= slave_max_allowed_packet; mysql->net.max_packet_size= thd->net.max_packet_size+= MAX_LOG_EVENT_HEADER; } else @@ -3202,12 +3202,12 @@ reading event")) switch (mysql_error_number) { case CR_NET_PACKET_TOO_LARGE: sql_print_error("\ -Log entry on master is longer than max_allowed_packet (%ld) on \ +Log entry on master is longer than slave_max_allowed_packet (%lu) on \ slave. If the entry is correct, restart the server with a higher value of \ -max_allowed_packet", - thd->variables.max_allowed_packet); +slave_max_allowed_packet", + slave_max_allowed_packet); mi->report(ERROR_LEVEL, ER_NET_PACKET_TOO_LARGE, - "%s", ER(ER_NET_PACKET_TOO_LARGE)); + "%s", "Got a packet bigger than 'slave_max_allowed_packet' bytes"); goto err; case ER_MASTER_FATAL_ERROR_READING_BINLOG: mi->report(ERROR_LEVEL, ER_MASTER_FATAL_ERROR_READING_BINLOG, diff --git a/sql/sql_acl.cc b/sql/sql_acl.cc index 41c04b9c413..8f27c45247e 100644 --- a/sql/sql_acl.cc +++ b/sql/sql_acl.cc @@ -8044,6 +8044,7 @@ static bool send_server_handshake_packet(MPVIO_EXT *mpvio, int2store(end+3, mpvio->thd->server_status); int2store(end+5, thd->client_capabilities >> 16); end[7]= data_len; + DBUG_EXECUTE_IF("poison_srv_handshake_scramble_len", end[7]= -100;); bzero(end + 8, 10); end+= 18; /* write scramble tail */ diff --git a/sql/sql_class.cc b/sql/sql_class.cc index 0165aa9f6e5..f77ef114d2d 100644 --- a/sql/sql_class.cc +++ b/sql/sql_class.cc @@ -5186,6 +5186,134 @@ show_query_type(THD::enum_binlog_query_type qtype) } #endif +/* + Constants required for the limit unsafe warnings suppression +*/ +//seconds after which the limit unsafe warnings suppression will be activated +#define LIMIT_UNSAFE_WARNING_ACTIVATION_TIMEOUT 50 +//number of limit unsafe warnings after which the suppression will be activated +#define LIMIT_UNSAFE_WARNING_ACTIVATION_THRESHOLD_COUNT 50 + +static ulonglong limit_unsafe_suppression_start_time= 0; +static bool unsafe_warning_suppression_is_activated= false; +static int limit_unsafe_warning_count= 0; + +/** + Auxiliary function to reset the limit unsafety warning suppression. +*/ +static void reset_binlog_unsafe_suppression() +{ + DBUG_ENTER("reset_binlog_unsafe_suppression"); + unsafe_warning_suppression_is_activated= false; + limit_unsafe_warning_count= 0; + limit_unsafe_suppression_start_time= my_interval_timer()/10000000; + DBUG_VOID_RETURN; +} + +/** + Auxiliary function to print warning in the error log. +*/ +static void print_unsafe_warning_to_log(int unsafe_type, char* buf, + char* query) +{ + DBUG_ENTER("print_unsafe_warning_in_log"); + sprintf(buf, ER(ER_BINLOG_UNSAFE_STATEMENT), + ER(LEX::binlog_stmt_unsafe_errcode[unsafe_type])); + sql_print_warning(ER(ER_MESSAGE_AND_STATEMENT), buf, query); + DBUG_VOID_RETURN; +} + +/** + Auxiliary function to check if the warning for limit unsafety should be + thrown or suppressed. Details of the implementation can be found in the + comments inline. + SYNOPSIS: + @params + buf - buffer to hold the warning message text + unsafe_type - The type of unsafety. + query - The actual query statement. + + TODO: Remove this function and implement a general service for all warnings + that would prevent flooding the error log. +*/ +static void do_unsafe_limit_checkout(char* buf, int unsafe_type, char* query) +{ + ulonglong now= 0; + DBUG_ENTER("do_unsafe_limit_checkout"); + DBUG_ASSERT(unsafe_type == LEX::BINLOG_STMT_UNSAFE_LIMIT); + limit_unsafe_warning_count++; + /* + INITIALIZING: + If this is the first time this function is called with log warning + enabled, the monitoring the unsafe warnings should start. + */ + if (limit_unsafe_suppression_start_time == 0) + { + limit_unsafe_suppression_start_time= my_interval_timer()/10000000; + print_unsafe_warning_to_log(unsafe_type, buf, query); + } + else + { + if (!unsafe_warning_suppression_is_activated) + print_unsafe_warning_to_log(unsafe_type, buf, query); + + if (limit_unsafe_warning_count >= + LIMIT_UNSAFE_WARNING_ACTIVATION_THRESHOLD_COUNT) + { + now= my_interval_timer()/10000000; + if (!unsafe_warning_suppression_is_activated) + { + /* + ACTIVATION: + We got LIMIT_UNSAFE_WARNING_ACTIVATION_THRESHOLD_COUNT warnings in + less than LIMIT_UNSAFE_WARNING_ACTIVATION_TIMEOUT we activate the + suppression. + */ + if ((now-limit_unsafe_suppression_start_time) <= + LIMIT_UNSAFE_WARNING_ACTIVATION_TIMEOUT) + { + unsafe_warning_suppression_is_activated= true; + DBUG_PRINT("info",("A warning flood has been detected and the limit \ +unsafety warning suppression has been activated.")); + } + else + { + /* + there is no flooding till now, therefore we restart the monitoring + */ + limit_unsafe_suppression_start_time= my_interval_timer()/10000000; + limit_unsafe_warning_count= 0; + } + } + else + { + /* + Print the suppression note and the unsafe warning. + */ + sql_print_information("The following warning was suppressed %d times \ +during the last %d seconds in the error log", + limit_unsafe_warning_count, + (int) + (now-limit_unsafe_suppression_start_time)); + print_unsafe_warning_to_log(unsafe_type, buf, query); + /* + DEACTIVATION: We got LIMIT_UNSAFE_WARNING_ACTIVATION_THRESHOLD_COUNT + warnings in more than LIMIT_UNSAFE_WARNING_ACTIVATION_TIMEOUT, the + suppression should be deactivated. + */ + if ((now - limit_unsafe_suppression_start_time) > + LIMIT_UNSAFE_WARNING_ACTIVATION_TIMEOUT) + { + reset_binlog_unsafe_suppression(); + DBUG_PRINT("info",("The limit unsafety warning supression has been \ +deactivated")); + } + } + limit_unsafe_warning_count= 0; + } + } + DBUG_VOID_RETURN; +} /** Auxiliary method used by @c binlog_query() to raise warnings. @@ -5195,6 +5323,7 @@ show_query_type(THD::enum_binlog_query_type qtype) */ void THD::issue_unsafe_warnings() { + char buf[MYSQL_ERRMSG_SIZE * 2]; DBUG_ENTER("issue_unsafe_warnings"); /* Ensure that binlog_unsafe_warning_flags is big enough to hold all @@ -5220,17 +5349,16 @@ void THD::issue_unsafe_warnings() ER(LEX::binlog_stmt_unsafe_errcode[unsafe_type])); if (global_system_variables.log_warnings) { - char buf[MYSQL_ERRMSG_SIZE * 2]; - sprintf(buf, ER(ER_BINLOG_UNSAFE_STATEMENT), - ER(LEX::binlog_stmt_unsafe_errcode[unsafe_type])); - sql_print_warning(ER(ER_MESSAGE_AND_STATEMENT), buf, query()); + if (unsafe_type == LEX::BINLOG_STMT_UNSAFE_LIMIT) + do_unsafe_limit_checkout( buf, unsafe_type, query()); + else //cases other than LIMIT unsafety + print_unsafe_warning_to_log(unsafe_type, buf, query()); } } } DBUG_VOID_RETURN; } - /** Log the current query. @@ -5406,3 +5534,4 @@ bool Discrete_intervals_list::append(Discrete_interval *new_interval) } #endif /* !defined(MYSQL_CLIENT) */ + diff --git a/sql/sql_delete.cc b/sql/sql_delete.cc index 5128b1284dd..81e3dca50ae 100644 --- a/sql/sql_delete.cc +++ b/sql/sql_delete.cc @@ -368,8 +368,14 @@ bool mysql_delete(THD *thd, TABLE_LIST *table_list, COND *conds, } } } - else + /* + Don't try unlocking the row if skip_record reported an error since in + this case the transaction might have been rolled back already. + */ + else if (!thd->is_error()) table->file->unlock_row(); // Row failed selection, release lock on it + else + break; } killed_status= thd->killed; if (killed_status != NOT_KILLED || thd->is_error()) diff --git a/sql/sql_plugin.cc b/sql/sql_plugin.cc index ff43c7abd55..3b55402bab3 100644 --- a/sql/sql_plugin.cc +++ b/sql/sql_plugin.cc @@ -907,7 +907,7 @@ bool plugin_is_ready(const LEX_STRING *name, int type) } -SHOW_COMP_OPTION plugin_status(const char *name, int len, size_t type) +SHOW_COMP_OPTION plugin_status(const char *name, size_t len, int type) { LEX_STRING plugin_name= { (char *) name, len }; return plugin_status(&plugin_name, type); diff --git a/sql/sql_plugin.h b/sql/sql_plugin.h index eaa368f3515..be1cfcdcc4f 100644 --- a/sql/sql_plugin.h +++ b/sql/sql_plugin.h @@ -1,5 +1,5 @@ -/* - Copyright (c) 2005, 2010, Oracle and/or its affiliates. +/* Copyright (c) 2005, 2012, Oracle and/or its affiliates. + Copyright (c) 2009, 2012, Monty Program Ab This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -165,7 +165,7 @@ extern bool mysql_uninstall_plugin(THD *thd, const LEX_STRING *name, extern bool plugin_register_builtin(struct st_mysql_plugin *plugin); extern void plugin_thdvar_init(THD *thd); extern void plugin_thdvar_cleanup(THD *thd); -extern SHOW_COMP_OPTION plugin_status(const char *name, int len, size_t type); +extern SHOW_COMP_OPTION plugin_status(const char *name, size_t len, int type); extern bool check_valid_path(const char *path, size_t length); typedef my_bool (plugin_foreach_func)(THD *thd, diff --git a/sql/sql_profile.cc b/sql/sql_profile.cc index b3348698a35..2d00a19870b 100644 --- a/sql/sql_profile.cc +++ b/sql/sql_profile.cc @@ -1,5 +1,5 @@ -/* Copyright (c) 2007, 2011, Oracle and/or its affiliates. - Copyright (c) 2008, 2011, Monty Program Ab +/* Copyright (c) 2007, 2012, Oracle and/or its affiliates. + Copyright (c) 2008, 2012, Monty Program Ab This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -88,8 +88,8 @@ ST_FIELD_INFO query_profile_statistics_info[]= int make_profile_table_for_show(THD *thd, ST_SCHEMA_TABLE *schema_table) { - int profile_options = thd->lex->profile_options; - int fields_include_condition_truth_values[]= { + uint profile_options = thd->lex->profile_options; + uint fields_include_condition_truth_values[]= { FALSE, /* Query_id */ FALSE, /* Seq */ TRUE, /* Status */ diff --git a/sql/sql_repl.cc b/sql/sql_repl.cc index fafa7a4389e..751c0d6ada5 100644 --- a/sql/sql_repl.cc +++ b/sql/sql_repl.cc @@ -653,7 +653,8 @@ void mysql_binlog_send(THD* thd, char* log_ident, my_off_t pos, heartbeat_ts= &heartbeat_buf; set_timespec_nsec(*heartbeat_ts, 0); } - sql_print_information("Start binlog_dump to slave_server(%d), pos(%s, %lu)", + if (global_system_variables.log_warnings > 1) + sql_print_information("Start binlog_dump to slave_server(%d), pos(%s, %lu)", thd->server_id, log_ident, (ulong)pos); if (RUN_HOOK(binlog_transmit, transmit_start, (thd, flags, log_ident, pos))) { @@ -765,7 +766,7 @@ impossible position"; this larger than the corresponding packet (query) sent from client to master. */ - thd->variables.max_allowed_packet+= MAX_LOG_EVENT_HEADER; + thd->variables.max_allowed_packet= MAX_MAX_ALLOWED_PACKET; /* We can set log_lock now, it does not move (it's a member of diff --git a/sql/sql_select.cc b/sql/sql_select.cc index 0ed351b720c..da43b4b5e30 100644 --- a/sql/sql_select.cc +++ b/sql/sql_select.cc @@ -715,6 +715,8 @@ JOIN::prepare(Item ***rref_pointer_array, if (having) { + Query_arena backup, *arena; + arena= thd->activate_stmt_arena_if_needed(&backup); nesting_map save_allow_sum_func= thd->lex->allow_sum_func; thd->where="having clause"; thd->lex->allow_sum_func|= 1 << select_lex_arg->nest_level; @@ -730,6 +732,10 @@ JOIN::prepare(Item ***rref_pointer_array, (having->fix_fields(thd, &having) || having->check_cols(1))); select_lex->having_fix_field= 0; + select_lex->having= having; + if (arena) + thd->restore_active_arena(arena, &backup); + if (having_fix_rc || thd->is_error()) DBUG_RETURN(-1); /* purecov: inspected */ thd->lex->allow_sum_func= save_allow_sum_func; @@ -16454,7 +16460,8 @@ int report_error(TABLE *table, int error) Locking reads can legally return also these errors, do not print them to the .err log */ - if (error != HA_ERR_LOCK_DEADLOCK && error != HA_ERR_LOCK_WAIT_TIMEOUT) + if (error != HA_ERR_LOCK_DEADLOCK && error != HA_ERR_LOCK_WAIT_TIMEOUT + && !table->in_use->killed) { push_warning_printf(table->in_use, MYSQL_ERROR::WARN_LEVEL_WARN, error, "Got error %d when reading table `%s`.`%s`", @@ -18861,6 +18868,14 @@ create_sort_index(THD *thd, JOIN *join, ORDER *order, /* Currently ORDER BY ... LIMIT is not supported in subqueries. */ DBUG_ASSERT(join->group_list || !join->is_in_subquery()); + /* + If we have a select->quick object that is created outside of + create_sort_index() and this is part of a subquery that + potentially can be executed multiple times then we should not + delete the quick object on exit from this function. + */ + bool keep_quick= select && select->quick && join->join_tab_save; + /* When there is SQL_BIG_RESULT do not sort using index for GROUP BY, and thus force sorting on disk unless a group min-max optimization @@ -18912,6 +18927,7 @@ create_sort_index(THD *thd, JOIN *join, ORDER *order, get_quick_select_for_ref(thd, table, &tab->ref, tab->found_records)))) goto err; + DBUG_ASSERT(!keep_quick); } } @@ -18944,9 +18960,26 @@ create_sort_index(THD *thd, JOIN *join, ORDER *order, tablesort_result_cache= table->sort.io_cache; table->sort.io_cache= NULL; - select->cleanup(); // filesort did select - table->quick_keys.clear_all(); // as far as we cleanup select->quick - table->intersect_keys.clear_all(); + /* + If a quick object was created outside of create_sort_index() + that might be reused, then do not call select->cleanup() since + it will delete the quick object. + */ + if (!keep_quick) + { + select->cleanup(); + /* + The select object should now be ready for the next use. If it + is re-used then there exists a backup copy of this join tab + which has the pointer to it. The join tab will be restored in + JOIN::reset(). So here we just delete the pointer to it. + */ + tab->select= NULL; + // If we deleted the quick select object we need to clear quick_keys + table->quick_keys.clear_all(); + table->intersect_keys.clear_all(); + } + // Restore the output resultset table->sort.io_cache= tablesort_result_cache; } tab->set_select_cond(NULL, __LINE__); diff --git a/sql/sql_show.cc b/sql/sql_show.cc index 1e2ed90e1b7..009ced7810a 100644 --- a/sql/sql_show.cc +++ b/sql/sql_show.cc @@ -3225,9 +3225,12 @@ int make_db_list(THD *thd, List<LEX_STRING> *files, /* If we have db lookup vaule we just add it to list and - exit from the function + exit from the function. + We don't do this for database names longer than the maximum + path length. */ - if (lookup_field_vals->db_value.str) + if (lookup_field_vals->db_value.str && + lookup_field_vals->db_value.length < FN_REFLEN) { if (is_infoschema_db(lookup_field_vals->db_value.str, lookup_field_vals->db_value.length)) diff --git a/sql/sql_table.cc b/sql/sql_table.cc index eb4ded0c502..dbc79c01485 100644 --- a/sql/sql_table.cc +++ b/sql/sql_table.cc @@ -6096,8 +6096,26 @@ bool mysql_alter_table(THD *thd,char *new_db, char *new_name, } else { + MDL_request_list mdl_requests; + MDL_request target_db_mdl_request; + target_mdl_request.init(MDL_key::TABLE, new_db, new_name, MDL_EXCLUSIVE, MDL_TRANSACTION); + mdl_requests.push_front(&target_mdl_request); + + /* + If we are moving the table to a different database, we also + need IX lock on the database name so that the target database + is protected by MDL while the table is moved. + */ + if (new_db != db) + { + target_db_mdl_request.init(MDL_key::SCHEMA, new_db, "", + MDL_INTENTION_EXCLUSIVE, + MDL_TRANSACTION); + mdl_requests.push_front(&target_db_mdl_request); + } + /* Global intention exclusive lock must have been already acquired when table to be altered was open, so there is no need to do it here. @@ -6106,14 +6124,10 @@ bool mysql_alter_table(THD *thd,char *new_db, char *new_name, "", "", MDL_INTENTION_EXCLUSIVE)); - if (thd->mdl_context.try_acquire_lock(&target_mdl_request)) + if (thd->mdl_context.acquire_locks(&mdl_requests, + thd->variables.lock_wait_timeout)) DBUG_RETURN(TRUE); - if (target_mdl_request.ticket == NULL) - { - /* Table exists and is locked by some thread. */ - my_error(ER_TABLE_EXISTS_ERROR, MYF(0), new_alias); - DBUG_RETURN(TRUE); - } + DEBUG_SYNC(thd, "locked_table_name"); /* Table maybe does not exist, but we got an exclusive lock @@ -6539,11 +6553,23 @@ bool mysql_alter_table(THD *thd,char *new_db, char *new_name, the primary key is not added and dropped in the same statement. Otherwise we have to recreate the table. need_copy_table is no-zero at this place. + + Also, in-place is not possible if we add a primary key + and drop another key in the same statement. If the drop fails, + we will not be able to revert adding of primary key. */ if ( pk_changed < 2 ) { - if ((alter_flags & needed_inplace_with_read_flags) == - needed_inplace_with_read_flags) + if ((needed_inplace_with_read_flags & HA_INPLACE_ADD_PK_INDEX_NO_WRITE) && + index_drop_count > 0) + { + /* + Do copy, not in-place ALTER. + Avoid setting ALTER_TABLE_METADATA_ONLY. + */ + } + else if ((alter_flags & needed_inplace_with_read_flags) == + needed_inplace_with_read_flags) { /* All required in-place flags to allow concurrent reads are present. */ need_copy_table= ALTER_TABLE_METADATA_ONLY; @@ -6821,17 +6847,38 @@ bool mysql_alter_table(THD *thd,char *new_db, char *new_name, Tell the handler to prepare for drop indexes. This re-numbers the indexes to get rid of gaps. */ - if ((error= table->file->prepare_drop_index(table, key_numbers, - index_drop_count))) + error= table->file->prepare_drop_index(table, key_numbers, + index_drop_count); + if (!error) { - table->file->print_error(error, MYF(0)); - goto err_new_table_cleanup; + /* Tell the handler to finally drop the indexes. */ + error= table->file->final_drop_index(table); } - /* Tell the handler to finally drop the indexes. */ - if ((error= table->file->final_drop_index(table))) + if (error) { table->file->print_error(error, MYF(0)); + if (index_add_count) // Drop any new indexes added. + { + /* + Temporarily set table-key_info to include information about the + indexes added above that we now need to drop. + */ + KEY *save_key_info= table->key_info; + table->key_info= key_info_buffer; + if ((error= table->file->prepare_drop_index(table, index_add_buffer, + index_add_count))) + table->file->print_error(error, MYF(0)); + else if ((error= table->file->final_drop_index(table))) + table->file->print_error(error, MYF(0)); + table->key_info= save_key_info; + } + + /* + Mark this TABLE instance as stale to avoid + out-of-sync index information. + */ + table->m_needs_reopen= true; goto err_new_table_cleanup; } } diff --git a/sql/sql_yacc.yy b/sql/sql_yacc.yy index 4e3629080be..1b5f741d44a 100644 --- a/sql/sql_yacc.yy +++ b/sql/sql_yacc.yy @@ -5644,7 +5644,23 @@ type: $$= MYSQL_TYPE_VARCHAR; } | YEAR_SYM opt_field_length field_options - { $$=MYSQL_TYPE_YEAR; } + { + if (Lex->length) + { + errno= 0; + ulong length= strtoul(Lex->length, NULL, 10); + if (errno == 0 && length <= MAX_FIELD_BLOBLENGTH && length != 4) + { + char buff[sizeof("YEAR()") + MY_INT64_NUM_DECIMAL_DIGITS + 1]; + my_snprintf(buff, sizeof(buff), "YEAR(%lu)", length); + push_warning_printf(YYTHD, MYSQL_ERROR::WARN_LEVEL_NOTE, + ER_WARN_DEPRECATED_SYNTAX, + ER(ER_WARN_DEPRECATED_SYNTAX), + buff, "YEAR(4)"); + } + } + $$=MYSQL_TYPE_YEAR; + } | DATE_SYM { $$=MYSQL_TYPE_DATE; } | TIME_SYM opt_field_length diff --git a/sql/sys_vars.cc b/sql/sys_vars.cc index e1cadb52648..6cc9c9577ee 100644 --- a/sql/sys_vars.cc +++ b/sql/sys_vars.cc @@ -48,6 +48,7 @@ #include <myisam.h> #include "log_slow.h" +#include "log_event.h" #ifdef WITH_PERFSCHEMA_STORAGE_ENGINE #include "../storage/perfschema/pfs_server.h" #endif /* WITH_PERFSCHEMA_STORAGE_ENGINE */ @@ -1052,6 +1053,14 @@ static Sys_var_ulong Sys_max_allowed_packet( BLOCK_SIZE(1024), NO_MUTEX_GUARD, NOT_IN_BINLOG, ON_CHECK(check_max_allowed_packet)); +static Sys_var_ulong Sys_slave_max_allowed_packet( + "slave_max_allowed_packet", + "The maximum packet length to sent successfully from the master to slave.", + GLOBAL_VAR(slave_max_allowed_packet), CMD_LINE(REQUIRED_ARG), + VALID_RANGE(1024, MAX_MAX_ALLOWED_PACKET), + DEFAULT(MAX_MAX_ALLOWED_PACKET), + BLOCK_SIZE(1024)); + static Sys_var_ulonglong Sys_max_binlog_cache_size( "max_binlog_cache_size", "Sets the total size of the transactional cache", diff --git a/storage/archive/azio.c b/storage/archive/azio.c index 8fc85965cf0..92d7ad70344 100644 --- a/storage/archive/azio.c +++ b/storage/archive/azio.c @@ -39,6 +39,10 @@ void putLong(File file, uLong x); uLong getLong(azio_stream *s); void read_header(azio_stream *s, unsigned char *buffer); +#ifdef HAVE_PSI_INTERFACE +extern PSI_file_key arch_key_file_data; +#endif + /* =========================================================================== Opens a gzip (.gz) file for reading or writing. The mode parameter is as in fopen ("rb" or "wb"). The file is given either by file descriptor @@ -115,7 +119,7 @@ int az_open (azio_stream *s, const char *path, int Flags, File fd) s->stream.avail_out = AZ_BUFSIZE_WRITE; errno = 0; - s->file = fd < 0 ? my_open(path, Flags, MYF(0)) : fd; + s->file = fd < 0 ? mysql_file_open(arch_key_file_data, path, Flags, MYF(0)) : fd; DBUG_EXECUTE_IF("simulate_archive_open_failure", { if (s->file >= 0) @@ -248,8 +252,8 @@ int get_byte(s) if (s->stream.avail_in == 0) { errno = 0; - s->stream.avail_in= (uInt) my_read(s->file, (uchar *)s->inbuf, - AZ_BUFSIZE_READ, MYF(0)); + s->stream.avail_in= (uInt) mysql_file_read(s->file, (uchar *)s->inbuf, + AZ_BUFSIZE_READ, MYF(0)); if (s->stream.avail_in == 0) { s->z_eof = 1; @@ -290,7 +294,8 @@ void check_header(azio_stream *s) if (len < 2) { if (len) s->inbuf[0] = s->stream.next_in[0]; errno = 0; - len = (uInt)my_read(s->file, (uchar *)s->inbuf + len, AZ_BUFSIZE_READ >> len, MYF(0)); + len = (uInt)mysql_file_read(s->file, (uchar *)s->inbuf + len, + AZ_BUFSIZE_READ >> len, MYF(0)); if (len == (uInt)-1) s->z_err = Z_ERRNO; s->stream.avail_in += len; s->stream.next_in = s->inbuf; @@ -481,7 +486,8 @@ unsigned int ZEXPORT azread ( azio_stream *s, voidp buf, size_t len, int *error) if (s->stream.avail_out > 0) { s->stream.avail_out -= - (uInt)my_read(s->file, (uchar *)next_out, s->stream.avail_out, MYF(0)); + (uInt)mysql_file_read(s->file, (uchar *)next_out, + s->stream.avail_out, MYF(0)); } len -= s->stream.avail_out; s->in += len; @@ -494,7 +500,8 @@ unsigned int ZEXPORT azread ( azio_stream *s, voidp buf, size_t len, int *error) if (s->stream.avail_in == 0 && !s->z_eof) { errno = 0; - s->stream.avail_in = (uInt)my_read(s->file, (uchar *)s->inbuf, AZ_BUFSIZE_READ, MYF(0)); + s->stream.avail_in = (uInt)mysql_file_read(s->file, (uchar *)s->inbuf, + AZ_BUFSIZE_READ, MYF(0)); if (s->stream.avail_in == 0) { s->z_eof = 1; @@ -561,8 +568,8 @@ unsigned int azwrite (azio_stream *s, const voidp buf, unsigned int len) { s->stream.next_out = s->outbuf; - if (my_write(s->file, (uchar *)s->outbuf, AZ_BUFSIZE_WRITE, - MYF(0)) != AZ_BUFSIZE_WRITE) + if (mysql_file_write(s->file, (uchar *)s->outbuf, AZ_BUFSIZE_WRITE, + MYF(0)) != AZ_BUFSIZE_WRITE) { s->z_err = Z_ERRNO; break; @@ -609,7 +616,7 @@ int do_flush (azio_stream *s, int flush) if (len != 0) { s->check_point= my_tell(s->file, MYF(0)); - if ((uInt)my_write(s->file, (uchar *)s->outbuf, len, MYF(0)) != len) + if ((uInt)mysql_file_write(s->file, (uchar *)s->outbuf, len, MYF(0)) != len) { s->z_err = Z_ERRNO; return Z_ERRNO; @@ -796,7 +803,7 @@ void putLong (File file, uLong x) for (n = 0; n < 4; n++) { buffer[0]= (int)(x & 0xff); - my_write(file, buffer, 1, MYF(0)); + mysql_file_write(file, buffer, 1, MYF(0)); x >>= 8; } } diff --git a/storage/archive/ha_archive.cc b/storage/archive/ha_archive.cc index 6b29c6d9d53..b21e0561322 100644 --- a/storage/archive/ha_archive.cc +++ b/storage/archive/ha_archive.cc @@ -112,6 +112,10 @@ static HASH archive_open_tables; #define DATA_BUFFER_SIZE 2 // Size of the data used in the data file #define ARCHIVE_CHECK_HEADER 254 // The number we use to determine corruption +#ifdef HAVE_PSI_INTERFACE +extern "C" PSI_file_key arch_key_file_data; +#endif + /* Static declarations for handerton */ static handler *archive_create_handler(handlerton *hton, TABLE_SHARE *table, @@ -157,6 +161,14 @@ static PSI_mutex_info all_archive_mutexes[]= { &az_key_mutex_ARCHIVE_SHARE_mutex, "ARCHIVE_SHARE::mutex", 0} }; +PSI_file_key arch_key_file_metadata, arch_key_file_data, arch_key_file_frm; +static PSI_file_info all_archive_files[]= +{ + { &arch_key_file_metadata, "metadata", 0}, + { &arch_key_file_data, "data", 0}, + { &arch_key_file_frm, "FRM", 0} +}; + static void init_archive_psi_keys(void) { const char* category= "archive"; @@ -167,6 +179,9 @@ static void init_archive_psi_keys(void) count= array_elements(all_archive_mutexes); PSI_server->register_mutex(category, all_archive_mutexes, count); + + count= array_elements(all_archive_files); + PSI_server->register_file(category, all_archive_files, count); } #endif /* HAVE_PSI_INTERFACE */ @@ -260,7 +275,7 @@ int archive_discover(handlerton *hton, THD* thd, const char *db, build_table_filename(az_file, sizeof(az_file) - 1, db, name, ARZ, 0); - if (!(my_stat(az_file, &file_stat, MYF(0)))) + if (!(mysql_file_stat(arch_key_file_data, az_file, &file_stat, MYF(0)))) goto err; if (!(azopen(&frm_stream, az_file, O_RDONLY|O_BINARY))) @@ -723,7 +738,7 @@ int ha_archive::create(const char *name, TABLE *table_arg, There is a chance that the file was "discovered". In this case just use whatever file is there. */ - if (!(my_stat(name_buff, &file_stat, MYF(0)))) + if (!(mysql_file_stat(arch_key_file_data, name_buff, &file_stat, MYF(0)))) { my_errno= 0; if (!(azopen(&create_stream, name_buff, O_CREAT|O_RDWR|O_BINARY))) @@ -740,19 +755,19 @@ int ha_archive::create(const char *name, TABLE *table_arg, /* Here is where we open up the frm and pass it to archive to store */ - if ((frm_file= my_open(name_buff, O_RDONLY, MYF(0))) > 0) + if ((frm_file= mysql_file_open(arch_key_file_frm, name_buff, O_RDONLY, MYF(0))) >= 0) { if (!mysql_file_fstat(frm_file, &file_stat, MYF(MY_WME))) { frm_ptr= (uchar *)my_malloc(sizeof(uchar) * (size_t)file_stat.st_size, MYF(0)); if (frm_ptr) { - my_read(frm_file, frm_ptr, (size_t)file_stat.st_size, MYF(0)); + mysql_file_read(frm_file, frm_ptr, (size_t)file_stat.st_size, MYF(0)); azwrite_frm(&create_stream, (char *)frm_ptr, (size_t)file_stat.st_size); my_free(frm_ptr); } } - my_close(frm_file, MYF(0)); + mysql_file_close(frm_file, MYF(0)); } if (create_info->comment.str) @@ -1615,7 +1630,7 @@ int ha_archive::info(uint flag) { MY_STAT file_stat; // Stat information for the data file - (void) my_stat(share->data_file_name, &file_stat, MYF(MY_WME)); + (void) mysql_file_stat(arch_key_file_data, share->data_file_name, &file_stat, MYF(MY_WME)); if (flag & HA_STATUS_TIME) stats.update_time= (ulong) file_stat.st_mtime; diff --git a/storage/innobase/btr/btr0btr.c b/storage/innobase/btr/btr0btr.c index fc3cdaf3cf1..b714219e304 100644 --- a/storage/innobase/btr/btr0btr.c +++ b/storage/innobase/btr/btr0btr.c @@ -42,6 +42,7 @@ Created 6/2/1994 Heikki Tuuri #include "ibuf0ibuf.h" #include "trx0trx.h" +#endif /* UNIV_HOTBACKUP */ /**************************************************************//** Report that an index page is corrupted. */ UNIV_INTERN @@ -64,6 +65,7 @@ btr_corruption_report( buf_page_print(buf_block_get_frame(block), 0, 0); } +#ifndef UNIV_HOTBACKUP #ifdef UNIV_BLOB_DEBUG # include "srv0srv.h" # include "ut0rbt.h" @@ -1575,7 +1577,9 @@ btr_page_reorganize_low( dict_index_t* index, /*!< in: record descriptor */ mtr_t* mtr) /*!< in: mtr */ { +#ifndef UNIV_HOTBACKUP buf_pool_t* buf_pool = buf_pool_from_bpage(&block->page); +#endif /* !UNIV_HOTBACKUP */ page_t* page = buf_block_get_frame(block); page_zip_des_t* page_zip = buf_block_get_page_zip(block); buf_block_t* temp_block; diff --git a/storage/innobase/buf/buf0buf.c b/storage/innobase/buf/buf0buf.c index 1672057d552..32d376136e6 100644 --- a/storage/innobase/buf/buf0buf.c +++ b/storage/innobase/buf/buf0buf.c @@ -302,7 +302,6 @@ struct buf_chunk_struct{ was allocated for the frames */ buf_block_t* blocks; /*!< array of buffer control blocks */ }; -#endif /* !UNIV_HOTBACKUP */ /********************************************************************//** Gets the smallest oldest_modification lsn for any page in the pool. Returns @@ -438,6 +437,7 @@ buf_block_alloc( return(block); } +#endif /* !UNIV_HOTBACKUP */ /********************************************************************//** Calculates a page checksum which is stored to the page when it is written @@ -3470,9 +3470,10 @@ buf_mark_space_corrupt( /********************************************************************//** Completes an asynchronous read or write request of a file page to or from -the buffer pool. */ +the buffer pool. +@return TRUE if successful */ UNIV_INTERN -void +ibool buf_page_io_complete( /*=================*/ buf_page_t* bpage) /*!< in: pointer to the block in question */ @@ -3599,7 +3600,7 @@ corrupt: table as corrupted instead of crashing server */ if (bpage->space > TRX_SYS_SPACE && buf_mark_space_corrupt(bpage)) { - return; + return(FALSE); } else { fputs("InnoDB: Ending processing" " because of" @@ -3689,6 +3690,8 @@ corrupt: mutex_exit(buf_page_get_mutex(bpage)); buf_pool_mutex_exit(buf_pool); + + return(TRUE); } /*********************************************************************//** diff --git a/storage/innobase/buf/buf0lru.c b/storage/innobase/buf/buf0lru.c index 8e787fdba17..7c8100df58e 100644 --- a/storage/innobase/buf/buf0lru.c +++ b/storage/innobase/buf/buf0lru.c @@ -2164,9 +2164,23 @@ buf_LRU_free_one_page( be in a state where it can be freed; there may or may not be a hash index to the page */ { +#ifdef UNIV_DEBUG + buf_pool_t* buf_pool = buf_pool_from_bpage(bpage); +#endif + mutex_t* block_mutex = buf_page_get_mutex(bpage); + + ut_ad(buf_pool_mutex_own(buf_pool)); + ut_ad(mutex_own(block_mutex)); + if (buf_LRU_block_remove_hashed_page(bpage, TRUE) != BUF_BLOCK_ZIP_FREE) { buf_LRU_block_free_hashed_page((buf_block_t*) bpage); + } else { + /* The block_mutex should have been released by + buf_LRU_block_remove_hashed_page() when it returns + BUF_BLOCK_ZIP_FREE. */ + ut_ad(block_mutex == &buf_pool->zip_mutex); + mutex_enter(block_mutex); } } diff --git a/storage/innobase/buf/buf0rea.c b/storage/innobase/buf/buf0rea.c index da804a66b29..40550186191 100644 --- a/storage/innobase/buf/buf0rea.c +++ b/storage/innobase/buf/buf0rea.c @@ -51,6 +51,44 @@ i/o-fixed buffer blocks */ #define BUF_READ_AHEAD_PEND_LIMIT 2 /********************************************************************//** +Unfixes the pages, unlatches the page, +removes it from page_hash and removes it from LRU. */ +static +void +buf_read_page_handle_error( +/*=======================*/ + buf_page_t* bpage) /*!< in: pointer to the block */ +{ + buf_pool_t* buf_pool = buf_pool_from_bpage(bpage); + const ibool uncompressed = (buf_page_get_state(bpage) + == BUF_BLOCK_FILE_PAGE); + + /* First unfix and release lock on the bpage */ + buf_pool_mutex_enter(buf_pool); + mutex_enter(buf_page_get_mutex(bpage)); + ut_ad(buf_page_get_io_fix(bpage) == BUF_IO_READ); + ut_ad(bpage->buf_fix_count == 0); + + /* Set BUF_IO_NONE before we remove the block from LRU list */ + buf_page_set_io_fix(bpage, BUF_IO_NONE); + + if (uncompressed) { + rw_lock_x_unlock_gen( + &((buf_block_t*) bpage)->lock, + BUF_IO_READ); + } + + /* remove the block from LRU list */ + buf_LRU_free_one_page(bpage); + + ut_ad(buf_pool->n_pend_reads > 0); + buf_pool->n_pend_reads--; + + mutex_exit(buf_page_get_mutex(bpage)); + buf_pool_mutex_exit(buf_pool); +} + +/********************************************************************//** Low-level function which reads a page asynchronously from a file to the buffer buf_pool if it is not already there, in which case does nothing. Sets the io_fix flag and sets an exclusive lock on the buffer frame. The @@ -152,12 +190,20 @@ buf_read_page_low( ((buf_block_t*) bpage)->frame, bpage); } thd_wait_end(NULL); + + if (*err == DB_TABLESPACE_DELETED) { + buf_read_page_handle_error(bpage); + return(0); + } + ut_a(*err == DB_SUCCESS); if (sync) { /* The i/o is already completed when we arrive from fil_read */ - buf_page_io_complete(bpage); + if (!buf_page_io_complete(bpage)) { + return(0); + } } return(1); diff --git a/storage/innobase/dict/dict0dict.c b/storage/innobase/dict/dict0dict.c index 5be94a10374..6f2c2caffaf 100644 --- a/storage/innobase/dict/dict0dict.c +++ b/storage/innobase/dict/dict0dict.c @@ -169,6 +169,7 @@ void dict_field_print_low( /*=================*/ const dict_field_t* field); /*!< in: field */ +#ifndef UNIV_HOTBACKUP /*********************************************************************//** Frees a foreign key struct. */ static @@ -182,7 +183,7 @@ and unique key errors */ UNIV_INTERN FILE* dict_foreign_err_file = NULL; /* mutex protecting the foreign and unique error buffers */ UNIV_INTERN mutex_t dict_foreign_err_mutex; - +#endif /* !UNIV_HOTBACKUP */ /******************************************************************//** Makes all characters in a NUL-terminated UTF-8 string lower case. */ UNIV_INTERN @@ -2247,6 +2248,7 @@ dict_index_build_internal_non_clust( return(new_index); } +#ifndef UNIV_HOTBACKUP /*====================== FOREIGN KEY PROCESSING ========================*/ /*********************************************************************//** @@ -2511,6 +2513,7 @@ dict_foreign_find_equiv_index( FALSE/* allow columns to be NULL */)); } +#endif /* !UNIV_HOTBACKUP */ /**********************************************************************//** Returns an index object by matching on the name and column names and if more than one index matches return the index with the max id @@ -2570,6 +2573,7 @@ dict_table_get_index_by_max_id( return(found); } +#ifndef UNIV_HOTBACKUP /**********************************************************************//** Report an error in a foreign key definition. */ static @@ -2735,6 +2739,7 @@ dict_foreign_add_to_cache( return(DB_SUCCESS); } +#endif /* !UNIV_HOTBACKUP */ /*********************************************************************//** Scans from pointer onwards. Stops if is at the start of a copy of 'string' where characters are compared without case sensitivity, and @@ -3214,6 +3219,7 @@ end_of_string: } } +#ifndef UNIV_HOTBACKUP /*********************************************************************//** Finds the highest [number] for foreign key constraints of the table. Looks only at the >= 4.0.18-format id's, which are of the form @@ -4050,7 +4056,7 @@ syntax_error: } /*==================== END OF FOREIGN KEY PROCESSING ====================*/ - +#endif /* !UNIV_HOTBACKUP */ /**********************************************************************//** Returns an index object if it is found in the dictionary cache. Assumes that dict_sys->mutex is already being held. @@ -4411,6 +4417,7 @@ fake_statistics: dict_table_stats_unlock(table, RW_X_LATCH); } +#ifndef UNIV_HOTBACKUP /**********************************************************************//** Prints info of a foreign key constraint. */ static @@ -4441,6 +4448,7 @@ dict_foreign_print_low( fputs(" )\n", stderr); } +#endif /* !UNIV_HOTBACKUP */ /**********************************************************************//** Prints a table data. */ UNIV_INTERN @@ -4622,6 +4630,7 @@ dict_field_print_low( } } +#ifndef UNIV_HOTBACKUP /**********************************************************************//** Outputs info on a foreign key of a table in a format suitable for CREATE TABLE. */ @@ -4810,6 +4819,7 @@ dict_print_info_on_foreign_keys( mutex_exit(&(dict_sys->mutex)); } +#endif /* !UNIV_HOTBACKUP */ /********************************************************************//** Displays the names of the index and the table. */ UNIV_INTERN @@ -4940,6 +4950,28 @@ dict_table_replace_index_in_foreign_list( foreign->foreign_index = new_index; } } + + + for (foreign = UT_LIST_GET_FIRST(table->referenced_list); + foreign; + foreign = UT_LIST_GET_NEXT(referenced_list, foreign)) { + + dict_index_t* new_index; + + if (foreign->referenced_index == index) { + ut_ad(foreign->referenced_table == index->table); + + new_index = dict_foreign_find_index( + foreign->referenced_table, + foreign->referenced_col_names, + foreign->n_fields, index, + /*check_charsets=*/TRUE, /*check_null=*/FALSE); + ut_ad(new_index || !trx->check_foreigns); + ut_ad(!new_index || new_index->table == index->table); + + foreign->referenced_index = new_index; + } + } } /**********************************************************************//** diff --git a/storage/innobase/dict/dict0mem.c b/storage/innobase/dict/dict0mem.c index 982cca5a796..a8ff501a700 100644 --- a/storage/innobase/dict/dict0mem.c +++ b/storage/innobase/dict/dict0mem.c @@ -33,8 +33,8 @@ Created 1/8/1996 Heikki Tuuri #include "data0type.h" #include "mach0data.h" #include "dict0dict.h" -#include "ha_prototypes.h" /* innobase_casedn_str()*/ #ifndef UNIV_HOTBACKUP +# include "ha_prototypes.h" /* innobase_casedn_str()*/ # include "lock0lock.h" #endif /* !UNIV_HOTBACKUP */ #ifdef UNIV_BLOB_DEBUG @@ -272,6 +272,7 @@ dict_mem_index_create( return(index); } +#ifndef UNIV_HOTBACKUP /**********************************************************************//** Creates and initializes a foreign constraint memory object. @return own: foreign constraint struct */ @@ -346,6 +347,7 @@ dict_mem_referenced_table_name_lookup_set( } } +#endif /* !UNIV_HOTBACKUP */ /**********************************************************************//** Adds a field definition to an index. NOTE: does not take a copy of the column name if the field is a column. The memory occupied diff --git a/storage/innobase/fil/fil0fil.c b/storage/innobase/fil/fil0fil.c index 0a467d40345..23fe76f2281 100644 --- a/storage/innobase/fil/fil0fil.c +++ b/storage/innobase/fil/fil0fil.c @@ -857,8 +857,10 @@ fil_node_close_file( ut_a(node->open); ut_a(node->n_pending == 0); ut_a(node->n_pending_flushes == 0); +#ifndef UNIV_HOTBACKUP ut_a(node->modification_counter == node->flush_counter || srv_fast_shutdown == 2); +#endif /* !UNIV_HOTBACKUP */ ret = os_file_close(node->handle); ut_a(ret); diff --git a/storage/innobase/ha/ha0ha.c b/storage/innobase/ha/ha0ha.c index 594a10dc431..35f2293577f 100644 --- a/storage/innobase/ha/ha0ha.c +++ b/storage/innobase/ha/ha0ha.c @@ -28,6 +28,7 @@ Created 8/22/1994 Heikki Tuuri #include "ha0ha.ic" #endif +#ifndef UNIV_HOTBACKUP #ifdef UNIV_DEBUG # include "buf0buf.h" #endif /* UNIV_DEBUG */ @@ -51,17 +52,13 @@ ha_create_func( hash table: must be a power of 2, or 0 */ { hash_table_t* table; -#ifndef UNIV_HOTBACKUP ulint i; -#endif /* !UNIV_HOTBACKUP */ ut_ad(ut_is_2pow(n_mutexes)); table = hash_create(n); #if defined UNIV_AHI_DEBUG || defined UNIV_DEBUG -# ifndef UNIV_HOTBACKUP table->adaptive = TRUE; -# endif /* !UNIV_HOTBACKUP */ #endif /* UNIV_AHI_DEBUG || UNIV_DEBUG */ /* Creating MEM_HEAP_BTR_SEARCH type heaps can potentially fail, but in practise it never should in this case, hence the asserts. */ @@ -74,7 +71,6 @@ ha_create_func( return(table); } -#ifndef UNIV_HOTBACKUP hash_create_mutexes(table, n_mutexes, mutex_level); table->heaps = mem_alloc(n_mutexes * sizeof(void*)); @@ -83,7 +79,6 @@ ha_create_func( table->heaps[i] = mem_heap_create_in_btr_search(4096); ut_a(table->heaps[i]); } -#endif /* !UNIV_HOTBACKUP */ return(table); } @@ -134,7 +129,6 @@ ha_insert_for_fold_func( while (prev_node != NULL) { if (prev_node->fold == fold) { #if defined UNIV_AHI_DEBUG || defined UNIV_DEBUG -# ifndef UNIV_HOTBACKUP if (table->adaptive) { buf_block_t* prev_block = prev_node->block; ut_a(prev_block->frame @@ -143,7 +137,6 @@ ha_insert_for_fold_func( prev_block->n_pointers--; block->n_pointers++; } -# endif /* !UNIV_HOTBACKUP */ prev_node->block = block; #endif /* UNIV_AHI_DEBUG || UNIV_DEBUG */ @@ -171,11 +164,9 @@ ha_insert_for_fold_func( ha_node_set_data(node, block, data); #if defined UNIV_AHI_DEBUG || defined UNIV_DEBUG -# ifndef UNIV_HOTBACKUP if (table->adaptive) { block->n_pointers++; } -# endif /* !UNIV_HOTBACKUP */ #endif /* UNIV_AHI_DEBUG || UNIV_DEBUG */ node->fold = fold; @@ -217,13 +208,11 @@ ha_delete_hash_node( #endif /* UNIV_SYNC_DEBUG */ ut_ad(btr_search_enabled); #if defined UNIV_AHI_DEBUG || defined UNIV_DEBUG -# ifndef UNIV_HOTBACKUP if (table->adaptive) { ut_a(del_node->block->frame = page_align(del_node->data)); ut_a(del_node->block->n_pointers > 0); del_node->block->n_pointers--; } -# endif /* !UNIV_HOTBACKUP */ #endif /* UNIV_AHI_DEBUG || UNIV_DEBUG */ HASH_DELETE_AND_COMPACT(ha_node_t, next, table, del_node); @@ -264,13 +253,11 @@ ha_search_and_update_if_found_func( if (node) { #if defined UNIV_AHI_DEBUG || defined UNIV_DEBUG -# ifndef UNIV_HOTBACKUP if (table->adaptive) { ut_a(node->block->n_pointers > 0); node->block->n_pointers--; new_block->n_pointers++; } -# endif /* !UNIV_HOTBACKUP */ node->block = new_block; #endif /* UNIV_AHI_DEBUG || UNIV_DEBUG */ @@ -278,7 +265,6 @@ ha_search_and_update_if_found_func( } } -#ifndef UNIV_HOTBACKUP /*****************************************************************//** Removes from the chain determined by fold all nodes whose data pointer points to the page given. */ diff --git a/storage/innobase/handler/ha_innodb.cc b/storage/innobase/handler/ha_innodb.cc index 32295c5314f..5300f3f8966 100644 --- a/storage/innobase/handler/ha_innodb.cc +++ b/storage/innobase/handler/ha_innodb.cc @@ -47,6 +47,7 @@ this program; if not, write to the Free Software Foundation, Inc., #include <sql_acl.h> // PROCESS_ACL #include <m_ctype.h> +#include <debug_sync.h> // DEBUG_SYNC #include <mysys_err.h> #include <mysql/plugin.h> #include <innodb_priv.h> @@ -5905,6 +5906,7 @@ ha_innobase::index_read( ulint ret; DBUG_ENTER("index_read"); + DEBUG_SYNC_C("ha_innobase_index_read_begin"); ut_a(prebuilt->trx == thd_to_trx(user_thd)); ut_ad(key_len != 0 || find_flag != HA_READ_KEY_EXACT); @@ -7718,6 +7720,8 @@ ha_innobase::rename_table( error = innobase_rename_table(trx, from, to, TRUE); + DEBUG_SYNC(thd, "after_innobase_rename_table"); + /* Tell the InnoDB server that there might be work for utility threads: */ @@ -8035,10 +8039,15 @@ innobase_get_mysql_key_number_for_index( } } - /* Print an error message if we cannot find the index - ** in the "index translation table". */ - sql_print_error("Cannot find index %s in InnoDB index " - "translation table.", index->name); + /* If index_count in translation table is set to 0, it + is possible we are in the process of rebuilding table, + do not spit error in this case */ + if (share->idx_trans_tbl.index_count) { + /* Print an error message if we cannot find the index + ** in the "index translation table". */ + sql_print_error("Cannot find index %s in InnoDB index " + "translation table.", index->name); + } } /* If we do not have an "index translation table", or not able @@ -11382,7 +11391,7 @@ static MYSQL_SYSVAR_BOOL(doublewrite, innobase_use_doublewrite, static MYSQL_SYSVAR_ULONG(io_capacity, srv_io_capacity, PLUGIN_VAR_RQCMDARG, "Number of IOPs the server can do. Tunes the background IO rate", - NULL, NULL, 200, 100, ~0L, 0); + NULL, NULL, 200, 100, ~0UL, 0); static MYSQL_SYSVAR_ULONG(purge_batch_size, srv_purge_batch_size, PLUGIN_VAR_OPCMDARG, @@ -11499,7 +11508,7 @@ static MYSQL_SYSVAR_BOOL(adaptive_flushing, srv_adaptive_flushing, static MYSQL_SYSVAR_ULONG(max_purge_lag, srv_max_purge_lag, PLUGIN_VAR_RQCMDARG, "Desired maximum length of the purge queue (0 = no limit)", - NULL, NULL, 0, 0, ~0L, 0); + NULL, NULL, 0, 0, ~0UL, 0); static MYSQL_SYSVAR_BOOL(rollback_on_timeout, innobase_rollback_on_timeout, PLUGIN_VAR_OPCMDARG | PLUGIN_VAR_READONLY, @@ -11561,7 +11570,7 @@ static MYSQL_SYSVAR_ULONG(commit_concurrency, innobase_commit_concurrency, static MYSQL_SYSVAR_ULONG(concurrency_tickets, srv_n_free_tickets_to_enter, PLUGIN_VAR_RQCMDARG, "Number of times a thread is allowed to enter InnoDB within the same SQL query after it has once got the ticket", - NULL, NULL, 500L, 1L, ~0L, 0); + NULL, NULL, 500L, 1L, ~0UL, 0); static MYSQL_SYSVAR_LONG(file_io_threads, innobase_file_io_threads, PLUGIN_VAR_RQCMDARG | PLUGIN_VAR_READONLY | PLUGIN_VAR_NOSYSVAR, @@ -11623,12 +11632,12 @@ static MYSQL_SYSVAR_LONG(open_files, innobase_open_files, static MYSQL_SYSVAR_ULONG(sync_spin_loops, srv_n_spin_wait_rounds, PLUGIN_VAR_RQCMDARG, "Count of spin-loop rounds in InnoDB mutexes (30 by default)", - NULL, NULL, 30L, 0L, ~0L, 0); + NULL, NULL, 30L, 0L, ~0UL, 0); static MYSQL_SYSVAR_ULONG(spin_wait_delay, srv_spin_wait_delay, PLUGIN_VAR_OPCMDARG, "Maximum delay between polling for a spin lock (6 by default)", - NULL, NULL, 6L, 0L, ~0L, 0); + NULL, NULL, 6L, 0L, ~0UL, 0); static MYSQL_SYSVAR_ULONG(thread_concurrency, srv_thread_concurrency, PLUGIN_VAR_RQCMDARG, @@ -11638,7 +11647,7 @@ static MYSQL_SYSVAR_ULONG(thread_concurrency, srv_thread_concurrency, static MYSQL_SYSVAR_ULONG(thread_sleep_delay, srv_thread_sleep_delay, PLUGIN_VAR_RQCMDARG, "Time of innodb thread sleeping before joining InnoDB queue (usec). Value 0 disable a sleep", - NULL, NULL, 10000L, 0L, ~0L, 0); + NULL, NULL, 10000L, 0L, ~0UL, 0); static MYSQL_SYSVAR_STR(data_file_path, innobase_data_file_path, PLUGIN_VAR_RQCMDARG | PLUGIN_VAR_READONLY, diff --git a/storage/innobase/handler/handler0alter.cc b/storage/innobase/handler/handler0alter.cc index 7bb370a8dc4..dc65fb3ff1a 100644 --- a/storage/innobase/handler/handler0alter.cc +++ b/storage/innobase/handler/handler0alter.cc @@ -708,6 +708,10 @@ ha_innobase::add_index( ut_a(indexed_table == prebuilt->table); + if (indexed_table->tablespace_discarded) { + DBUG_RETURN(-1); + } + /* Check that index keys are sensible */ error = innobase_check_index_keys(key_info, num_of_keys, prebuilt->table); @@ -769,7 +773,7 @@ ha_innobase::add_index( row_mysql_lock_data_dictionary(trx); dict_locked = TRUE; - ut_d(dict_table_check_for_dup_indexes(prebuilt->table, FALSE)); + ut_d(dict_table_check_for_dup_indexes(prebuilt->table, TRUE)); /* If a new primary key is defined for the table we need to drop the original table and rebuild all indexes. */ @@ -805,7 +809,7 @@ ha_innobase::add_index( } ut_d(dict_table_check_for_dup_indexes(prebuilt->table, - FALSE)); + TRUE)); mem_heap_free(heap); trx_general_rollback_for_mysql(trx, NULL); row_mysql_unlock_data_dictionary(trx); @@ -1057,7 +1061,7 @@ ha_innobase::final_add_index( trx_commit_for_mysql(prebuilt->trx); } - ut_d(dict_table_check_for_dup_indexes(prebuilt->table, FALSE)); + ut_d(dict_table_check_for_dup_indexes(prebuilt->table, TRUE)); row_mysql_unlock_data_dictionary(trx); trx_free_for_mysql(trx); @@ -1100,7 +1104,7 @@ ha_innobase::prepare_drop_index( /* Test and mark all the indexes to be dropped */ row_mysql_lock_data_dictionary(trx); - ut_d(dict_table_check_for_dup_indexes(prebuilt->table, FALSE)); + ut_d(dict_table_check_for_dup_indexes(prebuilt->table, TRUE)); /* Check that none of the indexes have previously been flagged for deletion. */ @@ -1271,7 +1275,7 @@ func_exit: } while (index); } - ut_d(dict_table_check_for_dup_indexes(prebuilt->table, FALSE)); + ut_d(dict_table_check_for_dup_indexes(prebuilt->table, TRUE)); row_mysql_unlock_data_dictionary(trx); DBUG_RETURN(err); @@ -1318,7 +1322,7 @@ ha_innobase::final_drop_index( prebuilt->table->flags, user_thd); row_mysql_lock_data_dictionary(trx); - ut_d(dict_table_check_for_dup_indexes(prebuilt->table, FALSE)); + ut_d(dict_table_check_for_dup_indexes(prebuilt->table, TRUE)); if (UNIV_UNLIKELY(err)) { @@ -1362,7 +1366,7 @@ ha_innobase::final_drop_index( share->idx_trans_tbl.index_count = 0; func_exit: - ut_d(dict_table_check_for_dup_indexes(prebuilt->table, FALSE)); + ut_d(dict_table_check_for_dup_indexes(prebuilt->table, TRUE)); trx_commit_for_mysql(trx); trx_commit_for_mysql(prebuilt->trx); row_mysql_unlock_data_dictionary(trx); diff --git a/storage/innobase/include/btr0btr.h b/storage/innobase/include/btr0btr.h index f531b785786..5592995d4b2 100644 --- a/storage/innobase/include/btr0btr.h +++ b/storage/innobase/include/btr0btr.h @@ -92,6 +92,8 @@ insert/delete buffer when the record is not in the buffer pool. */ buffer when the record is not in the buffer pool. */ #define BTR_DELETE 8192 +#endif /* UNIV_HOTBACKUP */ + /**************************************************************//** Report that an index page is corrupted. */ UNIV_INTERN @@ -112,6 +114,7 @@ btr_corruption_report( ut_error; \ } +#ifndef UNIV_HOTBACKUP #ifdef UNIV_BLOB_DEBUG # include "ut0rbt.h" /** An index->blobs entry for keeping track of off-page column references */ diff --git a/storage/innobase/include/btr0types.h b/storage/innobase/include/btr0types.h index 5adc858b931..ef329af1aac 100644 --- a/storage/innobase/include/btr0types.h +++ b/storage/innobase/include/btr0types.h @@ -39,6 +39,8 @@ typedef struct btr_cur_struct btr_cur_t; /** B-tree search information for the adaptive hash index */ typedef struct btr_search_struct btr_search_t; +#ifndef UNIV_HOTBACKUP + /** @brief The latch protecting the adaptive search system This latch protects the @@ -54,6 +56,8 @@ Bear in mind (3) and (4) when using the hash index. */ extern rw_lock_t* btr_search_latch_temp; +#endif /* UNIV_HOTBACKUP */ + /** The latch protecting the adaptive search system */ #define btr_search_latch (*btr_search_latch_temp) diff --git a/storage/innobase/include/buf0buf.h b/storage/innobase/include/buf0buf.h index d9e6801eb86..a39592943d8 100644 --- a/storage/innobase/include/buf0buf.h +++ b/storage/innobase/include/buf0buf.h @@ -593,34 +593,34 @@ ib_uint64_t buf_block_get_modify_clock( /*=======================*/ buf_block_t* block); /*!< in: block */ -#else /* !UNIV_HOTBACKUP */ -# define buf_block_modify_clock_inc(block) ((void) 0) -#endif /* !UNIV_HOTBACKUP */ /*******************************************************************//** Increments the bufferfix count. */ UNIV_INLINE void buf_block_buf_fix_inc_func( /*=======================*/ -#ifdef UNIV_SYNC_DEBUG +# ifdef UNIV_SYNC_DEBUG const char* file, /*!< in: file name */ ulint line, /*!< in: line */ -#endif /* UNIV_SYNC_DEBUG */ +# endif /* UNIV_SYNC_DEBUG */ buf_block_t* block) /*!< in/out: block to bufferfix */ __attribute__((nonnull)); -#ifdef UNIV_SYNC_DEBUG +# ifdef UNIV_SYNC_DEBUG /** Increments the bufferfix count. @param b in/out: block to bufferfix @param f in: file name where requested @param l in: line number where requested */ # define buf_block_buf_fix_inc(b,f,l) buf_block_buf_fix_inc_func(f,l,b) -#else /* UNIV_SYNC_DEBUG */ +# else /* UNIV_SYNC_DEBUG */ /** Increments the bufferfix count. @param b in/out: block to bufferfix @param f in: file name where requested @param l in: line number where requested */ # define buf_block_buf_fix_inc(b,f,l) buf_block_buf_fix_inc_func(b) -#endif /* UNIV_SYNC_DEBUG */ +# endif /* UNIV_SYNC_DEBUG */ +#else /* !UNIV_HOTBACKUP */ +# define buf_block_modify_clock_inc(block) ((void) 0) +#endif /* !UNIV_HOTBACKUP */ /********************************************************************//** Calculates a page checksum which is stored to the page when it is written to a file. Note that we must be careful to calculate the same value @@ -1162,9 +1162,10 @@ buf_page_init_for_read( ulint offset);/*!< in: page number */ /********************************************************************//** Completes an asynchronous read or write request of a file page to or from -the buffer pool. */ +the buffer pool. +@return TRUE if successful */ UNIV_INTERN -void +ibool buf_page_io_complete( /*=================*/ buf_page_t* bpage); /*!< in: pointer to the block in question */ diff --git a/storage/innobase/include/buf0buf.ic b/storage/innobase/include/buf0buf.ic index 917ee5dda84..0d9687e6b2a 100644 --- a/storage/innobase/include/buf0buf.ic +++ b/storage/innobase/include/buf0buf.ic @@ -31,6 +31,7 @@ Created 11/5/1995 Heikki Tuuri *******************************************************/ #include "mtr0mtr.h" +#ifndef UNIV_HOTBACKUP #include "buf0flu.h" #include "buf0lru.h" #include "buf0rea.h" @@ -180,6 +181,7 @@ buf_page_peek_if_too_old( return(!buf_page_peek_if_young(bpage)); } } +#endif /* !UNIV_HOTBACKUP */ /*********************************************************************//** Gets the state of a block. diff --git a/storage/innobase/include/dict0dict.h b/storage/innobase/include/dict0dict.h index 89d6fc66635..b609bce9d41 100644 --- a/storage/innobase/include/dict0dict.h +++ b/storage/innobase/include/dict0dict.h @@ -750,6 +750,7 @@ ulint dict_table_zip_size( /*================*/ const dict_table_t* table); /*!< in: table */ +#ifndef UNIV_HOTBACKUP /*********************************************************************//** Obtain exclusive locks on all index trees of the table. This is to prevent accessing index trees while InnoDB is updating internal metadata for @@ -766,6 +767,7 @@ void dict_table_x_unlock_indexes( /*========================*/ dict_table_t* table); /*!< in: table */ +#endif /* !UNIV_HOTBACKUP */ /********************************************************************//** Checks if a column is in the ordering columns of the clustered index of a table. Column prefixes are treated like whole columns. @@ -1251,7 +1253,7 @@ UNIV_INTERN void dict_close(void); /*============*/ - +#ifndef UNIV_HOTBACKUP /**********************************************************************//** Check whether the table is corrupted. @return nonzero for corrupted table, zero for valid tables */ @@ -1272,6 +1274,7 @@ dict_index_is_corrupted( const dict_index_t* index) /*!< in: index */ __attribute__((nonnull, pure, warn_unused_result)); +#endif /* !UNIV_HOTBACKUP */ /**********************************************************************//** Flags an index and table corrupted both in the data dictionary cache and in the system table SYS_INDEXES. */ diff --git a/storage/innobase/include/dict0dict.ic b/storage/innobase/include/dict0dict.ic index 7533ce01401..faa28959c59 100644 --- a/storage/innobase/include/dict0dict.ic +++ b/storage/innobase/include/dict0dict.ic @@ -491,6 +491,7 @@ dict_table_zip_size( return(dict_table_flags_to_zip_size(table->flags)); } +#ifndef UNIV_HOTBACKUP /*********************************************************************//** Obtain exclusive locks on all index trees of the table. This is to prevent accessing index trees while InnoDB is updating internal metadata for @@ -533,6 +534,7 @@ dict_table_x_unlock_indexes( rw_lock_x_unlock(dict_index_get_lock(index)); } } +#endif /* !UNIV_HOTBACKUP */ /********************************************************************//** Gets the number of fields in the internal representation of an index, including fields added by the dictionary system. diff --git a/storage/innobase/include/log0log.h b/storage/innobase/include/log0log.h index f2ab6a9898d..30250d4fd27 100644 --- a/storage/innobase/include/log0log.h +++ b/storage/innobase/include/log0log.h @@ -762,7 +762,6 @@ struct log_struct{ buffer */ #ifndef UNIV_HOTBACKUP mutex_t mutex; /*!< mutex protecting the log */ -#endif /* !UNIV_HOTBACKUP */ mutex_t log_flush_order_mutex;/*!< mutex to serialize access to the flush list when we are putting @@ -772,6 +771,7 @@ struct log_struct{ mtr_commit and still ensure that insertions in the flush_list happen in the LSN order. */ +#endif /* !UNIV_HOTBACKUP */ byte* buf_ptr; /* unaligned log buffer */ byte* buf; /*!< log buffer */ ulint buf_size; /*!< log buffer size in bytes */ diff --git a/storage/innobase/include/os0file.h b/storage/innobase/include/os0file.h index fb13120a481..8ef0906ff5f 100644 --- a/storage/innobase/include/os0file.h +++ b/storage/innobase/include/os0file.h @@ -309,7 +309,7 @@ to original un-instrumented file I/O APIs */ os_file_create_func(name, create, purpose, type, success) # define os_file_create_simple(key, name, create, access, success) \ - os_file_create_simple_func(name, create_mode, access, success) + os_file_create_simple_func(name, create, access, success) # define os_file_create_simple_no_error_handling( \ key, name, create_mode, access, success) \ diff --git a/storage/innobase/include/srv0srv.h b/storage/innobase/include/srv0srv.h index ed2f4672a99..5290ef5fe11 100644 --- a/storage/innobase/include/srv0srv.h +++ b/storage/innobase/include/srv0srv.h @@ -111,13 +111,13 @@ extern ulint srv_max_file_format_at_startup; /** Place locks to records only i.e. do not use next-key locking except on duplicate key checking and foreign key checking */ extern ibool srv_locks_unsafe_for_binlog; -#endif /* !UNIV_HOTBACKUP */ /* If this flag is TRUE, then we will use the native aio of the OS (provided we compiled Innobase with it in), otherwise we will use simulated aio we build below with threads. Currently we support native aio on windows and linux */ extern my_bool srv_use_native_aio; +#endif /* !UNIV_HOTBACKUP */ #ifdef __WIN__ extern ibool srv_use_native_conditions; #endif diff --git a/storage/innobase/include/trx0sys.h b/storage/innobase/include/trx0sys.h index 3913792d594..635e7ec30b6 100644 --- a/storage/innobase/include/trx0sys.h +++ b/storage/innobase/include/trx0sys.h @@ -222,7 +222,6 @@ UNIV_INLINE trx_id_t trx_sys_get_new_trx_id(void); /*========================*/ -#endif /* !UNIV_HOTBACKUP */ #ifdef UNIV_DEBUG /* Flag to control TRX_RSEG_N_SLOTS behavior debugging. */ @@ -239,7 +238,6 @@ trx_write_trx_id( /*=============*/ byte* ptr, /*!< in: pointer to memory where written */ trx_id_t id); /*!< in: id */ -#ifndef UNIV_HOTBACKUP /*****************************************************************//** Reads a trx id from an index page. In case that the id size changes in some future version, this function should be used instead of @@ -572,7 +570,6 @@ FIL_PAGE_ARCH_LOG_NO_OR_SPACE_NO. */ #define TRX_SYS_DOUBLEWRITE_BLOCK_SIZE FSP_EXTENT_SIZE /* @} */ -#ifndef UNIV_HOTBACKUP /** File format tag */ /* @{ */ /** The offset of the file format tag on the trx system header page @@ -591,6 +588,7 @@ identifier is added to this 64-bit constant. */ | TRX_SYS_FILE_FORMAT_TAG_MAGIC_N_LOW) /* @} */ +#ifndef UNIV_HOTBACKUP /** Doublewrite control struct */ struct trx_doublewrite_struct{ mutex_t mutex; /*!< mutex protecting the first_free field and diff --git a/storage/innobase/mem/mem0dbg.c b/storage/innobase/mem/mem0dbg.c index ae43d6097a6..0909b7c9a64 100644 --- a/storage/innobase/mem/mem0dbg.c +++ b/storage/innobase/mem/mem0dbg.c @@ -24,7 +24,9 @@ but is included in mem0mem.* ! Created 6/9/1994 Heikki Tuuri *************************************************************************/ -#include "ha_prototypes.h" +#ifndef UNIV_HOTBACKUP +# include "ha_prototypes.h" +#endif /* !UNIV_HOTBACKUP */ #ifdef UNIV_MEM_DEBUG # ifndef UNIV_HOTBACKUP diff --git a/storage/innobase/os/os0file.c b/storage/innobase/os/os0file.c index 15e66167f26..1068c033871 100644 --- a/storage/innobase/os/os0file.c +++ b/storage/innobase/os/os0file.c @@ -303,6 +303,7 @@ UNIV_INTERN ulint os_n_pending_writes = 0; UNIV_INTERN ulint os_n_pending_reads = 0; #ifdef UNIV_DEBUG +# ifndef UNIV_HOTBACKUP /**********************************************************************//** Validates the consistency the aio system some of the time. @return TRUE if ok or the check was skipped */ @@ -329,6 +330,7 @@ os_aio_validate_skip(void) os_aio_validate_count = OS_AIO_VALIDATE_SKIP; return(os_aio_validate()); } +# endif /* !UNIV_HOTBACKUP */ #endif /* UNIV_DEBUG */ #ifdef __WIN__ diff --git a/storage/innobase/page/page0zip.c b/storage/innobase/page/page0zip.c index fb618beac7e..ca3836689d3 100644 --- a/storage/innobase/page/page0zip.c +++ b/storage/innobase/page/page0zip.c @@ -4433,7 +4433,9 @@ page_zip_reorganize( dict_index_t* index, /*!< in: index of the B-tree node */ mtr_t* mtr) /*!< in: mini-transaction */ { +#ifndef UNIV_HOTBACKUP buf_pool_t* buf_pool = buf_pool_from_block(block); +#endif /* !UNIV_HOTBACKUP */ page_zip_des_t* page_zip = buf_block_get_page_zip(block); page_t* page = buf_block_get_frame(block); buf_block_t* temp_block; diff --git a/storage/innobase/row/row0ins.c b/storage/innobase/row/row0ins.c index 2b77c6f929d..60a66ea3945 100644 --- a/storage/innobase/row/row0ins.c +++ b/storage/innobase/row/row0ins.c @@ -1281,7 +1281,8 @@ run_again: check_index = foreign->foreign_index; } - if (check_table == NULL || check_table->ibd_file_missing) { + if (check_table == NULL || check_table->ibd_file_missing + || check_index == NULL) { if (check_ref) { FILE* ef = dict_foreign_err_file; @@ -1316,9 +1317,6 @@ run_again: goto exit_func; } - ut_a(check_table); - ut_a(check_index); - if (check_table != table) { /* We already have a LOCK_IX on table, but not necessarily on check_table */ diff --git a/storage/innobase/row/row0vers.c b/storage/innobase/row/row0vers.c index 5fd7d082194..6d83dbaf8ee 100644 --- a/storage/innobase/row/row0vers.c +++ b/storage/innobase/row/row0vers.c @@ -209,17 +209,6 @@ row_vers_impl_x_locked_off_kernel( prev_trx_id = row_get_rec_trx_id(prev_version, clust_index, clust_offsets); - /* If the trx_id and prev_trx_id are different and if - the prev_version is marked deleted then the - prev_trx_id must have already committed for the trx_id - to be able to modify the row. Therefore, prev_trx_id - cannot hold any implicit lock. */ - if (vers_del && trx_id != prev_trx_id) { - - mutex_enter(&kernel_mutex); - break; - } - /* The stack of versions is locked by mtr. Thus, it is safe to fetch the prefixes for externally stored columns. */ diff --git a/storage/innobase/trx/trx0sys.c b/storage/innobase/trx/trx0sys.c index 90091c00228..0c5e367ac30 100644 --- a/storage/innobase/trx/trx0sys.c +++ b/storage/innobase/trx/trx0sys.c @@ -134,12 +134,12 @@ UNIV_INTERN mysql_pfs_key_t trx_doublewrite_mutex_key; UNIV_INTERN mysql_pfs_key_t file_format_max_mutex_key; #endif /* UNIV_PFS_MUTEX */ +#ifndef UNIV_HOTBACKUP #ifdef UNIV_DEBUG /* Flag to control TRX_RSEG_N_SLOTS behavior debugging. */ uint trx_rseg_n_slots_debug = 0; #endif -#ifndef UNIV_HOTBACKUP /** This is used to track the maximum file format id known to InnoDB. It's updated via SET GLOBAL innodb_file_format_max = 'x' or when we open or create a table. */ diff --git a/storage/innobase/ut/ut0dbg.c b/storage/innobase/ut/ut0dbg.c index 64fadd76d1c..53ed4a53044 100644 --- a/storage/innobase/ut/ut0dbg.c +++ b/storage/innobase/ut/ut0dbg.c @@ -25,7 +25,9 @@ Created 1/30/1994 Heikki Tuuri #include "univ.i" #include "ut0dbg.h" -#include "ha_prototypes.h" +#ifndef UNIV_HOTBACKUP +# include "ha_prototypes.h" +#endif /* !UNIV_HOTBACKUP */ #if defined(__GNUC__) && (__GNUC__ > 2) #else @@ -56,7 +58,7 @@ ut_dbg_assertion_failed( ut_print_timestamp(stderr); #ifdef UNIV_HOTBACKUP fprintf(stderr, " InnoDB: Assertion failure in file %s line %lu\n", - innobase_basename(file), line); + file, line); #else /* UNIV_HOTBACKUP */ fprintf(stderr, " InnoDB: Assertion failure in thread %lu" diff --git a/storage/innobase/ut/ut0ut.c b/storage/innobase/ut/ut0ut.c index 117a777cb98..2fe45aad2a7 100644 --- a/storage/innobase/ut/ut0ut.c +++ b/storage/innobase/ut/ut0ut.c @@ -245,7 +245,9 @@ ut_print_timestamp( (int)cal_tm.wMinute, (int)cal_tm.wSecond); #else +#ifdef HAVE_LOCALTIME_R struct tm cal_tm; +#endif struct tm* cal_tm_ptr; time_t tm; @@ -288,7 +290,9 @@ ut_sprintf_timestamp( (int)cal_tm.wMinute, (int)cal_tm.wSecond); #else +#ifdef HAVE_LOCALTIME_R struct tm cal_tm; +#endif struct tm* cal_tm_ptr; time_t tm; @@ -333,7 +337,9 @@ ut_sprintf_timestamp_without_extra_chars( (int)cal_tm.wMinute, (int)cal_tm.wSecond); #else +#ifdef HAVE_LOCALTIME_R struct tm cal_tm; +#endif struct tm* cal_tm_ptr; time_t tm; @@ -374,7 +380,9 @@ ut_get_year_month_day( *month = (ulint)cal_tm.wMonth; *day = (ulint)cal_tm.wDay; #else +#ifdef HAVE_LOCALTIME_R struct tm cal_tm; +#endif struct tm* cal_tm_ptr; time_t tm; diff --git a/storage/myisam/ft_boolean_search.c b/storage/myisam/ft_boolean_search.c index f419ac3d689..8b61e1dc4f2 100644 --- a/storage/myisam/ft_boolean_search.c +++ b/storage/myisam/ft_boolean_search.c @@ -352,7 +352,7 @@ static int _ftb_no_dupes_cmp(void* not_used __attribute__((unused)), returns 1 if the search was finished (must-word wasn't found) */ -static int _ft2_search(FTB *ftb, FTB_WORD *ftbw, my_bool init_search) +static int _ft2_search_no_lock(FTB *ftb, FTB_WORD *ftbw, my_bool init_search) { int r; int subkeys=1; @@ -452,7 +452,7 @@ static int _ft2_search(FTB *ftb, FTB_WORD *ftbw, my_bool init_search) ftbw->key_root=info->s->state.key_root[ftb->keynr]; ftbw->keyinfo=info->s->keyinfo+ftb->keynr; ftbw->off=0; - return _ft2_search(ftb, ftbw, 0); + return _ft2_search_no_lock(ftb, ftbw, 0); } /* matching key found */ @@ -480,6 +480,18 @@ static int _ft2_search(FTB *ftb, FTB_WORD *ftbw, my_bool init_search) return 0; } +static int _ft2_search(FTB *ftb, FTB_WORD *ftbw, my_bool init_search) +{ + int r; + MYISAM_SHARE *share= ftb->info->s; + if (share->concurrent_insert) + mysql_rwlock_rdlock(&share->key_root_lock[ftb->keynr]); + r= _ft2_search_no_lock(ftb, ftbw, init_search); + if (share->concurrent_insert) + mysql_rwlock_unlock(&share->key_root_lock[ftb->keynr]); + return r; +} + static void _ftb_init_index_search(FT_INFO *ftb) { int i; diff --git a/storage/myisam/ft_nlq_search.c b/storage/myisam/ft_nlq_search.c index e31075e55d1..5a9468fe007 100644 --- a/storage/myisam/ft_nlq_search.c +++ b/storage/myisam/ft_nlq_search.c @@ -70,9 +70,10 @@ static int walk_and_match(FT_WORD *word, uint32 count, ALL_IN_ONE *aio) TREE_ELEMENT *selem; double gweight=1; MI_INFO *info=aio->info; + MYISAM_SHARE *share= info->s; uchar *keybuff=aio->keybuff; MI_KEYDEF *keyinfo=info->s->keyinfo+aio->keynr; - my_off_t key_root=info->s->state.key_root[aio->keynr]; + my_off_t key_root; uint extra= HA_FT_WLEN + info->s->rec_reflength; #if HA_FT_WTYPE == HA_KEYTYPE_FLOAT float tmp_weight; @@ -87,6 +88,11 @@ static int walk_and_match(FT_WORD *word, uint32 count, ALL_IN_ONE *aio) keylen-=HA_FT_WLEN; doc_cnt=0; + if (share->concurrent_insert) + mysql_rwlock_rdlock(&share->key_root_lock[aio->keynr]); + + key_root= share->state.key_root[aio->keynr]; + /* Skip rows inserted by current inserted */ for (r=_mi_search(info, keyinfo, keybuff, keylen, SEARCH_FIND, key_root) ; !r && @@ -96,6 +102,9 @@ static int walk_and_match(FT_WORD *word, uint32 count, ALL_IN_ONE *aio) info->lastkey_length, SEARCH_BIGGER, key_root)) ; + if (share->concurrent_insert) + mysql_rwlock_unlock(&share->key_root_lock[aio->keynr]); + info->update|= HA_STATE_AKTIV; /* for _mi_test_if_changed() */ /* The following should be safe, even if we compare doubles */ @@ -119,6 +128,8 @@ static int walk_and_match(FT_WORD *word, uint32 count, ALL_IN_ONE *aio) keyinfo=& info->s->ft2_keyinfo; key_root=info->lastpos; keylen=0; + if (share->concurrent_insert) + mysql_rwlock_rdlock(&share->key_root_lock[aio->keynr]); r=_mi_search_first(info, keyinfo, key_root); goto do_skip; } @@ -154,6 +165,9 @@ static int walk_and_match(FT_WORD *word, uint32 count, ALL_IN_ONE *aio) if (gweight < 0 || doc_cnt > 2000000) gweight=0; + if (share->concurrent_insert) + mysql_rwlock_rdlock(&share->key_root_lock[aio->keynr]); + if (_mi_test_if_changed(info) == 0) r=_mi_search_next(info, keyinfo, info->lastkey, info->lastkey_length, SEARCH_BIGGER, key_root); @@ -166,6 +180,8 @@ do_skip: r= _mi_search_next(info, keyinfo, info->lastkey, info->lastkey_length, SEARCH_BIGGER, key_root); + if (share->concurrent_insert) + mysql_rwlock_unlock(&share->key_root_lock[aio->keynr]); } word->weight=gweight; diff --git a/support-files/mysql.spec.sh b/support-files/mysql.spec.sh index a3d8554188e..5b9a296d90a 100644 --- a/support-files/mysql.spec.sh +++ b/support-files/mysql.spec.sh @@ -176,7 +176,7 @@ %endif %else %if %(test -f /etc/SuSE-release && echo 1 || echo 0) - %define susever %(rpm -qf --qf '%%{version}\\n' /etc/SuSE-release) + %define susever %(rpm -qf --qf '%%{version}\\n' /etc/SuSE-release | cut -d. -f1) %if "%susever" == "10" %define distro_description SUSE Linux Enterprise Server 10 %define distro_releasetag sles10 diff --git a/tests/mysql_client_fw.c b/tests/mysql_client_fw.c new file mode 100644 index 00000000000..979d47cb0b8 --- /dev/null +++ b/tests/mysql_client_fw.c @@ -0,0 +1,1440 @@ +/* Copyright (c) 2002, 2012, 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 General Public License as published by + the Free Software Foundation; version 2 of the License. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ + +#include <my_global.h> +#include <my_sys.h> +#include <mysql.h> +#include <errmsg.h> +#include <my_compare.h> +#include <my_getopt.h> +#include <m_string.h> +#include <mysqld_error.h> +#include <sql_common.h> +#include <mysql/client_plugin.h> + +/* + If non_blocking_api_enabled is true, we will re-define all the blocking + API functions as wrappers that call the corresponding non-blocking API + and use poll()/select() to wait for them to complete. This way we can get + a good coverage testing of the non-blocking API as well. +*/ +static my_bool non_blocking_api_enabled= 0; +#if !defined(EMBEDDED_LIBRARY) +#define WRAP_NONBLOCK_ENABLED non_blocking_api_enabled +#include "nonblock-wrappers.h" +#endif + +#define VER "2.1" +#define MAX_TEST_QUERY_LENGTH 300 /* MAX QUERY BUFFER LENGTH */ +#define MAX_KEY MAX_INDEXES +#define MAX_SERVER_ARGS 64 + +/* set default options */ +static int opt_testcase __attribute__((unused)) = 0; +static char *opt_db= 0; +static char *opt_user= 0; +static char *opt_password= 0; +static char *opt_host= 0; +static char *opt_unix_socket= 0; +#ifdef HAVE_SMEM +static char *shared_memory_base_name= 0; +#endif +static unsigned int opt_port; +static my_bool tty_password= 0, opt_silent= 0; + +static MYSQL *mysql= 0; +static char current_db[]= "client_test_db"; +static unsigned int test_count= 0; +static unsigned int opt_count= 0; +static unsigned int iter_count= 0; +static my_bool have_innodb= FALSE; +static char *opt_plugin_dir= 0, *opt_default_auth= 0; + +static const char *opt_basedir= "./"; +static const char *opt_vardir= "mysql-test/var"; + +static longlong opt_getopt_ll_test= 0; + +static int embedded_server_arg_count= 0; +static char *embedded_server_args[MAX_SERVER_ARGS]; + +static const char *embedded_server_groups[]= { + "server", + "embedded", + "mysql_client_test_SERVER", + NullS +}; + +static time_t start_time, end_time; +static double total_time; + +const char *default_dbug_option= "d:t:o,/tmp/mysql_client_test.trace"; + +struct my_tests_st +{ + const char *name; + void (*function)(); +}; + +#define myheader(str) \ +DBUG_PRINT("test", ("name: %s", str)); \ + if (opt_silent < 2) \ + { \ + fprintf(stdout, "\n\n#####################################\n"); \ + fprintf(stdout, "%u of (%u/%u): %s", test_count++, iter_count, \ + opt_count, str); \ + fprintf(stdout, " \n#####################################\n"); \ + } + +#define myheader_r(str) \ +DBUG_PRINT("test", ("name: %s", str)); \ + if (!opt_silent) \ + { \ + fprintf(stdout, "\n\n#####################################\n"); \ + fprintf(stdout, "%s", str); \ + fprintf(stdout, " \n#####################################\n"); \ + } + +static void print_error(const char *msg); +static void print_st_error(MYSQL_STMT *stmt, const char *msg); +static void client_disconnect(MYSQL* mysql, my_bool drop_db); + + +/* + Abort unless given experssion is non-zero. + + SYNOPSIS + DIE_UNLESS(expr) + + DESCRIPTION + We can't use any kind of system assert as we need to + preserve tested invariants in release builds as well. +*/ + +#define DIE_UNLESS(expr) \ + ((void) ((expr) ? 0 : (die(__FILE__, __LINE__, #expr), 0))) +#define DIE_IF(expr) \ + ((void) ((expr) ? (die(__FILE__, __LINE__, #expr), 0) : 0)) +#define DIE(expr) \ + die(__FILE__, __LINE__, #expr) + +static void die(const char *file, int line, const char *expr) +{ + fflush(stdout); + fprintf(stderr, "%s:%d: check failed: '%s'\n", file, line, expr); + fflush(stderr); + exit(1); +} + + +#define myerror(msg) print_error(msg) +#define mysterror(stmt, msg) print_st_error(stmt, msg) + +#define myquery(RES) \ +{ \ + int r= (RES); \ + if (r) \ + myerror(NULL); \ + DIE_UNLESS(r == 0); \ +} + +#define myquery_r(r) \ +{ \ + if (r) \ + myerror(NULL); \ + DIE_UNLESS(r != 0); \ +} + +#define check_execute(stmt, r) \ +{ \ + if (r) \ + mysterror(stmt, NULL); \ + DIE_UNLESS(r == 0); \ +} + +#define check_execute_r(stmt, r) \ +{ \ + if (r) \ + mysterror(stmt, NULL); \ + DIE_UNLESS(r != 0); \ +} + +#define check_stmt(stmt) \ +{ \ + if ( stmt == 0) \ + myerror(NULL); \ + DIE_UNLESS(stmt != 0); \ +} + +#define check_stmt_r(stmt) \ +{ \ + if (stmt == 0) \ + myerror(NULL); \ + DIE_UNLESS(stmt == 0); \ +} + +#define mytest(x) if (!(x)) {myerror(NULL);DIE_UNLESS(FALSE);} +#define mytest_r(x) if ((x)) {myerror(NULL);DIE_UNLESS(FALSE);} + + +/* A workaround for Sun Forte 5.6 on Solaris x86 */ + +static int cmp_double(double *a, double *b) +{ + return *a == *b; +} + + +/* Print the error message */ + +static void print_error(const char *msg) +{ + if (!opt_silent) + { + if (mysql && mysql_errno(mysql)) + { + if (mysql->server_version) + fprintf(stdout, "\n [MySQL-%s]", mysql->server_version); + else + fprintf(stdout, "\n [MySQL]"); + fprintf(stdout, "[%d] %s\n", mysql_errno(mysql), mysql_error(mysql)); + } + else if (msg) + fprintf(stderr, " [MySQL] %s\n", msg); + } +} + + +static void print_st_error(MYSQL_STMT *stmt, const char *msg) +{ + if (!opt_silent) + { + if (stmt && mysql_stmt_errno(stmt)) + { + if (stmt->mysql && stmt->mysql->server_version) + fprintf(stdout, "\n [MySQL-%s]", stmt->mysql->server_version); + else + fprintf(stdout, "\n [MySQL]"); + + fprintf(stdout, "[%d] %s\n", mysql_stmt_errno(stmt), + mysql_stmt_error(stmt)); + } + else if (msg) + fprintf(stderr, " [MySQL] %s\n", msg); + } +} + +/* + Enhanced version of mysql_client_init(), which may also set shared memory + base on Windows. +*/ +static MYSQL *mysql_client_init(MYSQL* con) +{ + MYSQL* res = mysql_init(con); +#ifdef HAVE_SMEM + if (res && shared_memory_base_name) + mysql_options(res, MYSQL_SHARED_MEMORY_BASE_NAME, shared_memory_base_name); +#endif + if (res && non_blocking_api_enabled) + mysql_options(res, MYSQL_OPT_NONBLOCK, 0); + if (opt_plugin_dir && *opt_plugin_dir) + mysql_options(res, MYSQL_PLUGIN_DIR, opt_plugin_dir); + + if (opt_default_auth && *opt_default_auth) + mysql_options(res, MYSQL_DEFAULT_AUTH, opt_default_auth); + return res; +} + +/* + Disable direct calls of mysql_init, as it disregards shared memory base. +*/ +#define mysql_init(A) Please use mysql_client_init instead of mysql_init + + +/* Check if the connection has InnoDB tables */ + +static my_bool check_have_innodb(MYSQL *conn) +{ + MYSQL_RES *res; + MYSQL_ROW row; + int rc; + my_bool result; + + rc= mysql_query(conn, "show variables like 'have_innodb'"); + myquery(rc); + res= mysql_use_result(conn); + DIE_UNLESS(res); + + row= mysql_fetch_row(res); + DIE_UNLESS(row); + + result= strcmp(row[1], "YES") == 0; + mysql_free_result(res); + return result; +} + + +/* + This is to be what mysql_query() is for mysql_real_query(), for + mysql_simple_prepare(): a variant without the 'length' parameter. +*/ + +static MYSQL_STMT *STDCALL +mysql_simple_prepare(MYSQL *mysql_arg, const char *query) +{ + MYSQL_STMT *stmt= mysql_stmt_init(mysql_arg); + if (stmt && mysql_stmt_prepare(stmt, query, (uint) strlen(query))) + { + mysql_stmt_close(stmt); + return 0; + } + return stmt; +} + + +/** + Connect to the server with options given by arguments to this application, + stored in global variables opt_host, opt_user, opt_password, opt_db, + opt_port and opt_unix_socket. + + @param flag[in] client_flag passed on to mysql_real_connect + @param protocol[in] MYSQL_PROTOCOL_* to use for this connection + @param auto_reconnect[in] set to 1 for auto reconnect + + @return pointer to initialized and connected MYSQL object +*/ +static MYSQL* client_connect(ulong flag, uint protocol, my_bool auto_reconnect) +{ + MYSQL* mysql; + int rc; + static char query[MAX_TEST_QUERY_LENGTH]; + myheader_r("client_connect"); + + if (!opt_silent) + fprintf(stdout, "\n Establishing a connection to '%s' ...", + opt_host ? opt_host : ""); + + if (!(mysql= mysql_client_init(NULL))) + { + opt_silent= 0; + myerror("mysql_client_init() failed"); + exit(1); + } + /* enable local infile, in non-binary builds often disabled by default */ + mysql_options(mysql, MYSQL_OPT_LOCAL_INFILE, 0); + mysql_options(mysql, MYSQL_OPT_PROTOCOL, &protocol); + if (opt_plugin_dir && *opt_plugin_dir) + mysql_options(mysql, MYSQL_PLUGIN_DIR, opt_plugin_dir); + + if (opt_default_auth && *opt_default_auth) + mysql_options(mysql, MYSQL_DEFAULT_AUTH, opt_default_auth); + + if (!(mysql_real_connect(mysql, opt_host, opt_user, + opt_password, opt_db ? opt_db:"test", opt_port, + opt_unix_socket, flag))) + { + opt_silent= 0; + myerror("connection failed"); + mysql_close(mysql); + fprintf(stdout, "\n Check the connection options using --help or -?\n"); + exit(1); + } + mysql->reconnect= auto_reconnect; + + if (!opt_silent) + fprintf(stdout, "OK"); + + /* set AUTOCOMMIT to ON*/ + mysql_autocommit(mysql, TRUE); + + if (!opt_silent) + { + fprintf(stdout, "\nConnected to MySQL server version: %s (%lu)\n", + mysql_get_server_info(mysql), + (ulong) mysql_get_server_version(mysql)); + fprintf(stdout, "\n Creating a test database '%s' ...", current_db); + } + strxmov(query, "CREATE DATABASE IF NOT EXISTS ", current_db, NullS); + + rc= mysql_query(mysql, query); + myquery(rc); + + strxmov(query, "USE ", current_db, NullS); + rc= mysql_query(mysql, query); + myquery(rc); + have_innodb= check_have_innodb(mysql); + + if (!opt_silent) + fprintf(stdout, "OK\n"); + + return mysql; +} + + +/* Close the connection */ + +static void client_disconnect(MYSQL* mysql, my_bool drop_db) +{ + static char query[MAX_TEST_QUERY_LENGTH]; + + myheader_r("client_disconnect"); + + if (mysql) + { + if (drop_db) + { + if (!opt_silent) + fprintf(stdout, "\n dropping the test database '%s' ...", current_db); + strxmov(query, "DROP DATABASE IF EXISTS ", current_db, NullS); + + mysql_query(mysql, query); + if (!opt_silent) + fprintf(stdout, "OK"); + } + + if (!opt_silent) + fprintf(stdout, "\n closing the connection ..."); + mysql_close(mysql); + if (!opt_silent) + fprintf(stdout, "OK\n"); + } +} + + +/* Print dashes */ + +static void my_print_dashes(MYSQL_RES *result) +{ + MYSQL_FIELD *field; + unsigned int i, j; + + mysql_field_seek(result, 0); + fputc('\t', stdout); + fputc('+', stdout); + + for(i= 0; i< mysql_num_fields(result); i++) + { + field= mysql_fetch_field(result); + for(j= 0; j < field->max_length+2; j++) + fputc('-', stdout); + fputc('+', stdout); + } + fputc('\n', stdout); +} + + +/* Print resultset metadata information */ + +static void my_print_result_metadata(MYSQL_RES *result) +{ + MYSQL_FIELD *field; + unsigned int i, j; + unsigned int field_count; + + mysql_field_seek(result, 0); + if (!opt_silent) + { + fputc('\n', stdout); + fputc('\n', stdout); + } + + field_count= mysql_num_fields(result); + for(i= 0; i< field_count; i++) + { + field= mysql_fetch_field(result); + j= strlen(field->name); + if (j < field->max_length) + j= field->max_length; + if (j < 4 && !IS_NOT_NULL(field->flags)) + j= 4; + field->max_length= j; + } + if (!opt_silent) + { + my_print_dashes(result); + fputc('\t', stdout); + fputc('|', stdout); + } + + mysql_field_seek(result, 0); + for(i= 0; i< field_count; i++) + { + field= mysql_fetch_field(result); + if (!opt_silent) + fprintf(stdout, " %-*s |", (int) field->max_length, field->name); + } + if (!opt_silent) + { + fputc('\n', stdout); + my_print_dashes(result); + } +} + + +/* Process the result set */ + +static int my_process_result_set(MYSQL_RES *result) +{ + MYSQL_ROW row; + MYSQL_FIELD *field; + unsigned int i; + unsigned int row_count= 0; + + if (!result) + return 0; + + my_print_result_metadata(result); + + while ((row= mysql_fetch_row(result)) != NULL) + { + mysql_field_seek(result, 0); + if (!opt_silent) + { + fputc('\t', stdout); + fputc('|', stdout); + } + + for(i= 0; i< mysql_num_fields(result); i++) + { + field= mysql_fetch_field(result); + if (!opt_silent) + { + if (row[i] == NULL) + fprintf(stdout, " %-*s |", (int) field->max_length, "NULL"); + else if (IS_NUM(field->type)) + fprintf(stdout, " %*s |", (int) field->max_length, row[i]); + else + fprintf(stdout, " %-*s |", (int) field->max_length, row[i]); + } + } + if (!opt_silent) + { + fputc('\t', stdout); + fputc('\n', stdout); + } + row_count++; + } + if (!opt_silent) + { + if (row_count) + my_print_dashes(result); + + if (mysql_errno(mysql) != 0) + fprintf(stderr, "\n\tmysql_fetch_row() failed\n"); + else + fprintf(stdout, "\n\t%d %s returned\n", row_count, + row_count == 1 ? "row" : "rows"); + } + return row_count; +} + + +static int my_process_result(MYSQL *mysql_arg) +{ + MYSQL_RES *result; + int row_count; + + if (!(result= mysql_store_result(mysql_arg))) + return 0; + + row_count= my_process_result_set(result); + + mysql_free_result(result); + return row_count; +} + + +/* Process the statement result set */ + +#define MAX_RES_FIELDS 50 +#define MAX_FIELD_DATA_SIZE 255 + +static int my_process_stmt_result(MYSQL_STMT *stmt) +{ + int field_count; + int row_count= 0; + MYSQL_BIND buffer[MAX_RES_FIELDS]; + MYSQL_FIELD *field; + MYSQL_RES *result; + char data[MAX_RES_FIELDS][MAX_FIELD_DATA_SIZE]; + ulong length[MAX_RES_FIELDS]; + my_bool is_null[MAX_RES_FIELDS]; + int rc, i; + + if (!(result= mysql_stmt_result_metadata(stmt))) /* No meta info */ + { + while (!mysql_stmt_fetch(stmt)) + row_count++; + return row_count; + } + + field_count= min(mysql_num_fields(result), MAX_RES_FIELDS); + + bzero((char*) buffer, sizeof(buffer)); + bzero((char*) length, sizeof(length)); + bzero((char*) is_null, sizeof(is_null)); + + for(i= 0; i < field_count; i++) + { + buffer[i].buffer_type= MYSQL_TYPE_STRING; + buffer[i].buffer_length= MAX_FIELD_DATA_SIZE; + buffer[i].length= &length[i]; + buffer[i].buffer= (void *) data[i]; + buffer[i].is_null= &is_null[i]; + } + + rc= mysql_stmt_bind_result(stmt, buffer); + check_execute(stmt, rc); + + rc= 1; + mysql_stmt_attr_set(stmt, STMT_ATTR_UPDATE_MAX_LENGTH, (void*)&rc); + rc= mysql_stmt_store_result(stmt); + check_execute(stmt, rc); + my_print_result_metadata(result); + + mysql_field_seek(result, 0); + while ((rc= mysql_stmt_fetch(stmt)) == 0) + { + if (!opt_silent) + { + fputc('\t', stdout); + fputc('|', stdout); + } + mysql_field_seek(result, 0); + for (i= 0; i < field_count; i++) + { + field= mysql_fetch_field(result); + if (!opt_silent) + { + if (is_null[i]) + fprintf(stdout, " %-*s |", (int) field->max_length, "NULL"); + else if (length[i] == 0) + { + data[i][0]= '\0'; /* unmodified buffer */ + fprintf(stdout, " %*s |", (int) field->max_length, data[i]); + } + else if (IS_NUM(field->type)) + fprintf(stdout, " %*s |", (int) field->max_length, data[i]); + else + fprintf(stdout, " %-*s |", (int) field->max_length, data[i]); + } + } + if (!opt_silent) + { + fputc('\t', stdout); + fputc('\n', stdout); + } + row_count++; + } + DIE_UNLESS(rc == MYSQL_NO_DATA); + if (!opt_silent) + { + if (row_count) + my_print_dashes(result); + fprintf(stdout, "\n\t%d %s returned\n", row_count, + row_count == 1 ? "row" : "rows"); + } + mysql_free_result(result); + return row_count; +} + + +/* Prepare statement, execute, and process result set for given query */ + +int my_stmt_result(const char *buff) +{ + MYSQL_STMT *stmt; + int row_count; + int rc; + + if (!opt_silent) + fprintf(stdout, "\n\n %s", buff); + stmt= mysql_simple_prepare(mysql, buff); + check_stmt(stmt); + + rc= mysql_stmt_execute(stmt); + check_execute(stmt, rc); + + row_count= my_process_stmt_result(stmt); + mysql_stmt_close(stmt); + + return row_count; +} + +/* Print the total number of warnings and the warnings themselves. */ + +void my_process_warnings(MYSQL *conn, unsigned expected_warning_count) +{ + MYSQL_RES *result; + int rc; + + if (!opt_silent) + fprintf(stdout, "\n total warnings: %u (expected: %u)\n", + mysql_warning_count(conn), expected_warning_count); + + DIE_UNLESS(mysql_warning_count(mysql) == expected_warning_count); + + rc= mysql_query(conn, "SHOW WARNINGS"); + DIE_UNLESS(rc == 0); + + result= mysql_store_result(conn); + mytest(result); + + rc= my_process_result_set(result); + mysql_free_result(result); +} + + +/* Utility function to verify a particular column data */ + +static void verify_col_data(const char *table, const char *col, + const char *exp_data) +{ + static char query[MAX_TEST_QUERY_LENGTH]; + MYSQL_RES *result; + MYSQL_ROW row; + int rc, field= 1; + + if (table && col) + { + strxmov(query, "SELECT ", col, " FROM ", table, " LIMIT 1", NullS); + if (!opt_silent) + fprintf(stdout, "\n %s", query); + rc= mysql_query(mysql, query); + myquery(rc); + + field= 0; + } + + result= mysql_use_result(mysql); + mytest(result); + + if (!(row= mysql_fetch_row(result)) || !row[field]) + { + fprintf(stdout, "\n *** ERROR: FAILED TO GET THE RESULT ***"); + exit(1); + } + if (strcmp(row[field], exp_data)) + { + fprintf(stdout, "\n obtained: `%s` (expected: `%s`)", + row[field], exp_data); + DIE_UNLESS(FALSE); + } + mysql_free_result(result); +} + + +/* Utility function to verify the field members */ + +#define verify_prepare_field(result,no,name,org_name,type,table,\ + org_table,db,length,def) \ + do_verify_prepare_field((result),(no),(name),(org_name),(type), \ + (table),(org_table),(db),(length),(def), \ + __FILE__, __LINE__) + +static void do_verify_prepare_field(MYSQL_RES *result, + unsigned int no, const char *name, + const char *org_name, + enum enum_field_types type, + const char *table, + const char *org_table, const char *db, + unsigned long length, const char *def, + const char *file, int line) +{ + MYSQL_FIELD *field; + CHARSET_INFO *cs; + ulonglong expected_field_length; + + if (!(field= mysql_fetch_field_direct(result, no))) + { + fprintf(stdout, "\n *** ERROR: FAILED TO GET THE RESULT ***"); + exit(1); + } + cs= get_charset(field->charsetnr, 0); + DIE_UNLESS(cs); + if ((expected_field_length= length * cs->mbmaxlen) > UINT_MAX32) + expected_field_length= UINT_MAX32; + if (!opt_silent) + { + fprintf(stdout, "\n field[%d]:", no); + fprintf(stdout, "\n name :`%s`\t(expected: `%s`)", field->name, name); + fprintf(stdout, "\n org_name :`%s`\t(expected: `%s`)", + field->org_name, org_name); + fprintf(stdout, "\n type :`%d`\t(expected: `%d`)", field->type, type); + if (table) + fprintf(stdout, "\n table :`%s`\t(expected: `%s`)", + field->table, table); + if (org_table) + fprintf(stdout, "\n org_table:`%s`\t(expected: `%s`)", + field->org_table, org_table); + fprintf(stdout, "\n database :`%s`\t(expected: `%s`)", field->db, db); + fprintf(stdout, "\n length :`%lu`\t(expected: `%llu`)", + field->length, expected_field_length); + fprintf(stdout, "\n maxlength:`%ld`", field->max_length); + fprintf(stdout, "\n charsetnr:`%d`", field->charsetnr); + fprintf(stdout, "\n default :`%s`\t(expected: `%s`)", + field->def ? field->def : "(null)", def ? def: "(null)"); + fprintf(stdout, "\n"); + } + DIE_UNLESS(strcmp(field->name, name) == 0); + DIE_UNLESS(strcmp(field->org_name, org_name) == 0); + /* + XXX: silent column specification change works based on number of + bytes a column occupies. So CHAR -> VARCHAR upgrade is possible even + for CHAR(2) column if its character set is multibyte. + VARCHAR -> CHAR downgrade won't work for VARCHAR(3) as one would + expect. + */ + if (cs->mbmaxlen == 1) + { + if (field->type != type) + { + fprintf(stderr, + "Expected field type: %d, got type: %d in file %s, line %d\n", + (int) type, (int) field->type, file, line); + DIE_UNLESS(field->type == type); + } + } + if (table) + DIE_UNLESS(strcmp(field->table, table) == 0); + if (org_table) + DIE_UNLESS(strcmp(field->org_table, org_table) == 0); + DIE_UNLESS(strcmp(field->db, db) == 0); + /* + Character set should be taken into account for multibyte encodings, such + as utf8. Field length is calculated as number of characters * maximum + number of bytes a character can occupy. + */ + if (length && (field->length != expected_field_length)) + { + fflush(stdout); + fprintf(stderr, "Expected field length: %llu, got length: %lu\n", + expected_field_length, field->length); + fflush(stderr); + DIE_UNLESS(field->length == expected_field_length); + } + if (def) + DIE_UNLESS(strcmp(field->def, def) == 0); +} + + +/* Utility function to verify the parameter count */ + +static void verify_param_count(MYSQL_STMT *stmt, long exp_count) +{ + long param_count= mysql_stmt_param_count(stmt); + if (!opt_silent) + fprintf(stdout, "\n total parameters in stmt: `%ld` (expected: `%ld`)", + param_count, exp_count); + DIE_UNLESS(param_count == exp_count); +} + + +/* Utility function to verify the total affected rows */ + +static void verify_st_affected_rows(MYSQL_STMT *stmt, ulonglong exp_count) +{ + ulonglong affected_rows= mysql_stmt_affected_rows(stmt); + if (!opt_silent) + fprintf(stdout, "\n total affected rows: `%ld` (expected: `%ld`)", + (long) affected_rows, (long) exp_count); + DIE_UNLESS(affected_rows == exp_count); +} + + +/* Utility function to verify the total affected rows */ + +static void verify_affected_rows(ulonglong exp_count) +{ + ulonglong affected_rows= mysql_affected_rows(mysql); + if (!opt_silent) + fprintf(stdout, "\n total affected rows: `%ld` (expected: `%ld`)", + (long) affected_rows, (long) exp_count); + DIE_UNLESS(affected_rows == exp_count); +} + + +/* Utility function to verify the total fields count */ + +static void verify_field_count(MYSQL_RES *result, uint exp_count) +{ + uint field_count= mysql_num_fields(result); + if (!opt_silent) + fprintf(stdout, "\n total fields in the result set: `%d` (expected: `%d`)", + field_count, exp_count); + DIE_UNLESS(field_count == exp_count); +} + + +/* Utility function to execute a query using prepare-execute */ + +#ifndef EMBEDDED_LIBRARY +static void execute_prepare_query(const char *query, ulonglong exp_count) +{ + MYSQL_STMT *stmt; + ulonglong affected_rows; + int rc; + + stmt= mysql_simple_prepare(mysql, query); + check_stmt(stmt); + + rc= mysql_stmt_execute(stmt); + myquery(rc); + + affected_rows= mysql_stmt_affected_rows(stmt); + if (!opt_silent) + fprintf(stdout, "\n total affected rows: `%ld` (expected: `%ld`)", + (long) affected_rows, (long) exp_count); + + DIE_UNLESS(affected_rows == exp_count); + mysql_stmt_close(stmt); +} +#endif + +/* +Accepts arbitrary number of queries and runs them against the database. +Used to fill tables for each test. +*/ + +void fill_tables(const char **query_list, unsigned query_count) +{ + int rc; + const char **query; + DBUG_ENTER("fill_tables"); + for (query= query_list; query < query_list + query_count; + ++query) + { + rc= mysql_query(mysql, *query); + myquery(rc); + } + DBUG_VOID_RETURN; +} + +/* +All state of fetch from one statement: statement handle, out buffers, +fetch position. +See fetch_n for for the only use case. +*/ + +enum { MAX_COLUMN_LENGTH= 255 }; + +typedef struct st_stmt_fetch +{ +const char *query; +unsigned stmt_no; +MYSQL_STMT *handle; +my_bool is_open; +MYSQL_BIND *bind_array; +char **out_data; +unsigned long *out_data_length; +unsigned column_count; +unsigned row_count; +} Stmt_fetch; + + +/* +Create statement handle, prepare it with statement, execute and allocate +fetch buffers. +*/ + +void stmt_fetch_init(Stmt_fetch *fetch, unsigned stmt_no_arg, +const char *query_arg) +{ + unsigned long type= CURSOR_TYPE_READ_ONLY; + int rc; + unsigned i; + MYSQL_RES *metadata; + DBUG_ENTER("stmt_fetch_init"); + + /* Save query and statement number for error messages */ + fetch->stmt_no= stmt_no_arg; + fetch->query= query_arg; + + fetch->handle= mysql_stmt_init(mysql); + + rc= mysql_stmt_prepare(fetch->handle, fetch->query, strlen(fetch->query)); + check_execute(fetch->handle, rc); + + /* + The attribute is sent to server on execute and asks to open read-only + for result set + */ + mysql_stmt_attr_set(fetch->handle, STMT_ATTR_CURSOR_TYPE, + (const void*) &type); + + rc= mysql_stmt_execute(fetch->handle); + check_execute(fetch->handle, rc); + + /* Find out total number of columns in result set */ + metadata= mysql_stmt_result_metadata(fetch->handle); + fetch->column_count= mysql_num_fields(metadata); + mysql_free_result(metadata); + + /* + Now allocate bind handles and buffers for output data: + calloc memory to reduce number of MYSQL_BIND members we need to + set up. + */ + + fetch->bind_array= (MYSQL_BIND *) calloc(1, sizeof(MYSQL_BIND) * + fetch->column_count); + fetch->out_data= (char**) calloc(1, sizeof(char*) * fetch->column_count); + fetch->out_data_length= (ulong*) calloc(1, sizeof(ulong) * + fetch->column_count); + for (i= 0; i < fetch->column_count; ++i) + { + fetch->out_data[i]= (char*) calloc(1, MAX_COLUMN_LENGTH); + fetch->bind_array[i].buffer_type= MYSQL_TYPE_STRING; + fetch->bind_array[i].buffer= fetch->out_data[i]; + fetch->bind_array[i].buffer_length= MAX_COLUMN_LENGTH; + fetch->bind_array[i].length= fetch->out_data_length + i; + } + + mysql_stmt_bind_result(fetch->handle, fetch->bind_array); + + fetch->row_count= 0; + fetch->is_open= TRUE; + + /* Ready for reading rows */ + DBUG_VOID_RETURN; +} + + +/* Fetch and print one row from cursor */ + +int stmt_fetch_fetch_row(Stmt_fetch *fetch) +{ + int rc; + unsigned i; + DBUG_ENTER("stmt_fetch_fetch_row"); + + if ((rc= mysql_stmt_fetch(fetch->handle)) == 0) + { + ++fetch->row_count; + if (!opt_silent) + printf("Stmt %d fetched row %d:\n", fetch->stmt_no, fetch->row_count); + for (i= 0; i < fetch->column_count; ++i) + { + fetch->out_data[i][fetch->out_data_length[i]]= '\0'; + if (!opt_silent) + printf("column %d: %s\n", i+1, fetch->out_data[i]); + } + } + else + fetch->is_open= FALSE; + DBUG_RETURN(rc); +} + + +void stmt_fetch_close(Stmt_fetch *fetch) +{ + unsigned i; + DBUG_ENTER("stmt_fetch_close"); + + for (i= 0; i < fetch->column_count; ++i) + free(fetch->out_data[i]); + free(fetch->out_data); + free(fetch->out_data_length); + free(fetch->bind_array); + mysql_stmt_close(fetch->handle); + DBUG_VOID_RETURN; +} + +/* +For given array of queries, open query_count cursors and fetch +from them in simultaneous manner. +In case there was an error in one of the cursors, continue +reading from the rest. +*/ + +enum fetch_type { USE_ROW_BY_ROW_FETCH= 0, USE_STORE_RESULT= 1 }; + +my_bool fetch_n(const char **query_list, unsigned query_count, +enum fetch_type fetch_type) +{ + unsigned open_statements= query_count; + int rc, error_count= 0; + Stmt_fetch *fetch_array= (Stmt_fetch*) calloc(1, sizeof(Stmt_fetch) * + query_count); + Stmt_fetch *fetch; + DBUG_ENTER("fetch_n"); + + for (fetch= fetch_array; fetch < fetch_array + query_count; ++fetch) + { + /* Init will exit(1) in case of error */ + stmt_fetch_init(fetch, fetch - fetch_array, + query_list[fetch - fetch_array]); + } + + if (fetch_type == USE_STORE_RESULT) + { + for (fetch= fetch_array; fetch < fetch_array + query_count; ++fetch) + { + rc= mysql_stmt_store_result(fetch->handle); + check_execute(fetch->handle, rc); + } + } + + while (open_statements) + { + for (fetch= fetch_array; fetch < fetch_array + query_count; ++fetch) + { + if (fetch->is_open && (rc= stmt_fetch_fetch_row(fetch))) + { + open_statements--; + /* + We try to fetch from the rest of the statements in case of + error + */ + if (rc != MYSQL_NO_DATA) + { + fprintf(stderr, + "Got error reading rows from statement %d,\n" + "query is: %s,\n" + "error message: %s", (int) (fetch - fetch_array), + fetch->query, + mysql_stmt_error(fetch->handle)); + error_count++; + } + } + } + } + if (error_count) + fprintf(stderr, "Fetch FAILED"); + else + { + unsigned total_row_count= 0; + for (fetch= fetch_array; fetch < fetch_array + query_count; ++fetch) + total_row_count+= fetch->row_count; + if (!opt_silent) + printf("Success, total rows fetched: %d\n", total_row_count); + } + for (fetch= fetch_array; fetch < fetch_array + query_count; ++fetch) + stmt_fetch_close(fetch); + free(fetch_array); + DBUG_RETURN(error_count != 0); +} + +/* Separate thread query to test some cases */ + +static my_bool thread_query(const char *query) +{ + MYSQL *l_mysql; + my_bool error; + + error= 0; + if (!opt_silent) + fprintf(stdout, "\n in thread_query(%s)", query); + if (!(l_mysql= mysql_client_init(NULL))) + { + myerror("mysql_client_init() failed"); + return 1; + } + if (!(mysql_real_connect(l_mysql, opt_host, opt_user, + opt_password, current_db, opt_port, + opt_unix_socket, 0))) + { + myerror("connection failed"); + error= 1; + goto end; + } + l_mysql->reconnect= 1; + if (mysql_query(l_mysql, query)) + { + fprintf(stderr, "Query failed (%s)\n", mysql_error(l_mysql)); + error= 1; + goto end; + } + mysql_commit(l_mysql); + end: + mysql_close(l_mysql); + return error; +} + + +/* + Read and parse arguments and MySQL options from my.cnf +*/ + +static const char *client_test_load_default_groups[]= +{ "client", "client-server", "client-mariadb", 0 }; +static char **defaults_argv; + +static struct my_option client_test_long_options[] = +{ + {"basedir", 'b', "Basedir for tests.", (char**) &opt_basedir, + (char**) &opt_basedir, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0}, + {"count", 't', "Number of times test to be executed", &opt_count, + &opt_count, 0, GET_UINT, REQUIRED_ARG, 1, 0, 0, 0, 0, 0}, + {"database", 'D', "Database to use", &opt_db, &opt_db, + 0, GET_STR_ALLOC, REQUIRED_ARG, 0, 0, 0, 0, 0, 0}, + {"debug", '#', "Output debug log", (char**) &default_dbug_option, + (char**) &default_dbug_option, 0, GET_STR, OPT_ARG, 0, 0, 0, 0, 0, 0}, + {"help", '?', "Display this help and exit", 0, 0, 0, GET_NO_ARG, NO_ARG, 0, + 0, 0, 0, 0, 0}, + {"host", 'h', "Connect to host", &opt_host, &opt_host, + 0, GET_STR_ALLOC, REQUIRED_ARG, 0, 0, 0, 0, 0, 0}, + {"password", 'p', + "Password to use when connecting to server. If password is not given it's asked from the tty.", + 0, 0, 0, GET_STR, OPT_ARG, 0, 0, 0, 0, 0, 0}, + {"port", 'P', "Port number to use for connection or 0 for default to, in " + "order of preference, my.cnf, $MYSQL_TCP_PORT, " +#if MYSQL_PORT_DEFAULT == 0 + "/etc/services, " +#endif + "built-in default (" STRINGIFY_ARG(MYSQL_PORT) ").", + &opt_port, &opt_port, 0, GET_UINT, REQUIRED_ARG, 0, 0, 0, 0, 0, 0}, + {"server-arg", 'A', "Send embedded server this as a parameter.", + 0, 0, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0}, + {"show-tests", 'T', "Show all tests' names", 0, 0, 0, GET_NO_ARG, NO_ARG, + 0, 0, 0, 0, 0, 0}, + {"silent", 's', "Be more silent", 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, + 0}, +#ifdef HAVE_SMEM + {"shared-memory-base-name", 'm', "Base name of shared memory.", + &shared_memory_base_name, (uchar**)&shared_memory_base_name, 0, + GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0}, +#endif + {"socket", 'S', "Socket file to use for connection", + &opt_unix_socket, &opt_unix_socket, 0, GET_STR, + REQUIRED_ARG, 0, 0, 0, 0, 0, 0}, + {"testcase", 'c', + "May disable some code when runs as mysql-test-run testcase.", + 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0}, +#ifndef DONT_ALLOW_USER_CHANGE + {"user", 'u', "User for login if not current user", &opt_user, + &opt_user, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0}, +#endif + {"vardir", 'v', "Data dir for tests.", (char**) &opt_vardir, + (char**) &opt_vardir, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0}, + {"non-blocking-api", 'n', + "Use the non-blocking client API for communication.", + &non_blocking_api_enabled, &non_blocking_api_enabled, 0, + GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0}, + {"getopt-ll-test", 'g', "Option for testing bug in getopt library", + &opt_getopt_ll_test, &opt_getopt_ll_test, 0, + GET_LL, REQUIRED_ARG, 0, 0, LONGLONG_MAX, 0, 0, 0}, + {"plugin_dir", 0, "Directory for client-side plugins.", + &opt_plugin_dir, &opt_plugin_dir, 0, + GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0}, + {"default_auth", 0, "Default authentication client-side plugin to use.", + &opt_default_auth, &opt_default_auth, 0, + GET_STR, 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} +}; + + +static void usage(void) +{ + /* show the usage string when the user asks for this */ + putc('\n', stdout); + printf("%s Ver %s Distrib %s, for %s (%s)\n", + my_progname, VER, MYSQL_SERVER_VERSION, SYSTEM_TYPE, MACHINE_TYPE); + puts("By Monty, Venu, Kent and others\n"); + printf("\ +Copyright (C) 2002-2004 MySQL AB\n\ +This software comes with ABSOLUTELY NO WARRANTY. This is free software,\n\ +and you are welcome to modify and redistribute it under the GPL license\n"); + printf("Usage: %s [OPTIONS] [TESTNAME1 TESTNAME2...]\n", my_progname); + my_print_help(client_test_long_options); + print_defaults("my", client_test_load_default_groups); + my_print_variables(client_test_long_options); +} + +static struct my_tests_st *get_my_tests(); /* To be defined in main .c file */ + +static struct my_tests_st *my_testlist= 0; + +static my_bool +get_one_option(int optid, const struct my_option *opt __attribute__((unused)), + char *argument) +{ + switch (optid) { + case '#': + DBUG_PUSH(argument ? argument : default_dbug_option); + break; + case 'c': + opt_testcase = 1; + break; + case 'p': + if (argument) + { + char *start=argument; + my_free(opt_password); + opt_password= my_strdup(argument, MYF(MY_FAE)); + while (*argument) *argument++= 'x'; /* Destroy argument */ + if (*start) + start[1]=0; + } + else + tty_password= 1; + break; + case 's': + if (argument == disabled_my_option) + opt_silent= 0; + else + opt_silent++; + break; + case 'A': + /* + When the embedded server is being tested, the test suite needs to be + able to pass command-line arguments to the embedded server so it can + locate the language files and data directory. The test suite + (mysql-test-run) never uses config files, just command-line options. + */ + if (!embedded_server_arg_count) + { + embedded_server_arg_count= 1; + embedded_server_args[0]= (char*) ""; + } + if (embedded_server_arg_count == MAX_SERVER_ARGS-1 || + !(embedded_server_args[embedded_server_arg_count++]= + my_strdup(argument, MYF(MY_FAE)))) + { + DIE("Can't use server argument"); + } + break; + case 'T': + { + struct my_tests_st *fptr; + + printf("All possible test names:\n\n"); + for (fptr= my_testlist; fptr->name; fptr++) + printf("%s\n", fptr->name); + exit(0); + break; + } + case '?': + case 'I': /* Info */ + usage(); + exit(0); + break; + } + return 0; +} + +static void get_options(int *argc, char ***argv) +{ + int ho_error; + + if ((ho_error= handle_options(argc, argv, client_test_long_options, + get_one_option))) + exit(ho_error); + + if (tty_password) + opt_password= get_tty_password(NullS); + return; +} + +/* + Print the test output on successful execution before exiting +*/ + +static void print_test_output() +{ + if (opt_silent < 3) + { + fprintf(stdout, "\n\n"); + fprintf(stdout, "All '%d' tests were successful (in '%d' iterations)", + test_count-1, opt_count); + fprintf(stdout, "\n Total execution time: %g SECS", total_time); + if (opt_count > 1) + fprintf(stdout, " (Avg: %g SECS)", total_time/opt_count); + + fprintf(stdout, "\n\n!!! SUCCESS !!!\n"); + } +} + +/*************************************************************************** + main routine +***************************************************************************/ + + +int main(int argc, char **argv) +{ + struct my_tests_st *fptr; + my_testlist= get_my_tests(); + + MY_INIT(argv[0]); + + if (load_defaults("my", client_test_load_default_groups, &argc, &argv)) + exit(1); + + defaults_argv= argv; + get_options(&argc, &argv); + + if (mysql_server_init(embedded_server_arg_count, + embedded_server_args, + (char**) embedded_server_groups)) + DIE("Can't initialize MySQL server"); + + /* connect to server with no flags, default protocol, auto reconnect true */ + mysql= client_connect(0, MYSQL_PROTOCOL_DEFAULT, 1); + + total_time= 0; + for (iter_count= 1; iter_count <= opt_count; iter_count++) + { + /* Start of tests */ + test_count= 1; + start_time= time((time_t *)0); + if (!argc) + { + for (fptr= my_testlist; fptr->name; fptr++) + (*fptr->function)(); + } + else + { + for ( ; *argv ; argv++) + { + for (fptr= my_testlist; fptr->name; fptr++) + { + if (!strcmp(fptr->name, *argv)) + { + (*fptr->function)(); + break; + } + } + if (!fptr->name) + { + fprintf(stderr, "\n\nGiven test not found: '%s'\n", *argv); + fprintf(stderr, "See legal test names with %s -T\n\nAborting!\n", + my_progname); + client_disconnect(mysql, 1); + free_defaults(defaults_argv); + exit(1); + } + } + } + + end_time= time((time_t *)0); + total_time+= difftime(end_time, start_time); + + /* End of tests */ + } + + client_disconnect(mysql, 1); /* disconnect from server */ + + free_defaults(defaults_argv); + print_test_output(); + + while (embedded_server_arg_count > 1) + my_free(embedded_server_args[--embedded_server_arg_count]); + + mysql_server_end(); + + my_end(0); + + exit(0); +} diff --git a/tests/mysql_client_test.c b/tests/mysql_client_test.c index 6bee26129e7..9c2329e609a 100644 --- a/tests/mysql_client_test.c +++ b/tests/mysql_client_test.c @@ -1,5 +1,5 @@ -/* Copyright (c) 2002, 2011, Oracle and/or its affiliates. - Copyright (c) 2008-2011 Monty Program Ab +/* Copyright (c) 2002, 2012, Oracle and/or its affiliates. + Copyright (c) 2008, 2012, Monty Program Ab This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -27,407 +27,12 @@ */ -#include <my_global.h> -#include <my_sys.h> -#include <mysql.h> -#include <errmsg.h> -#include <my_getopt.h> -#include <m_string.h> -#include <mysqld_error.h> -#include <my_compare.h> -#include <sql_common.h> -#include <mysql/client_plugin.h> - -/* - If non_blocking_api_enabled is true, we will re-define all the blocking - API functions as wrappers that call the corresponding non-blocking API - and use poll()/select() to wait for them to complete. This way we can get - a good coverage testing of the non-blocking API as well. -*/ -static my_bool non_blocking_api_enabled= 0; -#if !defined(EMBEDDED_LIBRARY) -#define WRAP_NONBLOCK_ENABLED non_blocking_api_enabled -#include "nonblock-wrappers.h" -#endif - -#define VER "2.1" -#define MAX_TEST_QUERY_LENGTH 300 /* MAX QUERY BUFFER LENGTH */ -#define MAX_KEY MAX_INDEXES -#define MAX_SERVER_ARGS 64 - -/* set default options */ -#ifdef NOT_USED -static int opt_testcase = 0; -#endif -static char *opt_db= 0; -static char *opt_user= 0; -static char *opt_password= 0; -static char *opt_host= 0; -static char *opt_unix_socket= 0; -#ifdef HAVE_SMEM -static char *shared_memory_base_name= 0; -#endif -static unsigned int opt_port; -static my_bool tty_password= 0, opt_silent= 0; - -static MYSQL *mysql= 0; -static char current_db[]= "client_test_db"; -static unsigned int test_count= 0; -static unsigned int opt_count= 0; -static unsigned int iter_count= 0; -static my_bool have_innodb= FALSE; -static char *opt_plugin_dir= 0, *opt_default_auth= 0; - -static const char *opt_basedir= "./"; -static const char *opt_vardir= "mysql-test/var"; - -static longlong opt_getopt_ll_test= 0; - -static int embedded_server_arg_count= 0; -static char *embedded_server_args[MAX_SERVER_ARGS]; - -static const char *embedded_server_groups[]= { - "server", - "embedded", - "mysql_client_test_SERVER", - NullS -}; - -static time_t start_time, end_time; -static double total_time; - -const char *default_dbug_option= "d:t:o,/tmp/mysql_client_test.trace"; - -struct my_tests_st -{ - const char *name; - void (*function)(); -}; - -#define myheader(str) \ -DBUG_PRINT("test", ("name: %s", str)); \ -if (opt_silent < 2) \ -{ \ - fprintf(stdout, "\n\n#####################################\n"); \ - fprintf(stdout, "%u of (%u/%u): %s", test_count++, iter_count, \ - opt_count, str); \ - fprintf(stdout, " \n#####################################\n"); \ -} - -#define myheader_r(str) \ -DBUG_PRINT("test", ("name: %s", str)); \ -if (!opt_silent) \ -{ \ - fprintf(stdout, "\n\n#####################################\n"); \ - fprintf(stdout, "%s", str); \ - fprintf(stdout, " \n#####################################\n"); \ -} - -static void print_error(const char *msg); -static void print_st_error(MYSQL_STMT *stmt, const char *msg); -static void client_disconnect(MYSQL* mysql, my_bool drop_db); - - -/* - Abort unless given experssion is non-zero. - - SYNOPSIS - DIE_UNLESS(expr) - - DESCRIPTION - We can't use any kind of system assert as we need to - preserve tested invariants in release builds as well. -*/ - -#define DIE_UNLESS(expr) \ - ((void) ((expr) ? 0 : (die(__FILE__, __LINE__, #expr), 0))) -#define DIE_IF(expr) \ - ((void) ((expr) ? (die(__FILE__, __LINE__, #expr), 0) : 0)) -#define DIE(expr) \ - die(__FILE__, __LINE__, #expr) - -static void die(const char *file, int line, const char *expr) -{ - fflush(stdout); - fprintf(stderr, "%s:%d: check failed: '%s'\n", file, line, expr); - fflush(stderr); - exit(1); -} - - -#define myerror(msg) print_error(msg) -#define mysterror(stmt, msg) print_st_error(stmt, msg) - -#define myquery(RES) \ -{ \ - int r= (RES); \ - if (r) \ - myerror(NULL); \ - DIE_UNLESS(r == 0); \ -} - -#define myquery_r(r) \ -{ \ -if (r) \ - myerror(NULL); \ -DIE_UNLESS(r != 0); \ -} - -#define check_execute(stmt, r) \ -{ \ -if (r) \ - mysterror(stmt, NULL); \ -DIE_UNLESS(r == 0);\ -} - -#define check_execute_r(stmt, r) \ -{ \ -if (r) \ - mysterror(stmt, NULL); \ -DIE_UNLESS(r != 0);\ -} - -#define check_stmt(stmt) \ -{ \ -if ( stmt == 0) \ - myerror(NULL); \ -DIE_UNLESS(stmt != 0); \ -} - -#define check_stmt_r(stmt) \ -{ \ -if (stmt == 0) \ - myerror(NULL);\ -DIE_UNLESS(stmt == 0);\ -} - -#define mytest(x) if (!(x)) {myerror(NULL);DIE_UNLESS(FALSE);} -#define mytest_r(x) if ((x)) {myerror(NULL);DIE_UNLESS(FALSE);} - - -/* A workaround for Sun Forte 5.6 on Solaris x86 */ - -static int cmp_double(double *a, double *b) -{ - return *a == *b; -} - - -/* Print the error message */ - -static void print_error(const char *msg) -{ - if (!opt_silent) - { - if (mysql && mysql_errno(mysql)) - { - if (mysql->server_version) - fprintf(stdout, "\n [MySQL-%s]", mysql->server_version); - else - fprintf(stdout, "\n [MySQL]"); - fprintf(stdout, "[%d] %s\n", mysql_errno(mysql), mysql_error(mysql)); - } - else if (msg) - fprintf(stderr, " [MySQL] %s\n", msg); - } -} - - -static void print_st_error(MYSQL_STMT *stmt, const char *msg) -{ - if (!opt_silent) - { - if (stmt && mysql_stmt_errno(stmt)) - { - if (stmt->mysql && stmt->mysql->server_version) - fprintf(stdout, "\n [MySQL-%s]", stmt->mysql->server_version); - else - fprintf(stdout, "\n [MySQL]"); - - fprintf(stdout, "[%d] %s\n", mysql_stmt_errno(stmt), - mysql_stmt_error(stmt)); - } - else if (msg) - fprintf(stderr, " [MySQL] %s\n", msg); - } -} - -/* - Enhanced version of mysql_client_init(), which may also set shared memory - base on Windows. -*/ -static MYSQL *mysql_client_init(MYSQL* con) -{ - MYSQL* res = mysql_init(con); -#ifdef HAVE_SMEM - if (res && shared_memory_base_name) - mysql_options(res, MYSQL_SHARED_MEMORY_BASE_NAME, shared_memory_base_name); -#endif - if (res && non_blocking_api_enabled) - mysql_options(res, MYSQL_OPT_NONBLOCK, 0); - if (opt_plugin_dir && *opt_plugin_dir) - mysql_options(res, MYSQL_PLUGIN_DIR, opt_plugin_dir); - - if (opt_default_auth && *opt_default_auth) - mysql_options(res, MYSQL_DEFAULT_AUTH, opt_default_auth); - return res; -} - /* - Disable direct calls of mysql_init, as it disregards shared memory base. + The fw.c file includes all the mysql_client_test framework; this file + contains only the actual tests, plus the list of test functions to call. */ -#define mysql_init(A) Please use mysql_client_init instead of mysql_init - - -/* Check if the connection has InnoDB tables */ - -static my_bool check_have_innodb(MYSQL *conn) -{ - MYSQL_RES *res; - MYSQL_ROW row; - int rc; - my_bool result; - - rc= mysql_query(conn, "show variables like 'have_innodb'"); - myquery(rc); - res= mysql_use_result(conn); - DIE_UNLESS(res); - - row= mysql_fetch_row(res); - DIE_UNLESS(row); - - result= strcmp(row[1], "YES") == 0; - mysql_free_result(res); - return result; -} - - -/* - This is to be what mysql_query() is for mysql_real_query(), for - mysql_simple_prepare(): a variant without the 'length' parameter. -*/ - -static MYSQL_STMT *STDCALL -mysql_simple_prepare(MYSQL *mysql_arg, const char *query) -{ - MYSQL_STMT *stmt= mysql_stmt_init(mysql_arg); - if (stmt && mysql_stmt_prepare(stmt, query, (uint) strlen(query))) - { - mysql_stmt_close(stmt); - return 0; - } - return stmt; -} - - -/** - Connect to the server with options given by arguments to this application, - stored in global variables opt_host, opt_user, opt_password, opt_db, - opt_port and opt_unix_socket. - - @param flag[in] client_flag passed on to mysql_real_connect - @param protocol[in] MYSQL_PROTOCOL_* to use for this connection - @param auto_reconnect[in] set to 1 for auto reconnect - - @return pointer to initialized and connected MYSQL object -*/ -static MYSQL* client_connect(ulong flag, uint protocol, my_bool auto_reconnect) -{ - MYSQL* mysql; - int rc; - static char query[MAX_TEST_QUERY_LENGTH]; - myheader_r("client_connect"); - - if (!opt_silent) - fprintf(stdout, "\n Establishing a connection to '%s' ...", - opt_host ? opt_host : ""); - - if (!(mysql= mysql_client_init(NULL))) - { - opt_silent= 0; - myerror("mysql_client_init() failed"); - exit(1); - } - /* enable local infile, in non-binary builds often disabled by default */ - mysql_options(mysql, MYSQL_OPT_LOCAL_INFILE, 0); - mysql_options(mysql, MYSQL_OPT_PROTOCOL, &protocol); - if (opt_plugin_dir && *opt_plugin_dir) - mysql_options(mysql, MYSQL_PLUGIN_DIR, opt_plugin_dir); - - if (opt_default_auth && *opt_default_auth) - mysql_options(mysql, MYSQL_DEFAULT_AUTH, opt_default_auth); - - if (!(mysql_real_connect(mysql, opt_host, opt_user, - opt_password, opt_db ? opt_db:"test", opt_port, - opt_unix_socket, flag))) - { - opt_silent= 0; - myerror("connection failed"); - mysql_close(mysql); - fprintf(stdout, "\n Check the connection options using --help or -?\n"); - exit(1); - } - mysql->reconnect= auto_reconnect; - - if (!opt_silent) - fprintf(stdout, "OK"); - - /* set AUTOCOMMIT to ON*/ - mysql_autocommit(mysql, TRUE); - - if (!opt_silent) - { - fprintf(stdout, "\nConnected to MySQL server version: %s (%lu)\n", - mysql_get_server_info(mysql), - (ulong) mysql_get_server_version(mysql)); - fprintf(stdout, "\n Creating a test database '%s' ...", current_db); - } - strxmov(query, "CREATE DATABASE IF NOT EXISTS ", current_db, NullS); - - rc= mysql_query(mysql, query); - myquery(rc); - - strxmov(query, "USE ", current_db, NullS); - rc= mysql_query(mysql, query); - myquery(rc); - have_innodb= check_have_innodb(mysql); - - if (!opt_silent) - fprintf(stdout, "OK\n"); - - return mysql; -} - - -/* Close the connection */ - -static void client_disconnect(MYSQL* mysql, my_bool drop_db) -{ - static char query[MAX_TEST_QUERY_LENGTH]; - - myheader_r("client_disconnect"); - - if (mysql) - { - if (drop_db) - { - if (!opt_silent) - fprintf(stdout, "\n dropping the test database '%s' ...", current_db); - strxmov(query, "DROP DATABASE IF EXISTS ", current_db, NullS); - - mysql_query(mysql, query); - if (!opt_silent) - fprintf(stdout, "OK"); - } - - if (!opt_silent) - fprintf(stdout, "\n closing the connection ..."); - mysql_close(mysql); - if (!opt_silent) - fprintf(stdout, "OK\n"); - } -} +#include "mysql_client_fw.c" /* Query processing */ @@ -474,496 +79,6 @@ static void client_query() } -/* Print dashes */ - -static void my_print_dashes(MYSQL_RES *result) -{ - MYSQL_FIELD *field; - unsigned int i, j; - - mysql_field_seek(result, 0); - fputc('\t', stdout); - fputc('+', stdout); - - for(i= 0; i< mysql_num_fields(result); i++) - { - field= mysql_fetch_field(result); - for(j= 0; j < field->max_length+2; j++) - fputc('-', stdout); - fputc('+', stdout); - } - fputc('\n', stdout); -} - - -/* Print resultset metadata information */ - -static void my_print_result_metadata(MYSQL_RES *result) -{ - MYSQL_FIELD *field; - unsigned int i, j; - unsigned int field_count; - - mysql_field_seek(result, 0); - if (!opt_silent) - { - fputc('\n', stdout); - fputc('\n', stdout); - } - - field_count= mysql_num_fields(result); - for(i= 0; i< field_count; i++) - { - field= mysql_fetch_field(result); - j= strlen(field->name); - if (j < field->max_length) - j= field->max_length; - if (j < 4 && !IS_NOT_NULL(field->flags)) - j= 4; - field->max_length= j; - } - if (!opt_silent) - { - my_print_dashes(result); - fputc('\t', stdout); - fputc('|', stdout); - } - - mysql_field_seek(result, 0); - for(i= 0; i< field_count; i++) - { - field= mysql_fetch_field(result); - if (!opt_silent) - fprintf(stdout, " %-*s |", (int) field->max_length, field->name); - } - if (!opt_silent) - { - fputc('\n', stdout); - my_print_dashes(result); - } -} - - -/* Process the result set */ - -static int my_process_result_set(MYSQL_RES *result) -{ - MYSQL_ROW row; - MYSQL_FIELD *field; - unsigned int i; - unsigned int row_count= 0; - - if (!result) - return 0; - - my_print_result_metadata(result); - - while ((row= mysql_fetch_row(result)) != NULL) - { - mysql_field_seek(result, 0); - if (!opt_silent) - { - fputc('\t', stdout); - fputc('|', stdout); - } - - for(i= 0; i< mysql_num_fields(result); i++) - { - field= mysql_fetch_field(result); - if (!opt_silent) - { - if (row[i] == NULL) - fprintf(stdout, " %-*s |", (int) field->max_length, "NULL"); - else if (IS_NUM(field->type)) - fprintf(stdout, " %*s |", (int) field->max_length, row[i]); - else - fprintf(stdout, " %-*s |", (int) field->max_length, row[i]); - } - } - if (!opt_silent) - { - fputc('\t', stdout); - fputc('\n', stdout); - } - row_count++; - } - if (!opt_silent) - { - if (row_count) - my_print_dashes(result); - - if (mysql_errno(mysql) != 0) - fprintf(stderr, "\n\tmysql_fetch_row() failed\n"); - else - fprintf(stdout, "\n\t%d %s returned\n", row_count, - row_count == 1 ? "row" : "rows"); - } - return row_count; -} - - -static int my_process_result(MYSQL *mysql_arg) -{ - MYSQL_RES *result; - int row_count; - - if (!(result= mysql_store_result(mysql_arg))) - return 0; - - row_count= my_process_result_set(result); - - mysql_free_result(result); - return row_count; -} - - -/* Process the statement result set */ - -#define MAX_RES_FIELDS 50 -#define MAX_FIELD_DATA_SIZE 255 - -static int my_process_stmt_result(MYSQL_STMT *stmt) -{ - int field_count; - int row_count= 0; - MYSQL_BIND buffer[MAX_RES_FIELDS]; - MYSQL_FIELD *field; - MYSQL_RES *result; - char data[MAX_RES_FIELDS][MAX_FIELD_DATA_SIZE]; - ulong length[MAX_RES_FIELDS]; - my_bool is_null[MAX_RES_FIELDS]; - int rc, i; - - if (!(result= mysql_stmt_result_metadata(stmt))) /* No meta info */ - { - while (!mysql_stmt_fetch(stmt)) - row_count++; - return row_count; - } - - field_count= min(mysql_num_fields(result), MAX_RES_FIELDS); - - bzero((char*) buffer, sizeof(buffer)); - bzero((char*) length, sizeof(length)); - bzero((char*) is_null, sizeof(is_null)); - - for(i= 0; i < field_count; i++) - { - buffer[i].buffer_type= MYSQL_TYPE_STRING; - buffer[i].buffer_length= MAX_FIELD_DATA_SIZE; - buffer[i].length= &length[i]; - buffer[i].buffer= (void *) data[i]; - buffer[i].is_null= &is_null[i]; - } - - rc= mysql_stmt_bind_result(stmt, buffer); - check_execute(stmt, rc); - - rc= 1; - mysql_stmt_attr_set(stmt, STMT_ATTR_UPDATE_MAX_LENGTH, (void*)&rc); - rc= mysql_stmt_store_result(stmt); - check_execute(stmt, rc); - my_print_result_metadata(result); - - mysql_field_seek(result, 0); - while ((rc= mysql_stmt_fetch(stmt)) == 0) - { - if (!opt_silent) - { - fputc('\t', stdout); - fputc('|', stdout); - } - mysql_field_seek(result, 0); - for (i= 0; i < field_count; i++) - { - field= mysql_fetch_field(result); - if (!opt_silent) - { - if (is_null[i]) - fprintf(stdout, " %-*s |", (int) field->max_length, "NULL"); - else if (length[i] == 0) - { - data[i][0]= '\0'; /* unmodified buffer */ - fprintf(stdout, " %*s |", (int) field->max_length, data[i]); - } - else if (IS_NUM(field->type)) - fprintf(stdout, " %*s |", (int) field->max_length, data[i]); - else - fprintf(stdout, " %-*s |", (int) field->max_length, data[i]); - } - } - if (!opt_silent) - { - fputc('\t', stdout); - fputc('\n', stdout); - } - row_count++; - } - DIE_UNLESS(rc == MYSQL_NO_DATA); - if (!opt_silent) - { - if (row_count) - my_print_dashes(result); - fprintf(stdout, "\n\t%d %s returned\n", row_count, - row_count == 1 ? "row" : "rows"); - } - mysql_free_result(result); - return row_count; -} - - -/* Prepare statement, execute, and process result set for given query */ - -int my_stmt_result(const char *buff) -{ - MYSQL_STMT *stmt; - int row_count; - int rc; - - if (!opt_silent) - fprintf(stdout, "\n\n %s", buff); - stmt= mysql_simple_prepare(mysql, buff); - check_stmt(stmt); - - rc= mysql_stmt_execute(stmt); - check_execute(stmt, rc); - - row_count= my_process_stmt_result(stmt); - mysql_stmt_close(stmt); - - return row_count; -} - -/* Print the total number of warnings and the warnings themselves. */ - -void my_process_warnings(MYSQL *conn, unsigned expected_warning_count) -{ - MYSQL_RES *result; - int rc; - - if (!opt_silent) - fprintf(stdout, "\n total warnings: %u (expected: %u)\n", - mysql_warning_count(conn), expected_warning_count); - - DIE_UNLESS(mysql_warning_count(mysql) == expected_warning_count); - - rc= mysql_query(conn, "SHOW WARNINGS"); - DIE_UNLESS(rc == 0); - - result= mysql_store_result(conn); - mytest(result); - - rc= my_process_result_set(result); - mysql_free_result(result); -} - - -/* Utility function to verify a particular column data */ - -static void verify_col_data(const char *table, const char *col, - const char *exp_data) -{ - static char query[MAX_TEST_QUERY_LENGTH]; - MYSQL_RES *result; - MYSQL_ROW row; - int rc, field= 1; - - if (table && col) - { - strxmov(query, "SELECT ", col, " FROM ", table, " LIMIT 1", NullS); - if (!opt_silent) - fprintf(stdout, "\n %s", query); - rc= mysql_query(mysql, query); - myquery(rc); - - field= 0; - } - - result= mysql_use_result(mysql); - mytest(result); - - if (!(row= mysql_fetch_row(result)) || !row[field]) - { - fprintf(stdout, "\n *** ERROR: FAILED TO GET THE RESULT ***"); - exit(1); - } - if (strcmp(row[field], exp_data)) - { - fprintf(stdout, "\n obtained: `%s` (expected: `%s`)", - row[field], exp_data); - DIE_UNLESS(FALSE); - } - mysql_free_result(result); -} - - -/* Utility function to verify the field members */ - -#define verify_prepare_field(result,no,name,org_name,type,table,\ - org_table,db,length,def) \ - do_verify_prepare_field((result),(no),(name),(org_name),(type), \ - (table),(org_table),(db),(length),(def), \ - __FILE__, __LINE__) - -static void do_verify_prepare_field(MYSQL_RES *result, - unsigned int no, const char *name, - const char *org_name, - enum enum_field_types type, - const char *table, - const char *org_table, const char *db, - unsigned long length, const char *def, - const char *file, int line) -{ - MYSQL_FIELD *field; - CHARSET_INFO *cs; - ulonglong expected_field_length; - - if (!(field= mysql_fetch_field_direct(result, no))) - { - fprintf(stdout, "\n *** ERROR: FAILED TO GET THE RESULT ***"); - exit(1); - } - cs= get_charset(field->charsetnr, 0); - DIE_UNLESS(cs); - if ((expected_field_length= length * cs->mbmaxlen) > UINT_MAX32) - expected_field_length= UINT_MAX32; - if (!opt_silent) - { - fprintf(stdout, "\n field[%d]:", no); - fprintf(stdout, "\n name :`%s`\t(expected: `%s`)", field->name, name); - fprintf(stdout, "\n org_name :`%s`\t(expected: `%s`)", - field->org_name, org_name); - fprintf(stdout, "\n type :`%d`\t(expected: `%d`)", field->type, type); - if (table) - fprintf(stdout, "\n table :`%s`\t(expected: `%s`)", - field->table, table); - if (org_table) - fprintf(stdout, "\n org_table:`%s`\t(expected: `%s`)", - field->org_table, org_table); - fprintf(stdout, "\n database :`%s`\t(expected: `%s`)", field->db, db); - fprintf(stdout, "\n length :`%lu`\t(expected: `%llu`)", - field->length, expected_field_length); - fprintf(stdout, "\n maxlength:`%ld`", field->max_length); - fprintf(stdout, "\n charsetnr:`%d`", field->charsetnr); - fprintf(stdout, "\n default :`%s`\t(expected: `%s`)", - field->def ? field->def : "(null)", def ? def: "(null)"); - fprintf(stdout, "\n"); - } - DIE_UNLESS(strcmp(field->name, name) == 0); - DIE_UNLESS(strcmp(field->org_name, org_name) == 0); - /* - XXX: silent column specification change works based on number of - bytes a column occupies. So CHAR -> VARCHAR upgrade is possible even - for CHAR(2) column if its character set is multibyte. - VARCHAR -> CHAR downgrade won't work for VARCHAR(3) as one would - expect. - */ - if (cs->mbmaxlen == 1) - { - if (field->type != type) - { - fprintf(stderr, - "Expected field type: %d, got type: %d in file %s, line %d\n", - (int) type, (int) field->type, file, line); - DIE_UNLESS(field->type == type); - } - } - if (table) - DIE_UNLESS(strcmp(field->table, table) == 0); - if (org_table) - DIE_UNLESS(strcmp(field->org_table, org_table) == 0); - DIE_UNLESS(strcmp(field->db, db) == 0); - /* - Character set should be taken into account for multibyte encodings, such - as utf8. Field length is calculated as number of characters * maximum - number of bytes a character can occupy. - */ - if (length && (field->length != expected_field_length)) - { - fflush(stdout); - fprintf(stderr, "Expected field length: %llu, got length: %lu\n", - expected_field_length, field->length); - fflush(stderr); - DIE_UNLESS(field->length == expected_field_length); - } - if (def) - DIE_UNLESS(strcmp(field->def, def) == 0); -} - - -/* Utility function to verify the parameter count */ - -static void verify_param_count(MYSQL_STMT *stmt, long exp_count) -{ - long param_count= mysql_stmt_param_count(stmt); - if (!opt_silent) - fprintf(stdout, "\n total parameters in stmt: `%ld` (expected: `%ld`)", - param_count, exp_count); - DIE_UNLESS(param_count == exp_count); -} - - -/* Utility function to verify the total affected rows */ - -static void verify_st_affected_rows(MYSQL_STMT *stmt, ulonglong exp_count) -{ - ulonglong affected_rows= mysql_stmt_affected_rows(stmt); - if (!opt_silent) - fprintf(stdout, "\n total affected rows: `%ld` (expected: `%ld`)", - (long) affected_rows, (long) exp_count); - DIE_UNLESS(affected_rows == exp_count); -} - - -/* Utility function to verify the total affected rows */ - -static void verify_affected_rows(ulonglong exp_count) -{ - ulonglong affected_rows= mysql_affected_rows(mysql); - if (!opt_silent) - fprintf(stdout, "\n total affected rows: `%ld` (expected: `%ld`)", - (long) affected_rows, (long) exp_count); - DIE_UNLESS(affected_rows == exp_count); -} - - -/* Utility function to verify the total fields count */ - -static void verify_field_count(MYSQL_RES *result, uint exp_count) -{ - uint field_count= mysql_num_fields(result); - if (!opt_silent) - fprintf(stdout, "\n total fields in the result set: `%d` (expected: `%d`)", - field_count, exp_count); - DIE_UNLESS(field_count == exp_count); -} - - -/* Utility function to execute a query using prepare-execute */ - -#ifndef EMBEDDED_LIBRARY -static void execute_prepare_query(const char *query, ulonglong exp_count) -{ - MYSQL_STMT *stmt; - ulonglong affected_rows; - int rc; - - stmt= mysql_simple_prepare(mysql, query); - check_stmt(stmt); - - rc= mysql_stmt_execute(stmt); - myquery(rc); - - affected_rows= mysql_stmt_affected_rows(stmt); - if (!opt_silent) - fprintf(stdout, "\n total affected rows: `%ld` (expected: `%ld`)", - (long) affected_rows, (long) exp_count); - - DIE_UNLESS(affected_rows == exp_count); - mysql_stmt_close(stmt); -} -#endif - /* Store result processing */ static void client_store_result() @@ -1005,267 +120,6 @@ static void client_use_result() } -/* - Accepts arbitrary number of queries and runs them against the database. - Used to fill tables for each test. -*/ - -void fill_tables(const char **query_list, unsigned query_count) -{ - int rc; - const char **query; - DBUG_ENTER("fill_tables"); - for (query= query_list; query < query_list + query_count; - ++query) - { - rc= mysql_query(mysql, *query); - myquery(rc); - } - DBUG_VOID_RETURN; -} - -/* - All state of fetch from one statement: statement handle, out buffers, - fetch position. - See fetch_n for for the only use case. -*/ - -enum { MAX_COLUMN_LENGTH= 255 }; - -typedef struct st_stmt_fetch -{ - const char *query; - unsigned stmt_no; - MYSQL_STMT *handle; - my_bool is_open; - MYSQL_BIND *bind_array; - char **out_data; - unsigned long *out_data_length; - unsigned column_count; - unsigned row_count; -} Stmt_fetch; - - -/* - Create statement handle, prepare it with statement, execute and allocate - fetch buffers. -*/ - -void stmt_fetch_init(Stmt_fetch *fetch, unsigned stmt_no_arg, - const char *query_arg) -{ - unsigned long type= CURSOR_TYPE_READ_ONLY; - int rc; - unsigned i; - MYSQL_RES *metadata; - DBUG_ENTER("stmt_fetch_init"); - - /* Save query and statement number for error messages */ - fetch->stmt_no= stmt_no_arg; - fetch->query= query_arg; - - fetch->handle= mysql_stmt_init(mysql); - - rc= mysql_stmt_prepare(fetch->handle, fetch->query, strlen(fetch->query)); - check_execute(fetch->handle, rc); - - /* - The attribute is sent to server on execute and asks to open read-only - for result set - */ - mysql_stmt_attr_set(fetch->handle, STMT_ATTR_CURSOR_TYPE, - (const void*) &type); - - rc= mysql_stmt_execute(fetch->handle); - check_execute(fetch->handle, rc); - - /* Find out total number of columns in result set */ - metadata= mysql_stmt_result_metadata(fetch->handle); - fetch->column_count= mysql_num_fields(metadata); - mysql_free_result(metadata); - - /* - Now allocate bind handles and buffers for output data: - calloc memory to reduce number of MYSQL_BIND members we need to - set up. - */ - - fetch->bind_array= (MYSQL_BIND *) calloc(1, sizeof(MYSQL_BIND) * - fetch->column_count); - fetch->out_data= (char**) calloc(1, sizeof(char*) * fetch->column_count); - fetch->out_data_length= (ulong*) calloc(1, sizeof(ulong) * - fetch->column_count); - for (i= 0; i < fetch->column_count; ++i) - { - fetch->out_data[i]= (char*) calloc(1, MAX_COLUMN_LENGTH); - fetch->bind_array[i].buffer_type= MYSQL_TYPE_STRING; - fetch->bind_array[i].buffer= fetch->out_data[i]; - fetch->bind_array[i].buffer_length= MAX_COLUMN_LENGTH; - fetch->bind_array[i].length= fetch->out_data_length + i; - } - - mysql_stmt_bind_result(fetch->handle, fetch->bind_array); - - fetch->row_count= 0; - fetch->is_open= TRUE; - - /* Ready for reading rows */ - DBUG_VOID_RETURN; -} - - -/* Fetch and print one row from cursor */ - -int stmt_fetch_fetch_row(Stmt_fetch *fetch) -{ - int rc; - unsigned i; - DBUG_ENTER("stmt_fetch_fetch_row"); - - if ((rc= mysql_stmt_fetch(fetch->handle)) == 0) - { - ++fetch->row_count; - if (!opt_silent) - printf("Stmt %d fetched row %d:\n", fetch->stmt_no, fetch->row_count); - for (i= 0; i < fetch->column_count; ++i) - { - fetch->out_data[i][fetch->out_data_length[i]]= '\0'; - if (!opt_silent) - printf("column %d: %s\n", i+1, fetch->out_data[i]); - } - } - else - fetch->is_open= FALSE; - DBUG_RETURN(rc); -} - - -void stmt_fetch_close(Stmt_fetch *fetch) -{ - unsigned i; - DBUG_ENTER("stmt_fetch_close"); - - for (i= 0; i < fetch->column_count; ++i) - free(fetch->out_data[i]); - free(fetch->out_data); - free(fetch->out_data_length); - free(fetch->bind_array); - mysql_stmt_close(fetch->handle); - DBUG_VOID_RETURN; -} - -/* - For given array of queries, open query_count cursors and fetch - from them in simultaneous manner. - In case there was an error in one of the cursors, continue - reading from the rest. -*/ - -enum fetch_type { USE_ROW_BY_ROW_FETCH= 0, USE_STORE_RESULT= 1 }; - -my_bool fetch_n(const char **query_list, unsigned query_count, - enum fetch_type fetch_type) -{ - unsigned open_statements= query_count; - int rc, error_count= 0; - Stmt_fetch *fetch_array= (Stmt_fetch*) calloc(1, sizeof(Stmt_fetch) * - query_count); - Stmt_fetch *fetch; - DBUG_ENTER("fetch_n"); - - for (fetch= fetch_array; fetch < fetch_array + query_count; ++fetch) - { - /* Init will exit(1) in case of error */ - stmt_fetch_init(fetch, fetch - fetch_array, - query_list[fetch - fetch_array]); - } - - if (fetch_type == USE_STORE_RESULT) - { - for (fetch= fetch_array; fetch < fetch_array + query_count; ++fetch) - { - rc= mysql_stmt_store_result(fetch->handle); - check_execute(fetch->handle, rc); - } - } - - while (open_statements) - { - for (fetch= fetch_array; fetch < fetch_array + query_count; ++fetch) - { - if (fetch->is_open && (rc= stmt_fetch_fetch_row(fetch))) - { - open_statements--; - /* - We try to fetch from the rest of the statements in case of - error - */ - if (rc != MYSQL_NO_DATA) - { - fprintf(stderr, - "Got error reading rows from statement %d,\n" - "query is: %s,\n" - "error message: %s", (int) (fetch - fetch_array), - fetch->query, - mysql_stmt_error(fetch->handle)); - error_count++; - } - } - } - } - if (error_count) - fprintf(stderr, "Fetch FAILED"); - else - { - unsigned total_row_count= 0; - for (fetch= fetch_array; fetch < fetch_array + query_count; ++fetch) - total_row_count+= fetch->row_count; - if (!opt_silent) - printf("Success, total rows fetched: %d\n", total_row_count); - } - for (fetch= fetch_array; fetch < fetch_array + query_count; ++fetch) - stmt_fetch_close(fetch); - free(fetch_array); - DBUG_RETURN(error_count != 0); -} - -/* Separate thread query to test some cases */ - -static my_bool thread_query(const char *query) -{ - MYSQL *l_mysql; - my_bool error; - - error= 0; - if (!opt_silent) - fprintf(stdout, "\n in thread_query(%s)", query); - if (!(l_mysql= mysql_client_init(NULL))) - { - myerror("mysql_client_init() failed"); - return 1; - } - if (!(mysql_real_connect(l_mysql, opt_host, opt_user, - opt_password, current_db, opt_port, - opt_unix_socket, 0))) - { - myerror("connection failed"); - error= 1; - goto end; - } - l_mysql->reconnect= 1; - if (mysql_query(l_mysql, query)) - { - fprintf(stderr, "Query failed (%s)\n", mysql_error(l_mysql)); - error= 1; - goto end; - } - mysql_commit(l_mysql); -end: - mysql_close(l_mysql); - return error; -} - - /* Query processing */ static void test_debug_example() @@ -19896,96 +18750,6 @@ static void test_bug13001491() } -/* - Read and parse arguments and MySQL options from my.cnf -*/ - -static const char *client_test_load_default_groups[]= -{ "client", "client-server", "client-mariadb", 0 }; -static char **defaults_argv; - -static struct my_option client_test_long_options[] = -{ - {"basedir", 'b', "Basedir for tests.", (char**) &opt_basedir, - (char**) &opt_basedir, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0}, - {"count", 't', "Number of times test to be executed", &opt_count, - &opt_count, 0, GET_UINT, REQUIRED_ARG, 1, 0, 0, 0, 0, 0}, - {"database", 'D', "Database to use", &opt_db, &opt_db, - 0, GET_STR_ALLOC, REQUIRED_ARG, 0, 0, 0, 0, 0, 0}, - {"debug", '#', "Output debug log", (char**) &default_dbug_option, - (char**) &default_dbug_option, 0, GET_STR, OPT_ARG, 0, 0, 0, 0, 0, 0}, - {"help", '?', "Display this help and exit", 0, 0, 0, GET_NO_ARG, NO_ARG, 0, - 0, 0, 0, 0, 0}, - {"host", 'h', "Connect to host", &opt_host, &opt_host, - 0, GET_STR_ALLOC, REQUIRED_ARG, 0, 0, 0, 0, 0, 0}, - {"password", 'p', - "Password to use when connecting to server. If password is not given it's asked from the tty.", - 0, 0, 0, GET_STR, OPT_ARG, 0, 0, 0, 0, 0, 0}, - {"port", 'P', "Port number to use for connection or 0 for default to, in " - "order of preference, my.cnf, $MYSQL_TCP_PORT, " -#if MYSQL_PORT_DEFAULT == 0 - "/etc/services, " -#endif - "built-in default (" STRINGIFY_ARG(MYSQL_PORT) ").", - &opt_port, &opt_port, 0, GET_UINT, REQUIRED_ARG, 0, 0, 0, 0, 0, 0}, - {"server-arg", 'A', "Send embedded server this as a parameter.", - 0, 0, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0}, - {"show-tests", 'T', "Show all tests' names", 0, 0, 0, GET_NO_ARG, NO_ARG, - 0, 0, 0, 0, 0, 0}, - {"silent", 's', "Be more silent", 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, - 0}, -#ifdef HAVE_SMEM - {"shared-memory-base-name", 'm', "Base name of shared memory.", - &shared_memory_base_name, (uchar**)&shared_memory_base_name, 0, - GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0}, -#endif - {"socket", 'S', "Socket file to use for connection", - &opt_unix_socket, &opt_unix_socket, 0, GET_STR, - REQUIRED_ARG, 0, 0, 0, 0, 0, 0}, - {"testcase", 'c', - "May disable some code when runs as mysql-test-run testcase.", - 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0}, -#ifndef DONT_ALLOW_USER_CHANGE - {"user", 'u', "User for login if not current user", &opt_user, - &opt_user, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0}, -#endif - {"vardir", 'v', "Data dir for tests.", (char**) &opt_vardir, - (char**) &opt_vardir, 0, GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0}, - {"non-blocking-api", 'n', - "Use the non-blocking client API for communication.", - &non_blocking_api_enabled, &non_blocking_api_enabled, 0, - GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0}, - {"getopt-ll-test", 'g', "Option for testing bug in getopt library", - &opt_getopt_ll_test, &opt_getopt_ll_test, 0, - GET_LL, REQUIRED_ARG, 0, 0, LONGLONG_MAX, 0, 0, 0}, - {"plugin_dir", 0, "Directory for client-side plugins.", - &opt_plugin_dir, &opt_plugin_dir, 0, - GET_STR, REQUIRED_ARG, 0, 0, 0, 0, 0, 0}, - {"default_auth", 0, "Default authentication client-side plugin to use.", - &opt_default_auth, &opt_default_auth, 0, - GET_STR, 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} -}; - - -static void usage(void) -{ - /* show the usage string when the user asks for this */ - putc('\n', stdout); - printf("%s Ver %s Distrib %s, for %s (%s)\n", - my_progname, VER, MYSQL_SERVER_VERSION, SYSTEM_TYPE, MACHINE_TYPE); - puts("By Monty, Venu, Kent and others\n"); - printf("\ -Copyright (C) 2002-2004 MySQL AB\n\ -This software comes with ABSOLUTELY NO WARRANTY. This is free software,\n\ -and you are welcome to modify and redistribute it under the GPL license\n"); - printf("Usage: %s [OPTIONS] [TESTNAME1 TESTNAME2...]\n", my_progname); - my_print_help(client_test_long_options); - print_defaults("my", client_test_load_default_groups); - my_print_variables(client_test_long_options); -} - - static struct my_tests_st my_tests[]= { { "disable_query_logs", disable_query_logs }, { "test_view_sp_list_fields", test_view_sp_list_fields }, @@ -20251,185 +19015,4 @@ static struct my_tests_st my_tests[]= { }; -static my_bool -get_one_option(int optid, const struct my_option *opt __attribute__((unused)), - char *argument) -{ - switch (optid) { - case '#': - DBUG_PUSH(argument ? argument : default_dbug_option); - break; - case 'c': -#ifdef NOT_USED - opt_testcase = 1; -#endif - break; - case 'p': - if (argument) - { - char *start=argument; - my_free(opt_password); - opt_password= my_strdup(argument, MYF(MY_FAE)); - while (*argument) *argument++= 'x'; /* Destroy argument */ - if (*start) - start[1]=0; - } - else - tty_password= 1; - break; - case 's': - if (argument == disabled_my_option) - opt_silent= 0; - else - opt_silent++; - break; - case 'A': - /* - When the embedded server is being tested, the test suite needs to be - able to pass command-line arguments to the embedded server so it can - locate the language files and data directory. The test suite - (mysql-test-run) never uses config files, just command-line options. - */ - if (!embedded_server_arg_count) - { - embedded_server_arg_count= 1; - embedded_server_args[0]= (char*) ""; - } - if (embedded_server_arg_count == MAX_SERVER_ARGS-1 || - !(embedded_server_args[embedded_server_arg_count++]= - my_strdup(argument, MYF(MY_FAE)))) - { - DIE("Can't use server argument"); - } - break; - case 'T': - { - struct my_tests_st *fptr; - - printf("All possible test names:\n\n"); - for (fptr= my_tests; fptr->name; fptr++) - printf("%s\n", fptr->name); - exit(0); - break; - } - case '?': - case 'I': /* Info */ - usage(); - exit(0); - break; - } - return 0; -} - -static void get_options(int *argc, char ***argv) -{ - int ho_error; - - if ((ho_error= handle_options(argc, argv, client_test_long_options, - get_one_option))) - exit(ho_error); - - if (tty_password) - opt_password= get_tty_password(NullS); - return; -} - -/* - Print the test output on successful execution before exiting -*/ - -static void print_test_output() -{ - if (opt_silent < 3) - { - fprintf(stdout, "\n\n"); - fprintf(stdout, "All '%d' tests were successful (in '%d' iterations)", - test_count-1, opt_count); - fprintf(stdout, "\n Total execution time: %g SECS", total_time); - if (opt_count > 1) - fprintf(stdout, " (Avg: %g SECS)", total_time/opt_count); - - fprintf(stdout, "\n\n!!! SUCCESS !!!\n"); - } -} - -/*************************************************************************** - main routine -***************************************************************************/ - - -int main(int argc, char **argv) -{ - struct my_tests_st *fptr; - - MY_INIT(argv[0]); - - if (load_defaults("my", client_test_load_default_groups, &argc, &argv)) - exit(1); - - defaults_argv= argv; - get_options(&argc, &argv); - - if (mysql_server_init(embedded_server_arg_count, - embedded_server_args, - (char**) embedded_server_groups)) - DIE("Can't initialize MySQL server"); - - /* connect to server with no flags, default protocol, auto reconnect true */ - mysql= client_connect(0, MYSQL_PROTOCOL_DEFAULT, 1); - - total_time= 0; - for (iter_count= 1; iter_count <= opt_count; iter_count++) - { - /* Start of tests */ - test_count= 1; - start_time= time((time_t *)0); - if (!argc) - { - for (fptr= my_tests; fptr->name; fptr++) - (*fptr->function)(); - } - else - { - for ( ; *argv ; argv++) - { - for (fptr= my_tests; fptr->name; fptr++) - { - if (!strcmp(fptr->name, *argv)) - { - (*fptr->function)(); - break; - } - } - if (!fptr->name) - { - fprintf(stderr, "\n\nGiven test not found: '%s'\n", *argv); - fprintf(stderr, "See legal test names with %s -T\n\nAborting!\n", - my_progname); - client_disconnect(mysql, 1); - free_defaults(defaults_argv); - exit(1); - } - } - } - - end_time= time((time_t *)0); - total_time+= difftime(end_time, start_time); - - /* End of tests */ - } - - client_disconnect(mysql, 1); /* disconnect from server */ - - free_defaults(defaults_argv); - print_test_output(); - - while (embedded_server_arg_count > 1) - my_free(embedded_server_args[--embedded_server_arg_count]); - - mysql_server_end(); - - my_end(0); - - exit(0); -} +static struct my_tests_st *get_my_tests() { return my_tests; } diff --git a/vio/viosslfactories.c b/vio/viosslfactories.c index f64869e905d..a1c2010912b 100644 --- a/vio/viosslfactories.c +++ b/vio/viosslfactories.c @@ -164,8 +164,8 @@ static void check_ssl_init() 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) + const char *cipher, my_bool is_client_method, + enum enum_ssl_init_error* error) { DH *dh; struct st_VioSSLFd *ssl_fd; @@ -185,7 +185,9 @@ new_VioSSLFd(const char *key_file, const char *cert_file, my_malloc(sizeof(struct st_VioSSLFd),MYF(0))))) DBUG_RETURN(0); - if (!(ssl_fd->ssl_context= SSL_CTX_new(method))) + if (!(ssl_fd->ssl_context= SSL_CTX_new(is_client_method ? + TLSv1_client_method() : + TLSv1_server_method()))) { *error= SSL_INITERR_MEMFAIL; DBUG_PRINT("error", ("%s", sslGetErrString(*error))); @@ -262,7 +264,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(), error))) + ca_path, cipher, TRUE, error))) { return 0; } @@ -284,8 +286,7 @@ new_VioSSLAcceptorFd(const char *key_file, const char *cert_file, struct st_VioSSLFd *ssl_fd; int verify= SSL_VERIFY_PEER | SSL_VERIFY_CLIENT_ONCE; if (!(ssl_fd= new_VioSSLFd(key_file, cert_file, ca_file, - ca_path, cipher, - (SSL_METHOD*) TLSv1_server_method(), error))) + ca_path, cipher, FALSE, error))) { return 0; } |