114 #include <my_global.h>
121 #if defined(MYSQL_SERVER)
122 #include <m_string.h>
126 #define strmov(a,b) stpcpy(a,b)
134 #pragma comment(lib, "ws2_32")
139 #if !defined(HAVE_GETHOSTBYADDR_R) || !defined(HAVE_SOLARIS_STYLE_GETHOST)
140 static pthread_mutex_t LOCK_hostname;
147 void metaphon_deinit(
UDF_INIT *initid);
149 unsigned long *length,
char *is_null,
char *error);
157 void sequence_deinit(
UDF_INIT *initid);
161 void avgcost_deinit(
UDF_INIT* initid );
162 void avgcost_reset(
UDF_INIT* initid,
UDF_ARGS* args,
char* is_null,
char *error );
163 void avgcost_clear(
UDF_INIT* initid,
char* is_null,
char *error );
164 void avgcost_add(
UDF_INIT* initid,
UDF_ARGS* args,
char* is_null,
char *error );
165 double avgcost(
UDF_INIT* initid,
UDF_ARGS* args,
char* is_null,
char *error );
167 char *is_const(
UDF_INIT *initid,
UDF_ARGS *args,
char *result,
unsigned long
168 *length,
char *is_null,
char *error);
213 if (args->arg_count != 1 || args->arg_type[0] != STRING_RESULT)
215 strcpy(message,
"Wrong arguments to metaphon; Use the source");
218 initid->max_length=MAXMETAPH;
230 void metaphon_deinit(
UDF_INIT *initid __attribute__((unused)))
254 static char codes[26] = {
255 1,16,4,16,9,2,4,16,9,2,0,2,2,2,1,4,0,2,4,4,1,0,0,0,8,0
261 #define ISVOWEL(x) (codes[(x) - 'A'] & 1)
264 #define NOCHANGE(x) (codes[(x) - 'A'] & 2)
267 #define AFFECTH(x) (codes[(x) - 'A'] & 4)
270 #define MAKESOFT(x) (codes[(x) - 'A'] & 8)
273 #define NOGHTOF(x) (codes[(x) - 'A'] & 16)
276 char *metaphon(
UDF_INIT *initid __attribute__((unused)),
277 UDF_ARGS *args,
char *result,
unsigned long *length,
278 char *is_null,
char *error __attribute__((unused)))
280 const char *
word=args->args[0];
283 char *
n, *n_start, *n_end;
293 w_end=word+args->lengths[0];
301 for (n = ntrans + 1, n_end = ntrans +
sizeof(ntrans)-2;
302 word != w_end && n < n_end; word++ )
303 if ( isalpha ( *word ))
304 *n++ = toupper ( *word );
306 if ( n == ntrans + 1 )
336 if ( *(n + 1) ==
'H')
354 for (metaph_end = result + MAXMETAPH, n_start = n;
355 n < n_end && result < metaph_end; n++ )
366 if ( *( n - 1 ) == *n && *n !=
'C' )
370 if ( NOCHANGE ( *n ) ||
371 ( n == n_start && ISVOWEL ( *n )))
376 if ( n < n_end || *( n - 1 ) !=
'M' )
384 if ( *( n - 1 ) !=
'S' ||
387 if ( n[1] ==
'I' && n[2] ==
'A' )
390 if ( MAKESOFT ( n[1]))
394 *result++ = (( n == n_start &&
396 *( n - 1 ) ==
'S' ) ?
397 (
char)
'K' : (char)
'X';
407 (
char)
'J' : (char)
'T';
411 if (( n[1] !=
'H' || ISVOWEL ( n[2]))
428 ( MAKESOFT ( *( n + 1 )) &&
430 (
char)
'J' : (char)
'K';
433 !NOGHTOF( *( n - 3 )) &&
441 if ( !AFFECTH ( *( n - 1 )) &&
442 ( !ISVOWEL ( *( n - 1 )) ||
448 if ( *( n - 1 ) !=
'C')
453 *result++ = *( n + 1 ) ==
'H'
454 ? (
char)
'F' : (char)
'P';
461 *result++ = ( n[1] ==
'H' ||
465 (char)
'X' : (
char)
'S';
470 if ( *( n + 1 ) ==
'I' && ( n[2] ==
'O'
477 if ( *( n + 1) !=
'C' || n[2] !=
'H')
487 if ( ISVOWEL ( n[1]))
508 *length= (
unsigned long) (result - org_result);
532 if (!args->arg_count)
534 strcpy(message,
"myfunc_double must have at least one argument");
541 for (i=0 ; i < args->arg_count; i++)
542 args->arg_type[i]=STRING_RESULT;
543 initid->maybe_null=1;
545 initid->max_length=6;
550 double myfunc_double(
UDF_INIT *initid __attribute__((unused)),
UDF_ARGS *args,
551 char *is_null,
char *error __attribute__((unused)))
553 unsigned long val = 0;
557 for (i = 0; i < args->arg_count; i++)
559 if (args->args[i] == NULL)
561 val += args->lengths[
i];
562 for (j=args->lengths[i] ; j-- > 0 ;)
563 v += args->args[
i][j];
566 return (
double) v/ (double) val;
589 longlong myfunc_int(
UDF_INIT *initid __attribute__((unused)),
UDF_ARGS *args,
590 char *is_null __attribute__((unused)),
591 char *error __attribute__((unused)))
596 for (i = 0; i < args->arg_count; i++)
598 if (args->args[i] == NULL)
600 switch (args->arg_type[i]) {
602 val += args->lengths[
i];
605 val += *((longlong*) args->args[i]);
608 val += (longlong) *((
double*) args->args[
i]);
621 my_bool myfunc_int_init(
UDF_INIT *initid __attribute__((unused)),
622 UDF_ARGS *args __attribute__((unused)),
623 char *message __attribute__((unused)))
635 if (args->arg_count > 1)
637 strmov(message,
"This function takes none or 1 argument");
641 args->arg_type[0]= INT_RESULT;
643 if (!(initid->ptr=(
char*) malloc(
sizeof(longlong))))
645 strmov(message,
"Couldn't allocate memory");
648 memset(initid->ptr, 0,
sizeof(longlong));
653 initid->const_item=0;
657 void sequence_deinit(
UDF_INIT *initid)
664 char *is_null __attribute__((unused)),
665 char *error __attribute__((unused)))
669 val= *((longlong*) args->args[0]);
670 return ++*((longlong*) initid->ptr) + val;
684 #include <winsock2.h>
686 #include <sys/socket.h>
687 #include <netinet/in.h>
688 #include <arpa/inet.h>
694 void lookup_deinit(
UDF_INIT *initid);
696 unsigned long *length,
char *null_value,
char *error);
697 my_bool reverse_lookup_init(
UDF_INIT *initid,
UDF_ARGS *args,
char *message);
698 void reverse_lookup_deinit(
UDF_INIT *initid);
700 unsigned long *length,
char *null_value,
char *error);
714 if (args->arg_count != 1 || args->arg_type[0] != STRING_RESULT)
716 strmov(message,
"Wrong arguments to lookup; Use the source");
719 initid->max_length=11;
720 initid->maybe_null=1;
721 #if !defined(HAVE_GETHOSTBYADDR_R) || !defined(HAVE_SOLARIS_STYLE_GETHOST)
722 (void) pthread_mutex_init(&LOCK_hostname,MY_MUTEX_INIT_SLOW);
727 void lookup_deinit(
UDF_INIT *initid __attribute__((unused)))
729 #if !defined(HAVE_GETHOSTBYADDR_R) || !defined(HAVE_SOLARIS_STYLE_GETHOST)
730 (void) pthread_mutex_destroy(&LOCK_hostname);
735 char *result,
unsigned long *res_length,
char *null_value,
736 char *error __attribute__((unused)))
740 struct hostent *hostent;
741 #if defined(HAVE_GETHOSTBYADDR_R) && defined(HAVE_SOLARIS_STYLE_GETHOST)
743 char hostname_buff[2048];
744 struct hostent tmp_hostent;
748 if (!args->args[0] || !(length=args->lengths[0]))
753 if (length >=
sizeof(name_buff))
754 length=
sizeof(name_buff)-1;
755 memcpy(name_buff,args->args[0],length);
757 #if defined(HAVE_GETHOSTBYADDR_R) && defined(HAVE_SOLARIS_STYLE_GETHOST)
758 if (!(hostent=gethostbyname_r(name_buff,&tmp_hostent,hostname_buff,
759 sizeof(hostname_buff), &tmp_errno)))
765 pthread_mutex_lock(&LOCK_hostname);
766 if (!(hostent= gethostbyname((
char*) name_buff)))
768 pthread_mutex_unlock(&LOCK_hostname);
772 pthread_mutex_unlock(&LOCK_hostname);
774 memcpy(&in, *hostent->h_addr_list,
sizeof(in.s_addr));
775 *res_length= (ulong) (strmov(result, inet_ntoa(in)) - result);
786 my_bool reverse_lookup_init(
UDF_INIT *initid,
UDF_ARGS *args,
char *message)
788 if (args->arg_count == 1)
789 args->arg_type[0]= STRING_RESULT;
790 else if (args->arg_count == 4)
791 args->arg_type[0]=args->arg_type[1]=args->arg_type[2]=args->arg_type[3]=
796 "Wrong number of arguments to reverse_lookup; Use the source");
799 initid->max_length=32;
800 initid->maybe_null=1;
801 #if !defined(HAVE_GETHOSTBYADDR_R) || !defined(HAVE_SOLARIS_STYLE_GETHOST)
802 (void) pthread_mutex_init(&LOCK_hostname,MY_MUTEX_INIT_SLOW);
807 void reverse_lookup_deinit(
UDF_INIT *initid __attribute__((unused)))
809 #if !defined(HAVE_GETHOSTBYADDR_R) || !defined(HAVE_SOLARIS_STYLE_GETHOST)
810 (void) pthread_mutex_destroy(&LOCK_hostname);
814 char *reverse_lookup(
UDF_INIT *initid __attribute__((unused)),
UDF_ARGS *args,
815 char *result,
unsigned long *res_length,
816 char *null_value,
char *error __attribute__((unused)))
818 #if defined(HAVE_GETHOSTBYADDR_R) && defined(HAVE_SOLARIS_STYLE_GETHOST)
820 struct hostent tmp_hostent;
827 if (args->arg_count == 4)
829 if (!args->args[0] || !args->args[1] ||!args->args[2] ||!args->args[3])
834 sprintf(result,
"%d.%d.%d.%d",
835 (
int) *((longlong*) args->args[0]),
836 (
int) *((longlong*) args->args[1]),
837 (
int) *((longlong*) args->args[2]),
838 (
int) *((longlong*) args->args[3]));
847 length=args->lengths[0];
848 if (length >= (uint) *res_length-1)
849 length=(uint) *res_length;
850 memcpy(result,args->args[0],length);
854 taddr = inet_addr(result);
855 if (taddr == (
unsigned long) -1L)
860 #if defined(HAVE_GETHOSTBYADDR_R) && defined(HAVE_SOLARIS_STYLE_GETHOST)
861 if (!(hp=gethostbyaddr_r((
char*) &taddr,
sizeof(taddr), AF_INET,
862 &tmp_hostent, name_buff,
sizeof(name_buff),
869 pthread_mutex_lock(&LOCK_hostname);
870 if (!(hp= gethostbyaddr((
char*) &taddr,
sizeof(taddr), AF_INET)))
872 pthread_mutex_unlock(&LOCK_hostname);
876 pthread_mutex_unlock(&LOCK_hostname);
878 *res_length=(ulong) (strmov(result,hp->h_name) - result);
896 longlong totalquantity;
907 struct avgcost_data* data;
909 if (args->arg_count != 2)
913 "wrong number of arguments: AVGCOST() requires two arguments"
918 if ((args->arg_type[0] != INT_RESULT) || (args->arg_type[1] != REAL_RESULT) )
922 "wrong argument type: AVGCOST() requires an INT and a REAL"
933 initid->maybe_null = 0;
934 initid->decimals = 4;
935 initid->max_length = 20;
937 if (!(data =
new (std::nothrow) avgcost_data))
939 strmov(message,
"Couldn't allocate memory");
942 data->totalquantity = 0;
943 data->totalprice = 0.0;
945 initid->ptr = (
char*)data;
953 void *void_ptr= initid->ptr;
954 avgcost_data *data=
static_cast<avgcost_data*
>(void_ptr);
961 avgcost_reset(
UDF_INIT* initid,
UDF_ARGS* args,
char* is_null,
char* message)
963 avgcost_clear(initid, is_null, message);
964 avgcost_add(initid, args, is_null, message);
970 avgcost_clear(
UDF_INIT* initid,
char* is_null __attribute__((unused)),
971 char* message __attribute__((unused)))
973 struct avgcost_data* data = (
struct avgcost_data*)initid->ptr;
974 data->totalprice= 0.0;
975 data->totalquantity= 0;
982 char* is_null __attribute__((unused)),
983 char* message __attribute__((unused)))
985 if (args->args[0] && args->args[1])
987 struct avgcost_data* data = (
struct avgcost_data*)initid->ptr;
988 longlong quantity = *((longlong*)args->args[0]);
989 longlong newquantity = data->totalquantity + quantity;
990 double price = *((
double*)args->args[1]);
994 if ( ((data->totalquantity >= 0) && (quantity < 0))
995 || ((data->totalquantity < 0) && (quantity > 0)) )
1000 if ( ((quantity < 0) && (newquantity < 0))
1001 || ((quantity > 0) && (newquantity > 0)) )
1003 data->totalprice = price * (double)newquantity;
1011 price = data->totalprice / (double)data->totalquantity;
1012 data->totalprice = price * (
double)newquantity;
1014 data->totalquantity = newquantity;
1018 data->totalquantity += quantity;
1019 data->totalprice += price * (double)quantity;
1022 if (data->totalquantity == 0)
1023 data->totalprice = 0.0;
1030 char* is_null,
char* error __attribute__((unused)))
1032 struct avgcost_data* data = (
struct avgcost_data*)initid->ptr;
1033 if (!data->count || !data->totalquantity)
1040 return data->totalprice/(double)data->totalquantity;
1046 unsigned long *length,
char *null_value,
1052 if (args->arg_count != 1)
1054 strmov(message,
"myfunc_argument_name_init accepts only one argument");
1057 initid->max_length= args->attribute_lengths[0];
1058 initid->maybe_null= 1;
1059 initid->const_item= 1;
1063 char *myfunc_argument_name(
UDF_INIT *initid __attribute__((unused)),
1065 unsigned long *length,
char *null_value,
1066 char *error __attribute__((unused)))
1068 if (!args->attributes[0])
1074 if (*length > args->attribute_lengths[0])
1075 *length= args->attribute_lengths[0];
1076 memcpy(result, args->attributes[0], *length);
1085 if (args->arg_count != 1)
1087 strmov(message,
"IS_CONST accepts only one argument");
1090 initid->ptr= (
char*)((args->args[0] != NULL) ? 1UL : 0);
1095 char *result,
unsigned long *length,
1096 char *is_null,
char *error __attribute__((unused)))
1098 if (initid->ptr != 0) {
1099 sprintf(result,
"const");
1101 sprintf(result,
"not const");
1104 *length= (uint) strlen(result);
1111 my_bool check_const_len_init(
UDF_INIT *initid,
UDF_ARGS *args,
char *message)
1113 if (args->arg_count != 1)
1115 strmov(message,
"CHECK_CONST_LEN accepts only one argument");
1118 if (args->args[0] == 0)
1120 initid->ptr= (
char*)
"Not constant";
1122 else if(strlen(args->args[0]) == args->lengths[0])
1124 initid->ptr= (
char*)
"Correct length";
1128 initid->ptr= (
char*)
"Wrong length";
1130 initid->max_length = 100;
1135 char * check_const_len(
UDF_INIT *initid,
UDF_ARGS *args __attribute__((unused)),
1136 char *result,
unsigned long *length,
1137 char *is_null,
char *error __attribute__((unused)))
1139 strmov(result, initid->ptr);
1140 *length= (uint) strlen(result);
1148 void my_median_deinit(
UDF_INIT* initid);
1150 char* is_null,
char *error);
1152 char* is_null,
char *error);
1154 char* is_null,
char *error);
1157 struct My_median_data
1159 std::vector<longlong> vec;
1165 My_median_data *data=
new (std::nothrow) My_median_data;
1168 strmov(message,
"Could not allocate memory");
1171 initid->ptr=
static_cast<char*
>(
static_cast<void*
>(data));
1175 void my_median_deinit(
UDF_INIT* initid)
1177 My_median_data *data=
1178 static_cast<My_median_data*
>(
static_cast<void*
>(initid->ptr));
1183 char* is_null __attribute__((unused)),
1184 char* message __attribute__((unused)))
1186 My_median_data *data=
1187 static_cast<My_median_data*
>(
static_cast<void*
>(initid->ptr));
1190 void *arg0= args->args[0];
1191 longlong number= *(
static_cast<longlong*
>(arg0));
1192 data->vec.push_back(number);
1197 char* is_null __attribute__((unused)),
1198 char* message __attribute__((unused)))
1200 My_median_data *data=
1201 static_cast<My_median_data*
>(
static_cast<void*
>(initid->ptr));
1207 char* message __attribute__((unused)))
1209 My_median_data *data=
1210 static_cast<My_median_data*
>(
static_cast<void*
>(initid->ptr));
1211 if (data->vec.size() == 0)
1216 const size_t ix= data->vec.size() / 2;
1217 std::nth_element(data->vec.begin(), data->vec.begin() + ix, data->vec.end());
1218 return data->vec[ix];