From b0e170f2c8c57b683c74e6cccfb7e46356dbacea Mon Sep 17 00:00:00 2001
From: Andres Freund <andres@anarazel.de>
Date: Wed, 14 Nov 2018 17:41:43 -0800
Subject: [PATCH v3] Remove WITH OIDs support.

System table oids are now normal columns.

Author: Andres Freund
Discussion: https://postgr.es/m/20180930034810.ywp2c7awz7opzcfr@alap3.anarazel.de
---
 contrib/adminpack/adminpack.c                 |   2 +-
 contrib/btree_gist/expected/cash.out          |   2 +-
 contrib/btree_gist/expected/oid.out           |  40 ++-
 contrib/btree_gist/sql/cash.sql               |   2 +-
 contrib/btree_gist/sql/oid.sql                |  25 +-
 contrib/dblink/dblink.c                       |   8 +-
 contrib/file_fdw/file_fdw.c                   |   5 +-
 contrib/pageinspect/heapfuncs.c               |   7 +-
 contrib/pg_buffercache/pg_buffercache_pages.c |   2 +-
 contrib/pg_visibility/pg_visibility.c         |   4 +-
 contrib/postgres_fdw/deparse.c                |  35 +-
 .../postgres_fdw/expected/postgres_fdw.out    |  41 +--
 contrib/postgres_fdw/postgres_fdw.c           |  34 +-
 contrib/postgres_fdw/sql/postgres_fdw.sql     |  11 -
 contrib/sepgsql/expected/alter.out            |  18 -
 contrib/sepgsql/expected/ddl.out              |   6 +-
 contrib/sepgsql/label.c                       |   8 +-
 contrib/sepgsql/sql/alter.sql                 |   4 -
 contrib/sepgsql/sql/ddl.sql                   |   3 +-
 contrib/test_decoding/test_decoding.c         |   7 -
 doc/src/sgml/catalogs.sgml                    |   9 -
 doc/src/sgml/config.sgml                      |  29 --
 doc/src/sgml/datatype.sgml                    |  23 +-
 doc/src/sgml/ddl.sgml                         |  58 ---
 doc/src/sgml/file-fdw.sgml                    |   5 +-
 doc/src/sgml/plpgsql.sgml                     |  10 +-
 doc/src/sgml/pltcl.sgml                       |  18 -
 doc/src/sgml/protocol.sgml                    |   9 +-
 doc/src/sgml/ref/alter_foreign_table.sgml     |  28 +-
 doc/src/sgml/ref/alter_table.sgml             |  37 +-
 doc/src/sgml/ref/copy.sgml                    |  32 +-
 .../sgml/ref/create_materialized_view.sgml    |   5 +-
 doc/src/sgml/ref/create_table.sgml            |  89 +----
 doc/src/sgml/ref/create_table_as.sgml         |  35 +-
 doc/src/sgml/ref/select_into.sgml             |   7 -
 doc/src/sgml/release-9.1.sgml                 |   2 +-
 doc/src/sgml/release-9.2.sgml                 |   2 +-
 doc/src/sgml/release-9.3.sgml                 |   2 +-
 src/backend/access/brin/brin_tuple.c          |   2 +-
 src/backend/access/common/heaptuple.c         |  29 +-
 src/backend/access/common/reloptions.c        |  27 +-
 src/backend/access/common/tupconvert.c        |  16 +-
 src/backend/access/common/tupdesc.c           |  18 +-
 src/backend/access/gin/ginutil.c              |   2 +-
 src/backend/access/gist/gistscan.c            |   2 +-
 src/backend/access/heap/heapam.c              |  71 +---
 src/backend/access/heap/tuptoaster.c          |  21 +-
 src/backend/access/transam/commit_ts.c        |   2 +-
 src/backend/access/transam/multixact.c        |   2 +-
 src/backend/access/transam/twophase.c         |   2 +-
 src/backend/access/transam/varsup.c           |   4 +-
 src/backend/access/transam/xlogfuncs.c        |   2 +-
 src/backend/bootstrap/bootparse.y             |  18 +-
 src/backend/bootstrap/bootscanner.l           |   1 -
 src/backend/bootstrap/bootstrap.c             |  10 +-
 src/backend/catalog/Catalog.pm                |   6 +-
 src/backend/catalog/aclchk.c                  |  60 ++--
 src/backend/catalog/catalog.c                 | 150 +++++---
 src/backend/catalog/genbki.pl                 |  25 +-
 src/backend/catalog/heap.c                    |  84 ++---
 src/backend/catalog/index.c                   |   9 +-
 src/backend/catalog/indexing.c                |  15 +-
 src/backend/catalog/information_schema.sql    |  14 +-
 src/backend/catalog/namespace.c               |  15 +-
 src/backend/catalog/objectaddress.c           | 112 ++++--
 src/backend/catalog/pg_aggregate.c            |   5 +-
 src/backend/catalog/pg_collation.c            |  10 +-
 src/backend/catalog/pg_constraint.c           |  27 +-
 src/backend/catalog/pg_conversion.c           |  13 +-
 src/backend/catalog/pg_enum.c                 |  12 +-
 src/backend/catalog/pg_largeobject.c          |  18 +-
 src/backend/catalog/pg_namespace.c            |  11 +-
 src/backend/catalog/pg_operator.c             |  33 +-
 src/backend/catalog/pg_proc.c                 |  20 +-
 src/backend/catalog/pg_publication.c          |   8 +-
 src/backend/catalog/pg_subscription.c         |  14 +-
 src/backend/catalog/pg_type.c                 |  55 ++-
 src/backend/catalog/toasting.c                |   4 +-
 src/backend/commands/alter.c                  |   8 +-
 src/backend/commands/amcmds.c                 |   7 +-
 src/backend/commands/cluster.c                |  16 +-
 src/backend/commands/copy.c                   | 142 +-------
 src/backend/commands/createas.c               |  21 +-
 src/backend/commands/dbcommands.c             |  40 +--
 src/backend/commands/event_trigger.c          |  23 +-
 src/backend/commands/explain.c                |   2 +-
 src/backend/commands/extension.c              |  23 +-
 src/backend/commands/foreigncmds.c            |  36 +-
 src/backend/commands/functioncmds.c           |  21 +-
 src/backend/commands/indexcmds.c              |  29 +-
 src/backend/commands/matview.c                |   5 +-
 src/backend/commands/opclasscmds.c            |  39 +-
 src/backend/commands/policy.c                 |  17 +-
 src/backend/commands/prepare.c                |   2 +-
 src/backend/commands/proclang.c               |  11 +-
 src/backend/commands/publicationcmds.c        |  33 +-
 src/backend/commands/schemacmds.c             |  20 +-
 src/backend/commands/seclabel.c               |   1 +
 src/backend/commands/sequence.c               |   2 +-
 src/backend/commands/statscmds.c              |  10 +-
 src/backend/commands/subscriptioncmds.c       |  26 +-
 src/backend/commands/tablecmds.c              | 323 ++---------------
 src/backend/commands/tablespace.c             |  22 +-
 src/backend/commands/trigger.c                |  34 +-
 src/backend/commands/tsearchcmds.c            |  64 ++--
 src/backend/commands/typecmds.c               |  27 +-
 src/backend/commands/user.c                   |  40 ++-
 src/backend/commands/vacuum.c                 |   6 +-
 src/backend/commands/vacuumlazy.c             |   6 -
 src/backend/commands/variable.c               |  12 +-
 src/backend/commands/view.c                   |   1 -
 src/backend/executor/execExpr.c               |   1 -
 src/backend/executor/execJunk.c               |   7 +-
 src/backend/executor/execMain.c               |  64 ----
 src/backend/executor/execPartition.c          |   2 +-
 src/backend/executor/execSRF.c                |   4 +-
 src/backend/executor/execTuples.c             |  31 +-
 src/backend/executor/execUtils.c              |  10 -
 src/backend/executor/functions.c              |   6 +-
 src/backend/executor/nodeAgg.c                |   4 +-
 src/backend/executor/nodeCustom.c             |   2 +-
 src/backend/executor/nodeForeignscan.c        |   2 +-
 src/backend/executor/nodeFunctionscan.c       |   4 +-
 src/backend/executor/nodeIndexonlyscan.c      |   2 +-
 src/backend/executor/nodeModifyTable.c        |  41 +--
 src/backend/executor/nodeSubplan.c            |   4 +-
 src/backend/executor/spi.c                    |  24 +-
 src/backend/foreign/foreign.c                 |   2 +-
 src/backend/optimizer/util/plancat.c          |   3 +-
 src/backend/parser/gram.y                     |  51 +--
 src/backend/parser/parse_clause.c             |  40 ---
 src/backend/parser/parse_oper.c               |   2 +-
 src/backend/parser/parse_relation.c           |  20 +-
 src/backend/parser/parse_target.c             |   2 +-
 src/backend/parser/parse_type.c               |  18 +-
 src/backend/parser/parse_utilcmd.c            |  46 +--
 src/backend/postmaster/autovacuum.c           |   6 +-
 src/backend/postmaster/pgstat.c               |   7 +-
 .../libpqwalreceiver/libpqwalreceiver.c       |   2 +-
 src/backend/replication/logical/launcher.c    |   2 +-
 src/backend/replication/walsender.c           |   6 +-
 src/backend/rewrite/rewriteDefine.c           |  24 +-
 src/backend/rewrite/rewriteRemove.c           |   2 +-
 src/backend/rewrite/rewriteSupport.c          |   6 +-
 src/backend/statistics/extended_stats.c       |   2 +-
 src/backend/storage/large_object/inv_api.c    |   2 +-
 src/backend/tcop/pquery.c                     |   9 +-
 src/backend/tsearch/wparser.c                 |   4 +-
 src/backend/utils/adt/acl.c                   |   2 +-
 src/backend/utils/adt/datetime.c              |   4 +-
 src/backend/utils/adt/enum.c                  |  13 +-
 src/backend/utils/adt/expandedrecord.c        |   8 +-
 src/backend/utils/adt/genfile.c               |   4 +-
 src/backend/utils/adt/lockfuncs.c             |   2 +-
 src/backend/utils/adt/misc.c                  |   2 +-
 src/backend/utils/adt/orderedsetaggs.c        |   4 +-
 src/backend/utils/adt/partitionfuncs.c        |   2 +-
 src/backend/utils/adt/pgstatfuncs.c           |   2 +-
 src/backend/utils/adt/ruleutils.c             |   9 +-
 src/backend/utils/adt/selfuncs.c              |   1 -
 src/backend/utils/adt/trigfuncs.c             |  11 -
 src/backend/utils/adt/tsvector_op.c           |   4 +-
 src/backend/utils/cache/catcache.c            |  86 ++---
 src/backend/utils/cache/inval.c               |   4 +-
 src/backend/utils/cache/lsyscache.c           |   2 +-
 src/backend/utils/cache/plancache.c           |   4 +-
 src/backend/utils/cache/relcache.c            | 120 +++----
 src/backend/utils/cache/relfilenodemap.c      |  22 +-
 src/backend/utils/cache/syscache.c            |  64 ++--
 src/backend/utils/cache/typcache.c            |   2 +-
 src/backend/utils/fmgr/fmgr.c                 |   4 +-
 src/backend/utils/fmgr/funcapi.c              |   4 +-
 src/backend/utils/init/miscinit.c             |   2 +-
 src/backend/utils/init/postinit.c             |   8 +-
 src/backend/utils/misc/guc.c                  |  22 +-
 src/backend/utils/misc/pg_controldata.c       |   8 +-
 src/backend/utils/misc/postgresql.conf.sample |   1 -
 src/backend/utils/mmgr/portalmem.c            |   2 +-
 src/bin/initdb/initdb.c                       |   7 +-
 src/bin/pg_dump/pg_backup_archiver.c          |  66 +---
 src/bin/pg_dump/pg_backup_archiver.h          |   5 +-
 src/bin/pg_dump/pg_dump.c                     | 169 +++++----
 src/bin/pg_dump/t/002_pg_dump.pl              | 163 ---------
 src/bin/pgbench/t/001_pgbench_with_server.pl  |  18 +-
 src/bin/psql/describe.c                       |  19 +-
 src/bin/psql/tab-complete.c                   |   5 +-
 src/include/access/heapam.h                   |   4 +-
 src/include/access/htup_details.h             |  24 +-
 src/include/access/reloptions.h               |   2 +-
 src/include/access/sysattr.h                  |  14 +-
 src/include/access/tupdesc.h                  |   8 +-
 src/include/catalog/catalog.h                 |   1 -
 src/include/catalog/genbki.h                  |   1 -
 src/include/catalog/heap.h                    |   8 +-
 src/include/catalog/indexing.h                |   4 +-
 src/include/catalog/objectaddress.h           |   3 +-
 src/include/catalog/pg_aggregate.h            |   2 +-
 src/include/catalog/pg_am.h                   |   2 +
 src/include/catalog/pg_amop.h                 |   2 +
 src/include/catalog/pg_amproc.h               |   2 +
 src/include/catalog/pg_attrdef.h              |   2 +
 src/include/catalog/pg_attribute.h            |   2 +-
 src/include/catalog/pg_auth_members.h         |   2 +-
 src/include/catalog/pg_authid.h               |   1 +
 src/include/catalog/pg_cast.h                 |   2 +
 src/include/catalog/pg_class.dat              |  12 +-
 src/include/catalog/pg_class.h                |   2 +-
 src/include/catalog/pg_collation.h            |   1 +
 src/include/catalog/pg_constraint.h           |   2 +
 src/include/catalog/pg_conversion.h           |   1 +
 src/include/catalog/pg_database.h             |   1 +
 src/include/catalog/pg_db_role_setting.h      |   2 +-
 src/include/catalog/pg_default_acl.h          |   1 +
 src/include/catalog/pg_depend.h               |   2 +-
 src/include/catalog/pg_description.h          |   2 +-
 src/include/catalog/pg_enum.h                 |   1 +
 src/include/catalog/pg_event_trigger.h        |   1 +
 src/include/catalog/pg_extension.h            |   1 +
 src/include/catalog/pg_foreign_data_wrapper.h |   1 +
 src/include/catalog/pg_foreign_server.h       |   1 +
 src/include/catalog/pg_foreign_table.h        |   2 +-
 src/include/catalog/pg_index.h                |   2 +-
 src/include/catalog/pg_inherits.h             |   2 +-
 src/include/catalog/pg_init_privs.h           |   2 +-
 src/include/catalog/pg_language.h             |   2 +
 src/include/catalog/pg_largeobject.h          |   2 +-
 src/include/catalog/pg_largeobject_metadata.h |   2 +
 src/include/catalog/pg_namespace.h            |   2 +
 src/include/catalog/pg_opclass.h              |   2 +
 src/include/catalog/pg_operator.h             |   2 +
 src/include/catalog/pg_opfamily.h             |   2 +
 src/include/catalog/pg_partitioned_table.h    |   2 +-
 src/include/catalog/pg_pltemplate.h           |   2 +-
 src/include/catalog/pg_policy.h               |   1 +
 src/include/catalog/pg_proc.dat               |   5 +
 src/include/catalog/pg_proc.h                 |   2 +
 src/include/catalog/pg_publication.h          |   2 +
 src/include/catalog/pg_publication_rel.h      |   1 +
 src/include/catalog/pg_range.h                |   2 +-
 src/include/catalog/pg_replication_origin.h   |   2 +-
 src/include/catalog/pg_rewrite.h              |   1 +
 src/include/catalog/pg_seclabel.h             |   2 +-
 src/include/catalog/pg_sequence.h             |   2 +-
 src/include/catalog/pg_shdepend.h             |   2 +-
 src/include/catalog/pg_shdescription.h        |   2 +-
 src/include/catalog/pg_shseclabel.h           |   2 +-
 src/include/catalog/pg_statistic.h            |   2 +-
 src/include/catalog/pg_statistic_ext.h        |   2 +
 src/include/catalog/pg_subscription.h         |   2 +
 src/include/catalog/pg_subscription_rel.h     |   6 +-
 src/include/catalog/pg_tablespace.h           |   1 +
 src/include/catalog/pg_transform.h            |   1 +
 src/include/catalog/pg_trigger.h              |   1 +
 src/include/catalog/pg_ts_config.h            |   1 +
 src/include/catalog/pg_ts_config_map.h        |   2 +-
 src/include/catalog/pg_ts_dict.h              |   1 +
 src/include/catalog/pg_ts_parser.h            |   2 +
 src/include/catalog/pg_ts_template.h          |   2 +
 src/include/catalog/pg_type.h                 |   2 +
 src/include/catalog/pg_user_mapping.h         |   2 +
 src/include/commands/copy.h                   |   2 +-
 src/include/commands/event_trigger.h          |   1 -
 src/include/executor/executor.h               |  14 +-
 src/include/executor/spi.h                    |   1 -
 src/include/executor/spi_priv.h               |   2 -
 src/include/nodes/execnodes.h                 |   1 -
 src/include/nodes/parsenodes.h                |   3 -
 src/include/parser/parse_clause.h             |   1 -
 src/include/utils/guc.h                       |   1 -
 src/include/utils/rel.h                       |   2 +
 src/include/utils/relcache.h                  |   1 -
 src/interfaces/ecpg/preproc/ecpg.addons       |   2 +-
 src/pl/plperl/plperl.c                        |   2 +-
 src/pl/plpgsql/src/pl_comp.c                  |   4 +-
 src/pl/plpgsql/src/pl_exec.c                  |  10 -
 src/pl/plpgsql/src/pl_funcs.c                 |   2 -
 src/pl/plpgsql/src/pl_gram.y                  |   6 -
 src/pl/plpgsql/src/pl_scanner.c               |   1 -
 src/pl/plpgsql/src/plpgsql.h                  |   2 -
 src/pl/tcl/expected/pltcl_queries.out         |  15 -
 src/pl/tcl/expected/pltcl_setup.out           |   4 -
 src/pl/tcl/pltcl.c                            |  26 --
 src/pl/tcl/sql/pltcl_queries.sql              |   6 -
 src/pl/tcl/sql/pltcl_setup.sql                |   5 -
 .../expected/create_table.out                 |   2 +-
 .../test_ddl_deparse/sql/create_table.sql     |   2 +-
 .../test_ddl_deparse/test_ddl_deparse.c       |   9 -
 .../modules/test_predtest/test_predtest.c     |   2 +-
 src/test/regress/expected/alter_table.out     | 160 +--------
 src/test/regress/expected/copy2.out           |  16 +-
 src/test/regress/expected/create_index.out    |  16 +-
 src/test/regress/expected/create_table.out    |  32 +-
 .../regress/expected/create_table_like.out    |  34 --
 src/test/regress/expected/enum.out            |   4 +-
 src/test/regress/expected/errors.out          |   4 +-
 src/test/regress/expected/foreign_data.out    |  70 +---
 src/test/regress/expected/inherit.out         |  49 ---
 src/test/regress/expected/insert_conflict.out |  67 +---
 src/test/regress/expected/misc_sanity.out     |   2 +-
 src/test/regress/expected/opr_sanity.out      |  24 +-
 src/test/regress/expected/prepare.out         |  46 +--
 src/test/regress/expected/privileges.out      |  24 +-
 src/test/regress/expected/reloptions.out      |   9 -
 .../regress/expected/replica_identity.out     |   9 +-
 src/test/regress/expected/roleattributes.out  |  64 ++--
 src/test/regress/expected/rowsecurity.out     | 340 +++++++++---------
 src/test/regress/expected/rowtypes.out        |  10 +-
 src/test/regress/expected/sanity_check.out    |  12 +-
 src/test/regress/expected/triggers.out        |  26 +-
 src/test/regress/expected/without_oid.out     | 103 ------
 src/test/regress/parallel_schedule            |   2 +-
 src/test/regress/serial_schedule              |   1 -
 src/test/regress/sql/alter_table.sql          | 101 +-----
 src/test/regress/sql/copy2.sql                |  23 +-
 src/test/regress/sql/create_index.sql         |  15 +-
 src/test/regress/sql/create_table.sql         |  25 +-
 src/test/regress/sql/create_table_like.sql    |  16 -
 src/test/regress/sql/errors.sql               |   2 +-
 src/test/regress/sql/foreign_data.sql         |  11 -
 src/test/regress/sql/inherit.sql              |  26 --
 src/test/regress/sql/insert_conflict.sql      |  27 +-
 src/test/regress/sql/misc_sanity.sql          |   2 +-
 src/test/regress/sql/prepare.sql              |  10 +-
 src/test/regress/sql/privileges.sql           |  12 +-
 src/test/regress/sql/reloptions.sql           |   5 -
 src/test/regress/sql/replica_identity.sql     |   6 +-
 src/test/regress/sql/roleattributes.sql       |  65 ++--
 src/test/regress/sql/rowsecurity.sql          |  24 +-
 src/test/regress/sql/rowtypes.sql             |   6 +-
 src/test/regress/sql/sanity_check.sql         |  12 +-
 src/test/regress/sql/triggers.sql             |  25 +-
 src/test/regress/sql/without_oid.sql          |  92 -----
 src/tools/findoidjoins/findoidjoins.c         |   4 +-
 333 files changed, 1949 insertions(+), 4030 deletions(-)
 delete mode 100644 src/test/regress/expected/without_oid.out
 delete mode 100644 src/test/regress/sql/without_oid.sql

diff --git a/contrib/adminpack/adminpack.c b/contrib/adminpack/adminpack.c
index 0a27701e9c6..ea0ec201f0d 100644
--- a/contrib/adminpack/adminpack.c
+++ b/contrib/adminpack/adminpack.c
@@ -502,7 +502,7 @@ pg_logdir_ls_internal(FunctionCallInfo fcinfo)
 
 		fctx = palloc(sizeof(directory_fctx));
 
-		tupdesc = CreateTemplateTupleDesc(2, false);
+		tupdesc = CreateTemplateTupleDesc(2);
 		TupleDescInitEntry(tupdesc, (AttrNumber) 1, "starttime",
 						   TIMESTAMPOID, -1, 0);
 		TupleDescInitEntry(tupdesc, (AttrNumber) 2, "filename",
diff --git a/contrib/btree_gist/expected/cash.out b/contrib/btree_gist/expected/cash.out
index cacbd718541..7fbc7355929 100644
--- a/contrib/btree_gist/expected/cash.out
+++ b/contrib/btree_gist/expected/cash.out
@@ -1,5 +1,5 @@
 -- money check
-CREATE TABLE moneytmp (a money) WITH OIDS;
+CREATE TABLE moneytmp (a money);
 \copy moneytmp from 'data/cash.data'
 SET enable_seqscan=on;
 SELECT count(*) FROM moneytmp WHERE a <  '22649.64';
diff --git a/contrib/btree_gist/expected/oid.out b/contrib/btree_gist/expected/oid.out
index ffa90c3c3c7..776bbb10267 100644
--- a/contrib/btree_gist/expected/oid.out
+++ b/contrib/btree_gist/expected/oid.out
@@ -1,64 +1,66 @@
 -- oid check
 SET enable_seqscan=on;
-SELECT count(*) FROM moneytmp WHERE oid <  ( SELECT oid FROM moneytmp WHERE a  = '22649.64' );
+CREATE TEMPORARY TABLE oidtmp (oid oid);
+INSERT INTO oidtmp SELECT g.i::oid FROM generate_series(1, 1000) g(i);
+SELECT count(*) FROM oidtmp WHERE oid <  17;
  count 
 -------
-   372
+    16
 (1 row)
 
-SELECT count(*) FROM moneytmp WHERE oid <= ( SELECT oid FROM moneytmp WHERE a  = '22649.64' );
+SELECT count(*) FROM oidtmp WHERE oid <= 17;
  count 
 -------
-   373
+    17
 (1 row)
 
-SELECT count(*) FROM moneytmp WHERE oid  = ( SELECT oid FROM moneytmp WHERE a  = '22649.64' );
+SELECT count(*) FROM oidtmp WHERE oid  = 17;
  count 
 -------
      1
 (1 row)
 
-SELECT count(*) FROM moneytmp WHERE oid >= ( SELECT oid FROM moneytmp WHERE a  = '22649.64' );
+SELECT count(*) FROM oidtmp WHERE oid >= 17;
  count 
 -------
-   228
+   984
 (1 row)
 
-SELECT count(*) FROM moneytmp WHERE oid >  ( SELECT oid FROM moneytmp WHERE a  = '22649.64' );
+SELECT count(*) FROM oidtmp WHERE oid >  17;
  count 
 -------
-   227
+   983
 (1 row)
 
-CREATE INDEX oididx ON moneytmp USING gist ( oid );
+CREATE INDEX oididx ON oidtmp USING gist ( oid );
 SET enable_seqscan=off;
-SELECT count(*) FROM moneytmp WHERE oid <  ( SELECT oid FROM moneytmp WHERE a  = '22649.64' );
+SELECT count(*) FROM oidtmp WHERE oid <  17;
  count 
 -------
-   372
+    16
 (1 row)
 
-SELECT count(*) FROM moneytmp WHERE oid <= ( SELECT oid FROM moneytmp WHERE a  = '22649.64' );
+SELECT count(*) FROM oidtmp WHERE oid <= 17;
  count 
 -------
-   373
+    17
 (1 row)
 
-SELECT count(*) FROM moneytmp WHERE oid  = ( SELECT oid FROM moneytmp WHERE a  = '22649.64' );
+SELECT count(*) FROM oidtmp WHERE oid  = 17;
  count 
 -------
      1
 (1 row)
 
-SELECT count(*) FROM moneytmp WHERE oid >= ( SELECT oid FROM moneytmp WHERE a  = '22649.64' );
+SELECT count(*) FROM oidtmp WHERE oid >= 17;
  count 
 -------
-   228
+   984
 (1 row)
 
-SELECT count(*) FROM moneytmp WHERE oid >  ( SELECT oid FROM moneytmp WHERE a  = '22649.64' );
+SELECT count(*) FROM oidtmp WHERE oid >  17;
  count 
 -------
-   227
+   983
 (1 row)
 
diff --git a/contrib/btree_gist/sql/cash.sql b/contrib/btree_gist/sql/cash.sql
index 0e037984e1b..4526cc4f0aa 100644
--- a/contrib/btree_gist/sql/cash.sql
+++ b/contrib/btree_gist/sql/cash.sql
@@ -1,6 +1,6 @@
 -- money check
 
-CREATE TABLE moneytmp (a money) WITH OIDS;
+CREATE TABLE moneytmp (a money);
 
 \copy moneytmp from 'data/cash.data'
 
diff --git a/contrib/btree_gist/sql/oid.sql b/contrib/btree_gist/sql/oid.sql
index fd03b82bd44..c9358234ce9 100644
--- a/contrib/btree_gist/sql/oid.sql
+++ b/contrib/btree_gist/sql/oid.sql
@@ -2,26 +2,29 @@
 
 SET enable_seqscan=on;
 
-SELECT count(*) FROM moneytmp WHERE oid <  ( SELECT oid FROM moneytmp WHERE a  = '22649.64' );
+CREATE TEMPORARY TABLE oidtmp (oid oid);
+INSERT INTO oidtmp SELECT g.i::oid FROM generate_series(1, 1000) g(i);
 
-SELECT count(*) FROM moneytmp WHERE oid <= ( SELECT oid FROM moneytmp WHERE a  = '22649.64' );
+SELECT count(*) FROM oidtmp WHERE oid <  17;
 
-SELECT count(*) FROM moneytmp WHERE oid  = ( SELECT oid FROM moneytmp WHERE a  = '22649.64' );
+SELECT count(*) FROM oidtmp WHERE oid <= 17;
 
-SELECT count(*) FROM moneytmp WHERE oid >= ( SELECT oid FROM moneytmp WHERE a  = '22649.64' );
+SELECT count(*) FROM oidtmp WHERE oid  = 17;
 
-SELECT count(*) FROM moneytmp WHERE oid >  ( SELECT oid FROM moneytmp WHERE a  = '22649.64' );
+SELECT count(*) FROM oidtmp WHERE oid >= 17;
 
-CREATE INDEX oididx ON moneytmp USING gist ( oid );
+SELECT count(*) FROM oidtmp WHERE oid >  17;
+
+CREATE INDEX oididx ON oidtmp USING gist ( oid );
 
 SET enable_seqscan=off;
 
-SELECT count(*) FROM moneytmp WHERE oid <  ( SELECT oid FROM moneytmp WHERE a  = '22649.64' );
+SELECT count(*) FROM oidtmp WHERE oid <  17;
 
-SELECT count(*) FROM moneytmp WHERE oid <= ( SELECT oid FROM moneytmp WHERE a  = '22649.64' );
+SELECT count(*) FROM oidtmp WHERE oid <= 17;
 
-SELECT count(*) FROM moneytmp WHERE oid  = ( SELECT oid FROM moneytmp WHERE a  = '22649.64' );
+SELECT count(*) FROM oidtmp WHERE oid  = 17;
 
-SELECT count(*) FROM moneytmp WHERE oid >= ( SELECT oid FROM moneytmp WHERE a  = '22649.64' );
+SELECT count(*) FROM oidtmp WHERE oid >= 17;
 
-SELECT count(*) FROM moneytmp WHERE oid >  ( SELECT oid FROM moneytmp WHERE a  = '22649.64' );
+SELECT count(*) FROM oidtmp WHERE oid >  17;
diff --git a/contrib/dblink/dblink.c b/contrib/dblink/dblink.c
index c6460688486..3b73ff13f19 100644
--- a/contrib/dblink/dblink.c
+++ b/contrib/dblink/dblink.c
@@ -849,7 +849,7 @@ materializeResult(FunctionCallInfo fcinfo, PGconn *conn, PGresult *res)
 			 * need a tuple descriptor representing one TEXT column to return
 			 * the command status string as our result tuple
 			 */
-			tupdesc = CreateTemplateTupleDesc(1, false);
+			tupdesc = CreateTemplateTupleDesc(1);
 			TupleDescInitEntry(tupdesc, (AttrNumber) 1, "status",
 							   TEXTOID, -1, 0);
 			ntuples = 1;
@@ -1032,7 +1032,7 @@ materializeQueryResult(FunctionCallInfo fcinfo,
 			 * need a tuple descriptor representing one TEXT column to return
 			 * the command status string as our result tuple
 			 */
-			tupdesc = CreateTemplateTupleDesc(1, false);
+			tupdesc = CreateTemplateTupleDesc(1);
 			TupleDescInitEntry(tupdesc, (AttrNumber) 1, "status",
 							   TEXTOID, -1, 0);
 			attinmeta = TupleDescGetAttInMetadata(tupdesc);
@@ -1526,7 +1526,7 @@ dblink_get_pkey(PG_FUNCTION_ARGS)
 		/*
 		 * need a tuple descriptor representing one INT and one TEXT column
 		 */
-		tupdesc = CreateTemplateTupleDesc(2, false);
+		tupdesc = CreateTemplateTupleDesc(2);
 		TupleDescInitEntry(tupdesc, (AttrNumber) 1, "position",
 						   INT4OID, -1, 0);
 		TupleDescInitEntry(tupdesc, (AttrNumber) 2, "colname",
@@ -1904,7 +1904,7 @@ dblink_get_notify(PG_FUNCTION_ARGS)
 	per_query_ctx = rsinfo->econtext->ecxt_per_query_memory;
 	oldcontext = MemoryContextSwitchTo(per_query_ctx);
 
-	tupdesc = CreateTemplateTupleDesc(DBLINK_NOTIFY_COLS, false);
+	tupdesc = CreateTemplateTupleDesc(DBLINK_NOTIFY_COLS);
 	TupleDescInitEntry(tupdesc, (AttrNumber) 1, "notify_name",
 					   TEXTOID, -1, 0);
 	TupleDescInitEntry(tupdesc, (AttrNumber) 2, "be_pid",
diff --git a/contrib/file_fdw/file_fdw.c b/contrib/file_fdw/file_fdw.c
index 2cf09aecf6e..4368d920413 100644
--- a/contrib/file_fdw/file_fdw.c
+++ b/contrib/file_fdw/file_fdw.c
@@ -727,8 +727,7 @@ fileIterateForeignScan(ForeignScanState *node)
 	 */
 	ExecClearTuple(slot);
 	found = NextCopyFrom(festate->cstate, NULL,
-						 slot->tts_values, slot->tts_isnull,
-						 NULL);
+						 slot->tts_values, slot->tts_isnull);
 	if (found)
 		ExecStoreVirtualTuple(slot);
 
@@ -1148,7 +1147,7 @@ file_acquire_sample_rows(Relation onerel, int elevel,
 		MemoryContextReset(tupcontext);
 		MemoryContextSwitchTo(tupcontext);
 
-		found = NextCopyFrom(cstate, NULL, values, nulls, NULL);
+		found = NextCopyFrom(cstate, NULL, values, nulls);
 
 		MemoryContextSwitchTo(oldcontext);
 
diff --git a/contrib/pageinspect/heapfuncs.c b/contrib/pageinspect/heapfuncs.c
index d96ba1e8b61..a5be57230a0 100644
--- a/contrib/pageinspect/heapfuncs.c
+++ b/contrib/pageinspect/heapfuncs.c
@@ -241,14 +241,13 @@ heap_page_items(PG_FUNCTION_ARGS)
 				else
 					nulls[11] = true;
 
-				if (tuphdr->t_infomask & HEAP_HASOID)
-					values[12] = HeapTupleHeaderGetOid(tuphdr);
-				else
-					nulls[12] = true;
+				// XXX: remove
+				nulls[12] = true;
 			}
 			else
 			{
 				nulls[11] = true;
+				// XXX: remove
 				nulls[12] = true;
 			}
 		}
diff --git a/contrib/pg_buffercache/pg_buffercache_pages.c b/contrib/pg_buffercache/pg_buffercache_pages.c
index b410aafa5a9..1bd579fcbb0 100644
--- a/contrib/pg_buffercache/pg_buffercache_pages.c
+++ b/contrib/pg_buffercache/pg_buffercache_pages.c
@@ -99,7 +99,7 @@ pg_buffercache_pages(PG_FUNCTION_ARGS)
 			elog(ERROR, "incorrect number of output arguments");
 
 		/* Construct a tuple descriptor for the result rows. */
-		tupledesc = CreateTemplateTupleDesc(expected_tupledesc->natts, false);
+		tupledesc = CreateTemplateTupleDesc(expected_tupledesc->natts);
 		TupleDescInitEntry(tupledesc, (AttrNumber) 1, "bufferid",
 						   INT4OID, -1, 0);
 		TupleDescInitEntry(tupledesc, (AttrNumber) 2, "relfilenode",
diff --git a/contrib/pg_visibility/pg_visibility.c b/contrib/pg_visibility/pg_visibility.c
index 944dea66fc8..c1aae9d6551 100644
--- a/contrib/pg_visibility/pg_visibility.c
+++ b/contrib/pg_visibility/pg_visibility.c
@@ -292,7 +292,7 @@ pg_visibility_map_summary(PG_FUNCTION_ARGS)
 		ReleaseBuffer(vmbuffer);
 	relation_close(rel, AccessShareLock);
 
-	tupdesc = CreateTemplateTupleDesc(2, false);
+	tupdesc = CreateTemplateTupleDesc(2);
 	TupleDescInitEntry(tupdesc, (AttrNumber) 1, "all_visible", INT8OID, -1, 0);
 	TupleDescInitEntry(tupdesc, (AttrNumber) 2, "all_frozen", INT8OID, -1, 0);
 	tupdesc = BlessTupleDesc(tupdesc);
@@ -447,7 +447,7 @@ pg_visibility_tupdesc(bool include_blkno, bool include_pd)
 		++maxattr;
 	if (include_pd)
 		++maxattr;
-	tupdesc = CreateTemplateTupleDesc(maxattr, false);
+	tupdesc = CreateTemplateTupleDesc(maxattr);
 	if (include_blkno)
 		TupleDescInitEntry(tupdesc, ++a, "blkno", INT8OID, -1, 0);
 	TupleDescInitEntry(tupdesc, ++a, "all_visible", BOOLOID, -1, 0);
diff --git a/contrib/postgres_fdw/deparse.c b/contrib/postgres_fdw/deparse.c
index 6001f4d25ef..654323f1554 100644
--- a/contrib/postgres_fdw/deparse.c
+++ b/contrib/postgres_fdw/deparse.c
@@ -332,14 +332,13 @@ foreign_expr_walker(Node *node,
 					/* Var belongs to foreign table */
 
 					/*
-					 * System columns other than ctid and oid should not be
-					 * sent to the remote, since we don't make any effort to
-					 * ensure that local and remote values match (tableoid, in
+					 * System columns other than ctid should not be sent to
+					 * the remote, since we don't make any effort to ensure
+					 * that local and remote values match (tableoid, in
 					 * particular, almost certainly doesn't match).
 					 */
 					if (var->varattno < 0 &&
-						var->varattno != SelfItemPointerAttributeNumber &&
-						var->varattno != ObjectIdAttributeNumber)
+						var->varattno != SelfItemPointerAttributeNumber)
 						return false;
 
 					/* Else check the collation */
@@ -1145,8 +1144,8 @@ deparseTargetList(StringInfo buf,
 	}
 
 	/*
-	 * Add ctid and oid if needed.  We currently don't support retrieving any
-	 * other system columns.
+	 * Add ctid if needed.  We currently don't support retrieving any other
+	 * system columns.
 	 */
 	if (bms_is_member(SelfItemPointerAttributeNumber - FirstLowInvalidHeapAttributeNumber,
 					  attrs_used))
@@ -1164,22 +1163,6 @@ deparseTargetList(StringInfo buf,
 		*retrieved_attrs = lappend_int(*retrieved_attrs,
 									   SelfItemPointerAttributeNumber);
 	}
-	if (bms_is_member(ObjectIdAttributeNumber - FirstLowInvalidHeapAttributeNumber,
-					  attrs_used))
-	{
-		if (!first)
-			appendStringInfoString(buf, ", ");
-		else if (is_returning)
-			appendStringInfoString(buf, " RETURNING ");
-		first = false;
-
-		if (qualify_col)
-			ADD_REL_QUALIFIER(buf, rtindex);
-		appendStringInfoString(buf, "oid");
-
-		*retrieved_attrs = lappend_int(*retrieved_attrs,
-									   ObjectIdAttributeNumber);
-	}
 
 	/* Don't generate bad syntax if no undropped columns */
 	if (first && !is_returning)
@@ -2079,12 +2062,6 @@ deparseColumnRef(StringInfo buf, int varno, int varattno, RangeTblEntry *rte,
 			ADD_REL_QUALIFIER(buf, varno);
 		appendStringInfoString(buf, "ctid");
 	}
-	else if (varattno == ObjectIdAttributeNumber)
-	{
-		if (qualify_col)
-			ADD_REL_QUALIFIER(buf, varno);
-		appendStringInfoString(buf, "oid");
-	}
 	else if (varattno < 0)
 	{
 		/*
diff --git a/contrib/postgres_fdw/expected/postgres_fdw.out b/contrib/postgres_fdw/expected/postgres_fdw.out
index 21a2ef5ad3a..e653c302bec 100644
--- a/contrib/postgres_fdw/expected/postgres_fdw.out
+++ b/contrib/postgres_fdw/expected/postgres_fdw.out
@@ -129,13 +129,6 @@ CREATE FOREIGN TABLE ft6 (
 	c2 int NOT NULL,
 	c3 text
 ) SERVER loopback2 OPTIONS (schema_name 'S 1', table_name 'T 4');
--- A table with oids. CREATE FOREIGN TABLE doesn't support the
--- WITH OIDS option, but ALTER does.
-CREATE FOREIGN TABLE ft_pg_type (
-	typname name,
-	typlen smallint
-) SERVER loopback OPTIONS (schema_name 'pg_catalog', table_name 'pg_type');
-ALTER TABLE ft_pg_type SET WITH OIDS;
 -- ===================================================================
 -- tests for validator
 -- ===================================================================
@@ -185,16 +178,15 @@ ALTER FOREIGN TABLE ft2 OPTIONS (schema_name 'S 1', table_name 'T 1');
 ALTER FOREIGN TABLE ft1 ALTER COLUMN c1 OPTIONS (column_name 'C 1');
 ALTER FOREIGN TABLE ft2 ALTER COLUMN c1 OPTIONS (column_name 'C 1');
 \det+
-                                      List of foreign tables
- Schema |   Table    |  Server   |                   FDW options                    | Description 
---------+------------+-----------+--------------------------------------------------+-------------
- public | ft1        | loopback  | (schema_name 'S 1', table_name 'T 1')            | 
- public | ft2        | loopback  | (schema_name 'S 1', table_name 'T 1')            | 
- public | ft4        | loopback  | (schema_name 'S 1', table_name 'T 3')            | 
- public | ft5        | loopback  | (schema_name 'S 1', table_name 'T 4')            | 
- public | ft6        | loopback2 | (schema_name 'S 1', table_name 'T 4')            | 
- public | ft_pg_type | loopback  | (schema_name 'pg_catalog', table_name 'pg_type') | 
-(6 rows)
+                              List of foreign tables
+ Schema | Table |  Server   |              FDW options              | Description 
+--------+-------+-----------+---------------------------------------+-------------
+ public | ft1   | loopback  | (schema_name 'S 1', table_name 'T 1') | 
+ public | ft2   | loopback  | (schema_name 'S 1', table_name 'T 1') | 
+ public | ft4   | loopback  | (schema_name 'S 1', table_name 'T 3') | 
+ public | ft5   | loopback  | (schema_name 'S 1', table_name 'T 4') | 
+ public | ft6   | loopback2 | (schema_name 'S 1', table_name 'T 4') | 
+(5 rows)
 
 -- Test that alteration of server options causes reconnection
 -- Remote's errors might be non-English, so hide them to ensure stable results
@@ -4048,21 +4040,6 @@ SELECT ctid, * FROM ft1 t1 LIMIT 1;
  (0,1) |  1 |  1 | 00001 | Fri Jan 02 00:00:00 1970 PST | Fri Jan 02 00:00:00 1970 | 1  | 1          | foo
 (1 row)
 
-EXPLAIN (VERBOSE, COSTS OFF)
-SELECT oid, * FROM ft_pg_type WHERE typname = 'int4';
-                                             QUERY PLAN                                             
-----------------------------------------------------------------------------------------------------
- Foreign Scan on public.ft_pg_type
-   Output: oid, typname, typlen
-   Remote SQL: SELECT typname, typlen, oid FROM pg_catalog.pg_type WHERE ((typname = 'int4'::name))
-(3 rows)
-
-SELECT oid, * FROM ft_pg_type WHERE typname = 'int4';
- oid | typname | typlen 
------+---------+--------
-  23 | int4    |      4
-(1 row)
-
 -- ===================================================================
 -- used in PL/pgSQL function
 -- ===================================================================
diff --git a/contrib/postgres_fdw/postgres_fdw.c b/contrib/postgres_fdw/postgres_fdw.c
index fd20aa96aa9..83433a077a8 100644
--- a/contrib/postgres_fdw/postgres_fdw.c
+++ b/contrib/postgres_fdw/postgres_fdw.c
@@ -3632,8 +3632,7 @@ build_remote_returning(Index rtindex, Relation rel, List *returningList)
 		if (IsA(var, Var) &&
 			var->varno == rtindex &&
 			var->varattno <= InvalidAttrNumber &&
-			var->varattno != SelfItemPointerAttributeNumber &&
-			var->varattno != ObjectIdAttributeNumber)
+			var->varattno != SelfItemPointerAttributeNumber)
 			continue;			/* don't need it */
 
 		if (tlist_member((Expr *) var, tlist))
@@ -3864,8 +3863,6 @@ init_returning_filter(PgFdwDirectModifyState *dmstate,
 				 */
 				if (attrno == SelfItemPointerAttributeNumber)
 					dmstate->ctidAttno = i;
-				else if (attrno == ObjectIdAttributeNumber)
-					dmstate->oidAttno = i;
 				else
 					Assert(false);
 				dmstate->hasSystemCols = true;
@@ -3962,15 +3959,6 @@ apply_returning_filter(PgFdwDirectModifyState *dmstate,
 			resultTup->t_self = *ctid;
 		}
 
-		/* oid */
-		if (dmstate->oidAttno)
-		{
-			Oid			oid = InvalidOid;
-
-			oid = DatumGetObjectId(old_values[dmstate->oidAttno - 1]);
-			HeapTupleSetOid(resultTup, oid);
-		}
-
 		/*
 		 * And remaining columns
 		 *
@@ -5555,7 +5543,6 @@ make_tuple_from_result_row(PGresult *res,
 	Datum	   *values;
 	bool	   *nulls;
 	ItemPointer ctid = NULL;
-	Oid			oid = InvalidOid;
 	ConversionLocation errpos;
 	ErrorContextCallback errcallback;
 	MemoryContext oldcontext;
@@ -5638,17 +5625,6 @@ make_tuple_from_result_row(PGresult *res,
 				ctid = (ItemPointer) DatumGetPointer(datum);
 			}
 		}
-		else if (i == ObjectIdAttributeNumber)
-		{
-			/* oid */
-			if (valstr != NULL)
-			{
-				Datum		datum;
-
-				datum = DirectFunctionCall1(oidin, CStringGetDatum(valstr));
-				oid = DatumGetObjectId(datum);
-			}
-		}
 		errpos.cur_attno = 0;
 
 		j++;
@@ -5692,12 +5668,6 @@ make_tuple_from_result_row(PGresult *res,
 	HeapTupleHeaderSetXmin(tuple->t_data, InvalidTransactionId);
 	HeapTupleHeaderSetCmin(tuple->t_data, InvalidTransactionId);
 
-	/*
-	 * If we have an OID to return, install it.
-	 */
-	if (OidIsValid(oid))
-		HeapTupleSetOid(tuple, oid);
-
 	/* Clean up */
 	MemoryContextReset(temp_context);
 
@@ -5726,8 +5696,6 @@ conversion_error_callback(void *arg)
 			attname = NameStr(attr->attname);
 		else if (errpos->cur_attno == SelfItemPointerAttributeNumber)
 			attname = "ctid";
-		else if (errpos->cur_attno == ObjectIdAttributeNumber)
-			attname = "oid";
 
 		relname = RelationGetRelationName(errpos->rel);
 	}
diff --git a/contrib/postgres_fdw/sql/postgres_fdw.sql b/contrib/postgres_fdw/sql/postgres_fdw.sql
index 88c4cb4783f..6aa9a7f4d9b 100644
--- a/contrib/postgres_fdw/sql/postgres_fdw.sql
+++ b/contrib/postgres_fdw/sql/postgres_fdw.sql
@@ -142,14 +142,6 @@ CREATE FOREIGN TABLE ft6 (
 	c3 text
 ) SERVER loopback2 OPTIONS (schema_name 'S 1', table_name 'T 4');
 
--- A table with oids. CREATE FOREIGN TABLE doesn't support the
--- WITH OIDS option, but ALTER does.
-CREATE FOREIGN TABLE ft_pg_type (
-	typname name,
-	typlen smallint
-) SERVER loopback OPTIONS (schema_name 'pg_catalog', table_name 'pg_type');
-ALTER TABLE ft_pg_type SET WITH OIDS;
-
 -- ===================================================================
 -- tests for validator
 -- ===================================================================
@@ -1002,9 +994,6 @@ SELECT * FROM ft1 t1 WHERE t1.ctid = '(0,2)';
 EXPLAIN (VERBOSE, COSTS OFF)
 SELECT ctid, * FROM ft1 t1 LIMIT 1;
 SELECT ctid, * FROM ft1 t1 LIMIT 1;
-EXPLAIN (VERBOSE, COSTS OFF)
-SELECT oid, * FROM ft_pg_type WHERE typname = 'int4';
-SELECT oid, * FROM ft_pg_type WHERE typname = 'int4';
 
 -- ===================================================================
 -- used in PL/pgSQL function
diff --git a/contrib/sepgsql/expected/alter.out b/contrib/sepgsql/expected/alter.out
index e1d31e5b2fa..b27274d83ec 100644
--- a/contrib/sepgsql/expected/alter.out
+++ b/contrib/sepgsql/expected/alter.out
@@ -212,16 +212,6 @@ ALTER TABLE regtest_table ENABLE  TRIGGER regtest_test_trig;    -- not supported
 CREATE RULE regtest_test_rule AS ON INSERT TO regtest_table_3 DO ALSO NOTHING;
 ALTER TABLE regtest_table_3 DISABLE RULE regtest_test_rule;     -- not supported
 ALTER TABLE regtest_table_3 ENABLE RULE regtest_test_rule;      -- not supported
-ALTER TABLE regtest_table SET WITH OIDS;
-LOG:  SELinux: allowed { create } scontext=unconfined_u:unconfined_r:sepgsql_regtest_superuser_t:s0 tcontext=unconfined_u:object_r:sepgsql_table_t:s0 tclass=db_column name="regtest_schema_2.regtest_table.oid"
-LOG:  SELinux: allowed { create } scontext=unconfined_u:unconfined_r:sepgsql_regtest_superuser_t:s0 tcontext=unconfined_u:object_r:sepgsql_table_t:s0 tclass=db_column name="regtest_schema.regtest_table_2.oid"
-ALTER TABLE regtest_table SET WITHOUT OIDS;
-LOG:  SELinux: allowed { drop } scontext=unconfined_u:unconfined_r:sepgsql_regtest_superuser_t:s0 tcontext=unconfined_u:object_r:sepgsql_table_t:s0 tclass=db_column name="regtest_schema.regtest_table_2.oid"
-LOG:  SELinux: allowed { drop } scontext=unconfined_u:unconfined_r:sepgsql_regtest_superuser_t:s0 tcontext=unconfined_u:object_r:sepgsql_table_t:s0 tclass=db_column name="regtest_schema_2.regtest_table.oid"
-ALTER TABLE regtest_table SET (fillfactor = 75);
-LOG:  SELinux: allowed { setattr } scontext=unconfined_u:unconfined_r:sepgsql_regtest_superuser_t:s0 tcontext=unconfined_u:object_r:sepgsql_table_t:s0 tclass=db_table name="regtest_schema_2.regtest_table"
-ALTER TABLE regtest_table RESET (fillfactor);
-LOG:  SELinux: allowed { setattr } scontext=unconfined_u:unconfined_r:sepgsql_regtest_superuser_t:s0 tcontext=unconfined_u:object_r:sepgsql_table_t:s0 tclass=db_table name="regtest_schema_2.regtest_table"
 ALTER TABLE regtest_table_2 NO INHERIT regtest_table;   -- not supported
 ALTER TABLE regtest_table_2 INHERIT regtest_table;      -- not supported
 ALTER TABLE regtest_table SET TABLESPACE pg_default;
@@ -265,14 +255,6 @@ LOG:  SELinux: allowed { setattr } scontext=unconfined_u:unconfined_r:sepgsql_re
 LOG:  SELinux: allowed { setattr } scontext=unconfined_u:unconfined_r:sepgsql_regtest_superuser_t:s0 tcontext=unconfined_u:object_r:sepgsql_table_t:s0 tclass=db_column name="regtest_schema.regtest_ptable_1_tens.p"
 ALTER TABLE regtest_ptable ADD CONSTRAINT test_ck CHECK (p like '%abc%') NOT VALID;      -- not supported by sepgsql
 ALTER TABLE regtest_ptable DROP CONSTRAINT test_ck;      -- not supported by sepgsql
-ALTER TABLE regtest_ptable SET WITH OIDS;
-LOG:  SELinux: allowed { create } scontext=unconfined_u:unconfined_r:sepgsql_regtest_superuser_t:s0 tcontext=unconfined_u:object_r:sepgsql_table_t:s0 tclass=db_column name="regtest_schema_2.regtest_ptable.oid"
-LOG:  SELinux: allowed { create } scontext=unconfined_u:unconfined_r:sepgsql_regtest_superuser_t:s0 tcontext=unconfined_u:object_r:sepgsql_table_t:s0 tclass=db_column name="regtest_schema_2.regtest_table_part.oid"
-LOG:  SELinux: allowed { create } scontext=unconfined_u:unconfined_r:sepgsql_regtest_superuser_t:s0 tcontext=unconfined_u:object_r:sepgsql_table_t:s0 tclass=db_column name="regtest_schema.regtest_ptable_1_tens.oid"
-ALTER TABLE regtest_ptable SET WITHOUT OIDS;
-LOG:  SELinux: allowed { drop } scontext=unconfined_u:unconfined_r:sepgsql_regtest_superuser_t:s0 tcontext=unconfined_u:object_r:sepgsql_table_t:s0 tclass=db_column name="regtest_schema_2.regtest_table_part.oid"
-LOG:  SELinux: allowed { drop } scontext=unconfined_u:unconfined_r:sepgsql_regtest_superuser_t:s0 tcontext=unconfined_u:object_r:sepgsql_table_t:s0 tclass=db_column name="regtest_schema.regtest_ptable_1_tens.oid"
-LOG:  SELinux: allowed { drop } scontext=unconfined_u:unconfined_r:sepgsql_regtest_superuser_t:s0 tcontext=unconfined_u:object_r:sepgsql_table_t:s0 tclass=db_column name="regtest_schema_2.regtest_ptable.oid"
 ALTER TABLE regtest_ptable SET TABLESPACE pg_default;
 -- partitioned table child
 ALTER TABLE regtest_table_part ALTER p SET DEFAULT 'abcd';   -- not supported by sepgsql
diff --git a/contrib/sepgsql/expected/ddl.out b/contrib/sepgsql/expected/ddl.out
index 1c0409a7a65..9c5c6061390 100644
--- a/contrib/sepgsql/expected/ddl.out
+++ b/contrib/sepgsql/expected/ddl.out
@@ -61,9 +61,9 @@ LINE 1: ALTER TABLE regtest_table ADD COLUMN z int;
                                                ^
 LOG:  SELinux: allowed { search } scontext=unconfined_u:unconfined_r:sepgsql_regtest_superuser_t:s0 tcontext=system_u:object_r:sepgsql_schema_t:s0 tclass=db_schema name="pg_catalog"
 LOG:  SELinux: allowed { create } scontext=unconfined_u:unconfined_r:sepgsql_regtest_superuser_t:s0 tcontext=unconfined_u:object_r:sepgsql_table_t:s0 tclass=db_column name="regtest_schema.regtest_table.z"
-CREATE TABLE regtest_table_2 (a int) WITH OIDS;
+CREATE TABLE regtest_table_2 (a int);
 LOG:  SELinux: allowed { search } scontext=unconfined_u:unconfined_r:sepgsql_regtest_superuser_t:s0 tcontext=system_u:object_r:sepgsql_schema_t:s0 tclass=db_schema name="pg_catalog"
-LINE 1: CREATE TABLE regtest_table_2 (a int) WITH OIDS;
+LINE 1: CREATE TABLE regtest_table_2 (a int);
                                         ^
 LOG:  SELinux: allowed { search } scontext=unconfined_u:unconfined_r:sepgsql_regtest_superuser_t:s0 tcontext=system_u:object_r:sepgsql_schema_t:s0 tclass=db_schema name="pg_catalog"
 LOG:  SELinux: allowed { add_name } scontext=unconfined_u:unconfined_r:sepgsql_regtest_superuser_t:s0 tcontext=unconfined_u:object_r:sepgsql_schema_t:s0 tclass=db_schema name="regtest_schema"
@@ -413,8 +413,6 @@ LOG:  SELinux: allowed { remove_name } scontext=unconfined_u:unconfined_r:sepgsq
 LOG:  SELinux: allowed { drop } scontext=unconfined_u:unconfined_r:sepgsql_regtest_superuser_t:s0 tcontext=unconfined_u:object_r:sepgsql_view_t:s0 tclass=db_view name="regtest_schema.regtest_view"
 ALTER TABLE regtest_table DROP COLUMN y;
 LOG:  SELinux: allowed { drop } scontext=unconfined_u:unconfined_r:sepgsql_regtest_superuser_t:s0 tcontext=unconfined_u:object_r:sepgsql_table_t:s0 tclass=db_column name="regtest_schema.regtest_table.y"
-ALTER TABLE regtest_table_2 SET WITHOUT OIDS;
-LOG:  SELinux: allowed { drop } scontext=unconfined_u:unconfined_r:sepgsql_regtest_superuser_t:s0 tcontext=unconfined_u:object_r:sepgsql_table_t:s0 tclass=db_column name="regtest_schema.regtest_table_2.oid"
 ALTER TABLE regtest_ptable DROP COLUMN q CASCADE;
 LOG:  SELinux: allowed { drop } scontext=unconfined_u:unconfined_r:sepgsql_regtest_superuser_t:s0 tcontext=unconfined_u:object_r:sepgsql_table_t:s0 tclass=db_column name="regtest_schema.regtest_ptable_ones.q"
 LOG:  SELinux: allowed { drop } scontext=unconfined_u:unconfined_r:sepgsql_regtest_superuser_t:s0 tcontext=unconfined_u:object_r:sepgsql_table_t:s0 tclass=db_column name="regtest_schema.regtest_ptable_tens.q"
diff --git a/contrib/sepgsql/label.c b/contrib/sepgsql/label.c
index dba0986e02a..acffc468d28 100644
--- a/contrib/sepgsql/label.c
+++ b/contrib/sepgsql/label.c
@@ -758,7 +758,7 @@ exec_object_restorecon(struct selabel_handle *sehnd, Oid catalogId)
 											NULL, NULL, NULL);
 
 				object.classId = DatabaseRelationId;
-				object.objectId = HeapTupleGetOid(tuple);
+				object.objectId = datForm->oid;
 				object.objectSubId = 0;
 				break;
 
@@ -772,7 +772,7 @@ exec_object_restorecon(struct selabel_handle *sehnd, Oid catalogId)
 											NULL, NULL);
 
 				object.classId = NamespaceRelationId;
-				object.objectId = HeapTupleGetOid(tuple);
+				object.objectId = nspForm->oid;
 				object.objectSubId = 0;
 				break;
 
@@ -797,7 +797,7 @@ exec_object_restorecon(struct selabel_handle *sehnd, Oid catalogId)
 				pfree(namespace_name);
 
 				object.classId = RelationRelationId;
-				object.objectId = HeapTupleGetOid(tuple);
+				object.objectId = relForm->oid;
 				object.objectSubId = 0;
 				break;
 
@@ -838,7 +838,7 @@ exec_object_restorecon(struct selabel_handle *sehnd, Oid catalogId)
 				pfree(namespace_name);
 
 				object.classId = ProcedureRelationId;
-				object.objectId = HeapTupleGetOid(tuple);
+				object.objectId = proForm->oid;
 				object.objectSubId = 0;
 				break;
 
diff --git a/contrib/sepgsql/sql/alter.sql b/contrib/sepgsql/sql/alter.sql
index 14000eaaeeb..f1144492329 100644
--- a/contrib/sepgsql/sql/alter.sql
+++ b/contrib/sepgsql/sql/alter.sql
@@ -134,8 +134,6 @@ CREATE RULE regtest_test_rule AS ON INSERT TO regtest_table_3 DO ALSO NOTHING;
 ALTER TABLE regtest_table_3 DISABLE RULE regtest_test_rule;     -- not supported
 ALTER TABLE regtest_table_3 ENABLE RULE regtest_test_rule;      -- not supported
 
-ALTER TABLE regtest_table SET WITH OIDS;
-ALTER TABLE regtest_table SET WITHOUT OIDS;
 ALTER TABLE regtest_table SET (fillfactor = 75);
 ALTER TABLE regtest_table RESET (fillfactor);
 ALTER TABLE regtest_table_2 NO INHERIT regtest_table;   -- not supported
@@ -157,8 +155,6 @@ ALTER TABLE regtest_ptable ALTER p SET STORAGE PLAIN;
 ALTER TABLE regtest_ptable ADD CONSTRAINT test_ck CHECK (p like '%abc%') NOT VALID;      -- not supported by sepgsql
 ALTER TABLE regtest_ptable DROP CONSTRAINT test_ck;      -- not supported by sepgsql
 
-ALTER TABLE regtest_ptable SET WITH OIDS;
-ALTER TABLE regtest_ptable SET WITHOUT OIDS;
 ALTER TABLE regtest_ptable SET TABLESPACE pg_default;
 
 -- partitioned table child
diff --git a/contrib/sepgsql/sql/ddl.sql b/contrib/sepgsql/sql/ddl.sql
index ae431f6cd2a..3deadb62526 100644
--- a/contrib/sepgsql/sql/ddl.sql
+++ b/contrib/sepgsql/sql/ddl.sql
@@ -30,7 +30,7 @@ CREATE TABLE regtest_table (x serial primary key, y text);
 
 ALTER TABLE regtest_table ADD COLUMN z int;
 
-CREATE TABLE regtest_table_2 (a int) WITH OIDS;
+CREATE TABLE regtest_table_2 (a int);
 
 CREATE TABLE regtest_ptable (a int) PARTITION BY RANGE (a);
 CREATE TABLE regtest_ptable_ones PARTITION OF regtest_ptable FOR VALUES FROM ('0') TO ('10');
@@ -112,7 +112,6 @@ DROP SEQUENCE regtest_seq;
 DROP VIEW regtest_view;
 
 ALTER TABLE regtest_table DROP COLUMN y;
-ALTER TABLE regtest_table_2 SET WITHOUT OIDS;
 
 ALTER TABLE regtest_ptable DROP COLUMN q CASCADE;
 
diff --git a/contrib/test_decoding/test_decoding.c b/contrib/test_decoding/test_decoding.c
index 1c439b57b0e..f6e77fbda13 100644
--- a/contrib/test_decoding/test_decoding.c
+++ b/contrib/test_decoding/test_decoding.c
@@ -319,13 +319,6 @@ static void
 tuple_to_stringinfo(StringInfo s, TupleDesc tupdesc, HeapTuple tuple, bool skip_nulls)
 {
 	int			natt;
-	Oid			oid;
-
-	/* print oid of tuple, it's not included in the TupleDesc */
-	if ((oid = HeapTupleHeaderGetOid(tuple->t_data)) != InvalidOid)
-	{
-		appendStringInfo(s, " oid[oid]:%u", oid);
-	}
 
 	/* print all columns individually */
 	for (natt = 0; natt < tupdesc->natts; natt++)
diff --git a/doc/src/sgml/catalogs.sgml b/doc/src/sgml/catalogs.sgml
index 8b7f169d50c..8675ef8c2fc 100644
--- a/doc/src/sgml/catalogs.sgml
+++ b/doc/src/sgml/catalogs.sgml
@@ -1853,15 +1853,6 @@ SCRAM-SHA-256$<replaceable>&lt;iteration count&gt;</replaceable>:<replaceable>&l
       </entry>
      </row>
 
-     <row>
-      <entry><structfield>relhasoids</structfield></entry>
-      <entry><type>bool</type></entry>
-      <entry></entry>
-      <entry>
-       True if we generate an OID for each row of the relation
-      </entry>
-     </row>
-
      <row>
       <entry><structfield>relhasrules</structfield></entry>
       <entry><type>bool</type></entry>
diff --git a/doc/src/sgml/config.sgml b/doc/src/sgml/config.sgml
index 0f8f2ef920d..1ba2e42ca38 100644
--- a/doc/src/sgml/config.sgml
+++ b/doc/src/sgml/config.sgml
@@ -7898,35 +7898,6 @@ dynamic_library_path = 'C:\tools\postgresql;H:\my_project\lib;$libdir'
       </listitem>
      </varlistentry>
 
-     <varlistentry id="guc-default-with-oids" xreflabel="default_with_oids">
-      <term><varname>default_with_oids</varname> (<type>boolean</type>)
-      <indexterm>
-       <primary><varname>default_with_oids</varname> configuration parameter</primary>
-      </indexterm>
-      </term>
-      <listitem>
-       <para>
-        This controls whether <command>CREATE TABLE</command> and
-        <command>CREATE TABLE AS</command> include an OID column in
-        newly-created tables, if neither <literal>WITH OIDS</literal>
-        nor <literal>WITHOUT OIDS</literal> is specified. It also
-        determines whether OIDs will be included in tables created by
-        <command>SELECT INTO</command>. The parameter is <literal>off</literal>
-        by default; in <productname>PostgreSQL</productname> 8.0 and earlier, it
-        was <literal>on</literal> by default.
-       </para>
-
-       <para>
-        The use of OIDs in user tables is considered deprecated, so
-        most installations should leave this variable disabled.
-        Applications that require OIDs for a particular table should
-        specify <literal>WITH OIDS</literal> when creating the
-        table. This variable can be enabled for compatibility with old
-        applications that do not follow this behavior.
-       </para>
-      </listitem>
-     </varlistentry>
-
      <varlistentry id="guc-escape-string-warning" xreflabel="escape_string_warning">
       <term><varname>escape_string_warning</varname> (<type>boolean</type>)
       <indexterm><primary>strings</primary><secondary>escape warning</secondary></indexterm>
diff --git a/doc/src/sgml/datatype.sgml b/doc/src/sgml/datatype.sgml
index 8c38dde8fb8..cae3fa95a89 100644
--- a/doc/src/sgml/datatype.sgml
+++ b/doc/src/sgml/datatype.sgml
@@ -4497,25 +4497,22 @@ INSERT INTO mytable VALUES(-1);  -- fails
    <para>
     Object identifiers (OIDs) are used internally by
     <productname>PostgreSQL</productname> as primary keys for various
-    system tables.  OIDs are not added to user-created tables, unless
-    <literal>WITH OIDS</literal> is specified when the table is
-    created, or the <xref linkend="guc-default-with-oids"/>
-    configuration variable is enabled.  Type <type>oid</type> represents
-    an object identifier.  There are also several alias types for
-    <type>oid</type>: <type>regproc</type>, <type>regprocedure</type>,
-    <type>regoper</type>, <type>regoperator</type>, <type>regclass</type>,
-    <type>regtype</type>, <type>regrole</type>, <type>regnamespace</type>,
-    <type>regconfig</type>, and <type>regdictionary</type>.
-    <xref linkend="datatype-oid-table"/> shows an overview.
+    system tables.
+
+    Type <type>oid</type> represents an object identifier.  There are also
+    several alias types for <type>oid</type>: <type>regproc</type>,
+    <type>regprocedure</type>, <type>regoper</type>, <type>regoperator</type>,
+    <type>regclass</type>, <type>regtype</type>, <type>regrole</type>,
+    <type>regnamespace</type>, <type>regconfig</type>, and
+    <type>regdictionary</type>.  <xref linkend="datatype-oid-table"/> shows an
+    overview.
    </para>
 
    <para>
     The <type>oid</type> type is currently implemented as an unsigned
     four-byte integer.  Therefore, it is not large enough to provide
     database-wide uniqueness in large databases, or even in large
-    individual tables.  So, using a user-created table's OID column as
-    a primary key is discouraged.  OIDs are best used only for
-    references to system tables.
+    individual tables.
    </para>
 
    <para>
diff --git a/doc/src/sgml/ddl.sgml b/doc/src/sgml/ddl.sgml
index c8268222af7..61c4a254603 100644
--- a/doc/src/sgml/ddl.sgml
+++ b/doc/src/sgml/ddl.sgml
@@ -938,24 +938,6 @@ CREATE TABLE circles (
   </indexterm>
 
   <variablelist>
-   <varlistentry>
-    <term><structfield>oid</structfield></term>
-    <listitem>
-     <para>
-      <indexterm>
-       <primary>OID</primary>
-       <secondary>column</secondary>
-      </indexterm>
-      The object identifier (object ID) of a row. This column is only
-      present if the table was created using <literal>WITH
-      OIDS</literal>, or if the <xref linkend="guc-default-with-oids"/>
-      configuration variable was set at the time. This column is of type
-      <type>oid</type> (same name as the column); see <xref
-      linkend="datatype-oid"/> for more information about the type.
-     </para>
-    </listitem>
-   </varlistentry>
-
    <varlistentry>
     <term><structfield>tableoid</structfield></term>
     <listitem>
@@ -1056,46 +1038,6 @@ CREATE TABLE circles (
    </varlistentry>
   </variablelist>
 
-   <para>
-    OIDs are 32-bit quantities and are assigned from a single
-    cluster-wide counter.  In a large or long-lived database, it is
-    possible for the counter to wrap around.  Hence, it is bad
-    practice to assume that OIDs are unique, unless you take steps to
-    ensure that this is the case.  If you need to identify the rows in
-    a table, using a sequence generator is strongly recommended.
-    However, OIDs can be used as well, provided that a few additional
-    precautions are taken:
-
-    <itemizedlist>
-     <listitem>
-      <para>
-       A unique constraint should be created on the OID column of each
-       table for which the OID will be used to identify rows.  When such
-       a unique constraint (or unique index) exists, the system takes
-       care not to generate an OID matching an already-existing row.
-       (Of course, this is only possible if the table contains fewer
-       than 2<superscript>32</superscript> (4 billion) rows, and in practice the
-       table size had better be much less than that, or performance
-       might suffer.)
-      </para>
-     </listitem>
-     <listitem>
-      <para>
-       OIDs should never be assumed to be unique across tables; use
-       the combination of <structfield>tableoid</structfield> and row OID if you
-       need a database-wide identifier.
-      </para>
-     </listitem>
-     <listitem>
-      <para>
-       Of course, the tables in question must be created <literal>WITH
-       OIDS</literal>.  As of <productname>PostgreSQL</productname> 8.1,
-       <literal>WITHOUT OIDS</literal> is the default.
-      </para>
-     </listitem>
-    </itemizedlist>
-   </para>
-
    <para>
     Transaction identifiers are also 32-bit quantities.  In a
     long-lived database it is possible for transaction IDs to wrap
diff --git a/doc/src/sgml/file-fdw.sgml b/doc/src/sgml/file-fdw.sgml
index 955a13ab7d9..19be824b039 100644
--- a/doc/src/sgml/file-fdw.sgml
+++ b/doc/src/sgml/file-fdw.sgml
@@ -174,9 +174,8 @@
  </variablelist>
 
  <para>
-  <command>COPY</command>'s <literal>OIDS</literal> and
-  <literal>FORCE_QUOTE</literal> options are currently not supported by
-  <literal>file_fdw</literal>.
+  <command>COPY</command>'s <literal>FORCE_QUOTE</literal> options is
+  currently not supported by <literal>file_fdw</literal>.
  </para>
 
  <para>
diff --git a/doc/src/sgml/plpgsql.sgml b/doc/src/sgml/plpgsql.sgml
index beb7e03bbcf..21f7a240493 100644
--- a/doc/src/sgml/plpgsql.sgml
+++ b/doc/src/sgml/plpgsql.sgml
@@ -1470,7 +1470,7 @@ GET DIAGNOSTICS integer_var = ROW_COUNT;
 
      <table id="plpgsql-current-diagnostics-values">
       <title>Available Diagnostics Items</title>
-      <tgroup cols="3">
+      <tgroup cols="2">
        <thead>
         <row>
          <entry>Name</entry>
@@ -1485,14 +1485,6 @@ GET DIAGNOSTICS integer_var = ROW_COUNT;
          <entry>the number of rows processed by the most
           recent <acronym>SQL</acronym> command</entry>
         </row>
-        <row>
-         <entry><varname>RESULT_OID</varname></entry>
-         <entry><type>oid</type></entry>
-         <entry>the OID of the last row inserted by the most
-          recent <acronym>SQL</acronym> command (only useful after
-          an <command>INSERT</command> command into a table having
-          OIDs)</entry>
-        </row>
         <row>
          <entry><literal>PG_CONTEXT</literal></entry>
          <entry><type>text</type></entry>
diff --git a/doc/src/sgml/pltcl.sgml b/doc/src/sgml/pltcl.sgml
index 4dd6fe434fa..7ff828de700 100644
--- a/doc/src/sgml/pltcl.sgml
+++ b/doc/src/sgml/pltcl.sgml
@@ -470,24 +470,6 @@ $$ LANGUAGE pltcl;
       </listitem>
      </varlistentry>
 
-     <varlistentry>
-      <term>
-       <function>spi_lastoid</function>
-       <indexterm>
-        <primary>spi_lastoid</primary>
-        <secondary>in PL/Tcl</secondary>
-       </indexterm>
-      </term>
-      <listitem>
-       <para>
-        Returns the OID of the row inserted by the last
-        <function>spi_exec</function> or <function>spi_execp</function>, if the
-        command was a single-row <command>INSERT</command> and the modified
-        table contained OIDs.  (If not, you get zero.)
-       </para>
-      </listitem>
-     </varlistentry>
-
      <varlistentry>
       <term><function>subtransaction</function> <replaceable>command</replaceable></term>
       <listitem>
diff --git a/doc/src/sgml/protocol.sgml b/doc/src/sgml/protocol.sgml
index f0b21452084..9f7fb0c1d04 100644
--- a/doc/src/sgml/protocol.sgml
+++ b/doc/src/sgml/protocol.sgml
@@ -3837,10 +3837,11 @@ CommandComplete (B)
         <literal>INSERT <replaceable>oid</replaceable>
         <replaceable>rows</replaceable></literal>, where
         <replaceable>rows</replaceable> is the number of rows
-        inserted. <replaceable>oid</replaceable> is the object ID
-        of the inserted row if <replaceable>rows</replaceable> is 1
-        and the target table has OIDs;
-        otherwise <replaceable>oid</replaceable> is 0.
+        inserted. <replaceable>oid</replaceable> used to be the object ID
+        of the inserted row if <replaceable>rows</replaceable> was 1
+        and the target table had OIDs, but OIDs system columns are
+        not supported anymore; therefore <replaceable>oid</replaceable>
+        is always 0.
        </para>
 
        <para>
diff --git a/doc/src/sgml/ref/alter_foreign_table.sgml b/doc/src/sgml/ref/alter_foreign_table.sgml
index f266be0c37b..b27eb6f2aae 100644
--- a/doc/src/sgml/ref/alter_foreign_table.sgml
+++ b/doc/src/sgml/ref/alter_foreign_table.sgml
@@ -50,7 +50,6 @@ ALTER FOREIGN TABLE [ IF EXISTS ] <replaceable class="parameter">name</replaceab
     ENABLE TRIGGER [ <replaceable class="parameter">trigger_name</replaceable> | ALL | USER ]
     ENABLE REPLICA TRIGGER <replaceable class="parameter">trigger_name</replaceable>
     ENABLE ALWAYS TRIGGER <replaceable class="parameter">trigger_name</replaceable>
-    SET WITH OIDS
     SET WITHOUT OIDS
     INHERIT <replaceable class="parameter">parent_table</replaceable>
     NO INHERIT <replaceable class="parameter">parent_table</replaceable>
@@ -223,34 +222,13 @@ ALTER FOREIGN TABLE [ IF EXISTS ] <replaceable class="parameter">name</replaceab
     </listitem>
    </varlistentry>
 
-   <varlistentry>
-    <term><literal>SET WITH OIDS</literal></term>
-    <listitem>
-     <para>
-      This form adds an <literal>oid</literal> system column to the
-      table (see <xref linkend="ddl-system-columns"/>).
-      It does nothing if the table already has OIDs.
-      Unless the table's foreign-data wrapper supports OIDs, this column
-      will simply read as zeroes.
-     </para>
-
-     <para>
-      Note that this is not equivalent to <literal>ADD COLUMN oid oid</literal>;
-      that would add a normal column that happened to be named
-      <literal>oid</literal>, not a system column.
-     </para>
-    </listitem>
-   </varlistentry>
-
    <varlistentry>
     <term><literal>SET WITHOUT OIDS</literal></term>
     <listitem>
      <para>
-      This form removes the <literal>oid</literal> system column from the
-      table.  This is exactly equivalent to
-      <literal>DROP COLUMN oid RESTRICT</literal>,
-      except that it will not complain if there is already no
-      <literal>oid</literal> column.
+      Backward compatibility syntax for removing the <literal>oid</literal>
+      system column. As oid system columns cannot be added anymore, this never
+      has an effect.
      </para>
     </listitem>
    </varlistentry>
diff --git a/doc/src/sgml/ref/alter_table.sgml b/doc/src/sgml/ref/alter_table.sgml
index f13a6cd944d..be1647937dc 100644
--- a/doc/src/sgml/ref/alter_table.sgml
+++ b/doc/src/sgml/ref/alter_table.sgml
@@ -72,7 +72,6 @@ ALTER TABLE [ IF EXISTS ] <replaceable class="parameter">name</replaceable>
     NO FORCE ROW LEVEL SECURITY
     CLUSTER ON <replaceable class="parameter">index_name</replaceable>
     SET WITHOUT CLUSTER
-    SET WITH OIDS
     SET WITHOUT OIDS
     SET TABLESPACE <replaceable class="parameter">new_tablespace</replaceable>
     SET { LOGGED | UNLOGGED }
@@ -613,32 +612,13 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM
     </listitem>
    </varlistentry>
 
-   <varlistentry>
-    <term><literal>SET WITH OIDS</literal></term>
-    <listitem>
-     <para>
-      This form adds an <literal>oid</literal> system column to the
-      table (see <xref linkend="ddl-system-columns"/>).
-      It does nothing if the table already has OIDs.
-     </para>
-
-     <para>
-      Note that this is not equivalent to <literal>ADD COLUMN oid oid</literal>;
-      that would add a normal column that happened to be named
-      <literal>oid</literal>, not a system column.
-     </para>
-    </listitem>
-   </varlistentry>
-
    <varlistentry>
     <term><literal>SET WITHOUT OIDS</literal></term>
     <listitem>
      <para>
-      This form removes the <literal>oid</literal> system column from the
-      table.  This is exactly equivalent to
-      <literal>DROP COLUMN oid RESTRICT</literal>,
-      except that it will not complain if there is already no
-      <literal>oid</literal> column.
+      Backward compatibility syntax for removing the <literal>oid</literal>
+      system column. As oid system columns cannot be added anymore, this never
+      has an effect.
      </para>
     </listitem>
    </varlistentry>
@@ -704,17 +684,6 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM
       <varname>effective_io_concurrency</varname>, <varname>parallel_workers</varname>, <varname>seq_page_cost</varname>,
       <varname>random_page_cost</varname>, <varname>n_distinct</varname> and <varname>n_distinct_inherited</varname>.
      </para>
-
-     <note>
-      <para>
-       While <command>CREATE TABLE</command> allows <literal>OIDS</literal> to be specified
-       in the <literal>WITH (<replaceable
-       class="parameter">storage_parameter</replaceable>)</literal> syntax,
-       <command>ALTER TABLE</command> does not treat <literal>OIDS</literal> as a
-       storage parameter.  Instead use the <literal>SET WITH OIDS</literal>
-       and <literal>SET WITHOUT OIDS</literal> forms to change OID status.
-      </para>
-     </note>
     </listitem>
    </varlistentry>
 
diff --git a/doc/src/sgml/ref/copy.sgml b/doc/src/sgml/ref/copy.sgml
index 13a8b68d951..eb458a59f2a 100644
--- a/doc/src/sgml/ref/copy.sgml
+++ b/doc/src/sgml/ref/copy.sgml
@@ -33,7 +33,6 @@ COPY { <replaceable class="parameter">table_name</replaceable> [ ( <replaceable
 <phrase>where <replaceable class="parameter">option</replaceable> can be one of:</phrase>
 
     FORMAT <replaceable class="parameter">format_name</replaceable>
-    OIDS [ <replaceable class="parameter">boolean</replaceable> ]
     FREEZE [ <replaceable class="parameter">boolean</replaceable> ]
     DELIMITER '<replaceable class="parameter">delimiter_character</replaceable>'
     NULL '<replaceable class="parameter">null_string</replaceable>'
@@ -203,18 +202,6 @@ COPY { <replaceable class="parameter">table_name</replaceable> [ ( <replaceable
     </listitem>
    </varlistentry>
 
-   <varlistentry>
-    <term><literal>OIDS</literal></term>
-    <listitem>
-     <para>
-      Specifies copying the OID for each row.  (An error is raised if
-      <literal>OIDS</literal> is specified for a table that does not
-      have OIDs, or in the case of copying a <replaceable
-      class="parameter">query</replaceable>.)
-     </para>
-    </listitem>
-   </varlistentry>
-
    <varlistentry>
     <term><literal>FREEZE</literal></term>
     <listitem>
@@ -547,8 +534,6 @@ COPY <replaceable class="parameter">count</replaceable>
     place of columns that are null.
     <command>COPY FROM</command> will raise an error if any line of the
     input file contains more or fewer columns than are expected.
-    If <literal>OIDS</literal> is specified, the OID is read or written as the first column,
-    preceding the user data columns.
    </para>
 
    <para>
@@ -822,7 +807,9 @@ only one flag bit is defined, and the rest must be zero:
           <term>Bit 16</term>
           <listitem>
            <para>
-            if 1, OIDs are included in the data; if 0, not
+            if 1, OIDs are included in the data; if 0, not. Oid system columns
+            are not supported in <productname>PostgreSQL</productname>
+            anymore, but the format still contains the indicator.
            </para>
           </listitem>
          </varlistentry>
@@ -893,10 +880,9 @@ distribution).
 
     <para>
 If OIDs are included in the file, the OID field immediately follows the
-field-count word.  It is a normal field except that it's not included
-in the field-count.  In particular it has a length word &mdash; this will allow
-handling of 4-byte vs. 8-byte OIDs without too much pain, and will allow
-OIDs to be shown as null if that ever proves desirable.
+field-count word.  It is a normal field except that it's not included in the
+field-count.  Note that oid system columns are note supported in current
+versions of <productname>PostgreSQL</productname>.
     </para>
    </refsect3>
 
@@ -999,7 +985,6 @@ COPY <replaceable class="parameter">table_name</replaceable> [ ( <replaceable cl
     FROM { '<replaceable class="parameter">filename</replaceable>' | STDIN }
     [ [ WITH ]
           [ BINARY ]
-          [ OIDS ]
           [ DELIMITER [ AS ] '<replaceable class="parameter">delimiter</replaceable>' ]
           [ NULL [ AS ] '<replaceable class="parameter">null string</replaceable>' ]
           [ CSV [ HEADER ]
@@ -1011,7 +996,6 @@ COPY { <replaceable class="parameter">table_name</replaceable> [ ( <replaceable
     TO { '<replaceable class="parameter">filename</replaceable>' | STDOUT }
     [ [ WITH ]
           [ BINARY ]
-          [ OIDS ]
           [ DELIMITER [ AS ] '<replaceable class="parameter">delimiter</replaceable>' ]
           [ NULL [ AS ] '<replaceable class="parameter">null string</replaceable>' ]
           [ CSV [ HEADER ]
@@ -1030,12 +1014,12 @@ COPY { <replaceable class="parameter">table_name</replaceable> [ ( <replaceable
    version 7.3 and is still supported:
 
 <synopsis>
-COPY [ BINARY ] <replaceable class="parameter">table_name</replaceable> [ WITH OIDS ]
+COPY [ BINARY ] <replaceable class="parameter">table_name</replaceable>
     FROM { '<replaceable class="parameter">filename</replaceable>' | STDIN }
     [ [USING] DELIMITERS '<replaceable class="parameter">delimiter</replaceable>' ]
     [ WITH NULL AS '<replaceable class="parameter">null string</replaceable>' ]
 
-COPY [ BINARY ] <replaceable class="parameter">table_name</replaceable> [ WITH OIDS ]
+COPY [ BINARY ] <replaceable class="parameter">table_name</replaceable>
     TO { '<replaceable class="parameter">filename</replaceable>' | STDOUT }
     [ [USING] DELIMITERS '<replaceable class="parameter">delimiter</replaceable>' ]
     [ WITH NULL AS '<replaceable class="parameter">null string</replaceable>' ]
diff --git a/doc/src/sgml/ref/create_materialized_view.sgml b/doc/src/sgml/ref/create_materialized_view.sgml
index eed4273c4b4..7f31ab4d26d 100644
--- a/doc/src/sgml/ref/create_materialized_view.sgml
+++ b/doc/src/sgml/ref/create_materialized_view.sgml
@@ -45,8 +45,7 @@ CREATE MATERIALIZED VIEW [ IF NOT EXISTS ] <replaceable>table_name</replaceable>
    <command>CREATE TABLE AS</command>, except that it also remembers the query used
    to initialize the view, so that it can be refreshed later upon demand.
    A materialized view has many of the same properties as a table, but there
-   is no support for temporary materialized views or automatic generation of
-   OIDs.
+   is no support for temporary materialized views.
   </para>
  </refsect1>
 
@@ -95,7 +94,7 @@ CREATE MATERIALIZED VIEW [ IF NOT EXISTS ] <replaceable>table_name</replaceable>
       endterm="sql-createtable-storage-parameters-title"/> for more
       information.  All parameters supported for <literal>CREATE
       TABLE</literal> are also supported for <literal>CREATE MATERIALIZED
-      VIEW</literal> with the exception of <literal>OIDS</literal>.
+      VIEW</literal>.
       See <xref linkend="sql-createtable"/> for more information.
      </para>
     </listitem>
diff --git a/doc/src/sgml/ref/create_table.sgml b/doc/src/sgml/ref/create_table.sgml
index 4b9c8a78017..aa420db79b0 100644
--- a/doc/src/sgml/ref/create_table.sgml
+++ b/doc/src/sgml/ref/create_table.sgml
@@ -29,7 +29,7 @@ CREATE [ [ GLOBAL | LOCAL ] { TEMPORARY | TEMP } | UNLOGGED ] TABLE [ IF NOT EXI
 ] )
 [ INHERITS ( <replaceable>parent_table</replaceable> [, ... ] ) ]
 [ PARTITION BY { RANGE | LIST | HASH } ( { <replaceable class="parameter">column_name</replaceable> | ( <replaceable class="parameter">expression</replaceable> ) } [ COLLATE <replaceable class="parameter">collation</replaceable> ] [ <replaceable class="parameter">opclass</replaceable> ] [, ... ] ) ]
-[ WITH ( <replaceable class="parameter">storage_parameter</replaceable> [= <replaceable class="parameter">value</replaceable>] [, ... ] ) | WITH OIDS | WITHOUT OIDS ]
+[ WITH ( <replaceable class="parameter">storage_parameter</replaceable> [= <replaceable class="parameter">value</replaceable>] [, ... ] ) | WITHOUT OIDS ]
 [ ON COMMIT { PRESERVE ROWS | DELETE ROWS | DROP } ]
 [ TABLESPACE <replaceable class="parameter">tablespace_name</replaceable> ]
 
@@ -40,7 +40,7 @@ CREATE [ [ GLOBAL | LOCAL ] { TEMPORARY | TEMP } | UNLOGGED ] TABLE [ IF NOT EXI
     [, ... ]
 ) ]
 [ PARTITION BY { RANGE | LIST | HASH } ( { <replaceable class="parameter">column_name</replaceable> | ( <replaceable class="parameter">expression</replaceable> ) } [ COLLATE <replaceable class="parameter">collation</replaceable> ] [ <replaceable class="parameter">opclass</replaceable> ] [, ... ] ) ]
-[ WITH ( <replaceable class="parameter">storage_parameter</replaceable> [= <replaceable class="parameter">value</replaceable>] [, ... ] ) | WITH OIDS | WITHOUT OIDS ]
+[ WITH ( <replaceable class="parameter">storage_parameter</replaceable> [= <replaceable class="parameter">value</replaceable>] [, ... ] ) | WITHOUT OIDS ]
 [ ON COMMIT { PRESERVE ROWS | DELETE ROWS | DROP } ]
 [ TABLESPACE <replaceable class="parameter">tablespace_name</replaceable> ]
 
@@ -51,7 +51,7 @@ CREATE [ [ GLOBAL | LOCAL ] { TEMPORARY | TEMP } | UNLOGGED ] TABLE [ IF NOT EXI
     [, ... ]
 ) ] { FOR VALUES <replaceable class="parameter">partition_bound_spec</replaceable> | DEFAULT }
 [ PARTITION BY { RANGE | LIST | HASH } ( { <replaceable class="parameter">column_name</replaceable> | ( <replaceable class="parameter">expression</replaceable> ) } [ COLLATE <replaceable class="parameter">collation</replaceable> ] [ <replaceable class="parameter">opclass</replaceable> ] [, ... ] ) ]
-[ WITH ( <replaceable class="parameter">storage_parameter</replaceable> [= <replaceable class="parameter">value</replaceable>] [, ... ] ) | WITH OIDS | WITHOUT OIDS ]
+[ WITH ( <replaceable class="parameter">storage_parameter</replaceable> [= <replaceable class="parameter">value</replaceable>] [, ... ] ) | WITHOUT OIDS ]
 [ ON COMMIT { PRESERVE ROWS | DELETE ROWS | DROP } ]
 [ TABLESPACE <replaceable class="parameter">tablespace_name</replaceable> ]
 
@@ -531,17 +531,13 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM
 
      <para>
       A partition must have the same column names and types as the partitioned
-      table to which it belongs.  If the parent is specified <literal>WITH
-      OIDS</literal> then all partitions must have OIDs; the parent's OID
-      column will be inherited by all partitions just like any other column.
-      Modifications to the column names or types of a partitioned table, or
-      the addition or removal of an OID column, will automatically propagate
-      to all partitions.  <literal>CHECK</literal> constraints will be inherited
-      automatically by every partition, but an individual partition may specify
-      additional <literal>CHECK</literal> constraints; additional constraints with
-      the same name and condition as in the parent will be merged with the
-      parent constraint.  Defaults may be specified separately for each
-      partition.
+      table to which it belongs. Modifications to the column names or types of
+      a partitioned table will automatically propagate to all partitions.
+      <literal>CHECK</literal> constraints will be inherited automatically by
+      every partition, but an individual partition may specify additional
+      <literal>CHECK</literal> constraints; additional constraints with the
+      same name and condition as in the parent will be merged with the parent
+      constraint.  Defaults may be specified separately for each partition.
      </para>
 
      <para>
@@ -1145,46 +1141,22 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM
       This clause specifies optional storage parameters for a table or index;
       see <xref linkend="sql-createtable-storage-parameters"
       endterm="sql-createtable-storage-parameters-title"/> for more
-      information.  The <literal>WITH</literal> clause for a
-      table can also include <literal>OIDS=TRUE</literal> (or just <literal>OIDS</literal>)
-      to specify that rows of the new table
-      should have OIDs (object identifiers) assigned to them, or
-      <literal>OIDS=FALSE</literal> to specify that the rows should not have OIDs.
-      If <literal>OIDS</literal> is not specified, the default setting depends upon
-      the <xref linkend="guc-default-with-oids"/> configuration parameter.
-      (If the new table inherits from any tables that have OIDs, then
-      <literal>OIDS=TRUE</literal> is forced even if the command says
-      <literal>OIDS=FALSE</literal>.)
-     </para>
-
-     <para>
-      If <literal>OIDS=FALSE</literal> is specified or implied, the new
-      table does not store OIDs and no OID will be assigned for a row inserted
-      into it. This is generally considered worthwhile, since it
-      will reduce OID consumption and thereby postpone the wraparound
-      of the 32-bit OID counter. Once the counter wraps around, OIDs
-      can no longer be assumed to be unique, which makes them
-      considerably less useful. In addition, excluding OIDs from a
-      table reduces the space required to store the table on disk by
-      4 bytes per row (on most machines), slightly improving performance.
-     </para>
-
-     <para>
-      To remove OIDs from a table after it has been created, use <xref
-      linkend="sql-altertable"/>.
+      information.  For backward-compatibility the <literal>WITH</literal>
+      clause for a table can also include <literal>OIDS=FALSE</literal> to
+      specify that rows of the new table should contain no OIDs (object
+      identifiers), <literal>OIDS=TRUE</literal> is not supported anymore.
+      OIDs.
      </para>
     </listitem>
    </varlistentry>
 
    <varlistentry>
-    <term><literal>WITH OIDS</literal></term>
     <term><literal>WITHOUT OIDS</literal></term>
     <listitem>
      <para>
-      These are obsolescent syntaxes equivalent to <literal>WITH (OIDS)</literal>
-      and <literal>WITH (OIDS=FALSE)</literal>, respectively.  If you wish to give
-      both an <literal>OIDS</literal> setting and storage parameters, you must use
-      the <literal>WITH ( ... )</literal> syntax; see above.
+      This is backward-compatible syntax for declaring a table
+      <literal>WITHOUT OIDS</literal>, creating a table <literal>WITH
+      OIDS</literal> is not supported anymore.
      </para>
     </listitem>
    </varlistentry>
@@ -1528,29 +1500,6 @@ WITH ( MODULUS <replaceable class="parameter">numeric_literal</replaceable>, REM
 
  <refsect1 id="sql-createtable-notes">
   <title>Notes</title>
-
-    <para>
-     Using OIDs in new applications is not recommended: where
-     possible, using an identity column or other sequence
-     generator as the table's primary key is preferred. However, if
-     your application does make use of OIDs to identify specific
-     rows of a table, it is recommended to create a unique constraint
-     on the <structfield>oid</structfield> column of that table, to ensure that
-     OIDs in the table will indeed uniquely identify rows even after
-     counter wraparound.  Avoid assuming that OIDs are unique across
-     tables; if you need a database-wide unique identifier, use the
-     combination of <structfield>tableoid</structfield> and row OID for the
-     purpose.
-    </para>
-
-    <tip>
-     <para>
-      The use of <literal>OIDS=FALSE</literal> is not recommended
-      for tables with no primary key, since without either an OID or a
-      unique data key, it is difficult to identify specific rows.
-     </para>
-    </tip>
-
     <para>
      <productname>PostgreSQL</productname> automatically creates an
      index for each unique constraint and primary key constraint to
@@ -2089,7 +2038,7 @@ CREATE TABLE cities_partdef
 
    <para>
     The <literal>WITH</literal> clause is a <productname>PostgreSQL</productname>
-    extension; neither storage parameters nor OIDs are in the standard.
+    extension; storage parameters are not in the standard.
    </para>
   </refsect2>
 
diff --git a/doc/src/sgml/ref/create_table_as.sgml b/doc/src/sgml/ref/create_table_as.sgml
index 527138e7872..679e8f521ed 100644
--- a/doc/src/sgml/ref/create_table_as.sgml
+++ b/doc/src/sgml/ref/create_table_as.sgml
@@ -23,7 +23,7 @@ PostgreSQL documentation
 <synopsis>
 CREATE [ [ GLOBAL | LOCAL ] { TEMPORARY | TEMP } | UNLOGGED ] TABLE [ IF NOT EXISTS ] <replaceable>table_name</replaceable>
     [ (<replaceable>column_name</replaceable> [, ...] ) ]
-    [ WITH ( <replaceable class="parameter">storage_parameter</replaceable> [= <replaceable class="parameter">value</replaceable>] [, ... ] ) | WITH OIDS | WITHOUT OIDS ]
+    [ WITH ( <replaceable class="parameter">storage_parameter</replaceable> [= <replaceable class="parameter">value</replaceable>] [, ... ] ) | WITHOUT OIDS ]
     [ ON COMMIT { PRESERVE ROWS | DELETE ROWS | DROP } ]
     [ TABLESPACE <replaceable class="parameter">tablespace_name</replaceable> ]
     AS <replaceable>query</replaceable>
@@ -127,25 +127,22 @@ CREATE [ [ GLOBAL | LOCAL ] { TEMPORARY | TEMP } | UNLOGGED ] TABLE [ IF NOT EXI
       This clause specifies optional storage parameters for the new table;
       see <xref linkend="sql-createtable-storage-parameters"
       endterm="sql-createtable-storage-parameters-title"/> for more
-      information.  The <literal>WITH</literal> clause
-      can also include <literal>OIDS=TRUE</literal> (or just <literal>OIDS</literal>)
-      to specify that rows of the new table
-      should have OIDs (object identifiers) assigned to them, or
-      <literal>OIDS=FALSE</literal> to specify that the rows should not have OIDs.
-      See <xref linkend="sql-createtable"/> for more information.
+      information.   For backward-compatibility the <literal>WITH</literal>
+      clause for a table can also include <literal>OIDS=FALSE</literal> to
+      specify that rows of the new table should contain no OIDs (object
+      identifiers), <literal>OIDS=TRUE</literal> is not supported anymore.
+      OIDs.
      </para>
     </listitem>
    </varlistentry>
 
    <varlistentry>
-    <term><literal>WITH OIDS</literal></term>
     <term><literal>WITHOUT OIDS</literal></term>
     <listitem>
      <para>
-      These are obsolescent syntaxes equivalent to <literal>WITH (OIDS)</literal>
-      and <literal>WITH (OIDS=FALSE)</literal>, respectively.  If you wish to give
-      both an <literal>OIDS</literal> setting and storage parameters, you must use
-      the <literal>WITH ( ... )</literal> syntax; see above.
+      This is backward-compatible syntax for declaring a table
+      <literal>WITHOUT OIDS</literal>, creating a table <literal>WITH
+      OIDS</literal> is not supported anymore.
      </para>
     </listitem>
    </varlistentry>
@@ -245,14 +242,6 @@ CREATE [ [ GLOBAL | LOCAL ] { TEMPORARY | TEMP } | UNLOGGED ] TABLE [ IF NOT EXI
    TABLE AS</command> offers a superset of the functionality offered
    by <command>SELECT INTO</command>.
   </para>
-
-  <para>
-   The <command>CREATE TABLE AS</command> command allows the user to
-   explicitly specify whether OIDs should be included. If the
-   presence of OIDs is not explicitly specified,
-   the <xref linkend="guc-default-with-oids"/> configuration variable is
-   used.
-  </para>
  </refsect1>
 
  <refsect1>
@@ -281,12 +270,12 @@ CREATE TABLE films2 AS
   <para>
    Create a new temporary table <literal>films_recent</literal>, consisting of
    only recent entries from the table <literal>films</literal>, using a
-   prepared statement.  The new table has OIDs and will be dropped at commit:
+   prepared statement.  The new table will be dropped at commit:
 
 <programlisting>
 PREPARE recentfilms(date) AS
   SELECT * FROM films WHERE date_prod &gt; $1;
-CREATE TEMP TABLE films_recent WITH (OIDS) ON COMMIT DROP AS
+CREATE TEMP TABLE films_recent ON COMMIT DROP AS
   EXECUTE recentfilms('2002-01-01');
 </programlisting></para>
  </refsect1>
@@ -325,7 +314,7 @@ CREATE TEMP TABLE films_recent WITH (OIDS) ON COMMIT DROP AS
     <listitem>
      <para>
       The <literal>WITH</literal> clause is a <productname>PostgreSQL</productname>
-      extension; neither storage parameters nor OIDs are in the standard.
+      extension; storage parameters are not in the standard.
      </para>
     </listitem>
 
diff --git a/doc/src/sgml/ref/select_into.sgml b/doc/src/sgml/ref/select_into.sgml
index 6c1a25f5ed5..462e3723819 100644
--- a/doc/src/sgml/ref/select_into.sgml
+++ b/doc/src/sgml/ref/select_into.sgml
@@ -104,13 +104,6 @@ SELECT [ ALL | DISTINCT [ ON ( <replaceable class="parameter">expression</replac
    <command>CREATE TABLE AS</command> offers a superset of the
    functionality provided by <command>SELECT INTO</command>.
   </para>
-
-  <para>
-   To add OIDs to the table created by <command>SELECT INTO</command>,
-   enable the <xref linkend="guc-default-with-oids"/> configuration
-   variable.  Alternatively, <command>CREATE TABLE AS</command> can be
-   used with the <literal>WITH OIDS</literal> clause.
-  </para>
  </refsect1>
 
  <refsect1>
diff --git a/doc/src/sgml/release-9.1.sgml b/doc/src/sgml/release-9.1.sgml
index e6ce80032fd..3407d8ad739 100644
--- a/doc/src/sgml/release-9.1.sgml
+++ b/doc/src/sgml/release-9.1.sgml
@@ -3654,7 +3654,7 @@ Branch: REL9_0_STABLE [9d6af7367] 2015-08-15 11:02:34 -0400
     <listitem>
      <para>
       Prevent foreign tables from being created with OIDS
-      when <xref linkend="guc-default-with-oids"/> is true
+      when <literal>default_with_oids"</literal> is true
       (Etsuro Fujita)
      </para>
     </listitem>
diff --git a/doc/src/sgml/release-9.2.sgml b/doc/src/sgml/release-9.2.sgml
index 3494ddb5cef..1e5f4e04c33 100644
--- a/doc/src/sgml/release-9.2.sgml
+++ b/doc/src/sgml/release-9.2.sgml
@@ -5650,7 +5650,7 @@ Branch: REL9_2_STABLE [6b700301c] 2015-02-17 16:03:00 +0100
     <listitem>
      <para>
       Prevent foreign tables from being created with OIDS
-      when <xref linkend="guc-default-with-oids"/> is true
+      when <literal>default_with_oids"</literal> is true
       (Etsuro Fujita)
      </para>
     </listitem>
diff --git a/doc/src/sgml/release-9.3.sgml b/doc/src/sgml/release-9.3.sgml
index 0c1498015ba..23868d65d8e 100644
--- a/doc/src/sgml/release-9.3.sgml
+++ b/doc/src/sgml/release-9.3.sgml
@@ -9237,7 +9237,7 @@ Branch: REL9_1_STABLE [dd1a5b09b] 2014-06-24 13:30:41 +0300
     <listitem>
      <para>
       Prevent foreign tables from being created with OIDS
-      when <xref linkend="guc-default-with-oids"/> is true
+      when <literal>default_with_oids"</literal> is true
       (Etsuro Fujita)
      </para>
     </listitem>
diff --git a/src/backend/access/brin/brin_tuple.c b/src/backend/access/brin/brin_tuple.c
index 00316b899c8..c82bbbaa7f8 100644
--- a/src/backend/access/brin/brin_tuple.c
+++ b/src/backend/access/brin/brin_tuple.c
@@ -62,7 +62,7 @@ brtuple_disk_tupdesc(BrinDesc *brdesc)
 		/* make sure it's in the bdesc's context */
 		oldcxt = MemoryContextSwitchTo(brdesc->bd_context);
 
-		tupdesc = CreateTemplateTupleDesc(brdesc->bd_totalstored, false);
+		tupdesc = CreateTemplateTupleDesc(brdesc->bd_totalstored);
 
 		for (i = 0; i < brdesc->bd_tupdesc->natts; i++)
 		{
diff --git a/src/backend/access/common/heaptuple.c b/src/backend/access/common/heaptuple.c
index 28127b311f5..f153ba1ab5e 100644
--- a/src/backend/access/common/heaptuple.c
+++ b/src/backend/access/common/heaptuple.c
@@ -382,7 +382,6 @@ heap_attisnull(HeapTuple tup, int attnum, TupleDesc tupleDesc)
 	{
 		case TableOidAttributeNumber:
 		case SelfItemPointerAttributeNumber:
-		case ObjectIdAttributeNumber:
 		case MinTransactionIdAttributeNumber:
 		case MinCommandIdAttributeNumber:
 		case MaxTransactionIdAttributeNumber:
@@ -640,9 +639,6 @@ heap_getsysattr(HeapTuple tup, int attnum, TupleDesc tupleDesc, bool *isnull)
 			/* pass-by-reference datatype */
 			result = PointerGetDatum(&(tup->t_self));
 			break;
-		case ObjectIdAttributeNumber:
-			result = ObjectIdGetDatum(HeapTupleGetOid(tup));
-			break;
 		case MinTransactionIdAttributeNumber:
 			result = TransactionIdGetDatum(HeapTupleHeaderGetRawXmin(tup->t_data));
 			break;
@@ -837,9 +833,6 @@ expand_tuple(HeapTuple *targetHeapTuple,
 	else
 		targetNullLen = 0;
 
-	if (tupleDesc->tdhasoid)
-		len += sizeof(Oid);
-
 	/*
 	 * Allocate and zero the space needed.  Note that the tuple body and
 	 * HeapTupleData management structure are allocated in one chunk.
@@ -1063,9 +1056,6 @@ heap_form_tuple(TupleDesc tupleDescriptor,
 	if (hasnull)
 		len += BITMAPLEN(numberOfAttributes);
 
-	if (tupleDescriptor->tdhasoid)
-		len += sizeof(Oid);
-
 	hoff = len = MAXALIGN(len); /* align user data safely */
 
 	data_len = heap_compute_data_size(tupleDescriptor, values, isnull);
@@ -1097,9 +1087,6 @@ heap_form_tuple(TupleDesc tupleDescriptor,
 	HeapTupleHeaderSetNatts(td, numberOfAttributes);
 	td->t_hoff = hoff;
 
-	if (tupleDescriptor->tdhasoid)	/* else leave infomask = 0 */
-		td->t_infomask = HEAP_HASOID;
-
 	heap_fill_tuple(tupleDescriptor,
 					values,
 					isnull,
@@ -1169,14 +1156,11 @@ heap_modify_tuple(HeapTuple tuple,
 	pfree(isnull);
 
 	/*
-	 * copy the identification info of the old tuple: t_ctid, t_self, and OID
-	 * (if any)
+	 * copy the identification info of the old tuple: t_ctid, t_self
 	 */
 	newTuple->t_data->t_ctid = tuple->t_data->t_ctid;
 	newTuple->t_self = tuple->t_self;
 	newTuple->t_tableOid = tuple->t_tableOid;
-	if (tupleDesc->tdhasoid)
-		HeapTupleSetOid(newTuple, HeapTupleGetOid(tuple));
 
 	return newTuple;
 }
@@ -1235,14 +1219,11 @@ heap_modify_tuple_by_cols(HeapTuple tuple,
 	pfree(isnull);
 
 	/*
-	 * copy the identification info of the old tuple: t_ctid, t_self, and OID
-	 * (if any)
+	 * copy the identification info of the old tuple: t_ctid, t_self
 	 */
 	newTuple->t_data->t_ctid = tuple->t_data->t_ctid;
 	newTuple->t_self = tuple->t_self;
 	newTuple->t_tableOid = tuple->t_tableOid;
-	if (tupleDesc->tdhasoid)
-		HeapTupleSetOid(newTuple, HeapTupleGetOid(tuple));
 
 	return newTuple;
 }
@@ -1590,9 +1571,6 @@ heap_form_minimal_tuple(TupleDesc tupleDescriptor,
 	if (hasnull)
 		len += BITMAPLEN(numberOfAttributes);
 
-	if (tupleDescriptor->tdhasoid)
-		len += sizeof(Oid);
-
 	hoff = len = MAXALIGN(len); /* align user data safely */
 
 	data_len = heap_compute_data_size(tupleDescriptor, values, isnull);
@@ -1611,9 +1589,6 @@ heap_form_minimal_tuple(TupleDesc tupleDescriptor,
 	HeapTupleHeaderSetNatts(tuple, numberOfAttributes);
 	tuple->t_hoff = hoff + MINIMAL_TUPLE_OFFSET;
 
-	if (tupleDescriptor->tdhasoid)	/* else leave infomask = 0 */
-		tuple->t_infomask = HEAP_HASOID;
-
 	heap_fill_tuple(tupleDescriptor,
 					values,
 					isnull,
diff --git a/src/backend/access/common/reloptions.c b/src/backend/access/common/reloptions.c
index db84da06789..57620648347 100644
--- a/src/backend/access/common/reloptions.c
+++ b/src/backend/access/common/reloptions.c
@@ -757,8 +757,8 @@ add_string_reloption(bits32 kinds, const char *name, const char *desc, const cha
  * reloptions value (possibly NULL), and we replace or remove entries
  * as needed.
  *
- * If ignoreOids is true, then we should ignore any occurrence of "oids"
- * in the list (it will be or has been handled by interpretOidsOption()).
+ * If acceptOidsOff is true, then we allow oids = false, but throw error when
+ * on. This is solely needed for backwards compatibility.
  *
  * Note that this is not responsible for determining whether the options
  * are valid, but it does check that namespaces for all the options given are
@@ -771,7 +771,7 @@ add_string_reloption(bits32 kinds, const char *name, const char *desc, const cha
  */
 Datum
 transformRelOptions(Datum oldOptions, List *defList, const char *namspace,
-					char *validnsps[], bool ignoreOids, bool isReset)
+					char *validnsps[], bool acceptOidsOff, bool isReset)
 {
 	Datum		result;
 	ArrayBuildState *astate;
@@ -882,9 +882,6 @@ transformRelOptions(Datum oldOptions, List *defList, const char *namspace,
 									def->defnamespace)));
 			}
 
-			if (ignoreOids && strcmp(def->defname, "oids") == 0)
-				continue;
-
 			/* ignore if not in the same namespace */
 			if (namspace == NULL)
 			{
@@ -905,6 +902,24 @@ transformRelOptions(Datum oldOptions, List *defList, const char *namspace,
 				value = defGetString(def);
 			else
 				value = "true";
+
+			/* FIXME: This is not a great place for this */
+			if (acceptOidsOff && strcmp(def->defname, "oids") == 0)
+			{
+				bool enabled;
+
+				if (!parse_bool(value, &enabled))
+					ereport(ERROR,
+							(errcode(ERRCODE_INVALID_PARAMETER_VALUE),
+							 errmsg("invalid value for boolean option \"%s\": %s",
+									def->defname, value)));
+				if (!enabled)
+					continue;
+				ereport(ERROR,
+						(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
+						 errmsg("tables with oids are not supported")));
+			}
+
 			len = VARHDRSZ + strlen(def->defname) + 1 + strlen(value);
 			/* +1 leaves room for sprintf's trailing null */
 			t = (text *) palloc(len + 1);
diff --git a/src/backend/access/common/tupconvert.c b/src/backend/access/common/tupconvert.c
index 21fe8ae4909..fc88aa376ac 100644
--- a/src/backend/access/common/tupconvert.c
+++ b/src/backend/access/common/tupconvert.c
@@ -138,13 +138,9 @@ convert_tuples_by_position(TupleDesc indesc,
 
 	/*
 	 * Check to see if the map is one-to-one, in which case we need not do a
-	 * tuple conversion.  We must also insist that both tupdescs either
-	 * specify or don't specify an OID column, else we need a conversion to
-	 * add/remove space for that.  (For some callers, presence or absence of
-	 * an OID column perhaps would not really matter, but let's be safe.)
+	 * tuple conversion.
 	 */
-	if (indesc->natts == outdesc->natts &&
-		indesc->tdhasoid == outdesc->tdhasoid)
+	if (indesc->natts == outdesc->natts)
 	{
 		for (i = 0; i < n; i++)
 		{
@@ -344,13 +340,9 @@ convert_tuples_by_name_map_if_req(TupleDesc indesc,
 
 	/*
 	 * Check to see if the map is one-to-one, in which case we need not do a
-	 * tuple conversion.  We must also insist that both tupdescs either
-	 * specify or don't specify an OID column, else we need a conversion to
-	 * add/remove space for that.  (For some callers, presence or absence of
-	 * an OID column perhaps would not really matter, but let's be safe.)
+	 * tuple conversion.
 	 */
-	if (indesc->natts == outdesc->natts &&
-		indesc->tdhasoid == outdesc->tdhasoid)
+	if (indesc->natts == outdesc->natts)
 	{
 		same = true;
 		for (i = 0; i < n; i++)
diff --git a/src/backend/access/common/tupdesc.c b/src/backend/access/common/tupdesc.c
index b0434b46720..5354a04639b 100644
--- a/src/backend/access/common/tupdesc.c
+++ b/src/backend/access/common/tupdesc.c
@@ -42,7 +42,7 @@
  * caller can overwrite this if needed.
  */
 TupleDesc
-CreateTemplateTupleDesc(int natts, bool hasoid)
+CreateTemplateTupleDesc(int natts)
 {
 	TupleDesc	desc;
 
@@ -73,7 +73,6 @@ CreateTemplateTupleDesc(int natts, bool hasoid)
 	desc->constr = NULL;
 	desc->tdtypeid = RECORDOID;
 	desc->tdtypmod = -1;
-	desc->tdhasoid = hasoid;
 	desc->tdrefcount = -1;		/* assume not reference-counted */
 
 	return desc;
@@ -88,12 +87,12 @@ CreateTemplateTupleDesc(int natts, bool hasoid)
  * caller can overwrite this if needed.
  */
 TupleDesc
-CreateTupleDesc(int natts, bool hasoid, Form_pg_attribute *attrs)
+CreateTupleDesc(int natts, Form_pg_attribute *attrs)
 {
 	TupleDesc	desc;
 	int			i;
 
-	desc = CreateTemplateTupleDesc(natts, hasoid);
+	desc = CreateTemplateTupleDesc(natts);
 
 	for (i = 0; i < natts; ++i)
 		memcpy(TupleDescAttr(desc, i), attrs[i], ATTRIBUTE_FIXED_PART_SIZE);
@@ -114,7 +113,7 @@ CreateTupleDescCopy(TupleDesc tupdesc)
 	TupleDesc	desc;
 	int			i;
 
-	desc = CreateTemplateTupleDesc(tupdesc->natts, tupdesc->tdhasoid);
+	desc = CreateTemplateTupleDesc(tupdesc->natts);
 
 	/* Flat-copy the attribute array */
 	memcpy(TupleDescAttr(desc, 0),
@@ -154,7 +153,7 @@ CreateTupleDescCopyConstr(TupleDesc tupdesc)
 	TupleConstr *constr = tupdesc->constr;
 	int			i;
 
-	desc = CreateTemplateTupleDesc(tupdesc->natts, tupdesc->tdhasoid);
+	desc = CreateTemplateTupleDesc(tupdesc->natts);
 
 	/* Flat-copy the attribute array */
 	memcpy(TupleDescAttr(desc, 0),
@@ -416,8 +415,6 @@ equalTupleDescs(TupleDesc tupdesc1, TupleDesc tupdesc2)
 		return false;
 	if (tupdesc1->tdtypeid != tupdesc2->tdtypeid)
 		return false;
-	if (tupdesc1->tdhasoid != tupdesc2->tdhasoid)
-		return false;
 
 	for (i = 0; i < tupdesc1->natts; i++)
 	{
@@ -574,7 +571,6 @@ hashTupleDesc(TupleDesc desc)
 
 	s = hash_combine(0, hash_uint32(desc->natts));
 	s = hash_combine(s, hash_uint32(desc->tdtypeid));
-	s = hash_combine(s, hash_uint32(desc->tdhasoid));
 	for (i = 0; i < desc->natts; ++i)
 		s = hash_combine(s, hash_uint32(TupleDescAttr(desc, i)->atttypid));
 
@@ -800,7 +796,7 @@ BuildDescForRelation(List *schema)
 	 * allocate a new tuple descriptor
 	 */
 	natts = list_length(schema);
-	desc = CreateTemplateTupleDesc(natts, false);
+	desc = CreateTemplateTupleDesc(natts);
 	has_not_null = false;
 
 	attnum = 0;
@@ -900,7 +896,7 @@ BuildDescFromLists(List *names, List *types, List *typmods, List *collations)
 	/*
 	 * allocate a new tuple descriptor
 	 */
-	desc = CreateTemplateTupleDesc(natts, false);
+	desc = CreateTemplateTupleDesc(natts);
 
 	attnum = 0;
 
diff --git a/src/backend/access/gin/ginutil.c b/src/backend/access/gin/ginutil.c
index 0a32182dd7f..d7696a1ad03 100644
--- a/src/backend/access/gin/ginutil.c
+++ b/src/backend/access/gin/ginutil.c
@@ -104,7 +104,7 @@ initGinState(GinState *state, Relation index)
 			state->tupdesc[i] = state->origTupdesc;
 		else
 		{
-			state->tupdesc[i] = CreateTemplateTupleDesc(2, false);
+			state->tupdesc[i] = CreateTemplateTupleDesc(2);
 
 			TupleDescInitEntry(state->tupdesc[i], (AttrNumber) 1, NULL,
 							   INT2OID, -1, 0);
diff --git a/src/backend/access/gist/gistscan.c b/src/backend/access/gist/gistscan.c
index 4d97ff1d5d2..6b18bd3afb8 100644
--- a/src/backend/access/gist/gistscan.c
+++ b/src/backend/access/gist/gistscan.c
@@ -167,7 +167,7 @@ gistrescan(IndexScanDesc scan, ScanKey key, int nkeys,
 		 * types.
 		 */
 		natts = RelationGetNumberOfAttributes(scan->indexRelation);
-		so->giststate->fetchTupdesc = CreateTemplateTupleDesc(natts, false);
+		so->giststate->fetchTupdesc = CreateTemplateTupleDesc(natts);
 		for (attno = 1; attno <= natts; attno++)
 		{
 			TupleDescInitEntry(so->giststate->fetchTupdesc, attno, NULL,
diff --git a/src/backend/access/heap/heapam.c b/src/backend/access/heap/heapam.c
index fb63471a0e0..ee88420d85d 100644
--- a/src/backend/access/heap/heapam.c
+++ b/src/backend/access/heap/heapam.c
@@ -2454,7 +2454,7 @@ ReleaseBulkInsertStatePin(BulkInsertState bistate)
  * TID where the tuple was stored.  But note that any toasting of fields
  * within the tuple data is NOT reflected into *tup.
  */
-Oid
+void
 heap_insert(Relation relation, HeapTuple tup, CommandId cid,
 			int options, BulkInsertState bistate)
 {
@@ -2628,8 +2628,6 @@ heap_insert(Relation relation, HeapTuple tup, CommandId cid,
 		tup->t_self = heaptup->t_self;
 		heap_freetuple(heaptup);
 	}
-
-	return HeapTupleGetOid(tup);
 }
 
 /*
@@ -2656,30 +2654,6 @@ heap_prepare_insert(Relation relation, HeapTuple tup, TransactionId xid,
 				(errcode(ERRCODE_INVALID_TRANSACTION_STATE),
 				 errmsg("cannot insert tuples in a parallel worker")));
 
-	if (relation->rd_rel->relhasoids)
-	{
-#ifdef NOT_USED
-		/* this is redundant with an Assert in HeapTupleSetOid */
-		Assert(tup->t_data->t_infomask & HEAP_HASOID);
-#endif
-
-		/*
-		 * If the object id of this tuple has already been assigned, trust the
-		 * caller.  There are a couple of ways this can happen.  At initial db
-		 * creation, the backend program sets oids for tuples. When we define
-		 * an index, we set the oid.  Finally, in the future, we may allow
-		 * users to set their own object ids in order to support a persistent
-		 * object store (objects need to contain pointers to one another).
-		 */
-		if (!OidIsValid(HeapTupleGetOid(tup)))
-			HeapTupleSetOid(tup, GetNewOid(relation));
-	}
-	else
-	{
-		/* check there is not space for an OID */
-		Assert(!(tup->t_data->t_infomask & HEAP_HASOID));
-	}
-
 	tup->t_data->t_infomask &= ~(HEAP_XACT_MASK);
 	tup->t_data->t_infomask2 &= ~(HEAP2_XACT_MASK);
 	tup->t_data->t_infomask |= HEAP_XMAX_INVALID;
@@ -2995,10 +2969,10 @@ heap_multi_insert(Relation relation, HeapTuple *tuples, int ntuples,
  * This should be used rather than using heap_insert directly in most places
  * where we are modifying system catalogs.
  */
-Oid
+void
 simple_heap_insert(Relation relation, HeapTuple tup)
 {
-	return heap_insert(relation, tup, GetCurrentCommandId(true), 0, NULL);
+	heap_insert(relation, tup, GetCurrentCommandId(true), 0, NULL);
 }
 
 /*
@@ -3656,21 +3630,6 @@ heap_update(Relation relation, ItemPointer otid, HeapTuple newtup,
 	/* the new tuple is ready, except for this: */
 	newtup->t_tableOid = RelationGetRelid(relation);
 
-	/* Fill in OID for newtup */
-	if (relation->rd_rel->relhasoids)
-	{
-#ifdef NOT_USED
-		/* this is redundant with an Assert in HeapTupleSetOid */
-		Assert(newtup->t_data->t_infomask & HEAP_HASOID);
-#endif
-		HeapTupleSetOid(newtup, HeapTupleGetOid(&oldtup));
-	}
-	else
-	{
-		/* check there is not space for an OID */
-		Assert(!(newtup->t_data->t_infomask & HEAP_HASOID));
-	}
-
 	/* Determine columns modified by the update. */
 	modified_attrs = HeapDetermineModifiedColumns(relation, interesting_attrs,
 												  &oldtup, newtup);
@@ -4437,13 +4396,12 @@ heap_tuple_attr_equals(TupleDesc tupdesc, int attrnum,
 
 	/*
 	 * Likewise, automatically say "not equal" for any system attribute other
-	 * than OID and tableOID; we cannot expect these to be consistent in a HOT
-	 * chain, or even to be set correctly yet in the new tuple.
+	 * than tableOID; we cannot expect these to be consistent in a HOT chain,
+	 * or even to be set correctly yet in the new tuple.
 	 */
 	if (attrnum < 0)
 	{
-		if (attrnum != ObjectIdAttributeNumber &&
-			attrnum != TableOidAttributeNumber)
+		if (attrnum != TableOidAttributeNumber)
 			return false;
 	}
 
@@ -8122,16 +8080,7 @@ ExtractReplicaIdentity(Relation relation, HeapTuple tp, bool key_changed, bool *
 		int			attno = idx_rel->rd_index->indkey.values[natt];
 
 		if (attno < 0)
-		{
-			/*
-			 * The OID column can appear in an index definition, but that's
-			 * OK, because we always copy the OID if present (see below).
-			 * Other system columns may not.
-			 */
-			if (attno == ObjectIdAttributeNumber)
-				continue;
 			elog(ERROR, "system column in index");
-		}
 		nulls[attno - 1] = false;
 	}
 
@@ -8139,14 +8088,6 @@ ExtractReplicaIdentity(Relation relation, HeapTuple tp, bool key_changed, bool *
 	*copy = true;
 	RelationClose(idx_rel);
 
-	/*
-	 * Always copy oids if the table has them, even if not included in the
-	 * index. The space in the logged tuple is used anyway, so there's little
-	 * point in not including the information.
-	 */
-	if (relation->rd_rel->relhasoids)
-		HeapTupleSetOid(key_tuple, HeapTupleGetOid(tp));
-
 	/*
 	 * If the tuple, which by here only contains indexed columns, still has
 	 * toasted columns, force them to be inlined. This is somewhat unlikely
diff --git a/src/backend/access/heap/tuptoaster.c b/src/backend/access/heap/tuptoaster.c
index cd42c50b09c..fdbaf38126d 100644
--- a/src/backend/access/heap/tuptoaster.c
+++ b/src/backend/access/heap/tuptoaster.c
@@ -723,8 +723,6 @@ toast_insert_or_update(Relation rel, HeapTuple newtup, HeapTuple oldtup,
 	hoff = SizeofHeapTupleHeader;
 	if (has_nulls)
 		hoff += BITMAPLEN(numAttrs);
-	if (newtup->t_data->t_infomask & HEAP_HASOID)
-		hoff += sizeof(Oid);
 	hoff = MAXALIGN(hoff);
 	/* now convert to a limit on the tuple data size */
 	maxDataLen = RelationGetToastTupleTarget(rel, TOAST_TUPLE_TARGET) - hoff;
@@ -1013,8 +1011,6 @@ toast_insert_or_update(Relation rel, HeapTuple newtup, HeapTuple oldtup,
 		new_header_len = SizeofHeapTupleHeader;
 		if (has_nulls)
 			new_header_len += BITMAPLEN(numAttrs);
-		if (olddata->t_infomask & HEAP_HASOID)
-			new_header_len += sizeof(Oid);
 		new_header_len = MAXALIGN(new_header_len);
 		new_data_len = heap_compute_data_size(tupleDesc,
 											  toast_values, toast_isnull);
@@ -1036,8 +1032,6 @@ toast_insert_or_update(Relation rel, HeapTuple newtup, HeapTuple oldtup,
 		memcpy(new_data, olddata, SizeofHeapTupleHeader);
 		HeapTupleHeaderSetNatts(new_data, numAttrs);
 		new_data->t_hoff = new_header_len;
-		if (olddata->t_infomask & HEAP_HASOID)
-			HeapTupleHeaderSetOid(new_data, HeapTupleHeaderGetOid(olddata));
 
 		/* Copy over the data, and fill the null bitmap if needed */
 		heap_fill_tuple(tupleDesc,
@@ -1124,13 +1118,10 @@ toast_flatten_tuple(HeapTuple tup, TupleDesc tupleDesc)
 	new_tuple = heap_form_tuple(tupleDesc, toast_values, toast_isnull);
 
 	/*
-	 * Be sure to copy the tuple's OID and identity fields.  We also make a
-	 * point of copying visibility info, just in case anybody looks at those
-	 * fields in a syscache entry.
+	 * Be sure to copy the tuple's identity fields.  We also make a point of
+	 * copying visibility info, just in case anybody looks at those fields in
+	 * a syscache entry.
 	 */
-	if (tupleDesc->tdhasoid)
-		HeapTupleSetOid(new_tuple, HeapTupleGetOid(tup));
-
 	new_tuple->t_self = tup->t_self;
 	new_tuple->t_tableOid = tup->t_tableOid;
 
@@ -1244,8 +1235,6 @@ toast_flatten_tuple_to_datum(HeapTupleHeader tup,
 	new_header_len = SizeofHeapTupleHeader;
 	if (has_nulls)
 		new_header_len += BITMAPLEN(numAttrs);
-	if (tup->t_infomask & HEAP_HASOID)
-		new_header_len += sizeof(Oid);
 	new_header_len = MAXALIGN(new_header_len);
 	new_data_len = heap_compute_data_size(tupleDesc,
 										  toast_values, toast_isnull);
@@ -1259,8 +1248,6 @@ toast_flatten_tuple_to_datum(HeapTupleHeader tup,
 	memcpy(new_data, tup, SizeofHeapTupleHeader);
 	HeapTupleHeaderSetNatts(new_data, numAttrs);
 	new_data->t_hoff = new_header_len;
-	if (tup->t_infomask & HEAP_HASOID)
-		HeapTupleHeaderSetOid(new_data, HeapTupleHeaderGetOid(tup));
 
 	/* Set the composite-Datum header fields correctly */
 	HeapTupleHeaderSetDatumLength(new_data, new_tuple_len);
@@ -1796,7 +1783,7 @@ toast_delete_datum(Relation rel, Datum value, bool is_speculative)
  *
  *	Test whether a toast value with the given ID exists in the toast relation.
  *	For safety, we consider a value to exist if there are either live or dead
- *	toast rows with that ID; see notes for GetNewOid().
+ *	toast rows with that ID; see notes for GetNewOidWithIndex().
  * ----------
  */
 static bool
diff --git a/src/backend/access/transam/commit_ts.c b/src/backend/access/transam/commit_ts.c
index 599203c96ce..66b940c66cc 100644
--- a/src/backend/access/transam/commit_ts.c
+++ b/src/backend/access/transam/commit_ts.c
@@ -434,7 +434,7 @@ pg_last_committed_xact(PG_FUNCTION_ARGS)
 	 * Construct a tuple descriptor for the result row.  This must match this
 	 * function's pg_proc entry!
 	 */
-	tupdesc = CreateTemplateTupleDesc(2, false);
+	tupdesc = CreateTemplateTupleDesc(2);
 	TupleDescInitEntry(tupdesc, (AttrNumber) 1, "xid",
 					   XIDOID, -1, 0);
 	TupleDescInitEntry(tupdesc, (AttrNumber) 2, "timestamp",
diff --git a/src/backend/access/transam/multixact.c b/src/backend/access/transam/multixact.c
index 365daf153ab..82346f1000d 100644
--- a/src/backend/access/transam/multixact.c
+++ b/src/backend/access/transam/multixact.c
@@ -3368,7 +3368,7 @@ pg_get_multixact_members(PG_FUNCTION_ARGS)
 												false);
 		multi->iter = 0;
 
-		tupdesc = CreateTemplateTupleDesc(2, false);
+		tupdesc = CreateTemplateTupleDesc(2);
 		TupleDescInitEntry(tupdesc, (AttrNumber) 1, "xid",
 						   XIDOID, -1, 0);
 		TupleDescInitEntry(tupdesc, (AttrNumber) 2, "mode",
diff --git a/src/backend/access/transam/twophase.c b/src/backend/access/transam/twophase.c
index 3942734e5ae..e65dccc6a2c 100644
--- a/src/backend/access/transam/twophase.c
+++ b/src/backend/access/transam/twophase.c
@@ -734,7 +734,7 @@ pg_prepared_xact(PG_FUNCTION_ARGS)
 
 		/* build tupdesc for result tuples */
 		/* this had better match pg_prepared_xacts view in system_views.sql */
-		tupdesc = CreateTemplateTupleDesc(5, false);
+		tupdesc = CreateTemplateTupleDesc(5);
 		TupleDescInitEntry(tupdesc, (AttrNumber) 1, "transaction",
 						   XIDOID, -1, 0);
 		TupleDescInitEntry(tupdesc, (AttrNumber) 2, "gid",
diff --git a/src/backend/access/transam/varsup.c b/src/backend/access/transam/varsup.c
index 664735b3814..a5eb29e01ac 100644
--- a/src/backend/access/transam/varsup.c
+++ b/src/backend/access/transam/varsup.c
@@ -451,8 +451,8 @@ ForceTransactionIdLimitUpdate(void)
  * OIDs are generated by a cluster-wide counter.  Since they are only 32 bits
  * wide, counter wraparound will occur eventually, and therefore it is unwise
  * to assume they are unique unless precautions are taken to make them so.
- * Hence, this routine should generally not be used directly.  The only
- * direct callers should be GetNewOid() and GetNewRelFileNode() in
+ * Hence, this routine should generally not be used directly.  The only direct
+ * callers should be GetNewOidWithIndex() and GetNewRelFileNode() in
  * catalog/catalog.c.
  */
 Oid
diff --git a/src/backend/access/transam/xlogfuncs.c b/src/backend/access/transam/xlogfuncs.c
index a31adcca5eb..bd18f496af1 100644
--- a/src/backend/access/transam/xlogfuncs.c
+++ b/src/backend/access/transam/xlogfuncs.c
@@ -471,7 +471,7 @@ pg_walfile_name_offset(PG_FUNCTION_ARGS)
 	 * Construct a tuple descriptor for the result row.  This must match this
 	 * function's pg_proc entry!
 	 */
-	resultTupleDesc = CreateTemplateTupleDesc(2, false);
+	resultTupleDesc = CreateTemplateTupleDesc(2);
 	TupleDescInitEntry(resultTupleDesc, (AttrNumber) 1, "file_name",
 					   TEXTOID, -1, 0);
 	TupleDescInitEntry(resultTupleDesc, (AttrNumber) 2, "file_offset",
diff --git a/src/backend/bootstrap/bootparse.y b/src/backend/bootstrap/bootparse.y
index 4c72989cc25..f49c808eeb7 100644
--- a/src/backend/bootstrap/bootparse.y
+++ b/src/backend/bootstrap/bootparse.y
@@ -113,7 +113,7 @@ static int num_columns_read = 0;
 %type <list>  boot_index_params
 %type <ielem> boot_index_param
 %type <str>   boot_ident
-%type <ival>  optbootstrap optsharedrelation optwithoutoids boot_column_nullness
+%type <ival>  optbootstrap optsharedrelation boot_column_nullness
 %type <oidval> oidspec optoideq optrowtypeoid
 
 %token <str> ID
@@ -123,7 +123,7 @@ static int num_columns_read = 0;
 /* All the rest are unreserved, and should be handled in boot_ident! */
 %token <kw> OPEN XCLOSE XCREATE INSERT_TUPLE
 %token <kw> XDECLARE INDEX ON USING XBUILD INDICES UNIQUE XTOAST
-%token <kw> OBJ_ID XBOOTSTRAP XSHARED_RELATION XWITHOUT_OIDS XROWTYPE_OID
+%token <kw> OBJ_ID XBOOTSTRAP XSHARED_RELATION XROWTYPE_OID
 %token <kw> XFORCE XNOT XNULL
 
 %start TopLevel
@@ -170,7 +170,7 @@ Boot_CloseStmt:
 		;
 
 Boot_CreateStmt:
-		  XCREATE boot_ident oidspec optbootstrap optsharedrelation optwithoutoids optrowtypeoid LPAREN
+		  XCREATE boot_ident oidspec optbootstrap optsharedrelation optrowtypeoid LPAREN
 				{
 					do_start();
 					numattr = 0;
@@ -192,7 +192,7 @@ Boot_CreateStmt:
 
 					do_start();
 
-					tupdesc = CreateTupleDesc(numattr, !($6), attrtypes);
+					tupdesc = CreateTupleDesc(numattr, attrtypes);
 
 					shared_relation = $5;
 
@@ -236,7 +236,7 @@ Boot_CreateStmt:
 													  PG_CATALOG_NAMESPACE,
 													  shared_relation ? GLOBALTABLESPACE_OID : 0,
 													  $3,
-													  $7,
+													  $6,
 													  InvalidOid,
 													  BOOTSTRAP_SUPERUSERID,
 													  tupdesc,
@@ -245,8 +245,6 @@ Boot_CreateStmt:
 													  RELPERSISTENCE_PERMANENT,
 													  shared_relation,
 													  mapped_relation,
-													  true,
-													  0,
 													  ONCOMMIT_NOOP,
 													  (Datum) 0,
 													  false,
@@ -432,11 +430,6 @@ optsharedrelation:
 		|						{ $$ = 0; }
 		;
 
-optwithoutoids:
-			XWITHOUT_OIDS	{ $$ = 1; }
-		|					{ $$ = 0; }
-		;
-
 optrowtypeoid:
 			XROWTYPE_OID oidspec	{ $$ = $2; }
 		|							{ $$ = InvalidOid; }
@@ -501,7 +494,6 @@ boot_ident:
 		| OBJ_ID		{ $$ = pstrdup($1); }
 		| XBOOTSTRAP	{ $$ = pstrdup($1); }
 		| XSHARED_RELATION	{ $$ = pstrdup($1); }
-		| XWITHOUT_OIDS	{ $$ = pstrdup($1); }
 		| XROWTYPE_OID	{ $$ = pstrdup($1); }
 		| XFORCE		{ $$ = pstrdup($1); }
 		| XNOT			{ $$ = pstrdup($1); }
diff --git a/src/backend/bootstrap/bootscanner.l b/src/backend/bootstrap/bootscanner.l
index 739087b786f..14bc0888979 100644
--- a/src/backend/bootstrap/bootscanner.l
+++ b/src/backend/bootstrap/bootscanner.l
@@ -91,7 +91,6 @@ create			{ yylval.kw = "create"; return XCREATE; }
 OID				{ yylval.kw = "OID"; return OBJ_ID; }
 bootstrap		{ yylval.kw = "bootstrap"; return XBOOTSTRAP; }
 shared_relation	{ yylval.kw = "shared_relation"; return XSHARED_RELATION; }
-without_oids	{ yylval.kw = "without_oids"; return XWITHOUT_OIDS; }
 rowtype_oid		{ yylval.kw = "rowtype_oid"; return XROWTYPE_OID; }
 
 insert			{ yylval.kw = "insert"; return INSERT_TUPLE; }
diff --git a/src/backend/bootstrap/bootstrap.c b/src/backend/bootstrap/bootstrap.c
index 578af2e66d8..8e2cf7df562 100644
--- a/src/backend/bootstrap/bootstrap.c
+++ b/src/backend/bootstrap/bootstrap.c
@@ -616,7 +616,7 @@ boot_openrel(char *relname)
 		app = Typ;
 		while ((tup = heap_getnext(scan, ForwardScanDirection)) != NULL)
 		{
-			(*app)->am_oid = HeapTupleGetOid(tup);
+			(*app)->am_oid = ((Form_pg_type) GETSTRUCT(tup))->oid;
 			memcpy((char *) &(*app)->am_typ,
 				   (char *) GETSTRUCT(tup),
 				   sizeof((*app)->am_typ));
@@ -807,12 +807,8 @@ InsertOneTuple(Oid objectid)
 
 	elog(DEBUG4, "inserting row oid %u, %d columns", objectid, numattr);
 
-	tupDesc = CreateTupleDesc(numattr,
-							  RelationGetForm(boot_reldesc)->relhasoids,
-							  attrtypes);
+	tupDesc = CreateTupleDesc(numattr, attrtypes);
 	tuple = heap_form_tuple(tupDesc, values, Nulls);
-	if (objectid != (Oid) 0)
-		HeapTupleSetOid(tuple, objectid);
 	pfree(tupDesc);				/* just free's tupDesc, not the attrtypes */
 
 	simple_heap_insert(boot_reldesc, tuple);
@@ -946,7 +942,7 @@ gettype(char *type)
 		app = Typ;
 		while ((tup = heap_getnext(scan, ForwardScanDirection)) != NULL)
 		{
-			(*app)->am_oid = HeapTupleGetOid(tup);
+			(*app)->am_oid = ((Form_pg_type) GETSTRUCT(tup))->oid;
 			memmove((char *) &(*app++)->am_typ,
 					(char *) GETSTRUCT(tup),
 					sizeof((*app)->am_typ));
diff --git a/src/backend/catalog/Catalog.pm b/src/backend/catalog/Catalog.pm
index 9699dfd8d52..d5c096f7d1b 100644
--- a/src/backend/catalog/Catalog.pm
+++ b/src/backend/catalog/Catalog.pm
@@ -111,8 +111,6 @@ sub ParseHeader
 			$catalog{bootstrap} = /BKI_BOOTSTRAP/ ? ' bootstrap' : '';
 			$catalog{shared_relation} =
 			  /BKI_SHARED_RELATION/ ? ' shared_relation' : '';
-			$catalog{without_oids} =
-			  /BKI_WITHOUT_OIDS/ ? ' without_oids' : '';
 			if (/BKI_ROWTYPE_OID\((\d+),(\w+)\)/)
 			{
 				$catalog{rowtype_oid}        = $1;
@@ -337,6 +335,10 @@ sub AddDefaultValues
 		{
 			;
 		}
+		elsif ($attname eq 'oid')
+		{
+			;
+		}
 		elsif (defined $column->{default})
 		{
 			$row->{$attname} = $column->{default};
diff --git a/src/backend/catalog/aclchk.c b/src/backend/catalog/aclchk.c
index bd147752ef9..1dd70bb9c69 100644
--- a/src/backend/catalog/aclchk.c
+++ b/src/backend/catalog/aclchk.c
@@ -848,7 +848,9 @@ objectsInSchemaToOids(ObjectType objtype, List *nspnames)
 
 					while ((tuple = heap_getnext(scan, ForwardScanDirection)) != NULL)
 					{
-						objects = lappend_oid(objects, HeapTupleGetOid(tuple));
+						Oid		oid = ((Form_pg_proc) GETSTRUCT(tuple))->oid;
+
+						objects = lappend_oid(objects, oid);
 					}
 
 					heap_endscan(scan);
@@ -893,7 +895,9 @@ getRelationsInNamespace(Oid namespaceId, char relkind)
 
 	while ((tuple = heap_getnext(scan, ForwardScanDirection)) != NULL)
 	{
-		relations = lappend_oid(relations, HeapTupleGetOid(tuple));
+		Oid		oid  = ((Form_pg_class) GETSTRUCT(tuple))->oid;
+
+		relations = lappend_oid(relations, oid);
 	}
 
 	heap_endscan(scan);
@@ -1299,7 +1303,7 @@ SetDefaultACL(InternalDefaultACL *iacls)
 			 * there shouldn't be anything depending on this entry.
 			 */
 			myself.classId = DefaultAclRelationId;
-			myself.objectId = HeapTupleGetOid(tuple);
+			myself.objectId = ((Form_pg_default_acl) GETSTRUCT(tuple))->oid;
 			myself.objectSubId = 0;
 
 			performDeletion(&myself, DROP_RESTRICT, 0);
@@ -1307,6 +1311,8 @@ SetDefaultACL(InternalDefaultACL *iacls)
 	}
 	else
 	{
+		Oid		defAclOid;
+
 		/* Prepare to insert or update pg_default_acl entry */
 		MemSet(values, 0, sizeof(values));
 		MemSet(nulls, false, sizeof(nulls));
@@ -1315,6 +1321,9 @@ SetDefaultACL(InternalDefaultACL *iacls)
 		if (isNew)
 		{
 			/* insert new entry */
+			defAclOid = GetNewOidWithIndex(rel, DefaultAclOidIndexId,
+										   Anum_pg_default_acl_oid);
+			values[Anum_pg_default_acl_oid - 1] = ObjectIdGetDatum(defAclOid);
 			values[Anum_pg_default_acl_defaclrole - 1] = ObjectIdGetDatum(iacls->roleid);
 			values[Anum_pg_default_acl_defaclnamespace - 1] = ObjectIdGetDatum(iacls->nspid);
 			values[Anum_pg_default_acl_defaclobjtype - 1] = CharGetDatum(objtype);
@@ -1325,6 +1334,8 @@ SetDefaultACL(InternalDefaultACL *iacls)
 		}
 		else
 		{
+			defAclOid = ((Form_pg_default_acl) GETSTRUCT(tuple))->oid;
+
 			/* update existing entry */
 			values[Anum_pg_default_acl_defaclacl - 1] = PointerGetDatum(new_acl);
 			replaces[Anum_pg_default_acl_defaclacl - 1] = true;
@@ -1338,8 +1349,7 @@ SetDefaultACL(InternalDefaultACL *iacls)
 		if (isNew)
 		{
 			/* dependency on role */
-			recordDependencyOnOwner(DefaultAclRelationId,
-									HeapTupleGetOid(newtuple),
+			recordDependencyOnOwner(DefaultAclRelationId, defAclOid,
 									iacls->roleid);
 
 			/* dependency on namespace */
@@ -1349,7 +1359,7 @@ SetDefaultACL(InternalDefaultACL *iacls)
 							referenced;
 
 				myself.classId = DefaultAclRelationId;
-				myself.objectId = HeapTupleGetOid(newtuple);
+				myself.objectId = defAclOid;
 				myself.objectSubId = 0;
 
 				referenced.classId = NamespaceRelationId;
@@ -1366,17 +1376,15 @@ SetDefaultACL(InternalDefaultACL *iacls)
 		nnewmembers = aclmembers(new_acl, &newmembers);
 
 		updateAclDependencies(DefaultAclRelationId,
-							  HeapTupleGetOid(newtuple), 0,
+							  defAclOid, 0,
 							  iacls->roleid,
 							  noldmembers, oldmembers,
 							  nnewmembers, newmembers);
 
 		if (isNew)
-			InvokeObjectPostCreateHook(DefaultAclRelationId,
-									   HeapTupleGetOid(newtuple), 0);
+			InvokeObjectPostCreateHook(DefaultAclRelationId, defAclOid, 0);
 		else
-			InvokeObjectPostAlterHook(DefaultAclRelationId,
-									  HeapTupleGetOid(newtuple), 0);
+			InvokeObjectPostAlterHook(DefaultAclRelationId,  defAclOid, 0);
 	}
 
 	if (HeapTupleIsValid(tuple))
@@ -1407,7 +1415,7 @@ RemoveRoleFromObjectACL(Oid roleid, Oid classid, Oid objid)
 		rel = heap_open(DefaultAclRelationId, AccessShareLock);
 
 		ScanKeyInit(&skey[0],
-					ObjectIdAttributeNumber,
+					Anum_pg_default_acl_oid,
 					BTEqualStrategyNumber, F_OIDEQ,
 					ObjectIdGetDatum(objid));
 
@@ -1530,7 +1538,7 @@ RemoveDefaultACLById(Oid defaclOid)
 	rel = heap_open(DefaultAclRelationId, RowExclusiveLock);
 
 	ScanKeyInit(&skey[0],
-				ObjectIdAttributeNumber,
+				Anum_pg_default_acl_oid,
 				BTEqualStrategyNumber, F_OIDEQ,
 				ObjectIdGetDatum(defaclOid));
 
@@ -1608,10 +1616,6 @@ expand_all_col_privileges(Oid table_oid, Form_pg_class classForm,
 		if (curr_att == InvalidAttrNumber)
 			continue;
 
-		/* Skip OID column if it doesn't exist */
-		if (curr_att == ObjectIdAttributeNumber && !classForm->relhasoids)
-			continue;
-
 		/* Views don't have any system columns at all */
 		if (classForm->relkind == RELKIND_VIEW && curr_att < 0)
 			continue;
@@ -2223,7 +2227,7 @@ ExecGrant_Database(InternalGrant *istmt)
 		CatalogTupleUpdate(relation, &newtuple->t_self, newtuple);
 
 		/* Update the shared dependency ACL info */
-		updateAclDependencies(DatabaseRelationId, HeapTupleGetOid(tuple), 0,
+		updateAclDependencies(DatabaseRelationId, pg_database_tuple->oid, 0,
 							  ownerId,
 							  noldmembers, oldmembers,
 							  nnewmembers, newmembers);
@@ -2350,7 +2354,7 @@ ExecGrant_Fdw(InternalGrant *istmt)
 
 		/* Update the shared dependency ACL info */
 		updateAclDependencies(ForeignDataWrapperRelationId,
-							  HeapTupleGetOid(tuple), 0,
+							  pg_fdw_tuple->oid, 0,
 							  ownerId,
 							  noldmembers, oldmembers,
 							  nnewmembers, newmembers);
@@ -2475,7 +2479,7 @@ ExecGrant_ForeignServer(InternalGrant *istmt)
 
 		/* Update the shared dependency ACL info */
 		updateAclDependencies(ForeignServerRelationId,
-							  HeapTupleGetOid(tuple), 0,
+							  pg_server_tuple->oid, 0,
 							  ownerId,
 							  noldmembers, oldmembers,
 							  nnewmembers, newmembers);
@@ -2729,7 +2733,7 @@ ExecGrant_Language(InternalGrant *istmt)
 		recordExtensionInitPriv(langId, LanguageRelationId, 0, new_acl);
 
 		/* Update the shared dependency ACL info */
-		updateAclDependencies(LanguageRelationId, HeapTupleGetOid(tuple), 0,
+		updateAclDependencies(LanguageRelationId, pg_language_tuple->oid, 0,
 							  ownerId,
 							  noldmembers, oldmembers,
 							  nnewmembers, newmembers);
@@ -2784,7 +2788,7 @@ ExecGrant_Largeobject(InternalGrant *istmt)
 
 		/* There's no syscache for pg_largeobject_metadata */
 		ScanKeyInit(&entry[0],
-					ObjectIdAttributeNumber,
+					Anum_pg_largeobject_metadata_oid,
 					BTEqualStrategyNumber, F_OIDEQ,
 					ObjectIdGetDatum(loid));
 
@@ -2869,7 +2873,7 @@ ExecGrant_Largeobject(InternalGrant *istmt)
 
 		/* Update the shared dependency ACL info */
 		updateAclDependencies(LargeObjectRelationId,
-							  HeapTupleGetOid(tuple), 0,
+							  form_lo_meta->oid, 0,
 							  ownerId,
 							  noldmembers, oldmembers,
 							  nnewmembers, newmembers);
@@ -2993,7 +2997,7 @@ ExecGrant_Namespace(InternalGrant *istmt)
 		recordExtensionInitPriv(nspid, NamespaceRelationId, 0, new_acl);
 
 		/* Update the shared dependency ACL info */
-		updateAclDependencies(NamespaceRelationId, HeapTupleGetOid(tuple), 0,
+		updateAclDependencies(NamespaceRelationId, pg_namespace_tuple->oid, 0,
 							  ownerId,
 							  noldmembers, oldmembers,
 							  nnewmembers, newmembers);
@@ -4116,7 +4120,7 @@ pg_largeobject_aclmask_snapshot(Oid lobj_oid, Oid roleid,
 						   AccessShareLock);
 
 	ScanKeyInit(&entry[0],
-				ObjectIdAttributeNumber,
+				Anum_pg_largeobject_metadata_oid,
 				BTEqualStrategyNumber, F_OIDEQ,
 				ObjectIdGetDatum(lobj_oid));
 
@@ -4898,7 +4902,7 @@ pg_largeobject_ownercheck(Oid lobj_oid, Oid roleid)
 						   AccessShareLock);
 
 	ScanKeyInit(&entry[0],
-				ObjectIdAttributeNumber,
+				Anum_pg_largeobject_metadata_oid,
 				BTEqualStrategyNumber, F_OIDEQ,
 				ObjectIdGetDatum(lobj_oid));
 
@@ -5260,7 +5264,7 @@ pg_extension_ownercheck(Oid ext_oid, Oid roleid)
 	pg_extension = heap_open(ExtensionRelationId, AccessShareLock);
 
 	ScanKeyInit(&entry[0],
-				ObjectIdAttributeNumber,
+				Anum_pg_extension_oid,
 				BTEqualStrategyNumber, F_OIDEQ,
 				ObjectIdGetDatum(ext_oid));
 
@@ -5726,7 +5730,7 @@ recordExtObjInitPriv(Oid objoid, Oid classoid)
 
 		/* There's no syscache for pg_largeobject_metadata */
 		ScanKeyInit(&entry[0],
-					ObjectIdAttributeNumber,
+					Anum_pg_largeobject_metadata_oid,
 					BTEqualStrategyNumber, F_OIDEQ,
 					ObjectIdGetDatum(objoid));
 
diff --git a/src/backend/catalog/catalog.c b/src/backend/catalog/catalog.c
index 6061428bccd..cd8e0c7f524 100644
--- a/src/backend/catalog/catalog.c
+++ b/src/backend/catalog/catalog.c
@@ -21,6 +21,8 @@
 #include <unistd.h>
 
 #include "access/genam.h"
+#include "access/heapam.h"
+#include "access/htup_details.h"
 #include "access/sysattr.h"
 #include "access/transam.h"
 #include "catalog/catalog.h"
@@ -43,7 +45,9 @@
 #include "miscadmin.h"
 #include "storage/fd.h"
 #include "utils/fmgroids.h"
+#include "utils/fmgrprotos.h"
 #include "utils/rel.h"
+#include "utils/syscache.h"
 #include "utils/tqual.h"
 
 
@@ -275,19 +279,9 @@ IsSharedRelation(Oid relationId)
 	return false;
 }
 
-
 /*
- * GetNewOid
- *		Generate a new OID that is unique within the given relation.
- *
- * Caller must have a suitable lock on the relation.
- *
- * Uniqueness is promised only if the relation has a unique index on OID.
- * This is true for all system catalogs that have OIDs, but might not be
- * true for user tables.  Note that we are effectively assuming that the
- * table has a relatively small number of entries (much less than 2^32)
- * and there aren't very long runs of consecutive existing OIDs.  Again,
- * this is reasonable for system catalogs but less so for user tables.
+ * GetNewOidWithIndex
+ *		Generate a new OID that is unique within the system relation.
  *
  * Since the OID is not immediately inserted into the table, there is a
  * race condition here; but a problem could occur only if someone else
@@ -300,44 +294,11 @@ IsSharedRelation(Oid relationId)
  * of transient conflicts for as long as our own MVCC snapshots think a
  * recently-deleted row is live.  The risk is far higher when selecting TOAST
  * OIDs, because SnapshotToast considers dead rows as active indefinitely.)
- */
-Oid
-GetNewOid(Relation relation)
-{
-	Oid			oidIndex;
-
-	/* If relation doesn't have OIDs at all, caller is confused */
-	Assert(relation->rd_rel->relhasoids);
-
-	/* In bootstrap mode, we don't have any indexes to use */
-	if (IsBootstrapProcessingMode())
-		return GetNewObjectId();
-
-	/* The relcache will cache the identity of the OID index for us */
-	oidIndex = RelationGetOidIndex(relation);
-
-	/* If no OID index, just hand back the next OID counter value */
-	if (!OidIsValid(oidIndex))
-	{
-		/*
-		 * System catalogs that have OIDs should *always* have a unique OID
-		 * index; we should only take this path for user tables. Give a
-		 * warning if it looks like somebody forgot an index.
-		 */
-		if (IsSystemRelation(relation))
-			elog(WARNING, "generating possibly-non-unique OID for \"%s\"",
-				 RelationGetRelationName(relation));
-
-		return GetNewObjectId();
-	}
-
-	/* Otherwise, use the index to find a nonconflicting OID */
-	return GetNewOidWithIndex(relation, oidIndex, ObjectIdAttributeNumber);
-}
-
-/*
- * GetNewOidWithIndex
- *		Guts of GetNewOid: use the supplied index
+ *
+ * Note that we are effectively assuming that the table has a relatively small
+ * number of entries (much less than 2^32) and there aren't very long runs of
+ * consecutive existing OIDs.  This is a mostly reasonable assumption for
+ * system catalogs.
  *
  * This is exported separately because there are cases where we want to use
  * an index that will not be recognized by RelationGetOidIndex: TOAST tables
@@ -356,6 +317,13 @@ GetNewOidWithIndex(Relation relation, Oid indexId, AttrNumber oidcolumn)
 	ScanKeyData key;
 	bool		collides;
 
+	/* Only system relations are supported */
+	Assert(IsSystemRelation(relation));
+
+	/* In bootstrap mode, we don't have any indexes to use */
+	if (IsBootstrapProcessingMode())
+		return GetNewObjectId();
+
 	/*
 	 * We should never be asked to generate a new pg_type OID during
 	 * pg_upgrade; doing so would risk collisions with the OIDs it wants to
@@ -450,7 +418,8 @@ GetNewRelFileNode(Oid reltablespace, Relation pg_class, char relpersistence)
 
 		/* Generate the OID */
 		if (pg_class)
-			rnode.node.relNode = GetNewOid(pg_class);
+			rnode.node.relNode = GetNewOidWithIndex(pg_class, ClassOidIndexId,
+													Anum_pg_class_oid);
 		else
 			rnode.node.relNode = GetNewObjectId();
 
@@ -479,3 +448,82 @@ GetNewRelFileNode(Oid reltablespace, Relation pg_class, char relpersistence)
 
 	return rnode.node.relNode;
 }
+
+/*
+ * SQL callable interface for GetNewOidWithIndex().  Outside of initdb's
+ * direct insertions into catalog tables, and recovering from corruption, this
+ * should rarely be needed.
+ *
+ * Function is intentionally not documented in the user facing docs.
+ */
+Datum
+pg_nextoid(PG_FUNCTION_ARGS)
+{
+	Oid		reloid = PG_GETARG_OID(0);
+	Name	attname = PG_GETARG_NAME(1);
+	Oid		idxoid = PG_GETARG_OID(2);
+	Relation rel;
+	Relation idx;
+	HeapTuple atttuple;
+	Form_pg_attribute attform;
+	AttrNumber attno;
+	Oid		newoid;
+
+	/*
+	 * As this function is not intended to be used during normal running, and
+	 * only supports system catalogs (which'd require superuser permissions to
+	 * modify), just checking for superuser ought to not obstruct valid
+	 * usecases.
+	 */
+	if (!superuser())
+		ereport(ERROR,
+				(errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
+				 errmsg("must be superuser to call pg_nextoid")));
+
+	rel = heap_open(reloid, RowExclusiveLock);
+	idx = index_open(idxoid, RowExclusiveLock);
+
+	if (!IsSystemRelation(rel))
+		ereport(ERROR,
+				(errcode(ERRCODE_INVALID_PARAMETER_VALUE),
+				 errmsg("pg_nextoid() can only be used on system relation")));
+
+	if (idx->rd_index->indrelid != RelationGetRelid(rel))
+		ereport(ERROR,
+				(errcode(ERRCODE_INVALID_PARAMETER_VALUE),
+				 errmsg("index %s does not belong to table %s",
+						RelationGetRelationName(idx),
+						RelationGetRelationName(rel))));
+
+	atttuple = SearchSysCacheAttName(reloid, NameStr(*attname));
+	if (!HeapTupleIsValid(atttuple))
+		ereport(ERROR,
+				(errcode(ERRCODE_INVALID_PARAMETER_VALUE),
+				 errmsg("attribute %s does not exists",
+						NameStr(*attname))));
+
+	attform = ((Form_pg_attribute) GETSTRUCT(atttuple));
+	attno = attform->attnum;
+
+	if (attform->atttypid != OIDOID)
+		ereport(ERROR,
+				(errcode(ERRCODE_INVALID_PARAMETER_VALUE),
+				 errmsg("attribute %s is not of type oid",
+						NameStr(*attname))));
+
+	if (IndexRelationGetNumberOfKeyAttributes(idx) != 1 ||
+		idx->rd_index->indkey.values[0] != attno)
+		ereport(ERROR,
+				(errcode(ERRCODE_INVALID_PARAMETER_VALUE),
+				 errmsg("index %s is not the index for attribute %s",
+						RelationGetRelationName(idx),
+						NameStr(*attname))));
+
+	newoid = GetNewOidWithIndex(rel, idxoid, attno);
+
+	ReleaseSysCache(atttuple);
+	heap_close(rel, RowExclusiveLock);
+	index_close(idx, RowExclusiveLock);
+
+	return newoid;
+}
diff --git a/src/backend/catalog/genbki.pl b/src/backend/catalog/genbki.pl
index 649200260a4..9c56f386c42 100644
--- a/src/backend/catalog/genbki.pl
+++ b/src/backend/catalog/genbki.pl
@@ -133,9 +133,17 @@ foreach my $header (@input_files)
 # While duplicate OIDs would only cause a failure if they appear in
 # the same catalog, our project policy is that manually assigned OIDs
 # should be globally unique, to avoid confusion.
+#
+# Also use the loop to determine the maximum explicitly assigned oid
+# found in the data file, we'll use that for default oid assignments.
 my $found = 0;
+my $maxoid = 0;
 foreach my $oid (keys %oidcounts)
 {
+	if ($oid > $maxoid)
+	{
+		$maxoid = $oid;
+	}
 	next unless $oidcounts{$oid} > 1;
 	print STDERR "Duplicate OIDs detected:\n" if !$found;
 	print STDERR "$oid\n";
@@ -320,7 +328,6 @@ EOM
 	print $bki "create $catname $catalog->{relation_oid}"
 	  . $catalog->{shared_relation}
 	  . $catalog->{bootstrap}
-	  . $catalog->{without_oids}
 	  . $catalog->{rowtype_oid_clause};
 
 	my $first = 1;
@@ -392,8 +399,7 @@ EOM
 		foreach my $key (keys %bki_values)
 		{
 			next
-			  if $key eq "oid"
-			  || $key eq "oid_symbol"
+			  if $key eq "oid_symbol"
 			  || $key eq "array_type_oid"
 			  || $key eq "descr"
 			  || $key eq "autogenerated"
@@ -409,6 +415,13 @@ EOM
 			my $attname = $column->{name};
 			my $atttype = $column->{type};
 
+			# Assign oid if oid column exists and no explicit assignment in row
+			if ($attname eq "oid" and not defined $bki_values{$attname})
+			{
+				$bki_values{$attname} = $maxoid;
+				$maxoid++;
+			}
+
 			# Substitute constant values we acquired above.
 			# (It's intentional that this can apply to parts of a field).
 			$bki_values{$attname} =~ s/\bPGUID\b/$BOOTSTRAP_SUPERUSERID/g;
@@ -627,7 +640,6 @@ sub gen_pg_attribute
 			$attnum = 0;
 			my @SYS_ATTRS = (
 				{ name => 'ctid',     type => 'tid' },
-				{ name => 'oid',      type => 'oid' },
 				{ name => 'xmin',     type => 'xid' },
 				{ name => 'cmin',     type => 'cid' },
 				{ name => 'xmax',     type => 'xid' },
@@ -641,11 +653,6 @@ sub gen_pg_attribute
 				$row{attrelid}      = $table->{relation_oid};
 				$row{attstattarget} = '0';
 
-				# Omit the oid column if the catalog doesn't have them
-				next
-				  if $table->{without_oids}
-				  && $attr->{name} eq 'oid';
-
 				morph_row_for_pgattr(\%row, $schema, $attr, 1);
 				print_bki_insert(\%row, $schema);
 			}
diff --git a/src/backend/catalog/heap.c b/src/backend/catalog/heap.c
index bd4c439ef35..05cfaeec35f 100644
--- a/src/backend/catalog/heap.c
+++ b/src/backend/catalog/heap.c
@@ -159,20 +159,6 @@ static const FormData_pg_attribute a1 = {
 };
 
 static const FormData_pg_attribute a2 = {
-	.attname = {"oid"},
-	.atttypid = OIDOID,
-	.attlen = sizeof(Oid),
-	.attnum = ObjectIdAttributeNumber,
-	.attcacheoff = -1,
-	.atttypmod = -1,
-	.attbyval = true,
-	.attstorage = 'p',
-	.attalign = 'i',
-	.attnotnull = true,
-	.attislocal = true,
-};
-
-static const FormData_pg_attribute a3 = {
 	.attname = {"xmin"},
 	.atttypid = XIDOID,
 	.attlen = sizeof(TransactionId),
@@ -186,7 +172,7 @@ static const FormData_pg_attribute a3 = {
 	.attislocal = true,
 };
 
-static const FormData_pg_attribute a4 = {
+static const FormData_pg_attribute a3 = {
 	.attname = {"cmin"},
 	.atttypid = CIDOID,
 	.attlen = sizeof(CommandId),
@@ -200,7 +186,7 @@ static const FormData_pg_attribute a4 = {
 	.attislocal = true,
 };
 
-static const FormData_pg_attribute a5 = {
+static const FormData_pg_attribute a4 = {
 	.attname = {"xmax"},
 	.atttypid = XIDOID,
 	.attlen = sizeof(TransactionId),
@@ -214,7 +200,7 @@ static const FormData_pg_attribute a5 = {
 	.attislocal = true,
 };
 
-static const FormData_pg_attribute a6 = {
+static const FormData_pg_attribute a5 = {
 	.attname = {"cmax"},
 	.atttypid = CIDOID,
 	.attlen = sizeof(CommandId),
@@ -234,7 +220,7 @@ static const FormData_pg_attribute a6 = {
  * table of a particular class/type. In any case table is still the word
  * used in SQL.
  */
-static const FormData_pg_attribute a7 = {
+static const FormData_pg_attribute a6 = {
 	.attname = {"tableoid"},
 	.atttypid = OIDOID,
 	.attlen = sizeof(Oid),
@@ -248,7 +234,7 @@ static const FormData_pg_attribute a7 = {
 	.attislocal = true,
 };
 
-static const FormData_pg_attribute *SysAtt[] = {&a1, &a2, &a3, &a4, &a5, &a6, &a7};
+static const FormData_pg_attribute *SysAtt[] = {&a1, &a2, &a3, &a4, &a5, &a6};
 
 /*
  * This function returns a Form_pg_attribute pointer for a system attribute.
@@ -256,12 +242,10 @@ static const FormData_pg_attribute *SysAtt[] = {&a1, &a2, &a3, &a4, &a5, &a6, &a
  * happen if there's a problem upstream.
  */
 const FormData_pg_attribute *
-SystemAttributeDefinition(AttrNumber attno, bool relhasoids)
+SystemAttributeDefinition(AttrNumber attno)
 {
 	if (attno >= 0 || attno < -(int) lengthof(SysAtt))
 		elog(ERROR, "invalid system attribute number %d", attno);
-	if (attno == ObjectIdAttributeNumber && !relhasoids)
-		elog(ERROR, "invalid system attribute number %d", attno);
 	return SysAtt[-attno - 1];
 }
 
@@ -270,7 +254,7 @@ SystemAttributeDefinition(AttrNumber attno, bool relhasoids)
  * pointer for a prototype definition.  If not, return NULL.
  */
 const FormData_pg_attribute *
-SystemAttributeByName(const char *attname, bool relhasoids)
+SystemAttributeByName(const char *attname)
 {
 	int			j;
 
@@ -278,11 +262,8 @@ SystemAttributeByName(const char *attname, bool relhasoids)
 	{
 		const FormData_pg_attribute *att = SysAtt[j];
 
-		if (relhasoids || att->attnum != ObjectIdAttributeNumber)
-		{
-			if (strcmp(NameStr(att->attname), attname) == 0)
-				return att;
-		}
+		if (strcmp(NameStr(att->attname), attname) == 0)
+			return att;
 	}
 
 	return NULL;
@@ -501,8 +482,7 @@ CheckAttributeNamesTypes(TupleDesc tupdesc, char relkind,
 		{
 			Form_pg_attribute attr = TupleDescAttr(tupdesc, i);
 
-			if (SystemAttributeByName(NameStr(attr->attname),
-									  tupdesc->tdhasoid) != NULL)
+			if (SystemAttributeByName(NameStr(attr->attname)) != NULL)
 				ereport(ERROR,
 						(errcode(ERRCODE_DUPLICATE_COLUMN),
 						 errmsg("column name \"%s\" conflicts with a system column name",
@@ -725,9 +705,7 @@ InsertPgAttributeTuple(Relation pg_attribute_rel,
 static void
 AddNewAttributeTuples(Oid new_rel_oid,
 					  TupleDesc tupdesc,
-					  char relkind,
-					  bool oidislocal,
-					  int oidinhcount)
+					  char relkind)
 {
 	Form_pg_attribute attr;
 	int			i;
@@ -789,23 +767,11 @@ AddNewAttributeTuples(Oid new_rel_oid,
 		{
 			FormData_pg_attribute attStruct;
 
-			/* skip OID where appropriate */
-			if (!tupdesc->tdhasoid &&
-				SysAtt[i]->attnum == ObjectIdAttributeNumber)
-				continue;
-
 			memcpy(&attStruct, (char *) SysAtt[i], sizeof(FormData_pg_attribute));
 
 			/* Fill in the correct relation OID in the copied tuple */
 			attStruct.attrelid = new_rel_oid;
 
-			/* Fill in correct inheritance info for the OID column */
-			if (attStruct.attnum == ObjectIdAttributeNumber)
-			{
-				attStruct.attislocal = oidislocal;
-				attStruct.attinhcount = oidinhcount;
-			}
-
 			InsertPgAttributeTuple(rel, &attStruct, indstate);
 		}
 	}
@@ -847,6 +813,7 @@ InsertPgClassTuple(Relation pg_class_desc,
 	memset(values, 0, sizeof(values));
 	memset(nulls, false, sizeof(nulls));
 
+	values[Anum_pg_class_oid - 1] = ObjectIdGetDatum(new_rel_oid);
 	values[Anum_pg_class_relname - 1] = NameGetDatum(&rd_rel->relname);
 	values[Anum_pg_class_relnamespace - 1] = ObjectIdGetDatum(rd_rel->relnamespace);
 	values[Anum_pg_class_reltype - 1] = ObjectIdGetDatum(rd_rel->reltype);
@@ -865,7 +832,6 @@ InsertPgClassTuple(Relation pg_class_desc,
 	values[Anum_pg_class_relkind - 1] = CharGetDatum(rd_rel->relkind);
 	values[Anum_pg_class_relnatts - 1] = Int16GetDatum(rd_rel->relnatts);
 	values[Anum_pg_class_relchecks - 1] = Int16GetDatum(rd_rel->relchecks);
-	values[Anum_pg_class_relhasoids - 1] = BoolGetDatum(rd_rel->relhasoids);
 	values[Anum_pg_class_relhasrules - 1] = BoolGetDatum(rd_rel->relhasrules);
 	values[Anum_pg_class_relhastriggers - 1] = BoolGetDatum(rd_rel->relhastriggers);
 	values[Anum_pg_class_relrowsecurity - 1] = BoolGetDatum(rd_rel->relrowsecurity);
@@ -891,12 +857,6 @@ InsertPgClassTuple(Relation pg_class_desc,
 
 	tup = heap_form_tuple(RelationGetDescr(pg_class_desc), values, nulls);
 
-	/*
-	 * The new tuple must have the oid already chosen for the rel.  Sure would
-	 * be embarrassing to do this sort of thing in polite company.
-	 */
-	HeapTupleSetOid(tup, new_rel_oid);
-
 	/* finally insert the new tuple, update the indexes, and clean up */
 	CatalogTupleInsert(pg_class_desc, tup);
 
@@ -1071,8 +1031,6 @@ AddNewRelationType(const char *typeName,
  *	relpersistence: rel's persistence status (permanent, temp, or unlogged)
  *	shared_relation: true if it's to be a shared relation
  *	mapped_relation: true if the relation will use the relfilenode map
- *	oidislocal: true if oid column (if any) should be marked attislocal
- *	oidinhcount: attinhcount to assign to oid column (if any)
  *	oncommit: ON COMMIT marking (only relevant if it's a temp table)
  *	reloptions: reloptions in Datum form, or (Datum) 0 if none
  *	use_user_acl: true if should look for user-defined default permissions;
@@ -1100,8 +1058,6 @@ heap_create_with_catalog(const char *relname,
 						 char relpersistence,
 						 bool shared_relation,
 						 bool mapped_relation,
-						 bool oidislocal,
-						 int oidinhcount,
 						 OnCommitAction oncommit,
 						 Datum reloptions,
 						 bool use_user_acl,
@@ -1347,8 +1303,7 @@ heap_create_with_catalog(const char *relname,
 	/*
 	 * now add tuples to pg_attribute for the attributes in our new relation.
 	 */
-	AddNewAttributeTuples(relid, new_rel_desc->rd_att, relkind,
-						  oidislocal, oidinhcount);
+	AddNewAttributeTuples(relid, new_rel_desc->rd_att, relkind);
 
 	/*
 	 * Make a dependency link to force the relation to be deleted if its
@@ -1741,9 +1696,10 @@ RemoveAttrDefault(Oid relid, AttrNumber attnum,
 	while (HeapTupleIsValid(tuple = systable_getnext(scan)))
 	{
 		ObjectAddress object;
+		Form_pg_attrdef attrtuple = (Form_pg_attrdef) GETSTRUCT(tuple);
 
 		object.classId = AttrDefaultRelationId;
-		object.objectId = HeapTupleGetOid(tuple);
+		object.objectId = attrtuple->oid;
 		object.objectSubId = 0;
 
 		performDeletion(&object, behavior,
@@ -1784,7 +1740,7 @@ RemoveAttrDefaultById(Oid attrdefId)
 
 	/* Find the pg_attrdef tuple */
 	ScanKeyInit(&scankeys[0],
-				ObjectIdAttributeNumber,
+				Anum_pg_attrdef_oid,
 				BTEqualStrategyNumber, F_OIDEQ,
 				ObjectIdGetDatum(attrdefId));
 
@@ -2162,6 +2118,8 @@ StoreAttrDefault(Relation rel, AttrNumber attnum,
 	ObjectAddress colobject,
 				defobject;
 
+	adrel = heap_open(AttrDefaultRelationId, RowExclusiveLock);
+
 	/*
 	 * Flatten expression to string form for storage.
 	 */
@@ -2170,14 +2128,14 @@ StoreAttrDefault(Relation rel, AttrNumber attnum,
 	/*
 	 * Make the pg_attrdef entry.
 	 */
+	attrdefOid = GetNewOidWithIndex(adrel, AttrDefaultOidIndexId, Anum_pg_attrdef_oid);
+	values[Anum_pg_attrdef_oid - 1] = ObjectIdGetDatum(attrdefOid);
 	values[Anum_pg_attrdef_adrelid - 1] = RelationGetRelid(rel);
 	values[Anum_pg_attrdef_adnum - 1] = attnum;
 	values[Anum_pg_attrdef_adbin - 1] = CStringGetTextDatum(adbin);
 
-	adrel = heap_open(AttrDefaultRelationId, RowExclusiveLock);
-
 	tuple = heap_form_tuple(adrel->rd_att, values, nulls);
-	attrdefOid = CatalogTupleInsert(adrel, tuple);
+	CatalogTupleInsert(adrel, tuple);
 
 	defobject.classId = AttrDefaultRelationId;
 	defobject.objectId = attrdefOid;
diff --git a/src/backend/catalog/index.c b/src/backend/catalog/index.c
index 4088286151a..77fadb97d51 100644
--- a/src/backend/catalog/index.c
+++ b/src/backend/catalog/index.c
@@ -322,7 +322,7 @@ ConstructTupleDescriptor(Relation heapRelation,
 	/*
 	 * allocate the new tuple descriptor
 	 */
-	indexTupDesc = CreateTemplateTupleDesc(numatts, false);
+	indexTupDesc = CreateTemplateTupleDesc(numatts);
 
 	/*
 	 * Fill in the pg_attribute row.
@@ -356,11 +356,11 @@ ConstructTupleDescriptor(Relation heapRelation,
 
 			if (atnum < 0)
 			{
+				elog(ERROR, "ain't possible anymore no?");
 				/*
 				 * here we are indexing on a system attribute (-1...-n)
 				 */
-				from = SystemAttributeDefinition(atnum,
-												 heapRelation->rd_rel->relhasoids);
+				from = SystemAttributeDefinition(atnum);
 			}
 			else
 			{
@@ -945,7 +945,6 @@ index_create(Relation heapRelation,
 	 */
 	indexRelation->rd_rel->relowner = heapRelation->rd_rel->relowner;
 	indexRelation->rd_rel->relam = accessMethodObjectId;
-	indexRelation->rd_rel->relhasoids = false;
 	indexRelation->rd_rel->relispartition = OidIsValid(parentIndexRelid);
 
 	/*
@@ -2145,7 +2144,7 @@ index_update_stats(Relation rel,
 		ScanKeyData key[1];
 
 		ScanKeyInit(&key[0],
-					ObjectIdAttributeNumber,
+					Anum_pg_class_oid,
 					BTEqualStrategyNumber, F_OIDEQ,
 					ObjectIdGetDatum(relid));
 
diff --git a/src/backend/catalog/indexing.c b/src/backend/catalog/indexing.c
index daf7ae2eb2b..59723821d0b 100644
--- a/src/backend/catalog/indexing.c
+++ b/src/backend/catalog/indexing.c
@@ -159,20 +159,17 @@ CatalogIndexInsert(CatalogIndexState indstate, HeapTuple heapTuple)
  * and building the index info structures is moderately expensive.
  * (Use CatalogTupleInsertWithInfo in such cases.)
  */
-Oid
+void
 CatalogTupleInsert(Relation heapRel, HeapTuple tup)
 {
 	CatalogIndexState indstate;
-	Oid			oid;
 
 	indstate = CatalogOpenIndexes(heapRel);
 
-	oid = simple_heap_insert(heapRel, tup);
+	simple_heap_insert(heapRel, tup);
 
 	CatalogIndexInsert(indstate, tup);
 	CatalogCloseIndexes(indstate);
-
-	return oid;
 }
 
 /*
@@ -183,17 +180,13 @@ CatalogTupleInsert(Relation heapRel, HeapTuple tup)
  * might cache the CatalogIndexState data somewhere (perhaps in the relcache)
  * so that callers needn't trouble over this ... but we don't do so today.
  */
-Oid
+void
 CatalogTupleInsertWithInfo(Relation heapRel, HeapTuple tup,
 						   CatalogIndexState indstate)
 {
-	Oid			oid;
-
-	oid = simple_heap_insert(heapRel, tup);
+	simple_heap_insert(heapRel, tup);
 
 	CatalogIndexInsert(indstate, tup);
-
-	return oid;
 }
 
 /*
diff --git a/src/backend/catalog/information_schema.sql b/src/backend/catalog/information_schema.sql
index f4e69f4a264..a3479afa104 100644
--- a/src/backend/catalog/information_schema.sql
+++ b/src/backend/catalog/information_schema.sql
@@ -1583,7 +1583,7 @@ CREATE TABLE sql_features (
     is_supported        yes_or_no,
     is_verified_by      character_data,
     comments            character_data
-) WITHOUT OIDS;
+);
 
 -- Will be filled with external data by initdb.
 
@@ -1604,7 +1604,7 @@ CREATE TABLE sql_implementation_info (
     integer_value               cardinal_number,
     character_value             character_data,
     comments                    character_data
-) WITHOUT OIDS;
+);
 
 INSERT INTO sql_implementation_info VALUES ('10003', 'CATALOG NAME', NULL, 'Y', NULL);
 INSERT INTO sql_implementation_info VALUES ('10004', 'COLLATING SEQUENCE', NULL, (SELECT default_collate_name FROM character_sets), NULL);
@@ -1635,7 +1635,7 @@ CREATE TABLE sql_languages (
     sql_language_implementation character_data,
     sql_language_binding_style  character_data,
     sql_language_programming_language character_data
-) WITHOUT OIDS;
+);
 
 INSERT INTO sql_languages VALUES ('ISO 9075', '1999', 'CORE', NULL, NULL, 'DIRECT', NULL);
 INSERT INTO sql_languages VALUES ('ISO 9075', '1999', 'CORE', NULL, NULL, 'EMBEDDED', 'C');
@@ -1656,7 +1656,7 @@ CREATE TABLE sql_packages (
     is_supported    yes_or_no,
     is_verified_by  character_data,
     comments        character_data
-) WITHOUT OIDS;
+);
 
 INSERT INTO sql_packages VALUES ('PKG000', 'Core', 'NO', NULL, '');
 INSERT INTO sql_packages VALUES ('PKG001', 'Enhanced datetime facilities', 'YES', NULL, '');
@@ -1683,7 +1683,7 @@ CREATE TABLE sql_parts (
     is_supported    yes_or_no,
     is_verified_by  character_data,
     comments        character_data
-) WITHOUT OIDS;
+);
 
 INSERT INTO sql_parts VALUES ('1', 'Framework (SQL/Framework)', 'NO', NULL, '');
 INSERT INTO sql_parts VALUES ('2', 'Foundation (SQL/Foundation)', 'NO', NULL, '');
@@ -1708,7 +1708,7 @@ CREATE TABLE sql_sizing (
     sizing_name     character_data,
     supported_value cardinal_number,
     comments        character_data
-) WITHOUT OIDS;
+);
 
 INSERT INTO sql_sizing VALUES (34,    'MAXIMUM CATALOG NAME LENGTH', 63, NULL);
 INSERT INTO sql_sizing VALUES (30,    'MAXIMUM COLUMN NAME LENGTH', 63, NULL);
@@ -1757,7 +1757,7 @@ CREATE TABLE sql_sizing_profiles (
     profile_id      character_data,
     required_value  cardinal_number,
     comments        character_data
-) WITHOUT OIDS;
+);
 
 GRANT SELECT ON sql_sizing_profiles TO PUBLIC;
 
diff --git a/src/backend/catalog/namespace.c b/src/backend/catalog/namespace.c
index 5d13e6a3d70..bdd0c042981 100644
--- a/src/backend/catalog/namespace.c
+++ b/src/backend/catalog/namespace.c
@@ -1084,7 +1084,7 @@ FuncnameGetCandidates(List *names, int nargs, List *argnames,
 			palloc(offsetof(struct _FuncCandidateList, args) +
 				   effective_nargs * sizeof(Oid));
 		newResult->pathpos = pathpos;
-		newResult->oid = HeapTupleGetOid(proctup);
+		newResult->oid = procform->oid;
 		newResult->nargs = effective_nargs;
 		newResult->argnumbers = argnumbers;
 		if (argnumbers)
@@ -1488,7 +1488,8 @@ OpernameGetOprid(List *names, Oid oprleft, Oid oprright)
 									  ObjectIdGetDatum(namespaceId));
 			if (HeapTupleIsValid(opertup))
 			{
-				Oid			result = HeapTupleGetOid(opertup);
+				Form_pg_operator operclass = (Form_pg_operator) GETSTRUCT(opertup);
+				Oid			result = operclass->oid;
 
 				ReleaseSysCache(opertup);
 				return result;
@@ -1533,7 +1534,7 @@ OpernameGetOprid(List *names, Oid oprleft, Oid oprright)
 
 			if (operform->oprnamespace == namespaceId)
 			{
-				Oid			result = HeapTupleGetOid(opertup);
+				Oid			result = operform->oid;
 
 				ReleaseSysCacheList(catlist);
 				return result;
@@ -1687,7 +1688,7 @@ OpernameGetCandidates(List *names, char oprkind, bool missing_schema_ok)
 						continue;	/* keep previous result */
 					/* replace previous result */
 					prevResult->pathpos = pathpos;
-					prevResult->oid = HeapTupleGetOid(opertup);
+					prevResult->oid = operform->oid;
 					continue;	/* args are same, of course */
 				}
 			}
@@ -1700,7 +1701,7 @@ OpernameGetCandidates(List *names, char oprkind, bool missing_schema_ok)
 		nextResult += SPACE_PER_OP;
 
 		newResult->pathpos = pathpos;
-		newResult->oid = HeapTupleGetOid(opertup);
+		newResult->oid = operform->oid;
 		newResult->nargs = 2;
 		newResult->nvargs = 0;
 		newResult->ndargs = 0;
@@ -1969,13 +1970,13 @@ lookup_collation(const char *collname, Oid collnamespace, int32 encoding)
 	if (collform->collprovider == COLLPROVIDER_ICU)
 	{
 		if (is_encoding_supported_by_icu(encoding))
-			collid = HeapTupleGetOid(colltup);
+			collid = collform->oid;
 		else
 			collid = InvalidOid;
 	}
 	else
 	{
-		collid = HeapTupleGetOid(colltup);
+		collid = collform->oid;
 	}
 	ReleaseSysCache(colltup);
 	return collid;
diff --git a/src/backend/catalog/objectaddress.c b/src/backend/catalog/objectaddress.c
index 593e6f7022d..5288d8e911a 100644
--- a/src/backend/catalog/objectaddress.c
+++ b/src/backend/catalog/objectaddress.c
@@ -27,6 +27,7 @@
 #include "catalog/pg_authid.h"
 #include "catalog/pg_cast.h"
 #include "catalog/pg_default_acl.h"
+#include "catalog/pg_enum.h"
 #include "catalog/pg_event_trigger.h"
 #include "catalog/pg_collation.h"
 #include "catalog/pg_constraint.h"
@@ -94,6 +95,7 @@
 typedef struct
 {
 	Oid			class_oid;		/* oid of catalog */
+	AttrNumber	attnum_oid;		/* attribute number of oid column */
 	Oid			oid_index_oid;	/* oid of index on system oid column */
 	int			oid_catcache_id;	/* id of catcache on system oid column	*/
 	int			name_catcache_id;	/* id of catcache on (name,namespace), or
@@ -114,6 +116,7 @@ static const ObjectPropertyType ObjectProperty[] =
 {
 	{
 		AccessMethodRelationId,
+		Anum_pg_am_oid,
 		AmOidIndexId,
 		AMOID,
 		AMNAME,
@@ -126,6 +129,7 @@ static const ObjectPropertyType ObjectProperty[] =
 	},
 	{
 		CastRelationId,
+		Anum_pg_cast_oid,
 		CastOidIndexId,
 		-1,
 		-1,
@@ -138,6 +142,7 @@ static const ObjectPropertyType ObjectProperty[] =
 	},
 	{
 		CollationRelationId,
+		Anum_pg_collation_oid,
 		CollationOidIndexId,
 		COLLOID,
 		-1,						/* COLLNAMEENCNSP also takes encoding */
@@ -150,6 +155,7 @@ static const ObjectPropertyType ObjectProperty[] =
 	},
 	{
 		ConstraintRelationId,
+		Anum_pg_constraint_oid,
 		ConstraintOidIndexId,
 		CONSTROID,
 		-1,
@@ -162,6 +168,7 @@ static const ObjectPropertyType ObjectProperty[] =
 	},
 	{
 		ConversionRelationId,
+		Anum_pg_conversion_oid,
 		ConversionOidIndexId,
 		CONVOID,
 		CONNAMENSP,
@@ -174,6 +181,7 @@ static const ObjectPropertyType ObjectProperty[] =
 	},
 	{
 		DatabaseRelationId,
+		Anum_pg_database_oid,
 		DatabaseOidIndexId,
 		DATABASEOID,
 		-1,
@@ -186,6 +194,7 @@ static const ObjectPropertyType ObjectProperty[] =
 	},
 	{
 		ExtensionRelationId,
+		Anum_pg_extension_oid,
 		ExtensionOidIndexId,
 		-1,
 		-1,
@@ -198,6 +207,7 @@ static const ObjectPropertyType ObjectProperty[] =
 	},
 	{
 		ForeignDataWrapperRelationId,
+		Anum_pg_foreign_data_wrapper_oid,
 		ForeignDataWrapperOidIndexId,
 		FOREIGNDATAWRAPPEROID,
 		FOREIGNDATAWRAPPERNAME,
@@ -210,6 +220,7 @@ static const ObjectPropertyType ObjectProperty[] =
 	},
 	{
 		ForeignServerRelationId,
+		Anum_pg_foreign_server_oid,
 		ForeignServerOidIndexId,
 		FOREIGNSERVEROID,
 		FOREIGNSERVERNAME,
@@ -222,6 +233,7 @@ static const ObjectPropertyType ObjectProperty[] =
 	},
 	{
 		ProcedureRelationId,
+		Anum_pg_proc_oid,
 		ProcedureOidIndexId,
 		PROCOID,
 		-1,						/* PROCNAMEARGSNSP also takes argument types */
@@ -234,6 +246,7 @@ static const ObjectPropertyType ObjectProperty[] =
 	},
 	{
 		LanguageRelationId,
+		Anum_pg_language_oid,
 		LanguageOidIndexId,
 		LANGOID,
 		LANGNAME,
@@ -246,6 +259,7 @@ static const ObjectPropertyType ObjectProperty[] =
 	},
 	{
 		LargeObjectMetadataRelationId,
+		Anum_pg_largeobject_metadata_oid,
 		LargeObjectMetadataOidIndexId,
 		-1,
 		-1,
@@ -258,6 +272,7 @@ static const ObjectPropertyType ObjectProperty[] =
 	},
 	{
 		OperatorClassRelationId,
+		Anum_pg_opclass_oid,
 		OpclassOidIndexId,
 		CLAOID,
 		-1,						/* CLAAMNAMENSP also takes opcmethod */
@@ -270,6 +285,7 @@ static const ObjectPropertyType ObjectProperty[] =
 	},
 	{
 		OperatorRelationId,
+		Anum_pg_operator_oid,
 		OperatorOidIndexId,
 		OPEROID,
 		-1,						/* OPERNAMENSP also takes left and right type */
@@ -282,6 +298,7 @@ static const ObjectPropertyType ObjectProperty[] =
 	},
 	{
 		OperatorFamilyRelationId,
+		Anum_pg_opfamily_oid,
 		OpfamilyOidIndexId,
 		OPFAMILYOID,
 		-1,						/* OPFAMILYAMNAMENSP also takes opfmethod */
@@ -294,6 +311,7 @@ static const ObjectPropertyType ObjectProperty[] =
 	},
 	{
 		AuthIdRelationId,
+		Anum_pg_authid_oid,
 		AuthIdOidIndexId,
 		AUTHOID,
 		AUTHNAME,
@@ -306,6 +324,7 @@ static const ObjectPropertyType ObjectProperty[] =
 	},
 	{
 		RewriteRelationId,
+		Anum_pg_rewrite_oid,
 		RewriteOidIndexId,
 		-1,
 		-1,
@@ -318,6 +337,7 @@ static const ObjectPropertyType ObjectProperty[] =
 	},
 	{
 		NamespaceRelationId,
+		Anum_pg_namespace_oid,
 		NamespaceOidIndexId,
 		NAMESPACEOID,
 		NAMESPACENAME,
@@ -330,6 +350,7 @@ static const ObjectPropertyType ObjectProperty[] =
 	},
 	{
 		RelationRelationId,
+		Anum_pg_class_oid,
 		ClassOidIndexId,
 		RELOID,
 		RELNAMENSP,
@@ -342,6 +363,7 @@ static const ObjectPropertyType ObjectProperty[] =
 	},
 	{
 		TableSpaceRelationId,
+		Anum_pg_tablespace_oid,
 		TablespaceOidIndexId,
 		TABLESPACEOID,
 		-1,
@@ -354,12 +376,14 @@ static const ObjectPropertyType ObjectProperty[] =
 	},
 	{
 		TransformRelationId,
+		Anum_pg_transform_oid,
 		TransformOidIndexId,
 		TRFOID,
 		InvalidAttrNumber
 	},
 	{
 		TriggerRelationId,
+		Anum_pg_trigger_oid,
 		TriggerOidIndexId,
 		-1,
 		-1,
@@ -372,6 +396,7 @@ static const ObjectPropertyType ObjectProperty[] =
 	},
 	{
 		PolicyRelationId,
+		Anum_pg_policy_oid,
 		PolicyOidIndexId,
 		-1,
 		-1,
@@ -384,6 +409,7 @@ static const ObjectPropertyType ObjectProperty[] =
 	},
 	{
 		EventTriggerRelationId,
+		Anum_pg_event_trigger_oid,
 		EventTriggerOidIndexId,
 		EVENTTRIGGEROID,
 		EVENTTRIGGERNAME,
@@ -396,6 +422,7 @@ static const ObjectPropertyType ObjectProperty[] =
 	},
 	{
 		TSConfigRelationId,
+		Anum_pg_ts_config_oid,
 		TSConfigOidIndexId,
 		TSCONFIGOID,
 		TSCONFIGNAMENSP,
@@ -408,6 +435,7 @@ static const ObjectPropertyType ObjectProperty[] =
 	},
 	{
 		TSDictionaryRelationId,
+		Anum_pg_ts_dict_oid,
 		TSDictionaryOidIndexId,
 		TSDICTOID,
 		TSDICTNAMENSP,
@@ -420,6 +448,7 @@ static const ObjectPropertyType ObjectProperty[] =
 	},
 	{
 		TSParserRelationId,
+		Anum_pg_ts_parser_oid,
 		TSParserOidIndexId,
 		TSPARSEROID,
 		TSPARSERNAMENSP,
@@ -432,6 +461,7 @@ static const ObjectPropertyType ObjectProperty[] =
 	},
 	{
 		TSTemplateRelationId,
+		Anum_pg_ts_template_oid,
 		TSTemplateOidIndexId,
 		TSTEMPLATEOID,
 		TSTEMPLATENAMENSP,
@@ -444,6 +474,7 @@ static const ObjectPropertyType ObjectProperty[] =
 	},
 	{
 		TypeRelationId,
+		Anum_pg_type_oid,
 		TypeOidIndexId,
 		TYPEOID,
 		TYPENAMENSP,
@@ -456,6 +487,7 @@ static const ObjectPropertyType ObjectProperty[] =
 	},
 	{
 		PublicationRelationId,
+		Anum_pg_publication_oid,
 		PublicationObjectIndexId,
 		PUBLICATIONOID,
 		PUBLICATIONNAME,
@@ -468,6 +500,7 @@ static const ObjectPropertyType ObjectProperty[] =
 	},
 	{
 		SubscriptionRelationId,
+		Anum_pg_subscription_oid,
 		SubscriptionObjectIndexId,
 		SUBSCRIPTIONOID,
 		SUBSCRIPTIONNAME,
@@ -480,6 +513,7 @@ static const ObjectPropertyType ObjectProperty[] =
 	},
 	{
 		StatisticExtRelationId,
+		Anum_pg_statistic_ext_oid,
 		StatisticExtOidIndexId,
 		STATEXTOID,
 		STATEXTNAMENSP,
@@ -1459,7 +1493,11 @@ get_object_address_attrdef(ObjectType objtype, List *object,
 		scan = systable_beginscan(attrdef, AttrDefaultIndexId, true,
 								  NULL, 2, keys);
 		if (HeapTupleIsValid(tup = systable_getnext(scan)))
-			defoid = HeapTupleGetOid(tup);
+		{
+			Form_pg_attrdef atdform = (Form_pg_attrdef) GETSTRUCT(tup);
+
+			defoid = atdform->oid;
+		}
 
 		systable_endscan(scan);
 		relation_close(attrdef, AccessShareLock);
@@ -1633,7 +1671,7 @@ get_object_address_opf_member(ObjectType objtype,
 				}
 				else
 				{
-					address.objectId = HeapTupleGetOid(tp);
+					address.objectId = ((Form_pg_amop) GETSTRUCT(tp))->oid;
 					ReleaseSysCache(tp);
 				}
 			}
@@ -1664,7 +1702,7 @@ get_object_address_opf_member(ObjectType objtype,
 				}
 				else
 				{
-					address.objectId = HeapTupleGetOid(tp);
+					address.objectId = ((Form_pg_amproc) GETSTRUCT(tp))->oid;
 					ReleaseSysCache(tp);
 				}
 			}
@@ -1711,7 +1749,7 @@ get_object_address_usermapping(List *object, bool missing_ok)
 								username, servername)));
 			return address;
 		}
-		userid = HeapTupleGetOid(tp);
+		userid = ((Form_pg_authid) GETSTRUCT(tp))->oid;
 		ReleaseSysCache(tp);
 	}
 
@@ -1738,7 +1776,7 @@ get_object_address_usermapping(List *object, bool missing_ok)
 		return address;
 	}
 
-	address.objectId = HeapTupleGetOid(tp);
+	address.objectId = ((Form_pg_user_mapping) GETSTRUCT(tp))->oid;
 
 	ReleaseSysCache(tp);
 
@@ -1868,7 +1906,7 @@ get_object_address_defacl(List *object, bool missing_ok)
 						 CStringGetDatum(username));
 	if (!HeapTupleIsValid(tp))
 		goto not_found;
-	userid = HeapTupleGetOid(tp);
+	userid = ((Form_pg_authid) GETSTRUCT(tp))->oid;
 	ReleaseSysCache(tp);
 
 	/*
@@ -1892,7 +1930,7 @@ get_object_address_defacl(List *object, bool missing_ok)
 	if (!HeapTupleIsValid(tp))
 		goto not_found;
 
-	address.objectId = HeapTupleGetOid(tp);
+	address.objectId = ((Form_pg_default_acl) GETSTRUCT(tp))->oid;
 	ReleaseSysCache(tp);
 
 	return address;
@@ -2202,7 +2240,7 @@ pg_get_object_address(PG_FUNCTION_ARGS)
 	if (relation)
 		relation_close(relation, AccessShareLock);
 
-	tupdesc = CreateTemplateTupleDesc(3, false);
+	tupdesc = CreateTemplateTupleDesc(3);
 	TupleDescInitEntry(tupdesc, (AttrNumber) 1, "classid",
 					   OIDOID, -1, 0);
 	TupleDescInitEntry(tupdesc, (AttrNumber) 2, "objid",
@@ -2486,6 +2524,14 @@ read_objtype_from_string(const char *objtype)
 /*
  * Interfaces to reference fields of ObjectPropertyType
  */
+AttrNumber
+get_object_attnum_oid(Oid class_id)
+{
+	const ObjectPropertyType *prop = get_object_property_data(class_id);
+
+	return prop->attnum_oid;
+}
+
 Oid
 get_object_oid_index(Oid class_id)
 {
@@ -2625,7 +2671,7 @@ get_object_property_data(Oid class_id)
  * We try a syscache first, if available.
  */
 HeapTuple
-get_catalog_object_by_oid(Relation catalog, Oid objectId)
+get_catalog_object_by_oid(Relation catalog, AttrNumber oidcol, Oid objectId)
 {
 	HeapTuple	tuple;
 	Oid			classId = RelationGetRelid(catalog);
@@ -2646,7 +2692,7 @@ get_catalog_object_by_oid(Relation catalog, Oid objectId)
 		Assert(OidIsValid(oidIndexId));
 
 		ScanKeyInit(&skey,
-					ObjectIdAttributeNumber,
+					oidcol,
 					BTEqualStrategyNumber, F_OIDEQ,
 					ObjectIdGetDatum(objectId));
 
@@ -2721,7 +2767,7 @@ getObjectDescription(const ObjectAddress *object)
 				castDesc = heap_open(CastRelationId, AccessShareLock);
 
 				ScanKeyInit(&skey[0],
-							ObjectIdAttributeNumber,
+							Anum_pg_cast_oid,
 							BTEqualStrategyNumber, F_OIDEQ,
 							ObjectIdGetDatum(object->objectId));
 
@@ -2842,7 +2888,7 @@ getObjectDescription(const ObjectAddress *object)
 				attrdefDesc = heap_open(AttrDefaultRelationId, AccessShareLock);
 
 				ScanKeyInit(&skey[0],
-							ObjectIdAttributeNumber,
+							Anum_pg_attrdef_oid,
 							BTEqualStrategyNumber, F_OIDEQ,
 							ObjectIdGetDatum(object->objectId));
 
@@ -2955,7 +3001,7 @@ getObjectDescription(const ObjectAddress *object)
 									 AccessShareLock);
 
 				ScanKeyInit(&skey[0],
-							ObjectIdAttributeNumber,
+							Anum_pg_amop_oid,
 							BTEqualStrategyNumber, F_OIDEQ,
 							ObjectIdGetDatum(object->objectId));
 
@@ -3005,7 +3051,7 @@ getObjectDescription(const ObjectAddress *object)
 									   AccessShareLock);
 
 				ScanKeyInit(&skey[0],
-							ObjectIdAttributeNumber,
+							Anum_pg_amproc_oid,
 							BTEqualStrategyNumber, F_OIDEQ,
 							ObjectIdGetDatum(object->objectId));
 
@@ -3054,7 +3100,7 @@ getObjectDescription(const ObjectAddress *object)
 				ruleDesc = heap_open(RewriteRelationId, AccessShareLock);
 
 				ScanKeyInit(&skey[0],
-							ObjectIdAttributeNumber,
+							Anum_pg_rewrite_oid,
 							BTEqualStrategyNumber, F_OIDEQ,
 							ObjectIdGetDatum(object->objectId));
 
@@ -3092,7 +3138,7 @@ getObjectDescription(const ObjectAddress *object)
 				trigDesc = heap_open(TriggerRelationId, AccessShareLock);
 
 				ScanKeyInit(&skey[0],
-							ObjectIdAttributeNumber,
+							Anum_pg_trigger_oid,
 							BTEqualStrategyNumber, F_OIDEQ,
 							ObjectIdGetDatum(object->objectId));
 
@@ -3352,7 +3398,7 @@ getObjectDescription(const ObjectAddress *object)
 				defaclrel = heap_open(DefaultAclRelationId, AccessShareLock);
 
 				ScanKeyInit(&skey[0],
-							ObjectIdAttributeNumber,
+							Anum_pg_default_acl_oid,
 							BTEqualStrategyNumber, F_OIDEQ,
 							ObjectIdGetDatum(object->objectId));
 
@@ -3479,7 +3525,7 @@ getObjectDescription(const ObjectAddress *object)
 				policy_rel = heap_open(PolicyRelationId, AccessShareLock);
 
 				ScanKeyInit(&skey[0],
-							ObjectIdAttributeNumber,
+							Anum_pg_policy_oid,
 							BTEqualStrategyNumber, F_OIDEQ,
 							ObjectIdGetDatum(object->objectId));
 
@@ -3753,7 +3799,7 @@ pg_identify_object(PG_FUNCTION_ARGS)
 	 * Construct a tuple descriptor for the result row.  This must match this
 	 * function's pg_proc entry!
 	 */
-	tupdesc = CreateTemplateTupleDesc(4, false);
+	tupdesc = CreateTemplateTupleDesc(4);
 	TupleDescInitEntry(tupdesc, (AttrNumber) 1, "type",
 					   TEXTOID, -1, 0);
 	TupleDescInitEntry(tupdesc, (AttrNumber) 2, "schema",
@@ -3770,7 +3816,9 @@ pg_identify_object(PG_FUNCTION_ARGS)
 		HeapTuple	objtup;
 		Relation	catalog = heap_open(address.classId, AccessShareLock);
 
-		objtup = get_catalog_object_by_oid(catalog, address.objectId);
+		objtup = get_catalog_object_by_oid(catalog,
+										   get_object_attnum_oid(address.classId),
+										   address.objectId);
 		if (objtup != NULL)
 		{
 			bool		isnull;
@@ -3870,7 +3918,7 @@ pg_identify_object_as_address(PG_FUNCTION_ARGS)
 	 * Construct a tuple descriptor for the result row.  This must match this
 	 * function's pg_proc entry!
 	 */
-	tupdesc = CreateTemplateTupleDesc(3, false);
+	tupdesc = CreateTemplateTupleDesc(3);
 	TupleDescInitEntry(tupdesc, (AttrNumber) 1, "type",
 					   TEXTOID, -1, 0);
 	TupleDescInitEntry(tupdesc, (AttrNumber) 2, "object_names",
@@ -4147,7 +4195,7 @@ getConstraintTypeDescription(StringInfo buffer, Oid constroid)
 	Form_pg_constraint constrForm;
 
 	constrRel = heap_open(ConstraintRelationId, AccessShareLock);
-	constrTup = get_catalog_object_by_oid(constrRel, constroid);
+	constrTup = get_catalog_object_by_oid(constrRel, Anum_pg_constraint_oid, constroid);
 	if (!HeapTupleIsValid(constrTup))
 		elog(ERROR, "cache lookup failed for constraint %u", constroid);
 
@@ -4158,7 +4206,7 @@ getConstraintTypeDescription(StringInfo buffer, Oid constroid)
 	else if (OidIsValid(constrForm->contypid))
 		appendStringInfoString(buffer, "domain constraint");
 	else
-		elog(ERROR, "invalid constraint %u", HeapTupleGetOid(constrTup));
+		elog(ERROR, "invalid constraint %u", constrForm->oid);
 
 	heap_close(constrRel, AccessShareLock);
 }
@@ -4271,7 +4319,7 @@ getObjectIdentityParts(const ObjectAddress *object,
 
 				castRel = heap_open(CastRelationId, AccessShareLock);
 
-				tup = get_catalog_object_by_oid(castRel, object->objectId);
+				tup = get_catalog_object_by_oid(castRel, Anum_pg_cast_oid, object->objectId);
 
 				if (!HeapTupleIsValid(tup))
 					elog(ERROR, "could not find tuple for cast %u",
@@ -4393,7 +4441,7 @@ getObjectIdentityParts(const ObjectAddress *object,
 				attrdefDesc = heap_open(AttrDefaultRelationId, AccessShareLock);
 
 				ScanKeyInit(&skey[0],
-							ObjectIdAttributeNumber,
+							Anum_pg_attrdef_oid,
 							BTEqualStrategyNumber, F_OIDEQ,
 							ObjectIdGetDatum(object->objectId));
 
@@ -4523,7 +4571,7 @@ getObjectIdentityParts(const ObjectAddress *object,
 									 AccessShareLock);
 
 				ScanKeyInit(&skey[0],
-							ObjectIdAttributeNumber,
+							Anum_pg_amop_oid,
 							BTEqualStrategyNumber, F_OIDEQ,
 							ObjectIdGetDatum(object->objectId));
 
@@ -4577,7 +4625,7 @@ getObjectIdentityParts(const ObjectAddress *object,
 									   AccessShareLock);
 
 				ScanKeyInit(&skey[0],
-							ObjectIdAttributeNumber,
+							Anum_pg_amproc_oid,
 							BTEqualStrategyNumber, F_OIDEQ,
 							ObjectIdGetDatum(object->objectId));
 
@@ -4624,7 +4672,7 @@ getObjectIdentityParts(const ObjectAddress *object,
 
 				ruleDesc = heap_open(RewriteRelationId, AccessShareLock);
 
-				tup = get_catalog_object_by_oid(ruleDesc, object->objectId);
+				tup = get_catalog_object_by_oid(ruleDesc, Anum_pg_rewrite_oid, object->objectId);
 
 				if (!HeapTupleIsValid(tup))
 					elog(ERROR, "could not find tuple for rule %u",
@@ -4650,7 +4698,7 @@ getObjectIdentityParts(const ObjectAddress *object,
 
 				trigDesc = heap_open(TriggerRelationId, AccessShareLock);
 
-				tup = get_catalog_object_by_oid(trigDesc, object->objectId);
+				tup = get_catalog_object_by_oid(trigDesc, Anum_pg_trigger_oid, object->objectId);
 
 				if (!HeapTupleIsValid(tup))
 					elog(ERROR, "could not find tuple for trigger %u",
@@ -4912,7 +4960,7 @@ getObjectIdentityParts(const ObjectAddress *object,
 				defaclrel = heap_open(DefaultAclRelationId, AccessShareLock);
 
 				ScanKeyInit(&skey[0],
-							ObjectIdAttributeNumber,
+							Anum_pg_default_acl_oid,
 							BTEqualStrategyNumber, F_OIDEQ,
 							ObjectIdGetDatum(object->objectId));
 
@@ -5022,7 +5070,7 @@ getObjectIdentityParts(const ObjectAddress *object,
 
 				polDesc = heap_open(PolicyRelationId, AccessShareLock);
 
-				tup = get_catalog_object_by_oid(polDesc, object->objectId);
+				tup = get_catalog_object_by_oid(polDesc, Anum_pg_policy_oid, object->objectId);
 
 				if (!HeapTupleIsValid(tup))
 					elog(ERROR, "could not find tuple for policy %u",
@@ -5099,7 +5147,7 @@ getObjectIdentityParts(const ObjectAddress *object,
 
 				transformDesc = heap_open(TransformRelationId, AccessShareLock);
 
-				tup = get_catalog_object_by_oid(transformDesc, object->objectId);
+				tup = get_catalog_object_by_oid(transformDesc, Anum_pg_transform_oid, object->objectId);
 
 				if (!HeapTupleIsValid(tup))
 					elog(ERROR, "could not find tuple for transform %u",
diff --git a/src/backend/catalog/pg_aggregate.c b/src/backend/catalog/pg_aggregate.c
index 246776093ec..4b12e9f2748 100644
--- a/src/backend/catalog/pg_aggregate.c
+++ b/src/backend/catalog/pg_aggregate.c
@@ -639,6 +639,8 @@ AggregateCreate(const char *aggName,
 	/*
 	 * Okay to create the pg_aggregate entry.
 	 */
+	aggdesc = heap_open(AggregateRelationId, RowExclusiveLock);
+	tupDesc = aggdesc->rd_att;
 
 	/* initialize nulls and values */
 	for (i = 0; i < Natts_pg_aggregate; i++)
@@ -675,9 +677,6 @@ AggregateCreate(const char *aggName,
 	else
 		nulls[Anum_pg_aggregate_aggminitval - 1] = true;
 
-	aggdesc = heap_open(AggregateRelationId, RowExclusiveLock);
-	tupDesc = aggdesc->rd_att;
-
 	tup = heap_form_tuple(tupDesc, values, nulls);
 	CatalogTupleInsert(aggdesc, tup);
 
diff --git a/src/backend/catalog/pg_collation.c b/src/backend/catalog/pg_collation.c
index ce7e5fb5cc1..54c5b57cbd7 100644
--- a/src/backend/catalog/pg_collation.c
+++ b/src/backend/catalog/pg_collation.c
@@ -18,6 +18,7 @@
 #include "access/heapam.h"
 #include "access/htup_details.h"
 #include "access/sysattr.h"
+#include "catalog/catalog.h"
 #include "catalog/dependency.h"
 #include "catalog/indexing.h"
 #include "catalog/objectaccess.h"
@@ -153,6 +154,8 @@ CollationCreate(const char *collname, Oid collnamespace,
 	memset(nulls, 0, sizeof(nulls));
 
 	namestrcpy(&name_name, collname);
+	oid = GetNewOidWithIndex(rel, CollationOidIndexId, Anum_pg_collation_oid);
+	values[Anum_pg_collation_oid - 1] = oid;
 	values[Anum_pg_collation_collname - 1] = NameGetDatum(&name_name);
 	values[Anum_pg_collation_collnamespace - 1] = ObjectIdGetDatum(collnamespace);
 	values[Anum_pg_collation_collowner - 1] = ObjectIdGetDatum(collowner);
@@ -170,7 +173,7 @@ CollationCreate(const char *collname, Oid collnamespace,
 	tup = heap_form_tuple(tupDesc, values, nulls);
 
 	/* insert a new tuple */
-	oid = CatalogTupleInsert(rel, tup);
+	CatalogTupleInsert(rel, tup);
 	Assert(OidIsValid(oid));
 
 	/* set up dependencies for the new collation */
@@ -185,7 +188,8 @@ CollationCreate(const char *collname, Oid collnamespace,
 	recordDependencyOn(&myself, &referenced, DEPENDENCY_NORMAL);
 
 	/* create dependency on owner */
-	recordDependencyOnOwner(CollationRelationId, HeapTupleGetOid(tup),
+	recordDependencyOnOwner(CollationRelationId,
+							((Form_pg_collation) GETSTRUCT(tup))->oid,
 							collowner);
 
 	/* dependency on extension */
@@ -217,7 +221,7 @@ RemoveCollationById(Oid collationOid)
 	rel = heap_open(CollationRelationId, RowExclusiveLock);
 
 	ScanKeyInit(&scanKeyData,
-				ObjectIdAttributeNumber,
+				Anum_pg_collation_oid,
 				BTEqualStrategyNumber, F_OIDEQ,
 				ObjectIdGetDatum(collationOid));
 
diff --git a/src/backend/catalog/pg_constraint.c b/src/backend/catalog/pg_constraint.c
index 1c235b4b296..a2cb4581fec 100644
--- a/src/backend/catalog/pg_constraint.c
+++ b/src/backend/catalog/pg_constraint.c
@@ -20,6 +20,7 @@
 #include "access/sysattr.h"
 #include "access/tupconvert.h"
 #include "access/xact.h"
+#include "catalog/catalog.h"
 #include "catalog/dependency.h"
 #include "catalog/indexing.h"
 #include "catalog/objectaccess.h"
@@ -169,6 +170,8 @@ CreateConstraintEntry(const char *constraintName,
 		values[i] = (Datum) NULL;
 	}
 
+	conOid = GetNewOidWithIndex(conDesc, ConstraintOidIndexId, Anum_pg_constraint_oid);
+	values[Anum_pg_constraint_oid - 1] = conOid;
 	values[Anum_pg_constraint_conname - 1] = NameGetDatum(&cname);
 	values[Anum_pg_constraint_connamespace - 1] = ObjectIdGetDatum(constraintNamespace);
 	values[Anum_pg_constraint_contype - 1] = CharGetDatum(constraintType);
@@ -224,7 +227,7 @@ CreateConstraintEntry(const char *constraintName,
 
 	tup = heap_form_tuple(RelationGetDescr(conDesc), values, nulls);
 
-	conOid = CatalogTupleInsert(conDesc, tup);
+	CatalogTupleInsert(conDesc, tup);
 
 	conobject.classId = ConstraintRelationId;
 	conobject.objectId = conOid;
@@ -408,7 +411,8 @@ CloneForeignKeyConstraints(Oid parentId, Oid relationId, List **cloned)
 	scan = systable_beginscan(pg_constraint, ConstraintRelidTypidNameIndexId, true,
 							  NULL, 1, &key);
 	while ((tuple = systable_getnext(scan)) != NULL)
-		clone = lappend_oid(clone, HeapTupleGetOid(tuple));
+		clone = lappend_oid(clone,
+							((Form_pg_constraint) GETSTRUCT(tuple))->oid);
 	systable_endscan(scan);
 
 	/* Do the actual work, recursing to partitions as needed */
@@ -647,8 +651,7 @@ clone_fk_constraints(Relation pg_constraint, Relation parentRel,
 			ReleaseSysCache(partcontup);
 
 			/* looks good!  Attach this constraint */
-			ConstraintSetParentConstraint(fk->conoid,
-										  HeapTupleGetOid(tuple));
+			ConstraintSetParentConstraint(fk->conoid, constrForm->oid);
 			CommandCounterIncrement();
 			attach_it = true;
 			break;
@@ -672,7 +675,7 @@ clone_fk_constraints(Relation pg_constraint, Relation parentRel,
 								  constrForm->condeferrable,
 								  constrForm->condeferred,
 								  constrForm->convalidated,
-								  HeapTupleGetOid(tuple),
+								  constrForm->oid,
 								  RelationGetRelid(partRel),
 								  mapped_conkey,
 								  nelem,
@@ -1111,7 +1114,7 @@ AlterConstraintNamespaces(Oid ownerId, Oid oldNspId,
 		ObjectAddress thisobj;
 
 		thisobj.classId = ConstraintRelationId;
-		thisobj.objectId = HeapTupleGetOid(tup);
+		thisobj.objectId = conform->oid;
 		thisobj.objectSubId = 0;
 
 		if (object_address_present(&thisobj, objsMoved))
@@ -1232,7 +1235,7 @@ get_relation_constraint_oid(Oid relid, const char *conname, bool missing_ok)
 
 	/* There can be at most one matching row */
 	if (HeapTupleIsValid(tuple = systable_getnext(scan)))
-		conOid = HeapTupleGetOid(tuple);
+		conOid = ((Form_pg_constraint) GETSTRUCT(tuple))->oid;
 
 	systable_endscan(scan);
 
@@ -1297,7 +1300,7 @@ get_relation_constraint_attnos(Oid relid, const char *conname,
 		Datum		adatum;
 		bool		isNull;
 
-		*constraintOid = HeapTupleGetOid(tuple);
+		*constraintOid = ((Form_pg_constraint) GETSTRUCT(tuple))->oid;
 
 		/* Extract the conkey array, ie, attnums of constrained columns */
 		adatum = heap_getattr(tuple, Anum_pg_constraint_conkey,
@@ -1370,7 +1373,7 @@ get_relation_idx_constraint_oid(Oid relationId, Oid indexId)
 		constrForm = (Form_pg_constraint) GETSTRUCT(tuple);
 		if (constrForm->conindid == indexId)
 		{
-			constraintId = HeapTupleGetOid(tuple);
+			constraintId = constrForm->oid;
 			break;
 		}
 	}
@@ -1414,7 +1417,7 @@ get_domain_constraint_oid(Oid typid, const char *conname, bool missing_ok)
 
 	/* There can be at most one matching row */
 	if (HeapTupleIsValid(tuple = systable_getnext(scan)))
-		conOid = HeapTupleGetOid(tuple);
+		conOid = ((Form_pg_constraint) GETSTRUCT(tuple))->oid;
 
 	systable_endscan(scan);
 
@@ -1494,7 +1497,7 @@ get_primary_key_attnos(Oid relid, bool deferrableOk, Oid *constraintOid)
 							  RelationGetDescr(pg_constraint), &isNull);
 		if (isNull)
 			elog(ERROR, "null conkey for constraint %u",
-				 HeapTupleGetOid(tuple));
+				 ((Form_pg_constraint) GETSTRUCT(tuple))->oid);
 		arr = DatumGetArrayTypeP(adatum);	/* ensure not toasted */
 		numkeys = ARR_DIMS(arr)[0];
 		if (ARR_NDIM(arr) != 1 ||
@@ -1510,7 +1513,7 @@ get_primary_key_attnos(Oid relid, bool deferrableOk, Oid *constraintOid)
 			pkattnos = bms_add_member(pkattnos,
 									  attnums[i] - FirstLowInvalidHeapAttributeNumber);
 		}
-		*constraintOid = HeapTupleGetOid(tuple);
+		*constraintOid = ((Form_pg_constraint) GETSTRUCT(tuple))->oid;
 
 		/* No need to search further */
 		break;
diff --git a/src/backend/catalog/pg_conversion.c b/src/backend/catalog/pg_conversion.c
index fd5c18426bf..f01f7117330 100644
--- a/src/backend/catalog/pg_conversion.c
+++ b/src/backend/catalog/pg_conversion.c
@@ -17,6 +17,7 @@
 #include "access/heapam.h"
 #include "access/htup_details.h"
 #include "access/sysattr.h"
+#include "catalog/catalog.h"
 #include "catalog/dependency.h"
 #include "catalog/indexing.h"
 #include "catalog/objectaccess.h"
@@ -46,6 +47,7 @@ ConversionCreate(const char *conname, Oid connamespace,
 	Relation	rel;
 	TupleDesc	tupDesc;
 	HeapTuple	tup;
+	Oid			oid;
 	bool		nulls[Natts_pg_conversion];
 	Datum		values[Natts_pg_conversion];
 	NameData	cname;
@@ -93,6 +95,8 @@ ConversionCreate(const char *conname, Oid connamespace,
 
 	/* form a tuple */
 	namestrcpy(&cname, conname);
+	oid = GetNewOidWithIndex(rel, ConversionOidIndexId, Anum_pg_conversion_oid);
+	values[Anum_pg_conversion_oid - 1] = oid;
 	values[Anum_pg_conversion_conname - 1] = NameGetDatum(&cname);
 	values[Anum_pg_conversion_connamespace - 1] = ObjectIdGetDatum(connamespace);
 	values[Anum_pg_conversion_conowner - 1] = ObjectIdGetDatum(conowner);
@@ -107,7 +111,7 @@ ConversionCreate(const char *conname, Oid connamespace,
 	CatalogTupleInsert(rel, tup);
 
 	myself.classId = ConversionRelationId;
-	myself.objectId = HeapTupleGetOid(tup);
+	myself.objectId = oid;
 	myself.objectSubId = 0;
 
 	/* create dependency on conversion procedure */
@@ -123,14 +127,13 @@ ConversionCreate(const char *conname, Oid connamespace,
 	recordDependencyOn(&myself, &referenced, DEPENDENCY_NORMAL);
 
 	/* create dependency on owner */
-	recordDependencyOnOwner(ConversionRelationId, HeapTupleGetOid(tup),
-							conowner);
+	recordDependencyOnOwner(ConversionRelationId, oid, conowner);
 
 	/* dependency on extension */
 	recordDependencyOnCurrentExtension(&myself, false);
 
 	/* Post creation hook for new conversion */
-	InvokeObjectPostCreateHook(ConversionRelationId, HeapTupleGetOid(tup), 0);
+	InvokeObjectPostCreateHook(ConversionRelationId, oid, 0);
 
 	heap_freetuple(tup);
 	heap_close(rel, RowExclusiveLock);
@@ -153,7 +156,7 @@ RemoveConversionById(Oid conversionOid)
 	ScanKeyData scanKeyData;
 
 	ScanKeyInit(&scanKeyData,
-				ObjectIdAttributeNumber,
+				Anum_pg_conversion_oid,
 				BTEqualStrategyNumber, F_OIDEQ,
 				ObjectIdGetDatum(conversionOid));
 
diff --git a/src/backend/catalog/pg_enum.c b/src/backend/catalog/pg_enum.c
index ece65587bba..45c345b02a4 100644
--- a/src/backend/catalog/pg_enum.c
+++ b/src/backend/catalog/pg_enum.c
@@ -102,7 +102,8 @@ EnumValuesCreate(Oid enumTypeOid, List *vals)
 
 		do
 		{
-			new_oid = GetNewOid(pg_enum);
+			new_oid = GetNewOidWithIndex(pg_enum, EnumOidIndexId,
+										 Anum_pg_enum_oid);
 		} while (new_oid & 1);
 		oids[elemno] = new_oid;
 	}
@@ -129,13 +130,13 @@ EnumValuesCreate(Oid enumTypeOid, List *vals)
 					 errdetail("Labels must be %d characters or less.",
 							   NAMEDATALEN - 1)));
 
+		values[Anum_pg_enum_oid - 1] = oids[elemno];
 		values[Anum_pg_enum_enumtypid - 1] = ObjectIdGetDatum(enumTypeOid);
 		values[Anum_pg_enum_enumsortorder - 1] = Float4GetDatum(elemno + 1);
 		namestrcpy(&enumlabel, lab);
 		values[Anum_pg_enum_enumlabel - 1] = NameGetDatum(&enumlabel);
 
 		tup = heap_form_tuple(RelationGetDescr(pg_enum), values, nulls);
-		HeapTupleSetOid(tup, oids[elemno]);
 
 		CatalogTupleInsert(pg_enum, tup);
 		heap_freetuple(tup);
@@ -406,7 +407,8 @@ restart:
 			bool		sorts_ok;
 
 			/* Get a new OID (different from all existing pg_enum tuples) */
-			newOid = GetNewOid(pg_enum);
+			newOid = GetNewOidWithIndex(pg_enum, EnumOidIndexId,
+										Anum_pg_enum_oid);
 
 			/*
 			 * Detect whether it sorts correctly relative to existing
@@ -419,7 +421,7 @@ restart:
 			{
 				HeapTuple	exists_tup = existing[i];
 				Form_pg_enum exists_en = (Form_pg_enum) GETSTRUCT(exists_tup);
-				Oid			exists_oid = HeapTupleGetOid(exists_tup);
+				Oid			exists_oid = exists_en->oid;
 
 				if (exists_oid & 1)
 					continue;	/* ignore odd Oids */
@@ -480,12 +482,12 @@ restart:
 
 	/* Create the new pg_enum entry */
 	memset(nulls, false, sizeof(nulls));
+	values[Anum_pg_enum_oid - 1] = newOid;
 	values[Anum_pg_enum_enumtypid - 1] = ObjectIdGetDatum(enumTypeOid);
 	values[Anum_pg_enum_enumsortorder - 1] = Float4GetDatum(newelemorder);
 	namestrcpy(&enumlabel, newVal);
 	values[Anum_pg_enum_enumlabel - 1] = NameGetDatum(&enumlabel);
 	enum_tup = heap_form_tuple(RelationGetDescr(pg_enum), values, nulls);
-	HeapTupleSetOid(enum_tup, newOid);
 	CatalogTupleInsert(pg_enum, enum_tup);
 	heap_freetuple(enum_tup);
 
diff --git a/src/backend/catalog/pg_largeobject.c b/src/backend/catalog/pg_largeobject.c
index a876473976a..82c14b401a3 100644
--- a/src/backend/catalog/pg_largeobject.c
+++ b/src/backend/catalog/pg_largeobject.c
@@ -18,6 +18,7 @@
 #include "access/heapam.h"
 #include "access/htup_details.h"
 #include "access/sysattr.h"
+#include "catalog/catalog.h"
 #include "catalog/dependency.h"
 #include "catalog/indexing.h"
 #include "catalog/pg_largeobject.h"
@@ -54,17 +55,22 @@ LargeObjectCreate(Oid loid)
 	memset(values, 0, sizeof(values));
 	memset(nulls, false, sizeof(nulls));
 
+	if (OidIsValid(loid))
+		loid_new = loid;
+	else
+		loid_new =
+			GetNewOidWithIndex(pg_lo_meta, LargeObjectMetadataOidIndexId, Anum_pg_largeobject_metadata_oid);
+
+
+	values[Anum_pg_largeobject_metadata_oid - 1] = ObjectIdGetDatum(loid_new);
 	values[Anum_pg_largeobject_metadata_lomowner - 1]
 		= ObjectIdGetDatum(GetUserId());
 	nulls[Anum_pg_largeobject_metadata_lomacl - 1] = true;
 
 	ntup = heap_form_tuple(RelationGetDescr(pg_lo_meta),
 						   values, nulls);
-	if (OidIsValid(loid))
-		HeapTupleSetOid(ntup, loid);
 
-	loid_new = CatalogTupleInsert(pg_lo_meta, ntup);
-	Assert(!OidIsValid(loid) || loid == loid_new);
+	CatalogTupleInsert(pg_lo_meta, ntup);
 
 	heap_freetuple(ntup);
 
@@ -96,7 +102,7 @@ LargeObjectDrop(Oid loid)
 	 * Delete an entry from pg_largeobject_metadata
 	 */
 	ScanKeyInit(&skey[0],
-				ObjectIdAttributeNumber,
+				Anum_pg_largeobject_metadata_oid,
 				BTEqualStrategyNumber, F_OIDEQ,
 				ObjectIdGetDatum(loid));
 
@@ -159,7 +165,7 @@ LargeObjectExists(Oid loid)
 	bool		retval = false;
 
 	ScanKeyInit(&skey[0],
-				ObjectIdAttributeNumber,
+				Anum_pg_largeobject_metadata_oid,
 				BTEqualStrategyNumber, F_OIDEQ,
 				ObjectIdGetDatum(loid));
 
diff --git a/src/backend/catalog/pg_namespace.c b/src/backend/catalog/pg_namespace.c
index 0538e31b3b3..96bef786ae9 100644
--- a/src/backend/catalog/pg_namespace.c
+++ b/src/backend/catalog/pg_namespace.c
@@ -16,6 +16,7 @@
 
 #include "access/heapam.h"
 #include "access/htup_details.h"
+#include "catalog/catalog.h"
 #include "catalog/dependency.h"
 #include "catalog/indexing.h"
 #include "catalog/objectaccess.h"
@@ -68,12 +69,18 @@ NamespaceCreate(const char *nspName, Oid ownerId, bool isTemp)
 	else
 		nspacl = NULL;
 
+	nspdesc = heap_open(NamespaceRelationId, RowExclusiveLock);
+	tupDesc = nspdesc->rd_att;
+
 	/* initialize nulls and values */
 	for (i = 0; i < Natts_pg_namespace; i++)
 	{
 		nulls[i] = false;
 		values[i] = (Datum) NULL;
 	}
+
+	nspoid = GetNewOidWithIndex(nspdesc, NamespaceOidIndexId, Anum_pg_namespace_oid);
+	values[Anum_pg_namespace_oid - 1] = nspoid;
 	namestrcpy(&nname, nspName);
 	values[Anum_pg_namespace_nspname - 1] = NameGetDatum(&nname);
 	values[Anum_pg_namespace_nspowner - 1] = ObjectIdGetDatum(ownerId);
@@ -82,12 +89,10 @@ NamespaceCreate(const char *nspName, Oid ownerId, bool isTemp)
 	else
 		nulls[Anum_pg_namespace_nspacl - 1] = true;
 
-	nspdesc = heap_open(NamespaceRelationId, RowExclusiveLock);
-	tupDesc = nspdesc->rd_att;
 
 	tup = heap_form_tuple(tupDesc, values, nulls);
 
-	nspoid = CatalogTupleInsert(nspdesc, tup);
+	CatalogTupleInsert(nspdesc, tup);
 	Assert(OidIsValid(nspoid));
 
 	heap_close(nspdesc, RowExclusiveLock);
diff --git a/src/backend/catalog/pg_operator.c b/src/backend/catalog/pg_operator.c
index 6dde75ed252..21366328ba5 100644
--- a/src/backend/catalog/pg_operator.c
+++ b/src/backend/catalog/pg_operator.c
@@ -20,6 +20,7 @@
 #include "access/heapam.h"
 #include "access/htup_details.h"
 #include "access/xact.h"
+#include "catalog/catalog.h"
 #include "catalog/dependency.h"
 #include "catalog/indexing.h"
 #include "catalog/namespace.h"
@@ -142,10 +143,10 @@ OperatorGet(const char *operatorName,
 						  ObjectIdGetDatum(operatorNamespace));
 	if (HeapTupleIsValid(tup))
 	{
-		RegProcedure oprcode = ((Form_pg_operator) GETSTRUCT(tup))->oprcode;
+		Form_pg_operator oprform = (Form_pg_operator) GETSTRUCT(tup);
 
-		operatorObjectId = HeapTupleGetOid(tup);
-		*defined = RegProcedureIsValid(oprcode);
+		operatorObjectId = oprform->oid;
+		*defined = RegProcedureIsValid(oprform->oprcode);
 		ReleaseSysCache(tup);
 	}
 	else
@@ -218,6 +219,12 @@ OperatorShellMake(const char *operatorName,
 				 errmsg("\"%s\" is not a valid operator name",
 						operatorName)));
 
+	/*
+	 * open pg_operator
+	 */
+	pg_operator_desc = heap_open(OperatorRelationId, RowExclusiveLock);
+	tupDesc = pg_operator_desc->rd_att;
+
 	/*
 	 * initialize our *nulls and *values arrays
 	 */
@@ -231,6 +238,8 @@ OperatorShellMake(const char *operatorName,
 	 * initialize values[] with the operator name and input data types. Note
 	 * that oprcode is set to InvalidOid, indicating it's a shell.
 	 */
+	operatorObjectId = GetNewOidWithIndex(pg_operator_desc, OperatorOidIndexId, Anum_pg_operator_oid);
+	values[Anum_pg_operator_oid - 1] = ObjectIdGetDatum(operatorObjectId);
 	namestrcpy(&oname, operatorName);
 	values[Anum_pg_operator_oprname - 1] = NameGetDatum(&oname);
 	values[Anum_pg_operator_oprnamespace - 1] = ObjectIdGetDatum(operatorNamespace);
@@ -247,12 +256,6 @@ OperatorShellMake(const char *operatorName,
 	values[Anum_pg_operator_oprrest - 1] = ObjectIdGetDatum(InvalidOid);
 	values[Anum_pg_operator_oprjoin - 1] = ObjectIdGetDatum(InvalidOid);
 
-	/*
-	 * open pg_operator
-	 */
-	pg_operator_desc = heap_open(OperatorRelationId, RowExclusiveLock);
-	tupDesc = pg_operator_desc->rd_att;
-
 	/*
 	 * create a new operator tuple
 	 */
@@ -261,7 +264,7 @@ OperatorShellMake(const char *operatorName,
 	/*
 	 * insert our "shell" operator tuple
 	 */
-	operatorObjectId = CatalogTupleInsert(pg_operator_desc, tup);
+	CatalogTupleInsert(pg_operator_desc, tup);
 
 	/* Add dependencies for the entry */
 	makeOperatorDependencies(tup, false);
@@ -517,6 +520,7 @@ OperatorCreate(const char *operatorName,
 			elog(ERROR, "cache lookup failed for operator %u",
 				 operatorObjectId);
 
+		replaces[Anum_pg_operator_oid - 1] = false;
 		tup = heap_modify_tuple(tup,
 								RelationGetDescr(pg_operator_desc),
 								values,
@@ -529,10 +533,13 @@ OperatorCreate(const char *operatorName,
 	{
 		isUpdate = false;
 
+		operatorObjectId = GetNewOidWithIndex(pg_operator_desc, OperatorOidIndexId, Anum_pg_operator_oid);
+		values[Anum_pg_operator_oid - 1] = ObjectIdGetDatum(operatorObjectId);
+
 		tup = heap_form_tuple(RelationGetDescr(pg_operator_desc),
 							  values, nulls);
 
-		operatorObjectId = CatalogTupleInsert(pg_operator_desc, tup);
+		CatalogTupleInsert(pg_operator_desc, tup);
 	}
 
 	/* Add dependencies for the entry */
@@ -767,7 +774,7 @@ makeOperatorDependencies(HeapTuple tuple, bool isUpdate)
 				referenced;
 
 	myself.classId = OperatorRelationId;
-	myself.objectId = HeapTupleGetOid(tuple);
+	myself.objectId = oper->oid;
 	myself.objectSubId = 0;
 
 	/*
@@ -853,7 +860,7 @@ makeOperatorDependencies(HeapTuple tuple, bool isUpdate)
 	}
 
 	/* Dependency on owner */
-	recordDependencyOnOwner(OperatorRelationId, HeapTupleGetOid(tuple),
+	recordDependencyOnOwner(OperatorRelationId, oper->oid,
 							oper->oprowner);
 
 	/* Dependency on extension */
diff --git a/src/backend/catalog/pg_proc.c b/src/backend/catalog/pg_proc.c
index e367da7dba5..00d59805f5d 100644
--- a/src/backend/catalog/pg_proc.c
+++ b/src/backend/catalog/pg_proc.c
@@ -16,6 +16,7 @@
 
 #include "access/htup_details.h"
 #include "access/xact.h"
+#include "catalog/catalog.h"
 #include "catalog/dependency.h"
 #include "catalog/indexing.h"
 #include "catalog/objectaccess.h"
@@ -382,7 +383,7 @@ ProcedureCreate(const char *procedureName,
 					(errcode(ERRCODE_DUPLICATE_FUNCTION),
 					 errmsg("function \"%s\" already exists with same argument types",
 							procedureName)));
-		if (!pg_proc_ownercheck(HeapTupleGetOid(oldtup), proowner))
+		if (!pg_proc_ownercheck(oldproc->oid, proowner))
 			aclcheck_error(ACLCHECK_NOT_OWNER, OBJECT_FUNCTION,
 						   procedureName);
 
@@ -421,7 +422,7 @@ ProcedureCreate(const char *procedureName,
 					 /* translator: first %s is DROP FUNCTION or DROP PROCEDURE */
 					 errhint("Use %s %s first.",
 							 dropcmd,
-							 format_procedure(HeapTupleGetOid(oldtup)))));
+							 format_procedure(oldproc->oid))));
 
 		/*
 		 * If it returns RECORD, check for possible change of record type
@@ -448,7 +449,7 @@ ProcedureCreate(const char *procedureName,
 						 /* translator: first %s is DROP FUNCTION or DROP PROCEDURE */
 						 errhint("Use %s %s first.",
 								 dropcmd,
-								 format_procedure(HeapTupleGetOid(oldtup)))));
+								 format_procedure(oldproc->oid))));
 		}
 
 		/*
@@ -493,7 +494,7 @@ ProcedureCreate(const char *procedureName,
 							 /* translator: first %s is DROP FUNCTION or DROP PROCEDURE */
 							 errhint("Use %s %s first.",
 									 dropcmd,
-									 format_procedure(HeapTupleGetOid(oldtup)))));
+									 format_procedure(oldproc->oid))));
 			}
 		}
 
@@ -519,7 +520,7 @@ ProcedureCreate(const char *procedureName,
 						 /* translator: first %s is DROP FUNCTION or DROP PROCEDURE */
 						 errhint("Use %s %s first.",
 								 dropcmd,
-								 format_procedure(HeapTupleGetOid(oldtup)))));
+								 format_procedure(oldproc->oid))));
 
 			proargdefaults = SysCacheGetAttr(PROCNAMEARGSNSP, oldtup,
 											 Anum_pg_proc_proargdefaults,
@@ -547,15 +548,16 @@ ProcedureCreate(const char *procedureName,
 							 /* translator: first %s is DROP FUNCTION or DROP PROCEDURE */
 							 errhint("Use %s %s first.",
 									 dropcmd,
-									 format_procedure(HeapTupleGetOid(oldtup)))));
+									 format_procedure(oldproc->oid))));
 				newlc = lnext(newlc);
 			}
 		}
 
 		/*
-		 * Do not change existing ownership or permissions, either.  Note
+		 * Do not change existing oid, ownership or permissions, either.  Note
 		 * dependency-update code below has to agree with this decision.
 		 */
+		replaces[Anum_pg_proc_oid - 1] = false;
 		replaces[Anum_pg_proc_proowner - 1] = false;
 		replaces[Anum_pg_proc_proacl - 1] = false;
 
@@ -578,13 +580,15 @@ ProcedureCreate(const char *procedureName,
 		else
 			nulls[Anum_pg_proc_proacl - 1] = true;
 
+		values[Anum_pg_proc_oid - 1] =
+			GetNewOidWithIndex(rel, ProcedureOidIndexId, Anum_pg_proc_oid);
 		tup = heap_form_tuple(tupDesc, values, nulls);
 		CatalogTupleInsert(rel, tup);
 		is_update = false;
 	}
 
 
-	retval = HeapTupleGetOid(tup);
+	retval = ((Form_pg_proc) GETSTRUCT(tup))->oid;
 
 	/*
 	 * Create dependencies for the new function.  If we are updating an
diff --git a/src/backend/catalog/pg_publication.c b/src/backend/catalog/pg_publication.c
index 3ecf6d57bf0..45457507f61 100644
--- a/src/backend/catalog/pg_publication.c
+++ b/src/backend/catalog/pg_publication.c
@@ -182,6 +182,8 @@ publication_add_relation(Oid pubid, Relation targetrel,
 	memset(values, 0, sizeof(values));
 	memset(nulls, false, sizeof(nulls));
 
+	prrelid = GetNewOidWithIndex(rel, PublicationRelObjectIndexId, Anum_pg_publication_rel_oid);
+	values[Anum_pg_publication_rel_oid - 1] = prrelid;
 	values[Anum_pg_publication_rel_prpubid - 1] =
 		ObjectIdGetDatum(pubid);
 	values[Anum_pg_publication_rel_prrelid - 1] =
@@ -190,7 +192,7 @@ publication_add_relation(Oid pubid, Relation targetrel,
 	tup = heap_form_tuple(RelationGetDescr(rel), values, nulls);
 
 	/* Insert tuple into catalog. */
-	prrelid = CatalogTupleInsert(rel, tup);
+	CatalogTupleInsert(rel, tup);
 	heap_freetuple(tup);
 
 	ObjectAddressSet(myself, PublicationRelRelationId, prrelid);
@@ -306,7 +308,7 @@ GetAllTablesPublications(void)
 
 	result = NIL;
 	while (HeapTupleIsValid(tup = systable_getnext(scan)))
-		result = lappend_oid(result, HeapTupleGetOid(tup));
+		result = lappend_oid(result, ((Form_pg_publication) GETSTRUCT(tup))->oid);
 
 	systable_endscan(scan);
 	heap_close(rel, AccessShareLock);
@@ -337,8 +339,8 @@ GetAllTablesPublicationRelations(void)
 
 	while ((tuple = heap_getnext(scan, ForwardScanDirection)) != NULL)
 	{
-		Oid			relid = HeapTupleGetOid(tuple);
 		Form_pg_class relForm = (Form_pg_class) GETSTRUCT(tuple);
+		Oid			relid = relForm->oid;
 
 		if (is_publishable_class(relid, relForm))
 			result = lappend_oid(result, relid);
diff --git a/src/backend/catalog/pg_subscription.c b/src/backend/catalog/pg_subscription.c
index f891ff80543..077701fde0d 100644
--- a/src/backend/catalog/pg_subscription.c
+++ b/src/backend/catalog/pg_subscription.c
@@ -236,13 +236,12 @@ textarray_to_stringlist(ArrayType *textarray)
 /*
  * Add new state record for a subscription table.
  */
-Oid
+void
 AddSubscriptionRelState(Oid subid, Oid relid, char state,
 						XLogRecPtr sublsn)
 {
 	Relation	rel;
 	HeapTuple	tup;
-	Oid			subrelid;
 	bool		nulls[Natts_pg_subscription_rel];
 	Datum		values[Natts_pg_subscription_rel];
 
@@ -272,26 +271,23 @@ AddSubscriptionRelState(Oid subid, Oid relid, char state,
 	tup = heap_form_tuple(RelationGetDescr(rel), values, nulls);
 
 	/* Insert tuple into catalog. */
-	subrelid = CatalogTupleInsert(rel, tup);
+	CatalogTupleInsert(rel, tup);
 
 	heap_freetuple(tup);
 
 	/* Cleanup. */
 	heap_close(rel, NoLock);
-
-	return subrelid;
 }
 
 /*
  * Update the state of a subscription table.
  */
-Oid
+void
 UpdateSubscriptionRelState(Oid subid, Oid relid, char state,
 						   XLogRecPtr sublsn)
 {
 	Relation	rel;
 	HeapTuple	tup;
-	Oid			subrelid;
 	bool		nulls[Natts_pg_subscription_rel];
 	Datum		values[Natts_pg_subscription_rel];
 	bool		replaces[Natts_pg_subscription_rel];
@@ -328,12 +324,8 @@ UpdateSubscriptionRelState(Oid subid, Oid relid, char state,
 	/* Update the catalog. */
 	CatalogTupleUpdate(rel, &tup->t_self, tup);
 
-	subrelid = HeapTupleGetOid(tup);
-
 	/* Cleanup. */
 	heap_close(rel, NoLock);
-
-	return subrelid;
 }
 
 /*
diff --git a/src/backend/catalog/pg_type.c b/src/backend/catalog/pg_type.c
index b729e7ec95d..04c0ad0b0b3 100644
--- a/src/backend/catalog/pg_type.c
+++ b/src/backend/catalog/pg_type.c
@@ -17,6 +17,7 @@
 #include "access/heapam.h"
 #include "access/htup_details.h"
 #include "access/xact.h"
+#include "catalog/catalog.h"
 #include "catalog/binary_upgrade.h"
 #include "catalog/dependency.h"
 #include "catalog/indexing.h"
@@ -121,11 +122,6 @@ TypeShellMake(const char *typeName, Oid typeNamespace, Oid ownerId)
 	nulls[Anum_pg_type_typdefault - 1] = true;
 	nulls[Anum_pg_type_typacl - 1] = true;
 
-	/*
-	 * create a new type tuple
-	 */
-	tup = heap_form_tuple(tupDesc, values, nulls);
-
 	/* Use binary-upgrade override for pg_type.oid? */
 	if (IsBinaryUpgrade)
 	{
@@ -134,14 +130,25 @@ TypeShellMake(const char *typeName, Oid typeNamespace, Oid ownerId)
 					(errcode(ERRCODE_INVALID_PARAMETER_VALUE),
 					 errmsg("pg_type OID value not set when in binary upgrade mode")));
 
-		HeapTupleSetOid(tup, binary_upgrade_next_pg_type_oid);
+		typoid = binary_upgrade_next_pg_type_oid;
 		binary_upgrade_next_pg_type_oid = InvalidOid;
 	}
+	else
+	{
+		typoid = GetNewOidWithIndex(pg_type_desc, TypeOidIndexId, Anum_pg_type_oid);
+	}
+
+	values[Anum_pg_type_oid - 1] = ObjectIdGetDatum(typoid);
+
+	/*
+	 * create a new type tuple
+	 */
+	tup = heap_form_tuple(tupDesc, values, nulls);
 
 	/*
 	 * insert the tuple in the relation and get the tuple's oid.
 	 */
-	typoid = CatalogTupleInsert(pg_type_desc, tup);
+	CatalogTupleInsert(pg_type_desc, tup);
 
 	/*
 	 * Create dependencies.  We can/must skip this in bootstrap mode.
@@ -180,7 +187,7 @@ TypeShellMake(const char *typeName, Oid typeNamespace, Oid ownerId)
  *		otherwise we use exactly that OID.
  * ----------------------------------------------------------------
  */
-ObjectAddress
+ ObjectAddress
 TypeCreate(Oid newTypeOid,
 		   const char *typeName,
 		   Oid typeNamespace,
@@ -407,11 +414,13 @@ TypeCreate(Oid newTypeOid,
 							  ObjectIdGetDatum(typeNamespace));
 	if (HeapTupleIsValid(tup))
 	{
+		Form_pg_type typform = (Form_pg_type) GETSTRUCT(tup);
+
 		/*
 		 * check that the type is not already defined.  It may exist as a
 		 * shell type, however.
 		 */
-		if (((Form_pg_type) GETSTRUCT(tup))->typisdefined)
+		if (typform->typisdefined)
 			ereport(ERROR,
 					(errcode(ERRCODE_DUPLICATE_OBJECT),
 					 errmsg("type \"%s\" already exists", typeName)));
@@ -419,13 +428,15 @@ TypeCreate(Oid newTypeOid,
 		/*
 		 * shell type must have been created by same owner
 		 */
-		if (((Form_pg_type) GETSTRUCT(tup))->typowner != ownerId)
+		if (typform->typowner != ownerId)
 			aclcheck_error(ACLCHECK_NOT_OWNER, OBJECT_TYPE, typeName);
 
 		/* trouble if caller wanted to force the OID */
 		if (OidIsValid(newTypeOid))
 			elog(ERROR, "cannot assign new OID to existing shell type");
 
+		replaces[Anum_pg_type_oid - 1] = false;
+
 		/*
 		 * Okay to update existing shell type tuple
 		 */
@@ -437,19 +448,15 @@ TypeCreate(Oid newTypeOid,
 
 		CatalogTupleUpdate(pg_type_desc, &tup->t_self, tup);
 
-		typeObjectId = HeapTupleGetOid(tup);
+		typeObjectId = typform->oid;
 
 		rebuildDeps = true;		/* get rid of shell type's dependencies */
 	}
 	else
 	{
-		tup = heap_form_tuple(RelationGetDescr(pg_type_desc),
-							  values,
-							  nulls);
-
 		/* Force the OID if requested by caller */
 		if (OidIsValid(newTypeOid))
-			HeapTupleSetOid(tup, newTypeOid);
+			typeObjectId = newTypeOid;
 		/* Use binary-upgrade override for pg_type.oid, if supplied. */
 		else if (IsBinaryUpgrade)
 		{
@@ -458,12 +465,22 @@ TypeCreate(Oid newTypeOid,
 						(errcode(ERRCODE_INVALID_PARAMETER_VALUE),
 						 errmsg("pg_type OID value not set when in binary upgrade mode")));
 
-			HeapTupleSetOid(tup, binary_upgrade_next_pg_type_oid);
+			typeObjectId = binary_upgrade_next_pg_type_oid;
 			binary_upgrade_next_pg_type_oid = InvalidOid;
 		}
-		/* else allow system to assign oid */
+		else
+		{
+			typeObjectId = GetNewOidWithIndex(pg_type_desc, TypeOidIndexId, Anum_pg_type_oid);
+		}
 
-		typeObjectId = CatalogTupleInsert(pg_type_desc, tup);
+		values[Anum_pg_type_oid - 1] = ObjectIdGetDatum(typeObjectId);
+
+		tup = heap_form_tuple(RelationGetDescr(pg_type_desc),
+							  values,
+							  nulls);
+
+
+		CatalogTupleInsert(pg_type_desc, tup);
 	}
 
 	/*
diff --git a/src/backend/catalog/toasting.c b/src/backend/catalog/toasting.c
index 3baaa082381..462969a8384 100644
--- a/src/backend/catalog/toasting.c
+++ b/src/backend/catalog/toasting.c
@@ -216,7 +216,7 @@ create_toast_table(Relation rel, Oid toastOid, Oid toastIndexOid,
 			 "pg_toast_%u_index", relOid);
 
 	/* this is pretty painful...  need a tuple descriptor */
-	tupdesc = CreateTemplateTupleDesc(3, false);
+	tupdesc = CreateTemplateTupleDesc(3);
 	TupleDescInitEntry(tupdesc, (AttrNumber) 1,
 					   "chunk_id",
 					   OIDOID,
@@ -272,8 +272,6 @@ create_toast_table(Relation rel, Oid toastOid, Oid toastIndexOid,
 										   rel->rd_rel->relpersistence,
 										   shared_relation,
 										   mapped_relation,
-										   true,
-										   0,
 										   ONCOMMIT_NOOP,
 										   reloptions,
 										   false,
diff --git a/src/backend/commands/alter.c b/src/backend/commands/alter.c
index eff325cc7d0..21e9d3916a1 100644
--- a/src/backend/commands/alter.c
+++ b/src/backend/commands/alter.c
@@ -903,6 +903,7 @@ void
 AlterObjectOwner_internal(Relation rel, Oid objectId, Oid new_ownerId)
 {
 	Oid			classId = RelationGetRelid(rel);
+	AttrNumber	Anum_oid = get_object_attnum_oid(classId);
 	AttrNumber	Anum_owner = get_object_attnum_owner(classId);
 	AttrNumber	Anum_namespace = get_object_attnum_namespace(classId);
 	AttrNumber	Anum_acl = get_object_attnum_acl(classId);
@@ -913,7 +914,7 @@ AlterObjectOwner_internal(Relation rel, Oid objectId, Oid new_ownerId)
 	Oid			old_ownerId;
 	Oid			namespaceId = InvalidOid;
 
-	oldtup = get_catalog_object_by_oid(rel, objectId);
+	oldtup = get_catalog_object_by_oid(rel, Anum_oid, objectId);
 	if (oldtup == NULL)
 		elog(ERROR, "cache lookup failed for object %u of catalog \"%s\"",
 			 objectId, RelationGetRelationName(rel));
@@ -959,8 +960,7 @@ AlterObjectOwner_internal(Relation rel, Oid objectId, Oid new_ownerId)
 				}
 				else
 				{
-					snprintf(namebuf, sizeof(namebuf), "%u",
-							 HeapTupleGetOid(oldtup));
+					snprintf(namebuf, sizeof(namebuf), "%u", objectId);
 					objname = namebuf;
 				}
 				aclcheck_error(ACLCHECK_NOT_OWNER, objtype, objname);
@@ -1017,7 +1017,7 @@ AlterObjectOwner_internal(Relation rel, Oid objectId, Oid new_ownerId)
 		/* Update owner dependency reference */
 		if (classId == LargeObjectMetadataRelationId)
 			classId = LargeObjectRelationId;
-		changeDependencyOnOwner(classId, HeapTupleGetOid(newtup), new_ownerId);
+		changeDependencyOnOwner(classId, objectId, new_ownerId);
 
 		/* Release memory */
 		pfree(values);
diff --git a/src/backend/commands/amcmds.c b/src/backend/commands/amcmds.c
index f2173450ad3..9c820acac3f 100644
--- a/src/backend/commands/amcmds.c
+++ b/src/backend/commands/amcmds.c
@@ -15,6 +15,7 @@
 
 #include "access/heapam.h"
 #include "access/htup_details.h"
+#include "catalog/catalog.h"
 #include "catalog/dependency.h"
 #include "catalog/indexing.h"
 #include "catalog/pg_am.h"
@@ -80,6 +81,8 @@ CreateAccessMethod(CreateAmStmt *stmt)
 	memset(values, 0, sizeof(values));
 	memset(nulls, false, sizeof(nulls));
 
+	amoid = GetNewOidWithIndex(rel, AmOidIndexId, Anum_pg_am_oid);
+	values[Anum_pg_am_oid - 1] = ObjectIdGetDatum(amoid);
 	values[Anum_pg_am_amname - 1] =
 		DirectFunctionCall1(namein, CStringGetDatum(stmt->amname));
 	values[Anum_pg_am_amhandler - 1] = ObjectIdGetDatum(amhandler);
@@ -87,7 +90,7 @@ CreateAccessMethod(CreateAmStmt *stmt)
 
 	tup = heap_form_tuple(RelationGetDescr(rel), values, nulls);
 
-	amoid = CatalogTupleInsert(rel, tup);
+	CatalogTupleInsert(rel, tup);
 	heap_freetuple(tup);
 
 	myself.classId = AccessMethodRelationId;
@@ -164,7 +167,7 @@ get_am_type_oid(const char *amname, char amtype, bool missing_ok)
 							NameStr(amform->amname),
 							get_am_type_string(amtype))));
 
-		oid = HeapTupleGetOid(tup);
+		oid = amform->oid;
 		ReleaseSysCache(tup);
 	}
 
diff --git a/src/backend/commands/cluster.c b/src/backend/commands/cluster.c
index 5ecd2565b4d..610e425a566 100644
--- a/src/backend/commands/cluster.c
+++ b/src/backend/commands/cluster.c
@@ -75,7 +75,7 @@ static List *get_tables_to_cluster(MemoryContext cluster_context);
 static void reform_and_rewrite_tuple(HeapTuple tuple,
 						 TupleDesc oldTupDesc, TupleDesc newTupDesc,
 						 Datum *values, bool *isnull,
-						 bool newRelHasOids, RewriteState rwstate);
+						 RewriteState rwstate);
 
 
 /*---------------------------------------------------------------------------
@@ -688,8 +688,6 @@ make_new_heap(Oid OIDOldHeap, Oid NewTableSpace, char relpersistence,
 										  relpersistence,
 										  false,
 										  RelationIsMapped(OldHeap),
-										  true,
-										  0,
 										  ONCOMMIT_NOOP,
 										  reloptions,
 										  false,
@@ -1061,7 +1059,7 @@ copy_heap_data(Oid OIDNewHeap, Oid OIDOldHeap, Oid OIDOldIndex, bool verbose,
 			reform_and_rewrite_tuple(tuple,
 									 oldTupDesc, newTupDesc,
 									 values, isnull,
-									 NewHeap->rd_rel->relhasoids, rwstate);
+									 rwstate);
 	}
 
 	if (indexScan != NULL)
@@ -1090,7 +1088,7 @@ copy_heap_data(Oid OIDNewHeap, Oid OIDOldHeap, Oid OIDOldIndex, bool verbose,
 			reform_and_rewrite_tuple(tuple,
 									 oldTupDesc, newTupDesc,
 									 values, isnull,
-									 NewHeap->rd_rel->relhasoids, rwstate);
+									 rwstate);
 		}
 
 		tuplesort_end(tuplesort);
@@ -1755,7 +1753,7 @@ get_tables_to_cluster(MemoryContext cluster_context)
  *
  * 2. The tuple might not even be legal for the new table; this is
  * currently only known to happen as an after-effect of ALTER TABLE
- * SET WITHOUT OIDS.
+ * SET WITHOUT OIDS (in an older version, via pg_upgrade).
  *
  * So, we must reconstruct the tuple from component Datums.
  */
@@ -1763,7 +1761,7 @@ static void
 reform_and_rewrite_tuple(HeapTuple tuple,
 						 TupleDesc oldTupDesc, TupleDesc newTupDesc,
 						 Datum *values, bool *isnull,
-						 bool newRelHasOids, RewriteState rwstate)
+						 RewriteState rwstate)
 {
 	HeapTuple	copiedTuple;
 	int			i;
@@ -1779,10 +1777,6 @@ reform_and_rewrite_tuple(HeapTuple tuple,
 
 	copiedTuple = heap_form_tuple(newTupDesc, values, isnull);
 
-	/* Preserve OID, if any */
-	if (newRelHasOids)
-		HeapTupleSetOid(copiedTuple, HeapTupleGetOid(tuple));
-
 	/* The heap rewrite module does the rest */
 	rewrite_heap_tuple(rwstate, tuple, copiedTuple);
 
diff --git a/src/backend/commands/copy.c b/src/backend/commands/copy.c
index b58a74f4e3d..cbd6a311dd2 100644
--- a/src/backend/commands/copy.c
+++ b/src/backend/commands/copy.c
@@ -128,7 +128,6 @@ typedef struct CopyStateData
 	bool		is_program;		/* is 'filename' a program to popen? */
 	copy_data_source_cb data_source_cb; /* function for reading data */
 	bool		binary;			/* binary format? */
-	bool		oids;			/* include OIDs? */
 	bool		freeze;			/* freeze rows on loading? */
 	bool		csv_mode;		/* Comma Separated Value format? */
 	bool		header_line;	/* CSV header line? */
@@ -170,7 +169,6 @@ typedef struct CopyStateData
 	 * Working state for COPY FROM
 	 */
 	AttrNumber	num_defaults;
-	bool		file_has_oids;
 	FmgrInfo	oid_in_function;
 	Oid			oid_typioparam;
 	FmgrInfo   *in_functions;	/* array of input functions for each attrs */
@@ -310,7 +308,7 @@ static CopyState BeginCopyTo(ParseState *pstate, Relation rel, RawStmt *query,
 static void EndCopyTo(CopyState cstate);
 static uint64 DoCopyTo(CopyState cstate);
 static uint64 CopyTo(CopyState cstate);
-static void CopyOneRowTo(CopyState cstate, Oid tupleOid,
+static void CopyOneRowTo(CopyState cstate,
 			 Datum *values, bool *nulls);
 static void CopyFromInsertBatch(CopyState cstate, EState *estate,
 					CommandId mycid, int hi_options,
@@ -1079,15 +1077,6 @@ ProcessCopyOptions(ParseState *pstate,
 						 errmsg("COPY format \"%s\" not recognized", fmt),
 						 parser_errposition(pstate, defel->location)));
 		}
-		else if (strcmp(defel->defname, "oids") == 0)
-		{
-			if (cstate->oids)
-				ereport(ERROR,
-						(errcode(ERRCODE_SYNTAX_ERROR),
-						 errmsg("conflicting or redundant options"),
-						 parser_errposition(pstate, defel->location)));
-			cstate->oids = defGetBoolean(defel);
-		}
 		else if (strcmp(defel->defname, "freeze") == 0)
 		{
 			if (cstate->freeze)
@@ -1433,13 +1422,6 @@ BeginCopy(ParseState *pstate,
 		cstate->rel = rel;
 
 		tupDesc = RelationGetDescr(cstate->rel);
-
-		/* Don't allow COPY w/ OIDs to or from a table without them */
-		if (cstate->oids && !cstate->rel->rd_rel->relhasoids)
-			ereport(ERROR,
-					(errcode(ERRCODE_UNDEFINED_COLUMN),
-					 errmsg("table \"%s\" does not have OIDs",
-							RelationGetRelationName(cstate->rel))));
 	}
 	else
 	{
@@ -1451,12 +1433,6 @@ BeginCopy(ParseState *pstate,
 		Assert(!is_from);
 		cstate->rel = NULL;
 
-		/* Don't allow COPY w/ OIDs from a query */
-		if (cstate->oids)
-			ereport(ERROR,
-					(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
-					 errmsg("COPY (query) WITH OIDS is not supported")));
-
 		/*
 		 * Run parse analysis and rewrite.  Note this also acquires sufficient
 		 * locks on the source table(s).
@@ -2009,8 +1985,6 @@ CopyTo(CopyState cstate)
 		CopySendData(cstate, BinarySignature, 11);
 		/* Flags field */
 		tmp = 0;
-		if (cstate->oids)
-			tmp |= (1 << 16);
 		CopySendInt32(cstate, tmp);
 		/* No header extension */
 		tmp = 0;
@@ -2072,7 +2046,7 @@ CopyTo(CopyState cstate)
 			heap_deform_tuple(tuple, tupDesc, values, nulls);
 
 			/* Format and send the data */
-			CopyOneRowTo(cstate, HeapTupleGetOid(tuple), values, nulls);
+			CopyOneRowTo(cstate, values, nulls);
 			processed++;
 		}
 
@@ -2105,7 +2079,7 @@ CopyTo(CopyState cstate)
  * Emit one row during CopyTo().
  */
 static void
-CopyOneRowTo(CopyState cstate, Oid tupleOid, Datum *values, bool *nulls)
+CopyOneRowTo(CopyState cstate, Datum *values, bool *nulls)
 {
 	bool		need_delim = false;
 	FmgrInfo   *out_functions = cstate->out_functions;
@@ -2120,25 +2094,6 @@ CopyOneRowTo(CopyState cstate, Oid tupleOid, Datum *values, bool *nulls)
 	{
 		/* Binary per-tuple header */
 		CopySendInt16(cstate, list_length(cstate->attnumlist));
-		/* Send OID if wanted --- note attnumlist doesn't include it */
-		if (cstate->oids)
-		{
-			/* Hack --- assume Oid is same size as int32 */
-			CopySendInt32(cstate, sizeof(int32));
-			CopySendInt32(cstate, tupleOid);
-		}
-	}
-	else
-	{
-		/* Text format has no per-tuple header, but send OID if wanted */
-		/* Assume digits don't need any quoting or encoding conversion */
-		if (cstate->oids)
-		{
-			string = DatumGetCString(DirectFunctionCall1(oidout,
-														 ObjectIdGetDatum(tupleOid)));
-			CopySendString(cstate, string);
-			need_delim = true;
-		}
 	}
 
 	foreach(cur, cstate->attnumlist)
@@ -2650,7 +2605,6 @@ CopyFrom(CopyState cstate)
 	{
 		TupleTableSlot *slot;
 		bool		skip_tuple;
-		Oid			loaded_oid = InvalidOid;
 
 		CHECK_FOR_INTERRUPTS();
 
@@ -2667,15 +2621,12 @@ CopyFrom(CopyState cstate)
 		/* Switch into its memory context */
 		MemoryContextSwitchTo(GetPerTupleMemoryContext(estate));
 
-		if (!NextCopyFrom(cstate, econtext, values, nulls, &loaded_oid))
+		if (!NextCopyFrom(cstate, econtext, values, nulls))
 			break;
 
 		/* And now we can form the input tuple. */
 		tuple = heap_form_tuple(tupDesc, values, nulls);
 
-		if (loaded_oid != InvalidOid)
-			HeapTupleSetOid(tuple, loaded_oid);
-
 		/*
 		 * Constraints might reference the tableoid column, so initialize
 		 * t_tableOid before evaluating them.
@@ -3360,12 +3311,7 @@ BeginCopyFrom(ParseState *pstate,
 		}
 	}
 
-	if (!cstate->binary)
-	{
-		/* must rely on user to tell us... */
-		cstate->file_has_oids = cstate->oids;
-	}
-	else
+	if (cstate->binary)
 	{
 		/* Read and verify binary header */
 		char		readSig[11];
@@ -3382,7 +3328,10 @@ BeginCopyFrom(ParseState *pstate,
 			ereport(ERROR,
 					(errcode(ERRCODE_BAD_COPY_FILE_FORMAT),
 					 errmsg("invalid COPY file header (missing flags)")));
-		cstate->file_has_oids = (tmp & (1 << 16)) != 0;
+		if ((tmp & (1 << 16)) != 0)
+			ereport(ERROR,
+					(errcode(ERRCODE_BAD_COPY_FILE_FORMAT),
+					 errmsg("invalid COPY file header (WITH OIDS)")));
 		tmp &= ~(1 << 16);
 		if ((tmp >> 16) != 0)
 			ereport(ERROR,
@@ -3404,21 +3353,13 @@ BeginCopyFrom(ParseState *pstate,
 		}
 	}
 
-	if (cstate->file_has_oids && cstate->binary)
-	{
-		getTypeBinaryInputInfo(OIDOID,
-							   &in_func_oid, &cstate->oid_typioparam);
-		fmgr_info(in_func_oid, &cstate->oid_in_function);
-	}
-
 	/* create workspace for CopyReadAttributes results */
 	if (!cstate->binary)
 	{
 		AttrNumber	attr_count = list_length(cstate->attnumlist);
-		int			nfields = cstate->file_has_oids ? (attr_count + 1) : attr_count;
 
-		cstate->max_fields = nfields;
-		cstate->raw_fields = (char **) palloc(nfields * sizeof(char *));
+		cstate->max_fields = attr_count;
+		cstate->raw_fields = (char **) palloc(attr_count * sizeof(char *));
 	}
 
 	MemoryContextSwitchTo(oldcontext);
@@ -3491,7 +3432,7 @@ NextCopyFromRawFields(CopyState cstate, char ***fields, int *nfields)
  */
 bool
 NextCopyFrom(CopyState cstate, ExprContext *econtext,
-			 Datum *values, bool *nulls, Oid *tupleOid)
+			 Datum *values, bool *nulls)
 {
 	TupleDesc	tupDesc;
 	AttrNumber	num_phys_attrs,
@@ -3500,16 +3441,12 @@ NextCopyFrom(CopyState cstate, ExprContext *econtext,
 	FmgrInfo   *in_functions = cstate->in_functions;
 	Oid		   *typioparams = cstate->typioparams;
 	int			i;
-	int			nfields;
-	bool		isnull;
-	bool		file_has_oids = cstate->file_has_oids;
 	int		   *defmap = cstate->defmap;
 	ExprState **defexprs = cstate->defexprs;
 
 	tupDesc = RelationGetDescr(cstate->rel);
 	num_phys_attrs = tupDesc->natts;
 	attr_count = list_length(cstate->attnumlist);
-	nfields = file_has_oids ? (attr_count + 1) : attr_count;
 
 	/* Initialize all values for row to NULL */
 	MemSet(values, 0, num_phys_attrs * sizeof(Datum));
@@ -3528,41 +3465,13 @@ NextCopyFrom(CopyState cstate, ExprContext *econtext,
 			return false;
 
 		/* check for overflowing fields */
-		if (nfields > 0 && fldct > nfields)
+		if (attr_count > 0 && fldct > attr_count)
 			ereport(ERROR,
 					(errcode(ERRCODE_BAD_COPY_FILE_FORMAT),
 					 errmsg("extra data after last expected column")));
 
 		fieldno = 0;
 
-		/* Read the OID field if present */
-		if (file_has_oids)
-		{
-			if (fieldno >= fldct)
-				ereport(ERROR,
-						(errcode(ERRCODE_BAD_COPY_FILE_FORMAT),
-						 errmsg("missing data for OID column")));
-			string = field_strings[fieldno++];
-
-			if (string == NULL)
-				ereport(ERROR,
-						(errcode(ERRCODE_BAD_COPY_FILE_FORMAT),
-						 errmsg("null OID in COPY data")));
-			else if (cstate->oids && tupleOid != NULL)
-			{
-				cstate->cur_attname = "oid";
-				cstate->cur_attval = string;
-				*tupleOid = DatumGetObjectId(DirectFunctionCall1(oidin,
-																 CStringGetDatum(string)));
-				if (*tupleOid == InvalidOid)
-					ereport(ERROR,
-							(errcode(ERRCODE_BAD_COPY_FILE_FORMAT),
-							 errmsg("invalid OID in COPY data")));
-				cstate->cur_attname = NULL;
-				cstate->cur_attval = NULL;
-			}
-		}
-
 		/* Loop to read the user attributes on the line. */
 		foreach(cur, cstate->attnumlist)
 		{
@@ -3620,7 +3529,7 @@ NextCopyFrom(CopyState cstate, ExprContext *econtext,
 			cstate->cur_attval = NULL;
 		}
 
-		Assert(fieldno == nfields);
+		Assert(fieldno == attr_count);
 	}
 	else
 	{
@@ -3666,27 +3575,6 @@ NextCopyFrom(CopyState cstate, ExprContext *econtext,
 					 errmsg("row field count is %d, expected %d",
 							(int) fld_count, attr_count)));
 
-		if (file_has_oids)
-		{
-			Oid			loaded_oid;
-
-			cstate->cur_attname = "oid";
-			loaded_oid =
-				DatumGetObjectId(CopyReadBinaryAttribute(cstate,
-														 0,
-														 &cstate->oid_in_function,
-														 cstate->oid_typioparam,
-														 -1,
-														 &isnull));
-			if (isnull || loaded_oid == InvalidOid)
-				ereport(ERROR,
-						(errcode(ERRCODE_BAD_COPY_FILE_FORMAT),
-						 errmsg("invalid OID in COPY data")));
-			cstate->cur_attname = NULL;
-			if (cstate->oids && tupleOid != NULL)
-				*tupleOid = loaded_oid;
-		}
-
 		i = 0;
 		foreach(cur, cstate->attnumlist)
 		{
@@ -5014,7 +4902,7 @@ copy_dest_receive(TupleTableSlot *slot, DestReceiver *self)
 	slot_getallattrs(slot);
 
 	/* And send the data */
-	CopyOneRowTo(cstate, InvalidOid, slot->tts_values, slot->tts_isnull);
+	CopyOneRowTo(cstate, slot->tts_values, slot->tts_isnull);
 	myState->processed++;
 
 	return true;
diff --git a/src/backend/commands/createas.c b/src/backend/commands/createas.c
index d5cb62da15b..f508f05a8bf 100644
--- a/src/backend/commands/createas.c
+++ b/src/backend/commands/createas.c
@@ -391,20 +391,7 @@ ExecCreateTableAs(CreateTableAsStmt *stmt, const char *queryString,
 int
 GetIntoRelEFlags(IntoClause *intoClause)
 {
-	int			flags;
-
-	/*
-	 * We need to tell the executor whether it has to produce OIDs or not,
-	 * because it doesn't have enough information to do so itself (since we
-	 * can't build the target relation until after ExecutorStart).
-	 *
-	 * Disallow the OIDS option for materialized views.
-	 */
-	if (interpretOidsOption(intoClause->options,
-							(intoClause->viewQuery == NULL)))
-		flags = EXEC_FLAG_WITH_OIDS;
-	else
-		flags = EXEC_FLAG_WITHOUT_OIDS;
+	int			flags = 0;
 
 	if (intoClause->skipData)
 		flags |= EXEC_FLAG_WITH_NO_DATA;
@@ -591,12 +578,6 @@ intorel_receive(TupleTableSlot *slot, DestReceiver *self)
 	 */
 	tuple = ExecMaterializeSlot(slot);
 
-	/*
-	 * force assignment of new OID (see comments in ExecInsert)
-	 */
-	if (myState->rel->rd_rel->relhasoids)
-		HeapTupleSetOid(tuple, InvalidOid);
-
 	heap_insert(myState->rel,
 				tuple,
 				myState->output_cid,
diff --git a/src/backend/commands/dbcommands.c b/src/backend/commands/dbcommands.c
index 5342f217c02..2d341c69a8c 100644
--- a/src/backend/commands/dbcommands.c
+++ b/src/backend/commands/dbcommands.c
@@ -504,7 +504,7 @@ createdb(ParseState *pstate, const CreatedbStmt *stmt)
 
 	do
 	{
-		dboid = GetNewOid(pg_database_rel);
+		dboid = GetNewOidWithIndex(pg_database_rel, DatabaseOidIndexId, Anum_pg_database_oid);
 	} while (check_db_file_conflict(dboid));
 
 	/*
@@ -517,6 +517,7 @@ createdb(ParseState *pstate, const CreatedbStmt *stmt)
 	MemSet(new_record, 0, sizeof(new_record));
 	MemSet(new_record_nulls, false, sizeof(new_record_nulls));
 
+	new_record[Anum_pg_database_oid - 1] = dboid;
 	new_record[Anum_pg_database_datname - 1] =
 		DirectFunctionCall1(namein, CStringGetDatum(dbname));
 	new_record[Anum_pg_database_datdba - 1] = ObjectIdGetDatum(datdba);
@@ -543,8 +544,6 @@ createdb(ParseState *pstate, const CreatedbStmt *stmt)
 	tuple = heap_form_tuple(RelationGetDescr(pg_database_rel),
 							new_record, new_record_nulls);
 
-	HeapTupleSetOid(tuple, dboid);
-
 	CatalogTupleInsert(pg_database_rel, tuple);
 
 	/*
@@ -593,7 +592,8 @@ createdb(ParseState *pstate, const CreatedbStmt *stmt)
 		scan = heap_beginscan_catalog(rel, 0, NULL);
 		while ((tuple = heap_getnext(scan, ForwardScanDirection)) != NULL)
 		{
-			Oid			srctablespace = HeapTupleGetOid(tuple);
+			Form_pg_tablespace spaceform = (Form_pg_tablespace) GETSTRUCT(tuple);
+			Oid			srctablespace = spaceform->oid;
 			Oid			dsttablespace;
 			char	   *srcpath;
 			char	   *dstpath;
@@ -1301,8 +1301,7 @@ movedb(const char *dbname, const char *tblspcname)
 									 new_record_nulls, new_record_repl);
 		CatalogTupleUpdate(pgdbrel, &oldtuple->t_self, newtuple);
 
-		InvokeObjectPostAlterHook(DatabaseRelationId,
-								  HeapTupleGetOid(newtuple), 0);
+		InvokeObjectPostAlterHook(DatabaseRelationId, db_id, 0);
 
 		systable_endscan(sysscan);
 
@@ -1400,6 +1399,7 @@ AlterDatabase(ParseState *pstate, AlterDatabaseStmt *stmt, bool isTopLevel)
 	Oid			dboid;
 	HeapTuple	tuple,
 				newtuple;
+	Form_pg_database datform;
 	ScanKeyData scankey;
 	SysScanDesc scan;
 	ListCell   *option;
@@ -1512,9 +1512,10 @@ AlterDatabase(ParseState *pstate, AlterDatabaseStmt *stmt, bool isTopLevel)
 				(errcode(ERRCODE_UNDEFINED_DATABASE),
 				 errmsg("database \"%s\" does not exist", stmt->dbname)));
 
-	dboid = HeapTupleGetOid(tuple);
+	datform = (Form_pg_database) GETSTRUCT(tuple);
+	dboid = datform->oid;
 
-	if (!pg_database_ownercheck(HeapTupleGetOid(tuple), GetUserId()))
+	if (!pg_database_ownercheck(dboid, GetUserId()))
 		aclcheck_error(ACLCHECK_NOT_OWNER, OBJECT_DATABASE,
 					   stmt->dbname);
 
@@ -1556,8 +1557,7 @@ AlterDatabase(ParseState *pstate, AlterDatabaseStmt *stmt, bool isTopLevel)
 								 new_record_nulls, new_record_repl);
 	CatalogTupleUpdate(rel, &tuple->t_self, newtuple);
 
-	InvokeObjectPostAlterHook(DatabaseRelationId,
-							  HeapTupleGetOid(newtuple), 0);
+	InvokeObjectPostAlterHook(DatabaseRelationId, dboid, 0);
 
 	systable_endscan(scan);
 
@@ -1626,8 +1626,8 @@ AlterDatabaseOwner(const char *dbname, Oid newOwnerId)
 				(errcode(ERRCODE_UNDEFINED_DATABASE),
 				 errmsg("database \"%s\" does not exist", dbname)));
 
-	db_id = HeapTupleGetOid(tuple);
 	datForm = (Form_pg_database) GETSTRUCT(tuple);
+	db_id = datForm->oid;
 
 	/*
 	 * If the new owner is the same as the existing owner, consider the
@@ -1645,7 +1645,7 @@ AlterDatabaseOwner(const char *dbname, Oid newOwnerId)
 		HeapTuple	newtuple;
 
 		/* Otherwise, must be owner of the existing object */
-		if (!pg_database_ownercheck(HeapTupleGetOid(tuple), GetUserId()))
+		if (!pg_database_ownercheck(db_id, GetUserId()))
 			aclcheck_error(ACLCHECK_NOT_OWNER, OBJECT_DATABASE,
 						   dbname);
 
@@ -1694,11 +1694,10 @@ AlterDatabaseOwner(const char *dbname, Oid newOwnerId)
 		heap_freetuple(newtuple);
 
 		/* Update owner dependency reference */
-		changeDependencyOnOwner(DatabaseRelationId, HeapTupleGetOid(tuple),
-								newOwnerId);
+		changeDependencyOnOwner(DatabaseRelationId, db_id, newOwnerId);
 	}
 
-	InvokeObjectPostAlterHook(DatabaseRelationId, HeapTupleGetOid(tuple), 0);
+	InvokeObjectPostAlterHook(DatabaseRelationId, db_id, 0);
 
 	ObjectAddressSet(address, DatabaseRelationId, db_id);
 
@@ -1762,7 +1761,6 @@ get_db_info(const char *name, LOCKMODE lockmode,
 								  NULL, 1, &scanKey);
 
 		tuple = systable_getnext(scan);
-
 		if (!HeapTupleIsValid(tuple))
 		{
 			/* definitely no database of that name */
@@ -1770,7 +1768,7 @@ get_db_info(const char *name, LOCKMODE lockmode,
 			break;
 		}
 
-		dbOid = HeapTupleGetOid(tuple);
+		dbOid = ((Form_pg_database) GETSTRUCT(tuple))->oid;
 
 		systable_endscan(scan);
 
@@ -1878,7 +1876,8 @@ remove_dbtablespaces(Oid db_id)
 	scan = heap_beginscan_catalog(rel, 0, NULL);
 	while ((tuple = heap_getnext(scan, ForwardScanDirection)) != NULL)
 	{
-		Oid			dsttablespace = HeapTupleGetOid(tuple);
+		Form_pg_tablespace spcform = (Form_pg_tablespace) GETSTRUCT(tuple);
+		Oid			dsttablespace = spcform->oid;
 		char	   *dstpath;
 		struct stat st;
 
@@ -1945,7 +1944,8 @@ check_db_file_conflict(Oid db_id)
 	scan = heap_beginscan_catalog(rel, 0, NULL);
 	while ((tuple = heap_getnext(scan, ForwardScanDirection)) != NULL)
 	{
-		Oid			dsttablespace = HeapTupleGetOid(tuple);
+		Form_pg_tablespace spcform = (Form_pg_tablespace) GETSTRUCT(tuple);
+		Oid			dsttablespace = spcform->oid;
 		char	   *dstpath;
 		struct stat st;
 
@@ -2030,7 +2030,7 @@ get_database_oid(const char *dbname, bool missing_ok)
 
 	/* We assume that there can be at most one matching tuple */
 	if (HeapTupleIsValid(dbtuple))
-		oid = HeapTupleGetOid(dbtuple);
+		oid = ((Form_pg_database)GETSTRUCT(dbtuple))->oid;
 	else
 		oid = InvalidOid;
 
diff --git a/src/backend/commands/event_trigger.c b/src/backend/commands/event_trigger.c
index 20a3a786929..b0c8b362a50 100644
--- a/src/backend/commands/event_trigger.c
+++ b/src/backend/commands/event_trigger.c
@@ -15,6 +15,7 @@
 
 #include "access/htup_details.h"
 #include "access/xact.h"
+#include "catalog/catalog.h"
 #include "catalog/dependency.h"
 #include "catalog/indexing.h"
 #include "catalog/objectaccess.h"
@@ -391,6 +392,8 @@ insert_event_trigger_tuple(const char *trigname, const char *eventname, Oid evtO
 	tgrel = heap_open(EventTriggerRelationId, RowExclusiveLock);
 
 	/* Build the new pg_trigger tuple. */
+	trigoid = GetNewOidWithIndex(tgrel, EventTriggerOidIndexId, Anum_pg_event_trigger_oid);
+	values[Anum_pg_event_trigger_oid - 1] = ObjectIdGetDatum(trigoid);
 	memset(nulls, false, sizeof(nulls));
 	namestrcpy(&evtnamedata, trigname);
 	values[Anum_pg_event_trigger_evtname - 1] = NameGetDatum(&evtnamedata);
@@ -408,7 +411,7 @@ insert_event_trigger_tuple(const char *trigname, const char *eventname, Oid evtO
 
 	/* Insert heap tuple. */
 	tuple = heap_form_tuple(tgrel->rd_att, values, nulls);
-	trigoid = CatalogTupleInsert(tgrel, tuple);
+	CatalogTupleInsert(tgrel, tuple);
 	heap_freetuple(tuple);
 
 	/* Depend on owner. */
@@ -516,14 +519,14 @@ AlterEventTrigger(AlterEventTrigStmt *stmt)
 				 errmsg("event trigger \"%s\" does not exist",
 						stmt->trigname)));
 
-	trigoid = HeapTupleGetOid(tup);
+	evtForm = (Form_pg_event_trigger) GETSTRUCT(tup);
+	trigoid = evtForm->oid;
 
 	if (!pg_event_trigger_ownercheck(trigoid, GetUserId()))
 		aclcheck_error(ACLCHECK_NOT_OWNER, OBJECT_EVENT_TRIGGER,
 					   stmt->trigname);
 
 	/* tuple is a copy, so we can modify it below */
-	evtForm = (Form_pg_event_trigger) GETSTRUCT(tup);
 	evtForm->evtenabled = tgenabled;
 
 	CatalogTupleUpdate(tgrel, &tup->t_self, tup);
@@ -546,6 +549,7 @@ AlterEventTriggerOwner(const char *name, Oid newOwnerId)
 {
 	Oid			evtOid;
 	HeapTuple	tup;
+	Form_pg_event_trigger evtForm;
 	Relation	rel;
 	ObjectAddress address;
 
@@ -558,7 +562,8 @@ AlterEventTriggerOwner(const char *name, Oid newOwnerId)
 				(errcode(ERRCODE_UNDEFINED_OBJECT),
 				 errmsg("event trigger \"%s\" does not exist", name)));
 
-	evtOid = HeapTupleGetOid(tup);
+	evtForm = (Form_pg_event_trigger) GETSTRUCT(tup);
+	evtOid = evtForm->oid;
 
 	AlterEventTriggerOwner_internal(rel, tup, newOwnerId);
 
@@ -609,7 +614,7 @@ AlterEventTriggerOwner_internal(Relation rel, HeapTuple tup, Oid newOwnerId)
 	if (form->evtowner == newOwnerId)
 		return;
 
-	if (!pg_event_trigger_ownercheck(HeapTupleGetOid(tup), GetUserId()))
+	if (!pg_event_trigger_ownercheck(form->oid, GetUserId()))
 		aclcheck_error(ACLCHECK_NOT_OWNER, OBJECT_EVENT_TRIGGER,
 					   NameStr(form->evtname));
 
@@ -626,11 +631,11 @@ AlterEventTriggerOwner_internal(Relation rel, HeapTuple tup, Oid newOwnerId)
 
 	/* Update owner dependency reference */
 	changeDependencyOnOwner(EventTriggerRelationId,
-							HeapTupleGetOid(tup),
+							form->oid,
 							newOwnerId);
 
 	InvokeObjectPostAlterHook(EventTriggerRelationId,
-							  HeapTupleGetOid(tup), 0);
+							  form->oid, 0);
 }
 
 /*
@@ -1357,7 +1362,8 @@ EventTriggerSQLDropAddObject(const ObjectAddress *object, bool original, bool no
 		HeapTuple	tuple;
 
 		catalog = heap_open(obj->address.classId, AccessShareLock);
-		tuple = get_catalog_object_by_oid(catalog, obj->address.objectId);
+		tuple = get_catalog_object_by_oid(catalog, get_object_attnum_oid(object->classId),
+										  obj->address.objectId);
 
 		if (tuple)
 		{
@@ -2106,6 +2112,7 @@ pg_event_trigger_ddl_commands(PG_FUNCTION_ARGS)
 
 							catalog = heap_open(addr.classId, AccessShareLock);
 							objtup = get_catalog_object_by_oid(catalog,
+															   get_object_attnum_oid(addr.classId),
 															   addr.objectId);
 							if (!HeapTupleIsValid(objtup))
 								elog(ERROR, "cache lookup failed for object %u/%u",
diff --git a/src/backend/commands/explain.c b/src/backend/commands/explain.c
index 799a22e9d55..6a7cef84a0f 100644
--- a/src/backend/commands/explain.c
+++ b/src/backend/commands/explain.c
@@ -323,7 +323,7 @@ ExplainResultDesc(ExplainStmt *stmt)
 	}
 
 	/* Need a tuple descriptor representing a single TEXT or XML column */
-	tupdesc = CreateTemplateTupleDesc(1, false);
+	tupdesc = CreateTemplateTupleDesc(1);
 	TupleDescInitEntry(tupdesc, (AttrNumber) 1, "QUERY PLAN",
 					   result_type, -1, 0);
 	return tupdesc;
diff --git a/src/backend/commands/extension.c b/src/backend/commands/extension.c
index 560064d3e1f..6d2005af657 100644
--- a/src/backend/commands/extension.c
+++ b/src/backend/commands/extension.c
@@ -32,6 +32,7 @@
 #include "access/htup_details.h"
 #include "access/sysattr.h"
 #include "access/xact.h"
+#include "catalog/catalog.h"
 #include "catalog/dependency.h"
 #include "catalog/indexing.h"
 #include "catalog/namespace.h"
@@ -154,7 +155,7 @@ get_extension_oid(const char *extname, bool missing_ok)
 
 	/* We assume that there can be at most one matching tuple */
 	if (HeapTupleIsValid(tuple))
-		result = HeapTupleGetOid(tuple);
+		result = ((Form_pg_extension) GETSTRUCT(tuple))->oid;
 	else
 		result = InvalidOid;
 
@@ -188,7 +189,7 @@ get_extension_name(Oid ext_oid)
 	rel = heap_open(ExtensionRelationId, AccessShareLock);
 
 	ScanKeyInit(&entry[0],
-				ObjectIdAttributeNumber,
+				Anum_pg_extension_oid,
 				BTEqualStrategyNumber, F_OIDEQ,
 				ObjectIdGetDatum(ext_oid));
 
@@ -227,7 +228,7 @@ get_extension_schema(Oid ext_oid)
 	rel = heap_open(ExtensionRelationId, AccessShareLock);
 
 	ScanKeyInit(&entry[0],
-				ObjectIdAttributeNumber,
+				Anum_pg_extension_oid,
 				BTEqualStrategyNumber, F_OIDEQ,
 				ObjectIdGetDatum(ext_oid));
 
@@ -1758,6 +1759,8 @@ InsertExtensionTuple(const char *extName, Oid extOwner,
 	memset(values, 0, sizeof(values));
 	memset(nulls, 0, sizeof(nulls));
 
+	extensionOid = GetNewOidWithIndex(rel, ExtensionOidIndexId, Anum_pg_extension_oid);
+	values[Anum_pg_extension_oid - 1] = ObjectIdGetDatum(extensionOid);
 	values[Anum_pg_extension_extname - 1] =
 		DirectFunctionCall1(namein, CStringGetDatum(extName));
 	values[Anum_pg_extension_extowner - 1] = ObjectIdGetDatum(extOwner);
@@ -1777,7 +1780,7 @@ InsertExtensionTuple(const char *extName, Oid extOwner,
 
 	tuple = heap_form_tuple(rel->rd_att, values, nulls);
 
-	extensionOid = CatalogTupleInsert(rel, tuple);
+	CatalogTupleInsert(rel, tuple);
 
 	heap_freetuple(tuple);
 	heap_close(rel, RowExclusiveLock);
@@ -1848,7 +1851,7 @@ RemoveExtensionById(Oid extId)
 	rel = heap_open(ExtensionRelationId, RowExclusiveLock);
 
 	ScanKeyInit(&entry[0],
-				ObjectIdAttributeNumber,
+				Anum_pg_extension_oid,
 				BTEqualStrategyNumber, F_OIDEQ,
 				ObjectIdGetDatum(extId));
 	scandesc = systable_beginscan(rel, ExtensionOidIndexId, true,
@@ -2376,7 +2379,7 @@ pg_extension_config_dump(PG_FUNCTION_ARGS)
 	extRel = heap_open(ExtensionRelationId, RowExclusiveLock);
 
 	ScanKeyInit(&key[0],
-				ObjectIdAttributeNumber,
+				Anum_pg_extension_oid,
 				BTEqualStrategyNumber, F_OIDEQ,
 				ObjectIdGetDatum(CurrentExtensionObject));
 
@@ -2524,7 +2527,7 @@ extension_config_remove(Oid extensionoid, Oid tableoid)
 	extRel = heap_open(ExtensionRelationId, RowExclusiveLock);
 
 	ScanKeyInit(&key[0],
-				ObjectIdAttributeNumber,
+				Anum_pg_extension_oid,
 				BTEqualStrategyNumber, F_OIDEQ,
 				ObjectIdGetDatum(extensionoid));
 
@@ -2723,7 +2726,7 @@ AlterExtensionNamespace(const char *extensionName, const char *newschema, Oid *o
 	extRel = heap_open(ExtensionRelationId, RowExclusiveLock);
 
 	ScanKeyInit(&key[0],
-				ObjectIdAttributeNumber,
+				Anum_pg_extension_oid,
 				BTEqualStrategyNumber, F_OIDEQ,
 				ObjectIdGetDatum(extensionOid));
 
@@ -2903,7 +2906,7 @@ ExecAlterExtensionStmt(ParseState *pstate, AlterExtensionStmt *stmt)
 				 errmsg("extension \"%s\" does not exist",
 						stmt->extname)));
 
-	extensionOid = HeapTupleGetOid(extTup);
+	extensionOid = ((Form_pg_extension) GETSTRUCT(extTup))->oid;
 
 	/*
 	 * Determine the existing version we are updating from
@@ -3045,7 +3048,7 @@ ApplyExtensionUpdates(Oid extensionOid,
 		extRel = heap_open(ExtensionRelationId, RowExclusiveLock);
 
 		ScanKeyInit(&key[0],
-					ObjectIdAttributeNumber,
+					Anum_pg_extension_oid,
 					BTEqualStrategyNumber, F_OIDEQ,
 					ObjectIdGetDatum(extensionOid));
 
diff --git a/src/backend/commands/foreigncmds.c b/src/backend/commands/foreigncmds.c
index e5dd9958a4c..8b2e4b5cfc2 100644
--- a/src/backend/commands/foreigncmds.c
+++ b/src/backend/commands/foreigncmds.c
@@ -17,6 +17,7 @@
 #include "access/htup_details.h"
 #include "access/reloptions.h"
 #include "access/xact.h"
+#include "catalog/catalog.h"
 #include "catalog/dependency.h"
 #include "catalog/indexing.h"
 #include "catalog/objectaccess.h"
@@ -260,12 +261,12 @@ AlterForeignDataWrapperOwner_internal(Relation rel, HeapTuple tup, Oid newOwnerI
 
 		/* Update owner dependency reference */
 		changeDependencyOnOwner(ForeignDataWrapperRelationId,
-								HeapTupleGetOid(tup),
+								form->oid,
 								newOwnerId);
 	}
 
 	InvokeObjectPostAlterHook(ForeignDataWrapperRelationId,
-							  HeapTupleGetOid(tup), 0);
+							  form->oid, 0);
 }
 
 /*
@@ -280,6 +281,8 @@ AlterForeignDataWrapperOwner(const char *name, Oid newOwnerId)
 	HeapTuple	tup;
 	Relation	rel;
 	ObjectAddress address;
+	Form_pg_foreign_data_wrapper form;
+
 
 	rel = heap_open(ForeignDataWrapperRelationId, RowExclusiveLock);
 
@@ -290,7 +293,8 @@ AlterForeignDataWrapperOwner(const char *name, Oid newOwnerId)
 				(errcode(ERRCODE_UNDEFINED_OBJECT),
 				 errmsg("foreign-data wrapper \"%s\" does not exist", name)));
 
-	fdwId = HeapTupleGetOid(tup);
+	form = (Form_pg_foreign_data_wrapper) GETSTRUCT(tup);
+	fdwId = form->oid;
 
 	AlterForeignDataWrapperOwner_internal(rel, tup, newOwnerId);
 
@@ -354,7 +358,7 @@ AlterForeignServerOwner_internal(Relation rel, HeapTuple tup, Oid newOwnerId)
 			Oid			srvId;
 			AclResult	aclresult;
 
-			srvId = HeapTupleGetOid(tup);
+			srvId = form->oid;
 
 			/* Must be owner */
 			if (!pg_foreign_server_ownercheck(srvId, GetUserId()))
@@ -399,12 +403,12 @@ AlterForeignServerOwner_internal(Relation rel, HeapTuple tup, Oid newOwnerId)
 		CatalogTupleUpdate(rel, &tup->t_self, tup);
 
 		/* Update owner dependency reference */
-		changeDependencyOnOwner(ForeignServerRelationId, HeapTupleGetOid(tup),
+		changeDependencyOnOwner(ForeignServerRelationId, form->oid,
 								newOwnerId);
 	}
 
 	InvokeObjectPostAlterHook(ForeignServerRelationId,
-							  HeapTupleGetOid(tup), 0);
+							  form->oid, 0);
 }
 
 /*
@@ -417,6 +421,7 @@ AlterForeignServerOwner(const char *name, Oid newOwnerId)
 	HeapTuple	tup;
 	Relation	rel;
 	ObjectAddress address;
+	Form_pg_foreign_server form;
 
 	rel = heap_open(ForeignServerRelationId, RowExclusiveLock);
 
@@ -427,7 +432,8 @@ AlterForeignServerOwner(const char *name, Oid newOwnerId)
 				(errcode(ERRCODE_UNDEFINED_OBJECT),
 				 errmsg("server \"%s\" does not exist", name)));
 
-	servOid = HeapTupleGetOid(tup);
+	form = (Form_pg_foreign_server) GETSTRUCT(tup);
+	servOid = form->oid;
 
 	AlterForeignServerOwner_internal(rel, tup, newOwnerId);
 
@@ -601,6 +607,8 @@ CreateForeignDataWrapper(CreateFdwStmt *stmt)
 	memset(values, 0, sizeof(values));
 	memset(nulls, false, sizeof(nulls));
 
+	fdwId = GetNewOidWithIndex(rel, ForeignDataWrapperOidIndexId, Anum_pg_foreign_data_wrapper_oid);
+	values[Anum_pg_foreign_data_wrapper_oid - 1] = ObjectIdGetDatum(fdwId);
 	values[Anum_pg_foreign_data_wrapper_fdwname - 1] =
 		DirectFunctionCall1(namein, CStringGetDatum(stmt->fdwname));
 	values[Anum_pg_foreign_data_wrapper_fdwowner - 1] = ObjectIdGetDatum(ownerId);
@@ -627,7 +635,7 @@ CreateForeignDataWrapper(CreateFdwStmt *stmt)
 
 	tuple = heap_form_tuple(rel->rd_att, values, nulls);
 
-	fdwId = CatalogTupleInsert(rel, tuple);
+	CatalogTupleInsert(rel, tuple);
 
 	heap_freetuple(tuple);
 
@@ -706,7 +714,7 @@ AlterForeignDataWrapper(AlterFdwStmt *stmt)
 				 errmsg("foreign-data wrapper \"%s\" does not exist", stmt->fdwname)));
 
 	fdwForm = (Form_pg_foreign_data_wrapper) GETSTRUCT(tp);
-	fdwId = HeapTupleGetOid(tp);
+	fdwId = fdwForm->oid;
 
 	memset(repl_val, 0, sizeof(repl_val));
 	memset(repl_null, false, sizeof(repl_null));
@@ -915,6 +923,8 @@ CreateForeignServer(CreateForeignServerStmt *stmt)
 	memset(values, 0, sizeof(values));
 	memset(nulls, false, sizeof(nulls));
 
+	srvId = GetNewOidWithIndex(rel, ForeignServerOidIndexId, Anum_pg_foreign_server_oid);
+	values[Anum_pg_foreign_server_oid - 1] = ObjectIdGetDatum(srvId);
 	values[Anum_pg_foreign_server_srvname - 1] =
 		DirectFunctionCall1(namein, CStringGetDatum(stmt->servername));
 	values[Anum_pg_foreign_server_srvowner - 1] = ObjectIdGetDatum(ownerId);
@@ -950,7 +960,7 @@ CreateForeignServer(CreateForeignServerStmt *stmt)
 
 	tuple = heap_form_tuple(rel->rd_att, values, nulls);
 
-	srvId = CatalogTupleInsert(rel, tuple);
+	CatalogTupleInsert(rel, tuple);
 
 	heap_freetuple(tuple);
 
@@ -1003,8 +1013,8 @@ AlterForeignServer(AlterForeignServerStmt *stmt)
 				(errcode(ERRCODE_UNDEFINED_OBJECT),
 				 errmsg("server \"%s\" does not exist", stmt->servername)));
 
-	srvId = HeapTupleGetOid(tp);
 	srvForm = (Form_pg_foreign_server) GETSTRUCT(tp);
+	srvId = srvForm->oid;
 
 	/*
 	 * Only owner or a superuser can ALTER a SERVER.
@@ -1195,6 +1205,8 @@ CreateUserMapping(CreateUserMappingStmt *stmt)
 	memset(values, 0, sizeof(values));
 	memset(nulls, false, sizeof(nulls));
 
+	umId = GetNewOidWithIndex(rel, UserMappingOidIndexId, Anum_pg_user_mapping_oid);
+	values[Anum_pg_user_mapping_oid - 1] = ObjectIdGetDatum(umId);
 	values[Anum_pg_user_mapping_umuser - 1] = ObjectIdGetDatum(useId);
 	values[Anum_pg_user_mapping_umserver - 1] = ObjectIdGetDatum(srv->serverid);
 
@@ -1211,7 +1223,7 @@ CreateUserMapping(CreateUserMappingStmt *stmt)
 
 	tuple = heap_form_tuple(rel->rd_att, values, nulls);
 
-	umId = CatalogTupleInsert(rel, tuple);
+	CatalogTupleInsert(rel, tuple);
 
 	heap_freetuple(tuple);
 
diff --git a/src/backend/commands/functioncmds.c b/src/backend/commands/functioncmds.c
index 3925fb83a54..0b5d0104e4e 100644
--- a/src/backend/commands/functioncmds.c
+++ b/src/backend/commands/functioncmds.c
@@ -36,6 +36,7 @@
 #include "access/heapam.h"
 #include "access/htup_details.h"
 #include "access/sysattr.h"
+#include "catalog/catalog.h"
 #include "catalog/dependency.h"
 #include "catalog/indexing.h"
 #include "catalog/objectaccess.h"
@@ -938,8 +939,8 @@ CreateFunction(ParseState *pstate, CreateFunctionStmt *stmt)
 				 (PLTemplateExists(language) ?
 				  errhint("Use CREATE EXTENSION to load the language into the database.") : 0)));
 
-	languageOid = HeapTupleGetOid(languageTuple);
 	languageStruct = (Form_pg_language) GETSTRUCT(languageTuple);
+	languageOid = languageStruct->oid;
 
 	if (languageStruct->lanpltrusted)
 	{
@@ -1668,6 +1669,8 @@ CreateCast(CreateCastStmt *stmt)
 						format_type_be(targettypeid))));
 
 	/* ready to go */
+	castid = GetNewOidWithIndex(relation, CastOidIndexId, Anum_pg_cast_oid);
+	values[Anum_pg_cast_oid - 1] = ObjectIdGetDatum(castid);
 	values[Anum_pg_cast_castsource - 1] = ObjectIdGetDatum(sourcetypeid);
 	values[Anum_pg_cast_casttarget - 1] = ObjectIdGetDatum(targettypeid);
 	values[Anum_pg_cast_castfunc - 1] = ObjectIdGetDatum(funcid);
@@ -1678,7 +1681,7 @@ CreateCast(CreateCastStmt *stmt)
 
 	tuple = heap_form_tuple(RelationGetDescr(relation), values, nulls);
 
-	castid = CatalogTupleInsert(relation, tuple);
+	CatalogTupleInsert(relation, tuple);
 
 	/* make dependency entries */
 	myself.classId = CastRelationId;
@@ -1753,7 +1756,7 @@ DropCastById(Oid castOid)
 	relation = heap_open(CastRelationId, RowExclusiveLock);
 
 	ScanKeyInit(&scankey,
-				ObjectIdAttributeNumber,
+				Anum_pg_cast_oid,
 				BTEqualStrategyNumber, F_OIDEQ,
 				ObjectIdGetDatum(castOid));
 	scan = systable_beginscan(relation, CastOidIndexId, true,
@@ -1925,6 +1928,8 @@ CreateTransform(CreateTransformStmt *stmt)
 							ObjectIdGetDatum(langid));
 	if (HeapTupleIsValid(tuple))
 	{
+		Form_pg_transform form = (Form_pg_transform) GETSTRUCT(tuple);
+
 		if (!stmt->replace)
 			ereport(ERROR,
 					(errcode(ERRCODE_DUPLICATE_OBJECT),
@@ -1939,14 +1944,16 @@ CreateTransform(CreateTransformStmt *stmt)
 		newtuple = heap_modify_tuple(tuple, RelationGetDescr(relation), values, nulls, replaces);
 		CatalogTupleUpdate(relation, &newtuple->t_self, newtuple);
 
-		transformid = HeapTupleGetOid(tuple);
+		transformid = form->oid;
 		ReleaseSysCache(tuple);
 		is_replace = true;
 	}
 	else
 	{
+		transformid = GetNewOidWithIndex(relation, TransformOidIndexId, Anum_pg_transform_oid);
+		values[Anum_pg_transform_oid - 1] = transformid;
 		newtuple = heap_form_tuple(RelationGetDescr(relation), values, nulls);
-		transformid = CatalogTupleInsert(relation, newtuple);
+		CatalogTupleInsert(relation, newtuple);
 		is_replace = false;
 	}
 
@@ -2035,7 +2042,7 @@ DropTransformById(Oid transformOid)
 	relation = heap_open(TransformRelationId, RowExclusiveLock);
 
 	ScanKeyInit(&scankey,
-				ObjectIdAttributeNumber,
+				Anum_pg_transform_oid,
 				BTEqualStrategyNumber, F_OIDEQ,
 				ObjectIdGetDatum(transformOid));
 	scan = systable_beginscan(relation, TransformOidIndexId, true,
@@ -2140,8 +2147,8 @@ ExecuteDoStmt(DoStmt *stmt, bool atomic)
 				 (PLTemplateExists(language) ?
 				  errhint("Use CREATE EXTENSION to load the language into the database.") : 0)));
 
-	codeblock->langOid = HeapTupleGetOid(languageTuple);
 	languageStruct = (Form_pg_language) GETSTRUCT(languageTuple);
+	codeblock->langOid = languageStruct->oid;
 	codeblock->langIsTrusted = languageStruct->lanpltrusted;
 	codeblock->atomic = atomic;
 
diff --git a/src/backend/commands/indexcmds.c b/src/backend/commands/indexcmds.c
index 906d7113781..fbd020d769d 100644
--- a/src/backend/commands/indexcmds.c
+++ b/src/backend/commands/indexcmds.c
@@ -172,8 +172,8 @@ CheckIndexCompatible(Oid oldId,
 				(errcode(ERRCODE_UNDEFINED_OBJECT),
 				 errmsg("access method \"%s\" does not exist",
 						accessMethodName)));
-	accessMethodId = HeapTupleGetOid(tuple);
 	accessMethodForm = (Form_pg_am) GETSTRUCT(tuple);
+	accessMethodId = accessMethodForm->oid;
 	amRoutine = GetIndexAmRoutine(accessMethodForm->amhandler);
 	ReleaseSysCache(tuple);
 
@@ -583,8 +583,8 @@ DefineIndex(Oid relationId,
 					 errmsg("access method \"%s\" does not exist",
 							accessMethodName)));
 	}
-	accessMethodId = HeapTupleGetOid(tuple);
 	accessMethodForm = (Form_pg_am) GETSTRUCT(tuple);
+	accessMethodId = accessMethodForm->oid;
 	amRoutine = GetIndexAmRoutine(accessMethodForm->amhandler);
 
 	if (stmt->unique && !amRoutine->amcanunique)
@@ -748,17 +748,19 @@ DefineIndex(Oid relationId,
 
 
 	/*
-	 * We disallow indexes on system columns other than OID.  They would not
-	 * necessarily get updated correctly, and they don't seem useful anyway.
+	 * We disallow indexes on system columns.  They would not necessarily get
+	 * updated correctly, and they don't seem useful anyway.
 	 */
 	for (i = 0; i < indexInfo->ii_NumIndexAttrs; i++)
 	{
 		AttrNumber	attno = indexInfo->ii_IndexAttrNumbers[i];
 
-		if (attno < 0 && attno != ObjectIdAttributeNumber)
+		if (attno < 0)
+		{
 			ereport(ERROR,
 					(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
 					 errmsg("index creation on system columns is not supported")));
+		}
 	}
 
 	/*
@@ -773,8 +775,7 @@ DefineIndex(Oid relationId,
 
 		for (i = FirstLowInvalidHeapAttributeNumber + 1; i < 0; i++)
 		{
-			if (i != ObjectIdAttributeNumber &&
-				bms_is_member(i - FirstLowInvalidHeapAttributeNumber,
+			if (bms_is_member(i - FirstLowInvalidHeapAttributeNumber,
 							  indexattrs))
 				ereport(ERROR,
 						(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
@@ -1712,6 +1713,7 @@ ResolveOpClass(List *opclass, Oid attrType,
 	char	   *schemaname;
 	char	   *opcname;
 	HeapTuple	tuple;
+	Form_pg_opclass opform;
 	Oid			opClassId,
 				opInputType;
 
@@ -1796,8 +1798,9 @@ ResolveOpClass(List *opclass, Oid attrType,
 	 * Verify that the index operator class accepts this datatype.  Note we
 	 * will accept binary compatibility.
 	 */
-	opClassId = HeapTupleGetOid(tuple);
-	opInputType = ((Form_pg_opclass) GETSTRUCT(tuple))->opcintype;
+	opform = (Form_pg_opclass) GETSTRUCT(tuple);
+	opClassId = opform->oid;
+	opInputType = opform->opcintype;
 
 	if (!IsBinaryCoercible(attrType, opInputType))
 		ereport(ERROR,
@@ -1866,7 +1869,7 @@ GetDefaultOpClass(Oid type_id, Oid am_id)
 		if (opclass->opcintype == type_id)
 		{
 			nexact++;
-			result = HeapTupleGetOid(tup);
+			result = opclass->oid;
 		}
 		else if (nexact == 0 &&
 				 IsBinaryCoercible(type_id, opclass->opcintype))
@@ -1874,12 +1877,12 @@ GetDefaultOpClass(Oid type_id, Oid am_id)
 			if (IsPreferredType(tcategory, opclass->opcintype))
 			{
 				ncompatiblepreferred++;
-				result = HeapTupleGetOid(tup);
+				result = opclass->oid;
 			}
 			else if (ncompatiblepreferred == 0)
 			{
 				ncompatible++;
-				result = HeapTupleGetOid(tup);
+				result = opclass->oid;
 			}
 		}
 	}
@@ -2405,7 +2408,7 @@ ReindexMultipleTables(const char *objectName, ReindexObjectType objectKind,
 	while ((tuple = heap_getnext(scan, ForwardScanDirection)) != NULL)
 	{
 		Form_pg_class classtuple = (Form_pg_class) GETSTRUCT(tuple);
-		Oid			relid = HeapTupleGetOid(tuple);
+		Oid			relid = classtuple->oid;
 
 		/*
 		 * Only regular tables and matviews can have indexes, so ignore any
diff --git a/src/backend/commands/matview.c b/src/backend/commands/matview.c
index e1eb7c374b8..4736eb2483c 100644
--- a/src/backend/commands/matview.c
+++ b/src/backend/commands/matview.c
@@ -184,9 +184,6 @@ ExecRefreshMatView(RefreshMatViewStmt *stmt, const char *queryString,
 				(errcode(ERRCODE_SYNTAX_ERROR),
 				 errmsg("CONCURRENTLY and WITH NO DATA options cannot be used together")));
 
-	/* We don't allow an oid column for a materialized view. */
-	Assert(!matviewRel->rd_rel->relhasoids);
-
 	/*
 	 * Check that everything is correct for a refresh. Problems at this point
 	 * are internal errors, so elog is sufficient.
@@ -408,7 +405,7 @@ refresh_matview_datafill(DestReceiver *dest, Query *query,
 								dest, NULL, NULL, 0);
 
 	/* call ExecutorStart to prepare the plan for execution */
-	ExecutorStart(queryDesc, EXEC_FLAG_WITHOUT_OIDS);
+	ExecutorStart(queryDesc, 0);
 
 	/* run the plan */
 	ExecutorRun(queryDesc, ForwardScanDirection, 0L, true);
diff --git a/src/backend/commands/opclasscmds.c b/src/backend/commands/opclasscmds.c
index 3b5c90e3f41..2a2fdd0a0d8 100644
--- a/src/backend/commands/opclasscmds.c
+++ b/src/backend/commands/opclasscmds.c
@@ -23,6 +23,7 @@
 #include "access/nbtree.h"
 #include "access/htup_details.h"
 #include "access/sysattr.h"
+#include "catalog/catalog.h"
 #include "catalog/dependency.h"
 #include "catalog/indexing.h"
 #include "catalog/objectaccess.h"
@@ -142,12 +143,14 @@ Oid
 get_opfamily_oid(Oid amID, List *opfamilyname, bool missing_ok)
 {
 	HeapTuple	htup;
+	Form_pg_opfamily opfamform;
 	Oid			opfID;
 
 	htup = OpFamilyCacheLookup(amID, opfamilyname, missing_ok);
 	if (!HeapTupleIsValid(htup))
 		return InvalidOid;
-	opfID = HeapTupleGetOid(htup);
+	opfamform = (Form_pg_opfamily) GETSTRUCT(htup);
+	opfID = opfamform->oid;
 	ReleaseSysCache(htup);
 
 	return opfID;
@@ -221,12 +224,14 @@ Oid
 get_opclass_oid(Oid amID, List *opclassname, bool missing_ok)
 {
 	HeapTuple	htup;
+	Form_pg_opclass opcform;
 	Oid			opcID;
 
 	htup = OpClassCacheLookup(amID, opclassname, missing_ok);
 	if (!HeapTupleIsValid(htup))
 		return InvalidOid;
-	opcID = HeapTupleGetOid(htup);
+	opcform = (Form_pg_opclass) GETSTRUCT(htup);
+	opcID = opcform->oid;
 	ReleaseSysCache(htup);
 
 	return opcID;
@@ -271,6 +276,8 @@ CreateOpFamily(const char *amname, const char *opfname, Oid namespaceoid, Oid am
 	memset(values, 0, sizeof(values));
 	memset(nulls, false, sizeof(nulls));
 
+	opfamilyoid = GetNewOidWithIndex(rel, OpfamilyOidIndexId, Anum_pg_opfamily_oid);
+	values[Anum_pg_opfamily_oid - 1] = ObjectIdGetDatum(opfamilyoid);
 	values[Anum_pg_opfamily_opfmethod - 1] = ObjectIdGetDatum(amoid);
 	namestrcpy(&opfName, opfname);
 	values[Anum_pg_opfamily_opfname - 1] = NameGetDatum(&opfName);
@@ -279,7 +286,7 @@ CreateOpFamily(const char *amname, const char *opfname, Oid namespaceoid, Oid am
 
 	tup = heap_form_tuple(rel->rd_att, values, nulls);
 
-	opfamilyoid = CatalogTupleInsert(rel, tup);
+	CatalogTupleInsert(rel, tup);
 
 	heap_freetuple(tup);
 
@@ -338,6 +345,7 @@ DefineOpClass(CreateOpClassStmt *stmt)
 	ListCell   *l;
 	Relation	rel;
 	HeapTuple	tup;
+	Form_pg_am	amform;
 	IndexAmRoutine *amroutine;
 	Datum		values[Natts_pg_opclass];
 	bool		nulls[Natts_pg_opclass];
@@ -364,7 +372,8 @@ DefineOpClass(CreateOpClassStmt *stmt)
 				 errmsg("access method \"%s\" does not exist",
 						stmt->amname)));
 
-	amoid = HeapTupleGetOid(tup);
+	amform = (Form_pg_am) GETSTRUCT(tup);
+	amoid = amform->oid;
 	amroutine = GetIndexAmRoutineByAmId(amoid, false);
 	ReleaseSysCache(tup);
 
@@ -429,7 +438,7 @@ DefineOpClass(CreateOpClassStmt *stmt)
 							  ObjectIdGetDatum(namespaceoid));
 		if (HeapTupleIsValid(tup))
 		{
-			opfamilyoid = HeapTupleGetOid(tup);
+			opfamilyoid = ((Form_pg_opfamily) GETSTRUCT(tup))->oid;
 
 			/*
 			 * XXX given the superuser check above, there's no need for an
@@ -633,6 +642,8 @@ DefineOpClass(CreateOpClassStmt *stmt)
 	memset(values, 0, sizeof(values));
 	memset(nulls, false, sizeof(nulls));
 
+	opclassoid = GetNewOidWithIndex(rel, OpclassOidIndexId, Anum_pg_opclass_oid);
+	values[Anum_pg_opclass_oid - 1] = ObjectIdGetDatum(opclassoid);
 	values[Anum_pg_opclass_opcmethod - 1] = ObjectIdGetDatum(amoid);
 	namestrcpy(&opcName, opcname);
 	values[Anum_pg_opclass_opcname - 1] = NameGetDatum(&opcName);
@@ -645,7 +656,7 @@ DefineOpClass(CreateOpClassStmt *stmt)
 
 	tup = heap_form_tuple(rel->rd_att, values, nulls);
 
-	opclassoid = CatalogTupleInsert(rel, tup);
+	CatalogTupleInsert(rel, tup);
 
 	heap_freetuple(tup);
 
@@ -768,6 +779,7 @@ AlterOpFamily(AlterOpFamilyStmt *stmt)
 	int			maxOpNumber,	/* amstrategies value */
 				maxProcNumber;	/* amsupport value */
 	HeapTuple	tup;
+	Form_pg_am	amform;
 	IndexAmRoutine *amroutine;
 
 	/* Get necessary info about access method */
@@ -778,7 +790,8 @@ AlterOpFamily(AlterOpFamilyStmt *stmt)
 				 errmsg("access method \"%s\" does not exist",
 						stmt->amname)));
 
-	amoid = HeapTupleGetOid(tup);
+	amform = (Form_pg_am) GETSTRUCT(tup);
+	amoid = amform->oid;
 	amroutine = GetIndexAmRoutineByAmId(amoid, false);
 	ReleaseSysCache(tup);
 
@@ -1333,6 +1346,8 @@ storeOperators(List *opfamilyname, Oid amoid,
 		memset(values, 0, sizeof(values));
 		memset(nulls, false, sizeof(nulls));
 
+		entryoid = GetNewOidWithIndex(rel, AccessMethodOperatorOidIndexId, Anum_pg_amop_oid);
+		values[Anum_pg_amop_oid - 1] = ObjectIdGetDatum(entryoid);
 		values[Anum_pg_amop_amopfamily - 1] = ObjectIdGetDatum(opfamilyoid);
 		values[Anum_pg_amop_amoplefttype - 1] = ObjectIdGetDatum(op->lefttype);
 		values[Anum_pg_amop_amoprighttype - 1] = ObjectIdGetDatum(op->righttype);
@@ -1344,7 +1359,7 @@ storeOperators(List *opfamilyname, Oid amoid,
 
 		tup = heap_form_tuple(rel->rd_att, values, nulls);
 
-		entryoid = CatalogTupleInsert(rel, tup);
+		CatalogTupleInsert(rel, tup);
 
 		heap_freetuple(tup);
 
@@ -1445,6 +1460,8 @@ storeProcedures(List *opfamilyname, Oid amoid,
 		memset(values, 0, sizeof(values));
 		memset(nulls, false, sizeof(nulls));
 
+		entryoid = GetNewOidWithIndex(rel, AccessMethodProcedureOidIndexId, Anum_pg_amproc_oid);
+		values[Anum_pg_amproc_oid - 1] = ObjectIdGetDatum(entryoid);
 		values[Anum_pg_amproc_amprocfamily - 1] = ObjectIdGetDatum(opfamilyoid);
 		values[Anum_pg_amproc_amproclefttype - 1] = ObjectIdGetDatum(proc->lefttype);
 		values[Anum_pg_amproc_amprocrighttype - 1] = ObjectIdGetDatum(proc->righttype);
@@ -1453,7 +1470,7 @@ storeProcedures(List *opfamilyname, Oid amoid,
 
 		tup = heap_form_tuple(rel->rd_att, values, nulls);
 
-		entryoid = CatalogTupleInsert(rel, tup);
+		CatalogTupleInsert(rel, tup);
 
 		heap_freetuple(tup);
 
@@ -1627,7 +1644,7 @@ RemoveAmOpEntryById(Oid entryOid)
 	SysScanDesc scan;
 
 	ScanKeyInit(&skey[0],
-				ObjectIdAttributeNumber,
+				Anum_pg_amop_oid,
 				BTEqualStrategyNumber, F_OIDEQ,
 				ObjectIdGetDatum(entryOid));
 
@@ -1656,7 +1673,7 @@ RemoveAmProcEntryById(Oid entryOid)
 	SysScanDesc scan;
 
 	ScanKeyInit(&skey[0],
-				ObjectIdAttributeNumber,
+				Anum_pg_amproc_oid,
 				BTEqualStrategyNumber, F_OIDEQ,
 				ObjectIdGetDatum(entryOid));
 
diff --git a/src/backend/commands/policy.c b/src/backend/commands/policy.c
index 2fd17b24b9e..3c19518c312 100644
--- a/src/backend/commands/policy.c
+++ b/src/backend/commands/policy.c
@@ -365,7 +365,7 @@ RemovePolicyById(Oid policy_id)
 	 * Find the policy to delete.
 	 */
 	ScanKeyInit(&skey[0],
-				ObjectIdAttributeNumber,
+				Anum_pg_policy_oid,
 				BTEqualStrategyNumber, F_OIDEQ,
 				ObjectIdGetDatum(policy_id));
 
@@ -457,7 +457,7 @@ RemoveRoleFromObjectPolicy(Oid roleid, Oid classid, Oid policy_id)
 	 * Find the policy to update.
 	 */
 	ScanKeyInit(&skey[0],
-				ObjectIdAttributeNumber,
+				Anum_pg_policy_oid,
 				BTEqualStrategyNumber, F_OIDEQ,
 				ObjectIdGetDatum(policy_id));
 
@@ -807,6 +807,8 @@ CreatePolicy(CreatePolicyStmt *stmt)
 				 errmsg("policy \"%s\" for table \"%s\" already exists",
 						stmt->policy_name, RelationGetRelationName(target_table))));
 
+	policy_id = GetNewOidWithIndex(pg_policy_rel, PolicyOidIndexId, Anum_pg_policy_oid);
+	values[Anum_pg_policy_oid - 1] = ObjectIdGetDatum(policy_id);
 	values[Anum_pg_policy_polrelid - 1] = ObjectIdGetDatum(table_id);
 	values[Anum_pg_policy_polname - 1] = DirectFunctionCall1(namein,
 															 CStringGetDatum(stmt->policy_name));
@@ -829,7 +831,7 @@ CreatePolicy(CreatePolicyStmt *stmt)
 	policy_tuple = heap_form_tuple(RelationGetDescr(pg_policy_rel), values,
 								   isnull);
 
-	policy_id = CatalogTupleInsert(pg_policy_rel, policy_tuple);
+	CatalogTupleInsert(pg_policy_rel, policy_tuple);
 
 	/* Record Dependencies */
 	target.classId = RelationRelationId;
@@ -1033,7 +1035,7 @@ AlterPolicy(AlterPolicyStmt *stmt)
 				(errcode(ERRCODE_SYNTAX_ERROR),
 				 errmsg("only WITH CHECK expression allowed for INSERT")));
 
-	policy_id = HeapTupleGetOid(policy_tuple);
+	policy_id = ((Form_pg_policy) GETSTRUCT(policy_tuple))->oid;
 
 	if (role_ids != NULL)
 	{
@@ -1284,7 +1286,7 @@ rename_policy(RenameStmt *stmt)
 				 errmsg("policy \"%s\" for table \"%s\" does not exist",
 						stmt->subname, RelationGetRelationName(target_table))));
 
-	opoloid = HeapTupleGetOid(policy_tuple);
+	opoloid = ((Form_pg_policy) GETSTRUCT(policy_tuple))->oid;
 
 	policy_tuple = heap_copytuple(policy_tuple);
 
@@ -1293,8 +1295,7 @@ rename_policy(RenameStmt *stmt)
 
 	CatalogTupleUpdate(pg_policy_rel, &policy_tuple->t_self, policy_tuple);
 
-	InvokeObjectPostAlterHook(PolicyRelationId,
-							  HeapTupleGetOid(policy_tuple), 0);
+	InvokeObjectPostAlterHook(PolicyRelationId, opoloid, 0);
 
 	ObjectAddressSet(address, PolicyRelationId, opoloid);
 
@@ -1359,7 +1360,7 @@ get_relation_policy_oid(Oid relid, const char *policy_name, bool missing_ok)
 		policy_oid = InvalidOid;
 	}
 	else
-		policy_oid = HeapTupleGetOid(policy_tuple);
+		policy_oid = ((Form_pg_policy) GETSTRUCT(policy_tuple))->oid;
 
 	/* Clean up. */
 	systable_endscan(sscan);
diff --git a/src/backend/commands/prepare.c b/src/backend/commands/prepare.c
index b945b1556a8..6036b735e9f 100644
--- a/src/backend/commands/prepare.c
+++ b/src/backend/commands/prepare.c
@@ -734,7 +734,7 @@ pg_prepared_statement(PG_FUNCTION_ARGS)
 	 * build tupdesc for result tuples. This must match the definition of the
 	 * pg_prepared_statements view in system_views.sql
 	 */
-	tupdesc = CreateTemplateTupleDesc(5, false);
+	tupdesc = CreateTemplateTupleDesc(5);
 	TupleDescInitEntry(tupdesc, (AttrNumber) 1, "name",
 					   TEXTOID, -1, 0);
 	TupleDescInitEntry(tupdesc, (AttrNumber) 2, "statement",
diff --git a/src/backend/commands/proclang.c b/src/backend/commands/proclang.c
index c900ad9431a..c1cb2435146 100644
--- a/src/backend/commands/proclang.c
+++ b/src/backend/commands/proclang.c
@@ -16,6 +16,7 @@
 #include "access/genam.h"
 #include "access/heapam.h"
 #include "access/htup_details.h"
+#include "catalog/catalog.h"
 #include "catalog/dependency.h"
 #include "catalog/indexing.h"
 #include "catalog/objectaccess.h"
@@ -329,6 +330,7 @@ create_proc_lang(const char *languageName, bool replace,
 	NameData	langname;
 	HeapTuple	oldtup;
 	HeapTuple	tup;
+	Oid			langoid;
 	bool		is_update;
 	ObjectAddress myself,
 				referenced;
@@ -356,12 +358,14 @@ create_proc_lang(const char *languageName, bool replace,
 
 	if (HeapTupleIsValid(oldtup))
 	{
+		Form_pg_language oldform = (Form_pg_language) GETSTRUCT(oldtup);
+
 		/* There is one; okay to replace it? */
 		if (!replace)
 			ereport(ERROR,
 					(errcode(ERRCODE_DUPLICATE_OBJECT),
 					 errmsg("language \"%s\" already exists", languageName)));
-		if (!pg_language_ownercheck(HeapTupleGetOid(oldtup), languageOwner))
+		if (!pg_language_ownercheck(oldform->oid, languageOwner))
 			aclcheck_error(ACLCHECK_NOT_OWNER, OBJECT_LANGUAGE,
 						   languageName);
 
@@ -376,12 +380,15 @@ create_proc_lang(const char *languageName, bool replace,
 		tup = heap_modify_tuple(oldtup, tupDesc, values, nulls, replaces);
 		CatalogTupleUpdate(rel, &tup->t_self, tup);
 
+		langoid = oldform->oid;
 		ReleaseSysCache(oldtup);
 		is_update = true;
 	}
 	else
 	{
 		/* Creating a new language */
+		langoid = GetNewOidWithIndex(rel, LanguageOidIndexId, Anum_pg_language_oid);
+		values[Anum_pg_language_oid - 1] = langoid;
 		tup = heap_form_tuple(tupDesc, values, nulls);
 		CatalogTupleInsert(rel, tup);
 		is_update = false;
@@ -394,7 +401,7 @@ create_proc_lang(const char *languageName, bool replace,
 	 * shared dependencies do *not* need to change, and we leave them alone.)
 	 */
 	myself.classId = LanguageRelationId;
-	myself.objectId = HeapTupleGetOid(tup);
+	myself.objectId = langoid;
 	myself.objectSubId = 0;
 
 	if (is_update)
diff --git a/src/backend/commands/publicationcmds.c b/src/backend/commands/publicationcmds.c
index 6f7762a906c..38a98217698 100644
--- a/src/backend/commands/publicationcmds.c
+++ b/src/backend/commands/publicationcmds.c
@@ -189,7 +189,8 @@ CreatePublication(CreatePublicationStmt *stmt)
 							  &publish_given, &publish_insert,
 							  &publish_update, &publish_delete,
 							  &publish_truncate);
-
+	puboid = GetNewOidWithIndex(rel, PublicationObjectIndexId, Anum_pg_publication_oid);
+	values[Anum_pg_publication_oid - 1] = ObjectIdGetDatum(puboid);
 	values[Anum_pg_publication_puballtables - 1] =
 		BoolGetDatum(stmt->for_all_tables);
 	values[Anum_pg_publication_pubinsert - 1] =
@@ -204,7 +205,7 @@ CreatePublication(CreatePublicationStmt *stmt)
 	tup = heap_form_tuple(RelationGetDescr(rel), values, nulls);
 
 	/* Insert tuple into catalog. */
-	puboid = CatalogTupleInsert(rel, tup);
+	CatalogTupleInsert(rel, tup);
 	heap_freetuple(tup);
 
 	recordDependencyOnOwner(PublicationRelationId, puboid, GetUserId());
@@ -248,6 +249,7 @@ AlterPublicationOptions(AlterPublicationStmt *stmt, Relation rel,
 	bool		publish_delete;
 	bool		publish_truncate;
 	ObjectAddress obj;
+	Form_pg_publication pubform;
 
 	parse_publication_options(stmt->options,
 							  &publish_given, &publish_insert,
@@ -282,14 +284,16 @@ AlterPublicationOptions(AlterPublicationStmt *stmt, Relation rel,
 
 	CommandCounterIncrement();
 
+	pubform = (Form_pg_publication) GETSTRUCT(tup);
+
 	/* Invalidate the relcache. */
-	if (((Form_pg_publication) GETSTRUCT(tup))->puballtables)
+	if (pubform->puballtables)
 	{
 		CacheInvalidateRelcacheAll();
 	}
 	else
 	{
-		List	   *relids = GetPublicationRelations(HeapTupleGetOid(tup));
+		List	   *relids = GetPublicationRelations(pubform->oid);
 
 		/*
 		 * We don't want to send too many individual messages, at some point
@@ -310,11 +314,11 @@ AlterPublicationOptions(AlterPublicationStmt *stmt, Relation rel,
 			CacheInvalidateRelcacheAll();
 	}
 
-	ObjectAddressSet(obj, PublicationRelationId, HeapTupleGetOid(tup));
+	ObjectAddressSet(obj, PublicationRelationId, pubform->oid);
 	EventTriggerCollectSimpleCommand(obj, InvalidObjectAddress,
 									 (Node *) stmt);
 
-	InvokeObjectPostAlterHook(PublicationRelationId, HeapTupleGetOid(tup), 0);
+	InvokeObjectPostAlterHook(PublicationRelationId, pubform->oid, 0);
 }
 
 /*
@@ -324,9 +328,9 @@ static void
 AlterPublicationTables(AlterPublicationStmt *stmt, Relation rel,
 					   HeapTuple tup)
 {
-	Oid			pubid = HeapTupleGetOid(tup);
 	List	   *rels = NIL;
 	Form_pg_publication pubform = (Form_pg_publication) GETSTRUCT(tup);
+	Oid			pubid = pubform->oid;
 
 	/* Check that user is allowed to manipulate the publication tables. */
 	if (pubform->puballtables)
@@ -403,6 +407,7 @@ AlterPublication(AlterPublicationStmt *stmt)
 {
 	Relation	rel;
 	HeapTuple	tup;
+	Form_pg_publication pubform;
 
 	rel = heap_open(PublicationRelationId, RowExclusiveLock);
 
@@ -415,8 +420,10 @@ AlterPublication(AlterPublicationStmt *stmt)
 				 errmsg("publication \"%s\" does not exist",
 						stmt->pubname)));
 
+	pubform = (Form_pg_publication) GETSTRUCT(tup);
+
 	/* must be owner */
-	if (!pg_publication_ownercheck(HeapTupleGetOid(tup), GetUserId()))
+	if (!pg_publication_ownercheck(pubform->oid, GetUserId()))
 		aclcheck_error(ACLCHECK_NOT_OWNER, OBJECT_PUBLICATION,
 					   stmt->pubname);
 
@@ -662,7 +669,7 @@ AlterPublicationOwner_internal(Relation rel, HeapTuple tup, Oid newOwnerId)
 		AclResult	aclresult;
 
 		/* Must be owner */
-		if (!pg_publication_ownercheck(HeapTupleGetOid(tup), GetUserId()))
+		if (!pg_publication_ownercheck(form->oid, GetUserId()))
 			aclcheck_error(ACLCHECK_NOT_OWNER, OBJECT_PUBLICATION,
 						   NameStr(form->pubname));
 
@@ -688,11 +695,11 @@ AlterPublicationOwner_internal(Relation rel, HeapTuple tup, Oid newOwnerId)
 
 	/* Update owner dependency reference */
 	changeDependencyOnOwner(PublicationRelationId,
-							HeapTupleGetOid(tup),
+							form->oid,
 							newOwnerId);
 
 	InvokeObjectPostAlterHook(PublicationRelationId,
-							  HeapTupleGetOid(tup), 0);
+							  form->oid, 0);
 }
 
 /*
@@ -705,6 +712,7 @@ AlterPublicationOwner(const char *name, Oid newOwnerId)
 	HeapTuple	tup;
 	Relation	rel;
 	ObjectAddress address;
+	Form_pg_publication pubform;
 
 	rel = heap_open(PublicationRelationId, RowExclusiveLock);
 
@@ -715,7 +723,8 @@ AlterPublicationOwner(const char *name, Oid newOwnerId)
 				(errcode(ERRCODE_UNDEFINED_OBJECT),
 				 errmsg("publication \"%s\" does not exist", name)));
 
-	subid = HeapTupleGetOid(tup);
+	pubform = (Form_pg_publication) GETSTRUCT(tup);
+	subid = pubform->oid;
 
 	AlterPublicationOwner_internal(rel, tup, newOwnerId);
 
diff --git a/src/backend/commands/schemacmds.c b/src/backend/commands/schemacmds.c
index dc6cb46e4e7..f0ebe2d1c31 100644
--- a/src/backend/commands/schemacmds.c
+++ b/src/backend/commands/schemacmds.c
@@ -246,6 +246,7 @@ RenameSchema(const char *oldname, const char *newname)
 	Relation	rel;
 	AclResult	aclresult;
 	ObjectAddress address;
+	Form_pg_namespace nspform;
 
 	rel = heap_open(NamespaceRelationId, RowExclusiveLock);
 
@@ -255,7 +256,8 @@ RenameSchema(const char *oldname, const char *newname)
 				(errcode(ERRCODE_UNDEFINED_SCHEMA),
 				 errmsg("schema \"%s\" does not exist", oldname)));
 
-	nspOid = HeapTupleGetOid(tup);
+	nspform = (Form_pg_namespace) GETSTRUCT(tup);
+	nspOid = nspform->oid;
 
 	/* make sure the new name doesn't exist */
 	if (OidIsValid(get_namespace_oid(newname, true)))
@@ -264,7 +266,7 @@ RenameSchema(const char *oldname, const char *newname)
 				 errmsg("schema \"%s\" already exists", newname)));
 
 	/* must be owner */
-	if (!pg_namespace_ownercheck(HeapTupleGetOid(tup), GetUserId()))
+	if (!pg_namespace_ownercheck(nspOid, GetUserId()))
 		aclcheck_error(ACLCHECK_NOT_OWNER, OBJECT_SCHEMA,
 					   oldname);
 
@@ -281,10 +283,10 @@ RenameSchema(const char *oldname, const char *newname)
 				 errdetail("The prefix \"pg_\" is reserved for system schemas.")));
 
 	/* rename */
-	namestrcpy(&(((Form_pg_namespace) GETSTRUCT(tup))->nspname), newname);
+	namestrcpy(&nspform->nspname, newname);
 	CatalogTupleUpdate(rel, &tup->t_self, tup);
 
-	InvokeObjectPostAlterHook(NamespaceRelationId, HeapTupleGetOid(tup), 0);
+	InvokeObjectPostAlterHook(NamespaceRelationId, nspOid, 0);
 
 	ObjectAddressSet(address, NamespaceRelationId, nspOid);
 
@@ -324,6 +326,7 @@ AlterSchemaOwner(const char *name, Oid newOwnerId)
 	HeapTuple	tup;
 	Relation	rel;
 	ObjectAddress address;
+	Form_pg_namespace nspform;
 
 	rel = heap_open(NamespaceRelationId, RowExclusiveLock);
 
@@ -333,7 +336,8 @@ AlterSchemaOwner(const char *name, Oid newOwnerId)
 				(errcode(ERRCODE_UNDEFINED_SCHEMA),
 				 errmsg("schema \"%s\" does not exist", name)));
 
-	nspOid = HeapTupleGetOid(tup);
+	nspform = (Form_pg_namespace) GETSTRUCT(tup);
+	nspOid = nspform->oid;
 
 	AlterSchemaOwner_internal(tup, rel, newOwnerId);
 
@@ -372,7 +376,7 @@ AlterSchemaOwner_internal(HeapTuple tup, Relation rel, Oid newOwnerId)
 		AclResult	aclresult;
 
 		/* Otherwise, must be owner of the existing object */
-		if (!pg_namespace_ownercheck(HeapTupleGetOid(tup), GetUserId()))
+		if (!pg_namespace_ownercheck(nspForm->oid, GetUserId()))
 			aclcheck_error(ACLCHECK_NOT_OWNER, OBJECT_SCHEMA,
 						   NameStr(nspForm->nspname));
 
@@ -422,10 +426,10 @@ AlterSchemaOwner_internal(HeapTuple tup, Relation rel, Oid newOwnerId)
 		heap_freetuple(newtuple);
 
 		/* Update owner dependency reference */
-		changeDependencyOnOwner(NamespaceRelationId, HeapTupleGetOid(tup),
+		changeDependencyOnOwner(NamespaceRelationId, nspForm->oid,
 								newOwnerId);
 	}
 
 	InvokeObjectPostAlterHook(NamespaceRelationId,
-							  HeapTupleGetOid(tup), 0);
+							  nspForm->oid, 0);
 }
diff --git a/src/backend/commands/seclabel.c b/src/backend/commands/seclabel.c
index 1ac7756f2a5..330b11c95ab 100644
--- a/src/backend/commands/seclabel.c
+++ b/src/backend/commands/seclabel.c
@@ -264,6 +264,7 @@ SetSharedSecurityLabel(const ObjectAddress *object,
 	/* Prepare to form or update a tuple, if necessary. */
 	memset(nulls, false, sizeof(nulls));
 	memset(replaces, false, sizeof(replaces));
+
 	values[Anum_pg_shseclabel_objoid - 1] = ObjectIdGetDatum(object->objectId);
 	values[Anum_pg_shseclabel_classoid - 1] = ObjectIdGetDatum(object->classId);
 	values[Anum_pg_shseclabel_provider - 1] = CStringGetTextDatum(provider);
diff --git a/src/backend/commands/sequence.c b/src/backend/commands/sequence.c
index 6d89925b237..f9dca39d3db 100644
--- a/src/backend/commands/sequence.c
+++ b/src/backend/commands/sequence.c
@@ -1788,7 +1788,7 @@ pg_sequence_parameters(PG_FUNCTION_ARGS)
 				 errmsg("permission denied for sequence %s",
 						get_rel_name(relid))));
 
-	tupdesc = CreateTemplateTupleDesc(7, false);
+	tupdesc = CreateTemplateTupleDesc(7);
 	TupleDescInitEntry(tupdesc, (AttrNumber) 1, "start_value",
 					   INT8OID, -1, 0);
 	TupleDescInitEntry(tupdesc, (AttrNumber) 2, "minimum_value",
diff --git a/src/backend/commands/statscmds.c b/src/backend/commands/statscmds.c
index 3bb0d24cd20..6be2d9b31c5 100644
--- a/src/backend/commands/statscmds.c
+++ b/src/backend/commands/statscmds.c
@@ -15,6 +15,7 @@
 #include "postgres.h"
 
 #include "access/relscan.h"
+#include "catalog/catalog.h"
 #include "catalog/dependency.h"
 #include "catalog/indexing.h"
 #include "catalog/namespace.h"
@@ -305,11 +306,16 @@ CreateStatistics(CreateStatsStmt *stmt)
 	Assert(ntypes > 0 && ntypes <= lengthof(types));
 	stxkind = construct_array(types, ntypes, CHAROID, 1, true, 'c');
 
+	statrel = heap_open(StatisticExtRelationId, RowExclusiveLock);
+
 	/*
 	 * Everything seems fine, so let's build the pg_statistic_ext tuple.
 	 */
 	memset(values, 0, sizeof(values));
 	memset(nulls, false, sizeof(nulls));
+
+	statoid = GetNewOidWithIndex(statrel, StatisticExtOidIndexId, Anum_pg_statistic_ext_oid);
+	values[Anum_pg_statistic_ext_oid - 1] = ObjectIdGetDatum(statoid);
 	values[Anum_pg_statistic_ext_stxrelid - 1] = ObjectIdGetDatum(relid);
 	values[Anum_pg_statistic_ext_stxname - 1] = NameGetDatum(&stxname);
 	values[Anum_pg_statistic_ext_stxnamespace - 1] = ObjectIdGetDatum(namespaceId);
@@ -322,10 +328,10 @@ CreateStatistics(CreateStatsStmt *stmt)
 	nulls[Anum_pg_statistic_ext_stxdependencies - 1] = true;
 
 	/* insert it into pg_statistic_ext */
-	statrel = heap_open(StatisticExtRelationId, RowExclusiveLock);
 	htup = heap_form_tuple(statrel->rd_att, values, nulls);
-	statoid = CatalogTupleInsert(statrel, htup);
+	CatalogTupleInsert(statrel, htup);
 	heap_freetuple(htup);
+
 	relation_close(statrel, RowExclusiveLock);
 
 	/*
diff --git a/src/backend/commands/subscriptioncmds.c b/src/backend/commands/subscriptioncmds.c
index f138e61a8d3..bc26a5149bb 100644
--- a/src/backend/commands/subscriptioncmds.c
+++ b/src/backend/commands/subscriptioncmds.c
@@ -20,6 +20,7 @@
 #include "access/htup_details.h"
 #include "access/xact.h"
 
+#include "catalog/catalog.h"
 #include "catalog/dependency.h"
 #include "catalog/indexing.h"
 #include "catalog/namespace.h"
@@ -379,6 +380,8 @@ CreateSubscription(CreateSubscriptionStmt *stmt, bool isTopLevel)
 	memset(values, 0, sizeof(values));
 	memset(nulls, false, sizeof(nulls));
 
+	subid = GetNewOidWithIndex(rel, SubscriptionObjectIndexId, Anum_pg_subscription_oid);
+	values[Anum_pg_subscription_oid - 1] = ObjectIdGetDatum(subid);
 	values[Anum_pg_subscription_subdbid - 1] = ObjectIdGetDatum(MyDatabaseId);
 	values[Anum_pg_subscription_subname - 1] =
 		DirectFunctionCall1(namein, CStringGetDatum(stmt->subname));
@@ -399,7 +402,7 @@ CreateSubscription(CreateSubscriptionStmt *stmt, bool isTopLevel)
 	tup = heap_form_tuple(RelationGetDescr(rel), values, nulls);
 
 	/* Insert tuple into catalog. */
-	subid = CatalogTupleInsert(rel, tup);
+	CatalogTupleInsert(rel, tup);
 	heap_freetuple(tup);
 
 	recordDependencyOnOwner(SubscriptionRelationId, subid, owner);
@@ -620,6 +623,7 @@ AlterSubscription(AlterSubscriptionStmt *stmt)
 	Oid			subid;
 	bool		update_tuple = false;
 	Subscription *sub;
+	Form_pg_subscription form;
 
 	rel = heap_open(SubscriptionRelationId, RowExclusiveLock);
 
@@ -633,12 +637,14 @@ AlterSubscription(AlterSubscriptionStmt *stmt)
 				 errmsg("subscription \"%s\" does not exist",
 						stmt->subname)));
 
+	form = (Form_pg_subscription) GETSTRUCT(tup);
+	subid = form->oid;
+
 	/* must be owner */
-	if (!pg_subscription_ownercheck(HeapTupleGetOid(tup), GetUserId()))
+	if (!pg_subscription_ownercheck(subid, GetUserId()))
 		aclcheck_error(ACLCHECK_NOT_OWNER, OBJECT_SUBSCRIPTION,
 					   stmt->subname);
 
-	subid = HeapTupleGetOid(tup);
 	sub = GetSubscription(subid, false);
 
 	/* Lock the subscription so nobody else can do anything with it. */
@@ -823,6 +829,7 @@ DropSubscription(DropSubscriptionStmt *stmt, bool isTopLevel)
 	RepOriginId originid;
 	WalReceiverConn *wrconn = NULL;
 	StringInfoData cmd;
+	Form_pg_subscription form;
 
 	/*
 	 * Lock pg_subscription with AccessExclusiveLock to ensure that the
@@ -850,7 +857,8 @@ DropSubscription(DropSubscriptionStmt *stmt, bool isTopLevel)
 		return;
 	}
 
-	subid = HeapTupleGetOid(tup);
+	form = (Form_pg_subscription) GETSTRUCT(tup);
+	subid = form->oid;
 
 	/* must be owner */
 	if (!pg_subscription_ownercheck(subid, GetUserId()))
@@ -1021,7 +1029,7 @@ AlterSubscriptionOwner_internal(Relation rel, HeapTuple tup, Oid newOwnerId)
 	if (form->subowner == newOwnerId)
 		return;
 
-	if (!pg_subscription_ownercheck(HeapTupleGetOid(tup), GetUserId()))
+	if (!pg_subscription_ownercheck(form->oid, GetUserId()))
 		aclcheck_error(ACLCHECK_NOT_OWNER, OBJECT_SUBSCRIPTION,
 					   NameStr(form->subname));
 
@@ -1038,11 +1046,11 @@ AlterSubscriptionOwner_internal(Relation rel, HeapTuple tup, Oid newOwnerId)
 
 	/* Update owner dependency reference */
 	changeDependencyOnOwner(SubscriptionRelationId,
-							HeapTupleGetOid(tup),
+							form->oid,
 							newOwnerId);
 
 	InvokeObjectPostAlterHook(SubscriptionRelationId,
-							  HeapTupleGetOid(tup), 0);
+							  form->oid, 0);
 }
 
 /*
@@ -1055,6 +1063,7 @@ AlterSubscriptionOwner(const char *name, Oid newOwnerId)
 	HeapTuple	tup;
 	Relation	rel;
 	ObjectAddress address;
+	Form_pg_subscription form;
 
 	rel = heap_open(SubscriptionRelationId, RowExclusiveLock);
 
@@ -1066,7 +1075,8 @@ AlterSubscriptionOwner(const char *name, Oid newOwnerId)
 				(errcode(ERRCODE_UNDEFINED_OBJECT),
 				 errmsg("subscription \"%s\" does not exist", name)));
 
-	subid = HeapTupleGetOid(tup);
+	form = (Form_pg_subscription) GETSTRUCT(tup);
+	subid = form->oid;
 
 	AlterSubscriptionOwner_internal(rel, tup, newOwnerId);
 
diff --git a/src/backend/commands/tablecmds.c b/src/backend/commands/tablecmds.c
index 73da6c39c22..57668aec0c3 100644
--- a/src/backend/commands/tablecmds.c
+++ b/src/backend/commands/tablecmds.c
@@ -305,8 +305,7 @@ static void truncate_check_activity(Relation rel);
 static void RangeVarCallbackForTruncate(const RangeVar *relation,
 							Oid relId, Oid oldRelId, void *arg);
 static List *MergeAttributes(List *schema, List *supers, char relpersistence,
-				bool is_partition, List **supOids, List **supconstr,
-				int *supOidCount);
+				bool is_partition, List **supOids, List **supconstr);
 static bool MergeCheckConstraint(List *constraints, char *name, Node *expr);
 static void MergeAttributesIntoExisting(Relation child_rel, Relation parent_rel);
 static void MergeConstraintsIntoExisting(Relation child_rel, Relation parent_rel);
@@ -363,15 +362,13 @@ static List *find_typed_table_dependencies(Oid typeOid, const char *typeName,
 static void ATPrepAddColumn(List **wqueue, Relation rel, bool recurse, bool recursing,
 				bool is_view, AlterTableCmd *cmd, LOCKMODE lockmode);
 static ObjectAddress ATExecAddColumn(List **wqueue, AlteredTableInfo *tab,
-				Relation rel, ColumnDef *colDef, bool isOid,
+				Relation rel, ColumnDef *colDef,
 				bool recurse, bool recursing,
 				bool if_not_exists, LOCKMODE lockmode);
 static bool check_for_column_name_collision(Relation rel, const char *colname,
 								bool if_not_exists);
 static void add_column_datatype_dependency(Oid relid, int32 attnum, Oid typid);
 static void add_column_collation_dependency(Oid relid, int32 attnum, Oid collid);
-static void ATPrepAddOids(List **wqueue, Relation rel, bool recurse,
-			  AlterTableCmd *cmd, LOCKMODE lockmode);
 static void ATPrepDropNotNull(Relation rel, bool recurse, bool recursing);
 static ObjectAddress ATExecDropNotNull(Relation rel, const char *colName, LOCKMODE lockmode);
 static void ATPrepSetNotNull(Relation rel, bool recurse, bool recursing);
@@ -531,8 +528,6 @@ DefineRelation(CreateStmt *stmt, char relkind, Oid ownerId,
 	TupleDesc	descriptor;
 	List	   *inheritOids;
 	List	   *old_constraints;
-	bool		localHasOids;
-	int			parentOidCount;
 	List	   *rawDefaults;
 	List	   *cookedDefaults;
 	Datum		reloptions;
@@ -654,7 +649,7 @@ DefineRelation(CreateStmt *stmt, char relkind, Oid ownerId,
 		MergeAttributes(stmt->tableElts, stmt->inhRelations,
 						stmt->relation->relpersistence,
 						stmt->partbound != NULL,
-						&inheritOids, &old_constraints, &parentOidCount);
+						&inheritOids, &old_constraints);
 
 	/*
 	 * Create a tuple descriptor from the relation schema.  Note that this
@@ -663,29 +658,6 @@ DefineRelation(CreateStmt *stmt, char relkind, Oid ownerId,
 	 */
 	descriptor = BuildDescForRelation(stmt->tableElts);
 
-	/*
-	 * Notice that we allow OIDs here only for plain tables and partitioned
-	 * tables, even though some other relkinds can support them.  This is
-	 * necessary because the default_with_oids GUC must apply only to plain
-	 * tables and not any other relkind; doing otherwise would break existing
-	 * pg_dump files.  We could allow explicit "WITH OIDS" while not allowing
-	 * default_with_oids to affect other relkinds, but it would complicate
-	 * interpretOidsOption().
-	 */
-	localHasOids = interpretOidsOption(stmt->options,
-									   (relkind == RELKIND_RELATION ||
-										relkind == RELKIND_PARTITIONED_TABLE));
-	descriptor->tdhasoid = (localHasOids || parentOidCount > 0);
-
-	/*
-	 * If a partitioned table doesn't have the system OID column, then none of
-	 * its partitions should have it.
-	 */
-	if (stmt->partbound && parentOidCount == 0 && localHasOids)
-		ereport(ERROR,
-				(errcode(ERRCODE_WRONG_OBJECT_TYPE),
-				 errmsg("cannot create table with OIDs as partition of table without OIDs")));
-
 	/*
 	 * Find columns with default values and prepare for insertion of the
 	 * defaults.  Pre-cooked (that is, inherited) defaults go into a list of
@@ -764,8 +736,6 @@ DefineRelation(CreateStmt *stmt, char relkind, Oid ownerId,
 										  stmt->relation->relpersistence,
 										  false,
 										  false,
-										  localHasOids,
-										  parentOidCount,
 										  stmt->oncommit,
 										  reloptions,
 										  true,
@@ -1816,7 +1786,6 @@ storage_name(char c)
  * 'supOids' receives a list of the OIDs of the parent relations.
  * 'supconstr' receives a list of constraints belonging to the parents,
  *		updated as necessary to be valid for the child.
- * 'supOidCount' is set to the number of parents that have OID columns.
  *
  * Return value:
  * Completed schema list.
@@ -1862,14 +1831,12 @@ storage_name(char c)
  */
 static List *
 MergeAttributes(List *schema, List *supers, char relpersistence,
-				bool is_partition, List **supOids, List **supconstr,
-				int *supOidCount)
+				bool is_partition, List **supOids, List **supconstr)
 {
 	ListCell   *entry;
 	List	   *inhSchema = NIL;
 	List	   *parentOids = NIL;
 	List	   *constraints = NIL;
-	int			parentsWithOids = 0;
 	bool		have_bogus_defaults = false;
 	int			child_attno;
 	static Node bogus_marker = {0}; /* marks conflicting defaults */
@@ -2077,9 +2044,6 @@ MergeAttributes(List *schema, List *supers, char relpersistence,
 
 		parentOids = lappend_oid(parentOids, RelationGetRelid(relation));
 
-		if (relation->rd_rel->relhasoids)
-			parentsWithOids++;
-
 		tupleDesc = RelationGetDescr(relation);
 		constr = tupleDesc->constr;
 
@@ -2498,7 +2462,6 @@ MergeAttributes(List *schema, List *supers, char relpersistence,
 
 	*supOids = parentOids;
 	*supconstr = constraints;
-	*supOidCount = parentsWithOids;
 	return schema;
 }
 
@@ -3424,7 +3387,6 @@ AlterTableGetLockLevel(List *cmds)
 								 * to SELECT */
 			case AT_SetTableSpace:	/* must rewrite heap */
 			case AT_AlterColumnType:	/* must rewrite heap */
-			case AT_AddOids:	/* must rewrite heap */
 				cmd_lockmode = AccessExclusiveLock;
 				break;
 
@@ -3453,7 +3415,6 @@ AlterTableGetLockLevel(List *cmds)
 				 */
 			case AT_DropColumn: /* change visible to SELECT */
 			case AT_AddColumnToView:	/* CREATE VIEW */
-			case AT_DropOids:	/* calls AT_DropColumn */
 			case AT_EnableAlwaysRule:	/* may change SELECT rules */
 			case AT_EnableReplicaRule:	/* may change SELECT rules */
 			case AT_EnableRule: /* may change SELECT rules */
@@ -3862,27 +3823,6 @@ ATPrepCmd(List **wqueue, Relation rel, AlterTableCmd *cmd,
 			}
 			pass = AT_PASS_MISC;
 			break;
-		case AT_AddOids:		/* SET WITH OIDS */
-			ATSimplePermissions(rel, ATT_TABLE | ATT_FOREIGN_TABLE);
-			if (!rel->rd_rel->relhasoids || recursing)
-				ATPrepAddOids(wqueue, rel, recurse, cmd, lockmode);
-			/* Recursion occurs during execution phase */
-			pass = AT_PASS_ADD_COL;
-			break;
-		case AT_DropOids:		/* SET WITHOUT OIDS */
-			ATSimplePermissions(rel, ATT_TABLE | ATT_FOREIGN_TABLE);
-			/* Performs own recursion */
-			if (rel->rd_rel->relhasoids)
-			{
-				AlterTableCmd *dropCmd = makeNode(AlterTableCmd);
-
-				dropCmd->subtype = AT_DropColumn;
-				dropCmd->name = pstrdup("oid");
-				dropCmd->behavior = cmd->behavior;
-				ATPrepCmd(wqueue, rel, dropCmd, recurse, false, lockmode);
-			}
-			pass = AT_PASS_DROP;
-			break;
 		case AT_SetTableSpace:	/* SET TABLESPACE */
 			ATSimplePermissions(rel, ATT_TABLE | ATT_MATVIEW | ATT_INDEX |
 								ATT_PARTITIONED_INDEX);
@@ -4068,12 +4008,12 @@ ATExecCmd(List **wqueue, AlteredTableInfo *tab, Relation rel,
 		case AT_AddColumn:		/* ADD COLUMN */
 		case AT_AddColumnToView:	/* add column via CREATE OR REPLACE VIEW */
 			address = ATExecAddColumn(wqueue, tab, rel, (ColumnDef *) cmd->def,
-									  false, false, false,
+									  false, false,
 									  false, lockmode);
 			break;
 		case AT_AddColumnRecurse:
 			address = ATExecAddColumn(wqueue, tab, rel, (ColumnDef *) cmd->def,
-									  false, true, false,
+									  true, false,
 									  cmd->missing_ok, lockmode);
 			break;
 		case AT_ColumnDefault:	/* ALTER COLUMN DEFAULT */
@@ -4197,29 +4137,6 @@ ATExecCmd(List **wqueue, AlteredTableInfo *tab, Relation rel,
 		case AT_SetLogged:		/* SET LOGGED */
 		case AT_SetUnLogged:	/* SET UNLOGGED */
 			break;
-		case AT_AddOids:		/* SET WITH OIDS */
-			/* Use the ADD COLUMN code, unless prep decided to do nothing */
-			if (cmd->def != NULL)
-				address =
-					ATExecAddColumn(wqueue, tab, rel, (ColumnDef *) cmd->def,
-									true, false, false,
-									cmd->missing_ok, lockmode);
-			break;
-		case AT_AddOidsRecurse: /* SET WITH OIDS */
-			/* Use the ADD COLUMN code, unless prep decided to do nothing */
-			if (cmd->def != NULL)
-				address =
-					ATExecAddColumn(wqueue, tab, rel, (ColumnDef *) cmd->def,
-									true, true, false,
-									cmd->missing_ok, lockmode);
-			break;
-		case AT_DropOids:		/* SET WITHOUT OIDS */
-
-			/*
-			 * Nothing to do here; we'll have generated a DropColumn
-			 * subcommand to do the real work
-			 */
-			break;
 		case AT_SetTableSpace:	/* SET TABLESPACE */
 			/*
 			 * Only do this for partitioned indexes, for which this is just
@@ -4774,12 +4691,8 @@ ATRewriteTable(AlteredTableInfo *tab, Oid OIDNewHeap, LOCKMODE lockmode)
 		{
 			if (tab->rewrite > 0)
 			{
-				Oid			tupOid = InvalidOid;
-
 				/* Extract data from old tuple */
 				heap_deform_tuple(tuple, oldTupDesc, values, isnull);
-				if (oldTupDesc->tdhasoid)
-					tupOid = HeapTupleGetOid(tuple);
 
 				/* Set dropped attributes to null in new tuple */
 				foreach(lc, dropped_attrs)
@@ -4807,10 +4720,6 @@ ATRewriteTable(AlteredTableInfo *tab, Oid OIDNewHeap, LOCKMODE lockmode)
 				 */
 				tuple = heap_form_tuple(newTupDesc, values, isnull);
 
-				/* Preserve OID, if any */
-				if (newTupDesc->tdhasoid)
-					HeapTupleSetOid(tuple, tupOid);
-
 				/*
 				 * Constraints might reference the tableoid column, so
 				 * initialize t_tableOid before evaluating them.
@@ -5293,6 +5202,8 @@ find_typed_table_dependencies(Oid typeOid, const char *typeName, DropBehavior be
 
 	while ((tuple = heap_getnext(scan, ForwardScanDirection)) != NULL)
 	{
+		Form_pg_class classform = (Form_pg_class) GETSTRUCT(tuple);
+
 		if (behavior == DROP_RESTRICT)
 			ereport(ERROR,
 					(errcode(ERRCODE_DEPENDENT_OBJECTS_STILL_EXIST),
@@ -5300,7 +5211,7 @@ find_typed_table_dependencies(Oid typeOid, const char *typeName, DropBehavior be
 							typeName),
 					 errhint("Use ALTER ... CASCADE to alter the typed tables too.")));
 		else
-			result = lappend_oid(result, HeapTupleGetOid(tuple));
+			result = lappend_oid(result, classform->oid);
 	}
 
 	heap_endscan(scan);
@@ -5345,7 +5256,7 @@ check_of_type(HeapTuple typetuple)
 		ereport(ERROR,
 				(errcode(ERRCODE_WRONG_OBJECT_TYPE),
 				 errmsg("type %s is not a composite type",
-						format_type_be(HeapTupleGetOid(typetuple)))));
+						format_type_be(typ->oid))));
 }
 
 
@@ -5385,7 +5296,7 @@ ATPrepAddColumn(List **wqueue, Relation rel, bool recurse, bool recursing,
  */
 static ObjectAddress
 ATExecAddColumn(List **wqueue, AlteredTableInfo *tab, Relation rel,
-				ColumnDef *colDef, bool isOid,
+				ColumnDef *colDef,
 				bool recurse, bool recursing,
 				bool if_not_exists, LOCKMODE lockmode)
 {
@@ -5455,13 +5366,6 @@ ATExecAddColumn(List **wqueue, AlteredTableInfo *tab, Relation rel,
 								   get_collation_name(ccollid),
 								   get_collation_name(childatt->attcollation))));
 
-			/* If it's OID, child column must actually be OID */
-			if (isOid && childatt->attnum != ObjectIdAttributeNumber)
-				ereport(ERROR,
-						(errcode(ERRCODE_DATATYPE_MISMATCH),
-						 errmsg("child table \"%s\" has a conflicting \"%s\" column",
-								RelationGetRelationName(rel), colDef->colname)));
-
 			/* Bump the existing child att's inhcount */
 			childatt->attinhcount++;
 			CatalogTupleUpdate(attrdesc, &tuple->t_self, tuple);
@@ -5506,21 +5410,16 @@ ATExecAddColumn(List **wqueue, AlteredTableInfo *tab, Relation rel,
 	}
 
 	/* Determine the new attribute's number */
-	if (isOid)
-		newattnum = ObjectIdAttributeNumber;
-	else
-	{
-		newattnum = ((Form_pg_class) GETSTRUCT(reltup))->relnatts + 1;
-		if (newattnum > MaxHeapAttributeNumber)
-			ereport(ERROR,
-					(errcode(ERRCODE_TOO_MANY_COLUMNS),
-					 errmsg("tables can have at most %d columns",
-							MaxHeapAttributeNumber)));
-	}
+	newattnum = ((Form_pg_class) GETSTRUCT(reltup))->relnatts + 1;
+	if (newattnum > MaxHeapAttributeNumber)
+		ereport(ERROR,
+				(errcode(ERRCODE_TOO_MANY_COLUMNS),
+				 errmsg("tables can have at most %d columns",
+						MaxHeapAttributeNumber)));
 
 	typeTuple = typenameType(NULL, colDef->typeName, &typmod);
 	tform = (Form_pg_type) GETSTRUCT(typeTuple);
-	typeOid = HeapTupleGetOid(typeTuple);
+	typeOid = tform->oid;
 
 	aclresult = pg_type_aclcheck(typeOid, GetUserId(), ACL_USAGE);
 	if (aclresult != ACLCHECK_OK)
@@ -5564,10 +5463,7 @@ ATExecAddColumn(List **wqueue, AlteredTableInfo *tab, Relation rel,
 	/*
 	 * Update pg_class tuple as appropriate
 	 */
-	if (isOid)
-		((Form_pg_class) GETSTRUCT(reltup))->relhasoids = true;
-	else
-		((Form_pg_class) GETSTRUCT(reltup))->relnatts = newattnum;
+	((Form_pg_class) GETSTRUCT(reltup))->relnatts = newattnum;
 
 	CatalogTupleUpdate(pgclass, &reltup->t_self, reltup);
 
@@ -5715,13 +5611,6 @@ ATExecAddColumn(List **wqueue, AlteredTableInfo *tab, Relation rel,
 		}
 	}
 
-	/*
-	 * If we are adding an OID column, we have to tell Phase 3 to rewrite the
-	 * table to fix that.
-	 */
-	if (isOid)
-		tab->rewrite |= AT_REWRITE_ALTER_OID;
-
 	/*
 	 * Add needed dependency entries for the new column.
 	 */
@@ -5767,7 +5656,7 @@ ATExecAddColumn(List **wqueue, AlteredTableInfo *tab, Relation rel,
 
 		/* Recurse to child; return value is ignored */
 		ATExecAddColumn(wqueue, childtab, childrel,
-						colDef, isOid, recurse, true,
+						colDef, recurse, true,
 						if_not_exists, lockmode);
 
 		heap_close(childrel, NoLock);
@@ -5871,35 +5760,6 @@ add_column_collation_dependency(Oid relid, int32 attnum, Oid collid)
 	}
 }
 
-/*
- * ALTER TABLE SET WITH OIDS
- *
- * Basically this is an ADD COLUMN for the special OID column.  We have
- * to cons up a ColumnDef node because the ADD COLUMN code needs one.
- */
-static void
-ATPrepAddOids(List **wqueue, Relation rel, bool recurse, AlterTableCmd *cmd, LOCKMODE lockmode)
-{
-	/* If we're recursing to a child table, the ColumnDef is already set up */
-	if (cmd->def == NULL)
-	{
-		ColumnDef  *cdef = makeNode(ColumnDef);
-
-		cdef->colname = pstrdup("oid");
-		cdef->typeName = makeTypeNameFromOid(OIDOID, -1);
-		cdef->inhcount = 0;
-		cdef->is_local = true;
-		cdef->is_not_null = true;
-		cdef->storage = 0;
-		cdef->location = -1;
-		cmd->def = (Node *) cdef;
-	}
-	ATPrepAddColumn(wqueue, rel, recurse, false, false, cmd, lockmode);
-
-	if (recurse)
-		cmd->subtype = AT_AddOidsRecurse;
-}
-
 /*
  * ALTER TABLE ALTER COLUMN DROP NOT NULL
  *
@@ -6801,8 +6661,8 @@ ATExecDropColumn(List **wqueue, Relation rel, const char *colName,
 
 	attnum = targetatt->attnum;
 
-	/* Can't drop a system attribute, except OID */
-	if (attnum <= 0 && attnum != ObjectIdAttributeNumber)
+	/* Can't drop a system attribute */
+	if (attnum <= 0)
 		ereport(ERROR,
 				(errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
 				 errmsg("cannot drop system column \"%s\"",
@@ -6932,39 +6792,6 @@ ATExecDropColumn(List **wqueue, Relation rel, const char *colName,
 
 	performDeletion(&object, behavior, 0);
 
-	/*
-	 * 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)
-	{
-		Relation	class_rel;
-		Form_pg_class tuple_class;
-		AlteredTableInfo *tab;
-
-		class_rel = heap_open(RelationRelationId, RowExclusiveLock);
-
-		tuple = SearchSysCacheCopy1(RELOID,
-									ObjectIdGetDatum(RelationGetRelid(rel)));
-		if (!HeapTupleIsValid(tuple))
-			elog(ERROR, "cache lookup failed for relation %u",
-				 RelationGetRelid(rel));
-		tuple_class = (Form_pg_class) GETSTRUCT(tuple);
-
-		tuple_class->relhasoids = false;
-		CatalogTupleUpdate(class_rel, &tuple->t_self, tuple);
-
-		heap_close(class_rel, RowExclusiveLock);
-
-		/* Find or create work queue entry for this table */
-		tab = ATGetQueueEntry(wqueue, rel);
-
-		/* Tell Phase 3 to physically remove the OID column */
-		tab->rewrite |= AT_REWRITE_ALTER_OID;
-	}
-
 	return object;
 }
 
@@ -7878,7 +7705,7 @@ ATExecAlterConstraint(Relation rel, AlterTableCmd *cmd,
 		CatalogTupleUpdate(conrel, &copyTuple->t_self, copyTuple);
 
 		InvokeObjectPostAlterHook(ConstraintRelationId,
-								  HeapTupleGetOid(contuple), 0);
+								  currcon->oid, 0);
 
 		heap_freetuple(copyTuple);
 
@@ -7891,7 +7718,7 @@ ATExecAlterConstraint(Relation rel, AlterTableCmd *cmd,
 		ScanKeyInit(&tgkey,
 					Anum_pg_trigger_tgconstraint,
 					BTEqualStrategyNumber, F_OIDEQ,
-					ObjectIdGetDatum(HeapTupleGetOid(contuple)));
+					ObjectIdGetDatum(currcon->oid));
 
 		tgscan = systable_beginscan(tgrel, TriggerConstraintIndexId, true,
 									NULL, 1, &tgkey);
@@ -7930,8 +7757,7 @@ ATExecAlterConstraint(Relation rel, AlterTableCmd *cmd,
 			copy_tg->tginitdeferred = cmdcon->initdeferred;
 			CatalogTupleUpdate(tgrel, &copyTuple->t_self, copyTuple);
 
-			InvokeObjectPostAlterHook(TriggerRelationId,
-									  HeapTupleGetOid(tgtuple), 0);
+			InvokeObjectPostAlterHook(TriggerRelationId, currcon->oid, 0);
 
 			heap_freetuple(copyTuple);
 		}
@@ -7952,8 +7778,7 @@ ATExecAlterConstraint(Relation rel, AlterTableCmd *cmd,
 			CacheInvalidateRelcacheByRelid(lfirst_oid(lc));
 		}
 
-		ObjectAddressSet(address, ConstraintRelationId,
-						 HeapTupleGetOid(contuple));
+		ObjectAddressSet(address, ConstraintRelationId, currcon->oid);
 	}
 	else
 		address = InvalidObjectAddress;
@@ -8043,7 +7868,7 @@ ATExecValidateConstraint(Relation rel, char *constrName, bool recurse,
 
 			validateForeignKeyConstraint(constrName, rel, refrel,
 										 con->conindid,
-										 HeapTupleGetOid(tuple));
+										 con->oid);
 			heap_close(refrel, NoLock);
 
 			/*
@@ -8116,13 +7941,11 @@ ATExecValidateConstraint(Relation rel, char *constrName, bool recurse,
 		copy_con->convalidated = true;
 		CatalogTupleUpdate(conrel, &copyTuple->t_self, copyTuple);
 
-		InvokeObjectPostAlterHook(ConstraintRelationId,
-								  HeapTupleGetOid(tuple), 0);
+		InvokeObjectPostAlterHook(ConstraintRelationId, con->oid, 0);
 
 		heap_freetuple(copyTuple);
 
-		ObjectAddressSet(address, ConstraintRelationId,
-						 HeapTupleGetOid(tuple));
+		ObjectAddressSet(address, ConstraintRelationId, con->oid);
 	}
 	else
 		address = InvalidObjectAddress; /* already validated */
@@ -8520,7 +8343,7 @@ validateCheckConstraint(Relation rel, HeapTuple constrtup)
 						  &isnull);
 	if (isnull)
 		elog(ERROR, "null conbin for constraint %u",
-			 HeapTupleGetOid(constrtup));
+			 constrForm->oid);
 	conbin = TextDatumGetCString(val);
 	origexpr = (Expr *) stringToNode(conbin);
 	exprstate = ExecPrepareExpr(origexpr, estate);
@@ -8944,7 +8767,7 @@ ATExecDropConstraint(Relation rel, const char *constrName,
 		 * Perform the actual constraint deletion
 		 */
 		conobj.classId = ConstraintRelationId;
-		conobj.objectId = HeapTupleGetOid(tuple);
+		conobj.objectId = con->oid;
 		conobj.objectSubId = 0;
 
 		performDeletion(&conobj, behavior, 0);
@@ -9419,7 +9242,7 @@ ATExecAlterColumnType(AlteredTableInfo *tab, Relation rel,
 	/* Look up the target type (should not fail, since prep found it) */
 	typeTuple = typenameType(NULL, typeName, &targettypmod);
 	tform = (Form_pg_type) GETSTRUCT(typeTuple);
-	targettype = HeapTupleGetOid(typeTuple);
+	targettype = tform->oid;
 	/* And the collation */
 	targetcollid = GetColumnDefCollation(NULL, def, targettype);
 
@@ -11229,10 +11052,8 @@ AlterTableMoveAll(AlterTableMoveAllStmt *stmt)
 	scan = heap_beginscan_catalog(rel, 1, key);
 	while ((tuple = heap_getnext(scan, ForwardScanDirection)) != NULL)
 	{
-		Oid			relOid = HeapTupleGetOid(tuple);
-		Form_pg_class relForm;
-
-		relForm = (Form_pg_class) GETSTRUCT(tuple);
+		Form_pg_class relForm = (Form_pg_class) GETSTRUCT(tuple);
+		Oid			relOid = relForm->oid;
 
 		/*
 		 * Do not move objects in pg_catalog as part of this, if an admin
@@ -11536,14 +11357,6 @@ ATExecAddInherit(Relation child_rel, RangeVar *parent, LOCKMODE lockmode)
 						   parent->relname,
 						   RelationGetRelationName(child_rel))));
 
-	/* If parent has OIDs then child must have OIDs */
-	if (parent_rel->rd_rel->relhasoids && !child_rel->rd_rel->relhasoids)
-		ereport(ERROR,
-				(errcode(ERRCODE_WRONG_OBJECT_TYPE),
-				 errmsg("table \"%s\" without OIDs cannot inherit from table \"%s\" with OIDs",
-						RelationGetRelationName(child_rel),
-						RelationGetRelationName(parent_rel))));
-
 	/*
 	 * If child_rel has row-level triggers with transition tables, we
 	 * currently don't allow it to become an inheritance child.  See also
@@ -11656,7 +11469,7 @@ decompile_conbin(HeapTuple contup, TupleDesc tupdesc)
 	con = (Form_pg_constraint) GETSTRUCT(contup);
 	attr = heap_getattr(contup, Anum_pg_constraint_conbin, tupdesc, &isnull);
 	if (isnull)
-		elog(ERROR, "null conbin for constraint %u", HeapTupleGetOid(contup));
+		elog(ERROR, "null conbin for constraint %u", con->oid);
 
 	expr = DirectFunctionCall2(pg_get_expr, attr,
 							   ObjectIdGetDatum(con->conrelid));
@@ -11790,45 +11603,6 @@ MergeAttributesIntoExisting(Relation child_rel, Relation parent_rel)
 		}
 	}
 
-	/*
-	 * If the parent has an OID column, so must the child, and we'd better
-	 * update the child's attinhcount and attislocal the same as for normal
-	 * columns.  We needn't check data type or not-nullness though.
-	 */
-	if (tupleDesc->tdhasoid)
-	{
-		/*
-		 * Here we match by column number not name; the match *must* be the
-		 * system column, not some random column named "oid".
-		 */
-		tuple = SearchSysCacheCopy2(ATTNUM,
-									ObjectIdGetDatum(RelationGetRelid(child_rel)),
-									Int16GetDatum(ObjectIdAttributeNumber));
-		if (HeapTupleIsValid(tuple))
-		{
-			Form_pg_attribute childatt = (Form_pg_attribute) GETSTRUCT(tuple);
-
-			/* See comments above; these changes should be the same */
-			childatt->attinhcount++;
-
-			if (child_is_partition)
-			{
-				Assert(childatt->attinhcount == 1);
-				childatt->attislocal = false;
-			}
-
-			CatalogTupleUpdate(attrrel, &tuple->t_self, tuple);
-			heap_freetuple(tuple);
-		}
-		else
-		{
-			ereport(ERROR,
-					(errcode(ERRCODE_DATATYPE_MISMATCH),
-					 errmsg("child table is missing column \"%s\"",
-							"oid")));
-		}
-	}
-
 	heap_close(attrrel, RowExclusiveLock);
 }
 
@@ -12258,6 +12032,7 @@ ATExecAddOf(Relation rel, const TypeName *ofTypename, LOCKMODE lockmode)
 {
 	Oid			relid = RelationGetRelid(rel);
 	Type		typetuple;
+	Form_pg_type typeform;
 	Oid			typeid;
 	Relation	inheritsRelation,
 				relationRelation;
@@ -12274,7 +12049,8 @@ ATExecAddOf(Relation rel, const TypeName *ofTypename, LOCKMODE lockmode)
 	/* Validate the type. */
 	typetuple = typenameType(NULL, ofTypename, NULL);
 	check_of_type(typetuple);
-	typeid = HeapTupleGetOid(typetuple);
+	typeform = (Form_pg_type) GETSTRUCT(typetuple);
+	typeid = typeform->oid;
 
 	/* Fail if the table has any inheritance parents. */
 	inheritsRelation = heap_open(InheritsRelationId, AccessShareLock);
@@ -12294,7 +12070,6 @@ ATExecAddOf(Relation rel, const TypeName *ofTypename, LOCKMODE lockmode)
 	/*
 	 * Check the tuple descriptors for compatibility.  Unlike inheritance, we
 	 * require that the order also match.  However, attnotnull need not match.
-	 * Also unlike inheritance, we do not require matching relhasoids.
 	 */
 	typeTupleDesc = lookup_rowtype_tupdesc(typeid, -1);
 	tableTupleDesc = RelationGetDescr(rel);
@@ -12619,10 +12394,6 @@ ATExecReplicaIdentity(Relation rel, ReplicaIdentityStmt *stmt, LOCKMODE lockmode
 		int16		attno = indexRel->rd_index->indkey.values[key];
 		Form_pg_attribute attr;
 
-		/* Allow OID column to be indexed; it's certainly not nullable */
-		if (attno == ObjectIdAttributeNumber)
-			continue;
-
 		/*
 		 * Reject any other system columns.  (Going forward, we'll disallow
 		 * indexes containing such columns in the first place, but they might
@@ -14292,22 +14063,6 @@ ATExecAttachPartition(List **wqueue, Relation rel, PartitionCmd *cmd)
 				(errcode(ERRCODE_WRONG_OBJECT_TYPE),
 				 errmsg("cannot attach temporary relation of another session as partition")));
 
-	/* If parent has OIDs then child must have OIDs */
-	if (rel->rd_rel->relhasoids && !attachrel->rd_rel->relhasoids)
-		ereport(ERROR,
-				(errcode(ERRCODE_WRONG_OBJECT_TYPE),
-				 errmsg("cannot attach table \"%s\" without OIDs as partition of"
-						" table \"%s\" with OIDs", RelationGetRelationName(attachrel),
-						RelationGetRelationName(rel))));
-
-	/* OTOH, if parent doesn't have them, do not allow in attachrel either */
-	if (attachrel->rd_rel->relhasoids && !rel->rd_rel->relhasoids)
-		ereport(ERROR,
-				(errcode(ERRCODE_WRONG_OBJECT_TYPE),
-				 errmsg("cannot attach table \"%s\" with OIDs as partition of table"
-						" \"%s\" without OIDs", RelationGetRelationName(attachrel),
-						RelationGetRelationName(rel))));
-
 	/* Check if there are any columns in attachrel that aren't in the parent */
 	tupleDesc = RelationGetDescr(attachrel);
 	natts = tupleDesc->natts;
@@ -14728,7 +14483,7 @@ CloneRowTriggersToPartition(Relation parent, Relation partition)
 
 		CreateTrigger(trigStmt, NULL, RelationGetRelid(partition),
 					  trigForm->tgconstrrelid, InvalidOid, InvalidOid,
-					  trigForm->tgfoid, HeapTupleGetOid(tuple), qual,
+					  trigForm->tgfoid, trigForm->oid, qual,
 					  false, true);
 
 		MemoryContextReset(perTupCxt);
diff --git a/src/backend/commands/tablespace.c b/src/backend/commands/tablespace.c
index f7e9160a4f6..bc37112f51e 100644
--- a/src/backend/commands/tablespace.c
+++ b/src/backend/commands/tablespace.c
@@ -327,6 +327,8 @@ CreateTableSpace(CreateTableSpaceStmt *stmt)
 
 	MemSet(nulls, false, sizeof(nulls));
 
+	tablespaceoid = GetNewOidWithIndex(rel, TablespaceOidIndexId, Anum_pg_tablespace_oid);
+	values[Anum_pg_tablespace_oid - 1] = ObjectIdGetDatum(tablespaceoid);
 	values[Anum_pg_tablespace_spcname - 1] =
 		DirectFunctionCall1(namein, CStringGetDatum(stmt->tablespacename));
 	values[Anum_pg_tablespace_spcowner - 1] =
@@ -345,7 +347,7 @@ CreateTableSpace(CreateTableSpaceStmt *stmt)
 
 	tuple = heap_form_tuple(rel->rd_att, values, nulls);
 
-	tablespaceoid = CatalogTupleInsert(rel, tuple);
+	CatalogTupleInsert(rel, tuple);
 
 	heap_freetuple(tuple);
 
@@ -406,6 +408,7 @@ DropTableSpace(DropTableSpaceStmt *stmt)
 	HeapScanDesc scandesc;
 	Relation	rel;
 	HeapTuple	tuple;
+	Form_pg_tablespace spcform;
 	ScanKeyData entry[1];
 	Oid			tablespaceoid;
 
@@ -442,7 +445,8 @@ DropTableSpace(DropTableSpaceStmt *stmt)
 		return;
 	}
 
-	tablespaceoid = HeapTupleGetOid(tuple);
+	spcform = (Form_pg_tablespace) GETSTRUCT(tuple);
+	tablespaceoid = spcform->oid;
 
 	/* Must be tablespace owner */
 	if (!pg_tablespace_ownercheck(tablespaceoid, GetUserId()))
@@ -935,14 +939,14 @@ RenameTableSpace(const char *oldname, const char *newname)
 				 errmsg("tablespace \"%s\" does not exist",
 						oldname)));
 
-	tspId = HeapTupleGetOid(tup);
 	newtuple = heap_copytuple(tup);
 	newform = (Form_pg_tablespace) GETSTRUCT(newtuple);
+	tspId = newform->oid;
 
 	heap_endscan(scan);
 
 	/* Must be owner */
-	if (!pg_tablespace_ownercheck(HeapTupleGetOid(newtuple), GetUserId()))
+	if (!pg_tablespace_ownercheck(tspId, GetUserId()))
 		aclcheck_error(ACLCHECK_NO_PRIV, OBJECT_TABLESPACE, oldname);
 
 	/* Validate new name */
@@ -1015,10 +1019,10 @@ AlterTableSpaceOptions(AlterTableSpaceOptionsStmt *stmt)
 				 errmsg("tablespace \"%s\" does not exist",
 						stmt->tablespacename)));
 
-	tablespaceoid = HeapTupleGetOid(tup);
+	tablespaceoid = ((Form_pg_tablespace) GETSTRUCT(tup))->oid;
 
 	/* Must be owner of the existing object */
-	if (!pg_tablespace_ownercheck(HeapTupleGetOid(tup), GetUserId()))
+	if (!pg_tablespace_ownercheck(tablespaceoid, GetUserId()))
 		aclcheck_error(ACLCHECK_NOT_OWNER, OBJECT_TABLESPACE,
 					   stmt->tablespacename);
 
@@ -1044,7 +1048,7 @@ AlterTableSpaceOptions(AlterTableSpaceOptionsStmt *stmt)
 	/* Update system catalog. */
 	CatalogTupleUpdate(rel, &newtuple->t_self, newtuple);
 
-	InvokeObjectPostAlterHook(TableSpaceRelationId, HeapTupleGetOid(tup), 0);
+	InvokeObjectPostAlterHook(TableSpaceRelationId, tablespaceoid, 0);
 
 	heap_freetuple(newtuple);
 
@@ -1403,7 +1407,7 @@ get_tablespace_oid(const char *tablespacename, bool missing_ok)
 
 	/* We assume that there can be at most one matching tuple */
 	if (HeapTupleIsValid(tuple))
-		result = HeapTupleGetOid(tuple);
+		result = ((Form_pg_tablespace) GETSTRUCT(tuple))->oid;
 	else
 		result = InvalidOid;
 
@@ -1441,7 +1445,7 @@ get_tablespace_name(Oid spc_oid)
 	rel = heap_open(TableSpaceRelationId, AccessShareLock);
 
 	ScanKeyInit(&entry[0],
-				ObjectIdAttributeNumber,
+				Anum_pg_tablespace_oid,
 				BTEqualStrategyNumber, F_OIDEQ,
 				ObjectIdGetDatum(spc_oid));
 	scandesc = heap_beginscan_catalog(rel, 1, entry);
diff --git a/src/backend/commands/trigger.c b/src/backend/commands/trigger.c
index ccb5706c162..ad966ec963b 100644
--- a/src/backend/commands/trigger.c
+++ b/src/backend/commands/trigger.c
@@ -764,7 +764,7 @@ CreateTrigger(CreateTrigStmt *stmt, const char *queryString,
 	 */
 	tgrel = heap_open(TriggerRelationId, RowExclusiveLock);
 
-	trigoid = GetNewOid(tgrel);
+	trigoid = GetNewOidWithIndex(tgrel, TriggerOidIndexId, Anum_pg_trigger_oid);
 
 	/*
 	 * If trigger is internally generated, modify the provided trigger name to
@@ -824,6 +824,7 @@ CreateTrigger(CreateTrigStmt *stmt, const char *queryString,
 	 */
 	memset(nulls, false, sizeof(nulls));
 
+	values[Anum_pg_trigger_oid - 1] = ObjectIdGetDatum(trigoid);
 	values[Anum_pg_trigger_tgrelid - 1] = ObjectIdGetDatum(RelationGetRelid(rel));
 	values[Anum_pg_trigger_tgname - 1] = DirectFunctionCall1(namein,
 															 CStringGetDatum(trigname));
@@ -940,9 +941,6 @@ CreateTrigger(CreateTrigStmt *stmt, const char *queryString,
 
 	tuple = heap_form_tuple(tgrel->rd_att, values, nulls);
 
-	/* force tuple to have the desired OID */
-	HeapTupleSetOid(tuple, trigoid);
-
 	/*
 	 * Insert tuple into pg_trigger.
 	 */
@@ -1494,7 +1492,7 @@ RemoveTriggerById(Oid trigOid)
 	 * Find the trigger to delete.
 	 */
 	ScanKeyInit(&skey[0],
-				ObjectIdAttributeNumber,
+				Anum_pg_trigger_oid,
 				BTEqualStrategyNumber, F_OIDEQ,
 				ObjectIdGetDatum(trigOid));
 
@@ -1595,7 +1593,7 @@ get_trigger_oid(Oid relid, const char *trigname, bool missing_ok)
 	}
 	else
 	{
-		oid = HeapTupleGetOid(tup);
+		oid = ((Form_pg_trigger) GETSTRUCT(tup))->oid;
 	}
 
 	systable_endscan(tgscan);
@@ -1722,20 +1720,22 @@ renametrig(RenameStmt *stmt)
 								NULL, 2, key);
 	if (HeapTupleIsValid(tuple = systable_getnext(tgscan)))
 	{
-		tgoid = HeapTupleGetOid(tuple);
+		Form_pg_trigger trigform = (Form_pg_trigger) GETSTRUCT(tuple);
+
+		tgoid = trigform->oid;
 
 		/*
 		 * Update pg_trigger tuple with new tgname.
 		 */
 		tuple = heap_copytuple(tuple);	/* need a modifiable copy */
 
-		namestrcpy(&((Form_pg_trigger) GETSTRUCT(tuple))->tgname,
+		namestrcpy(&trigform->tgname,
 				   stmt->newname);
 
 		CatalogTupleUpdate(tgrel, &tuple->t_self, tuple);
 
 		InvokeObjectPostAlterHook(TriggerRelationId,
-								  HeapTupleGetOid(tuple), 0);
+								  tgoid, 0);
 
 		/*
 		 * Invalidate relation's relcache entry so that other backends (and
@@ -1874,7 +1874,7 @@ EnableDisableTrigger(Relation rel, const char *tgname,
 		}
 
 		InvokeObjectPostAlterHook(TriggerRelationId,
-								  HeapTupleGetOid(tuple), 0);
+								  oldtrig->oid, 0);
 	}
 
 	systable_endscan(tgscan);
@@ -1958,7 +1958,7 @@ RelationBuildTriggers(Relation relation)
 		}
 		build = &(triggers[numtrigs]);
 
-		build->tgoid = HeapTupleGetOid(htup);
+		build->tgoid = pg_trigger->oid;
 		build->tgname = DatumGetCString(DirectFunctionCall1(nameout,
 															NameGetDatum(&pg_trigger->tgname)));
 		build->tgfoid = pg_trigger->tgfoid;
@@ -5445,8 +5445,7 @@ AfterTriggerSetState(ConstraintsSetStmt *stmt)
 					Form_pg_constraint con = (Form_pg_constraint) GETSTRUCT(tup);
 
 					if (con->condeferrable)
-						conoidlist = lappend_oid(conoidlist,
-												 HeapTupleGetOid(tup));
+						conoidlist = lappend_oid(conoidlist, con->oid);
 					else if (stmt->deferred)
 						ereport(ERROR,
 								(errcode(ERRCODE_WRONG_OBJECT_TYPE),
@@ -5498,7 +5497,11 @@ AfterTriggerSetState(ConstraintsSetStmt *stmt)
 			scan = systable_beginscan(conrel, ConstraintParentIndexId, true, NULL, 1, &key);
 
 			while (HeapTupleIsValid(tuple = systable_getnext(scan)))
-				conoidlist = lappend_oid(conoidlist, HeapTupleGetOid(tuple));
+			{
+				Form_pg_constraint con = (Form_pg_constraint) GETSTRUCT(tuple);
+
+				conoidlist = lappend_oid(conoidlist, con->oid);
+			}
 
 			systable_endscan(scan);
 		}
@@ -5540,8 +5543,7 @@ AfterTriggerSetState(ConstraintsSetStmt *stmt)
 				 * actions.
 				 */
 				if (pg_trigger->tgdeferrable)
-					tgoidlist = lappend_oid(tgoidlist,
-											HeapTupleGetOid(htup));
+					tgoidlist = lappend_oid(tgoidlist, pg_trigger->oid);
 
 				found = true;
 			}
diff --git a/src/backend/commands/tsearchcmds.c b/src/backend/commands/tsearchcmds.c
index 3a843512d13..1403d9ac2e3 100644
--- a/src/backend/commands/tsearchcmds.c
+++ b/src/backend/commands/tsearchcmds.c
@@ -21,6 +21,7 @@
 #include "access/heapam.h"
 #include "access/htup_details.h"
 #include "access/xact.h"
+#include "catalog/catalog.h"
 #include "catalog/dependency.h"
 #include "catalog/indexing.h"
 #include "catalog/objectaccess.h"
@@ -132,7 +133,7 @@ makeParserDependencies(HeapTuple tuple)
 				referenced;
 
 	myself.classId = TSParserRelationId;
-	myself.objectId = HeapTupleGetOid(tuple);
+	myself.objectId = prs->oid;
 	myself.objectSubId = 0;
 
 	/* dependency on namespace */
@@ -191,6 +192,8 @@ DefineTSParser(List *names, List *parameters)
 				(errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
 				 errmsg("must be superuser to create text search parsers")));
 
+	prsRel = heap_open(TSParserRelationId, RowExclusiveLock);
+
 	/* Convert list of names to a name and namespace */
 	namespaceoid = QualifiedNameGetCreationNamespace(names, &prsname);
 
@@ -198,6 +201,8 @@ DefineTSParser(List *names, List *parameters)
 	memset(values, 0, sizeof(values));
 	memset(nulls, false, sizeof(nulls));
 
+	prsOid = GetNewOidWithIndex(prsRel, TSParserOidIndexId, Anum_pg_ts_parser_oid);
+	values[Anum_pg_ts_parser_oid - 1] = ObjectIdGetDatum(prsOid);
 	namestrcpy(&pname, prsname);
 	values[Anum_pg_ts_parser_prsname - 1] = NameGetDatum(&pname);
 	values[Anum_pg_ts_parser_prsnamespace - 1] = ObjectIdGetDatum(namespaceoid);
@@ -267,11 +272,9 @@ DefineTSParser(List *names, List *parameters)
 	/*
 	 * Looks good, insert
 	 */
-	prsRel = heap_open(TSParserRelationId, RowExclusiveLock);
-
 	tup = heap_form_tuple(prsRel->rd_att, values, nulls);
 
-	prsOid = CatalogTupleInsert(prsRel, tup);
+	CatalogTupleInsert(prsRel, tup);
 
 	address = makeParserDependencies(tup);
 
@@ -323,7 +326,7 @@ makeDictionaryDependencies(HeapTuple tuple)
 				referenced;
 
 	myself.classId = TSDictionaryRelationId;
-	myself.objectId = HeapTupleGetOid(tuple);
+	myself.objectId = dict->oid;
 	myself.objectSubId = 0;
 
 	/* dependency on namespace */
@@ -459,12 +462,17 @@ DefineTSDictionary(List *names, List *parameters)
 
 	verify_dictoptions(templId, dictoptions);
 
+
+	dictRel = heap_open(TSDictionaryRelationId, RowExclusiveLock);
+
 	/*
 	 * Looks good, insert
 	 */
 	memset(values, 0, sizeof(values));
 	memset(nulls, false, sizeof(nulls));
 
+	dictOid = GetNewOidWithIndex(dictRel, TSDictionaryOidIndexId, Anum_pg_ts_dict_oid);
+	values[Anum_pg_ts_dict_oid - 1] = ObjectIdGetDatum(dictOid);
 	namestrcpy(&dname, dictname);
 	values[Anum_pg_ts_dict_dictname - 1] = NameGetDatum(&dname);
 	values[Anum_pg_ts_dict_dictnamespace - 1] = ObjectIdGetDatum(namespaceoid);
@@ -476,11 +484,9 @@ DefineTSDictionary(List *names, List *parameters)
 	else
 		nulls[Anum_pg_ts_dict_dictinitoption - 1] = true;
 
-	dictRel = heap_open(TSDictionaryRelationId, RowExclusiveLock);
-
 	tup = heap_form_tuple(dictRel->rd_att, values, nulls);
 
-	dictOid = CatalogTupleInsert(dictRel, tup);
+	CatalogTupleInsert(dictRel, tup);
 
 	address = makeDictionaryDependencies(tup);
 
@@ -694,7 +700,7 @@ makeTSTemplateDependencies(HeapTuple tuple)
 				referenced;
 
 	myself.classId = TSTemplateRelationId;
-	myself.objectId = HeapTupleGetOid(tuple);
+	myself.objectId = tmpl->oid;
 	myself.objectSubId = 0;
 
 	/* dependency on namespace */
@@ -748,12 +754,16 @@ DefineTSTemplate(List *names, List *parameters)
 	/* Convert list of names to a name and namespace */
 	namespaceoid = QualifiedNameGetCreationNamespace(names, &tmplname);
 
+	tmplRel = heap_open(TSTemplateRelationId, RowExclusiveLock);
+
 	for (i = 0; i < Natts_pg_ts_template; i++)
 	{
 		nulls[i] = false;
 		values[i] = ObjectIdGetDatum(InvalidOid);
 	}
 
+	tmplOid = GetNewOidWithIndex(tmplRel, TSTemplateOidIndexId, Anum_pg_ts_dict_oid);
+	values[Anum_pg_ts_template_oid - 1] = ObjectIdGetDatum(tmplOid);
 	namestrcpy(&dname, tmplname);
 	values[Anum_pg_ts_template_tmplname - 1] = NameGetDatum(&dname);
 	values[Anum_pg_ts_template_tmplnamespace - 1] = ObjectIdGetDatum(namespaceoid);
@@ -795,12 +805,9 @@ DefineTSTemplate(List *names, List *parameters)
 	/*
 	 * Looks good, insert
 	 */
-
-	tmplRel = heap_open(TSTemplateRelationId, RowExclusiveLock);
-
 	tup = heap_form_tuple(tmplRel->rd_att, values, nulls);
 
-	tmplOid = CatalogTupleInsert(tmplRel, tup);
+	CatalogTupleInsert(tmplRel, tup);
 
 	address = makeTSTemplateDependencies(tup);
 
@@ -879,7 +886,7 @@ makeConfigurationDependencies(HeapTuple tuple, bool removeOld,
 				referenced;
 
 	myself.classId = TSConfigRelationId;
-	myself.objectId = HeapTupleGetOid(tuple);
+	myself.objectId = cfg->oid;
 	myself.objectSubId = 0;
 
 	/* for ALTER case, first flush old dependencies, except extension deps */
@@ -1042,23 +1049,25 @@ DefineTSConfiguration(List *names, List *parameters, ObjectAddress *copied)
 				(errcode(ERRCODE_INVALID_OBJECT_DEFINITION),
 				 errmsg("text search parser is required")));
 
+	cfgRel = heap_open(TSConfigRelationId, RowExclusiveLock);
+
 	/*
 	 * Looks good, build tuple and insert
 	 */
 	memset(values, 0, sizeof(values));
 	memset(nulls, false, sizeof(nulls));
 
+	cfgOid = GetNewOidWithIndex(cfgRel, TSConfigOidIndexId, Anum_pg_ts_config_oid);
+	values[Anum_pg_ts_config_oid - 1] = ObjectIdGetDatum(cfgOid);
 	namestrcpy(&cname, cfgname);
 	values[Anum_pg_ts_config_cfgname - 1] = NameGetDatum(&cname);
 	values[Anum_pg_ts_config_cfgnamespace - 1] = ObjectIdGetDatum(namespaceoid);
 	values[Anum_pg_ts_config_cfgowner - 1] = ObjectIdGetDatum(GetUserId());
 	values[Anum_pg_ts_config_cfgparser - 1] = ObjectIdGetDatum(prsOid);
 
-	cfgRel = heap_open(TSConfigRelationId, RowExclusiveLock);
-
 	tup = heap_form_tuple(cfgRel->rd_att, values, nulls);
 
-	cfgOid = CatalogTupleInsert(cfgRel, tup);
+	CatalogTupleInsert(cfgRel, tup);
 
 	if (OidIsValid(sourceOid))
 	{
@@ -1185,10 +1194,10 @@ AlterTSConfiguration(AlterTSConfigurationStmt *stmt)
 				 errmsg("text search configuration \"%s\" does not exist",
 						NameListToString(stmt->cfgname))));
 
-	cfgId = HeapTupleGetOid(tup);
+	cfgId = ((Form_pg_ts_config) GETSTRUCT(tup))->oid;
 
 	/* must be owner */
-	if (!pg_ts_config_ownercheck(HeapTupleGetOid(tup), GetUserId()))
+	if (!pg_ts_config_ownercheck(cfgId, GetUserId()))
 		aclcheck_error(ACLCHECK_NOT_OWNER, OBJECT_TSCONFIGURATION,
 					   NameListToString(stmt->cfgname));
 
@@ -1203,8 +1212,7 @@ AlterTSConfiguration(AlterTSConfigurationStmt *stmt)
 	/* Update dependencies */
 	makeConfigurationDependencies(tup, true, relMap);
 
-	InvokeObjectPostAlterHook(TSConfigRelationId,
-							  HeapTupleGetOid(tup), 0);
+	InvokeObjectPostAlterHook(TSConfigRelationId, cfgId, 0);
 
 	ObjectAddressSet(address, TSConfigRelationId, cfgId);
 
@@ -1277,7 +1285,8 @@ static void
 MakeConfigurationMapping(AlterTSConfigurationStmt *stmt,
 						 HeapTuple tup, Relation relMap)
 {
-	Oid			cfgId = HeapTupleGetOid(tup);
+	Form_pg_ts_config tsform;
+	Oid			cfgId;
 	ScanKeyData skey[2];
 	SysScanDesc scan;
 	HeapTuple	maptup;
@@ -1290,7 +1299,9 @@ MakeConfigurationMapping(AlterTSConfigurationStmt *stmt,
 	int			ndict;
 	ListCell   *c;
 
-	prsId = ((Form_pg_ts_config) GETSTRUCT(tup))->cfgparser;
+	tsform = (Form_pg_ts_config) GETSTRUCT(tup);
+	cfgId = tsform->oid;
+	prsId = tsform->cfgparser;
 
 	tokens = getTokenTypes(prsId, stmt->tokentype);
 	ntoken = list_length(stmt->tokentype);
@@ -1438,7 +1449,8 @@ static void
 DropConfigurationMapping(AlterTSConfigurationStmt *stmt,
 						 HeapTuple tup, Relation relMap)
 {
-	Oid			cfgId = HeapTupleGetOid(tup);
+	Form_pg_ts_config tsform;
+	Oid			cfgId;
 	ScanKeyData skey[2];
 	SysScanDesc scan;
 	HeapTuple	maptup;
@@ -1447,7 +1459,9 @@ DropConfigurationMapping(AlterTSConfigurationStmt *stmt,
 	int		   *tokens;
 	ListCell   *c;
 
-	prsId = ((Form_pg_ts_config) GETSTRUCT(tup))->cfgparser;
+	tsform = (Form_pg_ts_config) GETSTRUCT(tup);
+	cfgId = tsform->oid;
+	prsId = tsform->cfgparser;
 
 	tokens = getTokenTypes(prsId, stmt->tokentype);
 
diff --git a/src/backend/commands/typecmds.c b/src/backend/commands/typecmds.c
index 285a0be6436..8c612a8f0d7 100644
--- a/src/backend/commands/typecmds.c
+++ b/src/backend/commands/typecmds.c
@@ -792,7 +792,7 @@ DefineDomain(CreateDomainStmt *stmt)
 	 */
 	typeTup = typenameType(NULL, stmt->typeName, &basetypeMod);
 	baseType = (Form_pg_type) GETSTRUCT(typeTup);
-	basetypeoid = HeapTupleGetOid(typeTup);
+	basetypeoid = baseType->oid;
 
 	/*
 	 * Base type must be a plain base type, a composite type, another domain,
@@ -1330,11 +1330,11 @@ checkEnumOwner(HeapTuple tup)
 		ereport(ERROR,
 				(errcode(ERRCODE_WRONG_OBJECT_TYPE),
 				 errmsg("%s is not an enum",
-						format_type_be(HeapTupleGetOid(tup)))));
+						format_type_be(typTup->oid))));
 
 	/* Permission check: must own type */
-	if (!pg_type_ownercheck(HeapTupleGetOid(tup), GetUserId()))
-		aclcheck_error_type(ACLCHECK_NOT_OWNER, HeapTupleGetOid(tup));
+	if (!pg_type_ownercheck(typTup->oid, GetUserId()))
+		aclcheck_error_type(ACLCHECK_NOT_OWNER, typTup->oid);
 }
 
 
@@ -2090,7 +2090,7 @@ AssignTypeArrayOid(void)
 	{
 		Relation	pg_type = heap_open(TypeRelationId, AccessShareLock);
 
-		type_array_oid = GetNewOid(pg_type);
+		type_array_oid = GetNewOidWithIndex(pg_type, TypeOidIndexId, Anum_pg_type_oid);
 		heap_close(pg_type, AccessShareLock);
 	}
 
@@ -2482,7 +2482,7 @@ AlterDomainDropConstraint(List *names, const char *constrName,
 		ObjectAddress conobj;
 
 		conobj.classId = ConstraintRelationId;
-		conobj.objectId = HeapTupleGetOid(contup);
+		conobj.objectId = ((Form_pg_constraint) GETSTRUCT(contup))->oid;
 		conobj.objectSubId = 0;
 
 		performDeletion(&conobj, behavior, 0);
@@ -2700,7 +2700,7 @@ AlterDomainValidateConstraint(List *names, const char *constrName)
 						  &isnull);
 	if (isnull)
 		elog(ERROR, "null conbin for constraint %u",
-			 HeapTupleGetOid(tuple));
+			 con->oid);
 	conbin = TextDatumGetCString(val);
 
 	validateDomainConstraint(domainoid, conbin);
@@ -2713,8 +2713,7 @@ AlterDomainValidateConstraint(List *names, const char *constrName)
 	copy_con->convalidated = true;
 	CatalogTupleUpdate(conrel, &copyTuple->t_self, copyTuple);
 
-	InvokeObjectPostAlterHook(ConstraintRelationId,
-							  HeapTupleGetOid(copyTuple), 0);
+	InvokeObjectPostAlterHook(ConstraintRelationId, con->oid, 0);
 
 	ObjectAddressSet(address, TypeRelationId, domainoid);
 
@@ -3027,11 +3026,11 @@ checkDomainOwner(HeapTuple tup)
 		ereport(ERROR,
 				(errcode(ERRCODE_WRONG_OBJECT_TYPE),
 				 errmsg("%s is not a domain",
-						format_type_be(HeapTupleGetOid(tup)))));
+						format_type_be(typTup->oid))));
 
 	/* Permission check: must own type */
-	if (!pg_type_ownercheck(HeapTupleGetOid(tup), GetUserId()))
-		aclcheck_error_type(ACLCHECK_NOT_OWNER, HeapTupleGetOid(tup));
+	if (!pg_type_ownercheck(typTup->oid, GetUserId()))
+		aclcheck_error_type(ACLCHECK_NOT_OWNER, typTup->oid);
 }
 
 /*
@@ -3342,8 +3341,8 @@ AlterTypeOwner(List *names, Oid newOwnerId, ObjectType objecttype)
 		if (!superuser())
 		{
 			/* Otherwise, must be owner of the existing object */
-			if (!pg_type_ownercheck(HeapTupleGetOid(tup), GetUserId()))
-				aclcheck_error_type(ACLCHECK_NOT_OWNER, HeapTupleGetOid(tup));
+			if (!pg_type_ownercheck(typTup->oid, GetUserId()))
+				aclcheck_error_type(ACLCHECK_NOT_OWNER, typTup->oid);
 
 			/* Must be able to become new owner */
 			check_is_member_of_role(GetUserId(), newOwnerId);
diff --git a/src/backend/commands/user.c b/src/backend/commands/user.c
index 71c5caa41b9..c43afa24410 100644
--- a/src/backend/commands/user.c
+++ b/src/backend/commands/user.c
@@ -423,8 +423,6 @@ CreateRole(ParseState *pstate, CreateRoleStmt *stmt)
 
 	new_record[Anum_pg_authid_rolbypassrls - 1] = BoolGetDatum(bypassrls);
 
-	tuple = heap_form_tuple(pg_authid_dsc, new_record, new_record_nulls);
-
 	/*
 	 * pg_largeobject_metadata contains pg_authid.oid's, so we use the
 	 * binary-upgrade override.
@@ -436,14 +434,22 @@ CreateRole(ParseState *pstate, CreateRoleStmt *stmt)
 					(errcode(ERRCODE_INVALID_PARAMETER_VALUE),
 					 errmsg("pg_authid OID value not set when in binary upgrade mode")));
 
-		HeapTupleSetOid(tuple, binary_upgrade_next_pg_authid_oid);
+		roleid = binary_upgrade_next_pg_authid_oid;
 		binary_upgrade_next_pg_authid_oid = InvalidOid;
 	}
+	else
+	{
+		roleid = GetNewOidWithIndex(pg_authid_rel, AuthIdOidIndexId, Anum_pg_authid_oid);
+	}
+
+	new_record[Anum_pg_authid_oid - 1] = ObjectIdGetDatum(roleid);
+
+	tuple = heap_form_tuple(pg_authid_dsc, new_record, new_record_nulls);
 
 	/*
 	 * Insert new record in the pg_authid table
 	 */
-	roleid = CatalogTupleInsert(pg_authid_rel, tuple);
+	CatalogTupleInsert(pg_authid_rel, tuple);
 
 	/*
 	 * Advance command counter so we can see new record; else tests in
@@ -459,8 +465,9 @@ CreateRole(ParseState *pstate, CreateRoleStmt *stmt)
 	{
 		RoleSpec   *oldrole = lfirst(item);
 		HeapTuple	oldroletup = get_rolespec_tuple(oldrole);
-		Oid			oldroleid = HeapTupleGetOid(oldroletup);
-		char	   *oldrolename = NameStr(((Form_pg_authid) GETSTRUCT(oldroletup))->rolname);
+		Form_pg_authid oldroleform = (Form_pg_authid) GETSTRUCT(oldroletup);
+		Oid			oldroleid = oldroleform->oid;
+		char	   *oldrolename = NameStr(oldroleform->rolname);
 
 		AddRoleMems(oldrolename, oldroleid,
 					list_make1(makeString(stmt->role)),
@@ -679,7 +686,7 @@ AlterRole(AlterRoleStmt *stmt)
 	tuple = get_rolespec_tuple(stmt->role);
 	authform = (Form_pg_authid) GETSTRUCT(tuple);
 	rolename = pstrdup(NameStr(authform->rolname));
-	roleid = HeapTupleGetOid(tuple);
+	roleid = authform->oid;
 
 	/*
 	 * To mess with a superuser you gotta be superuser; else you need
@@ -886,6 +893,7 @@ Oid
 AlterRoleSet(AlterRoleSetStmt *stmt)
 {
 	HeapTuple	roletuple;
+	Form_pg_authid roleform;
 	Oid			databaseid = InvalidOid;
 	Oid			roleid = InvalidOid;
 
@@ -895,19 +903,20 @@ AlterRoleSet(AlterRoleSetStmt *stmt)
 							"Cannot alter reserved roles.");
 
 		roletuple = get_rolespec_tuple(stmt->role);
-		roleid = HeapTupleGetOid(roletuple);
+		roleform = (Form_pg_authid) GETSTRUCT(roletuple);
+		roleid = roleform->oid;
 
 		/*
 		 * Obtain a lock on the role and make sure it didn't go away in the
 		 * meantime.
 		 */
-		shdepLockAndCheckObject(AuthIdRelationId, HeapTupleGetOid(roletuple));
+		shdepLockAndCheckObject(AuthIdRelationId, roleid);
 
 		/*
 		 * To mess with a superuser you gotta be superuser; else you need
 		 * createrole, or just want to change your own settings
 		 */
-		if (((Form_pg_authid) GETSTRUCT(roletuple))->rolsuper)
+		if (roleform->rolsuper)
 		{
 			if (!superuser())
 				ereport(ERROR,
@@ -916,8 +925,7 @@ AlterRoleSet(AlterRoleSetStmt *stmt)
 		}
 		else
 		{
-			if (!have_createrole_privilege() &&
-				HeapTupleGetOid(roletuple) != GetUserId())
+			if (!have_createrole_privilege() && roleid != GetUserId())
 				ereport(ERROR,
 						(errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
 						 errmsg("permission denied")));
@@ -987,6 +995,7 @@ DropRole(DropRoleStmt *stmt)
 		char	   *role;
 		HeapTuple	tuple,
 					tmp_tuple;
+		Form_pg_authid roleform;
 		ScanKeyData scankey;
 		char	   *detail;
 		char	   *detail_log;
@@ -1018,7 +1027,8 @@ DropRole(DropRoleStmt *stmt)
 			continue;
 		}
 
-		roleid = HeapTupleGetOid(tuple);
+		roleform = (Form_pg_authid) GETSTRUCT(tuple);
+		roleid = roleform->oid;
 
 		if (roleid == GetUserId())
 			ereport(ERROR,
@@ -1038,7 +1048,7 @@ DropRole(DropRoleStmt *stmt)
 		 * roles but not superuser roles.  This is mainly to avoid the
 		 * scenario where you accidentally drop the last superuser.
 		 */
-		if (((Form_pg_authid) GETSTRUCT(tuple))->rolsuper &&
+		if (roleform->rolsuper &&
 			!superuser())
 			ereport(ERROR,
 					(errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
@@ -1173,8 +1183,8 @@ RenameRole(const char *oldname, const char *newname)
 	 * effective userid, though.
 	 */
 
-	roleid = HeapTupleGetOid(oldtuple);
 	authform = (Form_pg_authid) GETSTRUCT(oldtuple);
+	roleid = authform->oid;
 
 	if (roleid == GetSessionUserId())
 		ereport(ERROR,
diff --git a/src/backend/commands/vacuum.c b/src/backend/commands/vacuum.c
index a86963fc86a..25b3b0312c7 100644
--- a/src/backend/commands/vacuum.c
+++ b/src/backend/commands/vacuum.c
@@ -757,7 +757,7 @@ get_all_vacuum_rels(int options)
 	{
 		Form_pg_class classForm = (Form_pg_class) GETSTRUCT(tuple);
 		MemoryContext oldcontext;
-		Oid			relid = HeapTupleGetOid(tuple);
+		Oid			relid = classForm->oid;
 
 		/* check permissions of relation */
 		if (!vacuum_is_relation_owner(relid, classForm, options))
@@ -1442,13 +1442,13 @@ vac_truncate_clog(TransactionId frozenXID,
 		else if (TransactionIdPrecedes(datfrozenxid, frozenXID))
 		{
 			frozenXID = datfrozenxid;
-			oldestxid_datoid = HeapTupleGetOid(tuple);
+			oldestxid_datoid = dbform->oid;
 		}
 
 		if (MultiXactIdPrecedes(datminmxid, minMulti))
 		{
 			minMulti = datminmxid;
-			minmulti_datoid = HeapTupleGetOid(tuple);
+			minmulti_datoid = dbform->oid;
 		}
 	}
 
diff --git a/src/backend/commands/vacuumlazy.c b/src/backend/commands/vacuumlazy.c
index 8996d366e91..8134c52253e 100644
--- a/src/backend/commands/vacuumlazy.c
+++ b/src/backend/commands/vacuumlazy.c
@@ -1053,12 +1053,6 @@ lazy_scan_heap(Relation onerel, int options, LVRelStats *vacrelstats,
 					all_visible = false;
 					break;
 				case HEAPTUPLE_LIVE:
-					/* Tuple is good --- but let's do some validity checks */
-					if (onerel->rd_rel->relhasoids &&
-						!OidIsValid(HeapTupleGetOid(&tuple)))
-						elog(WARNING, "relation \"%s\" TID %u/%u: OID is invalid",
-							 relname, blkno, offnum);
-
 					/*
 					 * Count it as live.  Not only is this natural, but it's
 					 * also what acquire_sample_rows() does.
diff --git a/src/backend/commands/variable.c b/src/backend/commands/variable.c
index c2d7a5bebf6..c7e5a9ca9fa 100644
--- a/src/backend/commands/variable.c
+++ b/src/backend/commands/variable.c
@@ -744,6 +744,7 @@ bool
 check_session_authorization(char **newval, void **extra, GucSource source)
 {
 	HeapTuple	roleTup;
+	Form_pg_authid roleform;
 	Oid			roleid;
 	bool		is_superuser;
 	role_auth_extra *myextra;
@@ -770,8 +771,9 @@ check_session_authorization(char **newval, void **extra, GucSource source)
 		return false;
 	}
 
-	roleid = HeapTupleGetOid(roleTup);
-	is_superuser = ((Form_pg_authid) GETSTRUCT(roleTup))->rolsuper;
+	roleform = (Form_pg_authid) GETSTRUCT(roleTup);
+	roleid = roleform->oid;
+	is_superuser = roleform->rolsuper;
 
 	ReleaseSysCache(roleTup);
 
@@ -815,6 +817,7 @@ check_role(char **newval, void **extra, GucSource source)
 	Oid			roleid;
 	bool		is_superuser;
 	role_auth_extra *myextra;
+	Form_pg_authid roleform;
 
 	if (strcmp(*newval, "none") == 0)
 	{
@@ -842,8 +845,9 @@ check_role(char **newval, void **extra, GucSource source)
 			return false;
 		}
 
-		roleid = HeapTupleGetOid(roleTup);
-		is_superuser = ((Form_pg_authid) GETSTRUCT(roleTup))->rolsuper;
+		roleform = (Form_pg_authid) GETSTRUCT(roleTup);
+		roleid = roleform->oid;
+		is_superuser = roleform->rolsuper;
 
 		ReleaseSysCache(roleTup);
 
diff --git a/src/backend/commands/view.c b/src/backend/commands/view.c
index b670cad8b1d..00e85ed935f 100644
--- a/src/backend/commands/view.c
+++ b/src/backend/commands/view.c
@@ -283,7 +283,6 @@ checkViewTupleDesc(TupleDesc newdesc, TupleDesc olddesc)
 		ereport(ERROR,
 				(errcode(ERRCODE_INVALID_TABLE_DEFINITION),
 				 errmsg("cannot drop columns from view")));
-	/* we can ignore tdhasoid */
 
 	for (i = 0; i < olddesc->natts; i++)
 	{
diff --git a/src/backend/executor/execExpr.c b/src/backend/executor/execExpr.c
index 885da18306a..1a50032b79d 100644
--- a/src/backend/executor/execExpr.c
+++ b/src/backend/executor/execExpr.c
@@ -2422,7 +2422,6 @@ ExecInitWholeRowVar(ExprEvalStep *scratch, Var *variable, ExprState *state)
 			{
 				scratch->d.wholerow.junkFilter =
 					ExecInitJunkFilter(subplan->plan->targetlist,
-									   ExecGetResultType(subplan)->tdhasoid,
 									   ExecInitExtraTupleSlot(parent->state, NULL));
 			}
 		}
diff --git a/src/backend/executor/execJunk.c b/src/backend/executor/execJunk.c
index 57d74e57c1a..00dcc3cb6b1 100644
--- a/src/backend/executor/execJunk.c
+++ b/src/backend/executor/execJunk.c
@@ -53,12 +53,11 @@
  * Initialize the Junk filter.
  *
  * The source targetlist is passed in.  The output tuple descriptor is
- * built from the non-junk tlist entries, plus the passed specification
- * of whether to include room for an OID or not.
+ * built from the non-junk tlist entries.
  * An optional resultSlot can be passed as well.
  */
 JunkFilter *
-ExecInitJunkFilter(List *targetList, bool hasoid, TupleTableSlot *slot)
+ExecInitJunkFilter(List *targetList, TupleTableSlot *slot)
 {
 	JunkFilter *junkfilter;
 	TupleDesc	cleanTupType;
@@ -70,7 +69,7 @@ ExecInitJunkFilter(List *targetList, bool hasoid, TupleTableSlot *slot)
 	/*
 	 * Compute the tuple descriptor for the cleaned tuple.
 	 */
-	cleanTupType = ExecCleanTypeFromTL(targetList, hasoid);
+	cleanTupType = ExecCleanTypeFromTL(targetList);
 
 	/*
 	 * Use the given slot, or make a new slot if we weren't given one.
diff --git a/src/backend/executor/execMain.c b/src/backend/executor/execMain.c
index ba156f8c5fc..88e3533056d 100644
--- a/src/backend/executor/execMain.c
+++ b/src/backend/executor/execMain.c
@@ -344,7 +344,6 @@ standard_ExecutorRun(QueryDesc *queryDesc,
 	 * startup tuple receiver, if we will be emitting tuples
 	 */
 	estate->es_processed = 0;
-	estate->es_lastoid = InvalidOid;
 
 	sendTuples = (operation == CMD_SELECT ||
 				  queryDesc->plannedstmt->hasReturning);
@@ -1054,7 +1053,6 @@ InitPlan(QueryDesc *queryDesc, int eflags)
 			JunkFilter *j;
 
 			j = ExecInitJunkFilter(planstate->plan->targetlist,
-								   tupType->tdhasoid,
 								   ExecInitExtraTupleSlot(estate, NULL));
 			estate->es_junkFilter = j;
 
@@ -1475,68 +1473,6 @@ ExecCleanUpTriggerState(EState *estate)
 	}
 }
 
-/*
- *		ExecContextForcesOids
- *
- * This is pretty grotty: when doing INSERT, UPDATE, or CREATE TABLE AS,
- * we need to ensure that result tuples have space for an OID iff they are
- * going to be stored into a relation that has OIDs.  In other contexts
- * we are free to choose whether to leave space for OIDs in result tuples
- * (we generally don't want to, but we do if a physical-tlist optimization
- * is possible).  This routine checks the plan context and returns true if the
- * choice is forced, false if the choice is not forced.  In the true case,
- * *hasoids is set to the required value.
- *
- * One reason this is ugly is that all plan nodes in the plan tree will emit
- * tuples with space for an OID, though we really only need the topmost node
- * to do so.  However, node types like Sort don't project new tuples but just
- * return their inputs, and in those cases the requirement propagates down
- * to the input node.  Eventually we might make this code smart enough to
- * recognize how far down the requirement really goes, but for now we just
- * make all plan nodes do the same thing if the top level forces the choice.
- *
- * We assume that if we are generating tuples for INSERT or UPDATE,
- * estate->es_result_relation_info is already set up to describe the target
- * relation.  Note that in an UPDATE that spans an inheritance tree, some of
- * the target relations may have OIDs and some not.  We have to make the
- * decisions on a per-relation basis as we initialize each of the subplans of
- * the ModifyTable node, so ModifyTable has to set es_result_relation_info
- * while initializing each subplan.
- *
- * CREATE TABLE AS is even uglier, because we don't have the target relation's
- * descriptor available when this code runs; we have to look aside at the
- * flags passed to ExecutorStart().
- */
-bool
-ExecContextForcesOids(PlanState *planstate, bool *hasoids)
-{
-	ResultRelInfo *ri = planstate->state->es_result_relation_info;
-
-	if (ri != NULL)
-	{
-		Relation	rel = ri->ri_RelationDesc;
-
-		if (rel != NULL)
-		{
-			*hasoids = rel->rd_rel->relhasoids;
-			return true;
-		}
-	}
-
-	if (planstate->state->es_top_eflags & EXEC_FLAG_WITH_OIDS)
-	{
-		*hasoids = true;
-		return true;
-	}
-	if (planstate->state->es_top_eflags & EXEC_FLAG_WITHOUT_OIDS)
-	{
-		*hasoids = false;
-		return true;
-	}
-
-	return false;
-}
-
 /* ----------------------------------------------------------------
  *		ExecPostprocessPlan
  *
diff --git a/src/backend/executor/execPartition.c b/src/backend/executor/execPartition.c
index 1e72e9fb3f5..3cb770c5647 100644
--- a/src/backend/executor/execPartition.c
+++ b/src/backend/executor/execPartition.c
@@ -637,7 +637,7 @@ ExecInitPartitionInfo(ModifyTableState *mtstate,
 				 * partition that's tupdesc-equal to the partitioned table;
 				 * partitions of different tupdescs must generate their own.
 				 */
-				tupDesc = ExecTypeFromTL(onconflset, partrelDesc->tdhasoid);
+				tupDesc = ExecTypeFromTL(onconflset);
 				ExecSetSlotDescriptor(mtstate->mt_conflproj, tupDesc);
 				leaf_part_rri->ri_onConflict->oc_ProjInfo =
 					ExecBuildProjectionInfo(onconflset, econtext,
diff --git a/src/backend/executor/execSRF.c b/src/backend/executor/execSRF.c
index b97b8d797ec..ce1c5835a28 100644
--- a/src/backend/executor/execSRF.c
+++ b/src/backend/executor/execSRF.c
@@ -260,7 +260,7 @@ ExecMakeTableFunctionResult(SetExprState *setexpr,
 				rsinfo.setResult = tupstore;
 				if (!returnsTuple)
 				{
-					tupdesc = CreateTemplateTupleDesc(1, false);
+					tupdesc = CreateTemplateTupleDesc(1);
 					TupleDescInitEntry(tupdesc,
 									   (AttrNumber) 1,
 									   "column",
@@ -746,7 +746,7 @@ init_sexpr(Oid foid, Oid input_collation, Expr *node,
 		else if (functypclass == TYPEFUNC_SCALAR)
 		{
 			/* Base data type, i.e. scalar */
-			tupdesc = CreateTemplateTupleDesc(1, false);
+			tupdesc = CreateTemplateTupleDesc(1);
 			TupleDescInitEntry(tupdesc,
 							   (AttrNumber) 1,
 							   NULL,
diff --git a/src/backend/executor/execTuples.c b/src/backend/executor/execTuples.c
index 9f0d9daa829..29f459477e2 100644
--- a/src/backend/executor/execTuples.c
+++ b/src/backend/executor/execTuples.c
@@ -70,7 +70,7 @@
 
 
 static TupleDesc ExecTypeFromTLInternal(List *targetList,
-					   bool hasoid, bool skipjunk);
+					   bool skipjunk);
 
 
 /* ----------------------------------------------------------------
@@ -915,20 +915,9 @@ ExecCopySlot(TupleTableSlot *dstslot, TupleTableSlot *srcslot)
 void
 ExecInitResultTypeTL(PlanState *planstate)
 {
-	bool		hasoid;
-	TupleDesc	tupDesc;
+	TupleDesc	tupDesc = ExecTypeFromTL(planstate->plan->targetlist);
 
-	if (ExecContextForcesOids(planstate, &hasoid))
-	{
-		/* context forces OID choice; hasoid is now set correctly */
-	}
-	else
-	{
-		/* given free choice, don't leave space for OIDs in result tuples */
-		hasoid = false;
-	}
-
-	tupDesc = ExecTypeFromTL(planstate->plan->targetlist, hasoid);
+	tupDesc = ExecTypeFromTL(planstate->plan->targetlist);
 	planstate->ps_ResultTupleDesc = tupDesc;
 }
 
@@ -1204,9 +1193,9 @@ slot_getsomeattrs(TupleTableSlot *slot, int attnum)
  * ----------------------------------------------------------------
  */
 TupleDesc
-ExecTypeFromTL(List *targetList, bool hasoid)
+ExecTypeFromTL(List *targetList)
 {
-	return ExecTypeFromTLInternal(targetList, hasoid, false);
+	return ExecTypeFromTLInternal(targetList, false);
 }
 
 /* ----------------------------------------------------------------
@@ -1216,13 +1205,13 @@ ExecTypeFromTL(List *targetList, bool hasoid)
  * ----------------------------------------------------------------
  */
 TupleDesc
-ExecCleanTypeFromTL(List *targetList, bool hasoid)
+ExecCleanTypeFromTL(List *targetList)
 {
-	return ExecTypeFromTLInternal(targetList, hasoid, true);
+	return ExecTypeFromTLInternal(targetList, true);
 }
 
 static TupleDesc
-ExecTypeFromTLInternal(List *targetList, bool hasoid, bool skipjunk)
+ExecTypeFromTLInternal(List *targetList, bool skipjunk)
 {
 	TupleDesc	typeInfo;
 	ListCell   *l;
@@ -1233,7 +1222,7 @@ ExecTypeFromTLInternal(List *targetList, bool hasoid, bool skipjunk)
 		len = ExecCleanTargetListLength(targetList);
 	else
 		len = ExecTargetListLength(targetList);
-	typeInfo = CreateTemplateTupleDesc(len, hasoid);
+	typeInfo = CreateTemplateTupleDesc(len);
 
 	foreach(l, targetList)
 	{
@@ -1269,7 +1258,7 @@ ExecTypeFromExprList(List *exprList)
 	ListCell   *lc;
 	int			cur_resno = 1;
 
-	typeInfo = CreateTemplateTupleDesc(list_length(exprList), false);
+	typeInfo = CreateTemplateTupleDesc(list_length(exprList));
 
 	foreach(lc, exprList)
 	{
diff --git a/src/backend/executor/execUtils.c b/src/backend/executor/execUtils.c
index f9e7bb479f1..c4f0fda0ed7 100644
--- a/src/backend/executor/execUtils.c
+++ b/src/backend/executor/execUtils.c
@@ -144,7 +144,6 @@ CreateExecutorState(void)
 	estate->es_tupleTable = NIL;
 
 	estate->es_processed = 0;
-	estate->es_lastoid = InvalidOid;
 
 	estate->es_top_eflags = 0;
 	estate->es_instrument = 0;
@@ -506,7 +505,6 @@ tlist_matches_tupdesc(PlanState *ps, List *tlist, Index varno, TupleDesc tupdesc
 {
 	int			numattrs = tupdesc->natts;
 	int			attrno;
-	bool		hasoid;
 	ListCell   *tlist_item = list_head(tlist);
 
 	/* Check the tlist attributes */
@@ -551,14 +549,6 @@ tlist_matches_tupdesc(PlanState *ps, List *tlist, Index varno, TupleDesc tupdesc
 	if (tlist_item)
 		return false;			/* tlist too long */
 
-	/*
-	 * If the plan context requires a particular hasoid setting, then that has
-	 * to match, too.
-	 */
-	if (ExecContextForcesOids(ps, &hasoid) &&
-		hasoid != tupdesc->tdhasoid)
-		return false;
-
 	return true;
 }
 
diff --git a/src/backend/executor/functions.c b/src/backend/executor/functions.c
index 23545896d4d..9f898513edc 100644
--- a/src/backend/executor/functions.c
+++ b/src/backend/executor/functions.c
@@ -1717,7 +1717,7 @@ check_sql_fn_retval(Oid func_id, Oid rettype, List *queryTreeList,
 
 		/* Set up junk filter if needed */
 		if (junkFilter)
-			*junkFilter = ExecInitJunkFilter(tlist, false, NULL);
+			*junkFilter = ExecInitJunkFilter(tlist, NULL);
 	}
 	else if (fn_typtype == TYPTYPE_COMPOSITE || rettype == RECORDOID)
 	{
@@ -1770,7 +1770,7 @@ check_sql_fn_retval(Oid func_id, Oid rettype, List *queryTreeList,
 				}
 				/* Set up junk filter if needed */
 				if (junkFilter)
-					*junkFilter = ExecInitJunkFilter(tlist, false, NULL);
+					*junkFilter = ExecInitJunkFilter(tlist, NULL);
 				return false;	/* NOT returning whole tuple */
 			}
 		}
@@ -1786,7 +1786,7 @@ check_sql_fn_retval(Oid func_id, Oid rettype, List *queryTreeList,
 			 * what the caller expects will happen at runtime.
 			 */
 			if (junkFilter)
-				*junkFilter = ExecInitJunkFilter(tlist, false, NULL);
+				*junkFilter = ExecInitJunkFilter(tlist, NULL);
 			return true;
 		}
 		Assert(tupdesc);
diff --git a/src/backend/executor/nodeAgg.c b/src/backend/executor/nodeAgg.c
index 85f1ec7140f..77324f6b0c6 100644
--- a/src/backend/executor/nodeAgg.c
+++ b/src/backend/executor/nodeAgg.c
@@ -1396,7 +1396,7 @@ find_hash_columns(AggState *aggstate)
 				Max(varNumber + 1, perhash->largestGrpColIdx);
 		}
 
-		hashDesc = ExecTypeFromTL(hashTlist, false);
+		hashDesc = ExecTypeFromTL(hashTlist);
 
 		execTuplesHashPrepare(perhash->numCols,
 							  perhash->aggnode->grpOperators,
@@ -3060,7 +3060,7 @@ build_pertrans_for_aggref(AggStatePerTrans pertrans,
 	 */
 	if (numSortCols > 0 || aggref->aggfilter)
 	{
-		pertrans->sortdesc = ExecTypeFromTL(aggref->args, false);
+		pertrans->sortdesc = ExecTypeFromTL(aggref->args);
 		pertrans->sortslot =
 			ExecInitExtraTupleSlot(estate, pertrans->sortdesc);
 	}
diff --git a/src/backend/executor/nodeCustom.c b/src/backend/executor/nodeCustom.c
index ab3e34790e8..aaf72bf6c95 100644
--- a/src/backend/executor/nodeCustom.c
+++ b/src/backend/executor/nodeCustom.c
@@ -72,7 +72,7 @@ ExecInitCustomScan(CustomScan *cscan, EState *estate, int eflags)
 	{
 		TupleDesc	scan_tupdesc;
 
-		scan_tupdesc = ExecTypeFromTL(cscan->custom_scan_tlist, false);
+		scan_tupdesc = ExecTypeFromTL(cscan->custom_scan_tlist);
 		ExecInitScanTupleSlot(estate, &css->ss, scan_tupdesc);
 		/* Node's targetlist will contain Vars with varno = INDEX_VAR */
 		tlistvarno = INDEX_VAR;
diff --git a/src/backend/executor/nodeForeignscan.c b/src/backend/executor/nodeForeignscan.c
index 5d2cd0ed717..ac16d0a4dfa 100644
--- a/src/backend/executor/nodeForeignscan.c
+++ b/src/backend/executor/nodeForeignscan.c
@@ -179,7 +179,7 @@ ExecInitForeignScan(ForeignScan *node, EState *estate, int eflags)
 	{
 		TupleDesc	scan_tupdesc;
 
-		scan_tupdesc = ExecTypeFromTL(node->fdw_scan_tlist, false);
+		scan_tupdesc = ExecTypeFromTL(node->fdw_scan_tlist);
 		ExecInitScanTupleSlot(estate, &scanstate->ss, scan_tupdesc);
 		/* Node's targetlist will contain Vars with varno = INDEX_VAR */
 		tlistvarno = INDEX_VAR;
diff --git a/src/backend/executor/nodeFunctionscan.c b/src/backend/executor/nodeFunctionscan.c
index 0596adbb2f1..fb717d8e816 100644
--- a/src/backend/executor/nodeFunctionscan.c
+++ b/src/backend/executor/nodeFunctionscan.c
@@ -383,7 +383,7 @@ ExecInitFunctionScan(FunctionScan *node, EState *estate, int eflags)
 		else if (functypclass == TYPEFUNC_SCALAR)
 		{
 			/* Base data type, i.e. scalar */
-			tupdesc = CreateTemplateTupleDesc(1, false);
+			tupdesc = CreateTemplateTupleDesc(1);
 			TupleDescInitEntry(tupdesc,
 							   (AttrNumber) 1,
 							   NULL,	/* don't care about the name here */
@@ -453,7 +453,7 @@ ExecInitFunctionScan(FunctionScan *node, EState *estate, int eflags)
 		if (node->funcordinality)
 			natts++;
 
-		scan_tupdesc = CreateTemplateTupleDesc(natts, false);
+		scan_tupdesc = CreateTemplateTupleDesc(natts);
 
 		for (i = 0; i < nfuncs; i++)
 		{
diff --git a/src/backend/executor/nodeIndexonlyscan.c b/src/backend/executor/nodeIndexonlyscan.c
index 865a056c027..17b3cfd6b7a 100644
--- a/src/backend/executor/nodeIndexonlyscan.c
+++ b/src/backend/executor/nodeIndexonlyscan.c
@@ -526,7 +526,7 @@ ExecInitIndexOnlyScan(IndexOnlyScan *node, EState *estate, int eflags)
 	 * types of the original datums.  (It's the AM's responsibility to return
 	 * suitable data anyway.)
 	 */
-	tupDesc = ExecTypeFromTL(node->indextlist, false);
+	tupDesc = ExecTypeFromTL(node->indextlist);
 	ExecInitScanTupleSlot(estate, &indexstate->ss, tupDesc);
 
 	/*
diff --git a/src/backend/executor/nodeModifyTable.c b/src/backend/executor/nodeModifyTable.c
index e2836b75ff3..802f61c05f9 100644
--- a/src/backend/executor/nodeModifyTable.c
+++ b/src/backend/executor/nodeModifyTable.c
@@ -39,6 +39,8 @@
 
 #include "access/htup_details.h"
 #include "access/xact.h"
+#include "catalog/catalog.h"
+#include "catalog/objectaddress.h"
 #include "commands/trigger.h"
 #include "executor/execPartition.h"
 #include "executor/executor.h"
@@ -269,7 +271,6 @@ ExecInsert(ModifyTableState *mtstate,
 	HeapTuple	tuple;
 	ResultRelInfo *resultRelInfo;
 	Relation	resultRelationDesc;
-	Oid			newId;
 	List	   *recheckIndexes = NIL;
 	TupleTableSlot *result = NULL;
 	TransitionCaptureState *ar_insert_trig_tcs;
@@ -288,21 +289,6 @@ ExecInsert(ModifyTableState *mtstate,
 	resultRelInfo = estate->es_result_relation_info;
 	resultRelationDesc = resultRelInfo->ri_RelationDesc;
 
-	/*
-	 * If the result relation has OIDs, force the tuple's OID to zero so that
-	 * heap_insert will assign a fresh OID.  Usually the OID already will be
-	 * zero at this point, but there are corner cases where the plan tree can
-	 * return a tuple extracted literally from some table with the same
-	 * rowtype.
-	 *
-	 * XXX if we ever wanted to allow users to assign their own OIDs to new
-	 * rows, this'd be the place to do it.  For the moment, we make a point of
-	 * doing this before calling triggers, so that a user-supplied trigger
-	 * could hack the OID if desired.
-	 */
-	if (resultRelationDesc->rd_rel->relhasoids)
-		HeapTupleSetOid(tuple, InvalidOid);
-
 	/*
 	 * BEFORE ROW INSERT Triggers.
 	 *
@@ -335,8 +321,6 @@ ExecInsert(ModifyTableState *mtstate,
 
 		/* trigger might have changed tuple */
 		tuple = ExecMaterializeSlot(slot);
-
-		newId = InvalidOid;
 	}
 	else if (resultRelInfo->ri_FdwRoutine)
 	{
@@ -359,8 +343,6 @@ ExecInsert(ModifyTableState *mtstate,
 		 * tableoid column, so initialize t_tableOid before evaluating them.
 		 */
 		tuple->t_tableOid = RelationGetRelid(resultRelationDesc);
-
-		newId = InvalidOid;
 	}
 	else
 	{
@@ -480,10 +462,10 @@ ExecInsert(ModifyTableState *mtstate,
 			HeapTupleHeaderSetSpeculativeToken(tuple->t_data, specToken);
 
 			/* insert the tuple, with the speculative token */
-			newId = heap_insert(resultRelationDesc, tuple,
-								estate->es_output_cid,
-								HEAP_INSERT_SPECULATIVE,
-								NULL);
+			heap_insert(resultRelationDesc, tuple,
+						estate->es_output_cid,
+						HEAP_INSERT_SPECULATIVE,
+						NULL);
 
 			/* insert index entries for tuple */
 			recheckIndexes = ExecInsertIndexTuples(slot, &(tuple->t_self),
@@ -526,9 +508,9 @@ ExecInsert(ModifyTableState *mtstate,
 			 * Note: heap_insert returns the tid (location) of the new tuple
 			 * in the t_self field.
 			 */
-			newId = heap_insert(resultRelationDesc, tuple,
-								estate->es_output_cid,
-								0, NULL);
+			heap_insert(resultRelationDesc, tuple,
+						estate->es_output_cid,
+						0, NULL);
 
 			/* insert index entries for tuple */
 			if (resultRelInfo->ri_NumIndices > 0)
@@ -541,7 +523,6 @@ ExecInsert(ModifyTableState *mtstate,
 	if (canSetTag)
 	{
 		(estate->es_processed)++;
-		estate->es_lastoid = newId;
 		setLastTid(&(tuple->t_self));
 	}
 
@@ -2493,8 +2474,7 @@ ExecInitModifyTable(ModifyTable *node, EState *estate, int eflags)
 		 * the tupdesc in the parent's state: it can be reused by partitions
 		 * with an identical descriptor to the parent.
 		 */
-		tupDesc = ExecTypeFromTL((List *) node->onConflictSet,
-								 relationDesc->tdhasoid);
+		tupDesc = ExecTypeFromTL((List *) node->onConflictSet);
 		mtstate->mt_conflproj =
 			ExecInitExtraTupleSlot(mtstate->ps.state,
 								   mtstate->mt_partition_tuple_routing ?
@@ -2608,7 +2588,6 @@ ExecInitModifyTable(ModifyTable *node, EState *estate, int eflags)
 										subplan->targetlist);
 
 				j = ExecInitJunkFilter(subplan->targetlist,
-									   resultRelInfo->ri_RelationDesc->rd_att->tdhasoid,
 									   ExecInitExtraTupleSlot(estate, NULL));
 
 				if (operation == CMD_UPDATE || operation == CMD_DELETE)
diff --git a/src/backend/executor/nodeSubplan.c b/src/backend/executor/nodeSubplan.c
index 63de981034d..e4b9cd80bc3 100644
--- a/src/backend/executor/nodeSubplan.c
+++ b/src/backend/executor/nodeSubplan.c
@@ -967,7 +967,7 @@ ExecInitSubPlan(SubPlan *subplan, PlanState *parent)
 		 * (hack alert!).  The righthand expressions will be evaluated in our
 		 * own innerecontext.
 		 */
-		tupDescLeft = ExecTypeFromTL(lefttlist, false);
+		tupDescLeft = ExecTypeFromTL(lefttlist);
 		slot = ExecInitExtraTupleSlot(estate, tupDescLeft);
 		sstate->projLeft = ExecBuildProjectionInfo(lefttlist,
 												   NULL,
@@ -975,7 +975,7 @@ ExecInitSubPlan(SubPlan *subplan, PlanState *parent)
 												   parent,
 												   NULL);
 
-		sstate->descRight = tupDescRight = ExecTypeFromTL(righttlist, false);
+		sstate->descRight = tupDescRight = ExecTypeFromTL(righttlist);
 		slot = ExecInitExtraTupleSlot(estate, tupDescRight);
 		sstate->projRight = ExecBuildProjectionInfo(righttlist,
 													sstate->innerecontext,
diff --git a/src/backend/executor/spi.c b/src/backend/executor/spi.c
index 19212738568..28a247441ff 100644
--- a/src/backend/executor/spi.c
+++ b/src/backend/executor/spi.c
@@ -43,7 +43,6 @@
  * when entering/exiting a SPI nesting level.
  */
 uint64		SPI_processed = 0;
-Oid			SPI_lastoid = InvalidOid;
 SPITupleTable *SPI_tuptable = NULL;
 int			SPI_result = 0;
 
@@ -128,7 +127,6 @@ SPI_connect_ext(int options)
 
 	_SPI_current = &(_SPI_stack[_SPI_connected]);
 	_SPI_current->processed = 0;
-	_SPI_current->lastoid = InvalidOid;
 	_SPI_current->tuptable = NULL;
 	_SPI_current->execSubid = InvalidSubTransactionId;
 	slist_init(&_SPI_current->tuptables);
@@ -139,7 +137,6 @@ SPI_connect_ext(int options)
 	_SPI_current->atomic = (options & SPI_OPT_NONATOMIC ? false : true);
 	_SPI_current->internal_xact = false;
 	_SPI_current->outer_processed = SPI_processed;
-	_SPI_current->outer_lastoid = SPI_lastoid;
 	_SPI_current->outer_tuptable = SPI_tuptable;
 	_SPI_current->outer_result = SPI_result;
 
@@ -169,7 +166,6 @@ SPI_connect_ext(int options)
 	 * depend on state of an outer caller.
 	 */
 	SPI_processed = 0;
-	SPI_lastoid = InvalidOid;
 	SPI_tuptable = NULL;
 	SPI_result = 0;
 
@@ -199,7 +195,6 @@ SPI_finish(void)
 	 * pointing at a just-deleted tuptable
 	 */
 	SPI_processed = _SPI_current->outer_processed;
-	SPI_lastoid = _SPI_current->outer_lastoid;
 	SPI_tuptable = _SPI_current->outer_tuptable;
 	SPI_result = _SPI_current->outer_result;
 
@@ -296,7 +291,6 @@ SPICleanup(void)
 	_SPI_connected = -1;
 	/* Reset API global variables, too */
 	SPI_processed = 0;
-	SPI_lastoid = InvalidOid;
 	SPI_tuptable = NULL;
 	SPI_result = 0;
 }
@@ -363,7 +357,6 @@ AtEOSubXact_SPI(bool isCommit, SubTransactionId mySubid)
 		 * be already gone.
 		 */
 		SPI_processed = connection->outer_processed;
-		SPI_lastoid = connection->outer_lastoid;
 		SPI_tuptable = connection->outer_tuptable;
 		SPI_result = connection->outer_result;
 
@@ -878,8 +871,6 @@ SPI_modifytuple(Relation rel, HeapTuple tuple, int natts, int *attnum,
 		mtuple->t_data->t_ctid = tuple->t_data->t_ctid;
 		mtuple->t_self = tuple->t_self;
 		mtuple->t_tableOid = tuple->t_tableOid;
-		if (rel->rd_att->tdhasoid)
-			HeapTupleSetOid(mtuple, HeapTupleGetOid(tuple));
 	}
 	else
 	{
@@ -910,7 +901,7 @@ SPI_fnumber(TupleDesc tupdesc, const char *fname)
 			return res + 1;
 	}
 
-	sysatt = SystemAttributeByName(fname, true /* "oid" will be accepted */ );
+	sysatt = SystemAttributeByName(fname);
 	if (sysatt != NULL)
 		return sysatt->attnum;
 
@@ -935,7 +926,7 @@ SPI_fname(TupleDesc tupdesc, int fnumber)
 	if (fnumber > 0)
 		att = TupleDescAttr(tupdesc, fnumber - 1);
 	else
-		att = SystemAttributeDefinition(fnumber, true);
+		att = SystemAttributeDefinition(fnumber);
 
 	return pstrdup(NameStr(att->attname));
 }
@@ -965,7 +956,7 @@ SPI_getvalue(HeapTuple tuple, TupleDesc tupdesc, int fnumber)
 	if (fnumber > 0)
 		typoid = TupleDescAttr(tupdesc, fnumber - 1)->atttypid;
 	else
-		typoid = (SystemAttributeDefinition(fnumber, true))->atttypid;
+		typoid = (SystemAttributeDefinition(fnumber))->atttypid;
 
 	getTypeOutputInfo(typoid, &foutoid, &typisvarlena);
 
@@ -1007,7 +998,7 @@ SPI_gettype(TupleDesc tupdesc, int fnumber)
 	if (fnumber > 0)
 		typoid = TupleDescAttr(tupdesc, fnumber - 1)->atttypid;
 	else
-		typoid = (SystemAttributeDefinition(fnumber, true))->atttypid;
+		typoid = (SystemAttributeDefinition(fnumber))->atttypid;
 
 	typeTuple = SearchSysCache1(TYPEOID, ObjectIdGetDatum(typoid));
 
@@ -1043,7 +1034,7 @@ SPI_gettypeid(TupleDesc tupdesc, int fnumber)
 	if (fnumber > 0)
 		return TupleDescAttr(tupdesc, fnumber - 1)->atttypid;
 	else
-		return (SystemAttributeDefinition(fnumber, true))->atttypid;
+		return (SystemAttributeDefinition(fnumber))->atttypid;
 }
 
 char *
@@ -2051,7 +2042,6 @@ _SPI_execute_plan(SPIPlanPtr plan, ParamListInfo paramLI,
 {
 	int			my_res = 0;
 	uint64		my_processed = 0;
-	Oid			my_lastoid = InvalidOid;
 	SPITupleTable *my_tuptable = NULL;
 	int			res = 0;
 	bool		pushed_active_snap = false;
@@ -2183,7 +2173,6 @@ _SPI_execute_plan(SPIPlanPtr plan, ParamListInfo paramLI,
 			DestReceiver *dest;
 
 			_SPI_current->processed = 0;
-			_SPI_current->lastoid = InvalidOid;
 			_SPI_current->tuptable = NULL;
 
 			if (stmt->utilityStmt)
@@ -2324,7 +2313,6 @@ _SPI_execute_plan(SPIPlanPtr plan, ParamListInfo paramLI,
 			if (canSetTag)
 			{
 				my_processed = _SPI_current->processed;
-				my_lastoid = _SPI_current->lastoid;
 				SPI_freetuptable(my_tuptable);
 				my_tuptable = _SPI_current->tuptable;
 				my_res = res;
@@ -2372,7 +2360,6 @@ fail:
 
 	/* Save results for caller */
 	SPI_processed = my_processed;
-	SPI_lastoid = my_lastoid;
 	SPI_tuptable = my_tuptable;
 
 	/* tuptable now is caller's responsibility, not SPI's */
@@ -2484,7 +2471,6 @@ _SPI_pquery(QueryDesc *queryDesc, bool fire_triggers, uint64 tcount)
 	ExecutorRun(queryDesc, ForwardScanDirection, tcount, true);
 
 	_SPI_current->processed = queryDesc->estate->es_processed;
-	_SPI_current->lastoid = queryDesc->estate->es_lastoid;
 
 	if ((res == SPI_OK_SELECT || queryDesc->plannedstmt->hasReturning) &&
 		queryDesc->dest->mydest == DestSPI)
diff --git a/src/backend/foreign/foreign.c b/src/backend/foreign/foreign.c
index a0bcc042cea..8731c955c62 100644
--- a/src/backend/foreign/foreign.c
+++ b/src/backend/foreign/foreign.c
@@ -189,7 +189,7 @@ GetUserMapping(Oid userid, Oid serverid)
 						MappingUserName(userid))));
 
 	um = (UserMapping *) palloc(sizeof(UserMapping));
-	um->umid = HeapTupleGetOid(tp);
+	um->umid = ((Form_pg_user_mapping) GETSTRUCT(tp))->oid;
 	um->userid = userid;
 	um->serverid = serverid;
 
diff --git a/src/backend/optimizer/util/plancat.c b/src/backend/optimizer/util/plancat.c
index 0c88c90de4d..a570ac0aabe 100644
--- a/src/backend/optimizer/util/plancat.c
+++ b/src/backend/optimizer/util/plancat.c
@@ -1694,8 +1694,7 @@ build_index_tlist(PlannerInfo *root, IndexOptInfo *index,
 			const FormData_pg_attribute *att_tup;
 
 			if (indexkey < 0)
-				att_tup = SystemAttributeDefinition(indexkey,
-													heapRelation->rd_rel->relhasoids);
+				att_tup = SystemAttributeDefinition(indexkey);
 			else
 				att_tup = TupleDescAttr(heapRelation->rd_att, indexkey - 1);
 
diff --git a/src/backend/parser/gram.y b/src/backend/parser/gram.y
index 2effd511358..f9d5172fd00 100644
--- a/src/backend/parser/gram.y
+++ b/src/backend/parser/gram.y
@@ -440,7 +440,7 @@ static Node *makeRecursiveViewSelect(char *relname, List *aliases, Node *query);
 %type <boolean> opt_instead
 %type <boolean> opt_unique opt_concurrently opt_verbose opt_full
 %type <boolean> opt_freeze opt_analyze opt_default opt_recheck
-%type <defelt>	opt_binary opt_oids copy_delimiter
+%type <defelt>	opt_binary copy_delimiter
 
 %type <boolean> copy_from opt_program
 
@@ -2311,20 +2311,6 @@ alter_table_cmd:
 					n->missing_ok = false;
 					$$ = (Node *)n;
 				}
-			/* ALTER TABLE <name> SET WITH OIDS  */
-			| SET WITH OIDS
-				{
-					AlterTableCmd *n = makeNode(AlterTableCmd);
-					n->subtype = AT_AddOids;
-					$$ = (Node *)n;
-				}
-			/* ALTER TABLE <name> SET WITHOUT OIDS  */
-			| SET WITHOUT OIDS
-				{
-					AlterTableCmd *n = makeNode(AlterTableCmd);
-					n->subtype = AT_DropOids;
-					$$ = (Node *)n;
-				}
 			/* ALTER TABLE <name> CLUSTER ON <indexname> */
 			| CLUSTER ON name
 				{
@@ -2961,23 +2947,23 @@ ClosePortalStmt:
  *				syntax had a hard-wired, space-separated set of options.
  *
  *				Really old syntax, from versions 7.2 and prior:
- *				COPY [ BINARY ] table [ WITH OIDS ] FROM/TO file
+ *				COPY [ BINARY ] table FROM/TO file
  *					[ [ USING ] DELIMITERS 'delimiter' ] ]
  *					[ WITH NULL AS 'null string' ]
  *				This option placement is not supported with COPY (query...).
  *
  *****************************************************************************/
 
-CopyStmt:	COPY opt_binary qualified_name opt_column_list opt_oids
+CopyStmt:	COPY opt_binary qualified_name opt_column_list
 			copy_from opt_program copy_file_name copy_delimiter opt_with copy_options
 				{
 					CopyStmt *n = makeNode(CopyStmt);
 					n->relation = $3;
 					n->query = NULL;
 					n->attlist = $4;
-					n->is_from = $6;
-					n->is_program = $7;
-					n->filename = $8;
+					n->is_from = $5;
+					n->is_program = $6;
+					n->filename = $7;
 
 					if (n->is_program && n->filename == NULL)
 						ereport(ERROR,
@@ -2989,12 +2975,10 @@ CopyStmt:	COPY opt_binary qualified_name opt_column_list opt_oids
 					/* Concatenate user-supplied flags */
 					if ($2)
 						n->options = lappend(n->options, $2);
-					if ($5)
-						n->options = lappend(n->options, $5);
-					if ($9)
-						n->options = lappend(n->options, $9);
-					if ($11)
-						n->options = list_concat(n->options, $11);
+					if ($8)
+						n->options = lappend(n->options, $8);
+					if ($10)
+						n->options = list_concat(n->options, $10);
 					$$ = (Node *)n;
 				}
 			| COPY '(' PreparableStmt ')' TO opt_program copy_file_name opt_with copy_options
@@ -3054,10 +3038,6 @@ copy_opt_item:
 				{
 					$$ = makeDefElem("format", (Node *)makeString("binary"), @1);
 				}
-			| OIDS
-				{
-					$$ = makeDefElem("oids", (Node *)makeInteger(true), @1);
-				}
 			| FREEZE
 				{
 					$$ = makeDefElem("freeze", (Node *)makeInteger(true), @1);
@@ -3118,14 +3098,6 @@ opt_binary:
 			| /*EMPTY*/								{ $$ = NULL; }
 		;
 
-opt_oids:
-			WITH OIDS
-				{
-					$$ = makeDefElem("oids", (Node *)makeInteger(true), @1);
-				}
-			| /*EMPTY*/								{ $$ = NULL; }
-		;
-
 copy_delimiter:
 			opt_using DELIMITERS Sconst
 				{
@@ -3942,10 +3914,9 @@ part_elem: ColId opt_collate opt_class
 					$$ = n;
 				}
 		;
-/* WITH (options) is preferred, WITH OIDS and WITHOUT OIDS are legacy forms */
+/* WITHOUT OIDS is legacy only */
 OptWith:
 			WITH reloptions				{ $$ = $2; }
-			| WITH OIDS					{ $$ = list_make1(makeDefElem("oids", (Node *) makeInteger(true), @1)); }
 			| WITHOUT OIDS				{ $$ = list_make1(makeDefElem("oids", (Node *) makeInteger(false), @1)); }
 			| /*EMPTY*/					{ $$ = NIL; }
 		;
diff --git a/src/backend/parser/parse_clause.c b/src/backend/parser/parse_clause.c
index 660011a3ec3..4ba51203a6a 100644
--- a/src/backend/parser/parse_clause.c
+++ b/src/backend/parser/parse_clause.c
@@ -249,46 +249,6 @@ setTargetTable(ParseState *pstate, RangeVar *relation,
 	return rtindex;
 }
 
-/*
- * Given a relation-options list (of DefElems), return true iff the specified
- * table/result set should be created with OIDs. This needs to be done after
- * parsing the query string because the return value can depend upon the
- * default_with_oids GUC var.
- *
- * In some situations, we want to reject an OIDS option even if it's present.
- * That's (rather messily) handled here rather than reloptions.c, because that
- * code explicitly punts checking for oids to here.
- */
-bool
-interpretOidsOption(List *defList, bool allowOids)
-{
-	ListCell   *cell;
-
-	/* Scan list to see if OIDS was included */
-	foreach(cell, defList)
-	{
-		DefElem    *def = (DefElem *) lfirst(cell);
-
-		if (def->defnamespace == NULL &&
-			strcmp(def->defname, "oids") == 0)
-		{
-			if (!allowOids)
-				ereport(ERROR,
-						(errcode(ERRCODE_INVALID_PARAMETER_VALUE),
-						 errmsg("unrecognized parameter \"%s\"",
-								def->defname)));
-			return defGetBoolean(def);
-		}
-	}
-
-	/* Force no-OIDS result if caller disallows OIDS. */
-	if (!allowOids)
-		return false;
-
-	/* OIDS option was not specified, so use default. */
-	return default_with_oids;
-}
-
 /*
  * Extract all not-in-common columns from column lists of a source table
  */
diff --git a/src/backend/parser/parse_oper.c b/src/backend/parser/parse_oper.c
index b279e1236ad..2f780b9941d 100644
--- a/src/backend/parser/parse_oper.c
+++ b/src/backend/parser/parse_oper.c
@@ -244,7 +244,7 @@ get_sort_group_operators(Oid argtype,
 Oid
 oprid(Operator op)
 {
-	return HeapTupleGetOid(op);
+	return ((Form_pg_operator) GETSTRUCT(op))->oid;
 }
 
 /* given operator tuple, return the underlying function's OID */
diff --git a/src/backend/parser/parse_relation.c b/src/backend/parser/parse_relation.c
index 66a7105b099..f6ddb4f38cf 100644
--- a/src/backend/parser/parse_relation.c
+++ b/src/backend/parser/parse_relation.c
@@ -1528,7 +1528,7 @@ addRangeTableEntryForFunction(ParseState *pstate,
 		else if (functypclass == TYPEFUNC_SCALAR)
 		{
 			/* Base data type, i.e. scalar */
-			tupdesc = CreateTemplateTupleDesc(1, false);
+			tupdesc = CreateTemplateTupleDesc(1);
 			TupleDescInitEntry(tupdesc,
 							   (AttrNumber) 1,
 							   chooseScalarFunctionAlias(funcexpr, funcname,
@@ -1545,7 +1545,7 @@ addRangeTableEntryForFunction(ParseState *pstate,
 			 * Use the column definition list to construct a tupdesc and fill
 			 * in the RangeTblFunction's lists.
 			 */
-			tupdesc = CreateTemplateTupleDesc(list_length(coldeflist), false);
+			tupdesc = CreateTemplateTupleDesc(list_length(coldeflist));
 			i = 1;
 			foreach(col, coldeflist)
 			{
@@ -1619,7 +1619,7 @@ addRangeTableEntryForFunction(ParseState *pstate,
 			totalatts++;
 
 		/* Merge the tuple descs of each function into a composite one */
-		tupdesc = CreateTemplateTupleDesc(totalatts, false);
+		tupdesc = CreateTemplateTupleDesc(totalatts);
 		natts = 0;
 		for (i = 0; i < nfuncs; i++)
 		{
@@ -3113,10 +3113,7 @@ attnameAttNum(Relation rd, const char *attname, bool sysColOK)
 	if (sysColOK)
 	{
 		if ((i = specialAttNum(attname)) != InvalidAttrNumber)
-		{
-			if (i != ObjectIdAttributeNumber || rd->rd_rel->relhasoids)
-				return i;
-		}
+			return i;
 	}
 
 	/* on failure */
@@ -3130,15 +3127,14 @@ attnameAttNum(Relation rd, const char *attname, bool sysColOK)
  *
  * Note: this only discovers whether the name could be a system attribute.
  * Caller needs to verify that it really is an attribute of the rel,
- * at least in the case of "oid", which is now optional.
+ * at least in the case of "oid", which is now optional. XXX?
  */
 static int
 specialAttNum(const char *attname)
 {
 	const FormData_pg_attribute *sysatt;
 
-	sysatt = SystemAttributeByName(attname,
-								   true /* "oid" will be accepted */ );
+	sysatt = SystemAttributeByName(attname);
 	if (sysatt != NULL)
 		return sysatt->attnum;
 	return InvalidAttrNumber;
@@ -3159,7 +3155,7 @@ attnumAttName(Relation rd, int attid)
 	{
 		const FormData_pg_attribute *sysatt;
 
-		sysatt = SystemAttributeDefinition(attid, rd->rd_rel->relhasoids);
+		sysatt = SystemAttributeDefinition(attid);
 		return &sysatt->attname;
 	}
 	if (attid > rd->rd_att->natts)
@@ -3181,7 +3177,7 @@ attnumTypeId(Relation rd, int attid)
 	{
 		const FormData_pg_attribute *sysatt;
 
-		sysatt = SystemAttributeDefinition(attid, rd->rd_rel->relhasoids);
+		sysatt = SystemAttributeDefinition(attid);
 		return sysatt->atttypid;
 	}
 	if (attid > rd->rd_att->natts)
diff --git a/src/backend/parser/parse_target.c b/src/backend/parser/parse_target.c
index 3d31be38d56..b8702d914dc 100644
--- a/src/backend/parser/parse_target.c
+++ b/src/backend/parser/parse_target.c
@@ -1503,7 +1503,7 @@ expandRecordVariable(ParseState *pstate, Var *var, int levelsup)
 		expandRTE(rte, var->varno, 0, var->location, false,
 				  &names, &vars);
 
-		tupleDesc = CreateTemplateTupleDesc(list_length(vars), false);
+		tupleDesc = CreateTemplateTupleDesc(list_length(vars));
 		i = 1;
 		forboth(lname, names, lvar, vars)
 		{
diff --git a/src/backend/parser/parse_type.c b/src/backend/parser/parse_type.c
index d959b6122a5..e767018df7d 100644
--- a/src/backend/parser/parse_type.c
+++ b/src/backend/parser/parse_type.c
@@ -230,7 +230,7 @@ LookupTypeNameOid(ParseState *pstate, const TypeName *typeName, bool missing_ok)
 		return InvalidOid;
 	}
 
-	typoid = HeapTupleGetOid(tup);
+	typoid = ((Form_pg_type) GETSTRUCT(tup))->oid;
 	ReleaseSysCache(tup);
 
 	return typoid;
@@ -277,7 +277,7 @@ typenameTypeId(ParseState *pstate, const TypeName *typeName)
 	Type		tup;
 
 	tup = typenameType(pstate, typeName, NULL);
-	typoid = HeapTupleGetOid(tup);
+	typoid = ((Form_pg_type) GETSTRUCT(tup))->oid;
 	ReleaseSysCache(tup);
 
 	return typoid;
@@ -296,7 +296,7 @@ typenameTypeIdAndMod(ParseState *pstate, const TypeName *typeName,
 	Type		tup;
 
 	tup = typenameType(pstate, typeName, typmod_p);
-	*typeid_p = HeapTupleGetOid(tup);
+	*typeid_p = ((Form_pg_type) GETSTRUCT(tup))->oid;
 	ReleaseSysCache(tup);
 }
 
@@ -570,9 +570,13 @@ typeidType(Oid id)
 Oid
 typeTypeId(Type tp)
 {
+	Form_pg_type typ;
+
 	if (tp == NULL)				/* probably useless */
 		elog(ERROR, "typeTypeId() called with NULL type struct");
-	return HeapTupleGetOid(tp);
+
+	typ = (Form_pg_type) GETSTRUCT(tp);
+	return typ->oid;
 }
 
 /* given type (as type struct), return the length of type */
@@ -832,13 +836,15 @@ parseTypeString(const char *str, Oid *typeid_p, int32 *typmod_p, bool missing_ok
 	}
 	else
 	{
-		if (!((Form_pg_type) GETSTRUCT(tup))->typisdefined)
+		Form_pg_type typ = (Form_pg_type) GETSTRUCT(tup);
+
+		if (!typ->typisdefined)
 			ereport(ERROR,
 					(errcode(ERRCODE_UNDEFINED_OBJECT),
 					 errmsg("type \"%s\" is only a shell",
 							TypeNameToString(typeName)),
 					 parser_errposition(NULL, typeName->location)));
-		*typeid_p = HeapTupleGetOid(tup);
+		*typeid_p = typ->oid;
 		ReleaseSysCache(tup);
 	}
 }
diff --git a/src/backend/parser/parse_utilcmd.c b/src/backend/parser/parse_utilcmd.c
index 2e222d822b3..52582d0a13f 100644
--- a/src/backend/parser/parse_utilcmd.c
+++ b/src/backend/parser/parse_utilcmd.c
@@ -80,7 +80,6 @@ typedef struct
 	List	   *inhRelations;	/* relations to inherit from */
 	bool		isforeign;		/* true if CREATE/ALTER FOREIGN TABLE */
 	bool		isalter;		/* true if altering existing table */
-	bool		hasoids;		/* does relation have an OID column? */
 	List	   *columns;		/* ColumnDef items */
 	List	   *ckconstraints;	/* CHECK constraints */
 	List	   *fkconstraints;	/* FOREIGN KEY constraints */
@@ -168,7 +167,6 @@ transformCreateStmt(CreateStmt *stmt, const char *queryString)
 	Oid			namespaceid;
 	Oid			existing_relid;
 	ParseCallbackState pcbstate;
-	bool		like_found = false;
 	bool		is_foreign_table = IsA(stmt, CreateForeignTableStmt);
 
 	/*
@@ -247,18 +245,6 @@ transformCreateStmt(CreateStmt *stmt, const char *queryString)
 	cxt.partbound = stmt->partbound;
 	cxt.ofType = (stmt->ofTypename != NULL);
 
-	/*
-	 * Notice that we allow OIDs here only for plain tables, even though
-	 * foreign tables also support them.  This is necessary because the
-	 * default_with_oids GUC must apply only to plain tables and not any other
-	 * relkind; doing otherwise would break existing pg_dump files.  We could
-	 * allow explicit "WITH OIDS" while not allowing default_with_oids to
-	 * affect other relkinds, but it would complicate interpretOidsOption(),
-	 * and right now there's no WITH OIDS option in CREATE FOREIGN TABLE
-	 * anyway.
-	 */
-	cxt.hasoids = interpretOidsOption(stmt->options, !cxt.isforeign);
-
 	Assert(!stmt->ofTypename || !stmt->inhRelations);	/* grammar enforces */
 
 	if (stmt->ofTypename)
@@ -291,7 +277,6 @@ transformCreateStmt(CreateStmt *stmt, const char *queryString)
 				break;
 
 			case T_TableLikeClause:
-				like_found = true;
 				transformTableLikeClause(&cxt, (TableLikeClause *) element);
 				break;
 
@@ -302,20 +287,6 @@ transformCreateStmt(CreateStmt *stmt, const char *queryString)
 		}
 	}
 
-	/*
-	 * If we had any LIKE tables, they may require creation of an OID column
-	 * even though the command's own WITH clause didn't ask for one (or,
-	 * perhaps, even specifically rejected having one).  Insert a WITH option
-	 * to ensure that happens.  We prepend to the list because the first oid
-	 * option will be honored, and we want to override anything already there.
-	 * (But note that DefineRelation will override this again to add an OID
-	 * column if one appears in an inheritance parent table.)
-	 */
-	if (like_found && cxt.hasoids)
-		stmt->options = lcons(makeDefElem("oids",
-										  (Node *) makeInteger(true), -1),
-							  stmt->options);
-
 	/*
 	 * transformIndexConstraints wants cxt.alist to contain only index
 	 * statements, so transfer anything we already have into save_alist.
@@ -692,7 +663,7 @@ transformColumnDefinition(CreateStmtContext *cxt, ColumnDef *column)
 								 errmsg("identity columns are not supported on partitions")));
 
 					ctype = typenameType(cxt->pstate, column->typeName, NULL);
-					typeOid = HeapTupleGetOid(ctype);
+					typeOid = ((Form_pg_type) GETSTRUCT(ctype))->oid;
 					ReleaseSysCache(ctype);
 
 					if (saw_identity)
@@ -1079,9 +1050,6 @@ transformTableLikeClause(CreateStmtContext *cxt, TableLikeClause *table_like_cla
 		}
 	}
 
-	/* We use oids if at least one LIKE'ed table has oids. */
-	cxt->hasoids |= relation->rd_rel->relhasoids;
-
 	/*
 	 * Copy CHECK constraints if requested, being careful to adjust attribute
 	 * numbers so they match the child.
@@ -1245,7 +1213,7 @@ transformOfType(CreateStmtContext *cxt, TypeName *ofTypename)
 
 	tuple = typenameType(NULL, ofTypename, NULL);
 	check_of_type(tuple);
-	ofTypeId = HeapTupleGetOid(tuple);
+	ofTypeId = ((Form_pg_type) GETSTRUCT(tuple))->oid;
 	ofTypename->typeOid = ofTypeId; /* cached for later */
 
 	tupdesc = lookup_rowtype_tupdesc(ofTypeId, -1);
@@ -2078,8 +2046,7 @@ transformIndexConstraint(Constraint *constraint, CreateStmtContext *cxt)
 				attform = TupleDescAttr(heap_rel->rd_att, attnum - 1);
 			}
 			else
-				attform = SystemAttributeDefinition(attnum,
-													heap_rel->rd_rel->relhasoids);
+				attform = SystemAttributeDefinition(attnum);
 			attname = pstrdup(NameStr(attform->attname));
 
 			if (i < index_form->indnkeyatts)
@@ -2169,7 +2136,7 @@ transformIndexConstraint(Constraint *constraint, CreateStmtContext *cxt)
 				if (constraint->contype == CONSTR_PRIMARY)
 					column->is_not_null = true;
 			}
-			else if (SystemAttributeByName(key, cxt->hasoids) != NULL)
+			else if (SystemAttributeByName(key) != NULL)
 			{
 				/*
 				 * column will be a system column in the new table, so accept
@@ -2292,7 +2259,7 @@ transformIndexConstraint(Constraint *constraint, CreateStmtContext *cxt)
 
 		if (!found)
 		{
-			if (SystemAttributeByName(key, cxt->hasoids) != NULL)
+			if (SystemAttributeByName(key) != NULL)
 			{
 				/*
 				 * column will be a system column in the new table, so accept
@@ -2966,7 +2933,6 @@ transformAlterTableStmt(Oid relid, AlterTableStmt *stmt,
 	cxt.rel = rel;
 	cxt.inhRelations = NIL;
 	cxt.isalter = true;
-	cxt.hasoids = false;		/* need not be right */
 	cxt.columns = NIL;
 	cxt.ckconstraints = NIL;
 	cxt.fkconstraints = NIL;
@@ -3400,7 +3366,7 @@ transformColumnType(CreateStmtContext *cxt, ColumnDef *column)
 			ereport(ERROR,
 					(errcode(ERRCODE_DATATYPE_MISMATCH),
 					 errmsg("collations are not supported by type %s",
-							format_type_be(HeapTupleGetOid(ctype))),
+							format_type_be(typtup->oid)),
 					 parser_errposition(cxt->pstate,
 										column->collClause->location)));
 	}
diff --git a/src/backend/postmaster/autovacuum.c b/src/backend/postmaster/autovacuum.c
index 978089575b8..31e98db9d69 100644
--- a/src/backend/postmaster/autovacuum.c
+++ b/src/backend/postmaster/autovacuum.c
@@ -1910,7 +1910,7 @@ get_database_list(void)
 
 		avdb = (avw_dbase *) palloc(sizeof(avw_dbase));
 
-		avdb->adw_datid = HeapTupleGetOid(tup);
+		avdb->adw_datid = pgdatabase->oid;
 		avdb->adw_name = pstrdup(NameStr(pgdatabase->datname));
 		avdb->adw_frozenxid = pgdatabase->datfrozenxid;
 		avdb->adw_minmulti = pgdatabase->datminmxid;
@@ -2072,7 +2072,7 @@ do_autovacuum(void)
 			classForm->relkind != RELKIND_MATVIEW)
 			continue;
 
-		relid = HeapTupleGetOid(tuple);
+		relid = classForm->oid;
 
 		/*
 		 * Check if it is a temp table (presumably, of some other backend's).
@@ -2166,7 +2166,7 @@ do_autovacuum(void)
 		if (classForm->relpersistence == RELPERSISTENCE_TEMP)
 			continue;
 
-		relid = HeapTupleGetOid(tuple);
+		relid = classForm->oid;
 
 		/*
 		 * fetch reloptions -- if this toast table does not have them, try the
diff --git a/src/backend/postmaster/pgstat.c b/src/backend/postmaster/pgstat.c
index 42bccce0af4..b4b742ede30 100644
--- a/src/backend/postmaster/pgstat.c
+++ b/src/backend/postmaster/pgstat.c
@@ -1209,6 +1209,7 @@ pgstat_collect_oids(Oid catalogid)
 	HeapScanDesc scan;
 	HeapTuple	tup;
 	Snapshot	snapshot;
+	AttrNumber	anum_oid = get_object_attnum_oid(catalogid);
 
 	memset(&hash_ctl, 0, sizeof(hash_ctl));
 	hash_ctl.keysize = sizeof(Oid);
@@ -1224,7 +1225,11 @@ pgstat_collect_oids(Oid catalogid)
 	scan = heap_beginscan(rel, snapshot, 0, NULL);
 	while ((tup = heap_getnext(scan, ForwardScanDirection)) != NULL)
 	{
-		Oid			thisoid = HeapTupleGetOid(tup);
+		Oid			thisoid;
+		bool		isnull;
+
+		thisoid = heap_getattr(tup, anum_oid, RelationGetDescr(rel), &isnull);
+		Assert(!isnull);
 
 		CHECK_FOR_INTERRUPTS();
 
diff --git a/src/backend/replication/libpqwalreceiver/libpqwalreceiver.c b/src/backend/replication/libpqwalreceiver/libpqwalreceiver.c
index 1e1695ef4f4..e2b54265d78 100644
--- a/src/backend/replication/libpqwalreceiver/libpqwalreceiver.c
+++ b/src/backend/replication/libpqwalreceiver/libpqwalreceiver.c
@@ -868,7 +868,7 @@ libpqrcv_processTuples(PGresult *pgres, WalRcvExecResult *walres,
 	walres->tuplestore = tuplestore_begin_heap(true, false, work_mem);
 
 	/* Create tuple descriptor corresponding to expected result. */
-	walres->tupledesc = CreateTemplateTupleDesc(nRetTypes, false);
+	walres->tupledesc = CreateTemplateTupleDesc(nRetTypes);
 	for (coln = 0; coln < nRetTypes; coln++)
 		TupleDescInitEntry(walres->tupledesc, (AttrNumber) coln + 1,
 						   PQfname(pgres, coln), retTypes[coln], -1, 0);
diff --git a/src/backend/replication/logical/launcher.c b/src/backend/replication/logical/launcher.c
index ada16adb67b..ce089ac07ca 100644
--- a/src/backend/replication/logical/launcher.c
+++ b/src/backend/replication/logical/launcher.c
@@ -153,7 +153,7 @@ get_subscription_list(void)
 		oldcxt = MemoryContextSwitchTo(resultcxt);
 
 		sub = (Subscription *) palloc0(sizeof(Subscription));
-		sub->oid = HeapTupleGetOid(tup);
+		sub->oid = subform->oid;
 		sub->dbid = subform->subdbid;
 		sub->owner = subform->subowner;
 		sub->enabled = subform->subenabled;
diff --git a/src/backend/replication/walsender.c b/src/backend/replication/walsender.c
index 2683385ca6e..15ddf155874 100644
--- a/src/backend/replication/walsender.c
+++ b/src/backend/replication/walsender.c
@@ -392,7 +392,7 @@ IdentifySystem(void)
 	MemSet(nulls, false, sizeof(nulls));
 
 	/* need a tuple descriptor representing four columns */
-	tupdesc = CreateTemplateTupleDesc(4, false);
+	tupdesc = CreateTemplateTupleDesc(4);
 	TupleDescInitBuiltinEntry(tupdesc, (AttrNumber) 1, "systemid",
 							  TEXTOID, -1, 0);
 	TupleDescInitBuiltinEntry(tupdesc, (AttrNumber) 2, "timeline",
@@ -728,7 +728,7 @@ StartReplication(StartReplicationCmd *cmd)
 		 * like a surprising data type for this, but in theory int4 would not
 		 * be wide enough for this, as TimeLineID is unsigned.
 		 */
-		tupdesc = CreateTemplateTupleDesc(2, false);
+		tupdesc = CreateTemplateTupleDesc(2);
 		TupleDescInitBuiltinEntry(tupdesc, (AttrNumber) 1, "next_tli",
 								  INT8OID, -1, 0);
 		TupleDescInitBuiltinEntry(tupdesc, (AttrNumber) 2, "next_tli_startpos",
@@ -996,7 +996,7 @@ CreateReplicationSlot(CreateReplicationSlotCmd *cmd)
 	 * - fourth field: output plugin
 	 *----------
 	 */
-	tupdesc = CreateTemplateTupleDesc(4, false);
+	tupdesc = CreateTemplateTupleDesc(4);
 	TupleDescInitBuiltinEntry(tupdesc, (AttrNumber) 1, "slot_name",
 							  TEXTOID, -1, 0);
 	TupleDescInitBuiltinEntry(tupdesc, (AttrNumber) 2, "consistent_point",
diff --git a/src/backend/rewrite/rewriteDefine.c b/src/backend/rewrite/rewriteDefine.c
index d81a2ea342b..4c6cd978e81 100644
--- a/src/backend/rewrite/rewriteDefine.c
+++ b/src/backend/rewrite/rewriteDefine.c
@@ -128,14 +128,18 @@ InsertRule(const char *rulname,
 
 		ReleaseSysCache(oldtup);
 
-		rewriteObjectId = HeapTupleGetOid(tup);
+		rewriteObjectId = ((Form_pg_rewrite) GETSTRUCT(tup))->oid;
 		is_update = true;
 	}
 	else
 	{
+		rewriteObjectId = GetNewOidWithIndex(pg_rewrite_desc, RewriteOidIndexId, Anum_pg_rewrite_oid);
+
+		values[Anum_pg_rewrite_oid - 1] = ObjectIdGetDatum(rewriteObjectId);
+
 		tup = heap_form_tuple(pg_rewrite_desc->rd_att, values, nulls);
 
-		rewriteObjectId = CatalogTupleInsert(pg_rewrite_desc, tup);
+		CatalogTupleInsert(pg_rewrite_desc, tup);
 	}
 
 
@@ -617,7 +621,6 @@ DefineQueryRewrite(const char *rulename,
 		classForm->reltoastrelid = InvalidOid;
 		classForm->relhasindex = false;
 		classForm->relkind = RELKIND_VIEW;
-		classForm->relhasoids = false;
 		classForm->relfrozenxid = InvalidTransactionId;
 		classForm->relminmxid = InvalidMultiXactId;
 		classForm->relreplident = REPLICA_IDENTITY_NOTHING;
@@ -842,6 +845,7 @@ EnableDisableRule(Relation rel, const char *rulename,
 	Oid			owningRel = RelationGetRelid(rel);
 	Oid			eventRelationOid;
 	HeapTuple	ruletup;
+	Form_pg_rewrite ruleform;
 	bool		changed = false;
 
 	/*
@@ -857,10 +861,12 @@ EnableDisableRule(Relation rel, const char *rulename,
 				 errmsg("rule \"%s\" for relation \"%s\" does not exist",
 						rulename, get_rel_name(owningRel))));
 
+	ruleform = (Form_pg_rewrite) GETSTRUCT(ruletup);
+
 	/*
 	 * Verify that the user has appropriate permissions.
 	 */
-	eventRelationOid = ((Form_pg_rewrite) GETSTRUCT(ruletup))->ev_class;
+	eventRelationOid = ruleform->ev_class;
 	Assert(eventRelationOid == owningRel);
 	if (!pg_class_ownercheck(eventRelationOid, GetUserId()))
 		aclcheck_error(ACLCHECK_NOT_OWNER, get_relkind_objtype(get_rel_relkind(eventRelationOid)),
@@ -869,18 +875,16 @@ EnableDisableRule(Relation rel, const char *rulename,
 	/*
 	 * Change ev_enabled if it is different from the desired new state.
 	 */
-	if (DatumGetChar(((Form_pg_rewrite) GETSTRUCT(ruletup))->ev_enabled) !=
+	if (DatumGetChar(ruleform->ev_enabled) !=
 		fires_when)
 	{
-		((Form_pg_rewrite) GETSTRUCT(ruletup))->ev_enabled =
-			CharGetDatum(fires_when);
+		ruleform->ev_enabled = CharGetDatum(fires_when);
 		CatalogTupleUpdate(pg_rewrite_desc, &ruletup->t_self, ruletup);
 
 		changed = true;
 	}
 
-	InvokeObjectPostAlterHook(RewriteRelationId,
-							  HeapTupleGetOid(ruletup), 0);
+	InvokeObjectPostAlterHook(RewriteRelationId, ruleform->oid, 0);
 
 	heap_freetuple(ruletup);
 	heap_close(pg_rewrite_desc, RowExclusiveLock);
@@ -971,7 +975,7 @@ RenameRewriteRule(RangeVar *relation, const char *oldName,
 				 errmsg("rule \"%s\" for relation \"%s\" does not exist",
 						oldName, RelationGetRelationName(targetrel))));
 	ruleform = (Form_pg_rewrite) GETSTRUCT(ruletup);
-	ruleOid = HeapTupleGetOid(ruletup);
+	ruleOid = ruleform->oid;
 
 	/* rule with the new name should not already exist */
 	if (IsDefinedRewriteRule(relid, newName))
diff --git a/src/backend/rewrite/rewriteRemove.c b/src/backend/rewrite/rewriteRemove.c
index 07de85b8a31..73e67083fbf 100644
--- a/src/backend/rewrite/rewriteRemove.c
+++ b/src/backend/rewrite/rewriteRemove.c
@@ -53,7 +53,7 @@ RemoveRewriteRuleById(Oid ruleOid)
 	 * Find the tuple for the target rule.
 	 */
 	ScanKeyInit(&skey[0],
-				ObjectIdAttributeNumber,
+				Anum_pg_rewrite_oid,
 				BTEqualStrategyNumber, F_OIDEQ,
 				ObjectIdGetDatum(ruleOid));
 
diff --git a/src/backend/rewrite/rewriteSupport.c b/src/backend/rewrite/rewriteSupport.c
index ab291a43e2c..c87fe4a4d93 100644
--- a/src/backend/rewrite/rewriteSupport.c
+++ b/src/backend/rewrite/rewriteSupport.c
@@ -94,6 +94,7 @@ Oid
 get_rewrite_oid(Oid relid, const char *rulename, bool missing_ok)
 {
 	HeapTuple	tuple;
+	Form_pg_rewrite ruleform;
 	Oid			ruleoid;
 
 	/* Find the rule's pg_rewrite tuple, get its OID */
@@ -109,8 +110,9 @@ get_rewrite_oid(Oid relid, const char *rulename, bool missing_ok)
 				 errmsg("rule \"%s\" for relation \"%s\" does not exist",
 						rulename, get_rel_name(relid))));
 	}
-	Assert(relid == ((Form_pg_rewrite) GETSTRUCT(tuple))->ev_class);
-	ruleoid = HeapTupleGetOid(tuple);
+	ruleform = (Form_pg_rewrite) GETSTRUCT(tuple);
+	Assert(relid == ruleform->ev_class);
+	ruleoid = ruleform->oid;
 	ReleaseSysCache(tuple);
 	return ruleoid;
 }
diff --git a/src/backend/statistics/extended_stats.c b/src/backend/statistics/extended_stats.c
index 2df5f7dc3a5..5dcee95250a 100644
--- a/src/backend/statistics/extended_stats.c
+++ b/src/backend/statistics/extended_stats.c
@@ -196,8 +196,8 @@ fetch_statentries_for_relation(Relation pg_statext, Oid relid)
 		Form_pg_statistic_ext staForm;
 
 		entry = palloc0(sizeof(StatExtEntry));
-		entry->statOid = HeapTupleGetOid(htup);
 		staForm = (Form_pg_statistic_ext) GETSTRUCT(htup);
+		entry->statOid = staForm->oid;
 		entry->schema = get_namespace_name(staForm->stxnamespace);
 		entry->name = pstrdup(NameStr(staForm->stxname));
 		for (i = 0; i < staForm->stxkeys.dim1; i++)
diff --git a/src/backend/storage/large_object/inv_api.c b/src/backend/storage/large_object/inv_api.c
index 7eac0724bb2..af22b6ba6dc 100644
--- a/src/backend/storage/large_object/inv_api.c
+++ b/src/backend/storage/large_object/inv_api.c
@@ -137,7 +137,7 @@ myLargeObjectExists(Oid loid, Snapshot snapshot)
 	bool		retval = false;
 
 	ScanKeyInit(&skey[0],
-				ObjectIdAttributeNumber,
+				Anum_pg_largeobject_metadata_oid,
 				BTEqualStrategyNumber, F_OIDEQ,
 				ObjectIdGetDatum(loid));
 
diff --git a/src/backend/tcop/pquery.c b/src/backend/tcop/pquery.c
index 66cc5c35c68..ae6dd415def 100644
--- a/src/backend/tcop/pquery.c
+++ b/src/backend/tcop/pquery.c
@@ -175,10 +175,8 @@ ProcessQuery(PlannedStmt *plan,
 						 queryDesc->estate->es_processed);
 				break;
 			case CMD_INSERT:
-				if (queryDesc->estate->es_processed == 1)
-					lastOid = queryDesc->estate->es_lastoid;
-				else
-					lastOid = InvalidOid;
+				/* lastoid doesn't exist anymore */
+				lastOid = InvalidOid;
 				snprintf(completionTag, COMPLETION_TAG_BUFSIZE,
 						 "INSERT %u " UINT64_FORMAT,
 						 lastOid, queryDesc->estate->es_processed);
@@ -551,8 +549,7 @@ PortalStart(Portal portal, ParamListInfo params,
 
 					pstmt = PortalGetPrimaryStmt(portal);
 					portal->tupDesc =
-						ExecCleanTypeFromTL(pstmt->planTree->targetlist,
-											false);
+						ExecCleanTypeFromTL(pstmt->planTree->targetlist);
 				}
 
 				/*
diff --git a/src/backend/tsearch/wparser.c b/src/backend/tsearch/wparser.c
index 649245b2922..e8b612d4310 100644
--- a/src/backend/tsearch/wparser.c
+++ b/src/backend/tsearch/wparser.c
@@ -66,7 +66,7 @@ tt_setup_firstcall(FuncCallContext *funcctx, Oid prsid)
 															 (Datum) 0));
 	funcctx->user_fctx = (void *) st;
 
-	tupdesc = CreateTemplateTupleDesc(3, false);
+	tupdesc = CreateTemplateTupleDesc(3);
 	TupleDescInitEntry(tupdesc, (AttrNumber) 1, "tokid",
 					   INT4OID, -1, 0);
 	TupleDescInitEntry(tupdesc, (AttrNumber) 2, "alias",
@@ -212,7 +212,7 @@ prs_setup_firstcall(FuncCallContext *funcctx, Oid prsid, text *txt)
 	st->cur = 0;
 
 	funcctx->user_fctx = (void *) st;
-	tupdesc = CreateTemplateTupleDesc(2, false);
+	tupdesc = CreateTemplateTupleDesc(2);
 	TupleDescInitEntry(tupdesc, (AttrNumber) 1, "tokid",
 					   INT4OID, -1, 0);
 	TupleDescInitEntry(tupdesc, (AttrNumber) 2, "token",
diff --git a/src/backend/utils/adt/acl.c b/src/backend/utils/adt/acl.c
index c5f7918440b..e2484b6a36b 100644
--- a/src/backend/utils/adt/acl.c
+++ b/src/backend/utils/adt/acl.c
@@ -1763,7 +1763,7 @@ aclexplode(PG_FUNCTION_ARGS)
 		 * build tupdesc for result tuples (matches out parameters in pg_proc
 		 * entry)
 		 */
-		tupdesc = CreateTemplateTupleDesc(4, false);
+		tupdesc = CreateTemplateTupleDesc(4);
 		TupleDescInitEntry(tupdesc, (AttrNumber) 1, "grantor",
 						   OIDOID, -1, 0);
 		TupleDescInitEntry(tupdesc, (AttrNumber) 2, "grantee",
diff --git a/src/backend/utils/adt/datetime.c b/src/backend/utils/adt/datetime.c
index 20d6cee8b10..cd5fd0a099f 100644
--- a/src/backend/utils/adt/datetime.c
+++ b/src/backend/utils/adt/datetime.c
@@ -4674,7 +4674,7 @@ pg_timezone_abbrevs(PG_FUNCTION_ARGS)
 		 * build tupdesc for result tuples. This must match this function's
 		 * pg_proc entry!
 		 */
-		tupdesc = CreateTemplateTupleDesc(3, false);
+		tupdesc = CreateTemplateTupleDesc(3);
 		TupleDescInitEntry(tupdesc, (AttrNumber) 1, "abbrev",
 						   TEXTOID, -1, 0);
 		TupleDescInitEntry(tupdesc, (AttrNumber) 2, "utc_offset",
@@ -4801,7 +4801,7 @@ pg_timezone_names(PG_FUNCTION_ARGS)
 		 * build tupdesc for result tuples. This must match this function's
 		 * pg_proc entry!
 		 */
-		tupdesc = CreateTemplateTupleDesc(4, false);
+		tupdesc = CreateTemplateTupleDesc(4);
 		TupleDescInitEntry(tupdesc, (AttrNumber) 1, "name",
 						   TEXTOID, -1, 0);
 		TupleDescInitEntry(tupdesc, (AttrNumber) 2, "abbrev",
diff --git a/src/backend/utils/adt/enum.c b/src/backend/utils/adt/enum.c
index 01edccced29..99f0a90248f 100644
--- a/src/backend/utils/adt/enum.c
+++ b/src/backend/utils/adt/enum.c
@@ -64,7 +64,7 @@ static void
 check_safe_enum_use(HeapTuple enumval_tup)
 {
 	TransactionId xmin;
-	Form_pg_enum en;
+	Form_pg_enum en = (Form_pg_enum) GETSTRUCT(enumval_tup);
 
 	/*
 	 * If the row is hinted as committed, it's surely safe.  This provides a
@@ -88,14 +88,13 @@ check_safe_enum_use(HeapTuple enumval_tup)
 	 * owning type.  (This'd also be false for values made by other
 	 * transactions; but the previous tests should have handled all of those.)
 	 */
-	if (!EnumBlacklisted(HeapTupleGetOid(enumval_tup)))
+	if (!EnumBlacklisted(en->oid))
 		return;
 
 	/*
 	 * There might well be other tests we could do here to narrow down the
 	 * unsafe conditions, but for now just raise an exception.
 	 */
-	en = (Form_pg_enum) GETSTRUCT(enumval_tup);
 	ereport(ERROR,
 			(errcode(ERRCODE_UNSAFE_NEW_ENUM_VALUE_USAGE),
 			 errmsg("unsafe use of new value \"%s\" of enum type %s",
@@ -140,7 +139,7 @@ enum_in(PG_FUNCTION_ARGS)
 	 * This comes from pg_enum.oid and stores system oids in user tables. This
 	 * oid must be preserved by binary upgrades.
 	 */
-	enumoid = HeapTupleGetOid(tup);
+	enumoid = ((Form_pg_enum) GETSTRUCT(tup))->oid;
 
 	ReleaseSysCache(tup);
 
@@ -204,7 +203,7 @@ enum_recv(PG_FUNCTION_ARGS)
 	/* check it's safe to use in SQL */
 	check_safe_enum_use(tup);
 
-	enumoid = HeapTupleGetOid(tup);
+	enumoid = ((Form_pg_enum) GETSTRUCT(tup))->oid;
 
 	ReleaseSysCache(tup);
 
@@ -414,7 +413,7 @@ enum_endpoint(Oid enumtypoid, ScanDirection direction)
 	{
 		/* check it's safe to use in SQL */
 		check_safe_enum_use(enum_tuple);
-		minmax = HeapTupleGetOid(enum_tuple);
+		minmax = ((Form_pg_enum) GETSTRUCT(enum_tuple))->oid;
 	}
 	else
 	{
@@ -574,7 +573,7 @@ enum_range_internal(Oid enumtypoid, Oid lower, Oid upper)
 
 	while (HeapTupleIsValid(enum_tuple = systable_getnext_ordered(enum_scan, ForwardScanDirection)))
 	{
-		Oid			enum_oid = HeapTupleGetOid(enum_tuple);
+		Oid			enum_oid = ((Form_pg_enum) GETSTRUCT(enum_tuple))->oid;
 
 		if (!left_found && lower == enum_oid)
 			left_found = true;
diff --git a/src/backend/utils/adt/expandedrecord.c b/src/backend/utils/adt/expandedrecord.c
index 9aa6f3aac51..5561b741e98 100644
--- a/src/backend/utils/adt/expandedrecord.c
+++ b/src/backend/utils/adt/expandedrecord.c
@@ -741,9 +741,6 @@ ER_get_flat_size(ExpandedObjectHeader *eohptr)
 	if (hasnull)
 		len += BITMAPLEN(tupdesc->natts);
 
-	if (tupdesc->tdhasoid)
-		len += sizeof(Oid);
-
 	hoff = len = MAXALIGN(len); /* align user data safely */
 
 	data_len = heap_compute_data_size(tupdesc, erh->dvalues, erh->dnulls);
@@ -804,9 +801,6 @@ ER_flatten_into(ExpandedObjectHeader *eohptr,
 	HeapTupleHeaderSetNatts(tuphdr, tupdesc->natts);
 	tuphdr->t_hoff = erh->hoff;
 
-	if (tupdesc->tdhasoid)		/* else leave infomask = 0 */
-		tuphdr->t_infomask = HEAP_HASOID;
-
 	/* And fill the data area from dvalues/dnulls */
 	heap_fill_tuple(tupdesc,
 					erh->dvalues,
@@ -1045,7 +1039,7 @@ expanded_record_lookup_field(ExpandedRecordHeader *erh, const char *fieldname,
 	}
 
 	/* How about system attributes? */
-	sysattr = SystemAttributeByName(fieldname, tupdesc->tdhasoid);
+	sysattr = SystemAttributeByName(fieldname);
 	if (sysattr != NULL)
 	{
 		finfo->fnumber = sysattr->attnum;
diff --git a/src/backend/utils/adt/genfile.c b/src/backend/utils/adt/genfile.c
index d4dc92c2fd9..5081a974c21 100644
--- a/src/backend/utils/adt/genfile.c
+++ b/src/backend/utils/adt/genfile.c
@@ -388,7 +388,7 @@ pg_stat_file(PG_FUNCTION_ARGS)
 	 * This record type had better match the output parameters declared for me
 	 * in pg_proc.h.
 	 */
-	tupdesc = CreateTemplateTupleDesc(6, false);
+	tupdesc = CreateTemplateTupleDesc(6);
 	TupleDescInitEntry(tupdesc, (AttrNumber) 1,
 					   "size", INT8OID, -1, 0);
 	TupleDescInitEntry(tupdesc, (AttrNumber) 2,
@@ -538,7 +538,7 @@ pg_ls_dir_files(FunctionCallInfo fcinfo, const char *dir, bool missing_ok)
 
 		fctx = palloc(sizeof(directory_fctx));
 
-		tupdesc = CreateTemplateTupleDesc(3, false);
+		tupdesc = CreateTemplateTupleDesc(3);
 		TupleDescInitEntry(tupdesc, (AttrNumber) 1, "name",
 						   TEXTOID, -1, 0);
 		TupleDescInitEntry(tupdesc, (AttrNumber) 2, "size",
diff --git a/src/backend/utils/adt/lockfuncs.c b/src/backend/utils/adt/lockfuncs.c
index 66c09a1f316..525decb6f1b 100644
--- a/src/backend/utils/adt/lockfuncs.c
+++ b/src/backend/utils/adt/lockfuncs.c
@@ -101,7 +101,7 @@ pg_lock_status(PG_FUNCTION_ARGS)
 
 		/* build tupdesc for result tuples */
 		/* this had better match function's declaration in pg_proc.h */
-		tupdesc = CreateTemplateTupleDesc(NUM_LOCK_STATUS_COLUMNS, false);
+		tupdesc = CreateTemplateTupleDesc(NUM_LOCK_STATUS_COLUMNS);
 		TupleDescInitEntry(tupdesc, (AttrNumber) 1, "locktype",
 						   TEXTOID, -1, 0);
 		TupleDescInitEntry(tupdesc, (AttrNumber) 2, "database",
diff --git a/src/backend/utils/adt/misc.c b/src/backend/utils/adt/misc.c
index 309eb2935c7..d05849f1d42 100644
--- a/src/backend/utils/adt/misc.c
+++ b/src/backend/utils/adt/misc.c
@@ -402,7 +402,7 @@ pg_get_keywords(PG_FUNCTION_ARGS)
 		funcctx = SRF_FIRSTCALL_INIT();
 		oldcontext = MemoryContextSwitchTo(funcctx->multi_call_memory_ctx);
 
-		tupdesc = CreateTemplateTupleDesc(3, false);
+		tupdesc = CreateTemplateTupleDesc(3);
 		TupleDescInitEntry(tupdesc, (AttrNumber) 1, "word",
 						   TEXTOID, -1, 0);
 		TupleDescInitEntry(tupdesc, (AttrNumber) 2, "catcode",
diff --git a/src/backend/utils/adt/orderedsetaggs.c b/src/backend/utils/adt/orderedsetaggs.c
index be9422dcfb6..fcebfa218ec 100644
--- a/src/backend/utils/adt/orderedsetaggs.c
+++ b/src/backend/utils/adt/orderedsetaggs.c
@@ -215,7 +215,7 @@ ordered_set_startup(FunctionCallInfo fcinfo, bool use_tuples)
 			 * Get a tupledesc corresponding to the aggregated inputs
 			 * (including sort expressions) of the agg.
 			 */
-			qstate->tupdesc = ExecTypeFromTL(aggref->args, false);
+			qstate->tupdesc = ExecTypeFromTL(aggref->args);
 
 			/* If we need a flag column, hack the tupledesc to include that */
 			if (ishypothetical)
@@ -223,7 +223,7 @@ ordered_set_startup(FunctionCallInfo fcinfo, bool use_tuples)
 				TupleDesc	newdesc;
 				int			natts = qstate->tupdesc->natts;
 
-				newdesc = CreateTemplateTupleDesc(natts + 1, false);
+				newdesc = CreateTemplateTupleDesc(natts + 1);
 				for (i = 1; i <= natts; i++)
 					TupleDescCopyEntry(newdesc, i, qstate->tupdesc, i);
 
diff --git a/src/backend/utils/adt/partitionfuncs.c b/src/backend/utils/adt/partitionfuncs.c
index 8f9218ad0aa..78dd2b542b5 100644
--- a/src/backend/utils/adt/partitionfuncs.c
+++ b/src/backend/utils/adt/partitionfuncs.c
@@ -72,7 +72,7 @@ pg_partition_tree(PG_FUNCTION_ARGS)
 		 */
 		partitions = find_all_inheritors(rootrelid, AccessShareLock, NULL);
 
-		tupdesc = CreateTemplateTupleDesc(PG_PARTITION_TREE_COLS, false);
+		tupdesc = CreateTemplateTupleDesc(PG_PARTITION_TREE_COLS);
 		TupleDescInitEntry(tupdesc, (AttrNumber) 1, "relid",
 						   REGCLASSOID, -1, 0);
 		TupleDescInitEntry(tupdesc, (AttrNumber) 2, "parentid",
diff --git a/src/backend/utils/adt/pgstatfuncs.c b/src/backend/utils/adt/pgstatfuncs.c
index e95e3471846..f955f1912a4 100644
--- a/src/backend/utils/adt/pgstatfuncs.c
+++ b/src/backend/utils/adt/pgstatfuncs.c
@@ -1829,7 +1829,7 @@ pg_stat_get_archiver(PG_FUNCTION_ARGS)
 	MemSet(nulls, 0, sizeof(nulls));
 
 	/* Initialise attributes information in the tuple descriptor */
-	tupdesc = CreateTemplateTupleDesc(7, false);
+	tupdesc = CreateTemplateTupleDesc(7);
 	TupleDescInitEntry(tupdesc, (AttrNumber) 1, "archived_count",
 					   INT8OID, -1, 0);
 	TupleDescInitEntry(tupdesc, (AttrNumber) 2, "last_archived_wal",
diff --git a/src/backend/utils/adt/ruleutils.c b/src/backend/utils/adt/ruleutils.c
index 29884f1c8b6..4857caecaad 100644
--- a/src/backend/utils/adt/ruleutils.c
+++ b/src/backend/utils/adt/ruleutils.c
@@ -843,7 +843,7 @@ pg_get_triggerdef_worker(Oid trigid, bool pretty)
 	tgrel = heap_open(TriggerRelationId, AccessShareLock);
 
 	ScanKeyInit(&skey[0],
-				ObjectIdAttributeNumber,
+				Anum_pg_trigger_oid,
 				BTEqualStrategyNumber, F_OIDEQ,
 				ObjectIdGetDatum(trigid));
 
@@ -1883,7 +1883,7 @@ pg_get_constraintdef_worker(Oid constraintId, bool fullCommand,
 	Relation	relation = heap_open(ConstraintRelationId, AccessShareLock);
 
 	ScanKeyInit(&scankey[0],
-				ObjectIdAttributeNumber,
+				Anum_pg_constraint_oid,
 				BTEqualStrategyNumber, F_OIDEQ,
 				ObjectIdGetDatum(constraintId));
 
@@ -2930,11 +2930,10 @@ print_function_arguments(StringInfo buf, HeapTuple proctup,
 		HeapTuple	aggtup;
 		Form_pg_aggregate agg;
 
-		aggtup = SearchSysCache1(AGGFNOID,
-								 ObjectIdGetDatum(HeapTupleGetOid(proctup)));
+		aggtup = SearchSysCache1(AGGFNOID, proc->oid);
 		if (!HeapTupleIsValid(aggtup))
 			elog(ERROR, "cache lookup failed for aggregate %u",
-				 HeapTupleGetOid(proctup));
+				 proc->oid);
 		agg = (Form_pg_aggregate) GETSTRUCT(aggtup);
 		if (AGGKIND_IS_ORDERED_SET(agg->aggkind))
 			insertorderbyat = agg->aggnumdirectargs;
diff --git a/src/backend/utils/adt/selfuncs.c b/src/backend/utils/adt/selfuncs.c
index e0ece74bb92..d110b07d35e 100644
--- a/src/backend/utils/adt/selfuncs.c
+++ b/src/backend/utils/adt/selfuncs.c
@@ -5216,7 +5216,6 @@ get_variable_numdistinct(VariableStatData *vardata, bool *isdefault)
 		{
 			switch (((Var *) vardata->var)->varattno)
 			{
-				case ObjectIdAttributeNumber:
 				case SelfItemPointerAttributeNumber:
 					stadistinct = -1.0; /* unique (and all non null) */
 					break;
diff --git a/src/backend/utils/adt/trigfuncs.c b/src/backend/utils/adt/trigfuncs.c
index 04605021d79..93ac936420d 100644
--- a/src/backend/utils/adt/trigfuncs.c
+++ b/src/backend/utils/adt/trigfuncs.c
@@ -66,17 +66,6 @@ suppress_redundant_updates_trigger(PG_FUNCTION_ARGS)
 	newheader = newtuple->t_data;
 	oldheader = oldtuple->t_data;
 
-	/*
-	 * We are called before the OID, if any, has been transcribed from the old
-	 * tuple to the new (in heap_update).  To avoid a bogus compare failure,
-	 * copy the OID now.  But check that someone didn't already put another
-	 * OID value into newtuple.  (That's not actually possible at present, but
-	 * maybe someday.)
-	 */
-	if (trigdata->tg_relation->rd_rel->relhasoids &&
-		!OidIsValid(HeapTupleHeaderGetOid(newheader)))
-		HeapTupleHeaderSetOid(newheader, HeapTupleHeaderGetOid(oldheader));
-
 	/* if the tuple payload is the same ... */
 	if (newtuple->t_len == oldtuple->t_len &&
 		newheader->t_hoff == oldheader->t_hoff &&
diff --git a/src/backend/utils/adt/tsvector_op.c b/src/backend/utils/adt/tsvector_op.c
index 258fe47a245..3c55166a14e 100644
--- a/src/backend/utils/adt/tsvector_op.c
+++ b/src/backend/utils/adt/tsvector_op.c
@@ -646,7 +646,7 @@ tsvector_unnest(PG_FUNCTION_ARGS)
 		funcctx = SRF_FIRSTCALL_INIT();
 		oldcontext = MemoryContextSwitchTo(funcctx->multi_call_memory_ctx);
 
-		tupdesc = CreateTemplateTupleDesc(3, false);
+		tupdesc = CreateTemplateTupleDesc(3);
 		TupleDescInitEntry(tupdesc, (AttrNumber) 1, "lexeme",
 						   TEXTOID, -1, 0);
 		TupleDescInitEntry(tupdesc, (AttrNumber) 2, "positions",
@@ -2187,7 +2187,7 @@ ts_setup_firstcall(FunctionCallInfo fcinfo, FuncCallContext *funcctx,
 		}
 	Assert(stat->stackpos <= stat->maxdepth);
 
-	tupdesc = CreateTemplateTupleDesc(3, false);
+	tupdesc = CreateTemplateTupleDesc(3);
 	TupleDescInitEntry(tupdesc, (AttrNumber) 1, "word",
 					   TEXTOID, -1, 0);
 	TupleDescInitEntry(tupdesc, (AttrNumber) 2, "ndoc",
diff --git a/src/backend/utils/cache/catcache.c b/src/backend/utils/cache/catcache.c
index 5ddbf6eab10..b31fd5acea7 100644
--- a/src/backend/utils/cache/catcache.c
+++ b/src/backend/utils/cache/catcache.c
@@ -338,39 +338,31 @@ CatalogCacheComputeTupleHashValue(CatCache *cache, int nkeys, HeapTuple tuple)
 	switch (nkeys)
 	{
 		case 4:
-			v4 = (cc_keyno[3] == ObjectIdAttributeNumber)
-				? ObjectIdGetDatum(HeapTupleGetOid(tuple))
-				: fastgetattr(tuple,
-							  cc_keyno[3],
-							  cc_tupdesc,
-							  &isNull);
+			v4 = fastgetattr(tuple,
+							 cc_keyno[3],
+							 cc_tupdesc,
+							 &isNull);
 			Assert(!isNull);
 			/* FALLTHROUGH */
 		case 3:
-			v3 = (cc_keyno[2] == ObjectIdAttributeNumber)
-				? ObjectIdGetDatum(HeapTupleGetOid(tuple))
-				: fastgetattr(tuple,
-							  cc_keyno[2],
-							  cc_tupdesc,
-							  &isNull);
+			v3 = fastgetattr(tuple,
+							 cc_keyno[2],
+							 cc_tupdesc,
+							 &isNull);
 			Assert(!isNull);
 			/* FALLTHROUGH */
 		case 2:
-			v2 = (cc_keyno[1] == ObjectIdAttributeNumber)
-				? ObjectIdGetDatum(HeapTupleGetOid(tuple))
-				: fastgetattr(tuple,
-							  cc_keyno[1],
-							  cc_tupdesc,
-							  &isNull);
+			v2 = fastgetattr(tuple,
+							 cc_keyno[1],
+							 cc_tupdesc,
+							 &isNull);
 			Assert(!isNull);
 			/* FALLTHROUGH */
 		case 1:
-			v1 = (cc_keyno[0] == ObjectIdAttributeNumber)
-				? ObjectIdGetDatum(HeapTupleGetOid(tuple))
-				: fastgetattr(tuple,
-							  cc_keyno[0],
-							  cc_tupdesc,
-							  &isNull);
+			v1 = fastgetattr(tuple,
+							 cc_keyno[0],
+							 cc_tupdesc,
+							 &isNull);
 			Assert(!isNull);
 			break;
 		default:
@@ -998,8 +990,8 @@ CatalogCacheInitializeCache(CatCache *cache)
 		}
 		else
 		{
-			if (cache->cc_keyno[i] != ObjectIdAttributeNumber)
-				elog(FATAL, "only sys attr supported in caches is OID");
+			if (cache->cc_keyno[i] < 0)
+				elog(FATAL, "sys attributes are not supported in caches");
 			keytype = OIDOID;
 		}
 
@@ -1935,9 +1927,7 @@ CatCacheFreeKeys(TupleDesc tupdesc, int nkeys, int *attnos, Datum *keys)
 		int			attnum = attnos[i];
 		Form_pg_attribute att;
 
-		/* only valid system attribute is the oid, which is by value */
-		if (attnum == ObjectIdAttributeNumber)
-			continue;
+		/* system attribute are not supported in caches */
 		Assert(attnum > 0);
 
 		att = TupleDescAttr(tupdesc, attnum - 1);
@@ -1966,33 +1956,25 @@ CatCacheCopyKeys(TupleDesc tupdesc, int nkeys, int *attnos,
 	for (i = 0; i < nkeys; i++)
 	{
 		int			attnum = attnos[i];
+		Form_pg_attribute att = TupleDescAttr(tupdesc, attnum - 1);
+		Datum		src = srckeys[i];
+		NameData	srcname;
 
-		if (attnum == ObjectIdAttributeNumber)
+		/*
+		 * Must be careful in case the caller passed a C string where a
+		 * NAME is wanted: convert the given argument to a correctly
+		 * padded NAME.  Otherwise the memcpy() done by datumCopy() could
+		 * fall off the end of memory.
+		 */
+		if (att->atttypid == NAMEOID)
 		{
-			dstkeys[i] = srckeys[i];
+			namestrcpy(&srcname, DatumGetCString(src));
+			src = NameGetDatum(&srcname);
 		}
-		else
-		{
-			Form_pg_attribute att = TupleDescAttr(tupdesc, attnum - 1);
-			Datum		src = srckeys[i];
-			NameData	srcname;
 
-			/*
-			 * Must be careful in case the caller passed a C string where a
-			 * NAME is wanted: convert the given argument to a correctly
-			 * padded NAME.  Otherwise the memcpy() done by datumCopy() could
-			 * fall off the end of memory.
-			 */
-			if (att->atttypid == NAMEOID)
-			{
-				namestrcpy(&srcname, DatumGetCString(src));
-				src = NameGetDatum(&srcname);
-			}
-
-			dstkeys[i] = datumCopy(src,
-								   att->attbyval,
-								   att->attlen);
-		}
+		dstkeys[i] = datumCopy(src,
+							   att->attbyval,
+							   att->attlen);
 	}
 
 }
diff --git a/src/backend/utils/cache/inval.c b/src/backend/utils/cache/inval.c
index f3ded4def90..51574937959 100644
--- a/src/backend/utils/cache/inval.c
+++ b/src/backend/utils/cache/inval.c
@@ -1166,7 +1166,7 @@ CacheInvalidateHeapTuple(Relation relation,
 	{
 		Form_pg_class classtup = (Form_pg_class) GETSTRUCT(tuple);
 
-		relationId = HeapTupleGetOid(tuple);
+		relationId = classtup->oid;
 		if (classtup->relisshared)
 			databaseId = InvalidOid;
 		else
@@ -1292,7 +1292,7 @@ CacheInvalidateRelcacheByTuple(HeapTuple classTuple)
 
 	PrepareInvalidationState();
 
-	relationId = HeapTupleGetOid(classTuple);
+	relationId = classtup->oid;
 	if (classtup->relisshared)
 		databaseId = InvalidOid;
 	else
diff --git a/src/backend/utils/cache/lsyscache.c b/src/backend/utils/cache/lsyscache.c
index 892ddc0d486..e01decb6287 100644
--- a/src/backend/utils/cache/lsyscache.c
+++ b/src/backend/utils/cache/lsyscache.c
@@ -2056,7 +2056,7 @@ getTypeIOParam(HeapTuple typeTuple)
 	if (OidIsValid(typeStruct->typelem))
 		return typeStruct->typelem;
 	else
-		return HeapTupleGetOid(typeTuple);
+		return typeStruct->oid;
 }
 
 /*
diff --git a/src/backend/utils/cache/plancache.c b/src/backend/utils/cache/plancache.c
index fc7e8dbe269..9ec81c5f367 100644
--- a/src/backend/utils/cache/plancache.c
+++ b/src/backend/utils/cache/plancache.c
@@ -1663,12 +1663,12 @@ PlanCacheComputeResultDesc(List *stmt_list)
 		case PORTAL_ONE_SELECT:
 		case PORTAL_ONE_MOD_WITH:
 			query = linitial_node(Query, stmt_list);
-			return ExecCleanTypeFromTL(query->targetList, false);
+			return ExecCleanTypeFromTL(query->targetList);
 
 		case PORTAL_ONE_RETURNING:
 			query = QueryListGetPrimaryStmt(stmt_list);
 			Assert(query->returningList);
-			return ExecCleanTypeFromTL(query->returningList, false);
+			return ExecCleanTypeFromTL(query->returningList);
 
 		case PORTAL_UTIL_SELECT:
 			query = linitial_node(Query, stmt_list);
diff --git a/src/backend/utils/cache/relcache.c b/src/backend/utils/cache/relcache.c
index aecbd4a9437..3637feeb7c5 100644
--- a/src/backend/utils/cache/relcache.c
+++ b/src/backend/utils/cache/relcache.c
@@ -261,8 +261,7 @@ static void write_relcache_init_file(bool shared);
 static void write_item(const void *data, Size len, FILE *fp);
 
 static void formrdesc(const char *relationName, Oid relationReltype,
-		  bool isshared, bool hasoids,
-		  int natts, const FormData_pg_attribute *attrs);
+		  bool isshared, int natts, const FormData_pg_attribute *attrs);
 
 static HeapTuple ScanPgRelation(Oid targetRelId, bool indexOK, bool force_non_historic);
 static Relation AllocateRelationDesc(Form_pg_class relp);
@@ -328,7 +327,7 @@ ScanPgRelation(Oid targetRelId, bool indexOK, bool force_non_historic)
 	 * form a scan key
 	 */
 	ScanKeyInit(&key[0],
-				ObjectIdAttributeNumber,
+				Anum_pg_class_oid,
 				BTEqualStrategyNumber, F_OIDEQ,
 				ObjectIdGetDatum(targetRelId));
 
@@ -414,8 +413,7 @@ AllocateRelationDesc(Form_pg_class relp)
 	relation->rd_rel = relationForm;
 
 	/* and allocate attribute tuple form storage */
-	relation->rd_att = CreateTemplateTupleDesc(relationForm->relnatts,
-											   relationForm->relhasoids);
+	relation->rd_att = CreateTemplateTupleDesc(relationForm->relnatts);
 	/* which we mark as a reference-counted tupdesc */
 	relation->rd_att->tdrefcount = 1;
 
@@ -505,7 +503,6 @@ RelationBuildTupleDesc(Relation relation)
 	/* copy some fields from pg_class row to rd_att */
 	relation->rd_att->tdtypeid = relation->rd_rel->reltype;
 	relation->rd_att->tdtypmod = -1;	/* unnecessary, but... */
-	relation->rd_att->tdhasoid = relation->rd_rel->relhasoids;
 
 	constr = (TupleConstr *) MemoryContextAlloc(CacheMemoryContext,
 												sizeof(TupleConstr));
@@ -789,7 +786,7 @@ RelationBuildRuleLock(Relation relation)
 		rule = (RewriteRule *) MemoryContextAlloc(rulescxt,
 												  sizeof(RewriteRule));
 
-		rule->ruleId = HeapTupleGetOid(rewrite_tuple);
+		rule->ruleId = rewrite_form->oid;
 
 		rule->event = rewrite_form->ev_type - '0';
 		rule->enabled = rewrite_form->ev_enabled;
@@ -1090,8 +1087,8 @@ RelationBuildDesc(Oid targetRelId, bool insertIt)
 	/*
 	 * get information from the pg_class_tuple
 	 */
-	relid = HeapTupleGetOid(pg_class_tuple);
 	relp = (Form_pg_class) GETSTRUCT(pg_class_tuple);
+	relid = relp->oid;
 	Assert(relid == targetRelId);
 
 	/*
@@ -1641,7 +1638,7 @@ LookupOpclassInfo(Oid operatorClassOid,
 	 * work while bootstrapping.
 	 */
 	ScanKeyInit(&skey[0],
-				ObjectIdAttributeNumber,
+				Anum_pg_opclass_oid,
 				BTEqualStrategyNumber, F_OIDEQ,
 				ObjectIdGetDatum(operatorClassOid));
 	rel = heap_open(OperatorClassRelationId, AccessShareLock);
@@ -1725,7 +1722,7 @@ LookupOpclassInfo(Oid operatorClassOid,
  */
 static void
 formrdesc(const char *relationName, Oid relationReltype,
-		  bool isshared, bool hasoids,
+		  bool isshared,
 		  int natts, const FormData_pg_attribute *attrs)
 {
 	Relation	relation;
@@ -1789,7 +1786,6 @@ formrdesc(const char *relationName, Oid relationReltype,
 	relation->rd_rel->reltuples = 0;
 	relation->rd_rel->relallvisible = 0;
 	relation->rd_rel->relkind = RELKIND_RELATION;
-	relation->rd_rel->relhasoids = hasoids;
 	relation->rd_rel->relnatts = (int16) natts;
 
 	/*
@@ -1799,7 +1795,7 @@ formrdesc(const char *relationName, Oid relationReltype,
 	 * because it will never be replaced.  The data comes from
 	 * src/include/catalog/ headers via genbki.pl.
 	 */
-	relation->rd_att = CreateTemplateTupleDesc(natts, hasoids);
+	relation->rd_att = CreateTemplateTupleDesc(natts);
 	relation->rd_att->tdrefcount = 1;	/* mark as refcounted */
 
 	relation->rd_att->tdtypeid = relationReltype;
@@ -2964,7 +2960,9 @@ AtEOXact_cleanup(Relation relation, bool isCommit)
 	{
 		list_free(relation->rd_indexlist);
 		relation->rd_indexlist = NIL;
+#if 0
 		relation->rd_oidindex = InvalidOid;
+#endif
 		relation->rd_pkindex = InvalidOid;
 		relation->rd_replidindex = InvalidOid;
 		relation->rd_indexvalid = 0;
@@ -3077,7 +3075,9 @@ AtEOSubXact_cleanup(Relation relation, bool isCommit,
 	{
 		list_free(relation->rd_indexlist);
 		relation->rd_indexlist = NIL;
+#if 0
 		relation->rd_oidindex = InvalidOid;
+#endif
 		relation->rd_pkindex = InvalidOid;
 		relation->rd_replidindex = InvalidOid;
 		relation->rd_indexvalid = 0;
@@ -3208,7 +3208,6 @@ RelationBuildLocalRelation(const char *relname,
 	rel->rd_rel->relnamespace = relnamespace;
 
 	rel->rd_rel->relkind = relkind;
-	rel->rd_rel->relhasoids = rel->rd_att->tdhasoid;
 	rel->rd_rel->relnatts = natts;
 	rel->rd_rel->reltype = InvalidOid;
 	/* needed when bootstrapping: */
@@ -3507,15 +3506,15 @@ RelationCacheInitializePhase2(void)
 	 */
 	if (!load_relcache_init_file(true))
 	{
-		formrdesc("pg_database", DatabaseRelation_Rowtype_Id, true,
+		formrdesc("pg_database", DatabaseRelation_Rowtype_Id,
 				  true, Natts_pg_database, Desc_pg_database);
-		formrdesc("pg_authid", AuthIdRelation_Rowtype_Id, true,
+		formrdesc("pg_authid", AuthIdRelation_Rowtype_Id,
 				  true, Natts_pg_authid, Desc_pg_authid);
-		formrdesc("pg_auth_members", AuthMemRelation_Rowtype_Id, true,
-				  false, Natts_pg_auth_members, Desc_pg_auth_members);
-		formrdesc("pg_shseclabel", SharedSecLabelRelation_Rowtype_Id, true,
-				  false, Natts_pg_shseclabel, Desc_pg_shseclabel);
-		formrdesc("pg_subscription", SubscriptionRelation_Rowtype_Id, true,
+		formrdesc("pg_auth_members", AuthMemRelation_Rowtype_Id,
+				  true, Natts_pg_auth_members, Desc_pg_auth_members);
+		formrdesc("pg_shseclabel", SharedSecLabelRelation_Rowtype_Id,
+				  true, Natts_pg_shseclabel, Desc_pg_shseclabel);
+		formrdesc("pg_subscription", SubscriptionRelation_Rowtype_Id,
 				  true, Natts_pg_subscription, Desc_pg_subscription);
 
 #define NUM_CRITICAL_SHARED_RELS	5	/* fix if you change list above */
@@ -3566,14 +3565,14 @@ RelationCacheInitializePhase3(void)
 	{
 		needNewCacheFile = true;
 
-		formrdesc("pg_class", RelationRelation_Rowtype_Id, false,
-				  true, Natts_pg_class, Desc_pg_class);
-		formrdesc("pg_attribute", AttributeRelation_Rowtype_Id, false,
+		formrdesc("pg_class", RelationRelation_Rowtype_Id,
+				  false, Natts_pg_class, Desc_pg_class);
+		formrdesc("pg_attribute", AttributeRelation_Rowtype_Id,
 				  false, Natts_pg_attribute, Desc_pg_attribute);
-		formrdesc("pg_proc", ProcedureRelation_Rowtype_Id, false,
-				  true, Natts_pg_proc, Desc_pg_proc);
-		formrdesc("pg_type", TypeRelation_Rowtype_Id, false,
-				  true, Natts_pg_type, Desc_pg_type);
+		formrdesc("pg_proc", ProcedureRelation_Rowtype_Id,
+				  false, Natts_pg_proc, Desc_pg_proc);
+		formrdesc("pg_type", TypeRelation_Rowtype_Id,
+				  false, Natts_pg_type, Desc_pg_type);
 
 #define NUM_CRITICAL_LOCAL_RELS 4	/* fix if you change list above */
 	}
@@ -3725,7 +3724,6 @@ RelationCacheInitializePhase3(void)
 			 */
 			Assert(relation->rd_att->tdtypeid == relp->reltype);
 			Assert(relation->rd_att->tdtypmod == -1);
-			Assert(relation->rd_att->tdhasoid == relp->relhasoids);
 
 			ReleaseSysCache(htup);
 
@@ -3868,8 +3866,7 @@ load_critical_index(Oid indexoid, Oid heapoid)
  * extracting fields.
  */
 static TupleDesc
-BuildHardcodedDescriptor(int natts, const FormData_pg_attribute *attrs,
-						 bool hasoids)
+BuildHardcodedDescriptor(int natts, const FormData_pg_attribute *attrs)
 {
 	TupleDesc	result;
 	MemoryContext oldcxt;
@@ -3877,7 +3874,7 @@ BuildHardcodedDescriptor(int natts, const FormData_pg_attribute *attrs,
 
 	oldcxt = MemoryContextSwitchTo(CacheMemoryContext);
 
-	result = CreateTemplateTupleDesc(natts, hasoids);
+	result = CreateTemplateTupleDesc(natts);
 	result->tdtypeid = RECORDOID;	/* not right, but we don't care */
 	result->tdtypmod = -1;
 
@@ -3906,8 +3903,7 @@ GetPgClassDescriptor(void)
 	/* Already done? */
 	if (pgclassdesc == NULL)
 		pgclassdesc = BuildHardcodedDescriptor(Natts_pg_class,
-											   Desc_pg_class,
-											   true);
+											   Desc_pg_class);
 
 	return pgclassdesc;
 }
@@ -3920,8 +3916,7 @@ GetPgIndexDescriptor(void)
 	/* Already done? */
 	if (pgindexdesc == NULL)
 		pgindexdesc = BuildHardcodedDescriptor(Natts_pg_index,
-											   Desc_pg_index,
-											   false);
+											   Desc_pg_index);
 
 	return pgindexdesc;
 }
@@ -4145,7 +4140,7 @@ RelationGetFKeyList(Relation relation)
 			continue;
 
 		info = makeNode(ForeignKeyCacheInfo);
-		info->conoid = HeapTupleGetOid(htup);
+		info->conoid = constraint->oid;
 		info->conrelid = constraint->conrelid;
 		info->confrelid = constraint->confrelid;
 
@@ -4268,7 +4263,9 @@ RelationGetIndexList(Relation relation)
 	List	   *result;
 	List	   *oldlist;
 	char		replident = relation->rd_rel->relreplident;
+#if 0
 	Oid			oidIndex = InvalidOid;
+#endif
 	Oid			pkeyIndex = InvalidOid;
 	Oid			candidateIndex = InvalidOid;
 	MemoryContext oldcxt;
@@ -4284,7 +4281,9 @@ RelationGetIndexList(Relation relation)
 	 * if we get some sort of error partway through.
 	 */
 	result = NIL;
+#if 0
 	oidIndex = InvalidOid;
+#endif
 
 	/* Prepare to scan pg_index for entries having indrelid = this rel. */
 	ScanKeyInit(&skey,
@@ -4299,9 +4298,11 @@ RelationGetIndexList(Relation relation)
 	while (HeapTupleIsValid(htup = systable_getnext(indscan)))
 	{
 		Form_pg_index index = (Form_pg_index) GETSTRUCT(htup);
+#if 0
 		Datum		indclassDatum;
 		oidvector  *indclass;
 		bool		isnull;
+#endif
 
 		/*
 		 * Ignore any indexes that are currently being dropped.  This will
@@ -4315,6 +4316,7 @@ RelationGetIndexList(Relation relation)
 		/* Add index's OID to result list in the proper order */
 		result = insert_ordered_oid(result, index->indexrelid);
 
+#if 0
 		/*
 		 * indclass cannot be referenced directly through the C struct,
 		 * because it comes after the variable-width indkey field.  Must
@@ -4326,6 +4328,7 @@ RelationGetIndexList(Relation relation)
 									 &isnull);
 		Assert(!isnull);
 		indclass = (oidvector *) DatumGetPointer(indclassDatum);
+#endif
 
 		/*
 		 * Invalid, non-unique, non-immediate or predicate indexes aren't
@@ -4337,11 +4340,13 @@ RelationGetIndexList(Relation relation)
 			!heap_attisnull(htup, Anum_pg_index_indpred, NULL))
 			continue;
 
+#if 0
 		/* Check to see if is a usable btree index on OID */
 		if (index->indnatts == 1 &&
 			index->indkey.values[0] == ObjectIdAttributeNumber &&
 			indclass->values[0] == OID_BTREE_OPS_OID)
 			oidIndex = index->indexrelid;
+#endif
 
 		/* remember primary key index if any */
 		if (index->indisprimary)
@@ -4360,7 +4365,9 @@ RelationGetIndexList(Relation relation)
 	oldcxt = MemoryContextSwitchTo(CacheMemoryContext);
 	oldlist = relation->rd_indexlist;
 	relation->rd_indexlist = list_copy(result);
+#if 0
 	relation->rd_oidindex = oidIndex;
+#endif
 	relation->rd_pkindex = pkeyIndex;
 	if (replident == REPLICA_IDENTITY_DEFAULT && OidIsValid(pkeyIndex))
 		relation->rd_replidindex = pkeyIndex;
@@ -4435,7 +4442,11 @@ RelationGetStatExtList(Relation relation)
 								 NULL, 1, &skey);
 
 	while (HeapTupleIsValid(htup = systable_getnext(indscan)))
-		result = insert_ordered_oid(result, HeapTupleGetOid(htup));
+	{
+		Oid oid = ((Form_pg_statistic_ext) GETSTRUCT(htup))->oid;
+
+		result = insert_ordered_oid(result, oid);
+	}
 
 	systable_endscan(indscan);
 
@@ -4522,7 +4533,9 @@ RelationSetIndexList(Relation relation, List *indexIds, Oid oidIndex)
 	/* Okay to replace old list */
 	list_free(relation->rd_indexlist);
 	relation->rd_indexlist = indexIds;
+#if 0
 	relation->rd_oidindex = oidIndex;
+#endif
 
 	/*
 	 * For the moment, assume the target rel hasn't got a pk or replica index.
@@ -4535,34 +4548,6 @@ RelationSetIndexList(Relation relation, List *indexIds, Oid oidIndex)
 	EOXactListAdd(relation);
 }
 
-/*
- * RelationGetOidIndex -- get the pg_class OID of the relation's OID index
- *
- * Returns InvalidOid if there is no such index.
- */
-Oid
-RelationGetOidIndex(Relation relation)
-{
-	List	   *ilist;
-
-	/*
-	 * If relation doesn't have OIDs at all, caller is probably confused. (We
-	 * could just silently return InvalidOid, but it seems better to throw an
-	 * assertion.)
-	 */
-	Assert(relation->rd_rel->relhasoids);
-
-	if (relation->rd_indexvalid == 0)
-	{
-		/* RelationGetIndexList does the heavy lifting. */
-		ilist = RelationGetIndexList(relation);
-		list_free(ilist);
-		Assert(relation->rd_indexvalid != 0);
-	}
-
-	return relation->rd_oidindex;
-}
-
 /*
  * RelationGetPrimaryKeyIndex -- get OID of the relation's primary key index
  *
@@ -5472,8 +5457,7 @@ load_relcache_init_file(bool shared)
 		rel->rd_rel = relform;
 
 		/* initialize attribute tuple forms */
-		rel->rd_att = CreateTemplateTupleDesc(relform->relnatts,
-											  relform->relhasoids);
+		rel->rd_att = CreateTemplateTupleDesc(relform->relnatts);
 		rel->rd_att->tdrefcount = 1;	/* mark as refcounted */
 
 		rel->rd_att->tdtypeid = relform->reltype;
@@ -5677,7 +5661,9 @@ load_relcache_init_file(bool shared)
 		rel->rd_fkeylist = NIL;
 		rel->rd_fkeyvalid = false;
 		rel->rd_indexlist = NIL;
+#if 0
 		rel->rd_oidindex = InvalidOid;
+#endif
 		rel->rd_pkindex = InvalidOid;
 		rel->rd_replidindex = InvalidOid;
 		rel->rd_indexattr = NULL;
diff --git a/src/backend/utils/cache/relfilenodemap.c b/src/backend/utils/cache/relfilenodemap.c
index 34679725b3d..74c4636895f 100644
--- a/src/backend/utils/cache/relfilenodemap.c
+++ b/src/backend/utils/cache/relfilenodemap.c
@@ -212,29 +212,17 @@ RelidByRelfilenode(Oid reltablespace, Oid relfilenode)
 
 		while (HeapTupleIsValid(ntp = systable_getnext(scandesc)))
 		{
+			Form_pg_class classform = (Form_pg_class) GETSTRUCT(ntp);
+
 			if (found)
 				elog(ERROR,
 					 "unexpected duplicate for tablespace %u, relfilenode %u",
 					 reltablespace, relfilenode);
 			found = true;
 
-#ifdef USE_ASSERT_CHECKING
-			{
-				bool		isnull;
-				Oid			check;
-
-				check = fastgetattr(ntp, Anum_pg_class_reltablespace,
-									RelationGetDescr(relation),
-									&isnull);
-				Assert(!isnull && check == reltablespace);
-
-				check = fastgetattr(ntp, Anum_pg_class_relfilenode,
-									RelationGetDescr(relation),
-									&isnull);
-				Assert(!isnull && check == relfilenode);
-			}
-#endif
-			relid = HeapTupleGetOid(ntp);
+			Assert(classform->reltablespace == reltablespace);
+			Assert(classform->relfilenode == relfilenode);
+			relid = classform->oid;
 		}
 
 		systable_endscan(scandesc);
diff --git a/src/backend/utils/cache/syscache.c b/src/backend/utils/cache/syscache.c
index 2b381782a32..237e7818024 100644
--- a/src/backend/utils/cache/syscache.c
+++ b/src/backend/utils/cache/syscache.c
@@ -147,7 +147,7 @@ static const struct cachedesc cacheinfo[] = {
 		AmOidIndexId,
 		1,
 		{
-			ObjectIdAttributeNumber,
+			Anum_pg_am_oid,
 			0,
 			0,
 			0
@@ -246,7 +246,7 @@ static const struct cachedesc cacheinfo[] = {
 		AuthIdOidIndexId,
 		1,
 		{
-			ObjectIdAttributeNumber,
+			Anum_pg_authid_oid,
 			0,
 			0,
 			0
@@ -280,7 +280,7 @@ static const struct cachedesc cacheinfo[] = {
 		OpclassOidIndexId,
 		1,
 		{
-			ObjectIdAttributeNumber,
+			Anum_pg_opclass_oid,
 			0,
 			0,
 			0
@@ -302,7 +302,7 @@ static const struct cachedesc cacheinfo[] = {
 		CollationOidIndexId,
 		1,
 		{
-			ObjectIdAttributeNumber,
+			Anum_pg_collation_oid,
 			0,
 			0,
 			0
@@ -316,7 +316,7 @@ static const struct cachedesc cacheinfo[] = {
 			Anum_pg_conversion_connamespace,
 			Anum_pg_conversion_conforencoding,
 			Anum_pg_conversion_contoencoding,
-			ObjectIdAttributeNumber,
+			Anum_pg_conversion_oid
 		},
 		8
 	},
@@ -335,7 +335,7 @@ static const struct cachedesc cacheinfo[] = {
 		ConstraintOidIndexId,
 		1,
 		{
-			ObjectIdAttributeNumber,
+			Anum_pg_constraint_oid,
 			0,
 			0,
 			0
@@ -346,7 +346,7 @@ static const struct cachedesc cacheinfo[] = {
 		ConversionOidIndexId,
 		1,
 		{
-			ObjectIdAttributeNumber,
+			Anum_pg_conversion_oid,
 			0,
 			0,
 			0
@@ -357,7 +357,7 @@ static const struct cachedesc cacheinfo[] = {
 		DatabaseOidIndexId,
 		1,
 		{
-			ObjectIdAttributeNumber,
+			Anum_pg_database_oid,
 			0,
 			0,
 			0
@@ -379,7 +379,7 @@ static const struct cachedesc cacheinfo[] = {
 		EnumOidIndexId,
 		1,
 		{
-			ObjectIdAttributeNumber,
+			Anum_pg_enum_oid,
 			0,
 			0,
 			0
@@ -412,7 +412,7 @@ static const struct cachedesc cacheinfo[] = {
 		EventTriggerOidIndexId,
 		1,
 		{
-			ObjectIdAttributeNumber,
+			Anum_pg_event_trigger_oid,
 			0,
 			0,
 			0
@@ -434,7 +434,7 @@ static const struct cachedesc cacheinfo[] = {
 		ForeignDataWrapperOidIndexId,
 		1,
 		{
-			ObjectIdAttributeNumber,
+			Anum_pg_foreign_data_wrapper_oid,
 			0,
 			0,
 			0
@@ -456,7 +456,7 @@ static const struct cachedesc cacheinfo[] = {
 		ForeignServerOidIndexId,
 		1,
 		{
-			ObjectIdAttributeNumber,
+			Anum_pg_foreign_server_oid,
 			0,
 			0,
 			0
@@ -500,7 +500,7 @@ static const struct cachedesc cacheinfo[] = {
 		LanguageOidIndexId,
 		1,
 		{
-			ObjectIdAttributeNumber,
+			Anum_pg_language_oid,
 			0,
 			0,
 			0
@@ -522,7 +522,7 @@ static const struct cachedesc cacheinfo[] = {
 		NamespaceOidIndexId,
 		1,
 		{
-			ObjectIdAttributeNumber,
+			Anum_pg_namespace_oid,
 			0,
 			0,
 			0
@@ -544,7 +544,7 @@ static const struct cachedesc cacheinfo[] = {
 		OperatorOidIndexId,
 		1,
 		{
-			ObjectIdAttributeNumber,
+			Anum_pg_operator_oid,
 			0,
 			0,
 			0
@@ -566,7 +566,7 @@ static const struct cachedesc cacheinfo[] = {
 		OpfamilyOidIndexId,
 		1,
 		{
-			ObjectIdAttributeNumber,
+			Anum_pg_opfamily_oid,
 			0,
 			0,
 			0
@@ -599,7 +599,7 @@ static const struct cachedesc cacheinfo[] = {
 		ProcedureOidIndexId,
 		1,
 		{
-			ObjectIdAttributeNumber,
+			Anum_pg_proc_oid,
 			0,
 			0,
 			0
@@ -621,7 +621,7 @@ static const struct cachedesc cacheinfo[] = {
 		PublicationObjectIndexId,
 		1,
 		{
-			ObjectIdAttributeNumber,
+			Anum_pg_publication_oid,
 			0,
 			0,
 			0
@@ -632,7 +632,7 @@ static const struct cachedesc cacheinfo[] = {
 		PublicationRelObjectIndexId,
 		1,
 		{
-			ObjectIdAttributeNumber,
+			Anum_pg_publication_rel_oid,
 			0,
 			0,
 			0
@@ -676,7 +676,7 @@ static const struct cachedesc cacheinfo[] = {
 		ClassOidIndexId,
 		1,
 		{
-			ObjectIdAttributeNumber,
+			Anum_pg_class_oid,
 			0,
 			0,
 			0
@@ -742,7 +742,7 @@ static const struct cachedesc cacheinfo[] = {
 		StatisticExtOidIndexId,
 		1,
 		{
-			ObjectIdAttributeNumber,
+			Anum_pg_statistic_ext_oid,
 			0,
 			0,
 			0
@@ -775,7 +775,7 @@ static const struct cachedesc cacheinfo[] = {
 		SubscriptionObjectIndexId,
 		1,
 		{
-			ObjectIdAttributeNumber,
+			Anum_pg_subscription_oid,
 			0,
 			0,
 			0
@@ -797,7 +797,7 @@ static const struct cachedesc cacheinfo[] = {
 		TablespaceOidIndexId,
 		1,
 		{
-			ObjectIdAttributeNumber,
+			Anum_pg_tablespace_oid,
 			0,
 			0,
 			0,
@@ -808,7 +808,7 @@ static const struct cachedesc cacheinfo[] = {
 		TransformOidIndexId,
 		1,
 		{
-			ObjectIdAttributeNumber,
+			Anum_pg_transform_oid,
 			0,
 			0,
 			0,
@@ -852,7 +852,7 @@ static const struct cachedesc cacheinfo[] = {
 		TSConfigOidIndexId,
 		1,
 		{
-			ObjectIdAttributeNumber,
+			Anum_pg_ts_config_oid,
 			0,
 			0,
 			0
@@ -874,7 +874,7 @@ static const struct cachedesc cacheinfo[] = {
 		TSDictionaryOidIndexId,
 		1,
 		{
-			ObjectIdAttributeNumber,
+			Anum_pg_ts_dict_oid,
 			0,
 			0,
 			0
@@ -896,7 +896,7 @@ static const struct cachedesc cacheinfo[] = {
 		TSParserOidIndexId,
 		1,
 		{
-			ObjectIdAttributeNumber,
+			Anum_pg_ts_parser_oid,
 			0,
 			0,
 			0
@@ -918,7 +918,7 @@ static const struct cachedesc cacheinfo[] = {
 		TSTemplateOidIndexId,
 		1,
 		{
-			ObjectIdAttributeNumber,
+			Anum_pg_ts_template_oid,
 			0,
 			0,
 			0
@@ -940,7 +940,7 @@ static const struct cachedesc cacheinfo[] = {
 		TypeOidIndexId,
 		1,
 		{
-			ObjectIdAttributeNumber,
+			Anum_pg_type_oid,
 			0,
 			0,
 			0
@@ -951,7 +951,7 @@ static const struct cachedesc cacheinfo[] = {
 		UserMappingOidIndexId,
 		1,
 		{
-			ObjectIdAttributeNumber,
+			Anum_pg_user_mapping_oid,
 			0,
 			0,
 			0
@@ -1230,7 +1230,9 @@ GetSysCacheOid(int cacheId,
 	tuple = SearchSysCache(cacheId, key1, key2, key3, key4);
 	if (!HeapTupleIsValid(tuple))
 		return InvalidOid;
-	result = HeapTupleGetOid(tuple);
+	/* XXX: THIS IS UNBELIEVABLY DIRTY AND NEEDS TO BE REWRITTEN */
+	result = ((Form_pg_class) GETSTRUCT(tuple))->oid;
+	//result = HeapTupleGetOid(tuple);
 	ReleaseSysCache(tuple);
 	return result;
 }
diff --git a/src/backend/utils/cache/typcache.c b/src/backend/utils/cache/typcache.c
index 663d4ed8bbd..09f9d5fdcbd 100644
--- a/src/backend/utils/cache/typcache.c
+++ b/src/backend/utils/cache/typcache.c
@@ -2351,7 +2351,7 @@ load_enum_cache_data(TypeCacheEntry *tcache)
 			maxitems *= 2;
 			items = (EnumItem *) repalloc(items, sizeof(EnumItem) * maxitems);
 		}
-		items[numitems].enum_oid = HeapTupleGetOid(enum_tuple);
+		items[numitems].enum_oid = en->oid;
 		items[numitems].sort_order = en->enumsortorder;
 		numitems++;
 	}
diff --git a/src/backend/utils/fmgr/fmgr.c b/src/backend/utils/fmgr/fmgr.c
index 6cbbd5b78b0..73ff48c1963 100644
--- a/src/backend/utils/fmgr/fmgr.c
+++ b/src/backend/utils/fmgr/fmgr.c
@@ -529,7 +529,7 @@ fetch_finfo_record(void *filehandle, const char *funcname)
 static CFuncHashTabEntry *
 lookup_C_func(HeapTuple procedureTuple)
 {
-	Oid			fn_oid = HeapTupleGetOid(procedureTuple);
+	Oid			fn_oid = ((Form_pg_proc) GETSTRUCT(procedureTuple))->oid;
 	CFuncHashTabEntry *entry;
 
 	if (CFuncHash == NULL)
@@ -554,7 +554,7 @@ static void
 record_C_func(HeapTuple procedureTuple,
 			  PGFunction user_fn, const Pg_finfo_record *inforec)
 {
-	Oid			fn_oid = HeapTupleGetOid(procedureTuple);
+	Oid			fn_oid =  ((Form_pg_proc) GETSTRUCT(procedureTuple))->oid;
 	CFuncHashTabEntry *entry;
 	bool		found;
 
diff --git a/src/backend/utils/fmgr/funcapi.c b/src/backend/utils/fmgr/funcapi.c
index 30923518f5e..c4df255f101 100644
--- a/src/backend/utils/fmgr/funcapi.c
+++ b/src/backend/utils/fmgr/funcapi.c
@@ -1301,7 +1301,7 @@ build_function_result_tupdesc_d(char prokind,
 	if (numoutargs < 2 && prokind != PROKIND_PROCEDURE)
 		return NULL;
 
-	desc = CreateTemplateTupleDesc(numoutargs, false);
+	desc = CreateTemplateTupleDesc(numoutargs);
 	for (i = 0; i < numoutargs; i++)
 	{
 		TupleDescInitEntry(desc, i + 1,
@@ -1421,7 +1421,7 @@ TypeGetTupleDesc(Oid typeoid, List *colaliases)
 		/* OK, get the column alias */
 		attname = strVal(linitial(colaliases));
 
-		tupdesc = CreateTemplateTupleDesc(1, false);
+		tupdesc = CreateTemplateTupleDesc(1);
 		TupleDescInitEntry(tupdesc,
 						   (AttrNumber) 1,
 						   attname,
diff --git a/src/backend/utils/init/miscinit.c b/src/backend/utils/init/miscinit.c
index 238fe1deec8..3d10aa57079 100644
--- a/src/backend/utils/init/miscinit.c
+++ b/src/backend/utils/init/miscinit.c
@@ -616,7 +616,7 @@ InitializeSessionUserId(const char *rolename, Oid roleid)
 	}
 
 	rform = (Form_pg_authid) GETSTRUCT(roleTup);
-	roleid = HeapTupleGetOid(roleTup);
+	roleid = rform->oid;
 	rname = NameStr(rform->rolname);
 
 	AuthenticatedUserId = roleid;
diff --git a/src/backend/utils/init/postinit.c b/src/backend/utils/init/postinit.c
index 4f1d2a0d288..b636b1e262a 100644
--- a/src/backend/utils/init/postinit.c
+++ b/src/backend/utils/init/postinit.c
@@ -146,7 +146,7 @@ GetDatabaseTupleByOid(Oid dboid)
 	 * form a scan key
 	 */
 	ScanKeyInit(&key[0],
-				ObjectIdAttributeNumber,
+				Anum_pg_database_oid,
 				BTEqualStrategyNumber, F_OIDEQ,
 				ObjectIdGetDatum(dboid));
 
@@ -885,7 +885,7 @@ InitPostgres(const char *in_dbname, Oid dboid, const char *username,
 					(errcode(ERRCODE_UNDEFINED_DATABASE),
 					 errmsg("database \"%s\" does not exist", in_dbname)));
 		dbform = (Form_pg_database) GETSTRUCT(tuple);
-		MyDatabaseId = HeapTupleGetOid(tuple);
+		MyDatabaseId = dbform->oid;
 		MyDatabaseTableSpace = dbform->dattablespace;
 		/* take database name from the caller, just for paranoia */
 		strlcpy(dbname, in_dbname, sizeof(dbname));
@@ -902,7 +902,7 @@ InitPostgres(const char *in_dbname, Oid dboid, const char *username,
 					(errcode(ERRCODE_UNDEFINED_DATABASE),
 					 errmsg("database %u does not exist", dboid)));
 		dbform = (Form_pg_database) GETSTRUCT(tuple);
-		MyDatabaseId = HeapTupleGetOid(tuple);
+		MyDatabaseId = dbform->oid;
 		MyDatabaseTableSpace = dbform->dattablespace;
 		Assert(MyDatabaseId == dboid);
 		strlcpy(dbname, NameStr(dbform->datname), sizeof(dbname));
@@ -984,7 +984,7 @@ InitPostgres(const char *in_dbname, Oid dboid, const char *username,
 
 		tuple = GetDatabaseTuple(dbname);
 		if (!HeapTupleIsValid(tuple) ||
-			MyDatabaseId != HeapTupleGetOid(tuple) ||
+			MyDatabaseId != ((Form_pg_database) GETSTRUCT(tuple))->oid ||
 			MyDatabaseTableSpace != ((Form_pg_database) GETSTRUCT(tuple))->dattablespace)
 			ereport(FATAL,
 					(errcode(ERRCODE_UNDEFINED_DATABASE),
diff --git a/src/backend/utils/misc/guc.c b/src/backend/utils/misc/guc.c
index 0327b295da8..2ef11a4c9d0 100644
--- a/src/backend/utils/misc/guc.c
+++ b/src/backend/utils/misc/guc.c
@@ -455,7 +455,6 @@ char	   *event_source;
 
 bool		row_security;
 bool		check_function_bodies = true;
-bool		default_with_oids = false;
 bool		session_auth_is_superuser;
 
 int			log_min_error_statement = ERROR;
@@ -1503,15 +1502,6 @@ static struct config_bool ConfigureNamesBool[] =
 		true,
 		NULL, NULL, NULL
 	},
-	{
-		{"default_with_oids", PGC_USERSET, COMPAT_OPTIONS_PREVIOUS,
-			gettext_noop("Create new tables with OIDs by default."),
-			NULL
-		},
-		&default_with_oids,
-		false,
-		NULL, NULL, NULL
-	},
 	{
 		{"logging_collector", PGC_POSTMASTER, LOGGING_WHERE,
 			gettext_noop("Start a subprocess to capture stderr output and/or csvlogs into log files."),
@@ -8218,7 +8208,7 @@ GetPGVariableResultDesc(const char *name)
 	if (guc_name_compare(name, "all") == 0)
 	{
 		/* need a tuple descriptor representing three TEXT columns */
-		tupdesc = CreateTemplateTupleDesc(3, false);
+		tupdesc = CreateTemplateTupleDesc(3);
 		TupleDescInitEntry(tupdesc, (AttrNumber) 1, "name",
 						   TEXTOID, -1, 0);
 		TupleDescInitEntry(tupdesc, (AttrNumber) 2, "setting",
@@ -8234,7 +8224,7 @@ GetPGVariableResultDesc(const char *name)
 		(void) GetConfigOptionByName(name, &varname, false);
 
 		/* need a tuple descriptor representing a single TEXT column */
-		tupdesc = CreateTemplateTupleDesc(1, false);
+		tupdesc = CreateTemplateTupleDesc(1);
 		TupleDescInitEntry(tupdesc, (AttrNumber) 1, varname,
 						   TEXTOID, -1, 0);
 	}
@@ -8257,7 +8247,7 @@ ShowGUCConfigOption(const char *name, DestReceiver *dest)
 	value = GetConfigOptionByName(name, &varname, false);
 
 	/* need a tuple descriptor representing a single TEXT column */
-	tupdesc = CreateTemplateTupleDesc(1, false);
+	tupdesc = CreateTemplateTupleDesc(1);
 	TupleDescInitBuiltinEntry(tupdesc, (AttrNumber) 1, varname,
 							  TEXTOID, -1, 0);
 
@@ -8283,7 +8273,7 @@ ShowAllGUCConfig(DestReceiver *dest)
 	bool		isnull[3] = {false, false, false};
 
 	/* need a tuple descriptor representing three TEXT columns */
-	tupdesc = CreateTemplateTupleDesc(3, false);
+	tupdesc = CreateTemplateTupleDesc(3);
 	TupleDescInitBuiltinEntry(tupdesc, (AttrNumber) 1, "name",
 							  TEXTOID, -1, 0);
 	TupleDescInitBuiltinEntry(tupdesc, (AttrNumber) 2, "setting",
@@ -8725,7 +8715,7 @@ show_all_settings(PG_FUNCTION_ARGS)
 		 * need a tuple descriptor representing NUM_PG_SETTINGS_ATTS columns
 		 * of the appropriate types
 		 */
-		tupdesc = CreateTemplateTupleDesc(NUM_PG_SETTINGS_ATTS, false);
+		tupdesc = CreateTemplateTupleDesc(NUM_PG_SETTINGS_ATTS);
 		TupleDescInitEntry(tupdesc, (AttrNumber) 1, "name",
 						   TEXTOID, -1, 0);
 		TupleDescInitEntry(tupdesc, (AttrNumber) 2, "setting",
@@ -8865,7 +8855,7 @@ show_all_file_settings(PG_FUNCTION_ARGS)
 	oldcontext = MemoryContextSwitchTo(per_query_ctx);
 
 	/* Build a tuple descriptor for our result type */
-	tupdesc = CreateTemplateTupleDesc(NUM_PG_FILE_SETTINGS_ATTS, false);
+	tupdesc = CreateTemplateTupleDesc(NUM_PG_FILE_SETTINGS_ATTS);
 	TupleDescInitEntry(tupdesc, (AttrNumber) 1, "sourcefile",
 					   TEXTOID, -1, 0);
 	TupleDescInitEntry(tupdesc, (AttrNumber) 2, "sourceline",
diff --git a/src/backend/utils/misc/pg_controldata.c b/src/backend/utils/misc/pg_controldata.c
index 3fc8b6a8a84..a3768752698 100644
--- a/src/backend/utils/misc/pg_controldata.c
+++ b/src/backend/utils/misc/pg_controldata.c
@@ -41,7 +41,7 @@ pg_control_system(PG_FUNCTION_ARGS)
 	 * Construct a tuple descriptor for the result row.  This must match this
 	 * function's pg_proc entry!
 	 */
-	tupdesc = CreateTemplateTupleDesc(4, false);
+	tupdesc = CreateTemplateTupleDesc(4);
 	TupleDescInitEntry(tupdesc, (AttrNumber) 1, "pg_control_version",
 					   INT4OID, -1, 0);
 	TupleDescInitEntry(tupdesc, (AttrNumber) 2, "catalog_version_no",
@@ -91,7 +91,7 @@ pg_control_checkpoint(PG_FUNCTION_ARGS)
 	 * Construct a tuple descriptor for the result row.  This must match this
 	 * function's pg_proc entry!
 	 */
-	tupdesc = CreateTemplateTupleDesc(18, false);
+	tupdesc = CreateTemplateTupleDesc(18);
 	TupleDescInitEntry(tupdesc, (AttrNumber) 1, "checkpoint_lsn",
 					   LSNOID, -1, 0);
 	TupleDescInitEntry(tupdesc, (AttrNumber) 2, "redo_lsn",
@@ -221,7 +221,7 @@ pg_control_recovery(PG_FUNCTION_ARGS)
 	 * Construct a tuple descriptor for the result row.  This must match this
 	 * function's pg_proc entry!
 	 */
-	tupdesc = CreateTemplateTupleDesc(5, false);
+	tupdesc = CreateTemplateTupleDesc(5);
 	TupleDescInitEntry(tupdesc, (AttrNumber) 1, "min_recovery_end_lsn",
 					   LSNOID, -1, 0);
 	TupleDescInitEntry(tupdesc, (AttrNumber) 2, "min_recovery_end_timeline",
@@ -274,7 +274,7 @@ pg_control_init(PG_FUNCTION_ARGS)
 	 * Construct a tuple descriptor for the result row.  This must match this
 	 * function's pg_proc entry!
 	 */
-	tupdesc = CreateTemplateTupleDesc(12, false);
+	tupdesc = CreateTemplateTupleDesc(12);
 	TupleDescInitEntry(tupdesc, (AttrNumber) 1, "max_data_alignment",
 					   INT4OID, -1, 0);
 	TupleDescInitEntry(tupdesc, (AttrNumber) 2, "database_block_size",
diff --git a/src/backend/utils/misc/postgresql.conf.sample b/src/backend/utils/misc/postgresql.conf.sample
index 3fe257c53f1..5986c1edfc0 100644
--- a/src/backend/utils/misc/postgresql.conf.sample
+++ b/src/backend/utils/misc/postgresql.conf.sample
@@ -647,7 +647,6 @@
 
 #array_nulls = on
 #backslash_quote = safe_encoding	# on, off, or safe_encoding
-#default_with_oids = off
 #escape_string_warning = on
 #lo_compat_privileges = off
 #operator_precedence_warning = off
diff --git a/src/backend/utils/mmgr/portalmem.c b/src/backend/utils/mmgr/portalmem.c
index d34cab0eb88..2b014c86bd1 100644
--- a/src/backend/utils/mmgr/portalmem.c
+++ b/src/backend/utils/mmgr/portalmem.c
@@ -1146,7 +1146,7 @@ pg_cursor(PG_FUNCTION_ARGS)
 	 * build tupdesc for result tuples. This must match the definition of the
 	 * pg_cursors view in system_views.sql
 	 */
-	tupdesc = CreateTemplateTupleDesc(6, false);
+	tupdesc = CreateTemplateTupleDesc(6);
 	TupleDescInitEntry(tupdesc, (AttrNumber) 1, "name",
 					   TEXTOID, -1, 0);
 	TupleDescInitEntry(tupdesc, (AttrNumber) 2, "statement",
diff --git a/src/bin/initdb/initdb.c b/src/bin/initdb/initdb.c
index ab5cb7f0c13..211a96380ef 100644
--- a/src/bin/initdb/initdb.c
+++ b/src/bin/initdb/initdb.c
@@ -1710,7 +1710,7 @@ setup_description(FILE *cmdfd)
 				"	objoid oid, "
 				"	classname name, "
 				"	objsubid int4, "
-				"	description text) WITHOUT OIDS;\n\n");
+				"	description text);\n\n");
 
 	PG_CMD_PRINTF1("COPY tmp_pg_description FROM E'%s';\n\n",
 				   escape_quotes(desc_file));
@@ -1723,7 +1723,7 @@ setup_description(FILE *cmdfd)
 	PG_CMD_PUTS("CREATE TEMP TABLE tmp_pg_shdescription ( "
 				" objoid oid, "
 				" classname name, "
-				" description text) WITHOUT OIDS;\n\n");
+				" description text);\n\n");
 
 	PG_CMD_PRINTF1("COPY tmp_pg_shdescription FROM E'%s';\n\n",
 				   escape_quotes(shdesc_file));
@@ -1766,7 +1766,8 @@ setup_collation(FILE *cmdfd)
 	 * in pg_collation.h.  But add it before reading system collations, so
 	 * that it wins if libc defines a locale named ucs_basic.
 	 */
-	PG_CMD_PRINTF3("INSERT INTO pg_collation (collname, collnamespace, collowner, collprovider, collencoding, collcollate, collctype) VALUES ('ucs_basic', 'pg_catalog'::regnamespace, %u, '%c', %d, 'C', 'C');\n\n",
+	PG_CMD_PRINTF3("INSERT INTO pg_collation (oid, collname, collnamespace, collowner, collprovider, collencoding, collcollate, collctype)"
+				   "VALUES (pg_nextoid('pg_catalog.pg_collation', 'oid', 'pg_catalog.pg_collation_oid_index'), 'ucs_basic', 'pg_catalog'::regnamespace, %u, '%c', %d, 'C', 'C');\n\n",
 				   BOOTSTRAP_SUPERUSERID, COLLPROVIDER_LIBC, PG_UTF8);
 
 	/* Now import all collations we can find in the operating system */
diff --git a/src/bin/pg_dump/pg_backup_archiver.c b/src/bin/pg_dump/pg_backup_archiver.c
index defa8a41b77..4c394c1bac8 100644
--- a/src/bin/pg_dump/pg_backup_archiver.c
+++ b/src/bin/pg_dump/pg_backup_archiver.c
@@ -80,7 +80,6 @@ static void _printTocEntry(ArchiveHandle *AH, TocEntry *te, bool isData);
 static char *replace_line_endings(const char *str);
 static void _doSetFixedOutputState(ArchiveHandle *AH);
 static void _doSetSessionAuth(ArchiveHandle *AH, const char *user);
-static void _doSetWithOids(ArchiveHandle *AH, const bool withOids);
 static void _reconnectToDB(ArchiveHandle *AH, const char *dbname);
 static void _becomeUser(ArchiveHandle *AH, const char *user);
 static void _becomeOwner(ArchiveHandle *AH, TocEntry *te);
@@ -1072,7 +1071,7 @@ ArchiveEntry(Archive *AHX,
 			 const char *tag,
 			 const char *namespace,
 			 const char *tablespace,
-			 const char *owner, bool withOids,
+			 const char *owner,
 			 const char *desc, teSection section,
 			 const char *defn,
 			 const char *dropStmt, const char *copyStmt,
@@ -1101,7 +1100,6 @@ ArchiveEntry(Archive *AHX,
 	newToc->namespace = namespace ? pg_strdup(namespace) : NULL;
 	newToc->tablespace = tablespace ? pg_strdup(tablespace) : NULL;
 	newToc->owner = pg_strdup(owner);
-	newToc->withOids = withOids;
 	newToc->desc = pg_strdup(desc);
 	newToc->defn = pg_strdup(defn);
 	newToc->dropStmt = pg_strdup(dropStmt);
@@ -2369,7 +2367,6 @@ _allocAH(const char *FileSpec, const ArchiveFormat fmt,
 	AH->currUser = NULL;		/* unknown */
 	AH->currSchema = NULL;		/* ditto */
 	AH->currTablespace = NULL;	/* ditto */
-	AH->currWithOids = -1;		/* force SET */
 
 	AH->toc = (TocEntry *) pg_malloc0(sizeof(TocEntry));
 
@@ -2597,7 +2594,7 @@ WriteToc(ArchiveHandle *AH)
 		WriteStr(AH, te->namespace);
 		WriteStr(AH, te->tablespace);
 		WriteStr(AH, te->owner);
-		WriteStr(AH, te->withOids ? "true" : "false");
+		WriteStr(AH, "false");
 
 		/* Dump list of dependencies */
 		for (i = 0; i < te->nDeps; i++)
@@ -2702,12 +2699,10 @@ ReadToc(ArchiveHandle *AH)
 		if (AH->version >= K_VERS_1_9)
 		{
 			if (strcmp(ReadStr(AH), "true") == 0)
-				te->withOids = true;
-			else
-				te->withOids = false;
+				write_msg(modulename, "WARNING: don't know how restore tables with oid");
 		}
 		else
-			te->withOids = true;
+			write_msg(modulename, "WARNING: don't know how restore tables with oid");
 
 		/* Read TOC entry dependencies */
 		if (AH->version >= K_VERS_1_5)
@@ -3253,38 +3248,6 @@ _doSetSessionAuth(ArchiveHandle *AH, const char *user)
 }
 
 
-/*
- * Issue a SET default_with_oids command.  Caller is responsible
- * for updating state if appropriate.
- */
-static void
-_doSetWithOids(ArchiveHandle *AH, const bool withOids)
-{
-	PQExpBuffer cmd = createPQExpBuffer();
-
-	appendPQExpBuffer(cmd, "SET default_with_oids = %s;", withOids ?
-					  "true" : "false");
-
-	if (RestoringToDB(AH))
-	{
-		PGresult   *res;
-
-		res = PQexec(AH->connection, cmd->data);
-
-		if (!res || PQresultStatus(res) != PGRES_COMMAND_OK)
-			warn_or_exit_horribly(AH, modulename,
-								  "could not set default_with_oids: %s",
-								  PQerrorMessage(AH->connection));
-
-		PQclear(res);
-	}
-	else
-		ahprintf(AH, "%s\n\n", cmd->data);
-
-	destroyPQExpBuffer(cmd);
-}
-
-
 /*
  * Issue the commands to connect to the specified database.
  *
@@ -3329,7 +3292,6 @@ _reconnectToDB(ArchiveHandle *AH, const char *dbname)
 	if (AH->currTablespace)
 		free(AH->currTablespace);
 	AH->currTablespace = NULL;
-	AH->currWithOids = -1;
 
 	/* re-establish fixed state */
 	_doSetFixedOutputState(AH);
@@ -3376,20 +3338,6 @@ _becomeOwner(ArchiveHandle *AH, TocEntry *te)
 }
 
 
-/*
- * Set the proper default_with_oids value for the table.
- */
-static void
-_setWithOids(ArchiveHandle *AH, TocEntry *te)
-{
-	if (AH->currWithOids != te->withOids)
-	{
-		_doSetWithOids(AH, te->withOids);
-		AH->currWithOids = te->withOids;
-	}
-}
-
-
 /*
  * Issue the commands to select the specified schema as the current schema
  * in the target database.
@@ -3604,10 +3552,6 @@ _printTocEntry(ArchiveHandle *AH, TocEntry *te, bool isData)
 	_selectOutputSchema(AH, te->namespace);
 	_selectTablespace(AH, te->tablespace);
 
-	/* Set up OID mode too */
-	if (strcmp(te->desc, "TABLE") == 0)
-		_setWithOids(AH, te);
-
 	/* Emit header comment for item */
 	if (!AH->noTocComments)
 	{
@@ -4081,7 +4025,6 @@ restore_toc_entries_prefork(ArchiveHandle *AH, TocEntry *pending_list)
 	if (AH->currTablespace)
 		free(AH->currTablespace);
 	AH->currTablespace = NULL;
-	AH->currWithOids = -1;
 }
 
 /*
@@ -4877,7 +4820,6 @@ CloneArchive(ArchiveHandle *AH)
 	clone->currUser = NULL;
 	clone->currSchema = NULL;
 	clone->currTablespace = NULL;
-	clone->currWithOids = -1;
 
 	/* savedPassword must be local in case we change it while connecting */
 	if (clone->savedPassword)
diff --git a/src/bin/pg_dump/pg_backup_archiver.h b/src/bin/pg_dump/pg_backup_archiver.h
index 05e9de632f4..306d2ceba9e 100644
--- a/src/bin/pg_dump/pg_backup_archiver.h
+++ b/src/bin/pg_dump/pg_backup_archiver.h
@@ -347,8 +347,6 @@ struct _archiveHandle
 	char	   *currUser;		/* current username, or NULL if unknown */
 	char	   *currSchema;		/* current schema, or NULL */
 	char	   *currTablespace; /* current tablespace, or NULL */
-	char		currWithOids;	/* current default_with_oids setting: true,
-								 * false, or -1 for unknown, forcing a SET */
 
 	void	   *lo_buf;
 	size_t		lo_buf_used;
@@ -376,7 +374,6 @@ struct _tocEntry
 	char	   *tablespace;		/* null if not in a tablespace; empty string
 								 * means use database default */
 	char	   *owner;
-	bool		withOids;		/* Used only by "TABLE" tags */
 	char	   *desc;
 	char	   *defn;
 	char	   *dropStmt;
@@ -413,7 +410,7 @@ extern TocEntry *ArchiveEntry(Archive *AHX,
 			 CatalogId catalogId, DumpId dumpId,
 			 const char *tag,
 			 const char *namespace, const char *tablespace,
-			 const char *owner, bool withOids,
+			 const char *owner,
 			 const char *desc, teSection section,
 			 const char *defn,
 			 const char *dropStmt, const char *copyStmt,
diff --git a/src/bin/pg_dump/pg_dump.c b/src/bin/pg_dump/pg_dump.c
index c8d01ed4a4c..72bdd6988ef 100644
--- a/src/bin/pg_dump/pg_dump.c
+++ b/src/bin/pg_dump/pg_dump.c
@@ -1738,8 +1738,6 @@ dumpTableData_copy(Archive *fout, void *dcontext)
 	TableDataInfo *tdinfo = (TableDataInfo *) dcontext;
 	TableInfo  *tbinfo = tdinfo->tdtable;
 	const char *classname = tbinfo->dobj.name;
-	const bool	hasoids = tbinfo->hasoids;
-	const bool	oids = tdinfo->oids;
 	PQExpBuffer q = createPQExpBuffer();
 
 	/*
@@ -1765,13 +1763,7 @@ dumpTableData_copy(Archive *fout, void *dcontext)
 	 */
 	column_list = fmtCopyColumnList(tbinfo, clistBuf);
 
-	if (oids && hasoids)
-	{
-		appendPQExpBuffer(q, "COPY %s %s WITH OIDS TO stdout;",
-						  fmtQualifiedDumpable(tbinfo),
-						  column_list);
-	}
-	else if (tdinfo->filtercond)
+	if (tdinfo->filtercond)
 	{
 		/* Note: this syntax is only supported in 8.2 and up */
 		appendPQExpBufferStr(q, "COPY (SELECT ");
@@ -2135,9 +2127,8 @@ dumpTableData(Archive *fout, TableDataInfo *tdinfo)
 		/* must use 2 steps here 'cause fmtId is nonreentrant */
 		appendPQExpBuffer(copyBuf, "COPY %s ",
 						  copyFrom);
-		appendPQExpBuffer(copyBuf, "%s %sFROM stdin;\n",
-						  fmtCopyColumnList(tbinfo, clistBuf),
-						  (tdinfo->oids && tbinfo->hasoids) ? "WITH OIDS " : "");
+		appendPQExpBuffer(copyBuf, "%s FROM stdin;\n",
+						  fmtCopyColumnList(tbinfo, clistBuf));
 		copyStmt = copyBuf->data;
 	}
 	else
@@ -2159,7 +2150,7 @@ dumpTableData(Archive *fout, TableDataInfo *tdinfo)
 		te = ArchiveEntry(fout, tdinfo->dobj.catId, tdinfo->dobj.dumpId,
 						  tbinfo->dobj.name, tbinfo->dobj.namespace->dobj.name,
 						  NULL, tbinfo->rolname,
-						  false, "TABLE DATA", SECTION_DATA,
+						  "TABLE DATA", SECTION_DATA,
 						  "", "", copyStmt,
 						  &(tbinfo->dobj.dumpId), 1,
 						  dumpFn, tdinfo);
@@ -2210,7 +2201,6 @@ refreshMatViewData(Archive *fout, TableDataInfo *tdinfo)
 					 tbinfo->dobj.namespace->dobj.name, /* Namespace */
 					 NULL,		/* Tablespace */
 					 tbinfo->rolname,	/* Owner */
-					 false,		/* with oids */
 					 "MATERIALIZED VIEW DATA",	/* Desc */
 					 SECTION_POST_DATA, /* Section */
 					 q->data,	/* Create */
@@ -2750,7 +2740,6 @@ dumpDatabase(Archive *fout)
 				 NULL,			/* Namespace */
 				 NULL,			/* Tablespace */
 				 dba,			/* Owner */
-				 false,			/* with oids */
 				 "DATABASE",	/* Desc */
 				 SECTION_PRE_DATA,	/* Section */
 				 creaQry->data, /* Create */
@@ -2788,7 +2777,7 @@ dumpDatabase(Archive *fout)
 
 			ArchiveEntry(fout, nilCatalogId, createDumpId(),
 						 labelq->data, NULL, NULL, dba,
-						 false, "COMMENT", SECTION_NONE,
+						 "COMMENT", SECTION_NONE,
 						 dbQry->data, "", NULL,
 						 &(dbDumpId), 1,
 						 NULL, NULL);
@@ -2815,7 +2804,7 @@ dumpDatabase(Archive *fout)
 		if (seclabelQry->len > 0)
 			ArchiveEntry(fout, nilCatalogId, createDumpId(),
 						 labelq->data, NULL, NULL, dba,
-						 false, "SECURITY LABEL", SECTION_NONE,
+						 "SECURITY LABEL", SECTION_NONE,
 						 seclabelQry->data, "", NULL,
 						 &(dbDumpId), 1,
 						 NULL, NULL);
@@ -2885,7 +2874,7 @@ dumpDatabase(Archive *fout)
 	if (creaQry->len > 0)
 		ArchiveEntry(fout, nilCatalogId, createDumpId(),
 					 datname, NULL, NULL, dba,
-					 false, "DATABASE PROPERTIES", SECTION_PRE_DATA,
+					 "DATABASE PROPERTIES", SECTION_PRE_DATA,
 					 creaQry->data, delQry->data, NULL,
 					 &(dbDumpId), 1,
 					 NULL, NULL);
@@ -2930,7 +2919,7 @@ dumpDatabase(Archive *fout)
 						  LargeObjectRelationId);
 		ArchiveEntry(fout, nilCatalogId, createDumpId(),
 					 "pg_largeobject", NULL, NULL, "",
-					 false, "pg_largeobject", SECTION_PRE_DATA,
+					 "pg_largeobject", SECTION_PRE_DATA,
 					 loOutQry->data, "", NULL,
 					 NULL, 0,
 					 NULL, NULL);
@@ -2970,7 +2959,7 @@ dumpDatabase(Archive *fout)
 							  LargeObjectMetadataRelationId);
 			ArchiveEntry(fout, nilCatalogId, createDumpId(),
 						 "pg_largeobject_metadata", NULL, NULL, "",
-						 false, "pg_largeobject_metadata", SECTION_PRE_DATA,
+						 "pg_largeobject_metadata", SECTION_PRE_DATA,
 						 loOutQry->data, "", NULL,
 						 NULL, 0,
 						 NULL, NULL);
@@ -3081,7 +3070,7 @@ dumpEncoding(Archive *AH)
 
 	ArchiveEntry(AH, nilCatalogId, createDumpId(),
 				 "ENCODING", NULL, NULL, "",
-				 false, "ENCODING", SECTION_PRE_DATA,
+				 "ENCODING", SECTION_PRE_DATA,
 				 qry->data, "", NULL,
 				 NULL, 0,
 				 NULL, NULL);
@@ -3108,7 +3097,7 @@ dumpStdStrings(Archive *AH)
 
 	ArchiveEntry(AH, nilCatalogId, createDumpId(),
 				 "STDSTRINGS", NULL, NULL, "",
-				 false, "STDSTRINGS", SECTION_PRE_DATA,
+				 "STDSTRINGS", SECTION_PRE_DATA,
 				 qry->data, "", NULL,
 				 NULL, 0,
 				 NULL, NULL);
@@ -3164,7 +3153,7 @@ dumpSearchPath(Archive *AH)
 
 	ArchiveEntry(AH, nilCatalogId, createDumpId(),
 				 "SEARCHPATH", NULL, NULL, "",
-				 false, "SEARCHPATH", SECTION_PRE_DATA,
+				 "SEARCHPATH", SECTION_PRE_DATA,
 				 qry->data, "", NULL,
 				 NULL, 0,
 				 NULL, NULL);
@@ -3345,7 +3334,7 @@ dumpBlob(Archive *fout, BlobInfo *binfo)
 		ArchiveEntry(fout, binfo->dobj.catId, binfo->dobj.dumpId,
 					 binfo->dobj.name,
 					 NULL, NULL,
-					 binfo->rolname, false,
+					 binfo->rolname,
 					 "BLOB", SECTION_PRE_DATA,
 					 cquery->data, dquery->data, NULL,
 					 NULL, 0,
@@ -3646,7 +3635,7 @@ dumpPolicy(Archive *fout, PolicyInfo *polinfo)
 						 polinfo->dobj.name,
 						 polinfo->dobj.namespace->dobj.name,
 						 NULL,
-						 tbinfo->rolname, false,
+						 tbinfo->rolname,
 						 "ROW SECURITY", SECTION_POST_DATA,
 						 query->data, "", NULL,
 						 &(tbinfo->dobj.dumpId), 1,
@@ -3702,7 +3691,7 @@ dumpPolicy(Archive *fout, PolicyInfo *polinfo)
 					 tag,
 					 polinfo->dobj.namespace->dobj.name,
 					 NULL,
-					 tbinfo->rolname, false,
+					 tbinfo->rolname,
 					 "POLICY", SECTION_POST_DATA,
 					 query->data, delqry->data, NULL,
 					 NULL, 0,
@@ -3876,7 +3865,7 @@ dumpPublication(Archive *fout, PublicationInfo *pubinfo)
 				 pubinfo->dobj.name,
 				 NULL,
 				 NULL,
-				 pubinfo->rolname, false,
+				 pubinfo->rolname,
 				 "PUBLICATION", SECTION_POST_DATA,
 				 query->data, delq->data, NULL,
 				 NULL, 0,
@@ -4019,7 +4008,7 @@ dumpPublicationTable(Archive *fout, PublicationRelInfo *pubrinfo)
 				 tag,
 				 tbinfo->dobj.namespace->dobj.name,
 				 NULL,
-				 "", false,
+				 "",
 				 "PUBLICATION TABLE", SECTION_POST_DATA,
 				 query->data, "", NULL,
 				 NULL, 0,
@@ -4212,7 +4201,7 @@ dumpSubscription(Archive *fout, SubscriptionInfo *subinfo)
 				 subinfo->dobj.name,
 				 NULL,
 				 NULL,
-				 subinfo->rolname, false,
+				 subinfo->rolname,
 				 "SUBSCRIPTION", SECTION_POST_DATA,
 				 query->data, delq->data, NULL,
 				 NULL, 0,
@@ -5921,6 +5910,7 @@ getTables(Archive *fout, int *numTables)
 		char	   *partkeydef = "NULL";
 		char	   *ispartition = "false";
 		char	   *partbound = "NULL";
+		char	   *withoids = "c.relhasoids";
 
 		PQExpBuffer acl_subquery = createPQExpBuffer();
 		PQExpBuffer racl_subquery = createPQExpBuffer();
@@ -5944,6 +5934,12 @@ getTables(Archive *fout, int *numTables)
 			partbound = "pg_get_expr(c.relpartbound, c.oid)";
 		}
 
+		/*
+		 * In PG12 upwards WITH OIDs does not exist anymore.
+		 */
+		if (fout->remoteVersion >= 120000)
+			withoids = "false";
+
 		/*
 		 * Left join to pick up dependency info linking sequences to their
 		 * owning column, if any (note this dependency is AUTO as of 8.2)
@@ -5969,7 +5965,7 @@ getTables(Archive *fout, int *numTables)
 						  "c.relkind, c.relnamespace, "
 						  "(%s c.relowner) AS rolname, "
 						  "c.relchecks, c.relhastriggers, "
-						  "c.relhasindex, c.relhasrules, c.relhasoids, "
+						  "c.relhasindex, c.relhasrules, %s AS relhasoids, "
 						  "c.relrowsecurity, c.relforcerowsecurity, "
 						  "c.relfrozenxid, c.relminmxid, tc.oid AS toid, "
 						  "tc.relfrozenxid AS tfrozenxid, "
@@ -6017,6 +6013,7 @@ getTables(Archive *fout, int *numTables)
 						  initacl_subquery->data,
 						  initracl_subquery->data,
 						  username_subquery,
+						  withoids,
 						  RELKIND_SEQUENCE,
 						  attacl_subquery->data,
 						  attracl_subquery->data,
@@ -9416,7 +9413,7 @@ dumpComment(Archive *fout, const char *type, const char *name,
 		 */
 		ArchiveEntry(fout, nilCatalogId, createDumpId(),
 					 tag->data, namespace, NULL, owner,
-					 false, "COMMENT", SECTION_NONE,
+					 "COMMENT", SECTION_NONE,
 					 query->data, "", NULL,
 					 &(dumpId), 1,
 					 NULL, NULL);
@@ -9484,7 +9481,7 @@ dumpTableComment(Archive *fout, TableInfo *tbinfo,
 						 tag->data,
 						 tbinfo->dobj.namespace->dobj.name,
 						 NULL, tbinfo->rolname,
-						 false, "COMMENT", SECTION_NONE,
+						 "COMMENT", SECTION_NONE,
 						 query->data, "", NULL,
 						 &(tbinfo->dobj.dumpId), 1,
 						 NULL, NULL);
@@ -9508,7 +9505,7 @@ dumpTableComment(Archive *fout, TableInfo *tbinfo,
 						 tag->data,
 						 tbinfo->dobj.namespace->dobj.name,
 						 NULL, tbinfo->rolname,
-						 false, "COMMENT", SECTION_NONE,
+						 "COMMENT", SECTION_NONE,
 						 query->data, "", NULL,
 						 &(tbinfo->dobj.dumpId), 1,
 						 NULL, NULL);
@@ -9789,7 +9786,7 @@ dumpDumpableObject(Archive *fout, DumpableObject *dobj)
 
 				te = ArchiveEntry(fout, dobj->catId, dobj->dumpId,
 								  dobj->name, NULL, NULL, "",
-								  false, "BLOBS", SECTION_DATA,
+								  "BLOBS", SECTION_DATA,
 								  "", "", NULL,
 								  NULL, 0,
 								  dumpBlobs, NULL);
@@ -9863,7 +9860,7 @@ dumpNamespace(Archive *fout, NamespaceInfo *nspinfo)
 					 nspinfo->dobj.name,
 					 NULL, NULL,
 					 nspinfo->rolname,
-					 false, "SCHEMA", SECTION_PRE_DATA,
+					 "SCHEMA", SECTION_PRE_DATA,
 					 q->data, delq->data, NULL,
 					 NULL, 0,
 					 NULL, NULL);
@@ -9999,7 +9996,7 @@ dumpExtension(Archive *fout, ExtensionInfo *extinfo)
 					 extinfo->dobj.name,
 					 NULL, NULL,
 					 "",
-					 false, "EXTENSION", SECTION_PRE_DATA,
+					 "EXTENSION", SECTION_PRE_DATA,
 					 q->data, delq->data, NULL,
 					 NULL, 0,
 					 NULL, NULL);
@@ -10149,7 +10146,7 @@ dumpEnumType(Archive *fout, TypeInfo *tyinfo)
 					 tyinfo->dobj.name,
 					 tyinfo->dobj.namespace->dobj.name,
 					 NULL,
-					 tyinfo->rolname, false,
+					 tyinfo->rolname,
 					 "TYPE", SECTION_PRE_DATA,
 					 q->data, delq->data, NULL,
 					 NULL, 0,
@@ -10276,7 +10273,7 @@ dumpRangeType(Archive *fout, TypeInfo *tyinfo)
 					 tyinfo->dobj.name,
 					 tyinfo->dobj.namespace->dobj.name,
 					 NULL,
-					 tyinfo->rolname, false,
+					 tyinfo->rolname,
 					 "TYPE", SECTION_PRE_DATA,
 					 q->data, delq->data, NULL,
 					 NULL, 0,
@@ -10349,7 +10346,7 @@ dumpUndefinedType(Archive *fout, TypeInfo *tyinfo)
 					 tyinfo->dobj.name,
 					 tyinfo->dobj.namespace->dobj.name,
 					 NULL,
-					 tyinfo->rolname, false,
+					 tyinfo->rolname,
 					 "TYPE", SECTION_PRE_DATA,
 					 q->data, delq->data, NULL,
 					 NULL, 0,
@@ -10631,7 +10628,7 @@ dumpBaseType(Archive *fout, TypeInfo *tyinfo)
 					 tyinfo->dobj.name,
 					 tyinfo->dobj.namespace->dobj.name,
 					 NULL,
-					 tyinfo->rolname, false,
+					 tyinfo->rolname,
 					 "TYPE", SECTION_PRE_DATA,
 					 q->data, delq->data, NULL,
 					 NULL, 0,
@@ -10788,7 +10785,7 @@ dumpDomain(Archive *fout, TypeInfo *tyinfo)
 					 tyinfo->dobj.name,
 					 tyinfo->dobj.namespace->dobj.name,
 					 NULL,
-					 tyinfo->rolname, false,
+					 tyinfo->rolname,
 					 "DOMAIN", SECTION_PRE_DATA,
 					 q->data, delq->data, NULL,
 					 NULL, 0,
@@ -11010,7 +11007,7 @@ dumpCompositeType(Archive *fout, TypeInfo *tyinfo)
 					 tyinfo->dobj.name,
 					 tyinfo->dobj.namespace->dobj.name,
 					 NULL,
-					 tyinfo->rolname, false,
+					 tyinfo->rolname,
 					 "TYPE", SECTION_PRE_DATA,
 					 q->data, delq->data, NULL,
 					 NULL, 0,
@@ -11146,7 +11143,7 @@ dumpCompositeTypeColComments(Archive *fout, TypeInfo *tyinfo)
 						 target->data,
 						 tyinfo->dobj.namespace->dobj.name,
 						 NULL, tyinfo->rolname,
-						 false, "COMMENT", SECTION_NONE,
+						 "COMMENT", SECTION_NONE,
 						 query->data, "", NULL,
 						 &(tyinfo->dobj.dumpId), 1,
 						 NULL, NULL);
@@ -11201,7 +11198,7 @@ dumpShellType(Archive *fout, ShellTypeInfo *stinfo)
 					 stinfo->dobj.name,
 					 stinfo->dobj.namespace->dobj.name,
 					 NULL,
-					 stinfo->baseType->rolname, false,
+					 stinfo->baseType->rolname,
 					 "SHELL TYPE", SECTION_PRE_DATA,
 					 q->data, "", NULL,
 					 NULL, 0,
@@ -11312,7 +11309,7 @@ dumpProcLang(Archive *fout, ProcLangInfo *plang)
 		ArchiveEntry(fout, plang->dobj.catId, plang->dobj.dumpId,
 					 plang->dobj.name,
 					 NULL, NULL, plang->lanowner,
-					 false, "PROCEDURAL LANGUAGE", SECTION_PRE_DATA,
+					 "PROCEDURAL LANGUAGE", SECTION_PRE_DATA,
 					 defqry->data, delqry->data, NULL,
 					 NULL, 0,
 					 NULL, NULL);
@@ -11983,7 +11980,7 @@ dumpFunc(Archive *fout, FuncInfo *finfo)
 					 funcsig_tag,
 					 finfo->dobj.namespace->dobj.name,
 					 NULL,
-					 finfo->rolname, false,
+					 finfo->rolname,
 					 keyword, SECTION_PRE_DATA,
 					 q->data, delqry->data, NULL,
 					 NULL, 0,
@@ -12117,7 +12114,7 @@ dumpCast(Archive *fout, CastInfo *cast)
 		ArchiveEntry(fout, cast->dobj.catId, cast->dobj.dumpId,
 					 labelq->data,
 					 NULL, NULL, "",
-					 false, "CAST", SECTION_PRE_DATA,
+					 "CAST", SECTION_PRE_DATA,
 					 defqry->data, delqry->data, NULL,
 					 NULL, 0,
 					 NULL, NULL);
@@ -12245,7 +12242,7 @@ dumpTransform(Archive *fout, TransformInfo *transform)
 		ArchiveEntry(fout, transform->dobj.catId, transform->dobj.dumpId,
 					 labelq->data,
 					 NULL, NULL, "",
-					 false, "TRANSFORM", SECTION_PRE_DATA,
+					 "TRANSFORM", SECTION_PRE_DATA,
 					 defqry->data, delqry->data, NULL,
 					 transform->dobj.dependencies, transform->dobj.nDeps,
 					 NULL, NULL);
@@ -12460,7 +12457,7 @@ dumpOpr(Archive *fout, OprInfo *oprinfo)
 					 oprinfo->dobj.namespace->dobj.name,
 					 NULL,
 					 oprinfo->rolname,
-					 false, "OPERATOR", SECTION_PRE_DATA,
+					 "OPERATOR", SECTION_PRE_DATA,
 					 q->data, delq->data, NULL,
 					 NULL, 0,
 					 NULL, NULL);
@@ -12630,7 +12627,7 @@ dumpAccessMethod(Archive *fout, AccessMethodInfo *aminfo)
 					 NULL,
 					 NULL,
 					 "",
-					 false, "ACCESS METHOD", SECTION_PRE_DATA,
+					 "ACCESS METHOD", SECTION_PRE_DATA,
 					 q->data, delq->data, NULL,
 					 NULL, 0,
 					 NULL, NULL);
@@ -12996,7 +12993,7 @@ dumpOpclass(Archive *fout, OpclassInfo *opcinfo)
 					 opcinfo->dobj.namespace->dobj.name,
 					 NULL,
 					 opcinfo->rolname,
-					 false, "OPERATOR CLASS", SECTION_PRE_DATA,
+					 "OPERATOR CLASS", SECTION_PRE_DATA,
 					 q->data, delq->data, NULL,
 					 NULL, 0,
 					 NULL, NULL);
@@ -13263,7 +13260,7 @@ dumpOpfamily(Archive *fout, OpfamilyInfo *opfinfo)
 					 opfinfo->dobj.namespace->dobj.name,
 					 NULL,
 					 opfinfo->rolname,
-					 false, "OPERATOR FAMILY", SECTION_PRE_DATA,
+					 "OPERATOR FAMILY", SECTION_PRE_DATA,
 					 q->data, delq->data, NULL,
 					 NULL, 0,
 					 NULL, NULL);
@@ -13406,7 +13403,7 @@ dumpCollation(Archive *fout, CollInfo *collinfo)
 					 collinfo->dobj.namespace->dobj.name,
 					 NULL,
 					 collinfo->rolname,
-					 false, "COLLATION", SECTION_PRE_DATA,
+					 "COLLATION", SECTION_PRE_DATA,
 					 q->data, delq->data, NULL,
 					 NULL, 0,
 					 NULL, NULL);
@@ -13501,7 +13498,7 @@ dumpConversion(Archive *fout, ConvInfo *convinfo)
 					 convinfo->dobj.namespace->dobj.name,
 					 NULL,
 					 convinfo->rolname,
-					 false, "CONVERSION", SECTION_PRE_DATA,
+					 "CONVERSION", SECTION_PRE_DATA,
 					 q->data, delq->data, NULL,
 					 NULL, 0,
 					 NULL, NULL);
@@ -13990,7 +13987,7 @@ dumpAgg(Archive *fout, AggInfo *agginfo)
 					 agginfo->aggfn.dobj.namespace->dobj.name,
 					 NULL,
 					 agginfo->aggfn.rolname,
-					 false, "AGGREGATE", SECTION_PRE_DATA,
+					 "AGGREGATE", SECTION_PRE_DATA,
 					 q->data, delq->data, NULL,
 					 NULL, 0,
 					 NULL, NULL);
@@ -14088,7 +14085,7 @@ dumpTSParser(Archive *fout, TSParserInfo *prsinfo)
 					 prsinfo->dobj.namespace->dobj.name,
 					 NULL,
 					 "",
-					 false, "TEXT SEARCH PARSER", SECTION_PRE_DATA,
+					 "TEXT SEARCH PARSER", SECTION_PRE_DATA,
 					 q->data, delq->data, NULL,
 					 NULL, 0,
 					 NULL, NULL);
@@ -14168,7 +14165,7 @@ dumpTSDictionary(Archive *fout, TSDictInfo *dictinfo)
 					 dictinfo->dobj.namespace->dobj.name,
 					 NULL,
 					 dictinfo->rolname,
-					 false, "TEXT SEARCH DICTIONARY", SECTION_PRE_DATA,
+					 "TEXT SEARCH DICTIONARY", SECTION_PRE_DATA,
 					 q->data, delq->data, NULL,
 					 NULL, 0,
 					 NULL, NULL);
@@ -14229,7 +14226,7 @@ dumpTSTemplate(Archive *fout, TSTemplateInfo *tmplinfo)
 					 tmplinfo->dobj.namespace->dobj.name,
 					 NULL,
 					 "",
-					 false, "TEXT SEARCH TEMPLATE", SECTION_PRE_DATA,
+					 "TEXT SEARCH TEMPLATE", SECTION_PRE_DATA,
 					 q->data, delq->data, NULL,
 					 NULL, 0,
 					 NULL, NULL);
@@ -14349,7 +14346,7 @@ dumpTSConfig(Archive *fout, TSConfigInfo *cfginfo)
 					 cfginfo->dobj.namespace->dobj.name,
 					 NULL,
 					 cfginfo->rolname,
-					 false, "TEXT SEARCH CONFIGURATION", SECTION_PRE_DATA,
+					 "TEXT SEARCH CONFIGURATION", SECTION_PRE_DATA,
 					 q->data, delq->data, NULL,
 					 NULL, 0,
 					 NULL, NULL);
@@ -14415,7 +14412,7 @@ dumpForeignDataWrapper(Archive *fout, FdwInfo *fdwinfo)
 					 NULL,
 					 NULL,
 					 fdwinfo->rolname,
-					 false, "FOREIGN DATA WRAPPER", SECTION_PRE_DATA,
+					 "FOREIGN DATA WRAPPER", SECTION_PRE_DATA,
 					 q->data, delq->data, NULL,
 					 NULL, 0,
 					 NULL, NULL);
@@ -14506,7 +14503,7 @@ dumpForeignServer(Archive *fout, ForeignServerInfo *srvinfo)
 					 NULL,
 					 NULL,
 					 srvinfo->rolname,
-					 false, "SERVER", SECTION_PRE_DATA,
+					 "SERVER", SECTION_PRE_DATA,
 					 q->data, delq->data, NULL,
 					 NULL, 0,
 					 NULL, NULL);
@@ -14623,7 +14620,7 @@ dumpUserMappings(Archive *fout,
 					 tag->data,
 					 namespace,
 					 NULL,
-					 owner, false,
+					 owner,
 					 "USER MAPPING", SECTION_PRE_DATA,
 					 q->data, delq->data, NULL,
 					 &dumpId, 1,
@@ -14703,7 +14700,7 @@ dumpDefaultACL(Archive *fout, DefaultACLInfo *daclinfo)
 					 daclinfo->dobj.namespace ? daclinfo->dobj.namespace->dobj.name : NULL,
 					 NULL,
 					 daclinfo->defaclrole,
-					 false, "DEFAULT ACL", SECTION_POST_DATA,
+					 "DEFAULT ACL", SECTION_POST_DATA,
 					 q->data, "", NULL,
 					 NULL, 0,
 					 NULL, NULL);
@@ -14801,7 +14798,7 @@ dumpACL(Archive *fout, CatalogId objCatId, DumpId objDumpId,
 					 tag->data, nspname,
 					 NULL,
 					 owner ? owner : "",
-					 false, "ACL", SECTION_NONE,
+					 "ACL", SECTION_NONE,
 					 sql->data, "", NULL,
 					 &(objDumpId), 1,
 					 NULL, NULL);
@@ -14887,7 +14884,7 @@ dumpSecLabel(Archive *fout, const char *type, const char *name,
 		appendPQExpBuffer(tag, "%s %s", type, name);
 		ArchiveEntry(fout, nilCatalogId, createDumpId(),
 					 tag->data, namespace, NULL, owner,
-					 false, "SECURITY LABEL", SECTION_NONE,
+					 "SECURITY LABEL", SECTION_NONE,
 					 query->data, "", NULL,
 					 &(dumpId), 1,
 					 NULL, NULL);
@@ -14969,7 +14966,7 @@ dumpTableSecLabel(Archive *fout, TableInfo *tbinfo, const char *reltypename)
 					 target->data,
 					 tbinfo->dobj.namespace->dobj.name,
 					 NULL, tbinfo->rolname,
-					 false, "SECURITY LABEL", SECTION_NONE,
+					 "SECURITY LABEL", SECTION_NONE,
 					 query->data, "", NULL,
 					 &(tbinfo->dobj.dumpId), 1,
 					 NULL, NULL);
@@ -15371,6 +15368,11 @@ dumpTableSchema(Archive *fout, TableInfo *tbinfo)
 	qrelname = pg_strdup(fmtId(tbinfo->dobj.name));
 	qualrelname = pg_strdup(fmtQualifiedDumpable(tbinfo));
 
+
+	if (tbinfo->hasoids)
+		write_msg(NULL, "WARNING: WITH OIDS is not supported for (table \"%s\")\n",
+				  qrelname);
+
 	if (dopt->binary_upgrade)
 		binary_upgrade_set_type_oids_by_rel_oid(fout, q,
 												tbinfo->dobj.catId.oid);
@@ -16031,10 +16033,6 @@ dumpTableSchema(Archive *fout, TableInfo *tbinfo)
 		}
 	}
 
-	if (tbinfo->relkind == RELKIND_FOREIGN_TABLE && tbinfo->hasoids)
-		appendPQExpBuffer(q, "\nALTER TABLE ONLY %s SET WITH OIDS;\n",
-						  qualrelname);
-
 	if (tbinfo->forcerowsec)
 		appendPQExpBuffer(q, "\nALTER TABLE ONLY %s FORCE ROW LEVEL SECURITY;\n",
 						  qualrelname);
@@ -16050,7 +16048,6 @@ dumpTableSchema(Archive *fout, TableInfo *tbinfo)
 					 tbinfo->dobj.namespace->dobj.name,
 					 (tbinfo->relkind == RELKIND_VIEW) ? NULL : tbinfo->reltablespace,
 					 tbinfo->rolname,
-					 (strcmp(reltypename, "TABLE") == 0) ? tbinfo->hasoids : false,
 					 reltypename,
 					 tbinfo->postponed_def ?
 					 SECTION_POST_DATA : SECTION_PRE_DATA,
@@ -16131,7 +16128,7 @@ dumpAttrDef(Archive *fout, AttrDefInfo *adinfo)
 					 tbinfo->dobj.namespace->dobj.name,
 					 NULL,
 					 tbinfo->rolname,
-					 false, "DEFAULT", SECTION_PRE_DATA,
+					 "DEFAULT", SECTION_PRE_DATA,
 					 q->data, delq->data, NULL,
 					 NULL, 0,
 					 NULL, NULL);
@@ -16158,8 +16155,6 @@ getAttrName(int attrnum, TableInfo *tblInfo)
 	{
 		case SelfItemPointerAttributeNumber:
 			return "ctid";
-		case ObjectIdAttributeNumber:
-			return "oid";
 		case MinTransactionIdAttributeNumber:
 			return "xmin";
 		case MinCommandIdAttributeNumber:
@@ -16248,7 +16243,7 @@ dumpIndex(Archive *fout, IndxInfo *indxinfo)
 						 indxinfo->dobj.name,
 						 tbinfo->dobj.namespace->dobj.name,
 						 indxinfo->tablespace,
-						 tbinfo->rolname, false,
+						 tbinfo->rolname,
 						 "INDEX", SECTION_POST_DATA,
 						 q->data, delq->data, NULL,
 						 NULL, 0,
@@ -16293,7 +16288,7 @@ dumpIndexAttach(Archive *fout, IndexAttachInfo *attachinfo)
 					 attachinfo->dobj.namespace->dobj.name,
 					 NULL,
 					 "",
-					 false, "INDEX ATTACH", SECTION_POST_DATA,
+					 "INDEX ATTACH", SECTION_POST_DATA,
 					 q->data, "", NULL,
 					 NULL, 0,
 					 NULL, NULL);
@@ -16347,7 +16342,7 @@ dumpStatisticsExt(Archive *fout, StatsExtInfo *statsextinfo)
 					 statsextinfo->dobj.name,
 					 statsextinfo->dobj.namespace->dobj.name,
 					 NULL,
-					 statsextinfo->rolname, false,
+					 statsextinfo->rolname,
 					 "STATISTICS", SECTION_POST_DATA,
 					 q->data, delq->data, NULL,
 					 NULL, 0,
@@ -16508,7 +16503,7 @@ dumpConstraint(Archive *fout, ConstraintInfo *coninfo)
 						 tag,
 						 tbinfo->dobj.namespace->dobj.name,
 						 indxinfo->tablespace,
-						 tbinfo->rolname, false,
+						 tbinfo->rolname,
 						 "CONSTRAINT", SECTION_POST_DATA,
 						 q->data, delq->data, NULL,
 						 NULL, 0,
@@ -16548,7 +16543,7 @@ dumpConstraint(Archive *fout, ConstraintInfo *coninfo)
 						 tag,
 						 tbinfo->dobj.namespace->dobj.name,
 						 NULL,
-						 tbinfo->rolname, false,
+						 tbinfo->rolname,
 						 "FK CONSTRAINT", SECTION_POST_DATA,
 						 q->data, delq->data, NULL,
 						 NULL, 0,
@@ -16580,7 +16575,7 @@ dumpConstraint(Archive *fout, ConstraintInfo *coninfo)
 							 tag,
 							 tbinfo->dobj.namespace->dobj.name,
 							 NULL,
-							 tbinfo->rolname, false,
+							 tbinfo->rolname,
 							 "CHECK CONSTRAINT", SECTION_POST_DATA,
 							 q->data, delq->data, NULL,
 							 NULL, 0,
@@ -16613,7 +16608,7 @@ dumpConstraint(Archive *fout, ConstraintInfo *coninfo)
 							 tag,
 							 tyinfo->dobj.namespace->dobj.name,
 							 NULL,
-							 tyinfo->rolname, false,
+							 tyinfo->rolname,
 							 "CHECK CONSTRAINT", SECTION_POST_DATA,
 							 q->data, delq->data, NULL,
 							 NULL, 0,
@@ -16888,7 +16883,7 @@ dumpSequence(Archive *fout, TableInfo *tbinfo)
 					 tbinfo->dobj.namespace->dobj.name,
 					 NULL,
 					 tbinfo->rolname,
-					 false, "SEQUENCE", SECTION_PRE_DATA,
+					 "SEQUENCE", SECTION_PRE_DATA,
 					 query->data, delqry->data, NULL,
 					 NULL, 0,
 					 NULL, NULL);
@@ -16929,7 +16924,7 @@ dumpSequence(Archive *fout, TableInfo *tbinfo)
 							 tbinfo->dobj.namespace->dobj.name,
 							 NULL,
 							 tbinfo->rolname,
-							 false, "SEQUENCE OWNED BY", SECTION_PRE_DATA,
+							 "SEQUENCE OWNED BY", SECTION_PRE_DATA,
 							 query->data, "", NULL,
 							 &(tbinfo->dobj.dumpId), 1,
 							 NULL, NULL);
@@ -16997,7 +16992,7 @@ dumpSequenceData(Archive *fout, TableDataInfo *tdinfo)
 					 tbinfo->dobj.namespace->dobj.name,
 					 NULL,
 					 tbinfo->rolname,
-					 false, "SEQUENCE SET", SECTION_DATA,
+					 "SEQUENCE SET", SECTION_DATA,
 					 query->data, "", NULL,
 					 &(tbinfo->dobj.dumpId), 1,
 					 NULL, NULL);
@@ -17195,7 +17190,7 @@ dumpTrigger(Archive *fout, TriggerInfo *tginfo)
 					 tag,
 					 tbinfo->dobj.namespace->dobj.name,
 					 NULL,
-					 tbinfo->rolname, false,
+					 tbinfo->rolname,
 					 "TRIGGER", SECTION_POST_DATA,
 					 query->data, delqry->data, NULL,
 					 NULL, 0,
@@ -17282,7 +17277,7 @@ dumpEventTrigger(Archive *fout, EventTriggerInfo *evtinfo)
 	if (evtinfo->dobj.dump & DUMP_COMPONENT_DEFINITION)
 		ArchiveEntry(fout, evtinfo->dobj.catId, evtinfo->dobj.dumpId,
 					 evtinfo->dobj.name, NULL, NULL,
-					 evtinfo->evtowner, false,
+					 evtinfo->evtowner,
 					 "EVENT TRIGGER", SECTION_POST_DATA,
 					 query->data, delqry->data, NULL,
 					 NULL, 0,
@@ -17442,7 +17437,7 @@ dumpRule(Archive *fout, RuleInfo *rinfo)
 					 tag,
 					 tbinfo->dobj.namespace->dobj.name,
 					 NULL,
-					 tbinfo->rolname, false,
+					 tbinfo->rolname,
 					 "RULE", SECTION_POST_DATA,
 					 cmd->data, delcmd->data, NULL,
 					 NULL, 0,
diff --git a/src/bin/pg_dump/t/002_pg_dump.pl b/src/bin/pg_dump/t/002_pg_dump.pl
index ec751a7c23d..c026d66cecf 100644
--- a/src/bin/pg_dump/t/002_pg_dump.pl
+++ b/src/bin/pg_dump/t/002_pg_dump.pl
@@ -603,17 +603,6 @@ my %tests = (
 		},
 	},
 
-	'ALTER SEQUENCE test_third_table_col1_seq' => {
-		regexp => qr/^
-			\QALTER SEQUENCE dump_test_second_schema.test_third_table_col1_seq OWNED BY dump_test_second_schema.test_third_table.col1;\E
-			/xm,
-		like => {
-			%full_runs,
-			role             => 1,
-			section_pre_data => 1,
-		},
-	},
-
 	'ALTER TABLE ONLY test_table ADD CONSTRAINT ... PRIMARY KEY' => {
 		regexp => qr/^
 			\QALTER TABLE ONLY dump_test.test_table\E \n^\s+
@@ -818,17 +807,6 @@ my %tests = (
 		},
 	},
 
-	'ALTER TABLE test_third_table OWNER TO' => {
-		regexp =>
-		  qr/^ALTER TABLE dump_test_second_schema.test_third_table OWNER TO .*;/m,
-		like => {
-			%full_runs,
-			role             => 1,
-			section_pre_data => 1,
-		},
-		unlike => { no_owner => 1, },
-	},
-
 	'ALTER TABLE measurement OWNER TO' => {
 		regexp => qr/^ALTER TABLE dump_test.measurement OWNER TO .*;/m,
 		like =>
@@ -1247,37 +1225,6 @@ my %tests = (
 		},
 	},
 
-	'COPY test_third_table' => {
-		create_order => 12,
-		create_sql =>
-		  'INSERT INTO dump_test_second_schema.test_third_table (col1) '
-		  . 'SELECT generate_series FROM generate_series(1,9);',
-		regexp => qr/^
-			\QCOPY dump_test_second_schema.test_third_table (col1) FROM stdin;\E
-			\n(?:\d\n){9}\\\.\n
-			/xm,
-		like => {
-			%full_runs,
-			data_only    => 1,
-			role         => 1,
-			section_data => 1,
-		},
-		unlike => {
-			binary_upgrade          => 1,
-			exclude_test_table_data => 1,
-			schema_only             => 1,
-			with_oids               => 1,
-		},
-	},
-
-	'COPY test_third_table WITH OIDS' => {
-		regexp => qr/^
-			\QCOPY dump_test_second_schema.test_third_table (col1) WITH OIDS FROM stdin;\E
-			\n(?:\d+\t\d\n){9}\\\.\n
-			/xm,
-		like => { with_oids => 1, },
-	},
-
 	'COPY test_fourth_table' => {
 		create_order => 7,
 		create_sql =>
@@ -1355,13 +1302,6 @@ my %tests = (
 		like => { column_inserts => 1, },
 	},
 
-	'INSERT INTO test_third_table' => {
-		regexp => qr/^
-			(?:INSERT\ INTO\ dump_test_second_schema.test_third_table\ \(col1\)
-			   \ VALUES\ \(\d\);\n){9}/xm,
-		like => { column_inserts => 1, },
-	},
-
 	'INSERT INTO test_fourth_table' => {
 		regexp =>
 		  qr/^\QINSERT INTO dump_test.test_fourth_table DEFAULT VALUES;\E/m,
@@ -2283,34 +2223,6 @@ my %tests = (
 		unlike => { exclude_dump_test_schema => 1, },
 	},
 
-	'CREATE UNLOGGED TABLE test_third_table WITH OIDS' => {
-		create_order => 11,
-		create_sql =>
-		  'CREATE UNLOGGED TABLE dump_test_second_schema.test_third_table (
-						   col1 serial
-					   ) WITH OIDS;',
-		regexp => qr/^
-			\QSET default_with_oids = true;\E\n\n
-			\Q--\E\n
-			(\Q-- TOC entry \E[0-9]+\ \(class\ 1259\ OID\ [0-9]+\)\n)?
-			\Q-- Name: test_third_table;\E.*\n
-			\Q--\E\n\n
-			\QCREATE UNLOGGED TABLE dump_test_second_schema.test_third_table (\E
-			\n\s+\Qcol1 integer NOT NULL\E
-			\n\);\n
-			/xm,
-		like => {
-			%full_runs,
-			role             => 1,
-			section_pre_data => 1,
-		},
-		unlike => {
-
-			# FIXME figure out why/how binary upgrade drops OIDs.
-			binary_upgrade => 1,
-		},
-	},
-
 	'CREATE TABLE measurement PARTITIONED BY' => {
 		create_order => 90,
 		create_sql   => 'CREATE TABLE dump_test.measurement (
@@ -2463,38 +2375,6 @@ my %tests = (
 		unlike => { exclude_dump_test_schema => 1, },
 	},
 
-	'CREATE SEQUENCE test_third_table_col1_seq' => {
-		regexp => qr/^
-			\QCREATE SEQUENCE dump_test_second_schema.test_third_table_col1_seq\E
-			\n\s+\QAS integer\E
-			\n\s+\QSTART WITH 1\E
-			\n\s+\QINCREMENT BY 1\E
-			\n\s+\QNO MINVALUE\E
-			\n\s+\QNO MAXVALUE\E
-			\n\s+\QCACHE 1;\E
-			/xm,
-		like => {
-			%full_runs,
-			role             => 1,
-			section_pre_data => 1,
-		},
-	},
-
-	'CREATE UNIQUE INDEX test_third_table_idx ON test_third_table' => {
-		create_order => 13,
-		create_sql   => 'CREATE UNIQUE INDEX test_third_table_idx
-					   ON dump_test_second_schema.test_third_table (col1);',
-		regexp => qr/^
-			\QCREATE UNIQUE INDEX test_third_table_idx \E
-			\QON dump_test_second_schema.test_third_table USING btree (col1);\E
-			/xm,
-		like => {
-			%full_runs,
-			role              => 1,
-			section_post_data => 1,
-		},
-	},
-
 	'CREATE INDEX ON ONLY measurement' => {
 		create_order => 92,
 		create_sql =>
@@ -2692,11 +2572,6 @@ my %tests = (
 		like   => { clean => 1, },
 	},
 
-	'DROP TABLE test_third_table' => {
-		regexp => qr/^DROP TABLE dump_test_second_schema\.test_third_table;/m,
-		like   => { clean => 1, },
-	},
-
 	'DROP EXTENSION IF EXISTS plpgsql' => {
 		regexp => qr/^DROP EXTENSION IF EXISTS plpgsql;/m,
 
@@ -2736,13 +2611,6 @@ my %tests = (
 		like   => { clean_if_exists => 1, },
 	},
 
-	'DROP TABLE IF EXISTS test_third_table' => {
-		regexp => qr/^
-			\QDROP TABLE IF EXISTS dump_test_second_schema.test_third_table;\E
-			/xm,
-		like => { clean_if_exists => 1, },
-	},
-
 	'DROP ROLE regress_dump_test_role' => {
 		regexp => qr/^
 			\QDROP ROLE regress_dump_test_role;\E
@@ -2885,37 +2753,6 @@ my %tests = (
 		},
 	},
 
-	'GRANT SELECT ON TABLE test_third_table' => {
-		create_order => 19,
-		create_sql   => 'GRANT SELECT ON
-						   TABLE dump_test_second_schema.test_third_table
-						   TO regress_dump_test_role;',
-		regexp =>
-		  qr/^GRANT SELECT ON TABLE dump_test_second_schema.test_third_table TO regress_dump_test_role;/m,
-		like => {
-			%full_runs,
-			role             => 1,
-			section_pre_data => 1,
-		},
-		unlike => { no_privs => 1, },
-	},
-
-	'GRANT ALL ON SEQUENCE test_third_table_col1_seq' => {
-		create_order => 28,
-		create_sql   => 'GRANT ALL ON SEQUENCE
-						   dump_test_second_schema.test_third_table_col1_seq
-						   TO regress_dump_test_role;',
-		regexp => qr/^
-			\QGRANT ALL ON SEQUENCE dump_test_second_schema.test_third_table_col1_seq TO regress_dump_test_role;\E
-			/xm,
-		like => {
-			%full_runs,
-			role             => 1,
-			section_pre_data => 1,
-		},
-		unlike => { no_privs => 1, },
-	},
-
 	'GRANT SELECT ON TABLE measurement' => {
 		create_order => 91,
 		create_sql   => 'GRANT SELECT ON
diff --git a/src/bin/pgbench/t/001_pgbench_with_server.pl b/src/bin/pgbench/t/001_pgbench_with_server.pl
index 00819890261..f6b38b39ba9 100644
--- a/src/bin/pgbench/t/001_pgbench_with_server.pl
+++ b/src/bin/pgbench/t/001_pgbench_with_server.pl
@@ -48,28 +48,26 @@ sub pgbench
 	return;
 }
 
-# Test concurrent insertion into table with UNIQUE oid column.  DDL expects
-# GetNewOidWithIndex() to successfully avoid violating uniqueness for indexes
-# like pg_class_oid_index and pg_proc_oid_index.  This indirectly exercises
-# LWLock and spinlock concurrency.  This test makes a 5-MiB table.
+# Test concurrent insertion into table with serial column.  This
+# indirectly exercises LWLock and spinlock concurrency.  This test
+# makes a 5-MiB table.
 
 $node->safe_psql('postgres',
-	    'CREATE UNLOGGED TABLE oid_tbl () WITH OIDS; '
-	  . 'ALTER TABLE oid_tbl ADD UNIQUE (oid);');
+	    'CREATE UNLOGGED TABLE insert_tbl (id serial primary key); ');
 
 pgbench(
 	'--no-vacuum --client=5 --protocol=prepared --transactions=25',
 	0,
 	[qr{processed: 125/125}],
 	[qr{^$}],
-	'concurrency OID generation',
+	'concurrent insert generation',
 	{
-		'001_pgbench_concurrent_oid_generation' =>
-		  'INSERT INTO oid_tbl SELECT FROM generate_series(1,1000);'
+		'001_pgbench_concurrent_insert' =>
+		  'INSERT INTO insert_tbl SELECT FROM generate_series(1,1000);'
 	});
 
 # cleanup
-$node->safe_psql('postgres', 'DROP TABLE oid_tbl;');
+$node->safe_psql('postgres', 'DROP TABLE insert_tbl;');
 
 # Trigger various connection errors
 pgbench(
diff --git a/src/bin/psql/describe.c b/src/bin/psql/describe.c
index 4ca0db1d0ca..e6b93fbd244 100644
--- a/src/bin/psql/describe.c
+++ b/src/bin/psql/describe.c
@@ -1496,7 +1496,24 @@ describeOneTableDetails(const char *schemaname,
 	initPQExpBuffer(&tmpbuf);
 
 	/* Get general table info */
-	if (pset.sversion >= 90500)
+	if (pset.sversion >= 120000)
+	{
+		printfPQExpBuffer(&buf,
+						  "SELECT c.relchecks, c.relkind, c.relhasindex, c.relhasrules, "
+						  "c.relhastriggers, c.relrowsecurity, c.relforcerowsecurity, "
+						  "false AS relhasoids, %s, c.reltablespace, "
+						  "CASE WHEN c.reloftype = 0 THEN '' ELSE c.reloftype::pg_catalog.regtype::pg_catalog.text END, "
+						  "c.relpersistence, c.relreplident\n"
+						  "FROM pg_catalog.pg_class c\n "
+						  "LEFT JOIN pg_catalog.pg_class tc ON (c.reltoastrelid = tc.oid)\n"
+						  "WHERE c.oid = '%s';",
+						  (verbose ?
+						   "pg_catalog.array_to_string(c.reloptions || "
+						   "array(select 'toast.' || x from pg_catalog.unnest(tc.reloptions) x), ', ')\n"
+						   : "''"),
+						  oid);
+	}
+	else if (pset.sversion >= 90500)
 	{
 		printfPQExpBuffer(&buf,
 						  "SELECT c.relchecks, c.relkind, c.relhasindex, c.relhasrules, "
diff --git a/src/bin/psql/tab-complete.c b/src/bin/psql/tab-complete.c
index 7294824948c..9dbd5551668 100644
--- a/src/bin/psql/tab-complete.c
+++ b/src/bin/psql/tab-complete.c
@@ -1884,9 +1884,6 @@ psql_completion(const char *text, int start, int end)
 	 */
 	else if (Matches("ALTER", "TABLE", MatchAny, "SET", "TABLESPACE"))
 		COMPLETE_WITH_QUERY(Query_for_list_of_tablespaces);
-	/* If we have ALTER TABLE <sth> SET WITH provide OIDS */
-	else if (Matches("ALTER", "TABLE", MatchAny, "SET", "WITH"))
-		COMPLETE_WITH("OIDS");
 	/* If we have ALTER TABLE <sth> SET WITHOUT provide CLUSTER or OIDS */
 	else if (Matches("ALTER", "TABLE", MatchAny, "SET", "WITHOUT"))
 		COMPLETE_WITH("CLUSTER", "OIDS");
@@ -2155,7 +2152,7 @@ psql_completion(const char *text, int start, int end)
 	/* Handle COPY [BINARY] <sth> FROM|TO filename */
 	else if (Matches("COPY|\\copy", MatchAny, "FROM|TO", MatchAny) ||
 			 Matches("COPY", "BINARY", MatchAny, "FROM|TO", MatchAny))
-		COMPLETE_WITH("BINARY", "OIDS", "DELIMITER", "NULL", "CSV",
+		COMPLETE_WITH("BINARY", "DELIMITER", "NULL", "CSV",
 					  "ENCODING");
 
 	/* Handle COPY [BINARY] <sth> FROM|TO filename CSV */
diff --git a/src/include/access/heapam.h b/src/include/access/heapam.h
index 40e153f71ad..64cfdbd2f06 100644
--- a/src/include/access/heapam.h
+++ b/src/include/access/heapam.h
@@ -151,7 +151,7 @@ extern BulkInsertState GetBulkInsertState(void);
 extern void FreeBulkInsertState(BulkInsertState);
 extern void ReleaseBulkInsertStatePin(BulkInsertState bistate);
 
-extern Oid heap_insert(Relation relation, HeapTuple tup, CommandId cid,
+extern void heap_insert(Relation relation, HeapTuple tup, CommandId cid,
 			int options, BulkInsertState bistate);
 extern void heap_multi_insert(Relation relation, HeapTuple *tuples, int ntuples,
 				  CommandId cid, int options, BulkInsertState bistate);
@@ -176,7 +176,7 @@ extern bool heap_tuple_needs_freeze(HeapTupleHeader tuple, TransactionId cutoff_
 						MultiXactId cutoff_multi, Buffer buf);
 extern bool heap_tuple_needs_eventual_freeze(HeapTupleHeader tuple);
 
-extern Oid	simple_heap_insert(Relation relation, HeapTuple tup);
+extern void simple_heap_insert(Relation relation, HeapTuple tup);
 extern void simple_heap_delete(Relation relation, ItemPointer tid);
 extern void simple_heap_update(Relation relation, ItemPointer otid,
 				   HeapTuple tup);
diff --git a/src/include/access/htup_details.h b/src/include/access/htup_details.h
index 97d240fdbb0..9cb80dc400a 100644
--- a/src/include/access/htup_details.h
+++ b/src/include/access/htup_details.h
@@ -65,7 +65,7 @@
  *			fixed fields (HeapTupleHeaderData struct)
  *			nulls bitmap (if HEAP_HASNULL is set in t_infomask)
  *			alignment padding (as needed to make user data MAXALIGN'd)
- *			object ID (if HEAP_HASOID is set in t_infomask)
+ *			object ID (if HEAP_HASOID is set in t_infomask) (not anymore)
  *			user data fields
  *
  * We store five "virtual" fields Xmin, Cmin, Xmax, Cmax, and Xvac in three
@@ -188,7 +188,7 @@ struct HeapTupleHeaderData
 #define HEAP_HASNULL			0x0001	/* has null attribute(s) */
 #define HEAP_HASVARWIDTH		0x0002	/* has variable-width attribute(s) */
 #define HEAP_HASEXTERNAL		0x0004	/* has external stored attribute(s) */
-#define HEAP_HASOID				0x0008	/* has an object-id field */
+#define HEAP_HASOID_OLD			0x0008	/* has an object-id field */
 #define HEAP_XMAX_KEYSHR_LOCK	0x0010	/* xmax is a key-shared locker */
 #define HEAP_COMBOCID			0x0020	/* t_cid is a combo cid */
 #define HEAP_XMAX_EXCL_LOCK		0x0040	/* xmax is exclusive locker */
@@ -474,20 +474,6 @@ do { \
 	(tup)->t_choice.t_datum.datum_typmod = (typmod) \
 )
 
-#define HeapTupleHeaderGetOid(tup) \
-( \
-	((tup)->t_infomask & HEAP_HASOID) ? \
-		*((Oid *) ((char *)(tup) + (tup)->t_hoff - sizeof(Oid))) \
-	: \
-		InvalidOid \
-)
-
-#define HeapTupleHeaderSetOid(tup, oid) \
-do { \
-	Assert((tup)->t_infomask & HEAP_HASOID); \
-	*((Oid *) ((char *)(tup) + (tup)->t_hoff - sizeof(Oid))) = (oid); \
-} while (0)
-
 /*
  * Note that we stop considering a tuple HOT-updated as soon as it is known
  * aborted or the would-be updating transaction is known aborted.  For best
@@ -704,12 +690,6 @@ struct MinimalTupleData
 #define HeapTupleClearHeapOnly(tuple) \
 		HeapTupleHeaderClearHeapOnly((tuple)->t_data)
 
-#define HeapTupleGetOid(tuple) \
-		HeapTupleHeaderGetOid((tuple)->t_data)
-
-#define HeapTupleSetOid(tuple, oid) \
-		HeapTupleHeaderSetOid((tuple)->t_data, (oid))
-
 
 /* ----------------
  *		fastgetattr
diff --git a/src/include/access/reloptions.h b/src/include/access/reloptions.h
index 4022c14a830..50690b9c9e0 100644
--- a/src/include/access/reloptions.h
+++ b/src/include/access/reloptions.h
@@ -258,7 +258,7 @@ extern void add_string_reloption(bits32 kinds, const char *name, const char *des
 
 extern Datum transformRelOptions(Datum oldOptions, List *defList,
 					const char *namspace, char *validnsps[],
-					bool ignoreOids, bool isReset);
+					bool acceptOidsOff, bool isReset);
 extern List *untransformRelOptions(Datum options);
 extern bytea *extractRelOptions(HeapTuple tuple, TupleDesc tupdesc,
 				  amoptions_function amoptions);
diff --git a/src/include/access/sysattr.h b/src/include/access/sysattr.h
index c6f244011ab..e3df369d962 100644
--- a/src/include/access/sysattr.h
+++ b/src/include/access/sysattr.h
@@ -19,12 +19,12 @@
  * Attribute numbers for the system-defined attributes
  */
 #define SelfItemPointerAttributeNumber			(-1)
-#define ObjectIdAttributeNumber					(-2)
-#define MinTransactionIdAttributeNumber			(-3)
-#define MinCommandIdAttributeNumber				(-4)
-#define MaxTransactionIdAttributeNumber			(-5)
-#define MaxCommandIdAttributeNumber				(-6)
-#define TableOidAttributeNumber					(-7)
-#define FirstLowInvalidHeapAttributeNumber		(-8)
+/* #define ObjectIdAttributeNumber					(-2) */
+#define MinTransactionIdAttributeNumber			(-2)
+#define MinCommandIdAttributeNumber				(-3)
+#define MaxTransactionIdAttributeNumber			(-4)
+#define MaxCommandIdAttributeNumber				(-5)
+#define TableOidAttributeNumber					(-6)
+#define FirstLowInvalidHeapAttributeNumber		(-7)
 
 #endif							/* SYSATTR_H */
diff --git a/src/include/access/tupdesc.h b/src/include/access/tupdesc.h
index 708160f645e..06af39ff2a3 100644
--- a/src/include/access/tupdesc.h
+++ b/src/include/access/tupdesc.h
@@ -55,7 +55,7 @@ typedef struct tupleConstr
  * structure is designed to let the constraints be omitted efficiently.
  *
  * Note that only user attributes, not system attributes, are mentioned in
- * TupleDesc; with the exception that tdhasoid indicates if OID is present.
+ * TupleDesc.
  *
  * If the tupdesc is known to correspond to a named rowtype (such as a table's
  * rowtype) then tdtypeid identifies that type and tdtypmod is -1.  Otherwise
@@ -82,7 +82,6 @@ typedef struct tupleDesc
 	int			natts;			/* number of attributes in the tuple */
 	Oid			tdtypeid;		/* composite type ID for tuple type */
 	int32		tdtypmod;		/* typmod for tuple type */
-	bool		tdhasoid;		/* tuple has oid attribute in its header */
 	int			tdrefcount;		/* reference count, or -1 if not counting */
 	TupleConstr *constr;		/* constraints, or NULL if none */
 	/* attrs[N] is the description of Attribute Number N+1 */
@@ -92,10 +91,9 @@ typedef struct tupleDesc
 /* Accessor for the i'th attribute of tupdesc. */
 #define TupleDescAttr(tupdesc, i) (&(tupdesc)->attrs[(i)])
 
-extern TupleDesc CreateTemplateTupleDesc(int natts, bool hasoid);
+extern TupleDesc CreateTemplateTupleDesc(int natts);
 
-extern TupleDesc CreateTupleDesc(int natts, bool hasoid,
-				Form_pg_attribute *attrs);
+extern TupleDesc CreateTupleDesc(int natts, Form_pg_attribute *attrs);
 
 extern TupleDesc CreateTupleDescCopy(TupleDesc tupdesc);
 
diff --git a/src/include/catalog/catalog.h b/src/include/catalog/catalog.h
index 197e77f7f4f..2f351700b40 100644
--- a/src/include/catalog/catalog.h
+++ b/src/include/catalog/catalog.h
@@ -33,7 +33,6 @@ extern bool IsReservedName(const char *name);
 
 extern bool IsSharedRelation(Oid relationId);
 
-extern Oid	GetNewOid(Relation relation);
 extern Oid GetNewOidWithIndex(Relation relation, Oid indexId,
 				   AttrNumber oidcolumn);
 extern Oid GetNewRelFileNode(Oid reltablespace, Relation pg_class,
diff --git a/src/include/catalog/genbki.h b/src/include/catalog/genbki.h
index 8a4277b7c87..c6a7feac24a 100644
--- a/src/include/catalog/genbki.h
+++ b/src/include/catalog/genbki.h
@@ -25,7 +25,6 @@
 /* Options that may appear after CATALOG (on the same line) */
 #define BKI_BOOTSTRAP
 #define BKI_SHARED_RELATION
-#define BKI_WITHOUT_OIDS
 #define BKI_ROWTYPE_OID(oid,oidmacro)
 #define BKI_SCHEMA_MACRO
 
diff --git a/src/include/catalog/heap.h b/src/include/catalog/heap.h
index 39f04b06eef..56a341a6222 100644
--- a/src/include/catalog/heap.h
+++ b/src/include/catalog/heap.h
@@ -65,8 +65,6 @@ extern Oid heap_create_with_catalog(const char *relname,
 						 char relpersistence,
 						 bool shared_relation,
 						 bool mapped_relation,
-						 bool oidislocal,
-						 int oidinhcount,
 						 OnCommitAction oncommit,
 						 Datum reloptions,
 						 bool use_user_acl,
@@ -127,11 +125,9 @@ extern void RemoveAttrDefault(Oid relid, AttrNumber attnum,
 extern void RemoveAttrDefaultById(Oid attrdefId);
 extern void RemoveStatistics(Oid relid, AttrNumber attnum);
 
-extern const FormData_pg_attribute *SystemAttributeDefinition(AttrNumber attno,
-						  bool relhasoids);
+extern const FormData_pg_attribute *SystemAttributeDefinition(AttrNumber attno);
 
-extern const FormData_pg_attribute *SystemAttributeByName(const char *attname,
-					  bool relhasoids);
+extern const FormData_pg_attribute *SystemAttributeByName(const char *attname);
 
 extern void CheckAttributeNamesTypes(TupleDesc tupdesc, char relkind,
 						 bool allow_system_table_mods);
diff --git a/src/include/catalog/indexing.h b/src/include/catalog/indexing.h
index 254fbef1f78..a672fd8ce3f 100644
--- a/src/include/catalog/indexing.h
+++ b/src/include/catalog/indexing.h
@@ -30,8 +30,8 @@ typedef struct ResultRelInfo *CatalogIndexState;
  */
 extern CatalogIndexState CatalogOpenIndexes(Relation heapRel);
 extern void CatalogCloseIndexes(CatalogIndexState indstate);
-extern Oid	CatalogTupleInsert(Relation heapRel, HeapTuple tup);
-extern Oid CatalogTupleInsertWithInfo(Relation heapRel, HeapTuple tup,
+extern void	CatalogTupleInsert(Relation heapRel, HeapTuple tup);
+extern void CatalogTupleInsertWithInfo(Relation heapRel, HeapTuple tup,
 						   CatalogIndexState indstate);
 extern void CatalogTupleUpdate(Relation heapRel, ItemPointer otid,
 				   HeapTuple tup);
diff --git a/src/include/catalog/objectaddress.h b/src/include/catalog/objectaddress.h
index 6a9b1eec73f..3f95733eb1a 100644
--- a/src/include/catalog/objectaddress.h
+++ b/src/include/catalog/objectaddress.h
@@ -58,6 +58,7 @@ extern bool is_objectclass_supported(Oid class_id);
 extern Oid	get_object_oid_index(Oid class_id);
 extern int	get_object_catcache_oid(Oid class_id);
 extern int	get_object_catcache_name(Oid class_id);
+extern AttrNumber get_object_attnum_oid(Oid class_id);
 extern AttrNumber get_object_attnum_name(Oid class_id);
 extern AttrNumber get_object_attnum_namespace(Oid class_id);
 extern AttrNumber get_object_attnum_owner(Oid class_id);
@@ -66,7 +67,7 @@ extern ObjectType get_object_type(Oid class_id, Oid object_id);
 extern bool get_object_namensp_unique(Oid class_id);
 
 extern HeapTuple get_catalog_object_by_oid(Relation catalog,
-						  Oid objectId);
+						  AttrNumber oidcol, Oid objectId);
 
 extern char *getObjectDescription(const ObjectAddress *object);
 extern char *getObjectDescriptionOids(Oid classid, Oid objid);
diff --git a/src/include/catalog/pg_aggregate.h b/src/include/catalog/pg_aggregate.h
index bcae93f5e14..c88ba91401f 100644
--- a/src/include/catalog/pg_aggregate.h
+++ b/src/include/catalog/pg_aggregate.h
@@ -29,7 +29,7 @@
  *		cpp turns this into typedef struct FormData_pg_aggregate
  * ----------------------------------------------------------------
  */
-CATALOG(pg_aggregate,2600,AggregateRelationId) BKI_WITHOUT_OIDS
+CATALOG(pg_aggregate,2600,AggregateRelationId)
 {
 	/* pg_proc OID of the aggregate itself */
 	regproc		aggfnoid BKI_LOOKUP(pg_proc);
diff --git a/src/include/catalog/pg_am.h b/src/include/catalog/pg_am.h
index 26cb2349875..57d65f830fc 100644
--- a/src/include/catalog/pg_am.h
+++ b/src/include/catalog/pg_am.h
@@ -28,6 +28,8 @@
  */
 CATALOG(pg_am,2601,AccessMethodRelationId)
 {
+	Oid			oid;			/* oid */
+
 	/* access method name */
 	NameData	amname;
 
diff --git a/src/include/catalog/pg_amop.h b/src/include/catalog/pg_amop.h
index 8e6f7408872..f110fdd7413 100644
--- a/src/include/catalog/pg_amop.h
+++ b/src/include/catalog/pg_amop.h
@@ -53,6 +53,8 @@
  */
 CATALOG(pg_amop,2602,AccessMethodOperatorRelationId)
 {
+	Oid			oid;			/* oid */
+
 	/* the index opfamily this entry is for */
 	Oid			amopfamily BKI_LOOKUP(pg_opfamily);
 
diff --git a/src/include/catalog/pg_amproc.h b/src/include/catalog/pg_amproc.h
index c34c3faa8ff..c5f79ba5939 100644
--- a/src/include/catalog/pg_amproc.h
+++ b/src/include/catalog/pg_amproc.h
@@ -42,6 +42,8 @@
  */
 CATALOG(pg_amproc,2603,AccessMethodProcedureRelationId)
 {
+	Oid			oid;			/* oid */
+
 	/* the index opfamily this entry is for */
 	Oid			amprocfamily BKI_LOOKUP(pg_opfamily);
 
diff --git a/src/include/catalog/pg_attrdef.h b/src/include/catalog/pg_attrdef.h
index a9a2351efdd..e320a69c90d 100644
--- a/src/include/catalog/pg_attrdef.h
+++ b/src/include/catalog/pg_attrdef.h
@@ -28,6 +28,8 @@
  */
 CATALOG(pg_attrdef,2604,AttrDefaultRelationId)
 {
+	Oid			oid;			/* oid XXX: Why? */
+
 	Oid			adrelid;		/* OID of table containing attribute */
 	int16		adnum;			/* attnum of attribute */
 
diff --git a/src/include/catalog/pg_attribute.h b/src/include/catalog/pg_attribute.h
index dc36753ede0..1bac59bf26e 100644
--- a/src/include/catalog/pg_attribute.h
+++ b/src/include/catalog/pg_attribute.h
@@ -34,7 +34,7 @@
  *		You may need to change catalog/genbki.pl as well.
  * ----------------
  */
-CATALOG(pg_attribute,1249,AttributeRelationId) BKI_BOOTSTRAP BKI_WITHOUT_OIDS BKI_ROWTYPE_OID(75,AttributeRelation_Rowtype_Id) BKI_SCHEMA_MACRO
+CATALOG(pg_attribute,1249,AttributeRelationId) BKI_BOOTSTRAP BKI_ROWTYPE_OID(75,AttributeRelation_Rowtype_Id) BKI_SCHEMA_MACRO
 {
 	Oid			attrelid;		/* OID of relation containing this attribute */
 	NameData	attname;		/* name of attribute */
diff --git a/src/include/catalog/pg_auth_members.h b/src/include/catalog/pg_auth_members.h
index 277ea89c6f2..6d93038f6cd 100644
--- a/src/include/catalog/pg_auth_members.h
+++ b/src/include/catalog/pg_auth_members.h
@@ -27,7 +27,7 @@
  *		typedef struct FormData_pg_auth_members
  * ----------------
  */
-CATALOG(pg_auth_members,1261,AuthMemRelationId) BKI_SHARED_RELATION BKI_WITHOUT_OIDS BKI_ROWTYPE_OID(2843,AuthMemRelation_Rowtype_Id) BKI_SCHEMA_MACRO
+CATALOG(pg_auth_members,1261,AuthMemRelationId) BKI_SHARED_RELATION BKI_ROWTYPE_OID(2843,AuthMemRelation_Rowtype_Id) BKI_SCHEMA_MACRO
 {
 	Oid			roleid;			/* ID of a role */
 	Oid			member;			/* ID of a member of that role */
diff --git a/src/include/catalog/pg_authid.h b/src/include/catalog/pg_authid.h
index ba482f1cb91..ee0c8da6120 100644
--- a/src/include/catalog/pg_authid.h
+++ b/src/include/catalog/pg_authid.h
@@ -30,6 +30,7 @@
  */
 CATALOG(pg_authid,1260,AuthIdRelationId) BKI_SHARED_RELATION BKI_ROWTYPE_OID(2842,AuthIdRelation_Rowtype_Id) BKI_SCHEMA_MACRO
 {
+	Oid			oid;			/* oid */
 	NameData	rolname;		/* name of role */
 	bool		rolsuper;		/* read this field via superuser() only! */
 	bool		rolinherit;		/* inherit privileges from other roles? */
diff --git a/src/include/catalog/pg_cast.h b/src/include/catalog/pg_cast.h
index 7f4a25b2dad..dd207bf318d 100644
--- a/src/include/catalog/pg_cast.h
+++ b/src/include/catalog/pg_cast.h
@@ -30,6 +30,8 @@
  */
 CATALOG(pg_cast,2605,CastRelationId)
 {
+	Oid			oid;			/* oid */
+
 	/* source datatype for cast */
 	Oid			castsource BKI_LOOKUP(pg_type);
 
diff --git a/src/include/catalog/pg_class.dat b/src/include/catalog/pg_class.dat
index 9fffdef3790..848264d9846 100644
--- a/src/include/catalog/pg_class.dat
+++ b/src/include/catalog/pg_class.dat
@@ -25,8 +25,8 @@
   reloftype => '0', relowner => 'PGUID', relam => '0', relfilenode => '0',
   reltablespace => '0', relpages => '0', reltuples => '0', relallvisible => '0',
   reltoastrelid => '0', relhasindex => 'f', relisshared => 'f',
-  relpersistence => 'p', relkind => 'r', relnatts => '30', relchecks => '0',
-  relhasoids => 't', relhasrules => 'f', relhastriggers => 'f',
+  relpersistence => 'p', relkind => 'r', relnatts => '31', relchecks => '0',
+  relhasrules => 'f', relhastriggers => 'f',
   relhassubclass => 'f', relrowsecurity => 'f', relforcerowsecurity => 'f',
   relispopulated => 't', relreplident => 'n', relispartition => 'f',
   relrewrite => '0', relfrozenxid => '3', relminmxid => '1', relacl => '_null_',
@@ -37,7 +37,7 @@
   reltablespace => '0', relpages => '0', reltuples => '0', relallvisible => '0',
   reltoastrelid => '0', relhasindex => 'f', relisshared => 'f',
   relpersistence => 'p', relkind => 'r', relnatts => '24', relchecks => '0',
-  relhasoids => 'f', relhasrules => 'f', relhastriggers => 'f',
+  relhasrules => 'f', relhastriggers => 'f',
   relhassubclass => 'f', relrowsecurity => 'f', relforcerowsecurity => 'f',
   relispopulated => 't', relreplident => 'n', relispartition => 'f',
   relrewrite => '0', relfrozenxid => '3', relminmxid => '1', relacl => '_null_',
@@ -47,8 +47,8 @@
   reloftype => '0', relowner => 'PGUID', relam => '0', relfilenode => '0',
   reltablespace => '0', relpages => '0', reltuples => '0', relallvisible => '0',
   reltoastrelid => '0', relhasindex => 'f', relisshared => 'f',
-  relpersistence => 'p', relkind => 'r', relnatts => '28', relchecks => '0',
-  relhasoids => 't', relhasrules => 'f', relhastriggers => 'f',
+  relpersistence => 'p', relkind => 'r', relnatts => '29', relchecks => '0',
+  relhasrules => 'f', relhastriggers => 'f',
   relhassubclass => 'f', relrowsecurity => 'f', relforcerowsecurity => 'f',
   relispopulated => 't', relreplident => 'n', relispartition => 'f',
   relrewrite => '0', relfrozenxid => '3', relminmxid => '1', relacl => '_null_',
@@ -59,7 +59,7 @@
   reltablespace => '0', relpages => '0', reltuples => '0', relallvisible => '0',
   reltoastrelid => '0', relhasindex => 'f', relisshared => 'f',
   relpersistence => 'p', relkind => 'r', relnatts => '33', relchecks => '0',
-  relhasoids => 't', relhasrules => 'f', relhastriggers => 'f',
+  relhasrules => 'f', relhastriggers => 'f',
   relhassubclass => 'f', relrowsecurity => 'f', relforcerowsecurity => 'f',
   relispopulated => 't', relreplident => 'n', relispartition => 'f',
   relrewrite => '0', relfrozenxid => '3', relminmxid => '1', relacl => '_null_',
diff --git a/src/include/catalog/pg_class.h b/src/include/catalog/pg_class.h
index 788d7a31dc0..84e63c6d06a 100644
--- a/src/include/catalog/pg_class.h
+++ b/src/include/catalog/pg_class.h
@@ -28,6 +28,7 @@
  */
 CATALOG(pg_class,1259,RelationRelationId) BKI_BOOTSTRAP BKI_ROWTYPE_OID(83,RelationRelation_Rowtype_Id) BKI_SCHEMA_MACRO
 {
+	Oid			oid;			/* oid */
 	NameData	relname;		/* class name */
 	Oid			relnamespace;	/* OID of namespace containing this class */
 	Oid			reltype;		/* OID of entry in pg_type for table's
@@ -57,7 +58,6 @@ CATALOG(pg_class,1259,RelationRelationId) BKI_BOOTSTRAP BKI_ROWTYPE_OID(83,Relat
 	 * contain entries with negative attnums for system attributes.
 	 */
 	int16		relchecks;		/* # of CHECK constraints for class */
-	bool		relhasoids;		/* T if we generate OIDs for rows of rel */
 	bool		relhasrules;	/* has (or has had) any rules */
 	bool		relhastriggers; /* has (or has had) any TRIGGERs */
 	bool		relhassubclass; /* has (or has had) child tables or indexes */
diff --git a/src/include/catalog/pg_collation.h b/src/include/catalog/pg_collation.h
index 7e0f4461c61..51f9b2a2ca4 100644
--- a/src/include/catalog/pg_collation.h
+++ b/src/include/catalog/pg_collation.h
@@ -28,6 +28,7 @@
  */
 CATALOG(pg_collation,3456,CollationRelationId)
 {
+	Oid			oid;			/* oid */
 	NameData	collname;		/* collation name */
 	Oid			collnamespace;	/* OID of namespace containing collation */
 	Oid			collowner;		/* owner of collation */
diff --git a/src/include/catalog/pg_constraint.h b/src/include/catalog/pg_constraint.h
index 630cabe0b8f..0e4007389b6 100644
--- a/src/include/catalog/pg_constraint.h
+++ b/src/include/catalog/pg_constraint.h
@@ -31,6 +31,8 @@
  */
 CATALOG(pg_constraint,2606,ConstraintRelationId)
 {
+	Oid			oid;			/* oid */
+
 	/*
 	 * conname + connamespace is deliberately not unique; we allow, for
 	 * example, the same name to be used for constraints of different
diff --git a/src/include/catalog/pg_conversion.h b/src/include/catalog/pg_conversion.h
index 37515f64c2f..6e8f054306f 100644
--- a/src/include/catalog/pg_conversion.h
+++ b/src/include/catalog/pg_conversion.h
@@ -39,6 +39,7 @@
  */
 CATALOG(pg_conversion,2607,ConversionRelationId)
 {
+	Oid			oid;			/* oid */
 	NameData	conname;
 	Oid			connamespace;
 	Oid			conowner;
diff --git a/src/include/catalog/pg_database.h b/src/include/catalog/pg_database.h
index ac027b79199..f6aebad8ef0 100644
--- a/src/include/catalog/pg_database.h
+++ b/src/include/catalog/pg_database.h
@@ -28,6 +28,7 @@
  */
 CATALOG(pg_database,1262,DatabaseRelationId) BKI_SHARED_RELATION BKI_ROWTYPE_OID(1248,DatabaseRelation_Rowtype_Id) BKI_SCHEMA_MACRO
 {
+	Oid			oid;			/* oid */
 	NameData	datname;		/* database name */
 	Oid			datdba;			/* owner of database */
 	int32		encoding;		/* character encoding */
diff --git a/src/include/catalog/pg_db_role_setting.h b/src/include/catalog/pg_db_role_setting.h
index eff801c3ce5..96440342f28 100644
--- a/src/include/catalog/pg_db_role_setting.h
+++ b/src/include/catalog/pg_db_role_setting.h
@@ -31,7 +31,7 @@
  *		typedef struct FormData_pg_db_role_setting
  * ----------------
  */
-CATALOG(pg_db_role_setting,2964,DbRoleSettingRelationId) BKI_SHARED_RELATION BKI_WITHOUT_OIDS
+CATALOG(pg_db_role_setting,2964,DbRoleSettingRelationId) BKI_SHARED_RELATION
 {
 	Oid			setdatabase;	/* database */
 	Oid			setrole;		/* role */
diff --git a/src/include/catalog/pg_default_acl.h b/src/include/catalog/pg_default_acl.h
index aee49fdb6da..f4f8f99b3e3 100644
--- a/src/include/catalog/pg_default_acl.h
+++ b/src/include/catalog/pg_default_acl.h
@@ -29,6 +29,7 @@
  */
 CATALOG(pg_default_acl,826,DefaultAclRelationId)
 {
+	Oid			oid;			/* oid */
 	Oid			defaclrole;		/* OID of role owning this ACL */
 	Oid			defaclnamespace;	/* OID of namespace, or 0 for all */
 	char		defaclobjtype;	/* see DEFACLOBJ_xxx constants below */
diff --git a/src/include/catalog/pg_depend.h b/src/include/catalog/pg_depend.h
index 482b8bd2516..8f2d95210fa 100644
--- a/src/include/catalog/pg_depend.h
+++ b/src/include/catalog/pg_depend.h
@@ -38,7 +38,7 @@
  *		typedef struct FormData_pg_depend
  * ----------------
  */
-CATALOG(pg_depend,2608,DependRelationId) BKI_WITHOUT_OIDS
+CATALOG(pg_depend,2608,DependRelationId)
 {
 	/*
 	 * Identification of the dependent (referencing) object.
diff --git a/src/include/catalog/pg_description.h b/src/include/catalog/pg_description.h
index 74302bd451d..1f21a83ba2a 100644
--- a/src/include/catalog/pg_description.h
+++ b/src/include/catalog/pg_description.h
@@ -45,7 +45,7 @@
  *		typedef struct FormData_pg_description
  * ----------------
  */
-CATALOG(pg_description,2609,DescriptionRelationId) BKI_WITHOUT_OIDS
+CATALOG(pg_description,2609,DescriptionRelationId)
 {
 	Oid			objoid;			/* OID of object itself */
 	Oid			classoid;		/* OID of table containing object */
diff --git a/src/include/catalog/pg_enum.h b/src/include/catalog/pg_enum.h
index 474877749b2..78e289378cf 100644
--- a/src/include/catalog/pg_enum.h
+++ b/src/include/catalog/pg_enum.h
@@ -30,6 +30,7 @@
  */
 CATALOG(pg_enum,3501,EnumRelationId)
 {
+	Oid			oid;			/* oid */
 	Oid			enumtypid;		/* OID of owning enum type */
 	float4		enumsortorder;	/* sort position of this enum value */
 	NameData	enumlabel;		/* text representation of enum value */
diff --git a/src/include/catalog/pg_event_trigger.h b/src/include/catalog/pg_event_trigger.h
index 9af00fd68ff..16ee3098edd 100644
--- a/src/include/catalog/pg_event_trigger.h
+++ b/src/include/catalog/pg_event_trigger.h
@@ -28,6 +28,7 @@
  */
 CATALOG(pg_event_trigger,3466,EventTriggerRelationId)
 {
+	Oid			oid;			/* oid */
 	NameData	evtname;		/* trigger's name */
 	NameData	evtevent;		/* trigger's event */
 	Oid			evtowner;		/* trigger's owner */
diff --git a/src/include/catalog/pg_extension.h b/src/include/catalog/pg_extension.h
index c698ddd699a..e3773f67251 100644
--- a/src/include/catalog/pg_extension.h
+++ b/src/include/catalog/pg_extension.h
@@ -28,6 +28,7 @@
  */
 CATALOG(pg_extension,3079,ExtensionRelationId)
 {
+	Oid			oid;			/* oid */
 	NameData	extname;		/* extension name */
 	Oid			extowner;		/* extension owner */
 	Oid			extnamespace;	/* namespace of contained objects */
diff --git a/src/include/catalog/pg_foreign_data_wrapper.h b/src/include/catalog/pg_foreign_data_wrapper.h
index 3e6191e3e25..e70823c4393 100644
--- a/src/include/catalog/pg_foreign_data_wrapper.h
+++ b/src/include/catalog/pg_foreign_data_wrapper.h
@@ -28,6 +28,7 @@
  */
 CATALOG(pg_foreign_data_wrapper,2328,ForeignDataWrapperRelationId)
 {
+	Oid			oid;			/* oid */
 	NameData	fdwname;		/* foreign-data wrapper name */
 	Oid			fdwowner;		/* FDW owner */
 	Oid			fdwhandler;		/* handler function, or 0 if none */
diff --git a/src/include/catalog/pg_foreign_server.h b/src/include/catalog/pg_foreign_server.h
index 3f7cc0c0469..49649bbd683 100644
--- a/src/include/catalog/pg_foreign_server.h
+++ b/src/include/catalog/pg_foreign_server.h
@@ -27,6 +27,7 @@
  */
 CATALOG(pg_foreign_server,1417,ForeignServerRelationId)
 {
+	Oid			oid;			/* oid */
 	NameData	srvname;		/* foreign server name */
 	Oid			srvowner;		/* server owner */
 	Oid			srvfdw;			/* server FDW */
diff --git a/src/include/catalog/pg_foreign_table.h b/src/include/catalog/pg_foreign_table.h
index 6e8b4195201..d21dec3766e 100644
--- a/src/include/catalog/pg_foreign_table.h
+++ b/src/include/catalog/pg_foreign_table.h
@@ -25,7 +25,7 @@
  *		typedef struct FormData_pg_foreign_table
  * ----------------
  */
-CATALOG(pg_foreign_table,3118,ForeignTableRelationId) BKI_WITHOUT_OIDS
+CATALOG(pg_foreign_table,3118,ForeignTableRelationId)
 {
 	Oid			ftrelid;		/* OID of foreign table */
 	Oid			ftserver;		/* OID of foreign server */
diff --git a/src/include/catalog/pg_index.h b/src/include/catalog/pg_index.h
index 5f72a5571f2..ebe8955bf38 100644
--- a/src/include/catalog/pg_index.h
+++ b/src/include/catalog/pg_index.h
@@ -26,7 +26,7 @@
  *		typedef struct FormData_pg_index.
  * ----------------
  */
-CATALOG(pg_index,2610,IndexRelationId) BKI_WITHOUT_OIDS BKI_SCHEMA_MACRO
+CATALOG(pg_index,2610,IndexRelationId) BKI_SCHEMA_MACRO
 {
 	Oid			indexrelid;		/* OID of the index */
 	Oid			indrelid;		/* OID of the relation it indexes */
diff --git a/src/include/catalog/pg_inherits.h b/src/include/catalog/pg_inherits.h
index 2a98e02c6ac..07dfb63068b 100644
--- a/src/include/catalog/pg_inherits.h
+++ b/src/include/catalog/pg_inherits.h
@@ -29,7 +29,7 @@
  *		typedef struct FormData_pg_inherits
  * ----------------
  */
-CATALOG(pg_inherits,2611,InheritsRelationId) BKI_WITHOUT_OIDS
+CATALOG(pg_inherits,2611,InheritsRelationId)
 {
 	Oid			inhrelid;
 	Oid			inhparent;
diff --git a/src/include/catalog/pg_init_privs.h b/src/include/catalog/pg_init_privs.h
index 39de09cb9da..8a6da5ecf2d 100644
--- a/src/include/catalog/pg_init_privs.h
+++ b/src/include/catalog/pg_init_privs.h
@@ -43,7 +43,7 @@
  *		typedef struct FormData_pg_init_privs
  * ----------------
  */
-CATALOG(pg_init_privs,3394,InitPrivsRelationId) BKI_WITHOUT_OIDS
+CATALOG(pg_init_privs,3394,InitPrivsRelationId)
 {
 	Oid			objoid;			/* OID of object itself */
 	Oid			classoid;		/* OID of table containing object */
diff --git a/src/include/catalog/pg_language.h b/src/include/catalog/pg_language.h
index 359701b4522..03654d8d074 100644
--- a/src/include/catalog/pg_language.h
+++ b/src/include/catalog/pg_language.h
@@ -28,6 +28,8 @@
  */
 CATALOG(pg_language,2612,LanguageRelationId)
 {
+	Oid			oid;			/* oid */
+
 	/* Language name */
 	NameData	lanname;
 
diff --git a/src/include/catalog/pg_largeobject.h b/src/include/catalog/pg_largeobject.h
index a8aa42e049a..1497c97cee5 100644
--- a/src/include/catalog/pg_largeobject.h
+++ b/src/include/catalog/pg_largeobject.h
@@ -26,7 +26,7 @@
  *		typedef struct FormData_pg_largeobject
  * ----------------
  */
-CATALOG(pg_largeobject,2613,LargeObjectRelationId) BKI_WITHOUT_OIDS
+CATALOG(pg_largeobject,2613,LargeObjectRelationId)
 {
 	Oid			loid;			/* Identifier of large object */
 	int32		pageno;			/* Page number (starting from 0) */
diff --git a/src/include/catalog/pg_largeobject_metadata.h b/src/include/catalog/pg_largeobject_metadata.h
index c8560dc2afb..ef6427b8cc3 100644
--- a/src/include/catalog/pg_largeobject_metadata.h
+++ b/src/include/catalog/pg_largeobject_metadata.h
@@ -29,6 +29,8 @@
  */
 CATALOG(pg_largeobject_metadata,2995,LargeObjectMetadataRelationId)
 {
+	Oid			oid;			/* oid */
+
 	Oid			lomowner;		/* OID of the largeobject owner */
 
 #ifdef CATALOG_VARLEN			/* variable-length fields start here */
diff --git a/src/include/catalog/pg_namespace.h b/src/include/catalog/pg_namespace.h
index 0923e066b46..a7e101202f0 100644
--- a/src/include/catalog/pg_namespace.h
+++ b/src/include/catalog/pg_namespace.h
@@ -33,6 +33,8 @@
  */
 CATALOG(pg_namespace,2615,NamespaceRelationId)
 {
+	Oid			oid;			/* oid */
+
 	NameData	nspname;
 	Oid			nspowner;
 
diff --git a/src/include/catalog/pg_opclass.h b/src/include/catalog/pg_opclass.h
index b980327fc03..5d229505077 100644
--- a/src/include/catalog/pg_opclass.h
+++ b/src/include/catalog/pg_opclass.h
@@ -48,6 +48,8 @@
  */
 CATALOG(pg_opclass,2616,OperatorClassRelationId)
 {
+	Oid			oid;			/* oid */
+
 	/* index access method opclass is for */
 	Oid			opcmethod BKI_LOOKUP(pg_am);
 
diff --git a/src/include/catalog/pg_operator.h b/src/include/catalog/pg_operator.h
index 3212b21418b..ca3ae6e191f 100644
--- a/src/include/catalog/pg_operator.h
+++ b/src/include/catalog/pg_operator.h
@@ -31,6 +31,8 @@
  */
 CATALOG(pg_operator,2617,OperatorRelationId)
 {
+	Oid			oid;			/* oid */
+
 	/* name of operator */
 	NameData	oprname;
 
diff --git a/src/include/catalog/pg_opfamily.h b/src/include/catalog/pg_opfamily.h
index 99dedbc42d1..ce37ede57bf 100644
--- a/src/include/catalog/pg_opfamily.h
+++ b/src/include/catalog/pg_opfamily.h
@@ -28,6 +28,8 @@
  */
 CATALOG(pg_opfamily,2753,OperatorFamilyRelationId)
 {
+	Oid			oid;			/* oid */
+
 	/* index access method opfamily is for */
 	Oid			opfmethod BKI_LOOKUP(pg_am);
 
diff --git a/src/include/catalog/pg_partitioned_table.h b/src/include/catalog/pg_partitioned_table.h
index 78bc5c81fbc..39095fa69b1 100644
--- a/src/include/catalog/pg_partitioned_table.h
+++ b/src/include/catalog/pg_partitioned_table.h
@@ -27,7 +27,7 @@
  *		typedef struct FormData_pg_partitioned_table
  * ----------------
  */
-CATALOG(pg_partitioned_table,3350,PartitionedRelationId) BKI_WITHOUT_OIDS
+CATALOG(pg_partitioned_table,3350,PartitionedRelationId)
 {
 	Oid			partrelid;		/* partitioned table oid */
 	char		partstrat;		/* partitioning strategy */
diff --git a/src/include/catalog/pg_pltemplate.h b/src/include/catalog/pg_pltemplate.h
index ae06b752125..fba9efac90e 100644
--- a/src/include/catalog/pg_pltemplate.h
+++ b/src/include/catalog/pg_pltemplate.h
@@ -26,7 +26,7 @@
  *		typedef struct FormData_pg_pltemplate
  * ----------------
  */
-CATALOG(pg_pltemplate,1136,PLTemplateRelationId) BKI_SHARED_RELATION BKI_WITHOUT_OIDS
+CATALOG(pg_pltemplate,1136,PLTemplateRelationId) BKI_SHARED_RELATION
 {
 	NameData	tmplname;		/* name of PL */
 	bool		tmpltrusted;	/* PL is trusted? */
diff --git a/src/include/catalog/pg_policy.h b/src/include/catalog/pg_policy.h
index 0dd9c50e536..d7eb1bd7596 100644
--- a/src/include/catalog/pg_policy.h
+++ b/src/include/catalog/pg_policy.h
@@ -28,6 +28,7 @@
  */
 CATALOG(pg_policy,3256,PolicyRelationId)
 {
+	Oid			oid;			/* oid */
 	NameData	polname;		/* Policy name. */
 	Oid			polrelid;		/* Oid of the relation with policy. */
 	char		polcmd;			/* One of ACL_*_CHR, or '*' for all */
diff --git a/src/include/catalog/pg_proc.dat b/src/include/catalog/pg_proc.dat
index 9264a2e9872..034a41eb556 100644
--- a/src/include/catalog/pg_proc.dat
+++ b/src/include/catalog/pg_proc.dat
@@ -3122,6 +3122,11 @@
   prorettype => 'int8', proargtypes => 'regclass',
   prosrc => 'pg_sequence_last_value' },
 
+{ oid => '275', descr => 'return the next oid for a system table',
+  proname => 'pg_nextoid', provolatile => 'v', proparallel => 'u',
+  prorettype => 'oid', proargtypes => 'regclass name regclass',
+  prosrc => 'pg_nextoid' },
+
 { oid => '1579', descr => 'I/O',
   proname => 'varbit_in', prorettype => 'varbit',
   proargtypes => 'cstring oid int4', prosrc => 'varbit_in' },
diff --git a/src/include/catalog/pg_proc.h b/src/include/catalog/pg_proc.h
index a34b2596fa0..b25dec6c311 100644
--- a/src/include/catalog/pg_proc.h
+++ b/src/include/catalog/pg_proc.h
@@ -30,6 +30,8 @@
  */
 CATALOG(pg_proc,1255,ProcedureRelationId) BKI_BOOTSTRAP BKI_ROWTYPE_OID(81,ProcedureRelation_Rowtype_Id) BKI_SCHEMA_MACRO
 {
+	Oid			oid;			/* oid */
+
 	/* procedure name */
 	NameData	proname;
 
diff --git a/src/include/catalog/pg_publication.h b/src/include/catalog/pg_publication.h
index a5d5570f76e..062b5afa0b5 100644
--- a/src/include/catalog/pg_publication.h
+++ b/src/include/catalog/pg_publication.h
@@ -29,6 +29,8 @@
  */
 CATALOG(pg_publication,6104,PublicationRelationId)
 {
+	Oid			oid;			/* oid */
+
 	NameData	pubname;		/* name of the publication */
 
 	Oid			pubowner;		/* publication owner */
diff --git a/src/include/catalog/pg_publication_rel.h b/src/include/catalog/pg_publication_rel.h
index d97b0fe9bd3..dbb4f3d9747 100644
--- a/src/include/catalog/pg_publication_rel.h
+++ b/src/include/catalog/pg_publication_rel.h
@@ -28,6 +28,7 @@
  */
 CATALOG(pg_publication_rel,6106,PublicationRelRelationId)
 {
+	Oid			oid;			/* oid: XXX: Needed? */
 	Oid			prpubid;		/* Oid of the publication */
 	Oid			prrelid;		/* Oid of the relation */
 } FormData_pg_publication_rel;
diff --git a/src/include/catalog/pg_range.h b/src/include/catalog/pg_range.h
index ca2b28b4936..32a7b2d1ae3 100644
--- a/src/include/catalog/pg_range.h
+++ b/src/include/catalog/pg_range.h
@@ -26,7 +26,7 @@
  *		typedef struct FormData_pg_range
  * ----------------
  */
-CATALOG(pg_range,3541,RangeRelationId) BKI_WITHOUT_OIDS
+CATALOG(pg_range,3541,RangeRelationId)
 {
 	/* OID of owning range type */
 	Oid			rngtypid BKI_LOOKUP(pg_type);
diff --git a/src/include/catalog/pg_replication_origin.h b/src/include/catalog/pg_replication_origin.h
index 82ff7a7c692..dd5a2e29648 100644
--- a/src/include/catalog/pg_replication_origin.h
+++ b/src/include/catalog/pg_replication_origin.h
@@ -28,7 +28,7 @@
  *		typedef struct FormData_pg_replication_origin
  * ----------------
  */
-CATALOG(pg_replication_origin,6000,ReplicationOriginRelationId) BKI_SHARED_RELATION BKI_WITHOUT_OIDS
+CATALOG(pg_replication_origin,6000,ReplicationOriginRelationId) BKI_SHARED_RELATION
 {
 	/*
 	 * Locally known id that get included into WAL.
diff --git a/src/include/catalog/pg_rewrite.h b/src/include/catalog/pg_rewrite.h
index 0e50b879265..9b2b06dfa4d 100644
--- a/src/include/catalog/pg_rewrite.h
+++ b/src/include/catalog/pg_rewrite.h
@@ -31,6 +31,7 @@
  */
 CATALOG(pg_rewrite,2618,RewriteRelationId)
 {
+	Oid			oid;			/* oid */
 	NameData	rulename;
 	Oid			ev_class;
 	char		ev_type;
diff --git a/src/include/catalog/pg_seclabel.h b/src/include/catalog/pg_seclabel.h
index 6889369b5de..6bef8353b64 100644
--- a/src/include/catalog/pg_seclabel.h
+++ b/src/include/catalog/pg_seclabel.h
@@ -25,7 +25,7 @@
  *		typedef struct FormData_pg_seclabel
  * ----------------
  */
-CATALOG(pg_seclabel,3596,SecLabelRelationId) BKI_WITHOUT_OIDS
+CATALOG(pg_seclabel,3596,SecLabelRelationId)
 {
 	Oid			objoid;			/* OID of the object itself */
 	Oid			classoid;		/* OID of table containing the object */
diff --git a/src/include/catalog/pg_sequence.h b/src/include/catalog/pg_sequence.h
index beea215c81e..abd1a9d0437 100644
--- a/src/include/catalog/pg_sequence.h
+++ b/src/include/catalog/pg_sequence.h
@@ -20,7 +20,7 @@
 #include "catalog/genbki.h"
 #include "catalog/pg_sequence_d.h"
 
-CATALOG(pg_sequence,2224,SequenceRelationId) BKI_WITHOUT_OIDS
+CATALOG(pg_sequence,2224,SequenceRelationId)
 {
 	Oid			seqrelid;
 	Oid			seqtypid;
diff --git a/src/include/catalog/pg_shdepend.h b/src/include/catalog/pg_shdepend.h
index 01e1eb760c7..3d560f4295f 100644
--- a/src/include/catalog/pg_shdepend.h
+++ b/src/include/catalog/pg_shdepend.h
@@ -34,7 +34,7 @@
  *		typedef struct FormData_pg_shdepend
  * ----------------
  */
-CATALOG(pg_shdepend,1214,SharedDependRelationId) BKI_SHARED_RELATION BKI_WITHOUT_OIDS
+CATALOG(pg_shdepend,1214,SharedDependRelationId) BKI_SHARED_RELATION
 {
 	/*
 	 * Identification of the dependent (referencing) object.
diff --git a/src/include/catalog/pg_shdescription.h b/src/include/catalog/pg_shdescription.h
index 53cade15488..47a6729f003 100644
--- a/src/include/catalog/pg_shdescription.h
+++ b/src/include/catalog/pg_shdescription.h
@@ -38,7 +38,7 @@
  *		typedef struct FormData_pg_shdescription
  * ----------------
  */
-CATALOG(pg_shdescription,2396,SharedDescriptionRelationId) BKI_SHARED_RELATION BKI_WITHOUT_OIDS
+CATALOG(pg_shdescription,2396,SharedDescriptionRelationId) BKI_SHARED_RELATION
 {
 	Oid			objoid;			/* OID of object itself */
 	Oid			classoid;		/* OID of table containing object */
diff --git a/src/include/catalog/pg_shseclabel.h b/src/include/catalog/pg_shseclabel.h
index 2630f965fd3..2a66ca36025 100644
--- a/src/include/catalog/pg_shseclabel.h
+++ b/src/include/catalog/pg_shseclabel.h
@@ -25,7 +25,7 @@
  *		typedef struct FormData_pg_shseclabel
  * ----------------
  */
-CATALOG(pg_shseclabel,3592,SharedSecLabelRelationId) BKI_SHARED_RELATION BKI_ROWTYPE_OID(4066,SharedSecLabelRelation_Rowtype_Id) BKI_WITHOUT_OIDS BKI_SCHEMA_MACRO
+CATALOG(pg_shseclabel,3592,SharedSecLabelRelationId) BKI_SHARED_RELATION BKI_ROWTYPE_OID(4066,SharedSecLabelRelation_Rowtype_Id) BKI_SCHEMA_MACRO
 {
 	Oid			objoid;			/* OID of the shared object itself */
 	Oid			classoid;		/* OID of table containing the shared object */
diff --git a/src/include/catalog/pg_statistic.h b/src/include/catalog/pg_statistic.h
index 141e260de94..49223aab4fc 100644
--- a/src/include/catalog/pg_statistic.h
+++ b/src/include/catalog/pg_statistic.h
@@ -26,7 +26,7 @@
  *		typedef struct FormData_pg_statistic
  * ----------------
  */
-CATALOG(pg_statistic,2619,StatisticRelationId) BKI_WITHOUT_OIDS
+CATALOG(pg_statistic,2619,StatisticRelationId)
 {
 	/* These fields form the unique key for the entry: */
 	Oid			starelid;		/* relation containing attribute */
diff --git a/src/include/catalog/pg_statistic_ext.h b/src/include/catalog/pg_statistic_ext.h
index 443798ae523..51ebd5d969f 100644
--- a/src/include/catalog/pg_statistic_ext.h
+++ b/src/include/catalog/pg_statistic_ext.h
@@ -28,6 +28,8 @@
  */
 CATALOG(pg_statistic_ext,3381,StatisticExtRelationId)
 {
+	Oid			oid;			/* oid: XXX: Why? */
+
 	Oid			stxrelid;		/* relation containing attributes */
 
 	/* These two fields form the unique key for the entry: */
diff --git a/src/include/catalog/pg_subscription.h b/src/include/catalog/pg_subscription.h
index e4dc771cf53..4298c3cbf29 100644
--- a/src/include/catalog/pg_subscription.h
+++ b/src/include/catalog/pg_subscription.h
@@ -38,6 +38,8 @@
  */
 CATALOG(pg_subscription,6100,SubscriptionRelationId) BKI_SHARED_RELATION BKI_ROWTYPE_OID(6101,SubscriptionRelation_Rowtype_Id) BKI_SCHEMA_MACRO
 {
+	Oid			oid;			/* oid */
+
 	Oid			subdbid;		/* Database the subscription is in. */
 	NameData	subname;		/* Name of the subscription */
 
diff --git a/src/include/catalog/pg_subscription_rel.h b/src/include/catalog/pg_subscription_rel.h
index 556cb94841d..efd7901032e 100644
--- a/src/include/catalog/pg_subscription_rel.h
+++ b/src/include/catalog/pg_subscription_rel.h
@@ -29,7 +29,7 @@
  *		typedef struct FormData_pg_subscription_rel
  * ----------------
  */
-CATALOG(pg_subscription_rel,6102,SubscriptionRelRelationId) BKI_WITHOUT_OIDS
+CATALOG(pg_subscription_rel,6102,SubscriptionRelRelationId)
 {
 	Oid			srsubid;		/* Oid of subscription */
 	Oid			srrelid;		/* Oid of relation */
@@ -67,9 +67,9 @@ typedef struct SubscriptionRelState
 	char		state;
 } SubscriptionRelState;
 
-extern Oid AddSubscriptionRelState(Oid subid, Oid relid, char state,
+extern void AddSubscriptionRelState(Oid subid, Oid relid, char state,
 						XLogRecPtr sublsn);
-extern Oid UpdateSubscriptionRelState(Oid subid, Oid relid, char state,
+extern void UpdateSubscriptionRelState(Oid subid, Oid relid, char state,
 						   XLogRecPtr sublsn);
 extern char GetSubscriptionRelState(Oid subid, Oid relid,
 						XLogRecPtr *sublsn, bool missing_ok);
diff --git a/src/include/catalog/pg_tablespace.h b/src/include/catalog/pg_tablespace.h
index 4010f1b5a73..80caefd77aa 100644
--- a/src/include/catalog/pg_tablespace.h
+++ b/src/include/catalog/pg_tablespace.h
@@ -28,6 +28,7 @@
  */
 CATALOG(pg_tablespace,1213,TableSpaceRelationId) BKI_SHARED_RELATION
 {
+	Oid			oid;			/* oid */
 	NameData	spcname;		/* tablespace name */
 	Oid			spcowner;		/* owner of tablespace */
 
diff --git a/src/include/catalog/pg_transform.h b/src/include/catalog/pg_transform.h
index f46ff0a90e0..e92f0bccd1c 100644
--- a/src/include/catalog/pg_transform.h
+++ b/src/include/catalog/pg_transform.h
@@ -28,6 +28,7 @@
  */
 CATALOG(pg_transform,3576,TransformRelationId)
 {
+	Oid			oid;			/* oid */
 	Oid			trftype;
 	Oid			trflang;
 	regproc		trffromsql;
diff --git a/src/include/catalog/pg_trigger.h b/src/include/catalog/pg_trigger.h
index 951d7d86e75..c3a685304b0 100644
--- a/src/include/catalog/pg_trigger.h
+++ b/src/include/catalog/pg_trigger.h
@@ -33,6 +33,7 @@
  */
 CATALOG(pg_trigger,2620,TriggerRelationId)
 {
+	Oid			oid;			/* oid */
 	Oid			tgrelid;		/* relation trigger is attached to */
 	NameData	tgname;			/* trigger's name */
 	Oid			tgfoid;			/* OID of function to be called */
diff --git a/src/include/catalog/pg_ts_config.h b/src/include/catalog/pg_ts_config.h
index ce93c2b7ffb..d15db9b4b91 100644
--- a/src/include/catalog/pg_ts_config.h
+++ b/src/include/catalog/pg_ts_config.h
@@ -29,6 +29,7 @@
  */
 CATALOG(pg_ts_config,3602,TSConfigRelationId)
 {
+	Oid			oid;			/* oid */
 	NameData	cfgname;		/* name of configuration */
 	Oid			cfgnamespace;	/* name space */
 	Oid			cfgowner;		/* owner */
diff --git a/src/include/catalog/pg_ts_config_map.h b/src/include/catalog/pg_ts_config_map.h
index 58563233733..37d81e5597e 100644
--- a/src/include/catalog/pg_ts_config_map.h
+++ b/src/include/catalog/pg_ts_config_map.h
@@ -27,7 +27,7 @@
  *		typedef struct FormData_pg_ts_config_map
  * ----------------
  */
-CATALOG(pg_ts_config_map,3603,TSConfigMapRelationId) BKI_WITHOUT_OIDS
+CATALOG(pg_ts_config_map,3603,TSConfigMapRelationId)
 {
 	Oid			mapcfg;			/* OID of configuration owning this entry */
 	int32		maptokentype;	/* token type from parser */
diff --git a/src/include/catalog/pg_ts_dict.h b/src/include/catalog/pg_ts_dict.h
index cd5f150fe8e..5c4182abac1 100644
--- a/src/include/catalog/pg_ts_dict.h
+++ b/src/include/catalog/pg_ts_dict.h
@@ -28,6 +28,7 @@
  */
 CATALOG(pg_ts_dict,3600,TSDictionaryRelationId)
 {
+	Oid			oid;			/* oid */
 	NameData	dictname;		/* dictionary name */
 	Oid			dictnamespace;	/* name space */
 	Oid			dictowner;		/* owner */
diff --git a/src/include/catalog/pg_ts_parser.h b/src/include/catalog/pg_ts_parser.h
index 34585eac00c..b46a91525e3 100644
--- a/src/include/catalog/pg_ts_parser.h
+++ b/src/include/catalog/pg_ts_parser.h
@@ -28,6 +28,8 @@
  */
 CATALOG(pg_ts_parser,3601,TSParserRelationId)
 {
+	Oid			oid;			/* oid */
+
 	/* parser's name */
 	NameData	prsname;
 
diff --git a/src/include/catalog/pg_ts_template.h b/src/include/catalog/pg_ts_template.h
index 50be08eca56..d970ebf659d 100644
--- a/src/include/catalog/pg_ts_template.h
+++ b/src/include/catalog/pg_ts_template.h
@@ -28,6 +28,8 @@
  */
 CATALOG(pg_ts_template,3764,TSTemplateRelationId)
 {
+	Oid			oid;			/* oid */
+
 	/* template name */
 	NameData	tmplname;
 
diff --git a/src/include/catalog/pg_type.h b/src/include/catalog/pg_type.h
index 87c9b673cf4..05185dd809d 100644
--- a/src/include/catalog/pg_type.h
+++ b/src/include/catalog/pg_type.h
@@ -36,6 +36,8 @@
  */
 CATALOG(pg_type,1247,TypeRelationId) BKI_BOOTSTRAP BKI_ROWTYPE_OID(71,TypeRelation_Rowtype_Id) BKI_SCHEMA_MACRO
 {
+	Oid			oid;			/* oid */
+
 	/* type name */
 	NameData	typname;
 
diff --git a/src/include/catalog/pg_user_mapping.h b/src/include/catalog/pg_user_mapping.h
index e4e2ff36dcf..985ad9b94cd 100644
--- a/src/include/catalog/pg_user_mapping.h
+++ b/src/include/catalog/pg_user_mapping.h
@@ -27,6 +27,8 @@
  */
 CATALOG(pg_user_mapping,1418,UserMappingRelationId)
 {
+	Oid			oid;			/* oid */
+
 	Oid			umuser;			/* Id of the user, InvalidOid if PUBLIC is
 								 * wanted */
 	Oid			umserver;		/* server of this mapping */
diff --git a/src/include/commands/copy.h b/src/include/commands/copy.h
index f393e7e73d7..b5cadce3efa 100644
--- a/src/include/commands/copy.h
+++ b/src/include/commands/copy.h
@@ -32,7 +32,7 @@ extern CopyState BeginCopyFrom(ParseState *pstate, Relation rel, const char *fil
 			  bool is_program, copy_data_source_cb data_source_cb, List *attnamelist, List *options);
 extern void EndCopyFrom(CopyState cstate);
 extern bool NextCopyFrom(CopyState cstate, ExprContext *econtext,
-			 Datum *values, bool *nulls, Oid *tupleOid);
+			 Datum *values, bool *nulls);
 extern bool NextCopyFromRawFields(CopyState cstate,
 					  char ***fields, int *nfields);
 extern void CopyFromErrorCallback(void *arg);
diff --git a/src/include/commands/event_trigger.h b/src/include/commands/event_trigger.h
index 0e1959462eb..5a2fc6c8d71 100644
--- a/src/include/commands/event_trigger.h
+++ b/src/include/commands/event_trigger.h
@@ -31,7 +31,6 @@ typedef struct EventTriggerData
 #define AT_REWRITE_ALTER_PERSISTENCE	0x01
 #define AT_REWRITE_DEFAULT_VAL			0x02
 #define AT_REWRITE_COLUMN_REWRITE		0x04
-#define AT_REWRITE_ALTER_OID			0x08
 
 /*
  * EventTriggerData is the node type that is passed as fmgr "context" info
diff --git a/src/include/executor/executor.h b/src/include/executor/executor.h
index 84412657845..1dc37979c03 100644
--- a/src/include/executor/executor.h
+++ b/src/include/executor/executor.h
@@ -50,18 +50,13 @@
  * AfterTriggerBeginQuery/AfterTriggerEndQuery.  This does not necessarily
  * mean that the plan can't queue any AFTER triggers; just that the caller
  * is responsible for there being a trigger context for them to be queued in.
- *
- * WITH/WITHOUT_OIDS tell the executor to emit tuples with or without space
- * for OIDs, respectively.  These are currently used only for CREATE TABLE AS.
- * If neither is set, the plan may or may not produce tuples including OIDs.
  */
 #define EXEC_FLAG_EXPLAIN_ONLY	0x0001	/* EXPLAIN, no ANALYZE */
 #define EXEC_FLAG_REWIND		0x0002	/* need efficient rescan */
 #define EXEC_FLAG_BACKWARD		0x0004	/* need backward scan */
 #define EXEC_FLAG_MARK			0x0008	/* need mark/restore */
 #define EXEC_FLAG_SKIP_TRIGGERS 0x0010	/* skip AfterTrigger calls */
-#define EXEC_FLAG_WITH_OIDS		0x0020	/* force OIDs in returned tuples */
-#define EXEC_FLAG_WITHOUT_OIDS	0x0040	/* force no OIDs in returned tuples */
+/* space, XXX: renumber? */
 #define EXEC_FLAG_WITH_NO_DATA	0x0080	/* rel scannability doesn't matter */
 
 
@@ -140,7 +135,7 @@ extern TupleHashEntry FindTupleHashEntry(TupleHashTable hashtable,
 /*
  * prototypes from functions in execJunk.c
  */
-extern JunkFilter *ExecInitJunkFilter(List *targetList, bool hasoid,
+extern JunkFilter *ExecInitJunkFilter(List *targetList,
 				   TupleTableSlot *slot);
 extern JunkFilter *ExecInitJunkFilterConversion(List *targetList,
 							 TupleDesc cleanTupType,
@@ -178,7 +173,6 @@ extern void InitResultRelInfo(ResultRelInfo *resultRelInfo,
 				  int instrument_options);
 extern ResultRelInfo *ExecGetTriggerResultRel(EState *estate, Oid relid);
 extern void ExecCleanUpTriggerState(EState *estate);
-extern bool ExecContextForcesOids(PlanState *planstate, bool *hasoids);
 extern void ExecConstraints(ResultRelInfo *resultRelInfo,
 				TupleTableSlot *slot, EState *estate);
 extern bool ExecPartitionCheck(ResultRelInfo *resultRelInfo,
@@ -437,8 +431,8 @@ extern TupleTableSlot *ExecInitExtraTupleSlot(EState *estate,
 					   TupleDesc tupleDesc);
 extern TupleTableSlot *ExecInitNullTupleSlot(EState *estate,
 					  TupleDesc tupType);
-extern TupleDesc ExecTypeFromTL(List *targetList, bool hasoid);
-extern TupleDesc ExecCleanTypeFromTL(List *targetList, bool hasoid);
+extern TupleDesc ExecTypeFromTL(List *targetList);
+extern TupleDesc ExecCleanTypeFromTL(List *targetList);
 extern TupleDesc ExecTypeFromExprList(List *exprList);
 extern void ExecTypeSetColNames(TupleDesc typeInfo, List *namesList);
 extern void UpdateChangedParamSet(PlanState *node, Bitmapset *newchg);
diff --git a/src/include/executor/spi.h b/src/include/executor/spi.h
index b16440cf004..d2616968ac4 100644
--- a/src/include/executor/spi.h
+++ b/src/include/executor/spi.h
@@ -75,7 +75,6 @@ typedef struct _SPI_plan *SPIPlanPtr;
 #define SPI_restore_connection()	((void) 0)
 
 extern PGDLLIMPORT uint64 SPI_processed;
-extern PGDLLIMPORT Oid SPI_lastoid;
 extern PGDLLIMPORT SPITupleTable *SPI_tuptable;
 extern PGDLLIMPORT int SPI_result;
 
diff --git a/src/include/executor/spi_priv.h b/src/include/executor/spi_priv.h
index 0da3a41050e..d86d7e0a831 100644
--- a/src/include/executor/spi_priv.h
+++ b/src/include/executor/spi_priv.h
@@ -23,7 +23,6 @@ typedef struct
 {
 	/* current results */
 	uint64		processed;		/* by Executor */
-	Oid			lastoid;
 	SPITupleTable *tuptable;	/* tuptable currently being built */
 
 	/* subtransaction in which current Executor call was started */
@@ -45,7 +44,6 @@ typedef struct
 
 	/* saved values of API global variables for previous nesting level */
 	uint64		outer_processed;
-	Oid			outer_lastoid;
 	SPITupleTable *outer_tuptable;
 	int			outer_result;
 } _SPI_connection;
diff --git a/src/include/nodes/execnodes.h b/src/include/nodes/execnodes.h
index 18544566f70..8356edbb062 100644
--- a/src/include/nodes/execnodes.h
+++ b/src/include/nodes/execnodes.h
@@ -540,7 +540,6 @@ typedef struct EState
 	List	   *es_tupleTable;	/* List of TupleTableSlots */
 
 	uint64		es_processed;	/* # of tuples processed */
-	Oid			es_lastoid;		/* last oid processed (by INSERT) */
 
 	int			es_top_eflags;	/* eflags passed to ExecutorStart */
 	int			es_instrument;	/* OR of InstrumentOption flags */
diff --git a/src/include/nodes/parsenodes.h b/src/include/nodes/parsenodes.h
index 9da8bf2f887..63f61e7ccdf 100644
--- a/src/include/nodes/parsenodes.h
+++ b/src/include/nodes/parsenodes.h
@@ -1769,9 +1769,6 @@ typedef enum AlterTableType
 	AT_DropCluster,				/* SET WITHOUT CLUSTER */
 	AT_SetLogged,				/* SET LOGGED */
 	AT_SetUnLogged,				/* SET UNLOGGED */
-	AT_AddOids,					/* SET WITH OIDS */
-	AT_AddOidsRecurse,			/* internal to commands/tablecmds.c */
-	AT_DropOids,				/* SET WITHOUT OIDS */
 	AT_SetTableSpace,			/* SET TABLESPACE */
 	AT_SetRelOptions,			/* SET (...) -- AM specific parameters */
 	AT_ResetRelOptions,			/* RESET (...) -- AM specific parameters */
diff --git a/src/include/parser/parse_clause.h b/src/include/parser/parse_clause.h
index 2c0e0928628..f37f55302fb 100644
--- a/src/include/parser/parse_clause.h
+++ b/src/include/parser/parse_clause.h
@@ -19,7 +19,6 @@
 extern void transformFromClause(ParseState *pstate, List *frmList);
 extern int setTargetTable(ParseState *pstate, RangeVar *relation,
 			   bool inh, bool alsoSource, AclMode requiredPerms);
-extern bool interpretOidsOption(List *defList, bool allowOids);
 
 extern Node *transformWhereClause(ParseState *pstate, Node *clause,
 					 ParseExprKind exprKind, const char *constructName);
diff --git a/src/include/utils/guc.h b/src/include/utils/guc.h
index f462eabe594..df2e556b021 100644
--- a/src/include/utils/guc.h
+++ b/src/include/utils/guc.h
@@ -244,7 +244,6 @@ extern bool log_statement_stats;
 extern bool log_btree_build_stats;
 
 extern PGDLLIMPORT bool check_function_bodies;
-extern bool default_with_oids;
 extern bool session_auth_is_superuser;
 
 extern int	log_min_error_statement;
diff --git a/src/include/utils/rel.h b/src/include/utils/rel.h
index 84469f57151..ab4d2192dce 100644
--- a/src/include/utils/rel.h
+++ b/src/include/utils/rel.h
@@ -103,7 +103,9 @@ typedef struct RelationData
 
 	/* data managed by RelationGetIndexList: */
 	List	   *rd_indexlist;	/* list of OIDs of indexes on relation */
+#if 0
 	Oid			rd_oidindex;	/* OID of unique index on OID, if any */
+#endif
 	Oid			rd_pkindex;		/* OID of primary key, if any */
 	Oid			rd_replidindex; /* OID of replica identity index, if any */
 
diff --git a/src/include/utils/relcache.h b/src/include/utils/relcache.h
index dbbf41b0c16..23082656b8d 100644
--- a/src/include/utils/relcache.h
+++ b/src/include/utils/relcache.h
@@ -45,7 +45,6 @@ extern void RelationClose(Relation relation);
 extern List *RelationGetFKeyList(Relation relation);
 extern List *RelationGetIndexList(Relation relation);
 extern List *RelationGetStatExtList(Relation relation);
-extern Oid	RelationGetOidIndex(Relation relation);
 extern Oid	RelationGetPrimaryKeyIndex(Relation relation);
 extern Oid	RelationGetReplicaIndex(Relation relation);
 extern List *RelationGetIndexExpressions(Relation relation);
diff --git a/src/interfaces/ecpg/preproc/ecpg.addons b/src/interfaces/ecpg/preproc/ecpg.addons
index ca3efadc481..0167ee4620a 100644
--- a/src/interfaces/ecpg/preproc/ecpg.addons
+++ b/src/interfaces/ecpg/preproc/ecpg.addons
@@ -192,7 +192,7 @@ ECPG: where_or_current_clauseWHERECURRENT_POFcursor_name block
 		char *cursor_marker = $4[0] == ':' ? mm_strdup("$0") : $4;
 		$$ = cat_str(2,mm_strdup("where current of"), cursor_marker);
 	}
-ECPG: CopyStmtCOPYopt_binaryqualified_nameopt_column_listopt_oidscopy_fromopt_programcopy_file_namecopy_delimiteropt_withcopy_options addon
+ECPG: CopyStmtCOPYopt_binaryqualified_nameopt_column_listcopy_fromopt_programcopy_file_namecopy_delimiteropt_withcopy_options addon
 			if (strcmp($6, "from") == 0 &&
 			   (strcmp($7, "stdin") == 0 || strcmp($7, "stdout") == 0))
 				mmerror(PARSE_ERROR, ET_WARNING, "COPY FROM STDIN is not implemented");
diff --git a/src/pl/plperl/plperl.c b/src/pl/plperl/plperl.c
index 4cfc5062531..fe54b209035 100644
--- a/src/pl/plperl/plperl.c
+++ b/src/pl/plperl/plperl.c
@@ -2825,7 +2825,7 @@ compile_plperl_function(Oid fn_oid, bool is_trigger, bool is_event_trigger)
 			elog(ERROR, "cache lookup failed for language %u",
 				 procStruct->prolang);
 		langStruct = (Form_pg_language) GETSTRUCT(langTup);
-		prodesc->lang_oid = HeapTupleGetOid(langTup);
+		prodesc->lang_oid = langStruct->oid;
 		prodesc->lanpltrusted = langStruct->lanpltrusted;
 		ReleaseSysCache(langTup);
 
diff --git a/src/pl/plpgsql/src/pl_comp.c b/src/pl/plpgsql/src/pl_comp.c
index 59460d26434..8bacc74cce1 100644
--- a/src/pl/plpgsql/src/pl_comp.c
+++ b/src/pl/plpgsql/src/pl_comp.c
@@ -1898,7 +1898,7 @@ build_row_from_vars(PLpgSQL_variable **vars, int numvars)
 	row->dtype = PLPGSQL_DTYPE_ROW;
 	row->refname = "(unnamed row)";
 	row->lineno = -1;
-	row->rowtupdesc = CreateTemplateTupleDesc(numvars, false);
+	row->rowtupdesc = CreateTemplateTupleDesc(numvars);
 	row->nfields = numvars;
 	row->fieldnames = palloc(numvars * sizeof(char *));
 	row->varnos = palloc(numvars * sizeof(int));
@@ -2031,7 +2031,7 @@ build_datatype(HeapTuple typeTup, int32 typmod, Oid collation)
 	typ = (PLpgSQL_type *) palloc(sizeof(PLpgSQL_type));
 
 	typ->typname = pstrdup(NameStr(typeStruct->typname));
-	typ->typoid = HeapTupleGetOid(typeTup);
+	typ->typoid = typeStruct->oid;
 	switch (typeStruct->typtype)
 	{
 		case TYPTYPE_BASE:
diff --git a/src/pl/plpgsql/src/pl_exec.c b/src/pl/plpgsql/src/pl_exec.c
index d5694d3d08e..39ea9258209 100644
--- a/src/pl/plpgsql/src/pl_exec.c
+++ b/src/pl/plpgsql/src/pl_exec.c
@@ -2332,12 +2332,6 @@ exec_stmt_getdiag(PLpgSQL_execstate *estate, PLpgSQL_stmt_getdiag *stmt)
 								  false, INT8OID, -1);
 				break;
 
-			case PLPGSQL_GETDIAG_RESULT_OID:
-				exec_assign_value(estate, var,
-								  ObjectIdGetDatum(estate->eval_lastoid),
-								  false, OIDOID, -1);
-				break;
-
 			case PLPGSQL_GETDIAG_ERROR_CONTEXT:
 				exec_assign_c_string(estate, var,
 									 estate->cur_error->context);
@@ -3936,7 +3930,6 @@ plpgsql_estate_setup(PLpgSQL_execstate *estate,
 
 	estate->eval_tuptable = NULL;
 	estate->eval_processed = 0;
-	estate->eval_lastoid = InvalidOid;
 	estate->eval_econtext = NULL;
 
 	estate->err_stmt = NULL;
@@ -4180,7 +4173,6 @@ exec_stmt_execsql(PLpgSQL_execstate *estate,
 
 	/* All variants should save result info for GET DIAGNOSTICS */
 	estate->eval_processed = SPI_processed;
-	estate->eval_lastoid = SPI_lastoid;
 
 	/* Process INTO if present */
 	if (stmt->into)
@@ -4371,7 +4363,6 @@ exec_stmt_dynexecute(PLpgSQL_execstate *estate,
 
 	/* Save result info for GET DIAGNOSTICS */
 	estate->eval_processed = SPI_processed;
-	estate->eval_lastoid = SPI_lastoid;
 
 	/* Process INTO if present */
 	if (stmt->into)
@@ -5841,7 +5832,6 @@ exec_run_select(PLpgSQL_execstate *estate,
 	Assert(estate->eval_tuptable == NULL);
 	estate->eval_tuptable = SPI_tuptable;
 	estate->eval_processed = SPI_processed;
-	estate->eval_lastoid = SPI_lastoid;
 
 	return rc;
 }
diff --git a/src/pl/plpgsql/src/pl_funcs.c b/src/pl/plpgsql/src/pl_funcs.c
index b93f8662233..4266e6cee75 100644
--- a/src/pl/plpgsql/src/pl_funcs.c
+++ b/src/pl/plpgsql/src/pl_funcs.c
@@ -307,8 +307,6 @@ plpgsql_getdiag_kindname(PLpgSQL_getdiag_kind kind)
 	{
 		case PLPGSQL_GETDIAG_ROW_COUNT:
 			return "ROW_COUNT";
-		case PLPGSQL_GETDIAG_RESULT_OID:
-			return "RESULT_OID";
 		case PLPGSQL_GETDIAG_CONTEXT:
 			return "PG_CONTEXT";
 		case PLPGSQL_GETDIAG_ERROR_CONTEXT:
diff --git a/src/pl/plpgsql/src/pl_gram.y b/src/pl/plpgsql/src/pl_gram.y
index 68e399f9cff..a979a5109d3 100644
--- a/src/pl/plpgsql/src/pl_gram.y
+++ b/src/pl/plpgsql/src/pl_gram.y
@@ -327,7 +327,6 @@ static	void			check_raise_parameters(PLpgSQL_stmt_raise *stmt);
 %token <keyword>	K_RAISE
 %token <keyword>	K_RELATIVE
 %token <keyword>	K_RESET
-%token <keyword>	K_RESULT_OID
 %token <keyword>	K_RETURN
 %token <keyword>	K_RETURNED_SQLSTATE
 %token <keyword>	K_REVERSE
@@ -977,7 +976,6 @@ stmt_getdiag	: K_GET getdiag_area_opt K_DIAGNOSTICS getdiag_list ';'
 							{
 								/* these fields are disallowed in stacked case */
 								case PLPGSQL_GETDIAG_ROW_COUNT:
-								case PLPGSQL_GETDIAG_RESULT_OID:
 									if (new->is_stacked)
 										ereport(ERROR,
 												(errcode(ERRCODE_SYNTAX_ERROR),
@@ -1060,9 +1058,6 @@ getdiag_item :
 						if (tok_is_keyword(tok, &yylval,
 										   K_ROW_COUNT, "row_count"))
 							$$ = PLPGSQL_GETDIAG_ROW_COUNT;
-						else if (tok_is_keyword(tok, &yylval,
-												K_RESULT_OID, "result_oid"))
-							$$ = PLPGSQL_GETDIAG_RESULT_OID;
 						else if (tok_is_keyword(tok, &yylval,
 												K_PG_CONTEXT, "pg_context"))
 							$$ = PLPGSQL_GETDIAG_CONTEXT;
@@ -2518,7 +2513,6 @@ unreserved_keyword	:
 				| K_RAISE
 				| K_RELATIVE
 				| K_RESET
-				| K_RESULT_OID
 				| K_RETURN
 				| K_RETURNED_SQLSTATE
 				| K_REVERSE
diff --git a/src/pl/plpgsql/src/pl_scanner.c b/src/pl/plpgsql/src/pl_scanner.c
index fc4ba3054a0..ab18946847d 100644
--- a/src/pl/plpgsql/src/pl_scanner.c
+++ b/src/pl/plpgsql/src/pl_scanner.c
@@ -158,7 +158,6 @@ static const ScanKeyword unreserved_keywords[] = {
 	PG_KEYWORD("raise", K_RAISE, UNRESERVED_KEYWORD)
 	PG_KEYWORD("relative", K_RELATIVE, UNRESERVED_KEYWORD)
 	PG_KEYWORD("reset", K_RESET, UNRESERVED_KEYWORD)
-	PG_KEYWORD("result_oid", K_RESULT_OID, UNRESERVED_KEYWORD)
 	PG_KEYWORD("return", K_RETURN, UNRESERVED_KEYWORD)
 	PG_KEYWORD("returned_sqlstate", K_RETURNED_SQLSTATE, UNRESERVED_KEYWORD)
 	PG_KEYWORD("reverse", K_REVERSE, UNRESERVED_KEYWORD)
diff --git a/src/pl/plpgsql/src/plpgsql.h b/src/pl/plpgsql/src/plpgsql.h
index f6c35a50490..42177ccaa65 100644
--- a/src/pl/plpgsql/src/plpgsql.h
+++ b/src/pl/plpgsql/src/plpgsql.h
@@ -148,7 +148,6 @@ enum
 typedef enum PLpgSQL_getdiag_kind
 {
 	PLPGSQL_GETDIAG_ROW_COUNT,
-	PLPGSQL_GETDIAG_RESULT_OID,
 	PLPGSQL_GETDIAG_CONTEXT,
 	PLPGSQL_GETDIAG_ERROR_CONTEXT,
 	PLPGSQL_GETDIAG_ERROR_DETAIL,
@@ -1043,7 +1042,6 @@ typedef struct PLpgSQL_execstate
 	/* temporary state for results from evaluation of query or expr */
 	SPITupleTable *eval_tuptable;
 	uint64		eval_processed;
-	Oid			eval_lastoid;
 	ExprContext *eval_econtext; /* for executing simple expressions */
 
 	/* status information for error context reporting */
diff --git a/src/pl/tcl/expected/pltcl_queries.out b/src/pl/tcl/expected/pltcl_queries.out
index 736671cc1bc..17e821bb4cf 100644
--- a/src/pl/tcl/expected/pltcl_queries.out
+++ b/src/pl/tcl/expected/pltcl_queries.out
@@ -402,21 +402,6 @@ NOTICE:  args: {42 {statement trigger}}
 ERROR:  argisnull cannot be used in triggers
 select trigger_data();
 ERROR:  trigger functions can only be called as triggers
--- Test spi_lastoid primitive
-create temp table t1 (f1 int);
-select tcl_lastoid('t1');
- tcl_lastoid 
--------------
-           0
-(1 row)
-
-create temp table t2 (f1 int) with oids;
-select tcl_lastoid('t2') > 0;
- ?column? 
-----------
- t
-(1 row)
-
 -- test some error cases
 create function tcl_error(out a int, out b int) as $$return {$$ language pltcl;
 select tcl_error();
diff --git a/src/pl/tcl/expected/pltcl_setup.out b/src/pl/tcl/expected/pltcl_setup.out
index f1958c3a984..b10cf4e47db 100644
--- a/src/pl/tcl/expected/pltcl_setup.out
+++ b/src/pl/tcl/expected/pltcl_setup.out
@@ -431,10 +431,6 @@ create function tcl_composite_arg_ref2(T_dta1) returns text as '
 create function tcl_argisnull(text) returns bool as '
     argisnull 1
 ' language pltcl;
-create function tcl_lastoid(tabname text) returns int8 as '
-    spi_exec "insert into $1 default values"
-    spi_lastoid
-' language pltcl;
 create function tcl_int4add(int4,int4) returns int4 as '
     return [expr $1 + $2]
 ' language pltcl;
diff --git a/src/pl/tcl/pltcl.c b/src/pl/tcl/pltcl.c
index e2fa43b890d..3b1454f8335 100644
--- a/src/pl/tcl/pltcl.c
+++ b/src/pl/tcl/pltcl.c
@@ -307,8 +307,6 @@ static int pltcl_SPI_prepare(ClientData cdata, Tcl_Interp *interp,
 				  int objc, Tcl_Obj *const objv[]);
 static int pltcl_SPI_execute_plan(ClientData cdata, Tcl_Interp *interp,
 					   int objc, Tcl_Obj *const objv[]);
-static int pltcl_SPI_lastoid(ClientData cdata, Tcl_Interp *interp,
-				  int objc, Tcl_Obj *const objv[]);
 static int pltcl_subtransaction(ClientData cdata, Tcl_Interp *interp,
 					 int objc, Tcl_Obj *const objv[]);
 static int pltcl_commit(ClientData cdata, Tcl_Interp *interp,
@@ -523,8 +521,6 @@ pltcl_init_interp(pltcl_interp_desc *interp_desc, Oid prolang, bool pltrusted)
 						 pltcl_SPI_prepare, NULL, NULL);
 	Tcl_CreateObjCommand(interp, "spi_execp",
 						 pltcl_SPI_execute_plan, NULL, NULL);
-	Tcl_CreateObjCommand(interp, "spi_lastoid",
-						 pltcl_SPI_lastoid, NULL, NULL);
 	Tcl_CreateObjCommand(interp, "subtransaction",
 						 pltcl_subtransaction, NULL, NULL);
 	Tcl_CreateObjCommand(interp, "commit",
@@ -2873,28 +2869,6 @@ pltcl_SPI_execute_plan(ClientData cdata, Tcl_Interp *interp,
 }
 
 
-/**********************************************************************
- * pltcl_SPI_lastoid()	- return the last oid. To
- *		  be used after insert queries
- **********************************************************************/
-static int
-pltcl_SPI_lastoid(ClientData cdata, Tcl_Interp *interp,
-				  int objc, Tcl_Obj *const objv[])
-{
-	/*
-	 * Check call syntax
-	 */
-	if (objc != 1)
-	{
-		Tcl_WrongNumArgs(interp, 1, objv, "");
-		return TCL_ERROR;
-	}
-
-	Tcl_SetObjResult(interp, Tcl_NewWideIntObj(SPI_lastoid));
-	return TCL_OK;
-}
-
-
 /**********************************************************************
  * pltcl_subtransaction()	- Execute some Tcl code in a subtransaction
  *
diff --git a/src/pl/tcl/sql/pltcl_queries.sql b/src/pl/tcl/sql/pltcl_queries.sql
index 71c1238bd20..7390de6bd6b 100644
--- a/src/pl/tcl/sql/pltcl_queries.sql
+++ b/src/pl/tcl/sql/pltcl_queries.sql
@@ -117,12 +117,6 @@ select tcl_argisnull(null);
 insert into trigger_test(test_argisnull) values(true);
 select trigger_data();
 
--- Test spi_lastoid primitive
-create temp table t1 (f1 int);
-select tcl_lastoid('t1');
-create temp table t2 (f1 int) with oids;
-select tcl_lastoid('t2') > 0;
-
 -- test some error cases
 create function tcl_error(out a int, out b int) as $$return {$$ language pltcl;
 select tcl_error();
diff --git a/src/pl/tcl/sql/pltcl_setup.sql b/src/pl/tcl/sql/pltcl_setup.sql
index 56a90dc8449..0ea46134c74 100644
--- a/src/pl/tcl/sql/pltcl_setup.sql
+++ b/src/pl/tcl/sql/pltcl_setup.sql
@@ -465,11 +465,6 @@ create function tcl_argisnull(text) returns bool as '
     argisnull 1
 ' language pltcl;
 
-create function tcl_lastoid(tabname text) returns int8 as '
-    spi_exec "insert into $1 default values"
-    spi_lastoid
-' language pltcl;
-
 
 create function tcl_int4add(int4,int4) returns int4 as '
     return [expr $1 + $2]
diff --git a/src/test/modules/test_ddl_deparse/expected/create_table.out b/src/test/modules/test_ddl_deparse/expected/create_table.out
index d27a7752570..2d7dfd533e4 100644
--- a/src/test/modules/test_ddl_deparse/expected/create_table.out
+++ b/src/test/modules/test_ddl_deparse/expected/create_table.out
@@ -98,7 +98,7 @@ NOTICE:  DDL test: type simple, tag CREATE INDEX
 CREATE TABLE emp (
 	salary 		int4,
 	manager 	name
-) INHERITS (person) WITH OIDS;
+) INHERITS (person);
 NOTICE:  DDL test: type simple, tag CREATE TABLE
 CREATE TABLE student (
 	gpa 		float8
diff --git a/src/test/modules/test_ddl_deparse/sql/create_table.sql b/src/test/modules/test_ddl_deparse/sql/create_table.sql
index 5e784527297..dd3a908638d 100644
--- a/src/test/modules/test_ddl_deparse/sql/create_table.sql
+++ b/src/test/modules/test_ddl_deparse/sql/create_table.sql
@@ -86,7 +86,7 @@ CREATE TABLE person (
 CREATE TABLE emp (
 	salary 		int4,
 	manager 	name
-) INHERITS (person) WITH OIDS;
+) INHERITS (person);
 
 
 CREATE TABLE student (
diff --git a/src/test/modules/test_ddl_deparse/test_ddl_deparse.c b/src/test/modules/test_ddl_deparse/test_ddl_deparse.c
index 82a51eb3039..9c588f3a3ad 100644
--- a/src/test/modules/test_ddl_deparse/test_ddl_deparse.c
+++ b/src/test/modules/test_ddl_deparse/test_ddl_deparse.c
@@ -195,15 +195,6 @@ get_altertable_subcmdtypes(PG_FUNCTION_ARGS)
 			case AT_SetUnLogged:
 				strtype = "SET UNLOGGED";
 				break;
-			case AT_AddOids:
-				strtype = "ADD OIDS";
-				break;
-			case AT_AddOidsRecurse:
-				strtype = "ADD OIDS (and recurse)";
-				break;
-			case AT_DropOids:
-				strtype = "DROP OIDS";
-				break;
 			case AT_SetTableSpace:
 				strtype = "SET TABLESPACE";
 				break;
diff --git a/src/test/modules/test_predtest/test_predtest.c b/src/test/modules/test_predtest/test_predtest.c
index 51320ade2e5..1e699e6556e 100644
--- a/src/test/modules/test_predtest/test_predtest.c
+++ b/src/test/modules/test_predtest/test_predtest.c
@@ -185,7 +185,7 @@ test_predtest(PG_FUNCTION_ARGS)
 	if (SPI_finish() != SPI_OK_FINISH)
 		elog(ERROR, "SPI_finish failed");
 
-	tupdesc = CreateTemplateTupleDesc(8, false);
+	tupdesc = CreateTemplateTupleDesc(8);
 	TupleDescInitEntry(tupdesc, (AttrNumber) 1,
 					   "strong_implied_by", BOOLOID, -1, 0);
 	TupleDescInitEntry(tupdesc, (AttrNumber) 2,
diff --git a/src/test/regress/expected/alter_table.out b/src/test/regress/expected/alter_table.out
index 0aa13b3cec2..591c56e4771 100644
--- a/src/test/regress/expected/alter_table.out
+++ b/src/test/regress/expected/alter_table.out
@@ -849,7 +849,7 @@ ERROR:  check constraint "foo" is violated by some row
 drop table atacc2;
 drop table atacc1;
 -- test unique constraint adding
-create table atacc1 ( test int ) with oids;
+create table atacc1 ( test int ) ;
 -- add a unique constraint
 alter table atacc1 add constraint atacc_test1 unique (test);
 -- insert first value
@@ -860,8 +860,6 @@ ERROR:  duplicate key value violates unique constraint "atacc_test1"
 DETAIL:  Key (test)=(2) already exists.
 -- should succeed
 insert into atacc1 (test) values (4);
--- try adding a unique oid constraint
-alter table atacc1 add constraint atacc_oid1 unique(oid);
 -- try to create duplicates via alter table using - should fail
 alter table atacc1 alter column test type integer using 0;
 ERROR:  could not create unique index "atacc_test1"
@@ -910,7 +908,7 @@ ERROR:  duplicate key value violates unique constraint "atacc1_test_key"
 DETAIL:  Key (test)=(3) already exists.
 drop table atacc1;
 -- test primary key constraint adding
-create table atacc1 ( test int ) with oids;
+create table atacc1 ( id serial, test int) ;
 -- add a primary key constraint
 alter table atacc1 add constraint atacc_test1 primary key (test);
 -- insert first value
@@ -924,14 +922,14 @@ insert into atacc1 (test) values (4);
 -- inserting NULL should fail
 insert into atacc1 (test) values(NULL);
 ERROR:  null value in column "test" violates not-null constraint
-DETAIL:  Failing row contains (null).
+DETAIL:  Failing row contains (4, null).
 -- try adding a second primary key (should fail)
-alter table atacc1 add constraint atacc_oid1 primary key(oid);
+alter table atacc1 add constraint atacc_oid1 primary key(id);
 ERROR:  multiple primary keys for table "atacc1" are not allowed
 -- drop first primary key constraint
 alter table atacc1 drop constraint atacc_test1 restrict;
 -- try adding a primary key on oid (should succeed)
-alter table atacc1 add constraint atacc_oid1 primary key(oid);
+alter table atacc1 add constraint atacc_oid1 primary key(id);
 drop table atacc1;
 -- let's do one where the primary key constraint fails when added
 create table atacc1 ( test int );
@@ -1021,7 +1019,7 @@ alter table non_existent alter column bar drop not null;
 ERROR:  relation "non_existent" does not exist
 -- test setting columns to null and not null and vice versa
 -- test checking for null values and primary key
-create table atacc1 (test int not null) with oids;
+create table atacc1 (test int not null);
 alter table atacc1 add constraint "atacc1_pkey" primary key (test);
 alter table atacc1 alter column test drop not null;
 ERROR:  column "test" is in a primary key
@@ -1037,11 +1035,6 @@ alter table atacc1 alter bar set not null;
 ERROR:  column "bar" of relation "atacc1" does not exist
 alter table atacc1 alter bar drop not null;
 ERROR:  column "bar" of relation "atacc1" does not exist
--- try altering the oid column, should fail
-alter table atacc1 alter oid set not null;
-ERROR:  cannot alter system column "oid"
-alter table atacc1 alter oid drop not null;
-ERROR:  cannot alter system column "oid"
 -- try creating a view and altering that, should fail
 create view myview as select * from atacc1;
 alter table myview alter column test drop not null;
@@ -1147,7 +1140,7 @@ ERROR:  permission denied: "pg_class" is a system catalog
 alter table nosuchtable drop column bar;
 ERROR:  relation "nosuchtable" does not exist
 -- test dropping columns
-create table atacc1 (a int4 not null, b int4, c int4 not null, d int4) with oids;
+create table atacc1 (a int4 not null, b int4, c int4 not null, d int4);
 insert into atacc1 values (1, 2, 3, 4);
 alter table atacc1 drop a;
 alter table atacc1 drop a;
@@ -1292,8 +1285,6 @@ delete from atacc1;
 -- try dropping a non-existent column, should fail
 alter table atacc1 drop bar;
 ERROR:  column "bar" of relation "atacc1" does not exist
--- try dropping the oid column, should succeed
-alter table atacc1 drop oid;
 -- try dropping the xmin column, should fail
 alter table atacc1 drop xmin;
 ERROR:  cannot drop system column "xmin"
@@ -1691,131 +1682,6 @@ order by attrelid::regclass::text, attnum;
  depth2   | c       |           1 | f
 (3 rows)
 
---
--- Test the ALTER TABLE SET WITH/WITHOUT OIDS command
---
-create table altstartwith (col integer) with oids;
-insert into altstartwith values (1);
-select oid > 0, * from altstartwith;
- ?column? | col 
-----------+-----
- t        |   1
-(1 row)
-
-alter table altstartwith set without oids;
-select oid > 0, * from altstartwith; -- fails
-ERROR:  column "oid" does not exist
-LINE 1: select oid > 0, * from altstartwith;
-               ^
-select * from altstartwith;
- col 
------
-   1
-(1 row)
-
-alter table altstartwith set with oids;
-select oid > 0, * from altstartwith;
- ?column? | col 
-----------+-----
- t        |   1
-(1 row)
-
-drop table altstartwith;
--- Check inheritance cases
-create table altwithoid (col integer) with oids;
--- Inherits parents oid column anyway
-create table altinhoid () inherits (altwithoid) without oids;
-insert into altinhoid values (1);
-select oid > 0, * from altwithoid;
- ?column? | col 
-----------+-----
- t        |   1
-(1 row)
-
-select oid > 0, * from altinhoid;
- ?column? | col 
-----------+-----
- t        |   1
-(1 row)
-
-alter table altwithoid set without oids;
-select oid > 0, * from altwithoid; -- fails
-ERROR:  column "oid" does not exist
-LINE 1: select oid > 0, * from altwithoid;
-               ^
-select oid > 0, * from altinhoid; -- fails
-ERROR:  column "oid" does not exist
-LINE 1: select oid > 0, * from altinhoid;
-               ^
-select * from altwithoid;
- col 
------
-   1
-(1 row)
-
-select * from altinhoid;
- col 
------
-   1
-(1 row)
-
-alter table altwithoid set with oids;
-select oid > 0, * from altwithoid;
- ?column? | col 
-----------+-----
- t        |   1
-(1 row)
-
-select oid > 0, * from altinhoid;
- ?column? | col 
-----------+-----
- t        |   1
-(1 row)
-
-drop table altwithoid cascade;
-NOTICE:  drop cascades to table altinhoid
-create table altwithoid (col integer) without oids;
--- child can have local oid column
-create table altinhoid () inherits (altwithoid) with oids;
-insert into altinhoid values (1);
-select oid > 0, * from altwithoid; -- fails
-ERROR:  column "oid" does not exist
-LINE 1: select oid > 0, * from altwithoid;
-               ^
-select oid > 0, * from altinhoid;
- ?column? | col 
-----------+-----
- t        |   1
-(1 row)
-
-alter table altwithoid set with oids;
-NOTICE:  merging definition of column "oid" for child "altinhoid"
-select oid > 0, * from altwithoid;
- ?column? | col 
-----------+-----
- t        |   1
-(1 row)
-
-select oid > 0, * from altinhoid;
- ?column? | col 
-----------+-----
- t        |   1
-(1 row)
-
--- the child's local definition should remain
-alter table altwithoid set without oids;
-select oid > 0, * from altwithoid; -- fails
-ERROR:  column "oid" does not exist
-LINE 1: select oid > 0, * from altwithoid;
-               ^
-select oid > 0, * from altinhoid;
- ?column? | col 
-----------+-----
- t        |   1
-(1 row)
-
-drop table altwithoid cascade;
-NOTICE:  drop cascades to table altinhoid
 -- test renumbering of child-table columns in inherited operations
 create table p1 (f1 int);
 create table c1 (f2 text, f3 int) inherits (p1);
@@ -2916,7 +2782,7 @@ CREATE TABLE tt3 (y numeric(8,2), x int);			-- wrong column order
 CREATE TABLE tt4 (x int);							-- too few columns
 CREATE TABLE tt5 (x int, y numeric(8,2), z int);	-- too few columns
 CREATE TABLE tt6 () INHERITS (tt0);					-- can't have a parent
-CREATE TABLE tt7 (x int, q text, y numeric(8,2)) WITH OIDS;
+CREATE TABLE tt7 (x int, q text, y numeric(8,2));
 ALTER TABLE tt7 DROP q;								-- OK
 ALTER TABLE tt0 OF tt_t0;
 ALTER TABLE tt1 OF tt_t0;
@@ -3441,16 +3307,6 @@ ALTER TABLE list_parted ATTACH PARTITION fail_part FOR VALUES IN (1);
 ERROR:  cannot attach a typed table as partition
 DROP TYPE mytype CASCADE;
 NOTICE:  drop cascades to table fail_part
--- check existence (or non-existence) of oid column
-ALTER TABLE list_parted SET WITH OIDS;
-CREATE TABLE fail_part (a int);
-ALTER TABLE list_parted ATTACH PARTITION fail_part FOR VALUES IN (1);
-ERROR:  cannot attach table "fail_part" without OIDs as partition of table "list_parted" with OIDs
-ALTER TABLE list_parted SET WITHOUT OIDS;
-ALTER TABLE fail_part SET WITH OIDS;
-ALTER TABLE list_parted ATTACH PARTITION fail_part FOR VALUES IN (1);
-ERROR:  cannot attach table "fail_part" with OIDs as partition of table "list_parted" without OIDs
-DROP TABLE fail_part;
 -- check that the table being attached has only columns present in the parent
 CREATE TABLE fail_part (like list_parted, c int);
 ALTER TABLE list_parted ATTACH PARTITION fail_part FOR VALUES IN (1);
diff --git a/src/test/regress/expected/copy2.out b/src/test/regress/expected/copy2.out
index eb9e4b97741..19bb5384110 100644
--- a/src/test/regress/expected/copy2.out
+++ b/src/test/regress/expected/copy2.out
@@ -4,7 +4,7 @@ CREATE TEMP TABLE x (
 	c text not null default 'stuff',
 	d text,
 	e text
-) WITH OIDS;
+) ;
 CREATE FUNCTION fn_x_before () RETURNS TRIGGER AS '
   BEGIN
 		NEW.e := ''before trigger fired''::text;
@@ -46,7 +46,7 @@ COPY x from stdin;
 ERROR:  extra data after last expected column
 CONTEXT:  COPY x, line 1: "2002	232	40	50	60	70	80"
 -- various COPY options: delimiters, oids, NULL string, encoding
-COPY x (b, c, d, e) from stdin with oids delimiter ',' null 'x';
+COPY x (b, c, d, e) from stdin delimiter ',' null 'x';
 COPY x from stdin WITH DELIMITER AS ';' NULL AS '';
 COPY x from stdin WITH DELIMITER AS ':' NULL AS E'\\X' ENCODING 'sql_ascii';
 -- check results of copy in
@@ -80,18 +80,6 @@ SELECT * FROM x;
      5 |  5 | stuff      | test_5 | after trigger fired
 (25 rows)
 
--- COPY w/ oids on a table w/o oids should fail
-CREATE TABLE no_oids (
-	a	int,
-	b	int
-) WITHOUT OIDS;
-INSERT INTO no_oids (a, b) VALUES (5, 10);
-INSERT INTO no_oids (a, b) VALUES (20, 30);
--- should fail
-COPY no_oids FROM stdin WITH OIDS;
-ERROR:  table "no_oids" does not have OIDs
-COPY no_oids TO stdout WITH OIDS;
-ERROR:  table "no_oids" does not have OIDs
 -- check copy out
 COPY x TO stdout;
 9999	\N	\\N	NN	before trigger fired
diff --git a/src/test/regress/expected/create_index.out b/src/test/regress/expected/create_index.out
index 297535bb8fd..46deb55c679 100644
--- a/src/test/regress/expected/create_index.out
+++ b/src/test/regress/expected/create_index.out
@@ -2779,19 +2779,17 @@ DROP TABLE cwi_test;
 --
 -- Check handling of indexes on system columns
 --
-CREATE TABLE oid_table (a INT) WITH OIDS;
--- An index on the OID column should be allowed
-CREATE INDEX ON oid_table (oid);
--- Other system columns cannot be indexed
-CREATE INDEX ON oid_table (ctid);
-ERROR:  index creation on system columns is not supported
+CREATE TABLE syscol_table (a INT);
+-- System columns cannot be indexed
+CREATE INDEX ON syscolcol_table (ctid);
+ERROR:  relation "syscolcol_table" does not exist
 -- nor used in expressions
-CREATE INDEX ON oid_table ((ctid >= '(1000,0)'));
+CREATE INDEX ON syscol_table ((ctid >= '(1000,0)'));
 ERROR:  index creation on system columns is not supported
 -- nor used in predicates
-CREATE INDEX ON oid_table (a) WHERE ctid >= '(1000,0)';
+CREATE INDEX ON syscol_table (a) WHERE ctid >= '(1000,0)';
 ERROR:  index creation on system columns is not supported
-DROP TABLE oid_table;
+DROP TABLE syscol_table;
 --
 -- Tests for IS NULL/IS NOT NULL with b-tree indexes
 --
diff --git a/src/test/regress/expected/create_table.out b/src/test/regress/expected/create_table.out
index 7b184330ed5..3dc0baf9835 100644
--- a/src/test/regress/expected/create_table.out
+++ b/src/test/regress/expected/create_table.out
@@ -47,7 +47,7 @@ CREATE TABLE tenk1 (
 	stringu1	name,
 	stringu2	name,
 	string4		name
-) WITH OIDS;
+);
 CREATE TABLE tenk2 (
 	unique1 	int4,
 	unique2 	int4,
@@ -74,7 +74,7 @@ CREATE TABLE person (
 CREATE TABLE emp (
 	salary 		int4,
 	manager 	name
-) INHERITS (person) WITH OIDS;
+) INHERITS (person);
 CREATE TABLE student (
 	gpa 		float8
 ) INHERITS (person);
@@ -218,8 +218,6 @@ NOTICE:  relation "test_tsvector" already exists, skipping
 -- invalid: non-lowercase quoted reloptions identifiers
 CREATE TABLE tas_case WITH ("Fillfactor" = 10) AS SELECT 1 a;
 ERROR:  unrecognized parameter "Fillfactor"
-CREATE TABLE tas_case (a text) WITH ("Oids" = true);
-ERROR:  unrecognized parameter "Oids"
 CREATE UNLOGGED TABLE unlogged1 (a int primary key);			-- OK
 CREATE TEMPORARY TABLE unlogged2 (a int primary key);			-- OK
 SELECT relname, relkind, relpersistence FROM pg_class WHERE relname ~ '^unlogged\d' ORDER BY relname;
@@ -263,9 +261,6 @@ ERROR:  relation "as_select1" already exists
 CREATE TABLE IF NOT EXISTS as_select1 AS SELECT * FROM pg_class WHERE relkind = 'r';
 NOTICE:  relation "as_select1" already exists, skipping
 DROP TABLE as_select1;
--- check that the oid column is added before the primary key is checked
-CREATE TABLE oid_pk (f1 INT, PRIMARY KEY(oid)) WITH OIDS;
-DROP TABLE oid_pk;
 --
 -- Partitioned tables
 --
@@ -575,29 +570,6 @@ CREATE TEMP TABLE temp_parted (
 CREATE TABLE fail_part PARTITION OF temp_parted FOR VALUES IN ('a');
 ERROR:  cannot create a permanent relation as partition of temporary relation "temp_parted"
 DROP TABLE temp_parted;
--- cannot create a table with oids as partition of table without oids
-CREATE TABLE no_oids_parted (
-	a int
-) PARTITION BY RANGE (a) WITHOUT OIDS;
-CREATE TABLE fail_part PARTITION OF no_oids_parted FOR VALUES FROM (1) TO (10) WITH OIDS;
-ERROR:  cannot create table with OIDs as partition of table without OIDs
-DROP TABLE no_oids_parted;
--- If the partitioned table has oids, then the partition must have them.
--- If the WITHOUT OIDS option is specified for partition, it is overridden.
-CREATE TABLE oids_parted (
-	a int
-) PARTITION BY RANGE (a) WITH OIDS;
-CREATE TABLE part_forced_oids PARTITION OF oids_parted FOR VALUES FROM (1) TO (10) WITHOUT OIDS;
-\d+ part_forced_oids
-                             Table "public.part_forced_oids"
- Column |  Type   | Collation | Nullable | Default | Storage | Stats target | Description 
---------+---------+-----------+----------+---------+---------+--------------+-------------
- a      | integer |           |          |         | plain   |              | 
-Partition of: oids_parted FOR VALUES FROM (1) TO (10)
-Partition constraint: ((a IS NOT NULL) AND (a >= 1) AND (a < 10))
-Has OIDs: yes
-
-DROP TABLE oids_parted, part_forced_oids;
 -- check for partition bound overlap and other invalid specifications
 CREATE TABLE list_parted2 (
 	a varchar
diff --git a/src/test/regress/expected/create_table_like.out b/src/test/regress/expected/create_table_like.out
index 8d4543bfe8d..b5822112706 100644
--- a/src/test/regress/expected/create_table_like.out
+++ b/src/test/regress/expected/create_table_like.out
@@ -285,37 +285,3 @@ DROP TYPE ctlty1;
 DROP VIEW ctlv1;
 DROP TABLE IF EXISTS ctlt4, ctlt10, ctlt11, ctlt11a, ctlt12;
 NOTICE:  table "ctlt10" does not exist, skipping
-/* LIKE WITH OIDS */
-CREATE TABLE has_oid (x INTEGER) WITH OIDS;
-CREATE TABLE no_oid (y INTEGER);
-CREATE TABLE like_test (z INTEGER, LIKE has_oid);
-SELECT oid FROM like_test;
- oid 
------
-(0 rows)
-
-CREATE TABLE like_test2 (z INTEGER, LIKE no_oid);
-SELECT oid FROM like_test2; -- fail
-ERROR:  column "oid" does not exist
-LINE 1: SELECT oid FROM like_test2;
-               ^
-CREATE TABLE like_test3 (z INTEGER, LIKE has_oid, LIKE no_oid);
-SELECT oid FROM like_test3;
- oid 
------
-(0 rows)
-
-CREATE TABLE like_test4 (z INTEGER, PRIMARY KEY(oid), LIKE has_oid);
-SELECT oid FROM like_test4;
- oid 
------
-(0 rows)
-
-CREATE TABLE like_test5 (z INTEGER, LIKE no_oid) WITH OIDS;
-SELECT oid FROM like_test5;
- oid 
------
-(0 rows)
-
-DROP TABLE has_oid, no_oid, like_test, like_test2, like_test3,
-  like_test4, like_test5;
diff --git a/src/test/regress/expected/enum.out b/src/test/regress/expected/enum.out
index 4f839ce0279..dffff88928e 100644
--- a/src/test/regress/expected/enum.out
+++ b/src/test/regress/expected/enum.out
@@ -685,7 +685,7 @@ SELECT COUNT(*) FROM pg_type WHERE typname = 'rainbow';
 
 SELECT * FROM pg_enum WHERE NOT EXISTS
   (SELECT 1 FROM pg_type WHERE pg_type.oid = enumtypid);
- enumtypid | enumsortorder | enumlabel 
------------+---------------+-----------
+ oid | enumtypid | enumsortorder | enumlabel 
+-----+-----------+---------------+-----------
 (0 rows)
 
diff --git a/src/test/regress/expected/errors.out b/src/test/regress/expected/errors.out
index ce473a03efd..7dd8a5b33e4 100644
--- a/src/test/regress/expected/errors.out
+++ b/src/test/regress/expected/errors.out
@@ -103,8 +103,8 @@ ERROR:  column "nonesuchatt" does not exist
 alter table emp rename column salary to manager;
 ERROR:  column "manager" of relation "stud_emp" already exists
 -- conflict
-alter table emp rename column salary to oid;
-ERROR:  column name "oid" conflicts with a system column name
+alter table emp rename column salary to ctid;
+ERROR:  column name "ctid" conflicts with a system column name
 --
 -- TRANSACTION STUFF
 -- not in a xact
diff --git a/src/test/regress/expected/foreign_data.out b/src/test/regress/expected/foreign_data.out
index 75365501d4a..0ef37e42bd7 100644
--- a/src/test/regress/expected/foreign_data.out
+++ b/src/test/regress/expected/foreign_data.out
@@ -30,8 +30,8 @@ SELECT srvname, srvoptions FROM pg_foreign_server;
 (0 rows)
 
 SELECT * FROM pg_user_mapping;
- umuser | umserver | umoptions 
---------+----------+-----------
+ oid | umuser | umserver | umoptions 
+-----+--------+----------+-----------
 (0 rows)
 
 -- CREATE FOREIGN DATA WRAPPER
@@ -684,10 +684,6 @@ LINE 1: CREATE FOREIGN TABLE ft1 ();
                                    ^
 CREATE FOREIGN TABLE ft1 () SERVER no_server;                   -- ERROR
 ERROR:  server "no_server" does not exist
-CREATE FOREIGN TABLE ft1 () SERVER s0 WITH OIDS;                -- ERROR
-ERROR:  syntax error at or near "WITH"
-LINE 1: CREATE FOREIGN TABLE ft1 () SERVER s0 WITH OIDS;
-                                              ^
 CREATE FOREIGN TABLE ft1 (
 	c1 integer OPTIONS ("param 1" 'val1') PRIMARY KEY,
 	c2 text OPTIONS (param2 'val2', param3 'val3'),
@@ -822,7 +818,6 @@ ALTER FOREIGN TABLE ft1 DROP CONSTRAINT no_const;               -- ERROR
 ERROR:  constraint "no_const" of relation "ft1" does not exist
 ALTER FOREIGN TABLE ft1 DROP CONSTRAINT IF EXISTS no_const;
 NOTICE:  constraint "no_const" of relation "ft1" does not exist, skipping
-ALTER FOREIGN TABLE ft1 SET WITH OIDS;
 ALTER FOREIGN TABLE ft1 OWNER TO regress_test_role;
 ALTER FOREIGN TABLE ft1 OPTIONS (DROP delimiter, SET quote '~', ADD escape '@');
 ALTER FOREIGN TABLE ft1 DROP COLUMN no_column;                  -- ERROR
@@ -1725,63 +1720,6 @@ Server: s0
 FDW options: (delimiter ',', quote '"', "be quoted" 'value')
 Inherits: fd_pt1
 
--- OID system column
-ALTER TABLE fd_pt1 SET WITH OIDS;
-\d+ fd_pt1
-                                   Table "public.fd_pt1"
- Column |  Type   | Collation | Nullable | Default | Storage  | Stats target | Description 
---------+---------+-----------+----------+---------+----------+--------------+-------------
- c1     | integer |           | not null |         | plain    | 10000        | 
- c2     | text    |           |          |         | extended |              | 
- c3     | date    |           |          |         | plain    |              | 
-Check constraints:
-    "fd_pt1chk3" CHECK (c2 <> ''::text)
-Child tables: ft2
-Has OIDs: yes
-
-\d+ ft2
-                                       Foreign table "public.ft2"
- Column |  Type   | Collation | Nullable | Default | FDW options | Storage  | Stats target | Description 
---------+---------+-----------+----------+---------+-------------+----------+--------------+-------------
- c1     | integer |           | not null |         |             | plain    |              | 
- c2     | text    |           |          |         |             | extended |              | 
- c3     | date    |           |          |         |             | plain    |              | 
-Check constraints:
-    "fd_pt1chk2" CHECK (c2 <> ''::text)
-    "fd_pt1chk3" CHECK (c2 <> ''::text)
-Server: s0
-FDW options: (delimiter ',', quote '"', "be quoted" 'value')
-Inherits: fd_pt1
-Has OIDs: yes
-
-ALTER TABLE ft2 SET WITHOUT OIDS;  -- ERROR
-ERROR:  cannot drop inherited column "oid"
-ALTER TABLE fd_pt1 SET WITHOUT OIDS;
-\d+ fd_pt1
-                                   Table "public.fd_pt1"
- Column |  Type   | Collation | Nullable | Default | Storage  | Stats target | Description 
---------+---------+-----------+----------+---------+----------+--------------+-------------
- c1     | integer |           | not null |         | plain    | 10000        | 
- c2     | text    |           |          |         | extended |              | 
- c3     | date    |           |          |         | plain    |              | 
-Check constraints:
-    "fd_pt1chk3" CHECK (c2 <> ''::text)
-Child tables: ft2
-
-\d+ ft2
-                                       Foreign table "public.ft2"
- Column |  Type   | Collation | Nullable | Default | FDW options | Storage  | Stats target | Description 
---------+---------+-----------+----------+---------+-------------+----------+--------------+-------------
- c1     | integer |           | not null |         |             | plain    |              | 
- c2     | text    |           |          |         |             | extended |              | 
- c3     | date    |           |          |         |             | plain    |              | 
-Check constraints:
-    "fd_pt1chk2" CHECK (c2 <> ''::text)
-    "fd_pt1chk3" CHECK (c2 <> ''::text)
-Server: s0
-FDW options: (delimiter ',', quote '"', "be quoted" 'value')
-Inherits: fd_pt1
-
 -- changes name of an attribute recursively
 ALTER TABLE fd_pt1 RENAME COLUMN c1 TO f1;
 ALTER TABLE fd_pt1 RENAME COLUMN c2 TO f2;
@@ -2097,7 +2035,7 @@ SELECT srvname, srvoptions FROM pg_foreign_server;
 (0 rows)
 
 SELECT * FROM pg_user_mapping;
- umuser | umserver | umoptions 
---------+----------+-----------
+ oid | umuser | umserver | umoptions 
+-----+--------+----------+-----------
 (0 rows)
 
diff --git a/src/test/regress/expected/inherit.out b/src/test/regress/expected/inherit.out
index 1e00c849f38..f259d075359 100644
--- a/src/test/regress/expected/inherit.out
+++ b/src/test/regress/expected/inherit.out
@@ -673,55 +673,6 @@ select * from d;
  32 | one | two | three
 (1 row)
 
--- check that oid column is handled properly during alter table inherit
-create table oid_parent (a int) with oids;
-create table oid_child () inherits (oid_parent);
-select attinhcount, attislocal from pg_attribute
-  where attrelid = 'oid_child'::regclass and attname = 'oid';
- attinhcount | attislocal 
--------------+------------
-           1 | f
-(1 row)
-
-drop table oid_child;
-create table oid_child (a int) without oids;
-alter table oid_child inherit oid_parent;  -- fail
-ERROR:  table "oid_child" without OIDs cannot inherit from table "oid_parent" with OIDs
-alter table oid_child set with oids;
-select attinhcount, attislocal from pg_attribute
-  where attrelid = 'oid_child'::regclass and attname = 'oid';
- attinhcount | attislocal 
--------------+------------
-           0 | t
-(1 row)
-
-alter table oid_child inherit oid_parent;
-select attinhcount, attislocal from pg_attribute
-  where attrelid = 'oid_child'::regclass and attname = 'oid';
- attinhcount | attislocal 
--------------+------------
-           1 | t
-(1 row)
-
-alter table oid_child set without oids;  -- fail
-ERROR:  cannot drop inherited column "oid"
-alter table oid_parent set without oids;
-select attinhcount, attislocal from pg_attribute
-  where attrelid = 'oid_child'::regclass and attname = 'oid';
- attinhcount | attislocal 
--------------+------------
-           0 | t
-(1 row)
-
-alter table oid_child set without oids;
-select attinhcount, attislocal from pg_attribute
-  where attrelid = 'oid_child'::regclass and attname = 'oid';
- attinhcount | attislocal 
--------------+------------
-(0 rows)
-
-drop table oid_parent cascade;
-NOTICE:  drop cascades to table oid_child
 -- Test non-inheritable parent constraints
 create table p1(ff1 int);
 alter table p1 add constraint p1chk check (ff1 > 0) no inherit;
diff --git a/src/test/regress/expected/insert_conflict.out b/src/test/regress/expected/insert_conflict.out
index 6b841c7850e..12ae6c5fa5f 100644
--- a/src/test/regress/expected/insert_conflict.out
+++ b/src/test/regress/expected/insert_conflict.out
@@ -443,18 +443,14 @@ drop table insertconflicttest;
 --
 -- Verify that EXCLUDED does not allow system column references. These
 -- do not make sense because EXCLUDED isn't an already stored tuple
--- (and thus doesn't have a ctid, oids are not assigned yet, etc).
+-- (and thus doesn't have a ctid etc).
 --
-create table syscolconflicttest(key int4, data text) WITH OIDS;
+create table syscolconflicttest(key int4, data text);
 insert into syscolconflicttest values (1);
 insert into syscolconflicttest values (1) on conflict (key) do update set data = excluded.ctid::text;
 ERROR:  column excluded.ctid does not exist
 LINE 1: ...values (1) on conflict (key) do update set data = excluded.c...
                                                              ^
-insert into syscolconflicttest values (1) on conflict (key) do update set data = excluded.oid::text;
-ERROR:  column excluded.oid does not exist
-LINE 1: ...values (1) on conflict (key) do update set data = excluded.o...
-                                                             ^
 drop table syscolconflicttest;
 --
 -- Previous tests all managed to not test any expressions requiring
@@ -620,65 +616,6 @@ insert into excluded values(1, '2') on conflict (key) do update set data = 3 RET
 
 -- clean up
 drop table excluded;
--- Check tables w/o oids are handled correctly
-create table testoids(key int primary key, data text) without oids;
--- first without oids
-insert into testoids values(1, '1') on conflict (key) do update set data = excluded.data RETURNING *;
- key | data 
------+------
-   1 | 1
-(1 row)
-
-insert into testoids values(1, '2') on conflict (key) do update set data = excluded.data RETURNING *;
- key | data 
------+------
-   1 | 2
-(1 row)
-
--- add oids
-alter table testoids set with oids;
--- update existing row, that didn't have an oid
-insert into testoids values(1, '3') on conflict (key) do update set data = excluded.data RETURNING *;
- key | data 
------+------
-   1 | 3
-(1 row)
-
--- insert a new row
-insert into testoids values(2, '1') on conflict (key) do update set data = excluded.data RETURNING *;
- key | data 
------+------
-   2 | 1
-(1 row)
-
--- and update it
-insert into testoids values(2, '2') on conflict (key) do update set data = excluded.data RETURNING *;
- key | data 
------+------
-   2 | 2
-(1 row)
-
--- remove oids again, test
-alter table testoids set without oids;
-insert into testoids values(1, '4') on conflict (key) do update set data = excluded.data RETURNING *;
- key | data 
------+------
-   1 | 4
-(1 row)
-
-insert into testoids values(3, '1') on conflict (key) do update set data = excluded.data RETURNING *;
- key | data 
------+------
-   3 | 1
-(1 row)
-
-insert into testoids values(3, '2') on conflict (key) do update set data = excluded.data RETURNING *;
- key | data 
------+------
-   3 | 2
-(1 row)
-
-DROP TABLE testoids;
 -- check that references to columns after dropped columns are handled correctly
 create table dropcol(key int primary key, drop1 int, keep1 text, drop2 numeric, keep2 float);
 insert into dropcol(key, drop1, keep1, drop2, keep2) values(1, 1, '1', '1', 1);
diff --git a/src/test/regress/expected/misc_sanity.out b/src/test/regress/expected/misc_sanity.out
index 2d3522b500d..3503aa69e81 100644
--- a/src/test/regress/expected/misc_sanity.out
+++ b/src/test/regress/expected/misc_sanity.out
@@ -52,7 +52,7 @@ declare relnm text;
 begin
 for relnm, reloid, shared in
   select relname, oid, relisshared from pg_class
-  where relhasoids and oid < 16384 order by 1
+  where EXISTS(SELECT * FROM pg_attribute WHERE attrelid = pg_class.oid AND attname = 'oid') and relkind = 'r' and oid < 16384 order by 1
 loop
   execute 'select min(oid) from ' || relnm into lowoid;
   continue when lowoid is null or lowoid >= 16384;
diff --git a/src/test/regress/expected/opr_sanity.out b/src/test/regress/expected/opr_sanity.out
index c073a5ac3fa..6072f6bdb1f 100644
--- a/src/test/regress/expected/opr_sanity.out
+++ b/src/test/regress/expected/opr_sanity.out
@@ -794,8 +794,8 @@ SELECT *
 FROM pg_cast c
 WHERE castsource = 0 OR casttarget = 0 OR castcontext NOT IN ('e', 'a', 'i')
     OR castmethod NOT IN ('f', 'b' ,'i');
- castsource | casttarget | castfunc | castcontext | castmethod 
-------------+------------+----------+-------------+------------
+ oid | castsource | casttarget | castfunc | castcontext | castmethod 
+-----+------------+------------+----------+-------------+------------
 (0 rows)
 
 -- Check that castfunc is nonzero only for cast methods that need a function,
@@ -804,8 +804,8 @@ SELECT *
 FROM pg_cast c
 WHERE (castmethod = 'f' AND castfunc = 0)
    OR (castmethod IN ('b', 'i') AND castfunc <> 0);
- castsource | casttarget | castfunc | castcontext | castmethod 
-------------+------------+----------+-------------+------------
+ oid | castsource | casttarget | castfunc | castcontext | castmethod 
+-----+------------+------------+----------+-------------+------------
 (0 rows)
 
 -- Look for casts to/from the same type that aren't length coercion functions.
@@ -814,15 +814,15 @@ WHERE (castmethod = 'f' AND castfunc = 0)
 SELECT *
 FROM pg_cast c
 WHERE castsource = casttarget AND castfunc = 0;
- castsource | casttarget | castfunc | castcontext | castmethod 
-------------+------------+----------+-------------+------------
+ oid | castsource | casttarget | castfunc | castcontext | castmethod 
+-----+------------+------------+----------+-------------+------------
 (0 rows)
 
 SELECT c.*
 FROM pg_cast c, pg_proc p
 WHERE c.castfunc = p.oid AND p.pronargs < 2 AND castsource = casttarget;
- castsource | casttarget | castfunc | castcontext | castmethod 
-------------+------------+----------+-------------+------------
+ oid | castsource | casttarget | castfunc | castcontext | castmethod 
+-----+------------+------------+----------+-------------+------------
 (0 rows)
 
 -- Look for cast functions that don't have the right signature.  The
@@ -840,8 +840,8 @@ WHERE c.castfunc = p.oid AND
              OR (c.castsource = 'character'::regtype AND
                  p.proargtypes[0] = 'text'::regtype))
      OR NOT binary_coercible(p.prorettype, c.casttarget));
- castsource | casttarget | castfunc | castcontext | castmethod 
-------------+------------+----------+-------------+------------
+ oid | castsource | casttarget | castfunc | castcontext | castmethod 
+-----+------------+------------+----------+-------------+------------
 (0 rows)
 
 SELECT c.*
@@ -849,8 +849,8 @@ FROM pg_cast c, pg_proc p
 WHERE c.castfunc = p.oid AND
     ((p.pronargs > 1 AND p.proargtypes[1] != 'int4'::regtype) OR
      (p.pronargs > 2 AND p.proargtypes[2] != 'bool'::regtype));
- castsource | casttarget | castfunc | castcontext | castmethod 
-------------+------------+----------+-------------+------------
+ oid | castsource | casttarget | castfunc | castcontext | castmethod 
+-----+------------+------------+----------+-------------+------------
 (0 rows)
 
 -- Look for binary compatible casts that do not have the reverse
diff --git a/src/test/regress/expected/prepare.out b/src/test/regress/expected/prepare.out
index 7016e82bd42..d07c0cc9c91 100644
--- a/src/test/regress/expected/prepare.out
+++ b/src/test/regress/expected/prepare.out
@@ -64,11 +64,11 @@ EXECUTE q2('postgres');
  postgres | f             | t
 (1 row)
 
-PREPARE q3(text, int, float, boolean, oid, smallint) AS
+PREPARE q3(text, int, float, boolean, smallint) AS
 	SELECT * FROM tenk1 WHERE string4 = $1 AND (four = $2 OR
-	ten = $3::bigint OR true = $4 OR oid = $5 OR odd = $6::int)
+	ten = $3::bigint OR true = $4 OR odd = $5::int)
 	ORDER BY unique1;
-EXECUTE q3('AAAAxx', 5::smallint, 10.5::float, false, 500::oid, 4::bigint);
+EXECUTE q3('AAAAxx', 5::smallint, 10.5::float, false, 4::bigint);
  unique1 | unique2 | two | four | ten | twenty | hundred | thousand | twothousand | fivethous | tenthous | odd | even | stringu1 | stringu2 | string4 
 ---------+---------+-----+------+-----+--------+---------+----------+-------------+-----------+----------+-----+------+----------+----------+---------
        2 |    2716 |   0 |    2 |   2 |      2 |       2 |        2 |           2 |         2 |        2 |   4 |    5 | CAAAAA   | MAEAAA   | AAAAxx
@@ -105,13 +105,13 @@ EXECUTE q3('AAAAxx', 5::smallint, 10.5::float, false, 500::oid, 4::bigint);
 -- too few params
 EXECUTE q3('bool');
 ERROR:  wrong number of parameters for prepared statement "q3"
-DETAIL:  Expected 6 parameters but got 1.
+DETAIL:  Expected 5 parameters but got 1.
 -- too many params
-EXECUTE q3('bytea', 5::smallint, 10.5::float, false, 500::oid, 4::bigint, true);
+EXECUTE q3('bytea', 5::smallint, 10.5::float, false, 4::bigint, true);
 ERROR:  wrong number of parameters for prepared statement "q3"
-DETAIL:  Expected 6 parameters but got 7.
+DETAIL:  Expected 5 parameters but got 6.
 -- wrong param types
-EXECUTE q3(5::smallint, 10.5::float, false, 500::oid, 4::bigint, 'bytea');
+EXECUTE q3(5::smallint, 10.5::float, false, 4::bigint, 'bytea');
 ERROR:  parameter $3 of type boolean cannot be coerced to the expected type double precision
 HINT:  You will need to rewrite or cast the expression.
 -- invalid type
@@ -152,22 +152,22 @@ PREPARE q7(unknown) AS
     SELECT * FROM road WHERE thepath = $1;
 SELECT name, statement, parameter_types FROM pg_prepared_statements
     ORDER BY name;
- name |                              statement                              |                    parameter_types                     
-------+---------------------------------------------------------------------+--------------------------------------------------------
- q2   | PREPARE q2(text) AS                                                +| {text}
-      |         SELECT datname, datistemplate, datallowconn                +| 
-      |         FROM pg_database WHERE datname = $1;                        | 
- q3   | PREPARE q3(text, int, float, boolean, oid, smallint) AS            +| {text,integer,"double precision",boolean,oid,smallint}
-      |         SELECT * FROM tenk1 WHERE string4 = $1 AND (four = $2 OR   +| 
-      |         ten = $3::bigint OR true = $4 OR oid = $5 OR odd = $6::int)+| 
-      |         ORDER BY unique1;                                           | 
- q5   | PREPARE q5(int, text) AS                                           +| {integer,text}
-      |         SELECT * FROM tenk1 WHERE unique1 = $1 OR stringu1 = $2    +| 
-      |         ORDER BY unique1;                                           | 
- q6   | PREPARE q6 AS                                                      +| {integer,name}
-      |     SELECT * FROM tenk1 WHERE unique1 = $1 AND stringu1 = $2;       | 
- q7   | PREPARE q7(unknown) AS                                             +| {path}
-      |     SELECT * FROM road WHERE thepath = $1;                          | 
+ name |                            statement                             |                  parameter_types                   
+------+------------------------------------------------------------------+----------------------------------------------------
+ q2   | PREPARE q2(text) AS                                             +| {text}
+      |         SELECT datname, datistemplate, datallowconn             +| 
+      |         FROM pg_database WHERE datname = $1;                     | 
+ q3   | PREPARE q3(text, int, float, boolean, smallint) AS              +| {text,integer,"double precision",boolean,smallint}
+      |         SELECT * FROM tenk1 WHERE string4 = $1 AND (four = $2 OR+| 
+      |         ten = $3::bigint OR true = $4 OR odd = $5::int)         +| 
+      |         ORDER BY unique1;                                        | 
+ q5   | PREPARE q5(int, text) AS                                        +| {integer,text}
+      |         SELECT * FROM tenk1 WHERE unique1 = $1 OR stringu1 = $2 +| 
+      |         ORDER BY unique1;                                        | 
+ q6   | PREPARE q6 AS                                                   +| {integer,name}
+      |     SELECT * FROM tenk1 WHERE unique1 = $1 AND stringu1 = $2;    | 
+ q7   | PREPARE q7(unknown) AS                                          +| {path}
+      |     SELECT * FROM road WHERE thepath = $1;                       | 
 (5 rows)
 
 -- test DEALLOCATE ALL;
diff --git a/src/test/regress/expected/privileges.out b/src/test/regress/expected/privileges.out
index 3af92ed1a83..83b3196b1df 100644
--- a/src/test/regress/expected/privileges.out
+++ b/src/test/regress/expected/privileges.out
@@ -587,10 +587,10 @@ ERROR:  permission denied for table atest5
 DELETE FROM atest5 WHERE two = 2; -- ok
 -- check inheritance cases
 SET SESSION AUTHORIZATION regress_priv_user1;
-CREATE TABLE atestp1 (f1 int, f2 int) WITH OIDS;
-CREATE TABLE atestp2 (fx int, fy int) WITH OIDS;
+CREATE TABLE atestp1 (f1 int, f2 int);
+CREATE TABLE atestp2 (fx int, fy int);
 CREATE TABLE atestc (fz int) INHERITS (atestp1, atestp2);
-GRANT SELECT(fx,fy,oid) ON atestp2 TO regress_priv_user2;
+GRANT SELECT(fx,fy,tableoid) ON atestp2 TO regress_priv_user2;
 GRANT SELECT(fx) ON atestc TO regress_priv_user2;
 SET SESSION AUTHORIZATION regress_priv_user2;
 SELECT fx FROM atestp2; -- ok
@@ -608,15 +608,15 @@ SELECT atestp2 FROM atestp2; -- ok
 ---------
 (0 rows)
 
-SELECT oid FROM atestp2; -- ok
- oid 
------
+SELECT tableoid FROM atestp2; -- ok
+ tableoid 
+----------
 (0 rows)
 
 SELECT fy FROM atestc; -- fail
 ERROR:  permission denied for table atestc
 SET SESSION AUTHORIZATION regress_priv_user1;
-GRANT SELECT(fy,oid) ON atestc TO regress_priv_user2;
+GRANT SELECT(fy,tableoid) ON atestc TO regress_priv_user2;
 SET SESSION AUTHORIZATION regress_priv_user2;
 SELECT fx FROM atestp2; -- still ok
  fx 
@@ -633,9 +633,9 @@ SELECT atestp2 FROM atestp2; -- ok
 ---------
 (0 rows)
 
-SELECT oid FROM atestp2; -- ok
- oid 
------
+SELECT tableoid FROM atestp2; -- ok
+ tableoid 
+----------
 (0 rows)
 
 -- privileges on functions, languages
@@ -1720,8 +1720,8 @@ DROP SCHEMA testns5 CASCADE;
 SELECT d.*     -- check that entries went away
   FROM pg_default_acl d LEFT JOIN pg_namespace n ON defaclnamespace = n.oid
   WHERE nspname IS NULL AND defaclnamespace != 0;
- defaclrole | defaclnamespace | defaclobjtype | defaclacl 
-------------+-----------------+---------------+-----------
+ oid | defaclrole | defaclnamespace | defaclobjtype | defaclacl 
+-----+------------+-----------------+---------------+-----------
 (0 rows)
 
 -- Grant on all objects of given type in a schema
diff --git a/src/test/regress/expected/reloptions.out b/src/test/regress/expected/reloptions.out
index df3c99d1eb1..f90c267c87e 100644
--- a/src/test/regress/expected/reloptions.out
+++ b/src/test/regress/expected/reloptions.out
@@ -86,15 +86,6 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass AND
 -- RESET fails if a value is specified
 ALTER TABLE reloptions_test RESET (fillfactor=12);
 ERROR:  RESET must not include values for parameters
--- The OIDS option is not stored as reloption
-DROP TABLE reloptions_test;
-CREATE TABLE reloptions_test(i INT) WITH (fillfactor=20, oids=true);
-SELECT reloptions, relhasoids FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-   reloptions    | relhasoids 
------------------+------------
- {fillfactor=20} | t
-(1 row)
-
 -- Test toast.* options
 DROP TABLE reloptions_test;
 CREATE TABLE reloptions_test (s VARCHAR)
diff --git a/src/test/regress/expected/replica_identity.out b/src/test/regress/expected/replica_identity.out
index 67c34a92a4e..175ecd28794 100644
--- a/src/test/regress/expected/replica_identity.out
+++ b/src/test/regress/expected/replica_identity.out
@@ -5,11 +5,10 @@ CREATE TABLE test_replica_identity (
        nonkey text,
        CONSTRAINT test_replica_identity_unique_defer UNIQUE (keya, keyb) DEFERRABLE,
        CONSTRAINT test_replica_identity_unique_nondefer UNIQUE (keya, keyb)
-) WITH OIDS;
+) ;
 CREATE TABLE test_replica_identity_othertable (id serial primary key);
 CREATE INDEX test_replica_identity_keyab ON test_replica_identity (keya, keyb);
 CREATE UNIQUE INDEX test_replica_identity_keyab_key ON test_replica_identity (keya, keyb);
-CREATE UNIQUE INDEX test_replica_identity_oid_idx ON test_replica_identity (oid);
 CREATE UNIQUE INDEX test_replica_identity_nonkey ON test_replica_identity (keya, nonkey);
 CREATE INDEX test_replica_identity_hash ON test_replica_identity USING hash (nonkey);
 CREATE UNIQUE INDEX test_replica_identity_expr ON test_replica_identity (keya, keyb, (3));
@@ -88,15 +87,12 @@ Indexes:
     "test_replica_identity_expr" UNIQUE, btree (keya, keyb, (3))
     "test_replica_identity_keyab_key" UNIQUE, btree (keya, keyb)
     "test_replica_identity_nonkey" UNIQUE, btree (keya, nonkey)
-    "test_replica_identity_oid_idx" UNIQUE, btree (oid)
     "test_replica_identity_partial" UNIQUE, btree (keya, keyb) WHERE keyb <> '3'::text
     "test_replica_identity_unique_defer" UNIQUE CONSTRAINT, btree (keya, keyb) DEFERRABLE
     "test_replica_identity_unique_nondefer" UNIQUE CONSTRAINT, btree (keya, keyb)
     "test_replica_identity_hash" hash (nonkey)
     "test_replica_identity_keyab" btree (keya, keyb)
 
--- succeed, oid unique index
-ALTER TABLE test_replica_identity REPLICA IDENTITY USING INDEX test_replica_identity_oid_idx;
 -- succeed, nondeferrable unique constraint over nonnullable cols
 ALTER TABLE test_replica_identity REPLICA IDENTITY USING INDEX test_replica_identity_unique_nondefer;
 -- succeed unique index over nonnullable cols
@@ -121,7 +117,6 @@ Indexes:
     "test_replica_identity_expr" UNIQUE, btree (keya, keyb, (3))
     "test_replica_identity_keyab_key" UNIQUE, btree (keya, keyb) REPLICA IDENTITY
     "test_replica_identity_nonkey" UNIQUE, btree (keya, nonkey)
-    "test_replica_identity_oid_idx" UNIQUE, btree (oid)
     "test_replica_identity_partial" UNIQUE, btree (keya, keyb) WHERE keyb <> '3'::text
     "test_replica_identity_unique_defer" UNIQUE CONSTRAINT, btree (keya, keyb) DEFERRABLE
     "test_replica_identity_unique_nondefer" UNIQUE CONSTRAINT, btree (keya, keyb)
@@ -170,14 +165,12 @@ Indexes:
     "test_replica_identity_expr" UNIQUE, btree (keya, keyb, (3))
     "test_replica_identity_keyab_key" UNIQUE, btree (keya, keyb)
     "test_replica_identity_nonkey" UNIQUE, btree (keya, nonkey)
-    "test_replica_identity_oid_idx" UNIQUE, btree (oid)
     "test_replica_identity_partial" UNIQUE, btree (keya, keyb) WHERE keyb <> '3'::text
     "test_replica_identity_unique_defer" UNIQUE CONSTRAINT, btree (keya, keyb) DEFERRABLE
     "test_replica_identity_unique_nondefer" UNIQUE CONSTRAINT, btree (keya, keyb)
     "test_replica_identity_hash" hash (nonkey)
     "test_replica_identity_keyab" btree (keya, keyb)
 Replica Identity: FULL
-Has OIDs: yes
 
 ALTER TABLE test_replica_identity REPLICA IDENTITY NOTHING;
 SELECT relreplident FROM pg_class WHERE oid = 'test_replica_identity'::regclass;
diff --git a/src/test/regress/expected/roleattributes.out b/src/test/regress/expected/roleattributes.out
index 570aa5f8343..5e6969b173e 100644
--- a/src/test/regress/expected/roleattributes.out
+++ b/src/test/regress/expected/roleattributes.out
@@ -1,27 +1,27 @@
 -- default for superuser is false
 CREATE ROLE regress_test_def_superuser;
-SELECT * FROM pg_authid WHERE rolname = 'regress_test_def_superuser';
+SELECT rolname, rolsuper, rolinherit, rolcreaterole, rolcreatedb, rolcanlogin, rolreplication, rolbypassrls, rolconnlimit, rolpassword, rolvaliduntil FROM pg_authid WHERE rolname = 'regress_test_def_superuser';
           rolname           | rolsuper | rolinherit | rolcreaterole | rolcreatedb | rolcanlogin | rolreplication | rolbypassrls | rolconnlimit | rolpassword | rolvaliduntil 
 ----------------------------+----------+------------+---------------+-------------+-------------+----------------+--------------+--------------+-------------+---------------
  regress_test_def_superuser | f        | t          | f             | f           | f           | f              | f            |           -1 |             | 
 (1 row)
 
 CREATE ROLE regress_test_superuser WITH SUPERUSER;
-SELECT * FROM pg_authid WHERE rolname = 'regress_test_superuser';
+SELECT rolname, rolsuper, rolinherit, rolcreaterole, rolcreatedb, rolcanlogin, rolreplication, rolbypassrls, rolconnlimit, rolpassword, rolvaliduntil FROM pg_authid WHERE rolname = 'regress_test_superuser';
         rolname         | rolsuper | rolinherit | rolcreaterole | rolcreatedb | rolcanlogin | rolreplication | rolbypassrls | rolconnlimit | rolpassword | rolvaliduntil 
 ------------------------+----------+------------+---------------+-------------+-------------+----------------+--------------+--------------+-------------+---------------
  regress_test_superuser | t        | t          | f             | f           | f           | f              | f            |           -1 |             | 
 (1 row)
 
 ALTER ROLE regress_test_superuser WITH NOSUPERUSER;
-SELECT * FROM pg_authid WHERE rolname = 'regress_test_superuser';
+SELECT rolname, rolsuper, rolinherit, rolcreaterole, rolcreatedb, rolcanlogin, rolreplication, rolbypassrls, rolconnlimit, rolpassword, rolvaliduntil FROM pg_authid WHERE rolname = 'regress_test_superuser';
         rolname         | rolsuper | rolinherit | rolcreaterole | rolcreatedb | rolcanlogin | rolreplication | rolbypassrls | rolconnlimit | rolpassword | rolvaliduntil 
 ------------------------+----------+------------+---------------+-------------+-------------+----------------+--------------+--------------+-------------+---------------
  regress_test_superuser | f        | t          | f             | f           | f           | f              | f            |           -1 |             | 
 (1 row)
 
 ALTER ROLE regress_test_superuser WITH SUPERUSER;
-SELECT * FROM pg_authid WHERE rolname = 'regress_test_superuser';
+SELECT rolname, rolsuper, rolinherit, rolcreaterole, rolcreatedb, rolcanlogin, rolreplication, rolbypassrls, rolconnlimit, rolpassword, rolvaliduntil FROM pg_authid WHERE rolname = 'regress_test_superuser';
         rolname         | rolsuper | rolinherit | rolcreaterole | rolcreatedb | rolcanlogin | rolreplication | rolbypassrls | rolconnlimit | rolpassword | rolvaliduntil 
 ------------------------+----------+------------+---------------+-------------+-------------+----------------+--------------+--------------+-------------+---------------
  regress_test_superuser | t        | t          | f             | f           | f           | f              | f            |           -1 |             | 
@@ -29,28 +29,28 @@ SELECT * FROM pg_authid WHERE rolname = 'regress_test_superuser';
 
 -- default for inherit is true
 CREATE ROLE regress_test_def_inherit;
-SELECT * FROM pg_authid WHERE rolname = 'regress_test_def_inherit';
+SELECT rolname, rolsuper, rolinherit, rolcreaterole, rolcreatedb, rolcanlogin, rolreplication, rolbypassrls, rolconnlimit, rolpassword, rolvaliduntil FROM pg_authid WHERE rolname = 'regress_test_def_inherit';
          rolname          | rolsuper | rolinherit | rolcreaterole | rolcreatedb | rolcanlogin | rolreplication | rolbypassrls | rolconnlimit | rolpassword | rolvaliduntil 
 --------------------------+----------+------------+---------------+-------------+-------------+----------------+--------------+--------------+-------------+---------------
  regress_test_def_inherit | f        | t          | f             | f           | f           | f              | f            |           -1 |             | 
 (1 row)
 
 CREATE ROLE regress_test_inherit WITH NOINHERIT;
-SELECT * FROM pg_authid WHERE rolname = 'regress_test_inherit';
+SELECT rolname, rolsuper, rolinherit, rolcreaterole, rolcreatedb, rolcanlogin, rolreplication, rolbypassrls, rolconnlimit, rolpassword, rolvaliduntil FROM pg_authid WHERE rolname = 'regress_test_inherit';
        rolname        | rolsuper | rolinherit | rolcreaterole | rolcreatedb | rolcanlogin | rolreplication | rolbypassrls | rolconnlimit | rolpassword | rolvaliduntil 
 ----------------------+----------+------------+---------------+-------------+-------------+----------------+--------------+--------------+-------------+---------------
  regress_test_inherit | f        | f          | f             | f           | f           | f              | f            |           -1 |             | 
 (1 row)
 
 ALTER ROLE regress_test_inherit WITH INHERIT;
-SELECT * FROM pg_authid WHERE rolname = 'regress_test_inherit';
+SELECT rolname, rolsuper, rolinherit, rolcreaterole, rolcreatedb, rolcanlogin, rolreplication, rolbypassrls, rolconnlimit, rolpassword, rolvaliduntil FROM pg_authid WHERE rolname = 'regress_test_inherit';
        rolname        | rolsuper | rolinherit | rolcreaterole | rolcreatedb | rolcanlogin | rolreplication | rolbypassrls | rolconnlimit | rolpassword | rolvaliduntil 
 ----------------------+----------+------------+---------------+-------------+-------------+----------------+--------------+--------------+-------------+---------------
  regress_test_inherit | f        | t          | f             | f           | f           | f              | f            |           -1 |             | 
 (1 row)
 
 ALTER ROLE regress_test_inherit WITH NOINHERIT;
-SELECT * FROM pg_authid WHERE rolname = 'regress_test_inherit';
+SELECT rolname, rolsuper, rolinherit, rolcreaterole, rolcreatedb, rolcanlogin, rolreplication, rolbypassrls, rolconnlimit, rolpassword, rolvaliduntil FROM pg_authid WHERE rolname = 'regress_test_inherit';
        rolname        | rolsuper | rolinherit | rolcreaterole | rolcreatedb | rolcanlogin | rolreplication | rolbypassrls | rolconnlimit | rolpassword | rolvaliduntil 
 ----------------------+----------+------------+---------------+-------------+-------------+----------------+--------------+--------------+-------------+---------------
  regress_test_inherit | f        | f          | f             | f           | f           | f              | f            |           -1 |             | 
@@ -58,28 +58,28 @@ SELECT * FROM pg_authid WHERE rolname = 'regress_test_inherit';
 
 -- default for create role is false
 CREATE ROLE regress_test_def_createrole;
-SELECT * FROM pg_authid WHERE rolname = 'regress_test_def_createrole';
+SELECT rolname, rolsuper, rolinherit, rolcreaterole, rolcreatedb, rolcanlogin, rolreplication, rolbypassrls, rolconnlimit, rolpassword, rolvaliduntil FROM pg_authid WHERE rolname = 'regress_test_def_createrole';
            rolname           | rolsuper | rolinherit | rolcreaterole | rolcreatedb | rolcanlogin | rolreplication | rolbypassrls | rolconnlimit | rolpassword | rolvaliduntil 
 -----------------------------+----------+------------+---------------+-------------+-------------+----------------+--------------+--------------+-------------+---------------
  regress_test_def_createrole | f        | t          | f             | f           | f           | f              | f            |           -1 |             | 
 (1 row)
 
 CREATE ROLE regress_test_createrole WITH CREATEROLE;
-SELECT * FROM pg_authid WHERE rolname = 'regress_test_createrole';
+SELECT rolname, rolsuper, rolinherit, rolcreaterole, rolcreatedb, rolcanlogin, rolreplication, rolbypassrls, rolconnlimit, rolpassword, rolvaliduntil FROM pg_authid WHERE rolname = 'regress_test_createrole';
          rolname         | rolsuper | rolinherit | rolcreaterole | rolcreatedb | rolcanlogin | rolreplication | rolbypassrls | rolconnlimit | rolpassword | rolvaliduntil 
 -------------------------+----------+------------+---------------+-------------+-------------+----------------+--------------+--------------+-------------+---------------
  regress_test_createrole | f        | t          | t             | f           | f           | f              | f            |           -1 |             | 
 (1 row)
 
 ALTER ROLE regress_test_createrole WITH NOCREATEROLE;
-SELECT * FROM pg_authid WHERE rolname = 'regress_test_createrole';
+SELECT rolname, rolsuper, rolinherit, rolcreaterole, rolcreatedb, rolcanlogin, rolreplication, rolbypassrls, rolconnlimit, rolpassword, rolvaliduntil FROM pg_authid WHERE rolname = 'regress_test_createrole';
          rolname         | rolsuper | rolinherit | rolcreaterole | rolcreatedb | rolcanlogin | rolreplication | rolbypassrls | rolconnlimit | rolpassword | rolvaliduntil 
 -------------------------+----------+------------+---------------+-------------+-------------+----------------+--------------+--------------+-------------+---------------
  regress_test_createrole | f        | t          | f             | f           | f           | f              | f            |           -1 |             | 
 (1 row)
 
 ALTER ROLE regress_test_createrole WITH CREATEROLE;
-SELECT * FROM pg_authid WHERE rolname = 'regress_test_createrole';
+SELECT rolname, rolsuper, rolinherit, rolcreaterole, rolcreatedb, rolcanlogin, rolreplication, rolbypassrls, rolconnlimit, rolpassword, rolvaliduntil FROM pg_authid WHERE rolname = 'regress_test_createrole';
          rolname         | rolsuper | rolinherit | rolcreaterole | rolcreatedb | rolcanlogin | rolreplication | rolbypassrls | rolconnlimit | rolpassword | rolvaliduntil 
 -------------------------+----------+------------+---------------+-------------+-------------+----------------+--------------+--------------+-------------+---------------
  regress_test_createrole | f        | t          | t             | f           | f           | f              | f            |           -1 |             | 
@@ -87,28 +87,28 @@ SELECT * FROM pg_authid WHERE rolname = 'regress_test_createrole';
 
 -- default for create database is false
 CREATE ROLE regress_test_def_createdb;
-SELECT * FROM pg_authid WHERE rolname = 'regress_test_def_createdb';
+SELECT rolname, rolsuper, rolinherit, rolcreaterole, rolcreatedb, rolcanlogin, rolreplication, rolbypassrls, rolconnlimit, rolpassword, rolvaliduntil FROM pg_authid WHERE rolname = 'regress_test_def_createdb';
           rolname          | rolsuper | rolinherit | rolcreaterole | rolcreatedb | rolcanlogin | rolreplication | rolbypassrls | rolconnlimit | rolpassword | rolvaliduntil 
 ---------------------------+----------+------------+---------------+-------------+-------------+----------------+--------------+--------------+-------------+---------------
  regress_test_def_createdb | f        | t          | f             | f           | f           | f              | f            |           -1 |             | 
 (1 row)
 
 CREATE ROLE regress_test_createdb WITH CREATEDB;
-SELECT * FROM pg_authid WHERE rolname = 'regress_test_createdb';
+SELECT rolname, rolsuper, rolinherit, rolcreaterole, rolcreatedb, rolcanlogin, rolreplication, rolbypassrls, rolconnlimit, rolpassword, rolvaliduntil FROM pg_authid WHERE rolname = 'regress_test_createdb';
         rolname        | rolsuper | rolinherit | rolcreaterole | rolcreatedb | rolcanlogin | rolreplication | rolbypassrls | rolconnlimit | rolpassword | rolvaliduntil 
 -----------------------+----------+------------+---------------+-------------+-------------+----------------+--------------+--------------+-------------+---------------
  regress_test_createdb | f        | t          | f             | t           | f           | f              | f            |           -1 |             | 
 (1 row)
 
 ALTER ROLE regress_test_createdb WITH NOCREATEDB;
-SELECT * FROM pg_authid WHERE rolname = 'regress_test_createdb';
+SELECT rolname, rolsuper, rolinherit, rolcreaterole, rolcreatedb, rolcanlogin, rolreplication, rolbypassrls, rolconnlimit, rolpassword, rolvaliduntil FROM pg_authid WHERE rolname = 'regress_test_createdb';
         rolname        | rolsuper | rolinherit | rolcreaterole | rolcreatedb | rolcanlogin | rolreplication | rolbypassrls | rolconnlimit | rolpassword | rolvaliduntil 
 -----------------------+----------+------------+---------------+-------------+-------------+----------------+--------------+--------------+-------------+---------------
  regress_test_createdb | f        | t          | f             | f           | f           | f              | f            |           -1 |             | 
 (1 row)
 
 ALTER ROLE regress_test_createdb WITH CREATEDB;
-SELECT * FROM pg_authid WHERE rolname = 'regress_test_createdb';
+SELECT rolname, rolsuper, rolinherit, rolcreaterole, rolcreatedb, rolcanlogin, rolreplication, rolbypassrls, rolconnlimit, rolpassword, rolvaliduntil FROM pg_authid WHERE rolname = 'regress_test_createdb';
         rolname        | rolsuper | rolinherit | rolcreaterole | rolcreatedb | rolcanlogin | rolreplication | rolbypassrls | rolconnlimit | rolpassword | rolvaliduntil 
 -----------------------+----------+------------+---------------+-------------+-------------+----------------+--------------+--------------+-------------+---------------
  regress_test_createdb | f        | t          | f             | t           | f           | f              | f            |           -1 |             | 
@@ -116,28 +116,28 @@ SELECT * FROM pg_authid WHERE rolname = 'regress_test_createdb';
 
 -- default for can login is false for role
 CREATE ROLE regress_test_def_role_canlogin;
-SELECT * FROM pg_authid WHERE rolname = 'regress_test_def_role_canlogin';
+SELECT rolname, rolsuper, rolinherit, rolcreaterole, rolcreatedb, rolcanlogin, rolreplication, rolbypassrls, rolconnlimit, rolpassword, rolvaliduntil FROM pg_authid WHERE rolname = 'regress_test_def_role_canlogin';
             rolname             | rolsuper | rolinherit | rolcreaterole | rolcreatedb | rolcanlogin | rolreplication | rolbypassrls | rolconnlimit | rolpassword | rolvaliduntil 
 --------------------------------+----------+------------+---------------+-------------+-------------+----------------+--------------+--------------+-------------+---------------
  regress_test_def_role_canlogin | f        | t          | f             | f           | f           | f              | f            |           -1 |             | 
 (1 row)
 
 CREATE ROLE regress_test_role_canlogin WITH LOGIN;
-SELECT * FROM pg_authid WHERE rolname = 'regress_test_role_canlogin';
+SELECT rolname, rolsuper, rolinherit, rolcreaterole, rolcreatedb, rolcanlogin, rolreplication, rolbypassrls, rolconnlimit, rolpassword, rolvaliduntil FROM pg_authid WHERE rolname = 'regress_test_role_canlogin';
           rolname           | rolsuper | rolinherit | rolcreaterole | rolcreatedb | rolcanlogin | rolreplication | rolbypassrls | rolconnlimit | rolpassword | rolvaliduntil 
 ----------------------------+----------+------------+---------------+-------------+-------------+----------------+--------------+--------------+-------------+---------------
  regress_test_role_canlogin | f        | t          | f             | f           | t           | f              | f            |           -1 |             | 
 (1 row)
 
 ALTER ROLE regress_test_role_canlogin WITH NOLOGIN;
-SELECT * FROM pg_authid WHERE rolname = 'regress_test_role_canlogin';
+SELECT rolname, rolsuper, rolinherit, rolcreaterole, rolcreatedb, rolcanlogin, rolreplication, rolbypassrls, rolconnlimit, rolpassword, rolvaliduntil FROM pg_authid WHERE rolname = 'regress_test_role_canlogin';
           rolname           | rolsuper | rolinherit | rolcreaterole | rolcreatedb | rolcanlogin | rolreplication | rolbypassrls | rolconnlimit | rolpassword | rolvaliduntil 
 ----------------------------+----------+------------+---------------+-------------+-------------+----------------+--------------+--------------+-------------+---------------
  regress_test_role_canlogin | f        | t          | f             | f           | f           | f              | f            |           -1 |             | 
 (1 row)
 
 ALTER ROLE regress_test_role_canlogin WITH LOGIN;
-SELECT * FROM pg_authid WHERE rolname = 'regress_test_role_canlogin';
+SELECT rolname, rolsuper, rolinherit, rolcreaterole, rolcreatedb, rolcanlogin, rolreplication, rolbypassrls, rolconnlimit, rolpassword, rolvaliduntil FROM pg_authid WHERE rolname = 'regress_test_role_canlogin';
           rolname           | rolsuper | rolinherit | rolcreaterole | rolcreatedb | rolcanlogin | rolreplication | rolbypassrls | rolconnlimit | rolpassword | rolvaliduntil 
 ----------------------------+----------+------------+---------------+-------------+-------------+----------------+--------------+--------------+-------------+---------------
  regress_test_role_canlogin | f        | t          | f             | f           | t           | f              | f            |           -1 |             | 
@@ -145,28 +145,28 @@ SELECT * FROM pg_authid WHERE rolname = 'regress_test_role_canlogin';
 
 -- default for can login is true for user
 CREATE USER regress_test_def_user_canlogin;
-SELECT * FROM pg_authid WHERE rolname = 'regress_test_def_user_canlogin';
+SELECT rolname, rolsuper, rolinherit, rolcreaterole, rolcreatedb, rolcanlogin, rolreplication, rolbypassrls, rolconnlimit, rolpassword, rolvaliduntil FROM pg_authid WHERE rolname = 'regress_test_def_user_canlogin';
             rolname             | rolsuper | rolinherit | rolcreaterole | rolcreatedb | rolcanlogin | rolreplication | rolbypassrls | rolconnlimit | rolpassword | rolvaliduntil 
 --------------------------------+----------+------------+---------------+-------------+-------------+----------------+--------------+--------------+-------------+---------------
  regress_test_def_user_canlogin | f        | t          | f             | f           | t           | f              | f            |           -1 |             | 
 (1 row)
 
 CREATE USER regress_test_user_canlogin WITH NOLOGIN;
-SELECT * FROM pg_authid WHERE rolname = 'regress_test_user_canlogin';
+SELECT rolname, rolsuper, rolinherit, rolcreaterole, rolcreatedb, rolcanlogin, rolreplication, rolbypassrls, rolconnlimit, rolpassword, rolvaliduntil FROM pg_authid WHERE rolname = 'regress_test_user_canlogin';
           rolname           | rolsuper | rolinherit | rolcreaterole | rolcreatedb | rolcanlogin | rolreplication | rolbypassrls | rolconnlimit | rolpassword | rolvaliduntil 
 ----------------------------+----------+------------+---------------+-------------+-------------+----------------+--------------+--------------+-------------+---------------
  regress_test_user_canlogin | f        | t          | f             | f           | f           | f              | f            |           -1 |             | 
 (1 row)
 
 ALTER USER regress_test_user_canlogin WITH LOGIN;
-SELECT * FROM pg_authid WHERE rolname = 'regress_test_user_canlogin';
+SELECT rolname, rolsuper, rolinherit, rolcreaterole, rolcreatedb, rolcanlogin, rolreplication, rolbypassrls, rolconnlimit, rolpassword, rolvaliduntil FROM pg_authid WHERE rolname = 'regress_test_user_canlogin';
           rolname           | rolsuper | rolinherit | rolcreaterole | rolcreatedb | rolcanlogin | rolreplication | rolbypassrls | rolconnlimit | rolpassword | rolvaliduntil 
 ----------------------------+----------+------------+---------------+-------------+-------------+----------------+--------------+--------------+-------------+---------------
  regress_test_user_canlogin | f        | t          | f             | f           | t           | f              | f            |           -1 |             | 
 (1 row)
 
 ALTER USER regress_test_user_canlogin WITH NOLOGIN;
-SELECT * FROM pg_authid WHERE rolname = 'regress_test_user_canlogin';
+SELECT rolname, rolsuper, rolinherit, rolcreaterole, rolcreatedb, rolcanlogin, rolreplication, rolbypassrls, rolconnlimit, rolpassword, rolvaliduntil FROM pg_authid WHERE rolname = 'regress_test_user_canlogin';
           rolname           | rolsuper | rolinherit | rolcreaterole | rolcreatedb | rolcanlogin | rolreplication | rolbypassrls | rolconnlimit | rolpassword | rolvaliduntil 
 ----------------------------+----------+------------+---------------+-------------+-------------+----------------+--------------+--------------+-------------+---------------
  regress_test_user_canlogin | f        | t          | f             | f           | f           | f              | f            |           -1 |             | 
@@ -174,28 +174,28 @@ SELECT * FROM pg_authid WHERE rolname = 'regress_test_user_canlogin';
 
 -- default for replication is false
 CREATE ROLE regress_test_def_replication;
-SELECT * FROM pg_authid WHERE rolname = 'regress_test_def_replication';
+SELECT rolname, rolsuper, rolinherit, rolcreaterole, rolcreatedb, rolcanlogin, rolreplication, rolbypassrls, rolconnlimit, rolpassword, rolvaliduntil FROM pg_authid WHERE rolname = 'regress_test_def_replication';
            rolname            | rolsuper | rolinherit | rolcreaterole | rolcreatedb | rolcanlogin | rolreplication | rolbypassrls | rolconnlimit | rolpassword | rolvaliduntil 
 ------------------------------+----------+------------+---------------+-------------+-------------+----------------+--------------+--------------+-------------+---------------
  regress_test_def_replication | f        | t          | f             | f           | f           | f              | f            |           -1 |             | 
 (1 row)
 
 CREATE ROLE regress_test_replication WITH REPLICATION;
-SELECT * FROM pg_authid WHERE rolname = 'regress_test_replication';
+SELECT rolname, rolsuper, rolinherit, rolcreaterole, rolcreatedb, rolcanlogin, rolreplication, rolbypassrls, rolconnlimit, rolpassword, rolvaliduntil FROM pg_authid WHERE rolname = 'regress_test_replication';
          rolname          | rolsuper | rolinherit | rolcreaterole | rolcreatedb | rolcanlogin | rolreplication | rolbypassrls | rolconnlimit | rolpassword | rolvaliduntil 
 --------------------------+----------+------------+---------------+-------------+-------------+----------------+--------------+--------------+-------------+---------------
  regress_test_replication | f        | t          | f             | f           | f           | t              | f            |           -1 |             | 
 (1 row)
 
 ALTER ROLE regress_test_replication WITH NOREPLICATION;
-SELECT * FROM pg_authid WHERE rolname = 'regress_test_replication';
+SELECT rolname, rolsuper, rolinherit, rolcreaterole, rolcreatedb, rolcanlogin, rolreplication, rolbypassrls, rolconnlimit, rolpassword, rolvaliduntil FROM pg_authid WHERE rolname = 'regress_test_replication';
          rolname          | rolsuper | rolinherit | rolcreaterole | rolcreatedb | rolcanlogin | rolreplication | rolbypassrls | rolconnlimit | rolpassword | rolvaliduntil 
 --------------------------+----------+------------+---------------+-------------+-------------+----------------+--------------+--------------+-------------+---------------
  regress_test_replication | f        | t          | f             | f           | f           | f              | f            |           -1 |             | 
 (1 row)
 
 ALTER ROLE regress_test_replication WITH REPLICATION;
-SELECT * FROM pg_authid WHERE rolname = 'regress_test_replication';
+SELECT rolname, rolsuper, rolinherit, rolcreaterole, rolcreatedb, rolcanlogin, rolreplication, rolbypassrls, rolconnlimit, rolpassword, rolvaliduntil FROM pg_authid WHERE rolname = 'regress_test_replication';
          rolname          | rolsuper | rolinherit | rolcreaterole | rolcreatedb | rolcanlogin | rolreplication | rolbypassrls | rolconnlimit | rolpassword | rolvaliduntil 
 --------------------------+----------+------------+---------------+-------------+-------------+----------------+--------------+--------------+-------------+---------------
  regress_test_replication | f        | t          | f             | f           | f           | t              | f            |           -1 |             | 
@@ -203,28 +203,28 @@ SELECT * FROM pg_authid WHERE rolname = 'regress_test_replication';
 
 -- default for bypassrls is false
 CREATE ROLE regress_test_def_bypassrls;
-SELECT * FROM pg_authid WHERE rolname = 'regress_test_def_bypassrls';
+SELECT rolname, rolsuper, rolinherit, rolcreaterole, rolcreatedb, rolcanlogin, rolreplication, rolbypassrls, rolconnlimit, rolpassword, rolvaliduntil FROM pg_authid WHERE rolname = 'regress_test_def_bypassrls';
           rolname           | rolsuper | rolinherit | rolcreaterole | rolcreatedb | rolcanlogin | rolreplication | rolbypassrls | rolconnlimit | rolpassword | rolvaliduntil 
 ----------------------------+----------+------------+---------------+-------------+-------------+----------------+--------------+--------------+-------------+---------------
  regress_test_def_bypassrls | f        | t          | f             | f           | f           | f              | f            |           -1 |             | 
 (1 row)
 
 CREATE ROLE regress_test_bypassrls WITH BYPASSRLS;
-SELECT * FROM pg_authid WHERE rolname = 'regress_test_bypassrls';
+SELECT rolname, rolsuper, rolinherit, rolcreaterole, rolcreatedb, rolcanlogin, rolreplication, rolbypassrls, rolconnlimit, rolpassword, rolvaliduntil FROM pg_authid WHERE rolname = 'regress_test_bypassrls';
         rolname         | rolsuper | rolinherit | rolcreaterole | rolcreatedb | rolcanlogin | rolreplication | rolbypassrls | rolconnlimit | rolpassword | rolvaliduntil 
 ------------------------+----------+------------+---------------+-------------+-------------+----------------+--------------+--------------+-------------+---------------
  regress_test_bypassrls | f        | t          | f             | f           | f           | f              | t            |           -1 |             | 
 (1 row)
 
 ALTER ROLE regress_test_bypassrls WITH NOBYPASSRLS;
-SELECT * FROM pg_authid WHERE rolname = 'regress_test_bypassrls';
+SELECT rolname, rolsuper, rolinherit, rolcreaterole, rolcreatedb, rolcanlogin, rolreplication, rolbypassrls, rolconnlimit, rolpassword, rolvaliduntil FROM pg_authid WHERE rolname = 'regress_test_bypassrls';
         rolname         | rolsuper | rolinherit | rolcreaterole | rolcreatedb | rolcanlogin | rolreplication | rolbypassrls | rolconnlimit | rolpassword | rolvaliduntil 
 ------------------------+----------+------------+---------------+-------------+-------------+----------------+--------------+--------------+-------------+---------------
  regress_test_bypassrls | f        | t          | f             | f           | f           | f              | f            |           -1 |             | 
 (1 row)
 
 ALTER ROLE regress_test_bypassrls WITH BYPASSRLS;
-SELECT * FROM pg_authid WHERE rolname = 'regress_test_bypassrls';
+SELECT rolname, rolsuper, rolinherit, rolcreaterole, rolcreatedb, rolcanlogin, rolreplication, rolbypassrls, rolconnlimit, rolpassword, rolvaliduntil FROM pg_authid WHERE rolname = 'regress_test_bypassrls';
         rolname         | rolsuper | rolinherit | rolcreaterole | rolcreatedb | rolcanlogin | rolreplication | rolbypassrls | rolconnlimit | rolpassword | rolvaliduntil 
 ------------------------+----------+------------+---------------+-------------+-------------+----------------+--------------+--------------+-------------+---------------
  regress_test_bypassrls | f        | t          | f             | f           | f           | f              | t            |           -1 |             | 
diff --git a/src/test/regress/expected/rowsecurity.out b/src/test/regress/expected/rowsecurity.out
index bc16ca4c43f..233672e9d0a 100644
--- a/src/test/regress/expected/rowsecurity.out
+++ b/src/test/regress/expected/rowsecurity.out
@@ -632,30 +632,30 @@ SELECT * FROM category;
 --
 SET SESSION AUTHORIZATION regress_rls_alice;
 SET row_security TO ON;
-CREATE TABLE t1 (a int, junk1 text, b text) WITH OIDS;
+CREATE TABLE t1 (id int not null primary key, a int, junk1 text, b text);
 ALTER TABLE t1 DROP COLUMN junk1;    -- just a disturbing factor
 GRANT ALL ON t1 TO public;
-COPY t1 FROM stdin WITH (oids);
+COPY t1 FROM stdin WITH ;
 CREATE TABLE t2 (c float) INHERITS (t1);
 GRANT ALL ON t2 TO public;
-COPY t2 FROM stdin WITH (oids);
-CREATE TABLE t3 (c text, b text, a int) WITH OIDS;
+COPY t2 FROM stdin;
+CREATE TABLE t3 (id int not null primary key, c text, b text, a int);
 ALTER TABLE t3 INHERIT t1;
 GRANT ALL ON t3 TO public;
-COPY t3(a,b,c) FROM stdin WITH (oids);
+COPY t3(id, a,b,c) FROM stdin;
 CREATE POLICY p1 ON t1 FOR ALL TO PUBLIC USING (a % 2 = 0); -- be even number
 CREATE POLICY p2 ON t2 FOR ALL TO PUBLIC USING (a % 2 = 1); -- be odd number
 ALTER TABLE t1 ENABLE ROW LEVEL SECURITY;
 ALTER TABLE t2 ENABLE ROW LEVEL SECURITY;
 SET SESSION AUTHORIZATION regress_rls_bob;
 SELECT * FROM t1;
- a |  b  
----+-----
- 2 | bbb
- 4 | dad
- 2 | bcd
- 4 | def
- 2 | yyy
+ id  | a |  b  
+-----+---+-----
+ 102 | 2 | bbb
+ 104 | 4 | dad
+ 202 | 2 | bcd
+ 204 | 4 | def
+ 302 | 2 | yyy
 (5 rows)
 
 EXPLAIN (COSTS OFF) SELECT * FROM t1;
@@ -676,13 +676,13 @@ NOTICE:  f_leak => dad
 NOTICE:  f_leak => bcd
 NOTICE:  f_leak => def
 NOTICE:  f_leak => yyy
- a |  b  
----+-----
- 2 | bbb
- 4 | dad
- 2 | bcd
- 4 | def
- 2 | yyy
+ id  | a |  b  
+-----+---+-----
+ 102 | 2 | bbb
+ 104 | 4 | dad
+ 202 | 2 | bcd
+ 204 | 4 | def
+ 302 | 2 | yyy
 (5 rows)
 
 EXPLAIN (COSTS OFF) SELECT * FROM t1 WHERE f_leak(b);
@@ -698,14 +698,14 @@ EXPLAIN (COSTS OFF) SELECT * FROM t1 WHERE f_leak(b);
 (7 rows)
 
 -- reference to system column
-SELECT oid, * FROM t1;
- oid | a |  b  
------+---+-----
- 102 | 2 | bbb
- 104 | 4 | dad
- 202 | 2 | bcd
- 204 | 4 | def
- 302 | 2 | yyy
+SELECT tableoid::regclass, * FROM t1;
+ tableoid | id  | a |  b  
+----------+-----+---+-----
+ t1       | 102 | 2 | bbb
+ t1       | 104 | 4 | dad
+ t2       | 202 | 2 | bcd
+ t2       | 204 | 4 | def
+ t3       | 302 | 2 | yyy
 (5 rows)
 
 EXPLAIN (COSTS OFF) SELECT *, t1 FROM t1;
@@ -722,13 +722,13 @@ EXPLAIN (COSTS OFF) SELECT *, t1 FROM t1;
 
 -- reference to whole-row reference
 SELECT *, t1 FROM t1;
- a |  b  |   t1    
----+-----+---------
- 2 | bbb | (2,bbb)
- 4 | dad | (4,dad)
- 2 | bcd | (2,bcd)
- 4 | def | (4,def)
- 2 | yyy | (2,yyy)
+ id  | a |  b  |     t1      
+-----+---+-----+-------------
+ 102 | 2 | bbb | (102,2,bbb)
+ 104 | 4 | dad | (104,4,dad)
+ 202 | 2 | bcd | (202,2,bcd)
+ 204 | 4 | def | (204,4,def)
+ 302 | 2 | yyy | (302,2,yyy)
 (5 rows)
 
 EXPLAIN (COSTS OFF) SELECT *, t1 FROM t1;
@@ -745,13 +745,13 @@ EXPLAIN (COSTS OFF) SELECT *, t1 FROM t1;
 
 -- for share/update lock
 SELECT * FROM t1 FOR SHARE;
- a |  b  
----+-----
- 2 | bbb
- 4 | dad
- 2 | bcd
- 4 | def
- 2 | yyy
+ id  | a |  b  
+-----+---+-----
+ 102 | 2 | bbb
+ 104 | 4 | dad
+ 202 | 2 | bcd
+ 204 | 4 | def
+ 302 | 2 | yyy
 (5 rows)
 
 EXPLAIN (COSTS OFF) SELECT * FROM t1 FOR SHARE;
@@ -773,13 +773,13 @@ NOTICE:  f_leak => dad
 NOTICE:  f_leak => bcd
 NOTICE:  f_leak => def
 NOTICE:  f_leak => yyy
- a |  b  
----+-----
- 2 | bbb
- 4 | dad
- 2 | bcd
- 4 | def
- 2 | yyy
+ id  | a |  b  
+-----+---+-----
+ 102 | 2 | bbb
+ 104 | 4 | dad
+ 202 | 2 | bcd
+ 204 | 4 | def
+ 302 | 2 | yyy
 (5 rows)
 
 EXPLAIN (COSTS OFF) SELECT * FROM t1 WHERE f_leak(b) FOR SHARE;
@@ -796,17 +796,17 @@ EXPLAIN (COSTS OFF) SELECT * FROM t1 WHERE f_leak(b) FOR SHARE;
 (8 rows)
 
 -- union all query
-SELECT a, b, oid FROM t2 UNION ALL SELECT a, b, oid FROM t3;
- a |  b  | oid 
----+-----+-----
- 1 | abc | 201
- 3 | cde | 203
- 1 | xxx | 301
- 2 | yyy | 302
- 3 | zzz | 303
+SELECT a, b, tableoid::regclass FROM t2 UNION ALL SELECT a, b, tableoid::regclass FROM t3;
+ a |  b  | tableoid 
+---+-----+----------
+ 1 | abc | t2
+ 3 | cde | t2
+ 1 | xxx | t3
+ 2 | yyy | t3
+ 3 | zzz | t3
 (5 rows)
 
-EXPLAIN (COSTS OFF) SELECT a, b, oid FROM t2 UNION ALL SELECT a, b, oid FROM t3;
+EXPLAIN (COSTS OFF) SELECT a, b, tableoid::regclass FROM t2 UNION ALL SELECT a, b, tableoid::regclass FROM t3;
           QUERY PLAN           
 -------------------------------
  Append
@@ -830,19 +830,19 @@ NOTICE:  f_leak => def
 NOTICE:  f_leak => xxx
 NOTICE:  f_leak => yyy
 NOTICE:  f_leak => zzz
- a |  b  
----+-----
- 1 | aba
- 2 | bbb
- 3 | ccc
- 4 | dad
- 1 | abc
- 2 | bcd
- 3 | cde
- 4 | def
- 1 | xxx
- 2 | yyy
- 3 | zzz
+ id  | a |  b  
+-----+---+-----
+ 101 | 1 | aba
+ 102 | 2 | bbb
+ 103 | 3 | ccc
+ 104 | 4 | dad
+ 201 | 1 | abc
+ 202 | 2 | bcd
+ 203 | 3 | cde
+ 204 | 4 | def
+ 301 | 1 | xxx
+ 302 | 2 | yyy
+ 303 | 3 | zzz
 (11 rows)
 
 EXPLAIN (COSTS OFF) SELECT * FROM t1 WHERE f_leak(b);
@@ -872,19 +872,19 @@ NOTICE:  f_leak => def
 NOTICE:  f_leak => xxx
 NOTICE:  f_leak => yyy
 NOTICE:  f_leak => zzz
- a |  b  
----+-----
- 1 | aba
- 2 | bbb
- 3 | ccc
- 4 | dad
- 1 | abc
- 2 | bcd
- 3 | cde
- 4 | def
- 1 | xxx
- 2 | yyy
- 3 | zzz
+ id  | a |  b  
+-----+---+-----
+ 101 | 1 | aba
+ 102 | 2 | bbb
+ 103 | 3 | ccc
+ 104 | 4 | dad
+ 201 | 1 | abc
+ 202 | 2 | bcd
+ 203 | 3 | cde
+ 204 | 4 | def
+ 301 | 1 | xxx
+ 302 | 2 | yyy
+ 303 | 3 | zzz
 (11 rows)
 
 EXPLAIN (COSTS OFF) SELECT * FROM t1 WHERE f_leak(b);
@@ -1500,11 +1500,11 @@ ERROR:  infinite recursion detected in policy for relation "s1"
 -- prepared statement with regress_rls_alice privilege
 PREPARE p1(int) AS SELECT * FROM t1 WHERE a <= $1;
 EXECUTE p1(2);
- a |  b  
----+-----
- 2 | bbb
- 2 | bcd
- 2 | yyy
+ id  | a |  b  
+-----+---+-----
+ 102 | 2 | bbb
+ 202 | 2 | bcd
+ 302 | 2 | yyy
 (3 rows)
 
 EXPLAIN (COSTS OFF) EXECUTE p1(2);
@@ -1534,19 +1534,19 @@ NOTICE:  f_leak => def
 NOTICE:  f_leak => xxx
 NOTICE:  f_leak => yyy
 NOTICE:  f_leak => zzz
- a |  b  
----+-----
- 1 | aba
- 2 | bbb
- 3 | ccc
- 4 | dad
- 1 | abc
- 2 | bcd
- 3 | cde
- 4 | def
- 1 | xxx
- 2 | yyy
- 3 | zzz
+ id  | a |  b  
+-----+---+-----
+ 101 | 1 | aba
+ 102 | 2 | bbb
+ 103 | 3 | ccc
+ 104 | 4 | dad
+ 201 | 1 | abc
+ 202 | 2 | bcd
+ 203 | 3 | cde
+ 204 | 4 | def
+ 301 | 1 | xxx
+ 302 | 2 | yyy
+ 303 | 3 | zzz
 (11 rows)
 
 EXPLAIN (COSTS OFF) SELECT * FROM t1 WHERE f_leak(b);
@@ -1563,14 +1563,14 @@ EXPLAIN (COSTS OFF) SELECT * FROM t1 WHERE f_leak(b);
 
 -- plan cache should be invalidated
 EXECUTE p1(2);
- a |  b  
----+-----
- 1 | aba
- 2 | bbb
- 1 | abc
- 2 | bcd
- 1 | xxx
- 2 | yyy
+ id  | a |  b  
+-----+---+-----
+ 101 | 1 | aba
+ 102 | 2 | bbb
+ 201 | 1 | abc
+ 202 | 2 | bcd
+ 301 | 1 | xxx
+ 302 | 2 | yyy
 (6 rows)
 
 EXPLAIN (COSTS OFF) EXECUTE p1(2);
@@ -1587,11 +1587,11 @@ EXPLAIN (COSTS OFF) EXECUTE p1(2);
 
 PREPARE p2(int) AS SELECT * FROM t1 WHERE a = $1;
 EXECUTE p2(2);
- a |  b  
----+-----
- 2 | bbb
- 2 | bcd
- 2 | yyy
+ id  | a |  b  
+-----+---+-----
+ 102 | 2 | bbb
+ 202 | 2 | bcd
+ 302 | 2 | yyy
 (3 rows)
 
 EXPLAIN (COSTS OFF) EXECUTE p2(2);
@@ -1610,11 +1610,11 @@ EXPLAIN (COSTS OFF) EXECUTE p2(2);
 SET SESSION AUTHORIZATION regress_rls_bob;
 SET row_security TO ON;
 EXECUTE p2(2);
- a |  b  
----+-----
- 2 | bbb
- 2 | bcd
- 2 | yyy
+ id  | a |  b  
+-----+---+-----
+ 102 | 2 | bbb
+ 202 | 2 | bcd
+ 302 | 2 | yyy
 (3 rows)
 
 EXPLAIN (COSTS OFF) EXECUTE p2(2);
@@ -1666,13 +1666,13 @@ UPDATE only t1 SET b = b || '_updt' WHERE f_leak(b);
 NOTICE:  f_leak => bbbbbb
 NOTICE:  f_leak => daddad
 -- returning clause with system column
-UPDATE only t1 SET b = b WHERE f_leak(b) RETURNING oid, *, t1;
+UPDATE only t1 SET b = b WHERE f_leak(b) RETURNING tableoid::regclass, *, t1;
 NOTICE:  f_leak => bbbbbb_updt
 NOTICE:  f_leak => daddad_updt
- oid | a |      b      |       t1        
------+---+-------------+-----------------
- 102 | 2 | bbbbbb_updt | (2,bbbbbb_updt)
- 104 | 4 | daddad_updt | (4,daddad_updt)
+ tableoid | id  | a |      b      |         t1          
+----------+-----+---+-------------+---------------------
+ t1       | 102 | 2 | bbbbbb_updt | (102,2,bbbbbb_updt)
+ t1       | 104 | 4 | daddad_updt | (104,4,daddad_updt)
 (2 rows)
 
 UPDATE t1 SET b = b WHERE f_leak(b) RETURNING *;
@@ -1681,28 +1681,28 @@ NOTICE:  f_leak => daddad_updt
 NOTICE:  f_leak => bcdbcd
 NOTICE:  f_leak => defdef
 NOTICE:  f_leak => yyyyyy
- a |      b      
----+-------------
- 2 | bbbbbb_updt
- 4 | daddad_updt
- 2 | bcdbcd
- 4 | defdef
- 2 | yyyyyy
+ id  | a |      b      
+-----+---+-------------
+ 102 | 2 | bbbbbb_updt
+ 104 | 4 | daddad_updt
+ 202 | 2 | bcdbcd
+ 204 | 4 | defdef
+ 302 | 2 | yyyyyy
 (5 rows)
 
-UPDATE t1 SET b = b WHERE f_leak(b) RETURNING oid, *, t1;
+UPDATE t1 SET b = b WHERE f_leak(b) RETURNING tableoid::regclass, *, t1;
 NOTICE:  f_leak => bbbbbb_updt
 NOTICE:  f_leak => daddad_updt
 NOTICE:  f_leak => bcdbcd
 NOTICE:  f_leak => defdef
 NOTICE:  f_leak => yyyyyy
- oid | a |      b      |       t1        
------+---+-------------+-----------------
- 102 | 2 | bbbbbb_updt | (2,bbbbbb_updt)
- 104 | 4 | daddad_updt | (4,daddad_updt)
- 202 | 2 | bcdbcd      | (2,bcdbcd)
- 204 | 4 | defdef      | (4,defdef)
- 302 | 2 | yyyyyy      | (2,yyyyyy)
+ tableoid | id  | a |      b      |         t1          
+----------+-----+---+-------------+---------------------
+ t1       | 102 | 2 | bbbbbb_updt | (102,2,bbbbbb_updt)
+ t1       | 104 | 4 | daddad_updt | (104,4,daddad_updt)
+ t2       | 202 | 2 | bcdbcd      | (202,2,bcdbcd)
+ t2       | 204 | 4 | defdef      | (204,4,defdef)
+ t3       | 302 | 2 | yyyyyy      | (302,2,yyyyyy)
 (5 rows)
 
 -- updates with from clause
@@ -1789,9 +1789,9 @@ WHERE t2_1.a = 3 AND t2_2.a = t2_1.a AND t2_2.b = t2_1.b
 AND f_leak(t2_1.b) AND f_leak(t2_2.b) RETURNING *, t2_1, t2_2;
 NOTICE:  f_leak => cde
 NOTICE:  f_leak => cde
- a |  b  |  c  | a |  b  |  c  |    t2_1     |    t2_2     
----+-----+-----+---+-----+-----+-------------+-------------
- 3 | cde | 3.3 | 3 | cde | 3.3 | (3,cde,3.3) | (3,cde,3.3)
+ id  | a |  b  |  c  | id  | a |  b  |  c  |      t2_1       |      t2_2       
+-----+---+-----+-----+-----+---+-----+-----+-----------------+-----------------
+ 203 | 3 | cde | 3.3 | 203 | 3 | cde | 3.3 | (203,3,cde,3.3) | (203,3,cde,3.3)
 (1 row)
 
 EXPLAIN (COSTS OFF) UPDATE t1 t1_1 SET b = t1_2.b FROM t1 t1_2
@@ -1847,28 +1847,28 @@ NOTICE:  f_leak => defdef
 NOTICE:  f_leak => defdef
 NOTICE:  f_leak => daddad_updt
 NOTICE:  f_leak => defdef
- a |      b      | a |      b      |      t1_1       |      t1_2       
----+-------------+---+-------------+-----------------+-----------------
- 4 | daddad_updt | 4 | daddad_updt | (4,daddad_updt) | (4,daddad_updt)
- 4 | defdef      | 4 | defdef      | (4,defdef)      | (4,defdef)
+ id  | a |      b      | id  | a |      b      |        t1_1         |        t1_2         
+-----+---+-------------+-----+---+-------------+---------------------+---------------------
+ 104 | 4 | daddad_updt | 104 | 4 | daddad_updt | (104,4,daddad_updt) | (104,4,daddad_updt)
+ 204 | 4 | defdef      | 204 | 4 | defdef      | (204,4,defdef)      | (204,4,defdef)
 (2 rows)
 
 RESET SESSION AUTHORIZATION;
 SET row_security TO OFF;
 SELECT * FROM t1 ORDER BY a,b;
- a |      b      
----+-------------
- 1 | aba
- 1 | abc
- 1 | xxx
- 2 | bbbbbb_updt
- 2 | bcdbcd
- 2 | yyyyyy
- 3 | ccc
- 3 | cde
- 3 | zzz
- 4 | daddad_updt
- 4 | defdef
+ id  | a |      b      
+-----+---+-------------
+ 101 | 1 | aba
+ 201 | 1 | abc
+ 301 | 1 | xxx
+ 102 | 2 | bbbbbb_updt
+ 202 | 2 | bcdbcd
+ 302 | 2 | yyyyyy
+ 103 | 3 | ccc
+ 203 | 3 | cde
+ 303 | 3 | zzz
+ 104 | 4 | daddad_updt
+ 204 | 4 | defdef
 (11 rows)
 
 SET SESSION AUTHORIZATION regress_rls_bob;
@@ -1896,24 +1896,24 @@ EXPLAIN (COSTS OFF) DELETE FROM t1 WHERE f_leak(b);
          Filter: (((a % 2) = 0) AND f_leak(b))
 (10 rows)
 
-DELETE FROM only t1 WHERE f_leak(b) RETURNING oid, *, t1;
+DELETE FROM only t1 WHERE f_leak(b) RETURNING tableoid::regclass, *, t1;
 NOTICE:  f_leak => bbbbbb_updt
 NOTICE:  f_leak => daddad_updt
- oid | a |      b      |       t1        
------+---+-------------+-----------------
- 102 | 2 | bbbbbb_updt | (2,bbbbbb_updt)
- 104 | 4 | daddad_updt | (4,daddad_updt)
+ tableoid | id  | a |      b      |         t1          
+----------+-----+---+-------------+---------------------
+ t1       | 102 | 2 | bbbbbb_updt | (102,2,bbbbbb_updt)
+ t1       | 104 | 4 | daddad_updt | (104,4,daddad_updt)
 (2 rows)
 
-DELETE FROM t1 WHERE f_leak(b) RETURNING oid, *, t1;
+DELETE FROM t1 WHERE f_leak(b) RETURNING tableoid::regclass, *, t1;
 NOTICE:  f_leak => bcdbcd
 NOTICE:  f_leak => defdef
 NOTICE:  f_leak => yyyyyy
- oid | a |   b    |     t1     
------+---+--------+------------
- 202 | 2 | bcdbcd | (2,bcdbcd)
- 204 | 4 | defdef | (4,defdef)
- 302 | 2 | yyyyyy | (2,yyyyyy)
+ tableoid | id  | a |   b    |       t1       
+----------+-----+---+--------+----------------
+ t2       | 202 | 2 | bcdbcd | (202,2,bcdbcd)
+ t2       | 204 | 4 | defdef | (204,4,defdef)
+ t3       | 302 | 2 | yyyyyy | (302,2,yyyyyy)
 (3 rows)
 
 --
diff --git a/src/test/regress/expected/rowtypes.out b/src/test/regress/expected/rowtypes.out
index 30053d07dff..d6a1a3331e3 100644
--- a/src/test/regress/expected/rowtypes.out
+++ b/src/test/regress/expected/rowtypes.out
@@ -1067,7 +1067,7 @@ select r, r is null as isnull, r is not null as isnotnull from r;
 --
 -- Tests for component access / FieldSelect
 --
-CREATE TABLE compositetable(a text, b text) WITH OIDS;
+CREATE TABLE compositetable(a text, b text);
 INSERT INTO compositetable(a, b) VALUES('fa', 'fb');
 -- composite type columns can't directly be accessed (error)
 SELECT d.a FROM (SELECT compositetable AS d FROM compositetable) s;
@@ -1081,10 +1081,10 @@ SELECT (d).a, (d).b FROM (SELECT compositetable AS d FROM compositetable) s;
  fa | fb
 (1 row)
 
--- oids can't be accessed in composite types (error)
-SELECT (d).oid FROM (SELECT compositetable AS d FROM compositetable) s;
-ERROR:  column "oid" not found in data type compositetable
-LINE 1: SELECT (d).oid FROM (SELECT compositetable AS d FROM composi...
+-- system columns can't be accessed in composite types (error)
+SELECT (d).ctid FROM (SELECT compositetable AS d FROM compositetable) s;
+ERROR:  column "ctid" not found in data type compositetable
+LINE 1: SELECT (d).ctid FROM (SELECT compositetable AS d FROM compos...
                 ^
 -- accessing non-existing column in NULL datum errors out
 SELECT (NULL::compositetable).nonexistant;
diff --git a/src/test/regress/expected/sanity_check.out b/src/test/regress/expected/sanity_check.out
index 9c7a60c092d..c77060d36c1 100644
--- a/src/test/regress/expected/sanity_check.out
+++ b/src/test/regress/expected/sanity_check.out
@@ -213,12 +213,12 @@ varchar_tbl|f
 -- We exclude non-system tables from the check by looking at nspname.
 --
 SELECT relname, nspname
-FROM pg_class c LEFT JOIN pg_namespace n ON n.oid = relnamespace
-WHERE relhasoids
-    AND ((nspname ~ '^pg_') IS NOT FALSE)
-    AND NOT EXISTS (SELECT 1 FROM pg_index i WHERE indrelid = c.oid
-                    AND indkey[0] = -2 AND indnatts = 1
-                    AND indisunique AND indimmediate);
+ FROM pg_class c LEFT JOIN pg_namespace n ON n.oid = relnamespace JOIN pg_attribute a ON (attrelid = c.oid AND attname = 'oid')
+ WHERE relkind = 'r' and c.oid < 16384
+     AND ((nspname ~ '^pg_') IS NOT FALSE)
+     AND NOT EXISTS (SELECT 1 FROM pg_index i WHERE indrelid = c.oid
+                     AND indkey[0] = a.attnum AND indnatts = 1
+                     AND indisunique AND indimmediate);
  relname | nspname 
 ---------+---------
 (0 rows)
diff --git a/src/test/regress/expected/triggers.out b/src/test/regress/expected/triggers.out
index 7d59de98ebd..c62f88c169a 100644
--- a/src/test/regress/expected/triggers.out
+++ b/src/test/regress/expected/triggers.out
@@ -441,11 +441,11 @@ DROP TRIGGER delete_a ON main_table;
 DROP TRIGGER insert_when ON main_table;
 DROP TRIGGER delete_when ON main_table;
 -- Test WHEN condition accessing system columns.
-create table table_with_oids(a int) with oids;
+create table table_with_oids(a int);
 insert into table_with_oids values (1);
 create trigger oid_unchanged_trig after update on table_with_oids
 	for each row
-	when (new.oid = old.oid AND new.oid <> 0)
+	when (new.tableoid = old.tableoid AND new.tableoid <> 0)
 	execute procedure trigger_func('after_upd_oid_unchanged');
 update table_with_oids set a = a + 1;
 NOTICE:  trigger_func(after_upd_oid_unchanged) called: action = UPDATE, when = AFTER, level = ROW
@@ -834,18 +834,10 @@ CREATE TABLE min_updates_test (
 	f1	text,
 	f2 int,
 	f3 int);
-CREATE TABLE min_updates_test_oids (
-	f1	text,
-	f2 int,
-	f3 int) WITH OIDS;
 INSERT INTO min_updates_test VALUES ('a',1,2),('b','2',null);
-INSERT INTO min_updates_test_oids VALUES ('a',1,2),('b','2',null);
 CREATE TRIGGER z_min_update
 BEFORE UPDATE ON min_updates_test
 FOR EACH ROW EXECUTE PROCEDURE suppress_redundant_updates_trigger();
-CREATE TRIGGER z_min_update
-BEFORE UPDATE ON min_updates_test_oids
-FOR EACH ROW EXECUTE PROCEDURE suppress_redundant_updates_trigger();
 \set QUIET false
 UPDATE min_updates_test SET f1 = f1;
 UPDATE 0
@@ -853,12 +845,6 @@ UPDATE min_updates_test SET f2 = f2 + 1;
 UPDATE 2
 UPDATE min_updates_test SET f3 = 2 WHERE f3 is null;
 UPDATE 1
-UPDATE min_updates_test_oids SET f1 = f1;
-UPDATE 0
-UPDATE min_updates_test_oids SET f2 = f2 + 1;
-UPDATE 2
-UPDATE min_updates_test_oids SET f3 = 2 WHERE f3 is null;
-UPDATE 1
 \set QUIET true
 SELECT * FROM min_updates_test;
  f1 | f2 | f3 
@@ -867,15 +853,7 @@ SELECT * FROM min_updates_test;
  b  |  3 |  2
 (2 rows)
 
-SELECT * FROM min_updates_test_oids;
- f1 | f2 | f3 
-----+----+----
- a  |  2 |  2
- b  |  3 |  2
-(2 rows)
-
 DROP TABLE min_updates_test;
-DROP TABLE min_updates_test_oids;
 --
 -- Test triggers on views
 --
diff --git a/src/test/regress/expected/without_oid.out b/src/test/regress/expected/without_oid.out
deleted file mode 100644
index cb2c0c01371..00000000000
--- a/src/test/regress/expected/without_oid.out
+++ /dev/null
@@ -1,103 +0,0 @@
---
--- WITHOUT OID
---
---
--- This test tries to verify that WITHOUT OIDS actually saves space.
--- On machines where MAXALIGN is 8, WITHOUT OIDS may or may not save any
--- space, depending on the size of the tuple header + null bitmap.
--- As of 8.3 we need a null bitmap of 8 or less bits for the difference
--- to appear.
---
-CREATE TABLE wi (i INT,
-                 n1 int, n2 int, n3 int, n4 int,
-                 n5 int, n6 int, n7 int) WITH OIDS;
-CREATE TABLE wo (i INT,
-                 n1 int, n2 int, n3 int, n4 int,
-                 n5 int, n6 int, n7 int) WITHOUT OIDS;
-INSERT INTO wi VALUES (1);  -- 1
-INSERT INTO wo SELECT i FROM wi;  -- 1
-INSERT INTO wo SELECT i+1 FROM wi;  -- 1+1=2
-INSERT INTO wi SELECT i+1 FROM wo;  -- 1+2=3
-INSERT INTO wi SELECT i+3 FROM wi;  -- 3+3=6
-INSERT INTO wo SELECT i+2 FROM wi;  -- 2+6=8
-INSERT INTO wo SELECT i+8 FROM wo;  -- 8+8=16
-INSERT INTO wi SELECT i+6 FROM wo;  -- 6+16=22
-INSERT INTO wi SELECT i+22 FROM wi;  -- 22+22=44
-INSERT INTO wo SELECT i+16 FROM wi;  -- 16+44=60
-INSERT INTO wo SELECT i+60 FROM wo;  -- 60+60=120
-INSERT INTO wi SELECT i+44 FROM wo;  -- 44+120=164
-INSERT INTO wi SELECT i+164 FROM wi;  -- 164+164=328
-INSERT INTO wo SELECT i+120 FROM wi;  -- 120+328=448
-INSERT INTO wo SELECT i+448 FROM wo;  -- 448+448=896
-INSERT INTO wi SELECT i+328 FROM wo;  -- 328+896=1224
-INSERT INTO wi SELECT i+1224 FROM wi;  -- 1224+1224=2448
-INSERT INTO wo SELECT i+896 FROM wi;  -- 896+2448=3344
-INSERT INTO wo SELECT i+3344 FROM wo;  -- 3344+3344=6688
-INSERT INTO wi SELECT i+2448 FROM wo;  -- 2448+6688=9136
-INSERT INTO wo SELECT i+6688 FROM wi WHERE i<=2448;  -- 6688+2448=9136
-SELECT count(oid) FROM wi;
- count 
--------
-  9136
-(1 row)
-
--- should fail
-SELECT count(oid) FROM wo;
-ERROR:  column "oid" does not exist
-LINE 1: SELECT count(oid) FROM wo;
-                     ^
-VACUUM ANALYZE wi;
-VACUUM ANALYZE wo;
-SELECT min(relpages) < max(relpages), min(reltuples) - max(reltuples)
-  FROM pg_class
- WHERE relname IN ('wi', 'wo');
- ?column? | ?column? 
-----------+----------
- t        |        0
-(1 row)
-
-DROP TABLE wi;
-DROP TABLE wo;
---
--- WITH / WITHOUT OIDS in CREATE TABLE AS
---
-CREATE TABLE create_table_test (
-    a int,
-    b int
-);
-COPY create_table_test FROM stdin;
-CREATE TABLE create_table_test2 WITH OIDS AS
-    SELECT a + b AS c1, a - b AS c2 FROM create_table_test;
-CREATE TABLE create_table_test3 WITHOUT OIDS AS
-    SELECT a + b AS c1, a - b AS c2 FROM create_table_test;
-SELECT count(oid) FROM create_table_test2;
- count 
--------
-     2
-(1 row)
-
--- should fail
-SELECT count(oid) FROM create_table_test3;
-ERROR:  column "oid" does not exist
-LINE 1: SELECT count(oid) FROM create_table_test3;
-                     ^
-PREPARE table_source(int) AS
-    SELECT a + b AS c1, a - b AS c2, $1 AS c3 FROM create_table_test;
-CREATE TABLE execute_with WITH OIDS AS EXECUTE table_source(1);
-CREATE TABLE execute_without WITHOUT OIDS AS EXECUTE table_source(2);
-SELECT count(oid) FROM execute_with;
- count 
--------
-     2
-(1 row)
-
--- should fail
-SELECT count(oid) FROM execute_without;
-ERROR:  column "oid" does not exist
-LINE 1: SELECT count(oid) FROM execute_without;
-                     ^
-DROP TABLE create_table_test;
-DROP TABLE create_table_test2;
-DROP TABLE create_table_test3;
-DROP TABLE execute_with;
-DROP TABLE execute_without;
diff --git a/src/test/regress/parallel_schedule b/src/test/regress/parallel_schedule
index 289c658483c..cc0bbf5db9f 100644
--- a/src/test/regress/parallel_schedule
+++ b/src/test/regress/parallel_schedule
@@ -111,7 +111,7 @@ test: select_views portals_p2 foreign_key cluster dependency guc bitmapops combo
 # NB: temp.sql does a reconnect which transiently uses 2 connections,
 # so keep this parallel group to at most 19 tests
 # ----------
-test: plancache limit plpgsql copy2 temp domain rangefuncs prepare without_oid conversion truncate alter_table sequence polymorphism rowtypes returning largeobject with xml
+test: plancache limit plpgsql copy2 temp domain rangefuncs prepare conversion truncate alter_table sequence polymorphism rowtypes returning largeobject with xml
 
 # ----------
 # Another group of parallel tests
diff --git a/src/test/regress/serial_schedule b/src/test/regress/serial_schedule
index bc43b18c628..0c10c7100c6 100644
--- a/src/test/regress/serial_schedule
+++ b/src/test/regress/serial_schedule
@@ -166,7 +166,6 @@ test: temp
 test: domain
 test: rangefuncs
 test: prepare
-test: without_oid
 test: conversion
 test: truncate
 test: alter_table
diff --git a/src/test/regress/sql/alter_table.sql b/src/test/regress/sql/alter_table.sql
index 0352536fa5a..67e1a36f52d 100644
--- a/src/test/regress/sql/alter_table.sql
+++ b/src/test/regress/sql/alter_table.sql
@@ -626,7 +626,7 @@ drop table atacc1;
 
 -- test unique constraint adding
 
-create table atacc1 ( test int ) with oids;
+create table atacc1 ( test int ) ;
 -- add a unique constraint
 alter table atacc1 add constraint atacc_test1 unique (test);
 -- insert first value
@@ -635,8 +635,6 @@ insert into atacc1 (test) values (2);
 insert into atacc1 (test) values (2);
 -- should succeed
 insert into atacc1 (test) values (4);
--- try adding a unique oid constraint
-alter table atacc1 add constraint atacc_oid1 unique(oid);
 -- try to create duplicates via alter table using - should fail
 alter table atacc1 alter column test type integer using 0;
 drop table atacc1;
@@ -682,7 +680,7 @@ drop table atacc1;
 
 -- test primary key constraint adding
 
-create table atacc1 ( test int ) with oids;
+create table atacc1 ( id serial, test int) ;
 -- add a primary key constraint
 alter table atacc1 add constraint atacc_test1 primary key (test);
 -- insert first value
@@ -694,11 +692,11 @@ insert into atacc1 (test) values (4);
 -- inserting NULL should fail
 insert into atacc1 (test) values(NULL);
 -- try adding a second primary key (should fail)
-alter table atacc1 add constraint atacc_oid1 primary key(oid);
+alter table atacc1 add constraint atacc_oid1 primary key(id);
 -- drop first primary key constraint
 alter table atacc1 drop constraint atacc_test1 restrict;
 -- try adding a primary key on oid (should succeed)
-alter table atacc1 add constraint atacc_oid1 primary key(oid);
+alter table atacc1 add constraint atacc_oid1 primary key(id);
 drop table atacc1;
 
 -- let's do one where the primary key constraint fails when added
@@ -775,7 +773,7 @@ alter table non_existent alter column bar drop not null;
 
 -- test setting columns to null and not null and vice versa
 -- test checking for null values and primary key
-create table atacc1 (test int not null) with oids;
+create table atacc1 (test int not null);
 alter table atacc1 add constraint "atacc1_pkey" primary key (test);
 alter table atacc1 alter column test drop not null;
 alter table atacc1 drop constraint "atacc1_pkey";
@@ -789,10 +787,6 @@ alter table atacc1 alter test set not null;
 alter table atacc1 alter bar set not null;
 alter table atacc1 alter bar drop not null;
 
--- try altering the oid column, should fail
-alter table atacc1 alter oid set not null;
-alter table atacc1 alter oid drop not null;
-
 -- try creating a view and altering that, should fail
 create view myview as select * from atacc1;
 alter table myview alter column test drop not null;
@@ -872,7 +866,7 @@ alter table pg_class drop column relname;
 alter table nosuchtable drop column bar;
 
 -- test dropping columns
-create table atacc1 (a int4 not null, b int4, c int4 not null, d int4) with oids;
+create table atacc1 (a int4 not null, b int4, c int4 not null, d int4);
 insert into atacc1 values (1, 2, 3, 4);
 alter table atacc1 drop a;
 alter table atacc1 drop a;
@@ -922,9 +916,6 @@ delete from atacc1;
 -- try dropping a non-existent column, should fail
 alter table atacc1 drop bar;
 
--- try dropping the oid column, should succeed
-alter table atacc1 drop oid;
-
 -- try dropping the xmin column, should fail
 alter table atacc1 drop xmin;
 
@@ -1183,74 +1174,6 @@ from pg_attribute
 where attnum > 0 and attrelid::regclass in ('depth0', 'depth1', 'depth2')
 order by attrelid::regclass::text, attnum;
 
---
--- Test the ALTER TABLE SET WITH/WITHOUT OIDS command
---
-create table altstartwith (col integer) with oids;
-
-insert into altstartwith values (1);
-
-select oid > 0, * from altstartwith;
-
-alter table altstartwith set without oids;
-
-select oid > 0, * from altstartwith; -- fails
-select * from altstartwith;
-
-alter table altstartwith set with oids;
-
-select oid > 0, * from altstartwith;
-
-drop table altstartwith;
-
--- Check inheritance cases
-create table altwithoid (col integer) with oids;
-
--- Inherits parents oid column anyway
-create table altinhoid () inherits (altwithoid) without oids;
-
-insert into altinhoid values (1);
-
-select oid > 0, * from altwithoid;
-select oid > 0, * from altinhoid;
-
-alter table altwithoid set without oids;
-
-select oid > 0, * from altwithoid; -- fails
-select oid > 0, * from altinhoid; -- fails
-select * from altwithoid;
-select * from altinhoid;
-
-alter table altwithoid set with oids;
-
-select oid > 0, * from altwithoid;
-select oid > 0, * from altinhoid;
-
-drop table altwithoid cascade;
-
-create table altwithoid (col integer) without oids;
-
--- child can have local oid column
-create table altinhoid () inherits (altwithoid) with oids;
-
-insert into altinhoid values (1);
-
-select oid > 0, * from altwithoid; -- fails
-select oid > 0, * from altinhoid;
-
-alter table altwithoid set with oids;
-
-select oid > 0, * from altwithoid;
-select oid > 0, * from altinhoid;
-
--- the child's local definition should remain
-alter table altwithoid set without oids;
-
-select oid > 0, * from altwithoid; -- fails
-select oid > 0, * from altinhoid;
-
-drop table altwithoid cascade;
-
 -- test renumbering of child-table columns in inherited operations
 
 create table p1 (f1 int);
@@ -1803,7 +1726,7 @@ CREATE TABLE tt3 (y numeric(8,2), x int);			-- wrong column order
 CREATE TABLE tt4 (x int);							-- too few columns
 CREATE TABLE tt5 (x int, y numeric(8,2), z int);	-- too few columns
 CREATE TABLE tt6 () INHERITS (tt0);					-- can't have a parent
-CREATE TABLE tt7 (x int, q text, y numeric(8,2)) WITH OIDS;
+CREATE TABLE tt7 (x int, q text, y numeric(8,2));
 ALTER TABLE tt7 DROP q;								-- OK
 
 ALTER TABLE tt0 OF tt_t0;
@@ -2136,16 +2059,6 @@ CREATE TABLE fail_part OF mytype;
 ALTER TABLE list_parted ATTACH PARTITION fail_part FOR VALUES IN (1);
 DROP TYPE mytype CASCADE;
 
--- check existence (or non-existence) of oid column
-ALTER TABLE list_parted SET WITH OIDS;
-CREATE TABLE fail_part (a int);
-ALTER TABLE list_parted ATTACH PARTITION fail_part FOR VALUES IN (1);
-
-ALTER TABLE list_parted SET WITHOUT OIDS;
-ALTER TABLE fail_part SET WITH OIDS;
-ALTER TABLE list_parted ATTACH PARTITION fail_part FOR VALUES IN (1);
-DROP TABLE fail_part;
-
 -- check that the table being attached has only columns present in the parent
 CREATE TABLE fail_part (like list_parted, c int);
 ALTER TABLE list_parted ATTACH PARTITION fail_part FOR VALUES IN (1);
diff --git a/src/test/regress/sql/copy2.sql b/src/test/regress/sql/copy2.sql
index f3a6d228fae..e36df8858eb 100644
--- a/src/test/regress/sql/copy2.sql
+++ b/src/test/regress/sql/copy2.sql
@@ -4,7 +4,7 @@ CREATE TEMP TABLE x (
 	c text not null default 'stuff',
 	d text,
 	e text
-) WITH OIDS;
+) ;
 
 CREATE FUNCTION fn_x_before () RETURNS TRIGGER AS '
   BEGIN
@@ -73,10 +73,10 @@ COPY x from stdin;
 \.
 
 -- various COPY options: delimiters, oids, NULL string, encoding
-COPY x (b, c, d, e) from stdin with oids delimiter ',' null 'x';
-500000,x,45,80,90
-500001,x,\x,\\x,\\\x
-500002,x,\,,\\\,,\\
+COPY x (b, c, d, e) from stdin delimiter ',' null 'x';
+x,45,80,90
+x,\x,\\x,\\\x
+x,\,,\\\,,\\
 \.
 
 COPY x from stdin WITH DELIMITER AS ';' NULL AS '';
@@ -98,19 +98,6 @@ COPY x from stdin WITH DELIMITER AS ':' NULL AS E'\\X' ENCODING 'sql_ascii';
 -- check results of copy in
 SELECT * FROM x;
 
--- COPY w/ oids on a table w/o oids should fail
-CREATE TABLE no_oids (
-	a	int,
-	b	int
-) WITHOUT OIDS;
-
-INSERT INTO no_oids (a, b) VALUES (5, 10);
-INSERT INTO no_oids (a, b) VALUES (20, 30);
-
--- should fail
-COPY no_oids FROM stdin WITH OIDS;
-COPY no_oids TO stdout WITH OIDS;
-
 -- check copy out
 COPY x TO stdout;
 COPY x (c, e) TO stdout;
diff --git a/src/test/regress/sql/create_index.sql b/src/test/regress/sql/create_index.sql
index be7f261871e..59da6b65926 100644
--- a/src/test/regress/sql/create_index.sql
+++ b/src/test/regress/sql/create_index.sql
@@ -951,21 +951,18 @@ DROP TABLE cwi_test;
 --
 -- Check handling of indexes on system columns
 --
-CREATE TABLE oid_table (a INT) WITH OIDS;
+CREATE TABLE syscol_table (a INT);
 
--- An index on the OID column should be allowed
-CREATE INDEX ON oid_table (oid);
-
--- Other system columns cannot be indexed
-CREATE INDEX ON oid_table (ctid);
+-- System columns cannot be indexed
+CREATE INDEX ON syscolcol_table (ctid);
 
 -- nor used in expressions
-CREATE INDEX ON oid_table ((ctid >= '(1000,0)'));
+CREATE INDEX ON syscol_table ((ctid >= '(1000,0)'));
 
 -- nor used in predicates
-CREATE INDEX ON oid_table (a) WHERE ctid >= '(1000,0)';
+CREATE INDEX ON syscol_table (a) WHERE ctid >= '(1000,0)';
 
-DROP TABLE oid_table;
+DROP TABLE syscol_table;
 
 --
 -- Tests for IS NULL/IS NOT NULL with b-tree indexes
diff --git a/src/test/regress/sql/create_table.sql b/src/test/regress/sql/create_table.sql
index 2af4455ecf8..54fb0cdc985 100644
--- a/src/test/regress/sql/create_table.sql
+++ b/src/test/regress/sql/create_table.sql
@@ -51,7 +51,7 @@ CREATE TABLE tenk1 (
 	stringu1	name,
 	stringu2	name,
 	string4		name
-) WITH OIDS;
+);
 
 CREATE TABLE tenk2 (
 	unique1 	int4,
@@ -83,7 +83,7 @@ CREATE TABLE person (
 CREATE TABLE emp (
 	salary 		int4,
 	manager 	name
-) INHERITS (person) WITH OIDS;
+) INHERITS (person);
 
 
 CREATE TABLE student (
@@ -255,7 +255,6 @@ CREATE TABLE IF NOT EXISTS test_tsvector(
 
 -- invalid: non-lowercase quoted reloptions identifiers
 CREATE TABLE tas_case WITH ("Fillfactor" = 10) AS SELECT 1 a;
-CREATE TABLE tas_case (a text) WITH ("Oids" = true);
 
 CREATE UNLOGGED TABLE unlogged1 (a int primary key);			-- OK
 CREATE TEMPORARY TABLE unlogged2 (a int primary key);			-- OK
@@ -278,10 +277,6 @@ CREATE TABLE as_select1 AS SELECT * FROM pg_class WHERE relkind = 'r';
 CREATE TABLE IF NOT EXISTS as_select1 AS SELECT * FROM pg_class WHERE relkind = 'r';
 DROP TABLE as_select1;
 
--- check that the oid column is added before the primary key is checked
-CREATE TABLE oid_pk (f1 INT, PRIMARY KEY(oid)) WITH OIDS;
-DROP TABLE oid_pk;
-
 --
 -- Partitioned tables
 --
@@ -520,22 +515,6 @@ CREATE TEMP TABLE temp_parted (
 CREATE TABLE fail_part PARTITION OF temp_parted FOR VALUES IN ('a');
 DROP TABLE temp_parted;
 
--- cannot create a table with oids as partition of table without oids
-CREATE TABLE no_oids_parted (
-	a int
-) PARTITION BY RANGE (a) WITHOUT OIDS;
-CREATE TABLE fail_part PARTITION OF no_oids_parted FOR VALUES FROM (1) TO (10) WITH OIDS;
-DROP TABLE no_oids_parted;
-
--- If the partitioned table has oids, then the partition must have them.
--- If the WITHOUT OIDS option is specified for partition, it is overridden.
-CREATE TABLE oids_parted (
-	a int
-) PARTITION BY RANGE (a) WITH OIDS;
-CREATE TABLE part_forced_oids PARTITION OF oids_parted FOR VALUES FROM (1) TO (10) WITHOUT OIDS;
-\d+ part_forced_oids
-DROP TABLE oids_parted, part_forced_oids;
-
 -- check for partition bound overlap and other invalid specifications
 
 CREATE TABLE list_parted2 (
diff --git a/src/test/regress/sql/create_table_like.sql b/src/test/regress/sql/create_table_like.sql
index 42cad6826b0..65c3880792b 100644
--- a/src/test/regress/sql/create_table_like.sql
+++ b/src/test/regress/sql/create_table_like.sql
@@ -136,19 +136,3 @@ DROP SEQUENCE ctlseq1;
 DROP TYPE ctlty1;
 DROP VIEW ctlv1;
 DROP TABLE IF EXISTS ctlt4, ctlt10, ctlt11, ctlt11a, ctlt12;
-
-/* LIKE WITH OIDS */
-CREATE TABLE has_oid (x INTEGER) WITH OIDS;
-CREATE TABLE no_oid (y INTEGER);
-CREATE TABLE like_test (z INTEGER, LIKE has_oid);
-SELECT oid FROM like_test;
-CREATE TABLE like_test2 (z INTEGER, LIKE no_oid);
-SELECT oid FROM like_test2; -- fail
-CREATE TABLE like_test3 (z INTEGER, LIKE has_oid, LIKE no_oid);
-SELECT oid FROM like_test3;
-CREATE TABLE like_test4 (z INTEGER, PRIMARY KEY(oid), LIKE has_oid);
-SELECT oid FROM like_test4;
-CREATE TABLE like_test5 (z INTEGER, LIKE no_oid) WITH OIDS;
-SELECT oid FROM like_test5;
-DROP TABLE has_oid, no_oid, like_test, like_test2, like_test3,
-  like_test4, like_test5;
diff --git a/src/test/regress/sql/errors.sql b/src/test/regress/sql/errors.sql
index 14bc723a52a..792c29c64b5 100644
--- a/src/test/regress/sql/errors.sql
+++ b/src/test/regress/sql/errors.sql
@@ -91,7 +91,7 @@ alter table emp rename column nonesuchatt to newnonesuchatt;
 alter table emp rename column salary to manager;
 
 -- conflict
-alter table emp rename column salary to oid;
+alter table emp rename column salary to ctid;
 
 
 --
diff --git a/src/test/regress/sql/foreign_data.sql b/src/test/regress/sql/foreign_data.sql
index dab9b62900e..d6fb3fae4e1 100644
--- a/src/test/regress/sql/foreign_data.sql
+++ b/src/test/regress/sql/foreign_data.sql
@@ -283,7 +283,6 @@ CREATE SCHEMA foreign_schema;
 CREATE SERVER s0 FOREIGN DATA WRAPPER dummy;
 CREATE FOREIGN TABLE ft1 ();                                    -- ERROR
 CREATE FOREIGN TABLE ft1 () SERVER no_server;                   -- ERROR
-CREATE FOREIGN TABLE ft1 () SERVER s0 WITH OIDS;                -- ERROR
 CREATE FOREIGN TABLE ft1 (
 	c1 integer OPTIONS ("param 1" 'val1') PRIMARY KEY,
 	c2 text OPTIONS (param2 'val2', param3 'val3'),
@@ -362,7 +361,6 @@ ALTER FOREIGN TABLE ft1 ALTER CONSTRAINT ft1_c9_check DEFERRABLE; -- ERROR
 ALTER FOREIGN TABLE ft1 DROP CONSTRAINT ft1_c9_check;
 ALTER FOREIGN TABLE ft1 DROP CONSTRAINT no_const;               -- ERROR
 ALTER FOREIGN TABLE ft1 DROP CONSTRAINT IF EXISTS no_const;
-ALTER FOREIGN TABLE ft1 SET WITH OIDS;
 ALTER FOREIGN TABLE ft1 OWNER TO regress_test_role;
 ALTER FOREIGN TABLE ft1 OPTIONS (DROP delimiter, SET quote '~', ADD escape '@');
 ALTER FOREIGN TABLE ft1 DROP COLUMN no_column;                  -- ERROR
@@ -693,15 +691,6 @@ ALTER TABLE fd_pt1 VALIDATE CONSTRAINT fd_pt1chk3;
 \d+ fd_pt1
 \d+ ft2
 
--- OID system column
-ALTER TABLE fd_pt1 SET WITH OIDS;
-\d+ fd_pt1
-\d+ ft2
-ALTER TABLE ft2 SET WITHOUT OIDS;  -- ERROR
-ALTER TABLE fd_pt1 SET WITHOUT OIDS;
-\d+ fd_pt1
-\d+ ft2
-
 -- changes name of an attribute recursively
 ALTER TABLE fd_pt1 RENAME COLUMN c1 TO f1;
 ALTER TABLE fd_pt1 RENAME COLUMN c2 TO f2;
diff --git a/src/test/regress/sql/inherit.sql b/src/test/regress/sql/inherit.sql
index afc72f47bc8..425052c1f45 100644
--- a/src/test/regress/sql/inherit.sql
+++ b/src/test/regress/sql/inherit.sql
@@ -190,32 +190,6 @@ insert into d values('test','one','two','three');
 alter table a alter column aa type integer using bit_length(aa);
 select * from d;
 
--- check that oid column is handled properly during alter table inherit
-create table oid_parent (a int) with oids;
-
-create table oid_child () inherits (oid_parent);
-select attinhcount, attislocal from pg_attribute
-  where attrelid = 'oid_child'::regclass and attname = 'oid';
-drop table oid_child;
-
-create table oid_child (a int) without oids;
-alter table oid_child inherit oid_parent;  -- fail
-alter table oid_child set with oids;
-select attinhcount, attislocal from pg_attribute
-  where attrelid = 'oid_child'::regclass and attname = 'oid';
-alter table oid_child inherit oid_parent;
-select attinhcount, attislocal from pg_attribute
-  where attrelid = 'oid_child'::regclass and attname = 'oid';
-alter table oid_child set without oids;  -- fail
-alter table oid_parent set without oids;
-select attinhcount, attislocal from pg_attribute
-  where attrelid = 'oid_child'::regclass and attname = 'oid';
-alter table oid_child set without oids;
-select attinhcount, attislocal from pg_attribute
-  where attrelid = 'oid_child'::regclass and attname = 'oid';
-
-drop table oid_parent cascade;
-
 -- Test non-inheritable parent constraints
 create table p1(ff1 int);
 alter table p1 add constraint p1chk check (ff1 > 0) no inherit;
diff --git a/src/test/regress/sql/insert_conflict.sql b/src/test/regress/sql/insert_conflict.sql
index fe6dcfaa06b..961cffd2091 100644
--- a/src/test/regress/sql/insert_conflict.sql
+++ b/src/test/regress/sql/insert_conflict.sql
@@ -253,12 +253,11 @@ drop table insertconflicttest;
 --
 -- Verify that EXCLUDED does not allow system column references. These
 -- do not make sense because EXCLUDED isn't an already stored tuple
--- (and thus doesn't have a ctid, oids are not assigned yet, etc).
+-- (and thus doesn't have a ctid etc).
 --
-create table syscolconflicttest(key int4, data text) WITH OIDS;
+create table syscolconflicttest(key int4, data text);
 insert into syscolconflicttest values (1);
 insert into syscolconflicttest values (1) on conflict (key) do update set data = excluded.ctid::text;
-insert into syscolconflicttest values (1) on conflict (key) do update set data = excluded.oid::text;
 drop table syscolconflicttest;
 
 --
@@ -373,28 +372,6 @@ insert into excluded values(1, '2') on conflict (key) do update set data = 3 RET
 drop table excluded;
 
 
--- Check tables w/o oids are handled correctly
-create table testoids(key int primary key, data text) without oids;
--- first without oids
-insert into testoids values(1, '1') on conflict (key) do update set data = excluded.data RETURNING *;
-insert into testoids values(1, '2') on conflict (key) do update set data = excluded.data RETURNING *;
--- add oids
-alter table testoids set with oids;
--- update existing row, that didn't have an oid
-insert into testoids values(1, '3') on conflict (key) do update set data = excluded.data RETURNING *;
--- insert a new row
-insert into testoids values(2, '1') on conflict (key) do update set data = excluded.data RETURNING *;
--- and update it
-insert into testoids values(2, '2') on conflict (key) do update set data = excluded.data RETURNING *;
--- remove oids again, test
-alter table testoids set without oids;
-insert into testoids values(1, '4') on conflict (key) do update set data = excluded.data RETURNING *;
-insert into testoids values(3, '1') on conflict (key) do update set data = excluded.data RETURNING *;
-insert into testoids values(3, '2') on conflict (key) do update set data = excluded.data RETURNING *;
-
-DROP TABLE testoids;
-
-
 -- check that references to columns after dropped columns are handled correctly
 create table dropcol(key int primary key, drop1 int, keep1 text, drop2 numeric, keep2 float);
 insert into dropcol(key, drop1, keep1, drop2, keep2) values(1, 1, '1', '1', 1);
diff --git a/src/test/regress/sql/misc_sanity.sql b/src/test/regress/sql/misc_sanity.sql
index f2af5e37508..f2cd0b46e25 100644
--- a/src/test/regress/sql/misc_sanity.sql
+++ b/src/test/regress/sql/misc_sanity.sql
@@ -54,7 +54,7 @@ declare relnm text;
 begin
 for relnm, reloid, shared in
   select relname, oid, relisshared from pg_class
-  where relhasoids and oid < 16384 order by 1
+  where EXISTS(SELECT * FROM pg_attribute WHERE attrelid = pg_class.oid AND attname = 'oid') and relkind = 'r' and oid < 16384 order by 1
 loop
   execute 'select min(oid) from ' || relnm into lowoid;
   continue when lowoid is null or lowoid >= 16384;
diff --git a/src/test/regress/sql/prepare.sql b/src/test/regress/sql/prepare.sql
index 25f814b4667..7fe8c8d7f55 100644
--- a/src/test/regress/sql/prepare.sql
+++ b/src/test/regress/sql/prepare.sql
@@ -36,21 +36,21 @@ PREPARE q2(text) AS
 
 EXECUTE q2('postgres');
 
-PREPARE q3(text, int, float, boolean, oid, smallint) AS
+PREPARE q3(text, int, float, boolean, smallint) AS
 	SELECT * FROM tenk1 WHERE string4 = $1 AND (four = $2 OR
-	ten = $3::bigint OR true = $4 OR oid = $5 OR odd = $6::int)
+	ten = $3::bigint OR true = $4 OR odd = $5::int)
 	ORDER BY unique1;
 
-EXECUTE q3('AAAAxx', 5::smallint, 10.5::float, false, 500::oid, 4::bigint);
+EXECUTE q3('AAAAxx', 5::smallint, 10.5::float, false, 4::bigint);
 
 -- too few params
 EXECUTE q3('bool');
 
 -- too many params
-EXECUTE q3('bytea', 5::smallint, 10.5::float, false, 500::oid, 4::bigint, true);
+EXECUTE q3('bytea', 5::smallint, 10.5::float, false, 4::bigint, true);
 
 -- wrong param types
-EXECUTE q3(5::smallint, 10.5::float, false, 500::oid, 4::bigint, 'bytea');
+EXECUTE q3(5::smallint, 10.5::float, false, 4::bigint, 'bytea');
 
 -- invalid type
 PREPARE q4(nonexistenttype) AS SELECT $1;
diff --git a/src/test/regress/sql/privileges.sql b/src/test/regress/sql/privileges.sql
index e3e69302a25..ac2c3df3a2d 100644
--- a/src/test/regress/sql/privileges.sql
+++ b/src/test/regress/sql/privileges.sql
@@ -407,27 +407,27 @@ DELETE FROM atest5 WHERE two = 2; -- ok
 
 -- check inheritance cases
 SET SESSION AUTHORIZATION regress_priv_user1;
-CREATE TABLE atestp1 (f1 int, f2 int) WITH OIDS;
-CREATE TABLE atestp2 (fx int, fy int) WITH OIDS;
+CREATE TABLE atestp1 (f1 int, f2 int);
+CREATE TABLE atestp2 (fx int, fy int);
 CREATE TABLE atestc (fz int) INHERITS (atestp1, atestp2);
-GRANT SELECT(fx,fy,oid) ON atestp2 TO regress_priv_user2;
+GRANT SELECT(fx,fy,tableoid) ON atestp2 TO regress_priv_user2;
 GRANT SELECT(fx) ON atestc TO regress_priv_user2;
 
 SET SESSION AUTHORIZATION regress_priv_user2;
 SELECT fx FROM atestp2; -- ok
 SELECT fy FROM atestp2; -- ok
 SELECT atestp2 FROM atestp2; -- ok
-SELECT oid FROM atestp2; -- ok
+SELECT tableoid FROM atestp2; -- ok
 SELECT fy FROM atestc; -- fail
 
 SET SESSION AUTHORIZATION regress_priv_user1;
-GRANT SELECT(fy,oid) ON atestc TO regress_priv_user2;
+GRANT SELECT(fy,tableoid) ON atestc TO regress_priv_user2;
 
 SET SESSION AUTHORIZATION regress_priv_user2;
 SELECT fx FROM atestp2; -- still ok
 SELECT fy FROM atestp2; -- ok
 SELECT atestp2 FROM atestp2; -- ok
-SELECT oid FROM atestp2; -- ok
+SELECT tableoid FROM atestp2; -- ok
 
 -- privileges on functions, languages
 
diff --git a/src/test/regress/sql/reloptions.sql b/src/test/regress/sql/reloptions.sql
index 37fbf41f7d5..44fcd8c4145 100644
--- a/src/test/regress/sql/reloptions.sql
+++ b/src/test/regress/sql/reloptions.sql
@@ -52,11 +52,6 @@ SELECT reloptions FROM pg_class WHERE oid = 'reloptions_test'::regclass AND
 -- RESET fails if a value is specified
 ALTER TABLE reloptions_test RESET (fillfactor=12);
 
--- The OIDS option is not stored as reloption
-DROP TABLE reloptions_test;
-CREATE TABLE reloptions_test(i INT) WITH (fillfactor=20, oids=true);
-SELECT reloptions, relhasoids FROM pg_class WHERE oid = 'reloptions_test'::regclass;
-
 -- Test toast.* options
 DROP TABLE reloptions_test;
 
diff --git a/src/test/regress/sql/replica_identity.sql b/src/test/regress/sql/replica_identity.sql
index 3d2171c7336..b08a3623b8c 100644
--- a/src/test/regress/sql/replica_identity.sql
+++ b/src/test/regress/sql/replica_identity.sql
@@ -5,13 +5,12 @@ CREATE TABLE test_replica_identity (
        nonkey text,
        CONSTRAINT test_replica_identity_unique_defer UNIQUE (keya, keyb) DEFERRABLE,
        CONSTRAINT test_replica_identity_unique_nondefer UNIQUE (keya, keyb)
-) WITH OIDS;
+) ;
 
 CREATE TABLE test_replica_identity_othertable (id serial primary key);
 
 CREATE INDEX test_replica_identity_keyab ON test_replica_identity (keya, keyb);
 CREATE UNIQUE INDEX test_replica_identity_keyab_key ON test_replica_identity (keya, keyb);
-CREATE UNIQUE INDEX test_replica_identity_oid_idx ON test_replica_identity (oid);
 CREATE UNIQUE INDEX test_replica_identity_nonkey ON test_replica_identity (keya, nonkey);
 CREATE INDEX test_replica_identity_hash ON test_replica_identity USING hash (nonkey);
 CREATE UNIQUE INDEX test_replica_identity_expr ON test_replica_identity (keya, keyb, (3));
@@ -53,9 +52,6 @@ ALTER TABLE test_replica_identity REPLICA IDENTITY USING INDEX test_replica_iden
 SELECT relreplident FROM pg_class WHERE oid = 'test_replica_identity'::regclass;
 \d test_replica_identity
 
--- succeed, oid unique index
-ALTER TABLE test_replica_identity REPLICA IDENTITY USING INDEX test_replica_identity_oid_idx;
-
 -- succeed, nondeferrable unique constraint over nonnullable cols
 ALTER TABLE test_replica_identity REPLICA IDENTITY USING INDEX test_replica_identity_unique_nondefer;
 
diff --git a/src/test/regress/sql/roleattributes.sql b/src/test/regress/sql/roleattributes.sql
index 1b034d752fb..c961b2d7303 100644
--- a/src/test/regress/sql/roleattributes.sql
+++ b/src/test/regress/sql/roleattributes.sql
@@ -1,82 +1,83 @@
 -- default for superuser is false
 CREATE ROLE regress_test_def_superuser;
-SELECT * FROM pg_authid WHERE rolname = 'regress_test_def_superuser';
+
+SELECT rolname, rolsuper, rolinherit, rolcreaterole, rolcreatedb, rolcanlogin, rolreplication, rolbypassrls, rolconnlimit, rolpassword, rolvaliduntil FROM pg_authid WHERE rolname = 'regress_test_def_superuser';
 CREATE ROLE regress_test_superuser WITH SUPERUSER;
-SELECT * FROM pg_authid WHERE rolname = 'regress_test_superuser';
+SELECT rolname, rolsuper, rolinherit, rolcreaterole, rolcreatedb, rolcanlogin, rolreplication, rolbypassrls, rolconnlimit, rolpassword, rolvaliduntil FROM pg_authid WHERE rolname = 'regress_test_superuser';
 ALTER ROLE regress_test_superuser WITH NOSUPERUSER;
-SELECT * FROM pg_authid WHERE rolname = 'regress_test_superuser';
+SELECT rolname, rolsuper, rolinherit, rolcreaterole, rolcreatedb, rolcanlogin, rolreplication, rolbypassrls, rolconnlimit, rolpassword, rolvaliduntil FROM pg_authid WHERE rolname = 'regress_test_superuser';
 ALTER ROLE regress_test_superuser WITH SUPERUSER;
-SELECT * FROM pg_authid WHERE rolname = 'regress_test_superuser';
+SELECT rolname, rolsuper, rolinherit, rolcreaterole, rolcreatedb, rolcanlogin, rolreplication, rolbypassrls, rolconnlimit, rolpassword, rolvaliduntil FROM pg_authid WHERE rolname = 'regress_test_superuser';
 
 -- default for inherit is true
 CREATE ROLE regress_test_def_inherit;
-SELECT * FROM pg_authid WHERE rolname = 'regress_test_def_inherit';
+SELECT rolname, rolsuper, rolinherit, rolcreaterole, rolcreatedb, rolcanlogin, rolreplication, rolbypassrls, rolconnlimit, rolpassword, rolvaliduntil FROM pg_authid WHERE rolname = 'regress_test_def_inherit';
 CREATE ROLE regress_test_inherit WITH NOINHERIT;
-SELECT * FROM pg_authid WHERE rolname = 'regress_test_inherit';
+SELECT rolname, rolsuper, rolinherit, rolcreaterole, rolcreatedb, rolcanlogin, rolreplication, rolbypassrls, rolconnlimit, rolpassword, rolvaliduntil FROM pg_authid WHERE rolname = 'regress_test_inherit';
 ALTER ROLE regress_test_inherit WITH INHERIT;
-SELECT * FROM pg_authid WHERE rolname = 'regress_test_inherit';
+SELECT rolname, rolsuper, rolinherit, rolcreaterole, rolcreatedb, rolcanlogin, rolreplication, rolbypassrls, rolconnlimit, rolpassword, rolvaliduntil FROM pg_authid WHERE rolname = 'regress_test_inherit';
 ALTER ROLE regress_test_inherit WITH NOINHERIT;
-SELECT * FROM pg_authid WHERE rolname = 'regress_test_inherit';
+SELECT rolname, rolsuper, rolinherit, rolcreaterole, rolcreatedb, rolcanlogin, rolreplication, rolbypassrls, rolconnlimit, rolpassword, rolvaliduntil FROM pg_authid WHERE rolname = 'regress_test_inherit';
 
 -- default for create role is false
 CREATE ROLE regress_test_def_createrole;
-SELECT * FROM pg_authid WHERE rolname = 'regress_test_def_createrole';
+SELECT rolname, rolsuper, rolinherit, rolcreaterole, rolcreatedb, rolcanlogin, rolreplication, rolbypassrls, rolconnlimit, rolpassword, rolvaliduntil FROM pg_authid WHERE rolname = 'regress_test_def_createrole';
 CREATE ROLE regress_test_createrole WITH CREATEROLE;
-SELECT * FROM pg_authid WHERE rolname = 'regress_test_createrole';
+SELECT rolname, rolsuper, rolinherit, rolcreaterole, rolcreatedb, rolcanlogin, rolreplication, rolbypassrls, rolconnlimit, rolpassword, rolvaliduntil FROM pg_authid WHERE rolname = 'regress_test_createrole';
 ALTER ROLE regress_test_createrole WITH NOCREATEROLE;
-SELECT * FROM pg_authid WHERE rolname = 'regress_test_createrole';
+SELECT rolname, rolsuper, rolinherit, rolcreaterole, rolcreatedb, rolcanlogin, rolreplication, rolbypassrls, rolconnlimit, rolpassword, rolvaliduntil FROM pg_authid WHERE rolname = 'regress_test_createrole';
 ALTER ROLE regress_test_createrole WITH CREATEROLE;
-SELECT * FROM pg_authid WHERE rolname = 'regress_test_createrole';
+SELECT rolname, rolsuper, rolinherit, rolcreaterole, rolcreatedb, rolcanlogin, rolreplication, rolbypassrls, rolconnlimit, rolpassword, rolvaliduntil FROM pg_authid WHERE rolname = 'regress_test_createrole';
 
 -- default for create database is false
 CREATE ROLE regress_test_def_createdb;
-SELECT * FROM pg_authid WHERE rolname = 'regress_test_def_createdb';
+SELECT rolname, rolsuper, rolinherit, rolcreaterole, rolcreatedb, rolcanlogin, rolreplication, rolbypassrls, rolconnlimit, rolpassword, rolvaliduntil FROM pg_authid WHERE rolname = 'regress_test_def_createdb';
 CREATE ROLE regress_test_createdb WITH CREATEDB;
-SELECT * FROM pg_authid WHERE rolname = 'regress_test_createdb';
+SELECT rolname, rolsuper, rolinherit, rolcreaterole, rolcreatedb, rolcanlogin, rolreplication, rolbypassrls, rolconnlimit, rolpassword, rolvaliduntil FROM pg_authid WHERE rolname = 'regress_test_createdb';
 ALTER ROLE regress_test_createdb WITH NOCREATEDB;
-SELECT * FROM pg_authid WHERE rolname = 'regress_test_createdb';
+SELECT rolname, rolsuper, rolinherit, rolcreaterole, rolcreatedb, rolcanlogin, rolreplication, rolbypassrls, rolconnlimit, rolpassword, rolvaliduntil FROM pg_authid WHERE rolname = 'regress_test_createdb';
 ALTER ROLE regress_test_createdb WITH CREATEDB;
-SELECT * FROM pg_authid WHERE rolname = 'regress_test_createdb';
+SELECT rolname, rolsuper, rolinherit, rolcreaterole, rolcreatedb, rolcanlogin, rolreplication, rolbypassrls, rolconnlimit, rolpassword, rolvaliduntil FROM pg_authid WHERE rolname = 'regress_test_createdb';
 
 -- default for can login is false for role
 CREATE ROLE regress_test_def_role_canlogin;
-SELECT * FROM pg_authid WHERE rolname = 'regress_test_def_role_canlogin';
+SELECT rolname, rolsuper, rolinherit, rolcreaterole, rolcreatedb, rolcanlogin, rolreplication, rolbypassrls, rolconnlimit, rolpassword, rolvaliduntil FROM pg_authid WHERE rolname = 'regress_test_def_role_canlogin';
 CREATE ROLE regress_test_role_canlogin WITH LOGIN;
-SELECT * FROM pg_authid WHERE rolname = 'regress_test_role_canlogin';
+SELECT rolname, rolsuper, rolinherit, rolcreaterole, rolcreatedb, rolcanlogin, rolreplication, rolbypassrls, rolconnlimit, rolpassword, rolvaliduntil FROM pg_authid WHERE rolname = 'regress_test_role_canlogin';
 ALTER ROLE regress_test_role_canlogin WITH NOLOGIN;
-SELECT * FROM pg_authid WHERE rolname = 'regress_test_role_canlogin';
+SELECT rolname, rolsuper, rolinherit, rolcreaterole, rolcreatedb, rolcanlogin, rolreplication, rolbypassrls, rolconnlimit, rolpassword, rolvaliduntil FROM pg_authid WHERE rolname = 'regress_test_role_canlogin';
 ALTER ROLE regress_test_role_canlogin WITH LOGIN;
-SELECT * FROM pg_authid WHERE rolname = 'regress_test_role_canlogin';
+SELECT rolname, rolsuper, rolinherit, rolcreaterole, rolcreatedb, rolcanlogin, rolreplication, rolbypassrls, rolconnlimit, rolpassword, rolvaliduntil FROM pg_authid WHERE rolname = 'regress_test_role_canlogin';
 
 -- default for can login is true for user
 CREATE USER regress_test_def_user_canlogin;
-SELECT * FROM pg_authid WHERE rolname = 'regress_test_def_user_canlogin';
+SELECT rolname, rolsuper, rolinherit, rolcreaterole, rolcreatedb, rolcanlogin, rolreplication, rolbypassrls, rolconnlimit, rolpassword, rolvaliduntil FROM pg_authid WHERE rolname = 'regress_test_def_user_canlogin';
 CREATE USER regress_test_user_canlogin WITH NOLOGIN;
-SELECT * FROM pg_authid WHERE rolname = 'regress_test_user_canlogin';
+SELECT rolname, rolsuper, rolinherit, rolcreaterole, rolcreatedb, rolcanlogin, rolreplication, rolbypassrls, rolconnlimit, rolpassword, rolvaliduntil FROM pg_authid WHERE rolname = 'regress_test_user_canlogin';
 ALTER USER regress_test_user_canlogin WITH LOGIN;
-SELECT * FROM pg_authid WHERE rolname = 'regress_test_user_canlogin';
+SELECT rolname, rolsuper, rolinherit, rolcreaterole, rolcreatedb, rolcanlogin, rolreplication, rolbypassrls, rolconnlimit, rolpassword, rolvaliduntil FROM pg_authid WHERE rolname = 'regress_test_user_canlogin';
 ALTER USER regress_test_user_canlogin WITH NOLOGIN;
-SELECT * FROM pg_authid WHERE rolname = 'regress_test_user_canlogin';
+SELECT rolname, rolsuper, rolinherit, rolcreaterole, rolcreatedb, rolcanlogin, rolreplication, rolbypassrls, rolconnlimit, rolpassword, rolvaliduntil FROM pg_authid WHERE rolname = 'regress_test_user_canlogin';
 
 -- default for replication is false
 CREATE ROLE regress_test_def_replication;
-SELECT * FROM pg_authid WHERE rolname = 'regress_test_def_replication';
+SELECT rolname, rolsuper, rolinherit, rolcreaterole, rolcreatedb, rolcanlogin, rolreplication, rolbypassrls, rolconnlimit, rolpassword, rolvaliduntil FROM pg_authid WHERE rolname = 'regress_test_def_replication';
 CREATE ROLE regress_test_replication WITH REPLICATION;
-SELECT * FROM pg_authid WHERE rolname = 'regress_test_replication';
+SELECT rolname, rolsuper, rolinherit, rolcreaterole, rolcreatedb, rolcanlogin, rolreplication, rolbypassrls, rolconnlimit, rolpassword, rolvaliduntil FROM pg_authid WHERE rolname = 'regress_test_replication';
 ALTER ROLE regress_test_replication WITH NOREPLICATION;
-SELECT * FROM pg_authid WHERE rolname = 'regress_test_replication';
+SELECT rolname, rolsuper, rolinherit, rolcreaterole, rolcreatedb, rolcanlogin, rolreplication, rolbypassrls, rolconnlimit, rolpassword, rolvaliduntil FROM pg_authid WHERE rolname = 'regress_test_replication';
 ALTER ROLE regress_test_replication WITH REPLICATION;
-SELECT * FROM pg_authid WHERE rolname = 'regress_test_replication';
+SELECT rolname, rolsuper, rolinherit, rolcreaterole, rolcreatedb, rolcanlogin, rolreplication, rolbypassrls, rolconnlimit, rolpassword, rolvaliduntil FROM pg_authid WHERE rolname = 'regress_test_replication';
 
 -- default for bypassrls is false
 CREATE ROLE regress_test_def_bypassrls;
-SELECT * FROM pg_authid WHERE rolname = 'regress_test_def_bypassrls';
+SELECT rolname, rolsuper, rolinherit, rolcreaterole, rolcreatedb, rolcanlogin, rolreplication, rolbypassrls, rolconnlimit, rolpassword, rolvaliduntil FROM pg_authid WHERE rolname = 'regress_test_def_bypassrls';
 CREATE ROLE regress_test_bypassrls WITH BYPASSRLS;
-SELECT * FROM pg_authid WHERE rolname = 'regress_test_bypassrls';
+SELECT rolname, rolsuper, rolinherit, rolcreaterole, rolcreatedb, rolcanlogin, rolreplication, rolbypassrls, rolconnlimit, rolpassword, rolvaliduntil FROM pg_authid WHERE rolname = 'regress_test_bypassrls';
 ALTER ROLE regress_test_bypassrls WITH NOBYPASSRLS;
-SELECT * FROM pg_authid WHERE rolname = 'regress_test_bypassrls';
+SELECT rolname, rolsuper, rolinherit, rolcreaterole, rolcreatedb, rolcanlogin, rolreplication, rolbypassrls, rolconnlimit, rolpassword, rolvaliduntil FROM pg_authid WHERE rolname = 'regress_test_bypassrls';
 ALTER ROLE regress_test_bypassrls WITH BYPASSRLS;
-SELECT * FROM pg_authid WHERE rolname = 'regress_test_bypassrls';
+SELECT rolname, rolsuper, rolinherit, rolcreaterole, rolcreatedb, rolcanlogin, rolreplication, rolbypassrls, rolconnlimit, rolpassword, rolvaliduntil FROM pg_authid WHERE rolname = 'regress_test_bypassrls';
 
 -- clean up roles
 DROP ROLE regress_test_def_superuser;
diff --git a/src/test/regress/sql/rowsecurity.sql b/src/test/regress/sql/rowsecurity.sql
index 5a9fdcad742..38e9b38bc40 100644
--- a/src/test/regress/sql/rowsecurity.sql
+++ b/src/test/regress/sql/rowsecurity.sql
@@ -232,11 +232,11 @@ SET SESSION AUTHORIZATION regress_rls_alice;
 
 SET row_security TO ON;
 
-CREATE TABLE t1 (a int, junk1 text, b text) WITH OIDS;
+CREATE TABLE t1 (id int not null primary key, a int, junk1 text, b text);
 ALTER TABLE t1 DROP COLUMN junk1;    -- just a disturbing factor
 GRANT ALL ON t1 TO public;
 
-COPY t1 FROM stdin WITH (oids);
+COPY t1 FROM stdin WITH ;
 101	1	aba
 102	2	bbb
 103	3	ccc
@@ -246,18 +246,18 @@ COPY t1 FROM stdin WITH (oids);
 CREATE TABLE t2 (c float) INHERITS (t1);
 GRANT ALL ON t2 TO public;
 
-COPY t2 FROM stdin WITH (oids);
+COPY t2 FROM stdin;
 201	1	abc	1.1
 202	2	bcd	2.2
 203	3	cde	3.3
 204	4	def	4.4
 \.
 
-CREATE TABLE t3 (c text, b text, a int) WITH OIDS;
+CREATE TABLE t3 (id int not null primary key, c text, b text, a int);
 ALTER TABLE t3 INHERIT t1;
 GRANT ALL ON t3 TO public;
 
-COPY t3(a,b,c) FROM stdin WITH (oids);
+COPY t3(id, a,b,c) FROM stdin;
 301	1	xxx	X
 302	2	yyy	Y
 303	3	zzz	Z
@@ -278,7 +278,7 @@ SELECT * FROM t1 WHERE f_leak(b);
 EXPLAIN (COSTS OFF) SELECT * FROM t1 WHERE f_leak(b);
 
 -- reference to system column
-SELECT oid, * FROM t1;
+SELECT tableoid::regclass, * FROM t1;
 EXPLAIN (COSTS OFF) SELECT *, t1 FROM t1;
 
 -- reference to whole-row reference
@@ -293,8 +293,8 @@ SELECT * FROM t1 WHERE f_leak(b) FOR SHARE;
 EXPLAIN (COSTS OFF) SELECT * FROM t1 WHERE f_leak(b) FOR SHARE;
 
 -- union all query
-SELECT a, b, oid FROM t2 UNION ALL SELECT a, b, oid FROM t3;
-EXPLAIN (COSTS OFF) SELECT a, b, oid FROM t2 UNION ALL SELECT a, b, oid FROM t3;
+SELECT a, b, tableoid::regclass FROM t2 UNION ALL SELECT a, b, tableoid::regclass FROM t3;
+EXPLAIN (COSTS OFF) SELECT a, b, tableoid::regclass FROM t2 UNION ALL SELECT a, b, tableoid::regclass FROM t3;
 
 -- superuser is allowed to bypass RLS checks
 RESET SESSION AUTHORIZATION;
@@ -614,9 +614,9 @@ EXPLAIN (COSTS OFF) UPDATE only t1 SET b = b || '_updt' WHERE f_leak(b);
 UPDATE only t1 SET b = b || '_updt' WHERE f_leak(b);
 
 -- returning clause with system column
-UPDATE only t1 SET b = b WHERE f_leak(b) RETURNING oid, *, t1;
+UPDATE only t1 SET b = b WHERE f_leak(b) RETURNING tableoid::regclass, *, t1;
 UPDATE t1 SET b = b WHERE f_leak(b) RETURNING *;
-UPDATE t1 SET b = b WHERE f_leak(b) RETURNING oid, *, t1;
+UPDATE t1 SET b = b WHERE f_leak(b) RETURNING tableoid::regclass, *, t1;
 
 -- updates with from clause
 EXPLAIN (COSTS OFF) UPDATE t2 SET b=t2.b FROM t3
@@ -663,8 +663,8 @@ SET row_security TO ON;
 EXPLAIN (COSTS OFF) DELETE FROM only t1 WHERE f_leak(b);
 EXPLAIN (COSTS OFF) DELETE FROM t1 WHERE f_leak(b);
 
-DELETE FROM only t1 WHERE f_leak(b) RETURNING oid, *, t1;
-DELETE FROM t1 WHERE f_leak(b) RETURNING oid, *, t1;
+DELETE FROM only t1 WHERE f_leak(b) RETURNING tableoid::regclass, *, t1;
+DELETE FROM t1 WHERE f_leak(b) RETURNING tableoid::regclass, *, t1;
 
 --
 -- S.b. view on top of Row-level security
diff --git a/src/test/regress/sql/rowtypes.sql b/src/test/regress/sql/rowtypes.sql
index faf2e108d6a..e6d389805cd 100644
--- a/src/test/regress/sql/rowtypes.sql
+++ b/src/test/regress/sql/rowtypes.sql
@@ -442,15 +442,15 @@ select r, r is null as isnull, r is not null as isnotnull from r;
 --
 -- Tests for component access / FieldSelect
 --
-CREATE TABLE compositetable(a text, b text) WITH OIDS;
+CREATE TABLE compositetable(a text, b text);
 INSERT INTO compositetable(a, b) VALUES('fa', 'fb');
 
 -- composite type columns can't directly be accessed (error)
 SELECT d.a FROM (SELECT compositetable AS d FROM compositetable) s;
 -- but can be accessed with proper parens
 SELECT (d).a, (d).b FROM (SELECT compositetable AS d FROM compositetable) s;
--- oids can't be accessed in composite types (error)
-SELECT (d).oid FROM (SELECT compositetable AS d FROM compositetable) s;
+-- system columns can't be accessed in composite types (error)
+SELECT (d).ctid FROM (SELECT compositetable AS d FROM compositetable) s;
 
 -- accessing non-existing column in NULL datum errors out
 SELECT (NULL::compositetable).nonexistant;
diff --git a/src/test/regress/sql/sanity_check.sql b/src/test/regress/sql/sanity_check.sql
index 04aee457dda..a2feebc91bf 100644
--- a/src/test/regress/sql/sanity_check.sql
+++ b/src/test/regress/sql/sanity_check.sql
@@ -25,9 +25,9 @@ SELECT relname, relhasindex
 -- We exclude non-system tables from the check by looking at nspname.
 --
 SELECT relname, nspname
-FROM pg_class c LEFT JOIN pg_namespace n ON n.oid = relnamespace
-WHERE relhasoids
-    AND ((nspname ~ '^pg_') IS NOT FALSE)
-    AND NOT EXISTS (SELECT 1 FROM pg_index i WHERE indrelid = c.oid
-                    AND indkey[0] = -2 AND indnatts = 1
-                    AND indisunique AND indimmediate);
+ FROM pg_class c LEFT JOIN pg_namespace n ON n.oid = relnamespace JOIN pg_attribute a ON (attrelid = c.oid AND attname = 'oid')
+ WHERE relkind = 'r' and c.oid < 16384
+     AND ((nspname ~ '^pg_') IS NOT FALSE)
+     AND NOT EXISTS (SELECT 1 FROM pg_index i WHERE indrelid = c.oid
+                     AND indkey[0] = a.attnum AND indnatts = 1
+                     AND indisunique AND indimmediate);
diff --git a/src/test/regress/sql/triggers.sql b/src/test/regress/sql/triggers.sql
index d7dfd753be2..5336185ed25 100644
--- a/src/test/regress/sql/triggers.sql
+++ b/src/test/regress/sql/triggers.sql
@@ -292,11 +292,11 @@ DROP TRIGGER insert_when ON main_table;
 DROP TRIGGER delete_when ON main_table;
 
 -- Test WHEN condition accessing system columns.
-create table table_with_oids(a int) with oids;
+create table table_with_oids(a int);
 insert into table_with_oids values (1);
 create trigger oid_unchanged_trig after update on table_with_oids
 	for each row
-	when (new.oid = old.oid AND new.oid <> 0)
+	when (new.tableoid = old.tableoid AND new.tableoid <> 0)
 	execute procedure trigger_func('after_upd_oid_unchanged');
 update table_with_oids set a = a + 1;
 drop table table_with_oids;
@@ -582,23 +582,12 @@ CREATE TABLE min_updates_test (
 	f2 int,
 	f3 int);
 
-CREATE TABLE min_updates_test_oids (
-	f1	text,
-	f2 int,
-	f3 int) WITH OIDS;
-
 INSERT INTO min_updates_test VALUES ('a',1,2),('b','2',null);
 
-INSERT INTO min_updates_test_oids VALUES ('a',1,2),('b','2',null);
-
 CREATE TRIGGER z_min_update
 BEFORE UPDATE ON min_updates_test
 FOR EACH ROW EXECUTE PROCEDURE suppress_redundant_updates_trigger();
 
-CREATE TRIGGER z_min_update
-BEFORE UPDATE ON min_updates_test_oids
-FOR EACH ROW EXECUTE PROCEDURE suppress_redundant_updates_trigger();
-
 \set QUIET false
 
 UPDATE min_updates_test SET f1 = f1;
@@ -607,22 +596,12 @@ UPDATE min_updates_test SET f2 = f2 + 1;
 
 UPDATE min_updates_test SET f3 = 2 WHERE f3 is null;
 
-UPDATE min_updates_test_oids SET f1 = f1;
-
-UPDATE min_updates_test_oids SET f2 = f2 + 1;
-
-UPDATE min_updates_test_oids SET f3 = 2 WHERE f3 is null;
-
 \set QUIET true
 
 SELECT * FROM min_updates_test;
 
-SELECT * FROM min_updates_test_oids;
-
 DROP TABLE min_updates_test;
 
-DROP TABLE min_updates_test_oids;
-
 --
 -- Test triggers on views
 --
diff --git a/src/test/regress/sql/without_oid.sql b/src/test/regress/sql/without_oid.sql
deleted file mode 100644
index 9fbb454d4dc..00000000000
--- a/src/test/regress/sql/without_oid.sql
+++ /dev/null
@@ -1,92 +0,0 @@
---
--- WITHOUT OID
---
-
---
--- This test tries to verify that WITHOUT OIDS actually saves space.
--- On machines where MAXALIGN is 8, WITHOUT OIDS may or may not save any
--- space, depending on the size of the tuple header + null bitmap.
--- As of 8.3 we need a null bitmap of 8 or less bits for the difference
--- to appear.
---
-CREATE TABLE wi (i INT,
-                 n1 int, n2 int, n3 int, n4 int,
-                 n5 int, n6 int, n7 int) WITH OIDS;
-CREATE TABLE wo (i INT,
-                 n1 int, n2 int, n3 int, n4 int,
-                 n5 int, n6 int, n7 int) WITHOUT OIDS;
-
-INSERT INTO wi VALUES (1);  -- 1
-INSERT INTO wo SELECT i FROM wi;  -- 1
-INSERT INTO wo SELECT i+1 FROM wi;  -- 1+1=2
-INSERT INTO wi SELECT i+1 FROM wo;  -- 1+2=3
-INSERT INTO wi SELECT i+3 FROM wi;  -- 3+3=6
-INSERT INTO wo SELECT i+2 FROM wi;  -- 2+6=8
-INSERT INTO wo SELECT i+8 FROM wo;  -- 8+8=16
-INSERT INTO wi SELECT i+6 FROM wo;  -- 6+16=22
-INSERT INTO wi SELECT i+22 FROM wi;  -- 22+22=44
-INSERT INTO wo SELECT i+16 FROM wi;  -- 16+44=60
-INSERT INTO wo SELECT i+60 FROM wo;  -- 60+60=120
-INSERT INTO wi SELECT i+44 FROM wo;  -- 44+120=164
-INSERT INTO wi SELECT i+164 FROM wi;  -- 164+164=328
-INSERT INTO wo SELECT i+120 FROM wi;  -- 120+328=448
-INSERT INTO wo SELECT i+448 FROM wo;  -- 448+448=896
-INSERT INTO wi SELECT i+328 FROM wo;  -- 328+896=1224
-INSERT INTO wi SELECT i+1224 FROM wi;  -- 1224+1224=2448
-INSERT INTO wo SELECT i+896 FROM wi;  -- 896+2448=3344
-INSERT INTO wo SELECT i+3344 FROM wo;  -- 3344+3344=6688
-INSERT INTO wi SELECT i+2448 FROM wo;  -- 2448+6688=9136
-INSERT INTO wo SELECT i+6688 FROM wi WHERE i<=2448;  -- 6688+2448=9136
-
-SELECT count(oid) FROM wi;
--- should fail
-SELECT count(oid) FROM wo;
-
-VACUUM ANALYZE wi;
-VACUUM ANALYZE wo;
-
-SELECT min(relpages) < max(relpages), min(reltuples) - max(reltuples)
-  FROM pg_class
- WHERE relname IN ('wi', 'wo');
-
-DROP TABLE wi;
-DROP TABLE wo;
-
---
--- WITH / WITHOUT OIDS in CREATE TABLE AS
---
-CREATE TABLE create_table_test (
-    a int,
-    b int
-);
-
-COPY create_table_test FROM stdin;
-5	10
-10	15
-\.
-
-CREATE TABLE create_table_test2 WITH OIDS AS
-    SELECT a + b AS c1, a - b AS c2 FROM create_table_test;
-
-CREATE TABLE create_table_test3 WITHOUT OIDS AS
-    SELECT a + b AS c1, a - b AS c2 FROM create_table_test;
-
-SELECT count(oid) FROM create_table_test2;
--- should fail
-SELECT count(oid) FROM create_table_test3;
-
-PREPARE table_source(int) AS
-    SELECT a + b AS c1, a - b AS c2, $1 AS c3 FROM create_table_test;
-
-CREATE TABLE execute_with WITH OIDS AS EXECUTE table_source(1);
-CREATE TABLE execute_without WITHOUT OIDS AS EXECUTE table_source(2);
-
-SELECT count(oid) FROM execute_with;
--- should fail
-SELECT count(oid) FROM execute_without;
-
-DROP TABLE create_table_test;
-DROP TABLE create_table_test2;
-DROP TABLE create_table_test3;
-DROP TABLE execute_with;
-DROP TABLE execute_without;
diff --git a/src/tools/findoidjoins/findoidjoins.c b/src/tools/findoidjoins/findoidjoins.c
index cbb7b59adc8..21a09ada4f6 100644
--- a/src/tools/findoidjoins/findoidjoins.c
+++ b/src/tools/findoidjoins/findoidjoins.c
@@ -63,7 +63,9 @@ main(int argc, char **argv)
 					  "pg_catalog.pg_namespace n WHERE n.oid = c.relnamespace) AS nspname "
 					  "FROM pg_catalog.pg_class c "
 					  "WHERE c.relkind = " CppAsString2(RELKIND_RELATION)
-					  " AND c.relhasoids "
+					  " AND EXISTS(SELECT * FROM pg_attribute a"
+					  "            WHERE a.attrelid = c.oid AND a.attname = 'oid' "
+					  "                  AND a.atttypid = 'oid'::regtype)"
 					  "ORDER BY nspname, c.relname"
 		);
 
-- 
2.18.0.rc2.dirty

