Exemplo n.º 1
0
/*
 * This function is used for morph parsing
 */
static void
pushval_morph(QPRS_STATE * state, int typeval, char *strval, int lenval, int2 weight)
{
	int4		count = 0;
	PRSTEXT		prs;

	prs.lenwords = 32;
	prs.curwords = 0;
	prs.pos = 0;
	prs.words = (TSWORD *) palloc(sizeof(TSWORD) * prs.lenwords);

	parsetext_v2(findcfg(state->cfg_id), &prs, strval, lenval);

	for (count = 0; count < prs.curwords; count++)
	{
		pushval_asis(state, VAL, prs.words[count].word, prs.words[count].len, weight);
		pfree(prs.words[count].word);
		if (count)
			pushquery(state, OPR, (int4) '&', 0, 0, 0);
	}
	pfree(prs.words);

	/* XXX */
	if (prs.curwords == 0)
		pushval_asis(state, VALSTOP, NULL, 0, 0);
}
Exemplo n.º 2
0
Datum
to_tsvector(PG_FUNCTION_ARGS)
{
	text	   *in = PG_GETARG_TEXT_P(1);
	PRSTEXT		prs;
	tsvector   *out = NULL;
	TSCfgInfo  *cfg = findcfg(PG_GETARG_INT32(0));

	prs.lenwords = 32;
	prs.curwords = 0;
	prs.pos = 0;
	prs.words = (WORD *) palloc(sizeof(WORD) * prs.lenwords);

	parsetext_v2(cfg, &prs, VARDATA(in), VARSIZE(in) - VARHDRSZ);
	PG_FREE_IF_COPY(in, 1);

	if (prs.curwords)
		out = makevalue(&prs);
	else
	{
		pfree(prs.words);
		out = palloc(CALCDATASIZE(0, 0));
		out->len = CALCDATASIZE(0, 0);
		out->size = 0;
	}
	PG_RETURN_POINTER(out);
}
Exemplo n.º 3
0
Datum
set_curcfg(PG_FUNCTION_ARGS)
{
    SET_FUNCOID();
    findcfg(PG_GETARG_OID(0));
    current_cfg_id = PG_GETARG_OID(0);
    PG_RETURN_VOID();
}
Exemplo n.º 4
0
Datum
headline(PG_FUNCTION_ARGS)
{
	text	   *in = PG_GETARG_TEXT_P(1);
	QUERYTYPE  *query = (QUERYTYPE *) DatumGetPointer(PG_DETOAST_DATUM(PG_GETARG_DATUM(2)));
	text	   *opt = (PG_NARGS() > 3 && PG_GETARG_POINTER(3)) ? PG_GETARG_TEXT_P(3) : NULL;
	HLPRSTEXT	prs;
	text	   *out;
	TSCfgInfo  *cfg;
	WParserInfo *prsobj;

	SET_FUNCOID();
	cfg = findcfg(PG_GETARG_OID(0));
	prsobj = findprs(cfg->prs_id);

	memset(&prs, 0, sizeof(HLPRSTEXT));
	prs.lenwords = 32;
	prs.words = (HLWORD *) palloc(sizeof(HLWORD) * prs.lenwords);
	hlparsetext(cfg, &prs, query, VARDATA(in), VARSIZE(in) - VARHDRSZ);


	FunctionCall3(
				  &(prsobj->headline_info),
				  PointerGetDatum(&prs),
				  PointerGetDatum(opt),
				  PointerGetDatum(query)
		);

	out = genhl(&prs);

	PG_FREE_IF_COPY(in, 1);
	PG_FREE_IF_COPY(query, 2);
	if (opt)
		PG_FREE_IF_COPY(opt, 3);
	pfree(prs.words);
	pfree(prs.startsel);
	pfree(prs.stopsel);

	PG_RETURN_POINTER(out);
}
Exemplo n.º 5
0
TSCfgInfo *
findcfg(Oid id)
{
    /* last used cfg */
    if (CList.last_cfg && CList.last_cfg->id == id)
        return CList.last_cfg;

    /* already used cfg */
    if (CList.len != 0)
    {
        TSCfgInfo	key;

        key.id = id;
        CList.last_cfg = bsearch(&key, CList.list, CList.len, sizeof(TSCfgInfo), comparecfg);
        if (CList.last_cfg != NULL)
            return CList.last_cfg;
    }

    /* last chance */
    if (CList.len == CList.reallen)
    {
        TSCfgInfo  *tmp;
        int			reallen = (CList.reallen) ? 2 * CList.reallen : 16;

        tmp = (TSCfgInfo *) realloc(CList.list, sizeof(TSCfgInfo) * reallen);
        if (!tmp)
            ts_error(ERROR, "No memory");
        CList.reallen = reallen;
        CList.list = tmp;
    }
    init_cfg(id, &(CList.list[CList.len]) );
    CList.last_cfg = &(CList.list[CList.len]);
    CList.len++;
    qsort(CList.list, CList.len, sizeof(TSCfgInfo), comparecfg);
    return findcfg(id); /* qsort changed order!! */ ;
}
Exemplo n.º 6
0
/*
 * Trigger
 */
Datum
tsearch2(PG_FUNCTION_ARGS)
{
	TriggerData *trigdata;
	Trigger    *trigger;
	Relation	rel;
	HeapTuple	rettuple = NULL;
	TSCfgInfo  *cfg = findcfg(get_currcfg());
	int			numidxattr,
				i;
	PRSTEXT		prs;
	Datum		datum = (Datum) 0;
	Oid			funcoid = InvalidOid;

	if (!CALLED_AS_TRIGGER(fcinfo))
		/* internal error */
		elog(ERROR, "TSearch: Not fired by trigger manager");

	trigdata = (TriggerData *) fcinfo->context;
	if (TRIGGER_FIRED_FOR_STATEMENT(trigdata->tg_event))
		/* internal error */
		elog(ERROR, "TSearch: Can't process STATEMENT events");
	if (TRIGGER_FIRED_AFTER(trigdata->tg_event))
		/* internal error */
		elog(ERROR, "TSearch: Must be fired BEFORE event");

	if (TRIGGER_FIRED_BY_INSERT(trigdata->tg_event))
		rettuple = trigdata->tg_trigtuple;
	else if (TRIGGER_FIRED_BY_UPDATE(trigdata->tg_event))
		rettuple = trigdata->tg_newtuple;
	else
		/* internal error */
		elog(ERROR, "TSearch: Unknown event");

	trigger = trigdata->tg_trigger;
	rel = trigdata->tg_relation;

	if (trigger->tgnargs < 2)
		/* internal error */
		elog(ERROR, "TSearch: format tsearch2(tsvector_field, text_field1,...)");

	numidxattr = SPI_fnumber(rel->rd_att, trigger->tgargs[0]);
	if (numidxattr == SPI_ERROR_NOATTRIBUTE)
		ereport(ERROR,
				(errcode(ERRCODE_UNDEFINED_COLUMN),
				 errmsg("tsvector column \"%s\" does not exist",
						trigger->tgargs[0])));

	prs.lenwords = 32;
	prs.curwords = 0;
	prs.pos = 0;
	prs.words = (WORD *) palloc(sizeof(WORD) * prs.lenwords);

	/* find all words in indexable column */
	for (i = 1; i < trigger->tgnargs; i++)
	{
		int			numattr;
		Oid			oidtype;
		Datum		txt_toasted;
		bool		isnull;
		text	   *txt;

		numattr = SPI_fnumber(rel->rd_att, trigger->tgargs[i]);
		if (numattr == SPI_ERROR_NOATTRIBUTE)
		{
			funcoid = findFunc(trigger->tgargs[i]);
			if (funcoid == InvalidOid)
				ereport(ERROR,
						(errcode(ERRCODE_UNDEFINED_COLUMN),
						 errmsg("could not find function or field \"%s\"",
								trigger->tgargs[i])));

			continue;
		}
		oidtype = SPI_gettypeid(rel->rd_att, numattr);
		/* We assume char() and varchar() are binary-equivalent to text */
		if (!(oidtype == TEXTOID ||
			  oidtype == VARCHAROID ||
			  oidtype == BPCHAROID))
		{
			elog(WARNING, "TSearch: '%s' is not of character type",
				 trigger->tgargs[i]);
			continue;
		}
		txt_toasted = SPI_getbinval(rettuple, rel->rd_att, numattr, &isnull);
		if (isnull)
			continue;

		if (funcoid != InvalidOid)
		{
			text	   *txttmp = (text *) DatumGetPointer(OidFunctionCall1(
																 funcoid,
											 PointerGetDatum(txt_toasted)
																	  ));

			txt = (text *) DatumGetPointer(PG_DETOAST_DATUM(PointerGetDatum(txttmp)));
			if (txt == txttmp)
				txt_toasted = PointerGetDatum(txt);
		}
		else
			txt = (text *) DatumGetPointer(PG_DETOAST_DATUM(PointerGetDatum(txt_toasted)));

		parsetext_v2(cfg, &prs, VARDATA(txt), VARSIZE(txt) - VARHDRSZ);
		if (txt != (text *) DatumGetPointer(txt_toasted))
			pfree(txt);
	}

	/* make tsvector value */
	if (prs.curwords)
	{
		datum = PointerGetDatum(makevalue(&prs));
		rettuple = SPI_modifytuple(rel, rettuple, 1, &numidxattr,
								   &datum, NULL);
		pfree(DatumGetPointer(datum));
	}
	else
	{
		tsvector   *out = palloc(CALCDATASIZE(0, 0));

		out->len = CALCDATASIZE(0, 0);
		out->size = 0;
		datum = PointerGetDatum(out);
		pfree(prs.words);
		rettuple = SPI_modifytuple(rel, rettuple, 1, &numidxattr,
								   &datum, NULL);
	}

	if (rettuple == NULL)
		/* internal error */
		elog(ERROR, "TSearch: %d returned by SPI_modifytuple", SPI_result);

	return PointerGetDatum(rettuple);
}