summaryrefslogtreecommitdiff
path: root/sql/sql_select.cc
diff options
context:
space:
mode:
Diffstat (limited to 'sql/sql_select.cc')
-rw-r--r--sql/sql_select.cc51
1 files changed, 31 insertions, 20 deletions
diff --git a/sql/sql_select.cc b/sql/sql_select.cc
index 00b573922fe..cc9f453e595 100644
--- a/sql/sql_select.cc
+++ b/sql/sql_select.cc
@@ -70,8 +70,10 @@ static int return_zero_rows(JOIN *join, select_result *res,TABLE_LIST *tables,
uint select_options, const char *info,
Item *having, Procedure *proc,
SELECT_LEX_UNIT *unit);
-static COND *optimize_cond(COND *conds,Item::cond_result *cond_value);
-static COND *remove_eq_conds(COND *cond,Item::cond_result *cond_value);
+static COND *optimize_cond(THD *thd, COND *conds,
+ Item::cond_result *cond_value);
+static COND *remove_eq_conds(THD *thd, COND *cond,
+ Item::cond_result *cond_value);
static bool const_expression_in_where(COND *conds,Item *item, Item **comp_item);
static bool open_tmp_table(TABLE *table);
static bool create_myisam_tmp_table(TABLE *table,TMP_TABLE_PARAM *param,
@@ -286,6 +288,10 @@ JOIN::prepare(Item ***rref_pointer_array,
{
DBUG_ENTER("JOIN::prepare");
+ // to prevent double initialization on EXPLAIN
+ if (optimized)
+ DBUG_RETURN(0);
+
conds= conds_init;
order= order_init;
group_list= group_init;
@@ -315,8 +321,9 @@ JOIN::prepare(Item ***rref_pointer_array,
thd->where="having clause";
thd->allow_sum_func=1;
select_lex->having_fix_field= 1;
- bool having_fix_rc= (having->fix_fields(thd, tables_list, &having) ||
- having->check_cols(1));
+ bool having_fix_rc= !having->fixed &&
+ (having->fix_fields(thd, tables_list, &having) ||
+ having->check_cols(1));
select_lex->having_fix_field= 0;
if (having_fix_rc || thd->net.report_error)
DBUG_RETURN(-1); /* purecov: inspected */
@@ -518,7 +525,7 @@ JOIN::optimize()
}
#endif
- conds= optimize_cond(conds,&cond_value);
+ conds= optimize_cond(thd, conds,&cond_value);
if (thd->net.report_error)
{
error= 1;
@@ -4333,6 +4340,7 @@ propagate_cond_constants(I_List<COND_CMP> *save_list,COND *and_father,
SYNPOSIS
eliminate_not_funcs()
+ thd thread handler
cond condition tree
DESCRIPTION
@@ -4349,7 +4357,7 @@ propagate_cond_constants(I_List<COND_CMP> *save_list,COND *and_father,
New condition tree
*/
-COND *eliminate_not_funcs(COND *cond)
+COND *eliminate_not_funcs(THD *thd, COND *cond)
{
if (!cond)
return cond;
@@ -4359,7 +4367,7 @@ COND *eliminate_not_funcs(COND *cond)
Item *item;
while ((item= li++))
{
- Item *new_item= eliminate_not_funcs(item);
+ Item *new_item= eliminate_not_funcs(thd, item);
if (item != new_item)
VOID(li.replace(new_item)); /* replace item with a new condition */
}
@@ -4367,14 +4375,13 @@ COND *eliminate_not_funcs(COND *cond)
else if (cond->type() == Item::FUNC_ITEM && /* 'NOT' operation? */
((Item_func*) cond)->functype() == Item_func::NOT_FUNC)
{
- COND *new_cond= ((Item_func*) cond)->arguments()[0]->neg_transformer();
+ COND *new_cond= ((Item_func*) cond)->arguments()[0]->neg_transformer(thd);
if (new_cond)
{
/*
Here we can delete the NOT function. Something like: delete cond;
But we don't need to do it. All items will be deleted later at once.
*/
- new_cond->fix_fields(current_thd, 0, &new_cond);
cond= new_cond;
}
}
@@ -4383,7 +4390,7 @@ COND *eliminate_not_funcs(COND *cond)
static COND *
-optimize_cond(COND *conds,Item::cond_result *cond_value)
+optimize_cond(THD *thd, COND *conds, Item::cond_result *cond_value)
{
DBUG_ENTER("optimize_cond");
if (!conds)
@@ -4393,7 +4400,7 @@ optimize_cond(COND *conds,Item::cond_result *cond_value)
}
DBUG_EXECUTE("where",print_where(conds,"original"););
/* eliminate NOT operators */
- conds= eliminate_not_funcs(conds);
+ conds= eliminate_not_funcs(thd, conds);
DBUG_EXECUTE("where", print_where(conds, "after negation elimination"););
/* change field = field to field = const for each found field = const */
propagate_cond_constants((I_List<COND_CMP> *) 0,conds,conds);
@@ -4402,7 +4409,7 @@ optimize_cond(COND *conds,Item::cond_result *cond_value)
Remove all and-levels where CONST item != CONST item
*/
DBUG_EXECUTE("where",print_where(conds,"after const change"););
- conds=remove_eq_conds(conds,cond_value) ;
+ conds= remove_eq_conds(thd, conds, cond_value) ;
DBUG_EXECUTE("info",print_where(conds,"after remove"););
DBUG_RETURN(conds);
}
@@ -4417,7 +4424,7 @@ optimize_cond(COND *conds,Item::cond_result *cond_value)
*/
static COND *
-remove_eq_conds(COND *cond,Item::cond_result *cond_value)
+remove_eq_conds(THD *thd, COND *cond, Item::cond_result *cond_value)
{
if (cond->type() == Item::COND_ITEM)
{
@@ -4431,7 +4438,7 @@ remove_eq_conds(COND *cond,Item::cond_result *cond_value)
Item *item;
while ((item=li++))
{
- Item *new_item=remove_eq_conds(item,&tmp_cond_value);
+ Item *new_item=remove_eq_conds(thd, item, &tmp_cond_value);
if (!new_item)
li.remove();
else if (item != new_item)
@@ -4465,7 +4472,7 @@ remove_eq_conds(COND *cond,Item::cond_result *cond_value)
}
}
if (should_fix_fields)
- cond->fix_fields(current_thd,0, &cond);
+ cond->update_used_tables();
if (!((Item_cond*) cond)->argument_list()->elements ||
*cond_value != Item::COND_OK)
@@ -4492,7 +4499,6 @@ remove_eq_conds(COND *cond,Item::cond_result *cond_value)
Item_func_isnull *func=(Item_func_isnull*) cond;
Item **args= func->arguments();
- THD *thd=current_thd;
if (args[0]->type() == Item::FIELD_ITEM)
{
Field *field=((Item_field*) args[0])->field;
@@ -7913,10 +7919,15 @@ find_order_in_list(THD *thd, Item **ref_pointer_array,
}
order->in_field_list=0;
Item *it= *order->item;
- if (it->fix_fields(thd, tables, order->item) ||
- //'it' ressigned because fix_field can change it
- (it= *order->item)->check_cols(1) ||
- thd->is_fatal_error)
+ /*
+ we check it->fixed because Item_func_group_concat can put
+ arguments for which fix_fields already was called
+ */
+ if (!it->fixed &&
+ (it->fix_fields(thd, tables, order->item) ||
+ //'it' ressigned because fix_field can change it
+ (it= *order->item)->check_cols(1) ||
+ thd->is_fatal_error))
return 1; // Wrong field
uint el= all_fields.elements;
all_fields.push_front(it); // Add new field to field list