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

Merge sanja.is.com.ua:/home/bell/mysql/bk/mysql-5.0

into sanja.is.com.ua:/home/bell/mysql/bk/work-bug4-5.0
parents 637a353d a1167702
......@@ -1726,3 +1726,20 @@ sum(a)
drop procedure p1;
drop view v1;
drop table t1;
create table t1 (s1 int);
create view v1 as select sum(distinct s1) from t1;
select * from v1;
sum(distinct s1)
NULL
drop view v1;
create view v1 as select avg(distinct s1) from t1;
select * from v1;
avg(distinct s1)
NULL
drop view v1;
drop table t1;
create view v1 as select cast(1 as decimal);
select * from v1;
cast(1 as decimal)
1.00
drop view v1;
......@@ -1569,3 +1569,21 @@ drop procedure p1;
drop view v1;
drop table t1;
#
# using sum(distinct ) & avg(distinct ) in views (BUG#7015)
#
create table t1 (s1 int);
create view v1 as select sum(distinct s1) from t1;
select * from v1;
drop view v1;
create view v1 as select avg(distinct s1) from t1;
select * from v1;
drop view v1;
drop table t1;
#
# using cast(... as decimal) in views (BUG#11387);
#
create view v1 as select cast(1 as decimal);
select * from v1;
drop view v1;
......@@ -468,6 +468,18 @@ public:
*/
virtual bool const_during_execution() const
{ return (used_tables() & ~PARAM_TABLE_BIT) == 0; }
/*
This is an essential method for correct functioning of VIEWS.
To save a view in an .frm file we need its unequivocal
definition in SQL that takes into account sql_mode and
environmental settings. Currently such definition is restored
by traversing through the parsed tree of a view and
print()'ing SQL syntax of every node to a String buffer. This
method is used to print the SQL definition of an item. The
second use of this method is for EXPLAIN EXTENDED, to print
the SQL of a query after all optimizations of the parsed tree
have been done.
*/
virtual void print(String *str_arg) { str_arg->append(full_name()); }
void print_item_w_name(String *);
virtual void update_used_tables() {}
......
......@@ -1061,6 +1061,14 @@ my_decimal *Item_decimal_typecast::val_decimal(my_decimal *dec)
}
void Item_decimal_typecast::print(String *str)
{
str->append("cast(", 5);
args[0]->print(str);
str->append(" as decimal)", 12);
}
double Item_func_plus::real_op()
{
double value= args[0]->val_real() + args[1]->val_real();
......@@ -4111,7 +4119,7 @@ bool Item_func_get_user_var::eq(const Item *item, bool binary_cmp) const
return 1; // Same item is same.
/* Check if other type is also a get_user_var() object */
if (item->type() != FUNC_ITEM ||
((Item_func*) item)->func_name() != func_name())
((Item_func*) item)->functype() != functype())
return 0;
Item_func_get_user_var *other=(Item_func_get_user_var*) item;
return (name.length == other->name.length &&
......
......@@ -54,7 +54,8 @@ public:
SP_POINTN,SP_GEOMETRYN,SP_INTERIORRINGN,
NOT_FUNC, NOT_ALL_FUNC,
NOW_FUNC, TRIG_COND_FUNC,
GUSERVAR_FUNC};
GUSERVAR_FUNC, COLLATE_FUNC,
EXTRACT_FUNC, CHAR_TYPECAST_FUNC };
enum optimize_type { OPTIMIZE_NONE,OPTIMIZE_KEY,OPTIMIZE_OP, OPTIMIZE_NULL,
OPTIMIZE_EQUAL };
enum Type type() const { return FUNC_ITEM; }
......@@ -123,7 +124,17 @@ public:
virtual optimize_type select_optimize() const { return OPTIMIZE_NONE; }
virtual bool have_rev_func() const { return 0; }
virtual Item *key_item() const { return args[0]; }
virtual const char *func_name() const { return "?"; }
/*
This method is used for debug purposes to print the name of an
item to the debug log. The second use of this method is as
a helper function of print(), where it is applicable.
To suit both goals it should return a meaningful,
distinguishable and sintactically correct string. This method
should not be used for runtime type identification, use enum
{Sum}Functype and Item_func::functype()/Item_sum::sum_func()
instead.
*/
virtual const char *func_name() const= 0;
virtual bool const_item() const { return const_item_cache; }
inline Item **arguments() const { return args; }
void set_arguments(List<Item> &list);
......@@ -306,6 +317,8 @@ public:
enum Item_result result_type () const { return DECIMAL_RESULT; }
enum_field_types field_type() const { return MYSQL_TYPE_NEWDECIMAL; }
void fix_length_and_dec() {};
const char *func_name() const { return "decimal_typecast"; }
void print(String *);
};
......@@ -506,7 +519,7 @@ public:
class Item_func_acos :public Item_dec_func
{
public:
public:
Item_func_acos(Item *a) :Item_dec_func(a) {}
double val_real();
const char *func_name() const { return "acos"; }
......@@ -514,7 +527,7 @@ class Item_func_acos :public Item_dec_func
class Item_func_asin :public Item_dec_func
{
public:
public:
Item_func_asin(Item *a) :Item_dec_func(a) {}
double val_real();
const char *func_name() const { return "asin"; }
......@@ -522,7 +535,7 @@ class Item_func_asin :public Item_dec_func
class Item_func_atan :public Item_dec_func
{
public:
public:
Item_func_atan(Item *a) :Item_dec_func(a) {}
Item_func_atan(Item *a,Item *b) :Item_dec_func(a,b) {}
double val_real();
......@@ -531,7 +544,7 @@ class Item_func_atan :public Item_dec_func
class Item_func_cos :public Item_dec_func
{
public:
public:
Item_func_cos(Item *a) :Item_dec_func(a) {}
double val_real();
const char *func_name() const { return "cos"; }
......@@ -539,7 +552,7 @@ class Item_func_cos :public Item_dec_func
class Item_func_sin :public Item_dec_func
{
public:
public:
Item_func_sin(Item *a) :Item_dec_func(a) {}
double val_real();
const char *func_name() const { return "sin"; }
......@@ -547,7 +560,7 @@ class Item_func_sin :public Item_dec_func
class Item_func_tan :public Item_dec_func
{
public:
public:
Item_func_tan(Item *a) :Item_dec_func(a) {}
double val_real();
const char *func_name() const { return "tan"; }
......@@ -634,7 +647,7 @@ class Item_func_units :public Item_real_func
{
char *name;
double mul,add;
public:
public:
Item_func_units(char *name_arg,Item *a,double mul_arg,double add_arg)
:Item_real_func(a),name(name_arg),mul(mul_arg),add(add_arg) {}
double val_real();
......@@ -853,7 +866,7 @@ public:
class Item_func_benchmark :public Item_int_func
{
ulong loop_count;
public:
public:
Item_func_benchmark(ulong loop_count_arg,Item *expr)
:Item_int_func(expr), loop_count(loop_count_arg)
{}
......@@ -868,7 +881,7 @@ class Item_func_benchmark :public Item_int_func
class Item_udf_func :public Item_func
{
protected:
protected:
udf_handler udf;
public:
......@@ -1046,7 +1059,7 @@ class Item_func_get_lock :public Item_int_func
class Item_func_release_lock :public Item_int_func
{
String value;
public:
public:
Item_func_release_lock(Item *a) :Item_int_func(a) {}
longlong val_int();
const char *func_name() const { return "release_lock"; }
......@@ -1058,7 +1071,7 @@ class Item_func_release_lock :public Item_int_func
class Item_master_pos_wait :public Item_int_func
{
String value;
public:
public:
Item_master_pos_wait(Item *a,Item *b) :Item_int_func(a,b) {}
Item_master_pos_wait(Item *a,Item *b,Item *c) :Item_int_func(a,b,c) {}
longlong val_int();
......
......@@ -2297,7 +2297,7 @@ bool Item_func_set_collation::eq(const Item *item, bool binary_cmp) const
return 0;
Item_func *item_func=(Item_func*) item;
if (arg_count != item_func->arg_count ||
func_name() != item_func->func_name())
functype() != item_func->functype())
return 0;
Item_func_set_collation *item_func_sc=(Item_func_set_collation*) item;
if (collation.collation != item_func_sc->collation.collation)
......
......@@ -573,6 +573,7 @@ public:
max_length=args[0]->max_length;
}
void print(String *str);
const char *func_name() const { return "cast_as_binary"; }
};
......@@ -648,6 +649,7 @@ public:
void fix_length_and_dec();
bool eq(const Item *item, bool binary_cmp) const;
const char *func_name() const { return "collate"; }
enum Functype func_type() const { return COLLATE_FUNC; }
void print(String *str);
Item_field *filed_for_view_update()
{
......
......@@ -86,7 +86,6 @@ void Item_sum::make_field(Send_field *tmp_field)
void Item_sum::print(String *str)
{
str->append(func_name());
str->append('(');
for (uint i=0 ; i < arg_count ; i++)
{
if (i)
......@@ -2425,13 +2424,6 @@ longlong Item_sum_count_distinct::val_int()
}
void Item_sum_count_distinct::print(String *str)
{
str->append("count(distinct ", 15);
args[0]->print(str);
str->append(')');
}
/****************************************************************************
** Functions to handle dynamic loadable aggregates
** Original source by: Alexis Mikhailov <root@medinf.chuvashia.su>
......@@ -2466,6 +2458,20 @@ void Item_udf_sum::cleanup()
}
void Item_udf_sum::print(String *str)
{
str->append(func_name());
str->append('(');
for (uint i=0 ; i < arg_count ; i++)
{
if (i)
str->append(',');
args[i]->print(str);
}
str->append(')');
}
Item *Item_sum_udf_float::copy_or_same(THD* thd)
{
return new (thd->mem_root) Item_sum_udf_float(thd, this);
......
......@@ -81,7 +81,22 @@ public:
virtual void update_field()=0;
virtual bool keep_field_type(void) const { return 0; }
virtual void fix_length_and_dec() { maybe_null=1; null_value=1; }
virtual const char *func_name() const { return "?"; }
/*
This method is used for debug purposes to print the name of an
item to the debug log. The second use of this method is as
a helper function of print(), where it is applicable.
To suit both goals it should return a meaningful,
distinguishable and sintactically correct string. This method
should not be used for runtime type identification, use enum
{Sum}Functype and Item_func::functype()/Item_sum::sum_func()
instead.
NOTE: for Items inherited from Item_sum, func_name() return part of
function name till first argument (including '(') to make difference in
names for functions with 'distinct' clause and without 'distinct' and
also to make printing of items inherited from Item_sum uniform.
*/
virtual const char *func_name() const= 0;
virtual Item *result_item(Field *field)
{ return new Item_field(field);}
table_map used_tables() const { return ~(table_map) 0; } /* Not used */
......@@ -159,7 +174,7 @@ public:
void reset_field();
void update_field();
void no_rows_in_result() {}
const char *func_name() const { return "sum"; }
const char *func_name() const { return "sum("; }
Item *copy_or_same(THD* thd);
};
......@@ -200,7 +215,6 @@ public:
enum Sumfunctype sum_func () const { return SUM_DISTINCT_FUNC; }
void reset_field() {} // not used
void update_field() {} // not used
const char *func_name() const { return "sum_distinct"; }
virtual void no_rows_in_result() {}
void fix_length_and_dec();
enum Item_result result_type () const { return val.traits->type(); }
......@@ -224,7 +238,7 @@ public:
Item_sum_sum_distinct(Item *item_arg) :Item_sum_distinct(item_arg) {}
enum Sumfunctype sum_func () const { return SUM_DISTINCT_FUNC; }
const char *func_name() const { return "sum_distinct"; }
const char *func_name() const { return "sum(distinct "; }
Item *copy_or_same(THD* thd) { return new Item_sum_sum_distinct(thd, this); }
};
......@@ -243,7 +257,7 @@ public:
void fix_length_and_dec();
virtual void calculate_val_and_count();
enum Sumfunctype sum_func () const { return AVG_DISTINCT_FUNC; }
const char *func_name() const { return "avg_distinct"; }
const char *func_name() const { return "avg(distinct "; }
Item *copy_or_same(THD* thd) { return new Item_sum_avg_distinct(thd, this); }
};
......@@ -272,7 +286,7 @@ class Item_sum_count :public Item_sum_int
void reset_field();
void cleanup();
void update_field();
const char *func_name() const { return "count"; }
const char *func_name() const { return "count("; }
Item *copy_or_same(THD* thd);
};
......@@ -326,12 +340,11 @@ public:
longlong val_int();
void reset_field() { return ;} // Never called
void update_field() { return ; } // Never called
const char *func_name() const { return "count_distinct"; }
const char *func_name() const { return "count(distinct "; }
bool setup(THD *thd);
void make_unique();
Item *copy_or_same(THD* thd);
void no_rows_in_result() {}
void print(String *str);
};
......@@ -389,7 +402,7 @@ public:
Item *result_item(Field *field)
{ return new Item_avg_field(hybrid_type, this); }
void no_rows_in_result() {}
const char *func_name() const { return "avg"; }
const char *func_name() const { return "avg("; }
Item *copy_or_same(THD* thd);
Field *create_tmp_field(bool group, TABLE *table, uint convert_blob_length);
};
......@@ -466,7 +479,7 @@ public:
Item *result_item(Field *field)
{ return new Item_variance_field(this); }
void no_rows_in_result() {}
const char *func_name() const { return "variance"; }
const char *func_name() const { return "variance("; }
Item *copy_or_same(THD* thd);
Field *create_tmp_field(bool group, TABLE *table, uint convert_blob_length);
enum Item_result result_type () const { return hybrid_type; }
......@@ -501,7 +514,7 @@ class Item_sum_std :public Item_sum_variance
double val_real();
Item *result_item(Field *field)
{ return new Item_std_field(this); }
const char *func_name() const { return "std"; }
const char *func_name() const { return "std("; }
Item *copy_or_same(THD* thd);
enum Item_result result_type () const { return REAL_RESULT; }
enum_field_types field_type() const { return MYSQL_TYPE_DOUBLE;}
......@@ -565,7 +578,7 @@ public:
enum Sumfunctype sum_func () const {return MIN_FUNC;}
bool add();
const char *func_name() const { return "min"; }
const char *func_name() const { return "min("; }
Item *copy_or_same(THD* thd);
};
......@@ -578,7 +591,7 @@ public:
enum Sumfunctype sum_func () const {return MAX_FUNC;}
bool add();
const char *func_name() const { return "max"; }
const char *func_name() const { return "max("; }
Item *copy_or_same(THD* thd);
};
......@@ -609,7 +622,7 @@ public:
Item_sum_or(Item *item_par) :Item_sum_bit(item_par,LL(0)) {}
Item_sum_or(THD *thd, Item_sum_or *item) :Item_sum_bit(thd, item) {}
bool add();
const char *func_name() const { return "bit_or"; }
const char *func_name() const { return "bit_or("; }
Item *copy_or_same(THD* thd);
};
......@@ -620,7 +633,7 @@ class Item_sum_and :public Item_sum_bit
Item_sum_and(Item *item_par) :Item_sum_bit(item_par, ULONGLONG_MAX) {}
Item_sum_and(THD *thd, Item_sum_and *item) :Item_sum_bit(thd, item) {}
bool add();
const char *func_name() const { return "bit_and"; }
const char *func_name() const { return "bit_and("; }
Item *copy_or_same(THD* thd);
};
......@@ -630,7 +643,7 @@ class Item_sum_xor :public Item_sum_bit
Item_sum_xor(Item *item_par) :Item_sum_bit(item_par,LL(0)) {}
Item_sum_xor(THD *thd, Item_sum_xor *item) :Item_sum_bit(thd, item) {}
bool add();
const char *func_name() const { return "bit_xor"; }
const char *func_name() const { return "bit_xor("; }
Item *copy_or_same(THD* thd);
};
......@@ -668,6 +681,7 @@ public:
void reset_field() {};
void update_field() {};
void cleanup();
void print(String *str);
};
......
......@@ -2158,7 +2158,7 @@ bool Item_extract::eq(const Item *item, bool binary_cmp) const
if (this == item)
return 1;
if (item->type() != FUNC_ITEM ||
func_name() != ((Item_func*)item)->func_name())
functype() != ((Item_func*)item)->functype())
return 0;
Item_extract* ie= (Item_extract*)item;
......@@ -2176,7 +2176,7 @@ bool Item_char_typecast::eq(const Item *item, bool binary_cmp) const
if (this == item)
return 1;
if (item->type() != FUNC_ITEM ||
func_name() != ((Item_func*)item)->func_name())
functype() != ((Item_func*)item)->functype())
return 0;
Item_char_typecast *cast= (Item_char_typecast*)item;
......
......@@ -637,6 +637,7 @@ class Item_extract :public Item_int_func
Item_extract(interval_type type_arg, Item *a)
:Item_int_func(a), int_type(type_arg) {}
longlong val_int();
enum Functype functype() const { return EXTRACT_FUNC; }
const char *func_name() const { return "extract"; }
void fix_length_and_dec();
bool eq(const Item *item, bool binary_cmp) const;
......@@ -689,6 +690,7 @@ class Item_char_typecast :public Item_typecast
public:
Item_char_typecast(Item *a, int length_arg, CHARSET_INFO *cs_arg)
:Item_typecast(a), cast_length(length_arg), cast_cs(cs_arg) {}
enum Functype functype() const { return CHAR_TYPECAST_FUNC; }
bool eq(const Item *item, bool binary_cmp) const;
const char *func_name() const { return "cast_as_char"; }
const char* cast_type() const { return "char"; };
......@@ -790,6 +792,7 @@ public:
return (new Field_string(max_length, maybe_null, name, t_arg, &my_charset_bin));
}
void print(String *str);
const char *func_name() const { return "add_time"; }
};
class Item_func_timediff :public Item_str_func
......
......@@ -30,6 +30,7 @@ public:
double val_real() { DBUG_ASSERT(fixed == 1); return 0.0; }
void fix_length_and_dec() { decimals=0; max_length=6; }
void print(String *str) { str->append("0.0", 3); }
const char *func_name() const { return "unique_users"; }
};
......@@ -58,4 +59,5 @@ public:
}
void print(String *str) { str->append("0.0", 3); }
Field *create_tmp_field(bool group, TABLE *table, uint convert_blob_length);
const char *func_name() const { return "sum_unique_users"; }
};
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