Thread: oid not "UNIQUE" for use as FOREIGN KEY?

oid not "UNIQUE" for use as FOREIGN KEY?

From
"Ernesto Baschny"
Date:
Hi!

Imagine I have tables like those in PostgreSQL 7.1.3:

CREATE TABLE rabattgruppe (
    gruppe_oid OID,
    produktgruppe VARCHAR(256)
);

CREATE TABLE gruppe (
    obergruppe_oid OID,
    name VARCHAR(32)
);

Then I try to establish integrity check

ALTER TABLE gruppe ADD
  FOREIGN KEY (obergruppe_oid) REFERENCES gruppe (oid);

But:

NOTICE:  ALTER TABLE ... ADD CONSTRAINT will create implicit
trigger(s) for FOREIGN KEY check(s)
ERROR:  UNIQUE constraint matching given keys for referenced
table "gruppe" not found

I thought the problem was I was referring to the same table,
but also this doesn't work:

ALTER TABLE rabattgruppe ADD
  FOREIGN KEY (gruppe_oid) REFERENCES gruppe (oid);

NOTICE:  ALTER TABLE ... ADD CONSTRAINT will create implicit
trigger(s) for FOREIGN KEY check(s)
ERROR:  UNIQUE constraint matching given keys for referenced
table "gruppe" not found

Now, what is the problem?  "oid" for sure should be an UNIQUE
field in each table, doesn't it?  Is it a bug?


Thanks,
Ernesto

--
Ernesto Baschny <ernst@baschny.de>
 http://www.baschny.de - PGP Key:
http://www.baschny.de/pgp.txt
 Sao Paulo/Brasil - Stuttgart/Germany
 Ernst@IRCnet - ICQ# 2955403


Re: oid not "UNIQUE" for use as FOREIGN KEY?

From
Stephan Szabo
Date:
On Tue, 23 Oct 2001, Ernesto Baschny wrote:

> Now, what is the problem?  "oid" for sure should be an UNIQUE
> field in each table, doesn't it?  Is it a bug?

To your last two questions, no and yes.  Unless you place a unique index
on oid, it is not actually guaranteed unique (due to potential
wraparound), however the alter code also doesn't yet handle referencing to
non-user columns.


Re: oid not "UNIQUE" for use as FOREIGN KEY?

From
Tom Lane
Date:
Stephan Szabo <sszabo@megazone23.bigpanda.com> writes:
> On Tue, 23 Oct 2001, Ernesto Baschny wrote:
>> Now, what is the problem?  "oid" for sure should be an UNIQUE
>> field in each table, doesn't it?  Is it a bug?

> To your last two questions, no and yes.  Unless you place a unique index
> on oid, it is not actually guaranteed unique (due to potential
> wraparound), however the alter code also doesn't yet handle referencing to
> non-user columns.

As of yesterday, I think this is a bug, because you can now create a
unique constraint on the OID column ... but I see it still doesn't work:

regression=# CREATE TABLE gruppe (
regression(#     obergruppe_oid OID,
regression(#     name VARCHAR(32),
regression(#     unique(oid));
NOTICE:  CREATE TABLE/UNIQUE will create implicit index 'gruppe_oid_key' for table 'gruppe'
CREATE
regression=# ALTER TABLE gruppe ADD
regression-#   FOREIGN KEY (obergruppe_oid) REFERENCES gruppe (oid);
NOTICE:  ALTER TABLE will create implicit trigger(s) for FOREIGN KEY check(s)
ERROR:  UNIQUE constraint matching given keys for referenced table "gruppe" not found
regression=#

I wonder why the ALTER code doesn't notice the index on oid?

            regards, tom lane

Re: oid not "UNIQUE" for use as FOREIGN KEY?

From
Stephan Szabo
Date:
On Tue, 23 Oct 2001, Tom Lane wrote:

> Stephan Szabo <sszabo@megazone23.bigpanda.com> writes:
> > On Tue, 23 Oct 2001, Ernesto Baschny wrote:
> >> Now, what is the problem?  "oid" for sure should be an UNIQUE
> >> field in each table, doesn't it?  Is it a bug?
>
> > To your last two questions, no and yes.  Unless you place a unique index
> > on oid, it is not actually guaranteed unique (due to potential
> > wraparound), however the alter code also doesn't yet handle referencing to
> > non-user columns.
>
> As of yesterday, I think this is a bug, because you can now create a
> unique constraint on the OID column ... but I see it still doesn't work:

The yes was to it being a bug.  I've always treated it as such since you
could make the "constraint" by making the index manually, just a low
priority one since such uses of oid should be discouraged anyway. :)

> regression=# CREATE TABLE gruppe (
> regression(#     obergruppe_oid OID,
> regression(#     name VARCHAR(32),
> regression(#     unique(oid));
> NOTICE:  CREATE TABLE/UNIQUE will create implicit index 'gruppe_oid_key' for table 'gruppe'
> CREATE
> regression=# ALTER TABLE gruppe ADD
> regression-#   FOREIGN KEY (obergruppe_oid) REFERENCES gruppe (oid);
> NOTICE:  ALTER TABLE will create implicit trigger(s) for FOREIGN KEY check(s)
> ERROR:  UNIQUE constraint matching given keys for referenced table "gruppe" not found
> regression=#
>
> I wonder why the ALTER code doesn't notice the index on oid?

I think it's the use of rel_attrs[<number>] to get the attribute
name rather than the function you mentioned to Christopher (I
think) because I didn't know of its existance at the time.  It should be
easy, I'll send a fix since it's now easier to run into.


Re: oid not "UNIQUE" for use as FOREIGN KEY?

From
Tom Lane
Date:
Stephan Szabo <sszabo@megazone23.bigpanda.com> writes:
> I think it's the use of rel_attrs[<number>] to get the attribute
> name rather than the function you mentioned to Christopher (I
> think) because I didn't know of its existance at the time.  It should be
> easy, I'll send a fix since it's now easier to run into.

I'm on it already ...

            regards, tom lane

Re: oid not "UNIQUE" for use as FOREIGN KEY?

From
"Ernesto Baschny"
Date:
On 23 Oct 2001 at 9:18, Stephan Szabo wrote:

> > (...)
> > As of yesterday, I think this is a bug, because you can
now create a
> > unique constraint on the OID column ... but I see it still
doesn't work:

> The yes was to it being a bug.  I've always treated it as
such since you
> could make the "constraint" by making the index manually,
just a low
> priority one since such uses of oid should be discouraged
anyway. :)

Thats interesting, as I thought that would be an "elegant"
way of doing that.  I've got the idea from Bruce Momjian's
book, here:

  http://www.ca.postgresql.org/docs/aw_pgsql_book/node71.html

Should I instead stick to separate INTEGER PRIMARY KEY _id
fields instead of using the OID's for it?  What use would one
want to make of an OID then?


--
Ernesto Baschny <ernst@baschny.de>
 http://www.baschny.de - PGP Key:
http://www.baschny.de/pgp.txt
 Sao Paulo/Brasil - Stuttgart/Germany
 Ernst@IRCnet - ICQ# 2955403


Re: oid not "UNIQUE" for use as FOREIGN KEY?

From
Stephan Szabo
Date:
On Tue, 23 Oct 2001, Ernesto Baschny wrote:

> On 23 Oct 2001 at 9:18, Stephan Szabo wrote:
>
> > > (...)
> > > As of yesterday, I think this is a bug, because you can
> now create a
> > > unique constraint on the OID column ... but I see it still
> doesn't work:
>
> > The yes was to it being a bug.  I've always treated it as
> such since you
> > could make the "constraint" by making the index manually,
> just a low
> > priority one since such uses of oid should be discouraged
> anyway. :)
>
> Thats interesting, as I thought that would be an "elegant"
> way of doing that.  I've got the idea from Bruce Momjian's
> book, here:

Well, the smiley was meant to be indicative of the fact that it's
just my opinion on the whole matter (I'll give some more detail below)
In general, oids aren't quite as unique as the book makes them out
to be since they are only effectively an int4 AFAIK.

>   http://www.ca.postgresql.org/docs/aw_pgsql_book/node71.html
>
> Should I instead stick to separate INTEGER PRIMARY KEY _id
> fields instead of using the OID's for it?  What use would one
> want to make of an OID then?

Well, it's going to work soon since Tom's on it, but in general,
I think assuming an oid is actually unique is dangerous since
in large systems it may wrap (although this will be less bad
in 7.2) and at that point you either have to deal with:
 1) You've made a unique index on oid to make it really unique.
    Now some inserts fail due to the unique constraint when you
    run into an oid that already exists in the table.  You have
    to realize that this is a transitory problem and that if you
    try again enough times it'll work. Heaven help you if you
    are doing large insert ... select queries.
 2) You don't make a unique index.  Now you have two rows with the
    same oid value. The foreign key stuff won't like that, nor
    will subqueries that expect a single row, etc...

With your own key, while it may still wrap around, it's much
more within your control.  This is of course just an opinion and
I'm sure someone will jump in with a pro oid use one too. :)
Of course, most of this is academic for most people who aren't
likely to run into oid conflicts of this sort, but...