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.

asked Nov 3, 2021 at 3:45

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, ...).

answered Nov 3, 2021 at 7:34
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 Commented 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. Commented Nov 3, 2021 at 7:41
  • I expanded in the question Commented Nov 3, 2021 at 8:03

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.