Example #1
0
Datum
hstore_to_plpython(PG_FUNCTION_ARGS)
{
	HStore	   *in = PG_GETARG_HS(0);
	int			i;
	int			count = HS_COUNT(in);
	char	   *base = STRPTR(in);
	HEntry	   *entries = ARRPTR(in);
	PyObject   *dict;

	dict = PyDict_New();

	for (i = 0; i < count; i++)
	{
		PyObject   *key;

		key = PyString_FromStringAndSize(HSTORE_KEY(entries, base, i),
										 HSTORE_KEYLEN(entries, i));
		if (HSTORE_VALISNULL(entries, i))
			PyDict_SetItem(dict, key, Py_None);
		else
		{
			PyObject   *value;

			value = PyString_FromStringAndSize(HSTORE_VAL(entries, base, i),
											   HSTORE_VALLEN(entries, i));
			PyDict_SetItem(dict, key, value);
			Py_XDECREF(value);
		}
		Py_XDECREF(key);
	}

	return PointerGetDatum(dict);
}
Example #2
0
Datum
ghstore_compress(PG_FUNCTION_ARGS)
{
	GISTENTRY  *entry = (GISTENTRY *) PG_GETARG_POINTER(0);
	GISTENTRY  *retval = entry;

	if (entry->leafkey)
	{
		GISTTYPE   *res = (GISTTYPE *) palloc0(CALCGTSIZE(0));
		HStore	   *val = DatumGetHStoreP(entry->key);
		HEntry	   *hsent = ARRPTR(val);
		char	   *ptr = STRPTR(val);
		int			count = HS_COUNT(val);
		int			i;

		SET_VARSIZE(res, CALCGTSIZE(0));

		for (i = 0; i < count; ++i)
		{
			int			h;

			h = crc32_sz((char *) HSTORE_KEY(hsent, ptr, i),
						 HSTORE_KEYLEN(hsent, i));
			HASH(GETSIGN(res), h);
			if (!HSTORE_VALISNULL(hsent, i))
			{
				h = crc32_sz((char *) HSTORE_VAL(hsent, ptr, i),
							 HSTORE_VALLEN(hsent, i));
				HASH(GETSIGN(res), h);
			}
		}

		retval = (GISTENTRY *) palloc(sizeof(GISTENTRY));
		gistentryinit(*retval, PointerGetDatum(res),
					  entry->rel, entry->page,
					  entry->offset,
					  FALSE);
	}
	else if (!ISALLTRUE(DatumGetPointer(entry->key)))
	{
		int32		i;
		GISTTYPE   *res;
		BITVECP		sign = GETSIGN(DatumGetPointer(entry->key));

		LOOPBYTE
		{
			if ((sign[i] & 0xff) != 0xff)
				PG_RETURN_POINTER(retval);
		}

		res = (GISTTYPE *) palloc(CALCGTSIZE(ALLISTRUE));
		SET_VARSIZE(res, CALCGTSIZE(ALLISTRUE));
		res->flag = ALLISTRUE;

		retval = (GISTENTRY *) palloc(sizeof(GISTENTRY));
		gistentryinit(*retval, PointerGetDatum(res),
					  entry->rel, entry->page,
					  entry->offset,
					  FALSE);
	}
/*
 * Validity test for a new-format hstore.
 *	0 = not valid
 *	1 = valid but with "slop" in the length
 *	2 = exactly valid
 */
static int
hstoreValidNewFormat(HStore *hs)
{
	int			count = HS_COUNT(hs);
	HEntry	   *entries = ARRPTR(hs);
	int			buflen = (count) ? HSE_ENDPOS(entries[2 * (count) - 1]) : 0;
	int			vsize = CALCDATASIZE(count, buflen);
	int			i;

	if (hs->size_ & HS_FLAG_NEWVERSION)
		return 2;

	if (count == 0)
		return 2;

	if (!HSE_ISFIRST(entries[0]))
		return 0;

	if (vsize > VARSIZE(hs))
		return 0;

	/* entry position must be nondecreasing */

	for (i = 1; i < 2 * count; ++i)
	{
		if (HSE_ISFIRST(entries[i])
			|| (HSE_ENDPOS(entries[i]) < HSE_ENDPOS(entries[i - 1])))
			return 0;
	}

	/* key length must be nondecreasing and keys must not be null */

	for (i = 1; i < count; ++i)
	{
		if (HSTORE_KEYLEN(entries, i) < HSTORE_KEYLEN(entries, i - 1))
			return 0;
		if (HSE_ISNULL(entries[2 * i]))
			return 0;
	}

	if (vsize != VARSIZE(hs))
		return 1;

	return 2;
}