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-1301 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 | ulong usage_count; |
51 | } udf_func; |
52 | |
53 | class Item_result_field; |
54 | |
55 | class udf_handler :public Sql_alloc |
56 | { |
57 | protected: |
58 | udf_func *u_d; |
59 | String *buffers; |
60 | UDF_ARGS f_args; |
61 | UDF_INIT initid; |
62 | char *num_buffer; |
63 | uchar error, is_null; |
64 | bool initialized; |
65 | Item **args; |
66 | |
67 | public: |
68 | bool not_original; |
69 | udf_handler(udf_func *udf_arg) :u_d(udf_arg), buffers(0), error(0), |
70 | is_null(0), initialized(0), not_original(0) |
71 | {} |
72 | ~udf_handler(); |
73 | const char *name() const { return u_d ? u_d->name.str : "?" ; } |
74 | Item_result result_type () const |
75 | { return u_d ? u_d->returns : STRING_RESULT;} |
76 | bool get_arguments(); |
77 | bool fix_fields(THD *thd, Item_func_or_sum *item, |
78 | uint arg_count, Item **args); |
79 | void cleanup(); |
80 | double val(my_bool *null_value) |
81 | { |
82 | is_null= 0; |
83 | if (get_arguments()) |
84 | { |
85 | *null_value=1; |
86 | return 0.0; |
87 | } |
88 | Udf_func_double func= (Udf_func_double) u_d->func; |
89 | double tmp=func(&initid, &f_args, &is_null, &error); |
90 | if (is_null || error) |
91 | { |
92 | *null_value=1; |
93 | return 0.0; |
94 | } |
95 | *null_value=0; |
96 | return tmp; |
97 | } |
98 | longlong val_int(my_bool *null_value) |
99 | { |
100 | is_null= 0; |
101 | if (get_arguments()) |
102 | { |
103 | *null_value=1; |
104 | return 0; |
105 | } |
106 | Udf_func_longlong func= (Udf_func_longlong) u_d->func; |
107 | longlong tmp=func(&initid, &f_args, &is_null, &error); |
108 | if (is_null || error) |
109 | { |
110 | *null_value=1; |
111 | return 0; |
112 | } |
113 | *null_value=0; |
114 | return tmp; |
115 | } |
116 | my_decimal *val_decimal(my_bool *null_value, my_decimal *dec_buf); |
117 | void clear() |
118 | { |
119 | is_null= 0; |
120 | Udf_func_clear func= u_d->func_clear; |
121 | func(&initid, &is_null, &error); |
122 | } |
123 | void add(my_bool *null_value) |
124 | { |
125 | if (get_arguments()) |
126 | { |
127 | *null_value=1; |
128 | return; |
129 | } |
130 | Udf_func_add func= u_d->func_add; |
131 | func(&initid, &f_args, &is_null, &error); |
132 | *null_value= (my_bool) (is_null || error); |
133 | } |
134 | String *val_str(String *str,String *save_str); |
135 | }; |
136 | |
137 | |
138 | #ifdef HAVE_DLOPEN |
139 | void udf_init(void),udf_free(void); |
140 | udf_func *find_udf(const char *name, size_t size, bool mark_used=0); |
141 | void free_udf(udf_func *udf); |
142 | int mysql_create_function(THD *thd,udf_func *udf); |
143 | int mysql_drop_function(THD *thd, const LEX_CSTRING *name); |
144 | #else |
145 | static inline void udf_init(void) { } |
146 | static inline void udf_free(void) { } |
147 | #endif |
148 | #endif /* SQL_UDF_INCLUDED */ |
149 | |