Situation:
7.1 has a new backend interface for loadable modules. (but it
supports old 7.0 interface too)
Now the problem:
How do you tell the backend with what interface to use for
particular function? At the moment 7.1-cvs uses 'newC' instead
of 'C' in the LANGUAGE part.
But this not good:
1) the 'newC' will be quite silly after couple of years, when it
will be the standard.
2) there is another change in the horizon, which would be the
automatic detection of function parameters, or rather the
shared object should provide info about it.
3) It has nothing to do with 'C'. The loadable modules can be
programmed in any language, as long it supports C calling
conventions.
4) And IMHO "LANGUAGE 'C'" is a hack, LANGUAGE construct should be
used only for actual definitions. Now should we extend one hack
with another hack?
Requirement:
7.1 should understand the 7.0 syntax, 7.2 should understand 7.1
and 7.0 syntax. That means the dump/restore should work
between versions. Whether 7.2 has the 'oldC' handler is another
matter, but it should not load it with wrong defaults.
I propose new command:
CREATE FUNCTION name
( [ftype [, ...] ] ) RETURNS rtype
FROM [ LIBRARY ] obj_file AS link_sym
[ WITH [ TYPE = ( 0 | 1 | ... ) ]
[[,] ATTRIBUTE = ( attr [, ...] ) ] ]
This mostly like the current "CREATE FUNCTION .. LANGUAGE 'C'".
Main difference is that the TYPE=0 means the old 'C' interface
and TYPE=1 means 'newC' interface. Default is 1. (As said,
7.1 supports the old LANGUAGE 'C' variant, so I think it is
not needed the default to be 0.)
CREATE FUNCTION ... AS defn ... LANGUAGE 'C' ..
means 7.0 oldC/Informix interface. No new languages will
come in this way. (I mean those where the defn is actually
objname, symbol pair.)
This only is for compatibility. The ".. LANGUAGE .." should
be only used for the actual definitions.
Alternative:
newC will be created as:
CREATE FUNCTION .. LANGUAGE 'C' WITH (pg_params)
default is old_params, 7.1 pg_dump dumps newC with "(pg_params)".
But as I said this is a hack.
Now some future ideas. I really think that something like that
should come into PostgreSQL eventually.
LOAD MODULE name FROM [LIBRARY] foomodule.so
The lib has a struct (e.g.) pg_module_<name>_info which defines
init/remove functions, functions, operators and types. PostgreSQL
registers module somehow, and when the module gets DROPped then
PostgreSQL calls its remove funtions and removes all stuff it has
itself registered.
LOAD FUNCTION name FROM [LIBRARY] foo.so
This means that in the object file there is defined struct
(e.g.) pg_function_<name>_info. (Probably by help of macros).
{ I am not sure if the following is needed, better they go through
the LOAD MODULE? }
LOAD TYPE name FROM [LIBRARY] foo.so
Module has struct (e.g.) pg_type_<name>_info.
LOAD OPERATOR name FROM [LIBRARY] foo.so AS obj_name
Module has struct (e.g.) pg_operator_<obj_name>_info
Random notes:
* why struct not some init funtion? ->
* it will be easier to function/module programmer.
* avoids duplicate code
* makes possible different interfaces.
* main backend can detect incompatible interface
* I am not knowledgeable in dump/restore problems. Someone
who is should comment on this what features are else needed.
* The *.so finding should accept some search paths (LD_LIBRARY_PATH?)
(Does it now?)
* In future maybe some currently 'core' parts can be separated into
'core modules' e.g. all geometric stuff. So they can be
loaded only as needed.
* There was a previous discussion on modules:
Mark Hollomon's idea:
http://www.postgresql.org/mhonarc/pgsql-hackers/1999-06/msg00959.html
Jan Wieck objections:
http://www.postgresql.org/mhonarc/pgsql-hackers/1999-06/msg00983.html
IMHO the objections are not very strong but sure the modules
interface needs lot of work.
--
marko