st 9. 10. 2024 v 14:39 odesílatel Florents Tselai <florents.tse...@gmail.com> napsal:
> > > On 9 Oct 2024, at 2:57 PM, Pavel Stehule <pavel.steh...@gmail.com> wrote: > > 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. > > > You’re right. > > > 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) > > > The example can be extended a bit more. > I like your first proposal. > > My primary purpose with this patch is to show explicitly how > one goes from SQL types, to Datum and/or char*/text if necessary, > use some internal C function (even if it doesn’t have an SQL equivalent). > and then return back an SQL type. > > So, simply GET_ARG_DATUM() and then PG_RETURN_DATUM() defeats the purpose. > so please, send updated patch + sentence missing null support, and I think so this patch can be ok Regards Pavel