1
/* -*- mode: c++; c-basic-offset: 2; indent-tabs-mode: nil; -*-
2
* vim:expandtab:shiftwidth=2:tabstop=2:smarttab:
4
* Copyright (C) 2008 Sun Microsystems
6
* This program is free software; you can redistribute it and/or modify
7
* it under the terms of the GNU General Public License as published by
8
* the Free Software Foundation; version 2 of the License.
10
* This program is distributed in the hope that it will be useful,
11
* but WITHOUT ANY WARRANTY; without even the implied warranty of
12
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13
* GNU General Public License for more details.
15
* You should have received a copy of the GNU General Public License
16
* along with this program; if not, write to the Free Software
17
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
20
#ifndef DRIZZLED_SERVER_ITEM_FUNC_H
21
#define DRIZZLED_SERVER_ITEM_FUNC_H
1
/* Copyright (C) 2000-2006 MySQL AB
3
This program is free software; you can redistribute it and/or modify
4
it under the terms of the GNU General Public License as published by
5
the Free Software Foundation; version 2 of the License.
7
This program is distributed in the hope that it will be useful,
8
but WITHOUT ANY WARRANTY; without even the implied warranty of
9
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10
GNU General Public License for more details.
12
You should have received a copy of the GNU General Public License
13
along with this program; if not, write to the Free Software
14
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
23
17
/* Function items used by mysql */
136
130
{Sum}Functype and Item_func::functype()/Item_sum::sum_func()
139
virtual const char *func_name() const { return NULL; };
133
virtual const char *func_name() const= 0;
140
134
virtual bool const_item() const { return const_item_cache; }
141
135
inline Item **arguments() const { return args; }
142
136
void set_arguments(List<Item> &list);
143
inline uint32_t argument_count() const { return arg_count; }
137
inline uint argument_count() const { return arg_count; }
144
138
inline void remove_arguments() { arg_count=0; }
145
139
void split_sum_func(THD *thd, Item **ref_pointer_array, List<Item> &fields);
146
140
virtual void print(String *str, enum_query_type query_type);
147
141
void print_op(String *str, enum_query_type query_type);
148
void print_args(String *str, uint32_t from, enum_query_type query_type);
142
void print_args(String *str, uint from, enum_query_type query_type);
149
143
virtual void fix_num_length_and_dec();
150
144
void count_only_length();
151
145
void count_real_length();
152
146
void count_decimal_length();
153
inline bool get_arg0_date(DRIZZLE_TIME *ltime, uint32_t fuzzy_date)
147
inline bool get_arg0_date(MYSQL_TIME *ltime, uint fuzzy_date)
155
149
return (null_value=args[0]->get_date(ltime, fuzzy_date));
157
inline bool get_arg0_time(DRIZZLE_TIME *ltime)
151
inline bool get_arg0_time(MYSQL_TIME *ltime)
159
153
return (null_value=args[0]->get_time(ltime));
163
157
return null_value;
165
159
void signal_divide_by_null();
160
friend class udf_handler;
167
161
Field *tmp_table_field() { return result_field; }
168
Field *tmp_table_field(Table *t_arg);
162
Field *tmp_table_field(TABLE *t_arg);
169
163
Item *get_tmp_table_item(THD *thd);
171
165
my_decimal *val_decimal(my_decimal *);
173
bool agg_arg_collations(DTCollation &c, Item **items, uint32_t nitems,
167
bool agg_arg_collations(DTCollation &c, Item **items, uint nitems,
176
170
return agg_item_collations(c, func_name(), items, nitems, flags, 1);
178
172
bool agg_arg_collations_for_comparison(DTCollation &c,
179
Item **items, uint32_t nitems,
173
Item **items, uint nitems,
182
176
return agg_item_collations_for_comparison(c, func_name(),
183
177
items, nitems, flags);
185
bool agg_arg_charsets(DTCollation &c, Item **items, uint32_t nitems,
186
uint32_t flags, int item_sep)
179
bool agg_arg_charsets(DTCollation &c, Item **items, uint nitems,
180
uint flags, int item_sep)
188
182
return agg_item_charsets(c, func_name(), items, nitems, flags, item_sep);
190
bool walk(Item_processor processor, bool walk_subquery, unsigned char *arg);
191
Item *transform(Item_transformer transformer, unsigned char *arg);
192
Item* compile(Item_analyzer analyzer, unsigned char **arg_p,
193
Item_transformer transformer, unsigned char *arg_t);
184
bool walk(Item_processor processor, bool walk_subquery, uchar *arg);
185
Item *transform(Item_transformer transformer, uchar *arg);
186
Item* compile(Item_analyzer analyzer, uchar **arg_p,
187
Item_transformer transformer, uchar *arg_t);
194
188
void traverse_cond(Cond_traverser traverser,
195
189
void * arg, traverse_order order);
196
190
inline double fix_result(double value)
992
986
virtual void print(String *str, enum_query_type query_type);
990
class Item_udf_func :public Item_func
994
bool is_expensive_processor(uchar *arg __attribute__((__unused__)))
998
Item_udf_func(udf_func *udf_arg)
999
:Item_func(), udf(udf_arg) {}
1000
Item_udf_func(udf_func *udf_arg, List<Item> &list)
1001
:Item_func(list), udf(udf_arg) {}
1002
const char *func_name() const { return udf.name(); }
1003
enum Functype functype() const { return UDF_FUNC; }
1004
bool fix_fields(THD *thd, Item **ref __attribute__((__unused__)))
1007
bool res= udf.fix_fields(thd, this, arg_count, args);
1008
used_tables_cache= udf.used_tables_cache;
1009
const_item_cache= udf.const_item_cache;
1013
void update_used_tables()
1016
TODO: Make a member in UDF_INIT and return if a UDF is deterministic or
1018
Currently UDF_INIT has a member (const_item) that is an in/out
1019
parameter to the init() call.
1020
The code in udf_handler::fix_fields also duplicates the arguments
1021
handling code in Item_func::fix_fields().
1023
The lack of information if a UDF is deterministic makes writing
1024
a correct update_used_tables() for UDFs impossible.
1025
One solution to this would be :
1026
- Add a is_deterministic member of UDF_INIT
1027
- (optionally) deprecate the const_item member of UDF_INIT
1028
- Take away the duplicate code from udf_handler::fix_fields() and
1029
make Item_udf_func call Item_func::fix_fields() to process its
1030
arguments as for any other function.
1031
- Store the deterministic flag returned by <udf>_init into the
1033
- Don't implement Item_udf_func::fix_fields, implement
1034
Item_udf_func::fix_length_and_dec() instead (similar to non-UDF
1036
- Override Item_func::update_used_tables to call
1037
Item_func::update_used_tables() and add a RAND_TABLE_BIT to the
1038
result of Item_func::update_used_tables() if the UDF is
1040
- (optionally) rename RAND_TABLE_BIT to NONDETERMINISTIC_BIT to
1041
better describe its usage.
1043
The above would require a change of the UDF API.
1044
Until that change is done here's how the current code works:
1045
We call Item_func::update_used_tables() only when we know that
1046
the function depends on real non-const tables and is deterministic.
1047
This can be done only because we know that the optimizer will
1048
call update_used_tables() only when there's possibly a new const
1049
table. So update_used_tables() can only make a Item_func more
1050
constant than it is currently.
1051
That's why we don't need to do anything if a function is guaranteed
1052
to return non-constant (it's non-deterministic) or is already a
1055
if ((used_tables_cache & ~PSEUDO_TABLE_BITS) &&
1056
!(used_tables_cache & RAND_TABLE_BIT))
1058
Item_func::update_used_tables();
1059
if (!const_item_cache && !used_tables_cache)
1060
used_tables_cache= RAND_TABLE_BIT;
1064
Item_result result_type () const { return udf.result_type(); }
1065
table_map not_null_tables() const { return 0; }
1066
virtual void print(String *str, enum_query_type query_type);
1070
class Item_func_udf_float :public Item_udf_func
1073
Item_func_udf_float(udf_func *udf_arg)
1074
:Item_udf_func(udf_arg) {}
1075
Item_func_udf_float(udf_func *udf_arg,
1077
:Item_udf_func(udf_arg, list) {}
1081
return (int64_t) rint(Item_func_udf_float::val_real());
1083
my_decimal *val_decimal(my_decimal *dec_buf)
1085
double res=val_real();
1088
double2my_decimal(E_DEC_FATAL_ERROR, res, dec_buf);
1092
String *val_str(String *str);
1093
void fix_length_and_dec() { fix_num_length_and_dec(); }
1097
class Item_func_udf_int :public Item_udf_func
1100
Item_func_udf_int(udf_func *udf_arg)
1101
:Item_udf_func(udf_arg) {}
1102
Item_func_udf_int(udf_func *udf_arg,
1104
:Item_udf_func(udf_arg, list) {}
1106
double val_real() { return (double) Item_func_udf_int::val_int(); }
1107
String *val_str(String *str);
1108
enum Item_result result_type () const { return INT_RESULT; }
1109
void fix_length_and_dec() { decimals= 0; max_length= 21; }
1113
class Item_func_udf_decimal :public Item_udf_func
1116
Item_func_udf_decimal(udf_func *udf_arg)
1117
:Item_udf_func(udf_arg) {}
1118
Item_func_udf_decimal(udf_func *udf_arg, List<Item> &list)
1119
:Item_udf_func(udf_arg, list) {}
1122
my_decimal *val_decimal(my_decimal *);
1123
String *val_str(String *str);
1124
enum Item_result result_type () const { return DECIMAL_RESULT; }
1125
void fix_length_and_dec();
1129
class Item_func_udf_str :public Item_udf_func
1132
Item_func_udf_str(udf_func *udf_arg)
1133
:Item_udf_func(udf_arg) {}
1134
Item_func_udf_str(udf_func *udf_arg, List<Item> &list)
1135
:Item_udf_func(udf_arg, list) {}
1136
String *val_str(String *);
1142
res= val_str(&str_value);
1143
return res ? my_strntod(res->charset(),(char*) res->ptr(),
1144
res->length(), &end_not_used, &err_not_used) : 0.0;
1149
String *res; res=val_str(&str_value);
1150
return res ? my_strntoll(res->charset(),res->ptr(),res->length(),10,
1151
(char**) 0, &err_not_used) : (int64_t) 0;
1153
my_decimal *val_decimal(my_decimal *dec_buf)
1155
String *res=val_str(&str_value);
1158
string2my_decimal(E_DEC_FATAL_ERROR, res, dec_buf);
1161
enum Item_result result_type () const { return STRING_RESULT; }
1162
void fix_length_and_dec();
995
1166
/* replication functions */
997
1168
class Item_master_pos_wait :public Item_int_func