Hello

I am sending light wrapper of integrated fulltext. API is compatible
with tsearch2.

Regards
Pavel Stehule

ToDo: rewrite functions
diff -c -N -r contrib.old/tsearch2api/Makefile contrib/tsearch2api/Makefile
*** contrib.old/tsearch2api/Makefile	1970-01-01 01:00:00.000000000 +0100
--- contrib/tsearch2api/Makefile	2007-11-07 08:02:56.000000000 +0100
***************
*** 0 ****
--- 1,17 ----
+ MODULE_big = tsearch2
+ OBJS= tsearch2api.o
+ 
+ DATA_built = tsearch2.sql
+ 
+ ifdef USE_PGXS
+ PGXS = $(shell pg_config --pgxs)
+ include $(PGXS)
+ else
+ subdir = contrib/tsearch2api
+ top_builddir = ../..
+ include $(top_builddir)/src/Makefile.global
+ include $(top_srcdir)/contrib/contrib-global.mk
+ endif
+ 
+ tsearch2.sql: tsearch.sql.in
+ 	sed -e 's,MODULE_PATHNAME,$$libdir/$(MODULE_big),g' $< >$@
diff -c -N -r contrib.old/tsearch2api/tsearch.sql.in contrib/tsearch2api/tsearch.sql.in
*** contrib.old/tsearch2api/tsearch.sql.in	1970-01-01 01:00:00.000000000 +0100
--- contrib/tsearch2api/tsearch.sql.in	2007-11-07 08:05:25.000000000 +0100
***************
*** 0 ****
--- 1,739 ----
+ SET search_path = public, pg_catalog;
+ 
+ BEGIN;
+ 
+ --dict interface
+ CREATE FUNCTION lexize(oid, text) 
+ 	RETURNS _text
+ 	as 'MODULE_PATHNAME'
+ 	LANGUAGE C
+ 	RETURNS NULL ON NULL INPUT;
+ 
+ CREATE FUNCTION lexize(text, text)
+         RETURNS _text
+         as 'MODULE_PATHNAME', 'lexize_byname'
+         LANGUAGE C
+         RETURNS NULL ON NULL INPUT;
+ 
+ CREATE FUNCTION lexize(text)
+         RETURNS _text
+         as 'MODULE_PATHNAME', 'lexize_bycurrent'
+         LANGUAGE C
+         RETURNS NULL ON NULL INPUT;
+ 
+ CREATE FUNCTION set_curdict(int)
+ 	RETURNS void
+ 	as 'MODULE_PATHNAME'
+ 	LANGUAGE C
+ 	RETURNS NULL ON NULL INPUT;
+ 
+ CREATE FUNCTION set_curdict(text)
+ 	RETURNS void
+ 	as 'MODULE_PATHNAME', 'set_curdict_byname'
+ 	LANGUAGE C
+ 	RETURNS NULL ON NULL INPUT;
+ 
+ --built-in dictionaries
+ CREATE FUNCTION dex_init(internal)
+ 	RETURNS internal
+ 	as 'MODULE_PATHNAME' 
+ 	LANGUAGE C;
+ 
+ CREATE FUNCTION dex_lexize(internal,internal,int4)
+ 	RETURNS internal
+ 	as 'MODULE_PATHNAME'
+ 	LANGUAGE C
+ 	RETURNS NULL ON NULL INPUT;
+ 
+ CREATE FUNCTION snb_en_init(internal)
+ 	RETURNS internal
+ 	as 'MODULE_PATHNAME' 
+ 	LANGUAGE C;
+ 
+ CREATE FUNCTION snb_lexize(internal,internal,int4)
+ 	RETURNS internal
+ 	as 'MODULE_PATHNAME'
+ 	LANGUAGE C
+ 	RETURNS NULL ON NULL INPUT;
+ 
+ CREATE FUNCTION snb_ru_init_koi8(internal)
+ 	RETURNS internal
+ 	as 'MODULE_PATHNAME' 
+ 	LANGUAGE C;
+ 
+ CREATE FUNCTION snb_ru_init_utf8(internal)
+ 	RETURNS internal
+ 	as 'MODULE_PATHNAME' 
+ 	LANGUAGE C;
+ 
+ CREATE FUNCTION spell_init(internal)
+ 	RETURNS internal
+ 	as 'MODULE_PATHNAME' 
+ 	LANGUAGE C;
+ 
+ CREATE FUNCTION spell_lexize(internal,internal,int4)
+ 	RETURNS internal
+ 	as 'MODULE_PATHNAME'
+ 	LANGUAGE C
+ 	RETURNS NULL ON NULL INPUT;
+ 
+ CREATE FUNCTION syn_init(internal)
+ 	RETURNS internal
+ 	as 'MODULE_PATHNAME' 
+ 	LANGUAGE C;
+ 
+ CREATE FUNCTION syn_lexize(internal,internal,int4)
+ 	RETURNS internal
+ 	as 'MODULE_PATHNAME'
+ 	LANGUAGE C
+ 	RETURNS NULL ON NULL INPUT;
+ 
+ CREATE FUNCTION thesaurus_init(internal)
+ 	RETURNS internal
+ 	as 'MODULE_PATHNAME' 
+ 	LANGUAGE C;
+ 
+ CREATE FUNCTION thesaurus_lexize(internal,internal,int4,internal)
+ 	RETURNS internal
+ 	as 'MODULE_PATHNAME'
+ 	LANGUAGE C
+ 	RETURNS NULL ON NULL INPUT;
+ 
+ --sql-level interface
+ CREATE TYPE tokentype 
+ 	as (tokid int4, alias text, descr text); 
+ 
+ CREATE FUNCTION token_type(int4)
+ 	RETURNS setof tokentype
+ 	as 'MODULE_PATHNAME'
+ 	LANGUAGE C
+ 	RETURNS NULL ON NULL INPUT;
+ 
+ CREATE FUNCTION token_type(text)
+ 	RETURNS setof tokentype
+ 	as 'MODULE_PATHNAME', 'token_type_byname'
+ 	LANGUAGE C
+ 	RETURNS NULL ON NULL INPUT;
+ 
+ CREATE FUNCTION token_type()
+ 	RETURNS setof tokentype
+ 	as 'MODULE_PATHNAME', 'token_type_current'
+ 	LANGUAGE C
+ 	RETURNS NULL ON NULL INPUT;
+ 
+ CREATE FUNCTION set_curprs(int)
+ 	RETURNS void
+ 	as 'MODULE_PATHNAME'
+ 	LANGUAGE C
+ 	RETURNS NULL ON NULL INPUT;
+ 
+ CREATE FUNCTION set_curprs(text)
+ 	RETURNS void
+ 	as 'MODULE_PATHNAME', 'set_curprs_byname'
+ 	LANGUAGE C
+ 	RETURNS NULL ON NULL INPUT;
+ 
+ CREATE TYPE tokenout 
+ 	as (tokid int4, token text);
+ 
+ CREATE FUNCTION parse(oid,text)
+ 	RETURNS setof tokenout
+ 	as 'MODULE_PATHNAME'
+ 	LANGUAGE C
+ 	RETURNS NULL ON NULL INPUT;
+  
+ CREATE FUNCTION parse(text,text)
+ 	RETURNS setof tokenout
+ 	as 'MODULE_PATHNAME', 'parse_byname'
+ 	LANGUAGE C
+ 	RETURNS NULL ON NULL INPUT;
+  
+ CREATE FUNCTION parse(text)
+ 	RETURNS setof tokenout
+ 	as 'MODULE_PATHNAME', 'parse_current'
+ 	LANGUAGE C
+ 	RETURNS NULL ON NULL INPUT;
+  
+ --default parser
+ CREATE FUNCTION prsd_start(internal,int4)
+ 	RETURNS internal
+ 	as 'MODULE_PATHNAME'
+ 	LANGUAGE C;
+ 
+ CREATE FUNCTION prsd_getlexeme(internal,internal,internal)
+ 	RETURNS int4
+ 	as 'MODULE_PATHNAME'
+ 	LANGUAGE C;
+ 
+ CREATE FUNCTION prsd_end(internal)
+ 	RETURNS void
+ 	as 'MODULE_PATHNAME'
+ 	LANGUAGE C;
+ 
+ CREATE FUNCTION prsd_lextype(internal)
+ 	RETURNS internal
+ 	as 'MODULE_PATHNAME'
+ 	LANGUAGE C;
+ 
+ CREATE FUNCTION prsd_headline(internal,internal,internal)
+ 	RETURNS internal
+ 	as 'MODULE_PATHNAME'
+ 	LANGUAGE C;
+ 
+ --tsearch config
+ CREATE FUNCTION set_curcfg(int)
+ 	RETURNS void
+ 	as 'MODULE_PATHNAME'
+ 	LANGUAGE C
+ 	RETURNS NULL ON NULL INPUT;
+ 
+ CREATE FUNCTION set_curcfg(text)
+ 	RETURNS void
+ 	as 'MODULE_PATHNAME', 'set_curcfg_byname'
+ 	LANGUAGE C
+ 	RETURNS NULL ON NULL INPUT;
+ 
+ CREATE FUNCTION show_curcfg()
+ 	RETURNS oid
+ 	as 'MODULE_PATHNAME'
+ 	LANGUAGE C
+ 	RETURNS NULL ON NULL INPUT;
+ 
+ CREATE FUNCTION tsvector_in(cstring)
+ 	RETURNS tsvector
+ 	AS 'MODULE_PATHNAME'
+ 	LANGUAGE C RETURNS NULL ON NULL INPUT;
+ 
+ CREATE FUNCTION tsvector_out(tsvector)
+ 	RETURNS cstring
+ 	AS 'MODULE_PATHNAME'
+ 	LANGUAGE C RETURNS NULL ON NULL INPUT;
+ 
+ CREATE FUNCTION length(tsvector)
+ 	RETURNS int4
+ 	AS 'MODULE_PATHNAME', 'tsvector_length'
+ 	LANGUAGE C RETURNS NULL ON NULL INPUT IMMUTABLE;
+ 
+ CREATE FUNCTION to_tsvector(oid, text)
+ 	RETURNS tsvector
+ 	AS 'MODULE_PATHNAME'
+ 	LANGUAGE C RETURNS NULL ON NULL INPUT IMMUTABLE;
+ 
+ CREATE FUNCTION to_tsvector(text, text)
+ 	RETURNS tsvector
+ 	AS 'MODULE_PATHNAME', 'to_tsvector_name'
+ 	LANGUAGE C RETURNS NULL ON NULL INPUT IMMUTABLE;
+ 
+ CREATE FUNCTION to_tsvector(text)
+ 	RETURNS tsvector
+ 	AS 'MODULE_PATHNAME', 'to_tsvector_current'
+ 	LANGUAGE C RETURNS NULL ON NULL INPUT IMMUTABLE;
+ 
+ CREATE FUNCTION strip(tsvector)
+ 	RETURNS tsvector
+ 	AS 'MODULE_PATHNAME'
+ 	LANGUAGE C RETURNS NULL ON NULL INPUT IMMUTABLE;
+ 
+ CREATE FUNCTION setweight(tsvector,"char")
+ 	RETURNS tsvector
+ 	AS 'MODULE_PATHNAME'
+ 	LANGUAGE C RETURNS NULL ON NULL INPUT IMMUTABLE;
+ 
+ CREATE FUNCTION concat(tsvector,tsvector)
+ 	RETURNS tsvector
+ 	AS 'MODULE_PATHNAME'
+ 	LANGUAGE C RETURNS NULL ON NULL INPUT IMMUTABLE;
+ 
+ CREATE FUNCTION tsquery_in(cstring)
+ 	RETURNS tsquery
+ 	AS 'MODULE_PATHNAME'
+ 	LANGUAGE C RETURNS NULL ON NULL INPUT;
+ 
+ CREATE FUNCTION tsquery_out(tsquery)
+ 	RETURNS cstring
+ 	AS 'MODULE_PATHNAME'
+ 	LANGUAGE C RETURNS NULL ON NULL INPUT;
+ 
+ CREATE FUNCTION querytree(tsquery)
+ 	RETURNS text
+ 	AS 'MODULE_PATHNAME', 'tsquerytree'
+ 	LANGUAGE C RETURNS NULL ON NULL INPUT;
+ 
+ CREATE FUNCTION to_tsquery(oid, text)
+ 	RETURNS tsquery
+ 	AS 'MODULE_PATHNAME'
+ 	LANGUAGE C RETURNS NULL ON NULL INPUT IMMUTABLE;
+ 
+ CREATE FUNCTION to_tsquery(text, text)
+ 	RETURNS tsquery
+ 	AS 'MODULE_PATHNAME','to_tsquery_name'
+ 	LANGUAGE C RETURNS NULL ON NULL INPUT IMMUTABLE;
+ 
+ CREATE FUNCTION to_tsquery(text)
+ 	RETURNS tsquery
+ 	AS 'MODULE_PATHNAME','to_tsquery_current'
+ 	LANGUAGE C RETURNS NULL ON NULL INPUT IMMUTABLE;
+ 
+ CREATE FUNCTION plainto_tsquery(oid, text)
+ 	RETURNS tsquery
+ 	AS 'MODULE_PATHNAME'
+ 	LANGUAGE C RETURNS NULL ON NULL INPUT IMMUTABLE;
+ 
+ CREATE FUNCTION plainto_tsquery(text, text)
+ 	RETURNS tsquery
+ 	AS 'MODULE_PATHNAME','plainto_tsquery_name'
+ 	LANGUAGE C RETURNS NULL ON NULL INPUT IMMUTABLE;
+ 
+ CREATE FUNCTION plainto_tsquery(text)
+ 	RETURNS tsquery
+ 	AS 'MODULE_PATHNAME','plainto_tsquery_current'
+ 	LANGUAGE C RETURNS NULL ON NULL INPUT IMMUTABLE;
+ 
+ --operations
+ CREATE FUNCTION exectsq(tsvector, tsquery)
+ 	RETURNS bool
+ 	AS 'MODULE_PATHNAME'
+ 	LANGUAGE C RETURNS NULL ON NULL INPUT IMMUTABLE;
+   
+ CREATE FUNCTION rexectsq(tsquery, tsvector)
+ 	RETURNS bool
+ 	AS 'MODULE_PATHNAME'
+ 	LANGUAGE C RETURNS NULL ON NULL INPUT IMMUTABLE;
+ 
+ --Trigger
+ CREATE FUNCTION tsearch2()
+ 	RETURNS trigger
+ 	AS 'MODULE_PATHNAME'
+ 	LANGUAGE C;
+ 
+ --Relevation
+ CREATE FUNCTION rank(float4[], tsvector, tsquery)
+ 	RETURNS float4
+ 	AS 'MODULE_PATHNAME'
+ 	LANGUAGE C RETURNS NULL ON NULL INPUT IMMUTABLE;
+ 
+ CREATE FUNCTION rank(float4[], tsvector, tsquery, int4)
+ 	RETURNS float4
+ 	AS 'MODULE_PATHNAME'
+ 	LANGUAGE C RETURNS NULL ON NULL INPUT IMMUTABLE;
+ 
+ CREATE FUNCTION rank(tsvector, tsquery)
+ 	RETURNS float4
+ 	AS 'MODULE_PATHNAME', 'rank_def'
+ 	LANGUAGE C RETURNS NULL ON NULL INPUT IMMUTABLE;
+ 
+ CREATE FUNCTION rank(tsvector, tsquery, int4)
+ 	RETURNS float4
+ 	AS 'MODULE_PATHNAME', 'rank_def'
+ 	LANGUAGE C RETURNS NULL ON NULL INPUT IMMUTABLE;
+ 
+ CREATE FUNCTION rank_cd(float4[], tsvector, tsquery)
+         RETURNS float4
+ 	AS 'MODULE_PATHNAME'
+ 	LANGUAGE C RETURNS NULL ON NULL INPUT IMMUTABLE;
+ 
+ CREATE FUNCTION rank_cd(float4[], tsvector, tsquery, int4)
+ 	RETURNS float4
+ 	AS 'MODULE_PATHNAME'
+ 	LANGUAGE C RETURNS NULL ON NULL INPUT IMMUTABLE;
+ 
+ CREATE FUNCTION rank_cd(tsvector, tsquery)
+ 	RETURNS float4
+ 	AS 'MODULE_PATHNAME', 'rank_cd_def'
+ 	LANGUAGE C RETURNS NULL ON NULL INPUT IMMUTABLE;
+ 
+ CREATE FUNCTION rank_cd(tsvector, tsquery, int4)
+ 	RETURNS float4
+ 	AS 'MODULE_PATHNAME', 'rank_cd_def'
+ 	LANGUAGE C RETURNS NULL ON NULL INPUT IMMUTABLE;
+ 
+ CREATE FUNCTION headline(oid, text, tsquery, text)
+ 	RETURNS text
+ 	AS 'MODULE_PATHNAME', 'headline'
+ 	LANGUAGE C RETURNS NULL ON NULL INPUT IMMUTABLE;
+ 
+ CREATE FUNCTION headline(oid, text, tsquery)
+ 	RETURNS text
+ 	AS 'MODULE_PATHNAME', 'headline'
+ 	LANGUAGE C RETURNS NULL ON NULL INPUT IMMUTABLE;
+ 
+ CREATE FUNCTION headline(text, text, tsquery, text)
+ 	RETURNS text
+ 	AS 'MODULE_PATHNAME', 'headline_byname'
+ 	LANGUAGE C RETURNS NULL ON NULL INPUT IMMUTABLE;
+ 
+ CREATE FUNCTION headline(text, text, tsquery)
+ 	RETURNS text
+ 	AS 'MODULE_PATHNAME', 'headline_byname'
+ 	LANGUAGE C RETURNS NULL ON NULL INPUT IMMUTABLE;
+ 
+ CREATE FUNCTION headline(text, tsquery, text)
+ 	RETURNS text
+ 	AS 'MODULE_PATHNAME', 'headline_current'
+ 	LANGUAGE C RETURNS NULL ON NULL INPUT IMMUTABLE;
+ 
+ CREATE FUNCTION headline(text, tsquery)
+ 	RETURNS text
+ 	AS 'MODULE_PATHNAME', 'headline_current'
+ 	LANGUAGE C RETURNS NULL ON NULL INPUT IMMUTABLE;
+ 
+ --GiST
+ --GiST key type
+ 
+ CREATE FUNCTION gtsvector_in(cstring)
+ RETURNS gtsvector
+ 	AS 'MODULE_PATHNAME'
+ 	LANGUAGE C RETURNS NULL ON NULL INPUT;
+ 
+ CREATE FUNCTION gtsvector_out(gtsvector)
+ 	RETURNS cstring
+ 	AS 'MODULE_PATHNAME'
+ 	LANGUAGE C RETURNS NULL ON NULL INPUT;
+ 
+ -- support FUNCTIONs
+ CREATE FUNCTION gtsvector_consistent(gtsvector,internal,int4)
+ 	RETURNS bool
+ 	AS 'MODULE_PATHNAME'
+ 	LANGUAGE C;
+   
+ CREATE FUNCTION gtsvector_compress(internal)
+ 	RETURNS internal
+ 	AS 'MODULE_PATHNAME'
+ 	LANGUAGE C;
+ 
+ CREATE FUNCTION gtsvector_decompress(internal)
+ 	RETURNS internal
+ 	AS 'MODULE_PATHNAME'
+ 	LANGUAGE C;
+ 
+ CREATE FUNCTION gtsvector_penalty(internal,internal,internal)
+ 	RETURNS internal
+ 	AS 'MODULE_PATHNAME'
+ 	LANGUAGE C RETURNS NULL ON NULL INPUT;
+ 
+ CREATE FUNCTION gtsvector_picksplit(internal, internal)
+ 	RETURNS internal
+ 	AS 'MODULE_PATHNAME'
+ 	LANGUAGE C;
+ 
+ CREATE FUNCTION gtsvector_union(internal, internal)
+ 	RETURNS _int4
+ 	AS 'MODULE_PATHNAME'
+ 	LANGUAGE C;
+ 
+ CREATE FUNCTION gtsvector_same(gtsvector, gtsvector, internal)
+ 	RETURNS internal
+ 	AS 'MODULE_PATHNAME'
+ 	LANGUAGE C;
+ 
+ --stat info
+ CREATE TYPE statinfo 
+ 	as (word text, ndoc int4, nentry int4);
+ 
+ --CREATE FUNCTION tsstat_in(cstring)
+ --RETURNS tsstat
+ --AS 'MODULE_PATHNAME'
+ --LANGUAGE C RETURNS NULL ON NULL INPUT;
+ --
+ --CREATE FUNCTION tsstat_out(tsstat)
+ --RETURNS cstring
+ --AS 'MODULE_PATHNAME'
+ --LANGUAGE C RETURNS NULL ON NULL INPUT;
+ --
+ --CREATE TYPE tsstat (
+ --        INTERNALLENGTH = -1,
+ --        INPUT = tsstat_in,
+ --        OUTPUT = tsstat_out,
+ --        STORAGE = plain
+ --);
+ --
+ --CREATE FUNCTION ts_accum(tsstat,tsvector)
+ --RETURNS tsstat
+ --AS 'MODULE_PATHNAME'
+ --LANGUAGE C RETURNS NULL ON NULL INPUT;
+ --
+ --CREATE FUNCTION ts_accum_finish(tsstat)
+ --	RETURNS setof statinfo
+ --	as 'MODULE_PATHNAME'
+ --	LANGUAGE C
+ --	RETURNS NULL ON NULL INPUT;
+ --
+ --CREATE AGGREGATE stat (
+ --	BASETYPE=tsvector,
+ --	SFUNC=ts_accum,
+ --	STYPE=tsstat,
+ --	FINALFUNC = ts_accum_finish,
+ --	initcond = ''
+ --); 
+ 
+ CREATE FUNCTION stat(text)
+ 	RETURNS setof statinfo
+ 	as 'MODULE_PATHNAME', 'ts_stat'
+ 	LANGUAGE C
+ 	RETURNS NULL ON NULL INPUT;
+ 
+ CREATE FUNCTION stat(text,text)
+ 	RETURNS setof statinfo
+ 	as 'MODULE_PATHNAME', 'ts_stat'
+ 	LANGUAGE C
+ 	RETURNS NULL ON NULL INPUT;
+ 
+ --reset - just for debuging
+ CREATE FUNCTION reset_tsearch()
+         RETURNS void
+         as 'MODULE_PATHNAME'
+         LANGUAGE C
+         RETURNS NULL ON NULL INPUT;
+ 
+ --get cover (debug for rank_cd)
+ CREATE FUNCTION get_covers(tsvector,tsquery)
+         RETURNS text
+         as 'MODULE_PATHNAME'
+         LANGUAGE C
+         RETURNS NULL ON NULL INPUT;
+ 
+ --debug function
+ create type tsdebug as (
+         ts_name text,
+         tok_type text,
+         description text,
+         token   text,
+         dict_name text[],
+         "tsvector" tsvector
+ );
+ 
+ CREATE or replace FUNCTION _get_parser_from_curcfg()
+ RETURNS text as
+ $$select prsname::text from pg_catalog.pg_ts_parser p join pg_ts_config c on cfgparser = p.oid where c.oid = show_curcfg();$$
+ LANGUAGE SQL RETURNS NULL ON NULL INPUT IMMUTABLE;
+ 
+ CREATE FUNCTION ts_debug(text)
+ RETURNS setof tsdebug as '
+ select
+         c.cfgname::text,
+         t.alias as tok_type,
+         t.descr as description,
+         p.token,
+         (ARRAY[d.dictname])::text[],
+         strip(to_tsvector(p.token)) as tsvector
+ from
+         parse( _get_parser_from_curcfg(), $1 ) as p,
+         token_type() as t,
+ 	pg_ts_config_map as m,
+         pg_ts_config as c, pg_catalog.pg_ts_dict d
+ where
+         t.tokid=p.tokid and
+         t.tokid= m.maptokentype and
+         m.mapcfg=c.oid and
+         c.oid=show_curcfg() and m.mapdict = d.oid;
+ ' LANGUAGE SQL RETURNS NULL ON NULL INPUT;
+ 
+ --compare functions
+ CREATE FUNCTION tsvector_cmp(tsvector,tsvector)
+ 	RETURNS int4
+ 	AS 'MODULE_PATHNAME'
+ 	LANGUAGE C RETURNS NULL ON NULL INPUT IMMUTABLE;
+ 
+ CREATE FUNCTION tsvector_lt(tsvector,tsvector)
+ 	RETURNS bool
+ 	AS 'MODULE_PATHNAME'
+ 	LANGUAGE C RETURNS NULL ON NULL INPUT IMMUTABLE;
+ 
+ CREATE FUNCTION tsvector_le(tsvector,tsvector)
+ 	RETURNS bool
+ 	AS 'MODULE_PATHNAME'
+ 	LANGUAGE C RETURNS NULL ON NULL INPUT IMMUTABLE;
+         
+ CREATE FUNCTION tsvector_eq(tsvector,tsvector)
+ 	RETURNS bool
+ 	AS 'MODULE_PATHNAME'
+ 	LANGUAGE C RETURNS NULL ON NULL INPUT IMMUTABLE;
+ 
+ CREATE FUNCTION tsvector_ge(tsvector,tsvector)
+ 	RETURNS bool
+ 	AS 'MODULE_PATHNAME'
+ 	LANGUAGE C RETURNS NULL ON NULL INPUT IMMUTABLE;
+         
+ CREATE FUNCTION tsvector_gt(tsvector,tsvector)
+ 	RETURNS bool
+ 	AS 'MODULE_PATHNAME'
+ 	LANGUAGE C RETURNS NULL ON NULL INPUT IMMUTABLE;
+ 
+ CREATE FUNCTION tsvector_ne(tsvector,tsvector)
+ 	RETURNS bool
+ 	AS 'MODULE_PATHNAME'
+ 	LANGUAGE C RETURNS NULL ON NULL INPUT IMMUTABLE;
+ 
+ ----------------Compare functions and operators for tsquery
+ CREATE OR REPLACE FUNCTION tsquery_cmp(tsquery,tsquery)
+ 	RETURNS int4
+ 	AS 'MODULE_PATHNAME'
+ 	LANGUAGE C RETURNS NULL ON NULL INPUT IMMUTABLE;
+ 
+ CREATE OR REPLACE FUNCTION tsquery_lt(tsquery,tsquery)
+ 	RETURNS bool
+ 	AS 'MODULE_PATHNAME'
+ 	LANGUAGE C RETURNS NULL ON NULL INPUT IMMUTABLE;
+ 
+ CREATE OR REPLACE FUNCTION tsquery_le(tsquery,tsquery)
+ 	RETURNS bool
+ 	AS 'MODULE_PATHNAME'
+ 	LANGUAGE C RETURNS NULL ON NULL INPUT IMMUTABLE;
+ 
+ CREATE OR REPLACE FUNCTION tsquery_eq(tsquery,tsquery)
+ 	RETURNS bool
+ 	AS 'MODULE_PATHNAME'
+ 	LANGUAGE C RETURNS NULL ON NULL INPUT IMMUTABLE;
+ 
+ CREATE OR REPLACE FUNCTION tsquery_ge(tsquery,tsquery)
+ 	RETURNS bool
+ 	AS 'MODULE_PATHNAME'
+ 	LANGUAGE C RETURNS NULL ON NULL INPUT IMMUTABLE;
+ 
+ CREATE OR REPLACE FUNCTION tsquery_gt(tsquery,tsquery)
+ 	RETURNS bool
+ 	AS 'MODULE_PATHNAME'
+ 	LANGUAGE C RETURNS NULL ON NULL INPUT IMMUTABLE;
+ 
+ CREATE OR REPLACE FUNCTION tsquery_ne(tsquery,tsquery)
+ 	RETURNS bool
+ 	AS 'MODULE_PATHNAME'
+ 	LANGUAGE C RETURNS NULL ON NULL INPUT IMMUTABLE;
+ 
+ CREATE OR REPLACE FUNCTION numnode(tsquery)
+         RETURNS int4
+         as 'MODULE_PATHNAME', 'tsquery_numnode'
+         LANGUAGE C
+         RETURNS NULL ON NULL INPUT IMMUTABLE;
+ 
+ CREATE OR REPLACE FUNCTION tsquery_and(tsquery,tsquery)
+         RETURNS tsquery
+         as 'MODULE_PATHNAME', 'tsquery_and'
+         LANGUAGE C
+         RETURNS NULL ON NULL INPUT IMMUTABLE;
+ 
+ CREATE OR REPLACE FUNCTION tsquery_or(tsquery,tsquery)
+         RETURNS tsquery
+         as 'MODULE_PATHNAME', 'tsquery_or'
+         LANGUAGE C
+         RETURNS NULL ON NULL INPUT IMMUTABLE;
+ 
+ CREATE OR REPLACE FUNCTION tsquery_not(tsquery)
+         RETURNS tsquery
+         as 'MODULE_PATHNAME', 'tsquery_not'
+         LANGUAGE C
+         RETURNS NULL ON NULL INPUT IMMUTABLE;
+ 
+ --------------rewrite subsystem
+ 
+ CREATE OR REPLACE FUNCTION rewrite(tsquery, text)
+         RETURNS tsquery
+         as 'MODULE_PATHNAME', 'tsquery_rewrite'
+         LANGUAGE C
+         RETURNS NULL ON NULL INPUT IMMUTABLE;
+ 
+ CREATE OR REPLACE FUNCTION rewrite(tsquery, tsquery, tsquery)
+         RETURNS tsquery
+         as 'MODULE_PATHNAME', 'tsquery_rewrite_query'
+         LANGUAGE C
+         RETURNS NULL ON NULL INPUT IMMUTABLE;
+ 
+ CREATE OR REPLACE FUNCTION rewrite_accum(tsquery,tsquery[])
+         RETURNS tsquery
+         AS 'MODULE_PATHNAME'
+         LANGUAGE C;
+ 
+ CREATE OR REPLACE FUNCTION rewrite_finish(tsquery)
+       RETURNS tsquery
+       as 'MODULE_PATHNAME'
+       LANGUAGE C;
+ 
+ CREATE AGGREGATE rewrite (
+       BASETYPE=tsquery[],
+       SFUNC=rewrite_accum,
+       STYPE=tsquery,
+       FINALFUNC = rewrite_finish
+ );
+ 
+ CREATE OR REPLACE FUNCTION tsq_mcontains(tsquery, tsquery)
+         RETURNS bool
+         as 'MODULE_PATHNAME'
+         LANGUAGE C
+         RETURNS NULL ON NULL INPUT IMMUTABLE;
+ 
+ CREATE OR REPLACE FUNCTION tsq_mcontained(tsquery, tsquery)
+         RETURNS bool
+         as 'MODULE_PATHNAME'
+         LANGUAGE C
+         RETURNS NULL ON NULL INPUT IMMUTABLE;
+ 
+ -----------gist support of rewrite------------------
+ CREATE TYPE gtsq;
+ 
+ CREATE FUNCTION gtsq_in(cstring)
+ 	RETURNS gtsq
+ 	AS 'MODULE_PATHNAME'
+ 	LANGUAGE C RETURNS NULL ON NULL INPUT;
+ 
+ CREATE FUNCTION gtsq_out(gtsq)
+ 	RETURNS cstring
+ 	AS 'MODULE_PATHNAME'
+ 	LANGUAGE C RETURNS NULL ON NULL INPUT;
+ 
+ CREATE TYPE gtsq (
+         INTERNALLENGTH = 8,
+         INPUT = gtsq_in,
+         OUTPUT = gtsq_out);
+ 
+ CREATE FUNCTION gtsq_consistent(gtsq,internal,int4)
+ 	RETURNS bool
+ 	AS 'MODULE_PATHNAME'
+ 	LANGUAGE C;
+ 
+ CREATE FUNCTION gtsq_compress(internal)
+ 	RETURNS internal
+ 	AS 'MODULE_PATHNAME'
+ 	LANGUAGE C;
+ 
+ CREATE FUNCTION gtsq_decompress(internal)
+ 	RETURNS internal
+ 	AS 'MODULE_PATHNAME'
+ 	LANGUAGE C;
+ 
+ CREATE FUNCTION gtsq_penalty(internal,internal,internal)
+ 	RETURNS internal
+ 	AS 'MODULE_PATHNAME'
+ 	LANGUAGE C RETURNS NULL ON NULL INPUT;
+ 
+ CREATE FUNCTION gtsq_picksplit(internal, internal)
+ 	RETURNS internal
+ 	AS 'MODULE_PATHNAME'
+ 	LANGUAGE C;
+ 
+ CREATE FUNCTION gtsq_union(bytea, internal)
+ 	RETURNS _int4
+ 	AS 'MODULE_PATHNAME'
+ 	LANGUAGE C;
+ 
+ CREATE FUNCTION gtsq_same(gtsq, gtsq, internal)
+ 	RETURNS internal
+ 	AS 'MODULE_PATHNAME'
+ 	LANGUAGE C;
+ 
+ --GIN support function
+ CREATE FUNCTION gin_extract_tsvector(tsvector,internal)
+ 	RETURNS internal
+ 	AS 'MODULE_PATHNAME'
+ 	LANGUAGE C RETURNS NULL ON NULL INPUT;
+ 
+ CREATE FUNCTION gin_extract_tsquery(tsquery,internal,internal)
+ 	RETURNS internal
+ 	AS 'MODULE_PATHNAME'
+ 	LANGUAGE C RETURNS NULL ON NULL INPUT;
+ 
+ CREATE FUNCTION gin_ts_consistent(internal,internal,tsquery)
+ 	RETURNS bool
+ 	AS 'MODULE_PATHNAME'
+ 	LANGUAGE C RETURNS NULL ON NULL INPUT;
+ 
+ END;
diff -c -N -r contrib.old/tsearch2api/tsearch2api.c contrib/tsearch2api/tsearch2api.c
*** contrib.old/tsearch2api/tsearch2api.c	1970-01-01 01:00:00.000000000 +0100
--- contrib/tsearch2api/tsearch2api.c	2007-11-07 07:57:36.000000000 +0100
***************
*** 0 ****
--- 1,792 ----
+ #include "postgres.h"
+ 
+ #include "fmgr.h"
+ #include "funcapi.h"
+ #include "executor/spi.h"
+ #include "tsearch/ts_utils.h"
+ #include "miscadmin.h"
+ #include "commands/trigger.h"
+ 
+ PG_MODULE_MAGIC;
+ 
+ Oid current_dictionary_oid = InvalidOid;
+ Oid current_parser_oid = InvalidOid;
+ 
+ /*
+  * General wrapper for V1 function, used for 
+  * forward an call from src function to dest function.
+  * In this content .. src is older TSearch2 functions,
+  * dest are newer 8.3 fulltext functions.
+  */
+ #define WRAPPER_FUNCTION(src, dest)				\
+ 	Datum src (PG_FUNCTION_ARGS);				\
+ 	PG_FUNCTION_INFO_V1(src);				\
+ 	Datum							\
+ 	src(PG_FUNCTION_ARGS)					\
+ 	{							\
+ 		return (dest)(fcinfo);				\
+ 	}							
+ 
+ #define UNSUPPORTED_FUNCTION(name)										\
+ 	Datum name (PG_FUNCTION_ARGS);										\
+ 	PG_FUNCTION_INFO_V1(name);										\
+ 	Datum													\
+ 	name (PG_FUNCTION_ARGS)											\
+ 	{													\
+ 		ereport(ERROR,											\
+ 				(errcode(ERRCODE_INTERNAL_ERROR),						\
+ 				 errmsg("The using of unsuppored function"),					\
+ 				 errdetail("Function 'public.%s' is unsupported now.", #name), 			\
+ 				 errhint("Specify schema in your application.")));				\
+ 		/* be compiler quite */										\
+ 		PG_RETURN_VOID();										\
+ 	} 
+ 
+ #define INSERT_ARGUMENT(argument, isnull)						\
+ 	{										\
+ 		int i;									\
+ 		for (i = fcinfo->nargs; i > 0; i--)					\
+ 		{									\
+ 			fcinfo->arg[i] = fcinfo->arg[1-1];				\
+ 			fcinfo->argnull[1] = fcinfo->argnull[i-1];			\
+ 		}									\
+ 		fcinfo->arg[0] = (argument);						\
+ 		fcinfo->argnull[0] = (isnull);						\
+ 	} 
+ 
+ #define TextPGetCString(t) DatumGetCString(DirectFunctionCall1(textout, PointerGetDatum(t)))
+ #define CStringGetTextP(c) DatumGetTextP(DirectFunctionCall1(textin, CStringGetDatum(c)))
+ 
+ #define TextGetObjectId(infunction, text)								\
+ 	DatumGetObjectId(DirectFunctionCall1(infunction,DirectFunctionCall1(textout,PointerGetDatum(text))))
+ 
+ static Oid GetCurrentDict(void);
+ static Oid GetCurrentParser(void);
+ 
+ 
+ Datum lexize_byname(PG_FUNCTION_ARGS);
+ Datum lexize_bycurrent(PG_FUNCTION_ARGS);
+ Datum set_curdict(PG_FUNCTION_ARGS);
+ Datum set_curdict_byname(PG_FUNCTION_ARGS);
+ Datum token_type_current(PG_FUNCTION_ARGS);
+ Datum set_curprs(PG_FUNCTION_ARGS);
+ Datum set_curprs_byname(PG_FUNCTION_ARGS);
+ Datum parse_current(PG_FUNCTION_ARGS);
+ Datum set_curcfg(PG_FUNCTION_ARGS);
+ Datum set_curcfg_byname(PG_FUNCTION_ARGS);
+ Datum show_curcfg(PG_FUNCTION_ARGS);
+ Datum to_tsvector_name(PG_FUNCTION_ARGS);
+ Datum to_tsquery_name(PG_FUNCTION_ARGS);
+ Datum plainto_tsquery_name(PG_FUNCTION_ARGS);
+ Datum headline_byname(PG_FUNCTION_ARGS);
+ Datum rank(PG_FUNCTION_ARGS);
+ Datum rank_def(PG_FUNCTION_ARGS);
+ Datum rank_cd(PG_FUNCTION_ARGS);
+ Datum rank_cd_def(PG_FUNCTION_ARGS);
+ Datum headline(PG_FUNCTION_ARGS);
+ Datum headline_current(PG_FUNCTION_ARGS);
+ Datum ts_stat(PG_FUNCTION_ARGS);
+ Datum tsearch2(PG_FUNCTION_ARGS);
+ 
+ PG_FUNCTION_INFO_V1(lexize_bycurrent);
+ PG_FUNCTION_INFO_V1(lexize_byname);
+ PG_FUNCTION_INFO_V1(set_curdict);
+ PG_FUNCTION_INFO_V1(set_curdict_byname);
+ PG_FUNCTION_INFO_V1(token_type_current);
+ PG_FUNCTION_INFO_V1(set_curprs);
+ PG_FUNCTION_INFO_V1(set_curprs_byname);
+ PG_FUNCTION_INFO_V1(parse_current);
+ PG_FUNCTION_INFO_V1(set_curcfg);
+ PG_FUNCTION_INFO_V1(set_curcfg_byname);
+ PG_FUNCTION_INFO_V1(show_curcfg);
+ PG_FUNCTION_INFO_V1(to_tsvector_name);
+ PG_FUNCTION_INFO_V1(to_tsquery_name);
+ PG_FUNCTION_INFO_V1(plainto_tsquery_name);
+ PG_FUNCTION_INFO_V1(headline_byname);
+ PG_FUNCTION_INFO_V1(rank);
+ PG_FUNCTION_INFO_V1(rank_def);
+ PG_FUNCTION_INFO_V1(rank_cd);
+ PG_FUNCTION_INFO_V1(rank_cd_def);
+ PG_FUNCTION_INFO_V1(headline);
+ PG_FUNCTION_INFO_V1(headline_current);
+ PG_FUNCTION_INFO_V1(ts_stat);
+ PG_FUNCTION_INFO_V1(tsearch2);
+ 
+ 
+ /* 
+  * List of renamed functions in integrated fulltext API
+  */
+ 
+ WRAPPER_FUNCTION(lexize, ts_lexize)
+ WRAPPER_FUNCTION(parse, ts_parse_byid)
+ WRAPPER_FUNCTION(parse_byname, ts_parse_byname)
+ WRAPPER_FUNCTION(token_type_byname, ts_token_type_byname)
+ WRAPPER_FUNCTION(token_type, ts_token_type_byid)
+ WRAPPER_FUNCTION(tsvector_length, tsvector_length)
+ WRAPPER_FUNCTION(to_tsvector, to_tsvector_byid)
+ WRAPPER_FUNCTION(to_tsvector_current, to_tsvector)
+ WRAPPER_FUNCTION(strip, tsvector_strip)
+ WRAPPER_FUNCTION(setweight, tsvector_setweight)
+ WRAPPER_FUNCTION(concat, tsvector_concat)
+ WRAPPER_FUNCTION(tsquerytree, tsquerytree) 
+ WRAPPER_FUNCTION(to_tsquery, to_tsquery_byid)
+ WRAPPER_FUNCTION(to_tsquery_current, to_tsquery)
+ WRAPPER_FUNCTION(plainto_tsquery, plainto_tsquery_byid)
+ WRAPPER_FUNCTION(plainto_tsquery_current, plainto_tsquery)
+ WRAPPER_FUNCTION(exectsq, ts_match_vq)
+ WRAPPER_FUNCTION(rexectsq, ts_match_qv)
+ WRAPPER_FUNCTION(tsquery_rewrite_query, tsquery_rewrite_query)
+ 
+ 
+ /*
+  * Listr of unsupported functions in public schema (traps)
+  */
+ 
+ UNSUPPORTED_FUNCTION(dex_init)
+ UNSUPPORTED_FUNCTION(dex_lexize)
+ 
+ UNSUPPORTED_FUNCTION(snb_en_init)
+ UNSUPPORTED_FUNCTION(snb_lexize)
+ UNSUPPORTED_FUNCTION(snb_ru_init_koi8)
+ UNSUPPORTED_FUNCTION(snb_ru_init_utf8)
+ UNSUPPORTED_FUNCTION(spell_init)
+ UNSUPPORTED_FUNCTION(spell_lexize)
+ UNSUPPORTED_FUNCTION(syn_init)
+ UNSUPPORTED_FUNCTION(syn_lexize)
+ UNSUPPORTED_FUNCTION(thesaurus_init)
+ UNSUPPORTED_FUNCTION(thesaurus_lexize)
+ 
+ UNSUPPORTED_FUNCTION(prsd_start)
+ UNSUPPORTED_FUNCTION(prsd_getlexeme)
+ UNSUPPORTED_FUNCTION(prsd_end)
+ UNSUPPORTED_FUNCTION(prsd_lextype)
+ UNSUPPORTED_FUNCTION(prsd_headline)
+ 
+ UNSUPPORTED_FUNCTION(tsvector_in)
+ UNSUPPORTED_FUNCTION(tsvector_out)
+ UNSUPPORTED_FUNCTION(tsquery_in)
+ UNSUPPORTED_FUNCTION(tsquery_out)
+ 
+ UNSUPPORTED_FUNCTION(gtsvector_in)
+ UNSUPPORTED_FUNCTION(gtsvector_out)
+ 
+ UNSUPPORTED_FUNCTION(gtsvector_consistent)
+ UNSUPPORTED_FUNCTION(gtsvector_compress)
+ UNSUPPORTED_FUNCTION(gtsvector_decompress)
+ UNSUPPORTED_FUNCTION(gtsvector_penalty)
+ UNSUPPORTED_FUNCTION(gtsvector_picksplit)
+ UNSUPPORTED_FUNCTION(gtsvector_union)
+ UNSUPPORTED_FUNCTION(gtsvector_same)
+ 
+ UNSUPPORTED_FUNCTION(reset_tsearch)
+ UNSUPPORTED_FUNCTION(get_covers)
+ 
+ UNSUPPORTED_FUNCTION(tsvector_cmp)
+ UNSUPPORTED_FUNCTION(tsvector_lt)
+ UNSUPPORTED_FUNCTION(tsvector_le)
+ UNSUPPORTED_FUNCTION(tsvector_eq)
+ UNSUPPORTED_FUNCTION(tsvector_ge)
+ UNSUPPORTED_FUNCTION(tsvector_gt)
+ UNSUPPORTED_FUNCTION(tsvector_ne)
+ 
+ UNSUPPORTED_FUNCTION(tsquery_cmp)
+ UNSUPPORTED_FUNCTION(tsquery_lt)
+ UNSUPPORTED_FUNCTION(tsquery_le)
+ UNSUPPORTED_FUNCTION(tsquery_eq)
+ UNSUPPORTED_FUNCTION(tsquery_ge)
+ UNSUPPORTED_FUNCTION(tsquery_gt)
+ UNSUPPORTED_FUNCTION(tsquery_ne)
+ 
+ UNSUPPORTED_FUNCTION(tsquery_numnode)
+ UNSUPPORTED_FUNCTION(tsquery_or)
+ UNSUPPORTED_FUNCTION(tsquery_and)
+ UNSUPPORTED_FUNCTION(tsquery_not)
+ 
+ UNSUPPORTED_FUNCTION(tsq_mcontains)
+ UNSUPPORTED_FUNCTION(tsq_mcontained)
+ 
+ UNSUPPORTED_FUNCTION(gtsq_in)
+ UNSUPPORTED_FUNCTION(gtsq_out)
+ 
+ UNSUPPORTED_FUNCTION(gtsq_consistent)
+ UNSUPPORTED_FUNCTION(gtsq_compress)
+ UNSUPPORTED_FUNCTION(gtsq_decompress)
+ UNSUPPORTED_FUNCTION(gtsq_penalty)
+ UNSUPPORTED_FUNCTION(gtsq_picksplit)
+ UNSUPPORTED_FUNCTION(gtsq_union)
+ UNSUPPORTED_FUNCTION(gtsq_same)
+ 
+ UNSUPPORTED_FUNCTION(gin_extract_tsvector)
+ UNSUPPORTED_FUNCTION(gin_extract_tsquery)
+ UNSUPPORTED_FUNCTION(gin_ts_consistent)
+ 
+ /* have to check, are really unsupported ?*/
+ UNSUPPORTED_FUNCTION(tsquery_rewrite)
+ UNSUPPORTED_FUNCTION(rewrite_accum)
+ UNSUPPORTED_FUNCTION(rewrite_finish)
+ 
+ 
+ /*
+  * list of redefined functions
+  */ 
+ 
+ /* lexize(text, text) */
+ Datum 
+ lexize_byname(PG_FUNCTION_ARGS)
+ {
+ 	text *dictname = PG_GETARG_TEXT_P(0);
+ 	Datum arg1 = PG_GETARG_DATUM(1);
+ 
+ 	return DirectFunctionCall2(ts_lexize, 
+ 							   ObjectIdGetDatum(TextGetObjectId(regdictionaryin, dictname)), 
+ 							   arg1);
+ }
+ 
+ /* lexize(text) */
+ Datum 
+ lexize_bycurrent(PG_FUNCTION_ARGS)
+ {
+ 	Datum arg0 = PG_GETARG_DATUM(0);
+ 	Oid id = GetCurrentDict();
+ 	
+ 	return DirectFunctionCall2(ts_lexize, 
+ 							   ObjectIdGetDatum(id), 
+ 							   arg0);
+ }
+ 
+ /* set_curdict(int) */
+ Datum
+ set_curdict(PG_FUNCTION_ARGS)
+ {
+ 	Oid dict_oid = PG_GETARG_OID(0);
+ 	void *plan;
+ 	Oid	argtypes[1] = {OIDOID};
+ 	Datum	pars[1];
+ 
+ 	pars[0] = ObjectIdGetDatum(dict_oid);
+ 
+ 	SPI_connect();
+ 	
+ 	if (!(plan = SPI_prepare("SELECT 1 FROM pg_catalog.pg_ts_dict WHERE oid = $1", 1, argtypes)))
+ 		ereport(ERROR,
+ 			(errcode(ERRCODE_INTERNAL_ERROR),
+ 			 errmsg("SPI_prepare() failed")));
+ 			 
+ 	if (SPI_OK_SELECT != SPI_execp(plan, pars, " ", 1))
+ 		ereport(ERROR,
+ 			(errcode(ERRCODE_INTERNAL_ERROR),
+ 			 errmsg("SPI_execp() failed")));
+ 			 
+ 	if (SPI_processed == 0)
+ 		ereport(ERROR,
+ 			(errcode(ERRCODE_INVALID_PARAMETER_VALUE),
+ 			 errmsg("No dictionary with id %d", dict_oid)));
+ 			 
+ 	SPI_freeplan(plan);
+ 	SPI_finish();
+ 	
+ 	current_dictionary_oid = dict_oid;
+ 	
+ 	PG_RETURN_VOID();
+ }	
+ 
+ /* set_curdict(text) */
+ Datum
+ set_curdict_byname(PG_FUNCTION_ARGS)
+ {
+ 	text *name = PG_GETARG_TEXT_P(0);
+ 	void *plan;
+ 	Oid argtypes[1] = {TEXTOID};
+ 	Datum pars[1];
+ 	bool isnull;
+ 	Oid dict_oid = InvalidOid;
+ 	
+ 	SPI_connect();
+ 	pars[0] = PointerGetDatum(name);
+ 	
+ 	if (!(plan = SPI_prepare("SELECT oid FROM pg_catalog.pg_ts_dict WHERE dictname = $1", 1, argtypes)))
+ 		ereport(ERROR,
+ 			(errcode(ERRCODE_INTERNAL_ERROR),
+ 			 errmsg("SPI_prepare() failed")));
+ 			 
+ 	if (SPI_OK_SELECT != SPI_execp(plan, pars, " ", 1))
+ 		ereport(ERROR,
+ 			(errcode(ERRCODE_INTERNAL_ERROR),
+ 			 errmsg("SPI_execp() failed")));
+ 			 
+ 	if (SPI_processed > 0)
+ 		dict_oid = DatumGetObjectId(SPI_getbinval(SPI_tuptable->vals[0],
+ 							SPI_tuptable->tupdesc, 1, &isnull));
+ 	else		 
+ 		ereport(ERROR,
+ 			(errcode(ERRCODE_INVALID_PARAMETER_VALUE),
+ 			 errmsg("No dictionary with name %s", TextPGetCString(name))));
+ 			 
+ 	SPI_freeplan(plan);
+ 	SPI_finish();
+ 	
+ 	current_dictionary_oid = dict_oid;
+ 	
+ 	PG_RETURN_VOID();
+ }
+ 
+ /* token_type() */
+ Datum 
+ token_type_current(PG_FUNCTION_ARGS)
+ {
+ 	INSERT_ARGUMENT(ObjectIdGetDatum(GetCurrentParser()), false)
+ 	return (ts_token_type_byid)(fcinfo);
+ }
+ 
+ /* set_curprs(int) */
+ Datum
+ set_curprs(PG_FUNCTION_ARGS)
+ {
+ 	Oid parser_oid = PG_GETARG_OID(0);
+ 	void *plan;
+ 	Oid	argtypes[1] = {OIDOID};
+ 	Datum	pars[1];
+ 
+ 	pars[0] = ObjectIdGetDatum(parser_oid);
+ 
+ 	SPI_connect();
+ 	
+ 	if (!(plan = SPI_prepare("SELECT 1 FROM pg_catalog.pg_ts_parser WHERE oid = $1", 1, argtypes)))
+ 		ereport(ERROR,
+ 			(errcode(ERRCODE_INTERNAL_ERROR),
+ 			 errmsg("SPI_prepare() failed")));
+ 			 
+ 	if (SPI_OK_SELECT != SPI_execp(plan, pars, " ", 1))
+ 		ereport(ERROR,
+ 			(errcode(ERRCODE_INTERNAL_ERROR),
+ 			 errmsg("SPI_execp() failed")));
+ 			 
+ 	if (SPI_processed == 0)
+ 		ereport(ERROR,
+ 			(errcode(ERRCODE_INVALID_PARAMETER_VALUE),
+ 			 errmsg("No paser with id %d", parser_oid)));
+ 			 
+ 	SPI_freeplan(plan);
+ 	SPI_finish();
+ 	
+ 	current_parser_oid = parser_oid;
+ 	
+ 	PG_RETURN_VOID();
+ }
+ 
+ /* set_curprs(text) */
+ Datum
+ set_curprs_byname(PG_FUNCTION_ARGS)
+ {
+ 	text *name = PG_GETARG_TEXT_P(0);
+ 	void *plan;
+ 	Oid argtypes[1] = {TEXTOID};
+ 	Datum pars[1];
+ 	bool isnull;
+ 	Oid parser_oid = InvalidOid;
+ 	
+ 	SPI_connect();
+ 	pars[0] = PointerGetDatum(name);
+ 	
+ 	if (!(plan = SPI_prepare("SELECT oid FROM pg_catalog.pg_ts_parser WHERE prsname = $1", 1, argtypes)))
+ 		ereport(ERROR,
+ 			(errcode(ERRCODE_INTERNAL_ERROR),
+ 			 errmsg("SPI_prepare() failed")));
+ 			 
+ 	if (SPI_OK_SELECT != SPI_execp(plan, pars, " ", 1))
+ 		ereport(ERROR,
+ 			(errcode(ERRCODE_INTERNAL_ERROR),
+ 			 errmsg("SPI_execp() failed")));
+ 			 
+ 	if (SPI_processed > 0)
+ 		parser_oid = DatumGetObjectId(SPI_getbinval(SPI_tuptable->vals[0],
+ 							SPI_tuptable->tupdesc, 1, &isnull));
+ 	else		 
+ 		ereport(ERROR,
+ 			(errcode(ERRCODE_INVALID_PARAMETER_VALUE),
+ 			 errmsg("No parser with name %s", TextPGetCString(name))));
+ 			 
+ 	SPI_freeplan(plan);
+ 	SPI_finish();
+ 	
+ 	current_parser_oid = parser_oid;
+ 	
+ 	PG_RETURN_VOID();
+ }
+ 
+ /* parse(text) */
+ Datum
+ parse_current(PG_FUNCTION_ARGS)
+ {
+ 	INSERT_ARGUMENT(ObjectIdGetDatum(GetCurrentParser()), false);
+ 	return (ts_parse_byid)(fcinfo);
+ }
+ 
+ /* set_curcfg(int) */
+ Datum
+ set_curcfg(PG_FUNCTION_ARGS)
+ {
+ 	Oid arg0 = PG_GETARG_OID(0);
+ 	char *name;
+ 	
+ 	name = DatumGetCString(DirectFunctionCall1(regconfigout, ObjectIdGetDatum(arg0)));							
+ 								
+ 	set_config_option("default_text_search_config", name,
+ 				(superuser() ? PGC_SUSET : PGC_USERSET),
+ 				PGC_S_SESSION,
+ 				GUC_ACTION_SET,
+ 				true);
+ 
+ 	PG_RETURN_VOID();
+ }
+ 
+ /* set_curcfg(text) */
+ Datum
+ set_curcfg_byname(PG_FUNCTION_ARGS)
+ {
+ 	text *arg0 = PG_GETARG_TEXT_P(0);
+ 	char *name;
+ 	
+ 	name = TextPGetCString(arg0);
+ 	set_config_option("default_text_search_config", name,
+ 				(superuser() ? PGC_SUSET : PGC_USERSET),
+ 				PGC_S_SESSION,
+ 				GUC_ACTION_SET,
+ 				true);
+ 
+ 	PG_RETURN_VOID();
+ }
+ 
+ /* show_curcfg() */
+ Datum
+ show_curcfg(PG_FUNCTION_ARGS)
+ {
+ 	char *cfgname;
+ 	Oid config_oid;
+ 	
+ 	cfgname = GetConfigOptionByName("default_text_search_config", NULL);
+ 	config_oid = DatumGetObjectId(DirectFunctionCall1(regconfigin, CStringGetDatum(cfgname)));
+ 	
+ 	PG_RETURN_OID(config_oid);
+ }
+ 
+ /* to_tsvector(text, text) */
+ Datum
+ to_tsvector_name(PG_FUNCTION_ARGS)
+ {
+ 	text *cfgname = PG_GETARG_TEXT_P(0);
+ 	Datum arg1 = PG_GETARG_DATUM(1);
+ 	Oid config_oid;
+ 		
+ 	config_oid = TextGetObjectId(regconfigin, cfgname);
+ 
+ 	return DirectFunctionCall2(to_tsvector_byid, ObjectIdGetDatum(config_oid), arg1);
+ }
+ 
+ /* to_tsquery(text, text) */
+ Datum
+ to_tsquery_name(PG_FUNCTION_ARGS)
+ {
+ 	text *cfgname = PG_GETARG_TEXT_P(0);
+ 	Datum arg1 = PG_GETARG_DATUM(1);
+ 	Oid config_oid;
+ 		
+     	config_oid = TextGetObjectId(regconfigin, cfgname);
+ 	
+ 	return DirectFunctionCall2(to_tsquery_byid, ObjectIdGetDatum(config_oid), arg1);
+ }
+ 
+ 
+ /* plainto_tsquery(text, text) */
+ Datum
+ plainto_tsquery_name(PG_FUNCTION_ARGS)
+ {
+ 	text *cfgname = PG_GETARG_TEXT_P(0);
+ 	Datum arg1 = PG_GETARG_DATUM(1);
+ 	Oid config_oid;
+ 		
+ 	config_oid = TextGetObjectId(regconfigin, cfgname);
+ 
+ 	return DirectFunctionCall2(plainto_tsquery_byid, ObjectIdGetDatum(config_oid), arg1);
+ }
+ 
+ /* rank(float4[], tsvector, tsquery [,int4]) */
+ Datum 
+ rank(PG_FUNCTION_ARGS)
+ {
+ 	Datum arg0 = PG_GETARG_DATUM(0);
+ 	Datum arg1 = PG_GETARG_DATUM(1);
+ 	Datum arg2 = PG_GETARG_DATUM(2);
+ 	Datum arg3;
+ 	
+ 	Datum result;
+ 	
+ 	if (PG_NARGS() == 3)
+ 		result = DirectFunctionCall3(ts_rank_wtt, arg0, arg1, arg2);	
+ 	else
+ 	{
+ 		arg3 = PG_GETARG_DATUM(3);
+ 		result = DirectFunctionCall4(ts_rank_wttf, arg0, arg1, arg2, arg3);
+ 	}
+ 	
+ 	return result;
+ }
+ 
+ 
+ /* rank(tsvector, tsquery [,int]) */
+ Datum 
+ rank_def(PG_FUNCTION_ARGS)
+ {
+ 	Datum arg0 = PG_GETARG_DATUM(0);
+ 	Datum arg1 = PG_GETARG_DATUM(1);
+ 	Datum arg2;
+ 	
+ 	Datum result;
+ 	
+ 	if (PG_NARGS() == 2)
+ 		result = DirectFunctionCall2(ts_rank_tt, arg0, arg1);	
+ 	else
+ 	{
+ 		arg2 = PG_GETARG_DATUM(2);
+ 		result = DirectFunctionCall3(ts_rank_ttf, arg0, arg1, arg2);
+ 	}
+ 	
+ 	return result;
+ }
+ 
+ /* rank_cd(float4[], tsvector, tsquery, [int4]) */
+ Datum 
+ rank_cd(PG_FUNCTION_ARGS)
+ {
+ 	Datum arg0 = PG_GETARG_DATUM(0);
+ 	Datum arg1 = PG_GETARG_DATUM(1);
+ 	Datum arg2 = PG_GETARG_DATUM(2);
+ 	Datum arg3;
+ 	
+ 	Datum result;
+ 	
+ 	if (PG_NARGS() == 3)
+ 		result = DirectFunctionCall3(ts_rankcd_wtt, arg0, arg1, arg2);	
+ 	else
+ 	{
+ 		arg3 = PG_GETARG_DATUM(3);
+ 		result = DirectFunctionCall4(ts_rankcd_wttf, arg0, arg1, arg2, arg3);
+ 	}
+ 	
+ 	return result;
+ }
+ 
+ /* rank_cd(tsvector, tsquery [,int4]) */
+ Datum 
+ rank_cd_def(PG_FUNCTION_ARGS)
+ {
+ 	Datum arg0 = PG_GETARG_DATUM(0);
+ 	Datum arg1 = PG_GETARG_DATUM(1);
+ 	Datum arg2;
+ 	
+ 	Datum result;
+ 	
+ 	if (PG_NARGS() == 2)
+ 		result = DirectFunctionCall2(ts_rankcd_tt, arg0, arg1);	
+ 	else
+ 	{
+ 		arg2 = PG_GETARG_DATUM(2);
+ 		result = DirectFunctionCall3(ts_rankcd_ttf, arg0, arg1, arg2);
+ 	}
+ 	
+ 	return result;
+ }
+ 
+ /* headline(oid, text, tsquery [,text]) */
+ Datum 
+ headline(PG_FUNCTION_ARGS)
+ {
+ 	Datum arg0 = PG_GETARG_DATUM(0);
+ 	Datum arg1 = PG_GETARG_DATUM(1);
+ 	Datum arg2 = PG_GETARG_DATUM(2);
+ 	Datum arg3;
+ 	Datum result;
+ 	
+ 	if (PG_NARGS() == 3)
+ 		result = DirectFunctionCall3(ts_headline_byid, arg0, arg1, arg2);
+ 	else
+ 	{
+ 		arg3 = PG_GETARG_DATUM(3);
+ 		result = DirectFunctionCall4(ts_headline_byid_opt, arg0, arg1, arg2, arg3);
+ 	}
+ 	
+ 	return result;
+ }
+ 
+ /* headline(text, text, tsquery [,text]) */
+ Datum 
+ headline_byname(PG_FUNCTION_ARGS)
+ {
+ 	Datum arg0 = PG_GETARG_DATUM(0);
+ 	Datum arg1 = PG_GETARG_DATUM(1);
+ 	Datum arg2 = PG_GETARG_DATUM(2);
+ 	Datum arg3;
+ 	Datum result;
+ 	Oid config_oid;
+ 
+ 	/* first parameter have to be converted to oid */
+ 	config_oid = DatumGetObjectId(DirectFunctionCall1(regconfigin, DirectFunctionCall1(textout, arg0)));
+ 	
+ 	if (PG_NARGS() == 3)
+ 		result = DirectFunctionCall3(ts_headline_byid, ObjectIdGetDatum(config_oid), arg1, arg2);
+ 	else
+ 	{
+ 		arg3 = PG_GETARG_DATUM(3);
+ 		result = DirectFunctionCall4(ts_headline_byid_opt, ObjectIdGetDatum(config_oid), 
+ 							arg1, arg2, arg3);
+ 	}
+ 	
+ 	return result;
+ 
+ }
+ 
+ /* headline(text, tsquery [,text]) */
+ Datum 
+ headline_current(PG_FUNCTION_ARGS)
+ {
+ 	Datum arg0 = PG_GETARG_DATUM(0);
+ 	Datum arg1 = PG_GETARG_DATUM(1);
+ 	Datum arg2;
+ 	Datum result;
+ 	
+ 	if (PG_NARGS() == 2)
+ 		result = DirectFunctionCall2(ts_headline, arg0, arg1);
+ 	else
+ 	{
+ 		arg2 = PG_GETARG_DATUM(2);
+ 		result = DirectFunctionCall3(ts_headline_opt, arg0, arg1, arg2);
+ 	}
+ 	
+ 	return result;
+ }
+ 
+ /* stat(text [,text]) */
+ Datum
+ ts_stat(PG_FUNCTION_ARGS)
+ {
+ 	Datum arg0 = PG_GETARG_DATUM(0);
+ 	Datum arg1;
+ 	Datum result;
+ 	
+ 	if (PG_NARGS() == 1)
+ 		result = DirectFunctionCall1(ts_stat1, arg0);
+ 	else
+ 	{
+ 		arg1 = PG_GETARG_DATUM(1);
+ 		result = DirectFunctionCall2(ts_stat2, arg0, arg1);
+ 	}
+ 
+ 	return result;
+ }
+ 
+ /*
+  * tsearch2 implementation, update trigger - it's use default configuration
+  * for tsvector_update_trigger_by_id call is necessary insert on second pos
+  * oid of current configuration.
+  */
+ Datum
+ tsearch2(PG_FUNCTION_ARGS)
+ {
+ 	TriggerData *trigdata;
+ 	Trigger    *trigger;
+ 	int			i;
+ 	char **tgargs;
+ 
+ 	/* Check call context */
+ 	if (!CALLED_AS_TRIGGER(fcinfo))	/* internal error */
+ 		elog(ERROR, "tsvector_update_trigger: not fired by trigger manager");
+ 
+ 	trigdata = (TriggerData *) fcinfo->context;
+ 	if (TRIGGER_FIRED_FOR_STATEMENT(trigdata->tg_event))
+ 		elog(ERROR, "tsvector_update_trigger: can't process STATEMENT events");
+ 	if (TRIGGER_FIRED_AFTER(trigdata->tg_event))
+ 		elog(ERROR, "tsvector_update_trigger: must be fired BEFORE event");
+ 
+ 	if (!TRIGGER_FIRED_BY_INSERT(trigdata->tg_event) &&
+ 		!TRIGGER_FIRED_BY_UPDATE(trigdata->tg_event))
+ 		elog(ERROR, "tsvector_update_trigger: must be fired for INSERT or UPDATE");
+ 
+ 	trigger = trigdata->tg_trigger;
+ 	if (trigger->tgnargs < 2)
+ 		/* internal error */
+ 		elog(ERROR, "TSearch: format tsearch2(tsvector_field, text_field1,...)");
+ 
+ 	tgargs = (char **) palloc((trigger->tgnargs + 1) * sizeof(char *));
+ 	/* create space for configuration name */
+ 	tgargs[0] = trigger->tgargs[0]; 
+ 
+ 	for (i = 1; i < trigger->tgnargs; i++)
+ 	{
+ 		tgargs[i+1] = trigger->tgargs[i];
+ 	}
+ 	
+ 	tgargs[1] = pstrdup(GetConfigOptionByName("default_text_search_config", NULL));
+ 
+ 	pfree(trigger->tgargs);
+ 	trigger->tgargs = tgargs;
+ 	trigger->tgnargs += 1;
+ 
+         return (tsvector_update_trigger_byid)(fcinfo);
+ }
+ 
+ /* 
+  * Get Oid of current dictionary and check if is valid 
+  */
+ static Oid
+ GetCurrentDict(void)
+ {
+ 	if (current_dictionary_oid == InvalidOid)
+ 		ereport(ERROR,
+ 			(errcode(ERRCODE_INVALID_PARAMETER_VALUE),
+ 			 errmsg("no current dictionary"),
+ 			 errhint("Execute select set_curdict()")));
+ 
+ 	return current_dictionary_oid;
+ }
+ 
+ /*
+  * find default parser
+  */
+ static Oid
+ GetCurrentParser(void)
+ {
+ 	if (current_parser_oid == InvalidOid)
+ 	{
+ 		/* search oid for 'default' parser */
+ 		void *plan;
+ 		bool isnull;
+ 		Oid parser_oid = InvalidOid;
+ 	
+ 		SPI_connect();
+ 	
+ 		if (!(plan = SPI_prepare("SELECT oid FROM pg_catalog.pg_ts_parser WHERE prsname = 'default'", 0, NULL)))
+ 			ereport(ERROR,
+ 				(errcode(ERRCODE_INTERNAL_ERROR),
+ 				 errmsg("SPI_prepare() failed")));
+ 			 
+ 		if (SPI_OK_SELECT != SPI_execp(plan, NULL, "", 0))
+ 			ereport(ERROR,
+ 				(errcode(ERRCODE_INTERNAL_ERROR),
+ 				 errmsg("SPI_execp() failed")));
+ 			 
+ 		if (SPI_processed > 0)
+ 			parser_oid = DatumGetObjectId(SPI_getbinval(SPI_tuptable->vals[0],
+ 							SPI_tuptable->tupdesc, 1, &isnull));
+ 		else		 
+ 			ereport(ERROR,
+ 				(errcode(ERRCODE_INVALID_PARAMETER_VALUE),
+ 				 errmsg("No default parser")));
+ 			 
+ 		SPI_freeplan(plan);
+ 		SPI_finish();
+ 		
+ 		return parser_oid;
+ 	}
+ 	else
+ 		return current_parser_oid;
+ }
---------------------------(end of broadcast)---------------------------
TIP 2: Don't 'kill -9' the postmaster

Reply via email to