diff options
author | unknown <jani@ua141d10.elisa.omakaista.fi> | 2007-04-12 12:50:02 +0300 |
---|---|---|
committer | unknown <jani@ua141d10.elisa.omakaista.fi> | 2007-04-12 12:50:02 +0300 |
commit | 239b385933864bff3694f95ccc9d0c645f6a0aad (patch) | |
tree | 30b412b9ebad3ddaa08bcf7eb478c89eeebc2ed2 | |
parent | c4879fe6dde9890496a6555e78fa9bde5e21f8f4 (diff) | |
parent | d2667d1a6ebe7feeb8b80fcc5cfefac80ed729b0 (diff) | |
download | mariadb-git-239b385933864bff3694f95ccc9d0c645f6a0aad.tar.gz |
Merge jamppa@bk-internal.mysql.com:/home/bk/mysql-5.0
into ua141d10.elisa.omakaista.fi:/home/my/bk/mysql-5.0-marvel
client/mysqldump.c:
Auto merged
mysql-test/t/sp.test:
Auto merged
mysys/my_malloc.c:
Auto merged
mysys/my_static.c:
Auto merged
mysys/safemalloc.c:
Auto merged
ndb/src/mgmclient/CommandInterpreter.cpp:
Auto merged
sql/ha_archive.cc:
Auto merged
sql/ha_innodb.cc:
Auto merged
sql/ha_ndbcluster.cc:
Auto merged
sql/handler.cc:
Auto merged
sql/item_cmpfunc.cc:
Auto merged
sql/item_func.h:
Auto merged
sql/log.cc:
Auto merged
sql/log_event.cc:
Auto merged
sql/mysql_priv.h:
Auto merged
sql-common/client.c:
Auto merged
sql/sp.cc:
Auto merged
sql/sp_head.cc:
Auto merged
sql/sql_delete.cc:
Auto merged
sql/sql_insert.cc:
Auto merged
sql/sql_show.cc:
Auto merged
sql/sql_table.cc:
Auto merged
sql/sql_update.cc:
Auto merged
sql/table.cc:
Auto merged
sql-common/my_time.c:
Auto merged
mysql-test/r/sp.result:
Merged from main 5.0
sql/sql_load.cc:
Merged from main 5.0
153 files changed, 4340 insertions, 1372 deletions
diff --git a/client/mysqldump.c b/client/mysqldump.c index 0d7c0c3a0bf..63db2cc268e 100644 --- a/client/mysqldump.c +++ b/client/mysqldump.c @@ -76,13 +76,13 @@ #define IGNORE_DATA 0x01 /* don't dump data for this table */ #define IGNORE_INSERT_DELAYED 0x02 /* table doesn't support INSERT DELAYED */ -static char *add_load_option(char *ptr, const char *object, - const char *statement); +static void add_load_option(DYNAMIC_STRING *str, const char *option, + const char *option_value); static ulong find_set(TYPELIB *lib, const char *x, uint length, char **err_pos, uint *err_len); static char *alloc_query_str(ulong size); -static char *field_escape(char *to,const char *from,uint length); +static void field_escape(DYNAMIC_STRING* in, const char *from); 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,flush_privileges=0, @@ -124,6 +124,19 @@ FILE *stderror_file=0; static char *shared_memory_base_name=0; #endif static uint opt_protocol= 0; + +/* +Dynamic_string wrapper functions. In this file use these +wrappers, they will terminate the process if there is +an allocation failure. +*/ +static void init_dynamic_string_checked(DYNAMIC_STRING *str, const char *init_str, + uint init_alloc, uint alloc_increment); +static void dynstr_append_checked(DYNAMIC_STRING* dest, const char* src); +static void dynstr_set_checked(DYNAMIC_STRING *str, const char *init_str); +static void dynstr_append_mem_checked(DYNAMIC_STRING *str, const char *append, + uint length); +static void dynstr_realloc_checked(DYNAMIC_STRING *str, ulong additional_size); /* Constant for detection of default value of default_charset. If default_charset is equal to mysql_universal_client_charset, then @@ -425,7 +438,9 @@ static struct my_option my_long_options[] = static const char *load_default_groups[]= { "mysqldump","client",0 }; -static void safe_exit(int error); +static void maybe_exit(int error); +static void die(int error, const char* reason, ...); +static void maybe_die(int error, const char* reason, ...); static void write_header(FILE *sql_file, char *db_name); static void print_value(FILE *file, MYSQL_RES *result, MYSQL_ROW row, const char *prefix,const char *name, @@ -480,11 +495,7 @@ static void verbose_msg(const char *fmt, ...) void check_io(FILE *file) { if (ferror(file)) - { - fprintf(stderr, "%s: Got errno %d on write\n", my_progname, errno); - ignore_errors= 0; /* We can't ignore this error */ - safe_exit(EX_EOF); - } + die(EX_EOF, "Got errno %d on write", errno); } static void print_version(void) @@ -870,12 +881,74 @@ static int get_options(int *argc, char ***argv) static void DB_error(MYSQL *mysql_arg, const char *when) { DBUG_ENTER("DB_error"); - fprintf(stderr, "%s: Got error: %d: %s %s\n", my_progname, + maybe_die(EX_MYSQLERR, "Got error: %d: %s %s", mysql_errno(mysql_arg), mysql_error(mysql_arg), when); - fflush(stderr); - safe_exit(EX_MYSQLERR); DBUG_VOID_RETURN; -} /* DB_error */ +} + + + +/* + Prints out an error message and kills the process. + + SYNOPSIS + die() + error_num - process return value + fmt_reason - a format string for use by my_vsnprintf. + ... - variable arguments for above fmt_reason string + + DESCRIPTION + This call prints out the formatted error message to stderr and then + terminates the process. +*/ +static void die(int error_num, const char* fmt_reason, ...) +{ + char buffer[1000]; + va_list args; + va_start(args,fmt_reason); + my_vsnprintf(buffer, sizeof(buffer), fmt_reason, args); + va_end(args); + + fprintf(stderr, "%s: %s\n", my_progname, buffer); + fflush(stderr); + + ignore_errors= 0; /* force the exit */ + maybe_exit(error_num); +} + + +/* + Prints out an error message and maybe kills the process. + + SYNOPSIS + maybe_die() + error_num - process return value + fmt_reason - a format string for use by my_vsnprintf. + ... - variable arguments for above fmt_reason string + + DESCRIPTION + This call prints out the formatted error message to stderr and then + terminates the process, unless the --force command line option is used. + + This call should be used for non-fatal errors (such as database + errors) that the code may still be able to continue to the next unit + of work. + +*/ +static void maybe_die(int error_num, const char* fmt_reason, ...) +{ + char buffer[1000]; + va_list args; + va_start(args,fmt_reason); + my_vsnprintf(buffer, sizeof(buffer), fmt_reason, args); + va_end(args); + + fprintf(stderr, "%s: %s\n", my_progname, buffer); + fflush(stderr); + + maybe_exit(error_num); +} + /* @@ -900,10 +973,8 @@ 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)))) { - fprintf(stderr, "%s: Couldn't execute '%s': %s (%d)\n", - my_progname, query, - mysql_error(mysql_con), mysql_errno(mysql_con)); - safe_exit(EX_MYSQLERR); + maybe_die(EX_MYSQLERR, "Couldn't execute '%s': %s (%d)", + query, mysql_error(mysql_con), mysql_errno(mysql_con)); return 1; } return 0; @@ -948,7 +1019,7 @@ static void free_resources() } -static void safe_exit(int error) +static void maybe_exit(int error) { if (!first_error) first_error= error; @@ -1008,10 +1079,7 @@ static int connect_to_db(char *host, char *user,char *passwd) my_snprintf(buff, sizeof(buff), "/*!40100 SET @@SQL_MODE='%s' */", compatible_mode_normal_str); if (mysql_query_with_error_report(mysql, 0, buff)) - { - safe_exit(EX_MYSQLERR); DBUG_RETURN(1); - } /* set time_zone to UTC to allow dumping date types between servers with different time zone settings @@ -1020,10 +1088,7 @@ static int connect_to_db(char *host, char *user,char *passwd) { my_snprintf(buff, sizeof(buff), "/*!40103 SET TIME_ZONE='+00:00' */"); if (mysql_query_with_error_report(mysql, 0, buff)) - { - safe_exit(EX_MYSQLERR); DBUG_RETURN(1); - } } DBUG_RETURN(0); } /* connect_to_db */ @@ -1044,10 +1109,8 @@ static void unescape(FILE *file,char *pos,uint length) char *tmp; DBUG_ENTER("unescape"); if (!(tmp=(char*) my_malloc(length*2+1, MYF(MY_WME)))) - { - ignore_errors=0; /* Fatal error */ - safe_exit(EX_MYSQLERR); /* Force exit */ - } + die(EX_MYSQLERR, "Couldn't allocate memory"); + mysql_real_escape_string(&mysql_connection, tmp, pos, length); fputc('\'', file); fputs(tmp, file); @@ -1356,7 +1419,7 @@ static void print_blob_as_hex(FILE *output_file, const char *str, ulong len) /* dump_routines_for_db - -- retrievs list of routines for a given db, and prints out + -- retrieves list of routines for a given db, and prints out the CREATE PROCEDURE definition into the output (the dump). This function has logic to print the appropriate syntax depending on whether @@ -1489,8 +1552,9 @@ static uint dump_routines_for_db(char *db) my_free(query_str, MYF(MY_ALLOW_ZERO_PTR)); } } /* end of routine printing */ + mysql_free_result(routine_res); + } /* end of list of routines */ - mysql_free_result(routine_res); } mysql_free_result(routine_list_res); } /* end of for i (0 .. 1) */ @@ -1551,11 +1615,10 @@ static uint get_table_structure(char *table, char *db, char *table_type, if (!insert_pat_inited) { insert_pat_inited= 1; - if (init_dynamic_string(&insert_pat, "", 1024, 1024)) - safe_exit(EX_MYSQLERR); + init_dynamic_string_checked(&insert_pat, "", 1024, 1024); } else - dynstr_set(&insert_pat, ""); + dynstr_set_checked(&insert_pat, ""); } insert_option= ((delayed && opt_ignore) ? " DELAYED IGNORE " : @@ -1587,18 +1650,13 @@ static uint get_table_structure(char *table, char *db, char *table_type, my_snprintf(buff, sizeof(buff), "show create table %s", result_table); if (mysql_query_with_error_report(mysql, 0, buff)) - { - safe_exit(EX_MYSQLERR); DBUG_RETURN(0); - } if (path) { if (!(sql_file= open_sql_file_for_table(table))) - { - safe_exit(EX_MYSQLERR); DBUG_RETURN(0); - } + write_header(sql_file, db); } if (!opt_xml && opt_comments) @@ -1662,7 +1720,6 @@ static uint get_table_structure(char *table, char *db, char *table_type, my_free(scv_buff, MYF(MY_ALLOW_ZERO_PTR)); - safe_exit(EX_MYSQLERR); DBUG_RETURN(0); } else @@ -1725,7 +1782,6 @@ static uint get_table_structure(char *table, char *db, char *table_type, { if (path) my_fclose(sql_file, MYF(MY_WME)); - safe_exit(EX_MYSQLERR); DBUG_RETURN(0); } @@ -1737,19 +1793,19 @@ static uint get_table_structure(char *table, char *db, char *table_type, */ if (write_data) { - dynstr_append_mem(&insert_pat, "INSERT ", 7); - dynstr_append(&insert_pat, insert_option); - dynstr_append_mem(&insert_pat, "INTO ", 5); - dynstr_append(&insert_pat, opt_quoted_table); + dynstr_append_checked(&insert_pat, "INSERT "); + dynstr_append_checked(&insert_pat, insert_option); + dynstr_append_checked(&insert_pat, "INTO "); + dynstr_append_checked(&insert_pat, opt_quoted_table); if (complete_insert) { - dynstr_append_mem(&insert_pat, " (", 2); + dynstr_append_checked(&insert_pat, " ("); } else { - dynstr_append_mem(&insert_pat, " VALUES ", 8); + dynstr_append_checked(&insert_pat, " VALUES "); if (!extended_insert) - dynstr_append_mem(&insert_pat, "(", 1); + dynstr_append_checked(&insert_pat, "("); } } @@ -1759,10 +1815,10 @@ static uint get_table_structure(char *table, char *db, char *table_type, { if (init) { - dynstr_append_mem(&insert_pat, ", ", 2); + dynstr_append_checked(&insert_pat, ", "); } init=1; - dynstr_append(&insert_pat, + dynstr_append_checked(&insert_pat, quote_name(row[SHOW_FIELDNAME], name_buff, 0)); } } @@ -1777,10 +1833,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(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 (!opt_no_create_info) @@ -1788,10 +1841,7 @@ static uint get_table_structure(char *table, char *db, char *table_type, if (path) { if (!(sql_file= open_sql_file_for_table(table))) - { - safe_exit(EX_MYSQLERR); DBUG_RETURN(0); - } write_header(sql_file, db); } if (!opt_xml && opt_comments) @@ -1809,17 +1859,17 @@ static uint get_table_structure(char *table, char *db, char *table_type, if (write_data) { - dynstr_append_mem(&insert_pat, "INSERT ", 7); - dynstr_append(&insert_pat, insert_option); - dynstr_append_mem(&insert_pat, "INTO ", 5); - dynstr_append(&insert_pat, result_table); - if (opt_complete_insert) - dynstr_append_mem(&insert_pat, " (", 2); + dynstr_append_checked(&insert_pat, "INSERT "); + dynstr_append_checked(&insert_pat, insert_option); + dynstr_append_checked(&insert_pat, "INTO "); + dynstr_append_checked(&insert_pat, result_table); + if (complete_insert) + dynstr_append_checked(&insert_pat, " ("); else { - dynstr_append_mem(&insert_pat, " VALUES ", 8); + dynstr_append_checked(&insert_pat, " VALUES "); if (!extended_insert) - dynstr_append_mem(&insert_pat, "(", 1); + dynstr_append_checked(&insert_pat, "("); } } @@ -1834,11 +1884,11 @@ static uint get_table_structure(char *table, char *db, char *table_type, check_io(sql_file); } if (complete_insert) - dynstr_append_mem(&insert_pat, ", ", 2); + dynstr_append_checked(&insert_pat, ", "); } init=1; - if (opt_complete_insert) - dynstr_append(&insert_pat, + if (complete_insert) + dynstr_append_checked(&insert_pat, quote_name(row[SHOW_FIELDNAME], name_buff, 0)); if (!opt_no_create_info) { @@ -1888,7 +1938,6 @@ static uint get_table_structure(char *table, char *db, char *table_type, my_progname, result_table, mysql_error(mysql)); if (path) my_fclose(sql_file, MYF(MY_WME)); - safe_exit(EX_MYSQLERR); DBUG_RETURN(0); } @@ -1996,11 +2045,11 @@ continue_xml: check_io(sql_file); } } - if (opt_complete_insert) + if (complete_insert) { - dynstr_append_mem(&insert_pat, ") VALUES ", 9); + dynstr_append_checked(&insert_pat, ") VALUES "); if (!extended_insert) - dynstr_append_mem(&insert_pat, "(", 1); + dynstr_append_checked(&insert_pat, "("); } if (sql_file != md_result_file) { @@ -2047,7 +2096,6 @@ static void dump_triggers_for_table(char *table, { if (path) my_fclose(sql_file, MYF(MY_WME)); - safe_exit(EX_MYSQLERR); DBUG_VOID_RETURN; } if (mysql_num_rows(result)) @@ -2106,24 +2154,28 @@ DELIMITER ;;\n"); DBUG_VOID_RETURN; } -static char *add_load_option(char *ptr,const char *object, - const char *statement) +static void add_load_option(DYNAMIC_STRING *str, const char *option, + const char *option_value) { - if (object) + if (!option_value) { - /* Don't escape hex constants */ - if (object[0] == '0' && (object[1] == 'x' || object[1] == 'X')) - ptr= strxmov(ptr," ",statement," ",object,NullS); - else - { - /* char constant; escape */ - ptr= strxmov(ptr," ",statement," '",NullS); - ptr= field_escape(ptr,object,(uint) strlen(object)); - *ptr++= '\''; - } + /* Null value means we don't add this option. */ + return; } - return ptr; -} /* add_load_option */ + + dynstr_append_checked(str, option); + + if (strncmp(option_value, "0x", sizeof("0x")-1) == 0) + { + /* It's a hex constant, don't escape */ + dynstr_append_checked(str, option_value); + } + else + { + /* char constant; escape */ + field_escape(str, option_value); + } +} /* @@ -2133,28 +2185,36 @@ static char *add_load_option(char *ptr,const char *object, syntax errors from the SQL parser. */ -static char *field_escape(char *to,const char *from,uint length) +static void field_escape(DYNAMIC_STRING* in, const char *from) { - const char *end; - uint end_backslashes=0; + uint end_backslashes= 0; + + dynstr_append_checked(in, "'"); - for (end= from+length; from != end; from++) + while (*from) { - *to++= *from; + dynstr_append_mem_checked(in, from, 1); + if (*from == '\\') end_backslashes^=1; /* find odd number of backslashes */ else { if (*from == '\'' && !end_backslashes) - *to++= *from; /* We want a duplicate of "'" for MySQL */ + { + /* We want a duplicate of "'" for MySQL */ + dynstr_append_checked(in, "\'"); + } end_backslashes=0; } + from++; } /* Add missing backslashes if user has specified odd number of backs.*/ if (end_backslashes) - *to++= '\\'; - return to; -} /* field_escape */ + dynstr_append_checked(in, "\\"); + + dynstr_append_checked(in, "'"); +} + static char *alloc_query_str(ulong size) @@ -2162,10 +2222,8 @@ static char *alloc_query_str(ulong size) char *query; if (!(query= (char*) my_malloc(size, MYF(MY_WME)))) - { - ignore_errors= 0; /* Fatal error */ - safe_exit(EX_MYSQLERR); /* Force exit */ - } + die(EX_MYSQLERR, "Couldn't allocate a query string."); + return query; } @@ -2185,13 +2243,14 @@ static char *alloc_query_str(ulong size) void */ + static void dump_table(char *table, char *db) { char ignore_flag; - char query_buf[QUERY_LENGTH], *end, buff[256],table_buff[NAME_LEN+3]; + char buf[200], table_buff[NAME_LEN+3]; + DYNAMIC_STRING query_string; char table_type[NAME_LEN]; char *result_table, table_buff2[NAME_LEN*2+3], *opt_quoted_table; - char *query= query_buf; int error= 0; ulong rownr, row_break, total_length, init_length; uint num_fields; @@ -2245,44 +2304,69 @@ static void dump_table(char *table, char *db) opt_quoted_table= quote_name(table, table_buff2, 0); verbose_msg("-- Sending SELECT query...\n"); + + init_dynamic_string_checked(&query_string, "", 1024, 1024); + if (path) { char filename[FN_REFLEN], tmp_path[FN_REFLEN]; - convert_dirname(tmp_path,path,NullS); + + if (strlen(path) >= FN_REFLEN) + { + /* + This check is made because the some the file functions below + have FN_REFLEN sized stack allocated buffers and will cause + a crash even if the input destination buffer is large enough + to hold the output. + */ + die(EX_USAGE, "Input filename or options too long: %s", path); + } + + /* + Convert the path to native os format + and resolve to the full filepath. + */ + convert_dirname(tmp_path,path,NullS); my_load_path(tmp_path, tmp_path, NULL); - fn_format(filename, table, tmp_path, ".txt", 4); - my_delete(filename, MYF(0)); /* 'INTO OUTFILE' doesn't work, if - filename wasn't deleted */ + fn_format(filename, table, tmp_path, ".txt", MYF(MY_UNPACK_FILENAME)); + + /* Must delete the file that 'INTO OUTFILE' will write to */ + my_delete(filename, MYF(0)); + + /* convert to a unix path name to stick into the query */ to_unix_path(filename); - my_snprintf(query, QUERY_LENGTH, - "SELECT /*!40001 SQL_NO_CACHE */ * INTO OUTFILE '%s'", - filename); - end= strend(query); + + /* now build the query string */ + + dynstr_append_checked(&query_string, "SELECT /*!40001 SQL_NO_CACHE */ * INTO OUTFILE '"); + dynstr_append_checked(&query_string, filename); + dynstr_append_checked(&query_string, "'"); if (fields_terminated || enclosed || opt_enclosed || escaped) - end= strmov(end, " FIELDS"); - end= add_load_option(end, fields_terminated, " TERMINATED BY"); - end= add_load_option(end, enclosed, " ENCLOSED BY"); - end= add_load_option(end, opt_enclosed, " OPTIONALLY ENCLOSED BY"); - end= add_load_option(end, escaped, " ESCAPED BY"); - end= add_load_option(end, lines_terminated, " LINES TERMINATED BY"); - *end= '\0'; - - my_snprintf(buff, sizeof(buff), " FROM %s", result_table); - end= strmov(end,buff); - if (where || order_by) - { - query= alloc_query_str((ulong) ((end - query) + 1 + - (where ? strlen(where) + 7 : 0) + - (order_by ? strlen(order_by) + 10 : 0))); - end= strmov(query, query_buf); - - if (where) - end= strxmov(end, " WHERE ", where, NullS); - if (order_by) - end= strxmov(end, " ORDER BY ", order_by, NullS); - } - if (mysql_real_query(mysql, query, (uint) (end - query))) + dynstr_append_checked(&query_string, " FIELDS"); + + add_load_option(&query_string, " TERMINATED BY ", fields_terminated); + add_load_option(&query_string, " ENCLOSED BY ", enclosed); + add_load_option(&query_string, " OPTIONALLY ENCLOSED BY ", opt_enclosed); + add_load_option(&query_string, " ESCAPED BY ", escaped); + add_load_option(&query_string, " LINES TERMINATED BY ", lines_terminated); + + dynstr_append_checked(&query_string, " FROM "); + dynstr_append_checked(&query_string, result_table); + + if (where) + { + dynstr_append_checked(&query_string, " WHERE "); + dynstr_append_checked(&query_string, where); + } + + if (order_by) + { + dynstr_append_checked(&query_string, " ORDER BY "); + dynstr_append_checked(&query_string, order_by); + } + + if (mysql_real_query(mysql, query_string.str, query_string.length)) { DB_error(mysql, "when executing 'SELECT INTO OUTFILE'"); DBUG_VOID_RETURN; @@ -2296,41 +2380,38 @@ static void dump_table(char *table, char *db) result_table); check_io(md_result_file); } - my_snprintf(query, QUERY_LENGTH, - "SELECT /*!40001 SQL_NO_CACHE */ * FROM %s", - result_table); - if (where || order_by) - { - query= alloc_query_str((ulong) (strlen(query) + 1 + - (where ? strlen(where) + 7 : 0) + - (order_by ? strlen(order_by) + 10 : 0))); - end= strmov(query, query_buf); + + dynstr_append_checked(&query_string, "SELECT /*!40001 SQL_NO_CACHE */ * FROM "); + dynstr_append_checked(&query_string, result_table); - if (where) + if (where) + { + if (!opt_xml && opt_comments) { - if (!opt_xml && opt_comments) - { - fprintf(md_result_file, "-- WHERE: %s\n", where); - check_io(md_result_file); - } - end= strxmov(end, " WHERE ", where, NullS); + fprintf(md_result_file, "-- WHERE: %s\n", where); + check_io(md_result_file); } - if (order_by) + + dynstr_append_checked(&query_string, " WHERE "); + dynstr_append_checked(&query_string, where); + } + if (order_by) + { + if (!opt_xml && opt_comments) { - if (!opt_xml && opt_comments) - { - fprintf(md_result_file, "-- ORDER BY: %s\n", order_by); - check_io(md_result_file); - } - end= strxmov(end, " ORDER BY ", order_by, NullS); + fprintf(md_result_file, "-- ORDER BY: %s\n", order_by); + check_io(md_result_file); } + dynstr_append_checked(&query_string, " ORDER BY "); + dynstr_append_checked(&query_string, order_by); } + if (!opt_xml && !opt_compact) { fputs("\n", md_result_file); check_io(md_result_file); } - if (mysql_query_with_error_report(mysql, 0, query)) + if (mysql_query_with_error_report(mysql, 0, query_string.str)) { DB_error(mysql, "when retrieving data from server"); goto err; @@ -2404,14 +2485,9 @@ static void dump_table(char *table, char *db) ulong length= lengths[i]; if (!(field= mysql_fetch_field(res))) - { - my_snprintf(query, QUERY_LENGTH, - "%s: Not enough fields from table %s! Aborting.\n", - my_progname, result_table); - fputs(query,stderr); - error= EX_CONSCHECK; - goto err; - } + die(EX_CONSCHECK, + "Not enough fields from table %s! Aborting.\n", + result_table); /* 63 is my_charset_bin. If charsetnr is not 63, @@ -2430,9 +2506,9 @@ static void dump_table(char *table, char *db) if (extended_insert && !opt_xml) { if (i == 0) - dynstr_set(&extended_row,"("); + dynstr_set_checked(&extended_row,"("); else - dynstr_append(&extended_row,","); + dynstr_append_checked(&extended_row,","); if (row[i]) { @@ -2447,15 +2523,10 @@ static void dump_table(char *table, char *db) - In non-HEX mode we need up to 2 bytes per character, plus 2 bytes for leading and trailing '\'' characters. */ - if (dynstr_realloc(&extended_row,length * 2+2)) - { - fputs("Aborting dump (out of memory)",stderr); - error= EX_EOM; - goto err; - } + dynstr_realloc_checked(&extended_row,length * 2+2); if (opt_hex_blob && is_blob) { - dynstr_append(&extended_row, "0x"); + dynstr_append_checked(&extended_row, "0x"); extended_row.length+= mysql_hex_string(extended_row.str + extended_row.length, row[i], length); @@ -2463,13 +2534,13 @@ static void dump_table(char *table, char *db) } else { - dynstr_append(&extended_row,"'"); + dynstr_append_checked(&extended_row,"'"); extended_row.length += mysql_real_escape_string(&mysql_connection, &extended_row.str[extended_row.length], row[i],length); extended_row.str[extended_row.length]='\0'; - dynstr_append(&extended_row,"'"); + dynstr_append_checked(&extended_row,"'"); } } else @@ -2478,30 +2549,26 @@ static void dump_table(char *table, char *db) char *ptr= row[i]; if (my_isalpha(charset_info, *ptr) || (*ptr == '-' && my_isalpha(charset_info, ptr[1]))) - dynstr_append(&extended_row, "NULL"); + dynstr_append_checked(&extended_row, "NULL"); else { if (field->type == FIELD_TYPE_DECIMAL) { /* add " signs around */ - dynstr_append(&extended_row, "'"); - dynstr_append(&extended_row, ptr); - dynstr_append(&extended_row, "'"); + dynstr_append_checked(&extended_row, "'"); + dynstr_append_checked(&extended_row, ptr); + dynstr_append_checked(&extended_row, "'"); } else - dynstr_append(&extended_row, ptr); + dynstr_append_checked(&extended_row, ptr); } } } else - dynstr_append(&extended_row,"''"); - } - else if (dynstr_append(&extended_row,"NULL")) - { - fputs("Aborting dump (out of memory)",stderr); - error= EX_EOM; - goto err; + dynstr_append_checked(&extended_row,"''"); } + else + dynstr_append_checked(&extended_row,"NULL"); } else { @@ -2518,16 +2585,16 @@ static void dump_table(char *table, char *db) { if (opt_hex_blob && is_blob && length) { - /* Define xsi:type="xs:hexBinary" for hex encoded data */ - print_xml_tag(md_result_file, "\t\t", "", "field", "name=", - field->name, "xsi:type=", "xs:hexBinary", NullS); - print_blob_as_hex(md_result_file, row[i], length); + /* Define xsi:type="xs:hexBinary" for hex encoded data */ + print_xml_tag(md_result_file, "\t\t", "", "field", "name=", + field->name, "xsi:type=", "xs:hexBinary", NullS); + print_blob_as_hex(md_result_file, row[i], length); } else { - print_xml_tag(md_result_file, "\t\t", "", "field", "name=", - field->name, NullS); - print_quoted_xml(md_result_file, row[i], length); + print_xml_tag(md_result_file, "\t\t", "", "field", "name=", + field->name, NullS); + print_quoted_xml(md_result_file, row[i], length); } fputs("</field>\n", md_result_file); } @@ -2587,7 +2654,7 @@ static void dump_table(char *table, char *db) if (extended_insert) { ulong row_length; - dynstr_append(&extended_row,")"); + dynstr_append_checked(&extended_row,")"); row_length= 2 + extended_row.length; if (total_length + row_length < opt_net_buffer_length) { @@ -2623,14 +2690,14 @@ static void dump_table(char *table, char *db) check_io(md_result_file); if (mysql_errno(mysql)) { - my_snprintf(query, QUERY_LENGTH, + my_snprintf(buf, sizeof(buf), "%s: Error %d: %s when dumping table %s at row: %ld\n", my_progname, mysql_errno(mysql), mysql_error(mysql), result_table, rownr); - fputs(query,stderr); + fputs(buf,stderr); error= EX_CONSCHECK; goto err; } @@ -2653,15 +2720,13 @@ static void dump_table(char *table, char *db) check_io(md_result_file); } mysql_free_result(res); - if (query != query_buf) - my_free(query, MYF(MY_ALLOW_ZERO_PTR)); + dynstr_free(&query_string); } DBUG_VOID_RETURN; err: - if (query != query_buf) - my_free(query, MYF(MY_ALLOW_ZERO_PTR)); - safe_exit(error); + dynstr_free(&query_string); + maybe_exit(error); DBUG_VOID_RETURN; } /* dump_table */ @@ -2848,8 +2913,8 @@ static int init_dumping(char *database, int init_func(char*)) check_io(md_result_file); } } - if (extended_insert && init_dynamic_string(&extended_row, "", 1024, 1024)) - exit(EX_EOM); + if (extended_insert) + init_dynamic_string_checked(&extended_row, "", 1024, 1024); return 0; } /* init_dumping */ @@ -2882,11 +2947,11 @@ static int dump_all_tables_in_db(char *database) if (lock_tables) { DYNAMIC_STRING query; - init_dynamic_string(&query, "LOCK TABLES ", 256, 1024); + init_dynamic_string_checked(&query, "LOCK TABLES ", 256, 1024); for (numrows= 0 ; (table= getTableName(1)) ; numrows++) { - dynstr_append(&query, quote_name(table, table_buff, 1)); - dynstr_append(&query, " READ /*!32311 LOCAL */,"); + dynstr_append_checked(&query, quote_name(table, table_buff, 1)); + dynstr_append_checked(&query, " READ /*!32311 LOCAL */,"); } if (numrows && mysql_real_query(mysql, query.str, query.length-1)) DB_error(mysql, "when using LOCK TABLES"); @@ -2959,11 +3024,11 @@ static my_bool dump_all_views_in_db(char *database) if (lock_tables) { DYNAMIC_STRING query; - init_dynamic_string(&query, "LOCK TABLES ", 256, 1024); + init_dynamic_string_checked(&query, "LOCK TABLES ", 256, 1024); for (numrows= 0 ; (table= getTableName(1)); numrows++) { - dynstr_append(&query, quote_name(table, table_buff, 1)); - dynstr_append(&query, " READ /*!32311 LOCAL */,"); + dynstr_append_checked(&query, quote_name(table, table_buff, 1)); + dynstr_append_checked(&query, " READ /*!32311 LOCAL */,"); } if (numrows && mysql_real_query(mysql, query.str, query.length-1)) DB_error(mysql, "when using LOCK TABLES"); @@ -3015,9 +3080,7 @@ static char *get_actual_table_name(const char *old_table_name, MEM_ROOT *root) quote_for_like(old_table_name, show_name_buff)); if (mysql_query_with_error_report(mysql, 0, query)) - { - safe_exit(EX_MYSQLERR); - } + return NullS; if ((table_res= mysql_store_result(mysql))) { @@ -3053,9 +3116,9 @@ static int dump_selected_tables(char *db, char **table_names, int tables) init_alloc_root(&root, 8192, 0); if (!(dump_tables= pos= (char**) alloc_root(&root, tables * sizeof(char *)))) - exit(EX_EOM); + die(EX_EOM, "alloc_root failure."); - init_dynamic_string(&lock_tables_query, "LOCK TABLES ", 256, 1024); + init_dynamic_string_checked(&lock_tables_query, "LOCK TABLES ", 256, 1024); for (; tables > 0 ; tables-- , table_names++) { /* the table name passed on commandline may be wrong case */ @@ -3064,16 +3127,14 @@ static int dump_selected_tables(char *db, char **table_names, int tables) /* Add found table name to lock_tables_query */ if (lock_tables) { - dynstr_append(&lock_tables_query, quote_name(*pos, table_buff, 1)); - dynstr_append(&lock_tables_query, " READ /*!32311 LOCAL */,"); + dynstr_append_checked(&lock_tables_query, quote_name(*pos, table_buff, 1)); + dynstr_append_checked(&lock_tables_query, " READ /*!32311 LOCAL */,"); } pos++; } else { - my_printf_error(0,"Couldn't find table: \"%s\"\n", MYF(0), - *table_names); - safe_exit(EX_ILLEGAL_TABLE); + maybe_die(EX_ILLEGAL_TABLE, "Couldn't find table: \"%s\"", *table_names); /* We shall countinue here, if --force was given */ } } @@ -3319,7 +3380,7 @@ char check_if_ignore_table(const char *table_name, char *table_type) { char result= IGNORE_NONE; char buff[FN_REFLEN+80], show_name_buff[FN_REFLEN]; - MYSQL_RES *res; + MYSQL_RES *res= NULL; MYSQL_ROW row; DBUG_ENTER("check_if_ignore_table"); @@ -3488,12 +3549,12 @@ static int replace(DYNAMIC_STRING *ds_str, const char *start= strstr(ds_str->str, search_str); if (!start) return 1; - init_dynamic_string(&ds_tmp, "", + init_dynamic_string_checked(&ds_tmp, "", ds_str->length + replace_len, 256); - dynstr_append_mem(&ds_tmp, ds_str->str, start - ds_str->str); - dynstr_append_mem(&ds_tmp, replace_str, replace_len); - dynstr_append(&ds_tmp, start + search_len); - dynstr_set(ds_str, ds_tmp.str); + dynstr_append_mem_checked(&ds_tmp, ds_str->str, start - ds_str->str); + dynstr_append_mem_checked(&ds_tmp, replace_str, replace_len); + dynstr_append_checked(&ds_tmp, start + search_len); + dynstr_set_checked(ds_str, ds_tmp.str); dynstr_free(&ds_tmp); return 0; } @@ -3539,10 +3600,7 @@ static my_bool get_view_structure(char *table, char* db) my_snprintf(query, sizeof(query), "SHOW CREATE TABLE %s", result_table); if (mysql_query_with_error_report(mysql, &table_res, query)) - { - safe_exit(EX_MYSQLERR); DBUG_RETURN(0); - } /* Check if this is a view */ field= mysql_fetch_field_direct(table_res, 0); @@ -3556,10 +3614,8 @@ static my_bool get_view_structure(char *table, char* db) if (path) { if (!(sql_file= open_sql_file_for_table(table))) - { - safe_exit(EX_MYSQLERR); DBUG_RETURN(1); - } + write_header(sql_file, db); } @@ -3605,14 +3661,14 @@ static my_bool get_view_structure(char *table, char* db) /* Save the result of SHOW CREATE TABLE in ds_view */ row= mysql_fetch_row(table_res); lengths= mysql_fetch_lengths(table_res); - init_dynamic_string(&ds_view, row[1], lengths[1] + 1, 1024); + init_dynamic_string_checked(&ds_view, row[1], lengths[1] + 1, 1024); mysql_free_result(table_res); /* Get the result from "select ... information_schema" */ if (!(table_res= mysql_store_result(mysql)) || !(row= mysql_fetch_row(table_res))) { - safe_exit(EX_MYSQLERR); + DB_error(mysql, "when trying to save the result of SHOW CREATE TABLE in ds_view."); DBUG_RETURN(1); } @@ -3684,6 +3740,45 @@ static my_bool get_view_structure(char *table, char* db) DBUG_RETURN(0); } +/* + The following functions are wrappers for the dynamic string functions + and if they fail, the wrappers will terminate the current process. +*/ + +#define DYNAMIC_STR_ERROR_MSG "Couldn't perform DYNAMIC_STRING operation" + +static void init_dynamic_string_checked(DYNAMIC_STRING *str, const char *init_str, + uint init_alloc, uint alloc_increment) +{ + if (init_dynamic_string(str, init_str, init_alloc, alloc_increment)) + die(EX_MYSQLERR, DYNAMIC_STR_ERROR_MSG); +} + +static void dynstr_append_checked(DYNAMIC_STRING* dest, const char* src) +{ + if (dynstr_append(dest, src)) + die(EX_MYSQLERR, DYNAMIC_STR_ERROR_MSG); +} + +static void dynstr_set_checked(DYNAMIC_STRING *str, const char *init_str) +{ + if (dynstr_set(str, init_str)) + die(EX_MYSQLERR, DYNAMIC_STR_ERROR_MSG); +} + +static void dynstr_append_mem_checked(DYNAMIC_STRING *str, const char *append, + uint length) +{ + if (dynstr_append_mem(str, append, length)) + die(EX_MYSQLERR, DYNAMIC_STR_ERROR_MSG); +} + +static void dynstr_realloc_checked(DYNAMIC_STRING *str, ulong additional_size) +{ + if (dynstr_realloc(str, additional_size)) + die(EX_MYSQLERR, DYNAMIC_STR_ERROR_MSG); +} + int main(int argc, char **argv) { diff --git a/client/mysqltest.c b/client/mysqltest.c index 30f95dd4340..568d33f7385 100644 --- a/client/mysqltest.c +++ b/client/mysqltest.c @@ -3534,7 +3534,7 @@ void do_connect(struct st_command *command) opt_ssl_capath, opt_ssl_cipher); #if MYSQL_VERSION_ID >= 50000 /* Turn on ssl_verify_server_cert only if host is "localhost" */ - opt_ssl_verify_server_cert= !strcmp(ds_connection_name.str, "localhost"); + opt_ssl_verify_server_cert= !strcmp(ds_host.str, "localhost"); mysql_options(&next_con->mysql, MYSQL_OPT_SSL_VERIFY_SERVER_CERT, &opt_ssl_verify_server_cert); #endif @@ -6002,15 +6002,13 @@ int main(int argc, char **argv) #ifdef HAVE_OPENSSL -#if MYSQL_VERSION_ID >= 50000 - opt_ssl_verify_server_cert= TRUE; /* Always on in mysqltest */ -#endif - if (opt_use_ssl) { mysql_ssl_set(&cur_con->mysql, opt_ssl_key, opt_ssl_cert, opt_ssl_ca, opt_ssl_capath, opt_ssl_cipher); #if MYSQL_VERSION_ID >= 50000 + /* Turn on ssl_verify_server_cert only if host is "localhost" */ + opt_ssl_verify_server_cert= opt_host && !strcmp(opt_host, "localhost"); mysql_options(&cur_con->mysql, MYSQL_OPT_SSL_VERIFY_SERVER_CERT, &opt_ssl_verify_server_cert); #endif diff --git a/extra/yassl/README b/extra/yassl/README index 32d97a1e873..6c4d101efc0 100644 --- a/extra/yassl/README +++ b/extra/yassl/README @@ -1,3 +1,11 @@ +*****************yaSSL Release notes, version 1.6.0 (2/22/07) + + This release of yaSSL contains bug fixes, portability enhancements, and + better X509 support. + +See normal build instructions below under 1.0.6. +See libcurl build instructions below under 1.3.0 and note in 1.5.8. + *****************yaSSL Release notes, version 1.5.8 (1/10/07) This release of yaSSL contains bug fixes, portability enhancements, and diff --git a/extra/yassl/include/buffer.hpp b/extra/yassl/include/buffer.hpp index 3fe12f38f57..a51bca9a630 100644 --- a/extra/yassl/include/buffer.hpp +++ b/extra/yassl/include/buffer.hpp @@ -49,13 +49,11 @@ const uint AUTO = 0xFEEDBEEF; // Checking Policy should implement a check function that tests whether the // index is within the size limit of the array struct Check { - Check() {} void check(uint i, uint limit); }; struct NoCheck { - NoCheck() {} void check(uint, uint); }; @@ -193,7 +191,6 @@ inline void checked_delete(T* p) // sets pointer to zero so safe for std conatiners struct del_ptr_zero { - del_ptr_zero() {} template <typename T> void operator()(T*& p) const { diff --git a/extra/yassl/include/crypto_wrapper.hpp b/extra/yassl/include/crypto_wrapper.hpp index 9e4eb582368..07b5925265a 100644 --- a/extra/yassl/include/crypto_wrapper.hpp +++ b/extra/yassl/include/crypto_wrapper.hpp @@ -42,7 +42,6 @@ namespace yaSSL { // Digest policy should implement a get_digest, update, and get sizes for pad // and digest struct Digest : public virtual_base { - Digest() {} virtual void get_digest(byte*) = 0; virtual void get_digest(byte*, const byte*, unsigned int) = 0; virtual void update(const byte*, unsigned int) = 0; @@ -54,7 +53,6 @@ struct Digest : public virtual_base { // For use with NULL Digests struct NO_MAC : public Digest { - NO_MAC() {} void get_digest(byte*); void get_digest(byte*, const byte*, unsigned int); void update(const byte*, unsigned int); @@ -179,7 +177,6 @@ private: // BulkCipher policy should implement encrypt, decrypt, get block size, // and set keys for encrypt and decrypt struct BulkCipher : public virtual_base { - BulkCipher() {} virtual void encrypt(byte*, const byte*, unsigned int) = 0; virtual void decrypt(byte*, const byte*, unsigned int) = 0; virtual void set_encryptKey(const byte*, const byte* = 0) = 0; @@ -193,7 +190,6 @@ struct BulkCipher : public virtual_base { // For use with NULL Ciphers struct NO_Cipher : public BulkCipher { - NO_Cipher() {} void encrypt(byte*, const byte*, unsigned int) {} void decrypt(byte*, const byte*, unsigned int) {} void set_encryptKey(const byte*, const byte*) {} @@ -315,14 +311,12 @@ struct Auth : public virtual_base { virtual bool verify(const byte*, unsigned int, const byte*, unsigned int) = 0; virtual uint get_signatureLength() const = 0; - Auth() {} virtual ~Auth() {} }; // For use with NULL Authentication schemes struct NO_Auth : public Auth { - NO_Auth() {} void sign(byte*, const byte*, unsigned int, const RandomPool&) {} bool verify(const byte*, unsigned int, const byte*, unsigned int) { return true; } diff --git a/extra/yassl/include/openssl/ssl.h b/extra/yassl/include/openssl/ssl.h index d0c49d6816c..7dd33e3fcad 100644 --- a/extra/yassl/include/openssl/ssl.h +++ b/extra/yassl/include/openssl/ssl.h @@ -33,7 +33,8 @@ #include "opensslv.h" /* for version number */ #include "rsa.h" -#define YASSL_VERSION "1.5.8" + +#define YASSL_VERSION "1.6.5" #if defined(__cplusplus) @@ -189,16 +190,17 @@ enum { /* ERR Constants */ EVP_R_BAD_DECRYPT = 2 }; -#ifdef WIN - typedef SOCKET socket_t; -#else - typedef int socket_t; +/* + Allow type used by SSL_set_fd to be changed, default to int + in order to be compatible with OpenSSL + */ +#ifndef YASSL_SOCKET_T_DEFINED +typedef int YASSL_SOCKET_T; #endif - SSL_CTX* SSL_CTX_new(SSL_METHOD*); SSL* SSL_new(SSL_CTX*); -int SSL_set_fd (SSL*, socket_t); +int SSL_set_fd (SSL*, YASSL_SOCKET_T); int SSL_connect(SSL*); int SSL_write(SSL*, const void*, int); int SSL_read(SSL*, void*, int); diff --git a/extra/yassl/include/socket_wrapper.hpp b/extra/yassl/include/socket_wrapper.hpp index de28778ead9..308704c2af0 100644 --- a/extra/yassl/include/socket_wrapper.hpp +++ b/extra/yassl/include/socket_wrapper.hpp @@ -38,14 +38,16 @@ #include <netinet/in.h> #include <arpa/inet.h> #endif -#include "openssl/ssl.h" /* for socket_t */ namespace yaSSL { typedef unsigned int uint; -#ifndef _WIN32 +#ifdef _WIN32 + typedef SOCKET socket_t; +#else + typedef int socket_t; const socket_t INVALID_SOCKET = -1; const int SD_RECEIVE = 0; const int SD_SEND = 1; diff --git a/extra/yassl/include/yassl_imp.hpp b/extra/yassl/include/yassl_imp.hpp index a94b03bacbf..f6434443cb0 100644 --- a/extra/yassl/include/yassl_imp.hpp +++ b/extra/yassl/include/yassl_imp.hpp @@ -64,7 +64,6 @@ struct RecordLayerHeader { // base for all messages struct Message : public virtual_base { - Message() {} virtual input_buffer& set(input_buffer&) =0; virtual output_buffer& get(output_buffer&) const =0; @@ -178,7 +177,6 @@ private: class HandShakeBase : public virtual_base { int length_; public: - HandShakeBase() {} int get_length() const; void set_length(int); @@ -196,7 +194,6 @@ public: struct HelloRequest : public HandShakeBase { - HelloRequest() {} input_buffer& set(input_buffer& in); output_buffer& get(output_buffer& out) const; @@ -330,7 +327,6 @@ private: struct ServerKeyBase : public virtual_base { - ServerKeyBase() {} virtual ~ServerKeyBase() {} virtual void build(SSL&) {} virtual void read(SSL&, input_buffer&) {} @@ -341,21 +337,15 @@ struct ServerKeyBase : public virtual_base { // Server random number for FORTEZZA KEA struct Fortezza_Server : public ServerKeyBase { - Fortezza_Server() {} opaque r_s_[FORTEZZA_MAX]; }; struct SignatureBase : public virtual_base { - SignatureBase() {} virtual ~SignatureBase() {} }; -struct anonymous_sa : public SignatureBase -{ -public: - anonymous_sa() {} -}; +struct anonymous_sa : public SignatureBase {}; struct Hashes { @@ -365,13 +355,11 @@ struct Hashes { struct rsa_sa : public SignatureBase { - rsa_sa() {} Hashes hashes_; }; struct dsa_sa : public SignatureBase { - dsa_sa() {} uint8 sha_[SHA_LEN]; }; @@ -399,7 +387,6 @@ private: // Server's RSA exchange struct RSA_Server : public ServerKeyBase { - RSA_Server() {} ServerRSAParams params_; opaque* signature_; // signed rsa_sa hashes }; @@ -474,7 +461,6 @@ struct PreMasterSecret { struct ClientKeyBase : public virtual_base { - ClientKeyBase() {} virtual ~ClientKeyBase() {} virtual void build(SSL&) {} virtual void read(SSL&, input_buffer&) {} @@ -505,7 +491,6 @@ private: // Fortezza Key Parameters from page 29 // hard code lengths cause only used here struct FortezzaKeys : public ClientKeyBase { - FortezzaKeys() {} opaque y_c_ [128]; // client's Yc, public value opaque r_c_ [128]; // client's Rc opaque y_signature_ [40]; // DSS signed public key diff --git a/extra/yassl/include/yassl_int.hpp b/extra/yassl/include/yassl_int.hpp index d75d2200b3c..94cb85c3300 100644 --- a/extra/yassl/include/yassl_int.hpp +++ b/extra/yassl/include/yassl_int.hpp @@ -228,7 +228,6 @@ struct BIGNUM { TaoCrypt::Integer), we need to explicitly state the namespace here to let gcc 2.96 deduce the correct type. */ - BIGNUM() {} yaSSL::Integer int_; void assign(const byte* b, uint s) { int_.assign(b,s); } }; diff --git a/extra/yassl/src/crypto_wrapper.cpp b/extra/yassl/src/crypto_wrapper.cpp index 0291faab301..28d7f1b5693 100644 --- a/extra/yassl/src/crypto_wrapper.cpp +++ b/extra/yassl/src/crypto_wrapper.cpp @@ -550,7 +550,6 @@ void RandomPool::Fill(opaque* dst, uint sz) const // Implementation of DSS Authentication struct DSS::DSSImpl { - DSSImpl() {} void SetPublic (const byte*, unsigned int); void SetPrivate(const byte*, unsigned int); TaoCrypt::DSA_PublicKey publicKey_; @@ -623,7 +622,6 @@ bool DSS::verify(const byte* sha_digest, unsigned int /* shaSz */, // Implementation of RSA key interface struct RSA::RSAImpl { - RSAImpl() {} void SetPublic (const byte*, unsigned int); void SetPrivate(const byte*, unsigned int); TaoCrypt::RSA_PublicKey publicKey_; diff --git a/extra/yassl/src/ssl.cpp b/extra/yassl/src/ssl.cpp index 1f9d0dd4020..86dfa1c6ebd 100644 --- a/extra/yassl/src/ssl.cpp +++ b/extra/yassl/src/ssl.cpp @@ -58,6 +58,9 @@ int read_file(SSL_CTX* ctx, const char* file, int format, CertType type) if (format != SSL_FILETYPE_ASN1 && format != SSL_FILETYPE_PEM) return SSL_BAD_FILETYPE; + if (file == NULL || !file[0]) + return SSL_BAD_FILE; + FILE* input = fopen(file, "rb"); if (!input) return SSL_BAD_FILE; @@ -229,7 +232,7 @@ void SSL_free(SSL* ssl) } -int SSL_set_fd(SSL* ssl, socket_t fd) +int SSL_set_fd(SSL* ssl, YASSL_SOCKET_T fd) { ssl->useSocket().set_fd(fd); return SSL_SUCCESS; @@ -950,7 +953,7 @@ void ERR_print_errors_fp(FILE* /*fp*/) char* ERR_error_string(unsigned long errNumber, char* buffer) { - static char* msg = (char*) "Please supply a buffer for error string"; + static char* msg = (char*)"Please supply a buffer for error string"; if (buffer) { SetErrorString(YasslError(errNumber), buffer); diff --git a/extra/yassl/taocrypt/README b/extra/yassl/taocrypt/README index 34e1744492e..0a7ff301786 100644 --- a/extra/yassl/taocrypt/README +++ b/extra/yassl/taocrypt/README @@ -1,4 +1,15 @@ -TaoCrypt release 0.9.0 09/18/2006 +TaoCrypt release 0.9.2 02/5/2007 + + +This release includes bug fixes, portability enhancements, and some +optimiations. + +See 0.9.0 for build instructions. + + + + +******************TaoCrypt release 0.9.0 09/18/2006 This is the first release of TaoCrypt, it was previously only included with yaSSL. TaoCrypt is highly portable and fast, its features include: diff --git a/extra/yassl/taocrypt/benchmark/benchmark.cpp b/extra/yassl/taocrypt/benchmark/benchmark.cpp index dd9d1b1ff0d..bb725a90187 100644 --- a/extra/yassl/taocrypt/benchmark/benchmark.cpp +++ b/extra/yassl/taocrypt/benchmark/benchmark.cpp @@ -65,7 +65,7 @@ int main(int argc, char** argv) const int megs = 5; // how much to test -const byte global_key[] = +const byte key[] = { 0x01,0x23,0x45,0x67,0x89,0xab,0xcd,0xef, 0xfe,0xde,0xba,0x98,0x76,0x54,0x32,0x10, @@ -81,19 +81,19 @@ const byte iv[] = }; -byte global_plain [1024*1024]; -byte global_cipher[1024*1024]; +byte plain [1024*1024]; +byte cipher[1024*1024]; void bench_des() { DES_EDE3_CBC_Encryption enc; - enc.SetKey(global_key, 16, iv); + enc.SetKey(key, 16, iv); double start = current_time(); for(int i = 0; i < megs; i++) - enc.Process(global_plain, global_cipher, sizeof(global_plain)); + enc.Process(plain, cipher, sizeof(plain)); double total = current_time() - start; @@ -107,12 +107,12 @@ void bench_des() void bench_aes(bool show) { AES_CBC_Encryption enc; - enc.SetKey(global_key, 16, iv); + enc.SetKey(key, 16, iv); double start = current_time(); for(int i = 0; i < megs; i++) - enc.Process(global_plain, global_cipher, sizeof(global_plain)); + enc.Process(plain, cipher, sizeof(plain)); double total = current_time() - start; @@ -127,12 +127,12 @@ void bench_aes(bool show) void bench_twofish() { Twofish_CBC_Encryption enc; - enc.SetKey(global_key, 16, iv); + enc.SetKey(key, 16, iv); double start = current_time(); for(int i = 0; i < megs; i++) - enc.Process(global_plain, global_cipher, sizeof(global_plain)); + enc.Process(plain, cipher, sizeof(plain)); double total = current_time() - start; @@ -147,12 +147,12 @@ void bench_twofish() void bench_blowfish() { Blowfish_CBC_Encryption enc; - enc.SetKey(global_key, 16, iv); + enc.SetKey(key, 16, iv); double start = current_time(); for(int i = 0; i < megs; i++) - enc.Process(global_plain, global_cipher, sizeof(global_plain)); + enc.Process(plain, cipher, sizeof(plain)); double total = current_time() - start; @@ -166,12 +166,12 @@ void bench_blowfish() void bench_arc4() { ARC4 enc; - enc.SetKey(global_key, 16); + enc.SetKey(key, 16); double start = current_time(); for(int i = 0; i < megs; i++) - enc.Process(global_cipher, global_plain, sizeof(global_plain)); + enc.Process(cipher, plain, sizeof(plain)); double total = current_time() - start; @@ -191,7 +191,7 @@ void bench_md5() for(int i = 0; i < megs; i++) - hash.Update(global_plain, sizeof(global_plain)); + hash.Update(plain, sizeof(plain)); hash.Final(digest); @@ -213,7 +213,7 @@ void bench_sha() for(int i = 0; i < megs; i++) - hash.Update(global_plain, sizeof(global_plain)); + hash.Update(plain, sizeof(plain)); hash.Final(digest); @@ -241,7 +241,7 @@ void bench_ripemd() for(int i = 0; i < megs; i++) - hash.Update(global_plain, sizeof(global_plain)); + hash.Update(plain, sizeof(plain)); hash.Final(digest); diff --git a/extra/yassl/taocrypt/include/algebra.hpp b/extra/yassl/taocrypt/include/algebra.hpp index 9a6b5344c0d..298ef115a4a 100644 --- a/extra/yassl/taocrypt/include/algebra.hpp +++ b/extra/yassl/taocrypt/include/algebra.hpp @@ -40,7 +40,6 @@ class TAOCRYPT_NO_VTABLE AbstractGroup : public virtual_base public: typedef Integer Element; - AbstractGroup() {} virtual ~AbstractGroup() {} virtual bool Equal(const Element &a, const Element &b) const =0; @@ -95,7 +94,6 @@ private: class MultiplicativeGroupT : public AbstractGroup { public: - MultiplicativeGroupT() {} const AbstractRing& GetRing() const {return *m_pRing;} @@ -147,7 +145,6 @@ class TAOCRYPT_NO_VTABLE AbstractEuclideanDomain : public AbstractRing { public: - AbstractEuclideanDomain() {} typedef Integer Element; virtual void DivisionAlgorithm(Element &r, Element &q, const Element &a, diff --git a/extra/yassl/taocrypt/include/des.hpp b/extra/yassl/taocrypt/include/des.hpp index 9082f8ab57d..f99a289392f 100644 --- a/extra/yassl/taocrypt/include/des.hpp +++ b/extra/yassl/taocrypt/include/des.hpp @@ -41,7 +41,6 @@ enum { DES_BLOCK_SIZE = 8, DES_KEY_SIZE = 32 }; class BasicDES { public: - BasicDES() {} void SetKey(const byte*, word32, CipherDir dir); void RawProcessBlock(word32&, word32&) const; protected: diff --git a/extra/yassl/taocrypt/include/hash.hpp b/extra/yassl/taocrypt/include/hash.hpp index 71072bd3e74..fa5f6c04720 100644 --- a/extra/yassl/taocrypt/include/hash.hpp +++ b/extra/yassl/taocrypt/include/hash.hpp @@ -31,7 +31,6 @@ namespace TaoCrypt { // HASH class HASH : public virtual_base { public: - HASH() {} virtual ~HASH() {} virtual void Update(const byte*, word32) = 0; @@ -58,8 +57,7 @@ public: word32 GetBitCountLo() const { return loLen_ << 3; } word32 GetBitCountHi() const { return (loLen_ >> (8*sizeof(loLen_) - 3)) + (hiLen_ << 3); } - - enum { MaxDigestSz = 5, MaxBufferSz = 64 }; + enum { MaxDigestSz = 8, MaxBufferSz = 64 }; protected: typedef word32 HashLengthType; word32 buffLen_; // in bytes @@ -74,6 +72,38 @@ protected: }; +#ifdef WORD64_AVAILABLE + +// 64-bit HASH with Transform +class HASH64withTransform : public HASH { +public: + HASH64withTransform(word32 digSz, word32 buffSz); + virtual ~HASH64withTransform() {} + virtual ByteOrder getByteOrder() const = 0; + virtual word32 getPadSize() const = 0; + + virtual void Update(const byte*, word32); + virtual void Final(byte*); + + word32 GetBitCountLo() const { return loLen_ << 3; } + word32 GetBitCountHi() const { return (loLen_ >> (8*sizeof(loLen_) - 3)) + + (hiLen_ << 3); } + enum { MaxDigestSz = 8, MaxBufferSz = 128 }; +protected: + typedef word32 HashLengthType; + word32 buffLen_; // in bytes + HashLengthType loLen_; // length in bytes + HashLengthType hiLen_; // length in bytes + word64 digest_[MaxDigestSz]; + word64 buffer_[MaxBufferSz / sizeof(word64)]; + + virtual void Transform() = 0; + + void AddLength(word32); +}; + +#endif // WORD64_AVAILABLE + } // namespace diff --git a/extra/yassl/taocrypt/include/hmac.hpp b/extra/yassl/taocrypt/include/hmac.hpp index ccd54c05cb1..1d486514e06 100644 --- a/extra/yassl/taocrypt/include/hmac.hpp +++ b/extra/yassl/taocrypt/include/hmac.hpp @@ -109,11 +109,11 @@ void HMAC<T>::KeyInnerHash() // Update template <class T> -void HMAC<T>::Update(const byte* msg_arg, word32 length) +void HMAC<T>::Update(const byte* msg, word32 length) { if (!innerHashKeyed_) KeyInnerHash(); - mac_.Update(msg_arg, length); + mac_.Update(msg, length); } diff --git a/extra/yassl/taocrypt/include/misc.hpp b/extra/yassl/taocrypt/include/misc.hpp index 224589e0640..96648a39aa1 100644 --- a/extra/yassl/taocrypt/include/misc.hpp +++ b/extra/yassl/taocrypt/include/misc.hpp @@ -464,6 +464,25 @@ inline word32 ByteReverse(word32 value) } +#ifdef WORD64_AVAILABLE + +inline word64 ByteReverse(word64 value) +{ +#ifdef TAOCRYPT_SLOW_WORD64 + return (word64(ByteReverse(word32(value))) << 32) | + ByteReverse(word32(value>>32)); +#else + value = ((value & W64LIT(0xFF00FF00FF00FF00)) >> 8) | + ((value & W64LIT(0x00FF00FF00FF00FF)) << 8); + value = ((value & W64LIT(0xFFFF0000FFFF0000)) >> 16) | + ((value & W64LIT(0x0000FFFF0000FFFF)) << 16); + return rotlFixed(value, 32U); +#endif +} + +#endif // WORD64_AVAILABLE + + template <typename T> inline void ByteReverse(T* out, const T* in, word32 byteCount) { diff --git a/extra/yassl/taocrypt/include/modarith.hpp b/extra/yassl/taocrypt/include/modarith.hpp index f42a4397d48..501a8129b90 100644 --- a/extra/yassl/taocrypt/include/modarith.hpp +++ b/extra/yassl/taocrypt/include/modarith.hpp @@ -37,8 +37,8 @@ public: typedef int RandomizationParameter; typedef Integer Element; - ModularArithmetic(const Integer &modulus_arg = Integer::One()) - : modulus(modulus_arg), result((word)0, modulus_arg.reg_.size()) {} + ModularArithmetic(const Integer &modulus = Integer::One()) + : modulus(modulus), result((word)0, modulus.reg_.size()) {} ModularArithmetic(const ModularArithmetic &ma) : AbstractRing(), diff --git a/extra/yassl/taocrypt/include/modes.hpp b/extra/yassl/taocrypt/include/modes.hpp index 36618a8f5ed..d1ebce7568b 100644 --- a/extra/yassl/taocrypt/include/modes.hpp +++ b/extra/yassl/taocrypt/include/modes.hpp @@ -42,8 +42,8 @@ public: { cipher_.Process(c, p, sz); } void SetKey(const byte* k, word32 sz) { cipher_.SetKey(k, sz, DIR); } - void SetKey(const byte* k, word32 sz, const byte* iv_arg) - { cipher_.SetKey(k, sz, DIR); cipher_.SetIV(iv_arg); } + void SetKey(const byte* k, word32 sz, const byte* iv) + { cipher_.SetKey(k, sz, DIR); cipher_.SetIV(iv); } private: T cipher_; diff --git a/extra/yassl/taocrypt/include/rsa.hpp b/extra/yassl/taocrypt/include/rsa.hpp index 454b0ef33a7..c895ab6fd34 100644 --- a/extra/yassl/taocrypt/include/rsa.hpp +++ b/extra/yassl/taocrypt/include/rsa.hpp @@ -131,7 +131,6 @@ private: // block type 2 padding class RSA_BlockType2 { public: - RSA_BlockType2() {} void Pad(const byte*, word32, byte*, word32, RandomNumberGenerator&) const; word32 UnPad(const byte*, word32, byte*) const; @@ -141,7 +140,6 @@ public: // block type 1 padding class RSA_BlockType1 { public: - RSA_BlockType1() {} void Pad(const byte*, word32, byte*, word32, RandomNumberGenerator&) const; word32 UnPad(const byte*, word32, byte*) const; @@ -176,27 +174,25 @@ public: // Public Encrypt template<class Pad> -void RSA_Encryptor<Pad>::Encrypt(const byte* plain_arg, word32 sz, - byte* cipher_arg, - RandomNumberGenerator& rng_arg) +void RSA_Encryptor<Pad>::Encrypt(const byte* plain, word32 sz, byte* cipher, + RandomNumberGenerator& rng) { PK_Lengths lengths(key_.GetModulus()); assert(sz <= lengths.FixedMaxPlaintextLength()); ByteBlock paddedBlock(lengths.PaddedBlockByteLength()); - padding_.Pad(plain_arg, sz, paddedBlock.get_buffer(), - lengths.PaddedBlockBitLength(), rng_arg); + padding_.Pad(plain, sz, paddedBlock.get_buffer(), + lengths.PaddedBlockBitLength(), rng); key_.ApplyFunction(Integer(paddedBlock.get_buffer(), paddedBlock.size())). - Encode(cipher_arg, lengths.FixedCiphertextLength()); + Encode(cipher, lengths.FixedCiphertextLength()); } // Private Decrypt template<class Pad> -word32 RSA_Decryptor<Pad>::Decrypt(const byte* cipher_arg, word32 sz, - byte* plain_arg, - RandomNumberGenerator& rng_arg) +word32 RSA_Decryptor<Pad>::Decrypt(const byte* cipher, word32 sz, byte* plain, + RandomNumberGenerator& rng) { PK_Lengths lengths(key_.GetModulus()); assert(sz == lengths.FixedCiphertextLength()); @@ -205,29 +201,29 @@ word32 RSA_Decryptor<Pad>::Decrypt(const byte* cipher_arg, word32 sz, return 0; ByteBlock paddedBlock(lengths.PaddedBlockByteLength()); - Integer x = key_.CalculateInverse(rng_arg, Integer(cipher_arg, + Integer x = key_.CalculateInverse(rng, Integer(cipher, lengths.FixedCiphertextLength()).Ref()); if (x.ByteCount() > paddedBlock.size()) x = Integer::Zero(); // don't return false, prevents timing attack x.Encode(paddedBlock.get_buffer(), paddedBlock.size()); return padding_.UnPad(paddedBlock.get_buffer(), - lengths.PaddedBlockBitLength(), plain_arg); + lengths.PaddedBlockBitLength(), plain); } // Private SSL type (block 1) Encrypt template<class Pad> void RSA_Decryptor<Pad>::SSL_Sign(const byte* message, word32 sz, byte* sig, - RandomNumberGenerator& rng_arg) + RandomNumberGenerator& rng) { RSA_PublicKey inverse; inverse.Initialize(key_.GetModulus(), key_.GetPrivateExponent()); RSA_Encryptor<RSA_BlockType1> enc(inverse); // SSL Type - enc.Encrypt(message, sz, sig, rng_arg); + enc.Encrypt(message, sz, sig, rng); } -word32 SSL_Decrypt(const RSA_PublicKey& key, const byte* sig, byte* plain_arg); +word32 SSL_Decrypt(const RSA_PublicKey& key, const byte* sig, byte* plain); // Public SSL type (block 1) Decrypt @@ -235,11 +231,11 @@ template<class Pad> bool RSA_Encryptor<Pad>::SSL_Verify(const byte* message, word32 sz, const byte* sig) { - ByteBlock local_plain(PK_Lengths(key_.GetModulus()).FixedMaxPlaintextLength()); - if (SSL_Decrypt(key_, sig, local_plain.get_buffer()) != sz) + ByteBlock plain(PK_Lengths(key_.GetModulus()).FixedMaxPlaintextLength()); + if (SSL_Decrypt(key_, sig, plain.get_buffer()) != sz) return false; // not right justified or bad padding - if ( (memcmp(local_plain.get_buffer(), message, sz)) == 0) + if ( (memcmp(plain.get_buffer(), message, sz)) == 0) return true; return false; } diff --git a/extra/yassl/taocrypt/include/sha.hpp b/extra/yassl/taocrypt/include/sha.hpp index c501d3ad306..c0b4368121b 100644 --- a/extra/yassl/taocrypt/include/sha.hpp +++ b/extra/yassl/taocrypt/include/sha.hpp @@ -64,6 +64,103 @@ inline void swap(SHA& a, SHA& b) a.Swap(b); } +// SHA-256 digest +class SHA256 : public HASHwithTransform { +public: + enum { BLOCK_SIZE = 64, DIGEST_SIZE = 32, PAD_SIZE = 56, + TAO_BYTE_ORDER = BigEndianOrder}; // in Bytes + SHA256() : HASHwithTransform(DIGEST_SIZE / sizeof(word32), BLOCK_SIZE) + { Init(); } + ByteOrder getByteOrder() const { return ByteOrder(TAO_BYTE_ORDER); } + word32 getBlockSize() const { return BLOCK_SIZE; } + word32 getDigestSize() const { return DIGEST_SIZE; } + word32 getPadSize() const { return PAD_SIZE; } + + void Init(); + + SHA256(const SHA256&); + SHA256& operator= (const SHA256&); + + void Swap(SHA256&); +private: + void Transform(); +}; + + +// SHA-224 digest +class SHA224 : public HASHwithTransform { +public: + enum { BLOCK_SIZE = 64, DIGEST_SIZE = 28, PAD_SIZE = 56, + TAO_BYTE_ORDER = BigEndianOrder}; // in Bytes + SHA224() : HASHwithTransform(SHA256::DIGEST_SIZE /sizeof(word32),BLOCK_SIZE) + { Init(); } + ByteOrder getByteOrder() const { return ByteOrder(TAO_BYTE_ORDER); } + word32 getBlockSize() const { return BLOCK_SIZE; } + word32 getDigestSize() const { return DIGEST_SIZE; } + word32 getPadSize() const { return PAD_SIZE; } + + void Init(); + + SHA224(const SHA224&); + SHA224& operator= (const SHA224&); + + void Swap(SHA224&); +private: + void Transform(); +}; + + +#ifdef WORD64_AVAILABLE + +// SHA-512 digest +class SHA512 : public HASH64withTransform { +public: + enum { BLOCK_SIZE = 128, DIGEST_SIZE = 64, PAD_SIZE = 112, + TAO_BYTE_ORDER = BigEndianOrder}; // in Bytes + SHA512() : HASH64withTransform(DIGEST_SIZE / sizeof(word64), BLOCK_SIZE) + { Init(); } + ByteOrder getByteOrder() const { return ByteOrder(TAO_BYTE_ORDER); } + word32 getBlockSize() const { return BLOCK_SIZE; } + word32 getDigestSize() const { return DIGEST_SIZE; } + word32 getPadSize() const { return PAD_SIZE; } + + void Init(); + + SHA512(const SHA512&); + SHA512& operator= (const SHA512&); + + void Swap(SHA512&); +private: + void Transform(); +}; + + +// SHA-384 digest +class SHA384 : public HASH64withTransform { +public: + enum { BLOCK_SIZE = 128, DIGEST_SIZE = 48, PAD_SIZE = 112, + TAO_BYTE_ORDER = BigEndianOrder}; // in Bytes + SHA384() : HASH64withTransform(SHA512::DIGEST_SIZE/ sizeof(word64), + BLOCK_SIZE) + { Init(); } + ByteOrder getByteOrder() const { return ByteOrder(TAO_BYTE_ORDER); } + word32 getBlockSize() const { return BLOCK_SIZE; } + word32 getDigestSize() const { return DIGEST_SIZE; } + word32 getPadSize() const { return PAD_SIZE; } + + void Init(); + + SHA384(const SHA384&); + SHA384& operator= (const SHA384&); + + void Swap(SHA384&); +private: + void Transform(); +}; + +#endif // WORD64_AVAILABLE + + } // namespace diff --git a/extra/yassl/taocrypt/include/type_traits.hpp b/extra/yassl/taocrypt/include/type_traits.hpp index ce21a2eaa63..0dd5e4e5c50 100644 --- a/extra/yassl/taocrypt/include/type_traits.hpp +++ b/extra/yassl/taocrypt/include/type_traits.hpp @@ -62,11 +62,7 @@ MK_FUNDAMENTAL_TYPE(unsigned long) MK_FUNDAMENTAL_TYPE(float) MK_FUNDAMENTAL_TYPE( double) - -#ifdef LONG_DOUBLE_IS_DISTINCT_TYPE -// Don't define by default as this gives warnings on power mac - MK_FUNDAMENTAL_TYPE(long double) -#endif +MK_FUNDAMENTAL_TYPE(long double) #if defined(WORD64_AVAILABLE) && defined(WORD64_IS_DISTINCT_TYPE) MK_FUNDAMENTAL_TYPE(word64) diff --git a/extra/yassl/taocrypt/include/types.hpp b/extra/yassl/taocrypt/include/types.hpp index c817572d265..3efdcdfbccb 100644 --- a/extra/yassl/taocrypt/include/types.hpp +++ b/extra/yassl/taocrypt/include/types.hpp @@ -46,13 +46,16 @@ typedef unsigned int word32; #define WORD64_AVAILABLE #define WORD64_IS_DISTINCT_TYPE typedef unsigned __int64 word64; + #define W64LIT(x) x##ui64 #elif SIZEOF_LONG == 8 #define WORD64_AVAILABLE typedef unsigned long word64; + #define W64LIT(x) x##LL #elif SIZEOF_LONG_LONG == 8 #define WORD64_AVAILABLE #define WORD64_IS_DISTINCT_TYPE typedef unsigned long long word64; + #define W64LIT(x) x##LL #endif diff --git a/extra/yassl/taocrypt/mySTL/list.hpp b/extra/yassl/taocrypt/mySTL/list.hpp index 98a4589a354..6a081cba5ad 100644 --- a/extra/yassl/taocrypt/mySTL/list.hpp +++ b/extra/yassl/taocrypt/mySTL/list.hpp @@ -231,7 +231,7 @@ void list<T>::push_front(T t) template<typename T> void list<T>::pop_front() { - node* local_front = head_; + node* front = head_; if (head_ == 0) return; @@ -241,8 +241,8 @@ void list<T>::pop_front() head_ = head_->next_; head_->prev_ = 0; } - destroy(local_front); - FreeMemory(local_front); + destroy(front); + FreeMemory(front); --sz_; } @@ -303,13 +303,13 @@ T list<T>::back() const template<typename T> typename list<T>::node* list<T>::look_up(T t) { - node* local_list = head_; + node* list = head_; - if (local_list == 0) return 0; + if (list == 0) return 0; - for (; local_list; local_list = local_list->next_) - if (local_list->value_ == t) - return local_list; + for (; list; list = list->next_) + if (list->value_ == t) + return list; return 0; } diff --git a/extra/yassl/taocrypt/src/aes.cpp b/extra/yassl/taocrypt/src/aes.cpp index 4f87bf3778a..b2b42d3dcf0 100644 --- a/extra/yassl/taocrypt/src/aes.cpp +++ b/extra/yassl/taocrypt/src/aes.cpp @@ -90,14 +90,13 @@ void AES::SetKey(const byte* userKey, word32 keylen, CipherDir /*dummy*/) rounds_ = keylen/4 + 6; word32 temp, *rk = key_; + unsigned int i=0; GetUserKey(BigEndianOrder, rk, keylen/4, userKey, keylen); switch(keylen) { case 16: - { - unsigned int i=0; while (true) { temp = rk[3]; @@ -115,10 +114,8 @@ void AES::SetKey(const byte* userKey, word32 keylen, CipherDir /*dummy*/) rk += 4; } break; - } + case 24: - { - unsigned int i=0; while (true) // for (;;) here triggers a bug in VC60 SP4 w/ Pro Pack { temp = rk[ 5]; @@ -139,10 +136,7 @@ void AES::SetKey(const byte* userKey, word32 keylen, CipherDir /*dummy*/) } break; - } case 32: - { - unsigned int i=0; while (true) { temp = rk[ 7]; @@ -171,7 +165,6 @@ void AES::SetKey(const byte* userKey, word32 keylen, CipherDir /*dummy*/) } break; } - } if (dir_ == DECRYPTION) { diff --git a/extra/yassl/taocrypt/src/algebra.cpp b/extra/yassl/taocrypt/src/algebra.cpp index d797d0d4108..cb597c41552 100644 --- a/extra/yassl/taocrypt/src/algebra.cpp +++ b/extra/yassl/taocrypt/src/algebra.cpp @@ -186,10 +186,10 @@ Integer AbstractGroup::CascadeScalarMultiply(const Element &x, struct WindowSlider { - WindowSlider(const Integer &exp_arg, bool fastNegate_arg, + WindowSlider(const Integer &exp, bool fastNegate, unsigned int windowSizeIn=0) - : exp(exp_arg), windowModulus(Integer::One()), windowSize(windowSizeIn), - windowBegin(0), fastNegate(fastNegate_arg), firstTime(true), + : exp(exp), windowModulus(Integer::One()), windowSize(windowSizeIn), + windowBegin(0), fastNegate(fastNegate), firstTime(true), finished(false) { if (windowSize == 0) diff --git a/extra/yassl/taocrypt/src/asn.cpp b/extra/yassl/taocrypt/src/asn.cpp index 5bc865a4ba7..a06ab658c7b 100644 --- a/extra/yassl/taocrypt/src/asn.cpp +++ b/extra/yassl/taocrypt/src/asn.cpp @@ -737,17 +737,17 @@ void CertDecoder::GetName(NameType nt) email = true; source_.advance(oidSz + 1); - word32 length2 = GetLength(source_); + word32 length = GetLength(source_); if (email) { memcpy(&ptr[idx], "/emailAddress=", 14); idx += 14; - memcpy(&ptr[idx], source_.get_current(), length2); - idx += length2; + memcpy(&ptr[idx], source_.get_current(), length); + idx += length; } - source_.advance(length2); + source_.advance(length); } } ptr[idx++] = 0; diff --git a/extra/yassl/taocrypt/src/hash.cpp b/extra/yassl/taocrypt/src/hash.cpp index 66598177631..c51dc42a909 100644 --- a/extra/yassl/taocrypt/src/hash.cpp +++ b/extra/yassl/taocrypt/src/hash.cpp @@ -108,4 +108,89 @@ void HASHwithTransform::Final(byte* hash) Init(); // reset state } + +#ifdef WORD64_AVAILABLE + +HASH64withTransform::HASH64withTransform(word32 digSz, word32 buffSz) +{ + assert(digSz <= MaxDigestSz); + assert(buffSz <= MaxBufferSz); +} + + +void HASH64withTransform::AddLength(word32 len) +{ + HashLengthType tmp = loLen_; + if ( (loLen_ += len) < tmp) + hiLen_++; // carry low to high + hiLen_ += SafeRightShift<8*sizeof(HashLengthType)>(len); +} + + +// Update digest with data of size len, do in blocks +void HASH64withTransform::Update(const byte* data, word32 len) +{ + // do block size increments + word32 blockSz = getBlockSize(); + byte* local = reinterpret_cast<byte*>(buffer_); + + while (len) { + word32 add = min(len, blockSz - buffLen_); + memcpy(&local[buffLen_], data, add); + + buffLen_ += add; + data += add; + len -= add; + + if (buffLen_ == blockSz) { + ByteReverseIf(buffer_, buffer_, blockSz, getByteOrder()); + Transform(); + AddLength(blockSz); + buffLen_ = 0; + } + } +} + + +// Final process, place digest in hash +void HASH64withTransform::Final(byte* hash) +{ + word32 blockSz = getBlockSize(); + word32 digestSz = getDigestSize(); + word32 padSz = getPadSize(); + ByteOrder order = getByteOrder(); + + AddLength(buffLen_); // before adding pads + HashLengthType preLoLen = GetBitCountLo(); + HashLengthType preHiLen = GetBitCountHi(); + byte* local = reinterpret_cast<byte*>(buffer_); + + local[buffLen_++] = 0x80; // add 1 + + // pad with zeros + if (buffLen_ > padSz) { + memset(&local[buffLen_], 0, blockSz - buffLen_); + buffLen_ += blockSz - buffLen_; + + ByteReverseIf(buffer_, buffer_, blockSz, order); + Transform(); + buffLen_ = 0; + } + memset(&local[buffLen_], 0, padSz - buffLen_); + + ByteReverseIf(buffer_, buffer_, padSz, order); + + buffer_[blockSz / sizeof(word64) - 2] = order ? preHiLen : preLoLen; + buffer_[blockSz / sizeof(word64) - 1] = order ? preLoLen : preHiLen; + + Transform(); + ByteReverseIf(digest_, digest_, digestSz, order); + memcpy(hash, digest_, digestSz); + + Init(); // reset state +} + +#endif // WORD64_AVAILABLE + + } // namespace diff --git a/extra/yassl/taocrypt/src/integer.cpp b/extra/yassl/taocrypt/src/integer.cpp index 84255aa8544..85733b88aa9 100644 --- a/extra/yassl/taocrypt/src/integer.cpp +++ b/extra/yassl/taocrypt/src/integer.cpp @@ -3390,7 +3390,7 @@ void Integer::DivideByPowerOf2(Integer &r, Integer &q, const Integer &a, CopyWords(r.reg_.get_buffer(), a.reg_.get_buffer(), wordCount); SetWords(r.reg_+wordCount, 0, r.reg_.size()-wordCount); if (n % WORD_BITS != 0) - r.reg_[wordCount-1] %= ((word) 1 << (n % WORD_BITS)); + r.reg_[wordCount-1] %= (word(1) << (n % WORD_BITS)); } else { diff --git a/extra/yassl/taocrypt/src/sha.cpp b/extra/yassl/taocrypt/src/sha.cpp index 9713940529a..ef165a342ad 100644 --- a/extra/yassl/taocrypt/src/sha.cpp +++ b/extra/yassl/taocrypt/src/sha.cpp @@ -69,6 +69,77 @@ void SHA::Init() hiLen_ = 0; } +void SHA256::Init() +{ + digest_[0] = 0x6A09E667L; + digest_[1] = 0xBB67AE85L; + digest_[2] = 0x3C6EF372L; + digest_[3] = 0xA54FF53AL; + digest_[4] = 0x510E527FL; + digest_[5] = 0x9B05688CL; + digest_[6] = 0x1F83D9ABL; + digest_[7] = 0x5BE0CD19L; + + buffLen_ = 0; + loLen_ = 0; + hiLen_ = 0; +} + + +void SHA224::Init() +{ + digest_[0] = 0xc1059ed8; + digest_[1] = 0x367cd507; + digest_[2] = 0x3070dd17; + digest_[3] = 0xf70e5939; + digest_[4] = 0xffc00b31; + digest_[5] = 0x68581511; + digest_[6] = 0x64f98fa7; + digest_[7] = 0xbefa4fa4; + + buffLen_ = 0; + loLen_ = 0; + hiLen_ = 0; +} + + +#ifdef WORD64_AVAILABLE + +void SHA512::Init() +{ + digest_[0] = W64LIT(0x6a09e667f3bcc908); + digest_[1] = W64LIT(0xbb67ae8584caa73b); + digest_[2] = W64LIT(0x3c6ef372fe94f82b); + digest_[3] = W64LIT(0xa54ff53a5f1d36f1); + digest_[4] = W64LIT(0x510e527fade682d1); + digest_[5] = W64LIT(0x9b05688c2b3e6c1f); + digest_[6] = W64LIT(0x1f83d9abfb41bd6b); + digest_[7] = W64LIT(0x5be0cd19137e2179); + + buffLen_ = 0; + loLen_ = 0; + hiLen_ = 0; +} + + +void SHA384::Init() +{ + digest_[0] = W64LIT(0xcbbb9d5dc1059ed8); + digest_[1] = W64LIT(0x629a292a367cd507); + digest_[2] = W64LIT(0x9159015a3070dd17); + digest_[3] = W64LIT(0x152fecd8f70e5939); + digest_[4] = W64LIT(0x67332667ffc00b31); + digest_[5] = W64LIT(0x8eb44a8768581511); + digest_[6] = W64LIT(0xdb0c2e0d64f98fa7); + digest_[7] = W64LIT(0x47b5481dbefa4fa4); + + buffLen_ = 0; + loLen_ = 0; + hiLen_ = 0; +} + +#endif // WORD64_AVAILABLE + SHA::SHA(const SHA& that) : HASHwithTransform(DIGEST_SIZE / sizeof(word32), BLOCK_SIZE) @@ -81,6 +152,59 @@ SHA::SHA(const SHA& that) : HASHwithTransform(DIGEST_SIZE / sizeof(word32), memcpy(buffer_, that.buffer_, BLOCK_SIZE); } + +SHA256::SHA256(const SHA256& that) : HASHwithTransform(DIGEST_SIZE / + sizeof(word32), BLOCK_SIZE) +{ + buffLen_ = that.buffLen_; + loLen_ = that.loLen_; + hiLen_ = that.hiLen_; + + memcpy(digest_, that.digest_, DIGEST_SIZE); + memcpy(buffer_, that.buffer_, BLOCK_SIZE); +} + + +SHA224::SHA224(const SHA224& that) : HASHwithTransform(SHA256::DIGEST_SIZE / + sizeof(word32), BLOCK_SIZE) +{ + buffLen_ = that.buffLen_; + loLen_ = that.loLen_; + hiLen_ = that.hiLen_; + + memcpy(digest_, that.digest_, DIGEST_SIZE); + memcpy(buffer_, that.buffer_, BLOCK_SIZE); +} + + +#ifdef WORD64_AVAILABLE + +SHA512::SHA512(const SHA512& that) : HASH64withTransform(DIGEST_SIZE / + sizeof(word64), BLOCK_SIZE) +{ + buffLen_ = that.buffLen_; + loLen_ = that.loLen_; + hiLen_ = that.hiLen_; + + memcpy(digest_, that.digest_, DIGEST_SIZE); + memcpy(buffer_, that.buffer_, BLOCK_SIZE); +} + + +SHA384::SHA384(const SHA384& that) : HASH64withTransform(SHA512::DIGEST_SIZE / + sizeof(word64), BLOCK_SIZE) +{ + buffLen_ = that.buffLen_; + loLen_ = that.loLen_; + hiLen_ = that.hiLen_; + + memcpy(digest_, that.digest_, DIGEST_SIZE); + memcpy(buffer_, that.buffer_, BLOCK_SIZE); +} + +#endif // WORD64_AVAILABLE + + SHA& SHA::operator= (const SHA& that) { SHA tmp(that); @@ -90,6 +214,46 @@ SHA& SHA::operator= (const SHA& that) } +SHA256& SHA256::operator= (const SHA256& that) +{ + SHA256 tmp(that); + Swap(tmp); + + return *this; +} + + +SHA224& SHA224::operator= (const SHA224& that) +{ + SHA224 tmp(that); + Swap(tmp); + + return *this; +} + + +#ifdef WORD64_AVAILABLE + +SHA512& SHA512::operator= (const SHA512& that) +{ + SHA512 tmp(that); + Swap(tmp); + + return *this; +} + + +SHA384& SHA384::operator= (const SHA384& that) +{ + SHA384 tmp(that); + Swap(tmp); + + return *this; +} + +#endif // WORD64_AVAILABLE + + void SHA::Swap(SHA& other) { STL::swap(loLen_, other.loLen_); @@ -101,6 +265,53 @@ void SHA::Swap(SHA& other) } +void SHA256::Swap(SHA256& other) +{ + STL::swap(loLen_, other.loLen_); + STL::swap(hiLen_, other.hiLen_); + STL::swap(buffLen_, other.buffLen_); + + memcpy(digest_, other.digest_, DIGEST_SIZE); + memcpy(buffer_, other.buffer_, BLOCK_SIZE); +} + + +void SHA224::Swap(SHA224& other) +{ + STL::swap(loLen_, other.loLen_); + STL::swap(hiLen_, other.hiLen_); + STL::swap(buffLen_, other.buffLen_); + + memcpy(digest_, other.digest_, DIGEST_SIZE); + memcpy(buffer_, other.buffer_, BLOCK_SIZE); +} + + +#ifdef WORD64_AVAILABLE + +void SHA512::Swap(SHA512& other) +{ + STL::swap(loLen_, other.loLen_); + STL::swap(hiLen_, other.hiLen_); + STL::swap(buffLen_, other.buffLen_); + + memcpy(digest_, other.digest_, DIGEST_SIZE); + memcpy(buffer_, other.buffer_, BLOCK_SIZE); +} + + +void SHA384::Swap(SHA384& other) +{ + STL::swap(loLen_, other.loLen_); + STL::swap(hiLen_, other.hiLen_); + STL::swap(buffLen_, other.buffLen_); + + memcpy(digest_, other.digest_, DIGEST_SIZE); + memcpy(buffer_, other.buffer_, BLOCK_SIZE); +} + +#endif // WORD64_AVIALABLE + #ifdef DO_SHA_ASM @@ -203,6 +414,205 @@ void SHA::Transform() } +#define blk2(i) (W[i&15]+=s1(W[(i-2)&15])+W[(i-7)&15]+s0(W[(i-15)&15])) + +#define Ch(x,y,z) (z^(x&(y^z))) +#define Maj(x,y,z) ((x&y)|(z&(x|y))) + +#define a(i) T[(0-i)&7] +#define b(i) T[(1-i)&7] +#define c(i) T[(2-i)&7] +#define d(i) T[(3-i)&7] +#define e(i) T[(4-i)&7] +#define f(i) T[(5-i)&7] +#define g(i) T[(6-i)&7] +#define h(i) T[(7-i)&7] + +#define R(i) h(i)+=S1(e(i))+Ch(e(i),f(i),g(i))+K[i+j]+(j?blk2(i):blk0(i));\ + d(i)+=h(i);h(i)+=S0(a(i))+Maj(a(i),b(i),c(i)) + +// for SHA256 +#define S0(x) (rotrFixed(x,2)^rotrFixed(x,13)^rotrFixed(x,22)) +#define S1(x) (rotrFixed(x,6)^rotrFixed(x,11)^rotrFixed(x,25)) +#define s0(x) (rotrFixed(x,7)^rotrFixed(x,18)^(x>>3)) +#define s1(x) (rotrFixed(x,17)^rotrFixed(x,19)^(x>>10)) + + +static const word32 K256[64] = { + 0x428a2f98, 0x71374491, 0xb5c0fbcf, 0xe9b5dba5, + 0x3956c25b, 0x59f111f1, 0x923f82a4, 0xab1c5ed5, + 0xd807aa98, 0x12835b01, 0x243185be, 0x550c7dc3, + 0x72be5d74, 0x80deb1fe, 0x9bdc06a7, 0xc19bf174, + 0xe49b69c1, 0xefbe4786, 0x0fc19dc6, 0x240ca1cc, + 0x2de92c6f, 0x4a7484aa, 0x5cb0a9dc, 0x76f988da, + 0x983e5152, 0xa831c66d, 0xb00327c8, 0xbf597fc7, + 0xc6e00bf3, 0xd5a79147, 0x06ca6351, 0x14292967, + 0x27b70a85, 0x2e1b2138, 0x4d2c6dfc, 0x53380d13, + 0x650a7354, 0x766a0abb, 0x81c2c92e, 0x92722c85, + 0xa2bfe8a1, 0xa81a664b, 0xc24b8b70, 0xc76c51a3, + 0xd192e819, 0xd6990624, 0xf40e3585, 0x106aa070, + 0x19a4c116, 0x1e376c08, 0x2748774c, 0x34b0bcb5, + 0x391c0cb3, 0x4ed8aa4a, 0x5b9cca4f, 0x682e6ff3, + 0x748f82ee, 0x78a5636f, 0x84c87814, 0x8cc70208, + 0x90befffa, 0xa4506ceb, 0xbef9a3f7, 0xc67178f2 +}; + + +static void Transform256(word32* digest_, word32* buffer_) +{ + const word32* K = K256; + + word32 W[16]; + word32 T[8]; + + // Copy digest to working vars + memcpy(T, digest_, sizeof(T)); + + // 64 operations, partially loop unrolled + for (unsigned int j = 0; j < 64; j += 16) { + R( 0); R( 1); R( 2); R( 3); + R( 4); R( 5); R( 6); R( 7); + R( 8); R( 9); R(10); R(11); + R(12); R(13); R(14); R(15); + } + + // Add the working vars back into digest + digest_[0] += a(0); + digest_[1] += b(0); + digest_[2] += c(0); + digest_[3] += d(0); + digest_[4] += e(0); + digest_[5] += f(0); + digest_[6] += g(0); + digest_[7] += h(0); + + // Wipe variables + memset(W, 0, sizeof(W)); + memset(T, 0, sizeof(T)); +} + + +// undef for 256 +#undef S0 +#undef S1 +#undef s0 +#undef s1 + + +void SHA256::Transform() +{ + Transform256(digest_, buffer_); +} + + +void SHA224::Transform() +{ + Transform256(digest_, buffer_); +} + + +#ifdef WORD64_AVAILABLE + +static const word64 K512[80] = { + W64LIT(0x428a2f98d728ae22), W64LIT(0x7137449123ef65cd), + W64LIT(0xb5c0fbcfec4d3b2f), W64LIT(0xe9b5dba58189dbbc), + W64LIT(0x3956c25bf348b538), W64LIT(0x59f111f1b605d019), + W64LIT(0x923f82a4af194f9b), W64LIT(0xab1c5ed5da6d8118), + W64LIT(0xd807aa98a3030242), W64LIT(0x12835b0145706fbe), + W64LIT(0x243185be4ee4b28c), W64LIT(0x550c7dc3d5ffb4e2), + W64LIT(0x72be5d74f27b896f), W64LIT(0x80deb1fe3b1696b1), + W64LIT(0x9bdc06a725c71235), W64LIT(0xc19bf174cf692694), + W64LIT(0xe49b69c19ef14ad2), W64LIT(0xefbe4786384f25e3), + W64LIT(0x0fc19dc68b8cd5b5), W64LIT(0x240ca1cc77ac9c65), + W64LIT(0x2de92c6f592b0275), W64LIT(0x4a7484aa6ea6e483), + W64LIT(0x5cb0a9dcbd41fbd4), W64LIT(0x76f988da831153b5), + W64LIT(0x983e5152ee66dfab), W64LIT(0xa831c66d2db43210), + W64LIT(0xb00327c898fb213f), W64LIT(0xbf597fc7beef0ee4), + W64LIT(0xc6e00bf33da88fc2), W64LIT(0xd5a79147930aa725), + W64LIT(0x06ca6351e003826f), W64LIT(0x142929670a0e6e70), + W64LIT(0x27b70a8546d22ffc), W64LIT(0x2e1b21385c26c926), + W64LIT(0x4d2c6dfc5ac42aed), W64LIT(0x53380d139d95b3df), + W64LIT(0x650a73548baf63de), W64LIT(0x766a0abb3c77b2a8), + W64LIT(0x81c2c92e47edaee6), W64LIT(0x92722c851482353b), + W64LIT(0xa2bfe8a14cf10364), W64LIT(0xa81a664bbc423001), + W64LIT(0xc24b8b70d0f89791), W64LIT(0xc76c51a30654be30), + W64LIT(0xd192e819d6ef5218), W64LIT(0xd69906245565a910), + W64LIT(0xf40e35855771202a), W64LIT(0x106aa07032bbd1b8), + W64LIT(0x19a4c116b8d2d0c8), W64LIT(0x1e376c085141ab53), + W64LIT(0x2748774cdf8eeb99), W64LIT(0x34b0bcb5e19b48a8), + W64LIT(0x391c0cb3c5c95a63), W64LIT(0x4ed8aa4ae3418acb), + W64LIT(0x5b9cca4f7763e373), W64LIT(0x682e6ff3d6b2b8a3), + W64LIT(0x748f82ee5defb2fc), W64LIT(0x78a5636f43172f60), + W64LIT(0x84c87814a1f0ab72), W64LIT(0x8cc702081a6439ec), + W64LIT(0x90befffa23631e28), W64LIT(0xa4506cebde82bde9), + W64LIT(0xbef9a3f7b2c67915), W64LIT(0xc67178f2e372532b), + W64LIT(0xca273eceea26619c), W64LIT(0xd186b8c721c0c207), + W64LIT(0xeada7dd6cde0eb1e), W64LIT(0xf57d4f7fee6ed178), + W64LIT(0x06f067aa72176fba), W64LIT(0x0a637dc5a2c898a6), + W64LIT(0x113f9804bef90dae), W64LIT(0x1b710b35131c471b), + W64LIT(0x28db77f523047d84), W64LIT(0x32caab7b40c72493), + W64LIT(0x3c9ebe0a15c9bebc), W64LIT(0x431d67c49c100d4c), + W64LIT(0x4cc5d4becb3e42b6), W64LIT(0x597f299cfc657e2a), + W64LIT(0x5fcb6fab3ad6faec), W64LIT(0x6c44198c4a475817) +}; + + +// for SHA512 +#define S0(x) (rotrFixed(x,28)^rotrFixed(x,34)^rotrFixed(x,39)) +#define S1(x) (rotrFixed(x,14)^rotrFixed(x,18)^rotrFixed(x,41)) +#define s0(x) (rotrFixed(x,1)^rotrFixed(x,8)^(x>>7)) +#define s1(x) (rotrFixed(x,19)^rotrFixed(x,61)^(x>>6)) + + +static void Transform512(word64* digest_, word64* buffer_) +{ + const word64* K = K512; + + word64 W[16]; + word64 T[8]; + + // Copy digest to working vars + memcpy(T, digest_, sizeof(T)); + + // 64 operations, partially loop unrolled + for (unsigned int j = 0; j < 80; j += 16) { + R( 0); R( 1); R( 2); R( 3); + R( 4); R( 5); R( 6); R( 7); + R( 8); R( 9); R(10); R(11); + R(12); R(13); R(14); R(15); + } + + // Add the working vars back into digest + + digest_[0] += a(0); + digest_[1] += b(0); + digest_[2] += c(0); + digest_[3] += d(0); + digest_[4] += e(0); + digest_[5] += f(0); + digest_[6] += g(0); + digest_[7] += h(0); + + // Wipe variables + memset(W, 0, sizeof(W)); + memset(T, 0, sizeof(T)); +} + + +void SHA512::Transform() +{ + Transform512(digest_, buffer_); +} + + +void SHA384::Transform() +{ + Transform512(digest_, buffer_); +} + +#endif // WORD64_AVIALABLE + + #ifdef DO_SHA_ASM // f1(x,y,z) (z^(x &(y^z))) diff --git a/extra/yassl/taocrypt/test/test.cpp b/extra/yassl/taocrypt/test/test.cpp index c0d7aa50f18..0af278404ab 100644 --- a/extra/yassl/taocrypt/test/test.cpp +++ b/extra/yassl/taocrypt/test/test.cpp @@ -29,6 +29,12 @@ using TaoCrypt::byte; using TaoCrypt::word32; using TaoCrypt::SHA; +using TaoCrypt::SHA256; +using TaoCrypt::SHA224; +#ifdef WORD64_AVAILABLE + using TaoCrypt::SHA512; + using TaoCrypt::SHA384; +#endif using TaoCrypt::MD5; using TaoCrypt::MD2; using TaoCrypt::MD4; @@ -88,8 +94,13 @@ struct testVector { output_((byte*)out), inLen_(strlen(in)), outLen_(strlen(out)) {} }; -void file_test(int, char**); int sha_test(); +int sha256_test(); +#ifdef WORD64_AVAILABLE + int sha512_test(); + int sha384_test(); +#endif +int sha224_test(); int md5_test(); int md2_test(); int md4_test(); @@ -139,20 +150,20 @@ const byte msgTmp[] = { // "now is the time for all " w/o trailing 0 0x66,0x6f,0x72,0x20,0x61,0x6c,0x6c,0x20 }; -byte* global_msg = 0; // for block cipher input -byte* global_plain = 0; // for cipher decrypt comparison -byte* global_cipher = 0; // block output +byte* msg = 0; // for block cipher input +byte* plain = 0; // for cipher decrypt comparison +byte* cipher = 0; // block output void taocrypt_test(void* args) { ((func_args*)args)->return_code = -1; // error state - global_msg = NEW_TC byte[24]; - global_plain = NEW_TC byte[24]; - global_cipher = NEW_TC byte[24]; + msg = NEW_TC byte[24]; + plain = NEW_TC byte[24]; + cipher = NEW_TC byte[24]; - memcpy(global_msg, msgTmp, 24); + memcpy(msg, msgTmp, 24); int ret = 0; if ( (ret = sha_test()) ) @@ -160,6 +171,30 @@ void taocrypt_test(void* args) else printf( "SHA test passed!\n"); + if ( (ret = sha256_test()) ) + err_sys("SHA-256 test failed!\n", ret); + else + printf( "SHA-256 test passed!\n"); + + if ( (ret = sha224_test()) ) + err_sys("SHA-224 test failed!\n", ret); + else + printf( "SHA-224 test passed!\n"); + +#ifdef WORD64_AVAILABLE + + if ( (ret = sha512_test()) ) + err_sys("SHA-512 test failed!\n", ret); + else + printf( "SHA-512 test passed!\n"); + + if ( (ret = sha384_test()) ) + err_sys("SHA-384 test failed!\n", ret); + else + printf( "SHA-384 test passed!\n"); + +#endif + if ( (ret = md5_test()) ) err_sys("MD5 test failed!\n", ret); else @@ -237,9 +272,9 @@ void taocrypt_test(void* args) printf( "PKCS12 test passed!\n"); */ - tcArrayDelete(global_cipher); - tcArrayDelete(global_plain); - tcArrayDelete(global_msg); + tcArrayDelete(cipher); + tcArrayDelete(plain); + tcArrayDelete(msg); ((func_args*)args)->return_code = ret; } @@ -264,7 +299,7 @@ void taocrypt_test(void* args) #endif // NO_MAIN_DRIVER -void file_test(char* file, byte* check) +void file_test(const char* file, byte* check) { FILE* f; int i(0); @@ -328,6 +363,136 @@ int sha_test() } +int sha256_test() +{ + SHA256 sha; + byte hash[SHA256::DIGEST_SIZE]; + + testVector test_sha[] = + { + testVector("abc", + "\xBA\x78\x16\xBF\x8F\x01\xCF\xEA\x41\x41\x40\xDE\x5D\xAE\x22" + "\x23\xB0\x03\x61\xA3\x96\x17\x7A\x9C\xB4\x10\xFF\x61\xF2\x00" + "\x15\xAD"), + testVector("abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq", + "\x24\x8D\x6A\x61\xD2\x06\x38\xB8\xE5\xC0\x26\x93\x0C\x3E\x60" + "\x39\xA3\x3C\xE4\x59\x64\xFF\x21\x67\xF6\xEC\xED\xD4\x19\xDB" + "\x06\xC1") + }; + + int times( sizeof(test_sha) / sizeof(testVector) ); + for (int i = 0; i < times; ++i) { + sha.Update(test_sha[i].input_, test_sha[i].inLen_); + sha.Final(hash); + + if (memcmp(hash, test_sha[i].output_, SHA256::DIGEST_SIZE) != 0) + return -1 - i; + } + + return 0; +} + + +#ifdef WORD64_AVAILABLE + +int sha512_test() +{ + SHA512 sha; + byte hash[SHA512::DIGEST_SIZE]; + + testVector test_sha[] = + { + testVector("abc", + "\xdd\xaf\x35\xa1\x93\x61\x7a\xba\xcc\x41\x73\x49\xae\x20\x41" + "\x31\x12\xe6\xfa\x4e\x89\xa9\x7e\xa2\x0a\x9e\xee\xe6\x4b\x55" + "\xd3\x9a\x21\x92\x99\x2a\x27\x4f\xc1\xa8\x36\xba\x3c\x23\xa3" + "\xfe\xeb\xbd\x45\x4d\x44\x23\x64\x3c\xe8\x0e\x2a\x9a\xc9\x4f" + "\xa5\x4c\xa4\x9f"), + testVector("abcdefghbcdefghicdefghijdefghijkefghijklfghijklmghijklmnhi" + "jklmnoijklmnopjklmnopqklmnopqrlmnopqrsmnopqrstnopqrstu", + "\x8e\x95\x9b\x75\xda\xe3\x13\xda\x8c\xf4\xf7\x28\x14\xfc\x14" + "\x3f\x8f\x77\x79\xc6\xeb\x9f\x7f\xa1\x72\x99\xae\xad\xb6\x88" + "\x90\x18\x50\x1d\x28\x9e\x49\x00\xf7\xe4\x33\x1b\x99\xde\xc4" + "\xb5\x43\x3a\xc7\xd3\x29\xee\xb6\xdd\x26\x54\x5e\x96\xe5\x5b" + "\x87\x4b\xe9\x09") + }; + + int times( sizeof(test_sha) / sizeof(testVector) ); + for (int i = 0; i < times; ++i) { + sha.Update(test_sha[i].input_, test_sha[i].inLen_); + sha.Final(hash); + + if (memcmp(hash, test_sha[i].output_, SHA512::DIGEST_SIZE) != 0) + return -1 - i; + } + + return 0; +} + + +int sha384_test() +{ + SHA384 sha; + byte hash[SHA384::DIGEST_SIZE]; + + testVector test_sha[] = + { + testVector("abc", + "\xcb\x00\x75\x3f\x45\xa3\x5e\x8b\xb5\xa0\x3d\x69\x9a\xc6\x50" + "\x07\x27\x2c\x32\xab\x0e\xde\xd1\x63\x1a\x8b\x60\x5a\x43\xff" + "\x5b\xed\x80\x86\x07\x2b\xa1\xe7\xcc\x23\x58\xba\xec\xa1\x34" + "\xc8\x25\xa7"), + testVector("abcdefghbcdefghicdefghijdefghijkefghijklfghijklmghijklmnhi" + "jklmnoijklmnopjklmnopqklmnopqrlmnopqrsmnopqrstnopqrstu", + "\x09\x33\x0c\x33\xf7\x11\x47\xe8\x3d\x19\x2f\xc7\x82\xcd\x1b" + "\x47\x53\x11\x1b\x17\x3b\x3b\x05\xd2\x2f\xa0\x80\x86\xe3\xb0" + "\xf7\x12\xfc\xc7\xc7\x1a\x55\x7e\x2d\xb9\x66\xc3\xe9\xfa\x91" + "\x74\x60\x39") + }; + + int times( sizeof(test_sha) / sizeof(testVector) ); + for (int i = 0; i < times; ++i) { + sha.Update(test_sha[i].input_, test_sha[i].inLen_); + sha.Final(hash); + + if (memcmp(hash, test_sha[i].output_, SHA384::DIGEST_SIZE) != 0) + return -1 - i; + } + + return 0; +} + +#endif // WORD64_AVAILABLE + + +int sha224_test() +{ + SHA224 sha; + byte hash[SHA224::DIGEST_SIZE]; + + testVector test_sha[] = + { + testVector("abc", + "\x23\x09\x7d\x22\x34\x05\xd8\x22\x86\x42\xa4\x77\xbd\xa2\x55" + "\xb3\x2a\xad\xbc\xe4\xbd\xa0\xb3\xf7\xe3\x6c\x9d\xa7"), + testVector("abcdbcdecdefdefgefghfghighijhijkijkljklmklmnlmnomnopnopq", + "\x75\x38\x8b\x16\x51\x27\x76\xcc\x5d\xba\x5d\xa1\xfd\x89\x01" + "\x50\xb0\xc6\x45\x5c\xb4\xf5\x8b\x19\x52\x52\x25\x25") + }; + + int times( sizeof(test_sha) / sizeof(testVector) ); + for (int i = 0; i < times; ++i) { + sha.Update(test_sha[i].input_, test_sha[i].inLen_); + sha.Final(hash); + + if (memcmp(hash, test_sha[i].output_, SHA224::DIGEST_SIZE) != 0) + return -1 - i; + } + + return 0; +} + + int md5_test() { MD5 md5; @@ -606,11 +771,11 @@ int des_test() const byte iv[] = { 0x12,0x34,0x56,0x78,0x90,0xab,0xcd,0xef }; enc.SetKey(key, sizeof(key)); - enc.Process(global_cipher, global_msg, sz); + enc.Process(cipher, msg, sz); dec.SetKey(key, sizeof(key)); - dec.Process(global_plain, global_cipher, sz); + dec.Process(plain, cipher, sz); - if (memcmp(global_plain, global_msg, sz)) + if (memcmp(plain, msg, sz)) return -50; const byte verify1[] = @@ -620,7 +785,7 @@ int des_test() 0x89,0x3d,0x51,0xec,0x4b,0x56,0x3b,0x53 }; - if (memcmp(global_cipher, verify1, sz)) + if (memcmp(cipher, verify1, sz)) return -51; // CBC mode @@ -628,11 +793,11 @@ int des_test() DES_CBC_Decryption dec2; enc2.SetKey(key, sizeof(key), iv); - enc2.Process(global_cipher, global_msg, sz); + enc2.Process(cipher, msg, sz); dec2.SetKey(key, sizeof(key), iv); - dec2.Process(global_plain, global_cipher, sz); + dec2.Process(plain, cipher, sz); - if (memcmp(global_plain, global_msg, sz)) + if (memcmp(plain, msg, sz)) return -52; const byte verify2[] = @@ -642,7 +807,7 @@ int des_test() 0x15,0x85,0xb3,0x22,0x4b,0x86,0x2b,0x4b }; - if (memcmp(global_cipher, verify2, sz)) + if (memcmp(cipher, verify2, sz)) return -53; // EDE3 CBC mode @@ -664,11 +829,11 @@ int des_test() }; enc3.SetKey(key3, sizeof(key3), iv3); - enc3.Process(global_cipher, global_msg, sz); + enc3.Process(cipher, msg, sz); dec3.SetKey(key3, sizeof(key3), iv3); - dec3.Process(global_plain, global_cipher, sz); + dec3.Process(plain, cipher, sz); - if (memcmp(global_plain, global_msg, sz)) + if (memcmp(plain, msg, sz)) return -54; const byte verify3[] = @@ -678,7 +843,7 @@ int des_test() 0x18,0xbc,0xbb,0x6d,0xd2,0xb1,0x16,0xda }; - if (memcmp(global_cipher, verify3, sz)) + if (memcmp(cipher, verify3, sz)) return -55; return 0; @@ -697,10 +862,10 @@ int aes_test() enc.SetKey(key, bs, iv); dec.SetKey(key, bs, iv); - enc.Process(global_cipher, global_msg, bs); - dec.Process(global_plain, global_cipher, bs); + enc.Process(cipher, msg, bs); + dec.Process(plain, cipher, bs); - if (memcmp(global_plain, global_msg, bs)) + if (memcmp(plain, msg, bs)) return -60; const byte verify[] = @@ -709,7 +874,7 @@ int aes_test() 0x2c,0xcc,0x9d,0x46,0x77,0xa2,0x33,0xcb }; - if (memcmp(global_cipher, verify, bs)) + if (memcmp(cipher, verify, bs)) return -61; AES_ECB_Encryption enc2; @@ -718,10 +883,10 @@ int aes_test() enc2.SetKey(key, bs, iv); dec2.SetKey(key, bs, iv); - enc2.Process(global_cipher, global_msg, bs); - dec2.Process(global_plain, global_cipher, bs); + enc2.Process(cipher, msg, bs); + dec2.Process(plain, cipher, bs); - if (memcmp(global_plain, global_msg, bs)) + if (memcmp(plain, msg, bs)) return -62; const byte verify2[] = @@ -730,7 +895,7 @@ int aes_test() 0xc8,0x8c,0x33,0x3b,0xb5,0x8f,0x85,0xd1 }; - if (memcmp(global_cipher, verify2, bs)) + if (memcmp(cipher, verify2, bs)) return -63; return 0; @@ -749,10 +914,10 @@ int twofish_test() enc.SetKey(key, bs, iv); dec.SetKey(key, bs, iv); - enc.Process(global_cipher, global_msg, bs); - dec.Process(global_plain, global_cipher, bs); + enc.Process(cipher, msg, bs); + dec.Process(plain, cipher, bs); - if (memcmp(global_plain, global_msg, bs)) + if (memcmp(plain, msg, bs)) return -60; const byte verify[] = @@ -761,7 +926,7 @@ int twofish_test() 0x21,0x03,0x58,0x79,0x5F,0x02,0x27,0x2C }; - if (memcmp(global_cipher, verify, bs)) + if (memcmp(cipher, verify, bs)) return -61; Twofish_ECB_Encryption enc2; @@ -770,10 +935,10 @@ int twofish_test() enc2.SetKey(key, bs, iv); dec2.SetKey(key, bs, iv); - enc2.Process(global_cipher, global_msg, bs); - dec2.Process(global_plain, global_cipher, bs); + enc2.Process(cipher, msg, bs); + dec2.Process(plain, cipher, bs); - if (memcmp(global_plain, global_msg, bs)) + if (memcmp(plain, msg, bs)) return -62; const byte verify2[] = @@ -782,7 +947,7 @@ int twofish_test() 0xC4,0xCD,0x6B,0x91,0x14,0xC5,0x3A,0x09 }; - if (memcmp(global_cipher, verify2, bs)) + if (memcmp(cipher, verify2, bs)) return -63; return 0; @@ -801,10 +966,10 @@ int blowfish_test() enc.SetKey(key, 16, iv); dec.SetKey(key, 16, iv); - enc.Process(global_cipher, global_msg, bs * 2); - dec.Process(global_plain, global_cipher, bs * 2); + enc.Process(cipher, msg, bs * 2); + dec.Process(plain, cipher, bs * 2); - if (memcmp(global_plain, global_msg, bs)) + if (memcmp(plain, msg, bs)) return -60; const byte verify[] = @@ -813,7 +978,7 @@ int blowfish_test() 0xBC,0xD9,0x08,0xC4,0x94,0x6C,0x89,0xA3 }; - if (memcmp(global_cipher, verify, bs)) + if (memcmp(cipher, verify, bs)) return -61; Blowfish_ECB_Encryption enc2; @@ -822,10 +987,10 @@ int blowfish_test() enc2.SetKey(key, 16, iv); dec2.SetKey(key, 16, iv); - enc2.Process(global_cipher, global_msg, bs * 2); - dec2.Process(global_plain, global_cipher, bs * 2); + enc2.Process(cipher, msg, bs * 2); + dec2.Process(plain, cipher, bs * 2); - if (memcmp(global_plain, global_msg, bs)) + if (memcmp(plain, msg, bs)) return -62; const byte verify2[] = @@ -834,7 +999,7 @@ int blowfish_test() 0x8F,0xCE,0x39,0x32,0xDE,0xD7,0xBC,0x5B }; - if (memcmp(global_cipher, verify2, bs)) + if (memcmp(cipher, verify2, bs)) return -63; return 0; diff --git a/extra/yassl/testsuite/testsuite.cpp b/extra/yassl/testsuite/testsuite.cpp index 06e75153341..3cd832ebb03 100644 --- a/extra/yassl/testsuite/testsuite.cpp +++ b/extra/yassl/testsuite/testsuite.cpp @@ -7,7 +7,7 @@ typedef unsigned char byte; void taocrypt_test(void*); -void file_test(char*, byte*); +void file_test(const char*, byte*); void client_test(void*); void echoclient_test(void*); @@ -86,8 +86,8 @@ int main(int argc, char** argv) // input output compare byte input[TaoCrypt::MD5::DIGEST_SIZE]; byte output[TaoCrypt::MD5::DIGEST_SIZE]; - file_test((char*) "input", input); - file_test((char*) "output", output); + file_test("input", input); + file_test("output", output); assert(memcmp(input, output, sizeof(input)) == 0); printf("\nAll tests passed!\n"); @@ -141,17 +141,16 @@ int test_openSSL_des() /* test des encrypt/decrypt */ char data[] = "this is my data "; int dataSz = strlen(data); - DES_key_schedule local_key[3]; + DES_key_schedule key[3]; byte iv[8]; EVP_BytesToKey(EVP_des_ede3_cbc(), EVP_md5(), NULL, (byte*)data, dataSz, 1, - (byte*)local_key, iv); + (byte*)key, iv); byte cipher[16]; - DES_ede3_cbc_encrypt((byte*)data, cipher, dataSz, - &local_key[0], &local_key[1], - &local_key[2], &iv, true); + DES_ede3_cbc_encrypt((byte*)data, cipher, dataSz, &key[0], &key[1], + &key[2], &iv, true); byte plain[16]; - DES_ede3_cbc_encrypt(cipher, plain, 16, &local_key[0], &local_key[1], - &local_key[2], &iv, false); + DES_ede3_cbc_encrypt(cipher, plain, 16, &key[0], &key[1], &key[2], + &iv, false); return 0; } diff --git a/include/my_base.h b/include/my_base.h index f832d9aea70..d07a4de8e6a 100644 --- a/include/my_base.h +++ b/include/my_base.h @@ -160,7 +160,15 @@ enum ha_extra_function { Off by default. */ HA_EXTRA_WRITE_CAN_REPLACE, - HA_EXTRA_WRITE_CANNOT_REPLACE + HA_EXTRA_WRITE_CANNOT_REPLACE, + /* + Inform handler that delete_row()/update_row() cannot batch deletes/updates + and should perform them immediately. This may be needed when table has + AFTER DELETE/UPDATE triggers which access to subject table. + These flags are reset by the handler::extra(HA_EXTRA_RESET) call. + */ + HA_EXTRA_DELETE_CANNOT_BATCH, + HA_EXTRA_UPDATE_CANNOT_BATCH }; /* The following is parameter to ha_panic() */ diff --git a/include/violite.h b/include/violite.h index 4122e581a0f..63388c170c9 100644 --- a/include/violite.h +++ b/include/violite.h @@ -102,6 +102,9 @@ void vio_timeout(Vio *vio,uint which, uint timeout); #define HEADER_DES_LOCL_H dummy_something #define YASSL_MYSQL_COMPATIBLE #define YASSL_PREFIX +/* Set yaSSL to use same type as MySQL do for socket handles */ +typedef my_socket YASSL_SOCKET_T; +#define YASSL_SOCKET_T_DEFINED #include <openssl/ssl.h> #include <openssl/err.h> diff --git a/innobase/dict/dict0dict.c b/innobase/dict/dict0dict.c index df48a8a4b5a..96c822857df 100644 --- a/innobase/dict/dict0dict.c +++ b/innobase/dict/dict0dict.c @@ -628,7 +628,8 @@ dict_table_get_on_id( CREATE, for example, we already have the mutex! */ #ifdef UNIV_SYNC_DEBUG - ut_ad(mutex_own(&(dict_sys->mutex))); + ut_ad(mutex_own(&(dict_sys->mutex)) + || trx->dict_operation_lock_mode == RW_X_LATCH); #endif /* UNIV_SYNC_DEBUG */ return(dict_table_get_on_id_low(table_id, trx)); @@ -2139,9 +2140,12 @@ dict_foreign_find_index( ulint n_cols, /* in: number of columns */ dict_index_t* types_idx, /* in: NULL or an index to whose types the column types must match */ - ibool check_charsets) /* in: whether to check charsets. + ibool check_charsets, /* in: whether to check charsets. only has an effect if types_idx != NULL. */ + ulint check_null) + /* in: nonzero if none of the columns must + be declared NOT NULL */ { #ifndef UNIV_HOTBACKUP dict_index_t* index; @@ -2154,10 +2158,11 @@ dict_foreign_find_index( if (dict_index_get_n_fields(index) >= n_cols) { for (i = 0; i < n_cols; i++) { - col_name = dict_index_get_nth_field(index, i) - ->col->name; - if (dict_index_get_nth_field(index, i) - ->prefix_len != 0) { + dict_field_t* field + = dict_index_get_nth_field(index, i); + + col_name = field->col->name; + if (field->prefix_len != 0) { /* We do not accept column prefix indexes here */ @@ -2169,6 +2174,13 @@ dict_foreign_find_index( break; } + if (check_null + && (field->col->type.prtype + & DATA_NOT_NULL)) { + + return(NULL); + } + if (types_idx && !cmp_types_are_equal( dict_index_get_nth_type(index, i), dict_index_get_nth_type(types_idx, i), @@ -2290,7 +2302,7 @@ dict_foreign_add_to_cache( index = dict_foreign_find_index(ref_table, (const char**) for_in_cache->referenced_col_names, for_in_cache->n_fields, - for_in_cache->foreign_index, check_charsets); + for_in_cache->foreign_index, check_charsets, FALSE); if (index == NULL) { dict_foreign_error_report(ef, for_in_cache, @@ -2317,13 +2329,17 @@ dict_foreign_add_to_cache( index = dict_foreign_find_index(for_table, (const char**) for_in_cache->foreign_col_names, for_in_cache->n_fields, - for_in_cache->referenced_index, check_charsets); + for_in_cache->referenced_index, check_charsets, + for_in_cache->type + & (DICT_FOREIGN_ON_DELETE_SET_NULL + | DICT_FOREIGN_ON_UPDATE_SET_NULL)); if (index == NULL) { dict_foreign_error_report(ef, for_in_cache, "there is no index in the table which would contain\n" "the columns as the first columns, or the data types in the\n" -"table do not match to the ones in the referenced table."); +"table do not match to the ones in the referenced table\n" +"or one of the ON ... SET NULL columns is declared NOT NULL."); if (for_in_cache == foreign) { if (added_to_referenced_list) { @@ -3125,7 +3141,8 @@ col_loop1: /* Try to find an index which contains the columns as the first fields and in the right order */ - index = dict_foreign_find_index(table, column_names, i, NULL, TRUE); + index = dict_foreign_find_index(table, column_names, i, + NULL, TRUE, FALSE); if (!index) { mutex_enter(&dict_foreign_err_mutex); @@ -3390,7 +3407,7 @@ try_find_index: if (referenced_table) { index = dict_foreign_find_index(referenced_table, - column_names, i, foreign->foreign_index, TRUE); + column_names, i, foreign->foreign_index, TRUE, FALSE); if (!index) { dict_foreign_free(foreign); mutex_enter(&dict_foreign_err_mutex); diff --git a/innobase/include/rem0rec.ic b/innobase/include/rem0rec.ic index 9c24f385f4f..1abbb503bab 100644 --- a/innobase/include/rem0rec.ic +++ b/innobase/include/rem0rec.ic @@ -982,6 +982,9 @@ rec_offs_nth_size( { ut_ad(rec_offs_validate(NULL, NULL, offsets)); ut_ad(n < rec_offs_n_fields(offsets)); + if (!n) { + return(rec_offs_base(offsets)[1 + n] & REC_OFFS_MASK); + } return((rec_offs_base(offsets)[1 + n] - rec_offs_base(offsets)[n]) & REC_OFFS_MASK); } diff --git a/innobase/include/sync0sync.ic b/innobase/include/sync0sync.ic index a32a82d6e8b..e5c6f56d8ba 100644 --- a/innobase/include/sync0sync.ic +++ b/innobase/include/sync0sync.ic @@ -6,6 +6,16 @@ Mutex, the basic synchronization primitive Created 9/5/1995 Heikki Tuuri *******************************************************/ +#if defined(not_defined) && defined(__GNUC__) && defined(UNIV_INTEL_X86) +/* %z0: Use the size of operand %0 which in our case is *m to determine +instruction size, it should end up as xchgl. "1" in the input constraint, +says that "in" has to go in the same place as "out".*/ +#define TAS(m, in, out) \ + asm volatile ("xchg%z0 %2, %0" \ + : "=g" (*(m)), "=r" (out) \ + : "1" (in)) /* Note: "1" here refers to "=r" (out) */ +#endif + /********************************************************************** Sets the waiters field in a mutex. */ @@ -85,20 +95,10 @@ mutex_test_and_set( return(res); #elif defined(not_defined) && defined(__GNUC__) && defined(UNIV_INTEL_X86) - ulint* lw; ulint res; - lw = &(mutex->lock_word); - - /* In assembly we use the so-called AT & T syntax where - the order of operands is inverted compared to the ordinary Intel - syntax. The 'l' after the mnemonics denotes a 32-bit operation. - The line after the code tells which values come out of the asm - code, and the second line tells the input to the asm code. */ + TAS(&mutex->lock_word, 1, res); - asm volatile("movl $1, %%eax; xchgl (%%ecx), %%eax" : - "=eax" (res), "=m" (*lw) : - "ecx" (lw)); return(res); #else ibool ret; @@ -137,20 +137,9 @@ mutex_reset_lock_word( __asm MOV ECX, lw __asm XCHG EDX, DWORD PTR [ECX] #elif defined(not_defined) && defined(__GNUC__) && defined(UNIV_INTEL_X86) - ulint* lw; - - lw = &(mutex->lock_word); - - /* In assembly we use the so-called AT & T syntax where - the order of operands is inverted compared to the ordinary Intel - syntax. The 'l' after the mnemonics denotes a 32-bit operation. */ + ulint res; - asm volatile("movl $0, %%eax; xchgl (%%ecx), %%eax" : - "=m" (*lw) : - "ecx" (lw) : - "eax"); /* gcc does not seem to understand - that our asm code resets eax: tell it - explicitly that after the third ':' */ + TAS(&mutex->lock_word, 0, res); #else mutex->lock_word = 0; diff --git a/innobase/lock/lock0lock.c b/innobase/lock/lock0lock.c index 06475c8ef7e..77dfca5fdf4 100644 --- a/innobase/lock/lock0lock.c +++ b/innobase/lock/lock0lock.c @@ -3259,12 +3259,6 @@ lock_deadlock_recursive( *cost = *cost + 1; - if ((depth > LOCK_MAX_DEPTH_IN_DEADLOCK_CHECK) - || (*cost > LOCK_MAX_N_STEPS_IN_DEADLOCK_CHECK)) { - - return(LOCK_VICTIM_IS_START); - } - lock = wait_lock; if (lock_get_type(wait_lock) == LOCK_REC) { @@ -3296,11 +3290,18 @@ lock_deadlock_recursive( if (lock_has_to_wait(wait_lock, lock)) { + ibool too_far + = depth > LOCK_MAX_DEPTH_IN_DEADLOCK_CHECK + || *cost > LOCK_MAX_N_STEPS_IN_DEADLOCK_CHECK; + lock_trx = lock->trx; - if (lock_trx == start) { + if (lock_trx == start || too_far) { + /* We came back to the recursion starting - point: a deadlock detected */ + point: a deadlock detected; or we have + searched the waits-for graph too long */ + FILE* ef = lock_latest_err_file; rewind(ef); @@ -3342,9 +3343,20 @@ lock_deadlock_recursive( } #ifdef UNIV_DEBUG if (lock_print_waits) { - fputs("Deadlock detected\n", stderr); + fputs("Deadlock detected" + " or too long search\n", + stderr); } #endif /* UNIV_DEBUG */ + if (too_far) { + + fputs("TOO DEEP OR LONG SEARCH" + " IN THE LOCK TABLE" + " WAITS-FOR GRAPH\n", ef); + + return(LOCK_VICTIM_IS_START); + } + if (ut_dulint_cmp(wait_lock->trx->undo_no, start->undo_no) >= 0) { /* Our recursion starting point diff --git a/innobase/os/os0file.c b/innobase/os/os0file.c index 5e5c4b19eb0..72f1f837fee 100644 --- a/innobase/os/os0file.c +++ b/innobase/os/os0file.c @@ -920,14 +920,14 @@ try_again: } file = CreateFile((LPCTSTR) name, - access, - FILE_SHARE_READ | FILE_SHARE_WRITE, - /* file can be read ansd written also - by other processes */ - NULL, /* default security attributes */ - create_flag, - attributes, - NULL); /* no template file */ + access, + FILE_SHARE_READ | FILE_SHARE_WRITE, + /* file can be read and written also + by other processes */ + NULL, /* default security attributes */ + create_flag, + attributes, + NULL); /* no template file */ if (file == INVALID_HANDLE_VALUE) { *success = FALSE; @@ -1494,7 +1494,7 @@ os_file_rename( return(TRUE); } - os_file_handle_error(oldpath, "rename"); + os_file_handle_error_no_exit(oldpath, "rename"); return(FALSE); #else @@ -1503,7 +1503,7 @@ os_file_rename( ret = rename((const char*)oldpath, (const char*)newpath); if (ret != 0) { - os_file_handle_error(oldpath, "rename"); + os_file_handle_error_no_exit(oldpath, "rename"); return(FALSE); } diff --git a/innobase/row/row0undo.c b/innobase/row/row0undo.c index 435c0279dbb..c9727e0098e 100644 --- a/innobase/row/row0undo.c +++ b/innobase/row/row0undo.c @@ -212,7 +212,7 @@ row_undo( ulint err; trx_t* trx; dulint roll_ptr; - ibool froze_data_dict = FALSE; + ibool locked_data_dict; ut_ad(node && thr); @@ -263,15 +263,15 @@ row_undo( } /* Prevent DROP TABLE etc. while we are rolling back this row. - If we are doing a TABLE CREATE or some other dictionary operation, - then we already have dict_operation_lock locked in x-mode. Do not - try to lock again in s-mode, because that would cause a hang. */ + If we are doing a TABLE CREATE or some other dictionary operation, + then we already have dict_operation_lock locked in x-mode. Do not + try to lock again, because that would cause a hang. */ - if (trx->dict_operation_lock_mode == 0) { - - row_mysql_freeze_data_dictionary(trx); + locked_data_dict = (trx->dict_operation_lock_mode == 0); - froze_data_dict = TRUE; + if (locked_data_dict) { + + row_mysql_lock_data_dictionary(trx); } if (node->state == UNDO_NODE_INSERT) { @@ -284,9 +284,9 @@ row_undo( err = row_undo_mod(node, thr); } - if (froze_data_dict) { + if (locked_data_dict) { - row_mysql_unfreeze_data_dictionary(trx); + row_mysql_unlock_data_dictionary(trx); } /* Do some cleanup */ diff --git a/innobase/srv/srv0srv.c b/innobase/srv/srv0srv.c index fe9e08d65be..96c0f05111b 100644 --- a/innobase/srv/srv0srv.c +++ b/innobase/srv/srv0srv.c @@ -1822,14 +1822,14 @@ srv_export_innodb_status(void) export_vars.innodb_pages_written= buf_pool->n_pages_written; export_vars.innodb_row_lock_waits= srv_n_lock_wait_count; export_vars.innodb_row_lock_current_waits= srv_n_lock_wait_current_count; - export_vars.innodb_row_lock_time= srv_n_lock_wait_time / 10000; + export_vars.innodb_row_lock_time= srv_n_lock_wait_time / 1000; if (srv_n_lock_wait_count > 0) { export_vars.innodb_row_lock_time_avg = (ulint) - (srv_n_lock_wait_time / 10000 / srv_n_lock_wait_count); + (srv_n_lock_wait_time / 1000 / srv_n_lock_wait_count); } else { export_vars.innodb_row_lock_time_avg = 0; } - export_vars.innodb_row_lock_time_max= srv_n_lock_max_wait_time / 10000; + export_vars.innodb_row_lock_time_max= srv_n_lock_max_wait_time / 1000; export_vars.innodb_rows_read= srv_n_rows_read; export_vars.innodb_rows_inserted= srv_n_rows_inserted; export_vars.innodb_rows_updated= srv_n_rows_updated; diff --git a/innobase/ut/ut0ut.c b/innobase/ut/ut0ut.c index 1be5939303a..feb03269d91 100644 --- a/innobase/ut/ut0ut.c +++ b/innobase/ut/ut0ut.c @@ -20,6 +20,55 @@ Created 5/11/1994 Heikki Tuuri ibool ut_always_false = FALSE; +#ifdef __WIN__ +/********************************************************************* +NOTE: The Windows epoch starts from 1601/01/01 whereas the Unix +epoch starts from 1970/1/1. For selection of constant see: +http://support.microsoft.com/kb/167296/ */ +#define WIN_TO_UNIX_DELTA_USEC ((ib_longlong) 11644473600000000ULL) + + +/********************************************************************* +This is the Windows version of gettimeofday(2).*/ +static +int +ut_gettimeofday( +/*============*/ + /* out: 0 if all OK else -1 */ + struct timeval* tv, /* out: Values are relative to Unix epoch */ + void* tz) /* in: not used */ +{ + FILETIME ft; + ib_longlong tm; + + if (!tv) { + errno = EINVAL; + return(-1); + } + + GetSystemTimeAsFileTime(&ft); + + tm = (ib_longlong) ft.dwHighDateTime << 32; + tm |= ft.dwLowDateTime; + + ut_a(tm >= 0); /* If tm wraps over to negative, the quotient / 10 + does not work */ + + tm /= 10; /* Convert from 100 nsec periods to usec */ + + /* If we don't convert to the Unix epoch the value for + struct timeval::tv_sec will overflow.*/ + tm -= WIN_TO_UNIX_DELTA_USEC; + + tv->tv_sec = (long) (tm / 1000000L); + tv->tv_usec = (long) (tm % 1000000L); + + return(0); +} +#else +#define ut_gettimeofday gettimeofday +#endif + /********************************************************************* Get the quote character to be used in SQL identifiers. This definition must match the one in sql/ha_innodb.cc! */ @@ -82,17 +131,11 @@ ut_usectime( ulint* sec, /* out: seconds since the Epoch */ ulint* ms) /* out: microseconds since the Epoch+*sec */ { -#ifdef __WIN__ - SYSTEMTIME st; - GetLocalTime(&st); - *sec = (ulint) st.wSecond; - *ms = (ulint) st.wMilliseconds; -#else struct timeval tv; - gettimeofday(&tv,NULL); + + ut_gettimeofday(&tv, NULL); *sec = (ulint) tv.tv_sec; *ms = (ulint) tv.tv_usec; -#endif } /************************************************************** diff --git a/mysql-test/include/gis_generic.inc b/mysql-test/include/gis_generic.inc index dc5d95baad9..70e82a13364 100644 --- a/mysql-test/include/gis_generic.inc +++ b/mysql-test/include/gis_generic.inc @@ -177,4 +177,73 @@ insert into t1 values (pointfromtext('point(1,1)')); drop table t1; -# End of 5.0 tests +--echo End of 4.1 tests + + +# +# Bug#24563: MBROverlaps does not seem to function propertly +# Bug#54888: MBROverlaps missing in 5.1? +# + +# Test all MBR* functions and their non-MBR-prefixed aliases, +# using shifted squares to verify the spatial relations. + +CREATE TABLE t1 (name VARCHAR(100), square GEOMETRY); + +INSERT INTO t1 VALUES("center", GeomFromText('POLYGON (( 0 0, 0 2, 2 2, 2 0, 0 0))')); + +INSERT INTO t1 VALUES("small", GeomFromText('POLYGON (( 0 0, 0 1, 1 1, 1 0, 0 0))')); +INSERT INTO t1 VALUES("big", GeomFromText('POLYGON (( 0 0, 0 3, 3 3, 3 0, 0 0))')); + +INSERT INTO t1 VALUES("up", GeomFromText('POLYGON (( 0 1, 0 3, 2 3, 2 1, 0 1))')); +INSERT INTO t1 VALUES("up2", GeomFromText('POLYGON (( 0 2, 0 4, 2 4, 2 2, 0 2))')); +INSERT INTO t1 VALUES("up3", GeomFromText('POLYGON (( 0 3, 0 5, 2 5, 2 3, 0 3))')); + +INSERT INTO t1 VALUES("down", GeomFromText('POLYGON (( 0 -1, 0 1, 2 1, 2 -1, 0 -1))')); +INSERT INTO t1 VALUES("down2", GeomFromText('POLYGON (( 0 -2, 0 0, 2 0, 2 -2, 0 -2))')); +INSERT INTO t1 VALUES("down3", GeomFromText('POLYGON (( 0 -3, 0 -1, 2 -1, 2 -3, 0 -3))')); + +INSERT INTO t1 VALUES("right", GeomFromText('POLYGON (( 1 0, 1 2, 3 2, 3 0, 1 0))')); +INSERT INTO t1 VALUES("right2", GeomFromText('POLYGON (( 2 0, 2 2, 4 2, 4 0, 2 0))')); +INSERT INTO t1 VALUES("right3", GeomFromText('POLYGON (( 3 0, 3 2, 5 2, 5 0, 3 0))')); + +INSERT INTO t1 VALUES("left", GeomFromText('POLYGON (( -1 0, -1 2, 1 2, 1 0, -1 0))')); +INSERT INTO t1 VALUES("left2", GeomFromText('POLYGON (( -2 0, -2 2, 0 2, 0 0, -2 0))')); +INSERT INTO t1 VALUES("left3", GeomFromText('POLYGON (( -3 0, -3 2, -1 2, -1 0, -3 0))')); + +SELECT GROUP_CONCAT(a2.name ORDER BY a2.name) AS mbrcontains FROM t1 a1 JOIN t1 a2 ON MBRContains( a1.square, a2.square) WHERE a1.name = "center" GROUP BY a1.name; +SELECT GROUP_CONCAT(a2.name ORDER BY a2.name) AS mbrdisjoint FROM t1 a1 JOIN t1 a2 ON MBRDisjoint( a1.square, a2.square) WHERE a1.name = "center" GROUP BY a1.name; +SELECT GROUP_CONCAT(a2.name ORDER BY a2.name) AS mbrequal FROM t1 a1 JOIN t1 a2 ON MBREqual( a1.square, a2.square) WHERE a1.name = "center" GROUP BY a1.name; +SELECT GROUP_CONCAT(a2.name ORDER BY a2.name) AS mbrintersect FROM t1 a1 JOIN t1 a2 ON MBRIntersects( a1.square, a2.square) WHERE a1.name = "center" GROUP BY a1.name; +SELECT GROUP_CONCAT(a2.name ORDER BY a2.name) AS mbroverlaps FROM t1 a1 JOIN t1 a2 ON MBROverlaps( a1.square, a2.square) WHERE a1.name = "center" GROUP BY a1.name; +SELECT GROUP_CONCAT(a2.name ORDER BY a2.name) AS mbrtouches FROM t1 a1 JOIN t1 a2 ON MBRTouches( a1.square, a2.square) WHERE a1.name = "center" GROUP BY a1.name; +SELECT GROUP_CONCAT(a2.name ORDER BY a2.name) AS mbrwithin FROM t1 a1 JOIN t1 a2 ON MBRWithin( a1.square, a2.square) WHERE a1.name = "center" GROUP BY a1.name; + +SELECT GROUP_CONCAT(a2.name ORDER BY a2.name) AS contains FROM t1 a1 JOIN t1 a2 ON Contains( a1.square, a2.square) WHERE a1.name = "center" GROUP BY a1.name; +SELECT GROUP_CONCAT(a2.name ORDER BY a2.name) AS disjoint FROM t1 a1 JOIN t1 a2 ON Disjoint( a1.square, a2.square) WHERE a1.name = "center" GROUP BY a1.name; +SELECT GROUP_CONCAT(a2.name ORDER BY a2.name) AS equals FROM t1 a1 JOIN t1 a2 ON Equals( a1.square, a2.square) WHERE a1.name = "center" GROUP BY a1.name; +SELECT GROUP_CONCAT(a2.name ORDER BY a2.name) AS intersect FROM t1 a1 JOIN t1 a2 ON Intersects( a1.square, a2.square) WHERE a1.name = "center" GROUP BY a1.name; +SELECT GROUP_CONCAT(a2.name ORDER BY a2.name) AS overlaps FROM t1 a1 JOIN t1 a2 ON Overlaps( a1.square, a2.square) WHERE a1.name = "center" GROUP BY a1.name; +SELECT GROUP_CONCAT(a2.name ORDER BY a2.name) AS touches FROM t1 a1 JOIN t1 a2 ON Touches( a1.square, a2.square) WHERE a1.name = "center" GROUP BY a1.name; +SELECT GROUP_CONCAT(a2.name ORDER BY a2.name) AS within FROM t1 a1 JOIN t1 a2 ON Within( a1.square, a2.square) WHERE a1.name = "center" GROUP BY a1.name; + +# Overlaps needs a few more tests, with point and line dimensions + +SET @vert1 = GeomFromText('POLYGON ((0 -2, 0 2, 0 -2))'); +SET @horiz1 = GeomFromText('POLYGON ((-2 0, 2 0, -2 0))'); +SET @horiz2 = GeomFromText('POLYGON ((-1 0, 3 0, -1 0))'); +SET @horiz3 = GeomFromText('POLYGON ((2 0, 3 0, 2 0))'); +SET @point1 = GeomFromText('POLYGON ((0 0))'); +SET @point2 = GeomFromText('POLYGON ((-2 0))'); + +SELECT GROUP_CONCAT(a1.name ORDER BY a1.name) AS overlaps FROM t1 a1 WHERE Overlaps(a1.square, @vert1) GROUP BY a1.name; +SELECT GROUP_CONCAT(a1.name ORDER BY a1.name) AS overlaps FROM t1 a1 WHERE Overlaps(a1.square, @horiz1) GROUP BY a1.name; +SELECT Overlaps(@horiz1, @vert1) FROM DUAL; +SELECT Overlaps(@horiz1, @horiz2) FROM DUAL; +SELECT Overlaps(@horiz1, @horiz3) FROM DUAL; +SELECT Overlaps(@horiz1, @point1) FROM DUAL; +SELECT Overlaps(@horiz1, @point2) FROM DUAL; + +DROP TABLE t1; + +--echo End of 5.0 tests diff --git a/mysql-test/lib/mtr_cases.pl b/mysql-test/lib/mtr_cases.pl index 22290a88d39..28c78fbffeb 100644 --- a/mysql-test/lib/mtr_cases.pl +++ b/mysql-test/lib/mtr_cases.pl @@ -498,6 +498,17 @@ sub collect_one_test_case($$$$$$$) { { mtr_options_from_test_file($tinfo,"$testdir/${tname}.test"); + if ( defined $::used_default_engine ) + { + # Different default engine is used + # tag test to require that engine + $tinfo->{'ndb_test'}= 1 + if ( $::used_default_engine =~ /^ndb/i ); + + $tinfo->{'innodb_test'}= 1 + if ( $::used_default_engine =~ /^innodb/i ); + } + if ( $tinfo->{'big_test'} and ! $::opt_big_test ) { $tinfo->{'skip'}= 1; diff --git a/mysql-test/lib/mtr_process.pl b/mysql-test/lib/mtr_process.pl index 690ca8313dd..53bf37bcc83 100644 --- a/mysql-test/lib/mtr_process.pl +++ b/mysql-test/lib/mtr_process.pl @@ -38,8 +38,8 @@ sub mtr_kill_processes ($); sub mtr_ping_with_timeout($); sub mtr_ping_port ($); -# static in C -sub spawn_impl ($$$$$$$$); +# Local function +sub spawn_impl ($$$$$$$); ############################################################################## # @@ -47,18 +47,16 @@ sub spawn_impl ($$$$$$$$); # ############################################################################## -# This function try to mimic the C version used in "netware/mysql_test_run.c" - sub mtr_run ($$$$$$;$) { my $path= shift; my $arg_list_t= shift; my $input= shift; my $output= shift; my $error= shift; - my $pid_file= shift; + my $pid_file= shift; # Not used my $spawn_opts= shift; - return spawn_impl($path,$arg_list_t,'run',$input,$output,$error,$pid_file, + return spawn_impl($path,$arg_list_t,'run',$input,$output,$error, $spawn_opts); } @@ -68,10 +66,10 @@ sub mtr_run_test ($$$$$$;$) { my $input= shift; my $output= shift; my $error= shift; - my $pid_file= shift; + my $pid_file= shift; # Not used my $spawn_opts= shift; - return spawn_impl($path,$arg_list_t,'test',$input,$output,$error,$pid_file, + return spawn_impl($path,$arg_list_t,'test',$input,$output,$error, $spawn_opts); } @@ -81,28 +79,22 @@ sub mtr_spawn ($$$$$$;$) { my $input= shift; my $output= shift; my $error= shift; - my $pid_file= shift; + my $pid_file= shift; # Not used my $spawn_opts= shift; - return spawn_impl($path,$arg_list_t,'spawn',$input,$output,$error,$pid_file, + return spawn_impl($path,$arg_list_t,'spawn',$input,$output,$error, $spawn_opts); } -############################################################################## -# -# If $join is set, we return the error code, else we return the PID -# -############################################################################## -sub spawn_impl ($$$$$$$$) { +sub spawn_impl ($$$$$$$) { my $path= shift; my $arg_list_t= shift; my $mode= shift; my $input= shift; my $output= shift; my $error= shift; - my $pid_file= shift; # FIXME my $spawn_opts= shift; if ( $::opt_script_debug ) @@ -155,10 +147,6 @@ sub spawn_impl ($$$$$$$$) { else { # Child, redirect output and exec - # FIXME I tried POSIX::setsid() here to detach and, I hoped, - # avoid zombies. But everything went wild, somehow the parent - # became a deamon as well, and was hard to kill ;-) - # Need to catch SIGCHLD and do waitpid or something instead...... $SIG{INT}= 'DEFAULT'; # Parent do some stuff, we don't @@ -196,7 +184,15 @@ sub spawn_impl ($$$$$$$$) { } else { - if ( ! open(STDERR,$log_file_open_mode,$error) ) + if ( $::glob_win32_perl ) + { + # Don't redirect stdout on ActiveState perl since this is + # just another thread in the same process. + # Should be fixed so that the thread that is created with fork + # executes the exe in another process and wait's for it to return. + # In the meanwhile, we get all the output from mysqld's to screen + } + elsif ( ! open(STDERR,$log_file_open_mode,$error) ) { mtr_child_error("can't redirect STDERR to \"$error\": $!"); } @@ -259,9 +255,7 @@ sub spawn_parent_impl { # We do blocking waitpid() until we get the return from the # "mysqltest" call. But if a mysqld process dies that we # started, we take this as an error, and kill mysqltest. - # - # FIXME is this as it should be? Can't mysqld terminate - # normally from running a test case? + my $exit_value= -1; my $saved_exit_value; @@ -450,7 +444,6 @@ sub mtr_kill_leftovers () { # We scan the "var/run/" directory for other process id's to kill - # FIXME $path_run_dir or something my $rundir= "$::opt_vardir/run"; mtr_debug("Processing PID files in directory '$rundir'..."); diff --git a/mysql-test/mysql-test-run.pl b/mysql-test/mysql-test-run.pl index 27e70e84afe..b48ac6c5abc 100755 --- a/mysql-test/mysql-test-run.pl +++ b/mysql-test/mysql-test-run.pl @@ -304,6 +304,7 @@ our $path_sql_dir; our @data_dir_lst; our $used_binlog_format; +our $used_default_engine; our $debug_compiled_binaries; our $glob_tot_real_time= 0; @@ -519,7 +520,7 @@ sub command_line_setup () { 'compress' => \$opt_compress, 'bench' => \$opt_bench, 'small-bench' => \$opt_small_bench, - 'with-ndbcluster' => \$opt_with_ndbcluster, + 'with-ndbcluster|ndb' => \$opt_with_ndbcluster, 'vs-config' => \$opt_vs_config, # Control what test suites or cases to run @@ -776,6 +777,26 @@ sub command_line_setup () { mtr_report("Using binlog format '$used_binlog_format'"); } + + # -------------------------------------------------------------------------- + # Find out default storage engine being used(if any) + # -------------------------------------------------------------------------- + if ( $opt_with_ndbcluster ) + { + # --ndb or --with-ndbcluster turns on --default-storage-engine=ndbcluster + push(@opt_extra_mysqld_opt, "--default-storage-engine=ndbcluster"); + } + + foreach my $arg ( @opt_extra_mysqld_opt ) + { + if ( $arg =~ /default-storage-engine=(\S+)/ ) + { + $used_default_engine= $1; + } + } + mtr_report("Using default engine '$used_default_engine'") + if defined $used_default_engine; + # -------------------------------------------------------------------------- # Check if we should speed up tests by trying to run on tmpfs # -------------------------------------------------------------------------- @@ -848,20 +869,22 @@ sub command_line_setup () { # -------------------------------------------------------------------------- # Check im suport # -------------------------------------------------------------------------- - if (!$opt_extern) + if ($opt_extern) { - if ( $mysql_version_id < 50000 ) { - # Instance manager is not supported until 5.0 - $opt_skip_im= 1; - - } - - if ( $glob_win32 ) { - mtr_report("Disable Instance manager - not supported on Windows"); - $opt_skip_im= 1; - } - + mtr_report("Disable instance manager when running with extern mysqld"); + $opt_skip_im= 1; + } + elsif ( $mysql_version_id < 50000 ) + { + # Instance manager is not supported until 5.0 + $opt_skip_im= 1; + } + elsif ( $glob_win32 ) + { + mtr_report("Disable Instance manager - testing not supported on Windows"); + $opt_skip_im= 1; } + # -------------------------------------------------------------------------- # Record flag # -------------------------------------------------------------------------- @@ -899,10 +922,6 @@ sub command_line_setup () { # -------------------------------------------------------------------------- # Ndb cluster flags # -------------------------------------------------------------------------- - if ( $opt_with_ndbcluster and !$opt_bench) - { - mtr_error("Can only use --with-ndbcluster togheter with --bench"); - } if ( $opt_ndbconnectstring ) { @@ -1055,8 +1074,6 @@ sub command_line_setup () { # socket path names. $sockdir = tempdir(CLEANUP => 0) if ( length($sockdir) > 80 ); - # Put this into a hash, will be a C struct - $master->[0]= { pid => 0, @@ -1064,7 +1081,6 @@ sub command_line_setup () { idx => 0, path_myddir => "$opt_vardir/master-data", path_myerr => "$opt_vardir/log/master.err", - path_mylog => "$opt_vardir/log/master.log", path_pid => "$opt_vardir/run/master.pid", path_sock => "$sockdir/master.sock", port => $opt_master_myport, @@ -1080,7 +1096,6 @@ sub command_line_setup () { idx => 1, path_myddir => "$opt_vardir/master1-data", path_myerr => "$opt_vardir/log/master1.err", - path_mylog => "$opt_vardir/log/master1.log", path_pid => "$opt_vardir/run/master1.pid", path_sock => "$sockdir/master1.sock", port => $opt_master_myport + 1, @@ -1096,7 +1111,6 @@ sub command_line_setup () { idx => 0, path_myddir => "$opt_vardir/slave-data", path_myerr => "$opt_vardir/log/slave.err", - path_mylog => "$opt_vardir/log/slave.log", path_pid => "$opt_vardir/run/slave.pid", path_sock => "$sockdir/slave.sock", port => $opt_slave_myport, @@ -1113,7 +1127,6 @@ sub command_line_setup () { idx => 1, path_myddir => "$opt_vardir/slave1-data", path_myerr => "$opt_vardir/log/slave1.err", - path_mylog => "$opt_vardir/log/slave1.log", path_pid => "$opt_vardir/run/slave1.pid", path_sock => "$sockdir/slave1.sock", port => $opt_slave_myport + 1, @@ -1129,7 +1142,6 @@ sub command_line_setup () { idx => 2, path_myddir => "$opt_vardir/slave2-data", path_myerr => "$opt_vardir/log/slave2.err", - path_mylog => "$opt_vardir/log/slave2.log", path_pid => "$opt_vardir/run/slave2.pid", path_sock => "$sockdir/slave2.sock", port => $opt_slave_myport + 2, @@ -1333,7 +1345,7 @@ sub collect_mysqld_features () { # # Execute "mysqld --no-defaults --help --verbose" to get a - # of all features and settings + # list of all features and settings # my $list= `$exe_mysqld --no-defaults --verbose --help`; @@ -1397,6 +1409,40 @@ sub collect_mysqld_features () { } +sub run_query($$) { + my ($mysqld, $query)= @_; + + my $args; + mtr_init_args(\$args); + + mtr_add_arg($args, "--no-defaults"); + mtr_add_arg($args, "--user=%s", $opt_user); + mtr_add_arg($args, "--port=%d", $mysqld->{'port'}); + mtr_add_arg($args, "--socket=%s", $mysqld->{'path_sock'}); + mtr_add_arg($args, "--silent"); # Tab separated output + mtr_add_arg($args, "-e '%s'", $query); + + my $cmd= "$exe_mysql " . join(' ', @$args); + mtr_verbose("cmd: $cmd"); + return `$cmd`; +} + + +sub collect_mysqld_features_from_running_server () +{ + my $list= run_query($master->[0], "use mysql; SHOW VARIABLES"); + + foreach my $line (split('\n', $list)) + { + # Put variables into hash + if ( $line =~ /^([\S]+)[ \t]+(.*?)\r?$/ ) + { + print "$1=\"$2\"\n"; + $mysqld_variables{$1}= $2; + } + } +} + sub executable_setup_im () { # Look for instance manager binary - mysqlmanager @@ -1913,7 +1959,7 @@ sub environment_setup () { # ---------------------------------------------------- my $cmdline_mysqlbinlog= mtr_native_path($exe_mysqlbinlog) . - " --no-defaults --local-load=$opt_tmpdir"; + " --no-defaults"; if (!$opt_extern && $mysql_version_id >= 50000 ) { $cmdline_mysqlbinlog .=" --character-sets-dir=$path_charsetsdir"; @@ -3691,8 +3737,10 @@ sub mysqld_arguments ($$$$) { mtr_add_arg($args, "%s--log-output=table,file", $prefix); } - mtr_add_arg($args, "%s--log=%s", $prefix, $mysqld->{'path_mylog'}); - + my $log_base_path= "$opt_vardir/log/$mysqld->{'type'}$sidx"; + mtr_add_arg($args, "%s--log=%s.log", $prefix, $log_base_path); + mtr_add_arg($args, + "%s--log-slow-queries=%s-slow.log", $prefix, $log_base_path); # Check if "extra_opt" contains --skip-log-bin my $skip_binlog= grep(/^--skip-log-bin/, @$extra_opt); @@ -4992,7 +5040,7 @@ Options to control what engine/variation to run skip-ssl Dont start server with support for ssl connections bench Run the benchmark suite small-bench Run the benchmarks with --small-tests --small-tables - with-ndbcluster Use cluster as default table type for benchmark + ndb|with-ndbcluster Use cluster as default table type vs-config Visual Studio configuration used to create executables (default: MTR_VS_CONFIG environment variable) diff --git a/mysql-test/r/archive.result b/mysql-test/r/archive.result index f73a80dde65..d89cecedcdd 100644 --- a/mysql-test/r/archive.result +++ b/mysql-test/r/archive.result @@ -12355,3 +12355,12 @@ auto fld1 companynr fld3 fld4 fld5 4 011403 37 intercepted audiology tinily 4 011403 37 intercepted audiology tinily drop table t1, t2, t4; +create table t1 (i int) engine=archive; +insert into t1 values (1); +repair table t1 use_frm; +Table Op Msg_type Msg_text +test.t1 repair status OK +select * from t1; +i +1 +drop table t1; diff --git a/mysql-test/r/archive_gis.result b/mysql-test/r/archive_gis.result index 7fb69e54a4c..3137d43ec3a 100644 --- a/mysql-test/r/archive_gis.result +++ b/mysql-test/r/archive_gis.result @@ -392,7 +392,7 @@ Intersects(g1.g, g2.g) as i, Crosses(g1.g, g2.g) as r FROM gis_geometrycollection g1, gis_geometrycollection g2 ORDER BY first, second; first second w c o e d t i r 120 120 1 1 0 1 0 0 1 0 -120 121 0 0 0 0 0 0 1 0 +120 121 0 0 1 0 0 0 1 0 121 120 0 0 1 0 0 0 1 0 121 121 1 1 0 1 0 0 1 0 explain extended SELECT g1.fid as first, g2.fid as second, @@ -456,3 +456,89 @@ ERROR 22003: Cannot get geometry object from data you send to the GEOMETRY field insert into t1 values (pointfromtext('point(1,1)')); ERROR 23000: Column 'fl' cannot be null drop table t1; +End of 4.1 tests +CREATE TABLE t1 (name VARCHAR(100), square GEOMETRY); +INSERT INTO t1 VALUES("center", GeomFromText('POLYGON (( 0 0, 0 2, 2 2, 2 0, 0 0))')); +INSERT INTO t1 VALUES("small", GeomFromText('POLYGON (( 0 0, 0 1, 1 1, 1 0, 0 0))')); +INSERT INTO t1 VALUES("big", GeomFromText('POLYGON (( 0 0, 0 3, 3 3, 3 0, 0 0))')); +INSERT INTO t1 VALUES("up", GeomFromText('POLYGON (( 0 1, 0 3, 2 3, 2 1, 0 1))')); +INSERT INTO t1 VALUES("up2", GeomFromText('POLYGON (( 0 2, 0 4, 2 4, 2 2, 0 2))')); +INSERT INTO t1 VALUES("up3", GeomFromText('POLYGON (( 0 3, 0 5, 2 5, 2 3, 0 3))')); +INSERT INTO t1 VALUES("down", GeomFromText('POLYGON (( 0 -1, 0 1, 2 1, 2 -1, 0 -1))')); +INSERT INTO t1 VALUES("down2", GeomFromText('POLYGON (( 0 -2, 0 0, 2 0, 2 -2, 0 -2))')); +INSERT INTO t1 VALUES("down3", GeomFromText('POLYGON (( 0 -3, 0 -1, 2 -1, 2 -3, 0 -3))')); +INSERT INTO t1 VALUES("right", GeomFromText('POLYGON (( 1 0, 1 2, 3 2, 3 0, 1 0))')); +INSERT INTO t1 VALUES("right2", GeomFromText('POLYGON (( 2 0, 2 2, 4 2, 4 0, 2 0))')); +INSERT INTO t1 VALUES("right3", GeomFromText('POLYGON (( 3 0, 3 2, 5 2, 5 0, 3 0))')); +INSERT INTO t1 VALUES("left", GeomFromText('POLYGON (( -1 0, -1 2, 1 2, 1 0, -1 0))')); +INSERT INTO t1 VALUES("left2", GeomFromText('POLYGON (( -2 0, -2 2, 0 2, 0 0, -2 0))')); +INSERT INTO t1 VALUES("left3", GeomFromText('POLYGON (( -3 0, -3 2, -1 2, -1 0, -3 0))')); +SELECT GROUP_CONCAT(a2.name ORDER BY a2.name) AS mbrcontains FROM t1 a1 JOIN t1 a2 ON MBRContains( a1.square, a2.square) WHERE a1.name = "center" GROUP BY a1.name; +mbrcontains +center,small +SELECT GROUP_CONCAT(a2.name ORDER BY a2.name) AS mbrdisjoint FROM t1 a1 JOIN t1 a2 ON MBRDisjoint( a1.square, a2.square) WHERE a1.name = "center" GROUP BY a1.name; +mbrdisjoint +down3,left3,right3,up3 +SELECT GROUP_CONCAT(a2.name ORDER BY a2.name) AS mbrequal FROM t1 a1 JOIN t1 a2 ON MBREqual( a1.square, a2.square) WHERE a1.name = "center" GROUP BY a1.name; +mbrequal +center +SELECT GROUP_CONCAT(a2.name ORDER BY a2.name) AS mbrintersect FROM t1 a1 JOIN t1 a2 ON MBRIntersects( a1.square, a2.square) WHERE a1.name = "center" GROUP BY a1.name; +mbrintersect +big,center,down,down2,left,left2,right,right2,small,up,up2 +SELECT GROUP_CONCAT(a2.name ORDER BY a2.name) AS mbroverlaps FROM t1 a1 JOIN t1 a2 ON MBROverlaps( a1.square, a2.square) WHERE a1.name = "center" GROUP BY a1.name; +mbroverlaps +down,left,right,up +SELECT GROUP_CONCAT(a2.name ORDER BY a2.name) AS mbrtouches FROM t1 a1 JOIN t1 a2 ON MBRTouches( a1.square, a2.square) WHERE a1.name = "center" GROUP BY a1.name; +mbrtouches +down2,left2,right2,up2 +SELECT GROUP_CONCAT(a2.name ORDER BY a2.name) AS mbrwithin FROM t1 a1 JOIN t1 a2 ON MBRWithin( a1.square, a2.square) WHERE a1.name = "center" GROUP BY a1.name; +mbrwithin +big,center +SELECT GROUP_CONCAT(a2.name ORDER BY a2.name) AS contains FROM t1 a1 JOIN t1 a2 ON Contains( a1.square, a2.square) WHERE a1.name = "center" GROUP BY a1.name; +contains +center,small +SELECT GROUP_CONCAT(a2.name ORDER BY a2.name) AS disjoint FROM t1 a1 JOIN t1 a2 ON Disjoint( a1.square, a2.square) WHERE a1.name = "center" GROUP BY a1.name; +disjoint +down3,left3,right3,up3 +SELECT GROUP_CONCAT(a2.name ORDER BY a2.name) AS equals FROM t1 a1 JOIN t1 a2 ON Equals( a1.square, a2.square) WHERE a1.name = "center" GROUP BY a1.name; +equals +center +SELECT GROUP_CONCAT(a2.name ORDER BY a2.name) AS intersect FROM t1 a1 JOIN t1 a2 ON Intersects( a1.square, a2.square) WHERE a1.name = "center" GROUP BY a1.name; +intersect +big,center,down,down2,left,left2,right,right2,small,up,up2 +SELECT GROUP_CONCAT(a2.name ORDER BY a2.name) AS overlaps FROM t1 a1 JOIN t1 a2 ON Overlaps( a1.square, a2.square) WHERE a1.name = "center" GROUP BY a1.name; +overlaps +down,left,right,up +SELECT GROUP_CONCAT(a2.name ORDER BY a2.name) AS touches FROM t1 a1 JOIN t1 a2 ON Touches( a1.square, a2.square) WHERE a1.name = "center" GROUP BY a1.name; +touches +down2,left2,right2,up2 +SELECT GROUP_CONCAT(a2.name ORDER BY a2.name) AS within FROM t1 a1 JOIN t1 a2 ON Within( a1.square, a2.square) WHERE a1.name = "center" GROUP BY a1.name; +within +big,center +SET @vert1 = GeomFromText('POLYGON ((0 -2, 0 2, 0 -2))'); +SET @horiz1 = GeomFromText('POLYGON ((-2 0, 2 0, -2 0))'); +SET @horiz2 = GeomFromText('POLYGON ((-1 0, 3 0, -1 0))'); +SET @horiz3 = GeomFromText('POLYGON ((2 0, 3 0, 2 0))'); +SET @point1 = GeomFromText('POLYGON ((0 0))'); +SET @point2 = GeomFromText('POLYGON ((-2 0))'); +SELECT GROUP_CONCAT(a1.name ORDER BY a1.name) AS overlaps FROM t1 a1 WHERE Overlaps(a1.square, @vert1) GROUP BY a1.name; +overlaps +SELECT GROUP_CONCAT(a1.name ORDER BY a1.name) AS overlaps FROM t1 a1 WHERE Overlaps(a1.square, @horiz1) GROUP BY a1.name; +overlaps +SELECT Overlaps(@horiz1, @vert1) FROM DUAL; +Overlaps(@horiz1, @vert1) +0 +SELECT Overlaps(@horiz1, @horiz2) FROM DUAL; +Overlaps(@horiz1, @horiz2) +1 +SELECT Overlaps(@horiz1, @horiz3) FROM DUAL; +Overlaps(@horiz1, @horiz3) +0 +SELECT Overlaps(@horiz1, @point1) FROM DUAL; +Overlaps(@horiz1, @point1) +0 +SELECT Overlaps(@horiz1, @point2) FROM DUAL; +Overlaps(@horiz1, @point2) +0 +DROP TABLE t1; +End of 5.0 tests diff --git a/mysql-test/r/bdb_gis.result b/mysql-test/r/bdb_gis.result index 512d681ff32..d48b5a26e1d 100644 --- a/mysql-test/r/bdb_gis.result +++ b/mysql-test/r/bdb_gis.result @@ -392,7 +392,7 @@ Intersects(g1.g, g2.g) as i, Crosses(g1.g, g2.g) as r FROM gis_geometrycollection g1, gis_geometrycollection g2 ORDER BY first, second; first second w c o e d t i r 120 120 1 1 0 1 0 0 1 0 -120 121 0 0 0 0 0 0 1 0 +120 121 0 0 1 0 0 0 1 0 121 120 0 0 1 0 0 0 1 0 121 121 1 1 0 1 0 0 1 0 explain extended SELECT g1.fid as first, g2.fid as second, @@ -456,3 +456,89 @@ ERROR 22003: Cannot get geometry object from data you send to the GEOMETRY field insert into t1 values (pointfromtext('point(1,1)')); ERROR 23000: Column 'fl' cannot be null drop table t1; +End of 4.1 tests +CREATE TABLE t1 (name VARCHAR(100), square GEOMETRY); +INSERT INTO t1 VALUES("center", GeomFromText('POLYGON (( 0 0, 0 2, 2 2, 2 0, 0 0))')); +INSERT INTO t1 VALUES("small", GeomFromText('POLYGON (( 0 0, 0 1, 1 1, 1 0, 0 0))')); +INSERT INTO t1 VALUES("big", GeomFromText('POLYGON (( 0 0, 0 3, 3 3, 3 0, 0 0))')); +INSERT INTO t1 VALUES("up", GeomFromText('POLYGON (( 0 1, 0 3, 2 3, 2 1, 0 1))')); +INSERT INTO t1 VALUES("up2", GeomFromText('POLYGON (( 0 2, 0 4, 2 4, 2 2, 0 2))')); +INSERT INTO t1 VALUES("up3", GeomFromText('POLYGON (( 0 3, 0 5, 2 5, 2 3, 0 3))')); +INSERT INTO t1 VALUES("down", GeomFromText('POLYGON (( 0 -1, 0 1, 2 1, 2 -1, 0 -1))')); +INSERT INTO t1 VALUES("down2", GeomFromText('POLYGON (( 0 -2, 0 0, 2 0, 2 -2, 0 -2))')); +INSERT INTO t1 VALUES("down3", GeomFromText('POLYGON (( 0 -3, 0 -1, 2 -1, 2 -3, 0 -3))')); +INSERT INTO t1 VALUES("right", GeomFromText('POLYGON (( 1 0, 1 2, 3 2, 3 0, 1 0))')); +INSERT INTO t1 VALUES("right2", GeomFromText('POLYGON (( 2 0, 2 2, 4 2, 4 0, 2 0))')); +INSERT INTO t1 VALUES("right3", GeomFromText('POLYGON (( 3 0, 3 2, 5 2, 5 0, 3 0))')); +INSERT INTO t1 VALUES("left", GeomFromText('POLYGON (( -1 0, -1 2, 1 2, 1 0, -1 0))')); +INSERT INTO t1 VALUES("left2", GeomFromText('POLYGON (( -2 0, -2 2, 0 2, 0 0, -2 0))')); +INSERT INTO t1 VALUES("left3", GeomFromText('POLYGON (( -3 0, -3 2, -1 2, -1 0, -3 0))')); +SELECT GROUP_CONCAT(a2.name ORDER BY a2.name) AS mbrcontains FROM t1 a1 JOIN t1 a2 ON MBRContains( a1.square, a2.square) WHERE a1.name = "center" GROUP BY a1.name; +mbrcontains +center,small +SELECT GROUP_CONCAT(a2.name ORDER BY a2.name) AS mbrdisjoint FROM t1 a1 JOIN t1 a2 ON MBRDisjoint( a1.square, a2.square) WHERE a1.name = "center" GROUP BY a1.name; +mbrdisjoint +down3,left3,right3,up3 +SELECT GROUP_CONCAT(a2.name ORDER BY a2.name) AS mbrequal FROM t1 a1 JOIN t1 a2 ON MBREqual( a1.square, a2.square) WHERE a1.name = "center" GROUP BY a1.name; +mbrequal +center +SELECT GROUP_CONCAT(a2.name ORDER BY a2.name) AS mbrintersect FROM t1 a1 JOIN t1 a2 ON MBRIntersects( a1.square, a2.square) WHERE a1.name = "center" GROUP BY a1.name; +mbrintersect +big,center,down,down2,left,left2,right,right2,small,up,up2 +SELECT GROUP_CONCAT(a2.name ORDER BY a2.name) AS mbroverlaps FROM t1 a1 JOIN t1 a2 ON MBROverlaps( a1.square, a2.square) WHERE a1.name = "center" GROUP BY a1.name; +mbroverlaps +down,left,right,up +SELECT GROUP_CONCAT(a2.name ORDER BY a2.name) AS mbrtouches FROM t1 a1 JOIN t1 a2 ON MBRTouches( a1.square, a2.square) WHERE a1.name = "center" GROUP BY a1.name; +mbrtouches +down2,left2,right2,up2 +SELECT GROUP_CONCAT(a2.name ORDER BY a2.name) AS mbrwithin FROM t1 a1 JOIN t1 a2 ON MBRWithin( a1.square, a2.square) WHERE a1.name = "center" GROUP BY a1.name; +mbrwithin +big,center +SELECT GROUP_CONCAT(a2.name ORDER BY a2.name) AS contains FROM t1 a1 JOIN t1 a2 ON Contains( a1.square, a2.square) WHERE a1.name = "center" GROUP BY a1.name; +contains +center,small +SELECT GROUP_CONCAT(a2.name ORDER BY a2.name) AS disjoint FROM t1 a1 JOIN t1 a2 ON Disjoint( a1.square, a2.square) WHERE a1.name = "center" GROUP BY a1.name; +disjoint +down3,left3,right3,up3 +SELECT GROUP_CONCAT(a2.name ORDER BY a2.name) AS equals FROM t1 a1 JOIN t1 a2 ON Equals( a1.square, a2.square) WHERE a1.name = "center" GROUP BY a1.name; +equals +center +SELECT GROUP_CONCAT(a2.name ORDER BY a2.name) AS intersect FROM t1 a1 JOIN t1 a2 ON Intersects( a1.square, a2.square) WHERE a1.name = "center" GROUP BY a1.name; +intersect +big,center,down,down2,left,left2,right,right2,small,up,up2 +SELECT GROUP_CONCAT(a2.name ORDER BY a2.name) AS overlaps FROM t1 a1 JOIN t1 a2 ON Overlaps( a1.square, a2.square) WHERE a1.name = "center" GROUP BY a1.name; +overlaps +down,left,right,up +SELECT GROUP_CONCAT(a2.name ORDER BY a2.name) AS touches FROM t1 a1 JOIN t1 a2 ON Touches( a1.square, a2.square) WHERE a1.name = "center" GROUP BY a1.name; +touches +down2,left2,right2,up2 +SELECT GROUP_CONCAT(a2.name ORDER BY a2.name) AS within FROM t1 a1 JOIN t1 a2 ON Within( a1.square, a2.square) WHERE a1.name = "center" GROUP BY a1.name; +within +big,center +SET @vert1 = GeomFromText('POLYGON ((0 -2, 0 2, 0 -2))'); +SET @horiz1 = GeomFromText('POLYGON ((-2 0, 2 0, -2 0))'); +SET @horiz2 = GeomFromText('POLYGON ((-1 0, 3 0, -1 0))'); +SET @horiz3 = GeomFromText('POLYGON ((2 0, 3 0, 2 0))'); +SET @point1 = GeomFromText('POLYGON ((0 0))'); +SET @point2 = GeomFromText('POLYGON ((-2 0))'); +SELECT GROUP_CONCAT(a1.name ORDER BY a1.name) AS overlaps FROM t1 a1 WHERE Overlaps(a1.square, @vert1) GROUP BY a1.name; +overlaps +SELECT GROUP_CONCAT(a1.name ORDER BY a1.name) AS overlaps FROM t1 a1 WHERE Overlaps(a1.square, @horiz1) GROUP BY a1.name; +overlaps +SELECT Overlaps(@horiz1, @vert1) FROM DUAL; +Overlaps(@horiz1, @vert1) +0 +SELECT Overlaps(@horiz1, @horiz2) FROM DUAL; +Overlaps(@horiz1, @horiz2) +1 +SELECT Overlaps(@horiz1, @horiz3) FROM DUAL; +Overlaps(@horiz1, @horiz3) +0 +SELECT Overlaps(@horiz1, @point1) FROM DUAL; +Overlaps(@horiz1, @point1) +0 +SELECT Overlaps(@horiz1, @point2) FROM DUAL; +Overlaps(@horiz1, @point2) +0 +DROP TABLE t1; +End of 5.0 tests diff --git a/mysql-test/r/create.result b/mysql-test/r/create.result index 0a8fef8d881..afa005e74c0 100644 --- a/mysql-test/r/create.result +++ b/mysql-test/r/create.result @@ -771,3 +771,4 @@ t1 CREATE TABLE `t1` ( drop table t1; create table t1 (upgrade int); drop table t1; +End of 5.0 tests diff --git a/mysql-test/r/date_formats.result b/mysql-test/r/date_formats.result index 8c3631c2707..f4ec6830cd5 100644 --- a/mysql-test/r/date_formats.result +++ b/mysql-test/r/date_formats.result @@ -186,12 +186,12 @@ date format datetime 2003-01-02 02:11:12.12345AM %Y-%m-%d %h:%i:%S.%f %p 2003-01-02 02:11:12.123450 2003-01-02 12:11:12.12345 am %Y-%m-%d %h:%i:%S.%f%p 2003-01-02 00:11:12.123450 2003-01-02 11:11:12Pm %Y-%m-%d %h:%i:%S%p 2003-01-02 23:11:12 -10:20:10 %H:%i:%s 0000-00-00 00:00:00 -10:20:10 %h:%i:%s.%f 0000-00-00 00:00:00 -10:20:10 %T 0000-00-00 00:00:00 -10:20:10AM %h:%i:%s%p 0000-00-00 00:00:00 -10:20:10AM %r 0000-00-00 00:00:00 -10:20:10.44AM %h:%i:%s.%f%p 0000-00-00 00:00:00 +10:20:10 %H:%i:%s 0000-00-00 10:20:10 +10:20:10 %h:%i:%s.%f 0000-00-00 10:20:10 +10:20:10 %T 0000-00-00 10:20:10 +10:20:10AM %h:%i:%s%p 0000-00-00 10:20:10 +10:20:10AM %r 0000-00-00 10:20:10 +10:20:10.44AM %h:%i:%s.%f%p 0000-00-00 10:20:10.440000 15-01-2001 12:59:58 %d-%m-%Y %H:%i:%S 2001-01-15 12:59:58 15 September 2001 %d %M %Y 2001-09-15 00:00:00 15 SEPTEMB 2001 %d %M %Y 2001-09-15 00:00:00 @@ -208,13 +208,6 @@ Tuesday 52 2001 %W %V %X 2002-01-01 00:00:00 15-01-2001 %d-%m-%Y %H:%i:%S 2001-01-15 00:00:00 15-01-20 %d-%m-%y 2020-01-15 00:00:00 15-2001-1 %d-%Y-%c 2001-01-15 00:00:00 -Warnings: -Warning 1292 Truncated incorrect datetime value: '0000-00-00 10:20:10' -Warning 1292 Truncated incorrect datetime value: '0000-00-00 10:20:10' -Warning 1292 Truncated incorrect datetime value: '0000-00-00 10:20:10' -Warning 1292 Truncated incorrect datetime value: '0000-00-00 10:20:10' -Warning 1292 Truncated incorrect datetime value: '0000-00-00 10:20:10' -Warning 1292 Truncated incorrect datetime value: '0000-00-00 10:20:10.440000' select date,format,DATE(str_to_date(date, format)) as date2 from t1; date format date2 2003-01-02 10:11:12 %Y-%m-%d %H:%i:%S 2003-01-02 @@ -255,12 +248,12 @@ date format time 2003-01-02 02:11:12.12345AM %Y-%m-%d %h:%i:%S.%f %p 02:11:12.123450 2003-01-02 12:11:12.12345 am %Y-%m-%d %h:%i:%S.%f%p 00:11:12.123450 2003-01-02 11:11:12Pm %Y-%m-%d %h:%i:%S%p 23:11:12 -10:20:10 %H:%i:%s NULL -10:20:10 %h:%i:%s.%f NULL -10:20:10 %T NULL -10:20:10AM %h:%i:%s%p NULL -10:20:10AM %r NULL -10:20:10.44AM %h:%i:%s.%f%p NULL +10:20:10 %H:%i:%s 10:20:10 +10:20:10 %h:%i:%s.%f 10:20:10 +10:20:10 %T 10:20:10 +10:20:10AM %h:%i:%s%p 10:20:10 +10:20:10AM %r 10:20:10 +10:20:10.44AM %h:%i:%s.%f%p 10:20:10.440000 15-01-2001 12:59:58 %d-%m-%Y %H:%i:%S 12:59:58 15 September 2001 %d %M %Y 00:00:00 15 SEPTEMB 2001 %d %M %Y 00:00:00 @@ -277,13 +270,6 @@ Tuesday 52 2001 %W %V %X 00:00:00 15-01-2001 %d-%m-%Y %H:%i:%S 00:00:00 15-01-20 %d-%m-%y 00:00:00 15-2001-1 %d-%Y-%c 00:00:00 -Warnings: -Warning 1292 Truncated incorrect time value: '0000-00-00 10:20:10' -Warning 1292 Truncated incorrect time value: '0000-00-00 10:20:10' -Warning 1292 Truncated incorrect time value: '0000-00-00 10:20:10' -Warning 1292 Truncated incorrect time value: '0000-00-00 10:20:10' -Warning 1292 Truncated incorrect time value: '0000-00-00 10:20:10' -Warning 1292 Truncated incorrect time value: '0000-00-00 10:20:10.440000' select date,format,concat(TIME(str_to_date(date, format))) as time2 from t1; date format time2 2003-01-02 10:11:12 %Y-%m-%d %H:%i:%S 10:11:12 @@ -293,12 +279,12 @@ date format time2 2003-01-02 02:11:12.12345AM %Y-%m-%d %h:%i:%S.%f %p 02:11:12.123450 2003-01-02 12:11:12.12345 am %Y-%m-%d %h:%i:%S.%f%p 00:11:12.123450 2003-01-02 11:11:12Pm %Y-%m-%d %h:%i:%S%p 23:11:12 -10:20:10 %H:%i:%s NULL -10:20:10 %h:%i:%s.%f NULL -10:20:10 %T NULL -10:20:10AM %h:%i:%s%p NULL -10:20:10AM %r NULL -10:20:10.44AM %h:%i:%s.%f%p NULL +10:20:10 %H:%i:%s 10:20:10 +10:20:10 %h:%i:%s.%f 10:20:10 +10:20:10 %T 10:20:10 +10:20:10AM %h:%i:%s%p 10:20:10 +10:20:10AM %r 10:20:10 +10:20:10.44AM %h:%i:%s.%f%p 10:20:10.440000 15-01-2001 12:59:58 %d-%m-%Y %H:%i:%S 12:59:58 15 September 2001 %d %M %Y 00:00:00 15 SEPTEMB 2001 %d %M %Y 00:00:00 @@ -315,13 +301,6 @@ Tuesday 52 2001 %W %V %X 00:00:00 15-01-2001 %d-%m-%Y %H:%i:%S 00:00:00 15-01-20 %d-%m-%y 00:00:00 15-2001-1 %d-%Y-%c 00:00:00 -Warnings: -Warning 1292 Truncated incorrect time value: '0000-00-00 10:20:10' -Warning 1292 Truncated incorrect time value: '0000-00-00 10:20:10' -Warning 1292 Truncated incorrect time value: '0000-00-00 10:20:10' -Warning 1292 Truncated incorrect time value: '0000-00-00 10:20:10' -Warning 1292 Truncated incorrect time value: '0000-00-00 10:20:10' -Warning 1292 Truncated incorrect time value: '0000-00-00 10:20:10.440000' select concat('',str_to_date('8:11:2.123456 03-01-02','%H:%i:%S.%f %y-%m-%d')); concat('',str_to_date('8:11:2.123456 03-01-02','%H:%i:%S.%f %y-%m-%d')) 2003-01-02 08:11:02.123456 @@ -470,8 +449,6 @@ 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 @@ -481,7 +458,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-00 58:00:00 +2003-01-02 10:11:12 10:11:12 2003-01-02 0000-00-02 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/errors.result b/mysql-test/r/errors.result index 0c84f24a2e4..94debb1785f 100644 --- a/mysql-test/r/errors.result +++ b/mysql-test/r/errors.result @@ -28,3 +28,16 @@ ERROR 42000: Display width out of range for column 'a' (max = 255) set sql_mode='traditional'; create table t1 (a varchar(66000)); ERROR 42000: Column length too big for column 'a' (max = 65535); use BLOB or TEXT instead +set sql_mode=default; +CREATE TABLE t1 (a INT); +SELECT a FROM t1 WHERE a IN(1, (SELECT IF(1=0,1,2/0))); +a +INSERT INTO t1 VALUES(1); +SELECT a FROM t1 WHERE a IN(1, (SELECT IF(1=0,1,2/0))); +a +1 +INSERT INTO t1 VALUES(2),(3); +SELECT a FROM t1 WHERE a IN(1, (SELECT IF(1=0,1,2/0))); +a +1 +DROP TABLE t1; diff --git a/mysql-test/r/flush2.result b/mysql-test/r/flush2.result index 7c94219fd71..13bcc371ef6 100644 --- a/mysql-test/r/flush2.result +++ b/mysql-test/r/flush2.result @@ -1,24 +1,12 @@ flush logs; set global expire_logs_days = 3; -show variables like 'log%'; +show variables like 'log_bin%'; Variable_name Value -log ON log_bin OFF log_bin_trust_function_creators ON -log_error -log_queries_not_using_indexes OFF -log_slave_updates OFF -log_slow_queries OFF -log_warnings 1 flush logs; -show variables like 'log%'; +show variables like 'log_bin%'; Variable_name Value -log ON log_bin OFF log_bin_trust_function_creators ON -log_error -log_queries_not_using_indexes OFF -log_slave_updates OFF -log_slow_queries OFF -log_warnings 1 set global expire_logs_days = 0; diff --git a/mysql-test/r/fulltext_left_join.result b/mysql-test/r/fulltext_left_join.result index fdf11c14cc4..ea4cacf2fab 100644 --- a/mysql-test/r/fulltext_left_join.result +++ b/mysql-test/r/fulltext_left_join.result @@ -90,3 +90,10 @@ id link name relevance 1 1 string 0 2 0 string 0 DROP TABLE t1,t2; +CREATE TABLE t1 (a INT); +CREATE TABLE t2 (b INT, c TEXT, KEY(b)); +INSERT INTO t1 VALUES(1); +INSERT INTO t2(b,c) VALUES(2,'castle'),(3,'castle'); +SELECT * FROM t1 LEFT JOIN t2 ON a=b WHERE MATCH(c) AGAINST('+castle' IN BOOLEAN MODE); +a b c +DROP TABLE t1, t2; diff --git a/mysql-test/r/func_group.result b/mysql-test/r/func_group.result index e421da1c462..f245d272ede 100644 --- a/mysql-test/r/func_group.result +++ b/mysql-test/r/func_group.result @@ -1296,6 +1296,15 @@ select var_samp(e) as '0.5', var_pop(e) as '0.25' from bug22555; 0.5 0.25 0.5000 0.2500 drop table bug22555; +create table t1 (a decimal(20)); +insert into t1 values (12345678901234567890); +select count(a) from t1; +count(a) +1 +select count(distinct a) from t1; +count(distinct a) +1 +drop table t1; CREATE TABLE t1 (a INT, b INT); INSERT INTO t1 VALUES (1,1),(1,2),(1,3),(1,4),(1,5),(1,6),(1,7),(1,8); INSERT INTO t1 SELECT a, b+8 FROM t1; diff --git a/mysql-test/r/func_str.result b/mysql-test/r/func_str.result index e06e7ffe00c..92265c77984 100644 --- a/mysql-test/r/func_str.result +++ b/mysql-test/r/func_str.result @@ -1964,6 +1964,15 @@ A B tire 0 # # 1 ## ## 2 +SELECT REPEAT('0', CAST(0 AS UNSIGNED)); +REPEAT('0', CAST(0 AS UNSIGNED)) + +SELECT REPEAT('0', -2); +REPEAT('0', -2) + +SELECT REPEAT('0', 2); +REPEAT('0', 2) +00 DROP TABLE t1; SELECT UNHEX('G'); UNHEX('G') diff --git a/mysql-test/r/gis.result b/mysql-test/r/gis.result index 749c84a1a6f..73e5b054f80 100644 --- a/mysql-test/r/gis.result +++ b/mysql-test/r/gis.result @@ -385,7 +385,7 @@ Intersects(g1.g, g2.g) as i, Crosses(g1.g, g2.g) as r FROM gis_geometrycollection g1, gis_geometrycollection g2 ORDER BY first, second; first second w c o e d t i r 120 120 1 1 0 1 0 0 1 0 -120 121 0 0 0 0 0 0 1 0 +120 121 0 0 1 0 0 0 1 0 121 120 0 0 1 0 0 0 1 0 121 121 1 1 0 1 0 0 1 0 explain extended SELECT g1.fid as first, g2.fid as second, @@ -780,3 +780,88 @@ Field Type Null Key Default Extra a geometry YES NULL DROP VIEW v1,v2; DROP TABLE t1; +create table t1 (name VARCHAR(100), square GEOMETRY); +INSERT INTO t1 VALUES("center", GeomFromText('POLYGON (( 0 0, 0 2, 2 2, 2 0, 0 0))')); +INSERT INTO t1 VALUES("small", GeomFromText('POLYGON (( 0 0, 0 1, 1 1, 1 0, 0 0))')); +INSERT INTO t1 VALUES("big", GeomFromText('POLYGON (( 0 0, 0 3, 3 3, 3 0, 0 0))')); +INSERT INTO t1 VALUES("up", GeomFromText('POLYGON (( 0 1, 0 3, 2 3, 2 1, 0 1))')); +INSERT INTO t1 VALUES("up2", GeomFromText('POLYGON (( 0 2, 0 4, 2 4, 2 2, 0 2))')); +INSERT INTO t1 VALUES("up3", GeomFromText('POLYGON (( 0 3, 0 5, 2 5, 2 3, 0 3))')); +INSERT INTO t1 VALUES("down", GeomFromText('POLYGON (( 0 -1, 0 1, 2 1, 2 -1, 0 -1))')); +INSERT INTO t1 VALUES("down2", GeomFromText('POLYGON (( 0 -2, 0 0, 2 0, 2 -2, 0 -2))')); +INSERT INTO t1 VALUES("down3", GeomFromText('POLYGON (( 0 -3, 0 -1, 2 -1, 2 -3, 0 -3))')); +INSERT INTO t1 VALUES("right", GeomFromText('POLYGON (( 1 0, 1 2, 3 2, 3 0, 1 0))')); +INSERT INTO t1 VALUES("right2", GeomFromText('POLYGON (( 2 0, 2 2, 4 2, 4 0, 2 0))')); +INSERT INTO t1 VALUES("right3", GeomFromText('POLYGON (( 3 0, 3 2, 5 2, 5 0, 3 0))')); +INSERT INTO t1 VALUES("left", GeomFromText('POLYGON (( -1 0, -1 2, 1 2, 1 0, -1 0))')); +INSERT INTO t1 VALUES("left2", GeomFromText('POLYGON (( -2 0, -2 2, 0 2, 0 0, -2 0))')); +INSERT INTO t1 VALUES("left3", GeomFromText('POLYGON (( -3 0, -3 2, -1 2, -1 0, -3 0))')); +SELECT GROUP_CONCAT(a2.name ORDER BY a2.name) AS mbrcontains FROM t1 a1 JOIN t1 a2 ON MBRContains( a1.square, a2.square) WHERE a1.name = "center" GROUP BY a1.name; +mbrcontains +center,small +SELECT GROUP_CONCAT(a2.name ORDER BY a2.name) AS mbrdisjoint FROM t1 a1 JOIN t1 a2 ON MBRDisjoint( a1.square, a2.square) WHERE a1.name = "center" GROUP BY a1.name; +mbrdisjoint +down3,left3,right3,up3 +SELECT GROUP_CONCAT(a2.name ORDER BY a2.name) AS mbrequal FROM t1 a1 JOIN t1 a2 ON MBREqual( a1.square, a2.square) WHERE a1.name = "center" GROUP BY a1.name; +mbrequal +center +SELECT GROUP_CONCAT(a2.name ORDER BY a2.name) AS mbrintersect FROM t1 a1 JOIN t1 a2 ON MBRIntersects( a1.square, a2.square) WHERE a1.name = "center" GROUP BY a1.name; +mbrintersect +big,center,down,down2,left,left2,right,right2,small,up,up2 +SELECT GROUP_CONCAT(a2.name ORDER BY a2.name) AS mbroverlaps FROM t1 a1 JOIN t1 a2 ON MBROverlaps( a1.square, a2.square) WHERE a1.name = "center" GROUP BY a1.name; +mbroverlaps +down,left,right,up +SELECT GROUP_CONCAT(a2.name ORDER BY a2.name) AS mbrtouches FROM t1 a1 JOIN t1 a2 ON MBRTouches( a1.square, a2.square) WHERE a1.name = "center" GROUP BY a1.name; +mbrtouches +down2,left2,right2,up2 +SELECT GROUP_CONCAT(a2.name ORDER BY a2.name) AS mbrwithin FROM t1 a1 JOIN t1 a2 ON MBRWithin( a1.square, a2.square) WHERE a1.name = "center" GROUP BY a1.name; +mbrwithin +big,center +SELECT GROUP_CONCAT(a2.name ORDER BY a2.name) AS contains FROM t1 a1 JOIN t1 a2 ON Contains( a1.square, a2.square) WHERE a1.name = "center" GROUP BY a1.name; +contains +center,small +SELECT GROUP_CONCAT(a2.name ORDER BY a2.name) AS disjoint FROM t1 a1 JOIN t1 a2 ON Disjoint( a1.square, a2.square) WHERE a1.name = "center" GROUP BY a1.name; +disjoint +down3,left3,right3,up3 +SELECT GROUP_CONCAT(a2.name ORDER BY a2.name) AS equals FROM t1 a1 JOIN t1 a2 ON Equals( a1.square, a2.square) WHERE a1.name = "center" GROUP BY a1.name; +equals +center +SELECT GROUP_CONCAT(a2.name ORDER BY a2.name) AS intersect FROM t1 a1 JOIN t1 a2 ON Intersects( a1.square, a2.square) WHERE a1.name = "center" GROUP BY a1.name; +intersect +big,center,down,down2,left,left2,right,right2,small,up,up2 +SELECT GROUP_CONCAT(a2.name ORDER BY a2.name) AS overlaps FROM t1 a1 JOIN t1 a2 ON Overlaps( a1.square, a2.square) WHERE a1.name = "center" GROUP BY a1.name; +overlaps +down,left,right,up +SELECT GROUP_CONCAT(a2.name ORDER BY a2.name) AS touches FROM t1 a1 JOIN t1 a2 ON Touches( a1.square, a2.square) WHERE a1.name = "center" GROUP BY a1.name; +touches +down2,left2,right2,up2 +SELECT GROUP_CONCAT(a2.name ORDER BY a2.name) AS within FROM t1 a1 JOIN t1 a2 ON Within( a1.square, a2.square) WHERE a1.name = "center" GROUP BY a1.name; +within +big,center +SET @vert1 = GeomFromText('POLYGON ((0 -2, 0 2, 0 -2))'); +SET @horiz1 = GeomFromText('POLYGON ((-2 0, 2 0, -2 0))'); +SET @horiz2 = GeomFromText('POLYGON ((-1 0, 3 0, -1 0))'); +SET @horiz3 = GeomFromText('POLYGON ((2 0, 3 0, 2 0))'); +SET @point1 = GeomFromText('POLYGON ((0 0))'); +SET @point2 = GeomFromText('POLYGON ((-2 0))'); +SELECT GROUP_CONCAT(a1.name ORDER BY a1.name) AS overlaps FROM t1 a1 WHERE Overlaps(a1.square, @vert1) GROUP BY a1.name; +overlaps +SELECT GROUP_CONCAT(a1.name ORDER BY a1.name) AS overlaps FROM t1 a1 WHERE Overlaps(a1.square, @horiz1) GROUP BY a1.name; +overlaps +SELECT Overlaps(@horiz1, @vert1) FROM DUAL; +Overlaps(@horiz1, @vert1) +0 +SELECT Overlaps(@horiz1, @horiz2) FROM DUAL; +Overlaps(@horiz1, @horiz2) +1 +SELECT Overlaps(@horiz1, @horiz3) FROM DUAL; +Overlaps(@horiz1, @horiz3) +0 +SELECT Overlaps(@horiz1, @point1) FROM DUAL; +Overlaps(@horiz1, @point1) +0 +SELECT Overlaps(@horiz1, @point2) FROM DUAL; +Overlaps(@horiz1, @point2) +0 +DROP TABLE t1; +End of 5.0 tests diff --git a/mysql-test/r/information_schema.result b/mysql-test/r/information_schema.result index 436bb70d0e7..db703df1f52 100644 --- a/mysql-test/r/information_schema.result +++ b/mysql-test/r/information_schema.result @@ -687,7 +687,7 @@ Warnings: Warning 1356 View 'test.v2' references invalid table(s) or column(s) or function(s) or definer/invoker of view lack rights to use them show create table v3; View Create View -v3 CREATE ALGORITHM=UNDEFINED DEFINER=`root`@`localhost` SQL SECURITY DEFINER VIEW `v3` AS select `test`.`sub1`(1) AS `c` +v3 CREATE ALGORITHM=UNDEFINED DEFINER=`root`@`localhost` SQL SECURITY DEFINER VIEW `v3` AS select `sub1`(1) AS `c` Warnings: Warning 1356 View 'test.v3' references invalid table(s) or column(s) or function(s) or definer/invoker of view lack rights to use them drop view v2; diff --git a/mysql-test/r/innodb.result b/mysql-test/r/innodb.result index 99f0d4100ee..0638152ba42 100644 --- a/mysql-test/r/innodb.result +++ b/mysql-test/r/innodb.result @@ -2968,3 +2968,21 @@ a drop table t2, t1; create table t1 (g geometry not null, spatial gk(g)) engine=innodb; ERROR HY000: The used table type doesn't support SPATIAL indexes +CREATE TABLE t1 (a INT, INDEX(a)) ENGINE=InnoDB; +CREATE TABLE t2 (a INT, INDEX(a)) ENGINE=InnoDB; +INSERT INTO t1 VALUES (1); +INSERT INTO t2 VALUES (1); +ALTER TABLE t2 ADD FOREIGN KEY (a) REFERENCES t1 (a) ON DELETE SET NULL; +ALTER TABLE t2 MODIFY a INT NOT NULL; +ERROR HY000: Error on rename of '#sql-temporary' to './test/t2' (errno: 150) +DELETE FROM t1; +DROP TABLE t2,t1; +CREATE TABLE t1 (a VARCHAR(5) COLLATE utf8_unicode_ci PRIMARY KEY) +ENGINE=InnoDB; +INSERT INTO t1 VALUES (0xEFBCA4EFBCA4EFBCA4); +DELETE FROM t1; +INSERT INTO t1 VALUES ('DDD'); +SELECT * FROM t1; +a +DDD +DROP TABLE t1; diff --git a/mysql-test/r/innodb_gis.result b/mysql-test/r/innodb_gis.result index 41a227a2850..2c62537aa94 100644 --- a/mysql-test/r/innodb_gis.result +++ b/mysql-test/r/innodb_gis.result @@ -392,7 +392,7 @@ Intersects(g1.g, g2.g) as i, Crosses(g1.g, g2.g) as r FROM gis_geometrycollection g1, gis_geometrycollection g2 ORDER BY first, second; first second w c o e d t i r 120 120 1 1 0 1 0 0 1 0 -120 121 0 0 0 0 0 0 1 0 +120 121 0 0 1 0 0 0 1 0 121 120 0 0 1 0 0 0 1 0 121 121 1 1 0 1 0 0 1 0 explain extended SELECT g1.fid as first, g2.fid as second, @@ -456,3 +456,89 @@ ERROR 22003: Cannot get geometry object from data you send to the GEOMETRY field insert into t1 values (pointfromtext('point(1,1)')); ERROR 23000: Column 'fl' cannot be null drop table t1; +End of 4.1 tests +CREATE TABLE t1 (name VARCHAR(100), square GEOMETRY); +INSERT INTO t1 VALUES("center", GeomFromText('POLYGON (( 0 0, 0 2, 2 2, 2 0, 0 0))')); +INSERT INTO t1 VALUES("small", GeomFromText('POLYGON (( 0 0, 0 1, 1 1, 1 0, 0 0))')); +INSERT INTO t1 VALUES("big", GeomFromText('POLYGON (( 0 0, 0 3, 3 3, 3 0, 0 0))')); +INSERT INTO t1 VALUES("up", GeomFromText('POLYGON (( 0 1, 0 3, 2 3, 2 1, 0 1))')); +INSERT INTO t1 VALUES("up2", GeomFromText('POLYGON (( 0 2, 0 4, 2 4, 2 2, 0 2))')); +INSERT INTO t1 VALUES("up3", GeomFromText('POLYGON (( 0 3, 0 5, 2 5, 2 3, 0 3))')); +INSERT INTO t1 VALUES("down", GeomFromText('POLYGON (( 0 -1, 0 1, 2 1, 2 -1, 0 -1))')); +INSERT INTO t1 VALUES("down2", GeomFromText('POLYGON (( 0 -2, 0 0, 2 0, 2 -2, 0 -2))')); +INSERT INTO t1 VALUES("down3", GeomFromText('POLYGON (( 0 -3, 0 -1, 2 -1, 2 -3, 0 -3))')); +INSERT INTO t1 VALUES("right", GeomFromText('POLYGON (( 1 0, 1 2, 3 2, 3 0, 1 0))')); +INSERT INTO t1 VALUES("right2", GeomFromText('POLYGON (( 2 0, 2 2, 4 2, 4 0, 2 0))')); +INSERT INTO t1 VALUES("right3", GeomFromText('POLYGON (( 3 0, 3 2, 5 2, 5 0, 3 0))')); +INSERT INTO t1 VALUES("left", GeomFromText('POLYGON (( -1 0, -1 2, 1 2, 1 0, -1 0))')); +INSERT INTO t1 VALUES("left2", GeomFromText('POLYGON (( -2 0, -2 2, 0 2, 0 0, -2 0))')); +INSERT INTO t1 VALUES("left3", GeomFromText('POLYGON (( -3 0, -3 2, -1 2, -1 0, -3 0))')); +SELECT GROUP_CONCAT(a2.name ORDER BY a2.name) AS mbrcontains FROM t1 a1 JOIN t1 a2 ON MBRContains( a1.square, a2.square) WHERE a1.name = "center" GROUP BY a1.name; +mbrcontains +center,small +SELECT GROUP_CONCAT(a2.name ORDER BY a2.name) AS mbrdisjoint FROM t1 a1 JOIN t1 a2 ON MBRDisjoint( a1.square, a2.square) WHERE a1.name = "center" GROUP BY a1.name; +mbrdisjoint +down3,left3,right3,up3 +SELECT GROUP_CONCAT(a2.name ORDER BY a2.name) AS mbrequal FROM t1 a1 JOIN t1 a2 ON MBREqual( a1.square, a2.square) WHERE a1.name = "center" GROUP BY a1.name; +mbrequal +center +SELECT GROUP_CONCAT(a2.name ORDER BY a2.name) AS mbrintersect FROM t1 a1 JOIN t1 a2 ON MBRIntersects( a1.square, a2.square) WHERE a1.name = "center" GROUP BY a1.name; +mbrintersect +big,center,down,down2,left,left2,right,right2,small,up,up2 +SELECT GROUP_CONCAT(a2.name ORDER BY a2.name) AS mbroverlaps FROM t1 a1 JOIN t1 a2 ON MBROverlaps( a1.square, a2.square) WHERE a1.name = "center" GROUP BY a1.name; +mbroverlaps +down,left,right,up +SELECT GROUP_CONCAT(a2.name ORDER BY a2.name) AS mbrtouches FROM t1 a1 JOIN t1 a2 ON MBRTouches( a1.square, a2.square) WHERE a1.name = "center" GROUP BY a1.name; +mbrtouches +down2,left2,right2,up2 +SELECT GROUP_CONCAT(a2.name ORDER BY a2.name) AS mbrwithin FROM t1 a1 JOIN t1 a2 ON MBRWithin( a1.square, a2.square) WHERE a1.name = "center" GROUP BY a1.name; +mbrwithin +big,center +SELECT GROUP_CONCAT(a2.name ORDER BY a2.name) AS contains FROM t1 a1 JOIN t1 a2 ON Contains( a1.square, a2.square) WHERE a1.name = "center" GROUP BY a1.name; +contains +center,small +SELECT GROUP_CONCAT(a2.name ORDER BY a2.name) AS disjoint FROM t1 a1 JOIN t1 a2 ON Disjoint( a1.square, a2.square) WHERE a1.name = "center" GROUP BY a1.name; +disjoint +down3,left3,right3,up3 +SELECT GROUP_CONCAT(a2.name ORDER BY a2.name) AS equals FROM t1 a1 JOIN t1 a2 ON Equals( a1.square, a2.square) WHERE a1.name = "center" GROUP BY a1.name; +equals +center +SELECT GROUP_CONCAT(a2.name ORDER BY a2.name) AS intersect FROM t1 a1 JOIN t1 a2 ON Intersects( a1.square, a2.square) WHERE a1.name = "center" GROUP BY a1.name; +intersect +big,center,down,down2,left,left2,right,right2,small,up,up2 +SELECT GROUP_CONCAT(a2.name ORDER BY a2.name) AS overlaps FROM t1 a1 JOIN t1 a2 ON Overlaps( a1.square, a2.square) WHERE a1.name = "center" GROUP BY a1.name; +overlaps +down,left,right,up +SELECT GROUP_CONCAT(a2.name ORDER BY a2.name) AS touches FROM t1 a1 JOIN t1 a2 ON Touches( a1.square, a2.square) WHERE a1.name = "center" GROUP BY a1.name; +touches +down2,left2,right2,up2 +SELECT GROUP_CONCAT(a2.name ORDER BY a2.name) AS within FROM t1 a1 JOIN t1 a2 ON Within( a1.square, a2.square) WHERE a1.name = "center" GROUP BY a1.name; +within +big,center +SET @vert1 = GeomFromText('POLYGON ((0 -2, 0 2, 0 -2))'); +SET @horiz1 = GeomFromText('POLYGON ((-2 0, 2 0, -2 0))'); +SET @horiz2 = GeomFromText('POLYGON ((-1 0, 3 0, -1 0))'); +SET @horiz3 = GeomFromText('POLYGON ((2 0, 3 0, 2 0))'); +SET @point1 = GeomFromText('POLYGON ((0 0))'); +SET @point2 = GeomFromText('POLYGON ((-2 0))'); +SELECT GROUP_CONCAT(a1.name ORDER BY a1.name) AS overlaps FROM t1 a1 WHERE Overlaps(a1.square, @vert1) GROUP BY a1.name; +overlaps +SELECT GROUP_CONCAT(a1.name ORDER BY a1.name) AS overlaps FROM t1 a1 WHERE Overlaps(a1.square, @horiz1) GROUP BY a1.name; +overlaps +SELECT Overlaps(@horiz1, @vert1) FROM DUAL; +Overlaps(@horiz1, @vert1) +0 +SELECT Overlaps(@horiz1, @horiz2) FROM DUAL; +Overlaps(@horiz1, @horiz2) +1 +SELECT Overlaps(@horiz1, @horiz3) FROM DUAL; +Overlaps(@horiz1, @horiz3) +0 +SELECT Overlaps(@horiz1, @point1) FROM DUAL; +Overlaps(@horiz1, @point1) +0 +SELECT Overlaps(@horiz1, @point2) FROM DUAL; +Overlaps(@horiz1, @point2) +0 +DROP TABLE t1; +End of 5.0 tests diff --git a/mysql-test/r/loaddata.result b/mysql-test/r/loaddata.result index bef483569d4..0478e48025f 100644 --- a/mysql-test/r/loaddata.result +++ b/mysql-test/r/loaddata.result @@ -156,3 +156,12 @@ select load_file("MYSQL_TEST_DIR/t/loaddata.test"); load_file("MYSQL_TEST_DIR/t/loaddata.test") NULL drop table t1, t2; +create table t1(f1 int); +insert into t1 values(1),(null); +create table t2(f2 int auto_increment primary key); +select * from t2; +f2 +1 +2 +SET @@SQL_MODE=@OLD_SQL_MODE; +drop table t1,t2; diff --git a/mysql-test/r/mysqlbinlog.result b/mysql-test/r/mysqlbinlog.result index 217d3e5f64a..a50d131cca8 100644 --- a/mysql-test/r/mysqlbinlog.result +++ b/mysql-test/r/mysqlbinlog.result @@ -289,23 +289,23 @@ SET @@session.sql_mode=0/*!*/; SET @@session.character_set_client=8,@@session.collation_connection=8,@@session.collation_server=8/*!*/; create table t1 (a varchar(64) character set utf8)/*!*/; SET TIMESTAMP=1000000000/*!*/; -load data LOCAL INFILE 'MYSQL_TMP_DIR/SQL_LOAD_MB-6-0' INTO table t1/*!*/; +load data LOCAL INFILE 'MYSQLTEST_VARDIR/tmp/SQL_LOAD_MB-6-0' INTO table t1/*!*/; SET TIMESTAMP=1000000000/*!*/; SET @@session.collation_database=7/*!*/; -load data LOCAL INFILE 'MYSQL_TMP_DIR/SQL_LOAD_MB-7-0' INTO table t1/*!*/; +load data LOCAL INFILE 'MYSQLTEST_VARDIR/tmp/SQL_LOAD_MB-7-0' INTO table t1/*!*/; SET TIMESTAMP=1000000000/*!*/; SET @@session.collation_database=DEFAULT/*!*/; -load data LOCAL INFILE 'MYSQL_TMP_DIR/SQL_LOAD_MB-8-0' INTO table t1/*!*/; +load data LOCAL INFILE 'MYSQLTEST_VARDIR/tmp/SQL_LOAD_MB-8-0' INTO table t1/*!*/; SET TIMESTAMP=1000000000/*!*/; -load data LOCAL INFILE 'MYSQL_TMP_DIR/SQL_LOAD_MB-9-0' INTO table t1/*!*/; +load data LOCAL INFILE 'MYSQLTEST_VARDIR/tmp/SQL_LOAD_MB-9-0' INTO table t1/*!*/; SET TIMESTAMP=1000000000/*!*/; SET @@session.collation_database=7/*!*/; -load data LOCAL INFILE 'MYSQL_TMP_DIR/SQL_LOAD_MB-a-0' INTO table t1/*!*/; +load data LOCAL INFILE 'MYSQLTEST_VARDIR/tmp/SQL_LOAD_MB-a-0' INTO table t1/*!*/; SET TIMESTAMP=1000000000/*!*/; SET @@session.collation_database=DEFAULT/*!*/; -load data LOCAL INFILE 'MYSQL_TMP_DIR/SQL_LOAD_MB-b-0' INTO table t1/*!*/; +load data LOCAL INFILE 'MYSQLTEST_VARDIR/tmp/SQL_LOAD_MB-b-0' INTO table t1/*!*/; SET TIMESTAMP=1000000000/*!*/; -load data LOCAL INFILE 'MYSQL_TMP_DIR/SQL_LOAD_MB-c-0' INTO table t1 character set koi8r/*!*/; +load data LOCAL INFILE 'MYSQLTEST_VARDIR/tmp/SQL_LOAD_MB-c-0' INTO table t1 character set koi8r/*!*/; SET TIMESTAMP=1000000000/*!*/; drop table t1/*!*/; DELIMITER ; diff --git a/mysql-test/r/mysqldump.result b/mysql-test/r/mysqldump.result index 2d32984e4ef..5caaa9264d0 100644 --- a/mysql-test/r/mysqldump.result +++ b/mysql-test/r/mysqldump.result @@ -1567,29 +1567,17 @@ create table t3(a varchar(30) primary key, b int not null); test_sequence ------ Testing with illegal table names ------ mysqldump: Couldn't find table: "\d-2-1.sql" - mysqldump: Couldn't find table: "\t1" - mysqldump: Couldn't find table: "\t1" - mysqldump: Couldn't find table: "\\t1" - mysqldump: Couldn't find table: "t\1" - mysqldump: Couldn't find table: "t\1" - mysqldump: Couldn't find table: "t/1" - mysqldump: Couldn't find table: "T_1" - mysqldump: Couldn't find table: "T%1" - mysqldump: Couldn't find table: "T'1" - mysqldump: Couldn't find table: "T_1" - mysqldump: Couldn't find table: "T_" - test_sequence ------ Testing with illegal database names ------ mysqldump: Got error: 1049: Unknown database 'mysqldump_test_d' when selecting the database @@ -3218,5 +3206,82 @@ INSERT INTO t1 VALUES(1,0xff00fef0); </mysqldump> DROP TABLE t1; # +# Bug#26346: stack + buffer overrun in mysqldump +# +CREATE TABLE t1(a int); +INSERT INTO t1 VALUES (1), (2); +mysqldump: Input filename or options too long: aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa +DROP TABLE t1; +CREATE TABLE t2 (a int); +CREATE TABLE t3 (a int); +CREATE TABLE t1 (a int) ENGINE=merge UNION=(t2, t3); + +/*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */; +/*!40101 SET @OLD_CHARACTER_SET_RESULTS=@@CHARACTER_SET_RESULTS */; +/*!40101 SET @OLD_COLLATION_CONNECTION=@@COLLATION_CONNECTION */; +/*!40101 SET NAMES utf8 */; +/*!40103 SET @OLD_TIME_ZONE=@@TIME_ZONE */; +/*!40103 SET TIME_ZONE='+00:00' */; +/*!40014 SET @OLD_UNIQUE_CHECKS=@@UNIQUE_CHECKS, UNIQUE_CHECKS=0 */; +/*!40014 SET @OLD_FOREIGN_KEY_CHECKS=@@FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS=0 */; +/*!40101 SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE='NO_AUTO_VALUE_ON_ZERO' */; +/*!40111 SET @OLD_SQL_NOTES=@@SQL_NOTES, SQL_NOTES=0 */; +DROP TABLE IF EXISTS `t1`; +CREATE TABLE `t1` ( + `a` int(11) default NULL +) ENGINE=MRG_MyISAM DEFAULT CHARSET=latin1 UNION=(`t2`,`t3`); +DROP TABLE IF EXISTS `t2`; +CREATE TABLE `t2` ( + `a` int(11) default NULL +) ENGINE=MyISAM DEFAULT CHARSET=latin1; + +LOCK TABLES `t2` WRITE; +/*!40000 ALTER TABLE `t2` DISABLE KEYS */; +/*!40000 ALTER TABLE `t2` ENABLE KEYS */; +UNLOCK TABLES; +DROP TABLE IF EXISTS `t3`; +CREATE TABLE `t3` ( + `a` int(11) default NULL +) ENGINE=MyISAM DEFAULT CHARSET=latin1; + +LOCK TABLES `t3` WRITE; +/*!40000 ALTER TABLE `t3` DISABLE KEYS */; +/*!40000 ALTER TABLE `t3` ENABLE KEYS */; +UNLOCK TABLES; +/*!40103 SET TIME_ZONE=@OLD_TIME_ZONE */; + +/*!40101 SET SQL_MODE=@OLD_SQL_MODE */; +/*!40014 SET FOREIGN_KEY_CHECKS=@OLD_FOREIGN_KEY_CHECKS */; +/*!40014 SET UNIQUE_CHECKS=@OLD_UNIQUE_CHECKS */; +/*!40101 SET CHARACTER_SET_CLIENT=@OLD_CHARACTER_SET_CLIENT */; +/*!40101 SET CHARACTER_SET_RESULTS=@OLD_CHARACTER_SET_RESULTS */; +/*!40101 SET COLLATION_CONNECTION=@OLD_COLLATION_CONNECTION */; +/*!40111 SET SQL_NOTES=@OLD_SQL_NOTES */; + +DROP TABLE t1, t2, t3; +# +# Bug #23491: MySQLDump prefix function call in a view by database name +# +create database bug23491_original; +create database bug23491_restore; +use bug23491_original; +create table t1 (c1 int); +create view v1 as select * from t1; +create procedure p1() select 1; +create function f1() returns int return 1; +create view v2 as select f1(); +create function f2() returns int return f1(); +create view v3 as select bug23491_original.f1(); +use bug23491_restore; +show create view bug23491_restore.v2; +View Create View +v2 CREATE ALGORITHM=UNDEFINED DEFINER=`root`@`localhost` SQL SECURITY DEFINER VIEW `v2` AS select `f1`() AS `f1()` +show create view bug23491_restore.v3; +View Create View +v3 CREATE ALGORITHM=UNDEFINED DEFINER=`root`@`localhost` SQL SECURITY DEFINER VIEW `v3` AS select `bug23491_original`.`f1`() AS `bug23491_original.f1()` +drop database bug23491_original; +drop database bug23491_restore; +use test; +# # End of 5.0 tests # diff --git a/mysql-test/r/ndb_autodiscover.result b/mysql-test/r/ndb_autodiscover.result index 6d1b7eb152d..01ea884a8ba 100644 --- a/mysql-test/r/ndb_autodiscover.result +++ b/mysql-test/r/ndb_autodiscover.result @@ -382,7 +382,7 @@ create table t1 (a int primary key) engine=ndb; select * from t1; a select * from t1; -ERROR HY000: Can't lock file (errno: 4009) +ERROR HY000: Can't lock file (errno: 157) use test; drop database test_only_ndb_tables; CREATE TABLE t9 ( diff --git a/mysql-test/r/ndb_gis.result b/mysql-test/r/ndb_gis.result index bdbbc65dd85..ec064ace651 100644 --- a/mysql-test/r/ndb_gis.result +++ b/mysql-test/r/ndb_gis.result @@ -392,7 +392,7 @@ Intersects(g1.g, g2.g) as i, Crosses(g1.g, g2.g) as r FROM gis_geometrycollection g1, gis_geometrycollection g2 ORDER BY first, second; first second w c o e d t i r 120 120 1 1 0 1 0 0 1 0 -120 121 0 0 0 0 0 0 1 0 +120 121 0 0 1 0 0 0 1 0 121 120 0 0 1 0 0 0 1 0 121 121 1 1 0 1 0 0 1 0 explain extended SELECT g1.fid as first, g2.fid as second, @@ -456,6 +456,92 @@ ERROR 22003: Cannot get geometry object from data you send to the GEOMETRY field insert into t1 values (pointfromtext('point(1,1)')); ERROR 23000: Column 'fl' cannot be null drop table t1; +End of 4.1 tests +CREATE TABLE t1 (name VARCHAR(100), square GEOMETRY); +INSERT INTO t1 VALUES("center", GeomFromText('POLYGON (( 0 0, 0 2, 2 2, 2 0, 0 0))')); +INSERT INTO t1 VALUES("small", GeomFromText('POLYGON (( 0 0, 0 1, 1 1, 1 0, 0 0))')); +INSERT INTO t1 VALUES("big", GeomFromText('POLYGON (( 0 0, 0 3, 3 3, 3 0, 0 0))')); +INSERT INTO t1 VALUES("up", GeomFromText('POLYGON (( 0 1, 0 3, 2 3, 2 1, 0 1))')); +INSERT INTO t1 VALUES("up2", GeomFromText('POLYGON (( 0 2, 0 4, 2 4, 2 2, 0 2))')); +INSERT INTO t1 VALUES("up3", GeomFromText('POLYGON (( 0 3, 0 5, 2 5, 2 3, 0 3))')); +INSERT INTO t1 VALUES("down", GeomFromText('POLYGON (( 0 -1, 0 1, 2 1, 2 -1, 0 -1))')); +INSERT INTO t1 VALUES("down2", GeomFromText('POLYGON (( 0 -2, 0 0, 2 0, 2 -2, 0 -2))')); +INSERT INTO t1 VALUES("down3", GeomFromText('POLYGON (( 0 -3, 0 -1, 2 -1, 2 -3, 0 -3))')); +INSERT INTO t1 VALUES("right", GeomFromText('POLYGON (( 1 0, 1 2, 3 2, 3 0, 1 0))')); +INSERT INTO t1 VALUES("right2", GeomFromText('POLYGON (( 2 0, 2 2, 4 2, 4 0, 2 0))')); +INSERT INTO t1 VALUES("right3", GeomFromText('POLYGON (( 3 0, 3 2, 5 2, 5 0, 3 0))')); +INSERT INTO t1 VALUES("left", GeomFromText('POLYGON (( -1 0, -1 2, 1 2, 1 0, -1 0))')); +INSERT INTO t1 VALUES("left2", GeomFromText('POLYGON (( -2 0, -2 2, 0 2, 0 0, -2 0))')); +INSERT INTO t1 VALUES("left3", GeomFromText('POLYGON (( -3 0, -3 2, -1 2, -1 0, -3 0))')); +SELECT GROUP_CONCAT(a2.name ORDER BY a2.name) AS mbrcontains FROM t1 a1 JOIN t1 a2 ON MBRContains( a1.square, a2.square) WHERE a1.name = "center" GROUP BY a1.name; +mbrcontains +center,small +SELECT GROUP_CONCAT(a2.name ORDER BY a2.name) AS mbrdisjoint FROM t1 a1 JOIN t1 a2 ON MBRDisjoint( a1.square, a2.square) WHERE a1.name = "center" GROUP BY a1.name; +mbrdisjoint +down3,left3,right3,up3 +SELECT GROUP_CONCAT(a2.name ORDER BY a2.name) AS mbrequal FROM t1 a1 JOIN t1 a2 ON MBREqual( a1.square, a2.square) WHERE a1.name = "center" GROUP BY a1.name; +mbrequal +center +SELECT GROUP_CONCAT(a2.name ORDER BY a2.name) AS mbrintersect FROM t1 a1 JOIN t1 a2 ON MBRIntersects( a1.square, a2.square) WHERE a1.name = "center" GROUP BY a1.name; +mbrintersect +big,center,down,down2,left,left2,right,right2,small,up,up2 +SELECT GROUP_CONCAT(a2.name ORDER BY a2.name) AS mbroverlaps FROM t1 a1 JOIN t1 a2 ON MBROverlaps( a1.square, a2.square) WHERE a1.name = "center" GROUP BY a1.name; +mbroverlaps +down,left,right,up +SELECT GROUP_CONCAT(a2.name ORDER BY a2.name) AS mbrtouches FROM t1 a1 JOIN t1 a2 ON MBRTouches( a1.square, a2.square) WHERE a1.name = "center" GROUP BY a1.name; +mbrtouches +down2,left2,right2,up2 +SELECT GROUP_CONCAT(a2.name ORDER BY a2.name) AS mbrwithin FROM t1 a1 JOIN t1 a2 ON MBRWithin( a1.square, a2.square) WHERE a1.name = "center" GROUP BY a1.name; +mbrwithin +big,center +SELECT GROUP_CONCAT(a2.name ORDER BY a2.name) AS contains FROM t1 a1 JOIN t1 a2 ON Contains( a1.square, a2.square) WHERE a1.name = "center" GROUP BY a1.name; +contains +center,small +SELECT GROUP_CONCAT(a2.name ORDER BY a2.name) AS disjoint FROM t1 a1 JOIN t1 a2 ON Disjoint( a1.square, a2.square) WHERE a1.name = "center" GROUP BY a1.name; +disjoint +down3,left3,right3,up3 +SELECT GROUP_CONCAT(a2.name ORDER BY a2.name) AS equals FROM t1 a1 JOIN t1 a2 ON Equals( a1.square, a2.square) WHERE a1.name = "center" GROUP BY a1.name; +equals +center +SELECT GROUP_CONCAT(a2.name ORDER BY a2.name) AS intersect FROM t1 a1 JOIN t1 a2 ON Intersects( a1.square, a2.square) WHERE a1.name = "center" GROUP BY a1.name; +intersect +big,center,down,down2,left,left2,right,right2,small,up,up2 +SELECT GROUP_CONCAT(a2.name ORDER BY a2.name) AS overlaps FROM t1 a1 JOIN t1 a2 ON Overlaps( a1.square, a2.square) WHERE a1.name = "center" GROUP BY a1.name; +overlaps +down,left,right,up +SELECT GROUP_CONCAT(a2.name ORDER BY a2.name) AS touches FROM t1 a1 JOIN t1 a2 ON Touches( a1.square, a2.square) WHERE a1.name = "center" GROUP BY a1.name; +touches +down2,left2,right2,up2 +SELECT GROUP_CONCAT(a2.name ORDER BY a2.name) AS within FROM t1 a1 JOIN t1 a2 ON Within( a1.square, a2.square) WHERE a1.name = "center" GROUP BY a1.name; +within +big,center +SET @vert1 = GeomFromText('POLYGON ((0 -2, 0 2, 0 -2))'); +SET @horiz1 = GeomFromText('POLYGON ((-2 0, 2 0, -2 0))'); +SET @horiz2 = GeomFromText('POLYGON ((-1 0, 3 0, -1 0))'); +SET @horiz3 = GeomFromText('POLYGON ((2 0, 3 0, 2 0))'); +SET @point1 = GeomFromText('POLYGON ((0 0))'); +SET @point2 = GeomFromText('POLYGON ((-2 0))'); +SELECT GROUP_CONCAT(a1.name ORDER BY a1.name) AS overlaps FROM t1 a1 WHERE Overlaps(a1.square, @vert1) GROUP BY a1.name; +overlaps +SELECT GROUP_CONCAT(a1.name ORDER BY a1.name) AS overlaps FROM t1 a1 WHERE Overlaps(a1.square, @horiz1) GROUP BY a1.name; +overlaps +SELECT Overlaps(@horiz1, @vert1) FROM DUAL; +Overlaps(@horiz1, @vert1) +0 +SELECT Overlaps(@horiz1, @horiz2) FROM DUAL; +Overlaps(@horiz1, @horiz2) +1 +SELECT Overlaps(@horiz1, @horiz3) FROM DUAL; +Overlaps(@horiz1, @horiz3) +0 +SELECT Overlaps(@horiz1, @point1) FROM DUAL; +Overlaps(@horiz1, @point1) +0 +SELECT Overlaps(@horiz1, @point2) FROM DUAL; +Overlaps(@horiz1, @point2) +0 +DROP TABLE t1; +End of 5.0 tests set engine_condition_pushdown = on; DROP TABLE IF EXISTS t1, gis_point, gis_line, gis_polygon, gis_multi_point, gis_multi_line, gis_multi_polygon, gis_geometrycollection, gis_geometry; CREATE TABLE gis_point (fid INTEGER, g POINT); @@ -850,7 +936,7 @@ Intersects(g1.g, g2.g) as i, Crosses(g1.g, g2.g) as r FROM gis_geometrycollection g1, gis_geometrycollection g2 ORDER BY first, second; first second w c o e d t i r 120 120 1 1 0 1 0 0 1 0 -120 121 0 0 0 0 0 0 1 0 +120 121 0 0 1 0 0 0 1 0 121 120 0 0 1 0 0 0 1 0 121 121 1 1 0 1 0 0 1 0 explain extended SELECT g1.fid as first, g2.fid as second, @@ -914,3 +1000,89 @@ ERROR 22003: Cannot get geometry object from data you send to the GEOMETRY field insert into t1 values (pointfromtext('point(1,1)')); ERROR 23000: Column 'fl' cannot be null drop table t1; +End of 4.1 tests +CREATE TABLE t1 (name VARCHAR(100), square GEOMETRY); +INSERT INTO t1 VALUES("center", GeomFromText('POLYGON (( 0 0, 0 2, 2 2, 2 0, 0 0))')); +INSERT INTO t1 VALUES("small", GeomFromText('POLYGON (( 0 0, 0 1, 1 1, 1 0, 0 0))')); +INSERT INTO t1 VALUES("big", GeomFromText('POLYGON (( 0 0, 0 3, 3 3, 3 0, 0 0))')); +INSERT INTO t1 VALUES("up", GeomFromText('POLYGON (( 0 1, 0 3, 2 3, 2 1, 0 1))')); +INSERT INTO t1 VALUES("up2", GeomFromText('POLYGON (( 0 2, 0 4, 2 4, 2 2, 0 2))')); +INSERT INTO t1 VALUES("up3", GeomFromText('POLYGON (( 0 3, 0 5, 2 5, 2 3, 0 3))')); +INSERT INTO t1 VALUES("down", GeomFromText('POLYGON (( 0 -1, 0 1, 2 1, 2 -1, 0 -1))')); +INSERT INTO t1 VALUES("down2", GeomFromText('POLYGON (( 0 -2, 0 0, 2 0, 2 -2, 0 -2))')); +INSERT INTO t1 VALUES("down3", GeomFromText('POLYGON (( 0 -3, 0 -1, 2 -1, 2 -3, 0 -3))')); +INSERT INTO t1 VALUES("right", GeomFromText('POLYGON (( 1 0, 1 2, 3 2, 3 0, 1 0))')); +INSERT INTO t1 VALUES("right2", GeomFromText('POLYGON (( 2 0, 2 2, 4 2, 4 0, 2 0))')); +INSERT INTO t1 VALUES("right3", GeomFromText('POLYGON (( 3 0, 3 2, 5 2, 5 0, 3 0))')); +INSERT INTO t1 VALUES("left", GeomFromText('POLYGON (( -1 0, -1 2, 1 2, 1 0, -1 0))')); +INSERT INTO t1 VALUES("left2", GeomFromText('POLYGON (( -2 0, -2 2, 0 2, 0 0, -2 0))')); +INSERT INTO t1 VALUES("left3", GeomFromText('POLYGON (( -3 0, -3 2, -1 2, -1 0, -3 0))')); +SELECT GROUP_CONCAT(a2.name ORDER BY a2.name) AS mbrcontains FROM t1 a1 JOIN t1 a2 ON MBRContains( a1.square, a2.square) WHERE a1.name = "center" GROUP BY a1.name; +mbrcontains +center,small +SELECT GROUP_CONCAT(a2.name ORDER BY a2.name) AS mbrdisjoint FROM t1 a1 JOIN t1 a2 ON MBRDisjoint( a1.square, a2.square) WHERE a1.name = "center" GROUP BY a1.name; +mbrdisjoint +down3,left3,right3,up3 +SELECT GROUP_CONCAT(a2.name ORDER BY a2.name) AS mbrequal FROM t1 a1 JOIN t1 a2 ON MBREqual( a1.square, a2.square) WHERE a1.name = "center" GROUP BY a1.name; +mbrequal +center +SELECT GROUP_CONCAT(a2.name ORDER BY a2.name) AS mbrintersect FROM t1 a1 JOIN t1 a2 ON MBRIntersects( a1.square, a2.square) WHERE a1.name = "center" GROUP BY a1.name; +mbrintersect +big,center,down,down2,left,left2,right,right2,small,up,up2 +SELECT GROUP_CONCAT(a2.name ORDER BY a2.name) AS mbroverlaps FROM t1 a1 JOIN t1 a2 ON MBROverlaps( a1.square, a2.square) WHERE a1.name = "center" GROUP BY a1.name; +mbroverlaps +down,left,right,up +SELECT GROUP_CONCAT(a2.name ORDER BY a2.name) AS mbrtouches FROM t1 a1 JOIN t1 a2 ON MBRTouches( a1.square, a2.square) WHERE a1.name = "center" GROUP BY a1.name; +mbrtouches +down2,left2,right2,up2 +SELECT GROUP_CONCAT(a2.name ORDER BY a2.name) AS mbrwithin FROM t1 a1 JOIN t1 a2 ON MBRWithin( a1.square, a2.square) WHERE a1.name = "center" GROUP BY a1.name; +mbrwithin +big,center +SELECT GROUP_CONCAT(a2.name ORDER BY a2.name) AS contains FROM t1 a1 JOIN t1 a2 ON Contains( a1.square, a2.square) WHERE a1.name = "center" GROUP BY a1.name; +contains +center,small +SELECT GROUP_CONCAT(a2.name ORDER BY a2.name) AS disjoint FROM t1 a1 JOIN t1 a2 ON Disjoint( a1.square, a2.square) WHERE a1.name = "center" GROUP BY a1.name; +disjoint +down3,left3,right3,up3 +SELECT GROUP_CONCAT(a2.name ORDER BY a2.name) AS equals FROM t1 a1 JOIN t1 a2 ON Equals( a1.square, a2.square) WHERE a1.name = "center" GROUP BY a1.name; +equals +center +SELECT GROUP_CONCAT(a2.name ORDER BY a2.name) AS intersect FROM t1 a1 JOIN t1 a2 ON Intersects( a1.square, a2.square) WHERE a1.name = "center" GROUP BY a1.name; +intersect +big,center,down,down2,left,left2,right,right2,small,up,up2 +SELECT GROUP_CONCAT(a2.name ORDER BY a2.name) AS overlaps FROM t1 a1 JOIN t1 a2 ON Overlaps( a1.square, a2.square) WHERE a1.name = "center" GROUP BY a1.name; +overlaps +down,left,right,up +SELECT GROUP_CONCAT(a2.name ORDER BY a2.name) AS touches FROM t1 a1 JOIN t1 a2 ON Touches( a1.square, a2.square) WHERE a1.name = "center" GROUP BY a1.name; +touches +down2,left2,right2,up2 +SELECT GROUP_CONCAT(a2.name ORDER BY a2.name) AS within FROM t1 a1 JOIN t1 a2 ON Within( a1.square, a2.square) WHERE a1.name = "center" GROUP BY a1.name; +within +big,center +SET @vert1 = GeomFromText('POLYGON ((0 -2, 0 2, 0 -2))'); +SET @horiz1 = GeomFromText('POLYGON ((-2 0, 2 0, -2 0))'); +SET @horiz2 = GeomFromText('POLYGON ((-1 0, 3 0, -1 0))'); +SET @horiz3 = GeomFromText('POLYGON ((2 0, 3 0, 2 0))'); +SET @point1 = GeomFromText('POLYGON ((0 0))'); +SET @point2 = GeomFromText('POLYGON ((-2 0))'); +SELECT GROUP_CONCAT(a1.name ORDER BY a1.name) AS overlaps FROM t1 a1 WHERE Overlaps(a1.square, @vert1) GROUP BY a1.name; +overlaps +SELECT GROUP_CONCAT(a1.name ORDER BY a1.name) AS overlaps FROM t1 a1 WHERE Overlaps(a1.square, @horiz1) GROUP BY a1.name; +overlaps +SELECT Overlaps(@horiz1, @vert1) FROM DUAL; +Overlaps(@horiz1, @vert1) +0 +SELECT Overlaps(@horiz1, @horiz2) FROM DUAL; +Overlaps(@horiz1, @horiz2) +1 +SELECT Overlaps(@horiz1, @horiz3) FROM DUAL; +Overlaps(@horiz1, @horiz3) +0 +SELECT Overlaps(@horiz1, @point1) FROM DUAL; +Overlaps(@horiz1, @point1) +0 +SELECT Overlaps(@horiz1, @point2) FROM DUAL; +Overlaps(@horiz1, @point2) +0 +DROP TABLE t1; +End of 5.0 tests diff --git a/mysql-test/r/ndb_trigger.result b/mysql-test/r/ndb_trigger.result index 27f83df70c9..562c5120715 100644 --- a/mysql-test/r/ndb_trigger.result +++ b/mysql-test/r/ndb_trigger.result @@ -116,4 +116,175 @@ op a b d 1 1.050000000000000000000000000000 d 2 2.050000000000000000000000000000 drop tables t1, t2, t3; +CREATE TABLE t1 ( +id INT NOT NULL PRIMARY KEY, +xy INT +) ENGINE=ndbcluster; +INSERT INTO t1 VALUES (1, 0); +CREATE TRIGGER t1_update AFTER UPDATE ON t1 FOR EACH ROW BEGIN REPLACE INTO t2 SELECT * FROM t1 WHERE t1.id = NEW.id; END // +CREATE TABLE t2 ( +id INT NOT NULL PRIMARY KEY, +xy INT +) ENGINE=ndbcluster; +INSERT INTO t2 VALUES (2, 0); +CREATE TABLE t3 (id INT NOT NULL PRIMARY KEY) ENGINE=ndbcluster; +INSERT INTO t3 VALUES (1); +CREATE TABLE t4 LIKE t1; +CREATE TRIGGER t4_update AFTER UPDATE ON t4 FOR EACH ROW BEGIN REPLACE INTO t5 SELECT * FROM t4 WHERE t4.id = NEW.id; END // +CREATE TABLE t5 LIKE t2; +UPDATE t1 SET xy = 3 WHERE id = 1; +SELECT xy FROM t1 where id = 1; +xy +3 +SELECT xy FROM t2 where id = 1; +xy +3 +UPDATE t1 SET xy = 4 WHERE id IN (SELECT id FROM t3 WHERE id = 1); +SELECT xy FROM t1 where id = 1; +xy +4 +SELECT xy FROM t2 where id = 1; +xy +4 +INSERT INTO t4 SELECT * FROM t1; +INSERT INTO t5 SELECT * FROM t2; +UPDATE t1,t4 SET t1.xy = 3, t4.xy = 3 WHERE t1.id = 1 AND t4.id = 1; +SELECT xy FROM t1 where id = 1; +xy +3 +SELECT xy FROM t2 where id = 1; +xy +3 +SELECT xy FROM t4 where id = 1; +xy +3 +SELECT xy FROM t5 where id = 1; +xy +3 +UPDATE t1,t4 SET t1.xy = 4, t4.xy = 4 WHERE t1.id IN (SELECT id FROM t3 WHERE id = 1) AND t4.id IN (SELECT id FROM t3 WHERE id = 1); +SELECT xy FROM t1 where id = 1; +xy +4 +SELECT xy FROM t2 where id = 1; +xy +4 +SELECT xy FROM t4 where id = 1; +xy +4 +SELECT xy FROM t5 where id = 1; +xy +4 +INSERT INTO t1 VALUES (1,0) ON DUPLICATE KEY UPDATE xy = 5; +SELECT xy FROM t1 where id = 1; +xy +5 +SELECT xy FROM t2 where id = 1; +xy +5 +DROP TRIGGER t1_update; +DROP TRIGGER t4_update; +CREATE TRIGGER t1_delete AFTER DELETE ON t1 FOR EACH ROW BEGIN REPLACE INTO t2 SELECT * FROM t1 WHERE t1.id > 4; END // +CREATE TRIGGER t4_delete AFTER DELETE ON t4 FOR EACH ROW BEGIN REPLACE INTO t5 SELECT * FROM t4 WHERE t4.id > 4; END // +INSERT INTO t1 VALUES (5, 0),(6,0); +INSERT INTO t2 VALUES (5, 1),(6,1); +INSERT INTO t3 VALUES (5); +SELECT * FROM t1 order by id; +id xy +1 5 +5 0 +6 0 +SELECT * FROM t2 order by id; +id xy +1 5 +2 0 +5 1 +6 1 +DELETE FROM t1 WHERE id IN (SELECT id FROM t3 WHERE id = 5); +SELECT * FROM t1 order by id; +id xy +1 5 +6 0 +SELECT * FROM t2 order by id; +id xy +1 5 +2 0 +5 1 +6 0 +INSERT INTO t1 VALUES (5,0); +UPDATE t2 SET xy = 1 WHERE id = 6; +TRUNCATE t4; +INSERT INTO t4 SELECT * FROM t1; +TRUNCATE t5; +INSERT INTO t5 SELECT * FROM t2; +SELECT * FROM t1 order by id; +id xy +1 5 +5 0 +6 0 +SELECT * FROM t2 order by id; +id xy +1 5 +2 0 +5 1 +6 1 +SELECT * FROM t4 order by id; +id xy +1 5 +5 0 +6 0 +SELECT * FROM t5 order by id; +id xy +1 5 +2 0 +5 1 +6 1 +DELETE FROM t1,t4 USING t1,t3,t4 WHERE t1.id IN (SELECT id FROM t3 WHERE id = 5) AND t4.id IN (SELECT id FROM t3 WHERE id = 5); +SELECT * FROM t1 order by id; +id xy +1 5 +6 0 +SELECT * FROM t2 order by id; +id xy +1 5 +2 0 +5 1 +6 0 +SELECT * FROM t4 order by id; +id xy +1 5 +6 0 +SELECT * FROM t5 order by id; +id xy +1 5 +2 0 +5 1 +6 0 +INSERT INTO t1 VALUES (5, 0); +REPLACE INTO t2 VALUES (6,1); +SELECT * FROM t1 order by id; +id xy +1 5 +5 0 +6 0 +SELECT * FROM t2 order by id; +id xy +1 5 +2 0 +5 1 +6 1 +REPLACE INTO t1 VALUES (5, 1); +SELECT * FROM t1 order by id; +id xy +1 5 +5 1 +6 0 +SELECT * FROM t2 order by id; +id xy +1 5 +2 0 +5 1 +6 0 +DROP TRIGGER t1_delete; +DROP TRIGGER t4_delete; +DROP TABLE t1, t2, t3, t4, t5; End of 5.0 tests diff --git a/mysql-test/r/openssl_1.result b/mysql-test/r/openssl_1.result index 34d8e3ab768..92900ac1a83 100644 --- a/mysql-test/r/openssl_1.result +++ b/mysql-test/r/openssl_1.result @@ -51,3 +51,5 @@ SSL error: Unable to get private key from '' mysqltest: Could not open connection 'default': 2026 SSL connection error SSL error: Unable to get certificate from '' mysqltest: Could not open connection 'default': 2026 SSL connection error +Variable_name Value +Ssl_cipher DHE-RSA-AES256-SHA diff --git a/mysql-test/r/order_by.result b/mysql-test/r/order_by.result index 67cf3b8dd36..eedc2fa476b 100644 --- a/mysql-test/r/order_by.result +++ b/mysql-test/r/order_by.result @@ -906,6 +906,90 @@ ERROR 23000: Column 'val' in order clause is ambiguous SELECT p.a AS val, q.a AS val FROM t1 p, t1 q ORDER BY val > 1; ERROR 23000: Column 'val' in order clause is ambiguous DROP TABLE t1; +CREATE TABLE t1 (a int); +INSERT INTO t1 VALUES (3), (2), (4), (1); +SELECT a, IF(a IN (2,3), a, a+10) FROM t1 +ORDER BY IF(a IN (2,3), a, a+10); +a IF(a IN (2,3), a, a+10) +2 2 +3 3 +1 11 +4 14 +SELECT a, IF(a NOT IN (2,3), a, a+10) FROM t1 +ORDER BY IF(a NOT IN (2,3), a, a+10); +a IF(a NOT IN (2,3), a, a+10) +1 1 +4 4 +2 12 +3 13 +SELECT a, IF(a IN (2,3), a, a+10) FROM t1 +ORDER BY IF(a NOT IN (2,3), a, a+10); +a IF(a IN (2,3), a, a+10) +1 11 +4 14 +2 2 +3 3 +SELECT a, IF(a BETWEEN 2 AND 3, a, a+10) FROM t1 +ORDER BY IF(a BETWEEN 2 AND 3, a, a+10); +a IF(a BETWEEN 2 AND 3, a, a+10) +2 2 +3 3 +1 11 +4 14 +SELECT a, IF(a NOT BETWEEN 2 AND 3, a, a+10) FROM t1 +ORDER BY IF(a NOT BETWEEN 2 AND 3, a, a+10); +a IF(a NOT BETWEEN 2 AND 3, a, a+10) +1 1 +4 4 +2 12 +3 13 +SELECT a, IF(a BETWEEN 2 AND 3, a, a+10) FROM t1 +ORDER BY IF(a NOT BETWEEN 2 AND 3, a, a+10); +a IF(a BETWEEN 2 AND 3, a, a+10) +1 11 +4 14 +2 2 +3 3 +SELECT IF(a IN (1,2), a, '') as x1, IF(a NOT IN (1,2), a, '') as x2 +FROM t1 GROUP BY x1, x2; +x1 x2 + 3 + 4 +1 +2 +SELECT IF(a IN (1,2), a, '') as x1, IF(a NOT IN (1,2), a, '') as x2 +FROM t1 GROUP BY x1, IF(a NOT IN (1,2), a, ''); +x1 x2 + 3 + 4 +1 +2 +SELECT a, a IN (1,2) FROM t1 ORDER BY a IN (1,2); +a a IN (1,2) +3 0 +4 0 +2 1 +1 1 +SELECT a FROM t1 ORDER BY a IN (1,2); +a +3 +4 +2 +1 +SELECT a+10 FROM t1 ORDER BY a IN (1,2); +a+10 +13 +14 +12 +11 +SELECT a, IF(a IN (1,2), a, a+10) FROM t1 +ORDER BY IF(a IN (3,4), a, a+10); +a IF(a IN (1,2), a, a+10) +3 13 +4 14 +1 1 +2 2 +DROP TABLE t1; create table t1 (a int not null, b int not null, c int not null); insert t1 values (1,1,1),(1,1,2),(1,2,1); select a, b from t1 group by a, b order by sum(c); diff --git a/mysql-test/r/rpl_ignore_table.result b/mysql-test/r/rpl_ignore_table.result index 136cf5cc5eb..80cff7c9a1e 100644 --- a/mysql-test/r/rpl_ignore_table.result +++ b/mysql-test/r/rpl_ignore_table.result @@ -14,6 +14,113 @@ SELECT * FROM t4; a DROP TABLE t1; DROP TABLE t4; +**** Test case for BUG#25482 **** +**** Adding GRANTS on master **** +create table test.t1(a int); +create table test.t4(a int); +GRANT SELECT ON test.t1 TO mysqltest1@localhost; +GRANT INSERT ON test.t4 TO mysqltest2@localhost; +GRANT select, update, insert, references on t1 +to mysqltest2@localhost; +GRANT SELECT ON test.* TO mysqltest3@localhost; +GRANT INSERT ON test.t4 TO mysqltest3@localhost; +GRANT select(a), update(a), insert(a), references(a) on t4 +to mysqltest3@localhost; +create database mysqltest2; +create table mysqltest2.t2 (id int); +GRANT SELECT ON mysqltest2.t2 TO mysqltest4@localhost IDENTIFIED BY 'pass'; +insert into mysql.user (user, host) values ("mysqltest5", "somehost"); +Warnings: +Warning 1364 Field 'ssl_cipher' doesn't have a default value +Warning 1364 Field 'x509_issuer' doesn't have a default value +Warning 1364 Field 'x509_subject' doesn't have a default value +GRANT SELECT ON *.* TO mysqltest6@localhost; +GRANT INSERT ON *.* TO mysqltest6@localhost; +GRANT INSERT ON test.* TO mysqltest6@localhost; +GRANT INSERT ON test.t1 TO mysqltest6@localhost; +show grants for mysqltest1@localhost; +Grants for mysqltest1@localhost +GRANT USAGE ON *.* TO 'mysqltest1'@'localhost' +GRANT SELECT ON `test`.`t1` TO 'mysqltest1'@'localhost' +show grants for mysqltest2@localhost; +Grants for mysqltest2@localhost +GRANT USAGE ON *.* TO 'mysqltest2'@'localhost' +GRANT SELECT, INSERT, UPDATE, REFERENCES ON `test`.`t1` TO 'mysqltest2'@'localhost' +GRANT INSERT ON `test`.`t4` TO 'mysqltest2'@'localhost' +show grants for mysqltest3@localhost; +Grants for mysqltest3@localhost +GRANT USAGE ON *.* TO 'mysqltest3'@'localhost' +GRANT SELECT ON `test`.* TO 'mysqltest3'@'localhost' +GRANT SELECT (a), INSERT, INSERT (a), UPDATE (a), REFERENCES (a) ON `test`.`t4` TO 'mysqltest3'@'localhost' +show grants for mysqltest4@localhost; +Grants for mysqltest4@localhost +GRANT USAGE ON *.* TO 'mysqltest4'@'localhost' IDENTIFIED BY PASSWORD '*196BDEDE2AE4F84CA44C47D54D78478C7E2BD7B7' +GRANT SELECT ON `mysqltest2`.`t2` TO 'mysqltest4'@'localhost' +show grants for mysqltest6@localhost; +Grants for mysqltest6@localhost +GRANT SELECT, INSERT ON *.* TO 'mysqltest6'@'localhost' +GRANT INSERT ON `test`.* TO 'mysqltest6'@'localhost' +GRANT INSERT ON `test`.`t1` TO 'mysqltest6'@'localhost' +flush privileges; +show grants for mysqltest5@somehost; +Grants for mysqltest5@somehost +GRANT USAGE ON *.* TO 'mysqltest5'@'somehost' +**** Checking grants on slave **** +show grants for mysqltest2@localhost; +Grants for mysqltest2@localhost +GRANT USAGE ON *.* TO 'mysqltest2'@'localhost' +GRANT INSERT ON `test`.`t4` TO 'mysqltest2'@'localhost' +show grants for mysqltest3@localhost; +Grants for mysqltest3@localhost +GRANT USAGE ON *.* TO 'mysqltest3'@'localhost' +GRANT SELECT ON `test`.* TO 'mysqltest3'@'localhost' +GRANT SELECT (a), INSERT, INSERT (a), UPDATE (a), REFERENCES (a) ON `test`.`t4` TO 'mysqltest3'@'localhost' +show grants for mysqltest4@localhost; +Grants for mysqltest4@localhost +GRANT USAGE ON *.* TO 'mysqltest4'@'localhost' IDENTIFIED BY PASSWORD '*196BDEDE2AE4F84CA44C47D54D78478C7E2BD7B7' +GRANT SELECT ON `mysqltest2`.`t2` TO 'mysqltest4'@'localhost' +show grants for mysqltest5@somehost; +Grants for mysqltest5@somehost +GRANT USAGE ON *.* TO 'mysqltest5'@'somehost' +show grants for mysqltest6@localhost; +Grants for mysqltest6@localhost +GRANT SELECT, INSERT ON *.* TO 'mysqltest6'@'localhost' +GRANT INSERT ON `test`.* TO 'mysqltest6'@'localhost' +show grants for mysqltest1@localhost; +ERROR 42000: There is no such grant defined for user 'mysqltest1' on host 'localhost' +**** Revoking grants on master **** +REVOKE SELECT ON test.t1 FROM mysqltest1@localhost; +REVOKE SELECT ON mysqltest2.t2 FROM mysqltest4@localhost; +REVOKE select(a) on t4 +from mysqltest3@localhost; +show grants for mysqltest1@localhost; +Grants for mysqltest1@localhost +GRANT USAGE ON *.* TO 'mysqltest1'@'localhost' +show grants for mysqltest3@localhost; +Grants for mysqltest3@localhost +GRANT USAGE ON *.* TO 'mysqltest3'@'localhost' +GRANT SELECT ON `test`.* TO 'mysqltest3'@'localhost' +GRANT INSERT, INSERT (a), UPDATE (a), REFERENCES (a) ON `test`.`t4` TO 'mysqltest3'@'localhost' +show grants for mysqltest4@localhost; +Grants for mysqltest4@localhost +GRANT USAGE ON *.* TO 'mysqltest4'@'localhost' IDENTIFIED BY PASSWORD '*196BDEDE2AE4F84CA44C47D54D78478C7E2BD7B7' +**** Checking grants on slave **** +show grants for mysqltest1@localhost; +ERROR 42000: There is no such grant defined for user 'mysqltest1' on host 'localhost' +show grants for mysqltest3@localhost; +Grants for mysqltest3@localhost +GRANT USAGE ON *.* TO 'mysqltest3'@'localhost' +GRANT SELECT ON `test`.* TO 'mysqltest3'@'localhost' +GRANT INSERT, INSERT (a), UPDATE (a), REFERENCES (a) ON `test`.`t4` TO 'mysqltest3'@'localhost' +show grants for mysqltest4@localhost; +Grants for mysqltest4@localhost +GRANT USAGE ON *.* TO 'mysqltest4'@'localhost' IDENTIFIED BY PASSWORD '*196BDEDE2AE4F84CA44C47D54D78478C7E2BD7B7' +drop table t1, t4, mysqltest2.t2; +drop database mysqltest2; +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%"; DROP TABLE IF EXISTS t5; CREATE TABLE t5 ( word varchar(50) collate utf8_unicode_ci NOT NULL default '' diff --git a/mysql-test/r/sp-code.result b/mysql-test/r/sp-code.result index 67b030f87a4..9d86a6bc08d 100644 --- a/mysql-test/r/sp-code.result +++ b/mysql-test/r/sp-code.result @@ -187,7 +187,7 @@ Pos Instruction 32 set v_dig@4 (v_dig@4 + 1) 33 stmt 4 "update sudoku_work set dig = v_dig wh..." 34 set v_tcounter@6 (v_tcounter@6 + 1) -35 jump_if_not 37(37) (not(`test`.`sudoku_digit_ok`(v_row@7,v_col@8,v_dig@4))) +35 jump_if_not 37(37) (not(`sudoku_digit_ok`(v_row@7,v_col@8,v_dig@4))) 36 jump 15 37 set v_i@3 (v_i@3 + 1) 38 jump 15 diff --git a/mysql-test/r/sp.result b/mysql-test/r/sp.result index 6773facb641..5386aa642a6 100644 --- a/mysql-test/r/sp.result +++ b/mysql-test/r/sp.result @@ -5984,6 +5984,91 @@ DATABASE() NULL DROP DATABASE mysqltest1| use test| +drop function if exists bug20777| +drop table if exists examplebug20777| +create function bug20777(f1 bigint unsigned) returns bigint unsigned +begin +set f1 = (f1 - 10); set f1 = (f1 + 10); +return f1; +end| +select bug20777(9223372036854775803) as '9223372036854775803 2**63-5'; +9223372036854775803 2**63-5 +9223372036854775803 +select bug20777(9223372036854775804) as '9223372036854775804 2**63-4'; +9223372036854775804 2**63-4 +9223372036854775804 +select bug20777(9223372036854775805) as '9223372036854775805 2**63-3'; +9223372036854775805 2**63-3 +9223372036854775805 +select bug20777(9223372036854775806) as '9223372036854775806 2**63-2'; +9223372036854775806 2**63-2 +9223372036854775806 +select bug20777(9223372036854775807) as '9223372036854775807 2**63-1'; +9223372036854775807 2**63-1 +9223372036854775807 +select bug20777(9223372036854775808) as '9223372036854775808 2**63+0'; +9223372036854775808 2**63+0 +9223372036854775808 +select bug20777(9223372036854775809) as '9223372036854775809 2**63+1'; +9223372036854775809 2**63+1 +9223372036854775809 +select bug20777(9223372036854775810) as '9223372036854775810 2**63+2'; +9223372036854775810 2**63+2 +9223372036854775810 +select bug20777(-9223372036854775808) as 'lower bounds signed bigint'; +lower bounds signed bigint +0 +select bug20777(9223372036854775807) as 'upper bounds signed bigint'; +upper bounds signed bigint +9223372036854775807 +select bug20777(0) as 'lower bounds unsigned bigint'; +lower bounds unsigned bigint +0 +select bug20777(18446744073709551615) as 'upper bounds unsigned bigint'; +upper bounds unsigned bigint +18446744073709551615 +select bug20777(18446744073709551616) as 'upper bounds unsigned bigint + 1'; +upper bounds unsigned bigint + 1 +18446744073709551615 +select bug20777(-1) as 'lower bounds unsigned bigint - 1'; +lower bounds unsigned bigint - 1 +0 +create table examplebug20777 as select +0 as 'i', +bug20777(9223372036854775806) as '2**63-2', +bug20777(9223372036854775807) as '2**63-1', +bug20777(9223372036854775808) as '2**63', +bug20777(9223372036854775809) as '2**63+1', +bug20777(18446744073709551614) as '2**64-2', +bug20777(18446744073709551615) as '2**64-1', +bug20777(18446744073709551616) as '2**64', +bug20777(0) as '0', +bug20777(-1) as '-1'; +insert into examplebug20777 values (1, 9223372036854775806, 9223372036854775807, 223372036854775808, 9223372036854775809, 18446744073709551614, 18446744073709551615, 8446744073709551616, 0, -1); +show create table examplebug20777; +Table Create Table +examplebug20777 CREATE TABLE `examplebug20777` ( + `i` int(1) NOT NULL default '0', + `2**63-2` bigint(20) unsigned default NULL, + `2**63-1` bigint(20) unsigned default NULL, + `2**63` bigint(20) unsigned default NULL, + `2**63+1` bigint(20) unsigned default NULL, + `2**64-2` bigint(20) unsigned default NULL, + `2**64-1` bigint(20) unsigned default NULL, + `2**64` bigint(20) unsigned default NULL, + `0` bigint(20) unsigned default NULL, + `-1` bigint(20) unsigned default NULL +) ENGINE=MyISAM DEFAULT CHARSET=latin1 +select * from examplebug20777 order by i; +i 2**63-2 2**63-1 2**63 2**63+1 2**64-2 2**64-1 2**64 0 -1 +0 9223372036854775806 9223372036854775807 9223372036854775808 9223372036854775809 18446744073709551614 18446744073709551615 18446744073709551615 0 0 +1 9223372036854775806 9223372036854775807 223372036854775808 9223372036854775809 18446744073709551614 18446744073709551615 8446744073709551616 0 0 +drop table examplebug20777; +select bug20777(18446744073709551613)+1; +bug20777(18446744073709551613)+1 +18446744073709551614 +drop function bug20777; +End of 5.0 tests. drop table t1,t2; CREATE TABLE t1 (a int auto_increment primary key) engine=MyISAM; CREATE TABLE t2 (a int auto_increment primary key, b int) engine=innodb; diff --git a/mysql-test/r/strict.result b/mysql-test/r/strict.result index 702fc68bb25..636a00a4343 100644 --- a/mysql-test/r/strict.result +++ b/mysql-test/r/strict.result @@ -7,7 +7,6 @@ DROP TABLE IF EXISTS t1; CREATE TABLE t1 (col1 date); 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'); @@ -57,6 +56,7 @@ select * from t1; col1 2004-01-01 2004-02-29 +0000-10-31 2004-01-02 2004-01-03 2004-00-31 @@ -124,7 +124,6 @@ set @@sql_mode='ansi,traditional'; CREATE TABLE t1 (col1 datetime); 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'); @@ -145,6 +144,7 @@ select * from t1; col1 2004-10-31 15:30:00 2004-02-29 15:30:00 +0000-10-31 15:30:00 drop table t1; CREATE TABLE t1 (col1 timestamp); INSERT INTO t1 VALUES('2004-10-31 15:30:00'),('2004-02-29 15:30:00'); @@ -206,7 +206,6 @@ 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')); @@ -222,7 +221,6 @@ 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')); @@ -259,7 +257,6 @@ 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)); @@ -267,7 +264,6 @@ 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: Truncated 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)); @@ -275,7 +271,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: Truncated incorrect datetime value: '0000-00-00' INSERT INTO t1 (col3) VALUES(CAST('0000-10-31 15:30' AS DATETIME)); -ERROR 22007: Truncated incorrect datetime value: '0000-10-31 15:30' +ERROR 22007: Incorrect datetime value: '0000-10-31 15:30:00' for column 'col3' at row 1 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)); @@ -288,7 +284,6 @@ 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)); @@ -296,7 +291,6 @@ 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: Truncated 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)); @@ -304,7 +298,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: Truncated incorrect datetime value: '0000-00-00' INSERT INTO t1 (col3) VALUES(CONVERT('0000-10-31 15:30',DATETIME)); -ERROR 22007: Truncated incorrect datetime value: '0000-10-31 15:30' +ERROR 22007: Incorrect datetime value: '0000-10-31 15:30:00' for column 'col3' at row 1 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)); @@ -1352,3 +1346,44 @@ t1 CREATE TABLE `t1` ( `i` int(11) default NULL ) ENGINE=MyISAM DEFAULT CHARSET=latin1 COMMENT='123456789*123456789*123456789*123456789*123456789*123456789*' drop table t1; +set sql_mode= 'traditional'; +create table t1(col1 tinyint, col2 tinyint unsigned, +col3 smallint, col4 smallint unsigned, +col5 mediumint, col6 mediumint unsigned, +col7 int, col8 int unsigned, +col9 bigint, col10 bigint unsigned); +insert into t1(col1) values('-'); +ERROR HY000: Incorrect integer value: '-' for column 'col1' at row 1 +insert into t1(col2) values('+'); +ERROR HY000: Incorrect integer value: '+' for column 'col2' at row 1 +insert into t1(col3) values('-'); +ERROR HY000: Incorrect integer value: '-' for column 'col3' at row 1 +insert into t1(col4) values('+'); +ERROR HY000: Incorrect integer value: '+' for column 'col4' at row 1 +insert into t1(col5) values('-'); +ERROR HY000: Incorrect integer value: '-' for column 'col5' at row 1 +insert into t1(col6) values('+'); +ERROR HY000: Incorrect integer value: '+' for column 'col6' at row 1 +insert into t1(col7) values('-'); +ERROR HY000: Incorrect integer value: '-' for column 'col7' at row 1 +insert into t1(col8) values('+'); +ERROR HY000: Incorrect integer value: '+' for column 'col8' at row 1 +insert into t1(col9) values('-'); +ERROR HY000: Incorrect integer value: '-' for column 'col9' at row 1 +insert into t1(col10) values('+'); +ERROR HY000: Incorrect integer value: '+' for column 'col10' at row 1 +drop table t1; +set sql_mode='traditional'; +create table t1(a year); +insert into t1 values ('-'); +ERROR HY000: Incorrect integer value: '-' for column 'a' at row 1 +insert into t1 values ('+'); +ERROR HY000: Incorrect integer value: '+' for column 'a' at row 1 +insert into t1 values (''); +ERROR HY000: Incorrect integer value: '' for column 'a' at row 1 +insert into t1 values ('2000a'); +ERROR 01000: Data truncated for column 'a' at row 1 +insert into t1 values ('2E3x'); +ERROR 01000: Data truncated for column 'a' at row 1 +drop table t1; +End of 5.0 tests diff --git a/mysql-test/r/type_date.result b/mysql-test/r/type_date.result index ed15293bb45..644d4d971c6 100644 --- a/mysql-test/r/type_date.result +++ b/mysql-test/r/type_date.result @@ -99,7 +99,7 @@ DROP TABLE t1, t2, t3; CREATE TABLE t1 (y YEAR); INSERT INTO t1 VALUES ('abc'); Warnings: -Warning 1264 Out of range value adjusted for column 'y' at row 1 +Warning 1366 Incorrect integer value: 'abc' for column 'y' at row 1 SELECT * FROM t1; y 0000 diff --git a/mysql-test/r/type_datetime.result b/mysql-test/r/type_datetime.result index a9083b29805..7caa23d330d 100644 --- a/mysql-test/r/type_datetime.result +++ b/mysql-test/r/type_datetime.result @@ -26,8 +26,6 @@ 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; @@ -36,7 +34,7 @@ t 2069-12-31 00:00:00 1970-01-01 00:00:00 1999-12-31 00:00:00 -0000-00-00 00:00:00 +0000-01-01 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_set.result b/mysql-test/r/type_set.result index fdda4aca25c..03de20baef2 100644 --- a/mysql-test/r/type_set.result +++ b/mysql-test/r/type_set.result @@ -66,3 +66,22 @@ ss ue ue DROP TABLE t1; +create table t1(f1 +set('1','2','3','4','5','6','7','8','9','10','11','12','13','14','15','16','17', +'18','19','20','21','22','23','24','25','26','27','28','29','30','31','32','33', +'34','35','36','37','38','39','40','41','42','43','44','45','46','47','48','49', +'50','51','52','53','54','55','56','57','58','59','60','61','62','63','64','128')); +ERROR HY000: Too many strings for column f1 and SET +create table t1(f1 +set('1','2','3','4','5','6','7','8','9','10','11','12','13','14','15','16','17', +'18','19','20','21','22','23','24','25','26','27','28','29','30','31','32','33', +'34','35','36','37','38','39','40','41','42','43','44','45','46','47','48','49', +'50','51','52','53','54','55','56','57','58','59','60','61','62','63','64','1')); +Warnings: +Note 1291 Column 'f1' has duplicated value '1' in SET +show create table t1; +Table Create Table +t1 CREATE TABLE `t1` ( + `f1` set('1','2','3','4','5','6','7','8','9','10','11','12','13','14','15','16','17','18','19','20','21','22','23','24','25','26','27','28','29','30','31','32','33','34','35','36','37','38','39','40','41','42','43','44','45','46','47','48','49','50','51','52','53','54','55','56','57','58','59','60','61','62','63','64','1') default NULL +) ENGINE=MyISAM DEFAULT CHARSET=latin1 +drop table t1; diff --git a/mysql-test/r/type_year.result b/mysql-test/r/type_year.result index 84b688429db..e52947455c8 100644 --- a/mysql-test/r/type_year.result +++ b/mysql-test/r/type_year.result @@ -34,3 +34,15 @@ select if(y = now(), 1, 0) from t1; if(y = now(), 1, 0) 1 drop table t1; +create table t1(a year); +insert into t1 values (2000.5), ('2000.5'), ('2001a'), ('2.001E3'); +Warnings: +Warning 1265 Data truncated for column 'a' at row 3 +select * from t1; +a +2001 +2001 +2001 +2001 +drop table t1; +End of 5.0 tests diff --git a/mysql-test/r/udf.result b/mysql-test/r/udf.result index d5f59247084..7c52e7da496 100644 --- a/mysql-test/r/udf.result +++ b/mysql-test/r/udf.result @@ -159,7 +159,7 @@ EXPLAIN EXTENDED SELECT myfunc_int(fn(MIN(b))) as c FROM t1 GROUP BY a; id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE t1 ALL NULL NULL NULL NULL 2 Using temporary; Using filesort Warnings: -Note 1003 select myfunc_int(`test`.`fn`(min(`test`.`t1`.`b`)) AS `fn(MIN(b))`) AS `c` from `test`.`t1` group by `test`.`t1`.`a` +Note 1003 select myfunc_int(`fn`(min(`test`.`t1`.`b`)) AS `fn(MIN(b))`) AS `c` from `test`.`t1` group by `test`.`t1`.`a` EXPLAIN EXTENDED SELECT myfunc_int(test.fn(MIN(b))) as c FROM t1 GROUP BY a; id select_type table type possible_keys key key_len ref rows Extra 1 SIMPLE t1 ALL NULL NULL NULL NULL 2 Using temporary; Using filesort diff --git a/mysql-test/t/archive.test b/mysql-test/t/archive.test index 80533f21311..0ffbfab3d4f 100644 --- a/mysql-test/t/archive.test +++ b/mysql-test/t/archive.test @@ -1364,3 +1364,13 @@ SELECT * from t2; drop table t1, t2, t4; + +# +# BUG#26138 - REPAIR TABLE with option USE_FRM erases all records in ARCHIVE +# table +# +create table t1 (i int) engine=archive; +insert into t1 values (1); +repair table t1 use_frm; +select * from t1; +drop table t1; diff --git a/mysql-test/t/create.test b/mysql-test/t/create.test index 8e55bf62ba6..ba5f56e12b1 100644 --- a/mysql-test/t/create.test +++ b/mysql-test/t/create.test @@ -656,6 +656,7 @@ create table t1(a set("a,b","c,d") not null); # End of 4.1 tests + # # Bug #14155: Maximum value of MAX_ROWS handled incorrectly on 64-bit # platforms @@ -674,4 +675,4 @@ drop table t1; create table t1 (upgrade int); drop table t1; -# End of 5.0 tests +--echo End of 5.0 tests diff --git a/mysql-test/t/errors.test b/mysql-test/t/errors.test index f5647a293e8..4fbdcba635f 100644 --- a/mysql-test/t/errors.test +++ b/mysql-test/t/errors.test @@ -40,5 +40,17 @@ create table t1 (a int(256)); set sql_mode='traditional'; --error 1074 create table t1 (a varchar(66000)); +set sql_mode=default; + +# +# Bug #27513: mysql 5.0.x + NULL pointer DoS +# +CREATE TABLE t1 (a INT); +SELECT a FROM t1 WHERE a IN(1, (SELECT IF(1=0,1,2/0))); +INSERT INTO t1 VALUES(1); +SELECT a FROM t1 WHERE a IN(1, (SELECT IF(1=0,1,2/0))); +INSERT INTO t1 VALUES(2),(3); +SELECT a FROM t1 WHERE a IN(1, (SELECT IF(1=0,1,2/0))); +DROP TABLE t1; # End of 5.0 tests diff --git a/mysql-test/t/flush2.test b/mysql-test/t/flush2.test index fc9e88e3141..7582ab8426b 100644 --- a/mysql-test/t/flush2.test +++ b/mysql-test/t/flush2.test @@ -3,7 +3,7 @@ # flush logs; set global expire_logs_days = 3; -show variables like 'log%'; +show variables like 'log_bin%'; flush logs; -show variables like 'log%'; +show variables like 'log_bin%'; set global expire_logs_days = 0; diff --git a/mysql-test/t/fulltext_left_join.test b/mysql-test/t/fulltext_left_join.test index 5942ce119ee..8c13ae5cad9 100644 --- a/mysql-test/t/fulltext_left_join.test +++ b/mysql-test/t/fulltext_left_join.test @@ -87,3 +87,14 @@ SELECT t1.*, MATCH(t1.name) AGAINST('string') AS relevance DROP TABLE t1,t2; # End of 4.1 tests + +# +# BUG#25729 - boolean full text search is confused by NULLs produced by LEFT +# JOIN +# +CREATE TABLE t1 (a INT); +CREATE TABLE t2 (b INT, c TEXT, KEY(b)); +INSERT INTO t1 VALUES(1); +INSERT INTO t2(b,c) VALUES(2,'castle'),(3,'castle'); +SELECT * FROM t1 LEFT JOIN t2 ON a=b WHERE MATCH(c) AGAINST('+castle' IN BOOLEAN MODE); +DROP TABLE t1, t2; diff --git a/mysql-test/t/func_group.test b/mysql-test/t/func_group.test index b102148472a..654bb8bb75d 100644 --- a/mysql-test/t/func_group.test +++ b/mysql-test/t/func_group.test @@ -794,6 +794,16 @@ drop table bug22555; # +# Bug #21976: Unnecessary warning with count(decimal) +# + +create table t1 (a decimal(20)); +insert into t1 values (12345678901234567890); +select count(a) from t1; +select count(distinct a) from t1; +drop table t1; + +# # Bug #23184: SELECT causes server crash # CREATE TABLE t1 (a INT, b INT); @@ -817,5 +827,4 @@ SELECT a,AVG(DISTINCT b) AS average FROM t1 GROUP BY a HAVING average > 50; DROP TABLE t1; -### --echo End of 5.0 tests diff --git a/mysql-test/t/func_str.test b/mysql-test/t/func_str.test index d42be70c057..0e4b404fe3a 100644 --- a/mysql-test/t/func_str.test +++ b/mysql-test/t/func_str.test @@ -1038,6 +1038,10 @@ INSERT INTO `t1` (`id`, `tire`) VALUES ('A', 0), ('B', 1),('C', 2); SELECT REPEAT( '#', tire ) AS A, REPEAT( '#', tire % 999 ) AS B, tire FROM `t1`; +SELECT REPEAT('0', CAST(0 AS UNSIGNED)); +SELECT REPEAT('0', -2); +SELECT REPEAT('0', 2); + DROP TABLE t1; # diff --git a/mysql-test/t/gis.test b/mysql-test/t/gis.test index 4f6104aab3e..ccc38db8dea 100644 --- a/mysql-test/t/gis.test +++ b/mysql-test/t/gis.test @@ -490,3 +490,71 @@ DESCRIBE v2; DROP VIEW v1,v2; DROP TABLE t1; + +# +# Bug#24563: MBROverlaps does not seem to function propertly +# Bug#54888: MBROverlaps missing in 5.1? +# + +# Test all MBR* functions and their non-MBR-prefixed aliases, +# using shifted squares to verify the spatial relations. + +create table t1 (name VARCHAR(100), square GEOMETRY); + +INSERT INTO t1 VALUES("center", GeomFromText('POLYGON (( 0 0, 0 2, 2 2, 2 0, 0 0))')); + +INSERT INTO t1 VALUES("small", GeomFromText('POLYGON (( 0 0, 0 1, 1 1, 1 0, 0 0))')); +INSERT INTO t1 VALUES("big", GeomFromText('POLYGON (( 0 0, 0 3, 3 3, 3 0, 0 0))')); + +INSERT INTO t1 VALUES("up", GeomFromText('POLYGON (( 0 1, 0 3, 2 3, 2 1, 0 1))')); +INSERT INTO t1 VALUES("up2", GeomFromText('POLYGON (( 0 2, 0 4, 2 4, 2 2, 0 2))')); +INSERT INTO t1 VALUES("up3", GeomFromText('POLYGON (( 0 3, 0 5, 2 5, 2 3, 0 3))')); + +INSERT INTO t1 VALUES("down", GeomFromText('POLYGON (( 0 -1, 0 1, 2 1, 2 -1, 0 -1))')); +INSERT INTO t1 VALUES("down2", GeomFromText('POLYGON (( 0 -2, 0 0, 2 0, 2 -2, 0 -2))')); +INSERT INTO t1 VALUES("down3", GeomFromText('POLYGON (( 0 -3, 0 -1, 2 -1, 2 -3, 0 -3))')); + +INSERT INTO t1 VALUES("right", GeomFromText('POLYGON (( 1 0, 1 2, 3 2, 3 0, 1 0))')); +INSERT INTO t1 VALUES("right2", GeomFromText('POLYGON (( 2 0, 2 2, 4 2, 4 0, 2 0))')); +INSERT INTO t1 VALUES("right3", GeomFromText('POLYGON (( 3 0, 3 2, 5 2, 5 0, 3 0))')); + +INSERT INTO t1 VALUES("left", GeomFromText('POLYGON (( -1 0, -1 2, 1 2, 1 0, -1 0))')); +INSERT INTO t1 VALUES("left2", GeomFromText('POLYGON (( -2 0, -2 2, 0 2, 0 0, -2 0))')); +INSERT INTO t1 VALUES("left3", GeomFromText('POLYGON (( -3 0, -3 2, -1 2, -1 0, -3 0))')); + +SELECT GROUP_CONCAT(a2.name ORDER BY a2.name) AS mbrcontains FROM t1 a1 JOIN t1 a2 ON MBRContains( a1.square, a2.square) WHERE a1.name = "center" GROUP BY a1.name; +SELECT GROUP_CONCAT(a2.name ORDER BY a2.name) AS mbrdisjoint FROM t1 a1 JOIN t1 a2 ON MBRDisjoint( a1.square, a2.square) WHERE a1.name = "center" GROUP BY a1.name; +SELECT GROUP_CONCAT(a2.name ORDER BY a2.name) AS mbrequal FROM t1 a1 JOIN t1 a2 ON MBREqual( a1.square, a2.square) WHERE a1.name = "center" GROUP BY a1.name; +SELECT GROUP_CONCAT(a2.name ORDER BY a2.name) AS mbrintersect FROM t1 a1 JOIN t1 a2 ON MBRIntersects( a1.square, a2.square) WHERE a1.name = "center" GROUP BY a1.name; +SELECT GROUP_CONCAT(a2.name ORDER BY a2.name) AS mbroverlaps FROM t1 a1 JOIN t1 a2 ON MBROverlaps( a1.square, a2.square) WHERE a1.name = "center" GROUP BY a1.name; +SELECT GROUP_CONCAT(a2.name ORDER BY a2.name) AS mbrtouches FROM t1 a1 JOIN t1 a2 ON MBRTouches( a1.square, a2.square) WHERE a1.name = "center" GROUP BY a1.name; +SELECT GROUP_CONCAT(a2.name ORDER BY a2.name) AS mbrwithin FROM t1 a1 JOIN t1 a2 ON MBRWithin( a1.square, a2.square) WHERE a1.name = "center" GROUP BY a1.name; + +SELECT GROUP_CONCAT(a2.name ORDER BY a2.name) AS contains FROM t1 a1 JOIN t1 a2 ON Contains( a1.square, a2.square) WHERE a1.name = "center" GROUP BY a1.name; +SELECT GROUP_CONCAT(a2.name ORDER BY a2.name) AS disjoint FROM t1 a1 JOIN t1 a2 ON Disjoint( a1.square, a2.square) WHERE a1.name = "center" GROUP BY a1.name; +SELECT GROUP_CONCAT(a2.name ORDER BY a2.name) AS equals FROM t1 a1 JOIN t1 a2 ON Equals( a1.square, a2.square) WHERE a1.name = "center" GROUP BY a1.name; +SELECT GROUP_CONCAT(a2.name ORDER BY a2.name) AS intersect FROM t1 a1 JOIN t1 a2 ON Intersects( a1.square, a2.square) WHERE a1.name = "center" GROUP BY a1.name; +SELECT GROUP_CONCAT(a2.name ORDER BY a2.name) AS overlaps FROM t1 a1 JOIN t1 a2 ON Overlaps( a1.square, a2.square) WHERE a1.name = "center" GROUP BY a1.name; +SELECT GROUP_CONCAT(a2.name ORDER BY a2.name) AS touches FROM t1 a1 JOIN t1 a2 ON Touches( a1.square, a2.square) WHERE a1.name = "center" GROUP BY a1.name; +SELECT GROUP_CONCAT(a2.name ORDER BY a2.name) AS within FROM t1 a1 JOIN t1 a2 ON Within( a1.square, a2.square) WHERE a1.name = "center" GROUP BY a1.name; + +# Overlaps needs a few more tests, with point and line dimensions + +SET @vert1 = GeomFromText('POLYGON ((0 -2, 0 2, 0 -2))'); +SET @horiz1 = GeomFromText('POLYGON ((-2 0, 2 0, -2 0))'); +SET @horiz2 = GeomFromText('POLYGON ((-1 0, 3 0, -1 0))'); +SET @horiz3 = GeomFromText('POLYGON ((2 0, 3 0, 2 0))'); +SET @point1 = GeomFromText('POLYGON ((0 0))'); +SET @point2 = GeomFromText('POLYGON ((-2 0))'); + +SELECT GROUP_CONCAT(a1.name ORDER BY a1.name) AS overlaps FROM t1 a1 WHERE Overlaps(a1.square, @vert1) GROUP BY a1.name; +SELECT GROUP_CONCAT(a1.name ORDER BY a1.name) AS overlaps FROM t1 a1 WHERE Overlaps(a1.square, @horiz1) GROUP BY a1.name; +SELECT Overlaps(@horiz1, @vert1) FROM DUAL; +SELECT Overlaps(@horiz1, @horiz2) FROM DUAL; +SELECT Overlaps(@horiz1, @horiz3) FROM DUAL; +SELECT Overlaps(@horiz1, @point1) FROM DUAL; +SELECT Overlaps(@horiz1, @point2) FROM DUAL; + +DROP TABLE t1; + +--echo End of 5.0 tests diff --git a/mysql-test/t/innodb.test b/mysql-test/t/innodb.test index aa25677bd99..e762d740d66 100644 --- a/mysql-test/t/innodb.test +++ b/mysql-test/t/innodb.test @@ -1976,6 +1976,34 @@ drop table t2, t1; --error ER_TABLE_CANT_HANDLE_SPKEYS create table t1 (g geometry not null, spatial gk(g)) engine=innodb; +# +# Bug #25927: Prevent ALTER TABLE ... MODIFY ... NOT NULL on columns +# for which there is a foreign key constraint ON ... SET NULL. +# + +CREATE TABLE t1 (a INT, INDEX(a)) ENGINE=InnoDB; +CREATE TABLE t2 (a INT, INDEX(a)) ENGINE=InnoDB; +INSERT INTO t1 VALUES (1); +INSERT INTO t2 VALUES (1); +ALTER TABLE t2 ADD FOREIGN KEY (a) REFERENCES t1 (a) ON DELETE SET NULL; +--replace_regex /'\.\/test\/#sql-[0-9a-f_]*'/'#sql-temporary'/ +--error 1025 +ALTER TABLE t2 MODIFY a INT NOT NULL; +DELETE FROM t1; +DROP TABLE t2,t1; + +# +# Bug #26835: table corruption after delete+insert +# + +CREATE TABLE t1 (a VARCHAR(5) COLLATE utf8_unicode_ci PRIMARY KEY) +ENGINE=InnoDB; +INSERT INTO t1 VALUES (0xEFBCA4EFBCA4EFBCA4); +DELETE FROM t1; +INSERT INTO t1 VALUES ('DDD'); +SELECT * FROM t1; +DROP TABLE t1; + ####################################################################### # # # Please, DO NOT TOUCH this file as well as the innodb.result file. # diff --git a/mysql-test/t/loaddata.test b/mysql-test/t/loaddata.test index 125a65826ca..e6788cd7798 100644 --- a/mysql-test/t/loaddata.test +++ b/mysql-test/t/loaddata.test @@ -136,4 +136,20 @@ eval select load_file("$MYSQL_TEST_DIR/t/loaddata.test"); # cleanup drop table t1, t2; +# +# Bug#27586: Wrong autoinc value assigned by LOAD DATA in the +# NO_AUTO_VALUE_ON_ZERO mode +# +create table t1(f1 int); +insert into t1 values(1),(null); +create table t2(f2 int auto_increment primary key); +disable_query_log; +eval select * into outfile '$MYSQLTEST_VARDIR/tmp/t1' from t1; +SET @OLD_SQL_MODE=@@SQL_MODE, @@SQL_MODE=NO_AUTO_VALUE_ON_ZERO; +eval load data infile '$MYSQLTEST_VARDIR/tmp/t1' into table t2; +enable_query_log; +select * from t2; +--exec rm $MYSQLTEST_VARDIR/tmp/t1 +SET @@SQL_MODE=@OLD_SQL_MODE; +drop table t1,t2; # End of 5.0 tests diff --git a/mysql-test/t/mysqlbinlog.test b/mysql-test/t/mysqlbinlog.test index 97239360507..a7b3f413f23 100644 --- a/mysql-test/t/mysqlbinlog.test +++ b/mysql-test/t/mysqlbinlog.test @@ -201,7 +201,7 @@ load data infile '../std_data_ln/loaddata6.dat' into table t1 character set koi8 select hex(a) from t1; drop table t1; flush logs; ---replace_result $MYSQL_TMP_DIR MYSQL_TMP_DIR ---exec $MYSQL_BINLOG --short-form $MYSQLTEST_VARDIR/log/master-bin.000009 +--replace_result $MYSQLTEST_VARDIR MYSQLTEST_VARDIR +--exec $MYSQL_BINLOG --short-form --local-load=$MYSQLTEST_VARDIR/tmp/ $MYSQLTEST_VARDIR/log/master-bin.000009 --echo End of 5.0 tests diff --git a/mysql-test/t/mysqldump.test b/mysql-test/t/mysqldump.test index 31741cdba9f..126412057ab 100644 --- a/mysql-test/t/mysqldump.test +++ b/mysql-test/t/mysqldump.test @@ -918,7 +918,7 @@ port=1234 EOF --exec $MYSQL_MY_PRINT_DEFAULTS -c $MYSQLTEST_VARDIR/tmp/tmp.cnf mysqltest1 --exec $MYSQL_MY_PRINT_DEFAULTS -e $MYSQLTEST_VARDIR/tmp/tmp.cnf mysqltest1 mysqltest1 ---remov_file $MYSQLTEST_VARDIR/tmp/tmp.cnf +--remove_file $MYSQLTEST_VARDIR/tmp/tmp.cnf --echo # --echo # Test of fix to BUG 12597 @@ -1429,6 +1429,72 @@ INSERT INTO t1 VALUES(1,0xff00fef0); DROP TABLE t1; + + +--echo # +--echo # Bug#26346: stack + buffer overrun in mysqldump +--echo # + +CREATE TABLE t1(a int); +INSERT INTO t1 VALUES (1), (2); + +# too long a file path causes an error +--error 1 +--exec $MYSQL_DUMP --tab=aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa test 2>&1 + +--exec $MYSQL_DUMP --tab=$MYSQLTEST_VARDIR/tmp/ --fields-terminated-by=aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa test +--exec $MYSQL_DUMP --tab=$MYSQLTEST_VARDIR/tmp/ --fields-enclosed-by=aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa test +--exec $MYSQL_DUMP --tab=$MYSQLTEST_VARDIR/tmp/ --fields-optionally-enclosed-by=aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa test +--exec $MYSQL_DUMP --tab=$MYSQLTEST_VARDIR/tmp/ --fields-escaped-by=aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa test +--exec $MYSQL_DUMP --tab=$MYSQLTEST_VARDIR/tmp/ --lines-terminated-by=aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa test + +--remove_file $MYSQLTEST_VARDIR/tmp/t1.sql +--remove_file $MYSQLTEST_VARDIR/tmp/t1.txt + +DROP TABLE t1; + +# +# Bug #25993: crashe with a merge table and -c +# + +CREATE TABLE t2 (a int); +CREATE TABLE t3 (a int); +CREATE TABLE t1 (a int) ENGINE=merge UNION=(t2, t3); +--exec $MYSQL_DUMP --skip-comments -c test +DROP TABLE t1, t2, t3; + +--echo # +--echo # Bug #23491: MySQLDump prefix function call in a view by database name +--echo # + +# Setup +create database bug23491_original; +create database bug23491_restore; +use bug23491_original; +create table t1 (c1 int); +create view v1 as select * from t1; +create procedure p1() select 1; +create function f1() returns int return 1; +create view v2 as select f1(); +create function f2() returns int return f1(); +create view v3 as select bug23491_original.f1(); + +# Backup. +--exec $MYSQL_DUMP --skip-comments -uroot --opt --routines bug23491_original > $MYSQLTEST_VARDIR/tmp/bug23491_backup.sql + +# Restore. +--exec $MYSQL bug23491_restore < $MYSQLTEST_VARDIR/tmp/bug23491_backup.sql + +# Verify +use bug23491_restore; +show create view bug23491_restore.v2; +show create view bug23491_restore.v3; + +# Cleanup +drop database bug23491_original; +drop database bug23491_restore; +use test; + --echo # --echo # End of 5.0 tests --echo # diff --git a/mysql-test/t/ndb_autodiscover3.test b/mysql-test/t/ndb_autodiscover3.test index 73b4bf8b94f..259da6e3501 100644 --- a/mysql-test/t/ndb_autodiscover3.test +++ b/mysql-test/t/ndb_autodiscover3.test @@ -1,5 +1,6 @@ -- source include/have_ndb.inc -- source include/have_multi_ndb.inc +-- source include/ndb_default_cluster.inc -- source include/not_embedded.inc @@ -7,6 +8,11 @@ drop table if exists t1, t2; --enable_warnings +# Workaround for Bug#27644 +# ndb: connecting api node/mysqld may "steal" node_id from running mysqld +# - let ndb_waiter use a fixed node id so "steal" cannot happen +--let connect_str = "nodeid=6;$NDB_CONNECTSTRING" + # # Transaction ongoing while cluster is restarted # @@ -17,7 +23,7 @@ begin; insert into t1 values (1); --exec $NDB_MGM --no-defaults -e "all restart" >> $NDB_TOOLS_OUTPUT ---exec $NDB_TOOLS_DIR/ndb_waiter --no-defaults >> $NDB_TOOLS_OUTPUT +--exec $NDB_TOOLS_DIR/ndb_waiter --no-defaults -c $connect_str >> $NDB_TOOLS_OUTPUT --error 1297 insert into t1 values (2); @@ -35,7 +41,7 @@ insert into t2 values (1,1),(2,1),(3,1),(4,1),(5,1),(6,1),(7,1),(8,1),(9,1),(10, select * from t2 order by a limit 3; --exec $NDB_MGM --no-defaults -e "all restart -i" >> $NDB_TOOLS_OUTPUT ---exec $NDB_TOOLS_DIR/ndb_waiter --no-defaults >> $NDB_TOOLS_OUTPUT +--exec $NDB_TOOLS_DIR/ndb_waiter --no-defaults -c $connect_str >> $NDB_TOOLS_OUTPUT --connection server2 create table t2 (a int key) engine=ndbcluster; @@ -49,7 +55,7 @@ select * from t2 order by a limit 3; select * from t2 order by a limit 3; --exec $NDB_MGM --no-defaults -e "all restart -i" >> $NDB_TOOLS_OUTPUT ---exec $NDB_TOOLS_DIR/ndb_waiter --no-defaults >> $NDB_TOOLS_OUTPUT +--exec $NDB_TOOLS_DIR/ndb_waiter --no-defaults -c $connect_str >> $NDB_TOOLS_OUTPUT --connection server1 show tables; diff --git a/mysql-test/t/ndb_trigger.test b/mysql-test/t/ndb_trigger.test index 2521ef17842..25b079cfe7c 100644 --- a/mysql-test/t/ndb_trigger.test +++ b/mysql-test/t/ndb_trigger.test @@ -89,4 +89,112 @@ select * from t2 order by op, a, b; drop tables t1, t2, t3; +# Test for bug#26242 +# Verify that AFTER UPDATE/DELETE triggers are executed +# after the change has actually taken place + +CREATE TABLE t1 ( + id INT NOT NULL PRIMARY KEY, + xy INT +) ENGINE=ndbcluster; + +INSERT INTO t1 VALUES (1, 0); + +DELIMITER //; +CREATE TRIGGER t1_update AFTER UPDATE ON t1 FOR EACH ROW BEGIN REPLACE INTO t2 SELECT * FROM t1 WHERE t1.id = NEW.id; END // +DELIMITER ;// + +CREATE TABLE t2 ( + id INT NOT NULL PRIMARY KEY, + xy INT +) ENGINE=ndbcluster; + +INSERT INTO t2 VALUES (2, 0); + +CREATE TABLE t3 (id INT NOT NULL PRIMARY KEY) ENGINE=ndbcluster; + +INSERT INTO t3 VALUES (1); + +CREATE TABLE t4 LIKE t1; + +DELIMITER //; +CREATE TRIGGER t4_update AFTER UPDATE ON t4 FOR EACH ROW BEGIN REPLACE INTO t5 SELECT * FROM t4 WHERE t4.id = NEW.id; END // +DELIMITER ;// + +CREATE TABLE t5 LIKE t2; + +UPDATE t1 SET xy = 3 WHERE id = 1; +SELECT xy FROM t1 where id = 1; +SELECT xy FROM t2 where id = 1; + +UPDATE t1 SET xy = 4 WHERE id IN (SELECT id FROM t3 WHERE id = 1); +SELECT xy FROM t1 where id = 1; +SELECT xy FROM t2 where id = 1; + +INSERT INTO t4 SELECT * FROM t1; +INSERT INTO t5 SELECT * FROM t2; +UPDATE t1,t4 SET t1.xy = 3, t4.xy = 3 WHERE t1.id = 1 AND t4.id = 1; +SELECT xy FROM t1 where id = 1; +SELECT xy FROM t2 where id = 1; +SELECT xy FROM t4 where id = 1; +SELECT xy FROM t5 where id = 1; + +UPDATE t1,t4 SET t1.xy = 4, t4.xy = 4 WHERE t1.id IN (SELECT id FROM t3 WHERE id = 1) AND t4.id IN (SELECT id FROM t3 WHERE id = 1); +SELECT xy FROM t1 where id = 1; +SELECT xy FROM t2 where id = 1; +SELECT xy FROM t4 where id = 1; +SELECT xy FROM t5 where id = 1; + +INSERT INTO t1 VALUES (1,0) ON DUPLICATE KEY UPDATE xy = 5; +SELECT xy FROM t1 where id = 1; +SELECT xy FROM t2 where id = 1; + +DROP TRIGGER t1_update; +DROP TRIGGER t4_update; + +DELIMITER //; +CREATE TRIGGER t1_delete AFTER DELETE ON t1 FOR EACH ROW BEGIN REPLACE INTO t2 SELECT * FROM t1 WHERE t1.id > 4; END // +DELIMITER ;// + +DELIMITER //; +CREATE TRIGGER t4_delete AFTER DELETE ON t4 FOR EACH ROW BEGIN REPLACE INTO t5 SELECT * FROM t4 WHERE t4.id > 4; END // +DELIMITER ;// + +INSERT INTO t1 VALUES (5, 0),(6,0); +INSERT INTO t2 VALUES (5, 1),(6,1); +INSERT INTO t3 VALUES (5); +SELECT * FROM t1 order by id; +SELECT * FROM t2 order by id; +DELETE FROM t1 WHERE id IN (SELECT id FROM t3 WHERE id = 5); +SELECT * FROM t1 order by id; +SELECT * FROM t2 order by id; + +INSERT INTO t1 VALUES (5,0); +UPDATE t2 SET xy = 1 WHERE id = 6; +TRUNCATE t4; +INSERT INTO t4 SELECT * FROM t1; +TRUNCATE t5; +INSERT INTO t5 SELECT * FROM t2; +SELECT * FROM t1 order by id; +SELECT * FROM t2 order by id; +SELECT * FROM t4 order by id; +SELECT * FROM t5 order by id; +DELETE FROM t1,t4 USING t1,t3,t4 WHERE t1.id IN (SELECT id FROM t3 WHERE id = 5) AND t4.id IN (SELECT id FROM t3 WHERE id = 5); +SELECT * FROM t1 order by id; +SELECT * FROM t2 order by id; +SELECT * FROM t4 order by id; +SELECT * FROM t5 order by id; + +INSERT INTO t1 VALUES (5, 0); +REPLACE INTO t2 VALUES (6,1); +SELECT * FROM t1 order by id; +SELECT * FROM t2 order by id; +REPLACE INTO t1 VALUES (5, 1); +SELECT * FROM t1 order by id; +SELECT * FROM t2 order by id; + +DROP TRIGGER t1_delete; +DROP TRIGGER t4_delete; +DROP TABLE t1, t2, t3, t4, t5; + --echo End of 5.0 tests diff --git a/mysql-test/t/openssl_1.test b/mysql-test/t/openssl_1.test index 8772b8157e3..362443023e1 100644 --- a/mysql-test/t/openssl_1.test +++ b/mysql-test/t/openssl_1.test @@ -96,4 +96,11 @@ drop table t1; --error 1 --exec $MYSQL_TEST --ssl-cert= --max-connect-retries=1 < $MYSQLTEST_VARDIR/tmp/test.sql 2>&1 - +# +# Bug#25309 SSL connections without CA certificate broken since MySQL 5.0.23 +# +# Test that we can open encrypted connection to server without +# verification of servers certificate by setting both ca certificate +# and ca path to NULL +# +--exec $MYSQL --ssl --ssl-key=$MYSQL_TEST_DIR/std_data/client-key.pem --ssl-cert=$MYSQL_TEST_DIR/std_data/client-cert.pem -e "SHOW STATUS LIKE 'ssl_Cipher'" 2>&1 diff --git a/mysql-test/t/order_by.test b/mysql-test/t/order_by.test index 4597276e3bc..3e8fa07dfb7 100644 --- a/mysql-test/t/order_by.test +++ b/mysql-test/t/order_by.test @@ -617,7 +617,6 @@ UPDATE bug25126 SET MissingCol = val ORDER BY MissingCol; UPDATE bug25126 SET MissingCol = MissingCol ORDER BY MissingCol; DROP TABLE bug25126; - # # Bug #25427: crash when order by expression contains a name # that cannot be resolved unambiguously @@ -633,6 +632,41 @@ SELECT p.a AS val, q.a AS val FROM t1 p, t1 q ORDER BY val > 1; DROP TABLE t1; +# +# Bug #27532: ORDER/GROUP BY expressions with IN/BETWEEN and NOT IN/BETWEEN +# + +CREATE TABLE t1 (a int); +INSERT INTO t1 VALUES (3), (2), (4), (1); + +SELECT a, IF(a IN (2,3), a, a+10) FROM t1 + ORDER BY IF(a IN (2,3), a, a+10); +SELECT a, IF(a NOT IN (2,3), a, a+10) FROM t1 + ORDER BY IF(a NOT IN (2,3), a, a+10); +SELECT a, IF(a IN (2,3), a, a+10) FROM t1 + ORDER BY IF(a NOT IN (2,3), a, a+10); + +SELECT a, IF(a BETWEEN 2 AND 3, a, a+10) FROM t1 + ORDER BY IF(a BETWEEN 2 AND 3, a, a+10); +SELECT a, IF(a NOT BETWEEN 2 AND 3, a, a+10) FROM t1 + ORDER BY IF(a NOT BETWEEN 2 AND 3, a, a+10); +SELECT a, IF(a BETWEEN 2 AND 3, a, a+10) FROM t1 + ORDER BY IF(a NOT BETWEEN 2 AND 3, a, a+10); + +SELECT IF(a IN (1,2), a, '') as x1, IF(a NOT IN (1,2), a, '') as x2 + FROM t1 GROUP BY x1, x2; +SELECT IF(a IN (1,2), a, '') as x1, IF(a NOT IN (1,2), a, '') as x2 + FROM t1 GROUP BY x1, IF(a NOT IN (1,2), a, ''); + +# The remaining queries are for better coverage +SELECT a, a IN (1,2) FROM t1 ORDER BY a IN (1,2); +SELECT a FROM t1 ORDER BY a IN (1,2); +SELECT a+10 FROM t1 ORDER BY a IN (1,2); +SELECT a, IF(a IN (1,2), a, a+10) FROM t1 + ORDER BY IF(a IN (3,4), a, a+10); +DROP TABLE t1; + +# End of 4.1 create table t1 (a int not null, b int not null, c int not null); insert t1 values (1,1,1),(1,1,2),(1,2,1); select a, b from t1 group by a, b order by sum(c); diff --git a/mysql-test/t/rpl_ignore_table.test b/mysql-test/t/rpl_ignore_table.test index b875075f71c..79235f0cd4a 100644 --- a/mysql-test/t/rpl_ignore_table.test +++ b/mysql-test/t/rpl_ignore_table.test @@ -29,6 +29,105 @@ DROP TABLE t4; # +# Bug#25482 GRANT statements are not replicated if +# you use "replicate-ignore-table" +# + +--echo **** Test case for BUG#25482 **** +--echo **** Adding GRANTS on master **** + +connection master; +create table test.t1(a int); +create table test.t4(a int); + +# Simple user that should not replicate +GRANT SELECT ON test.t1 TO mysqltest1@localhost; + +# Partial replicate +GRANT INSERT ON test.t4 TO mysqltest2@localhost; +GRANT select, update, insert, references on t1 + to mysqltest2@localhost; + +# Partial replicate 2 +GRANT SELECT ON test.* TO mysqltest3@localhost; +GRANT INSERT ON test.t4 TO mysqltest3@localhost; +GRANT select(a), update(a), insert(a), references(a) on t4 + to mysqltest3@localhost; + +# Create another database and table +create database mysqltest2; +create table mysqltest2.t2 (id int); +# Create a grant that should replicate +GRANT SELECT ON mysqltest2.t2 TO mysqltest4@localhost IDENTIFIED BY 'pass'; + +# Create a grant manually +insert into mysql.user (user, host) values ("mysqltest5", "somehost"); + +# Partial replicate 3 with *.* +GRANT SELECT ON *.* TO mysqltest6@localhost; +GRANT INSERT ON *.* TO mysqltest6@localhost; +GRANT INSERT ON test.* TO mysqltest6@localhost; +GRANT INSERT ON test.t1 TO mysqltest6@localhost; + +show grants for mysqltest1@localhost; +show grants for mysqltest2@localhost; +show grants for mysqltest3@localhost; +show grants for mysqltest4@localhost; +show grants for mysqltest6@localhost; + +flush privileges; +show grants for mysqltest5@somehost; + + +sync_slave_with_master; + +--echo **** Checking grants on slave **** + +# Check that grants are replicated to slave +show grants for mysqltest2@localhost; +show grants for mysqltest3@localhost; +show grants for mysqltest4@localhost; +show grants for mysqltest5@somehost; +show grants for mysqltest6@localhost; + +# mysqltest1 should not be on slave +--error 1141 +show grants for mysqltest1@localhost; + +--echo **** Revoking grants on master **** +connection master; +REVOKE SELECT ON test.t1 FROM mysqltest1@localhost; +REVOKE SELECT ON mysqltest2.t2 FROM mysqltest4@localhost; +REVOKE select(a) on t4 + from mysqltest3@localhost; + +show grants for mysqltest1@localhost; +show grants for mysqltest3@localhost; +show grants for mysqltest4@localhost; + +sync_slave_with_master; + +--echo **** Checking grants on slave **** + +# mysqltest1 should not be on slave +--error 1141 +show grants for mysqltest1@localhost; +show grants for mysqltest3@localhost; +show grants for mysqltest4@localhost; + +# Cleanup +connection master; +drop table t1, t4, mysqltest2.t2; +drop database mysqltest2; +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%"; +sync_slave_with_master; + +connection master; + +# # bug#22877 replication character sets get out of sync # using replicate-wild-ignore-table # diff --git a/mysql-test/t/sp.test b/mysql-test/t/sp.test index 6aab1ae3c6a..2bc9e7c1946 100644 --- a/mysql-test/t/sp.test +++ b/mysql-test/t/sp.test @@ -6971,9 +6971,54 @@ use test| # -# NOTE: The delimiter is `|`, and not `;`. It is changed to `;` -# at the end of the file! -# +# Bug#20777: Function w BIGINT UNSIGNED shows diff. behaviour --ps-protocol +--disable_warnings +drop function if exists bug20777| +drop table if exists examplebug20777| +--enabled_warnings +create function bug20777(f1 bigint unsigned) returns bigint unsigned +begin + set f1 = (f1 - 10); set f1 = (f1 + 10); +return f1; +end| +delimiter ;| +select bug20777(9223372036854775803) as '9223372036854775803 2**63-5'; +select bug20777(9223372036854775804) as '9223372036854775804 2**63-4'; +select bug20777(9223372036854775805) as '9223372036854775805 2**63-3'; +select bug20777(9223372036854775806) as '9223372036854775806 2**63-2'; +select bug20777(9223372036854775807) as '9223372036854775807 2**63-1'; +select bug20777(9223372036854775808) as '9223372036854775808 2**63+0'; +select bug20777(9223372036854775809) as '9223372036854775809 2**63+1'; +select bug20777(9223372036854775810) as '9223372036854775810 2**63+2'; +select bug20777(-9223372036854775808) as 'lower bounds signed bigint'; +select bug20777(9223372036854775807) as 'upper bounds signed bigint'; +select bug20777(0) as 'lower bounds unsigned bigint'; +select bug20777(18446744073709551615) as 'upper bounds unsigned bigint'; +select bug20777(18446744073709551616) as 'upper bounds unsigned bigint + 1'; +select bug20777(-1) as 'lower bounds unsigned bigint - 1'; + +create table examplebug20777 as select + 0 as 'i', + bug20777(9223372036854775806) as '2**63-2', + bug20777(9223372036854775807) as '2**63-1', + bug20777(9223372036854775808) as '2**63', + bug20777(9223372036854775809) as '2**63+1', + bug20777(18446744073709551614) as '2**64-2', + bug20777(18446744073709551615) as '2**64-1', + bug20777(18446744073709551616) as '2**64', + bug20777(0) as '0', + bug20777(-1) as '-1'; +insert into examplebug20777 values (1, 9223372036854775806, 9223372036854775807, 223372036854775808, 9223372036854775809, 18446744073709551614, 18446744073709551615, 8446744073709551616, 0, -1); +show create table examplebug20777; +select * from examplebug20777 order by i; + +drop table examplebug20777; +select bug20777(18446744073709551613)+1; +drop function bug20777; +delimiter |; + +### +--echo End of 5.0 tests. # # BUG#NNNN: New bug synopsis @@ -6982,9 +7027,13 @@ use test| #drop procedure if exists bugNNNN| #--enable_warnings #create procedure bugNNNN... - +# # Add bugs above this line. Use existing tables t1 and t2 when -# practical, or create table t3, t4 etc temporarily (and drop them). +# practical, or create table t3,t4 etc temporarily (and drop them). +# NOTE: The delimiter is `|`, and not `;`. It is changed to `;` +# at the end of the file! +# + delimiter ;| drop table t1,t2; diff --git a/mysql-test/t/ssl_des-master.opt b/mysql-test/t/ssl_des-master.opt deleted file mode 100644 index 0b2b8cb85ac..00000000000 --- a/mysql-test/t/ssl_des-master.opt +++ /dev/null @@ -1 +0,0 @@ ---loose_ssl-cert=std_data/server-cert-des.pem --loose_ssl-key=std_data/server-key-des.pem diff --git a/mysql-test/t/strict.test b/mysql-test/t/strict.test index 224a7422de1..5e4d956527b 100644 --- a/mysql-test/t/strict.test +++ b/mysql-test/t/strict.test @@ -14,7 +14,6 @@ DROP TABLE IF EXISTS t1; CREATE TABLE t1 (col1 date); 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 @@ -100,7 +99,6 @@ set @@sql_mode='ansi,traditional'; CREATE TABLE t1 (col1 datetime); 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 @@ -194,7 +192,6 @@ 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 @@ -216,7 +213,6 @@ 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 @@ -271,7 +267,6 @@ INSERT INTO t1 (col3) VALUES (CAST('2004-10-15 10:15' AS DATETIME)); # 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 @@ -299,7 +294,6 @@ INSERT INTO t1 (col1) VALUES(CAST('0000-00-00' AS DATE)); # 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 @@ -367,7 +361,6 @@ INSERT INTO t1 (col3) VALUES (CONVERT('2004-10-15 10:15',DATETIME)); # 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 @@ -394,7 +387,6 @@ INSERT INTO t1 (col1) VALUES(CONVERT('0000-00-00',DATE)); # 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 @@ -1208,3 +1200,53 @@ create table t1 (i int) comment '123456789*123456789*123456789*123456789*123456789*123456789*'; show create table t1; drop table t1; + +# +# Bug #26359: Strings becoming truncated and converted to numbers under STRICT mode +# +set sql_mode= 'traditional'; +create table t1(col1 tinyint, col2 tinyint unsigned, + col3 smallint, col4 smallint unsigned, + col5 mediumint, col6 mediumint unsigned, + col7 int, col8 int unsigned, + col9 bigint, col10 bigint unsigned); +--error 1366 +insert into t1(col1) values('-'); +--error 1366 +insert into t1(col2) values('+'); +--error 1366 +insert into t1(col3) values('-'); +--error 1366 +insert into t1(col4) values('+'); +--error 1366 +insert into t1(col5) values('-'); +--error 1366 +insert into t1(col6) values('+'); +--error 1366 +insert into t1(col7) values('-'); +--error 1366 +insert into t1(col8) values('+'); +--error 1366 +insert into t1(col9) values('-'); +--error 1366 +insert into t1(col10) values('+'); +drop table t1; + +# +# Bug #27176: Assigning a string to an year column has unexpected results +# +set sql_mode='traditional'; +create table t1(a year); +--error 1366 +insert into t1 values ('-'); +--error 1366 +insert into t1 values ('+'); +--error 1366 +insert into t1 values (''); +--error 1265 +insert into t1 values ('2000a'); +--error 1265 +insert into t1 values ('2E3x'); +drop table t1; + +--echo End of 5.0 tests diff --git a/mysql-test/t/type_set.test b/mysql-test/t/type_set.test index 56df3328246..b1c816f3371 100644 --- a/mysql-test/t/type_set.test +++ b/mysql-test/t/type_set.test @@ -39,3 +39,20 @@ SELECT c FROM t1 ORDER BY concat(c); DROP TABLE t1; # End of 4.1 tests + +# +# Bug#27069 set with identical elements are created +# +--error 1097 +create table t1(f1 +set('1','2','3','4','5','6','7','8','9','10','11','12','13','14','15','16','17', +'18','19','20','21','22','23','24','25','26','27','28','29','30','31','32','33', +'34','35','36','37','38','39','40','41','42','43','44','45','46','47','48','49', +'50','51','52','53','54','55','56','57','58','59','60','61','62','63','64','128')); +create table t1(f1 +set('1','2','3','4','5','6','7','8','9','10','11','12','13','14','15','16','17', +'18','19','20','21','22','23','24','25','26','27','28','29','30','31','32','33', +'34','35','36','37','38','39','40','41','42','43','44','45','46','47','48','49', +'50','51','52','53','54','55','56','57','58','59','60','61','62','63','64','1')); +show create table t1; +drop table t1; diff --git a/mysql-test/t/type_year.test b/mysql-test/t/type_year.test index 9744da24c02..0e174a556d6 100644 --- a/mysql-test/t/type_year.test +++ b/mysql-test/t/type_year.test @@ -21,4 +21,12 @@ insert into t1 values (now()); select if(y = now(), 1, 0) from t1; drop table t1; -# End of 4.1 tests +# +# Bug #27176: Assigning a string to an year column has unexpected results +# +create table t1(a year); +insert into t1 values (2000.5), ('2000.5'), ('2001a'), ('2.001E3'); +select * from t1; +drop table t1; + +--echo End of 5.0 tests diff --git a/mysys/mf_tempfile.c b/mysys/mf_tempfile.c index 431674c5d61..c1108f85054 100644 --- a/mysys/mf_tempfile.c +++ b/mysys/mf_tempfile.c @@ -22,15 +22,36 @@ #include <paths.h> #endif -#ifdef HAVE_TEMPNAM -#if !defined(MSDOS) && !defined(OS2) && !defined(__NETWARE__) -extern char **environ; -#endif -#endif + /* - Create a temporary file in a given directory - This function should be used instead of my_tempnam() ! + @brief + Create a temporary file with unique name in a given directory + + @details + create_temp_file + to pointer to buffer where temporary filename will be stored + dir directory where to create the file + prefix prefix the filename with this + mode Flags to use for my_create/my_open + MyFlags Magic flags + + @return + File descriptor of opened file if success + -1 and sets errno if fails. + + @note + The behaviour of this function differs a lot between + implementation, it's main use is to generate a file with + a name that does not already exist. + + When passing O_TEMPORARY flag in "mode" the file should + be automatically deleted + + The implementation using mkstemp should be considered the + reference implementation when adding a new or modifying an + existing one + */ File create_temp_file(char *to, const char *dir, const char *prefix, @@ -38,41 +59,33 @@ File create_temp_file(char *to, const char *dir, const char *prefix, myf MyFlags __attribute__((unused))) { File file= -1; + DBUG_ENTER("create_temp_file"); -#if defined(_MSC_VER) + DBUG_PRINT("enter", ("dir: %s, prefix: %s", dir, prefix)); +#if defined (__WIN__) + + /* + Use GetTempFileName to generate a unique filename, create + the file and release it's handle + - uses up to the first three letters from prefix + */ + if (GetTempFileName(dir, prefix, 0, to) == 0) + DBUG_RETURN(-1); + + DBUG_PRINT("info", ("name: %s", to)); + + /* + Open the file without the "open only if file doesn't already exist" + since the file has already been created by GetTempFileName + */ + if ((file= my_open(to, (mode & ~O_EXCL), MyFlags)) < 0) { - char temp[FN_REFLEN],*end,*res,**old_env,*temp_env[1]; - old_env=environ; - if (dir) - { - end=strend(dir)-1; - if (!dir[0]) - { /* Change empty string to current dir */ - to[0]= FN_CURLIB; - to[1]= 0; - dir=to; - } - else if (*end == FN_DEVCHAR) - { /* Get current dir for drive */ - _fullpath(temp,dir,FN_REFLEN); - dir=to; - } - else if (*end == FN_LIBCHAR && dir < end && end[-1] != FN_DEVCHAR) - { - strmake(to,dir,(uint) (end-dir)); /* Copy and remove last '\' */ - dir=to; - } - environ=temp_env; /* Force use of dir (dir not checked) */ - temp_env[0]=0; - } - if ((res=tempnam((char*) dir,(char *) prefix))) - { - strmake(to,res,FN_REFLEN-1); - (*free)(res); - file=my_create(to,0, mode | O_EXCL | O_NOFOLLOW, MyFlags); - } - environ=old_env; + /* Open failed, remove the file created by GetTempFileName */ + int tmp= my_errno; + (void) my_delete(to, MYF(0)); + my_errno= tmp; } + #elif defined(_ZTC__) if (!dir) dir=getenv("TMPDIR"); @@ -101,6 +114,8 @@ File create_temp_file(char *to, const char *dir, const char *prefix, } strmov(convert_dirname(to,dir,NullS),prefix_buff); org_file=mkstemp(to); + if (mode & O_TEMPORARY) + (void) my_delete(to, MYF(MY_WME | ME_NOINPUT)); file=my_register_filename(org_file, to, FILE_BY_MKSTEMP, EE_CANTCREATEFILE, MyFlags); /* If we didn't manage to register the name, remove the temp file */ @@ -113,6 +128,10 @@ File create_temp_file(char *to, const char *dir, const char *prefix, } #elif defined(HAVE_TEMPNAM) { +#if !defined(__NETWARE__) + extern char **environ; +#endif + char *res,**old_env,*temp_env[1]; if (dir && !dir[0]) { /* Change empty string to current dir */ @@ -120,16 +139,7 @@ File create_temp_file(char *to, const char *dir, const char *prefix, to[1]= 0; dir=to; } -#ifdef OS2 - /* changing environ variable doesn't work with VACPP */ - char buffer[256], *end; - buffer[sizeof(buffer)-1]= 0; - end= strxnmov(buffer, sizeof(buffer)-1, (char*) "TMP=", dir, NullS); - /* remove ending backslash */ - if (end[-1] == '\\') - end[-1]= 0; - putenv(buffer); -#elif !defined(__NETWARE__) +#if !defined(__NETWARE__) old_env= (char**) environ; if (dir) { /* Don't use TMPDIR if dir is given */ @@ -151,45 +161,12 @@ File create_temp_file(char *to, const char *dir, const char *prefix, { DBUG_PRINT("error",("Got error: %d from tempnam",errno)); } -#if !defined(OS2) && !defined(__NETWARE__) +#if !defined(__NETWARE__) environ=(const char**) old_env; #endif } #else - { - register long uniq; - register int length; - my_string pos,end_pos; - /* Make an unique number */ - pthread_mutex_lock(&THR_LOCK_open); - uniq= ((long) getpid() << 20) + (long) _my_tempnam_used++ ; - pthread_mutex_unlock(&THR_LOCK_open); - if (!dir && !(dir=getenv("TMPDIR"))) /* Use this if possibly */ - dir=P_tmpdir; /* Use system default */ - length=strlen(dir)+strlen(pfx)+1; - - DBUG_PRINT("test",("mallocing %d byte",length+8+sizeof(TMP_EXT)+1)); - if (length+8+sizeof(TMP_EXT)+1 > FN_REFLENGTH) - errno=my_errno= ENAMETOOLONG; - else - { - end_pos=strmov(to,dir); - if (end_pos != to && end_pos[-1] != FN_LIBCHAR) - *end_pos++=FN_LIBCHAR; - end_pos=strmov(end_pos,pfx); - - for (length=0 ; length < 8 && uniq ; length++) - { - *end_pos++= _dig_vec_upper[(int) (uniq & 31)]; - uniq >>= 5; - } - (void) strmov(end_pos,TMP_EXT); - file=my_create(to,0, - (int) (O_RDWR | O_BINARY | O_TRUNC | O_EXCL | O_NOFOLLOW | - O_TEMPORARY | O_SHORT_LIVED), - MYF(MY_WME)); - } - } +#error No implementation found for create_temp_file #endif if (file >= 0) thread_safe_increment(my_tmp_file_created,&THR_LOCK_open); diff --git a/mysys/my_malloc.c b/mysys/my_malloc.c index 3baf55d4c57..38d0263b495 100644 --- a/mysys/my_malloc.c +++ b/mysys/my_malloc.c @@ -37,7 +37,7 @@ gptr my_malloc(unsigned int size, myf my_flags) if (my_flags & MY_FAE) error_handler_hook=fatal_error_handler_hook; if (my_flags & (MY_FAE+MY_WME)) - my_error(EE_OUTOFMEMORY, MYF(ME_BELL+ME_WAITTANG),size); + my_error(EE_OUTOFMEMORY, MYF(ME_BELL+ME_WAITTANG+ME_NOREFRESH),size); if (my_flags & MY_FAE) exit(1); } diff --git a/mysys/my_static.c b/mysys/my_static.c index 694e5058bb0..77dbffb911e 100644 --- a/mysys/my_static.c +++ b/mysys/my_static.c @@ -69,11 +69,6 @@ my_bool my_use_large_pages= 0; uint my_large_page_size= 0; #endif - /* from my_tempnam */ -#if !defined(HAVE_TEMPNAM) || defined(HPUX11) -int _my_tempnam_used=0; -#endif - /* from safe_malloc */ uint sf_malloc_prehunc=0, /* If you have problem with core- */ sf_malloc_endhunc=0, /* dump when malloc-message.... */ diff --git a/mysys/my_static.h b/mysys/my_static.h index cbd293a0431..b438c936225 100644 --- a/mysys/my_static.h +++ b/mysys/my_static.h @@ -60,10 +60,6 @@ extern const char *soundex_map; extern USED_MEM* my_once_root_block; extern uint my_once_extra; -#if !defined(HAVE_TEMPNAM) || defined(HPUX11) -extern int _my_tempnam_used; -#endif - extern byte *sf_min_adress,*sf_max_adress; extern uint sf_malloc_count; extern struct st_irem *sf_malloc_root; diff --git a/mysys/safemalloc.c b/mysys/safemalloc.c index f43c860adb0..a7d8f372151 100644 --- a/mysys/safemalloc.c +++ b/mysys/safemalloc.c @@ -150,11 +150,11 @@ gptr _mymalloc(uint size, const char *filename, uint lineno, myf MyFlags) char buff[SC_MAXWIDTH]; my_errno=errno; sprintf(buff,"Out of memory at line %d, '%s'", lineno, filename); - my_message(EE_OUTOFMEMORY,buff,MYF(ME_BELL+ME_WAITTANG)); + my_message(EE_OUTOFMEMORY, buff, MYF(ME_BELL+ME_WAITTANG+ME_NOREFRESH)); sprintf(buff,"needed %d byte (%ldk), memory in use: %ld bytes (%ldk)", size, (size + 1023L) / 1024L, sf_malloc_max_memory, (sf_malloc_max_memory + 1023L) / 1024L); - my_message(EE_OUTOFMEMORY,buff,MYF(ME_BELL+ME_WAITTANG)); + my_message(EE_OUTOFMEMORY, buff, MYF(ME_BELL+ME_WAITTANG+ME_NOREFRESH)); } DBUG_PRINT("error",("Out of memory, in use: %ld at line %d, '%s'", sf_malloc_max_memory,lineno, filename)); diff --git a/ndb/src/common/transporter/TCP_Transporter.cpp b/ndb/src/common/transporter/TCP_Transporter.cpp index 9f873f0476c..c8095defd86 100644 --- a/ndb/src/common/transporter/TCP_Transporter.cpp +++ b/ndb/src/common/transporter/TCP_Transporter.cpp @@ -155,6 +155,8 @@ TCP_Transporter::initTransporter() { void TCP_Transporter::setSocketOptions(){ + int sockOptKeepAlive = 1; + if (setsockopt(theSocket, SOL_SOCKET, SO_RCVBUF, (char*)&sockOptRcvBufSize, sizeof(sockOptRcvBufSize)) < 0) { #ifdef DEBUG_TRANSPORTER @@ -169,6 +171,11 @@ TCP_Transporter::setSocketOptions(){ #endif }//if + if (setsockopt(theSocket, SOL_SOCKET, SO_KEEPALIVE, + (char*)&sockOptKeepAlive, sizeof(sockOptKeepAlive)) < 0) { + ndbout_c("The setsockopt SO_KEEPALIVE error code = %d", InetErrno); + }//if + //----------------------------------------------- // Set the TCP_NODELAY option so also small packets are sent // as soon as possible diff --git a/ndb/src/kernel/blocks/dbtup/DbtupPageMap.cpp b/ndb/src/kernel/blocks/dbtup/DbtupPageMap.cpp index 60a83e46cd9..49c7af4161a 100644 --- a/ndb/src/kernel/blocks/dbtup/DbtupPageMap.cpp +++ b/ndb/src/kernel/blocks/dbtup/DbtupPageMap.cpp @@ -452,6 +452,13 @@ Uint32 Dbtup::leafPageRangeFull(Fragrecord* const regFragPtr, PageRangePtr curr ptrCheckGuard(parentPageRangePtr, cnoOfPageRangeRec, pageRange); if (parentPageRangePtr.p->currentIndexPos < 3) { ljam(); + + if (c_noOfFreePageRanges < tiprNoLevels) + { + ljam(); + return RNIL; + }//if + /* ---------------------------------------------------------------- */ /* WE HAVE FOUND AN EMPTY ENTRY IN A PAGE RANGE RECORD. */ /* ALLOCATE A NEW PAGE RANGE RECORD, FILL IN THE START RANGE, */ diff --git a/ndb/src/mgmclient/CommandInterpreter.cpp b/ndb/src/mgmclient/CommandInterpreter.cpp index e3ca1efeeea..2265579ad1e 100644 --- a/ndb/src/mgmclient/CommandInterpreter.cpp +++ b/ndb/src/mgmclient/CommandInterpreter.cpp @@ -2026,6 +2026,9 @@ CommandInterpreter::executeRestart(Vector<BaseString> &command_list, return -1; } + if (!nostart) + ndbout_c("Shutting down nodes with \"-n, no start\" option, to subsequently start the nodes."); + result= ndb_mgm_restart3(m_mgmsrv, no_of_nodes, node_ids, initialstart, nostart, abort, &need_disconnect); diff --git a/ndb/src/mgmsrv/InitConfigFileParser.cpp b/ndb/src/mgmsrv/InitConfigFileParser.cpp index 7735f7106e7..fc25197cf38 100644 --- a/ndb/src/mgmsrv/InitConfigFileParser.cpp +++ b/ndb/src/mgmsrv/InitConfigFileParser.cpp @@ -657,7 +657,7 @@ InitConfigFileParser::store_in_properties(Vector<struct my_option>& options, if (options[i].var_type == GET_INT) ctx.m_currentSection->put(options[i].name, (Uint32)value_int); else - ctx.m_currentSection->put(options[i].name, value_int); + ctx.m_currentSection->put64(options[i].name, value_int); } } return true; diff --git a/ndb/src/ndbapi/NdbScanFilter.cpp b/ndb/src/ndbapi/NdbScanFilter.cpp index 89abba2eddc..eb0ef4ba391 100644 --- a/ndb/src/ndbapi/NdbScanFilter.cpp +++ b/ndb/src/ndbapi/NdbScanFilter.cpp @@ -328,12 +328,18 @@ NdbScanFilterImpl::cond_col(Interpreter::UnaryCondition op, Uint32 AttrId){ int NdbScanFilter::isnull(int AttrId){ - return m_impl.cond_col(Interpreter::IS_NULL, AttrId); + if(m_impl.m_negative == 1) + return m_impl.cond_col(Interpreter::IS_NOT_NULL, AttrId); + else + return m_impl.cond_col(Interpreter::IS_NULL, AttrId); } int NdbScanFilter::isnotnull(int AttrId){ - return m_impl.cond_col(Interpreter::IS_NOT_NULL, AttrId); + if(m_impl.m_negative == 1) + return m_impl.cond_col(Interpreter::IS_NULL, AttrId); + else + return m_impl.cond_col(Interpreter::IS_NOT_NULL, AttrId); } struct tab3 { diff --git a/ndb/tools/delete_all.cpp b/ndb/tools/delete_all.cpp index ae380560e35..9b6a8cf94c6 100644 --- a/ndb/tools/delete_all.cpp +++ b/ndb/tools/delete_all.cpp @@ -67,6 +67,7 @@ int main(int argc, char** argv){ return NDBT_ProgramExit(NDBT_WRONGARGS); Ndb_cluster_connection con(opt_connect_str); + con.set_name("ndb_delete_all"); if(con.connect(12, 5, 1) != 0) { ndbout << "Unable to connect to management server." << endl; diff --git a/ndb/tools/desc.cpp b/ndb/tools/desc.cpp index c2f3ea8b615..83258515796 100644 --- a/ndb/tools/desc.cpp +++ b/ndb/tools/desc.cpp @@ -69,6 +69,7 @@ int main(int argc, char** argv){ return NDBT_ProgramExit(NDBT_WRONGARGS); Ndb_cluster_connection con(opt_connect_str); + con.set_name("ndb_desc"); if(con.connect(12, 5, 1) != 0) { ndbout << "Unable to connect to management server." << endl; diff --git a/ndb/tools/drop_index.cpp b/ndb/tools/drop_index.cpp index 23ebfff6cf4..256c40e1924 100644 --- a/ndb/tools/drop_index.cpp +++ b/ndb/tools/drop_index.cpp @@ -61,6 +61,7 @@ int main(int argc, char** argv){ } Ndb_cluster_connection con(opt_connect_str); + con.set_name("ndb_drop_index"); if(con.connect(12, 5, 1) != 0) { return NDBT_ProgramExit(NDBT_FAILED); diff --git a/ndb/tools/drop_tab.cpp b/ndb/tools/drop_tab.cpp index d965be29f31..a7accb904a4 100644 --- a/ndb/tools/drop_tab.cpp +++ b/ndb/tools/drop_tab.cpp @@ -61,6 +61,7 @@ int main(int argc, char** argv){ } Ndb_cluster_connection con(opt_connect_str); + con.set_name("ndb_drop_table"); if(con.connect(12, 5, 1) != 0) { ndbout << "Unable to connect to management server." << endl; diff --git a/ndb/tools/listTables.cpp b/ndb/tools/listTables.cpp index db88f9bc25c..009789824e8 100644 --- a/ndb/tools/listTables.cpp +++ b/ndb/tools/listTables.cpp @@ -219,6 +219,7 @@ int main(int argc, char** argv){ _tabname = argv[0]; ndb_cluster_connection = new Ndb_cluster_connection(opt_connect_str); + ndb_cluster_connection->set_name("ndb_show_tables"); if (ndb_cluster_connection->connect(12,5,1)) fatal("Unable to connect to management server."); if (ndb_cluster_connection->wait_until_ready(30,0) < 0) diff --git a/ndb/tools/select_all.cpp b/ndb/tools/select_all.cpp index 69bd5b0f917..27d96a9c6ed 100644 --- a/ndb/tools/select_all.cpp +++ b/ndb/tools/select_all.cpp @@ -108,6 +108,7 @@ int main(int argc, char** argv){ } Ndb_cluster_connection con(opt_connect_str); + con.set_name("ndb_select_all"); if(con.connect(12, 5, 1) != 0) { ndbout << "Unable to connect to management server." << endl; diff --git a/ndb/tools/select_count.cpp b/ndb/tools/select_count.cpp index 8933d803f53..552d156b665 100644 --- a/ndb/tools/select_count.cpp +++ b/ndb/tools/select_count.cpp @@ -83,6 +83,7 @@ int main(int argc, char** argv){ } Ndb_cluster_connection con(opt_connect_str); + con.set_name("ndb_select_count"); if(con.connect(12, 5, 1) != 0) { ndbout << "Unable to connect to management server." << endl; diff --git a/scripts/mysql_install_db.sh b/scripts/mysql_install_db.sh index 5dd5d86c666..c1a27eb0bc8 100644 --- a/scripts/mysql_install_db.sh +++ b/scripts/mysql_install_db.sh @@ -135,6 +135,17 @@ else fi fi +# Check that no previous MySQL installation exist +if test -f "$ldata/mysql/db.frm" +then + echo "FATAL ERROR: Found already existing MySQL system tables" + echo "in $ldata." + echo "If you are upgrading from a previous MySQL version you" + echo "should run '$bindir/mysql_upgrade', " + echo "to upgrade all tables for this version of MySQL" + exit 1; +fi + # Find SQL scripts needed for bootstrap fill_help_tables="fill_help_tables.sql" create_system_tables="mysql_system_tables.sql" @@ -181,7 +192,6 @@ then fi # Find executables and paths -mdata=$ldata/mysql mysqld=$execdir/mysqld mysqld_opt="" scriptdir=$bindir @@ -264,12 +274,6 @@ if test -w / -a ! -z "$user"; then chown $user $ldata $ldata/mysql $ldata/test; fi -# Check is "db" table already exist -if test ! -f $mdata/db.frm -then - db_table_already_exist="yes" -fi - if test -n "$user"; then args="$args --user=$user" fi @@ -322,16 +326,6 @@ then echo "$bindir/mysqladmin -u root -h $hostname password 'new-password'" echo "See the manual for more instructions." - # Print message about upgrading unless we have created a new db table. - if test -z "$db_table_already_exist" - then - echo - echo "NOTE: If you are upgrading from a previous MySQL verision you " - echo "should run '$bindir/mysql_upgrade', to make sure all tables have " - echo "been upgraded for this version of MySQL" - fi - echo - if test "$in_rpm" = "0" then echo "You can start the MySQL daemon with:" diff --git a/sql-common/client.c b/sql-common/client.c index 1acaaea9a79..3342db4bcfe 100644 --- a/sql-common/client.c +++ b/sql-common/client.c @@ -3022,7 +3022,7 @@ mysql_options(MYSQL *mysql,enum mysql_option option, const char *arg) mysql->reconnect= *(my_bool *) arg; break; case MYSQL_OPT_SSL_VERIFY_SERVER_CERT: - if (!arg || test(*(uint*) arg)) + if (*(my_bool*) arg) mysql->options.client_flag|= CLIENT_SSL_VERIFY_SERVER_CERT; else mysql->options.client_flag&= ~CLIENT_SSL_VERIFY_SERVER_CERT; diff --git a/sql-common/my_time.c b/sql-common/my_time.c index 83b647be1bd..4032c273e35 100644 --- a/sql-common/my_time.c +++ b/sql-common/my_time.c @@ -85,8 +85,7 @@ 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->year == 0 && (ltime->month != 0 || ltime->day != 0))) + ltime->day != 29))) { *was_cut= 2; return TRUE; @@ -410,9 +409,7 @@ str_to_datetime(const char *str, uint length, MYSQL_TIME *l_time, if (number_of_fields < 3 || l_time->year > 9999 || l_time->month > 12 || l_time->day > 31 || l_time->hour > 23 || - l_time->minute > 59 || l_time->second > 59 || - (l_time->year == 0 && l_time->month == 0 && l_time->day == 0 && - (l_time->hour != 0 || l_time->minute != 0 || l_time->second != 0))) + l_time->minute > 59 || l_time->second > 59) { /* Only give warning for a zero date if there is some garbage after */ if (!not_zero_date) /* If zero date */ diff --git a/sql/examples/ha_example.cc b/sql/examples/ha_example.cc index 19c686ee495..d59ada3b445 100644 --- a/sql/examples/ha_example.cc +++ b/sql/examples/ha_example.cc @@ -211,6 +211,12 @@ ha_example::ha_example(TABLE *table_arg) If frm_error() is called then we will use this to to find out what file extentions exist for the storage engine. This is also used by the default rename_table and delete_table method in handler.cc. + + For engines that have two file name extentions (separate meta/index file + and data file), the order of elements is relevant. First element of engine + file name extentions array should be meta/index file extention. Second + element - data file extention. This order is assumed by + prepare_for_repair() when REPAIR TABLE ... USE_FRM is issued. */ static const char *ha_example_exts[] = { NullS diff --git a/sql/field.cc b/sql/field.cc index 152c1bdc364..635b10e0e5e 100644 --- a/sql/field.cc +++ b/sql/field.cc @@ -964,6 +964,31 @@ static Item_result field_types_result_type [FIELDTYPE_NUM]= /* + Test if the given string contains important data: + not spaces for character string, + or any data for binary string. + + SYNOPSIS + test_if_important_data() + cs Character set + str String to test + strend String end + + RETURN + FALSE - If string does not have important data + TRUE - If string has some important data +*/ + +static bool +test_if_important_data(CHARSET_INFO *cs, const char *str, const char *strend) +{ + if (cs != &my_charset_bin) + str+= cs->cset->scan(cs, str, strend, MY_SEQ_SPACES); + return (str < strend); +} + + +/* Detect Item_result by given field type of UNION merge result SYNOPSIS @@ -1052,64 +1077,113 @@ void Field_num::prepend_zeros(String *value) } /* - Test if given number is a int (or a fixed format float with .000) + Test if given number is a int. SYNOPSIS - test_if_int() + Field_num::check_int + cs Character set str String to test end Pointer to char after last used digit - cs Character set + length String length + error Error returned by strntoull10rnd() - NOTES - This is called after one has called my_strntol() or similar function. - This is only used to give warnings in ALTER TABLE or LOAD DATA... - - TODO - Make this multi-byte-character safe + NOTE + This is called after one has called strntoull10rnd() function. RETURN - 0 OK - 1 error. A warning is pushed if field_name != 0 + 0 ok + 1 error: empty string or wrong integer. + 2 error: garbage at the end of string. */ -bool Field::check_int(const char *str, int length, const char *int_end, - CHARSET_INFO *cs) +int Field_num::check_int(CHARSET_INFO *cs, const char *str, int length, + const char *int_end, int error) { - const char *end; - if (str == int_end) + /* Test if we get an empty string or wrong integer */ + if (str == int_end || error == MY_ERRNO_EDOM) { char buff[128]; - String tmp(buff,(uint32) sizeof(buff), system_charset_info); + String tmp(buff, (uint32) sizeof(buff), system_charset_info); tmp.copy(str, length, system_charset_info); push_warning_printf(table->in_use, MYSQL_ERROR::WARN_LEVEL_WARN, ER_TRUNCATED_WRONG_VALUE_FOR_FIELD, ER(ER_TRUNCATED_WRONG_VALUE_FOR_FIELD), "integer", tmp.c_ptr(), field_name, (ulong) table->in_use->row_count); - return 1; // Empty string + return 1; } - end= str+length; - if ((str= int_end) == end) - return 0; // OK; All digits was used + /* Test if we have garbage at the end of the given string. */ + if (test_if_important_data(cs, int_end, str + length)) + { + set_warning(MYSQL_ERROR::WARN_LEVEL_WARN, WARN_DATA_TRUNCATED, 1); + return 2; + } + return 0; +} - /* Allow end .0000 */ - if (*str == '.') + +/* + Conver a string to an integer then check bounds. + + SYNOPSIS + Field_num::get_int + cs Character set + from String to convert + len Length of the string + rnd OUT longlong value + unsigned_max max unsigned value + signed_min min signed value + signed_max max signed value + + DESCRIPTION + The function calls strntoull10rnd() to get an integer value then + check bounds and errors returned. In case of any error a warning + is raised. + + RETURN + 0 ok + 1 error +*/ + +bool Field_num::get_int(CHARSET_INFO *cs, const char *from, uint len, + longlong *rnd, ulonglong unsigned_max, + longlong signed_min, longlong signed_max) +{ + char *end; + int error; + + *rnd= (longlong) cs->cset->strntoull10rnd(cs, from, len, unsigned_flag, &end, + &error); + if (unsigned_flag) { - for (str++ ; str != end && *str == '0'; str++) - ; + + if (((ulonglong) *rnd > unsigned_max) && (*rnd= (longlong) unsigned_max) || + error == MY_ERRNO_ERANGE) + { + goto out_of_range; + } } - /* Allow end space */ - for ( ; str != end ; str++) + else { - if (!my_isspace(cs,*str)) + if (*rnd < signed_min) { - set_warning(MYSQL_ERROR::WARN_LEVEL_WARN, WARN_DATA_TRUNCATED, 1); - return 1; + *rnd= signed_min; + goto out_of_range; + } + else if (*rnd > signed_max) + { + *rnd= signed_max; + goto out_of_range; } } + if (table->in_use->count_cuted_fields && check_int(cs, from, len, end, error)) + return 1; return 0; -} +out_of_range: + set_warning(MYSQL_ERROR::WARN_LEVEL_WARN, ER_WARN_DATA_OUT_OF_RANGE, 1); + return 1; +} /* Process decimal library return codes and issue warnings for overflow and @@ -2506,45 +2580,11 @@ void Field_new_decimal::sql_type(String &str) const int Field_tiny::store(const char *from,uint len,CHARSET_INFO *cs) { - char *end; int error; - - if (unsigned_flag) - { - ulonglong tmp= cs->cset->strntoull10rnd(cs, from, len, 1, &end, &error); - if (error == MY_ERRNO_ERANGE || tmp > 255) - { - set_if_smaller(tmp, 255); - set_warning(MYSQL_ERROR::WARN_LEVEL_WARN, ER_WARN_DATA_OUT_OF_RANGE, 1); - error= 1; - } - else if (table->in_use->count_cuted_fields && check_int(from,len,end,cs)) - error= 1; - else - error= 0; - ptr[0]= (char) tmp; - } - else - { - longlong tmp= cs->cset->strntoull10rnd(cs, from, len, 0, &end, &error); - if (tmp < -128) - { - tmp= -128; - set_warning(MYSQL_ERROR::WARN_LEVEL_WARN, ER_WARN_DATA_OUT_OF_RANGE, 1); - error= 1; - } - else if (tmp >= 128) - { - tmp= 127; - set_warning(MYSQL_ERROR::WARN_LEVEL_WARN, ER_WARN_DATA_OUT_OF_RANGE, 1); - error= 1; - } - else if (table->in_use->count_cuted_fields && check_int(from,len,end,cs)) - error= 1; - else - error= 0; - ptr[0]= (char) tmp; - } + longlong rnd; + + error= get_int(cs, from, len, &rnd, 255, -128, 127); + ptr[0]= unsigned_flag ? (char) (ulonglong) rnd : (char) rnd; return error; } @@ -2709,59 +2749,20 @@ void Field_tiny::sql_type(String &res) const int Field_short::store(const char *from,uint len,CHARSET_INFO *cs) { - char *end; + int store_tmp; int error; - - if (unsigned_flag) - { - ulonglong tmp= cs->cset->strntoull10rnd(cs, from, len, 1, &end, &error); - if (error == MY_ERRNO_ERANGE || tmp > UINT_MAX16) - { - set_if_smaller(tmp, UINT_MAX16); - set_warning(MYSQL_ERROR::WARN_LEVEL_WARN, ER_WARN_DATA_OUT_OF_RANGE, 1); - error= 1; - } - else if (table->in_use->count_cuted_fields && check_int(from,len,end,cs)) - error= 1; - else - error= 0; + longlong rnd; + + error= get_int(cs, from, len, &rnd, UINT_MAX16, INT_MIN16, INT_MAX16); + store_tmp= unsigned_flag ? (int) (ulonglong) rnd : (int) rnd; #ifdef WORDS_BIGENDIAN - if (table->s->db_low_byte_first) - { - int2store(ptr,tmp); - } - else -#endif - shortstore(ptr,(short) tmp); + if (table->s->db_low_byte_first) + { + int2store(ptr, store_tmp); } else - { - longlong tmp= cs->cset->strntoull10rnd(cs, from, len, 0, &end, &error); - if (tmp < INT_MIN16) - { - tmp= INT_MIN16; - set_warning(MYSQL_ERROR::WARN_LEVEL_WARN, ER_WARN_DATA_OUT_OF_RANGE, 1); - error= 1; - } - else if (tmp > INT_MAX16) - { - tmp=INT_MAX16; - set_warning(MYSQL_ERROR::WARN_LEVEL_WARN, ER_WARN_DATA_OUT_OF_RANGE, 1); - error= 1; - } - else if (table->in_use->count_cuted_fields && check_int(from,len,end,cs)) - error= 1; - else - error= 0; -#ifdef WORDS_BIGENDIAN - if (table->s->db_low_byte_first) - { - int2store(ptr,tmp); - } - else #endif - shortstore(ptr,(short) tmp); - } + shortstore(ptr, (short) store_tmp); return error; } @@ -2989,45 +2990,13 @@ void Field_short::sql_type(String &res) const int Field_medium::store(const char *from,uint len,CHARSET_INFO *cs) { - char *end; + int store_tmp; int error; - - if (unsigned_flag) - { - ulonglong tmp= cs->cset->strntoull10rnd(cs, from, len, 1, &end, &error); - if (error == MY_ERRNO_ERANGE || tmp > UINT_MAX24) - { - set_if_smaller(tmp, UINT_MAX24); - set_warning(MYSQL_ERROR::WARN_LEVEL_WARN, ER_WARN_DATA_OUT_OF_RANGE, 1); - error= 1; - } - else if (table->in_use->count_cuted_fields && check_int(from,len,end,cs)) - error= 1; - else - error= 0; - int3store(ptr,tmp); - } - else - { - longlong tmp= cs->cset->strntoull10rnd(cs, from, len, 0, &end, &error); - if (tmp < INT_MIN24) - { - tmp= INT_MIN24; - set_warning(MYSQL_ERROR::WARN_LEVEL_WARN, ER_WARN_DATA_OUT_OF_RANGE, 1); - error= 1; - } - else if (tmp > INT_MAX24) - { - tmp=INT_MAX24; - set_warning(MYSQL_ERROR::WARN_LEVEL_WARN, ER_WARN_DATA_OUT_OF_RANGE, 1); - error= 1; - } - else if (table->in_use->count_cuted_fields && check_int(from,len,end,cs)) - error= 1; - else - error= 0; - int3store(ptr,tmp); - } + longlong rnd; + + error= get_int(cs, from, len, &rnd, UINT_MAX24, INT_MIN24, INT_MAX24); + store_tmp= unsigned_flag ? (int) (ulonglong) rnd : (int) rnd; + int3store(ptr, store_tmp); return error; } @@ -3206,45 +3175,10 @@ int Field_long::store(const char *from,uint len,CHARSET_INFO *cs) { long store_tmp; int error; - char *end; - - if (unsigned_flag) - { - ulonglong tmp= cs->cset->strntoull10rnd(cs, from, len, 1, &end, &error); - if (error == MY_ERRNO_ERANGE || tmp > (ulonglong) UINT_MAX32) - { - set_if_smaller(tmp, (ulonglong) UINT_MAX32); - set_warning(MYSQL_ERROR::WARN_LEVEL_WARN, ER_WARN_DATA_OUT_OF_RANGE, 1); - error= 1; - } - else if (table->in_use->count_cuted_fields && check_int(from,len,end,cs)) - error= 1; - else - error= 0; - store_tmp= (long) tmp; - } - else - { - longlong tmp= cs->cset->strntoull10rnd(cs, from, len, 0, &end, &error); - if (tmp < INT_MIN32) - { - tmp= INT_MIN32; - set_warning(MYSQL_ERROR::WARN_LEVEL_WARN, ER_WARN_DATA_OUT_OF_RANGE, 1); - error= 1; - } - else if (tmp > INT_MAX32) - { - tmp=INT_MAX32; - set_warning(MYSQL_ERROR::WARN_LEVEL_WARN, ER_WARN_DATA_OUT_OF_RANGE, 1); - error= 1; - } - else if (table->in_use->count_cuted_fields && check_int(from,len,end,cs)) - error= 1; - else - error= 0; - store_tmp= (long) tmp; - } - + longlong rnd; + + error= get_int(cs, from, len, &rnd, UINT_MAX32, INT_MIN32, INT_MAX32); + store_tmp= unsigned_flag ? (long) (ulonglong) rnd : (long) rnd; #ifdef WORDS_BIGENDIAN if (table->s->db_low_byte_first) { @@ -3490,7 +3424,8 @@ int Field_longlong::store(const char *from,uint len,CHARSET_INFO *cs) set_warning(MYSQL_ERROR::WARN_LEVEL_WARN, ER_WARN_DATA_OUT_OF_RANGE, 1); error= 1; } - else if (table->in_use->count_cuted_fields && check_int(from,len,end,cs)) + else if (table->in_use->count_cuted_fields && + check_int(cs, from, len, end, error)) error= 1; else error= 0; @@ -5008,16 +4943,25 @@ int Field_year::store(const char *from, uint len,CHARSET_INFO *cs) { char *end; int error; - long nr= my_strntol(cs, from, len, 10, &end, &error); + longlong nr= cs->cset->strntoull10rnd(cs, from, len, 0, &end, &error); - if (nr < 0 || nr >= 100 && nr <= 1900 || nr > 2155 || error) + if (nr < 0 || nr >= 100 && nr <= 1900 || nr > 2155 || + error == MY_ERRNO_ERANGE) { *ptr=0; set_warning(MYSQL_ERROR::WARN_LEVEL_WARN, ER_WARN_DATA_OUT_OF_RANGE, 1); return 1; } - if (table->in_use->count_cuted_fields && check_int(from,len,end,cs)) + if (table->in_use->count_cuted_fields && + (error= check_int(cs, from, len, end, error))) + { + if (error == 1) /* empty or incorrect string */ + { + *ptr= 0; + return 1; + } error= 1; + } if (nr != 0 || len != 4) { @@ -5907,31 +5851,6 @@ report_data_too_long(Field_str *field) } -/* - Test if the given string contains important data: - not spaces for character string, - or any data for binary string. - - SYNOPSIS - test_if_important_data() - cs Character set - str String to test - strend String end - - RETURN - FALSE - If string does not have important data - TRUE - If string has some important data -*/ - -static bool -test_if_important_data(CHARSET_INFO *cs, const char *str, const char *strend) -{ - if (cs != &my_charset_bin) - str+= cs->cset->scan(cs, str, strend, MY_SEQ_SPACES); - return (str < strend); -} - - /* Copy a string and fill with space */ int Field_string::store(const char *from,uint length,CHARSET_INFO *cs) @@ -8676,11 +8595,6 @@ bool create_field::init(THD *thd, char *fld_name, enum_field_types fld_type, break; case FIELD_TYPE_SET: { - if (fld_interval_list->elements > sizeof(longlong)*8) - { - my_error(ER_TOO_BIG_SET, MYF(0), fld_name); /* purecov: inspected */ - DBUG_RETURN(TRUE); - } pack_length= get_set_pack_length(fld_interval_list->elements); List_iterator<String> it(*fld_interval_list); diff --git a/sql/field.h b/sql/field.h index e82e90ce5ab..fc68a4549a9 100644 --- a/sql/field.h +++ b/sql/field.h @@ -306,8 +306,6 @@ public: virtual void set_derivation(enum Derivation derivation_arg) { } bool set_warning(MYSQL_ERROR::enum_warning_level, unsigned int code, int cuted_increment); - bool check_int(const char *str, int length, const char *int_end, - CHARSET_INFO *cs); void set_datetime_warning(MYSQL_ERROR::enum_warning_level, uint code, const char *str, uint str_len, timestamp_type ts_type, int cuted_increment); @@ -369,6 +367,11 @@ public: bool eq_def(Field *field); int store_decimal(const my_decimal *); my_decimal *val_decimal(my_decimal *); + int check_int(CHARSET_INFO *cs, const char *str, int length, + const char *int_end, int error); + bool get_int(CHARSET_INFO *cs, const char *from, uint len, + longlong *rnd, ulonglong unsigned_max, + longlong signed_min, longlong signed_max); }; diff --git a/sql/ha_archive.cc b/sql/ha_archive.cc index 2ee514f29c9..e2a2211259f 100644 --- a/sql/ha_archive.cc +++ b/sql/ha_archive.cc @@ -503,8 +503,8 @@ int ha_archive::init_archive_writer() We just implement one additional file extension. */ static const char *ha_archive_exts[] = { - ARZ, ARM, + ARZ, NullS }; diff --git a/sql/ha_innodb.cc b/sql/ha_innodb.cc index cbefa9d3949..217f59d4b7e 100644 --- a/sql/ha_innodb.cc +++ b/sql/ha_innodb.cc @@ -6066,6 +6066,15 @@ ha_innobase::external_lock( trx->isolation_level = innobase_map_isolation_level( (enum_tx_isolation) thd->variables.tx_isolation); + + if (trx->isolation_level <= TRX_ISO_READ_COMMITTED + && trx->global_read_view) { + + /* At low transaction isolation levels we let + each consistent read set its own snapshot */ + + read_view_close_for_mysql(trx); + } } if (trx->isolation_level == TRX_ISO_SERIALIZABLE diff --git a/sql/ha_ndbcluster.cc b/sql/ha_ndbcluster.cc index b02be09251f..33744b49cef 100644 --- a/sql/ha_ndbcluster.cc +++ b/sql/ha_ndbcluster.cc @@ -203,6 +203,8 @@ static const err_code_mapping err_map[]= { 284, HA_ERR_TABLE_DEF_CHANGED, 0 }, + {4009, HA_ERR_NO_CONNECTION, 1 }, + { 0, 1, 0 }, { -1, -1, 1 } @@ -2521,8 +2523,13 @@ int ha_ndbcluster::update_row(const byte *old_data, byte *new_data) ERR_RETURN(op->getNdbError()); } - // Execute update operation - if (!cursor && execute_no_commit(this,trans,false) != 0) { + /* + Execute update operation if we are not doing a scan for update + and there exist UPDATE AFTER triggers + */ + + if ((!cursor || m_update_cannot_batch) && + execute_no_commit(this,trans,false) != 0) { no_uncommitted_rows_execute_failure(); DBUG_RETURN(ndb_err(trans)); } @@ -2563,7 +2570,7 @@ int ha_ndbcluster::delete_row(const byte *record) no_uncommitted_rows_update(-1); - if (!m_primary_key_update) + if (!(m_primary_key_update || m_delete_cannot_batch)) // If deleting from cursor, NoCommit will be handled in next_result DBUG_RETURN(0); } @@ -3404,6 +3411,16 @@ int ha_ndbcluster::extra(enum ha_extra_function operation) DBUG_PRINT("info", ("Turning OFF use of write instead of insert")); m_use_write= FALSE; break; + case HA_EXTRA_DELETE_CANNOT_BATCH: + DBUG_PRINT("info", ("HA_EXTRA_DELETE_CANNOT_BATCH")); + m_delete_cannot_batch= TRUE; + break; + case HA_EXTRA_UPDATE_CANNOT_BATCH: + DBUG_PRINT("info", ("HA_EXTRA_UPDATE_CANNOT_BATCH")); + m_update_cannot_batch= TRUE; + break; + default: + break; } DBUG_RETURN(0); @@ -3420,6 +3437,8 @@ int ha_ndbcluster::reset() m_retrieve_primary_key= FALSE; m_ignore_dup_key= FALSE; m_use_write= FALSE; + m_delete_cannot_batch= FALSE; + m_update_cannot_batch= FALSE; DBUG_RETURN(0); } @@ -4785,6 +4804,8 @@ ha_ndbcluster::ha_ndbcluster(TABLE *table_arg): m_bulk_insert_rows((ha_rows) 1024), m_rows_changed((ha_rows) 0), m_bulk_insert_not_flushed(FALSE), + m_delete_cannot_batch(FALSE), + m_update_cannot_batch(FALSE), m_ops_pending(0), m_skip_auto_increment(TRUE), m_blobs_pending(0), @@ -5067,14 +5088,11 @@ int ndbcluster_table_exists_in_engine(THD* thd, const char *db, const char *name dict->invalidateTable(name); if (!(tab= dict->getTable(name))) { - const NdbError err= dict->getNdbError(); - if (err.code == 709) - DBUG_RETURN(0); - ERR_RETURN(err); + ERR_RETURN(dict->getNdbError()); } DBUG_PRINT("info", ("Found table %s", tab->getName())); - DBUG_RETURN(1); + DBUG_RETURN(HA_ERR_TABLE_EXIST); } @@ -5259,7 +5277,7 @@ int ndbcluster_find_files(THD *thd,const char *db,const char *path, DBUG_PRINT("info", ("%s existed on disk", name)); // The .ndb file exists on disk, but it's not in list of tables in ndb // Verify that handler agrees table is gone. - if (ndbcluster_table_exists_in_engine(thd, db, file_name) == 0) + if (ndbcluster_table_exists_in_engine(thd, db, file_name) == HA_ERR_NO_SUCH_TABLE) { DBUG_PRINT("info", ("NDB says %s does not exists", file_name)); it.remove(); @@ -6696,7 +6714,8 @@ pthread_handler_t ndb_util_thread_func(void *arg __attribute__((unused))) DBUG_RETURN(NULL); } - List<NDB_SHARE> util_open_tables; + uint share_list_size= 0; + NDB_SHARE **share_list= NULL; set_timespec(abstime, 0); for (;;) { @@ -6726,7 +6745,22 @@ pthread_handler_t ndb_util_thread_func(void *arg __attribute__((unused))) /* Lock mutex and fill list with pointers to all open tables */ NDB_SHARE *share; pthread_mutex_lock(&ndbcluster_mutex); - for (uint i= 0; i < ndbcluster_open_tables.records; i++) + uint i, record_count= ndbcluster_open_tables.records; + if (share_list_size < record_count) + { + NDB_SHARE ** new_share_list= new NDB_SHARE * [record_count]; + if (!new_share_list) + { + sql_print_warning("ndb util thread: malloc failure, " + "query cache not maintained properly"); + pthread_mutex_unlock(&ndbcluster_mutex); + goto next; // At least do not crash + } + delete [] share_list; + share_list_size= record_count; + share_list= new_share_list; + } + for (i= 0; i < record_count; i++) { share= (NDB_SHARE *)hash_element(&ndbcluster_open_tables, i); share->use_count++; /* Make sure the table can't be closed */ @@ -6735,14 +6769,14 @@ pthread_handler_t ndb_util_thread_func(void *arg __attribute__((unused))) i, share->table_name, share->use_count)); /* Store pointer to table */ - util_open_tables.push_back(share); + share_list[i]= share; } pthread_mutex_unlock(&ndbcluster_mutex); - /* Iterate through the open files list */ - List_iterator_fast<NDB_SHARE> it(util_open_tables); - while ((share= it++)) + /* Iterate through the open files list */ + for (i= 0; i < record_count; i++) { + share= share_list[i]; /* Split tab- and dbname */ char buf[FN_REFLEN]; char *tabname, *db; @@ -6791,10 +6825,7 @@ pthread_handler_t ndb_util_thread_func(void *arg __attribute__((unused))) /* Decrease the use count and possibly free share */ free_share(share); } - - /* Clear the list of open tables */ - util_open_tables.empty(); - +next: /* Calculate new time to wake up */ int secs= 0; int msecs= ndb_cache_check_time; @@ -6817,6 +6848,8 @@ pthread_handler_t ndb_util_thread_func(void *arg __attribute__((unused))) } } + if (share_list) + delete [] share_list; thd->cleanup(); delete thd; delete ndb; @@ -7114,7 +7147,7 @@ void ndb_serialize_cond(const Item *item, void *arg) Check that the field is part of the table of the handler instance and that we expect a field with of this result type. */ - if (context->table == field->table) + if (context->table->s == field->table->s) { const NDBTAB *tab= (const NDBTAB *) context->ndb_table; DBUG_PRINT("info", ("FIELD_ITEM")); diff --git a/sql/ha_ndbcluster.h b/sql/ha_ndbcluster.h index 6b49b0e3c70..3495f35e10f 100644 --- a/sql/ha_ndbcluster.h +++ b/sql/ha_ndbcluster.h @@ -774,6 +774,8 @@ bool uses_blob_value(bool all_fields); ha_rows m_bulk_insert_rows; ha_rows m_rows_changed; bool m_bulk_insert_not_flushed; + bool m_delete_cannot_batch; + bool m_update_cannot_batch; ha_rows m_ops_pending; bool m_skip_auto_increment; bool m_blobs_pending; diff --git a/sql/handler.cc b/sql/handler.cc index 6788d21b40f..c6c31593a5f 100644 --- a/sql/handler.cc +++ b/sql/handler.cc @@ -2438,14 +2438,14 @@ ha_find_files(THD *thd,const char *db,const char *path, Ask handler if the table exists in engine RETURN - 0 Table does not exist - 1 Table exists - # Error code + HA_ERR_NO_SUCH_TABLE Table does not exist + HA_ERR_TABLE_EXIST Table exists + # Error code */ int ha_table_exists_in_engine(THD* thd, const char* db, const char* name) { - int error= 0; + int error= HA_ERR_NO_SUCH_TABLE; DBUG_ENTER("ha_table_exists_in_engine"); DBUG_PRINT("enter", ("db: %s, name: %s", db, name)); #ifdef HAVE_NDBCLUSTER_DB diff --git a/sql/handler.h b/sql/handler.h index 9e381ca4482..9863d541b5f 100644 --- a/sql/handler.h +++ b/sql/handler.h @@ -780,6 +780,17 @@ public: virtual void free_foreign_key_create_info(char* str) {} /* The following can be called without an open handler */ virtual const char *table_type() const =0; + /* + If frm_error() is called then we will use this to find out what file + extentions exist for the storage engine. This is also used by the default + rename_table and delete_table method in handler.cc. + + For engines that have two file name extentions (separate meta/index file + and data file), the order of elements is relevant. First element of engine + file name extentions array should be meta/index file extention. Second + element - data file extention. This order is assumed by + prepare_for_repair() when REPAIR TABLE ... USE_FRM is issued. + */ virtual const char **bas_ext() const =0; virtual ulong table_flags(void) const =0; virtual ulong index_flags(uint idx, uint part, bool all_parts) const =0; diff --git a/sql/item.h b/sql/item.h index 7b0d18e19c5..2c4943bea6e 100644 --- a/sql/item.h +++ b/sql/item.h @@ -694,12 +694,11 @@ public: virtual bool get_date_result(TIME *ltime,uint fuzzydate) { return get_date(ltime,fuzzydate); } /* - This function is used only in Item_func_isnull/Item_func_isnotnull - (implementations of IS NULL/IS NOT NULL clauses). Item_func_is{not}null - calls this method instead of one of val/result*() methods, which - normally will set null_value. This allows to determine nullness of - a complex expression without fully evaluating it. - Any new item which can be NULL must implement this call. + The method allows to determine nullness of a complex expression + without fully evaluating it, instead of calling val/result*() then + checking null_value. Used in Item_func_isnull/Item_func_isnotnull + and Item_sum_count/Item_sum_count_distinct. + Any new item which can be NULL must implement this method. */ virtual bool is_null() { return 0; } diff --git a/sql/item_cmpfunc.cc b/sql/item_cmpfunc.cc index c5e7d8a0b29..3bb537c2fd5 100644 --- a/sql/item_cmpfunc.cc +++ b/sql/item_cmpfunc.cc @@ -1079,6 +1079,26 @@ longlong Item_func_strcmp::val_int() } +bool Item_func_opt_neg::eq(const Item *item, bool binary_cmp) const +{ + /* Assume we don't have rtti */ + if (this == item) + return 1; + if (item->type() != FUNC_ITEM) + return 0; + Item_func *item_func=(Item_func*) item; + if (arg_count != item_func->arg_count || + functype() != item_func->functype()) + return 0; + if (negated != ((Item_func_opt_neg *) item_func)->negated) + return 0; + for (uint i=0; i < arg_count ; i++) + if (!args[i]->eq(item_func->arguments()[i], binary_cmp)) + return 0; + return 1; +} + + void Item_func_interval::fix_length_and_dec() { use_decimal_comparison= (row->element_index(0)->result_type() == DECIMAL_RESULT) || diff --git a/sql/item_cmpfunc.h b/sql/item_cmpfunc.h index f6c6f612c5b..0c4a62aaa24 100644 --- a/sql/item_cmpfunc.h +++ b/sql/item_cmpfunc.h @@ -561,6 +561,7 @@ public: negated= !negated; return this; } + bool eq(const Item *item, bool binary_cmp) const; bool subst_argument_checker(byte **arg) { return TRUE; } }; diff --git a/sql/item_func.cc b/sql/item_func.cc index 3d92be5e9d2..c4279d1bd4e 100644 --- a/sql/item_func.cc +++ b/sql/item_func.cc @@ -230,6 +230,8 @@ void Item_func::traverse_cond(Cond_traverser traverser, (*traverser)(this, argument); } } + else + (*traverser)(this, argument); } @@ -4615,14 +4617,14 @@ void Item_func_match::init_search(bool no_order) fields.push_back(new Item_string(" ",1, cmp_collation.collation)); for (uint i=1; i < arg_count; i++) fields.push_back(args[i]); - concat=new Item_func_concat_ws(fields); + concat_ws=new Item_func_concat_ws(fields); /* Above function used only to get value and do not need fix_fields for it: Item_string - basic constant fields - fix_fields() was already called for this arguments Item_func_concat_ws - do not need fix_fields() to produce value */ - concat->quick_fix_field(); + concat_ws->quick_fix_field(); } if (master) @@ -4837,8 +4839,8 @@ double Item_func_match::val_real() if (key == NO_SUCH_KEY) { - String *a= concat->val_str(&value); - if ((null_value= (a == 0))) + String *a= concat_ws->val_str(&value); + if ((null_value= (a == 0)) || !a->length()) DBUG_RETURN(0); DBUG_RETURN(ft_handler->please->find_relevance(ft_handler, (byte *)a->ptr(), a->length())); @@ -4996,10 +4998,10 @@ longlong Item_func_row_count::val_int() } -Item_func_sp::Item_func_sp(Name_resolution_context *context_arg, - sp_name *name_arg) - :Item_func(), context(context_arg), m_name(name_arg), m_sp(NULL), - result_field(NULL) + + +Item_func_sp::Item_func_sp(Name_resolution_context *context_arg, sp_name *name) + :Item_func(), context(context_arg), m_name(name), m_sp(NULL), sp_result_field(NULL) { maybe_null= 1; m_name->init_qname(current_thd); @@ -5008,22 +5010,22 @@ Item_func_sp::Item_func_sp(Name_resolution_context *context_arg, Item_func_sp::Item_func_sp(Name_resolution_context *context_arg, - sp_name *name_arg, List<Item> &list) - :Item_func(list), context(context_arg), m_name(name_arg), m_sp(NULL), - result_field(NULL) + sp_name *name, List<Item> &list) + :Item_func(list), context(context_arg), m_name(name), m_sp(NULL),sp_result_field(NULL) { maybe_null= 1; m_name->init_qname(current_thd); dummy_table= (TABLE*) sql_calloc(sizeof(TABLE)); } + void Item_func_sp::cleanup() { - if (result_field) + if (sp_result_field) { - delete result_field; - result_field= NULL; + delete sp_result_field; + sp_result_field= NULL; } m_sp= NULL; dummy_table->s= NULL; @@ -5035,7 +5037,7 @@ Item_func_sp::func_name() const { THD *thd= current_thd; /* Calculate length to avoid reallocation of string for sure */ - uint len= ((m_name->m_db.length + + uint len= ((m_name->m_explicit_name ? m_name->m_db.length : 0 + m_name->m_name.length)*2 + //characters*quoting 2 + // ` and ` 1 + // . @@ -5045,89 +5047,127 @@ Item_func_sp::func_name() const system_charset_info); qname.length(0); - append_identifier(thd, &qname, m_name->m_db.str, m_name->m_db.length); - qname.append('.'); + if (m_name->m_explicit_name) + { + append_identifier(thd, &qname, m_name->m_db.str, m_name->m_db.length); + qname.append('.'); + } append_identifier(thd, &qname, m_name->m_name.str, m_name->m_name.length); return qname.ptr(); } -Field * -Item_func_sp::sp_result_field(void) const + +/** + @brief Initialize the result field by creating a temporary dummy table + and assign it to a newly created field object. Meta data used to + create the field is fetched from the sp_head belonging to the stored + proceedure found in the stored procedure functon cache. + + @note This function should be called from fix_fields to init the result + field. It is some what related to Item_field. + + @see Item_field + + @param thd A pointer to the session and thread context. + + @return Function return error status. + @retval TRUE is returned on an error + @retval FALSE is returned on success. +*/ +bool +Item_func_sp::init_result_field(THD *thd) { - Field *field; - DBUG_ENTER("Item_func_sp::sp_result_field"); - DBUG_PRINT("info", ("sp: %s, flags: %x, level: %lu", - (m_sp ? "YES" : "NO"), - (m_sp ? m_sp->m_flags : (uint)0), - (m_sp ? m_sp->m_recursion_level : (ulong)0))); + DBUG_ENTER("Item_func_sp::init_result_field"); + + char *empty_name= (char *) ""; + TABLE_SHARE *share; - if (!m_sp) + DBUG_ASSERT(m_sp == NULL); + DBUG_ASSERT(sp_result_field == NULL); + DBUG_ASSERT(dummy_table->s == NULL); + + if (!(m_sp= sp_find_routine(thd, TYPE_ENUM_FUNCTION, m_name, + &thd->sp_func_cache, TRUE))) { - THD *thd= current_thd; - if (!(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); - DBUG_RETURN(0); - } + my_error(ER_SP_DOES_NOT_EXIST, MYF(0), "FUNCTION", m_name->m_qname.str); + context->process_error(thd); + DBUG_RETURN(TRUE); + } + + /* + A Field need to be attached to a Table. + Below we "create" a dummy table by initializing + the needed pointers. + */ + dummy_table->s= share= &dummy_table->share_not_to_be_used; + dummy_table->alias = empty_name; + dummy_table->maybe_null = maybe_null; + dummy_table->in_use= thd; + dummy_table->copy_blobs= TRUE; + share->table_cache_key = empty_name; + share->table_name = empty_name; + + if (!(sp_result_field= m_sp->create_result_field(max_length, name, dummy_table))) + { + DBUG_RETURN(TRUE); } - if (!dummy_table->s) + + if (sp_result_field->pack_length() > sizeof(result_buf)) { - char *empty_name= (char *) ""; - TABLE_SHARE *share; - dummy_table->s= share= &dummy_table->share_not_to_be_used; - dummy_table->alias = empty_name; - dummy_table->maybe_null = maybe_null; - dummy_table->in_use= current_thd; - dummy_table->copy_blobs= TRUE; - share->table_cache_key = empty_name; - share->table_name = empty_name; + sp_result_field->move_field(sql_alloc(sp_result_field->pack_length())); + } else { + sp_result_field->move_field(result_buf); } - if (!(field= m_sp->create_result_field(max_length, name, dummy_table))) - my_message(ER_OUT_OF_RESOURCES, ER(ER_OUT_OF_RESOURCES), MYF(0)); + + sp_result_field->null_ptr= (uchar *) &null_value; + sp_result_field->null_bit= 1; + - DBUG_RETURN(field); + DBUG_RETURN(FALSE); } +/** + @brief Initialize local members with values from the Field interface. -/* - Execute function & store value in field + @note called from Item::fix_fields. +*/ +void Item_func_sp::fix_length_and_dec() +{ + DBUG_ENTER("Item_func_sp::fix_length_and_dec"); - RETURN - 0 value <> NULL - 1 value = NULL or error + DBUG_ASSERT(sp_result_field); + decimals= sp_result_field->decimals(); + max_length= sp_result_field->field_length; + collation.set(sp_result_field->charset()); + maybe_null= 1; + unsigned_flag= test(sp_result_field->flags & UNSIGNED_FLAG); + + DBUG_VOID_RETURN; +} + +/** + @brief Execute function & store value in field. + + @return Function returns error status. + @retval FALSE on success. + @retval TRUE if an error occurred. */ bool -Item_func_sp::execute(Field **flp) +Item_func_sp::execute() { THD *thd= current_thd; - Field *f; - + /* Get field in virtual tmp table to store result. Create the field if invoked first time. */ - - if (!(f= *flp)) - { - if (!(*flp= f= sp_result_field())) - { - /* Error set by sp_result_field() */ - null_value= 1; - return TRUE; - } - f->move_field((f->pack_length() > sizeof(result_buf)) ? - sql_alloc(f->pack_length()) : result_buf); - f->null_ptr= (uchar *)&null_value; - f->null_bit= 1; - } /* Execute function and store the return value in the field. */ - if (execute_impl(thd, f)) + if (execute_impl(thd)) { null_value= 1; context->process_error(thd); @@ -5136,14 +5176,24 @@ Item_func_sp::execute(Field **flp) /* Check that the field (the value) is not NULL. */ - null_value= f->is_null(); + null_value= sp_result_field->is_null(); return null_value; } +/** + @brief Execute function and store the return value in the field. + + @note This function was intended to be the concrete implementation of + the interface function execute. This was never realized. + + @return The error state. + @retval FALSE on success + @retval TRUE if an error occurred. +*/ bool -Item_func_sp::execute_impl(THD *thd, Field *return_value_fld) +Item_func_sp::execute_impl(THD *thd) { bool err_status= TRUE; Sub_statement_state statement_state; @@ -5160,7 +5210,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)) + if (sp_check_access(thd)) goto error; /* @@ -5169,7 +5219,7 @@ Item_func_sp::execute_impl(THD *thd, Field *return_value_fld) function call into binlog. */ thd->reset_sub_statement_state(&statement_state, SUB_STMT_FUNCTION); - err_status= m_sp->execute_function(thd, args, arg_count, return_value_fld); + err_status= m_sp->execute_function(thd, args, arg_count, sp_result_field); thd->restore_sub_statement_state(&statement_state); error: @@ -5184,15 +5234,9 @@ error: void Item_func_sp::make_field(Send_field *tmp_field) { - Field *field; DBUG_ENTER("Item_func_sp::make_field"); - if ((field= sp_result_field())) - { - field->make_field(tmp_field); - delete field; - DBUG_VOID_RETURN; - } - init_make_field(tmp_field, MYSQL_TYPE_VARCHAR); + DBUG_ASSERT(sp_result_field); + sp_result_field->make_field(tmp_field); DBUG_VOID_RETURN; } @@ -5200,67 +5244,20 @@ Item_func_sp::make_field(Send_field *tmp_field) enum enum_field_types Item_func_sp::field_type() const { - Field *field; DBUG_ENTER("Item_func_sp::field_type"); - - if (result_field) - DBUG_RETURN(result_field->type()); - if ((field= sp_result_field())) - { - enum_field_types result= field->type(); - delete field; - DBUG_RETURN(result); - } - DBUG_RETURN(MYSQL_TYPE_VARCHAR); + DBUG_ASSERT(sp_result_field); + DBUG_RETURN(sp_result_field->type()); } - Item_result Item_func_sp::result_type() const { - Field *field; DBUG_ENTER("Item_func_sp::result_type"); DBUG_PRINT("info", ("m_sp = %p", m_sp)); - - if (result_field) - DBUG_RETURN(result_field->result_type()); - if ((field= sp_result_field())) - { - Item_result result= field->result_type(); - delete field; - DBUG_RETURN(result); - } - DBUG_RETURN(STRING_RESULT); -} - -void -Item_func_sp::fix_length_and_dec() -{ - Field *field; - DBUG_ENTER("Item_func_sp::fix_length_and_dec"); - - if (result_field) - { - decimals= result_field->decimals(); - max_length= result_field->field_length; - collation.set(result_field->charset()); - DBUG_VOID_RETURN; - } - - if (!(field= sp_result_field())) - { - context->process_error(current_thd); - DBUG_VOID_RETURN; - } - decimals= field->decimals(); - max_length= field->field_length; - collation.set(field->charset()); - maybe_null= 1; - delete field; - DBUG_VOID_RETURN; + DBUG_ASSERT(sp_result_field); + DBUG_RETURN(sp_result_field->result_type()); } - longlong Item_func_found_rows::val_int() { DBUG_ASSERT(fixed == 1); @@ -5271,57 +5268,39 @@ longlong Item_func_found_rows::val_int() Field * Item_func_sp::tmp_table_field(TABLE *t_arg) { - Field *field= 0; DBUG_ENTER("Item_func_sp::tmp_table_field"); - if (m_sp) - field= m_sp->create_result_field(max_length, (const char*) name, t_arg); - - if (!field) - field= Item_func::tmp_table_field(t_arg); - - if (!field) - my_message(ER_OUT_OF_RESOURCES, ER(ER_OUT_OF_RESOURCES), MYF(0)); - - DBUG_RETURN(field); + DBUG_ASSERT(sp_result_field); + DBUG_RETURN(sp_result_field); } -/* - Find the function and check access rights to the function - - SYNOPSIS - find_and_check_access() - thd thread handler - - RETURN - FALSE Access granted - TRUE Requested access can't be granted or function doesn't exists - - NOTES - Checks if requested access to function can be granted to user. +/** + @brief 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. + + @param thd thread handler + + @return Indication if the access was granted or not. + @retval FALSE Access is granted. + @retval TRUE Requested access can't be granted or function doesn't exists. + */ bool -Item_func_sp::find_and_check_access(THD *thd) +Item_func_sp::sp_check_access(THD *thd) { - 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); - return TRUE; - } - + DBUG_ENTER("Item_func_sp::sp_check_access"); + DBUG_ASSERT(m_sp); #ifndef NO_EMBEDDED_ACCESS_CHECKS if (check_routine_access(thd, EXECUTE_ACL, m_sp->m_db.str, m_sp->m_name.str, 0, FALSE)) - return TRUE; + DBUG_RETURN(TRUE); #endif - return FALSE; + DBUG_RETURN(FALSE); } @@ -5329,9 +5308,25 @@ bool Item_func_sp::fix_fields(THD *thd, Item **ref) { bool res; + DBUG_ENTER("Item_func_sp::fix_fields"); DBUG_ASSERT(fixed == 0); + + /* + We must call init_result_field before Item_func::fix_fields() + to make m_sp and result_field members available to fix_length_and_dec(), + which is called from Item_func::fix_fields(). + */ + res= init_result_field(thd); + + if (res) + DBUG_RETURN(res); + res= Item_func::fix_fields(thd, ref); - if (!res && thd->lex->view_prepare_mode) + + if (res) + DBUG_RETURN(res); + + if (thd->lex->view_prepare_mode) { /* Here we check privileges of the stored routine only during view @@ -5343,15 +5338,17 @@ Item_func_sp::fix_fields(THD *thd, Item **ref) good idea especially if the view has SQL SECURITY DEFINER and the used stored procedure has SQL SECURITY DEFINER. */ - res= find_and_check_access(thd); + res= sp_check_access(thd); #ifndef NO_EMBEDDED_ACCESS_CHECKS + /* + Try to set and restore the security context to see whether it's valid + */ Security_context *save_secutiry_ctx; - if (!res && !(res= set_routine_security_ctx(thd, m_sp, false, - &save_secutiry_ctx))) - { + res= set_routine_security_ctx(thd, m_sp, false, &save_secutiry_ctx); + if (!res) sp_restore_security_context(thd, save_secutiry_ctx); - } + #endif /* ! NO_EMBEDDED_ACCESS_CHECKS */ } - return res; + DBUG_RETURN(res); } diff --git a/sql/item_func.h b/sql/item_func.h index 24f30994b22..635a409e0a2 100644 --- a/sql/item_func.h +++ b/sql/item_func.h @@ -1308,12 +1308,12 @@ public: FT_INFO *ft_handler; TABLE *table; Item_func_match *master; // for master-slave optimization - Item *concat; // Item_func_concat_ws - String value; // value of concat + Item *concat_ws; // Item_func_concat_ws + String value; // value of concat_ws String search_value; // key_item()'s value converted to cmp_collation Item_func_match(List<Item> &a, uint b): Item_real_func(a), key(0), flags(b), - join_key(0), ft_handler(0), table(0), master(0), concat(0) { } + join_key(0), ft_handler(0), table(0), master(0), concat_ws(0) { } void cleanup() { DBUG_ENTER("Item_func_match"); @@ -1321,7 +1321,7 @@ public: if (!master && ft_handler) ft_handler->please->close_search(ft_handler); ft_handler= 0; - concat= 0; + concat_ws= 0; DBUG_VOID_RETURN; } enum Functype functype() const { return FT_FUNC; } @@ -1405,12 +1405,15 @@ private: sp_name *m_name; mutable sp_head *m_sp; TABLE *dummy_table; - Field *result_field; char result_buf[64]; + /* + The result field of the concrete stored function. + */ + Field *sp_result_field; - bool execute(Field **flp); - bool execute_impl(THD *thd, Field *return_value_fld); - Field *sp_result_field(void) const; + bool execute(); + bool execute_impl(THD *thd); + bool init_result_field(THD *thd); public: @@ -1438,23 +1441,23 @@ public: longlong val_int() { - if (execute(&result_field)) + if (execute()) return (longlong) 0; - return result_field->val_int(); + return sp_result_field->val_int(); } double val_real() { - if (execute(&result_field)) + if (execute()) return 0.0; - return result_field->val_real(); + return sp_result_field->val_real(); } my_decimal *val_decimal(my_decimal *dec_buf) { - if (execute(&result_field)) + if (execute()) return NULL; - return result_field->val_decimal(dec_buf); + return sp_result_field->val_decimal(dec_buf); } String *val_str(String *str) @@ -1463,7 +1466,7 @@ public: char buff[20]; buf.set(buff, 20, str->charset()); buf.length(0); - if (execute(&result_field)) + if (execute()) return NULL; /* result_field will set buf pointing to internal buffer @@ -1471,7 +1474,7 @@ public: when SP is executed. In order to prevent occasional corruption of returned value, we make here a copy. */ - result_field->val_str(&buf); + sp_result_field->val_str(&buf); str->copy(buf); return str; } @@ -1479,11 +1482,11 @@ public: virtual bool change_context_processor(byte *cntx) { context= (Name_resolution_context *)cntx; return FALSE; } - void fix_length_and_dec(); - bool find_and_check_access(THD * thd); + bool sp_check_access(THD * thd); virtual enum Functype functype() const { return FUNC_SP; } bool fix_fields(THD *thd, Item **ref); + void fix_length_and_dec(void); bool is_expensive() { return 1; } }; diff --git a/sql/item_strfunc.cc b/sql/item_strfunc.cc index 03887629519..1991526345c 100644 --- a/sql/item_strfunc.cc +++ b/sql/item_strfunc.cc @@ -2319,7 +2319,7 @@ String *Item_func_repeat::val_str(String *str) goto err; // string and/or delim are null null_value= 0; - if (count == 0 || count < 0 && !args[1]->unsigned_flag) + if (count <= 0 && (count == 0 || !args[1]->unsigned_flag)) return &my_empty_string; /* Assumes that the maximum length of a String is < INT_MAX32. */ diff --git a/sql/item_sum.cc b/sql/item_sum.cc index 359b4516c3c..752cefa07d6 100644 --- a/sql/item_sum.cc +++ b/sql/item_sum.cc @@ -1080,14 +1080,8 @@ void Item_sum_count::clear() bool Item_sum_count::add() { - if (!args[0]->maybe_null) + if (!args[0]->maybe_null || !args[0]->is_null()) count++; - else - { - args[0]->update_null_value(); - if (!args[0]->null_value) - count++; - } return 0; } @@ -1921,14 +1915,8 @@ void Item_sum_count::reset_field() char *res=result_field->ptr; longlong nr=0; - if (!args[0]->maybe_null) + if (!args[0]->maybe_null || !args[0]->is_null()) nr=1; - else - { - args[0]->update_null_value(); - if (!args[0]->null_value) - nr=1; - } int8store(res,nr); } @@ -2031,14 +2019,8 @@ void Item_sum_count::update_field() char *res=result_field->ptr; nr=sint8korr(res); - if (!args[0]->maybe_null) + if (!args[0]->maybe_null || !args[0]->is_null()) nr++; - else - { - args[0]->update_null_value(); - if (!args[0]->null_value) - nr++; - } int8store(res,nr); } @@ -2462,12 +2444,8 @@ bool Item_sum_count_distinct::setup(THD *thd) Item *item=args[i]; if (list.push_back(item)) return TRUE; // End of memory - if (item->const_item()) - { - item->update_null_value(); - if (item->null_value) - always_null=1; - } + if (item->const_item() && item->is_null()) + always_null= 1; } if (always_null) return FALSE; diff --git a/sql/log.cc b/sql/log.cc index a0068dce1c5..7563d754556 100644 --- a/sql/log.cc +++ b/sql/log.cc @@ -283,7 +283,7 @@ err: #ifdef __NT__ static int eventSource = 0; -void setup_windows_event_source() +static void setup_windows_event_source() { HKEY hRegKey= NULL; DWORD dwError= 0; @@ -2229,37 +2229,6 @@ static bool test_if_number(register const char *str, } /* test_if_number */ -void print_buffer_to_file(enum loglevel level, const char *buffer) -{ - time_t skr; - struct tm tm_tmp; - struct tm *start; - DBUG_ENTER("print_buffer_to_file"); - DBUG_PRINT("enter",("buffer: %s", buffer)); - - VOID(pthread_mutex_lock(&LOCK_error_log)); - - skr=time(NULL); - localtime_r(&skr, &tm_tmp); - start=&tm_tmp; - fprintf(stderr, "%02d%02d%02d %2d:%02d:%02d [%s] %s\n", - start->tm_year % 100, - start->tm_mon+1, - start->tm_mday, - start->tm_hour, - start->tm_min, - start->tm_sec, - (level == ERROR_LEVEL ? "ERROR" : level == WARNING_LEVEL ? - "Warning" : "Note"), - buffer); - - fflush(stderr); - - VOID(pthread_mutex_unlock(&LOCK_error_log)); - DBUG_VOID_RETURN; -} - - void sql_perror(const char *message) { #ifdef HAVE_STRERROR @@ -2326,23 +2295,15 @@ void MYSQL_LOG::signal_update() } #ifdef __NT__ -void print_buffer_to_nt_eventlog(enum loglevel level, char *buff, - uint length, int buffLen) +static void print_buffer_to_nt_eventlog(enum loglevel level, char *buff, + size_t length, size_t buffLen) { HANDLE event; - char *buffptr; - LPCSTR *buffmsgptr; + char *buffptr= buff; DBUG_ENTER("print_buffer_to_nt_eventlog"); - buffptr= buff; - if (length > (uint)(buffLen-5)) - { - char *newBuff= new char[length + 5]; - strcpy(newBuff, buff); - buffptr= newBuff; - } - strmov(buffptr+length, "\r\n\r\n"); - buffmsgptr= (LPCSTR*) &buffptr; // Keep windows happy + /* Add ending CR/LF's to string, overwrite last chars if necessary */ + strmov(buffptr+min(length, buffLen-5), "\r\n\r\n"); setup_windows_event_source(); if ((event= RegisterEventSource(NULL,"MySQL"))) @@ -2350,24 +2311,20 @@ void print_buffer_to_nt_eventlog(enum loglevel level, char *buff, switch (level) { case ERROR_LEVEL: ReportEvent(event, EVENTLOG_ERROR_TYPE, 0, MSG_DEFAULT, NULL, 1, 0, - buffmsgptr, NULL); + (LPCSTR*)&buffptr, NULL); break; case WARNING_LEVEL: ReportEvent(event, EVENTLOG_WARNING_TYPE, 0, MSG_DEFAULT, NULL, 1, 0, - buffmsgptr, NULL); + (LPCSTR*) &buffptr, NULL); break; case INFORMATION_LEVEL: ReportEvent(event, EVENTLOG_INFORMATION_TYPE, 0, MSG_DEFAULT, NULL, 1, - 0, buffmsgptr, NULL); + 0, (LPCSTR*) &buffptr, NULL); break; } DeregisterEventSource(event); } - /* if we created a string buffer, then delete it */ - if (buffptr != buff) - delete[] buffptr; - DBUG_VOID_RETURN; } #endif /* __NT__ */ @@ -2399,13 +2356,44 @@ void vprint_msg_to_log(enum loglevel level __attribute__((unused)), va_list argsi __attribute__((unused))) {} #else /*!EMBEDDED_LIBRARY*/ +static void print_buffer_to_file(enum loglevel level, const char *buffer) +{ + time_t skr; + struct tm tm_tmp; + struct tm *start; + DBUG_ENTER("print_buffer_to_file"); + DBUG_PRINT("enter",("buffer: %s", buffer)); + + VOID(pthread_mutex_lock(&LOCK_error_log)); + + skr=time(NULL); + localtime_r(&skr, &tm_tmp); + start=&tm_tmp; + fprintf(stderr, "%02d%02d%02d %2d:%02d:%02d [%s] %s\n", + start->tm_year % 100, + start->tm_mon+1, + start->tm_mday, + start->tm_hour, + start->tm_min, + start->tm_sec, + (level == ERROR_LEVEL ? "ERROR" : level == WARNING_LEVEL ? + "Warning" : "Note"), + buffer); + + fflush(stderr); + + VOID(pthread_mutex_unlock(&LOCK_error_log)); + DBUG_VOID_RETURN; +} + + void vprint_msg_to_log(enum loglevel level, const char *format, va_list args) { char buff[1024]; - uint length; + size_t length; DBUG_ENTER("vprint_msg_to_log"); - length= my_vsnprintf(buff, sizeof(buff)-5, format, args); + length= my_vsnprintf(buff, sizeof(buff), format, args); print_buffer_to_file(level, buff); #ifdef __NT__ diff --git a/sql/log_event.cc b/sql/log_event.cc index e272140c080..8bb63e72bde 100644 --- a/sql/log_event.cc +++ b/sql/log_event.cc @@ -669,19 +669,34 @@ int Log_event::read_log_event(IO_CACHE* file, String* packet, LOG_READ_TOO_LARGE); goto end; } - packet->append(buf, sizeof(buf)); + + /* Append the log event header to packet */ + if (packet->append(buf, sizeof(buf))) + { + /* Failed to allocate packet */ + result= LOG_READ_MEM; + goto end; + } data_len-= LOG_EVENT_MINIMAL_HEADER_LEN; if (data_len) { + /* Append rest of event, read directly from file into packet */ if (packet->append(file, data_len)) { /* - Here if we hit EOF it's really an error: as data_len is >=0 - there's supposed to be more bytes available. - EOF means we are reading the event partially, which should - never happen: either we read badly or the binlog is truncated. + Fatal error occured when appending rest of the event + to packet, possible failures: + 1. EOF occured when reading from file, it's really an error + as data_len is >=0 there's supposed to be more bytes available. + file->error will have been set to number of bytes left to read + 2. Read was interrupted, file->error would normally be set to -1 + 3. Failed to allocate memory for packet, my_errno + will be ENOMEM(file->error shuold be 0, but since the + memory allocation occurs before the call to read it might + be uninitialized) */ - result= file->error >= 0 ? LOG_READ_TRUNC: LOG_READ_IO; + result= (my_errno == ENOMEM ? LOG_READ_MEM : + (file->error >= 0 ? LOG_READ_TRUNC: LOG_READ_IO)); /* Implicit goto end; */ } } diff --git a/sql/mysql_priv.h b/sql/mysql_priv.h index 629ffb93b97..a9c20e142c5 100644 --- a/sql/mysql_priv.h +++ b/sql/mysql_priv.h @@ -842,6 +842,8 @@ bool mysql_insert(THD *thd,TABLE_LIST *table,List<Item> &fields, bool ignore); int check_that_all_fields_are_given_values(THD *thd, TABLE *entry, TABLE_LIST *table_list); +void prepare_triggers_for_insert_stmt(THD *thd, TABLE *table, + enum_duplicates duplic); void mark_fields_used_by_triggers_for_insert_stmt(THD *thd, TABLE *table, enum_duplicates duplic); bool mysql_prepare_delete(THD *thd, TABLE_LIST *table_list, Item **conds); diff --git a/sql/parse_file.cc b/sql/parse_file.cc index 1351cf66161..aa352433141 100644 --- a/sql/parse_file.cc +++ b/sql/parse_file.cc @@ -719,14 +719,18 @@ nlist_err: /* parse parameters - + SYNOPSIS File_parser::parse() base base address for parameter writing (structure like TABLE) mem_root MEM_ROOT for parameters allocation parameters parameters description - required number of required parameters in above list + required number of parameters in the above list. If the file + contains more parameters than "required", they will + be ignored. If the file contains less parameters + then "required", non-existing parameters will + remain their values. hook hook called for unknown keys hook_data some data specific for the hook @@ -909,6 +913,13 @@ list_err: } } } + + /* + NOTE: if we read less than "required" parameters, it is still Ok. + Probably, we've just read the file of the previous version, which + contains less parameters. + */ + DBUG_RETURN(FALSE); } diff --git a/sql/sp.cc b/sql/sp.cc index 506b0bcd92b..4fc9ea1f602 100644 --- a/sql/sp.cc +++ b/sql/sp.cc @@ -1068,7 +1068,7 @@ sp_exist_routines(THD *thd, TABLE_LIST *routines, bool any, bool no_error) lex_name.length= strlen(routine->table_name); lex_db.str= thd->strmake(routine->db, lex_db.length); lex_name.str= thd->strmake(routine->table_name, lex_name.length); - name= new sp_name(lex_db, lex_name); + name= new sp_name(lex_db, lex_name, true); name->init_qname(thd); sp_object_found= sp_find_routine(thd, TYPE_ENUM_PROCEDURE, name, &thd->sp_proc_cache, FALSE) != NULL || diff --git a/sql/sp_head.cc b/sql/sp_head.cc index bba231ba685..338b2eb84bb 100644 --- a/sql/sp_head.cc +++ b/sql/sp_head.cc @@ -954,6 +954,12 @@ sp_head::execute(THD *thd) m_first_instance->m_last_cached_sp == this) || (m_recursion_level + 1 == m_next_cached_sp->m_recursion_level)); + /* + NOTE: The SQL Standard does not specify the context that should be + preserved for stored routines. However, at SAP/Walldorf meeting it was + decided that current database should be preserved. + */ + if (m_db.length && (err_status= sp_use_new_db(thd, m_db, &old_db, 0, &dbchanged))) goto done; diff --git a/sql/sp_head.h b/sql/sp_head.h index 901b7a19c39..cce400d6a14 100644 --- a/sql/sp_head.h +++ b/sql/sp_head.h @@ -59,9 +59,10 @@ public: calling set_routine_type(). */ LEX_STRING m_sroutines_key; + bool m_explicit_name; /**< Prepend the db name? */ - sp_name(LEX_STRING db, LEX_STRING name) - : m_db(db), m_name(name) + sp_name(LEX_STRING db, LEX_STRING name, bool use_explicit_name) + : m_db(db), m_name(name), m_explicit_name(use_explicit_name) { m_qname.str= m_sroutines_key.str= 0; m_qname.length= m_sroutines_key.length= 0; @@ -79,6 +80,7 @@ public: m_name.length= m_qname.length= key_len - 1; m_db.str= 0; m_db.length= 0; + m_explicit_name= false; } // Init. the qualified name from the db and name. diff --git a/sql/spatial.h b/sql/spatial.h index 86232fcd524..837ae153310 100644 --- a/sql/spatial.h +++ b/sql/spatial.h @@ -144,15 +144,46 @@ struct MBR return (xmin<x) && (xmax>x) && (ymin<y) && (ymax>y); } + /** + The dimension maps to an integer as: + - Polygon -> 2 + - Horizontal or vertical line -> 1 + - Point -> 0 + - Invalid MBR -> -1 + */ + int dimension() const + { + int d= 0; + + if (xmin > xmax) + return -1; + else if (xmin < xmax) + d++; + + if (ymin > ymax) + return -1; + else if (ymin < ymax) + d++; + + return d; + } + int overlaps(const MBR *mbr) { - int lb= mbr->inner_point(xmin, ymin); - int rb= mbr->inner_point(xmax, ymin); - int rt= mbr->inner_point(xmax, ymax); - int lt= mbr->inner_point(xmin, ymax); + /* + overlaps() requires that some point inside *this is also inside + *mbr, and that both geometries and their intersection are of the + same dimension. + */ + int d = dimension(); + + if (d != mbr->dimension() || d <= 0 || contains(mbr) || within(mbr)) + return 0; + + MBR intersection(max(xmin, mbr->xmin), max(ymin, mbr->ymin), + min(xmax, mbr->xmax), min(ymax, mbr->ymax)); - int a = lb+rb+rt+lt; - return (a>0) && (a<4) && (!within(mbr)); + return (d == intersection.dimension()); } }; diff --git a/sql/sql_delete.cc b/sql/sql_delete.cc index 0488fdd4eb8..bccd4d4cafe 100644 --- a/sql/sql_delete.cc +++ b/sql/sql_delete.cc @@ -217,7 +217,19 @@ bool mysql_delete(THD *thd, TABLE_LIST *table_list, COND *conds, thd->proc_info="updating"; if (table->triggers) + { table->triggers->mark_fields_used(thd, TRG_EVENT_DELETE); + if (table->triggers->has_triggers(TRG_EVENT_DELETE, + TRG_ACTION_AFTER)) + { + /* + The table has AFTER DELETE triggers that might access to subject table + and therefore might need delete to be done immediately. So we turn-off + the batching. + */ + (void) table->file->extra(HA_EXTRA_DELETE_CANNOT_BATCH); + } + } while (!(error=info.read_record(&info)) && !thd->killed && !thd->net.report_error) @@ -540,7 +552,19 @@ multi_delete::initialize_tables(JOIN *join) else normal_tables= 1; if (tbl->triggers) + { tbl->triggers->mark_fields_used(thd, TRG_EVENT_DELETE); + if (tbl->triggers->has_triggers(TRG_EVENT_DELETE, + TRG_ACTION_AFTER)) + { + /* + The table has AFTER DELETE triggers that might access to subject + table and therefore might need delete to be done immediately. + So we turn-off the batching. + */ + (void) tbl->file->extra(HA_EXTRA_DELETE_CANNOT_BATCH); + } + } } else if ((tab->type != JT_SYSTEM && tab->type != JT_CONST) && walk == delete_tables) diff --git a/sql/sql_insert.cc b/sql/sql_insert.cc index 49b271dd219..f1d86224adb 100644 --- a/sql/sql_insert.cc +++ b/sql/sql_insert.cc @@ -330,6 +330,51 @@ static int check_update_fields(THD *thd, TABLE_LIST *insert_table_list, /* + Prepare triggers for INSERT-like statement. + + SYNOPSIS + prepare_triggers_for_insert_stmt() + thd The current thread + table Table to which insert will happen + duplic Type of duplicate handling for insert which will happen + + NOTE + Prepare triggers for INSERT-like statement by marking fields + used by triggers and inform handlers that batching of UPDATE/DELETE + cannot be done if there are BEFORE UPDATE/DELETE triggers. +*/ + +void prepare_triggers_for_insert_stmt(THD *thd, TABLE *table, + enum_duplicates duplic) +{ + if (table->triggers) + { + if (table->triggers->has_triggers(TRG_EVENT_DELETE, + TRG_ACTION_AFTER)) + { + /* + The table has AFTER DELETE triggers that might access to + subject table and therefore might need delete to be done + immediately. So we turn-off the batching. + */ + (void) table->file->extra(HA_EXTRA_DELETE_CANNOT_BATCH); + } + if (table->triggers->has_triggers(TRG_EVENT_UPDATE, + TRG_ACTION_AFTER)) + { + /* + The table has AFTER UPDATE triggers that might access to subject + table and therefore might need update to be done immediately. + So we turn-off the batching. + */ + (void) table->file->extra(HA_EXTRA_UPDATE_CANNOT_BATCH); + } + mark_fields_used_by_triggers_for_insert_stmt(thd, table, duplic); + } +} + + +/* Mark fields used by triggers for INSERT-like statement. SYNOPSIS @@ -589,7 +634,7 @@ bool mysql_insert(THD *thd,TABLE_LIST *table_list, (MODE_STRICT_TRANS_TABLES | MODE_STRICT_ALL_TABLES))); - mark_fields_used_by_triggers_for_insert_stmt(thd, table, duplic); + prepare_triggers_for_insert_stmt(thd, table, duplic); if (table_list->prepare_where(thd, 0, TRUE) || table_list->prepare_check_option(thd)) @@ -2528,8 +2573,8 @@ select_insert::prepare(List<Item> &values, SELECT_LEX_UNIT *u) table_list->prepare_check_option(thd)); if (!res) - mark_fields_used_by_triggers_for_insert_stmt(thd, table, - info.handle_duplicates); + prepare_triggers_for_insert_stmt(thd, table, + info.handle_duplicates); DBUG_RETURN(res); } diff --git a/sql/sql_load.cc b/sql/sql_load.cc index 64022fa719b..ee6d2d0a572 100644 --- a/sql/sql_load.cc +++ b/sql/sql_load.cc @@ -222,7 +222,7 @@ bool mysql_load(THD *thd,sql_exchange *ex,TABLE_LIST *table_list, DBUG_RETURN(TRUE); } - mark_fields_used_by_triggers_for_insert_stmt(thd, table, handle_duplicates); + prepare_triggers_for_insert_stmt(thd, table, handle_duplicates); uint tot_length=0; bool use_blobs= 0, use_vars= 0; @@ -532,7 +532,7 @@ read_fixed_length(THD *thd, COPY_INFO &info, TABLE_LIST *table_list, Item_field *sql_field; TABLE *table= table_list->table; ulonglong id; - bool no_trans_update_stmt; + bool no_trans_update_stmt, err; DBUG_ENTER("read_fixed_length"); id= 0; @@ -624,7 +624,9 @@ read_fixed_length(THD *thd, COPY_INFO &info, TABLE_LIST *table_list, DBUG_RETURN(-1); } - if (write_record(thd, table, &info)) + err= write_record(thd, table, &info); + table->auto_increment_field_not_null= FALSE; + if (err) DBUG_RETURN(1); thd->no_trans_update.stmt= no_trans_update_stmt; @@ -669,7 +671,7 @@ read_sep_field(THD *thd, COPY_INFO &info, TABLE_LIST *table_list, TABLE *table= table_list->table; uint enclosed_length; ulonglong id; - bool no_trans_update_stmt; + bool no_trans_update_stmt, err; DBUG_ENTER("read_sep_field"); enclosed_length=enclosed.length(); @@ -716,8 +718,6 @@ read_sep_field(THD *thd, COPY_INFO &info, TABLE_LIST *table_list, DBUG_RETURN(1); } field->set_null(); - if (field == table->next_number_field) - table->auto_increment_field_not_null= TRUE; if (!field->maybe_null()) { if (field->type() == FIELD_TYPE_TIMESTAMP) @@ -803,8 +803,9 @@ read_sep_field(THD *thd, COPY_INFO &info, TABLE_LIST *table_list, DBUG_RETURN(-1); } - - if (write_record(thd, table, &info)) + err= write_record(thd, table, &info); + table->auto_increment_field_not_null= FALSE; + if (err) DBUG_RETURN(1); /* If auto_increment values are used, save the first one for diff --git a/sql/sql_show.cc b/sql/sql_show.cc index fa78db50532..8cf3dc022d9 100644 --- a/sql/sql_show.cc +++ b/sql/sql_show.cc @@ -3603,7 +3603,16 @@ TABLE *create_schema_table(THD *thd, TABLE_LIST *table_list) DBUG_RETURN(0); } break; + case MYSQL_TYPE_FLOAT: + case MYSQL_TYPE_DOUBLE: + if ((item= new Item_float(fields_info->field_name, 0.0, NOT_FIXED_DEC, + fields_info->field_length)) == NULL) + DBUG_RETURN(NULL); + break; default: + /* Don't let unimplemented types pass through. Could be a grave error. */ + DBUG_ASSERT(fields_info->field_type == MYSQL_TYPE_STRING); + /* this should be changed when Item_empty_string is fixed(in 4.1) */ if (!(item= new Item_empty_string("", 0, cs))) { diff --git a/sql/sql_table.cc b/sql/sql_table.cc index 8ee762044cc..6836811e7f3 100644 --- a/sql/sql_table.cc +++ b/sql/sql_table.cc @@ -407,6 +407,7 @@ static int sort_keys(KEY *a, KEY *b) set_or_name "SET" or "ENUM" string for warning message name name of the checked column typelib list of values for the column + dup_val_count returns count of duplicate elements DESCRIPTION This function prints an warning for each value in list @@ -418,11 +419,12 @@ static int sort_keys(KEY *a, KEY *b) void check_duplicates_in_interval(const char *set_or_name, const char *name, TYPELIB *typelib, - CHARSET_INFO *cs) + CHARSET_INFO *cs, unsigned int *dup_val_count) { TYPELIB tmp= *typelib; const char **cur_value= typelib->type_names; unsigned int *cur_length= typelib->type_lengths; + *dup_val_count= 0; for ( ; tmp.count > 1; cur_value++, cur_length++) { @@ -435,6 +437,7 @@ void check_duplicates_in_interval(const char *set_or_name, ER_DUPLICATED_VALUE_IN_TYPE, ER(ER_DUPLICATED_VALUE_IN_TYPE), name,*cur_value,set_or_name); + (*dup_val_count)++; } } } @@ -498,6 +501,7 @@ int prepare_create_field(create_field *sql_field, int *timestamps, int *timestamps_with_niladic, uint table_flags) { + unsigned int dup_val_count; DBUG_ENTER("prepare_field"); /* @@ -573,7 +577,7 @@ int prepare_create_field(create_field *sql_field, sql_field->unireg_check=Field::INTERVAL_FIELD; check_duplicates_in_interval("ENUM",sql_field->field_name, sql_field->interval, - sql_field->charset); + sql_field->charset, &dup_val_count); break; case FIELD_TYPE_SET: sql_field->pack_flag=pack_length_to_packflag(sql_field->pack_length) | @@ -583,7 +587,13 @@ int prepare_create_field(create_field *sql_field, sql_field->unireg_check=Field::BIT_FIELD; check_duplicates_in_interval("SET",sql_field->field_name, sql_field->interval, - sql_field->charset); + sql_field->charset, &dup_val_count); + /* Check that count of unique members is not more then 64 */ + if (sql_field->interval->count - dup_val_count > sizeof(longlong)*8) + { + my_error(ER_TOO_BIG_SET, MYF(0), sql_field->field_name); + DBUG_RETURN(1); + } break; case FIELD_TYPE_DATE: // Rest of string types case FIELD_TYPE_NEWDATE: @@ -1697,6 +1707,7 @@ bool mysql_create_table(THD *thd,const char *db, const char *table_name, alias); DBUG_RETURN(FALSE); } + DBUG_PRINT("info",("1")); my_error(ER_TABLE_EXISTS_ERROR, MYF(0), alias); DBUG_RETURN(TRUE); } @@ -1707,6 +1718,7 @@ bool mysql_create_table(THD *thd,const char *db, const char *table_name, { if (create_info->options & HA_LEX_CREATE_IF_NOT_EXISTS) goto warn; + DBUG_PRINT("info",("2")); my_error(ER_TABLE_EXISTS_ERROR,MYF(0),table_name); goto end; } @@ -1725,14 +1737,25 @@ bool mysql_create_table(THD *thd,const char *db, const char *table_name, { bool create_if_not_exists = create_info->options & HA_LEX_CREATE_IF_NOT_EXISTS; - if (ha_table_exists_in_engine(thd, db, table_name)) + int retcode = ha_table_exists_in_engine(thd, db, table_name); + DBUG_PRINT("info", ("exists_in_engine: %u",retcode)); + switch (retcode) { - DBUG_PRINT("info", ("Table with same name already existed in handler")); + case HA_ERR_NO_SUCH_TABLE: + /* Normal case, no table exists. we can go and create it */ + break; + case HA_ERR_TABLE_EXIST: + DBUG_PRINT("info", ("Table existed in handler")); - if (create_if_not_exists) - goto warn; - my_error(ER_TABLE_EXISTS_ERROR,MYF(0),table_name); - goto end; + if (create_if_not_exists) + goto warn; + my_error(ER_TABLE_EXISTS_ERROR,MYF(0),table_name); + goto end; + break; + default: + DBUG_PRINT("info", ("error: %u from storage engine", retcode)); + my_error(retcode, MYF(0),table_name); + goto end; } } @@ -2068,7 +2091,9 @@ static int prepare_for_repair(THD* thd, TABLE_LIST *table_list, /* Check if this is a table type that stores index and data separately, - like ISAM or MyISAM + like ISAM or MyISAM. We assume fixed order of engine file name + extentions array. First element of engine file name extentions array + is meta/index file extention. Second element - data file extention. */ if (!ext[0] || !ext[1]) goto end; // No data file diff --git a/sql/sql_trigger.h b/sql/sql_trigger.h index 19b2b24a3fe..b029a70ca20 100644 --- a/sql/sql_trigger.h +++ b/sql/sql_trigger.h @@ -110,6 +110,11 @@ public: const char *old_table, const char *new_db, const char *new_table); + bool has_triggers(trg_event_type event_type, + trg_action_time_type action_time) + { + return (bodies[event_type][action_time] != NULL); + } bool has_delete_triggers() { return (bodies[TRG_EVENT_DELETE][TRG_ACTION_BEFORE] || diff --git a/sql/sql_update.cc b/sql/sql_update.cc index 860d00b5bdd..6f6c4538040 100644 --- a/sql/sql_update.cc +++ b/sql/sql_update.cc @@ -436,7 +436,19 @@ int mysql_update(THD *thd, MODE_STRICT_ALL_TABLES))); if (table->triggers) + { table->triggers->mark_fields_used(thd, TRG_EVENT_UPDATE); + if (table->triggers->has_triggers(TRG_EVENT_UPDATE, + TRG_ACTION_AFTER)) + { + /* + The table has AFTER UPDATE triggers that might access to subject + table and therefore might need update to be done immediately. + So we turn-off the batching. + */ + (void) table->file->extra(HA_EXTRA_UPDATE_CANNOT_BATCH); + } + } /* We can use compare_record() to optimize away updates if @@ -1001,6 +1013,20 @@ int multi_update::prepare(List<Item> ¬_used_values, table->no_keyread=1; table->used_keys.clear_all(); table->pos_in_table_list= tl; + if (table->triggers) + { + table->triggers->mark_fields_used(thd, TRG_EVENT_UPDATE); + if (table->triggers->has_triggers(TRG_EVENT_UPDATE, + TRG_ACTION_AFTER)) + { + /* + The table has AFTER UPDATE triggers that might access to subject + table and therefore might need update to be done immediately. + So we turn-off the batching. + */ + (void) table->file->extra(HA_EXTRA_UPDATE_CANNOT_BATCH); + } + } } } diff --git a/sql/sql_yacc.yy b/sql/sql_yacc.yy index bbb0d11b942..4a50a602121 100644 --- a/sql/sql_yacc.yy +++ b/sql/sql_yacc.yy @@ -1577,7 +1577,7 @@ sp_name: my_error(ER_SP_WRONG_NAME, MYF(0), $3.str); MYSQL_YYABORT; } - $$= new sp_name($1, $3); + $$= new sp_name($1, $3, true); $$->init_qname(YYTHD); } | ident @@ -1591,7 +1591,7 @@ sp_name: } if (thd->copy_db_to(&db.str, &db.length)) MYSQL_YYABORT; - $$= new sp_name(db, $1); + $$= new sp_name(db, $1, false); if ($$) $$->init_qname(YYTHD); } @@ -5041,7 +5041,7 @@ simple_expr: | ident '.' ident '(' opt_expr_list ')' { LEX *lex= Lex; - sp_name *name= new sp_name($1, $3); + sp_name *name= new sp_name($1, $3, true); name->init_qname(YYTHD); sp_add_used_routine(lex, YYTHD, name, TYPE_ENUM_FUNCTION); @@ -5156,7 +5156,7 @@ simple_expr: LEX_STRING db; if (thd->copy_db_to(&db.str, &db.length)) MYSQL_YYABORT; - sp_name *name= new sp_name(db, $1); + sp_name *name= new sp_name(db, $1, false); if (name) name->init_qname(thd); @@ -9050,7 +9050,8 @@ grant_ident: | table_ident { LEX *lex=Lex; - if (!lex->current_select->add_table_to_list(lex->thd, $1,NULL,0)) + if (!lex->current_select->add_table_to_list(lex->thd, $1,NULL, + TL_OPTION_UPDATING)) MYSQL_YYABORT; if (lex->grant == GLOBAL_ACLS) lex->grant = TABLE_ACLS & ~GRANT_ACL; diff --git a/vio/viosslfactories.c b/vio/viosslfactories.c index 55d3792365f..a12a45df648 100644 --- a/vio/viosslfactories.c +++ b/vio/viosslfactories.c @@ -301,6 +301,14 @@ new_VioSSLConnectorFd(const char *key_file, const char *cert_file, { struct st_VioSSLFd *ssl_fd; int verify= SSL_VERIFY_PEER; + + /* + Turn off verification of servers certificate if both + ca_file and ca_path is set to NULL + */ + if (ca_file == 0 && ca_path == 0) + verify= SSL_VERIFY_NONE; + if (!(ssl_fd= new_VioSSLFd(key_file, cert_file, ca_file, ca_path, cipher, TLSv1_client_method()))) { |