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