mirror of
https://github.com/MariaDB/server.git
synced 2025-07-30 16:24:05 +03:00
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 sql/item.h: Auto merged sql/item_func.cc: Auto merged
This commit is contained in:
@ -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;
|
||||
|
12
sql/item.h
12
sql/item.h
@ -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 *);
|
||||
};
|
||||
|
||||
|
||||
|
@ -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"; }
|
||||
};
|
||||
|
Reference in New Issue
Block a user