diff options
-rw-r--r-- | client/mysql.cc | 8 | ||||
-rw-r--r-- | myisam/mi_delete.c | 4 | ||||
-rw-r--r-- | myisam/mi_delete_table.c | 3 | ||||
-rw-r--r-- | myisam/mi_extra.c | 3 | ||||
-rw-r--r-- | myisam/mi_locking.c | 3 | ||||
-rw-r--r-- | myisam/mi_log.c | 1 | ||||
-rw-r--r-- | myisam/mi_page.c | 3 | ||||
-rw-r--r-- | myisam/mi_rename.c | 3 | ||||
-rw-r--r-- | myisam/mi_update.c | 5 | ||||
-rw-r--r-- | myisam/mi_write.c | 4 | ||||
-rw-r--r-- | mysql-test/r/rpl_until.result | 2 | ||||
-rw-r--r-- | mysql-test/r/subselect.result | 4 | ||||
-rw-r--r-- | mysql-test/t/rpl_until.test | 6 | ||||
-rw-r--r-- | mysys/charset.c | 14 | ||||
-rw-r--r-- | sql/item_cmpfunc.cc | 15 | ||||
-rw-r--r-- | sql/item_cmpfunc.h | 4 | ||||
-rw-r--r-- | sql/item_func.cc | 10 | ||||
-rw-r--r-- | sql/mysqld.cc | 2 | ||||
-rw-r--r-- | sql/opt_range.cc | 21 | ||||
-rw-r--r-- | sql/opt_range.h | 1 | ||||
-rw-r--r-- | sql/set_var.cc | 10 | ||||
-rw-r--r-- | sql/slave.cc | 2 | ||||
-rw-r--r-- | sql/slave.h | 5 | ||||
-rw-r--r-- | sql/sql_acl.cc | 2 | ||||
-rw-r--r-- | sql/sql_class.cc | 110 | ||||
-rw-r--r-- | sql/sql_class.h | 30 | ||||
-rw-r--r-- | sql/sql_select.cc | 34 |
27 files changed, 160 insertions, 149 deletions
diff --git a/client/mysql.cc b/client/mysql.cc index 2cdcd23165e..665a8dde82d 100644 --- a/client/mysql.cc +++ b/client/mysql.cc @@ -44,7 +44,7 @@ #include <locale.h> #endif -const char *VER= "14.4"; +const char *VER= "14.5"; /* Don't try to make a nice table if the data is too big */ #define MAX_COLUMN_LENGTH 1024 @@ -2703,6 +2703,9 @@ com_status(String *buffer __attribute__((unused)), char *line __attribute__((unused))) { const char *status; + char buff[22]; + ulonglong id; + tee_puts("--------------", stdout); usage(1); /* Print version */ if (connected) @@ -2748,6 +2751,9 @@ com_status(String *buffer __attribute__((unused)), tee_fprintf(stdout, "Server version:\t\t%s\n", mysql_get_server_info(&mysql)); tee_fprintf(stdout, "Protocol version:\t%d\n", mysql_get_proto_info(&mysql)); tee_fprintf(stdout, "Connection:\t\t%s\n", mysql_get_host_info(&mysql)); + if ((id= mysql_insert_id(&mysql))) + tee_fprintf(stdout, "Insert id:\t\t%s\n", llstr(id, buff)); + tee_fprintf(stdout, "Client characterset:\t%s\n", charset_info->name); tee_fprintf(stdout, "Server characterset:\t%s\n", mysql.charset->name); diff --git a/myisam/mi_delete.c b/myisam/mi_delete.c index a55d5b2a5ca..19cfc050ea1 100644 --- a/myisam/mi_delete.c +++ b/myisam/mi_delete.c @@ -20,10 +20,6 @@ #include "rt_index.h" #include <assert.h> -#ifdef __WIN__ -#include <errno.h> -#endif - static int d_search(MI_INFO *info,MI_KEYDEF *keyinfo,uint comp_flag, uchar *key,uint key_length,my_off_t page,uchar *anc_buff); static int del(MI_INFO *info,MI_KEYDEF *keyinfo,uchar *key,uchar *anc_buff, diff --git a/myisam/mi_delete_table.c b/myisam/mi_delete_table.c index 6d842d7e6a4..6843881568d 100644 --- a/myisam/mi_delete_table.c +++ b/myisam/mi_delete_table.c @@ -19,9 +19,6 @@ */ #include "fulltext.h" -#ifdef __WIN__ -#include <errno.h> -#endif int mi_delete_table(const char *name) { diff --git a/myisam/mi_extra.c b/myisam/mi_extra.c index 10f52f1e39a..ce072d7d57e 100644 --- a/myisam/mi_extra.c +++ b/myisam/mi_extra.c @@ -18,9 +18,6 @@ #ifdef HAVE_MMAP #include <sys/mman.h> #endif -#ifdef __WIN__ -#include <errno.h> -#endif /* Set options and buffers to optimize table handling diff --git a/myisam/mi_locking.c b/myisam/mi_locking.c index 67ccca52d08..816748d459a 100644 --- a/myisam/mi_locking.c +++ b/myisam/mi_locking.c @@ -22,9 +22,6 @@ */ #include "myisamdef.h" -#ifdef __WIN__ -#include <errno.h> -#endif /* lock table by F_UNLCK, F_RDLCK or F_WRLCK */ diff --git a/myisam/mi_log.c b/myisam/mi_log.c index 1dcfd5250d2..13842c56828 100644 --- a/myisam/mi_log.c +++ b/myisam/mi_log.c @@ -21,7 +21,6 @@ #include "myisamdef.h" #if defined(MSDOS) || defined(__WIN__) -#include <errno.h> #include <fcntl.h> #ifndef __WIN__ #include <process.h> diff --git a/myisam/mi_page.c b/myisam/mi_page.c index c70209c2da6..16713c87e10 100644 --- a/myisam/mi_page.c +++ b/myisam/mi_page.c @@ -17,9 +17,6 @@ /* Read and write key blocks */ #include "myisamdef.h" -#ifdef __WIN__ -#include <errno.h> -#endif /* Fetch a key-page in memory */ diff --git a/myisam/mi_rename.c b/myisam/mi_rename.c index db44b8fe28f..8380ee1bfad 100644 --- a/myisam/mi_rename.c +++ b/myisam/mi_rename.c @@ -19,9 +19,6 @@ */ #include "fulltext.h" -#ifdef __WIN__ -#include <errno.h> -#endif int mi_rename(const char *old_name, const char *new_name) { diff --git a/myisam/mi_update.c b/myisam/mi_update.c index d1d41ac351a..f62be133ed9 100644 --- a/myisam/mi_update.c +++ b/myisam/mi_update.c @@ -19,11 +19,6 @@ #include "fulltext.h" #include "rt_index.h" -#ifdef __WIN__ -#include <errno.h> -#endif - - int mi_update(register MI_INFO *info, const byte *oldrec, byte *newrec) { int flag,key_changed,save_errno; diff --git a/myisam/mi_write.c b/myisam/mi_write.c index 060d4431de6..88e7f070642 100644 --- a/myisam/mi_write.c +++ b/myisam/mi_write.c @@ -20,10 +20,6 @@ #include "rt_index.h" #include <assert.h> -#ifdef __WIN__ -#include <errno.h> -#endif - #define MAX_POINTER_LENGTH 8 /* Functions declared in this file */ diff --git a/mysql-test/r/rpl_until.result b/mysql-test/r/rpl_until.result index c179351551d..82b1ed233ec 100644 --- a/mysql-test/r/rpl_until.result +++ b/mysql-test/r/rpl_until.result @@ -31,7 +31,7 @@ n 4 show slave status; Slave_IO_State Master_Host Master_User Master_Port Connect_Retry Master_Log_File Read_Master_Log_Pos Relay_Log_File Relay_Log_Pos Relay_Master_Log_File Slave_IO_Running Slave_SQL_Running Replicate_Do_DB Replicate_Ignore_DB Replicate_Do_Table Replicate_Ignore_Table Replicate_Wild_Do_Table Replicate_Wild_Ignore_Table Last_Errno Last_Error Skip_Counter Exec_Master_Log_Pos Relay_Log_Space Until_Condition Until_Log_File Until_Log_Pos Master_SSL_Allowed Master_SSL_CA_File Master_SSL_CA_Path Master_SSL_Cert Master_SSL_Cipher Master_SSL_Key Seconds_Behind_Master -# 127.0.0.1 root MASTER_MYPORT 1 master-bin.000001 561 slave-relay-bin.000002 332 master-bin.000001 Yes No 0 0 244 649 Master master-bin.000001 244 No # +# 127.0.0.1 root MASTER_MYPORT 1 master-bin.000001 561 slave-relay-bin.000002 # master-bin.000001 Yes No 0 0 244 # Master master-bin.000001 244 No # start slave until master_log_file='master-no-such-bin.000001', master_log_pos=291; select * from t1; n diff --git a/mysql-test/r/subselect.result b/mysql-test/r/subselect.result index c5050cf5f27..c06c9824b33 100644 --- a/mysql-test/r/subselect.result +++ b/mysql-test/r/subselect.result @@ -1340,8 +1340,8 @@ a explain extended select * from t2 where t2.a in (select t1.a from t1,t3 where t1.b=t3.a); id select_type table type possible_keys key key_len ref rows Extra 1 PRIMARY t2 index NULL a 5 NULL 4 Using where; Using index -2 DEPENDENT SUBQUERY t3 index a a 5 NULL 3 Using index -2 DEPENDENT SUBQUERY t1 ref a a 10 func,test.t3.a 1000 Using where; Using index +2 DEPENDENT SUBQUERY t1 ref a a 5 func 1001 Using where; Using index +2 DEPENDENT SUBQUERY t3 index a a 5 NULL 3 Using where; Using index Warnings: Note 1003 select high_priority test.t2.a AS `a` from test.t2 where <in_optimizer>(test.t2.a,<exists>(select 1 AS `Not_used` from test.t1 join test.t3 where ((test.t1.b = test.t3.a) and (<cache>(test.t2.a) = test.t1.a)) limit 1)) insert into t1 values (3,31); diff --git a/mysql-test/t/rpl_until.test b/mysql-test/t/rpl_until.test index 9bc4ea4e7b1..4508fbea194 100644 --- a/mysql-test/t/rpl_until.test +++ b/mysql-test/t/rpl_until.test @@ -29,7 +29,7 @@ sleep 2; # here table should be still not deleted select * from t1; --replace_result $MASTER_MYPORT MASTER_MYPORT ---replace_column 1 # 33 # +--replace_column 1 # 9 # 23 # 33 # show slave status; # this should fail right after start @@ -59,9 +59,9 @@ stop slave; # this should stop immideately start slave until master_log_file='master-bin.000001', master_log_pos=561; -sleep 2; +--real-sleep 2; # here the sql slave thread should be stopped ---replace_result $MASTER_MYPORT MASTER_MYPORT +--replace_result $MASTER_MYPORT MASTER_MYPORT bin.000005 bin.000004 bin.000006 bin.000004 bin.000007 bin.000004 --replace_column 1 # 9 # 23 # 33 # show slave status; diff --git a/mysys/charset.c b/mysys/charset.c index 40a026f161f..5bf0ea972a5 100644 --- a/mysys/charset.c +++ b/mysys/charset.c @@ -537,15 +537,15 @@ static CHARSET_INFO *get_internal_charset(uint cs_number, myf flags) while we may changing the cs_info_table */ pthread_mutex_lock(&THR_LOCK_charset); - - cs= all_charsets[cs_number]; - - if (cs && !(cs->state & MY_CS_COMPILED) && !(cs->state & MY_CS_LOADED)) + if ((cs= all_charsets[cs_number])) { - strxmov(get_charsets_dir(buf), cs->csname, ".xml", NullS); - my_read_charset_file(buf,flags); + if (!(cs->state & MY_CS_COMPILED) && !(cs->state & MY_CS_LOADED)) + { + strxmov(get_charsets_dir(buf), cs->csname, ".xml", NullS); + my_read_charset_file(buf,flags); + } + cs= (cs->state & MY_CS_AVAILABLE) ? cs : NULL; } - cs= (cs && cs->state & MY_CS_AVAILABLE) ? cs : NULL; pthread_mutex_unlock(&THR_LOCK_charset); return cs; } diff --git a/sql/item_cmpfunc.cc b/sql/item_cmpfunc.cc index 55d511bb39d..4046a4d6414 100644 --- a/sql/item_cmpfunc.cc +++ b/sql/item_cmpfunc.cc @@ -1657,26 +1657,19 @@ Item_cond::Item_cond(THD *thd, Item_cond *item) and_tables_cache(item->and_tables_cache) { /* - here should be following text: - - List_iterator_fast<Item*> li(item.list); - while(Item *it= li++) - list.push_back(it); - - but it do not need, - because this constructor used only for AND/OR and - argument list will be copied by copy_andor_arguments call + item->list will be copied by copy_andor_arguments() call */ - } + void Item_cond::copy_andor_arguments(THD *thd, Item_cond *item) { List_iterator_fast<Item> li(item->list); - while(Item *it= li++) + while (Item *it= li++) list.push_back(it->copy_andor_structure(thd)); } + bool Item_cond::fix_fields(THD *thd, TABLE_LIST *tables, Item **ref) { diff --git a/sql/item_cmpfunc.h b/sql/item_cmpfunc.h index 7079fcf193d..7e1749ef7a0 100644 --- a/sql/item_cmpfunc.h +++ b/sql/item_cmpfunc.h @@ -929,7 +929,7 @@ public: Item* copy_andor_structure(THD *thd) { Item_cond_and *item; - if((item= new Item_cond_and(thd, this))) + if ((item= new Item_cond_and(thd, this))) item->copy_andor_arguments(thd, this); return item; } @@ -950,7 +950,7 @@ public: Item* copy_andor_structure(THD *thd) { Item_cond_or *item; - if((item= new Item_cond_or(thd, this))) + if ((item= new Item_cond_or(thd, this))) item->copy_andor_arguments(thd, this); return item; } diff --git a/sql/item_func.cc b/sql/item_func.cc index e49980af733..efeb0d456ef 100644 --- a/sql/item_func.cc +++ b/sql/item_func.cc @@ -2648,9 +2648,15 @@ longlong Item_func_inet_aton::val_int() } if (c != '.') // IP number can't end on '.' { + /* + Handle short-forms addresses according to standard. Examples: + 127 -> 0.0.0.127 + 127.1 -> 127.0.0.1 + 127.2.1 -> 127.2.0.1 + */ switch (dot_count) { - case 1: result<<= 8; /* fall through */ - case 2: result<<= 8; /* fall through */ + case 1: result<<= 8; /* Fall through */ + case 2: result<<= 8; /* Fall through */ } return (result << 8) + (ulonglong) byte_result; } diff --git a/sql/mysqld.cc b/sql/mysqld.cc index 53cf792a86c..509c18d3dda 100644 --- a/sql/mysqld.cc +++ b/sql/mysqld.cc @@ -4619,7 +4619,7 @@ The minimum value for this variable is 4096.", (gptr*) &max_system_variables.net_wait_timeout, 0, GET_ULONG, REQUIRED_ARG, NET_WAIT_TIMEOUT, 1, LONG_TIMEOUT, 0, 1, 0}, {"expire_logs_days", OPT_EXPIRE_LOGS_DAYS, - "Logs will be rotated after expire-log-days days ", + "Binary logs will be rotated after expire-log-days days ", (gptr*) &expire_logs_days, (gptr*) &expire_logs_days, 0, GET_ULONG, REQUIRED_ARG, 0, 0, 99, 0, 1, 0}, diff --git a/sql/opt_range.cc b/sql/opt_range.cc index d39636fdc6c..2647a0ae818 100644 --- a/sql/opt_range.cc +++ b/sql/opt_range.cc @@ -370,14 +370,25 @@ SQL_SELECT::SQL_SELECT() :quick(0),cond(0),free_cond(0) } -SQL_SELECT::~SQL_SELECT() +void SQL_SELECT::cleanup() { delete quick; + quick= 0; if (free_cond) + { + free_cond=0; delete cond; + cond= 0; + } close_cached_file(&file); } + +SQL_SELECT::~SQL_SELECT() +{ + cleanup(); +} + #undef index // Fix for Unixware 7 QUICK_SELECT::QUICK_SELECT(THD *thd, TABLE *table, uint key_nr, bool no_alloc) @@ -2195,6 +2206,7 @@ check_quick_select(PARAM *param,uint idx,SEL_ARG *tree) param->table->quick_rows[key]=records; param->table->quick_key_parts[key]=param->max_key_part+1; } + DBUG_PRINT("exit", ("Records: %lu", (ulong) records)); DBUG_RETURN(records); } @@ -2569,12 +2581,7 @@ int QUICK_SELECT::get_next() int result; if (range) { // Already read through key -/* result=((range->flag & EQ_RANGE) ? - file->index_next_same(record, (byte*) range->min_key, - range->min_length) : - file->index_next(record)); -*/ - result=((range->flag & (EQ_RANGE | GEOM_FLAG) ) ? + result=((range->flag & (EQ_RANGE | GEOM_FLAG)) ? file->index_next_same(record, (byte*) range->min_key, range->min_length) : file->index_next(record)); diff --git a/sql/opt_range.h b/sql/opt_range.h index bb1cd0f7513..bf10c02c295 100644 --- a/sql/opt_range.h +++ b/sql/opt_range.h @@ -127,6 +127,7 @@ class SQL_SELECT :public Sql_alloc { SQL_SELECT(); ~SQL_SELECT(); + void cleanup(); bool check_quick(THD *thd, bool force_quick_range, ha_rows limit) { return test_quick_select(thd, key_map(~0), 0, limit, force_quick_range) < 0; } inline bool skip_record() { return cond ? cond->val_int() == 0 : 0; } diff --git a/sql/set_var.cc b/sql/set_var.cc index c8b11eb0f58..ecb85440068 100644 --- a/sql/set_var.cc +++ b/sql/set_var.cc @@ -2629,11 +2629,6 @@ ulong fix_sql_mode(ulong sql_mode) MODE_IGNORE_SPACE | MODE_NO_KEY_OPTIONS | MODE_NO_TABLE_OPTIONS | MODE_NO_FIELD_OPTIONS); - if (sql_mode & MODE_MSSQL) - sql_mode|= (MODE_PIPES_AS_CONCAT | MODE_ANSI_QUOTES | - MODE_IGNORE_SPACE | - MODE_NO_KEY_OPTIONS | MODE_NO_TABLE_OPTIONS | - MODE_NO_FIELD_OPTIONS); if (sql_mode & MODE_POSTGRESQL) sql_mode|= (MODE_PIPES_AS_CONCAT | MODE_ANSI_QUOTES | MODE_IGNORE_SPACE | @@ -2644,11 +2639,6 @@ ulong fix_sql_mode(ulong sql_mode) MODE_IGNORE_SPACE | MODE_NO_KEY_OPTIONS | MODE_NO_TABLE_OPTIONS | MODE_NO_FIELD_OPTIONS); - if (sql_mode & MODE_DB2) - sql_mode|= (MODE_PIPES_AS_CONCAT | MODE_ANSI_QUOTES | - MODE_IGNORE_SPACE | - MODE_NO_KEY_OPTIONS | MODE_NO_TABLE_OPTIONS | - MODE_NO_FIELD_OPTIONS); if (sql_mode & MODE_MAXDB) sql_mode|= (MODE_PIPES_AS_CONCAT | MODE_ANSI_QUOTES | MODE_IGNORE_SPACE | diff --git a/sql/slave.cc b/sql/slave.cc index 8af38624df6..968293369a8 100644 --- a/sql/slave.cc +++ b/sql/slave.cc @@ -2682,7 +2682,7 @@ static int exec_relay_log_event(THD* thd, RELAY_LOG_INFO* rli) rli->is_until_satisfied()) { sql_print_error("Slave SQL thread stopped because it reached its" - " UNTIL position"); + " UNTIL position %ld", (long) rli->until_pos()); /* Setting abort_slave flag because we do not want additional message about error in query execution to be printed. diff --git a/sql/slave.h b/sql/slave.h index e42b93a47ef..d92c44dd2ba 100644 --- a/sql/slave.h +++ b/sql/slave.h @@ -324,6 +324,11 @@ typedef struct st_relay_log_info /* Check if UNTIL condition is satisfied. See slave.cc for more. */ bool is_until_satisfied(); + inline ulonglong until_pos() + { + return ((until_condition == UNTIL_MASTER_POS) ? group_master_log_pos : + group_relay_log_pos); + } } RELAY_LOG_INFO; diff --git a/sql/sql_acl.cc b/sql/sql_acl.cc index 77131a37869..9d3ab8621d7 100644 --- a/sql/sql_acl.cc +++ b/sql/sql_acl.cc @@ -2549,7 +2549,7 @@ my_bool grant_init(THD *org_thd) do { GRANT_TABLE *mem_check; - if (!(mem_check=new GRANT_TABLE(t_table,c_table)) || mem_check->ok()) + if (!(mem_check=new GRANT_TABLE(t_table,c_table)) || !mem_check->ok()) { /* This could only happen if we are out memory */ grant_option= FALSE; /* purecov: deadcode */ diff --git a/sql/sql_class.cc b/sql/sql_class.cc index 7b3d1fd3cd2..fc042ae7918 100644 --- a/sql/sql_class.cc +++ b/sql/sql_class.cc @@ -677,12 +677,24 @@ bool select_send::send_eof() } -/*************************************************************************** -** Export of select to textfile -***************************************************************************/ +/************************************************************************ + Handling writing to file +************************************************************************/ +void select_to_file::send_error(uint errcode,const char *err) +{ + ::send_error(thd,errcode,err); + if (file > 0) + { + (void) end_io_cache(&cache); + (void) my_close(file,MYF(0)); + (void) my_delete(path,MYF(0)); // Delete file on error + file= -1; + } +} -select_export::~select_export() + +select_to_file::~select_to_file() { if (file >= 0) { // This only happens in case of error @@ -690,17 +702,42 @@ select_export::~select_export() (void) my_close(file,MYF(0)); file= -1; } +} + +/*************************************************************************** +** Export of select to textfile +***************************************************************************/ + +select_export::~select_export() +{ thd->sent_row_count=row_count; } -static int create_file(THD *thd, char *path, sql_exchange *exchange, - File *file, IO_CACHE *cache) +/* + Create file with IO cache + + SYNOPSIS + create_file() + thd Thread handle + path File name + exchange Excange class + cache IO cache + + RETURN + >= 0 File handle + -1 Error +*/ + + +static File create_file(THD *thd, char *path, sql_exchange *exchange, + IO_CACHE *cache) { - uint option= 4; + File file; + uint option= MY_UNPACK_FILENAME; #ifdef DONT_ALLOW_FULL_LOAD_DATA_PATHS - option|= 1; // Force use of db directory + option|= MY_REPLACE_DIR; // Force use of db directory #endif (void) fn_format(path, exchange->file_name, thd->db ? thd->db : "", "", option); @@ -710,35 +747,32 @@ static int create_file(THD *thd, char *path, sql_exchange *exchange, return 1; } /* Create the file world readable */ - if ((*file= my_create(path, 0666, O_WRONLY, MYF(MY_WME))) < 0) - return 1; + if ((file= my_create(path, 0666, O_WRONLY, MYF(MY_WME))) < 0) + return file; #ifdef HAVE_FCHMOD - (void) fchmod(*file, 0666); // Because of umask() + (void) fchmod(file, 0666); // Because of umask() #else (void) chmod(path, 0666); #endif - if (init_io_cache(cache, *file, 0L, WRITE_CACHE, 0L, 1, MYF(MY_WME))) + if (init_io_cache(cache, file, 0L, WRITE_CACHE, 0L, 1, MYF(MY_WME))) { - my_close(*file, MYF(0)); + my_close(file, MYF(0)); my_delete(path, MYF(0)); // Delete file on error, it was just created - *file= -1; - end_io_cache(cache); - return 1; + return -1; } - return 0; + return file; } int select_export::prepare(List<Item> &list, SELECT_LEX_UNIT *u) { - char path[FN_REFLEN]; bool blob_flag=0; unit= u; if ((uint) strlen(exchange->file_name) + NAME_LEN >= FN_REFLEN) strmake(path,exchange->file_name,FN_REFLEN-1); - if (create_file(thd, path, exchange, &file, &cache)) + if ((file= create_file(thd, path, exchange, &cache)) < 0) return 1; /* Check if there is any blobs in data */ { @@ -910,14 +944,6 @@ err: } -void select_export::send_error(uint errcode, const char *err) -{ - ::send_error(thd,errcode,err); - (void) my_close(file,MYF(0)); - file= -1; -} - - bool select_export::send_eof() { int error=test(end_io_cache(&cache)); @@ -935,24 +961,12 @@ bool select_export::send_eof() ***************************************************************************/ -select_dump::~select_dump() -{ - if (file >= 0) - { // This only happens in case of error - (void) end_io_cache(&cache); - (void) my_close(file,MYF(0)); - file= -1; - } -} - int select_dump::prepare(List<Item> &list __attribute__((unused)), SELECT_LEX_UNIT *u) { unit= u; - if (create_file(thd, path, exchange, &file, &cache)) - return 1; - return 0; + return (int) ((file= create_file(thd, path, exchange, &cache)) < 0); } @@ -995,13 +1009,6 @@ err: } -void select_dump::send_error(uint errcode,const char *err) -{ - ::send_error(thd,errcode,err); - (void) my_close(file,MYF(0)); - file= -1; -} - bool select_dump::send_eof() { int error=test(end_io_cache(&cache)); @@ -1013,11 +1020,13 @@ bool select_dump::send_eof() return error; } + select_subselect::select_subselect(Item_subselect *item_arg) { item= item_arg; } + bool select_singlerow_subselect::send_data(List<Item> &items) { DBUG_ENTER("select_singlerow_subselect::send_data"); @@ -1040,6 +1049,7 @@ bool select_singlerow_subselect::send_data(List<Item> &items) DBUG_RETURN(0); } + bool select_max_min_finder_subselect::send_data(List<Item> &items) { DBUG_ENTER("select_max_min_finder_subselect::send_data"); @@ -1145,8 +1155,9 @@ bool select_exists_subselect::send_data(List<Item> &items) /*************************************************************************** -** Dump of select to variables + Dump of select to variables ***************************************************************************/ + int select_dumpvar::prepare(List<Item> &list, SELECT_LEX_UNIT *u) { List_iterator_fast<Item> li(list); @@ -1163,7 +1174,8 @@ int select_dumpvar::prepare(List<Item> &list, SELECT_LEX_UNIT *u) { ls= gl++; Item_func_set_user_var *xx = new Item_func_set_user_var(*ls,item); - xx->fix_fields(thd,(TABLE_LIST*) thd->lex->select_lex.table_list.first,&item); + xx->fix_fields(thd,(TABLE_LIST*) thd->lex->select_lex.table_list.first, + &item); xx->fix_length_and_dec(); vars.push_back(xx); } diff --git a/sql/sql_class.h b/sql/sql_class.h index 7971137d848..51dc8270d09 100644 --- a/sql/sql_class.h +++ b/sql/sql_class.h @@ -962,41 +962,45 @@ public: }; -class select_export :public select_result { +class select_to_file :public select_result { +protected: sql_exchange *exchange; File file; IO_CACHE cache; ha_rows row_count; + char path[FN_REFLEN]; + +public: + select_to_file(sql_exchange *ex) :exchange(ex), file(-1),row_count(0L) + { path[0]=0; } + ~select_to_file(); + bool send_fields(List<Item> &list, uint flag) { return 0; } + void send_error(uint errcode,const char *err); +}; + + +class select_export :public select_to_file { uint field_term_length; int field_sep_char,escape_char,line_sep_char; bool fixed_row_size; public: - select_export(sql_exchange *ex) :exchange(ex),file(-1),row_count(0L) {} + select_export(sql_exchange *ex) :select_to_file(ex) {} ~select_export(); int prepare(List<Item> &list, SELECT_LEX_UNIT *u); - bool send_fields(List<Item> &list, - uint flag) { return 0; } bool send_data(List<Item> &items); - void send_error(uint errcode,const char *err); bool send_eof(); }; -class select_dump :public select_result { +class select_dump :public select_to_file { sql_exchange *exchange; File file; IO_CACHE cache; ha_rows row_count; - char path[FN_REFLEN]; public: - select_dump(sql_exchange *ex) :exchange(ex),file(-1),row_count(0L) - { path[0]=0; } - ~select_dump(); + select_dump(sql_exchange *ex) :select_to_file(ex) {} int prepare(List<Item> &list, SELECT_LEX_UNIT *u); - bool send_fields(List<Item> &list, - uint flag) { return 0; } bool send_data(List<Item> &items); - void send_error(uint errcode,const char *err); bool send_eof(); }; diff --git a/sql/sql_select.cc b/sql/sql_select.cc index aeaad4559e2..81051f70a4a 100644 --- a/sql/sql_select.cc +++ b/sql/sql_select.cc @@ -1648,8 +1648,8 @@ static ha_rows get_quick_record_count(THD *thd, SQL_SELECT *select, { select->head=table; table->reginfo.impossible_range=0; - if ((error=select->test_quick_select(thd, *(key_map *)keys,(table_map) 0,limit)) - == 1) + if ((error=select->test_quick_select(thd, *(key_map *)keys,(table_map) 0, + limit)) == 1) DBUG_RETURN(select->quick->records); if (error == -1) { @@ -2700,22 +2700,35 @@ find_best(JOIN *join,table_map rest_tables,uint idx,double record_count, do { uint keypart=keyuse->keypart; - uint found_part_ref_or_null= KEY_OPTIMIZE_REF_OR_NULL; + table_map best_part_found_ref= 0; + double best_prev_record_reads= DBL_MAX; do { if (!(rest_tables & keyuse->used_tables) && !(found_ref_or_null & keyuse->optimize)) { found_part|=keyuse->keypart_map; - found_ref|= keyuse->used_tables; + double tmp= prev_record_reads(join, + (found_ref | + keyuse->used_tables)); + if (tmp < best_prev_record_reads) + { + best_part_found_ref= keyuse->used_tables; + best_prev_record_reads= tmp; + } if (rec > keyuse->ref_table_rows) rec= keyuse->ref_table_rows; - found_part_ref_or_null&= keyuse->optimize; + /* + If there is one 'key_column IS NULL' expression, we can + use this ref_or_null optimsation of this field + */ + found_ref_or_null|= (keyuse->optimize & + KEY_OPTIMIZE_REF_OR_NULL); } keyuse++; - found_ref_or_null|= found_part_ref_or_null; } while (keyuse->table == table && keyuse->key == key && keyuse->keypart == keypart); + found_ref|= best_part_found_ref; } while (keyuse->table == table && keyuse->key == key); /* @@ -7203,9 +7216,12 @@ create_sort_index(THD *thd, JOIN *join, ORDER *order, table->file->info(HA_STATUS_VARIABLE); // Get record count table->sort.found_records=filesort(thd, table,sortorder, length, select, filesort_limit, &examined_rows); - tab->records=table->sort.found_records; // For SQL_CALC_ROWS - delete select; - tab->select=0; + tab->records= table->sort.found_records; // For SQL_CALC_ROWS + if (select) + { + select->cleanup(); // filesort did select + tab->select= 0; + } tab->select_cond=0; tab->type=JT_ALL; // Read with normal read_record tab->read_first_record= join_init_read_record; |