Any reason to keep HEAP_HASOID_OLD?

Started by David Rowley6 months ago3 messageshackers
Beta feature

Hackorum builds and tests every patch posted to the lists, not only commitfest submissions. This is Hackorum's own CI rather than the PostgreSQL project's, and it is still under testing - please report anything that looks wrong.

appliessuccessCI history

You can run a PostgreSQL built from this patch straight from Docker, with no checkout and no build:

docker run --rm -p 5432:5432 ghcr.io/hackorum-dev/postgres-patch:t139502
psql -h localhost -U postgres

Built from patchset v3 (message #3), October 22, 2026 at 01:53 AM.

Every patchset is also pushed to a branch of our PostgreSQL fork, so you can check out the same tree CI built. Without a PostgreSQL checkout:

git clone --branch t139502_3 https://github.com/hackorum-dev/postgres.git

In a checkout you already have, add the fork once:

git remote add hackorum https://github.com/hackorum-dev/postgres.git

then, for this patchset and every later one:

git fetch hackorum t139502_3 && git checkout t139502_3

Patchset v3 (message #3) is on t139502_3

Jump to latest
#1David Rowley
dgrowleyml@gmail.com

Andres mentioned to me that I might want to look at
HeapTupleHeaderGetOidOld() as there's a comment and some code there
that would lead you to believe we can still have tuples with oids. If
that were true, the code I recently added for getting 'tp' in
slot_selectively_deform_heap_tuple() is wrong.

#define HEAP_HASOID_OLD 0x0008 /* has an object-id field */

On 11.22, I tried:

create extension pageinspect;
create table t1 (a int) with oids;
insert into t1 select generate_Series(1,1000);
select count(*) from heap_page_items(get_raw_page('public.t1',0))
where t_infomask & 8 <> 0;

count
-------
185

alter table t1 set without oids;

select count(*) from heap_page_items(get_raw_page('public.t1',0))
where t_infomask & 8 <> 0;
count
-------
0

And also, if I try to pg_upgrade before SET WITHOUT OIDS, I get:

$ pg_upgrade -d pgdata11 -D pgdata -b ~/pg11/bin -B ~/pg/bin
Performing Consistency Checks
-----------------------------
Checking cluster versions ok
Checking database user is the install user ok
Checking database connection settings ok
Checking for prepared transactions ok
Checking for system-defined composite types in user tables ok
Checking for reg* data types in user tables ok
Checking for contrib/isn with bigint-passing mismatch ok
Checking for user-defined encoding conversions ok
Checking for user-defined postfix operators ok
Checking for incompatible polymorphic functions ok
Checking for tables WITH OIDS fatal

So, I'm not following how we could get a tuple with OIDs in versions after 11.

Should we get rid of HEAP_HASOID_OLD and the code that relates to it?

David

#2Andres Freund
andres@anarazel.de
In reply to: David Rowley (#1)
Re: Any reason to keep HEAP_HASOID_OLD?

Hi,

On 2026-04-28 16:27:59 +1200, David Rowley wrote:

Andres mentioned to me that I might want to look at
HeapTupleHeaderGetOidOld() as there's a comment and some code there
that would lead you to believe we can still have tuples with oids. If
that were true, the code I recently added for getting 'tp' in
slot_selectively_deform_heap_tuple() is wrong.

#define HEAP_HASOID_OLD 0x0008 /* has an object-id field */

On 11.22, I tried:

create extension pageinspect;
create table t1 (a int) with oids;
insert into t1 select generate_Series(1,1000);
select count(*) from heap_page_items(get_raw_page('public.t1',0))
where t_infomask & 8 <> 0;

count
-------
185

alter table t1 set without oids;

select count(*) from heap_page_items(get_raw_page('public.t1',0))
where t_infomask & 8 <> 0;
count
-------
0

Yea, it seems we've started rewriting tables for SET WITHOUT OIDS a long time
ago:
/*
* If we dropped the OID column, must adjust pg_class.relhasoids and tell
* Phase 3 to physically get rid of the column. We formerly left the
* column in place physically, but this caused subtle problems. See
* http://archives.postgresql.org/pgsql-hackers/2009-02/msg00363.php
*/
if (attnum == ObjectIdAttributeNumber)

I also verified that we don't allow SET WITHOUT OIDS when it's used as a row
type in another table.

And also, if I try to pg_upgrade before SET WITHOUT OIDS, I get:

$ pg_upgrade -d pgdata11 -D pgdata -b ~/pg11/bin -B ~/pg/bin
Performing Consistency Checks
-----------------------------
Checking cluster versions ok
Checking database user is the install user ok
Checking database connection settings ok
Checking for prepared transactions ok
Checking for system-defined composite types in user tables ok
Checking for reg* data types in user tables ok
Checking for contrib/isn with bigint-passing mismatch ok
Checking for user-defined encoding conversions ok
Checking for user-defined postfix operators ok
Checking for incompatible polymorphic functions ok
Checking for tables WITH OIDS fatal

So, I'm not following how we could get a tuple with OIDs in versions after 11.

I don't see it either. Wonder why I / decided to leave it :/.

Should we get rid of HEAP_HASOID_OLD and the code that relates to it?

Looks like it.

Greetings,

Andres Freund

#3shihao zhong
zhong950419@gmail.com
In reply to: Andres Freund (#2)
Re: Any reason to keep HEAP_HASOID_OLD?

Should we get rid of HEAP_HASOID_OLD and the code that relates to it?

Looks like it.

Patch attached. It removes the define, the doc paragraph about the oid
field, and everything pageinspect did with it.

The bit is kept as a comment so nobody reuses it.

master only.

Thanks,
Shihao

Attachments:

t139502_3
v1-0001-Remove-HEAP_HASOID_OLD.patchapplication/octet-stream; name=v1-0001-Remove-HEAP_HASOID_OLD.patchDownload+159-41