summaryrefslogtreecommitdiff
path: root/contrib/tsearch2/tsearch2.c
diff options
context:
space:
mode:
Diffstat (limited to 'contrib/tsearch2/tsearch2.c')
-rw-r--r--contrib/tsearch2/tsearch2.c542
1 files changed, 0 insertions, 542 deletions
diff --git a/contrib/tsearch2/tsearch2.c b/contrib/tsearch2/tsearch2.c
deleted file mode 100644
index 16772a2b92b..00000000000
--- a/contrib/tsearch2/tsearch2.c
+++ /dev/null
@@ -1,542 +0,0 @@
-/*-------------------------------------------------------------------------
- *
- * tsearch2.c
- * Backwards-compatibility package for old contrib/tsearch2 API
- *
- * Portions Copyright (c) 1996-2017, PostgreSQL Global Development Group
- *
- *
- * IDENTIFICATION
- * contrib/tsearch2/tsearch2.c
- *
- *-------------------------------------------------------------------------
- */
-#include "postgres.h"
-
-#include "catalog/namespace.h"
-#include "catalog/pg_type.h"
-#include "commands/trigger.h"
-#include "tsearch/ts_utils.h"
-#include "utils/builtins.h"
-#include "utils/guc.h"
-#include "utils/regproc.h"
-#include "utils/syscache.h"
-
-PG_MODULE_MAGIC;
-
-static Oid current_dictionary_oid = InvalidOid;
-static Oid current_parser_oid = InvalidOid;
-
-/* insert given value at argument position 0 */
-#define INSERT_ARGUMENT0(argument, isnull) \
- do { \
- int i; \
- for (i = fcinfo->nargs; i > 0; i--) \
- { \
- fcinfo->arg[i] = fcinfo->arg[i-1]; \
- fcinfo->argnull[i] = fcinfo->argnull[i-1]; \
- } \
- fcinfo->arg[0] = (argument); \
- fcinfo->argnull[0] = (isnull); \
- fcinfo->nargs++; \
- } while (0)
-
-#define TextGetObjectId(infunction, text) \
- DatumGetObjectId(DirectFunctionCall1(infunction, \
- CStringGetDatum(text_to_cstring(text))))
-
-#define UNSUPPORTED_FUNCTION(name) \
- PG_FUNCTION_INFO_V1(name); \
- Datum \
- name(PG_FUNCTION_ARGS) \
- { \
- ereport(ERROR, \
- (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),\
- errmsg("function %s is no longer supported", \
- format_procedure(fcinfo->flinfo->fn_oid)), \
- errhint("Switch to new tsearch functionality."))); \
- /* keep compiler quiet */ \
- PG_RETURN_NULL(); \
- } \
- extern int no_such_variable
-
-static Oid GetCurrentDict(void);
-static Oid GetCurrentParser(void);
-
-PG_FUNCTION_INFO_V1(tsa_lexize_byname);
-PG_FUNCTION_INFO_V1(tsa_lexize_bycurrent);
-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_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_ts_stat);
-PG_FUNCTION_INFO_V1(tsa_tsearch2);
-PG_FUNCTION_INFO_V1(tsa_rewrite_accum);
-PG_FUNCTION_INFO_V1(tsa_rewrite_finish);
-
-
-/*
- * List of unsupported functions
- *
- * The parser and dictionary functions are defined only so that the former
- * contents of pg_ts_parser and pg_ts_dict can be loaded into the system,
- * for ease of reference while creating the new tsearch configuration.
- */
-
-UNSUPPORTED_FUNCTION(tsa_dex_init);
-UNSUPPORTED_FUNCTION(tsa_dex_lexize);
-
-UNSUPPORTED_FUNCTION(tsa_snb_en_init);
-UNSUPPORTED_FUNCTION(tsa_snb_lexize);
-UNSUPPORTED_FUNCTION(tsa_snb_ru_init_koi8);
-UNSUPPORTED_FUNCTION(tsa_snb_ru_init_utf8);
-UNSUPPORTED_FUNCTION(tsa_snb_ru_init);
-
-UNSUPPORTED_FUNCTION(tsa_spell_init);
-UNSUPPORTED_FUNCTION(tsa_spell_lexize);
-
-UNSUPPORTED_FUNCTION(tsa_syn_init);
-UNSUPPORTED_FUNCTION(tsa_syn_lexize);
-
-UNSUPPORTED_FUNCTION(tsa_thesaurus_init);
-UNSUPPORTED_FUNCTION(tsa_thesaurus_lexize);
-
-UNSUPPORTED_FUNCTION(tsa_prsd_start);
-UNSUPPORTED_FUNCTION(tsa_prsd_getlexeme);
-UNSUPPORTED_FUNCTION(tsa_prsd_end);
-UNSUPPORTED_FUNCTION(tsa_prsd_lextype);
-UNSUPPORTED_FUNCTION(tsa_prsd_headline);
-
-UNSUPPORTED_FUNCTION(tsa_reset_tsearch);
-UNSUPPORTED_FUNCTION(tsa_get_covers);
-
-
-/*
- * list of redefined functions
- */
-
-/* lexize(text, text) */
-Datum
-tsa_lexize_byname(PG_FUNCTION_ARGS)
-{
- text *dictname = PG_GETARG_TEXT_PP(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);
-
- if (!SearchSysCacheExists(TSDICTOID,
- ObjectIdGetDatum(dict_oid),
- 0, 0, 0))
- elog(ERROR, "cache lookup failed for text search dictionary %u",
- dict_oid);
-
- current_dictionary_oid = dict_oid;
-
- PG_RETURN_VOID();
-}
-
-/* set_curdict(text) */
-Datum
-tsa_set_curdict_byname(PG_FUNCTION_ARGS)
-{
- text *name = PG_GETARG_TEXT_PP(0);
- Oid dict_oid;
-
- dict_oid = get_ts_dict_oid(stringToQualifiedNameList(text_to_cstring(name)), false);
-
- current_dictionary_oid = dict_oid;
-
- PG_RETURN_VOID();
-}
-
-/* token_type() */
-Datum
-tsa_token_type_current(PG_FUNCTION_ARGS)
-{
- INSERT_ARGUMENT0(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);
-
- if (!SearchSysCacheExists(TSPARSEROID,
- ObjectIdGetDatum(parser_oid),
- 0, 0, 0))
- elog(ERROR, "cache lookup failed for text search parser %u",
- parser_oid);
-
- current_parser_oid = parser_oid;
-
- PG_RETURN_VOID();
-}
-
-/* set_curprs(text) */
-Datum
-tsa_set_curprs_byname(PG_FUNCTION_ARGS)
-{
- text *name = PG_GETARG_TEXT_PP(0);
- Oid parser_oid;
-
- parser_oid = get_ts_parser_oid(stringToQualifiedNameList(text_to_cstring(name)), false);
-
- current_parser_oid = parser_oid;
-
- PG_RETURN_VOID();
-}
-
-/* parse(text) */
-Datum
-tsa_parse_current(PG_FUNCTION_ARGS)
-{
- INSERT_ARGUMENT0(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)));
-
- SetConfigOption("default_text_search_config", name,
- PGC_USERSET, PGC_S_SESSION);
-
- PG_RETURN_VOID();
-}
-
-/* set_curcfg(text) */
-Datum
-tsa_set_curcfg_byname(PG_FUNCTION_ARGS)
-{
- text *arg0 = PG_GETARG_TEXT_PP(0);
- char *name;
-
- name = text_to_cstring(arg0);
-
- SetConfigOption("default_text_search_config", name,
- PGC_USERSET, PGC_S_SESSION);
-
- PG_RETURN_VOID();
-}
-
-/* to_tsvector(text, text) */
-Datum
-tsa_to_tsvector_name(PG_FUNCTION_ARGS)
-{
- text *cfgname = PG_GETARG_TEXT_PP(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_PP(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_PP(0);
- Datum arg1 = PG_GETARG_DATUM(1);
- Oid config_oid;
-
- config_oid = TextGetObjectId(regconfigin, cfgname);
-
- return DirectFunctionCall2(plainto_tsquery_byid,
- ObjectIdGetDatum(config_oid), arg1);
-}
-
-/* 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 result;
- Oid config_oid;
-
- /* first parameter has to be converted to oid */
- config_oid = DatumGetObjectId(DirectFunctionCall1(regconfigin,
- CStringGetDatum(TextDatumGetCString(arg0))));
-
- if (PG_NARGS() == 3)
- result = DirectFunctionCall3(ts_headline_byid,
- ObjectIdGetDatum(config_oid), arg1, arg2);
- else
- {
- Datum arg3 = PG_GETARG_DATUM(3);
-
- result = DirectFunctionCall4(ts_headline_byid_opt,
- ObjectIdGetDatum(config_oid),
- arg1, arg2, arg3);
- }
-
- return result;
-}
-
-/*
- * tsearch2 version of update trigger
- *
- * We pass this on to the core trigger after inserting the default text
- * search configuration name as the second argument. Note that this isn't
- * a complete implementation of the original functionality; tsearch2 allowed
- * transformation function names to be included in the list. However, that
- * is deliberately removed as being a security risk.
- */
-Datum
-tsa_tsearch2(PG_FUNCTION_ARGS)
-{
- TriggerData *trigdata;
- Trigger *trigger;
- char **tgargs,
- **tgargs_old;
- int i;
- Datum res;
-
- /* Check call context */
- if (!CALLED_AS_TRIGGER(fcinfo)) /* internal error */
- elog(ERROR, "tsvector_update_trigger: not fired by trigger manager");
-
- trigdata = (TriggerData *) fcinfo->context;
- trigger = trigdata->tg_trigger;
-
- if (trigger->tgnargs < 2)
- elog(ERROR, "TSearch: format tsearch2(tsvector_field, text_field1,...)");
-
- /* create space for configuration name */
- tgargs = (char **) palloc((trigger->tgnargs + 1) * sizeof(char *));
- 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, false));
- tgargs_old = trigger->tgargs;
- trigger->tgargs = tgargs;
- trigger->tgnargs++;
-
- res = tsvector_update_trigger_byid(fcinfo);
-
- /* restore old trigger data */
- trigger->tgargs = tgargs_old;
- trigger->tgnargs--;
-
- pfree(tgargs[1]);
- pfree(tgargs);
-
- return res;
-}
-
-
-Datum
-tsa_rewrite_accum(PG_FUNCTION_ARGS)
-{
- TSQuery acc;
- ArrayType *qa;
- TSQuery q;
- QTNode *qex = NULL,
- *subs = NULL,
- *acctree = NULL;
- bool isfind = false;
- Datum *elemsp;
- int nelemsp;
- MemoryContext aggcontext;
- MemoryContext oldcontext;
-
- if (!AggCheckCallContext(fcinfo, &aggcontext))
- elog(ERROR, "tsa_rewrite_accum called in non-aggregate context");
-
- if (PG_ARGISNULL(0) || PG_GETARG_POINTER(0) == NULL)
- {
- acc = (TSQuery) MemoryContextAlloc(aggcontext, HDRSIZETQ);
- SET_VARSIZE(acc, HDRSIZETQ);
- acc->size = 0;
- }
- else
- acc = PG_GETARG_TSQUERY(0);
-
- if (PG_ARGISNULL(1) || PG_GETARG_POINTER(1) == NULL)
- PG_RETURN_TSQUERY(acc);
- else
- qa = PG_GETARG_ARRAYTYPE_P_COPY(1);
-
- if (ARR_NDIM(qa) != 1)
- elog(ERROR, "array must be one-dimensional, not %d dimensions",
- ARR_NDIM(qa));
- if (ArrayGetNItems(ARR_NDIM(qa), ARR_DIMS(qa)) != 3)
- elog(ERROR, "array must have three elements");
- if (ARR_ELEMTYPE(qa) != TSQUERYOID)
- elog(ERROR, "array must contain tsquery elements");
-
- deconstruct_array(qa, TSQUERYOID, -1, false, 'i', &elemsp, NULL, &nelemsp);
-
- q = DatumGetTSQuery(elemsp[0]);
- if (q->size == 0)
- {
- pfree(elemsp);
- PG_RETURN_POINTER(acc);
- }
-
- if (!acc->size)
- {
- if (VARSIZE(acc) > HDRSIZETQ)
- {
- pfree(elemsp);
- PG_RETURN_POINTER(acc);
- }
- else
- acctree = QT2QTN(GETQUERY(q), GETOPERAND(q));
- }
- else
- acctree = QT2QTN(GETQUERY(acc), GETOPERAND(acc));
-
- QTNTernary(acctree);
- QTNSort(acctree);
-
- q = DatumGetTSQuery(elemsp[1]);
- if (q->size == 0)
- {
- pfree(elemsp);
- PG_RETURN_POINTER(acc);
- }
- qex = QT2QTN(GETQUERY(q), GETOPERAND(q));
- QTNTernary(qex);
- QTNSort(qex);
-
- q = DatumGetTSQuery(elemsp[2]);
- if (q->size)
- subs = QT2QTN(GETQUERY(q), GETOPERAND(q));
-
- acctree = findsubquery(acctree, qex, subs, &isfind);
-
- if (isfind || !acc->size)
- {
- /* pfree( acc ); do not pfree(p), because nodeAgg.c will */
- if (acctree)
- {
- QTNBinary(acctree);
- oldcontext = MemoryContextSwitchTo(aggcontext);
- acc = QTN2QT(acctree);
- MemoryContextSwitchTo(oldcontext);
- }
- else
- {
- acc = (TSQuery) MemoryContextAlloc(aggcontext, HDRSIZETQ);
- SET_VARSIZE(acc, HDRSIZETQ);
- acc->size = 0;
- }
- }
-
- pfree(elemsp);
- QTNFree(qex);
- QTNFree(subs);
- QTNFree(acctree);
-
- PG_RETURN_TSQUERY(acc);
-}
-
-Datum
-tsa_rewrite_finish(PG_FUNCTION_ARGS)
-{
- TSQuery acc = PG_GETARG_TSQUERY(0);
- TSQuery rewrited;
-
- if (acc == NULL || PG_ARGISNULL(0) || acc->size == 0)
- {
- rewrited = (TSQuery) palloc(HDRSIZETQ);
- SET_VARSIZE(rewrited, HDRSIZETQ);
- rewrited->size = 0;
- }
- else
- {
- rewrited = (TSQuery) palloc(VARSIZE(acc));
- memcpy(rewrited, acc, VARSIZE(acc));
- pfree(acc);
- }
-
- PG_RETURN_POINTER(rewrited);
-}
-
-
-/*
- * Get Oid of current dictionary
- */
-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;
-}
-
-/*
- * Get Oid of current parser
- *
- * Here, it seems reasonable to select the "default" parser if none has been
- * set.
- */
-static Oid
-GetCurrentParser(void)
-{
- if (current_parser_oid == InvalidOid)
- current_parser_oid = get_ts_parser_oid(stringToQualifiedNameList("pg_catalog.default"), false);
- return current_parser_oid;
-}