mirror of
https://github.com/MariaDB/server.git
synced 2025-01-16 12:02:42 +01:00
5a759d31f7
Benefits of this patch: - Removed a lot of calls to strlen(), especially for field_string - Strings generated by parser are now const strings, less chance of accidently changing a string - Removed a lot of calls with LEX_STRING as parameter (changed to pointer) - More uniform code - Item::name_length was not kept up to date. Now fixed - Several bugs found and fixed (Access to null pointers, access of freed memory, wrong arguments to printf like functions) - Removed a lot of casts from (const char*) to (char*) Changes: - This caused some ABI changes - lex_string_set now uses LEX_CSTRING - Some fucntions are now taking const char* instead of char* - Create_field::change and after changed to LEX_CSTRING - handler::connect_string, comment and engine_name() changed to LEX_CSTRING - Checked printf() related calls to find bugs. Found and fixed several errors in old code. - A lot of changes from LEX_STRING to LEX_CSTRING, especially related to parsing and events. - Some changes from LEX_STRING and LEX_STRING & to LEX_CSTRING* - Some changes for char* to const char* - Added printf argument checking for my_snprintf() - Introduced null_clex_str, star_clex_string, temp_lex_str to simplify code - Added item_empty_name and item_used_name to be able to distingush between items that was given an empty name and items that was not given a name This is used in sql_yacc.yy to know when to give an item a name. - select table_name."*' is not anymore same as table_name.* - removed not used function Item::rename() - Added comparision of item->name_length before some calls to my_strcasecmp() to speed up comparison - Moved Item_sp_variable::make_field() from item.h to item.cc - Some minimal code changes to avoid copying to const char * - Fixed wrong error message in wsrep_mysql_parse() - Fixed wrong code in find_field_in_natural_join() where real_item() was set when it shouldn't - ER_ERROR_ON_RENAME was used with extra arguments. - Removed some (wrong) ER_OUTOFMEMORY, as alloc_root will already give the error. TODO: - Check possible unsafe casts in plugin/auth_examples/qa_auth_interface.c - Change code to not modify LEX_CSTRING for database name (as part of lower_case_table_names)
148 lines
3.9 KiB
C++
148 lines
3.9 KiB
C++
#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-1301 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;
|
|
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);
|
|
}
|
|
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, uint len, bool mark_used=0);
|
|
void free_udf(udf_func *udf);
|
|
int mysql_create_function(THD *thd,udf_func *udf);
|
|
int 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 */
|