diff options
Diffstat (limited to 'sql')
-rw-r--r-- | sql/item_cmpfunc.cc | 22 | ||||
-rw-r--r-- | sql/item_cmpfunc.h | 2 | ||||
-rw-r--r-- | sql/item_strfunc.cc | 17 | ||||
-rw-r--r-- | sql/item_strfunc.h | 4 | ||||
-rw-r--r-- | sql/item_subselect.cc | 16 | ||||
-rw-r--r-- | sql/item_subselect.h | 9 | ||||
-rw-r--r-- | sql/mysql_priv.h | 3 | ||||
-rw-r--r-- | sql/mysqld.cc | 5 | ||||
-rw-r--r-- | sql/opt_range.h | 2 | ||||
-rw-r--r-- | sql/set_var.cc | 3 | ||||
-rw-r--r-- | sql/sql_parse.cc | 2 | ||||
-rw-r--r-- | sql/sql_select.cc | 35 | ||||
-rw-r--r-- | sql/sql_update.cc | 2 |
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); |