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

Fri, 25 Aug 2000 08:08:50 -0600 (MDT)
Brook Milligan <brook@biology.nmsu.edu>
advice on extensions needed
> - 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

Fri, 25 Aug 2000 15:12:39 +0000
Thomas Lockhart <lockhart@alumni.caltech.edu>
Re: advice on extensions needed
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

Fri, 25 Aug 2000 11:25:45 -0400
Tom Lane <tgl@sss.pgh.pa.us>
Re: advice on extensions needed 
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

Fri, 25 Aug 2000 11:30:53 -0600 (MDT)
Brook Milligan <brook@biology.nmsu.edu>
Re: advice on extensions needed
   > - 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

Fri, 25 Aug 2000 12:19:30 -0600 (MDT)
Brook Milligan <brook@biology.nmsu.edu>
Re: advice on extensions needed
> 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?
>         /* conversions */
> A * A (const B *);
> B * B (const A *);

Right.

                     - Thomas

Sat, 26 Aug 2000 07:00:11 +0000
Thomas Lockhart <lockhart@alumni.caltech.edu>
Re: advice on extensions needed