0

Currently the docs says,

There are two ways you can build a composite data value (henceforth a “tuple”): you can build it from an array of Datum values, or from an array of C strings that can be passed to the input conversion functions of the tuple's column data types.

When it comes to returning that "tuple" it says,

One way to declare this function in SQL is:

CREATE TYPE __retcomposite AS (f1 integer, f2 integer, f3 integer);

CREATE OR REPLACE FUNCTION retcomposite(integer, integer)
    RETURNS SETOF __retcomposite
    AS 'filename', 'retcomposite'
    LANGUAGE C IMMUTABLE STRICT;

A different way is to use OUT parameters:

CREATE OR REPLACE FUNCTION retcomposite(IN integer, IN integer,
   OUT f1 integer, OUT f2 integer, OUT f3 integer)
   RETURNS SETOF record
   AS 'filename', 'retcomposite'
   LANGUAGE C IMMUTABLE STRICT;

Notice that in this method the output type of the function is formally an anonymous record type.

But is there a way to put the contents of __retcomposite in C too? It seems kind of sloppy to have to write/maintain the prototype for the function in C, and in another language (SQL).

To expand a bit, there is a hook when you load the .so into the database with _PG_init. Is there no way to write my function signature there. It seems redundant to have to do something like this where I tell C what all my types are (the initial defaults) when I then have to tell SQL the very same thing.

1 Answer 1

0

I don't know what you are talking about.

The “prototype” is only in SQL in the shape of the CREATE FUNCTION statement.

In C, all functions are declared and defined alike:

PG_FUNCTION_INFO_V1(retcomposite);

Datum
retcomposite(PG_FUNCTION_ARGS)
{
    [...]
}

You could probably use the PG_init function in the shared object to run a CREATE FUNCTION statement. Then you'd need to LOAD the shared object as superuser to define the function. I don't think that would be an improvement: I don't think that LOAD 'retcomposite' is much simpler than CREATE EXTENSION retcomposite, and the C code would become much more complicated (check if the function is already there, invoke SPI, ...).

3
  • "The “prototype” is only in SQL in the shape of the CREATE FUNCTION statement." I'm asking if it's possible to put this prototype (declaration of arguments and return types) in C too, so it can live in the same file and I don't have to manually keep them in sync. Is there a method to write the CREATE FUNCTION command in C in the foo extension and have it load when someone writes CREATE EXTENSION foo Nov 3, 2021 at 7:38
  • No, that's not possible. How do you propose to create a database object from a definition in C? I had assumed that you are complaining about a perceived redundancy, but it seems that you simply don't agree with the way C functions work in PostgreSQL. Nov 3, 2021 at 7:41
  • I expanded in the question Nov 3, 2021 at 8:03

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.