1 #ifndef SQL_UDF_INCLUDED
2 #define SQL_UDF_INCLUDED
3 
4 /* Copyright (c) 2000, 2003-2007 MySQL AB, 2009 Sun Microsystems, Inc.
5    Use is subject to license terms.
6 
7    This program is free software; you can redistribute it and/or modify
8    it under the terms of the GNU General Public License as published by
9    the Free Software Foundation; version 2 of the License.
10 
11    This program is distributed in the hope that it will be useful,
12    but WITHOUT ANY WARRANTY; without even the implied warranty of
13    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14    GNU General Public License for more details.
15 
16    You should have received a copy of the GNU General Public License
17    along with this program; if not, write to the Free Software
18    Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1335  USA */
19 
20 
21 /* This file defines structures needed by udf functions */
22 
23 #ifdef USE_PRAGMA_INTERFACE
24 #pragma interface
25 #endif
26 
27 enum Item_udftype {UDFTYPE_FUNCTION=1,UDFTYPE_AGGREGATE};
28 
29 typedef void (*Udf_func_clear)(UDF_INIT *, uchar *, uchar *);
30 typedef void (*Udf_func_add)(UDF_INIT *, UDF_ARGS *, uchar *, uchar *);
31 typedef void (*Udf_func_deinit)(UDF_INIT*);
32 typedef my_bool (*Udf_func_init)(UDF_INIT *, UDF_ARGS *,  char *);
33 typedef void (*Udf_func_any)();
34 typedef double (*Udf_func_double)(UDF_INIT *, UDF_ARGS *, uchar *, uchar *);
35 typedef longlong (*Udf_func_longlong)(UDF_INIT *, UDF_ARGS *, uchar *,
36                                       uchar *);
37 
38 typedef struct st_udf_func
39 {
40   LEX_CSTRING name;
41   Item_result returns;
42   Item_udftype type;
43   const char *dl;
44   void *dlhandle;
45   Udf_func_any func;
46   Udf_func_init func_init;
47   Udf_func_deinit func_deinit;
48   Udf_func_clear func_clear;
49   Udf_func_add func_add;
50   Udf_func_add func_remove;
51   ulong usage_count;
52 } udf_func;
53 
54 class Item_result_field;
55 
56 class udf_handler :public Sql_alloc
57 {
58  protected:
59   udf_func *u_d;
60   String *buffers;
61   UDF_ARGS f_args;
62   UDF_INIT initid;
63   char *num_buffer;
64   uchar error, is_null;
65   bool initialized;
66   Item **args;
67 
68  public:
69   bool not_original;
udf_handler(udf_func * udf_arg)70   udf_handler(udf_func *udf_arg) :u_d(udf_arg), buffers(0), error(0),
71     is_null(0), initialized(0), not_original(0)
72   {}
73   ~udf_handler();
name()74   const char *name() const { return u_d ? u_d->name.str : "?"; }
result_type()75   Item_result result_type () const
76   { return u_d	? u_d->returns : STRING_RESULT;}
77   bool get_arguments();
78   bool fix_fields(THD *thd, Item_func_or_sum *item,
79 		  uint arg_count, Item **args);
80   void cleanup();
val(my_bool * null_value)81   double val(my_bool *null_value)
82   {
83     is_null= 0;
84     if (get_arguments())
85     {
86       *null_value=1;
87       return 0.0;
88     }
89     Udf_func_double func= (Udf_func_double) u_d->func;
90     double tmp=func(&initid, &f_args, &is_null, &error);
91     if (is_null || error)
92     {
93       *null_value=1;
94       return 0.0;
95     }
96     *null_value=0;
97     return tmp;
98   }
val_int(my_bool * null_value)99   longlong val_int(my_bool *null_value)
100   {
101     is_null= 0;
102     if (get_arguments())
103     {
104       *null_value=1;
105       return 0;
106     }
107     Udf_func_longlong func= (Udf_func_longlong) u_d->func;
108     longlong tmp=func(&initid, &f_args, &is_null, &error);
109     if (is_null || error)
110     {
111       *null_value=1;
112       return 0;
113     }
114     *null_value=0;
115     return tmp;
116   }
117   my_decimal *val_decimal(my_bool *null_value, my_decimal *dec_buf);
clear()118   void clear()
119   {
120     is_null= 0;
121     Udf_func_clear func= u_d->func_clear;
122     func(&initid, &is_null, &error);
123   }
add(my_bool * null_value)124   void add(my_bool *null_value)
125   {
126     if (get_arguments())
127     {
128       *null_value=1;
129       return;
130     }
131     Udf_func_add func= u_d->func_add;
132     func(&initid, &f_args, &is_null, &error);
133     *null_value= (my_bool) (is_null || error);
134   }
supports_removal()135   bool supports_removal() const
136   { return MY_TEST(u_d->func_remove); }
remove(my_bool * null_value)137   void remove(my_bool *null_value)
138   {
139     DBUG_ASSERT(u_d->func_remove);
140     if (get_arguments())
141     {
142       *null_value=1;
143       return;
144     }
145     Udf_func_add func= u_d->func_remove;
146     func(&initid, &f_args, &is_null, &error);
147     *null_value= (my_bool) (is_null || error);
148   }
149   String *val_str(String *str,String *save_str);
150 };
151 
152 
153 #ifdef HAVE_DLOPEN
154 void udf_init(void),udf_free(void);
155 udf_func *find_udf(const char *name, size_t size, bool mark_used=0);
156 void free_udf(udf_func *udf);
157 int mysql_create_function(THD *thd,udf_func *udf);
158 enum drop_udf_result
159 {
160   UDF_DEL_RESULT_ABSENT,
161   UDF_DEL_RESULT_DELETED,
162   UDF_DEL_RESULT_ERROR
163 };
164 enum drop_udf_result mysql_drop_function(THD *thd, const LEX_CSTRING *name);
165 #else
udf_init(void)166 static inline void udf_init(void) { }
udf_free(void)167 static inline void udf_free(void) { }
168 #endif
169 #endif /* SQL_UDF_INCLUDED */
170