Exemplo n.º 1
0
Datum
querytree(PG_FUNCTION_ARGS)
{
	QUERYTYPE  *query = (QUERYTYPE *) PG_GETARG_QUERYTYPE_P_COPY(0);
	INFIX		nrm;
	text	   *res;
	ITEM	   *q;
	int4		len;

	if (query->size == 0)
		ereport(ERROR,
				(errcode(ERRCODE_INVALID_PARAMETER_VALUE),
				 errmsg("empty query")));

	q = (ITEM *) palloc(sizeof(ITEM) * query->size);
	memcpy((void *) q, GETQUERY(query), sizeof(ITEM) * query->size);
	len = shorterquery(q, query->size);
	PG_FREE_IF_COPY(query, 0);

	if (len == 0)
	{
		res = (text *) palloc(1 + VARHDRSZ);
		SET_VARSIZE(res, 1 + VARHDRSZ);
		*((char *) VARDATA(res)) = 'T';
	}
	else
	{
		nrm.curpol = q + len - 1;
		nrm.buflen = 32;
		nrm.cur = nrm.buf = (char *) palloc(sizeof(char) * nrm.buflen);
		*(nrm.cur) = '\0';
		infix(&nrm, true);

		res = (text *) palloc(nrm.cur - nrm.buf + VARHDRSZ);
		SET_VARSIZE(res, nrm.cur - nrm.buf + VARHDRSZ);
		memcpy(VARDATA(res), nrm.buf, nrm.cur - nrm.buf);
	}
	pfree(q);

	PG_RETURN_POINTER(res);
}
Exemplo n.º 2
0
Datum
querytree(PG_FUNCTION_ARGS)
{
	QUERYTYPE  *query = (QUERYTYPE *) PG_DETOAST_DATUM(PG_GETARG_POINTER(0));
	INFIX		nrm;
	text	   *res;
	ITEM	   *q;
	int4		len;

	if (query->size == 0)
		ereport(ERROR,
				(errcode(ERRCODE_INVALID_PARAMETER_VALUE),
				 errmsg("empty query")));

	q = (ITEM *) palloc(sizeof(ITEM) * query->size);
	memcpy((void *) q, GETQUERY(query), sizeof(ITEM) * query->size);
	len = shorterquery(q, query->size);
	PG_FREE_IF_COPY(query, 0);

	if (len == 0)
	{
		res = cstring_to_text("T");
	}
	else
	{
		nrm.curpol = q + len - 1;
		nrm.buflen = 32;
		nrm.cur = nrm.buf = (char *) palloc(sizeof(char) * nrm.buflen);
		*(nrm.cur) = '\0';
		infix(&nrm, true);
		res = cstring_to_text_with_len(nrm.buf, nrm.cur - nrm.buf);
	}
	pfree(q);

	PG_RETURN_TEXT_P(res);
}
Exemplo n.º 3
0
Datum
ginint4_queryextract(PG_FUNCTION_ARGS)
{
	int32	   *nentries = (int32 *) PG_GETARG_POINTER(1);
	StrategyNumber strategy = PG_GETARG_UINT16(2);
	Datum	   *res = NULL;

	*nentries = 0;

	if (strategy == BooleanSearchStrategy)
	{
		QUERYTYPE  *query = (QUERYTYPE *) PG_DETOAST_DATUM_COPY(PG_GETARG_POINTER(0));
		ITEM	   *items = GETQUERY(query);
		int			i;

		if (query->size == 0)
			PG_RETURN_POINTER(NULL);

		if (shorterquery(items, query->size) == 0)
			elog(ERROR, "Query requires full scan, GIN doesn't support it");

		pfree(query);

		query = (QUERYTYPE *) PG_DETOAST_DATUM(PG_GETARG_POINTER(0));
		items = GETQUERY(query);

		res = (Datum *) palloc(sizeof(Datum) * query->size);
		*nentries = 0;

		for (i = 0; i < query->size; i++)
			if (items[i].type == VAL)
			{
				res[*nentries] = Int32GetDatum(items[i].val);
				(*nentries)++;
			}
	}
	else
	{
		ArrayType  *query = PG_GETARG_ARRAYTYPE_P(0);
		int4	   *arr;
		uint32		i;

		CHECKARRVALID(query);
		*nentries = ARRNELEMS(query);
		if (*nentries > 0)
		{
			res = (Datum *) palloc(sizeof(Datum) * (*nentries));

			arr = ARRPTR(query);
			for (i = 0; i < *nentries; i++)
				res[i] = Int32GetDatum(arr[i]);
		}
	}

	if (*nentries == 0)
	{
		switch (strategy)
		{
			case BooleanSearchStrategy:
			case RTOverlapStrategyNumber:
				*nentries = -1; /* nobody can be found */
				break;
			default:			/* require fullscan: GIN can't find void
								 * arrays */
				break;
		}
	}

	PG_RETURN_POINTER(res);
}