前提,大整数保存为varchar, char暂时还不行,还需改进
bigint.h头文件
#include
#include
#include
#define N 4
#ifdef __cplusplus
extern "C"{
#endif
typedef structbigint_node
{
intvalue; // four bitsbetween 0000 and 9999
structbigint_node *preview;
structbigint_node *next;
}*BigInt_Node;
typedef structbigint_list
{
BigInt_Nodefirst;
intcount; // the length ofBigInt_Node
//intflag; // the sign flag, 0represent plus, 1 represent minus.--Have not considered it at present.
}*BigInt_List;
BigInt_Listbigint_init();
BigInt_Listbigint_mov(BigInt_List b);
BigInt_Listbigint_mov_value(int value);
BigInt_Liststring_to_list(char *s);
char*list_to_string(BigInt_List list);
BigInt_Listbigint_add(BigInt_List a, BigInt_List b);
#ifdef __cplusplus
}
#endif
bigint.c源代码
#include"bigint.h"
/*
bigintinitialization
*/
BigInt_Listbigint_init()
{
BigInt_Listlist=(BigInt_List)(malloc(sizeof(struct bigint_list)));
list->first= NULL;
list->count= 0;
//list->flag= 0;
returnlist;
}
/*
a=b;
*/
BigInt_Listbigint_mov(BigInt_List b)
{
BigInt_Lista=bigint_init();
BigInt_Nodenode = b->first;
inti;
for(i = 0; i < b->count; i++)
{
BigInt_Nodetemp = (BigInt_Node)malloc(sizeof(struct bigint_node));
temp->value= node->value;
if(a->first == NULL)
{
a->first= temp;
temp->preview= temp;
temp->next= temp;
}
else
{
BigInt_Nodelast = a->first->preview;
last->next= temp;
temp->preview= last;
temp->next= a->first;
a->first->preview= temp;
}
node= node->next;
}
a->count=b->count;
returna;
}
/*
mova value to list
*/
BigInt_Listbigint_mov_value(int value)
{
BigInt_Listlist=bigint_init();
BigInt_Nodenode = (BigInt_Node)malloc(sizeof(struct bigint_node));
node->value= value;
node->preview= node;
node->next= node;
list->count= 1;
list->first= node;
returnlist;
}
/*
* input: char *s
* output: BigInt_List
*/
BigInt_Liststring_to_list(char *s)
{
BigInt_Listlist=bigint_init();
inti,k=N-1,len=strlen(s);
charstr[N+1];
for(i=len-1;i>=-1;i--)
{
if(k==-1)
{
BigInt_Nodenode=(BigInt_Node)malloc(sizeof(struct bigint_node));
node->value=atoi(str);
if(list->first==NULL)
{
list->first=node;
node->preview=node;
node->next=node;
}
else
{
list->first->preview->next=node;
node->preview=list->first->preview;
node->next=list->first;
list->first->preview=node;
list->first=node;
}
list->count++;
if(i==-1)break; // end
k=N-1;
}
if(i str[k--]=s[i]; } returnlist; } /* input:BigInt_List output:char * */ char*list_to_string(BigInt_List list) { char*s=(char *)malloc(256); inti,j,k=0; BigInt_Nodenode=list->first; for(i=0;i { charstr[N+1]; sprintf(str,"%d",node->value); intlen=strlen(str); //if the length is less N(=4) bits, then supplement enough by '0', and do notconsider the first one for it's MSB. if(i!=0&& len { charstr_temp[N+1]; intt=0; for(j=0;j { if(j elsestr_temp[j]=str[t++]; } for(j=0;j len=strlen(str); } for(j=0;j { s[k++]=str[j]; } node=node->next; } s[k]='\0'; returns; } /* * c=a+b */ BigInt_Listbigint_add(BigInt_List a, BigInt_List b) { inti, carry = 0; BigInt_Listc=bigint_mov(a); //from end to begin BigInt_Nodenode_a = c->first->preview; BigInt_Nodenode_b = b->first->preview; for(i = 0; i < c->count && i < b->count; i++) { intvalue=node_a->value + node_b->value + carry; if(value<10000)carry=0; else { value-=10000; carry=1; } node_a->value=value; node_a= node_a->preview; node_b= node_b->preview; } //if c(also a) has more while(i < c->count && carry>0) { intvalue = node_a->value + carry; if(value < 10000) carry = 0; else { value-=10000; carry= 1; } node_a->value=value; node_a= node_a->preview; i++; } //if b has more while(i < b->count) { intvalue = node_b->value + carry; if(value < 10000) carry = 0; else { value-= 10000; carry= 1; } BigInt_Nodenode=(BigInt_Node)malloc(sizeof(struct bigint_node)); node->value=value; c->first->preview->next=node; node->preview=c->first->preview; node->next=c->first; c->first->preview=node; c->first=node; c->count++; node_b= node_b->preview; i++; } if(carry == 1) { BigInt_Nodenode = (BigInt_Node)malloc(sizeof(struct bigint_node)); node->value= carry; c->first->preview->next= node; node->preview= c->first->preview; node->next= c->first; c->first->preview= node; c->first= node; c->count++; } if(c->count > 1) { while(c->first->value == 0) { c->first->preview->next= c->first->next; c->first->next->preview= c->first->preview; c->first= c->first->next; c->count--; if(c->count == 1) { break; } } } returnc; } 编译成动态库g++ -shared -fPIC -o libbigint.so bigint.c 将生成的.so文件放入/usr/lib目录下 udf文件udf_sum_samp.cc #define DEBUG 1 #include #include #include #include #include extern "C"{ typedef unsignedlong long ulonglong; typedef long longlonglong; // Use the standardmysql dev headers. #include #include my_bool udf_sum_samp_init(UDF_INIT *const initid,UDF_ARGS *const args, char *constmessage); void udf_sum_samp_deinit(UDF_INIT *constinitid); void udf_sum_samp_clear(UDF_INIT *constinitid, char *const is_null, char *const error); my_bool udf_sum_samp_add(UDF_INIT *const initid,UDF_ARGS *const args, char *const is_null,char *const error); char * udf_sum_samp(UDF_INIT *const initid,UDF_ARGS *const args, char *const result,unsigned long *const length, char *const is_null, char*const error); } /* extern"C" */ struct agg_state { BigInt_List sum; void *rbuf; }; my_bool udf_sum_samp_init(UDF_INIT*const initid, UDF_ARGS *const args, char *const message) { if (args->arg_count != 1 || args->arg_type[0] != STRING_RESULT) { strcpy(message, "Usage:udf_sum_samp(string value)"); return 1; } agg_state *const as = new agg_state(); as->rbuf = malloc(256); initid->ptr = reinterpret_cast initid->maybe_null = 1; return 0; } void udf_sum_samp_deinit(UDF_INIT*const initid) { agg_state *const as =reinterpret_cast free(as->rbuf); delete as; } void udf_sum_samp_clear(UDF_INIT*const initid, char *const is_null, char *const error) { agg_state *const as =reinterpret_cast as->sum = bigint_mov_value(0); } my_bool udf_sum_samp_add(UDF_INIT*const initid, UDF_ARGS *const args, char *const is_null, char*const error) { agg_state *const as =reinterpret_cast // BigInt_List e; if (NULL == args->args[0]) { e = bigint_mov_value(0); } else { e = string_to_list(args->args[0]); } //std::cerr << "the value ofargs " << args->args[0] << "\n"; //std::cerr << "the value oflist_to_string " << list_to_string(e) << "\n"; as->sum=bigint_add(as->sum,e); //std::cerr << "sum so far" << as->sum << "\n"; memset(args->args[0],0,strlen(args->args[0])); return true; } char * udf_sum_samp(UDF_INIT*const initid, UDF_ARGS *const args, char *const result, unsigned long *const length, char*const is_null, char *const error) { agg_state *const as =reinterpret_cast strcpy(static_cast //std::cerr << "the result:" << static_cast strcpy(result,static_cast *length=strlen(result); return static_cast } 将udf文件编译成动态库 g++ -shared -fPIC -I /usr/include/mysql/ udf_sum_samp.cc-o udf_sum_samp.so -lbigint 将生成的.so放入mysql/plugin下,sudo cp udf_sum_samp.so/usr/lib/mysql/plugin 进入mysql,mysql -u root -p udf代码中注释掉输出语句,可以把一些结果输出到mysql的错误日志中,默认是在/var/log/error.log