예제 #1
0
Datum pcpatch_uncompress(PG_FUNCTION_ARGS)
{
	SERIALIZED_PATCH *serpa = PG_GETARG_SERPATCH_P(0);
    PCSCHEMA *schema = pc_schema_from_pcid(serpa->pcid, fcinfo);
    PCPATCH *patch = pc_patch_deserialize(serpa, schema);
    SERIALIZED_PATCH *serpa_out = pc_patch_serialize_uncompressed(patch);
    pc_patch_free(patch);
    PG_RETURN_POINTER(serpa_out);
}
예제 #2
0
Datum pcpatch_enforce_typmod(PG_FUNCTION_ARGS)
{
	SERIALIZED_PATCH *arg = PG_GETARG_SERPATCH_P(0);
	uint32 typmod = PG_GETARG_INT32(1);
	uint32 pcid = pcid_from_typmod(typmod);
	/* We don't need to have different behavior based on explicitness. */
	/* bool isExplicit = PG_GETARG_BOOL(2); */

	/* Check if column typmod is consistent with the object */
	if ( pcid != arg->pcid )
		elog(ERROR, "column pcid (%d) and patch pcid (%d) are not consistent", pcid, arg->pcid);

	PG_RETURN_POINTER(arg);
}
예제 #3
0
Datum pcpatch_out(PG_FUNCTION_ARGS)
{
	PCPATCH *patch = NULL;
	SERIALIZED_PATCH *serpatch = NULL;
	char *hexwkb = NULL;
	PCSCHEMA *schema = NULL;

	serpatch = PG_GETARG_SERPATCH_P(0);
	schema = pc_schema_from_pcid(serpatch->pcid, fcinfo);
	patch = pc_patch_deserialize(serpatch, schema);
	hexwkb = pc_patch_to_hexwkb(patch);
	pc_patch_free(patch);
	PG_RETURN_CSTRING(hexwkb);
}
예제 #4
0
Datum pcpatch_as_text(PG_FUNCTION_ARGS)
{
	SERIALIZED_PATCH *serpatch = PG_GETARG_SERPATCH_P(0);
	text *txt;
	char *str;
	PCSCHEMA *schema = pc_schema_from_pcid(serpatch->pcid, fcinfo);
	PCPATCH *patch = pc_patch_deserialize(serpatch, schema);
	if ( ! patch )
		PG_RETURN_NULL();

	str = pc_patch_to_string(patch);
	pc_patch_free(patch);
	txt = cstring_to_text(str);
	pfree(str);
	PG_RETURN_TEXT_P(txt);
}
예제 #5
0
파일: pc_inout.c 프로젝트: gijs/pointcloud
Datum pcpatch_bytea_envelope(PG_FUNCTION_ARGS)
{
	SERIALIZED_PATCH *serpatch = PG_GETARG_SERPATCH_P(0);
	uint8 *bytes;
	size_t bytes_size;
	bytea *wkb;
	size_t wkb_size;
    PCSCHEMA *schema = pc_schema_from_pcid(serpatch->pcid, fcinfo);
	PCPATCH *pa = pc_patch_deserialize(serpatch, schema);

	if ( ! pa ) 
		PG_RETURN_NULL();	

	bytes = pc_patch_to_geometry_wkb_envelope(pa, &bytes_size);
	wkb_size = VARHDRSZ + bytes_size;
	wkb = palloc(wkb_size);
	memcpy(VARDATA(wkb), bytes, bytes_size);
	SET_VARSIZE(wkb, wkb_size);
	
	pc_patch_free(pa);
	pfree(bytes);

	PG_RETURN_BYTEA_P(wkb);
}
예제 #6
0
Datum pcpatch_numpoints(PG_FUNCTION_ARGS)
{
	SERIALIZED_PATCH *serpa = PG_GETARG_SERPATCH_P(0);
    PG_RETURN_INT32(serpa->npoints);
}
예제 #7
0
Datum pcpatch_unnest(PG_FUNCTION_ARGS)
{
	typedef struct
	{
		int nextelem;
		int numelems;
		PCPOINTLIST *pointlist;
	} pcpatch_unnest_fctx;

	FuncCallContext *funcctx;
	pcpatch_unnest_fctx *fctx;
	MemoryContext oldcontext;

	/* stuff done only on the first call of the function */
	if (SRF_IS_FIRSTCALL())
	{		
		PCPATCH *patch;
		SERIALIZED_PATCH *serpatch;
		
		/* create a function context for cross-call persistence */
		funcctx = SRF_FIRSTCALL_INIT();

		/*
		* switch to memory context appropriate for multiple function calls
		*/
		oldcontext = MemoryContextSwitchTo(funcctx->multi_call_memory_ctx);

		/*
		* Get the patch value and detoast if needed.  We can't do this
		* earlier because if we have to detoast, we want the detoasted copy
		* to be in multi_call_memory_ctx, so it will go away when we're done
		* and not before.      (If no detoast happens, we assume the originally
		* passed array will stick around till then.)
		*/
		serpatch = PG_GETARG_SERPATCH_P(0);
		patch = pc_patch_deserialize(serpatch, pc_schema_from_pcid_uncached(serpatch->pcid));

		/* allocate memory for user context */
		fctx = (pcpatch_unnest_fctx *) palloc(sizeof(pcpatch_unnest_fctx));

		/* initialize state */
		fctx->nextelem = 0;
		fctx->numelems = patch->npoints;
		fctx->pointlist = pc_pointlist_from_patch(patch);

		/* save user context, switch back to function context */
		funcctx->user_fctx = fctx;
		MemoryContextSwitchTo(oldcontext);
	}

	/* stuff done on every call of the function */
	funcctx = SRF_PERCALL_SETUP();
	fctx = funcctx->user_fctx;

	if (fctx->nextelem < fctx->numelems)
	{
		Datum elem;
		PCPOINT *pt = pc_pointlist_get_point(fctx->pointlist, fctx->nextelem);
		SERIALIZED_POINT *serpt = pc_point_serialize(pt);
		fctx->nextelem++;
		elem = PointerGetDatum(serpt);
		SRF_RETURN_NEXT(funcctx, elem);
	}
	else
	{
		/* do when there is no more left */
		SRF_RETURN_DONE(funcctx);
	}
}