Commit e5b5f453 authored by unknown's avatar unknown

subselect in having clause

fixed bug in sum function in subselect


mysql-test/r/subselect.result:
  subselect in having clause
mysql-test/t/subselect.test:
  subselect in having clause
sql/item.cc:
  subselect in having clause
sql/item.h:
  subselect in having clause
sql/item_cmpfunc.cc:
  subselect in having clause
sql/item_cmpfunc.h:
  subselect in having clause
sql/item_func.cc:
  subselect in having clause
sql/item_func.h:
  subselect in having clause
sql/item_strfunc.h:
  subselect in having clause
sql/item_subselect.cc:
  subselect in having clause
sql/item_subselect.h:
  subselect in having clause
sql/item_uniq.h:
  subselect in having clause
sql/sql_base.cc:
  subselect in having clause
sql/sql_class.cc:
  subselect in having clause
sql/sql_class.h:
  subselect in having clause
sql/sql_handler.cc:
  subselect in having clause
sql/sql_lex.cc:
  subselect in having clause
sql/sql_lex.h:
  subselect in having clause
sql/sql_prepare.cc:
  subselect in having clause
sql/sql_yacc.yy:
  subselect in having clause
parent 96991914
...@@ -65,8 +65,8 @@ a ...@@ -65,8 +65,8 @@ a
select b,(select avg(t2.a+(select min(t3.a) from t3 where t3.a >= t4.a)) from t2) from t4; select b,(select avg(t2.a+(select min(t3.a) from t3 where t3.a >= t4.a)) from t2) from t4;
b (select avg(t2.a+(select min(t3.a) from t3 where t3.a >= t4.a)) from t2) b (select avg(t2.a+(select min(t3.a) from t3 where t3.a >= t4.a)) from t2)
8 7.5000 8 7.5000
8 6.0000 8 4.5000
9 5.5000 9 7.5000
select * from t3 where exists (select * from t2 where t2.b=t3.a); select * from t3 where exists (select * from t2 where t2.b=t3.a);
a a
7 7
...@@ -74,4 +74,12 @@ select * from t3 where not exists (select * from t2 where t2.b=t3.a); ...@@ -74,4 +74,12 @@ select * from t3 where not exists (select * from t2 where t2.b=t3.a);
a a
6 6
3 3
insert into t4 values (12,7),(1,7),(10,9),(9,6),(7,6),(3,9);
select b,max(a) as ma from t4 group by b having b < (select max(t2.a)
from t2 where t2.b=t4.b);
b ma
select b,max(a) as ma from t4 group by b having b >= (select max(t2.a)
from t2 where t2.b=t4.b);
b ma
7 12
drop table t1,t2,t3,t4; drop table t1,t2,t3,t4;
...@@ -28,4 +28,9 @@ select * from t1 where t1.a=(select t2.a from t2 where t2.b=(select max(a) from ...@@ -28,4 +28,9 @@ select * from t1 where t1.a=(select t2.a from t2 where t2.b=(select max(a) from
select b,(select avg(t2.a+(select min(t3.a) from t3 where t3.a >= t4.a)) from t2) from t4; select b,(select avg(t2.a+(select min(t3.a) from t3 where t3.a >= t4.a)) from t2) from t4;
select * from t3 where exists (select * from t2 where t2.b=t3.a); select * from t3 where exists (select * from t2 where t2.b=t3.a);
select * from t3 where not exists (select * from t2 where t2.b=t3.a); select * from t3 where not exists (select * from t2 where t2.b=t3.a);
insert into t4 values (12,7),(1,7),(10,9),(9,6),(7,6),(3,9);
select b,max(a) as ma from t4 group by b having b < (select max(t2.a)
from t2 where t2.b=t4.b);
select b,max(a) as ma from t4 group by b having b >= (select max(t2.a)
from t2 where t2.b=t4.b);
drop table t1,t2,t3,t4; drop table t1,t2,t3,t4;
...@@ -446,12 +446,13 @@ String *Item_copy_string::val_str(String *str) ...@@ -446,12 +446,13 @@ String *Item_copy_string::val_str(String *str)
/* ARGSUSED */ /* ARGSUSED */
bool Item::fix_fields(THD *thd, bool Item::fix_fields(THD *thd,
struct st_table_list *list) struct st_table_list *list,
Item ** ref)
{ {
return 0; return 0;
} }
bool Item_field::fix_fields(THD *thd,TABLE_LIST *tables) bool Item_field::fix_fields(THD *thd, TABLE_LIST *tables, Item **ref)
{ {
if (!field) // If field is not checked if (!field) // If field is not checked
{ {
...@@ -467,7 +468,7 @@ bool Item_field::fix_fields(THD *thd,TABLE_LIST *tables) ...@@ -467,7 +468,7 @@ bool Item_field::fix_fields(THD *thd,TABLE_LIST *tables)
mention of table name, but if we join tables in one list it will mention of table name, but if we join tables in one list it will
cause error ER_NON_UNIQ_ERROR in find_field_in_tables. cause error ER_NON_UNIQ_ERROR in find_field_in_tables.
*/ */
SELECT_LEX *last; SELECT_LEX *last= 0;
for (SELECT_LEX *sl= thd->lex.select->outer_select(); for (SELECT_LEX *sl= thd->lex.select->outer_select();
sl && !tmp; sl && !tmp;
sl= sl->outer_select()) sl= sl->outer_select())
...@@ -476,6 +477,8 @@ bool Item_field::fix_fields(THD *thd,TABLE_LIST *tables) ...@@ -476,6 +477,8 @@ bool Item_field::fix_fields(THD *thd,TABLE_LIST *tables)
if (!tmp) if (!tmp)
return 1; return 1;
else else
{
depended_from= last;
/* /*
Mark all selects from resolved to 1 before select where was Mark all selects from resolved to 1 before select where was
found table as depended (of select where was found table) found table as depended (of select where was found table)
...@@ -493,6 +496,7 @@ bool Item_field::fix_fields(THD *thd,TABLE_LIST *tables) ...@@ -493,6 +496,7 @@ bool Item_field::fix_fields(THD *thd,TABLE_LIST *tables)
tbl= tbl->next) tbl= tbl->next)
tbl->shared= 1; tbl->shared= 1;
} }
}
} }
set_field(tmp); set_field(tmp);
} }
...@@ -504,6 +508,14 @@ bool Item_field::fix_fields(THD *thd,TABLE_LIST *tables) ...@@ -504,6 +508,14 @@ bool Item_field::fix_fields(THD *thd,TABLE_LIST *tables)
table->used_fields++; table->used_fields++;
table->used_keys&=field->part_of_key; table->used_keys&=field->part_of_key;
} }
if (depended_from != 0 && depended_from->having_fix_field)
{
*ref= new Item_ref((char *)db_name, (char *)table_name,
(char *)field_name);
if (!*ref)
return 1;
return (*ref)->fix_fields(thd, tables, ref);
}
return 0; return 0;
} }
...@@ -787,12 +799,50 @@ bool Item_null::send(THD *thd, String *packet) ...@@ -787,12 +799,50 @@ bool Item_null::send(THD *thd, String *packet)
Find field in select list having the same name Find field in select list having the same name
*/ */
bool Item_ref::fix_fields(THD *thd,TABLE_LIST *tables) bool Item_ref::fix_fields(THD *thd,TABLE_LIST *tables, Item **reference)
{ {
if (!ref) if (!ref)
{ {
if (!(ref=find_item_in_list(this,thd->lex.select->item_list))) if (!(ref= find_item_in_list(this,thd->lex.select->item_list)))
return 1; {
/*
We can't find table field in table list of current select,
consequently we have to find it in outer subselect(s).
We can't join lists of outer & current select, because of scope
of view rules. For example if both tables (outer & current) have
field 'field' it is not mistake to refer to this field without
mention of table name, but if we join tables in one list it will
cause error ER_NON_UNIQ_ERROR in find_field_in_tables.
*/
SELECT_LEX *last=0;
for (SELECT_LEX *sl= thd->lex.select->outer_select();
sl && !ref;
sl= sl->outer_select())
ref= find_item_in_list(this, (last= sl)->item_list);
if (!ref)
return 1;
else
{
depended_from= last;
/*
Mark all selects from resolved to 1 before select where was
found table as depended (of select where was found table)
*/
for (SELECT_LEX *s= thd->lex.select;
s &&s != last;
s= s->outer_select())
if( !s->depended )
{
s->depended= 1; //Select is depended of outer select
//Tables will be reopened many times
for (TABLE_LIST *tbl=
(TABLE_LIST*)s->table_list.first;
tbl;
tbl= tbl->next)
tbl->shared= 1;
}
}
}
max_length= (*ref)->max_length; max_length= (*ref)->max_length;
maybe_null= (*ref)->maybe_null; maybe_null= (*ref)->maybe_null;
decimals= (*ref)->decimals; decimals= (*ref)->decimals;
......
...@@ -52,7 +52,7 @@ class Item { ...@@ -52,7 +52,7 @@ class Item {
virtual ~Item() { name=0; } /*lint -e1509 */ virtual ~Item() { name=0; } /*lint -e1509 */
void set_name(char* str,uint length=0); void set_name(char* str,uint length=0);
void init_make_field(Send_field *tmp_field,enum enum_field_types type); void init_make_field(Send_field *tmp_field,enum enum_field_types type);
virtual bool fix_fields(THD *,struct st_table_list *); virtual bool fix_fields(THD *, struct st_table_list *, Item **);
virtual bool save_in_field(Field *field); virtual bool save_in_field(Field *field);
virtual void save_org_in_field(Field *field) virtual void save_org_in_field(Field *field)
{ (void) save_in_field(field); } { (void) save_in_field(field); }
...@@ -85,15 +85,18 @@ class Item { ...@@ -85,15 +85,18 @@ class Item {
}; };
class st_select_lex;
class Item_ident :public Item class Item_ident :public Item
{ {
public: public:
const char *db_name; const char *db_name;
const char *table_name; const char *table_name;
const char *field_name; const char *field_name;
st_select_lex *depended_from;
Item_ident(const char *db_name_par,const char *table_name_par, Item_ident(const char *db_name_par,const char *table_name_par,
const char *field_name_par) const char *field_name_par)
:db_name(db_name_par),table_name(table_name_par),field_name(field_name_par) :db_name(db_name_par),table_name(table_name_par),
field_name(field_name_par), depended_from(0)
{ name = (char*) field_name_par; } { name = (char*) field_name_par; }
const char *full_name() const; const char *full_name() const;
}; };
...@@ -120,7 +123,7 @@ class Item_field :public Item_ident ...@@ -120,7 +123,7 @@ class Item_field :public Item_ident
String *str_result(String* tmp); String *str_result(String* tmp);
bool send(THD *thd, String *str_arg) { return result_field->send(thd,str_arg); } bool send(THD *thd, String *str_arg) { return result_field->send(thd,str_arg); }
void make_field(Send_field *field); void make_field(Send_field *field);
bool fix_fields(THD *,struct st_table_list *); bool fix_fields(THD *, struct st_table_list *, Item **);
bool save_in_field(Field *field); bool save_in_field(Field *field);
void save_org_in_field(Field *field); void save_org_in_field(Field *field);
table_map used_tables() const; table_map used_tables() const;
...@@ -390,7 +393,7 @@ class Item_ref :public Item_ident ...@@ -390,7 +393,7 @@ class Item_ref :public Item_ident
} }
bool send(THD *thd, String *tmp) { return (*ref)->send(thd, tmp); } bool send(THD *thd, String *tmp) { return (*ref)->send(thd, tmp); }
void make_field(Send_field *field) { (*ref)->make_field(field); } void make_field(Send_field *field) { (*ref)->make_field(field); }
bool fix_fields(THD *,struct st_table_list *); bool fix_fields(THD *, struct st_table_list *, Item **);
bool save_in_field(Field *field) { return (*ref)->save_in_field(field); } bool save_in_field(Field *field) { return (*ref)->save_in_field(field); }
void save_org_in_field(Field *field) { (*ref)->save_org_in_field(field); } void save_org_in_field(Field *field) { (*ref)->save_org_in_field(field); }
enum Item_result result_type () const { return (*ref)->result_type(); } enum Item_result result_type () const { return (*ref)->result_type(); }
......
...@@ -727,12 +727,12 @@ double Item_func_case::val() ...@@ -727,12 +727,12 @@ double Item_func_case::val()
bool bool
Item_func_case::fix_fields(THD *thd,TABLE_LIST *tables) Item_func_case::fix_fields(THD *thd, TABLE_LIST *tables, Item **ref)
{ {
if (first_expr && first_expr->fix_fields(thd,tables) || if (first_expr && first_expr->fix_fields(thd, tables, &first_expr) ||
else_expr && else_expr->fix_fields(thd,tables)) else_expr && else_expr->fix_fields(thd, tables, &else_expr))
return 1; return 1;
if (Item_func::fix_fields(thd,tables)) if (Item_func::fix_fields(thd, tables, ref))
return 1; return 1;
if (first_expr) if (first_expr)
{ {
...@@ -1074,7 +1074,7 @@ longlong Item_func_bit_and::val_int() ...@@ -1074,7 +1074,7 @@ longlong Item_func_bit_and::val_int()
bool bool
Item_cond::fix_fields(THD *thd,TABLE_LIST *tables) Item_cond::fix_fields(THD *thd, TABLE_LIST *tables, Item **ref)
{ {
List_iterator<Item> li(list); List_iterator<Item> li(list);
Item *item; Item *item;
...@@ -1096,7 +1096,7 @@ Item_cond::fix_fields(THD *thd,TABLE_LIST *tables) ...@@ -1096,7 +1096,7 @@ Item_cond::fix_fields(THD *thd,TABLE_LIST *tables)
#endif #endif
item= *li.ref(); // new current item item= *li.ref(); // new current item
} }
if (item->fix_fields(thd,tables)) if (item->fix_fields(thd, tables, li.ref()))
return 1; /* purecov: inspected */ return 1; /* purecov: inspected */
used_tables_cache|=item->used_tables(); used_tables_cache|=item->used_tables();
with_sum_func= with_sum_func || item->with_sum_func; with_sum_func= with_sum_func || item->with_sum_func;
...@@ -1272,9 +1272,9 @@ Item_func::optimize_type Item_func_like::select_optimize() const ...@@ -1272,9 +1272,9 @@ Item_func::optimize_type Item_func_like::select_optimize() const
return OPTIMIZE_NONE; return OPTIMIZE_NONE;
} }
bool Item_func_like::fix_fields(THD *thd,struct st_table_list *tlist) bool Item_func_like::fix_fields(THD *thd, TABLE_LIST *tlist, Item ** ref)
{ {
if (Item_bool_func2::fix_fields(thd, tlist)) if (Item_bool_func2::fix_fields(thd, tlist, ref))
return 1; return 1;
/* /*
...@@ -1324,9 +1324,10 @@ bool Item_func_like::fix_fields(THD *thd,struct st_table_list *tlist) ...@@ -1324,9 +1324,10 @@ bool Item_func_like::fix_fields(THD *thd,struct st_table_list *tlist)
#ifdef USE_REGEX #ifdef USE_REGEX
bool bool
Item_func_regex::fix_fields(THD *thd,TABLE_LIST *tables) Item_func_regex::fix_fields(THD *thd, TABLE_LIST *tables, Item **ref)
{ {
if (args[0]->fix_fields(thd,tables) || args[1]->fix_fields(thd,tables)) if (args[0]->fix_fields(thd, tables, args) ||
args[1]->fix_fields(thd,tables, args + 1))
return 1; /* purecov: inspected */ return 1; /* purecov: inspected */
with_sum_func=args[0]->with_sum_func || args[1]->with_sum_func; with_sum_func=args[0]->with_sum_func || args[1]->with_sum_func;
max_length=1; decimals=0; max_length=1; decimals=0;
......
...@@ -177,9 +177,10 @@ class Item_func_interval :public Item_int_func ...@@ -177,9 +177,10 @@ class Item_func_interval :public Item_int_func
Item_func_interval(Item *a,List<Item> &list) Item_func_interval(Item *a,List<Item> &list)
:Item_int_func(list),item(a),intervals(0) {} :Item_int_func(list),item(a),intervals(0) {}
longlong val_int(); longlong val_int();
bool fix_fields(THD *thd,struct st_table_list *tlist) bool fix_fields(THD *thd, struct st_table_list *tlist, Item **ref)
{ {
return (item->fix_fields(thd,tlist) || Item_func::fix_fields(thd,tlist)); return (item->fix_fields(thd, tlist, &item) ||
Item_func::fix_fields(thd, tlist, ref));
} }
void fix_length_and_dec(); void fix_length_and_dec();
~Item_func_interval() { delete item; } ~Item_func_interval() { delete item; }
...@@ -259,7 +260,7 @@ class Item_func_case :public Item_func ...@@ -259,7 +260,7 @@ class Item_func_case :public Item_func
enum Item_result result_type () const { return cached_result_type; } enum Item_result result_type () const { return cached_result_type; }
const char *func_name() const { return "case"; } const char *func_name() const { return "case"; }
void print(String *str); void print(String *str);
bool fix_fields(THD *thd,struct st_table_list *tlist); bool fix_fields(THD *thd, struct st_table_list *tlist, Item **ref);
Item *find_item(String *str); Item *find_item(String *str);
}; };
...@@ -409,9 +410,10 @@ class Item_func_in :public Item_int_func ...@@ -409,9 +410,10 @@ class Item_func_in :public Item_int_func
Item_func_in(Item *a,List<Item> &list) Item_func_in(Item *a,List<Item> &list)
:Item_int_func(list),item(a),array(0),in_item(0) {} :Item_int_func(list),item(a),array(0),in_item(0) {}
longlong val_int(); longlong val_int();
bool fix_fields(THD *thd,struct st_table_list *tlist) bool fix_fields(THD *thd, struct st_table_list *tlist, Item **ref)
{ {
return (item->fix_fields(thd,tlist) || Item_func::fix_fields(thd,tlist)); return (item->fix_fields(thd, tlist, &item) ||
Item_func::fix_fields(thd, tlist, ref));
} }
void fix_length_and_dec(); void fix_length_and_dec();
~Item_func_in() { delete item; delete array; delete in_item; } ~Item_func_in() { delete item; delete array; delete in_item; }
...@@ -505,7 +507,7 @@ class Item_func_like :public Item_bool_func2 ...@@ -505,7 +507,7 @@ class Item_func_like :public Item_bool_func2
cond_result eq_cmp_result() const { return COND_TRUE; } cond_result eq_cmp_result() const { return COND_TRUE; }
const char *func_name() const { return "like"; } const char *func_name() const { return "like"; }
void fix_length_and_dec(); void fix_length_and_dec();
bool fix_fields(THD *thd,struct st_table_list *tlist); bool fix_fields(THD *thd, struct st_table_list *tlist, Item **ref);
}; };
#ifdef USE_REGEX #ifdef USE_REGEX
...@@ -523,7 +525,7 @@ class Item_func_regex :public Item_bool_func ...@@ -523,7 +525,7 @@ class Item_func_regex :public Item_bool_func
regex_compiled(0),regex_is_const(0) {} regex_compiled(0),regex_is_const(0) {}
~Item_func_regex(); ~Item_func_regex();
longlong val_int(); longlong val_int();
bool fix_fields(THD *thd,struct st_table_list *tlist); bool fix_fields(THD *thd, struct st_table_list *tlist, Item **ref);
const char *func_name() const { return "regex"; } const char *func_name() const { return "regex"; }
}; };
...@@ -552,7 +554,7 @@ class Item_cond :public Item_bool_func ...@@ -552,7 +554,7 @@ class Item_cond :public Item_bool_func
{ list.push_back(i1); list.push_back(i2); } { list.push_back(i1); list.push_back(i2); }
~Item_cond() { list.delete_elements(); } ~Item_cond() { list.delete_elements(); }
bool add(Item *item) { return list.push_back(item); } bool add(Item *item) { return list.push_back(item); }
bool fix_fields(THD *,struct st_table_list *); bool fix_fields(THD *, struct st_table_list *, Item **ref);
enum Type type() const { return COND_ITEM; } enum Type type() const { return COND_ITEM; }
List<Item>* argument_list() { return &list; } List<Item>* argument_list() { return &list; }
......
...@@ -58,7 +58,7 @@ Item_func::Item_func(List<Item> &list) ...@@ -58,7 +58,7 @@ Item_func::Item_func(List<Item> &list)
} }
bool bool
Item_func::fix_fields(THD *thd,TABLE_LIST *tables) Item_func::fix_fields(THD *thd, TABLE_LIST *tables, Item **ref)
{ {
Item **arg,**arg_end; Item **arg,**arg_end;
char buff[STACK_BUFF_ALLOC]; // Max argument in function char buff[STACK_BUFF_ALLOC]; // Max argument in function
...@@ -72,7 +72,7 @@ Item_func::fix_fields(THD *thd,TABLE_LIST *tables) ...@@ -72,7 +72,7 @@ Item_func::fix_fields(THD *thd,TABLE_LIST *tables)
{ // Print purify happy { // Print purify happy
for (arg=args, arg_end=args+arg_count; arg != arg_end ; arg++) for (arg=args, arg_end=args+arg_count; arg != arg_end ; arg++)
{ {
if ((*arg)->fix_fields(thd,tables)) if ((*arg)->fix_fields(thd, tables, arg))
return 1; /* purecov: inspected */ return 1; /* purecov: inspected */
if ((*arg)->maybe_null) if ((*arg)->maybe_null)
maybe_null=1; maybe_null=1;
...@@ -1102,7 +1102,7 @@ udf_handler::~udf_handler() ...@@ -1102,7 +1102,7 @@ udf_handler::~udf_handler()
bool bool
udf_handler::fix_fields(THD *thd,TABLE_LIST *tables,Item_result_field *func, udf_handler::fix_fields(THD *thd, TABLE_LIST *tables, Item_result_field *func,
uint arg_count, Item **arguments) uint arg_count, Item **arguments)
{ {
char buff[STACK_BUFF_ALLOC]; // Max argument in function char buff[STACK_BUFF_ALLOC]; // Max argument in function
...@@ -1146,7 +1146,7 @@ udf_handler::fix_fields(THD *thd,TABLE_LIST *tables,Item_result_field *func, ...@@ -1146,7 +1146,7 @@ udf_handler::fix_fields(THD *thd,TABLE_LIST *tables,Item_result_field *func,
arg != arg_end ; arg != arg_end ;
arg++,i++) arg++,i++)
{ {
if ((*arg)->fix_fields(thd,tables)) if ((*arg)->fix_fields(thd, tables, arg))
return 1; return 1;
if ((*arg)->binary) if ((*arg)->binary)
func->binary=1; func->binary=1;
...@@ -1765,11 +1765,12 @@ static user_var_entry *get_variable(HASH *hash, LEX_STRING &name, ...@@ -1765,11 +1765,12 @@ static user_var_entry *get_variable(HASH *hash, LEX_STRING &name,
} }
bool Item_func_set_user_var::fix_fields(THD *thd,TABLE_LIST *tables) bool Item_func_set_user_var::fix_fields(THD *thd, TABLE_LIST *tables,
Item **ref)
{ {
if (!thd) if (!thd)
thd=current_thd; thd=current_thd;
if (Item_func::fix_fields(thd,tables) || if (Item_func::fix_fields(thd, tables, ref) ||
!(entry= get_variable(&thd->user_vars, name, 1))) !(entry= get_variable(&thd->user_vars, name, 1)))
return 1; return 1;
entry->update_query_id=thd->query_id; entry->update_query_id=thd->query_id;
...@@ -2095,7 +2096,7 @@ void Item_func_match::init_search(bool no_order) ...@@ -2095,7 +2096,7 @@ void Item_func_match::init_search(bool no_order)
} }
} }
bool Item_func_match::fix_fields(THD *thd,struct st_table_list *tlist) bool Item_func_match::fix_fields(THD *thd, TABLE_LIST *tlist, Item **ref)
{ {
List_iterator<Item> li(fields); List_iterator<Item> li(fields);
Item *item; Item *item;
...@@ -2108,7 +2109,7 @@ bool Item_func_match::fix_fields(THD *thd,struct st_table_list *tlist) ...@@ -2108,7 +2109,7 @@ bool Item_func_match::fix_fields(THD *thd,struct st_table_list *tlist)
modifications to find_best and auto_close as complement to auto_init code modifications to find_best and auto_close as complement to auto_init code
above. above.
*/ */
if (Item_func::fix_fields(thd,tlist) || !const_item()) if (Item_func::fix_fields(thd, tlist, ref) || !const_item())
{ {
my_error(ER_WRONG_ARGUMENTS,MYF(0),"AGAINST"); my_error(ER_WRONG_ARGUMENTS,MYF(0),"AGAINST");
return 1; return 1;
...@@ -2116,7 +2117,7 @@ bool Item_func_match::fix_fields(THD *thd,struct st_table_list *tlist) ...@@ -2116,7 +2117,7 @@ bool Item_func_match::fix_fields(THD *thd,struct st_table_list *tlist)
while ((item=li++)) while ((item=li++))
{ {
if (item->fix_fields(thd,tlist)) if (item->fix_fields(thd, tlist, li.ref()))
return 1; return 1;
if (item->type() == Item::REF_ITEM) if (item->type() == Item::REF_ITEM)
li.replace(item= *((Item_ref *)item)->ref); li.replace(item= *((Item_ref *)item)->ref);
......
...@@ -99,7 +99,7 @@ class Item_func :public Item_result_field ...@@ -99,7 +99,7 @@ class Item_func :public Item_result_field
} }
Item_func(List<Item> &list); Item_func(List<Item> &list);
~Item_func() {} /* Nothing to do; Items are freed automaticly */ ~Item_func() {} /* Nothing to do; Items are freed automaticly */
bool fix_fields(THD *,struct st_table_list *); bool fix_fields(THD *,struct st_table_list *, Item **ref);
void make_field(Send_field *field); void make_field(Send_field *field);
table_map used_tables() const; table_map used_tables() const;
void update_used_tables(); void update_used_tables();
...@@ -567,9 +567,10 @@ class Item_func_field :public Item_int_func ...@@ -567,9 +567,10 @@ class Item_func_field :public Item_int_func
Item_func_field(Item *a,List<Item> &list) :Item_int_func(list),item(a) {} Item_func_field(Item *a,List<Item> &list) :Item_int_func(list),item(a) {}
~Item_func_field() { delete item; } ~Item_func_field() { delete item; }
longlong val_int(); longlong val_int();
bool fix_fields(THD *thd,struct st_table_list *tlist) bool fix_fields(THD *thd,struct st_table_list *tlist, Item **ref)
{ {
return (item->fix_fields(thd,tlist) || Item_func::fix_fields(thd,tlist)); return (item->fix_fields(thd, tlist, &item) ||
Item_func::fix_fields(thd, tlist, ref));
} }
void update_used_tables() void update_used_tables()
{ {
...@@ -708,11 +709,11 @@ class Item_udf_func :public Item_func ...@@ -708,11 +709,11 @@ class Item_udf_func :public Item_func
:Item_func(list), udf(udf_arg) {} :Item_func(list), udf(udf_arg) {}
~Item_udf_func() {} ~Item_udf_func() {}
const char *func_name() const { return udf.name(); } const char *func_name() const { return udf.name(); }
bool fix_fields(THD *thd,struct st_table_list *tables) bool fix_fields(THD *thd, struct st_table_list *tables, Item **ref)
{ {
bool res=udf.fix_fields(thd,tables,this,arg_count,args); bool res= udf.fix_fields(thd, tables, this, arg_count, args);
used_tables_cache=udf.used_tables_cache; used_tables_cache= udf.used_tables_cache;
const_item_cache=udf.const_item_cache; const_item_cache= udf.const_item_cache;
return res; return res;
} }
Item_result result_type () const { return udf.result_type(); } Item_result result_type () const { return udf.result_type(); }
...@@ -867,7 +868,7 @@ class Item_func_set_user_var :public Item_func ...@@ -867,7 +868,7 @@ class Item_func_set_user_var :public Item_func
void update_hash(void *ptr, uint length, enum Item_result type); void update_hash(void *ptr, uint length, enum Item_result type);
bool update(); bool update();
enum Item_result result_type () const { return cached_result_type; } enum Item_result result_type () const { return cached_result_type; }
bool fix_fields(THD *thd,struct st_table_list *tables); bool fix_fields(THD *thd, struct st_table_list *tables, Item **ref);
void fix_length_and_dec(); void fix_length_and_dec();
void print(String *str); void print(String *str);
const char *func_name() const { return "set_user_var"; } const char *func_name() const { return "set_user_var"; }
...@@ -941,7 +942,7 @@ class Item_func_match :public Item_real_func ...@@ -941,7 +942,7 @@ class Item_func_match :public Item_real_func
} }
enum Functype functype() const { return FT_FUNC; } enum Functype functype() const { return FT_FUNC; }
void update_used_tables() {} void update_used_tables() {}
bool fix_fields(THD *thd,struct st_table_list *tlist); bool fix_fields(THD *thd, struct st_table_list *tlist, Item **ref);
bool eq(const Item *, bool binary_cmp) const; bool eq(const Item *, bool binary_cmp) const;
longlong val_int() { return val()!=0.0; } longlong val_int() { return val()!=0.0; }
double val(); double val();
......
...@@ -79,10 +79,10 @@ class Item_func_concat_ws :public Item_str_func ...@@ -79,10 +79,10 @@ class Item_func_concat_ws :public Item_str_func
String *val_str(String *); String *val_str(String *);
void fix_length_and_dec(); void fix_length_and_dec();
void update_used_tables(); void update_used_tables();
bool fix_fields(THD *thd,struct st_table_list *tlist) bool fix_fields(THD *thd, TABLE_LIST *tlist, Item **ref)
{ {
return (separator->fix_fields(thd,tlist) return (separator->fix_fields(thd, tlist, &separator)
|| Item_func::fix_fields(thd,tlist)); || Item_func::fix_fields(thd, tlist, ref));
} }
const char *func_name() const { return "concat_ws"; } const char *func_name() const { return "concat_ws"; }
}; };
...@@ -325,9 +325,10 @@ class Item_func_elt :public Item_str_func ...@@ -325,9 +325,10 @@ class Item_func_elt :public Item_str_func
double val(); double val();
longlong val_int(); longlong val_int();
String *val_str(String *str); String *val_str(String *str);
bool fix_fields(THD *thd,struct st_table_list *tlist) bool fix_fields(THD *thd, TABLE_LIST *tlist, Item **ref)
{ {
return (item->fix_fields(thd,tlist) || Item_func::fix_fields(thd,tlist)); return (item->fix_fields(thd, tlist, &item) ||
Item_func::fix_fields(thd, tlist, ref));
} }
void fix_length_and_dec(); void fix_length_and_dec();
void update_used_tables(); void update_used_tables();
...@@ -344,9 +345,10 @@ class Item_func_make_set :public Item_str_func ...@@ -344,9 +345,10 @@ class Item_func_make_set :public Item_str_func
Item_func_make_set(Item *a,List<Item> &list) :Item_str_func(list),item(a) {} Item_func_make_set(Item *a,List<Item> &list) :Item_str_func(list),item(a) {}
~Item_func_make_set() { delete item; } ~Item_func_make_set() { delete item; }
String *val_str(String *str); String *val_str(String *str);
bool fix_fields(THD *thd,struct st_table_list *tlist) bool fix_fields(THD *thd, TABLE_LIST *tlist, Item **ref)
{ {
return (item->fix_fields(thd,tlist) || Item_func::fix_fields(thd,tlist)); return (item->fix_fields(thd, tlist, &item) ||
Item_func::fix_fields(thd, tlist, ref));
} }
void fix_length_and_dec(); void fix_length_and_dec();
void update_used_tables(); void update_used_tables();
......
...@@ -75,15 +75,8 @@ void Item_subselect::make_field (Send_field *tmp_field) ...@@ -75,15 +75,8 @@ void Item_subselect::make_field (Send_field *tmp_field)
} }
} }
bool Item_subselect::fix_fields(THD *thd,TABLE_LIST *tables) bool Item_subselect::fix_fields(THD *thd, TABLE_LIST *tables, Item **ref)
{ {
if (thd->having_fix_field)
{
//TODO: subselects in having do not suported now
my_printf_error(ER_SYNTAX_ERROR, ER(ER_SYNTAX_ERROR), MYF(0));
return 1;
}
// Is it one field subselect? // Is it one field subselect?
if (select_lex->item_list.elements > max_columns) if (select_lex->item_list.elements > max_columns)
{ {
......
...@@ -63,7 +63,7 @@ class Item_subselect :public Item ...@@ -63,7 +63,7 @@ class Item_subselect :public Item
enum Type type() const; enum Type type() const;
bool is_null() { return null_value; } bool is_null() { return null_value; }
void make_field (Send_field *); void make_field (Send_field *);
bool fix_fields(THD *thd, TABLE_LIST *tables); bool fix_fields(THD *thd, TABLE_LIST *tables, Item **ref);
table_map used_tables() const; table_map used_tables() const;
friend class select_subselect; friend class select_subselect;
......
...@@ -112,7 +112,7 @@ Item_sum_int::val_str(String *str) ...@@ -112,7 +112,7 @@ Item_sum_int::val_str(String *str)
bool bool
Item_sum_num::fix_fields(THD *thd,TABLE_LIST *tables) Item_sum_num::fix_fields(THD *thd, TABLE_LIST *tables, Item **ref)
{ {
if (!thd->allow_sum_func) if (!thd->allow_sum_func)
{ {
...@@ -124,7 +124,7 @@ Item_sum_num::fix_fields(THD *thd,TABLE_LIST *tables) ...@@ -124,7 +124,7 @@ Item_sum_num::fix_fields(THD *thd,TABLE_LIST *tables)
maybe_null=0; maybe_null=0;
for (uint i=0 ; i < arg_count ; i++) for (uint i=0 ; i < arg_count ; i++)
{ {
if (args[i]->fix_fields(thd,tables)) if (args[i]->fix_fields(thd, tables, args + i))
return 1; return 1;
if (decimals < args[i]->decimals) if (decimals < args[i]->decimals)
decimals=args[i]->decimals; decimals=args[i]->decimals;
...@@ -140,7 +140,7 @@ Item_sum_num::fix_fields(THD *thd,TABLE_LIST *tables) ...@@ -140,7 +140,7 @@ Item_sum_num::fix_fields(THD *thd,TABLE_LIST *tables)
bool bool
Item_sum_hybrid::fix_fields(THD *thd,TABLE_LIST *tables) Item_sum_hybrid::fix_fields(THD *thd, TABLE_LIST *tables, Item **ref)
{ {
Item *item=args[0]; Item *item=args[0];
if (!thd->allow_sum_func) if (!thd->allow_sum_func)
...@@ -149,7 +149,7 @@ Item_sum_hybrid::fix_fields(THD *thd,TABLE_LIST *tables) ...@@ -149,7 +149,7 @@ Item_sum_hybrid::fix_fields(THD *thd,TABLE_LIST *tables)
return 1; return 1;
} }
thd->allow_sum_func=0; // No included group funcs thd->allow_sum_func=0; // No included group funcs
if (item->fix_fields(thd,tables)) if (item->fix_fields(thd, tables, args))
return 1; return 1;
hybrid_type=item->result_type(); hybrid_type=item->result_type();
if (hybrid_type == INT_RESULT) if (hybrid_type == INT_RESULT)
...@@ -930,9 +930,10 @@ Item_sum_count_distinct::~Item_sum_count_distinct() ...@@ -930,9 +930,10 @@ Item_sum_count_distinct::~Item_sum_count_distinct()
} }
bool Item_sum_count_distinct::fix_fields(THD *thd,TABLE_LIST *tables) bool Item_sum_count_distinct::fix_fields(THD *thd, TABLE_LIST *tables,
Item **ref)
{ {
if (Item_sum_num::fix_fields(thd,tables) || if (Item_sum_num::fix_fields(thd, tables, ref) ||
!(tmp_table_param= new TMP_TABLE_PARAM)) !(tmp_table_param= new TMP_TABLE_PARAM))
return 1; return 1;
return 0; return 0;
......
...@@ -80,7 +80,7 @@ class Item_sum_num :public Item_sum ...@@ -80,7 +80,7 @@ class Item_sum_num :public Item_sum
Item_sum_num(Item *item_par) :Item_sum(item_par) {} Item_sum_num(Item *item_par) :Item_sum(item_par) {}
Item_sum_num(Item *a, Item* b) :Item_sum(a,b) {} Item_sum_num(Item *a, Item* b) :Item_sum(a,b) {}
Item_sum_num(List<Item> &list) :Item_sum(list) {} Item_sum_num(List<Item> &list) :Item_sum(list) {}
bool fix_fields(THD *,struct st_table_list *); bool fix_fields(THD *, TABLE_LIST *, Item **);
longlong val_int() { return (longlong) val(); } /* Real as default */ longlong val_int() { return (longlong) val(); } /* Real as default */
String *val_str(String*str); String *val_str(String*str);
void reset_field(); void reset_field();
...@@ -146,7 +146,7 @@ class Item_sum_count_distinct :public Item_sum_int ...@@ -146,7 +146,7 @@ class Item_sum_count_distinct :public Item_sum_int
{ {
TABLE *table; TABLE *table;
table_map used_table_cache; table_map used_table_cache;
bool fix_fields(THD *thd,TABLE_LIST *tables); bool fix_fields(THD *thd, TABLE_LIST *tables, Item **ref);
uint32 *field_lengths; uint32 *field_lengths;
TMP_TABLE_PARAM *tmp_table_param; TMP_TABLE_PARAM *tmp_table_param;
TREE tree; TREE tree;
...@@ -283,7 +283,7 @@ class Item_sum_hybrid :public Item_sum ...@@ -283,7 +283,7 @@ class Item_sum_hybrid :public Item_sum
Item_sum_hybrid(Item *item_par,int sign) :Item_sum(item_par),cmp_sign(sign), Item_sum_hybrid(Item *item_par,int sign) :Item_sum(item_par),cmp_sign(sign),
used_table_cache(~(table_map) 0) used_table_cache(~(table_map) 0)
{} {}
bool fix_fields(THD *,struct st_table_list *); bool fix_fields(THD *, TABLE_LIST *, Item **);
table_map used_tables() const { return used_table_cache; } table_map used_tables() const { return used_table_cache; }
bool const_item() const { return !used_table_cache; } bool const_item() const { return !used_table_cache; }
...@@ -382,7 +382,7 @@ class Item_udf_sum : public Item_sum ...@@ -382,7 +382,7 @@ class Item_udf_sum : public Item_sum
{ quick_group=0;} { quick_group=0;}
~Item_udf_sum() {} ~Item_udf_sum() {}
const char *func_name() const { return udf.name(); } const char *func_name() const { return udf.name(); }
bool fix_fields(THD *thd,struct st_table_list *tables) bool fix_fields(THD *thd, TABLE_LIST *tables, Item **ref)
{ {
return udf.fix_fields(thd,tables,this,this->arg_count,this->args); return udf.fix_fields(thd,tables,this,this->arg_count,this->args);
} }
......
...@@ -42,5 +42,5 @@ class Item_sum_unique_users :public Item_sum_num ...@@ -42,5 +42,5 @@ class Item_sum_unique_users :public Item_sum_num
bool add() { return 0; } bool add() { return 0; }
void reset_field() {} void reset_field() {}
void update_field(int offset) {} void update_field(int offset) {}
bool fix_fields(THD *thd,struct st_table_list *tlist) { return 0;} bool fix_fields(THD *thd, TABLE_LIST *tlist, Item **ref) { return 0;}
}; };
...@@ -1874,7 +1874,7 @@ int setup_fields(THD *thd, TABLE_LIST *tables, List<Item> &fields, ...@@ -1874,7 +1874,7 @@ int setup_fields(THD *thd, TABLE_LIST *tables, List<Item> &fields,
} }
else else
{ {
if (item->fix_fields(thd,tables)) if (item->fix_fields(thd, tables, it.ref()))
DBUG_RETURN(-1); /* purecov: inspected */ DBUG_RETURN(-1); /* purecov: inspected */
if (item->with_sum_func && item->type() != Item::SUM_FUNC_ITEM && if (item->with_sum_func && item->type() != Item::SUM_FUNC_ITEM &&
sum_func_list) sum_func_list)
...@@ -2025,7 +2025,7 @@ int setup_conds(THD *thd,TABLE_LIST *tables,COND **conds) ...@@ -2025,7 +2025,7 @@ int setup_conds(THD *thd,TABLE_LIST *tables,COND **conds)
if (*conds) if (*conds)
{ {
thd->where="where clause"; thd->where="where clause";
if ((*conds)->fix_fields(thd,tables)) if ((*conds)->fix_fields(thd, tables, conds))
DBUG_RETURN(1); DBUG_RETURN(1);
} }
...@@ -2036,7 +2036,7 @@ int setup_conds(THD *thd,TABLE_LIST *tables,COND **conds) ...@@ -2036,7 +2036,7 @@ int setup_conds(THD *thd,TABLE_LIST *tables,COND **conds)
{ {
/* Make a join an a expression */ /* Make a join an a expression */
thd->where="on clause"; thd->where="on clause";
if (table->on_expr->fix_fields(thd,tables)) if (table->on_expr->fix_fields(thd, tables, &table->on_expr))
DBUG_RETURN(1); DBUG_RETURN(1);
thd->cond_count++; thd->cond_count++;
......
...@@ -81,7 +81,7 @@ static void free_var(user_var_entry *entry) ...@@ -81,7 +81,7 @@ static void free_var(user_var_entry *entry)
THD::THD():user_time(0),fatal_error(0),last_insert_id_used(0), THD::THD():user_time(0),fatal_error(0),last_insert_id_used(0),
insert_id_used(0), in_lock_tables(0), insert_id_used(0), in_lock_tables(0),
global_read_lock(0), bootstrap(0), having_fix_field(0) global_read_lock(0), bootstrap(0)
{ {
host=user=priv_user=db=query=ip=0; host=user=priv_user=db=query=ip=0;
host_or_ip="unknown ip"; host_or_ip="unknown ip";
......
...@@ -453,7 +453,6 @@ class THD :public ilink { ...@@ -453,7 +453,6 @@ class THD :public ilink {
bool query_error, bootstrap, cleanup_done; bool query_error, bootstrap, cleanup_done;
bool safe_to_cache_query; bool safe_to_cache_query;
bool volatile killed; bool volatile killed;
bool having_fix_field; //TRUE when having fix field called
bool prepare_command; bool prepare_command;
ulong param_count,current_param_number; ulong param_count,current_param_number;
Error<mysql_st_error> err_list; Error<mysql_st_error> err_list;
......
...@@ -106,7 +106,7 @@ int mysql_ha_read(THD *thd, TABLE_LIST *tables, ...@@ -106,7 +106,7 @@ int mysql_ha_read(THD *thd, TABLE_LIST *tables,
} }
tables->table=table; tables->table=table;
if (cond && cond->fix_fields(thd,tables)) if (cond && cond->fix_fields(thd, tables, &cond))
return -1; return -1;
if (keyname) if (keyname)
......
...@@ -942,8 +942,8 @@ void st_select_lex::init_select() ...@@ -942,8 +942,8 @@ void st_select_lex::init_select()
interval_list.empty(); interval_list.empty();
use_index.empty(); use_index.empty();
ftfunc_list.empty(); ftfunc_list.empty();
linkage=UNSPECIFIED_TYPE; linkage= UNSPECIFIED_TYPE;
depended= 0; depended= having_fix_field= 0;
} }
/* /*
......
...@@ -253,7 +253,10 @@ class st_select_lex: public st_select_lex_node { ...@@ -253,7 +253,10 @@ class st_select_lex: public st_select_lex_node {
uint in_sum_expr; uint in_sum_expr;
bool create_refs, bool create_refs,
braces, /* SELECT ... UNION (SELECT ... ) <- this braces */ braces, /* SELECT ... UNION (SELECT ... ) <- this braces */
depended; /* depended from outer select subselect */ depended, /* depended from outer select subselect */
/* TRUE when having fix field called in processing of this SELECT */
having_fix_field;
void init_query(); void init_query();
void init_select(); void init_select();
st_select_lex_unit* master_unit() { return (st_select_lex_unit*) master; } st_select_lex_unit* master_unit() { return (st_select_lex_unit*) master; }
......
...@@ -448,7 +448,7 @@ static bool mysql_test_upd_fields(THD *thd, TABLE_LIST *table_list, ...@@ -448,7 +448,7 @@ static bool mysql_test_upd_fields(THD *thd, TABLE_LIST *table_list,
static bool mysql_test_select_fields(THD *thd, TABLE_LIST *tables, static bool mysql_test_select_fields(THD *thd, TABLE_LIST *tables,
List<Item> &fields, List<Item> &values, List<Item> &fields, List<Item> &values,
COND *conds, ORDER *order, ORDER *group, COND *conds, ORDER *order, ORDER *group,
Item *having,thr_lock_type lock_type) Item *having, thr_lock_type lock_type)
{ {
TABLE *table; TABLE *table;
bool hidden_group_fields; bool hidden_group_fields;
...@@ -470,7 +470,7 @@ static bool mysql_test_select_fields(THD *thd, TABLE_LIST *tables, ...@@ -470,7 +470,7 @@ static bool mysql_test_select_fields(THD *thd, TABLE_LIST *tables,
{ {
thd->where="having clause"; thd->where="having clause";
thd->allow_sum_func=1; thd->allow_sum_func=1;
if (having->fix_fields(thd,tables) || thd->fatal_error) if (having->fix_fields(thd, tables, &having) || thd->fatal_error)
DBUG_RETURN(1); DBUG_RETURN(1);
if (having->with_sum_func) if (having->with_sum_func)
having->split_sum_func(all_fields); having->split_sum_func(all_fields);
......
...@@ -227,10 +227,9 @@ JOIN::prepare(TABLE_LIST *tables_init, ...@@ -227,10 +227,9 @@ JOIN::prepare(TABLE_LIST *tables_init,
{ {
thd->where="having clause"; thd->where="having clause";
thd->allow_sum_func=1; thd->allow_sum_func=1;
bool having_fix_field_store= thd->having_fix_field; select_lex->having_fix_field= 1;
thd->having_fix_field= 1; bool having_fix_rc= having->fix_fields(thd, tables_list, &having);
bool having_fix_rc= having->fix_fields(thd,tables_list); select_lex->having_fix_field= 0;
thd->having_fix_field= having_fix_field_store;
if (having_fix_rc || thd->fatal_error) if (having_fix_rc || thd->fatal_error)
DBUG_RETURN(-1); /* purecov: inspected */ DBUG_RETURN(-1); /* purecov: inspected */
if (having->with_sum_func) if (having->with_sum_func)
...@@ -349,7 +348,7 @@ JOIN::optimize() ...@@ -349,7 +348,7 @@ JOIN::optimize()
} }
else if ((conds=new Item_cond_and(conds,having))) else if ((conds=new Item_cond_and(conds,having)))
{ {
conds->fix_fields(thd, tables_list); conds->fix_fields(thd, tables_list, &conds);
conds->change_ref_to_fields(thd, tables_list); conds->change_ref_to_fields(thd, tables_list);
having= 0; having= 0;
} }
...@@ -612,6 +611,15 @@ JOIN::reinit() ...@@ -612,6 +611,15 @@ JOIN::reinit()
if (setup_tables(tables_list)) if (setup_tables(tables_list))
DBUG_RETURN(1); DBUG_RETURN(1);
// Reset of sum functions
first_record= 0;
if (sum_funcs)
{
Item_sum *func, **func_ptr= sum_funcs;
while ((func= *(func_ptr++)))
func->null_value= 1;
}
DBUG_RETURN(0); DBUG_RETURN(0);
} }
...@@ -3381,7 +3389,7 @@ remove_eq_conds(COND *cond,Item::cond_result *cond_value) ...@@ -3381,7 +3389,7 @@ remove_eq_conds(COND *cond,Item::cond_result *cond_value)
21)))) 21))))
{ {
cond=new_cond; cond=new_cond;
cond->fix_fields(thd,0); cond->fix_fields(thd, 0, &cond);
} }
thd->insert_id(0); // Clear for next request thd->insert_id(0); // Clear for next request
} }
...@@ -3395,7 +3403,7 @@ remove_eq_conds(COND *cond,Item::cond_result *cond_value) ...@@ -3395,7 +3403,7 @@ remove_eq_conds(COND *cond,Item::cond_result *cond_value)
if ((new_cond= new Item_func_eq(args[0],new Item_int("0", 0, 2)))) if ((new_cond= new Item_func_eq(args[0],new Item_int("0", 0, 2))))
{ {
cond=new_cond; cond=new_cond;
cond->fix_fields(thd,0); cond->fix_fields(thd, 0, &cond);
} }
} }
} }
...@@ -6429,7 +6437,7 @@ find_order_in_list(THD *thd,TABLE_LIST *tables,ORDER *order,List<Item> &fields, ...@@ -6429,7 +6437,7 @@ find_order_in_list(THD *thd,TABLE_LIST *tables,ORDER *order,List<Item> &fields,
return 0; return 0;
} }
order->in_field_list=0; order->in_field_list=0;
if ((*order->item)->fix_fields(thd,tables) || thd->fatal_error) if ((*order->item)->fix_fields(thd, tables, order->item) || thd->fatal_error)
return 1; // Wrong field return 1; // Wrong field
all_fields.push_front(*order->item); // Add new field to field list all_fields.push_front(*order->item); // Add new field to field list
order->item=(Item**) all_fields.head_ref(); order->item=(Item**) all_fields.head_ref();
...@@ -6527,7 +6535,7 @@ setup_new_fields(THD *thd,TABLE_LIST *tables,List<Item> &fields, ...@@ -6527,7 +6535,7 @@ setup_new_fields(THD *thd,TABLE_LIST *tables,List<Item> &fields,
else else
{ {
thd->where="procedure list"; thd->where="procedure list";
if ((*new_field->item)->fix_fields(thd,tables)) if ((*new_field->item)->fix_fields(thd, tables, new_field->item))
DBUG_RETURN(1); /* purecov: inspected */ DBUG_RETURN(1); /* purecov: inspected */
thd->where=0; thd->where=0;
all_fields.push_front(*new_field->item); all_fields.push_front(*new_field->item);
...@@ -7092,7 +7100,7 @@ static bool add_ref_to_table_cond(THD *thd, JOIN_TAB *join_tab) ...@@ -7092,7 +7100,7 @@ static bool add_ref_to_table_cond(THD *thd, JOIN_TAB *join_tab)
Here we pass 0 as the first argument to fix_fields that don't need Here we pass 0 as the first argument to fix_fields that don't need
to do any stack checking (This is already done in the initial fix_fields). to do any stack checking (This is already done in the initial fix_fields).
*/ */
cond->fix_fields((THD *) 0,(TABLE_LIST *) 0); cond->fix_fields((THD *) 0,(TABLE_LIST *) 0, (Item**)&cond);
if (join_tab->select) if (join_tab->select)
{ {
error=(int) cond->add(join_tab->select->cond); error=(int) cond->add(join_tab->select->cond);
......
...@@ -2973,7 +2973,7 @@ kill: ...@@ -2973,7 +2973,7 @@ kill:
KILL_SYM expr KILL_SYM expr
{ {
LEX *lex=Lex; LEX *lex=Lex;
if ($2->fix_fields(lex->thd,0)) if ($2->fix_fields(lex->thd, 0, &$2))
{ {
send_error(&lex->thd->net, ER_SET_CONSTANTS_ONLY); send_error(&lex->thd->net, ER_SET_CONSTANTS_ONLY);
YYABORT; YYABORT;
...@@ -3469,7 +3469,8 @@ option_value: ...@@ -3469,7 +3469,8 @@ option_value:
| '@' ident_or_text equal expr | '@' ident_or_text equal expr
{ {
Item_func_set_user_var *item = new Item_func_set_user_var($2,$4); Item_func_set_user_var *item = new Item_func_set_user_var($2,$4);
if (item->fix_fields(current_thd,0) || item->update()) if (item->fix_fields(current_thd, 0, (Item**) &item) ||
item->update())
{ {
send_error(&current_thd->net, ER_SET_CONSTANTS_ONLY); send_error(&current_thd->net, ER_SET_CONSTANTS_ONLY);
YYABORT; YYABORT;
...@@ -3501,7 +3502,7 @@ option_value: ...@@ -3501,7 +3502,7 @@ option_value:
{ {
THD *thd=current_thd; THD *thd=current_thd;
Item *item= $3; Item *item= $3;
if (item->fix_fields(current_thd,0)) if (item->fix_fields(current_thd, 0, &item))
{ {
send_error(&thd->net, ER_SET_CONSTANTS_ONLY); send_error(&thd->net, ER_SET_CONSTANTS_ONLY);
YYABORT; YYABORT;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment