3

I'm writing a c function to make a range type on a float range. I find PostgreSQL allows using numrange(low, high) to create a nunrange, but I can't find the corresponding part in the C code. The only method I find(i hope it works) is

    TypeCacheEntry *cache=lookup_type_cache(3907,TYPECACHE_RANGE_INFO);
    RangeBound  lower;
    lower.val = Float8GetDatum(b.zmin);
    lower.infinite = false;
    lower.inclusive = false;
    lower.lower = true;
    RangeBound  upper;
    upper.val = Float8GetDatum(b.zmax);
    upper.infinite = false;
    upper.inclusive = false;
    upper.lower = true;
    return PointerGetDatum(range_serialize(cache, &lower,&upper,false));

However the solution seems ugly... Could anyone give me some instruction about how to return a numrange in a more beautiful way?

I use DirectFunctionCall like this following the instruction of @Laurenz Albe

Datum s1= DirectFunctionCall1(float8_numeric,Float8GetDatum(b.zmin));
Datum s2= DirectFunctionCall1(float8_numeric,Float8GetDatum(b.zmax));
return DirectFunctionCall2(range_constructor2,s1,s2);

And sadly got a SIGSIEV in range_get_typcache

1 Answer 1

2

First, find the name of the C function for the two-argument version of numrange:

SELECT prosrc
FROM pg_proc
WHERE proname = 'numrange'
  AND pronargs = 2;

       prosrc       
--------------------
 range_constructor2
(1 row)

Now find that function in the source:

> git grep range_constructor2

src/backend/commands/typecmds.c:    static const char *const prosrc[2] = {"range_constructor2",
src/backend/utils/adt/rangetypes.c:range_constructor2(PG_FUNCTION_ARGS)
src/include/catalog/pg_proc.dat:  proargtypes => 'int4 int4', prosrc => 'range_constructor2' },
src/include/catalog/pg_proc.dat:  proargtypes => 'numeric numeric', prosrc => 'range_constructor2' },
src/include/catalog/pg_proc.dat:  proargtypes => 'timestamp timestamp', prosrc => 'range_constructor2' },
src/include/catalog/pg_proc.dat:  proargtypes => 'timestamptz timestamptz', prosrc => 'range_constructor2' },
src/include/catalog/pg_proc.dat:  proargtypes => 'date date', prosrc => 'range_constructor2' },
src/include/catalog/pg_proc.dat:  proargtypes => 'int8 int8', prosrc => 'range_constructor2' },

So your function is in src/backend/utils/adt/rangetypes.c.

You should be able to call it with DirectFunctionCall2.

Sign up to request clarification or add additional context in comments.

2 Comments

I got a SIGSIEV in range_get_typcache when writing return DirectFunctionCall2(range_constructor2,Float8GetDatum(b.zmin),Float8GetDatum(b.zmax));, where b.zmin and b.zmax are double values... Possibly still something wrong, as i didn't pass the argtypes to the function?
Right. Then you must use a more complicated way of calling the function.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.