Commit d095d475 authored by bell@sanja.is.com.ua's avatar bell@sanja.is.com.ua

after review changes

parent ede07fcd
...@@ -301,15 +301,12 @@ bool DTCollation::aggregate(DTCollation &dt) ...@@ -301,15 +301,12 @@ bool DTCollation::aggregate(DTCollation &dt)
return 0; return 0;
} }
Item_field::Item_field(Field *f, bool already_fixed) Item_field::Item_field(Field *f)
:Item_ident(NullS, f->table_name, f->field_name) :Item_ident(NullS, f->table_name, f->field_name)
#ifndef DBUG_OFF
,double_fix(0)
#endif
{ {
set_field(f); set_field(f);
collation.set(DERIVATION_IMPLICIT); collation.set(DERIVATION_IMPLICIT);
fixed= already_fixed; fixed= 1;
} }
// Constructor need to process subselect with temporary tables (see Item) // Constructor need to process subselect with temporary tables (see Item)
...@@ -317,9 +314,6 @@ Item_field::Item_field(THD *thd, Item_field *item) ...@@ -317,9 +314,6 @@ Item_field::Item_field(THD *thd, Item_field *item)
:Item_ident(thd, item), :Item_ident(thd, item),
field(item->field), field(item->field),
result_field(item->result_field) result_field(item->result_field)
#ifndef DBUG_OFF
,double_fix(0)
#endif
{ {
collation.set(DERIVATION_IMPLICIT); collation.set(DERIVATION_IMPLICIT);
} }
...@@ -487,6 +481,7 @@ Item *Item_field::get_tmp_table_item(THD *thd) ...@@ -487,6 +481,7 @@ Item *Item_field::get_tmp_table_item(THD *thd)
String *Item_int::val_str(String *str) String *Item_int::val_str(String *str)
{ {
// following assert is redundant, because fixed=1 assigned in constructor
DBUG_ASSERT(fixed == 1); DBUG_ASSERT(fixed == 1);
str->set(value, &my_charset_bin); str->set(value, &my_charset_bin);
return str; return str;
...@@ -502,6 +497,7 @@ void Item_int::print(String *str) ...@@ -502,6 +497,7 @@ void Item_int::print(String *str)
String *Item_uint::val_str(String *str) String *Item_uint::val_str(String *str)
{ {
// following assert is redundant, because fixed=1 assigned in constructor
DBUG_ASSERT(fixed == 1); DBUG_ASSERT(fixed == 1);
str->set((ulonglong) value, &my_charset_bin); str->set((ulonglong) value, &my_charset_bin);
return str; return str;
...@@ -518,6 +514,7 @@ void Item_uint::print(String *str) ...@@ -518,6 +514,7 @@ void Item_uint::print(String *str)
String *Item_real::val_str(String *str) String *Item_real::val_str(String *str)
{ {
// following assert is redundant, because fixed=1 assigned in constructor
DBUG_ASSERT(fixed == 1); DBUG_ASSERT(fixed == 1);
str->set(value,decimals,&my_charset_bin); str->set(value,decimals,&my_charset_bin);
return str; return str;
...@@ -537,20 +534,23 @@ bool Item_null::eq(const Item *item, bool binary_cmp) const ...@@ -537,20 +534,23 @@ bool Item_null::eq(const Item *item, bool binary_cmp) const
{ return item->type() == type(); } { return item->type() == type(); }
double Item_null::val() double Item_null::val()
{ {
// NULL can be used without fix_fields // following assert is redundant, because fixed=1 assigned in constructor
DBUG_ASSERT(fixed == 1);
null_value=1; null_value=1;
return 0.0; return 0.0;
} }
longlong Item_null::val_int() longlong Item_null::val_int()
{ {
// NULL can be used without fix_fields // following assert is redundant, because fixed=1 assigned in constructor
DBUG_ASSERT(fixed == 1);
null_value=1; null_value=1;
return 0; return 0;
} }
/* ARGSUSED */ /* ARGSUSED */
String *Item_null::val_str(String *str) String *Item_null::val_str(String *str)
{ {
// NULL can be used without fix_fields // following assert is redundant, because fixed=1 assigned in constructor
DBUG_ASSERT(fixed == 1);
null_value=1; null_value=1;
return 0; return 0;
} }
...@@ -832,8 +832,7 @@ bool Item::fix_fields(THD *thd, ...@@ -832,8 +832,7 @@ bool Item::fix_fields(THD *thd,
{ {
// We do not check fields which are fixed during construction // We do not check fields which are fixed during construction
DBUG_ASSERT(fixed == 0 || type() == INT_ITEM || type() == CACHE_ITEM || DBUG_ASSERT(fixed == 0 || basic_const_item());
type() == STRING_ITEM || type() == MYSQL_TYPE_DATETIME);
fixed= 1; fixed= 1;
return 0; return 0;
} }
...@@ -904,7 +903,7 @@ static void mark_as_dependent(THD *thd, SELECT_LEX *last, SELECT_LEX *current, ...@@ -904,7 +903,7 @@ static void mark_as_dependent(THD *thd, SELECT_LEX *last, SELECT_LEX *current,
bool Item_field::fix_fields(THD *thd, TABLE_LIST *tables, Item **ref) bool Item_field::fix_fields(THD *thd, TABLE_LIST *tables, Item **ref)
{ {
DBUG_ASSERT(fixed == 0 || double_fix == 0); DBUG_ASSERT(fixed == 0);
if (!field) // If field is not checked if (!field) // If field is not checked
{ {
TABLE_LIST *where= 0; TABLE_LIST *where= 0;
...@@ -1341,6 +1340,10 @@ int Item_int::save_in_field(Field *field, bool no_conversions) ...@@ -1341,6 +1340,10 @@ int Item_int::save_in_field(Field *field, bool no_conversions)
return field->store(nr); return field->store(nr);
} }
Item_num *Item_uint::neg()
{
return new Item_real(name, - ((double) value), 0, max_length);
}
int Item_real::save_in_field(Field *field, bool no_conversions) int Item_real::save_in_field(Field *field, bool no_conversions)
{ {
...@@ -1383,10 +1386,12 @@ Item_varbinary::Item_varbinary(const char *str, uint str_length) ...@@ -1383,10 +1386,12 @@ Item_varbinary::Item_varbinary(const char *str, uint str_length)
} }
*ptr=0; // Keep purify happy *ptr=0; // Keep purify happy
collation.set(&my_charset_bin, DERIVATION_COERCIBLE); collation.set(&my_charset_bin, DERIVATION_COERCIBLE);
fixed= 1;
} }
longlong Item_varbinary::val_int() longlong Item_varbinary::val_int()
{ {
// following assert is redundant, because fixed=1 assigned in constructor
DBUG_ASSERT(fixed == 1); DBUG_ASSERT(fixed == 1);
char *end=(char*) str_value.ptr()+str_value.length(), char *end=(char*) str_value.ptr()+str_value.length(),
*ptr=end-min(str_value.length(),sizeof(longlong)); *ptr=end-min(str_value.length(),sizeof(longlong));
...@@ -1648,7 +1653,7 @@ bool Item_ref::fix_fields(THD *thd,TABLE_LIST *tables, Item **reference) ...@@ -1648,7 +1653,7 @@ bool Item_ref::fix_fields(THD *thd,TABLE_LIST *tables, Item **reference)
{ {
ref= 0; // To prevent "delete *ref;" on ~Item_erf() of this item ref= 0; // To prevent "delete *ref;" on ~Item_erf() of this item
Item_field* fld; Item_field* fld;
if (!((*reference)= fld= new Item_field(tmp, 1))) if (!((*reference)= fld= new Item_field(tmp)))
return 1; return 1;
register_item_tree_changing(reference); register_item_tree_changing(reference);
mark_as_dependent(thd, last, thd->lex->current_select, fld); mark_as_dependent(thd, last, thd->lex->current_select, fld);
......
...@@ -137,6 +137,11 @@ public: ...@@ -137,6 +137,11 @@ public:
} }
virtual void make_field(Send_field *field); virtual void make_field(Send_field *field);
virtual bool fix_fields(THD *, struct st_table_list *, Item **); virtual bool fix_fields(THD *, struct st_table_list *, Item **);
/*
should be used in case where we are shure that we do not need
complete fix_fields() procedure.
*/
inline void quick_fix_field() { fixed= 1; }
virtual int save_in_field(Field *field, bool no_conversions); virtual int save_in_field(Field *field, bool no_conversions);
virtual void save_org_in_field(Field *field) virtual void save_org_in_field(Field *field)
{ (void) save_in_field(field, 1); } { (void) save_in_field(field, 1); }
...@@ -245,7 +250,7 @@ public: ...@@ -245,7 +250,7 @@ public:
class Item_num: public Item class Item_num: public Item
{ {
public: public:
virtual void neg()= 0; virtual Item_num* neg()= 0;
}; };
...@@ -288,7 +293,7 @@ public: ...@@ -288,7 +293,7 @@ public:
{ collation.set(DERIVATION_IMPLICIT); } { collation.set(DERIVATION_IMPLICIT); }
// Constructor need to process subselect with temporary tables (see Item) // Constructor need to process subselect with temporary tables (see Item)
Item_field(THD *thd, Item_field *item); Item_field(THD *thd, Item_field *item);
Item_field(Field *field, bool already_fixed); Item_field(Field *field);
enum Type type() const { return FIELD_ITEM; } enum Type type() const { return FIELD_ITEM; }
bool eq(const Item *item, bool binary_cmp) const; bool eq(const Item *item, bool binary_cmp) const;
double val(); double val();
...@@ -321,13 +326,19 @@ public: ...@@ -321,13 +326,19 @@ public:
void cleanup(); void cleanup();
friend class Item_default_value; friend class Item_default_value;
friend class Item_insert_value; friend class Item_insert_value;
friend class st_select_lex_unit;
}; };
class Item_null :public Item class Item_null :public Item
{ {
public: public:
Item_null(char *name_par=0) Item_null(char *name_par=0)
{ maybe_null=null_value=TRUE; name= name_par ? name_par : (char*) "NULL";} {
maybe_null= null_value= TRUE;
max_length= 0;
name= name_par ? name_par : (char*) "NULL";
fixed= 1;
}
enum Type type() const { return NULL_ITEM; } enum Type type() const { return NULL_ITEM; }
bool eq(const Item *item, bool binary_cmp) const; bool eq(const Item *item, bool binary_cmp) const;
double val(); double val();
...@@ -338,13 +349,8 @@ public: ...@@ -338,13 +349,8 @@ public:
bool send(Protocol *protocol, String *str); bool send(Protocol *protocol, String *str);
enum Item_result result_type () const { return STRING_RESULT; } enum Item_result result_type () const { return STRING_RESULT; }
enum_field_types field_type() const { return MYSQL_TYPE_NULL; } enum_field_types field_type() const { return MYSQL_TYPE_NULL; }
bool fix_fields(THD *thd, struct st_table_list *list, Item **item) // to prevent drop fixed flag (no need parent cleanup call)
{ void cleanup() {}
DBUG_ASSERT(fixed == 0);
bool res= Item::fix_fields(thd, list, item);
max_length=0;
return res;
}
bool basic_const_item() const { return 1; } bool basic_const_item() const { return 1; }
Item *new_item() { return new Item_null(name); } Item *new_item() { return new Item_null(name); }
bool is_null() { return 1; } bool is_null() { return 1; }
...@@ -431,9 +437,9 @@ public: ...@@ -431,9 +437,9 @@ public:
bool basic_const_item() const { return 1; } bool basic_const_item() const { return 1; }
Item *new_item() { return new Item_int(name,value,max_length); } Item *new_item() { return new Item_int(name,value,max_length); }
// to prevent drop fixed flag (no need parent cleanup call) // to prevent drop fixed flag (no need parent cleanup call)
void cleanup() { fixed= 1; } void cleanup() {}
void print(String *str); void print(String *str);
void neg() { value= -value; } Item_num *neg() { value= -value; return this; }
}; };
...@@ -451,6 +457,7 @@ public: ...@@ -451,6 +457,7 @@ public:
Item *new_item() { return new Item_uint(name,max_length); } Item *new_item() { return new Item_uint(name,max_length); }
int save_in_field(Field *field, bool no_conversions); int save_in_field(Field *field, bool no_conversions);
void print(String *str); void print(String *str);
Item_num *neg ();
}; };
...@@ -459,11 +466,12 @@ class Item_real :public Item_num ...@@ -459,11 +466,12 @@ class Item_real :public Item_num
public: public:
double value; double value;
// Item_real() :value(0) {} // Item_real() :value(0) {}
Item_real(const char *str_arg,uint length) :value(my_atof(str_arg)) Item_real(const char *str_arg, uint length) :value(my_atof(str_arg))
{ {
name=(char*) str_arg; name=(char*) str_arg;
decimals=(uint8) nr_of_decimals(str_arg); decimals=(uint8) nr_of_decimals(str_arg);
max_length=length; max_length=length;
fixed= 1;
} }
Item_real(const char *str,double val_arg,uint decimal_par,uint length) Item_real(const char *str,double val_arg,uint decimal_par,uint length)
:value(val_arg) :value(val_arg)
...@@ -471,8 +479,9 @@ public: ...@@ -471,8 +479,9 @@ public:
name=(char*) str; name=(char*) str;
decimals=(uint8) decimal_par; decimals=(uint8) decimal_par;
max_length=length; max_length=length;
fixed= 1;
} }
Item_real(double value_par) :value(value_par) {} Item_real(double value_par) :value(value_par) { fixed= 1; }
int save_in_field(Field *field, bool no_conversions); int save_in_field(Field *field, bool no_conversions);
enum Type type() const { return REAL_ITEM; } enum Type type() const { return REAL_ITEM; }
enum_field_types field_type() const { return MYSQL_TYPE_DOUBLE; } enum_field_types field_type() const { return MYSQL_TYPE_DOUBLE; }
...@@ -484,8 +493,10 @@ public: ...@@ -484,8 +493,10 @@ public:
} }
String *val_str(String*); String *val_str(String*);
bool basic_const_item() const { return 1; } bool basic_const_item() const { return 1; }
// to prevent drop fixed flag (no need parent cleanup call)
void cleanup() {}
Item *new_item() { return new Item_real(name,value,decimals,max_length); } Item *new_item() { return new Item_real(name,value,decimals,max_length); }
void neg() { value= -value; } Item_num *neg() { value= -value; return this; }
}; };
...@@ -564,11 +575,8 @@ public: ...@@ -564,11 +575,8 @@ public:
String *const_string() { return &str_value; } String *const_string() { return &str_value; }
inline void append(char *str, uint length) { str_value.append(str, length); } inline void append(char *str, uint length) { str_value.append(str, length); }
void print(String *str); void print(String *str);
void cleanup() // to prevent drop fixed flag (no need parent cleanup call)
{ void cleanup() {}
// it is constant => can be used without fix_fields (and frequently used)
fixed= 1;
}
}; };
/* for show tables */ /* for show tables */
...@@ -613,10 +621,13 @@ public: ...@@ -613,10 +621,13 @@ public:
double val() double val()
{ DBUG_ASSERT(fixed == 1); return (double) Item_varbinary::val_int(); } { DBUG_ASSERT(fixed == 1); return (double) Item_varbinary::val_int(); }
longlong val_int(); longlong val_int();
bool basic_const_item() const { return 1; }
String *val_str(String*) { DBUG_ASSERT(fixed == 1); return &str_value; } String *val_str(String*) { DBUG_ASSERT(fixed == 1); return &str_value; }
int save_in_field(Field *field, bool no_conversions); int save_in_field(Field *field, bool no_conversions);
enum Item_result result_type () const { return STRING_RESULT; } enum Item_result result_type () const { return STRING_RESULT; }
enum_field_types field_type() const { return MYSQL_TYPE_STRING; } enum_field_types field_type() const { return MYSQL_TYPE_STRING; }
// to prevent drop fixed flag (no need parent cleanup call)
void cleanup() {}
}; };
...@@ -874,7 +885,6 @@ public: ...@@ -874,7 +885,6 @@ public:
bool eq(const Item *item, bool binary_cmp) const; bool eq(const Item *item, bool binary_cmp) const;
bool fix_fields(THD *, struct st_table_list *, Item **); bool fix_fields(THD *, struct st_table_list *, Item **);
void print(String *str); void print(String *str);
virtual bool basic_const_item() const { return true; }
int save_in_field(Field *field_arg, bool no_conversions) int save_in_field(Field *field_arg, bool no_conversions)
{ {
if (!arg) if (!arg)
...@@ -902,7 +912,6 @@ public: ...@@ -902,7 +912,6 @@ public:
bool eq(const Item *item, bool binary_cmp) const; bool eq(const Item *item, bool binary_cmp) const;
bool fix_fields(THD *, struct st_table_list *, Item **); bool fix_fields(THD *, struct st_table_list *, Item **);
void print(String *str); void print(String *str);
virtual bool basic_const_item() const { return true; }
int save_in_field(Field *field_arg, bool no_conversions) int save_in_field(Field *field_arg, bool no_conversions)
{ {
return Item_field::save_in_field(field_arg, no_conversions); return Item_field::save_in_field(field_arg, no_conversions);
...@@ -926,7 +935,7 @@ public: ...@@ -926,7 +935,7 @@ public:
void set_used_tables(table_map map) { used_table_map= map; } void set_used_tables(table_map map) { used_table_map= map; }
virtual bool allocate(uint i) { return 0; }; virtual bool allocate(uint i) { return 0; }
virtual bool setup(Item *item) virtual bool setup(Item *item)
{ {
example= item; example= item;
...@@ -941,7 +950,7 @@ public: ...@@ -941,7 +950,7 @@ public:
table_map used_tables() const { return used_table_map; } table_map used_tables() const { return used_table_map; }
virtual void keep_array() {} virtual void keep_array() {}
// to prevent drop fixed flag (no need parent cleanup call) // to prevent drop fixed flag (no need parent cleanup call)
void cleanup() { fixed= 1; } void cleanup() {}
void print(String *str); void print(String *str);
}; };
......
...@@ -991,13 +991,13 @@ public: ...@@ -991,13 +991,13 @@ public:
/* Some usefull inline functions */ /* Some usefull inline functions */
inline Item *and_conds(Item *a,Item *b) inline Item *and_conds(Item *a, Item *b, TABLE_LIST *tables)
{ {
if (!b) return a; if (!b) return a;
if (!a) return b; if (!a) return b;
Item *cond= new Item_cond_and(a,b); Item *cond= new Item_cond_and(a,b);
if (cond) if (cond)
cond->fix_fields(current_thd, 0, &cond); cond->fix_fields(current_thd, tables, &cond);
return cond; return cond;
} }
......
...@@ -428,7 +428,7 @@ void Item_func::fix_num_length_and_dec() ...@@ -428,7 +428,7 @@ void Item_func::fix_num_length_and_dec()
Item *Item_func::get_tmp_table_item(THD *thd) Item *Item_func::get_tmp_table_item(THD *thd)
{ {
if (!with_sum_func && !const_item()) if (!with_sum_func && !const_item())
return new Item_field(result_field, 1); return new Item_field(result_field);
return copy_or_same(thd); return copy_or_same(thd);
} }
...@@ -2780,7 +2780,13 @@ void Item_func_match::init_search(bool no_order) ...@@ -2780,7 +2780,13 @@ void Item_func_match::init_search(bool no_order)
fields.push_back(args[i]); fields.push_back(args[i]);
concat=new Item_func_concat_ws(new Item_string(" ",1, concat=new Item_func_concat_ws(new Item_string(" ",1,
cmp_collation.collation), fields); cmp_collation.collation), fields);
concat->fix_fields(current_thd, 0, &concat); /*
Above function used only to get value and do not need fix_fields for it:
Item_string - basic constant
fields - fix_fieds already was called for this arguments
Item_func_concat_ws - do not need fix_fields to produce value
*/
concat->quick_fix_field();
} }
if (master) if (master)
......
...@@ -74,9 +74,10 @@ longlong Item_str_func::val_int() ...@@ -74,9 +74,10 @@ longlong Item_str_func::val_int()
int err; int err;
String *res; String *res;
res=val_str(&str_value); res=val_str(&str_value);
return res ? return (res ?
my_strntoll(res->charset(), res->ptr(), res->length(), 10, NULL, &err) : my_strntoll(res->charset(), res->ptr(), res->length(), 10, NULL,
(longlong) 0; &err) :
(longlong) 0);
} }
......
...@@ -116,6 +116,8 @@ bool Item_subselect::fix_fields(THD *thd_param, TABLE_LIST *tables, Item **ref) ...@@ -116,6 +116,8 @@ bool Item_subselect::fix_fields(THD *thd_param, TABLE_LIST *tables, Item **ref)
{ {
if (substitution) if (substitution)
{ {
int ret= 0;
// did we changed top item of WHERE condition // did we changed top item of WHERE condition
if (unit->outer_select()->where == (*ref)) if (unit->outer_select()->where == (*ref))
unit->outer_select()->where= substitution; // correct WHERE for PS unit->outer_select()->where= substitution; // correct WHERE for PS
...@@ -127,7 +129,6 @@ bool Item_subselect::fix_fields(THD *thd_param, TABLE_LIST *tables, Item **ref) ...@@ -127,7 +129,6 @@ bool Item_subselect::fix_fields(THD *thd_param, TABLE_LIST *tables, Item **ref)
substitution= 0; substitution= 0;
fixed= 1; fixed= 1;
thd->where= "checking transformed subquery"; thd->where= "checking transformed subquery";
int ret= 0;
if (!(*ref)->fixed) if (!(*ref)->fixed)
ret= (*ref)->fix_fields(thd, tables, ref); ret= (*ref)->fix_fields(thd, tables, ref);
// We can't substitute aggregate functions (like (SELECT (max(i))) // We can't substitute aggregate functions (like (SELECT (max(i)))
...@@ -204,7 +205,7 @@ bool Item_subselect::const_item() const ...@@ -204,7 +205,7 @@ bool Item_subselect::const_item() const
Item *Item_subselect::get_tmp_table_item(THD *thd) Item *Item_subselect::get_tmp_table_item(THD *thd)
{ {
if (!with_sum_func && !const_item()) if (!with_sum_func && !const_item())
return new Item_field(result_field, 1); return new Item_field(result_field);
return copy_or_same(thd); return copy_or_same(thd);
} }
......
...@@ -113,7 +113,7 @@ Item *Item_sum::get_tmp_table_item(THD *thd) ...@@ -113,7 +113,7 @@ Item *Item_sum::get_tmp_table_item(THD *thd)
if (arg->type() == Item::FIELD_ITEM) if (arg->type() == Item::FIELD_ITEM)
((Item_field*) arg)->field= result_field_tmp++; ((Item_field*) arg)->field= result_field_tmp++;
else else
sum_item->args[i]= new Item_field(result_field_tmp++, 1); sum_item->args[i]= new Item_field(result_field_tmp++);
} }
} }
} }
......
...@@ -88,7 +88,7 @@ public: ...@@ -88,7 +88,7 @@ public:
virtual void fix_length_and_dec() { maybe_null=1; null_value=1; } virtual void fix_length_and_dec() { maybe_null=1; null_value=1; }
virtual const char *func_name() const { return "?"; } virtual const char *func_name() const { return "?"; }
virtual Item *result_item(Field *field) virtual Item *result_item(Field *field)
{ return new Item_field(field, 1);} { return new Item_field(field);}
table_map used_tables() const { return ~(table_map) 0; } /* Not used */ table_map used_tables() const { return ~(table_map) 0; } /* Not used */
bool const_item() const { return 0; } bool const_item() const { return 0; }
bool is_null() { return null_value; } bool is_null() { return null_value; }
......
...@@ -2293,7 +2293,7 @@ insert_fields(THD *thd,TABLE_LIST *tables, const char *db_name, ...@@ -2293,7 +2293,7 @@ insert_fields(THD *thd,TABLE_LIST *tables, const char *db_name,
thd->used_tables|=table->map; thd->used_tables|=table->map;
while ((field = *ptr++)) while ((field = *ptr++))
{ {
Item_field *item= new Item_field(field, 0); Item_field *item= new Item_field(field);
if (!found++) if (!found++)
(void) it->replace(item); // Replace '*' (void) it->replace(item); // Replace '*'
else else
...@@ -2365,7 +2365,7 @@ int setup_conds(THD *thd,TABLE_LIST *tables,COND **conds) ...@@ -2365,7 +2365,7 @@ int setup_conds(THD *thd,TABLE_LIST *tables,COND **conds)
!(specialflag & SPECIAL_NO_NEW_FUNC))) !(specialflag & SPECIAL_NO_NEW_FUNC)))
{ {
table->outer_join= 0; table->outer_join= 0;
if (!(*conds=and_conds(*conds, table->on_expr))) if (!(*conds= and_conds(*conds, table->on_expr, tables)))
DBUG_RETURN(1); DBUG_RETURN(1);
table->on_expr=0; table->on_expr=0;
} }
...@@ -2373,9 +2373,9 @@ int setup_conds(THD *thd,TABLE_LIST *tables,COND **conds) ...@@ -2373,9 +2373,9 @@ int setup_conds(THD *thd,TABLE_LIST *tables,COND **conds)
if (table->natural_join) if (table->natural_join)
{ {
/* Make a join of all fields with have the same name */ /* Make a join of all fields with have the same name */
TABLE *t1=table->table; TABLE *t1= table->table;
TABLE *t2=table->natural_join->table; TABLE *t2= table->natural_join->table;
Item_cond_and *cond_and=new Item_cond_and(); Item_cond_and *cond_and= new Item_cond_and();
if (!cond_and) // If not out of memory if (!cond_and) // If not out of memory
DBUG_RETURN(1); DBUG_RETURN(1);
cond_and->top_level_item(); cond_and->top_level_item();
...@@ -2390,10 +2390,8 @@ int setup_conds(THD *thd,TABLE_LIST *tables,COND **conds) ...@@ -2390,10 +2390,8 @@ int setup_conds(THD *thd,TABLE_LIST *tables,COND **conds)
t1->field[i]->field_name, t1->field[i]->field_name,
t2->field[j]->field_name)) t2->field[j]->field_name))
{ {
// fix_fields() call will be made for tmp by cond_and->fix_fields Item_func_eq *tmp= new Item_func_eq(new Item_field(t1->field[i]),
Item_func_eq *tmp=new Item_func_eq(new Item_field(t1->field[i], 1), new Item_field(t2->field[j]));
new Item_field(t2->field[j],
1));
if (!tmp) if (!tmp)
DBUG_RETURN(1); DBUG_RETURN(1);
/* Mark field used for table cache */ /* Mark field used for table cache */
...@@ -2405,18 +2403,22 @@ int setup_conds(THD *thd,TABLE_LIST *tables,COND **conds) ...@@ -2405,18 +2403,22 @@ int setup_conds(THD *thd,TABLE_LIST *tables,COND **conds)
} }
} }
} }
//cond_and->used_tables_cache= t1->map | t2->map;
thd->lex->current_select->cond_count+= cond_and->list.elements; thd->lex->current_select->cond_count+= cond_and->list.elements;
if (cond_and->fix_fields(thd, tables, (Item**)&cond_and) ||
cond_and->check_cols(1))
DBUG_RETURN(1);
if (!table->outer_join) // Not left join if (!table->outer_join) // Not left join
{ {
if (!(*conds=and_conds(*conds, cond_and))) if (!(*conds= and_conds(*conds, cond_and, tables)) ||
(*conds && !(*conds)->fixed &&
(*conds)->fix_fields(thd, tables, conds)))
DBUG_RETURN(1); DBUG_RETURN(1);
} }
else else
table->on_expr=and_conds(table->on_expr,cond_and); {
table->on_expr= and_conds(table->on_expr, cond_and, tables);
if (table->on_expr && !table->on_expr->fixed &&
table->on_expr->fix_fields(thd, tables, &table->on_expr))
DBUG_RETURN(1);
}
} }
} }
DBUG_RETURN(test(thd->net.report_error)); DBUG_RETURN(test(thd->net.report_error));
......
...@@ -624,7 +624,7 @@ SQL_SELECT *prepare_select_for_name(THD *thd, const char *mask, uint mlen, ...@@ -624,7 +624,7 @@ SQL_SELECT *prepare_select_for_name(THD *thd, const char *mask, uint mlen,
TABLE_LIST *tables, TABLE *table, TABLE_LIST *tables, TABLE *table,
Field *pfname, int *error) Field *pfname, int *error)
{ {
Item *cond= new Item_func_like(new Item_field(pfname, 1), Item *cond= new Item_func_like(new Item_field(pfname),
new Item_string(mask,mlen,pfname->charset()), new Item_string(mask,mlen,pfname->charset()),
(char*) "\\"); (char*) "\\");
if (thd->is_fatal_error) if (thd->is_fatal_error)
...@@ -744,10 +744,10 @@ int mysqld_help(THD *thd, const char *mask) ...@@ -744,10 +744,10 @@ int mysqld_help(THD *thd, const char *mask)
{ {
Field *topic_cat_id= used_fields[help_topic_help_category_id].field; Field *topic_cat_id= used_fields[help_topic_help_category_id].field;
Item *cond_topic_by_cat= Item *cond_topic_by_cat=
new Item_func_equal(new Item_field(topic_cat_id, 1), new Item_func_equal(new Item_field(topic_cat_id),
new Item_int((int32)category_id)); new Item_int((int32)category_id));
Item *cond_cat_by_cat= Item *cond_cat_by_cat=
new Item_func_equal(new Item_field(cat_cat_id, 1), new Item_func_equal(new Item_field(cat_cat_id),
new Item_int((int32)category_id)); new Item_int((int32)category_id));
if (!(select_topics_by_cat= prepare_simple_select(thd,cond_topic_by_cat, if (!(select_topics_by_cat= prepare_simple_select(thd,cond_topic_by_cat,
tables,tables[0].table, tables,tables[0].table,
......
...@@ -122,7 +122,7 @@ int mysql_load(THD *thd,sql_exchange *ex,TABLE_LIST *table_list, ...@@ -122,7 +122,7 @@ int mysql_load(THD *thd,sql_exchange *ex,TABLE_LIST *table_list,
{ {
Field **field; Field **field;
for (field=table->field; *field ; field++) for (field=table->field; *field ; field++)
fields.push_back(new Item_field(*field, 1)); fields.push_back(new Item_field(*field));
} }
else else
{ // Part field list { // Part field list
......
...@@ -4031,11 +4031,10 @@ bool add_field_to_list(THD *thd, char *field_name, enum_field_types type, ...@@ -4031,11 +4031,10 @@ bool add_field_to_list(THD *thd, char *field_name, enum_field_types type,
if (default_value) if (default_value)
{ {
if (default_value->fix_fields(thd, 0, &default_value))
{
DBUG_RETURN(1);
}
/* /*
Default value should be literal => basic constants =>
no need fix_fields()
We allow specifying value for first TIMESTAMP column We allow specifying value for first TIMESTAMP column
altough it is silently ignored. This should be fixed in 4.1 altough it is silently ignored. This should be fixed in 4.1
(by proper warning or real support for default values) (by proper warning or real support for default values)
......
...@@ -321,9 +321,9 @@ JOIN::prepare(Item ***rref_pointer_array, ...@@ -321,9 +321,9 @@ JOIN::prepare(Item ***rref_pointer_array,
thd->where="having clause"; thd->where="having clause";
thd->allow_sum_func=1; thd->allow_sum_func=1;
select_lex->having_fix_field= 1; select_lex->having_fix_field= 1;
bool having_fix_rc= !having->fixed && bool having_fix_rc= (!having->fixed &&
(having->fix_fields(thd, tables_list, &having) || (having->fix_fields(thd, tables_list, &having) ||
having->check_cols(1)); having->check_cols(1)));
select_lex->having_fix_field= 0; select_lex->having_fix_field= 0;
if (having_fix_rc || thd->net.report_error) if (having_fix_rc || thd->net.report_error)
DBUG_RETURN(-1); /* purecov: inspected */ DBUG_RETURN(-1); /* purecov: inspected */
...@@ -525,7 +525,7 @@ JOIN::optimize() ...@@ -525,7 +525,7 @@ JOIN::optimize()
} }
#endif #endif
conds= optimize_cond(thd, conds,&cond_value); conds= optimize_cond(thd, conds, &cond_value);
if (thd->net.report_error) if (thd->net.report_error)
{ {
error= 1; error= 1;
...@@ -1431,10 +1431,13 @@ JOIN::exec() ...@@ -1431,10 +1431,13 @@ JOIN::exec()
{ {
if (!(curr_table->select->cond= if (!(curr_table->select->cond=
new Item_cond_and(curr_table->select->cond, new Item_cond_and(curr_table->select->cond,
sort_table_cond)) || sort_table_cond)))
curr_table->select->cond->fix_fields(thd, tables_list,
&curr_table->select->cond))
DBUG_VOID_RETURN; DBUG_VOID_RETURN;
/*
Item_cond_and do not need fix_fields for execution, its parameters
are fixed or do not need fix_fields, too
*/
curr_table->select->cond->quick_fix_field();
} }
curr_table->select_cond= curr_table->select->cond; curr_table->select_cond= curr_table->select->cond;
curr_table->select_cond->top_level_item(); curr_table->select_cond->top_level_item();
...@@ -3533,7 +3536,7 @@ make_join_select(JOIN *join,SQL_SELECT *select,COND *cond) ...@@ -3533,7 +3536,7 @@ make_join_select(JOIN *join,SQL_SELECT *select,COND *cond)
{ {
/* Join with outer join condition */ /* Join with outer join condition */
COND *orig_cond=sel->cond; COND *orig_cond=sel->cond;
sel->cond=and_conds(sel->cond,tab->on_expr); sel->cond=and_conds(sel->cond, tab->on_expr, 0);
if (sel->test_quick_select(join->thd, tab->keys, if (sel->test_quick_select(join->thd, tab->keys,
used_tables & ~ current_map, used_tables & ~ current_map,
(join->select_options & (join->select_options &
...@@ -5016,7 +5019,7 @@ create_tmp_table(THD *thd,TMP_TABLE_PARAM *param,List<Item> &fields, ...@@ -5016,7 +5019,7 @@ create_tmp_table(THD *thd,TMP_TABLE_PARAM *param,List<Item> &fields,
*blob_field++= new_field; *blob_field++= new_field;
blob_count++; blob_count++;
} }
((Item_sum*) item)->args[i]= new Item_field(new_field, 1); ((Item_sum*) item)->args[i]= new Item_field(new_field);
} }
} }
} }
...@@ -6798,8 +6801,14 @@ make_cond_for_table(COND *cond, table_map tables, table_map used_table) ...@@ -6798,8 +6801,14 @@ make_cond_for_table(COND *cond, table_map tables, table_map used_table)
case 1: case 1:
return new_cond->argument_list()->head(); return new_cond->argument_list()->head();
default: default:
if (new_cond->fix_fields(current_thd, 0, (Item**)&new_cond)) /*
return (COND*) 0; Item_cond_and do not need fix_fields for execution, its parameters
are fixed or do not need fix_fields, too
*/
new_cond->quick_fix_field();
new_cond->used_tables_cache=
((Item_cond_and*) cond)->used_tables_cache &
tables;
return new_cond; return new_cond;
} }
} }
...@@ -6817,8 +6826,12 @@ make_cond_for_table(COND *cond, table_map tables, table_map used_table) ...@@ -6817,8 +6826,12 @@ make_cond_for_table(COND *cond, table_map tables, table_map used_table)
return (COND*) 0; // Always true return (COND*) 0; // Always true
new_cond->argument_list()->push_back(fix); new_cond->argument_list()->push_back(fix);
} }
if (new_cond->fix_fields(current_thd, 0, (Item**)&new_cond)) /*
return (COND*) 0; Item_cond_and do not need fix_fields for execution, its parameters
are fixed or do not need fix_fields, too
*/
new_cond->quick_fix_field();
new_cond->used_tables_cache= ((Item_cond_or*) cond)->used_tables_cache;
new_cond->top_level_item(); new_cond->top_level_item();
return new_cond; return new_cond;
} }
...@@ -7324,7 +7337,7 @@ static bool fix_having(JOIN *join, Item **having) ...@@ -7324,7 +7337,7 @@ static bool fix_having(JOIN *join, Item **having)
else // This should never happen else // This should never happen
if (!(table->select->cond= new Item_cond_and(table->select->cond, if (!(table->select->cond= new Item_cond_and(table->select->cond,
sort_table_cond)) || sort_table_cond)) ||
table->select->cond->fix_fields(join->thd, join->tanles_list, table->select->cond->fix_fields(join->thd, join->tables_list,
&table->select->cond)) &table->select->cond))
return 1; return 1;
table->select_cond=table->select->cond; table->select_cond=table->select->cond;
...@@ -7945,12 +7958,13 @@ find_order_in_list(THD *thd, Item **ref_pointer_array, ...@@ -7945,12 +7958,13 @@ find_order_in_list(THD *thd, Item **ref_pointer_array,
order->in_field_list=0; order->in_field_list=0;
Item *it= *order->item; Item *it= *order->item;
/* /*
we check it->fixed because Item_func_group_concat can put We check it->fixed because Item_func_group_concat can put
arguments for which fix_fields already was called arguments for which fix_fields already was called.
'it' reassigned in if condition because fix_field can change it.
*/ */
if (!it->fixed && if (!it->fixed &&
(it->fix_fields(thd, tables, order->item) || (it->fix_fields(thd, tables, order->item) ||
//'it' ressigned because fix_field can change it
(it= *order->item)->check_cols(1) || (it= *order->item)->check_cols(1) ||
thd->is_fatal_error)) thd->is_fatal_error))
return 1; // Wrong field return 1; // Wrong field
...@@ -8603,7 +8617,7 @@ change_to_use_tmp_fields(THD *thd, Item **ref_pointer_array, ...@@ -8603,7 +8617,7 @@ change_to_use_tmp_fields(THD *thd, Item **ref_pointer_array,
if (item->type() == Item::SUM_FUNC_ITEM && field->table->group) if (item->type() == Item::SUM_FUNC_ITEM && field->table->group)
item_field= ((Item_sum*) item)->result_item(field); item_field= ((Item_sum*) item)->result_item(field);
else else
item_field= (Item*) new Item_field(field, 1); item_field= (Item*) new Item_field(field);
if (!item_field) if (!item_field)
return TRUE; // Fatal error return TRUE; // Fatal error
item_field->name= item->name; /*lint -e613 */ item_field->name= item->name; /*lint -e613 */
...@@ -8778,7 +8792,7 @@ static bool add_ref_to_table_cond(THD *thd, JOIN_TAB *join_tab) ...@@ -8778,7 +8792,7 @@ static bool add_ref_to_table_cond(THD *thd, JOIN_TAB *join_tab)
Field *field=table->field[table->key_info[join_tab->ref.key].key_part[i]. Field *field=table->field[table->key_info[join_tab->ref.key].key_part[i].
fieldnr-1]; fieldnr-1];
Item *value=join_tab->ref.items[i]; Item *value=join_tab->ref.items[i];
cond->add(new Item_func_equal(new Item_field(field, 1), value)); cond->add(new Item_func_equal(new Item_field(field), value));
} }
if (thd->is_fatal_error) if (thd->is_fatal_error)
DBUG_RETURN(TRUE); DBUG_RETURN(TRUE);
......
...@@ -1050,7 +1050,7 @@ mysqld_list_fields(THD *thd, TABLE_LIST *table_list, const char *wild) ...@@ -1050,7 +1050,7 @@ mysqld_list_fields(THD *thd, TABLE_LIST *table_list, const char *wild)
{ {
if (!wild || !wild[0] || if (!wild || !wild[0] ||
!wild_case_compare(system_charset_info, field->field_name,wild)) !wild_case_compare(system_charset_info, field->field_name,wild))
field_list.push_back(new Item_field(field, 1)); field_list.push_back(new Item_field(field));
} }
restore_record(table,default_values); // Get empty record restore_record(table,default_values); // Get empty record
if (thd->protocol->send_fields(&field_list,2)) if (thd->protocol->send_fields(&field_list,2))
......
...@@ -229,12 +229,9 @@ int st_select_lex_unit::prepare(THD *thd_arg, select_result *sel_result, ...@@ -229,12 +229,9 @@ int st_select_lex_unit::prepare(THD *thd_arg, select_result *sel_result,
Field **field; Field **field;
for (field= table->field; *field; field++) for (field= table->field; *field; field++)
{ {
Item_field *item= new Item_field(*field, 1); Item_field *item= new Item_field(*field);
if (item_list.push_back(item)) if (!item || item_list.push_back(item))
DBUG_RETURN(-1); DBUG_RETURN(-1);
#ifndef DBUG_OFF
item->double_fix= 0;
#endif
} }
} }
} }
...@@ -463,4 +460,17 @@ int st_select_lex_unit::cleanup() ...@@ -463,4 +460,17 @@ int st_select_lex_unit::cleanup()
void st_select_lex_unit::reinit_exec_mechanism() void st_select_lex_unit::reinit_exec_mechanism()
{ {
prepared= optimized= executed= 0; prepared= optimized= executed= 0;
#ifndef DBUG_OFF
List_iterator_fast<Item> it(item_list);
Item_field *field;
while ((field= (Item_field *)it++))
{
/*
we can't cleanup here, because it broke link to temporary table field,
but have to drop fixed flag to allow next fix_field of this field
during re-executing
*/
field->fixed= 0;
}
#endif
} }
...@@ -689,7 +689,7 @@ multi_update::initialize_tables(JOIN *join) ...@@ -689,7 +689,7 @@ multi_update::initialize_tables(JOIN *join)
{ {
TABLE *table=table_ref->table; TABLE *table=table_ref->table;
uint cnt= table_ref->shared; uint cnt= table_ref->shared;
Item_field *If; Item_field *ifield;
List<Item> temp_fields= *fields_for_table[cnt]; List<Item> temp_fields= *fields_for_table[cnt];
ORDER group; ORDER group;
...@@ -713,10 +713,10 @@ multi_update::initialize_tables(JOIN *join) ...@@ -713,10 +713,10 @@ multi_update::initialize_tables(JOIN *join)
/* ok to be on stack as this is not referenced outside of this func */ /* ok to be on stack as this is not referenced outside of this func */
Field_string offset(table->file->ref_length, 0, "offset", Field_string offset(table->file->ref_length, 0, "offset",
table, &my_charset_bin); table, &my_charset_bin);
if (!(If= new Item_field(((Field *) &offset), 1))) if (!(ifield= new Item_field(((Field *) &offset))))
DBUG_RETURN(1); DBUG_RETURN(1);
If->maybe_null=0; ifield->maybe_null= 0;
if (temp_fields.push_front(If)) if (temp_fields.push_front(ifield))
DBUG_RETURN(1); DBUG_RETURN(1);
/* Make an unique key over the first field to avoid duplicated updates */ /* Make an unique key over the first field to avoid duplicated updates */
......
...@@ -4353,10 +4353,10 @@ purge_option: ...@@ -4353,10 +4353,10 @@ purge_option:
} }
Item *tmp= new Item_func_unix_timestamp($2); Item *tmp= new Item_func_unix_timestamp($2);
/* /*
it is OK olny emulate fix_fieds, because we need only it is OK only emulate fix_fieds, because we need only
value of constant value of constant
*/ */
tmp->Item::fix_fields(0,0,0); tmp->quick_fix_field();
Lex->sql_command = SQLCOM_PURGE_BEFORE; Lex->sql_command = SQLCOM_PURGE_BEFORE;
Lex->purge_time= (ulong) tmp->val_int(); Lex->purge_time= (ulong) tmp->val_int();
} }
...@@ -4492,11 +4492,11 @@ text_string: ...@@ -4492,11 +4492,11 @@ text_string:
{ {
Item *tmp = new Item_varbinary($1.str,$1.length); Item *tmp = new Item_varbinary($1.str,$1.length);
/* /*
it is OK olny emulate fix_fieds, because we need only it is OK only emulate fix_fieds, because we need only
value of constant value of constant
*/ */
$$= tmp ? $$= tmp ?
tmp->Item::fix_fields(0,0,0), tmp->val_str((String*) 0) : tmp->quick_fix_field(), tmp->val_str((String*) 0) :
(String*) 0; (String*) 0;
} }
; ;
...@@ -4529,9 +4529,8 @@ signed_literal: ...@@ -4529,9 +4529,8 @@ signed_literal:
| '+' NUM_literal { $$ = $2; } | '+' NUM_literal { $$ = $2; }
| '-' NUM_literal | '-' NUM_literal
{ {
$2->neg();
$2->max_length++; $2->max_length++;
$$= $2; $$= $2->neg();
} }
; ;
...@@ -4546,11 +4545,11 @@ literal: ...@@ -4546,11 +4545,11 @@ literal:
{ {
Item *tmp= new Item_varbinary($2.str,$2.length); Item *tmp= new Item_varbinary($2.str,$2.length);
/* /*
it is OK olny emulate fix_fieds, because we need only it is OK only emulate fix_fieds, because we need only
value of constant value of constant
*/ */
String *str= tmp ? String *str= tmp ?
tmp->Item::fix_fields(0,0,0), tmp->val_str((String*) 0) : tmp->quick_fix_field(), tmp->val_str((String*) 0) :
(String*) 0; (String*) 0;
$$= new Item_string(str ? str->ptr() : "", $$= new Item_string(str ? str->ptr() : "",
str ? str->length() : 0, str ? str->length() : 0,
......
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