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);
992
class Item_udf_func :public Item_func
996
bool is_expensive_processor(uchar *arg __attribute__((__unused__)))
1000
Item_udf_func(udf_func *udf_arg)
1001
:Item_func(), udf(udf_arg) {}
1002
Item_udf_func(udf_func *udf_arg, List<Item> &list)
1003
:Item_func(list), udf(udf_arg) {}
1004
const char *func_name() const { return udf.name(); }
1005
enum Functype functype() const { return UDF_FUNC; }
1006
bool fix_fields(THD *thd, Item **ref __attribute__((__unused__)))
1009
bool res= udf.fix_fields(thd, this, arg_count, args);
1010
used_tables_cache= udf.used_tables_cache;
1011
const_item_cache= udf.const_item_cache;
1015
void update_used_tables()
1018
TODO: Make a member in UDF_INIT and return if a UDF is deterministic or
1020
Currently UDF_INIT has a member (const_item) that is an in/out
1021
parameter to the init() call.
1022
The code in udf_handler::fix_fields also duplicates the arguments
1023
handling code in Item_func::fix_fields().
1025
The lack of information if a UDF is deterministic makes writing
1026
a correct update_used_tables() for UDFs impossible.
1027
One solution to this would be :
1028
- Add a is_deterministic member of UDF_INIT
1029
- (optionally) deprecate the const_item member of UDF_INIT
1030
- Take away the duplicate code from udf_handler::fix_fields() and
1031
make Item_udf_func call Item_func::fix_fields() to process its
1032
arguments as for any other function.
1033
- Store the deterministic flag returned by <udf>_init into the
1035
- Don't implement Item_udf_func::fix_fields, implement
1036
Item_udf_func::fix_length_and_dec() instead (similar to non-UDF
1038
- Override Item_func::update_used_tables to call
1039
Item_func::update_used_tables() and add a RAND_TABLE_BIT to the
1040
result of Item_func::update_used_tables() if the UDF is
1042
- (optionally) rename RAND_TABLE_BIT to NONDETERMINISTIC_BIT to
1043
better describe its usage.
1045
The above would require a change of the UDF API.
1046
Until that change is done here's how the current code works:
1047
We call Item_func::update_used_tables() only when we know that
1048
the function depends on real non-const tables and is deterministic.
1049
This can be done only because we know that the optimizer will
1050
call update_used_tables() only when there's possibly a new const
1051
table. So update_used_tables() can only make a Item_func more
1052
constant than it is currently.
1053
That's why we don't need to do anything if a function is guaranteed
1054
to return non-constant (it's non-deterministic) or is already a
1057
if ((used_tables_cache & ~PSEUDO_TABLE_BITS) &&
1058
!(used_tables_cache & RAND_TABLE_BIT))
1060
Item_func::update_used_tables();
1061
if (!const_item_cache && !used_tables_cache)
1062
used_tables_cache= RAND_TABLE_BIT;
1066
Item_result result_type () const { return udf.result_type(); }
1067
table_map not_null_tables() const { return 0; }
1068
virtual void print(String *str, enum_query_type query_type);
1072
class Item_func_udf_float :public Item_udf_func
1075
Item_func_udf_float(udf_func *udf_arg)
1076
:Item_udf_func(udf_arg) {}
1077
Item_func_udf_float(udf_func *udf_arg,
1079
:Item_udf_func(udf_arg, list) {}
1083
return (int64_t) rint(Item_func_udf_float::val_real());
1085
my_decimal *val_decimal(my_decimal *dec_buf)
1087
double res=val_real();
1090
double2my_decimal(E_DEC_FATAL_ERROR, res, dec_buf);
1094
String *val_str(String *str);
1095
void fix_length_and_dec() { fix_num_length_and_dec(); }
1099
class Item_func_udf_int :public Item_udf_func
1102
Item_func_udf_int(udf_func *udf_arg)
1103
:Item_udf_func(udf_arg) {}
1104
Item_func_udf_int(udf_func *udf_arg,
1106
:Item_udf_func(udf_arg, list) {}
1108
double val_real() { return (double) Item_func_udf_int::val_int(); }
1109
String *val_str(String *str);
1110
enum Item_result result_type () const { return INT_RESULT; }
1111
void fix_length_and_dec() { decimals= 0; max_length= 21; }
1115
class Item_func_udf_decimal :public Item_udf_func
1118
Item_func_udf_decimal(udf_func *udf_arg)
1119
:Item_udf_func(udf_arg) {}
1120
Item_func_udf_decimal(udf_func *udf_arg, List<Item> &list)
1121
:Item_udf_func(udf_arg, list) {}
1124
my_decimal *val_decimal(my_decimal *);
1125
String *val_str(String *str);
1126
enum Item_result result_type () const { return DECIMAL_RESULT; }
1127
void fix_length_and_dec();
1131
class Item_func_udf_str :public Item_udf_func
1134
Item_func_udf_str(udf_func *udf_arg)
1135
:Item_udf_func(udf_arg) {}
1136
Item_func_udf_str(udf_func *udf_arg, List<Item> &list)
1137
:Item_udf_func(udf_arg, list) {}
1138
String *val_str(String *);
1144
res= val_str(&str_value);
1145
return res ? my_strntod(res->charset(),(char*) res->ptr(),
1146
res->length(), &end_not_used, &err_not_used) : 0.0;
1151
String *res; res=val_str(&str_value);
1152
return res ? my_strntoll(res->charset(),res->ptr(),res->length(),10,
1153
(char**) 0, &err_not_used) : (int64_t) 0;
1155
my_decimal *val_decimal(my_decimal *dec_buf)
1157
String *res=val_str(&str_value);
1160
string2my_decimal(E_DEC_FATAL_ERROR, res, dec_buf);
1163
enum Item_result result_type () const { return STRING_RESULT; }
1164
void fix_length_and_dec();
1167
#else /* Dummy functions to get sql_yacc.cc compiled */
1169
class Item_func_udf_float :public Item_real_func
1172
Item_func_udf_float(udf_func *udf_arg)
1173
:Item_real_func() {}
1174
Item_func_udf_float(udf_func *udf_arg, List<Item> &list)
1175
:Item_real_func(list) {}
1176
double val_real() { assert(fixed == 1); return 0.0; }
1180
class Item_func_udf_int :public Item_int_func
1183
Item_func_udf_int(udf_func *udf_arg)
1185
Item_func_udf_int(udf_func *udf_arg, List<Item> &list)
1186
:Item_int_func(list) {}
1187
int64_t val_int() { assert(fixed == 1); return 0; }
1191
class Item_func_udf_decimal :public Item_int_func
1194
Item_func_udf_decimal(udf_func *udf_arg)
1196
Item_func_udf_decimal(udf_func *udf_arg, List<Item> &list)
1197
:Item_int_func(list) {}
1198
my_decimal *val_decimal(my_decimal *) { assert(fixed == 1); return 0; }
1202
class Item_func_udf_str :public Item_func
1205
Item_func_udf_str(udf_func *udf_arg)
1207
Item_func_udf_str(udf_func *udf_arg, List<Item> &list)
1209
String *val_str(String *)
1210
{ assert(fixed == 1); null_value=1; return 0; }
1211
double val_real() { assert(fixed == 1); null_value= 1; return 0.0; }
1212
int64_t val_int() { assert(fixed == 1); null_value=1; return 0; }
1213
enum Item_result result_type () const { return STRING_RESULT; }
1214
void fix_length_and_dec() { maybe_null=1; max_length=0; }
1217
#endif /* HAVE_DLOPEN */
995
1219
/* replication functions */
997
1221
class Item_master_pos_wait :public Item_int_func