函数效果如下:
select * from cxf limit 10;
id
----------
a
b
c
d
e
f
g
h
i
j
(10 row)
mysql=# select STRCAT2(id,'|') from (select * from cxf limit 10) t;
strcat2
-----------------------------------------------------------------------------------------
a|b|c|d|e|f|g|h|i|j
(1 row)
创建聚集函数的子函数:
drop FUNCTION strcat2_sfunc(varchar, varchar,varchar);
CREATE FUNCTION strcat2_sfunc(varchar, varchar,varchar)
RETURNS varchar AS '/home/mysql/cxf/postgresql-8.2.16/contrib/strcat/libstrcat2_sfunc'
LANGUAGE C IMMUTABLE;
创建聚集函数
drop AGGREGATE PUBLIC.STRCAT2(VARCHAR,varchar);
CREATE AGGREGATE PUBLIC.STRCAT2(VARCHAR,varchar)
(
SFUNC=strcat2_sfunc,
STYPE=VARCHAR
);
子函数源码如下:
strcat2_sfunc.c
#include "postgres.h"
#include "funcapi.h"
#include "fmgr.h"
#ifdef PG_MODULE_MAGIC
PG_MODULE_MAGIC;
#endif
PG_FUNCTION_INFO_V1(strcat2_sfunc);
Datum
strcat2_sfunc(PG_FUNCTION_ARGS)
{
VarChar *arg1;
VarChar *arg2;
VarChar *arg3;
if(PG_ARGISNULL(0) && PG_ARGISNULL(1))
{
PG_RETURN_NULL();
}
else if(PG_ARGISNULL(0)){
PG_RETURN_VARCHAR_P(PG_GETARG_VARCHAR_P(1));
}
else if(PG_ARGISNULL(1))
{
PG_RETURN_VARCHAR_P(PG_GETARG_VARCHAR_P(0));
}
else{
arg1 = PG_GETARG_VARCHAR_P(0);
arg2 = PG_GETARG_VARCHAR_P(1);
arg3 = PG_GETARG_VARCHAR_P(2);
int32 new_text_size = VARSIZE(arg1) + VARSIZE(arg2) +VARSIZE(arg3)- VARHDRSZ*2;
VarChar *new_text = (VarChar *) palloc(new_text_size);
VARATT_SIZEP(new_text) = new_text_size;
memcpy(VARDATA(new_text), VARDATA(arg1), VARSIZE(arg1) - VARHDRSZ);
memcpy(VARDATA(new_text) + (VARSIZE(arg1) - VARHDRSZ), VARDATA(arg3), VARSIZE(arg3) - VARHDRSZ);
memcpy(VARDATA(new_text) + (VARSIZE(arg1)+VARSIZE(arg3) - VARHDRSZ*2),
VARDATA(arg2), VARSIZE(arg2)- VARHDRSZ);
PG_RETURN_VARCHAR_P(new_text);
}
}
Makefile:
#
# Makefile for building PostgreSQL extension modules
#
MODULE_big = strcat2_sfunc
OBJS = strcat2_sfunc.o
DATA =
DOCS =
REGRESS =
ifdef USE_PGXS
PG_CONFIG = pg_config
PGXS := $(shell $(PG_CONFIG) --pgxs)
include $(PGXS)
else
subdir = contrib/statfunc
top_builddir = ../..
include $(top_builddir)/src/Makefile.global
include $(top_srcdir)/contrib/contrib-global.mk
endif