Esempio n. 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);
}
Datum
hstore_slice_to_hstore(PG_FUNCTION_ARGS)
{
    HStore	   *hs = PG_GETARG_HS(0);
    HEntry	   *entries = ARRPTR(hs);
    char	   *ptr = STRPTR(hs);
    ArrayType  *key_array = PG_GETARG_ARRAYTYPE_P(1);
    HStore	   *out;
    int			nkeys;
    Pairs	   *key_pairs = hstoreArrayToPairs(key_array, &nkeys);
    Pairs	   *out_pairs;
    int			bufsiz;
    int			lastidx = 0;
    int			i;
    int			out_count = 0;

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

    out_pairs = palloc(sizeof(Pairs) * nkeys);
    bufsiz = 0;

    /*
     * we exploit the fact that the pairs list is already sorted into strictly
     * increasing order to narrow the hstoreFindKey search; each search can
     * start one entry past the previous "found" entry, or at the lower bound
     * of the last search.
     */

    for (i = 0; i < nkeys; ++i)
    {
        int			idx = hstoreFindKey(hs, &lastidx,
                                        key_pairs[i].key, key_pairs[i].keylen);

        if (idx >= 0)
        {
            out_pairs[out_count].key = key_pairs[i].key;
            bufsiz += (out_pairs[out_count].keylen = key_pairs[i].keylen);
            out_pairs[out_count].val = HS_VAL(entries, ptr, idx);
            bufsiz += (out_pairs[out_count].vallen = HS_VALLEN(entries, idx));
            out_pairs[out_count].isnull = HS_VALISNULL(entries, idx);
            out_pairs[out_count].needfree = false;
            ++out_count;
        }
    }

    /*
     * we don't use uniquePairs here because we know that the pairs list is
     * already sorted and uniq'ed.
     */

    out = hstorePairs(out_pairs, out_count, bufsiz);

    PG_RETURN_POINTER(out);
}
Esempio n. 3
0
File: hstore_io.c Progetto: d/gpdb
Datum
hstore_from_text(PG_FUNCTION_ARGS)
{
	text	   *key;
	text	   *val = NULL;
	Pairs		p;
	HStore	   *out;

	if (PG_ARGISNULL(0))
		PG_RETURN_NULL();

	p.needfree = false;
	key = PG_GETARG_TEXT_PP(0);
	p.key = VARDATA_ANY(key);
	p.keylen = hstoreCheckKeyLen(VARSIZE_ANY_EXHDR(key));

	if (PG_ARGISNULL(1))
	{
		p.vallen = 0;
		p.isnull = true;
	}
	else
	{
		val = PG_GETARG_TEXT_PP(1);
		p.val = VARDATA_ANY(val);
		p.vallen = hstoreCheckValLen(VARSIZE_ANY_EXHDR(val));
		p.isnull = false;
	}

	out = hstorePairs(&p, 1, p.keylen + p.vallen);

	PG_RETURN_POINTER(out);
}
Esempio n. 4
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);
}
Esempio n. 5
0
File: hstore_io.c Progetto: d/gpdb
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);
}
Esempio n. 6
0
File: hstore_io.c Progetto: d/gpdb
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);
}
Esempio n. 7
0
File: hstore_io.c Progetto: d/gpdb
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);
}
Esempio n. 8
0
File: hstore_io.c Progetto: d/gpdb
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);
}
Esempio n. 9
0
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);
}
Esempio n. 10
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);
}
Esempio n. 11
0
HStore * adeven_count_int_array( Datum* i_data, int n, bool * nulls )
{
    int i, j, biggest = 0;
    int exp = 1;
    int * a = palloc0( sizeof( int ) * n );
    int * b = palloc0( sizeof( int ) * n );
    int * c = palloc0( sizeof( int ) * n );

    for( i = 0 ; i < n; ++i )
    {
        a[i] = DatumGetInt32( i_data[i] );
        if( a[i] > biggest )
        {
            biggest = a[i];
        }
    }

    while( biggest / exp > 0 )
    {
        int box[10] = { 0 };
        for( i = 0; i < n; i++ )
        {
            box[a[i] / exp % 10]++;
        }
        for( i = 1; i < 10; i++ )
        {
            box[i] += box[i - 1];
        }
        for( i = n - 1; i >= 0; i-- )
        {
            b[--box[a[i] / exp % 10]] = a[i];
        }
        for( i = 0; i < n; i++ )
        {
            a[i] = b[i];
        }
        exp *= 10;
    }

    int m = 0;

    for( i = 0; i < n; ++i )
    {
        b[i] = 0;
    }

    for( i = 0, j = i + 1; j <= n; j++ )
    {
        if( a[i]==a[j] )
        {
            b[m] = a[i];
            if( c[m] == 0 )
            {
                c[m]++;
            }
            c[m]++;
            continue;
        }
        if( c[m] == 0 )
        {
            c[m]  = 1;
        }
        b[m++]=a[i];
        i=j;
    }

    n = 0;
    while( c[n] != 0 )
    {
        ++n;
    }

    Pairs * pairs = palloc0( n * sizeof( Pairs ) );
    int4 buflen = 0;

    for( i = 0; i < n; ++i )
    {
        int digit_key_num = adeven_count_get_digit_num( b[i] );
        int digit_val_num = adeven_count_get_digit_num( c[i] );
        char * dig_key_str = palloc0(digit_key_num);
        char * dig_val_str = palloc0(digit_val_num);
        sprintf( dig_key_str, "%d", b[i] );
        sprintf( dig_val_str, "%d", c[i] );
        pairs[i].key = dig_key_str;
        pairs[i].keylen =  digit_key_num;
        pairs[i].val = dig_val_str;
        pairs[i].vallen =  digit_val_num;
        pairs[i].isnull = false;
        pairs[i].needfree = false;
        buflen += pairs[i].keylen;
        buflen += pairs[i].vallen;
    }
    HStore * out;
    out = hstorePairs( pairs, n, buflen );
    pfree( a );
    pfree( b );
    pfree( c );
    return out;
}
Esempio n. 12
0
HStore * adeven_count_text_array( Datum* i_data, int n, bool * nulls )
{
    adeven_count_Array a;
    adeven_count_init_array( &a, 100 );
    AvlTree tree = make_empty( NULL );
    int i, j;

    for( i = 0; i < n; ++i )
    {
        if( ! nulls[i] )
        {
            bool found = false;
            size_t datum_len = VARSIZE( i_data[i] ) - VARHDRSZ;
            char * current_datum = ( char * ) palloc ( datum_len );
            memcpy( current_datum, VARDATA( i_data[i] ), datum_len );

            Position position = find( current_datum, datum_len, tree );
            if( position == NULL )
            {
                j = a.used;
                tree = insert( current_datum, datum_len, j, tree );
                adeven_count_insert_array( &a, current_datum, datum_len );
            }
            else
            {
                j = value( position );
            }

            a.counts[j] += 1;
        }
    }

    // save sort permutation to create pairs in order of ascending keys
    // we assume that postgres stores the pairs in that order
    int * perm = ( int * ) palloc ( a.used * sizeof( int ) );
    sort_perm( tree, perm );

    make_empty( tree );

    Pairs * pairs = palloc0( a.used * sizeof( Pairs ) );
    int4 buflen = 0;
    for( i = 0; i < a.used; ++i )
    {
        j = perm[i];
        if( a.array[j] != NULL )
        {
            size_t datum_len = a.sizes[j];
            int digit_num = adeven_count_get_digit_num( a.counts[j] );
            char * dig_str = palloc0(digit_num);
            sprintf( dig_str, "%d", a.counts[j] );
            a.counts_str[j] = dig_str;
            pairs[i].key = a.array[j];
            pairs[i].keylen =  datum_len;
            pairs[i].val = dig_str;
            pairs[i].vallen =  digit_num;
            pairs[i].isnull = false;
            pairs[i].needfree = false;
            buflen += pairs[i].keylen;
            buflen += pairs[i].vallen;
        }
    }
    HStore * out;
    out = hstorePairs( pairs, a.used, buflen );
    //adeven_count_free_array( &a );
    return out;
}