GetNewOidWithIndex can cause infinite loop on user tables(not catalog).

Started by Jacky Lengabout 18 years ago3 messagesbugs
Jump to latest
#1Jacky Leng
lengjianquan@163.com

e.g.
--Create table t(a int) with oids;
--create unique index it on t(oid);
--insert 4G-16384 rows into t;
--insert into t values(1);
As all oids has been used, GetNewObjectId will never find a usable Oid,
so.....

#2Heikki Linnakangas
heikki.linnakangas@enterprisedb.com
In reply to: Jacky Leng (#1)
Re: GetNewOidWithIndex can cause infinite loop on user tables(not catalog).

Jacky Leng wrote:

e.g.
--Create table t(a int) with oids;
--create unique index it on t(oid);
--insert 4G-16384 rows into t;
--insert into t values(1);
As all oids has been used, GetNewObjectId will never find a usable Oid,
so.....

GetNewObjectId doesn't try to guarantee uniqueness. You will get
duplicate oids, unless you have a unique index on the oid column.

If you do have a unique index, you will get into an endless loop in
GetNewOidWithIndex. Therefore: don't do that.

At worst, you might be able to turn this into a denial-of-service
attack, by something like 2^32 CREATE TEMPORARY TABLE calls, using up
the OID space of pg_class. But if you have access to CREATE TEMPORARY
TABLE, there's plenty of other ways to launch a DoS attack, so I
wouldn't worry about this too much.

Per documentation of CREATE TABLE:

Using OIDs in new applications is not recommended: where possible, using a SERIAL or other sequence generator as the table's primary key is preferred.

A sequence will give you more control over wrap-around as well.

--
Heikki Linnakangas
EnterpriseDB http://www.enterprisedb.com

#3Tom Lane
tgl@sss.pgh.pa.us
In reply to: Heikki Linnakangas (#2)
Re: GetNewOidWithIndex can cause infinite loop on user tables(not catalog).

"Heikki Linnakangas" <heikki@enterprisedb.com> writes:

Jacky Leng wrote:

--Create table t(a int) with oids;
--create unique index it on t(oid);
--insert 4G-16384 rows into t;

... Therefore: don't do that.

Indeed. It might be a good idea if that loop had a
CHECK_FOR_INTERRUPTS, though.

regards, tom lane