Thread: Missing OID rant

Missing OID rant

From
"John Sidney-Woollett"
Date:
<rant>

Please can someone explain why Postgres cannot recognize that objects
(referenced by pl/pgsql functions) whose OID no longer exists could in
fact be found (as new objects) if the function was reparsed and compiled
again.

Here's an example:

Create table t1 (f1 integer);
insert into t1 values (1);

CREATE OR REPLACE FUNCTION GetOne() RETURNS integer AS '
DECLARE
  i                  integer;
BEGIN
  select f1 into i from t1 limit 1;
  return i;
END;
' LANGUAGE 'plpgsql';

select GetOne(); <-- WORKS OK

drop table t1;
Create table t1 (f1 integer);
insert into t1 values (1);

select GetOne(); <-- ERROR:  relation with OID xxxxxx does not exist

Now I know why this is happening, but it is really crap.

Here's a solution (similar to what Oracle does (I believe):

Whenever you delete an object, you locate any functions (or other objects)
referencing that object's OID, and you mark them as invalid, and any
subsequent objects that now refer to the newly invalidated object(s).

When a function is invoked which is marked invalid, then it is first
parsed/compiled again - if that is successful then the function executes
as before. If compiling is unsuccessful, then the standard "relation with
OID xxxxxx does not exist" error could be returned (or perhaps an even
better error message detailing the actual name of the missing object, God
forbid!).

Where else would this be useful? How about the following scenario when you
want to make use of a temporary table in a pl/pgsql function:

-- This will not work
...
CREATE TEMP TABLE foo AS SELECT ....;
FOR r IN SELECT * FROM foo
LOOP
....
END LOOP;
DROP TABLE foo;

-- You have to do this
...
CREATE TEMP TABLE foo AS SELECT ....;
FOR r IN EXECUTE "SELECT * FROM foo"
LOOP
....
END LOOP;
DROP TABLE foo;
...

This might even make rebuilding databases easier because you could refer
to objects (during the rebuild) that don't yet exist (haven't been
inserted yet), but that would be validated the first time the object was
actually accessed.

There are loads of instances (db in flux, move table to another schema
etc) why you might want/need to drop a table, and recreate it. But in
Postgres, you have to reapply all DDL statements to the db that referenced
that dropped/recreated object - this is just not fun!

I don't know, but cannot believe that it would be hard to implement this,
and although many might not think that it is worth it, it is a really NICE
feature in Oracle. And when you're used to it, it is a royal pain in the
ass not having it.

</rant>

BTW, I still love postgres - I just want it to be better!

John Sidney-Woollett

Re: Missing OID rant

From
"John Sidney-Woollett"
Date:
Alvaro Herrera said:
> Actually, in your example the only thing you need to do is close the
> connection and reconnect.  I agree it would be nice to recompile the
> function automatically, but it's not as bad as you put it.

Thanks, I wasn't aware of that.

John Sidney-Woollett

Re: Missing OID rant

From
Alvaro Herrera
Date:
On Thu, Apr 22, 2004 at 02:07:39PM +0100, John Sidney-Woollett wrote:

> There are loads of instances (db in flux, move table to another schema
> etc) why you might want/need to drop a table, and recreate it. But in
> Postgres, you have to reapply all DDL statements to the db that referenced
> that dropped/recreated object - this is just not fun!

Actually, in your example the only thing you need to do is close the
connection and reconnect.  I agree it would be nice to recompile the
function automatically, but it's not as bad as you put it.

--
Alvaro Herrera (<alvherre[a]dcc.uchile.cl>)
"Sallah, I said NO camels! That's FIVE camels; can't you count?"
(Indiana Jones)

Re: Missing OID rant

From
"John Sidney-Woollett"
Date:
Tom Lane said:
> "John Sidney-Woollett" <johnsw@wardbrook.com> writes:
>> Please can someone explain why Postgres cannot recognize that objects
>> (referenced by pl/pgsql functions) whose OID no longer exists could in
>> fact be found (as new objects) if the function was reparsed and compiled
>> again.
>
> Criticism in the form of a patch would be useful.

I know but I don't have the expertise to do that - I was only trying to
raise the issue... :)

>> Whenever you delete an object, you locate any functions (or other
>> objects)
>> referencing that object's OID, and you mark them as invalid, and any
>> subsequent objects that now refer to the newly invalidated object(s).
>
> Yup, this is on the TODO list, and has been for awhile:
>
> * Flush cached query plans when their underlying catalog data changes

Is the query plan cached for the life of the session, or the life of the
cache/database/postmaster session?

Isn't removing the plan from the cache, and marking objects invalid two
separate although related issues?

>> I don't know, but cannot believe that it would be hard to implement
>> this,
>
> Step right up ...

Believe you me, you don't want my code - it's been quite a few years since
I've done any C programming, a patch I produced might set Postgres back 5
years!!

BTW, I was only highlighting the issue because the missing OID message bit
me in the ass again today, and I didn't realise that it existed as an
outstanding todo item.

I guess that there are other missing features like exception handling and
nested transactions which are more important and need attention more
urgently...

John Sidney-Woollett

Re: Missing OID rant

From
Tom Lane
Date:
"John Sidney-Woollett" <johnsw@wardbrook.com> writes:
> Please can someone explain why Postgres cannot recognize that objects
> (referenced by pl/pgsql functions) whose OID no longer exists could in
> fact be found (as new objects) if the function was reparsed and compiled
> again.

Criticism in the form of a patch would be useful.

> Whenever you delete an object, you locate any functions (or other objects)
> referencing that object's OID, and you mark them as invalid, and any
> subsequent objects that now refer to the newly invalidated object(s).

Yup, this is on the TODO list, and has been for awhile:

* Flush cached query plans when their underlying catalog data changes

> I don't know, but cannot believe that it would be hard to implement this,

Step right up ...

            regards, tom lane

Re: Missing OID rant

From
"John Sidney-Woollett"
Date:
Jan Wieck said:
> Exactly, and because of that we want you to do the easy stuff with the
> cache invalidation, so that we have the time to think about the others.

Might be easy for you... I shudder when I try to imagine the size of the
mountain that that simple task would represent for me ;)

John Sidney-Woollett

Re: Missing OID rant

From
Jan Wieck
Date:
John Sidney-Woollett wrote:

> Tom Lane said:

>> Yup, this is on the TODO list, and has been for awhile:
>>
>> * Flush cached query plans when their underlying catalog data changes
>
> Is the query plan cached for the life of the session, or the life of the
> cache/database/postmaster session?

DB connection is the lifetime of PL/pgSQL cached plans.

>
> Isn't removing the plan from the cache, and marking objects invalid two
> separate although related issues?

It is.

>
>>> I don't know, but cannot believe that it would be hard to implement
>>> this,
>>
>> Step right up ...
>
> Believe you me, you don't want my code - it's been quite a few years since
> I've done any C programming, a patch I produced might set Postgres back 5
> years!!

Well, that's what I do with French people, I convince them that it hurts
less if they rather talk English or German instead of me uttering
something in their language.

>
> BTW, I was only highlighting the issue because the missing OID message bit
> me in the ass again today, and I didn't realise that it existed as an
> outstanding todo item.
>
> I guess that there are other missing features like exception handling and
> nested transactions which are more important and need attention more
> urgently...

Exactly, and because of that we want you to do the easy stuff with the
cache invalidation, so that we have the time to think about the others.


Jan

>
> John Sidney-Woollett
>
> ---------------------------(end of broadcast)---------------------------
> TIP 1: subscribe and unsubscribe commands go to majordomo@postgresql.org


--
#======================================================================#
# It's easier to get forgiveness for being wrong than for being right. #
# Let's break this rule - forgive me.                                  #
#================================================== JanWieck@Yahoo.com #