Subject: Re: oid's

From: postarch (Postgres Mailing Archive)
Date: Mon, 04 Nov 91 08:48:11 PST

In message <[email-masked]> you write:
> Dear Postgres group,
> 
> I have two separate questions/requests related to the oid's.
> First, would it be possible to show the oid of a new instance in the
> "return"-string.  (e.g. APPEND-54321 with 54321 the oid of the new instance).
> I assume that the monitor shows the same string as
> returned by the function "char* PQexec(query)" in libpq.
> There are some (rare multi-user) cases in which it would be
> impossible to obtain the oid of this instance in any other way.

I had thought this might be fairly straightforward and useful to provide.
However, before we try to decide what to implement
i would be interested to hear the multi-user situation you cite to get a
feel for how general or specific the problem really is.

Jeff Meredith
[email-masked]

>Second, would it be possible to set the oid of a new instance
>before the rules triggered by this append are executed.
>A small example:
>   create c1 ( attr = int4)\g
>   create c2 ( father = oid)\g
>   define rule add is
>      on append to c1
>      do append c2 ( father = new.oid )\g
>Now we only do explicit appends to c1:
>   append c1 ( attr = 2 )\g
>The father attribute of c2 is set to 0 and not to the oid of the new c1.
>However, we have several useful applicaions for these types of rules.
>Could you give any comments on these issues?
>
>Regards, Peter van Oosterom.

I am afraid that there is no straightforward solution to this problem.
The rules are invoked before an oid is assigned to the new tuple.
Although this can be easily (??? famous last words...) fixed by hacking
the code a little bit, there is nothing a user can do about.

However, there is a way to work around the problem, by having an extra
(user defined) attribute in "c1":

    create c1 (attr = int4, my_oid = oid)

Then you must define a C function "my_newoid" that generates new oids.
For example:

    #include "tmp/postgres.h"
    oid
    my_newoid()
    {
	return(newoid());
    }

(this function uses the internal postgres function "newoid" that generates new
oids - unfortunately, "newoid" is not registered in the system catalogs
and can not be called directly from POSTQUEL, that's why you have to
call it indirectly through "my_newoid")
Then compile it (don't forget the "-G 0" and the appropriate "-I" options!
see the examples in the demo if you encounter any problems) and define it as:

    define c function foo (file = "/object/file/goes/here.o", returntype = oid)

Use this function in a rule that automatically fills the "my_oid" field.
    
    define rule my_oid_rule is
    on append to c1
    do replace new(my_oid = my_newoid())

Finally define the rule that appends the appropriate tuple to "c2"

    define rule add is
    on append to c1
    do append c2 (father = new.my_oid)

and the right thing will happen. Note that the system will detect the
dependency between the two rules and will activate them in the right order
(first "my_oid_rule" and then "add").

Of course this is not such an elegant solution but it works!

Spyros Potamianos
The Official POSTGRES Tuple Level Rule System Person

P.S. Unfortunately, rules of the form:

    on append to c1
    do replace new(oid = my_newoid())

will not work (they will be silently ignored). A rule (in the current
implementation) can only change the values of user defined attributes.