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-10 00:40:30.000000000 +0100 *************** *** 0 **** --- 1,738 ---- + SET search_path = public, pg_catalog; + + BEGIN; + + --dict interface + CREATE FUNCTION lexize(oid, text) + RETURNS _text + as 'MODULE_PATHNAME', 'tsa_lexize' + LANGUAGE C + RETURNS NULL ON NULL INPUT; + + CREATE FUNCTION lexize(text, text) + RETURNS _text + as 'MODULE_PATHNAME', 'tsa_lexize_byname' + LANGUAGE C + RETURNS NULL ON NULL INPUT; + + CREATE FUNCTION lexize(text) + RETURNS _text + as 'MODULE_PATHNAME', 'tsa_lexize_bycurrent' + LANGUAGE C + RETURNS NULL ON NULL INPUT; + + CREATE FUNCTION set_curdict(int) + RETURNS void + as 'MODULE_PATHNAME', 'tsa_set_curdict' + LANGUAGE C + RETURNS NULL ON NULL INPUT; + + CREATE FUNCTION set_curdict(text) + RETURNS void + as 'MODULE_PATHNAME', 'tsa_set_curdict_byname' + LANGUAGE C + RETURNS NULL ON NULL INPUT; + + --built-in dictionaries + CREATE FUNCTION dex_init(internal) + RETURNS internal + as 'MODULE_PATHNAME', 'tsa_dex_init' + LANGUAGE C; + + CREATE FUNCTION dex_lexize(internal,internal,int4) + RETURNS internal + as 'MODULE_PATHNAME', 'tsa_dex_lexize' + LANGUAGE C + RETURNS NULL ON NULL INPUT; + + CREATE FUNCTION snb_en_init(internal) + RETURNS internal + as 'MODULE_PATHNAME', 'tsa_snb_en_init' + LANGUAGE C; + + CREATE FUNCTION snb_lexize(internal,internal,int4) + RETURNS internal + as 'MODULE_PATHNAME', 'tsa_snb_lexize' + LANGUAGE C + RETURNS NULL ON NULL INPUT; + + CREATE FUNCTION snb_ru_init_koi8(internal) + RETURNS internal + as 'MODULE_PATHNAME', 'tsa_snb_ru_init_koi8' + LANGUAGE C; + + CREATE FUNCTION snb_ru_init_utf8(internal) + RETURNS internal + as 'MODULE_PATHNAME', 'tsa_snb_ru_init_utf8' + LANGUAGE C; + + CREATE FUNCTION spell_init(internal) + RETURNS internal + as 'MODULE_PATHNAME', 'tsa_spell_init' + LANGUAGE C; + + CREATE FUNCTION spell_lexize(internal,internal,int4) + RETURNS internal + as 'MODULE_PATHNAME', 'tsa_spell_lexize' + LANGUAGE C + RETURNS NULL ON NULL INPUT; + + CREATE FUNCTION syn_init(internal) + RETURNS internal + as 'MODULE_PATHNAME', 'tsa_syn_init' + LANGUAGE C; + + CREATE FUNCTION syn_lexize(internal,internal,int4) + RETURNS internal + as 'MODULE_PATHNAME', 'tsa_syn_lexize' + LANGUAGE C + RETURNS NULL ON NULL INPUT; + + CREATE FUNCTION thesaurus_init(internal) + RETURNS internal + as 'MODULE_PATHNAME', 'tsa_thesaurus_init' + LANGUAGE C; + + CREATE FUNCTION thesaurus_lexize(internal,internal,int4,internal) + RETURNS internal + as 'MODULE_PATHNAME', 'tsa_thesaurus_lexize' + 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', 'tsa_token_type' + LANGUAGE C + RETURNS NULL ON NULL INPUT; + + CREATE FUNCTION token_type(text) + RETURNS setof tokentype + as 'MODULE_PATHNAME', 'tsa_token_type_byname' + LANGUAGE C + RETURNS NULL ON NULL INPUT; + + CREATE FUNCTION token_type() + RETURNS setof tokentype + as 'MODULE_PATHNAME', 'tsa_token_type_current' + LANGUAGE C + RETURNS NULL ON NULL INPUT; + + CREATE FUNCTION set_curprs(int) + RETURNS void + as 'MODULE_PATHNAME', 'tsa_set_curprs' + LANGUAGE C + RETURNS NULL ON NULL INPUT; + + CREATE FUNCTION set_curprs(text) + RETURNS void + as 'MODULE_PATHNAME', 'tsa_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', 'tsa_parse' + LANGUAGE C + RETURNS NULL ON NULL INPUT; + + CREATE FUNCTION parse(text,text) + RETURNS setof tokenout + as 'MODULE_PATHNAME', 'tsa_parse_byname' + LANGUAGE C + RETURNS NULL ON NULL INPUT; + + CREATE FUNCTION parse(text) + RETURNS setof tokenout + as 'MODULE_PATHNAME', 'tsa_parse_current' + LANGUAGE C + RETURNS NULL ON NULL INPUT; + + --default parser + CREATE FUNCTION prsd_start(internal,int4) + RETURNS internal + as 'MODULE_PATHNAME', 'tsa_prsd_start' + LANGUAGE C; + + CREATE FUNCTION prsd_getlexeme(internal,internal,internal) + RETURNS int4 + as 'MODULE_PATHNAME', 'tsa_prsd_getlexeme' + LANGUAGE C; + + CREATE FUNCTION prsd_end(internal) + RETURNS void + as 'MODULE_PATHNAME', 'tsa_prsd_end' + LANGUAGE C; + + CREATE FUNCTION prsd_lextype(internal) + RETURNS internal + as 'MODULE_PATHNAME', 'tsa_prsd_lextype' + LANGUAGE C; + + CREATE FUNCTION prsd_headline(internal,internal,internal) + RETURNS internal + as 'MODULE_PATHNAME', 'tsa_prsd_headline' + LANGUAGE C; + + --tsearch config + CREATE FUNCTION set_curcfg(int) + RETURNS void + as 'MODULE_PATHNAME', 'tsa_set_curcfg' + LANGUAGE C + RETURNS NULL ON NULL INPUT; + + CREATE FUNCTION set_curcfg(text) + RETURNS void + as 'MODULE_PATHNAME', 'tsa_set_curcfg_byname' + LANGUAGE C + RETURNS NULL ON NULL INPUT; + + CREATE FUNCTION show_curcfg() + RETURNS oid + as 'MODULE_PATHNAME', 'tsa_show_curcfg' + LANGUAGE C + RETURNS NULL ON NULL INPUT; + + CREATE FUNCTION tsvector_in(cstring) + RETURNS tsvector + AS 'MODULE_PATHNAME', 'tsa_tsvector_in' + LANGUAGE C RETURNS NULL ON NULL INPUT; + + CREATE FUNCTION tsvector_out(tsvector) + RETURNS cstring + AS 'MODULE_PATHNAME', 'tsa_tsvector_out' + LANGUAGE C RETURNS NULL ON NULL INPUT; + + CREATE FUNCTION length(tsvector) + RETURNS int4 + AS 'MODULE_PATHNAME', 'tsa_tsvector_length' + LANGUAGE C RETURNS NULL ON NULL INPUT IMMUTABLE; + + CREATE FUNCTION to_tsvector(oid, text) + RETURNS tsvector + AS 'MODULE_PATHNAME', 'tsa_to_tsvector' + LANGUAGE C RETURNS NULL ON NULL INPUT IMMUTABLE; + + CREATE FUNCTION to_tsvector(text, text) + RETURNS tsvector + AS 'MODULE_PATHNAME', 'tsa_to_tsvector_name' + LANGUAGE C RETURNS NULL ON NULL INPUT IMMUTABLE; + + CREATE FUNCTION to_tsvector(text) + RETURNS tsvector + AS 'MODULE_PATHNAME', 'tsa_to_tsvector_current' + LANGUAGE C RETURNS NULL ON NULL INPUT IMMUTABLE; + + CREATE FUNCTION strip(tsvector) + RETURNS tsvector + AS 'MODULE_PATHNAME', 'tsa_strip' + LANGUAGE C RETURNS NULL ON NULL INPUT IMMUTABLE; + + CREATE FUNCTION setweight(tsvector,"char") + RETURNS tsvector + AS 'MODULE_PATHNAME', 'tsa_setweight' + LANGUAGE C RETURNS NULL ON NULL INPUT IMMUTABLE; + + CREATE FUNCTION concat(tsvector,tsvector) + RETURNS tsvector + AS 'MODULE_PATHNAME', 'tsa_concat' + LANGUAGE C RETURNS NULL ON NULL INPUT IMMUTABLE; + + CREATE FUNCTION tsquery_in(cstring) + RETURNS tsquery + AS 'MODULE_PATHNAME', 'tsa_tsquery_in' + LANGUAGE C RETURNS NULL ON NULL INPUT; + + CREATE FUNCTION tsquery_out(tsquery) + RETURNS cstring + AS 'MODULE_PATHNAME', 'tsa_tsquery_out' + LANGUAGE C RETURNS NULL ON NULL INPUT; + + CREATE FUNCTION querytree(tsquery) + RETURNS text + AS 'MODULE_PATHNAME', 'tsa_tsquerytree' + LANGUAGE C RETURNS NULL ON NULL INPUT; + + CREATE FUNCTION to_tsquery(oid, text) + RETURNS tsquery + AS 'MODULE_PATHNAME', 'tsa_to_tsquery' + LANGUAGE C RETURNS NULL ON NULL INPUT IMMUTABLE; + + CREATE FUNCTION to_tsquery(text, text) + RETURNS tsquery + AS 'MODULE_PATHNAME','tsa_to_tsquery_name' + LANGUAGE C RETURNS NULL ON NULL INPUT IMMUTABLE; + + CREATE FUNCTION to_tsquery(text) + RETURNS tsquery + AS 'MODULE_PATHNAME','tsa_to_tsquery_current' + LANGUAGE C RETURNS NULL ON NULL INPUT IMMUTABLE; + + CREATE FUNCTION plainto_tsquery(oid, text) + RETURNS tsquery + AS 'MODULE_PATHNAME', 'tsa_plainto_tsquery' + LANGUAGE C RETURNS NULL ON NULL INPUT IMMUTABLE; + + CREATE FUNCTION plainto_tsquery(text, text) + RETURNS tsquery + AS 'MODULE_PATHNAME','tsa_plainto_tsquery_name' + LANGUAGE C RETURNS NULL ON NULL INPUT IMMUTABLE; + + CREATE FUNCTION plainto_tsquery(text) + RETURNS tsquery + AS 'MODULE_PATHNAME','tsa_plainto_tsquery_current' + LANGUAGE C RETURNS NULL ON NULL INPUT IMMUTABLE; + + --operations + CREATE FUNCTION exectsq(tsvector, tsquery) + RETURNS bool + AS 'MODULE_PATHNAME', 'tsa_exectsq' + LANGUAGE C RETURNS NULL ON NULL INPUT IMMUTABLE; + + CREATE FUNCTION rexectsq(tsquery, tsvector) + RETURNS bool + AS 'MODULE_PATHNAME', 'tsa_rexectsq' + LANGUAGE C RETURNS NULL ON NULL INPUT IMMUTABLE; + + --Trigger + CREATE FUNCTION tsearch2() + RETURNS trigger + AS 'MODULE_PATHNAME', 'tsa_tsearch2' + LANGUAGE C; + + --Relevation + CREATE FUNCTION rank(float4[], tsvector, tsquery) + RETURNS float4 + AS 'MODULE_PATHNAME', 'tsa_rank' + LANGUAGE C RETURNS NULL ON NULL INPUT IMMUTABLE; + + CREATE FUNCTION rank(float4[], tsvector, tsquery, int4) + RETURNS float4 + AS 'MODULE_PATHNAME', 'tsa_rank' + LANGUAGE C RETURNS NULL ON NULL INPUT IMMUTABLE; + + CREATE FUNCTION rank(tsvector, tsquery) + RETURNS float4 + AS 'MODULE_PATHNAME', 'tsa_rank_def' + LANGUAGE C RETURNS NULL ON NULL INPUT IMMUTABLE; + + CREATE FUNCTION rank(tsvector, tsquery, int4) + RETURNS float4 + AS 'MODULE_PATHNAME', 'tsa_rank_def' + LANGUAGE C RETURNS NULL ON NULL INPUT IMMUTABLE; + + CREATE FUNCTION rank_cd(float4[], tsvector, tsquery) + RETURNS float4 + AS 'MODULE_PATHNAME', 'tsa_rank_cd' + LANGUAGE C RETURNS NULL ON NULL INPUT IMMUTABLE; + + CREATE FUNCTION rank_cd(float4[], tsvector, tsquery, int4) + RETURNS float4 + AS 'MODULE_PATHNAME', 'tsa_rank_cd' + LANGUAGE C RETURNS NULL ON NULL INPUT IMMUTABLE; + + CREATE FUNCTION rank_cd(tsvector, tsquery) + RETURNS float4 + AS 'MODULE_PATHNAME', 'tsa_rank_cd_def' + LANGUAGE C RETURNS NULL ON NULL INPUT IMMUTABLE; + + CREATE FUNCTION rank_cd(tsvector, tsquery, int4) + RETURNS float4 + AS 'MODULE_PATHNAME', 'tsa_rank_cd_def' + LANGUAGE C RETURNS NULL ON NULL INPUT IMMUTABLE; + + CREATE FUNCTION headline(oid, text, tsquery, text) + RETURNS text + AS 'MODULE_PATHNAME', 'tsa_headline' + LANGUAGE C RETURNS NULL ON NULL INPUT IMMUTABLE; + + CREATE FUNCTION headline(oid, text, tsquery) + RETURNS text + AS 'MODULE_PATHNAME', 'tsa_headline' + LANGUAGE C RETURNS NULL ON NULL INPUT IMMUTABLE; + + CREATE FUNCTION headline(text, text, tsquery, text) + RETURNS text + AS 'MODULE_PATHNAME', 'tsa_headline_byname' + LANGUAGE C RETURNS NULL ON NULL INPUT IMMUTABLE; + + CREATE FUNCTION headline(text, text, tsquery) + RETURNS text + AS 'MODULE_PATHNAME', 'tsa_headline_byname' + LANGUAGE C RETURNS NULL ON NULL INPUT IMMUTABLE; + + CREATE FUNCTION headline(text, tsquery, text) + RETURNS text + AS 'MODULE_PATHNAME', 'tsa_headline_current' + LANGUAGE C RETURNS NULL ON NULL INPUT IMMUTABLE; + + CREATE FUNCTION headline(text, tsquery) + RETURNS text + AS 'MODULE_PATHNAME', 'tsa_headline_current' + LANGUAGE C RETURNS NULL ON NULL INPUT IMMUTABLE; + + --GiST + --GiST key type + + CREATE FUNCTION gtsvector_in(cstring) + RETURNS gtsvector + AS 'MODULE_PATHNAME', 'tsa_gtsvector_in' + LANGUAGE C RETURNS NULL ON NULL INPUT; + + CREATE FUNCTION gtsvector_out(gtsvector) + RETURNS cstring + AS 'MODULE_PATHNAME', 'tsa_gtsvector_out' + LANGUAGE C RETURNS NULL ON NULL INPUT; + + -- support FUNCTIONs + CREATE FUNCTION gtsvector_consistent(gtsvector,internal,int4) + RETURNS bool + AS 'MODULE_PATHNAME', 'tsa_gtsvector_consistent' + LANGUAGE C; + + CREATE FUNCTION gtsvector_compress(internal) + RETURNS internal + AS 'MODULE_PATHNAME', 'tsa_gtsvector_compress' + LANGUAGE C; + + CREATE FUNCTION gtsvector_decompress(internal) + RETURNS internal + AS 'MODULE_PATHNAME', 'tsa_gtsvector_decompress' + LANGUAGE C; + + CREATE FUNCTION gtsvector_penalty(internal,internal,internal) + RETURNS internal + AS 'MODULE_PATHNAME', 'tsa_gtsvector_penalty' + LANGUAGE C RETURNS NULL ON NULL INPUT; + + CREATE FUNCTION gtsvector_picksplit(internal, internal) + RETURNS internal + AS 'MODULE_PATHNAME', 'tsa_gtsvector_picksplit' + LANGUAGE C; + + CREATE FUNCTION gtsvector_union(internal, internal) + RETURNS _int4 + AS 'MODULE_PATHNAME', 'tsa_gtsvector_union' + LANGUAGE C; + + CREATE FUNCTION gtsvector_same(gtsvector, gtsvector, internal) + RETURNS internal + AS 'MODULE_PATHNAME', 'tsa_gtsvector_same' + LANGUAGE C; + + --stat info + CREATE TYPE statinfo + as (word text, ndoc int4, nentry int4); + + --CREATE FUNCTION tsstat_in(cstring) + --RETURNS tsstat + --AS 'MODULE_PATHNAME', 'tsa_tsstat_in' + --LANGUAGE C RETURNS NULL ON NULL INPUT; + -- + --CREATE FUNCTION tsstat_out(tsstat) + --RETURNS cstring + --AS 'MODULE_PATHNAME', 'tsa_tsstat_out' + --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', 'tsa_ts_accum' + --LANGUAGE C RETURNS NULL ON NULL INPUT; + -- + --CREATE FUNCTION ts_accum_finish(tsstat) + -- RETURNS setof statinfo + -- as 'MODULE_PATHNAME', 'tsa_ts_accum_finish' + -- LANGUAGE C + -- RETURNS NULL ON NULL INPUT; + -- + --CREATE AGGREGATE stat ( + -- BASETYPE=tsvector, + -- SFUNC=ts_accum, + -- STYPE=tsstat, + -- FINALFUNC = ts_accum_finish, + -- initcond = 'tsa_ts_accum_finish' + --); + + CREATE FUNCTION stat(text) + RETURNS setof statinfo + as 'MODULE_PATHNAME', 'tsa_ts_stat' + LANGUAGE C + RETURNS NULL ON NULL INPUT; + + CREATE FUNCTION stat(text,text) + RETURNS setof statinfo + as 'MODULE_PATHNAME', 'tsa_ts_stat' + LANGUAGE C + RETURNS NULL ON NULL INPUT; + + --reset - just for debuging + CREATE FUNCTION reset_tsearch() + RETURNS void + as 'MODULE_PATHNAME', 'tsa_reset_tsearch' + LANGUAGE C + RETURNS NULL ON NULL INPUT; + + --get cover (debug for rank_cd) + CREATE FUNCTION get_covers(tsvector,tsquery) + RETURNS text + as 'MODULE_PATHNAME', 'tsa_get_covers' + 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', 'tsa_tsvector_cmp' + LANGUAGE C RETURNS NULL ON NULL INPUT IMMUTABLE; + + CREATE FUNCTION tsvector_lt(tsvector,tsvector) + RETURNS bool + AS 'MODULE_PATHNAME', 'tsa_tsvector_lt' + LANGUAGE C RETURNS NULL ON NULL INPUT IMMUTABLE; + + CREATE FUNCTION tsvector_le(tsvector,tsvector) + RETURNS bool + AS 'MODULE_PATHNAME', 'tsa_tsvector_le' + LANGUAGE C RETURNS NULL ON NULL INPUT IMMUTABLE; + + CREATE FUNCTION tsvector_eq(tsvector,tsvector) + RETURNS bool + AS 'MODULE_PATHNAME', 'tsa_tsvector_eq' + LANGUAGE C RETURNS NULL ON NULL INPUT IMMUTABLE; + + CREATE FUNCTION tsvector_ge(tsvector,tsvector) + RETURNS bool + AS 'MODULE_PATHNAME', 'tsa_tsvector_ge' + LANGUAGE C RETURNS NULL ON NULL INPUT IMMUTABLE; + + CREATE FUNCTION tsvector_gt(tsvector,tsvector) + RETURNS bool + AS 'MODULE_PATHNAME', 'tsa_tsvector_gt' + LANGUAGE C RETURNS NULL ON NULL INPUT IMMUTABLE; + + CREATE FUNCTION tsvector_ne(tsvector,tsvector) + RETURNS bool + AS 'MODULE_PATHNAME', 'tsa_tsvector_ne' + 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', 'tsa_tsquery_cmp' + LANGUAGE C RETURNS NULL ON NULL INPUT IMMUTABLE; + + CREATE OR REPLACE FUNCTION tsquery_lt(tsquery,tsquery) + RETURNS bool + AS 'MODULE_PATHNAME', 'tsa_tsquery_lt' + LANGUAGE C RETURNS NULL ON NULL INPUT IMMUTABLE; + + CREATE OR REPLACE FUNCTION tsquery_le(tsquery,tsquery) + RETURNS bool + AS 'MODULE_PATHNAME', 'tsa_tsquery_le' + LANGUAGE C RETURNS NULL ON NULL INPUT IMMUTABLE; + + CREATE OR REPLACE FUNCTION tsquery_eq(tsquery,tsquery) + RETURNS bool + AS 'MODULE_PATHNAME', 'tsa_tsquery_eq' + LANGUAGE C RETURNS NULL ON NULL INPUT IMMUTABLE; + + CREATE OR REPLACE FUNCTION tsquery_ge(tsquery,tsquery) + RETURNS bool + AS 'MODULE_PATHNAME', 'tsa_tsquery_ge' + LANGUAGE C RETURNS NULL ON NULL INPUT IMMUTABLE; + + CREATE OR REPLACE FUNCTION tsquery_gt(tsquery,tsquery) + RETURNS bool + AS 'MODULE_PATHNAME', 'tsa_tsquery_gt' + LANGUAGE C RETURNS NULL ON NULL INPUT IMMUTABLE; + + CREATE OR REPLACE FUNCTION tsquery_ne(tsquery,tsquery) + RETURNS bool + AS 'MODULE_PATHNAME', 'tsa_tsquery_ne' + LANGUAGE C RETURNS NULL ON NULL INPUT IMMUTABLE; + + CREATE OR REPLACE FUNCTION numnode(tsquery) + RETURNS int4 + as 'MODULE_PATHNAME', 'tsa_tsquery_numnode' + LANGUAGE C + RETURNS NULL ON NULL INPUT IMMUTABLE; + + CREATE OR REPLACE FUNCTION tsquery_and(tsquery,tsquery) + RETURNS tsquery + as 'MODULE_PATHNAME', 'tsa_tsquery_and' + LANGUAGE C + RETURNS NULL ON NULL INPUT IMMUTABLE; + + CREATE OR REPLACE FUNCTION tsquery_or(tsquery,tsquery) + RETURNS tsquery + as 'MODULE_PATHNAME', 'tsa_tsquery_or' + LANGUAGE C + RETURNS NULL ON NULL INPUT IMMUTABLE; + + CREATE OR REPLACE FUNCTION tsquery_not(tsquery) + RETURNS tsquery + as 'MODULE_PATHNAME', 'tsa_tsquery_not' + LANGUAGE C + RETURNS NULL ON NULL INPUT IMMUTABLE; + + --------------rewrite subsystem + + CREATE OR REPLACE FUNCTION rewrite(tsquery, text) + RETURNS tsquery + as 'MODULE_PATHNAME', 'tsa_tsquery_rewrite_query' + LANGUAGE C + RETURNS NULL ON NULL INPUT IMMUTABLE; + + CREATE OR REPLACE FUNCTION rewrite(tsquery, tsquery, tsquery) + RETURNS tsquery + as 'MODULE_PATHNAME', 'tsa_tsquery_rewrite' + LANGUAGE C + RETURNS NULL ON NULL INPUT IMMUTABLE; + + CREATE OR REPLACE FUNCTION rewrite_accum(tsquery,tsquery[]) + RETURNS tsquery + AS 'MODULE_PATHNAME', 'tsa_rewrite_accum' + LANGUAGE C; + + CREATE OR REPLACE FUNCTION rewrite_finish(tsquery) + RETURNS tsquery + as 'MODULE_PATHNAME', 'tsa_rewrite_finish' + 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', 'tsa_tsq_mcontains' + LANGUAGE C + RETURNS NULL ON NULL INPUT IMMUTABLE; + + CREATE OR REPLACE FUNCTION tsq_mcontained(tsquery, tsquery) + RETURNS bool + as 'MODULE_PATHNAME', 'tsa_tsq_mcontained' + 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', 'tsa_gtsq_in' + LANGUAGE C RETURNS NULL ON NULL INPUT; + + CREATE FUNCTION gtsq_out(gtsq) + RETURNS cstring + AS 'MODULE_PATHNAME', 'tsa_gtsq_out' + 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', 'tsa_gtsq_consistent' + LANGUAGE C; + + CREATE FUNCTION gtsq_compress(internal) + RETURNS internal + AS 'MODULE_PATHNAME', 'tsa_gtsq_compress' + LANGUAGE C; + + CREATE FUNCTION gtsq_decompress(internal) + RETURNS internal + AS 'MODULE_PATHNAME', 'tsa_gtsq_decompress' + LANGUAGE C; + + CREATE FUNCTION gtsq_penalty(internal,internal,internal) + RETURNS internal + AS 'MODULE_PATHNAME', 'tsa_gtsq_penalty' + LANGUAGE C RETURNS NULL ON NULL INPUT; + + CREATE FUNCTION gtsq_picksplit(internal, internal) + RETURNS internal + AS 'MODULE_PATHNAME', 'tsa_gtsq_picksplit' + LANGUAGE C; + + CREATE FUNCTION gtsq_union(bytea, internal) + RETURNS _int4 + AS 'MODULE_PATHNAME', 'tsa_gtsq_union' + LANGUAGE C; + + CREATE FUNCTION gtsq_same(gtsq, gtsq, internal) + RETURNS internal + AS 'MODULE_PATHNAME', 'tsa_gtsq_same' + LANGUAGE C; + + --GIN support function + CREATE FUNCTION gin_extract_tsvector(tsvector,internal) + RETURNS internal + AS 'MODULE_PATHNAME', 'tsa_gin_extract_tsvector' + LANGUAGE C RETURNS NULL ON NULL INPUT; + + CREATE FUNCTION gin_extract_tsquery(tsquery,internal,internal) + RETURNS internal + AS 'MODULE_PATHNAME', 'tsa_gin_extract_tsquery' + LANGUAGE C RETURNS NULL ON NULL INPUT; + + CREATE FUNCTION gin_ts_consistent(internal,internal,tsquery) + RETURNS bool + AS 'MODULE_PATHNAME', 'tsa_gin_ts_consistent' + 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-10 00:40:04.000000000 +0100 *************** *** 0 **** --- 1,794 ---- + #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. All function + * has prefix tsa (TSearch API), because some functions + * are not unique (without prefix). + */ + #define WRAPPER_FUNCTION(src, dest) \ + Datum tsa_ ## src (PG_FUNCTION_ARGS); \ + PG_FUNCTION_INFO_V1(tsa_ ## src); \ + Datum \ + tsa_ ## src(PG_FUNCTION_ARGS) \ + { \ + return (dest)(fcinfo); \ + } + + #define UNSUPPORTED_FUNCTION(name) \ + Datum tsa_ ## name (PG_FUNCTION_ARGS); \ + PG_FUNCTION_INFO_V1(tsa_ ## name); \ + Datum \ + tsa_ ## 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 tsa_lexize_byname(PG_FUNCTION_ARGS); + Datum tsa_lexize_bycurrent(PG_FUNCTION_ARGS); + Datum tsa_set_curdict(PG_FUNCTION_ARGS); + Datum tsa_set_curdict_byname(PG_FUNCTION_ARGS); + Datum tsa_token_type_current(PG_FUNCTION_ARGS); + Datum tsa_set_curprs(PG_FUNCTION_ARGS); + Datum tsa_set_curprs_byname(PG_FUNCTION_ARGS); + Datum tsa_parse_current(PG_FUNCTION_ARGS); + Datum tsa_set_curcfg(PG_FUNCTION_ARGS); + Datum tsa_set_curcfg_byname(PG_FUNCTION_ARGS); + Datum tsa_show_curcfg(PG_FUNCTION_ARGS); + Datum tsa_to_tsvector_name(PG_FUNCTION_ARGS); + Datum tsa_to_tsquery_name(PG_FUNCTION_ARGS); + Datum tsa_plainto_tsquery_name(PG_FUNCTION_ARGS); + Datum tsa_headline_byname(PG_FUNCTION_ARGS); + Datum tsa_rank(PG_FUNCTION_ARGS); + Datum tsa_rank_def(PG_FUNCTION_ARGS); + Datum tsa_rank_cd(PG_FUNCTION_ARGS); + Datum tsa_rank_cd_def(PG_FUNCTION_ARGS); + Datum tsa_headline(PG_FUNCTION_ARGS); + Datum tsa_headline_current(PG_FUNCTION_ARGS); + Datum tsa_ts_stat(PG_FUNCTION_ARGS); + Datum tsa_tsearch2(PG_FUNCTION_ARGS); + + PG_FUNCTION_INFO_V1(tsa_lexize_bycurrent); + PG_FUNCTION_INFO_V1(tsa_lexize_byname); + PG_FUNCTION_INFO_V1(tsa_set_curdict); + PG_FUNCTION_INFO_V1(tsa_set_curdict_byname); + PG_FUNCTION_INFO_V1(tsa_token_type_current); + PG_FUNCTION_INFO_V1(tsa_set_curprs); + PG_FUNCTION_INFO_V1(tsa_set_curprs_byname); + PG_FUNCTION_INFO_V1(tsa_parse_current); + PG_FUNCTION_INFO_V1(tsa_set_curcfg); + PG_FUNCTION_INFO_V1(tsa_set_curcfg_byname); + PG_FUNCTION_INFO_V1(tsa_show_curcfg); + PG_FUNCTION_INFO_V1(tsa_to_tsvector_name); + PG_FUNCTION_INFO_V1(tsa_to_tsquery_name); + PG_FUNCTION_INFO_V1(tsa_plainto_tsquery_name); + PG_FUNCTION_INFO_V1(tsa_headline_byname); + PG_FUNCTION_INFO_V1(tsa_rank); + PG_FUNCTION_INFO_V1(tsa_rank_def); + PG_FUNCTION_INFO_V1(tsa_rank_cd); + PG_FUNCTION_INFO_V1(tsa_rank_cd_def); + PG_FUNCTION_INFO_V1(tsa_headline); + PG_FUNCTION_INFO_V1(tsa_headline_current); + PG_FUNCTION_INFO_V1(tsa_ts_stat); + PG_FUNCTION_INFO_V1(tsa_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, tsquery_rewrite) + 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(rewrite_accum) + UNSUPPORTED_FUNCTION(rewrite_finish) + + + /* + * list of redefined functions + */ + + /* lexize(text, text) */ + Datum + tsa_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 + tsa_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 + tsa_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 + tsa_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 + tsa_token_type_current(PG_FUNCTION_ARGS) + { + INSERT_ARGUMENT(ObjectIdGetDatum(GetCurrentParser()), false) + return (ts_token_type_byid)(fcinfo); + } + + /* set_curprs(int) */ + Datum + tsa_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 + tsa_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 + tsa_parse_current(PG_FUNCTION_ARGS) + { + INSERT_ARGUMENT(ObjectIdGetDatum(GetCurrentParser()), false); + return (ts_parse_byid)(fcinfo); + } + + /* set_curcfg(int) */ + Datum + tsa_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 + tsa_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 + tsa_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 + tsa_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 + tsa_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 + tsa_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 + tsa_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 + tsa_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 + tsa_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 + tsa_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 + tsa_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 + tsa_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 + tsa_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 + tsa_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 + tsa_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; + }