diff options
125 files changed, 3353 insertions, 754 deletions
diff --git a/.bzrignore b/.bzrignore index 90e966390d2..1cf0cf7b889 100644 --- a/.bzrignore +++ b/.bzrignore @@ -943,6 +943,7 @@ ndb/src/common/mgmcommon/printConfig/*.d ndb/src/common/portlib/libportlib.dsp ndb/src/common/transporter/libtransporter.dsp ndb/src/common/util/libgeneral.dsp +ndb/src/common/util/testBitmask.cpp ndb/src/cw/cpcd/ndb_cpcd ndb/src/dummy.cpp ndb/src/kernel/blocks/backup/libbackup.dsp diff --git a/client/Makefile.am b/client/Makefile.am index ff97243815a..d3e96dd126f 100644 --- a/client/Makefile.am +++ b/client/Makefile.am @@ -62,13 +62,13 @@ mysqlimport_LDADD = $(CXXLDFLAGS) $(CLIENT_THREAD_LIBS) \ @CLIENT_EXTRA_LDFLAGS@ \ $(LIBMYSQLCLIENT_LA) \ $(top_builddir)/mysys/libmysys.a -mysqlcheck_SOURCES= mysqlcheck.c $(yassl_dummy_link_fix) +mysqlcheck_SOURCES= mysqlcheck.c $(yassl_dummy_link_fix) mysqlshow_SOURCES= mysqlshow.c $(yassl_dummy_link_fix) -mysqlslap_SOURCES= mysqlslap.c \ - $(yassl_dummy_link_fix) -mysqldump_SOURCES= mysqldump.c my_user.c $(yassl_dummy_link_fix) -mysqlimport_SOURCES= mysqlimport.c \ - $(yassl_dummy_link_fix) +mysqlslap_SOURCES= mysqlslap.c $(yassl_dummy_link_fix) +mysqldump_SOURCES= mysqldump.c my_user.c \ + $(top_srcdir)/mysys/mf_getdate.c \ + $(yassl_dummy_link_fix) +mysqlimport_SOURCES= mysqlimport.c $(yassl_dummy_link_fix) mysql_upgrade_SOURCES= mysql_upgrade.c $(yassl_dummy_link_fix) sql_src=log_event.h mysql_priv.h log_event.cc my_decimal.h my_decimal.cc strings_src=decimal.c diff --git a/client/mysql.cc b/client/mysql.cc index a77901e5220..6b188271174 100644 --- a/client/mysql.cc +++ b/client/mysql.cc @@ -2884,7 +2884,7 @@ com_connect(String *buffer, char *line) bzero(buff, sizeof(buff)); if (buffer) { - strmov(buff, line); + strmake(buff, line, sizeof(buff)); tmp= get_arg(buff, 0); if (tmp && *tmp) { @@ -3738,6 +3738,9 @@ static const char* construct_prompt() case 't': processed_prompt.append('\t'); break; + case 'l': + processed_prompt.append(delimiter_str); + break; default: processed_prompt.append(c); } diff --git a/client/mysqlbinlog.cc b/client/mysqlbinlog.cc index 81ad74466eb..83385e9d005 100644 --- a/client/mysqlbinlog.cc +++ b/client/mysqlbinlog.cc @@ -36,6 +36,7 @@ /* That one is necessary for defines of OPTION_NO_FOREIGN_KEY_CHECKS etc */ #include "mysql_priv.h" #include "log_event.h" +#include "sql_common.h" #define BIN_LOG_HEADER_SIZE 4 #define PROBE_HEADER_LEN (EVENT_LEN_OFFSET+4) @@ -1104,7 +1105,7 @@ could be out of memory"); const char *error_msg; Log_event *ev; - len = net_safe_read(mysql); + len= cli_safe_read(mysql); if (len == packet_error) { fprintf(stderr, "Got error reading packet from server: %s\n", diff --git a/client/mysqlcheck.c b/client/mysqlcheck.c index db7ae062203..fdfd9fc36fb 100644 --- a/client/mysqlcheck.c +++ b/client/mysqlcheck.c @@ -475,7 +475,7 @@ static int process_all_tables_in_db(char *database) LINT_INIT(res); if (use_db(database)) return 1; - if (mysql_query(sock, "SHOW TABLES") || + if (mysql_query(sock, "SHOW TABLE STATUS") || !((res= mysql_store_result(sock)))) return 1; @@ -501,8 +501,12 @@ static int process_all_tables_in_db(char *database) } for (end = tables + 1; (row = mysql_fetch_row(res)) ;) { - end= fix_table_name(end, row[0]); - *end++= ','; + /* Skip tables with an engine of NULL (probably a view). */ + if (row[1]) + { + end= fix_table_name(end, row[0]); + *end++= ','; + } } *--end = 0; if (tot_length) @@ -512,7 +516,11 @@ static int process_all_tables_in_db(char *database) else { while ((row = mysql_fetch_row(res))) - handle_request_for_tables(row[0], strlen(row[0])); + /* Skip tables with an engine of NULL (probably a view). */ + if (row[1]) + { + handle_request_for_tables(row[0], strlen(row[0])); + } } mysql_free_result(res); return 0; diff --git a/client/mysqldump.c b/client/mysqldump.c index 64633702df6..dc7527c9c73 100644 --- a/client/mysqldump.c +++ b/client/mysqldump.c @@ -84,7 +84,8 @@ static ulong find_set(TYPELIB *lib, const char *x, uint length, static char *alloc_query_str(ulong size); static char *field_escape(char *to,const char *from,uint length); -static my_bool verbose=0,tFlag=0,dFlag=0,quick= 1, extended_insert= 1, +static my_bool verbose= 0, opt_no_create_info= 0, opt_no_data= 0, + quick= 1, extended_insert= 1, lock_tables=1,ignore_errors=0,flush_logs=0, opt_drop=1,opt_keywords=0,opt_lock=1,opt_compress=0, opt_delayed=0,create_options=1,opt_quoted=0,opt_databases=0, @@ -100,7 +101,7 @@ static my_bool verbose=0,tFlag=0,dFlag=0,quick= 1, extended_insert= 1, opt_events= 0, opt_alltspcs=0; static ulong opt_max_allowed_packet, opt_net_buffer_length; -static MYSQL mysql_connection,*sock=0; +static MYSQL mysql_connection,*mysql=0; static my_bool insert_pat_inited=0; static DYNAMIC_STRING insert_pat; static char *opt_password=0,*current_user=0, @@ -322,9 +323,10 @@ static struct my_option my_long_options[] = (gptr*) &opt_create_db, (gptr*) &opt_create_db, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0}, {"no-create-info", 't', "Don't write table creation info.", - (gptr*) &tFlag, (gptr*) &tFlag, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0}, - {"no-data", 'd', "No row information.", (gptr*) &dFlag, (gptr*) &dFlag, 0, - GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0}, + (gptr*) &opt_no_create_info, (gptr*) &opt_no_create_info, 0, GET_BOOL, + NO_ARG, 0, 0, 0, 0, 0, 0}, + {"no-data", 'd', "No row information.", (gptr*) &opt_no_data, + (gptr*) &opt_no_data, 0, GET_BOOL, NO_ARG, 0, 0, 0, 0, 0, 0}, {"no-set-names", 'N', "Deprecated. Use --skip-set-charset instead.", 0, 0, 0, GET_NO_ARG, NO_ARG, 0, 0, 0, 0, 0, 0}, @@ -440,6 +442,30 @@ static my_bool dump_all_views_in_db(char *database); #include <help_start.h> /* + Print the supplied message if in verbose mode + + SYNOPSIS + verbose_msg() + fmt format specifier + ... variable number of parameters +*/ + +static void verbose_msg(const char *fmt, ...) +{ + va_list args; + DBUG_ENTER("verbose_msg"); + + if (!verbose) + DBUG_VOID_RETURN; + + va_start(args, fmt); + vfprintf(stderr, fmt, args); + va_end(args); + + DBUG_VOID_RETURN; +} + +/* exit with message if ferror(file) SYNOPSIS @@ -578,6 +604,13 @@ static void write_footer(FILE *sql_file) fprintf(sql_file, "/*!40111 SET SQL_NOTES=@OLD_SQL_NOTES */;\n"); fputs("\n", sql_file); + if (opt_comments) + { + char time_str[20]; + get_date(time_str, GETDATE_DATE_TIME, 0); + fprintf(sql_file, "-- Dump completed on %s\n", + time_str); + } check_io(sql_file); } } /* write_footer */ @@ -857,9 +890,9 @@ static int mysql_query_with_error_report(MYSQL *mysql_con, MYSQL_RES **res, if (mysql_query(mysql_con, query) || (res && !((*res)= mysql_store_result(mysql_con)))) { - my_printf_error(0, "%s: Couldn't execute '%s': %s (%d)", - MYF(0), my_progname, query, - mysql_error(mysql_con), mysql_errno(mysql_con)); + my_printf_error(0, "Couldn't execute '%s': %s (%d)", MYF(0), + query, mysql_error(mysql_con), mysql_errno(mysql_con)); + safe_exit(EX_MYSQLERR); return 1; } return 0; @@ -893,8 +926,8 @@ static void safe_exit(int error) first_error= error; if (ignore_errors) return; - if (sock) - mysql_close(sock); + if (mysql) + mysql_close(mysql); exit(error); } /* safe_exit */ @@ -907,10 +940,8 @@ static int dbConnect(char *host, char *user,char *passwd) { char buff[20+FN_REFLEN]; DBUG_ENTER("dbConnect"); - if (verbose) - { - fprintf(stderr, "-- Connecting to %s...\n", host ? host : "localhost"); - } + + verbose_msg("-- Connecting to %s...\n", host ? host : "localhost"); mysql_init(&mysql_connection); if (opt_compress) mysql_options(&mysql_connection,MYSQL_OPT_COMPRESS,NullS); @@ -928,7 +959,7 @@ static int dbConnect(char *host, char *user,char *passwd) mysql_options(&mysql_connection,MYSQL_SHARED_MEMORY_BASE_NAME,shared_memory_base_name); #endif mysql_options(&mysql_connection, MYSQL_SET_CHARSET_NAME, default_charset); - if (!(sock= mysql_real_connect(&mysql_connection,host,user,passwd, + if (!(mysql= mysql_real_connect(&mysql_connection,host,user,passwd, NULL,opt_mysql_port,opt_mysql_unix_port, 0))) { @@ -944,12 +975,11 @@ static int dbConnect(char *host, char *user,char *passwd) As we're going to set SQL_MODE, it would be lost on reconnect, so we cannot reconnect. */ - sock->reconnect= 0; + mysql->reconnect= 0; my_snprintf(buff, sizeof(buff), "/*!40100 SET @@SQL_MODE='%s' */", compatible_mode_normal_str); - if (mysql_query_with_error_report(sock, 0, buff)) + if (mysql_query_with_error_report(mysql, 0, buff)) { - mysql_close(sock); safe_exit(EX_MYSQLERR); return 1; } @@ -960,9 +990,8 @@ static int dbConnect(char *host, char *user,char *passwd) if (opt_tz_utc) { my_snprintf(buff, sizeof(buff), "/*!40103 SET TIME_ZONE='+00:00' */"); - if (mysql_query_with_error_report(sock, 0, buff)) + if (mysql_query_with_error_report(mysql, 0, buff)) { - mysql_close(sock); safe_exit(EX_MYSQLERR); return 1; } @@ -976,9 +1005,8 @@ static int dbConnect(char *host, char *user,char *passwd) */ static void dbDisconnect(char *host) { - if (verbose) - fprintf(stderr, "-- Disconnecting from %s...\n", host ? host : "localhost"); - mysql_close(sock); + verbose_msg("-- Disconnecting from %s...\n", host ? host : "localhost"); + mysql_close(mysql); } /* dbDisconnect */ @@ -1398,7 +1426,7 @@ static uint dump_routines_for_db(char *db) DBUG_ENTER("dump_routines_for_db"); DBUG_PRINT("enter", ("db: '%s'", db)); - mysql_real_escape_string(sock, db_name_buff, db, strlen(db)); + mysql_real_escape_string(mysql, db_name_buff, db, strlen(db)); /* nice comments */ if (opt_comments) @@ -1409,7 +1437,7 @@ static uint dump_routines_for_db(char *db) enough privileges to lock mysql.proc. */ if (lock_tables) - mysql_query(sock, "LOCK TABLES mysql.proc READ"); + mysql_query(mysql, "LOCK TABLES mysql.proc READ"); fprintf(sql_file, "DELIMITER ;;\n"); @@ -1420,7 +1448,7 @@ static uint dump_routines_for_db(char *db) "SHOW %s STATUS WHERE Db = '%s'", routine_type[i], db_name_buff); - if (mysql_query_with_error_report(sock, &routine_list_res, query_buff)) + if (mysql_query_with_error_report(mysql, &routine_list_res, query_buff)) DBUG_RETURN(1); if (mysql_num_rows(routine_list_res)) @@ -1434,7 +1462,7 @@ static uint dump_routines_for_db(char *db) my_snprintf(query_buff, sizeof(query_buff), "SHOW CREATE %s %s", routine_type[i], routine_name); - if (mysql_query_with_error_report(sock, &routine_res, query_buff)) + if (mysql_query_with_error_report(mysql, &routine_res, query_buff)) DBUG_RETURN(1); while ((row= mysql_fetch_row(routine_res))) @@ -1516,7 +1544,7 @@ static uint dump_routines_for_db(char *db) fprintf(sql_file, "DELIMITER ;\n"); if (lock_tables) - VOID(mysql_query_with_error_report(sock, 0, "UNLOCK TABLES")); + VOID(mysql_query_with_error_report(mysql, 0, "UNLOCK TABLES")); DBUG_RETURN(0); } @@ -1558,10 +1586,8 @@ static uint get_table_structure(char *table, char *db, char *table_type, if (delayed && (*ignore_flag & IGNORE_INSERT_DELAYED)) { delayed= 0; - if (verbose) - fprintf(stderr, - "-- Warning: Unable to use delayed inserts for table '%s' " - "because it's of type %s\n", table, table_type); + verbose_msg("-- Warning: Unable to use delayed inserts for table '%s' " + "because it's of type %s\n", table, table_type); } complete_insert= 0; @@ -1577,8 +1603,7 @@ static uint get_table_structure(char *table, char *db, char *table_type, insert_option= ((delayed && opt_ignore) ? " DELAYED IGNORE " : delayed ? " DELAYED " : opt_ignore ? " IGNORE " : ""); - if (verbose) - fprintf(stderr, "-- Retrieving table structure for table %s...\n", table); + verbose_msg("-- Retrieving table structure for table %s...\n", table); len= my_snprintf(query_buff, sizeof(query_buff), "SET OPTION SQL_QUOTE_SHOW_CREATE=%d", @@ -1593,17 +1618,17 @@ static uint get_table_structure(char *table, char *db, char *table_type, if (opt_order_by_primary) order_by = primary_key_fields(result_table); - if (!opt_xml && !mysql_query_with_error_report(sock, 0, query_buff)) + if (!opt_xml && !mysql_query_with_error_report(mysql, 0, query_buff)) { /* using SHOW CREATE statement */ - if (!tFlag) + if (!opt_no_create_info) { /* Make an sql-file, if path was given iow. option -T was given */ char buff[20+FN_REFLEN]; MYSQL_FIELD *field; my_snprintf(buff, sizeof(buff), "show create table %s", result_table); - if (mysql_query_with_error_report(sock, 0, buff)) + if (mysql_query_with_error_report(mysql, 0, buff)) { safe_exit(EX_MYSQLERR); DBUG_RETURN(0); @@ -1639,14 +1664,13 @@ static uint get_table_structure(char *table, char *db, char *table_type, check_io(sql_file); } - result= mysql_store_result(sock); + result= mysql_store_result(mysql); field= mysql_fetch_field_direct(result, 0); if (strcmp(field->name, "View") == 0) { char *scv_buff = NULL; - if (verbose) - fprintf(stderr, "-- It's a view, create dummy table for view\n"); + verbose_msg("-- It's a view, create dummy table for view\n"); /* save "show create" statement for later */ if ((row= mysql_fetch_row(result)) && (scv_buff=row[1])) @@ -1667,7 +1691,7 @@ static uint get_table_structure(char *table, char *db, char *table_type, */ my_snprintf(query_buff, sizeof(query_buff), "SHOW FIELDS FROM %s", result_table); - if (mysql_query_with_error_report(sock, 0, query_buff)) + if (mysql_query_with_error_report(mysql, 0, query_buff)) { /* View references invalid or privileged table/col/fun (err 1356), @@ -1675,7 +1699,7 @@ static uint get_table_structure(char *table, char *db, char *table_type, a comment with the view's 'show create' statement. (Bug #17371) */ - if (mysql_errno(sock) == ER_VIEW_INVALID) + if (mysql_errno(mysql) == ER_VIEW_INVALID) fprintf(sql_file, "\n-- failed on view %s: %s\n\n", result_table, scv_buff ? scv_buff : ""); my_free(scv_buff, MYF(MY_ALLOW_ZERO_PTR)); @@ -1686,7 +1710,7 @@ static uint get_table_structure(char *table, char *db, char *table_type, else my_free(scv_buff, MYF(MY_ALLOW_ZERO_PTR)); - if ((result= mysql_store_result(sock))) + if ((result= mysql_store_result(mysql))) { if (mysql_num_rows(result)) { @@ -1739,7 +1763,7 @@ static uint get_table_structure(char *table, char *db, char *table_type, } my_snprintf(query_buff, sizeof(query_buff), "show fields from %s", result_table); - if (mysql_query_with_error_report(sock, &result, query_buff)) + if (mysql_query_with_error_report(mysql, &result, query_buff)) { if (path) my_fclose(sql_file, MYF(MY_WME)); @@ -1792,21 +1816,19 @@ static uint get_table_structure(char *table, char *db, char *table_type, } else { - if (verbose) - fprintf(stderr, - "%s: Warning: Can't set SQL_QUOTE_SHOW_CREATE option (%s)\n", - my_progname, mysql_error(sock)); + verbose_msg("%s: Warning: Can't set SQL_QUOTE_SHOW_CREATE option (%s)\n", + my_progname, mysql_error(mysql)); my_snprintf(query_buff, sizeof(query_buff), "show fields from %s", result_table); - if (mysql_query_with_error_report(sock, &result, query_buff)) + if (mysql_query_with_error_report(mysql, &result, query_buff)) { safe_exit(EX_MYSQLERR); DBUG_RETURN(0); } /* Make an sql-file, if path was given iow. option -T was given */ - if (!tFlag) + if (!opt_no_create_info) { if (path) { @@ -1853,7 +1875,7 @@ static uint get_table_structure(char *table, char *db, char *table_type, ulong *lengths= mysql_fetch_lengths(result); if (init) { - if (!opt_xml && !tFlag) + if (!opt_xml && !opt_no_create_info) { fputs(",\n",sql_file); check_io(sql_file); @@ -1865,7 +1887,7 @@ static uint get_table_structure(char *table, char *db, char *table_type, if (opt_complete_insert) dynstr_append(&insert_pat, quote_name(row[SHOW_FIELDNAME], name_buff, 0)); - if (!tFlag) + if (!opt_no_create_info) { if (opt_xml) { @@ -1895,22 +1917,22 @@ static uint get_table_structure(char *table, char *db, char *table_type, } num_fields= mysql_num_rows(result); mysql_free_result(result); - if (!tFlag) + if (!opt_no_create_info) { /* Make an sql-file, if path was given iow. option -T was given */ char buff[20+FN_REFLEN]; uint keynr,primary_key; my_snprintf(buff, sizeof(buff), "show keys from %s", result_table); - if (mysql_query_with_error_report(sock, &result, buff)) + if (mysql_query_with_error_report(mysql, &result, buff)) { - if (mysql_errno(sock) == ER_WRONG_OBJECT) + if (mysql_errno(mysql) == ER_WRONG_OBJECT) { /* it is VIEW */ fputs("\t\t<options Comment=\"view\" />\n", sql_file); goto continue_xml; } fprintf(stderr, "%s: Can't get keys for table %s (%s)\n", - my_progname, result_table, mysql_error(sock)); + my_progname, result_table, mysql_error(mysql)); if (path) my_fclose(sql_file, MYF(MY_WME)); safe_exit(EX_MYSQLERR); @@ -1983,21 +2005,19 @@ static uint get_table_structure(char *table, char *db, char *table_type, my_snprintf(buff, sizeof(buff), "show table status like %s", quote_for_like(table, show_name_buff)); - if (mysql_query_with_error_report(sock, &result, buff)) + if (mysql_query_with_error_report(mysql, &result, buff)) { - if (mysql_errno(sock) != ER_PARSE_ERROR) + if (mysql_errno(mysql) != ER_PARSE_ERROR) { /* If old MySQL version */ - if (verbose) - fprintf(stderr, - "-- Warning: Couldn't get status information for table %s (%s)\n", - result_table,mysql_error(sock)); + verbose_msg("-- Warning: Couldn't get status information for " \ + "table %s (%s)\n", result_table,mysql_error(mysql)); } } else if (!(row= mysql_fetch_row(result))) { fprintf(stderr, "Error: Couldn't read status information for table %s (%s)\n", - result_table,mysql_error(sock)); + result_table,mysql_error(mysql)); } else { @@ -2070,7 +2090,7 @@ static void dump_triggers_for_table (char *table, char *db) "SHOW TRIGGERS LIKE %s", quote_for_like(table, name_buff)); - if (mysql_query_with_error_report(sock, &result, query_buff)) + if (mysql_query_with_error_report(mysql, &result, query_buff)) { if (path) my_fclose(sql_file, MYF(MY_WME)); @@ -2240,12 +2260,10 @@ static void dump_table(char *table, char *db) return; /* Check --no-data flag */ - if (dFlag) + if (opt_no_data) { - if (verbose) - fprintf(stderr, - "-- Skipping dump data for table '%s', --no-data was used\n", - table); + verbose_msg("-- Skipping dump data for table '%s', --no-data was used\n", + table); DBUG_VOID_RETURN; } @@ -2258,27 +2276,22 @@ static void dump_table(char *table, char *db) */ if (ignore_flag & IGNORE_DATA) { - if (verbose) - fprintf(stderr, - "-- Warning: Skipping data for table '%s' because it's of type %s\n", - table, table_type); + verbose_msg("-- Warning: Skipping data for table '%s' because " \ + "it's of type %s\n", table, table_type); DBUG_VOID_RETURN; } /* Check that there are any fields in the table */ if (num_fields == 0) { - if (verbose) - fprintf(stderr, - "-- Skipping dump data for table '%s', it has no fields\n", - table); + verbose_msg("-- Skipping dump data for table '%s', it has no fields\n", + table); DBUG_VOID_RETURN; } result_table= quote_name(table,table_buff, 1); opt_quoted_table= quote_name(table, table_buff2, 0); - if (verbose) - fprintf(stderr, "-- Sending SELECT query...\n"); + verbose_msg("-- Sending SELECT query...\n"); if (path) { char filename[FN_REFLEN], tmp_path[FN_REFLEN]; @@ -2316,9 +2329,9 @@ static void dump_table(char *table, char *db) if (order_by) end = strxmov(end, " ORDER BY ", order_by, NullS); } - if (mysql_real_query(sock, query, (uint) (end - query))) + if (mysql_real_query(mysql, query, (uint) (end - query))) { - DB_error(sock, "when executing 'SELECT INTO OUTFILE'"); + DB_error(mysql, "when executing 'SELECT INTO OUTFILE'"); DBUG_VOID_RETURN; } } @@ -2364,19 +2377,19 @@ static void dump_table(char *table, char *db) fputs("\n", md_result_file); check_io(md_result_file); } - if (mysql_query_with_error_report(sock, 0, query)) - DB_error(sock, "when retrieving data from server"); + if (mysql_query_with_error_report(mysql, 0, query)) + DB_error(mysql, "when retrieving data from server"); if (quick) - res=mysql_use_result(sock); + res=mysql_use_result(mysql); else - res=mysql_store_result(sock); + res=mysql_store_result(mysql); if (!res) { - DB_error(sock, "when retrieving data from server"); + DB_error(mysql, "when retrieving data from server"); goto err; } - if (verbose) - fprintf(stderr, "-- Retrieving rows...\n"); + + verbose_msg("-- Retrieving rows...\n"); if (mysql_num_fields(res) != num_fields) { fprintf(stderr,"%s: Error in field count for table: %s ! Aborting.\n", @@ -2645,13 +2658,13 @@ static void dump_table(char *table, char *db) fputs(";\n", md_result_file); /* If not empty table */ fflush(md_result_file); check_io(md_result_file); - if (mysql_errno(sock)) + if (mysql_errno(mysql)) { my_snprintf(query, QUERY_LENGTH, "%s: Error %d: %s when dumping table %s at row: %ld\n", my_progname, - mysql_errno(sock), - mysql_error(sock), + mysql_errno(mysql), + mysql_error(mysql), result_table, rownr); fputs(query,stderr); @@ -2697,7 +2710,7 @@ static char *getTableName(int reset) if (!res) { - if (!(res = mysql_list_tables(sock,NullS))) + if (!(res = mysql_list_tables(mysql,NullS))) return(NULL); } if ((row = mysql_fetch_row(res))) @@ -2844,7 +2857,7 @@ static int dump_all_databases() MYSQL_RES *tableres; int result=0; - if (mysql_query_with_error_report(sock, &tableres, "SHOW DATABASES")) + if (mysql_query_with_error_report(mysql, &tableres, "SHOW DATABASES")) return 1; while ((row = mysql_fetch_row(tableres))) { @@ -2853,11 +2866,11 @@ static int dump_all_databases() } if (seen_views) { - if (mysql_query(sock, "SHOW DATABASES") || - !(tableres = mysql_store_result(sock))) + if (mysql_query(mysql, "SHOW DATABASES") || + !(tableres = mysql_store_result(mysql))) { my_printf_error(0, "Error: Couldn't execute 'SHOW DATABASES': %s", - MYF(0), mysql_error(sock)); + MYF(0), mysql_error(mysql)); return 1; } while ((row = mysql_fetch_row(tableres))) @@ -2894,13 +2907,13 @@ static int dump_databases(char **db_names) static int init_dumping(char *database) { - if (mysql_get_server_version(sock) >= 50003 && + if (mysql_get_server_version(mysql) >= 50003 && !my_strcasecmp(&my_charset_latin1, database, "information_schema")) return 1; - if (mysql_select_db(sock, database)) + if (mysql_select_db(mysql, database)) { - DB_error(sock, "when selecting the database"); + DB_error(mysql, "when selecting the database"); return 1; /* If --force */ } if (!path && !opt_xml) @@ -2927,7 +2940,7 @@ static int init_dumping(char *database) "SHOW CREATE DATABASE IF NOT EXISTS %s", qdatabase); - if (mysql_query(sock, qbuf) || !(dbinfo = mysql_store_result(sock))) + if (mysql_query(mysql, qbuf) || !(dbinfo = mysql_store_result(mysql))) { /* Old server version, dump generic CREATE DATABASE */ if (opt_drop_database) @@ -2997,15 +3010,15 @@ static int dump_all_tables_in_db(char *database) dynstr_append(&query, quote_name(table, table_buff, 1)); dynstr_append(&query, " READ /*!32311 LOCAL */,"); } - if (numrows && mysql_real_query(sock, query.str, query.length-1)) - DB_error(sock, "when using LOCK TABLES"); + if (numrows && mysql_real_query(mysql, query.str, query.length-1)) + DB_error(mysql, "when using LOCK TABLES"); /* We shall continue here, if --force was given */ dynstr_free(&query); } if (flush_logs) { - if (mysql_refresh(sock, REFRESH_LOG)) - DB_error(sock, "when doing refresh"); + if (mysql_refresh(mysql, REFRESH_LOG)) + DB_error(mysql, "when doing refresh"); /* We shall continue here, if --force was given */ } while ((table= getTableName(0))) @@ -3017,7 +3030,7 @@ static int dump_all_tables_in_db(char *database) my_free(order_by, MYF(MY_ALLOW_ZERO_PTR)); order_by= 0; if (opt_dump_triggers && ! opt_xml && - mysql_get_server_version(sock) >= 50009) + mysql_get_server_version(mysql) >= 50009) dump_triggers_for_table(table, database); } } @@ -3028,7 +3041,7 @@ static int dump_all_tables_in_db(char *database) dump_events_for_db(database); } if (opt_routines && !opt_xml && - mysql_get_server_version(sock) >= 50009) + mysql_get_server_version(mysql) >= 50009) { DBUG_PRINT("info", ("Dumping routines for database %s", database)); dump_routines_for_db(database); @@ -3039,7 +3052,7 @@ static int dump_all_tables_in_db(char *database) check_io(md_result_file); } if (lock_tables) - VOID(mysql_query_with_error_report(sock, 0, "UNLOCK TABLES")); + VOID(mysql_query_with_error_report(mysql, 0, "UNLOCK TABLES")); return 0; } /* dump_all_tables_in_db */ @@ -3062,9 +3075,9 @@ static my_bool dump_all_views_in_db(char *database) uint numrows; char table_buff[NAME_LEN*2+3]; - if (mysql_select_db(sock, database)) + if (mysql_select_db(mysql, database)) { - DB_error(sock, "when selecting the database"); + DB_error(mysql, "when selecting the database"); return 1; } if (opt_databases || opt_alldbs) @@ -3090,15 +3103,15 @@ static my_bool dump_all_views_in_db(char *database) dynstr_append(&query, quote_name(table, table_buff, 1)); dynstr_append(&query, " READ /*!32311 LOCAL */,"); } - if (numrows && mysql_real_query(sock, query.str, query.length-1)) - DB_error(sock, "when using LOCK TABLES"); + if (numrows && mysql_real_query(mysql, query.str, query.length-1)) + DB_error(mysql, "when using LOCK TABLES"); /* We shall continue here, if --force was given */ dynstr_free(&query); } if (flush_logs) { - if (mysql_refresh(sock, REFRESH_LOG)) - DB_error(sock, "when doing refresh"); + if (mysql_refresh(mysql, REFRESH_LOG)) + DB_error(mysql, "when doing refresh"); /* We shall continue here, if --force was given */ } while ((table= getTableName(0))) @@ -3109,7 +3122,7 @@ static my_bool dump_all_views_in_db(char *database) check_io(md_result_file); } if (lock_tables) - VOID(mysql_query_with_error_report(sock, 0, "UNLOCK TABLES")); + VOID(mysql_query_with_error_report(mysql, 0, "UNLOCK TABLES")); return 0; } /* dump_all_tables_in_db */ @@ -3139,12 +3152,12 @@ static char *get_actual_table_name(const char *old_table_name, MEM_ROOT *root) my_snprintf(query, sizeof(query), "SHOW TABLES LIKE %s", quote_for_like(old_table_name, show_name_buff)); - if (mysql_query_with_error_report(sock, 0, query)) + if (mysql_query_with_error_report(mysql, 0, query)) { safe_exit(EX_MYSQLERR); } - if ((table_res= mysql_store_result(sock))) + if ((table_res= mysql_store_result(mysql))) { my_ulonglong num_rows= mysql_num_rows(table_res); if (num_rows > 0) @@ -3206,16 +3219,16 @@ static int dump_selected_tables(char *db, char **table_names, int tables) if (lock_tables) { - if (mysql_real_query(sock, lock_tables_query.str, + if (mysql_real_query(mysql, lock_tables_query.str, lock_tables_query.length-1)) - DB_error(sock, "when doing LOCK TABLES"); + DB_error(mysql, "when doing LOCK TABLES"); /* We shall countinue here, if --force was given */ } dynstr_free(&lock_tables_query); if (flush_logs) { - if (mysql_refresh(sock, REFRESH_LOG)) - DB_error(sock, "when doing refresh"); + if (mysql_refresh(mysql, REFRESH_LOG)) + DB_error(mysql, "when doing refresh"); /* We shall countinue here, if --force was given */ } if (opt_xml) @@ -3227,7 +3240,7 @@ static int dump_selected_tables(char *db, char **table_names, int tables) DBUG_PRINT("info",("Dumping table %s", *pos)); dump_table(*pos, db); if (opt_dump_triggers && - mysql_get_server_version(sock) >= 50009) + mysql_get_server_version(mysql) >= 50009) dump_triggers_for_table(*pos, db); } @@ -3245,7 +3258,7 @@ static int dump_selected_tables(char *db, char **table_names, int tables) } /* obtain dump of routines (procs/functions) */ if (opt_routines && !opt_xml && - mysql_get_server_version(sock) >= 50009) + mysql_get_server_version(mysql) >= 50009) { DBUG_PRINT("info", ("Dumping routines for database %s", db)); dump_routines_for_db(db); @@ -3259,7 +3272,7 @@ static int dump_selected_tables(char *db, char **table_names, int tables) check_io(md_result_file); } if (lock_tables) - VOID(mysql_query_with_error_report(sock, 0, "UNLOCK TABLES")); + VOID(mysql_query_with_error_report(mysql, 0, "UNLOCK TABLES")); DBUG_RETURN(0); } /* dump_selected_tables */ @@ -3272,8 +3285,6 @@ static int do_show_master_status(MYSQL *mysql_con) (opt_master_data == MYSQL_OPT_MASTER_DATA_COMMENTED_SQL) ? "-- " : ""; if (mysql_query_with_error_report(mysql_con, &master, "SHOW MASTER STATUS")) { - my_printf_error(0, "Error: Couldn't execute 'SHOW MASTER STATUS': %s", - MYF(0), mysql_error(mysql_con)); return 1; } else @@ -3444,7 +3455,7 @@ static void print_value(FILE *file, MYSQL_RES *result, MYSQL_ROW row, table_type Type of table GLOBAL VARIABLES - sock MySQL socket + mysql MySQL connection verbose Write warning messages RETURN @@ -3463,14 +3474,12 @@ char check_if_ignore_table(const char *table_name, char *table_type) DBUG_ASSERT(2*sizeof(table_name) < sizeof(show_name_buff)); my_snprintf(buff, sizeof(buff), "show table status like %s", quote_for_like(table_name, show_name_buff)); - if (mysql_query_with_error_report(sock, &res, buff)) + if (mysql_query_with_error_report(mysql, &res, buff)) { - if (mysql_errno(sock) != ER_PARSE_ERROR) + if (mysql_errno(mysql) != ER_PARSE_ERROR) { /* If old MySQL version */ - if (verbose) - fprintf(stderr, - "-- Warning: Couldn't get status information for table %s (%s)\n", - table_name,mysql_error(sock)); + verbose_msg("-- Warning: Couldn't get status information for " \ + "table %s (%s)\n", table_name,mysql_error(mysql)); DBUG_RETURN(result); /* assume table is ok */ } } @@ -3478,7 +3487,7 @@ char check_if_ignore_table(const char *table_name, char *table_type) { fprintf(stderr, "Error: Couldn't read status information for table %s (%s)\n", - table_name, mysql_error(sock)); + table_name, mysql_error(mysql)); mysql_free_result(res); DBUG_RETURN(result); /* assume table is ok */ } @@ -3506,7 +3515,7 @@ char check_if_ignore_table(const char *table_name, char *table_type) /* If these two types, we do want to skip dumping the table */ - if (!dFlag && + if (!opt_no_data && (!strcmp(table_type,"MRG_MyISAM") || !strcmp(table_type,"MRG_ISAM"))) result= IGNORE_DATA; } @@ -3514,6 +3523,7 @@ char check_if_ignore_table(const char *table_name, char *table_type) DBUG_RETURN(result); } + /* Get string of comma-separated primary key field names @@ -3543,12 +3553,12 @@ static char *primary_key_fields(const char *table_name) my_snprintf(show_keys_buff, sizeof(show_keys_buff), "SHOW KEYS FROM %s", table_name); - if (mysql_query(sock, show_keys_buff) || - !(res = mysql_store_result(sock))) + if (mysql_query(mysql, show_keys_buff) || + !(res = mysql_store_result(mysql))) { fprintf(stderr, "Warning: Couldn't read keys from table %s;" " records are NOT sorted (%s)\n", - table_name, mysql_error(sock)); + table_name, mysql_error(mysql)); /* Don't exit, because it's better to print out unsorted records */ goto cleanup; } @@ -3653,11 +3663,10 @@ static my_bool get_view_structure(char *table, char* db) FILE *sql_file = md_result_file; DBUG_ENTER("get_view_structure"); - if (tFlag) /* Don't write table creation info */ + if (opt_no_create_info) /* Don't write table creation info */ DBUG_RETURN(0); - if (verbose) - fprintf(stderr, "-- Retrieving view structure for table %s...\n", table); + verbose_msg("-- Retrieving view structure for table %s...\n", table); #ifdef NOT_REALLY_USED_YET sprintf(insert_pat,"SET OPTION SQL_QUOTE_SHOW_CREATE=%d", @@ -3668,7 +3677,7 @@ static my_bool get_view_structure(char *table, char* db) opt_quoted_table= quote_name(table, table_buff2, 0); my_snprintf(query, sizeof(query), "SHOW CREATE TABLE %s", result_table); - if (mysql_query_with_error_report(sock, &table_res, query)) + if (mysql_query_with_error_report(mysql, &table_res, query)) { safe_exit(EX_MYSQLERR); DBUG_RETURN(0); @@ -3678,8 +3687,7 @@ static my_bool get_view_structure(char *table, char* db) field= mysql_fetch_field_direct(table_res, 0); if (strcmp(field->name, "View") != 0) { - if (verbose) - fprintf(stderr, "-- It's base table, skipped\n"); + verbose_msg("-- It's base table, skipped\n"); DBUG_RETURN(0); } @@ -3714,7 +3722,7 @@ static my_bool get_view_structure(char *table, char* db) "SELECT CHECK_OPTION, DEFINER, SECURITY_TYPE " \ "FROM information_schema.views " \ "WHERE table_name=\"%s\" AND table_schema=\"%s\"", table, db); - if (mysql_query(sock, query)) + if (mysql_query(mysql, query)) { /* Use the raw output from SHOW CREATE TABLE if @@ -3740,7 +3748,7 @@ static my_bool get_view_structure(char *table, char* db) mysql_free_result(table_res); /* Get the result from "select ... information_schema" */ - if (!(table_res= mysql_store_result(sock)) || + if (!(table_res= mysql_store_result(mysql)) || !(row= mysql_fetch_row(table_res))) { safe_exit(EX_MYSQLERR); @@ -3835,21 +3843,21 @@ int main(int argc, char **argv) write_header(md_result_file, *argv); if ((opt_lock_all_tables || opt_master_data) && - do_flush_tables_read_lock(sock)) + do_flush_tables_read_lock(mysql)) goto err; - if (opt_single_transaction && start_transaction(sock, test(opt_master_data))) + if (opt_single_transaction && start_transaction(mysql, test(opt_master_data))) goto err; - if (opt_delete_master_logs && do_reset_master(sock)) + if (opt_delete_master_logs && do_reset_master(mysql)) goto err; if (opt_lock_all_tables || opt_master_data) { - if (flush_logs && mysql_refresh(sock, REFRESH_LOG)) + if (flush_logs && mysql_refresh(mysql, REFRESH_LOG)) goto err; flush_logs= 0; /* not anymore; that would not be sensible */ } - if (opt_master_data && do_show_master_status(sock)) + if (opt_master_data && do_show_master_status(mysql)) goto err; - if (opt_single_transaction && do_unlock_tables(sock)) /* unlock but no commit! */ + if (opt_single_transaction && do_unlock_tables(mysql)) /* unlock but no commit! */ goto err; if (opt_alltspcs) diff --git a/client/mysqlimport.c b/client/mysqlimport.c index 18a31117c08..2ef08c9a504 100644 --- a/client/mysqlimport.c +++ b/client/mysqlimport.c @@ -538,7 +538,7 @@ pthread_handler_t worker_thread(void *arg) goto error; } - if (mysql_query(mysql, "set @@character_set_database=binary;")) + if (mysql_query(mysql, "/*!40101 set @@character_set_database=binary */;")) { db_error(mysql); /* We shall countinue here, if --force was given */ goto error; @@ -644,7 +644,7 @@ int main(int argc, char **argv) return(1); /* purecov: deadcode */ } - if (mysql_query(mysql, "set @@character_set_database=binary;")) + if (mysql_query(mysql, "/*!40101 set @@character_set_database=binary */;")) { db_error(mysql); /* We shall countinue here, if --force was given */ return(1); diff --git a/client/mysqlshow.c b/client/mysqlshow.c index d090495ff81..40405c53565 100644 --- a/client/mysqlshow.c +++ b/client/mysqlshow.c @@ -344,7 +344,7 @@ list_dbs(MYSQL *mysql,const char *wild) char query[255]; MYSQL_FIELD *field; MYSQL_RES *result; - MYSQL_ROW row, rrow; + MYSQL_ROW row= NULL, rrow; if (!(result=mysql_list_dbs(mysql,wild))) { @@ -352,6 +352,26 @@ list_dbs(MYSQL *mysql,const char *wild) mysql_error(mysql)); return 1; } + + /* + If a wildcard was used, but there was only one row and it's name is an + exact match, we'll assume they really wanted to see the contents of that + database. This is because it is fairly common for database names to + contain the underscore (_), like INFORMATION_SCHEMA. + */ + if (wild && mysql_num_rows(result) == 1) + { + row= mysql_fetch_row(result); + if (!my_strcasecmp(&my_charset_latin1, row[0], wild)) + { + mysql_free_result(result); + if (opt_status) + return list_table_status(mysql, wild, NULL); + else + return list_tables(mysql, wild, NULL); + } + } + if (wild) printf("Wildcard: %s\n",wild); @@ -368,7 +388,8 @@ list_dbs(MYSQL *mysql,const char *wild) else print_header(header,length,"Tables",6,"Total Rows",12,NullS); - while ((row = mysql_fetch_row(result))) + /* The first row may have already been read up above. */ + while (row || (row= mysql_fetch_row(result))) { counter++; @@ -422,6 +443,8 @@ list_dbs(MYSQL *mysql,const char *wild) print_row(row[0],length,tables,6,NullS); else print_row(row[0],length,tables,6,rows,12,NullS); + + row= NULL; } print_trailer(length, diff --git a/client/mysqltest.c b/client/mysqltest.c index bc025e68ffe..06f6ab2f1ce 100644 --- a/client/mysqltest.c +++ b/client/mysqltest.c @@ -5319,6 +5319,14 @@ int main(int argc, char **argv) q->require_file=require_file; save_file[0]=0; } + /* + To force something being sent as a query to the mysqld one can + use the prefix "query". Remove "query" from string before executing + */ + if (strncmp(q->query, "query ", 6) == 0) + { + q->query= q->first_argument; + } run_query(&cur_con->mysql, q, flags); query_executed= 1; q->last_argument= q->end; diff --git a/configure.in b/configure.in index e322f20f962..2eb21ad701b 100644 --- a/configure.in +++ b/configure.in @@ -1531,17 +1531,20 @@ AC_ARG_WITH(debug, if test "$with_debug" = "yes" then # Medium debug. - CFLAGS="$DEBUG_CFLAGS $DEBUG_OPTIMIZE_CC -DDBUG_ON -DSAFE_MUTEX $CFLAGS" - CXXFLAGS="$DEBUG_CXXFLAGS $DEBUG_OPTIMIZE_CXX -DDBUG_ON -DSAFE_MUTEX $CXXFLAGS" + AC_DEFINE([DBUG_ON], [1], [Use libdbug]) + CFLAGS="$DEBUG_CFLAGS $DEBUG_OPTIMIZE_CC -DSAFE_MUTEX $CFLAGS" + CXXFLAGS="$DEBUG_CXXFLAGS $DEBUG_OPTIMIZE_CXX -DSAFE_MUTEX $CXXFLAGS" elif test "$with_debug" = "full" then # Full debug. Very slow in some cases - CFLAGS="$DEBUG_CFLAGS -DDBUG_ON -DSAFE_MUTEX -DSAFEMALLOC $CFLAGS" - CXXFLAGS="$DEBUG_CXXFLAGS -DDBUG_ON -DSAFE_MUTEX -DSAFEMALLOC $CXXFLAGS" + AC_DEFINE([DBUG_ON], [1], [Use libdbug]) + CFLAGS="$DEBUG_CFLAGS -DSAFE_MUTEX -DSAFEMALLOC $CFLAGS" + CXXFLAGS="$DEBUG_CXXFLAGS -DSAFE_MUTEX -DSAFEMALLOC $CXXFLAGS" else # Optimized version. No debug - CFLAGS="$OPTIMIZE_CFLAGS -DDBUG_OFF $CFLAGS" - CXXFLAGS="$OPTIMIZE_CXXFLAGS -DDBUG_OFF $CXXFLAGS" + AC_DEFINE([DBUG_OFF], [1], [Don't use libdbug]) + CFLAGS="$OPTIMIZE_CFLAGS $CFLAGS" + CXXFLAGS="$OPTIMIZE_CXXFLAGS $CXXFLAGS" fi # If we should allow error injection tests diff --git a/dbug/dbug.c b/dbug/dbug.c index 48b2398e9c6..a543a335952 100644 --- a/dbug/dbug.c +++ b/dbug/dbug.c @@ -71,10 +71,13 @@ * */ +#include <my_global.h> + +/* This file won't compile unless DBUG_OFF is undefined locally */ #ifdef DBUG_OFF #undef DBUG_OFF #endif -#include <my_global.h> + #include <m_string.h> #include <errno.h> #if defined(MSDOS) || defined(__WIN__) diff --git a/extra/perror.c b/extra/perror.c index 3b7560837b9..d4eae3e471d 100644 --- a/extra/perror.c +++ b/extra/perror.c @@ -218,8 +218,11 @@ int main(int argc,char *argv[]) On some system, like NETWARE, strerror(unknown_error) returns a string 'Unknown Error'. To avoid printing it we try to find the error string by asking for an impossible big error message. + + On Solaris 2.8 it might return NULL */ - msg= strerror(10000); + if ((msg= strerror(10000)) == NULL) + msg= "Unknown Error"; /* Allocate a buffer for unknown_error since strerror always returns @@ -258,7 +261,7 @@ int main(int argc,char *argv[]) found= 1; msg= 0; } - else + else #endif msg = strerror(code); @@ -278,20 +281,23 @@ int main(int argc,char *argv[]) else puts(msg); } - if (!(msg=get_ha_error_msg(code))) + + if (!found) { - if (!found) - { + /* Error message still not found, look in handler error codes */ + if (!(msg=get_ha_error_msg(code))) + { fprintf(stderr,"Illegal error code: %d\n",code); error=1; - } - } - else - { - if (verbose) - printf("MySQL error code %3d: %s\n",code,msg); - else - puts(msg); + } + else + { + found= 1; + if (verbose) + printf("MySQL error code %3d: %s\n",code,msg); + else + puts(msg); + } } } } diff --git a/extra/yassl/COPYING b/extra/yassl/COPYING new file mode 100644 index 00000000000..d60c31a97a5 --- /dev/null +++ b/extra/yassl/COPYING @@ -0,0 +1,340 @@ + GNU GENERAL PUBLIC LICENSE + Version 2, June 1991 + + Copyright (C) 1989, 1991 Free Software Foundation, Inc. + 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + Preamble + + The licenses for most software are designed to take away your +freedom to share and change it. By contrast, the GNU General Public +License is intended to guarantee your freedom to share and change free +software--to make sure the software is free for all its users. This +General Public License applies to most of the Free Software +Foundation's software and to any other program whose authors commit to +using it. (Some other Free Software Foundation software is covered by +the GNU Library General Public License instead.) You can apply it to +your programs, too. + + When we speak of free software, we are referring to freedom, not +price. Our General Public Licenses are designed to make sure that you +have the freedom to distribute copies of free software (and charge for +this service if you wish), that you receive source code or can get it +if you want it, that you can change the software or use pieces of it +in new free programs; and that you know you can do these things. + + To protect your rights, we need to make restrictions that forbid +anyone to deny you these rights or to ask you to surrender the rights. +These restrictions translate to certain responsibilities for you if you +distribute copies of the software, or if you modify it. + + For example, if you distribute copies of such a program, whether +gratis or for a fee, you must give the recipients all the rights that +you have. You must make sure that they, too, receive or can get the +source code. And you must show them these terms so they know their +rights. + + We protect your rights with two steps: (1) copyright the software, and +(2) offer you this license which gives you legal permission to copy, +distribute and/or modify the software. + + Also, for each author's protection and ours, we want to make certain +that everyone understands that there is no warranty for this free +software. If the software is modified by someone else and passed on, we +want its recipients to know that what they have is not the original, so +that any problems introduced by others will not reflect on the original +authors' reputations. + + Finally, any free program is threatened constantly by software +patents. We wish to avoid the danger that redistributors of a free +program will individually obtain patent licenses, in effect making the +program proprietary. To prevent this, we have made it clear that any +patent must be licensed for everyone's free use or not licensed at all. + + The precise terms and conditions for copying, distribution and +modification follow. + + GNU GENERAL PUBLIC LICENSE + TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION + + 0. This License applies to any program or other work which contains +a notice placed by the copyright holder saying it may be distributed +under the terms of this General Public License. The "Program", below, +refers to any such program or work, and a "work based on the Program" +means either the Program or any derivative work under copyright law: +that is to say, a work containing the Program or a portion of it, +either verbatim or with modifications and/or translated into another +language. (Hereinafter, translation is included without limitation in +the term "modification".) Each licensee is addressed as "you". + +Activities other than copying, distribution and modification are not +covered by this License; they are outside its scope. The act of +running the Program is not restricted, and the output from the Program +is covered only if its contents constitute a work based on the +Program (independent of having been made by running the Program). +Whether that is true depends on what the Program does. + + 1. You may copy and distribute verbatim copies of the Program's +source code as you receive it, in any medium, provided that you +conspicuously and appropriately publish on each copy an appropriate +copyright notice and disclaimer of warranty; keep intact all the +notices that refer to this License and to the absence of any warranty; +and give any other recipients of the Program a copy of this License +along with the Program. + +You may charge a fee for the physical act of transferring a copy, and +you may at your option offer warranty protection in exchange for a fee. + + 2. You may modify your copy or copies of the Program or any portion +of it, thus forming a work based on the Program, and copy and +distribute such modifications or work under the terms of Section 1 +above, provided that you also meet all of these conditions: + + a) You must cause the modified files to carry prominent notices + stating that you changed the files and the date of any change. + + b) You must cause any work that you distribute or publish, that in + whole or in part contains or is derived from the Program or any + part thereof, to be licensed as a whole at no charge to all third + parties under the terms of this License. + + c) If the modified program normally reads commands interactively + when run, you must cause it, when started running for such + interactive use in the most ordinary way, to print or display an + announcement including an appropriate copyright notice and a + notice that there is no warranty (or else, saying that you provide + a warranty) and that users may redistribute the program under + these conditions, and telling the user how to view a copy of this + License. (Exception: if the Program itself is interactive but + does not normally print such an announcement, your work based on + the Program is not required to print an announcement.) + +These requirements apply to the modified work as a whole. If +identifiable sections of that work are not derived from the Program, +and can be reasonably considered independent and separate works in +themselves, then this License, and its terms, do not apply to those +sections when you distribute them as separate works. But when you +distribute the same sections as part of a whole which is a work based +on the Program, the distribution of the whole must be on the terms of +this License, whose permissions for other licensees extend to the +entire whole, and thus to each and every part regardless of who wrote it. + +Thus, it is not the intent of this section to claim rights or contest +your rights to work written entirely by you; rather, the intent is to +exercise the right to control the distribution of derivative or +collective works based on the Program. + +In addition, mere aggregation of another work not based on the Program +with the Program (or with a work based on the Program) on a volume of +a storage or distribution medium does not bring the other work under +the scope of this License. + + 3. You may copy and distribute the Program (or a work based on it, +under Section 2) in object code or executable form under the terms of +Sections 1 and 2 above provided that you also do one of the following: + + a) Accompany it with the complete corresponding machine-readable + source code, which must be distributed under the terms of Sections + 1 and 2 above on a medium customarily used for software interchange; or, + + b) Accompany it with a written offer, valid for at least three + years, to give any third party, for a charge no more than your + cost of physically performing source distribution, a complete + machine-readable copy of the corresponding source code, to be + distributed under the terms of Sections 1 and 2 above on a medium + customarily used for software interchange; or, + + c) Accompany it with the information you received as to the offer + to distribute corresponding source code. (This alternative is + allowed only for noncommercial distribution and only if you + received the program in object code or executable form with such + an offer, in accord with Subsection b above.) + +The source code for a work means the preferred form of the work for +making modifications to it. For an executable work, complete source +code means all the source code for all modules it contains, plus any +associated interface definition files, plus the scripts used to +control compilation and installation of the executable. However, as a +special exception, the source code distributed need not include +anything that is normally distributed (in either source or binary +form) with the major components (compiler, kernel, and so on) of the +operating system on which the executable runs, unless that component +itself accompanies the executable. + +If distribution of executable or object code is made by offering +access to copy from a designated place, then offering equivalent +access to copy the source code from the same place counts as +distribution of the source code, even though third parties are not +compelled to copy the source along with the object code. + + 4. You may not copy, modify, sublicense, or distribute the Program +except as expressly provided under this License. Any attempt +otherwise to copy, modify, sublicense or distribute the Program is +void, and will automatically terminate your rights under this License. +However, parties who have received copies, or rights, from you under +this License will not have their licenses terminated so long as such +parties remain in full compliance. + + 5. You are not required to accept this License, since you have not +signed it. However, nothing else grants you permission to modify or +distribute the Program or its derivative works. These actions are +prohibited by law if you do not accept this License. Therefore, by +modifying or distributing the Program (or any work based on the +Program), you indicate your acceptance of this License to do so, and +all its terms and conditions for copying, distributing or modifying +the Program or works based on it. + + 6. Each time you redistribute the Program (or any work based on the +Program), the recipient automatically receives a license from the +original licensor to copy, distribute or modify the Program subject to +these terms and conditions. You may not impose any further +restrictions on the recipients' exercise of the rights granted herein. +You are not responsible for enforcing compliance by third parties to +this License. + + 7. If, as a consequence of a court judgment or allegation of patent +infringement or for any other reason (not limited to patent issues), +conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot +distribute so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you +may not distribute the Program at all. For example, if a patent +license would not permit royalty-free redistribution of the Program by +all those who receive copies directly or indirectly through you, then +the only way you could satisfy both it and this License would be to +refrain entirely from distribution of the Program. + +If any portion of this section is held invalid or unenforceable under +any particular circumstance, the balance of the section is intended to +apply and the section as a whole is intended to apply in other +circumstances. + +It is not the purpose of this section to induce you to infringe any +patents or other property right claims or to contest validity of any +such claims; this section has the sole purpose of protecting the +integrity of the free software distribution system, which is +implemented by public license practices. Many people have made +generous contributions to the wide range of software distributed +through that system in reliance on consistent application of that +system; it is up to the author/donor to decide if he or she is willing +to distribute software through any other system and a licensee cannot +impose that choice. + +This section is intended to make thoroughly clear what is believed to +be a consequence of the rest of this License. + + 8. If the distribution and/or use of the Program is restricted in +certain countries either by patents or by copyrighted interfaces, the +original copyright holder who places the Program under this License +may add an explicit geographical distribution limitation excluding +those countries, so that distribution is permitted only in or among +countries not thus excluded. In such case, this License incorporates +the limitation as if written in the body of this License. + + 9. The Free Software Foundation may publish revised and/or new versions +of the General Public License from time to time. Such new versions will +be similar in spirit to the present version, but may differ in detail to +address new problems or concerns. + +Each version is given a distinguishing version number. If the Program +specifies a version number of this License which applies to it and "any +later version", you have the option of following the terms and conditions +either of that version or of any later version published by the Free +Software Foundation. If the Program does not specify a version number of +this License, you may choose any version ever published by the Free Software +Foundation. + + 10. If you wish to incorporate parts of the Program into other free +programs whose distribution conditions are different, write to the author +to ask for permission. For software which is copyrighted by the Free +Software Foundation, write to the Free Software Foundation; we sometimes +make exceptions for this. Our decision will be guided by the two goals +of preserving the free status of all derivatives of our free software and +of promoting the sharing and reuse of software generally. + + NO WARRANTY + + 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY +FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN +OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES +PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED +OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF +MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS +TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE +PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, +REPAIR OR CORRECTION. + + 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING +WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR +REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, +INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING +OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED +TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY +YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER +PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE +POSSIBILITY OF SUCH DAMAGES. + + END OF TERMS AND CONDITIONS + + How to Apply These Terms to Your New Programs + + If you develop a new program, and you want it to be of the greatest +possible use to the public, the best way to achieve this is to make it +free software which everyone can redistribute and change under these terms. + + To do so, attach the following notices to the program. It is safest +to attach them to the start of each source file to most effectively +convey the exclusion of warranty; and each file should have at least +the "copyright" line and a pointer to where the full notice is found. + + <one line to give the program's name and a brief idea of what it does.> + Copyright (C) <year> <name of author> + + 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; either version 2 of the License, or + (at your option) any later version. + + 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 + + +Also add information on how to contact you by electronic and paper mail. + +If the program is interactive, make it output a short notice like this +when it starts in an interactive mode: + + Gnomovision version 69, Copyright (C) year name of author + Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. + This is free software, and you are welcome to redistribute it + under certain conditions; type `show c' for details. + +The hypothetical commands `show w' and `show c' should show the appropriate +parts of the General Public License. Of course, the commands you use may +be called something other than `show w' and `show c'; they could even be +mouse-clicks or menu items--whatever suits your program. + +You should also get your employer (if you work as a programmer) or your +school, if any, to sign a "copyright disclaimer" for the program, if +necessary. Here is a sample; alter the names: + + Yoyodyne, Inc., hereby disclaims all copyright interest in the program + `Gnomovision' (which makes passes at compilers) written by James Hacker. + + <signature of Ty Coon>, 1 April 1989 + Ty Coon, President of Vice + +This General Public License does not permit incorporating your program into +proprietary programs. If your program is a subroutine library, you may +consider it more useful to permit linking proprietary applications with the +library. If this is what you want to do, use the GNU Library General +Public License instead of this License. diff --git a/extra/yassl/include/yassl_imp.hpp b/extra/yassl/include/yassl_imp.hpp index 838aace72c8..6e475c23db8 100644 --- a/extra/yassl/include/yassl_imp.hpp +++ b/extra/yassl/include/yassl_imp.hpp @@ -626,6 +626,7 @@ struct Connection { bool send_server_key_; // server key exchange? bool master_clean_; // master secret clean? bool TLS_; // TLSv1 or greater + bool sessionID_Set_; // do we have a session ProtocolVersion version_; RandomPool& random_; diff --git a/extra/yassl/src/yassl_imp.cpp b/extra/yassl/src/yassl_imp.cpp index 310e8819c54..98f8035732e 100644 --- a/extra/yassl/src/yassl_imp.cpp +++ b/extra/yassl/src/yassl_imp.cpp @@ -1172,7 +1172,8 @@ input_buffer& operator>>(input_buffer& input, ServerHello& hello) // Session hello.id_len_ = input[AUTO]; - input.read(hello.session_id_, ID_LEN); + if (hello.id_len_) + input.read(hello.session_id_, hello.id_len_); // Suites hello.cipher_suite_[0] = input[AUTO]; @@ -1215,7 +1216,10 @@ void ServerHello::Process(input_buffer&, SSL& ssl) { ssl.set_pending(cipher_suite_[1]); ssl.set_random(random_, server_end); + if (id_len_) ssl.set_sessionID(session_id_); + else + ssl.useSecurity().use_connection().sessionID_Set_ = false; if (ssl.getSecurity().get_resuming()) if (memcmp(session_id_, ssl.getSecurity().get_resume().GetID(), diff --git a/extra/yassl/src/yassl_int.cpp b/extra/yassl/src/yassl_int.cpp index 831942aaf69..9b83f964348 100644 --- a/extra/yassl/src/yassl_int.cpp +++ b/extra/yassl/src/yassl_int.cpp @@ -709,6 +709,7 @@ void SSL::set_masterSecret(const opaque* sec) void SSL::set_sessionID(const opaque* sessionID) { memcpy(secure_.use_connection().sessionID_, sessionID, ID_LEN); + secure_.use_connection().sessionID_Set_ = true; } @@ -1423,8 +1424,10 @@ typedef Mutex::Lock Lock; void Sessions::add(const SSL& ssl) { + if (ssl.getSecurity().get_connection().sessionID_Set_) { Lock guard(mutex_); list_.push_back(NEW_YS SSL_SESSION(ssl, random_)); + } } diff --git a/include/mysql.h b/include/mysql.h index 7ed205024e2..72e5c457d5a 100644 --- a/include/mysql.h +++ b/include/mysql.h @@ -848,7 +848,6 @@ int STDCALL mysql_drop_db(MYSQL *mysql, const char *DB); #define stmt_command(mysql, command, arg, length, stmt) \ (*(mysql)->methods->advanced_command)(mysql, command, NullS, \ 0, arg, length, 1, stmt) -unsigned long net_safe_read(MYSQL* mysql); #ifdef __NETWARE__ #pragma pack(pop) /* restore alignment */ diff --git a/include/mysql_com.h b/include/mysql_com.h index c65f5944747..196930fcb3f 100644 --- a/include/mysql_com.h +++ b/include/mysql_com.h @@ -144,7 +144,6 @@ enum enum_server_command #define SERVER_STATUS_IN_TRANS 1 /* Transaction has started */ #define SERVER_STATUS_AUTOCOMMIT 2 /* Server in auto_commit mode */ -#define SERVER_STATUS_MORE_RESULTS 4 /* More results on server */ #define SERVER_MORE_RESULTS_EXISTS 8 /* Multi query - next query exists */ #define SERVER_QUERY_NO_GOOD_INDEX_USED 16 #define SERVER_QUERY_NO_INDEX_USED 32 diff --git a/include/sql_common.h b/include/sql_common.h index 7ea8b6c87e0..29a9cbd4b08 100644 --- a/include/sql_common.h +++ b/include/sql_common.h @@ -36,7 +36,7 @@ cli_advanced_command(MYSQL *mysql, enum enum_server_command command, const char *header, ulong header_length, const char *arg, ulong arg_length, my_bool skip_check, MYSQL_STMT *stmt); - +unsigned long cli_safe_read(MYSQL *mysql); void set_stmt_errmsg(MYSQL_STMT * stmt, const char *err, int errcode, const char *sqlstate); void set_mysql_error(MYSQL *mysql, int errcode, const char *sqlstate); diff --git a/libmysql/libmysql.c b/libmysql/libmysql.c index c2e7df6f208..e80b142e419 100644 --- a/libmysql/libmysql.c +++ b/libmysql/libmysql.c @@ -639,7 +639,7 @@ int cli_read_change_user_result(MYSQL *mysql, char *buff, const char *passwd) NET *net= &mysql->net; ulong pkt_length; - pkt_length= net_safe_read(mysql); + pkt_length= cli_safe_read(mysql); if (pkt_length == packet_error) return 1; @@ -660,7 +660,7 @@ int cli_read_change_user_result(MYSQL *mysql, char *buff, const char *passwd) return 1; } /* Read what server thinks about out new auth message report */ - if (net_safe_read(mysql) == packet_error) + if (cli_safe_read(mysql) == packet_error) return 1; } return 0; @@ -1881,7 +1881,7 @@ my_bool cli_read_prepare_result(MYSQL *mysql, MYSQL_STMT *stmt) DBUG_ENTER("cli_read_prepare_result"); mysql= mysql->last_used_con; - if ((packet_length= net_safe_read(mysql)) == packet_error) + if ((packet_length= cli_safe_read(mysql)) == packet_error) DBUG_RETURN(1); mysql->warning_count= 0; @@ -2499,7 +2499,8 @@ int cli_stmt_execute(MYSQL_STMT *stmt) if (stmt->param_count) { - NET *net= &stmt->mysql->net; + MYSQL *mysql= stmt->mysql; + NET *net= &mysql->net; MYSQL_BIND *param, *param_end; char *param_data; ulong length; @@ -2511,7 +2512,8 @@ int cli_stmt_execute(MYSQL_STMT *stmt) set_stmt_error(stmt, CR_PARAMS_NOT_BOUND, unknown_sqlstate); DBUG_RETURN(1); } - if (stmt->mysql->status != MYSQL_STATUS_READY) + if (mysql->status != MYSQL_STATUS_READY || + mysql->server_status & SERVER_MORE_RESULTS_EXISTS) { set_stmt_error(stmt, CR_COMMANDS_OUT_OF_SYNC, unknown_sqlstate); DBUG_RETURN(1); @@ -4526,7 +4528,7 @@ static int stmt_fetch_row(MYSQL_STMT *stmt, uchar *row) int cli_unbuffered_fetch(MYSQL *mysql, char **row) { - if (packet_error == net_safe_read(mysql)) + if (packet_error == cli_safe_read(mysql)) return 1; *row= ((mysql->net.read_pos[0] == 254) ? NULL : @@ -4635,7 +4637,7 @@ int cli_read_binary_rows(MYSQL_STMT *stmt) mysql= mysql->last_used_con; - while ((pkt_len= net_safe_read(mysql)) != packet_error) + while ((pkt_len= cli_safe_read(mysql)) != packet_error) { cp= net->read_pos; if (cp[0] != 254 || pkt_len >= 8) diff --git a/mysql-test/include/im_check_env.inc b/mysql-test/include/im_check_env.inc new file mode 100644 index 00000000000..169edbac6b3 --- /dev/null +++ b/mysql-test/include/im_check_env.inc @@ -0,0 +1,27 @@ +# This file is intended to be used in each IM-test. It contains stamements, +# that ensure that starting conditions (environment) for the IM-test are as +# expected. + +# Wait for mysqld1 (guarded instance) to start. + +--exec $MYSQL_TEST_DIR/t/wait_for_process.sh $IM_MYSQLD1_PATH_PID 30 started + +# Check the running instances. + +--connect (mysql1_con,localhost,root,,mysql,$IM_MYSQLD1_PORT,$IM_MYSQLD1_SOCK) + +--connection mysql1_con + +SHOW VARIABLES LIKE 'server_id'; + +--connection default + +# Let IM detect that mysqld1 is online. This delay should be longer than +# monitoring interval. + +--sleep 2 + +# Check that IM understands that mysqld1 is online, while mysqld2 is +# offline. + +SHOW INSTANCES; diff --git a/mysql-test/mysql-test-run.pl b/mysql-test/mysql-test-run.pl index 5d6f39bc882..45accee56fb 100755 --- a/mysql-test/mysql-test-run.pl +++ b/mysql-test/mysql-test-run.pl @@ -190,6 +190,7 @@ our $exe_ndb_mgmd; our $exe_slave_mysqld; our $exe_im; our $exe_my_print_defaults; +our $exe_perror; our $lib_udf_example; our $exe_libtool; @@ -856,6 +857,12 @@ sub command_line_setup () { } } + # Check IM arguments + if ( $glob_win32 ) + { + mtr_report("Disable Instance manager - not supported on Windows"); + $opt_skip_im= 1; + } # Check valgrind arguments if ( $opt_valgrind or $opt_valgrind_path or defined $opt_valgrind_options) { @@ -1164,19 +1171,22 @@ sub executable_setup () { "$path_client_bindir/mysqld-max", "$path_client_bindir/mysqld-nt", "$path_client_bindir/mysqld", - "$path_client_bindir/mysqld-debug", "$path_client_bindir/mysqld-max", "$glob_basedir/sql/release/mysqld", "$glob_basedir/sql/debug/mysqld"); + "$path_client_bindir/mysqld-debug", $path_language= mtr_path_exists("$glob_basedir/share/english/", "$glob_basedir/sql/share/english/"); $path_charsetsdir= mtr_path_exists("$glob_basedir/share/charsets", "$glob_basedir/sql/share/charsets"); - $exe_my_print_defaults= mtr_exe_exists("$path_client_bindir/my_print_defaults", "$glob_basedir/extra/release/my_print_defaults", "$glob_basedir/extra/debug/my_print_defaults"); + $exe_perror= + mtr_exe_exists("$path_client_bindir/perror", + "$glob_basedir/extra/release/perror", + "$glob_basedir/extra/debug/perror"); } else { @@ -1190,6 +1200,8 @@ sub executable_setup () { "$glob_basedir/server-tools/instance-manager/mysqlmanager"); $exe_my_print_defaults= mtr_exe_exists("$glob_basedir/extra/my_print_defaults"); + $exe_perror= + mtr_exe_exists("$glob_basedir/extra/perror"); } if ( $glob_use_embedded_server ) @@ -1244,6 +1256,8 @@ sub executable_setup () { "/usr/bin/false"); $exe_my_print_defaults= mtr_exe_exists("$path_client_bindir/my_print_defaults"); + $exe_perror= + mtr_exe_exists("$path_client_bindir/perror"); $path_language= mtr_path_exists("$glob_basedir/share/mysql/english/", "$glob_basedir/share/english/"); @@ -3508,31 +3522,60 @@ sub im_stop($$) { } # Check if all processes shutdown cleanly - my $clean_shutdown= 1; # Assum they did + my $clean_shutdown= 0; - if (kill (0, $instance_manager->{'pid'})) + while (1) { - mtr_warning("IM-main is still alive."); - $clean_shutdown= 0; - } + # Check that IM-main died. - if (defined $instance_manager->{'angel_pid'} && - kill (0, $instance_manager->{'angel_pid'})) - { - mtr_warning("IM-angel is still alive."); - $clean_shutdown= 0; - } + if (kill (0, $instance_manager->{'pid'})) + { + mtr_debug("IM-main is still alive."); + last; + } - foreach my $pid (@mysqld_pids) - { - if (kill (0, $pid)) + # Check that IM-angel died. + + if (defined $instance_manager->{'angel_pid'} && + kill (0, $instance_manager->{'angel_pid'})) { - mtr_warning("Guarded mysqld ($pid) is still alive."); - $clean_shutdown= 0; + mtr_debug("IM-angel is still alive."); + last; } + + # Check that all guarded mysqld-instances died. + + my $guarded_mysqlds_dead= 1; + + foreach my $pid (@mysqld_pids) + { + if (kill (0, $pid)) + { + mtr_debug("Guarded mysqld ($pid) is still alive."); + $guarded_mysqlds_dead= 0; + last; + } + } + + last unless $guarded_mysqlds_dead; + + # Ok, all necessary processes are dead. + + $clean_shutdown= 1; + last; } # Kill leftovers (the order is important). + + if ($clean_shutdown) + { + mtr_debug("IM-shutdown was clean -- all processed died."); + } + else + { + mtr_debug("IM failed to shutdown gracefully. We have to clean the mess..."); + } + unless ($clean_shutdown) { @@ -3553,17 +3596,24 @@ sub im_stop($$) { mtr_kill_processes(\@mysqld_pids); # Complain in error log so that a warning will be shown. - - my $errlog= "$opt_vardir/log/mysql-test-run.pl.err"; - - open (ERRLOG, ">>$errlog") || - mtr_error("Can not open error log ($errlog)"); + # + # TODO: unless BUG#20761 is fixed, we will print the warning + # to stdout, so that it can be seen on console and does not + # produce pushbuild error. + + # my $errlog= "$opt_vardir/log/mysql-test-run.pl.err"; + # + # open (ERRLOG, ">>$errlog") || + # mtr_error("Can not open error log ($errlog)"); + # + # my $ts= localtime(); + # print ERRLOG + # "Warning: [$ts] Instance Manager did not shutdown gracefully.\n"; + # + # close ERRLOG; my $ts= localtime(); - print ERRLOG - "[$where] Warning: [$ts] Instance Manager did not shutdown gracefully.\n"; - - close ERRLOG; + print "[$where] Warning: [$ts] Instance Manager did not shutdown gracefully.\n"; } # That's all. @@ -3746,6 +3796,7 @@ sub run_mysqltest ($) { $ENV{'MYSQL_MY_PRINT_DEFAULTS'}= $exe_my_print_defaults; $ENV{'UDF_EXAMPLE_LIB'}= ($lib_udf_example ? basename($lib_udf_example) : ""); + $ENV{'MY_PERROR'}= $exe_perror; $ENV{'NDB_STATUS_OK'}= $clusters->[0]->{'installed_ok'}; $ENV{'NDB_SLAVE_STATUS_OK'}= $clusters->[0]->{'installed_ok'};; diff --git a/mysql-test/r/cast.result b/mysql-test/r/cast.result index 5e8f5dca711..27a36b0cb7c 100644 --- a/mysql-test/r/cast.result +++ b/mysql-test/r/cast.result @@ -381,3 +381,14 @@ DROP TABLE t1; select cast(NULL as decimal(6)) as t1; t1 NULL +set names latin1; +select hex(cast('a' as char(2) binary)); +hex(cast('a' as char(2) binary)) +61 +select hex(cast('a' as binary(2))); +hex(cast('a' as binary(2))) +6100 +select hex(cast('a' as char(2) binary)); +hex(cast('a' as char(2) binary)) +61 +End of 5.0 tests diff --git a/mysql-test/r/date_formats.result b/mysql-test/r/date_formats.result index ee70327d17b..017631bf8d1 100644 --- a/mysql-test/r/date_formats.result +++ b/mysql-test/r/date_formats.result @@ -452,6 +452,8 @@ create table t1 select str_to_date("2003-01-02 10:11:12.0012", "%Y-%m-%d %H:%i:% str_to_date("10:11:12.0012", "%H:%i:%S.%f") as f2, str_to_date("2003-01-02", "%Y-%m-%d") as f3, str_to_date("02", "%d") as f4, str_to_date("02 10", "%d %H") as f5; +Warnings: +Warning 1265 Data truncated for column 'f4' at row 1 describe t1; Field Type Null Key Default Extra f1 datetime YES NULL @@ -461,7 +463,7 @@ f4 date YES NULL f5 time YES NULL select * from t1; f1 f2 f3 f4 f5 -2003-01-02 10:11:12 10:11:12 2003-01-02 0000-00-02 58:00:00 +2003-01-02 10:11:12 10:11:12 2003-01-02 0000-00-00 58:00:00 drop table t1; create table t1 select "02 10" as a, "%d %H" as b; select str_to_date(a,b) from t1; diff --git a/mysql-test/r/delete.result b/mysql-test/r/delete.result index 05f1c967e77..0946dc8f809 100644 --- a/mysql-test/r/delete.result +++ b/mysql-test/r/delete.result @@ -192,3 +192,13 @@ delete t2.*,t3.* from t1,t2,t3 where t1.a=t2.a AND t2.b=t3.a and t1.b=t3.b; select * from t3; a b drop table t1,t2,t3; +create table t1(a date not null); +insert into t1 values (0); +select * from t1 where a is null; +a +0000-00-00 +delete from t1 where a is null; +select count(*) from t1; +count(*) +0 +drop table t1; diff --git a/mysql-test/r/federated.result b/mysql-test/r/federated.result index 97d138cfc76..77e2d251cb8 100644 --- a/mysql-test/r/federated.result +++ b/mysql-test/r/federated.result @@ -967,6 +967,8 @@ CREATE TABLE federated.t1 ( `blurb` text default '', PRIMARY KEY (blurb_id)) DEFAULT CHARSET=latin1; +Warnings: +Warning 1101 BLOB/TEXT column 'blurb' can't have a default value DROP TABLE IF EXISTS federated.t1; CREATE TABLE federated.t1 ( `blurb_id` int NOT NULL DEFAULT 0, @@ -975,6 +977,8 @@ PRIMARY KEY (blurb_id)) ENGINE="FEDERATED" DEFAULT CHARSET=latin1 CONNECTION='mysql://root@127.0.0.1:SLAVE_PORT/federated/t1'; +Warnings: +Warning 1101 BLOB/TEXT column 'blurb' can't have a default value INSERT INTO federated.t1 VALUES (1, " MySQL supports a number of column types in several categories: numeric types, date and time types, and string (character) types. This chapter first gives an overview of these column types, and then provides a more detailed description of the properties of the types in each category, and a summary of the column type storage requirements. The overview is intentionally brief. The more detailed descriptions should be consulted for additional information about particular column types, such as the allowable formats in which you can specify values."); INSERT INTO federated.t1 VALUES (2, "All arithmetic is done using signed BIGINT or DOUBLE values, so you should not use unsigned big integers larger than 9223372036854775807 (63 bits) except with bit functions! If you do that, some of the last digits in the result may be wrong because of rounding errors when converting a BIGINT value to a DOUBLE."); INSERT INTO federated.t1 VALUES (3, " A floating-point number. p represents the precision. It can be from 0 to 24 for a single-precision floating-point number and from 25 to 53 for a double-precision floating-point number. These types are like the FLOAT and DOUBLE types described immediately following. FLOAT(p) has the same range as the corresponding FLOAT and DOUBLE types, but the display size and number of decimals are undefined. "); diff --git a/mysql-test/r/fulltext_distinct.result b/mysql-test/r/fulltext_distinct.result index de0668ff28c..7fd42fab646 100644 --- a/mysql-test/r/fulltext_distinct.result +++ b/mysql-test/r/fulltext_distinct.result @@ -8,6 +8,8 @@ KEY kt(tag), KEY kv(value(15)), FULLTEXT KEY kvf(value) ) ENGINE=MyISAM; +Warnings: +Warning 1101 BLOB/TEXT column 'value' can't have a default value CREATE TABLE t2 ( id_t2 mediumint unsigned NOT NULL default '0', id_t1 mediumint unsigned NOT NULL default '0', diff --git a/mysql-test/r/fulltext_update.result b/mysql-test/r/fulltext_update.result index 5d3f95b318c..4a615c88fdd 100644 --- a/mysql-test/r/fulltext_update.result +++ b/mysql-test/r/fulltext_update.result @@ -9,6 +9,8 @@ name VARCHAR(80) DEFAULT '' NOT NULL, FULLTEXT(url,description,shortdesc,longdesc), PRIMARY KEY(gnr) ); +Warnings: +Warning 1101 BLOB/TEXT column 'longdesc' can't have a default value insert into test (url,shortdesc,longdesc,description,name) VALUES ("http:/test.at", "kurz", "lang","desc", "name"); insert into test (url,shortdesc,longdesc,description,name) VALUES diff --git a/mysql-test/r/func_compress.result b/mysql-test/r/func_compress.result index a4b780d146a..1a5e64978e6 100644 --- a/mysql-test/r/func_compress.result +++ b/mysql-test/r/func_compress.result @@ -79,3 +79,31 @@ uncompress(a) uncompressed_length(a) NULL NULL a 1 drop table t1; +create table t1 (a varchar(32) not null); +insert into t1 values ('foo'); +explain select * from t1 where uncompress(a) is null; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 system NULL NULL NULL NULL 1 +Warnings: +Error 1259 ZLIB: Input data corrupted +select * from t1 where uncompress(a) is null; +a +foo +Warnings: +Error 1259 ZLIB: Input data corrupted +explain select *, uncompress(a) from t1; +id select_type table type possible_keys key key_len ref rows Extra +1 SIMPLE t1 system NULL NULL NULL NULL 1 +select *, uncompress(a) from t1; +a uncompress(a) +foo NULL +Warnings: +Error 1259 ZLIB: Input data corrupted +select *, uncompress(a), uncompress(a) is null from t1; +a uncompress(a) uncompress(a) is null +foo NULL 1 +Warnings: +Error 1259 ZLIB: Input data corrupted +Error 1259 ZLIB: Input data corrupted +drop table t1; +End of 5.0 tests diff --git a/mysql-test/r/func_group.result b/mysql-test/r/func_group.result index 74da6478470..26cf94bb820 100644 --- a/mysql-test/r/func_group.result +++ b/mysql-test/r/func_group.result @@ -990,3 +990,17 @@ FROM t1 t, t2 c WHERE t.a = c.b; minid NULL DROP TABLE t1,t2; +create table t1 select variance(0); +show create table t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `variance(0)` double(8,4) default NULL +) ENGINE=MyISAM DEFAULT CHARSET=latin1 +drop table t1; +create table t1 select stddev(0); +show create table t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `stddev(0)` double(8,4) default NULL +) ENGINE=MyISAM DEFAULT CHARSET=latin1 +drop table t1; diff --git a/mysql-test/r/func_time.result b/mysql-test/r/func_time.result index 487d40f8a67..7f7228fbf4d 100644 --- a/mysql-test/r/func_time.result +++ b/mysql-test/r/func_time.result @@ -667,6 +667,78 @@ timestampdiff(SQL_TSI_DAY, '1996-02-01', '1996-03-01') as a3, timestampdiff(SQL_TSI_DAY, '2000-02-01', '2000-03-01') as a4; a1 a2 a3 a4 28 28 29 29 +SELECT TIMESTAMPDIFF(day,'2006-01-10 14:30:28','2006-01-11 14:30:27'); +TIMESTAMPDIFF(day,'2006-01-10 14:30:28','2006-01-11 14:30:27') +0 +SELECT TIMESTAMPDIFF(day,'2006-01-10 14:30:28','2006-01-11 14:30:28'); +TIMESTAMPDIFF(day,'2006-01-10 14:30:28','2006-01-11 14:30:28') +1 +SELECT TIMESTAMPDIFF(day,'2006-01-10 14:30:28','2006-01-11 14:30:29'); +TIMESTAMPDIFF(day,'2006-01-10 14:30:28','2006-01-11 14:30:29') +1 +SELECT TIMESTAMPDIFF(day,'2006-01-10 14:30:28','2006-01-12 14:30:27'); +TIMESTAMPDIFF(day,'2006-01-10 14:30:28','2006-01-12 14:30:27') +1 +SELECT TIMESTAMPDIFF(day,'2006-01-10 14:30:28','2006-01-12 14:30:28'); +TIMESTAMPDIFF(day,'2006-01-10 14:30:28','2006-01-12 14:30:28') +2 +SELECT TIMESTAMPDIFF(day,'2006-01-10 14:30:28','2006-01-12 14:30:29'); +TIMESTAMPDIFF(day,'2006-01-10 14:30:28','2006-01-12 14:30:29') +2 +SELECT TIMESTAMPDIFF(week,'2006-01-10 14:30:28','2006-01-17 14:30:27'); +TIMESTAMPDIFF(week,'2006-01-10 14:30:28','2006-01-17 14:30:27') +0 +SELECT TIMESTAMPDIFF(week,'2006-01-10 14:30:28','2006-01-17 14:30:28'); +TIMESTAMPDIFF(week,'2006-01-10 14:30:28','2006-01-17 14:30:28') +1 +SELECT TIMESTAMPDIFF(week,'2006-01-10 14:30:28','2006-01-17 14:30:29'); +TIMESTAMPDIFF(week,'2006-01-10 14:30:28','2006-01-17 14:30:29') +1 +SELECT TIMESTAMPDIFF(week,'2006-01-10 14:30:28','2006-01-24 14:30:27'); +TIMESTAMPDIFF(week,'2006-01-10 14:30:28','2006-01-24 14:30:27') +1 +SELECT TIMESTAMPDIFF(week,'2006-01-10 14:30:28','2006-01-24 14:30:28'); +TIMESTAMPDIFF(week,'2006-01-10 14:30:28','2006-01-24 14:30:28') +2 +SELECT TIMESTAMPDIFF(week,'2006-01-10 14:30:28','2006-01-24 14:30:29'); +TIMESTAMPDIFF(week,'2006-01-10 14:30:28','2006-01-24 14:30:29') +2 +SELECT TIMESTAMPDIFF(month,'2006-01-10 14:30:28','2006-02-10 14:30:27'); +TIMESTAMPDIFF(month,'2006-01-10 14:30:28','2006-02-10 14:30:27') +0 +SELECT TIMESTAMPDIFF(month,'2006-01-10 14:30:28','2006-02-10 14:30:28'); +TIMESTAMPDIFF(month,'2006-01-10 14:30:28','2006-02-10 14:30:28') +1 +SELECT TIMESTAMPDIFF(month,'2006-01-10 14:30:28','2006-02-10 14:30:29'); +TIMESTAMPDIFF(month,'2006-01-10 14:30:28','2006-02-10 14:30:29') +1 +SELECT TIMESTAMPDIFF(month,'2006-01-10 14:30:28','2006-03-10 14:30:27'); +TIMESTAMPDIFF(month,'2006-01-10 14:30:28','2006-03-10 14:30:27') +1 +SELECT TIMESTAMPDIFF(month,'2006-01-10 14:30:28','2006-03-10 14:30:28'); +TIMESTAMPDIFF(month,'2006-01-10 14:30:28','2006-03-10 14:30:28') +2 +SELECT TIMESTAMPDIFF(month,'2006-01-10 14:30:28','2006-03-10 14:30:29'); +TIMESTAMPDIFF(month,'2006-01-10 14:30:28','2006-03-10 14:30:29') +2 +SELECT TIMESTAMPDIFF(year,'2006-01-10 14:30:28','2007-01-10 14:30:27'); +TIMESTAMPDIFF(year,'2006-01-10 14:30:28','2007-01-10 14:30:27') +0 +SELECT TIMESTAMPDIFF(year,'2006-01-10 14:30:28','2007-01-10 14:30:28'); +TIMESTAMPDIFF(year,'2006-01-10 14:30:28','2007-01-10 14:30:28') +1 +SELECT TIMESTAMPDIFF(year,'2006-01-10 14:30:28','2007-01-10 14:30:29'); +TIMESTAMPDIFF(year,'2006-01-10 14:30:28','2007-01-10 14:30:29') +1 +SELECT TIMESTAMPDIFF(year,'2006-01-10 14:30:28','2008-01-10 14:30:27'); +TIMESTAMPDIFF(year,'2006-01-10 14:30:28','2008-01-10 14:30:27') +1 +SELECT TIMESTAMPDIFF(year,'2006-01-10 14:30:28','2008-01-10 14:30:28'); +TIMESTAMPDIFF(year,'2006-01-10 14:30:28','2008-01-10 14:30:28') +2 +SELECT TIMESTAMPDIFF(year,'2006-01-10 14:30:28','2008-01-10 14:30:29'); +TIMESTAMPDIFF(year,'2006-01-10 14:30:28','2008-01-10 14:30:29') +2 select date_add(time,INTERVAL 1 SECOND) from t1; date_add(time,INTERVAL 1 SECOND) NULL diff --git a/mysql-test/r/gis-rtree.result b/mysql-test/r/gis-rtree.result index e2e7a612dec..92fcbfcdc9e 100644 --- a/mysql-test/r/gis-rtree.result +++ b/mysql-test/r/gis-rtree.result @@ -804,6 +804,8 @@ INSERT INTO t2 SELECT GeomFromText(st) FROM t1; ERROR 22003: Cannot get geometry object from data you send to the GEOMETRY field drop table t1, t2; CREATE TABLE t1 (`geometry` geometry NOT NULL default '',SPATIAL KEY `gndx` (`geometry`(32))) ENGINE=MyISAM DEFAULT CHARSET=latin1; +Warnings: +Warning 1101 BLOB/TEXT column 'geometry' can't have a default value INSERT INTO t1 (geometry) VALUES (PolygonFromText('POLYGON((-18.6086111000 -66.9327777000, -18.6055555000 -66.8158332999, -18.7186111000 -66.8102777000, -18.7211111000 -66.9269443999, @@ -820,6 +822,8 @@ CREATE TABLE t1 ( c1 geometry NOT NULL default '', SPATIAL KEY i1 (c1(32)) ) ENGINE=MyISAM DEFAULT CHARSET=latin1; +Warnings: +Warning 1101 BLOB/TEXT column 'c1' can't have a default value INSERT INTO t1 (c1) VALUES ( PolygonFromText('POLYGON((-18.6086111000 -66.9327777000, -18.6055555000 -66.8158332999, @@ -834,6 +838,8 @@ CREATE TABLE t1 ( c1 geometry NOT NULL default '', SPATIAL KEY i1 (c1(32)) ) ENGINE=MyISAM DEFAULT CHARSET=latin1; +Warnings: +Warning 1101 BLOB/TEXT column 'c1' can't have a default value INSERT INTO t1 (c1) VALUES ( PolygonFromText('POLYGON((-18.6086111000 -66.9327777000, -18.6055555000 -66.8158332999, diff --git a/mysql-test/r/gis.result b/mysql-test/r/gis.result index 9017e96c8f4..8fff04508d1 100644 --- a/mysql-test/r/gis.result +++ b/mysql-test/r/gis.result @@ -583,6 +583,8 @@ t1 CREATE TABLE `t1` ( drop table t1; CREATE TABLE `t1` (`object_id` bigint(20) unsigned NOT NULL default '0', `geo` geometry NOT NULL default '') ENGINE=MyISAM ; +Warnings: +Warning 1101 BLOB/TEXT column 'geo' can't have a default value insert into t1 values ('85984',GeomFromText('MULTIPOLYGON(((-115.006363 36.305435,-114.992394 36.305202,-114.991219 36.305975,-114.991163 36.306845,-114.989432 36.309452,-114.978275 36.312642,-114.977363 diff --git a/mysql-test/r/have_perror.require b/mysql-test/r/have_perror.require new file mode 100644 index 00000000000..260687c87f0 --- /dev/null +++ b/mysql-test/r/have_perror.require @@ -0,0 +1,2 @@ +have_perror +1 diff --git a/mysql-test/r/im_daemon_life_cycle.result b/mysql-test/r/im_daemon_life_cycle.result index a5526a31384..927ea86dfdd 100644 --- a/mysql-test/r/im_daemon_life_cycle.result +++ b/mysql-test/r/im_daemon_life_cycle.result @@ -1,4 +1,7 @@ Success: the process has been started. +SHOW VARIABLES LIKE 'server_id'; +Variable_name Value +server_id 1 SHOW INSTANCES; instance_name state mysqld1 online diff --git a/mysql-test/r/im_utils.result b/mysql-test/r/im_utils.result index df20a7fb5c7..ee70d7950f8 100644 --- a/mysql-test/r/im_utils.result +++ b/mysql-test/r/im_utils.result @@ -1,4 +1,7 @@ Success: the process has been started. +SHOW VARIABLES LIKE 'server_id'; +Variable_name Value +server_id 1 SHOW INSTANCES; instance_name state mysqld1 online diff --git a/mysql-test/r/join_outer.result b/mysql-test/r/join_outer.result index b199ec5b2fb..aca47a675d4 100644 --- a/mysql-test/r/join_outer.result +++ b/mysql-test/r/join_outer.result @@ -598,6 +598,8 @@ id int(11) DEFAULT '0' NOT NULL, name tinytext DEFAULT '' NOT NULL, UNIQUE id (id) ); +Warnings: +Warning 1101 BLOB/TEXT column 'name' can't have a default value INSERT INTO t1 VALUES (1,'yes'),(2,'no'); CREATE TABLE t2 ( id int(11) DEFAULT '0' NOT NULL, diff --git a/mysql-test/r/mysql.result b/mysql-test/r/mysql.result index d70366a7589..c133e4eb2cb 100644 --- a/mysql-test/r/mysql.result +++ b/mysql-test/r/mysql.result @@ -104,4 +104,14 @@ c_cp932 | 2 | NULL | | 3 | | +------+------+ +create table t1(a int, b varchar(255), c int); +Field Type Null Key Default Extra +a int(11) YES NULL +b varchar(255) YES NULL +c int(11) YES NULL +Field Type Null Key Default Extra +a int(11) YES NULL +b varchar(255) YES NULL +c int(11) YES NULL +drop table t1; End of 5.0 tests diff --git a/mysql-test/r/mysqlcheck.result b/mysql-test/r/mysqlcheck.result index a3c14b13bde..a76402a87b0 100644 --- a/mysql-test/r/mysqlcheck.result +++ b/mysql-test/r/mysqlcheck.result @@ -48,3 +48,10 @@ mysql.time_zone_name OK mysql.time_zone_transition OK mysql.time_zone_transition_type OK mysql.user OK +create table t1 (a int); +create view v1 as select * from t1; +test.t1 OK +test.t1 OK +drop view v1; +drop table t1; +End of 5.0 tests diff --git a/mysql-test/r/mysqldump.result b/mysql-test/r/mysqldump.result index 153ddb7ca2b..9d44756f17c 100644 --- a/mysql-test/r/mysqldump.result +++ b/mysql-test/r/mysqldump.result @@ -2324,7 +2324,7 @@ RETURN a+b */;; /*!50003 SET SESSION SQL_MODE=@OLD_SQL_MODE*/;; /*!50003 DROP FUNCTION IF EXISTS `bug9056_func2` */;; /*!50003 SET SESSION SQL_MODE=""*/;; -/*!50003 CREATE*/ /*!50020 DEFINER=`root`@`localhost`*/ /*!50003 FUNCTION `bug9056_func2`(f1 char binary) RETURNS char(1) +/*!50003 CREATE*/ /*!50020 DEFINER=`root`@`localhost`*/ /*!50003 FUNCTION `bug9056_func2`(f1 char binary) RETURNS char(1) CHARSET latin1 begin set f1= concat( 'hello', f1 ); return f1; @@ -2914,6 +2914,22 @@ drop view v1; drop table t1; drop database mysqldump_dbb; use test; +create user mysqltest_1; +create table t1(a int, b varchar(34)); +reset master; +mysqldump: Couldn't execute 'FLUSH TABLES': Access denied; you need the RELOAD privilege for this operation (1227) +mysqldump: Couldn't execute 'FLUSH TABLES': Access denied; you need the RELOAD privilege for this operation (1227) +grant RELOAD on *.* to mysqltest_1@localhost; +mysqldump: Couldn't execute 'SHOW MASTER STATUS': Access denied; you need the SUPER,REPLICATION CLIENT privilege for this operation (1227) +mysqldump: Couldn't execute 'SHOW MASTER STATUS': Access denied; you need the SUPER,REPLICATION CLIENT privilege for this operation (1227) +grant REPLICATION CLIENT on *.* to mysqltest_1@localhost; +CHANGE MASTER TO MASTER_LOG_FILE='master-bin.000001', MASTER_LOG_POS=537; +CREATE TABLE `t1` ( + `a` int(11) default NULL, + `b` varchar(34) default NULL +) ENGINE=MyISAM DEFAULT CHARSET=latin1; +drop table t1; +drop user mysqltest_1; End of 5.0 tests create table t1 (a text , b text); create table t2 (a text , b text); diff --git a/mysql-test/r/mysqlshow.result b/mysql-test/r/mysqlshow.result index 942cde83f21..2bf8a58de4e 100644 --- a/mysql-test/r/mysqlshow.result +++ b/mysql-test/r/mysqlshow.result @@ -75,3 +75,52 @@ Database: test 2 rows in set. DROP TABLE t1, t2; +Database: information_schema ++---------------------------------------+ +| Tables | ++---------------------------------------+ +| CHARACTER_SETS | +| COLLATIONS | +| COLLATION_CHARACTER_SET_APPLICABILITY | +| COLUMNS | +| COLUMN_PRIVILEGES | +| KEY_COLUMN_USAGE | +| ROUTINES | +| SCHEMATA | +| SCHEMA_PRIVILEGES | +| STATISTICS | +| TABLES | +| TABLE_CONSTRAINTS | +| TABLE_PRIVILEGES | +| TRIGGERS | +| USER_PRIVILEGES | +| VIEWS | ++---------------------------------------+ +Database: INFORMATION_SCHEMA ++---------------------------------------+ +| Tables | ++---------------------------------------+ +| CHARACTER_SETS | +| COLLATIONS | +| COLLATION_CHARACTER_SET_APPLICABILITY | +| COLUMNS | +| COLUMN_PRIVILEGES | +| KEY_COLUMN_USAGE | +| ROUTINES | +| SCHEMATA | +| SCHEMA_PRIVILEGES | +| STATISTICS | +| TABLES | +| TABLE_CONSTRAINTS | +| TABLE_PRIVILEGES | +| TRIGGERS | +| USER_PRIVILEGES | +| VIEWS | ++---------------------------------------+ +Wildcard: inf_rmation_schema ++--------------------+ +| Databases | ++--------------------+ +| information_schema | ++--------------------+ +End of 5.0 tests diff --git a/mysql-test/r/mysqltest.result b/mysql-test/r/mysqltest.result index ef4dd83564b..a50b1dfd5ab 100644 --- a/mysql-test/r/mysqltest.result +++ b/mysql-test/r/mysqltest.result @@ -440,6 +440,13 @@ select-me ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'insertz error query' at line 1 drop table t1; drop table t1; +sleep; +ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'sleep' at line 1 +sleep; +ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'sleep' at line 1 +; +ERROR 42000: Query was empty +End of 5.0 tests select "b" as col1, "c" as col2; col1 col2 b c diff --git a/mysql-test/r/ndb_basic.result b/mysql-test/r/ndb_basic.result index 631165d9fc8..997c7bae1d6 100644 --- a/mysql-test/r/ndb_basic.result +++ b/mysql-test/r/ndb_basic.result @@ -748,6 +748,8 @@ f1 f2 f3 111111 aaaaaa 1 222222 bbbbbb 2 drop table t1; +Illegal ndb error code: 1186 +Enf of 5.0 tests CREATE TABLE t1 (a VARCHAR(255) NOT NULL, CONSTRAINT pk_a PRIMARY KEY (a))engine=ndb; CREATE TABLE t2(a VARCHAR(255) NOT NULL, diff --git a/mysql-test/r/order_by.result b/mysql-test/r/order_by.result index a36935a583d..9756ab49ac7 100644 --- a/mysql-test/r/order_by.result +++ b/mysql-test/r/order_by.result @@ -280,6 +280,8 @@ info text NOT NULL default '', ipnr varchar(30) NOT NULL default '', PRIMARY KEY (member_id) ) ENGINE=MyISAM PACK_KEYS=1; +Warnings: +Warning 1101 BLOB/TEXT column 'info' can't have a default value insert into t1 (member_id) values (1),(2),(3); select member_id, nickname, voornaam FROM t1 ORDER by lastchange_datum DESC LIMIT 2; diff --git a/mysql-test/r/perror.result b/mysql-test/r/perror.result new file mode 100644 index 00000000000..4946523bc42 --- /dev/null +++ b/mysql-test/r/perror.result @@ -0,0 +1 @@ +Illegal error code: 10000 diff --git a/mysql-test/r/rpl_sp.result b/mysql-test/r/rpl_sp.result index 24c0a73c717..261e7cb072c 100644 --- a/mysql-test/r/rpl_sp.result +++ b/mysql-test/r/rpl_sp.result @@ -420,4 +420,48 @@ SELECT * FROM t1; col test DROP PROCEDURE p1; + +---> Test for BUG#20438 + +---> Preparing environment... +---> connection: master +DROP PROCEDURE IF EXISTS p1; +DROP FUNCTION IF EXISTS f1; + +---> Synchronizing slave with master... + +---> connection: master + +---> Creating procedure... +/*!50003 CREATE PROCEDURE p1() SET @a = 1 */; +/*!50003 CREATE FUNCTION f1() RETURNS INT RETURN 0 */; + +---> Checking on master... +SHOW CREATE PROCEDURE p1; +Procedure sql_mode Create Procedure +p1 CREATE DEFINER=`root`@`localhost` PROCEDURE `p1`() +SET @a = 1 +SHOW CREATE FUNCTION f1; +Function sql_mode Create Function +f1 CREATE DEFINER=`root`@`localhost` FUNCTION `f1`() RETURNS int(11) +RETURN 0 + +---> Synchronizing slave with master... +---> connection: master + +---> Checking on slave... +SHOW CREATE PROCEDURE p1; +Procedure sql_mode Create Procedure +p1 CREATE DEFINER=`root`@`localhost` PROCEDURE `p1`() +SET @a = 1 +SHOW CREATE FUNCTION f1; +Function sql_mode Create Function +f1 CREATE DEFINER=`root`@`localhost` FUNCTION `f1`() RETURNS int(11) +RETURN 0 + +---> connection: master + +---> Cleaning up... +DROP PROCEDURE p1; +DROP FUNCTION f1; drop table t1; diff --git a/mysql-test/r/rpl_trigger.result b/mysql-test/r/rpl_trigger.result index 53ec2c59cf3..bd6d6e63d57 100644 --- a/mysql-test/r/rpl_trigger.result +++ b/mysql-test/r/rpl_trigger.result @@ -899,3 +899,50 @@ Tables_in_test (t_) SHOW TRIGGERS; Trigger Event Table Statement Timing Created sql_mode Definer RESET MASTER; +START SLAVE; + +---> Test for BUG#20438 + +---> Preparing environment... +---> connection: master +DROP TABLE IF EXISTS t1; +DROP TABLE IF EXISTS t2; + +---> Synchronizing slave with master... + +---> connection: master + +---> Creating objects... +CREATE TABLE t1(c INT); +CREATE TABLE t2(c INT); +/*!50003 CREATE TRIGGER t1_bi BEFORE INSERT ON t1 +FOR EACH ROW +INSERT INTO t2 VALUES(NEW.c * 10) */; + +---> Inserting value... +INSERT INTO t1 VALUES(1); + +---> Checking on master... +SELECT * FROM t1; +c +1 +SELECT * FROM t2; +c +10 + +---> Synchronizing slave with master... +---> connection: master + +---> Checking on slave... +SELECT * FROM t1; +c +1 +SELECT * FROM t2; +c +10 + +---> connection: master + +---> Cleaning up... +DROP TABLE t1; +DROP TABLE t2; diff --git a/mysql-test/r/rpl_view.result b/mysql-test/r/rpl_view.result index f038f4d00cb..4e1a7153b65 100644 --- a/mysql-test/r/rpl_view.result +++ b/mysql-test/r/rpl_view.result @@ -43,3 +43,40 @@ drop view v1; select * from v1 order by a; ERROR 42S02: Table 'test.v1' doesn't exist drop table t1; + +---> Test for BUG#20438 + +---> Preparing environment... +---> connection: master +DROP TABLE IF EXISTS t1; +DROP VIEW IF EXISTS v1; + +---> Synchronizing slave with master... + +---> connection: master + +---> Creating objects... +CREATE TABLE t1(c INT); +/*!50003 CREATE VIEW v1 AS SELECT * FROM t1 */; + +---> Inserting value... +INSERT INTO t1 VALUES(1); + +---> Checking on master... +SELECT * FROM t1; +c +1 + +---> Synchronizing slave with master... +---> connection: master + +---> Checking on slave... +SELECT * FROM t1; +c +1 + +---> connection: master + +---> Cleaning up... +DROP VIEW v1; +DROP TABLE t1; diff --git a/mysql-test/r/show_check.result b/mysql-test/r/show_check.result index f5b3fc99baf..465cb853581 100644 --- a/mysql-test/r/show_check.result +++ b/mysql-test/r/show_check.result @@ -692,3 +692,20 @@ Warning 1541 The syntax 'SHOW PLUGIN' is deprecated and will be removed in MySQL show plugin; show plugins; End of 5.1 tests +CREATE PROCEDURE p1() +BEGIN +SET @s= 'CREATE VIEW v1 AS SELECT SQL_CACHE 1'; +PREPARE stmt FROM @s; +EXECUTE stmt; +DROP PREPARE stmt; +END | +CALL p1(); +SHOW CREATE VIEW v1; +View Create View +v1 CREATE ALGORITHM=UNDEFINED DEFINER=`root`@`localhost` SQL SECURITY DEFINER VIEW `v1` AS select sql_cache 1 AS `1` +DROP PROCEDURE p1; +DROP VIEW v1; +SHOW TABLES FROM no_such_database; +ERROR 42000: Unknown database 'no_such_database' +SHOW COLUMNS FROM no_such_table; +ERROR 42S02: Table 'test.no_such_table' doesn't exist diff --git a/mysql-test/r/sp-code.result b/mysql-test/r/sp-code.result index 8bdb9a724d7..4ae38861d29 100644 --- a/mysql-test/r/sp-code.result +++ b/mysql-test/r/sp-code.result @@ -155,11 +155,11 @@ Pos Instruction 0 stmt 9 "drop temporary table if exists sudoku..." 1 stmt 1 "create temporary table sudoku_work ( ..." 2 stmt 1 "create temporary table sudoku_schedul..." -3 stmt 95 "call sudoku_init(" +3 stmt 95 "call sudoku_init()" 4 jump_if_not 7(8) p_naive@0 5 stmt 4 "update sudoku_work set cnt = 0 where ..." 6 jump 8 -7 stmt 95 "call sudoku_count(" +7 stmt 95 "call sudoku_count()" 8 stmt 6 "insert into sudoku_schedule (row,col)..." 9 set v_scounter@2 0 10 set v_i@3 1 @@ -199,3 +199,10 @@ Pos Instruction 44 jump 14 45 stmt 9 "drop temporary table sudoku_work, sud..." drop procedure sudoku_solve; +DROP PROCEDURE IF EXISTS p1; +CREATE PROCEDURE p1() CREATE INDEX idx ON t1 (c1); +SHOW PROCEDURE CODE p1; +Pos Instruction +0 stmt 2 "CREATE INDEX idx ON t1 (c1)" +DROP PROCEDURE p1; +End of 5.0 tests. diff --git a/mysql-test/r/sp-error.result b/mysql-test/r/sp-error.result index 63401845f23..2b01415c2d0 100644 --- a/mysql-test/r/sp-error.result +++ b/mysql-test/r/sp-error.result @@ -1174,6 +1174,19 @@ drop procedure bug15091; drop function if exists bug16896; create aggregate function bug16896() returns int return 1; ERROR 42000: AGGREGATE is not supported for stored functions +DROP PROCEDURE IF EXISTS bug14702; +CREATE IF NOT EXISTS PROCEDURE bug14702() +BEGIN +END; +ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'IF NOT EXISTS PROCEDURE bug14702() +BEGIN +END' at line 1 +CREATE PROCEDURE IF NOT EXISTS bug14702() +BEGIN +END; +ERROR 42000: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'IF NOT EXISTS bug14702() +BEGIN +END' at line 1 drop function if exists bug16164; create function bug16164() returns int begin diff --git a/mysql-test/r/sp-security.result b/mysql-test/r/sp-security.result index 4860058a8a1..5272bf47672 100644 --- a/mysql-test/r/sp-security.result +++ b/mysql-test/r/sp-security.result @@ -441,3 +441,55 @@ SELECT Host,User,Password FROM mysql.user WHERE User='user19857'; Host User Password localhost user19857 *82DC221D557298F6CE9961037DB1C90604792F5C DROP USER user19857@localhost; +DROP TABLE IF EXISTS t1; +DROP VIEW IF EXISTS v1; +DROP FUNCTION IF EXISTS f_suid; +DROP PROCEDURE IF EXISTS p_suid; +DROP FUNCTION IF EXISTS f_evil; +DELETE FROM mysql.user WHERE user LIKE 'mysqltest\_%'; +DELETE FROM mysql.db WHERE user LIKE 'mysqltest\_%'; +DELETE FROM mysql.tables_priv WHERE user LIKE 'mysqltest\_%'; +DELETE FROM mysql.columns_priv WHERE user LIKE 'mysqltest\_%'; +FLUSH PRIVILEGES; +CREATE TABLE t1 (i INT); +CREATE FUNCTION f_suid(i INT) RETURNS INT SQL SECURITY DEFINER RETURN 0; +CREATE PROCEDURE p_suid(IN i INT) SQL SECURITY DEFINER SET @c:= 0; +CREATE USER mysqltest_u1@localhost; +GRANT EXECUTE ON test.* TO mysqltest_u1@localhost; +CREATE DEFINER=mysqltest_u1@localhost FUNCTION f_evil () RETURNS INT +SQL SECURITY INVOKER +BEGIN +SET @a:= CURRENT_USER(); +SET @b:= (SELECT COUNT(*) FROM t1); +RETURN @b; +END| +CREATE SQL SECURITY INVOKER VIEW v1 AS SELECT f_evil(); +SELECT COUNT(*) FROM t1; +ERROR 42000: SELECT command denied to user 'mysqltest_u1'@'localhost' for table 't1' +SELECT f_evil(); +ERROR 42000: SELECT command denied to user 'mysqltest_u1'@'localhost' for table 't1' +SELECT @a, @b; +@a @b +mysqltest_u1@localhost NULL +SELECT f_suid(f_evil()); +ERROR 42000: SELECT command denied to user 'mysqltest_u1'@'localhost' for table 't1' +SELECT @a, @b; +@a @b +mysqltest_u1@localhost NULL +CALL p_suid(f_evil()); +ERROR 42000: SELECT command denied to user 'mysqltest_u1'@'localhost' for table 't1' +SELECT @a, @b; +@a @b +mysqltest_u1@localhost NULL +SELECT * FROM v1; +ERROR 42000: SELECT command denied to user 'mysqltest_u1'@'localhost' for table 'v1' +SELECT @a, @b; +@a @b +mysqltest_u1@localhost NULL +DROP VIEW v1; +DROP FUNCTION f_evil; +DROP USER mysqltest_u1@localhost; +DROP PROCEDURE p_suid; +DROP FUNCTION f_suid; +DROP TABLE t1; +End of 5.0 tests. diff --git a/mysql-test/r/sp.result b/mysql-test/r/sp.result index 8ff180044df..e768ebe36b3 100644 --- a/mysql-test/r/sp.result +++ b/mysql-test/r/sp.result @@ -5057,6 +5057,205 @@ concat('data was: /', var1, '/') data was: /1/ drop table t3| drop procedure bug15217| +DROP PROCEDURE IF EXISTS bug21013 | +CREATE PROCEDURE bug21013(IN lim INT) +BEGIN +DECLARE i INT DEFAULT 0; +WHILE (i < lim) DO +SET @b = LOCATE(_latin1'b', @a, 1); +SET i = i + 1; +END WHILE; +END | +SET @a = _latin2"aaaaaaaaaa" | +CALL bug21013(10) | +DROP PROCEDURE bug21013 | +DROP DATABASE IF EXISTS mysqltest1| +DROP DATABASE IF EXISTS mysqltest2| +CREATE DATABASE mysqltest1 DEFAULT CHARACTER SET utf8| +CREATE DATABASE mysqltest2 DEFAULT CHARACTER SET utf8| +use mysqltest1| +CREATE FUNCTION bug16211_f1() RETURNS CHAR(10) +RETURN ""| +CREATE FUNCTION bug16211_f2() RETURNS CHAR(10) CHARSET koi8r +RETURN ""| +CREATE FUNCTION mysqltest2.bug16211_f3() RETURNS CHAR(10) +RETURN ""| +CREATE FUNCTION mysqltest2.bug16211_f4() RETURNS CHAR(10) CHARSET koi8r +RETURN ""| +SHOW CREATE FUNCTION bug16211_f1| +Function sql_mode Create Function +bug16211_f1 CREATE DEFINER=`root`@`localhost` FUNCTION `bug16211_f1`() RETURNS char(10) CHARSET utf8 +RETURN "" +SHOW CREATE FUNCTION bug16211_f2| +Function sql_mode Create Function +bug16211_f2 CREATE DEFINER=`root`@`localhost` FUNCTION `bug16211_f2`() RETURNS char(10) CHARSET koi8r +RETURN "" +SHOW CREATE FUNCTION mysqltest2.bug16211_f3| +Function sql_mode Create Function +bug16211_f3 CREATE DEFINER=`root`@`localhost` FUNCTION `bug16211_f3`() RETURNS char(10) CHARSET utf8 +RETURN "" +SHOW CREATE FUNCTION mysqltest2.bug16211_f4| +Function sql_mode Create Function +bug16211_f4 CREATE DEFINER=`root`@`localhost` FUNCTION `bug16211_f4`() RETURNS char(10) CHARSET koi8r +RETURN "" +SELECT dtd_identifier +FROM INFORMATION_SCHEMA.ROUTINES +WHERE ROUTINE_SCHEMA = "mysqltest1" AND ROUTINE_NAME = "bug16211_f1"| +dtd_identifier +char(10) CHARSET utf8 +SELECT dtd_identifier +FROM INFORMATION_SCHEMA.ROUTINES +WHERE ROUTINE_SCHEMA = "mysqltest1" AND ROUTINE_NAME = "bug16211_f2"| +dtd_identifier +char(10) CHARSET koi8r +SELECT dtd_identifier +FROM INFORMATION_SCHEMA.ROUTINES +WHERE ROUTINE_SCHEMA = "mysqltest2" AND ROUTINE_NAME = "bug16211_f3"| +dtd_identifier +char(10) CHARSET utf8 +SELECT dtd_identifier +FROM INFORMATION_SCHEMA.ROUTINES +WHERE ROUTINE_SCHEMA = "mysqltest2" AND ROUTINE_NAME = "bug16211_f4"| +dtd_identifier +char(10) CHARSET koi8r +SELECT CHARSET(bug16211_f1())| +CHARSET(bug16211_f1()) +utf8 +SELECT CHARSET(bug16211_f2())| +CHARSET(bug16211_f2()) +koi8r +SELECT CHARSET(mysqltest2.bug16211_f3())| +CHARSET(mysqltest2.bug16211_f3()) +utf8 +SELECT CHARSET(mysqltest2.bug16211_f4())| +CHARSET(mysqltest2.bug16211_f4()) +koi8r +ALTER DATABASE mysqltest1 CHARACTER SET cp1251| +ALTER DATABASE mysqltest2 CHARACTER SET cp1251| +SHOW CREATE FUNCTION bug16211_f1| +Function sql_mode Create Function +bug16211_f1 CREATE DEFINER=`root`@`localhost` FUNCTION `bug16211_f1`() RETURNS char(10) CHARSET utf8 +RETURN "" +SHOW CREATE FUNCTION bug16211_f2| +Function sql_mode Create Function +bug16211_f2 CREATE DEFINER=`root`@`localhost` FUNCTION `bug16211_f2`() RETURNS char(10) CHARSET koi8r +RETURN "" +SHOW CREATE FUNCTION mysqltest2.bug16211_f3| +Function sql_mode Create Function +bug16211_f3 CREATE DEFINER=`root`@`localhost` FUNCTION `bug16211_f3`() RETURNS char(10) CHARSET utf8 +RETURN "" +SHOW CREATE FUNCTION mysqltest2.bug16211_f4| +Function sql_mode Create Function +bug16211_f4 CREATE DEFINER=`root`@`localhost` FUNCTION `bug16211_f4`() RETURNS char(10) CHARSET koi8r +RETURN "" +SELECT dtd_identifier +FROM INFORMATION_SCHEMA.ROUTINES +WHERE ROUTINE_SCHEMA = "mysqltest1" AND ROUTINE_NAME = "bug16211_f1"| +dtd_identifier +char(10) CHARSET utf8 +SELECT dtd_identifier +FROM INFORMATION_SCHEMA.ROUTINES +WHERE ROUTINE_SCHEMA = "mysqltest1" AND ROUTINE_NAME = "bug16211_f2"| +dtd_identifier +char(10) CHARSET koi8r +SELECT dtd_identifier +FROM INFORMATION_SCHEMA.ROUTINES +WHERE ROUTINE_SCHEMA = "mysqltest2" AND ROUTINE_NAME = "bug16211_f3"| +dtd_identifier +char(10) CHARSET utf8 +SELECT dtd_identifier +FROM INFORMATION_SCHEMA.ROUTINES +WHERE ROUTINE_SCHEMA = "mysqltest2" AND ROUTINE_NAME = "bug16211_f4"| +dtd_identifier +char(10) CHARSET koi8r +SELECT CHARSET(bug16211_f1())| +CHARSET(bug16211_f1()) +utf8 +SELECT CHARSET(bug16211_f2())| +CHARSET(bug16211_f2()) +koi8r +SELECT CHARSET(mysqltest2.bug16211_f3())| +CHARSET(mysqltest2.bug16211_f3()) +utf8 +SELECT CHARSET(mysqltest2.bug16211_f4())| +CHARSET(mysqltest2.bug16211_f4()) +koi8r +use test| +DROP DATABASE mysqltest1| +DROP DATABASE mysqltest2| +DROP DATABASE IF EXISTS mysqltest1| +CREATE DATABASE mysqltest1 DEFAULT CHARACTER SET utf8| +use mysqltest1| +CREATE PROCEDURE bug16676_p1( +IN p1 CHAR(10), +INOUT p2 CHAR(10), +OUT p3 CHAR(10)) +BEGIN +SELECT CHARSET(p1), COLLATION(p1); +SELECT CHARSET(p2), COLLATION(p2); +SELECT CHARSET(p3), COLLATION(p3); +END| +CREATE PROCEDURE bug16676_p2( +IN p1 CHAR(10) CHARSET koi8r, +INOUT p2 CHAR(10) CHARSET cp1251, +OUT p3 CHAR(10) CHARSET greek) +BEGIN +SELECT CHARSET(p1), COLLATION(p1); +SELECT CHARSET(p2), COLLATION(p2); +SELECT CHARSET(p3), COLLATION(p3); +END| +SET @v2 = 'b'| +SET @v3 = 'c'| +CALL bug16676_p1('a', @v2, @v3)| +CHARSET(p1) COLLATION(p1) +utf8 utf8_general_ci +CHARSET(p2) COLLATION(p2) +utf8 utf8_general_ci +CHARSET(p3) COLLATION(p3) +utf8 utf8_general_ci +CALL bug16676_p2('a', @v2, @v3)| +CHARSET(p1) COLLATION(p1) +koi8r koi8r_general_ci +CHARSET(p2) COLLATION(p2) +cp1251 cp1251_general_ci +CHARSET(p3) COLLATION(p3) +greek greek_general_ci +use test| +DROP DATABASE mysqltest1| +drop procedure if exists bug19862| +CREATE TABLE t11 (a INT)| +CREATE TABLE t12 (a INT)| +CREATE FUNCTION bug19862(x INT) RETURNS INT +BEGIN +INSERT INTO t11 VALUES (x); +RETURN x+1; +END| +INSERT INTO t12 VALUES (1), (2)| +SELECT bug19862(a) FROM t12 ORDER BY 1| +bug19862(a) +2 +3 +SELECT * FROM t11| +a +1 +2 +DROP TABLE t11, t12| +DROP FUNCTION bug19862| +drop table if exists t3| +drop database if exists mysqltest1| +create table t3 (a int)| +insert into t3 (a) values (1), (2)| +create database mysqltest1| +use mysqltest1| +drop database mysqltest1| +select database()| +database() +NULL +select * from (select 1 as a) as t1 natural join (select * from test.t3) as t2| +a +1 +use test| +drop table t3| drop table if exists t3| drop database if exists mysqltest1| create table t3 (a int)| diff --git a/mysql-test/r/strict.result b/mysql-test/r/strict.result index dd96dc6d983..4a8ca484329 100644 --- a/mysql-test/r/strict.result +++ b/mysql-test/r/strict.result @@ -5,7 +5,9 @@ select @@sql_mode; REAL_AS_FLOAT,PIPES_AS_CONCAT,ANSI_QUOTES,IGNORE_SPACE,ANSI,STRICT_TRANS_TABLES,STRICT_ALL_TABLES,NO_ZERO_IN_DATE,NO_ZERO_DATE,ERROR_FOR_DIVISION_BY_ZERO,TRADITIONAL,NO_AUTO_CREATE_USER DROP TABLE IF EXISTS t1; CREATE TABLE t1 (col1 date); -INSERT INTO t1 VALUES('2004-01-01'),('0000-10-31'),('2004-02-29'); +INSERT INTO t1 VALUES('2004-01-01'),('2004-02-29'); +INSERT INTO t1 VALUES('0000-10-31'); +ERROR 22007: Incorrect date value: '0000-10-31' for column 'col1' at row 1 INSERT INTO t1 VALUES('2004-0-31'); ERROR 22007: Incorrect date value: '2004-0-31' for column 'col1' at row 1 INSERT INTO t1 VALUES('2004-01-02'),('2004-0-31'); @@ -54,7 +56,6 @@ Warning 1265 Data truncated for column 'col1' at row 3 select * from t1; col1 2004-01-01 -0000-10-31 2004-02-29 2004-01-02 2004-01-03 @@ -121,7 +122,9 @@ col1 drop table t1; set @@sql_mode='ansi,traditional'; CREATE TABLE t1 (col1 datetime); -INSERT INTO t1 VALUES('2004-10-31 15:30:00'),('0000-10-31 15:30:00'),('2004-02-29 15:30:00'); +INSERT INTO t1 VALUES('2004-10-31 15:30:00'),('2004-02-29 15:30:00'); +INSERT INTO t1 VALUES('0000-10-31 15:30:00'); +ERROR 22007: Incorrect datetime value: '0000-10-31 15:30:00' for column 'col1' at row 1 INSERT INTO t1 VALUES('2004-0-31 15:30:00'); ERROR 22007: Incorrect datetime value: '2004-0-31 15:30:00' for column 'col1' at row 1 INSERT INTO t1 VALUES('2004-10-0 15:30:00'); @@ -141,7 +144,6 @@ ERROR 22007: Incorrect datetime value: '59' for column 'col1' at row 1 select * from t1; col1 2004-10-31 15:30:00 -0000-10-31 15:30:00 2004-02-29 15:30:00 drop table t1; CREATE TABLE t1 (col1 timestamp); @@ -204,6 +206,7 @@ INSERT INTO t1 (col1) VALUES (STR_TO_DATE('15.10.2004','%d.%m.%Y')); INSERT INTO t1 (col2) VALUES (STR_TO_DATE('15.10.2004 10.15','%d.%m.%Y %H.%i')); INSERT INTO t1 (col3) VALUES (STR_TO_DATE('15.10.2004 10.15','%d.%m.%Y %H.%i')); INSERT INTO t1 (col1) VALUES(STR_TO_DATE('31.10.0000 15.30','%d.%m.%Y %H.%i')); +ERROR 22007: Incorrect date value: '0000-10-31 15:30:00' for column 'col1' at row 1 INSERT INTO t1 (col1) VALUES(STR_TO_DATE('31.0.2004 15.30','%d.%m.%Y %H.%i')); ERROR 22007: Incorrect date value: '2004-00-31 15:30:00' for column 'col1' at row 1 INSERT INTO t1 (col1) VALUES(STR_TO_DATE('0.10.2004 15.30','%d.%m.%Y %H.%i')); @@ -219,6 +222,7 @@ ERROR HY000: Incorrect datetime value: '15.13.2004 15.30' for function str_to_ti INSERT INTO t1 (col1) VALUES(STR_TO_DATE('00.00.0000','%d.%m.%Y')); ERROR 22007: Incorrect date value: '0000-00-00' for column 'col1' at row 1 INSERT INTO t1 (col2) VALUES(STR_TO_DATE('31.10.0000 15.30','%d.%m.%Y %H.%i')); +ERROR 22007: Incorrect datetime value: '0000-10-31 15:30:00' for column 'col2' at row 1 INSERT INTO t1 (col2) VALUES(STR_TO_DATE('31.0.2004 15.30','%d.%m.%Y %H.%i')); ERROR 22007: Incorrect datetime value: '2004-00-31 15:30:00' for column 'col2' at row 1 INSERT INTO t1 (col2) VALUES(STR_TO_DATE('0.10.2004 15.30','%d.%m.%Y %H.%i')); @@ -255,6 +259,7 @@ INSERT INTO t1 (col1) VALUES (CAST('2004-10-15' AS DATE)); INSERT INTO t1 (col2) VALUES (CAST('2004-10-15 10:15' AS DATETIME)); INSERT INTO t1 (col3) VALUES (CAST('2004-10-15 10:15' AS DATETIME)); INSERT INTO t1 (col1) VALUES(CAST('0000-10-31' AS DATE)); +ERROR 22007: Truncated incorrect datetime value: '0000-10-31' INSERT INTO t1 (col1) VALUES(CAST('2004-10-0' AS DATE)); ERROR 22007: Incorrect date value: '2004-10-00' for column 'col1' at row 1 INSERT INTO t1 (col1) VALUES(CAST('2004-0-10' AS DATE)); @@ -262,6 +267,7 @@ ERROR 22007: Incorrect date value: '2004-00-10' for column 'col1' at row 1 INSERT INTO t1 (col1) VALUES(CAST('0000-00-00' AS DATE)); ERROR 22007: Incorrect datetime value: '0000-00-00' INSERT INTO t1 (col2) VALUES(CAST('0000-10-31 15:30' AS DATETIME)); +ERROR 22007: Truncated incorrect datetime value: '0000-10-31 15:30' INSERT INTO t1 (col2) VALUES(CAST('2004-10-0 15:30' AS DATETIME)); ERROR 22007: Incorrect datetime value: '2004-10-00 15:30:00' for column 'col2' at row 1 INSERT INTO t1 (col2) VALUES(CAST('2004-0-10 15:30' AS DATETIME)); @@ -269,7 +275,7 @@ ERROR 22007: Incorrect datetime value: '2004-00-10 15:30:00' for column 'col2' a INSERT INTO t1 (col2) VALUES(CAST('0000-00-00' AS DATETIME)); ERROR 22007: Incorrect datetime value: '0000-00-00' INSERT INTO t1 (col3) VALUES(CAST('0000-10-31 15:30' AS DATETIME)); -ERROR 22007: Incorrect datetime value: '0000-10-31 15:30:00' for column 'col3' at row 1 +ERROR 22007: Truncated incorrect datetime value: '0000-10-31 15:30' INSERT INTO t1 (col3) VALUES(CAST('2004-10-0 15:30' AS DATETIME)); ERROR 22007: Incorrect datetime value: '2004-10-00 15:30:00' for column 'col3' at row 1 INSERT INTO t1 (col3) VALUES(CAST('2004-0-10 15:30' AS DATETIME)); @@ -282,6 +288,7 @@ INSERT INTO t1 (col1) VALUES (CONVERT('2004-10-15',DATE)); INSERT INTO t1 (col2) VALUES (CONVERT('2004-10-15 10:15',DATETIME)); INSERT INTO t1 (col3) VALUES (CONVERT('2004-10-15 10:15',DATETIME)); INSERT INTO t1 (col1) VALUES(CONVERT('0000-10-31' , DATE)); +ERROR 22007: Truncated incorrect datetime value: '0000-10-31' INSERT INTO t1 (col1) VALUES(CONVERT('2004-10-0' , DATE)); ERROR 22007: Incorrect date value: '2004-10-00' for column 'col1' at row 1 INSERT INTO t1 (col1) VALUES(CONVERT('2004-0-10' , DATE)); @@ -289,6 +296,7 @@ ERROR 22007: Incorrect date value: '2004-00-10' for column 'col1' at row 1 INSERT INTO t1 (col1) VALUES(CONVERT('0000-00-00',DATE)); ERROR 22007: Incorrect datetime value: '0000-00-00' INSERT INTO t1 (col2) VALUES(CONVERT('0000-10-31 15:30',DATETIME)); +ERROR 22007: Truncated incorrect datetime value: '0000-10-31 15:30' INSERT INTO t1 (col2) VALUES(CONVERT('2004-10-0 15:30',DATETIME)); ERROR 22007: Incorrect datetime value: '2004-10-00 15:30:00' for column 'col2' at row 1 INSERT INTO t1 (col2) VALUES(CONVERT('2004-0-10 15:30',DATETIME)); @@ -296,7 +304,7 @@ ERROR 22007: Incorrect datetime value: '2004-00-10 15:30:00' for column 'col2' a INSERT INTO t1 (col2) VALUES(CONVERT('0000-00-00',DATETIME)); ERROR 22007: Incorrect datetime value: '0000-00-00' INSERT INTO t1 (col3) VALUES(CONVERT('0000-10-31 15:30',DATETIME)); -ERROR 22007: Incorrect datetime value: '0000-10-31 15:30:00' for column 'col3' at row 1 +ERROR 22007: Truncated incorrect datetime value: '0000-10-31 15:30' INSERT INTO t1 (col3) VALUES(CONVERT('2004-10-0 15:30',DATETIME)); ERROR 22007: Incorrect datetime value: '2004-10-00 15:30:00' for column 'col3' at row 1 INSERT INTO t1 (col3) VALUES(CONVERT('2004-0-10 15:30',DATETIME)); diff --git a/mysql-test/r/type_blob.result b/mysql-test/r/type_blob.result index d05e9403d11..e5adad14267 100644 --- a/mysql-test/r/type_blob.result +++ b/mysql-test/r/type_blob.result @@ -503,6 +503,8 @@ foobar boggle fish 10 drop table t1; create table t1 (id integer auto_increment unique,imagem LONGBLOB not null default ''); +Warnings: +Warning 1101 BLOB/TEXT column 'imagem' can't have a default value insert into t1 (id) values (1); select charset(load_file('../../std_data/words.dat')), @@ -788,3 +790,21 @@ NULL 616100000000 620000000000 drop table t1; +create table t1 (a text default ''); +Warnings: +Warning 1101 BLOB/TEXT column 'a' can't have a default value +show create table t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `a` text +) ENGINE=MyISAM DEFAULT CHARSET=latin1 +insert into t1 values (default); +select * from t1; +a +NULL +drop table t1; +set @@sql_mode='TRADITIONAL'; +create table t1 (a text default ''); +ERROR 42000: BLOB/TEXT column 'a' can't have a default value +set @@sql_mode=''; +End of 5.0 tests diff --git a/mysql-test/r/type_datetime.result b/mysql-test/r/type_datetime.result index 6f1a45f27c5..3ae224879df 100644 --- a/mysql-test/r/type_datetime.result +++ b/mysql-test/r/type_datetime.result @@ -26,6 +26,8 @@ Table Op Msg_type Msg_text test.t1 check status OK delete from t1; insert into t1 values("000101"),("691231"),("700101"),("991231"),("00000101"),("00010101"),("99991231"),("00101000000"),("691231000000"),("700101000000"),("991231235959"),("10000101000000"),("99991231235959"),("20030100000000"),("20030000000000"); +Warnings: +Warning 1264 Out of range value adjusted for column 't' at row 5 insert into t1 values ("2003-003-03"); insert into t1 values ("20030102T131415"),("2001-01-01T01:01:01"), ("2001-1-1T1:01:01"); select * from t1; @@ -34,7 +36,7 @@ t 2069-12-31 00:00:00 1970-01-01 00:00:00 1999-12-31 00:00:00 -0000-01-01 00:00:00 +0000-00-00 00:00:00 0001-01-01 00:00:00 9999-12-31 00:00:00 2000-10-10 00:00:00 diff --git a/mysql-test/r/type_ranges.result b/mysql-test/r/type_ranges.result index 32bb6abf7ac..50867219fd8 100644 --- a/mysql-test/r/type_ranges.result +++ b/mysql-test/r/type_ranges.result @@ -38,6 +38,9 @@ KEY (ulong), KEY (ulonglong,ulong), KEY (options,flags) ); +Warnings: +Warning 1101 BLOB/TEXT column 'mediumblob_col' can't have a default value +Warning 1101 BLOB/TEXT column 'longblob_col' can't have a default value show full fields from t1; Field Type Collation Null Key Default Extra Privileges Comment auto int(5) unsigned NULL NO PRI NULL auto_increment # diff --git a/mysql-test/r/udf.result b/mysql-test/r/udf.result index 624895f71c9..a552282fece 100644 --- a/mysql-test/r/udf.result +++ b/mysql-test/r/udf.result @@ -93,6 +93,12 @@ NULL 0R FR DROP TABLE bug19904; +CREATE DEFINER=CURRENT_USER() FUNCTION should_not_parse +RETURNS STRING SONAME "should_not_parse.so"; +ERROR HY000: Incorrect usage of SONAME and DEFINER +CREATE DEFINER=someone@somewhere FUNCTION should_not_parse +RETURNS STRING SONAME "should_not_parse.so"; +ERROR HY000: Incorrect usage of SONAME and DEFINER create table t1(f1 int); insert into t1 values(1),(2); explain select myfunc_int(f1) from t1 order by 1; diff --git a/mysql-test/r/union.result b/mysql-test/r/union.result index b96f97b535c..42fbf0f6ff1 100644 --- a/mysql-test/r/union.result +++ b/mysql-test/r/union.result @@ -1318,7 +1318,7 @@ t2 CREATE TABLE `t2` ( `f5` timestamp NOT NULL DEFAULT '0000-00-00 00:00:00', `f6` varchar(1) CHARACTER SET utf8 DEFAULT NULL, `f7` text, - `f8` text CHARACTER SET utf8 + `f8` mediumtext character set utf8 ) ENGINE=MyISAM DEFAULT CHARSET=latin1 drop table t1, t2; (select avg(1)) union (select avg(1)) union (select avg(1)) union @@ -1366,3 +1366,8 @@ drop table t1, t2; (select avg(1)) union (select avg(1)) union (select avg(1)); avg(1) NULL +select _utf8'12' union select _latin1'12345'; +12 +12 +12345 +End of 5.0 tests diff --git a/mysql-test/r/user_var.result b/mysql-test/r/user_var.result index 9c3fdf0d8d2..1ff2e9948bd 100644 --- a/mysql-test/r/user_var.result +++ b/mysql-test/r/user_var.result @@ -256,3 +256,39 @@ t1 CREATE TABLE `t1` ( `@first_var` longtext ) ENGINE=MyISAM DEFAULT CHARSET=latin1 drop table t1; +set @a=18446744071710965857; +select @a; +@a +18446744071710965857 +CREATE TABLE `bigfailure` ( +`afield` BIGINT UNSIGNED NOT NULL +); +INSERT INTO `bigfailure` VALUES (18446744071710965857); +SELECT * FROM bigfailure; +afield +18446744071710965857 +select * from (SELECT afield FROM bigfailure) as b; +afield +18446744071710965857 +select * from bigfailure where afield = (SELECT afield FROM bigfailure); +afield +18446744071710965857 +select * from bigfailure where afield = 18446744071710965857; +afield +18446744071710965857 +select * from bigfailure where afield = 18446744071710965856+1; +afield +18446744071710965857 +SET @a := (SELECT afield FROM bigfailure); +SELECT @a; +@a +18446744071710965857 +SET @a := (select afield from (SELECT afield FROM bigfailure) as b); +SELECT @a; +@a +18446744071710965857 +SET @a := (select * from bigfailure where afield = (SELECT afield FROM bigfailure)); +SELECT @a; +@a +18446744071710965857 +drop table bigfailure; diff --git a/mysql-test/t/cast.test b/mysql-test/t/cast.test index b733a23f398..ed9fdfa087a 100644 --- a/mysql-test/t/cast.test +++ b/mysql-test/t/cast.test @@ -204,7 +204,19 @@ SELECT CAST(v AS DECIMAL), CAST(tt AS DECIMAL), CAST(t AS DECIMAL), CAST(mt AS DECIMAL), CAST(lt AS DECIMAL) from t1; DROP TABLE t1; -# Bug @10237 (CAST(NULL DECIMAL) crashes server) + +# +# Bug #10237 (CAST(NULL DECIMAL) crashes server) # select cast(NULL as decimal(6)) as t1; + +# +# Bug #17903: cast to char results in binary +# +set names latin1; +select hex(cast('a' as char(2) binary)); +select hex(cast('a' as binary(2))); +select hex(cast('a' as char(2) binary)); + +--echo End of 5.0 tests diff --git a/mysql-test/t/delete.test b/mysql-test/t/delete.test index 4284bd2a06d..677ffaa2860 100644 --- a/mysql-test/t/delete.test +++ b/mysql-test/t/delete.test @@ -171,3 +171,14 @@ delete t2.*,t3.* from t1,t2,t3 where t1.a=t2.a AND t2.b=t3.a and t1.b=t3.b; # This should be empty select * from t3; drop table t1,t2,t3; + +# +# Bug #8143: deleting '0000-00-00' values using IS NULL +# + +create table t1(a date not null); +insert into t1 values (0); +select * from t1 where a is null; +delete from t1 where a is null; +select count(*) from t1; +drop table t1; diff --git a/mysql-test/t/func_compress.test b/mysql-test/t/func_compress.test index 4ae749f2343..eeb5d509b94 100644 --- a/mysql-test/t/func_compress.test +++ b/mysql-test/t/func_compress.test @@ -57,3 +57,17 @@ select uncompress(a), uncompressed_length(a) from t1; drop table t1; # End of 4.1 tests + +# +# Bug #18539: uncompress(d) is null: impossible? +# +create table t1 (a varchar(32) not null); +insert into t1 values ('foo'); +explain select * from t1 where uncompress(a) is null; +select * from t1 where uncompress(a) is null; +explain select *, uncompress(a) from t1; +select *, uncompress(a) from t1; +select *, uncompress(a), uncompress(a) is null from t1; +drop table t1; + +--echo End of 5.0 tests diff --git a/mysql-test/t/func_group.test b/mysql-test/t/func_group.test index 2806ffb5ae0..3a62b9feb3a 100644 --- a/mysql-test/t/func_group.test +++ b/mysql-test/t/func_group.test @@ -682,3 +682,15 @@ SELECT SQL_NO_CACHE FROM t1 t, t2 c WHERE t.a = c.b; DROP TABLE t1,t2; + +# +# Bug #10966: Variance functions return wrong data type +# + +create table t1 select variance(0); +show create table t1; +drop table t1; +create table t1 select stddev(0); +show create table t1; +drop table t1; + diff --git a/mysql-test/t/func_time.test b/mysql-test/t/func_time.test index 7987b3f563d..c9623df2650 100644 --- a/mysql-test/t/func_time.test +++ b/mysql-test/t/func_time.test @@ -318,6 +318,37 @@ select timestampdiff(SQL_TSI_DAY, '1986-02-01', '1986-03-01') as a1, timestampdiff(SQL_TSI_DAY, '1996-02-01', '1996-03-01') as a3, timestampdiff(SQL_TSI_DAY, '2000-02-01', '2000-03-01') as a4; +# bug 16226 +SELECT TIMESTAMPDIFF(day,'2006-01-10 14:30:28','2006-01-11 14:30:27'); +SELECT TIMESTAMPDIFF(day,'2006-01-10 14:30:28','2006-01-11 14:30:28'); +SELECT TIMESTAMPDIFF(day,'2006-01-10 14:30:28','2006-01-11 14:30:29'); +SELECT TIMESTAMPDIFF(day,'2006-01-10 14:30:28','2006-01-12 14:30:27'); +SELECT TIMESTAMPDIFF(day,'2006-01-10 14:30:28','2006-01-12 14:30:28'); +SELECT TIMESTAMPDIFF(day,'2006-01-10 14:30:28','2006-01-12 14:30:29'); + +SELECT TIMESTAMPDIFF(week,'2006-01-10 14:30:28','2006-01-17 14:30:27'); +SELECT TIMESTAMPDIFF(week,'2006-01-10 14:30:28','2006-01-17 14:30:28'); +SELECT TIMESTAMPDIFF(week,'2006-01-10 14:30:28','2006-01-17 14:30:29'); +SELECT TIMESTAMPDIFF(week,'2006-01-10 14:30:28','2006-01-24 14:30:27'); +SELECT TIMESTAMPDIFF(week,'2006-01-10 14:30:28','2006-01-24 14:30:28'); +SELECT TIMESTAMPDIFF(week,'2006-01-10 14:30:28','2006-01-24 14:30:29'); + +SELECT TIMESTAMPDIFF(month,'2006-01-10 14:30:28','2006-02-10 14:30:27'); +SELECT TIMESTAMPDIFF(month,'2006-01-10 14:30:28','2006-02-10 14:30:28'); +SELECT TIMESTAMPDIFF(month,'2006-01-10 14:30:28','2006-02-10 14:30:29'); +SELECT TIMESTAMPDIFF(month,'2006-01-10 14:30:28','2006-03-10 14:30:27'); +SELECT TIMESTAMPDIFF(month,'2006-01-10 14:30:28','2006-03-10 14:30:28'); +SELECT TIMESTAMPDIFF(month,'2006-01-10 14:30:28','2006-03-10 14:30:29'); + +SELECT TIMESTAMPDIFF(year,'2006-01-10 14:30:28','2007-01-10 14:30:27'); +SELECT TIMESTAMPDIFF(year,'2006-01-10 14:30:28','2007-01-10 14:30:28'); +SELECT TIMESTAMPDIFF(year,'2006-01-10 14:30:28','2007-01-10 14:30:29'); +SELECT TIMESTAMPDIFF(year,'2006-01-10 14:30:28','2008-01-10 14:30:27'); +SELECT TIMESTAMPDIFF(year,'2006-01-10 14:30:28','2008-01-10 14:30:28'); +SELECT TIMESTAMPDIFF(year,'2006-01-10 14:30:28','2008-01-10 14:30:29'); + +# end of bug + select date_add(time,INTERVAL 1 SECOND) from t1; drop table t1; diff --git a/mysql-test/t/im_daemon_life_cycle.imtest b/mysql-test/t/im_daemon_life_cycle.imtest index 3afc36935f8..fe2345a9987 100644 --- a/mysql-test/t/im_daemon_life_cycle.imtest +++ b/mysql-test/t/im_daemon_life_cycle.imtest @@ -7,21 +7,7 @@ ########################################################################### --source include/im_check_os.inc - -########################################################################### - -# Wait for mysqld1 (guarded instance) to start. - ---exec $MYSQL_TEST_DIR/t/wait_for_process.sh $IM_MYSQLD1_PATH_PID 30 started - -# Let IM detect that mysqld1 is online. This delay should be longer than -# monitoring interval. - ---sleep 3 - -# Check that start conditions are as expected. - -SHOW INSTANCES; +--source include/im_check_env.inc ########################################################################### diff --git a/mysql-test/t/im_life_cycle.imtest b/mysql-test/t/im_life_cycle.imtest index 2cbe53a7b28..35258396415 100644 --- a/mysql-test/t/im_life_cycle.imtest +++ b/mysql-test/t/im_life_cycle.imtest @@ -7,33 +7,7 @@ ########################################################################### --source include/im_check_os.inc - -########################################################################### -# -# 1.1.1. Check that Instance Manager is able: -# - to read definitions of two mysqld-instances; -# - to start the first instance; -# - to understand 'nonguarded' option and keep the second instance down; -# -########################################################################### - ---echo ---echo -------------------------------------------------------------------- ---echo -- 1.1.1. ---echo -------------------------------------------------------------------- - -# Wait for mysqld1 (guarded instance) to start. - ---exec $MYSQL_TEST_DIR/t/wait_for_process.sh $IM_MYSQLD1_PATH_PID 30 started - -# Let IM detect that mysqld1 is online. This delay should be longer than -# monitoring interval. - ---sleep 3 - -# Check that start conditions are as expected. - -SHOW INSTANCES; +--source include/im_check_env.inc ########################################################################### # @@ -54,9 +28,10 @@ START INSTANCE mysqld2; # FIXME: START INSTANCE should be synchronous. --exec $MYSQL_TEST_DIR/t/wait_for_process.sh $IM_MYSQLD2_PATH_PID 30 started -# FIXME: SHOW INSTANCES is not deterministic unless START INSTANCE is -# synchronous. Even waiting for mysqld to start by looking at its pid file is -# not enough, because IM may not detect that mysqld has started. +# FIXME: Result of SHOW INSTANCES here is not deterministic unless START +# INSTANCE is synchronous. Even waiting for mysqld to start by looking at +# its pid file is not enough, because it is unknown when IM detects that +# mysqld has started. # SHOW INSTANCES; --connect (mysql_con,localhost,root,,mysql,$IM_MYSQLD2_PORT,$IM_MYSQLD2_SOCK) @@ -86,9 +61,10 @@ STOP INSTANCE mysqld2; # FIXME: STOP INSTANCE should be synchronous. --exec $MYSQL_TEST_DIR/t/wait_for_process.sh $IM_MYSQLD2_PATH_PID 30 stopped -# FIXME: SHOW INSTANCES is not deterministic unless START INSTANCE is -# synchronous. Even waiting for mysqld to start by looking at its pid file is -# not enough, because IM may not detect that mysqld has started. +# FIXME: Result of SHOW INSTANCES here is not deterministic unless START +# INSTANCE is synchronous. Even waiting for mysqld to start by looking at +# its pid file is not enough, because it is unknown when IM detects that +# mysqld has started. # SHOW INSTANCES; ########################################################################### @@ -114,8 +90,8 @@ START INSTANCE mysqld1; ########################################################################### # -# 1.1.5. Check that Instance Manager reports correct errors for 'STOP INSTANCE' -# command: +# 1.1.5. Check that Instance Manager reports correct errors for +# 'STOP INSTANCE' command: # - if the client tries to start unregistered instance; # - if the client tries to start already stopped instance; # - if the client submits invalid arguments; @@ -146,12 +122,10 @@ STOP INSTANCE mysqld3; --echo -- 1.1.6. --echo -------------------------------------------------------------------- -SHOW INSTANCES; - --exec $MYSQL_TEST_DIR/t/kill_n_check.sh $IM_MYSQLD1_PATH_PID restarted 30 -# Give some time to IM to detect that mysqld was restarted. It should be longer -# than monitoring interval. +# Give some time to IM to detect that mysqld was restarted. It should be +# longer than monitoring interval. --sleep 3 @@ -172,16 +146,18 @@ START INSTANCE mysqld2; # FIXME: START INSTANCE should be synchronous. --exec $MYSQL_TEST_DIR/t/wait_for_process.sh $IM_MYSQLD2_PATH_PID 30 started -# FIXME: SHOW INSTANCES is not deterministic unless START INSTANCE is -# synchronous. Even waiting for mysqld to start by looking at its pid file is -# not enough, because IM may not detect that mysqld has started. +# FIXME: Result of SHOW INSTANCES here is not deterministic unless START +# INSTANCE is synchronous. Even waiting for mysqld to start by looking at +# its pid file is not enough, because it is unknown when IM detects that +# mysqld has started. # SHOW INSTANCES; --exec $MYSQL_TEST_DIR/t/kill_n_check.sh $IM_MYSQLD2_PATH_PID killed 10 -# FIXME: SHOW INSTANCES is not deterministic unless START INSTANCE is -# synchronous. Even waiting for mysqld to start by looking at its pid file is -# not enough, because IM may not detect that mysqld has started. +# FIXME: Result of SHOW INSTANCES here is not deterministic unless START +# INSTANCE is synchronous. Even waiting for mysqld to start by looking at +# its pid file is not enough, because it is unknown when IM detects that +# mysqld has started. # SHOW INSTANCES; ########################################################################### diff --git a/mysql-test/t/im_utils.imtest b/mysql-test/t/im_utils.imtest index 47902eeba52..4c05b342af5 100644 --- a/mysql-test/t/im_utils.imtest +++ b/mysql-test/t/im_utils.imtest @@ -7,36 +7,17 @@ ########################################################################### --source include/im_check_os.inc +--source include/im_check_env.inc ########################################################################### # -# Check starting conditions. This test case assumes that: -# - two mysqld-instances are registered; -# - the first instance is online; -# - the second instance is offline; +# Check 'SHOW INSTANCE OPTIONS' command. # - -# Wait for mysqld1 (guarded instance) to start. - ---exec $MYSQL_TEST_DIR/t/wait_for_process.sh $IM_MYSQLD1_PATH_PID 30 started - -# Let IM detect that mysqld1 is online. This delay should be longer than -# monitoring interval. - ---sleep 3 - -# Check that start conditions are as expected. - -SHOW INSTANCES; - -# -# Check 'SHOW INSTANCE OPTIONS' command: -# - check that options of both offline and online instances are accessible; -# - since configuration of an mysqld-instance contains directories, we should -# completely ignore the second column (values) in order to make the test -# case produce the same results on different installations; -# TODO: ignore values of only directory-specific options. +# Since configuration of an mysqld-instance contains directories, we should +# completely ignore the second column (values) in order to make the test +# case produce the same results on different installations; +# TODO: ignore values of only directory-specific options. # --replace_column 2 VALUE diff --git a/mysql-test/t/mysql.test b/mysql-test/t/mysql.test index 98fadcfc75d..cf6f72570ff 100644 --- a/mysql-test/t/mysql.test +++ b/mysql-test/t/mysql.test @@ -77,6 +77,23 @@ drop table t1; # --exec $MYSQL -t test -e "create table b19564 (i int, s1 char(1)); insert into b19564 values (1, 'x'); insert into b19564 values (2, NULL); insert into b19564 values (3, ' '); select * from b19564 order by i; drop table b19564;" +# +# Bug#19265 describe command does not work from mysql prompt +# + +create table t1(a int, b varchar(255), c int); +--exec $MYSQL test -e "desc t1" +--exec $MYSQL test -e "desc t1\g" +drop table t1; + +--disable_parsing +# +# Bug#21042 mysql client segfaults on importing a mysqldump export +# +--error 1 +--exec $MYSQL test -e "connect verylongdatabasenamethatshouldblowthe256byteslongbufferincom_connectfunctionxkxkxkxkxkxkxkxkxkxkxkxkxkxkxkxkxkxkxkxkxkxkxkxkxkxkxkxkxkxkxkxkxkxkxkxkxkxkxkxkxkxkxkxkxkxkxkxkxkxkxkxkxendcccccccdxxxxxxxxxxxxxxxxxkskskskskkskskskskskskskskskskkskskskskkskskskskskskskskskend" 2>&1 +--enable_parsing + --echo End of 5.0 tests diff --git a/mysql-test/t/mysqlcheck.test b/mysql-test/t/mysqlcheck.test index f5eddff8816..a96dbc74591 100644 --- a/mysql-test/t/mysqlcheck.test +++ b/mysql-test/t/mysqlcheck.test @@ -19,3 +19,17 @@ CREATE SCHEMA test; --replace_result 'Table is already up to date' OK --exec $MYSQL_CHECK --analyze --optimize --databases test information_schema mysql --exec $MYSQL_CHECK --analyze --optimize information_schema schemata + +# +# Bug #16502: mysqlcheck tries to check views +# +create table t1 (a int); +create view v1 as select * from t1; +--replace_result 'Table is already up to date' OK +--exec $MYSQL_CHECK --analyze --optimize --databases test +--replace_result 'Table is already up to date' OK +--exec $MYSQL_CHECK --all-in-1 --analyze --optimize --databases test +drop view v1; +drop table t1; + +--echo End of 5.0 tests diff --git a/mysql-test/t/mysqldump.test b/mysql-test/t/mysqldump.test index c40a21e0ca0..b0cb93ccd85 100644 --- a/mysql-test/t/mysqldump.test +++ b/mysql-test/t/mysqldump.test @@ -1281,8 +1281,49 @@ use mysqldump_dbb; drop view v1; drop table t1; drop database mysqldump_dbb; +# +# Bug#21215 mysqldump creating incomplete backups without warning +# use test; +# Create user without sufficient privs to perform the requested operation +create user mysqltest_1; +create table t1(a int, b varchar(34)); + +# To get consistent output, reset the master, starts over from first log +reset master; + +# Execute mysqldump, will fail on FLUSH TABLES +--error 2 +--exec $MYSQL_DUMP --compact --master-data -u mysqltest_1 test 2>&1 + +# Execute mysqldump, will fail on FLUSH TABLES +# use --force, should no affect behaviour +--error 2 +--exec $MYSQL_DUMP --compact --force --master-data -u mysqltest_1 test 2>&1 + +# Add RELOAD grants +grant RELOAD on *.* to mysqltest_1@localhost; + +# Execute mysqldump, will fail on SHOW MASTER STATUS +--error 2 +--exec $MYSQL_DUMP --compact --master-data -u mysqltest_1 test 2>&1 + +# Execute mysqldump, will fail on SHOW MASTER STATUS. +# use --force, should not alter behaviour +--error 2 +--exec $MYSQL_DUMP --compact --force --master-data -u mysqltest_1 test 2>&1 + +# Add REPLICATION CLIENT grants +grant REPLICATION CLIENT on *.* to mysqltest_1@localhost; + +# Execute mysqldump, should now succeed +--exec $MYSQL_DUMP --compact --master-data -u mysqltest_1 test 2>&1 + +# Clean up +drop table t1; +drop user mysqltest_1; + --echo End of 5.0 tests # diff --git a/mysql-test/t/mysqlshow.test b/mysql-test/t/mysqlshow.test index 78c4ae2b531..9ed93079f57 100644 --- a/mysql-test/t/mysqlshow.test +++ b/mysql-test/t/mysqlshow.test @@ -25,3 +25,12 @@ select "---- -v -t ---------" as ""; select "---- -v -v -t ------" as ""; --exec $MYSQL_SHOW test -v -v -t DROP TABLE t1, t2; + +# +# Bug #19147: mysqlshow INFORMATION_SCHEMA does not work +# +--exec $MYSQL_SHOW information_schema +--exec $MYSQL_SHOW INFORMATION_SCHEMA +--exec $MYSQL_SHOW inf_rmation_schema + +--echo End of 5.0 tests diff --git a/mysql-test/t/mysqltest.test b/mysql-test/t/mysqltest.test index 86cfd66ae2b..04e0532851a 100644 --- a/mysql-test/t/mysqltest.test +++ b/mysql-test/t/mysqltest.test @@ -1121,6 +1121,23 @@ drop table t1; --exec test -s $MYSQLTEST_VARDIR/tmp/bug11731.out drop table t1; +# +# Bug#19890 mysqltest: "query" command is broken +# + +# It should be possible to use the command "query" to force mysqltest to +# send the command to the server although it's a builtin mysqltest command. +--error 1064 +query sleep; + +--error 1064 +--query sleep + +# Just an empty query command +--error 1065 +query ; + +--echo End of 5.0 tests # test for replace_regex --replace_regex /at/b/ @@ -1159,3 +1176,5 @@ insert into t1 values (2,4); --replace_regex /A/C/ /B/D/i /3/2/ /2/1/ select * from t1; drop table t1; + +--echo End of 5.1 tests diff --git a/mysql-test/t/ndb_basic.test b/mysql-test/t/ndb_basic.test index c7fa5aeee1e..7bbc580c9ad 100644 --- a/mysql-test/t/ndb_basic.test +++ b/mysql-test/t/ndb_basic.test @@ -713,6 +713,15 @@ select * from t1 order by f1; select * from t1 order by f2; select * from t1 order by f3; drop table t1; +# Bug#16561 Unknown ERROR msg "ERROR 1186 (HY000): Binlog closed" by perror +# + +# As long there is no error code 1186 defined by NDB +# we should get a message "Illegal ndb error code: 1186" +--error 1 +--exec $MY_PERROR --ndb 1186 2>&1 + +--echo End of 5.0 tests # # Bug #18483 Cannot create table with FK constraint @@ -727,3 +736,5 @@ CREATE TABLE t2(a VARCHAR(255) NOT NULL, CONSTRAINT pk_b_c_id PRIMARY KEY (b,c), CONSTRAINT fk_a FOREIGN KEY(a) REFERENCES t1(a))engine=ndb; drop table t1, t2; + +--echo End of 5.1 tests diff --git a/mysql-test/t/perror.test b/mysql-test/t/perror.test new file mode 100644 index 00000000000..a4b99d8aa22 --- /dev/null +++ b/mysql-test/t/perror.test @@ -0,0 +1,19 @@ +# +# Check if the variable MY_PERROR is set +# +--require r/have_perror.require +disable_query_log; +eval select LENGTH("$MY_PERROR") > 0 as "have_perror"; +enable_query_log; + +--exec $MY_PERROR 150 > /dev/null +--exec $MY_PERROR --silent 120 > /dev/null + +# +# Bug#16561 Unknown ERROR msg "ERROR 1186 (HY000): Binlog closed" by perror +# + +# Test with error code 10000 as it's a common "unknown error" +# As there is no error code defined for 10000, expect error +--error 1 +--exec $MY_PERROR 10000 2>&1 diff --git a/mysql-test/t/ps.test b/mysql-test/t/ps.test index 9165fceb85e..aa7b6ebf266 100644 --- a/mysql-test/t/ps.test +++ b/mysql-test/t/ps.test @@ -491,6 +491,7 @@ deallocate prepare stmt; drop table t1, t2; # +# # Bug#19399 "Stored Procedures 'Lost Connection' when dropping/creating # tables" # Check that multi-delete tables are also cleaned up before re-execution. @@ -538,86 +539,6 @@ SELECT FOUND_ROWS(); deallocate prepare stmt; # -# Bug#8115: equality propagation and prepared statements -# - -create table t1 (a char(3) not null, b char(3) not null, - c char(3) not null, primary key (a, b, c)); -create table t2 like t1; - -# reduced query -prepare stmt from - "select t1.a from (t1 left outer join t2 on t2.a=1 and t1.b=t2.b) - where t1.a=1"; -execute stmt; -execute stmt; -execute stmt; - -# original query -prepare stmt from -"select t1.a, t1.b, t1.c, t2.a, t2.b, t2.c from -(t1 left outer join t2 on t2.a=? and t1.b=t2.b) -left outer join t2 t3 on t3.a=? where t1.a=?"; - -set @a:=1, @b:=1, @c:=1; - -execute stmt using @a, @b, @c; -execute stmt using @a, @b, @c; -execute stmt using @a, @b, @c; - -deallocate prepare stmt; - -drop table t1,t2; - - -# -# Bug#9383: INFORMATION_SCHEMA.COLUMNS, JOIN, Crash, prepared statement -# - -eval SET @aux= "SELECT COUNT(*) - FROM INFORMATION_SCHEMA.COLUMNS A, - INFORMATION_SCHEMA.COLUMNS B - WHERE A.TABLE_SCHEMA = B.TABLE_SCHEMA - AND A.TABLE_NAME = B.TABLE_NAME - AND A.COLUMN_NAME = B.COLUMN_NAME AND - A.TABLE_NAME = 'user'"; - -let $exec_loop_count= 3; -eval prepare my_stmt from @aux; -while ($exec_loop_count) -{ - eval execute my_stmt; - dec $exec_loop_count; -} -deallocate prepare my_stmt; - -# Test CALL in prepared mode -delimiter |; ---disable_warnings -drop procedure if exists p1| -drop table if exists t1| ---enable_warnings -create table t1 (id int)| -insert into t1 values(1)| -create procedure p1(a int, b int) -begin - declare c int; - select max(id)+1 into c from t1; - insert into t1 select a+b; - insert into t1 select a-b; - insert into t1 select a-c; -end| -set @a= 3, @b= 4| -prepare stmt from "call p1(?, ?)"| -execute stmt using @a, @b| -execute stmt using @a, @b| -select * from t1| -deallocate prepare stmt| -drop procedure p1| -drop table t1| -delimiter ;| - -# # Bug#9096 "select doesn't return all matched records if prepared statements # is used" # The bug was is bad co-operation of the optimizer's algorithm which determines @@ -692,35 +613,6 @@ deallocate prepare stmt; drop table t1, t2; # -# Bug#7306 LIMIT ?, ? and also WL#1785 " Prepared statements: implement -# support for placeholders in LIMIT clause." -# Add basic test coverage for the feature. -# -create table t1 (a int); -insert into t1 (a) values (1), (2), (3), (4), (5), (6), (7), (8), (9), (10); -prepare stmt from "select * from t1 limit ?, ?"; -set @offset=0, @limit=1; -execute stmt using @offset, @limit; -select * from t1 limit 0, 1; -set @offset=3, @limit=2; -execute stmt using @offset, @limit; -select * from t1 limit 3, 2; -prepare stmt from "select * from t1 limit ?"; -execute stmt using @limit; ---error 1235 -prepare stmt from "select * from t1 where a in (select a from t1 limit ?)"; -prepare stmt from "select * from t1 union all select * from t1 limit ?, ?"; -set @offset=9; -set @limit=2; -execute stmt using @offset, @limit; -prepare stmt from "(select * from t1 limit ?, ?) union all - (select * from t1 limit ?, ?) order by a limit ?"; -execute stmt using @offset, @limit, @offset, @limit, @limit; - -drop table t1; -deallocate prepare stmt; - -# # Bug#11060 "Server crashes on calling stored procedure with INSERT SELECT # UNION SELECT" aka "Server crashes on re-execution of prepared INSERT ... # SELECT with UNION". @@ -837,22 +729,6 @@ select ??; select ? from t1; --enable_ps_protocol drop table t1; - -# -# Bug#12651 -# (Crash on a PS including a subquery which is a select from a simple view) -# -CREATE TABLE b12651_T1(a int) ENGINE=MYISAM; -CREATE TABLE b12651_T2(b int) ENGINE=MYISAM; -CREATE VIEW b12651_V1 as SELECT b FROM b12651_T2; - -PREPARE b12651 FROM 'SELECT 1 FROM b12651_T1 WHERE a IN (SELECT b FROM b12651_V1)'; -EXECUTE b12651; - -DROP VIEW b12651_V1; -DROP TABLE b12651_T1, b12651_T2; -DEALLOCATE PREPARE b12651; - # # Bug#9359 "Prepared statements take snapshot of system vars at PREPARE # time" @@ -1087,7 +963,172 @@ select @@max_prepared_stmt_count, @@prepared_stmt_count; set global max_prepared_stmt_count= @old_max_prepared_stmt_count; --enable_ps_protocol -# End of 4.1 tests +# +# Bug#19399 "Stored Procedures 'Lost Connection' when dropping/creating +# tables" +# Check that multi-delete tables are also cleaned up before re-execution. +# +--disable_warnings +drop table if exists t1; +create temporary table if not exists t1 (a1 int); +--enable_warnings +# exact delete syntax is essential +prepare stmt from "delete t1 from t1 where (cast(a1/3 as unsigned) * 3) = a1"; +drop temporary table t1; +create temporary table if not exists t1 (a1 int); +# the server crashed on the next statement without the fix +execute stmt; +drop temporary table t1; +create temporary table if not exists t1 (a1 int); +# the problem was in memory corruption: repeat the test just in case +execute stmt; +drop temporary table t1; +create temporary table if not exists t1 (a1 int); +execute stmt; +drop temporary table t1; +deallocate prepare stmt; + +--echo End of 4.1 tests +############################# 5.0 tests start ################################ +# +# +# Bug#6102 "Server crash with prepared statement and blank after +# function name" +# ensure that stored functions are cached when preparing a statement +# before we open tables +# +create table t1 (a varchar(20)); +insert into t1 values ('foo'); +--error 1305 +prepare stmt FROM 'SELECT char_length (a) FROM t1'; +drop table t1; + +# +# Bug#8115: equality propagation and prepared statements +# + +create table t1 (a char(3) not null, b char(3) not null, + c char(3) not null, primary key (a, b, c)); +create table t2 like t1; + +# reduced query +prepare stmt from + "select t1.a from (t1 left outer join t2 on t2.a=1 and t1.b=t2.b) + where t1.a=1"; +execute stmt; +execute stmt; +execute stmt; + +# original query +prepare stmt from +"select t1.a, t1.b, t1.c, t2.a, t2.b, t2.c from +(t1 left outer join t2 on t2.a=? and t1.b=t2.b) +left outer join t2 t3 on t3.a=? where t1.a=?"; + +set @a:=1, @b:=1, @c:=1; + +execute stmt using @a, @b, @c; +execute stmt using @a, @b, @c; +execute stmt using @a, @b, @c; + +deallocate prepare stmt; + +drop table t1,t2; + + +# +# Bug#9383: INFORMATION_SCHEMA.COLUMNS, JOIN, Crash, prepared statement +# + +eval SET @aux= "SELECT COUNT(*) + FROM INFORMATION_SCHEMA.COLUMNS A, + INFORMATION_SCHEMA.COLUMNS B + WHERE A.TABLE_SCHEMA = B.TABLE_SCHEMA + AND A.TABLE_NAME = B.TABLE_NAME + AND A.COLUMN_NAME = B.COLUMN_NAME AND + A.TABLE_NAME = 'user'"; + +let $exec_loop_count= 3; +eval prepare my_stmt from @aux; +while ($exec_loop_count) +{ + eval execute my_stmt; + dec $exec_loop_count; +} +deallocate prepare my_stmt; + +# Test CALL in prepared mode +delimiter |; +--disable_warnings +drop procedure if exists p1| +drop table if exists t1| +--enable_warnings +create table t1 (id int)| +insert into t1 values(1)| +create procedure p1(a int, b int) +begin + declare c int; + select max(id)+1 into c from t1; + insert into t1 select a+b; + insert into t1 select a-b; + insert into t1 select a-c; +end| +set @a= 3, @b= 4| +prepare stmt from "call p1(?, ?)"| +execute stmt using @a, @b| +execute stmt using @a, @b| +select * from t1| +deallocate prepare stmt| +drop procedure p1| +drop table t1| +delimiter ;| + + +# +# Bug#7306 LIMIT ?, ? and also WL#1785 " Prepared statements: implement +# support for placeholders in LIMIT clause." +# Add basic test coverage for the feature. +# +create table t1 (a int); +insert into t1 (a) values (1), (2), (3), (4), (5), (6), (7), (8), (9), (10); +prepare stmt from "select * from t1 limit ?, ?"; +set @offset=0, @limit=1; +execute stmt using @offset, @limit; +select * from t1 limit 0, 1; +set @offset=3, @limit=2; +execute stmt using @offset, @limit; +select * from t1 limit 3, 2; +prepare stmt from "select * from t1 limit ?"; +execute stmt using @limit; +--error 1235 +prepare stmt from "select * from t1 where a in (select a from t1 limit ?)"; +prepare stmt from "select * from t1 union all select * from t1 limit ?, ?"; +set @offset=9; +set @limit=2; +execute stmt using @offset, @limit; +prepare stmt from "(select * from t1 limit ?, ?) union all + (select * from t1 limit ?, ?) order by a limit ?"; +execute stmt using @offset, @limit, @offset, @limit, @limit; + +drop table t1; +deallocate prepare stmt; + +# +# Bug#12651 +# (Crash on a PS including a subquery which is a select from a simple view) +# +CREATE TABLE b12651_T1(a int) ENGINE=MYISAM; +CREATE TABLE b12651_T2(b int) ENGINE=MYISAM; +CREATE VIEW b12651_V1 as SELECT b FROM b12651_T2; + +PREPARE b12651 FROM 'SELECT 1 FROM b12651_T1 WHERE a IN (SELECT b FROM b12651_V1)'; +EXECUTE b12651; + +DROP VIEW b12651_V1; +DROP TABLE b12651_T1, b12651_T2; +DEALLOCATE PREPARE b12651; + + # # Bug #14956: ROW_COUNT() returns incorrect result after EXECUTE of prepared diff --git a/mysql-test/t/rpl_sp.test b/mysql-test/t/rpl_sp.test index f9072b5a711..22ab72df104 100644 --- a/mysql-test/t/rpl_sp.test +++ b/mysql-test/t/rpl_sp.test @@ -433,5 +433,92 @@ SELECT * FROM t1; # Cleanup connection master; DROP PROCEDURE p1; + + +# +# BUG#20438: CREATE statements for views, stored routines and triggers can be +# not replicable. +# + +--echo +--echo ---> Test for BUG#20438 + +# Prepare environment. + +--echo +--echo ---> Preparing environment... +--echo ---> connection: master +--connection master + +--disable_warnings +DROP PROCEDURE IF EXISTS p1; +DROP FUNCTION IF EXISTS f1; +--enable_warnings + +--echo +--echo ---> Synchronizing slave with master... + +--save_master_pos +--connection slave +--sync_with_master + +--echo +--echo ---> connection: master +--connection master + +# Test. + +--echo +--echo ---> Creating procedure... + +/*!50003 CREATE PROCEDURE p1() SET @a = 1 */; + +/*!50003 CREATE FUNCTION f1() RETURNS INT RETURN 0 */; + +--echo +--echo ---> Checking on master... + +SHOW CREATE PROCEDURE p1; +SHOW CREATE FUNCTION f1; + +--echo +--echo ---> Synchronizing slave with master... + +--save_master_pos +--connection slave +--sync_with_master + +--echo ---> connection: master + +--echo +--echo ---> Checking on slave... + +SHOW CREATE PROCEDURE p1; +SHOW CREATE FUNCTION f1; + +# Cleanup. + +--echo +--echo ---> connection: master +--connection master + +--echo +--echo ---> Cleaning up... + +DROP PROCEDURE p1; +DROP FUNCTION f1; + +--save_master_pos +--connection slave +--sync_with_master +--connection master + + +# cleanup +connection master; drop table t1; sync_slave_with_master; + +--echo End of 5.0 tests +--echo End of 5.1 tests + diff --git a/mysql-test/t/rpl_trigger.test b/mysql-test/t/rpl_trigger.test index 591941c19eb..3671763ee18 100644 --- a/mysql-test/t/rpl_trigger.test +++ b/mysql-test/t/rpl_trigger.test @@ -339,6 +339,98 @@ SHOW TRIGGERS; RESET MASTER; +# Restart slave. + +connection slave; +START SLAVE; + + +# +# BUG#20438: CREATE statements for views, stored routines and triggers can be +# not replicable. +# + +--echo +--echo ---> Test for BUG#20438 + +# Prepare environment. + +--echo +--echo ---> Preparing environment... +--echo ---> connection: master +--connection master + +--disable_warnings +DROP TABLE IF EXISTS t1; +DROP TABLE IF EXISTS t2; +--enable_warnings + +--echo +--echo ---> Synchronizing slave with master... + +--save_master_pos +--connection slave +--sync_with_master + +--echo +--echo ---> connection: master +--connection master + +# Test. + +--echo +--echo ---> Creating objects... + +CREATE TABLE t1(c INT); +CREATE TABLE t2(c INT); + +/*!50003 CREATE TRIGGER t1_bi BEFORE INSERT ON t1 + FOR EACH ROW + INSERT INTO t2 VALUES(NEW.c * 10) */; + +--echo +--echo ---> Inserting value... + +INSERT INTO t1 VALUES(1); + +--echo +--echo ---> Checking on master... + +SELECT * FROM t1; +SELECT * FROM t2; + +--echo +--echo ---> Synchronizing slave with master... + +--save_master_pos +--connection slave +--sync_with_master + +--echo ---> connection: master + +--echo +--echo ---> Checking on slave... + +SELECT * FROM t1; +SELECT * FROM t2; + +# Cleanup. + +--echo +--echo ---> connection: master +--connection master + +--echo +--echo ---> Cleaning up... + +DROP TABLE t1; +DROP TABLE t2; + +--save_master_pos +--connection slave +--sync_with_master +--connection master + # # End of tests diff --git a/mysql-test/t/rpl_view.test b/mysql-test/t/rpl_view.test index 0e8c7514488..687c702c79d 100644 --- a/mysql-test/t/rpl_view.test +++ b/mysql-test/t/rpl_view.test @@ -50,3 +50,86 @@ sync_slave_with_master; # Change: Commented out binlog events to work with SBR and RBR #--replace_column 2 # 5 # # show binlog events limit 1,100; + +# +# BUG#20438: CREATE statements for views, stored routines and triggers can be +# not replicable. +# + +--echo +--echo ---> Test for BUG#20438 + +# Prepare environment. + +--echo +--echo ---> Preparing environment... +--echo ---> connection: master +--connection master + +--disable_warnings +DROP TABLE IF EXISTS t1; +DROP VIEW IF EXISTS v1; +--enable_warnings + +--echo +--echo ---> Synchronizing slave with master... + +--save_master_pos +--connection slave +--sync_with_master + +--echo +--echo ---> connection: master +--connection master + +# Test. + +--echo +--echo ---> Creating objects... + +CREATE TABLE t1(c INT); + +/*!50003 CREATE VIEW v1 AS SELECT * FROM t1 */; + +--echo +--echo ---> Inserting value... + +INSERT INTO t1 VALUES(1); + +--echo +--echo ---> Checking on master... + +SELECT * FROM t1; + +--echo +--echo ---> Synchronizing slave with master... + +--save_master_pos +--connection slave +--sync_with_master + +--echo ---> connection: master + +--echo +--echo ---> Checking on slave... + +SELECT * FROM t1; + +# Cleanup. + +--echo +--echo ---> connection: master +--connection master + +--echo +--echo ---> Cleaning up... + +DROP VIEW v1; +DROP TABLE t1; + +--save_master_pos +--connection slave +--sync_with_master +--connection master + +--echo End of 5.0 tests diff --git a/mysql-test/t/show_check.test b/mysql-test/t/show_check.test index 00520df350c..e99387bf695 100644 --- a/mysql-test/t/show_check.test +++ b/mysql-test/t/show_check.test @@ -491,6 +491,17 @@ SHOW CREATE VIEW v1; DROP PROCEDURE p1; DROP VIEW v1; + +# +# Check that SHOW TABLES and SHOW COLUMNS give a error if there is no +# referenced database and table respectively. +# +--error ER_BAD_DB_ERROR +SHOW TABLES FROM no_such_database; +--error ER_NO_SUCH_TABLE +SHOW COLUMNS FROM no_such_table; + +# End of 5.0 tests. --echo End of 5.0 tests. --disable_result_log diff --git a/mysql-test/t/sp-code.test b/mysql-test/t/sp-code.test index 0a26ea644f6..72efa831059 100644 --- a/mysql-test/t/sp-code.test +++ b/mysql-test/t/sp-code.test @@ -190,3 +190,25 @@ delimiter ;// show procedure code sudoku_solve; drop procedure sudoku_solve; + + +# +# Bug#19207: Final parenthesis omitted for CREATE INDEX in Stored +# Procedure +# +# Wrong criteria was used to distinguish the case when there was no +# lookahead performed in the parser. Bug affected only statements +# ending in one-character token without any optional tail, like CREATE +# INDEX and CALL. +# +--disable_warnings +DROP PROCEDURE IF EXISTS p1; +--enable_warnings + +CREATE PROCEDURE p1() CREATE INDEX idx ON t1 (c1); +SHOW PROCEDURE CODE p1; + +DROP PROCEDURE p1; + + +--echo End of 5.0 tests. diff --git a/mysql-test/t/sp-error.test b/mysql-test/t/sp-error.test index 73a64b6feeb..e1179f36dad 100644 --- a/mysql-test/t/sp-error.test +++ b/mysql-test/t/sp-error.test @@ -1709,9 +1709,31 @@ drop function if exists bug16896; --error ER_SP_NO_AGGREGATE create aggregate function bug16896() returns int return 1; +# BUG#14702: misleading error message when syntax error in CREATE +# PROCEDURE +# +# Misleading error message was given when IF NOT EXISTS was used in +# CREATE PROCEDURE. +# +--disable_warnings +DROP PROCEDURE IF EXISTS bug14702; +--enable_warnings + +--error ER_PARSE_ERROR +CREATE IF NOT EXISTS PROCEDURE bug14702() +BEGIN +END; + +--error ER_PARSE_ERROR +CREATE PROCEDURE IF NOT EXISTS bug14702() +BEGIN +END; + + # # End of 5.0 tests # +--echo End of 5.0 tests # # Bug#16164 "Easter egg": check that SHOW AUTHORS is disabled in @@ -1743,6 +1765,7 @@ drop function if exists bug20701| create function bug20701() returns varchar(25) binary return "test"| create function bug20701() returns varchar(25) return "test"| drop function bug20701| +--echo End of 5.1 tests # # BUG#NNNN: New bug synopsis diff --git a/mysql-test/t/sp-security.test b/mysql-test/t/sp-security.test index 591e9a3ed70..0bb8c8bd48f 100644 --- a/mysql-test/t/sp-security.test +++ b/mysql-test/t/sp-security.test @@ -767,4 +767,80 @@ SELECT Host,User,Password FROM mysql.user WHERE User='user19857'; DROP USER user19857@localhost; -# End of 5.0 bugs. +--disconnect con1root +--connection default + + +# +# BUG#18630: Arguments of suid routine calculated in wrong security +# context +# +# Arguments of suid routines were calculated in definer's security +# context instead of caller's context thus creating security hole. +# +--disable_warnings +DROP TABLE IF EXISTS t1; +DROP VIEW IF EXISTS v1; +DROP FUNCTION IF EXISTS f_suid; +DROP PROCEDURE IF EXISTS p_suid; +DROP FUNCTION IF EXISTS f_evil; +--enable_warnings +DELETE FROM mysql.user WHERE user LIKE 'mysqltest\_%'; +DELETE FROM mysql.db WHERE user LIKE 'mysqltest\_%'; +DELETE FROM mysql.tables_priv WHERE user LIKE 'mysqltest\_%'; +DELETE FROM mysql.columns_priv WHERE user LIKE 'mysqltest\_%'; +FLUSH PRIVILEGES; + +CREATE TABLE t1 (i INT); +CREATE FUNCTION f_suid(i INT) RETURNS INT SQL SECURITY DEFINER RETURN 0; +CREATE PROCEDURE p_suid(IN i INT) SQL SECURITY DEFINER SET @c:= 0; + +CREATE USER mysqltest_u1@localhost; +# Thanks to this grant statement privileges of anonymous users on +# 'test' database are not applicable for mysqltest_u1@localhost. +GRANT EXECUTE ON test.* TO mysqltest_u1@localhost; + +delimiter |; +CREATE DEFINER=mysqltest_u1@localhost FUNCTION f_evil () RETURNS INT + SQL SECURITY INVOKER +BEGIN + SET @a:= CURRENT_USER(); + SET @b:= (SELECT COUNT(*) FROM t1); + RETURN @b; +END| +delimiter ;| + +CREATE SQL SECURITY INVOKER VIEW v1 AS SELECT f_evil(); + +connect (conn1, localhost, mysqltest_u1,,); + +--error ER_TABLEACCESS_DENIED_ERROR +SELECT COUNT(*) FROM t1; + +--error ER_TABLEACCESS_DENIED_ERROR +SELECT f_evil(); +SELECT @a, @b; + +--error ER_TABLEACCESS_DENIED_ERROR +SELECT f_suid(f_evil()); +SELECT @a, @b; + +--error ER_TABLEACCESS_DENIED_ERROR +CALL p_suid(f_evil()); +SELECT @a, @b; + +--error ER_TABLEACCESS_DENIED_ERROR +SELECT * FROM v1; +SELECT @a, @b; + +disconnect conn1; +connection default; + +DROP VIEW v1; +DROP FUNCTION f_evil; +DROP USER mysqltest_u1@localhost; +DROP PROCEDURE p_suid; +DROP FUNCTION f_suid; +DROP TABLE t1; + +--echo End of 5.0 tests. diff --git a/mysql-test/t/sp.test b/mysql-test/t/sp.test index f029678a66e..8f83767b883 100644 --- a/mysql-test/t/sp.test +++ b/mysql-test/t/sp.test @@ -5962,6 +5962,189 @@ drop table t3| drop procedure bug15217| +# +# BUG#21013: Performance Degrades when importing data that uses +# Trigger and Stored Procedure +# +# This is a performance and memory leak test. Run with large number +# passed to bug21013() procedure. +# +--disable_warnings +DROP PROCEDURE IF EXISTS bug21013 | +--enable_warnings + +CREATE PROCEDURE bug21013(IN lim INT) +BEGIN + DECLARE i INT DEFAULT 0; + WHILE (i < lim) DO + SET @b = LOCATE(_latin1'b', @a, 1); + SET i = i + 1; + END WHILE; +END | + +SET @a = _latin2"aaaaaaaaaa" | +CALL bug21013(10) | + +DROP PROCEDURE bug21013 | + + +# +# BUG#16211: Stored function return type for strings is ignored +# + +# Prepare: create database with fixed, pre-defined character set. + +--disable_warnings +DROP DATABASE IF EXISTS mysqltest1| +DROP DATABASE IF EXISTS mysqltest2| +--enable_warnings + +CREATE DATABASE mysqltest1 DEFAULT CHARACTER SET utf8| +CREATE DATABASE mysqltest2 DEFAULT CHARACTER SET utf8| + +# Test case: + +use mysqltest1| + +# - Create two stored functions -- with and without explicit CHARSET-clause +# for return value; + +CREATE FUNCTION bug16211_f1() RETURNS CHAR(10) + RETURN ""| + +CREATE FUNCTION bug16211_f2() RETURNS CHAR(10) CHARSET koi8r + RETURN ""| + +CREATE FUNCTION mysqltest2.bug16211_f3() RETURNS CHAR(10) + RETURN ""| + +CREATE FUNCTION mysqltest2.bug16211_f4() RETURNS CHAR(10) CHARSET koi8r + RETURN ""| + +# - Check that CHARSET-clause is specified for the second function; + +SHOW CREATE FUNCTION bug16211_f1| +SHOW CREATE FUNCTION bug16211_f2| + +SHOW CREATE FUNCTION mysqltest2.bug16211_f3| +SHOW CREATE FUNCTION mysqltest2.bug16211_f4| + +SELECT dtd_identifier +FROM INFORMATION_SCHEMA.ROUTINES +WHERE ROUTINE_SCHEMA = "mysqltest1" AND ROUTINE_NAME = "bug16211_f1"| + +SELECT dtd_identifier +FROM INFORMATION_SCHEMA.ROUTINES +WHERE ROUTINE_SCHEMA = "mysqltest1" AND ROUTINE_NAME = "bug16211_f2"| + +SELECT dtd_identifier +FROM INFORMATION_SCHEMA.ROUTINES +WHERE ROUTINE_SCHEMA = "mysqltest2" AND ROUTINE_NAME = "bug16211_f3"| + +SELECT dtd_identifier +FROM INFORMATION_SCHEMA.ROUTINES +WHERE ROUTINE_SCHEMA = "mysqltest2" AND ROUTINE_NAME = "bug16211_f4"| + +SELECT CHARSET(bug16211_f1())| +SELECT CHARSET(bug16211_f2())| + +SELECT CHARSET(mysqltest2.bug16211_f3())| +SELECT CHARSET(mysqltest2.bug16211_f4())| + +# - Alter database character set. + +ALTER DATABASE mysqltest1 CHARACTER SET cp1251| +ALTER DATABASE mysqltest2 CHARACTER SET cp1251| + +# - Check that CHARSET-clause has not changed. + +SHOW CREATE FUNCTION bug16211_f1| +SHOW CREATE FUNCTION bug16211_f2| + +SHOW CREATE FUNCTION mysqltest2.bug16211_f3| +SHOW CREATE FUNCTION mysqltest2.bug16211_f4| + +SELECT dtd_identifier +FROM INFORMATION_SCHEMA.ROUTINES +WHERE ROUTINE_SCHEMA = "mysqltest1" AND ROUTINE_NAME = "bug16211_f1"| + +SELECT dtd_identifier +FROM INFORMATION_SCHEMA.ROUTINES +WHERE ROUTINE_SCHEMA = "mysqltest1" AND ROUTINE_NAME = "bug16211_f2"| + +SELECT dtd_identifier +FROM INFORMATION_SCHEMA.ROUTINES +WHERE ROUTINE_SCHEMA = "mysqltest2" AND ROUTINE_NAME = "bug16211_f3"| + +SELECT dtd_identifier +FROM INFORMATION_SCHEMA.ROUTINES +WHERE ROUTINE_SCHEMA = "mysqltest2" AND ROUTINE_NAME = "bug16211_f4"| + +SELECT CHARSET(bug16211_f1())| +SELECT CHARSET(bug16211_f2())| + +SELECT CHARSET(mysqltest2.bug16211_f3())| +SELECT CHARSET(mysqltest2.bug16211_f4())| + +# Cleanup. + +use test| + +DROP DATABASE mysqltest1| +DROP DATABASE mysqltest2| + + +# +# BUG#16676: Database CHARSET not used for stored procedures +# + +# Prepare: create database with fixed, pre-defined character set. + +--disable_warnings +DROP DATABASE IF EXISTS mysqltest1| +--enable_warnings + +CREATE DATABASE mysqltest1 DEFAULT CHARACTER SET utf8| + +# Test case: + +use mysqltest1| + +# - Create two stored procedures -- with and without explicit CHARSET-clause; + +CREATE PROCEDURE bug16676_p1( + IN p1 CHAR(10), + INOUT p2 CHAR(10), + OUT p3 CHAR(10)) +BEGIN + SELECT CHARSET(p1), COLLATION(p1); + SELECT CHARSET(p2), COLLATION(p2); + SELECT CHARSET(p3), COLLATION(p3); +END| + +CREATE PROCEDURE bug16676_p2( + IN p1 CHAR(10) CHARSET koi8r, + INOUT p2 CHAR(10) CHARSET cp1251, + OUT p3 CHAR(10) CHARSET greek) +BEGIN + SELECT CHARSET(p1), COLLATION(p1); + SELECT CHARSET(p2), COLLATION(p2); + SELECT CHARSET(p3), COLLATION(p3); +END| + +# - Call procedures. + +SET @v2 = 'b'| +SET @v3 = 'c'| + +CALL bug16676_p1('a', @v2, @v3)| +CALL bug16676_p2('a', @v2, @v3)| + +# Cleanup. + +use test| + +DROP DATABASE mysqltest1| # Bug#21002 "Derived table not selecting from a "real" table fails in JOINs" # # A regression caused by the fix for Bug#18444: for derived tables we should @@ -6006,7 +6189,7 @@ SELECT * FROM t11| DROP TABLE t11, t12| DROP FUNCTION bug19862| - +--echo End of 5.0 tests # # BUG#NNNN: New bug synopsis # diff --git a/mysql-test/t/strict.test b/mysql-test/t/strict.test index f6a8824c841..4037e1231cd 100644 --- a/mysql-test/t/strict.test +++ b/mysql-test/t/strict.test @@ -13,7 +13,9 @@ DROP TABLE IF EXISTS t1; # Test INSERT with DATE CREATE TABLE t1 (col1 date); -INSERT INTO t1 VALUES('2004-01-01'),('0000-10-31'),('2004-02-29'); +INSERT INTO t1 VALUES('2004-01-01'),('2004-02-29'); +--error 1292 +INSERT INTO t1 VALUES('0000-10-31'); # All test cases expected to fail should return # SQLSTATE 22007 <invalid date value> @@ -97,7 +99,9 @@ set @@sql_mode='ansi,traditional'; # Test INSERT with DATETIME CREATE TABLE t1 (col1 datetime); -INSERT INTO t1 VALUES('2004-10-31 15:30:00'),('0000-10-31 15:30:00'),('2004-02-29 15:30:00'); +INSERT INTO t1 VALUES('2004-10-31 15:30:00'),('2004-02-29 15:30:00'); +--error 1292 +INSERT INTO t1 VALUES('0000-10-31 15:30:00'); # All test cases expected to fail should return # SQLSTATE 22007 <invalid datetime value> @@ -190,6 +194,7 @@ INSERT INTO t1 (col3) VALUES (STR_TO_DATE('15.10.2004 10.15','%d.%m.%Y %H.%i')); # All test cases expected to fail should return # SQLSTATE 22007 <invalid date value> +--error 1292 INSERT INTO t1 (col1) VALUES(STR_TO_DATE('31.10.0000 15.30','%d.%m.%Y %H.%i')); --error 1292 @@ -211,6 +216,7 @@ INSERT INTO t1 (col1) VALUES(STR_TO_DATE('00.00.0000','%d.%m.%Y')); # All test cases expected to fail should return # SQLSTATE 22007 <invalid datetime value> +--error 1292 INSERT INTO t1 (col2) VALUES(STR_TO_DATE('31.10.0000 15.30','%d.%m.%Y %H.%i')); --error 1292 @@ -264,6 +270,8 @@ INSERT INTO t1 (col3) VALUES (CAST('2004-10-15 10:15' AS DATETIME)); ## Test INSERT with CAST AS DATE into DATE # All test cases expected to fail should return # SQLSTATE 22007 <invalid date value> + +--error 1292 INSERT INTO t1 (col1) VALUES(CAST('0000-10-31' AS DATE)); --error 1292 @@ -290,6 +298,8 @@ INSERT INTO t1 (col1) VALUES(CAST('0000-00-00' AS DATE)); ## Test INSERT with CAST AS DATETIME into DATETIME # All test cases expected to fail should return # SQLSTATE 22007 <invalid datetime value> + +--error 1292 INSERT INTO t1 (col2) VALUES(CAST('0000-10-31 15:30' AS DATETIME)); --error 1292 @@ -356,6 +366,8 @@ INSERT INTO t1 (col3) VALUES (CONVERT('2004-10-15 10:15',DATETIME)); ## Test INSERT with CONVERT to DATE into DATE # All test cases expected to fail should return # SQLSTATE 22007 <invalid date value> + +--error 1292 INSERT INTO t1 (col1) VALUES(CONVERT('0000-10-31' , DATE)); --error 1292 @@ -381,6 +393,8 @@ INSERT INTO t1 (col1) VALUES(CONVERT('0000-00-00',DATE)); ## Test INSERT with CONVERT to DATETIME into DATETIME # All test cases expected to fail should return # SQLSTATE 22007 <invalid datetime value> + +--error 1292 INSERT INTO t1 (col2) VALUES(CONVERT('0000-10-31 15:30',DATETIME)); --error 1292 diff --git a/mysql-test/t/type_blob.test b/mysql-test/t/type_blob.test index 503d7ffc0b9..6d79dcc863b 100644 --- a/mysql-test/t/type_blob.test +++ b/mysql-test/t/type_blob.test @@ -423,3 +423,18 @@ alter table t1 modify a binary(5); select hex(a) from t1 order by a; select hex(concat(a,'\0')) as b from t1 order by concat(a,'\0'); drop table t1; + +# +# Bug #19489: Inconsistent support for DEFAULT in TEXT columns +# +create table t1 (a text default ''); +show create table t1; +insert into t1 values (default); +select * from t1; +drop table t1; +set @@sql_mode='TRADITIONAL'; +--error ER_BLOB_CANT_HAVE_DEFAULT +create table t1 (a text default ''); +set @@sql_mode=''; + +--echo End of 5.0 tests diff --git a/mysql-test/t/udf.test b/mysql-test/t/udf.test index c8843e42f87..96e559f5c05 100644 --- a/mysql-test/t/udf.test +++ b/mysql-test/t/udf.test @@ -110,6 +110,17 @@ SELECT metaphon(v) AS f FROM bug19904; DROP TABLE bug19904; # +# Bug#21269: DEFINER-clause is allowed for UDF-functions +# + +--error ER_WRONG_USAGE +CREATE DEFINER=CURRENT_USER() FUNCTION should_not_parse +RETURNS STRING SONAME "should_not_parse.so"; + +--error ER_WRONG_USAGE +CREATE DEFINER=someone@somewhere FUNCTION should_not_parse +RETURNS STRING SONAME "should_not_parse.so"; +# # Bug#19862: Sort with filesort by function evaluates function twice # create table t1(f1 int); diff --git a/mysql-test/t/union.test b/mysql-test/t/union.test index fdb5f968589..bf5c5e066f0 100644 --- a/mysql-test/t/union.test +++ b/mysql-test/t/union.test @@ -849,3 +849,10 @@ drop table t1, t2; (select avg(1)) union (select avg(1)) union (select avg(1)) union (select avg(1)) union (select avg(1)) union (select avg(1)); +# +# Bug #16881: password() and union select +# (The issue was poor handling of character set aggregation.) +# +select _utf8'12' union select _latin1'12345'; + +--echo End of 5.0 tests diff --git a/mysql-test/t/user_var.test b/mysql-test/t/user_var.test index e1b23a1782f..58c52b59a5a 100644 --- a/mysql-test/t/user_var.test +++ b/mysql-test/t/user_var.test @@ -171,3 +171,34 @@ set @first_var= cast(NULL as CHAR); create table t1 select @first_var; show create table t1; drop table t1; + +# +# Bug #7498 User variable SET saves SIGNED BIGINT as UNSIGNED BIGINT +# + +# First part, set user var to large number and select it +set @a=18446744071710965857; +select @a; + +# Second part, set user var from large number in table +# then select it +CREATE TABLE `bigfailure` ( + `afield` BIGINT UNSIGNED NOT NULL +); +INSERT INTO `bigfailure` VALUES (18446744071710965857); +SELECT * FROM bigfailure; +select * from (SELECT afield FROM bigfailure) as b; +select * from bigfailure where afield = (SELECT afield FROM bigfailure); +select * from bigfailure where afield = 18446744071710965857; +# This is fixed in 5.0, to be uncommented there +#select * from bigfailure where afield = '18446744071710965857'; +select * from bigfailure where afield = 18446744071710965856+1; + +SET @a := (SELECT afield FROM bigfailure); +SELECT @a; +SET @a := (select afield from (SELECT afield FROM bigfailure) as b); +SELECT @a; +SET @a := (select * from bigfailure where afield = (SELECT afield FROM bigfailure)); +SELECT @a; + +drop table bigfailure; diff --git a/sql-common/client.c b/sql-common/client.c index feaa4ed0bfd..fb76c864e79 100644 --- a/sql-common/client.c +++ b/sql-common/client.c @@ -579,7 +579,7 @@ err: *****************************************************************************/ ulong -net_safe_read(MYSQL *mysql) +cli_safe_read(MYSQL *mysql) { NET *net= &mysql->net; ulong len=0; @@ -622,6 +622,16 @@ net_safe_read(MYSQL *mysql) } else set_mysql_error(mysql, CR_UNKNOWN_ERROR, unknown_sqlstate); + /* + Cover a protocol design error: error packet does not + contain the server status. Therefore, the client has no way + to find out whether there are more result sets of + a multiple-result-set statement pending. Luckily, in 5.0 an + error always aborts execution of a statement, wherever it is + a multi-statement or a stored procedure, so it should be + safe to unconditionally turn off the flag here. + */ + mysql->server_status&= ~SERVER_MORE_RESULTS_EXISTS; DBUG_PRINT("error",("Got error: %d/%s (%s)", net->last_errno, net->sqlstate, net->last_error)); @@ -648,7 +658,7 @@ cli_advanced_command(MYSQL *mysql, enum enum_server_command command, NET *net= &mysql->net; my_bool result= 1; init_sigpipe_variables - DBUG_ENTER("cli_advanced_command"); + DBUG_ENTER("cli_advanced_command"); /* Don't give sigpipe errors if the client doesn't want them */ set_sigpipe(mysql); @@ -658,7 +668,8 @@ cli_advanced_command(MYSQL *mysql, enum enum_server_command command, if (mysql_reconnect(mysql)) DBUG_RETURN(1); } - if (mysql->status != MYSQL_STATUS_READY) + if (mysql->status != MYSQL_STATUS_READY || + mysql->server_status & SERVER_MORE_RESULTS_EXISTS) { DBUG_PRINT("error",("state: %d", mysql->status)); set_mysql_error(mysql, CR_COMMANDS_OUT_OF_SYNC, unknown_sqlstate); @@ -697,7 +708,7 @@ cli_advanced_command(MYSQL *mysql, enum enum_server_command command, } result=0; if (!skip_check) - result= ((mysql->packet_length=net_safe_read(mysql)) == packet_error ? + result= ((mysql->packet_length=cli_safe_read(mysql)) == packet_error ? 1 : 0); end: reset_sigpipe(mysql); @@ -749,7 +760,7 @@ static void cli_flush_use_result(MYSQL *mysql) for (;;) { ulong pkt_len; - if ((pkt_len=net_safe_read(mysql)) == packet_error) + if ((pkt_len=cli_safe_read(mysql)) == packet_error) break; if (pkt_len <= 8 && mysql->net.read_pos[0] == 254) { @@ -1271,7 +1282,7 @@ MYSQL_DATA *cli_read_rows(MYSQL *mysql,MYSQL_FIELD *mysql_fields, NET *net = &mysql->net; DBUG_ENTER("cli_read_rows"); - if ((pkt_len= net_safe_read(mysql)) == packet_error) + if ((pkt_len= cli_safe_read(mysql)) == packet_error) DBUG_RETURN(0); if (!(result=(MYSQL_DATA*) my_malloc(sizeof(MYSQL_DATA), MYF(MY_WME | MY_ZEROFILL)))) @@ -1336,7 +1347,7 @@ MYSQL_DATA *cli_read_rows(MYSQL *mysql,MYSQL_FIELD *mysql_fields, } } cur->data[field]=to; /* End of last field */ - if ((pkt_len=net_safe_read(mysql)) == packet_error) + if ((pkt_len=cli_safe_read(mysql)) == packet_error) { free_rows(result); DBUG_RETURN(0); @@ -1368,7 +1379,7 @@ read_one_row(MYSQL *mysql,uint fields,MYSQL_ROW row, ulong *lengths) uchar *pos, *prev_pos, *end_pos; NET *net= &mysql->net; - if ((pkt_len=net_safe_read(mysql)) == packet_error) + if ((pkt_len=cli_safe_read(mysql)) == packet_error) return -1; if (pkt_len <= 8 && net->read_pos[0] == 254) { @@ -1645,23 +1656,23 @@ static MYSQL_RES *cli_use_result(MYSQL *mysql); static MYSQL_METHODS client_methods= { - cli_read_query_result, - cli_advanced_command, - cli_read_rows, - cli_use_result, - cli_fetch_lengths, - cli_flush_use_result + cli_read_query_result, /* read_query_result */ + cli_advanced_command, /* advanced_command */ + cli_read_rows, /* read_rows */ + cli_use_result, /* use_result */ + cli_fetch_lengths, /* fetch_lengths */ + cli_flush_use_result /* flush_use_result */ #ifndef MYSQL_SERVER - ,cli_list_fields, - cli_read_prepare_result, - cli_stmt_execute, - cli_read_binary_rows, - cli_unbuffered_fetch, - NULL, - cli_read_statistics, - cli_read_query_result, - cli_read_change_user_result, - cli_read_binary_rows + ,cli_list_fields, /* list_fields */ + cli_read_prepare_result, /* read_prepare_result */ + cli_stmt_execute, /* stmt_execute */ + cli_read_binary_rows, /* read_binary_rows */ + cli_unbuffered_fetch, /* unbuffered_fetch */ + NULL, /* free_embedded_thd */ + cli_read_statistics, /* read_statistics */ + cli_read_query_result, /* next_result */ + cli_read_change_user_result, /* read_change_user_result */ + cli_read_binary_rows /* read_rows_from_cursor */ #endif }; @@ -2024,7 +2035,7 @@ CLI_MYSQL_REAL_CONNECT(MYSQL *mysql,const char *host, const char *user, Part 1: Connection established, read and parse first packet */ - if ((pkt_length=net_safe_read(mysql)) == packet_error) + if ((pkt_length=cli_safe_read(mysql)) == packet_error) goto error; /* Check if version of protocol matches current one */ @@ -2248,7 +2259,7 @@ CLI_MYSQL_REAL_CONNECT(MYSQL *mysql,const char *host, const char *user, OK-packet, or re-request scrambled password. */ - if ((pkt_length=net_safe_read(mysql)) == packet_error) + if ((pkt_length=cli_safe_read(mysql)) == packet_error) goto error; if (pkt_length == 1 && net->read_pos[0] == 254 && @@ -2265,7 +2276,7 @@ CLI_MYSQL_REAL_CONNECT(MYSQL *mysql,const char *host, const char *user, goto error; } /* Read what server thinks about out new auth message report */ - if (net_safe_read(mysql) == packet_error) + if (cli_safe_read(mysql) == packet_error) goto error; } @@ -2589,7 +2600,7 @@ static my_bool cli_read_query_result(MYSQL *mysql) */ mysql = mysql->last_used_con; - if ((length = net_safe_read(mysql)) == packet_error) + if ((length = cli_safe_read(mysql)) == packet_error) DBUG_RETURN(1); free_old_query(mysql); /* Free old result */ #ifdef MYSQL_CLIENT /* Avoid warn of unused labels*/ @@ -2624,7 +2635,7 @@ get_info: if (field_count == NULL_LENGTH) /* LOAD DATA LOCAL INFILE */ { int error=handle_local_infile(mysql,(char*) pos); - if ((length=net_safe_read(mysql)) == packet_error || error) + if ((length= cli_safe_read(mysql)) == packet_error || error) DBUG_RETURN(1); goto get_info; /* Get info packet */ } diff --git a/sql-common/my_time.c b/sql-common/my_time.c index f75298e4f5d..8efe09a45be 100644 --- a/sql-common/my_time.c +++ b/sql-common/my_time.c @@ -69,6 +69,7 @@ uint calc_days_in_year(uint year) Here we assume that year and month is ok ! If month is 0 we allow any date. (This only happens if we allow zero date parts in str_to_datetime()) + Disallow dates with zero year and non-zero month and/or day. RETURN 0 ok @@ -85,7 +86,8 @@ static my_bool check_date(const MYSQL_TIME *ltime, my_bool not_zero_date, (!(flags & TIME_INVALID_DATES) && ltime->month && ltime->day > days_in_month[ltime->month-1] && (ltime->month != 2 || calc_days_in_year(ltime->year) != 366 || - ltime->day != 29))) + ltime->day != 29)) || + (ltime->year == 0 && (ltime->month != 0 || ltime->day != 0))) { *was_cut= 2; return TRUE; diff --git a/sql/field.cc b/sql/field.cc index 4e3c54fbd63..6a205db0d80 100644 --- a/sql/field.cc +++ b/sql/field.cc @@ -8523,7 +8523,8 @@ bool create_field::init(THD *thd, char *fld_name, enum_field_types fld_type, comment= *fld_comment; /* - Set flag if this field doesn't have a default value + Set NO_DEFAULT_VALUE_FLAG if this field doesn't have a default value and + it is NOT NULL, not an AUTO_INCREMENT field and not a TIMESTAMP. */ if (!fld_default_value && !(fld_type_modifier & AUTO_INCREMENT_FLAG) && (fld_type_modifier & NOT_NULL_FLAG) && fld_type != FIELD_TYPE_TIMESTAMP) @@ -8600,12 +8601,28 @@ bool create_field::init(THD *thd, char *fld_name, enum_field_types fld_type, /* Allow empty as default value. */ String str,*res; res= fld_default_value->val_str(&str); - if (res->length()) + /* + A default other than '' is always an error, and any non-NULL + specified default is an error in strict mode. + */ + if (res->length() || (thd->variables.sql_mode & + (MODE_STRICT_TRANS_TABLES | + MODE_STRICT_ALL_TABLES))) { my_error(ER_BLOB_CANT_HAVE_DEFAULT, MYF(0), fld_name); /* purecov: inspected */ DBUG_RETURN(TRUE); } + else + { + /* + Otherwise a default of '' is just a warning. + */ + push_warning_printf(thd, MYSQL_ERROR::WARN_LEVEL_WARN, + ER_BLOB_CANT_HAVE_DEFAULT, + ER(ER_BLOB_CANT_HAVE_DEFAULT), + fld_name); + } def= 0; } flags|= BLOB_FLAG; diff --git a/sql/item.cc b/sql/item.cc index 1afe25b1990..6e661afbd91 100644 --- a/sql/item.cc +++ b/sql/item.cc @@ -1456,7 +1456,8 @@ bool agg_item_charsets(DTCollation &coll, const char *fname, In case we're in statement prepare, create conversion item in its memory: it will be reused on each execute. */ - arena= thd->activate_stmt_arena_if_needed(&backup); + arena= thd->is_stmt_prepare() ? thd->activate_stmt_arena_if_needed(&backup) + : NULL; for (i= 0, arg= args; i < nargs; i++, arg+= item_sep) { @@ -1491,7 +1492,7 @@ bool agg_item_charsets(DTCollation &coll, const char *fname, been created in prepare. In this case register the change for rollback. */ - if (arena && arena->is_conventional()) + if (arena) *arg= conv; else thd->change_item_tree(arg, conv); @@ -6148,14 +6149,13 @@ bool Item_type_holder::join_types(THD *thd, Item *item) max_length= my_decimal_precision_to_length(precision, decimals, unsigned_flag); } - else - max_length= max(max_length, display_length(item)); - + switch (Field::result_merge_type(fld_type)) { case STRING_RESULT: { const char *old_cs, *old_derivation; + uint32 old_max_chars= max_length / collation.collation->mbmaxlen; old_cs= collation.collation->name; old_derivation= collation.derivation_name(); if (collation.aggregate(item->collation, MY_COLL_ALLOW_CONV)) @@ -6167,6 +6167,14 @@ bool Item_type_holder::join_types(THD *thd, Item *item) "UNION"); DBUG_RETURN(TRUE); } + /* + To figure out max_length, we have to take into account possible + expansion of the size of the values because of character set + conversions. + */ + max_length= max(old_max_chars * collation.collation->mbmaxlen, + display_length(item) / item->collation.collation->mbmaxlen * + collation.collation->mbmaxlen); break; } case REAL_RESULT: @@ -6185,7 +6193,8 @@ bool Item_type_holder::join_types(THD *thd, Item *item) max_length= (fld_type == MYSQL_TYPE_FLOAT) ? FLT_DIG+6 : DBL_DIG+7; break; } - default:; + default: + max_length= max(max_length, display_length(item)); }; maybe_null|= item->maybe_null; get_full_info(item); diff --git a/sql/item_func.cc b/sql/item_func.cc index e901eaf8654..9a2ef4e5482 100644 --- a/sql/item_func.cc +++ b/sql/item_func.cc @@ -3412,6 +3412,7 @@ static user_var_entry *get_variable(HASH *hash, LEX_STRING &name, entry->length=0; entry->update_query_id=0; entry->collation.set(NULL, DERIVATION_IMPLICIT); + entry->unsigned_flag= 0; /* If we are here, we were called from a SET or a query which sets a variable. Imagine it is this: @@ -3498,6 +3499,7 @@ Item_func_set_user_var::fix_length_and_dec() type - type of new value cs - charset info for new value dv - derivation for new value + unsigned_arg - indiates if a value of type INT_RESULT is unsigned RETURN VALUE False - success, True - failure @@ -3505,7 +3507,8 @@ Item_func_set_user_var::fix_length_and_dec() static bool update_hash(user_var_entry *entry, bool set_null, void *ptr, uint length, - Item_result type, CHARSET_INFO *cs, Derivation dv) + Item_result type, CHARSET_INFO *cs, Derivation dv, + bool unsigned_arg) { if (set_null) { @@ -3553,6 +3556,7 @@ update_hash(user_var_entry *entry, bool set_null, void *ptr, uint length, ((my_decimal*)entry->value)->fix_buffer_pointer(); entry->length= length; entry->collation.set(cs, dv); + entry->unsigned_flag= unsigned_arg; } entry->type=type; return 0; @@ -3561,7 +3565,8 @@ update_hash(user_var_entry *entry, bool set_null, void *ptr, uint length, bool Item_func_set_user_var::update_hash(void *ptr, uint length, Item_result type, - CHARSET_INFO *cs, Derivation dv) + CHARSET_INFO *cs, Derivation dv, + bool unsigned_arg) { /* If we set a variable explicitely to NULL then keep the old @@ -3570,7 +3575,7 @@ Item_func_set_user_var::update_hash(void *ptr, uint length, Item_result type, if ((null_value= args[0]->null_value) && null_item) type= entry->type; // Don't change type of item if (::update_hash(entry, (null_value= args[0]->null_value), - ptr, length, type, cs, dv)) + ptr, length, type, cs, dv, unsigned_arg)) { current_thd->fatal_error(); // Probably end of memory null_value= 1; @@ -3652,7 +3657,10 @@ String *user_var_entry::val_str(my_bool *null_value, String *str, str->set_real(*(double*) value, decimals, &my_charset_bin); break; case INT_RESULT: - str->set(*(longlong*) value, &my_charset_bin); + if (!unsigned_flag) + str->set(*(longlong*) value, &my_charset_bin); + else + str->set(*(ulonglong*) value, &my_charset_bin); break; case DECIMAL_RESULT: my_decimal2string(E_DEC_FATAL_ERROR, (my_decimal *)value, 0, 0, 0, str); @@ -3723,6 +3731,7 @@ Item_func_set_user_var::check() case INT_RESULT: { save_result.vint= args[0]->val_int(); + unsigned_flag= args[0]->unsigned_flag; break; } case STRING_RESULT: @@ -3778,7 +3787,8 @@ Item_func_set_user_var::update() case INT_RESULT: { res= update_hash((void*) &save_result.vint, sizeof(save_result.vint), - INT_RESULT, &my_charset_bin, DERIVATION_IMPLICIT); + INT_RESULT, &my_charset_bin, DERIVATION_IMPLICIT, + unsigned_flag); break; } case STRING_RESULT: @@ -4157,7 +4167,7 @@ bool Item_user_var_as_out_param::fix_fields(THD *thd, Item **ref) void Item_user_var_as_out_param::set_null_value(CHARSET_INFO* cs) { if (::update_hash(entry, TRUE, 0, 0, STRING_RESULT, cs, - DERIVATION_IMPLICIT)) + DERIVATION_IMPLICIT, 0 /* unsigned_arg */)) current_thd->fatal_error(); // Probably end of memory } @@ -4166,7 +4176,7 @@ void Item_user_var_as_out_param::set_value(const char *str, uint length, CHARSET_INFO* cs) { if (::update_hash(entry, FALSE, (void*)str, length, STRING_RESULT, cs, - DERIVATION_IMPLICIT)) + DERIVATION_IMPLICIT, 0 /* unsigned_arg */)) current_thd->fatal_error(); // Probably end of memory } @@ -4837,7 +4847,9 @@ Item_func_sp::execute_impl(THD *thd, Field *return_value_fld) { bool err_status= TRUE; Sub_statement_state statement_state; - Security_context *save_security_ctx= thd->security_ctx, *save_ctx_func; +#ifndef NO_EMBEDDED_ACCESS_CHECKS + Security_context *save_security_ctx= thd->security_ctx; +#endif DBUG_ENTER("Item_func_sp::execute_impl"); @@ -4848,7 +4860,7 @@ Item_func_sp::execute_impl(THD *thd, Field *return_value_fld) thd->security_ctx= context->security_ctx; } #endif - if (find_and_check_access(thd, EXECUTE_ACL, &save_ctx_func)) + if (find_and_check_access(thd)) goto error; /* @@ -4860,13 +4872,11 @@ Item_func_sp::execute_impl(THD *thd, Field *return_value_fld) err_status= m_sp->execute_function(thd, args, arg_count, return_value_fld); thd->restore_sub_statement_state(&statement_state); -#ifndef NO_EMBEDDED_ACCESS_CHECKS - sp_restore_security_context(thd, save_ctx_func); error: +#ifndef NO_EMBEDDED_ACCESS_CHECKS thd->security_ctx= save_security_ctx; -#else -error: #endif + DBUG_RETURN(err_status); } @@ -4983,70 +4993,38 @@ Item_func_sp::tmp_table_field(TABLE *t_arg) SYNOPSIS find_and_check_access() thd thread handler - want_access requested access - save backup of security context RETURN FALSE Access granted TRUE Requested access can't be granted or function doesn't exists - In this case security context is not changed and *save = 0 NOTES Checks if requested access to function can be granted to user. If function isn't found yet, it searches function first. If function can't be found or user don't have requested access error is raised. - If security context sp_ctx is provided and access can be granted then - switch back to previous context isn't performed. - In case of access error or if context is not provided then - find_and_check_access() switches back to previous security context. */ bool -Item_func_sp::find_and_check_access(THD *thd, ulong want_access, - Security_context **save) +Item_func_sp::find_and_check_access(THD *thd) { - bool res= TRUE; - - *save= 0; // Safety if error if (! m_sp && ! (m_sp= sp_find_routine(thd, TYPE_ENUM_FUNCTION, m_name, &thd->sp_func_cache, TRUE))) { my_error(ER_SP_DOES_NOT_EXIST, MYF(0), "FUNCTION", m_name->m_qname.str); - goto error; + return TRUE; } #ifndef NO_EMBEDDED_ACCESS_CHECKS - if (check_routine_access(thd, want_access, - m_sp->m_db.str, m_sp->m_name.str, 0, FALSE)) - goto error; - - sp_change_security_context(thd, m_sp, save); - /* - If we changed context to run as another user, we need to check the - access right for the new context again as someone may have deleted - this person the right to use the procedure - - TODO: - Cache if the definer has the right to use the object on the first - usage and only reset the cache if someone does a GRANT statement - that 'may' affect this. - */ - if (*save && - check_routine_access(thd, want_access, + if (check_routine_access(thd, EXECUTE_ACL, m_sp->m_db.str, m_sp->m_name.str, 0, FALSE)) - { - sp_restore_security_context(thd, *save); - *save= 0; // Safety - goto error; - } + return TRUE; #endif - res= FALSE; // no error -error: - return res; + return FALSE; } + bool Item_func_sp::fix_fields(THD *thd, Item **ref) { @@ -5057,19 +5035,23 @@ Item_func_sp::fix_fields(THD *thd, Item **ref) { /* Here we check privileges of the stored routine only during view - creation, in order to validate the view. A runtime check is perfomed - in Item_func_sp::execute(), and this method is not called during - context analysis. We do not need to restore the security context - changed in find_and_check_access because all view structures created - in CREATE VIEW are not used for execution. Notice, that during view - creation we do not infer into stored routine bodies and do not check - privileges of its statements, which would probably be a good idea - especially if the view has SQL SECURITY DEFINER and the used stored - procedure has SQL SECURITY DEFINER + creation, in order to validate the view. A runtime check is + perfomed in Item_func_sp::execute(), and this method is not + called during context analysis. Notice, that during view + creation we do not infer into stored routine bodies and do not + check privileges of its statements, which would probably be a + good idea especially if the view has SQL SECURITY DEFINER and + the used stored procedure has SQL SECURITY DEFINER. */ - Security_context *save_ctx; - if (!(res= find_and_check_access(thd, EXECUTE_ACL, &save_ctx))) - sp_restore_security_context(thd, save_ctx); + res= find_and_check_access(thd); +#ifndef NO_EMBEDDED_ACCESS_CHECKS + Security_context *save_secutiry_ctx; + if (!res && !(res= set_routine_security_ctx(thd, m_sp, false, + &save_secutiry_ctx))) + { + sp_restore_security_context(thd, save_secutiry_ctx); + } +#endif /* ! NO_EMBEDDED_ACCESS_CHECKS */ } return res; } diff --git a/sql/item_func.h b/sql/item_func.h index 3a1952c8d0f..168430a5a11 100644 --- a/sql/item_func.h +++ b/sql/item_func.h @@ -1190,8 +1190,6 @@ class Item_func_set_user_var :public Item_func String *vstr; my_decimal *vdec; } save_result; - String save_buff; - public: LEX_STRING name; // keep it public @@ -1202,8 +1200,8 @@ public: longlong val_int(); String *val_str(String *str); my_decimal *val_decimal(my_decimal *); - bool update_hash(void *ptr, uint length, enum Item_result type, - CHARSET_INFO *cs, Derivation dv); + bool update_hash(void *ptr, uint length, enum Item_result type, + CHARSET_INFO *cs, Derivation dv, bool unsigned_arg= 0); bool check(); bool update(); enum Item_result result_type () const { return cached_result_type; } @@ -1502,8 +1500,7 @@ public: { context= (Name_resolution_context *)cntx; return FALSE; } void fix_length_and_dec(); - bool find_and_check_access(THD * thd, ulong want_access, - Security_context **backup); + bool find_and_check_access(THD * thd); virtual enum Functype functype() const { return FUNC_SP; } bool fix_fields(THD *thd, Item **ref); diff --git a/sql/item_strfunc.cc b/sql/item_strfunc.cc index dee7f408733..23c7cb4c3d8 100644 --- a/sql/item_strfunc.cc +++ b/sql/item_strfunc.cc @@ -2985,6 +2985,16 @@ String *Item_func_uncompress::val_str(String *str) if (res->is_empty()) return res; + /* If length is less than 4 bytes, data is corrupt */ + if (res->length() <= 4) + { + push_warning_printf(current_thd,MYSQL_ERROR::WARN_LEVEL_ERROR, + ER_ZLIB_Z_DATA_ERROR, + ER(ER_ZLIB_Z_DATA_ERROR)); + goto err; + } + + /* Size of uncompressed data is stored as first 4 bytes of field */ new_size= uint4korr(res->ptr()) & 0x3FFFFFFF; if (new_size > current_thd->variables.max_allowed_packet) { diff --git a/sql/item_strfunc.h b/sql/item_strfunc.h index e085c0b4d7b..1b843b27203 100644 --- a/sql/item_strfunc.h +++ b/sql/item_strfunc.h @@ -831,7 +831,7 @@ class Item_func_uncompress: public Item_str_func String buffer; public: Item_func_uncompress(Item *a): Item_str_func(a){} - void fix_length_and_dec(){max_length= MAX_BLOB_WIDTH;} + void fix_length_and_dec(){ maybe_null= 1; max_length= MAX_BLOB_WIDTH; } const char *func_name() const{return "uncompress";} String *val_str(String *) ZLIB_DEPENDED_FUNCTION bool check_partition_func_processor(byte *bool_arg) { return 0;} diff --git a/sql/item_subselect.cc b/sql/item_subselect.cc index 7dfe65d793a..e24a57809f2 100644 --- a/sql/item_subselect.cc +++ b/sql/item_subselect.cc @@ -1554,6 +1554,7 @@ static Item_result set_row(List<Item> &item_list, Item *item, item->max_length= sel_item->max_length; res_type= sel_item->result_type(); item->decimals= sel_item->decimals; + item->unsigned_flag= sel_item->unsigned_flag; *maybe_null= sel_item->maybe_null; if (!(row[i]= Item_cache::get_cache(res_type))) return STRING_RESULT; // we should return something diff --git a/sql/item_sum.cc b/sql/item_sum.cc index 024b0ecfb42..ee23139d79a 100644 --- a/sql/item_sum.cc +++ b/sql/item_sum.cc @@ -1278,11 +1278,10 @@ Field *Item_sum_variance::create_tmp_field(bool group, TABLE *table, sizeof(double)*2) + sizeof(longlong), 0, name, &my_charset_bin); } - else if (hybrid_type == DECIMAL_RESULT) - field= new Field_new_decimal(max_length, maybe_null, name, - decimals, unsigned_flag); else - field= new Field_double(max_length, maybe_null, name, decimals); + { + field= new Field_double(max_length, maybe_null,name,table,decimals); + } if (field) field->init(table); return field; diff --git a/sql/item_sum.h b/sql/item_sum.h index a0cd08dcb11..3679780db60 100644 --- a/sql/item_sum.h +++ b/sql/item_sum.h @@ -688,7 +688,7 @@ public: { return sample ? "var_samp(" : "variance("; } Item *copy_or_same(THD* thd); Field *create_tmp_field(bool group, TABLE *table, uint convert_blob_length); - enum Item_result result_type () const { return hybrid_type; } + enum Item_result result_type () const { return REAL_RESULT; } }; class Item_sum_std; diff --git a/sql/item_timefunc.cc b/sql/item_timefunc.cc index 2c8d8423d50..e0c80087c05 100644 --- a/sql/item_timefunc.cc +++ b/sql/item_timefunc.cc @@ -2756,6 +2756,8 @@ longlong Item_func_timestamp_diff::val_int() { uint year_beg, year_end, month_beg, month_end, day_beg, day_end; uint years= 0; + uint second_beg, second_end, microsecond_beg, microsecond_end; + if (neg == -1) { year_beg= ltime2.year; @@ -2764,6 +2766,10 @@ longlong Item_func_timestamp_diff::val_int() month_end= ltime1.month; day_beg= ltime2.day; day_end= ltime1.day; + second_beg= ltime2.hour * 3600 + ltime2.minute * 60 + ltime2.second; + second_end= ltime1.hour * 3600 + ltime1.minute * 60 + ltime1.second; + microsecond_beg= ltime2.second_part; + microsecond_end= ltime1.second_part; } else { @@ -2773,6 +2779,10 @@ longlong Item_func_timestamp_diff::val_int() month_end= ltime2.month; day_beg= ltime1.day; day_end= ltime2.day; + second_beg= ltime1.hour * 3600 + ltime1.minute * 60 + ltime1.second; + second_end= ltime2.hour * 3600 + ltime2.minute * 60 + ltime2.second; + microsecond_beg= ltime1.second_part; + microsecond_end= ltime2.second_part; } /* calc years */ @@ -2786,8 +2796,13 @@ longlong Item_func_timestamp_diff::val_int() months+= 12 - (month_beg - month_end); else months+= (month_end - month_beg); + if (day_end < day_beg) months-= 1; + else if ((day_end == day_beg) && + ((second_end < second_beg) || + (second_end == second_beg && microsecond_end < microsecond_beg))) + months-= 1; } switch (int_type) { diff --git a/sql/mysql_priv.h b/sql/mysql_priv.h index a9ecbb23a27..15cf463b744 100644 --- a/sql/mysql_priv.h +++ b/sql/mysql_priv.h @@ -1019,8 +1019,6 @@ bool mysqld_show_create_db(THD *thd, char *dbname, HA_CREATE_INFO *create); void mysqld_list_processes(THD *thd,const char *user,bool verbose); int mysqld_show_status(THD *thd); int mysqld_show_variables(THD *thd,const char *wild); -int mysql_find_files(THD *thd,List<char> *files, const char *db, - const char *path, const char *wild, bool dir); bool mysqld_show_storage_engines(THD *thd); bool mysqld_show_authors(THD *thd); bool mysqld_show_contributors(THD *thd); @@ -1464,7 +1462,11 @@ bool is_keyword(const char *name, uint len); #define MY_DB_OPT_FILE "db.opt" bool my_database_names_init(void); void my_database_names_free(void); +bool check_db_dir_existence(const char *db_name); bool load_db_opt(THD *thd, const char *path, HA_CREATE_INFO *create); +bool load_db_opt_by_name(THD *thd, const char *db_name, + HA_CREATE_INFO *db_create_info); +bool my_dbopt_init(void); void my_dbopt_cleanup(void); extern int creating_database; // How many database locks are made extern int creating_table; // How many mysql_create_table() are running diff --git a/sql/mysqld.cc b/sql/mysqld.cc index 087613c6b7c..b4558dec35e 100644 --- a/sql/mysqld.cc +++ b/sql/mysqld.cc @@ -2837,6 +2837,11 @@ You should consider changing lower_case_table_names to 1 or 2", mysql_real_data_home); lower_case_table_names= 0; } + else + { + lower_case_file_system= + (test_if_case_insensitive(mysql_real_data_home) == 1); + } /* Reset table_alias_charset, now that lower_case_table_names is set. */ table_alias_charset= (lower_case_table_names ? diff --git a/sql/protocol.cc b/sql/protocol.cc index 2edc11b6b3e..46d28a16c58 100644 --- a/sql/protocol.cc +++ b/sql/protocol.cc @@ -322,7 +322,7 @@ static char eof_buff[1]= { (char) 254 }; /* Marker for end of fields */ 254 Marker (1 byte) warning_count Stored in 2 bytes; New in 4.1 protocol status_flag Stored in 2 bytes; - For flags like SERVER_STATUS_MORE_RESULTS + For flags like SERVER_MORE_RESULTS_EXISTS Note that the warning count will not be sent if 'no_flush' is set as we don't want to report the warning count until all data is sent to the diff --git a/sql/slave.cc b/sql/slave.cc index 19060eba2d4..84d97242bf3 100644 --- a/sql/slave.cc +++ b/sql/slave.cc @@ -2823,7 +2823,7 @@ static ulong read_event(MYSQL* mysql, MASTER_INFO *mi, bool* suppress_warnings) DBUG_RETURN(packet_error); #endif - len = net_safe_read(mysql); + len = cli_safe_read(mysql); if (len == packet_error || (long) len < 1) { if (mysql_errno(mysql) == ER_NET_READ_INTERRUPTED) diff --git a/sql/sp.cc b/sql/sp.cc index f60a167e39a..b7671803cf5 100644 --- a/sql/sp.cc +++ b/sql/sp.cc @@ -497,6 +497,13 @@ sp_returns_type(THD *thd, String &result, sp_head *sp) table.s = &share; field= sp->create_result_field(0, 0, &table); field->sql_type(result); + + if (field->has_charset()) + { + result.append(STRING_WITH_LEN(" CHARSET ")); + result.append(field->charset()->csname); + } + delete field; } @@ -628,7 +635,10 @@ db_create_routine(THD *thd, int type, sp_head *sp) log_query.append(STRING_WITH_LEN("CREATE ")); append_definer(thd, &log_query, &thd->lex->definer->user, &thd->lex->definer->host); - log_query.append(thd->lex->stmt_definition_begin); + log_query.append(thd->lex->stmt_definition_begin, + (char *)sp->m_body_begin - + thd->lex->stmt_definition_begin + + sp->m_body.length); /* Such a statement can always go directly to binlog, no trans cache */ thd->binlog_query(THD::MYSQL_QUERY_TYPE, @@ -975,6 +985,11 @@ sp_find_routine(THD *thd, int type, sp_name *name, sp_cache **cp, sp_head *new_sp; const char *returns= ""; char definer[USER_HOST_BUFF_SIZE]; + + /* + String buffer for RETURNS data type must have system charset; + 64 -- size of "returns" column of mysql.proc. + */ String retstr(64); DBUG_PRINT("info", ("found: 0x%lx", (ulong)sp)); diff --git a/sql/sp_head.cc b/sql/sp_head.cc index 8368e828fdc..c967a82cffe 100644 --- a/sql/sp_head.cc +++ b/sql/sp_head.cc @@ -450,7 +450,14 @@ sp_head::sp_head() m_first_instance(this), m_first_free_instance(this), m_last_cached_sp(this), m_cont_level(0) { + const LEX_STRING str_reset= { NULL, 0 }; m_return_field_def.charset = NULL; + /* + FIXME: the only use case when name is NULL is events, and it should + be rewritten soon. Remove the else part and replace 'if' with + an assert when this is done. + */ + m_db= m_name= m_qname= str_reset; extern byte * sp_table_key(const byte *ptr, uint *plen, my_bool first); @@ -479,7 +486,7 @@ sp_head::init(LEX *lex) lex->trg_table_fields.empty(); my_init_dynamic_array(&m_instr, sizeof(sp_instr *), 16, 8); m_param_begin= m_param_end= m_body_begin= 0; - m_qname.str= m_db.str= m_name.str= m_params.str= + m_qname.str= m_db.str= m_name.str= m_params.str= m_body.str= m_defstr.str= 0; m_qname.length= m_db.length= m_name.length= m_params.length= m_body.length= m_defstr.length= 0; @@ -487,41 +494,42 @@ sp_head::init(LEX *lex) DBUG_VOID_RETURN; } + void -sp_head::init_strings(THD *thd, LEX *lex, sp_name *name) +sp_head::init_sp_name(THD *thd, sp_name *spname) +{ + DBUG_ENTER("sp_head::init_sp_name"); + + /* Must be initialized in the parser. */ + + DBUG_ASSERT(spname && spname->m_db.str && spname->m_db.length); + + /* We have to copy strings to get them into the right memroot. */ + + m_db.length= spname->m_db.length; + m_db.str= strmake_root(thd->mem_root, spname->m_db.str, spname->m_db.length); + + m_name.length= spname->m_name.length; + m_name.str= strmake_root(thd->mem_root, spname->m_name.str, + spname->m_name.length); + + if (spname->m_qname.length == 0) + spname->init_qname(thd); + + m_qname.length= spname->m_qname.length; + m_qname.str= strmake_root(thd->mem_root, spname->m_qname.str, + m_qname.length); +} + + +void +sp_head::init_strings(THD *thd, LEX *lex) { DBUG_ENTER("sp_head::init_strings"); const uchar *endp; /* Used to trim the end */ /* During parsing, we must use thd->mem_root */ MEM_ROOT *root= thd->mem_root; - if (name) - { - /* Must be initialized in the parser */ - DBUG_ASSERT(name->m_db.str && name->m_db.length); - - /* We have to copy strings to get them into the right memroot */ - m_db.length= name->m_db.length; - m_db.str= strmake_root(root, name->m_db.str, name->m_db.length); - m_name.length= name->m_name.length; - m_name.str= strmake_root(root, name->m_name.str, name->m_name.length); - - if (name->m_qname.length == 0) - name->init_qname(thd); - m_qname.length= name->m_qname.length; - m_qname.str= strmake_root(root, name->m_qname.str, m_qname.length); - } - else - { - /* - FIXME: the only use case when name is NULL is events, and it should - be rewritten soon. Remove the else part and replace 'if' with - an assert when this is done. - */ - LEX_STRING str_reset= { NULL, 0 }; - m_db= m_name= m_qname= str_reset; - } - if (m_param_begin && m_param_end) { m_params.length= m_param_end - m_param_begin; @@ -535,10 +543,7 @@ sp_head::init_strings(THD *thd, LEX *lex, sp_name *name) Trim "garbage" at the end. This is sometimes needed with the "/ * ! VERSION... * /" wrapper in dump files. */ - while (m_body_begin < endp && - (endp[-1] <= ' ' || endp[-1] == '*' || - endp[-1] == '/' || endp[-1] == ';')) - endp-= 1; + endp= skip_rear_comments(m_body_begin, endp); m_body.length= endp - m_body_begin; m_body.str= strmake_root(root, (char *)m_body_begin, m_body.length); @@ -1125,6 +1130,7 @@ sp_head::execute(THD *thd) thd->restore_active_arena(&execute_arena, &backup_arena); + thd->spcont->pop_all_cursors(); // To avoid memory leaks after an error /* Restore all saved */ old_packet.swap(thd->packet); @@ -1186,6 +1192,161 @@ sp_head::execute(THD *thd) m_first_instance->m_first_free_instance->m_recursion_level == m_recursion_level + 1)); m_first_instance->m_first_free_instance= this; + + DBUG_RETURN(err_status); +} + + +#ifndef NO_EMBEDDED_ACCESS_CHECKS +/* + set_routine_security_ctx() changes routine security context, and + checks if there is an EXECUTE privilege in new context. If there is + no EXECUTE privilege, it changes the context back and returns a + error. + + SYNOPSIS + set_routine_security_ctx() + thd thread handle + sp stored routine to change the context for + is_proc TRUE is procedure, FALSE if function + save_ctx pointer to an old security context + + RETURN + TRUE if there was a error, and the context wasn't changed. + FALSE if the context was changed. +*/ + +bool +set_routine_security_ctx(THD *thd, sp_head *sp, bool is_proc, + Security_context **save_ctx) +{ + *save_ctx= 0; + if (sp_change_security_context(thd, sp, save_ctx)) + return TRUE; + + /* + If we changed context to run as another user, we need to check the + access right for the new context again as someone may have revoked + the right to use the procedure from this user. + + TODO: + Cache if the definer has the right to use the object on the + first usage and only reset the cache if someone does a GRANT + statement that 'may' affect this. + */ + if (*save_ctx && + check_routine_access(thd, EXECUTE_ACL, + sp->m_db.str, sp->m_name.str, is_proc, FALSE)) + { + sp_restore_security_context(thd, *save_ctx); + *save_ctx= 0; + return TRUE; + } + + return FALSE; +} +#endif // ! NO_EMBEDDED_ACCESS_CHECKS + + +/* + Execute a trigger: + - changes security context for triggers + - switch to new memroot + - call sp_head::execute + - restore old memroot + - restores security context + + SYNOPSIS + sp_head::execute_trigger() + thd Thread handle + db database name + table table name + grant_info GRANT_INFO structure to be filled with + information about definer's privileges + on subject table + + RETURN + FALSE on success + TRUE on error +*/ + +bool +sp_head::execute_trigger(THD *thd, const char *db, const char *table, + GRANT_INFO *grant_info) +{ + sp_rcontext *octx = thd->spcont; + sp_rcontext *nctx = NULL; + bool err_status= FALSE; + MEM_ROOT call_mem_root; + Query_arena call_arena(&call_mem_root, Query_arena::INITIALIZED_FOR_SP); + Query_arena backup_arena; + + DBUG_ENTER("sp_head::execute_trigger"); + DBUG_PRINT("info", ("trigger %s", m_name.str)); + +#ifndef NO_EMBEDDED_ACCESS_CHECKS + Security_context *save_ctx; + if (sp_change_security_context(thd, this, &save_ctx)) + DBUG_RETURN(TRUE); + + /* + NOTE: TRIGGER_ACL should be used here. + */ + if (check_global_access(thd, SUPER_ACL)) + { + sp_restore_security_context(thd, save_ctx); + DBUG_RETURN(TRUE); + } + + /* + Fetch information about table-level privileges to GRANT_INFO + structure for subject table. Check of privileges that will use it + and information about column-level privileges will happen in + Item_trigger_field::fix_fields(). + */ + fill_effective_table_privileges(thd, grant_info, db, table); +#endif // NO_EMBEDDED_ACCESS_CHECKS + + /* + Prepare arena and memroot for objects which lifetime is whole + duration of trigger call (sp_rcontext, it's tables and items, + sp_cursor and Item_cache holders for case expressions). We can't + use caller's arena/memroot for those objects because in this case + some fixed amount of memory will be consumed for each trigger + invocation and so statements which involve lot of them will hog + memory. + + TODO: we should create sp_rcontext once per command and reuse it + on subsequent executions of a trigger. + */ + init_sql_alloc(&call_mem_root, MEM_ROOT_BLOCK_SIZE, 0); + thd->set_n_backup_active_arena(&call_arena, &backup_arena); + + if (!(nctx= new sp_rcontext(m_pcont, 0, octx)) || + nctx->init(thd)) + { + err_status= TRUE; + goto err_with_cleanup; + } + +#ifndef DBUG_OFF + nctx->sp= this; +#endif + + thd->spcont= nctx; + + err_status= execute(thd); + +err_with_cleanup: + thd->restore_active_arena(&call_arena, &backup_arena); +#ifndef NO_EMBEDDED_ACCESS_CHECKS + sp_restore_security_context(thd, save_ctx); +#endif // NO_EMBEDDED_ACCESS_CHECKS + delete nctx; + call_arena.free_items(); + free_root(&call_mem_root, MYF(0)); + thd->spcont= octx; + DBUG_RETURN(err_status); } @@ -1193,8 +1354,12 @@ sp_head::execute(THD *thd) /* Execute a function: - evaluate parameters + - changes security context for SUID routines + - switch to new memroot - call sp_head::execute + - restore old memroot - evaluate the return value + - restores security context SYNOPSIS sp_head::execute_function() @@ -1328,6 +1493,15 @@ sp_head::execute_function(THD *thd, Item **argp, uint argcount, } thd->spcont= nctx; +#ifndef NO_EMBEDDED_ACCESS_CHECKS + Security_context *save_security_ctx; + if (set_routine_security_ctx(thd, this, FALSE, &save_security_ctx)) + { + err_status= TRUE; + goto err_with_cleanup; + } +#endif + if (need_binlog_call) { reset_dynamic(&thd->user_var_events); @@ -1369,7 +1543,7 @@ sp_head::execute_function(THD *thd, Item **argp, uint argcount, } } - if (m_type == TYPE_ENUM_FUNCTION && !err_status) + if (!err_status) { /* We need result only in function but not in trigger */ @@ -1380,8 +1554,9 @@ sp_head::execute_function(THD *thd, Item **argp, uint argcount, } } - - nctx->pop_all_cursors(); // To avoid memory leaks after an error +#ifndef NO_EMBEDDED_ACCESS_CHECKS + sp_restore_security_context(thd, save_security_ctx); +#endif err_with_cleanup: delete nctx; @@ -1404,8 +1579,10 @@ err_with_cleanup: The function does the following steps: - Set all parameters + - changes security context for SUID routines - call sp_head::execute - copy back values of INOUT and OUT parameters + - restores security context RETURN FALSE on success @@ -1539,7 +1716,13 @@ sp_head::execute_procedure(THD *thd, List<Item> *args) thd->options |= OPTION_LOG_OFF; } thd->spcont= nctx; - + +#ifndef NO_EMBEDDED_ACCESS_CHECKS + Security_context *save_security_ctx= 0; + if (!err_status) + err_status= set_routine_security_ctx(thd, this, TRUE, &save_security_ctx); +#endif + if (!err_status) err_status= execute(thd); @@ -1588,10 +1771,14 @@ sp_head::execute_procedure(THD *thd, List<Item> *args) } } +#ifndef NO_EMBEDDED_ACCESS_CHECKS + if (save_security_ctx) + sp_restore_security_context(thd, save_security_ctx); +#endif + if (!save_spcont) delete octx; - nctx->pop_all_cursors(); // To avoid memory leaks after an error delete nctx; thd->spcont= save_spcont; @@ -1738,14 +1925,18 @@ sp_head::fill_field_definition(THD *thd, LEX *lex, enum enum_field_types field_type, create_field *field_def) { + HA_CREATE_INFO sp_db_info; LEX_STRING cmt = { 0, 0 }; uint unused1= 0; int unused2= 0; + load_db_opt_by_name(thd, m_db.str, &sp_db_info); + if (field_def->init(thd, (char*) "", field_type, lex->length, lex->dec, lex->type, (Item*) 0, (Item*) 0, &cmt, 0, &lex->interval_list, - (lex->charset ? lex->charset : default_charset_info), + (lex->charset ? lex->charset : + sp_db_info.default_table_charset), lex->uint_geom_type)) return TRUE; diff --git a/sql/sp_head.h b/sql/sp_head.h index 4712647b6f4..3ad1e1b85f0 100644 --- a/sql/sp_head.h +++ b/sql/sp_head.h @@ -195,9 +195,13 @@ public: void init(LEX *lex); + /* Copy sp name from parser. */ + void + init_sp_name(THD *thd, sp_name *spname); + // Initialize strings after parsing header void - init_strings(THD *thd, LEX *lex, sp_name *name); + init_strings(THD *thd, LEX *lex); int create(THD *thd); @@ -209,6 +213,10 @@ public: destroy(); bool + execute_trigger(THD *thd, const char *db, const char *table, + GRANT_INFO *grant_onfo); + + bool execute_function(THD *thd, Item **args, uint argcount, Field *return_fld); bool @@ -1170,6 +1178,10 @@ sp_change_security_context(THD *thd, sp_head *sp, Security_context **backup); void sp_restore_security_context(THD *thd, Security_context *backup); + +bool +set_routine_security_ctx(THD *thd, sp_head *sp, bool is_proc, + Security_context **save_ctx); #endif /* NO_EMBEDDED_ACCESS_CHECKS */ TABLE_LIST * diff --git a/sql/sql_class.h b/sql/sql_class.h index 31b97cf5982..6b46c9676f7 100644 --- a/sql/sql_class.h +++ b/sql/sql_class.h @@ -2018,6 +2018,7 @@ class user_var_entry ulong length; query_id_t update_query_id, used_query_id; Item_result type; + bool unsigned_flag; double val_real(my_bool *null_value); longlong val_int(my_bool *null_value); diff --git a/sql/sql_db.cc b/sql/sql_db.cc index 77d99862bf0..b055957259c 100644 --- a/sql/sql_db.cc +++ b/sql/sql_db.cc @@ -408,7 +408,6 @@ static bool write_db_opt(THD *thd, const char *path, HA_CREATE_INFO *create) create Where to store the read options DESCRIPTION - For now, only default-character-set is read. RETURN VALUES 0 File found @@ -497,6 +496,50 @@ err1: /* + Retrieve database options by name. Load database options file or fetch from + cache. + + SYNOPSIS + load_db_opt_by_name() + db_name Database name + db_create_info Where to store the database options + + DESCRIPTION + load_db_opt_by_name() is a shortcut for load_db_opt(). + + NOTE + Although load_db_opt_by_name() (and load_db_opt()) returns status of + the operation, it is useless usually and should be ignored. The problem + is that there are 1) system databases ("mysql") and 2) virtual + databases ("information_schema"), which do not contain options file. + So, load_db_opt[_by_name]() returns FALSE for these databases, but this + is not an error. + + load_db_opt[_by_name]() clears db_create_info structure in any case, so + even on failure it contains valid data. So, common use case is just + call load_db_opt[_by_name]() without checking return value and use + db_create_info right after that. + + RETURN VALUES (read NOTE!) + FALSE Success + TRUE Failed to retrieve options +*/ + +bool load_db_opt_by_name(THD *thd, const char *db_name, + HA_CREATE_INFO *db_create_info) +{ + char db_opt_path[FN_REFLEN]; + + strxnmov(db_opt_path, sizeof (db_opt_path) - 1, mysql_data_home, "/", + db_name, "/", MY_DB_OPT_FILE, NullS); + + unpack_filename(db_opt_path, db_opt_path); + + return load_db_opt(thd, db_opt_path, db_create_info); +} + + +/* Create a database SYNOPSIS @@ -1254,8 +1297,6 @@ bool mysql_change_db(THD *thd, const char *name, bool no_access_check) { int path_length, db_length; char *db_name; - char path[FN_REFLEN]; - HA_CREATE_INFO create; bool system_db= 0; #ifndef NO_EMBEDDED_ACCESS_CHECKS ulong db_access; @@ -1324,15 +1365,14 @@ bool mysql_change_db(THD *thd, const char *name, bool no_access_check) } } #endif - path_length= build_table_filename(path, sizeof(path), db_name, "", ""); - if (path_length && path[path_length-1] == FN_LIBCHAR) - path[path_length-1]= '\0'; // remove ending '\' - if (my_access(path,F_OK)) + + if (check_db_dir_existence(db_name)) { my_error(ER_BAD_DB_ERROR, MYF(0), db_name); my_free(db_name, MYF(0)); DBUG_RETURN(1); } + end: x_free(thd->db); DBUG_ASSERT(db_name == NULL || db_name[0] != '\0'); @@ -1348,8 +1388,10 @@ end: } else { - strmov(path+unpack_dirname(path,path), MY_DB_OPT_FILE); - load_db_opt(thd, path, &create); + HA_CREATE_INFO create; + + load_db_opt_by_name(thd, db_name, &create); + thd->db_charset= create.default_table_charset ? create.default_table_charset : thd->variables.collation_server; @@ -1666,3 +1708,31 @@ exit: DBUG_RETURN(error); } + +/* + Check if there is directory for the database name. + + SYNOPSIS + check_db_dir_existence() + db_name database name + + RETURN VALUES + FALSE There is directory for the specified database name. + TRUE The directory does not exist. +*/ + +bool check_db_dir_existence(const char *db_name) +{ + char db_dir_path[FN_REFLEN]; + uint db_dir_path_len; + + db_dir_path_length= build_table_filename(path, sizeof(path), + db_name, "", "", 0); + + if (db_dir_path_len && db_dir_path[db_dir_path_len - 1] == FN_LIBCHAR) + db_dir_path[db_dir_path_len - 1]= 0; + + /* Check access. */ + + return my_access(db_dir_path, F_OK); +} diff --git a/sql/sql_delete.cc b/sql/sql_delete.cc index 659695e8e73..8ac69bd1cb2 100644 --- a/sql/sql_delete.cc +++ b/sql/sql_delete.cc @@ -100,6 +100,13 @@ bool mysql_delete(THD *thd, TABLE_LIST *table_list, COND *conds, } /* Handler didn't support fast delete; Delete rows one by one */ } + if (conds) + { + Item::cond_result result; + conds= remove_eq_conds(thd, conds, &result); + if (result == Item::COND_FALSE) // Impossible where + limit= 0; + } #ifdef WITH_PARTITION_STORAGE_ENGINE if (prune_partitions(thd, table, conds)) diff --git a/sql/sql_lex.cc b/sql/sql_lex.cc index fe36b578f3b..9ee67413e40 100644 --- a/sql/sql_lex.cc +++ b/sql/sql_lex.cc @@ -127,6 +127,7 @@ void lex_start(THD *thd, const uchar *buf, uint length) lex->param_list.empty(); lex->view_list.empty(); lex->prepared_stmt_params.empty(); + lex->auxiliary_table_list.empty(); lex->unit.next= lex->unit.master= lex->unit.link_next= lex->unit.return_to= 0; lex->unit.prev= lex->unit.link_prev= 0; @@ -1060,6 +1061,30 @@ int MYSQLlex(void *arg, void *yythd) } } + +/* + Skip comment in the end of statement. + + SYNOPSIS + skip_rear_comments() + begin pointer to the beginning of statement + end pointer to the end of statement + + DESCRIPTION + The function is intended to trim comments at the end of the statement. + + RETURN + Pointer to the last non-comment symbol of the statement. +*/ + +uchar *skip_rear_comments(uchar *begin, uchar *end) +{ + while (begin < end && (end[-1] <= ' ' || end[-1] == '*' || + end[-1] == '/' || end[-1] == ';')) + end-= 1; + return end; +} + /* st_select_lex structures initialisations */ diff --git a/sql/sql_lex.h b/sql/sql_lex.h index 192b6c75f24..498bba267ed 100644 --- a/sql/sql_lex.h +++ b/sql/sql_lex.h @@ -1190,5 +1190,6 @@ extern void lex_free(void); extern void lex_start(THD *thd, const uchar *buf, uint length); extern void lex_end(LEX *lex); extern int MYSQLlex(void *arg, void *yythd); +extern uchar *skip_rear_comments(uchar *begin, uchar *end); #endif /* MYSQL_SERVER */ diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc index 1af80f2c4b0..9217c147143 100644 --- a/sql/sql_parse.cc +++ b/sql/sql_parse.cc @@ -4587,9 +4587,6 @@ end_with_restore_list: } else { -#ifndef NO_EMBEDDED_ACCESS_CHECKS - Security_context *save_ctx; -#endif ha_rows select_limit; /* bits that should be cleared in thd->server_status */ uint bits_to_be_cleared= 0; @@ -4631,21 +4628,11 @@ end_with_restore_list: #ifndef NO_EMBEDDED_ACCESS_CHECKS if (check_routine_access(thd, EXECUTE_ACL, - sp->m_db.str, sp->m_name.str, TRUE, 0) || - sp_change_security_context(thd, sp, &save_ctx)) + sp->m_db.str, sp->m_name.str, TRUE, FALSE)) { thd->net.no_send_ok= nsok; goto error; } - if (save_ctx && - check_routine_access(thd, EXECUTE_ACL, - sp->m_db.str, sp->m_name.str, TRUE, 0)) - { - thd->net.no_send_ok= nsok; - sp_restore_security_context(thd, save_ctx); - goto error; - } - #endif select_limit= thd->variables.select_limit; thd->variables.select_limit= HA_POS_ERROR; @@ -4669,9 +4656,6 @@ end_with_restore_list: thd->total_warn_count= 0; thd->variables.select_limit= select_limit; -#ifndef NO_EMBEDDED_ACCESS_CHECKS - sp_restore_security_context(thd, save_ctx); -#endif thd->net.no_send_ok= nsok; thd->server_status&= ~bits_to_be_cleared; diff --git a/sql/sql_prepare.cc b/sql/sql_prepare.cc index ca31845ff95..16508516df7 100644 --- a/sql/sql_prepare.cc +++ b/sql/sql_prepare.cc @@ -2134,29 +2134,21 @@ void reinit_stmt_before_use(THD *thd, LEX *lex) they have their own table list). */ for (TABLE_LIST *tables= lex->query_tables; - tables; - tables= tables->next_global) + tables; + tables= tables->next_global) + { + tables->reinit_before_use(thd); + } + /* + Cleanup of the special case of DELETE t1, t2 FROM t1, t2, t3 ... + (multi-delete). We do a full clean up, although at the moment all we + need to clean in the tables of MULTI-DELETE list is 'table' member. + */ + for (TABLE_LIST *tables= (TABLE_LIST*) lex->auxiliary_table_list.first; + tables; + tables= tables->next_global) { - /* - Reset old pointers to TABLEs: they are not valid since the tables - were closed in the end of previous prepare or execute call. - */ tables->reinit_before_use(thd); - - /* Reset is_schema_table_processed value(needed for I_S tables */ - tables->is_schema_table_processed= FALSE; - - TABLE_LIST *embedded; /* The table at the current level of nesting. */ - TABLE_LIST *embedding= tables; /* The parent nested table reference. */ - do - { - embedded= embedding; - if (embedded->prep_on_expr) - embedded->on_expr= embedded->prep_on_expr->copy_andor_structure(thd); - embedding= embedded->embedding; - } - while (embedding && - embedding->nested_join->join_list.head() == embedded); } lex->current_select= &lex->select_lex; @@ -2171,7 +2163,7 @@ void reinit_stmt_before_use(THD *thd, LEX *lex) } lex->allow_sum_func= 0; lex->in_sum_func= NULL; - DBUG_VOID_RETURN; + DBUG_VOID_RETURN; } diff --git a/sql/sql_show.cc b/sql/sql_show.cc index bf09f516499..6a8124e485f 100644 --- a/sql/sql_show.cc +++ b/sql/sql_show.cc @@ -455,9 +455,35 @@ bool mysqld_show_column_types(THD *thd) } -int -mysql_find_files(THD *thd,List<char> *files, const char *db,const char *path, - const char *wild, bool dir) +/* + find_files() - find files in a given directory. + + SYNOPSIS + find_files() + thd thread handler + files put found files in this list + db database name to set in TABLE_LIST structure + path path to database + wild filter for found files + dir read databases in path if TRUE, read .frm files in + database otherwise + + RETURN + FIND_FILES_OK success + FIND_FILES_OOM out of memory error + FIND_FILES_DIR no such directory, or directory can't be read +*/ + +enum find_files_result { + FIND_FILES_OK, + FIND_FILES_OOM, + FIND_FILES_DIR +}; + +static +find_files_result +find_files(THD *thd, List<char> *files, const char *db, + const char *path, const char *wild, bool dir) { uint i; char *ext; @@ -468,7 +494,7 @@ mysql_find_files(THD *thd,List<char> *files, const char *db,const char *path, #endif TABLE_LIST table_list; char tbbuff[FN_REFLEN]; - DBUG_ENTER("mysql_find_files"); + DBUG_ENTER("find_files"); if (wild && !wild[0]) wild=0; @@ -481,7 +507,7 @@ mysql_find_files(THD *thd,List<char> *files, const char *db,const char *path, my_error(ER_BAD_DB_ERROR, MYF(ME_BELL+ME_WAITTANG), db); else my_error(ER_CANT_READ_DIR, MYF(ME_BELL+ME_WAITTANG), path, my_errno); - DBUG_RETURN(-1); + DBUG_RETURN(FIND_FILES_DIR); } VOID(tablename_to_filename(tmp_file_prefix, tbbuff, sizeof(tbbuff))); @@ -555,7 +581,7 @@ mysql_find_files(THD *thd,List<char> *files, const char *db,const char *path, if (files->push_back(thd->strdup(file->name))) { my_dirend(dirp); - DBUG_RETURN(-1); + DBUG_RETURN(FIND_FILES_OOM); } } DBUG_PRINT("info",("found: %d files", files->elements)); @@ -563,7 +589,7 @@ mysql_find_files(THD *thd,List<char> *files, const char *db,const char *path, VOID(ha_find_files(thd,db,path,wild,dir,files)); - DBUG_RETURN(0); + DBUG_RETURN(FIND_FILES_OK); } @@ -657,13 +683,11 @@ bool mysqld_show_create_db(THD *thd, char *dbname, { Security_context *sctx= thd->security_ctx; int length; - char path[FN_REFLEN]; char buff[2048]; String buffer(buff, sizeof(buff), system_charset_info); #ifndef NO_EMBEDDED_ACCESS_CHECKS uint db_access; #endif - bool found_libchar; HA_CREATE_INFO create; uint create_options = create_info ? create_info->options : 0; Protocol *protocol=thd->protocol; @@ -692,7 +716,8 @@ bool mysqld_show_create_db(THD *thd, char *dbname, } else { - length= build_table_filename(path, sizeof(path), dbname, "", ""); + (void) sprintf(path,"%s/%s",mysql_data_home, dbname); + length=unpack_dirname(path,path); // Convert if not unix found_libchar= 0; if (length && path[length-1] == FN_LIBCHAR) { @@ -700,14 +725,20 @@ bool mysqld_show_create_db(THD *thd, char *dbname, path[length-1]=0; // remove ending '\' } if (access(path,F_OK)) + length= build_table_filename(path, sizeof(path), dbname, "", ""); + found_libchar= 0; + if (length && path[length-1] == FN_LIBCHAR) + { + found_libchar= 1; + path[length-1]=0; // remove ending '\' + } + if (check_db_dir_existence(dbname)) { my_error(ER_BAD_DB_ERROR, MYF(0), dbname); DBUG_RETURN(TRUE); } - if (found_libchar) - path[length-1]= FN_LIBCHAR; - strmov(path+length, MY_DB_OPT_FILE); - load_db_opt(thd, path, &create); + + load_db_opt_by_name(thd, dbname, &create); } List<Item> field_list; field_list.push_back(new Item_empty_string("Database",NAME_LEN)); @@ -2356,8 +2387,8 @@ enum enum_schema_tables get_schema_table_idx(ST_SCHEMA_TABLE *schema_table) wild string otherwise it's db name; RETURN - 1 error - 0 success + zero success + non-zero error */ int make_db_list(THD *thd, List<char> *files, @@ -2383,8 +2414,8 @@ int make_db_list(THD *thd, List<char> *files, if (files->push_back(thd->strdup(information_schema_name.str))) return 1; } - return mysql_find_files(thd, files, NullS, mysql_data_home, - idx_field_vals->db_value, 1); + return (find_files(thd, files, NullS, mysql_data_home, + idx_field_vals->db_value, 1) != FIND_FILES_OK); } /* @@ -2410,7 +2441,8 @@ int make_db_list(THD *thd, List<char> *files, if (files->push_back(thd->strdup(information_schema_name.str))) return 1; *with_i_schema= 1; - return mysql_find_files(thd, files, NullS, mysql_data_home, NullS, 1); + return (find_files(thd, files, NullS, + mysql_data_home, NullS, 1) != FIND_FILES_OK); } @@ -2561,9 +2593,28 @@ int get_all_tables(THD *thd, TABLE_LIST *tables, COND *cond) len= build_table_filename(path, sizeof(path), base_name, "", ""); end= path + len; len= FN_LEN - len; - if (mysql_find_files(thd, &files, base_name, - path, idx_field_vals.table_value, 0)) - goto err; + find_files_result res= find_files(thd, &files, base_name, + path, idx_field_vals.table_value, 0); + if (res != FIND_FILES_OK) + { + /* + Downgrade errors about problems with database directory to + warnings if this is not a 'SHOW' command. Another thread + may have dropped database, and we may still have a name + for that directory. + */ + if (res == FIND_FILES_DIR && lex->orig_sql_command == SQLCOM_END) + { + push_warning(thd, MYSQL_ERROR::WARN_LEVEL_WARN, + thd->net.last_errno, thd->net.last_error); + thd->clear_error(); + continue; + } + else + { + goto err; + } + } if (lower_case_table_names) orig_base_name= thd->strdup(base_name); } @@ -2679,8 +2730,11 @@ bool store_schema_shemata(THD* thd, TABLE *table, const char *db_name, int fill_schema_shemata(THD *thd, TABLE_LIST *tables, COND *cond) { - char path[FN_REFLEN]; - bool found_libchar; + /* + TODO: fill_schema_shemata() is called when new client is connected. + Returning error status in this case leads to client hangup. + */ + INDEX_FIELD_VALUES idx_field_vals; List<char> files; char *file_name; @@ -2712,19 +2766,9 @@ int fill_schema_shemata(THD *thd, TABLE_LIST *tables, COND *cond) (grant_option && !check_grant_db(thd, file_name))) #endif { - length= build_table_filename(path, sizeof(path), file_name, "", ""); - found_libchar= 0; - if (length && path[length-1] == FN_LIBCHAR) - { - found_libchar= 1; - path[length-1]=0; // remove ending '\' - } + load_db_opt_by_name(thd, file_name, &create); - if (found_libchar) - path[length-1]= FN_LIBCHAR; - strmov(path+length, MY_DB_OPT_FILE); - load_db_opt(thd, path, &create); - if (store_schema_shemata(thd, table, file_name, + if (store_schema_shemata(thd, table, file_name, create.default_table_charset)) DBUG_RETURN(1); } @@ -5114,7 +5158,12 @@ bool get_schema_tables_result(JOIN *join) if (table_list->schema_table->fill_table(thd, table_list, tab->select_cond)) + { result= 1; + join->error= 1; + table_list->is_schema_table_processed= TRUE; + break; + } table_list->is_schema_table_processed= TRUE; } } diff --git a/sql/sql_table.cc b/sql/sql_table.cc index 5325758fd12..43c80e907e1 100644 --- a/sql/sql_table.cc +++ b/sql/sql_table.cc @@ -2896,13 +2896,17 @@ static int mysql_prepare_table(THD *thd, HA_CREATE_INFO *create_info, static void set_table_default_charset(THD *thd, HA_CREATE_INFO *create_info, char *db) { + /* + If the table character set was not given explicitly, + let's fetch the database default character set and + apply it to the table. + */ if (!create_info->default_table_charset) { HA_CREATE_INFO db_info; - char path[FN_REFLEN]; - /* Abuse build_table_filename() to build the path to the db.opt file */ - build_table_filename(path, sizeof(path), db, "", MY_DB_OPT_FILE); - load_db_opt(thd, path, &db_info); + + load_db_opt_by_name(thd, db, &db_info); + create_info->default_table_charset= db_info.default_table_charset; } } diff --git a/sql/sql_trigger.cc b/sql/sql_trigger.cc index 1837372c6c4..6af88541c86 100644 --- a/sql/sql_trigger.cc +++ b/sql/sql_trigger.cc @@ -301,7 +301,10 @@ end: append_definer(thd, &log_query, &definer_user, &definer_host); } - log_query.append(thd->lex->stmt_definition_begin); + log_query.append(thd->lex->stmt_definition_begin, + (char *)thd->lex->sphead->m_body_begin - + thd->lex->stmt_definition_begin + + thd->lex->sphead->m_body.length); } /* Such a statement can always go directly to binlog, no trans cache. */ @@ -1497,45 +1500,11 @@ bool Table_triggers_list::process_triggers(THD *thd, trg_event_type event, old_field= table->field; } -#ifndef NO_EMBEDDED_ACCESS_CHECKS - Security_context *save_ctx; - - if (sp_change_security_context(thd, sp_trigger, &save_ctx)) - return TRUE; - - /* - Fetch information about table-level privileges to GRANT_INFO structure for - subject table. Check of privileges that will use it and information about - column-level privileges will happen in Item_trigger_field::fix_fields(). - */ - - fill_effective_table_privileges(thd, - &subject_table_grants[event][time_type], - table->s->db.str, table->s->table_name.str); - - /* Check that the definer has TRIGGER privilege on the subject table. */ - - if (!(subject_table_grants[event][time_type].privilege & TRIGGER_ACL)) - { - char priv_desc[128]; - get_privilege_desc(priv_desc, sizeof(priv_desc), TRIGGER_ACL); - - my_error(ER_TABLEACCESS_DENIED_ERROR, MYF(0), priv_desc, - thd->security_ctx->priv_user, thd->security_ctx->host_or_ip, - table->s->table_name.str); - - sp_restore_security_context(thd, save_ctx); - return TRUE; - } -#endif // NO_EMBEDDED_ACCESS_CHECKS - thd->reset_sub_statement_state(&statement_state, SUB_STMT_TRIGGER); - err_status= sp_trigger->execute_function(thd, 0, 0, 0); + err_status= sp_trigger->execute_trigger + (thd, table->s->db, table->s->table_name, + &subject_table_grants[event][time_type]); thd->restore_sub_statement_state(&statement_state); - -#ifndef NO_EMBEDDED_ACCESS_CHECKS - sp_restore_security_context(thd, save_ctx); -#endif // NO_EMBEDDED_ACCESS_CHECKS } return err_status; diff --git a/sql/sql_udf.cc b/sql/sql_udf.cc index 13302c2c3f7..f0d31965573 100644 --- a/sql/sql_udf.cc +++ b/sql/sql_udf.cc @@ -210,7 +210,7 @@ void udf_init() } } if (error > 0) - sql_print_error(ER(ER_GET_ERRNO), my_errno); + sql_print_error("Got unknown error: %d", my_errno); end_read_record(&read_record_info); new_thd->version--; // Force close to free memory diff --git a/sql/sql_view.cc b/sql/sql_view.cc index 201725301d6..1a83547816b 100644 --- a/sql/sql_view.cc +++ b/sql/sql_view.cc @@ -186,8 +186,10 @@ fill_defined_view_parts (THD *thd, TABLE_LIST *view) if (!open_table(thd, &decoy, thd->mem_root, ¬_used, OPEN_VIEW_NO_PARSE) && !decoy.view) { + /* It's a table */ return TRUE; } + if (!lex->definer) { view->definer.host= decoy.definer.host; @@ -729,8 +731,10 @@ static int mysql_register_view(THD *thd, TABLE_LIST *view, view->query.str= (char*)str.ptr(); view->query.length= str.length()-1; // we do not need last \0 view->source.str= thd->query + thd->lex->create_view_select_start; - view->source.length= (thd->query_length - - thd->lex->create_view_select_start); + view->source.length= (char *)skip_rear_comments((uchar *)view->source.str, + (uchar *)thd->query + + thd->query_length) - + view->source.str; view->file_version= 1; view->calc_md5(md5); view->md5.str= md5; diff --git a/sql/sql_yacc.yy b/sql/sql_yacc.yy index 4fd4572e58b..14530e3ed12 100644 --- a/sql/sql_yacc.yy +++ b/sql/sql_yacc.yy @@ -1613,6 +1613,17 @@ create_function_tail: RETURNS_SYM udf_type SONAME_SYM TEXT_STRING_sys { LEX *lex=Lex; + if (lex->definer != NULL) + { + /* + DEFINER is a concept meaningful when interpreting SQL code. + UDF functions are compiled. + Using DEFINER with UDF has therefore no semantic, + and is considered a parsing error. + */ + my_error(ER_WRONG_USAGE, MYF(0), "SONAME", "DEFINER"); + YYABORT; + } lex->sql_command = SQLCOM_CREATE_FUNCTION; lex->udf.name = lex->spname->m_name; lex->udf.returns=(Item_result) $2; @@ -1642,6 +1653,7 @@ create_function_tail: sp= new sp_head(); sp->reset_thd_mem_root(YYTHD); sp->init(lex); + sp->init_sp_name(YYTHD, lex->spname); sp->m_type= TYPE_ENUM_FUNCTION; lex->sphead= sp; @@ -1707,7 +1719,7 @@ create_function_tail: YYABORT; lex->sql_command= SQLCOM_CREATE_SPFUNCTION; - sp->init_strings(YYTHD, lex, lex->spname); + sp->init_strings(YYTHD, lex); if (!(sp->m_flags & sp_head::HAS_RETURN)) { my_error(ER_SP_NORETURN, MYF(0), sp->m_qname.str); @@ -2302,9 +2314,12 @@ sp_proc_stmt_statement: sp_instr_stmt *i=new sp_instr_stmt(sp->instructions(), lex->spcont, lex); - /* Extract the query statement from the tokenizer: - The end is either lex->tok_end or tok->ptr. */ - if (lex->ptr - lex->tok_end > 1) + /* + Extract the query statement from the tokenizer. The + end is either lex->ptr, if there was no lookahead, + lex->tok_end otherwise. + */ + if (yychar == YYEMPTY) i->m_query.length= lex->ptr - sp->m_tmp_query; else i->m_query.length= lex->tok_end - sp->m_tmp_query; @@ -4457,7 +4472,7 @@ opt_bin_mod: | BINARY { Lex->type|= BINCMP_FLAG; }; opt_bin_charset: - /* empty */ { } + /* empty */ { Lex->charset= NULL; } | ASCII_SYM { Lex->charset=&my_charset_latin1; } | UNICODE_SYM { @@ -9701,7 +9716,12 @@ option_type_value: lex))) YYABORT; - if (lex->ptr - lex->tok_end > 1) + /* + Extract the query statement from the tokenizer. The + end is either lex->ptr, if there was no lookahead, + lex->tok_end otherwise. + */ + if (yychar == YYEMPTY) qbuff.length= lex->ptr - sp->m_tmp_query; else qbuff.length= lex->tok_end - sp->m_tmp_query; @@ -10972,7 +10992,7 @@ trigger_tail: YYABORT; sp->reset_thd_mem_root(YYTHD); sp->init(lex); - + sp->init_sp_name(YYTHD, $3); lex->stmt_definition_begin= $2; lex->ident.str= $7; lex->ident.length= $10 - $7; @@ -11000,7 +11020,7 @@ trigger_tail: sp_head *sp= lex->sphead; lex->sql_command= SQLCOM_CREATE_TRIGGER; - sp->init_strings(YYTHD, lex, $3); + sp->init_strings(YYTHD, lex); /* Restore flag if it was cleared above */ YYTHD->client_capabilities |= $<ulong_num>13; @@ -11048,13 +11068,14 @@ sp_tail: my_error(ER_SP_NO_RECURSIVE_CREATE, MYF(0), "PROCEDURE"); YYABORT; } - + lex->stmt_definition_begin= $2; - + /* Order is important here: new - reset - init */ sp= new sp_head(); sp->reset_thd_mem_root(YYTHD); sp->init(lex); + sp->init_sp_name(YYTHD, $3); sp->m_type= TYPE_ENUM_PROCEDURE; lex->sphead= sp; @@ -11092,7 +11113,7 @@ sp_tail: LEX *lex= Lex; sp_head *sp= lex->sphead; - sp->init_strings(YYTHD, lex, $3); + sp->init_strings(YYTHD, lex); lex->sql_command= SQLCOM_CREATE_PROCEDURE; /* Restore flag if it was cleared above diff --git a/sql/table.cc b/sql/table.cc index 21dbcccedd7..b5ec2b35e76 100644 --- a/sql/table.cc +++ b/sql/table.cc @@ -4041,13 +4041,27 @@ void st_table::mark_columns_needed_for_insert() st_table_list::reinit_before_use() */ -void st_table_list::reinit_before_use(THD * /* thd */) +void st_table_list::reinit_before_use(THD *thd) { /* Reset old pointers to TABLEs: they are not valid since the tables were closed in the end of previous prepare or execute call. */ table= 0; + /* Reset is_schema_table_processed value(needed for I_S tables */ + is_schema_table_processed= FALSE; + + TABLE_LIST *embedded; /* The table at the current level of nesting. */ + TABLE_LIST *embedding= this; /* The parent nested table reference. */ + do + { + embedded= embedding; + if (embedded->prep_on_expr) + embedded->on_expr= embedded->prep_on_expr->copy_andor_structure(thd); + embedding= embedded->embedding; + } + while (embedding && + embedding->nested_join->join_list.head() == embedded); } diff --git a/sql/table.h b/sql/table.h index 0d8ec4f98e1..7675c27823b 100644 --- a/sql/table.h +++ b/sql/table.h @@ -795,6 +795,10 @@ typedef struct st_table_list private: bool prep_check_option(THD *thd, uint8 check_opt_type); bool prep_where(THD *thd, Item **conds, bool no_where_clause); + /* + Cleanup for re-execution in a prepared statement or a stored + procedure. + */ } TABLE_LIST; class Item; diff --git a/storage/ndb/src/kernel/error/ndbd_exit_codes.c b/storage/ndb/src/kernel/error/ndbd_exit_codes.c index 2c32c31a15f..b2aa6456369 100644 --- a/storage/ndb/src/kernel/error/ndbd_exit_codes.c +++ b/storage/ndb/src/kernel/error/ndbd_exit_codes.c @@ -252,7 +252,7 @@ int ndbd_exit_string(int err_no, char *str, unsigned int size) ndbd_exit_classification cl; ndbd_exit_status st; const char *msg = ndbd_exit_message(err_no, &cl); - if (msg[0] != '\0') + if (msg[0] != '\0' && cl != XUE) { const char *cl_msg = ndbd_exit_classification_message(cl, &st); const char *st_msg = ndbd_exit_status_message(st); diff --git a/tests/mysql_client_test.c b/tests/mysql_client_test.c index 924f9169f5a..4b7d61192c1 100644 --- a/tests/mysql_client_test.c +++ b/tests/mysql_client_test.c @@ -50,7 +50,6 @@ static unsigned int opt_port; static my_bool tty_password= 0, opt_silent= 0; static MYSQL *mysql= 0; -static char query[MAX_TEST_QUERY_LENGTH]; static char current_db[]= "client_test_db"; static unsigned int test_count= 0; static unsigned int opt_count= 0; @@ -270,6 +269,7 @@ mysql_simple_prepare(MYSQL *mysql, const char *query) static void client_connect(ulong flag) { int rc; + static char query[MAX_TEST_QUERY_LENGTH]; myheader_r("client_connect"); if (!opt_silent) @@ -327,6 +327,8 @@ static void client_connect(ulong flag) static void client_disconnect() { + static char query[MAX_TEST_QUERY_LENGTH]; + myheader_r("client_disconnect"); if (mysql) @@ -658,6 +660,7 @@ int my_stmt_result(const char *buff) 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; @@ -1363,6 +1366,7 @@ static void test_prepare_insert_update() for (cur_query= testcase; *cur_query; cur_query++) { + char query[MAX_TEST_QUERY_LENGTH]; printf("\nRunning query: %s", *cur_query); strmov(query, *cur_query); stmt= mysql_simple_prepare(mysql, query); @@ -1397,6 +1401,7 @@ static void test_prepare_simple() { MYSQL_STMT *stmt; int rc; + char query[MAX_TEST_QUERY_LENGTH]; myheader("test_prepare_simple"); @@ -1467,6 +1472,7 @@ static void test_prepare_field_result() MYSQL_STMT *stmt; MYSQL_RES *result; int rc; + char query[MAX_TEST_QUERY_LENGTH]; myheader("test_prepare_field_result"); @@ -1518,6 +1524,7 @@ static void test_prepare_syntax() { MYSQL_STMT *stmt; int rc; + char query[MAX_TEST_QUERY_LENGTH]; myheader("test_prepare_syntax"); @@ -1559,6 +1566,7 @@ static void test_prepare() my_bool is_null[7]; char llbuf[22]; MYSQL_BIND bind[7]; + char query[MAX_TEST_QUERY_LENGTH]; myheader("test_prepare"); @@ -1732,6 +1740,7 @@ static void test_double_compare() MYSQL_RES *result; MYSQL_BIND bind[3]; ulong length[3]; + char query[MAX_TEST_QUERY_LENGTH]; myheader("test_double_compare"); @@ -1814,6 +1823,7 @@ static void test_null() uint nData; MYSQL_BIND bind[2]; my_bool is_null[2]; + char query[MAX_TEST_QUERY_LENGTH]; myheader("test_null"); @@ -1960,6 +1970,7 @@ static void test_ps_null_param() /* Execute several queries, all returning NULL in result. */ for(cur_query= queries; *cur_query; cur_query++) { + char query[MAX_TEST_QUERY_LENGTH]; strmov(query, *cur_query); stmt= mysql_simple_prepare(mysql, query); check_stmt(stmt); @@ -1991,6 +2002,7 @@ static void test_fetch_null() MYSQL_BIND bind[11]; ulong length[11]; my_bool is_null[11]; + char query[MAX_TEST_QUERY_LENGTH]; myheader("test_fetch_null"); @@ -2219,6 +2231,7 @@ static void test_select() int nData= 1; MYSQL_BIND bind[2]; ulong length[2]; + char query[MAX_TEST_QUERY_LENGTH]; myheader("test_select"); @@ -2290,6 +2303,7 @@ static void test_ps_conj_select() int32 int_data; char str_data[32]; unsigned long str_length; + char query[MAX_TEST_QUERY_LENGTH]; myheader("test_ps_conj_select"); rc= mysql_query(mysql, "drop table if exists t1"); @@ -2347,6 +2361,7 @@ static void test_bug1115() MYSQL_BIND bind[1]; ulong length[1]; char szData[11]; + char query[MAX_TEST_QUERY_LENGTH]; myheader("test_bug1115"); @@ -2458,6 +2473,7 @@ static void test_bug1180() MYSQL_BIND bind[1]; ulong length[1]; char szData[11]; + char query[MAX_TEST_QUERY_LENGTH]; myheader("test_select_bug"); @@ -2548,6 +2564,7 @@ static void test_bug1644() int num; my_bool isnull; int rc, i; + char query[MAX_TEST_QUERY_LENGTH]; myheader("test_bug1644"); @@ -2647,6 +2664,7 @@ static void test_select_show() { MYSQL_STMT *stmt; int rc; + char query[MAX_TEST_QUERY_LENGTH]; myheader("test_select_show"); @@ -2715,6 +2733,7 @@ static void test_simple_update() MYSQL_RES *result; MYSQL_BIND bind[2]; ulong length[2]; + char query[MAX_TEST_QUERY_LENGTH]; myheader("test_simple_update"); @@ -2792,6 +2811,7 @@ static void test_long_data() char *data= NullS; MYSQL_RES *result; MYSQL_BIND bind[3]; + char query[MAX_TEST_QUERY_LENGTH]; myheader("test_long_data"); @@ -2878,6 +2898,7 @@ static void test_long_data_str() MYSQL_RES *result; MYSQL_BIND bind[2]; my_bool is_null[2]; + char query[MAX_TEST_QUERY_LENGTH]; myheader("test_long_data_str"); @@ -2970,6 +2991,7 @@ static void test_long_data_str1() MYSQL_RES *result; MYSQL_BIND bind[2]; MYSQL_FIELD *field; + char query[MAX_TEST_QUERY_LENGTH]; myheader("test_long_data_str1"); @@ -3125,6 +3147,7 @@ static void test_long_data_bin() long length; MYSQL_RES *result; MYSQL_BIND bind[2]; + char query[MAX_TEST_QUERY_LENGTH]; myheader("test_long_data_bin"); @@ -3204,6 +3227,7 @@ static void test_simple_delete() MYSQL_RES *result; MYSQL_BIND bind[2]; ulong length[2]; + char query[MAX_TEST_QUERY_LENGTH]; myheader("test_simple_delete"); @@ -3286,6 +3310,7 @@ static void test_update() MYSQL_RES *result; MYSQL_BIND bind[2]; ulong length[2]; + char query[MAX_TEST_QUERY_LENGTH]; myheader("test_update"); @@ -3382,6 +3407,7 @@ static void test_prepare_noparam() MYSQL_STMT *stmt; int rc; MYSQL_RES *result; + char query[MAX_TEST_QUERY_LENGTH]; myheader("test_prepare_noparam"); @@ -4238,6 +4264,7 @@ static void test_prepare_ext() short sData= 10; longlong bData= 20; MYSQL_BIND bind[6]; + char query[MAX_TEST_QUERY_LENGTH]; myheader("test_prepare_ext"); rc= mysql_query(mysql, "DROP TABLE IF EXISTS test_prepare_ext"); @@ -4625,6 +4652,7 @@ static void test_stmt_close() MYSQL_RES *result; unsigned int count; int rc; + char query[MAX_TEST_QUERY_LENGTH]; myheader("test_stmt_close"); @@ -5271,6 +5299,7 @@ static void test_manual_sample() ulonglong affected_rows; MYSQL_BIND bind[3]; my_bool is_null; + char query[MAX_TEST_QUERY_LENGTH]; myheader("test_manual_sample"); @@ -5625,6 +5654,7 @@ static void test_prepare_multi_statements() { MYSQL *mysql_local; MYSQL_STMT *stmt; + char query[MAX_TEST_QUERY_LENGTH]; myheader("test_prepare_multi_statements"); if (!(mysql_local= mysql_init(NULL))) @@ -5842,6 +5872,7 @@ static void test_store_result2() int nData; ulong length; MYSQL_BIND bind[1]; + char query[MAX_TEST_QUERY_LENGTH]; myheader("test_store_result2"); @@ -7121,6 +7152,7 @@ static void test_set_option() static void test_prepare_grant() { int rc; + char query[MAX_TEST_QUERY_LENGTH]; myheader("test_prepare_grant"); @@ -8593,6 +8625,7 @@ static void test_sqlmode() MYSQL_BIND bind[2]; char c1[5], c2[5]; int rc; + char query[MAX_TEST_QUERY_LENGTH]; myheader("test_sqlmode"); @@ -8736,6 +8769,7 @@ static void test_ts() ulong length; int rc, field_count; char name; + char query[MAX_TEST_QUERY_LENGTH]; myheader("test_ts"); @@ -15228,6 +15262,65 @@ static void test_bug20152() } } +/* Bug#15752 "Lost connection to MySQL server when calling a SP from C API" */ + +static void test_bug15752() +{ + MYSQL mysql_local; + int rc, i; + const int ITERATION_COUNT= 100; + char *query= "CALL p1()"; + + myheader("test_bug15752"); + + rc= mysql_query(mysql, "drop procedure if exists p1"); + myquery(rc); + rc= mysql_query(mysql, "create procedure p1() select 1"); + myquery(rc); + + mysql_init(&mysql_local); + if (! mysql_real_connect(&mysql_local, opt_host, opt_user, + opt_password, current_db, opt_port, + opt_unix_socket, + CLIENT_MULTI_STATEMENTS|CLIENT_MULTI_RESULTS)) + { + printf("Unable connect to MySQL server: %s\n", mysql_error(&mysql_local)); + DIE_UNLESS(0); + } + rc= mysql_real_query(&mysql_local, query, strlen(query)); + myquery(rc); + mysql_free_result(mysql_store_result(&mysql_local)); + + rc= mysql_real_query(&mysql_local, query, strlen(query)); + DIE_UNLESS(rc && mysql_errno(&mysql_local) == CR_COMMANDS_OUT_OF_SYNC); + + if (! opt_silent) + printf("Got error (as expected): %s\n", mysql_error(&mysql_local)); + + /* Check some other commands too */ + + DIE_UNLESS(mysql_next_result(&mysql_local) == 0); + mysql_free_result(mysql_store_result(&mysql_local)); + DIE_UNLESS(mysql_next_result(&mysql_local) == -1); + + /* The second problem is not reproducible: add the test case */ + for (i = 0; i < ITERATION_COUNT; i++) + { + if (mysql_real_query(&mysql_local, query, strlen(query))) + { + printf("\ni=%d %s failed: %s\n", i, query, mysql_error(&mysql_local)); + break; + } + mysql_free_result(mysql_store_result(&mysql_local)); + DIE_UNLESS(mysql_next_result(&mysql_local) == 0); + mysql_free_result(mysql_store_result(&mysql_local)); + DIE_UNLESS(mysql_next_result(&mysql_local) == -1); + + } + mysql_close(&mysql_local); + rc= mysql_query(mysql, "drop procedure p1"); + myquery(rc); +} /* Bug#21206: memory corruption when too many cursors are opened at once @@ -15544,6 +15637,7 @@ static struct my_tests_st my_tests[]= { { "test_bug20152", test_bug20152 }, { "test_bug14169", test_bug14169 }, { "test_bug17667", test_bug17667 }, + { "test_bug15752", test_bug15752 }, { "test_mysql_insert_id", test_mysql_insert_id }, { "test_bug19671", test_bug19671}, { "test_bug21206", test_bug21206}, |