mariadb/sql/sql_udf.h
Monty 5a759d31f7 Changing field::field_name and Item::name to LEX_CSTRING
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)
2017-04-23 22:35:46 +03:00

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 */