diff options
Diffstat (limited to 'sql/sql_udf.h')
-rw-r--r-- | sql/sql_udf.h | 169 |
1 files changed, 169 insertions, 0 deletions
diff --git a/sql/sql_udf.h b/sql/sql_udf.h new file mode 100644 index 00000000..cb195435 --- /dev/null +++ b/sql/sql_udf.h @@ -0,0 +1,169 @@ +#ifndef SQL_UDF_INCLUDED +#define SQL_UDF_INCLUDED + +/* Copyright (c) 2000, 2003-2007 MySQL AB, 2009 Sun Microsystems, Inc. + Use is subject to license terms. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; version 2 of the License. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1335 USA */ + + +/* This file defines structures needed by udf functions */ + +#ifdef USE_PRAGMA_INTERFACE +#pragma interface +#endif + +enum Item_udftype {UDFTYPE_FUNCTION=1,UDFTYPE_AGGREGATE}; + +typedef void (*Udf_func_clear)(UDF_INIT *, uchar *, uchar *); +typedef void (*Udf_func_add)(UDF_INIT *, UDF_ARGS *, uchar *, uchar *); +typedef void (*Udf_func_deinit)(UDF_INIT*); +typedef my_bool (*Udf_func_init)(UDF_INIT *, UDF_ARGS *, char *); +typedef void (*Udf_func_any)(); +typedef double (*Udf_func_double)(UDF_INIT *, UDF_ARGS *, uchar *, uchar *); +typedef longlong (*Udf_func_longlong)(UDF_INIT *, UDF_ARGS *, uchar *, + uchar *); + +typedef struct st_udf_func +{ + LEX_CSTRING name; + Item_result returns; + Item_udftype type; + const char *dl; + void *dlhandle; + Udf_func_any func; + Udf_func_init func_init; + Udf_func_deinit func_deinit; + Udf_func_clear func_clear; + Udf_func_add func_add; + Udf_func_add func_remove; + ulong usage_count; +} udf_func; + +class Item_result_field; + +class udf_handler :public Sql_alloc +{ + protected: + udf_func *u_d; + String *buffers; + UDF_ARGS f_args; + UDF_INIT initid; + char *num_buffer; + uchar error, is_null; + bool initialized; + Item **args; + + public: + bool not_original; + udf_handler(udf_func *udf_arg) :u_d(udf_arg), buffers(0), error(0), + is_null(0), initialized(0), not_original(0) + {} + ~udf_handler(); + const char *name() const { return u_d ? u_d->name.str : "?"; } + Item_result result_type () const + { return u_d ? u_d->returns : STRING_RESULT;} + bool get_arguments(); + bool fix_fields(THD *thd, Item_func_or_sum *item, + uint arg_count, Item **args); + void cleanup(); + double val(my_bool *null_value) + { + is_null= 0; + if (get_arguments()) + { + *null_value=1; + return 0.0; + } + Udf_func_double func= (Udf_func_double) u_d->func; + double tmp=func(&initid, &f_args, &is_null, &error); + if (is_null || error) + { + *null_value=1; + return 0.0; + } + *null_value=0; + return tmp; + } + longlong val_int(my_bool *null_value) + { + is_null= 0; + if (get_arguments()) + { + *null_value=1; + return 0; + } + Udf_func_longlong func= (Udf_func_longlong) u_d->func; + longlong tmp=func(&initid, &f_args, &is_null, &error); + if (is_null || error) + { + *null_value=1; + return 0; + } + *null_value=0; + return tmp; + } + my_decimal *val_decimal(my_bool *null_value, my_decimal *dec_buf); + void clear() + { + is_null= 0; + Udf_func_clear func= u_d->func_clear; + func(&initid, &is_null, &error); + } + void add(my_bool *null_value) + { + if (get_arguments()) + { + *null_value=1; + return; + } + Udf_func_add func= u_d->func_add; + func(&initid, &f_args, &is_null, &error); + *null_value= (my_bool) (is_null || error); + } + bool supports_removal() const + { return MY_TEST(u_d->func_remove); } + void remove(my_bool *null_value) + { + DBUG_ASSERT(u_d->func_remove); + if (get_arguments()) + { + *null_value=1; + return; + } + Udf_func_add func= u_d->func_remove; + func(&initid, &f_args, &is_null, &error); + *null_value= (my_bool) (is_null || error); + } + String *val_str(String *str,String *save_str); +}; + + +#ifdef HAVE_DLOPEN +void udf_init(void),udf_free(void); +udf_func *find_udf(const char *name, size_t size, bool mark_used=0); +void free_udf(udf_func *udf); +int mysql_create_function(THD *thd,udf_func *udf); +enum drop_udf_result +{ + UDF_DEL_RESULT_ABSENT, + UDF_DEL_RESULT_DELETED, + UDF_DEL_RESULT_ERROR +}; +enum drop_udf_result mysql_drop_function(THD *thd, const LEX_CSTRING *name); +#else +static inline void udf_init(void) { } +static inline void udf_free(void) { } +#endif +#endif /* SQL_UDF_INCLUDED */ |