Hi I am checking this patch
čt 12. 9. 2024 v 11:42 odesílatel Florents Tselai <florents.tse...@gmail.com> napsal: > Hi, > > The documentation on extending using C functions, > leaves a blank on how to call other internal Postgres functions. > This can leave first-timers hanging. > > I think it’d be helpful to spend some paragraphs on discussing the > DirectFunctionCall API. > > Here’s an attempt (also a PR[0]). > > Here’s the relevant HTML snippet for convenience: > > To call another version-1 function, you can use DirectFunctionCall*n*(func, > arg1,...,argn). This is particularly useful when you want to call > functions defined in the standard internal library, by using an interface > similar to their SQL signature. > > Different flavors of similar macros can be found in fmgr.h. The main > point though is that they expect a C function name to call as their first > argument (or its Oid in some cases), and actual arguments should be > supplied as Datums. They always return Datum. > > For example, to call the starts_with(text, text) from C, you can search > through the catalog and find out that its C implementation is based on the > Datum > text_starts_with(PG_FUNCTION_ARGS) function. > > In fmgr.h there are also available macros the facilitate conversions > between C types and Datum. For example to turn text* into Datum, you can > use DatumGetTextPP(X). If your extension defines additional types, it is > usually convenient to define similar macros for these types too. > I’ve also added the below example function: > > PG_FUNCTION_INFO_V1(t_starts_with); > > Datum > t_starts_with(PG_FUNCTION_ARGS) > { > Datum t1 = PG_GETARG_DATUM(0); > Datum t2 = PG_GETARG_DATUM(1); > bool bool_res; > > Datum datum_res = DirectFunctionCall2(text_starts_with, t1, t2); > bool_res = DatumGetBool(datum_res); > > PG_RETURN_BOOL(bool_res); > } > > PS1: I was not sure if src/tutorial is still relevant with this part of > the documentation. > If so, it needs updating too. > > I have few points 1. I am missing warning so NULL is not supported by DirectFunctionCall - on input and on output. Any argument should not be null, and the result should not be null. 2. The example looks little bit not consistent I propose Text *t1 = PG_GETARG_TEXT_PP(0); Text *t2 = PG_GETARG_TEXT_PP(1); bool result; result = DatumGetBool( DirectFunctionCall2(text_starts_with, PointerGetDatum(t1), PointerGetDatum(t2)); PG_RETURN_BOOL(result); or Datum t1 = PG_GETARG_DATUM(0); Datum t2 = PG_GETARG_DATUM(1); Datum result; result = DirectFunctionCall2(text_starts_with, t1, t2); PG_RETURN_DATUM(result); Both examples can show some interesting patterns (maybe can be used both) Regards Pavel > > [0] > https://github.com/Florents-Tselai/postgres/pull/1/commits/1651b7bb68e0f9c2b61e1462367295d846d253ec >