Exemple #1
0
Datum
hstore_recv(PG_FUNCTION_ARGS)
{
	int32		buflen;
	HStore	   *out;
	Pairs	   *pairs;
	int32		i;
	int32		pcount;
	StringInfo	buf = (StringInfo) PG_GETARG_POINTER(0);

	pcount = pq_getmsgint(buf, 4);

	if (pcount == 0)
	{
		out = hstorePairs(NULL, 0, 0);
		PG_RETURN_POINTER(out);
	}

	if (pcount < 0 || pcount > MaxAllocSize / sizeof(Pairs))
		ereport(ERROR,
				(errcode(ERRCODE_PROGRAM_LIMIT_EXCEEDED),
			  errmsg("number of pairs (%d) exceeds the maximum allowed (%d)",
					 pcount, (int) (MaxAllocSize / sizeof(Pairs)))));
	pairs = palloc(pcount * sizeof(Pairs));

	for (i = 0; i < pcount; ++i)
	{
		int			rawlen = pq_getmsgint(buf, 4);
		int			len;

		if (rawlen < 0)
			ereport(ERROR,
					(errcode(ERRCODE_NULL_VALUE_NOT_ALLOWED),
					 errmsg("null value not allowed for hstore key")));

		pairs[i].key = pq_getmsgtext(buf, rawlen, &len);
		pairs[i].keylen = hstoreCheckKeyLen(len);
		pairs[i].needfree = true;

		rawlen = pq_getmsgint(buf, 4);
		if (rawlen < 0)
		{
			pairs[i].val = NULL;
			pairs[i].vallen = 0;
			pairs[i].isnull = true;
		}
		else
		{
			pairs[i].val = pq_getmsgtext(buf, rawlen, &len);
			pairs[i].vallen = hstoreCheckValLen(len);
			pairs[i].isnull = false;
		}
	}

	pcount = hstoreUniquePairs(pairs, pcount, &buflen);

	out = hstorePairs(pairs, pcount, buflen);

	PG_RETURN_POINTER(out);
}
Exemple #2
0
Datum
plperl_to_hstore(PG_FUNCTION_ARGS)
{
	HV		   *hv;
	HE		   *he;
	int32		buflen;
	int32		i;
	int32		pcount;
	HStore	   *out;
	Pairs	   *pairs;

	hv = (HV *) SvRV((SV *) PG_GETARG_POINTER(0));

	pcount = hv_iterinit(hv);

	pairs = palloc(pcount * sizeof(Pairs));

	i = 0;
	while ((he = hv_iternext(hv)))
	{
		char	   *key = sv2cstr(HeSVKEY_force(he));
		SV		   *value = HeVAL(he);

		pairs[i].key = pstrdup(key);
		pairs[i].keylen = hstoreCheckKeyLen(strlen(pairs[i].key));
		pairs[i].needfree = true;

		if (!SvOK(value))
		{
			pairs[i].val = NULL;
			pairs[i].vallen = 0;
			pairs[i].isnull = true;
		}
		else
		{
			pairs[i].val = pstrdup(sv2cstr(value));
			pairs[i].vallen = hstoreCheckValLen(strlen(pairs[i].val));
			pairs[i].isnull = false;
		}

		i++;
	}

	pcount = hstoreUniquePairs(pairs, pcount, &buflen);
	out = hstorePairs(pairs, pcount, buflen);
	PG_RETURN_POINTER(out);
}
Exemple #3
0
Datum
hstore_in(PG_FUNCTION_ARGS)
{
	HSParser	state;
	int4		buflen;
	HStore	   *out;

	state.begin = PG_GETARG_CSTRING(0);

	parse_hstore(&state);

	state.pcur = hstoreUniquePairs(state.pairs, state.pcur, &buflen);

	out = hstorePairs(state.pairs, state.pcur, buflen);

	PG_RETURN_POINTER(out);
}
Pairs *
hstoreArrayToPairs(ArrayType *a, int *npairs)
{
    Datum	   *key_datums;
    bool	   *key_nulls;
    int			key_count;
    Pairs	   *key_pairs;
    int			bufsiz;
    int			i,
                j;

    deconstruct_array(a,
                      TEXTOID, -1, false, 'i',
                      &key_datums, &key_nulls, &key_count);

    if (key_count == 0)
    {
        *npairs = 0;
        return NULL;
    }

    key_pairs = palloc(sizeof(Pairs) * key_count);

    for (i = 0, j = 0; i < key_count; i++)
    {
        if (!key_nulls[i])
        {
            key_pairs[j].key = VARDATA(key_datums[i]);
            key_pairs[j].keylen = VARSIZE(key_datums[i]) - VARHDRSZ;
            key_pairs[j].val = NULL;
            key_pairs[j].vallen = 0;
            key_pairs[j].needfree = 0;
            key_pairs[j].isnull = 1;
            j++;
        }
    }

    *npairs = hstoreUniquePairs(key_pairs, j, &bufsiz);

    return key_pairs;
}
Exemple #5
0
Datum
hstore_from_record(PG_FUNCTION_ARGS)
{
	HeapTupleHeader rec;
	int4		buflen;
	HStore	   *out;
	Pairs	   *pairs;
	Oid			tupType;
	int32		tupTypmod;
	TupleDesc	tupdesc;
	HeapTupleData tuple;
	RecordIOData *my_extra;
	int			ncolumns;
	int			i,
				j;
	Datum	   *values;
	bool	   *nulls;

	if (PG_ARGISNULL(0))
	{
		Oid			argtype = get_fn_expr_argtype(fcinfo->flinfo, 0);

		/*
		 * have no tuple to look at, so the only source of type info is the
		 * argtype. The lookup_rowtype_tupdesc call below will error out if we
		 * don't have a known composite type oid here.
		 */
		tupType = argtype;
		tupTypmod = -1;

		rec = NULL;
	}
	else
	{
		rec = PG_GETARG_HEAPTUPLEHEADER(0);

		/* Extract type info from the tuple itself */
		tupType = HeapTupleHeaderGetTypeId(rec);
		tupTypmod = HeapTupleHeaderGetTypMod(rec);
	}

	tupdesc = lookup_rowtype_tupdesc(tupType, tupTypmod);
	ncolumns = tupdesc->natts;

	/*
	 * We arrange to look up the needed I/O info just once per series of
	 * calls, assuming the record type doesn't change underneath us.
	 */
	my_extra = (RecordIOData *) fcinfo->flinfo->fn_extra;
	if (my_extra == NULL ||
		my_extra->ncolumns != ncolumns)
	{
		fcinfo->flinfo->fn_extra =
			MemoryContextAlloc(fcinfo->flinfo->fn_mcxt,
							   sizeof(RecordIOData) - sizeof(ColumnIOData)
							   + ncolumns * sizeof(ColumnIOData));
		my_extra = (RecordIOData *) fcinfo->flinfo->fn_extra;
		my_extra->record_type = InvalidOid;
		my_extra->record_typmod = 0;
	}

	if (my_extra->record_type != tupType ||
		my_extra->record_typmod != tupTypmod)
	{
		MemSet(my_extra, 0,
			   sizeof(RecordIOData) - sizeof(ColumnIOData)
			   + ncolumns * sizeof(ColumnIOData));
		my_extra->record_type = tupType;
		my_extra->record_typmod = tupTypmod;
		my_extra->ncolumns = ncolumns;
	}

	pairs = palloc(ncolumns * sizeof(Pairs));

	if (rec)
	{
		/* Build a temporary HeapTuple control structure */
		tuple.t_len = HeapTupleHeaderGetDatumLength(rec);
		ItemPointerSetInvalid(&(tuple.t_self));
		//tuple.t_tableOid = InvalidOid;
		tuple.t_data = rec;

		values = (Datum *) palloc(ncolumns * sizeof(Datum));
		nulls = (bool *) palloc(ncolumns * sizeof(bool));

		/* Break down the tuple into fields */
		heap_deform_tuple(&tuple, tupdesc, values, nulls);
	}
	else
	{
		values = NULL;
		nulls = NULL;
	}

	for (i = 0, j = 0; i < ncolumns; ++i)
	{
		ColumnIOData *column_info = &my_extra->columns[i];
		Oid			column_type = tupdesc->attrs[i]->atttypid;
		char	   *value;

		/* Ignore dropped columns in datatype */
		if (tupdesc->attrs[i]->attisdropped)
			continue;

		pairs[j].key = NameStr(tupdesc->attrs[i]->attname);
		pairs[j].keylen = hstoreCheckKeyLen(strlen(NameStr(tupdesc->attrs[i]->attname)));

		if (!nulls || nulls[i])
		{
			pairs[j].val = NULL;
			pairs[j].vallen = 4;
			pairs[j].isnull = true;
			pairs[j].needfree = false;
			++j;
			continue;
		}

		/*
		 * Convert the column value to text
		 */
		if (column_info->column_type != column_type)
		{
			bool		typIsVarlena;

			getTypeOutputInfo(column_type,
							  &column_info->typiofunc,
							  &typIsVarlena);
			fmgr_info_cxt(column_info->typiofunc, &column_info->proc,
						  fcinfo->flinfo->fn_mcxt);
			column_info->column_type = column_type;
		}

		value = OutputFunctionCall(&column_info->proc, values[i]);

		pairs[j].val = value;
		pairs[j].vallen = hstoreCheckValLen(strlen(value));
		pairs[j].isnull = false;
		pairs[j].needfree = false;
		++j;
	}

	ncolumns = hstoreUniquePairs(pairs, j, &buflen);

	out = hstorePairs(pairs, ncolumns, buflen);

	ReleaseTupleDesc(tupdesc);

	PG_RETURN_POINTER(out);
}
Exemple #6
0
Datum
hstore_from_array(PG_FUNCTION_ARGS)
{
	ArrayType  *in_array = PG_GETARG_ARRAYTYPE_P(0);
	int			ndims = ARR_NDIM(in_array);
	int			count;
	int4		buflen;
	HStore	   *out;
	Pairs	   *pairs;
	Datum	   *in_datums;
	bool	   *in_nulls;
	int			in_count;
	int			i;

	Assert(ARR_ELEMTYPE(in_array) == TEXTOID);

	switch (ndims)
	{
		case 0:
			out = hstorePairs(NULL, 0, 0);
			PG_RETURN_POINTER(out);

		case 1:
			if ((ARR_DIMS(in_array)[0]) % 2)
				ereport(ERROR,
						(errcode(ERRCODE_ARRAY_SUBSCRIPT_ERROR),
						 errmsg("array must have even number of elements")));
			break;

		case 2:
			if ((ARR_DIMS(in_array)[1]) != 2)
				ereport(ERROR,
						(errcode(ERRCODE_ARRAY_SUBSCRIPT_ERROR),
						 errmsg("array must have two columns")));
			break;

		default:
			ereport(ERROR,
					(errcode(ERRCODE_ARRAY_SUBSCRIPT_ERROR),
					 errmsg("wrong number of array subscripts")));
	}

	deconstruct_array(in_array,
					  TEXTOID, -1, false, 'i',
					  &in_datums, &in_nulls, &in_count);

	count = in_count / 2;

	pairs = palloc(count * sizeof(Pairs));

	for (i = 0; i < count; ++i)
	{
		if (in_nulls[i * 2])
			ereport(ERROR,
					(errcode(ERRCODE_NULL_VALUE_NOT_ALLOWED),
					 errmsg("null value not allowed for hstore key")));

		if (in_nulls[i * 2 + 1])
		{
			pairs[i].key = VARDATA_ANY(in_datums[i * 2]);
			pairs[i].val = NULL;
			pairs[i].keylen = hstoreCheckKeyLen(VARSIZE_ANY_EXHDR(in_datums[i * 2]));
			pairs[i].vallen = 4;
			pairs[i].isnull = true;
			pairs[i].needfree = false;
		}
		else
		{
			pairs[i].key = VARDATA_ANY(in_datums[i * 2]);
			pairs[i].val = VARDATA_ANY(in_datums[i * 2 + 1]);
			pairs[i].keylen = hstoreCheckKeyLen(VARSIZE_ANY_EXHDR(in_datums[i * 2]));
			pairs[i].vallen = hstoreCheckValLen(VARSIZE_ANY_EXHDR(in_datums[i * 2 + 1]));
			pairs[i].isnull = false;
			pairs[i].needfree = false;
		}
	}

	count = hstoreUniquePairs(pairs, count, &buflen);

	out = hstorePairs(pairs, count, buflen);

	PG_RETURN_POINTER(out);
}
Exemple #7
0
Datum
hstore_from_arrays(PG_FUNCTION_ARGS)
{
	int4		buflen;
	HStore	   *out;
	Pairs	   *pairs;
	Datum	   *key_datums;
	bool	   *key_nulls;
	int			key_count;
	Datum	   *value_datums;
	bool	   *value_nulls;
	int			value_count;
	ArrayType  *key_array;
	ArrayType  *value_array;
	int			i;

	if (PG_ARGISNULL(0))
		PG_RETURN_NULL();

	key_array = PG_GETARG_ARRAYTYPE_P(0);

	Assert(ARR_ELEMTYPE(key_array) == TEXTOID);

	/*
	 * must check >1 rather than != 1 because empty arrays have 0 dimensions,
	 * not 1
	 */

	if (ARR_NDIM(key_array) > 1)
		ereport(ERROR,
				(errcode(ERRCODE_ARRAY_SUBSCRIPT_ERROR),
				 errmsg("wrong number of array subscripts")));

	deconstruct_array(key_array,
					  TEXTOID, -1, false, 'i',
					  &key_datums, &key_nulls, &key_count);

	/* value_array might be NULL */

	if (PG_ARGISNULL(1))
	{
		value_array = NULL;
		value_count = key_count;
		value_datums = NULL;
		value_nulls = NULL;
	}
	else
	{
		value_array = PG_GETARG_ARRAYTYPE_P(1);

		Assert(ARR_ELEMTYPE(value_array) == TEXTOID);

		if (ARR_NDIM(value_array) > 1)
			ereport(ERROR,
					(errcode(ERRCODE_ARRAY_SUBSCRIPT_ERROR),
					 errmsg("wrong number of array subscripts")));

		if ((ARR_NDIM(key_array) > 0 || ARR_NDIM(value_array) > 0) &&
			(ARR_NDIM(key_array) != ARR_NDIM(value_array) ||
			 ARR_DIMS(key_array)[0] != ARR_DIMS(value_array)[0] ||
			 ARR_LBOUND(key_array)[0] != ARR_LBOUND(value_array)[0]))
			ereport(ERROR,
					(errcode(ERRCODE_ARRAY_SUBSCRIPT_ERROR),
					 errmsg("arrays must have same bounds")));

		deconstruct_array(value_array,
						  TEXTOID, -1, false, 'i',
						  &value_datums, &value_nulls, &value_count);

		Assert(key_count == value_count);
	}

	pairs = palloc(key_count * sizeof(Pairs));

	for (i = 0; i < key_count; ++i)
	{
		if (key_nulls[i])
			ereport(ERROR,
					(errcode(ERRCODE_NULL_VALUE_NOT_ALLOWED),
					 errmsg("null value not allowed for hstore key")));

		if (!value_nulls || value_nulls[i])
		{
			pairs[i].key = VARDATA_ANY(key_datums[i]);
			pairs[i].val = NULL;
			pairs[i].keylen = hstoreCheckKeyLen(VARSIZE_ANY_EXHDR(key_datums[i]));
			pairs[i].vallen = 4;
			pairs[i].isnull = true;
			pairs[i].needfree = false;
		}
		else
		{
			pairs[i].key = VARDATA_ANY(key_datums[i]);
			pairs[i].val = VARDATA_ANY(value_datums[i]);
			pairs[i].keylen = hstoreCheckKeyLen(VARSIZE_ANY_EXHDR(key_datums[i]));
			pairs[i].vallen = hstoreCheckValLen(VARSIZE_ANY_EXHDR(value_datums[i]));
			pairs[i].isnull = false;
			pairs[i].needfree = false;
		}
	}

	key_count = hstoreUniquePairs(pairs, key_count, &buflen);

	out = hstorePairs(pairs, key_count, buflen);

	PG_RETURN_POINTER(out);
}
Datum
plpython_to_hstore(PG_FUNCTION_ARGS)
{
	PyObject   *dict;
	volatile PyObject *items_v = NULL;
	int32		pcount;
	HStore	   *out;

	dict = (PyObject *) PG_GETARG_POINTER(0);
	if (!PyMapping_Check(dict))
		ereport(ERROR,
				(errcode(ERRCODE_WRONG_OBJECT_TYPE),
				 errmsg("not a Python mapping")));

	pcount = PyMapping_Size(dict);
	items_v = PyMapping_Items(dict);

	PG_TRY();
	{
		int32		buflen;
		int32		i;
		Pairs	   *pairs;
		PyObject   *items = (PyObject *) items_v;

		pairs = palloc(pcount * sizeof(*pairs));

		for (i = 0; i < pcount; i++)
		{
			PyObject   *tuple;
			PyObject   *key;
			PyObject   *value;

			tuple = PyList_GetItem(items, i);
			key = PyTuple_GetItem(tuple, 0);
			value = PyTuple_GetItem(tuple, 1);

			pairs[i].key = PLyObject_AsString(key);
			pairs[i].keylen = hstoreCheckKeyLen(strlen(pairs[i].key));
			pairs[i].needfree = true;

			if (value == Py_None)
			{
				pairs[i].val = NULL;
				pairs[i].vallen = 0;
				pairs[i].isnull = true;
			}
			else
			{
				pairs[i].val = PLyObject_AsString(value);
				pairs[i].vallen = hstoreCheckValLen(strlen(pairs[i].val));
				pairs[i].isnull = false;
			}
		}
		Py_DECREF(items_v);

		pcount = hstoreUniquePairs(pairs, pcount, &buflen);
		out = hstorePairs(pairs, pcount, buflen);
	}
	PG_CATCH();
	{
		Py_DECREF(items_v);
		PG_RE_THROW();
	}
	PG_END_TRY();

	PG_RETURN_POINTER(out);
}
Exemple #9
0
static void apply_changes(lua_State *L, Lua_Hstore *strg){
    HStore	   *hsout;
    int32		buflen;
    HStore	   *in;
    int			i;
    int			count;
    int         pcount;
    char	   *base;
    HEntry	   *entries;
    Pairs	   *pairs;

    if (strg->issync == 1) return;

    in = strg->hstore;
    count = HS_COUNT(in);
    base = STRPTR(in);
    entries = ARRPTR(in);

    lua_pushlightuserdata(L, strg);
    lua_gettable(L, LUA_REGISTRYINDEX);

    for (i=0; i < count; i++)
    {
        char *key = HS_KEY(entries, base, i);
        int klen = HS_KEYLEN(entries, i);
        lua_pushlstring(L, key, klen);
        lua_rawget(L, -2);
        if (lua_isnil(L,-1)){
            lua_pop(L, 1);
            lua_pushlstring(L, key, klen);
            lua_pushinteger(L, i);
            lua_rawset(L, -3);
        }else {
            lua_pop(L, 1);
        }
    }

    pcount = 0;
    lua_pushnil(L);  /* first key */

    while (lua_next(L, -2) != 0) {
        ++pcount;
        /* removes 'value'; keeps 'key' for next iteration */
        lua_pop(L, 1);
    }

    MTOLUA(L);
    pairs = palloc(pcount * sizeof(*pairs));
    MTOPG;
    i = 0;
    //-------------------------------
    lua_pushnil(L);
    while (lua_next(L, -2) != 0) {
        const char *key = lua_tostring(L, -2);
        int ltype = lua_type(L, -1);

        if (ltype == LUA_TNUMBER){
            int idx = lua_tointeger(L, -1);
            set_pair(L, &pairs[i], entries, base, idx);
        } else {
            char *mov_value = (char *)lua_touserdata (L, -1);
            set_pair_from_lv(L, &pairs[i], key, mov_value);
        }
        lua_pop(L, 1);
        ++i;
    }
    //-------------------------------
    lua_pop(L, 1);

    MTOLUA(L);
    pcount = hstoreUniquePairs(pairs, pcount, &buflen);
    hsout = hstorePairs(pairs, pcount, buflen);
    MTOPG;


    if (strg->havetodel){
        pg_datumFree(strg->datum, hs_type.byval, hs_type.len);
    }
    strg->hstore = hsout;
    strg->datum = PointerGetDatum(hsout);
    strg->issync = 1;
    strg->havetodel = 1;

    lua_pushlightuserdata(L, strg);
    lua_newtable(L);
    lua_settable(L, LUA_REGISTRYINDEX);
}