diff options
author | Tor Didriksen <tor.didriksen@oracle.com> | 2011-05-05 08:13:22 +0200 |
---|---|---|
committer | Tor Didriksen <tor.didriksen@oracle.com> | 2011-05-05 08:13:22 +0200 |
commit | 294fb44d67ff1b12e11b7f771d5260ed2b1b97fb (patch) | |
tree | cd172df35bbbc323a22f426774bc859ed6080cb5 /sql | |
parent | e889b48749583751895b8f34e1906c93f69d53f0 (diff) | |
parent | 9baf84e99a6d7edd36c777593a90671d02aacbc9 (diff) | |
download | mariadb-git-294fb44d67ff1b12e11b7f771d5260ed2b1b97fb.tar.gz |
merge 5.1 => 5.5 : Bug#12329653
Diffstat (limited to 'sql')
-rw-r--r-- | sql/item.cc | 4 | ||||
-rw-r--r-- | sql/item_subselect.cc | 9 | ||||
-rw-r--r-- | sql/item_sum.cc | 6 | ||||
-rw-r--r-- | sql/sql_lex.cc | 5 | ||||
-rw-r--r-- | sql/sql_lex.h | 28 | ||||
-rw-r--r-- | sql/sql_partition.cc | 27 | ||||
-rw-r--r-- | sql/sql_priv.h | 7 | ||||
-rw-r--r-- | sql/sql_select.cc | 12 |
8 files changed, 55 insertions, 43 deletions
diff --git a/sql/item.cc b/sql/item.cc index af3917c09c1..639a3a81b78 100644 --- a/sql/item.cc +++ b/sql/item.cc @@ -4759,14 +4759,14 @@ mark_non_agg_field: SELECT_LEX *select_lex= cached_table ? cached_table->select_lex : context->select_lex; if (!thd->lex->in_sum_func) - select_lex->full_group_by_flag|= NON_AGG_FIELD_USED; + select_lex->set_non_agg_field_used(true); else { if (outer_fixed) thd->lex->in_sum_func->outer_fields.push_back(this); else if (thd->lex->in_sum_func->nest_level != thd->lex->current_select->nest_level) - select_lex->full_group_by_flag|= NON_AGG_FIELD_USED; + select_lex->set_non_agg_field_used(true); } } return FALSE; diff --git a/sql/item_subselect.cc b/sql/item_subselect.cc index 118bae7342f..721b3fd5095 100644 --- a/sql/item_subselect.cc +++ b/sql/item_subselect.cc @@ -38,6 +38,7 @@ #include "set_var.h" #include "sql_select.h" #include "sql_parse.h" // check_stack_overrun +#include "sql_test.h" inline Item * and_items(Item* cond, Item *item) { @@ -1025,6 +1026,14 @@ Item_in_subselect::single_value_transformer(JOIN *join, it.replace(item); } + DBUG_EXECUTE("where", + print_where(item, "rewrite with MIN/MAX", QT_ORDINARY);); + if (thd->variables.sql_mode & MODE_ONLY_FULL_GROUP_BY) + { + DBUG_ASSERT(select_lex->non_agg_field_used()); + select_lex->set_non_agg_field_used(false); + } + save_allow_sum_func= thd->lex->allow_sum_func; thd->lex->allow_sum_func|= 1 << thd->lex->current_select->nest_level; /* diff --git a/sql/item_sum.cc b/sql/item_sum.cc index 8855ef05c84..42088616f4a 100644 --- a/sql/item_sum.cc +++ b/sql/item_sum.cc @@ -259,10 +259,10 @@ bool Item_sum::check_sum_func(THD *thd, Item **ref) in_sum_func->outer_fields.push_back(field); } else - sel->full_group_by_flag|= NON_AGG_FIELD_USED; + sel->set_non_agg_field_used(true); } if (sel->nest_level > aggr_level && - (sel->full_group_by_flag & SUM_FUNC_USED) && + (sel->agg_func_used()) && !sel->group_list.elements) { my_message(ER_MIX_OF_GROUP_FUNC_AND_FIELDS, @@ -271,7 +271,7 @@ bool Item_sum::check_sum_func(THD *thd, Item **ref) } } } - aggr_sel->full_group_by_flag|= SUM_FUNC_USED; + aggr_sel->set_agg_func_used(true); update_used_tables(); thd->lex->in_sum_func= in_sum_func; return FALSE; diff --git a/sql/sql_lex.cc b/sql/sql_lex.cc index 5e8ecc6b815..6e3f0a33147 100644 --- a/sql/sql_lex.cc +++ b/sql/sql_lex.cc @@ -1755,6 +1755,8 @@ void st_select_lex::init_query() exclude_from_table_unique_test= no_wrap_view_item= FALSE; nest_level= 0; link_next= 0; + m_non_agg_field_used= false; + m_agg_func_used= false; } void st_select_lex::init_select() @@ -1785,7 +1787,8 @@ void st_select_lex::init_select() non_agg_fields.empty(); cond_value= having_value= Item::COND_UNDEF; inner_refs_list.empty(); - full_group_by_flag= 0; + m_non_agg_field_used= false; + m_agg_func_used= false; } /* diff --git a/sql/sql_lex.h b/sql/sql_lex.h index e6b5f23f17e..2b40741698e 100644 --- a/sql/sql_lex.h +++ b/sql/sql_lex.h @@ -800,16 +800,7 @@ public: joins on the right. */ List<String> *prev_join_using; - /* - Bitmap used in the ONLY_FULL_GROUP_BY_MODE to prevent mixture of aggregate - functions and non aggregated fields when GROUP BY list is absent. - Bits: - 0 - non aggregated fields are used in this select, - defined as NON_AGG_FIELD_USED. - 1 - aggregate functions are used in this select, - defined as SUM_FUNC_USED. - */ - uint8 full_group_by_flag; + void init_query(); void init_select(); st_select_lex_unit* master_unit(); @@ -918,7 +909,22 @@ public: void clear_index_hints(void) { index_hints= NULL; } -private: + /* + For MODE_ONLY_FULL_GROUP_BY we need to maintain two flags: + - Non-aggregated fields are used in this select. + - Aggregate functions are used in this select. + In MODE_ONLY_FULL_GROUP_BY only one of these may be true. + */ + bool non_agg_field_used() const { return m_non_agg_field_used; } + bool agg_func_used() const { return m_agg_func_used; } + + void set_non_agg_field_used(bool val) { m_non_agg_field_used= val; } + void set_agg_func_used(bool val) { m_agg_func_used= val; } + +private: + bool m_non_agg_field_used; + bool m_agg_func_used; + /* current index hint kind. used in filling up index_hints */ enum index_hint_type current_index_hint_type; index_clause_map current_index_hint_clause; diff --git a/sql/sql_partition.cc b/sql/sql_partition.cc index 5c2c0bb95d6..b9bbec63e7d 100644 --- a/sql/sql_partition.cc +++ b/sql/sql_partition.cc @@ -1077,8 +1077,6 @@ static bool fix_fields_part_func(THD *thd, Item* func_expr, TABLE *table, int error; LEX *old_lex= thd->lex; LEX lex; - uint8 saved_full_group_by_flag; - nesting_map saved_allow_sum_func; DBUG_ENTER("fix_fields_part_func"); if (init_lex_with_single_table(thd, table, &lex)) @@ -1103,19 +1101,22 @@ static bool fix_fields_part_func(THD *thd, Item* func_expr, TABLE *table, This is a tricky call to prepare for since it can have a large number of interesting side effects, both desirable and undesirable. */ - saved_full_group_by_flag= thd->lex->current_select->full_group_by_flag; - saved_allow_sum_func= thd->lex->allow_sum_func; - thd->lex->allow_sum_func= 0; - - error= func_expr->fix_fields(thd, (Item**)&func_expr); + { + const bool save_agg_field= thd->lex->current_select->non_agg_field_used(); + const bool save_agg_func= thd->lex->current_select->agg_func_used(); + const nesting_map saved_allow_sum_func= thd->lex->allow_sum_func; + thd->lex->allow_sum_func= 0; - /* - Restore full_group_by_flag and allow_sum_func, - fix_fields should not affect mysql_select later, see Bug#46923. - */ - thd->lex->current_select->full_group_by_flag= saved_full_group_by_flag; - thd->lex->allow_sum_func= saved_allow_sum_func; + error= func_expr->fix_fields(thd, (Item**)&func_expr); + /* + Restore agg_field/agg_func and allow_sum_func, + fix_fields should not affect mysql_select later, see Bug#46923. + */ + thd->lex->current_select->set_non_agg_field_used(save_agg_field); + thd->lex->current_select->set_agg_func_used(save_agg_func); + thd->lex->allow_sum_func= saved_allow_sum_func; + } if (unlikely(error)) { DBUG_PRINT("info", ("Field in partition function not part of table")); diff --git a/sql/sql_priv.h b/sql/sql_priv.h index 434dfb1e306..da7f3f6f116 100644 --- a/sql/sql_priv.h +++ b/sql/sql_priv.h @@ -261,13 +261,6 @@ enum enum_yes_no_unknown #ifdef MYSQL_SERVER /* - A set of constants used for checking non aggregated fields and sum - functions mixture in the ONLY_FULL_GROUP_BY_MODE. -*/ -#define NON_AGG_FIELD_USED 1 -#define SUM_FUNC_USED 2 - -/* External variables */ diff --git a/sql/sql_select.cc b/sql/sql_select.cc index 3173b6c1a0e..28981e719b8 100644 --- a/sql/sql_select.cc +++ b/sql/sql_select.cc @@ -455,19 +455,18 @@ inline int setup_without_group(THD *thd, Item **ref_pointer_array, int res; nesting_map save_allow_sum_func=thd->lex->allow_sum_func ; /* - Need to save the value, so we can turn off only the new NON_AGG_FIELD + Need to save the value, so we can turn off only any new non_agg_field_used additions coming from the WHERE */ - uint8 saved_flag= thd->lex->current_select->full_group_by_flag; + const bool saved_non_agg_field_used= + thd->lex->current_select->non_agg_field_used(); DBUG_ENTER("setup_without_group"); thd->lex->allow_sum_func&= ~(1 << thd->lex->current_select->nest_level); res= setup_conds(thd, tables, leaves, conds); /* it's not wrong to have non-aggregated columns in a WHERE */ - if (thd->variables.sql_mode & MODE_ONLY_FULL_GROUP_BY) - thd->lex->current_select->full_group_by_flag= saved_flag | - (thd->lex->current_select->full_group_by_flag & ~NON_AGG_FIELD_USED); + thd->lex->current_select->set_non_agg_field_used(saved_non_agg_field_used); thd->lex->allow_sum_func|= 1 << thd->lex->current_select->nest_level; res= res || setup_order(thd, ref_pointer_array, tables, fields, all_fields, @@ -673,7 +672,8 @@ JOIN::prepare(Item ***rref_pointer_array, aggregate functions with implicit grouping (there is no GROUP BY). */ if (thd->variables.sql_mode & MODE_ONLY_FULL_GROUP_BY && !group_list && - select_lex->full_group_by_flag == (NON_AGG_FIELD_USED | SUM_FUNC_USED)) + select_lex->non_agg_field_used() && + select_lex->agg_func_used()) { my_message(ER_MIX_OF_GROUP_FUNC_AND_FIELDS, ER(ER_MIX_OF_GROUP_FUNC_AND_FIELDS), MYF(0)); |