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) 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