Обсуждение: question re internal functions requiring initdb
I was trying to see if it was possible to create an 'internal' function
after bootstrap (i.e. without listing in pg_proc.h). The test case below
illustrates that it is indeed possible.
test=# CREATE OR REPLACE FUNCTION mytest(text,int,int) RETURNS text AS
'text_substr' LANGUAGE 'internal' IMMUTABLE STRICT;
CREATE FUNCTION
test=# select mytest('abcde',2,2); mytest
-------- bc
(1 row)
It made me wonder why don't we always create internal functions this
way, or at least all except a core set of bootstrapped functions. Am I
wrong in thinking that it would eliminate the need to initdb every time
a new internal function is added?
We could have a script, say "internal_functions.sql", that would contain
"CREATE OR REPLACE FUNCTION...LANGUAGE 'internal'..." for each internal
function and be executed by initdb. When a new builtin function is added
to the backend, you could run this script directly to update your catalog.
Just a thought. Any reason we can't or don't want to do this?
Joe
Joe Conway <mail@joeconway.com> writes:
> It made me wonder why don't we always create internal functions this
> way, or at least all except a core set of bootstrapped functions.
I don't believe it will actually work: you *must* add an internal
function to include/catalog/pg_proc.h, or it won't get into the function
lookup table that's built by Gen_fmgrtab.sh.
It is true that you don't have to force an initdb right away, but
there's an efficiency penalty IIRC (can't bypass the lookup table
search, or something ... read the fmgr code for details).
regards, tom lane
Tom Lane wrote: > Joe Conway <mail@joeconway.com> writes: >>It made me wonder why don't we always create internal functions this >>way, or at least all except a core set of bootstrapped functions. > > I don't believe it will actually work: you *must* add an internal > function to include/catalog/pg_proc.h, or it won't get into the function > lookup table that's built by Gen_fmgrtab.sh. > > It is true that you don't have to force an initdb right away, but > there's an efficiency penalty IIRC (can't bypass the lookup table > search, or something ... read the fmgr code for details). > OK -- I see what you mean now. For a *user alias* of an existing builtin function fmgr_isbuiltin(), which does a binary search on the sorted fmgr_builtins array, will fail. So there is a speed penalty in that the function is looked up with fmgr_lookupByName(), which does a sequential scan through the fmgr_builtins array. Regardless, if the function is not listed in the fmgr_builtins array at all, which it won't be if Gen_fmgrtab.sh doesn't see it in pg_proc.h, then the lookup will fail entirely. I guess I would have found this out on my own if I had carried the experiment out a little farther. Shucks! Joe