Thread: I remember why I suggested CREATE FUNCTION...AS NULL

I remember why I suggested CREATE FUNCTION...AS NULL

From
Mike Mascari
Date:
A few weeks ago there was a discussion on how views should be
treated during dump/reload, and whether or not to change pg_dump
to use CREATE VIEW instead of the current CREATE TABLE/CREATE
RULE sequence. I suggested at that time that the dependencies
issue could be resolved if PostgreSQL would allow for the
creation of function prototypes in conjunction with ALTER
FUNCTION to supply the body of the function later.

Although I don't see it on the TODO list, one of the FAQs on
General is the problem related to triggers or rules which are
based upon functions. If a user executes a DROP/CREATE sequence
to change the function's body, those triggers or rules based upon
the function break, since the OID has changed.

The solution tossed around is to create a SQL command such as
"ALTER FUNCTION" or "CREATE OR REPLACE FUNCTION", etc. Under the
assumption that such a command were to exist, its sole purpose
would be to change the function implementation without changing
the OID. 

Now back to pg_dump. Since the temporary solution to eliminating
dependency problems is to dump in OID order, with the current
code, things won't break. But with an ALTER FUNCTION, dumping in
OID order could very well break the schema:

CREATE TABLE employees (key int4);

CREATE FUNCTION numpeople() RETURNS int4 AS'SELECT COUNT(*) FROM employees' LANGUAGE 'plpgsql';

CREATE VIEW AS SELECT numpeople();

CREATE TABLE managers (key int4);

ALTER FUNCTION numpeople() AS 'SELECT COUNT(*) FROM managers' LANGUAGE 'plpgsql';

So what to do?

1) Don't create an ALTER FUNCTION command?
2) Change pg_dump to walk through dependencies?
3) Or devise a manner by which pg_dump can dump objects in a
certain sequence such that dependencies never break?

Any comments?

Mike Mascari

P.S. The reason why I'm asking is I thought I could at least
contribute some trivial SQL commands such as a CREATE FUNCTION
... AS NULL/ALTER FUNCTION, but it seems there are many
consequences to everything.


Re: I remember why I suggested CREATE FUNCTION...AS NULL

From
Stephan Szabo
Date:
On Fri, 8 Sep 2000, Mike Mascari wrote:
> The solution tossed around is to create a SQL command such as
> "ALTER FUNCTION" or "CREATE OR REPLACE FUNCTION", etc. Under the
> assumption that such a command were to exist, its sole purpose
> would be to change the function implementation without changing
> the OID. 
> 
> Now back to pg_dump. Since the temporary solution to eliminating
> dependency problems is to dump in OID order, with the current
> code, things won't break. But with an ALTER FUNCTION, dumping in
> OID order could very well break the schema:
> 
> CREATE TABLE employees (key int4);
> 
> CREATE FUNCTION numpeople() RETURNS int4 AS
>  'SELECT COUNT(*) FROM employees' LANGUAGE 'plpgsql';
> 
> CREATE VIEW AS SELECT numpeople();
> 
> CREATE TABLE managers (key int4);
> 
> ALTER FUNCTION numpeople() AS 
>  'SELECT COUNT(*) FROM managers' LANGUAGE 'plpgsql';

Actually, I think this would still work, because it
doesn't check the table name existance until it's 
used for the first time, not when it's created.

> So what to do?
> 
> 1) Don't create an ALTER FUNCTION command?
> 2) Change pg_dump to walk through dependencies?
> 3) Or devise a manner by which pg_dump can dump objects in a
> certain sequence such that dependencies never break?

Well, I was discussing something related a few weeks (?) ago
for constraints, some kind of system that kept track of
what objects were dependent on what other objects.  Unfortunately,
it's not possible to do it completely without an awful lot
of work because you could have arguments to functions that
turned into objects to be dependent to.

You could limit the effect by defining the functions as NULL
(if you were to do that) in oid order and changing their code
later in the dump.  That way all of the objects are there
but may not be usable at that time.




Re: I remember why I suggested CREATE FUNCTION...AS NULL

From
Tom Lane
Date:
Mike Mascari <mascarm@mascari.com> writes:
> Now back to pg_dump. Since the temporary solution to eliminating
> dependency problems is to dump in OID order, with the current
> code, things won't break. But with an ALTER FUNCTION, dumping in
> OID order could very well break the schema:

Yes, that's been understood all along to be the weak spot of dumping
in OID order.  But you can already break dump-in-OID-order with
existing commands like ALTER TABLE ADD CONSTRAINT.  I think that the
advantages of ALTER FUNCTION are well worth the slightly increased risk
of dump/reload difficulties.

> 2) Change pg_dump to walk through dependencies?

The trouble with that is that dependency analysis is a monstrous job,
and one that would make pg_dump even more fragile and backend-version-
dependent than it is now.  Besides, with ALTER it is possible to create
*circular* dependencies, so even after you'd done the work you'd still
not have a bulletproof solution, just a 99.9% solution instead of a 99%
solution.  (Exact numbers open to debate, obviously, but you see my
point.)

> 3) Or devise a manner by which pg_dump can dump objects in a
> certain sequence such that dependencies never break?

If you've got one, step right up to the plate and swing away ;-).
You might be on the right track with the notion of creating functions
with dummy bodies and then doing ALTER later.  I haven't thought it
through in detail, but maybe something based on that attack could work.
        regards, tom lane


Re: I remember why I suggested CREATE FUNCTION...AS NULL

From
Tom Lane
Date:
Stephan Szabo <sszabo@megazone23.bigpanda.com> writes:
>> ALTER FUNCTION numpeople() AS 
>> 'SELECT COUNT(*) FROM managers' LANGUAGE 'plpgsql';

> Actually, I think this would still work, because it
> doesn't check the table name existance until it's 
> used for the first time, not when it's created.

But SQL-language function bodies are checked at entry, not only
at first use.  (I consider it a deficiency of plpgsql that it
doesn't do likewise.)
        regards, tom lane