Re: Calling a SQL function inside a C function

From: Eric Zhu <erkangzhu(at)gmail(dot)com>
To: Pavel Stehule <pavel(dot)stehule(at)gmail(dot)com>
Cc: pgsql-general <pgsql-general(at)lists(dot)postgresql(dot)org>
Subject: Re: Calling a SQL function inside a C function
Date: 2020-08-27 05:53:28
Message-ID: CAF0GwR3SpCLe+gHRo8=u4Kojj8pUkqHFhT00i5aJdpTZZjXAQg@mail.gmail.com
Views: Raw Message | Whole Thread | Download mbox | Resend email
Thread:
Lists: pgsql-general

Much thanks! This is exactly what I was looking for:

funcname = stringToQualifiedNameList("times_two");
> funcoid = LookupFuncName(func_name, 1, funcargs, false);
>
> Datum ret = OidFunctionCall1(funcoid, Int32GetDatum(13));
>

Eric

On Wed, Aug 26, 2020 at 8:53 PM Pavel Stehule <pavel(dot)stehule(at)gmail(dot)com>
wrote:

> Hi
>
> čt 27. 8. 2020 v 0:43 odesílatel Eric Zhu <erkangzhu(at)gmail(dot)com> napsal:
>
>> How do I call a function defined using CREATE FUNCTION in SQL inside a C
>> function in an extension? I feel this should be possible as the query
>> parser is able to resolve the function names and arguments in a raw string
>> query. I want to know if there is a standard way to look up for
>> user-defined functions in the backend.
>>
>> For example, I have a function defined in SQL:
>>
>> ```
>> CREATE FUNCTION times_two(x integer)
>> RETURNS integer AS $$
>> SELECT x*2
>> $$ LANGUAGE SQL;
>> ```
>>
>> Now I wish to call `times_two()` in a C extension similar to:
>>
>> ```
>> // Look up for the user-defined function times_two()
>> // ...
>>
>> // Use the function.
>> Datum ret = DirectFunctionCall(times_two, Int32GetDatum(13));
>> ```
>>
>
> Surely, it is not possible. You can use SPI interface, which is most
> simple https://www.postgresql.org/docs/current/spi.html and instead of
> calling function, you can call "SELECT times_two(x)". PLpgSQL is working
> like that. It ensures necessary checks, and you don't need to manually
> handle NULL values.
>
> For direct function call of SQL function, you can use OidFunctionCall
>
> some like
>
> Oid funcargs = {INT4OID};
> List *funcname;
> Oid funcoid
>
> funcname = stringToQualifiedNameList("times_two");
> funcoid = LookupFuncName(func_name, 1, funcargs, false);
>
> Datum ret = OidFunctionCall1(funcoid, Int32GetDatum(13));
>
> Attention - for direct function calls the function should not to have any
> NULL argument, and should not to return NULL.
>
> Regards
>
> Pavel
>
>
>
>
>> Best,
>> Eric
>>
>

In response to

Browse pgsql-general by date

  From Date Subject
Next Message Laurenz Albe 2020-08-27 06:53:53 Re: Are advisory locks guaranteed to be First Come First Serve? And can the behavior be relied upon?
Previous Message Hemil Ruparel 2020-08-27 04:40:07 Are advisory locks guaranteed to be First Come First Serve? And can the behavior be relied upon?