diff options
author | unknown <serg@serg.mysql.com> | 2001-10-09 15:01:02 +0200 |
---|---|---|
committer | unknown <serg@serg.mysql.com> | 2001-10-09 15:01:02 +0200 |
commit | 85e02d693c10553fd15c1193865a7e6996545838 (patch) | |
tree | 3065e2b92039e911c2fc142749b31c47d64db7cd /sql | |
parent | 2204fbea330b5877a104d64a62f2fa6535833fce (diff) | |
parent | ade101ca2bf132b5eb065ef74aa574c01e202074 (diff) | |
download | mariadb-git-85e02d693c10553fd15c1193865a7e6996545838.tar.gz |
Merge work:/home/bk/mysql-4.0
into serg.mysql.com:/usr/home/serg/Abk/mysql-4.0
mysql-test/r/join.result:
Auto merged
mysql-test/t/join.test:
Auto merged
Diffstat (limited to 'sql')
81 files changed, 1254 insertions, 1058 deletions
diff --git a/sql/Makefile.am b/sql/Makefile.am index abde8b3a738..a11b1d0c252 100644 --- a/sql/Makefile.am +++ b/sql/Makefile.am @@ -24,12 +24,12 @@ INCLUDES = @MT_INCLUDES@ \ @bdb_includes@ @innodb_includes@ @gemini_includes@ \ -I$(srcdir)/../include \ -I$(srcdir)/../regex \ - -I$(srcdir) -I../include $(openssl_includes) + -I$(srcdir) -I../include -I. $(openssl_includes) WRAPLIBS= @WRAPLIBS@ SUBDIRS = share libexec_PROGRAMS = mysqld noinst_PROGRAMS = gen_lex_hash -gen_lex_hash_LDFLAGS = @NOINST_LDFLAGS@ +gen_lex_hash_LDFLAGS = @NOINST_LDFLAGS@ LDADD = ../isam/libnisam.a \ ../merge/libmerge.a \ ../myisam/libmyisam.a \ @@ -43,7 +43,7 @@ LDADD = ../isam/libnisam.a \ mysqld_LDADD = @MYSQLD_EXTRA_LDFLAGS@ \ @bdb_libs@ @innodb_libs@ @pstack_libs@ \ - @gemini_libs@ \ + @gemini_libs@ @innodb_system_libs@ \ $(LDADD) $(CXXLDFLAGS) $(WRAPLIBS) @LIBDL@ @openssl_libs@ noinst_HEADERS = item.h item_func.h item_sum.h item_cmpfunc.h \ item_strfunc.h item_timefunc.h item_uniq.h \ @@ -55,7 +55,7 @@ noinst_HEADERS = item.h item_func.h item_sum.h item_cmpfunc.h \ ha_heap.h ha_myisam.h ha_berkeley.h ha_innobase.h \ ha_gemini.h opt_range.h opt_ft.h \ sql_select.h structs.h table.h sql_udf.h hash_filo.h\ - lex.h lex_symbol.h sql_acl.h sql_crypt.h md5.h \ + lex.h lex_symbol.h sql_acl.h sql_crypt.h \ log_event.h mini_client.h sql_repl.h slave.h \ stacktrace.h sql_sort.h mysqld_SOURCES = sql_lex.cc sql_handler.cc \ @@ -82,7 +82,7 @@ mysqld_SOURCES = sql_lex.cc sql_handler.cc \ sql_udf.cc sql_analyse.cc sql_analyse.h sql_cache.cc \ slave.cc sql_repl.cc sql_union.cc \ mini_client.cc mini_client_errors.c \ - md5.c stacktrace.c + stacktrace.c gen_lex_hash_SOURCES = gen_lex_hash.cc gen_lex_hash_LDADD = $(LDADD) $(CXXLDFLAGS) diff --git a/sql/derror.cc b/sql/derror.cc index 62971fde394..bda0690ae7d 100644 --- a/sql/derror.cc +++ b/sql/derror.cc @@ -51,6 +51,7 @@ static void read_texts(const char *file_name,const char ***point, uchar head[32],*pos; DBUG_ENTER("read_texts"); + *point=0; // If something goes wrong LINT_INIT(buff); funktpos=0; if ((file=my_open(fn_format(name,file_name,language,"",4), @@ -72,8 +73,7 @@ static void read_texts(const char *file_name,const char ***point, Check that the above file is the right version for this program!\n\n", my_progname,name,ant,error_messages); VOID(my_close(file,MYF(MY_WME))); - clean_up(0); /* Clean_up frees everything */ - exit(1); /* We can't continue */ + unireg_abort(1); } x_free((gptr) *point); /* Free old language */ @@ -115,8 +115,7 @@ err: if (file != FERR) VOID(my_close(file,MYF(MY_WME))); fprintf(stderr,buff,my_progname,name); - clean_up(0); /* Clean_up frees everything */ - exit(1); /* We can't continue */ + unireg_abort(1); } /* read_texts */ diff --git a/sql/field.cc b/sql/field.cc index 01178efbdb1..b34f58439db 100644 --- a/sql/field.cc +++ b/sql/field.cc @@ -4122,7 +4122,7 @@ ulonglong Field_blob::get_id(const char *from) ulonglong id = 0; ulong length=get_length(from); if (length) - uint8korr(id, from+packlength); + id=uint8korr(from+packlength); return id; } diff --git a/sql/field.h b/sql/field.h index b9d8e1957c9..8f60b7e008b 100644 --- a/sql/field.h +++ b/sql/field.h @@ -415,10 +415,11 @@ public: unireg_check_arg, field_name_arg, table_arg, 0, zero_arg,unsigned_arg) {} - Field_longlong(uint32 len_arg,bool maybe_null_arg, const char *field_name_arg, - struct st_table *table_arg) + Field_longlong(uint32 len_arg,bool maybe_null_arg, + const char *field_name_arg, + struct st_table *table_arg, bool unsigned_arg) :Field_num((char*) 0, len_arg, maybe_null_arg ? (uchar*) "": 0,0, - NONE, field_name_arg, table_arg,0,0,0) + NONE, field_name_arg, table_arg,0,0,unsigned_arg) {} enum Item_result result_type () const { return INT_RESULT; } enum_field_types type() const { return FIELD_TYPE_LONGLONG;} diff --git a/sql/gen_lex_hash.cc b/sql/gen_lex_hash.cc index 722f5226980..2358dde7b6d 100644 --- a/sql/gen_lex_hash.cc +++ b/sql/gen_lex_hash.cc @@ -26,7 +26,8 @@ #include "mysql_version.h" #include "lex.h" -bool opt_search=0,opt_verbose=0; +bool opt_search=0; +int opt_verbose=0; ulong opt_count=100000; #define max_allowed_array 8000 // Don't generate bigger arrays than this @@ -216,7 +217,7 @@ you have to change 'main' to print out the new function\n"); return(1); } - if (opt_verbose) + if (opt_verbose > 1) fprintf (stderr,"Info: Possible add values: %d\n",found-type_count); for (prime=primes; (function_mod=*prime) ; prime++) @@ -376,7 +377,7 @@ static int get_options(int argc, char **argv) opt_search=1; break; case 'v': - opt_verbose=1; + opt_verbose++; break; case 'V': usage(1); exit(0); case 'I': @@ -473,7 +474,7 @@ int main(int argc,char **argv) MY_INIT(argv[0]); - start_value=2250933L; best_t1=2721579L; best_t2=4627039L; best_type=3; /* mode=4567 add=4 type: 0 */ + start_value=1109118L; best_t1=6657025L; best_t2=6114496L; best_type=1; /* mode=4903 add=3 type: 0 */ if (get_options(argc,(char **) argv)) exit(1); @@ -493,7 +494,7 @@ int main(int argc,char **argv) printf("start_value=%ldL; best_t1=%ldL; best_t2=%ldL; best_type=%d; /* mode=%d add=%d type: %d */\n", start_value, best_t1,best_t2,best_type,best_mod,best_add, best_functype); - + best_start_value=start_value; for (uint i=1 ; i <= opt_count ; i++) { if (i % 10 == 0) @@ -516,6 +517,10 @@ int main(int argc,char **argv) best_start_value,best_t1,best_t2,best_type,best_mod,best_add, best_functype); } + if (opt_verbose && (i % 20000) == 0) + printf("\nstart_value=%ldL; best_t1=%ldL; best_t2=%ldL; best_type=%d; /* mode=%d add=%d type: %d */\n", + best_start_value,best_t1,best_t2,best_type,best_mod,best_add, + best_functype); } } diff --git a/sql/ha_berkeley.cc b/sql/ha_berkeley.cc index e9cd3f57122..b10939227ff 100644 --- a/sql/ha_berkeley.cc +++ b/sql/ha_berkeley.cc @@ -90,7 +90,7 @@ const char *berkeley_lock_names[] = { "DEFAULT", "OLDEST","RANDOM","YOUNGEST",0 }; u_int32_t berkeley_lock_types[]= { DB_LOCK_DEFAULT, DB_LOCK_OLDEST, DB_LOCK_RANDOM }; -TYPELIB berkeley_lock_typelib= {array_elements(berkeley_lock_names),"", +TYPELIB berkeley_lock_typelib= {array_elements(berkeley_lock_names)-1,"", berkeley_lock_names}; static void berkeley_print_error(const char *db_errpfx, char *buffer); diff --git a/sql/ha_gemini.cc b/sql/ha_gemini.cc index e8130c55fc7..a60841c3fe6 100644 --- a/sql/ha_gemini.cc +++ b/sql/ha_gemini.cc @@ -68,7 +68,7 @@ ulong gemini_recovery_options = GEMINI_RECOVERY_FULL; /* bits in gemini_recovery_options */ const char *gemini_recovery_names[] = { "FULL", "NONE", "FORCE" }; -TYPELIB gemini_recovery_typelib= {array_elements(gemini_recovery_names),"", +TYPELIB gemini_recovery_typelib= {array_elements(gemini_recovery_names)-1,"", gemini_recovery_names}; const int start_of_name = 2; /* Name passed as ./<db>/<table-name> diff --git a/sql/ha_innobase.cc b/sql/ha_innobase.cc index cb76c034749..e7d98dbe406 100644 --- a/sql/ha_innobase.cc +++ b/sql/ha_innobase.cc @@ -85,7 +85,7 @@ char *innobase_data_home_dir; char *innobase_log_group_home_dir, *innobase_log_arch_dir; char *innobase_unix_file_flush_method; bool innobase_flush_log_at_trx_commit, innobase_log_archive, - innobase_use_native_aio; + innobase_use_native_aio; /* Set default InnoDB size to 64M, to let users use InnoDB without having @@ -524,7 +524,6 @@ innobase_init(void) /*===============*/ /* out: TRUE if error */ { - static char current_dir[3]; int err; bool ret; @@ -537,11 +536,6 @@ innobase_init(void) srv_query_thread_priority = QUERY_PRIOR; } - /* Use current_dir if no paths are set */ - current_dir[0]=FN_CURLIB; - current_dir[1]=FN_LIBCHAR; - current_dir[2]=0; - /* Set InnoDB initialization parameters according to the values read from MySQL .cnf file */ @@ -550,10 +544,10 @@ innobase_init(void) MYF(MY_WME)); srv_data_home = (innobase_data_home_dir ? innobase_data_home_dir : - current_dir); + mysql_real_data_home); srv_logs_home = (char*) ""; srv_arch_dir = (innobase_log_arch_dir ? innobase_log_arch_dir : - current_dir); + mysql_real_data_home); ret = innobase_parse_data_file_paths_and_sizes(); @@ -563,7 +557,7 @@ innobase_init(void) } if (!innobase_log_group_home_dir) - innobase_log_group_home_dir= current_dir; + innobase_log_group_home_dir= mysql_real_data_home; ret = innobase_parse_log_group_home_dirs(); if (ret == FALSE) { @@ -591,6 +585,8 @@ innobase_init(void) srv_lock_wait_timeout = (ulint) innobase_lock_wait_timeout; + srv_print_verbose_log = mysql_embedded ? 0 : 1; + err = innobase_start_or_create_for_mysql(); if (err != DB_SUCCESS) { diff --git a/sql/ha_isam.cc b/sql/ha_isam.cc index 746fdd2f585..2451b8bdaec 100644 --- a/sql/ha_isam.cc +++ b/sql/ha_isam.cc @@ -20,6 +20,7 @@ #endif #include "mysql_priv.h" +#ifdef HAVE_ISAM #include <m_ctype.h> #include <myisampack.h> #include "ha_isam.h" @@ -388,3 +389,4 @@ ha_rows ha_isam::records_in_range(int inx, end_key,end_key_len, end_search_flag); } +#endif /* HAVE_ISAM */ diff --git a/sql/ha_isammrg.cc b/sql/ha_isammrg.cc index dd2e4e2f723..41fb99fe867 100644 --- a/sql/ha_isammrg.cc +++ b/sql/ha_isammrg.cc @@ -20,11 +20,12 @@ #endif #include "mysql_priv.h" +#ifdef HAVE_ISAM #include <m_ctype.h> #ifndef MASTER -#include "../srclib/merge/mrgdef.h" +#include "../srclib/merge/mrg_def.h" #else -#include "../merge/mrgdef.h" +#include "../merge/mrg_def.h" #endif #include "ha_isammrg.h" @@ -208,3 +209,4 @@ int ha_isammrg::create(const char *name, register TABLE *form, char buff[FN_REFLEN]; return mrg_create(fn_format(buff,name,"","",2+4+16),0); } +#endif /* HAVE_ISAM */ diff --git a/sql/ha_myisam.cc b/sql/ha_myisam.cc index 812e0b77077..ea91a460182 100644 --- a/sql/ha_myisam.cc +++ b/sql/ha_myisam.cc @@ -36,7 +36,7 @@ ulong myisam_recover_options= HA_RECOVER_NONE; /* bits in myisam_recover_options */ const char *myisam_recover_names[] = { "DEFAULT", "BACKUP", "FORCE", "QUICK", NullS}; -TYPELIB myisam_recover_typelib= {array_elements(myisam_recover_names),"", +TYPELIB myisam_recover_typelib= {array_elements(myisam_recover_names)-1,"", myisam_recover_names}; @@ -374,14 +374,14 @@ int ha_myisam::restore(THD* thd, HA_CHECK_OPT *check_opt) char* backup_dir = thd->lex.backup_dir; char src_path[FN_REFLEN], dst_path[FN_REFLEN]; char* table_name = table->real_name; + int error; + const char* errmsg; DBUG_ENTER("restore"); - if (!fn_format(src_path, table_name, backup_dir, MI_NAME_DEXT, 4 + 64)) + if (fn_format_relative_to_data_home(src_path, table_name, backup_dir, + MI_NAME_DEXT)) DBUG_RETURN(HA_ADMIN_INVALID); - int error = 0; - const char* errmsg = ""; - if (my_copy(src_path, fn_format(dst_path, table->path, "", MI_NAME_DEXT, 4), MYF(MY_WME))) { @@ -404,7 +404,7 @@ int ha_myisam::restore(THD* thd, HA_CHECK_OPT *check_opt) param.db_name = table->table_cache_key; param.table_name = table->table_name; param.testflag = 0; - mi_check_print_error(¶m,errmsg, errno ); + mi_check_print_error(¶m,errmsg, my_errno); DBUG_RETURN(error); } } @@ -415,41 +415,47 @@ int ha_myisam::backup(THD* thd, HA_CHECK_OPT *check_opt) char* backup_dir = thd->lex.backup_dir; char src_path[FN_REFLEN], dst_path[FN_REFLEN]; char* table_name = table->real_name; - int error = 0; - const char* errmsg = ""; - - if (!fn_format(dst_path, table_name, backup_dir, reg_ext, 4 + 64)) - { - errmsg = "Failed in fn_format() for .frm file: errno = %d"; - error = HA_ADMIN_INVALID; - goto err; - } + int error; + const char *errmsg; + DBUG_ENTER("ha_myisam::backup"); + + if (fn_format_relative_to_data_home(dst_path, table_name, backup_dir, + reg_ext)) + { + errmsg = "Failed in fn_format() for .frm file: errno = %d"; + error = HA_ADMIN_INVALID; + goto err; + } - if (my_copy(fn_format(src_path, table->path,"", reg_ext, 4), - dst_path, - MYF(MY_WME | MY_HOLD_ORIGINAL_MODES ))) + if (my_copy(fn_format(src_path, table->path,"", reg_ext, MY_UNPACK_FILENAME), + dst_path, + MYF(MY_WME | MY_HOLD_ORIGINAL_MODES))) { error = HA_ADMIN_FAILED; errmsg = "Failed copying .frm file: errno = %d"; goto err; } - if (!fn_format(dst_path, table_name, backup_dir, MI_NAME_DEXT, 4 + 64)) - { - errmsg = "Failed in fn_format() for .MYD file: errno = %d"; - error = HA_ADMIN_INVALID; - goto err; - } + /* Change extension */ + if (!fn_format(dst_path, dst_path, "", MI_NAME_DEXT, + MY_REPLACE_EXT | MY_UNPACK_FILENAME | MY_SAFE_PATH)) + { + errmsg = "Failed in fn_format() for .MYD file: errno = %d"; + error = HA_ADMIN_INVALID; + goto err; + } - if (my_copy(fn_format(src_path, table->path,"", MI_NAME_DEXT, 4), + if (my_copy(fn_format(src_path, table->path,"", MI_NAME_DEXT, + MY_UNPACK_FILENAME), dst_path, - MYF(MY_WME | MY_HOLD_ORIGINAL_MODES )) ) - { - errmsg = "Failed copying .MYD file: errno = %d"; - error= HA_ADMIN_FAILED; - goto err; - } - return HA_ADMIN_OK; + MYF(MY_WME | MY_HOLD_ORIGINAL_MODES))) + { + errmsg = "Failed copying .MYD file: errno = %d"; + error= HA_ADMIN_FAILED; + goto err; + } + DBUG_RETURN(HA_ADMIN_OK); + err: { MI_CHECK param; @@ -459,8 +465,8 @@ int ha_myisam::backup(THD* thd, HA_CHECK_OPT *check_opt) param.db_name = table->table_cache_key; param.table_name = table->table_name; param.testflag = 0; - mi_check_print_error(¶m,errmsg, errno ); - return error; + mi_check_print_error(¶m,errmsg, my_errno); + DBUG_RETURN(error); } } diff --git a/sql/ha_myisammrg.cc b/sql/ha_myisammrg.cc index abcf81806ad..0a2ef534ad1 100644 --- a/sql/ha_myisammrg.cc +++ b/sql/ha_myisammrg.cc @@ -23,9 +23,9 @@ #include <m_ctype.h> #include "ha_myisammrg.h" #ifndef MASTER -#include "../srclib/myisammrg/mymrgdef.h" +#include "../srclib/myisammrg/myrg_def.h" #else -#include "../myisammrg/mymrgdef.h" +#include "../myisammrg/myrg_def.h" #endif /***************************************************************************** @@ -66,7 +66,13 @@ int ha_myisammrg::close(void) int ha_myisammrg::write_row(byte * buf) { - return (my_errno=HA_ERR_WRONG_COMMAND); + statistic_increment(ha_write_count,&LOCK_status); + if (table->time_stamp) + update_timestamp(buf+table->time_stamp-1); + if (table->next_number_field && buf == table->record[0]) + return (my_errno=HA_ERR_WRONG_COMMAND); + // update_auto_increment(); - [phi] have to check this before allowing it + return myrg_write(file,buf); } int ha_myisammrg::update_row(const byte * old_data, byte * new_data) @@ -181,6 +187,11 @@ void ha_myisammrg::info(uint flag) int ha_myisammrg::extra(enum ha_extra_function operation) { + /* As this is just a mapping, we don't have to force the underlying + tables to be closed */ + if (operation == HA_EXTRA_FORCE_REOPEN || + operation == HA_EXTRA_PREPARE_FOR_DELETE) + return 0; return myrg_extra(file,operation); } @@ -217,6 +228,7 @@ THR_LOCK_DATA **ha_myisammrg::store_lock(THD *thd, void ha_myisammrg::update_create_info(HA_CREATE_INFO *create_info) { + // [phi] auto_increment stuff is missing (but currently not needed) DBUG_ENTER("ha_myisammrg::update_create_info"); if (!(create_info->used_fields & HA_CREATE_USED_UNION)) { @@ -241,6 +253,10 @@ void ha_myisammrg::update_create_info(HA_CREATE_INFO *create_info) } *create_info->merge_list.next=0; } + if (!(create_info->used_fields & HA_CREATE_USED_INSERT_METHOD)) + { + create_info->merge_insert_method = file->merge_insert_method; + } DBUG_VOID_RETURN; err: @@ -263,12 +279,19 @@ int ha_myisammrg::create(const char *name, register TABLE *form, *pos++= tables->real_name; *pos=0; DBUG_RETURN(myrg_create(fn_format(buff,name,"","",2+4+16), - (const char **) table_names, (my_bool) 0)); + (const char **) table_names, + create_info->merge_insert_method, + (my_bool) 0)); } void ha_myisammrg::append_create_info(String *packet) { char buff[FN_REFLEN]; + if (file->merge_insert_method != MERGE_INSERT_DISABLED) + { + packet->append(" INSERT_METHOD=",15); + packet->append(get_type(&merge_insert_method,file->merge_insert_method-1)); + } packet->append(" UNION=(",8); MYRG_TABLE *table,*first; diff --git a/sql/handler.cc b/sql/handler.cc index 8b7b7fe6799..5a41498aff1 100644 --- a/sql/handler.cc +++ b/sql/handler.cc @@ -25,7 +25,7 @@ #include "ha_heap.h" #include "ha_myisam.h" #include "ha_myisammrg.h" -#ifndef NO_ISAM +#ifdef HAVE_ISAM #include "ha_isam.h" #include "ha_isammrg.h" #endif @@ -88,11 +88,9 @@ enum db_type ha_checktype(enum db_type database_type) #ifndef NO_HASH case DB_TYPE_HASH: #endif -#ifndef NO_MERGE - case DB_TYPE_MRG_ISAM: -#endif -#ifndef NO_ISAM +#ifdef HAVE_ISAM case DB_TYPE_ISAM: + case DB_TYPE_MRG_ISAM: #endif case DB_TYPE_HEAP: case DB_TYPE_MYISAM: @@ -111,11 +109,9 @@ handler *get_new_handler(TABLE *table, enum db_type db_type) #ifndef NO_HASH return new ha_hash(table); #endif -#ifndef NO_MERGE +#ifdef HAVE_ISAM case DB_TYPE_MRG_ISAM: return new ha_isammrg(table); -#endif -#ifndef NO_ISAM case DB_TYPE_ISAM: return new ha_isam(table); #endif @@ -186,14 +182,14 @@ int ha_init() int ha_panic(enum ha_panic_function flag) { int error=0; -#ifndef NO_MERGE - error|=mrg_panic(flag); -#endif #ifndef NO_HASH error|=h_panic(flag); /* fix hash */ #endif - error|=heap_panic(flag); +#ifdef HAVE_ISAM + error|=mrg_panic(flag); error|=nisam_panic(flag); +#endif + error|=heap_panic(flag); error|=mi_panic(flag); error|=myrg_panic(flag); #ifdef HAVE_BERKELEY_DB diff --git a/sql/handler.h b/sql/handler.h index 5cf39daeadf..f0806ea3bea 100644 --- a/sql/handler.h +++ b/sql/handler.h @@ -114,15 +114,20 @@ enum db_type { DB_TYPE_UNKNOWN=0,DB_TYPE_DIAB_ISAM=1, DB_TYPE_BERKELEY_DB, DB_TYPE_INNODB, DB_TYPE_GEMINI, DB_TYPE_DEFAULT }; -enum row_type { ROW_TYPE_DEFAULT, ROW_TYPE_FIXED, ROW_TYPE_DYNAMIC, - ROW_TYPE_COMPRESSED }; +enum row_type { ROW_TYPE_NOT_USED=-1, ROW_TYPE_DEFAULT, ROW_TYPE_FIXED, + ROW_TYPE_DYNAMIC, ROW_TYPE_COMPRESSED}; /* struct to hold information about the table that should be created */ /* Bits in used_fields */ -#define HA_CREATE_USED_AUTO 1 -#define HA_CREATE_USED_RAID 2 -#define HA_CREATE_USED_UNION 4 +#define HA_CREATE_USED_AUTO 1 +#define HA_CREATE_USED_RAID 2 +#define HA_CREATE_USED_UNION 4 +#define HA_CREATE_USED_INSERT_METHOD 8 +#define HA_CREATE_USED_MIN_ROWS 16 +#define HA_CREATE_USED_MAX_ROWS 32 +#define HA_CREATE_USED_AVG_ROW_LENGTH 64 +#define HA_CREATE_USED_PACK_KEYS 128 typedef struct st_thd_trans { void *bdb_tid; @@ -150,6 +155,7 @@ typedef struct st_ha_create_information bool if_not_exists; ulong used_fields; SQL_LIST merge_list; + uint merge_insert_method; } HA_CREATE_INFO; diff --git a/sql/item.cc b/sql/item.cc index d5961fe1733..5eae3a9b542 100644 --- a/sql/item.cc +++ b/sql/item.cc @@ -37,7 +37,7 @@ void item_init(void) Item::Item() { marker=0; - binary=maybe_null=null_value=with_sum_func=0; + binary=maybe_null=null_value=with_sum_func=unsigned_flag=0; name=0; decimals=0; max_length=0; next=current_thd->free_list; // Put in free list @@ -116,6 +116,7 @@ void Item_field::set_field(Field *field_par) table_name=field_par->table_name; field_name=field_par->field_name; binary=field_par->binary(); + unsigned_flag=test(field_par->flags & UNSIGNED_FLAG); } const char *Item_ident::full_name() const @@ -298,13 +299,21 @@ bool Item::fix_fields(THD *thd, bool Item_field::fix_fields(THD *thd,TABLE_LIST *tables) { - if (!field) + if (!field) // If field is not checked { Field *tmp; if (!(tmp=find_field_in_tables(thd,this,tables))) return 1; set_field(tmp); } + else if (thd && thd->set_query_id && field->query_id != thd->query_id) + { + /* We only come here in unions */ + TABLE *table=field->table; + field->query_id=thd->query_id; + table->used_fields++; + table->used_keys&=field->part_of_key; + } return 0; } @@ -318,6 +327,8 @@ void Item::init_make_field(Send_field *tmp_field, tmp_field->type=field_type; tmp_field->length=max_length; tmp_field->decimals=decimals; + if (unsigned_flag) + tmp_field->flags |= UNSIGNED_FLAG; } /* ARGSUSED */ @@ -337,6 +348,7 @@ void Item_uint::make_field(Send_field *tmp_field) { init_make_field(tmp_field,FIELD_TYPE_LONGLONG); tmp_field->flags|= UNSIGNED_FLAG; + unsigned_flag=1; } void Item_real::make_field(Send_field *tmp_field) diff --git a/sql/item.h b/sql/item.h index 98abdc834d9..27611a3cce5 100644 --- a/sql/item.h +++ b/sql/item.h @@ -43,6 +43,7 @@ public: my_bool maybe_null; /* If item may be null */ my_bool null_value; /* if item is null */ my_bool binary; + my_bool unsigned_flag; my_bool with_sum_func; @@ -80,6 +81,7 @@ public: virtual void split_sum_func(List<Item> &fields) {} virtual bool get_date(TIME *ltime,bool fuzzydate); virtual bool get_time(TIME *ltime); + virtual bool is_null() { return 0; } }; @@ -129,6 +131,7 @@ public: Field *tmp_table_field() { return result_field; } bool get_date(TIME *ltime,bool fuzzydate); bool get_time(TIME *ltime); + bool is_null() { return field->is_null(); } }; @@ -149,6 +152,7 @@ public: bool send(String *str); bool basic_const_item() const { return 1; } Item *new_item() { return new Item_null(name); } + bool is_null() { return 1; } }; @@ -382,6 +386,7 @@ public: void copy(); table_map used_tables() const { return (table_map) 1L; } bool const_item() const { return 0; } + bool is_null() { return null_value; } }; diff --git a/sql/item_cmpfunc.cc b/sql/item_cmpfunc.cc index db1d6911119..f825b4960c5 100644 --- a/sql/item_cmpfunc.cc +++ b/sql/item_cmpfunc.cc @@ -1197,14 +1197,12 @@ longlong Item_cond_or::val_int() longlong Item_func_isnull::val_int() { - (void) args[0]->val(); - return (args[0]->null_value) ? 1 : 0; + return args[0]->is_null() ? 1: 0; } longlong Item_func_isnotnull::val_int() { - (void) args[0]->val(); - return !(args[0]->null_value) ? 1 : 0; + return args[0]->is_null() ? 0 : 1; } diff --git a/sql/item_cmpfunc.h b/sql/item_cmpfunc.h index 5ee0687c064..9ed3e86d6e8 100644 --- a/sql/item_cmpfunc.h +++ b/sql/item_cmpfunc.h @@ -46,6 +46,7 @@ public: virtual enum Functype rev_functype() const { return UNKNOWN_FUNC; } bool have_rev_func() const { return rev_functype() != UNKNOWN_FUNC; } void print(String *str) { Item_func::print_op(str); } + bool is_null() { return test(args[0]->is_null() || args[1]->is_null()); } }; @@ -459,7 +460,10 @@ public: Item_func_isnotnull(Item *a) :Item_bool_func(a) {} longlong val_int(); enum Functype functype() const { return ISNOTNULL_FUNC; } - void fix_length_and_dec() { decimals=0; max_length=1; maybe_null=0; } + void fix_length_and_dec() + { + decimals=0; max_length=1; maybe_null=0; + } const char *func_name() const { return "isnotnull"; } optimize_type select_optimize() const { return OPTIMIZE_NULL; } }; diff --git a/sql/item_func.cc b/sql/item_func.cc index 3ef5ed5d7a3..1d5603505e5 100644 --- a/sql/item_func.cc +++ b/sql/item_func.cc @@ -184,8 +184,10 @@ String *Item_num_func::val_str(String *str) longlong nr=val_int(); if (null_value) return 0; /* purecov: inspected */ - else + else if (!unsigned_flag) str->set(nr); + else + str->set((ulonglong) nr); } else { @@ -207,24 +209,31 @@ void Item_func::fix_num_length_and_dec() max_length=float_length(decimals); } - String *Item_int_func::val_str(String *str) { longlong nr=val_int(); if (null_value) return 0; - else + else if (!unsigned_flag) str->set(nr); + else + str->set((ulonglong) nr); return str; } -/* Change from REAL_RESULT (default) to INT_RESULT if both arguments are integers */ +/* + Change from REAL_RESULT (default) to INT_RESULT if both arguments are + integers +*/ void Item_num_op::find_num_type(void) { if (args[0]->result_type() == INT_RESULT && args[1]->result_type() == INT_RESULT) + { hybrid_type=INT_RESULT; + unsigned_flag=args[0]->unsigned_flag | args[1]->unsigned_flag; + } } String *Item_num_op::val_str(String *str) @@ -234,8 +243,10 @@ String *Item_num_op::val_str(String *str) longlong nr=val_int(); if (null_value) return 0; /* purecov: inspected */ - else + else if (!unsigned_flag) str->set(nr); + else + str->set((ulonglong) nr); } else { @@ -667,8 +678,10 @@ String *Item_func_min_max::val_str(String *str) longlong nr=val_int(); if (null_value) return 0; - else + else if (!unsigned_flag) str->set(nr); + else + str->set((ulonglong) nr); return str; } case REAL_RESULT: @@ -1050,7 +1063,8 @@ udf_handler::~udf_handler() } free_udf(u_d); } - delete [] buffers; + if (buffers) // Because of bug in ecc + delete [] buffers; } @@ -1306,8 +1320,10 @@ String *Item_func_udf_int::val_str(String *str) longlong nr=val_int(); if (null_value) return 0; - else + else if (!unsigned_flag) str->set(nr); + else + str->set((ulonglong) nr); return str; } @@ -1402,19 +1418,16 @@ void item_user_lock_release(ULL *ull) if (mysql_bin_log.is_open()) { THD *thd = current_thd; - int save_errno; char buf[256]; String tmp(buf,sizeof(buf)); tmp.length(0); tmp.append("SELECT release_lock(\""); tmp.append(ull->key,ull->key_length); tmp.append("\")"); - save_errno=thd->net.last_errno; - thd->net.last_errno=0; thd->query_length=tmp.length(); Query_log_event qev(thd,tmp.ptr()); + qev.error_code=0; // this query is always safe to run on slave mysql_bin_log.write(&qev); - thd->net.last_errno=save_errno; } if (--ull->count) pthread_cond_signal(&ull->cond); @@ -1448,6 +1461,80 @@ longlong Item_master_pos_wait::val_int() return event_count; } +#ifdef EXTRA_DEBUG +void debug_sync_point(const char* lock_name, uint lock_timeout) +{ + THD* thd=current_thd; + ULL* ull; + struct timespec abstime; + int lock_name_len,error=0; + lock_name_len=strlen(lock_name); + pthread_mutex_lock(&LOCK_user_locks); + + if (thd->ull) + { + item_user_lock_release(thd->ull); + thd->ull=0; + } + + /* if the lock has not been aquired by some client, we do not want to + create an entry for it, since we immediately release the lock. In + this case, we will not be waiting, but rather, just waste CPU and + memory on the whole deal + */ + if (!(ull= ((ULL*) hash_search(&hash_user_locks,lock_name, + lock_name_len)))) + { + pthread_mutex_unlock(&LOCK_user_locks); + return; + } + ull->count++; + + /* structure is now initialized. Try to get the lock */ + /* Set up control struct to allow others to abort locks */ + thd->proc_info="User lock"; + thd->mysys_var->current_mutex= &LOCK_user_locks; + thd->mysys_var->current_cond= &ull->cond; + +#ifdef HAVE_TIMESPEC_TS_SEC + abstime.ts_sec=time((time_t*) 0)+(time_t) lock_timeout; + abstime.ts_nsec=0; +#else + abstime.tv_sec=time((time_t*) 0)+(time_t) lock_timeout; + abstime.tv_nsec=0; +#endif + + while (!thd->killed && + (error=pthread_cond_timedwait(&ull->cond,&LOCK_user_locks,&abstime)) + != ETIME && error != ETIMEDOUT && ull->locked) ; + if (ull->locked) + { + if (!--ull->count) + delete ull; // Should never happen + } + else + { + ull->locked=1; + ull->thread=thd->real_id; + thd->ull=ull; + } + pthread_mutex_unlock(&LOCK_user_locks); + pthread_mutex_lock(&thd->mysys_var->mutex); + thd->proc_info=0; + thd->mysys_var->current_mutex= 0; + thd->mysys_var->current_cond= 0; + pthread_mutex_unlock(&thd->mysys_var->mutex); + pthread_mutex_lock(&LOCK_user_locks); + if (thd->ull) + { + item_user_lock_release(thd->ull); + thd->ull=0; + } + pthread_mutex_unlock(&LOCK_user_locks); +} + +#endif + /* Get a user level lock. If the thread has an old lock this is first released. Returns 1: Got lock diff --git a/sql/item_func.h b/sql/item_func.h index ac4c230f312..bd3ef0bf2d7 100644 --- a/sql/item_func.h +++ b/sql/item_func.h @@ -119,6 +119,7 @@ public: { return (null_value=args[0]->get_time(ltime)); } + bool is_null() { (void) val_int(); return null_value; } friend class udf_handler; }; @@ -147,6 +148,7 @@ public: longlong val_int() { return (longlong) val(); } enum Item_result result_type () const { return hybrid_type; } void fix_length_and_dec() { fix_num_length_and_dec(); } + bool is_null() { (void) val(); return null_value; } }; @@ -161,6 +163,7 @@ class Item_num_op :public Item_func enum Item_result result_type () const { return hybrid_type; } void fix_length_and_dec() { fix_num_length_and_dec(); find_num_type(); } void find_num_type(void); + bool is_null() { (void) val(); return null_value; } }; diff --git a/sql/item_strfunc.cc b/sql/item_strfunc.cc index 12561fe4326..355f28d5432 100644 --- a/sql/item_strfunc.cc +++ b/sql/item_strfunc.cc @@ -17,7 +17,7 @@ /* This file defines all string functions ** Warning: Some string functions doesn't always put and end-null on a String -** (This shouldn't be neaded) +** (This shouldn't be needed) */ #ifdef __GNUC__ @@ -384,7 +384,7 @@ void Item_func_reverse::fix_length_and_dec() /* ** Replace all occurences of string2 in string1 with string3. -** Don't reallocate val_str() if not neaded +** Don't reallocate val_str() if not needed */ /* TODO: Fix that this works with binary strings when using USE_MB */ diff --git a/sql/item_sum.cc b/sql/item_sum.cc index 812fc636fef..431d8b56e6a 100644 --- a/sql/item_sum.cc +++ b/sql/item_sum.cc @@ -52,6 +52,8 @@ void Item_sum::make_field(Send_field *tmp_field) tmp_field->flags=0; if (!maybe_null) tmp_field->flags|= NOT_NULL_FLAG; + if (unsigned_flag) + tmp_field->flags |= UNSIGNED_FLAG; tmp_field->length=max_length; tmp_field->decimals=decimals; tmp_field->type=(result_type() == INT_RESULT ? FIELD_TYPE_LONG : @@ -150,7 +152,7 @@ Item_sum_hybrid::fix_fields(THD *thd,TABLE_LIST *tables) return 1; hybrid_type=item->result_type(); if (hybrid_type == INT_RESULT) - max_length=21; + max_length=20; else if (hybrid_type == REAL_RESULT) max_length=float_length(decimals); else @@ -158,6 +160,7 @@ Item_sum_hybrid::fix_fields(THD *thd,TABLE_LIST *tables) decimals=item->decimals; maybe_null=item->maybe_null; binary=item->binary; + unsigned_flag=item->unsigned_flag; result_field=0; null_value=1; fix_length_and_dec(); @@ -323,12 +326,27 @@ double Item_sum_hybrid::val() { if (null_value) return 0.0; - if (hybrid_type == STRING_RESULT) - { + switch (hybrid_type) { + case STRING_RESULT: String *res; res=val_str(&str_value); return res ? atof(res->c_ptr()) : 0.0; + case INT_RESULT: + if (unsigned_flag) + return ulonglong2double(sum_int); + return (double) sum_int; + case REAL_RESULT: + return sum; } - return sum; + return 0; // Keep compiler happy +} + +longlong Item_sum_hybrid::val_int() +{ + if (null_value) + return 0; + if (hybrid_type == INT_RESULT) + return sum_int; + return (longlong) Item_sum_hybrid::val(); } @@ -337,25 +355,26 @@ Item_sum_hybrid::val_str(String *str) { if (null_value) return 0; - if (hybrid_type == STRING_RESULT) + switch (hybrid_type) { + case STRING_RESULT: return &value; - str->set(sum,decimals); - return str; + case REAL_RESULT: + str->set(sum,decimals); + break; + case INT_RESULT: + if (unsigned_flag) + str->set((ulonglong) sum_int); + else + str->set((longlong) sum_int); + break; + } + return str; // Keep compiler happy } - bool Item_sum_min::add() { - if (hybrid_type != STRING_RESULT) - { - double nr=args[0]->val(); - if (!args[0]->null_value && (null_value || nr < sum)) - { - sum=nr; - null_value=0; - } - } - else + switch (hybrid_type) { + case STRING_RESULT: { String *result=args[0]->val_str(&tmp_value); if (!args[0]->null_value && @@ -366,22 +385,39 @@ bool Item_sum_min::add() null_value=0; } } - return 0; -} - - -bool Item_sum_max::add() -{ - if (hybrid_type != STRING_RESULT) + break; + case INT_RESULT: + { + longlong nr=args[0]->val_int(); + if (!args[0]->null_value && (null_value || + (unsigned_flag && + (ulonglong) nr < (ulonglong) sum_int) || + (!unsigned_flag && nr < sum_int))) + { + sum_int=nr; + null_value=0; + } + } + break; + case REAL_RESULT: { double nr=args[0]->val(); - if (!args[0]->null_value && (null_value || nr > sum)) + if (!args[0]->null_value && (null_value || nr < sum)) { sum=nr; null_value=0; } } - else + break; + } + return 0; +} + + +bool Item_sum_max::add() +{ + switch (hybrid_type) { + case STRING_RESULT: { String *result=args[0]->val_str(&tmp_value); if (!args[0]->null_value && @@ -392,6 +428,31 @@ bool Item_sum_max::add() null_value=0; } } + break; + case INT_RESULT: + { + longlong nr=args[0]->val_int(); + if (!args[0]->null_value && (null_value || + (unsigned_flag && + (ulonglong) nr > (ulonglong) sum_int) || + (!unsigned_flag && nr > sum_int))) + { + sum_int=nr; + null_value=0; + } + } + break; + case REAL_RESULT: + { + double nr=args[0]->val(); + if (!args[0]->null_value && (null_value || nr > sum)) + { + sum=nr; + null_value=0; + } + } + break; + } return 0; } @@ -676,9 +737,17 @@ Item_sum_hybrid::min_max_update_int_field(int offset) nr=args[0]->val_int(); if (!args[0]->null_value) { - if (result_field->is_null(offset) || - (cmp_sign > 0 ? old_nr > nr : old_nr < nr)) + if (result_field->is_null(offset)) old_nr=nr; + else + { + bool res=(unsigned_flag ? + (ulonglong) old_nr > (ulonglong) nr : + old_nr > nr); + /* (cmp_sign > 0 && res) || (!(cmp_sign > 0) && !res) */ + if ((cmp_sign > 0) ^ (!res)) + old_nr=nr; + } result_field->set_notnull(); } else if (result_field->is_null(offset)) @@ -1079,7 +1148,7 @@ void Item_udf_sum::reset() bool Item_udf_sum::add() { - DBUG_ENTER("Item_udf_sum::reset"); + DBUG_ENTER("Item_udf_sum::add"); udf.add(&null_value); DBUG_RETURN(0); } diff --git a/sql/item_sum.h b/sql/item_sum.h index 7356eeda28c..18b0c3ff577 100644 --- a/sql/item_sum.h +++ b/sql/item_sum.h @@ -271,6 +271,7 @@ class Item_sum_hybrid :public Item_sum protected: String value,tmp_value; double sum; + longlong sum_int; Item_result hybrid_type; int cmp_sign; table_map used_table_cache; @@ -286,12 +287,13 @@ class Item_sum_hybrid :public Item_sum void reset() { sum=0.0; + sum_int=0; value.length(0); null_value=1; add(); } double val(); - longlong val_int() { return (longlong) val(); } /* Real as default */ + longlong val_int(); void reset_field(); String *val_str(String *); void make_const() { used_table_cache=0; } diff --git a/sql/lex.h b/sql/lex.h index 1d481aa7c85..72d77e18910 100644 --- a/sql/lex.h +++ b/sql/lex.h @@ -83,6 +83,7 @@ static SYMBOL symbols[] = { { "CHANGED", SYM(CHANGED),0,0}, { "CHECK", SYM(CHECK_SYM),0,0}, { "CHECKSUM", SYM(CHECKSUM_SYM),0,0}, + { "CIPHER", SYM(CIPHER_SYM),0,0}, { "CLOSE", SYM(CLOSE_SYM),0,0}, { "COLUMN", SYM(COLUMN_SYM),0,0}, { "COLUMNS", SYM(COLUMNS),0,0}, @@ -177,6 +178,7 @@ static SYMBOL symbols[] = { { "INNODB", SYM(INNOBASE_SYM),0,0}, { "INSERT", SYM(INSERT),0,0}, { "INSERT_ID", SYM(INSERT_ID),0,0}, + { "INSERT_METHOD", SYM(INSERT_METHOD),0,0}, { "INT", SYM(INT_SYM),0,0}, { "INTEGER", SYM(INT_SYM),0,0}, { "INTERVAL", SYM(INTERVAL_SYM),0,0}, @@ -190,6 +192,7 @@ static SYMBOL symbols[] = { { "IS", SYM(IS),0,0}, { "ISOLATION", SYM(ISOLATION),0,0}, { "ISAM", SYM(ISAM_SYM),0,0}, + { "ISSUER", SYM(ISSUER_SYM),0,0}, { "JOIN", SYM(JOIN_SYM),0,0}, { "KEY", SYM(KEY_SYM),0,0}, { "KEYS", SYM(KEYS),0,0}, @@ -277,6 +280,7 @@ static SYMBOL symbols[] = { { "REPAIR", SYM(REPAIR),0,0}, { "REPLACE", SYM(REPLACE),0,0}, { "REPEATABLE", SYM(REPEATABLE_SYM),0,0}, + { "REQUIRE", SYM(REQUIRE_SYM),0,0}, { "RESET", SYM(RESET_SYM),0,0}, { "RESTORE", SYM(RESTORE_SYM),0,0}, { "RESTRICT", SYM(RESTRICT),0,0}, @@ -315,6 +319,7 @@ static SYMBOL symbols[] = { { "SQL_SLAVE_SKIP_COUNTER", SYM(SQL_SLAVE_SKIP_COUNTER),0,0}, { "SQL_SMALL_RESULT", SYM(SQL_SMALL_RESULT),0,0}, { "SQL_WARNINGS", SYM(SQL_WARNINGS),0,0}, + { "SSL", SYM(SSL_SYM),0,0}, { "STRAIGHT_JOIN", SYM(STRAIGHT_JOIN),0,0}, { "START", SYM(START_SYM),0,0}, { "STARTING", SYM(STARTING),0,0}, @@ -322,6 +327,7 @@ static SYMBOL symbols[] = { { "STRING", SYM(STRING_SYM),0,0}, { "STOP", SYM(STOP_SYM),0,0}, { "STRIPED", SYM(RAID_STRIPED_SYM),0,0}, + { "SUBJECT", SYM(SUBJECT_SYM),0,0}, { "TABLE", SYM(TABLE_SYM),0,0}, { "TABLES", SYM(TABLES),0,0}, { "TEMPORARY", SYM(TEMPORARY),0,0}, @@ -357,6 +363,7 @@ static SYMBOL symbols[] = { { "WRITE", SYM(WRITE_SYM),0,0}, { "WHEN", SYM(WHEN_SYM),0,0}, { "WHERE", SYM(WHERE),0,0}, + { "X509", SYM(X509_SYM),0,0}, { "YEAR", SYM(YEAR_SYM),0,0}, { "YEAR_MONTH", SYM(YEAR_MONTH_SYM),0,0}, { "ZEROFILL", SYM(ZEROFILL),0,0}, diff --git a/sql/log_event.cc b/sql/log_event.cc index 83fac4a7706..5bd386c7b29 100644 --- a/sql/log_event.cc +++ b/sql/log_event.cc @@ -21,6 +21,7 @@ #endif #include "mysql_priv.h" #include "slave.h" +#include <my_dir.h> #endif /* MYSQL_CLIENT */ #ifdef MYSQL_CLIENT @@ -127,6 +128,25 @@ Log_event::Log_event(THD* thd_arg, uint16 flags_arg): when = time(NULL); } } + +static void cleanup_load_tmpdir() +{ + MY_DIR *dirp; + FILEINFO *file; + uint i; + if (!(dirp=my_dir(slave_load_tmpdir,MYF(MY_WME)))) + return; + + for (i=0;i<(uint)dirp->number_off_files;i++) + { + file=dirp->dir_entry+i; + if (!memcmp(file->name,"SQL_LOAD-",9)) + my_delete(file->name,MYF(MY_WME)); + } + + my_dirend(dirp); +} + #endif Log_event::Log_event(const char* buf):cached_event_len(0),temp_buf(0) @@ -469,7 +489,7 @@ Log_event* Log_event::read_log_event(IO_CACHE* file) error = "read error"; goto err; } - if((res = read_log_event(buf, data_len))) + if ((res = read_log_event(buf, data_len, &error))) res->register_temp_buf(buf); err: UNLOCK_MUTEX; @@ -481,10 +501,11 @@ err: return res; } -Log_event* Log_event::read_log_event(const char* buf, int event_len) +Log_event* Log_event::read_log_event(const char* buf, int event_len, + const char **error) { - if(event_len < EVENT_LEN_OFFSET || - (uint)event_len != uint4korr(buf+EVENT_LEN_OFFSET)) + if (event_len < EVENT_LEN_OFFSET || + (uint)event_len != uint4korr(buf+EVENT_LEN_OFFSET)) return NULL; // general sanity check - will fail on a partial read Log_event* ev = NULL; @@ -531,6 +552,7 @@ Log_event* Log_event::read_log_event(const char* buf, int event_len) if (!ev) return 0; if (!ev->is_valid()) { + *error= "Found invalid event in binary log"; delete ev; return 0; } @@ -812,80 +834,92 @@ int Load_log_event::write_data_body(IO_CACHE* file) if (sql_ex.write_data(file)) return 1; if (num_fields && fields && field_lens) { - if(my_b_write(file, (byte*)field_lens, num_fields) || - my_b_write(file, (byte*)fields, field_block_len)) + if (my_b_write(file, (byte*)field_lens, num_fields) || + my_b_write(file, (byte*)fields, field_block_len)) return 1; } - return my_b_write(file, (byte*)table_name, table_name_len + 1) || - my_b_write(file, (byte*)db, db_len + 1) || - my_b_write(file, (byte*)fname, fname_len); + return (my_b_write(file, (byte*)table_name, table_name_len + 1) || + my_b_write(file, (byte*)db, db_len + 1) || + my_b_write(file, (byte*)fname, fname_len)); } -#define WRITE_STR(name) my_b_write(file,(byte*)&name ## _len, 1) || \ - my_b_write(file,(byte*)name,name ## _len) -#define OLD_EX_INIT(name) old_ex.##name = *name + +static bool write_str(IO_CACHE *file, char *str, byte length) +{ + return (my_b_write(file, &length, 1) || + my_b_write(file, (byte*) str, (int) length)); +} int sql_ex_info::write_data(IO_CACHE* file) { if (new_format()) { - return WRITE_STR(field_term) || WRITE_STR(enclosed) || - WRITE_STR(line_term) || WRITE_STR(line_start) || - WRITE_STR(escaped) || my_b_write(file,(byte*)&opt_flags,1); + return (write_str(file, field_term, field_term_len) || + write_str(file, enclosed, enclosed_len) || + write_str(file, line_term, line_term_len) || + write_str(file, line_start, line_start_len) || + write_str(file, escaped, escaped_len) || + my_b_write(file,(byte*) &opt_flags,1)); } else { old_sql_ex old_ex; - OLD_EX_INIT(field_term); - OLD_EX_INIT(enclosed); - OLD_EX_INIT(line_term); - OLD_EX_INIT(line_start); - OLD_EX_INIT(escaped); - old_ex.opt_flags = opt_flags; - old_ex.empty_flags = empty_flags; - return my_b_write(file,(byte*)&old_ex,sizeof(old_ex)); + old_ex.field_term= *field_term; + old_ex.enclosed= *enclosed; + old_ex.line_term= *line_term; + old_ex.line_start= *line_start; + old_ex.escaped= *escaped; + old_ex.opt_flags= opt_flags; + old_ex.empty_flags=empty_flags; + return my_b_write(file, (byte*) &old_ex, sizeof(old_ex)); } } -#define READ_STR(name) name ## _len = *buf++;\ - if (buf >= buf_end) return 0;\ - name = buf; \ - buf += name ## _len; \ - if (buf >= buf_end) return 0; - -#define READ_OLD_STR(name) name ## _len = 1; \ - name = buf++; \ - if (buf >= buf_end) return 0; - -#define FIX_OLD_LEN(name,NAME) if (empty_flags & NAME ## _EMPTY) \ - name ## _len = 0 +static inline int read_str(char * &buf, char *buf_end, char * &str, + uint8 &len) +{ + if (buf + (uint) (uchar) *buf >= buf_end) + return 1; + len = (uint8) *buf; + str= buf+1; + buf+= (uint) len+1; + return 0; +} char* sql_ex_info::init(char* buf,char* buf_end,bool use_new_format) { cached_new_format = use_new_format; if (use_new_format) { - READ_STR(field_term); - READ_STR(enclosed); - READ_STR(line_term); - READ_STR(line_start); - READ_STR(escaped); + empty_flags=0; + if (read_str(buf, buf_end, field_term, field_term_len) || + read_str(buf, buf_end, enclosed, enclosed_len) || + read_str(buf, buf_end, line_term, line_term_len) || + read_str(buf, buf_end, line_start, line_start_len) || + read_str(buf, buf_end, escaped, escaped_len)) + return 0; opt_flags = *buf++; } else { - READ_OLD_STR(field_term); - READ_OLD_STR(enclosed); - READ_OLD_STR(line_term); - READ_OLD_STR(line_start); - READ_OLD_STR(escaped); + field_term_len= enclosed_len= line_term_len= line_start_len= escaped_len=1; + *field_term=*buf++; + *enclosed= *buf++; + *line_term= *buf++; + *line_start=*buf++; + *escaped= *buf++; opt_flags = *buf++; - empty_flags = *buf++; - FIX_OLD_LEN(field_term,FIELD_TERM); - FIX_OLD_LEN(enclosed,ENCLOSED); - FIX_OLD_LEN(line_term,LINE_TERM); - FIX_OLD_LEN(line_start,LINE_START); - FIX_OLD_LEN(escaped,ESCAPED); + empty_flags=*buf++; + if (empty_flags & FIELD_TERM_EMPTY) + field_term_len=0; + if (empty_flags & ENCLOSED_EMPTY) + enclosed_len=0; + if (empty_flags & LINE_TERM_EMPTY) + line_term_len=0; + if (empty_flags & LINE_START_EMPTY) + line_start_len=0; + if (empty_flags & ESCAPED_EMPTY) + escaped_len=0; } return buf; } @@ -1271,6 +1305,8 @@ Create_file_log_event::Create_file_log_event(const char* buf, int len): block = (char*)buf + block_offset; block_len = len - block_offset; } + + #ifdef MYSQL_CLIENT void Create_file_log_event::print(FILE* file, bool short_form, char* last_db) @@ -1477,10 +1513,10 @@ int Query_log_event::exec_event(struct st_master_info* mi) (actual_error = thd->net.last_errno) && expected_error) { const char* errmsg = "Slave: did not get the expected error\ - running query from master - expected: '%s'(%d), got '%s'(%d)"; + running query from master - expected: '%s' (%d), got '%s' (%d)"; sql_print_error(errmsg, ER_SAFE(expected_error), expected_error, - actual_error ? thd->net.last_error:"no error", + actual_error ? thd->net.last_error: "no error", actual_error); thd->query_error = 1; } @@ -1553,20 +1589,16 @@ int Load_log_event::exec_event(NET* net, struct st_master_info* mi) handle_dup = DUP_REPLACE; sql_exchange ex((char*)fname, sql_ex.opt_flags && DUMPFILE_FLAG ); - -#define SET_EX(name) String name(sql_ex.name,sql_ex.name ## _len);\ - ex.name = &name; - - SET_EX(field_term); - SET_EX(enclosed); - SET_EX(line_term); - SET_EX(line_start); - SET_EX(escaped); + String field_term(sql_ex.field_term,sql_ex.field_term_len); + String enclosed(sql_ex.enclosed,sql_ex.enclosed_len); + String line_term(sql_ex.line_term,sql_ex.line_term_len); + String line_start(sql_ex.line_start,sql_ex.line_start_len); + String escaped(sql_ex.escaped,sql_ex.escaped_len); ex.opt_enclosed = (sql_ex.opt_flags & OPT_ENCLOSED_FLAG); - if(sql_ex.empty_flags & FIELD_TERM_EMPTY) + if (sql_ex.empty_flags & FIELD_TERM_EMPTY) ex.field_term->length(0); - + ex.skip_lines = skip_lines; List<Item> fields; set_fields(fields); @@ -1626,6 +1658,7 @@ int Load_log_event::exec_event(NET* net, struct st_master_info* mi) int Start_log_event::exec_event(struct st_master_info* mi) { close_temporary_tables(thd); + cleanup_load_tmpdir(); return Log_event::exec_event(mi); } @@ -1634,6 +1667,7 @@ int Stop_log_event::exec_event(struct st_master_info* mi) if(mi->pos > 4) // stop event should be ignored after rotate event { close_temporary_tables(thd); + cleanup_load_tmpdir(); mi->inc_pos(get_event_len(), log_seq); flush_master_info(mi); } @@ -1862,10 +1896,3 @@ err: #endif - - - - - - - diff --git a/sql/log_event.h b/sql/log_event.h index d938bced742..71f0f2a8575 100644 --- a/sql/log_event.h +++ b/sql/log_event.h @@ -272,7 +272,8 @@ public: #else // avoid having to link mysqlbinlog against libpthread static Log_event* read_log_event(IO_CACHE* file); #endif - static Log_event* read_log_event(const char* buf, int event_len); + static Log_event* read_log_event(const char* buf, int event_len, + const char **error); const char* get_type_str(); #ifndef MYSQL_CLIENT @@ -567,9 +568,10 @@ public: uint file_id; #ifndef MYSQL_CLIENT Create_file_log_event(THD* thd, sql_exchange* ex, const char* db_arg, - const char* table_name_arg, - List<Item>& fields_arg, enum enum_duplicates handle_dup, - char* block_arg, uint block_len_arg); + const char* table_name_arg, + List<Item>& fields_arg, + enum enum_duplicates handle_dup, + char* block_arg, uint block_len_arg); #endif Create_file_log_event(const char* buf, int event_len); diff --git a/sql/md5.c b/sql/md5.c deleted file mode 100644 index a4ff75d469a..00000000000 --- a/sql/md5.c +++ /dev/null @@ -1,353 +0,0 @@ -/* MD5C.C - RSA Data Security, Inc., MD5 message-digest algorithm - */ - -/* Copyright (C) 1991-2, RSA Data Security, Inc. Created 1991. All -rights reserved. - -License to copy and use this software is granted provided that it -is identified as the "RSA Data Security, Inc. MD5 Message-Digest -Algorithm" in all material mentioning or referencing this software -or this function. - -License is also granted to make and use derivative works provided -that such works are identified as "derived from the RSA Data -Security, Inc. MD5 Message-Digest Algorithm" in all material -mentioning or referencing the derived work. - -RSA Data Security, Inc. makes no representations concerning either -the merchantability of this software or the suitability of this -software for any particular purpose. It is provided "as is" -without express or implied warranty of any kind. - -These notices must be retained in any copies of any part of this -documentation and/or software. -*/ - -/* - Changes by Monty: - Replace of MD5_memset and MD5_memcpy with memset & memcpy -*/ - -#include <my_global.h> -#include <m_string.h> -#include "md5.h" - -/* Constants for MD5Transform routine. */ - -#define S11 7 -#define S12 12 -#define S13 17 -#define S14 22 -#define S21 5 -#define S22 9 -#define S23 14 -#define S24 20 -#define S31 4 -#define S32 11 -#define S33 16 -#define S34 23 -#define S41 6 -#define S42 10 -#define S43 15 -#define S44 21 - - -static void MD5Transform PROTO_LIST ((UINT4 [4], unsigned char [64])); -static void Encode PROTO_LIST - ((unsigned char *, UINT4 *, unsigned int)); -static void Decode PROTO_LIST - ((UINT4 *, unsigned char *, unsigned int)); -#ifdef OLD_CODE -static void MD5_memcpy PROTO_LIST ((POINTER, POINTER, unsigned int)); -static void MD5_memset PROTO_LIST ((POINTER, int, unsigned int)); -#else -#define MD5_memcpy(A,B,C) memcpy((char*) (A),(char*) (B), (C)) -#define MD5_memset(A,B,C) memset((char*) (A),(B), (C)) -#endif - -static unsigned char PADDING[64] = { - 0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 -}; - -/* F, G, H and I are basic MD5 functions. - */ -#define F(x, y, z) (((x) & (y)) | ((~x) & (z))) -#define G(x, y, z) (((x) & (z)) | ((y) & (~z))) -#define H(x, y, z) ((x) ^ (y) ^ (z)) -#define I(x, y, z) ((y) ^ ((x) | (~z))) - -/* ROTATE_LEFT rotates x left n bits. - */ -#define ROTATE_LEFT(x, n) (((x) << (n)) | ((x) >> (32-(n)))) - -/* FF, GG, HH, and II transformations for rounds 1, 2, 3, and 4. -Rotation is separate from addition to prevent recomputation. - */ -#define FF(a, b, c, d, x, s, ac) { \ - (a) += F ((b), (c), (d)) + (x) + (UINT4)(ac); \ - (a) = ROTATE_LEFT ((a), (s)); \ - (a) += (b); \ - } -#define GG(a, b, c, d, x, s, ac) { \ - (a) += G ((b), (c), (d)) + (x) + (UINT4)(ac); \ - (a) = ROTATE_LEFT ((a), (s)); \ - (a) += (b); \ - } -#define HH(a, b, c, d, x, s, ac) { \ - (a) += H ((b), (c), (d)) + (x) + (UINT4)(ac); \ - (a) = ROTATE_LEFT ((a), (s)); \ - (a) += (b); \ - } -#define II(a, b, c, d, x, s, ac) { \ - (a) += I ((b), (c), (d)) + (x) + (UINT4)(ac); \ - (a) = ROTATE_LEFT ((a), (s)); \ - (a) += (b); \ - } - -/* MD5 initialization. Begins an MD5 operation, writing a new context. - */ -void my_MD5Init (my_MD5_CTX *context) /* context */ -{ - context->count[0] = context->count[1] = 0; - /* Load magic initialization constants. -*/ - context->state[0] = 0x67452301; - context->state[1] = 0xefcdab89; - context->state[2] = 0x98badcfe; - context->state[3] = 0x10325476; -} - -/* MD5 block update operation. Continues an MD5 message-digest - operation, processing another message block, and updating the - context. - */ - -void my_MD5Update ( -my_MD5_CTX *context, /* context */ -unsigned char *input, /* input block */ -unsigned int inputLen) /* length of input block */ -{ - unsigned int i, idx, partLen; - - /* Compute number of bytes mod 64 */ - idx = (unsigned int)((context->count[0] >> 3) & 0x3F); - - - /* Update number of bits */ - if ((context->count[0] += ((UINT4)inputLen << 3)) - < ((UINT4)inputLen << 3)) - context->count[1]++; - context->count[1] += ((UINT4)inputLen >> 29); - - partLen = 64 - idx; - - /* Transform as many times as possible. -*/ - if (inputLen >= partLen) { - MD5_memcpy((POINTER)&context->buffer[idx], (POINTER)input, partLen); - MD5Transform(context->state, context->buffer); - - for (i = partLen; i + 63 < inputLen; i += 64) - MD5Transform (context->state, &input[i]); - - idx = 0; - } - else - i = 0; - - /* Buffer remaining input */ - MD5_memcpy((POINTER)&context->buffer[idx], (POINTER)&input[i], - inputLen-i); -} - -/* MD5 finalization. Ends an MD5 message-digest operation, writing the - the message digest and zeroizing the context. - */ - -void my_MD5Final ( -unsigned char digest[16], /* message digest */ -my_MD5_CTX *context) /* context */ -{ - unsigned char bits[8]; - unsigned int idx, padLen; - - /* Save number of bits */ - Encode (bits, context->count, 8); - - /* Pad out to 56 mod 64. -*/ - idx = (unsigned int)((context->count[0] >> 3) & 0x3f); - padLen = (idx < 56) ? (56 - idx) : (120 - idx); - my_MD5Update (context, PADDING, padLen); - - /* Append length (before padding) */ - my_MD5Update (context, bits, 8); - - /* Store state in digest */ - Encode (digest, context->state, 16); - - /* Zeroize sensitive information. -*/ - MD5_memset ((POINTER)context, 0, sizeof (*context)); -} - -/* MD5 basic transformation. Transforms state based on block. - */ -static void MD5Transform ( -UINT4 state[4], -unsigned char block[64]) -{ - UINT4 a = state[0], b = state[1], c = state[2], d = state[3], x[16]; - - Decode (x, block, 64); - - /* Round 1 */ - FF (a, b, c, d, x[ 0], S11, 0xd76aa478); /* 1 */ - FF (d, a, b, c, x[ 1], S12, 0xe8c7b756); /* 2 */ - FF (c, d, a, b, x[ 2], S13, 0x242070db); /* 3 */ - FF (b, c, d, a, x[ 3], S14, 0xc1bdceee); /* 4 */ - FF (a, b, c, d, x[ 4], S11, 0xf57c0faf); /* 5 */ - FF (d, a, b, c, x[ 5], S12, 0x4787c62a); /* 6 */ - FF (c, d, a, b, x[ 6], S13, 0xa8304613); /* 7 */ - FF (b, c, d, a, x[ 7], S14, 0xfd469501); /* 8 */ - FF (a, b, c, d, x[ 8], S11, 0x698098d8); /* 9 */ - FF (d, a, b, c, x[ 9], S12, 0x8b44f7af); /* 10 */ - FF (c, d, a, b, x[10], S13, 0xffff5bb1); /* 11 */ - FF (b, c, d, a, x[11], S14, 0x895cd7be); /* 12 */ - FF (a, b, c, d, x[12], S11, 0x6b901122); /* 13 */ - FF (d, a, b, c, x[13], S12, 0xfd987193); /* 14 */ - FF (c, d, a, b, x[14], S13, 0xa679438e); /* 15 */ - FF (b, c, d, a, x[15], S14, 0x49b40821); /* 16 */ - - /* Round 2 */ - GG (a, b, c, d, x[ 1], S21, 0xf61e2562); /* 17 */ - GG (d, a, b, c, x[ 6], S22, 0xc040b340); /* 18 */ - GG (c, d, a, b, x[11], S23, 0x265e5a51); /* 19 */ - GG (b, c, d, a, x[ 0], S24, 0xe9b6c7aa); /* 20 */ - GG (a, b, c, d, x[ 5], S21, 0xd62f105d); /* 21 */ - GG (d, a, b, c, x[10], S22, 0x2441453); /* 22 */ - GG (c, d, a, b, x[15], S23, 0xd8a1e681); /* 23 */ - GG (b, c, d, a, x[ 4], S24, 0xe7d3fbc8); /* 24 */ - GG (a, b, c, d, x[ 9], S21, 0x21e1cde6); /* 25 */ - GG (d, a, b, c, x[14], S22, 0xc33707d6); /* 26 */ - GG (c, d, a, b, x[ 3], S23, 0xf4d50d87); /* 27 */ - GG (b, c, d, a, x[ 8], S24, 0x455a14ed); /* 28 */ - GG (a, b, c, d, x[13], S21, 0xa9e3e905); /* 29 */ - GG (d, a, b, c, x[ 2], S22, 0xfcefa3f8); /* 30 */ - GG (c, d, a, b, x[ 7], S23, 0x676f02d9); /* 31 */ - GG (b, c, d, a, x[12], S24, 0x8d2a4c8a); /* 32 */ - - /* Round 3 */ - HH (a, b, c, d, x[ 5], S31, 0xfffa3942); /* 33 */ - HH (d, a, b, c, x[ 8], S32, 0x8771f681); /* 34 */ - HH (c, d, a, b, x[11], S33, 0x6d9d6122); /* 35 */ - HH (b, c, d, a, x[14], S34, 0xfde5380c); /* 36 */ - HH (a, b, c, d, x[ 1], S31, 0xa4beea44); /* 37 */ - HH (d, a, b, c, x[ 4], S32, 0x4bdecfa9); /* 38 */ - HH (c, d, a, b, x[ 7], S33, 0xf6bb4b60); /* 39 */ - HH (b, c, d, a, x[10], S34, 0xbebfbc70); /* 40 */ - HH (a, b, c, d, x[13], S31, 0x289b7ec6); /* 41 */ - HH (d, a, b, c, x[ 0], S32, 0xeaa127fa); /* 42 */ - HH (c, d, a, b, x[ 3], S33, 0xd4ef3085); /* 43 */ - HH (b, c, d, a, x[ 6], S34, 0x4881d05); /* 44 */ - HH (a, b, c, d, x[ 9], S31, 0xd9d4d039); /* 45 */ - HH (d, a, b, c, x[12], S32, 0xe6db99e5); /* 46 */ - HH (c, d, a, b, x[15], S33, 0x1fa27cf8); /* 47 */ - HH (b, c, d, a, x[ 2], S34, 0xc4ac5665); /* 48 */ - - /* Round 4 */ - II (a, b, c, d, x[ 0], S41, 0xf4292244); /* 49 */ - II (d, a, b, c, x[ 7], S42, 0x432aff97); /* 50 */ - II (c, d, a, b, x[14], S43, 0xab9423a7); /* 51 */ - II (b, c, d, a, x[ 5], S44, 0xfc93a039); /* 52 */ - II (a, b, c, d, x[12], S41, 0x655b59c3); /* 53 */ - II (d, a, b, c, x[ 3], S42, 0x8f0ccc92); /* 54 */ - II (c, d, a, b, x[10], S43, 0xffeff47d); /* 55 */ - II (b, c, d, a, x[ 1], S44, 0x85845dd1); /* 56 */ - II (a, b, c, d, x[ 8], S41, 0x6fa87e4f); /* 57 */ - II (d, a, b, c, x[15], S42, 0xfe2ce6e0); /* 58 */ - II (c, d, a, b, x[ 6], S43, 0xa3014314); /* 59 */ - II (b, c, d, a, x[13], S44, 0x4e0811a1); /* 60 */ - II (a, b, c, d, x[ 4], S41, 0xf7537e82); /* 61 */ - II (d, a, b, c, x[11], S42, 0xbd3af235); /* 62 */ - II (c, d, a, b, x[ 2], S43, 0x2ad7d2bb); /* 63 */ - II (b, c, d, a, x[ 9], S44, 0xeb86d391); /* 64 */ - - - state[0] += a; - state[1] += b; - state[2] += c; - state[3] += d; - - /* Zeroize sensitive information. -*/ - MD5_memset ((POINTER)x, 0, sizeof (x)); -} - -/* Encodes input (UINT4) into output (unsigned char). Assumes len is - a multiple of 4. - */ -static void Encode ( -unsigned char *output, -UINT4 *input, -unsigned int len) -{ - unsigned int i, j; - - for (i = 0, j = 0; j < len; i++, j += 4) { - output[j] = (unsigned char)(input[i] & 0xff); - output[j+1] = (unsigned char)((input[i] >> 8) & 0xff); - output[j+2] = (unsigned char)((input[i] >> 16) & 0xff); - output[j+3] = (unsigned char)((input[i] >> 24) & 0xff); - } -} - - -/* Decodes input (unsigned char) into output (UINT4). Assumes len is - a multiple of 4. - */ -static void Decode ( -UINT4 *output, -unsigned char *input, -unsigned int len) -{ - unsigned int i, j; - - for (i = 0, j = 0; j < len; i++, j += 4) - output[i] = ((UINT4)input[j]) | (((UINT4)input[j+1]) << 8) | - (((UINT4)input[j+2]) << 16) | (((UINT4)input[j+3]) << 24); -} - -/* Note: Replace "for loop" with standard memcpy if possible. - */ - -#ifndef MD5_memcpy -static void MD5_memcpy (output, input, len) -POINTER output; -POINTER input; -unsigned int len; -{ - unsigned int i; - - for (i = 0; i < len; i++) - output[i] = input[i]; -} -#endif - -/* Note: Replace "for loop" with standard memset if possible. - */ - -#ifndef MD5_memset -static void MD5_memset (output, value, len) -POINTER output; -int value; -unsigned int len; -{ - unsigned int i; - - for (i = 0; i < len; i++) - ((char *)output)[i] = (char)value; -} -#endif diff --git a/sql/md5.h b/sql/md5.h deleted file mode 100644 index 6fe4e543bb0..00000000000 --- a/sql/md5.h +++ /dev/null @@ -1,78 +0,0 @@ - -/* MD5.H - header file for MD5C.C - */ - -/* Copyright (C) 1991-2, RSA Data Security, Inc. Created 1991. All -rights reserved. - -License to copy and use this software is granted provided that it -is identified as the "RSA Data Security, Inc. MD5 Message-Digest -Algorithm" in all material mentioning or referencing this software -or this function. - -License is also granted to make and use derivative works provided -that such works are identified as "derived from the RSA Data -Security, Inc. MD5 Message-Digest Algorithm" in all material -mentioning or referencing the derived work. - -RSA Data Security, Inc. makes no representations concerning either -the merchantability of this software or the suitability of this -software for any particular purpose. It is provided "as is" -without express or implied warranty of any kind. - -These notices must be retained in any copies of any part of this -documentation and/or software. - */ - -/* GLOBAL.H - RSAREF types and constants - */ - -/* PROTOTYPES should be set to one if and only if the compiler supports - function argument prototyping. -The following makes PROTOTYPES default to 0 if it has not already - been defined with C compiler flags. - */ - -/* egcs 1.1.2 under linux didn't defined it.... :( */ - -#ifndef PROTOTYPES -#define PROTOTYPES 1 /* Assume prototypes */ -#endif - -/* POINTER defines a generic pointer type */ -typedef unsigned char *POINTER; - -/* UINT2 defines a two byte word */ -typedef uint16 UINT2; /* Fix for MySQL / Alpha */ - -/* UINT4 defines a four byte word */ -typedef uint32 UINT4; /* Fix for MySQL / Alpha */ - -/* PROTO_LIST is defined depending on how PROTOTYPES is defined above. -If using PROTOTYPES, then PROTO_LIST returns the list, otherwise it - returns an empty list. - */ -#if PROTOTYPES -#define PROTO_LIST(list) list -#else -#define PROTO_LIST(list) () -#endif -/* MD5 context. */ -typedef struct { - UINT4 state[4]; /* state (ABCD) */ - UINT4 count[2]; /* number of bits, modulo 2^64 (lsb first) */ - unsigned char buffer[64]; /* input buffer */ -} my_MD5_CTX; - -#ifdef __cplusplus -extern "C" { -#endif - void my_MD5Init PROTO_LIST ((my_MD5_CTX *)); - void my_MD5Update PROTO_LIST - ((my_MD5_CTX *, unsigned char *, unsigned int)); - void my_MD5Final PROTO_LIST ((unsigned char [16], my_MD5_CTX *)); - -#ifdef __cplusplus -} -#endif - diff --git a/sql/mf_iocache.cc b/sql/mf_iocache.cc index 24af439961e..40b98983291 100644 --- a/sql/mf_iocache.cc +++ b/sql/mf_iocache.cc @@ -81,7 +81,7 @@ int init_io_cache(IO_CACHE *info, File file, uint cachesize, if ((my_off_t) cachesize > end_of_file-seek_offset+IO_SIZE*2-1) { cachesize=(uint) (end_of_file-seek_offset)+IO_SIZE*2-1; - use_async_io=0; /* No nead to use async */ + use_async_io=0; /* No need to use async */ } } } diff --git a/sql/mini_client.cc b/sql/mini_client.cc index 1afe4c97b8e..266a292fe1d 100644 --- a/sql/mini_client.cc +++ b/sql/mini_client.cc @@ -22,7 +22,6 @@ in case we decide to make them external at some point */ -#define DONT_USE_RAID #if defined(__WIN__) #include <winsock.h> #include <odbcinst.h> @@ -41,6 +40,7 @@ inline int local_thr_alarm(my_bool *A,int B __attribute__((unused)),ALARM *C __a #endif #include <my_global.h> +#include <mysql_embed.h> #include <mysql_com.h> #include <violite.h> #include <my_sys.h> @@ -803,7 +803,7 @@ mc_mysql_connect(MYSQL *mysql,const char *host, const char *user, /* Do the SSL layering. */ DBUG_PRINT("info", ("IO layer change in progress...")); DBUG_PRINT("info", ("IO context %p",((struct st_VioSSLConnectorFd*)mysql->connector_fd)->ssl_context_)); - sslconnect((struct st_VioSSLConnectorFd*)(mysql->connector_fd),mysql->net.vio); + sslconnect((struct st_VioSSLConnectorFd*)(mysql->connector_fd),mysql->net.vio,60L); DBUG_PRINT("info", ("IO layer change done!")); } #endif /* HAVE_OPENSSL */ diff --git a/sql/mysql_priv.h b/sql/mysql_priv.h index 7151f43904f..bd7c2f3cfd1 100644 --- a/sql/mysql_priv.h +++ b/sql/mysql_priv.h @@ -18,9 +18,10 @@ #define _MYSQL_PRIV_H #include <my_global.h> +#include "mysql_embed.h" #include <my_sys.h> #include <m_string.h> -#include "mysql_version.h" +#include <mysql_version.h> #include <hash.h> #include <signal.h> #include <thr_lock.h> @@ -70,7 +71,6 @@ char* query_table_status(THD *thd,const char *db,const char *table_name); #define HASH_PASSWORD_LENGTH 16 #define HOST_CACHE_SIZE 128 #define MAX_ACCEPT_RETRY 10 // Test accept this many times -#define MAX_BLOB_WIDTH 8192 // Default width for blob #define MAX_FIELDS_BEFORE_HASH 32 #define USER_VARS_HASH_SIZE 16 #define STACK_MIN_SIZE 8192 // Abort if less stack during eval. @@ -189,6 +189,19 @@ char* query_table_status(THD *thd,const char *db,const char *table_name); #define RAID_BLOCK_SIZE 1024 +// Sync points allow us to force the server to reach a certain line of code +// and block there until the client tells the server it is ok to go on. +// The client tells the server to block with SELECT GET_LOCK() +// and unblocks it with SELECT RELEASE_LOCK(). Used for debugging difficult +// concurrency problems +#ifdef EXTRA_DEBUG +#define DBUG_SYNC_POINT(lock_name,lock_timeout) \ + debug_sync_point(lock_name,lock_timeout) +void debug_sync_point(const char* lock_name, uint lock_timeout); +#else +#define DBUG_SYNC_POINT(lock_name,lock_timeout) +#endif + /* BINLOG_DUMP options */ #define BINLOG_DUMP_NON_BLOCK 1 @@ -504,11 +517,13 @@ void init_errmessage(void); void sql_perror(const char *message); void sql_print_error(const char *format,...) __attribute__ ((format (printf, 1, 2))); +bool fn_format_relative_to_data_home(my_string to, const char *name, + const char *dir, const char *extension); extern uint32 server_id; -extern char mysql_data_home[2],server_version[SERVER_VERSION_LENGTH], +extern char *mysql_data_home,server_version[SERVER_VERSION_LENGTH], max_sort_char, mysql_real_data_home[]; -extern my_string mysql_unix_port,mysql_tmpdir; +extern my_string mysql_tmpdir; extern const char *first_keyword, *localhost, *delayed_user; extern ulong refresh_version,flush_version, thread_id,query_id,opened_tables, created_tmp_tables, created_tmp_disk_tables, @@ -522,7 +537,7 @@ extern ulong filesort_merge_passes; extern ulong select_range_check_count, select_range_count, select_scan_count; extern ulong select_full_range_join_count,select_full_join_count, slave_open_temp_tables; -extern uint test_flags,select_errors,mysql_port,ha_open_options; +extern uint test_flags,select_errors,ha_open_options; extern ulong thd_startup_options, slow_launch_threads, slow_launch_time; extern time_t start_time; extern const char *command_name[]; @@ -540,7 +555,7 @@ extern pthread_cond_t COND_refresh,COND_thread_count, COND_binlog_update, COND_slave_stopped, COND_slave_start; extern pthread_attr_t connection_attrib; extern bool opt_endinfo, using_udf_functions, locked_in_memory, - opt_using_transactions, use_temp_pool; + opt_using_transactions, use_temp_pool, mysql_embedded; extern char f_fyllchar; extern ulong ha_read_count, ha_write_count, ha_delete_count, ha_update_count, ha_read_key_count, ha_read_next_count, ha_read_prev_count, diff --git a/sql/mysqld.cc b/sql/mysqld.cc index 87d42da976b..7b0c97c4b79 100644 --- a/sql/mysqld.cc +++ b/sql/mysqld.cc @@ -193,7 +193,7 @@ SHOW_COMP_OPTION have_innodb=SHOW_OPTION_YES; #else SHOW_COMP_OPTION have_innodb=SHOW_OPTION_NO; #endif -#ifndef NO_ISAM +#ifdef HAVE_ISAM SHOW_COMP_OPTION have_isam=SHOW_OPTION_YES; #else SHOW_COMP_OPTION have_isam=SHOW_OPTION_NO; @@ -214,8 +214,9 @@ SHOW_COMP_OPTION have_symlink=SHOW_OPTION_YES; static bool opt_skip_slave_start = 0; // if set, slave is not autostarted static bool opt_do_pstack = 0; static ulong opt_specialflag=SPECIAL_ENGLISH; -static my_socket unix_sock= INVALID_SOCKET,ip_sock= INVALID_SOCKET; static ulong back_log,connect_timeout,concurrency; +static ulong opt_myisam_block_size; +static my_socket unix_sock= INVALID_SOCKET,ip_sock= INVALID_SOCKET; static my_string opt_logname=0,opt_update_logname=0, opt_binlog_index_name = 0,opt_slow_logname=0; static char mysql_home[FN_REFLEN],pidfile_name[FN_REFLEN]; @@ -242,16 +243,11 @@ static char **defaults_argv,time_zone[30]; static const char *default_table_type_name; static char glob_hostname[FN_REFLEN]; +#include "sslopt-vars.h" #ifdef HAVE_OPENSSL -static bool opt_use_ssl = FALSE; -static char *opt_ssl_key = 0; -static char *opt_ssl_cert = 0; -static char *opt_ssl_ca = 0; -static char *opt_ssl_capath = 0; struct st_VioSSLAcceptorFd * ssl_acceptor_fd = 0; #endif /* HAVE_OPENSSL */ - I_List <i_string_pair> replicate_rewrite_db; I_List<i_string> replicate_do_db, replicate_ignore_db; // allow the user to tell us which db to replicate and which to ignore @@ -290,7 +286,7 @@ uint master_port = MYSQL_PORT, master_connect_retry = 60; uint report_port = MYSQL_PORT; bool master_ssl = 0; -ulong max_tmp_tables,max_heap_table_size; +ulong max_tmp_tables,max_heap_table_size,master_retry_count=0; ulong bytes_sent = 0L, bytes_received = 0L; bool opt_endinfo,using_udf_functions,low_priority_updates, locked_in_memory; @@ -315,10 +311,18 @@ ulong slow_launch_threads = 0; ulong myisam_max_sort_file_size, myisam_max_extra_sort_file_size; char mysql_real_data_home[FN_REFLEN], - mysql_data_home[2],language[LIBLEN],reg_ext[FN_EXTLEN], + language[LIBLEN],reg_ext[FN_EXTLEN], default_charset[LIBLEN],mysql_charsets_dir[FN_REFLEN], *charsets_list, blob_newline,f_fyllchar,max_sort_char,*mysqld_user,*mysqld_chroot, *opt_init_file; +#ifndef EMBEDDED_LIBRARY +char mysql_data_home_buff[2], *mysql_data_home=mysql_data_home_buff; +bool mysql_embedded=0; +#else +char *mysql_data_home=mysql_real_data_home; +bool mysql_embedded=1; +#endif + char *opt_bin_logname = 0; // this one needs to be seen in sql_parse.cc char server_version[SERVER_VERSION_LENGTH]=MYSQL_SERVER_VERSION; const char *first_keyword="first"; @@ -328,10 +332,12 @@ const char *sql_mode_str="OFF"; const char *default_tx_isolation_name; enum_tx_isolation default_tx_isolation=ISO_READ_COMMITTED; +uint rpl_recovery_rank=0; + #ifdef HAVE_GEMINI_DB const char *gemini_recovery_options_str="FULL"; #endif -my_string mysql_unix_port=NULL,mysql_tmpdir=NULL; +my_string mysql_unix_port=NULL, mysql_tmpdir=NULL, allocated_mysql_tmpdir=NULL; ulong my_bind_addr; /* the address we bind to */ DATE_FORMAT dayord; double log_10[32]; /* 10 potences */ @@ -342,7 +348,7 @@ ulong opt_sql_mode = 0L; const char *sql_mode_names[] = { "REAL_AS_FLOAT", "PIPES_AS_CONCAT", "ANSI_QUOTES", "IGNORE_SPACE", "SERIALIZE","ONLY_FULL_GROUP_BY", NullS }; -TYPELIB sql_mode_typelib= {array_elements(sql_mode_names),"", +TYPELIB sql_mode_typelib= {array_elements(sql_mode_names)-1,"", sql_mode_names}; MY_BITMAP temp_pool; @@ -682,11 +688,8 @@ static sig_handler print_signal_warning(int sig) void unireg_end(int signal_number __attribute__((unused))) { clean_up(); -#if defined(EMBEDDED_LIBRARY) - exit(0); // XXX QQ: this is a temporary hack (I hope) -#else + my_thread_end(); pthread_exit(0); // Exit is in main thread -#endif } @@ -695,6 +698,7 @@ void unireg_abort(int exit_code) if (exit_code) sql_print_error("Aborting\n"); clean_up(); /* purecov: inspected */ + my_thread_end(); exit(exit_code); /* purecov: inspected */ } @@ -725,25 +729,25 @@ void clean_up(bool print_message) my_free(opt_ssl_cert,MYF(MY_ALLOW_ZERO_PTR)); my_free(opt_ssl_ca,MYF(MY_ALLOW_ZERO_PTR)); my_free(opt_ssl_capath,MYF(MY_ALLOW_ZERO_PTR)); + my_free(opt_ssl_cipher,MYF(MY_ALLOW_ZERO_PTR)); opt_ssl_key=opt_ssl_cert=opt_ssl_ca=opt_ssl_capath=0; #endif /* HAVE_OPENSSL */ free_defaults(defaults_argv); my_free(charsets_list, MYF(MY_ALLOW_ZERO_PTR)); - my_free(mysql_tmpdir,MYF(0)); - my_free(slave_load_tmpdir,MYF(0)); + my_free(allocated_mysql_tmpdir,MYF(MY_ALLOW_ZERO_PTR)); + my_free(slave_load_tmpdir,MYF(MY_ALLOW_ZERO_PTR)); x_free(opt_bin_logname); bitmap_free(&temp_pool); free_max_user_conn(); end_slave_list(); -#ifndef __WIN__ +#if !defined(__WIN__) && !defined(EMBEDDED_LIBRARY) if (!opt_bootstrap) (void) my_delete(pidfile_name,MYF(0)); // This may not always exist #endif - if (print_message) + if (print_message && errmesg) sql_print_error(ER(ER_SHUTDOWN_COMPLETE),my_progname); x_free((gptr) my_errmsg[ERRMAPP]); /* Free messages */ - my_thread_end(); /* Tell main we are ready */ (void) pthread_mutex_lock(&LOCK_thread_count); @@ -1202,13 +1206,13 @@ static sig_handler handle_segfault(int sig) fprintf(stderr,"\ mysqld got signal %d;\n\ This could be because you hit a bug. It is also possible that this binary\n\ -or one of the libraries it was linked agaist is corrupt, improperly built,\n\ +or one of the libraries it was linked against is corrupt, improperly built,\n\ or misconfigured. This error can also be caused by malfunctioning hardware.\n", sig); fprintf(stderr, "\ We will try our best to scrape up some info that will hopefully help diagnose\n\ the problem, but since we have already crashed, something is definitely wrong\n\ -and this may fail\n\n"); +and this may fail.\n\n"); fprintf(stderr, "key_buffer_size=%ld\n", keybuff_size); fprintf(stderr, "record_buffer=%ld\n", my_default_record_cache_size); fprintf(stderr, "sort_buffer=%ld\n", sortbuff_size); @@ -1219,15 +1223,15 @@ and this may fail\n\n"); key_buffer_size + (record_buffer + sort_buffer)*max_connections = %ld K\n\ bytes of memory\n", (keybuff_size + (my_default_record_cache_size + sortbuff_size) * max_connections)/ 1024); - fprintf(stderr, "Hope that's ok, if not, decrease some variables in the equation\n\n"); + fprintf(stderr, "Hope that's ok; if not, decrease some variables in the equation.\n\n"); #if defined(HAVE_LINUXTHREADS) if (sizeof(char*) == 4 && thread_count > UNSAFE_DEFAULT_LINUX_THREADS) { fprintf(stderr, "\ You seem to be running 32-bit Linux and have %d concurrent connections.\n\ -If you have not changed STACK_SIZE in LinuxThreads and build the binary \n\ -yourself, LinuxThreads is quite likely to steal a part of global heap for\n\ +If you have not changed STACK_SIZE in LinuxThreads and built the binary \n\ +yourself, LinuxThreads is quite likely to steal a part of the global heap for\n\ the thread stack. Please read http://www.mysql.com/doc/L/i/Linux.html\n\n", thread_count); } @@ -1251,12 +1255,12 @@ Some pointers may be invalid and cause the dump to abort...\n"); fprintf(stderr, "\n Successfully dumped variables, if you ran with --log, take a look at the\n\ details of what thread %ld did to cause the crash. In some cases of really\n\ -bad corruption, the values shown above may be invalid\n\n", +bad corruption, the values shown above may be invalid.\n\n", thd->thread_id); } fprintf(stderr, "\ The manual page at http://www.mysql.com/doc/C/r/Crashing.html contains\n\ -information that should help you find out what is causing the crash\n"); +information that should help you find out what is causing the crash.\n"); fflush(stderr); #endif /* HAVE_STACKTRACE */ @@ -1712,7 +1716,7 @@ int main(int argc, char **argv) if (opt_use_ssl) { ssl_acceptor_fd = new_VioSSLAcceptorFd(opt_ssl_key, opt_ssl_cert, - opt_ssl_ca, opt_ssl_capath); + opt_ssl_ca, opt_ssl_capath, opt_ssl_cipher); DBUG_PRINT("info",("ssl_acceptor_fd: %p",ssl_acceptor_fd)); if (!ssl_acceptor_fd) opt_use_ssl=0; @@ -1738,7 +1742,7 @@ int main(int argc, char **argv) pthread_attr_setscope(&connection_attrib, PTHREAD_SCOPE_SYSTEM); #if defined( SET_RLIMIT_NOFILE) || defined( OS2) - /* connections and databases neads lots of files */ + /* connections and databases needs lots of files */ { uint wanted_files=10+(uint) max(max_connections*5, max_connections+table_cache_size*2); @@ -1788,10 +1792,6 @@ int main(int argc, char **argv) init_thr_lock(); init_slave_list(); - /* Fix varibles that are base 1024*1024 */ - myisam_max_temp_length= (my_off_t) min(((ulonglong) myisam_max_sort_file_size)*1024*1024, (ulonglong) MAX_FILE_SIZE); - myisam_max_extra_temp_length= (my_off_t) min(((ulonglong) myisam_max_extra_sort_file_size)*1024*1024, (ulonglong) MAX_FILE_SIZE); - /* Setup log files */ if (opt_log) open_log(&mysql_log, glob_hostname, opt_logname, ".log", LOG_NORMAL); @@ -1802,17 +1802,18 @@ int main(int argc, char **argv) using_update_log=1; } - //make sure slave thread gets started - // if server_id is set, valid master.info is present, and master_host has - // not been specified - if(server_id && !master_host) - { - char fname[FN_REFLEN+128]; - MY_STAT stat_area; - fn_format(fname, master_info_file, mysql_data_home, "", 4+16+32); - if(my_stat(fname, &stat_area, MYF(0)) && !init_master_info(&glob_mi)) - master_host = glob_mi.host; - } + /* + make sure slave thread gets started if server_id is set, + valid master.info is present, and master_host has not been specified + */ + if (server_id && !master_host) + { + char fname[FN_REFLEN+128]; + MY_STAT stat_area; + fn_format(fname, master_info_file, mysql_data_home, "", 4+16+32); + if (my_stat(fname, &stat_area, MYF(0)) && !init_master_info(&glob_mi)) + master_host = glob_mi.host; + } if (opt_bin_log && !server_id) { @@ -1906,7 +1907,7 @@ The server will not act as a slave."); (void) pthread_kill(signal_thread,MYSQL_KILL_SIGNAL); #ifndef __WIN__ if (!opt_bootstrap) - (void) my_delete(pidfile_name,MYF(MY_WME)); // Not neaded anymore + (void) my_delete(pidfile_name,MYF(MY_WME)); // Not needed anymore #endif exit(1); } @@ -2046,7 +2047,7 @@ The server will not act as a slave."); { if(start_mode) { - if (WaitForSingleObject(hEventShutdown,INFINITE)==WAIT_OBJECT_0) + if (WaitForSingleObject(hEventShutdown,1000)==WAIT_TIMEOUT) Service.Stop(); } else @@ -2062,7 +2063,7 @@ The server will not act as a slave."); } #endif #ifdef HAVE_OPENSSL - my_free((gptr)ssl_acceptor_fd,MYF(0)); + my_free((gptr)ssl_acceptor_fd,MYF(MY_ALLOW_ZERO_PTR)); #endif /* HAVE_OPENSSL */ /* Wait until cleanup is done */ (void) pthread_mutex_lock(&LOCK_thread_count); @@ -2576,10 +2577,9 @@ enum options { OPT_MASTER_HOST, OPT_MASTER_USER, OPT_MASTER_PASSWORD, OPT_MASTER_PORT, OPT_MASTER_INFO_FILE, OPT_MASTER_CONNECT_RETRY, -#ifdef HAVE_OPENSSL + OPT_MASTER_RETRY_COUNT, OPT_MASTER_SSL, OPT_MASTER_SSL_KEY, OPT_MASTER_SSL_CERT, -#endif /* HAVE_OPESSSL*/ OPT_SQL_BIN_UPDATE_SAME, OPT_REPLICATE_DO_DB, OPT_REPLICATE_IGNORE_DB, OPT_LOG_SLAVE_UPDATES, OPT_BINLOG_DO_DB, OPT_BINLOG_IGNORE_DB, @@ -2610,7 +2610,8 @@ enum options { OPT_DO_PSTACK, OPT_REPORT_HOST, OPT_REPORT_USER, OPT_REPORT_PASSWORD, OPT_REPORT_PORT, OPT_SHOW_SLAVE_AUTH_INFO, OPT_OLD_RPL_COMPAT, - OPT_SLAVE_LOAD_TMPDIR, OPT_NO_MIX_TYPE + OPT_SLAVE_LOAD_TMPDIR, OPT_NO_MIX_TYPE, + OPT_RPL_RECOVERY_RANK }; static struct option long_options[] = { @@ -2642,9 +2643,8 @@ static struct option long_options[] = { {"default-table-type", required_argument, 0, (int) OPT_TABLE_TYPE}, {"delay-key-write-for-all-tables", no_argument, 0, (int) OPT_DELAY_KEY_WRITE}, - {"do-pstack", - no_argument, 0, (int) OPT_DO_PSTACK}, {"enable-locking", no_argument, 0, (int) OPT_ENABLE_LOCK}, + {"enable-pstack", no_argument, 0, (int) OPT_DO_PSTACK}, {"exit-info", optional_argument, 0, 'T'}, {"flush", no_argument, 0, (int) OPT_FLUSH}, #ifdef HAVE_GEMINI_DB @@ -2687,12 +2687,11 @@ static struct option long_options[] = { {"master-password", required_argument, 0, (int) OPT_MASTER_PASSWORD}, {"master-port", required_argument, 0, (int) OPT_MASTER_PORT}, {"master-connect-retry", required_argument, 0, (int) OPT_MASTER_CONNECT_RETRY}, + {"master-retry-count", required_argument, 0, (int) OPT_MASTER_RETRY_COUNT}, {"master-info-file", required_argument, 0, (int) OPT_MASTER_INFO_FILE}, -#ifdef HAVE_OPENSSL {"master-ssl", optional_argument, 0, (int) OPT_MASTER_SSL}, {"master-ssl-key", optional_argument, 0, (int) OPT_MASTER_SSL_KEY}, {"master-ssl-cert", optional_argument, 0, (int) OPT_MASTER_SSL_CERT}, -#endif {"myisam-recover", optional_argument, 0, (int) OPT_MYISAM_RECOVER}, {"memlock", no_argument, 0, (int) OPT_MEMLOCK}, // needs to be available for the test case to pass in non-debugging mode @@ -2737,6 +2736,7 @@ static struct option long_options[] = { {"report-user", required_argument, 0, (int) OPT_REPORT_USER}, {"report-password", required_argument, 0, (int) OPT_REPORT_PASSWORD}, {"report-port", required_argument, 0, (int) OPT_REPORT_PORT}, + {"rpl-recovery-rank", required_argument, 0, (int) OPT_RPL_RECOVERY_RANK}, {"safe-mode", no_argument, 0, (int) OPT_SAFE}, {"safe-show-database", no_argument, 0, (int) OPT_SAFE_SHOW_DB}, {"safe-user-create", no_argument, 0, (int) OPT_SAFE_USER_CREATE}, @@ -2889,6 +2889,9 @@ CHANGEABLE_VAR changeable_vars[] = { ~0L, 1, ~0L, 0, 1 }, { "myisam_bulk_insert_tree_size", (long*) &myisam_bulk_insert_tree_size, 8192*1024, 4, ~0L, 0, 1 }, + { "myisam_block_size", (long*) &opt_myisam_block_size, + MI_KEY_BLOCK_LENGTH, MI_MIN_KEY_BLOCK_LENGTH, MI_MAX_KEY_BLOCK_LENGTH, + 0, MI_MIN_KEY_BLOCK_LENGTH }, { "myisam_max_extra_sort_file_size", (long*) &myisam_max_extra_sort_file_size, (long) (MI_MAX_TEMP_LENGTH/(1024L*1024L)), 0, ~0L, 0, 1 }, @@ -3033,6 +3036,7 @@ struct show_var_st init_vars[]= { {"protocol_version", (char*) &protocol_version, SHOW_INT}, {"record_buffer", (char*) &my_default_record_cache_size,SHOW_LONG}, {"record_rnd_buffer", (char*) &record_rnd_cache_size, SHOW_LONG}, + {"rpl_recovery_rank", (char*) &rpl_recovery_rank, SHOW_LONG}, {"query_buffer_size", (char*) &query_buff_size, SHOW_LONG}, {"safe_show_database", (char*) &opt_safe_show_db, SHOW_BOOL}, {"server_id", (char*) &server_id, SHOW_LONG}, @@ -3111,21 +3115,29 @@ struct show_var_st status_vars[]= { {"Sort_rows", (char*) &filesort_rows, SHOW_LONG}, {"Sort_scan", (char*) &filesort_scan_count, SHOW_LONG}, #ifdef HAVE_OPENSSL - {"SSL_CTX_sess_accept", (char*) 0, SHOW_SSL_CTX_SESS_ACCEPT}, - {"SSL_CTX_sess_accept_good", (char*) 0, SHOW_SSL_CTX_SESS_ACCEPT_GOOD}, - {"SSL_CTX_sess_accept_renegotiate", (char*) 0, SHOW_SSL_CTX_SESS_ACCEPT_RENEGOTIATE}, - {"SSL_CTX_sess_cb_hits", (char*) 0, SHOW_SSL_CTX_SESS_CB_HITS}, - {"SSL_CTX_sess_number", (char*) 0, SHOW_SSL_CTX_SESS_NUMBER}, - {"SSL_CTX_get_session_cache_mode", (char*) 0, SHOW_SSL_CTX_GET_SESSION_CACHE_MODE}, - {"SSL_CTX_sess_get_cache_size", (char*) 0, SHOW_SSL_CTX_SESS_GET_CACHE_SIZE}, - {"SSL_CTX_get_verify_mode", (char*) 0, SHOW_SSL_CTX_GET_VERIFY_MODE}, - {"SSL_CTX_get_verify_depth", (char*) 0, SHOW_SSL_CTX_GET_VERIFY_DEPTH}, - {"SSL_get_verify_mode", (char*) 0, SHOW_SSL_GET_VERIFY_MODE}, - {"SSL_get_verify_depth", (char*) 0, SHOW_SSL_GET_VERIFY_DEPTH}, - {"SSL_session_reused", (char*) 0, SHOW_SSL_SESSION_REUSED}, - {"SSL_get_version", (char*) 0, SHOW_SSL_GET_VERSION}, - {"SSL_get_cipher", (char*) 0, SHOW_SSL_GET_CIPHER}, - {"SSL_get_default_timeout", (char*) 0, SHOW_SSL_GET_DEFAULT_TIMEOUT}, + {"ssl_accepts", (char*) 0, SHOW_SSL_CTX_SESS_ACCEPT}, + {"ssl_finished_accepts", (char*) 0, SHOW_SSL_CTX_SESS_ACCEPT_GOOD}, + {"ssl_finished_connects", (char*) 0, SHOW_SSL_CTX_SESS_CONNECT_GOOD}, + {"ssl_accept_renegotiates", (char*) 0, SHOW_SSL_CTX_SESS_ACCEPT_RENEGOTIATE}, + {"ssl_connect_renegotiates", (char*) 0, SHOW_SSL_CTX_SESS_CONNECT_RENEGOTIATE}, + {"ssl_callback_cache_hits", (char*) 0, SHOW_SSL_CTX_SESS_CB_HITS}, + {"ssl_session_cache_hits", (char*) 0, SHOW_SSL_CTX_SESS_HITS}, + {"ssl_session_cache_misses", (char*) 0, SHOW_SSL_CTX_SESS_MISSES}, + {"ssl_session_cache_timeouts", (char*) 0, SHOW_SSL_CTX_SESS_TIMEOUTS}, + {"ssl_used_session_cache_entries",(char*) 0, SHOW_SSL_CTX_SESS_NUMBER}, + {"ssl_client_connects", (char*) 0, SHOW_SSL_CTX_SESS_CONNECT}, + {"ssl_session_cache_overflows", (char*) 0, SHOW_SSL_CTX_SESS_CACHE_FULL}, + {"ssl_session_cache_size", (char*) 0, SHOW_SSL_CTX_SESS_GET_CACHE_SIZE}, + {"ssl_session_cache_mode", (char*) 0, SHOW_SSL_CTX_GET_SESSION_CACHE_MODE}, + {"ssl_sessions_reused", (char*) 0, SHOW_SSL_SESSION_REUSED}, + {"ssl_ctx_verify_mode", (char*) 0, SHOW_SSL_CTX_GET_VERIFY_MODE}, + {"ssl_ctx_verify_depth", (char*) 0, SHOW_SSL_CTX_GET_VERIFY_DEPTH}, + {"ssl_verify_mode", (char*) 0, SHOW_SSL_GET_VERIFY_MODE}, + {"ssl_verify_depth", (char*) 0, SHOW_SSL_GET_VERIFY_DEPTH}, + {"ssl_version", (char*) 0, SHOW_SSL_GET_VERSION}, + {"ssl_cipher", (char*) 0, SHOW_SSL_GET_CIPHER}, + {"ssl_cipher_list", (char*) 0, SHOW_SSL_GET_CIPHER_LIST}, + {"ssl_default_timeout", (char*) 0, SHOW_SSL_GET_DEFAULT_TIMEOUT}, #endif /* HAVE_OPENSSL */ {"Table_locks_immediate", (char*) &locks_immediate, SHOW_LONG}, {"Table_locks_waited", (char*) &locks_waited, SHOW_LONG}, @@ -3188,6 +3200,7 @@ static void usage(void) Don't flush key buffers between writes for any MyISAM\n\ table\n\ --enable-locking Enable system locking\n\ + --enable-pstack Print a symbolic stack trace on failure\n\ -T, --exit-info Used for debugging; Use at your own risk!\n\ --flush Flush tables to disk between SQL commands\n\ -?, --help Display this help and exit\n\ @@ -3444,6 +3457,9 @@ static void get_options(int argc,char **argv) safemalloc_mem_limit = atoi(optarg); #endif break; + case OPT_RPL_RECOVERY_RANK: + rpl_recovery_rank=atoi(optarg); + break; case OPT_SLAVE_LOAD_TMPDIR: slave_load_tmpdir = my_strdup(optarg, MYF(MY_FAE)); break; @@ -3682,7 +3698,7 @@ static void get_options(int argc,char **argv) opt_specialflag|= SPECIAL_NO_HOST_CACHE; break; case (int) OPT_ENABLE_LOCK: - my_disable_locking=0; + my_disable_locking=myisam_single_user=0; break; case (int) OPT_USE_LOCKING: my_disable_locking=0; @@ -3764,7 +3780,10 @@ static void get_options(int argc,char **argv) break; #endif case (int) OPT_FLUSH: - nisam_flush=myisam_flush=1; +#ifdef HAVE_ISAM + nisam_flush=1; +#endif + myisam_flush=1; flush_time=0; // No auto flush break; case OPT_LOW_PRIORITY_UPDATES: @@ -3964,7 +3983,6 @@ static void get_options(int argc,char **argv) case OPT_MASTER_PORT: master_port= atoi(optarg); break; -#ifdef HAVE_OPENSSL case OPT_MASTER_SSL: master_ssl=atoi(optarg); break; @@ -3974,7 +3992,6 @@ static void get_options(int argc,char **argv) case OPT_MASTER_SSL_CERT: master_ssl_cert=optarg; break; -#endif /* HAVE_OPENSSL */ case OPT_REPORT_HOST: report_host=optarg; break; @@ -3990,6 +4007,9 @@ static void get_options(int argc,char **argv) case OPT_MASTER_CONNECT_RETRY: master_connect_retry= atoi(optarg); break; + case OPT_MASTER_RETRY_COUNT: + master_retry_count= atoi(optarg); + break; case OPT_SAFE_SHOW_DB: opt_safe_show_db=1; break; @@ -4023,6 +4043,12 @@ static void get_options(int argc,char **argv) /* To be deleted in MySQL 4.0 */ if (!record_rnd_cache_size) record_rnd_cache_size=my_default_record_cache_size; + + /* Fix variables that are base 1024*1024 */ + myisam_max_temp_length= (my_off_t) min(((ulonglong) myisam_max_sort_file_size)*1024*1024, (ulonglong) MAX_FILE_SIZE); + myisam_max_extra_temp_length= (my_off_t) min(((ulonglong) myisam_max_extra_sort_file_size)*1024*1024, (ulonglong) MAX_FILE_SIZE); + + myisam_block_size=(uint) 1 << my_bit_log2(opt_myisam_block_size); } @@ -4282,7 +4308,10 @@ static int get_service_parameters() else if ( lstrcmp(szKeyValueName, TEXT("FlushTables")) == 0 ) { CHECK_KEY_TYPE( REG_DWORD, szKeyValueName ); - nisam_flush = myisam_flush= *lpdwValue ? 1 : 0; +#ifdef HAVE_NISAM + nisam_flush = 1; +#endif + myisam_flush= *lpdwValue ? 1 : 0; } else if ( lstrcmp(szKeyValueName, TEXT("BackLog")) == 0 ) { @@ -4516,12 +4545,34 @@ static char *get_relative_path(const char *path) } +/* + Fix filename and replace extension where 'dir' is relative to + mysql_real_data_home. + Return 1 if len(path) > FN_REFLEN +*/ + +bool +fn_format_relative_to_data_home(my_string to, const char *name, + const char *dir, const char *extension) +{ + char tmp_path[FN_REFLEN]; + if (!test_if_hard_path(dir)) + { + strxnmov(tmp_path,sizeof(tmp_path)-1, mysql_real_data_home, + dir, NullS); + dir=tmp_path; + } + return !fn_format(to, name, dir, extension, + MY_REPLACE_EXT | MY_UNPACK_FILENAME | MY_SAFE_PATH); +} + + static void fix_paths(void) { (void) fn_format(mysql_home,mysql_home,"","",16); // Remove symlinks - convert_dirname(mysql_home); - convert_dirname(mysql_real_data_home); - convert_dirname(language); + convert_dirname(mysql_home,mysql_home,NullS); + convert_dirname(mysql_real_data_home,mysql_real_data_home,NullS); + convert_dirname(language,language,NullS); (void) my_load_path(mysql_home,mysql_home,""); // Resolve current dir (void) my_load_path(mysql_real_data_home,mysql_real_data_home,mysql_home); (void) my_load_path(pidfile_name,pidfile_name,mysql_real_data_home); @@ -4531,7 +4582,7 @@ static void fix_paths(void) strmov(buff,sharedir); /* purecov: tested */ else strxmov(buff,mysql_home,sharedir,NullS); - convert_dirname(buff); + convert_dirname(buff,buff,NullS); (void) my_load_path(language,language,buff); /* If --character-sets-dir isn't given, use shared library dir */ @@ -4545,19 +4596,16 @@ static void fix_paths(void) char *tmp= (char*) my_malloc(FN_REFLEN,MYF(MY_FAE)); if (tmp) { - strmov(tmp,mysql_tmpdir); - mysql_tmpdir=tmp; - convert_dirname(mysql_tmpdir); - mysql_tmpdir=(char*) my_realloc(mysql_tmpdir,(uint) strlen(mysql_tmpdir)+1, + char *end=convert_dirname(tmp, mysql_tmpdir, NullS); + + mysql_tmpdir=(char*) my_realloc(tmp,(uint) (end-tmp)+1, MYF(MY_HOLD_ON_ERROR)); + allocated_mysql_tmpdir=mysql_tmpdir; } if (!slave_load_tmpdir) { - int copy_len; - slave_load_tmpdir = (char*) my_malloc((copy_len=strlen(mysql_tmpdir) + 1) - , MYF(MY_FAE)); // no need to check return value, if we fail, my_malloc() never returns - memcpy(slave_load_tmpdir, mysql_tmpdir, copy_len); + slave_load_tmpdir = (char*) my_strdup(mysql_tmpdir, MYF(MY_FAE)); } } diff --git a/sql/net_serv.cc b/sql/net_serv.cc index 43650f365bb..5e002a0f63e 100644 --- a/sql/net_serv.cc +++ b/sql/net_serv.cc @@ -31,16 +31,16 @@ #include <winsock.h> #endif #include <my_global.h> +#include <mysql.h> +#include <mysql_embed.h> #include <mysql_com.h> -#include <violite.h> +#include <mysqld_error.h> #include <my_sys.h> #include <m_string.h> -#include "mysql.h" -#include "mysqld_error.h" +#include <my_net.h> +#include <violite.h> #include <signal.h> #include <errno.h> -#include <sys/types.h> -#include <assert.h> #ifdef MYSQL_SERVER ulong max_allowed_packet=65536; @@ -60,20 +60,9 @@ ulong net_write_timeout= NET_WRITE_TIMEOUT; #endif ulong net_buffer_length=8192; /* Default length. Enlarged if necessary */ -#if !defined(__WIN__) && !defined(MSDOS) -#include <sys/socket.h> -#else +#if defined(__WIN__) || defined(MSDOS) #undef MYSQL_SERVER /* Win32 can't handle interrupts */ #endif -#if !defined(MSDOS) && !defined(__WIN__) && !defined(HAVE_BROKEN_NETINET_INCLUDES) && !defined(__BEOS__) -#include <netinet/in_systm.h> -#include <netinet/in.h> -#include <netinet/ip.h> -#if !defined(alpha_linux_port) -#include <netinet/tcp.h> -#endif -#endif -#include "mysqld_error.h" #ifdef MYSQL_SERVER #include "my_pthread.h" #include "thr_alarm.h" @@ -90,7 +79,7 @@ extern ulong mysqld_net_retry_count; typedef my_bool thr_alarm_t; typedef my_bool ALARM; #define thr_alarm_init(A) (*(A))=0 -#define thr_alarm_in_use(A) (*(A)) +#define thr_alarm_in_use(A) (*(A) != 0) #define thr_end_alarm(A) #define thr_alarm(A,B,C) local_thr_alarm((A),(B),(C)) inline int local_thr_alarm(my_bool *A,int B __attribute__((unused)),ALARM *C __attribute__((unused))) @@ -130,7 +119,7 @@ int my_net_init(NET *net, Vio* vio) net->no_send_ok = 0; net->error=0; net->return_errno=0; net->return_status=0; net->timeout=(uint) net_read_timeout; /* Timeout for read */ - net->pkt_nr=0; + net->pkt_nr=net->compress_pkt_nr=0; net->write_pos=net->read_pos = net->buff; net->last_error[0]=0; net->compress=0; net->reading_or_writing=0; @@ -191,7 +180,7 @@ static my_bool net_realloc(NET *net, ulong length) void net_clear(NET *net) { #ifndef EXTRA_DEBUG - int count; // One may get 'unused' warning + int count; /* One may get 'unused' warn */ bool is_blocking=vio_is_blocking(net->vio); if (is_blocking) vio_blocking(net->vio, FALSE); @@ -205,7 +194,7 @@ void net_clear(NET *net) vio_blocking(net->vio, TRUE); } #endif /* EXTRA_DEBUG */ - net->pkt_nr=0; /* Ready for new command */ + net->pkt_nr=net->compress_pkt_nr=0; /* Ready for new command */ net->write_pos=net->buff; } @@ -218,9 +207,12 @@ int net_flush(NET *net) if (net->buff != net->write_pos) { error=net_real_write(net,(char*) net->buff, - (uint) (net->write_pos - net->buff)); + (ulong) (net->write_pos - net->buff)); net->write_pos=net->buff; } + /* Sync packet number if using compression */ + if (net->compress) + net->pkt_nr=net->compress_pkt_nr; DBUG_RETURN(error); } @@ -249,7 +241,7 @@ my_net_write(NET *net,const char *packet,ulong len) { const ulong z_size = MAX_THREE_BYTES; int3store(buff, z_size); - buff[3]= (net->compress) ? 0 : (uchar) (net->pkt_nr++); + buff[3]= net->pkt_nr++; if (net_write_buff(net, (char*) buff, NET_HEADER_SIZE) || net_write_buff(net, packet, z_size)) return 1; @@ -258,7 +250,7 @@ my_net_write(NET *net,const char *packet,ulong len) } /* Write last packet */ int3store(buff,len); - buff[3]= (net->compress) ? 0 : (uchar) (net->pkt_nr++); + buff[3]= net->pkt_nr++; if (net_write_buff(net,(char*) buff,NET_HEADER_SIZE)) return 1; return net_write_buff(net,packet,len); @@ -276,7 +268,7 @@ my_net_write(NET *net,const char *packet,ulong len) int net_write_command(NET *net,uchar command,const char *packet,ulong len) { - uint length=len+1; /* 1 extra byte for command */ + ulong length=len+1; /* 1 extra byte for command */ uchar buff[NET_HEADER_SIZE+1]; uint header_size=NET_HEADER_SIZE+1; buff[4]=command; /* For first packet */ @@ -288,7 +280,7 @@ net_write_command(NET *net,uchar command,const char *packet,ulong len) do { int3store(buff, MAX_THREE_BYTES); - buff[3]= (net->compress) ? 0 : (uchar) (net->pkt_nr++); + buff[3]= net->pkt_nr++; if (net_write_buff(net,(char*) buff, header_size) || net_write_buff(net,packet,len)) return 1; @@ -300,7 +292,7 @@ net_write_command(NET *net,uchar command,const char *packet,ulong len) len=length; /* Data left to be written */ } int3store(buff,length); - buff[3]= (net->compress) ? 0 : (uchar) (net->pkt_nr++); + buff[3]= net->pkt_nr++; return test(net_write_buff(net,(char*) buff,header_size) || net_write_buff(net,packet,len) || net_flush(net)); } @@ -313,7 +305,7 @@ net_write_command(NET *net,uchar command,const char *packet,ulong len) static int net_write_buff(NET *net,const char *packet,ulong len) { - uint left_length=(uint) (net->buff_end - net->write_pos); + ulong left_length=(ulong) (net->buff_end - net->write_pos); while (len > left_length) { @@ -339,10 +331,10 @@ net_write_buff(NET *net,const char *packet,ulong len) int net_real_write(NET *net,const char *packet,ulong len) { - int length; + long int length; char *pos,*end; thr_alarm_t alarmed; -#if !defined(__WIN__) +#if !defined(__WIN__) && !defined(__EMX__) && !defined(OS2) ALARM alarm_buff; #endif uint retry_count=0; @@ -379,7 +371,7 @@ net_real_write(NET *net,const char *packet,ulong len) } int3store(&b[NET_HEADER_SIZE],complen); int3store(b,len); - b[3]=(uchar) (net->pkt_nr++); + b[3]=(uchar) (net->compress_pkt_nr++); len+= header_length; packet= (char*) b; } @@ -397,7 +389,7 @@ net_real_write(NET *net,const char *packet,ulong len) pos=(char*) packet; end=pos+len; while (pos != end) { - if ((int) (length=vio_write(net->vio,pos,(int) (end-pos))) <= 0) + if ((long) (length=vio_write(net->vio,pos,(ulong) (end-pos))) <= 0) { my_bool interrupted = vio_should_retry(net->vio); #if (!defined(__WIN__) && !defined(__EMX__) && !defined(OS2)) @@ -498,7 +490,7 @@ static void my_net_skip_rest(NET *net, ulong remain, thr_alarm_t *alarmed) { my_bool interrupted = vio_should_retry(net->vio); if (!thr_got_alarm(&alarmed) && interrupted) - { /* Probably in MIT threads */ + { /* Probably in MIT threads */ if (retry_count++ < RETRY_COUNT) continue; } @@ -517,7 +509,7 @@ static void my_net_skip_rest(NET *net, ulong remain, thr_alarm_t *alarmed) This function reallocates the net->buff buffer if necessary. */ -static uint +static ulong my_real_read(NET *net, ulong *complen) { uchar *pos; @@ -628,9 +620,9 @@ my_real_read(NET *net, ulong *complen) if (net->buff[net->where_b] != (uchar) 255) { DBUG_PRINT("error", - ("Packets out of order (Found: %d, expected %d)", + ("Packets out of order (Found: %d, expected %u)", (int) net->buff[net->where_b + 3], - (uint) (uchar) net->pkt_nr)); + net->pkt_nr)); #ifdef EXTRA_DEBUG fprintf(stderr,"Packets out of order (Found: %d, expected %d)\n", (int) net->buff[net->where_b + 3], @@ -643,7 +635,7 @@ my_real_read(NET *net, ulong *complen) #endif goto end; } - net->pkt_nr++; + net->compress_pkt_nr= ++net->pkt_nr; #ifdef HAVE_COMPRESS if (net->compress) { @@ -711,7 +703,7 @@ my_net_read(NET *net) if (len == MAX_THREE_BYTES) { /* First packet of a multi-packet. Concatenate the packets */ - int save_pos = net->where_b; + ulong save_pos = net->where_b; ulong total_length=0; do { @@ -821,8 +813,8 @@ my_net_read(NET *net) net->read_pos= net->buff+ first_packet_offset + NET_HEADER_SIZE; net->buf_length= buf_length; - net->remain_in_buf= buf_length - start_of_packet; - len = ((uint) (start_of_packet - first_packet_offset) - NET_HEADER_SIZE - + net->remain_in_buf= (ulong) (buf_length - start_of_packet); + len = ((ulong) (start_of_packet - first_packet_offset) - NET_HEADER_SIZE - multi_byte_packet); net->save_char= net->read_pos[len]; /* Must be saved */ net->read_pos[len]=0; /* Safeguard for mysql_use_result */ diff --git a/sql/nt_servc.cc b/sql/nt_servc.cc index 5884300fe95..3a36f5740a9 100644 --- a/sql/nt_servc.cc +++ b/sql/nt_servc.cc @@ -246,7 +246,8 @@ void NTService::ServiceMain(DWORD argc, LPTSTR *argv) WaitForSingleObject (pService->hExitEvent, INFINITE); // wait for thread to exit - WaitForSingleObject (pService->hThreadHandle, 30000); + if (WaitForSingleObject (pService->hThreadHandle, 1000)==WAIT_TIMEOUT) + CloseHandle(pService->hThreadHandle); pService->Exit(0); } diff --git a/sql/opt_range.cc b/sql/opt_range.cc index 0831634a9a6..cc659623f1d 100644 --- a/sql/opt_range.cc +++ b/sql/opt_range.cc @@ -607,7 +607,7 @@ int SQL_SELECT::test_quick_select(key_map keys_to_use, table_map prev_tables, if (limit < records) read_time=(double) records+scan_time+1; // Force to use index else if (read_time <= 2.0 && !force_quick_range) - DBUG_RETURN(0); /* No nead for quick select */ + DBUG_RETURN(0); /* No need for quick select */ DBUG_PRINT("info",("Time to scan table: %ld",(long) read_time)); diff --git a/sql/opt_sum.cc b/sql/opt_sum.cc index c16c0d919d4..182fb6cf362 100644 --- a/sql/opt_sum.cc +++ b/sql/opt_sum.cc @@ -305,7 +305,7 @@ static bool find_range_key(TABLE_REF *ref, Field* field, COND *cond) key>>=1; ref->key_length=0; ref->key=idx; - if (field->part_of_key & ((table_map) 1 << idx)) + if (field->part_of_key & ((key_map) 1 << idx)) { table->key_read=1; table->file->extra(HA_EXTRA_KEYREAD); @@ -350,7 +350,7 @@ static bool find_range_key(TABLE_REF *ref, Field* field, COND *cond) { ref->key_length= (uint) (key_ptr-ref->key_buff); ref->key=idx; - if (field->part_of_key & ((table_map) 1 << idx)) + if (field->part_of_key & ((key_map) 1 << idx)) { table->key_read=1; table->file->extra(HA_EXTRA_KEYREAD); diff --git a/sql/share/czech/errmsg.txt b/sql/share/czech/errmsg.txt index b92297abbf8..8d9fda437a5 100644 --- a/sql/share/czech/errmsg.txt +++ b/sql/share/czech/errmsg.txt @@ -231,3 +231,4 @@ "The used SELECT statements have a different number of columns", "Can't execute the query because you have a conflicting read lock", "Mixing of transactional and non-transactional tables is disabled", +"Option '%s' used twice in statement", diff --git a/sql/share/danish/errmsg.txt b/sql/share/danish/errmsg.txt index 9adc2f5fb73..81d44de6a87 100644 --- a/sql/share/danish/errmsg.txt +++ b/sql/share/danish/errmsg.txt @@ -225,3 +225,4 @@ "The used SELECT statements have a different number of columns", "Can't execute the query because you have a conflicting read lock", "Mixing of transactional and non-transactional tables is disabled", +"Option '%s' used twice in statement", diff --git a/sql/share/dutch/errmsg.txt b/sql/share/dutch/errmsg.txt index 61db11f39f8..68e20deb257 100644 --- a/sql/share/dutch/errmsg.txt +++ b/sql/share/dutch/errmsg.txt @@ -228,3 +228,4 @@ "The used SELECT statements have a different number of columns", "Can't execute the query because you have a conflicting read lock", "Mixing of transactional and non-transactional tables is disabled", +"Option '%s' used twice in statement", diff --git a/sql/share/english/errmsg.txt b/sql/share/english/errmsg.txt index bd328dbb6e4..5d057c30a0e 100644 --- a/sql/share/english/errmsg.txt +++ b/sql/share/english/errmsg.txt @@ -222,3 +222,4 @@ "The used SELECT statements have a different number of columns", "Can't execute the query because you have a conflicting read lock", "Mixing of transactional and non-transactional tables is disabled", +"Option '%s' used twice in statement", diff --git a/sql/share/estonian/errmsg.txt b/sql/share/estonian/errmsg.txt index 166637c43e1..3f9d15c2e4d 100644 --- a/sql/share/estonian/errmsg.txt +++ b/sql/share/estonian/errmsg.txt @@ -226,3 +226,4 @@ "The used SELECT statements have a different number of columns", "Can't execute the query because you have a conflicting read lock", "Mixing of transactional and non-transactional tables is disabled", +"Option '%s' used twice in statement", diff --git a/sql/share/french/errmsg.txt b/sql/share/french/errmsg.txt index 0db8b69622e..7d9c6202c5f 100644 --- a/sql/share/french/errmsg.txt +++ b/sql/share/french/errmsg.txt @@ -222,3 +222,4 @@ "The used SELECT statements have a different number of columns", "Can't execute the query because you have a conflicting read lock", "Mixing of transactional and non-transactional tables is disabled", +"Option '%s' used twice in statement", diff --git a/sql/share/german/errmsg.txt b/sql/share/german/errmsg.txt index a9ba1f41c42..14bd0f8a042 100644 --- a/sql/share/german/errmsg.txt +++ b/sql/share/german/errmsg.txt @@ -225,3 +225,4 @@ "The used SELECT statements have a different number of columns", "Can't execute the query because you have a conflicting read lock", "Mixing of transactional and non-transactional tables is disabled", +"Option '%s' used twice in statement", diff --git a/sql/share/greek/errmsg.txt b/sql/share/greek/errmsg.txt index aa8d659b263..ab1103a56b4 100644 --- a/sql/share/greek/errmsg.txt +++ b/sql/share/greek/errmsg.txt @@ -222,3 +222,4 @@ "The used SELECT statements have a different number of columns", "Can't execute the query because you have a conflicting read lock", "Mixing of transactional and non-transactional tables is disabled", +"Option '%s' used twice in statement", diff --git a/sql/share/hungarian/errmsg.txt b/sql/share/hungarian/errmsg.txt index 5cc5ac663b1..33d51cb0e60 100644 --- a/sql/share/hungarian/errmsg.txt +++ b/sql/share/hungarian/errmsg.txt @@ -224,3 +224,4 @@ "The used SELECT statements have a different number of columns", "Can't execute the query because you have a conflicting read lock", "Mixing of transactional and non-transactional tables is disabled", +"Option '%s' used twice in statement", diff --git a/sql/share/italian/errmsg.txt b/sql/share/italian/errmsg.txt index 7c44e0bf4c7..127a33bbb28 100644 --- a/sql/share/italian/errmsg.txt +++ b/sql/share/italian/errmsg.txt @@ -222,3 +222,4 @@ "The used SELECT statements have a different number of columns", "Can't execute the query because you have a conflicting read lock", "Mixing of transactional and non-transactional tables is disabled", +"Option '%s' used twice in statement", diff --git a/sql/share/japanese/errmsg.txt b/sql/share/japanese/errmsg.txt index 5d6f0158ea2..e345f462f2a 100644 --- a/sql/share/japanese/errmsg.txt +++ b/sql/share/japanese/errmsg.txt @@ -224,3 +224,4 @@ "The used SELECT statements have a different number of columns", "Can't execute the query because you have a conflicting read lock", "Mixing of transactional and non-transactional tables is disabled", +"Option '%s' used twice in statement", diff --git a/sql/share/korean/errmsg.txt b/sql/share/korean/errmsg.txt index 6288ac535d4..dd1d92adf64 100644 --- a/sql/share/korean/errmsg.txt +++ b/sql/share/korean/errmsg.txt @@ -222,3 +222,4 @@ "The used SELECT statements have a different number of columns", "Can't execute the query because you have a conflicting read lock", "Mixing of transactional and non-transactional tables is disabled", +"Option '%s' used twice in statement", diff --git a/sql/share/norwegian-ny/errmsg.txt b/sql/share/norwegian-ny/errmsg.txt index de783f93d1a..bbdf23e4056 100644 --- a/sql/share/norwegian-ny/errmsg.txt +++ b/sql/share/norwegian-ny/errmsg.txt @@ -224,3 +224,4 @@ "The used SELECT statements have a different number of columns", "Can't execute the query because you have a conflicting read lock", "Mixing of transactional and non-transactional tables is disabled", +"Option '%s' used twice in statement", diff --git a/sql/share/norwegian/errmsg.txt b/sql/share/norwegian/errmsg.txt index 3cbc5b6138d..6139b1bb700 100644 --- a/sql/share/norwegian/errmsg.txt +++ b/sql/share/norwegian/errmsg.txt @@ -224,3 +224,4 @@ "The used SELECT statements have a different number of columns", "Can't execute the query because you have a conflicting read lock", "Mixing of transactional and non-transactional tables is disabled", +"Option '%s' used twice in statement", diff --git a/sql/share/polish/errmsg.txt b/sql/share/polish/errmsg.txt index c144dda47ae..39ff72acba1 100644 --- a/sql/share/polish/errmsg.txt +++ b/sql/share/polish/errmsg.txt @@ -226,3 +226,4 @@ "The used SELECT statements have a different number of columns", "Can't execute the query because you have a conflicting read lock", "Mixing of transactional and non-transactional tables is disabled", +"Option '%s' used twice in statement", diff --git a/sql/share/portuguese/errmsg.txt b/sql/share/portuguese/errmsg.txt index c11adc3af70..a522e792750 100644 --- a/sql/share/portuguese/errmsg.txt +++ b/sql/share/portuguese/errmsg.txt @@ -222,3 +222,4 @@ "The used SELECT statements have a different number of columns", "Can't execute the query because you have a conflicting read lock", "Mixing of transactional and non-transactional tables is disabled", +"Option '%s' used twice in statement", diff --git a/sql/share/romanian/errmsg.txt b/sql/share/romanian/errmsg.txt index 32b6eddfeeb..0177ff942a0 100644 --- a/sql/share/romanian/errmsg.txt +++ b/sql/share/romanian/errmsg.txt @@ -226,3 +226,4 @@ "The used SELECT statements have a different number of columns", "Can't execute the query because you have a conflicting read lock", "Mixing of transactional and non-transactional tables is disabled", +"Option '%s' used twice in statement", diff --git a/sql/share/russian/errmsg.txt b/sql/share/russian/errmsg.txt index fbff74993fb..c6b5c324cad 100644 --- a/sql/share/russian/errmsg.txt +++ b/sql/share/russian/errmsg.txt @@ -225,3 +225,4 @@ "The used SELECT statements have a different number of columns", "Can't execute the query because you have a conflicting read lock", "Mixing of transactional and non-transactional tables is disabled", +"Option '%s' used twice in statement", diff --git a/sql/share/slovak/errmsg.txt b/sql/share/slovak/errmsg.txt index d60dbf0956c..26ca2881212 100644 --- a/sql/share/slovak/errmsg.txt +++ b/sql/share/slovak/errmsg.txt @@ -230,3 +230,4 @@ "The used SELECT statements have a different number of columns", "Can't execute the query because you have a conflicting read lock", "Mixing of transactional and non-transactional tables is disabled", +"Option '%s' used twice in statement", diff --git a/sql/share/spanish/errmsg.txt b/sql/share/spanish/errmsg.txt index 9234de04786..8bbf04c9a3d 100644 --- a/sql/share/spanish/errmsg.txt +++ b/sql/share/spanish/errmsg.txt @@ -223,3 +223,4 @@ "The used SELECT statements have a different number of columns", "Can't execute the query because you have a conflicting read lock", "Mixing of transactional and non-transactional tables is disabled", +"Option '%s' used twice in statement", diff --git a/sql/share/swedish/errmsg.txt b/sql/share/swedish/errmsg.txt index 25309cd0598..b4303de8619 100644 --- a/sql/share/swedish/errmsg.txt +++ b/sql/share/swedish/errmsg.txt @@ -222,3 +222,4 @@ "SELECT kommandona har olika antal kolumner" "Kan inte utföra kommandot emedan du har ett READ lås", "Blandning av transaktionella och icke-transaktionella tabeller är inaktiverat", +"Option '%s' användes två gånger", diff --git a/sql/share/ukrainian/errmsg.txt b/sql/share/ukrainian/errmsg.txt index 49ab4399664..80c2bcc06fb 100644 --- a/sql/share/ukrainian/errmsg.txt +++ b/sql/share/ukrainian/errmsg.txt @@ -227,3 +227,4 @@ "The used SELECT statements have a different number of columns", "Can't execute the query because you have a conflicting read lock", "Mixing of transactional and non-transactional tables is disabled", +"Option '%s' used twice in statement", diff --git a/sql/slave.cc b/sql/slave.cc index 1a6a0910f54..d2e038bef88 100644 --- a/sql/slave.cc +++ b/sql/slave.cc @@ -307,7 +307,7 @@ static int init_strvar_from_file(char* var, int max_size, IO_CACHE* f, } else if (default_val) { - strmake(var, default_val, max_size); + strmake(var, default_val, max_size-1); return 0; } return 1; @@ -522,7 +522,7 @@ int init_master_info(MASTER_INFO* mi) if (master_user) strmake(mi->user, master_user, sizeof(mi->user) - 1); if (master_password) - strmake(mi->password, master_password, sizeof(mi->password) - 1); + strmake(mi->password, master_password, HASH_PASSWORD_LENGTH); mi->port = master_port; mi->connect_retry = master_connect_retry; } @@ -548,20 +548,20 @@ int init_master_info(MASTER_INFO* mi) } mi->log_file_name[length-1]= 0; // kill \n - char buf[FN_REFLEN]; - if(!my_b_gets(&mi->file, buf, sizeof(buf))) + /* Reuse fname buffer */ + if(!my_b_gets(&mi->file, fname, sizeof(fname))) { msg="Error reading log file position from master info file"; goto error; } + mi->pos = strtoull(fname,(char**) 0, 10); - mi->pos = strtoull(buf,(char**) 0, 10); mi->fd = fd; if(init_strvar_from_file(mi->host, sizeof(mi->host), &mi->file, master_host) || init_strvar_from_file(mi->user, sizeof(mi->user), &mi->file, master_user) || - init_strvar_from_file(mi->password, sizeof(mi->password), &mi->file, + init_strvar_from_file(mi->password, HASH_PASSWORD_LENGTH+1, &mi->file, master_password) || init_intvar_from_file((int*)&mi->port, &mi->file, master_port) || init_intvar_from_file((int*)&mi->connect_retry, &mi->file, @@ -925,7 +925,7 @@ point. If you are sure that your master is ok, run this query manually on the\ slave and then restart the slave with SET SQL_SLAVE_SKIP_COUNTER=1;\ SLAVE START;", thd->query); last_slave_errno = expected_error; - sql_print_error(last_slave_error); + sql_print_error("%s",last_slave_error); return 1; default: return 0; @@ -934,8 +934,9 @@ point. If you are sure that your master is ok, run this query manually on the\ static int exec_event(THD* thd, NET* net, MASTER_INFO* mi, int event_len) { + const char *error_msg; Log_event * ev = Log_event::read_log_event((const char*)net->read_pos + 1, - event_len); + event_len, &error_msg); if (ev) { int type_code = ev->get_type_code(); @@ -1249,7 +1250,7 @@ static int safe_connect(THD* thd, MYSQL* mysql, MASTER_INFO* mi) !mc_mysql_connect(mysql, mi->host, mi->user, mi->password, 0, mi->port, 0, 0)) { - sql_print_error("Slave thread: error connecting to master:%s(%d),\ + sql_print_error("Slave thread: error connecting to master: %s (%d),\ retry in %d sec", mc_mysql_error(mysql), errno, mi->connect_retry); safe_sleep(thd, mi->connect_retry); } @@ -1266,38 +1267,55 @@ static int safe_connect(THD* thd, MYSQL* mysql, MASTER_INFO* mi) return slave_was_killed; } -/* try to connect until successful or slave killed */ +/* + Try to connect until successful or slave killed or we have retried + master_retry_count times +*/ static int safe_reconnect(THD* thd, MYSQL* mysql, MASTER_INFO* mi) { int slave_was_killed; + int last_errno= -2; // impossible error + ulong err_count=0; char llbuff[22]; - // if we lost connection after reading a state set event - // we will be re-reading it, so pending needs to be cleared + /* + If we lost connection after reading a state set event + we will be re-reading it, so pending needs to be cleared + */ mi->pending = 0; #ifndef DBUG_OFF events_till_disconnect = disconnect_slave_event_count; #endif - while(!(slave_was_killed = slave_killed(thd)) && mc_mysql_reconnect(mysql)) + while (!(slave_was_killed = slave_killed(thd)) && mc_mysql_reconnect(mysql)) { - sql_print_error("Slave thread: error re-connecting to master:\ + /* Don't repeat last error */ + if (mc_mysql_errno(mysql) != last_errno) + { + sql_print_error("Slave thread: error re-connecting to master: \ %s, last_errno=%d, retry in %d sec", - mc_mysql_error(mysql), errno, mi->connect_retry); - safe_sleep(thd, mi->connect_retry); + mc_mysql_error(mysql), last_errno=mc_mysql_errno(mysql), + mi->connect_retry); + safe_sleep(thd, mi->connect_retry); + } + if (err_count++ == master_retry_count) + { + slave_was_killed=1; + break; + } } - if(!slave_was_killed) - { - sql_print_error("Slave: reconnected to master '%s@%s:%d',\ + if (!slave_was_killed) + { + sql_print_error("Slave: reconnected to master '%s@%s:%d',\ replication resumed in log '%s' at position %s", glob_mi.user, glob_mi.host, glob_mi.port, RPL_LOG_NAME, llstr(glob_mi.pos,llbuff)); #ifdef SIGNAL_WITH_VIO_CLOSE - thd->set_active_vio(mysql->net.vio); + thd->set_active_vio(mysql->net.vio); #endif - } + } return slave_was_killed; } diff --git a/sql/slave.h b/sql/slave.h index 5850b57d3b3..5c6772147b6 100644 --- a/sql/slave.h +++ b/sql/slave.h @@ -4,7 +4,7 @@ #include "mysql.h" #define SLAVE_NET_TIMEOUT 3600 -extern ulong slave_net_timeout; +extern ulong slave_net_timeout, master_retry_count; extern char* slave_load_tmpdir; typedef struct st_master_info diff --git a/sql/sql_acl.cc b/sql/sql_acl.cc index 4c128a882c6..888ccf7b482 100644 --- a/sql/sql_acl.cc +++ b/sql/sql_acl.cc @@ -62,8 +62,9 @@ public: char *user,*password; ulong salt[2]; #ifdef HAVE_OPENSSL - char *ssl_type, *ssl_cipher, *x509_issuer, *x509_subject; -#endif + enum SSL_type ssl_type; + const char *ssl_cipher, *x509_issuer, *x509_subject; +#endif /* HAVE_OPENSSL */ }; class ACL_DB :public ACL_ACCESS @@ -204,13 +205,22 @@ int acl_init(bool dont_read_acl_tables) user.password=get_field(&mem, table,2); #ifdef HAVE_OPENSSL DBUG_PRINT("info",("table->fields=%d",table->fields)); - if (table->fields >= 21) { - user.ssl_type=get_field(&mem, table,17); - user.ssl_cipher=get_field(&mem, table,18); - user.x509_issuer=get_field(&mem, table,19); - user.x509_subject=get_field(&mem, table,20); + if (table->fields >= 21) /* From 4.0.0 we have more fields */ + { + char *ssl_type=get_field(&mem, table,17); + if (!strcmp(ssl_type, "ANY")) + user.ssl_type=SSL_TYPE_ANY; + else if (!strcmp(ssl_type, "X509")) + user.ssl_type=SSL_TYPE_X509; + else if (!strcmp(ssl_type, "SPECIFIED")) + user.ssl_type=SSL_TYPE_SPECIFIED; + else + user.ssl_type=SSL_TYPE_NONE; + user.ssl_cipher=get_field(&mem, table, 18); + user.x509_issuer=get_field(&mem, table, 19); + user.x509_subject=get_field(&mem, table, 20); } -#endif +#endif /* HAVE_OPENSSL */ if (user.password && (length=(uint) strlen(user.password)) == 8 && protocol_version == PROTOCOL_VERSION) { @@ -410,15 +420,14 @@ static int acl_compare(ACL_ACCESS *a,ACL_ACCESS *b) } -/* Get master privilges for user (priviliges for all tables) */ - - -uint acl_getroot(const char *host, const char *ip, const char *user, +/* Get master privilges for user (priviliges for all tables). Required to connect */ +uint acl_getroot(THD *thd, const char *host, const char *ip, const char *user, const char *password,const char *message,char **priv_user, bool old_ver) { uint user_access=NO_ACCESS; *priv_user=(char*) user; + char *ptr=0; if (!initialized) return (uint) ~NO_ACCESS; // If no data allow anything /* purecov: tested */ @@ -440,7 +449,93 @@ uint acl_getroot(const char *host, const char *ip, const char *user, !check_scramble(password,message,acl_user->salt, (my_bool) old_ver))) { +#ifdef HAVE_OPENSSL + Vio *vio=thd->net.vio; + /* + In this point we know that user is allowed to connect + from given host by given username/password pair. Now + we check if SSL is required, if user is using SSL and + if X509 certificate attributes are OK + */ + switch(acl_user->ssl_type) { + case SSL_TYPE_NONE: /* SSL is not required to connect */ + user_access=acl_user->access; + break; + case SSL_TYPE_ANY: /* Any kind of SSL is good enough */ + if (vio_type(vio) == VIO_TYPE_SSL) + user_access=acl_user->access; + break; + case SSL_TYPE_X509: /* Client should have any valid certificate. */ + /* + Connections with non-valid certificates are dropped already + in sslaccept() anyway, so we do not check validity here. + */ + if (SSL_get_peer_certificate(vio->ssl_)) + user_access=acl_user->access; + break; + case SSL_TYPE_SPECIFIED: /* Client should have specified attrib */ + /* + We do not check for absence of SSL because without SSL it does + not pass all checks here anyway. + If cipher name is specified, we compare it to actual cipher in + use. + */ + if (acl_user->ssl_cipher) + DBUG_PRINT("info",("comparing ciphers: '%s' and '%s'", + acl_user->ssl_cipher, + SSL_get_cipher(vio->ssl_))); + if (!strcmp(acl_user->ssl_cipher,SSL_get_cipher(vio->ssl_))) + user_access=acl_user->access; + else + { + user_access=NO_ACCESS; + break; + } + /* Prepare certificate (if exists) */ + DBUG_PRINT("info",("checkpoint 1")); + X509* cert=SSL_get_peer_certificate(vio->ssl_); + DBUG_PRINT("info",("checkpoint 2")); + /* If X509 issuer is speified, we check it... */ + if (acl_user->x509_issuer) + { + DBUG_PRINT("info",("checkpoint 3")); + ptr = X509_NAME_oneline(X509_get_issuer_name(cert), 0, 0); + DBUG_PRINT("info",("comparing issuers: '%s' and '%s'", + acl_user->x509_issuer, ptr)); + if (!strcmp(acl_user->x509_issuer,ptr)) + user_access=acl_user->access; + else + { + user_access=NO_ACCESS; + free(ptr); + break; + } + free(ptr); + } + DBUG_PRINT("info",("checkpoint 4")); + /* X509 subject is specified, we check it .. */ + if (acl_user->x509_subject) + { + ptr = X509_NAME_oneline(X509_get_subject_name(cert), 0, 0); + DBUG_PRINT("info",("comparing subjects: '%s' and '%s'", + acl_user->x509_subject, ptr)); + if (!strcmp(acl_user->x509_subject,ptr)) + user_access=acl_user->access; + else + { + user_access=NO_ACCESS; + free(ptr); + break; + } + free(ptr); + } + DBUG_PRINT("info",("checkpoint 5")); + break; + } + DBUG_PRINT("info",("checkpoint 6")); +#else /* HAVE_OPENSSL */ user_access=acl_user->access; +#endif /* HAVE_OPENSSL */ if (!acl_user->user) *priv_user=(char*) ""; // Change to anonymous user /* purecov: inspected */ break; @@ -469,7 +564,12 @@ static byte* check_get_key(ACL_USER *buff,uint *length, } static void acl_update_user(const char *user, const char *host, - const char *password, uint privileges) + const char *password, + enum SSL_type ssl_type, + const char *ssl_cipher, + const char *x509_issuer, + const char *x509_subject, + uint privileges) { for (uint i=0 ; i < acl_users.elements ; i++) { @@ -482,6 +582,12 @@ static void acl_update_user(const char *user, const char *host, acl_user->host.hostname && !strcmp(host,acl_user->host.hostname)) { acl_user->access=privileges; +#ifdef HAVE_OPENSSL + acl_user->ssl_type=ssl_type; + acl_user->ssl_cipher=ssl_cipher; + acl_user->x509_issuer=x509_issuer; + acl_user->x509_subject=x509_subject; +#endif /* HAVE_OPENSSL */ if (password) { if (!password[0]) @@ -500,7 +606,11 @@ static void acl_update_user(const char *user, const char *host, static void acl_insert_user(const char *user, const char *host, - const char *password, + const char *password, + enum SSL_type ssl_type, + const char *ssl_cipher, + const char *x509_issuer, + const char *x509_subject, uint privileges) { ACL_USER acl_user; @@ -510,6 +620,12 @@ static void acl_insert_user(const char *user, const char *host, acl_user.access=privileges; acl_user.sort=get_sort(2,acl_user.host.hostname,acl_user.user); acl_user.hostname_length=(uint) strlen(acl_user.host.hostname); +#ifdef HAVE_OPENSSL + acl_user.ssl_type=ssl_type; + acl_user.ssl_cipher=ssl_cipher; + acl_user.x509_issuer=x509_issuer; + acl_user.x509_subject=x509_subject; +#endif /* HAVE_OPENSSL */ if (password) { acl_user.password=(char*) ""; // Just point at something @@ -984,7 +1100,7 @@ static bool test_if_create_new_users(THD *thd) ** Handle GRANT commands ****************************************************************************/ -static int replace_user_table(TABLE *table, const LEX_USER &combo, +static int replace_user_table(THD *thd, TABLE *table, const LEX_USER &combo, uint rights, char what, bool create_user) { int error = -1; @@ -1044,7 +1160,38 @@ static int replace_user_table(TABLE *table, const LEX_USER &combo, table->field[i]->store(&what,1); } rights=get_access(table,3); - +#ifdef HAVE_OPENSSL + /* We write down SSL related ACL stuff */ + DBUG_PRINT("info",("table->fields=%d",table->fields)); + if (table->fields >= 21) /* From 4.0.0 we have more fields */ + { + table->field[18]->store("",0); + table->field[19]->store("",0); + table->field[20]->store("",0); + switch (thd->lex.ssl_type) { + case SSL_TYPE_ANY: + table->field[17]->store("ANY",3); + break; + case SSL_TYPE_X509: + table->field[17]->store("X509",4); + break; + case SSL_TYPE_SPECIFIED: + table->field[17]->store("SPECIFIED",9); + if (thd->lex.ssl_cipher) + table->field[18]->store(thd->lex.ssl_cipher, + strlen(thd->lex.ssl_cipher)); + if (thd->lex.x509_issuer) + table->field[19]->store(thd->lex.x509_issuer, + strlen(thd->lex.x509_issuer)); + if (thd->lex.x509_subject) + table->field[20]->store(thd->lex.x509_subject, + strlen(thd->lex.x509_subject)); + break; + default: + table->field[17]->store("NONE",4); + } + } +#endif /* HAVE_OPENSSL */ if (old_row_exists) { /* @@ -1071,16 +1218,26 @@ static int replace_user_table(TABLE *table, const LEX_USER &combo, } error=0; // Privileges granted / revoked - end: +end: if (!error) { acl_cache->clear(1); // Clear privilege cache if (!combo.password.str) password=0; // No password given on command if (old_row_exists) - acl_update_user(combo.user.str,combo.host.str,password,rights); + acl_update_user(combo.user.str,combo.host.str,password, + thd->lex.ssl_type, + thd->lex.ssl_cipher, + thd->lex.x509_issuer, + thd->lex.x509_subject, + rights); else - acl_insert_user(combo.user.str,combo.host.str,password,rights); + acl_insert_user(combo.user.str,combo.host.str,password, + thd->lex.ssl_type, + thd->lex.ssl_cipher, + thd->lex.x509_issuer, + thd->lex.x509_subject, + rights); } table->file->index_end(); DBUG_RETURN(error); @@ -1626,6 +1783,9 @@ int mysql_table_grant (THD *thd, TABLE_LIST *table_list, TABLE_LIST tables[3]; bool create_new_users=0; DBUG_ENTER("mysql_table_grant"); + DBUG_PRINT("info",("ssl_cipher=%s",thd->lex.ssl_cipher)); + DBUG_PRINT("info",("x509_issuer=%s",thd->lex.x509_issuer)); + DBUG_PRINT("info",("x509_subject=%s",thd->lex.x509_subject)); if (!initialized) { @@ -1715,9 +1875,10 @@ int mysql_table_grant (THD *thd, TABLE_LIST *table_list, continue; } /* Create user if needed */ - if (replace_user_table(tables[0].table, - *Str, - 0, + if (replace_user_table(thd, + tables[0].table, + *Str, + 0, revoke_grant ? 'N' : 'Y', create_new_users)) { @@ -1810,7 +1971,7 @@ int mysql_table_grant (THD *thd, TABLE_LIST *table_list, pthread_mutex_unlock(&LOCK_grant); if (!result) send_ok(&thd->net); - /* Tables are automaticly closed */ + /* Tables are automatically closed */ DBUG_RETURN(result); } @@ -1871,7 +2032,8 @@ int mysql_grant (THD *thd, const char *db, List <LEX_USER> &list, uint rights, result= -1; continue; } - if ((replace_user_table(tables[0].table, + if ((replace_user_table(thd, + tables[0].table, *Str, (!db ? rights : 0), what, create_new_users))) result= -1; @@ -2332,6 +2494,7 @@ int mysql_show_grants(THD *thd,LEX_USER *lex_user) { uint counter, want_access,index; int error = 0; + int ssl_options = 0; ACL_USER *acl_user; ACL_DB *acl_db; char buff[1024]; DBUG_ENTER("mysql_show_grants"); @@ -2426,30 +2589,40 @@ int mysql_show_grants(THD *thd,LEX_USER *lex_user) global.append('\''); } #ifdef HAVE_OPENSSL -/* SSL grant stuff */ - DBUG_PRINT("info",("acl_user->ssl_type=%s",acl_user->ssl_type)); - DBUG_PRINT("info",("acl_user->ssl_cipher=%s",acl_user->ssl_cipher)); - DBUG_PRINT("info",("acl_user->x509_subject=%s",acl_user->x509_subject)); - DBUG_PRINT("info",("acl_user->x509_issuer=%s",acl_user->x509_issuer)); - if(acl_user->ssl_type) { - if(!strcmp(acl_user->ssl_type,"ssl")) - global.append(" REQUIRE SSL",12); - else if(!strcmp(acl_user->ssl_type,"x509")) - { - global.append(" REQUIRE X509 ",14); - if(acl_user->x509_issuer) { - global.append("SUBJECT \"",9); - global.append(acl_user->x509_issuer,strlen(acl_user->x509_issuer)); - global.append("\"",1); - } - if(acl_user->x509_subject) { - global.append("ISSUER \"",8); - global.append(acl_user->x509_subject,strlen(acl_user->x509_subject)); - global.append("\"",1); - } - } + /* "show grants" SSL related stuff */ + if (acl_user->ssl_type == SSL_TYPE_ANY) + global.append(" REQUIRE SSL",12); + else if (acl_user->ssl_type==SSL_TYPE_X509) + global.append(" REQUIRE X509",13); + else if (acl_user->ssl_type==SSL_TYPE_SPECIFIED) + { + global.append(" REQUIRE ",9); + if (acl_user->x509_issuer) + { + if (ssl_options++) + global.append(" AND ",5); + global.append("ISSUER \"",8); + global.append(acl_user->x509_issuer,strlen(acl_user->x509_issuer)); + global.append("\"",1); + } + if (acl_user->x509_subject) + { + if (ssl_options++) + global.append(" AND ",5); + global.append("SUBJECT \"",9); + global.append(acl_user->x509_subject,strlen(acl_user->x509_subject)); + global.append("\"",1); + } + if (acl_user->ssl_cipher) + { + if (ssl_options++) + global.append(" AND ",5); + global.append("CIPHER \"",8); + global.append(acl_user->ssl_cipher,strlen(acl_user->ssl_cipher)); + global.append("\"",1); } -#endif + } +#endif /* HAVE_OPENSSL */ if (want_access & GRANT_ACL) global.append(" WITH GRANT OPTION",18); thd->packet.length(0); diff --git a/sql/sql_acl.h b/sql/sql_acl.h index cf9696d51e7..e6a39f1b269 100644 --- a/sql/sql_acl.h +++ b/sql/sql_acl.h @@ -59,7 +59,7 @@ void acl_reload(void); void acl_free(bool end=0); uint acl_get(const char *host, const char *ip, const char *bin_ip, const char *user, const char *db); -uint acl_getroot(const char *host, const char *ip, const char *user, +uint acl_getroot(THD *thd, const char *host, const char *ip, const char *user, const char *password,const char *scramble,char **priv_user, bool old_ver); bool acl_check_host(const char *host, const char *ip); diff --git a/sql/sql_base.cc b/sql/sql_base.cc index 41093452984..595bee99908 100644 --- a/sql/sql_base.cc +++ b/sql/sql_base.cc @@ -15,7 +15,7 @@ Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ -/* Basic functions neaded by many modules */ +/* Basic functions needed by many modules */ #include "mysql_priv.h" #include "sql_acl.h" @@ -160,17 +160,19 @@ OPEN_TABLE_LIST *list_open_tables(THD *thd, const char *wild) if (table) continue; if (!(*start_list = (OPEN_TABLE_LIST *) - sql_alloc(sizeof(OPEN_TABLE_LIST)+entry->key_length))) + sql_alloc(sizeof(*start_list)+entry->key_length))) { open_list=0; // Out of memory break; } - (*start_list)->table=(strmov((*start_list)->db=(char*) ((*start_list)+1), - entry->table_cache_key)+1, - entry->real_name); + strmov((*start_list)->table= + strmov(((*start_list)->db= (char*) ((*start_list)+1)), + entry->table_cache_key)+1, + entry->real_name); (*start_list)->in_use= entry->in_use ? 1 : 0; (*start_list)->locked= entry->locked_by_name ? 1 : 0; start_list= &(*start_list)->next; + *start_list=0; } VOID(pthread_mutex_unlock(&LOCK_open)); DBUG_RETURN(open_list); @@ -1579,13 +1581,7 @@ Field *find_field_in_table(THD *thd,TABLE *table,const char *name,uint length, { field->query_id=thd->query_id; table->used_fields++; - if (field->part_of_key) - { - if (!(field->part_of_key & table->ref_primary_key)) - table->used_keys&=field->part_of_key; - } - else - table->used_keys=0; + table->used_keys&=field->part_of_key; } else thd->dupp_field=field; @@ -1655,7 +1651,8 @@ find_field_in_tables(THD *thd,Item_field *item,TABLE_LIST *tables) for (; tables ; tables=tables->next) { Field *field=find_field_in_table(thd,tables->table,name,length, - grant_option && !thd->master_access, allow_rowid); + grant_option && + !thd->master_access, allow_rowid); if (field) { if (field == WRONG_GRANT) @@ -1879,14 +1876,7 @@ insert_fields(THD *thd,TABLE_LIST *tables, const char *db_name, if (field->query_id == thd->query_id) thd->dupp_field=field; field->query_id=thd->query_id; - - if (field->part_of_key) - { - if (!(field->part_of_key & table->ref_primary_key)) - table->used_keys&=field->part_of_key; - } - else - table->used_keys=0; + table->used_keys&=field->part_of_key; } /* All fields are used */ table->used_fields=table->fields; @@ -1954,7 +1944,6 @@ int setup_conds(THD *thd,TABLE_LIST *tables,COND **conds) // TODO: This could be optimized to use hashed names if t2 had a hash for (j=0 ; j < t2->fields ; j++) { - key_map tmp_map; if (!my_strcasecmp(t1->field[i]->field_name, t2->field[j]->field_name)) { @@ -1967,20 +1956,8 @@ int setup_conds(THD *thd,TABLE_LIST *tables,COND **conds) /* Mark field used for table cache */ t1->field[i]->query_id=t2->field[j]->query_id=thd->query_id; cond_and->list.push_back(tmp); - if ((tmp_map=t1->field[i]->part_of_key)) - { - if (!(tmp_map & t1->ref_primary_key)) - t1->used_keys&=tmp_map; - } - else - t1->used_keys=0; - if ((tmp_map=t2->field[j]->part_of_key)) - { - if (!(tmp_map & t2->ref_primary_key)) - t2->used_keys&=tmp_map; - } - else - t2->used_keys=0; + t1->used_keys&= t1->field[i]->part_of_key; + t2->used_keys&= t2->field[j]->part_of_key; break; } } diff --git a/sql/sql_class.h b/sql/sql_class.h index 0104a251f2c..b34b97b29a0 100644 --- a/sql/sql_class.h +++ b/sql/sql_class.h @@ -51,6 +51,7 @@ typedef struct st_log_info ~st_log_info() { pthread_mutex_destroy(&lock);} } LOG_INFO; +class Log_event; class MYSQL_LOG { private: diff --git a/sql/sql_delete.cc b/sql/sql_delete.cc index 00ebef89fa5..8ba293c82f9 100644 --- a/sql/sql_delete.cc +++ b/sql/sql_delete.cc @@ -274,6 +274,8 @@ multi_delete::initialize_tables(JOIN *join) /* We are going to delete from this table */ walk->table=tab->table; walk=walk->next; + if (tab == join->join_tab) + tab->table->no_keyread=1; } } } @@ -309,7 +311,6 @@ bool multi_delete::send_data(List<Item> &values) continue; table->file->position(table->record[0]); - int rl = table->file->ref_length; if (secure_counter < 0) { @@ -354,6 +355,10 @@ void multi_delete::send_error(uint errcode,const char *err) { /* First send error what ever it is ... */ ::send_error(&thd->net,errcode,err); + + /* reset used flags */ + delete_tables->table->no_keyread=0; + /* If nothing deleted return */ if (!deleted) return; @@ -397,7 +402,6 @@ int multi_delete::do_deletes (bool from_send_error) table_being_deleted=table_being_deleted->next, counter++) { TABLE *table = table_being_deleted->table; - int rl = table->file->ref_length; if (tempfiles[counter]->get(table)) { error=1; @@ -453,6 +457,9 @@ bool multi_delete::send_eof() thd->proc_info="deleting from reference tables"; int error = do_deletes(false); + /* reset used flags */ + delete_tables->table->no_keyread=0; + thd->proc_info="end"; if (error && error != -1) { diff --git a/sql/sql_insert.cc b/sql/sql_insert.cc index 1d2805d8e90..7a89a3d38dd 100644 --- a/sql/sql_insert.cc +++ b/sql/sql_insert.cc @@ -391,7 +391,7 @@ int write_record(TABLE *table,COPY_INFO *info) } else { - if (table->file->extra(HA_EXTRA_FLUSH_CACHE)) /* Not neaded with NISAM */ + if (table->file->extra(HA_EXTRA_FLUSH_CACHE)) /* Not needed with NISAM */ { error=my_errno; goto err; @@ -534,7 +534,7 @@ public: } ~delayed_insert() { - /* The following is not really neaded, but just for safety */ + /* The following is not really needed, but just for safety */ delayed_row *row; while ((row=rows.get())) delete row; @@ -868,6 +868,7 @@ void kill_delayed_threads(void) delayed_insert *tmp; while ((tmp=it++)) { + /* Ensure that the thread doesn't kill itself while we are looking at it */ pthread_mutex_lock(&tmp->mutex); tmp->thd.killed=1; if (tmp->thd.mysys_var) @@ -875,9 +876,15 @@ void kill_delayed_threads(void) pthread_mutex_lock(&tmp->thd.mysys_var->mutex); if (tmp->thd.mysys_var->current_cond) { - pthread_mutex_lock(tmp->thd.mysys_var->current_mutex); + /* + We need the following test because the main mutex may be locked + in handle_delayed_insert() + */ + if (&tmp->mutex != tmp->thd.mysys_var->current_mutex) + pthread_mutex_lock(tmp->thd.mysys_var->current_mutex); pthread_cond_broadcast(tmp->thd.mysys_var->current_cond); - pthread_mutex_unlock(tmp->thd.mysys_var->current_mutex); + if (&tmp->mutex != tmp->thd.mysys_var->current_mutex) + pthread_mutex_unlock(tmp->thd.mysys_var->current_mutex); } pthread_mutex_unlock(&tmp->thd.mysys_var->mutex); } diff --git a/sql/sql_lex.h b/sql/sql_lex.h index 4d2441da246..6ccb0a6b059 100644 --- a/sql/sql_lex.h +++ b/sql/sql_lex.h @@ -22,7 +22,7 @@ class Table_ident; class sql_exchange; class LEX_COLUMN; -// The following hack is neaded because mysql_yacc.cc does not define +// The following hack is needed because mysql_yacc.cc does not define // YYSTYPE before including this file #ifdef MYSQL_YACC @@ -56,7 +56,7 @@ enum enum_sql_command { SQLCOM_SHOW_OPEN_TABLES, SQLCOM_LOAD_MASTER_DATA, SQLCOM_HA_OPEN, SQLCOM_HA_CLOSE, SQLCOM_HA_READ, SQLCOM_SHOW_SLAVE_HOSTS, SQLCOM_MULTI_DELETE, - SQLCOM_SHOW_BINLOG_EVENTS, SQLCOM_SHOW_NEW_MASTER, + SQLCOM_SHOW_BINLOG_EVENTS, SQLCOM_SHOW_NEW_MASTER }; enum lex_states { STATE_START, STATE_CHAR, STATE_IDENT, @@ -145,6 +145,8 @@ typedef struct st_lex { char *length,*dec,*change,*name; char *backup_dir; /* For RESTORE/BACKUP */ char* to_log; /* For PURGE MASTER LOGS TO */ + char* x509_subject,*x509_issuer,*ssl_cipher; + enum SSL_type ssl_type; /* defined in violite.h */ String *wild; sql_exchange *exchange; diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc index c6e23eb927a..cdf6cb8e7f1 100644 --- a/sql/sql_parse.cc +++ b/sql/sql_parse.cc @@ -115,7 +115,7 @@ static bool check_user(THD *thd,enum_server_command command, const char *user, send_error(net,ER_OUT_OF_RESOURCES); return 1; } - thd->master_access=acl_getroot(thd->host, thd->ip, thd->user, + thd->master_access=acl_getroot(thd, thd->host, thd->ip, thd->user, passwd, thd->scramble, &thd->priv_user, protocol_version == 9 || !(thd->client_capabilities & @@ -433,7 +433,7 @@ check_connections(THD *thd) DBUG_PRINT("info", ("Agreed to change IO layer to SSL") ); /* Do the SSL layering. */ DBUG_PRINT("info", ("IO layer change in progress...")); - sslaccept(ssl_acceptor_fd, net->vio); + sslaccept(ssl_acceptor_fd, net->vio, (long)60L); DBUG_PRINT("info", ("Reading user information over SSL layer")); if ((pkt_len=my_net_read(net)) == packet_error || pkt_len < NORMAL_HANDSHAKE_SIZE) @@ -633,6 +633,7 @@ pthread_handler_decl(handle_bootstrap,arg) length--; buff[length]=0; thd->current_tablenr=0; + thd->query_length=length; thd->query= thd->memdup(buff,length+1); thd->query_id=query_id++; mysql_parse(thd,thd->query,length); @@ -692,19 +693,18 @@ int mysql_table_dump(THD* thd, char* db, char* tbl_name, int fd) thd->free_list = 0; thd->query = tbl_name; - if((error = mysqld_dump_create_info(thd, table, -1))) - { - my_error(ER_GET_ERRNO, MYF(0)); - goto err; - } + thd->query_length=strlen(tbl_name); + if ((error = mysqld_dump_create_info(thd, table, -1))) + { + my_error(ER_GET_ERRNO, MYF(0)); + goto err; + } net_flush(&thd->net); if ((error = table->file->dump(thd,fd))) my_error(ER_GET_ERRNO, MYF(0)); err: - close_thread_tables(thd); - DBUG_RETURN(error); } @@ -855,7 +855,7 @@ bool dispatch_command(enum enum_server_command command, THD *thd, DBUG_PRINT("info",("query ready")); break; } - case COM_FIELD_LIST: // This isn't actually neaded + case COM_FIELD_LIST: // This isn't actually needed #ifdef DONT_ALLOW_SHOW_COMMANDS send_error(&thd->net,ER_NOT_ALLOWED_COMMAND); /* purecov: inspected */ break; @@ -872,6 +872,7 @@ bool dispatch_command(enum enum_server_command command, THD *thd, thd->free_list=0; table_list.name=table_list.real_name=thd->strdup(packet); thd->query=fields=thd->strdup(strend(packet)+1); + thd->query_length=strlen(thd->query); mysql_log.write(thd,command,"%s %s",table_list.real_name,fields); remove_escape(table_list.real_name); // This can't have wildcards @@ -2052,9 +2053,9 @@ mysql_execute_command(void) goto error; res = mysql_table_grant(thd,tables,lex->users_list, lex->columns, lex->grant, lex->sql_command == SQLCOM_REVOKE); - if(!res) + if (!res) { - mysql_update_log.write(thd, thd->query,thd->query_length); + mysql_update_log.write(thd, thd->query, thd->query_length); if (mysql_bin_log.is_open()) { Query_log_event qinfo(thd, thd->query); @@ -2074,7 +2075,7 @@ mysql_execute_command(void) lex->sql_command == SQLCOM_REVOKE); if (!res) { - mysql_update_log.write(thd, thd->query,thd->query_length); + mysql_update_log.write(thd, thd->query, thd->query_length); if (mysql_bin_log.is_open()) { Query_log_event qinfo(thd, thd->query); @@ -2390,7 +2391,7 @@ bool my_yyoverflow(short **yyss, YYSTYPE **yyvs, int *yystacksize) /**************************************************************************** - Initialize global thd variables neaded for query + Initialize global thd variables needed for query ****************************************************************************/ static void @@ -3051,7 +3052,7 @@ static void refresh_status(void) static bool append_file_to_dir(char **filename_ptr, char *table_name) { - char buff[FN_REFLEN],*ptr; + char buff[FN_REFLEN],*ptr, *end; if (!*filename_ptr) return 0; // nothing to do @@ -3064,8 +3065,8 @@ static bool append_file_to_dir(char **filename_ptr, char *table_name) } /* Fix is using unix filename format on dos */ strmov(buff,*filename_ptr); - convert_dirname(buff); - if (!(ptr=sql_alloc(strlen(buff)+strlen(table_name)+1))) + end=convert_dirname(buff, *filename_ptr, NullS); + if (!(ptr=sql_alloc((uint) (end-buff)+strlen(table_name)+1))) return 1; // End of memory *filename_ptr=ptr; strxmov(ptr,buff,table_name,NullS); diff --git a/sql/sql_repl.cc b/sql/sql_repl.cc index f274d1ff91e..6123ecfea91 100644 --- a/sql/sql_repl.cc +++ b/sql/sql_repl.cc @@ -1623,6 +1623,7 @@ int log_loaded_block(IO_CACHE* file) block_len); mysql_bin_log.write(&c); lf_info->wrote_create_file = 1; + DBUG_SYNC_POINT("debug_lock.created_file_event",10); } return 0; } diff --git a/sql/sql_select.cc b/sql/sql_select.cc index 3aa534222e7..53d83c350ea 100644 --- a/sql/sql_select.cc +++ b/sql/sql_select.cc @@ -107,7 +107,6 @@ static uint find_shortest_key(TABLE *table, key_map usable_keys); static bool test_if_skip_sort_order(JOIN_TAB *tab,ORDER *order, ha_rows select_limit, bool no_changes); static int create_sort_index(JOIN_TAB *tab,ORDER *order,ha_rows select_limit); -static bool fix_having(JOIN *join, Item **having); static int remove_duplicates(JOIN *join,TABLE *entry,List<Item> &fields, Item *having); static int remove_dup_with_compare(THD *thd, TABLE *entry, Field **field, @@ -2332,7 +2331,20 @@ make_join_select(JOIN *join,SQL_SELECT *select,COND *cond) { JOIN_TAB *tab=join->join_tab+i; table_map current_map= tab->table->map; + bool use_quick_range=0; used_tables|=current_map; + + if (tab->type == JT_REF && tab->quick && + tab->ref.key_length < tab->quick->max_used_key_length) + { + /* Range uses longer key; Use this instead of ref on key */ + tab->type=JT_ALL; + use_quick_range=1; + tab->use_quick=1; + tab->ref.key_parts=0; // Don't use ref key. + join->best_positions[i].records_read=tab->quick->records; + } + COND *tmp=make_cond_for_table(cond,used_tables,current_map); if (!tmp && tab->quick) { // Outer join @@ -2375,7 +2387,7 @@ make_join_select(JOIN *join,SQL_SELECT *select,COND *cond) if (tab->const_keys && tab->table->reginfo.impossible_range) DBUG_RETURN(1); } - else if (tab->type == JT_ALL) + else if (tab->type == JT_ALL && ! use_quick_range) { if (tab->const_keys && tab->table->reginfo.impossible_range) @@ -2434,15 +2446,6 @@ make_join_select(JOIN *join,SQL_SELECT *select,COND *cond) } } } - if (tab->type == JT_REF && sel->quick && - tab->ref.key_length < sel->quick->max_used_key_length) - { - /* Range uses longer key; Use this instead of ref on key */ - tab->type=JT_ALL; - tab->use_quick=1; - tab->ref.key_parts=0; // Don't use ref key. - join->best_positions[i].records_read=sel->quick->records; - } } } } @@ -2486,7 +2489,8 @@ make_join_readinfo(JOIN *join,uint options) table->file->index_init(tab->ref.key); tab->read_first_record= join_read_key; tab->read_record.read_record= join_no_more_records; - if (table->used_keys & ((key_map) 1 << tab->ref.key)) + if (table->used_keys & ((key_map) 1 << tab->ref.key) && + !table->no_keyread) { table->key_read=1; table->file->extra(HA_EXTRA_KEYREAD); @@ -2504,7 +2508,8 @@ make_join_readinfo(JOIN *join,uint options) table->file->index_init(tab->ref.key); tab->read_first_record= join_read_always_key; tab->read_record.read_record= join_read_next; - if (table->used_keys & ((key_map) 1 << tab->ref.key)) + if (table->used_keys & ((key_map) 1 << tab->ref.key) && + !table->no_keyread) { table->key_read=1; table->file->extra(HA_EXTRA_KEYREAD); @@ -2565,18 +2570,21 @@ make_join_readinfo(JOIN *join,uint options) statistic_increment(select_full_join_count, &LOCK_status); } } - if (tab->select && tab->select->quick && - table->used_keys & ((key_map) 1 << tab->select->quick->index)) + if (!table->no_keyread) { - table->key_read=1; - table->file->extra(HA_EXTRA_KEYREAD); - } - else if (table->used_keys && ! (tab->select && tab->select->quick)) - { // Only read index tree - tab->index=find_shortest_key(table, table->used_keys); - tab->table->file->index_init(tab->index); - tab->read_first_record= join_init_read_first_with_key; - tab->type=JT_NEXT; // Read with index_first / index_next + if (tab->select && tab->select->quick && + table->used_keys & ((key_map) 1 << tab->select->quick->index)) + { + table->key_read=1; + table->file->extra(HA_EXTRA_KEYREAD); + } + else if (table->used_keys && ! (tab->select && tab->select->quick)) + { // Only read index tree + tab->index=find_shortest_key(table, table->used_keys); + tab->table->file->index_init(tab->index); + tab->read_first_record= join_init_read_first_with_key; + tab->type=JT_NEXT; // Read with index_first / index_next + } } } break; @@ -2637,7 +2645,8 @@ join_free(JOIN *join) } join->group_fields.delete_elements(); join->tmp_table_param.copy_funcs.delete_elements(); - delete [] join->tmp_table_param.copy_field; + if (join->tmp_table_param.copy_field) // Because of bug in ecc + delete [] join->tmp_table_param.copy_field; join->tmp_table_param.copy_field=0; DBUG_VOID_RETURN; } @@ -3306,7 +3315,7 @@ Field *create_tmp_field(TABLE *table,Item *item, Item::Type type, item->name,table,item_sum->decimals); case INT_RESULT: return new Field_longlong(item_sum->max_length,maybe_null, - item->name,table); + item->name,table,item->unsigned_flag); case STRING_RESULT: if (item_sum->max_length > 255) return new Field_blob(item_sum->max_length,maybe_null, @@ -3357,7 +3366,7 @@ Field *create_tmp_field(TABLE *table,Item *item, Item::Type type, break; case INT_RESULT: new_field=new Field_longlong(item->max_length,maybe_null, - item->name,table); + item->name,table, item->unsigned_flag); break; case STRING_RESULT: if (item->max_length > 255) @@ -4553,7 +4562,8 @@ join_init_read_first_with_key(JOIN_TAB *tab) { int error; TABLE *table=tab->table; - if (!table->key_read && (table->used_keys & ((key_map) 1 << tab->index))) + if (!table->key_read && (table->used_keys & ((key_map) 1 << tab->index)) && + !table->no_keyread) { table->key_read=1; table->file->extra(HA_EXTRA_KEYREAD); @@ -5439,39 +5449,6 @@ err: DBUG_RETURN(-1); } - -/* -** Add the HAVING criteria to table->select -*/ - -static bool fix_having(JOIN *join, Item **having) -{ - (*having)->update_used_tables(); // Some tables may have been const - JOIN_TAB *table=&join->join_tab[join->const_tables]; - table_map used_tables= join->const_table_map | table->table->map; - - Item* sort_table_cond=make_cond_for_table(*having,used_tables,used_tables); - if (sort_table_cond) - { - if (!table->select) - if (!(table->select=new SQL_SELECT)) - return 1; - if (!table->select->cond) - table->select->cond=sort_table_cond; - else // This should never happen - if (!(table->select->cond=new Item_cond_and(table->select->cond, - sort_table_cond))) - return 1; - table->select_cond=table->select->cond; - DBUG_EXECUTE("where",print_where(table->select_cond, - "select and having");); - *having=make_cond_for_table(*having,~ (table_map) 0,~used_tables); - DBUG_EXECUTE("where",print_where(*having,"having after make_cond");); - } - return 0; -} - - /***************************************************************************** ** Remove duplicates from tmp table ** This should be recoded to add a uniuqe index to the table and remove @@ -6419,7 +6396,7 @@ setup_copy_fields(TMP_TABLE_PARAM *param,List<Item> &fields) DBUG_ENTER("setup_copy_fields"); if (!(copy=param->copy_field= new Copy_field[param->field_count])) - goto err; + goto err2; param->copy_funcs.empty(); while ((pos=li++)) @@ -6468,8 +6445,9 @@ setup_copy_fields(TMP_TABLE_PARAM *param,List<Item> &fields) DBUG_RETURN(0); err: - delete [] param->copy_field; + delete [] param->copy_field; // This is never 0 param->copy_field=0; +err2: DBUG_RETURN(TRUE); } diff --git a/sql/sql_show.cc b/sql/sql_show.cc index b51e9ab5a73..5a9777e24a4 100644 --- a/sql/sql_show.cc +++ b/sql/sql_show.cc @@ -17,7 +17,6 @@ /* Function with list databases, tables or fields */ -#include "my_global.h" #include "mysql_priv.h" #include "sql_select.h" // For select_describe #include "sql_acl.h" @@ -391,7 +390,7 @@ int mysqld_extend_show_tables(THD *thd,const char *db,const char *wild) if (table->db_create_options & HA_OPTION_DELAY_KEY_WRITE) ptr=strmov(ptr," delay_key_write=1"); if (table->row_type != ROW_TYPE_DEFAULT) - ptr=strxmov(ptr, " format=", ha_row_type[(uint) table->row_type], + ptr=strxmov(ptr, " row_format=", ha_row_type[(uint) table->row_type], NullS); if (file->raid_type) { @@ -760,17 +759,16 @@ mysqld_dump_create_info(THD *thd, TABLE *table, int fd) convert->convert((char*) packet->ptr(), packet->length()); if (fd < 0) { - if(my_net_write(&thd->net, (char*)packet->ptr(), packet->length())) + if (my_net_write(&thd->net, (char*)packet->ptr(), packet->length())) DBUG_RETURN(-1); VOID(net_flush(&thd->net)); } else { - if(my_write(fd, (const byte*) packet->ptr(), packet->length(), - MYF(MY_WME))) + if (my_write(fd, (const byte*) packet->ptr(), packet->length(), + MYF(MY_WME))) DBUG_RETURN(-1); } - DBUG_RETURN(0); } @@ -920,6 +918,12 @@ store_create_info(THD *thd, TABLE *table, String *packet) p = longlong10_to_str(table->max_rows, buff, 10); packet->append(buff, (uint) (p - buff)); } + if (table->avg_row_length) + { + packet->append(" AVG_ROW_LENGTH="); + p=longlong10_to_str(table->avg_row_length, buff,10); + packet->append(buff, (uint) (p - buff)); + } if (table->db_create_options & HA_OPTION_PACK_KEYS) packet->append(" PACK_KEYS=1", 12); @@ -929,6 +933,11 @@ store_create_info(THD *thd, TABLE *table, String *packet) packet->append(" CHECKSUM=1", 11); if (table->db_create_options & HA_OPTION_DELAY_KEY_WRITE) packet->append(" DELAY_KEY_WRITE=1",18); + if (table->row_type != ROW_TYPE_DEFAULT) + { + packet->append(" ROW_FORMAT=",12); + packet->append(ha_row_type[(uint) table->row_type]); + } table->file->append_create_info(packet); if (table->comment && table->comment[0]) { @@ -1174,18 +1183,46 @@ int mysqld_show(THD *thd, const char *wild, show_var_st *variables) net_store_data(&packet2,(uint32) SSL_CTX_sess_accept_good(ssl_acceptor_fd->ssl_context_)); break; + case SHOW_SSL_CTX_SESS_CONNECT_GOOD: + net_store_data(&packet2,(uint32) + SSL_CTX_sess_connect_good(ssl_acceptor_fd->ssl_context_)); + break; case SHOW_SSL_CTX_SESS_ACCEPT_RENEGOTIATE: net_store_data(&packet2,(uint32) SSL_CTX_sess_accept_renegotiate(ssl_acceptor_fd->ssl_context_)); break; + case SHOW_SSL_CTX_SESS_CONNECT_RENEGOTIATE: + net_store_data(&packet2,(uint32) + SSL_CTX_sess_connect_renegotiate(ssl_acceptor_fd->ssl_context_)); + break; case SHOW_SSL_CTX_SESS_CB_HITS: net_store_data(&packet2,(uint32) SSL_CTX_sess_cb_hits(ssl_acceptor_fd->ssl_context_)); break; + case SHOW_SSL_CTX_SESS_HITS: + net_store_data(&packet2,(uint32) + SSL_CTX_sess_hits(ssl_acceptor_fd->ssl_context_)); + break; + case SHOW_SSL_CTX_SESS_CACHE_FULL: + net_store_data(&packet2,(uint32) + SSL_CTX_sess_cache_full(ssl_acceptor_fd->ssl_context_)); + break; + case SHOW_SSL_CTX_SESS_MISSES: + net_store_data(&packet2,(uint32) + SSL_CTX_sess_misses(ssl_acceptor_fd->ssl_context_)); + break; + case SHOW_SSL_CTX_SESS_TIMEOUTS: + net_store_data(&packet2,(uint32) + SSL_CTX_sess_timeouts(ssl_acceptor_fd->ssl_context_)); + break; case SHOW_SSL_CTX_SESS_NUMBER: net_store_data(&packet2,(uint32) SSL_CTX_sess_number(ssl_acceptor_fd->ssl_context_)); break; + case SHOW_SSL_CTX_SESS_CONNECT: + net_store_data(&packet2,(uint32) + SSL_CTX_sess_connect(ssl_acceptor_fd->ssl_context_)); + break; case SHOW_SSL_CTX_SESS_GET_CACHE_SIZE: net_store_data(&packet2,(uint32) SSL_CTX_sess_get_cache_size(ssl_acceptor_fd->ssl_context_)); @@ -1247,6 +1284,23 @@ int mysqld_show(THD *thd, const char *wild, show_var_st *variables) break; case SHOW_SSL_GET_CIPHER: net_store_data(&packet2, thd->net.vio->ssl_ ? SSL_get_cipher(thd->net.vio->ssl_) : ""); + case SHOW_SSL_GET_CIPHER_LIST: + if(thd->net.vio->ssl_) + { + char buf[1024]=""; + for (int i=0; ; i++) + { + const char *p=SSL_get_cipher_list(thd->net.vio->ssl_,i); + if (p == NULL) + break; + if (i != 0) + strcat(buf,":"); + strcat(buf,p); + DBUG_PRINT("info",("cipher to add: %s,%s",p,buf)); + } + net_store_data(&packet2, buf); + } else + net_store_data(&packet2, ""); break; #endif /* HAVE_OPENSSL */ diff --git a/sql/sql_table.cc b/sql/sql_table.cc index ad9bf532268..99c2b837480 100644 --- a/sql/sql_table.cc +++ b/sql/sql_table.cc @@ -841,7 +841,8 @@ static int prepare_for_restore(THD* thd, TABLE_LIST* table) char* table_name = table->name; char* db = thd->db ? thd->db : table->db; - if (!fn_format(src_path, table_name, backup_dir, reg_ext, 4 + 64)) + if (fn_format_relative_to_data_home(src_path, table_name, backup_dir, + reg_ext)) DBUG_RETURN(-1); // protect buffer overflow sprintf(dst_path, "%s/%s/%s", mysql_real_data_home, db, table_name); @@ -850,9 +851,8 @@ static int prepare_for_restore(THD* thd, TABLE_LIST* table) DBUG_RETURN(-1); if (my_copy(src_path, - fn_format(dst_path, dst_path,"", - reg_ext, 4), - MYF(MY_WME))) + fn_format(dst_path, dst_path,"", reg_ext, 4), + MYF(MY_WME))) { unlock_table_name(thd, table); DBUG_RETURN(send_check_errmsg(thd, table, "restore", @@ -1110,7 +1110,7 @@ int mysql_alter_table(THD *thd,char *new_db, char *new_name, bool use_timestamp=0; ha_rows copied,deleted; ulonglong next_insert_id; - uint save_time_stamp,db_create_options; + uint save_time_stamp,db_create_options, used_fields; enum db_type old_db_type,new_db_type; DBUG_ENTER("mysql_alter_table"); @@ -1119,6 +1119,7 @@ int mysql_alter_table(THD *thd,char *new_db, char *new_name, db=table_list->db; if (!new_db) new_db=db; + used_fields=create_info->used_fields; if (!(table=open_ltable(thd,table_list,TL_WRITE_ALLOW_READ))) DBUG_RETURN(-1); @@ -1164,7 +1165,7 @@ int mysql_alter_table(THD *thd,char *new_db, char *new_name, if (create_info->db_type == DB_TYPE_DEFAULT) create_info->db_type=old_db_type; new_db_type=create_info->db_type= ha_checktype(create_info->db_type); - if (create_info->row_type == ROW_TYPE_DEFAULT) + if (create_info->row_type == ROW_TYPE_NOT_USED) create_info->row_type=table->row_type; /* In some simple cases we need not to recreate the table */ @@ -1252,7 +1253,7 @@ int mysql_alter_table(THD *thd,char *new_db, char *new_name, { /* Reset auto_increment value if it was dropped */ if (MTYP_TYPENR(field->unireg_check) == Field::NEXT_NUMBER && - !(create_info->used_fields & HA_CREATE_USED_AUTO)) + !(used_fields & HA_CREATE_USED_AUTO)) { create_info->auto_increment_value=0; create_info->used_fields|=HA_CREATE_USED_AUTO; @@ -1438,20 +1439,25 @@ int mysql_alter_table(THD *thd,char *new_db, char *new_name, goto err; } + db_create_options=table->db_create_options & ~(HA_OPTION_PACK_RECORD); (void) sprintf(tmp_name,"%s-%lx_%lx", tmp_file_prefix, current_pid, thd->thread_id); create_info->db_type=new_db_type; - if (!create_info->max_rows) - create_info->max_rows=table->max_rows; - if (!create_info->avg_row_length) - create_info->avg_row_length=table->avg_row_length; - table->file->update_create_info(create_info); if (!create_info->comment) create_info->comment=table->comment; + /* let new create options override the old ones */ - db_create_options=table->db_create_options & ~(HA_OPTION_PACK_RECORD); - if (create_info->table_options & - (HA_OPTION_PACK_KEYS | HA_OPTION_NO_PACK_KEYS)) + if (!(used_fields & HA_CREATE_USED_MIN_ROWS)) + create_info->min_rows=table->min_rows; + if (!(used_fields & HA_CREATE_USED_MAX_ROWS)) + create_info->max_rows=table->max_rows; + if (!(used_fields & HA_CREATE_USED_AVG_ROW_LENGTH)) + create_info->avg_row_length=table->avg_row_length; + + table->file->update_create_info(create_info); + if ((create_info->table_options & + (HA_OPTION_PACK_KEYS | HA_OPTION_NO_PACK_KEYS)) || + (used_fields & HA_CREATE_USED_PACK_KEYS)) db_create_options&= ~(HA_OPTION_PACK_KEYS | HA_OPTION_NO_PACK_KEYS); if (create_info->table_options & (HA_OPTION_CHECKSUM | HA_OPTION_NO_CHECKSUM)) @@ -1808,7 +1814,7 @@ copy_data_between_tables(TABLE *from,TABLE *to, } end_read_record(&info); free_io_cache(from); - delete [] copy; + delete [] copy; // This is never 0 uint tmp_error; if ((tmp_error=to->file->extra(HA_EXTRA_NO_CACHE))) { diff --git a/sql/sql_union.cc b/sql/sql_union.cc index 5dd897ee826..c0ec6c81575 100644 --- a/sql/sql_union.cc +++ b/sql/sql_union.cc @@ -31,7 +31,7 @@ int mysql_union(THD *thd, LEX *lex,select_result *result) ORDER *order; List<Item> item_list; TABLE *table; - TABLE_LIST *first_table, result_table_list; + TABLE_LIST result_table_list; TMP_TABLE_PARAM tmp_table_param; select_union *union_result; int res; @@ -75,9 +75,9 @@ int mysql_union(THD *thd, LEX *lex,select_result *result) { Item *item; List_iterator<Item> it(lex->select_lex.item_list); + TABLE_LIST *first_table= (TABLE_LIST*) lex->select_lex.table_list.first; /* Create a list of items that will be in the result set */ - first_table= (TABLE_LIST*) lex->select_lex.table_list.first; while ((item= it++)) if (item_list.push_back(item)) DBUG_RETURN(-1); diff --git a/sql/sql_yacc.yy b/sql/sql_yacc.yy index 5be1b86e8ab..7d084f5878e 100644 --- a/sql/sql_yacc.yy +++ b/sql/sql_yacc.yy @@ -27,6 +27,7 @@ #include "sql_acl.h" #include "lex_symbol.h" #include <myisam.h> +#include <myisammrg.h> extern void yyerror(const char*); int yylex(void *yylval); @@ -98,7 +99,7 @@ bool my_yyoverflow(short **a, YYSTYPE **b,int *yystacksize); %token MIN_SYM %token SUM_SYM %token STD_SYM - +%token ABORT_SYM %token ADD %token ALTER %token AFTER_SYM @@ -134,7 +135,6 @@ bool my_yyoverflow(short **a, YYSTYPE **b,int *yystacksize); %token BINLOG_SYM %token EVENTS_SYM -%token ABORT_SYM %token ACTION %token AGGREGATE_SYM %token ALL @@ -285,6 +285,7 @@ bool my_yyoverflow(short **a, YYSTYPE **b,int *yystacksize); %token SERIALIZABLE_SYM %token SESSION_SYM %token SHUTDOWN +%token SSL_SYM %token STARTING %token STATUS_SYM %token STRAIGHT_JOIN @@ -316,6 +317,7 @@ bool my_yyoverflow(short **a, YYSTYPE **b,int *yystacksize); %token WHERE %token WITH %token WRITE_SYM +%token X509_SYM %token COMPRESSED_SYM %token BIGINT @@ -391,6 +393,7 @@ bool my_yyoverflow(short **a, YYSTYPE **b,int *yystacksize); %token IDENTIFIED_SYM %token IF %token INSERT_ID +%token INSERT_METHOD %token INTERVAL_SYM %token LAST_INSERT_ID %token LEFT @@ -450,6 +453,10 @@ bool my_yyoverflow(short **a, YYSTYPE **b,int *yystacksize); %token SQL_QUOTE_SHOW_CREATE %token SQL_SLAVE_SKIP_COUNTER +%token ISSUER_SYM +%token SUBJECT_SYM +%token CIPHER_SYM + %left SET_VAR %left OR_OR_CONCAT OR %left AND @@ -487,7 +494,7 @@ bool my_yyoverflow(short **a, YYSTYPE **b,int *yystacksize); table_option opt_if_not_exists %type <ulong_num> - ULONG_NUM raid_types + ULONG_NUM raid_types merge_insert_types %type <ulonglong_number> ulonglong_num @@ -767,13 +774,14 @@ create_table_options: create_table_option: TYPE_SYM EQ table_types { Lex->create_info.db_type= $3; } - | MAX_ROWS EQ ulonglong_num { Lex->create_info.max_rows= $3; } - | MIN_ROWS EQ ulonglong_num { Lex->create_info.min_rows= $3; } - | AVG_ROW_LENGTH EQ ULONG_NUM { Lex->create_info.avg_row_length=$3; } + | MAX_ROWS EQ ulonglong_num { Lex->create_info.max_rows= $3; Lex->create_info.used_fields|= HA_CREATE_USED_MAX_ROWS;} + | MIN_ROWS EQ ulonglong_num { Lex->create_info.min_rows= $3; Lex->create_info.used_fields|= HA_CREATE_USED_MIN_ROWS;} + | AVG_ROW_LENGTH EQ ULONG_NUM { Lex->create_info.avg_row_length=$3; Lex->create_info.used_fields|= HA_CREATE_USED_AVG_ROW_LENGTH;} | PASSWORD EQ TEXT_STRING { Lex->create_info.password=$3.str; } | COMMENT_SYM EQ TEXT_STRING { Lex->create_info.comment=$3.str; } | AUTO_INC EQ ulonglong_num { Lex->create_info.auto_increment_value=$3; Lex->create_info.used_fields|= HA_CREATE_USED_AUTO;} - | PACK_KEYS_SYM EQ ULONG_NUM { Lex->create_info.table_options|= $3 ? HA_OPTION_PACK_KEYS : HA_OPTION_NO_PACK_KEYS; } + | PACK_KEYS_SYM EQ ULONG_NUM { Lex->create_info.table_options|= $3 ? HA_OPTION_PACK_KEYS : HA_OPTION_NO_PACK_KEYS; Lex->create_info.used_fields|= HA_CREATE_USED_PACK_KEYS;} + | PACK_KEYS_SYM EQ DEFAULT { Lex->create_info.table_options&= ~(HA_OPTION_PACK_KEYS | HA_OPTION_NO_PACK_KEYS); Lex->create_info.used_fields|= HA_CREATE_USED_PACK_KEYS;} | CHECKSUM_SYM EQ ULONG_NUM { Lex->create_info.table_options|= $3 ? HA_OPTION_CHECKSUM : HA_OPTION_NO_CHECKSUM; } | DELAY_KEY_WRITE_SYM EQ ULONG_NUM { Lex->create_info.table_options|= $3 ? HA_OPTION_DELAY_KEY_WRITE : HA_OPTION_NO_DELAY_KEY_WRITE; } | ROW_FORMAT_SYM EQ row_types { Lex->create_info.row_type= $3; } @@ -793,6 +801,7 @@ create_table_option: table_list->next=0; lex->create_info.used_fields|= HA_CREATE_USED_UNION; } + | INSERT_METHOD EQ merge_insert_types { Lex->create_info.merge_insert_method= $3; Lex->create_info.used_fields|= HA_CREATE_USED_INSERT_METHOD;} | DATA_SYM DIRECTORY_SYM EQ TEXT_STRING { Lex->create_info.data_file_name= $4.str; } | INDEX DIRECTORY_SYM EQ TEXT_STRING { Lex->create_info.index_file_name= $4.str; } @@ -816,6 +825,11 @@ raid_types: | RAID_0_SYM { $$= RAID_TYPE_0; } | ULONG_NUM { $$=$1;} +merge_insert_types: + NO_SYM { $$= MERGE_INSERT_DISABLED; } + | FIRST_SYM { $$= MERGE_INSERT_TO_FIRST; } + | LAST_SYM { $$= MERGE_INSERT_TO_LAST; } + opt_select_from: /* empty */ | select_from select_lock_type @@ -1105,6 +1119,7 @@ alter: lex->select->db=lex->name=0; bzero((char*) &lex->create_info,sizeof(lex->create_info)); lex->create_info.db_type= DB_TYPE_DEFAULT; + lex->create_info.row_type= ROW_TYPE_NOT_USED; lex->alter_keys_onoff=LEAVE_AS_IS; lex->simple_alter=1; } @@ -2819,6 +2834,7 @@ keyword: | CHANGED {} | CHECKSUM_SYM {} | CHECK_SYM {} + | CIPHER_SYM {} | CLOSE_SYM {} | COMMENT_SYM {} | COMMIT_SYM {} @@ -2856,7 +2872,9 @@ keyword: | INDEXES {} | ISOLATION {} | ISAM_SYM {} + | ISSUER_SYM {} | INNOBASE_SYM {} + | INSERT_METHOD {} | LAST_SYM {} | LEVEL_SYM {} | LOCAL_SYM {} @@ -2882,6 +2900,7 @@ keyword: | NATIONAL_SYM {} | NCHAR_SYM {} | NEXT_SYM {} + | NEW_SYM {} | NO_SYM {} | OPEN_SYM {} | PACK_KEYS_SYM {} @@ -2909,10 +2928,12 @@ keyword: | SESSION_SYM {} | SHARE_SYM {} | SHUTDOWN {} + | SLAVE {} | START_SYM {} | STATUS_SYM {} | STOP_SYM {} | STRING_SYM {} + | SUBJECT_SYM {} | TEMPORARY {} | TEXT_SYM {} | TRANSACTION_SYM {} @@ -3129,8 +3150,8 @@ set_isolation: } | SESSION_SYM tx_isolation { - LEX *lex=Lex; - lex->thd->session_tx_isolation= lex->tx_isolation= $2; + LEX *lex=Lex; + lex->thd->session_tx_isolation= lex->tx_isolation= $2; } | tx_isolation { Lex->tx_isolation= $1; } @@ -3251,9 +3272,11 @@ grant: lex->columns.empty(); lex->grant= lex->grant_tot_col=0; lex->select->db=0; + lex->ssl_type=SSL_TYPE_NONE; + lex->ssl_cipher=lex->x509_subject=lex->x509_issuer=0; } grant_privileges ON opt_table TO_SYM user_list - grant_option + require_clause grant_option grant_privileges: grant_privilege_list {} @@ -3287,6 +3310,40 @@ grant_privilege: | FILE_SYM { Lex->grant |= FILE_ACL;} | GRANT OPTION { Lex->grant |= GRANT_ACL;} +require_list: require_list_element AND require_list +| require_list_element + +require_list_element: SUBJECT_SYM TEXT_STRING + { + LEX *lex=Lex; + if (lex->x509_subject) + { + net_printf(&lex->thd->net,ER_DUP_ARGUMENT, "SUBJECT"); + YYABORT; + } + lex->x509_subject=$2.str; + } + | ISSUER_SYM TEXT_STRING + { + LEX *lex=Lex; + if (lex->x509_issuer) + { + net_printf(&lex->thd->net,ER_DUP_ARGUMENT, "ISSUER"); + YYABORT; + } + lex->x509_issuer=$2.str; + } + | CIPHER_SYM TEXT_STRING + { + LEX *lex=Lex; + if (lex->ssl_cipher) + { + net_printf(&lex->thd->net,ER_DUP_ARGUMENT, "CHIPER"); + YYABORT; + } + lex->ssl_cipher=$2.str; + } + opt_table: '*' { @@ -3393,16 +3450,18 @@ column_list_id: require_clause: /* empty */ - | REQUIRE_SYM require_list { /* do magic */} - -require_list: require_list_element AND require_list - { /* do magic */} - | require_list_element {/*do magic*/} - -require_list_element: SUBJECT_SYM TEXT_STRING - | ISSUER TEXT_STRING - | CIPHER TEXT_STRING - + | REQUIRE_SYM require_list + { + Lex->ssl_type=SSL_TYPE_SPECIFIED; + } + | REQUIRE_SYM SSL_SYM + { + Lex->ssl_type=SSL_TYPE_ANY; + } + | REQUIRE_SYM X509_SYM + { + Lex->ssl_type=SSL_TYPE_X509; + } grant_option: /* empty */ {} @@ -3438,7 +3497,7 @@ union_list: if (lex->exchange) { /* Only the last SELECT can have INTO...... */ - net_printf(¤t_thd->net, ER_WRONG_USAGE,"UNION","INTO"); + net_printf(&lex->thd->net, ER_WRONG_USAGE,"UNION","INTO"); YYABORT; } mysql_new_select(lex); diff --git a/sql/structs.h b/sql/structs.h index 12ba5004a2e..2f6f850bc9e 100644 --- a/sql/structs.h +++ b/sql/structs.h @@ -134,7 +134,11 @@ enum SHOW_TYPE { SHOW_LONG,SHOW_CHAR,SHOW_INT,SHOW_CHAR_PTR,SHOW_BOOL, ,SHOW_SSL_CTX_SESS_GET_CACHE_SIZE, SHOW_SSL_GET_CIPHER ,SHOW_SSL_GET_DEFAULT_TIMEOUT, SHOW_SSL_GET_VERIFY_MODE ,SHOW_SSL_CTX_GET_VERIFY_MODE, SHOW_SSL_GET_VERIFY_DEPTH - ,SHOW_SSL_CTX_GET_VERIFY_DEPTH + ,SHOW_SSL_CTX_GET_VERIFY_DEPTH, SHOW_SSL_CTX_SESS_CONNECT + ,SHOW_SSL_CTX_SESS_CONNECT_RENEGOTIATE, SHOW_SSL_CTX_SESS_CONNECT_GOOD + ,SHOW_SSL_CTX_SESS_HITS, SHOW_SSL_CTX_SESS_MISSES + ,SHOW_SSL_CTX_SESS_TIMEOUTS, SHOW_SSL_CTX_SESS_CACHE_FULL + ,SHOW_SSL_GET_CIPHER_LIST #endif /* HAVE_OPENSSL */ }; @@ -170,7 +174,7 @@ typedef struct st_lex_user { /* Bits in form->status */ #define STATUS_NO_RECORD (1+2) /* Record isn't usably */ #define STATUS_GARBAGE 1 -#define STATUS_NOT_FOUND 2 /* No record in database when neaded */ +#define STATUS_NOT_FOUND 2 /* No record in database when needed */ #define STATUS_NO_PARENT 4 /* Parent record wasn't found */ #define STATUS_NOT_READ 8 /* Record isn't read */ #define STATUS_UPDATED 16 /* Record is updated by formula */ diff --git a/sql/table.cc b/sql/table.cc index eed4170c14a..1ed856f7854 100644 --- a/sql/table.cc +++ b/sql/table.cc @@ -455,8 +455,12 @@ int openfrm(const char *name, const char *alias, uint db_stat, uint prgflag, if (key == primary_key) { field->flags|= PRI_KEY_FLAG; + /* + If this field is part of the primary key and all keys contains + the primary key, then we can use any key to find this column + */ if (ha_option & HA_PRIMARY_KEY_IN_READ_INDEX) - field->part_of_key|= ((key_map) 1 << primary_key); + field->part_of_key= outparam->keys_in_use; } if (field->key_length() != key_part->length) { @@ -480,8 +484,6 @@ int openfrm(const char *name, const char *alias, uint db_stat, uint prgflag, (outparam->keys_in_use & ((key_map) 1 << primary_key))) { outparam->primary_key=primary_key; - if (outparam->file->option_flag() & HA_PRIMARY_KEY_IN_READ_INDEX) - outparam->ref_primary_key= (key_map) 1 << primary_key; /* If we are using an integer as the primary key then allow the user to refer to it as '_rowid' @@ -996,6 +998,7 @@ File create_frm(register my_string name, uint reclength, uchar *fileinfo, void update_create_info_from_table(HA_CREATE_INFO *create_info, TABLE *table) { + DBUG_ENTER("update_create_info_from_table"); create_info->max_rows=table->max_rows; create_info->min_rows=table->min_rows; create_info->table_options=table->db_create_options; @@ -1004,6 +1007,7 @@ void update_create_info_from_table(HA_CREATE_INFO *create_info, TABLE *table) create_info->raid_type=table->raid_type; create_info->raid_chunks=table->raid_chunks; create_info->raid_chunksize=table->raid_chunksize; + DBUG_VOID_RETURN; } int diff --git a/sql/table.h b/sql/table.h index 5d50851259d..071c447e660 100644 --- a/sql/table.h +++ b/sql/table.h @@ -97,6 +97,7 @@ struct st_table { my_bool locked_by_name; my_bool crashed; my_bool is_view; + my_bool no_keyread; Field *next_number_field, /* Set if next_number is activated */ *found_next_number_field, /* Set on open */ *rowid_field; @@ -117,7 +118,7 @@ struct st_table { byte *record_pointers; /* If sorted in memory */ ha_rows found_records; /* How many records in sort */ ORDER *group; - key_map quick_keys, used_keys, ref_primary_key; + key_map quick_keys, used_keys; ha_rows quick_rows[MAX_KEY]; uint quick_key_parts[MAX_KEY]; key_part_map const_key_parts[MAX_KEY]; diff --git a/sql/time.cc b/sql/time.cc index d1e0aee0fa4..440cba457f4 100644 --- a/sql/time.cc +++ b/sql/time.cc @@ -24,7 +24,7 @@ static ulong const days_at_timestart=719528; /* daynr at 1970.01.01 */ uchar *days_in_month= (uchar*) "\037\034\037\036\037\036\037\037\036\037\036\037"; - /* Init some variabels neaded when using my_local_time */ + /* Init some variabels needed when using my_local_time */ /* Currently only my_time_zone is inited */ static long my_time_zone=0; diff --git a/sql/udf_example.cc b/sql/udf_example.cc index 3a528a9ad3a..44a1d00437a 100644 --- a/sql/udf_example.cc +++ b/sql/udf_example.cc @@ -66,7 +66,7 @@ ** You can easily get all switches right by doing: ** cd sql ; make udf_example.o ** Take the compile line that make writes, remove the '-c' near the end of -** the line and add -o udf_example.so to the end of the compile line. +** the line and add -shared -o udf_example.so to the end of the compile line. ** The resulting library (udf_example.so) should be copied to some dir ** searched by ld. (/usr/lib ?) ** @@ -97,6 +97,13 @@ ** Active function will be reloaded on every restart of server ** (if --skip-grant-tables is not given) ** +** If you ge problems with undefined symbols when loading the shared +** library, you should verify that mysqld is compiled with the -rdynamic +** option. +** +** If you can't get AGGREGATES to work, check that you have the column +** 'type' in the mysql.func table. If not, run 'mysql_fix_privilege_tables'. +** */ #ifdef STANDARD @@ -128,6 +135,11 @@ my_bool sequence_init(UDF_INIT *initid, UDF_ARGS *args, char *message); void sequence_deinit(UDF_INIT *initid); long long sequence(UDF_INIT *initid, UDF_ARGS *args, char *is_null, char *error); +my_bool avgcost_init( UDF_INIT* initid, UDF_ARGS* args, char* message ); +void avgcost_deinit( UDF_INIT* initid ); +void avgcost_reset( UDF_INIT* initid, UDF_ARGS* args, char* is_null, char *error ); +void avgcost_add( UDF_INIT* initid, UDF_ARGS* args, char* is_null, char *error ); +double avgcost( UDF_INIT* initid, UDF_ARGS* args, char* is_null, char *error ); } @@ -766,6 +778,7 @@ char *reverse_lookup(UDF_INIT *initid, UDF_ARGS *args, char *result, *res_length=(ulong) (strmov(result,hp->h_name) - result); return result; } +#endif // defined(HAVE_GETHOSTBYADDR_R) && defined(HAVE_SOLARIS_STYLE_GETHOST) /* ** Syntax for the new aggregate commands are: @@ -777,13 +790,6 @@ char *reverse_lookup(UDF_INIT *initid, UDF_ARGS *args, char *result, ** (this example is provided by Andreas F. Bobak <bobak@relog.ch>) */ -extern "C" { -my_bool avgcost_init( UDF_INIT* initid, UDF_ARGS* args, char* message ); -void avgcost_deinit( UDF_INIT* initid ); -void avgcost_reset( UDF_INIT* initid, UDF_ARGS* args, char* is_null, char *error ); -void avgcost_add( UDF_INIT* initid, UDF_ARGS* args, char* is_null, char *error ); -double avgcost( UDF_INIT* initid, UDF_ARGS* args, char* is_null, char *error ); -} struct avgcost_data { @@ -810,7 +816,7 @@ avgcost_init( UDF_INIT* initid, UDF_ARGS* args, char* message ) return 1; } - if ((args->arg_type[0] != INT_RESULT) && (args->arg_type[1] != REAL_RESULT) ) + if ((args->arg_type[0] != INT_RESULT) || (args->arg_type[1] != REAL_RESULT) ) { strcpy( message, @@ -917,5 +923,4 @@ avgcost( UDF_INIT* initid, UDF_ARGS* args, char* is_null, char* error ) return data->totalprice/double(data->totalquantity); } -#endif // defined(HAVE_GETHOSTBYADDR_R) && defined(HAVE_SOLARIS_STYLE_GETHOST) #endif /* HAVE_DLOPEN */ diff --git a/sql/uniques.cc b/sql/uniques.cc index bd3ca6db0d0..fcee97dbb1a 100644 --- a/sql/uniques.cc +++ b/sql/uniques.cc @@ -35,6 +35,19 @@ #include "sql_sort.h" +int unique_write_to_file(gptr key, element_count count, Unique *unique) +{ + return my_b_write(&unique->file, (byte*) key, + unique->tree.size_of_element) ? 1 : 0; +} + +int unique_write_to_ptrs(gptr key, element_count count, Unique *unique) +{ + memcpy(unique->record_pointers, key, unique->tree.size_of_element); + unique->record_pointers+=unique->tree.size_of_element; + return 0; +} + Unique::Unique(qsort_cmp2 comp_func, void * comp_func_fixed_arg, uint size, ulong max_in_memory_size_arg) :max_in_memory_size(max_in_memory_size_arg),elements(0) @@ -73,20 +86,6 @@ bool Unique::flush() } -int unique_write_to_file(gptr key, element_count count, Unique *unique) -{ - return my_b_write(&unique->file, (byte*) key, - unique->tree.size_of_element) ? 1 : 0; -} - -int unique_write_to_ptrs(gptr key, element_count count, Unique *unique) -{ - memcpy(unique->record_pointers, key, unique->tree.size_of_element); - unique->record_pointers+=unique->tree.size_of_element; - return 0; -} - - /* Modify the TABLE element so that when one calls init_records() the rows will be read in priority order. diff --git a/sql/unireg.cc b/sql/unireg.cc index c5bfbbbea88..b0dd3471a64 100644 --- a/sql/unireg.cc +++ b/sql/unireg.cc @@ -20,7 +20,7 @@ struct. In the following functions FIELD * is an ordinary field-structure with the following exeptions: - sc_length,typepos,row,kol,dtype,regnr and field nead not to be set. + sc_length,typepos,row,kol,dtype,regnr and field need not to be set. str is a (long) to record position where 0 is the first position. */ @@ -391,8 +391,8 @@ static bool pack_header(uchar *forminfo, enum db_type table_type, int2store(forminfo+272,int_parts); int2store(forminfo+274,int_length); int2store(forminfo+276,time_stamp_pos); - int2store(forminfo+278,80); /* Columns neaded */ - int2store(forminfo+280,22); /* Rows neaded */ + int2store(forminfo+278,80); /* Columns needed */ + int2store(forminfo+280,22); /* Rows needed */ int2store(forminfo+282,null_fields); DBUG_RETURN(0); } /* pack_header */ |