Re: [PATCH] Add some documentation on how to call internal functions

From: Florents Tselai <florents(dot)tselai(at)gmail(dot)com>
To: Pavel Stehule <pavel(dot)stehule(at)gmail(dot)com>
Cc: pgsql-hackers <pgsql-hackers(at)lists(dot)postgresql(dot)org>
Subject: Re: [PATCH] Add some documentation on how to call internal functions
Date: 2024-10-09 12:38:45
Message-ID: 3D2B82D0-7E4A-4029-AAE8-87F915720096@gmail.com
Views: Raw Message | Whole Thread | Download mbox | Resend email
Thread:
Lists: pgsql-hackers

> On 9 Oct 2024, at 2:57 PM, Pavel Stehule <pavel(dot)stehule(at)gmail(dot)com> wrote:
>
> Hi
>
> I am checking this patch
>
> čt 12. 9. 2024 v 11:42 odesílatel Florents Tselai <florents(dot)tselai(at)gmail(dot)com <mailto:florents(dot)tselai(at)gmail(dot)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 DirectFunctionCalln(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.

In response to

Responses

Browse pgsql-hackers by date

  From Date Subject
Next Message Robert Haas 2024-10-09 12:41:10 Re: Proposal to Enable/Disable Index using ALTER INDEX
Previous Message Matthias van de Meent 2024-10-09 12:34:55 Use MAX_PARALLEL_WORKER_LIMIT consistently in guc_tables.c