Defining the Input and Output Functions in PostgreSQL
Now that you have created the input (external to internal) and output (internal to external) functions in C, you must compile them into a shared object module:
$ make -f makefile fcur.so
Next, create a symbolic link between fcur.so and PostgreSQL's preferred package directory so that PostgreSQL knows how to find out code:
$ ln -s `pwd`/fcur.so `pg_config --pkglibdir`
Now you can define the input and output functions in PostgreSQL:
movies=# CREATE OR REPLACE FUNCTION fcur_in( opaque ) movies-# RETURNS opaque movies-# AS 'fcur.so' LANGUAGE 'C' movies=# IMMUTABLE STRICT CREATE movies=# CREATE OR REPLACE FUNCTION fcur_out( opaque ) movies-# RETURNS opaque movies-# AS 'fcur.so' LANGUAGE 'C' movies=# IMMUTABLE STRICT
Notice that each of these functions expects an opaque parameter and returns an opaque value. You might be thinking that fcur_in() should take a null-terminated string and return a FCUR. That makes sense except for two minor problems: PostgreSQL doesn't have a SQL data type that represents a null-terminated string and PostgreSQL doesn't know anything about the FCUR data type yet. Okay, those aren't exactly minor problems. PostgreSQL helps you out a little here by letting you define these functions in terms of opaque. The opaque data type tells PostgreSQL that a SQL data type doesn't define the data that you are working with. One of the special properties of an opaque function is that you can't call it directly:
movies=# SELECT fcur_in( '5(1.3/GPB)' ); ERROR: getTypeOutputInfo: Cache lookup of type 0 failed
This error message means, "don't try that again."
We've defined each of these functions with two additional attributes. The IMMUTABLE attribute tells PostgreSQL that calling this function twice with the same argument(s) is guaranteed to return the same result. If PostgreSQL knows that a function IMMUTABLE, it can optimize certain operations by computing the return value once and caching the result (hence the clever name).