summaryrefslogtreecommitdiff
path: root/sql
diff options
context:
space:
mode:
Diffstat (limited to 'sql')
-rw-r--r--sql/item_cmpfunc.cc22
-rw-r--r--sql/item_cmpfunc.h2
-rw-r--r--sql/item_strfunc.cc17
-rw-r--r--sql/item_strfunc.h4
-rw-r--r--sql/item_subselect.cc16
-rw-r--r--sql/item_subselect.h9
-rw-r--r--sql/mysql_priv.h3
-rw-r--r--sql/mysqld.cc5
-rw-r--r--sql/opt_range.h2
-rw-r--r--sql/set_var.cc3
-rw-r--r--sql/sql_parse.cc2
-rw-r--r--sql/sql_select.cc35
-rw-r--r--sql/sql_update.cc2
13 files changed, 100 insertions, 22 deletions
diff --git a/sql/item_cmpfunc.cc b/sql/item_cmpfunc.cc
index f14efc7187b..a32bd0a7337 100644
--- a/sql/item_cmpfunc.cc
+++ b/sql/item_cmpfunc.cc
@@ -3099,6 +3099,28 @@ Item *Item_cond_or::neg_transformer(THD *thd) /* NOT(a OR b OR ...) -> */
}
+Item *Item_func_nop_all::neg_transformer(THD *thd)
+{
+ /* "NOT (e $cmp$ ANY (SELECT ...)) -> e $rev_cmp$" ALL (SELECT ...) */
+ Item_func_not_all *new_item= new Item_func_not_all(args[0]);
+ Item_allany_subselect *allany= (Item_allany_subselect*)args[0];
+ allany->func= allany->func_creator(FALSE);
+ allany->all= !allany->all;
+ allany->upper_item= new_item;
+ return new_item;
+}
+
+Item *Item_func_not_all::neg_transformer(THD *thd)
+{
+ /* "NOT (e $cmp$ ALL (SELECT ...)) -> e $rev_cmp$" ANY (SELECT ...) */
+ Item_func_nop_all *new_item= new Item_func_nop_all(args[0]);
+ Item_allany_subselect *allany= (Item_allany_subselect*)args[0];
+ allany->all= !allany->all;
+ allany->func= allany->func_creator(TRUE);
+ allany->upper_item= new_item;
+ return new_item;
+}
+
Item *Item_func_eq::negated_item() /* a = b -> a != b */
{
return new Item_func_ne(args[0], args[1]);
diff --git a/sql/item_cmpfunc.h b/sql/item_cmpfunc.h
index 73abe208d9e..0e157fd412c 100644
--- a/sql/item_cmpfunc.h
+++ b/sql/item_cmpfunc.h
@@ -268,6 +268,7 @@ public:
void set_sum_test(Item_sum_hybrid *item) { test_sum_item= item; };
void set_sub_test(Item_maxmin_subselect *item) { test_sub_item= item; };
bool empty_underlying_subquery();
+ Item *neg_transformer(THD *thd);
};
@@ -278,6 +279,7 @@ public:
Item_func_nop_all(Item *a) :Item_func_not_all(a) {}
longlong val_int();
const char *func_name() const { return "<nop>"; }
+ Item *neg_transformer(THD *thd);
};
diff --git a/sql/item_strfunc.cc b/sql/item_strfunc.cc
index 7bc7956283b..1c5b947cb2b 100644
--- a/sql/item_strfunc.cc
+++ b/sql/item_strfunc.cc
@@ -1444,6 +1444,23 @@ void Item_func_trim::fix_length_and_dec()
}
}
+void Item_func_trim::print(String *str)
+{
+ if (arg_count == 1)
+ {
+ Item_func::print(str);
+ return;
+ }
+ str->append(Item_func_trim::func_name());
+ str->append('(');
+ str->append(mode_name());
+ str->append(' ');
+ args[1]->print(str);
+ str->append(" from ",6);
+ args[0]->print(str);
+ str->append(')');
+}
+
/* Item_func_password */
diff --git a/sql/item_strfunc.h b/sql/item_strfunc.h
index f800c17182b..880a19242ca 100644
--- a/sql/item_strfunc.h
+++ b/sql/item_strfunc.h
@@ -218,6 +218,8 @@ public:
String *val_str(String *);
void fix_length_and_dec();
const char *func_name() const { return "trim"; }
+ void print(String *str);
+ virtual const char *mode_name() const { return "both"; }
};
@@ -228,6 +230,7 @@ public:
Item_func_ltrim(Item *a) :Item_func_trim(a) {}
String *val_str(String *);
const char *func_name() const { return "ltrim"; }
+ const char *mode_name() const { return "leading"; }
};
@@ -238,6 +241,7 @@ public:
Item_func_rtrim(Item *a) :Item_func_trim(a) {}
String *val_str(String *);
const char *func_name() const { return "rtrim"; }
+ const char *mode_name() const { return "trailing"; }
};
diff --git a/sql/item_subselect.cc b/sql/item_subselect.cc
index f6f8eec9af5..13beb022c9d 100644
--- a/sql/item_subselect.cc
+++ b/sql/item_subselect.cc
@@ -542,14 +542,14 @@ Item_in_subselect::Item_in_subselect(Item * left_exp,
}
Item_allany_subselect::Item_allany_subselect(Item * left_exp,
- Comp_creator *fn,
+ chooser_compare_func_creator fc,
st_select_lex *select_lex,
bool all_arg)
- :Item_in_subselect(), all(all_arg)
+ :Item_in_subselect(), all(all_arg), func_creator(fc)
{
DBUG_ENTER("Item_in_subselect::Item_in_subselect");
left_expr= left_exp;
- func= fn;
+ func= func_creator(all_arg);
init(select_lex, new select_exists_subselect(this));
max_columns= 1;
abort_on_null= 0;
@@ -976,18 +976,18 @@ Item_in_subselect::row_value_transformer(JOIN *join)
DBUG_RETURN(RES_ERROR);
Item *item_eq=
new Item_func_eq(new
- Item_direct_ref((*optimizer->get_cache())->
+ Item_ref((*optimizer->get_cache())->
addr(i),
(char *)"<no matter>",
(char *)in_left_expr_name),
new
- Item_direct_ref(select_lex->ref_pointer_array + i,
+ Item_ref(select_lex->ref_pointer_array + i,
(char *)"<no matter>",
(char *)"<list ref>")
);
Item *item_isnull=
new Item_func_isnull(new
- Item_direct_ref( select_lex->
+ Item_ref( select_lex->
ref_pointer_array+i,
(char *)"<no matter>",
(char *)"<list ref>")
@@ -1000,7 +1000,7 @@ Item_in_subselect::row_value_transformer(JOIN *join)
new
Item_is_not_null_test(this,
new
- Item_direct_ref(select_lex->
+ Item_ref(select_lex->
ref_pointer_array + i,
(char *)"<no matter>",
(char *)"<list ref>")
@@ -1057,7 +1057,7 @@ Item_in_subselect::row_value_transformer(JOIN *join)
new
Item_is_not_null_test(this,
new
- Item_direct_ref(select_lex->
+ Item_ref(select_lex->
ref_pointer_array + i,
(char *)"<no matter>",
(char *)"<list ref>")
diff --git a/sql/item_subselect.h b/sql/item_subselect.h
index dec32398a80..93171ad64a1 100644
--- a/sql/item_subselect.h
+++ b/sql/item_subselect.h
@@ -251,14 +251,13 @@ public:
/* ALL/ANY/SOME subselect */
class Item_allany_subselect :public Item_in_subselect
{
-protected:
- Comp_creator *func;
-
public:
+ chooser_compare_func_creator func_creator;
+ Comp_creator *func;
bool all;
- Item_allany_subselect(Item * left_expr, Comp_creator *f,
- st_select_lex *select_lex, bool all);
+ Item_allany_subselect(Item * left_expr, chooser_compare_func_creator fc,
+ st_select_lex *select_lex, bool all);
// only ALL subquery has upper not
subs_type substype() { return all?ALL_SUBS:ANY_SUBS; }
diff --git a/sql/mysql_priv.h b/sql/mysql_priv.h
index b9faa062850..9c5bcc2d53f 100644
--- a/sql/mysql_priv.h
+++ b/sql/mysql_priv.h
@@ -387,8 +387,9 @@ enum enum_var_type
OPT_DEFAULT, OPT_SESSION, OPT_GLOBAL
};
class sys_var;
-#include "item.h"
+class Comp_creator;
typedef Comp_creator* (*chooser_compare_func_creator)(bool invert);
+#include "item.h"
/* sql_parse.cc */
void free_items(Item *item);
void cleanup_items(Item *item);
diff --git a/sql/mysqld.cc b/sql/mysqld.cc
index 0de8f005247..74c7b1a4e4c 100644
--- a/sql/mysqld.cc
+++ b/sql/mysqld.cc
@@ -2646,6 +2646,11 @@ You should consider changing lower_case_table_names to 1 or 2",
mysql_real_data_home);
lower_case_table_names= 0;
}
+ else
+ {
+ lower_case_file_system=
+ (test_if_case_insensitive(mysql_real_data_home) == 1);
+ }
/* Reset table_alias_charset, now that lower_case_table_names is set. */
table_alias_charset= (lower_case_table_names ?
diff --git a/sql/opt_range.h b/sql/opt_range.h
index 15f0bf02b34..d2f4452a762 100644
--- a/sql/opt_range.h
+++ b/sql/opt_range.h
@@ -86,7 +86,7 @@ public:
QUICK_SELECT(THD *thd, TABLE *table,uint index_arg,bool no_alloc=0);
virtual ~QUICK_SELECT();
- void reset(void) { next=0; it.rewind(); }
+ void reset(void) { next=0; it.rewind(); range= NULL;}
int init()
{
key_part_info= head->key_info[index].key_part;
diff --git a/sql/set_var.cc b/sql/set_var.cc
index a665a6dc3aa..1d994f1c98f 100644
--- a/sql/set_var.cc
+++ b/sql/set_var.cc
@@ -424,7 +424,8 @@ static sys_var_thd_bit sys_sql_big_tables("sql_big_tables", 0,
static sys_var_thd_bit sys_big_selects("sql_big_selects", 0,
set_option_bit,
OPTION_BIG_SELECTS);
-static sys_var_thd_bit sys_log_off("sql_log_off", 0,
+static sys_var_thd_bit sys_log_off("sql_log_off",
+ check_log_update,
set_option_bit,
OPTION_LOG_OFF);
static sys_var_thd_bit sys_log_update("sql_log_update",
diff --git a/sql/sql_parse.cc b/sql/sql_parse.cc
index ad3accbe187..cf1f50aed63 100644
--- a/sql/sql_parse.cc
+++ b/sql/sql_parse.cc
@@ -5442,7 +5442,7 @@ Item * all_any_subquery_creator(Item *left_expr,
return new Item_func_not(new Item_in_subselect(left_expr, select_lex));
Item_allany_subselect *it=
- new Item_allany_subselect(left_expr, (*cmp)(all), select_lex, all);
+ new Item_allany_subselect(left_expr, cmp, select_lex, all);
if (all)
return it->upper_item= new Item_func_not_all(it); /* ALL */
diff --git a/sql/sql_select.cc b/sql/sql_select.cc
index 9e3883e87e0..605ef49bb07 100644
--- a/sql/sql_select.cc
+++ b/sql/sql_select.cc
@@ -547,6 +547,24 @@ JOIN::optimize()
}
zero_result_cause= "Select tables optimized away";
tables_list= 0; // All tables resolved
+ /*
+ Extract all table-independent conditions and replace the WHERE
+ clause with them. All other conditions were computed by opt_sum_query
+ and the MIN/MAX/COUNT function(s) have been replaced by constants,
+ so there is no need to compute the whole WHERE clause again.
+ Notice that make_cond_for_table() will always succeed to remove all
+ computed conditions, because opt_sum_query() is applicable only to
+ conjunctions.
+ */
+ if (conds)
+ {
+ COND *table_independent_conds=
+ make_cond_for_table(conds, PSEUDO_TABLE_BITS, 0);
+ DBUG_EXECUTE("where",
+ print_where(table_independent_conds,
+ "where after opt_sum_query()"););
+ conds= table_independent_conds;
+ }
}
}
if (!tables_list)
@@ -2143,8 +2161,11 @@ merge_key_fields(KEY_FIELD *start,KEY_FIELD *new_fields,KEY_FIELD *end,
/* field = expression OR field IS NULL */
old->level= and_level;
old->optimize= KEY_OPTIMIZE_REF_OR_NULL;
- /* Remember the NOT NULL value */
- if (old->val->is_null())
+ /*
+ Remember the NOT NULL value unless the value does not depend
+ on other tables.
+ */
+ if (!old->val->used_tables() && old->val->is_null())
old->val= new_fields->val;
/* The referred expression can be NULL: */
old->null_rejecting= 0;
@@ -4452,10 +4473,16 @@ return_zero_rows(JOIN *join, select_result *result,TABLE_LIST *tables,
DBUG_RETURN(0);
}
-
+/*
+ used only in JOIN::clear
+*/
static void clear_tables(JOIN *join)
{
- for (uint i=0 ; i < join->tables ; i++)
+ /*
+ must clear only the non-const tables, as const tables
+ are not re-calculated.
+ */
+ for (uint i=join->const_tables ; i < join->tables ; i++)
mark_as_null_row(join->table[i]); // All fields are NULL
}
diff --git a/sql/sql_update.cc b/sql/sql_update.cc
index 089d0bf0660..af4ba8025f9 100644
--- a/sql/sql_update.cc
+++ b/sql/sql_update.cc
@@ -628,7 +628,7 @@ int mysql_multi_update_lock(THD *thd,
if (!using_lock_tables)
tl->table->reginfo.lock_type= tl->lock_type;
if (check_access(thd, wants, tl->db, &tl->grant.privilege, 0, 0) ||
- (grant_option && check_grant(thd, wants, tl, 0, 0, 0)))
+ (grant_option && check_grant(thd, wants, tl, 0, 1, 0)))
{
tl->next= save;
DBUG_RETURN(1);