Hello Heikki, Thank you for responding to my email. This is what I am doing:
//========================= C file ==================================== static int get_range_lower(FunctionCallInfo fcinfo, RangeType *r1) { TypeCacheEntry *typcache; RangeBound lower; RangeBound upper; bool empty; typcache = range_get_typcache(fcinfo, RangeTypeGetOid(r1)); range_deserialize(typcache, r1, &lower, &upper, &empty); /* Return NULL if there's no finite lower bound */ if (empty || lower.infinite) PG_RETURN_NULL(); return (lower.val); } static int get_range_upper_griis(FunctionCallInfo fcinfo, RangeType *r1) { TypeCacheEntry *typcache; RangeBound lower; RangeBound upper; bool empty; typcache = range_get_typcache(fcinfo, RangeTypeGetOid(r1)); range_deserialize(typcache, r1, &lower, &upper, &empty); /* Return NULL if there's no finite upper bound */ if (empty || upper.infinite) PG_RETURN_NULL(); return (upper.val); } static RangeType * make_range(int start, int finish) { RangeBound lower; RangeBound upper; lower.val = (Datum) (start); lower.infinite = false; lower.inclusive = true; lower.lower = true; upper.val = (Datum) (finish); upper.infinite = false; upper.inclusive = false; upper.lower = false; if (!lower.infinite && !lower.inclusive) { lower.val = DirectFunctionCall2(int4pl, lower.val, Int32GetDatum(1)); lower.inclusive = true; } if (!upper.infinite && upper.inclusive) { upper.val = DirectFunctionCall2(int4pl, upper.val, Int32GetDatum(1)); upper.inclusive = false; } TypeCacheEntry *typcache; PG_RETURN_RANGE_P(range_serialize(typcache, &lower, &upper, false)); } typedef struct { int32 current; int32 finish; int32 step; } generate_series_range_fctx; static inline bool control_increment(int32 a, int32 b, int32 *result) { int64 res = (int64) a + (int64) b; if (res > PG_INT32_MAX || res < PG_INT32_MIN) { *result = 0x5EED; return true; } *result = (int32) res; return false; } PG_FUNCTION_INFO_V1(generate_ranges); Datum generate_ranges(PG_FUNCTION_ARGS) { FuncCallContext *funcctx; generate_series_range_fctx *fctx; MemoryContext oldcontext; RangeType *r1 = PG_GETARG_RANGE_P(0); RangeType *result; TypeCacheEntry *typcache; typcache = range_get_typcache(fcinfo, RangeTypeGetOid(r1)); int32 lower = get_range_lower(fcinfo, r1); int32 upper = get_range_upper(fcinfo, r1); if (SRF_IS_FIRSTCALL()) { int32 start = lower; int32 finish = upper; int32 step = 1; funcctx = SRF_FIRSTCALL_INIT(); oldcontext = MemoryContextSwitchTo(funcctx->multi_call_memory_ctx); fctx = (generate_series_range_fctx *) palloc(sizeof(generate_series_range_fctx)); fctx->current = start; fctx->finish = finish; fctx->step = step; funcctx->user_fctx = fctx; MemoryContextSwitchTo(oldcontext); } funcctx = SRF_PERCALL_SETUP(); fctx = funcctx->user_fctx; result = make_range(fctx->current, fctx->current+1); if ((fctx->step > 0 && fctx->current <= fctx->finish) || (fctx->step < 0 && fctx->current >= fctx->finish)) { if (control_increment(fctx->current, fctx->step, &fctx->current)) fctx->step = 0; SRF_RETURN_NEXT(funcctx, PointerGetDatum(result)); } else SRF_RETURN_DONE(funcctx); } //============================= SQL file ================================ CREATE FUNCTION generate_ranges(anyrange) RETURNS setof anyrange AS 'MODULE_PATHNAME' LANGUAGE C IMMUTABLE STRICT; //========================= Test File Expected ============================ SELECT generate_ranges(int4range(4,10)); generate_ranges ----------------------- [4,5) [5,6) [6,7) [7,8) [8,9) [9,10) [10,11) (7 row) //===================================================================== Regards, *Andjasubu Bungama, Patrick * Le ven. 27 nov. 2020 à 04:01, Heikki Linnakangas <hlinn...@iki.fi> a écrit : > On 26/11/2020 23:28, Patrick Handja wrote: > > Hello, > > > > I am currently working on Library with some specific operators to > > manipulate RangeType in PostGreSQL. I would like to know if it is > > possible to return a setof rangetype elements in Postresql in C-Language > > function using the suggestion like specified here: > > https://www.postgresql.org/docs/current/xfunc-c.html#XFUNC-C-RETURN-SET > > <https://www.postgresql.org/docs/current/xfunc-c.html#XFUNC-C-RETURN-SET>. > > > I have been trying this for days. If what I am trying to do is > > impossible, is there any way I can use to have a RangeType set return? > > Yes, it is possible. > > I bet there's just a silly little bug or misunderstanding in your code. > This stuff can be fiddly. Feel free to post what you have here, and I'm > sure someone will point out where the problem is very quickly. > > - Heikki >