summaryrefslogtreecommitdiff
path: root/sql
diff options
context:
space:
mode:
Diffstat (limited to 'sql')
-rw-r--r--sql/item_cmpfunc.cc15
-rw-r--r--sql/item_cmpfunc.h4
-rw-r--r--sql/item_func.cc10
-rw-r--r--sql/mysqld.cc2
-rw-r--r--sql/opt_range.cc21
-rw-r--r--sql/opt_range.h1
-rw-r--r--sql/set_var.cc10
-rw-r--r--sql/slave.cc2
-rw-r--r--sql/slave.h5
-rw-r--r--sql/sql_acl.cc2
-rw-r--r--sql/sql_class.cc110
-rw-r--r--sql/sql_class.h30
-rw-r--r--sql/sql_select.cc34
13 files changed, 140 insertions, 106 deletions
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;