Обсуждение: 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 multipleexternal 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 usedto 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 sharedobject modules be structured in order to allow code sharing among functions? (This question is obviously related tothe 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 iswhat datepart() does). Should such functions return character strings or some other type? If they return an appropriatebuilt-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 thecurrent 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 shouldthis be done? A function named the same as a type, with one argument of some other type, is treated as an implicit type conversion ruleby 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
> 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