advice on extensions needed
I'm in the process of extending PostgreSQL and need a bit of advice
that I don't seem to get from the manuals.
- When dynamically linking functions must there be at most one
function per shared object module or can there be multiple external
entry points within a single shared object?
- If the latter, will multiple copies of the file be loaded (e.g., one
per function invoked) or will the same copy be used to resolve all
the multiple external entry points?
- I am writing some functions to handle some new types. These
functions logically should share code. How should the shared object
modules be structured in order to allow code sharing among
functions? (This question is obviously related to the previous
two.)
- Is it possible to write functions to automatically convert one
extended type into another? If so, how should this be done?
- Some of my types will be complex and so it makes sense to have
functions extract components of the types (an analogy is what
datepart() does). Should such functions return character strings or
some other type? If they return an appropriate built-in (or
extended?) type will the needed conversion be provided
automatically depending on context?
By the way, the new web pages seem to be missing some links. For
example, the "users-lounge/documentation" link just goes to a
directory; shouldn't there be an actual page with links to the various
components of the documentation?
Also, in the docs for Chapter 5. Extending SQL: Types there is a code
example with the following:
elog(WARN, ...);
elog.h does not define WARN. Should this be changed to NOTICE in the
docs?
Thanks for your help.
Cheers,
Brook
- When dynamically linking functions must there be at most one
function per shared object module or can there be multiple external
entry points within a single shared object?
multiple entry points are fine.
- If the latter, will multiple copies of the file be loaded (e.g., one
per function invoked) or will the same copy be used to resolve all
the multiple external entry points?
afaik the same file is used.
- I am writing some functions to handle some new types. These
functions logically should share code. How should the shared object
modules be structured in order to allow code sharing among
functions? (This question is obviously related to the previous
two.)
You want *multiple* loadable modules to share code between them? afaik
you will have to make direct calls to the dynamic linker to get this to
happen. Usually, I resolve all symbols within the loadable module since
it is self-contained. However, it may be that the dynamic linker is
smart enough to find symbols from previously-loaded modules; try it out
and then check src/backend/port/dynloader/... for details.
- Is it possible to write functions to automatically convert one
extended type into another? If so, how should this be done?
Is "extended type" the same as a "user defined type"? Or something else?
If it is a UDT then sure, write away. And if you provide a function with
the target type as the name and taking one argument having the source
type, Postgres will know how to convert it automatically when required.
- Some of my types will be complex and so it makes sense to have
functions extract components of the types (an analogy is what
datepart() does). Should such functions return character strings or
some other type? If they return an appropriate built-in (or
extended?) type will the needed conversion be provided
automatically depending on context?
Sure, as long as you have the right conversion functions defined and as
long as the conversion can be chosen without ambiguity.
elog.h does not define WARN. Should this be changed to NOTICE in the
docs?
That seems to already be fixed.
- Thomas
Brook Milligan <brook@biology.nmsu.edu> writes:
- When dynamically linking functions must there be at most one
function per shared object module or can there be multiple external
entry points within a single shared object?
Multi functions per shared object file is fine (in fact normal, I'd
say). See the example in src/tutorial/.
- If the latter, will multiple copies of the file be loaded (e.g., one
per function invoked) or will the same copy be used to resolve all
the multiple external entry points?
Just one copy --- see src/backend/utils/fmgr/dfmgr.c
- Is it possible to write functions to automatically convert one
extended type into another? If so, how should this be done?
A function named the same as a type, with one argument of some other
type, is treated as an implicit type conversion rule by the parser.
Also, in the docs for Chapter 5. Extending SQL: Types there is a code
example with the following:
elog(WARN, ...);
elog.h does not define WARN. Should this be changed to NOTICE in the
docs?
elog(ERROR) is the correct equivalent. Looks like someone fixed that
already; I can't find elog WARN anywhere in the current docs, except for
/home/postgres/pgsql/HISTORY: Change elog(WARN) to elog(ERROR)(Bruce)
regards, tom lane
Thanks for the quick responses. They are very helpful.
elog(ERROR) is the correct equivalent. Looks like someone fixed that
already; I can't find elog WARN anywhere in the current docs, except for
/home/postgres/pgsql/HISTORY: Change elog(WARN) to elog(ERROR)(Bruce)
I was going by the web page
(http://www.postgresql.org/users-lounge/docs/7.0/programmer/xtypes.htm),
which still by the way mentions WARN. Perhaps they are out of date.
Cheers,
Brook
- Is it possible to write functions to automatically convert one
extended type into another? If so, how should this be done?
A function named the same as a type, with one argument of some other
type, is treated as an implicit type conversion rule by the parser.
Just to make sure I understand. Suppose I create two user-defined
types A and B and want interconversions. I will need the following
functions, right?
/* I/O */
A * A_in (const char *);
char * A_out (const A *);
B * B_in (const char *);
char * B_out (const B *);
/* conversions */
A * A (const B *);
B * B (const A *);
Thanks again.
Cheers,
Brook