diff --git a/include/mysql.h b/include/mysql.h index 68cce3196a0..d114afb6c93 100644 --- a/include/mysql.h +++ b/include/mysql.h @@ -557,16 +557,6 @@ unsigned long STDCALL mysql_real_escape_string(MYSQL *mysql, char *to,const char *from, unsigned long length); void STDCALL mysql_debug(const char *debug); -char * STDCALL mysql_odbc_escape_string(MYSQL *mysql, - char *to, - unsigned long to_length, - const char *from, - unsigned long from_length, - void *param, - char * - (*extend_buffer) - (void *, char *to, - unsigned long *length)); void STDCALL myodbc_remove_escape(MYSQL *mysql,char *name); unsigned int STDCALL mysql_thread_safe(void); my_bool STDCALL mysql_embedded(void); diff --git a/include/mysql_h.ic b/include/mysql_h.ic index 12e16df878a..4bedb9e8050 100644 --- a/include/mysql_h.ic +++ b/include/mysql_h.ic @@ -54,7 +54,7 @@ typedef struct st_list LIST; typedef struct st_mem_root MEM_ROOT; # 258 "mysql.h" typedef struct st_mysql MYSQL; -# 664 "mysql.h" +# 654 "mysql.h" typedef struct st_mysql_bind MYSQL_BIND; # 95 "mysql.h" typedef struct st_mysql_field MYSQL_FIELD; @@ -72,17 +72,17 @@ typedef struct st_mysql_res MYSQL_RES; typedef char * * MYSQL_ROW; # 145 "mysql.h" typedef MYSQL_ROWS * MYSQL_ROW_OFFSET; -# 693 "mysql.h" +# 683 "mysql.h" typedef struct st_mysql_stmt MYSQL_STMT; # 52 "mysql/plugin.h" typedef struct st_mysql_xid MYSQL_XID; # 243 "mysql.h" typedef struct character_set MY_CHARSET_INFO; -# 187 "mysql_com.h" +# 188 "mysql_com.h" typedef struct st_net NET; # 22 "typelib.h" typedef struct st_typelib TYPELIB; -# 177 "mysql_com.h" +# 178 "mysql_com.h" typedef struct st_vio Vio; # 28 "my_list.h" typedef int (* list_walk_action)(void *, void *); @@ -92,7 +92,7 @@ typedef char my_bool; typedef int my_socket; # 128 "mysql.h" typedef unsigned long long int my_ulonglong; -# 214 "/usr/lib/gcc/i486-linux-gnu/4.1.2/include/stddef.h" +# 214 "/usr/lib/gcc/i486-linux-gnu/4.1.3/include/stddef.h" typedef unsigned int size_t; # 149 "mysql.h" typedef struct embedded_query_result EMBEDDED_QUERY_RESULT; @@ -102,13 +102,13 @@ typedef struct st_mysql_data MYSQL_DATA; typedef struct st_mysql_ftparser_boolean_info MYSQL_FTPARSER_BOOLEAN_INFO; # 557 "mysql/plugin.h" typedef struct st_mysql_ftparser_param MYSQL_FTPARSER_PARAM; -# 763 "mysql.h" +# 753 "mysql.h" typedef struct st_mysql_methods MYSQL_METHODS; # 47 "mysql_time.h" typedef struct st_mysql_time MYSQL_TIME; -# 383 "mysql_com.h" +# 384 "mysql_com.h" typedef struct st_udf_args UDF_ARGS; -# 397 "mysql_com.h" +# 398 "mysql_com.h" typedef struct st_udf_init UDF_INIT; # 26 "my_alloc.h" typedef struct st_used_mem USED_MEM; @@ -130,7 +130,7 @@ struct __attribute__((aligned(__alignof__(unsigned int)), aligned(__alignof__(vo unsigned int mbminlen; unsigned int mbmaxlen; }; -# 369 "mysql_com.h" +# 370 "mysql_com.h" struct __attribute__((aligned(__alignof__(unsigned long int)), aligned(__alignof__(double)))) rand_struct { unsigned long int seed1; @@ -203,7 +203,7 @@ struct __attribute__((aligned(__alignof__(void *)), aligned(__alignof__(unsigned char * info_buffer; void * extension; }; -# 664 "mysql.h" +# 654 "mysql.h" struct __attribute__((aligned(__alignof__(void *)), aligned(__alignof__(unsigned long int)))) st_mysql_bind { unsigned long int * length; @@ -328,7 +328,7 @@ struct __attribute__((aligned(__alignof__(void *)), aligned(__alignof__(unsigned char last_error[256]; void * extension; }; -# 763 "mysql.h" +# 753 "mysql.h" struct __attribute__((aligned(__alignof__(void *)))) st_mysql_methods { my_bool (* read_query_result)(MYSQL * mysql); @@ -448,7 +448,7 @@ struct __attribute__((aligned(__alignof__(void *)))) st_mysql_show_var char * value; enum enum_mysql_show_type type; }; -# 693 "mysql.h" +# 683 "mysql.h" struct __attribute__((aligned(__alignof__(void *)), aligned(__alignof__(unsigned long long int)))) st_mysql_stmt { MEM_ROOT mem_root; @@ -513,7 +513,7 @@ struct __attribute__((aligned(__alignof__(long int)))) st_mysql_xid long int bqual_length; char data[128]; }; -# 187 "mysql_com.h" +# 188 "mysql_com.h" struct __attribute__((aligned(__alignof__(void *)), aligned(__alignof__(unsigned long int)))) st_net { Vio * vio; @@ -558,7 +558,7 @@ struct __attribute__((aligned(__alignof__(unsigned int)), aligned(__alignof__(vo char const * * type_names; unsigned int * type_lengths; }; -# 383 "mysql_com.h" +# 384 "mysql_com.h" struct __attribute__((aligned(__alignof__(unsigned int)), aligned(__alignof__(void *)))) st_udf_args { unsigned int arg_count; @@ -570,7 +570,7 @@ struct __attribute__((aligned(__alignof__(unsigned int)), aligned(__alignof__(vo unsigned long int * attribute_lengths; void * extension; }; -# 397 "mysql_com.h" +# 398 "mysql_com.h" struct __attribute__((aligned(__alignof__(unsigned long int)), aligned(__alignof__(void *)))) st_udf_init { my_bool maybe_null; @@ -587,7 +587,7 @@ struct __attribute__((aligned(__alignof__(void *)), aligned(__alignof__(unsigned unsigned int left; unsigned int size; }; -# 380 "mysql_com.h" +# 381 "mysql_com.h" enum Item_result { STRING_RESULT = 0, @@ -596,7 +596,7 @@ enum Item_result ROW_RESULT = 3, DECIMAL_RESULT = 4, }; -# 321 "mysql_com.h" +# 322 "mysql_com.h" enum enum_cursor_type { CURSOR_TYPE_NO_CURSOR = 0, @@ -604,7 +604,7 @@ enum enum_cursor_type CURSOR_TYPE_FOR_UPDATE = 2, CURSOR_TYPE_SCROLLABLE = 4, }; -# 234 "mysql_com.h" +# 235 "mysql_com.h" enum enum_field_types { MYSQL_TYPE_DECIMAL = 0, @@ -651,7 +651,7 @@ enum enum_ftparser_mode MYSQL_FTPARSER_WITH_STOPWORDS = 1, MYSQL_FTPARSER_FULL_BOOLEAN_INFO = 2, }; -# 331 "mysql_com.h" +# 332 "mysql_com.h" enum enum_mysql_set_option { MYSQL_OPTION_MULTI_STATEMENTS_ON = 0, @@ -671,7 +671,7 @@ enum enum_mysql_show_type SHOW_FUNC = 8, SHOW_DOUBLE = 9, }; -# 594 "mysql.h" +# 584 "mysql.h" enum enum_mysql_stmt_state { MYSQL_STMT_INIT_DONE = 1, @@ -723,14 +723,14 @@ enum enum_server_command COM_DAEMON = 29, COM_END = 30, }; -# 740 "mysql.h" +# 730 "mysql.h" enum enum_stmt_attr_type { STMT_ATTR_UPDATE_MAX_LENGTH = 0, STMT_ATTR_CURSOR_TYPE = 1, STMT_ATTR_PREFETCH_ROWS = 2, }; -# 296 "mysql_com.h" +# 297 "mysql_com.h" enum mysql_enum_shutdown_level { SHUTDOWN_DEFAULT = 0, @@ -790,13 +790,13 @@ enum mysql_status MYSQL_STATUS_GET_RESULT = 1, MYSQL_STATUS_USE_RESULT = 2, }; -# 438 "mysql_com.h" +# 439 "mysql_com.h" extern my_bool check_scramble(char const * reply, char const * message, unsigned char const * hash_stage2); -# 431 "mysql_com.h" +# 432 "mysql_com.h" extern my_bool check_scramble_323(char const *, char const * message, unsigned long int * salt); # 35 "typelib.h" extern TYPELIB * copy_typelib(MEM_ROOT * root, TYPELIB * from); -# 426 "mysql_com.h" +# 427 "mysql_com.h" extern void create_random_string(char * to, unsigned int, struct rand_struct * rand_st); # 32 "typelib.h" extern int find_type(char * x, TYPELIB const * typelib, unsigned int); @@ -804,15 +804,15 @@ extern int find_type(char * x, TYPELIB const * typelib, unsigned int); extern int find_type_or_exit(char const * x, TYPELIB * typelib, char const * option); # 29 "typelib.h" extern my_ulonglong find_typeset(char * x, TYPELIB * typelib, int * error_position); -# 440 "mysql_com.h" +# 441 "mysql_com.h" extern void get_salt_from_password(unsigned char * res, char const * password); -# 433 "mysql_com.h" +# 434 "mysql_com.h" extern void get_salt_from_password_323(unsigned long int * res, char const * password); -# 446 "mysql_com.h" +# 447 "mysql_com.h" extern char * get_tty_password(char const * opt_message); # 34 "typelib.h" extern char const * get_type(TYPELIB * typelib, unsigned int); -# 428 "mysql_com.h" +# 429 "mysql_com.h" extern void hash_password(unsigned long int * to, char const * password, unsigned int); # 30 "my_list.h" extern LIST * list_add(LIST * root, LIST * element); @@ -828,47 +828,47 @@ extern unsigned int list_length(LIST *); extern LIST * list_reverse(LIST * root); # 36 "my_list.h" extern int list_walk(LIST *, list_walk_action, unsigned char * argument); -# 441 "mysql_com.h" +# 442 "mysql_com.h" extern void make_password_from_salt(char * to, unsigned char const * hash_stage2); -# 434 "mysql_com.h" +# 435 "mysql_com.h" extern void make_password_from_salt_323(char * to, unsigned long int const * salt); -# 436 "mysql_com.h" +# 437 "mysql_com.h" extern void make_scrambled_password(char * to, char const * password); -# 429 "mysql_com.h" +# 430 "mysql_com.h" extern void make_scrambled_password_323(char * to, char const * password); # 33 "typelib.h" extern void make_type(char * to, unsigned int, TYPELIB * typelib); -# 366 "mysql_com.h" +# 367 "mysql_com.h" extern int my_connect(my_socket, struct sockaddr const * name, unsigned int, unsigned int); -# 343 "mysql_com.h" -extern my_bool my_net_init(NET * net, Vio * vio); # 344 "mysql_com.h" +extern my_bool my_net_init(NET * net, Vio * vio); +# 345 "mysql_com.h" extern void my_net_local_init(NET * net); -# 354 "mysql_com.h" +# 355 "mysql_com.h" extern unsigned long int my_net_read(NET * net); -# 349 "mysql_com.h" +# 350 "mysql_com.h" extern my_bool my_net_write(NET * net, unsigned char const * packet, size_t); -# 425 "mysql_com.h" +# 426 "mysql_com.h" extern double my_rnd(struct rand_struct *); -# 452 "mysql_com.h" +# 453 "mysql_com.h" extern void my_thread_end(void); -# 451 "mysql_com.h" +# 452 "mysql_com.h" extern my_bool my_thread_init(void); -# 570 "mysql.h" +# 560 "mysql.h" extern void myodbc_remove_escape(MYSQL * mysql, char * name); # 512 "mysql.h" extern int mysql_add_slave(MYSQL * mysql, char const * host, unsigned int, char const * user, char const * passwd); # 421 "mysql.h" extern my_ulonglong mysql_affected_rows(MYSQL * mysql); -# 836 "mysql.h" +# 826 "mysql.h" extern my_bool mysql_autocommit(MYSQL * mysql, my_bool); # 437 "mysql.h" extern my_bool mysql_change_user(MYSQL * mysql, char const * user, char const * passwd, char const * db); # 429 "mysql.h" extern char const * mysql_character_set_name(MYSQL * mysql); -# 839 "mysql.h" +# 829 "mysql.h" extern void mysql_close(MYSQL * sock); -# 834 "mysql.h" +# 824 "mysql.h" extern my_bool mysql_commit(MYSQL * mysql); # 541 "mysql.h" extern void mysql_data_seek(MYSQL_RES * result, my_ulonglong); @@ -880,7 +880,7 @@ extern void mysql_disable_reads_from_master(MYSQL * mysql); extern void mysql_disable_rpl_parse(MYSQL * mysql); # 520 "mysql.h" extern int mysql_dump_debug_info(MYSQL * mysql); -# 572 "mysql.h" +# 562 "mysql.h" extern my_bool mysql_embedded(void); # 497 "mysql.h" extern void mysql_enable_reads_from_master(MYSQL * mysql); @@ -890,7 +890,7 @@ extern void mysql_enable_rpl_parse(MYSQL * mysql); extern my_bool mysql_eof(MYSQL_RES * res); # 423 "mysql.h" extern unsigned int mysql_errno(MYSQL * mysql); -# 447 "mysql_com.h" +# 448 "mysql_com.h" extern char const * mysql_errno_to_sqlstate(unsigned int); # 424 "mysql.h" extern char const * mysql_error(MYSQL * mysql); @@ -950,30 +950,28 @@ extern MYSQL_RES * mysql_list_fields(MYSQL * mysql, char const * table, char con extern MYSQL_RES * mysql_list_processes(MYSQL * mysql); # 536 "mysql.h" extern MYSQL_RES * mysql_list_tables(MYSQL * mysql, char const * wild); -# 579 "mysql.h" +# 569 "mysql.h" extern void mysql_manager_close(MYSQL_MANAGER * con); -# 580 "mysql.h" +# 570 "mysql.h" extern int mysql_manager_command(MYSQL_MANAGER * con, char const * cmd, int); -# 574 "mysql.h" +# 564 "mysql.h" extern MYSQL_MANAGER * mysql_manager_connect(MYSQL_MANAGER * con, char const * host, char const * user, char const * passwd, unsigned int); -# 582 "mysql.h" +# 572 "mysql.h" extern int mysql_manager_fetch_line(MYSQL_MANAGER * con, char * res_buf, int); -# 573 "mysql.h" +# 563 "mysql.h" extern MYSQL_MANAGER * mysql_manager_init(MYSQL_MANAGER * con); # 456 "mysql.h" extern my_bool mysql_master_query(MYSQL * mysql, char const * q, unsigned long int); # 458 "mysql.h" extern my_bool mysql_master_send_query(MYSQL * mysql, char const * q, unsigned long int); -# 837 "mysql.h" +# 827 "mysql.h" extern my_bool mysql_more_results(MYSQL * mysql); -# 838 "mysql.h" +# 828 "mysql.h" extern int mysql_next_result(MYSQL * mysql); # 412 "mysql.h" extern unsigned int mysql_num_fields(MYSQL_RES * res); # 411 "mysql.h" extern my_ulonglong mysql_num_rows(MYSQL_RES * res); -# 560 "mysql.h" -extern char * mysql_odbc_escape_string(MYSQL * mysql, char * to, unsigned long int, char const * from, unsigned long int, void * param, char * (* extend_buffer)(void *, char * to, unsigned long int * length)); # 538 "mysql.h" extern int mysql_options(MYSQL * mysql, enum mysql_option, void const * arg); # 527 "mysql.h" @@ -984,7 +982,7 @@ extern unsigned int mysql_port; extern int mysql_query(MYSQL * mysql, char const * q); # 780 "mysql/plugin.h" extern void mysql_query_cache_invalidate4(void * thd, char const * key, unsigned int, int); -# 585 "mysql.h" +# 575 "mysql.h" extern my_bool mysql_read_query_result(MYSQL * mysql); # 500 "mysql.h" extern my_bool mysql_reads_from_master_enabled(MYSQL * mysql); @@ -996,7 +994,7 @@ extern unsigned long int mysql_real_escape_string(MYSQL * mysql, char * to, char extern int mysql_real_query(MYSQL * mysql, char const * q, unsigned long int); # 521 "mysql.h" extern int mysql_refresh(MYSQL * mysql, unsigned int); -# 835 "mysql.h" +# 825 "mysql.h" extern my_bool mysql_rollback(MYSQL * mysql); # 543 "mysql.h" extern MYSQL_ROW_OFFSET mysql_row_seek(MYSQL_RES * result, MYSQL_ROW_OFFSET); @@ -1038,59 +1036,59 @@ extern char const * mysql_sqlstate(MYSQL * mysql); extern my_bool mysql_ssl_set(MYSQL * mysql, char const * key, char const * cert, char const * ca, char const * capath, char const * cipher); # 528 "mysql.h" extern char const * mysql_stat(MYSQL * mysql); -# 830 "mysql.h" -extern my_ulonglong mysql_stmt_affected_rows(MYSQL_STMT * stmt); -# 808 "mysql.h" -extern my_bool mysql_stmt_attr_get(MYSQL_STMT * stmt, enum enum_stmt_attr_type, void * attr); -# 805 "mysql.h" -extern my_bool mysql_stmt_attr_set(MYSQL_STMT * stmt, enum enum_stmt_attr_type, void const * attr); -# 811 "mysql.h" -extern my_bool mysql_stmt_bind_param(MYSQL_STMT * stmt, MYSQL_BIND * bnd); -# 812 "mysql.h" -extern my_bool mysql_stmt_bind_result(MYSQL_STMT * stmt, MYSQL_BIND * bnd); -# 813 "mysql.h" -extern my_bool mysql_stmt_close(MYSQL_STMT * stmt); -# 828 "mysql.h" -extern void mysql_stmt_data_seek(MYSQL_STMT * stmt, my_ulonglong); -# 822 "mysql.h" -extern unsigned int mysql_stmt_errno(MYSQL_STMT * stmt); -# 823 "mysql.h" -extern char const * mysql_stmt_error(MYSQL_STMT * stmt); -# 798 "mysql.h" -extern int mysql_stmt_execute(MYSQL_STMT * stmt); -# 799 "mysql.h" -extern int mysql_stmt_fetch(MYSQL_STMT * stmt); -# 800 "mysql.h" -extern int mysql_stmt_fetch_column(MYSQL_STMT * stmt, MYSQL_BIND * bind_arg, unsigned int, unsigned long int); -# 832 "mysql.h" -extern unsigned int mysql_stmt_field_count(MYSQL_STMT * stmt); -# 815 "mysql.h" -extern my_bool mysql_stmt_free_result(MYSQL_STMT * stmt); -# 795 "mysql.h" -extern MYSQL_STMT * mysql_stmt_init(MYSQL * mysql); -# 831 "mysql.h" -extern my_ulonglong mysql_stmt_insert_id(MYSQL_STMT * stmt); -# 829 "mysql.h" -extern my_ulonglong mysql_stmt_num_rows(MYSQL_STMT * stmt); -# 804 "mysql.h" -extern unsigned long int mysql_stmt_param_count(MYSQL_STMT * stmt); -# 821 "mysql.h" -extern MYSQL_RES * mysql_stmt_param_metadata(MYSQL_STMT * stmt); -# 796 "mysql.h" -extern int mysql_stmt_prepare(MYSQL_STMT * stmt, char const * query, unsigned long int); -# 814 "mysql.h" -extern my_bool mysql_stmt_reset(MYSQL_STMT * stmt); # 820 "mysql.h" -extern MYSQL_RES * mysql_stmt_result_metadata(MYSQL_STMT * stmt); -# 825 "mysql.h" -extern MYSQL_ROW_OFFSET mysql_stmt_row_seek(MYSQL_STMT * stmt, MYSQL_ROW_OFFSET); -# 827 "mysql.h" -extern MYSQL_ROW_OFFSET mysql_stmt_row_tell(MYSQL_STMT * stmt); -# 816 "mysql.h" -extern my_bool mysql_stmt_send_long_data(MYSQL_STMT * stmt, unsigned int, char const * data, unsigned long int); -# 824 "mysql.h" -extern char const * mysql_stmt_sqlstate(MYSQL_STMT * stmt); +extern my_ulonglong mysql_stmt_affected_rows(MYSQL_STMT * stmt); +# 798 "mysql.h" +extern my_bool mysql_stmt_attr_get(MYSQL_STMT * stmt, enum enum_stmt_attr_type, void * attr); +# 795 "mysql.h" +extern my_bool mysql_stmt_attr_set(MYSQL_STMT * stmt, enum enum_stmt_attr_type, void const * attr); +# 801 "mysql.h" +extern my_bool mysql_stmt_bind_param(MYSQL_STMT * stmt, MYSQL_BIND * bnd); +# 802 "mysql.h" +extern my_bool mysql_stmt_bind_result(MYSQL_STMT * stmt, MYSQL_BIND * bnd); # 803 "mysql.h" +extern my_bool mysql_stmt_close(MYSQL_STMT * stmt); +# 818 "mysql.h" +extern void mysql_stmt_data_seek(MYSQL_STMT * stmt, my_ulonglong); +# 812 "mysql.h" +extern unsigned int mysql_stmt_errno(MYSQL_STMT * stmt); +# 813 "mysql.h" +extern char const * mysql_stmt_error(MYSQL_STMT * stmt); +# 788 "mysql.h" +extern int mysql_stmt_execute(MYSQL_STMT * stmt); +# 789 "mysql.h" +extern int mysql_stmt_fetch(MYSQL_STMT * stmt); +# 790 "mysql.h" +extern int mysql_stmt_fetch_column(MYSQL_STMT * stmt, MYSQL_BIND * bind_arg, unsigned int, unsigned long int); +# 822 "mysql.h" +extern unsigned int mysql_stmt_field_count(MYSQL_STMT * stmt); +# 805 "mysql.h" +extern my_bool mysql_stmt_free_result(MYSQL_STMT * stmt); +# 785 "mysql.h" +extern MYSQL_STMT * mysql_stmt_init(MYSQL * mysql); +# 821 "mysql.h" +extern my_ulonglong mysql_stmt_insert_id(MYSQL_STMT * stmt); +# 819 "mysql.h" +extern my_ulonglong mysql_stmt_num_rows(MYSQL_STMT * stmt); +# 794 "mysql.h" +extern unsigned long int mysql_stmt_param_count(MYSQL_STMT * stmt); +# 811 "mysql.h" +extern MYSQL_RES * mysql_stmt_param_metadata(MYSQL_STMT * stmt); +# 786 "mysql.h" +extern int mysql_stmt_prepare(MYSQL_STMT * stmt, char const * query, unsigned long int); +# 804 "mysql.h" +extern my_bool mysql_stmt_reset(MYSQL_STMT * stmt); +# 810 "mysql.h" +extern MYSQL_RES * mysql_stmt_result_metadata(MYSQL_STMT * stmt); +# 815 "mysql.h" +extern MYSQL_ROW_OFFSET mysql_stmt_row_seek(MYSQL_STMT * stmt, MYSQL_ROW_OFFSET); +# 817 "mysql.h" +extern MYSQL_ROW_OFFSET mysql_stmt_row_tell(MYSQL_STMT * stmt); +# 806 "mysql.h" +extern my_bool mysql_stmt_send_long_data(MYSQL_STMT * stmt, unsigned int, char const * data, unsigned long int); +# 814 "mysql.h" +extern char const * mysql_stmt_sqlstate(MYSQL_STMT * stmt); +# 793 "mysql.h" extern int mysql_stmt_store_result(MYSQL_STMT * stmt); # 452 "mysql.h" extern MYSQL_RES * mysql_store_result(MYSQL * mysql); @@ -1100,7 +1098,7 @@ extern void mysql_thread_end(void); extern unsigned long int mysql_thread_id(MYSQL * mysql); # 403 "mysql.h" extern my_bool mysql_thread_init(void); -# 571 "mysql.h" +# 561 "mysql.h" extern unsigned int mysql_thread_safe(void); # 699 "mysql/plugin.h" extern int mysql_tmpfile(char const * prefix); @@ -1110,25 +1108,25 @@ extern char * mysql_unix_port; extern MYSQL_RES * mysql_use_result(MYSQL * mysql); # 426 "mysql.h" extern unsigned int mysql_warning_count(MYSQL * mysql); -# 346 "mysql_com.h" -extern void net_clear(NET * net, my_bool); -# 345 "mysql_com.h" -extern void net_end(NET * net); -# 348 "mysql_com.h" -extern my_bool net_flush(NET * net); -# 353 "mysql_com.h" -extern int net_real_write(NET * net, unsigned char const * packet, size_t); # 347 "mysql_com.h" +extern void net_clear(NET * net, my_bool); +# 346 "mysql_com.h" +extern void net_end(NET * net); +# 349 "mysql_com.h" +extern my_bool net_flush(NET * net); +# 354 "mysql_com.h" +extern int net_real_write(NET * net, unsigned char const * packet, size_t); +# 348 "mysql_com.h" extern my_bool net_realloc(NET * net, size_t); -# 350 "mysql_com.h" +# 351 "mysql_com.h" extern my_bool net_write_command(NET * net, unsigned char, unsigned char const * header, size_t, unsigned char const * packet, size_t); -# 442 "mysql_com.h" +# 443 "mysql_com.h" extern char * octet2hex(char * to, char const * str, unsigned int); -# 423 "mysql_com.h" +# 424 "mysql_com.h" extern void randominit(struct rand_struct *, unsigned long int, unsigned long int); -# 437 "mysql_com.h" +# 438 "mysql_com.h" extern void scramble(char * to, char const * message, char const * password); -# 430 "mysql_com.h" +# 431 "mysql_com.h" extern void scramble_323(char * to, char const * message, char const * password); # 37 "typelib.h" extern TYPELIB sql_protocol_typelib; diff --git a/libmysql/libmysql.c b/libmysql/libmysql.c index cb326fa4685..bf5dd7d63eb 100644 --- a/libmysql/libmysql.c +++ b/libmysql/libmysql.c @@ -1629,78 +1629,6 @@ mysql_real_escape_string(MYSQL *mysql, char *to,const char *from, return escape_string_for_mysql(mysql->charset, to, 0, from, length); } - -char * STDCALL -mysql_odbc_escape_string(MYSQL *mysql, - char *to, ulong to_length, - const char *from, ulong from_length, - void *param, - char * (*extend_buffer) - (void *, char *, ulong *)) -{ - char *to_end=to+to_length-5; - const char *end; -#ifdef USE_MB - my_bool use_mb_flag=use_mb(mysql->charset); -#endif - - for (end=from+from_length; from != end ; from++) - { - if (to >= to_end) - { - to_length = (ulong) (end-from)+512; /* We want this much more */ - if (!(to=(*extend_buffer)(param, to, &to_length))) - return to; - to_end=to+to_length-5; - } -#ifdef USE_MB - { - int l; - if (use_mb_flag && (l = my_ismbchar(mysql->charset, from, end))) - { - while (l--) - *to++ = *from++; - from--; - continue; - } - } -#endif - switch (*from) { - case 0: /* Must be escaped for 'mysql' */ - *to++= '\\'; - *to++= '0'; - break; - case '\n': /* Must be escaped for logs */ - *to++= '\\'; - *to++= 'n'; - break; - case '\r': - *to++= '\\'; - *to++= 'r'; - break; - case '\\': - *to++= '\\'; - *to++= '\\'; - break; - case '\'': - *to++= '\\'; - *to++= '\''; - break; - case '"': /* Better safe than sorry */ - *to++= '\\'; - *to++= '"'; - break; - case '\032': /* This gives problems on Win32 */ - *to++= '\\'; - *to++= 'Z'; - break; - default: - *to++= *from; - } - } - return to; -} - void STDCALL myodbc_remove_escape(MYSQL *mysql,char *name) { diff --git a/libmysql/libmysql.def b/libmysql/libmysql.def index 8c6b71d9553..81f86dc8726 100644 --- a/libmysql/libmysql.def +++ b/libmysql/libmysql.def @@ -78,7 +78,6 @@ EXPORTS mysql_next_result mysql_num_fields mysql_num_rows - mysql_odbc_escape_string mysql_options mysql_stmt_param_count mysql_stmt_param_metadata diff --git a/libmysqld/libmysqld.def b/libmysqld/libmysqld.def index 78ff08e510a..2aa75c0b23c 100644 --- a/libmysqld/libmysqld.def +++ b/libmysqld/libmysqld.def @@ -78,7 +78,6 @@ EXPORTS mysql_next_result mysql_num_fields mysql_num_rows - mysql_odbc_escape_string mysql_options mysql_ping mysql_query diff --git a/mysql-test/include/handler.inc b/mysql-test/include/handler.inc index 79e21382d4c..485b2e881d3 100644 --- a/mysql-test/include/handler.inc +++ b/mysql-test/include/handler.inc @@ -598,3 +598,97 @@ handler a2 read a last; handler a2 read a prev; handler a2 close; drop table t1; + +# +# Bug#31397 Inconsistent drop table behavior of handler tables. +# + +--disable_warnings +drop table if exists t1,t2; +--enable_warnings +create table t1 (a int); +handler t1 open as t1_alias; +drop table t1; +create table t1 (a int); +handler t1 open as t1_alias; +flush tables; +drop table t1; +create table t1 (a int); +handler t1 open as t1_alias; +handler t1_alias close; +drop table t1; +create table t1 (a int); +handler t1 open as t1_alias; +handler t1_alias read first; +drop table t1; +--error ER_UNKNOWN_TABLE +handler t1_alias read next; + +# Test that temporary tables associated with handlers are properly dropped. + +create table t1 (a int); +create temporary table t2 (a int, key(a)); +handler t1 open as a1; +handler t2 open as a2; +handler a2 read a first; +drop table t1, t2; +--error ER_UNKNOWN_TABLE +handler a2 read a next; +--error ER_UNKNOWN_TABLE +handler a1 close; + +# Alter table drop handlers + +create table t1 (a int, key(a)); +create table t2 like t1; +handler t1 open as a1; +handler t2 open as a2; +handler a1 read a first; +handler a2 read a first; +alter table t1 add b int; +--error ER_UNKNOWN_TABLE +handler a1 close; +handler a2 close; +drop table t1, t2; + +# Rename table drop handlers + +create table t1 (a int, key(a)); +handler t1 open as a1; +handler a1 read a first; +rename table t1 to t2; +--error ER_UNKNOWN_TABLE +handler a1 read a first; +drop table t2; + +# Optimize table drop handlers + +create table t1 (a int, key(a)); +create table t2 like t1; +handler t1 open as a1; +handler t2 open as a2; +handler a1 read a first; +handler a2 read a first; +optimize table t1; +--error ER_UNKNOWN_TABLE +handler a1 close; +handler a2 close; +drop table t1, t2; + +# Flush tables causes handlers reopen + +create table t1 (a int, b char(1), key a(a), key b(a,b)); +insert into t1 values (0,"a"),(1,"b"),(2,"c"),(3,"d"),(4,"e"), + (5,"f"),(6,"g"),(7,"h"),(8,"i"),(9,"j"); +handler t1 open; +handler t1 read a first; +handler t1 read a next; +flush tables; +handler t1 read a next; +handler t1 read a next; +flush tables with read lock; +handler t1 read a next; +unlock tables; +drop table t1; +--error ER_UNKNOWN_TABLE +handler t1 read a next; diff --git a/mysql-test/r/events_bugs.result b/mysql-test/r/events_bugs.result index 83609856393..b91e7e88d64 100644 --- a/mysql-test/r/events_bugs.result +++ b/mysql-test/r/events_bugs.result @@ -3,6 +3,10 @@ drop database if exists mysqltest_db1; drop database if exists mysqltest_db2; create database events_test; use events_test; +select * from information_schema.global_variables where variable_name like 'event_scheduler'; +VARIABLE_NAME VARIABLE_VALUE +EVENT_SCHEDULER ON +SET GLOBAL event_scheduler = 'OFF'; CREATE EVENT lower_case ON SCHEDULE EVERY 1 MINUTE DO SELECT 1; CREATE EVENT Lower_case ON SCHEDULE EVERY 2 MINUTE DO SELECT 2; ERROR HY000: Event 'Lower_case' already exists diff --git a/mysql-test/r/flush.result b/mysql-test/r/flush.result index dcbffd6f7c8..f1b6c471943 100644 --- a/mysql-test/r/flush.result +++ b/mysql-test/r/flush.result @@ -55,6 +55,23 @@ flush tables with read lock; insert into t2 values(1); unlock tables; drop table t1, t2; +drop table if exists t1, t2; +set session low_priority_updates=1; +create table t1 (a int); +create table t2 (b int); +lock tables t1 write; +flush tables with read lock; +ERROR HY000: Can't execute the given command because you have active locked tables or an active transaction +unlock tables; +lock tables t1 read, t2 write; +flush tables with read lock; +ERROR HY000: Can't execute the given command because you have active locked tables or an active transaction +unlock tables; +lock tables t1 read; +flush tables with read lock; +unlock tables; +drop table t1, t2; +set session low_priority_updates=default; End of 5.0 tests set @old_general_log= @@general_log; set @old_read_only= @@read_only; diff --git a/mysql-test/r/grant.result b/mysql-test/r/grant.result index 4d402d7d0e9..0d40778d5f2 100644 --- a/mysql-test/r/grant.result +++ b/mysql-test/r/grant.result @@ -1226,3 +1226,22 @@ drop user юзер_юзер@localhost; grant select on test.* to очень_длинный_юзер@localhost; ERROR HY000: String 'очень_длинный_юзер' is too long for user name (should be no longer than 16) set names default; +FLUSH PRIVILEGES without procs_priv table. +RENAME TABLE mysql.procs_priv TO mysql.procs_gone; +FLUSH PRIVILEGES; +Warnings: +Error 1146 Table 'mysql.procs_priv' doesn't exist +Error 1548 Cannot load from mysql.mysql.procs_priv. The table is probably corrupted +Assigning privileges without procs_priv table. +CREATE DATABASE mysqltest1; +CREATE PROCEDURE mysqltest1.test() SQL SECURITY DEFINER +SELECT 1; +GRANT EXECUTE ON FUNCTION mysqltest1.test TO mysqltest_1@localhost; +ERROR 42S02: Table 'mysql.procs_priv' doesn't exist +GRANT ALL PRIVILEGES ON test.* TO mysqltest_1@localhost; +CALL mysqltest1.test(); +1 +1 +DROP DATABASE mysqltest1; +RENAME TABLE mysql.procs_gone TO mysql.procs_priv; +FLUSH PRIVILEGES; diff --git a/mysql-test/r/handler_innodb.result b/mysql-test/r/handler_innodb.result index d9a1a0aa12b..9d269f78d10 100644 --- a/mysql-test/r/handler_innodb.result +++ b/mysql-test/r/handler_innodb.result @@ -637,3 +637,94 @@ a b 8 i handler a2 close; drop table t1; +drop table if exists t1,t2; +create table t1 (a int); +handler t1 open as t1_alias; +drop table t1; +create table t1 (a int); +handler t1 open as t1_alias; +flush tables; +drop table t1; +create table t1 (a int); +handler t1 open as t1_alias; +handler t1_alias close; +drop table t1; +create table t1 (a int); +handler t1 open as t1_alias; +handler t1_alias read first; +a +drop table t1; +handler t1_alias read next; +ERROR 42S02: Unknown table 't1_alias' in HANDLER +create table t1 (a int); +create temporary table t2 (a int, key(a)); +handler t1 open as a1; +handler t2 open as a2; +handler a2 read a first; +a +drop table t1, t2; +handler a2 read a next; +ERROR 42S02: Unknown table 'a2' in HANDLER +handler a1 close; +ERROR 42S02: Unknown table 'a1' in HANDLER +create table t1 (a int, key(a)); +create table t2 like t1; +handler t1 open as a1; +handler t2 open as a2; +handler a1 read a first; +a +handler a2 read a first; +a +alter table t1 add b int; +handler a1 close; +ERROR 42S02: Unknown table 'a1' in HANDLER +handler a2 close; +drop table t1, t2; +create table t1 (a int, key(a)); +handler t1 open as a1; +handler a1 read a first; +a +rename table t1 to t2; +handler a1 read a first; +ERROR 42S02: Unknown table 'a1' in HANDLER +drop table t2; +create table t1 (a int, key(a)); +create table t2 like t1; +handler t1 open as a1; +handler t2 open as a2; +handler a1 read a first; +a +handler a2 read a first; +a +optimize table t1; +Table Op Msg_type Msg_text +test.t1 optimize status OK +handler a1 close; +ERROR 42S02: Unknown table 'a1' in HANDLER +handler a2 close; +drop table t1, t2; +create table t1 (a int, b char(1), key a(a), key b(a,b)); +insert into t1 values (0,"a"),(1,"b"),(2,"c"),(3,"d"),(4,"e"), +(5,"f"),(6,"g"),(7,"h"),(8,"i"),(9,"j"); +handler t1 open; +handler t1 read a first; +a b +0 a +handler t1 read a next; +a b +1 b +flush tables; +handler t1 read a next; +a b +0 a +handler t1 read a next; +a b +1 b +flush tables with read lock; +handler t1 read a next; +a b +0 a +unlock tables; +drop table t1; +handler t1 read a next; +ERROR 42S02: Unknown table 't1' in HANDLER diff --git a/mysql-test/r/handler_myisam.result b/mysql-test/r/handler_myisam.result index b42fdc864fe..0b27b07c4d2 100644 --- a/mysql-test/r/handler_myisam.result +++ b/mysql-test/r/handler_myisam.result @@ -637,3 +637,94 @@ a b 8 i handler a2 close; drop table t1; +drop table if exists t1,t2; +create table t1 (a int); +handler t1 open as t1_alias; +drop table t1; +create table t1 (a int); +handler t1 open as t1_alias; +flush tables; +drop table t1; +create table t1 (a int); +handler t1 open as t1_alias; +handler t1_alias close; +drop table t1; +create table t1 (a int); +handler t1 open as t1_alias; +handler t1_alias read first; +a +drop table t1; +handler t1_alias read next; +ERROR 42S02: Unknown table 't1_alias' in HANDLER +create table t1 (a int); +create temporary table t2 (a int, key(a)); +handler t1 open as a1; +handler t2 open as a2; +handler a2 read a first; +a +drop table t1, t2; +handler a2 read a next; +ERROR 42S02: Unknown table 'a2' in HANDLER +handler a1 close; +ERROR 42S02: Unknown table 'a1' in HANDLER +create table t1 (a int, key(a)); +create table t2 like t1; +handler t1 open as a1; +handler t2 open as a2; +handler a1 read a first; +a +handler a2 read a first; +a +alter table t1 add b int; +handler a1 close; +ERROR 42S02: Unknown table 'a1' in HANDLER +handler a2 close; +drop table t1, t2; +create table t1 (a int, key(a)); +handler t1 open as a1; +handler a1 read a first; +a +rename table t1 to t2; +handler a1 read a first; +ERROR 42S02: Unknown table 'a1' in HANDLER +drop table t2; +create table t1 (a int, key(a)); +create table t2 like t1; +handler t1 open as a1; +handler t2 open as a2; +handler a1 read a first; +a +handler a2 read a first; +a +optimize table t1; +Table Op Msg_type Msg_text +test.t1 optimize status Table is already up to date +handler a1 close; +ERROR 42S02: Unknown table 'a1' in HANDLER +handler a2 close; +drop table t1, t2; +create table t1 (a int, b char(1), key a(a), key b(a,b)); +insert into t1 values (0,"a"),(1,"b"),(2,"c"),(3,"d"),(4,"e"), +(5,"f"),(6,"g"),(7,"h"),(8,"i"),(9,"j"); +handler t1 open; +handler t1 read a first; +a b +0 a +handler t1 read a next; +a b +1 b +flush tables; +handler t1 read a next; +a b +0 a +handler t1 read a next; +a b +1 b +flush tables with read lock; +handler t1 read a next; +a b +0 a +unlock tables; +drop table t1; +handler t1 read a next; +ERROR 42S02: Unknown table 't1' in HANDLER diff --git a/mysql-test/r/kill.result b/mysql-test/r/kill.result index a08be429a83..3ea5bbd20bc 100644 --- a/mysql-test/r/kill.result +++ b/mysql-test/r/kill.result @@ -125,3 +125,14 @@ drop function bug27563; drop procedure proc27563; PREPARE stmt FROM 'EXPLAIN SELECT * FROM t1,t2,t3,t4,t5,t6,t7,t8,t9,t10,t11,t12,t13,t14,t15,t16,t17,t18,t19,t20,t21,t22,t23,t24,t25,t26,t27,t28,t29,t30,t31,t32,t33,t34,t35,t36,t37,t38,t39,t40 WHERE a1=a2 AND a2=a3 AND a3=a4 AND a4=a5 AND a5=a6 AND a6=a7 AND a7=a8 AND a8=a9 AND a9=a10 AND a10=a11 AND a11=a12 AND a12=a13 AND a13=a14 AND a14=a15 AND a15=a16 AND a16=a17 AND a17=a18 AND a18=a19 AND a19=a20 AND a20=a21 AND a21=a22 AND a22=a23 AND a23=a24 AND a24=a25 AND a25=a26 AND a26=a27 AND a27=a28 AND a28=a29 AND a29=a30 AND a30=a31 AND a31=a32 AND a32=a33 AND a33=a34 AND a34=a35 AND a35=a36 AND a36=a37 AND a37=a38 AND a38=a39 AND a39=a40 '; EXECUTE stmt; +# +# Bug#19723: kill of active connection yields different error code +# depending on platform. +# + +# Connection: con2. +KILL CONNECTION_ID(); +# CR_SERVER_LOST, CR_SERVER_GONE_ERROR, depending on the timing +# of close of the connection socket +SELECT 1; +Got one of the listed errors diff --git a/mysql-test/r/no-threads.result b/mysql-test/r/no-threads.result index 50e52138be8..aefecd0f7bc 100644 --- a/mysql-test/r/no-threads.result +++ b/mysql-test/r/no-threads.result @@ -4,3 +4,6 @@ select 1+1; select 1+2; 1+2 3 +SHOW GLOBAL VARIABLES LIKE 'thread_handling'; +Variable_name Value +thread_handling no-threads diff --git a/mysql-test/r/skip_grants.result b/mysql-test/r/skip_grants.result index cd652c03f96..bf0f16a174f 100644 --- a/mysql-test/r/skip_grants.result +++ b/mysql-test/r/skip_grants.result @@ -77,3 +77,10 @@ ERROR HY000: Can't initialize function 'a'; UDFs are unavailable with the --skip DROP FUNCTION a; ERROR 42000: FUNCTION test.a does not exist End of 5.0 tests +# +# Bug#29817 Queries with UDF fail with non-descriptive error +# if mysql.proc is missing +# +select no_such_function(1); +ERROR 42000: FUNCTION test.no_such_function does not exist +End of 5.1 tests diff --git a/mysql-test/t/events_bugs-master.opt b/mysql-test/t/events_bugs-master.opt new file mode 100644 index 00000000000..f93413a61e5 --- /dev/null +++ b/mysql-test/t/events_bugs-master.opt @@ -0,0 +1 @@ +--event-scheduler diff --git a/mysql-test/t/events_bugs.test b/mysql-test/t/events_bugs.test index ebd86f3a3d2..efdb67349ec 100644 --- a/mysql-test/t/events_bugs.test +++ b/mysql-test/t/events_bugs.test @@ -9,6 +9,21 @@ drop database if exists mysqltest_db2; create database events_test; use events_test; +# +# START: Bug #31332 --event-scheduler option misbehaving +# + +# NOTE!! this test must come first! It's testing that the --event-scheduler +# option with no argument in events_bugs-master.opt turns the scheduler on. + +select * from information_schema.global_variables where variable_name like 'event_scheduler'; + +SET GLOBAL event_scheduler = 'OFF'; + +# +# END: Bug #31332 +# + # # START - 16415: Events: event names are case sensitive # diff --git a/mysql-test/t/flush.test b/mysql-test/t/flush.test index d58d038c3ea..794423ca211 100644 --- a/mysql-test/t/flush.test +++ b/mysql-test/t/flush.test @@ -133,6 +133,37 @@ disconnect con3; connection default; drop table t1, t2; +# +# Bug#32528 Global read lock with a low priority write lock causes a server crash +# + +--disable_warnings +drop table if exists t1, t2; +--enable_warnings + +set session low_priority_updates=1; + +create table t1 (a int); +create table t2 (b int); + +lock tables t1 write; +--error ER_LOCK_OR_ACTIVE_TRANSACTION +flush tables with read lock; +unlock tables; + +lock tables t1 read, t2 write; +--error ER_LOCK_OR_ACTIVE_TRANSACTION +flush tables with read lock; +unlock tables; + +lock tables t1 read; +flush tables with read lock; +unlock tables; + +drop table t1, t2; + +set session low_priority_updates=default; + --echo End of 5.0 tests # diff --git a/mysql-test/t/grant.test b/mysql-test/t/grant.test index 8d909d63f51..2a1940f4326 100644 --- a/mysql-test/t/grant.test +++ b/mysql-test/t/grant.test @@ -1277,3 +1277,23 @@ drop user юзер_юзер@localhost; --error ER_WRONG_STRING_LENGTH grant select on test.* to очень_длинный_юзер@localhost; set names default; + + +# +# Bug #16470 crash on grant if old grant tables +# +--echo FLUSH PRIVILEGES without procs_priv table. +RENAME TABLE mysql.procs_priv TO mysql.procs_gone; +FLUSH PRIVILEGES; +--echo Assigning privileges without procs_priv table. +CREATE DATABASE mysqltest1; +CREATE PROCEDURE mysqltest1.test() SQL SECURITY DEFINER + SELECT 1; +--error ER_NO_SUCH_TABLE +GRANT EXECUTE ON FUNCTION mysqltest1.test TO mysqltest_1@localhost; +GRANT ALL PRIVILEGES ON test.* TO mysqltest_1@localhost; +CALL mysqltest1.test(); +DROP DATABASE mysqltest1; +RENAME TABLE mysql.procs_gone TO mysql.procs_priv; +FLUSH PRIVILEGES; + diff --git a/mysql-test/t/information_schema.test b/mysql-test/t/information_schema.test index 2dd19a94758..f08d216da27 100644 --- a/mysql-test/t/information_schema.test +++ b/mysql-test/t/information_schema.test @@ -1143,6 +1143,7 @@ END$$ DELIMITER ;$$ +let $wait_timeout= 300; let $wait_condition=select count(*) = 0 from information_schema.events where event_name='event_status'; --source include/wait_condition.inc diff --git a/mysql-test/t/kill.test b/mysql-test/t/kill.test index 5d5095f7d61..3da4232502d 100644 --- a/mysql-test/t/kill.test +++ b/mysql-test/t/kill.test @@ -304,3 +304,21 @@ while ($i) dec $i ; } --enable_query_log + +########################################################################### + +--echo # +--echo # Bug#19723: kill of active connection yields different error code +--echo # depending on platform. +--echo # + +--echo +--echo # Connection: con2. +--connection con2 + +KILL CONNECTION_ID(); + +--echo # CR_SERVER_LOST, CR_SERVER_GONE_ERROR, depending on the timing +--echo # of close of the connection socket +--error 2013, 2006 +SELECT 1; diff --git a/mysql-test/t/no-threads.test b/mysql-test/t/no-threads.test index 806cf24e961..31ea6406ee9 100644 --- a/mysql-test/t/no-threads.test +++ b/mysql-test/t/no-threads.test @@ -3,3 +3,4 @@ # select 1+1; select 1+2; +SHOW GLOBAL VARIABLES LIKE 'thread_handling'; diff --git a/mysql-test/t/skip_grants.test b/mysql-test/t/skip_grants.test index 018366f705f..72a073ac541 100644 --- a/mysql-test/t/skip_grants.test +++ b/mysql-test/t/skip_grants.test @@ -122,7 +122,6 @@ select count(*) from information_schema.COLUMN_PRIVILEGES; select count(*) from information_schema.SCHEMA_PRIVILEGES; select count(*) from information_schema.TABLE_PRIVILEGES; select count(*) from information_schema.USER_PRIVILEGES; - # # Bug #32020: loading udfs while --skip-grant-tables is enabled causes out of # memory errors @@ -134,3 +133,12 @@ CREATE FUNCTION a RETURNS STRING SONAME ''; DROP FUNCTION a; --echo End of 5.0 tests + +--echo # +--echo # Bug#29817 Queries with UDF fail with non-descriptive error +--echo # if mysql.proc is missing +--echo # +--error ER_SP_DOES_NOT_EXIST +select no_such_function(1); + +--echo End of 5.1 tests diff --git a/mysql-test/t/sp_notembedded.test b/mysql-test/t/sp_notembedded.test index b5037b469ae..4a747b9c614 100644 --- a/mysql-test/t/sp_notembedded.test +++ b/mysql-test/t/sp_notembedded.test @@ -45,27 +45,9 @@ call bug4902_2()| call bug4902_2()| drop procedure bug4902_2| - -# Disable until bug#17244 is fixed ---disable_parsing # -# BUG#5278: Stored procedure packets out of order if SET PASSWORD. +# BUG#3583: query cache doesn't work for stored procedures # ---disable_warnings -drop function if exists bug5278| ---enable_warnings -create function bug5278 () returns char -begin - SET PASSWORD FOR 'bob'@'%.loc.gov' = PASSWORD('newpass'); - return 'okay'; -end| - ---error 1133 -select bug5278()| ---error 1133 -select bug5278()| -drop function bug5278| ---enable_parsing --disable_warnings drop table if exists t1| @@ -74,9 +56,6 @@ create table t1 ( id char(16) not null default '', data int not null )| -# -# BUG#3583: query cache doesn't work for stored procedures -# --disable_warnings drop procedure if exists bug3583| --enable_warnings diff --git a/sql/events.cc b/sql/events.cc index 262c62bdbc8..73b8f2cda84 100644 --- a/sql/events.cc +++ b/sql/events.cc @@ -146,7 +146,7 @@ bool Events::set_opt_event_scheduler(char *argument) { if (argument == NULL) - opt_event_scheduler= Events::EVENTS_DISABLED; + opt_event_scheduler= Events::EVENTS_ON; else { int type; diff --git a/sql/item_func.cc b/sql/item_func.cc index 3b108812127..101832b58a9 100644 --- a/sql/item_func.cc +++ b/sql/item_func.cc @@ -3721,13 +3721,12 @@ longlong Item_func_sleep::val_int() break; error= 0; } - + pthread_mutex_unlock(&LOCK_user_locks); pthread_mutex_lock(&thd->mysys_var->mutex); thd->mysys_var->current_mutex= 0; thd->mysys_var->current_cond= 0; pthread_mutex_unlock(&thd->mysys_var->mutex); - pthread_mutex_unlock(&LOCK_user_locks); pthread_cond_destroy(&cond); return test(!error); // Return 1 killed diff --git a/sql/item_strfunc.cc b/sql/item_strfunc.cc index 03c65c9d654..a7624c5bbcd 100644 --- a/sql/item_strfunc.cc +++ b/sql/item_strfunc.cc @@ -356,10 +356,35 @@ String *Item_func_concat::val_str(String *str) } else { // Two big const strings - if (tmp_value.alloc(max_length) || - tmp_value.copy(*res) || - tmp_value.append(*res2)) + /* + NOTE: We should be prudent in the initial allocation unit -- the + size of the arguments is a function of data distribution, which + can be any. Instead of overcommitting at the first row, we grow + the allocated amount by the factor of 2. This ensures that no + more than 25% of memory will be overcommitted on average. + */ + + uint concat_len= res->length() + res2->length(); + + if (tmp_value.alloced_length() < concat_len) + { + if (tmp_value.alloced_length() == 0) + { + if (tmp_value.alloc(concat_len)) + goto null; + } + else + { + uint new_len = max(tmp_value.alloced_length() * 2, concat_len); + + if (tmp_value.realloc(new_len)) + goto null; + } + } + + if (tmp_value.copy(*res) || tmp_value.append(*res2)) goto null; + res= &tmp_value; use_as_buff=str; } @@ -679,8 +704,33 @@ String *Item_func_concat_ws::val_str(String *str) } else { // Two big const strings - if (tmp_value.alloc(max_length) || - tmp_value.copy(*res) || + /* + NOTE: We should be prudent in the initial allocation unit -- the + size of the arguments is a function of data distribution, which can + be any. Instead of overcommitting at the first row, we grow the + allocated amount by the factor of 2. This ensures that no more than + 25% of memory will be overcommitted on average. + */ + + uint concat_len= res->length() + sep_str->length() + res2->length(); + + if (tmp_value.alloced_length() < concat_len) + { + if (tmp_value.alloced_length() == 0) + { + if (tmp_value.alloc(concat_len)) + goto null; + } + else + { + uint new_len = max(tmp_value.alloced_length() * 2, concat_len); + + if (tmp_value.realloc(new_len)) + goto null; + } + } + + if (tmp_value.copy(*res) || tmp_value.append(*sep_str) || tmp_value.append(*res2)) goto null; diff --git a/sql/mysql_priv.h b/sql/mysql_priv.h index 2663de0b16a..8a0993d4f14 100644 --- a/sql/mysql_priv.h +++ b/sql/mysql_priv.h @@ -1291,12 +1291,9 @@ bool mysql_ha_open(THD *thd, TABLE_LIST *tables, bool reopen); bool mysql_ha_close(THD *thd, TABLE_LIST *tables); bool mysql_ha_read(THD *, TABLE_LIST *,enum enum_ha_read_modes,char *, List *,enum ha_rkey_function,Item *,ha_rows,ha_rows); -int mysql_ha_flush(THD *thd, TABLE_LIST *tables, uint mode_flags, - bool is_locked); -/* mysql_ha_flush mode_flags bits */ -#define MYSQL_HA_CLOSE_FINAL 0x00 -#define MYSQL_HA_REOPEN_ON_USAGE 0x01 -#define MYSQL_HA_FLUSH_ALL 0x02 +void mysql_ha_flush(THD *thd); +void mysql_ha_rm_tables(THD *thd, TABLE_LIST *tables); +void mysql_ha_cleanup(THD *thd); /* sql_base.cc */ #define TMP_TABLE_KEY_EXTRA 8 diff --git a/sql/mysqld.cc b/sql/mysqld.cc index 9e947470ca1..fad2e5dcd22 100644 --- a/sql/mysqld.cc +++ b/sql/mysqld.cc @@ -2596,7 +2596,12 @@ int my_message_sql(uint error, const char *str, myf MyFlags) thd->is_slave_error= 1; // needed to catch query errors during replication if (!thd->no_warnings_for_error) + { + thd->no_warnings_for_error= TRUE; push_warning(thd, MYSQL_ERROR::WARN_LEVEL_ERROR, error, str); + thd->no_warnings_for_error= FALSE; + } + /* thd->lex->current_select == 0 if lex structure is not inited (not query command (COM_QUERY)) @@ -4598,8 +4603,13 @@ pthread_handler_t handle_connections_sockets(void *arg __attribute__((unused))) sock == unix_sock ? VIO_LOCALHOST: 0)) || my_net_init(&thd->net,vio_tmp)) { - if (vio_tmp) - vio_delete(vio_tmp); + /* + Only delete the temporary vio if we didn't already attach it to the + NET object. The destructor in THD will delete any initialized net + structure. + */ + if (vio_tmp && thd->net.vio != vio_tmp) + vio_delete(vio_tmp); else { (void) shutdown(new_sock, SHUT_RDWR); @@ -7744,12 +7754,13 @@ mysqld_get_one_option(int optid, break; } case OPT_ONE_THREAD: - global_system_variables.thread_handling= 2; + global_system_variables.thread_handling= + SCHEDULER_ONE_THREAD_PER_CONNECTION; break; case OPT_THREAD_HANDLING: { global_system_variables.thread_handling= - find_type_or_exit(argument, &thread_handling_typelib, opt->name); + find_type_or_exit(argument, &thread_handling_typelib, opt->name)-1; break; } case OPT_FT_BOOLEAN_SYNTAX: diff --git a/sql/scheduler.h b/sql/scheduler.h index 8351cefda4c..46bbd300cbb 100644 --- a/sql/scheduler.h +++ b/sql/scheduler.h @@ -40,7 +40,7 @@ public: enum scheduler_types { - SCHEDULER_ONE_THREAD_PER_CONNECTION=1, + SCHEDULER_ONE_THREAD_PER_CONNECTION=0, SCHEDULER_NO_THREADS, SCHEDULER_POOL_OF_THREADS }; diff --git a/sql/sp_head.cc b/sql/sp_head.cc index 9babbcd49d8..4b432cef5cd 100644 --- a/sql/sp_head.cc +++ b/sql/sp_head.cc @@ -466,14 +466,16 @@ check_routine_name(LEX_STRING *ident) */ void * -sp_head::operator new(size_t size) +sp_head::operator new(size_t size) throw() { DBUG_ENTER("sp_head::operator new"); MEM_ROOT own_root; sp_head *sp; - init_alloc_root(&own_root, MEM_ROOT_BLOCK_SIZE, MEM_ROOT_PREALLOC); + init_sql_alloc(&own_root, MEM_ROOT_BLOCK_SIZE, MEM_ROOT_PREALLOC); sp= (sp_head *) alloc_root(&own_root, size); + if (sp == NULL) + return NULL; sp->main_mem_root= own_root; DBUG_PRINT("info", ("mem_root 0x%lx", (ulong) &sp->mem_root)); DBUG_RETURN(sp); @@ -484,6 +486,10 @@ sp_head::operator delete(void *ptr, size_t size) { DBUG_ENTER("sp_head::operator delete"); MEM_ROOT own_root; + + if (ptr == NULL) + DBUG_VOID_RETURN; + sp_head *sp= (sp_head *) ptr; /* Make a copy of main_mem_root as free_root will free the sp */ @@ -537,6 +543,9 @@ sp_head::init(LEX *lex) lex->spcont= m_pcont= new sp_pcontext(); + if (!lex->spcont) + DBUG_VOID_RETURN; + /* Altough trg_table_fields list is used only in triggers we init for all types of stored procedures to simplify reset_lex()/restore_lex() code. @@ -1070,7 +1079,7 @@ sp_head::execute(THD *thd) DBUG_RETURN(TRUE); /* init per-instruction memroot */ - init_alloc_root(&execute_mem_root, MEM_ROOT_BLOCK_SIZE, 0); + init_sql_alloc(&execute_mem_root, MEM_ROOT_BLOCK_SIZE, 0); DBUG_ASSERT(!(m_flags & IS_INVOKED)); m_flags|= IS_INVOKED; @@ -1962,16 +1971,29 @@ sp_head::execute_procedure(THD *thd, List *args) } -// Reset lex during parsing, before we parse a sub statement. -void +/** + @brief Reset lex during parsing, before we parse a sub statement. + + @param thd Thread handler. + + @return Error state + @retval true An error occurred. + @retval false Success. +*/ + +bool sp_head::reset_lex(THD *thd) { DBUG_ENTER("sp_head::reset_lex"); LEX *sublex; LEX *oldlex= thd->lex; + sublex= new (thd->mem_root)st_lex_local; + if (sublex == 0) + DBUG_RETURN(TRUE); + + thd->lex= sublex; (void)m_lex.push_front(oldlex); - thd->lex= sublex= new st_lex; /* Reset most stuff. */ lex_start(thd); @@ -1992,7 +2014,7 @@ sp_head::reset_lex(THD *thd) sublex->interval_list.empty(); sublex->type= 0; - DBUG_VOID_RETURN; + DBUG_RETURN(FALSE); } // Restore lex during parsing, after we have parsed a sub statement. @@ -3857,7 +3879,7 @@ sp_add_to_query_tables(THD *thd, LEX *lex, if (!(table= (TABLE_LIST *)thd->calloc(sizeof(TABLE_LIST)))) { - my_error(ER_OUTOFMEMORY, MYF(0), sizeof(TABLE_LIST)); + thd->fatal_error(); return NULL; } table->db_length= strlen(db); diff --git a/sql/sp_head.h b/sql/sp_head.h index d74170534bd..86a77a434ff 100644 --- a/sql/sp_head.h +++ b/sql/sp_head.h @@ -260,10 +260,10 @@ public: Security_context m_security_ctx; static void * - operator new(size_t size); + operator new(size_t size) throw (); static void - operator delete(void *ptr, size_t size); + operator delete(void *ptr, size_t size) throw (); sp_head(); @@ -326,7 +326,7 @@ public: } // Resets lex in 'thd' and keeps a copy of the old one. - void + bool reset_lex(THD *thd); // Restores lex in 'thd' from our copy, but keeps some status from the diff --git a/sql/sql_acl.cc b/sql/sql_acl.cc index 311b76c6149..519ca429aa6 100644 --- a/sql/sql_acl.cc +++ b/sql/sql_acl.cc @@ -3472,16 +3472,13 @@ void grant_free(void) } -/* - Initialize structures responsible for table/column-level privilege checking - and load information for them from tables in the 'mysql' database. +/** + @brief Initialize structures responsible for table/column-level privilege + checking and load information for them from tables in the 'mysql' database. - SYNOPSIS - grant_init() - - RETURN VALUES - 0 ok - 1 Could not initialize grant's + @return Error status + @retval 0 OK + @retval 1 Could not initialize grant subsystem. */ my_bool grant_init() @@ -3503,50 +3500,136 @@ my_bool grant_init() } -/* - Initialize structures responsible for table/column-level privilege - checking and load information about grants from open privilege tables. +/** + @brief Helper function to grant_reload_procs_priv - SYNOPSIS - grant_load() - thd Current thread - tables List containing open "mysql.tables_priv" and - "mysql.columns_priv" tables. + Reads the procs_priv table into memory hash. - RETURN VALUES - FALSE - success - TRUE - error + @param table A pointer to the procs_priv table structure. + + @see grant_reload + @see grant_reload_procs_priv + + @return Error state + @retval TRUE An error occurred + @retval FALSE Success +*/ + +static my_bool grant_load_procs_priv(TABLE *p_table) +{ + MEM_ROOT *memex_ptr; + my_bool return_val= 1; + bool check_no_resolve= specialflag & SPECIAL_NO_RESOLVE; + MEM_ROOT **save_mem_root_ptr= my_pthread_getspecific_ptr(MEM_ROOT**, + THR_MALLOC); + DBUG_ENTER("grant_load"); + (void) hash_init(&proc_priv_hash,system_charset_info, + 0,0,0, (hash_get_key) get_grant_table, + 0,0); + (void) hash_init(&func_priv_hash,system_charset_info, + 0,0,0, (hash_get_key) get_grant_table, + 0,0); + p_table->file->ha_index_init(0, 1); + p_table->use_all_columns(); + + if (!p_table->file->index_first(p_table->record[0])) + { + memex_ptr= &memex; + my_pthread_setspecific_ptr(THR_MALLOC, &memex_ptr); + do + { + GRANT_NAME *mem_check; + HASH *hash; + if (!(mem_check=new (memex_ptr) GRANT_NAME(p_table))) + { + /* This could only happen if we are out memory */ + goto end_unlock; + } + + if (check_no_resolve) + { + if (hostname_requires_resolving(mem_check->host.hostname)) + { + sql_print_warning("'procs_priv' entry '%s %s@%s' " + "ignored in --skip-name-resolve mode.", + mem_check->tname, mem_check->user, + mem_check->host.hostname ? + mem_check->host.hostname : ""); + continue; + } + } + if (p_table->field[4]->val_int() == TYPE_ENUM_PROCEDURE) + { + hash= &proc_priv_hash; + } + else + if (p_table->field[4]->val_int() == TYPE_ENUM_FUNCTION) + { + hash= &func_priv_hash; + } + else + { + sql_print_warning("'procs_priv' entry '%s' " + "ignored, bad routine type", + mem_check->tname); + continue; + } + + mem_check->privs= fix_rights_for_procedure(mem_check->privs); + if (! mem_check->ok()) + delete mem_check; + else if (my_hash_insert(hash, (uchar*) mem_check)) + { + delete mem_check; + goto end_unlock; + } + } + while (!p_table->file->index_next(p_table->record[0])); + } + /* Return ok */ + return_val= 0; + +end_unlock: + p_table->file->ha_index_end(); + my_pthread_setspecific_ptr(THR_MALLOC, save_mem_root_ptr); + DBUG_RETURN(return_val); +} + + +/** + @brief Initialize structures responsible for table/column-level privilege + checking and load information about grants from open privilege tables. + + @param thd Current thread + @param tables List containing open "mysql.tables_priv" and + "mysql.columns_priv" tables. + + @see grant_reload + + @return Error state + @retval FALSE Success + @retval TRUE Error */ static my_bool grant_load(TABLE_LIST *tables) { MEM_ROOT *memex_ptr; my_bool return_val= 1; - TABLE *t_table, *c_table, *p_table; + TABLE *t_table= 0, *c_table= 0; bool check_no_resolve= specialflag & SPECIAL_NO_RESOLVE; MEM_ROOT **save_mem_root_ptr= my_pthread_getspecific_ptr(MEM_ROOT**, THR_MALLOC); DBUG_ENTER("grant_load"); - (void) hash_init(&column_priv_hash,system_charset_info, - 0,0,0, (hash_get_key) get_grant_table, - (hash_free_key) free_grant_table,0); - (void) hash_init(&proc_priv_hash,system_charset_info, - 0,0,0, (hash_get_key) get_grant_table, - 0,0); - (void) hash_init(&func_priv_hash,system_charset_info, - 0,0,0, (hash_get_key) get_grant_table, - 0,0); - init_sql_alloc(&memex, ACL_ALLOC_BLOCK_SIZE, 0); + 0,0,0, (hash_get_key) get_grant_table, + (hash_free_key) free_grant_table,0); t_table = tables[0].table; c_table = tables[1].table; - p_table= tables[2].table; t_table->file->ha_index_init(0, 1); - p_table->file->ha_index_init(0, 1); t_table->use_all_columns(); c_table->use_all_columns(); - p_table->use_all_columns(); + if (!t_table->file->index_first(t_table->record[0])) { memex_ptr= &memex; @@ -3584,92 +3667,91 @@ static my_bool grant_load(TABLE_LIST *tables) } while (!t_table->file->index_next(t_table->record[0])); } - if (!p_table->file->index_first(p_table->record[0])) - { - memex_ptr= &memex; - my_pthread_setspecific_ptr(THR_MALLOC, &memex_ptr); - do - { - GRANT_NAME *mem_check; - HASH *hash; - if (!(mem_check=new (&memex) GRANT_NAME(p_table))) - { - /* This could only happen if we are out memory */ - goto end_unlock; - } - if (check_no_resolve) - { - if (hostname_requires_resolving(mem_check->host.hostname)) - { - sql_print_warning("'procs_priv' entry '%s %s@%s' " - "ignored in --skip-name-resolve mode.", - mem_check->tname, mem_check->user, - mem_check->host.hostname ? - mem_check->host.hostname : ""); - continue; - } - } - if (p_table->field[4]->val_int() == TYPE_ENUM_PROCEDURE) - { - hash= &proc_priv_hash; - } - else - if (p_table->field[4]->val_int() == TYPE_ENUM_FUNCTION) - { - hash= &func_priv_hash; - } - else - { - sql_print_warning("'procs_priv' entry '%s' " - "ignored, bad routine type", - mem_check->tname); - continue; - } - - mem_check->privs= fix_rights_for_procedure(mem_check->privs); - if (! mem_check->ok()) - delete mem_check; - else if (my_hash_insert(hash, (uchar*) mem_check)) - { - delete mem_check; - goto end_unlock; - } - } - while (!p_table->file->index_next(p_table->record[0])); - } return_val=0; // Return ok end_unlock: t_table->file->ha_index_end(); - p_table->file->ha_index_end(); my_pthread_setspecific_ptr(THR_MALLOC, save_mem_root_ptr); DBUG_RETURN(return_val); } -/* - Reload information about table and column level privileges if possible. +/** + @brief Helper function to grant_reload. Reloads procs_priv table is it + exists. - SYNOPSIS - grant_reload() - thd Current thread + @param thd A pointer to the thread handler object. - NOTES - Locked tables are checked by acl_reload() and doesn't have to be checked - in this call. - This function is also used for initialization of structures responsible - for table/column-level privilege checking. + @see grant_reload - RETURN VALUE - FALSE Success - TRUE Error + @return Error state + @retval FALSE Success + @retval TRUE An error has occurred. +*/ + +static my_bool grant_reload_procs_priv(THD *thd) +{ + HASH old_proc_priv_hash, old_func_priv_hash; + TABLE_LIST table; + my_bool return_val= FALSE; + DBUG_ENTER("grant_reload_procs_priv"); + + bzero((char*) &table, sizeof(table)); + table.alias= table.table_name= (char*) "procs_priv"; + table.db= (char *) "mysql"; + table.lock_type= TL_READ; + + if (simple_open_n_lock_tables(thd, &table)) + { + close_thread_tables(thd); + DBUG_RETURN(TRUE); + } + + /* Save a copy of the current hash if we need to undo the grant load */ + old_proc_priv_hash= proc_priv_hash; + old_func_priv_hash= func_priv_hash; + + rw_wrlock(&LOCK_grant); + if ((return_val= grant_load_procs_priv(table.table))) + { + /* Error; Reverting to old hash */ + DBUG_PRINT("error",("Reverting to old privileges")); + grant_free(); + proc_priv_hash= old_proc_priv_hash; + func_priv_hash= old_func_priv_hash; + } + else + { + hash_free(&old_proc_priv_hash); + hash_free(&old_func_priv_hash); + } + rw_unlock(&LOCK_grant); + + close_thread_tables(thd); + DBUG_RETURN(return_val); +} + + +/** + @brief Reload information about table and column level privileges if possible + + @param thd Current thread + + Locked tables are checked by acl_reload() and doesn't have to be checked + in this call. + This function is also used for initialization of structures responsible + for table/column-level privilege checking. + + @return Error state + @retval FALSE Success + @retval TRUE Error */ my_bool grant_reload(THD *thd) { - TABLE_LIST tables[3]; - HASH old_column_priv_hash, old_proc_priv_hash, old_func_priv_hash; + TABLE_LIST tables[2]; + HASH old_column_priv_hash; MEM_ROOT old_mem; my_bool return_val= 1; DBUG_ENTER("grant_reload"); @@ -3681,11 +3763,9 @@ my_bool grant_reload(THD *thd) bzero((char*) tables, sizeof(tables)); tables[0].alias= tables[0].table_name= (char*) "tables_priv"; tables[1].alias= tables[1].table_name= (char*) "columns_priv"; - tables[2].alias= tables[2].table_name= (char*) "procs_priv"; - tables[0].db= tables[1].db= tables[2].db= (char *) "mysql"; + tables[0].db= tables[1].db= (char *) "mysql"; tables[0].next_local= tables[0].next_global= tables+1; - tables[1].next_local= tables[1].next_global= tables+2; - tables[0].lock_type= tables[1].lock_type= tables[2].lock_type= TL_READ; + tables[0].lock_type= tables[1].lock_type= TL_READ; /* To avoid deadlocks we should obtain table locks before @@ -3695,35 +3775,45 @@ my_bool grant_reload(THD *thd) goto end; rw_wrlock(&LOCK_grant); - grant_version++; old_column_priv_hash= column_priv_hash; - old_proc_priv_hash= proc_priv_hash; - old_func_priv_hash= func_priv_hash; + + /* + Create a new memory pool but save the current memory pool to make an undo + opertion possible in case of failure. + */ old_mem= memex; + init_sql_alloc(&memex, ACL_ALLOC_BLOCK_SIZE, 0); if ((return_val= grant_load(tables))) { // Error. Revert to old hash DBUG_PRINT("error",("Reverting to old privileges")); grant_free(); /* purecov: deadcode */ column_priv_hash= old_column_priv_hash; /* purecov: deadcode */ - proc_priv_hash= old_proc_priv_hash; - func_priv_hash= old_func_priv_hash; memex= old_mem; /* purecov: deadcode */ } else { hash_free(&old_column_priv_hash); - hash_free(&old_proc_priv_hash); - hash_free(&old_func_priv_hash); free_root(&old_mem,MYF(0)); } rw_unlock(&LOCK_grant); -end: close_thread_tables(thd); + + /* + It is ok failing to load procs_priv table because we may be + working with 4.1 privilege tables. + */ + if (grant_reload_procs_priv(thd)) + my_error(ER_CANNOT_LOAD_FROM_TABLE, MYF(0), "mysql.procs_priv"); + + rw_wrlock(&LOCK_grant); + grant_version++; + rw_unlock(&LOCK_grant); + +end: DBUG_RETURN(return_val); } - /**************************************************************************** Check table level grants diff --git a/sql/sql_base.cc b/sql/sql_base.cc index a7d5848dd66..3cc8a685aa9 100644 --- a/sql/sql_base.cc +++ b/sql/sql_base.cc @@ -87,7 +87,6 @@ bool Prelock_error_handler::safely_trapped_errors() @defgroup Data_Dictionary Data Dictionary @{ */ - TABLE *unused_tables; /* Used by mysql_test */ HASH open_cache; /* Used by mysql_test */ static HASH table_def_cache; @@ -993,8 +992,8 @@ bool close_cached_tables(THD *thd, bool if_wait_for_refresh, thd->proc_info="Flushing tables"; close_old_data_files(thd,thd->open_tables,1,1); - mysql_ha_flush(thd, tables, MYSQL_HA_REOPEN_ON_USAGE | MYSQL_HA_FLUSH_ALL, - TRUE); + mysql_ha_flush(thd); + bool found=1; /* Wait until all threads has closed all the tables we had locked */ DBUG_PRINT("info", @@ -2731,7 +2730,7 @@ TABLE *open_table(THD *thd, TABLE_LIST *table_list, MEM_ROOT *mem_root, deadlock may occur. */ if (thd->handler_tables) - mysql_ha_flush(thd, (TABLE_LIST*) NULL, MYSQL_HA_REOPEN_ON_USAGE, TRUE); + mysql_ha_flush(thd); /* Actually try to find the table in the open_cache. @@ -3530,7 +3529,7 @@ bool wait_for_tables(THD *thd) { thd->some_tables_deleted=0; close_old_data_files(thd,thd->open_tables,0,dropping_tables != 0); - mysql_ha_flush(thd, (TABLE_LIST*) NULL, MYSQL_HA_REOPEN_ON_USAGE, TRUE); + mysql_ha_flush(thd); if (!table_is_used(thd->open_tables,1)) break; (void) pthread_cond_wait(&COND_refresh,&LOCK_open); @@ -4300,7 +4299,7 @@ int open_tables(THD *thd, TABLE_LIST **start, uint *counter, uint flags) temporary mem_root for new .frm parsing. TODO: variables for size */ - init_alloc_root(&new_frm_mem, 8024, 8024); + init_sql_alloc(&new_frm_mem, 8024, 8024); thd->current_tablenr= 0; restart: diff --git a/sql/sql_class.cc b/sql/sql_class.cc index bf8413e8627..f59a848a242 100644 --- a/sql/sql_class.cc +++ b/sql/sql_class.cc @@ -678,9 +678,7 @@ void THD::cleanup(void) lock=locked_tables; locked_tables=0; close_thread_tables(this); } - mysql_ha_flush(this, (TABLE_LIST*) 0, - MYSQL_HA_CLOSE_FINAL | MYSQL_HA_FLUSH_ALL, FALSE); - hash_free(&handler_tables_hash); + mysql_ha_cleanup(this); delete_dynamic(&user_var_events); hash_free(&user_vars); close_temporary_tables(this); @@ -818,7 +816,20 @@ void THD::awake(THD::killed_state state_to_set) if (!slave_thread) thread_scheduler.post_kill_notification(this); #ifdef SIGNAL_WITH_VIO_CLOSE - close_active_vio(); + if (this != current_thd) + { + /* + In addition to a signal, let's close the socket of the thread that + is being killed. This is to make sure it does not block if the + signal is lost. This needs to be done only on platforms where + signals are not a reliable interruption mechanism. + + If we're killing ourselves, we know that we're not blocked, so this + hack is not used. + */ + + close_active_vio(); + } #endif } if (mysys_var) diff --git a/sql/sql_handler.cc b/sql/sql_handler.cc index 19a99f9d12b..31d6b28a73c 100644 --- a/sql/sql_handler.cc +++ b/sql/sql_handler.cc @@ -65,9 +65,6 @@ static enum enum_ha_read_modes rkey_to_rnext[]= { RNEXT_SAME, RNEXT, RPREV, RNEXT, RPREV, RNEXT, RPREV, RPREV }; -static int mysql_ha_flush_table(THD *thd, TABLE **table_ptr, uint mode_flags); - - /* Get hash key and hash key length. @@ -119,13 +116,15 @@ static void mysql_ha_hash_free(TABLE_LIST *tables) @param thd Thread identifier. @param tables A list of tables with the first entry to close. + @param is_locked If LOCK_open is locked. @note Though this function takes a list of tables, only the first list entry will be closed. - @note Broadcasts refresh if it closed the table. + @note Broadcasts refresh if it closed a table with old version. */ -static void mysql_ha_close_table(THD *thd, TABLE_LIST *tables) +static void mysql_ha_close_table(THD *thd, TABLE_LIST *tables, + bool is_locked) { TABLE **table_ptr; @@ -143,13 +142,15 @@ static void mysql_ha_close_table(THD *thd, TABLE_LIST *tables) if (*table_ptr) { (*table_ptr)->file->ha_index_or_rnd_end(); - VOID(pthread_mutex_lock(&LOCK_open)); + if (! is_locked) + VOID(pthread_mutex_lock(&LOCK_open)); if (close_thread_table(thd, table_ptr)) { /* Tell threads waiting for refresh that something has happened */ broadcast_refresh(); } - VOID(pthread_mutex_unlock(&LOCK_open)); + if (! is_locked) + VOID(pthread_mutex_unlock(&LOCK_open)); } else if (tables->table) { @@ -305,7 +306,7 @@ err: if (hash_tables) my_free((char*) hash_tables, MYF(0)); if (tables->table) - mysql_ha_close_table(thd, tables); + mysql_ha_close_table(thd, tables, FALSE); DBUG_PRINT("exit",("ERROR")); DBUG_RETURN(TRUE); } @@ -339,7 +340,7 @@ bool mysql_ha_close(THD *thd, TABLE_LIST *tables) (uchar*) tables->alias, strlen(tables->alias) + 1))) { - mysql_ha_close_table(thd, hash_tables); + mysql_ha_close_table(thd, hash_tables, FALSE); hash_delete(&thd->handler_tables_hash, (uchar*) hash_tables); } else @@ -478,7 +479,7 @@ retry: if (need_reopen) { - mysql_ha_close_table(thd, tables); + mysql_ha_close_table(thd, tables, FALSE); hash_tables->table= NULL; /* The lock might have been aborted, we need to manually reset @@ -669,163 +670,131 @@ err0: } -/* - Flush (close) a list of HANDLER tables. +/** + Scan the handler tables hash for matching tables. - SYNOPSIS - mysql_ha_flush() - thd Thread identifier. - tables The list of tables to close. If NULL, - close all HANDLER tables [marked as flushed]. - mode_flags MYSQL_HA_CLOSE_FINAL finally close the table. - MYSQL_HA_REOPEN_ON_USAGE mark for reopen. - MYSQL_HA_FLUSH_ALL flush all tables, not only - those marked for flush. - is_locked If LOCK_open is locked. + @param thd Thread identifier. + @param tables The list of tables to remove. - DESCRIPTION - The list of HANDLER tables may be NULL, in which case all HANDLER - tables are closed (if MYSQL_HA_FLUSH_ALL) is set. - If 'tables' is NULL and MYSQL_HA_FLUSH_ALL is not set, - all HANDLER tables marked for flush are closed. - Broadcasts refresh for every table closed. - - NOTE - Since mysql_ha_flush() is called when the base table has to be closed, - we compare real table names, not aliases. Hence, database names matter. - - RETURN - 0 ok + @return Pointer to head of linked list (TABLE_LIST::next_local) of matching + TABLE_LIST elements from handler_tables_hash. Otherwise, NULL if no + table was matched. */ -int mysql_ha_flush(THD *thd, TABLE_LIST *tables, uint mode_flags, - bool is_locked) +static TABLE_LIST *mysql_ha_find(THD *thd, TABLE_LIST *tables) { - TABLE_LIST *tmp_tables; - TABLE **table_ptr; - bool did_lock= FALSE; - DBUG_ENTER("mysql_ha_flush"); - DBUG_PRINT("enter", ("tables: 0x%lx mode_flags: 0x%02x", - (long) tables, mode_flags)); + TABLE_LIST *hash_tables, *head= NULL, *first= tables; + DBUG_ENTER("mysql_ha_find"); - if (tables) + /* search for all handlers with matching table names */ + for (uint i= 0; i < thd->handler_tables_hash.records; i++) { - /* Close all tables in the list. */ - for (tmp_tables= tables ; tmp_tables; tmp_tables= tmp_tables->next_local) + hash_tables= (TABLE_LIST*) hash_element(&thd->handler_tables_hash, i); + for (tables= first; tables; tables= tables->next_local) { - DBUG_PRINT("info-in-tables-list",("'%s'.'%s' as '%s'", - tmp_tables->db, tmp_tables->table_name, - tmp_tables->alias)); - /* Close all currently open handler tables with the same base table. */ - table_ptr= &(thd->handler_tables); - while (*table_ptr) - { - if ((!*tmp_tables->db || - !my_strcasecmp(&my_charset_latin1, (*table_ptr)->s->db.str, - tmp_tables->db)) && - ! my_strcasecmp(&my_charset_latin1, - (*table_ptr)->s->table_name.str, - tmp_tables->table_name)) - { - DBUG_PRINT("info",("*table_ptr '%s'.'%s' as '%s'", - (*table_ptr)->s->db.str, - (*table_ptr)->s->table_name.str, - (*table_ptr)->alias)); - /* The first time it is required, lock for close_thread_table(). */ - if (! did_lock && ! is_locked) - { - VOID(pthread_mutex_lock(&LOCK_open)); - did_lock= TRUE; - } - mysql_ha_flush_table(thd, table_ptr, mode_flags); - continue; - } - table_ptr= &(*table_ptr)->next; - } - /* end of handler_tables list */ + if ((! *tables->db || + ! my_strcasecmp(&my_charset_latin1, hash_tables->db, tables->db)) && + ! my_strcasecmp(&my_charset_latin1, hash_tables->table_name, + tables->table_name)) + break; } - /* end of flush tables list */ - } - else - { - /* Close all currently open tables [which are marked for flush]. */ - table_ptr= &(thd->handler_tables); - while (*table_ptr) + if (tables) { - if ((mode_flags & MYSQL_HA_FLUSH_ALL) || - (*table_ptr)->needs_reopen_or_name_lock()) - { - /* The first time it is required, lock for close_thread_table(). */ - if (! did_lock && ! is_locked) - { - VOID(pthread_mutex_lock(&LOCK_open)); - did_lock= TRUE; - } - mysql_ha_flush_table(thd, table_ptr, mode_flags); - continue; - } - table_ptr= &(*table_ptr)->next; + hash_tables->next_local= head; + head= hash_tables; } } - /* Release the lock if it was taken by this function. */ - if (did_lock) - VOID(pthread_mutex_unlock(&LOCK_open)); - - DBUG_RETURN(0); + DBUG_RETURN(head); } -/* - Flush (close) a table. - SYNOPSIS - mysql_ha_flush_table() - thd Thread identifier. - table The table to close. - mode_flags MYSQL_HA_CLOSE_FINAL finally close the table. - MYSQL_HA_REOPEN_ON_USAGE mark for reopen. +/** + Remove matching tables from the HANDLER's hash table. - DESCRIPTION - Broadcasts refresh if it closed the table. - The caller must lock LOCK_open. + @param thd Thread identifier. + @param tables The list of tables to remove. - RETURN - 0 ok + @note Broadcasts refresh if it closed a table with old version. */ -static int mysql_ha_flush_table(THD *thd, TABLE **table_ptr, uint mode_flags) +void mysql_ha_rm_tables(THD *thd, TABLE_LIST *tables) { - TABLE_LIST *hash_tables; - TABLE *table= *table_ptr; - DBUG_ENTER("mysql_ha_flush_table"); - DBUG_PRINT("enter",("'%s'.'%s' as '%s' flags: 0x%02x", - table->s->db.str, table->s->table_name.str, - table->alias, mode_flags)); + TABLE_LIST *hash_tables, *next; + DBUG_ENTER("mysql_ha_rm_tables"); - if ((hash_tables= (TABLE_LIST*) hash_search(&thd->handler_tables_hash, - (uchar*) table->alias, - strlen(table->alias) + 1))) + safe_mutex_assert_not_owner(&LOCK_open); + + DBUG_ASSERT(tables); + + hash_tables= mysql_ha_find(thd, tables); + + while (hash_tables) { - if (! (mode_flags & MYSQL_HA_REOPEN_ON_USAGE)) - { - /* This is a final close. Remove from hash. */ - hash_delete(&thd->handler_tables_hash, (uchar*) hash_tables); - } - else + next= hash_tables->next_local; + if (hash_tables->table) + mysql_ha_close_table(thd, hash_tables, FALSE); + hash_delete(&thd->handler_tables_hash, (uchar*) hash_tables); + hash_tables= next; + } + + DBUG_VOID_RETURN; +} + + +/** + Flush (close and mark for re-open) all tables that should be should + be reopen. + + @param thd Thread identifier. + + @note Broadcasts refresh if it closed a table with old version. +*/ + +void mysql_ha_flush(THD *thd) +{ + TABLE_LIST *hash_tables; + DBUG_ENTER("mysql_ha_flush"); + + safe_mutex_assert_owner(&LOCK_open); + + for (uint i= 0; i < thd->handler_tables_hash.records; i++) + { + hash_tables= (TABLE_LIST*) hash_element(&thd->handler_tables_hash, i); + if (hash_tables->table && hash_tables->table->needs_reopen_or_name_lock()) { + mysql_ha_close_table(thd, hash_tables, TRUE); /* Mark table as closed, ready for re-open. */ hash_tables->table= NULL; } - } - - safe_mutex_assert_owner(&LOCK_open); - (*table_ptr)->file->ha_index_or_rnd_end(); - safe_mutex_assert_owner(&LOCK_open); - if (close_thread_table(thd, table_ptr)) - { - /* Tell threads waiting for refresh that something has happened */ - broadcast_refresh(); } - DBUG_RETURN(0); + DBUG_VOID_RETURN; } + + +/** + Close all HANDLER's tables. + + @param thd Thread identifier. + + @note Broadcasts refresh if it closed a table with old version. +*/ + +void mysql_ha_cleanup(THD *thd) +{ + TABLE_LIST *hash_tables; + DBUG_ENTER("mysql_ha_cleanup"); + + for (uint i= 0; i < thd->handler_tables_hash.records; i++) + { + hash_tables= (TABLE_LIST*) hash_element(&thd->handler_tables_hash, i); + if (hash_tables->table) + mysql_ha_close_table(thd, hash_tables, FALSE); + } + + hash_free(&thd->handler_tables_hash); + + DBUG_VOID_RETURN; +} + diff --git a/sql/sql_lex.h b/sql/sql_lex.h index da0ff94ec96..cdae7449cc7 100644 --- a/sql/sql_lex.h +++ b/sql/sql_lex.h @@ -1834,11 +1834,11 @@ typedef struct st_lex : public Query_tables_list struct st_lex_local: public st_lex { - static void *operator new(size_t size) + static void *operator new(size_t size) throw() { return sql_alloc(size); } - static void *operator new(size_t size, MEM_ROOT *mem_root) + static void *operator new(size_t size, MEM_ROOT *mem_root) throw() { return (void*) alloc_root(mem_root, (uint) size); } diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc index 8ed658df90d..a43d8335b9e 100644 --- a/sql/sql_parse.cc +++ b/sql/sql_parse.cc @@ -6340,24 +6340,23 @@ void add_join_natural(TABLE_LIST *a, TABLE_LIST *b, List *using_fields, } -/* - Reload/resets privileges and the different caches. +/** + @brief Reload/resets privileges and the different caches. - SYNOPSIS - reload_acl_and_cache() - thd Thread handler (can be NULL!) - options What should be reset/reloaded (tables, privileges, - slave...) - tables Tables to flush (if any) - write_to_binlog Depending on 'options', it may be very bad to write the - query to the binlog (e.g. FLUSH SLAVE); this is a - pointer where reload_acl_and_cache() will put 0 if - it thinks we really should not write to the binlog. - Otherwise it will put 1. + @param thd Thread handler (can be NULL!) + @param options What should be reset/reloaded (tables, privileges, slave...) + @param tables Tables to flush (if any) + @param write_to_binlog True if we can write to the binlog. + + @note Depending on 'options', it may be very bad to write the + query to the binlog (e.g. FLUSH SLAVE); this is a + pointer where reload_acl_and_cache() will put 0 if + it thinks we really should not write to the binlog. + Otherwise it will put 1. - RETURN - 0 ok - !=0 error. thd->killed or thd->is_error() is set + @return Error status code + @retval 0 Ok + @retval !=0 Error; thd->killed is set or thd->is_error() is true */ bool reload_acl_and_cache(THD *thd, ulong options, TABLE_LIST *tables, @@ -6461,7 +6460,7 @@ bool reload_acl_and_cache(THD *thd, ulong options, TABLE_LIST *tables, for (; lock_p < end_p; lock_p++) { - if ((*lock_p)->type == TL_WRITE) + if ((*lock_p)->type >= TL_WRITE_ALLOW_WRITE) { my_error(ER_LOCK_OR_ACTIVE_TRANSACTION, MYF(0)); return 1; diff --git a/sql/sql_prepare.cc b/sql/sql_prepare.cc index b1b1502f015..9d4d62e57b6 100644 --- a/sql/sql_prepare.cc +++ b/sql/sql_prepare.cc @@ -2700,7 +2700,7 @@ Prepared_statement::Prepared_statement(THD *thd_arg, Protocol *protocol_arg) last_errno(0), flags((uint) IS_IN_USE) { - init_alloc_root(&main_mem_root, thd_arg->variables.query_alloc_block_size, + init_sql_alloc(&main_mem_root, thd_arg->variables.query_alloc_block_size, thd_arg->variables.query_prealloc_size); *last_error= '\0'; } diff --git a/sql/sql_rename.cc b/sql/sql_rename.cc index 750bcd50479..66d89edc146 100644 --- a/sql/sql_rename.cc +++ b/sql/sql_rename.cc @@ -51,6 +51,8 @@ bool mysql_rename_tables(THD *thd, TABLE_LIST *table_list, bool silent) DBUG_RETURN(1); } + mysql_ha_rm_tables(thd, table_list); + if (wait_if_global_read_lock(thd,0,1)) DBUG_RETURN(1); diff --git a/sql/sql_table.cc b/sql/sql_table.cc index 91acd8d20a3..862a36f8876 100644 --- a/sql/sql_table.cc +++ b/sql/sql_table.cc @@ -1521,6 +1521,8 @@ int mysql_rm_table_part2(THD *thd, TABLE_LIST *tables, bool if_exists, built_query.append("DROP TABLE "); } + mysql_ha_rm_tables(thd, tables); + pthread_mutex_lock(&LOCK_open); /* @@ -1577,13 +1579,7 @@ int mysql_rm_table_part2(THD *thd, TABLE_LIST *tables, bool if_exists, tmp_table_deleted= 1; continue; case -1: - // table already in use - /* - XXX: This branch should never be taken outside of SF, trigger or - prelocked mode. - - DBUG_ASSERT(thd->in_sub_stmt); - */ + DBUG_ASSERT(thd->in_sub_stmt); error= 1; goto err_with_placeholders; default: @@ -4038,7 +4034,8 @@ static bool mysql_admin_table(THD* thd, TABLE_LIST* tables, Protocol::SEND_NUM_ROWS | Protocol::SEND_EOF)) DBUG_RETURN(TRUE); - mysql_ha_flush(thd, tables, MYSQL_HA_CLOSE_FINAL, FALSE); + mysql_ha_rm_tables(thd, tables); + for (table= tables; table; table= table->next_local) { char table_name[NAME_LEN*2+2]; @@ -5801,8 +5798,7 @@ bool mysql_alter_table(THD *thd,char *new_db, char *new_name, build_table_filename(reg_path, sizeof(reg_path), db, table_name, reg_ext, 0); build_table_filename(path, sizeof(path), db, table_name, "", 0); - - mysql_ha_flush(thd, table_list, MYSQL_HA_CLOSE_FINAL, FALSE); + mysql_ha_rm_tables(thd, table_list); /* DISCARD/IMPORT TABLESPACE is always alone in an ALTER TABLE */ if (alter_info->tablespace_op != NO_TABLESPACE_OP)